From 9ebf44d84754adc5b64fcf612c6816c02c80462d Mon Sep 17 00:00:00 2001
From: Benjamin Barenblat
Date: Sat, 2 Feb 2019 19:29:23 -0500
Subject: Imported Upstream version 8.9.0
---
.bintray.json | 20 -
.github/PULL_REQUEST_TEMPLATE.md | 7 +-
.gitlab-ci.yml | 86 +-
.merlin | 54 -
.merlin.in | 54 +
.travis.yml | 235 --
CHANGES | 3802 ------------------
CHANGES.md | 4015 ++++++++++++++++++++
CONTRIBUTING.md | 75 +-
CREDITS | 4 +-
INSTALL | 4 +-
INSTALL.doc | 105 -
INSTALL.ide | 123 -
META.coq | 571 ---
META.coq.in | 543 +++
Makefile | 112 +-
Makefile.build | 158 +-
Makefile.checker | 39 +-
Makefile.ci | 2 +
Makefile.common | 84 +-
Makefile.dev | 6 +-
Makefile.doc | 125 +-
Makefile.ide | 61 +-
Makefile.install | 22 +-
Makefile.vofiles | 43 +
README.md | 17 +-
checker/check.mllib | 1 -
checker/checker.ml | 4 +-
checker/cic.mli | 32 +-
checker/closure.ml | 48 +-
checker/closure.mli | 2 +-
checker/declarations.ml | 51 +-
checker/declarations.mli | 3 +
checker/environ.ml | 27 +-
checker/environ.mli | 4 +-
checker/indtypes.ml | 35 +-
checker/inductive.ml | 26 +-
checker/mod_checking.ml | 13 +-
checker/modops.ml | 22 +-
checker/print.ml | 4 +-
checker/reduction.ml | 70 +-
checker/subtyping.ml | 32 +-
checker/term.ml | 22 +-
checker/typeops.ml | 25 +-
checker/univ.ml | 25 +-
checker/univ.mli | 12 +-
checker/values.ml | 29 +-
clib/cArray.ml | 300 +-
clib/cArray.mli | 84 +-
clib/cList.ml | 1217 +++---
clib/cList.mli | 380 +-
clib/cMap.ml | 58 +-
clib/cMap.mli | 13 +-
clib/canary.ml | 28 -
clib/canary.mli | 27 -
clib/clib.mllib | 3 +-
clib/diff2.ml | 158 +
clib/diff2.mli | 101 +
clib/dyn.ml | 194 +-
clib/dyn.mli | 63 +-
clib/hMap.ml | 20 +-
clib/hashcons.ml | 40 -
clib/hashcons.mli | 3 -
clib/option.ml | 21 +-
clib/option.mli | 13 +-
clib/terminal.ml | 48 +-
clib/terminal.mli | 6 +
configure.ml | 99 +-
coqpp/coqpp_ast.mli | 96 +
coqpp/coqpp_lex.mll | 168 +
coqpp/coqpp_main.ml | 360 ++
coqpp/coqpp_parse.mly | 261 ++
default.nix | 10 +-
dev/README | 50 -
dev/README.md | 46 +
dev/base_include | 13 +-
dev/build/osx/make-macos-dmg.sh | 54 +-
dev/build/windows/MakeCoq_MinGW.bat | 976 ++---
dev/build/windows/configure_profile.sh | 24 +-
dev/build/windows/difftar-folder.sh | 22 +-
dev/build/windows/makecoq_mingw.sh | 84 +-
dev/build/windows/patches_coq/VST.patch | 15 +
...-86ac28259030649ef51460e4de2441c8a1017751.patch | 21 -
.../windows/patches_coq/quickchick-v1.0.2.patch | 38 -
dev/build/windows/patches_coq/quickchick.patch | 26 +
dev/checker.dbg | 6 +
dev/checker_db | 39 +
dev/checker_printers.ml | 73 +
dev/checker_printers.mli | 54 +
dev/ci/README.md | 45 +-
dev/ci/appveyor.sh | 2 +-
dev/ci/ci-basic-overlay.sh | 128 +-
dev/ci/ci-common.sh | 8 +-
dev/ci/ci-cross-crypto.sh | 9 +
dev/ci/ci-elpi.sh | 1 -
dev/ci/ci-fiat-crypto-legacy.sh | 1 +
dev/ci/ci-hott.sh | 2 +-
dev/ci/ci-iris-lambda-rust.sh | 6 +-
dev/ci/ci-math-comp.sh | 1 +
dev/ci/ci-pidetop.sh | 19 +
dev/ci/ci-sf.sh | 9 +-
dev/ci/ci-simple-io.sh | 1 -
dev/ci/docker/README.md | 36 +
dev/ci/docker/bionic_coq/Dockerfile | 53 +-
dev/ci/gitlab.bat | 263 +-
.../user-overlays/00669-maximedenes-ssr-merge.sh | 2 +
.../07085-ppedrot-pure-sharing-flag.sh | 8 +
dev/ci/user-overlays/README.md | 8 +-
dev/core.dbg | 3 +-
dev/doc/MERGING.md | 136 +
dev/doc/README.md | 77 +
dev/doc/changes.md | 227 +-
dev/doc/coq-src-description.txt | 6 -
dev/doc/critical-bugs | 262 ++
dev/doc/proof-engine.md | 31 +-
dev/doc/release-process.md | 128 +
dev/doc/setup.txt | 269 --
dev/doc/translate.txt | 495 ---
dev/doc/versions-history.tex | 12 +-
dev/doc/xml-protocol.md | 4 +-
dev/lint-repository.sh | 2 +
dev/ocamldebug-coq.run | 22 +-
dev/tools/backport-pr.sh | 53 +-
dev/tools/check-overlays.sh | 11 +
dev/tools/check-owners-pr.sh | 32 +
dev/tools/check-owners.sh | 138 +
dev/tools/coqdev.el | 47 +-
dev/tools/merge-pr.sh | 218 +-
dev/tools/pre-commit | 2 +
dev/tools/update-compat.py | 341 ++
dev/top_printers.ml | 58 +-
dev/top_printers.mli | 6 +-
dev/vm_printers.ml | 13 +-
doc/LICENSE | 23 +-
doc/README.md | 126 +
doc/stdlib/hidden-files | 78 +-
doc/stdlib/index-list.html.template | 17 +-
doc/stdlib/make-library-index | 25 +-
doc/tools/coqrst/coqdomain.py | 3 +
doc/tools/coqrst/repl/coqtop.py | 5 +-
engine/eConstr.ml | 259 +-
engine/eConstr.mli | 44 +-
engine/engine.mllib | 6 +
engine/evar_kinds.ml | 52 +
engine/evar_kinds.mli | 51 +
engine/evarutil.ml | 209 +-
engine/evarutil.mli | 127 +-
engine/evd.ml | 158 +-
engine/evd.mli | 208 +-
engine/namegen.ml | 18 +-
engine/namegen.mli | 10 +
engine/nameops.ml | 28 +-
engine/nameops.mli | 44 -
engine/proofview.ml | 32 +-
engine/proofview.mli | 18 +-
engine/termops.ml | 101 +-
engine/termops.mli | 76 +-
engine/uState.ml | 108 +-
engine/uState.mli | 28 +-
engine/univGen.ml | 246 ++
engine/univGen.mli | 80 +
engine/univMinim.ml | 383 ++
engine/univMinim.mli | 32 +
engine/univNames.ml | 106 +
engine/univNames.mli | 41 +
engine/univProblem.ml | 166 +
engine/univProblem.mli | 55 +
engine/univSubst.ml | 177 +
engine/univSubst.mli | 53 +
engine/universes.ml | 1195 +-----
engine/universes.mli | 262 +-
engine/univops.ml | 100 +-
engine/univops.mli | 9 +-
grammar/q_util.mli | 2 +
grammar/q_util.mlp | 16 +-
grammar/tacextend.mlp | 31 +-
grammar/vernacextend.mlp | 171 +-
ide/.merlin | 6 -
ide/.merlin.in | 8 +
ide/MacOS/default_accel_map | 1 -
ide/MacOS/relatify_with-respect-to_.sh | 15 -
ide/configwin.ml | 51 +
ide/configwin.mli | 164 +
ide/configwin_ihm.ml | 809 ++++
ide/configwin_ihm.mli | 66 +
ide/configwin_messages.ml | 50 +
ide/configwin_types.ml | 121 +
ide/coq.ml | 51 +-
ide/coq.mli | 10 +-
ide/coq_commands.ml | 1 -
ide/coq_lex.mll | 6 +-
ide/coqide.ml | 25 +-
ide/coqide_ui.ml | 5 +-
ide/coqidetop.mllib | 8 -
ide/gtk_parsing.ml | 7 +-
ide/ide.mllib | 8 -
ide/ide_common.mllib | 7 +
ide/ide_slave.ml | 522 ---
ide/ide_slave.mli | 12 -
ide/idetop.ml | 546 +++
ide/ideutils.ml | 61 +-
ide/interface.mli | 261 --
ide/nanoPG.ml | 6 +-
ide/preferences.ml | 28 +-
ide/preferences.mli | 2 +
ide/protocol/ideprotocol.mllib | 7 +
ide/protocol/interface.ml | 261 ++
ide/protocol/richpp.ml | 171 +
ide/protocol/richpp.mli | 53 +
ide/protocol/serialize.ml | 123 +
ide/protocol/serialize.mli | 41 +
ide/protocol/xml_lexer.mli | 44 +
ide/protocol/xml_lexer.mll | 320 ++
ide/protocol/xml_parser.ml | 232 ++
ide/protocol/xml_parser.mli | 106 +
ide/protocol/xml_printer.ml | 147 +
ide/protocol/xml_printer.mli | 31 +
ide/protocol/xmlprotocol.ml | 964 +++++
ide/protocol/xmlprotocol.mli | 73 +
ide/richpp.ml | 171 -
ide/richpp.mli | 53 -
ide/serialize.ml | 123 -
ide/serialize.mli | 41 -
ide/utils/configwin.ml | 51 -
ide/utils/configwin.mli | 164 -
ide/utils/configwin_ihm.ml | 809 ----
ide/utils/configwin_ihm.mli | 66 -
ide/utils/configwin_messages.ml | 50 -
ide/utils/configwin_types.mli | 121 -
ide/wg_Command.ml | 8 +-
ide/xml_lexer.mli | 44 -
ide/xml_lexer.mll | 320 --
ide/xml_parser.ml | 232 --
ide/xml_parser.mli | 106 -
ide/xml_printer.ml | 147 -
ide/xml_printer.mli | 31 -
ide/xmlprotocol.ml | 964 -----
ide/xmlprotocol.mli | 73 -
interp/constrexpr.ml | 162 +
interp/constrexpr_ops.ml | 107 +-
interp/constrexpr_ops.mli | 26 +-
interp/constrextern.ml | 285 +-
interp/constrextern.mli | 8 +-
interp/constrintern.ml | 238 +-
interp/constrintern.mli | 14 +-
interp/declare.ml | 117 +-
interp/declare.mli | 6 +-
interp/discharge.ml | 7 +-
interp/dumpglob.ml | 10 +-
interp/dumpglob.mli | 10 +-
interp/genintern.ml | 8 +-
interp/genintern.mli | 8 +-
interp/genredexpr.ml | 65 +
interp/impargs.ml | 310 +-
interp/impargs.mli | 9 +-
interp/implicit_quantifiers.ml | 25 +-
interp/implicit_quantifiers.mli | 17 +-
interp/interp.mllib | 6 +-
interp/modintern.ml | 12 +-
interp/modintern.mli | 3 +-
interp/notation.ml | 961 +++--
interp/notation.mli | 179 +-
interp/notation_ops.ml | 83 +-
interp/notation_ops.mli | 10 +-
interp/notation_term.ml | 98 +
interp/ppextend.ml | 43 -
interp/ppextend.mli | 36 -
interp/redops.ml | 64 +
interp/redops.mli | 20 +
interp/reserve.ml | 6 +-
interp/reserve.mli | 2 +-
interp/smartlocate.ml | 19 +-
interp/smartlocate.mli | 13 +-
interp/stdarg.ml | 15 +-
interp/stdarg.mli | 38 +-
interp/syntax_def.ml | 4 +-
interp/tactypes.ml | 34 -
interp/topconstr.ml | 23 -
interp/topconstr.mli | 53 -
intf/constrexpr.ml | 152 -
intf/decl_kinds.ml | 87 -
intf/evar_kinds.ml | 37 -
intf/extend.ml | 134 -
intf/genredexpr.ml | 66 -
intf/glob_term.ml | 112 -
intf/intf.mllib | 11 -
intf/locus.ml | 96 -
intf/misctypes.ml | 162 -
intf/notation_term.ml | 123 -
intf/pattern.ml | 44 -
intf/vernacexpr.ml | 543 ---
kernel/byterun/coq_fix_code.c | 51 +-
kernel/byterun/coq_fix_code.h | 2 +-
kernel/byterun/coq_interp.c | 55 +-
kernel/byterun/coq_interp.h | 9 +-
kernel/byterun/coq_memory.c | 92 +-
kernel/byterun/coq_memory.h | 7 -
kernel/byterun/coq_values.c | 31 +-
kernel/cClosure.ml | 233 +-
kernel/cClosure.mli | 17 +-
kernel/cbytecodes.ml | 100 +-
kernel/cbytecodes.mli | 40 +-
kernel/cbytegen.ml | 204 +-
kernel/cbytegen.mli | 5 +-
kernel/cemitcodes.ml | 23 +-
kernel/cemitcodes.mli | 2 +
kernel/cinstr.mli | 6 +-
kernel/clambda.ml | 87 +-
kernel/clambda.mli | 9 +-
kernel/constr.ml | 97 +-
kernel/constr.mli | 41 +-
kernel/context.ml | 25 +-
kernel/context.mli | 21 +-
kernel/cooking.ml | 79 +-
kernel/cooking.mli | 6 +-
kernel/csymtable.ml | 55 +-
kernel/csymtable.mli | 4 +-
kernel/declarations.ml | 43 +-
kernel/declareops.ml | 78 +-
kernel/declareops.mli | 10 +-
kernel/entries.ml | 32 +-
kernel/environ.ml | 376 +-
kernel/environ.mli | 112 +-
kernel/esubst.ml | 35 +-
kernel/esubst.mli | 13 +-
kernel/indtypes.ml | 141 +-
kernel/indtypes.mli | 5 -
kernel/inductive.ml | 30 +-
kernel/inductive.mli | 8 +-
kernel/kernel.mllib | 17 +-
kernel/mod_subst.ml | 35 +-
kernel/mod_subst.mli | 5 +-
kernel/mod_typing.ml | 2 +-
kernel/modops.ml | 25 +-
kernel/modops.mli | 2 +-
kernel/names.ml | 305 +-
kernel/names.mli | 333 +-
kernel/nativecode.ml | 185 +-
kernel/nativecode.mli | 6 +-
kernel/nativeconv.ml | 19 +-
kernel/nativeconv.mli | 4 -
kernel/nativeinstr.mli | 6 +-
kernel/nativelambda.ml | 277 +-
kernel/nativelambda.mli | 5 +-
kernel/nativelibrary.ml | 7 +-
kernel/nativevalues.ml | 38 +-
kernel/nativevalues.mli | 11 +-
kernel/opaqueproof.ml | 2 +-
kernel/opaqueproof.mli | 2 +-
kernel/pre_env.ml | 213 --
kernel/pre_env.mli | 108 -
kernel/reduction.ml | 96 +-
kernel/reduction.mli | 14 +-
kernel/retroknowledge.ml | 19 -
kernel/retroknowledge.mli | 22 +-
kernel/safe_typing.ml | 202 +-
kernel/safe_typing.mli | 18 +-
kernel/sorts.ml | 57 +-
kernel/sorts.mli | 7 +-
kernel/subtyping.ml | 9 +-
kernel/term.ml | 255 +-
kernel/term.mli | 433 +--
kernel/term_typing.ml | 244 +-
kernel/term_typing.mli | 10 +-
kernel/type_errors.ml | 4 +
kernel/type_errors.mli | 3 +
kernel/typeops.ml | 59 +-
kernel/typeops.mli | 7 +-
kernel/uGraph.ml | 74 +-
kernel/uGraph.mli | 21 +-
kernel/univ.ml | 29 +-
kernel/univ.mli | 2 +-
kernel/vars.mli | 14 +-
kernel/vconv.ml | 21 +-
kernel/vconv.mli | 4 -
kernel/vm.ml | 10 +-
kernel/vmvalues.ml | 203 +-
kernel/vmvalues.mli | 50 +-
lib/cErrors.ml | 4 +-
lib/cErrors.mli | 2 -
lib/cWarnings.ml | 6 +-
lib/coqProject_file.ml | 282 ++
lib/coqProject_file.ml4 | 255 --
lib/envars.ml | 2 +
lib/flags.ml | 21 +-
lib/flags.mli | 37 +-
lib/future.ml | 6 +-
lib/future.mli | 4 +-
lib/lib.mllib | 1 +
lib/pp.ml | 75 +-
lib/pp.mli | 19 +
lib/pp_diff.ml | 303 ++
lib/pp_diff.mli | 116 +
lib/rtree.ml | 28 +-
lib/rtree.mli | 11 +-
lib/spawn.ml | 59 +-
lib/spawn.mli | 4 +-
lib/stateid.ml | 10 +-
lib/system.ml | 22 +-
lib/system.mli | 20 +-
lib/util.ml | 4 +-
library/coqlib.ml | 34 +-
library/coqlib.mli | 123 +-
library/decl_kinds.ml | 76 +
library/declaremods.ml | 23 +-
library/declaremods.mli | 26 +-
library/global.ml | 7 +
library/global.mli | 19 +-
library/globnames.ml | 15 +-
library/globnames.mli | 57 +-
library/goptions.ml | 23 +-
library/goptions.mli | 8 +-
library/heads.ml | 193 -
library/heads.mli | 28 -
library/keys.ml | 9 +-
library/keys.mli | 4 +-
library/lib.ml | 52 +-
library/lib.mli | 80 +-
library/libnames.ml | 90 +-
library/libnames.mli | 46 +-
library/libobject.ml | 16 +-
library/library.ml | 50 +-
library/library.mli | 2 +-
library/library.mllib | 2 +-
library/nametab.ml | 50 +-
library/nametab.mli | 36 +-
library/summary.ml | 44 -
library/summary.mli | 20 -
man/gallina.1 | 74 -
parsing/egramcoq.ml | 483 ---
parsing/egramcoq.mli | 19 -
parsing/egramml.ml | 84 -
parsing/egramml.mli | 33 -
parsing/extend.ml | 126 +
parsing/g_constr.ml4 | 519 ---
parsing/g_constr.mlg | 526 +++
parsing/g_prim.ml4 | 122 -
parsing/g_prim.mlg | 123 +
parsing/g_proofs.ml4 | 133 -
parsing/g_vernac.ml4 | 1195 ------
parsing/notation_gram.ml | 43 +
parsing/notgram_ops.ml | 71 +
parsing/notgram_ops.mli | 20 +
parsing/parsing.mllib | 8 +-
parsing/pcoq.ml | 299 +-
parsing/pcoq.mli | 252 +-
parsing/ppextend.ml | 77 +
parsing/ppextend.mli | 51 +
plugins/.merlin | 1 -
plugins/.merlin.in | 1 +
plugins/btauto/Algebra.v | 24 +-
plugins/btauto/g_btauto.ml4 | 18 -
plugins/btauto/g_btauto.mlg | 22 +
plugins/btauto/refl_btauto.ml | 30 +-
plugins/cc/ccalgo.ml | 20 +-
plugins/cc/cctac.ml | 15 +-
plugins/cc/g_congruence.ml4 | 29 -
plugins/cc/g_congruence.mlg | 33 +
plugins/derive/derive.ml | 2 +-
plugins/extraction/ExtrHaskellString.v | 2 +
plugins/extraction/ExtrOcamlString.v | 1 +
plugins/extraction/common.mli | 3 +-
plugins/extraction/extract_env.ml | 15 +-
plugins/extraction/extract_env.mli | 11 +-
plugins/extraction/extraction.ml | 22 +-
plugins/extraction/miniml.ml | 25 +-
plugins/extraction/miniml.mli | 25 +-
plugins/extraction/mlutil.ml | 26 +-
plugins/extraction/mlutil.mli | 5 +-
plugins/extraction/modutil.ml | 2 +-
plugins/extraction/modutil.mli | 7 +-
plugins/extraction/table.ml | 8 +-
plugins/extraction/table.mli | 77 +-
plugins/firstorder/formula.ml | 2 +-
plugins/firstorder/formula.mli | 8 +-
plugins/firstorder/g_ground.ml4 | 3 +-
plugins/firstorder/ground.ml | 16 +-
plugins/firstorder/instances.ml | 7 +-
plugins/firstorder/instances.mli | 4 +-
plugins/firstorder/rules.ml | 4 +-
plugins/firstorder/rules.mli | 9 +-
plugins/firstorder/sequent.ml | 32 +-
plugins/firstorder/sequent.mli | 22 +-
plugins/firstorder/unify.ml | 6 +-
plugins/fourier/Fourier.v | 20 -
plugins/fourier/Fourier_util.v | 222 --
plugins/fourier/fourier.ml | 204 -
plugins/fourier/fourierR.ml | 644 ----
plugins/fourier/fourier_plugin.mlpack | 3 -
plugins/fourier/g_fourier.ml4 | 18 -
plugins/funind/functional_principles_proofs.ml | 60 +-
plugins/funind/functional_principles_types.ml | 36 +-
plugins/funind/functional_principles_types.mli | 4 +-
plugins/funind/g_indfun.ml4 | 15 +-
plugins/funind/glob_term_to_relation.ml | 11 +-
plugins/funind/glob_termops.ml | 25 +-
plugins/funind/glob_termops.mli | 2 +-
plugins/funind/indfun.ml | 63 +-
plugins/funind/indfun.mli | 5 +-
plugins/funind/indfun_common.ml | 38 +-
plugins/funind/indfun_common.mli | 14 +-
plugins/funind/invfun.ml | 32 +-
plugins/funind/invfun.mli | 4 +-
plugins/funind/recdef.ml | 52 +-
plugins/funind/recdef.mli | 2 +-
plugins/ltac/coretactics.ml4 | 366 --
plugins/ltac/coretactics.mlg | 388 ++
plugins/ltac/evar_tactics.ml | 10 +-
plugins/ltac/extraargs.ml4 | 51 +-
plugins/ltac/extraargs.mli | 23 +-
plugins/ltac/extratactics.ml4 | 137 +-
plugins/ltac/g_auto.ml4 | 9 +-
plugins/ltac/g_eqdecide.ml4 | 28 -
plugins/ltac/g_eqdecide.mlg | 32 +
plugins/ltac/g_ltac.ml4 | 69 +-
plugins/ltac/g_obligations.ml4 | 5 +-
plugins/ltac/g_rewrite.ml4 | 8 +-
plugins/ltac/g_tactic.ml4 | 698 ----
plugins/ltac/g_tactic.mlg | 706 ++++
plugins/ltac/pltac.ml | 9 +-
plugins/ltac/pltac.mli | 40 +-
plugins/ltac/pptactic.ml | 83 +-
plugins/ltac/pptactic.mli | 10 +-
plugins/ltac/rewrite.ml | 60 +-
plugins/ltac/rewrite.mli | 4 +-
plugins/ltac/tacarg.ml | 8 +
plugins/ltac/tacarg.mli | 34 +-
plugins/ltac/taccoerce.ml | 38 +-
plugins/ltac/taccoerce.mli | 18 +-
plugins/ltac/tacentries.ml | 87 +-
plugins/ltac/tacentries.mli | 21 +-
plugins/ltac/tacenv.ml | 49 +-
plugins/ltac/tacenv.mli | 18 +-
plugins/ltac/tacexpr.ml | 54 +-
plugins/ltac/tacexpr.mli | 54 +-
plugins/ltac/tacintern.ml | 164 +-
plugins/ltac/tacintern.mli | 2 +-
plugins/ltac/tacinterp.ml | 99 +-
plugins/ltac/tacinterp.mli | 5 +-
plugins/ltac/tacsubst.ml | 7 +-
plugins/ltac/tacsubst.mli | 2 +-
plugins/ltac/tactic_debug.ml | 18 +-
plugins/ltac/tactic_debug.mli | 2 +-
plugins/ltac/tactic_matching.ml | 2 +-
plugins/ltac/tauto.ml | 11 +-
plugins/micromega/Fourier.v | 5 +
plugins/micromega/Fourier_util.v | 31 +
plugins/micromega/Tauto.v | 4 +-
plugins/micromega/certificate.ml | 194 +-
plugins/micromega/certificate.mli | 22 +
plugins/micromega/coq_micromega.ml | 323 +-
plugins/micromega/coq_micromega.mli | 22 +
plugins/micromega/csdpcert.ml | 36 +-
plugins/micromega/csdpcert.mli | 9 +
plugins/micromega/g_micromega.ml4 | 85 -
plugins/micromega/g_micromega.mlg | 89 +
plugins/micromega/g_micromega.mli | 9 +
plugins/micromega/mfourier.ml | 85 +-
plugins/micromega/mfourier.mli | 49 +
plugins/micromega/mutils.ml | 109 -
plugins/micromega/mutils.mli | 70 +
plugins/micromega/persistent_cache.mli | 47 +
plugins/micromega/polynomial.ml | 68 +-
plugins/micromega/polynomial.mli | 118 +
plugins/micromega/sos.ml | 616 +--
plugins/micromega/sos_lib.ml | 105 +-
plugins/micromega/sos_lib.mli | 79 +
plugins/nsatz/g_nsatz.ml4 | 18 -
plugins/nsatz/g_nsatz.mlg | 22 +
plugins/nsatz/nsatz.ml | 2 +-
plugins/omega/PreOmega.v | 8 +-
plugins/omega/coq_omega.ml | 23 +-
plugins/omega/g_omega.ml4 | 56 -
plugins/omega/g_omega.mlg | 59 +
plugins/omega/omega.ml | 2 +-
plugins/quote/g_quote.ml4 | 39 -
plugins/quote/g_quote.mlg | 46 +
plugins/quote/quote.ml | 2 +-
plugins/romega/const_omega.ml | 10 +-
plugins/romega/g_romega.ml4 | 51 -
plugins/romega/g_romega.mlg | 63 +
plugins/romega/refl_omega.ml | 5 +-
plugins/rtauto/g_rtauto.ml4 | 19 -
plugins/rtauto/g_rtauto.mlg | 22 +
plugins/rtauto/refl_tauto.ml | 8 +-
plugins/setoid_ring/g_newring.ml4 | 9 +-
plugins/setoid_ring/newring.ml | 196 +-
plugins/setoid_ring/newring.mli | 3 -
plugins/setoid_ring/newring_ast.ml | 2 +-
plugins/setoid_ring/newring_ast.mli | 2 +-
plugins/ssr/ssrast.mli | 6 +-
plugins/ssr/ssrbool.v | 936 ++---
plugins/ssr/ssrcommon.ml | 43 +-
plugins/ssr/ssrcommon.mli | 4 +-
plugins/ssr/ssreflect.v | 439 ++-
plugins/ssr/ssrelim.ml | 7 +-
plugins/ssr/ssrequality.ml | 32 +-
plugins/ssr/ssrfun.v | 487 +--
plugins/ssr/ssrfwd.ml | 15 +-
plugins/ssr/ssripats.ml | 85 +-
plugins/ssr/ssrparser.ml4 | 74 +-
plugins/ssr/ssrparser.mli | 8 +-
plugins/ssr/ssrprinters.ml | 5 +-
plugins/ssr/ssrtacticals.ml | 15 +-
plugins/ssr/ssrtacticals.mli | 4 +-
plugins/ssr/ssrvernac.ml4 | 38 +-
plugins/ssr/ssrview.ml | 99 +-
plugins/ssr/ssrview.mli | 6 +-
plugins/ssrmatching/g_ssrmatching.ml4 | 101 +
plugins/ssrmatching/ssrmatching.ml | 1428 +++++++
plugins/ssrmatching/ssrmatching.ml4 | 1484 --------
plugins/ssrmatching/ssrmatching.mli | 258 ++
plugins/ssrmatching/ssrmatching.v | 36 +
plugins/ssrmatching/ssrmatching_plugin.mlpack | 1 +
plugins/syntax/ascii_syntax.ml | 20 +-
plugins/syntax/g_numeral.ml4 | 38 +
plugins/syntax/int31_syntax.ml | 23 +-
plugins/syntax/nat_syntax.ml | 84 -
plugins/syntax/nat_syntax_plugin.mlpack | 1 -
plugins/syntax/numeral.ml | 142 +
plugins/syntax/numeral.mli | 17 +
plugins/syntax/numeral_notation_plugin.mlpack | 2 +
plugins/syntax/r_syntax.ml | 28 +-
plugins/syntax/string_syntax.ml | 25 +-
plugins/syntax/z_syntax.ml | 202 -
plugins/syntax/z_syntax_plugin.mlpack | 1 -
pretyping/arguments_renaming.ml | 2 +-
pretyping/arguments_renaming.mli | 5 +-
pretyping/cases.ml | 101 +-
pretyping/cbv.ml | 31 +-
pretyping/cbv.mli | 2 +-
pretyping/classops.ml | 126 +-
pretyping/classops.mli | 24 +-
pretyping/coercion.ml | 85 +-
pretyping/constr_matching.ml | 60 +-
pretyping/constr_matching.mli | 2 +-
pretyping/detyping.ml | 234 +-
pretyping/detyping.mli | 12 +-
pretyping/evarconv.ml | 109 +-
pretyping/evarconv.mli | 8 +-
pretyping/evardefine.ml | 23 +-
pretyping/evarsolve.ml | 147 +-
pretyping/geninterp.mli | 4 +-
pretyping/glob_ops.ml | 60 +-
pretyping/glob_ops.mli | 9 +-
pretyping/glob_term.ml | 137 +
pretyping/heads.ml | 193 +
pretyping/heads.mli | 28 +
pretyping/indrec.ml | 13 +-
pretyping/indrec.mli | 2 +-
pretyping/inductiveops.ml | 154 +-
pretyping/inductiveops.mli | 30 +-
pretyping/locus.ml | 99 +
pretyping/locusops.ml | 4 +-
pretyping/miscops.ml | 76 -
pretyping/miscops.mli | 36 -
pretyping/nativenorm.ml | 109 +-
pretyping/nativenorm.mli | 2 +-
pretyping/pattern.ml | 44 +
pretyping/patternops.ml | 169 +-
pretyping/patternops.mli | 11 +-
pretyping/pretype_errors.ml | 2 +-
pretyping/pretyping.ml | 158 +-
pretyping/pretyping.mli | 2 +-
pretyping/pretyping.mllib | 8 +-
pretyping/program.ml | 4 +-
pretyping/program.mli | 38 +-
pretyping/recordops.ml | 72 +-
pretyping/recordops.mli | 20 +-
pretyping/redops.ml | 44 -
pretyping/redops.mli | 15 -
pretyping/reductionops.ml | 167 +-
pretyping/reductionops.mli | 27 +-
pretyping/retyping.ml | 23 +-
pretyping/tacred.ml | 45 +-
pretyping/tacred.mli | 11 +-
pretyping/typeclasses.ml | 47 +-
pretyping/typeclasses.mli | 50 +-
pretyping/typeclasses_errors.ml | 8 +-
pretyping/typeclasses_errors.mli | 10 +-
pretyping/typing.ml | 428 ++-
pretyping/typing.mli | 12 +-
pretyping/unification.ml | 182 +-
pretyping/unification.mli | 3 +-
pretyping/univdecls.ml | 52 -
pretyping/univdecls.mli | 21 -
pretyping/vnorm.ml | 73 +-
printing/genprint.ml | 8 +-
printing/genprint.mli | 8 +-
printing/ppconstr.ml | 51 +-
printing/ppconstr.mli | 13 +-
printing/pputils.ml | 5 +-
printing/pputils.mli | 3 +-
printing/ppvernac.ml | 1252 ------
printing/ppvernac.mli | 26 -
printing/prettyp.ml | 61 +-
printing/prettyp.mli | 34 +-
printing/printer.ml | 217 +-
printing/printer.mli | 97 +-
printing/printing.mllib | 2 +-
printing/printmod.ml | 19 +-
printing/printmod.mli | 2 +-
printing/proof_diffs.ml | 635 ++++
printing/proof_diffs.mli | 84 +
proofs/clenv.ml | 31 +-
proofs/clenv.mli | 2 +-
proofs/clenvtac.ml | 12 +-
proofs/clenvtac.mli | 7 +-
proofs/evar_refiner.ml | 8 +-
proofs/goal.ml | 25 +-
proofs/goal.mli | 5 +-
proofs/goal_select.ml | 68 +
proofs/goal_select.mli | 26 +
proofs/logic.ml | 97 +-
proofs/logic.mli | 15 +-
proofs/miscprint.ml | 12 +-
proofs/miscprint.mli | 7 +-
proofs/pfedit.ml | 52 +-
proofs/pfedit.mli | 9 +-
proofs/proof.ml | 45 +
proofs/proof.mli | 6 +
proofs/proof_bullet.ml | 68 +-
proofs/proof_bullet.mli | 19 +-
proofs/proof_global.ml | 35 +-
proofs/proof_global.mli | 18 +-
proofs/proofs.mllib | 1 +
proofs/redexpr.ml | 15 +-
proofs/refine.ml | 51 +-
proofs/refiner.mli | 3 +
proofs/tacmach.ml | 8 +-
proofs/tacmach.mli | 5 +-
proofs/tactypes.ml | 54 +
stm/asyncTaskQueue.ml | 18 +-
stm/coqworkmgrApi.ml | 4 +
stm/coqworkmgrApi.mli | 3 +
stm/proofBlockDelimiter.ml | 6 +-
stm/proofBlockDelimiter.mli | 4 +-
stm/proofworkertop.ml | 16 -
stm/proofworkertop.mllib | 1 -
stm/queryworkertop.ml | 16 -
stm/queryworkertop.mllib | 1 -
stm/spawned.ml | 4 +-
stm/stm.ml | 234 +-
stm/stm.mli | 18 +-
stm/stm.mllib | 1 -
stm/tacworkertop.ml | 16 -
stm/tacworkertop.mllib | 1 -
stm/vernac_classifier.ml | 41 +-
stm/vernac_classifier.mli | 6 +-
stm/workerLoop.ml | 25 -
stm/workerLoop.mli | 14 -
tactics/auto.ml | 9 +-
tactics/autorewrite.ml | 26 +-
tactics/btermdn.ml | 4 +-
tactics/class_tactics.ml | 54 +-
tactics/contradiction.ml | 5 +-
tactics/contradiction.mli | 2 +-
tactics/eauto.ml | 11 +-
tactics/elim.mli | 3 +-
tactics/elimschemes.ml | 6 +-
tactics/eqdecide.ml | 12 +-
tactics/eqschemes.ml | 43 +-
tactics/equality.ml | 63 +-
tactics/equality.mli | 18 +-
tactics/hints.ml | 241 +-
tactics/hints.mli | 76 +-
tactics/hipattern.ml | 12 +-
tactics/hipattern.mli | 2 +-
tactics/ind_tables.ml | 10 +-
tactics/inv.ml | 33 +-
tactics/inv.mli | 6 +-
tactics/leminv.ml | 9 +-
tactics/leminv.mli | 2 +-
tactics/tacticals.ml | 73 +-
tactics/tacticals.mli | 11 +-
tactics/tactics.ml | 296 +-
tactics/tactics.mli | 44 +-
tactics/term_dnet.ml | 4 +-
tactics/term_dnet.mli | 2 +-
test-suite/Makefile | 148 +-
test-suite/README.md | 31 +-
test-suite/bugs/closed/1341.v | 2 +-
test-suite/bugs/closed/1844.v | 2 +-
test-suite/bugs/closed/1891.v | 2 +-
test-suite/bugs/closed/1951.v | 2 +-
test-suite/bugs/closed/1981.v | 2 +-
test-suite/bugs/closed/2362.v | 2 +-
test-suite/bugs/closed/2378.v | 96 +-
test-suite/bugs/closed/2404.v | 4 +-
test-suite/bugs/closed/2456.v | 2 +-
test-suite/bugs/closed/2584.v | 2 +-
test-suite/bugs/closed/2667.v | 4 +-
test-suite/bugs/closed/2670.v | 8 +
test-suite/bugs/closed/2729.v | 4 +-
test-suite/bugs/closed/2733.v | 15 +
test-suite/bugs/closed/2830.v | 10 +-
test-suite/bugs/closed/2969.v | 2 +
test-suite/bugs/closed/3068.v | 2 +-
test-suite/bugs/closed/3377.v | 3 +-
test-suite/bugs/closed/3513.v | 2 +-
test-suite/bugs/closed/3647.v | 6 +-
test-suite/bugs/closed/3690.v | 7 +-
test-suite/bugs/closed/3732.v | 2 +-
test-suite/bugs/closed/3956.v | 8 +-
test-suite/bugs/closed/4069.v | 2 +
test-suite/bugs/closed/4095.v | 2 +-
test-suite/bugs/closed/4132.v | 2 +-
test-suite/bugs/closed/4198.v | 2 +
test-suite/bugs/closed/4306.v | 6 +-
test-suite/bugs/closed/4527.v | 8 +-
test-suite/bugs/closed/4533.v | 11 +-
test-suite/bugs/closed/4544.v | 3 +-
test-suite/bugs/closed/4782.v | 2 +
test-suite/bugs/closed/4798.v | 2 +-
test-suite/bugs/closed/4865.v | 2 +-
test-suite/bugs/closed/4882.v | 50 -
test-suite/bugs/closed/5012.v | 17 +
test-suite/bugs/closed/5500.v | 35 +
test-suite/bugs/closed/5547.v | 16 +
test-suite/bugs/closed/5696.v | 5 +
test-suite/bugs/closed/5719.v | 9 +
test-suite/bugs/closed/7011.v | 16 +
test-suite/bugs/closed/7068.v | 6 +
test-suite/bugs/closed/7076.v | 4 +
test-suite/bugs/closed/7092.v | 70 +
test-suite/bugs/closed/7421.v | 39 +
test-suite/bugs/closed/7631.v | 2 +
test-suite/bugs/closed/7900.v | 53 +
test-suite/bugs/closed/7903.v | 4 +
test-suite/bugs/closed/8081.v | 4 +
test-suite/bugs/closed/8106.v | 4 +
test-suite/bugs/closed/8126.v | 13 +
test-suite/bugs/closed/8270.v | 15 +
test-suite/bugs/closed/8553.v | 7 +
test-suite/bugs/closed/8672.v | 5 +
test-suite/bugs/closed/bug_8544.v | 6 +
test-suite/bugs/closed/bug_8755.v | 6 +
test-suite/bugs/closed/bug_8794.v | 11 +
test-suite/bugs/closed/bug_8885.v | 8 +
test-suite/bugs/opened/3295.v | 4 +-
test-suite/check | 7 -
test-suite/complexity/injection.v | 2 +-
test-suite/coq-makefile/coqdoc1/run.sh | 10 +-
test-suite/coq-makefile/coqdoc2/run.sh | 8 +-
test-suite/coq-makefile/findlib-package/run.sh | 3 +-
test-suite/coq-makefile/mlpack1/run.sh | 2 +-
test-suite/coq-makefile/mlpack2/run.sh | 2 +-
test-suite/coq-makefile/multiroot/run.sh | 7 +-
test-suite/coq-makefile/native1/run.sh | 8 +-
test-suite/coq-makefile/plugin1/run.sh | 2 +-
test-suite/coq-makefile/plugin2/run.sh | 2 +-
test-suite/coq-makefile/plugin3/run.sh | 2 +-
test-suite/coq-makefile/quick2vo/run.sh | 4 +-
test-suite/coq-makefile/template/init.sh | 3 +-
test-suite/coq-makefile/template/path-init.sh | 1 +
.../timing/precomputed-time-tests/run.sh | 7 +-
test-suite/coq-makefile/timing/run.sh | 27 +-
test-suite/coq-makefile/uninstall1/run.sh | 7 +-
test-suite/coq-makefile/uninstall2/run.sh | 7 +-
test-suite/coq-makefile/vio2vo/run.sh | 4 +-
test-suite/coqchk/bug_8655.v | 1 +
test-suite/coqchk/bug_8876.v | 19 +
test-suite/coqchk/bug_8881.v | 23 +
test-suite/coqchk/include_primproj.v | 13 +
test-suite/coqdoc/links.html.out | 34 +-
test-suite/coqdoc/links.tex.out | 34 +-
test-suite/failure/check.v | 2 +-
test-suite/ide/undo012.fake | 1 +
test-suite/ide/undo013.fake | 1 +
test-suite/ide/undo014.fake | 1 +
test-suite/ide/undo015.fake | 1 +
test-suite/ide/undo016.fake | 1 +
test-suite/interactive/PrimNotation.v | 64 +
test-suite/misc/7595.sh | 5 +
test-suite/misc/7595/FOO.v | 39 +
test-suite/misc/7595/base.v | 28 +
test-suite/misc/7704.sh | 7 +
test-suite/misc/aux7704.v | 6 +
test-suite/misc/deps-checksum.sh | 1 +
test-suite/misc/deps-order.sh | 9 +-
test-suite/misc/deps-utf8.sh | 9 +-
test-suite/misc/exitstatus.sh | 7 +-
test-suite/misc/poly-capture-global-univs.sh | 19 +
.../misc/poly-capture-global-univs/_CoqProject | 9 +
.../misc/poly-capture-global-univs/src/evil.ml4 | 9 +
.../misc/poly-capture-global-univs/src/evilImpl.ml | 22 +
.../poly-capture-global-univs/src/evilImpl.mli | 2 +
.../src/evil_plugin.mlpack | 2 +
.../misc/poly-capture-global-univs/theories/evil.v | 13 +
test-suite/misc/printers.sh | 5 +-
test-suite/misc/universes.sh | 5 +-
test-suite/modules/PO.v | 4 +-
test-suite/modules/Przyklad.v | 2 +-
test-suite/output/Arguments_renaming.out | 6 +-
test-suite/output/BadOptionValueType.out | 8 +
test-suite/output/BadOptionValueType.v | 4 +
test-suite/output/Cases.out | 2 +
test-suite/output/Cases.v | 4 +
test-suite/output/Deprecation.out | 3 +
test-suite/output/Deprecation.v | 6 +
test-suite/output/Errors.out | 8 +
test-suite/output/Errors.v | 6 +
test-suite/output/Notations.out | 14 +-
test-suite/output/Notations3.out | 6 +
test-suite/output/Notations3.v | 11 +
test-suite/output/Notations4.out | 19 +
test-suite/output/Notations4.v | 72 +
test-suite/output/PrintInfos.out | 4 +-
test-suite/output/PrintInfos.v | 4 +-
test-suite/output/RecordMissingField.out | 4 +
test-suite/output/RecordMissingField.v | 8 +
test-suite/output/UnclosedBlocks.out | 1 -
test-suite/output/Unicode.out | 41 +
test-suite/output/Unicode.v | 28 +
test-suite/output/bug5778.out | 4 +-
test-suite/output/bug6404.out | 4 +
test-suite/output/bug6404.v | 7 +
test-suite/output/ltac.v | 3 +
test-suite/output/ltac_missing_args.out | 14 +-
test-suite/output/ssr_explain_match.out | 55 +
test-suite/output/ssr_explain_match.v | 23 +
test-suite/prerequisite/make_local.v | 3 +-
test-suite/prerequisite/ssr_mini_mathcomp.v | 1472 +++++++
test-suite/prerequisite/ssr_ssrsyntax1.v | 36 +
test-suite/report.sh | 55 +
test-suite/save-logs.sh | 19 -
test-suite/ssr/absevarprop.v | 96 +
test-suite/ssr/abstract_var2.v | 25 +
test-suite/ssr/binders.v | 55 +
test-suite/ssr/binders_of.v | 23 +
test-suite/ssr/caseview.v | 17 +
test-suite/ssr/congr.v | 34 +
test-suite/ssr/deferclear.v | 37 +
test-suite/ssr/delayed_clear_rename.v | 5 +
test-suite/ssr/dependent_type_err.v | 20 +
test-suite/ssr/derive_inversion.v | 29 +
test-suite/ssr/elim.v | 279 ++
test-suite/ssr/elim2.v | 74 +
test-suite/ssr/elim_pattern.v | 27 +
test-suite/ssr/first_n.v | 21 +
test-suite/ssr/gen_have.v | 174 +
test-suite/ssr/gen_pattern.v | 33 +
test-suite/ssr/have_TC.v | 50 +
test-suite/ssr/have_transp.v | 48 +
test-suite/ssr/have_view_idiom.v | 18 +
test-suite/ssr/havesuff.v | 85 +
test-suite/ssr/if_isnt.v | 22 +
test-suite/ssr/intro_beta.v | 25 +
test-suite/ssr/intro_noop.v | 37 +
test-suite/ssr/ipat_clear_if_id.v | 23 +
test-suite/ssr/ipatalternation.v | 18 +
test-suite/ssr/ltac_have.v | 39 +
test-suite/ssr/ltac_in.v | 26 +
test-suite/ssr/move_after.v | 19 +
test-suite/ssr/multiview.v | 58 +
test-suite/ssr/occarrow.v | 23 +
test-suite/ssr/patnoX.v | 18 +
test-suite/ssr/pattern.v | 32 +
test-suite/ssr/primproj.v | 164 +
test-suite/ssr/rewpatterns.v | 146 +
test-suite/ssr/rewrite_illtyped.v | 9 +
test-suite/ssr/set_lamda.v | 27 +
test-suite/ssr/set_pattern.v | 64 +
test-suite/ssr/ssrpattern.v | 7 +
test-suite/ssr/ssrsyntax2.v | 20 +
test-suite/ssr/tc.v | 39 +
test-suite/ssr/typeof.v | 22 +
test-suite/ssr/unfold_Opaque.v | 18 +
test-suite/ssr/unkeyed.v | 31 +
test-suite/ssr/view_case.v | 31 +
test-suite/ssr/wlog_suff.v | 28 +
test-suite/ssr/wlogletin.v | 50 +
test-suite/ssr/wlong_intro.v | 20 +
test-suite/stm/Nijmegen_QArithSternBrocot_Zaux.v | 714 ++--
test-suite/success/AdvancedTypeClasses.v | 4 +-
test-suite/success/BracketsWithGoalSelector.v | 9 +
test-suite/success/Case11.v | 4 +-
test-suite/success/Case17.v | 14 +-
test-suite/success/Compat88.v | 18 +
test-suite/success/CompatCurrentFlag.v | 4 +-
test-suite/success/CompatOldFlag.v | 4 +-
test-suite/success/CompatPreviousFlag.v | 4 +-
test-suite/success/Fourier.v | 12 -
test-suite/success/FunindExtraction_compat86.v | 506 ---
test-suite/success/Hints.v | 30 +
test-suite/success/ImplicitArguments.v | 2 +-
test-suite/success/ImplicitTactic.v | 16 -
test-suite/success/Inductive.v | 4 +-
test-suite/success/Injection.v | 12 +-
test-suite/success/Inversion.v | 4 +-
test-suite/success/LraTest.v | 14 +
test-suite/success/LtacDeprecation.v | 32 +
test-suite/success/Notations2.v | 28 +
test-suite/success/NumeralNotations.v | 302 ++
test-suite/success/ROmega4.v | 6 +-
test-suite/success/RecTutorial.v | 14 +-
test-suite/success/Record.v | 2 +-
test-suite/success/Scopes.v | 2 +-
test-suite/success/Typeclasses.v | 4 +-
test-suite/success/apply.v | 25 +-
test-suite/success/attribute-syntax.v | 23 +
test-suite/success/dependentind.v | 2 +-
test-suite/success/destruct.v | 1 +
test-suite/success/evars.v | 2 +-
test-suite/success/goal_selector.v | 14 +
test-suite/success/implicit.v | 12 +-
test-suite/success/intros.v | 24 +
test-suite/success/letproj.v | 2 +
test-suite/success/mutual_record.v | 57 +
test-suite/success/primitiveproj.v | 30 +-
test-suite/success/refine.v | 4 +-
test-suite/success/rewrite.v | 6 +-
test-suite/success/sideff.v | 2 +
test-suite/success/ssr_delayed_clear_rename.v | 5 -
test-suite/success/uniform_inductive_parameters.v | 13 +
test-suite/success/univers.v | 2 +-
test-suite/success/vm_records.v | 40 +
test-suite/tools/update-compat/run.sh | 9 +
test-suite/unit-tests/.merlin.in | 6 +
test-suite/unit-tests/clib/inteq.ml | 15 +
test-suite/unit-tests/clib/unicode_tests.ml | 17 +
test-suite/unit-tests/printing/proof_diffs_test.ml | 333 ++
test-suite/unit-tests/src/utest.ml | 76 +
test-suite/unit-tests/src/utest.mli | 18 +
test-suite/vio/numeral.v | 21 +
theories/Arith/Compare_dec.v | 6 +-
theories/Bool/Bool.v | 7 +
theories/Compat/Coq86.v | 15 -
theories/Compat/Coq88.v | 16 +
theories/Compat/Coq89.v | 11 +
theories/FSets/FMapFacts.v | 2 +-
theories/FSets/FMapFullAVL.v | 6 +-
theories/FSets/FSetEqProperties.v | 4 +-
theories/Init/Datatypes.v | 1 -
theories/Init/Decimal.v | 14 +-
theories/Init/Logic.v | 7 +
theories/Init/Nat.v | 4 +
theories/Init/Peano.v | 1 +
theories/Init/Prelude.v | 19 +-
theories/Init/Specif.v | 26 +-
theories/Logic/Berardi.v | 7 +-
theories/Logic/Diaconescu.v | 2 -
theories/Logic/EqdepFacts.v | 2 +-
theories/MSets/MSetEqProperties.v | 4 +-
theories/NArith/BinNat.v | 80 +-
theories/NArith/BinNatDef.v | 9 +
theories/NArith/Ndec.v | 4 +-
theories/NArith/Ndigits.v | 43 +
theories/NArith/Ndiv_def.v | 6 +-
theories/NArith/Nsqrt_def.v | 8 +-
theories/Numbers/AltBinNotations.v | 69 +
theories/Numbers/BinNums.v | 14 +-
theories/Numbers/Cyclic/Int31/Cyclic31.v | 20 +-
theories/Numbers/Cyclic/Int31/Int31.v | 10 +-
theories/Numbers/DecimalString.v | 20 +-
theories/Numbers/Integer/Abstract/ZBits.v | 6 +-
theories/Numbers/Integer/Abstract/ZDivEucl.v | 2 +-
theories/Numbers/Natural/Abstract/NBits.v | 6 +-
theories/PArith/BinPos.v | 82 +-
theories/PArith/BinPosDef.v | 13 +-
theories/Program/Tactics.v | 2 +-
theories/Reals/Machin.v | 36 +-
theories/Reals/PSeries_reg.v | 29 +-
theories/Reals/R_sqrt.v | 20 +-
theories/Reals/Ranalysis5.v | 90 +-
theories/Reals/Ratan.v | 238 +-
theories/Reals/Rbasic_fun.v | 4 +-
theories/Reals/Rderiv.v | 6 +-
theories/Reals/Reals.v | 1 +
theories/Reals/Rlimit.v | 8 +-
theories/Reals/Rpower.v | 24 +-
theories/Reals/Rsqrt_def.v | 2 +-
theories/Reals/Rtrigo.v | 2 +-
theories/Reals/Rtrigo1.v | 40 +-
theories/Reals/Rtrigo_calc.v | 1 -
theories/Strings/Ascii.v | 34 +
theories/Strings/BinaryString.v | 147 +
theories/Strings/HexString.v | 229 ++
theories/Strings/OctalString.v | 179 +
theories/Strings/String.v | 34 +
theories/Structures/GenericMinMax.v | 2 +-
theories/Unicode/Utf8_core.v | 6 +-
theories/Vectors/VectorDef.v | 1 +
theories/ZArith/BinInt.v | 56 +-
theories/ZArith/BinIntDef.v | 15 +-
theories/ZArith/ZArith_dec.v | 2 +-
theories/ZArith/Zabs.v | 8 +-
theories/ZArith/Zcompare.v | 14 +-
theories/ZArith/Zdiv.v | 6 +-
theories/ZArith/Zeven.v | 4 +-
theories/ZArith/Zmax.v | 18 +-
theories/ZArith/Zmin.v | 18 +-
theories/ZArith/Znumtheory.v | 28 +-
theories/ZArith/Zorder.v | 28 +-
theories/ZArith/Zpow_facts.v | 4 +-
theories/ZArith/Zquot.v | 46 +-
tools/CoqMakefile.in | 45 +-
tools/coq-font-lock.el | 137 -
tools/coq_makefile.ml | 6 +-
tools/coqdep.ml | 53 +-
tools/coqdep_common.ml | 37 +-
tools/coqdep_common.mli | 2 +
tools/coqdoc/index.ml | 16 +-
tools/coqdoc/index.mli | 2 +-
tools/coqdoc/output.ml | 6 +-
tools/coqworkmgr.ml | 2 +-
tools/fake_ide.ml | 22 +-
tools/gallina-db.el | 240 --
tools/gallina-syntax.el | 980 -----
tools/gallina.el | 142 -
tools/gallina.ml | 63 -
tools/gallina_lexer.mll | 126 -
tools/inferior-coq.el | 324 --
topbin/coqproofworker_bin.ml | 14 +
topbin/coqqueryworker_bin.ml | 13 +
topbin/coqtacticworker_bin.ml | 13 +
topbin/coqtop_bin.ml | 16 +
topbin/coqtop_byte_bin.ml | 34 +
toplevel/coqargs.ml | 51 +-
toplevel/coqargs.mli | 4 +-
toplevel/coqinit.ml | 32 +-
toplevel/coqinit.mli | 4 +-
toplevel/coqloop.ml | 217 +-
toplevel/coqloop.mli | 17 +-
toplevel/coqtop.ml | 220 +-
toplevel/coqtop.mli | 24 +-
toplevel/coqtop_byte_bin.ml | 34 -
toplevel/coqtop_opt_bin.ml | 16 -
toplevel/g_toplevel.mlg | 54 +
toplevel/toplevel.mllib | 4 +-
toplevel/usage.ml | 3 +-
toplevel/vernac.ml | 36 +-
toplevel/vernac.mli | 5 +-
toplevel/workerLoop.ml | 29 +
toplevel/workerLoop.mli | 14 +
vernac/assumptions.mli | 4 +-
vernac/auto_ind_decl.ml | 54 +-
vernac/auto_ind_decl.mli | 2 +-
vernac/class.ml | 24 +-
vernac/class.mli | 9 +-
vernac/classes.ml | 63 +-
vernac/classes.mli | 16 +-
vernac/comAssumption.ml | 11 +-
vernac/comAssumption.mli | 9 +-
vernac/comDefinition.ml | 48 +-
vernac/comDefinition.mli | 2 +-
vernac/comFixpoint.ml | 22 +-
vernac/comFixpoint.mli | 14 +-
vernac/comInductive.ml | 157 +-
vernac/comInductive.mli | 11 +-
vernac/comProgramFixpoint.ml | 24 +-
vernac/declareDef.mli | 10 +-
vernac/egramcoq.ml | 537 +++
vernac/egramcoq.mli | 22 +
vernac/egramml.ml | 93 +
vernac/egramml.mli | 35 +
vernac/explainErr.ml | 6 +-
vernac/g_proofs.mlg | 140 +
vernac/g_vernac.mlg | 1208 ++++++
vernac/himsg.ml | 121 +-
vernac/himsg.mli | 4 +
vernac/indschemes.ml | 2 +-
vernac/indschemes.mli | 6 +-
vernac/lemmas.ml | 30 +-
vernac/lemmas.mli | 10 +-
vernac/metasyntax.ml | 413 +-
vernac/metasyntax.mli | 3 +-
vernac/misctypes.ml | 75 +
vernac/mltop.ml | 9 -
vernac/mltop.mli | 3 -
vernac/obligations.ml | 68 +-
vernac/obligations.mli | 11 +-
vernac/ppvernac.ml | 1231 ++++++
vernac/ppvernac.mli | 26 +
vernac/proof_using.ml | 12 +-
vernac/pvernac.ml | 55 +
vernac/pvernac.mli | 36 +
vernac/record.ml | 307 +-
vernac/record.mli | 18 +-
vernac/search.ml | 25 +-
vernac/search.mli | 5 +-
vernac/topfmt.ml | 155 +-
vernac/topfmt.mli | 11 +-
vernac/vernac.mllib | 17 +-
vernac/vernacentries.ml | 534 ++-
vernac/vernacentries.mli | 40 +-
vernac/vernacexpr.ml | 539 +++
vernac/vernacinterp.ml | 12 +-
vernac/vernacinterp.mli | 10 +-
vernac/vernacprop.ml | 1 -
1190 files changed, 50557 insertions(+), 42015 deletions(-)
delete mode 100644 .bintray.json
delete mode 100644 .merlin
create mode 100644 .merlin.in
delete mode 100644 .travis.yml
delete mode 100644 CHANGES
create mode 100644 CHANGES.md
delete mode 100644 INSTALL.doc
delete mode 100644 INSTALL.ide
delete mode 100644 META.coq
create mode 100644 META.coq.in
create mode 100644 Makefile.vofiles
delete mode 100644 clib/canary.ml
delete mode 100644 clib/canary.mli
create mode 100644 clib/diff2.ml
create mode 100644 clib/diff2.mli
create mode 100644 coqpp/coqpp_ast.mli
create mode 100644 coqpp/coqpp_lex.mll
create mode 100644 coqpp/coqpp_main.ml
create mode 100644 coqpp/coqpp_parse.mly
delete mode 100644 dev/README
create mode 100644 dev/README.md
create mode 100755 dev/build/windows/patches_coq/VST.patch
delete mode 100644 dev/build/windows/patches_coq/aactactis-86ac28259030649ef51460e4de2441c8a1017751.patch
delete mode 100644 dev/build/windows/patches_coq/quickchick-v1.0.2.patch
create mode 100755 dev/build/windows/patches_coq/quickchick.patch
create mode 100644 dev/checker.dbg
create mode 100644 dev/checker_db
create mode 100644 dev/checker_printers.ml
create mode 100644 dev/checker_printers.mli
create mode 100755 dev/ci/ci-cross-crypto.sh
create mode 100755 dev/ci/ci-pidetop.sh
create mode 100644 dev/ci/docker/README.md
create mode 100644 dev/ci/user-overlays/07085-ppedrot-pure-sharing-flag.sh
create mode 100644 dev/doc/MERGING.md
create mode 100644 dev/doc/README.md
create mode 100644 dev/doc/critical-bugs
create mode 100644 dev/doc/release-process.md
delete mode 100644 dev/doc/setup.txt
delete mode 100644 dev/doc/translate.txt
create mode 100755 dev/tools/check-overlays.sh
create mode 100755 dev/tools/check-owners-pr.sh
create mode 100755 dev/tools/check-owners.sh
create mode 100755 dev/tools/update-compat.py
create mode 100644 doc/README.md
create mode 100644 engine/evar_kinds.ml
create mode 100644 engine/evar_kinds.mli
create mode 100644 engine/univGen.ml
create mode 100644 engine/univGen.mli
create mode 100644 engine/univMinim.ml
create mode 100644 engine/univMinim.mli
create mode 100644 engine/univNames.ml
create mode 100644 engine/univNames.mli
create mode 100644 engine/univProblem.ml
create mode 100644 engine/univProblem.mli
create mode 100644 engine/univSubst.ml
create mode 100644 engine/univSubst.mli
delete mode 100644 ide/.merlin
create mode 100644 ide/.merlin.in
delete mode 100755 ide/MacOS/relatify_with-respect-to_.sh
create mode 100644 ide/configwin.ml
create mode 100644 ide/configwin.mli
create mode 100644 ide/configwin_ihm.ml
create mode 100644 ide/configwin_ihm.mli
create mode 100644 ide/configwin_messages.ml
create mode 100644 ide/configwin_types.ml
delete mode 100644 ide/coqidetop.mllib
create mode 100644 ide/ide_common.mllib
delete mode 100644 ide/ide_slave.ml
delete mode 100644 ide/ide_slave.mli
create mode 100644 ide/idetop.ml
delete mode 100644 ide/interface.mli
create mode 100644 ide/protocol/ideprotocol.mllib
create mode 100644 ide/protocol/interface.ml
create mode 100644 ide/protocol/richpp.ml
create mode 100644 ide/protocol/richpp.mli
create mode 100644 ide/protocol/serialize.ml
create mode 100644 ide/protocol/serialize.mli
create mode 100644 ide/protocol/xml_lexer.mli
create mode 100644 ide/protocol/xml_lexer.mll
create mode 100644 ide/protocol/xml_parser.ml
create mode 100644 ide/protocol/xml_parser.mli
create mode 100644 ide/protocol/xml_printer.ml
create mode 100644 ide/protocol/xml_printer.mli
create mode 100644 ide/protocol/xmlprotocol.ml
create mode 100644 ide/protocol/xmlprotocol.mli
delete mode 100644 ide/richpp.ml
delete mode 100644 ide/richpp.mli
delete mode 100644 ide/serialize.ml
delete mode 100644 ide/serialize.mli
delete mode 100644 ide/utils/configwin.ml
delete mode 100644 ide/utils/configwin.mli
delete mode 100644 ide/utils/configwin_ihm.ml
delete mode 100644 ide/utils/configwin_ihm.mli
delete mode 100644 ide/utils/configwin_messages.ml
delete mode 100644 ide/utils/configwin_types.mli
delete mode 100644 ide/xml_lexer.mli
delete mode 100644 ide/xml_lexer.mll
delete mode 100644 ide/xml_parser.ml
delete mode 100644 ide/xml_parser.mli
delete mode 100644 ide/xml_printer.ml
delete mode 100644 ide/xml_printer.mli
delete mode 100644 ide/xmlprotocol.ml
delete mode 100644 ide/xmlprotocol.mli
create mode 100644 interp/constrexpr.ml
create mode 100644 interp/genredexpr.ml
create mode 100644 interp/notation_term.ml
delete mode 100644 interp/ppextend.ml
delete mode 100644 interp/ppextend.mli
create mode 100644 interp/redops.ml
create mode 100644 interp/redops.mli
delete mode 100644 interp/tactypes.ml
delete mode 100644 interp/topconstr.ml
delete mode 100644 interp/topconstr.mli
delete mode 100644 intf/constrexpr.ml
delete mode 100644 intf/decl_kinds.ml
delete mode 100644 intf/evar_kinds.ml
delete mode 100644 intf/extend.ml
delete mode 100644 intf/genredexpr.ml
delete mode 100644 intf/glob_term.ml
delete mode 100644 intf/intf.mllib
delete mode 100644 intf/locus.ml
delete mode 100644 intf/misctypes.ml
delete mode 100644 intf/notation_term.ml
delete mode 100644 intf/pattern.ml
delete mode 100644 intf/vernacexpr.ml
delete mode 100644 kernel/pre_env.ml
delete mode 100644 kernel/pre_env.mli
create mode 100644 lib/coqProject_file.ml
delete mode 100644 lib/coqProject_file.ml4
create mode 100644 lib/pp_diff.ml
create mode 100644 lib/pp_diff.mli
create mode 100644 library/decl_kinds.ml
delete mode 100644 library/heads.ml
delete mode 100644 library/heads.mli
delete mode 100644 man/gallina.1
delete mode 100644 parsing/egramcoq.ml
delete mode 100644 parsing/egramcoq.mli
delete mode 100644 parsing/egramml.ml
delete mode 100644 parsing/egramml.mli
create mode 100644 parsing/extend.ml
delete mode 100644 parsing/g_constr.ml4
create mode 100644 parsing/g_constr.mlg
delete mode 100644 parsing/g_prim.ml4
create mode 100644 parsing/g_prim.mlg
delete mode 100644 parsing/g_proofs.ml4
delete mode 100644 parsing/g_vernac.ml4
create mode 100644 parsing/notation_gram.ml
create mode 100644 parsing/notgram_ops.ml
create mode 100644 parsing/notgram_ops.mli
create mode 100644 parsing/ppextend.ml
create mode 100644 parsing/ppextend.mli
delete mode 100644 plugins/.merlin
create mode 100644 plugins/.merlin.in
delete mode 100644 plugins/btauto/g_btauto.ml4
create mode 100644 plugins/btauto/g_btauto.mlg
delete mode 100644 plugins/cc/g_congruence.ml4
create mode 100644 plugins/cc/g_congruence.mlg
delete mode 100644 plugins/fourier/Fourier.v
delete mode 100644 plugins/fourier/Fourier_util.v
delete mode 100644 plugins/fourier/fourier.ml
delete mode 100644 plugins/fourier/fourierR.ml
delete mode 100644 plugins/fourier/fourier_plugin.mlpack
delete mode 100644 plugins/fourier/g_fourier.ml4
delete mode 100644 plugins/ltac/coretactics.ml4
create mode 100644 plugins/ltac/coretactics.mlg
delete mode 100644 plugins/ltac/g_eqdecide.ml4
create mode 100644 plugins/ltac/g_eqdecide.mlg
delete mode 100644 plugins/ltac/g_tactic.ml4
create mode 100644 plugins/ltac/g_tactic.mlg
create mode 100644 plugins/micromega/Fourier.v
create mode 100644 plugins/micromega/Fourier_util.v
create mode 100644 plugins/micromega/certificate.mli
create mode 100644 plugins/micromega/coq_micromega.mli
create mode 100644 plugins/micromega/csdpcert.mli
delete mode 100644 plugins/micromega/g_micromega.ml4
create mode 100644 plugins/micromega/g_micromega.mlg
create mode 100644 plugins/micromega/g_micromega.mli
create mode 100644 plugins/micromega/mfourier.mli
create mode 100644 plugins/micromega/mutils.mli
create mode 100644 plugins/micromega/persistent_cache.mli
create mode 100644 plugins/micromega/polynomial.mli
create mode 100644 plugins/micromega/sos_lib.mli
delete mode 100644 plugins/nsatz/g_nsatz.ml4
create mode 100644 plugins/nsatz/g_nsatz.mlg
delete mode 100644 plugins/omega/g_omega.ml4
create mode 100644 plugins/omega/g_omega.mlg
delete mode 100644 plugins/quote/g_quote.ml4
create mode 100644 plugins/quote/g_quote.mlg
delete mode 100644 plugins/romega/g_romega.ml4
create mode 100644 plugins/romega/g_romega.mlg
delete mode 100644 plugins/rtauto/g_rtauto.ml4
create mode 100644 plugins/rtauto/g_rtauto.mlg
create mode 100644 plugins/ssrmatching/g_ssrmatching.ml4
create mode 100644 plugins/ssrmatching/ssrmatching.ml
delete mode 100644 plugins/ssrmatching/ssrmatching.ml4
create mode 100644 plugins/ssrmatching/ssrmatching.mli
create mode 100644 plugins/ssrmatching/ssrmatching.v
create mode 100644 plugins/syntax/g_numeral.ml4
delete mode 100644 plugins/syntax/nat_syntax.ml
delete mode 100644 plugins/syntax/nat_syntax_plugin.mlpack
create mode 100644 plugins/syntax/numeral.ml
create mode 100644 plugins/syntax/numeral.mli
create mode 100644 plugins/syntax/numeral_notation_plugin.mlpack
delete mode 100644 plugins/syntax/z_syntax.ml
delete mode 100644 plugins/syntax/z_syntax_plugin.mlpack
create mode 100644 pretyping/glob_term.ml
create mode 100644 pretyping/heads.ml
create mode 100644 pretyping/heads.mli
create mode 100644 pretyping/locus.ml
delete mode 100644 pretyping/miscops.ml
delete mode 100644 pretyping/miscops.mli
create mode 100644 pretyping/pattern.ml
delete mode 100644 pretyping/redops.ml
delete mode 100644 pretyping/redops.mli
delete mode 100644 pretyping/univdecls.ml
delete mode 100644 pretyping/univdecls.mli
delete mode 100644 printing/ppvernac.ml
delete mode 100644 printing/ppvernac.mli
create mode 100644 printing/proof_diffs.ml
create mode 100644 printing/proof_diffs.mli
create mode 100644 proofs/goal_select.ml
create mode 100644 proofs/goal_select.mli
create mode 100644 proofs/tactypes.ml
delete mode 100644 stm/proofworkertop.ml
delete mode 100644 stm/proofworkertop.mllib
delete mode 100644 stm/queryworkertop.ml
delete mode 100644 stm/queryworkertop.mllib
delete mode 100644 stm/tacworkertop.ml
delete mode 100644 stm/tacworkertop.mllib
delete mode 100644 stm/workerLoop.ml
delete mode 100644 stm/workerLoop.mli
delete mode 100644 test-suite/bugs/closed/4882.v
create mode 100644 test-suite/bugs/closed/5012.v
create mode 100644 test-suite/bugs/closed/5500.v
create mode 100644 test-suite/bugs/closed/5547.v
create mode 100644 test-suite/bugs/closed/5696.v
create mode 100644 test-suite/bugs/closed/5719.v
create mode 100644 test-suite/bugs/closed/7011.v
create mode 100644 test-suite/bugs/closed/7068.v
create mode 100644 test-suite/bugs/closed/7076.v
create mode 100644 test-suite/bugs/closed/7092.v
create mode 100644 test-suite/bugs/closed/7421.v
create mode 100644 test-suite/bugs/closed/7900.v
create mode 100644 test-suite/bugs/closed/7903.v
create mode 100644 test-suite/bugs/closed/8081.v
create mode 100644 test-suite/bugs/closed/8106.v
create mode 100644 test-suite/bugs/closed/8126.v
create mode 100644 test-suite/bugs/closed/8270.v
create mode 100644 test-suite/bugs/closed/8553.v
create mode 100644 test-suite/bugs/closed/8672.v
create mode 100644 test-suite/bugs/closed/bug_8544.v
create mode 100644 test-suite/bugs/closed/bug_8755.v
create mode 100644 test-suite/bugs/closed/bug_8794.v
create mode 100644 test-suite/bugs/closed/bug_8885.v
delete mode 100755 test-suite/check
create mode 100644 test-suite/coqchk/bug_8655.v
create mode 100644 test-suite/coqchk/bug_8876.v
create mode 100644 test-suite/coqchk/bug_8881.v
create mode 100644 test-suite/coqchk/include_primproj.v
create mode 100644 test-suite/interactive/PrimNotation.v
create mode 100755 test-suite/misc/7595.sh
create mode 100644 test-suite/misc/7595/FOO.v
create mode 100644 test-suite/misc/7595/base.v
create mode 100755 test-suite/misc/7704.sh
create mode 100644 test-suite/misc/aux7704.v
create mode 100755 test-suite/misc/poly-capture-global-univs.sh
create mode 100644 test-suite/misc/poly-capture-global-univs/_CoqProject
create mode 100644 test-suite/misc/poly-capture-global-univs/src/evil.ml4
create mode 100644 test-suite/misc/poly-capture-global-univs/src/evilImpl.ml
create mode 100644 test-suite/misc/poly-capture-global-univs/src/evilImpl.mli
create mode 100644 test-suite/misc/poly-capture-global-univs/src/evil_plugin.mlpack
create mode 100644 test-suite/misc/poly-capture-global-univs/theories/evil.v
create mode 100644 test-suite/output/BadOptionValueType.out
create mode 100644 test-suite/output/BadOptionValueType.v
create mode 100644 test-suite/output/Deprecation.out
create mode 100644 test-suite/output/Deprecation.v
create mode 100644 test-suite/output/Notations4.out
create mode 100644 test-suite/output/Notations4.v
create mode 100644 test-suite/output/RecordMissingField.out
create mode 100644 test-suite/output/RecordMissingField.v
create mode 100644 test-suite/output/Unicode.out
create mode 100644 test-suite/output/Unicode.v
create mode 100644 test-suite/output/bug6404.out
create mode 100644 test-suite/output/bug6404.v
create mode 100644 test-suite/output/ssr_explain_match.out
create mode 100644 test-suite/output/ssr_explain_match.v
create mode 100644 test-suite/prerequisite/ssr_mini_mathcomp.v
create mode 100644 test-suite/prerequisite/ssr_ssrsyntax1.v
create mode 100755 test-suite/report.sh
delete mode 100755 test-suite/save-logs.sh
create mode 100644 test-suite/ssr/absevarprop.v
create mode 100644 test-suite/ssr/abstract_var2.v
create mode 100644 test-suite/ssr/binders.v
create mode 100644 test-suite/ssr/binders_of.v
create mode 100644 test-suite/ssr/caseview.v
create mode 100644 test-suite/ssr/congr.v
create mode 100644 test-suite/ssr/deferclear.v
create mode 100644 test-suite/ssr/delayed_clear_rename.v
create mode 100644 test-suite/ssr/dependent_type_err.v
create mode 100644 test-suite/ssr/derive_inversion.v
create mode 100644 test-suite/ssr/elim.v
create mode 100644 test-suite/ssr/elim2.v
create mode 100644 test-suite/ssr/elim_pattern.v
create mode 100644 test-suite/ssr/first_n.v
create mode 100644 test-suite/ssr/gen_have.v
create mode 100644 test-suite/ssr/gen_pattern.v
create mode 100644 test-suite/ssr/have_TC.v
create mode 100644 test-suite/ssr/have_transp.v
create mode 100644 test-suite/ssr/have_view_idiom.v
create mode 100644 test-suite/ssr/havesuff.v
create mode 100644 test-suite/ssr/if_isnt.v
create mode 100644 test-suite/ssr/intro_beta.v
create mode 100644 test-suite/ssr/intro_noop.v
create mode 100644 test-suite/ssr/ipat_clear_if_id.v
create mode 100644 test-suite/ssr/ipatalternation.v
create mode 100644 test-suite/ssr/ltac_have.v
create mode 100644 test-suite/ssr/ltac_in.v
create mode 100644 test-suite/ssr/move_after.v
create mode 100644 test-suite/ssr/multiview.v
create mode 100644 test-suite/ssr/occarrow.v
create mode 100644 test-suite/ssr/patnoX.v
create mode 100644 test-suite/ssr/pattern.v
create mode 100644 test-suite/ssr/primproj.v
create mode 100644 test-suite/ssr/rewpatterns.v
create mode 100644 test-suite/ssr/rewrite_illtyped.v
create mode 100644 test-suite/ssr/set_lamda.v
create mode 100644 test-suite/ssr/set_pattern.v
create mode 100644 test-suite/ssr/ssrpattern.v
create mode 100644 test-suite/ssr/ssrsyntax2.v
create mode 100644 test-suite/ssr/tc.v
create mode 100644 test-suite/ssr/typeof.v
create mode 100644 test-suite/ssr/unfold_Opaque.v
create mode 100644 test-suite/ssr/unkeyed.v
create mode 100644 test-suite/ssr/view_case.v
create mode 100644 test-suite/ssr/wlog_suff.v
create mode 100644 test-suite/ssr/wlogletin.v
create mode 100644 test-suite/ssr/wlong_intro.v
create mode 100644 test-suite/success/Compat88.v
delete mode 100644 test-suite/success/Fourier.v
delete mode 100644 test-suite/success/FunindExtraction_compat86.v
delete mode 100644 test-suite/success/ImplicitTactic.v
create mode 100644 test-suite/success/LraTest.v
create mode 100644 test-suite/success/LtacDeprecation.v
create mode 100644 test-suite/success/NumeralNotations.v
create mode 100644 test-suite/success/attribute-syntax.v
create mode 100644 test-suite/success/mutual_record.v
delete mode 100644 test-suite/success/ssr_delayed_clear_rename.v
create mode 100644 test-suite/success/uniform_inductive_parameters.v
create mode 100644 test-suite/success/vm_records.v
create mode 100755 test-suite/tools/update-compat/run.sh
create mode 100644 test-suite/unit-tests/.merlin.in
create mode 100644 test-suite/unit-tests/clib/inteq.ml
create mode 100644 test-suite/unit-tests/clib/unicode_tests.ml
create mode 100644 test-suite/unit-tests/printing/proof_diffs_test.ml
create mode 100644 test-suite/unit-tests/src/utest.ml
create mode 100644 test-suite/unit-tests/src/utest.mli
create mode 100644 test-suite/vio/numeral.v
delete mode 100644 theories/Compat/Coq86.v
create mode 100644 theories/Compat/Coq89.v
create mode 100644 theories/Numbers/AltBinNotations.v
create mode 100644 theories/Strings/BinaryString.v
create mode 100644 theories/Strings/HexString.v
create mode 100644 theories/Strings/OctalString.v
delete mode 100644 tools/coq-font-lock.el
delete mode 100644 tools/gallina-db.el
delete mode 100644 tools/gallina-syntax.el
delete mode 100644 tools/gallina.el
delete mode 100644 tools/gallina.ml
delete mode 100644 tools/gallina_lexer.mll
delete mode 100644 tools/inferior-coq.el
create mode 100644 topbin/coqproofworker_bin.ml
create mode 100644 topbin/coqqueryworker_bin.ml
create mode 100644 topbin/coqtacticworker_bin.ml
create mode 100644 topbin/coqtop_bin.ml
create mode 100644 topbin/coqtop_byte_bin.ml
delete mode 100644 toplevel/coqtop_byte_bin.ml
delete mode 100644 toplevel/coqtop_opt_bin.ml
create mode 100644 toplevel/g_toplevel.mlg
create mode 100644 toplevel/workerLoop.ml
create mode 100644 toplevel/workerLoop.mli
create mode 100644 vernac/egramcoq.ml
create mode 100644 vernac/egramcoq.mli
create mode 100644 vernac/egramml.ml
create mode 100644 vernac/egramml.mli
create mode 100644 vernac/g_proofs.mlg
create mode 100644 vernac/g_vernac.mlg
create mode 100644 vernac/misctypes.ml
create mode 100644 vernac/ppvernac.ml
create mode 100644 vernac/ppvernac.mli
create mode 100644 vernac/pvernac.ml
create mode 100644 vernac/pvernac.mli
create mode 100644 vernac/vernacexpr.ml
diff --git a/.bintray.json b/.bintray.json
deleted file mode 100644
index 34a501e8..00000000
--- a/.bintray.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "package": {
- "name": "coq",
- "repo": "coq",
- "subject": "coq"
- },
-
- "version": {
- "name": "8.8.2"
- },
-
- "files":
- [
- {"includePattern": "_build/(.*\\.dmg)", "uploadPattern": "$1",
- "matrixParams": {
- "override": 1 }
- }
- ],
- "publish": true
-}
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index a9230042..73b61ee0 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -10,7 +10,10 @@
Fixes / closes #????
+
+
+- [ ] Added / updated test-suite
-- [ ] Corresponding documentation was added / updated.
-- [ ] Entry added in CHANGES.
+- [ ] Corresponding documentation was added / updated (including any warning and error messages added / removed / modified).
+- [ ] Entry added in CHANGES.md.
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 799f5b14..b936401a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -9,12 +9,13 @@ stages:
variables:
# Format: $IMAGE-V$DATE [Cache is not used as of today but kept here
# for reference]
- CACHEKEY: "bionic_coq-v8.8-V2018-09-20"
+ CACHEKEY: "bionic_coq-v8.9-V2018-10-22"
IMAGE: "$CI_REGISTRY_IMAGE:$CACHEKEY"
# By default, jobs run in the base switch; override to select another switch
OPAM_SWITCH: "base"
# Used to select special compiler switches such as flambda, 32bits, etc...
OPAM_VARIANT: ""
+ GIT_DEPTH: "10"
docker-boot:
stage: docker
@@ -37,11 +38,11 @@ docker-boot:
before_script:
- cat /proc/{cpu,mem}info || true
- ls -a # figure out if artifacts are around
- - printenv | sort
+ - printenv -0 | sort -z | tr '\0' '\n'
- declare -A switch_table
- switch_table=( ["base"]="$COMPILER" ["edge"]="$COMPILER_EDGE" )
- - opam switch -y "${switch_table[$OPAM_SWITCH]}$OPAM_VARIANT"
- - eval $(opam config env)
+ - opam switch set -y "${switch_table[$OPAM_SWITCH]}$OPAM_VARIANT"
+ - eval $(opam env)
- opam list
- opam config list
@@ -60,23 +61,28 @@ after_script:
paths:
- _install_ci
- config/Makefile
+ - config/coq_config.py
- test-suite/misc/universes/all_stdlib.v
expire_in: 1 week
script:
- set -e
+ - echo 'start:coq.clean'
+ - make clean # ensure that `make clean` works on a fresh clone
+ - echo 'end:coq.clean'
+
- echo 'start:coq.config'
- ./configure -warn-error yes -prefix "$(pwd)/_install_ci" ${COQ_EXTRA_CONF}"$COQ_EXTRA_CONF_QUOTE"
- echo 'end:coq.config'
- echo 'start:coq.build'
- make -j "$NJOBS" byte
- - make -j "$NJOBS"
+ - make -j "$NJOBS" world $EXTRA_TARGET
- make test-suite/misc/universes/all_stdlib.v
- echo 'end:coq:build'
- echo 'start:coq.install'
- - make install
+ - make install install-byte $EXTRA_INSTALL
- make install-byte
- cp bin/fake_ide _install_ci/bin/
- echo 'end:coq.install'
@@ -88,6 +94,19 @@ after_script:
# purpose, we add a spurious dependency `not-a-real-job` that must be
# overridden otherwise the CI will fail.
+.doc-template: &doc-template
+ stage: test
+ dependencies:
+ - not-a-real-job
+ script:
+ - SPHINXENV='COQBIN="'"$PWD"'/_install_ci/bin/" COQBOOT=no'
+ - make -j "$NJOBS" SPHINXENV="$SPHINXENV" SPHINX_DEPS= refman
+ - make install-doc-sphinx
+ artifacts:
+ name: "$CI_JOB_NAME"
+ paths:
+ - _install_ci/share/doc/coq/
+
# set dependencies when using
.test-suite-template: &test-suite-template
stage: test
@@ -155,12 +174,15 @@ after_script:
- call dev/ci/gitlab.bat
only:
variables:
- - $WINDOWS == "enabled"
+ - $WINDOWS =~ /enabled/
build:base:
<<: *build-template
variables:
- COQ_EXTRA_CONF: "-native-compiler yes -coqide opt -with-doc yes"
+ COQ_EXTRA_CONF: "-native-compiler yes -coqide opt"
+ # coqdoc for stdlib, until we know how to build it from installed Coq
+ EXTRA_TARGET: "stdlib"
+ EXTRA_INSTALL: "install-doc-stdlib-html install-doc-printable"
# no coqide for 32bit: libgtk installation problems
build:base+32bit:
@@ -225,6 +247,42 @@ pkg:nix:
paths:
- nix-build-coq.drv-0/*/test-suite/logs
+build:macOS:
+ stage: build
+ artifacts:
+ name: "$CI_JOB_NAME"
+ paths:
+ - _build
+ expire_in: 1 week
+ tags:
+ - macOS
+ dependencies: []
+ before_script: []
+ script:
+ - dev/build/osx/make-macos-dmg.sh
+ variables:
+ NJOBS: "2"
+ only:
+ variables:
+ - $MACOS == "enabled"
+
+doc:refman:
+ <<: *doc-template
+ dependencies:
+ - build:base
+
+doc:ml-api:
+ stage: test
+ dependencies:
+ - build:edge
+ script:
+ - ./configure -warn-error yes -prefix "$(pwd)/_install_ci"
+ - make mli-doc source-doc # ml-doc [broken in 4.07.0]
+ artifacts:
+ name: "$CI_JOB_NAME"
+ paths:
+ - dev/ocamldoc
+
test-suite:base:
<<: *test-suite-template
dependencies:
@@ -297,6 +355,9 @@ ci-coq-dpdgraph:
ci-coquelicot:
<<: *ci-template
+ci-cross-crypto:
+ <<: *ci-template
+
ci-elpi:
<<: *ci-template
@@ -336,12 +397,15 @@ ci-ltac2:
ci-math-comp:
<<: *ci-template-flambda
-ci-quickchick:
- <<: *ci-template-flambda
-
ci-mtac2:
<<: *ci-template
+ci-pidetop:
+ <<: *ci-template
+
+ci-quickchick:
+ <<: *ci-template-flambda
+
ci-sf:
<<: *ci-template
diff --git a/.merlin b/.merlin
deleted file mode 100644
index d60f5037..00000000
--- a/.merlin
+++ /dev/null
@@ -1,54 +0,0 @@
-FLG -rectypes -thread -safe-string -w +a-4-9-27-41-42-44-45-48-50
-
-S clib
-B clib
-S config
-B config
-S lib
-B lib
-S kernel
-B kernel
-S kernel/byterun
-B kernel/byterun
-S intf
-B intf
-S library
-B library
-S engine
-B engine
-S pretyping
-B pretyping
-S interp
-B interp
-S proofs
-B proofs
-S tactics
-B tactics
-S printing
-B printing
-S parsing
-B parsing
-S stm
-B stm
-S vernac
-B vernac
-S toplevel
-B toplevel
-S plugins/ltac
-B plugins/ltac
-S API
-B API
-S ide
-B ide
-
-S tools
-B tools
-S tools/coqdoc
-B tools/coqdoc
-S dev
-B dev
-
-S plugins/**
-B plugins/**
-
-PKG threads.posix camlp5
diff --git a/.merlin.in b/.merlin.in
new file mode 100644
index 00000000..404a7e79
--- /dev/null
+++ b/.merlin.in
@@ -0,0 +1,54 @@
+FLG -rectypes -thread -safe-string -w +a-4-9-27-41-42-44-45-48-50
+
+S clib
+B clib
+S config
+B config
+S lib
+B lib
+S kernel
+B kernel
+S kernel/byterun
+B kernel/byterun
+S library
+B library
+S engine
+B engine
+S pretyping
+B pretyping
+S interp
+B interp
+S proofs
+B proofs
+S tactics
+B tactics
+S printing
+B printing
+S parsing
+B parsing
+S stm
+B stm
+S vernac
+B vernac
+S toplevel
+B toplevel
+S topbin
+B topbin
+S plugins/ltac
+B plugins/ltac
+S API
+B API
+S ide
+B ide
+
+S tools
+B tools
+S tools/coqdoc
+B tools/coqdoc
+S dev
+B dev
+
+S plugins/**
+B plugins/**
+
+PKG threads.posix camlp5
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index f20599ed..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,235 +0,0 @@
-dist: trusty
-
-# Travis builds are slower using sudo: false (the container-based
-# infrastructure) as of March 2017; see
-# https://github.com/coq/coq/pull/467 for some discussion.
-sudo: required
-
-# Until Ocaml becomes a language, we set a known one.
-language: c
-
-cache:
- apt: true
- directories:
- - $HOME/.opam
-
-before_cache:
- - rm -rf ~/.opam/log/
-
-addons:
- apt:
- sources:
- - avsm
-## Due to issues like
-## https://github.com/travis-ci/travis-ci/issues/8507 ,
-## https://github.com/travis-ci/travis-ci/issues/9000 ,
-## https://github.com/travis-ci/travis-ci/issues/9081 , and
-## https://github.com/travis-ci/travis-ci/issues/9126 , we get frequent
-## failures with using `packages`. Therefore, for most targets, we
-## instead invoke `apt-get update` manually with `travis_retry` before
-## invoking `apt-get install`, manually, below in the `install:`
-## target.
-# packages:
-# - opam
-# - aspcud
-# - gcc-multilib
-
-env:
- global:
- - NJOBS=2
- # system is == 4.02.3
- - COMPILER="system"
- - COMPILER_BE="4.07.0"
- - DUNE_VER=".1.0.0"
- - CAMLP5_VER=".6.14"
- - CAMLP5_VER_BE=".7.06"
- - FINDLIB_VER=".1.4.1"
- - FINDLIB_VER_BE=".1.8.0"
- - LABLGTK="lablgtk.2.18.3 conf-gtksourceview.2"
- - LABLGTK_BE="lablgtk.2.18.6 conf-gtksourceview.2"
- - NATIVE_COMP="yes"
- - COQ_DEST="-local"
- - MAIN_TARGET="world"
-
-matrix:
-
- include:
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="test-suite" COMPILER="4.02.3+32bit"
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="validate" TW="travis_wait"
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="validate" COMPILER="4.02.3+32bit" TW="travis_wait"
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="validate" COMPILER="${COMPILER_BE}+flambda" CAMLP5_VER="${CAMLP5_VER_BE}" EXTRA_CONF="-flambda-opts -O3" FINDLIB_VER="${FINDLIB_VER_BE}"
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="ci-coq-dpdgraph" EXTRA_OPAM="ocamlgraph"
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="ci-coquelicot"
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="ci-equations"
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="ci-flocq"
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="ci-hott"
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="ci-ltac2"
-
- - env:
- - TEST_TARGET="lint"
- install: []
- before_script: []
- addons:
- apt:
- sources: []
- packages: []
- script:
- - dev/lint-repository.sh
-
- # Full Coq test-suite with two compilers
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="sphinx test-suite"
- - EXTRA_CONF="-coqide opt"
- - EXTRA_OPAM="hevea ${LABLGTK}"
- before_install: &sphinx-install
- - sudo pip3 install bs4 sphinx sphinx_rtd_theme pexpect antlr4-python3-runtime sphinxcontrib-bibtex
- addons:
- apt:
- sources:
- - avsm
- packages: &extra-packages
- - opam
- - aspcud
- - libgtk2.0-dev
- - libgtksourceview2.0-dev
- - python3
- - python3-pip
- - python3-setuptools
-
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="sphinx test-suite"
- - COMPILER="${COMPILER_BE}"
- - FINDLIB_VER="${FINDLIB_VER_BE}"
- - CAMLP5_VER="${CAMLP5_VER_BE}"
- - EXTRA_CONF="-coqide opt"
- - EXTRA_OPAM="hevea ${LABLGTK_BE}"
- before_install: *sphinx-install
- addons:
- apt:
- sources:
- - avsm
- packages: *extra-packages
-
- # Full test-suite with flambda
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="sphinx test-suite"
- - COMPILER="${COMPILER_BE}+flambda"
- - FINDLIB_VER="${FINDLIB_VER_BE}"
- - CAMLP5_VER="${CAMLP5_VER_BE}"
- - EXTRA_CONF="-coqide opt -flambda-opts -O3"
- - EXTRA_OPAM="hevea ${LABLGTK_BE}"
- before_install: *sphinx-install
- addons:
- apt:
- sources:
- - avsm
- packages: *extra-packages
-
- - os: osx
- env:
- - TEST_TARGET="test-suite"
- - COMPILER="${COMPILER_BE}"
- - FINDLIB_VER="${FINDLIB_VER_BE}"
- - CAMLP5_VER="${CAMLP5_VER_BE}"
- - NATIVE_COMP="no"
- - COQ_DEST="-local"
- before_install:
- - brew update
- - brew unlink python
- - brew install gnu-time
- # only way to continue using OPAM 1.2
- - brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/d156edeeed7291f4bc1e08620b331bbd05d52b78/Formula/opam.rb
-
- - if: NOT (type = pull_request)
- os: osx
- osx_image: xcode7.3
- env:
- - TEST_TARGET=""
- - COMPILER="${COMPILER_BE}"
- - FINDLIB_VER="${FINDLIB_VER_BE}"
- - CAMLP5_VER="${CAMLP5_VER_BE}"
- - NATIVE_COMP="no"
- - COQ_DEST="-prefix ${PWD}/_install"
- - EXTRA_CONF="-coqide opt -warn-error yes"
- - EXTRA_OPAM="${LABLGTK_BE}"
- before_install:
- - brew update
- - brew unlink python
- - brew install gnu-time gtk+ expat gtksourceview gdk-pixbuf
- # only way to continue using OPAM 1.2
- - brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/d156edeeed7291f4bc1e08620b331bbd05d52b78/Formula/opam.rb
- - brew unlink python@2
- - brew install python3
- - pip3 install macpack
- before_deploy:
- - dev/build/osx/make-macos-dmg.sh
- deploy:
- - provider: bintray
- user: maximedenes
- file: .bintray.json
- key:
- secure: "gUvXWwWR0gicDqsKOnBfe45taToSFied6gN8tCa5IOtl6E6gFoHoPZ83ZWXQsZP50oMDFS5eji0VQAFGEbOsGrTZaD9Y9Jnu34NND78SWL1tsJ6nHO3aCAoMpB0N3+oRuF6S+9HStU6KXWqgj+GeU4vZ4TOlG01RGctJa6U3vII="
- skip_cleanup: true
- on:
- all_branches: true
-
-before_install:
-- if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then echo "Tested commit (followed by parent commits):"; git log -1; for commit in `git log -1 --format="%P"`; do echo; git log -1 $commit; done; fi
-
-install:
-- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then travis_retry ./dev/tools/sudo-apt-get-update.sh -q; fi
-- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then sudo apt-get install -y opam aspcud gcc-multilib --allow-unauthenticated; fi
-- opam init -j ${NJOBS} --compiler=${COMPILER} -n -y
-- opam switch "$COMPILER" && opam update
-- eval $(opam config env)
-- opam config list
-- opam install -j ${NJOBS} -y num ocamlfind${FINDLIB_VER} camlp5${CAMLP5_VER} ${EXTRA_OPAM}
-- opam list
-
-script:
-
-- set -e
-- echo 'Configuring Coq...' && echo -en 'travis_fold:start:coq.config\\r'
-- ./configure ${COQ_DEST} -warn-error yes -native-compiler ${NATIVE_COMP} ${EXTRA_CONF}
-- echo -en 'travis_fold:end:coq.config\\r'
-
-- echo 'Building Coq...' && echo -en 'travis_fold:start:coq.build\\r'
-- make -j ${NJOBS} ${MAIN_TARGET}
-- echo -en 'travis_fold:end:coq.build\\r'
-
-- echo 'Running tests...' && echo -en 'travis_fold:start:coq.test\\r'
-- if [ -n "${TEST_TARGET}" ]; then ${TW} make -j ${NJOBS} ${TEST_TARGET}; fi
-- echo -en 'travis_fold:end:coq.test\\r'
-- set +e
-
-# Testing Gitter webhook
-notifications:
- webhooks:
- urls:
- - https://webhooks.gitter.im/e/3cdabdec318214c7cd63
- on_success: change # options: [always|never|change] default: always
- on_failure: always # options: [always|never|change] default: always
- on_start: never # options: [always|never|change] default: always
diff --git a/CHANGES b/CHANGES
deleted file mode 100644
index ab63d8ec..00000000
--- a/CHANGES
+++ /dev/null
@@ -1,3802 +0,0 @@
-Changes from 8.8.1 to 8.8.2
-===========================
-
-Documentation
-
-- A PDF version of the reference manual is available once again.
-
-Tools
-
-- The coq-makefile targets `print-pretty-timed`, `print-pretty-timed-diff`,
- and `print-pretty-single-time-diff` now correctly label the "before" and
- "after" columns, rather than swapping them.
-
-Kernel
-
-- The kernel does not tolerate capture of global universes by
- polymorphic universe binders, fixing a soundness break (triggered
- only through custom plugins)
-
-Windows installer
-
-- The Windows installer now includes many more external packages that can be
-individually selected for installation.
-
-Many other bug fixes and lots of documentation improvements (for details,
-see the 8.8.2 milestone at https://github.com/coq/coq/milestone/15?closed=1).
-
-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
-===============================
-
-Tools
-
-- Asynchronous proof delegation policy was fixed. Since version 8.7
- Coq was ignoring previous runs and the -async-proofs-delegation-threshold
- option did not have the expected behavior.
-
-Tactic language
-
-- The undocumented "nameless" forms `fix N`, `cofix N` have been
- deprecated; please use `fix/cofix ident N` to explicitely name
- hypothesis to be introduced.
-
-Documentation
-
-- The reference manual is now fully ported to Sphinx.
-
-Other small deprecations and bug fixes.
-
-Changes from 8.7.2 to 8.8+beta1
-===============================
-
-Kernel
-
-- Support for template polymorphism for definitions was removed. May trigger
- more "universe inconsistency" errors in rare occasions.
-- Fixpoints are no longer allowed on non-recursive inductive types.
-
-Notations
-
-- Recursive notations with the recursive pattern repeating on the
- right (e.g. "( x ; .. ; y ; z )") now supported.
-- Notations with a specific level for the leftmost nonterminal,
- when printing-only, are supported.
-- Notations can now refer to the syntactic category of patterns (as in
- "fun 'pat =>" or "match p with pat => ... end"). Two variants are
- available, depending on whether a single variable is considered as a
- pattern or not.
-- Recursive notations now support ".." patterns with several
- occurrences of the recursive term or binder, possibly mixing terms
- and binders, possibly in reverse left-to-right order.
-- "Locate" now working also on notations of the form "x + y" (rather
- than "_ + _").
-
-Specification language
-
-- When printing clauses of a "match", clauses with same right-hand
- side are factorized and the last most factorized clause with no
- variables, if it exists, is turned into a default clause.
- Use "Unset Printing Allow Default Clause" do deactivate printing
- of a default clause.
- Use "Unset Printing Factorizable Match Patterns" to deactivate
- factorization of clauses with same right-hand side.
-
-Tactics
-
-- On Linux, "native_compute" calls can be profiled using the "perf"
- utility. The command "Set NativeCompute Profiling" enables
- profiling, and "Set NativeCompute Profile Filename" customizes
- the profile filename.
-- The tactic "omega" is now aware of the bodies of context variables
- such as "x := 5 : Z" (see BZ#148). This could be disabled via
- Unset Omega UseLocalDefs.
-- The tactic "romega" is also aware now of the bodies of context variables.
-- The tactic "zify" resp. "omega with N" is now aware of N.pred.
-- Tactic "decide equality" now able to manage constructors which
- contain proofs.
-- Added tactics reset ltac profile, show ltac profile (and variants)
-- Added tactics restart_timer, finish_timing, and time_constr as an
- experimental way of timing Ltac's evaluation phase
-- Added tactic optimize_heap, analogous to the Vernacular Optimize
- Heap, which performs a major garbage collection and heap compaction
- in the OCaml run-time system.
-- The tactics "dtauto", "dintuition", "firstorder" now handle inductive types
- with let bindings in the parameters.
-- The tactic "dtauto" now handles some inductives such as
- "@sigT A (fun _ => B)" as non-dependent conjunctions.
-- A bug fixed in "rewrite H in *" and "rewrite H in * |-" may cause a
- few rare incompatibilities (it was unintendedly recursively
- rewriting in the side conditions generated by H).
-- Added tactics "assert_succeeds tac" and "assert_fails tac" to ensure
- properties of the executation of a tactic without keeping the effect
- of the execution.
-- `vm_compute` now supports existential variables.
-- Calls to `shelve` and `give_up` within calls to tactic `refine` now working.
-- Deprecated tactic `appcontext` was removed.
-
-Focusing
-
-- Focusing bracket `{` now supports single-numbered goal selector,
- e.g. `2: {` will focus on the second sub-goal. As usual, unfocus
- with `}` once the sub-goal is fully solved.
- The `Focus` and `Unfocus` commands are now deprecated.
-
-Vernacular Commands
-
-- Proofs ending in "Qed exporting ident, .., ident" are not supported
- anymore. Constants generated during `abstract` are kept private to the
- local environment.
-- The deprecated Coercion Local, Open Local Scope, Notation Local syntax
- was removed. Use Local as a prefix instead.
-- For the Extraction Language command, "OCaml" is spelled correctly.
- The older "Ocaml" is still accepted, but deprecated.
-- Using “Require” inside a section is deprecated.
-- An experimental command "Show Extraction" allows to extract the content
- of the current ongoing proof (grant wish #4129).
-- Coercion now accepts the type of its argument to be "Prop" or "Type".
-- The "Export" modifier can now be used when setting and unsetting options, and
- will result in performing the same change when the module corresponding the
- command is imported.
-- The `Axiom` command does not automatically declare axioms as instances when
- their type is a class. Previous behavior can be restored using `Set
- Typeclasses Axioms Are Instances`.
-
-Universes
-
-- Qualified naming of global universes now works like other namespaced
- objects (e.g. constants), with a separate namespace, inside and across
- module and library boundaries. Global universe names introduced in an
- inductive / constant / Let declaration get qualified with the name of
- the declaration.
-- Universe cumulativity for inductive types is now specified as a
- variance for each polymorphic universe. See the reference manual for
- more information.
-- Inference of universe constraints with cumulative inductive types
- produces more general constraints. Unsetting new option Cumulativity
- Weak Constraints produces even more general constraints (but may
- produce too many universes to be practical).
-- Fix #5726: Notations that start with `Type` now support universe instances
- with `@{u}`.
-- `with Definition` now understands universe declarations
- (like `@{u| Set < u}`).
-
-Tools
-
-- Coq can now be run with the option -mangle-names to change the auto-generated
- name scheme. This is intended to function as a linter for developments that
- want to be robust to changes in auto-generated names. This feature is experimental,
- and may change or disappear without warning.
-- GeoProof support was removed.
-
-Checker
-
-- The checker now accepts filenames in addition to logical paths.
-
-CoqIDE
-
-- Find and Replace All report the number of occurrences found; Find indicates
- when it wraps.
-
-coqdep
-
-- Learned to read -I, -Q, -R and filenames from _CoqProject files.
- This is used by coq_makefile when generating dependencies for .v
- files (but not other files).
-
-Documentation
-
-- The Coq FAQ, formerly located at https://coq.inria.fr/faq, has been
- moved to the GitHub wiki section of this repository; the main entry
- page is https://github.com/coq/coq/wiki/The-Coq-FAQ.
-- Documentation: a large community effort resulted in the migration
- of the reference manual to the Sphinx documentation tool. The result
- is partially integrated in this version.
-
-Standard Library
-
-- New libraries Coq.Init.Decimal, Coq.Numbers.DecimalFacts,
- Coq.Numbers.DecimalNat, Coq.Numbers.DecimalPos,
- Coq.Numbers.DecimalN, Coq.Numbers.DecimalZ,
- Coq.Numbers.DecimalString providing a type of decimal numbers, some
- facts about them, and conversions between decimal numbers and nat,
- positive, N, Z, and string.
-- Added [Coq.Strings.String.concat] to concatenate a list of strings
- inserting a separator between each item
-- Notation `'` for Zpos in QArith was removed.
-
-- Some deprecated aliases are now emitting warnings when used.
-
-Compatibility support
-
-- Support for compatibility with versions before 8.6 was dropped.
-
-Options
-
-- The following deprecated options have been removed:
-
- + `Refolding Reduction`
- + `Standard Proposition Elimination`
- + `Dependent Propositions Elimination`
- + `Discriminate Introduction`
- + `Shrink Abstract`
- + `Tactic Pattern Unification`
- + `Intuition Iff Unfolding`
- + `Injection L2R Pattern Order`
- + `Record Elimination Schemes`
- + `Match Strict`
- + `Tactic Compat Context`
- + `Typeclasses Legacy Resolution`
- + `Typeclasses Module Eta`
- + `Typeclass Resolution After Apply`
-
-Changes from 8.7.1 to 8.7.2
-===========================
-
-Fixed a critical bug in the VM handling of universes (#6677). This bug
-affected all releases since 8.5.
-
-Improved support for building with OCaml 4.06.0 and external num package.
-
-Many other bug fixes, documentation improvements, and user
-message improvements (for details, see the 8.7.2 milestone at
-https://github.com/coq/coq/milestone/11?closed=1).
-
-Changes from 8.7.0 to 8.7.1
-===========================
-
-Compatibility with OCaml 4.06.0.
-
-Many bug fixes, documentation improvements, and user message improvements (for
-details see the 8.7.1 milestone at https://github.com/coq/coq/milestone/10?closed=1).
-
-Changes from 8.7+beta2 to 8.7.0
-===============================
-
-OCaml
-
-- Users can pass specific flags to the OCaml optimizing compiler by
- -using the flambda-opts configure-time option.
-
- Beware that compiling Coq with a flambda-enabled compiler is
- experimental and may require large amounts of RAM and CPU, see
- INSTALL for more details.
-
-Changes from 8.7+beta1 to 8.7+beta2
-===================================
-
-Tools
-
-- In CoqIDE, the "Compile Buffer" command takes account of flags in
- _CoqProject or other project file.
-
-Improvements around some error messages.
-
-Many bug fixes including two important ones:
-
-- BZ#5730: CoqIDE becomes unresponsive on file open.
-- coq_makefile: make sure compile flags for Coq and coq_makefile are in sync
- (in particular, make sure the `-safe-string` option is used to compile plugins).
-
-Changes from 8.6.1 to 8.7+beta1
-===============================
-
-Tactics
-
-- New tactic "extensionality in H" which applies (possibly dependent)
- functional extensionality in H supposed to be a quantified equality
- until giving a bare equality.
-- New tactic "inversion_sigma" which turns equalities of dependent
- pairs (e.g., "existT P x p = existT P y q", frequently left over by
- "inversion" on a dependent type family) into pairs of equalities
- (e.g., a hypothesis "H : x = y" and a hypothesis of type "rew H in p
- = q"); these hypotheses can subsequently be simplified using
- "subst", without ever invoking any kind of axiom asserting
- uniqueness of identity proofs. If you want to explicitly specify the
- hypothesis to be inverted, or name the generated hypotheses, you can
- invoke "induction H as [H1 H2] using eq_sigT_rect". The tactic also
- works for "sig", "sigT2", and "sig2", and there are similar
- "eq_sig*_rect" induction lemmas.
-- Tactic "specialize with ..." now accepts any partial bindings.
- Missing bindings are either solved by unification or left quantified
- in the hypothesis.
-- New representation of terms that statically ensure stability by
- evar-expansion. This has several consequences.
- * In terms of performance, this adds a cost to every term destructuration,
- but at the same time most eager evar normalizations were removed, which
- couterbalances this drawback and even sometimes outperforms the old
- implementation. For instance, many operations that would require O(n)
- normalization of the term are now O(1) in tactics. YMMV.
- * This triggers small changes in unification, which was not evar-insensitive.
- Most notably, the new implementation recognizes Miller patterns that were
- missed before because of a missing normalization step. Hopefully this should
- be fairly uncommon.
-- Tactic "auto with real" can now discharge comparisons of literals.
-- The types of variables in patterns of "match" are now
- beta-iota-reduced after type-checking. This has an impact on the
- type of the variables that the tactic "refine" introduces in the
- context, producing types a priori closer to the expectations.
-- In "Tactic Notation" or "TACTIC EXTEND", entry "constr_with_bindings"
- now uses type classes and rejects terms with unresolved holes, like
- entry "constr" does. To get the former behavior use
- "open_constr_with_bindings" (possible source of incompatibility).
-- New e-variants eassert, eenough, epose proof, eset, eremember, epose
- which behave like the corresponding variants with no "e" but turn
- unresolved implicit arguments into existential variables, on the
- shelf, rather than failing.
-- Tactic injection has become more powerful (closes BZ#4890) and its
- documentation has been updated.
-- New variants of the `first` and `solve` tacticals that do not rely
- on parsing rules, meant to define tactic notations.
-- Added support for side effects hooks in `cbv`, `cbn` and `simpl`.
- The side effects are provided via a plugin:
- https://github.com/herbelin/reduction-effects/
-- It is now possible to take hint database names as parameters in a
- Ltac definition or a Tactic Notation.
-- New option `Set Ltac Batch Debug` on top of `Set Ltac Debug` for
- non-interactive Ltac debug output.
-
-Gallina
-
-- Now supporting all kinds of binders, including 'pat, in syntax of record fields.
-
-Vernacular Commands
-
-- Goals context can be printed in a more compact way when `Set
- Printing Compact Contexts` is activated.
-- Unfocused goals can be printed with the `Set Printing Unfocused`
- option.
-- `Print` now shows the types of let-bindings.
-- The compatibility options for printing primitive projections
- (`Set Printing Primitive Projection Parameters` and
- `Set Printing Primitive Projection Compatibility`) are now off by default.
-- Possibility to unset the printing of notations in a more fine grained
- fashion than `Unset Printing Notations` is provided without any
- user-syntax. The goal is that someone creates a plugin to experiment
- such a user-syntax, to be later integrated in Coq when stabilized.
-- `About` now tells if a reference is a coercion.
-- The deprecated `Save` vernacular and its form `Save Theorem id` to
- close proofs have been removed from the syntax. Please use `Qed`.
-- `Search` now sorts results by relevance (the relevance metric is a
- weighted sum of number of distinct symbols and size of the term).
-
-Standard Library
-
-- New file PropExtensionality.v to explicitly work in the axiomatic
- context of propositional extensionality.
-- New file SetoidChoice.v axiomatically providing choice over setoids,
- and, consequently, choice of representatives in equivalence classes.
- Various proof-theoretic characterizations of choice over setoids in
- file ChoiceFacts.v.
-- New lemmas about iff and about orders on positive and Z.
-- New lemmas on powerRZ.
-- Strengthened statement of JMeq_eq_dep (closes BZ#4912).
-- The BigN, BigZ, BigZ libraries are no longer part of the Coq standard
- library, they are now provided by a separate repository
- https://github.com/coq/bignums
- The split has been done just after the Int31 library.
-
-- IZR (Reals) has been changed to produce a compact representation of
- integers. As a consequence, IZR is no longer convertible to INR and
- lemmas such as INR_IZR_INZ should be used instead.
-- Real constants are now represented using IZR rather than R0 and R1;
- this might cause rewriting rules to fail to apply to constants.
-- Added new notation {x & P} for sigT (without a type for x)
-
-Plugins
-
-- The Ssreflect plugin is now distributed with Coq. Its documentation has
- been integrated as a chapter of the reference manual. This chapter is
- work in progress so feedback is welcome.
-- The mathematical proof language (also known as declarative mode) was removed.
-- A new command Extraction TestCompile has been introduced, not meant
- for the general user but instead for Coq's test-suite.
-- The extraction plugin is no longer loaded by default. It must be
- explicitly loaded with [Require Extraction], which is backwards
- compatible.
-- The functional induction plugin (which provides the [Function]
- vernacular) is no longer loaded by default. It must be explicitly
- loaded with [Require FunInd], which is backwards compatible.
-
-
-Dependencies
-
-- Support for camlp4 has been removed.
-
-Tools
-
-- coq_makefile was completely redesigned to improve its maintainability and
- the extensibility of generated Makefiles, and to make _CoqProject files
- more palatable to IDEs. Overview:
- * _CoqProject files contain only Coq specific data (i.e. the list of
- files, -R options, ...)
- * coq_makefile translates _CoqProject to Makefile.conf and copies in the
- desired location a standard Makefile (that reads Makefile.conf)
- * Makefile extensions can be implemented in a Makefile.local file (read
- by the main Makefile) by installing a hook in the extension points
- provided by the standard Makefile
- The current version contains code for retro compatibility that prints
- warnings when a deprecated feature is used. Please upgrade your _CoqProject
- accordingly.
- * Additionally, coq_makefile-made Makefiles now support experimental timing
- targets `pretty-timed`, `pretty-timed-before`, `pretty-timed-after`,
- `print-pretty-timed-diff`, `print-pretty-single-time-diff`,
- `all.timing.diff`, and the variable `TIMING=1` (or `TIMING=before` or
- `TIMING=after`); see the documentation for more details.
-
-Build Infrastructure
-
-- Note that 'make world' does not build the bytecode binaries anymore.
- For that, you can use 'make byte' (and 'make install-byte' afterwards).
- Warning: native and byte compilations should *not* be mixed in the same
- instance of 'make -j', otherwise both ocamlc and ocamlopt might race for
- access to the same .cmi files. In short, use "make -j && make -j byte"
- instead of "make -j world byte".
-
-Universes
-
-- Cumulative inductive types. see prefixes "Cumulative", "NonCumulative"
- for inductive definitions and the option "Set Polymorphic Inductive Cumulativity"
- in the reference manual.
-- New syntax `foo@{_}` to instantiate a polymorphic definition with
- anonymous universes (can also be used with `Type`).
-
-XML Protocol and internal changes
-
-See dev/doc/changes.txt
-
-Many bugfixes including BZ#1859, BZ#2884, BZ#3613, BZ#3943, BZ#3994,
-BZ#4250, BZ#4709, BZ#4720, BZ#4824, BZ#4844, BZ#4911, BZ#5026, BZ#5233,
-BZ#5275, BZ#5315, BZ#5336, BZ#5360, BZ#5390, BZ#5414, BZ#5417, BZ#5420,
-BZ#5439, BZ#5449, BZ#5475, BZ#5476, BZ#5482, BZ#5501, BZ#5507, BZ#5520,
-BZ#5523, BZ#5524, BZ#5553, BZ#5577, BZ#5578, BZ#5589, BZ#5597, BZ#5598,
-BZ#5607, BZ#5618, BZ#5619, BZ#5620, BZ#5641, BZ#5648, BZ#5651, BZ#5671.
-
-Many bugfixes on OS X and Windows (now the test-suite passes on these
-platforms too).
-
-Many optimizations.
-
-Many documentation improvements.
-
-Changes from 8.6 to 8.6.1
-=========================
-
-- Fix #5380: Default colors for CoqIDE are actually applied.
-- Fix plugin warnings
-- Document named evars (including Show ident)
-- Fix Bug #5574, document function scope
-- Adding a test case as requested in bug 5205.
-- Fix Bug #5568, no dup notation warnings on repeated module imports
-- Fix documentation of Typeclasses eauto :=
-- Refactor documentation of records.
-- Protecting from warnings while compiling 8.6
-- Fixing an inconsistency between configure and configure.ml
-- Add test-suite checks for coqchk with constraints
-- Fix bug #5019 (looping zify on dependent types)
-- Fix bug 5550: "typeclasses eauto with" does not work with section variables.
-- Bug 5546, qualify datatype constructors when needed in Show Match
-- Bug #5535, test for Show with -emacs
-- Fix bug #5486, don't reverse ids in tuples
-- Fixing #5522 (anomaly with free vars of pat)
-- Fix bug #5526, don't check for nonlinearity in notation if printing only
-- Fix bug #5255
-- Fix bug #3659: -time should understand multibyte encodings.
-- FIx bug #5300: Anomaly: Uncaught exception Not_found" in "Print Assumptions".
-- Fix outdated description in RefMan.
-- Repairing `Set Rewriting Schemes`
-- Fixing #5487 (v8.5 regression on ltac-matching expressions with evars).
-- Fix description of command-line arguments for Add (Rec) LoadPath
-- Fix bug #5377: @? patterns broken.
-- add XML protocol doc
-- Fix anomaly when doing [all:Check _.] during a proof.
-- Correction of bug #4306
-- Fix #5435: [Eval native_compute in] raises anomaly.
-- Instances should obey universe binders even when defined by tactics.
-- Intern names bound in match patterns
-- funind: Ignore missing info for current function
-- Do not typecheck twice the type of opaque constants.
-- show unused intro pattern warning
-- [future] Be eager when "chaining" already resolved future values.
-- Opaque side effects
-- Fix #5132: coq_makefile generates incorrect install goal
-- Run non-tactic comands without resilient_command
-- Univs: fix bug #5365, generation of u+k <= v constraints
-- make `emit' tail recursive
-- Don't require printing-only notation to be productive
-- Fix the way setoid_rewrite handles bindings.
-- Fix for bug 5244 - set printing width ignored when given enough space
-- Fix bug 4969, autoapply was not tagging shelved subgoals correctly
-
-Changes from V8.6beta1 to V8.6
-==============================
-
-Kernel
-
-- Fixed critical bug #5248 in VM long multiplication on 32-bit
- architectures. Was there only since 8.6beta1, so no stable release impacted.
-
-Other bug fixes in universes, type class shelving,...
-
-Changes from V8.5 to V8.6beta1
-==============================
-
-Kernel
-
-- A new, faster state-of-the-art universe constraint checker.
-
-Specification language
-
-- Giving implicit arguments explicitly to a constant with multiple
- choices of implicit arguments does not break any more insertion of
- further maximal implicit arguments.
-- Ability to put any pattern in binders, prefixed by quote, e.g.
- "fun '(a,b) => ...", "λ '(a,(b,c)), ...", "Definition foo '(x,y) := ...".
- It expands into a "let 'pattern := ..."
-
-Tactics
-
-- Flag "Bracketing Last Introduction Pattern" is now on by default.
-- Flag "Regular Subst Tactic" is now on by default: it respects the
- initial order of hypothesis, it contracts cycles, it unfolds no
- local definitions (common source of incompatibilities, fixable by
- "Unset Regular Subst Tactic").
-- New flag "Refolding Reduction", now disabled by default, which turns
- on refolding of constants/fixpoints (as in cbn) during the reductions
- done during type inference and tactic retyping. Can be extremely
- expensive. When set off, this recovers the 8.4 behaviour of unification
- and type inference. Potential source of incompatibility with 8.5 developments
- (the option is set on in Compat/Coq85.v).
-- New flag "Shrink Abstract" that minimalizes proofs generated by the abstract
- tactical w.r.t. variables appearing in the body of the proof.
- On by default and deprecated. Minor source of incompatibility
- for code relying on the precise arguments of abstracted proofs.
-- Serious bugs are fixed in tactic "double induction" (source of
- incompatibilities as soon as the inductive types have dependencies in
- the type of their constructors; "double induction" remains however
- deprecated).
-- In introduction patterns of the form (pat1,...,patn), n should match
- the exact number of hypotheses introduced (except for local definitions
- for which pattern can be omitted, as in regular pattern-matching).
-- Tactic scopes in Ltac like constr: and ltac: now require parentheses around
- their argument.
-- Every generic argument type declares a tactic scope of the form "name:(...)"
- where name is the name of the argument. This generalizes the constr: and ltac:
- instances.
-- When in strict mode (i.e. in a Ltac definition), if the "intro" tactic is
- given a free identifier, it is not bound in subsequent tactics anymore.
- In order to introduce a binding, use e.g. the "fresh" primitive instead
- (potential source of incompatibilities).
-- New tactics is_ind, is_const, is_proj, is_constructor for use in Ltac.
-- New goal selectors. Sets of goals can be selected by listing integers
- ranges. Example: "1,4-7,24: tac" focuses "tac" on goals 1,4,5,6,7,24.
-- For uniformity with "destruct"/"induction" and for a more natural
- behavior, "injection" can now work in place by activating option
- "Structural Injection". In this case, hypotheses are also put in the
- context in the natural left-to-right order and the hypothesis on
- which injection applies is cleared.
-- Tactic "contradiction" (hence "easy") now also solve goals with
- hypotheses of the form "~True" or "t<>t" (possible source of
- incompatibilities because of more successes in automation, but
- generally a more intuitive strategy).
-- Option "Injection On Proofs" was renamed "Keep Proof Equalities". When
- enabled, injection and inversion do not drop equalities between objects
- in Prop. Still disabled by default.
-- New tactics "notypeclasses refine" and "simple notypeclasses refine" that
- disallow typeclass resolution when typechecking their argument, for use
- in typeclass hints.
-- Integration of LtacProf, a profiler for Ltac.
-- Reduction tactics now accept more fine-grained flags: iota is now a shorthand
- for the new flags match, fix and cofix.
-- The ssreflect subterm selection algorithm is now accessible to tactic writers
- through the ssrmatching plugin.
-- When used as an argument of an ltac function, "auto" without "with"
- nor "using" clause now correctly uses only the core hint database by
- default.
-
-Hints
-
-- Revised the syntax of [Hint Cut] to follow standard notation for regexps.
-- Hint Mode now accepts "!" which means that the mode matches only if the
- argument's head is not an evar (it goes under applications, casts, and
- scrutinees of matches and projections).
-- Hints can now take an optional user-given pattern, used only by
- [typeclasses eauto] with the [Filtered Unification] option on.
-
-Typeclasses
-
-- Many new options and new engine based on the proof monad. The
- [typeclasses eauto] tactic is now a multi-goal, multi-success tactic.
- See reference manual for more information. It is planned to
- replace auto and eauto in the following version. The 8.5 resolution
- engine is still available to help solve compatibility issues.
-
-Program
-
-- The "Shrink Obligations" flag now applies to all obligations, not only
- those solved by the automatic tactic.
-- "Shrink Obligations" is on by default and deprecated. Minor source of
- incompatibility for code relying on the precise arguments of
- obligations.
-
-Notations
-
-- "Bind Scope" can once again bind "Funclass" and "Sortclass".
-
-General infrastructure
-
-- New configurable warning system which can be controlled with the vernacular
- command "Set Warnings", or, under coqc/coqtop, with the flag "-w". In
- particular, the default is now that warnings are printed by coqc.
-- In asynchronous mode, Coq is now capable of recovering from errors and
- continue processing the document.
-
-Tools
-
-- coqc accepts a -o option to specify the output file name
-- coqtop accepts --print-version to print Coq and OCaml versions in
- easy to parse format
-- Setting [Printing Dependent Evars Line] can be unset to disable the
- computation associated with printing the "dependent evars: " line in
- -emacs mode
-- Removed the -verbose-compat-notations flag and the corresponding Set
- Verbose Compat vernacular, since these warnings can now be silenced or
- turned into errors using "-w".
-
-XML protocol
-
-- message format has changed, see dev/doc/changes.txt for more details.
-
-Many bug fixes, minor changes and documentation improvements are not mentioned
-here.
-
-Changes from V8.5pl2 to V8.5pl3
-===============================
-
-Critical bugfix
-
-- #4876: Guard checker incompleteness when using primitive projections
-
-Other bugfixes
-
-- #4780: Induction with universe polymorphism on was creating ill-typed terms.
-- #4673: regression in setoid_rewrite, unfolding let-ins for type unification.
-- #4754: Regression in setoid_rewrite, allow postponed unification problems to remain.
-- #4769: Anomaly with universe polymorphic schemes defined inside sections.
-- #3886: Program: duplicate obligations of mutual fixpoints.
-- #4994: Documentation typo.
-- #5008: Use the "md5" command on OpenBSD.
-- #5007: Do not assume the "TERM" environment variable is always set.
-- #4606: Output a break before a list only if there was an empty line.
-- #5001: metas not cleaned properly in clenv_refine_in.
-- #2336: incorrect glob data for module symbols (bug #2336).
-- #4832: Remove extraneous dot in error message.
-- Anomaly in printing a unification error message.
-- #4947: Options which take string arguments are not backwards compatible.
-- #4156: micromega cache files are now hidden files.
-- #4871: interrupting par:abstract kills coqtop.
-- #5043: [Admitted] lemmas pick up section variables.
-- Fix name of internal refine ("simple refine").
-- #5062: probably a typo in Strict Proofs mode.
-- #5065: Anomaly: Not a proof by induction.
-- Restore native compiler optimizations, they were disabled since 8.5!
-- #5077: failure on typing a fixpoint with evars in its type.
-- Fix recursive notation bug.
-- #5095: non relevant too strict test in let-in abstraction.
-- Ensuring that the evar name is preserved by "rename".
-- #4887: confusion between using and with in documentation of firstorder.
-- Bug in subst with let-ins.
-- #4762: eauto weaker than auto.
-- Remove if_then_else (was buggy). Use tryif instead.
-- #4970: confusion between special "{" and non special "{{" in notations.
-- #4529: primitive projections unfolding.
-- #4416: Incorrect "Error: Incorrect number of goals".
-- #4863: abstract in typeclass hint fails.
-- #5123: unshelve can impact typeclass resolution
-- Fix a collision about the meta-variable ".." in recursive notations.
-- Fix printing of info_auto.
-- #3209: Not_found due to an occur-check cycle.
-- #5097: status of evars refined by "clear" in ltac: closed wrt evars.
-- #5150: Missing dependency of the test-suite subsystems in prerequisite.
-- Fix a bug in error printing of unif constraints
-- #3941: Do not stop propagation of signals when Coq is busy.
-- #4822: Incorrect assertion in cbn.
-- #3479 parsing of "{" and "}" when a keyword starts with "{" or "}".
-- #5127: Memory corruption with the VM.
-- #5102: bullets parsing broken by calls to parse_entry.
-
-Various documentation improvements
-
-
-Changes from V8.5pl1 to V8.5pl2
-===============================
-
-Critical bugfix
-- Checksums of .vo files dependencies were not correctly checked.
-- Unicode-to-ASCII translation was not injective, leading in a soundness bug in
- the native compiler.
-
-Other bugfixes
-
-- #4097: more efficient occur-check in presence of primitive projections
-- #4398: type_scope used consistently in "match goal".
-- #4450: eauto does not work with polymorphic lemmas
-- #4677: fix alpha-conversion in notations needing eta-expansion.
-- Fully preserve initial order of hypotheses in "Regular Subst Tactic" mode.
-- #4644: a regression in unification.
-- #4725: Function (Error: Conversion test raised an anomaly) and Program
- (Error: Cannot infer this placeholder of type)
-- #4747: Problem building Coq 8.5pl1 with OCaml 4.03.0: Fatal warnings
-- #4752: CoqIDE crash on files not ended by ".v".
-- #4777: printing inefficiency with implicit arguments
-- #4818: "Admitted" fails due to undefined universe anomaly after calling
- "destruct"
-- #4823: remote counter: avoid thread race on sockets
-- #4841: -verbose flag changed semantics in 8.5, is much harder to use
-- #4851: [nsatz] cannot handle duplicated hypotheses
-- #4858: Anomaly: Uncaught exception Failure("hd"). Please report. in variant
- of nsatz
-- #4880: [nsatz_compute] generates invalid certificates if given redundant
- hypotheses
-- #4881: synchronizing "Declare Implicit Tactic" with backtrack.
-- #4882: anomaly with Declare Implicit Tactic on hole of type with evars
-- Fix use of "Declare Implicit Tactic" in refine.
- triggered by CoqIDE
-- #4069, #4718: congruence fails when universes are involved.
-
-Universes
-- Disallow silently dropping universe instances applied to variables
- (forward compatible)
-- Allow explicit universe instances on notations, when they can apply
- to the head reference of their expansion.
-
-Build infrastructure
-- New update on how to find camlp5 binary and library at configure time.
-
-Changes from V8.5 to V8.5pl1
-============================
-
-Critical bugfix
-- The subterm relation for the guard condition was incorrectly defined on
- primitive projections (#4588)
-
-Plugin development tools
-- add a .merlin target to the makefile
-
-Various performance improvements (time, space used by .vo files)
-
-Other bugfixes
-
-- Fix order of arguments to Big.compare_case in ExtrOcamlZBigInt.v
-- Added compatibility coercions from Specif.v which were present in Coq 8.4.
-- Fixing a source of inefficiency and an artificial dependency in the printer in the congruence tactic.
-- Allow to unset the refinement mode of Instance in ML
-- Fixing an incorrect use of prod_appvect on a term which was not a product in setoid_rewrite.
-- Add -compat 8.4 econstructor tactics, and tests
-- Add compatibility Nonrecursive Elimination Schemes
-- Fixing the "No applicable tactic" non informative error message regression on apply.
-- Univs: fix get_current_context (bug #4603, part I)
-- Fix a bug in Program coercion code
-- Fix handling of arity of definitional classes.
-- #4630: Some tactics are 20x slower in 8.5 than 8.4.
-- #4627: records with no declared arity can be template polymorphic.
-- #4623: set tactic too weak with universes (regression)
-- Fix incorrect behavior of CS resolution
-- #4591: Uncaught exception in directory browsing.
-- CoqIDE is more resilient to initialization errors.
-- #4614: "Fully check the document" is uninterruptable.
-- Try eta-expansion of records only on non-recursive ones
-- Fix bug when a sort is ascribed to a Record
-- Primitive projections: protect kernel from erroneous definitions.
-- Fixed bug #4533 with previous Keyed Unification commit
-- Win: kill unreliable hence do not waitpid after kill -9 (Close #4369)
-- Fix strategy of Keyed Unification
-- #4608: Anomaly "output_value: abstract value (outside heap)".
-- #4607: do not read native code files if native compiler was disabled.
-- #4105: poor escaping in the protocol between CoqIDE and coqtop.
-- #4596: [rewrite] broke in the past few weeks.
-- #4533 (partial): respect declared global transparency of projections in unification.ml
-- #4544: Backtrack on using full betaiota reduction during keyed unification.
-- #4540: CoqIDE bottom progress bar does not update.
-- Fix regression from 8.4 in reflexivity
-- #4580: [Set Refine Instance Mode] also used for Program Instance.
-- #4582: cannot override notation [ x ]. MAY CREATE INCOMPATIBILITIES, see #4683.
-- STM: Print/Extraction have to be skipped if -quick
-- #4542: CoqIDE: STOP button also stops workers
-- STM: classify some variants of Instance as regular `Fork nodes.
-- #4574: Anomaly: Uncaught exception Invalid_argument("splay_arity").
-- Do not give a name to anonymous evars anymore. See bug #4547.
-- STM: always stock in vio files the first node (state) of a proof
-- STM: not delegate proofs that contain Vernac(Module|Require|Import), #4530
-- Don't fail fatally if PATH is not set.
-- #4537: Coq 8.5 is slower in typeclass resolution.
-- #4522: Incorrect "Warning..." on windows.
-- #4373: coqdep does not know about .vio files.
-- #3826: "Incompatible module types" is uninformative.
-- #4495: Failed assertion in metasyntax.ml.
-- #4511: evar tactic can create non-typed evars.
-- #4503: mixing universe polymorphic and monomorphic variables and definitions in sections is unsupported.
-- #4519: oops, global shadowed local universe level bindings.
-- #4506: Anomaly: File "pretyping/indrec.ml", line 169, characters 14-20: Assertion failed.
-- #4548: Coqide crashes when going back one command
-
-Changes from V8.5beta3 to V8.5
-==============================
-
-Tools
-
-- Flag "-compat 8.4" now loads Coq.Compat.Coq84. The standard way of
- putting Coq in v8.4 compatibility mode is to pass the command line flag
- "-compat 8.4". It can be followed by "-require Coq.Compat.AdmitAxiom"
- if the 8.4 behavior of admit is needed, in which case it uses an axiom.
-
-Specification language
-
-- Syntax "$(tactic)$" changed to "ltac:(tactic)".
-
-Tactics
-
-- Syntax "destruct !hyp" changed to "destruct (hyp)", and similarly
- for induction (rare source of incompatibilities easily solvable by
- removing parentheses around "hyp" when not for the purpose of keeping
- the hypothesis).
-- Syntax "p/c" for on-the-fly application of a lemma c before
- introducing along pattern p changed to p%c1..%cn. The feature and
- syntax are in experimental stage.
-- "Proof using" does not clear unused section variables.
-- Tactic "refine" has been changed back to the 8.4 behavior of shelving subgoals
- that occur in other subgoals. The "refine" tactic of 8.5beta3 has been
- renamed "simple refine"; it does not shelve any subgoal.
-- New tactical "unshelve tac" which grab existential variables put on
- the tactic shelve by the execution of "tac".
-
-Changes from V8.5beta2 to V8.5beta3
-===================================
-
-Vernacular commands
-
-- New command "Redirect" to redirect the output of a command to a file.
-- New command "Undelimit Scope" to remove the delimiter of a scope.
-- New option "Strict Universe Declaration", set by default. It enforces the
- declaration of all polymorphic universes appearing in a definition when
- introducing it.
-- New command "Show id" to show goal named id.
-- Option "Virtual Machine" removed.
-
-Tactics
-
-- New flag "Regular Subst Tactic" which fixes "subst" in situations where
- it failed to substitute all substitutable equations or failed to simplify
- cycles, or accidentally unfolded local definitions (flag is off by default).
-- New flag "Loose Hint Behavior" to handle hints loaded but not imported in a
- special way. It accepts three distinct flags:
- * "Lax", which is the default one, sets the old behavior, i.e. a non-imported
- hint behaves the same as an imported one.
- * "Warn" outputs a warning when a non-imported hint is used. Note that this is
- an over-approximation, because a hint may be triggered by an eauto run that
- will eventually fail and backtrack.
- * "Strict" changes the behavior of an unloaded hint to the one of the fail
- tactic, allowing to emulate the hopefully future import-scoped hint mechanism.
-- New compatibility flag "Universal Lemma Under Conjunction" which
- let tactics working under conjunctions apply sublemmas of the form
- "forall A, ... -> A".
-- New compatibility flag "Bracketing Last Introduction Pattern" which can be
- set so that the last disjunctive-conjunctive introduction pattern given to
- "intros" automatically complete the introduction of its subcomponents, as the
- the disjunctive-conjunctive introduction patterns in non-terminal position
- already do.
-- New flag "Shrink Abstract" that minimalizes proofs generated by the abstract
- tactical w.r.t. variables appearing in the body of the proof.
-
-Program
-
-- The "Shrink Obligations" flag now applies to all obligations, not only those
-solved by the automatic tactic.
-- Importing Program no longer overrides the "exists" tactic (potential source
- of incompatibilities).
-- Hints costs are now correctly taken into account (potential source of
- incompatibilities).
-- Documented the Hint Cut command that allows control of the
- proof-search during typeclass resolution (see reference manual).
-
-API
-
-- Some functions from pretyping/typing.ml and their derivatives were potential
- source of evarmap leaks, as they dropped their resulting evarmap. The
- situation was clarified by renaming them according to a unsafe_* scheme. Their
- sound variant is likewise renamed to their old name. The following renamings
- were made.
- * Typing.type_of -> unsafe_type_of
- * Typing.e_type_of -> type_of
- * A new e_type_of function that matches the e_ prefix policy
- * Tacmach.pf_type_of -> pf_unsafe_type_of
- * A new safe pf_type_of function.
- All uses of unsafe_* functions should be eventually eliminated.
-
-Tools
-
-- Added an option -w to control the output of coqtop warnings.
-- Configure now takes an optional -native-compiler (yes|no) flag replacing
- -no-native-compiler. The new flag is set to no by default under Windows.
-- Flag -no-native-compiler was removed and became the default for coqc. If
- precompilation of files for native conversion test is desired, use
- -native-compiler.
-- The -compile command-line option now takes the full path of the considered
- file, including the ".v" extension, and outputs a warning if such an extension
- is lacking.
-- The -require and -load-vernac-object command-line options now take a logical
- path of a given library rather than a physical path, thus they behave like
- Require [Import] path.
-- The -vm command-line option has been removed.
-
-Standard Library
-
- - There is now a Coq.Compat.Coq84 library, which sets the various compatibility
- options and does a few redefinitions to make Coq behave more like Coq v8.4.
- The standard way of putting Coq in v8.4 compatibility mode is to pass the command
- line flags "-require Coq.Compat.Coq84 -compat 8.4".
-
-Changes from V8.5beta1 to V8.5beta2
-===================================
-
-Logic
-
-- The VM now supports inductive types with up to 8388851 non-constant
- constructors and up to 8388607 constant ones.
-
-Specification language
-
-- Syntax "$(tactic)$" changed to "ltac: tactic".
-
-Tactics
-
-- A script using the admit tactic can no longer be concluded by either
- Qed or Defined. In the first case, Admitted can be used instead. In
- the second case, a subproof should be used.
-- The easy tactic and the now tactical now have a more predictable
- behavior, but they might now discharge some previously unsolved goals.
-
-Extraction
-
-- Definitions extracted to Haskell GHC should no longer randomly
- segfault when some Coq types cannot be represented by Haskell types.
-- Definitions can now be extracted to Json for post-processing.
-
-Tools
-
-- Option -I -as has been removed, and option -R -as has been
- deprecated. In both cases, option -R can be used instead.
-- coq_makefile now generates double-colon rules for rules such as clean.
-
-API
-
-- The interface of [change] has changed to take a [change_arg], which
- can be built from a [constr] using [make_change_arg].
-
-Changes from V8.4 to V8.5beta1
-==============================
-
-Logic
-
-- Primitive projections for records allow for a compact representation
- of projections, without parameters and avoid the behavior of defined
- projections that can unfold to a case expression. To turn the use of
- native projections on, use [Set Primitive Projections]. Record,
- Class and Structure types defined while this option is set will be
- defined with primitive projections instead of the usual encoding as
- a case expression. For compatibility, when p is a primitive
- projection, @p can be used to refer to the projection with explicit
- parameters, i.e. [@p] is definitionally equal to [λ params r. r.(p)].
- Records with primitive projections have eta-conversion, the
- canonical form being [mkR pars (p1 t) ... (pn t)].
-- New universe polymorphism (see reference manual)
-- New option -type-in-type to collapse the universe hierarchy (this makes the
- logic inconsistent).
-- The guard condition for fixpoints is now a bit stricter. Propagation
- of subterm value through pattern matching is restricted according to
- the return predicate. Restores compatibility of Coq's logic with the
- propositional extensionality axiom. May create incompatibilities in
- recursive programs heavily using dependent types.
-- Trivial inductive types are no longer defined in Type but in Prop, which
- leads to a non-dependent induction principle being generated in place of
- the dependent one. To recover the old behavior, explicitly define your
- inductive types in Set.
-
-Vernacular commands
-
-- A command "Variant" allows to define non-recursive variant types.
-- The command "Record foo ..." does not generate induction principles
- (foo_rect, foo_rec, foo_ind) anymore by default (feature wish
- #2693). The command "Variant foo ..." does not either. A flag
- "Set/Unset Nonrecursive Elimination Schemes" allows changing this.
- The tactic "induction" on a "Record" or a "Variant" is now actually
- doing "destruct".
-- The "Open Scope" command can now be given also a delimiter (e.g. Z).
-- The "Definition" command now allows the "Local" modifier, allowing
- for non-importable definitions. The same goes for "Axiom" and "Parameter".
-- Section-specific commands such as "Let" (resp. "Variable", "Hypothesis") used
- out of a section now behave like the corresponding "Local" command, i.e.
- "Local Definition" (resp. "Local Parameter", "Local Axiom"). (potential source
- of rare incompatibilities).
-- The "Let" command can now define local (co)fixpoints.
-- Command "Search" has been renamed into "SearchHead". The command
- name "Search" now behaves like former "SearchAbout". The latter name
- is deprecated.
-- "Search", "About", "SearchHead", "SearchRewrite" and "SearchPattern"
- now search for hypothesis (of the current goal by default) first.
- They now also support the goal selector prefix to specify another
- goal to search: e.g. "n:Search id". This is also true for
- SearchAbout although it is deprecated.
-- The coq/user-contrib directory and the XDG directories are no longer
- recursively added to the load path, so files from installed libraries
- now need to be fully qualified for the "Require" command to find them.
- The tools/update-require script can be used to convert a development.
-- A new Print Strategies command allows visualizing the opacity status
- of the whole engine.
-- The "Locate" command now searches through all sorts of qualified namespaces of
- Coq: terms, modules, tactics, etc. The old behavior of the command can be
- retrieved using the "Locate Term" command.
-- New "Derive" command to help writing program by derivation.
-- New "Refine Instance Mode" option that allows to deactivate the generation of
- obligations in incomplete typeclass instances, raising an error instead.
-- "Collection" command to name sets of section hypotheses. Named collections
- can be used in the syntax of "Proof using" to assert which section variables
- are used in a proof.
-- The "Optimize Proof" command can be placed in the middle of a proof to
- force the compaction of the data structure used to represent the ongoing
- proof (evar map). This may result in a lower memory footprint and speed up
- the execution of the following tactics.
-- "Optimize Heap" command to tell the OCaml runtime to perform a major
- garbage collection step and heap compaction.
-- "Instance" no longer treats the {|...|} syntax specially; it handles it
- in the same way as other commands, e.g. "Definition". Use the {...}
- syntax (no pipe symbols) to recover the old behavior.
-
-Specification Language
-
-- Slight changes in unification error messages.
-- Added a syntax $(...)$ that allows putting tactics in terms (may
- break user notations using "$(", fixable by inserting a space or
- rewriting the notation).
-- Constructors in pattern-matching patterns now respect the same rules
- regarding implicit arguments as in applicative position. The old
- behavior can be recovered by the command "Set Asymmetric
- Patterns". As a side effect, notations for constructors explicitly
- mentioning non-implicit parameters can now be used in patterns.
- Considering that the pattern language is already rich enough, binding
- local definitions is however now forbidden in patterns (source of
- incompatibilities for local definitions that delta-reduce to a constructor).
-- Type inference algorithm now granting opacity of constants. This might also
- affect behavior of tactics (source of incompatibilities, solvable by
- re-declaring transparent constants which were set opaque).
-- Existential variables are now referred to by an identifier and the
- relevant part of their instance is displayed by default. They can be
- reparsed. The naming policy is yet unstable and subject to changes
- in future releases.
-
-Tactics
-
-- New tactic engine allowing dependent subgoals, fully backtracking
- (also known as multiple success) tactics, as well as tactics which
- can consider multiple goals together. In the new tactic engine,
- instantiation information of existential variables is always
- propagated to tactics, removing the need to manually use the
- "instantiate" tactics to mark propagation points.
- * New tactical (a+b) inserts a backtracking point. When (a+b);c fails
- during the execution of c, it can backtrack and try b instead of a.
- * New tactical (once a) removes all the backtracking points from a
- (i.e. it selects the first success of a).
- * Tactic "constructor" is now fully backtracking. In case of
- incompatibilities (e.g. combinatoric explosion), the former
- behavior of "constructor" can be retrieved by using instead
- "[> once constructor ..]". Thanks to backtracking, undocumented
- "constructor " syntax is now equivalent to
- "[> once (constructor; tac) ..]".
- * New "multimatch" variant of "match" tactic which backtracks to
- new branches in case of a later failure. The "match" tactic is
- equivalent to "once multimatch".
- * New selector "all:" such that "all:tac" applies tactic "tac" to
- all the focused goals, instead of just the first one as is the
- default.
- * A corresponding new option Set Default Goal Selector "all" makes
- the tactics in scripts be applied to all the focused goal by default
- * New selector "par:" such that "par:tac" applies the (terminating)
- tactic "tac" to all the focused goal in parallel. The number of worker
- can be selected with -async-proofs-tac-j and also limited using the
- coqworkmgr utility.
- * New tactics "revgoals", "cycle" and "swap" to reorder goals.
- * The semantics of recursive tactics (introduced with "Ltac t := ..."
- or "let rec t := ... in ...") changed slightly as t is now
- applied to every goal, not each goal independently. In particular
- it may be applied when no goals are left. This may cause tactics
- such as "let rec t := constructor;t" to loop indefinitely. The
- simple fix is to rewrite the recursive calls as follows:
- "let rec t := constructor;[t..]" which recovers the earlier behavior
- (source of rare incompatibilities).
- * New tactic language feature "numgoals" to count number of goals. It is
- accompanied by a "guard" tactic which fails if a Boolean test over
- integers does not pass.
- * New tactical "[> ... ]" to apply tactics to individual goals.
- * New tactic "gfail" which works like "fail" except it will also
- fail if every goal has been solved.
- * The refine tactic is changed not to use an ad hoc typing algorithm
- to generate subgoals. It also uses the dependent subgoal feature
- to generate goals to materialize every existential variable which
- is introduced by the refinement (source of incompatibilities).
- * A tactic shelve is introduced to manage the subgoals which may be
- solved by unification: shelve removes every goal it is applied to
- from focus. These goals can later be called back into focus by the
- Unshelve command.
- * A variant shelve_unifiable only removes those goals which appear
- as existential variables in other goals. To emulate the old
- refine, use "refine c;shelve_unifiable". This can still cause
- incompatibilities in rare occasions.
- * New "give_up" tactic to skip over a goal. A proof containing
- given up goals cannot be closed with "Qed", but only with "Admitted".
-- The implementation of the admit tactic has changed: no axiom is
- generated for the admitted sub proof. "admit" is now an alias for
- "give_up". Code relying on this specific behavior of "admit"
- can be made to work by:
- * Adding an "Axiom" for each admitted subproof.
- * Adding a single "Axiom proof_admitted : False." and the Ltac definition
- "Ltac admit := case proof_admitted.".
-- Matching using "lazymatch" was fundamentally modified. It now behaves
- like "match" (immediate execution of the matching branch) but without
- the backtracking mechanism in case of failure.
-- New "tryif t then u else v" tactical which executes "u" in case of success
- of "t" and "v" in case of failure.
-- New conversion tactic "native_compute": evaluates the goal (or an hypothesis)
- with a call-by-value strategy, using the OCaml native compiler. Useful on
- very intensive computations.
-- New "cbn" tactic, a well-behaved simpl.
-- Repeated identical calls to omega should now produce identical proof terms.
-- Tactics btauto, a reflexive Boolean tautology solver.
-- Tactic "tauto" was exceptionally able to destruct other connectives
- than the binary connectives "and", "or", "prod", "sum", "iff". This
- non-uniform behavior has been fixed (bug #2680) and tauto is
- slightly weaker (possible source of incompatibilities). On the
- opposite side, new tactic "dtauto" is able to destruct any
- record-like inductive types, superseding the old version of "tauto".
-- Similarly, "intuition" has been made more uniform and, where it now
- fails, "dintuition" can be used (possible source of incompatibilities).
-- New option "Unset Intuition Negation Unfolding" for deactivating automatic
- unfolding of "not" in intuition.
-- Tactic notations can now be defined locally to a module (use "Local" prefix).
-- Tactic "red" now reduces head beta-iota redexes (potential source of
- rare incompatibilities).
-- Tactic "hnf" now reduces inner beta-iota redexes
- (potential source of rare incompatibilities).
-- Tactic "intro H" now reduces beta-iota redexes if these hide a product
- (potential source of rare incompatibilities).
-- In Ltac matching on patterns of the form "_ pat1 ... patn" now
- behaves like if matching on "?X pat1 ... patn", i.e. accepting "_"
- to be instantiated by an applicative term (experimental at this
- stage, potential source of incompatibilities).
-- In Ltac matching on goal, types of hypotheses are now interpreted in
- the %type scope (possible source of incompatibilities).
-- "change ... in ..." and "simpl ... in ..." now properly consider nested
- occurrences (possible source of incompatibilities since this alters
- the numbering of occurrences), but do not support nested occurrences.
-- Tactics simpl, vm_compute and native_compute can be given a notation string
- to a constant as argument.
-- When given a reference as argument, simpl, vm_compute and
- native_compute now strictly interpret it as the head of a pattern
- starting with this reference.
-- The "change p with c" tactic semantics changed, now type-checking
- "c" at each matching occurrence "t" of the pattern "p", and
- converting "t" with "c".
-- Now "appcontext" and "context" behave the same. The old buggy behavior of
- "context" can be retrieved at parse time by setting the
- "Tactic Compat Context" flag (possible source of incompatibilities).
-- New introduction pattern p/c which applies lemma c on the fly on the
- hypothesis under consideration before continuing with introduction pattern p.
-- New introduction pattern [= x1 .. xn] applies "injection as [x1 .. xn]"
- on the fly if injection is applicable to the hypothesis under consideration
- (idea borrowed from Georges Gonthier). Introduction pattern [=] applies
- "discriminate" if a discriminable equality.
-- New introduction patterns * and ** to respectively introduce all forthcoming
- dependent variables and all variables/hypotheses dependent or not.
-- Tactic "injection c as ipats" now clears c if c refers to an
- hypothesis and moves the resulting equations in the hypotheses
- independently of the number of ipats, which has itself to be less
- than the number of new hypotheses (possible source of incompatibilities;
- former behavior obtainable by "Unset Injection L2R Pattern Order").
-- Tactic "injection" now automatically simplifies subgoals
- "existT n p = existT n p'" into "p = p'" when "n" is in an inductive type for
- which a decidable equality scheme has been generated with "Scheme Equality"
- (possible source of incompatibilities).
-- New tactic "rewrite_strat" for generalized rewriting with user-defined
- strategies, subsuming autorewrite.
-- Injection can now also deduce equality of arguments of sort Prop, by using
- the option "Set Injection On Proofs" (disabled by default). Also improved the
- error messages.
-- Tactic "subst id" now supports id occurring in dependent local definitions.
-- Bugs fixed about intro-pattern "*" might lead to some rare incompatibilities.
-- New tactical "time" to display time spent executing its argument.
-- Tactics referring or using a constant dependent in a section variable which
- has been cleared or renamed in the current goal context now fail
- (possible source of incompatibilities solvable by avoiding clearing
- the relevant hypotheses).
-- New construct "uconstr:c" and "type_term c" to build untyped terms.
-- Binders in terms defined in Ltac (either "constr" or "uconstr") can
- now take their names from identifiers defined in Ltac. As a
- consequence, a name cannot be used in a binder "constr:(fun x =>
- ...)" if an Ltac variable of that name already exists and does not
- contain an identifier. Source of occasional incompatibilities.
-- The "refine" tactic now accepts untyped terms built with "uconstr"
- so that terms with holes can be constructed piecewise in Ltac.
-- New bullets --, ++, **, ---, +++, ***, ... made available.
-- More informative messages when wrong bullet is used.
-- Bullet suggestion when a subgoal is solved.
-- New tactic "enough", symmetric to "assert", but with subgoals
- swapped, as a more friendly replacement of "cut".
-- In destruct/induction, experimental modifier "!" prefixing the
- hypothesis name to tell not erasing the hypothesis.
-- Bug fixes in "inversion as" may occasionally lead to incompatibilities.
-- Behavior of introduction patterns -> and <- made more uniform
- (hypothesis is cleared, rewrite in hypotheses and conclusion and
- erasing the variable when rewriting a variable).
-- New experimental option "Set Standard Proposition Elimination Names"
- so that case analysis or induction on schemes in Type containing
- propositions now produces "H"-based names.
-- Tactics from plugins are now active only when the corresponding module
- is imported (source of incompatibilities, solvable by adding an "Import";
- in the particular case of Omega, use "Require Import OmegaTactic").
-- Semantics of destruct/induction has been made more regular in some
- edge cases, possibly leading to incompatibilities:
- - new goals are now opened when the term does not match a subterm of
- the goal and has unresolved holes, while in 8.4 these holes were
- turned into existential variables
- - when no "at" option is given, the historical semantics which
- selects all subterms syntactically identical to the first subterm
- matching the given pattern is used
- - non-dependent destruct/induction on an hypothesis with premises in
- an inductive type with indices is fixed
- - residual local definitions are now correctly removed.
-- The rename tactic may now replace variables in parallel.
-- A new "Info" command replaces the "info" tactical discontinued in
- v8.4. It still gives informative results in many cases.
-- The "info_auto" tactic is known to be broken and does not print a
- trace anymore. Use "Info 1 auto" instead. The same goes for
- "info_trivial". On the other hand "info_eauto" still works fine,
- while "Info 1 eauto" prints a trivial trace.
-- When using a lemma of the prototypical form "forall A, {a:A & P a}",
- "apply" and "apply in" do not instantiate anymore "A" with the
- current goal and use "a" as the proof, as they were sometimes doing,
- now considering that it is a too powerful decision.
-
-Program
-
-- "Solve Obligations using" changed to "Solve Obligations with",
- consistent with "Proof with".
-- Program Lemma, Definition now respect automatic introduction.
-- Program Lemma, Definition, etc.. now interpret "->" like Lemma and
- Definition as a non-dependent arrow (potential source of
- incompatibility).
-- Add/document "Set Hide Obligations" (to hide obligations in the final
- term inside an implicit argument) and "Set Shrink Obligations" (to
- minimize dependencies of obligations defined by tactics).
-
-Notations
-
-- The syntax "x -> y" is now declared at level 99. In particular, it has
- now a lower priority than "<->": "A -> B <-> C" is now "A -> (B <-> C)"
- (possible source of incompatibilities)
-- Notations accept term-providing tactics using the $(...)$ syntax.
-- "Bind Scope" can no longer bind "Funclass" and "Sortclass".
-- A notation can be given a (compat "8.x") annotation, making it behave
- like a "only parsing" notation, but the annotation may lead to eventually
- issue warnings or errors in further versions when this notation is used.
-- More systematic insertion of spaces as a default for printing
- notations ("format" still available to override the default).
-- In notations, a level modifier referring to a non-existent variable is
- now considered an error rather than silently ignored.
-
-Tools
-
-- Option -I now only adds directories to the ml path.
-- Option -Q behaves as -R, except that the logical path of any loaded file has
- to be fully qualified.
-- Option -R no longer adds recursively to the ml path; only the root
- directory is added. (Behavior with respect to the load path is
- unchanged.)
-- Option -nois prevents coq/theories and coq/plugins to be recursively
- added to the load path. (Same behavior as with coq/user-contrib.)
-- coqdep accepts a -dumpgraph option generating a dot file.
-- Makefiles generated through coq_makefile have three new targets "quick"
- "checkproofs" and "vio2vo", allowing respectively to asynchronously compile
- the files without playing the proof scripts, asynchronously checking
- that the quickly generated proofs are correct and generating the object
- files from the quickly generated proofs.
-- The XML plugin was discontinued and removed from the source.
-- A new utility called coqworkmgr can be used to limit the number of
- concurrent workers started by independent processes, like make and CoqIDE.
- This is of interest for users of the par: goal selector.
-
-Interfaces
-
-- CoqIDE supports asynchronous edition of the document, ongoing tasks and
- errors are reported in the bottom right window. The number of workers
- taking care of processing proofs can be selected with -async-proofs-j.
-- CoqIDE highlights in yellow "unsafe" commands such as axiom
- declarations, and tactics like "give_up".
-- CoqIDE supports Proof General like key bindings;
- to activate the PG mode go to Edit -> Preferences -> Editor.
- For the documentation see Help -> Help for PG mode.
-- CoqIDE automatically retracts the locked area when one edits the
- locked text.
-- CoqIDE search and replace got regular expressions power. See the
- documentation of OCaml's Str module for the supported syntax.
-- Many CoqIDE windows, including the query one, are now detachable to
- improve usability on multi screen work stations.
-- Coqtop/coqc outputs highlighted syntax. Colors can be configured thanks
- to the COQ_COLORS environment variable, and their current state can
- be displayed with the -list-tags command line option.
-- Third party user interfaces can install their main loop in $COQLIB/toploop
- and call coqtop with the -toploop flag to select it.
-
-Internal Infrastructure
-
-- Many reorganizations in the ocaml source files. For instance,
- many internal a.s.t. of Coq are now placed in mli files in
- a new directory intf/, for instance constrexpr.mli or glob_term.mli.
- More details in dev/doc/changes.
-- The file states/initial.coq does not exist anymore. Instead, coqtop
- initially does a "Require" of Prelude.vo (or nothing when given
- the options -noinit or -nois).
-- The format of vo files has slightly changed: cf final comments in
- checker/cic.mli.
-- The build system does not produce anymore programs named coqtop.opt
- and a symbolic link to coqtop. Instead, coqtop is now directly
- an executable compiled with the best OCaml compiler available.
- The bytecode program coqtop.byte is still produced. Same for other
- utilities.
-- Some options of the ./configure script slightly changed:
- * The -coqrunbyteflags and its blank-separated argument is replaced
- by option -vmbyteflags which expects a comma-separated argument.
- * The -coqtoolsbyteflags option is discontinued, see -no-custom instead.
-
-Miscellaneous
-
-- ML plugins now require a "DECLARE PLUGIN \"foo\"" statement. The "foo" name
- must be exactly the name of the ML module that will be loaded through a
- "Declare ML \"foo\"" command.
-
-Changes from V8.4beta2 to V8.4
-==============================
-
-Vernacular commands
-
-- The "Reset" command is now supported again in files given to coqc or Load.
-- "Show Script" now indents again the displayed scripts. It can also work
- correctly across Load'ed files if the option "Unset Atomic Load" is used.
-- "Open Scope" can now be given the delimiter (e.g. Z) instead of the full
- scope name (e.g. Z_scope).
-
-Notations
-
-- Most compatibility notations of the standard library are now tagged as
- (compat xyz), where xyz is a former Coq version, for instance "8.3".
- These notations behave as (only parsing) notations, except that they may
- triggers warnings (or errors) when used while Coq is not in a corresponding
- -compat mode.
-- To activate these compatibility warnings, use "Set Verbose Compat Notations"
- or the command-line flag -verbose-compat-notations.
-- For a strict mode without these compatibility notations, use
- "Unset Compat Notations" or the command-line flag -no-compat-notations.
-
-Tactics
-
-- An annotation "eqn:H" or "eqn:?" can be added to a "destruct"
- or "induction" to make it generate equations in the spirit of "case_eq".
- The former syntax "_eqn" is discontinued.
-- The name of the hypothesis introduced by tactic "remember" can be
- set via the new syntax "remember t as x eqn:H" (wish #2489).
-
-Libraries
-
-- Reals: changed definition of PI, no more axiom about sin(PI/2).
-- SetoidPermutation: a notion of permutation for lists modulo a setoid equality.
-- BigN: fixed the ocaml code doing the parsing/printing of big numbers.
-- List: a couple of lemmas added especially about no-duplication, partitions.
-- Init: Removal of the coercions between variants of sigma-types and
- subset types (possible source of incompatibility).
-
-Changes from V8.4beta to V8.4beta2
-==================================
-
-Vernacular commands
-
-- Commands "Back" and "BackTo" are now handling the proof states. They may
- perform some extra steps of backtrack to avoid states where the proof
- state is unavailable (typically a closed proof).
-- The commands "Suspend" and "Resume" have been removed.
-- A basic Show Script has been reintroduced (no indentation).
-- New command "Set Parsing Explicit" for deactivating parsing (and printing)
- of implicit arguments (useful for teaching).
-- New command "Grab Existential Variables" to transform the unresolved evars
- at the end of a proof into goals.
-
-Tactics
-
-- Still no general "info" tactical, but new specific tactics info_auto,
- info_eauto, info_trivial which provides information on the proofs found
- by auto/eauto/trivial. Display of these details could also be activated by
- "Set Info Auto"/"Set Info Eauto"/"Set Info Trivial".
-- Details on everything tried by auto/eauto/trivial during a proof search
- could be obtained by "debug auto", "debug eauto", "debug trivial" or by a
- global "Set Debug Auto"/"Set Debug Eauto"/"Set Debug Trivial".
-- New command "r string" in Ltac debugger that interprets "idtac
- string" in Ltac code as a breakpoint and jumps to its next use.
-- Tactics from the Dp plugin (simplify, ergo, yices, cvc3, z3, cvcl,
- harvey, zenon, gwhy) have been removed, since Why2 has not been
- maintained for the last few years. The Why3 plugin should be a suitable
- replacement in most cases.
-
-Libraries
-
-- MSetRBT: a new implementation of MSets via Red-Black trees (initial
- contribution by Andrew Appel).
-- MSetAVL: for maximal sharing with the new MSetRBT, the argument order
- of Node has changed (this should be transparent to regular MSets users).
-
-Module System
-
-- The names of modules (and module types) are now in a fully separated
- namespace from ordinary definitions: "Definition E:=0. Module E. End E."
- is now accepted.
-
-CoqIDE
-
-- Coqide now supports the "Restart" command, and "Undo" (with a warning).
- Better support for "Abort".
-
-Changes from V8.3 to V8.4beta
-=============================
-
-Logic
-
-- Standard eta-conversion now supported (dependent product only).
-- Guard condition improvement: subterm property is propagated through beta-redex
- blocked by pattern-matching, as in "(match v with C .. => fun x => u end) x";
- this allows for instance to use "rewrite ... in ..." without breaking
- the guard condition.
-
-Specification language and notations
-
-- Maximal implicit arguments can now be set locally by { }. The registration
- traverses fixpoints and lambdas. Because there is conversion in types,
- maximal implicit arguments are not taken into account in partial
- applications (use eta expanded form with explicit { } instead).
-- Added support for recursive notations with binders (allows for instance
- to write "exists x y z, P").
-- Structure/Record printing can be disable by "Unset Printing Records".
- In addition, it can be controlled on type by type basis using
- "Add Printing Record" or "Add Printing Constructor".
-- Pattern-matching compilation algorithm: in "match x, y with ... end",
- possible dependencies of x (or of the indices of its type) in the type
- of y are now taken into account.
-
-Tactics
-
-- New proof engine.
-- Scripts can now be structured thanks to bullets - * + and to subgoal
- delimitation via { }. Note: for use with Proof General, a cvs version of
- Proof General no older than mid-July 2011 is currently required.
-- Support for tactical "info" is suspended.
-- Support for command "Show Script" is suspended.
-- New tactics constr_eq, is_evar and has_evar for use in Ltac (DOC TODO).
-- Removed the two-argument variant of "decide equality".
-- New experimental tactical "timeout ". Since is a time
- in second for the moment, this feature should rather be avoided
- in scripts meant to be machine-independent.
-- Fix in "destruct": removal of unexpected local definitions in context might
- result in some rare incompatibilities (solvable by adapting name hypotheses).
-- Introduction pattern "_" made more robust.
-- Tactic (and Eval command) vm_compute can now be interrupted via Ctrl-C.
-- Unification in "apply" supports unification of patterns of the form
- ?f x y = g(x,y) (compatibility ensured by using
- "Unset Tactic Pattern Unification"). It also supports (full) betaiota.
-- Tactic autorewrite does no longer instantiate pre-existing
- existential variables (theoretical source of possible incompatibilities).
-- Tactic "dependent rewrite" now supports equality in "sig".
-- Tactic omega now understands Zpred (wish #1912) and can prove any goal
- from a context containing an arithmetical contradiction (wish #2236).
-- Using "auto with nocore" disables the use of the "core" database (wish #2188).
- This pseudo-database "nocore" can also be used with trivial and eauto.
-- Tactics "set", "destruct" and "induction" accepts incomplete terms and
- use the goal to complete the pattern assuming it is non ambiguous.
-- When used on arguments with a dependent type, tactics such as
- "destruct", "induction", "case", "elim", etc. now try to abstract
- automatically the dependencies over the arguments of the types
- (based on initial ideas from Chung-Kil Hur, extension to nested
- dependencies suggested by Dan Grayson)
-- Tactic "injection" now failing on an equality showing no constructors while
- it was formerly generalizing again the goal over the given equality.
-- In Ltac, the "context [...]" syntax has now a variant "appcontext [...]"
- allowing to match partial applications in larger applications.
-- When applying destruct or inversion on a fixpoint hiding an inductive
- type, recursive calls to the fixpoint now remain folded by default (rare
- source of incompatibility generally solvable by adding a call to simpl).
-- In an ltac pattern containing a "match", a final "| _ => _" branch could be
- used now instead of enumerating all remaining constructors. Moreover, the
- pattern "match _ with _ => _ end" now allows to match any "match". A "in"
- annotation can also be added to restrict to a precise inductive type.
-- The behavior of "simpl" can be tuned using the "Arguments" vernacular.
- In particular constants can be marked so that they are always/never unfolded
- by "simpl", or unfolded only when a set of arguments evaluates to a
- constructor. Last one can mark a constant so that it is unfolded only if the
- simplified term does not expose a match in head position.
-
-Vernacular commands
-
-- It is now mandatory to have a space (or tabulation or newline or end-of-file)
- after a "." ending a sentence.
-- In SearchAbout, the [ ] delimiters are now optional.
-- New command "Add/Remove Search Blacklist ...":
- a Search or SearchAbout or similar query will never mention lemmas
- whose qualified names contain any of the declared substrings.
- The default blacklisted substrings are "_subproof" "Private_".
-- When the output file of "Print Universes" ends in ".dot" or ".gv",
- the universe graph is printed in the DOT language, and can be
- processed by Graphviz tools.
-- New command "Print Sorted Universes".
-- The undocumented and obsolete option "Set/Unset Boxed Definitions" has
- been removed, as well as syntaxes like "Boxed Fixpoint foo".
-- A new option "Set Default Timeout n / Unset Default Timeout".
-- Qed now uses information from the reduction tactics used in proof script
- to avoid conversion at Qed time to go into a very long computation.
-- New command "Show Goal ident" to display the statement of a goal, even
- a closed one (available from Proof General).
-- Command "Proof" accept a new modifier "using" to force generalization
- over a given list of section variables at section ending (DOC TODO).
-- New command "Arguments" generalizing "Implicit Arguments" and
- "Arguments Scope" and that also allows to rename the parameters of a
- definition and to tune the behavior of the tactic "simpl".
-
-Module System
-
-- During subtyping checks, an opaque constant in a module type could now
- be implemented by anything of the right type, even if bodies differ.
- Said otherwise, with respect to subtyping, an opaque constant behaves
- just as a parameter. Coqchk was already implementing this, but not coqtop.
-- The inlining done during application of functors can now be controlled
- more precisely, by the annotations (no inline) or (inline at level XX).
- With the latter annotation, only functor parameters whose levels
- are lower or equal than XX will be inlined.
- The level of a parameter can be fixed by "Parameter Inline(30) foo".
- When levels aren't given, the default value is 100. One can also use
- the flag "Set Inline Level ..." to set a level (DOC TODO).
-- Print Assumptions should now handle correctly opaque modules (#2168).
-- Print Module (Type) now tries to print more details, such as types and
- bodies of the module elements. Note that Print Module Type could be
- used on a module to display only its interface. The option
- "Set Short Module Printing" could be used to switch back to the earlier
- behavior were only field names were displayed.
-
-Libraries
-
-- Extension of the abstract part of Numbers, which now provide axiomatizations
- and results about many more integer functions, such as pow, gcd, lcm, sqrt,
- log2 and bitwise functions. These functions are implemented for nat, N, BigN,
- Z, BigZ. See in particular file NPeano for new functions about nat.
-- The definition of types positive, N, Z is now in file BinNums.v
-- Major reorganization of ZArith. The initial file ZArith/BinInt.v now contains
- an internal module Z implementing the Numbers interface for integers.
- This module Z regroups:
- * all functions over type Z : Z.add, Z.mul, ...
- * the minimal proofs of specifications for these functions : Z.add_0_l, ...
- * an instantation of all derived properties proved generically in Numbers :
- Z.add_comm, Z.add_assoc, ...
- A large part of ZArith is now simply compatibility notations, for instance
- Zplus_comm is an alias for Z.add_comm. The direct use of module Z is now
- recommended instead of relying on these compatibility notations.
-- Similar major reorganization of NArith, via a module N in NArith/BinNat.v
-- Concerning the positive datatype, BinPos.v is now in a specific directory
- PArith, and contains an internal submodule Pos. We regroup there functions
- such as Pos.add Pos.mul etc as well as many results about them. These results
- are here proved directly (no Number interface for strictly positive numbers).
-- Note that in spite of the compatibility layers, all these reorganizations
- may induce some marginal incompatibilies in scripts. In particular:
- * the "?=" notation for positive now refers to a binary function Pos.compare,
- instead of the infamous ternary Pcompare (now Pos.compare_cont).
- * some hypothesis names generated by the system may changed (typically for
- a "destruct Z_le_gt_dec") since naming is done after the short name of
- the head predicate (here now "le" in module Z instead of "Zle", etc).
- * the internals of Z.add has changed, now relying of Z.pos_sub.
-- Also note these new notations:
- * "" "<=?" "=?" for boolean tests such as Z.ltb Z.leb Z.eqb.
- * "÷" for the alternative integer division Z.quot implementing the Truncate
- convention (former ZOdiv), while the notation for the Coq usual division
- Z.div implementing the Flooring convention remains "/". Their corresponding
- modulo functions are Z.rem (no notations) for Z.quot and Z.modulo (infix
- "mod" notation) for Z.div.
-- Lemmas about conversions between these datatypes are also organized
- in modules, see for instance modules Z2Nat, N2Z, etc.
-- When creating BigN, the macro-generated part NMake_gen is much smaller.
- The generic part NMake has been reworked and improved. Some changes
- may introduce incompatibilities. In particular, the order of the arguments
- for BigN.shiftl and BigN.shiftr is now reversed: the number to shift now
- comes first. By default, the power function now takes two BigN.
-- Creation of Vector, an independent library for lists indexed by their length.
- Vectors' names overwrite lists' one so you should not "Import" the library.
- All old names changed: function names follow the ocaml ones and, for example,
- Vcons becomes Vector.cons. You can get [..;..;..]-style notations by importing
- Vector.VectorNotations.
-- Removal of TheoryList. Requiring List instead should work most of the time.
-- New syntax "rew Heq in H" and "rew <- Heq in H" for eq_rect and
- eq_rect_r (available by importing module EqNotations).
-- Wf.iter_nat is now Peano.nat_iter (with an implicit type argument).
-
-Internal infrastructure
-
-- Opaque proofs are now loaded lazily by default. This allows to be almost as
- fast as -dont-load-proofs, while being safer (no creation of axioms) and
- avoiding feature restrictions (Print and Print Assumptions work ok).
-- Revised hash-consing code allowing more sharing of memory
-- Experimental support added for camlp4 (the one provided alongside ocaml),
- simply pass option -usecamlp4 to ./configure. By default camlp5 is used.
-- Revised build system: no more stages in Makefile thanks to some recursive
- aspect of recent gnu make, use of vo.itarget files containing .v to compile
- for both make and ocamlbuild, etc.
-- Support of cross-compilation via mingw from unix toward Windows,
- contact P. Letouzey for more informations.
-- New Makefile rules mli-doc to make html of mli in dev/doc/html and
- full-stdlib to get a (huge) pdf reflecting the whole standard library.
-
-Extraction
-
-- By default, opaque terms are now truly considered opaque by extraction:
- instead of accessing their body, they are now considered as axioms.
- The previous behaviour can be reactivated via the option
- "Set Extraction AccessOpaque".
-- The pretty-printer for Haskell now produces layout-independent code
-- A new command "Separate Extraction cst1 cst2 ..." that mixes a
- minimal extracted environment a la "Recursive Extraction" and the
- production of several files (one per coq source) a la "Extraction Library"
- (DOC TODO).
-- New option "Set/Unset Extraction KeepSingleton" for preventing the
- extraction to optimize singleton container types (DOC TODO).
-- The extraction now identifies and properly rejects a particular case of
- universe polymorphism it cannot handle yet (the pair (I,I) being Prop).
-- Support of anonymous fields in record (#2555).
-
-CoqIDE
-
-- Coqide now runs coqtop as separated process, making it more robust:
- coqtop subprocess can be interrupted, or even killed and relaunched
- (cf button "Restart Coq", ex-"Go to Start"). For allowing such
- interrupts, the Windows version of coqide now requires Windows >= XP
- SP1.
-- The communication between CoqIDE and Coqtop is now done via a dialect
- of XML (DOC TODO).
-- The backtrack engine of CoqIDE has been reworked, it now uses the
- "Backtrack" command similarly to Proof General.
-- The Coqide parsing of sentences has be reworked and now supports
- tactic delimitation via { }.
-- Coqide now accepts the Abort command (wish #2357).
-- Coqide can read coq_makefile files as "project file" and use it to
- set automatically options to send to coqtop.
-- Preference files have moved to $XDG_CONFIG_HOME/coq and accelerators
- are not stored as a list anymore.
-
-Tools
-
-- Coq now searches directories specified in COQPATH, $XDG_DATA_HOME/coq,
- $XDG_DATA_DIRS/coq, and user-contribs before the standard library.
-- Coq rc file has moved to $XDG_CONFIG_HOME/coq.
-- Major changes to coq_makefile:
- * mli/mlpack/mllib taken into account, ml not preproccessed anymore, ml4 work;
- * mlihtml generates doc of mli, install-doc install the html doc in DOCDIR
- with the same policy as vo in COQLIB;
- * More variables are given by coqtop -config, others are defined only if the
- users doesn't have defined them elsewhere. Consequently, generated makefile
- should work directly on any architecture;
- * Packagers can take advantage of $(DSTROOT) introduction. Installation can
- be made in $XDG_DATA_HOME/coq;
- * -arg option allows to send option as argument to coqc.
-
-Changes from V8.2 to V8.3
-=========================
-
-Rewriting tactics
-
-- Tactic "rewrite" now supports rewriting on ad hoc equalities such as eq_true.
-- "Hint Rewrite" now checks that the lemma looks like an equation.
-- New tactic "etransitivity".
-- Support for heterogeneous equality (JMeq) in "injection" and "discriminate".
-- Tactic "subst" now supports heterogeneous equality and equality
- proofs that are dependent (use "simple subst" for preserving compatibility).
-- Added support for Leibniz-rewriting of dependent hypotheses.
-- Renamed "Morphism" into "Proper" and "respect" into "proper_prf"
- (possible source of incompatibility). A partial fix is to define
- "Notation Morphism R f := (Proper (R%signature) f)."
-- New tactic variants "rewrite* by" and "autorewrite*" that rewrite
- respectively the first and all matches whose side-conditions are
- solved.
-- "Require Import Setoid" does not export all of "Morphisms" and
- "RelationClasses" anymore (possible source of incompatibility, fixed
- by importing "Morphisms" too).
-- Support added for using Chung-Kil Hur's Heq library for rewriting over
- heterogeneous equality (courtesy of the library's author).
-- Tactic "replace" supports matching terms with holes.
-
-Automation tactics
-
-- Tactic "intuition" now preserves inner "iff" and "not" (exceptional
- source of incompatibilities solvable by redefining "intuition" as
- "unfold iff, not in *; intuition", or, for iff only, by using
- "Set Intuition Iff Unfolding".)
-- Tactic "tauto" now proves classical tautologies as soon as classical logic
- (i.e. library Classical_Prop or Classical) is loaded.
-- Tactic "gappa" has been removed from the Dp plugin.
-- Tactic "firstorder" now supports the combination of its "using" and
- "with" options.
-- New "Hint Resolve ->" (or "<-") for declaring iff's as oriented
- hints (wish #2104).
-- An inductive type as argument of the "using" option of "auto/eauto/firstorder"
- is interpreted as using the collection of its constructors.
-- New decision tactic "nsatz" to prove polynomial equations
- by computation of Groebner bases.
-
-Other tactics
-
-- Tactic "discriminate" now performs intros before trying to discriminate an
- hypothesis of the goal (previously it applied intro only if the goal
- had the form t1<>t2) (exceptional source of incompatibilities - former
- behavior can be obtained by "Unset Discriminate Introduction").
-- Tactic "quote" now supports quotation of arbitrary terms (not just the
- goal).
-- Tactic "idtac" now displays its "list" arguments.
-- New introduction patterns "*" for introducing the next block of dependent
- variables and "**" for introducing all quantified variables and hypotheses.
-- Pattern Unification for existential variables activated in tactics and
- new option "Unset Tactic Evars Pattern Unification" to deactivate it.
-- Resolution of canonical structure is now part of the tactic's unification
- algorithm.
-- New tactic "decide lemma with hyp" for rewriting decidability lemmas
- when one knows which side is true.
-- Improved support of dependent goals over objects in dependent types for
- "destruct" (rare source of incompatibility that can be avoided by unsetting
- option "Dependent Propositions Elimination").
-- Tactic "exists", "eexists", "destruct" and "edestruct" supports iteration
- using comma-separated arguments.
-- Tactic names "case" and "elim" now support clauses "as" and "in" and become
- then synonymous of "destruct" and "induction" respectively.
-- A new tactic name "exfalso" for the use of 'ex-falso quodlibet' principle.
- This tactic is simply a shortcut for "elimtype False".
-- Made quantified hypotheses get the name they would have if introduced in
- the context (possible but rare source of incompatibilities).
-- When applying a component of a conjunctive lemma, "apply in" (and
- sequences of "apply in") now leave the side conditions of the lemmas
- uniformly after the main goal (possible source of rare incompatibilities).
-- In "simpl c" and "change c with d", c can be a pattern.
-- Tactic "revert" now preserves let-in's making it the exact inverse of
- "intro".
-- New tactics "clear dependent H" and "revert dependent H" that
- clears (resp. reverts) H and all the hypotheses that depend on H.
-- Ltac's pattern-matching now supports matching metavariables that
- depend on variables bound upwards in the pattern.
-
-Tactic definitions
-
-- Ltac definitions support Local option for non-export outside modules.
-- Support for parsing non-empty lists with separators in tactic notations.
-- New command "Locate Ltac" to get the full name of an Ltac definition.
-
-Notations
-
-- Record syntax "{|x=...; y=...|}" now works inside patterns too.
-- Abbreviations from non-imported module now invisible at printing time.
-- Abbreviations now use implicit arguments and arguments scopes for printing.
-- Abbreviations to pure names now strictly behave like the name they refer to
- (make redirections of qualified names easier).
-- Abbreviations for applied constant now propagate the implicit arguments
- and arguments scope of the underlying reference (possible source of
- incompatibilities generally solvable by changing such abbreviations from
- e.g. "Notation foo' := (foo x)" to "Notation foo' y := (foo x (y:=y))").
-- The "where" clause now supports multiple notations per defined object.
-- Recursive notations automatically expand one step on the left for better
- factorization; recursion notations inner separators now ensured being tokens.
-- Added "Reserved Infix" as a specific shortcut of the corresponding
- "Reserved Notation".
-- Open/Close Scope command supports Global option in sections.
-
-Specification language
-
-- New support for local binders in the syntax of Record/Structure fields.
-- Fixpoint/CoFixpoint now support building part or all of bodies using tactics.
-- Binders given before ":" in lemmas and in definitions built by tactics are
- now automatically introduced (possible source of incompatibility that can
- be resolved by invoking "Unset Automatic Introduction").
-- New support for multiple implicit arguments signatures per reference.
-
-Module system
-
-- Include Type is now deprecated since Include now accept both modules and
- module types.
-- Declare ML Module supports Local option.
-- The sharing between non-logical object and the management of the
- name-space has been improved by the new "Delta-equivalence" on
- qualified name.
-- The include operator has been extended to high-order structures
-- Sequences of Include can be abbreviated via new syntax "<+".
-- A module (or module type) can be given several "<:" signatures.
-- Interactive proofs are now permitted in module type. Functors can hence
- be declared as Module Type and be used later to type themselves.
-- A functor application can be prefixed by a "!" to make it ignore any
- "Inline" annotation in the type of its argument(s) (for examples of
- use of the new features, see libraries Structures and Numbers).
-- Coercions are now active only when modules are imported (use "Set Automatic
- Coercions Import" to get the behavior of the previous versions of Coq).
-
-Extraction
-
-- When using (Recursive) Extraction Library, the filenames are directly the
- Coq ones with new appropriate extensions : we do not force anymore
- uncapital first letters for Ocaml and capital ones for Haskell.
-- The extraction now tries harder to avoid code transformations that can be
- dangerous for the complexity. In particular many eta-expansions at the top
- of functions body are now avoided, clever partial applications will likely
- be preserved, let-ins are almost always kept, etc.
-- In the same spirit, auto-inlining is now disabled by default, except for
- induction principles, since this feature was producing more frequently
- weird code than clear gain. The previous behavior can be restored via
- "Set Extraction AutoInline".
-- Unicode characters in identifiers are now transformed into ascii strings
- that are legal in Ocaml and other languages.
-- Harsh support of module extraction to Haskell and Scheme: module hierarchy
- is flattened, module abbreviations and functor applications are expanded,
- module types and unapplied functors are discarded.
-- Less unsupported situations when extracting modules to Ocaml. In particular
- module parameters might be alpha-renamed if a name clash is detected.
-- Extract Inductive is now possible toward non-inductive types (e.g. nat => int)
-- Extraction Implicit: this new experimental command allows to mark
- some arguments of a function or constructor for removed during
- extraction, even if these arguments don't fit the usual elimination
- principles of extraction, for instance the length n of a vector.
-- Files ExtrOcaml*.v in plugins/extraction try to provide a library of common
- extraction commands: mapping of basics types toward Ocaml's counterparts,
- conversions from/to int and big_int, or even complete mapping of nat,Z,N
- to int or big_int, or mapping of ascii to char and string to char list
- (in this case recognition of ascii constants is hard-wired in the extraction).
-
-Program
-
-- Streamlined definitions using well-founded recursion and measures so
- that they can work on any subset of the arguments directly (uses currying).
-- Try to automatically clear structural fixpoint prototypes in
- obligations to avoid issues with opacity.
-- Use return type clause inference in pattern-matching as in the standard
- typing algorithm.
-- Support [Local Obligation Tactic] and [Next Obligation with tactic].
-- Use [Show Obligation Tactic] to print the current default tactic.
-- [fst] and [snd] have maximal implicit arguments in Program now (possible
- source of incompatibility).
-
-Type classes
-
-- Declaring axiomatic type class instances in Module Type should be now
- done via new command "Declare Instance", while the syntax "Instance"
- now always provides a concrete instance, both in and out of Module Type.
-- Use [Existing Class foo] to declare foo as a class a posteriori.
- [foo] can be an inductive type or a constant definition. No
- projections or instances are defined.
-- Various bug fixes and improvements: support for defined fields,
- anonymous instances, declarations giving terms, better handling of
- sections and [Context].
-
-Vernacular commands
-
-- New command "Timeout ." interprets a command and a timeout
- interrupts the interpretation after seconds.
-- New command "Compute ." is a shortcut for "Eval vm_compute in ".
-- New command "Fail ." interprets a command and is successful iff
- the command fails on an error (but not an anomaly). Handy for tests and
- illustration of wrong commands.
-- Most commands referring to constant (e.g. Print or About) now support
- referring to the constant by a notation string.
-- New option "Boolean Equality Schemes" to make generation of boolean
- equality automatic for datatypes (together with option "Decidable
- Equality Schemes", this replaces deprecated option "Equality Scheme").
-- Made support for automatic generation of case analysis schemes available
- to user (governed by option "Set Case Analysis Schemes").
-- New command "(Global?) Generalizable [All|No] Variable(s)? ident(s)?" to
- declare which identifiers are generalizable in `{} and `() binders.
-- New command "Print Opaque Dependencies" to display opaque constants in
- addition to all variables, parameters or axioms a theorem or
- definition relies on.
-- New command "Declare Reduction := ", allowing to write
- later "Eval in ...". This command accepts a Local variant.
-- Syntax of Implicit Type now supports more than one block of variables of
- a given type.
-- Command "Canonical Structure" now warns when it has no effects.
-- Commands of the form "Set X" or "Unset X" now support "Local" and "Global"
- prefixes.
-
-Library
-
-- Use "standard" Coq names for the properties of eq and identity
- (e.g. refl_equal is now eq_refl). Support for compatibility is provided.
-- The function Compare_dec.nat_compare is now defined directly,
- instead of relying on lt_eq_lt_dec. The earlier version is still
- available under the name nat_compare_alt.
-- Lemmas in library Relations and Reals have been homogenized a bit.
-- The implicit argument of Logic.eq is now maximally inserted, allowing
- to simply write "eq" instead of "@eq _" in morphism signatures.
-- Wrongly named lemmas (Zlt_gt_succ and Zlt_succ_gt) fixed (potential source
- of incompatibilities)
-- List library:
- - Definitions of list, length and app are now in Init/Datatypes.
- Support for compatibility is provided.
- - Definition of Permutation is now in Sorting/Permtation.v
- - Some other light revisions and extensions (possible source
- of incompatibilities solvable by qualifying names accordingly).
-- In ListSet, set_map has been fixed (source of incompatibilities if used).
-- Sorting library:
- - new mergesort of worst-case complexity O(n*ln(n)) made available in
- Mergesort.v;
- - former notion of permutation up to setoid from Permutation.v is
- deprecated and moved to PermutSetoid.v;
- - heapsort from Heap.v of worst-case complexity O(n*n) is deprecated;
- - new file Sorted.v for some definitions of being sorted.
-- Structure library. This new library is meant to contain generic
- structures such as types with equalities or orders, either
- in Module version (for now) or Type Classes (still to do):
- - DecidableType.v and OrderedType.v: initial notions for FSets/FMaps,
- left for compatibility but considered as deprecated.
- - Equalities.v and Orders.v: evolutions of the previous files,
- with fine-grain Module architecture, many variants, use of
- Equivalence and other relevant Type Classes notions.
- - OrdersTac.v: a generic tactic for solving chains of (in)equalities
- over variables. See {Nat,N,Z,P}OrderedType.v for concrete instances.
- - GenericMinMax.v: any ordered type can be equipped with min and max.
- We derived here all the generic properties of these functions.
-- MSets library: an important evolution of the FSets library.
- "MSets" stands for Modular (Finite) Sets, by contrast with a forthcoming
- library of Class (Finite) Sets contributed by S. Lescuyer which will be
- integrated with the next release of Coq. The main features of MSets are:
- - The use of Equivalence, Proper and other Type Classes features
- easing the handling of setoid equalities.
- - The interfaces are now stated in iff-style. Old specifications
- are now derived properties.
- - The compare functions are now pure, and return a "comparison" value.
- Thanks to the CompSpec inductive type, reasoning on them remains easy.
- - Sets structures requiring invariants (i.e. sorted lists) are
- built first as "Raw" sets (pure objects and separate proofs) and
- attached with their proofs thanks to a generic functor. "Raw" sets
- have now a proper interface and can be manipulated directly.
- Note: No Maps yet in MSets. The FSets library is still provided
- for compatibility, but will probably be considered as deprecated in the
- next release of Coq.
-- Numbers library:
- - The abstract layer (NatInt, Natural/Abstract, Integer/Abstract) has
- been simplified and enhance thanks to new features of the module
- system such as Include (see above). It has been extended to Euclidean
- division (three flavors for integers: Trunc, Floor and Math).
- - The arbitrary-large efficient numbers (BigN, BigZ, BigQ) has also
- been reworked. They benefit from the abstract layer improvements
- (especially for div and mod). Note that some specifications have
- slightly changed (compare, div, mod, shift{r,l}). Ring/Field should
- work better (true recognition of constants).
-
-Tools
-
-- Option -R now supports binding Coq root read-only.
-- New coqtop/coqc option -beautify to reformat .v files (usable
- e.g. to globally update notations).
-- New tool beautify-archive to beautify a full archive of developments.
-- New coqtop/coqc option -compat X.Y to simulate the general behavior
- of previous versions of Coq (provides e.g. support for 8.2 compatibility).
-
-Coqdoc
-
-- List have been revamped. List depth and scope is now determined by
- an "offside" whitespace rule.
-- Text may be italicized by placing it in _underscores_.
-- The "--index " flag changes the filename of the index.
-- The "--toc-depth " flag limits the depth of headers which are
- included in the table of contents.
-- The "--lib-name " flag prints " Foo" instead of
- "Library Foo" where library titles are called for. The
- "--no-lib-name" flag eliminates the extra title.
-- New option "--parse-comments" to allow parsing of regular "(* *)"
- comments.
-- New option "--plain-comments" to disable interpretation inside comments.
-- New option "--interpolate" to try and typeset identifiers in Coq escapings
- using the available globalization information.
-- New option "--external url root" to refer to external libraries.
-- Links to section variables and notations now supported.
-
-Internal infrastructure
-
-- To avoid confusion with the repository of user's contributions,
- the subdirectory "contrib" has been renamed into "plugins".
- On platforms supporting ocaml native dynlink, code located there
- is built as loadable plugins for coqtop.
-- An experimental build mechanism via ocamlbuild is provided.
- From the top of the archive, run ./configure as usual, and
- then ./build. Feedback about this build mechanism is most welcome.
- Compiling Coq on platforms such as Windows might be simpler
- this way, but this remains to be tested.
-- The Makefile system has been simplified and factorized with
- the ocamlbuild system. In particular "make" takes advantage
- of .mllib files for building .cma/.cmxa. The .vo files to
- compile are now listed in several vo.itarget files.
-
-Changes from V8.1 to V8.2
-=========================
-
-Language
-
-- If a fixpoint is not written with an explicit { struct ... }, then
- all arguments are tried successively (from left to right) until one is
- found that satisfies the structural decreasing condition.
-- New experimental typeclass system giving ad-hoc polymorphism and
- overloading based on dependent records and implicit arguments.
-- New syntax "let 'pat := b in c" for let-binding using irrefutable patterns.
-- New syntax "forall {A}, T" for specifying maximally inserted implicit
- arguments in terms.
-- Sort of Record/Structure, Inductive and CoInductive defaults to Type
- if omitted.
-- (Co)Inductive types can be defined as records
- (e.g. "CoInductive stream := { hd : nat; tl : stream }.")
-- New syntax "Theorem id1:t1 ... with idn:tn" for proving mutually dependent
- statements.
-- Support for sort-polymorphism on constants denoting inductive types.
-- Several evolutions of the module system (handling of module aliases,
- functorial module types, an Include feature, etc).
-- Prop now a subtype of Set (predicative and impredicative forms).
-- Recursive inductive types in Prop with a single constructor of which
- all arguments are in Prop is now considered to be a singleton
- type. It consequently supports all eliminations to Prop, Set and Type.
- As a consequence, Acc_rect has now a more direct proof [possible source
- of easily fixed incompatibility in case of manual definition of a recursor
- in a recursive singleton inductive type].
-
-Vernacular commands
-
-- Added option Global to "Arguments Scope" for section surviving.
-- Added option "Unset Elimination Schemes" to deactivate the automatic
- generation of elimination schemes.
-- Modification of the Scheme command so you can ask for the name to be
- automatically computed (e.g. Scheme Induction for nat Sort Set).
-- New command "Combined Scheme" to build combined mutual induction
- principles from existing mutual induction principles.
-- New command "Scheme Equality" to build a decidable (boolean) equality
- for simple inductive datatypes and a decision property over this equality
- (e.g. Scheme Equality for nat).
-- Added option "Set Equality Scheme" to make automatic the declaration
- of the boolean equality when possible.
-- Source of universe inconsistencies now printed when option
- "Set Printing Universes" is activated.
-- New option "Set Printing Existential Instances" for making the display of
- existential variable instances explicit.
-- Support for option "[id1 ... idn]", and "-[id1 ... idn]", for the
- "compute"/"cbv" reduction strategy, respectively meaning reduce only, or
- everything but, the constants id1 ... idn. "lazy" alone or followed by
- "[id1 ... idn]", and "-[id1 ... idn]" also supported, meaning apply
- all of beta-iota-zeta-delta, possibly restricting delta.
-- New command "Strategy" to control the expansion of constants during
- conversion tests. It generalizes commands Opaque and Transparent by
- introducing a range of levels. Lower levels are assigned to constants
- that should be expanded first.
-- New options Global and Local to Opaque and Transparent.
-- New command "Print Assumptions" to display all variables, parameters
- or axioms a theorem or definition relies on.
-- "Add Rec LoadPath" now provides references to libraries using partially
- qualified names (this holds also for coqtop/coqc option -R).
-- SearchAbout supports negated search criteria, reference to logical objects
- by their notation, and more generally search of subterms.
-- "Declare ML Module" now allows to import .cmxs files when Coq is
- compiled in native code with a version of OCaml that supports native
- Dynlink (>= 3.11).
-- Specific sort constraints on Record now taken into account.
-- "Print LoadPath" supports a path argument to filter the display.
-
-Libraries
-
-- Several parts of the libraries are now in Type, in particular FSets,
- SetoidList, ListSet, Sorting, Zmisc. This may induce a few
- incompatibilities. In case of trouble while fixing existing development,
- it may help to simply declare Set as an alias for Type (see file
- SetIsType).
-- New arithmetical library in theories/Numbers. It contains:
- * an abstract modular development of natural and integer arithmetics
- in Numbers/Natural/Abstract and Numbers/Integer/Abstract
- * an implementation of efficient computational bounded and unbounded
- integers that can be mapped to processor native arithmetics.
- See Numbers/Cyclic/Int31 for 31-bit integers and Numbers/Natural/BigN
- for unbounded natural numbers and Numbers/Integer/BigZ for unbounded
- integers.
- * some proofs that both older libraries Arith, ZArith and NArith and
- newer BigN and BigZ implement the abstract modular development.
- This allows in particular BigN and BigZ to already come with a
- large database of basic lemmas and some generic tactics (ring),
- This library has still an experimental status, as well as the
- processor-acceleration mechanism, but both its abstract and its
- concrete parts are already quite usable and could challenge the use
- of nat, N and Z in actual developments. Moreover, an extension of
- this framework to rational numbers is ongoing, and an efficient
- Q structure is already provided (see Numbers/Rational/BigQ), but
- this part is currently incomplete (no abstract layer and generic
- lemmas).
-- Many changes in FSets/FMaps. In practice, compatibility with earlier
- version should be fairly good, but some adaptations may be required.
- * Interfaces of unordered ("weak") and ordered sets have been factorized
- thanks to new features of Coq modules (in particular Include), see
- FSetInterface. Same for maps. Hints in these interfaces have been
- reworked (they are now placed in a "set" database).
- * To allow full subtyping between weak and ordered sets, a field
- "eq_dec" has been added to OrderedType. The old version of OrderedType
- is now called MiniOrderedType and functor MOT_to_OT allow to
- convert to the new version. The interfaces and implementations
- of sets now contain also such a "eq_dec" field.
- * FSetDecide, contributed by Aaron Bohannon, contains a decision
- procedure allowing to solve basic set-related goals (for instance,
- is a point in a particular set ?). See FSetProperties for examples.
- * Functors of properties have been improved, especially the ones about
- maps, that now propose some induction principles. Some properties
- of fold need less hypothesis.
- * More uniformity in implementations of sets and maps: they all use
- implicit arguments, and no longer export unnecessary scopes (see
- bug #1347)
- * Internal parts of the implementations based on AVL have evolved a
- lot. The main files FSetAVL and FMapAVL are now much more
- lightweight now. In particular, minor changes in some functions
- has allowed to fully separate the proofs of operational
- correctness from the proofs of well-balancing: well-balancing is
- critical for efficiency, but not anymore for proving that these
- trees implement our interfaces, hence we have moved these proofs
- into appendix files FSetFullAVL and FMapFullAVL. Moreover, a few
- functions like union and compare have been modified in order to be
- structural yet efficient. The appendix files also contains
- alternative versions of these few functions, much closer to the
- initial Ocaml code and written via the Function framework.
-- Library IntMap, subsumed by FSets/FMaps, has been removed from
- Coq Standard Library and moved into a user contribution Cachan/IntMap
-- Better computational behavior of some constants (eq_nat_dec and
- le_lt_dec more efficient, Z_lt_le_dec and Positive_as_OT.compare
- transparent, ...) (exceptional source of incompatibilities).
-- Boolean operators moved from module Bool to module Datatypes (may need
- to rename qualified references in script and force notations || and &&
- to be at levels 50 and 40 respectively).
-- The constructors xI and xO of type positive now have postfix notations
- "~1" and "~0", allowing to write numbers in binary form easily, for instance
- 6 is 1~1~0 and 4*p is p~0~0 (see BinPos.v).
-- Improvements to NArith (Nminus, Nmin, Nmax), and to QArith (in particular
- a better power function).
-- Changes in ZArith: several additional lemmas (used in theories/Numbers),
- especially in Zdiv, Znumtheory, Zpower. Moreover, many results in
- Zdiv have been generalized: the divisor may simply be non-null
- instead of strictly positive (see lemmas with name ending by
- "_full"). An alternative file ZOdiv proposes a different behavior
- (the one of Ocaml) when dividing by negative numbers.
-- Changes in Arith: EqNat and Wf_nat now exported from Arith, some
- constructions on nat that were outside Arith are now in (e.g. iter_nat).
-- In SetoidList, eqlistA now expresses that two lists have similar elements
- at the same position, while the predicate previously called eqlistA
- is now equivlistA (this one only states that the lists contain the same
- elements, nothing more).
-- Changes in Reals:
- * Most statement in "sigT" (including the
- completeness axiom) are now in "sig" (in case of incompatibility,
- use proj1_sig instead of projT1, sig instead of sigT, etc).
- * More uniform naming scheme (identifiers in French moved to English,
- consistent use of 0 -- zero -- instead of O -- letter O --, etc).
- * Lemma on prod_f_SO is now on prod_f_R0.
- * Useless hypothesis of ln_exists1 dropped.
- * New Rlogic.v states a few logical properties about R axioms.
- * RIneq.v extended and made cleaner.
-- Slight restructuration of the Logic library regarding choice and classical
- logic. Addition of files providing intuitionistic axiomatizations of
- descriptions: Epsilon.v, Description.v and IndefiniteDescription.v.
-- Definition of pred and minus made compatible with the structural
- decreasing criterion for use in fixpoints.
-- Files Relations/Rstar.v and Relations/Newman.v moved out to the user
- contribution repository (contribution CoC_History). New lemmas about
- transitive closure added and some bound variables renamed (exceptional
- risk of incompatibilities).
-- Syntax for binders in terms (e.g. for "exists") supports anonymous names.
-
-Notations, coercions, implicit arguments and type inference
-
-- More automation in the inference of the return clause of dependent
- pattern-matching problems.
-- Experimental allowance for omission of the clauses easily detectable as
- impossible in pattern-matching problems.
-- Improved inference of implicit arguments.
-- New options "Set Maximal Implicit Insertion", "Set Reversible Pattern
- Implicit", "Set Strongly Strict Implicit" and "Set Printing Implicit
- Defensive" for controlling inference and use of implicit arguments.
-- New modifier in "Implicit Arguments" to force an implicit argument to
- be maximally inserted.
-- New modifier of "Implicit Arguments" to enrich the set of implicit arguments.
-- New options Global and Local to "Implicit Arguments" for section
- surviving or non export outside module.
-- Level "constr" moved from 9 to 8.
-- Structure/Record now printed as Record (unless option Printing All is set).
-- Support for parametric notations defining constants.
-- Insertion of coercions below product types refrains to unfold
- constants (possible source of incompatibility).
-- New support for fix/cofix in notations.
-
-Tactic Language
-
-- Second-order pattern-matching now working in Ltac "match" clauses
- (syntax for second-order unification variable is "@?X").
-- Support for matching on let bindings in match context using syntax
- "H := body" or "H := body : type".
-- Ltac accepts integer arguments (syntax is "ltac:nnn" for nnn an integer).
-- The general sequence tactical "expr_0 ; [ expr_1 | ... | expr_n ]"
- is extended so that at most one expr_i may have the form "expr .."
- or just "..". Also, n can be different from the number of subgoals
- generated by expr_0. In this case, the value of expr (or idtac in
- case of just "..") is applied to the intermediate subgoals to make
- the number of tactics equal to the number of subgoals.
-- A name used as the name of the parameter of a lemma (like f in
- "apply f_equal with (f:=t)") is now interpreted as a ltac variable
- if such a variable exists (this is a possible source of
- incompatibility and it can be fixed by renaming the variables of a
- ltac function into names that do not clash with the lemmas
- parameter names used in the tactic).
-- New syntax "Ltac tac ::= ..." to rebind a tactic to a new expression.
-- "let rec ... in ... " now supported for expressions without explicit
- parameters; interpretation is lazy to the contrary of "let ... in ...";
- hence, the "rec" keyword can be used to turn the argument of a
- "let ... in ..." into a lazy one.
-- Patterns for hypotheses types in "match goal" are now interpreted in
- type_scope.
-- A bound variable whose name is not used elsewhere now serves as
- metavariable in "match" and it gets instantiated by an identifier
- (allow e.g. to extract the name of a statement like "exists x, P x").
-- New printing of Ltac call trace for better debugging.
-
-Tactics
-
-- New tactics "apply -> term", "apply <- term", "apply -> term in
- ident", "apply <- term in ident" for applying equivalences (iff).
-- Slight improvement of the hnf and simpl tactics when applied on
- expressions with explicit occurrences of match or fix.
-- New tactics "eapply in", "erewrite", "erewrite in".
-- New tactics "ediscriminate", "einjection", "esimplify_eq".
-- Tactics "discriminate", "injection", "simplify_eq" now support any
- term as argument. Clause "with" is also supported.
-- Unfoldable references can be given by notation's string rather than by name
- in unfold.
-- The "with" arguments are now typed using informations from the current goal:
- allows support for coercions and more inference of implicit arguments.
-- Application of "f_equal"-style lemmas works better.
-- Tactics elim, case, destruct and induction now support variants eelim,
- ecase, edestruct and einduction.
-- Tactics destruct and induction now support the "with" option and the
- "in" clause option. If the option "in" is used, an equality is added
- to remember the term to which the induction or case analysis applied
- (possible source of parsing incompatibilities when destruct or induction is
- part of a let-in expression in Ltac; extra parentheses are then required).
-- New support for "as" clause in tactics "apply in" and "eapply in".
-- Some new intro patterns:
- * intro pattern "?A" genererates a fresh name based on A.
- Caveat about a slight loss of compatibility:
- Some intro patterns don't need space between them. In particular
- intros ?a?b used to be legal and equivalent to intros ? a ? b. Now it
- is still legal but equivalent to intros ?a ?b.
- * intro pattern "(A & ... & Y & Z)" synonym to "(A,....,(Y,Z)))))"
- for right-associative constructs like /\ or exists.
-- Several syntax extensions concerning "rewrite":
- * "rewrite A,B,C" can be used to rewrite A, then B, then C. These rewrites
- occur only on the first subgoal: in particular, side-conditions of the
- "rewrite A" are not concerned by the "rewrite B,C".
- * "rewrite A by tac" allows to apply tac on all side-conditions generated by
- the "rewrite A".
- * "rewrite A at n" allows to select occurrences to rewrite: rewrite only
- happen at the n-th exact occurrence of the first successful matching of
- A in the goal.
- * "rewrite 3 A" or "rewrite 3!A" is equivalent to "rewrite A,A,A".
- * "rewrite !A" means rewriting A as long as possible (and at least once).
- * "rewrite 3?A" means rewriting A at most three times.
- * "rewrite ?A" means rewriting A as long as possible (possibly never).
- * many of the above extensions can be combined with each other.
-- Introduction patterns better respect the structure of context in presence of
- missing or extra names in nested disjunction-conjunction patterns [possible
- source of rare incompatibilities].
-- New syntax "rename a into b, c into d" for "rename a into b; rename c into d"
-- New tactics "dependent induction/destruction H [ generalizing id_1 .. id_n ]"
- to do induction-inversion on instantiated inductive families à la BasicElim.
-- Tactics "apply" and "apply in" now able to reason modulo unfolding of
- constants (possible source of incompatibility in situations where apply
- may fail, e.g. as argument of a try or a repeat and in a ltac function);
- versions that do not unfold are renamed into "simple apply" and
- "simple apply in" (usable for compatibility or for automation).
-- Tactics "apply" and "apply in" now able to traverse conjunctions and to
- select the first matching lemma among the components of the conjunction;
- tactic "apply" also able to apply lemmas of conclusion an empty type.
-- Tactic "apply" now supports application of several lemmas in a row.
-- Tactics "set" and "pose" can set functions using notation "(f x1..xn := c)".
-- New tactic "instantiate" (without argument).
-- Tactic firstorder "with" and "using" options have their meaning swapped for
- consistency with auto/eauto (source of incompatibility).
-- Tactic "generalize" now supports "at" options to specify occurrences
- and "as" options to name the quantified hypotheses.
-- New tactic "specialize H with a" or "specialize (H a)" allows to transform
- in-place a universally-quantified hypothesis (H : forall x, T x) into its
- instantiated form (H : T a). Nota: "specialize" was in fact there in earlier
- versions of Coq, but was undocumented, and had a slightly different behavior.
-- New tactic "contradict H" can be used to solve any kind of goal as long as
- the user can provide afterwards a proof of the negation of the hypothesis H.
- If H is already a negation, say ~T, then a proof of T is asked.
- If the current goal is a negation, say ~U, then U is saved in H afterwards,
- hence this new tactic "contradict" extends earlier tactic "swap", which is
- now obsolete.
-- Tactics f_equal is now done in ML instead of Ltac: it now works on any
- equality of functions, regardless of the arity of the function.
-- New options "before id", "at top", "at bottom" for tactics "move"/"intro".
-- Some more debug of reflexive omega (romega), and internal clarifications.
- Moreover, romega now has a variant "romega with *" that can be also used
- on non-Z goals (nat, N, positive) via a call to a translation tactic named
- zify (its purpose is to Z-ify your goal...). This zify may also be used
- independently of romega.
-- Tactic "remember" now supports an "in" clause to remember only selected
- occurrences of a term.
-- Tactic "pose proof" supports name overwriting in case of specialization of an
- hypothesis.
-- Semi-decision tactic "jp" for first-order intuitionistic logic moved to user
- contributions (subsumed by "firstorder").
-
-Program
-
-- Moved useful tactics in theories/Program and documented them.
-- Add Program.Basics which contains standard definitions for functional
- programming (id, apply, flip...)
-- More robust obligation handling, dependent pattern-matching and
- well-founded definitions.
-- New syntax " dest term as pat in term " for destructing objects using
- an irrefutable pattern while keeping equalities (use this instead of
- "let" in Programs).
-- Program CoFixpoint is accepted, Program Fixpoint uses the new way to infer
- which argument decreases structurally.
-- Program Lemma, Axiom etc... now permit to have obligations in the statement
- iff they can be automatically solved by the default tactic.
-- Renamed "Obligations Tactic" command to "Obligation Tactic".
-- New command "Preterm [ of id ]" to see the actual term fed to Coq for
- debugging purposes.
-- New option "Transparent Obligations" to control the declaration of
- obligations as transparent or opaque. All obligations are now transparent
- by default, otherwise the system declares them opaque if possible.
-- Changed the notations "left" and "right" to "in_left" and "in_right" to hide
- the proofs in standard disjunctions, to avoid breaking existing scripts when
- importing Program. Also, put them in program_scope.
-
-Type Classes
-
-- New "Class", "Instance" and "Program Instance" commands to define
- classes and instances documented in the reference manual.
-- New binding construct " [ Class_1 param_1 .. param_n, Class_2 ... ] "
- for binding type classes, usable everywhere.
-- New command " Print Classes " and " Print Instances some_class " to
- print tables for typeclasses.
-- New default eauto hint database "typeclass_instances" used by the default
- typeclass instance search tactic.
-- New theories directory "theories/Classes" for standard typeclasses
- declarations. Module Classes.RelationClasses is a typeclass port of
- Relation_Definitions plus a generic development of algebra on
- n-ary heterogeneous predicates.
-
-Setoid rewriting
-
-- Complete (and still experimental) rewrite of the tactic
- based on typeclasses. The old interface and semantics are
- almost entirely respected, except:
-
- - Import Setoid is now mandatory to be able to call setoid_replace
- and declare morphisms.
-
- - "-->", "++>" and "==>" are now right associative notations
- declared at level 55 in scope signature_scope.
- Their introduction may break existing scripts that defined
- them as notations with different levels.
-
- - One needs to use [Typeclasses unfold [cst]] if [cst] is used
- as an abbreviation hiding products in types of morphisms,
- e.g. if ones redefines [relation] and declares morphisms
- whose type mentions [relation].
-
- - The [setoid_rewrite]'s semantics change when rewriting with
- a lemma: it can rewrite two different instantiations of the lemma
- at once. Use [setoid_rewrite H at 1] for (almost) the usual semantics.
- [setoid_rewrite] will also try to rewrite under binders now, and can
- succeed on different terms than before. In particular, it will unify under
- let-bound variables. When called through [rewrite], the semantics are
- unchanged though.
-
- - [Add Morphism term : id] has different semantics when used with
- parametric morphism: it will try to find a relation on the parameters
- too. The behavior has also changed with respect to default relations:
- the most recently declared Setoid/Relation will be used, the documentation
- explains how to customize this behavior.
-
- - Parametric Relation and Morphism are declared differently, using the
- new [Add Parametric] commands, documented in the manual.
-
- - Setoid_Theory is now an alias to Equivalence, scripts building objects
- of type Setoid_Theory need to unfold (or "red") the definitions
- of Reflexive, Symmetric and Transitive in order to get the same goals
- as before. Scripts which introduced variables explicitely will not break.
-
- - The order of subgoals when doing [setoid_rewrite] with side-conditions
- is always the same: first the new goal, then the conditions.
-
-- New standard library modules Classes.Morphisms declares
- standard morphisms on refl/sym/trans relations.
- Classes.Morphisms_Prop declares morphisms on propositional
- connectives and Classes.Morphisms_Relations on generalized predicate
- connectives. Classes.Equivalence declares notations and tactics
- related to equivalences and Classes.SetoidTactics defines the
- setoid_replace tactics and some support for the "Add *" interface,
- notably the tactic applied automatically before each "Add Morphism"
- proof.
-
-- User-defined subrelations are supported, as well as higher-order morphisms
- and rewriting under binders. The tactic is also extensible entirely in Ltac.
- The documentation has been updated to cover these features.
-
-- [setoid_rewrite] and [rewrite] now support the [at] modifier to select
- occurrences to rewrite, and both use the [setoid_rewrite] code, even when
- rewriting with leibniz equality if occurrences are specified.
-
-Extraction
-
-- Improved behavior of the Caml extraction of modules: name clashes should
- not happen anymore.
-- The command Extract Inductive has now a syntax for infix notations. This
- allows in particular to map Coq lists and pairs onto Caml ones:
- Extract Inductive list => list [ "[]" "(::)" ].
- Extract Inductive prod => "(*)" [ "(,)" ].
-- In pattern matchings, a default pattern "| _ -> ..." is now used whenever
- possible if several branches are identical. For instance, functions
- corresponding to decidability of equalities are now linear instead of
- quadratic.
-- A new instruction Extraction Blacklist id1 .. idn allows to prevent filename
- conflits with existing code, for instance when extracting module List
- to Ocaml.
-
-CoqIDE
-
-- CoqIDE font defaults to monospace so as indentation to be meaningful.
-- CoqIDE supports nested goals and any other kind of declaration in the middle
- of a proof.
-- Undoing non-tactic commands in CoqIDE works faster.
-- New CoqIDE menu for activating display of various implicit informations.
-- Added the possibility to choose the location of tabs in coqide:
- (in Edit->Preferences->Misc)
-- New Open and Save As dialogs in CoqIDE which filter *.v files.
-
-Tools
-
-- New stand-alone .vo files verifier "coqchk".
-- Extended -I coqtop/coqc option to specify a logical dir: "-I dir -as coqdir".
-- New coqtop/coqc option -exclude-dir to exclude subdirs for option -R.
-- The binary "parser" has been renamed to "coq-parser".
-- Improved coqdoc and dump of globalization information to give more
- meta-information on identifiers. All categories of Coq definitions are
- supported, which makes typesetting trivial in the generated documentation.
- Support for hyperlinking and indexing developments in the tex output
- has been implemented as well.
-
-Miscellaneous
-
-- Coq installation provides enough files so that Ocaml's extensions need not
- the Coq sources to be compiled (this assumes O'Caml 3.10 and Camlp5).
-- New commands "Set Whelp Server" and "Set Whelp Getter" to customize the
- Whelp search tool.
-- Syntax of "Test Printing Let ref" and "Test Printing If ref" changed into
- "Test Printing Let for ref" and "Test Printing If for ref".
-- An overhauled build system (new Makefiles); see dev/doc/build-system.txt.
-- Add -browser option to configure script.
-- Build a shared library for the C part of Coq, and use it by default on
- non-(Windows or MacOS) systems. Bytecode executables are now pure. The
- behaviour is configurable with -coqrunbyteflags, -coqtoolsbyteflags and
- -custom configure options.
-- Complexity tests can be skipped by setting the environment variable
- COQTEST_SKIPCOMPLEXITY.
-
-Changes from V8.1gamma to V8.1
-==============================
-
-Bug fixes
-
-- Many bugs have been fixed (cf coq-bugs web page)
-
-Tactics
-
-- New tactics ring, ring_simplify and new tactic field now able to manage
- power to a positive integer constant. Tactic ring on Z and R, and
- field on R manage power (may lead to incompatibilities with V8.1gamma).
-- Tactic field_simplify now applicable in hypotheses.
-- New field_simplify_eq for simplifying field equations into ring equations.
-- Tactics ring, ring_simplify, field, field_simplify and field_simplify_eq
- all able to apply user-given equations to rewrite monoms on the fly
- (see documentation).
-
-Libraries
-
-- New file ConstructiveEpsilon.v defining an epsilon operator and
- proving the axiom of choice constructively for a countable domain
- and a decidable predicate.
-
-Changes from V8.1beta to V8.1gamma
-==================================
-
-Syntax
-
-- changed parsing precedence of let/in and fun constructions of Ltac:
- let x := t in e1; e2 is now parsed as let x := t in (e1;e2).
-
-Language and commands
-
-- Added sort-polymorphism for definitions in Type (but finally abandonned).
-- Support for implicit arguments in the types of parameters in
- (co-)fixpoints and (co-)inductive declarations.
-- Improved type inference: use as much of possible general information.
- before applying irreversible unification heuristics (allow e.g. to
- infer the predicate in "(exist _ 0 (refl_equal 0) : {n:nat | n=0 })").
-- Support for Miller-Pfenning's patterns unification in type synthesis
- (e.g. can infer P such that P x y = phi(x,y)).
-- Support for "where" clause in cofixpoint definitions.
-- New option "Set Printing Universes" for making Type levels explicit.
-
-Tactics
-
-- Improved implementation of the ring and field tactics. For compatibility
- reasons, the previous tactics are renamed as legacy ring and legacy field,
- but should be considered as deprecated.
-- New declarative mathematical proof language.
-- Support for argument lists of arbitrary length in Tactic Notation.
-- [rewrite ... in H] now fails if [H] is used either in an hypothesis
- or in the goal.
-- The semantics of [rewrite ... in *] has been slightly modified (see doc).
-- Support for "as" clause in tactic injection.
-- New forward-reasoning tactic "apply in".
-- Ltac fresh operator now builds names from a concatenation of its arguments.
-- New ltac tactic "remember" to abstract over a subterm and keep an equality
-- Support for Miller-Pfenning's patterns unification in apply/rewrite/...
- (may lead to few incompatibilities - generally now useless tactic calls).
-
-Bug fixes
-
-- Fix for notations involving basic "match" expressions.
-- Numerous other bugs solved (a few fixes may lead to incompatibilities).
-
-
-Changes from V8.0 to V8.1beta
-=============================
-
-Logic
-
-- Added sort-polymorphism on inductive families
-- Allowance for recursively non uniform parameters in inductive types
-
-Syntax
-
-- No more support for version 7 syntax and for translation to version 8 syntax.
-- In fixpoints, the { struct ... } annotation is not mandatory any more when
- only one of the arguments has an inductive type
-- Added disjunctive patterns in match-with patterns
-- Support for primitive interpretation of string literals
-- Extended support for Unicode ranges
-
-Vernacular commands
-
-- Added "Print Ltac qualid" to print a user defined tactic.
-- Added "Print Rewrite HintDb" to print the content of a DB used by
- autorewrite.
-- Added "Print Canonical Projections".
-- Added "Example" as synonym of "Definition".
-- Added "Proposition" and "Corollary" as extra synonyms of "Lemma".
-- New command "Whelp" to send requests to the Helm database of proofs
- formalized in the Calculus of Inductive Constructions.
-- Command "functional induction" has been re-implemented from the new
- "Function" command.
-
-Ltac and tactic syntactic extensions
-
-- New primitive "external" for communication with tool external to Coq
-- New semantics for "match t with": if a clause returns a
- tactic, it is now applied to the current goal. If it fails, the next
- clause or next matching subterm is tried (i.e. it behaves as "match
- goal with" does). The keyword "lazymatch" can be used to delay the
- evaluation of tactics occurring in matching clauses.
-- Hint base names can be parametric in auto and trivial.
-- Occurrence values can be parametric in unfold, pattern, etc.
-- Added entry constr_may_eval for tactic extensions.
-- Low-priority term printer made available in ML-written tactic extensions.
-- "Tactic Notation" extended to allow notations of tacticals.
-
-Tactics
-
-- New implementation and generalization of [setoid_]* (setoid_rewrite,
- setoid_symmetry, setoid_transitivity, setoid_reflexivity and autorewite).
- New syntax for declaring relations and morphisms (old syntax still working
- with minor modifications, but deprecated).
-- New implementation (still experimental) of the ring tactic with a built-in
- notion of coefficients and a better usage of setoids.
-- New conversion tactic "vm_compute": evaluates the goal (or an hypothesis)
- with a call-by-value strategy, using the compiled version of terms.
-- When rewriting H where H is not directly a Coq equality, search first H for
- a registered setoid equality before starting to reduce in H. This is unlikely
- to break any script. Should this happen nonetheless, one can insert manually
- some "unfold ... in H" before rewriting.
-- Fixed various bugs about (setoid) rewrite ... in ... (in particular BZ#1101)
-- "rewrite ... in" now accepts a clause as place where to rewrite instead of
- juste a simple hypothesis name. For instance:
- rewrite H in H1,H2 |- * means rewrite H in H1; rewrite H in H2; rewrite H
- rewrite H in * |- will do try rewrite H in Hi for all hypothesis Hi <> H.
-- Added "dependent rewrite term" and "dependent rewrite term in hyp".
-- Added "autorewrite with ... in hyp [using ...]".
-- Tactic "replace" now accepts a "by" tactic clause.
-- Added "clear - id" to clear all hypotheses except the ones depending in id.
-- The argument of Declare Left Step and Declare Right Step is now a term
- (it used to be a reference).
-- Omega now handles arbitrary precision integers.
-- Several bug fixes in Reflexive Omega (romega).
-- Idtac can now be left implicit in a [...|...] construct: for instance,
- [ foo | | bar ] stands for [ foo | idtac | bar ].
-- Fixed a "fold" bug (non critical but possible source of incompatibilities).
-- Added classical_left and classical_right which transforms |- A \/ B into
- ~B |- A and ~A |- B respectively.
-- Added command "Declare Implicit Tactic" to set up a default tactic to be
- used to solve unresolved subterms of term arguments of tactics.
-- Better support for coercions to Sortclass in tactics expecting type
- arguments.
-- Tactic "assert" now accepts "as" intro patterns and "by" tactic clauses.
-- New tactic "pose proof" that generalizes "assert (id:=p)" with intro patterns.
-- New introduction pattern "?" for letting Coq choose a name.
-- Introduction patterns now support side hypotheses (e.g. intros [|] on
- "(nat -> nat) -> nat" works).
-- New introduction patterns "->" and "<-" for immediate rewriting of
- introduced hypotheses.
-- Introduction patterns coming after non trivial introduction patterns now
- force full introduction of the first pattern (e.g. "intros [[|] p]" on
- "nat->nat->nat" now behaves like "intros [[|?] p]")
-- Added "eassumption".
-- Added option 'using lemmas' to auto, trivial and eauto.
-- Tactic "congruence" is now complete for its intended scope (ground
- equalities and inequalities with constructors). Furthermore, it
- tries to equates goal and hypotheses.
-- New tactic "rtauto" solves pure propositional logic and gives a
- reflective version of the available proof.
-- Numbering of "pattern", "unfold", "simpl", ... occurrences in "match
- with" made consistent with the printing of the return clause after
- the term to match in the "match-with" construct (use "Set Printing All"
- to see hidden occurrences).
-- Generalization of induction "induction x1...xn using scheme" where
- scheme is an induction principle with complex predicates (like the
- ones generated by function induction).
-- Some small Ltac tactics has been added to the standard library
- (file Tactics.v):
- * f_equal : instead of using the different f_equalX lemmas
- * case_eq : a "case" without loss of information. An equality
- stating the current situation is generated in every sub-cases.
- * swap : for a negated goal ~B and a negated hypothesis H:~A,
- swap H asks you to prove A from hypothesis B
- * revert : revert H is generalize H; clear H.
-
-Extraction
-
-- All type parts should now disappear instead of sometimes producing _
- (for instance in Map.empty).
-- Haskell extraction: types of functions are now printed, better
- unsafeCoerce mechanism, both for hugs and ghc.
-- Scheme extraction improved, see http://www.pps.jussieu.fr/~letouzey/scheme.
-- Many bug fixes.
-
-Modules
-
-- Added "Locate Module qualid" to get the full path of a module.
-- Module/Declare Module syntax made more uniform.
-- Added syntactic sugar "Declare Module Export/Import" and
- "Module Export/Import".
-- Added syntactic sugar "Module M(Export/Import X Y: T)" and
- "Module Type M(Export/Import X Y: T)"
- (only for interactive definitions)
-- Construct "with" generalized to module paths:
- T with (Definition|Module) M1.M2....Mn.l := l'.
-
-Notations
-
-- Option "format" aware of recursive notations.
-- Added insertion of spaces by default in recursive notations w/o separators.
-- No more automatic printing box in case of user-provided printing "format".
-- New notation "exists! x:A, P" for unique existence.
-- Notations for specific numerals now compatible with generic notations of
- numerals (e.g. "1" can be used to denote the unit of a group without
- hiding 1%nat)
-
-Libraries
-
-- New library on String and Ascii characters (contributed by L. Thery).
-- New library FSets+FMaps of finite sets and maps.
-- New library QArith on rational numbers.
-- Small extension of Zmin.V, new Zmax.v, new Zminmax.v.
-- Reworking and extension of the files on classical logic and
- description principles (possible incompatibilities)
-- Few other improvements in ZArith potentially exceptionally breaking the
- compatibility (useless hypothesys of Zgt_square_simpl and
- Zlt_square_simpl removed; fixed names mentioning letter O instead of
- digit 0; weaken premises in Z_lt_induction).
-- Restructuration of Eqdep_dec.v and Eqdep.v: more lemmas in Type.
-- Znumtheory now contains a gcd function that can compute within Coq.
-- More lemmas stated on Type in Wf.v, removal of redundant Acc_iter and
- Acc_iter2.
-- Change of the internal names of lemmas in OmegaLemmas.
-- Acc in Wf.v and clos_refl_trans in Relation_Operators.v now rely on
- the allowance for recursively non uniform parameters (possible
- source of incompatibilities: explicit pattern-matching on these
- types may require to remove the occurrence associated to their
- recursively non uniform parameter).
-- Coq.List.In_dec has been set transparent (this may exceptionally break
- proof scripts, set it locally opaque for compatibility).
-- More on permutations of lists in List.v and Permutation.v.
-- List.v has been much expanded.
-- New file SetoidList.v now contains results about lists seen with
- respect to a setoid equality.
-- Library NArith has been expanded, mostly with results coming from
- Intmap (for instance a bitwise xor), plus also a bridge between N and
- Bitvector.
-- Intmap has been reorganized. In particular its address type "addr" is
- now N. User contributions known to use Intmap have been adapted
- accordingly. If you're using this library please contact us.
- A wrapper FMapIntMap now presents Intmap as a particular implementation
- of FMaps. New developments are strongly encouraged to use either this
- wrapper or any other implementations of FMap instead of using directly
- this obsolete Intmap.
-
-Tools
-
-- New semantics for coqtop options ("-batch" expects option "-top dir"
- for loading vernac file that contains definitions).
-- Tool coq_makefile now removes custom targets that are file names in
- "make clean"
-- New environment variable COQREMOTEBROWSER to set the command invoked
- to start the remote browser both in Coq and coqide. Standard syntax:
- "%s" is the placeholder for the URL.
-
-
-Changes from V8.0beta to V8.0
-=============================
-
-Vernacular commands
-
-- New option "Set Printing All" to deactivate all high-level forms of
- printing (implicit arguments, coercions, destructing let,
- if-then-else, notations, projections)
-- "Functional Scheme" and "Functional Induction" extended to polymorphic
- types and dependent types
-- Notation now allows recursive patterns, hence recovering parts of the
- fonctionalities of pre-V8 Grammar/Syntax commands
-- Command "Print." discontinued.
-- Redundant syntax "Implicit Arguments On/Off" discontinued
-
-New syntax
-
-- Semantics change of the if-then-else construction in new syntax:
- "if c then t1 else t2" now stands for
- "match c with c1 _ ... _ => t1 | c2 _ ... _ => t2 end"
- with no dependency of t1 and t2 in the arguments of the constructors;
- this may cause incompatibilities for files translated using coq 8.0beta
-
-Interpretation scopes
-
-- Delimiting key %bool for bool_scope added
-- Import no more needed to activate argument scopes from a module
-
-Tactics and the tactic Language
-
-- Semantics of "assert" is now consistent with the reference manual
-- New tactics stepl and stepr for chaining transitivity steps
-- Tactic "replace ... with ... in" added
-- Intro patterns now supported in Ltac (parsed with prefix "ipattern:")
-
-Executables and tools
-
-- Added option -top to change the name of the toplevel module "Top"
-- Coqdoc updated to new syntax and now part of Coq sources
-- XML exportation tool now exports the structure of vernacular files
- (cf chapter 13 in the reference manual)
-
-User contributions
-
-- User contributions have been updated to the new syntax
-
-Bug fixes
-
-- Many bugs have been fixed (cf coq-bugs web page)
-
-Changes from V8.0beta old syntax to V8.0beta
-============================================
-
-New concrete syntax
-
-- A completely new syntax for terms
-- A more uniform syntax for tactics and the tactic language
-- A few syntactic changes for vernacular commands
-- A smart automatic translator translating V8.0 files in old syntax to
- files valid for V8.0
-
-Syntax extensions
-
-- "Grammar" for terms disappears
-- "Grammar" for tactics becomes "Tactic Notation"
-- "Syntax" disappears
-- Introduction of a notion of interpretation scope allowing to use the
- same notations in various contexts without using specific delimiters
- (e.g the same expression "4<=3+x" is interpreted either in "nat",
- "positive", "N" (previously "entier"), "Z", "R", depending on which
- interpretation scope is currently open) [see documentation for details]
-- Notation now mandatorily requires a precedence and associativity
- (default was to set precedence to 1 and associativity to none)
-
-Revision of the standard library
-
-- Many lemmas and definitions names have been made more uniform mostly
- in Arith, NArith, ZArith and Reals (e.g : "times" -> "Pmult",
- "times_sym" -> "Pmult_comm", "Zle_Zmult_pos_right" ->
- "Zmult_le_compat_r", "SUPERIEUR" -> "Gt", "ZERO" -> "Z0")
-- Order and names of arguments of basic lemmas on nat, Z, positive and R
- have been made uniform.
-- Notions of Coq initial state are declared with (strict) implicit arguments
-- eq merged with eqT: old eq disappear, new eq (written =) is old eqT
- and new eqT is syntactic sugar for new eq (notation == is an alias
- for = and is written as it, exceptional source of incompatibilities)
-- Similarly, ex, ex2, all, identity are merged with exT, exT2, allT, identityT
-- Arithmetical notations for nat, positive, N, Z, R, without needing
- any backquote or double-backquotes delimiters.
-- In Lists: new concrete notations; argument of nil is now implicit
-- All changes in the library are taken in charge by the translator
-
-Semantical changes during translation
-
-- Recursive keyword set by default (and no longer needed) in Tactic Definition
-- Set Implicit Arguments is strict by default in new syntax
-- reductions in hypotheses of the form "... in H" now apply to the type
- also if H is a local definition
-- etc
-
-Gallina
-
-- New syntax of the form "Inductive bool : Set := true, false : bool." for
- enumerated types
-- Experimental syntax of the form p.(fst) for record projections
- (activable with option "Set Printing Projections" which is
- recognized by the translator)
-
-Known problems of the automatic translation
-
-- iso-latin-1 characters are no longer supported: move your files to
- 7-bits ASCII or unicode before translation (swith to unicode is
- automatically done if a file is loaded and saved again by coqide)
-- Renaming in ZArith: incompatibilities in Coq user contribs due to
- merging names INZ, from Reals, and inject_nat.
-- Renaming and new lemmas in ZArith: may clash with names used by users
-- Restructuration of ZArith: replace requirement of specific modules
- in ZArith by "Require Import ZArith_base" or "Require Import ZArith"
-- Some implicit arguments must be made explicit before translation: typically
- for "length nil", the implicit argument of length must be made explicit
-- Grammar rules, Infix notations and V7.4 Notations must be updated wrt the
- new scheme for syntactic extensions (see translator documentation)
-- Unsafe for annotation Cases when constructors coercions are used or when
- annotations are eta-reduced predicates
-
-
-Changes from V7.4 to V8.0beta old syntax
-========================================
-
-Logic
-
-- Set now predicative by default
-- New option -impredicative-set to set Set impredicative
-- The standard library doesn't need impredicativity of Set and is
- compatible with the classical axioms which contradict Set impredicativity
-
-Syntax for arithmetic
-
-- Notation "=" and "<>" in Z and R are no longer implicitly in Z or R
- (with possible introduction of a coercion), use ...=... or
- ...<>... instead
-- Locate applied to a simple string (e.g. "+") searches for all
- notations containing this string
-
-Vernacular commands
-
-- "Declare ML Module" now allows to import .cma files. This avoids to use a
- bunch of "Declare ML Module" statements when using several ML files.
-- "Set Printing Width n" added, allows to change the size of width printing.
-- "Implicit Variables Type x,y:t" (new syntax: "Implicit Types x y:t")
- assigns default types for binding variables.
-- Declarations of Hints and Notation now accept a "Local" flag not to
- be exported outside the current file even if not in section
-- "Print Scopes" prints all notations
-- New command "About name" for light printing of type, implicit arguments, etc.
-- New command "Admitted" to declare incompletely proven statement as axioms
-- New keyword "Conjecture" to declare an axiom intended to be provable
-- SearchAbout can now search for lemmas referring to more than one constant
- and on substrings of the name of the lemma
-- "Print Implicit" displays the implicit arguments of a constant
-- Locate now searches for all names having a given suffix
-- New command "Functional Scheme" for building an induction principle
- from a function defined by case analysis and fix.
-
-Commands
-
-- new coqtop/coqc option -dont-load-proofs not to load opaque proofs in memory
-
-Implicit arguments
-
-- Inductive in sections declared with implicits now "discharged" with
- implicits (like constants and variables)
-- Implicit Arguments flags are now synchronous with reset
-- New switch "Unset/Set Printing Implicits" (new syntax: "Unset/Set Printing
- Implicit") to globally control printing of implicits
-
-Grammar extensions
-
-- Many newly supported UTF-8 encoded unicode blocks
- - Greek letters (0380-03FF), Hebrew letters (U05D0-05EF), letter-like
- symbols (2100-214F, that includes double N,Z,Q,R), prime
- signs (from 2080-2089) and characters from many written languages
- are valid in identifiers
- - mathematical operators (2200-22FF), supplemental mathematical
- operators (2A00-2AFF), miscellaneous technical (2300-23FF that
- includes sqrt symbol), miscellaneous symbols (2600-26FF), arrows
- (2190-21FF and 2900-297F), invisible mathematical operators (from
- 2080-2089), ... are valid symbols
-
-Library
-
-- New file about the factorial function in Arith
-- An additional elimination Acc_iter for Acc, simplier than Acc_rect.
- This new elimination principle is used for definition well_founded_induction.
-- New library NArith on binary natural numbers
-- R is now of type Set
-- Restructuration in ZArith library
- - "true_sub" used in Zplus now a definition, not a local one (source
- of incompatibilities in proof referring to true_sub, may need extra Unfold)
- - Some lemmas about minus moved from fast_integer to Arith/Minus.v
- (le_minus, lt_mult_left) (theoretical source of incompatibilities)
- - Several lemmas moved from auxiliary.v and zarith_aux.v to
- fast_integer.v (theoretical source of incompatibilities)
- - Variables names of iff_trans changed (source of incompatibilities)
- - ZArith lemmas named OMEGA something or fast_ something, and lemma new_var
- are now out of ZArith (except OMEGA2)
- - Redundant ZArith lemmas have been renamed: for the following pairs,
- use the second name (Zle_Zmult_right2, Zle_mult_simpl), (OMEGA2,
- Zle_0_plus), (Zplus_assoc_l, Zplus_assoc), (Zmult_one, Zmult_1_n),
- (Zmult_assoc_l, Zmult_assoc), (Zmult_minus_distr, Zmult_Zminus_distr_l)
- (add_un_double_moins_un_xO, is_double_moins_un),
- (Rlt_monotony_rev,Rlt_monotony_contra) (source of incompatibilities)
-- Few minor changes (no more implicit arguments in
- Zmult_Zminus_distr_l and Zmult_Zminus_distr_r, lemmas moved from
- Zcomplements to other files) (rare source of incompatibilities)
-- New lemmas provided by users added
-
-Tactic language
-
-- Fail tactic now accepts a failure message
-- Idtac tactic now accepts a message
-- New primitive tactic "FreshId" (new syntax: "fresh") to generate new names
-- Debugger prints levels of calls
-
-Tactics
-
-- Replace can now replace proofs also
-- Fail levels are now decremented at "Match Context" blocks only and
- if the right-hand-side of "Match term With" are tactics, these
- tactics are never evaluated immediately and do not induce
- backtracking (in contrast with "Match Context")
-- Quantified names now avoid global names of the current module (like
- Intro names did) [source of rare incompatibilities: 2 changes in the set of
- user contribs]
-- NewDestruct/NewInduction accepts intro patterns as introduction names
-- NewDestruct/NewInduction now work for non-inductive type using option "using"
-- A NewInduction naming bug for inductive types with functional
- arguments (e.g. the accessibility predicate) has been fixed (source
- of incompatibilities)
-- Symmetry now applies to hypotheses too
-- Inversion now accept option "as [ ... ]" to name the hypotheses
-- Contradiction now looks also for contradictory hypotheses stating ~A and A
- (source of incompatibility)
-- "Contradiction c" try to find an hypothesis in context which
- contradicts the type of c
-- Ring applies to new library NArith (require file NArithRing)
-- Field now works on types in Set
-- Auto with reals now try to replace le by ge (Rge_le is no longer an
- immediate hint), resulting in shorter proofs
-- Instantiate now works in hyps (syntax : Instantiate in ...)
-- Some new tactics : EConstructor, ELeft, Eright, ESplit, EExists
-- New tactic "functional induction" to perform case analysis and
- induction following the definition of a function.
-- Clear now fails when trying to remove a local definition used by
- a constant appearing in the current goal
-
-Extraction (See details in plugins/extraction/CHANGES)
-
-- The old commands: (Recursive) Extraction Module M.
- are now: (Recursive) Extraction Library M.
- To use these commands, M should come from a library M.v
-- The other syntax Extraction & Recursive Extraction now accept
- module names as arguments.
-
-Bugs
-
-- see coq-bugs server for the complete list of fixed bugs
-
-Miscellaneous
-
-- Implicit parameters of inductive types definition now taken into
- account for infering other implicit arguments
-
-Incompatibilities
-
-- Persistence of true_sub (4 incompatibilities in Coq user contributions)
-- Variable names of some constants changed for a better uniformity (2 changes
- in Coq user contributions)
-- Naming of quantified names in goal now avoid global names (2 occurrences)
-- NewInduction naming for inductive types with functional arguments
- (no incompatibility in Coq user contributions)
-- Contradiction now solve more goals (source of 2 incompatibilities)
-- Merge of eq and eqT may exceptionally result in subgoals now
- solved automatically
-- Redundant pairs of ZArith lemmas may have different names: it may
- cause "Apply/Rewrite with" to fail if using the first name of a pair
- of redundant lemmas (this is solved by renaming the variables bound by
- "with"; 3 incompatibilities in Coq user contribs)
-- ML programs referring to constants from fast_integer.v must use
- "Coqlib.gen_constant_modules Coqlib.zarith_base_modules" instead
-
-Changes from V7.3.1 to V7.4
-===========================
-
-Symbolic notations
-
-- Introduction of a notion of scope gathering notations in a consistent set;
- a notation sets has been developed for nat, Z and R (undocumented)
-- New command "Notation" for declaring notations simultaneously for
- parsing and printing (see chap 10 of the reference manual)
-- Declarations with only implicit arguments now handled (e.g. the
- argument of nil can be set implicit; use !nil to refer to nil
- without arguments)
-- "Print Scope sc" and "Locate ntn" allows to know to what expression a
- notation is bound
-- New defensive strategy for printing or not implicit arguments to ensure
- re-type-checkability of the printed term
-- In Grammar command, the only predefined non-terminal entries are ident,
- global, constr and pattern (e.g. nvar, numarg disappears); the only
- allowed grammar types are constr and pattern; ast and ast list are no
- longer supported; some incompatibilities in Grammar: when a syntax is a
- initial segment of an other one, Grammar does not work, use Notation
-
-Library
-
-- Lemmas in Set from Compare_dec.v (le_lt_dec, ...) and Wf_nat.v
- (lt_wf_rec, ...) are now transparent. This may be source of
- incompatibilities.
-- Syntactic Definitions Fst, Snd, Ex, All, Ex2, AllT, ExT, ExT2,
- ProjS1, ProjS2, Error, Value and Except are turned to
- notations. They now must be applied (incompatibilities only in
- unrealistic cases).
-- More efficient versions of Zmult and times (30% faster)
-- Reals: the library is now divided in 6 parts (Rbase, Rfunctions,
- SeqSeries, Rtrigo, Ranalysis, Integration). New tactics: Sup and
- RCompute. See Reals.v for details.
-
-Modules
-
-- Beta version, see doc chap 2.5 for commands and chap 5 for theory
-
-Language
-
-- Inductive definitions now accept ">" in constructor types to declare
- the corresponding constructor as a coercion.
-- Idem for assumptions declarations and constants when the type is mentionned.
-- The "Coercion" and "Canonical Structure" keywords now accept the
- same syntax as "Definition", i.e. "hyps :=c (:t)?" or "hyps :t".
-- Theorem-like declaration now accepts the syntax "Theorem thm [x:t;...] : u".
-- Remark's and Fact's now definitively behave as Theorem and Lemma: when
- sections are closed, the full name of a Remark or a Fact has no longer a
- section part (source of incompatibilities)
-- Opaque Local's (i.e. built by tactics and ended by Qed), do not
- survive section closing any longer; as a side-effect, Opaque Local's
- now appear in the local context of proofs; their body is hidden
- though (source of incompatibilities); use one of Remark/Fact/Lemma/Theorem
- instead to simulate the old behaviour of Local (the section part of
- the name is not kept though)
-
-ML tactic and vernacular commands
-
-- "Grammar tactic" and "Grammar vernac" of type "ast" are no longer
- supported (only "Grammar tactic simple_tactic" of type "tactic"
- remains available).
-- Concrete syntax for ML written vernacular commands and tactics is
- now declared at ML level using camlp4 macros TACTIC EXTEND et VERNAC
- COMMAND EXTEND.
-- "Check n c" now "n:Check c", "Eval n ..." now "n:Eval ..."
-- "Proof with T" (* no documentation *)
-- SearchAbout id - prints all theorems which contain id in their type
-
-Tactic definitions
-
-- Static globalisation of identifiers and global references (source of
- incompatibilities, especially, Recursive keyword is required for
- mutually recursive definitions).
-- New evaluation semantics: no more partial evaluation at definition time;
- evaluation of all Tactic/Meta Definition, even producing terms, expect
- a proof context to be evaluated (especially "()" is no longer needed).
-- Debugger now shows the nesting level and the reasons of failure
-
-Tactics
-
-- Equality tactics (Rewrite, Reflexivity, Symmetry, Transitivity) now
- understand JM equality
-- Simpl and Change now apply to subterms also
-- "Simpl f" reduces subterms whose head constant is f
-- Double Induction now referring to hypotheses like "Intros until"
-- "Inversion" now applies also on quantified hypotheses (naming as
- for Intros until)
-- NewDestruct now accepts terms with missing hypotheses
-- NewDestruct and NewInduction now accept user-provided elimination scheme
-- NewDestruct and NewInduction now accept user-provided introduction names
-- Omega could solve goals such as ~`x=y` but failed when the
- hypothesis was unfolded to `x < y` -> False. This is fixed. In addition,
- it can also recognize 'False' in the hypothesis and use it to solve the
- goal.
-- Coercions now handled in "with" bindings
-- "Subst x" replaces all ocurrences of x by t in the goal and hypotheses
- when an hypothesis x=t or x:=t or t=x exists
-- Fresh names for Assert and Pose now based on collision-avoiding
- Intro naming strategy (exceptional source of incompatibilities)
-- LinearIntuition (* no documentation *)
-- Unfold expects a correct evaluable argument
-- Clear expects existing hypotheses
-
-Extraction (See details in plugins/extraction/CHANGES and README):
-
-- An experimental Scheme extraction is provided.
-- Concerning Ocaml, extracted code is now ensured to always type-check,
- thanks to automatic inserting of Obj.magic.
-- Experimental extraction of Coq new modules to Ocaml modules.
-
-Proof rendering in natural language
-
-- Export of theories to XML for publishing and rendering purposes now
- includes proof-trees (see http://www.cs.unibo.it/helm)
-
-Miscellaneous
-
-- Printing Coercion now used through the standard keywords Set/Add, Test, Print
-- "Print Term id" is an alias for "Print id"
-- New switch "Unset/Set Printing Symbols" to control printing of
- symbolic notations
-- Two new variants of implicit arguments are available
- - "Unset/Set Contextual Implicits" tells to consider implicit also the
- arguments inferable from the context (e.g. for nil or refl_eq)
- - "Unset/Set Strict Implicits" tells to consider implicit only the
- arguments that are inferable in any case (i.e. arguments that occurs
- as argument of rigid constants in the type of the remaining arguments;
- e.g. the witness of an existential is not strict since it can vanish when
- applied to a predicate which does not use its argument)
-
-Incompatibilities
-
-- "Grammar tactic ... : ast" and "Grammar vernac ... : ast" are no
- longer supported, use TACTIC EXTEND and VERNAC COMMAND EXTEND on the
- ML-side instead
-- Transparency of le_lt_dec and co (leads to some simplification in
- proofs; in some cases, incompatibilites is solved by declaring locally
- opaque the relevant constant)
-- Opaque Local do not now survive section closing (rename them into
- Remark/Lemma/... to get them still surviving the sections; this
- renaming allows also to solve incompatibilites related to now
- forbidden calls to the tactic Clear)
-- Remark and Fact have no longer (very) long names (use Local instead in case
- of name conflict)
-
-Bugs
-
-- Improved localisation of errors in Syntactic Definitions
-- Induction principle creation failure in presence of let-in fixed (BZ#238)
-- Inversion bugs fixed (BZ#212 and BZ#220)
-- Omega bug related to Set fixed (BZ#180)
-- Type-checking inefficiency of nested destructuring let-in fixed (BZ#216)
-- Improved handling of let-in during holes resolution phase (BZ#239)
-
-Efficiency
-
-- Implementation of a memory sharing strategy reducing memory
- requirements by an average ratio of 3.
-
-Changes from V7.3 to V7.3.1
-===========================
-
-Bug fixes
-
- - Corrupted Field tactic and Match Context tactic construction fixed
- - Checking of names already existing in Assert added (BZ#182)
- - Invalid argument bug in Exact tactic solved (BZ#183)
- - Colliding bound names bug fixed (BZ#202)
- - Wrong non-recursivity test for Record fixed (BZ#189)
- - Out of memory/seg fault bug related to parametric inductive fixed (BZ#195)
- - Setoid_replace/Setoid_rewrite bug wrt "==" fixed
-
-Misc
-
- - Ocaml version >= 3.06 is needed to compile Coq from sources
- - Simplification of fresh names creation strategy for Assert, Pose and
- LetTac (BZ#192)
-
-Changes from V7.2 to V7.3
-=========================
-
-Language
-
-- Slightly improved compilation of pattern-matching (slight source of
- incompatibilities)
-- Record's now accept anonymous fields "_" which does not build projections
-- Changes in the allowed elimination sorts for certain class of inductive
- definitions : an inductive definition without constructors
- of Sort Prop can be eliminated on sorts Set and Type A "singleton"
- inductive definition (one constructor with arguments in the sort Prop
- like conjunction of two propositions or equality) can be eliminated
- directly on sort Type (In V7.2, only the sorts Prop and Set were allowed)
-
-Tactics
-
-- New tactic "Rename x into y" for renaming hypotheses
-- New tactics "Pose x:=u" and "Pose u" to add definitions to local context
-- Pattern now working on partially applied subterms
-- Ring no longer applies irreversible congruence laws of mult but
- better applies congruence laws of plus (slight source of incompatibilities).
-- Field now accepts terms to be simplified as arguments (as for Ring). This
- extension has been also implemented using the toplevel tactic language.
-- Intuition does no longer unfold constants except "<->" and "~". It
- can be parameterized by a tactic. It also can introduce dependent
- product if needed (source of incompatibilities)
-- "Match Context" now matching more recent hypotheses first and failing only
- on user errors and Fail tactic (possible source of incompatibilities)
-- Tactic Definition's without arguments now allowed in Coq states
-- Better simplification and discrimination made by Inversion (source
- of incompatibilities)
-
-Bugs
-
-- "Intros H" now working like "Intro H" trying first to reduce if not a product
-- Forward dependencies in Cases now taken into account
-- Known bugs related to Inversion and let-in's fixed
-- Bug unexpected Delta with let-in now fixed
-
-Extraction (details in plugins/extraction/CHANGES or documentation)
-
-- Signatures of extracted terms are now mostly expunged from dummy arguments.
-- Haskell extraction is now operational (tested & debugged).
-
-Standard library
-
-- Some additions in [ZArith]: three files (Zcomplements.v, Zpower.v
- and Zlogarithms.v) moved from plugins/omega in order to be more
- visible, one Zsgn function, more induction principles (Wf_Z.v and
- tail of Zcomplements.v), one more general Euclid theorem
-- Peano_dec.v and Compare_dec.v now part of Arith.v
-
-Tools
-
-- new option -dump-glob to coqtop to dump globalizations (to be used by the
- new documentation tool coqdoc; see http://www.lri.fr/~filliatr/coqdoc)
-
-User Contributions
-
-- CongruenceClosure (congruence closure decision procedure)
- [Pierre Corbineau, ENS Cachan]
-- MapleMode (an interface to embed Maple simplification procedures over
- rational fractions in Coq)
- [David Delahaye, Micaela Mayero, Chalmers University]
-- Presburger: A formalization of Presburger's algorithm
- [Laurent Thery, INRIA Sophia Antipolis]
-- Chinese has been rewritten using Z from ZArith as datatype
- ZChinese is the new version, Chinese the obsolete one
- [Pierre Letouzey, LRI Orsay]
-
-Incompatibilities
-
-- Ring: exceptional incompatibilities (1 above 650 in submitted user
- contribs, leading to a simplification)
-- Intuition: does not unfold any definition except "<->" and "~"
-- Cases: removal of some extra Cases in configurations of the form
- "Cases ... of C _ => ... | _ D => ..." (effects on 2 definitions of
- submitted user contributions necessitating the removal of now superfluous
- proof steps in 3 different proofs)
-- Match Context, in case of incompatibilities because of a now non
- trapped error (e.g. Not_found or Failure), use instead tactic Fail
- to force Match Context trying the next clause
-- Inversion: better simplification and discrimination may occasionally
- lead to less subgoals and/or hypotheses and different naming of hypotheses
-- Unification done by Apply/Elim has been changed and may exceptionally lead
- to incompatible instantiations
-- Peano_dec.v and Compare_dec.v parts of Arith.v make Auto more
- powerful if these files were not already required (1 occurrence of
- this in submitted user contribs)
-
-Changes from V7.1 to V7.2
-=========================
-
-Language
-
-- Automatic insertion of patterns for local definitions in the type of
- the constructors of an inductive types (for compatibility with V6.3
- let-in style)
-- Coercions allowed in Cases patterns
-- New declaration "Canonical Structure id = t : I" to help resolution of
- equations of the form (proj ?)=a; if proj(e)=a then a is canonically
- equipped with the remaining fields in e, i.e. ? is instantiated by e
-
-Tactics
-
-- New tactic "ClearBody H" to clear the body of definitions in local context
-- New tactic "Assert H := c" for forward reasoning
-- Slight improvement in naming strategy for NewInduction/NewDestruct
-- Intuition/Tauto do not perform useless unfolding and work up to conversion
-
-Extraction (details in plugins/extraction/CHANGES or documentation)
-
-- Syntax changes: there are no more options inside the extraction commands.
- New commands for customization and options have been introduced instead.
-- More optimizations on extracted code.
-- Extraction tests are now embedded in 14 user contributions.
-
-Standard library
-
-- In [Relations], Rstar.v and Newman.v now axiom-free.
-- In [Sets], Integers.v now based on nat
-- In [Arith], more lemmas in Min.v, new file Max.v, tail-recursive
- plus and mult added to Plus.v and Mult.v respectively
-- New directory [Sorting] with a proof of heapsort (dragged from 6.3.1 lib)
-- In [Reals], more lemmas in Rbase.v, new lemmas on square, square root and
- trigonometric functions (R_sqr.v - Rtrigo.v); a complementary approach
- and new theorems about continuity and derivability in Ranalysis.v; some
- properties in plane geometry such as translation, rotation or similarity
- in Rgeom.v; finite sums and Chasles property in Rsigma.v
-
-Bugs
-
-- Confusion between implicit args of locals and globals of same base name fixed
-- Various incompatibilities wrt inference of "?" in V6.3.1 fixed
-- Implicits in infix section variables bug fixed
-- Known coercions bugs fixed
-
-- Apply "universe anomaly" bug fixed
-- NatRing now working
-- "Discriminate 1", "Injection 1", "Simplify_eq 1" now working
-- NewInduction bugs with let-in and recursively dependent hypotheses fixed
-- Syntax [x:=t:T]u now allowed as mentioned in documentation
-
-- Bug with recursive inductive types involving let-in fixed
-- Known pattern-matching bugs fixed
-- Known Cases elimination predicate bugs fixed
-- Improved errors messages for pattern-matching and projections
-- Better error messages for ill-typed Cases expressions
-
-Incompatibilities
-
-- New naming strategy for NewInduction/NewDestruct may affect 7.1 compatibility
-- Extra parentheses may exceptionally be needed in tactic definitions.
-- Coq extensions written in Ocaml need to be updated (see dev/changements.txt
- for a description of the main changes in the interface files of V7.2)
-- New behaviour of Intuition/Tauto may exceptionally lead to incompatibilities
-
-----------------------------------------------------------------------------
-Changes from V6.3.1 and V7.0 to V7.1
-====================================
-
-Notes:
-
-- items followed by (**) are important sources of incompatibilities
-- items followed by (*) may exceptionally be sources of incompatibilities
-- items followed by (+) have been introduced in version 7.0
-
-
-Main novelties
-==============
-
-References are to Coq V7.1 reference manual
-
-- New primitive let-in construct (see sections 1.2.8 and )
-- Long names (see sections 2.6 and 2.7)
-- New high-level tactic language (see chapter 10)
-- Improved search facilities (see section 5.2)
-- New extraction algorithm managing the Type level (see chapter 17)
-- New rewriting tactic for arbitrary equalities (see chapter 19)
-- New tactic Field to decide equalities on commutative fields (see 7.11)
-- New tactic Fourier to solve linear inequalities on reals numbers (see 7.11)
-- New tactics for induction/case analysis in "natural" style (see 7.7)
-- Deep restructuration of the code (safer, simpler and more efficient)
-- Export of theories to XML for publishing and rendering purposes
- (see http://www.cs.unibo.it/helm)
-
-
-Details of changes
-==================
-
-Language: new "let-in" construction
------------------------------------
-
-- New construction for local definitions (let-in) with syntax [x:=u]t (*)(+)
-
-- Local definitions allowed in Record (a.k.a. record à la Randy Pollack)
-
-
-Language: long names
---------------------
-
-- Each construction has a unique absolute names built from a base
- name, the name of the module in which they are defined (Top if in
- coqtop), and possibly an arbitrary long sequence of directory (e.g.
- "Coq.Lists.PolyList.flat_map" where "Coq" means that "flat_map" is part
- of Coq standard library, "Lists" means it is defined in the Lists
- library and "PolyList" means it is in the file Polylist) (+)
-
-- Constructions can be referred by their base name, or, in case of
- conflict, by a "qualified" name, where the base name is prefixed
- by the module name (and possibly by a directory name, and so
- on). A fully qualified name is an absolute name which always refer
- to the construction it denotes (to preserve the visibility of
- all constructions, no conflict is allowed for an absolute name) (+)
-
-- Long names are available for modules with the possibility of using
- the directory name as a component of the module full name (with
- option -R to coqtop and coqc, or command Add LoadPath) (+)
-
-- Improved conflict resolution strategy (the Unix PATH model),
- allowing more constructions to be referred just by their base name
-
-
-Language: miscellaneous
------------------------
-
-- The names of variables for Record projections _and_ for induction principles
- (e.g. sum_ind) is now based on the first letter of their type (main
- source of incompatibility) (**)(+)
-
-- Most typing errors have now a precise location in the source (+)
-
-- Slightly different mechanism to solve "?" (*)(+)
-
-- More arguments may be considered implicit at section closing (*)(+)
-
-- Bug with identifiers ended by a number greater than 2^30 fixed (+)
-
-- New visibility discipline for Remark, Fact and Local: Remark's and
- Fact's now survive at the end of section, but are only accessible using a
- qualified names as soon as their strength expires; Local's disappear and
- are moved into local definitions for each construction persistent at
- section closing
-
-
-Language: Cases
----------------
-
-- Cases no longer considers aliases inferable from dependencies in types (*)(+)
-
-- A redundant clause in Cases is now an error (*)
-
-
-Reduction
----------
-
-- New reduction flags "Zeta" and "Evar" in Eval Compute, for inlining of
- local definitions and instantiation of existential variables
-
-- Delta reduction flag does not perform Zeta and Evar reduction any more (*)
-
-- Constants declared as opaque (using Qed) can no longer become
- transparent (a constant intended to be alternatively opaque and
- transparent must be declared as transparent (using Defined)); a risk
- exists (until next Coq version) that Simpl and Hnf reduces opaque
- constants (*)
-
-
-New tactics
------------
-
-- New set of tactics to deal with types equipped with specific
- equalities (a.k.a. Setoids, e.g. nat equipped with eq_nat) [by C. Renard]
-
-- New tactic Assert, similar to Cut but expected to be more user-friendly
-
-- New tactic NewDestruct and NewInduction intended to replace Elim
- and Induction, Case and Destruct in a more user-friendly way (see
- restrictions in the reference manual)
-
-- New tactic ROmega: an experimental alternative (based on reflexion) to Omega
- [by P. Crégut]
-
-- New tactic language Ltac (see reference manual) (+)
-
-- New versions of Tauto and Intuition, fully rewritten in the new Ltac
- language; they run faster and produce more compact proofs; Tauto is
- fully compatible but, in exchange of a better uniformity, Intuition
- is slightly weaker (then use Tauto instead) (**)(+)
-
-- New tactic Field to decide equalities on commutative fields (as a
- special case, it works on real numbers) (+)
-
-- New tactic Fourier to solve linear inequalities on reals numbers
- [by L. Pottier] (+)
-
-- New tactics dedicated to real numbers: DiscrR, SplitRmult, SplitAbsolu (+)
-
-
-Changes in existing tactics
----------------------------
-
-- Reduction tactics in local definitions apply only to the body
-
-- New syntax of the form "Compute in Type of H." to require a reduction on
- the types of local definitions
-
-- Inversion, Injection, Discriminate, ... apply also on the
- quantified premises of a goal (using the "Intros until" syntax)
-
-- Decompose has been fixed but hypotheses may get different names (*)(+)
-
-- Tauto now manages uniformly hypotheses and conclusions of the form
- "t=t" which all are considered equivalent to "True". Especially,
- Tauto now solves goals of the form "H : ~ t = t |- A".
-
-- The "Let" tactic has been renamed "LetTac" and is now based on the
- primitive "let-in" (+)
-
-- Elim can no longer be used with an elimination schema different from
- the one defined at definition time of the inductive type. To overload
- an elimination schema, use "Elim using "
- (*)(+)
-
-- Simpl no longer unfolds the recursive calls of a mutually defined
- fixpoint (*)(+)
-
-- Intro now fails if the hypothesis name already exists (*)(+)
-
-- "Require Prolog" is no longer needed (i.e. it is available by default) (*)(+)
-
-- Unfold now fails on a non unfoldable identifier (*)(+)
-
-- Unfold also applies on definitions of the local context
-
-- AutoRewrite now deals only with the main goal and it is the purpose of
- Hint Rewrite to deal with generated subgoals (+)
-
-- Redundant or incompatible instantiations in Apply ... with ... are now
- correctly managed (+)
-
-
-Efficiency
-----------
-
-- Excessive memory uses specific to V7.0 fixed
-
-- Sizes of .vo files vary a lot compared to V6.3 (from -30% to +300%
- depending on the developments)
-
-- An improved reduction strategy for lazy evaluation
-
-- A more economical mechanism to ensure logical consistency at the Type level;
- warning: this is experimental and may produce "universes" anomalies
- (please report)
-
-
-Concrete syntax of constructions
---------------------------------
-
-- Only identifiers starting with "_" or a letter, and followed by letters,
- digits, "_" or "'" are allowed (e.g. "$" and "@" are no longer allowed) (*)
-
-- A multiple binder like (a:A)(a,b:(P a))(Q a) is no longer parsed as
- (a:A)(a0:(P a))(b:(P a))(Q a0) but as (a:A)(a0:(P a))(b:(P a0))(Q a0) (*)(+)
-
-- A dedicated syntax has been introduced for Reals (e.g ``3+1/x``) (+)
-
-- Pretty-printing of Infix notations fixed. (+)
-
-
-Parsing and grammar extension
------------------------------
-
-- More constraints when writing ast
-
- - "{...}" and the macros $LIST, $VAR, etc. now expect a metavariable
- (an identifier starting with $) (*)
- - identifiers should starts with a letter or "_" and be followed
- by letters, digits, "_" or "'" (other characters are still
- supported but it is not advised to use them) (*)(+)
-
-- Entry "command" in "Grammar" and quotations (<<...>> stuff) is
- renamed "constr" as in "Syntax" (+)
-
-- New syntax "[" sentence_1 ... sentence_n"]." to group sentences (useful
- for Time and to write grammar rules abbreviating several commands) (+)
-
-- The default parser for actions in the grammar rules (and for
- patterns in the pretty-printing rules) is now the one associated to
- the grammar (i.e. vernac, tactic or constr); no need then for
- quotations as in <:vernac:<...>>; to return an "ast", the grammar
- must be explicitly typed with tag ": ast" or ": ast list", or if a
- syntax rule, by using <<...>> in the patterns (expression inside
- these angle brackets are parsed as "ast"); for grammars other than
- vernac, tactic or constr, you may explicitly type the action with
- tags ": constr", ": tactic", or ":vernac" (**)(+)
-
-- Interpretation of names in Grammar rule is now based on long names,
- which allows to avoid problems (or sometimes tricks;) related to
- overloaded names (+)
-
-
-New commands
-------------
-
-- New commands "Print XML All", "Show XML Proof", ... to show or
- export theories to XML to be used with Helm's publishing and rendering
- tools (see http://www.cs.unibo.it/helm) (by Claudio Sacerdoti Coen) (+)
-
-- New commands to manually set implicit arguments (+)
-
- - "Implicits ident." to activate the implicit arguments mode just for ident
- - "Implicits ident [num1 num2 ...]." to explicitly give which
- arguments have to be considered as implicit
-
-- New SearchPattern/SearchRewrite (by Yves Bertot) (+)
-
-- New commands "Debug on"/"Debug off" to activate/deactivate the tactic
- language debugger (+)
-
-- New commands to map physical paths to logical paths (+)
- - Add LoadPath physical_dir as logical_dir
- - Add Rec LoadPath physical_dir as logical_dir
-
-
-Changes in existing commands
-----------------------------
-
-- Generalization of the usage of qualified identifiers in tactics
- and commands about globals, e.g. Decompose, Eval Delta;
- Hints Unfold, Transparent, Require
-
-- Require synchronous with Reset; Require's scope stops at Section ending (*)
-
-- For a module indirectly loaded by a "Require" but not exported,
- the command "Import module" turns the constructions defined in the
- module accessible by their short name, and activates the Grammar,
- Syntax, Hint, ... declared in the module (+)
-
-- The scope of the "Search" command can be restricted to some modules (+)
-
-- Final dot in command (full stop/period) must be followed by a blank
- (newline, tabulation or whitespace) (+)
-
-- Slight restriction of the syntax for Cbv Delta: if present, option [-myconst]
- must immediately follow the Delta keyword (*)(+)
-
-- SearchIsos currently not supported
-
-- Add ML Path is now implied by Add LoadPath (+)
-
-- New names for the following commands (+)
-
- AddPath -> Add LoadPath
- Print LoadPath -> Print LoadPath
- DelPath -> Remove LoadPath
- AddRecPath -> Add Rec LoadPath
- Print Path -> Print Coercion Paths
-
- Implicit Arguments On -> Set Implicit Arguments
- Implicit Arguments Off -> Unset Implicit Arguments
-
- Begin Silent -> Set Silent
- End Silent -> Unset Silent.
-
-
-Tools
------
-
-- coqtop (+)
-
- - Two executables: coqtop.byte and coqtop.opt (if supported by the platform)
- - coqtop is a link to the more efficient executable (coqtop.opt if present)
- - option -full is obsolete (+)
-
-- do_Makefile renamed into coq_makefile (+)
-
-- New option -R to coqtop and coqc to map a physical directory to a logical
- one (+)
-
-- coqc no longer needs to create a temporary file
-
-- No more warning if no initialization file .coqrc exists
-
-
-Extraction
-----------
-
-- New algorithm for extraction able to deal with "Type" (+)
- (by J.-C. Filliâtre and P. Letouzey)
-
-
-Standard library
-----------------
-
-- New library on maps on integers (IntMap, contributed by Jean Goubault)
-
-- New lemmas about integer numbers [ZArith]
-
-- New lemmas and a "natural" syntax for reals [Reals] (+)
-
-- Exc/Error/Value renamed into Option/Some/None (*)
-
-
-New user contributions
-----------------------
-
-- Constructive complex analysis and the Fundamental Theorem of Algebra [FTA]
- (Herman Geuvers, Freek Wiedijk, Jan Zwanenburg, Randy Pollack,
- Henk Barendregt, Nijmegen)
-
-- A new axiomatization of ZFC set theory [Functions_in_ZFC]
- (C. Simpson, Sophia-Antipolis)
-
-- Basic notions of graph theory [GRAPHS-BASICS] (Jean Duprat, Lyon)
-
-- A library for floating-point numbers [Float] (Laurent Théry, Sylvie Boldo,
- Sophia-Antipolis)
-
-- Formalisation of CTL and TCTL temporal logic [CtlTctl] (Carlos
- Daniel Luna,Montevideo)
-
-- Specification and verification of the Railroad Crossing Problem
- in CTL and TCTL [RailroadCrossing] (Carlos Daniel Luna,Montevideo)
-
-- P-automaton and the ABR algorithm [PAutomata]
- (Christine Paulin, Emmanuel Freund, Orsay)
-
-- Semantics of a subset of the C language [MiniC]
- (Eduardo Giménez, Emmanuel Ledinot, Suresnes)
-
-- Correctness proofs of the following imperative algorithms:
- Bresenham line drawing algorithm [Bresenham], Marché's minimal edition
- distance algorithm [Diff] (Jean-Christophe Filliâtre, Orsay)
-
-- Correctness proofs of Buchberger's algorithm [Buchberger] and RSA
- cryptographic algorithm [Rsa] (Laurent Théry, Sophia-Antipolis)
-
-- Correctness proof of Stalmarck tautology checker algorithm
- [Stalmarck] (Laurent Théry, Pierre Letouzey, Sophia-Antipolis)
diff --git a/CHANGES.md b/CHANGES.md
new file mode 100644
index 00000000..56e185e8
--- /dev/null
+++ b/CHANGES.md
@@ -0,0 +1,4015 @@
+Changes from 8.9+beta1 to 8.9.0
+===============================
+
+Assorted bug fixes.
+
+Changes from 8.8.2 to 8.9+beta1
+===============================
+
+Kernel
+
+- Mutually defined records are now supported.
+
+Notations
+
+- New support for autonomous grammars of terms, called "custom
+ entries" (see chapter "Syntax extensions" of the reference manual).
+
+- Deprecated compatibility notations will actually be removed in the
+ next version of Coq. Uses of these notations are generally easy to
+ fix thanks to the hint contained in the deprecation warnings. For
+ projects that require more than a handful of such fixes, there is [a
+ script](https://gist.github.com/JasonGross/9770653967de3679d131c59d42de6d17#file-replace-notations-py)
+ that will do it automatically, using the output of coqc. The script
+ contains documentation on its usage in a comment at the top.
+
+Tactics
+
+- Added toplevel goal selector `!` which expects a single focused goal.
+ Use with `Set Default Goal Selector` to force focusing before tactics
+ are called.
+
+- The undocumented "nameless" forms `fix N`, `cofix` that were
+ deprecated in 8.8 have been removed from Ltac's syntax; please use
+ `fix ident N/cofix ident` to explicitly name the (co)fixpoint
+ hypothesis to be introduced.
+
+- Introduction tactics `intro`/`intros` on a goal that is an
+ existential variable now force a refinement of the goal into a
+ dependent product rather than failing.
+
+- Support for `fix`/`cofix` added in Ltac `match` and `lazymatch`.
+
+- Ltac backtraces now include trace information about tactics
+ called by OCaml-defined tactics.
+
+- Option `Ltac Debug` now applies also to terms built using Ltac functions.
+
+- Deprecated the `Implicit Tactic` family of commands.
+
+- The default program obligation tactic uses a bounded proof search
+ instead of an unbounded and potentially non-terminating one now
+ (source of incompatibility).
+
+- The `simple apply` tactic now respects the `Opaque` flag when called from
+ Ltac (`auto` still does not respect it).
+
+- Tactic `constr_eq` now adds universe constraints needed for the
+ identity to the context (it used to ignore them). New tactic
+ `constr_eq_strict` checks that the required constraints already hold
+ without adding new ones. Preexisting tactic `constr_eq_nounivs` can
+ still be used if you really want to ignore universe constraints.
+
+- Tactics and tactic notations now understand the `deprecated` attribute.
+- The `fourier` tactic has been removed. Please now use `lra` instead. You
+ may need to add `Require Import Lra` to your developments. For compatibility,
+ we now define `fourier` as a deprecated alias of `lra`.
+
+- The `romega` tactics have been deprecated; please use `lia` instead.
+
+Focusing
+
+- Focusing bracket `{` now supports named goal selectors,
+ e.g. `[x]: {` will focus on a goal (existential variable) named `x`.
+ As usual, unfocus with `}` once the sub-goal is fully solved.
+
+Specification language
+
+- A fix to unification (which was sensitive to the ascii name of
+ variables) may occasionally change type inference in incompatible
+ ways, especially regarding the inference of the return clause of `match`.
+
+Standard Library
+
+- Added `Ascii.eqb` and `String.eqb` and the `=?` notation for them,
+ and proved some lemmas about them. Note that this might cause
+ incompatibilities if you have, e.g., `string_scope` and `Z_scope` both
+ open with `string_scope` on top, and expect `=?` to refer to `Z.eqb`.
+ Solution: wrap `_ =? _` in `(_ =? _)%Z` (or whichever scope you
+ want).
+
+- Added `Ndigits.N2Bv_sized`, and proved some lemmas about it.
+ Deprecated `Ndigits.N2Bv_gen`.
+
+- The scopes `int_scope` and `uint_scope` have been renamed to
+ `dec_int_scope` and `dec_uint_scope`, to clash less with ssreflect
+ and other packages. They are still delimited by `%int` and `%uint`.
+
+- Syntax notations for `string`, `ascii`, `Z`, `positive`, `N`, `R`,
+ and `int31` are no longer available merely by `Require`ing the files
+ that define the inductives. You must `Import` `Coq.Strings.String`,
+ `Coq.Strings.Ascii`, `Coq.ZArith.BinIntDef`, `Coq.PArith.BinPosDef`,
+ `Coq.NArith.BinNatDef`, `Coq.Reals.Rdefinitions`, and
+ `Coq.Numbers.Cyclic.Int31.Int31`, respectively, to be able to use
+ these notations. Note that passing `-compat 8.8` or issuing
+ `Require Import Coq.Compat.Coq88` will make these notations
+ available. Users wishing to port their developments automatically
+ may download `fix.py` from
+
+ and run a command like `while true; do make -Okj 2>&1 |
+ /path/to/fix.py; done` and get a cup of coffee. (This command must
+ be manually interrupted once the build finishes all the way though.
+ Note also that this method is not fail-proof; you may have to adjust
+ some scopes if you were relying on string notations not being
+ available even when `string_scope` was open.)
+
+- Numeral syntax for `nat` is no longer available without loading the
+ entire prelude (`Require Import Coq.Init.Prelude`). This only
+ impacts users running Coq without the init library (`-nois` or
+ `-noinit`) and also issuing `Require Import Coq.Init.Datatypes`.
+
+Tools
+
+- Coq_makefile lets one override or extend the following variables from
+ the command line: `COQFLAGS`, `COQCHKFLAGS`, `COQDOCFLAGS`.
+ `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`
+ (not the option). Use the `Arguments` command instead.
+- 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.
+- Added generic syntax for "attributes", as in:
+ `#[local] Lemma foo : bar.`
+- Added the `Numeral Notation` command for registering decimal numeral
+ notations for custom types
+- The `Set SsrHave NoTCResolution` command no longer has special global
+ scope. If you want the previous behavior, use `Global Set SsrHave
+ NoTCResolution`.
+- Multiple sections with the same name are allowed.
+
+Coq binaries and process model
+
+- Before 8.9, Coq distributed a single `coqtop` binary and a set of
+ dynamically loadable plugins that used to take over the main loop
+ for tasks such as IDE language server or parallel proof checking.
+
+ These plugins have been turned into full-fledged binaries so each
+ different process has associated a particular binary now, in
+ particular `coqidetop` is the CoqIDE language server, and
+ `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, the third rule 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).
+
+Standard Library
+
+- There are now conversions between `string` and `positive`, `Z`,
+ `nat`, and `N` in binary, octal, and hex.
+
+Display diffs between proof steps
+
+- `coqtop` and `coqide` can now highlight the differences between proof steps
+ in color. This can be enabled from the command line or the
+ `Set Diffs "on"/"off"/"removed"` command. Please see the documentation for
+ details. Showing diffs in Proof General requires small changes to PG
+ (under discussion).
+
+Notations
+
+- Added `++` infix for `VectorDef.append`.
+ Note that this might cause incompatibilities if you have, e.g., `list_scope`
+ and `vector_scope` both open with `vector_scope` on top, and expect `++` to
+ refer to `app`.
+ Solution: wrap `_ ++ _` in `(_ ++ _)%list` (or whichever scope you want).
+
+Changes from 8.8.1 to 8.8.2
+===========================
+
+Documentation
+
+- A PDF version of the reference manual is available once again.
+
+Tools
+
+- The coq-makefile targets `print-pretty-timed`, `print-pretty-timed-diff`,
+ and `print-pretty-single-time-diff` now correctly label the "before" and
+ "after" columns, rather than swapping them.
+
+Kernel
+
+- The kernel does not tolerate capture of global universes by
+ polymorphic universe binders, fixing a soundness break (triggered
+ only through custom plugins)
+
+Windows installer
+
+- The Windows installer now includes many more external packages that can be
+ individually selected for installation.
+
+Many other bug fixes and lots of documentation improvements (for details,
+see the 8.8.2 milestone at https://github.com/coq/coq/milestone/15?closed=1).
+
+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
+===============================
+
+Tools
+
+- Asynchronous proof delegation policy was fixed. Since version 8.7
+ Coq was ignoring previous runs and the `-async-proofs-delegation-threshold`
+ option did not have the expected behavior.
+
+Tactic language
+
+- The undocumented "nameless" forms `fix N`, `cofix` have been
+ deprecated; please use `fix ident N /cofix ident` to explicitely
+ name the (co)fixpoint hypothesis to be introduced.
+
+Documentation
+
+- The reference manual is now fully ported to Sphinx.
+
+Other small deprecations and bug fixes.
+
+Changes from 8.7.2 to 8.8+beta1
+===============================
+
+Kernel
+
+- Support for template polymorphism for definitions was removed. May trigger
+ more "universe inconsistency" errors in rare occasions.
+- Fixpoints are no longer allowed on non-recursive inductive types.
+
+Notations
+
+- Recursive notations with the recursive pattern repeating on the
+ right (e.g. "( x ; .. ; y ; z )") now supported.
+- Notations with a specific level for the leftmost nonterminal,
+ when printing-only, are supported.
+- Notations can now refer to the syntactic category of patterns (as in
+ "fun 'pat =>" or "match p with pat => ... end"). Two variants are
+ available, depending on whether a single variable is considered as a
+ pattern or not.
+- Recursive notations now support ".." patterns with several
+ occurrences of the recursive term or binder, possibly mixing terms
+ and binders, possibly in reverse left-to-right order.
+- "Locate" now working also on notations of the form "x + y" (rather
+ than "_ + _").
+
+Specification language
+
+- When printing clauses of a "match", clauses with same right-hand
+ side are factorized and the last most factorized clause with no
+ variables, if it exists, is turned into a default clause.
+ Use "Unset Printing Allow Default Clause" do deactivate printing
+ of a default clause.
+ Use "Unset Printing Factorizable Match Patterns" to deactivate
+ factorization of clauses with same right-hand side.
+
+Tactics
+
+- On Linux, "native_compute" calls can be profiled using the "perf"
+ utility. The command "Set NativeCompute Profiling" enables
+ profiling, and "Set NativeCompute Profile Filename" customizes
+ the profile filename.
+- The tactic "omega" is now aware of the bodies of context variables
+ such as "x := 5 : Z" (see #1362). This could be disabled via
+ Unset Omega UseLocalDefs.
+- The tactic "romega" is also aware now of the bodies of context variables.
+- The tactic "zify" resp. "omega with N" is now aware of N.pred.
+- Tactic "decide equality" now able to manage constructors which
+ contain proofs.
+- Added tactics reset ltac profile, show ltac profile (and variants)
+- Added tactics restart_timer, finish_timing, and time_constr as an
+ experimental way of timing Ltac's evaluation phase
+- Added tactic optimize_heap, analogous to the Vernacular Optimize
+ Heap, which performs a major garbage collection and heap compaction
+ in the OCaml run-time system.
+- The tactics "dtauto", "dintuition", "firstorder" now handle inductive types
+ with let bindings in the parameters.
+- The tactic "dtauto" now handles some inductives such as
+ "@sigT A (fun _ => B)" as non-dependent conjunctions.
+- A bug fixed in "rewrite H in *" and "rewrite H in * |-" may cause a
+ few rare incompatibilities (it was unintendedly recursively
+ rewriting in the side conditions generated by H).
+- Added tactics "assert_succeeds tac" and "assert_fails tac" to ensure
+ properties of the executation of a tactic without keeping the effect
+ of the execution.
+- `vm_compute` now supports existential variables.
+- Calls to `shelve` and `give_up` within calls to tactic `refine` now working.
+- Deprecated tactic `appcontext` was removed.
+
+Focusing
+
+- Focusing bracket `{` now supports single-numbered goal selector,
+ e.g. `2: {` will focus on the second sub-goal. As usual, unfocus
+ with `}` once the sub-goal is fully solved.
+ The `Focus` and `Unfocus` commands are now deprecated.
+
+Vernacular Commands
+
+- Proofs ending in "Qed exporting ident, .., ident" are not supported
+ anymore. Constants generated during `abstract` are kept private to the
+ local environment.
+- The deprecated Coercion Local, Open Local Scope, Notation Local syntax
+ was removed. Use Local as a prefix instead.
+- For the Extraction Language command, "OCaml" is spelled correctly.
+ The older "Ocaml" is still accepted, but deprecated.
+- Using “Require” inside a section is deprecated.
+- An experimental command "Show Extraction" allows to extract the content
+ of the current ongoing proof (grant wish #4129).
+- Coercion now accepts the type of its argument to be "Prop" or "Type".
+- The "Export" modifier can now be used when setting and unsetting options, and
+ will result in performing the same change when the module corresponding the
+ command is imported.
+- The `Axiom` command does not automatically declare axioms as instances when
+ their type is a class. Previous behavior can be restored using `Set
+ Typeclasses Axioms Are Instances`.
+
+Universes
+
+- Qualified naming of global universes now works like other namespaced
+ objects (e.g. constants), with a separate namespace, inside and across
+ module and library boundaries. Global universe names introduced in an
+ inductive / constant / Let declaration get qualified with the name of
+ the declaration.
+- Universe cumulativity for inductive types is now specified as a
+ variance for each polymorphic universe. See the reference manual for
+ more information.
+- Inference of universe constraints with cumulative inductive types
+ produces more general constraints. Unsetting new option Cumulativity
+ Weak Constraints produces even more general constraints (but may
+ produce too many universes to be practical).
+- Fix #5726: Notations that start with `Type` now support universe instances
+ with `@{u}`.
+- `with Definition` now understands universe declarations
+ (like `@{u| Set < u}`).
+
+Tools
+
+- Coq can now be run with the option -mangle-names to change the auto-generated
+ name scheme. This is intended to function as a linter for developments that
+ want to be robust to changes in auto-generated names. This feature is experimental,
+ and may change or disappear without warning.
+- GeoProof support was removed.
+
+Checker
+
+- The checker now accepts filenames in addition to logical paths.
+
+CoqIDE
+
+- Find and Replace All report the number of occurrences found; Find indicates
+ when it wraps.
+
+coqdep
+
+- Learned to read -I, -Q, -R and filenames from _CoqProject files.
+ This is used by coq_makefile when generating dependencies for .v
+ files (but not other files).
+
+Documentation
+
+- The Coq FAQ, formerly located at https://coq.inria.fr/faq, has been
+ moved to the GitHub wiki section of this repository; the main entry
+ page is https://github.com/coq/coq/wiki/The-Coq-FAQ.
+- Documentation: a large community effort resulted in the migration
+ of the reference manual to the Sphinx documentation tool. The result
+ is partially integrated in this version.
+
+Standard Library
+
+- New libraries Coq.Init.Decimal, Coq.Numbers.DecimalFacts,
+ Coq.Numbers.DecimalNat, Coq.Numbers.DecimalPos,
+ Coq.Numbers.DecimalN, Coq.Numbers.DecimalZ,
+ Coq.Numbers.DecimalString providing a type of decimal numbers, some
+ facts about them, and conversions between decimal numbers and nat,
+ positive, N, Z, and string.
+- Added [Coq.Strings.String.concat] to concatenate a list of strings
+ inserting a separator between each item
+- Notation `'` for Zpos in QArith was removed.
+
+- Some deprecated aliases are now emitting warnings when used.
+
+Compatibility support
+
+- Support for compatibility with versions before 8.6 was dropped.
+
+Options
+
+- The following deprecated options have been removed:
+
+ + `Refolding Reduction`
+ + `Standard Proposition Elimination`
+ + `Dependent Propositions Elimination`
+ + `Discriminate Introduction`
+ + `Shrink Abstract`
+ + `Tactic Pattern Unification`
+ + `Intuition Iff Unfolding`
+ + `Injection L2R Pattern Order`
+ + `Record Elimination Schemes`
+ + `Match Strict`
+ + `Tactic Compat Context`
+ + `Typeclasses Legacy Resolution`
+ + `Typeclasses Module Eta`
+ + `Typeclass Resolution After Apply`
+
+Changes from 8.7.1 to 8.7.2
+===========================
+
+Fixed a critical bug in the VM handling of universes (#6677). This bug
+affected all releases since 8.5.
+
+Improved support for building with OCaml 4.06.0 and external num package.
+
+Many other bug fixes, documentation improvements, and user
+message improvements (for details, see the 8.7.2 milestone at
+https://github.com/coq/coq/milestone/11?closed=1).
+
+Changes from 8.7.0 to 8.7.1
+===========================
+
+Compatibility with OCaml 4.06.0.
+
+Many bug fixes, documentation improvements, and user message improvements (for
+details see the 8.7.1 milestone at https://github.com/coq/coq/milestone/10?closed=1).
+
+Changes from 8.7+beta2 to 8.7.0
+===============================
+
+OCaml
+
+- Users can pass specific flags to the OCaml optimizing compiler by
+ -using the flambda-opts configure-time option.
+
+ Beware that compiling Coq with a flambda-enabled compiler is
+ experimental and may require large amounts of RAM and CPU, see
+ INSTALL for more details.
+
+Changes from 8.7+beta1 to 8.7+beta2
+===================================
+
+Tools
+
+- In CoqIDE, the "Compile Buffer" command takes account of flags in
+ _CoqProject or other project file.
+
+Improvements around some error messages.
+
+Many bug fixes including two important ones:
+
+- Bug #5730: CoqIDE becomes unresponsive on file open.
+- coq_makefile: make sure compile flags for Coq and coq_makefile are in sync
+ (in particular, make sure the `-safe-string` option is used to compile plugins).
+
+Changes from 8.6.1 to 8.7+beta1
+===============================
+
+Tactics
+
+- New tactic "extensionality in H" which applies (possibly dependent)
+ functional extensionality in H supposed to be a quantified equality
+ until giving a bare equality.
+- New tactic "inversion_sigma" which turns equalities of dependent
+ pairs (e.g., "existT P x p = existT P y q", frequently left over by
+ "inversion" on a dependent type family) into pairs of equalities
+ (e.g., a hypothesis "H : x = y" and a hypothesis of type "rew H in p
+ = q"); these hypotheses can subsequently be simplified using
+ "subst", without ever invoking any kind of axiom asserting
+ uniqueness of identity proofs. If you want to explicitly specify the
+ hypothesis to be inverted, or name the generated hypotheses, you can
+ invoke "induction H as [H1 H2] using eq_sigT_rect". The tactic also
+ works for "sig", "sigT2", and "sig2", and there are similar
+ "eq_sig*_rect" induction lemmas.
+- Tactic "specialize with ..." now accepts any partial bindings.
+ Missing bindings are either solved by unification or left quantified
+ in the hypothesis.
+- New representation of terms that statically ensure stability by
+ evar-expansion. This has several consequences.
+ * In terms of performance, this adds a cost to every term destructuration,
+ but at the same time most eager evar normalizations were removed, which
+ couterbalances this drawback and even sometimes outperforms the old
+ implementation. For instance, many operations that would require O(n)
+ normalization of the term are now O(1) in tactics. YMMV.
+ * This triggers small changes in unification, which was not evar-insensitive.
+ Most notably, the new implementation recognizes Miller patterns that were
+ missed before because of a missing normalization step. Hopefully this should
+ be fairly uncommon.
+- Tactic "auto with real" can now discharge comparisons of literals.
+- The types of variables in patterns of "match" are now
+ beta-iota-reduced after type-checking. This has an impact on the
+ type of the variables that the tactic "refine" introduces in the
+ context, producing types a priori closer to the expectations.
+- In "Tactic Notation" or "TACTIC EXTEND", entry "constr_with_bindings"
+ now uses type classes and rejects terms with unresolved holes, like
+ entry "constr" does. To get the former behavior use
+ "open_constr_with_bindings" (possible source of incompatibility).
+- New e-variants eassert, eenough, epose proof, eset, eremember, epose
+ which behave like the corresponding variants with no "e" but turn
+ unresolved implicit arguments into existential variables, on the
+ shelf, rather than failing.
+- Tactic injection has become more powerful (closes bug #4890) and its
+ documentation has been updated.
+- New variants of the `first` and `solve` tacticals that do not rely
+ on parsing rules, meant to define tactic notations.
+- Added support for side effects hooks in `cbv`, `cbn` and `simpl`.
+ The side effects are provided via a plugin:
+ https://github.com/herbelin/reduction-effects/
+- It is now possible to take hint database names as parameters in a
+ Ltac definition or a Tactic Notation.
+- New option `Set Ltac Batch Debug` on top of `Set Ltac Debug` for
+ non-interactive Ltac debug output.
+
+Gallina
+
+- Now supporting all kinds of binders, including 'pat, in syntax of record fields.
+
+Vernacular Commands
+
+- Goals context can be printed in a more compact way when `Set
+ Printing Compact Contexts` is activated.
+- Unfocused goals can be printed with the `Set Printing Unfocused`
+ option.
+- `Print` now shows the types of let-bindings.
+- The compatibility options for printing primitive projections
+ (`Set Printing Primitive Projection Parameters` and
+ `Set Printing Primitive Projection Compatibility`) are now off by default.
+- Possibility to unset the printing of notations in a more fine grained
+ fashion than `Unset Printing Notations` is provided without any
+ user-syntax. The goal is that someone creates a plugin to experiment
+ such a user-syntax, to be later integrated in Coq when stabilized.
+- `About` now tells if a reference is a coercion.
+- The deprecated `Save` vernacular and its form `Save Theorem id` to
+ close proofs have been removed from the syntax. Please use `Qed`.
+- `Search` now sorts results by relevance (the relevance metric is a
+ weighted sum of number of distinct symbols and size of the term).
+
+Standard Library
+
+- New file PropExtensionality.v to explicitly work in the axiomatic
+ context of propositional extensionality.
+- New file SetoidChoice.v axiomatically providing choice over setoids,
+ and, consequently, choice of representatives in equivalence classes.
+ Various proof-theoretic characterizations of choice over setoids in
+ file ChoiceFacts.v.
+- New lemmas about iff and about orders on positive and Z.
+- New lemmas on powerRZ.
+- Strengthened statement of JMeq_eq_dep (closes bug #4912).
+- The BigN, BigZ, BigZ libraries are no longer part of the Coq standard
+ library, they are now provided by a separate repository
+ https://github.com/coq/bignums
+ The split has been done just after the Int31 library.
+
+- IZR (Reals) has been changed to produce a compact representation of
+ integers. As a consequence, IZR is no longer convertible to INR and
+ lemmas such as INR_IZR_INZ should be used instead.
+- Real constants are now represented using IZR rather than R0 and R1;
+ this might cause rewriting rules to fail to apply to constants.
+- Added new notation {x & P} for sigT (without a type for x)
+
+Plugins
+
+- The Ssreflect plugin is now distributed with Coq. Its documentation has
+ been integrated as a chapter of the reference manual. This chapter is
+ work in progress so feedback is welcome.
+- The mathematical proof language (also known as declarative mode) was removed.
+- A new command Extraction TestCompile has been introduced, not meant
+ for the general user but instead for Coq's test-suite.
+- The extraction plugin is no longer loaded by default. It must be
+ explicitly loaded with [Require Extraction], which is backwards
+ compatible.
+- The functional induction plugin (which provides the [Function]
+ vernacular) is no longer loaded by default. It must be explicitly
+ loaded with [Require FunInd], which is backwards compatible.
+
+
+Dependencies
+
+- Support for camlp4 has been removed.
+
+Tools
+
+- coq_makefile was completely redesigned to improve its maintainability and
+ the extensibility of generated Makefiles, and to make _CoqProject files
+ more palatable to IDEs. Overview:
+ * _CoqProject files contain only Coq specific data (i.e. the list of
+ files, -R options, ...)
+ * coq_makefile translates _CoqProject to Makefile.conf and copies in the
+ desired location a standard Makefile (that reads Makefile.conf)
+ * Makefile extensions can be implemented in a Makefile.local file (read
+ by the main Makefile) by installing a hook in the extension points
+ provided by the standard Makefile
+ The current version contains code for retro compatibility that prints
+ warnings when a deprecated feature is used. Please upgrade your _CoqProject
+ accordingly.
+ * Additionally, coq_makefile-made Makefiles now support experimental timing
+ targets `pretty-timed`, `pretty-timed-before`, `pretty-timed-after`,
+ `print-pretty-timed-diff`, `print-pretty-single-time-diff`,
+ `all.timing.diff`, and the variable `TIMING=1` (or `TIMING=before` or
+ `TIMING=after`); see the documentation for more details.
+
+Build Infrastructure
+
+- Note that 'make world' does not build the bytecode binaries anymore.
+ For that, you can use 'make byte' (and 'make install-byte' afterwards).
+ Warning: native and byte compilations should *not* be mixed in the same
+ instance of 'make -j', otherwise both ocamlc and ocamlopt might race for
+ access to the same .cmi files. In short, use "make -j && make -j byte"
+ instead of "make -j world byte".
+
+Universes
+
+- Cumulative inductive types. see prefixes "Cumulative", "NonCumulative"
+ for inductive definitions and the option "Set Polymorphic Inductive Cumulativity"
+ in the reference manual.
+- New syntax `foo@{_}` to instantiate a polymorphic definition with
+ anonymous universes (can also be used with `Type`).
+
+XML Protocol and internal changes
+
+See dev/doc/changes.txt
+
+Many bugfixes including #1859, #2884, #3613, #3943, #3994,
+#4250, #4709, #4720, #4824, #4844, #4911, #5026, #5233,
+#5275, #5315, #5336, #5360, #5390, #5414, #5417, #5420,
+#5439, #5449, #5475, #5476, #5482, #5501, #5507, #5520,
+#5523, #5524, #5553, #5577, #5578, #5589, #5597, #5598,
+#5607, #5618, #5619, #5620, #5641, #5648, #5651, #5671.
+
+Many bugfixes on OS X and Windows (now the test-suite passes on these
+platforms too).
+
+Many optimizations.
+
+Many documentation improvements.
+
+Changes from 8.6 to 8.6.1
+=========================
+
+- Fix #5380: Default colors for CoqIDE are actually applied.
+- Fix plugin warnings
+- Document named evars (including Show ident)
+- Fix Bug #5574, document function scope
+- Adding a test case as requested in bug 5205.
+- Fix Bug #5568, no dup notation warnings on repeated module imports
+- Fix documentation of Typeclasses eauto :=
+- Refactor documentation of records.
+- Protecting from warnings while compiling 8.6
+- Fixing an inconsistency between configure and configure.ml
+- Add test-suite checks for coqchk with constraints
+- Fix bug #5019 (looping zify on dependent types)
+- Fix bug 5550: "typeclasses eauto with" does not work with section variables.
+- Bug 5546, qualify datatype constructors when needed in Show Match
+- Bug #5535, test for Show with -emacs
+- Fix bug #5486, don't reverse ids in tuples
+- Fixing #5522 (anomaly with free vars of pat)
+- Fix bug #5526, don't check for nonlinearity in notation if printing only
+- Fix bug #5255
+- Fix bug #3659: -time should understand multibyte encodings.
+- FIx bug #5300: Anomaly: Uncaught exception Not_found" in "Print Assumptions".
+- Fix outdated description in RefMan.
+- Repairing `Set Rewriting Schemes`
+- Fixing #5487 (v8.5 regression on ltac-matching expressions with evars).
+- Fix description of command-line arguments for Add (Rec) LoadPath
+- Fix bug #5377: @? patterns broken.
+- add XML protocol doc
+- Fix anomaly when doing [all:Check _.] during a proof.
+- Correction of bug #4306
+- Fix #5435: [Eval native_compute in] raises anomaly.
+- Instances should obey universe binders even when defined by tactics.
+- Intern names bound in match patterns
+- funind: Ignore missing info for current function
+- Do not typecheck twice the type of opaque constants.
+- show unused intro pattern warning
+- [future] Be eager when "chaining" already resolved future values.
+- Opaque side effects
+- Fix #5132: coq_makefile generates incorrect install goal
+- Run non-tactic comands without resilient_command
+- Univs: fix bug #5365, generation of u+k <= v constraints
+- make `emit' tail recursive
+- Don't require printing-only notation to be productive
+- Fix the way setoid_rewrite handles bindings.
+- Fix for bug 5244 - set printing width ignored when given enough space
+- Fix bug 4969, autoapply was not tagging shelved subgoals correctly
+
+Changes from V8.6beta1 to V8.6
+==============================
+
+Kernel
+
+- Fixed critical bug #5248 in VM long multiplication on 32-bit
+ architectures. Was there only since 8.6beta1, so no stable release impacted.
+
+Other bug fixes in universes, type class shelving,...
+
+Changes from V8.5 to V8.6beta1
+==============================
+
+Kernel
+
+- A new, faster state-of-the-art universe constraint checker.
+
+Specification language
+
+- Giving implicit arguments explicitly to a constant with multiple
+ choices of implicit arguments does not break any more insertion of
+ further maximal implicit arguments.
+- Ability to put any pattern in binders, prefixed by quote, e.g.
+ "fun '(a,b) => ...", "λ '(a,(b,c)), ...", "Definition foo '(x,y) := ...".
+ It expands into a "let 'pattern := ..."
+
+Tactics
+
+- Flag "Bracketing Last Introduction Pattern" is now on by default.
+- Flag "Regular Subst Tactic" is now on by default: it respects the
+ initial order of hypothesis, it contracts cycles, it unfolds no
+ local definitions (common source of incompatibilities, fixable by
+ "Unset Regular Subst Tactic").
+- New flag "Refolding Reduction", now disabled by default, which turns
+ on refolding of constants/fixpoints (as in cbn) during the reductions
+ done during type inference and tactic retyping. Can be extremely
+ expensive. When set off, this recovers the 8.4 behaviour of unification
+ and type inference. Potential source of incompatibility with 8.5 developments
+ (the option is set on in Compat/Coq85.v).
+- New flag "Shrink Abstract" that minimalizes proofs generated by the abstract
+ tactical w.r.t. variables appearing in the body of the proof.
+ On by default and deprecated. Minor source of incompatibility
+ for code relying on the precise arguments of abstracted proofs.
+- Serious bugs are fixed in tactic "double induction" (source of
+ incompatibilities as soon as the inductive types have dependencies in
+ the type of their constructors; "double induction" remains however
+ deprecated).
+- In introduction patterns of the form (pat1,...,patn), n should match
+ the exact number of hypotheses introduced (except for local definitions
+ for which pattern can be omitted, as in regular pattern-matching).
+- Tactic scopes in Ltac like constr: and ltac: now require parentheses around
+ their argument.
+- Every generic argument type declares a tactic scope of the form "name:(...)"
+ where name is the name of the argument. This generalizes the constr: and ltac:
+ instances.
+- When in strict mode (i.e. in a Ltac definition), if the "intro" tactic is
+ given a free identifier, it is not bound in subsequent tactics anymore.
+ In order to introduce a binding, use e.g. the "fresh" primitive instead
+ (potential source of incompatibilities).
+- New tactics is_ind, is_const, is_proj, is_constructor for use in Ltac.
+- New goal selectors. Sets of goals can be selected by listing integers
+ ranges. Example: "1,4-7,24: tac" focuses "tac" on goals 1,4,5,6,7,24.
+- For uniformity with "destruct"/"induction" and for a more natural
+ behavior, "injection" can now work in place by activating option
+ "Structural Injection". In this case, hypotheses are also put in the
+ context in the natural left-to-right order and the hypothesis on
+ which injection applies is cleared.
+- Tactic "contradiction" (hence "easy") now also solve goals with
+ hypotheses of the form "~True" or "t<>t" (possible source of
+ incompatibilities because of more successes in automation, but
+ generally a more intuitive strategy).
+- Option "Injection On Proofs" was renamed "Keep Proof Equalities". When
+ enabled, injection and inversion do not drop equalities between objects
+ in Prop. Still disabled by default.
+- New tactics "notypeclasses refine" and "simple notypeclasses refine" that
+ disallow typeclass resolution when typechecking their argument, for use
+ in typeclass hints.
+- Integration of LtacProf, a profiler for Ltac.
+- Reduction tactics now accept more fine-grained flags: iota is now a shorthand
+ for the new flags match, fix and cofix.
+- The ssreflect subterm selection algorithm is now accessible to tactic writers
+ through the ssrmatching plugin.
+- When used as an argument of an ltac function, "auto" without "with"
+ nor "using" clause now correctly uses only the core hint database by
+ default.
+
+Hints
+
+- Revised the syntax of [Hint Cut] to follow standard notation for regexps.
+- Hint Mode now accepts "!" which means that the mode matches only if the
+ argument's head is not an evar (it goes under applications, casts, and
+ scrutinees of matches and projections).
+- Hints can now take an optional user-given pattern, used only by
+ [typeclasses eauto] with the [Filtered Unification] option on.
+
+Typeclasses
+
+- Many new options and new engine based on the proof monad. The
+ [typeclasses eauto] tactic is now a multi-goal, multi-success tactic.
+ See reference manual for more information. It is planned to
+ replace auto and eauto in the following version. The 8.5 resolution
+ engine is still available to help solve compatibility issues.
+
+Program
+
+- The "Shrink Obligations" flag now applies to all obligations, not only
+ those solved by the automatic tactic.
+- "Shrink Obligations" is on by default and deprecated. Minor source of
+ incompatibility for code relying on the precise arguments of
+ obligations.
+
+Notations
+
+- "Bind Scope" can once again bind "Funclass" and "Sortclass".
+
+General infrastructure
+
+- New configurable warning system which can be controlled with the vernacular
+ command "Set Warnings", or, under coqc/coqtop, with the flag "-w". In
+ particular, the default is now that warnings are printed by coqc.
+- In asynchronous mode, Coq is now capable of recovering from errors and
+ continue processing the document.
+
+Tools
+
+- coqc accepts a -o option to specify the output file name
+- coqtop accepts --print-version to print Coq and OCaml versions in
+ easy to parse format
+- Setting [Printing Dependent Evars Line] can be unset to disable the
+ computation associated with printing the "dependent evars: " line in
+ -emacs mode
+- Removed the -verbose-compat-notations flag and the corresponding Set
+ Verbose Compat vernacular, since these warnings can now be silenced or
+ turned into errors using "-w".
+
+XML protocol
+
+- message format has changed, see dev/doc/changes.txt for more details.
+
+Many bug fixes, minor changes and documentation improvements are not mentioned
+here.
+
+Changes from V8.5pl2 to V8.5pl3
+===============================
+
+Critical bugfix
+
+- #4876: Guard checker incompleteness when using primitive projections
+
+Other bugfixes
+
+- #4780: Induction with universe polymorphism on was creating ill-typed terms.
+- #4673: regression in setoid_rewrite, unfolding let-ins for type unification.
+- #4754: Regression in setoid_rewrite, allow postponed unification problems to remain.
+- #4769: Anomaly with universe polymorphic schemes defined inside sections.
+- #3886: Program: duplicate obligations of mutual fixpoints.
+- #4994: Documentation typo.
+- #5008: Use the "md5" command on OpenBSD.
+- #5007: Do not assume the "TERM" environment variable is always set.
+- #4606: Output a break before a list only if there was an empty line.
+- #5001: metas not cleaned properly in clenv_refine_in.
+- #2336: incorrect glob data for module symbols (bug #2336).
+- #4832: Remove extraneous dot in error message.
+- Anomaly in printing a unification error message.
+- #4947: Options which take string arguments are not backwards compatible.
+- #4156: micromega cache files are now hidden files.
+- #4871: interrupting par:abstract kills coqtop.
+- #5043: [Admitted] lemmas pick up section variables.
+- Fix name of internal refine ("simple refine").
+- #5062: probably a typo in Strict Proofs mode.
+- #5065: Anomaly: Not a proof by induction.
+- Restore native compiler optimizations, they were disabled since 8.5!
+- #5077: failure on typing a fixpoint with evars in its type.
+- Fix recursive notation bug.
+- #5095: non relevant too strict test in let-in abstraction.
+- Ensuring that the evar name is preserved by "rename".
+- #4887: confusion between using and with in documentation of firstorder.
+- Bug in subst with let-ins.
+- #4762: eauto weaker than auto.
+- Remove if_then_else (was buggy). Use tryif instead.
+- #4970: confusion between special "{" and non special "{{" in notations.
+- #4529: primitive projections unfolding.
+- #4416: Incorrect "Error: Incorrect number of goals".
+- #4863: abstract in typeclass hint fails.
+- #5123: unshelve can impact typeclass resolution
+- Fix a collision about the meta-variable ".." in recursive notations.
+- Fix printing of info_auto.
+- #3209: Not_found due to an occur-check cycle.
+- #5097: status of evars refined by "clear" in ltac: closed wrt evars.
+- #5150: Missing dependency of the test-suite subsystems in prerequisite.
+- Fix a bug in error printing of unif constraints
+- #3941: Do not stop propagation of signals when Coq is busy.
+- #4822: Incorrect assertion in cbn.
+- #3479 parsing of "{" and "}" when a keyword starts with "{" or "}".
+- #5127: Memory corruption with the VM.
+- #5102: bullets parsing broken by calls to parse_entry.
+
+Various documentation improvements
+
+
+Changes from V8.5pl1 to V8.5pl2
+===============================
+
+Critical bugfix
+- Checksums of .vo files dependencies were not correctly checked.
+- Unicode-to-ASCII translation was not injective, leading in a soundness bug in
+ the native compiler.
+
+Other bugfixes
+
+- #4097: more efficient occur-check in presence of primitive projections
+- #4398: type_scope used consistently in "match goal".
+- #4450: eauto does not work with polymorphic lemmas
+- #4677: fix alpha-conversion in notations needing eta-expansion.
+- Fully preserve initial order of hypotheses in "Regular Subst Tactic" mode.
+- #4644: a regression in unification.
+- #4725: Function (Error: Conversion test raised an anomaly) and Program
+ (Error: Cannot infer this placeholder of type)
+- #4747: Problem building Coq 8.5pl1 with OCaml 4.03.0: Fatal warnings
+- #4752: CoqIDE crash on files not ended by ".v".
+- #4777: printing inefficiency with implicit arguments
+- #4818: "Admitted" fails due to undefined universe anomaly after calling
+ "destruct"
+- #4823: remote counter: avoid thread race on sockets
+- #4841: -verbose flag changed semantics in 8.5, is much harder to use
+- #4851: [nsatz] cannot handle duplicated hypotheses
+- #4858: Anomaly: Uncaught exception Failure("hd"). Please report. in variant
+ of nsatz
+- #4880: [nsatz_compute] generates invalid certificates if given redundant
+ hypotheses
+- #4881: synchronizing "Declare Implicit Tactic" with backtrack.
+- #4882: anomaly with Declare Implicit Tactic on hole of type with evars
+- Fix use of "Declare Implicit Tactic" in refine.
+ triggered by CoqIDE
+- #4069, #4718: congruence fails when universes are involved.
+
+Universes
+- Disallow silently dropping universe instances applied to variables
+ (forward compatible)
+- Allow explicit universe instances on notations, when they can apply
+ to the head reference of their expansion.
+
+Build infrastructure
+- New update on how to find camlp5 binary and library at configure time.
+
+Changes from V8.5 to V8.5pl1
+============================
+
+Critical bugfix
+- The subterm relation for the guard condition was incorrectly defined on
+ primitive projections (#4588)
+
+Plugin development tools
+- add a .merlin target to the makefile
+
+Various performance improvements (time, space used by .vo files)
+
+Other bugfixes
+
+- Fix order of arguments to Big.compare_case in ExtrOcamlZBigInt.v
+- Added compatibility coercions from Specif.v which were present in Coq 8.4.
+- Fixing a source of inefficiency and an artificial dependency in the printer in the congruence tactic.
+- Allow to unset the refinement mode of Instance in ML
+- Fixing an incorrect use of prod_appvect on a term which was not a product in setoid_rewrite.
+- Add -compat 8.4 econstructor tactics, and tests
+- Add compatibility Nonrecursive Elimination Schemes
+- Fixing the "No applicable tactic" non informative error message regression on apply.
+- Univs: fix get_current_context (bug #4603, part I)
+- Fix a bug in Program coercion code
+- Fix handling of arity of definitional classes.
+- #4630: Some tactics are 20x slower in 8.5 than 8.4.
+- #4627: records with no declared arity can be template polymorphic.
+- #4623: set tactic too weak with universes (regression)
+- Fix incorrect behavior of CS resolution
+- #4591: Uncaught exception in directory browsing.
+- CoqIDE is more resilient to initialization errors.
+- #4614: "Fully check the document" is uninterruptable.
+- Try eta-expansion of records only on non-recursive ones
+- Fix bug when a sort is ascribed to a Record
+- Primitive projections: protect kernel from erroneous definitions.
+- Fixed bug #4533 with previous Keyed Unification commit
+- Win: kill unreliable hence do not waitpid after kill -9 (Close #4369)
+- Fix strategy of Keyed Unification
+- #4608: Anomaly "output_value: abstract value (outside heap)".
+- #4607: do not read native code files if native compiler was disabled.
+- #4105: poor escaping in the protocol between CoqIDE and coqtop.
+- #4596: [rewrite] broke in the past few weeks.
+- #4533 (partial): respect declared global transparency of projections in unification.ml
+- #4544: Backtrack on using full betaiota reduction during keyed unification.
+- #4540: CoqIDE bottom progress bar does not update.
+- Fix regression from 8.4 in reflexivity
+- #4580: [Set Refine Instance Mode] also used for Program Instance.
+- #4582: cannot override notation [ x ]. MAY CREATE INCOMPATIBILITIES, see #4683.
+- STM: Print/Extraction have to be skipped if -quick
+- #4542: CoqIDE: STOP button also stops workers
+- STM: classify some variants of Instance as regular `Fork nodes.
+- #4574: Anomaly: Uncaught exception Invalid_argument("splay_arity").
+- Do not give a name to anonymous evars anymore. See bug #4547.
+- STM: always stock in vio files the first node (state) of a proof
+- STM: not delegate proofs that contain Vernac(Module|Require|Import), #4530
+- Don't fail fatally if PATH is not set.
+- #4537: Coq 8.5 is slower in typeclass resolution.
+- #4522: Incorrect "Warning..." on windows.
+- #4373: coqdep does not know about .vio files.
+- #3826: "Incompatible module types" is uninformative.
+- #4495: Failed assertion in metasyntax.ml.
+- #4511: evar tactic can create non-typed evars.
+- #4503: mixing universe polymorphic and monomorphic variables and definitions in sections is unsupported.
+- #4519: oops, global shadowed local universe level bindings.
+- #4506: Anomaly: File "pretyping/indrec.ml", line 169, characters 14-20: Assertion failed.
+- #4548: Coqide crashes when going back one command
+
+Changes from V8.5beta3 to V8.5
+==============================
+
+Tools
+
+- Flag "-compat 8.4" now loads Coq.Compat.Coq84. The standard way of
+ putting Coq in v8.4 compatibility mode is to pass the command line flag
+ "-compat 8.4". It can be followed by "-require Coq.Compat.AdmitAxiom"
+ if the 8.4 behavior of admit is needed, in which case it uses an axiom.
+
+Specification language
+
+- Syntax "$(tactic)$" changed to "ltac:(tactic)".
+
+Tactics
+
+- Syntax "destruct !hyp" changed to "destruct (hyp)", and similarly
+ for induction (rare source of incompatibilities easily solvable by
+ removing parentheses around "hyp" when not for the purpose of keeping
+ the hypothesis).
+- Syntax "p/c" for on-the-fly application of a lemma c before
+ introducing along pattern p changed to p%c1..%cn. The feature and
+ syntax are in experimental stage.
+- "Proof using" does not clear unused section variables.
+- Tactic "refine" has been changed back to the 8.4 behavior of shelving subgoals
+ that occur in other subgoals. The "refine" tactic of 8.5beta3 has been
+ renamed "simple refine"; it does not shelve any subgoal.
+- New tactical "unshelve tac" which grab existential variables put on
+ the tactic shelve by the execution of "tac".
+
+Changes from V8.5beta2 to V8.5beta3
+===================================
+
+Vernacular commands
+
+- New command "Redirect" to redirect the output of a command to a file.
+- New command "Undelimit Scope" to remove the delimiter of a scope.
+- New option "Strict Universe Declaration", set by default. It enforces the
+ declaration of all polymorphic universes appearing in a definition when
+ introducing it.
+- New command "Show id" to show goal named id.
+- Option "Virtual Machine" removed.
+
+Tactics
+
+- New flag "Regular Subst Tactic" which fixes "subst" in situations where
+ it failed to substitute all substitutable equations or failed to simplify
+ cycles, or accidentally unfolded local definitions (flag is off by default).
+- New flag "Loose Hint Behavior" to handle hints loaded but not imported in a
+ special way. It accepts three distinct flags:
+ * "Lax", which is the default one, sets the old behavior, i.e. a non-imported
+ hint behaves the same as an imported one.
+ * "Warn" outputs a warning when a non-imported hint is used. Note that this is
+ an over-approximation, because a hint may be triggered by an eauto run that
+ will eventually fail and backtrack.
+ * "Strict" changes the behavior of an unloaded hint to the one of the fail
+ tactic, allowing to emulate the hopefully future import-scoped hint mechanism.
+- New compatibility flag "Universal Lemma Under Conjunction" which
+ let tactics working under conjunctions apply sublemmas of the form
+ "forall A, ... -> A".
+- New compatibility flag "Bracketing Last Introduction Pattern" which can be
+ set so that the last disjunctive-conjunctive introduction pattern given to
+ "intros" automatically complete the introduction of its subcomponents, as the
+ the disjunctive-conjunctive introduction patterns in non-terminal position
+ already do.
+- New flag "Shrink Abstract" that minimalizes proofs generated by the abstract
+ tactical w.r.t. variables appearing in the body of the proof.
+
+Program
+
+- The "Shrink Obligations" flag now applies to all obligations, not only those
+solved by the automatic tactic.
+- Importing Program no longer overrides the "exists" tactic (potential source
+ of incompatibilities).
+- Hints costs are now correctly taken into account (potential source of
+ incompatibilities).
+- Documented the Hint Cut command that allows control of the
+ proof-search during typeclass resolution (see reference manual).
+
+API
+
+- Some functions from pretyping/typing.ml and their derivatives were potential
+ source of evarmap leaks, as they dropped their resulting evarmap. The
+ situation was clarified by renaming them according to a unsafe_* scheme. Their
+ sound variant is likewise renamed to their old name. The following renamings
+ were made.
+ * Typing.type_of -> unsafe_type_of
+ * Typing.e_type_of -> type_of
+ * A new e_type_of function that matches the e_ prefix policy
+ * Tacmach.pf_type_of -> pf_unsafe_type_of
+ * A new safe pf_type_of function.
+ All uses of unsafe_* functions should be eventually eliminated.
+
+Tools
+
+- Added an option -w to control the output of coqtop warnings.
+- Configure now takes an optional -native-compiler (yes|no) flag replacing
+ -no-native-compiler. The new flag is set to no by default under Windows.
+- Flag -no-native-compiler was removed and became the default for coqc. If
+ precompilation of files for native conversion test is desired, use
+ -native-compiler.
+- The -compile command-line option now takes the full path of the considered
+ file, including the ".v" extension, and outputs a warning if such an extension
+ is lacking.
+- The -require and -load-vernac-object command-line options now take a logical
+ path of a given library rather than a physical path, thus they behave like
+ Require [Import] path.
+- The -vm command-line option has been removed.
+
+Standard Library
+
+ - There is now a Coq.Compat.Coq84 library, which sets the various compatibility
+ options and does a few redefinitions to make Coq behave more like Coq v8.4.
+ The standard way of putting Coq in v8.4 compatibility mode is to pass the command
+ line flags "-require Coq.Compat.Coq84 -compat 8.4".
+
+Changes from V8.5beta1 to V8.5beta2
+===================================
+
+Logic
+
+- The VM now supports inductive types with up to 8388851 non-constant
+ constructors and up to 8388607 constant ones.
+
+Specification language
+
+- Syntax "$(tactic)$" changed to "ltac: tactic".
+
+Tactics
+
+- A script using the admit tactic can no longer be concluded by either
+ Qed or Defined. In the first case, Admitted can be used instead. In
+ the second case, a subproof should be used.
+- The easy tactic and the now tactical now have a more predictable
+ behavior, but they might now discharge some previously unsolved goals.
+
+Extraction
+
+- Definitions extracted to Haskell GHC should no longer randomly
+ segfault when some Coq types cannot be represented by Haskell types.
+- Definitions can now be extracted to Json for post-processing.
+
+Tools
+
+- Option -I -as has been removed, and option -R -as has been
+ deprecated. In both cases, option -R can be used instead.
+- coq_makefile now generates double-colon rules for rules such as clean.
+
+API
+
+- The interface of [change] has changed to take a [change_arg], which
+ can be built from a [constr] using [make_change_arg].
+
+Changes from V8.4 to V8.5beta1
+==============================
+
+Logic
+
+- Primitive projections for records allow for a compact representation
+ of projections, without parameters and avoid the behavior of defined
+ projections that can unfold to a case expression. To turn the use of
+ native projections on, use [Set Primitive Projections]. Record,
+ Class and Structure types defined while this option is set will be
+ defined with primitive projections instead of the usual encoding as
+ a case expression. For compatibility, when p is a primitive
+ projection, @p can be used to refer to the projection with explicit
+ parameters, i.e. [@p] is definitionally equal to [λ params r. r.(p)].
+ Records with primitive projections have eta-conversion, the
+ canonical form being [mkR pars (p1 t) ... (pn t)].
+- New universe polymorphism (see reference manual)
+- New option -type-in-type to collapse the universe hierarchy (this makes the
+ logic inconsistent).
+- The guard condition for fixpoints is now a bit stricter. Propagation
+ of subterm value through pattern matching is restricted according to
+ the return predicate. Restores compatibility of Coq's logic with the
+ propositional extensionality axiom. May create incompatibilities in
+ recursive programs heavily using dependent types.
+- Trivial inductive types are no longer defined in Type but in Prop, which
+ leads to a non-dependent induction principle being generated in place of
+ the dependent one. To recover the old behavior, explicitly define your
+ inductive types in Set.
+
+Vernacular commands
+
+- A command "Variant" allows to define non-recursive variant types.
+- The command "Record foo ..." does not generate induction principles
+ (foo_rect, foo_rec, foo_ind) anymore by default (feature wish
+ #2693). The command "Variant foo ..." does not either. A flag
+ "Set/Unset Nonrecursive Elimination Schemes" allows changing this.
+ The tactic "induction" on a "Record" or a "Variant" is now actually
+ doing "destruct".
+- The "Open Scope" command can now be given also a delimiter (e.g. Z).
+- The "Definition" command now allows the "Local" modifier, allowing
+ for non-importable definitions. The same goes for "Axiom" and "Parameter".
+- Section-specific commands such as "Let" (resp. "Variable", "Hypothesis") used
+ out of a section now behave like the corresponding "Local" command, i.e.
+ "Local Definition" (resp. "Local Parameter", "Local Axiom"). (potential source
+ of rare incompatibilities).
+- The "Let" command can now define local (co)fixpoints.
+- Command "Search" has been renamed into "SearchHead". The command
+ name "Search" now behaves like former "SearchAbout". The latter name
+ is deprecated.
+- "Search", "About", "SearchHead", "SearchRewrite" and "SearchPattern"
+ now search for hypothesis (of the current goal by default) first.
+ They now also support the goal selector prefix to specify another
+ goal to search: e.g. "n:Search id". This is also true for
+ SearchAbout although it is deprecated.
+- The coq/user-contrib directory and the XDG directories are no longer
+ recursively added to the load path, so files from installed libraries
+ now need to be fully qualified for the "Require" command to find them.
+ The tools/update-require script can be used to convert a development.
+- A new Print Strategies command allows visualizing the opacity status
+ of the whole engine.
+- The "Locate" command now searches through all sorts of qualified namespaces of
+ Coq: terms, modules, tactics, etc. The old behavior of the command can be
+ retrieved using the "Locate Term" command.
+- New "Derive" command to help writing program by derivation.
+- New "Refine Instance Mode" option that allows to deactivate the generation of
+ obligations in incomplete typeclass instances, raising an error instead.
+- "Collection" command to name sets of section hypotheses. Named collections
+ can be used in the syntax of "Proof using" to assert which section variables
+ are used in a proof.
+- The "Optimize Proof" command can be placed in the middle of a proof to
+ force the compaction of the data structure used to represent the ongoing
+ proof (evar map). This may result in a lower memory footprint and speed up
+ the execution of the following tactics.
+- "Optimize Heap" command to tell the OCaml runtime to perform a major
+ garbage collection step and heap compaction.
+- "Instance" no longer treats the {|...|} syntax specially; it handles it
+ in the same way as other commands, e.g. "Definition". Use the {...}
+ syntax (no pipe symbols) to recover the old behavior.
+
+Specification Language
+
+- Slight changes in unification error messages.
+- Added a syntax $(...)$ that allows putting tactics in terms (may
+ break user notations using "$(", fixable by inserting a space or
+ rewriting the notation).
+- Constructors in pattern-matching patterns now respect the same rules
+ regarding implicit arguments as in applicative position. The old
+ behavior can be recovered by the command "Set Asymmetric
+ Patterns". As a side effect, notations for constructors explicitly
+ mentioning non-implicit parameters can now be used in patterns.
+ Considering that the pattern language is already rich enough, binding
+ local definitions is however now forbidden in patterns (source of
+ incompatibilities for local definitions that delta-reduce to a constructor).
+- Type inference algorithm now granting opacity of constants. This might also
+ affect behavior of tactics (source of incompatibilities, solvable by
+ re-declaring transparent constants which were set opaque).
+- Existential variables are now referred to by an identifier and the
+ relevant part of their instance is displayed by default. They can be
+ reparsed. The naming policy is yet unstable and subject to changes
+ in future releases.
+
+Tactics
+
+- New tactic engine allowing dependent subgoals, fully backtracking
+ (also known as multiple success) tactics, as well as tactics which
+ can consider multiple goals together. In the new tactic engine,
+ instantiation information of existential variables is always
+ propagated to tactics, removing the need to manually use the
+ "instantiate" tactics to mark propagation points.
+ * New tactical (a+b) inserts a backtracking point. When (a+b);c fails
+ during the execution of c, it can backtrack and try b instead of a.
+ * New tactical (once a) removes all the backtracking points from a
+ (i.e. it selects the first success of a).
+ * Tactic "constructor" is now fully backtracking. In case of
+ incompatibilities (e.g. combinatoric explosion), the former
+ behavior of "constructor" can be retrieved by using instead
+ "[> once constructor ..]". Thanks to backtracking, undocumented
+ "constructor " syntax is now equivalent to
+ "[> once (constructor; tac) ..]".
+ * New "multimatch" variant of "match" tactic which backtracks to
+ new branches in case of a later failure. The "match" tactic is
+ equivalent to "once multimatch".
+ * New selector "all:" such that "all:tac" applies tactic "tac" to
+ all the focused goals, instead of just the first one as is the
+ default.
+ * A corresponding new option Set Default Goal Selector "all" makes
+ the tactics in scripts be applied to all the focused goal by default
+ * New selector "par:" such that "par:tac" applies the (terminating)
+ tactic "tac" to all the focused goal in parallel. The number of worker
+ can be selected with -async-proofs-tac-j and also limited using the
+ coqworkmgr utility.
+ * New tactics "revgoals", "cycle" and "swap" to reorder goals.
+ * The semantics of recursive tactics (introduced with "Ltac t := ..."
+ or "let rec t := ... in ...") changed slightly as t is now
+ applied to every goal, not each goal independently. In particular
+ it may be applied when no goals are left. This may cause tactics
+ such as "let rec t := constructor;t" to loop indefinitely. The
+ simple fix is to rewrite the recursive calls as follows:
+ "let rec t := constructor;[t..]" which recovers the earlier behavior
+ (source of rare incompatibilities).
+ * New tactic language feature "numgoals" to count number of goals. It is
+ accompanied by a "guard" tactic which fails if a Boolean test over
+ integers does not pass.
+ * New tactical "[> ... ]" to apply tactics to individual goals.
+ * New tactic "gfail" which works like "fail" except it will also
+ fail if every goal has been solved.
+ * The refine tactic is changed not to use an ad hoc typing algorithm
+ to generate subgoals. It also uses the dependent subgoal feature
+ to generate goals to materialize every existential variable which
+ is introduced by the refinement (source of incompatibilities).
+ * A tactic shelve is introduced to manage the subgoals which may be
+ solved by unification: shelve removes every goal it is applied to
+ from focus. These goals can later be called back into focus by the
+ Unshelve command.
+ * A variant shelve_unifiable only removes those goals which appear
+ as existential variables in other goals. To emulate the old
+ refine, use "refine c;shelve_unifiable". This can still cause
+ incompatibilities in rare occasions.
+ * New "give_up" tactic to skip over a goal. A proof containing
+ given up goals cannot be closed with "Qed", but only with "Admitted".
+- The implementation of the admit tactic has changed: no axiom is
+ generated for the admitted sub proof. "admit" is now an alias for
+ "give_up". Code relying on this specific behavior of "admit"
+ can be made to work by:
+ * Adding an "Axiom" for each admitted subproof.
+ * Adding a single "Axiom proof_admitted : False." and the Ltac definition
+ "Ltac admit := case proof_admitted.".
+- Matching using "lazymatch" was fundamentally modified. It now behaves
+ like "match" (immediate execution of the matching branch) but without
+ the backtracking mechanism in case of failure.
+- New "tryif t then u else v" tactical which executes "u" in case of success
+ of "t" and "v" in case of failure.
+- New conversion tactic "native_compute": evaluates the goal (or an hypothesis)
+ with a call-by-value strategy, using the OCaml native compiler. Useful on
+ very intensive computations.
+- New "cbn" tactic, a well-behaved simpl.
+- Repeated identical calls to omega should now produce identical proof terms.
+- Tactics btauto, a reflexive Boolean tautology solver.
+- Tactic "tauto" was exceptionally able to destruct other connectives
+ than the binary connectives "and", "or", "prod", "sum", "iff". This
+ non-uniform behavior has been fixed (bug #2680) and tauto is
+ slightly weaker (possible source of incompatibilities). On the
+ opposite side, new tactic "dtauto" is able to destruct any
+ record-like inductive types, superseding the old version of "tauto".
+- Similarly, "intuition" has been made more uniform and, where it now
+ fails, "dintuition" can be used (possible source of incompatibilities).
+- New option "Unset Intuition Negation Unfolding" for deactivating automatic
+ unfolding of "not" in intuition.
+- Tactic notations can now be defined locally to a module (use "Local" prefix).
+- Tactic "red" now reduces head beta-iota redexes (potential source of
+ rare incompatibilities).
+- Tactic "hnf" now reduces inner beta-iota redexes
+ (potential source of rare incompatibilities).
+- Tactic "intro H" now reduces beta-iota redexes if these hide a product
+ (potential source of rare incompatibilities).
+- In Ltac matching on patterns of the form "_ pat1 ... patn" now
+ behaves like if matching on "?X pat1 ... patn", i.e. accepting "_"
+ to be instantiated by an applicative term (experimental at this
+ stage, potential source of incompatibilities).
+- In Ltac matching on goal, types of hypotheses are now interpreted in
+ the %type scope (possible source of incompatibilities).
+- "change ... in ..." and "simpl ... in ..." now properly consider nested
+ occurrences (possible source of incompatibilities since this alters
+ the numbering of occurrences), but do not support nested occurrences.
+- Tactics simpl, vm_compute and native_compute can be given a notation string
+ to a constant as argument.
+- When given a reference as argument, simpl, vm_compute and
+ native_compute now strictly interpret it as the head of a pattern
+ starting with this reference.
+- The "change p with c" tactic semantics changed, now type-checking
+ "c" at each matching occurrence "t" of the pattern "p", and
+ converting "t" with "c".
+- Now "appcontext" and "context" behave the same. The old buggy behavior of
+ "context" can be retrieved at parse time by setting the
+ "Tactic Compat Context" flag (possible source of incompatibilities).
+- New introduction pattern p/c which applies lemma c on the fly on the
+ hypothesis under consideration before continuing with introduction pattern p.
+- New introduction pattern [= x1 .. xn] applies "injection as [x1 .. xn]"
+ on the fly if injection is applicable to the hypothesis under consideration
+ (idea borrowed from Georges Gonthier). Introduction pattern [=] applies
+ "discriminate" if a discriminable equality.
+- New introduction patterns * and ** to respectively introduce all forthcoming
+ dependent variables and all variables/hypotheses dependent or not.
+- Tactic "injection c as ipats" now clears c if c refers to an
+ hypothesis and moves the resulting equations in the hypotheses
+ independently of the number of ipats, which has itself to be less
+ than the number of new hypotheses (possible source of incompatibilities;
+ former behavior obtainable by "Unset Injection L2R Pattern Order").
+- Tactic "injection" now automatically simplifies subgoals
+ "existT n p = existT n p'" into "p = p'" when "n" is in an inductive type for
+ which a decidable equality scheme has been generated with "Scheme Equality"
+ (possible source of incompatibilities).
+- New tactic "rewrite_strat" for generalized rewriting with user-defined
+ strategies, subsuming autorewrite.
+- Injection can now also deduce equality of arguments of sort Prop, by using
+ the option "Set Injection On Proofs" (disabled by default). Also improved the
+ error messages.
+- Tactic "subst id" now supports id occurring in dependent local definitions.
+- Bugs fixed about intro-pattern "*" might lead to some rare incompatibilities.
+- New tactical "time" to display time spent executing its argument.
+- Tactics referring or using a constant dependent in a section variable which
+ has been cleared or renamed in the current goal context now fail
+ (possible source of incompatibilities solvable by avoiding clearing
+ the relevant hypotheses).
+- New construct "uconstr:c" and "type_term c" to build untyped terms.
+- Binders in terms defined in Ltac (either "constr" or "uconstr") can
+ now take their names from identifiers defined in Ltac. As a
+ consequence, a name cannot be used in a binder "constr:(fun x =>
+ ...)" if an Ltac variable of that name already exists and does not
+ contain an identifier. Source of occasional incompatibilities.
+- The "refine" tactic now accepts untyped terms built with "uconstr"
+ so that terms with holes can be constructed piecewise in Ltac.
+- New bullets --, ++, **, ---, +++, ***, ... made available.
+- More informative messages when wrong bullet is used.
+- Bullet suggestion when a subgoal is solved.
+- New tactic "enough", symmetric to "assert", but with subgoals
+ swapped, as a more friendly replacement of "cut".
+- In destruct/induction, experimental modifier "!" prefixing the
+ hypothesis name to tell not erasing the hypothesis.
+- Bug fixes in "inversion as" may occasionally lead to incompatibilities.
+- Behavior of introduction patterns -> and <- made more uniform
+ (hypothesis is cleared, rewrite in hypotheses and conclusion and
+ erasing the variable when rewriting a variable).
+- New experimental option "Set Standard Proposition Elimination Names"
+ so that case analysis or induction on schemes in Type containing
+ propositions now produces "H"-based names.
+- Tactics from plugins are now active only when the corresponding module
+ is imported (source of incompatibilities, solvable by adding an "Import";
+ in the particular case of Omega, use "Require Import OmegaTactic").
+- Semantics of destruct/induction has been made more regular in some
+ edge cases, possibly leading to incompatibilities:
+ - new goals are now opened when the term does not match a subterm of
+ the goal and has unresolved holes, while in 8.4 these holes were
+ turned into existential variables
+ - when no "at" option is given, the historical semantics which
+ selects all subterms syntactically identical to the first subterm
+ matching the given pattern is used
+ - non-dependent destruct/induction on an hypothesis with premises in
+ an inductive type with indices is fixed
+ - residual local definitions are now correctly removed.
+- The rename tactic may now replace variables in parallel.
+- A new "Info" command replaces the "info" tactical discontinued in
+ v8.4. It still gives informative results in many cases.
+- The "info_auto" tactic is known to be broken and does not print a
+ trace anymore. Use "Info 1 auto" instead. The same goes for
+ "info_trivial". On the other hand "info_eauto" still works fine,
+ while "Info 1 eauto" prints a trivial trace.
+- When using a lemma of the prototypical form "forall A, {a:A & P a}",
+ "apply" and "apply in" do not instantiate anymore "A" with the
+ current goal and use "a" as the proof, as they were sometimes doing,
+ now considering that it is a too powerful decision.
+
+Program
+
+- "Solve Obligations using" changed to "Solve Obligations with",
+ consistent with "Proof with".
+- Program Lemma, Definition now respect automatic introduction.
+- Program Lemma, Definition, etc.. now interpret "->" like Lemma and
+ Definition as a non-dependent arrow (potential source of
+ incompatibility).
+- Add/document "Set Hide Obligations" (to hide obligations in the final
+ term inside an implicit argument) and "Set Shrink Obligations" (to
+ minimize dependencies of obligations defined by tactics).
+
+Notations
+
+- The syntax "x -> y" is now declared at level 99. In particular, it has
+ now a lower priority than "<->": "A -> B <-> C" is now "A -> (B <-> C)"
+ (possible source of incompatibilities)
+- Notations accept term-providing tactics using the $(...)$ syntax.
+- "Bind Scope" can no longer bind "Funclass" and "Sortclass".
+- A notation can be given a (compat "8.x") annotation, making it behave
+ like a "only parsing" notation, but the annotation may lead to eventually
+ issue warnings or errors in further versions when this notation is used.
+- More systematic insertion of spaces as a default for printing
+ notations ("format" still available to override the default).
+- In notations, a level modifier referring to a non-existent variable is
+ now considered an error rather than silently ignored.
+
+Tools
+
+- Option -I now only adds directories to the ml path.
+- Option -Q behaves as -R, except that the logical path of any loaded file has
+ to be fully qualified.
+- Option -R no longer adds recursively to the ml path; only the root
+ directory is added. (Behavior with respect to the load path is
+ unchanged.)
+- Option -nois prevents coq/theories and coq/plugins to be recursively
+ added to the load path. (Same behavior as with coq/user-contrib.)
+- coqdep accepts a -dumpgraph option generating a dot file.
+- Makefiles generated through coq_makefile have three new targets "quick"
+ "checkproofs" and "vio2vo", allowing respectively to asynchronously compile
+ the files without playing the proof scripts, asynchronously checking
+ that the quickly generated proofs are correct and generating the object
+ files from the quickly generated proofs.
+- The XML plugin was discontinued and removed from the source.
+- A new utility called coqworkmgr can be used to limit the number of
+ concurrent workers started by independent processes, like make and CoqIDE.
+ This is of interest for users of the par: goal selector.
+
+Interfaces
+
+- CoqIDE supports asynchronous edition of the document, ongoing tasks and
+ errors are reported in the bottom right window. The number of workers
+ taking care of processing proofs can be selected with -async-proofs-j.
+- CoqIDE highlights in yellow "unsafe" commands such as axiom
+ declarations, and tactics like "give_up".
+- CoqIDE supports Proof General like key bindings;
+ to activate the PG mode go to Edit -> Preferences -> Editor.
+ For the documentation see Help -> Help for PG mode.
+- CoqIDE automatically retracts the locked area when one edits the
+ locked text.
+- CoqIDE search and replace got regular expressions power. See the
+ documentation of OCaml's Str module for the supported syntax.
+- Many CoqIDE windows, including the query one, are now detachable to
+ improve usability on multi screen work stations.
+- Coqtop/coqc outputs highlighted syntax. Colors can be configured thanks
+ to the COQ_COLORS environment variable, and their current state can
+ be displayed with the -list-tags command line option.
+- Third party user interfaces can install their main loop in $COQLIB/toploop
+ and call coqtop with the -toploop flag to select it.
+
+Internal Infrastructure
+
+- Many reorganizations in the ocaml source files. For instance,
+ many internal a.s.t. of Coq are now placed in mli files in
+ a new directory intf/, for instance constrexpr.mli or glob_term.mli.
+ More details in dev/doc/changes.
+- The file states/initial.coq does not exist anymore. Instead, coqtop
+ initially does a "Require" of Prelude.vo (or nothing when given
+ the options -noinit or -nois).
+- The format of vo files has slightly changed: cf final comments in
+ checker/cic.mli.
+- The build system does not produce anymore programs named coqtop.opt
+ and a symbolic link to coqtop. Instead, coqtop is now directly
+ an executable compiled with the best OCaml compiler available.
+ The bytecode program coqtop.byte is still produced. Same for other
+ utilities.
+- Some options of the ./configure script slightly changed:
+ * The -coqrunbyteflags and its blank-separated argument is replaced
+ by option -vmbyteflags which expects a comma-separated argument.
+ * The -coqtoolsbyteflags option is discontinued, see -no-custom instead.
+
+Miscellaneous
+
+- ML plugins now require a "DECLARE PLUGIN \"foo\"" statement. The "foo" name
+ must be exactly the name of the ML module that will be loaded through a
+ "Declare ML \"foo\"" command.
+
+Changes from V8.4beta2 to V8.4
+==============================
+
+Vernacular commands
+
+- The "Reset" command is now supported again in files given to coqc or Load.
+- "Show Script" now indents again the displayed scripts. It can also work
+ correctly across Load'ed files if the option "Unset Atomic Load" is used.
+- "Open Scope" can now be given the delimiter (e.g. Z) instead of the full
+ scope name (e.g. Z_scope).
+
+Notations
+
+- Most compatibility notations of the standard library are now tagged as
+ (compat xyz), where xyz is a former Coq version, for instance "8.3".
+ These notations behave as (only parsing) notations, except that they may
+ triggers warnings (or errors) when used while Coq is not in a corresponding
+ -compat mode.
+- To activate these compatibility warnings, use "Set Verbose Compat Notations"
+ or the command-line flag -verbose-compat-notations.
+- For a strict mode without these compatibility notations, use
+ "Unset Compat Notations" or the command-line flag -no-compat-notations.
+
+Tactics
+
+- An annotation "eqn:H" or "eqn:?" can be added to a "destruct"
+ or "induction" to make it generate equations in the spirit of "case_eq".
+ The former syntax "_eqn" is discontinued.
+- The name of the hypothesis introduced by tactic "remember" can be
+ set via the new syntax "remember t as x eqn:H" (wish #2489).
+
+Libraries
+
+- Reals: changed definition of PI, no more axiom about sin(PI/2).
+- SetoidPermutation: a notion of permutation for lists modulo a setoid equality.
+- BigN: fixed the ocaml code doing the parsing/printing of big numbers.
+- List: a couple of lemmas added especially about no-duplication, partitions.
+- Init: Removal of the coercions between variants of sigma-types and
+ subset types (possible source of incompatibility).
+
+Changes from V8.4beta to V8.4beta2
+==================================
+
+Vernacular commands
+
+- Commands "Back" and "BackTo" are now handling the proof states. They may
+ perform some extra steps of backtrack to avoid states where the proof
+ state is unavailable (typically a closed proof).
+- The commands "Suspend" and "Resume" have been removed.
+- A basic Show Script has been reintroduced (no indentation).
+- New command "Set Parsing Explicit" for deactivating parsing (and printing)
+ of implicit arguments (useful for teaching).
+- New command "Grab Existential Variables" to transform the unresolved evars
+ at the end of a proof into goals.
+
+Tactics
+
+- Still no general "info" tactical, but new specific tactics info_auto,
+ info_eauto, info_trivial which provides information on the proofs found
+ by auto/eauto/trivial. Display of these details could also be activated by
+ "Set Info Auto"/"Set Info Eauto"/"Set Info Trivial".
+- Details on everything tried by auto/eauto/trivial during a proof search
+ could be obtained by "debug auto", "debug eauto", "debug trivial" or by a
+ global "Set Debug Auto"/"Set Debug Eauto"/"Set Debug Trivial".
+- New command "r string" in Ltac debugger that interprets "idtac
+ string" in Ltac code as a breakpoint and jumps to its next use.
+- Tactics from the Dp plugin (simplify, ergo, yices, cvc3, z3, cvcl,
+ harvey, zenon, gwhy) have been removed, since Why2 has not been
+ maintained for the last few years. The Why3 plugin should be a suitable
+ replacement in most cases.
+
+Libraries
+
+- MSetRBT: a new implementation of MSets via Red-Black trees (initial
+ contribution by Andrew Appel).
+- MSetAVL: for maximal sharing with the new MSetRBT, the argument order
+ of Node has changed (this should be transparent to regular MSets users).
+
+Module System
+
+- The names of modules (and module types) are now in a fully separated
+ namespace from ordinary definitions: "Definition E:=0. Module E. End E."
+ is now accepted.
+
+CoqIDE
+
+- Coqide now supports the "Restart" command, and "Undo" (with a warning).
+ Better support for "Abort".
+
+Changes from V8.3 to V8.4beta
+=============================
+
+Logic
+
+- Standard eta-conversion now supported (dependent product only).
+- Guard condition improvement: subterm property is propagated through beta-redex
+ blocked by pattern-matching, as in "(match v with C .. => fun x => u end) x";
+ this allows for instance to use "rewrite ... in ..." without breaking
+ the guard condition.
+
+Specification language and notations
+
+- Maximal implicit arguments can now be set locally by { }. The registration
+ traverses fixpoints and lambdas. Because there is conversion in types,
+ maximal implicit arguments are not taken into account in partial
+ applications (use eta expanded form with explicit { } instead).
+- Added support for recursive notations with binders (allows for instance
+ to write "exists x y z, P").
+- Structure/Record printing can be disable by "Unset Printing Records".
+ In addition, it can be controlled on type by type basis using
+ "Add Printing Record" or "Add Printing Constructor".
+- Pattern-matching compilation algorithm: in "match x, y with ... end",
+ possible dependencies of x (or of the indices of its type) in the type
+ of y are now taken into account.
+
+Tactics
+
+- New proof engine.
+- Scripts can now be structured thanks to bullets - * + and to subgoal
+ delimitation via { }. Note: for use with Proof General, a cvs version of
+ Proof General no older than mid-July 2011 is currently required.
+- Support for tactical "info" is suspended.
+- Support for command "Show Script" is suspended.
+- New tactics constr_eq, is_evar and has_evar for use in Ltac (DOC TODO).
+- Removed the two-argument variant of "decide equality".
+- New experimental tactical "timeout ". Since is a time
+ in second for the moment, this feature should rather be avoided
+ in scripts meant to be machine-independent.
+- Fix in "destruct": removal of unexpected local definitions in context might
+ result in some rare incompatibilities (solvable by adapting name hypotheses).
+- Introduction pattern "_" made more robust.
+- Tactic (and Eval command) vm_compute can now be interrupted via Ctrl-C.
+- Unification in "apply" supports unification of patterns of the form
+ ?f x y = g(x,y) (compatibility ensured by using
+ "Unset Tactic Pattern Unification"). It also supports (full) betaiota.
+- Tactic autorewrite does no longer instantiate pre-existing
+ existential variables (theoretical source of possible incompatibilities).
+- Tactic "dependent rewrite" now supports equality in "sig".
+- Tactic omega now understands Zpred (wish #1912) and can prove any goal
+ from a context containing an arithmetical contradiction (wish #2236).
+- Using "auto with nocore" disables the use of the "core" database (wish #2188).
+ This pseudo-database "nocore" can also be used with trivial and eauto.
+- Tactics "set", "destruct" and "induction" accepts incomplete terms and
+ use the goal to complete the pattern assuming it is non ambiguous.
+- When used on arguments with a dependent type, tactics such as
+ "destruct", "induction", "case", "elim", etc. now try to abstract
+ automatically the dependencies over the arguments of the types
+ (based on initial ideas from Chung-Kil Hur, extension to nested
+ dependencies suggested by Dan Grayson)
+- Tactic "injection" now failing on an equality showing no constructors while
+ it was formerly generalizing again the goal over the given equality.
+- In Ltac, the "context [...]" syntax has now a variant "appcontext [...]"
+ allowing to match partial applications in larger applications.
+- When applying destruct or inversion on a fixpoint hiding an inductive
+ type, recursive calls to the fixpoint now remain folded by default (rare
+ source of incompatibility generally solvable by adding a call to simpl).
+- In an ltac pattern containing a "match", a final "| _ => _" branch could be
+ used now instead of enumerating all remaining constructors. Moreover, the
+ pattern "match _ with _ => _ end" now allows to match any "match". A "in"
+ annotation can also be added to restrict to a precise inductive type.
+- The behavior of "simpl" can be tuned using the "Arguments" vernacular.
+ In particular constants can be marked so that they are always/never unfolded
+ by "simpl", or unfolded only when a set of arguments evaluates to a
+ constructor. Last one can mark a constant so that it is unfolded only if the
+ simplified term does not expose a match in head position.
+
+Vernacular commands
+
+- It is now mandatory to have a space (or tabulation or newline or end-of-file)
+ after a "." ending a sentence.
+- In SearchAbout, the [ ] delimiters are now optional.
+- New command "Add/Remove Search Blacklist ...":
+ a Search or SearchAbout or similar query will never mention lemmas
+ whose qualified names contain any of the declared substrings.
+ The default blacklisted substrings are "_subproof" "Private_".
+- When the output file of "Print Universes" ends in ".dot" or ".gv",
+ the universe graph is printed in the DOT language, and can be
+ processed by Graphviz tools.
+- New command "Print Sorted Universes".
+- The undocumented and obsolete option "Set/Unset Boxed Definitions" has
+ been removed, as well as syntaxes like "Boxed Fixpoint foo".
+- A new option "Set Default Timeout n / Unset Default Timeout".
+- Qed now uses information from the reduction tactics used in proof script
+ to avoid conversion at Qed time to go into a very long computation.
+- New command "Show Goal ident" to display the statement of a goal, even
+ a closed one (available from Proof General).
+- Command "Proof" accept a new modifier "using" to force generalization
+ over a given list of section variables at section ending (DOC TODO).
+- New command "Arguments" generalizing "Implicit Arguments" and
+ "Arguments Scope" and that also allows to rename the parameters of a
+ definition and to tune the behavior of the tactic "simpl".
+
+Module System
+
+- During subtyping checks, an opaque constant in a module type could now
+ be implemented by anything of the right type, even if bodies differ.
+ Said otherwise, with respect to subtyping, an opaque constant behaves
+ just as a parameter. Coqchk was already implementing this, but not coqtop.
+- The inlining done during application of functors can now be controlled
+ more precisely, by the annotations (no inline) or (inline at level XX).
+ With the latter annotation, only functor parameters whose levels
+ are lower or equal than XX will be inlined.
+ The level of a parameter can be fixed by "Parameter Inline(30) foo".
+ When levels aren't given, the default value is 100. One can also use
+ the flag "Set Inline Level ..." to set a level (DOC TODO).
+- Print Assumptions should now handle correctly opaque modules (#2168).
+- Print Module (Type) now tries to print more details, such as types and
+ bodies of the module elements. Note that Print Module Type could be
+ used on a module to display only its interface. The option
+ "Set Short Module Printing" could be used to switch back to the earlier
+ behavior were only field names were displayed.
+
+Libraries
+
+- Extension of the abstract part of Numbers, which now provide axiomatizations
+ and results about many more integer functions, such as pow, gcd, lcm, sqrt,
+ log2 and bitwise functions. These functions are implemented for nat, N, BigN,
+ Z, BigZ. See in particular file NPeano for new functions about nat.
+- The definition of types positive, N, Z is now in file BinNums.v
+- Major reorganization of ZArith. The initial file ZArith/BinInt.v now contains
+ an internal module Z implementing the Numbers interface for integers.
+ This module Z regroups:
+ * all functions over type Z : Z.add, Z.mul, ...
+ * the minimal proofs of specifications for these functions : Z.add_0_l, ...
+ * an instantation of all derived properties proved generically in Numbers :
+ Z.add_comm, Z.add_assoc, ...
+ A large part of ZArith is now simply compatibility notations, for instance
+ Zplus_comm is an alias for Z.add_comm. The direct use of module Z is now
+ recommended instead of relying on these compatibility notations.
+- Similar major reorganization of NArith, via a module N in NArith/BinNat.v
+- Concerning the positive datatype, BinPos.v is now in a specific directory
+ PArith, and contains an internal submodule Pos. We regroup there functions
+ such as Pos.add Pos.mul etc as well as many results about them. These results
+ are here proved directly (no Number interface for strictly positive numbers).
+- Note that in spite of the compatibility layers, all these reorganizations
+ may induce some marginal incompatibilies in scripts. In particular:
+ * the "?=" notation for positive now refers to a binary function Pos.compare,
+ instead of the infamous ternary Pcompare (now Pos.compare_cont).
+ * some hypothesis names generated by the system may changed (typically for
+ a "destruct Z_le_gt_dec") since naming is done after the short name of
+ the head predicate (here now "le" in module Z instead of "Zle", etc).
+ * the internals of Z.add has changed, now relying of Z.pos_sub.
+- Also note these new notations:
+ * "" "<=?" "=?" for boolean tests such as Z.ltb Z.leb Z.eqb.
+ * "÷" for the alternative integer division Z.quot implementing the Truncate
+ convention (former ZOdiv), while the notation for the Coq usual division
+ Z.div implementing the Flooring convention remains "/". Their corresponding
+ modulo functions are Z.rem (no notations) for Z.quot and Z.modulo (infix
+ "mod" notation) for Z.div.
+- Lemmas about conversions between these datatypes are also organized
+ in modules, see for instance modules Z2Nat, N2Z, etc.
+- When creating BigN, the macro-generated part NMake_gen is much smaller.
+ The generic part NMake has been reworked and improved. Some changes
+ may introduce incompatibilities. In particular, the order of the arguments
+ for BigN.shiftl and BigN.shiftr is now reversed: the number to shift now
+ comes first. By default, the power function now takes two BigN.
+- Creation of Vector, an independent library for lists indexed by their length.
+ Vectors' names overwrite lists' one so you should not "Import" the library.
+ All old names changed: function names follow the ocaml ones and, for example,
+ Vcons becomes Vector.cons. You can get [..;..;..]-style notations by importing
+ Vector.VectorNotations.
+- Removal of TheoryList. Requiring List instead should work most of the time.
+- New syntax "rew Heq in H" and "rew <- Heq in H" for eq_rect and
+ eq_rect_r (available by importing module EqNotations).
+- Wf.iter_nat is now Peano.nat_iter (with an implicit type argument).
+
+Internal infrastructure
+
+- Opaque proofs are now loaded lazily by default. This allows to be almost as
+ fast as -dont-load-proofs, while being safer (no creation of axioms) and
+ avoiding feature restrictions (Print and Print Assumptions work ok).
+- Revised hash-consing code allowing more sharing of memory
+- Experimental support added for camlp4 (the one provided alongside ocaml),
+ simply pass option -usecamlp4 to ./configure. By default camlp5 is used.
+- Revised build system: no more stages in Makefile thanks to some recursive
+ aspect of recent gnu make, use of vo.itarget files containing .v to compile
+ for both make and ocamlbuild, etc.
+- Support of cross-compilation via mingw from unix toward Windows,
+ contact P. Letouzey for more informations.
+- New Makefile rules mli-doc to make html of mli in dev/doc/html and
+ full-stdlib to get a (huge) pdf reflecting the whole standard library.
+
+Extraction
+
+- By default, opaque terms are now truly considered opaque by extraction:
+ instead of accessing their body, they are now considered as axioms.
+ The previous behaviour can be reactivated via the option
+ "Set Extraction AccessOpaque".
+- The pretty-printer for Haskell now produces layout-independent code
+- A new command "Separate Extraction cst1 cst2 ..." that mixes a
+ minimal extracted environment a la "Recursive Extraction" and the
+ production of several files (one per coq source) a la "Extraction Library"
+ (DOC TODO).
+- New option "Set/Unset Extraction KeepSingleton" for preventing the
+ extraction to optimize singleton container types (DOC TODO).
+- The extraction now identifies and properly rejects a particular case of
+ universe polymorphism it cannot handle yet (the pair (I,I) being Prop).
+- Support of anonymous fields in record (#2555).
+
+CoqIDE
+
+- Coqide now runs coqtop as separated process, making it more robust:
+ coqtop subprocess can be interrupted, or even killed and relaunched
+ (cf button "Restart Coq", ex-"Go to Start"). For allowing such
+ interrupts, the Windows version of coqide now requires Windows >= XP
+ SP1.
+- The communication between CoqIDE and Coqtop is now done via a dialect
+ of XML (DOC TODO).
+- The backtrack engine of CoqIDE has been reworked, it now uses the
+ "Backtrack" command similarly to Proof General.
+- The Coqide parsing of sentences has be reworked and now supports
+ tactic delimitation via { }.
+- Coqide now accepts the Abort command (wish #2357).
+- Coqide can read coq_makefile files as "project file" and use it to
+ set automatically options to send to coqtop.
+- Preference files have moved to $XDG_CONFIG_HOME/coq and accelerators
+ are not stored as a list anymore.
+
+Tools
+
+- Coq now searches directories specified in COQPATH, $XDG_DATA_HOME/coq,
+ $XDG_DATA_DIRS/coq, and user-contribs before the standard library.
+- Coq rc file has moved to $XDG_CONFIG_HOME/coq.
+- Major changes to coq_makefile:
+ * mli/mlpack/mllib taken into account, ml not preproccessed anymore, ml4 work;
+ * mlihtml generates doc of mli, install-doc install the html doc in DOCDIR
+ with the same policy as vo in COQLIB;
+ * More variables are given by coqtop -config, others are defined only if the
+ users doesn't have defined them elsewhere. Consequently, generated makefile
+ should work directly on any architecture;
+ * Packagers can take advantage of $(DSTROOT) introduction. Installation can
+ be made in $XDG_DATA_HOME/coq;
+ * -arg option allows to send option as argument to coqc.
+
+Changes from V8.2 to V8.3
+=========================
+
+Rewriting tactics
+
+- Tactic "rewrite" now supports rewriting on ad hoc equalities such as eq_true.
+- "Hint Rewrite" now checks that the lemma looks like an equation.
+- New tactic "etransitivity".
+- Support for heterogeneous equality (JMeq) in "injection" and "discriminate".
+- Tactic "subst" now supports heterogeneous equality and equality
+ proofs that are dependent (use "simple subst" for preserving compatibility).
+- Added support for Leibniz-rewriting of dependent hypotheses.
+- Renamed "Morphism" into "Proper" and "respect" into "proper_prf"
+ (possible source of incompatibility). A partial fix is to define
+ "Notation Morphism R f := (Proper (R%signature) f)."
+- New tactic variants "rewrite* by" and "autorewrite*" that rewrite
+ respectively the first and all matches whose side-conditions are
+ solved.
+- "Require Import Setoid" does not export all of "Morphisms" and
+ "RelationClasses" anymore (possible source of incompatibility, fixed
+ by importing "Morphisms" too).
+- Support added for using Chung-Kil Hur's Heq library for rewriting over
+ heterogeneous equality (courtesy of the library's author).
+- Tactic "replace" supports matching terms with holes.
+
+Automation tactics
+
+- Tactic "intuition" now preserves inner "iff" and "not" (exceptional
+ source of incompatibilities solvable by redefining "intuition" as
+ "unfold iff, not in *; intuition", or, for iff only, by using
+ "Set Intuition Iff Unfolding".)
+- Tactic "tauto" now proves classical tautologies as soon as classical logic
+ (i.e. library Classical_Prop or Classical) is loaded.
+- Tactic "gappa" has been removed from the Dp plugin.
+- Tactic "firstorder" now supports the combination of its "using" and
+ "with" options.
+- New "Hint Resolve ->" (or "<-") for declaring iff's as oriented
+ hints (wish #2104).
+- An inductive type as argument of the "using" option of "auto/eauto/firstorder"
+ is interpreted as using the collection of its constructors.
+- New decision tactic "nsatz" to prove polynomial equations
+ by computation of Groebner bases.
+
+Other tactics
+
+- Tactic "discriminate" now performs intros before trying to discriminate an
+ hypothesis of the goal (previously it applied intro only if the goal
+ had the form t1<>t2) (exceptional source of incompatibilities - former
+ behavior can be obtained by "Unset Discriminate Introduction").
+- Tactic "quote" now supports quotation of arbitrary terms (not just the
+ goal).
+- Tactic "idtac" now displays its "list" arguments.
+- New introduction patterns "*" for introducing the next block of dependent
+ variables and "**" for introducing all quantified variables and hypotheses.
+- Pattern Unification for existential variables activated in tactics and
+ new option "Unset Tactic Evars Pattern Unification" to deactivate it.
+- Resolution of canonical structure is now part of the tactic's unification
+ algorithm.
+- New tactic "decide lemma with hyp" for rewriting decidability lemmas
+ when one knows which side is true.
+- Improved support of dependent goals over objects in dependent types for
+ "destruct" (rare source of incompatibility that can be avoided by unsetting
+ option "Dependent Propositions Elimination").
+- Tactic "exists", "eexists", "destruct" and "edestruct" supports iteration
+ using comma-separated arguments.
+- Tactic names "case" and "elim" now support clauses "as" and "in" and become
+ then synonymous of "destruct" and "induction" respectively.
+- A new tactic name "exfalso" for the use of 'ex-falso quodlibet' principle.
+ This tactic is simply a shortcut for "elimtype False".
+- Made quantified hypotheses get the name they would have if introduced in
+ the context (possible but rare source of incompatibilities).
+- When applying a component of a conjunctive lemma, "apply in" (and
+ sequences of "apply in") now leave the side conditions of the lemmas
+ uniformly after the main goal (possible source of rare incompatibilities).
+- In "simpl c" and "change c with d", c can be a pattern.
+- Tactic "revert" now preserves let-in's making it the exact inverse of
+ "intro".
+- New tactics "clear dependent H" and "revert dependent H" that
+ clears (resp. reverts) H and all the hypotheses that depend on H.
+- Ltac's pattern-matching now supports matching metavariables that
+ depend on variables bound upwards in the pattern.
+
+Tactic definitions
+
+- Ltac definitions support Local option for non-export outside modules.
+- Support for parsing non-empty lists with separators in tactic notations.
+- New command "Locate Ltac" to get the full name of an Ltac definition.
+
+Notations
+
+- Record syntax "{|x=...; y=...|}" now works inside patterns too.
+- Abbreviations from non-imported module now invisible at printing time.
+- Abbreviations now use implicit arguments and arguments scopes for printing.
+- Abbreviations to pure names now strictly behave like the name they refer to
+ (make redirections of qualified names easier).
+- Abbreviations for applied constant now propagate the implicit arguments
+ and arguments scope of the underlying reference (possible source of
+ incompatibilities generally solvable by changing such abbreviations from
+ e.g. "Notation foo' := (foo x)" to "Notation foo' y := (foo x (y:=y))").
+- The "where" clause now supports multiple notations per defined object.
+- Recursive notations automatically expand one step on the left for better
+ factorization; recursion notations inner separators now ensured being tokens.
+- Added "Reserved Infix" as a specific shortcut of the corresponding
+ "Reserved Notation".
+- Open/Close Scope command supports Global option in sections.
+
+Specification language
+
+- New support for local binders in the syntax of Record/Structure fields.
+- Fixpoint/CoFixpoint now support building part or all of bodies using tactics.
+- Binders given before ":" in lemmas and in definitions built by tactics are
+ now automatically introduced (possible source of incompatibility that can
+ be resolved by invoking "Unset Automatic Introduction").
+- New support for multiple implicit arguments signatures per reference.
+
+Module system
+
+- Include Type is now deprecated since Include now accept both modules and
+ module types.
+- Declare ML Module supports Local option.
+- The sharing between non-logical object and the management of the
+ name-space has been improved by the new "Delta-equivalence" on
+ qualified name.
+- The include operator has been extended to high-order structures
+- Sequences of Include can be abbreviated via new syntax "<+".
+- A module (or module type) can be given several "<:" signatures.
+- Interactive proofs are now permitted in module type. Functors can hence
+ be declared as Module Type and be used later to type themselves.
+- A functor application can be prefixed by a "!" to make it ignore any
+ "Inline" annotation in the type of its argument(s) (for examples of
+ use of the new features, see libraries Structures and Numbers).
+- Coercions are now active only when modules are imported (use "Set Automatic
+ Coercions Import" to get the behavior of the previous versions of Coq).
+
+Extraction
+
+- When using (Recursive) Extraction Library, the filenames are directly the
+ Coq ones with new appropriate extensions : we do not force anymore
+ uncapital first letters for Ocaml and capital ones for Haskell.
+- The extraction now tries harder to avoid code transformations that can be
+ dangerous for the complexity. In particular many eta-expansions at the top
+ of functions body are now avoided, clever partial applications will likely
+ be preserved, let-ins are almost always kept, etc.
+- In the same spirit, auto-inlining is now disabled by default, except for
+ induction principles, since this feature was producing more frequently
+ weird code than clear gain. The previous behavior can be restored via
+ "Set Extraction AutoInline".
+- Unicode characters in identifiers are now transformed into ascii strings
+ that are legal in Ocaml and other languages.
+- Harsh support of module extraction to Haskell and Scheme: module hierarchy
+ is flattened, module abbreviations and functor applications are expanded,
+ module types and unapplied functors are discarded.
+- Less unsupported situations when extracting modules to Ocaml. In particular
+ module parameters might be alpha-renamed if a name clash is detected.
+- Extract Inductive is now possible toward non-inductive types (e.g. nat => int)
+- Extraction Implicit: this new experimental command allows to mark
+ some arguments of a function or constructor for removed during
+ extraction, even if these arguments don't fit the usual elimination
+ principles of extraction, for instance the length n of a vector.
+- Files ExtrOcaml*.v in plugins/extraction try to provide a library of common
+ extraction commands: mapping of basics types toward Ocaml's counterparts,
+ conversions from/to int and big_int, or even complete mapping of nat,Z,N
+ to int or big_int, or mapping of ascii to char and string to char list
+ (in this case recognition of ascii constants is hard-wired in the extraction).
+
+Program
+
+- Streamlined definitions using well-founded recursion and measures so
+ that they can work on any subset of the arguments directly (uses currying).
+- Try to automatically clear structural fixpoint prototypes in
+ obligations to avoid issues with opacity.
+- Use return type clause inference in pattern-matching as in the standard
+ typing algorithm.
+- Support [Local Obligation Tactic] and [Next Obligation with tactic].
+- Use [Show Obligation Tactic] to print the current default tactic.
+- [fst] and [snd] have maximal implicit arguments in Program now (possible
+ source of incompatibility).
+
+Type classes
+
+- Declaring axiomatic type class instances in Module Type should be now
+ done via new command "Declare Instance", while the syntax "Instance"
+ now always provides a concrete instance, both in and out of Module Type.
+- Use [Existing Class foo] to declare foo as a class a posteriori.
+ [foo] can be an inductive type or a constant definition. No
+ projections or instances are defined.
+- Various bug fixes and improvements: support for defined fields,
+ anonymous instances, declarations giving terms, better handling of
+ sections and [Context].
+
+Vernacular commands
+
+- New command "Timeout ." interprets a command and a timeout
+ interrupts the interpretation after seconds.
+- New command "Compute ." is a shortcut for "Eval vm_compute in ".
+- New command "Fail ." interprets a command and is successful iff
+ the command fails on an error (but not an anomaly). Handy for tests and
+ illustration of wrong commands.
+- Most commands referring to constant (e.g. Print or About) now support
+ referring to the constant by a notation string.
+- New option "Boolean Equality Schemes" to make generation of boolean
+ equality automatic for datatypes (together with option "Decidable
+ Equality Schemes", this replaces deprecated option "Equality Scheme").
+- Made support for automatic generation of case analysis schemes available
+ to user (governed by option "Set Case Analysis Schemes").
+- New command "(Global?) Generalizable [All|No] Variable(s)? ident(s)?" to
+ declare which identifiers are generalizable in `{} and `() binders.
+- New command "Print Opaque Dependencies" to display opaque constants in
+ addition to all variables, parameters or axioms a theorem or
+ definition relies on.
+- New command "Declare Reduction := ", allowing to write
+ later "Eval in ...". This command accepts a Local variant.
+- Syntax of Implicit Type now supports more than one block of variables of
+ a given type.
+- Command "Canonical Structure" now warns when it has no effects.
+- Commands of the form "Set X" or "Unset X" now support "Local" and "Global"
+ prefixes.
+
+Library
+
+- Use "standard" Coq names for the properties of eq and identity
+ (e.g. refl_equal is now eq_refl). Support for compatibility is provided.
+- The function Compare_dec.nat_compare is now defined directly,
+ instead of relying on lt_eq_lt_dec. The earlier version is still
+ available under the name nat_compare_alt.
+- Lemmas in library Relations and Reals have been homogenized a bit.
+- The implicit argument of Logic.eq is now maximally inserted, allowing
+ to simply write "eq" instead of "@eq _" in morphism signatures.
+- Wrongly named lemmas (Zlt_gt_succ and Zlt_succ_gt) fixed (potential source
+ of incompatibilities)
+- List library:
+ - Definitions of list, length and app are now in Init/Datatypes.
+ Support for compatibility is provided.
+ - Definition of Permutation is now in Sorting/Permtation.v
+ - Some other light revisions and extensions (possible source
+ of incompatibilities solvable by qualifying names accordingly).
+- In ListSet, set_map has been fixed (source of incompatibilities if used).
+- Sorting library:
+ - new mergesort of worst-case complexity O(n*ln(n)) made available in
+ Mergesort.v;
+ - former notion of permutation up to setoid from Permutation.v is
+ deprecated and moved to PermutSetoid.v;
+ - heapsort from Heap.v of worst-case complexity O(n*n) is deprecated;
+ - new file Sorted.v for some definitions of being sorted.
+- Structure library. This new library is meant to contain generic
+ structures such as types with equalities or orders, either
+ in Module version (for now) or Type Classes (still to do):
+ - DecidableType.v and OrderedType.v: initial notions for FSets/FMaps,
+ left for compatibility but considered as deprecated.
+ - Equalities.v and Orders.v: evolutions of the previous files,
+ with fine-grain Module architecture, many variants, use of
+ Equivalence and other relevant Type Classes notions.
+ - OrdersTac.v: a generic tactic for solving chains of (in)equalities
+ over variables. See {Nat,N,Z,P}OrderedType.v for concrete instances.
+ - GenericMinMax.v: any ordered type can be equipped with min and max.
+ We derived here all the generic properties of these functions.
+- MSets library: an important evolution of the FSets library.
+ "MSets" stands for Modular (Finite) Sets, by contrast with a forthcoming
+ library of Class (Finite) Sets contributed by S. Lescuyer which will be
+ integrated with the next release of Coq. The main features of MSets are:
+ - The use of Equivalence, Proper and other Type Classes features
+ easing the handling of setoid equalities.
+ - The interfaces are now stated in iff-style. Old specifications
+ are now derived properties.
+ - The compare functions are now pure, and return a "comparison" value.
+ Thanks to the CompSpec inductive type, reasoning on them remains easy.
+ - Sets structures requiring invariants (i.e. sorted lists) are
+ built first as "Raw" sets (pure objects and separate proofs) and
+ attached with their proofs thanks to a generic functor. "Raw" sets
+ have now a proper interface and can be manipulated directly.
+ Note: No Maps yet in MSets. The FSets library is still provided
+ for compatibility, but will probably be considered as deprecated in the
+ next release of Coq.
+- Numbers library:
+ - The abstract layer (NatInt, Natural/Abstract, Integer/Abstract) has
+ been simplified and enhance thanks to new features of the module
+ system such as Include (see above). It has been extended to Euclidean
+ division (three flavors for integers: Trunc, Floor and Math).
+ - The arbitrary-large efficient numbers (BigN, BigZ, BigQ) has also
+ been reworked. They benefit from the abstract layer improvements
+ (especially for div and mod). Note that some specifications have
+ slightly changed (compare, div, mod, shift{r,l}). Ring/Field should
+ work better (true recognition of constants).
+
+Tools
+
+- Option -R now supports binding Coq root read-only.
+- New coqtop/coqc option -beautify to reformat .v files (usable
+ e.g. to globally update notations).
+- New tool beautify-archive to beautify a full archive of developments.
+- New coqtop/coqc option -compat X.Y to simulate the general behavior
+ of previous versions of Coq (provides e.g. support for 8.2 compatibility).
+
+Coqdoc
+
+- List have been revamped. List depth and scope is now determined by
+ an "offside" whitespace rule.
+- Text may be italicized by placing it in _underscores_.
+- The "--index " flag changes the filename of the index.
+- The "--toc-depth " flag limits the depth of headers which are
+ included in the table of contents.
+- The "--lib-name " flag prints " Foo" instead of
+ "Library Foo" where library titles are called for. The
+ "--no-lib-name" flag eliminates the extra title.
+- New option "--parse-comments" to allow parsing of regular "(* *)"
+ comments.
+- New option "--plain-comments" to disable interpretation inside comments.
+- New option "--interpolate" to try and typeset identifiers in Coq escapings
+ using the available globalization information.
+- New option "--external url root" to refer to external libraries.
+- Links to section variables and notations now supported.
+
+Internal infrastructure
+
+- To avoid confusion with the repository of user's contributions,
+ the subdirectory "contrib" has been renamed into "plugins".
+ On platforms supporting ocaml native dynlink, code located there
+ is built as loadable plugins for coqtop.
+- An experimental build mechanism via ocamlbuild is provided.
+ From the top of the archive, run ./configure as usual, and
+ then ./build. Feedback about this build mechanism is most welcome.
+ Compiling Coq on platforms such as Windows might be simpler
+ this way, but this remains to be tested.
+- The Makefile system has been simplified and factorized with
+ the ocamlbuild system. In particular "make" takes advantage
+ of .mllib files for building .cma/.cmxa. The .vo files to
+ compile are now listed in several vo.itarget files.
+
+Changes from V8.1 to V8.2
+=========================
+
+Language
+
+- If a fixpoint is not written with an explicit { struct ... }, then
+ all arguments are tried successively (from left to right) until one is
+ found that satisfies the structural decreasing condition.
+- New experimental typeclass system giving ad-hoc polymorphism and
+ overloading based on dependent records and implicit arguments.
+- New syntax "let 'pat := b in c" for let-binding using irrefutable patterns.
+- New syntax "forall {A}, T" for specifying maximally inserted implicit
+ arguments in terms.
+- Sort of Record/Structure, Inductive and CoInductive defaults to Type
+ if omitted.
+- (Co)Inductive types can be defined as records
+ (e.g. "CoInductive stream := { hd : nat; tl : stream }.")
+- New syntax "Theorem id1:t1 ... with idn:tn" for proving mutually dependent
+ statements.
+- Support for sort-polymorphism on constants denoting inductive types.
+- Several evolutions of the module system (handling of module aliases,
+ functorial module types, an Include feature, etc).
+- Prop now a subtype of Set (predicative and impredicative forms).
+- Recursive inductive types in Prop with a single constructor of which
+ all arguments are in Prop is now considered to be a singleton
+ type. It consequently supports all eliminations to Prop, Set and Type.
+ As a consequence, Acc_rect has now a more direct proof [possible source
+ of easily fixed incompatibility in case of manual definition of a recursor
+ in a recursive singleton inductive type].
+
+Vernacular commands
+
+- Added option Global to "Arguments Scope" for section surviving.
+- Added option "Unset Elimination Schemes" to deactivate the automatic
+ generation of elimination schemes.
+- Modification of the Scheme command so you can ask for the name to be
+ automatically computed (e.g. Scheme Induction for nat Sort Set).
+- New command "Combined Scheme" to build combined mutual induction
+ principles from existing mutual induction principles.
+- New command "Scheme Equality" to build a decidable (boolean) equality
+ for simple inductive datatypes and a decision property over this equality
+ (e.g. Scheme Equality for nat).
+- Added option "Set Equality Scheme" to make automatic the declaration
+ of the boolean equality when possible.
+- Source of universe inconsistencies now printed when option
+ "Set Printing Universes" is activated.
+- New option "Set Printing Existential Instances" for making the display of
+ existential variable instances explicit.
+- Support for option "[id1 ... idn]", and "-[id1 ... idn]", for the
+ "compute"/"cbv" reduction strategy, respectively meaning reduce only, or
+ everything but, the constants id1 ... idn. "lazy" alone or followed by
+ "[id1 ... idn]", and "-[id1 ... idn]" also supported, meaning apply
+ all of beta-iota-zeta-delta, possibly restricting delta.
+- New command "Strategy" to control the expansion of constants during
+ conversion tests. It generalizes commands Opaque and Transparent by
+ introducing a range of levels. Lower levels are assigned to constants
+ that should be expanded first.
+- New options Global and Local to Opaque and Transparent.
+- New command "Print Assumptions" to display all variables, parameters
+ or axioms a theorem or definition relies on.
+- "Add Rec LoadPath" now provides references to libraries using partially
+ qualified names (this holds also for coqtop/coqc option -R).
+- SearchAbout supports negated search criteria, reference to logical objects
+ by their notation, and more generally search of subterms.
+- "Declare ML Module" now allows to import .cmxs files when Coq is
+ compiled in native code with a version of OCaml that supports native
+ Dynlink (>= 3.11).
+- Specific sort constraints on Record now taken into account.
+- "Print LoadPath" supports a path argument to filter the display.
+
+Libraries
+
+- Several parts of the libraries are now in Type, in particular FSets,
+ SetoidList, ListSet, Sorting, Zmisc. This may induce a few
+ incompatibilities. In case of trouble while fixing existing development,
+ it may help to simply declare Set as an alias for Type (see file
+ SetIsType).
+- New arithmetical library in theories/Numbers. It contains:
+ * an abstract modular development of natural and integer arithmetics
+ in Numbers/Natural/Abstract and Numbers/Integer/Abstract
+ * an implementation of efficient computational bounded and unbounded
+ integers that can be mapped to processor native arithmetics.
+ See Numbers/Cyclic/Int31 for 31-bit integers and Numbers/Natural/BigN
+ for unbounded natural numbers and Numbers/Integer/BigZ for unbounded
+ integers.
+ * some proofs that both older libraries Arith, ZArith and NArith and
+ newer BigN and BigZ implement the abstract modular development.
+ This allows in particular BigN and BigZ to already come with a
+ large database of basic lemmas and some generic tactics (ring),
+ This library has still an experimental status, as well as the
+ processor-acceleration mechanism, but both its abstract and its
+ concrete parts are already quite usable and could challenge the use
+ of nat, N and Z in actual developments. Moreover, an extension of
+ this framework to rational numbers is ongoing, and an efficient
+ Q structure is already provided (see Numbers/Rational/BigQ), but
+ this part is currently incomplete (no abstract layer and generic
+ lemmas).
+- Many changes in FSets/FMaps. In practice, compatibility with earlier
+ version should be fairly good, but some adaptations may be required.
+ * Interfaces of unordered ("weak") and ordered sets have been factorized
+ thanks to new features of Coq modules (in particular Include), see
+ FSetInterface. Same for maps. Hints in these interfaces have been
+ reworked (they are now placed in a "set" database).
+ * To allow full subtyping between weak and ordered sets, a field
+ "eq_dec" has been added to OrderedType. The old version of OrderedType
+ is now called MiniOrderedType and functor MOT_to_OT allow to
+ convert to the new version. The interfaces and implementations
+ of sets now contain also such a "eq_dec" field.
+ * FSetDecide, contributed by Aaron Bohannon, contains a decision
+ procedure allowing to solve basic set-related goals (for instance,
+ is a point in a particular set ?). See FSetProperties for examples.
+ * Functors of properties have been improved, especially the ones about
+ maps, that now propose some induction principles. Some properties
+ of fold need less hypothesis.
+ * More uniformity in implementations of sets and maps: they all use
+ implicit arguments, and no longer export unnecessary scopes (see
+ bug #1347)
+ * Internal parts of the implementations based on AVL have evolved a
+ lot. The main files FSetAVL and FMapAVL are now much more
+ lightweight now. In particular, minor changes in some functions
+ has allowed to fully separate the proofs of operational
+ correctness from the proofs of well-balancing: well-balancing is
+ critical for efficiency, but not anymore for proving that these
+ trees implement our interfaces, hence we have moved these proofs
+ into appendix files FSetFullAVL and FMapFullAVL. Moreover, a few
+ functions like union and compare have been modified in order to be
+ structural yet efficient. The appendix files also contains
+ alternative versions of these few functions, much closer to the
+ initial Ocaml code and written via the Function framework.
+- Library IntMap, subsumed by FSets/FMaps, has been removed from
+ Coq Standard Library and moved into a user contribution Cachan/IntMap
+- Better computational behavior of some constants (eq_nat_dec and
+ le_lt_dec more efficient, Z_lt_le_dec and Positive_as_OT.compare
+ transparent, ...) (exceptional source of incompatibilities).
+- Boolean operators moved from module Bool to module Datatypes (may need
+ to rename qualified references in script and force notations || and &&
+ to be at levels 50 and 40 respectively).
+- The constructors xI and xO of type positive now have postfix notations
+ "~1" and "~0", allowing to write numbers in binary form easily, for instance
+ 6 is 1~1~0 and 4*p is p~0~0 (see BinPos.v).
+- Improvements to NArith (Nminus, Nmin, Nmax), and to QArith (in particular
+ a better power function).
+- Changes in ZArith: several additional lemmas (used in theories/Numbers),
+ especially in Zdiv, Znumtheory, Zpower. Moreover, many results in
+ Zdiv have been generalized: the divisor may simply be non-null
+ instead of strictly positive (see lemmas with name ending by
+ "_full"). An alternative file ZOdiv proposes a different behavior
+ (the one of Ocaml) when dividing by negative numbers.
+- Changes in Arith: EqNat and Wf_nat now exported from Arith, some
+ constructions on nat that were outside Arith are now in (e.g. iter_nat).
+- In SetoidList, eqlistA now expresses that two lists have similar elements
+ at the same position, while the predicate previously called eqlistA
+ is now equivlistA (this one only states that the lists contain the same
+ elements, nothing more).
+- Changes in Reals:
+ * Most statement in "sigT" (including the
+ completeness axiom) are now in "sig" (in case of incompatibility,
+ use proj1_sig instead of projT1, sig instead of sigT, etc).
+ * More uniform naming scheme (identifiers in French moved to English,
+ consistent use of 0 -- zero -- instead of O -- letter O --, etc).
+ * Lemma on prod_f_SO is now on prod_f_R0.
+ * Useless hypothesis of ln_exists1 dropped.
+ * New Rlogic.v states a few logical properties about R axioms.
+ * RIneq.v extended and made cleaner.
+- Slight restructuration of the Logic library regarding choice and classical
+ logic. Addition of files providing intuitionistic axiomatizations of
+ descriptions: Epsilon.v, Description.v and IndefiniteDescription.v.
+- Definition of pred and minus made compatible with the structural
+ decreasing criterion for use in fixpoints.
+- Files Relations/Rstar.v and Relations/Newman.v moved out to the user
+ contribution repository (contribution CoC_History). New lemmas about
+ transitive closure added and some bound variables renamed (exceptional
+ risk of incompatibilities).
+- Syntax for binders in terms (e.g. for "exists") supports anonymous names.
+
+Notations, coercions, implicit arguments and type inference
+
+- More automation in the inference of the return clause of dependent
+ pattern-matching problems.
+- Experimental allowance for omission of the clauses easily detectable as
+ impossible in pattern-matching problems.
+- Improved inference of implicit arguments.
+- New options "Set Maximal Implicit Insertion", "Set Reversible Pattern
+ Implicit", "Set Strongly Strict Implicit" and "Set Printing Implicit
+ Defensive" for controlling inference and use of implicit arguments.
+- New modifier in "Implicit Arguments" to force an implicit argument to
+ be maximally inserted.
+- New modifier of "Implicit Arguments" to enrich the set of implicit arguments.
+- New options Global and Local to "Implicit Arguments" for section
+ surviving or non export outside module.
+- Level "constr" moved from 9 to 8.
+- Structure/Record now printed as Record (unless option Printing All is set).
+- Support for parametric notations defining constants.
+- Insertion of coercions below product types refrains to unfold
+ constants (possible source of incompatibility).
+- New support for fix/cofix in notations.
+
+Tactic Language
+
+- Second-order pattern-matching now working in Ltac "match" clauses
+ (syntax for second-order unification variable is "@?X").
+- Support for matching on let bindings in match context using syntax
+ "H := body" or "H := body : type".
+- Ltac accepts integer arguments (syntax is "ltac:nnn" for nnn an integer).
+- The general sequence tactical "expr_0 ; [ expr_1 | ... | expr_n ]"
+ is extended so that at most one expr_i may have the form "expr .."
+ or just "..". Also, n can be different from the number of subgoals
+ generated by expr_0. In this case, the value of expr (or idtac in
+ case of just "..") is applied to the intermediate subgoals to make
+ the number of tactics equal to the number of subgoals.
+- A name used as the name of the parameter of a lemma (like f in
+ "apply f_equal with (f:=t)") is now interpreted as a ltac variable
+ if such a variable exists (this is a possible source of
+ incompatibility and it can be fixed by renaming the variables of a
+ ltac function into names that do not clash with the lemmas
+ parameter names used in the tactic).
+- New syntax "Ltac tac ::= ..." to rebind a tactic to a new expression.
+- "let rec ... in ... " now supported for expressions without explicit
+ parameters; interpretation is lazy to the contrary of "let ... in ...";
+ hence, the "rec" keyword can be used to turn the argument of a
+ "let ... in ..." into a lazy one.
+- Patterns for hypotheses types in "match goal" are now interpreted in
+ type_scope.
+- A bound variable whose name is not used elsewhere now serves as
+ metavariable in "match" and it gets instantiated by an identifier
+ (allow e.g. to extract the name of a statement like "exists x, P x").
+- New printing of Ltac call trace for better debugging.
+
+Tactics
+
+- New tactics "apply -> term", "apply <- term", "apply -> term in
+ ident", "apply <- term in ident" for applying equivalences (iff).
+- Slight improvement of the hnf and simpl tactics when applied on
+ expressions with explicit occurrences of match or fix.
+- New tactics "eapply in", "erewrite", "erewrite in".
+- New tactics "ediscriminate", "einjection", "esimplify_eq".
+- Tactics "discriminate", "injection", "simplify_eq" now support any
+ term as argument. Clause "with" is also supported.
+- Unfoldable references can be given by notation's string rather than by name
+ in unfold.
+- The "with" arguments are now typed using informations from the current goal:
+ allows support for coercions and more inference of implicit arguments.
+- Application of "f_equal"-style lemmas works better.
+- Tactics elim, case, destruct and induction now support variants eelim,
+ ecase, edestruct and einduction.
+- Tactics destruct and induction now support the "with" option and the
+ "in" clause option. If the option "in" is used, an equality is added
+ to remember the term to which the induction or case analysis applied
+ (possible source of parsing incompatibilities when destruct or induction is
+ part of a let-in expression in Ltac; extra parentheses are then required).
+- New support for "as" clause in tactics "apply in" and "eapply in".
+- Some new intro patterns:
+ * intro pattern "?A" genererates a fresh name based on A.
+ Caveat about a slight loss of compatibility:
+ Some intro patterns don't need space between them. In particular
+ intros ?a?b used to be legal and equivalent to intros ? a ? b. Now it
+ is still legal but equivalent to intros ?a ?b.
+ * intro pattern "(A & ... & Y & Z)" synonym to "(A,....,(Y,Z)))))"
+ for right-associative constructs like /\ or exists.
+- Several syntax extensions concerning "rewrite":
+ * "rewrite A,B,C" can be used to rewrite A, then B, then C. These rewrites
+ occur only on the first subgoal: in particular, side-conditions of the
+ "rewrite A" are not concerned by the "rewrite B,C".
+ * "rewrite A by tac" allows to apply tac on all side-conditions generated by
+ the "rewrite A".
+ * "rewrite A at n" allows to select occurrences to rewrite: rewrite only
+ happen at the n-th exact occurrence of the first successful matching of
+ A in the goal.
+ * "rewrite 3 A" or "rewrite 3!A" is equivalent to "rewrite A,A,A".
+ * "rewrite !A" means rewriting A as long as possible (and at least once).
+ * "rewrite 3?A" means rewriting A at most three times.
+ * "rewrite ?A" means rewriting A as long as possible (possibly never).
+ * many of the above extensions can be combined with each other.
+- Introduction patterns better respect the structure of context in presence of
+ missing or extra names in nested disjunction-conjunction patterns [possible
+ source of rare incompatibilities].
+- New syntax "rename a into b, c into d" for "rename a into b; rename c into d"
+- New tactics "dependent induction/destruction H [ generalizing id_1 .. id_n ]"
+ to do induction-inversion on instantiated inductive families à la BasicElim.
+- Tactics "apply" and "apply in" now able to reason modulo unfolding of
+ constants (possible source of incompatibility in situations where apply
+ may fail, e.g. as argument of a try or a repeat and in a ltac function);
+ versions that do not unfold are renamed into "simple apply" and
+ "simple apply in" (usable for compatibility or for automation).
+- Tactics "apply" and "apply in" now able to traverse conjunctions and to
+ select the first matching lemma among the components of the conjunction;
+ tactic "apply" also able to apply lemmas of conclusion an empty type.
+- Tactic "apply" now supports application of several lemmas in a row.
+- Tactics "set" and "pose" can set functions using notation "(f x1..xn := c)".
+- New tactic "instantiate" (without argument).
+- Tactic firstorder "with" and "using" options have their meaning swapped for
+ consistency with auto/eauto (source of incompatibility).
+- Tactic "generalize" now supports "at" options to specify occurrences
+ and "as" options to name the quantified hypotheses.
+- New tactic "specialize H with a" or "specialize (H a)" allows to transform
+ in-place a universally-quantified hypothesis (H : forall x, T x) into its
+ instantiated form (H : T a). Nota: "specialize" was in fact there in earlier
+ versions of Coq, but was undocumented, and had a slightly different behavior.
+- New tactic "contradict H" can be used to solve any kind of goal as long as
+ the user can provide afterwards a proof of the negation of the hypothesis H.
+ If H is already a negation, say ~T, then a proof of T is asked.
+ If the current goal is a negation, say ~U, then U is saved in H afterwards,
+ hence this new tactic "contradict" extends earlier tactic "swap", which is
+ now obsolete.
+- Tactics f_equal is now done in ML instead of Ltac: it now works on any
+ equality of functions, regardless of the arity of the function.
+- New options "before id", "at top", "at bottom" for tactics "move"/"intro".
+- Some more debug of reflexive omega (romega), and internal clarifications.
+ Moreover, romega now has a variant "romega with *" that can be also used
+ on non-Z goals (nat, N, positive) via a call to a translation tactic named
+ zify (its purpose is to Z-ify your goal...). This zify may also be used
+ independently of romega.
+- Tactic "remember" now supports an "in" clause to remember only selected
+ occurrences of a term.
+- Tactic "pose proof" supports name overwriting in case of specialization of an
+ hypothesis.
+- Semi-decision tactic "jp" for first-order intuitionistic logic moved to user
+ contributions (subsumed by "firstorder").
+
+Program
+
+- Moved useful tactics in theories/Program and documented them.
+- Add Program.Basics which contains standard definitions for functional
+ programming (id, apply, flip...)
+- More robust obligation handling, dependent pattern-matching and
+ well-founded definitions.
+- New syntax " dest term as pat in term " for destructing objects using
+ an irrefutable pattern while keeping equalities (use this instead of
+ "let" in Programs).
+- Program CoFixpoint is accepted, Program Fixpoint uses the new way to infer
+ which argument decreases structurally.
+- Program Lemma, Axiom etc... now permit to have obligations in the statement
+ iff they can be automatically solved by the default tactic.
+- Renamed "Obligations Tactic" command to "Obligation Tactic".
+- New command "Preterm [ of id ]" to see the actual term fed to Coq for
+ debugging purposes.
+- New option "Transparent Obligations" to control the declaration of
+ obligations as transparent or opaque. All obligations are now transparent
+ by default, otherwise the system declares them opaque if possible.
+- Changed the notations "left" and "right" to "in_left" and "in_right" to hide
+ the proofs in standard disjunctions, to avoid breaking existing scripts when
+ importing Program. Also, put them in program_scope.
+
+Type Classes
+
+- New "Class", "Instance" and "Program Instance" commands to define
+ classes and instances documented in the reference manual.
+- New binding construct " [ Class_1 param_1 .. param_n, Class_2 ... ] "
+ for binding type classes, usable everywhere.
+- New command " Print Classes " and " Print Instances some_class " to
+ print tables for typeclasses.
+- New default eauto hint database "typeclass_instances" used by the default
+ typeclass instance search tactic.
+- New theories directory "theories/Classes" for standard typeclasses
+ declarations. Module Classes.RelationClasses is a typeclass port of
+ Relation_Definitions plus a generic development of algebra on
+ n-ary heterogeneous predicates.
+
+Setoid rewriting
+
+- Complete (and still experimental) rewrite of the tactic
+ based on typeclasses. The old interface and semantics are
+ almost entirely respected, except:
+
+ - Import Setoid is now mandatory to be able to call setoid_replace
+ and declare morphisms.
+
+ - "-->", "++>" and "==>" are now right associative notations
+ declared at level 55 in scope signature_scope.
+ Their introduction may break existing scripts that defined
+ them as notations with different levels.
+
+ - One needs to use [Typeclasses unfold [cst]] if [cst] is used
+ as an abbreviation hiding products in types of morphisms,
+ e.g. if ones redefines [relation] and declares morphisms
+ whose type mentions [relation].
+
+ - The [setoid_rewrite]'s semantics change when rewriting with
+ a lemma: it can rewrite two different instantiations of the lemma
+ at once. Use [setoid_rewrite H at 1] for (almost) the usual semantics.
+ [setoid_rewrite] will also try to rewrite under binders now, and can
+ succeed on different terms than before. In particular, it will unify under
+ let-bound variables. When called through [rewrite], the semantics are
+ unchanged though.
+
+ - [Add Morphism term : id] has different semantics when used with
+ parametric morphism: it will try to find a relation on the parameters
+ too. The behavior has also changed with respect to default relations:
+ the most recently declared Setoid/Relation will be used, the documentation
+ explains how to customize this behavior.
+
+ - Parametric Relation and Morphism are declared differently, using the
+ new [Add Parametric] commands, documented in the manual.
+
+ - Setoid_Theory is now an alias to Equivalence, scripts building objects
+ of type Setoid_Theory need to unfold (or "red") the definitions
+ of Reflexive, Symmetric and Transitive in order to get the same goals
+ as before. Scripts which introduced variables explicitely will not break.
+
+ - The order of subgoals when doing [setoid_rewrite] with side-conditions
+ is always the same: first the new goal, then the conditions.
+
+- New standard library modules Classes.Morphisms declares
+ standard morphisms on refl/sym/trans relations.
+ Classes.Morphisms_Prop declares morphisms on propositional
+ connectives and Classes.Morphisms_Relations on generalized predicate
+ connectives. Classes.Equivalence declares notations and tactics
+ related to equivalences and Classes.SetoidTactics defines the
+ setoid_replace tactics and some support for the "Add *" interface,
+ notably the tactic applied automatically before each "Add Morphism"
+ proof.
+
+- User-defined subrelations are supported, as well as higher-order morphisms
+ and rewriting under binders. The tactic is also extensible entirely in Ltac.
+ The documentation has been updated to cover these features.
+
+- [setoid_rewrite] and [rewrite] now support the [at] modifier to select
+ occurrences to rewrite, and both use the [setoid_rewrite] code, even when
+ rewriting with leibniz equality if occurrences are specified.
+
+Extraction
+
+- Improved behavior of the Caml extraction of modules: name clashes should
+ not happen anymore.
+- The command Extract Inductive has now a syntax for infix notations. This
+ allows in particular to map Coq lists and pairs onto Caml ones:
+ Extract Inductive list => list [ "[]" "(::)" ].
+ Extract Inductive prod => "(*)" [ "(,)" ].
+- In pattern matchings, a default pattern "| _ -> ..." is now used whenever
+ possible if several branches are identical. For instance, functions
+ corresponding to decidability of equalities are now linear instead of
+ quadratic.
+- A new instruction Extraction Blacklist id1 .. idn allows to prevent filename
+ conflits with existing code, for instance when extracting module List
+ to Ocaml.
+
+CoqIDE
+
+- CoqIDE font defaults to monospace so as indentation to be meaningful.
+- CoqIDE supports nested goals and any other kind of declaration in the middle
+ of a proof.
+- Undoing non-tactic commands in CoqIDE works faster.
+- New CoqIDE menu for activating display of various implicit informations.
+- Added the possibility to choose the location of tabs in coqide:
+ (in Edit->Preferences->Misc)
+- New Open and Save As dialogs in CoqIDE which filter *.v files.
+
+Tools
+
+- New stand-alone .vo files verifier "coqchk".
+- Extended -I coqtop/coqc option to specify a logical dir: "-I dir -as coqdir".
+- New coqtop/coqc option -exclude-dir to exclude subdirs for option -R.
+- The binary "parser" has been renamed to "coq-parser".
+- Improved coqdoc and dump of globalization information to give more
+ meta-information on identifiers. All categories of Coq definitions are
+ supported, which makes typesetting trivial in the generated documentation.
+ Support for hyperlinking and indexing developments in the tex output
+ has been implemented as well.
+
+Miscellaneous
+
+- Coq installation provides enough files so that Ocaml's extensions need not
+ the Coq sources to be compiled (this assumes O'Caml 3.10 and Camlp5).
+- New commands "Set Whelp Server" and "Set Whelp Getter" to customize the
+ Whelp search tool.
+- Syntax of "Test Printing Let ref" and "Test Printing If ref" changed into
+ "Test Printing Let for ref" and "Test Printing If for ref".
+- An overhauled build system (new Makefiles); see dev/doc/build-system.txt.
+- Add -browser option to configure script.
+- Build a shared library for the C part of Coq, and use it by default on
+ non-(Windows or MacOS) systems. Bytecode executables are now pure. The
+ behaviour is configurable with -coqrunbyteflags, -coqtoolsbyteflags and
+ -custom configure options.
+- Complexity tests can be skipped by setting the environment variable
+ COQTEST_SKIPCOMPLEXITY.
+
+Changes from V8.1gamma to V8.1
+==============================
+
+Bug fixes
+
+- Many bugs have been fixed (cf coq-bugs web page)
+
+Tactics
+
+- New tactics ring, ring_simplify and new tactic field now able to manage
+ power to a positive integer constant. Tactic ring on Z and R, and
+ field on R manage power (may lead to incompatibilities with V8.1gamma).
+- Tactic field_simplify now applicable in hypotheses.
+- New field_simplify_eq for simplifying field equations into ring equations.
+- Tactics ring, ring_simplify, field, field_simplify and field_simplify_eq
+ all able to apply user-given equations to rewrite monoms on the fly
+ (see documentation).
+
+Libraries
+
+- New file ConstructiveEpsilon.v defining an epsilon operator and
+ proving the axiom of choice constructively for a countable domain
+ and a decidable predicate.
+
+Changes from V8.1beta to V8.1gamma
+==================================
+
+Syntax
+
+- changed parsing precedence of let/in and fun constructions of Ltac:
+ let x := t in e1; e2 is now parsed as let x := t in (e1;e2).
+
+Language and commands
+
+- Added sort-polymorphism for definitions in Type (but finally abandonned).
+- Support for implicit arguments in the types of parameters in
+ (co-)fixpoints and (co-)inductive declarations.
+- Improved type inference: use as much of possible general information.
+ before applying irreversible unification heuristics (allow e.g. to
+ infer the predicate in "(exist _ 0 (refl_equal 0) : {n:nat | n=0 })").
+- Support for Miller-Pfenning's patterns unification in type synthesis
+ (e.g. can infer P such that P x y = phi(x,y)).
+- Support for "where" clause in cofixpoint definitions.
+- New option "Set Printing Universes" for making Type levels explicit.
+
+Tactics
+
+- Improved implementation of the ring and field tactics. For compatibility
+ reasons, the previous tactics are renamed as legacy ring and legacy field,
+ but should be considered as deprecated.
+- New declarative mathematical proof language.
+- Support for argument lists of arbitrary length in Tactic Notation.
+- [rewrite ... in H] now fails if [H] is used either in an hypothesis
+ or in the goal.
+- The semantics of [rewrite ... in *] has been slightly modified (see doc).
+- Support for "as" clause in tactic injection.
+- New forward-reasoning tactic "apply in".
+- Ltac fresh operator now builds names from a concatenation of its arguments.
+- New ltac tactic "remember" to abstract over a subterm and keep an equality
+- Support for Miller-Pfenning's patterns unification in apply/rewrite/...
+ (may lead to few incompatibilities - generally now useless tactic calls).
+
+Bug fixes
+
+- Fix for notations involving basic "match" expressions.
+- Numerous other bugs solved (a few fixes may lead to incompatibilities).
+
+
+Changes from V8.0 to V8.1beta
+=============================
+
+Logic
+
+- Added sort-polymorphism on inductive families
+- Allowance for recursively non uniform parameters in inductive types
+
+Syntax
+
+- No more support for version 7 syntax and for translation to version 8 syntax.
+- In fixpoints, the { struct ... } annotation is not mandatory any more when
+ only one of the arguments has an inductive type
+- Added disjunctive patterns in match-with patterns
+- Support for primitive interpretation of string literals
+- Extended support for Unicode ranges
+
+Vernacular commands
+
+- Added "Print Ltac qualid" to print a user defined tactic.
+- Added "Print Rewrite HintDb" to print the content of a DB used by
+ autorewrite.
+- Added "Print Canonical Projections".
+- Added "Example" as synonym of "Definition".
+- Added "Proposition" and "Corollary" as extra synonyms of "Lemma".
+- New command "Whelp" to send requests to the Helm database of proofs
+ formalized in the Calculus of Inductive Constructions.
+- Command "functional induction" has been re-implemented from the new
+ "Function" command.
+
+Ltac and tactic syntactic extensions
+
+- New primitive "external" for communication with tool external to Coq
+- New semantics for "match t with": if a clause returns a
+ tactic, it is now applied to the current goal. If it fails, the next
+ clause or next matching subterm is tried (i.e. it behaves as "match
+ goal with" does). The keyword "lazymatch" can be used to delay the
+ evaluation of tactics occurring in matching clauses.
+- Hint base names can be parametric in auto and trivial.
+- Occurrence values can be parametric in unfold, pattern, etc.
+- Added entry constr_may_eval for tactic extensions.
+- Low-priority term printer made available in ML-written tactic extensions.
+- "Tactic Notation" extended to allow notations of tacticals.
+
+Tactics
+
+- New implementation and generalization of [setoid_]* (setoid_rewrite,
+ setoid_symmetry, setoid_transitivity, setoid_reflexivity and autorewite).
+ New syntax for declaring relations and morphisms (old syntax still working
+ with minor modifications, but deprecated).
+- New implementation (still experimental) of the ring tactic with a built-in
+ notion of coefficients and a better usage of setoids.
+- New conversion tactic "vm_compute": evaluates the goal (or an hypothesis)
+ with a call-by-value strategy, using the compiled version of terms.
+- When rewriting H where H is not directly a Coq equality, search first H for
+ a registered setoid equality before starting to reduce in H. This is unlikely
+ to break any script. Should this happen nonetheless, one can insert manually
+ some "unfold ... in H" before rewriting.
+- Fixed various bugs about (setoid) rewrite ... in ... (in particular bug #5941)
+- "rewrite ... in" now accepts a clause as place where to rewrite instead of
+ juste a simple hypothesis name. For instance:
+ rewrite H in H1,H2 |- * means rewrite H in H1; rewrite H in H2; rewrite H
+ rewrite H in * |- will do try rewrite H in Hi for all hypothesis Hi <> H.
+- Added "dependent rewrite term" and "dependent rewrite term in hyp".
+- Added "autorewrite with ... in hyp [using ...]".
+- Tactic "replace" now accepts a "by" tactic clause.
+- Added "clear - id" to clear all hypotheses except the ones depending in id.
+- The argument of Declare Left Step and Declare Right Step is now a term
+ (it used to be a reference).
+- Omega now handles arbitrary precision integers.
+- Several bug fixes in Reflexive Omega (romega).
+- Idtac can now be left implicit in a [...|...] construct: for instance,
+ [ foo | | bar ] stands for [ foo | idtac | bar ].
+- Fixed a "fold" bug (non critical but possible source of incompatibilities).
+- Added classical_left and classical_right which transforms |- A \/ B into
+ ~B |- A and ~A |- B respectively.
+- Added command "Declare Implicit Tactic" to set up a default tactic to be
+ used to solve unresolved subterms of term arguments of tactics.
+- Better support for coercions to Sortclass in tactics expecting type
+ arguments.
+- Tactic "assert" now accepts "as" intro patterns and "by" tactic clauses.
+- New tactic "pose proof" that generalizes "assert (id:=p)" with intro patterns.
+- New introduction pattern "?" for letting Coq choose a name.
+- Introduction patterns now support side hypotheses (e.g. intros [|] on
+ "(nat -> nat) -> nat" works).
+- New introduction patterns "->" and "<-" for immediate rewriting of
+ introduced hypotheses.
+- Introduction patterns coming after non trivial introduction patterns now
+ force full introduction of the first pattern (e.g. "intros [[|] p]" on
+ "nat->nat->nat" now behaves like "intros [[|?] p]")
+- Added "eassumption".
+- Added option 'using lemmas' to auto, trivial and eauto.
+- Tactic "congruence" is now complete for its intended scope (ground
+ equalities and inequalities with constructors). Furthermore, it
+ tries to equates goal and hypotheses.
+- New tactic "rtauto" solves pure propositional logic and gives a
+ reflective version of the available proof.
+- Numbering of "pattern", "unfold", "simpl", ... occurrences in "match
+ with" made consistent with the printing of the return clause after
+ the term to match in the "match-with" construct (use "Set Printing All"
+ to see hidden occurrences).
+- Generalization of induction "induction x1...xn using scheme" where
+ scheme is an induction principle with complex predicates (like the
+ ones generated by function induction).
+- Some small Ltac tactics has been added to the standard library
+ (file Tactics.v):
+ * f_equal : instead of using the different f_equalX lemmas
+ * case_eq : a "case" without loss of information. An equality
+ stating the current situation is generated in every sub-cases.
+ * swap : for a negated goal ~B and a negated hypothesis H:~A,
+ swap H asks you to prove A from hypothesis B
+ * revert : revert H is generalize H; clear H.
+
+Extraction
+
+- All type parts should now disappear instead of sometimes producing _
+ (for instance in Map.empty).
+- Haskell extraction: types of functions are now printed, better
+ unsafeCoerce mechanism, both for hugs and ghc.
+- Scheme extraction improved, see http://www.pps.jussieu.fr/~letouzey/scheme.
+- Many bug fixes.
+
+Modules
+
+- Added "Locate Module qualid" to get the full path of a module.
+- Module/Declare Module syntax made more uniform.
+- Added syntactic sugar "Declare Module Export/Import" and
+ "Module Export/Import".
+- Added syntactic sugar "Module M(Export/Import X Y: T)" and
+ "Module Type M(Export/Import X Y: T)"
+ (only for interactive definitions)
+- Construct "with" generalized to module paths:
+ T with (Definition|Module) M1.M2....Mn.l := l'.
+
+Notations
+
+- Option "format" aware of recursive notations.
+- Added insertion of spaces by default in recursive notations w/o separators.
+- No more automatic printing box in case of user-provided printing "format".
+- New notation "exists! x:A, P" for unique existence.
+- Notations for specific numerals now compatible with generic notations of
+ numerals (e.g. "1" can be used to denote the unit of a group without
+ hiding 1%nat)
+
+Libraries
+
+- New library on String and Ascii characters (contributed by L. Thery).
+- New library FSets+FMaps of finite sets and maps.
+- New library QArith on rational numbers.
+- Small extension of Zmin.V, new Zmax.v, new Zminmax.v.
+- Reworking and extension of the files on classical logic and
+ description principles (possible incompatibilities)
+- Few other improvements in ZArith potentially exceptionally breaking the
+ compatibility (useless hypothesys of Zgt_square_simpl and
+ Zlt_square_simpl removed; fixed names mentioning letter O instead of
+ digit 0; weaken premises in Z_lt_induction).
+- Restructuration of Eqdep_dec.v and Eqdep.v: more lemmas in Type.
+- Znumtheory now contains a gcd function that can compute within Coq.
+- More lemmas stated on Type in Wf.v, removal of redundant Acc_iter and
+ Acc_iter2.
+- Change of the internal names of lemmas in OmegaLemmas.
+- Acc in Wf.v and clos_refl_trans in Relation_Operators.v now rely on
+ the allowance for recursively non uniform parameters (possible
+ source of incompatibilities: explicit pattern-matching on these
+ types may require to remove the occurrence associated to their
+ recursively non uniform parameter).
+- Coq.List.In_dec has been set transparent (this may exceptionally break
+ proof scripts, set it locally opaque for compatibility).
+- More on permutations of lists in List.v and Permutation.v.
+- List.v has been much expanded.
+- New file SetoidList.v now contains results about lists seen with
+ respect to a setoid equality.
+- Library NArith has been expanded, mostly with results coming from
+ Intmap (for instance a bitwise xor), plus also a bridge between N and
+ Bitvector.
+- Intmap has been reorganized. In particular its address type "addr" is
+ now N. User contributions known to use Intmap have been adapted
+ accordingly. If you're using this library please contact us.
+ A wrapper FMapIntMap now presents Intmap as a particular implementation
+ of FMaps. New developments are strongly encouraged to use either this
+ wrapper or any other implementations of FMap instead of using directly
+ this obsolete Intmap.
+
+Tools
+
+- New semantics for coqtop options ("-batch" expects option "-top dir"
+ for loading vernac file that contains definitions).
+- Tool coq_makefile now removes custom targets that are file names in
+ "make clean"
+- New environment variable COQREMOTEBROWSER to set the command invoked
+ to start the remote browser both in Coq and coqide. Standard syntax:
+ "%s" is the placeholder for the URL.
+
+
+Changes from V8.0beta to V8.0
+=============================
+
+Vernacular commands
+
+- New option "Set Printing All" to deactivate all high-level forms of
+ printing (implicit arguments, coercions, destructing let,
+ if-then-else, notations, projections)
+- "Functional Scheme" and "Functional Induction" extended to polymorphic
+ types and dependent types
+- Notation now allows recursive patterns, hence recovering parts of the
+ fonctionalities of pre-V8 Grammar/Syntax commands
+- Command "Print." discontinued.
+- Redundant syntax "Implicit Arguments On/Off" discontinued
+
+New syntax
+
+- Semantics change of the if-then-else construction in new syntax:
+ "if c then t1 else t2" now stands for
+ "match c with c1 _ ... _ => t1 | c2 _ ... _ => t2 end"
+ with no dependency of t1 and t2 in the arguments of the constructors;
+ this may cause incompatibilities for files translated using coq 8.0beta
+
+Interpretation scopes
+
+- Delimiting key %bool for bool_scope added
+- Import no more needed to activate argument scopes from a module
+
+Tactics and the tactic Language
+
+- Semantics of "assert" is now consistent with the reference manual
+- New tactics stepl and stepr for chaining transitivity steps
+- Tactic "replace ... with ... in" added
+- Intro patterns now supported in Ltac (parsed with prefix "ipattern:")
+
+Executables and tools
+
+- Added option -top to change the name of the toplevel module "Top"
+- Coqdoc updated to new syntax and now part of Coq sources
+- XML exportation tool now exports the structure of vernacular files
+ (cf chapter 13 in the reference manual)
+
+User contributions
+
+- User contributions have been updated to the new syntax
+
+Bug fixes
+
+- Many bugs have been fixed (cf coq-bugs web page)
+
+Changes from V8.0beta old syntax to V8.0beta
+============================================
+
+New concrete syntax
+
+- A completely new syntax for terms
+- A more uniform syntax for tactics and the tactic language
+- A few syntactic changes for vernacular commands
+- A smart automatic translator translating V8.0 files in old syntax to
+ files valid for V8.0
+
+Syntax extensions
+
+- "Grammar" for terms disappears
+- "Grammar" for tactics becomes "Tactic Notation"
+- "Syntax" disappears
+- Introduction of a notion of interpretation scope allowing to use the
+ same notations in various contexts without using specific delimiters
+ (e.g the same expression "4<=3+x" is interpreted either in "nat",
+ "positive", "N" (previously "entier"), "Z", "R", depending on which
+ interpretation scope is currently open) [see documentation for details]
+- Notation now mandatorily requires a precedence and associativity
+ (default was to set precedence to 1 and associativity to none)
+
+Revision of the standard library
+
+- Many lemmas and definitions names have been made more uniform mostly
+ in Arith, NArith, ZArith and Reals (e.g : "times" -> "Pmult",
+ "times_sym" -> "Pmult_comm", "Zle_Zmult_pos_right" ->
+ "Zmult_le_compat_r", "SUPERIEUR" -> "Gt", "ZERO" -> "Z0")
+- Order and names of arguments of basic lemmas on nat, Z, positive and R
+ have been made uniform.
+- Notions of Coq initial state are declared with (strict) implicit arguments
+- eq merged with eqT: old eq disappear, new eq (written =) is old eqT
+ and new eqT is syntactic sugar for new eq (notation == is an alias
+ for = and is written as it, exceptional source of incompatibilities)
+- Similarly, ex, ex2, all, identity are merged with exT, exT2, allT, identityT
+- Arithmetical notations for nat, positive, N, Z, R, without needing
+ any backquote or double-backquotes delimiters.
+- In Lists: new concrete notations; argument of nil is now implicit
+- All changes in the library are taken in charge by the translator
+
+Semantical changes during translation
+
+- Recursive keyword set by default (and no longer needed) in Tactic Definition
+- Set Implicit Arguments is strict by default in new syntax
+- reductions in hypotheses of the form "... in H" now apply to the type
+ also if H is a local definition
+- etc
+
+Gallina
+
+- New syntax of the form "Inductive bool : Set := true, false : bool." for
+ enumerated types
+- Experimental syntax of the form p.(fst) for record projections
+ (activable with option "Set Printing Projections" which is
+ recognized by the translator)
+
+Known problems of the automatic translation
+
+- iso-latin-1 characters are no longer supported: move your files to
+ 7-bits ASCII or unicode before translation (swith to unicode is
+ automatically done if a file is loaded and saved again by coqide)
+- Renaming in ZArith: incompatibilities in Coq user contribs due to
+ merging names INZ, from Reals, and inject_nat.
+- Renaming and new lemmas in ZArith: may clash with names used by users
+- Restructuration of ZArith: replace requirement of specific modules
+ in ZArith by "Require Import ZArith_base" or "Require Import ZArith"
+- Some implicit arguments must be made explicit before translation: typically
+ for "length nil", the implicit argument of length must be made explicit
+- Grammar rules, Infix notations and V7.4 Notations must be updated wrt the
+ new scheme for syntactic extensions (see translator documentation)
+- Unsafe for annotation Cases when constructors coercions are used or when
+ annotations are eta-reduced predicates
+
+
+Changes from V7.4 to V8.0beta old syntax
+========================================
+
+Logic
+
+- Set now predicative by default
+- New option -impredicative-set to set Set impredicative
+- The standard library doesn't need impredicativity of Set and is
+ compatible with the classical axioms which contradict Set impredicativity
+
+Syntax for arithmetic
+
+- Notation "=" and "<>" in Z and R are no longer implicitly in Z or R
+ (with possible introduction of a coercion), use ...=... or
+ ...<>... instead
+- Locate applied to a simple string (e.g. "+") searches for all
+ notations containing this string
+
+Vernacular commands
+
+- "Declare ML Module" now allows to import .cma files. This avoids to use a
+ bunch of "Declare ML Module" statements when using several ML files.
+- "Set Printing Width n" added, allows to change the size of width printing.
+- "Implicit Variables Type x,y:t" (new syntax: "Implicit Types x y:t")
+ assigns default types for binding variables.
+- Declarations of Hints and Notation now accept a "Local" flag not to
+ be exported outside the current file even if not in section
+- "Print Scopes" prints all notations
+- New command "About name" for light printing of type, implicit arguments, etc.
+- New command "Admitted" to declare incompletely proven statement as axioms
+- New keyword "Conjecture" to declare an axiom intended to be provable
+- SearchAbout can now search for lemmas referring to more than one constant
+ and on substrings of the name of the lemma
+- "Print Implicit" displays the implicit arguments of a constant
+- Locate now searches for all names having a given suffix
+- New command "Functional Scheme" for building an induction principle
+ from a function defined by case analysis and fix.
+
+Commands
+
+- new coqtop/coqc option -dont-load-proofs not to load opaque proofs in memory
+
+Implicit arguments
+
+- Inductive in sections declared with implicits now "discharged" with
+ implicits (like constants and variables)
+- Implicit Arguments flags are now synchronous with reset
+- New switch "Unset/Set Printing Implicits" (new syntax: "Unset/Set Printing
+ Implicit") to globally control printing of implicits
+
+Grammar extensions
+
+- Many newly supported UTF-8 encoded unicode blocks
+ - Greek letters (0380-03FF), Hebrew letters (U05D0-05EF), letter-like
+ symbols (2100-214F, that includes double N,Z,Q,R), prime
+ signs (from 2080-2089) and characters from many written languages
+ are valid in identifiers
+ - mathematical operators (2200-22FF), supplemental mathematical
+ operators (2A00-2AFF), miscellaneous technical (2300-23FF that
+ includes sqrt symbol), miscellaneous symbols (2600-26FF), arrows
+ (2190-21FF and 2900-297F), invisible mathematical operators (from
+ 2080-2089), ... are valid symbols
+
+Library
+
+- New file about the factorial function in Arith
+- An additional elimination Acc_iter for Acc, simplier than Acc_rect.
+ This new elimination principle is used for definition well_founded_induction.
+- New library NArith on binary natural numbers
+- R is now of type Set
+- Restructuration in ZArith library
+ - "true_sub" used in Zplus now a definition, not a local one (source
+ of incompatibilities in proof referring to true_sub, may need extra Unfold)
+ - Some lemmas about minus moved from fast_integer to Arith/Minus.v
+ (le_minus, lt_mult_left) (theoretical source of incompatibilities)
+ - Several lemmas moved from auxiliary.v and zarith_aux.v to
+ fast_integer.v (theoretical source of incompatibilities)
+ - Variables names of iff_trans changed (source of incompatibilities)
+ - ZArith lemmas named OMEGA something or fast_ something, and lemma new_var
+ are now out of ZArith (except OMEGA2)
+ - Redundant ZArith lemmas have been renamed: for the following pairs,
+ use the second name (Zle_Zmult_right2, Zle_mult_simpl), (OMEGA2,
+ Zle_0_plus), (Zplus_assoc_l, Zplus_assoc), (Zmult_one, Zmult_1_n),
+ (Zmult_assoc_l, Zmult_assoc), (Zmult_minus_distr, Zmult_Zminus_distr_l)
+ (add_un_double_moins_un_xO, is_double_moins_un),
+ (Rlt_monotony_rev,Rlt_monotony_contra) (source of incompatibilities)
+- Few minor changes (no more implicit arguments in
+ Zmult_Zminus_distr_l and Zmult_Zminus_distr_r, lemmas moved from
+ Zcomplements to other files) (rare source of incompatibilities)
+- New lemmas provided by users added
+
+Tactic language
+
+- Fail tactic now accepts a failure message
+- Idtac tactic now accepts a message
+- New primitive tactic "FreshId" (new syntax: "fresh") to generate new names
+- Debugger prints levels of calls
+
+Tactics
+
+- Replace can now replace proofs also
+- Fail levels are now decremented at "Match Context" blocks only and
+ if the right-hand-side of "Match term With" are tactics, these
+ tactics are never evaluated immediately and do not induce
+ backtracking (in contrast with "Match Context")
+- Quantified names now avoid global names of the current module (like
+ Intro names did) [source of rare incompatibilities: 2 changes in the set of
+ user contribs]
+- NewDestruct/NewInduction accepts intro patterns as introduction names
+- NewDestruct/NewInduction now work for non-inductive type using option "using"
+- A NewInduction naming bug for inductive types with functional
+ arguments (e.g. the accessibility predicate) has been fixed (source
+ of incompatibilities)
+- Symmetry now applies to hypotheses too
+- Inversion now accept option "as [ ... ]" to name the hypotheses
+- Contradiction now looks also for contradictory hypotheses stating ~A and A
+ (source of incompatibility)
+- "Contradiction c" try to find an hypothesis in context which
+ contradicts the type of c
+- Ring applies to new library NArith (require file NArithRing)
+- Field now works on types in Set
+- Auto with reals now try to replace le by ge (Rge_le is no longer an
+ immediate hint), resulting in shorter proofs
+- Instantiate now works in hyps (syntax : Instantiate in ...)
+- Some new tactics : EConstructor, ELeft, Eright, ESplit, EExists
+- New tactic "functional induction" to perform case analysis and
+ induction following the definition of a function.
+- Clear now fails when trying to remove a local definition used by
+ a constant appearing in the current goal
+
+Extraction (See details in plugins/extraction/CHANGES)
+
+- The old commands: (Recursive) Extraction Module M.
+ are now: (Recursive) Extraction Library M.
+ To use these commands, M should come from a library M.v
+- The other syntax Extraction & Recursive Extraction now accept
+ module names as arguments.
+
+Bugs
+
+- see coq-bugs server for the complete list of fixed bugs
+
+Miscellaneous
+
+- Implicit parameters of inductive types definition now taken into
+ account for infering other implicit arguments
+
+Incompatibilities
+
+- Persistence of true_sub (4 incompatibilities in Coq user contributions)
+- Variable names of some constants changed for a better uniformity (2 changes
+ in Coq user contributions)
+- Naming of quantified names in goal now avoid global names (2 occurrences)
+- NewInduction naming for inductive types with functional arguments
+ (no incompatibility in Coq user contributions)
+- Contradiction now solve more goals (source of 2 incompatibilities)
+- Merge of eq and eqT may exceptionally result in subgoals now
+ solved automatically
+- Redundant pairs of ZArith lemmas may have different names: it may
+ cause "Apply/Rewrite with" to fail if using the first name of a pair
+ of redundant lemmas (this is solved by renaming the variables bound by
+ "with"; 3 incompatibilities in Coq user contribs)
+- ML programs referring to constants from fast_integer.v must use
+ "Coqlib.gen_constant_modules Coqlib.zarith_base_modules" instead
+
+Changes from V7.3.1 to V7.4
+===========================
+
+Symbolic notations
+
+- Introduction of a notion of scope gathering notations in a consistent set;
+ a notation sets has been developed for nat, Z and R (undocumented)
+- New command "Notation" for declaring notations simultaneously for
+ parsing and printing (see chap 10 of the reference manual)
+- Declarations with only implicit arguments now handled (e.g. the
+ argument of nil can be set implicit; use !nil to refer to nil
+ without arguments)
+- "Print Scope sc" and "Locate ntn" allows to know to what expression a
+ notation is bound
+- New defensive strategy for printing or not implicit arguments to ensure
+ re-type-checkability of the printed term
+- In Grammar command, the only predefined non-terminal entries are ident,
+ global, constr and pattern (e.g. nvar, numarg disappears); the only
+ allowed grammar types are constr and pattern; ast and ast list are no
+ longer supported; some incompatibilities in Grammar: when a syntax is a
+ initial segment of an other one, Grammar does not work, use Notation
+
+Library
+
+- Lemmas in Set from Compare_dec.v (le_lt_dec, ...) and Wf_nat.v
+ (lt_wf_rec, ...) are now transparent. This may be source of
+ incompatibilities.
+- Syntactic Definitions Fst, Snd, Ex, All, Ex2, AllT, ExT, ExT2,
+ ProjS1, ProjS2, Error, Value and Except are turned to
+ notations. They now must be applied (incompatibilities only in
+ unrealistic cases).
+- More efficient versions of Zmult and times (30% faster)
+- Reals: the library is now divided in 6 parts (Rbase, Rfunctions,
+ SeqSeries, Rtrigo, Ranalysis, Integration). New tactics: Sup and
+ RCompute. See Reals.v for details.
+
+Modules
+
+- Beta version, see doc chap 2.5 for commands and chap 5 for theory
+
+Language
+
+- Inductive definitions now accept ">" in constructor types to declare
+ the corresponding constructor as a coercion.
+- Idem for assumptions declarations and constants when the type is mentionned.
+- The "Coercion" and "Canonical Structure" keywords now accept the
+ same syntax as "Definition", i.e. "hyps :=c (:t)?" or "hyps :t".
+- Theorem-like declaration now accepts the syntax "Theorem thm [x:t;...] : u".
+- Remark's and Fact's now definitively behave as Theorem and Lemma: when
+ sections are closed, the full name of a Remark or a Fact has no longer a
+ section part (source of incompatibilities)
+- Opaque Local's (i.e. built by tactics and ended by Qed), do not
+ survive section closing any longer; as a side-effect, Opaque Local's
+ now appear in the local context of proofs; their body is hidden
+ though (source of incompatibilities); use one of Remark/Fact/Lemma/Theorem
+ instead to simulate the old behaviour of Local (the section part of
+ the name is not kept though)
+
+ML tactic and vernacular commands
+
+- "Grammar tactic" and "Grammar vernac" of type "ast" are no longer
+ supported (only "Grammar tactic simple_tactic" of type "tactic"
+ remains available).
+- Concrete syntax for ML written vernacular commands and tactics is
+ now declared at ML level using camlp4 macros TACTIC EXTEND et VERNAC
+ COMMAND EXTEND.
+- "Check n c" now "n:Check c", "Eval n ..." now "n:Eval ..."
+- "Proof with T" (* no documentation *)
+- SearchAbout id - prints all theorems which contain id in their type
+
+Tactic definitions
+
+- Static globalisation of identifiers and global references (source of
+ incompatibilities, especially, Recursive keyword is required for
+ mutually recursive definitions).
+- New evaluation semantics: no more partial evaluation at definition time;
+ evaluation of all Tactic/Meta Definition, even producing terms, expect
+ a proof context to be evaluated (especially "()" is no longer needed).
+- Debugger now shows the nesting level and the reasons of failure
+
+Tactics
+
+- Equality tactics (Rewrite, Reflexivity, Symmetry, Transitivity) now
+ understand JM equality
+- Simpl and Change now apply to subterms also
+- "Simpl f" reduces subterms whose head constant is f
+- Double Induction now referring to hypotheses like "Intros until"
+- "Inversion" now applies also on quantified hypotheses (naming as
+ for Intros until)
+- NewDestruct now accepts terms with missing hypotheses
+- NewDestruct and NewInduction now accept user-provided elimination scheme
+- NewDestruct and NewInduction now accept user-provided introduction names
+- Omega could solve goals such as ~`x=y` but failed when the
+ hypothesis was unfolded to `x < y` -> False. This is fixed. In addition,
+ it can also recognize 'False' in the hypothesis and use it to solve the
+ goal.
+- Coercions now handled in "with" bindings
+- "Subst x" replaces all ocurrences of x by t in the goal and hypotheses
+ when an hypothesis x=t or x:=t or t=x exists
+- Fresh names for Assert and Pose now based on collision-avoiding
+ Intro naming strategy (exceptional source of incompatibilities)
+- LinearIntuition (* no documentation *)
+- Unfold expects a correct evaluable argument
+- Clear expects existing hypotheses
+
+Extraction (See details in plugins/extraction/CHANGES and README):
+
+- An experimental Scheme extraction is provided.
+- Concerning Ocaml, extracted code is now ensured to always type-check,
+ thanks to automatic inserting of Obj.magic.
+- Experimental extraction of Coq new modules to Ocaml modules.
+
+Proof rendering in natural language
+
+- Export of theories to XML for publishing and rendering purposes now
+ includes proof-trees (see http://www.cs.unibo.it/helm)
+
+Miscellaneous
+
+- Printing Coercion now used through the standard keywords Set/Add, Test, Print
+- "Print Term id" is an alias for "Print id"
+- New switch "Unset/Set Printing Symbols" to control printing of
+ symbolic notations
+- Two new variants of implicit arguments are available
+ - "Unset/Set Contextual Implicits" tells to consider implicit also the
+ arguments inferable from the context (e.g. for nil or refl_eq)
+ - "Unset/Set Strict Implicits" tells to consider implicit only the
+ arguments that are inferable in any case (i.e. arguments that occurs
+ as argument of rigid constants in the type of the remaining arguments;
+ e.g. the witness of an existential is not strict since it can vanish when
+ applied to a predicate which does not use its argument)
+
+Incompatibilities
+
+- "Grammar tactic ... : ast" and "Grammar vernac ... : ast" are no
+ longer supported, use TACTIC EXTEND and VERNAC COMMAND EXTEND on the
+ ML-side instead
+- Transparency of le_lt_dec and co (leads to some simplification in
+ proofs; in some cases, incompatibilites is solved by declaring locally
+ opaque the relevant constant)
+- Opaque Local do not now survive section closing (rename them into
+ Remark/Lemma/... to get them still surviving the sections; this
+ renaming allows also to solve incompatibilites related to now
+ forbidden calls to the tactic Clear)
+- Remark and Fact have no longer (very) long names (use Local instead in case
+ of name conflict)
+
+Bugs
+
+- Improved localisation of errors in Syntactic Definitions
+- Induction principle creation failure in presence of let-in fixed (#1459)
+- Inversion bugs fixed (#1427 and #1437)
+- Omega bug related to Set fixed (#1384)
+- Type-checking inefficiency of nested destructuring let-in fixed (#1435)
+- Improved handling of let-in during holes resolution phase (#1460)
+
+Efficiency
+
+- Implementation of a memory sharing strategy reducing memory
+ requirements by an average ratio of 3.
+
+Changes from V7.3 to V7.3.1
+===========================
+
+Bug fixes
+
+ - Corrupted Field tactic and Match Context tactic construction fixed
+ - Checking of names already existing in Assert added (#1386)
+ - Invalid argument bug in Exact tactic solved (#1387)
+ - Colliding bound names bug fixed (#1412)
+ - Wrong non-recursivity test for Record fixed (#1394)
+ - Out of memory/seg fault bug related to parametric inductive fixed (#1404)
+ - Setoid_replace/Setoid_rewrite bug wrt "==" fixed
+
+Misc
+
+ - Ocaml version >= 3.06 is needed to compile Coq from sources
+ - Simplification of fresh names creation strategy for Assert, Pose and
+ LetTac (#1402)
+
+Changes from V7.2 to V7.3
+=========================
+
+Language
+
+- Slightly improved compilation of pattern-matching (slight source of
+ incompatibilities)
+- Record's now accept anonymous fields "_" which does not build projections
+- Changes in the allowed elimination sorts for certain class of inductive
+ definitions : an inductive definition without constructors
+ of Sort Prop can be eliminated on sorts Set and Type A "singleton"
+ inductive definition (one constructor with arguments in the sort Prop
+ like conjunction of two propositions or equality) can be eliminated
+ directly on sort Type (In V7.2, only the sorts Prop and Set were allowed)
+
+Tactics
+
+- New tactic "Rename x into y" for renaming hypotheses
+- New tactics "Pose x:=u" and "Pose u" to add definitions to local context
+- Pattern now working on partially applied subterms
+- Ring no longer applies irreversible congruence laws of mult but
+ better applies congruence laws of plus (slight source of incompatibilities).
+- Field now accepts terms to be simplified as arguments (as for Ring). This
+ extension has been also implemented using the toplevel tactic language.
+- Intuition does no longer unfold constants except "<->" and "~". It
+ can be parameterized by a tactic. It also can introduce dependent
+ product if needed (source of incompatibilities)
+- "Match Context" now matching more recent hypotheses first and failing only
+ on user errors and Fail tactic (possible source of incompatibilities)
+- Tactic Definition's without arguments now allowed in Coq states
+- Better simplification and discrimination made by Inversion (source
+ of incompatibilities)
+
+Bugs
+
+- "Intros H" now working like "Intro H" trying first to reduce if not a product
+- Forward dependencies in Cases now taken into account
+- Known bugs related to Inversion and let-in's fixed
+- Bug unexpected Delta with let-in now fixed
+
+Extraction (details in plugins/extraction/CHANGES or documentation)
+
+- Signatures of extracted terms are now mostly expunged from dummy arguments.
+- Haskell extraction is now operational (tested & debugged).
+
+Standard library
+
+- Some additions in [ZArith]: three files (Zcomplements.v, Zpower.v
+ and Zlogarithms.v) moved from plugins/omega in order to be more
+ visible, one Zsgn function, more induction principles (Wf_Z.v and
+ tail of Zcomplements.v), one more general Euclid theorem
+- Peano_dec.v and Compare_dec.v now part of Arith.v
+
+Tools
+
+- new option -dump-glob to coqtop to dump globalizations (to be used by the
+ new documentation tool coqdoc; see http://www.lri.fr/~filliatr/coqdoc)
+
+User Contributions
+
+- CongruenceClosure (congruence closure decision procedure)
+ [Pierre Corbineau, ENS Cachan]
+- MapleMode (an interface to embed Maple simplification procedures over
+ rational fractions in Coq)
+ [David Delahaye, Micaela Mayero, Chalmers University]
+- Presburger: A formalization of Presburger's algorithm
+ [Laurent Thery, INRIA Sophia Antipolis]
+- Chinese has been rewritten using Z from ZArith as datatype
+ ZChinese is the new version, Chinese the obsolete one
+ [Pierre Letouzey, LRI Orsay]
+
+Incompatibilities
+
+- Ring: exceptional incompatibilities (1 above 650 in submitted user
+ contribs, leading to a simplification)
+- Intuition: does not unfold any definition except "<->" and "~"
+- Cases: removal of some extra Cases in configurations of the form
+ "Cases ... of C _ => ... | _ D => ..." (effects on 2 definitions of
+ submitted user contributions necessitating the removal of now superfluous
+ proof steps in 3 different proofs)
+- Match Context, in case of incompatibilities because of a now non
+ trapped error (e.g. Not_found or Failure), use instead tactic Fail
+ to force Match Context trying the next clause
+- Inversion: better simplification and discrimination may occasionally
+ lead to less subgoals and/or hypotheses and different naming of hypotheses
+- Unification done by Apply/Elim has been changed and may exceptionally lead
+ to incompatible instantiations
+- Peano_dec.v and Compare_dec.v parts of Arith.v make Auto more
+ powerful if these files were not already required (1 occurrence of
+ this in submitted user contribs)
+
+Changes from V7.1 to V7.2
+=========================
+
+Language
+
+- Automatic insertion of patterns for local definitions in the type of
+ the constructors of an inductive types (for compatibility with V6.3
+ let-in style)
+- Coercions allowed in Cases patterns
+- New declaration "Canonical Structure id = t : I" to help resolution of
+ equations of the form (proj ?)=a; if proj(e)=a then a is canonically
+ equipped with the remaining fields in e, i.e. ? is instantiated by e
+
+Tactics
+
+- New tactic "ClearBody H" to clear the body of definitions in local context
+- New tactic "Assert H := c" for forward reasoning
+- Slight improvement in naming strategy for NewInduction/NewDestruct
+- Intuition/Tauto do not perform useless unfolding and work up to conversion
+
+Extraction (details in plugins/extraction/CHANGES or documentation)
+
+- Syntax changes: there are no more options inside the extraction commands.
+ New commands for customization and options have been introduced instead.
+- More optimizations on extracted code.
+- Extraction tests are now embedded in 14 user contributions.
+
+Standard library
+
+- In [Relations], Rstar.v and Newman.v now axiom-free.
+- In [Sets], Integers.v now based on nat
+- In [Arith], more lemmas in Min.v, new file Max.v, tail-recursive
+ plus and mult added to Plus.v and Mult.v respectively
+- New directory [Sorting] with a proof of heapsort (dragged from 6.3.1 lib)
+- In [Reals], more lemmas in Rbase.v, new lemmas on square, square root and
+ trigonometric functions (R_sqr.v - Rtrigo.v); a complementary approach
+ and new theorems about continuity and derivability in Ranalysis.v; some
+ properties in plane geometry such as translation, rotation or similarity
+ in Rgeom.v; finite sums and Chasles property in Rsigma.v
+
+Bugs
+
+- Confusion between implicit args of locals and globals of same base name fixed
+- Various incompatibilities wrt inference of "?" in V6.3.1 fixed
+- Implicits in infix section variables bug fixed
+- Known coercions bugs fixed
+
+- Apply "universe anomaly" bug fixed
+- NatRing now working
+- "Discriminate 1", "Injection 1", "Simplify_eq 1" now working
+- NewInduction bugs with let-in and recursively dependent hypotheses fixed
+- Syntax [x:=t:T]u now allowed as mentioned in documentation
+
+- Bug with recursive inductive types involving let-in fixed
+- Known pattern-matching bugs fixed
+- Known Cases elimination predicate bugs fixed
+- Improved errors messages for pattern-matching and projections
+- Better error messages for ill-typed Cases expressions
+
+Incompatibilities
+
+- New naming strategy for NewInduction/NewDestruct may affect 7.1 compatibility
+- Extra parentheses may exceptionally be needed in tactic definitions.
+- Coq extensions written in Ocaml need to be updated (see dev/changements.txt
+ for a description of the main changes in the interface files of V7.2)
+- New behaviour of Intuition/Tauto may exceptionally lead to incompatibilities
+
+----------------------------------------------------------------------------
+Changes from V6.3.1 and V7.0 to V7.1
+====================================
+
+Notes:
+
+- items followed by (**) are important sources of incompatibilities
+- items followed by (*) may exceptionally be sources of incompatibilities
+- items followed by (+) have been introduced in version 7.0
+
+
+Main novelties
+==============
+
+References are to Coq V7.1 reference manual
+
+- New primitive let-in construct (see sections 1.2.8 and )
+- Long names (see sections 2.6 and 2.7)
+- New high-level tactic language (see chapter 10)
+- Improved search facilities (see section 5.2)
+- New extraction algorithm managing the Type level (see chapter 17)
+- New rewriting tactic for arbitrary equalities (see chapter 19)
+- New tactic Field to decide equalities on commutative fields (see 7.11)
+- New tactic Fourier to solve linear inequalities on reals numbers (see 7.11)
+- New tactics for induction/case analysis in "natural" style (see 7.7)
+- Deep restructuration of the code (safer, simpler and more efficient)
+- Export of theories to XML for publishing and rendering purposes
+ (see http://www.cs.unibo.it/helm)
+
+
+Details of changes
+==================
+
+Language: new "let-in" construction
+-----------------------------------
+
+- New construction for local definitions (let-in) with syntax [x:=u]t (*)(+)
+
+- Local definitions allowed in Record (a.k.a. record à la Randy Pollack)
+
+
+Language: long names
+--------------------
+
+- Each construction has a unique absolute names built from a base
+ name, the name of the module in which they are defined (Top if in
+ coqtop), and possibly an arbitrary long sequence of directory (e.g.
+ "Coq.Lists.PolyList.flat_map" where "Coq" means that "flat_map" is part
+ of Coq standard library, "Lists" means it is defined in the Lists
+ library and "PolyList" means it is in the file Polylist) (+)
+
+- Constructions can be referred by their base name, or, in case of
+ conflict, by a "qualified" name, where the base name is prefixed
+ by the module name (and possibly by a directory name, and so
+ on). A fully qualified name is an absolute name which always refer
+ to the construction it denotes (to preserve the visibility of
+ all constructions, no conflict is allowed for an absolute name) (+)
+
+- Long names are available for modules with the possibility of using
+ the directory name as a component of the module full name (with
+ option -R to coqtop and coqc, or command Add LoadPath) (+)
+
+- Improved conflict resolution strategy (the Unix PATH model),
+ allowing more constructions to be referred just by their base name
+
+
+Language: miscellaneous
+-----------------------
+
+- The names of variables for Record projections _and_ for induction principles
+ (e.g. sum_ind) is now based on the first letter of their type (main
+ source of incompatibility) (**)(+)
+
+- Most typing errors have now a precise location in the source (+)
+
+- Slightly different mechanism to solve "?" (*)(+)
+
+- More arguments may be considered implicit at section closing (*)(+)
+
+- Bug with identifiers ended by a number greater than 2^30 fixed (+)
+
+- New visibility discipline for Remark, Fact and Local: Remark's and
+ Fact's now survive at the end of section, but are only accessible using a
+ qualified names as soon as their strength expires; Local's disappear and
+ are moved into local definitions for each construction persistent at
+ section closing
+
+
+Language: Cases
+---------------
+
+- Cases no longer considers aliases inferable from dependencies in types (*)(+)
+
+- A redundant clause in Cases is now an error (*)
+
+
+Reduction
+---------
+
+- New reduction flags "Zeta" and "Evar" in Eval Compute, for inlining of
+ local definitions and instantiation of existential variables
+
+- Delta reduction flag does not perform Zeta and Evar reduction any more (*)
+
+- Constants declared as opaque (using Qed) can no longer become
+ transparent (a constant intended to be alternatively opaque and
+ transparent must be declared as transparent (using Defined)); a risk
+ exists (until next Coq version) that Simpl and Hnf reduces opaque
+ constants (*)
+
+
+New tactics
+-----------
+
+- New set of tactics to deal with types equipped with specific
+ equalities (a.k.a. Setoids, e.g. nat equipped with eq_nat) [by C. Renard]
+
+- New tactic Assert, similar to Cut but expected to be more user-friendly
+
+- New tactic NewDestruct and NewInduction intended to replace Elim
+ and Induction, Case and Destruct in a more user-friendly way (see
+ restrictions in the reference manual)
+
+- New tactic ROmega: an experimental alternative (based on reflexion) to Omega
+ [by P. Crégut]
+
+- New tactic language Ltac (see reference manual) (+)
+
+- New versions of Tauto and Intuition, fully rewritten in the new Ltac
+ language; they run faster and produce more compact proofs; Tauto is
+ fully compatible but, in exchange of a better uniformity, Intuition
+ is slightly weaker (then use Tauto instead) (**)(+)
+
+- New tactic Field to decide equalities on commutative fields (as a
+ special case, it works on real numbers) (+)
+
+- New tactic Fourier to solve linear inequalities on reals numbers
+ [by L. Pottier] (+)
+
+- New tactics dedicated to real numbers: DiscrR, SplitRmult, SplitAbsolu (+)
+
+
+Changes in existing tactics
+---------------------------
+
+- Reduction tactics in local definitions apply only to the body
+
+- New syntax of the form "Compute in Type of H." to require a reduction on
+ the types of local definitions
+
+- Inversion, Injection, Discriminate, ... apply also on the
+ quantified premises of a goal (using the "Intros until" syntax)
+
+- Decompose has been fixed but hypotheses may get different names (*)(+)
+
+- Tauto now manages uniformly hypotheses and conclusions of the form
+ "t=t" which all are considered equivalent to "True". Especially,
+ Tauto now solves goals of the form "H : ~ t = t |- A".
+
+- The "Let" tactic has been renamed "LetTac" and is now based on the
+ primitive "let-in" (+)
+
+- Elim can no longer be used with an elimination schema different from
+ the one defined at definition time of the inductive type. To overload
+ an elimination schema, use "Elim using "
+ (*)(+)
+
+- Simpl no longer unfolds the recursive calls of a mutually defined
+ fixpoint (*)(+)
+
+- Intro now fails if the hypothesis name already exists (*)(+)
+
+- "Require Prolog" is no longer needed (i.e. it is available by default) (*)(+)
+
+- Unfold now fails on a non unfoldable identifier (*)(+)
+
+- Unfold also applies on definitions of the local context
+
+- AutoRewrite now deals only with the main goal and it is the purpose of
+ Hint Rewrite to deal with generated subgoals (+)
+
+- Redundant or incompatible instantiations in Apply ... with ... are now
+ correctly managed (+)
+
+
+Efficiency
+----------
+
+- Excessive memory uses specific to V7.0 fixed
+
+- Sizes of .vo files vary a lot compared to V6.3 (from -30% to +300%
+ depending on the developments)
+
+- An improved reduction strategy for lazy evaluation
+
+- A more economical mechanism to ensure logical consistency at the Type level;
+ warning: this is experimental and may produce "universes" anomalies
+ (please report)
+
+
+Concrete syntax of constructions
+--------------------------------
+
+- Only identifiers starting with "_" or a letter, and followed by letters,
+ digits, "_" or "'" are allowed (e.g. "$" and "@" are no longer allowed) (*)
+
+- A multiple binder like (a:A)(a,b:(P a))(Q a) is no longer parsed as
+ (a:A)(a0:(P a))(b:(P a))(Q a0) but as (a:A)(a0:(P a))(b:(P a0))(Q a0) (*)(+)
+
+- A dedicated syntax has been introduced for Reals (e.g ``3+1/x``) (+)
+
+- Pretty-printing of Infix notations fixed. (+)
+
+
+Parsing and grammar extension
+-----------------------------
+
+- More constraints when writing ast
+
+ - "{...}" and the macros $LIST, $VAR, etc. now expect a metavariable
+ (an identifier starting with $) (*)
+ - identifiers should starts with a letter or "_" and be followed
+ by letters, digits, "_" or "'" (other characters are still
+ supported but it is not advised to use them) (*)(+)
+
+- Entry "command" in "Grammar" and quotations (<<...>> stuff) is
+ renamed "constr" as in "Syntax" (+)
+
+- New syntax "[" sentence_1 ... sentence_n"]." to group sentences (useful
+ for Time and to write grammar rules abbreviating several commands) (+)
+
+- The default parser for actions in the grammar rules (and for
+ patterns in the pretty-printing rules) is now the one associated to
+ the grammar (i.e. vernac, tactic or constr); no need then for
+ quotations as in <:vernac:<...>>; to return an "ast", the grammar
+ must be explicitly typed with tag ": ast" or ": ast list", or if a
+ syntax rule, by using <<...>> in the patterns (expression inside
+ these angle brackets are parsed as "ast"); for grammars other than
+ vernac, tactic or constr, you may explicitly type the action with
+ tags ": constr", ": tactic", or ":vernac" (**)(+)
+
+- Interpretation of names in Grammar rule is now based on long names,
+ which allows to avoid problems (or sometimes tricks;) related to
+ overloaded names (+)
+
+
+New commands
+------------
+
+- New commands "Print XML All", "Show XML Proof", ... to show or
+ export theories to XML to be used with Helm's publishing and rendering
+ tools (see http://www.cs.unibo.it/helm) (by Claudio Sacerdoti Coen) (+)
+
+- New commands to manually set implicit arguments (+)
+
+ - "Implicits ident." to activate the implicit arguments mode just for ident
+ - "Implicits ident [num1 num2 ...]." to explicitly give which
+ arguments have to be considered as implicit
+
+- New SearchPattern/SearchRewrite (by Yves Bertot) (+)
+
+- New commands "Debug on"/"Debug off" to activate/deactivate the tactic
+ language debugger (+)
+
+- New commands to map physical paths to logical paths (+)
+ - Add LoadPath physical_dir as logical_dir
+ - Add Rec LoadPath physical_dir as logical_dir
+
+
+Changes in existing commands
+----------------------------
+
+- Generalization of the usage of qualified identifiers in tactics
+ and commands about globals, e.g. Decompose, Eval Delta;
+ Hints Unfold, Transparent, Require
+
+- Require synchronous with Reset; Require's scope stops at Section ending (*)
+
+- For a module indirectly loaded by a "Require" but not exported,
+ the command "Import module" turns the constructions defined in the
+ module accessible by their short name, and activates the Grammar,
+ Syntax, Hint, ... declared in the module (+)
+
+- The scope of the "Search" command can be restricted to some modules (+)
+
+- Final dot in command (full stop/period) must be followed by a blank
+ (newline, tabulation or whitespace) (+)
+
+- Slight restriction of the syntax for Cbv Delta: if present, option [-myconst]
+ must immediately follow the Delta keyword (*)(+)
+
+- SearchIsos currently not supported
+
+- Add ML Path is now implied by Add LoadPath (+)
+
+- New names for the following commands (+)
+
+ AddPath -> Add LoadPath
+ Print LoadPath -> Print LoadPath
+ DelPath -> Remove LoadPath
+ AddRecPath -> Add Rec LoadPath
+ Print Path -> Print Coercion Paths
+
+ Implicit Arguments On -> Set Implicit Arguments
+ Implicit Arguments Off -> Unset Implicit Arguments
+
+ Begin Silent -> Set Silent
+ End Silent -> Unset Silent.
+
+
+Tools
+-----
+
+- coqtop (+)
+
+ - Two executables: coqtop.byte and coqtop.opt (if supported by the platform)
+ - coqtop is a link to the more efficient executable (coqtop.opt if present)
+ - option -full is obsolete (+)
+
+- do_Makefile renamed into coq_makefile (+)
+
+- New option -R to coqtop and coqc to map a physical directory to a logical
+ one (+)
+
+- coqc no longer needs to create a temporary file
+
+- No more warning if no initialization file .coqrc exists
+
+
+Extraction
+----------
+
+- New algorithm for extraction able to deal with "Type" (+)
+ (by J.-C. Filliâtre and P. Letouzey)
+
+
+Standard library
+----------------
+
+- New library on maps on integers (IntMap, contributed by Jean Goubault)
+
+- New lemmas about integer numbers [ZArith]
+
+- New lemmas and a "natural" syntax for reals [Reals] (+)
+
+- Exc/Error/Value renamed into Option/Some/None (*)
+
+
+New user contributions
+----------------------
+
+- Constructive complex analysis and the Fundamental Theorem of Algebra [FTA]
+ (Herman Geuvers, Freek Wiedijk, Jan Zwanenburg, Randy Pollack,
+ Henk Barendregt, Nijmegen)
+
+- A new axiomatization of ZFC set theory [Functions_in_ZFC]
+ (C. Simpson, Sophia-Antipolis)
+
+- Basic notions of graph theory [GRAPHS-BASICS] (Jean Duprat, Lyon)
+
+- A library for floating-point numbers [Float] (Laurent Théry, Sylvie Boldo,
+ Sophia-Antipolis)
+
+- Formalisation of CTL and TCTL temporal logic [CtlTctl] (Carlos
+ Daniel Luna,Montevideo)
+
+- Specification and verification of the Railroad Crossing Problem
+ in CTL and TCTL [RailroadCrossing] (Carlos Daniel Luna,Montevideo)
+
+- P-automaton and the ABR algorithm [PAutomata]
+ (Christine Paulin, Emmanuel Freund, Orsay)
+
+- Semantics of a subset of the C language [MiniC]
+ (Eduardo Giménez, Emmanuel Ledinot, Suresnes)
+
+- Correctness proofs of the following imperative algorithms:
+ Bresenham line drawing algorithm [Bresenham], Marché's minimal edition
+ distance algorithm [Diff] (Jean-Christophe Filliâtre, Orsay)
+
+- Correctness proofs of Buchberger's algorithm [Buchberger] and RSA
+ cryptographic algorithm [Rsa] (Laurent Théry, Sophia-Antipolis)
+
+- Correctness proof of Stalmarck tautology checker algorithm
+ [Stalmarck] (Laurent Théry, Pierre Letouzey, Sophia-Antipolis)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 213b8773..de7fb918 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -20,17 +20,38 @@ 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 files in [`dev/doc`](/dev/doc) (for example, [debugging.md](/dev/doc/debugging.md)). For further help with the Coq sources, feel free to join the [Coq Gitter chat](https://gitter.im/coq/coq) and ask questions.
+Documentation for getting started with the Coq sources is located in various
+files in [`dev/doc`](dev/doc) (for example, [debugging.md](dev/doc/debugging.md)).
+For further help with the Coq sources, feel free to join
+the [Coq Gitter chat](https://gitter.im/coq/coq) and ask questions.
Please make pull requests against the `master` branch.
-If it's your first significant contribution to Coq (significant means: more than fixing a typo), your pull request should include a commit adding your name to the [`CREDITS`](/CREDITS) file (possibly with the name of your institution / employer if relevant to your contribution, an ORCID if you have one —you may log into https://orcid.org/ using your institutional account to get one—, and the year of your contribution).
+If it's your first significant contribution to Coq (significant means: more
+than fixing a typo), your pull request should include a commit adding your name
+to the [`CREDITS`](CREDITS) file (possibly with the name of your
+institution / employer if relevant to your contribution, an ORCID if you have
+one —you may log into https://orcid.org/ using your institutional account to
+get one—, and the year of your contribution).
+
+It's helpful to run the Coq test suite with `make test-suite` before submitting
+your change. Our CI runs this test suite and lots of other tests, including
+building external Coq developments, on every pull request, but these results
+take significantly longer to come back (on the order of a few hours). Running
+the test suite locally will take somewhere around 10-15 minutes. Refer to
+[`dev/ci/README.md`](dev/ci/README.md#information-for-developers) for more
+information on CI tests, including how to run them on your private branches.
-It's helpful to run the Coq test suite with `make test-suite` before submitting your change. Travis CI runs this test suite and a much larger one including external Coq developments on every pull request, but these results take significantly longer to come back (on the order of a few hours). Running the test suite locally will take somewhere around 10-15 minutes. Refer to [`dev/ci/README.md`](/dev/ci/README.md#information-for-developers) for more information on Travis CI tests.
+If your pull request fixes a bug, please consider adding a regression test as
+well. See [`test-suite/README.md`](test-suite/README.md) for how to do so.
-If your pull request fixes a bug, please consider adding a regression test as well. See [`test-suite/README.md`](/test-suite/README.md) for how to do so.
+If your pull request fixes a critical bug (a bug allowing a proof of `False`),
+please add an entry to [`dev/doc/critical-bugs`](/dev/doc/critical-bugs).
Don't be alarmed if the pull request process takes some time. It can take a few days to get feedback, approval on the final changes, and then a merge. Coq doesn't release new versions very frequently so it can take a few months for your change to land in a released version. That said, you can start using the latest Coq `master` branch to take advantage of all the new features, improvements, and fixes.
@@ -38,13 +59,22 @@ Whitespace discipline (do not indent using tabs, no trailing spaces, text files
Here are a few tags Coq developers may add to your PR and what they mean. In general feedback and requests for you as the pull request author will be in the comments and tags are only used to organize pull requests.
-- [needs: rebase](https://github.com/coq/coq/pulls?utf8=%E2%9C%93&q=is%3Aopen%20is%3Apr%20label%3A%22needs%3A%20rebase%22%20) indicates the PR should be rebased on top of the latest `master` branch. See the [GitHub documentation](https://help.github.com/articles/about-git-rebase/) for a brief introduction to using `git rebase`.
-- [needs: fixing](https://github.com/coq/coq/pulls?q=is%3Aopen+is%3Apr+label%3A%22needs%3A+fixing%22) indicates the PR needs a fix, as discussed in the comments.
-- [needs: testing](https://github.com/coq/coq/pulls?q=is%3Aopen+is%3Apr+label%3A%22needs%3A+testing%22) indicates the PR needs testing. This is often used when testing beyond what the test suite can handle is required. For example, performance benchmarking is currently performed with a different infrastructure. Unless some followup is specifically requested you aren't expected to do this additional testing.
-
-The release manager uses the following filter to know which PRs seem ready for merge. If you are waiting for a PR to be merged, make sure it appears in this list:
-
-- [Pull requests ready for merge](https://github.com/coq/coq/pulls?utf8=%E2%9C%93&q=is%3Apr%20is%3Aopen%20-label%3A%22needs%3A%20discussion%22%20-label%3A%22needs%3A%20testing%22%20-label%3A%22needs%3A%20fixing%22%20-label%3A%22needs%3A%20progress%22%20-label%3A%22needs%3A%20rebase%22%20-label%3A%22needs%3A%20review%22%20-label%3A%22needs%3A%20help%22%20-label%3A%22needs%3A%20independent%20fix%22%20-label%3A%22needs%3A%20feedback%22%20-label%3A%22help%20wanted%22%20-review%3Achanges_requested%20-status%3Apending%20base%3Amaster%20sort%3Aupdated-asc%20-label%3A%22needs%3A%20squashing%22%20)
+- [needs: rebase][rebase-label] indicates the PR should be rebased on top of
+ the latest base branch (usually `master`). See the
+ [GitHub documentation](https://help.github.com/articles/about-git-rebase/)
+ for a brief introduction to using `git rebase`.
+ This label will be automatically added if you open or synchronize your PR and
+ it is not up-to-date with the base branch. So please, do not forget to rebase
+ your branch every time you update it.
+- [needs: fixing][fixing-label] indicates the PR needs a fix, as discussed in the comments.
+- [needs: benchmarking][benchmarking-label] and [needs: testing][testing-label]
+ indicate the PR needs testing beyond what the test suite can handle.
+ For example, performance benchmarking is currently performed with a different
+ infrastructure ([documented in the wiki][jenkins-doc]). Unless some followup
+ is specifically requested you aren't expected to do this additional testing.
+
+To learn more about the merging process, you can read the
+[merging documentation for Coq maintainers](dev/doc/MERGING.md).
## Documentation
@@ -52,10 +82,24 @@ Currently the process for contributing to the documentation is the same as for c
Our issue tracker includes a flag to mark bugs related to documentation. You can view a list of documentation-related bugs using a [GitHub issue search](https://github.com/coq/coq/issues?q=is%3Aopen+is%3Aissue+label%3A%22kind%3A+documentation%22). Many of these bugs can be fixed by contributing writing, without knowledge of Coq's OCaml source code.
-The sources for the [Coq reference manual](https://coq.inria.fr/distrib/current/refman/) are at [`doc/refman`](/doc/refman). These are written in LaTeX and compiled to HTML with [HeVeA](http://hevea.inria.fr/).
+The sources for the [Coq reference manual](https://coq.inria.fr/distrib/current/refman/) are at [`doc/sphinx`](/doc/sphinx). These are written in reStructuredText and compiled to HTML and PDF with [Sphinx](http://www.sphinx-doc.org/).
You may also contribute to the informal documentation available in [Cocorico](https://github.com/coq/coq/wiki) (the Coq wiki), and the [Coq FAQ](https://github.com/coq/coq/wiki/The-Coq-FAQ). Both of these are editable by anyone with a GitHub account.
+## Following the development
+
+If you want to follow the development activity around Coq, you are encouraged
+to subscribe to the [Coqdev mailing list](https://sympa.inria.fr/sympa/info/coqdev).
+This mailing list has reasonably low traffic.
+
+You may also choose to use GitHub feature to
+["watch" this repository](https://github.com/coq/coq/subscription), but be
+advised that this means receiving a very large number of notifications.
+GitHub gives [some advice](https://blog.github.com/2017-07-18-managing-large-numbers-of-github-notifications/#prioritize-the-notifications-you-receive)
+on how to configure your e-mail client to filter these notifications.
+A possible alternative is to deactivate e-mail notifications and manage your
+GitHub web notifications using a tool such as [Octobox](http://octobox.io/).
+
## Contributing outside this repository
There are many useful ways to contribute to the Coq ecosystem that don't involve the Coq repository.
@@ -67,3 +111,10 @@ External plugins / libraries contribute to create a successful ecosystem around
Ask and answer questions on [Stack Exchange](https://stackexchange.com/filters/299857/questions-tagged-coq-on-stackexchange-sites) which has a helpful community of Coq users.
Hang out on the Coq IRC channel, `irc://irc.freenode.net/#coq`, and help answer questions.
+
+[rebase-label]: https://github.com/coq/coq/pulls?utf8=%E2%9C%93&q=is%3Aopen%20is%3Apr%20label%3A%22needs%3A%20rebase%22
+[fixing-label]: https://github.com/coq/coq/pulls?q=is%3Aopen+is%3Apr+label%3A%22needs%3A+fixing%22
+[benchmarking-label]: https://github.com/coq/coq/pulls?q=is%3Aopen+is%3Apr+label%3A%22needs%3A+benchmarking%22
+[testing-label]: https://github.com/coq/coq/pulls?q=is%3Aopen+is%3Apr+label%3A%22needs%3A+testing%22
+
+[jenkins-doc]: https://github.com/coq/coq/wiki/Jenkins-(automated-benchmarking)
diff --git a/CREDITS b/CREDITS
index 7d9dfb49..9c3a93da 100644
--- a/CREDITS
+++ b/CREDITS
@@ -37,8 +37,6 @@ plugins/extraction
developed by Pierre Letouzey (LRI, 2000-2004, PPS, 2005-now)
plugins/firstorder
developed by Pierre Corbineau (LRI, 2003-2008)
-plugins/fourier
- developed by Loïc Pottier (INRIA-Lemme, 2001)
plugins/funind
developed by Pierre Courtieu (INRIA-Lemme, 2003-2004, CNAM, 2006-now),
Julien Forest (INRIA-Everest, 2006, CNAM, 2007-2008, ENSIIE, 2008-now)
@@ -128,6 +126,8 @@ of the Coq Proof assistant during the indicated time:
Matej Košík (INRIA, 2015-2017)
Pierre Letouzey (LRI, 2000-2004, PPS, 2005-2008,
INRIA-PPS then IRIF, 2009-now)
+ Yishuai Li (ORCID: https://orcid.org/0000-0002-5728-5903
+ U. Penn, 2018)
Patrick Loiseleur (Paris Sud, 1997-1999)
Evgeny Makarov (INRIA, 2007)
Gregory Malecha (Harvard University 2013-2015,
diff --git a/INSTALL b/INSTALL
index bb41e490..6e7903a6 100644
--- a/INSTALL
+++ b/INSTALL
@@ -46,8 +46,8 @@ 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 num, camlp5 and lablgtk should be properly registered with
findlib/ocamlfind as Coq's makefile will use it to locate the
diff --git a/INSTALL.doc b/INSTALL.doc
deleted file mode 100644
index f8a08528..00000000
--- a/INSTALL.doc
+++ /dev/null
@@ -1,105 +0,0 @@
- The Coq documentation
- =====================
-
-The Coq documentation includes
-
-- A Reference Manual
-- A Tutorial
-- A document presenting the Coq standard library
-- A list of questions/answers in the FAQ style
-
-The sources of the documents are mainly made of LaTeX code from which
-user-readable PostScript or PDF files, or a user-browsable bunch of
-html files are generated.
-
-Prerequisite
-------------
-
-To produce all the documents, the following tools are needed:
-
- - latex (latex2e)
- - pdflatex
- - dvips
- - bibtex
- - makeindex
- - hevea
- - 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 hevea 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
-Sphinx 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 tutorial
- to produce all formats of the tutorial
-
- make rectutorial
- to produce all formats of the tutorial on recursive types
-
- make faq
- to produce all formats of the FAQ
-
- 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 defauts to /usr/share/doc/coq
-
-
-
diff --git a/INSTALL.ide b/INSTALL.ide
deleted file mode 100644
index c4da8404..00000000
--- 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.3 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//.config/coq/coqiderc under Linux, or
- C:\Documents and Settings\\.config\coq\coqiderc under Windows)
- and replace any occurrence of MOD4 by MOD1.
-
diff --git a/META.coq b/META.coq
deleted file mode 100644
index 30bfdd67..00000000
--- a/META.coq
+++ /dev/null
@@ -1,571 +0,0 @@
-# TODO: Generate automatically with Dune
-
-description = "The Coq Proof Assistant Plugin API"
-version = "8.8"
-
-directory = ""
-requires = "camlp5"
-
-package "config" (
-
- description = "Coq Configuration Variables"
- version = "8.8"
-
- directory = "config"
-
-)
-
-package "clib" (
- description = "Base General Coq Library"
- version = "8.8"
-
- directory = "clib"
- requires = "num, str, unix, threads"
-
- archive(byte) = "clib.cma"
- archive(native) = "clib.cmxa"
-)
-
-package "lib" (
-
- description = "Base Coq-Specific Library"
- version = "8.8"
-
- directory = "lib"
-
- requires = "coq.clib, coq.config"
-
- archive(byte) = "lib.cma"
- archive(native) = "lib.cmxa"
-
-)
-
-package "vm" (
-
- description = "Coq VM"
- version = "8.8"
-
- directory = "kernel/byterun"
-
-# We could generate this file at configure time for the share byte
-# build path to work properly.
-#
-# Enable this setting for local byte builds if you want dynamic linking:
-#
-# linkopts(byte) = "-dllpath path_to_coq/kernel/byterun/ -dllib -lcoqrun"
-
-# We currently prefer static linking of the VM.
- archive(byte) = "libcoqrun.a"
- linkopts(byte) = "-custom"
-
- linkopts(native) = "-cclib -lcoqrun"
-
-)
-
-package "kernel" (
-
- description = "Coq's Kernel"
- version = "8.8"
-
- directory = "kernel"
-
- requires = "dynlink, coq.lib, coq.vm"
-
- archive(byte) = "kernel.cma"
- archive(native) = "kernel.cmxa"
-
-)
-
-package "library" (
-
- description = "Coq Libraries (vo) support"
- version = "8.8"
-
- requires = "coq.kernel"
-
- directory = "library"
-
- archive(byte) = "library.cma"
- archive(native) = "library.cmxa"
-
-)
-
-package "intf" (
-
- description = "Coq Public Data Types"
- version = "8.8"
-
- requires = "coq.library"
-
- directory = "intf"
-
- archive(byte) = "intf.cma"
- archive(native) = "intf.cmxa"
-)
-
-package "engine" (
-
- description = "Coq Tactic Engine"
- version = "8.8"
-
- requires = "coq.library"
- directory = "engine"
-
- archive(byte) = "engine.cma"
- archive(native) = "engine.cmxa"
-
-)
-
-package "pretyping" (
-
- description = "Coq Pretyper"
- version = "8.8"
-
- requires = "coq.engine"
- directory = "pretyping"
-
- archive(byte) = "pretyping.cma"
- archive(native) = "pretyping.cmxa"
-
-)
-
-package "interp" (
-
- description = "Coq Term Interpretation"
- version = "8.8"
-
- requires = "coq.pretyping"
- directory = "interp"
-
- archive(byte) = "interp.cma"
- archive(native) = "interp.cmxa"
-
-)
-
-package "grammar" (
-
- description = "Coq Base Grammar"
- version = "8.8"
-
- requires = "coq.interp"
- directory = "grammar"
-
- archive(byte) = "grammar.cma"
- archive(native) = "grammar.cmxa"
-)
-
-package "proofs" (
-
- description = "Coq Proof Engine"
- version = "8.8"
-
- requires = "coq.interp"
- directory = "proofs"
-
- archive(byte) = "proofs.cma"
- archive(native) = "proofs.cmxa"
-
-)
-
-package "parsing" (
-
- description = "Coq Parsing Engine"
- version = "8.8"
-
- requires = "camlp5.gramlib, coq.proofs"
- directory = "parsing"
-
- archive(byte) = "parsing.cma"
- archive(native) = "parsing.cmxa"
-
-)
-
-package "printing" (
-
- description = "Coq Printing Engine"
- version = "8.8"
-
- requires = "coq.parsing"
- directory = "printing"
-
- archive(byte) = "printing.cma"
- archive(native) = "printing.cmxa"
-
-)
-
-package "tactics" (
-
- description = "Coq Basic Tactics"
- version = "8.8"
-
- requires = "coq.printing"
- directory = "tactics"
-
- archive(byte) = "tactics.cma"
- archive(native) = "tactics.cmxa"
-
-)
-
-package "vernac" (
-
- description = "Coq Vernacular Interpreter"
- version = "8.8"
-
- requires = "coq.tactics"
- directory = "vernac"
-
- archive(byte) = "vernac.cma"
- archive(native) = "vernac.cmxa"
-
-)
-
-package "stm" (
-
- description = "Coq State Transactional Machine"
- version = "8.8"
-
- requires = "coq.vernac"
- directory = "stm"
-
- archive(byte) = "stm.cma"
- archive(native) = "stm.cmxa"
-
-)
-
-package "toplevel" (
-
- description = "Coq Toplevel"
- version = "8.8"
-
- requires = "coq.stm"
- directory = "toplevel"
-
- archive(byte) = "toplevel.cma"
- archive(native) = "toplevel.cmxa"
-
-)
-
-package "idetop" (
-
- description = "Coq IDE Libraries"
- version = "8.8"
-
- requires = "coq.toplevel"
- directory = "ide"
-
- archive(byte) = "coqidetop.cma"
- archive(native) = "coqidetop.cmxa"
-
-)
-
-# XXX Depends on way less than toplevel
-package "ide" (
-
- description = "Coq IDE Libraries"
- version = "8.8"
-
-# XXX Add GTK
- requires = "coq.toplevel"
- directory = "ide"
-
- archive(byte) = "ide.cma"
- archive(native) = "ide.cmxa"
-
-)
-
-package "plugins" (
-
- description = "Coq built-in plugins"
- version = "8.8"
-
- directory = "plugins"
-
- package "ltac" (
-
- description = "Coq LTAC Plugin"
- version = "8.8"
-
- requires = "coq.stm"
- directory = "ltac"
-
- archive(byte) = "ltac_plugin.cmo"
- archive(native) = "ltac_plugin.cmx"
-
- )
-
- package "tauto" (
-
- description = "Coq tauto plugin"
- version = "8.8"
-
- requires = "coq.plugins.ltac"
- directory = "ltac"
-
- archive(byte) = "tauto_plugin.cmo"
- archive(native) = "tauto_plugin.cmx"
- )
-
- package "omega" (
-
- description = "Coq omega plugin"
- version = "8.8"
-
- requires = "coq.plugins.ltac"
- directory = "omega"
-
- archive(byte) = "omega_plugin.cmo"
- archive(native) = "omega_plugin.cmx"
- )
-
- package "romega" (
-
- description = "Coq romega plugin"
- version = "8.8"
-
- requires = "coq.plugins.omega"
- directory = "romega"
-
- archive(byte) = "romega_plugin.cmo"
- archive(native) = "romega_plugin.cmx"
- )
-
- package "micromega" (
-
- description = "Coq micromega plugin"
- version = "8.8"
-
- requires = "num,coq.plugins.ltac"
- directory = "micromega"
-
- archive(byte) = "micromega_plugin.cmo"
- archive(native) = "micromega_plugin.cmx"
- )
-
- package "quote" (
-
- description = "Coq quote plugin"
- version = "8.8"
-
- requires = "coq.plugins.ltac"
- directory = "quote"
-
- archive(byte) = "quote_plugin.cmo"
- archive(native) = "quote_plugin.cmx"
- )
-
- package "newring" (
-
- description = "Coq newring plugin"
- version = "8.8"
-
- requires = "coq.plugins.quote"
- directory = "setoid_ring"
-
- archive(byte) = "newring_plugin.cmo"
- archive(native) = "newring_plugin.cmx"
- )
-
- package "fourier" (
-
- description = "Coq fourier plugin"
- version = "8.8"
-
- requires = "coq.plugins.ltac"
- directory = "fourier"
-
- archive(byte) = "fourier_plugin.cmo"
- archive(native) = "fourier_plugin.cmx"
- )
-
- package "extraction" (
-
- description = "Coq extraction plugin"
- version = "8.8"
-
- requires = "coq.plugins.ltac"
- directory = "extraction"
-
- archive(byte) = "extraction_plugin.cmo"
- archive(native) = "extraction_plugin.cmx"
- )
-
- package "cc" (
-
- description = "Coq cc plugin"
- version = "8.8"
-
- requires = "coq.plugins.ltac"
- directory = "cc"
-
- archive(byte) = "cc_plugin.cmo"
- archive(native) = "cc_plugin.cmx"
- )
-
- package "ground" (
-
- description = "Coq ground plugin"
- version = "8.8"
-
- requires = "coq.plugins.ltac"
- directory = "firstorder"
-
- archive(byte) = "ground_plugin.cmo"
- archive(native) = "ground_plugin.cmx"
- )
-
- package "rtauto" (
-
- description = "Coq rtauto plugin"
- version = "8.8"
-
- requires = "coq.plugins.ltac"
- directory = "rtauto"
-
- archive(byte) = "rtauto_plugin.cmo"
- archive(native) = "rtauto_plugin.cmx"
- )
-
- package "btauto" (
-
- description = "Coq btauto plugin"
- version = "8.8"
-
- requires = "coq.plugins.ltac"
- directory = "btauto"
-
- archive(byte) = "btauto_plugin.cmo"
- archive(native) = "btauto_plugin.cmx"
- )
-
- package "recdef" (
-
- description = "Coq recdef plugin"
- version = "8.8"
-
- requires = "coq.plugins.extraction"
- directory = "funind"
-
- archive(byte) = "recdef_plugin.cmo"
- archive(native) = "recdef_plugin.cmx"
- )
-
- package "nsatz" (
-
- description = "Coq nsatz plugin"
- version = "8.8"
-
- requires = "num,coq.plugins.ltac"
- directory = "nsatz"
-
- archive(byte) = "nsatz_plugin.cmo"
- archive(native) = "nsatz_plugin.cmx"
- )
-
- package "natsyntax" (
-
- description = "Coq natsyntax plugin"
- version = "8.8"
-
- requires = ""
- directory = "syntax"
-
- archive(byte) = "nat_syntax_plugin.cmo"
- archive(native) = "nat_syntax_plugin.cmx"
- )
-
- package "zsyntax" (
-
- description = "Coq zsyntax plugin"
- version = "8.8"
-
- requires = ""
- directory = "syntax"
-
- archive(byte) = "z_syntax_plugin.cmo"
- archive(native) = "z_syntax_plugin.cmx"
- )
-
- package "rsyntax" (
-
- description = "Coq rsyntax plugin"
- version = "8.8"
-
- requires = ""
- directory = "syntax"
-
- archive(byte) = "r_syntax_plugin.cmo"
- archive(native) = "r_syntax_plugin.cmx"
- )
-
- package "int31syntax" (
-
- description = "Coq int31syntax plugin"
- version = "8.8"
-
- requires = ""
- directory = "syntax"
-
- archive(byte) = "int31_syntax_plugin.cmo"
- archive(native) = "int31_syntax_plugin.cmx"
- )
-
- package "asciisyntax" (
-
- description = "Coq asciisyntax plugin"
- version = "8.8"
-
- requires = ""
- directory = "syntax"
-
- archive(byte) = "ascii_syntax_plugin.cmo"
- archive(native) = "ascii_syntax_plugin.cmx"
- )
-
- package "stringsyntax" (
-
- description = "Coq stringsyntax plugin"
- version = "8.8"
-
- requires = "coq.plugins.asciisyntax"
- directory = "syntax"
-
- archive(byte) = "string_syntax_plugin.cmo"
- archive(native) = "string_syntax_plugin.cmx"
- )
-
- package "derive" (
-
- description = "Coq derive plugin"
- version = "8.8"
-
- requires = ""
- directory = "derive"
-
- archive(byte) = "derive_plugin.cmo"
- archive(native) = "derive_plugin.cmx"
- )
-
- package "ssrmatching" (
-
- description = "Coq ssrmatching plugin"
- version = "8.8"
-
- requires = "coq.plugins.ltac"
- directory = "ssrmatching"
-
- archive(byte) = "ssrmatching_plugin.cmo"
- archive(native) = "ssrmatching_plugin.cmx"
- )
-
- package "ssreflect" (
-
- description = "Coq ssreflect plugin"
- version = "8.8"
-
- requires = "coq.plugins.ssrmatching"
- directory = "ssr"
-
- archive(byte) = "ssreflect_plugin.cmo"
- archive(native) = "ssreflect_plugin.cmx"
- )
-)
diff --git a/META.coq.in b/META.coq.in
new file mode 100644
index 00000000..b2924e32
--- /dev/null
+++ b/META.coq.in
@@ -0,0 +1,543 @@
+# TODO: Generate automatically with Dune
+
+description = "The Coq Proof Assistant Plugin API"
+version = "8.9"
+
+directory = ""
+requires = "camlp5"
+
+package "grammar" (
+
+ description = "Coq Camlp5 Grammar Extensions for Plugins"
+ version = "8.9"
+
+ requires = "camlp5.gramlib"
+ directory = "grammar"
+
+ archive(byte) = "grammar.cma"
+ archive(native) = "grammar.cmxa"
+)
+
+package "config" (
+
+ description = "Coq Configuration Variables"
+ version = "8.9"
+
+ directory = "config"
+
+)
+
+package "clib" (
+ description = "Base General Coq Library"
+ version = "8.9"
+
+ directory = "clib"
+ requires = "num, str, unix, threads"
+
+ archive(byte) = "clib.cma"
+ archive(native) = "clib.cmxa"
+)
+
+package "lib" (
+
+ description = "Base Coq-Specific Library"
+ version = "8.9"
+
+ directory = "lib"
+
+ requires = "coq.clib, coq.config"
+
+ archive(byte) = "lib.cma"
+ archive(native) = "lib.cmxa"
+
+)
+
+package "vm" (
+
+ description = "Coq VM"
+ version = "8.9"
+
+ directory = "kernel/byterun"
+
+# We could generate this file at configure time for the share byte
+# build path to work properly.
+#
+# Enable this setting for local byte builds if you want dynamic linking:
+#
+# linkopts(byte) = "-dllpath path_to_coq/kernel/byterun/ -dllib -lcoqrun"
+
+# We currently prefer static linking of the VM.
+ archive(byte) = "libcoqrun.a"
+ linkopts(byte) = "-custom"
+)
+
+package "kernel" (
+
+ description = "Coq's Kernel"
+ version = "8.9"
+
+ directory = "kernel"
+
+ requires = "dynlink, coq.lib, coq.vm"
+
+ archive(byte) = "kernel.cma"
+ archive(native) = "kernel.cmxa"
+
+)
+
+package "library" (
+
+ description = "Coq Libraries (vo) support"
+ version = "8.9"
+
+ requires = "coq.kernel"
+
+ directory = "library"
+
+ archive(byte) = "library.cma"
+ archive(native) = "library.cmxa"
+
+)
+
+package "engine" (
+
+ description = "Coq Tactic Engine"
+ version = "8.9"
+
+ requires = "coq.library"
+ directory = "engine"
+
+ archive(byte) = "engine.cma"
+ archive(native) = "engine.cmxa"
+
+)
+
+package "pretyping" (
+
+ description = "Coq Pretyper"
+ version = "8.9"
+
+ requires = "coq.engine"
+ directory = "pretyping"
+
+ archive(byte) = "pretyping.cma"
+ archive(native) = "pretyping.cmxa"
+
+)
+
+package "interp" (
+
+ description = "Coq Term Interpretation"
+ version = "8.9"
+
+ requires = "coq.pretyping"
+ directory = "interp"
+
+ archive(byte) = "interp.cma"
+ archive(native) = "interp.cmxa"
+
+)
+
+package "proofs" (
+
+ description = "Coq Proof Engine"
+ version = "8.9"
+
+ requires = "coq.interp"
+ directory = "proofs"
+
+ archive(byte) = "proofs.cma"
+ archive(native) = "proofs.cmxa"
+
+)
+
+package "parsing" (
+
+ description = "Coq Parsing Engine"
+ version = "8.9"
+
+ requires = "camlp5.gramlib, coq.proofs"
+ directory = "parsing"
+
+ archive(byte) = "parsing.cma"
+ archive(native) = "parsing.cmxa"
+
+)
+
+package "printing" (
+
+ description = "Coq Printing Engine"
+ version = "8.9"
+
+ requires = "coq.parsing"
+ directory = "printing"
+
+ archive(byte) = "printing.cma"
+ archive(native) = "printing.cmxa"
+
+)
+
+package "tactics" (
+
+ description = "Coq Basic Tactics"
+ version = "8.9"
+
+ requires = "coq.printing"
+ directory = "tactics"
+
+ archive(byte) = "tactics.cma"
+ archive(native) = "tactics.cmxa"
+
+)
+
+package "vernac" (
+
+ description = "Coq Vernacular Interpreter"
+ version = "8.9"
+
+ requires = "coq.tactics"
+ directory = "vernac"
+
+ archive(byte) = "vernac.cma"
+ archive(native) = "vernac.cmxa"
+
+)
+
+package "stm" (
+
+ description = "Coq State Transactional Machine"
+ version = "8.9"
+
+ requires = "coq.vernac"
+ directory = "stm"
+
+ archive(byte) = "stm.cma"
+ archive(native) = "stm.cmxa"
+
+)
+
+package "toplevel" (
+
+ description = "Coq Toplevel"
+ version = "8.9"
+
+ requires = "coq.stm"
+ directory = "toplevel"
+
+ archive(byte) = "toplevel.cma"
+ archive(native) = "toplevel.cmxa"
+
+)
+
+package "idetop" (
+
+ description = "Coq IDE Libraries"
+ version = "8.9"
+
+ requires = "coq.toplevel"
+ directory = "ide"
+
+ archive(byte) = "coqidetop.cma"
+ archive(native) = "coqidetop.cmxa"
+
+)
+
+# XXX Depends on way less than toplevel
+package "ide" (
+
+ description = "Coq IDE Libraries"
+ version = "8.9"
+
+# XXX Add GTK
+ requires = "coq.toplevel"
+ directory = "ide"
+
+ archive(byte) = "ide.cma"
+ archive(native) = "ide.cmxa"
+
+)
+
+package "plugins" (
+
+ description = "Coq built-in plugins"
+ version = "8.9"
+
+ directory = "plugins"
+
+ package "ltac" (
+
+ description = "Coq LTAC Plugin"
+ version = "8.9"
+
+ requires = "coq.stm"
+ directory = "ltac"
+
+ archive(byte) = "ltac_plugin.cmo"
+ archive(native) = "ltac_plugin.cmx"
+
+ )
+
+ package "tauto" (
+
+ description = "Coq tauto plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.ltac"
+ directory = "ltac"
+
+ archive(byte) = "tauto_plugin.cmo"
+ archive(native) = "tauto_plugin.cmx"
+ )
+
+ package "omega" (
+
+ description = "Coq omega plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.ltac"
+ directory = "omega"
+
+ archive(byte) = "omega_plugin.cmo"
+ archive(native) = "omega_plugin.cmx"
+ )
+
+ package "romega" (
+
+ description = "Coq romega plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.omega"
+ directory = "romega"
+
+ archive(byte) = "romega_plugin.cmo"
+ archive(native) = "romega_plugin.cmx"
+ )
+
+ package "micromega" (
+
+ description = "Coq micromega plugin"
+ version = "8.9"
+
+ requires = "num,coq.plugins.ltac"
+ directory = "micromega"
+
+ archive(byte) = "micromega_plugin.cmo"
+ archive(native) = "micromega_plugin.cmx"
+ )
+
+ package "quote" (
+
+ description = "Coq quote plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.ltac"
+ directory = "quote"
+
+ archive(byte) = "quote_plugin.cmo"
+ archive(native) = "quote_plugin.cmx"
+ )
+
+ package "newring" (
+
+ description = "Coq newring plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.quote"
+ directory = "setoid_ring"
+
+ archive(byte) = "newring_plugin.cmo"
+ archive(native) = "newring_plugin.cmx"
+ )
+
+ package "extraction" (
+
+ description = "Coq extraction plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.ltac"
+ directory = "extraction"
+
+ archive(byte) = "extraction_plugin.cmo"
+ archive(native) = "extraction_plugin.cmx"
+ )
+
+ package "cc" (
+
+ description = "Coq cc plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.ltac"
+ directory = "cc"
+
+ archive(byte) = "cc_plugin.cmo"
+ archive(native) = "cc_plugin.cmx"
+ )
+
+ package "ground" (
+
+ description = "Coq ground plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.ltac"
+ directory = "firstorder"
+
+ archive(byte) = "ground_plugin.cmo"
+ archive(native) = "ground_plugin.cmx"
+ )
+
+ package "rtauto" (
+
+ description = "Coq rtauto plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.ltac"
+ directory = "rtauto"
+
+ archive(byte) = "rtauto_plugin.cmo"
+ archive(native) = "rtauto_plugin.cmx"
+ )
+
+ package "btauto" (
+
+ description = "Coq btauto plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.ltac"
+ directory = "btauto"
+
+ archive(byte) = "btauto_plugin.cmo"
+ archive(native) = "btauto_plugin.cmx"
+ )
+
+ package "recdef" (
+
+ description = "Coq recdef plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.extraction"
+ directory = "funind"
+
+ archive(byte) = "recdef_plugin.cmo"
+ archive(native) = "recdef_plugin.cmx"
+ )
+
+ package "nsatz" (
+
+ description = "Coq nsatz plugin"
+ version = "8.9"
+
+ requires = "num,coq.plugins.ltac"
+ directory = "nsatz"
+
+ archive(byte) = "nsatz_plugin.cmo"
+ archive(native) = "nsatz_plugin.cmx"
+ )
+
+ package "natsyntax" (
+
+ description = "Coq natsyntax plugin"
+ version = "8.9"
+
+ requires = ""
+ directory = "syntax"
+
+ archive(byte) = "nat_syntax_plugin.cmo"
+ archive(native) = "nat_syntax_plugin.cmx"
+ )
+
+ package "zsyntax" (
+
+ description = "Coq zsyntax plugin"
+ version = "8.9"
+
+ requires = ""
+ directory = "syntax"
+
+ archive(byte) = "z_syntax_plugin.cmo"
+ archive(native) = "z_syntax_plugin.cmx"
+ )
+
+ package "rsyntax" (
+
+ description = "Coq rsyntax plugin"
+ version = "8.9"
+
+ requires = ""
+ directory = "syntax"
+
+ archive(byte) = "r_syntax_plugin.cmo"
+ archive(native) = "r_syntax_plugin.cmx"
+ )
+
+ package "int31syntax" (
+
+ description = "Coq int31syntax plugin"
+ version = "8.9"
+
+ requires = ""
+ directory = "syntax"
+
+ archive(byte) = "int31_syntax_plugin.cmo"
+ archive(native) = "int31_syntax_plugin.cmx"
+ )
+
+ package "asciisyntax" (
+
+ description = "Coq asciisyntax plugin"
+ version = "8.9"
+
+ requires = ""
+ directory = "syntax"
+
+ archive(byte) = "ascii_syntax_plugin.cmo"
+ archive(native) = "ascii_syntax_plugin.cmx"
+ )
+
+ package "stringsyntax" (
+
+ description = "Coq stringsyntax plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.asciisyntax"
+ directory = "syntax"
+
+ archive(byte) = "string_syntax_plugin.cmo"
+ archive(native) = "string_syntax_plugin.cmx"
+ )
+
+ package "derive" (
+
+ description = "Coq derive plugin"
+ version = "8.9"
+
+ requires = ""
+ directory = "derive"
+
+ archive(byte) = "derive_plugin.cmo"
+ archive(native) = "derive_plugin.cmx"
+ )
+
+ package "ssrmatching" (
+
+ description = "Coq ssrmatching plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.ltac"
+ directory = "ssrmatching"
+
+ archive(byte) = "ssrmatching_plugin.cmo"
+ archive(native) = "ssrmatching_plugin.cmx"
+ )
+
+ package "ssreflect" (
+
+ description = "Coq ssreflect plugin"
+ version = "8.9"
+
+ requires = "coq.plugins.ssrmatching"
+ directory = "ssr"
+
+ archive(byte) = "ssreflect_plugin.cmo"
+ archive(native) = "ssreflect_plugin.cmx"
+ )
+)
diff --git a/Makefile b/Makefile
index 86ff596a..aa214d18 100644
--- a/Makefile
+++ b/Makefile
@@ -58,7 +58,7 @@ FIND_SKIP_DIRS:='(' \
-name '_build_ci' -o \
-name '_install_ci' -o \
-name 'user-contrib' -o \
- -name 'coq-makefile' -o \
+ -name 'test-suite' -o \
-name '.opamcache' -o \
-name '.coq-native' \
')' -prune -o
@@ -74,11 +74,15 @@ 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')
+
+MERLININFILES := $(call find, '.merlin.in')
+export MERLINFILES := $(MERLININFILES:.in=)
# NB: The lists of currently existing .ml and .mli files will change
# before and after a build or a make clean. Hence we do not export
@@ -90,7 +94,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 +105,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
@@ -111,7 +116,7 @@ include Makefile.common
NOARG: world
-.PHONY: NOARG help noconfig submake
+.PHONY: NOARG help noconfig submake camldevfiles
help:
@echo "Please use either:"
@@ -138,46 +143,13 @@ Then, you may want to consider whether you want to restore the autosaves)
#run.
endif
-# Check that every compiled file around has a known source file.
-# This should help preventing weird compilation failures caused by leftover
-# compiled files after deleting or moving some source files.
-
-EXISTINGVO:=$(call find, '*.vo')
-KNOWNVO:=$(patsubst %.v,%.vo,$(call find, '*.v'))
-ALIENVO:=$(filter-out $(KNOWNVO),$(EXISTINGVO))
-
-EXISTINGOBJS:=$(call find, '*.cm[oxia]' -o -name '*.cmxa')
-KNOWNML:=$(EXISTINGML) $(GENMLFILES) $(GENML4FILES) $(MLPACKFILES:.mlpack=.ml) \
- $(patsubst %.mlp,%.ml,$(wildcard grammar/*.mlp))
-KNOWNOBJS:=$(KNOWNML:.ml=.cmo) $(KNOWNML:.ml=.cmx) $(KNOWNML:.ml=.cmi) \
- $(MLIFILES:.mli=.cmi) \
- $(MLLIBFILES:.mllib=.cma) $(MLLIBFILES:.mllib=.cmxa) grammar/grammar.cma
-ALIENOBJS:=$(filter-out $(KNOWNOBJS),$(EXISTINGOBJS))
-
-ifeq (,$(findstring clean,$(MAKECMDGOALS))) # Skip this for 'make clean' and alii
-ifndef ACCEPT_ALIEN_VO
-ifdef ALIENVO
-$(error Leftover compiled Coq files without known sources: $(ALIENVO); \
-remove them first, for instance via 'make voclean' or 'make alienclean' \
-(or skip this check via 'make ACCEPT_ALIEN_VO=1'))
-endif
-endif
-
-ifndef ACCEPT_ALIEN_OBJ
-ifdef ALIENOBJS
-$(error Leftover compiled OCaml files without known sources: $(ALIENOBJS); \
-remove them first, for instance via 'make clean' or 'make alienclean' \
-(or skip this check via 'make ACCEPT_ALIEN_OBJ=1'))
-endif
-endif
-endif
-
-# Apart from clean and tags, everything will be done in a sub-call to make
-# on Makefile.build. This way, we avoid doing here the -include of .d :
-# since they trigger some compilations, we do not want them for a mere clean.
-# Moreover, we regroup this sub-call in a common target named 'submake'.
-# This way, multiple user-given goals (cf the MAKECMDGOALS variable) won't
-# trigger multiple (possibly parallel) make sub-calls
+# Apart from clean and a few misc files, everything will be done in a
+# sub-call to make on Makefile.build. This way, we avoid doing here
+# the -include of .d : since they trigger some compilations, we do not
+# want them for a mere clean. Moreover, we regroup this sub-call in a
+# common target named 'submake'. This way, multiple user-given goals
+# (cf the MAKECMDGOALS variable) won't trigger multiple (possibly
+# parallel) make sub-calls
ifdef COQ_CONFIGURED
%:: submake ;
@@ -187,7 +159,10 @@ endif
MAKE_OPTS := --warn-undefined-variable --no-builtin-rules
-submake:
+bin:
+ mkdir bin
+
+submake: alienclean camldevfiles | bin
$(MAKE) $(MAKE_OPTS) -f Makefile.build $(MAKECMDGOALS)
noconfig:
@@ -197,13 +172,30 @@ noconfig:
Makefile $(wildcard Makefile.*) config/Makefile : ;
+###########################################################################
+# OCaml dev files
+###########################################################################
+camldevfiles: $(MERLINFILES) META.coq
+
+# prevent submake dependency
+META.coq.in $(MERLININFILES): ;
+
+.merlin: .merlin.in
+ cp -a "$<" "$@"
+
+%/.merlin: %/.merlin.in
+ cp -a "$<" "$@"
+
+META.coq: META.coq.in
+ cp -a "$<" "$@"
+
###########################################################################
# Cleaning
###########################################################################
.PHONY: clean cleankeepvo objclean cruftclean indepclean docclean archclean optclean clean-ide ml4clean depclean cleanconfig distclean voclean timingclean devdocclean alienclean
-clean: objclean cruftclean depclean docclean devdocclean
+clean: objclean cruftclean depclean docclean devdocclean camldevfilesclean
cleankeepvo: indepclean clean-ide optclean cruftclean depclean docclean devdocclean
@@ -213,14 +205,16 @@ cruftclean: ml4clean
find . -name '*~' -o -name '*.annot' | xargs rm -f
rm -f gmon.out core
+camldevfilesclean:
+ rm -f $(MERLINFILES) META.coq
+
indepclean:
rm -f $(GENFILES)
- rm -f $(COQTOPBYTE) $(CHICKENBYTE)
+ rm -f $(COQTOPBYTE) $(CHICKENBYTE) $(TOPBYTE)
find . \( -name '*~' -o -name '*.cm[ioat]' -o -name '*.cmti' \) -delete
rm -f */*.pp[iox] plugins/*/*.pp[iox]
rm -rf $(SOURCEDOCDIR)
rm -f toplevel/mltop.byteml toplevel/mltop.optml
- rm -f test-suite/check.log
rm -f glob.dump
rm -f config/revision.ml revision
rm -f plugins/micromega/.micromega.ml.generated
@@ -246,7 +240,7 @@ archclean: clean-ide optclean voclean
rm -f $(ALLSTDLIB).*
optclean:
- rm -f $(COQTOPEXE) $(CHICKEN)
+ 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
@@ -258,7 +252,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
@@ -284,6 +278,22 @@ devdocclean:
rm -f $(OCAMLDOCDIR)/ocamldoc.sty $(OCAMLDOCDIR)/coq.tex
rm -f $(OCAMLDOCDIR)/html/*.html
+# Ensure that every compiled file around has a known source file.
+# This should help preventing weird compilation failures caused by leftover
+# compiled files after deleting or moving some source files.
+
+EXISTINGVO:=$(call find, '*.vo')
+KNOWNVO:=$(patsubst %.v,%.vo,$(call find, '*.v'))
+ALIENVO:=$(filter-out $(KNOWNVO),$(EXISTINGVO))
+
+EXISTINGOBJS:=$(call find, '*.cm[oxia]' -o -name '*.cmxa')
+KNOWNML:=$(EXISTINGML) $(GENMLFILES) $(GENML4FILES) $(MLPACKFILES:.mlpack=.ml) \
+ $(patsubst %.mlp,%.ml,$(wildcard grammar/*.mlp))
+KNOWNOBJS:=$(KNOWNML:.ml=.cmo) $(KNOWNML:.ml=.cmx) $(KNOWNML:.ml=.cmi) \
+ $(MLIFILES:.mli=.cmi) \
+ $(MLLIBFILES:.mllib=.cma) $(MLLIBFILES:.mllib=.cmxa) grammar/grammar.cma
+ALIENOBJS:=$(filter-out $(KNOWNOBJS),$(EXISTINGOBJS))
+
alienclean:
rm -f $(ALIENOBJS) $(ALIENVO)
diff --git a/Makefile.build b/Makefile.build
index ffe60575..c100eda4 100644
--- a/Makefile.build
+++ b/Makefile.build
@@ -89,6 +89,7 @@ byte: coqbyte coqide-byte pluginsbyte printers
MLFILES := $(MLSTATICFILES) $(GENMLFILES) $(ML4FILES:.ml4=.ml)
include Makefile.common
+include Makefile.vofiles
include Makefile.doc ## provides the 'documentation' rule
include Makefile.checker
include Makefile.ide ## provides the 'coqide' rule
@@ -194,7 +195,7 @@ TIMER=$(if $(TIMED), $(STDTIME), $(TIMECMD))
# the output format of the unix command time. For instance:
# TIME="%C (%U user, %S sys, %e total, %M maxres)"
-COQOPTS=$(NATIVECOMPUTE)
+COQOPTS=$(NATIVECOMPUTE) $(COQWARNERROR)
BOOTCOQC=$(TIMER) $(COQTOPBEST) -boot $(COQOPTS) -compile
LOCALINCLUDES=$(addprefix -I ,$(SRCDIRS))
@@ -205,15 +206,23 @@ OCAMLOPT := $(OCAMLFIND) opt $(CAMLFLAGS)
BYTEFLAGS=$(CAMLDEBUG) $(USERFLAGS)
OPTFLAGS=$(CAMLDEBUGOPT) $(CAMLTIMEPROF) $(USERFLAGS) $(FLAMBDA_FLAGS)
-DEPFLAGS=$(LOCALINCLUDES)$(if $(filter plugins/%,$@),, -I ide -I ide/utils)
+DEPFLAGS=$(LOCALINCLUDES)$(if $(filter plugins/%,$@),, -I ide -I ide/protocol)
# On MacOS, the binaries are signed, except our private ones
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
@@ -240,6 +249,10 @@ $(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) $(LINKMETADATA) -o $@ -linkpkg $(1) $^ &&
$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $(CUSTOM) -o $@ -linkpkg $(1) $^)
endef
+define ocamlbyte
+$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $(CUSTOM) -o $@ -linkpkg $(1) $^
+endef
+
# Camlp5 settings
CAMLP5DEPS:=grammar/grammar.cma
@@ -337,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 := $(addsuffix .cmo, $(addprefix coqpp/, coqpp_parse coqpp_lex))
grammar/argextend.cmo : $(GRAMBASEDEPS)
grammar/q_util.cmo : $(GRAMBASEDEPS)
@@ -344,6 +358,10 @@ grammar/tacextend.cmo : $(GRAMBASEDEPS) grammar/argextend.cmo
grammar/vernacextend.cmo : $(GRAMBASEDEPS) grammar/tacextend.cmo \
grammar/argextend.cmo
+coqpp/coqpp_parse.cmi: coqpp/coqpp_ast.cmi
+coqpp/coqpp_parse.cmo: coqpp/coqpp_ast.cmi coqpp/coqpp_parse.cmi
+coqpp/coqpp_lex.cmo: coqpp/coqpp_ast.cmi coqpp/coqpp_parse.cmo
+
## Ocaml compiler with the right options and -I for grammar
GRAMC := $(OCAMLFIND) ocamlc $(CAMLFLAGS) $(CAMLDEBUG) $(USERFLAGS) \
@@ -354,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 $@
+$(COQPP): $(COQPPCMO) coqpp/coqpp_main.ml
+ $(SHOW)'OCAMLC -a $@'
+ $(HIDE)$(GRAMC) -I coqpp $^ -linkall -o $@
+
## Support of Camlp5 and Camlp5
COMPATCMO:=
@@ -371,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 $<
@@ -382,29 +408,34 @@ grammar/%.cmi: grammar/%.mli
.PHONY: coqbinaries coqbyte
-coqbinaries: $(COQTOPEXE) $(CHICKEN) $(CSDPCERT) $(FAKEIDE)
-
-coqbyte: $(COQTOPBYTE) $(CHICKENBYTE)
+coqbinaries: $(TOPBINOPT) $(COQTOPEXE) $(CHICKEN) $(CSDPCERT) $(FAKEIDE)
+coqbyte: $(TOPBYTE) $(CHICKENBYTE)
-COQTOP_OPT=toplevel/coqtop_opt_bin.ml
-COQTOP_BYTE=toplevel/coqtop_byte_bin.ml
+# Special rule for coqtop, we imitate `ocamlopt` can delete the target
+# to avoid #7666
+$(COQTOPEXE): $(TOPBINOPT:.opt=.$(BEST))
+ rm -f $@ && cp $< $@
-ifeq ($(BEST),opt)
-$(COQTOPEXE): $(LINKCMX) $(LIBCOQRUN) $(TOPLOOPCMA:.cma=.cmxs) $(COQTOP_OPT)
+bin/%.opt$(EXE): topbin/%_bin.ml $(LINKCMX) $(LIBCOQRUN)
$(SHOW)'COQMKTOP -o $@'
- $(HIDE)$(OCAMLOPT) -linkall -linkpkg -I vernac -I toplevel \
- -I kernel/byterun/ -cclib -lcoqrun \
+ $(HIDE)$(OCAMLOPT) -linkall -linkpkg $(MLINCLUDES) \
$(SYSMOD) -package camlp5.gramlib \
- $(LINKCMX) $(OPTFLAGS) $(LINKMETADATA) $(COQTOP_OPT) -o $@
- $(STRIP) $@
- $(CODESIGN) $@
-else
-$(COQTOPEXE): $(COQTOPBYTE)
- cp $< $@
-endif
+ $(LINKCMX) $(OPTFLAGS) $(LINKMETADATA) $< -o $@
+ $(STRIP_HIDE) $@
+ $(CODESIGN_HIDE) $@
+
+bin/%.byte$(EXE): topbin/%_bin.ml $(LINKCMO) $(LIBCOQRUN)
+ $(SHOW)'COQMKTOP -o $@'
+ $(HIDE)$(OCAMLC) -linkall -linkpkg $(MLINCLUDES) \
+ -I kernel/byterun/ -cclib -lcoqrun $(VMBYTEFLAGS) \
+ $(SYSMOD) -package camlp5.gramlib \
+ $(LINKCMO) $(BYTEFLAGS) $< -o $@
+
+COQTOP_BYTE=topbin/coqtop_byte_bin.ml
+# Special rule for coqtop.byte
# VMBYTEFLAGS will either contain -custom of the right -dllpath for the VM
-$(COQTOPBYTE): $(LINKCMO) $(LIBCOQRUN) $(TOPLOOPCMA) $(COQTOP_BYTE)
+$(COQTOPBYTE): $(LINKCMO) $(LIBCOQRUN) $(COQTOP_BYTE)
$(SHOW)'COQMKTOP -o $@'
$(HIDE)$(OCAMLC) -linkall -linkpkg -I lib -I vernac -I toplevel \
-I kernel/byterun/ -cclib -lcoqrun $(VMBYTEFLAGS) \
@@ -418,6 +449,10 @@ $(COQC): $(call bestobj, $(COQCCMO))
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, $(SYSMOD))
+$(COQCBYTE): $(COQCCMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, $(SYSMOD))
+
###########################################################################
# other tools
###########################################################################
@@ -455,10 +490,18 @@ $(COQDEPBOOT): $(call bestobj, $(COQDEPBOOTSRC))
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, -I tools -package unix)
+$(COQDEPBOOTBYTE): $(COQDEPBOOTSRC)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -I tools -package unix)
+
$(OCAMLLIBDEP): $(call bestobj, tools/ocamllibdep.cmo)
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, -I tools -package unix)
+$(OCAMLLIBDEPBYTE): tools/ocamllibdep.cmo
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call ocamlbyte, -I tools -package unix)
+
# The full coqdep (unused by this build, but distributed by make install)
COQDEPCMO:=clib/clib.cma lib/lib.cma tools/coqdep_lexer.cmo \
@@ -468,24 +511,36 @@ $(COQDEP): $(call bestobj, $(COQDEPCMO))
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, $(SYSMOD))
-$(GALLINA): $(call bestobj, tools/gallina_lexer.cmo tools/gallina.cmo)
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,)
+$(COQDEPBYTE): $(COQDEPCMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, $(SYSMOD))
COQMAKEFILECMO:=clib/clib.cma lib/lib.cma tools/coq_makefile.cmo
$(COQMAKEFILE): $(call bestobj,$(COQMAKEFILECMO))
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml, -package str,unix,threads)
+ $(HIDE)$(call bestocaml, -package str)
+
+$(COQMAKEFILEBYTE): $(COQMAKEFILECMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -package str,unix,threads)
$(COQTEX): $(call bestobj, tools/coq_tex.cmo)
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, -package str)
+$(COQTEXBYTE): tools/coq_tex.cmo
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -package str)
+
$(COQWC): $(call bestobj, tools/coqwc.cmo)
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, -package str)
+$(COQWCBYTE): tools/coqwc.cmo
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -package str)
+
COQDOCCMO:=clib/clib.cma lib/lib.cma $(addprefix tools/coqdoc/, \
cdglobals.cmo alpha.cmo index.cmo tokens.cmo output.cmo cpretty.cmo main.cmo )
@@ -493,28 +548,45 @@ $(COQDOC): $(call bestobj, $(COQDOCCMO))
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, -package str,unix)
-$(COQWORKMGR): $(call bestobj, clib/clib.cma lib/lib.cma stm/spawned.cmo stm/coqworkmgrApi.cmo tools/coqworkmgr.cmo)
+$(COQDOCBYTE): $(COQDOCCMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -package str,unix)
+
+COQWORKMGRCMO:=clib/clib.cma lib/lib.cma stm/spawned.cmo stm/coqworkmgrApi.cmo tools/coqworkmgr.cmo
+
+$(COQWORKMGR): $(call bestobj, $(COQWORKMGRCMO))
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, $(SYSMOD))
+$(COQWORKMGRBYTE): $(COQWORKMGRCMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, $(SYSMOD))
+
# fake_ide : for debugging or test-suite purpose, a fake ide simulating
-# a connection to coqtop -ideslave
+# a connection to coqidetop
-FAKEIDECMO:=clib/clib.cma lib/lib.cma ide/document.cmo \
- ide/serialize.cmo ide/xml_lexer.cmo ide/xml_parser.cmo \
- ide/xml_printer.cmo ide/richpp.cmo ide/xmlprotocol.cmo \
- tools/fake_ide.cmo
+FAKEIDECMO:=clib/clib.cma lib/lib.cma ide/protocol/ideprotocol.cma ide/document.cmo tools/fake_ide.cmo
-$(FAKEIDE): $(call bestobj, $(FAKEIDECMO)) | $(IDETOPLOOPCMA:.cma=$(BESTDYN))
+$(FAKEIDE): $(call bestobj, $(FAKEIDECMO)) | $(IDETOP)
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml, -I ide -package str,unix,threads)
+ $(HIDE)$(call bestocaml, -I ide -I ide/protocol -package str -package dynlink)
+
+$(FAKEIDEBYTE): $(FAKEIDECMO) | $(IDETOPBYTE)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -I ide -package str,unix,threads)
# votour: a small vo explorer (based on the checker)
-bin/votour: $(call bestobj, clib/cObj.cmo checker/analyze.cmo checker/values.cmo checker/votour.cmo)
+VOTOURCMO:=clib/cObj.cmo checker/analyze.cmo checker/values.cmo checker/votour.cmo
+
+bin/votour: $(call bestobj, $(VOTOURCMO))
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, -I checker)
+bin/votour.byte: $(VOTOURCMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -I checker)
+
###########################################################################
# Csdp to micromega special targets
###########################################################################
@@ -527,6 +599,10 @@ $(CSDPCERT): $(call bestobj, $(CSDPCERTCMO))
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, -package num,unix)
+$(CSDPCERTBYTE): $(CSDPCERTCMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -package num,unix)
+
###########################################################################
# tests
###########################################################################
@@ -571,6 +647,11 @@ kernel/kernel.cma: kernel/kernel.mllib
$(SHOW)'OCAMLC -a -o $@'
$(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $(VMBYTEFLAGS) -a -o $@ $(filter-out %.mllib, $^)
+# Specific rule for kernel.cmxa as to adjoin -cclib -lcoqrun
+kernel/kernel.cmxa: kernel/kernel.mllib
+ $(SHOW)'OCAMLOPT -a -o $@'
+ $(HIDE)$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) -I kernel/byterun/ -cclib -lcoqrun -a -o $@ $(filter-out %.mllib, $^)
+
%.cma: %.mllib
$(SHOW)'OCAMLC -a -o $@'
$(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) -a -o $@ $(filter-out %.mllib, $^)
@@ -589,7 +670,7 @@ kernel/kernel.cma: kernel/kernel.mllib
$(SHOW)'OCAMLOPT -pack -o $@'
$(HIDE)$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) -pack -o $@ $(filter-out %.mlpack, $^)
-COND_IDEFLAGS=$(if $(filter tools/fake_ide% tools/coq_makefile%,$<), -I ide,)
+COND_IDEFLAGS=$(if $(filter tools/fake_ide% tools/coq_makefile%,$<), -I ide -I ide/protocol,)
COND_PRINTERFLAGS=$(if $(filter dev/%,$<), -I dev,)
COND_BYTEFLAGS= \
@@ -679,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) $(COQPP)
$(SHOW)'CAMLP5O $<'
$(HIDE)$(CAMLP5O) -I $(MYCAMLP5LIB) $(PR_O) \
$(CAMLP5DEPS) $(CAMLP5USE) $(CAMLP5COMPAT) -impl $< -o $@
+%.ml: %.mlg $(COQPP)
+ $(SHOW)'COQPP $<'
+ $(HIDE)$(COQPP) $<
###########################################################################
# Dependencies of ML code
diff --git a/Makefile.checker b/Makefile.checker
index 172c64af..6c19a1a4 100644
--- a/Makefile.checker
+++ b/Makefile.checker
@@ -34,12 +34,26 @@ CHECKMLLIBFILE := checker/.mllibfiles
CHECKERDEPS := $(addsuffix .d, $(CHECKMLDFILE) $(CHECKMLLIBFILE))
-include $(CHECKERDEPS)
+# Copied files
+checker/esubst.mli: kernel/esubst.mli
+ cp -a $< $@
+ sed -i.bak '1i(* AUTOGENERATED FILE: DO NOT EDIT *)\n\n\n\n\n\n\n\n' $@ && rm $@.bak
+checker/esubst.ml: kernel/esubst.ml
+ cp -a $< $@
+ sed -i.bak '1i(* AUTOGENERATED FILE: DO NOT EDIT *)\n\n\n\n\n\n\n\n' $@ && rm $@.bak
+checker/names.mli: kernel/names.mli
+ cp -a $< $@
+ sed -i.bak '1i(* AUTOGENERATED FILE: DO NOT EDIT *)\n\n\n\n\n\n\n\n' $@ && rm $@.bak
+checker/names.ml: kernel/names.ml
+ cp -a $< $@
+ sed -i.bak '1i(* AUTOGENERATED FILE: DO NOT EDIT *)\n\n\n\n\n\n\n\n' $@ && rm $@.bak
+
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 $< $@
@@ -57,13 +71,18 @@ checker/check.cmxa: checker/check.mllib | md5chk
$(SHOW)'OCAMLOPT -a -o $@'
$(HIDE)$(OCAMLOPT) $(CHKLIBS) $(OPTFLAGS) -a -o $@ $(filter-out %.mllib, $^)
-$(CHECKMLDFILE).d: $(filter checker/%, $(MLFILES) $(MLIFILES))
+CHECKGENFILES:=$(addprefix checker/, names.mli names.ml esubst.mli esubst.ml)
+
+CHECKMLFILES:=$(filter checker/%, $(MLFILES) $(MLIFILES)) $(CHECKGENFILES) \
+ $(filter dev/checker_%, $(MLFILES) $(MLIFILES))
+
+$(CHECKMLDFILE).d: $(filter checker/%, $(MLFILES) $(MLIFILES) $(CHECKGENFILES))
$(SHOW)'OCAMLDEP checker/MLFILES checker/MLIFILES'
- $(HIDE)$(OCAMLFIND) ocamldep -slash $(CHKLIBS) $(filter checker/%, $(MLFILES) $(MLIFILES)) $(TOTARGET)
+ $(HIDE)$(OCAMLFIND) ocamldep -slash $(CHKLIBS) $(CHECKMLFILES) $(TOTARGET)
-$(CHECKMLLIBFILE).d: $(filter checker/%, $(MLLIBFILES) $(MLPACKFILES)) | $(OCAMLLIBDEP)
+$(CHECKMLLIBFILE).d: $(filter checker/%, $(MLLIBFILES) $(MLPACKFILES) $(CHECKGENFILES)) | $(OCAMLLIBDEP)
$(SHOW)'OCAMLLIBDEP checker/MLLIBFILES checker/MLPACKFILES'
- $(HIDE)$(OCAMLLIBDEP) $(CHKLIBS) $(filter checker/%, $(MLLIBFILES) $(MLPACKFILES)) $(TOTARGET)
+ $(HIDE)$(OCAMLLIBDEP) $(CHKLIBS) $(filter checker/%, $(MLLIBFILES) $(MLPACKFILES) $(CHECKGENFILES)) $(TOTARGET)
checker/%.cmi: checker/%.mli
$(SHOW)'OCAMLC $<'
@@ -77,6 +96,14 @@ checker/%.cmx: checker/%.ml
$(SHOW)'OCAMLOPT $<'
$(HIDE)$(OCAMLOPT) $(CHKLIBS) $(OPTFLAGS) -c $<
+dev/checker_%.cmo: dev/checker_%.ml
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(CHKLIBS) $(BYTEFLAGS) -I dev/ -c $<
+
+dev/checker_%.cmi: dev/checker_%.mli
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(CHKLIBS) $(BYTEFLAGS) -I dev/ -c $<
+
md5chk:
$(SHOW)'MD5SUM cic.mli'
$(HIDE)if grep -q "^MD5 $$($(OCAML) tools/md5sum.ml checker/cic.mli)$$" checker/values.ml; \
diff --git a/Makefile.ci b/Makefile.ci
index 20712b60..e86504b7 100644
--- a/Makefile.ci
+++ b/Makefile.ci
@@ -16,6 +16,7 @@ CI_TARGETS=ci-bedrock2 \
ci-coquelicot \
ci-corn \
ci-cpdt \
+ ci-cross-crypto \
ci-elpi \
ci-ext-lib \
ci-equations \
@@ -32,6 +33,7 @@ CI_TARGETS=ci-bedrock2 \
ci-math-classes \
ci-math-comp \
ci-mtac2 \
+ ci-pidetop \
ci-quickchick \
ci-sf \
ci-simple-io \
diff --git a/Makefile.common b/Makefile.common
index 1e63d52f..09457ced 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -14,34 +14,48 @@
# Executables
###########################################################################
-COQTOPBYTE:=bin/coqtop.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)
COQDEP:=bin/coqdep$(EXE)
+COQPP:=bin/coqpp$(EXE)
+COQDEPBYTE:=bin/coqdep.byte$(EXE)
COQMAKEFILE:=bin/coq_makefile$(EXE)
-GALLINA:=bin/gallina$(EXE)
+COQMAKEFILEBYTE:=bin/coq_makefile.byte$(EXE)
COQTEX:=bin/coq-tex$(EXE)
+COQTEXBYTE:=bin/coq-tex.byte$(EXE)
COQWC:=bin/coqwc$(EXE)
+COQWCBYTE:=bin/coqwc.byte$(EXE)
COQDOC:=bin/coqdoc$(EXE)
+COQDOCBYTE:=bin/coqdoc.byte$(EXE)
COQC:=bin/coqc$(EXE)
+COQCBYTE:=bin/coqc.byte$(EXE)
COQWORKMGR:=bin/coqworkmgr$(EXE)
+COQWORKMGRBYTE:=bin/coqworkmgr.byte$(EXE)
COQMAKE_ONE_TIME_FILE:=tools/make-one-time-file.py
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)\
- $(COQWORKMGR)
+TOOLS:=$(COQDEP) $(COQMAKEFILE) $(COQTEX) $(COQWC) $(COQDOC) $(COQC)\
+ $(COQWORKMGR) $(COQPP)
TOOLS_HELPERS:=tools/CoqMakefile.in $(COQMAKE_ONE_TIME_FILE) $(COQTIME_FILE_MAKER)\
$(COQMAKE_BOTH_TIME_FILES) $(COQMAKE_BOTH_SINGLE_TIMING_FILES)
COQDEPBOOT:=bin/coqdep_boot$(EXE)
+COQDEPBOOTBYTE:=bin/coqdep_boot.byte$(EXE)
OCAMLLIBDEP:=bin/ocamllibdep$(EXE)
+OCAMLLIBDEPBYTE:=bin/ocamllibdep.byte$(EXE)
FAKEIDE:=bin/fake_ide$(EXE)
+FAKEIDEBYTE:=bin/fake_ide.byte$(EXE)
PRIVATEBINARIES:=$(FAKEIDE) $(OCAMLLIBDEP) $(COQDEPBOOT)
CSDPCERT:=plugins/micromega/csdpcert$(EXE)
+CSDPCERTBYTE:=plugins/micromega/csdpcert.byte$(EXE)
###########################################################################
# Object and Source files
@@ -75,13 +89,14 @@ INSTALLSH:=./install.sh
MKDIR:=install -d
CORESRCDIRS:=\
- config clib lib kernel intf kernel/byterun library \
+ coqpp \
+ config clib lib kernel kernel/byterun library \
engine pretyping interp proofs parsing printing \
tactics vernac stm toplevel
PLUGINDIRS:=\
omega romega micromega quote \
- setoid_ring extraction fourier \
+ setoid_ring extraction \
cc funind firstorder derive \
rtauto nsatz syntax btauto \
ssrmatching ltac ssr
@@ -102,19 +117,13 @@ BYTERUN:=$(addprefix kernel/byterun/, \
# respecting this order is useful for developers that want to load or link
# the libraries directly
-CORECMA:=clib/clib.cma lib/lib.cma kernel/kernel.cma intf/intf.cma library/library.cma \
+CORECMA:=clib/clib.cma lib/lib.cma kernel/kernel.cma library/library.cma \
engine/engine.cma pretyping/pretyping.cma interp/interp.cma proofs/proofs.cma \
parsing/parsing.cma printing/printing.cma tactics/tactics.cma vernac/vernac.cma \
- stm/stm.cma toplevel/toplevel.cma
-
-TOPLOOPCMA:=stm/proofworkertop.cma stm/tacworkertop.cma stm/queryworkertop.cma
+ stm/stm.cma toplevel/toplevel.cma
GRAMMARCMA:=grammar/grammar.cma
-# modules known by the toplevel of Coq
-
-OBJSMOD:=$(shell cat $(CORECMA:.cma=.mllib))
-
###########################################################################
# plugins object files
###########################################################################
@@ -125,20 +134,18 @@ MICROMEGACMO:=plugins/micromega/micromega_plugin.cmo
QUOTECMO:=plugins/quote/quote_plugin.cmo
RINGCMO:=plugins/setoid_ring/newring_plugin.cmo
NSATZCMO:=plugins/nsatz/nsatz_plugin.cmo
-FOURIERCMO:=plugins/fourier/fourier_plugin.cmo
EXTRACTIONCMO:=plugins/extraction/extraction_plugin.cmo
FUNINDCMO:=plugins/funind/recdef_plugin.cmo
FOCMO:=plugins/firstorder/ground_plugin.cmo
CCCMO:=plugins/cc/cc_plugin.cmo
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 \
+SYNTAXCMO:=$(addprefix plugins/syntax/, \
r_syntax_plugin.cmo \
int31_syntax_plugin.cmo \
ascii_syntax_plugin.cmo \
- string_syntax_plugin.cmo )
+ string_syntax_plugin.cmo \
+ numeral_notation_plugin.cmo)
DERIVECMO:=plugins/derive/derive_plugin.cmo
LTACCMO:=plugins/ltac/ltac_plugin.cmo plugins/ltac/tauto_plugin.cmo
SSRMATCHINGCMO:=plugins/ssrmatching/ssrmatching_plugin.cmo
@@ -146,9 +153,9 @@ SSRCMO:=plugins/ssr/ssreflect_plugin.cmo
PLUGINSCMO:=$(LTACCMO) $(OMEGACMO) $(ROMEGACMO) $(MICROMEGACMO) \
$(QUOTECMO) $(RINGCMO) \
- $(FOURIERCMO) $(EXTRACTIONCMO) \
+ $(EXTRACTIONCMO) \
$(CCCMO) $(FOCMO) $(RTAUTOCMO) $(BTAUTOCMO) \
- $(FUNINDCMO) $(NSATZCMO) $(NATSYNTAXCMO) $(OTHERSYNTAXCMO) \
+ $(FUNINDCMO) $(NSATZCMO) $(SYNTAXCMO) \
$(DERIVECMO) $(SSRMATCHINGCMO) $(SSRCMO)
ifeq ($(HASNATDYNLINK)-$(BEST),false-opt)
@@ -163,43 +170,8 @@ PLUGINSOPT:=$(PLUGINSCMO:.cmo=.cmxs)
LINKCMO:=$(CORECMA) $(STATICPLUGINS)
LINKCMX:=$(CORECMA:.cma=.cmxa) $(STATICPLUGINS:.cmo=.cmx)
-###########################################################################
-# vo files
-###########################################################################
-
-THEORIESVO := $(patsubst %.v,%.vo,$(shell find theories -type f -name "*.v"))
-PLUGINSVO := $(patsubst %.v,%.vo,$(shell find plugins -type f -name "*.v"))
-ALLVO := $(THEORIESVO) $(PLUGINSVO)
-VFILES := $(ALLVO:.vo=.v)
-
-## More specific targets
-
-THEORIESLIGHTVO:= \
- $(filter theories/Init/% theories/Logic/% theories/Unicode/% theories/Arith/%, $(THEORIESVO))
-
ALLSTDLIB := test-suite/misc/universes/all_stdlib
-# convert a (stdlib) filename into a module name:
-# remove .vo, replace theories and plugins by Coq, and replace slashes by dots
-vo_to_mod = $(subst /,.,$(patsubst theories/%,Coq.%,$(patsubst plugins/%,Coq.%,$(1:.vo=))))
-
-ALLMODS:=$(call vo_to_mod,$(ALLVO))
-
-
-# Converting a stdlib filename into native compiler filenames
-# Used for install targets
-vo_to_cm = $(foreach vo,$(1),$(dir $(vo)).coq-native/$(subst /,_,$(patsubst theories/%,NCoq_%,$(patsubst plugins/%,NCoq_%,$(vo:.vo=.cm*)))))
-
-vo_to_obj = $(foreach vo,$(1),$(dir $(vo)).coq-native/$(subst /,_,$(patsubst theories/%,NCoq_%,$(patsubst plugins/%,NCoq_%,$(vo:.vo=.o)))))
-
-GLOBFILES:=$(ALLVO:.vo=.glob)
-ifdef NATIVECOMPUTE
-NATIVEFILES := $(call vo_to_cm,$(ALLVO)) $(call vo_to_obj,$(ALLVO))
-else
-NATIVEFILES :=
-endif
-LIBFILES:=$(ALLVO) $(NATIVEFILES) $(VFILES) $(GLOBFILES)
-
# For emacs:
# Local Variables:
# mode: makefile
diff --git a/Makefile.dev b/Makefile.dev
index 0461fe07..7fc1076a 100644
--- a/Makefile.dev
+++ b/Makefile.dev
@@ -17,7 +17,7 @@
.PHONY: devel printers
-DEBUGPRINTERS:=dev/top_printers.cmo dev/vm_printers.cmo
+DEBUGPRINTERS:=dev/top_printers.cmo dev/vm_printers.cmo dev/checker_printers.cmo
devel: printers
printers: $(CORECMA) $(DEBUGPRINTERS) dev/camlp5.dbg
@@ -174,7 +174,6 @@ MICROMEGAVO:=$(filter plugins/micromega/%, $(PLUGINSVO))
QUOTEVO:=$(filter plugins/quote/%, $(PLUGINSVO))
RINGVO:=$(filter plugins/setoid_ring/%, $(PLUGINSVO))
NSATZVO:=$(filter plugins/nsatz/%, $(PLUGINSVO))
-FOURIERVO:=$(filter plugins/fourier/%, $(PLUGINSVO))
FUNINDVO:=$(filter plugins/funind/%, $(PLUGINSVO))
BTAUTOVO:=$(filter plugins/btauto/%, $(PLUGINSVO))
RTAUTOVO:=$(filter plugins/rtauto/%, $(PLUGINSVO))
@@ -188,7 +187,6 @@ micromega: $(MICROMEGAVO) $(MICROMEGACMO) $(CSDPCERT)
setoid_ring: $(RINGVO) $(RINGCMO)
nsatz: $(NSATZVO) $(NSATZCMO)
extraction: $(EXTRACTIONCMO) $(EXTRACTIONVO)
-fourier: $(FOURIERVO) $(FOURIERCMO)
funind: $(FUNINDCMO) $(FUNINDVO)
cc: $(CCVO) $(CCCMO)
rtauto: $(RTAUTOVO) $(RTAUTOCMO)
@@ -196,7 +194,7 @@ btauto: $(BTAUTOVO) $(BTAUTOCMO)
ltac: $(LTACVO) $(LTACCMO)
.PHONY: omega micromega setoid_ring nsatz extraction
-.PHONY: fourier funind cc rtauto btauto ltac
+.PHONY: funind cc rtauto btauto ltac
# For emacs:
# Local Variables:
diff --git a/Makefile.doc b/Makefile.doc
index 07581748..a857ab80 100644
--- a/Makefile.doc
+++ b/Makefile.doc
@@ -10,10 +10,7 @@
# Makefile for the Coq documentation
-# To compile documentation, you need the following tools:
-# Dvi: latex (latex2e), bibtex, makeindex
-# Pdf: pdflatex
-# Html: hevea (http://hevea.inria.fr) >= 1.05
+# Read doc/README.md to learn about the dependencies
# The main entry point :
@@ -28,23 +25,18 @@ doc-no:
######################################################################
LATEX:=latex
-BIBTEX:=BIBINPUTS=.: bibtex -min-crossrefs=10
MAKEINDEX:=makeindex
PDFLATEX:=pdflatex
DVIPS:=dvips
-HEVEA:=hevea
-HEVEAOPTS:=-fix -exec xxdate.exe
-HEVEALIB:=/usr/local/lib/hevea:/usr/lib/hevea
HTMLSTYLE:=coqremote
-export TEXINPUTS:=$(HEVEALIB):
-ifdef COQDOC_NOBOOT
-COQTEXOPTS:=-n 72 -sl -small
-else
-COQTEXOPTS:=-boot -n 72 -sl -small
-endif
# Sphinx-related variables
+SPHINXENV:=COQBIN="$(CURDIR)/bin/"
SPHINXOPTS= -j4
+SPHINXWARNERROR ?= 0
+ifeq ($(SPHINXWARNERROR),1)
+SPHINXOPTS += -W
+endif
SPHINXBUILD= sphinx-build
SPHINXBUILDDIR= doc/sphinx/_build
@@ -59,24 +51,23 @@ DOCCOMMON:=doc/common/version.tex doc/common/title.tex doc/common/macros.tex
.PHONY: doc doc-html doc-pdf doc-ps
.PHONY: stdlib full-stdlib sphinx
-.PHONY: tutorial rectutorial
-doc: refman tutorial rectutorial stdlib
+doc: refman stdlib
ifndef QUICK
SPHINX_DEPS := coq
endif
# refman-html and refman-latex
-refman-%: coq
+refman-%: $(SPHINX_DEPS)
$(SHOW)'SPHINXBUILD doc/sphinx ($*)'
- $(HIDE)COQBIN="$(abspath bin)" $(SPHINXBUILD) -b $* \
+ $(HIDE)$(SPHINXENV) $(SPHINXBUILD) -b $* \
$(ALLSPHINXOPTS) doc/sphinx $(SPHINXBUILDDIR)/$*
refman-pdf: refman-latex
+$(MAKE) -C $(SPHINXBUILDDIR)/latex
-refman: coq
+refman: $(SPHINX_DEPS)
+$(MAKE) refman-html
+$(MAKE) refman-pdf
@@ -84,19 +75,13 @@ refman: coq
sphinx: refman-html
doc-html:\
- doc/tutorial/Tutorial.v.html doc/stdlib/html/index.html \
- doc/RecTutorial/RecTutorial.html refman-html
+ doc/stdlib/html/index.html refman-html
doc-pdf:\
- doc/tutorial/Tutorial.v.pdf doc/stdlib/Library.pdf \
- doc/RecTutorial/RecTutorial.pdf refman-pdf
+ doc/stdlib/Library.pdf refman-pdf
doc-ps:\
- doc/tutorial/Tutorial.v.ps \
- doc/stdlib/Library.ps doc/RecTutorial/RecTutorial.ps
-
-tutorial: \
- doc/tutorial/Tutorial.v.html doc/tutorial/Tutorial.v.ps doc/tutorial/Tutorial.v.pdf
+ doc/stdlib/Library.ps
stdlib: \
doc/stdlib/html/index.html doc/stdlib/Library.ps doc/stdlib/Library.pdf
@@ -104,31 +89,13 @@ stdlib: \
full-stdlib: \
doc/stdlib/html/index.html doc/stdlib/FullLibrary.ps doc/stdlib/FullLibrary.pdf
-rectutorial: doc/RecTutorial/RecTutorial.html \
- doc/RecTutorial/RecTutorial.ps doc/RecTutorial/RecTutorial.pdf
-
######################################################################
### Implicit rules
######################################################################
-ifdef QUICK
-%.v.tex: %.tex
- $(COQTEX) $(COQTEXOPTS) $<
-else
-%.v.tex: %.tex $(COQTEX) $(COQTOPEXE) $(ALLVO)
- $(COQTEX) $(COQTEXOPTS) $<
-endif
-
%.ps: %.dvi
(cd `dirname $<`; $(DVIPS) -q -o `basename $@` `basename $<`)
-######################################################################
-# Macros for filtering outputs
-######################################################################
-
-HIDEBIBTEXINFO=| grep -v "^A level-1 auxiliary file"
-SHOWMAKEINDEXERROR=egrep '^!! Input index error|^\*\* Input style error|^ --'
-
######################################################################
# Common
######################################################################
@@ -138,23 +105,6 @@ SHOWMAKEINDEXERROR=egrep '^!! Input index error|^\*\* Input style error|^ --'
doc/common/version.tex: config/Makefile
printf '\\newcommand{\\coqversion}{$(VERSION)}' > doc/common/version.tex
-######################################################################
-# Tutorial
-######################################################################
-
-doc/tutorial/Tutorial.v.dvi: $(DOCCOMMON) doc/tutorial/Tutorial.v.tex
- (cd doc/tutorial;\
- $(LATEX) -interaction=batchmode Tutorial.v;\
- ../tools/show_latex_messages Tutorial.v.log)
-
-doc/tutorial/Tutorial.v.pdf: $(DOCCOMMON) doc/tutorial/Tutorial.v.tex
- (cd doc/tutorial;\
- $(PDFLATEX) -interaction=batchmode Tutorial.v.tex;\
- ../tools/show_latex_messages Tutorial.v.log)
-
-doc/tutorial/Tutorial.v.html: $(DOCCOMMON) doc/tutorial/Tutorial.v.tex
- (cd doc/tutorial; $(HEVEA) $(HEVEAOPTS) Tutorial.v)
-
######################################################################
# Standard library
######################################################################
@@ -228,35 +178,14 @@ doc/stdlib/FullLibrary.pdf: $(DOCCOMMON) doc/stdlib/FullLibrary.coqdoc.tex doc/s
$(PDFLATEX) -interaction=batchmode FullLibrary;\
../tools/show_latex_messages -no-overfull FullLibrary.log)
-######################################################################
-# Tutorial on inductive types
-######################################################################
-
-doc/RecTutorial/RecTutorial.dvi: doc/common/version.tex doc/common/title.tex doc/RecTutorial/RecTutorial.tex
- (cd doc/RecTutorial;\
- $(LATEX) -interaction=batchmode RecTutorial;\
- $(BIBTEX) -terse RecTutorial;\
- $(LATEX) -interaction=batchmode RecTutorial > /dev/null;\
- $(LATEX) -interaction=batchmode RecTutorial > /dev/null;\
- ../tools/show_latex_messages RecTutorial.log)
-
-doc/RecTutorial/RecTutorial.pdf: doc/common/version.tex doc/common/title.tex doc/RecTutorial/RecTutorial.dvi
- (cd doc/RecTutorial;\
- $(PDFLATEX) -interaction=batchmode RecTutorial.tex;\
- ../tools/show_latex_messages RecTutorial.log)
-
-doc/RecTutorial/RecTutorial.html: doc/RecTutorial/RecTutorial.tex
- (cd doc/RecTutorial; $(HEVEA) $(HEVEAOPTS) RecTutorial)
-
######################################################################
# Install all documentation files
######################################################################
.PHONY: install-doc install-doc-meta install-doc-html install-doc-printable \
- install-doc-index-urls install-doc-sphinx
+ install-doc-sphinx install-doc-stdlib-html
-install-doc: install-doc-meta install-doc-html install-doc-printable \
- install-doc-index-urls install-doc-sphinx
+install-doc: install-doc-meta install-doc-html install-doc-printable
install-doc-meta:
$(MKDIR) $(FULLDOCDIR)
@@ -267,17 +196,11 @@ install-doc-html: install-doc-stdlib-html install-doc-sphinx
install-doc-stdlib-html:
$(MKDIR) $(FULLDOCDIR)/html/stdlib
$(INSTALLLIB) doc/stdlib/html/* $(FULLDOCDIR)/html/stdlib
- $(INSTALLLIB) doc/RecTutorial/RecTutorial.html $(FULLDOCDIR)/html/RecTutorial.html
- $(INSTALLLIB) doc/tutorial/Tutorial.v.html $(FULLDOCDIR)/html/Tutorial.html
install-doc-printable:
$(MKDIR) $(FULLDOCDIR)/ps $(FULLDOCDIR)/pdf
$(INSTALLLIB) doc/stdlib/Library.pdf $(FULLDOCDIR)/pdf
$(INSTALLLIB) doc/stdlib/Library.ps $(FULLDOCDIR)/ps
- $(INSTALLLIB) doc/tutorial/Tutorial.v.pdf $(FULLDOCDIR)/pdf/Tutorial.pdf
- $(INSTALLLIB) doc/RecTutorial/RecTutorial.pdf $(FULLDOCDIR)/pdf/RecTutorial.pdf
- $(INSTALLLIB) doc/tutorial/Tutorial.v.ps $(FULLDOCDIR)/ps/Tutorial.ps
- $(INSTALLLIB) doc/RecTutorial/RecTutorial.ps $(FULLDOCDIR)/ps/RecTutorial.ps
install-doc-sphinx:
$(MKDIR) $(FULLDOCDIR)/sphinx
@@ -305,9 +228,11 @@ ODOCDOTOPTS=-dot -dot-reduce
source-doc: mli-doc $(OCAMLDOCDIR)/coq.pdf
+OCAMLDOC_CAML_FLAGS=-rectypes -I +threads $(MLINCLUDES)
+
$(OCAMLDOCDIR)/coq.tex: $(DOCMLIS:.mli=.cmi)
$(SHOW)'OCAMLDOC -latex -o $@'
- $(HIDE)$(OCAMLFIND) ocamldoc -latex -rectypes -I $(MYCAMLP5LIB) $(MLINCLUDES)\
+ $(HIDE)$(OCAMLFIND) ocamldoc -latex $(OCAMLDOC_CAML_FLAGS) \
$(DOCMLIS) -noheader -t "Coq mlis documentation" \
-intro $(OCAMLDOCDIR)/docintro -o $@.tmp
$(SHOW)'OCAMLDOC utf8 fix'
@@ -317,31 +242,31 @@ $(OCAMLDOCDIR)/coq.tex: $(DOCMLIS:.mli=.cmi)
mli-doc: $(DOCMLIS:.mli=.cmi)
$(SHOW)'OCAMLDOC -html'
- $(HIDE)$(OCAMLFIND) ocamldoc -charset utf-8 -html -rectypes -I +threads -I $(MYCAMLP5LIB) $(MLINCLUDES) \
+ $(HIDE)$(OCAMLFIND) ocamldoc -charset utf-8 -html $(OCAMLDOC_CAML_FLAGS) \
$(DOCMLIS) -d $(OCAMLDOCDIR)/html -colorize-code \
-t "Coq mlis documentation" -intro $(OCAMLDOCDIR)/docintro \
-css-style style.css
ml-dot: $(MLFILES)
- $(OCAMLFIND) ocamldoc -dot -dot-reduce -rectypes -I +threads -I $(CAMLLIB) -I $(MYCAMLP5LIB) $(MLINCLUDES) \
+ $(OCAMLFIND) ocamldoc -dot -dot-reduce $(OCAMLDOC_CAML_FLAGS) \
$(filter $(addsuffix /%.ml,$(CORESRCDIRS)),$(MLFILES)) -o $(OCAMLDOCDIR)/coq.dot
%_dep.png: %.dot
$(DOT) -Tpng $< -o $@
%_types.dot: %.mli
- $(OCAMLFIND) ocamldoc -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -dot-types -o $@ $<
+ $(OCAMLFIND) ocamldoc $(OCAMLDOC_CAML_FLAGS) $(ODOCDOTOPTS) -dot-types -o $@ $<
-OCAMLDOC_MLLIBD = $(OCAMLFIND) ocamldoc -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -o $@ \
+OCAMLDOC_MLLIBD = $(OCAMLFIND) ocamldoc $(OCAMLDOC_CAML_FLAGS) $(ODOCDOTOPTS) -o $@ \
$(foreach lib,$(|:.mllib.d=_MLLIB_DEPENDENCIES),$(addsuffix .ml,$($(lib))))
%.dot: | %.mllib.d
$(OCAMLDOC_MLLIBD)
-ml-doc:
+ml-doc: kernel/copcodes.cmi
$(SHOW)'OCAMLDOC -html'
$(HIDE)mkdir -p $(OCAMLDOCDIR)/html/implementation
- $(HIDE)$(OCAMLFIND) ocamldoc -charset utf-8 -html -rectypes -I +threads $(MLINCLUDES) $(COQIDEFLAGS) \
+ $(HIDE)$(OCAMLFIND) ocamldoc -charset utf-8 -html $(OCAMLDOC_CAML_FLAGS) \
$(DOCMLS) -d $(OCAMLDOCDIR)/html/implementation -colorize-code \
-t "Coq mls documentation" \
-css-style ../style.css
@@ -356,7 +281,7 @@ tactics/tactics.dot: | tactics/tactics.mllib.d ltac/ltac.mllib.d
$(OCAMLDOC_MLLIBD)
%.dot: %.mli
- $(OCAMLFIND) ocamldoc -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -o $@ $<
+ $(OCAMLFIND) ocamldoc $(OCAMLDOC_CAML_FLAGS) $(ODOCDOTOPTS) -o $@ $<
$(OCAMLDOCDIR)/%.pdf: $(OCAMLDOCDIR)/%.tex
$(SHOW)'PDFLATEX $*.tex'
diff --git a/Makefile.ide b/Makefile.ide
index ac4ba75d..cb559602 100644
--- a/Makefile.ide
+++ b/Makefile.ide
@@ -36,16 +36,18 @@ COQIDEINAPP:=$(COQIDEAPP)/Contents/MacOS/coqide
# Note : for just building bin/coqide, we could only consider
# config, lib, ide and ide/utils. But the coqidetop plugin (the
-# one that will be loaded by coqtop -ideslave) refers to some
+# one that will be loaded by coqidetop) refers to some
# core modules of coq, for instance printing/*.
-IDESRCDIRS:= $(CORESRCDIRS) ide ide/utils
+IDESRCDIRS:= $(CORESRCDIRS) ide ide/protocol
COQIDEFLAGS=$(addprefix -I , $(IDESRCDIRS)) $(COQIDEINCLUDES)
-IDEDEPS:=clib/clib.cma lib/lib.cma
+IDEDEPS:=clib/clib.cma lib/lib.cma ide/protocol/ideprotocol.cma
IDECMA:=ide/ide.cma
-IDETOPLOOPCMA=ide/coqidetop.cma
+IDETOPEXE=bin/coqidetop$(EXE)
+IDETOP=bin/coqidetop.opt$(EXE)
+IDETOPBYTE=bin/coqidetop.byte$(EXE)
LINKIDE:=$(IDEDEPS) $(IDECDEPS) $(IDECMA) ide/coqide_main.mli ide/coqide_main.ml
LINKIDEOPT:=$(IDEOPTCDEPS) $(patsubst %.cma,%.cmxa,$(IDEDEPS:.cmo=.cmx)) $(IDECMA:.cma=.cmxa) ide/coqide_main.mli ide/coqide_main.ml
@@ -88,16 +90,16 @@ endif
coqide-files: $(IDEFILES)
-ide-byteloop: $(IDETOPLOOPCMA)
-ide-optloop: $(IDETOPLOOPCMA:.cma=.cmxs)
-ide-toploop: ide-$(BEST)loop
+ide-byteloop: $(IDETOPBYTE)
+ide-optloop: $(IDETOP)
+ide-toploop: $(IDETOPEXE)
ifeq ($(HASCOQIDE),opt)
$(COQIDE): $(LINKIDEOPT)
$(SHOW)'OCAMLOPT -o $@'
- $(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) -o $@ unix.cmxa threads.cmxa lablgtk.cmxa \
- lablgtksourceview2.cmxa str.cmxa $(IDEFLAGS:.cma=.cmxa) $^
- $(STRIP) $@
+ $(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) -o $@ \
+ -linkpkg -package str,unix,dynlink,threads,lablgtk2.sourceview2 $(IDEFLAGS:.cma=.cmxa) $^
+ $(STRIP_HIDE) $@
else
$(COQIDE): $(COQIDEBYTE)
cp $< $@
@@ -105,8 +107,8 @@ endif
$(COQIDEBYTE): $(LINKIDE)
$(SHOW)'OCAMLC -o $@'
- $(HIDE)$(OCAMLC) $(COQIDEFLAGS) $(BYTEFLAGS) -o $@ unix.cma threads.cma lablgtk.cma \
- lablgtksourceview2.cma str.cma $(IDEFLAGS) $(IDECDEPSFLAGS) $^
+ $(HIDE)$(OCAMLC) $(COQIDEFLAGS) $(BYTEFLAGS) -o $@ \
+ -linkpkg -package str,unix,dynlink,threads,lablgtk2.sourceview2 $(IDEFLAGS) $(IDECDEPSFLAGS) $^
ide/coqide_main.ml: ide/coqide_main.ml4 config/Makefile # no camlp5deps here
$(SHOW)'CAMLP5O $<'
@@ -135,6 +137,28 @@ ide/ideutils.cmx: ide/ideutils.ml
$(SHOW)'OCAMLOPT $<'
$(HIDE)$(filter-out -safe-string,$(OCAMLOPT)) $(COQIDEFLAGS) $(filter-out -safe-string,$(OPTFLAGS)) -c $<
+IDETOPCMA:=ide/ide_common.cma
+IDETOPCMX:=$(IDETOPCMA:.cma=.cmxa)
+
+# Special rule for coqidetop
+$(IDETOPEXE): $(IDETOP:.opt=.$(BEST))
+ cp $< $@
+
+$(IDETOP): ide/idetop.ml $(LINKCMX) $(LIBCOQRUN) $(IDETOPCMX)
+ $(SHOW)'COQMKTOP -o $@'
+ $(HIDE)$(OCAMLOPT) -linkall -linkpkg $(MLINCLUDES) -I ide -I ide/protocol/ \
+ $(SYSMOD) -package camlp5.gramlib \
+ $(LINKCMX) $(IDETOPCMX) $(OPTFLAGS) $(LINKMETADATA) $< -o $@
+ $(STRIP_HIDE) $@
+ $(CODESIGN_HIDE) $@
+
+$(IDETOPBYTE): ide/idetop.ml $(LINKCMO) $(LIBCOQRUN) $(IDETOPCMA)
+ $(SHOW)'COQMKTOP -o $@'
+ $(HIDE)$(OCAMLC) -linkall -linkpkg $(MLINCLUDES) -I ide -I ide/protocol/ \
+ -I kernel/byterun/ -cclib -lcoqrun $(VMBYTEFLAGS) \
+ $(SYSMOD) -package camlp5.gramlib \
+ $(LINKCMO) $(IDETOPCMA) $(BYTEFLAGS) $< -o $@
+
####################
## Install targets
####################
@@ -164,13 +188,11 @@ install-ide-bin:
install-ide-toploop:
ifeq ($(BEST),opt)
- $(MKDIR) $(FULLCOQLIB)/toploop/
- $(INSTALLBIN) $(IDETOPLOOPCMA:.cma=.cmxs) $(FULLCOQLIB)/toploop/
+ $(INSTALLBIN) $(IDETOPEXE) $(IDETOP) $(FULLBINDIR)
endif
install-ide-toploop-byte:
ifneq ($(BEST),opt)
- $(MKDIR) $(FULLCOQLIB)/toploop/
- $(INSTALLBIN) $(IDETOPLOOPCMA) $(FULLCOQLIB)/toploop/
+ $(INSTALLBIN) $(IDETOPEXE) $(IDETOPBYTE) $(FULLBINDIR)
endif
install-ide-devfiles:
@@ -206,9 +228,8 @@ $(COQIDEAPP)/Contents:
$(COQIDEINAPP): ide/macos_prehook.cmx $(LINKIDEOPT) | $(COQIDEAPP)/Contents
$(SHOW)'OCAMLOPT -o $@'
$(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) -o $@ \
- unix.cmxa lablgtk.cmxa lablgtksourceview2.cmxa str.cmxa \
- threads.cmxa $(IDEFLAGS:.cma=.cmxa) $^
- $(STRIP) $@
+ -linkpkg -package str,unix,dynlink,threads,lablgtk2.sourceview2 $(IDEFLAGS:.cma=.cmxa) $^
+ $(STRIP_HIDE) $@
$(COQIDEAPP)/Contents/Resources/share: $(COQIDEAPP)/Contents
$(MKDIR) $@/coq/
@@ -254,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 5f4458c2..be6fe549 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,17 +68,11 @@ endif
install-binaries: install-tools
$(MKDIR) $(FULLBINDIR)
- $(INSTALLBIN) $(COQC) $(COQTOPEXE) $(CHICKEN) $(FULLBINDIR)
- $(MKDIR) $(FULLCOQLIB)/toploop
-ifeq ($(BEST),opt)
- $(INSTALLBIN) $(TOPLOOPCMA:.cma=.cmxs) $(FULLCOQLIB)/toploop/
-endif
+ $(INSTALLBIN) $(COQC) $(CHICKEN) $(COQTOPEXE) $(TOPBINOPT) $(FULLBINDIR)
install-byte: install-coqide-byte
$(MKDIR) $(FULLBINDIR)
- $(INSTALLBIN) $(COQTOPBYTE) $(FULLBINDIR)
- $(MKDIR) $(FULLCOQLIB)/toploop
- $(INSTALLBIN) $(TOPLOOPCMA) $(FULLCOQLIB)/toploop/
+ $(INSTALLBIN) $(TOPBYTE) $(FULLBINDIR)
$(INSTALLSH) $(FULLCOQLIB) $(LINKCMO) $(PLUGINS)
ifndef CUSTOM
$(INSTALLLIB) $(DLLCOQRUN) $(FULLCOQLIB)
@@ -142,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
@@ -153,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/Makefile.vofiles b/Makefile.vofiles
new file mode 100644
index 00000000..d0ae3173
--- /dev/null
+++ b/Makefile.vofiles
@@ -0,0 +1,43 @@
+
+# This file calls [find] and as such is not suitable for inclusion in
+# the test suite Makefile, unlike Makefile.common.
+
+###########################################################################
+# vo files
+###########################################################################
+
+THEORIESVO := $(patsubst %.v,%.vo,$(shell find theories -type f -name "*.v"))
+PLUGINSVO := $(patsubst %.v,%.vo,$(shell find plugins -type f -name "*.v"))
+ALLVO := $(THEORIESVO) $(PLUGINSVO)
+VFILES := $(ALLVO:.vo=.v)
+
+## More specific targets
+
+THEORIESLIGHTVO:= \
+ $(filter theories/Init/% theories/Logic/% theories/Unicode/% theories/Arith/%, $(THEORIESVO))
+
+# convert a (stdlib) filename into a module name:
+# remove .vo, replace theories and plugins by Coq, and replace slashes by dots
+vo_to_mod = $(subst /,.,$(patsubst theories/%,Coq.%,$(patsubst plugins/%,Coq.%,$(1:.vo=))))
+
+ALLMODS:=$(call vo_to_mod,$(ALLVO))
+
+
+# Converting a stdlib filename into native compiler filenames
+# Used for install targets
+vo_to_cm = $(foreach vo,$(1),$(dir $(vo)).coq-native/$(subst /,_,$(patsubst theories/%,NCoq_%,$(patsubst plugins/%,NCoq_%,$(vo:.vo=.cm*)))))
+
+vo_to_obj = $(foreach vo,$(1),$(dir $(vo)).coq-native/$(subst /,_,$(patsubst theories/%,NCoq_%,$(patsubst plugins/%,NCoq_%,$(vo:.vo=.o)))))
+
+GLOBFILES:=$(ALLVO:.vo=.glob)
+ifdef NATIVECOMPUTE
+NATIVEFILES := $(call vo_to_cm,$(ALLVO)) $(call vo_to_obj,$(ALLVO))
+else
+NATIVEFILES :=
+endif
+LIBFILES:=$(ALLVO) $(NATIVEFILES) $(VFILES) $(GLOBFILES)
+
+# For emacs:
+# Local Variables:
+# mode: makefile
+# End:
diff --git a/README.md b/README.md
index 51dd3f27..e6a52e95 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
# Coq
+[![pipeline status](https://gitlab.com/coq/coq/badges/master/pipeline.svg)](https://gitlab.com/coq/coq/commits/master)
[![Travis](https://travis-ci.org/coq/coq.svg?branch=master)](https://travis-ci.org/coq/coq/builds)
[![Appveyor](https://ci.appveyor.com/api/projects/status/eln43k05pa2vm908/branch/master?svg=true)](https://ci.appveyor.com/project/coq/coq/branch/master)
[![Gitter](https://badges.gitter.im/coq/coq.svg)](https://gitter.im/coq/coq)
@@ -12,11 +13,13 @@ environment for semi-interactive development of machine-checked proofs.
## Installation
Download the pre-built packages of the [latest release](https://github.com/coq/coq/releases/latest) for Windows and MacOS;
read the [help page](https://coq.inria.fr/opam/www/using.html) on how to install Coq with OPAM;
-or refer to the [`INSTALL` file](/INSTALL) for the procedure to install from source.
+or refer to the [`INSTALL` file](INSTALL) for the procedure to install from source.
## 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),
@@ -24,7 +27,7 @@ and the [Coq FAQ](https://github.com/coq/coq/wiki/The-Coq-FAQ),
for additional user-contributed documentation.
## Changes
-There is a file named [`CHANGES`](/CHANGES) that explains the differences and the
+There is a file named [`CHANGES.md`](CHANGES.md) that explains the differences and the
incompatibilities since last versions. If you upgrade Coq, please read
it carefully.
@@ -52,3 +55,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/check.mllib b/checker/check.mllib
index f79ba66e..139fa765 100644
--- a/checker/check.mllib
+++ b/checker/check.mllib
@@ -3,7 +3,6 @@ Coq_config
Analyze
Hook
Terminal
-Canary
Hashset
Hashcons
CSet
diff --git a/checker/checker.ml b/checker/checker.ml
index fd2725c8..d63575b3 100644
--- a/checker/checker.ml
+++ b/checker/checker.ml
@@ -243,7 +243,9 @@ let explain_exn = function
| Invalid_argument s ->
hov 0 (anomaly_string () ++ str "uncaught exception Invalid_argument " ++ guill s ++ report ())
| Sys.Break ->
- hov 0 (fnl () ++ str "User interrupt.")
+ hov 0 (fnl () ++ str "User interrupt.")
+ | Univ.AlreadyDeclared ->
+ hov 0 (str "Error: Multiply declared universe.")
| Univ.UniverseInconsistency (o,u,v) ->
let msg =
if !Flags.debug (*!Constrextern.print_universes*) then
diff --git a/checker/cic.mli b/checker/cic.mli
index c4b00d0d..17259bb4 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. } *)
@@ -128,7 +127,7 @@ type section_context = unit
(** {6 Substitutions} *)
type delta_hint =
- | Inline of int * constr option
+ | Inline of int * (Univ.AUContext.t * constr) option
| Equiv of KerName.t
type delta_resolver = ModPath.t MPmap.t * delta_hint KNmap.t
@@ -203,18 +202,6 @@ type inline = int option
(** A constant can have no body (axiom/parameter), or a
transparent body, or an opaque one *)
-(** Projections are a particular kind of constant:
- always transparent. *)
-
-type projection_body = {
- proj_ind : MutInd.t;
- proj_npars : int;
- proj_arg : int;
- proj_type : constr; (* Type under params *)
- proj_eta : constr * constr; (* Eta-expanded term and type *)
- proj_body : constr; (* For compatibility, the match version *)
-}
-
type constant_def =
| Undef of inline
| Def of constr_substituted
@@ -233,6 +220,7 @@ type typing_flags = {
points are assumed to be total. *)
check_universes : bool; (** If [false] universe constraints are not checked *)
conv_oracle : oracle; (** Unfolding strategies for conversion *)
+ share_reduction : bool; (** Use by-need reduction algorithm *)
}
type constant_body = {
@@ -241,7 +229,6 @@ type constant_body = {
const_type : constr;
const_body_code : to_patch_substituted;
const_universes : constant_universes;
- const_proj : projection_body option;
const_inline_code : bool;
const_typing_flags : typing_flags;
}
@@ -255,9 +242,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 * Label.t array * constr array) array
type regular_inductive_arity = {
mind_user_arity : constr;
@@ -325,7 +313,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 b9ae4daa..57060116 100644
--- a/checker/closure.ml
+++ b/checker/closure.ml
@@ -273,7 +273,7 @@ let update v1 (no,t) =
type stack_member =
| Zapp of fconstr array
| ZcaseT of case_info * constr * constr array * fconstr subs
- | Zproj of int * int * Projection.t
+ | Zproj of Projection.Repr.t
| Zfix of fconstr * stack
| Zshift of int
| Zupdate of fconstr
@@ -497,8 +497,8 @@ let rec zip m stk =
| ZcaseT(ci,p,br,e)::s ->
let t = FCaseT(ci, p, m, br, e) in
zip {norm=neutr m.norm; term=t} s
- | Zproj (i,j,cst) :: s ->
- zip {norm=neutr m.norm; term=FProj (cst,m)} s
+ | Zproj p :: s ->
+ zip {norm=neutr m.norm; term=FProj (Projection.make p true,m)} s
| Zfix(fx,par)::s ->
zip fx (par @ append_stack [|m|] s)
| Zshift(n)::s ->
@@ -618,20 +618,25 @@ 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 ->
- (* (Construct, pars1 .. parsm :: arg1...argn :: []) ~= (f, s') ->
- arg1..argn ~= (proj1 t...projn t) where t = zip (f,s') *)
- let pars = mib.mind_nparams in
- let right = fapp_stack (f, s') in
- let (depth, args, s) = strip_update_shift_app m s in
- (** Try to drop the params, might fail on partially applied constructors. *)
- let argss = try_drop_parameters depth pars args in
- let hstack =
- Array.map (fun p -> { norm = Red; (* right can't be a constructor though *)
- term = FProj (Projection.make p false, right) }) projs in
- argss, [Zapp hstack]
- | _ -> raise Not_found (* disallow eta-exp for non-primitive records *)
+ (* disallow eta-exp for non-primitive records *)
+ if not (mib.mind_finite == BiFinite) then raise Not_found;
+ match Declarations.inductive_make_projections ind mib with
+ | Some projs ->
+ (* (Construct, pars1 .. parsm :: arg1...argn :: []) ~= (f, s') ->
+ arg1..argn ~= (proj1 t...projn t) where t = zip (f,s') *)
+ let pars = mib.mind_nparams in
+ let right = fapp_stack (f, s') in
+ let (depth, args, s) = strip_update_shift_app m s in
+ (** Try to drop the params, might fail on partially applied constructors. *)
+ let argss = try_drop_parameters depth pars args in
+ let hstack =
+ Array.map (fun p ->
+ { norm = Red; (* right can't be a constructor though *)
+ term = FProj (Projection.make p false, right) })
+ projs
+ in
+ argss, [Zapp hstack]
+ | None -> raise Not_found (* disallow eta-exp for non-primitive records *)
let rec project_nth_arg n argstk =
match argstk with
@@ -668,8 +673,7 @@ let contract_fix_vect fix =
(subs_cons(Array.init nfix make_body, env), thisbody)
let unfold_projection env p =
- let pb = lookup_projection p env in
- Zproj (pb.proj_npars, pb.proj_arg, p)
+ Zproj (Projection.repr p)
(*********************************************************************)
(* A machine that inspects the head of a term until it finds an
@@ -747,9 +751,9 @@ let rec knr info m stk =
let stk' = par @ append_stack [|rarg|] s in
let (fxe,fxbd) = contract_fix_vect fx.term in
knit info fxe fxbd stk'
- | (depth, args, Zproj (n, m, cst)::s) ->
- let rargs = drop_parameters depth n args in
- let rarg = project_nth_arg m rargs in
+ | (depth, args, Zproj p::s) ->
+ let rargs = drop_parameters depth (Projection.Repr.npars p) args in
+ let rarg = project_nth_arg (Projection.Repr.arg p) rargs in
kni info rarg s
| (_,args,s) -> (m,args@s))
| FCoFix _ when red_set info.i_flags fIOTA ->
diff --git a/checker/closure.mli b/checker/closure.mli
index 49b07f73..cec78569 100644
--- a/checker/closure.mli
+++ b/checker/closure.mli
@@ -103,7 +103,7 @@ type fterm =
type stack_member =
| Zapp of fconstr array
| ZcaseT of case_info * constr * constr array * fconstr subs
- | Zproj of int * int * Projection.t
+ | Zproj of Projection.Repr.t
| Zfix of fconstr * stack
| Zshift of int
| Zupdate of fconstr
diff --git a/checker/declarations.ml b/checker/declarations.ml
index d2c3f203..0540227c 100644
--- a/checker/declarations.ml
+++ b/checker/declarations.ml
@@ -196,7 +196,12 @@ let subst_con0 sub con u =
let dup con = con, Const (con, u) in
let side,con',resolve = gen_subst_mp rebuild_con sub mp1 mp2 in
match constant_of_delta_with_inline resolve con' with
- | Some t -> con', subst_instance_constr u t
+ | Some (ctx, t) ->
+ (** FIXME: we never typecheck the inlined term, so that it could well
+ be garbage. What environment do we type it in though? The substitution
+ code should be moot in the checker but it **is** used nonetheless. *)
+ let () = assert (Univ.AUContext.size ctx == Univ.Instance.length u) in
+ con', subst_instance_constr u t
| None ->
let con'' = match side with
| User -> constant_of_delta resolve con'
@@ -209,11 +214,7 @@ let rec map_kn f f' c =
match c with
| Const (kn, u) -> (try snd (f' kn u) with No_subst -> c)
| Proj (p,t) ->
- let p' =
- Projection.map (fun kn ->
- try fst (f' kn Univ.Instance.empty)
- with No_subst -> kn) p
- in
+ let p' = Projection.map f p in
let t' = func t in
if p' == p && t' == t then c
else Proj (p', t')
@@ -231,7 +232,7 @@ let rec map_kn f f' c =
in
let p' = func p in
let ct' = func ct in
- let l' = Array.smartmap func l in
+ let l' = Array.Smart.map func l in
if (ci.ci_ind==ci_ind && p'==p
&& l'==l && ct'==ct)then c
else
@@ -260,21 +261,21 @@ let rec map_kn f f' c =
else LetIn (na, b', t', ct')
| App (ct,l) ->
let ct' = func ct in
- let l' = Array.smartmap func l in
+ let l' = Array.Smart.map func l in
if (ct'== ct && l'==l) then c
else App (ct',l')
| Evar (e,l) ->
- let l' = Array.smartmap func l in
+ let l' = Array.Smart.map func l in
if (l'==l) then c
else Evar (e,l')
| Fix (ln,(lna,tl,bl)) ->
- let tl' = Array.smartmap func tl in
- let bl' = Array.smartmap func bl in
+ let tl' = Array.Smart.map func tl in
+ let bl' = Array.Smart.map func bl in
if (bl == bl'&& tl == tl') then c
else Fix (ln,(lna,tl',bl'))
| CoFix(ln,(lna,tl,bl)) ->
- let tl' = Array.smartmap func tl in
- let bl' = Array.smartmap func bl in
+ let tl' = Array.Smart.map func tl in
+ let bl' = Array.Smart.map func bl in
if (bl == bl'&& tl == tl') then c
else CoFix (ln,(lna,tl',bl'))
| _ -> c
@@ -340,7 +341,7 @@ let gen_subst_delta_resolver dom subst resolver =
let kkey' = if dom then subst_kn subst kkey else kkey in
let hint' = match hint with
| Equiv kequ -> Equiv (subst_kn_delta subst kequ)
- | Inline (lev,Some t) -> Inline (lev,Some (subst_mps subst t))
+ | Inline (lev,Some (ctx, t)) -> Inline (lev,Some (ctx, subst_mps subst t))
| Inline (_,None) -> hint
in
Deltamap.add_kn kkey' hint' rslv
@@ -480,7 +481,7 @@ let dest_subterms p =
let (_,cstrs) = Rtree.dest_node p in
Array.map (fun t -> Array.to_list (snd (Rtree.dest_node t))) cstrs
-let subst_wf_paths sub p = Rtree.smartmap (subst_recarg sub) p
+let subst_wf_paths sub p = Rtree.Smart.map (subst_recarg sub) p
let eq_recarg r1 r2 = match r1, r2 with
| Norec, Norec -> true
@@ -490,6 +491,16 @@ let eq_recarg r1 r2 = match r1, r2 with
let eq_wf_paths = Rtree.equal eq_recarg
+let inductive_make_projections ind mib =
+ match mib.mind_record with
+ | NotRecord | FakeRecord -> None
+ | PrimRecord infos ->
+ let projs = Array.mapi (fun proj_arg lab ->
+ Names.Projection.Repr.make ind ~proj_npars:mib.mind_nparams ~proj_arg lab)
+ (pi2 infos.(snd ind))
+ in
+ Some projs
+
(**********************************************************************)
(* Representation of mutual inductive types in the kernel *)
(*
@@ -513,7 +524,7 @@ let subst_decl_arity f g sub ar =
let subst_rel_declaration sub =
Term.map_rel_decl (subst_mps sub)
-let subst_rel_context sub = List.smartmap (subst_rel_declaration sub)
+let subst_rel_context sub = List.Smart.map (subst_rel_declaration sub)
let constant_is_polymorphic cb =
match cb.const_universes with
@@ -544,10 +555,10 @@ let subst_mind_packet sub mbp =
mind_consnrealdecls = mbp.mind_consnrealdecls;
mind_consnrealargs = mbp.mind_consnrealargs;
mind_typename = mbp.mind_typename;
- mind_nf_lc = Array.smartmap (subst_mps sub) mbp.mind_nf_lc;
+ mind_nf_lc = Array.Smart.map (subst_mps sub) mbp.mind_nf_lc;
mind_arity_ctxt = subst_rel_context sub mbp.mind_arity_ctxt;
mind_arity = subst_ind_arity sub mbp.mind_arity;
- mind_user_lc = Array.smartmap (subst_mps sub) mbp.mind_user_lc;
+ mind_user_lc = Array.Smart.map (subst_mps sub) mbp.mind_user_lc;
mind_nrealargs = mbp.mind_nrealargs;
mind_nrealdecls = mbp.mind_nrealdecls;
mind_kelim = mbp.mind_kelim;
@@ -560,7 +571,7 @@ let subst_mind_packet sub mbp =
let subst_mind sub mib =
{ mib with
mind_params_ctxt = map_rel_context (subst_mps sub) mib.mind_params_ctxt;
- mind_packets = Array.smartmap (subst_mind_packet sub) mib.mind_packets }
+ mind_packets = Array.Smart.map (subst_mind_packet sub) mib.mind_packets }
(* Modules *)
@@ -599,7 +610,7 @@ and subst_body : 'a. (_ -> 'a -> 'a) -> _ -> 'a generic_module_body -> 'a generi
mod_mp = subst_mp sub mb.mod_mp;
mod_expr = subst_impl sub mb.mod_expr;
mod_type = subst_signature sub mb.mod_type;
- mod_type_alg = Option.smartmap (subst_expression sub) mb.mod_type_alg }
+ mod_type_alg = Option.Smart.map (subst_expression sub) mb.mod_type_alg }
and subst_module sub mb =
subst_body (fun sub e -> implem_map (subst_signature sub) (subst_expression sub) e) sub mb
diff --git a/checker/declarations.mli b/checker/declarations.mli
index 7458b3e0..ce852644 100644
--- a/checker/declarations.mli
+++ b/checker/declarations.mli
@@ -25,6 +25,9 @@ val dest_subterms : wf_paths -> wf_paths list array
val eq_recarg : recarg -> recarg -> bool
val eq_wf_paths : wf_paths -> wf_paths -> bool
+val inductive_make_projections : Names.inductive -> mutual_inductive_body ->
+ Names.Projection.Repr.t array option
+
(* Modules *)
val empty_delta_resolver : delta_resolver
diff --git a/checker/environ.ml b/checker/environ.ml
index bbd043c8..b172acb1 100644
--- a/checker/environ.ml
+++ b/checker/environ.ml
@@ -164,14 +164,6 @@ let evaluable_constant cst env =
try let _ = constant_value env (cst, Univ.Instance.empty) in true
with Not_found | NotEvaluableConst _ -> false
-let is_projection cst env =
- not (Option.is_empty (lookup_constant cst env).const_proj)
-
-let lookup_projection p env =
- match (lookup_constant (Projection.constant p) env).const_proj with
- | Some pb -> pb
- | None -> anomaly ("lookup_projection: constant is not a projection.")
-
(* Mutual Inductives *)
let scrape_mind env kn=
try
@@ -191,7 +183,7 @@ let lookup_mind kn env =
let add_mind kn mib env =
if Mindmap_env.mem kn env.env_globals.env_inductives then
- Printf.ksprintf anomaly ("Inductive %s is already defined.")
+ Printf.ksprintf anomaly ("Mutual inductive block %s is already defined.")
(MutInd.to_string kn);
let new_inds = Mindmap_env.add kn mib env.env_globals.env_inductives in
let kn1,kn2 = MutInd.user kn, MutInd.canonical kn in
@@ -201,10 +193,23 @@ let add_mind kn mib env =
KNmap.add kn1 kn2 env.env_globals.env_inductives_eq in
let new_globals =
{ env.env_globals with
- env_inductives = new_inds;
- env_inductives_eq = new_inds_eq} in
+ env_inductives = new_inds;
+ env_inductives_eq = new_inds_eq} in
{ env with env_globals = new_globals }
+let lookup_projection p env =
+ let mind,i = Projection.inductive p in
+ let mib = lookup_mind mind env in
+ match mib.mind_record with
+ | NotRecord | FakeRecord -> CErrors.anomaly ~label:"lookup_projection" Pp.(str "not a projection")
+ | PrimRecord infos ->
+ let _,labs,typs = infos.(i) in
+ let parg = Projection.arg p in
+ if not (Label.equal labs.(parg) (Projection.label p))
+ then CErrors.anomaly ~label:"lookup_projection" Pp.(str "incorrect label on projection")
+ else if not (Int.equal mib.mind_nparams (Projection.npars p))
+ then CErrors.anomaly ~label:"lookup_projection" Pp.(str "incorrect param number on projection")
+ else typs.(parg)
(* Modules *)
diff --git a/checker/environ.mli b/checker/environ.mli
index 81da8387..af1b2a62 100644
--- a/checker/environ.mli
+++ b/checker/environ.mli
@@ -57,8 +57,8 @@ exception NotEvaluableConst of const_evaluation_result
val constant_value : env -> Constant.t puniverses -> constr
val evaluable_constant : Constant.t -> env -> bool
-val is_projection : Constant.t -> env -> bool
-val lookup_projection : Projection.t -> env -> projection_body
+(** NB: here in the checker we check the inferred info (npars, label) *)
+val lookup_projection : Projection.t -> env -> constr
(* Inductives *)
val mind_equiv : env -> inductive -> inductive -> bool
diff --git a/checker/indtypes.ml b/checker/indtypes.ml
index 916934a8..f36fef7f 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
@@ -525,10 +525,11 @@ let check_positivity env_ar mind params nrecp inds =
Array.mapi (fun j t -> (Mrec(mind,j),t)) (Rtree.mk_rec_calls ntypes) in
let lra_ind = List.rev (Array.to_list rc) in
let lparams = rel_context_length params in
+ let ra_env =
+ List.init lparams (fun _ -> (Norec,mk_norec)) @ lra_ind in
+ let env_ar_par = push_rel_context params env_ar in
let check_one i mip =
- let ra_env =
- List.init lparams (fun _ -> (Norec,mk_norec)) @ lra_ind in
- let ienv = (env_ar, 1+lparams, ntypes, ra_env) in
+ let ienv = (env_ar_par, 1+lparams, ntypes, ra_env) in
check_positivity_one ienv params nrecp (mind,i) mip.mind_nf_lc
in
let irecargs = Array.mapi check_one inds in
@@ -595,8 +596,12 @@ let check_subtyping cumi paramsctxt env inds =
(************************************************************************)
(************************************************************************)
+let print_mutind ind =
+ let kn = MutInd.user ind in
+ str (ModPath.to_string (KerName.modpath kn) ^ "." ^ Label.to_string (KerName.label kn))
+
let check_inductive env kn mib =
- Flags.if_verbose Feedback.msg_notice (str " checking ind: " ++ MutInd.print kn);
+ Flags.if_verbose Feedback.msg_notice (str " checking mutind block: " ++ print_mutind kn);
(* check mind_constraints: should be consistent with env *)
let env0 =
match mib.mind_universes with
@@ -625,7 +630,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 e1c6b135..46a859f0 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 =
@@ -383,7 +383,7 @@ let type_case_branches env (pind,largs) (p,pj) c =
let check_case_info env indsp ci =
let (mib,mip) = lookup_mind_specif env indsp in
if
- not (eq_ind_chk indsp ci.ci_ind) ||
+ not (mind_equiv env indsp ci.ci_ind) ||
(mib.mind_nparams <> ci.ci_npar) ||
(mip.mind_consnrealdecls <> ci.ci_cstr_ndecls) ||
(mip.mind_consnrealargs <> ci.ci_cstr_nargs)
@@ -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 3ef2b340..6b2af71f 100644
--- a/checker/mod_checking.ml
+++ b/checker/mod_checking.ml
@@ -26,17 +26,12 @@ let check_constant_declaration env kn cb =
push_context ~strict:false ctx env
in
let ty = cb.const_type in
- let () = ignore(infer_type env' ty) in
- let () =
+ let _ = infer_type env' ty in
+ let () =
match body_of_constant cb with
| Some bd ->
- (match cb.const_proj with
- | None -> let j = infer env' bd in
- conv_leq env' j ty
- | Some pb ->
- let env' = add_constant kn cb env' in
- let j = infer env' bd in
- conv_leq env' 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 c7ad0977..b92d7bbf 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 fc9cd687..247c811f 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 4e508dc7..ee16675e 100644
--- a/checker/reduction.ml
+++ b/checker/reduction.ml
@@ -43,7 +43,7 @@ let compare_stack_shape stk1 stk2 =
| (_, (Zupdate _|Zshift _)::s2) -> compare_rec bal stk1 s2
| (Zapp l1::s1, _) -> compare_rec (bal+Array.length l1) s1 stk2
| (_, Zapp l2::s2) -> compare_rec (bal-Array.length l2) stk1 s2
- | (Zproj (n1,m1,p1)::s1, Zproj (n2,m2,p2)::s2) ->
+ | (Zproj p1::s1, Zproj p2::s2) ->
Int.equal bal 0 && compare_rec 0 s1 s2
| ((ZcaseT(c1,_,_,_))::s1,
(ZcaseT(c2,_,_,_))::s2) ->
@@ -55,7 +55,7 @@ let compare_stack_shape stk1 stk2 =
type lft_constr_stack_elt =
Zlapp of (lift * fconstr) array
- | Zlproj of Names.Projection.t * lift
+ | Zlproj of Names.Projection.Repr.t * lift
| Zlfix of (lift * fconstr) * lft_constr_stack
| Zlcase of case_info * lift * fconstr * fconstr array
and lft_constr_stack = lft_constr_stack_elt list
@@ -74,8 +74,8 @@ let pure_stack lfts stk =
| (Zshift n,(l,pstk)) -> (el_shft n l, pstk)
| (Zapp a, (l,pstk)) ->
(l,zlapp (Array.map (fun t -> (l,t)) a) pstk)
- | (Zproj (n,m,c), (l,pstk)) ->
- (l, Zlproj (c,l)::pstk)
+ | (Zproj p, (l,pstk)) ->
+ (l, Zlproj (p,l)::pstk)
| (Zfix(fx,a),(l,pstk)) ->
let (lfx,pa) = pure_rec l a in
(l, Zlfix((lfx,fx),pa)::pstk)
@@ -133,7 +133,7 @@ let convert_universes univ u u' =
if Univ.Instance.check_eq univ u u' then ()
else raise NotConvertible
-let compare_stacks f fmind lft1 stk1 lft2 stk2 =
+let compare_stacks f fmind fproj lft1 stk1 lft2 stk2 =
let rec cmp_rec pstk1 pstk2 =
match (pstk1,pstk2) with
| (z1::s1, z2::s2) ->
@@ -143,10 +143,8 @@ let compare_stacks f fmind lft1 stk1 lft2 stk2 =
| (Zlfix(fx1,a1),Zlfix(fx2,a2)) ->
f fx1 fx2; cmp_rec a1 a2
| (Zlproj (c1,l1),Zlproj (c2,l2)) ->
- if not (Names.Constant.UserOrd.equal
- (Names.Projection.constant c1)
- (Names.Projection.constant c2)) then
- raise NotConvertible
+ if not (fproj c1 c2) then
+ raise NotConvertible
| (Zlcase(ci1,l1,p1,br1),Zlcase(ci2,l2,p2,br2)) ->
if not (fmind ci1.ci_ind ci2.ci_ind) then
raise NotConvertible;
@@ -194,10 +192,7 @@ let convert_constructors
| Monomorphic_ind _ | Polymorphic_ind _ -> convert_universes univs u1 u2
| Cumulative_ind cumi ->
let num_cnstr_args =
- let nparamsctxt =
- mind.mind_nparams + mind.mind_packets.(ind).mind_nrealargs
- in
- nparamsctxt + mind.mind_packets.(ind).mind_consnrealargs.(cns - 1)
+ mind.mind_nparams + mind.mind_packets.(ind).mind_consnrealargs.(cns - 1)
in
if not (num_cnstr_args = sv1 && num_cnstr_args = sv2) then
convert_universes univs u1 u2
@@ -210,29 +205,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
@@ -260,7 +252,7 @@ let rec no_case_available = function
| Zupdate _ :: stk -> no_case_available stk
| Zshift _ :: stk -> no_case_available stk
| Zapp _ :: stk -> no_case_available stk
- | Zproj (_,_,_) :: _ -> false
+ | Zproj _ :: _ -> false
| ZcaseT _ :: _ -> false
| Zfix _ :: _ -> true
@@ -303,6 +295,10 @@ let eq_table_key univ =
Constant.UserOrd.equal c1 c2 &&
Univ.Instance.check_eq univ u1 u2)
+let proj_equiv_infos infos p1 p2 =
+ Int.equal (Projection.Repr.arg p1) (Projection.Repr.arg p2) &&
+ mind_equiv (infos_env infos) (Projection.Repr.inductive p1) (Projection.Repr.inductive p2)
+
(* Conversion between [lft1]term1 and [lft2]term2 *)
let rec ccnv univ cv_pb infos lft1 lft2 term1 term2 =
eqappr univ cv_pb infos (lft1, (term1,[])) (lft2, (term2,[]))
@@ -526,7 +522,7 @@ and eqappr univ cv_pb infos (lft1,st1) (lft2,st2) =
and convert_stacks univ infos lft1 lft2 stk1 stk2 =
compare_stacks
(fun (l1,t1) (l2,t2) -> ccnv univ CONV infos l1 l2 t1 t2)
- (mind_equiv_infos infos)
+ (mind_equiv_infos infos) (proj_equiv_infos infos)
lft1 stk1 lft2 stk2
and convert_vect univ infos lft1 lft2 v1 v2 =
diff --git a/checker/subtyping.ml b/checker/subtyping.ml
index 31dab0c9..0916d98d 100644
--- a/checker/subtyping.ml
+++ b/checker/subtyping.ml
@@ -12,7 +12,6 @@
open Util
open Names
open Cic
-open Term
open Declarations
open Environ
open Reduction
@@ -123,16 +122,6 @@ let check_inductive env mp1 l info1 mib2 spec2 subst1 subst2=
env, Univ.make_abstract_instance auctx'
| _ -> error ()
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 (==) (fun x -> x.proj_npars);
- check (==) (fun x -> x.proj_arg);
- check (eq_constr) (fun x -> x.proj_type);
- check (eq_constr) (fun x -> fst x.proj_eta);
- check (eq_constr) (fun x -> snd x.proj_eta);
- check (eq_constr) (fun x -> x.proj_body); true
- in
let check_inductive_type t1 t2 = check_conv conv_leq env t1 t2 in
let check_packet p1 p2 =
@@ -186,16 +175,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) =
+ (* we don't care about the id, the types are inferred from the inductive
+ (ie checked before now) *)
+ Array.for_all2 Label.equal p1 p2
+ 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)
@@ -216,7 +208,7 @@ 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 = check_conv conv_leq env t1 t2 in
@@ -280,7 +272,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 0236f786..d84491b3 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
(********************************************************************)
@@ -243,7 +243,7 @@ let map_rel_decl f = function
LocalDef (n, body', typ')
let map_rel_context f =
- List.smartmap (map_rel_decl f)
+ List.Smart.map (map_rel_decl f)
let extended_rel_list n hyps =
let rec reln l p = function
@@ -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 18f07dc0..e4c3f4ae 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 *)
@@ -158,7 +158,7 @@ let judge_of_inductive_knowing_parameters env (ind,u) (paramstyp:constr array) =
let specif =
try lookup_mind_specif env ind
with Not_found ->
- failwith ("Cannot find inductive: "^MutInd.to_string (fst ind))
+ failwith ("Cannot find mutual inductive block: "^MutInd.to_string (fst ind))
in
type_of_inductive_knowing_parameters env (specif,u) paramstyp
@@ -172,7 +172,7 @@ let judge_of_constructor env (c,u) =
let specif =
try lookup_mind_specif env ind
with Not_found ->
- failwith ("Cannot find inductive: "^MutInd.to_string (fst ind))
+ failwith ("Cannot find mutual inductive block: "^MutInd.to_string (fst ind))
in
type_of_constructor (c,u) specif
@@ -198,14 +198,13 @@ let judge_of_case env ci pj (c,cj) lfj =
(* Projection. *)
let judge_of_projection env p c ct =
- let pb = lookup_projection p env in
+ let pty = lookup_projection p env in
let (ind,u), args =
try find_rectype env ct
with Not_found -> error_case_not_inductive env (c, ct)
in
- assert(MutInd.equal pb.proj_ind (fst ind));
- let ty = subst_instance_constr u pb.proj_type in
- substl (c :: List.rev args) ty
+ let ty = subst_instance_constr u pty in
+ substl (c :: List.rev args) ty
(* Fixpoints. *)
@@ -239,7 +238,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 1619010c..a0511ad2 100644
--- a/checker/univ.ml
+++ b/checker/univ.ml
@@ -142,7 +142,13 @@ end
(** Level sets and maps *)
module LMap = HMap.Make (Level)
-module LSet = LMap.Set
+module LSet = struct
+ include LMap.Set
+
+ let pr s =
+ str"{" ++ prlist_with_sep spc Level.pr (elements s) ++ str"}"
+
+end
type 'a universe_map = 'a LMap.t
@@ -301,7 +307,7 @@ struct
let for_all = List.for_all
- let smartmap = List.smartmap
+ let smart_map = List.Smart.map
end
@@ -863,12 +869,12 @@ struct
let is_empty x = Int.equal (Array.length x) 0
let subst_fn fn t =
- let t' = CArray.smartmap fn t in
+ let t' = CArray.Smart.map fn t in
if t' == t then t else t'
let subst s t =
let t' =
- CArray.smartmap (fun x -> try LMap.find x s with Not_found -> x) t
+ CArray.Smart.map (fun x -> try LMap.find x s with Not_found -> x) t
in if t' == t then t else t'
let pr =
@@ -904,11 +910,11 @@ let subst_instance_level s l =
| _ -> l
let subst_instance_instance s i =
- Array.smartmap (fun l -> subst_instance_level s l) i
+ Array.Smart.map (fun l -> subst_instance_level s l) i
let subst_instance_universe s u =
let f x = Universe.Expr.map (fun u -> subst_instance_level s u) x in
- let u' = Universe.smartmap f u in
+ let u' = Universe.smart_map f u in
if u == u' then u
else Universe.sort u'
@@ -1049,7 +1055,7 @@ let subst_univs_level_level subst l =
let subst_univs_level_universe subst u =
let f x = Universe.Expr.map (fun u -> subst_univs_level_level subst u) x in
- let u' = Universe.smartmap f u in
+ let u' = Universe.smart_map f u in
if u == u' then u
else Universe.sort u'
@@ -1082,14 +1088,13 @@ let subst_univs_universe fn ul =
let merge_context strict ctx g =
let g = Array.fold_left
- (* Be lenient, module typing reintroduces universes and
- constraints due to includes *)
- (fun g v -> try add_universe v strict g with AlreadyDeclared -> g)
+ (fun g v -> add_universe v strict g)
g (UContext.instance ctx)
in merge_constraints (UContext.constraints ctx) g
let merge_context_set strict ctx g =
let g = LSet.fold
+ (* Include and side effects still have double-declared universes *)
(fun v g -> try add_universe v strict g with AlreadyDeclared -> g)
(ContextSet.levels ctx) g
in merge_constraints (ContextSet.constraints ctx) g
diff --git a/checker/univ.mli b/checker/univ.mli
index 473159c0..3b29b158 100644
--- a/checker/univ.mli
+++ b/checker/univ.mli
@@ -49,6 +49,7 @@ sig
val make : Level.t -> t
(** Create a universe representing the given level. *)
+ val pr : t -> Pp.t
end
type universe = Universe.t
@@ -138,7 +139,14 @@ val check_constraints : constraints -> universes -> bool
(** Polymorphic maps from universe levels to 'a *)
module LMap : CSig.MapS with type key = universe_level
-module LSet : CSig.SetS with type elt = universe_level
+module LSet :
+sig
+ include CSig.SetS with type elt = Level.t
+
+ val pr : t -> Pp.t
+ (** Pretty-printing *)
+end
+
type 'a universe_map = 'a LMap.t
(** {6 Substitution} *)
@@ -214,6 +222,8 @@ sig
val instantiate : Instance.t -> t -> Constraint.t
val repr : t -> UContext.t
+ val pr : (Level.t -> Pp.t) -> t -> Pp.t
+
end
type abstract_universe_context = AUContext.t
diff --git a/checker/values.ml b/checker/values.ml
index 1ac8d7ce..e1b5a949 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 c4fdf8a846aed45c27b5acb1add7d1c6 checker/cic.mli
+MD5 f7b267579138eabf86a74d6f2a7ed794 checker/cic.mli
*)
@@ -91,7 +91,7 @@ let rec v_mp = Sum("module_path",0,
[|[|v_dp|];
[|v_uid|];
[|v_mp;v_id|]|])
-let v_kn = v_tuple "kernel_name" [|Any;v_mp;v_dp;v_id;Int|]
+let v_kn = v_tuple "kernel_name" [|v_mp;v_dp;v_id;Int|]
let v_cst = v_sum "cst|mind" 0 [|[|v_kn|];[|v_kn;v_kn|]|]
let v_ind = v_tuple "inductive" [|v_cst;Int|]
let v_cons = v_tuple "constructor" [|v_ind;Int|]
@@ -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|]
@@ -135,7 +135,9 @@ let v_caseinfo =
v_tuple "case_info" [|v_ind;Int;Array Int;Array Int;v_cprint|]
let v_cast = v_enum "cast_kind" 4
-let v_proj = v_tuple "projection" [|v_cst; v_bool|]
+
+let v_proj_repr = v_tuple "projection_repr" [|v_ind;Int;Int;v_id|]
+let v_proj = v_tuple "projection" [|v_proj_repr; v_bool|]
let rec v_constr =
Sum ("constr",0,[|
@@ -173,7 +175,7 @@ let v_section_ctxt = v_enum "emptylist" 1
(** kernel/mod_subst *)
let v_delta_hint =
- v_sum "delta_hint" 0 [|[|Int; Opt v_constr|];[|v_kn|]|]
+ v_sum "delta_hint" 0 [|[|Int; Opt (v_pair v_abs_context v_constr)|];[|v_kn|]|]
let v_resolver =
v_tuple "delta_resolver"
@@ -223,14 +225,8 @@ let v_cst_def =
v_sum "constant_def" 0
[|[|Opt Int|]; [|v_cstr_subst|]; [|v_lazy_constr|]|]
-let v_projbody =
- v_tuple "projection_body"
- [|v_cst;Int;Int;v_constr;
- v_tuple "proj_eta" [|v_constr;v_constr|];
- v_constr|]
-
let v_typing_flags =
- v_tuple "typing_flags" [|v_bool; v_bool; v_oracle|]
+ v_tuple "typing_flags" [|v_bool; v_bool; v_oracle; v_bool|]
let v_const_univs = v_sum "constant_universes" 0 [|[|v_context_set|]; [|v_abs_context|]|]
@@ -240,7 +236,6 @@ let v_cb = v_tuple "constant_body"
v_constr;
Any;
v_const_univs;
- Opt v_projbody;
v_bool;
v_typing_flags|]
@@ -277,8 +272,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_id; Array v_constr |]) |] |]
let v_ind_pack_univs =
v_sum "abstract_inductive_universes" 0
@@ -286,7 +283,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/cArray.ml b/clib/cArray.ml
index e2b1a7be..d509c55b 100644
--- a/clib/cArray.ml
+++ b/clib/cArray.ml
@@ -41,6 +41,8 @@ sig
('a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
val fold_left3 :
('a -> 'b -> 'c -> 'd -> 'a) -> 'a -> 'b array -> 'c array -> 'd array -> 'a
+ val fold_left4 :
+ ('a -> 'b -> 'c -> 'd -> 'e -> 'a) -> 'a -> 'b array -> 'c array -> 'd array -> 'e array -> 'a
val fold_left2_i :
(int -> 'a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
val fold_left_from : int -> ('a -> 'b -> 'a) -> 'a -> 'b array -> 'a
@@ -48,13 +50,16 @@ sig
val map_of_list : ('a -> 'b) -> 'a list -> 'b array
val chop : int -> 'a array -> 'a array * 'a array
val smartmap : ('a -> 'a) -> 'a array -> 'a array
+ [@@ocaml.deprecated "Same as [Smart.map]"]
val smartfoldmap : ('r -> 'a -> 'r * 'a) -> 'r -> 'a array -> 'r * 'a array
+ [@@ocaml.deprecated "Same as [Smart.fold_left_map]"]
val map2 : ('a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array
val map2_i : (int -> 'a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array
val map3 :
('a -> 'b -> 'c -> 'd) -> 'a array -> 'b array -> 'c array -> 'd array
val map_left : ('a -> 'b) -> 'a array -> 'b array
val iter2 : ('a -> 'b -> unit) -> 'a array -> 'b array -> unit
+ val iter2_i : (int -> 'a -> 'b -> unit) -> 'a array -> 'b array -> unit
val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b array -> 'a * 'c array
val fold_right_map : ('a -> 'c -> 'b * 'c) -> 'a array -> 'c -> 'b array * 'c
val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b array -> 'c array -> 'a * 'd array
@@ -70,6 +75,25 @@ sig
val rev_of_list : 'a list -> 'a array
val rev_to_list : 'a array -> 'a list
val filter_with : bool list -> 'a array -> 'a array
+ module Smart :
+ sig
+ val map : ('a -> 'a) -> 'a array -> 'a array
+ val map2 : ('a -> 'b -> 'b) -> 'a array -> 'b array -> 'b array
+ val fold_left_map : ('a -> 'b -> 'a * 'b) -> 'a -> 'b array -> 'a * 'b array
+ val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'c) -> 'a -> 'b array -> 'c array -> 'a * 'c array
+ end
+ module Fun1 :
+ sig
+ val map : ('r -> 'a -> 'b) -> 'r -> 'a array -> 'b array
+ val smartmap : ('r -> 'a -> 'a) -> 'r -> 'a array -> 'a array
+ [@@ocaml.deprecated "Same as [Fun1.Smart.map]"]
+ val iter : ('r -> 'a -> unit) -> 'r -> 'a array -> unit
+ val iter2 : ('r -> 'a -> 'b -> unit) -> 'r -> 'a array -> 'b array -> unit
+ module Smart :
+ sig
+ val map : ('r -> 'a -> 'a) -> 'r -> 'a array -> 'a array
+ end
+ end
end
include Array
@@ -257,7 +281,7 @@ let fold_left2_i f a v1 v2 =
let rec fold a n =
if n >= lv1 then a else fold (f n a (uget v1 n) (uget v2 n)) (succ n)
in
- if Array.length v2 <> lv1 then invalid_arg "Array.fold_left2";
+ if Array.length v2 <> lv1 then invalid_arg "Array.fold_left2_i";
fold a 0
let fold_left3 f a v1 v2 v3 =
@@ -267,7 +291,17 @@ let fold_left3 f a v1 v2 v3 =
else fold (f a (uget v1 n) (uget v2 n) (uget v3 n)) (succ n)
in
if Array.length v2 <> lv1 || Array.length v3 <> lv1 then
- invalid_arg "Array.fold_left2";
+ invalid_arg "Array.fold_left3";
+ fold a 0
+
+let fold_left4 f a v1 v2 v3 v4 =
+ let lv1 = Array.length v1 in
+ let rec fold a n =
+ if n >= lv1 then a
+ else fold (f a (uget v1 n) (uget v2 n) (uget v3 n) (uget v4 n)) (succ n)
+ in
+ if Array.length v2 <> lv1 || Array.length v3 <> lv1 || Array.length v4 <> lv1 then
+ invalid_arg "Array.fold_left4";
fold a 0
let fold_left_from n f a v =
@@ -314,72 +348,6 @@ let chop n v =
if n > vlen then failwith "Array.chop";
(Array.sub v 0 n, Array.sub v n (vlen-n))
-(* If none of the elements is changed by f we return ar itself.
- The while loop looks for the first such an element.
- If found, we break here and the new array is produced,
- but f is not re-applied to elements that are already checked *)
-let smartmap f (ar : 'a array) =
- let len = Array.length ar in
- let i = ref 0 in
- let break = ref true in
- let temp = ref None in
- while !break && (!i < len) do
- let v = Array.unsafe_get ar !i in
- let v' = f v in
- if v == v' then incr i
- else begin
- break := false;
- temp := Some v';
- end
- done;
- if !i < len then begin
- (** The array is not the same as the original one *)
- let ans : 'a array = Array.copy ar in
- let v = match !temp with None -> assert false | Some x -> x in
- Array.unsafe_set ans !i v;
- incr i;
- while !i < len do
- let v = Array.unsafe_get ans !i in
- let v' = f v in
- if v != v' then Array.unsafe_set ans !i v';
- incr i
- done;
- ans
- end else ar
-
-(** Same as [smartmap] but threads a state meanwhile *)
-let smartfoldmap f accu (ar : 'a array) =
- let len = Array.length ar in
- let i = ref 0 in
- let break = ref true in
- let r = ref accu in
- (** This variable is never accessed unset *)
- let temp = ref None in
- while !break && (!i < len) do
- let v = Array.unsafe_get ar !i in
- let (accu, v') = f !r v in
- r := accu;
- if v == v' then incr i
- else begin
- break := false;
- temp := Some v';
- end
- done;
- if !i < len then begin
- let ans : 'a array = Array.copy ar in
- let v = match !temp with None -> assert false | Some x -> x in
- Array.unsafe_set ans !i v;
- incr i;
- while !i < len do
- let v = Array.unsafe_get ar !i in
- let (accu, v') = f !r v in
- r := accu;
- if v != v' then Array.unsafe_set ans !i v';
- incr i
- done;
- !r, ans
- end else !r, ar
-
let map2 f v1 v2 =
let len1 = Array.length v1 in
let len2 = Array.length v2 in
@@ -440,6 +408,12 @@ let iter2 f v1 v2 =
let () = if not (Int.equal len2 len1) then invalid_arg "Array.iter2" in
for i = 0 to len1 - 1 do f (uget v1 i) (uget v2 i) done
+let iter2_i f v1 v2 =
+ let len1 = Array.length v1 in
+ let len2 = Array.length v2 in
+ let () = if not (Int.equal len2 len1) then invalid_arg "Array.iter2" in
+ for i = 0 to len1 - 1 do f i (uget v1 i) (uget v2 i) done
+
let pure_functional = false
let fold_right_map f v e =
@@ -496,29 +470,53 @@ let rev_to_list a =
let filter_with filter v =
Array.of_list (CList.filter_with filter (Array.to_list v))
-module Fun1 =
+module Smart =
struct
- let map f arg v = match v with
- | [| |] -> [| |]
- | _ ->
- let len = Array.length v in
- let x0 = Array.unsafe_get v 0 in
- let ans = Array.make len (f arg x0) in
- for i = 1 to pred len do
- let x = Array.unsafe_get v i in
- Array.unsafe_set ans i (f arg x)
+ (* If none of the elements is changed by f we return ar itself.
+ The while loop looks for the first such an element.
+ If found, we break here and the new array is produced,
+ but f is not re-applied to elements that are already checked *)
+ let map f (ar : 'a array) =
+ let len = Array.length ar in
+ let i = ref 0 in
+ let break = ref true in
+ let temp = ref None in
+ while !break && (!i < len) do
+ let v = Array.unsafe_get ar !i in
+ let v' = f v in
+ if v == v' then incr i
+ else begin
+ break := false;
+ temp := Some v';
+ end
done;
- ans
+ if !i < len then begin
+ (** The array is not the same as the original one *)
+ let ans : 'a array = Array.copy ar in
+ let v = match !temp with None -> assert false | Some x -> x in
+ Array.unsafe_set ans !i v;
+ incr i;
+ while !i < len do
+ let v = Array.unsafe_get ans !i in
+ let v' = f v in
+ if v != v' then Array.unsafe_set ans !i v';
+ incr i
+ done;
+ ans
+ end else ar
- let smartmap f arg (ar : 'a array) =
+ let map2 f aux_ar ar =
let len = Array.length ar in
+ let aux_len = Array.length aux_ar in
+ let () = if not (Int.equal len aux_len) then invalid_arg "Array.Smart.map2" in
let i = ref 0 in
let break = ref true in
let temp = ref None in
while !break && (!i < len) do
let v = Array.unsafe_get ar !i in
- let v' = f arg v in
+ let w = Array.unsafe_get aux_ar !i in
+ let v' = f w v in
if v == v' then incr i
else begin
break := false;
@@ -533,13 +531,105 @@ struct
incr i;
while !i < len do
let v = Array.unsafe_get ans !i in
- let v' = f arg v in
+ let w = Array.unsafe_get aux_ar !i in
+ let v' = f w v in
if v != v' then Array.unsafe_set ans !i v';
incr i
done;
ans
end else ar
+ (** Same as [Smart.map] but threads a state meanwhile *)
+ let fold_left_map f accu (ar : 'a array) =
+ let len = Array.length ar in
+ let i = ref 0 in
+ let break = ref true in
+ let r = ref accu in
+ (** This variable is never accessed unset *)
+ let temp = ref None in
+ while !break && (!i < len) do
+ let v = Array.unsafe_get ar !i in
+ let (accu, v') = f !r v in
+ r := accu;
+ if v == v' then incr i
+ else begin
+ break := false;
+ temp := Some v';
+ end
+ done;
+ if !i < len then begin
+ let ans : 'a array = Array.copy ar in
+ let v = match !temp with None -> assert false | Some x -> x in
+ Array.unsafe_set ans !i v;
+ incr i;
+ while !i < len do
+ let v = Array.unsafe_get ar !i in
+ let (accu, v') = f !r v in
+ r := accu;
+ if v != v' then Array.unsafe_set ans !i v';
+ incr i
+ done;
+ !r, ans
+ end else !r, ar
+
+ (** Same as [Smart.map2] but threads a state meanwhile *)
+ let fold_left2_map f accu aux_ar ar =
+ let len = Array.length ar in
+ let aux_len = Array.length aux_ar in
+ let () = if not (Int.equal len aux_len) then invalid_arg "Array.Smart.fold_left2_map" in
+ let i = ref 0 in
+ let break = ref true in
+ let r = ref accu in
+ (** This variable is never accessed unset *)
+ let temp = ref None in
+ while !break && (!i < len) do
+ let v = Array.unsafe_get ar !i in
+ let w = Array.unsafe_get aux_ar !i in
+ let (accu, v') = f !r w v in
+ r := accu;
+ if v == v' then incr i
+ else begin
+ break := false;
+ temp := Some v';
+ end
+ done;
+ if !i < len then begin
+ let ans : 'a array = Array.copy ar in
+ let v = match !temp with None -> assert false | Some x -> x in
+ Array.unsafe_set ans !i v;
+ incr i;
+ while !i < len do
+ let v = Array.unsafe_get ar !i in
+ let w = Array.unsafe_get aux_ar !i in
+ let (accu, v') = f !r w v in
+ r := accu;
+ if v != v' then Array.unsafe_set ans !i v';
+ incr i
+ done;
+ !r, ans
+ end else !r, ar
+
+end
+
+(* Deprecated aliases *)
+let smartmap = Smart.map
+let smartfoldmap = Smart.fold_left_map
+
+module Fun1 =
+struct
+
+ let map f arg v = match v with
+ | [| |] -> [| |]
+ | _ ->
+ let len = Array.length v in
+ let x0 = Array.unsafe_get v 0 in
+ let ans = Array.make len (f arg x0) in
+ for i = 1 to pred len do
+ let x = Array.unsafe_get v i in
+ Array.unsafe_set ans i (f arg x)
+ done;
+ ans
+
let iter f arg v =
let len = Array.length v in
for i = 0 to pred len do
@@ -547,4 +637,50 @@ struct
f arg x
done
+ let iter2 f arg v1 v2 =
+ let len1 = Array.length v1 in
+ let len2 = Array.length v2 in
+ let () = if not (Int.equal len2 len1) then invalid_arg "Array.Fun1.iter2" in
+ for i = 0 to pred len1 do
+ let x1 = uget v1 i in
+ let x2 = uget v2 i in
+ f arg x1 x2
+ done
+
+ module Smart =
+ struct
+
+ let map f arg (ar : 'a array) =
+ let len = Array.length ar in
+ let i = ref 0 in
+ let break = ref true in
+ let temp = ref None in
+ while !break && (!i < len) do
+ let v = Array.unsafe_get ar !i in
+ let v' = f arg v in
+ if v == v' then incr i
+ else begin
+ break := false;
+ temp := Some v';
+ end
+ done;
+ if !i < len then begin
+ (** The array is not the same as the original one *)
+ let ans : 'a array = Array.copy ar in
+ let v = match !temp with None -> assert false | Some x -> x in
+ Array.unsafe_set ans !i v;
+ incr i;
+ while !i < len do
+ let v = Array.unsafe_get ans !i in
+ let v' = f arg v in
+ if v != v' then Array.unsafe_set ans !i v';
+ incr i
+ done;
+ ans
+ end else ar
+
+ end
+
+ let smartmap = Smart.map
+
end
diff --git a/clib/cArray.mli b/clib/cArray.mli
index fa3978bd..5c7e09ee 100644
--- a/clib/cArray.mli
+++ b/clib/cArray.mli
@@ -66,6 +66,8 @@ sig
('a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
val fold_left3 :
('a -> 'b -> 'c -> 'd -> 'a) -> 'a -> 'b array -> 'c array -> 'd array -> 'a
+ val fold_left4 :
+ ('a -> 'b -> 'c -> 'd -> 'e -> 'a) -> 'a -> 'b array -> 'c array -> 'd array -> 'e array -> 'a
val fold_left2_i :
(int -> 'a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
val fold_left_from : int -> ('a -> 'b -> 'a) -> 'a -> 'b array -> 'a
@@ -81,13 +83,14 @@ sig
Raise [Failure "Array.chop"] if [i] is not a valid index. *)
val smartmap : ('a -> 'a) -> 'a array -> 'a array
- (** [smartmap f a] behaves as [map f a] but returns [a] instead of a copy when
- [f x == x] for all [x] in [a]. *)
+ [@@ocaml.deprecated "Same as [Smart.map]"]
val smartfoldmap : ('r -> 'a -> 'r * 'a) -> 'r -> 'a array -> 'r * 'a array
- (** Same as [smartmap] but threads an additional state left-to-right. *)
+ [@@ocaml.deprecated "Same as [Smart.fold_left_map]"]
val map2 : ('a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array
+ (** See also [Smart.map2] *)
+
val map2_i : (int -> 'a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array
val map3 :
('a -> 'b -> 'c -> 'd) -> 'a array -> 'b array -> 'c array -> 'd array
@@ -98,15 +101,18 @@ sig
val iter2 : ('a -> 'b -> unit) -> 'a array -> 'b array -> unit
(** Iter on two arrays. Raise [Invalid_argument "Array.iter2"] if sizes differ. *)
+ val iter2_i : (int -> 'a -> 'b -> unit) -> 'a array -> 'b array -> unit
+ (** Iter on two arrays. Raise [Invalid_argument "Array.iter2_i"] if sizes differ. *)
+
val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b array -> 'a * 'c array
(** [fold_left_map f e_0 [|l_1...l_n|] = e_n,[|k_1...k_n|]]
- where [(e_i,k_i)=f e_{i-1} l_i] *)
+ where [(e_i,k_i)=f e_{i-1} l_i]; see also [Smart.fold_left_map] *)
val fold_right_map : ('a -> 'c -> 'b * 'c) -> 'a array -> 'c -> 'b array * 'c
(** Same, folding on the right *)
val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b array -> 'c array -> 'a * 'd array
- (** Same with two arrays, folding on the left *)
+ (** Same with two arrays, folding on the left; see also [Smart.fold_left2_map] *)
val fold_right2_map : ('a -> 'b -> 'c -> 'd * 'c) -> 'a array -> 'b array -> 'c -> 'd array * 'c
(** Same with two arrays, folding on the left *)
@@ -135,23 +141,57 @@ sig
(** [filter_with b a] selects elements of [a] whose corresponding element in
[b] is [true]. Raise [Invalid_argument _] when sizes differ. *)
+ module Smart :
+ sig
+ val map : ('a -> 'a) -> 'a array -> 'a array
+ (** [Smart.map f a] behaves as [map f a] but returns [a] instead of a copy when
+ [f x == x] for all [x] in [a]. *)
+
+ val map2 : ('a -> 'b -> 'b) -> 'a array -> 'b array -> 'b array
+ (** [Smart.map2 f a b] behaves as [map2 f a b] but returns [a] instead of a copy when
+ [f x y == y] for all [x] in [a] and [y] in [b] pointwise. *)
+
+ val fold_left_map : ('a -> 'b -> 'a * 'b) -> 'a -> 'b array -> 'a * 'b array
+ (** [Smart.fold_left_mapf a b] behaves as [fold_left_map] but
+ returns [b] as second component instead of a copy of [b] when
+ the output array is pointwise the same as the input array [b] *)
+
+ val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'c) -> 'a -> 'b array -> 'c array -> 'a * 'c array
+ (** [Smart.fold_left2_map f a b c] behaves as [fold_left2_map] but
+ returns [c] as second component instead of a copy of [c] when
+ the output array is pointwise the same as the input array [c] *)
+
+ end
+ (** The functions defined in this module are optimized specializations
+ of the main ones, when the returned array is of same type as one of
+ the original array. *)
+
+ module Fun1 :
+ sig
+ val map : ('r -> 'a -> 'b) -> 'r -> 'a array -> 'b array
+ (** [Fun1.map f x v = map (f x) v] *)
+
+ val smartmap : ('r -> 'a -> 'a) -> 'r -> 'a array -> 'a array
+ [@@ocaml.deprecated "Same as [Fun1.Smart.map]"]
+
+ val iter : ('r -> 'a -> unit) -> 'r -> 'a array -> unit
+ (** [Fun1.iter f x v = iter (f x) v] *)
+
+ val iter2 : ('r -> 'a -> 'b -> unit) -> 'r -> 'a array -> 'b array -> unit
+ (** [Fun1.iter2 f x v1 v2 = iter (f x) v1 v2] *)
+
+ module Smart :
+ sig
+ val map : ('r -> 'a -> 'a) -> 'r -> 'a array -> 'a array
+ (** [Fun1.Smart.map f x v = Smart.map (f x) v] *)
+ end
+
+ end
+ (** The functions defined in this module are the same as the main ones, except
+ that they are all higher-order, and their function arguments have an
+ additional parameter. This allows us to prevent closure creation in critical
+ cases. *)
+
end
include ExtS
-
-module Fun1 :
-sig
- val map : ('r -> 'a -> 'b) -> 'r -> 'a array -> 'b array
- (** [Fun1.map f x v = map (f x) v] *)
-
- val smartmap : ('r -> 'a -> 'a) -> 'r -> 'a array -> 'a array
- (** [Fun1.smartmap f x v = smartmap (f x) v] *)
-
- val iter : ('r -> 'a -> unit) -> 'r -> 'a array -> unit
- (** [Fun1.iter f x v = iter (f x) v] *)
-
-end
-(** The functions defined in this module are the same as the main ones, except
- that they are all higher-order, and their function arguments have an
- additional parameter. This allows us to prevent closure creation in critical
- cases. *)
diff --git a/clib/cList.ml b/clib/cList.ml
index b25c4ffd..dc59ff29 100644
--- a/clib/cList.ml
+++ b/clib/cList.ml
@@ -19,26 +19,33 @@ sig
val compare : 'a cmp -> 'a list cmp
val equal : 'a eq -> 'a list eq
val is_empty : 'a list -> bool
- val init : int -> (int -> 'a) -> 'a list
val mem_f : 'a eq -> 'a -> 'a list -> bool
- val add_set : 'a eq -> 'a -> 'a list -> 'a list
- val eq_set : 'a eq -> 'a list -> 'a list -> bool
- val intersect : 'a eq -> 'a list -> 'a list -> 'a list
- val union : 'a eq -> 'a list -> 'a list -> 'a list
- val unionq : 'a list -> 'a list -> 'a list
- val subtract : 'a eq -> 'a list -> 'a list -> 'a list
- val subtractq : 'a list -> 'a list -> 'a list
+ val for_all_i : (int -> 'a -> bool) -> int -> 'a list -> bool
+ val for_all2eq : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool
+ val prefix_of : 'a eq -> 'a list -> 'a list -> bool
val interval : int -> int -> int list
val make : int -> 'a -> 'a list
+ val addn : int -> 'a -> 'a list -> 'a list
+ val init : int -> (int -> 'a) -> 'a list
+ val append : 'a list -> 'a list -> 'a list
+ val concat : 'a list list -> 'a list
+ val flatten : 'a list list -> 'a list
val assign : 'a list -> int -> 'a -> 'a list
- val distinct : 'a list -> bool
- val distinct_f : 'a cmp -> 'a list -> bool
- val duplicates : 'a eq -> 'a list -> 'a list
+ val filter : ('a -> bool) -> 'a list -> 'a list
val filter2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> 'a list * 'b list
+ val filteri :
+ (int -> 'a -> bool) -> 'a list -> 'a list
+ val filter_with : bool list -> 'a list -> 'a list
+ val smartfilter : ('a -> bool) -> 'a list -> 'a list
+ [@@ocaml.deprecated "Same as [filter]"]
val map_filter : ('a -> 'b option) -> 'a list -> 'b list
val map_filter_i : (int -> 'a -> 'b option) -> 'a list -> 'b list
- val filter_with : bool list -> 'a list -> 'a list
+ val partitioni :
+ (int -> 'a -> bool) -> 'a list -> 'a list * 'a list
+ val map : ('a -> 'b) -> 'a list -> 'b list
+ val map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
val smartmap : ('a -> 'a) -> 'a list -> 'a list
+ [@@ocaml.deprecated "Same as [Smart.map]"]
val map_left : ('a -> 'b) -> 'a list -> 'b list
val map_i : (int -> 'a -> 'b) -> int -> 'a list -> 'b list
val map2_i :
@@ -47,17 +54,14 @@ sig
('a -> 'b -> 'c -> 'd) -> 'a list -> 'b list -> 'c list -> 'd list
val map4 :
('a -> 'b -> 'c -> 'd -> 'e) -> 'a list -> 'b list -> 'c list -> 'd list -> 'e list
- val filteri :
- (int -> 'a -> bool) -> 'a list -> 'a list
- val partitioni :
- (int -> 'a -> bool) -> 'a list -> 'a list * 'a list
val map_of_array : ('a -> 'b) -> 'a array -> 'b list
- val smartfilter : ('a -> bool) -> 'a list -> 'a list
+ val map_append : ('a -> 'b list) -> 'a list -> 'b list
+ val map_append2 : ('a -> 'b -> 'c list) -> 'a list -> 'b list -> 'c list
val extend : bool list -> 'a -> 'a list -> 'a list
val count : ('a -> bool) -> 'a list -> int
val index : 'a eq -> 'a -> 'a list -> int
+ val safe_index : 'a eq -> 'a -> 'a list -> int option
val index0 : 'a eq -> 'a -> 'a list -> int
- val iteri : (int -> 'a -> unit) -> 'a list -> unit
val fold_left_until : ('c -> 'a -> 'c CSig.until) -> 'c -> 'a list -> 'c
val fold_right_i : (int -> 'a -> 'b -> 'b) -> int -> 'a list -> 'b -> 'b
val fold_left_i : (int -> 'a -> 'b -> 'a) -> int -> 'a -> 'b list -> 'a
@@ -65,58 +69,71 @@ sig
('a -> 'b -> 'b list -> 'a) -> 'b list -> 'a -> 'a
val fold_left3 : ('a -> 'b -> 'c -> 'd -> 'a) -> 'a -> 'b list -> 'c list -> 'd list -> 'a
val fold_left2_set : exn -> ('a -> 'b -> 'c -> 'b list -> 'c list -> 'a) -> 'a -> 'b list -> 'c list -> 'a
- val for_all_i : (int -> 'a -> bool) -> int -> 'a list -> bool
+ val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
+ val fold_right_map : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
+ val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b list -> 'c list -> 'a * 'd list
+ val fold_right2_map : ('b -> 'c -> 'a -> 'd * 'a) -> 'b list -> 'c list -> 'a -> 'd list * 'a
+ val fold_left3_map : ('a -> 'b -> 'c -> 'd -> 'a * 'e) -> 'a -> 'b list -> 'c list -> 'd list -> 'a * 'e list
+ val fold_left4_map : ('a -> 'b -> 'c -> 'd -> 'e -> 'a * 'r) -> 'a -> 'b list -> 'c list -> 'd list -> 'e list -> 'a * 'r list
+ val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
+ [@@ocaml.deprecated "Same as [fold_left_map]"]
+ val fold_map' : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
+ [@@ocaml.deprecated "Same as [fold_right_map]"]
val except : 'a eq -> 'a -> 'a list -> 'a list
val remove : 'a eq -> 'a -> 'a list -> 'a list
val remove_first : ('a -> bool) -> 'a list -> 'a list
val extract_first : ('a -> bool) -> 'a list -> 'a list * 'a
- val insert : ('a -> 'a -> bool) -> 'a -> 'a list -> 'a list
- val for_all2eq : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool
- val sep_last : 'a list -> 'a * 'a list
val find_map : ('a -> 'b option) -> 'a list -> 'b
- val uniquize : 'a list -> 'a list
- val sort_uniquize : 'a cmp -> 'a list -> 'a list
- val merge_uniq : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
- val subset : 'a list -> 'a list -> bool
- val chop : int -> 'a list -> 'a list * 'a list
exception IndexOutOfRange
val goto : int -> 'a list -> 'a list * 'a list
val split_when : ('a -> bool) -> 'a list -> 'a list * 'a list
- val split3 : ('a * 'b * 'c) list -> 'a list * 'b list * 'c list
- val firstn : int -> 'a list -> 'a list
+ val sep_last : 'a list -> 'a * 'a list
+ val drop_last : 'a list -> 'a list
val last : 'a list -> 'a
val lastn : int -> 'a list -> 'a list
+ val chop : int -> 'a list -> 'a list * 'a list
+ val firstn : int -> 'a list -> 'a list
val skipn : int -> 'a list -> 'a list
val skipn_at_least : int -> 'a list -> 'a list
- val addn : int -> 'a -> 'a list -> 'a list
- val prefix_of : 'a eq -> 'a list -> 'a list -> bool
val drop_prefix : 'a eq -> 'a list -> 'a list -> 'a list
- val drop_last : 'a list -> 'a list
- val map_append : ('a -> 'b list) -> 'a list -> 'b list
- val map_append2 : ('a -> 'b -> 'c list) -> 'a list -> 'b list -> 'c list
+ val insert : ('a -> 'a -> bool) -> 'a -> 'a list -> 'a list
val share_tails : 'a list -> 'a list -> 'a list * 'a list * 'a list
- val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
- val fold_right_map : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
- val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b list -> 'c list -> 'a * 'd list
- val fold_right2_map : ('b -> 'c -> 'a -> 'd * 'a) -> 'b list -> 'c list -> 'a -> 'd list * 'a
- val fold_left3_map : ('a -> 'b -> 'c -> 'd -> 'a * 'e) -> 'a -> 'b list -> 'c list -> 'd list -> 'a * 'e list
- val fold_left4_map : ('a -> 'b -> 'c -> 'd -> 'e -> 'a * 'r) -> 'a -> 'b list -> 'c list -> 'd list -> 'e list -> 'a * 'r list
- val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
- [@@ocaml.deprecated "Same as [fold_left_map]"]
- val fold_map' : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
- [@@ocaml.deprecated "Same as [fold_right_map]"]
val map_assoc : ('a -> 'b) -> ('c * 'a) list -> ('c * 'b) list
val assoc_f : 'a eq -> 'a -> ('a * 'b) list -> 'b
val remove_assoc_f : 'a eq -> 'a -> ('a * 'b) list -> ('a * 'b) list
val mem_assoc_f : 'a eq -> 'a -> ('a * 'b) list -> bool
+ val factorize_left : 'a eq -> ('a * 'b) list -> ('a * 'b list) list
+ val split : ('a * 'b) list -> 'a list * 'b list
+ val combine : 'a list -> 'b list -> ('a * 'b) list
+ val split3 : ('a * 'b * 'c) list -> 'a list * 'b list * 'c list
+ val combine3 : 'a list -> 'b list -> 'c list -> ('a * 'b * 'c) list
+ val add_set : 'a eq -> 'a -> 'a list -> 'a list
+ val eq_set : 'a eq -> 'a list -> 'a list -> bool
+ val subset : 'a list -> 'a list -> bool
+ val merge_set : 'a cmp -> 'a list -> 'a list -> 'a list
+ val intersect : 'a eq -> 'a list -> 'a list -> 'a list
+ val union : 'a eq -> 'a list -> 'a list -> 'a list
+ val unionq : 'a list -> 'a list -> 'a list
+ val subtract : 'a eq -> 'a list -> 'a list -> 'a list
+ val subtractq : 'a list -> 'a list -> 'a list
+ val merge_uniq : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
+ [@@ocaml.deprecated "Same as [merge_set]"]
+ val distinct : 'a list -> bool
+ val distinct_f : 'a cmp -> 'a list -> bool
+ 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
- val combine3 : 'a list -> 'b list -> 'c list -> ('a * 'b * 'c) list
val cartesians_filter :
('a -> 'b -> 'b option) -> 'b -> 'a list list -> 'b list
- val factorize_left : 'a eq -> ('a * 'b) list -> ('a * 'b list) list
+
+ module Smart :
+ sig
+ val map : ('a -> 'a) -> 'a list -> 'a list
+ end
module type MonoS = sig
type elt
@@ -142,71 +159,71 @@ type 'a cell = {
external cast : 'a cell -> 'a list = "%identity"
-let rec map_loop f p = function
-| [] -> ()
-| x :: l ->
- let c = { head = f x; tail = [] } in
- p.tail <- cast c;
- map_loop f c l
+(** Extensions and redefinitions of OCaml Stdlib *)
-let map f = function
-| [] -> []
-| x :: l ->
- let c = { head = f x; tail = [] } in
- map_loop f c l;
- cast c
+(** {6 Equality, testing} *)
-let rec map2_loop f p l1 l2 = match l1, l2 with
-| [], [] -> ()
-| x :: l1, y :: l2 ->
- let c = { head = f x y; tail = [] } in
- p.tail <- cast c;
- map2_loop f c l1 l2
-| _ -> invalid_arg "List.map2"
+let rec compare cmp l1 l2 =
+ if l1 == l2 then 0 else
+ match l1,l2 with
+ | [], [] -> 0
+ | _::_, [] -> 1
+ | [], _::_ -> -1
+ | x1::l1, x2::l2 ->
+ match cmp x1 x2 with
+ | 0 -> compare cmp l1 l2
+ | c -> c
-let map2 f l1 l2 = match l1, l2 with
-| [], [] -> []
-| x :: l1, y :: l2 ->
- let c = { head = f x y; tail = [] } in
- map2_loop f c l1 l2;
- cast c
-| _ -> invalid_arg "List.map2"
+let rec equal cmp l1 l2 =
+ l1 == l2 ||
+ match l1, l2 with
+ | [], [] -> true
+ | x1 :: l1, x2 :: l2 -> cmp x1 x2 && equal cmp l1 l2
+ | _ -> false
-let rec map_of_array_loop f p a i l =
- if Int.equal i l then ()
- else
- let c = { head = f (Array.unsafe_get a i); tail = [] } in
- p.tail <- cast c;
- map_of_array_loop f c a (i + 1) l
+let is_empty = function
+ | [] -> true
+ | _ -> false
-let map_of_array f a =
- let l = Array.length a in
- if Int.equal l 0 then []
- else
- let c = { head = f (Array.unsafe_get a 0); tail = [] } in
- map_of_array_loop f c a 1 l;
- cast c
+let mem_f cmp x l =
+ List.exists (cmp x) l
-let rec append_loop p tl = function
-| [] -> p.tail <- tl
-| x :: l ->
- let c = { head = x; tail = [] } in
- p.tail <- cast c;
- append_loop c tl l
+let for_all_i p =
+ let rec for_all_p i = function
+ | [] -> true
+ | a::l -> p i a && for_all_p (i+1) l
+ in
+ for_all_p
-let append l1 l2 = match l1 with
-| [] -> l2
-| x :: l ->
- let c = { head = x; tail = [] } in
- append_loop c l2 l;
- cast c
+let for_all2eq f l1 l2 =
+ try List.for_all2 f l1 l2 with Invalid_argument _ -> false
-let rec copy p = function
-| [] -> p
-| x :: l ->
- let c = { head = x; tail = [] } in
- p.tail <- cast c;
- copy c l
+let prefix_of cmp prefl l =
+ let rec prefrec = function
+ | (h1::t1, h2::t2) -> cmp h1 h2 && prefrec (t1,t2)
+ | ([], _) -> true
+ | _ -> false
+ in
+ prefrec (prefl,l)
+
+(** {6 Creating lists} *)
+
+let interval n m =
+ let rec interval_n (l,m) =
+ if n > m then l else interval_n (m::l, pred m)
+ in
+ interval_n ([], m)
+
+let addn n v =
+ let rec aux n l =
+ if Int.equal n 0 then l
+ else aux (pred n) (v :: l)
+ in
+ if n < 0 then invalid_arg "List.addn"
+ else aux n
+
+let make n v =
+ addn n v []
let rec init_loop len f p i =
if Int.equal i len then ()
@@ -223,9 +240,30 @@ let init len f =
init_loop len f c 1;
cast c
+let rec append_loop p tl = function
+ | [] -> p.tail <- tl
+ | x :: l ->
+ let c = { head = x; tail = [] } in
+ p.tail <- cast c;
+ append_loop c tl l
+
+let append l1 l2 = match l1 with
+ | [] -> l2
+ | x :: l ->
+ let c = { head = x; tail = [] } in
+ append_loop c l2 l;
+ cast c
+
+let rec copy p = function
+ | [] -> p
+ | x :: l ->
+ let c = { head = x; tail = [] } in
+ p.tail <- cast c;
+ copy c l
+
let rec concat_loop p = function
-| [] -> ()
-| x :: l -> concat_loop (copy p x) l
+ | [] -> ()
+ | x :: l -> concat_loop (copy p x) l
let concat l =
let dummy = { head = Obj.magic 0; tail = [] } in
@@ -234,230 +272,310 @@ let concat l =
let flatten = concat
-let rec split_loop p q = function
-| [] -> ()
-| (x, y) :: l ->
- let cl = { head = x; tail = [] } in
- let cr = { head = y; tail = [] } in
- p.tail <- cast cl;
- q.tail <- cast cr;
- split_loop cl cr l
-
-let split = function
-| [] -> [], []
-| (x, y) :: l ->
- let cl = { head = x; tail = [] } in
- let cr = { head = y; tail = [] } in
- split_loop cl cr l;
- (cast cl, cast cr)
+(** {6 Lists as arrays} *)
-let rec combine_loop p l1 l2 = match l1, l2 with
-| [], [] -> ()
-| x :: l1, y :: l2 ->
- let c = { head = (x, y); tail = [] } in
- p.tail <- cast c;
- combine_loop c l1 l2
-| _ -> invalid_arg "List.combine"
+let assign l n e =
+ let rec assrec stk l i = match l, i with
+ | (h :: t, 0) -> List.rev_append stk (e :: t)
+ | (h :: t, n) -> assrec (h :: stk) t (pred n)
+ | ([], _) -> failwith "List.assign"
+ in
+ assrec [] l n
-let combine l1 l2 = match l1, l2 with
-| [], [] -> []
-| x :: l1, y :: l2 ->
- let c = { head = (x, y); tail = [] } in
- combine_loop c l1 l2;
- cast c
-| _ -> invalid_arg "List.combine"
+(** {6 Filtering} *)
let rec filter_loop f p = function
-| [] -> ()
-| x :: l ->
- if f x then
- let c = { head = x; tail = [] } in
- let () = p.tail <- cast c in
- filter_loop f c l
- else
- filter_loop f p l
+ | [] -> ()
+ | x :: l' as l ->
+ let b = f x in
+ filter_loop f p l';
+ if b then if p.tail == l' then p.tail <- l else p.tail <- x :: p.tail
-let filter f l =
- let c = { head = Obj.magic 0; tail = [] } in
- filter_loop f c l;
- c.tail
+let rec filter f = function
+ | [] -> []
+ | x :: l' as l ->
+ if f x then
+ let c = { head = x; tail = [] } in
+ filter_loop f c l';
+ if c.tail == l' then l else cast c
+ else
+ filter f l'
-(** FIXME: Already present in OCaml 4.00 *)
+let rec filter2_loop f p q l1 l2 = match l1, l2 with
+ | [], [] -> ()
+ | x :: l1', y :: l2' ->
+ let b = f x y in
+ filter2_loop f p q l1' l2';
+ if b then
+ if p.tail == l1' then begin
+ p.tail <- l1;
+ q.tail <- l2
+ end
+ else begin
+ p.tail <- x :: p.tail;
+ q.tail <- y :: q.tail
+ end
+ | _ -> invalid_arg "List.filter2"
+
+let rec filter2 f l1 l2 = match l1, l2 with
+ | [], [] -> ([],[])
+ | x1 :: l1', x2 :: l2' ->
+ let b = f x1 x2 in
+ if b then
+ let c1 = { head = x1; tail = [] } in
+ let c2 = { head = x2; tail = [] } in
+ filter2_loop f c1 c2 l1' l2';
+ if c1.tail == l1' then (l1, l2) else (cast c1, cast c2)
+ else
+ filter2 f l1' l2'
+ | _ -> invalid_arg "List.filter2"
-let rec map_i_loop f i p = function
-| [] -> ()
-| x :: l ->
- let c = { head = f i x; tail = [] } in
- p.tail <- cast c;
- map_i_loop f (succ i) c l
+let filteri p =
+ let rec filter_i_rec i = function
+ | [] -> []
+ | x :: l -> let l' = filter_i_rec (succ i) l in if p i x then x :: l' else l'
+ in
+ filter_i_rec 0
-let map_i f i = function
-| [] -> []
-| x :: l ->
- let c = { head = f i x; tail = [] } in
- map_i_loop f (succ i) c l;
- cast c
+let smartfilter = filter (* Alias *)
-(** Extensions of OCaml Stdlib *)
+let rec filter_with_loop filter p l = match filter, l with
+ | [], [] -> ()
+ | b :: filter, x :: l' ->
+ filter_with_loop filter p l';
+ if b then if p.tail == l' then p.tail <- l else p.tail <- x :: p.tail
+ | _ -> invalid_arg "List.filter_with"
-let rec compare cmp l1 l2 =
- if l1 == l2 then 0 else
- match l1,l2 with
- [], [] -> 0
- | _::_, [] -> 1
- | [], _::_ -> -1
- | x1::l1, x2::l2 ->
- (match cmp x1 x2 with
- | 0 -> compare cmp l1 l2
- | c -> c)
+let rec filter_with filter l = match filter, l with
+ | [], [] -> []
+ | b :: filter, x :: l' ->
+ if b then
+ let c = { head = x; tail = [] } in
+ filter_with_loop filter c l';
+ if c.tail == l' then l else cast c
+ else filter_with filter l'
+ | _ -> invalid_arg "List.filter_with"
-let rec equal cmp l1 l2 =
- l1 == l2 ||
- match l1, l2 with
- | [], [] -> true
- | x1 :: l1, x2 :: l2 ->
- cmp x1 x2 && equal cmp l1 l2
- | _ -> false
+let rec map_filter_loop f p = function
+ | [] -> ()
+ | x :: l ->
+ match f x with
+ | None -> map_filter_loop f p l
+ | Some y ->
+ let c = { head = y; tail = [] } in
+ p.tail <- cast c;
+ map_filter_loop f c l
-let is_empty = function
-| [] -> true
-| _ -> false
+let rec map_filter f = function
+ | [] -> []
+ | x :: l' ->
+ match f x with
+ | None -> map_filter f l'
+ | Some y ->
+ let c = { head = y; tail = [] } in
+ map_filter_loop f c l';
+ cast c
-let mem_f cmp x l = List.exists (cmp x) l
+let rec map_filter_i_loop f i p = function
+ | [] -> ()
+ | x :: l ->
+ match f i x with
+ | None -> map_filter_i_loop f (succ i) p l
+ | Some y ->
+ let c = { head = y; tail = [] } in
+ p.tail <- cast c;
+ map_filter_i_loop f (succ i) c l
-let intersect cmp l1 l2 =
- filter (fun x -> mem_f cmp x l2) l1
+let rec map_filter_i_loop' f i = function
+ | [] -> []
+ | x :: l' ->
+ match f i x with
+ | None -> map_filter_i_loop' f (succ i) l'
+ | Some y ->
+ let c = { head = y; tail = [] } in
+ map_filter_i_loop f (succ i) c l';
+ cast c
-let union cmp l1 l2 =
- let rec urec = function
- | [] -> l2
- | a::l -> if mem_f cmp a l2 then urec l else a::urec l
+let map_filter_i f l =
+ map_filter_i_loop' f 0 l
+
+let partitioni p =
+ let rec aux i = function
+ | [] -> [], []
+ | x :: l ->
+ let (l1, l2) = aux (succ i) l in
+ if p i x then (x :: l1, l2)
+ else (l1, x :: l2)
in
- urec l1
+ aux 0
-let subtract cmp l1 l2 =
- if is_empty l2 then l1
- else List.filter (fun x -> not (mem_f cmp x l2)) l1
+(** {6 Applying functorially} *)
-let unionq l1 l2 = union (==) l1 l2
-let subtractq l1 l2 = subtract (==) l1 l2
+let rec map_loop f p = function
+ | [] -> ()
+ | x :: l ->
+ let c = { head = f x; tail = [] } in
+ p.tail <- cast c;
+ map_loop f c l
-let interval n m =
- let rec interval_n (l,m) =
- if n > m then l else interval_n (m::l, pred m)
- in
- interval_n ([], m)
+let map f = function
+ | [] -> []
+ | x :: l ->
+ let c = { head = f x; tail = [] } in
+ map_loop f c l;
+ cast c
-let addn n v =
- let rec aux n l =
- if Int.equal n 0 then l
- else aux (pred n) (v :: l)
- in
- if n < 0 then invalid_arg "List.addn"
- else aux n
+let rec map2_loop f p l1 l2 = match l1, l2 with
+ | [], [] -> ()
+ | x :: l1, y :: l2 ->
+ let c = { head = f x y; tail = [] } in
+ p.tail <- cast c;
+ map2_loop f c l1 l2
+ | _ -> invalid_arg "List.map2"
-let make n v = addn n v []
+let map2 f l1 l2 = match l1, l2 with
+ | [], [] -> []
+ | x :: l1, y :: l2 ->
+ let c = { head = f x y; tail = [] } in
+ map2_loop f c l1 l2;
+ cast c
+ | _ -> invalid_arg "List.map2"
-let assign l n e =
- let rec assrec stk l i = match l, i with
- | ((h::t), 0) -> List.rev_append stk (e :: t)
- | ((h::t), n) -> assrec (h :: stk) t (pred n)
- | ([], _) -> failwith "List.assign"
- in
- assrec [] l n
+(** Like OCaml [List.mapi] but tail-recursive *)
+
+let rec map_i_loop f i p = function
+ | [] -> ()
+ | x :: l ->
+ let c = { head = f i x; tail = [] } in
+ p.tail <- cast c;
+ map_i_loop f (succ i) c l
-let rec smartmap f l = match l with
- [] -> l
- | h::tl ->
- let h' = f h and tl' = smartmap f tl in
- if h'==h && tl'==tl then l
- else h'::tl'
+let map_i f i = function
+ | [] -> []
+ | x :: l ->
+ let c = { head = f i x; tail = [] } in
+ map_i_loop f (succ i) c l;
+ cast c
let map_left = map
let map2_i f i l1 l2 =
let rec map_i i = function
| ([], []) -> []
- | ((h1::t1), (h2::t2)) -> let v = f i h1 h2 in v :: map_i (succ i) (t1,t2)
+ | (h1 :: t1, h2 :: t2) -> let v = f i h1 h2 in v :: map_i (succ i) (t1,t2)
| (_, _) -> invalid_arg "map2_i"
in
map_i i (l1,l2)
-let map3 f l1 l2 l3 =
- let rec map = function
- | ([], [], []) -> []
- | ((h1::t1), (h2::t2), (h3::t3)) -> let v = f h1 h2 h3 in v::map (t1,t2,t3)
- | (_, _, _) -> invalid_arg "map3"
- in
- map (l1,l2,l3)
+let rec map3_loop f p l1 l2 l3 = match l1, l2, l3 with
+ | [], [], [] -> ()
+ | x :: l1, y :: l2, z :: l3 ->
+ let c = { head = f x y z; tail = [] } in
+ p.tail <- cast c;
+ map3_loop f c l1 l2 l3
+ | _ -> invalid_arg "List.map3"
-let map4 f l1 l2 l3 l4 =
- let rec map = function
- | ([], [], [], []) -> []
- | ((h1::t1), (h2::t2), (h3::t3), (h4::t4)) -> let v = f h1 h2 h3 h4 in v::map (t1,t2,t3,t4)
- | (_, _, _, _) -> invalid_arg "map4"
- in
- map (l1,l2,l3,l4)
+let map3 f l1 l2 l3 = match l1, l2, l3 with
+ | [], [], [] -> []
+ | x :: l1, y :: l2, z :: l3 ->
+ let c = { head = f x y z; tail = [] } in
+ map3_loop f c l1 l2 l3;
+ cast c
+ | _ -> invalid_arg "List.map3"
+
+let rec map4_loop f p l1 l2 l3 l4 = match l1, l2, l3, l4 with
+ | [], [], [], [] -> ()
+ | x :: l1, y :: l2, z :: l3, t :: l4 ->
+ let c = { head = f x y z t; tail = [] } in
+ p.tail <- cast c;
+ map4_loop f c l1 l2 l3 l4
+ | _ -> invalid_arg "List.map4"
+
+let map4 f l1 l2 l3 l4 = match l1, l2, l3, l4 with
+ | [], [], [], [] -> []
+ | x :: l1, y :: l2, z :: l3, t :: l4 ->
+ let c = { head = f x y z t; tail = [] } in
+ map4_loop f c l1 l2 l3 l4;
+ cast c
+ | _ -> invalid_arg "List.map4"
+
+let rec map_of_array_loop f p a i l =
+ if Int.equal i l then ()
+ else
+ let c = { head = f (Array.unsafe_get a i); tail = [] } in
+ p.tail <- cast c;
+ map_of_array_loop f c a (i + 1) l
+
+let map_of_array f a =
+ let l = Array.length a in
+ if Int.equal l 0 then []
+ else
+ let c = { head = f (Array.unsafe_get a 0); tail = [] } in
+ map_of_array_loop f c a 1 l;
+ cast c
+
+let map_append f l = flatten (map f l)
-let rec smartfilter f l = match l with
- [] -> l
- | h::tl ->
- let tl' = smartfilter f tl in
- if f h then
- if tl' == tl then l
- else h :: tl'
- else tl'
+let map_append2 f l1 l2 = flatten (map2 f l1 l2)
let rec extend l a l' = match l,l' with
- | true::l, b::l' -> b :: extend l a l'
- | false::l, l' -> a :: extend l a l'
+ | true :: l, b :: l' -> b :: extend l a l'
+ | false :: l, l' -> a :: extend l a l'
| [], [] -> []
| _ -> invalid_arg "extend"
let count f l =
let rec aux acc = function
| [] -> acc
- | h :: t -> if f h then aux (acc + 1) t else aux acc t in
+ | h :: t -> if f h then aux (acc + 1) t else aux acc t
+ in
aux 0 l
+(** {6 Finding position} *)
+
let rec index_f f x l n = match l with
-| [] -> raise Not_found
-| y :: l -> if f x y then n else index_f f x l (succ n)
+ | [] -> raise Not_found
+ | y :: l -> if f x y then n else index_f f x l (succ n)
let index f x l = index_f f x l 1
+let safe_index f x l = try Some (index f x l) with Not_found -> None
+
let index0 f x l = index_f f x l 0
+(** {6 Folding} *)
+
let fold_left_until f accu s =
let rec aux accu = function
| [] -> accu
- | x :: xs -> match f accu x with CSig.Stop x -> x | CSig.Cont i -> aux i xs in
+ | x :: xs -> match f accu x with CSig.Stop x -> x | CSig.Cont i -> aux i xs
+ in
aux accu s
let fold_right_i f i l =
let rec it_f i l a = match l with
| [] -> a
- | b::l -> f (i-1) b (it_f (i-1) l a)
+ | b :: l -> f (i-1) b (it_f (i-1) l a)
in
it_f (List.length l + i) l
let fold_left_i f =
let rec it_list_f i a = function
| [] -> a
- | b::l -> it_list_f (i+1) (f i a b) l
+ | b :: l -> it_list_f (i+1) (f i a b) l
in
it_list_f
let rec fold_left3 f accu l1 l2 l3 =
match (l1, l2, l3) with
- ([], [], []) -> accu
- | (a1::l1, a2::l2, a3::l3) -> fold_left3 f (f accu a1 a2 a3) l1 l2 l3
+ | ([], [], []) -> accu
+ | (a1 :: l1, a2 :: l2, a3 :: l3) -> fold_left3 f (f accu a1 a2 a3) l1 l2 l3
| (_, _, _) -> invalid_arg "List.fold_left3"
let rec fold_left4 f accu l1 l2 l3 l4 =
match (l1, l2, l3, l4) with
- ([], [], [], []) -> accu
- | (a1::l1, a2::l2, a3::l3, a4::l4) -> fold_left4 f (f accu a1 a2 a3 a4) l1 l2 l3 l4
+ | ([], [], [], []) -> accu
+ | (a1 :: l1, a2 :: l2, a3 :: l3, a4 :: l4) -> fold_left4 f (f accu a1 a2 a3 a4) l1 l2 l3 l4
| (_,_, _, _) -> invalid_arg "List.fold_left4"
(* [fold_right_and_left f [a1;...;an] hd =
@@ -475,223 +593,103 @@ let rec fold_left4 f accu l1 l2 l3 l4 =
let fold_right_and_left f l hd =
let rec aux tl = function
| [] -> hd
- | a::l -> let hd = aux (a::tl) l in f hd a tl
- in aux [] l
+ | a :: l -> let hd = aux (a :: tl) l in f hd a tl
+ in
+ aux [] l
(* Match sets as lists according to a matching function, also folding a side effect *)
let rec fold_left2_set e f x l1 l2 =
match l1 with
- | a1::l1 ->
- let rec find seen = function
- | [] -> raise e
- | a2::l2 ->
- try fold_left2_set e f (f x a1 a2 l1 l2) l1 (List.rev_append seen l2)
- with e' when e' = e -> find (a2::seen) l2 in
- find [] l2
+ | a1 :: l1 ->
+ let rec find seen = function
+ | [] -> raise e
+ | a2 :: l2 ->
+ try fold_left2_set e f (f x a1 a2 l1 l2) l1 (List.rev_append seen l2)
+ with e' when e' = e -> find (a2 :: seen) l2 in
+ find [] l2
| [] ->
- if l2 = [] then x else raise e
-
-let iteri f l = fold_left_i (fun i _ x -> f i x) 0 () l
-
-let for_all_i p =
- let rec for_all_p i = function
- | [] -> true
- | a::l -> p i a && for_all_p (i+1) l
- in
- for_all_p
-
-let except cmp x l = List.filter (fun y -> not (cmp x y)) l
-
-let remove = except (* Alias *)
-
-let rec remove_first p = function
- | b::l when p b -> l
- | b::l -> b::remove_first p l
- | [] -> raise Not_found
+ if l2 = [] then x else raise e
-let extract_first p li =
- let rec loop rev_left = function
- | [] -> raise Not_found
- | x::right ->
- if p x then List.rev_append rev_left right, x
- else loop (x :: rev_left) right
- in loop [] li
-
-let insert p v l =
- let rec insrec = function
- | [] -> [v]
- | h::tl -> if p v h then v::h::tl else h::insrec tl
- in
- insrec l
-
-let add_set cmp x l = if mem_f cmp x l then l else x :: l
-
-(** List equality up to permutation (but considering multiple occurrences) *)
-
-let eq_set cmp l1 l2 =
- let rec aux l1 = function
- | [] -> is_empty l1
- | a::l2 -> aux (remove_first (cmp a) l1) l2 in
- try aux l1 l2 with Not_found -> false
+(* Poor man's monadic map *)
+let rec fold_left_map f e = function
+ | [] -> (e,[])
+ | h :: t ->
+ let e',h' = f e h in
+ let e'',t' = fold_left_map f e' t in
+ e'',h' :: t'
-let for_all2eq f l1 l2 =
- try List.for_all2 f l1 l2 with Invalid_argument _ -> false
+let fold_map = fold_left_map
-let filteri p =
- let rec filter_i_rec i = function
- | [] -> []
- | x::l -> let l' = filter_i_rec (succ i) l in if p i x then x::l' else l'
+(* (* tail-recursive version of the above function *)
+let fold_left_map f e l =
+ let g (e,b') h =
+ let (e',h') = f e h in
+ (e',h'::b')
in
- filter_i_rec 0
-
-let partitioni p =
- let rec aux i = function
- | [] -> [], []
- | x :: l ->
- let (l1, l2) = aux (succ i) l in
- if p i x then (x :: l1, l2)
- else (l1, x :: l2)
- in aux 0
-
-let rec sep_last = function
- | [] -> failwith "sep_last"
- | hd::[] -> (hd,[])
- | hd::tl -> let (l,tl) = sep_last tl in (l,hd::tl)
-
-let rec find_map f = function
-| [] -> raise Not_found
-| x :: l ->
- match f x with
- | None -> find_map f l
- | Some y -> y
-
-(* FIXME: we should avoid relying on the generic hash function,
- just as we'd better avoid Pervasives.compare *)
-
-let uniquize l =
- let visited = Hashtbl.create 23 in
- let rec aux acc changed = function
- | h::t -> if Hashtbl.mem visited h then aux acc true t else
- begin
- Hashtbl.add visited h h;
- aux (h::acc) changed t
- end
- | [] -> if changed then List.rev acc else l
- in aux [] false l
-
-(** [sort_uniquize] might be an alternative to the hashtbl-based
- [uniquize], when the order of the elements is irrelevant *)
-
-let rec uniquize_sorted cmp = function
- | a::b::l when Int.equal (cmp a b) 0 -> uniquize_sorted cmp (a::l)
- | a::l -> a::uniquize_sorted cmp l
- | [] -> []
-
-let sort_uniquize cmp l = uniquize_sorted cmp (List.sort cmp l)
+ let (e',lrev) = List.fold_left g (e,[]) l in
+ (e',List.rev lrev)
+*)
-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
+(* The same, based on fold_right, with the effect accumulated on the right *)
+let fold_right_map f l e =
+ List.fold_right (fun x (l,e) -> let (y,e) = f x e in (y::l,e)) l ([],e)
-(* FIXME: again, generic hash function *)
+let fold_map' = fold_right_map
-let distinct l =
- let visited = Hashtbl.create 23 in
- let rec loop = function
- | h::t ->
- if Hashtbl.mem visited h then false
- else
- begin
- Hashtbl.add visited h h;
- loop t
- end
- | [] -> true
- in loop l
+let on_snd f (x,y) = (x,f y)
-let distinct_f cmp l =
- let rec loop = function
- | a::b::_ when Int.equal (cmp a b) 0 -> false
- | a::l -> loop l
- | [] -> true
- in loop (List.sort cmp l)
+let fold_left2_map f e l l' =
+ on_snd List.rev @@
+ List.fold_left2 (fun (e,l) x x' ->
+ let (e,y) = f e x x' in
+ (e, y::l)
+ ) (e, []) l l'
-let rec merge_uniq cmp l1 l2 =
- match l1, l2 with
- | [], l2 -> l2
- | l1, [] -> l1
- | h1 :: t1, h2 :: t2 ->
- let c = cmp h1 h2 in
- if Int.equal c 0
- then h1 :: merge_uniq cmp t1 t2
- else if c <= 0
- then h1 :: merge_uniq cmp t1 l2
- else h2 :: merge_uniq cmp l1 t2
+let fold_right2_map f l l' e =
+ List.fold_right2 (fun x x' (l,e) -> let (y,e) = f x x' e in (y::l,e)) l l' ([],e)
-let rec duplicates cmp = function
- | [] -> []
- | x::l ->
- let l' = duplicates cmp l in
- if mem_f cmp x l then add_set cmp x l' else l'
+let fold_left3_map f e l l' l'' =
+ on_snd List.rev @@
+ fold_left3 (fun (e,l) x x' x'' -> let (e,y) = f e x x' x'' in (e,y::l)) (e,[]) l l' l''
-let rec filter2_loop f p q l1 l2 = match l1, l2 with
-| [], [] -> ()
-| x :: l1, y :: l2 ->
- if f x y then
- let c1 = { head = x; tail = [] } in
- let c2 = { head = y; tail = [] } in
- let () = p.tail <- cast c1 in
- let () = q.tail <- cast c2 in
- filter2_loop f c1 c2 l1 l2
- else
- filter2_loop f p q l1 l2
-| _ -> invalid_arg "List.filter2"
+let fold_left4_map f e l1 l2 l3 l4 =
+ on_snd List.rev @@
+ fold_left4 (fun (e,l) x1 x2 x3 x4 -> let (e,y) = f e x1 x2 x3 x4 in (e,y::l)) (e,[]) l1 l2 l3 l4
-let filter2 f l1 l2 =
- let c1 = { head = Obj.magic 0; tail = [] } in
- let c2 = { head = Obj.magic 0; tail = [] } in
- filter2_loop f c1 c2 l1 l2;
- (c1.tail, c2.tail)
+(** {6 Splitting} *)
-let rec map_filter_loop f p = function
- | [] -> ()
- | x :: l ->
- match f x with
- | None -> map_filter_loop f p l
- | Some y ->
- let c = { head = y; tail = [] } in
- p.tail <- cast c;
- map_filter_loop f c l
+let except cmp x l =
+ List.filter (fun y -> not (cmp x y)) l
-let map_filter f l =
- let c = { head = Obj.magic 0; tail = [] } in
- map_filter_loop f c l;
- c.tail
+let remove = except (* Alias *)
-let rec map_filter_i_loop f i p = function
- | [] -> ()
- | x :: l ->
- match f i x with
- | None -> map_filter_i_loop f (succ i) p l
- | Some y ->
- let c = { head = y; tail = [] } in
- p.tail <- cast c;
- map_filter_i_loop f (succ i) c l
+let rec remove_first p = function
+ | b :: l when p b -> l
+ | b :: l -> b :: remove_first p l
+ | [] -> raise Not_found
-let map_filter_i f l =
- let c = { head = Obj.magic 0; tail = [] } in
- map_filter_i_loop f 0 c l;
- c.tail
+let extract_first p li =
+ let rec loop rev_left = function
+ | [] -> raise Not_found
+ | x :: right ->
+ if p x then List.rev_append rev_left right, x
+ else loop (x :: rev_left) right
+ in
+ loop [] li
-let rec filter_with filter l = match filter, l with
-| [], [] -> []
-| true :: filter, x :: l -> x :: filter_with filter l
-| false :: filter, _ :: l -> filter_with filter l
-| _ -> invalid_arg "List.filter_with"
+let insert p v l =
+ let rec insrec = function
+ | [] -> [v]
+ | h :: tl -> if p v h then v :: h :: tl else h :: insrec tl
+ in
+ insrec l
+
+let rec find_map f = function
+ | [] -> raise Not_found
+ | x :: l ->
+ match f x with
+ | None -> find_map f l
+ | Some y -> y
(* FIXME: again, generic hash function *)
@@ -700,7 +698,7 @@ let subset l1 l2 =
List.iter (fun x -> Hashtbl.add t2 x ()) l2;
let rec look = function
| [] -> true
- | x::ll -> try Hashtbl.find t2 x; look ll with Not_found -> false
+ | x :: ll -> try Hashtbl.find t2 x; look ll with Not_found -> false
in
look l1
@@ -712,7 +710,7 @@ exception IndexOutOfRange
let goto n l =
let rec goto i acc = function
| tl when Int.equal i 0 -> (acc, tl)
- | h::t -> goto (pred i) (h::acc) t
+ | h :: t -> goto (pred i) (h :: acc) t
| [] -> raise IndexOutOfRange
in
goto n [] l
@@ -733,29 +731,36 @@ let chop n l =
let split_when p =
let rec split_when_loop x y =
match y with
- | [] -> (List.rev x,[])
- | (a::l) -> if (p a) then (List.rev x,y) else split_when_loop (a::x) l
+ | [] -> (List.rev x,[])
+ | (a :: l) -> if (p a) then (List.rev x,y) else split_when_loop (a :: x) l
in
split_when_loop []
-let rec split3 = function
- | [] -> ([], [], [])
- | (x,y,z)::l ->
- let (rx, ry, rz) = split3 l in (x::rx, y::ry, z::rz)
-
let firstn n l =
let rec aux acc n l =
match n, l with
| 0, _ -> List.rev acc
- | n, h::t -> aux (h::acc) (pred n) t
+ | n, h :: t -> aux (h :: acc) (pred n) t
| _ -> failwith "firstn"
in
aux [] n l
+let rec sep_last = function
+ | [] -> failwith "sep_last"
+ | hd :: [] -> (hd,[])
+ | hd :: tl -> let (l,tl) = sep_last tl in (l,hd :: tl)
+
+(* Drop the last element of a list *)
+
+let rec drop_last = function
+ | [] -> failwith "drop_last"
+ | hd :: [] -> []
+ | hd :: tl -> hd :: drop_last tl
+
let rec last = function
| [] -> failwith "List.last"
- | [x] -> x
- | _ :: l -> last l
+ | hd :: [] -> hd
+ | _ :: tl -> last tl
let lastn n l =
let len = List.length l in
@@ -767,96 +772,225 @@ let lastn n l =
let rec skipn n l = match n,l with
| 0, _ -> l
| _, [] -> failwith "List.skipn"
- | n, _::l -> skipn (pred n) l
+ | n, _ :: l -> skipn (pred n) l
let skipn_at_least n l =
- try skipn n l with Failure _ -> []
-
-let prefix_of cmp prefl l =
- let rec prefrec = function
- | (h1::t1, h2::t2) -> cmp h1 h2 && prefrec (t1,t2)
- | ([], _) -> true
- | _ -> false
- in
- prefrec (prefl,l)
+ try skipn n l with Failure _ when n >= 0 -> []
(** if [l=p++t] then [drop_prefix p l] is [t] else [l] *)
let drop_prefix cmp p l =
let rec drop_prefix_rec = function
- | (h1::tp, h2::tl) when cmp h1 h2 -> drop_prefix_rec (tp,tl)
+ | (h1 :: tp, h2 :: tl) when cmp h1 h2 -> drop_prefix_rec (tp,tl)
| ([], tl) -> tl
| _ -> l
in
drop_prefix_rec (p,l)
-let map_append f l = List.flatten (List.map f l)
-
-let map_append2 f l1 l2 = List.flatten (List.map2 f l1 l2)
-
let share_tails l1 l2 =
let rec shr_rev acc = function
- | ((x1::l1), (x2::l2)) when x1 == x2 -> shr_rev (x1::acc) (l1,l2)
- | (l1,l2) -> (List.rev l1, List.rev l2, acc)
+ | (x1 :: l1, x2 :: l2) when x1 == x2 -> shr_rev (x1 :: acc) (l1,l2)
+ | (l1, l2) -> (List.rev l1, List.rev l2, acc)
in
shr_rev [] (List.rev l1, List.rev l2)
-(* Poor man's monadic map *)
-let rec fold_left_map f e = function
- | [] -> (e,[])
- | h::t ->
- let e',h' = f e h in
- let e'',t' = fold_left_map f e' t in
- e'',h'::t'
+(** {6 Association lists} *)
-let fold_map = fold_left_map
+let map_assoc f = List.map (fun (x,a) -> (x,f a))
-(* (* tail-recursive version of the above function *)
-let fold_map f e l =
- let g (e,b') h =
- let (e',h') = f e h in
- (e',h'::b')
+let rec assoc_f f a = function
+ | (x, e) :: xs -> if f a x then e else assoc_f f a xs
+ | [] -> raise Not_found
+
+let remove_assoc_f f a l =
+ try remove_first (fun (x,_) -> f a x) l with Not_found -> l
+
+let mem_assoc_f f a l = List.exists (fun (x,_) -> f a x) l
+
+(** {6 Operations on lists of tuples} *)
+
+let rec split_loop p q = function
+ | [] -> ()
+ | (x, y) :: l ->
+ let cl = { head = x; tail = [] } in
+ let cr = { head = y; tail = [] } in
+ p.tail <- cast cl;
+ q.tail <- cast cr;
+ split_loop cl cr l
+
+let split = function
+ | [] -> [], []
+ | (x, y) :: l ->
+ let cl = { head = x; tail = [] } in
+ let cr = { head = y; tail = [] } in
+ split_loop cl cr l;
+ (cast cl, cast cr)
+
+let rec combine_loop p l1 l2 = match l1, l2 with
+ | [], [] -> ()
+ | x :: l1, y :: l2 ->
+ let c = { head = (x, y); tail = [] } in
+ p.tail <- cast c;
+ combine_loop c l1 l2
+ | _ -> invalid_arg "List.combine"
+
+let combine l1 l2 = match l1, l2 with
+ | [], [] -> []
+ | x :: l1, y :: l2 ->
+ let c = { head = (x, y); tail = [] } in
+ combine_loop c l1 l2;
+ cast c
+ | _ -> invalid_arg "List.combine"
+
+let rec split3_loop p q r = function
+ | [] -> ()
+ | (x, y, z) :: l ->
+ let cp = { head = x; tail = [] } in
+ let cq = { head = y; tail = [] } in
+ let cr = { head = z; tail = [] } in
+ p.tail <- cast cp;
+ q.tail <- cast cq;
+ r.tail <- cast cr;
+ split3_loop cp cq cr l
+
+let split3 = function
+ | [] -> [], [], []
+ | (x, y, z) :: l ->
+ let cp = { head = x; tail = [] } in
+ let cq = { head = y; tail = [] } in
+ let cr = { head = z; tail = [] } in
+ split3_loop cp cq cr l;
+ (cast cp, cast cq, cast cr)
+
+let rec combine3_loop p l1 l2 l3 = match l1, l2, l3 with
+ | [], [], [] -> ()
+ | x :: l1, y :: l2, z :: l3 ->
+ let c = { head = (x, y, z); tail = [] } in
+ p.tail <- cast c;
+ combine3_loop c l1 l2 l3
+ | _ -> invalid_arg "List.combine3"
+
+let combine3 l1 l2 l3 = match l1, l2, l3 with
+ | [], [], [] -> []
+ | x :: l1, y :: l2, z :: l3 ->
+ let c = { head = (x, y, z); tail = [] } in
+ combine3_loop c l1 l2 l3;
+ cast c
+ | _ -> invalid_arg "List.combine3"
+
+(** {6 Operations on lists seen as sets, preserving uniqueness of elements} *)
+
+(** Add an element, preserving uniqueness of elements *)
+
+let add_set cmp x l =
+ if mem_f cmp x l then l else x :: l
+
+(** List equality up to permutation (but considering multiple occurrences) *)
+
+let eq_set cmp l1 l2 =
+ let rec aux l1 = function
+ | [] -> is_empty l1
+ | a :: l2 -> aux (remove_first (cmp a) l1) l2
in
- let (e',lrev) = List.fold_left g (e,[]) l in
- (e',List.rev lrev)
-*)
+ try aux l1 l2 with Not_found -> false
-(* The same, based on fold_right, with the effect accumulated on the right *)
-let fold_right_map f l e =
- List.fold_right (fun x (l,e) -> let (y,e) = f x e in (y::l,e)) l ([],e)
+let rec merge_set cmp l1 l2 = match l1, l2 with
+ | [], l2 -> l2
+ | l1, [] -> l1
+ | h1 :: t1, h2 :: t2 ->
+ let c = cmp h1 h2 in
+ if Int.equal c 0
+ then h1 :: merge_set cmp t1 t2
+ else if c <= 0
+ then h1 :: merge_set cmp t1 l2
+ else h2 :: merge_set cmp l1 t2
-let fold_map' = fold_right_map
+let merge_uniq = merge_set
-let on_snd f (x,y) = (x,f y)
+let intersect cmp l1 l2 =
+ filter (fun x -> mem_f cmp x l2) l1
-let fold_left2_map f e l l' =
- on_snd List.rev @@
- List.fold_left2 (fun (e,l) x x' ->
- let (e,y) = f e x x' in
- (e, y::l)
- ) (e, []) l l'
+let union cmp l1 l2 =
+ let rec urec = function
+ | [] -> l2
+ | a :: l -> if mem_f cmp a l2 then urec l else a :: urec l
+ in
+ urec l1
-let fold_right2_map f l l' e =
- List.fold_right2 (fun x x' (l,e) -> let (y,e) = f x x' e in (y::l,e)) l l' ([],e)
+let subtract cmp l1 l2 =
+ if is_empty l2 then l1
+ else List.filter (fun x -> not (mem_f cmp x l2)) l1
-let fold_left3_map f e l l' l'' =
- on_snd List.rev @@
- fold_left3 (fun (e,l) x x' x'' -> let (e,y) = f e x x' x'' in (e,y::l)) (e,[]) l l' l''
+let unionq l1 l2 = union (==) l1 l2
+let subtractq l1 l2 = subtract (==) l1 l2
-let fold_left4_map f e l1 l2 l3 l4 =
- on_snd List.rev @@
- fold_left4 (fun (e,l) x1 x2 x3 x4 -> let (e,y) = f e x1 x2 x3 x4 in (e,y::l)) (e,[]) l1 l2 l3 l4
+(** {6 Uniqueness and duplication} *)
-let map_assoc f = List.map (fun (x,a) -> (x,f a))
+(* FIXME: we should avoid relying on the generic hash function,
+ just as we'd better avoid Pervasives.compare *)
-let rec assoc_f f a = function
- | (x, e) :: xs -> if f a x then e else assoc_f f a xs
+let distinct l =
+ let visited = Hashtbl.create 23 in
+ let rec loop = function
+ | h :: t ->
+ if Hashtbl.mem visited h then false
+ else
+ begin
+ Hashtbl.add visited h h;
+ loop t
+ end
+ | [] -> true
+ in
+ loop l
+
+let distinct_f cmp l =
+ let rec loop = function
+ | a :: b :: _ when Int.equal (cmp a b) 0 -> false
+ | a :: l -> loop l
+ | [] -> true
+ in loop (List.sort cmp l)
+
+(* FIXME: again, generic hash function *)
+
+let uniquize l =
+ let visited = Hashtbl.create 23 in
+ let rec aux acc changed = function
+ | h :: t -> if Hashtbl.mem visited h then aux acc true t else
+ begin
+ Hashtbl.add visited h h;
+ aux (h :: acc) changed t
+ end
+ | [] -> if changed then List.rev acc else l
+ in
+ aux [] false l
+
+(** [sort_uniquize] might be an alternative to the hashtbl-based
+ [uniquize], when the order of the elements is irrelevant *)
+
+let rec uniquize_sorted cmp = function
+ | a :: b :: l when Int.equal (cmp a b) 0 -> uniquize_sorted cmp (a :: l)
+ | a :: l -> a :: uniquize_sorted cmp l
+ | [] -> []
+
+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 remove_assoc_f f a l =
- try remove_first (fun (x,_) -> f a x) l with Not_found -> l
+let rec duplicates cmp = function
+ | [] -> []
+ | x :: l ->
+ let l' = duplicates cmp l in
+ if mem_f cmp x l then add_set cmp x l' else l'
-let mem_assoc_f f a l = List.exists (fun (x,_) -> f a x) l
+(** {6 Cartesian product} *)
(* A generic cartesian product: for any operator (**),
[cartesian (**) [x1;x2] [y1;y2] = [x1**y1; x1**y2; x2**y1; x2**y1]],
@@ -873,15 +1007,9 @@ let cartesians op init ll =
(* combinations [[a;b];[c;d]] gives [[a;c];[a;d];[b;c];[b;d]] *)
-let combinations l = cartesians (fun x l -> x::l) [] l
+let combinations l =
+ cartesians (fun x l -> x :: l) [] l
-let rec combine3 x y z =
- match x, y, z with
- | [], [], [] -> []
- | (x :: xs), (y :: ys), (z :: zs) ->
- (x, y, z) :: combine3 xs ys zs
- | _, _, _ -> invalid_arg "List.combine3"
-
(* Keep only those products that do not return None *)
let cartesian_filter op l1 l2 =
@@ -892,20 +1020,35 @@ let cartesian_filter op l1 l2 =
let cartesians_filter op init ll =
List.fold_right (cartesian_filter op) ll [init]
-(* Drop the last element of a list *)
-
-let rec drop_last = function
- | [] -> assert false
- | hd :: [] -> []
- | hd :: tl -> hd :: drop_last tl
-
(* Factorize lists of pairs according to the left argument *)
let rec factorize_left cmp = function
- | (a,b)::l ->
+ | (a,b) :: l ->
let al,l' = partition (fun (a',_) -> cmp a a') l in
- (a,(b::List.map snd al)) :: factorize_left cmp l'
+ (a,(b :: List.map snd al)) :: factorize_left cmp l'
| [] -> []
+module Smart =
+struct
+
+ let rec map_loop f p = function
+ | [] -> ()
+ | x :: l' as l ->
+ let x' = f x in
+ map_loop f p l';
+ if x' == x && !p == l' then p := l else p := x' :: !p
+
+ let map f = function
+ | [] -> []
+ | x :: l' as l ->
+ let p = ref [] in
+ let x' = f x in
+ map_loop f p l';
+ if x' == x && !p == l' then l else x' :: !p
+
+end
+
+let smartmap = Smart.map
+
module type MonoS = sig
type elt
val equal : elt list -> elt list -> bool
diff --git a/clib/cList.mli b/clib/cList.mli
index e025f7b4..39d9a5e5 100644
--- a/clib/cList.mli
+++ b/clib/cList.mli
@@ -18,33 +18,31 @@ module type ExtS =
sig
include S
+ (** {6 Equality, testing} *)
+
val compare : 'a cmp -> 'a list cmp
(** Lexicographic order on lists. *)
val equal : 'a eq -> 'a list eq
- (** Lifts equality to list type. *)
+ (** Lift equality to list type. *)
val is_empty : 'a list -> bool
- (** Checks whether a list is empty *)
-
- val init : int -> (int -> 'a) -> 'a list
- (** [init n f] constructs the list [f 0; ... ; f (n - 1)]. *)
+ (** Check whether a list is empty *)
val mem_f : 'a eq -> 'a -> 'a list -> bool
- (* Same as [List.mem], for some specific equality *)
+ (** Same as [List.mem], for some specific equality *)
- val add_set : 'a eq -> 'a -> 'a list -> 'a list
- (** [add_set x l] adds [x] in [l] if it is not already there, or returns [l]
- otherwise. *)
+ val for_all_i : (int -> 'a -> bool) -> int -> 'a list -> bool
+ (** Same as [List.for_all] but with an index *)
- val eq_set : 'a eq -> 'a list eq
- (** Test equality up to permutation (but considering multiple occurrences) *)
+ val for_all2eq : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool
+ (** Same as [List.for_all2] but returning [false] when of different length *)
- val intersect : 'a eq -> 'a list -> 'a list -> 'a list
- val union : 'a eq -> 'a list -> 'a list -> 'a list
- val unionq : 'a list -> 'a list -> 'a list
- val subtract : 'a eq -> 'a list -> 'a list -> 'a list
- val subtractq : 'a list -> 'a list -> 'a list
+ val prefix_of : 'a eq -> 'a list eq
+ (** [prefix_of eq l1 l2] returns [true] if [l1] is a prefix of [l2], [false]
+ otherwise. It uses [eq] to compare elements *)
+
+ (** {6 Creating lists} *)
val interval : int -> int -> int list
(** [interval i j] creates the list [[i; i + 1; ...; j]], or [[]] when
@@ -52,88 +50,177 @@ sig
val make : int -> 'a -> 'a list
(** [make n x] returns a list made of [n] times [x]. Raise
- [Invalid_argument "List.make"] if [n] is negative. *)
+ [Invalid_argument _] if [n] is negative. *)
- val assign : 'a list -> int -> 'a -> 'a list
- (** [assign l i x] sets the [i]-th element of [l] to [x], starting from [0]. *)
+ val addn : int -> 'a -> 'a list -> 'a list
+ (** [addn n x l] adds [n] times [x] on the left of [l]. *)
- val distinct : 'a list -> bool
- (** Return [true] if all elements of the list are distinct. *)
+ val init : int -> (int -> 'a) -> 'a list
+ (** [init n f] constructs the list [f 0; ... ; f (n - 1)]. Raise
+ [Invalid_argument _] if [n] is negative *)
- val distinct_f : 'a cmp -> 'a list -> bool
+ val append : 'a list -> 'a list -> 'a list
+ (** Like OCaml's [List.append] but tail-recursive. *)
- val duplicates : 'a eq -> 'a list -> 'a list
- (** Return the list of unique elements which appear at least twice. Elements
- are kept in the order of their first appearance. *)
+ val concat : 'a list list -> 'a list
+ (** Like OCaml's [List.concat] but tail-recursive. *)
+
+ val flatten : 'a list list -> 'a list
+ (** Synonymous of [concat] *)
+
+ (** {6 Lists as arrays} *)
+
+ val assign : 'a list -> int -> 'a -> 'a list
+ (** [assign l i x] sets the [i]-th element of [l] to [x], starting
+ from [0]. Raise [Failure _] if [i] is out of range. *)
+
+ (** {6 Filtering} *)
+
+ val filter : ('a -> bool) -> 'a list -> 'a list
+ (** Like OCaml [List.filter] but tail-recursive and physically returns
+ the original list if the predicate holds for all elements. *)
val filter2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> 'a list * 'b list
+ (** Like [List.filter] but with 2 arguments, raise [Invalid_argument _]
+ if the lists are not of same length. *)
+
+ val filteri : (int -> 'a -> bool) -> 'a list -> 'a list
+ (** Like [List.filter] but with an index starting from [0] *)
+
+ val filter_with : bool list -> 'a list -> 'a list
+ (** [filter_with bl l] selects elements of [l] whose corresponding element in
+ [bl] is [true]. Raise [Invalid_argument _] if sizes differ. *)
+
+ val smartfilter : ('a -> bool) -> 'a list -> 'a list
+ [@@ocaml.deprecated "Same as [filter]"]
+
val map_filter : ('a -> 'b option) -> 'a list -> 'b list
+ (** Like [map] but keeping only non-[None] elements *)
+
val map_filter_i : (int -> 'a -> 'b option) -> 'a list -> 'b list
+ (** Like [map_filter] but with an index starting from [0] *)
- val filter_with : bool list -> 'a list -> 'a list
- (** [filter_with b a] selects elements of [a] whose corresponding element in
- [b] is [true]. Raise [Invalid_argument _] when sizes differ. *)
+ val partitioni : (int -> 'a -> bool) -> 'a list -> 'a list * 'a list
+ (** Like [List.partition] but with an index starting from [0] *)
+
+ (** {6 Applying functorially} *)
+
+ val map : ('a -> 'b) -> 'a list -> 'b list
+ (** Like OCaml [List.map] but tail-recursive *)
+
+ val map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
+ (** Like OCaml [List.map2] but tail-recursive *)
val smartmap : ('a -> 'a) -> 'a list -> 'a list
- (** [smartmap f [a1...an] = List.map f [a1...an]] but if for all i
- [f ai == ai], then [smartmap f l == l] *)
+ [@@ocaml.deprecated "Same as [Smart.map]"]
val map_left : ('a -> 'b) -> 'a list -> 'b list
(** As [map] but ensures the left-to-right order of evaluation. *)
val map_i : (int -> 'a -> 'b) -> int -> 'a list -> 'b list
- (** As [map] but with the index, which starts from [0]. *)
+ (** Like OCaml [List.mapi] but tail-recursive. Alternatively, like
+ [map] but with an index *)
val map2_i :
(int -> 'a -> 'b -> 'c) -> int -> 'a list -> 'b list -> 'c list
+ (** Like [map2] but with an index *)
+
val map3 :
('a -> 'b -> 'c -> 'd) -> 'a list -> 'b list -> 'c list -> 'd list
+ (** Like [map] but for 3 lists. *)
+
val map4 : ('a -> 'b -> 'c -> 'd -> 'e) -> 'a list -> 'b list -> 'c list ->
'd list -> 'e list
- val filteri : (int -> 'a -> bool) -> 'a list -> 'a list
- val partitioni : (int -> 'a -> bool) -> 'a list -> 'a list * 'a list
+ (** Like [map] but for 4 lists. *)
val map_of_array : ('a -> 'b) -> 'a array -> 'b list
(** [map_of_array f a] behaves as [List.map f (Array.to_list a)] *)
- val smartfilter : ('a -> bool) -> 'a list -> 'a list
- (** [smartfilter f [a1...an] = List.filter f [a1...an]] but if for all i
- [f ai = true], then [smartfilter f l == l] *)
+ val map_append : ('a -> 'b list) -> 'a list -> 'b list
+ (** [map_append f [x1; ...; xn]] returns [f x1 @ ... @ f xn]. *)
+
+ val map_append2 : ('a -> 'b -> 'c list) -> 'a list -> 'b list -> 'c list
+ (** Like [map_append] but for two lists; raises [Invalid_argument _]
+ if the two lists do not have the same length. *)
val extend : bool list -> 'a -> 'a list -> 'a list
-(** [extend l a [a1..an]] assumes that the number of [true] in [l] is [n];
+ (** [extend l a [a1..an]] assumes that the number of [true] in [l] is [n];
it extends [a1..an] by inserting [a] at the position of [false] in [l] *)
+
val count : ('a -> bool) -> 'a list -> int
+ (** Count the number of elements satisfying a predicate *)
+
+ (** {6 Finding position} *)
val index : 'a eq -> 'a -> 'a list -> int
(** [index] returns the 1st index of an element in a list (counting from 1). *)
+ val safe_index : 'a eq -> 'a -> 'a list -> int option
+ (** [safe_index] returns the 1st index of an element in a list (counting from 1)
+ and None otherwise. *)
+
val index0 : 'a eq -> 'a -> 'a list -> int
(** [index0] behaves as [index] except that it starts counting at 0. *)
- val iteri : (int -> 'a -> unit) -> 'a list -> unit
- (** As [iter] but with the index argument (starting from 0). *)
+ (** {6 Folding} *)
val fold_left_until : ('c -> 'a -> 'c CSig.until) -> 'c -> 'a list -> 'c
(** acts like [fold_left f acc s] while [f] returns
[Cont acc']; it stops returning [c] as soon as [f] returns [Stop c]. *)
val fold_right_i : (int -> 'a -> 'b -> 'b) -> int -> 'a list -> 'b -> 'b
+ (** Like [List.fold_right] but with an index *)
+
val fold_left_i : (int -> 'a -> 'b -> 'a) -> int -> 'a -> 'b list -> 'a
- val fold_right_and_left :
- ('a -> 'b -> 'b list -> 'a) -> 'b list -> 'a -> 'a
+ (** Like [List.fold_left] but with an index *)
+
+ val fold_right_and_left : ('b -> 'a -> 'a list -> 'b) -> 'a list -> 'b -> 'b
+ (** [fold_right_and_left f [a1;...;an] hd] is
+ [f (f (... (f (f hd an [an-1;...;a1]) an-1 [an-2;...;a1]) ...) a2 [a1]) a1 []] *)
+
val fold_left3 : ('a -> 'b -> 'c -> 'd -> 'a) -> 'a -> 'b list -> 'c list -> 'd list -> 'a
+ (** Like [List.fold_left] but for 3 lists; raise [Invalid_argument _] if
+ not all lists of the same size *)
+ val fold_left2_set : exn -> ('a -> 'b -> 'c -> 'b list -> 'c list -> 'a) -> 'a -> 'b list -> 'c list -> 'a
(** Fold sets, i.e. lists up to order; the folding function tells
when elements match by returning a value and raising the given
exception otherwise; sets should have the same size; raise the
given exception if no pairing of the two sets is found;;
complexity in O(n^2) *)
- val fold_left2_set : exn -> ('a -> 'b -> 'c -> 'b list -> 'c list -> 'a) -> 'a -> 'b list -> 'c list -> 'a
- val for_all_i : (int -> 'a -> bool) -> int -> 'a list -> bool
+ val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
+ (** [fold_left_map f e_0 [a1;...;an]] is [e_n,[k_1...k_n]]
+ where [(e_i,k_i)] is [f e_{i-1} ai] for each i<=n *)
+
+ val fold_right_map : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
+ (** Same, folding on the right *)
+
+ val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b list -> 'c list -> 'a * 'd list
+ (** Same with two lists, folding on the left *)
+
+ val fold_right2_map : ('b -> 'c -> 'a -> 'd * 'a) -> 'b list -> 'c list -> 'a -> 'd list * 'a
+ (** Same with two lists, folding on the right *)
+
+ val fold_left3_map : ('a -> 'b -> 'c -> 'd -> 'a * 'e) -> 'a -> 'b list -> 'c list -> 'd list -> 'a * 'e list
+ (** Same with three lists, folding on the left *)
+
+ val fold_left4_map : ('a -> 'b -> 'c -> 'd -> 'e -> 'a * 'r) -> 'a -> 'b list -> 'c list -> 'd list -> 'e list -> 'a * 'r list
+ (** Same with four lists, folding on the left *)
+
+ val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
+ [@@ocaml.deprecated "Same as [fold_left_map]"]
+
+ val fold_map' : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
+ [@@ocaml.deprecated "Same as [fold_right_map]"]
+
+ (** {6 Splitting} *)
+
val except : 'a eq -> 'a -> 'a list -> 'a list
+ (** [except eq a l] Remove all occurrences of [a] in [l] *)
+
val remove : 'a eq -> 'a -> 'a list -> 'a list
+ (** Alias of [except] *)
val remove_first : ('a -> bool) -> 'a list -> 'a list
(** Remove the first element satisfying a predicate, or raise [Not_found] *)
@@ -142,35 +229,10 @@ sig
(** Remove and return the first element satisfying a predicate,
or raise [Not_found] *)
- val insert : ('a -> 'a -> bool) -> 'a -> 'a list -> 'a list
- (** Insert at the (first) position so that if the list is ordered wrt to the
- total order given as argument, the order is preserved *)
-
- val for_all2eq : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool
- val sep_last : 'a list -> 'a * 'a list
-
val find_map : ('a -> 'b option) -> 'a list -> 'b
(** Returns the first element that is mapped to [Some _]. Raise [Not_found] if
there is none. *)
- val uniquize : 'a list -> 'a list
- (** Return the list of elements without duplicates.
- This is the list unchanged if there was none. *)
-
- val sort_uniquize : 'a cmp -> 'a list -> 'a list
- (** Return a sorted and de-duplicated version of a list,
- according to some comparison function. *)
-
- val merge_uniq : 'a cmp -> 'a list -> 'a list -> 'a list
- (** Merge two sorted lists and preserves the uniqueness property. *)
-
- val subset : 'a list -> 'a list -> bool
-
- val chop : int -> 'a list -> 'a list * 'a list
- (** [chop i l] splits [l] into two lists [(l1,l2)] such that
- [l1++l2=l] and [l1] has length [i]. It raises [Failure] when [i]
- is negative or greater than the length of [l] *)
-
exception IndexOutOfRange
val goto: int -> 'a list -> 'a list * 'a list
(** [goto i l] splits [l] into two lists [(l1,l2)] such that
@@ -178,90 +240,180 @@ sig
[IndexOutOfRange] when [i] is negative or greater than the
length of [l]. *)
-
val split_when : ('a -> bool) -> 'a list -> 'a list * 'a list
- val split3 : ('a * 'b * 'c) list -> 'a list * 'b list * 'c list
- val firstn : int -> 'a list -> 'a list
+ (** [split_when p l] splits [l] into two lists [(l1,a::l2)] such that
+ [l1++(a::l2)=l], [p a=true] and [p b = false] for every element [b] of [l1].
+ if there is no such [a], then it returns [(l,[])] instead. *)
+
+ val sep_last : 'a list -> 'a * 'a list
+ (** [sep_last l] returns [(a,l')] such that [l] is [l'@[a]].
+ It raises [Failure _] if the list is empty. *)
+
+ val drop_last : 'a list -> 'a list
+ (** Remove the last element of the list. It raises [Failure _] if the
+ list is empty. This is the second part of [sep_last]. *)
+
val last : 'a list -> 'a
+ (** Return the last element of the list. It raises [Failure _] if the
+ list is empty. This is the first part of [sep_last]. *)
+
val lastn : int -> 'a list -> 'a list
+ (** [lastn n l] returns the [n] last elements of [l]. It raises
+ [Failure _] if [n] is less than 0 or larger than the length of [l] *)
+
+ val chop : int -> 'a list -> 'a list * 'a list
+ (** [chop i l] splits [l] into two lists [(l1,l2)] such that
+ [l1++l2=l] and [l1] has length [i]. It raises [Failure _] when
+ [i] is negative or greater than the length of [l]. *)
+
+ val firstn : int -> 'a list -> 'a list
+ (** [firstn n l] Returns the [n] first elements of [l]. It raises
+ [Failure _] if [n] negative or too large. This is the first part
+ of [chop]. *)
+
val skipn : int -> 'a list -> 'a list
+ (** [skipn n l] drops the [n] first elements of [l]. It raises
+ [Failure _] if [n] is less than 0 or larger than the length of [l].
+ This is the second part of [chop]. *)
+
val skipn_at_least : int -> 'a list -> 'a list
+ (** Same as [skipn] but returns [] if [n] is larger than the list of
+ the list. *)
- val addn : int -> 'a -> 'a list -> 'a list
- (** [addn n x l] adds [n] times [x] on the left of [l]. *)
+ val drop_prefix : 'a eq -> 'a list -> 'a list -> 'a list
+ (** [drop_prefix eq l1 l] returns [l2] if [l=l1++l2] else return [l]. *)
+
+ val insert : 'a eq -> 'a -> 'a list -> 'a list
+ (** Insert at the (first) position so that if the list is ordered wrt to the
+ total order given as argument, the order is preserved *)
+
+ val share_tails : 'a list -> 'a list -> 'a list * 'a list * 'a list
+ (** [share_tails l1 l2] returns [(l1',l2',l)] such that [l1] is
+ [l1'\@l] and [l2] is [l2'\@l] and [l] is maximal amongst all such
+ decompositions *)
+
+ (** {6 Association lists} *)
+
+ val map_assoc : ('a -> 'b) -> ('c * 'a) list -> ('c * 'b) list
+ (** Applies a function on the codomain of an association list *)
+
+ val assoc_f : 'a eq -> 'a -> ('a * 'b) list -> 'b
+ (** Like [List.assoc] but using the equality given as argument *)
+
+ val remove_assoc_f : 'a eq -> 'a -> ('a * 'b) list -> ('a * 'b) list
+ (** Remove first matching element; unchanged if no such element *)
+
+ val mem_assoc_f : 'a eq -> 'a -> ('a * 'b) list -> bool
+ (** Like [List.mem_assoc] but using the equality given as argument *)
- val prefix_of : 'a eq -> 'a list -> 'a list -> bool
- (** [prefix_of l1 l2] returns [true] if [l1] is a prefix of [l2], [false]
+ val factorize_left : 'a eq -> ('a * 'b) list -> ('a * 'b list) list
+ (** Create a list of associations from a list of pairs *)
+
+ (** {6 Operations on lists of tuples} *)
+
+ val split : ('a * 'b) list -> 'a list * 'b list
+ (** Like OCaml's [List.split] but tail-recursive. *)
+
+ val combine : 'a list -> 'b list -> ('a * 'b) list
+ (** Like OCaml's [List.combine] but tail-recursive. *)
+
+ val split3 : ('a * 'b * 'c) list -> 'a list * 'b list * 'c list
+ (** Like [split] but for triples *)
+
+ val combine3 : 'a list -> 'b list -> 'c list -> ('a * 'b * 'c) list
+ (** Like [combine] but for triples *)
+
+ (** {6 Operations on lists seen as sets, preserving uniqueness of elements} *)
+
+ val add_set : 'a eq -> 'a -> 'a list -> 'a list
+ (** [add_set x l] adds [x] in [l] if it is not already there, or returns [l]
otherwise. *)
- val drop_prefix : 'a eq -> 'a list -> 'a list -> 'a list
- (** [drop_prefix p l] returns [t] if [l=p++t] else return [l]. *)
+ val eq_set : 'a eq -> 'a list eq
+ (** Test equality up to permutation. It respects multiple occurrences
+ and thus works also on multisets. *)
- val drop_last : 'a list -> 'a list
+ val subset : 'a list eq
+ (** Tell if a list is a subset of another up to permutation. It expects
+ each element to occur only once. *)
- val map_append : ('a -> 'b list) -> 'a list -> 'b list
- (** [map_append f [x1; ...; xn]] returns [(f x1)@(f x2)@...@(f xn)]. *)
+ val merge_set : 'a cmp -> 'a list -> 'a list -> 'a list
+ (** Merge two sorted lists and preserves the uniqueness property. *)
- val map_append2 : ('a -> 'b -> 'c list) -> 'a list -> 'b list -> 'c list
- (** As [map_append]. Raises [Invalid_argument _] if the two lists don't have
- the same length. *)
+ val intersect : 'a eq -> 'a list -> 'a list -> 'a list
+ (** Return the intersection of two lists, assuming and preserving
+ uniqueness of elements *)
- val share_tails : 'a list -> 'a list -> 'a list * 'a list * 'a list
+ val union : 'a eq -> 'a list -> 'a list -> 'a list
+ (** Return the union of two lists, assuming and preserving
+ uniqueness of elements *)
- val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
- (** [fold_left_map f e_0 [l_1...l_n] = e_n,[k_1...k_n]]
- where [(e_i,k_i)=f e_{i-1} l_i] *)
+ val unionq : 'a list -> 'a list -> 'a list
+ (** [union] specialized to physical equality *)
- val fold_right_map : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
- (** Same, folding on the right *)
+ val subtract : 'a eq -> 'a list -> 'a list -> 'a list
+ (** Remove from the first list all elements from the second list. *)
- val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b list -> 'c list -> 'a * 'd list
- (** Same with two lists, folding on the left *)
+ val subtractq : 'a list -> 'a list -> 'a list
+ (** [subtract] specialized to physical equality *)
- val fold_right2_map : ('b -> 'c -> 'a -> 'd * 'a) -> 'b list -> 'c list -> 'a -> 'd list * 'a
- (** Same with two lists, folding on the right *)
+ val merge_uniq : 'a cmp -> 'a list -> 'a list -> 'a list
+ [@@ocaml.deprecated "Same as [merge_set]"]
- val fold_left3_map : ('a -> 'b -> 'c -> 'd -> 'a * 'e) -> 'a -> 'b list -> 'c list -> 'd list -> 'a * 'e list
- (** Same with three lists, folding on the left *)
+ (** {6 Uniqueness and duplication} *)
- val fold_left4_map : ('a -> 'b -> 'c -> 'd -> 'e -> 'a * 'r) -> 'a -> 'b list -> 'c list -> 'd list -> 'e list -> 'a * 'r list
- (** Same with four lists, folding on the left *)
+ val distinct : 'a list -> bool
+ (** Return [true] if all elements of the list are distinct. *)
- val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
- [@@ocaml.deprecated "Same as [fold_left_map]"]
+ val distinct_f : 'a cmp -> 'a list -> bool
+ (** Like [distinct] but using the equality given as argument *)
- val fold_map' : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
- [@@ocaml.deprecated "Same as [fold_right_map]"]
+ val duplicates : 'a eq -> 'a list -> 'a list
+ (** Return the list of unique elements which appear at least twice. Elements
+ are kept in the order of their first appearance. *)
- val map_assoc : ('a -> 'b) -> ('c * 'a) list -> ('c * 'b) list
- val assoc_f : 'a eq -> 'a -> ('a * 'b) list -> 'b
- val remove_assoc_f : 'a eq -> 'a -> ('a * 'b) list -> ('a * 'b) list
- val mem_assoc_f : 'a eq -> 'a -> ('a * 'b) list -> bool
+ val uniquize : 'a list -> 'a list
+ (** Return the list of elements without duplicates.
+ This is the list unchanged if there was none. *)
+
+ val sort_uniquize : 'a cmp -> 'a list -> 'a list
+ (** 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
- (** A generic cartesian product: for any operator (**),
+ (** A generic binary cartesian product: for any operator (**),
[cartesian (**) [x1;x2] [y1;y2] = [x1**y1; x1**y2; x2**y1; x2**y1]],
and so on if there are more elements in the lists. *)
val cartesians : ('a -> 'b -> 'b) -> 'b -> 'a list list -> 'b list
- (** [cartesians] is an n-ary cartesian product: it iterates
- [cartesian] over a list of lists. *)
+ (** [cartesians op init l] is an n-ary cartesian product: it builds
+ the list of all [op a1 .. (op an init) ..] for [a1], ..., [an] in
+ the product of the elements of the lists *)
val combinations : 'a list list -> 'a list list
- (** combinations [[a;b];[c;d]] returns [[a;c];[a;d];[b;c];[b;d]] *)
-
- val combine3 : 'a list -> 'b list -> 'c list -> ('a * 'b * 'c) list
+ (** [combinations l] returns the list of [n_1] * ... * [n_p] tuples
+ [[a11;...;ap1];...;[a1n_1;...;apn_pd]] whenever [l] is a list
+ [[a11;..;a1n_1];...;[ap1;apn_p]]; otherwise said, it is
+ [cartesians (::) [] l] *)
val cartesians_filter :
('a -> 'b -> 'b option) -> 'b -> 'a list list -> 'b list
- (** Keep only those products that do not return None *)
-
- val factorize_left : 'a eq -> ('a * 'b) list -> ('a * 'b list) list
+ (** Like [cartesians op init l] but keep only the tuples for which
+ [op] returns [Some _] on all the elements of the tuple. *)
+
+ module Smart :
+ sig
+ val map : ('a -> 'a) -> 'a list -> 'a list
+ (** [Smart.map f [a1...an] = List.map f [a1...an]] but if for all i
+ [f ai == ai], then [Smart.map f l == l] *)
+ end
module type MonoS = sig
type elt
diff --git a/clib/cMap.ml b/clib/cMap.ml
index 373e3f8f..54a8b258 100644
--- a/clib/cMap.ml
+++ b/clib/cMap.ml
@@ -35,8 +35,15 @@ sig
val fold_left : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
val fold_right : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
val smartmap : ('a -> 'a) -> 'a t -> 'a t
+ [@@ocaml.deprecated "Same as [Smart.map]"]
val smartmapi : (key -> 'a -> 'a) -> 'a t -> 'a t
+ [@@ocaml.deprecated "Same as [Smart.mapi]"]
val height : 'a t -> int
+ module Smart :
+ sig
+ val map : ('a -> 'a) -> 'a t -> 'a t
+ val mapi : (key -> 'a -> 'a) -> 'a t -> 'a t
+ end
module Unsafe :
sig
val map : (key -> 'a -> key * 'b) -> 'a t -> 'b t
@@ -59,8 +66,15 @@ sig
val fold_left : (M.t -> 'a -> 'b -> 'b) -> 'a map -> 'b -> 'b
val fold_right : (M.t -> 'a -> 'b -> 'b) -> 'a map -> 'b -> 'b
val smartmap : ('a -> 'a) -> 'a map -> 'a map
+ [@@ocaml.deprecated "Same as [Smart.map]"]
val smartmapi : (M.t -> 'a -> 'a) -> 'a map -> 'a map
+ [@@ocaml.deprecated "Same as [Smart.mapi]"]
val height : 'a map -> int
+ module Smart :
+ sig
+ val map : ('a -> 'a) -> 'a map -> 'a map
+ val mapi : (M.t -> 'a -> 'a) -> 'a map -> 'a map
+ end
module Unsafe :
sig
val map : (M.t -> 'a -> M.t * 'b) -> 'a map -> 'b map
@@ -154,28 +168,36 @@ struct
let accu = f k v (fold_right f r accu) in
fold_right f l accu
- let rec smartmap f (s : 'a map) = match map_prj s with
- | MEmpty -> map_inj MEmpty
- | MNode (l, k, v, r, h) ->
- let l' = smartmap f l in
- let r' = smartmap f r in
- let v' = f v in
- if l == l' && r == r' && v == v' then s
- else map_inj (MNode (l', k, v', r', h))
-
- let rec smartmapi f (s : 'a map) = match map_prj s with
- | MEmpty -> map_inj MEmpty
- | MNode (l, k, v, r, h) ->
- let l' = smartmapi f l in
- let r' = smartmapi f r in
- let v' = f k v in
- if l == l' && r == r' && v == v' then s
- else map_inj (MNode (l', k, v', r', h))
-
let height s = match map_prj s with
| MEmpty -> 0
| MNode (_, _, _, _, h) -> h
+ module Smart =
+ struct
+
+ let rec map f (s : 'a map) = match map_prj s with
+ | MEmpty -> map_inj MEmpty
+ | MNode (l, k, v, r, h) ->
+ let l' = map f l in
+ let r' = map f r in
+ let v' = f v in
+ if l == l' && r == r' && v == v' then s
+ else map_inj (MNode (l', k, v', r', h))
+
+ let rec mapi f (s : 'a map) = match map_prj s with
+ | MEmpty -> map_inj MEmpty
+ | MNode (l, k, v, r, h) ->
+ let l' = mapi f l in
+ let r' = mapi f r in
+ let v' = f k v in
+ if l == l' && r == r' && v == v' then s
+ else map_inj (MNode (l', k, v', r', h))
+
+ end
+
+ let smartmap = Smart.map
+ let smartmapi = Smart.mapi
+
module Unsafe =
struct
diff --git a/clib/cMap.mli b/clib/cMap.mli
index bb0019bb..127bf23a 100644
--- a/clib/cMap.mli
+++ b/clib/cMap.mli
@@ -58,14 +58,23 @@ sig
(** Folding keys in decreasing order. *)
val smartmap : ('a -> 'a) -> 'a t -> 'a t
- (** As [map] but tries to preserve sharing. *)
+ [@@ocaml.deprecated "Same as [Smart.map]"]
val smartmapi : (key -> 'a -> 'a) -> 'a t -> 'a t
- (** As [mapi] but tries to preserve sharing. *)
+ [@@ocaml.deprecated "Same as [Smart.mapi]"]
val height : 'a t -> int
(** An indication of the logarithmic size of a map *)
+ module Smart :
+ sig
+ val map : ('a -> 'a) -> 'a t -> 'a t
+ (** As [map] but tries to preserve sharing. *)
+
+ val mapi : (key -> 'a -> 'a) -> 'a t -> 'a t
+ (** As [mapi] but tries to preserve sharing. *)
+ end
+
module Unsafe :
sig
val map : (key -> 'a -> key * 'b) -> 'a t -> 'b t
diff --git a/clib/canary.ml b/clib/canary.ml
deleted file mode 100644
index b8b79ed7..00000000
--- a/clib/canary.ml
+++ /dev/null
@@ -1,28 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* M.t
- val inj : M.t -> t
-end
-(** Adds a canary to any type. *)
diff --git a/clib/clib.mllib b/clib/clib.mllib
index c9b4d72f..5a2c9a9c 100644
--- a/clib/clib.mllib
+++ b/clib/clib.mllib
@@ -1,4 +1,3 @@
-Canary
CObj
CEphemeron
@@ -38,3 +37,5 @@ Backtrace
IStream
Terminal
Monad
+
+Diff2
diff --git a/clib/diff2.ml b/clib/diff2.ml
new file mode 100644
index 00000000..42c4733f
--- /dev/null
+++ b/clib/diff2.ml
@@ -0,0 +1,158 @@
+(* copied from https://github.com/leque/ocaml-diff.git and renamed from "diff.ml" *)
+
+(*
+ * Copyright (C) 2016 OOHASHI Daichi
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *)
+
+type 'a common =
+ [ `Common of int * int * 'a ]
+
+type 'a edit =
+ [ `Added of int * 'a
+ | `Removed of int * 'a
+ | 'a common
+ ]
+
+module type SeqType = sig
+ type t
+ type elem
+ val get : t -> int -> elem
+ val length : t -> int
+end
+
+module type S = sig
+ type t
+ type elem
+
+ val lcs :
+ ?equal:(elem -> elem -> bool) ->
+ t -> t -> elem common list
+
+ val diff :
+ ?equal:(elem -> elem -> bool) ->
+ t -> t -> elem edit list
+
+ val fold_left :
+ ?equal:(elem -> elem -> bool) ->
+ f:('a -> elem edit -> 'a) ->
+ init:'a ->
+ t -> t -> 'a
+
+ val iter :
+ ?equal:(elem -> elem -> bool) ->
+ f:(elem edit -> unit) ->
+ t -> t -> unit
+end
+
+module Make(M : SeqType) : (S with type t = M.t and type elem = M.elem) = struct
+ type t = M.t
+ type elem = M.elem
+
+ let lcs ?(equal = (=)) a b =
+ let n = M.length a in
+ let m = M.length b in
+ let mn = m + n in
+ let sz = 2 * mn + 1 in
+ let vd = Array.make sz 0 in
+ let vl = Array.make sz 0 in
+ let vr = Array.make sz [] in
+ let get v i = Array.get v (i + mn) in
+ let set v i x = Array.set v (i + mn) x in
+ let finish () =
+ let rec loop i maxl r =
+ if i > mn then
+ List.rev r
+ else if get vl i > maxl then
+ loop (i + 1) (get vl i) (get vr i)
+ else
+ loop (i + 1) maxl r
+ in loop (- mn) 0 []
+ in
+ if mn = 0 then
+ []
+ else
+ (* For d <- 0 to mn Do *)
+ let rec dloop d =
+ assert (d <= mn);
+ (* For k <- -d to d in steps of 2 Do *)
+ let rec kloop k =
+ if k > d then
+ dloop @@ d + 1
+ else
+ let x, l, r =
+ if k = -d || (k <> d && get vd (k - 1) < get vd (k + 1)) then
+ get vd (k + 1), get vl (k + 1), get vr (k + 1)
+ else
+ get vd (k - 1) + 1, get vl (k - 1), get vr (k - 1)
+ in
+ let x, y, l, r =
+ let rec xyloop x y l r =
+ if x < n && y < m && equal (M.get a x) (M.get b y) then
+ xyloop (x + 1) (y + 1) (l + 1) (`Common(x, y, M.get a x) :: r)
+ else
+ x, y, l, r
+ in xyloop x (x - k) l r
+ in
+ set vd k x;
+ set vl k l;
+ set vr k r;
+ if x >= n && y >= m then
+ (* Stop *)
+ finish ()
+ else
+ kloop @@ k + 2
+ in kloop @@ -d
+ in dloop 0
+
+ let fold_left ?(equal = (=)) ~f ~init a b =
+ let ff x y = f y x in
+ let fold_map f g x from to_ init =
+ let rec loop i init =
+ if i >= to_ then
+ init
+ else
+ loop (i + 1) (f (g i @@ M.get x i) init)
+ in loop from init
+ in
+ let added i x = `Added (i, x) in
+ let removed i x = `Removed (i, x) in
+ let rec loop cs apos bpos init =
+ match cs with
+ | [] ->
+ init
+ |> fold_map ff removed a apos (M.length a)
+ |> fold_map ff added b bpos (M.length b)
+ | `Common (aoff, boff, _) as e :: rest ->
+ init
+ |> fold_map ff removed a apos aoff
+ |> fold_map ff added b bpos boff
+ |> ff e
+ |> loop rest (aoff + 1) (boff + 1)
+ in loop (lcs ~equal a b) 0 0 init
+
+ let diff ?(equal = (=)) a b =
+ fold_left ~equal ~f:(fun xs x -> x::xs) ~init:[] a b
+
+ let iter ?(equal = (=)) ~f a b =
+ fold_left a b
+ ~equal
+ ~f:(fun () x -> f x)
+ ~init:()
+end
diff --git a/clib/diff2.mli b/clib/diff2.mli
new file mode 100644
index 00000000..a085f4ff
--- /dev/null
+++ b/clib/diff2.mli
@@ -0,0 +1,101 @@
+(* copied from https://github.com/leque/ocaml-diff.git and renamed from "diff.mli" *)
+(**
+ An implementation of Eugene Myers' O(ND) Difference Algorithm\[1\].
+ This implementation is a port of util.lcs module of
+ {{:http://practical-scheme.net/gauche} Gauche Scheme interpreter}.
+
+ - \[1\] Eugene Myers, An O(ND) Difference Algorithm and Its Variations, Algorithmica Vol. 1 No. 2, pp. 251-266, 1986.
+ *)
+
+type 'a common = [
+ `Common of int * int * 'a
+ ]
+(** an element of lcs of seq1 and seq2 *)
+
+type 'a edit =
+ [ `Removed of int * 'a
+ | `Added of int * 'a
+ | 'a common
+ ]
+(** an element of diff of seq1 and seq2. *)
+
+module type SeqType = sig
+ type t
+ (** The type of the sequence. *)
+
+ type elem
+ (** The type of the elements of the sequence. *)
+
+ val get : t -> int -> elem
+ (** [get t n] returns [n]-th element of the sequence [t]. *)
+
+ val length : t -> int
+ (** [length t] returns the length of the sequence [t]. *)
+end
+(** Input signature of {!Diff.Make}. *)
+
+module type S = sig
+ type t
+ (** The type of input sequence. *)
+
+ type elem
+ (** The type of the elements of result / input sequence. *)
+
+ val lcs :
+ ?equal:(elem -> elem -> bool) ->
+ t -> t -> elem common list
+ (**
+ [lcs ~equal seq1 seq2] computes the LCS (longest common sequence) of
+ [seq1] and [seq2].
+ Elements of [seq1] and [seq2] are compared with [equal].
+ [equal] defaults to [Pervasives.(=)].
+
+ Elements of lcs are [`Common (pos1, pos2, e)]
+ where [e] is an element, [pos1] is a position in [seq1],
+ and [pos2] is a position in [seq2].
+ *)
+
+ val diff :
+ ?equal:(elem -> elem -> bool) ->
+ t -> t -> elem edit list
+ (**
+ [diff ~equal seq1 seq2] computes the diff of [seq1] and [seq2].
+ Elements of [seq1] and [seq2] are compared with [equal].
+
+ Elements only in [seq1] are represented as [`Removed (pos, e)]
+ where [e] is an element, and [pos] is a position in [seq1];
+ those only in [seq2] are represented as [`Added (pos, e)]
+ where [e] is an element, and [pos] is a position in [seq2];
+ those common in [seq1] and [seq2] are represented as
+ [`Common (pos1, pos2, e)]
+ where [e] is an element, [pos1] is a position in [seq1],
+ and [pos2] is a position in [seq2].
+ *)
+
+ val fold_left :
+ ?equal:(elem -> elem -> bool) ->
+ f:('a -> elem edit -> 'a) ->
+ init:'a ->
+ t -> t -> 'a
+ (**
+ [fold_left ~equal ~f ~init seq1 seq2] is same as
+ [diff ~equal seq1 seq2 |> ListLabels.fold_left ~f ~init],
+ but does not create an intermediate list.
+ *)
+
+ val iter :
+ ?equal:(elem -> elem -> bool) ->
+ f:(elem edit -> unit) ->
+ t -> t -> unit
+ (**
+ [iter ~equal ~f seq1 seq2] is same as
+ [diff ~equal seq1 seq2 |> ListLabels.iter ~f],
+ but does not create an intermediate list.
+ *)
+end
+(** Output signature of {!Diff.Make}. *)
+
+module Make :
+ functor (M : SeqType) -> (S with type t = M.t and type elem = M.elem)
+(** Functor building an implementation of the diff structure
+ given a sequence type. *)
diff --git a/clib/dyn.ml b/clib/dyn.ml
index e9b04198..6c457672 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 51d30914..ff9762bd 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/clib/hMap.ml b/clib/hMap.ml
index 37f867c6..b2cf4743 100644
--- a/clib/hMap.ml
+++ b/clib/hMap.ml
@@ -383,13 +383,21 @@ struct
let m = Map.set k x m in
Int.Map.set h m s
- let smartmap f s =
- let fs m = Map.smartmap f m in
- Int.Map.smartmap fs s
+ module Smart =
+ struct
+
+ let map f s =
+ let fs m = Map.Smart.map f m in
+ Int.Map.Smart.map fs s
+
+ let mapi f s =
+ let fs m = Map.Smart.mapi f m in
+ Int.Map.Smart.map fs s
+
+ end
- let smartmapi f s =
- let fs m = Map.smartmapi f m in
- Int.Map.smartmap fs s
+ let smartmap = Smart.map
+ let smartmapi = Smart.mapi
let height s = Int.Map.height s
diff --git a/clib/hashcons.ml b/clib/hashcons.ml
index ec73c6d9..39969ebf 100644
--- a/clib/hashcons.ml
+++ b/clib/hashcons.ml
@@ -10,8 +10,6 @@
(* Hash consing of datastructures *)
-(* The generic hash-consing functions (does not use Obj) *)
-
(* [t] is the type of object to hash-cons
* [u] is the type of hash-cons functions for the sub-structures
* of objects of type t (u usually has the form (t1->t1)*(t2->t2)*...).
@@ -148,41 +146,3 @@ module Hstring = Make(
let len = String.length s in
hash len s 0 0
end)
-
-(* Obj.t *)
-exception NotEq
-
-(* From CAMLLIB/caml/mlvalues.h *)
-let no_scan_tag = 251
-let tuple_p obj = Obj.is_block obj && (Obj.tag obj < no_scan_tag)
-
-let comp_obj o1 o2 =
- if tuple_p o1 && tuple_p o2 then
- let n1 = Obj.size o1 and n2 = Obj.size o2 in
- if n1=n2 then
- try
- for i = 0 to pred n1 do
- if not (Obj.field o1 i == Obj.field o2 i) then raise NotEq
- done; true
- with NotEq -> false
- else false
- else o1=o2
-
-let hash_obj hrec o =
- begin
- if tuple_p o then
- let n = Obj.size o in
- for i = 0 to pred n do
- Obj.set_field o i (hrec (Obj.field o i))
- done
- end;
- o
-
-module Hobj = Make(
- struct
- type t = Obj.t
- type u = (Obj.t -> Obj.t) * unit
- let hashcons (hrec,_) = hash_obj hrec
- let eq = comp_obj
- let hash = Hashtbl.hash
- end)
diff --git a/clib/hashcons.mli b/clib/hashcons.mli
index 3e396ff2..223dd2a4 100644
--- a/clib/hashcons.mli
+++ b/clib/hashcons.mli
@@ -87,6 +87,3 @@ module Hstring : (S with type t = string and type u = unit)
module Hlist (D:HashedType) :
(S with type t = D.t list and type u = (D.t list -> D.t list)*(D.t->D.t))
(** Hashconsing of lists. *)
-
-module Hobj : (S with type t = Obj.t and type u = (Obj.t -> Obj.t) * unit)
-(** Hashconsing of OCaml values. *)
diff --git a/clib/option.ml b/clib/option.ml
index 32fe2fc5..7a3d5f93 100644
--- a/clib/option.ml
+++ b/clib/option.ml
@@ -100,12 +100,6 @@ let map f = function
| Some y -> Some (f y)
| _ -> None
-(** [smartmap f x] does the same as [map f x] except that it tries to share
- some memory. *)
-let smartmap f = function
- | Some y as x -> let y' = f y in if y' == y then x else Some y'
- | _ -> None
-
(** [fold_left f a x] is [f a y] if [x] is [Some y], and [a] otherwise. *)
let fold_left f a = function
| Some y -> f a y
@@ -176,6 +170,21 @@ let lift2 f x y =
| _,_ -> None
+(** {6 Smart operations} *)
+
+module Smart =
+struct
+
+ (** [Smart.map f x] does the same as [map f x] except that it tries to share
+ some memory. *)
+ let map f = function
+ | Some y as x -> let y' = f y in if y' == y then x else Some y'
+ | _ -> None
+
+end
+
+let smartmap = Smart.map
+
(** {6 Operations with Lists} *)
module List =
diff --git a/clib/option.mli b/clib/option.mli
index 14fa9da3..8f82bf09 100644
--- a/clib/option.mli
+++ b/clib/option.mli
@@ -75,9 +75,8 @@ val iter2 : ('a -> 'b -> unit) -> 'a option -> 'b option -> unit
(** [map f x] is [None] if [x] is [None] and [Some (f y)] if [x] is [Some y]. *)
val map : ('a -> 'b) -> 'a option -> 'b option
-(** [smartmap f x] does the same as [map f x] except that it tries to share
- some memory. *)
val smartmap : ('a -> 'a) -> 'a option -> 'a option
+[@@ocaml.deprecated "Same as [Smart.map]"]
(** [fold_left f a x] is [f a y] if [x] is [Some y], and [a] otherwise. *)
val fold_left : ('b -> 'a -> 'b) -> 'b -> 'a option -> 'b
@@ -123,6 +122,16 @@ val lift_left : ('a -> 'b -> 'c) -> 'a option -> 'b -> 'c option
[Some w]. It is [None] otherwise. *)
val lift2 : ('a -> 'b -> 'c) -> 'a option -> 'b option -> 'c option
+(** {6 Smart operations} *)
+
+module Smart :
+sig
+
+ (** [Smart.map f x] does the same as [map f x] except that it tries to share
+ some memory. *)
+ val map : ('a -> 'a) -> 'a option -> 'a option
+
+end
(** {6 Operations with Lists} *)
diff --git a/clib/terminal.ml b/clib/terminal.ml
index 1d946813..d243d659 100644
--- a/clib/terminal.ml
+++ b/clib/terminal.ml
@@ -59,6 +59,19 @@ let default = {
suffix = None;
}
+let reset = "\027[0m"
+
+let reset_style = {
+ fg_color = Some `DEFAULT;
+ bg_color = Some `DEFAULT;
+ bold = Some false;
+ italic = Some false;
+ underline = Some false;
+ negative = Some false;
+ prefix = None;
+ suffix = None;
+}
+
let make ?fg_color ?bg_color ?bold ?italic ?underline ?negative ?style ?prefix ?suffix () =
let st = match style with
| None -> default
@@ -87,6 +100,25 @@ let merge s1 s2 =
suffix = set s1.suffix s2.suffix;
}
+let diff s1 s2 =
+ let diff_op o1 o2 reset_val = match o1 with
+ | None -> o2
+ | Some _ ->
+ match o2 with
+ | None -> reset_val
+ | Some _ -> if o1 = o2 then None else o2 in
+
+ {
+ fg_color = diff_op s1.fg_color s2.fg_color reset_style.fg_color;
+ bg_color = diff_op s1.bg_color s2.bg_color reset_style.bg_color;
+ bold = diff_op s1.bold s2.bold reset_style.bold;
+ italic = diff_op s1.italic s2.italic reset_style.italic;
+ underline = diff_op s1.underline s2.underline reset_style.underline;
+ negative = diff_op s1.negative s2.negative reset_style.negative;
+ prefix = diff_op s1.prefix s2.prefix reset_style.prefix;
+ suffix = diff_op s1.suffix s2.suffix reset_style.suffix;
+ }
+
let base_color = function
| `DEFAULT -> 9
| `BLACK -> 0
@@ -167,20 +199,8 @@ let repr st =
let eval st =
let tags = repr st in
let tags = List.map string_of_int tags in
- Printf.sprintf "\027[%sm" (String.concat ";" tags)
-
-let reset = "\027[0m"
-
-let reset_style = {
- fg_color = Some `DEFAULT;
- bg_color = Some `DEFAULT;
- bold = Some false;
- italic = Some false;
- underline = Some false;
- negative = Some false;
- prefix = None;
- suffix = None;
-}
+ if List.length tags = 0 then "" else
+ Printf.sprintf "\027[%sm" (String.concat ";" tags)
let has_style t =
Unix.isatty t && Sys.os_type = "Unix"
diff --git a/clib/terminal.mli b/clib/terminal.mli
index dbf8d464..bc30b001 100644
--- a/clib/terminal.mli
+++ b/clib/terminal.mli
@@ -51,6 +51,9 @@ val make : ?fg_color:color -> ?bg_color:color ->
val merge : style -> style -> style
(** [merge s1 s2] returns [s1] with all defined values of [s2] overwritten. *)
+val diff : style -> style -> style
+(** [diff s1 s2] returns the differences between [s1] and [s2]. *)
+
val repr : style -> int list
(** Generate the ANSI code representing the given style. *)
@@ -60,6 +63,9 @@ val eval : style -> string
val reset : string
(** This escape sequence resets all attributes. *)
+val reset_style : style
+(** The default style *)
+
val has_style : Unix.file_descr -> bool
(** Whether an output file descriptor handles styles. Very heuristic, only
checks it is a terminal. *)
diff --git a/configure.ml b/configure.ml
index 5bbf0111..4b468c7e 100644
--- a/configure.ml
+++ b/configure.ml
@@ -11,21 +11,29 @@
#load "str.cma"
open Printf
-let coq_version = "8.8.2"
-let coq_macos_version = "8.8.2" (** "[...] should be a string comprised of
+let coq_version = "8.9.0"
+let coq_macos_version = "8.9.0" (** "[...] should be a string comprised of
three non-negative, period-separated integers [...]" *)
-let vo_magic = 8800
-let state_magic = 58800
-let distributed_exec = ["coqtop";"coqc";"coqchk";"coqdoc";"coqworkmgr";
-"coqdoc";"coq_makefile";"coq-tex";"gallina";"coqwc";"csdpcert";"coqdep"]
+let vo_magic = 8900
+let state_magic = 58900
+let distributed_exec =
+ ["coqtop.opt"; "coqidetop.opt"; "coqqueryworker.opt"; "coqproofworker.opt"; "coqtacticworker.opt";
+ "coqc";"coqchk";"coqdoc";"coqworkmgr";"coq_makefile";"coq-tex";"coqwc";"csdpcert";"coqdep"]
let verbose = ref false (* for debugging this script *)
+let red, yellow, reset =
+ if Unix.isatty Unix.stdout && Unix.isatty Unix.stderr && Sys.os_type = "Unix"
+ then "\027[31m", "\027[33m", "\027[0m"
+ else "", "", ""
+
(** * Utility functions *)
let cfprintf oc = kfprintf (fun oc -> fprintf oc "\n%!") oc
let cprintf s = cfprintf stdout s
let ceprintf s = cfprintf stderr s
-let die msg = ceprintf "%s\nConfiguration script failed!" msg; exit 1
+let die msg = ceprintf "%s%s%s\nConfiguration script failed!" red msg reset; exit 1
+
+let warn s = kfprintf (fun oc -> cfprintf oc "%s" reset) stdout ("%sWarning: " ^^ s) yellow
let s2i = int_of_string
let i2s = string_of_int
@@ -109,7 +117,7 @@ let run ?(fatal=true) ?(err=StdErr) prog args =
let cmd = String.concat " " (prog::args) in
let exn = match e with Failure s -> s | _ -> Printexc.to_string e in
let msg = sprintf "Error while running '%s' (%s)" cmd exn in
- if fatal then die msg else (cprintf "W: %s" msg; "", [])
+ if fatal then die msg else (warn "%s" msg; "", [])
let tryrun prog args = run ~fatal:false ~err:DevNull prog args
@@ -205,7 +213,7 @@ let win_aware_quote_executable str =
sprintf "%S" str
else
let _ = if contains_suspicious_characters str then
- cprintf "*Warning* The string %S contains suspicious characters; ocamlfind might fail" str in
+ warn "The string %S contains suspicious characters; ocamlfind might fail" str in
Str.global_replace (Str.regexp "\\\\") "/" str
(** * Date *)
@@ -227,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
@@ -248,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;
@@ -286,7 +287,6 @@ let default = {
datadir = None;
mandir = None;
docdir = None;
- emacslib = None;
coqdocdir = None;
ocamlfindcmd = None;
lablgtkdir = None;
@@ -384,8 +384,6 @@ let args_options = Arg.align [
" Where to install man files";
"-docdir", arg_string_option (fun p docdir -> { p with docdir }),
" Where to install doc files";
- "-emacslib", arg_string_option (fun p emacslib -> { p with emacslib }),
- " Where to install emacs files";
"-coqdocdir", arg_string_option (fun p coqdocdir -> { p with coqdocdir }),
" Where to install Coqdoc style files";
"-ocamlfind", arg_string_option (fun p ocamlfindcmd -> { p with ocamlfindcmd }),
@@ -414,8 +412,8 @@ let args_options = Arg.align [
" Do not add debugging information in the Coq executables";
"-profiling", arg_set (fun p profile -> { p with profile }),
" Add profiling information in the Coq executables";
- "-annotate", Arg.Unit (fun () -> cprintf "*Warning* -annotate is deprecated. Please use -annot or -bin-annot instead."),
- " Deprecated. Please use -annot or -bin-annot instead";
+ "-annotate", Arg.Unit (fun () -> die "-annotate has been removed. Please use -annot or -bin-annot instead."),
+ " Removed option. Please use -annot or -bin-annot instead";
"-annot", arg_set (fun p annot -> { p with annot }),
" Dumps ml text annotation files while compiling Coq (e.g. for Tuareg)";
"-bin-annot", arg_set (fun p bin_annot -> { p with bin_annot }),
@@ -453,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
@@ -472,6 +475,7 @@ let coq_bin_annot_flag = if !prefs.bin_annot then "-bin-annot" else ""
(* This variable can be overriden only for debug purposes, use with
care. *)
let coq_safe_string = "-safe-string"
+let coq_strict_sequence = "-strict-sequence"
let cflags = "-Wall -Wno-unused -g -O2"
@@ -571,6 +575,9 @@ let camlbin, caml_version, camllib, findlib_version =
let () =
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
@@ -598,7 +605,7 @@ let check_caml_version () =
else
let () = cprintf "Your version of OCaml is %s." caml_version in
if !prefs.force_caml_version then
- cprintf "*Warning* Your version of OCaml is outdated."
+ warn "Your version of OCaml is outdated."
else
die "You need OCaml 4.02.3 or later."
@@ -620,7 +627,7 @@ let check_findlib_version () =
else
let () = cprintf "Your version of OCamlfind is %s." findlib_version in
if !prefs.force_findlib_version then
- cprintf "*Warning* Your version of OCamlfind is outdated."
+ warn "Your version of OCamlfind is outdated."
else
die "You need OCamlfind 1.4.1 or later."
@@ -655,7 +662,7 @@ let coq_warn_error =
(* Flags used to compile Coq and plugins (via coq_makefile) *)
let caml_flags =
- Printf.sprintf "-thread -rectypes %s %s %s %s" coq_warnings coq_annot_flag coq_bin_annot_flag coq_safe_string
+ Printf.sprintf "-thread -rectypes %s %s %s %s %s" coq_warnings coq_annot_flag coq_bin_annot_flag coq_safe_string coq_strict_sequence
(* Flags used to compile Coq but _not_ plugins (via coq_makefile) *)
let coq_caml_flags =
@@ -733,17 +740,17 @@ let camlp5libdir = shorten_camllib fullcamlp5libdir
(** * Native compiler *)
-let msg_byteonly () =
- cprintf "Only the bytecode version of Coq will be available."
+let msg_byteonly =
+ "Only the bytecode version of Coq will be available."
let msg_no_ocamlopt () =
- cprintf "Cannot find the OCaml native-code compiler."; msg_byteonly ()
+ warn "Cannot find the OCaml native-code compiler.\n%s" msg_byteonly
let msg_no_camlp5_cmxa () =
- cprintf "Cannot find the native-code library of camlp5."; msg_byteonly ()
+ warn "Cannot find the native-code library of camlp5.\n%s" msg_byteonly
let msg_no_dynlink_cmxa () =
- cprintf "Cannot find native-code dynlink library."; msg_byteonly ();
+ warn "Cannot find native-code dynlink library.\n%s" msg_byteonly;
cprintf "For building a native-code Coq, you may try to first";
cprintf "compile and install a dummy dynlink.cmxa (see dev/dynlink.ml)";
cprintf "and then run ./configure -natdynlink no"
@@ -759,8 +766,7 @@ let check_native () =
else
let () =
if version <> caml_version then
- cprintf
- "Warning: Native and bytecode compilers do not have the same version!"
+ warn "Native and bytecode compilers do not have the same version!"
in cprintf "You have native-code compilation. Good!"
let best_compiler =
@@ -815,7 +821,7 @@ let get_source = function
(** Is some location a suitable LablGtk2 installation ? *)
let check_lablgtkdir ?(fatal=false) src dir =
- let yell msg = if fatal then die msg else (cprintf "%s" msg; false) in
+ let yell msg = if fatal then die msg else (warn "%s" msg; false) in
let msg = get_source src in
if not (dir_exists dir) then
yell (sprintf "No such directory '%s' (%s)." dir msg)
@@ -851,7 +857,7 @@ let get_lablgtkdir () =
let check_lablgtk_version src dir = match src with
| Manual | Stdlib ->
- cprintf "Warning: could not check the version of lablgtk2.\nMake sure your version is at least 2.18.3.";
+ warn "Could not check the version of lablgtk2.\nMake sure your version is at least 2.18.3.";
(true, "an unknown version")
| OCamlFind ->
let v, _ = tryrun camlexec.find ["query"; "-format"; "%v"; "lablgtk2"] in
@@ -862,7 +868,11 @@ let check_lablgtk_version src dir = match src with
else if vi < [2; 18; 3] then
begin
(* Version 2.18.3 is known to report incorrectly as 2.18.0, and Launchpad packages report as version 2.16.0 due to a misconfigured META file; see https://bugs.launchpad.net/ubuntu/+source/lablgtk2/+bug/1577236 *)
- cprintf "Warning: Your installed lablgtk reports as %s.\n It is possible that the installed version is actually more recent\n but reports an incorrect version. If the installed version is\n actually more recent than 2.18.3, that's fine; if it is not,\n CoqIDE will compile but may be very unstable." v;
+ warn "Your installed lablgtk reports as %s.\n\
+It is possible that the installed version is actually more recent\n\
+but reports an incorrect version. If the installed version is\n\
+actually more recent than 2.18.3, that's fine; if it is not,\n
+CoqIDE will compile but may be very unstable." v;
(true, "an unknown version")
end
else
@@ -997,8 +1007,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";
]
@@ -1214,7 +1222,7 @@ let write_configml f =
let core_src_dirs = [ "config"; "dev"; "lib"; "clib"; "kernel"; "library";
"engine"; "pretyping"; "interp"; "parsing"; "proofs";
- "tactics"; "toplevel"; "printing"; "intf";
+ "tactics"; "toplevel"; "printing";
"grammar"; "ide"; "stm"; "vernac" ] in
let core_src_dirs = List.fold_left (fun acc core_src_subdir -> acc ^ " \"" ^ core_src_subdir ^ "\";\n")
""
@@ -1239,17 +1247,6 @@ let write_configml f =
let _ = write_configml "config/coq_config.ml"
-(** * Symlinks or copies for the checker *)
-
-let _ =
- let prog, args, prf =
- if arch = "win32" then "cp", [], ""
- else "ln", ["-s"], "../" in
- List.iter (fun file ->
- ignore(run "rm" ["-f"; "checker/"^file]);
- ignore(run ~fatal:true prog (args @ [prf^"kernel/"^file;"checker/"^file])))
- [ "esubst.ml"; "esubst.mli"; "names.ml"; "names.mli" ]
-
(** * Build the config/Makefile file *)
let write_makefile f =
@@ -1282,6 +1279,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";
@@ -1342,6 +1340,7 @@ let write_makefile f =
pr "WITHDOC=%s\n\n" (if !prefs.withdoc then "all" else "no");
pr "# Option to produce precompiled files for native_compute\n";
pr "NATIVECOMPUTE=%s\n" (if !prefs.nativecompiler then "-native-compiler" else "");
+ pr "COQWARNERROR=%s\n" (if !prefs.warn_error then "-w +default" else "");
close_out o;
Unix.chmod f 0o444
diff --git a/coqpp/coqpp_ast.mli b/coqpp/coqpp_ast.mli
new file mode 100644
index 00000000..181c4361
--- /dev/null
+++ b/coqpp/coqpp_ast.mli
@@ -0,0 +1,96 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* 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 }
+| "DEPRECATED" { DEPRECATED }
+(** 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/coqpp/coqpp_main.ml b/coqpp/coqpp_main.ml
new file mode 100644
index 00000000..c7fd15f3
--- /dev/null
+++ b/coqpp/coqpp_main.ml
@@ -0,0 +1,360 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(*
+ 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 "@[let %s =@ @[%a@]@]@ " e mk_e e in
+ let iter e = fprintf fmt "@[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 "@[[%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 "@[%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.([@[%a@]])" print_rules rules
+
+let print_ast fmt ext =
+ let deprecation fmt =
+ function
+ | None -> ()
+ | Some { code } -> fprintf fmt "~deprecation:(%s) " code
+ in
+ 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%a"
+ plugin_name ext.tacext_name level
+ deprecation ext.tacext_deprecated
+ print_rules ext.tacext_rules
+ in
+ let () = fprintf fmt "let () = @[%a@]\n" pr () in
+ ()
+
+end
+
+let declare_plugin fmt name =
+ fprintf fmt "let %s = \"%s\"@\n" plugin_name name;
+ fprintf fmt "let _ = Mltop.add_known_module %s@\n" plugin_name
+
+let pr_ast fmt = function
+| Code s -> fprintf fmt "%s@\n" s.code
+| Comment s -> fprintf fmt "%s@\n" s
+| DeclarePlugin name -> declare_plugin fmt 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/coqpp/coqpp_parse.mly b/coqpp/coqpp_parse.mly
new file mode 100644
index 00000000..bf435fd2
--- /dev/null
+++ b/coqpp/coqpp_parse.mly
@@ -0,0 +1,261 @@
+/************************************************************************/
+/* v * The Coq Proof Assistant / The Coq Development Team */
+/* 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 CODE
+%token COMMENT
+%token IDENT QUALID
+%token STRING
+%token INT
+%token VERNAC TACTIC GRAMMAR EXTEND END DECLARE PLUGIN DEPRECATED
+%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 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_deprecated tactic_level tactic_rules END
+ { TacticExt { tacext_name = $3; tacext_deprecated = $4; tacext_level = $5; tacext_rules = $6 } }
+;
+
+tactic_deprecated:
+| { None }
+| DEPRECATED CODE { Some $2 }
+;
+
+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/default.nix b/default.nix
index a64d8120..12ab470d 100644
--- a/default.nix
+++ b/default.nix
@@ -61,8 +61,9 @@ stdenv.mkDerivation rec {
optional (!versionAtLeast ocaml.version "4.07") ncurses
++ [ ocamlPackages.ounit rsync which ]
)
- ++ optionals shell (with ocamlPackages;
- [ merlin ocp-indent ocp-index ] # Dev tools
+ ++ optionals shell (
+ [ jq curl git gnupg ] # Dependencies of the merging script
+ ++ (with ocamlPackages; [ merlin ocp-indent ocp-index ]) # Dev tools
);
src =
@@ -74,14 +75,15 @@ stdenv.mkDerivation rec {
prefixKey = "-prefix ";
- buildFlags = [ "world" "byte" ] ++ optional buildDoc "sphinx";
+ buildFlags = [ "world" "byte" ] ++ optional buildDoc "doc-html";
installTargets =
- [ "install" "install-byte" ] ++ optional buildDoc "install-doc-sphinx";
+ [ "install" "install-byte" ] ++ optional buildDoc "install-doc-html";
inherit doInstallCheck;
preInstallCheck = ''
+ patchShebangs dev/tools/
patchShebangs tools/
patchShebangs test-suite/
'';
diff --git a/dev/README b/dev/README
deleted file mode 100644
index 453f85f0..00000000
--- 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 00000000..4642aaf0
--- /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/base_include b/dev/base_include
index 1fb80dc0..6f54ecb2 100644
--- a/dev/base_include
+++ b/dev/base_include
@@ -15,7 +15,6 @@
#directory "tactics";;
#directory "printing";;
#directory "grammar";;
-#directory "intf";;
#directory "stm";;
#directory "vernac";;
@@ -109,8 +108,6 @@ open Inductiveops
open Locusops
open Find_subterm
open Unification
-open Miscops
-open Miscops
open Nativenorm
open Typeclasses
open Typeclasses_errors
@@ -190,7 +187,7 @@ let qid = Libnames.qualid_of_string;;
(* parsing of terms *)
let parse_constr = Pcoq.parse_string Pcoq.Constr.constr;;
-let parse_vernac = Pcoq.parse_string Pcoq.Vernac_.vernac_control;;
+let parse_vernac = Pcoq.parse_string Pvernac.Vernac_.vernac_control;;
let parse_tac = Pcoq.parse_string Ltac_plugin.Pltac.tactic;;
(* build a term of type glob_constr without type-checking or resolution of
@@ -205,7 +202,9 @@ let e s =
implicit syntax *)
let constr_of_string s =
- Constrintern.interp_constr (Global.env()) Evd.empty (parse_constr s);;
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ Constrintern.interp_constr env sigma (parse_constr s);;
(* get the body of a constant *)
@@ -230,9 +229,9 @@ let pf_e gl s =
let _ = Flags.in_debugger := false
let _ = Flags.in_toplevel := true
let _ = Constrextern.set_extern_reference
- (fun ?loc _ r -> CAst.make ?loc @@ Libnames.Qualid (Nametab.shortest_qualid_of_global Id.Set.empty r));;
+ (fun ?loc _ r -> Nametab.shortest_qualid_of_global ?loc Id.Set.empty r);;
-let go () = Coqloop.loop ~time:false ~state:Option.(get !Coqloop.drop_last_doc)
+let go () = Coqloop.(loop ~opts:Option.(get !drop_args) ~state:Option.(get !drop_last_doc))
let _ =
print_string
diff --git a/dev/build/osx/make-macos-dmg.sh b/dev/build/osx/make-macos-dmg.sh
index dc33838f..9b08f517 100755
--- a/dev/build/osx/make-macos-dmg.sh
+++ b/dev/build/osx/make-macos-dmg.sh
@@ -3,26 +3,68 @@
# Fail on first error
set -e
+# TODO use Docker instead of this
+brew update
+brew unlink python
+brew install opam gnu-time gtk+ expat gtksourceview gdk-pixbuf
+brew unlink python@2
+brew link python3
+pip3 install macpack
+opam init -a -y -j 2 --compiler=ocaml-base-compiler.4.07.1 default https://opam.ocaml.org
+opam switch ocaml-base-compiler.4.07.1
+eval $(opam config env)
+opam update
+opam config list
+opam list
+opam install -j 2 -y camlp5 ocamlfind.1.8.0 num lablgtk.2.18.6 conf-gtksourceview.2
+rm -rf ~/.opam/log/
+opam list
+
# Configuration setup
OUTDIR=$PWD/_install
DMGDIR=$PWD/_dmg
VERSION=$(sed -n -e '/^let coq_version/ s/^[^"]*"\([^"]*\)"$/\1/p' configure.ml)
APP=bin/CoqIDE_${VERSION}.app
+make clean
+./configure -native-compiler no -coqide opt -prefix "$OUTDIR"
+make -j "$NJOBS" byte
+make -j "$NJOBS" world
+make test-suite/misc/universes/all_stdlib.v
+make -j "$NJOBS" world
+make install
+make install-byte
+
# Create a .app file with CoqIDE, without signing it
-make PRIVATEBINARIES=$APP -j $NJOBS -l2 $APP
+make PRIVATEBINARIES="$APP" -j "$NJOBS" -l2 "$APP"
# Add Coq to the .app file
-make OLDROOT=$OUTDIR COQINSTALLPREFIX=$APP/Contents/Resources/ install-coq install-ide-toploop
+make OLDROOT="$OUTDIR" COQINSTALLPREFIX="$APP/Contents/Resources/" install-coq install-ide-toploop
+
+if [ -n "$MACOS_CERTIFICATE_IDENTITY" ] && [ -n "$MACOS_CERTIFICATE_PASSWORD" ] && [ -n "$MACOS_CERTIFICATE_BASE_PATH" ]
+then
+ readonly KEYCHAIN=macos-build.keychain
+ # This pile of hacks is required to avoid having to manually validate access to the key through UI
+ security create-keychain -p gitlab "${KEYCHAIN}"
+ security default-keychain -s "${KEYCHAIN}"
+ security unlock-keychain -p gitlab "${KEYCHAIN}"
+ security set-keychain-settings -t 3600 -u "${KEYCHAIN}"
+ security import "${MACOS_CERTIFICATE_BASE_PATH}/foundation.cer" -k ~/Library/Keychains/"${KEYCHAIN}" -T /usr/bin/codesign
+ security import "${MACOS_CERTIFICATE_BASE_PATH}/foundation.p12" -k ~/Library/Keychains/"${KEYCHAIN}" -P "${MACOS_CERTIFICATE_PASSWORD}" -T /usr/bin/codesign
+ security set-key-partition-list -S apple-tool:,apple: -s -k gitlab ~/Library/Keychains/"${KEYCHAIN}"
+ codesign -f -v -s "$MACOS_CERTIFICATE_IDENTITY" "$APP"
+ security default-keychain -s "login.keychain"
+ security delete-keychain "${KEYCHAIN}"
+fi
# Create the dmg bundle
-mkdir -p $DMGDIR
-ln -sf /Applications $DMGDIR/Applications
-cp -r $APP $DMGDIR
+mkdir -p "$DMGDIR"
+ln -sf /Applications "$DMGDIR/Applications"
+cp -r "$APP" "$DMGDIR"
mkdir -p _build
# Temporary countermeasure to hdiutil error 5341
# head -c9703424 /dev/urandom > $DMGDIR/.padding
-hdiutil create -imagekey zlib-level=9 -volname coq-$VERSION-installer-macos -srcfolder $DMGDIR -ov -format UDZO _build/coq-$VERSION-installer-macos.dmg
+hdiutil create -imagekey zlib-level=9 -volname "coq-$VERSION-installer-macos" -srcfolder "$DMGDIR" -ov -format UDZO "_build/coq-$VERSION-installer-macos.dmg"
diff --git a/dev/build/windows/MakeCoq_MinGW.bat b/dev/build/windows/MakeCoq_MinGW.bat
index 61cf6bc4..8489bcfc 100755
--- a/dev/build/windows/MakeCoq_MinGW.bat
+++ b/dev/build/windows/MakeCoq_MinGW.bat
@@ -1,488 +1,488 @@
-@ECHO OFF
-
-REM ========== COPYRIGHT/COPYLEFT ==========
-
-REM (C) 2016 Intel Deutschland GmbH
-REM Author: Michael Soegtrop
-
-REM Released to the public by Intel under the
-REM GNU Lesser General Public License Version 2.1 or later
-REM See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
-
-REM ========== NOTES ==========
-
-REM For Cygwin setup command line options
-REM see https://cygwin.com/faq/faq.html#faq.setup.cli
-
-REM ========== DEFAULT VALUES FOR PARAMETERS ==========
-
-REM For a description of all parameters, see ReadMe.txt
-
-SET BATCHFILE=%~0
-SET BATCHDIR=%~dp0
-
-REM see -arch in ReadMe.txt, but values are x86_64 or i686 (not 64 or 32)
-SET ARCH=x86_64
-
-REM see -mode in ReadMe.txt
-SET INSTALLMODE=absolute
-
-REM see -installer in ReadMe.txt
-SET MAKEINSTALLER=N
-
-REM see -ocaml in ReadMe.txt
-SET INSTALLOCAML=N
-
-REM see -make in ReadMe.txt
-SET INSTALLMAKE=N
-
-REM see -destcyg in ReadMe.txt
-SET DESTCYG=C:\bin\cygwin_coq
-
-REM see -destcoq in ReadMe.txt
-SET DESTCOQ=C:\bin\coq
-
-REM see -setup in ReadMe.txt
-SET SETUP=setup-x86_64.exe
-
-REM see -proxy in ReadMe.txt
-IF DEFINED HTTP_PROXY (
- SET PROXY=%HTTP_PROXY:http://=%
-) else (
- REM One can't set a variable to empty in DOS, but you can set it to a space this way.
- REM The quotes are just there to make the space visible and to protect from "remove trailing spaces".
- SET "PROXY= "
-)
-
-REM see -cygrepo in ReadMe.txt
-SET CYGWIN_REPOSITORY=http://ftp.inf.tu-dresden.de/software/windows/cygwin32
-
-REM see -cygcache in ReadMe.txt
-SET CYGWIN_LOCAL_CACHE_WFMT=%BATCHDIR%cygwin_cache
-
-REM see -cyglocal in ReadMe.txt
-SET CYGWIN_FROM_CACHE=N
-
-REM see -cygquiet in ReadMe.txt
-SET CYGWIN_QUIET=Y
-
-REM see -srccache in ReadMe.txt
-SET SOURCE_LOCAL_CACHE_WFMT=%BATCHDIR%source_cache
-
-REM see -coqver in ReadMe.txt
-SET COQ_VERSION=8.5pl3
-
-REM see -gtksrc in ReadMe.txt
-SET GTK_FROM_SOURCES=N
-
-REM see -threads in ReadMe.txt
-SET MAKE_THREADS=8
-
-REM see -addon in ReadMe.txt
-SET "COQ_ADDONS= "
-
-REM ========== PARSE COMMAND LINE PARAMETERS ==========
-
-SHIFT
-
-:Parse
-
-IF "%~0" == "-arch" (
- IF "%~1" == "32" (
- SET ARCH=i686
- SET SETUP=setup-x86.exe
- ) ELSE (
- IF "%~1" == "64" (
- SET ARCH=x86_64
- SET SETUP=setup-x86_64.exe
- ) ELSE (
- ECHO "Invalid -arch, valid are 32 and 64"
- GOTO :EOF
- )
- )
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-mode" (
- IF "%~1" == "mingwincygwin" (
- SET INSTALLMODE=%~1
- ) ELSE (
- IF "%~1" == "absolute" (
- SET INSTALLMODE=%~1
- ) ELSE (
- IF "%~1" == "relocatable" (
- SET INSTALLMODE=%~1
- ) ELSE (
- ECHO "Invalid -mode, valid are mingwincygwin, absolute and relocatable"
- GOTO :EOF
- )
- )
- )
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-installer" (
- SET MAKEINSTALLER=%~1
- CALL :CheckYN -installer %~1 || GOTO ErrorExit
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-ocaml" (
- SET INSTALLOCAML=%~1
- CALL :CheckYN -installer %~1 || GOTO ErrorExit
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-make" (
- SET INSTALLMAKE=%~1
- CALL :CheckYN -installer %~1 || GOTO ErrorExit
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-destcyg" (
- SET DESTCYG=%~1
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-destcoq" (
- SET DESTCOQ=%~1
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-setup" (
- SET SETUP=%~1
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-proxy" (
- SET PROXY=%~1
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-cygrepo" (
- SET CYGWIN_REPOSITORY=%~1
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-cygcache" (
- SET CYGWIN_LOCAL_CACHE_WFMT=%~1
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-cyglocal" (
- SET CYGWIN_FROM_CACHE=%~1
- CALL :CheckYN -cyglocal %~1 || GOTO ErrorExit
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-cygquiet" (
- SET CYGWIN_QUIET=%~1
- CALL :CheckYN -cygquiet %~1 || GOTO ErrorExit
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-srccache" (
- SET SOURCE_LOCAL_CACHE_WFMT=%~1
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-coqver" (
- SET COQ_VERSION=%~1
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-gtksrc" (
- SET GTK_FROM_SOURCES=%~1
- CALL :CheckYN -gtksrc %~1 || GOTO ErrorExit
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-threads" (
- SET MAKE_THREADS=%~1
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-IF "%~0" == "-addon" (
- SET "COQ_ADDONS=%COQ_ADDONS% %~1"
- SHIFT
- SHIFT
- GOTO Parse
-)
-
-
-IF NOT "%~0" == "" (
- ECHO Install cygwin and download, compile and install OCaml and Coq for MinGW
- ECHO !!! Illegal parameter %~0
- ECHO Usage:
- ECHO MakeCoq_MinGW
- CALL :PrintPars
- GOTO :EOF
-)
-
-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
-)
-
-REM ========== ADJUST PARAMETERS ==========
-
-IF "%INSTALLMODE%" == "mingwincygwin" (
- SET DESTCOQ=%DESTCYG%\usr\%ARCH%-w64-mingw32\sys-root\mingw
-)
-
-IF "%MAKEINSTALLER%" == "Y" (
- SET INSTALLMODE=relocatable
-)
-
-REM ========== CONFIRM PARAMETERS ==========
-
-CALL :PrintPars
-REM Note: DOS batch replaces variables on parsing, so one can't use a variable just set in an () block
-IF "%COQREGTESTING%"=="Y" (GOTO DontAsk)
- SET /p ANSWER="Is this correct? y/n "
- IF NOT "%ANSWER%"=="y" (GOTO :EOF)
-:DontAsk
-
-REM ========== DERIVED VARIABLES ==========
-
-SET CYGWIN_INSTALLDIR_WFMT=%DESTCYG%
-SET RESULT_INSTALLDIR_WFMT=%DESTCOQ%
-SET TARGET_ARCH=%ARCH%-w64-mingw32
-SET BASH=%CYGWIN_INSTALLDIR_WFMT%\bin\bash
-
-REM Convert pathes to various formats
-REM WFMT = windows format (C:\..) Used in this batch file.
-REM CFMT = cygwin format (\cygdrive\c\..) Used for Cygwin PATH varible, which is : separated, so C: doesn't work.
-REM MFMT = MinGW format (C:/...) Used for the build, because \\ requires escaping. Mingw can handle \ and /.
-
-SET CYGWIN_INSTALLDIR_MFMT=%CYGWIN_INSTALLDIR_WFMT:\=/%
-SET RESULT_INSTALLDIR_MFMT=%RESULT_INSTALLDIR_WFMT:\=/%
-SET SOURCE_LOCAL_CACHE_MFMT=%SOURCE_LOCAL_CACHE_WFMT:\=/%
-
-SET CYGWIN_INSTALLDIR_CFMT=%CYGWIN_INSTALLDIR_MFMT:C:/=/cygdrive/c/%
-SET RESULT_INSTALLDIR_CFMT=%RESULT_INSTALLDIR_MFMT:C:/=/cygdrive/c/%
-SET SOURCE_LOCAL_CACHE_CFMT=%SOURCE_LOCAL_CACHE_MFMT:C:/=/cygdrive/c/%
-
-SET CYGWIN_INSTALLDIR_CFMT=%CYGWIN_INSTALLDIR_CFMT:D:/=/cygdrive/d/%
-SET RESULT_INSTALLDIR_CFMT=%RESULT_INSTALLDIR_CFMT:D:/=/cygdrive/d/%
-SET SOURCE_LOCAL_CACHE_CFMT=%SOURCE_LOCAL_CACHE_CFMT:D:/=/cygdrive/d/%
-
-SET CYGWIN_INSTALLDIR_CFMT=%CYGWIN_INSTALLDIR_CFMT:E:/=/cygdrive/e/%
-SET RESULT_INSTALLDIR_CFMT=%RESULT_INSTALLDIR_CFMT:E:/=/cygdrive/e/%
-SET SOURCE_LOCAL_CACHE_CFMT=%SOURCE_LOCAL_CACHE_CFMT:E:/=/cygdrive/e/%
-
-ECHO CYGWIN INSTALL DIR (WIN) = %CYGWIN_INSTALLDIR_WFMT%
-ECHO CYGWIN INSTALL DIR (MINGW) = %CYGWIN_INSTALLDIR_MFMT%
-ECHO CYGWIN INSTALL DIR (CYGWIN) = %CYGWIN_INSTALLDIR_CFMT%
-ECHO RESULT INSTALL DIR (WIN) = %RESULT_INSTALLDIR_WFMT%
-ECHO RESULT INSTALL DIR (MINGW) = %RESULT_INSTALLDIR_MFMT%
-ECHO RESULT INSTALL DIR (CYGWIN) = %RESULT_INSTALLDIR_CFMT%
-
-REM WARNING: Add a space after the = in case you want set this to empty, otherwise the variable will be unset
-SET MAKE_OPT=-j %MAKE_THREADS%
-
-REM ========== DERIVED CYGWIN SETUP OPTIONS ==========
-
-REM One can't set a variable to empty in DOS, but you can set it to a space this way.
-REM The quotes are just there to make the space visible and to protect from "remove trailing spaces".
-SET "CYGWIN_OPT= "
-
-IF "%CYGWIN_FROM_CACHE%" == "Y" (
- SET CYGWIN_OPT= %CYGWIN_OPT% -L
-)
-
-IF "%CYGWIN_QUIET%" == "Y" (
- SET CYGWIN_OPT= %CYGWIN_OPT% -q --no-admin
-)
-
-IF "%GTK_FROM_SOURCES%"=="N" (
- SET CYGWIN_OPT= %CYGWIN_OPT% -P mingw64-%ARCH%-gtk2.0,mingw64-%ARCH%-gtksourceview2.0
-)
-
-REM Cygwin setup sets proper ACLs (permissions) for folders it CREATES.
-REM Otherwise chmod won't work and e.g. the ocaml build will fail.
-REM Cygwin setup does not touch the ACLs of existing folders.
-
-REM Run Cygwin Setup
-
-SET RUNSETUP=Y
-IF EXIST "%CYGWIN_INSTALLDIR_WFMT%\etc\setup\installed.db" (
- SET RUNSETUP=N
-)
-IF NOT "%CYGWIN_QUIET%" == "Y" (
- SET RUNSETUP=Y
-)
-
-IF "%COQREGTESTING%" == "Y" (
- ECHO "========== REMOVE EXISTING CYGWIN =========="
- DEL /S /F /Q "%CYGWIN_INSTALLDIR_WFMT%" > NUL
- SET RUNSETUP=Y
-)
-
-SET "EXTRAPACKAGES= "
-
-IF NOT "%APPVEYOR%" == "True" (
- SET EXTRAPACKAGES=-P wget,curl,git,gcc-core,gcc-g++,automake1.5
-)
-
-ECHO "========== INSTALL CYGWIN =========="
-
-IF "%RUNSETUP%"=="Y" (
- %SETUP% ^
- --proxy "%PROXY%" ^
- --site "%CYGWIN_REPOSITORY%" ^
- --root "%CYGWIN_INSTALLDIR_WFMT%" ^
- --local-package-dir "%CYGWIN_LOCAL_CACHE_WFMT%" ^
- --no-shortcuts ^
- %CYGWIN_OPT% ^
- -P make,unzip ^
- -P gdb,liblzma5 ^
- -P patch,automake1.14 ^
- -P mingw64-%ARCH%-binutils,mingw64-%ARCH%-gcc-core,mingw64-%ARCH%-gcc-g++,mingw64-%ARCH%-pkg-config,mingw64-%ARCH%-windows_default_manifest ^
- -P mingw64-%ARCH%-headers,mingw64-%ARCH%-runtime,mingw64-%ARCH%-pthreads,mingw64-%ARCH%-zlib ^
- -P libiconv-devel,libunistring-devel,libncurses-devel ^
- -P gettext-devel,libgettextpo-devel ^
- -P libglib2.0-devel,libgdk_pixbuf2.0-devel ^
- -P libfontconfig1 ^
- -P gtk-update-icon-cache ^
- -P libtool,automake ^
- -P intltool ^
- %EXTRAPACKAGES% ^
- || GOTO ErrorExit
-
- MKDIR "%CYGWIN_INSTALLDIR_WFMT%\build"
- 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.
- :waitsetup
- tasklist /fi "imagename eq %SETUP%" | find ":" > NUL
- IF ERRORLEVEL 1 GOTO waitsetup
-)
-
-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
-
-ECHO ========== BUILD COQ ==========
-
-MKDIR "%CYGWIN_INSTALLDIR_WFMT%\build"
-MKDIR "%CYGWIN_INSTALLDIR_WFMT%\build\patches"
-
-COPY "%BATCHDIR%\makecoq_mingw.sh" "%CYGWIN_INSTALLDIR_WFMT%\build" || GOTO ErrorExit
-COPY "%BATCHDIR%\patches_coq\*.*" "%CYGWIN_INSTALLDIR_WFMT%\build\patches" || GOTO ErrorExit
-
-%BASH% --login "%CYGWIN_INSTALLDIR_CFMT%\build\makecoq_mingw.sh" || GOTO ErrorExit
-
-ECHO ========== FINISHED ==========
-
-GOTO :EOF
-
-ECHO ========== BATCH FUNCTIONS ==========
-
-:PrintPars
- REM 01234567890123456789012345678901234567890123456789012345678901234567890123456789
- ECHO -arch ^ Set cygwin, ocaml and coq to 32 or 64 bit
- ECHO -mode ^
- ECHO ^
- ECHO ^
- ECHO -installer^ create a windows installer (will be in /build/coq/dev/nsis)
- ECHO -ocaml ^ install OCaml in Coq folder (Y) or just in cygwin folder (N)
- ECHO -make ^ install GNU Make in Coq folder (Y) or not (N)
- ECHO -destcyg ^
- ECHO -destcoq ^
- ECHO -setup ^ (auto adjusted to -arch)
- ECHO -proxy ^
- ECHO -cygrepo ^
- ECHO -cygcache ^
- ECHO -cyglocal ^ install cygwin from cache
- ECHO -cygquiet ^ install cygwin without user interaction
- ECHO -srccache ^
- ECHO -coqver ^
- ECHO -gtksrc ^ build GTK ^(90 min^) or use cygwin version
- ECHO -threads ^<1..N^> Number of make threads
- ECHO -addon ^ Enable building selected addon (can be repeated)
- ECHO(
- ECHO See ReadMe.txt for a detailed description of all parameters
- ECHO(
- ECHO Parameter values (default or currently set):
- ECHO -arch = %ARCH%
- ECHO -mode = %INSTALLMODE%
- ECHO -ocaml = %INSTALLOCAML%
- ECHO -installer= %MAKEINSTALLER%
- ECHO -make = %INSTALLMAKE%
- ECHO -destcyg = %DESTCYG%
- ECHO -destcoq = %DESTCOQ%
- ECHO -setup = %SETUP%
- ECHO -proxy = %PROXY%
- ECHO -cygrepo = %CYGWIN_REPOSITORY%
- ECHO -cygcache = %CYGWIN_LOCAL_CACHE_WFMT%
- ECHO -cyglocal = %CYGWIN_FROM_CACHE%
- ECHO -cygquiet = %CYGWIN_QUIET%
- ECHO -srccache = %SOURCE_LOCAL_CACHE_WFMT%
- ECHO -coqver = %COQ_VERSION%
- ECHO -gtksrc = %GTK_FROM_SOURCES%
- ECHO -threads = %MAKE_THREADS%
- ECHO -addon = %COQ_ADDONS%
- GOTO :EOF
-
-:CheckYN
- REM Reset errorlevel to 0
- CMD /c "EXIT /b 0"
- IF "%2" == "Y" (
- REM OK Y
- ) ELSE IF "%2" == "N" (
- REM OK N
- ) ELSE (
- ECHO ERROR Parameter %1 must be Y or N, but is %2
- GOTO ErrorExit
- )
- GOTO :EOF
-
-:ErrorExit
- ECHO ERROR MakeCoq_MinGW.bat failed
- EXIT /b 1
+@ECHO OFF
+
+REM ========== COPYRIGHT/COPYLEFT ==========
+
+REM (C) 2016 Intel Deutschland GmbH
+REM Author: Michael Soegtrop
+
+REM Released to the public by Intel under the
+REM GNU Lesser General Public License Version 2.1 or later
+REM See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+
+REM ========== NOTES ==========
+
+REM For Cygwin setup command line options
+REM see https://cygwin.com/faq/faq.html#faq.setup.cli
+
+REM ========== DEFAULT VALUES FOR PARAMETERS ==========
+
+REM For a description of all parameters, see ReadMe.txt
+
+SET BATCHFILE=%~0
+SET BATCHDIR=%~dp0
+
+REM see -arch in ReadMe.txt, but values are x86_64 or i686 (not 64 or 32)
+SET ARCH=x86_64
+
+REM see -mode in ReadMe.txt
+SET INSTALLMODE=absolute
+
+REM see -installer in ReadMe.txt
+SET MAKEINSTALLER=N
+
+REM see -ocaml in ReadMe.txt
+SET INSTALLOCAML=N
+
+REM see -make in ReadMe.txt
+SET INSTALLMAKE=N
+
+REM see -destcyg in ReadMe.txt
+SET DESTCYG=C:\bin\cygwin_coq
+
+REM see -destcoq in ReadMe.txt
+SET DESTCOQ=C:\bin\coq
+
+REM see -setup in ReadMe.txt
+SET SETUP=setup-x86_64.exe
+
+REM see -proxy in ReadMe.txt
+IF DEFINED HTTP_PROXY (
+ SET PROXY=%HTTP_PROXY:http://=%
+) else (
+ REM One can't set a variable to empty in DOS, but you can set it to a space this way.
+ REM The quotes are just there to make the space visible and to protect from "remove trailing spaces".
+ SET "PROXY= "
+)
+
+REM see -cygrepo in ReadMe.txt
+SET CYGWIN_REPOSITORY=http://mirror.easyname.at/cygwin
+
+REM see -cygcache in ReadMe.txt
+SET CYGWIN_LOCAL_CACHE_WFMT=%BATCHDIR%cygwin_cache
+
+REM see -cyglocal in ReadMe.txt
+SET CYGWIN_FROM_CACHE=N
+
+REM see -cygquiet in ReadMe.txt
+SET CYGWIN_QUIET=Y
+
+REM see -srccache in ReadMe.txt
+SET SOURCE_LOCAL_CACHE_WFMT=%BATCHDIR%source_cache
+
+REM see -coqver in ReadMe.txt
+SET COQ_VERSION=8.5pl3
+
+REM see -gtksrc in ReadMe.txt
+SET GTK_FROM_SOURCES=N
+
+REM see -threads in ReadMe.txt
+SET MAKE_THREADS=8
+
+REM see -addon in ReadMe.txt
+SET "COQ_ADDONS= "
+
+REM ========== PARSE COMMAND LINE PARAMETERS ==========
+
+SHIFT
+
+:Parse
+
+IF "%~0" == "-arch" (
+ IF "%~1" == "32" (
+ SET ARCH=i686
+ SET SETUP=setup-x86.exe
+ ) ELSE (
+ IF "%~1" == "64" (
+ SET ARCH=x86_64
+ SET SETUP=setup-x86_64.exe
+ ) ELSE (
+ ECHO "Invalid -arch, valid are 32 and 64"
+ GOTO :EOF
+ )
+ )
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-mode" (
+ IF "%~1" == "mingwincygwin" (
+ SET INSTALLMODE=%~1
+ ) ELSE (
+ IF "%~1" == "absolute" (
+ SET INSTALLMODE=%~1
+ ) ELSE (
+ IF "%~1" == "relocatable" (
+ SET INSTALLMODE=%~1
+ ) ELSE (
+ ECHO "Invalid -mode, valid are mingwincygwin, absolute and relocatable"
+ GOTO :EOF
+ )
+ )
+ )
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-installer" (
+ SET MAKEINSTALLER=%~1
+ CALL :CheckYN -installer %~1 || GOTO ErrorExit
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-ocaml" (
+ SET INSTALLOCAML=%~1
+ CALL :CheckYN -installer %~1 || GOTO ErrorExit
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-make" (
+ SET INSTALLMAKE=%~1
+ CALL :CheckYN -installer %~1 || GOTO ErrorExit
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-destcyg" (
+ SET DESTCYG=%~1
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-destcoq" (
+ SET DESTCOQ=%~1
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-setup" (
+ SET SETUP=%~1
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-proxy" (
+ SET PROXY=%~1
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-cygrepo" (
+ SET CYGWIN_REPOSITORY=%~1
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-cygcache" (
+ SET CYGWIN_LOCAL_CACHE_WFMT=%~1
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-cyglocal" (
+ SET CYGWIN_FROM_CACHE=%~1
+ CALL :CheckYN -cyglocal %~1 || GOTO ErrorExit
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-cygquiet" (
+ SET CYGWIN_QUIET=%~1
+ CALL :CheckYN -cygquiet %~1 || GOTO ErrorExit
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-srccache" (
+ SET SOURCE_LOCAL_CACHE_WFMT=%~1
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-coqver" (
+ SET COQ_VERSION=%~1
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-gtksrc" (
+ SET GTK_FROM_SOURCES=%~1
+ CALL :CheckYN -gtksrc %~1 || GOTO ErrorExit
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-threads" (
+ SET MAKE_THREADS=%~1
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+IF "%~0" == "-addon" (
+ SET "COQ_ADDONS=%COQ_ADDONS% %~1"
+ SHIFT
+ SHIFT
+ GOTO Parse
+)
+
+
+IF NOT "%~0" == "" (
+ ECHO Install cygwin and download, compile and install OCaml and Coq for MinGW
+ ECHO !!! Illegal parameter %~0
+ ECHO Usage:
+ ECHO MakeCoq_MinGW
+ CALL :PrintPars
+ GOTO :EOF
+)
+
+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
+)
+
+REM ========== ADJUST PARAMETERS ==========
+
+IF "%INSTALLMODE%" == "mingwincygwin" (
+ SET DESTCOQ=%DESTCYG%\usr\%ARCH%-w64-mingw32\sys-root\mingw
+)
+
+IF "%MAKEINSTALLER%" == "Y" (
+ SET INSTALLMODE=relocatable
+)
+
+REM ========== CONFIRM PARAMETERS ==========
+
+CALL :PrintPars
+REM Note: DOS batch replaces variables on parsing, so one can't use a variable just set in an () block
+IF "%COQREGTESTING%"=="Y" (GOTO DontAsk)
+ SET /p ANSWER="Is this correct? y/n "
+ IF NOT "%ANSWER%"=="y" (GOTO :EOF)
+:DontAsk
+
+REM ========== DERIVED VARIABLES ==========
+
+SET CYGWIN_INSTALLDIR_WFMT=%DESTCYG%
+SET RESULT_INSTALLDIR_WFMT=%DESTCOQ%
+SET TARGET_ARCH=%ARCH%-w64-mingw32
+SET BASH=%CYGWIN_INSTALLDIR_WFMT%\bin\bash
+
+REM Convert pathes to various formats
+REM WFMT = windows format (C:\..) Used in this batch file.
+REM CFMT = cygwin format (\cygdrive\c\..) Used for Cygwin PATH varible, which is : separated, so C: doesn't work.
+REM MFMT = MinGW format (C:/...) Used for the build, because \\ requires escaping. Mingw can handle \ and /.
+
+SET CYGWIN_INSTALLDIR_MFMT=%CYGWIN_INSTALLDIR_WFMT:\=/%
+SET RESULT_INSTALLDIR_MFMT=%RESULT_INSTALLDIR_WFMT:\=/%
+SET SOURCE_LOCAL_CACHE_MFMT=%SOURCE_LOCAL_CACHE_WFMT:\=/%
+
+SET CYGWIN_INSTALLDIR_CFMT=%CYGWIN_INSTALLDIR_MFMT:C:/=/cygdrive/c/%
+SET RESULT_INSTALLDIR_CFMT=%RESULT_INSTALLDIR_MFMT:C:/=/cygdrive/c/%
+SET SOURCE_LOCAL_CACHE_CFMT=%SOURCE_LOCAL_CACHE_MFMT:C:/=/cygdrive/c/%
+
+SET CYGWIN_INSTALLDIR_CFMT=%CYGWIN_INSTALLDIR_CFMT:D:/=/cygdrive/d/%
+SET RESULT_INSTALLDIR_CFMT=%RESULT_INSTALLDIR_CFMT:D:/=/cygdrive/d/%
+SET SOURCE_LOCAL_CACHE_CFMT=%SOURCE_LOCAL_CACHE_CFMT:D:/=/cygdrive/d/%
+
+SET CYGWIN_INSTALLDIR_CFMT=%CYGWIN_INSTALLDIR_CFMT:E:/=/cygdrive/e/%
+SET RESULT_INSTALLDIR_CFMT=%RESULT_INSTALLDIR_CFMT:E:/=/cygdrive/e/%
+SET SOURCE_LOCAL_CACHE_CFMT=%SOURCE_LOCAL_CACHE_CFMT:E:/=/cygdrive/e/%
+
+ECHO CYGWIN INSTALL DIR (WIN) = %CYGWIN_INSTALLDIR_WFMT%
+ECHO CYGWIN INSTALL DIR (MINGW) = %CYGWIN_INSTALLDIR_MFMT%
+ECHO CYGWIN INSTALL DIR (CYGWIN) = %CYGWIN_INSTALLDIR_CFMT%
+ECHO RESULT INSTALL DIR (WIN) = %RESULT_INSTALLDIR_WFMT%
+ECHO RESULT INSTALL DIR (MINGW) = %RESULT_INSTALLDIR_MFMT%
+ECHO RESULT INSTALL DIR (CYGWIN) = %RESULT_INSTALLDIR_CFMT%
+
+REM WARNING: Add a space after the = in case you want set this to empty, otherwise the variable will be unset
+SET MAKE_OPT=-j %MAKE_THREADS%
+
+REM ========== DERIVED CYGWIN SETUP OPTIONS ==========
+
+REM One can't set a variable to empty in DOS, but you can set it to a space this way.
+REM The quotes are just there to make the space visible and to protect from "remove trailing spaces".
+SET "CYGWIN_OPT= "
+
+IF "%CYGWIN_FROM_CACHE%" == "Y" (
+ SET CYGWIN_OPT= %CYGWIN_OPT% -L
+)
+
+IF "%CYGWIN_QUIET%" == "Y" (
+ SET CYGWIN_OPT= %CYGWIN_OPT% -q --no-admin
+)
+
+IF "%GTK_FROM_SOURCES%"=="N" (
+ SET CYGWIN_OPT= %CYGWIN_OPT% -P mingw64-%ARCH%-gtk2.0,mingw64-%ARCH%-gtksourceview2.0
+)
+
+REM Cygwin setup sets proper ACLs (permissions) for folders it CREATES.
+REM Otherwise chmod won't work and e.g. the ocaml build will fail.
+REM Cygwin setup does not touch the ACLs of existing folders.
+
+REM Run Cygwin Setup
+
+SET RUNSETUP=Y
+IF EXIST "%CYGWIN_INSTALLDIR_WFMT%\etc\setup\installed.db" (
+ SET RUNSETUP=N
+)
+IF NOT "%CYGWIN_QUIET%" == "Y" (
+ SET RUNSETUP=Y
+)
+
+IF "%COQREGTESTING%" == "Y" (
+ ECHO "========== REMOVE EXISTING CYGWIN =========="
+ DEL /S /F /Q "%CYGWIN_INSTALLDIR_WFMT%" > NUL
+ SET RUNSETUP=Y
+)
+
+SET "EXTRAPACKAGES= "
+
+IF NOT "%APPVEYOR%" == "True" (
+ SET EXTRAPACKAGES=-P wget,curl,git,gcc-core,gcc-g++,automake1.5
+)
+
+ECHO "========== INSTALL CYGWIN =========="
+
+IF "%RUNSETUP%"=="Y" (
+ %SETUP% ^
+ --proxy "%PROXY%" ^
+ --site "%CYGWIN_REPOSITORY%" ^
+ --root "%CYGWIN_INSTALLDIR_WFMT%" ^
+ --local-package-dir "%CYGWIN_LOCAL_CACHE_WFMT%" ^
+ --no-shortcuts ^
+ %CYGWIN_OPT% ^
+ -P make,unzip ^
+ -P gdb,liblzma5 ^
+ -P patch,automake1.14 ^
+ -P mingw64-%ARCH%-binutils,mingw64-%ARCH%-gcc-core,mingw64-%ARCH%-gcc-g++,mingw64-%ARCH%-pkg-config,mingw64-%ARCH%-windows_default_manifest ^
+ -P mingw64-%ARCH%-headers,mingw64-%ARCH%-runtime,mingw64-%ARCH%-pthreads,mingw64-%ARCH%-zlib ^
+ -P libiconv-devel,libunistring-devel,libncurses-devel ^
+ -P gettext-devel,libgettextpo-devel ^
+ -P libglib2.0-devel,libgdk_pixbuf2.0-devel ^
+ -P libfontconfig1 ^
+ -P gtk-update-icon-cache ^
+ -P libtool,automake ^
+ -P intltool ^
+ %EXTRAPACKAGES% ^
+ || GOTO ErrorExit
+
+ MKDIR "%CYGWIN_INSTALLDIR_WFMT%\build"
+ 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.
+ :waitsetup
+ tasklist /fi "imagename eq %SETUP%" | find ":" > NUL
+ IF ERRORLEVEL 1 GOTO waitsetup
+)
+
+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
+
+ECHO ========== BUILD COQ ==========
+
+MKDIR "%CYGWIN_INSTALLDIR_WFMT%\build"
+MKDIR "%CYGWIN_INSTALLDIR_WFMT%\build\patches"
+
+COPY "%BATCHDIR%\makecoq_mingw.sh" "%CYGWIN_INSTALLDIR_WFMT%\build" || GOTO ErrorExit
+COPY "%BATCHDIR%\patches_coq\*.*" "%CYGWIN_INSTALLDIR_WFMT%\build\patches" || GOTO ErrorExit
+
+%BASH% --login "%CYGWIN_INSTALLDIR_CFMT%\build\makecoq_mingw.sh" || GOTO ErrorExit
+
+ECHO ========== FINISHED ==========
+
+GOTO :EOF
+
+ECHO ========== BATCH FUNCTIONS ==========
+
+:PrintPars
+ REM 01234567890123456789012345678901234567890123456789012345678901234567890123456789
+ ECHO -arch ^ Set cygwin, ocaml and coq to 32 or 64 bit
+ ECHO -mode ^
+ ECHO ^
+ ECHO ^
+ ECHO -installer^ create a windows installer (will be in /build/coq/dev/nsis)
+ ECHO -ocaml ^ install OCaml in Coq folder (Y) or just in cygwin folder (N)
+ ECHO -make ^ install GNU Make in Coq folder (Y) or not (N)
+ ECHO -destcyg ^
+ ECHO -destcoq ^
+ ECHO -setup ^ (auto adjusted to -arch)
+ ECHO -proxy ^
+ ECHO -cygrepo ^
+ ECHO -cygcache ^
+ ECHO -cyglocal ^ install cygwin from cache
+ ECHO -cygquiet ^ install cygwin without user interaction
+ ECHO -srccache ^
+ ECHO -coqver ^
+ ECHO -gtksrc ^ build GTK ^(90 min^) or use cygwin version
+ ECHO -threads ^<1..N^> Number of make threads
+ ECHO -addon ^ Enable building selected addon (can be repeated)
+ ECHO(
+ ECHO See ReadMe.txt for a detailed description of all parameters
+ ECHO(
+ ECHO Parameter values (default or currently set):
+ ECHO -arch = %ARCH%
+ ECHO -mode = %INSTALLMODE%
+ ECHO -ocaml = %INSTALLOCAML%
+ ECHO -installer= %MAKEINSTALLER%
+ ECHO -make = %INSTALLMAKE%
+ ECHO -destcyg = %DESTCYG%
+ ECHO -destcoq = %DESTCOQ%
+ ECHO -setup = %SETUP%
+ ECHO -proxy = %PROXY%
+ ECHO -cygrepo = %CYGWIN_REPOSITORY%
+ ECHO -cygcache = %CYGWIN_LOCAL_CACHE_WFMT%
+ ECHO -cyglocal = %CYGWIN_FROM_CACHE%
+ ECHO -cygquiet = %CYGWIN_QUIET%
+ ECHO -srccache = %SOURCE_LOCAL_CACHE_WFMT%
+ ECHO -coqver = %COQ_VERSION%
+ ECHO -gtksrc = %GTK_FROM_SOURCES%
+ ECHO -threads = %MAKE_THREADS%
+ ECHO -addon = %COQ_ADDONS%
+ GOTO :EOF
+
+:CheckYN
+ REM Reset errorlevel to 0
+ CMD /c "EXIT /b 0"
+ IF "%2" == "Y" (
+ REM OK Y
+ ) ELSE IF "%2" == "N" (
+ REM OK N
+ ) ELSE (
+ ECHO ERROR Parameter %1 must be Y or N, but is %2
+ GOTO ErrorExit
+ )
+ GOTO :EOF
+
+:ErrorExit
+ ECHO ERROR MakeCoq_MinGW.bat failed
+ EXIT /b 1
diff --git a/dev/build/windows/configure_profile.sh b/dev/build/windows/configure_profile.sh
index 16c972e8..7e606b55 100644
--- a/dev/build/windows/configure_profile.sh
+++ b/dev/build/windows/configure_profile.sh
@@ -14,30 +14,30 @@
rcfile=~/.bash_profile
donefile=~/.bash_profile.upated
+# to learn about `exec >> $file`, see https://www.tldp.org/LDP/abs/html/x17974.html
+exec >> $rcfile
+
if [ ! -f $donefile ] ; then
- echo >> $rcfile
-
- if [ "$1" != "" -a "$1" != " " ]; then
- echo export http_proxy="http://$1" >> $rcfile
- echo export https_proxy="http://$1" >> $rcfile
- echo export ftp_proxy="http://$1" >> $rcfile
+ if [ "$1" != "" ] && [ "$1" != " " ]; then
+ echo export http_proxy="http://$1"
+ echo export https_proxy="http://$1"
+ echo export ftp_proxy="http://$1"
fi
-
- mkdir -p $RESULT_INSTALLDIR_CFMT/bin
+
+ mkdir -p "$RESULT_INSTALLDIR_CFMT/bin"
# A tightly controlled path helps to avoid issues
# Note: the order is important: first have the cygwin binaries, then the mingw binaries in the path!
# Note: /bin is mounted at /usr/bin and /lib at /usr/lib and it is common to use /usr/bin in PATH
# See cat /proc/mounts
- echo "export PATH=/usr/local/bin:/usr/bin:$RESULT_INSTALLDIR_CFMT/bin:/usr/$TARGET_ARCH/sys-root/mingw/bin:/cygdrive/c/Windows/system32:/cygdrive/c/Windows" >> $rcfile
+ echo "export PATH=/usr/local/bin:/usr/bin:$RESULT_INSTALLDIR_CFMT/bin:/usr/$TARGET_ARCH/sys-root/mingw/bin:/cygdrive/c/Windows/system32:/cygdrive/c/Windows"
# find and xargs complain if the environment is larger than (I think) 8k.
# ORIGINAL_PATH (set by cygwin) can be a few k and exceed the limit
- echo unset ORIGINAL_PATH >> $rcfile
-
+ echo unset ORIGINAL_PATH
# Other installations of OCaml will mess up things
- echo unset OCAMLLIB >> $rcfile
+ echo unset OCAMLLIB
touch $donefile
fi
diff --git a/dev/build/windows/difftar-folder.sh b/dev/build/windows/difftar-folder.sh
index cbcf14ec..3bba451e 100644
--- a/dev/build/windows/difftar-folder.sh
+++ b/dev/build/windows/difftar-folder.sh
@@ -42,7 +42,7 @@ fi
if [ "$strip" -gt 0 ] ; then
# Get the path/name of the first file from teh tar and extract the first $strip path components
# This assumes that the first file in the tar file has at least $strip many path components
- prefix=$(tar -t -f $tarfile | head -1 | cut -d / -f -$strip)/
+ prefix=$(tar -t -f "$tarfile" | head -1 | cut -d / -f -$strip)/
else
prefix=
fi
@@ -60,13 +60,13 @@ mkdir -p "$empty"
# Print information (this is ignored by patch)
-echo diff/patch file created on $(date) with:
-echo difftar-folder.sh $@
-echo TARFILE= $tarfile
-echo FOLDER= $folder
-echo TARSTRIP= $strip
-echo TARPREFIX= $prefix
-echo ORIGFOLDER= $orig
+echo diff/patch file created on "$(date)" with:
+echo difftar-folder.sh "$@"
+echo TARFILE= "$tarfile"
+echo FOLDER= "$folder"
+echo TARSTRIP= "$strip"
+echo TARPREFIX= "$prefix"
+echo ORIGFOLDER= "$orig"
# Make sure tar uses english output (for Mod time differs)
export LC_ALL=C
@@ -76,14 +76,14 @@ tar --diff -a -f "$tarfile" --strip $strip --directory "$folder" | grep "Mod tim
# Substitute ': Mod time differs' with nothing
file=${file/: Mod time differs/}
# Check if file exists
- if [ -f "$folder/$file" ] ; then
+ if [ -f "$folder/$file" ] ; then
# Extract original file
tar -x -a -f "$tarfile" --strip $strip --directory "$orig" "$prefix$file"
# Compute diff
- diff -u "$orig/$file" "$folder/$file"
+ diff -u "$orig/$file" "$folder/$file"
fi
done
if [ -d "$new" ] ; then
- diff -u -r --unidirectional-new-file $empty $new
+ diff -u -r --unidirectional-new-file "$empty" "$new"
fi
diff --git a/dev/build/windows/makecoq_mingw.sh b/dev/build/windows/makecoq_mingw.sh
index 86cc5f2d..070af6b4 100755
--- a/dev/build/windows/makecoq_mingw.sh
+++ b/dev/build/windows/makecoq_mingw.sh
@@ -159,19 +159,19 @@ if [ "${COQREGTESTING:-N}" == "Y" ] ; then
# Log command output - take log target name from command name (like log1 make => log target is "-make")
log1() {
{ local -; set +x; } 2> /dev/null
- "$@" >"$LOGS/$LOGTARGET-$1.log" 2>"$LOGS/$LOGTARGET-$1.err"
+ "$@" >"$LOGS/$LOGTARGET-$1_log.txt" 2>"$LOGS/$LOGTARGET-$1_err.txt"
}
# Log command output - take log target name from command name and first argument (like log2 make install => log target is "-make-install")
log2() {
{ local -; set +x; } 2> /dev/null
- "$@" >"$LOGS/$LOGTARGET-$1-$2.log" 2>"$LOGS/$LOGTARGET-$1-$2.err"
+ "$@" >"$LOGS/$LOGTARGET-$1-$2_log.txt" 2>"$LOGS/$LOGTARGET-$1-$2_err.txt"
}
# Log command output - take log target name from command name and second argument (like log_1_3 ocaml setup.ml -configure => log target is "-ocaml--configure")
log_1_3() {
{ local -; set +x; } 2> /dev/null
- "$@" >"$LOGS/$LOGTARGET-$1-$3.log" 2>"$LOGS/$LOGTARGET-$1-$3.err"
+ "$@" >"$LOGS/$LOGTARGET-$1-$3_log.txt" 2>"$LOGS/$LOGTARGET-$1-$3_err.txt"
}
# Log command output - log target name is first argument (like logn untar tar xvaf ... => log target is "-untar")
@@ -179,26 +179,26 @@ if [ "${COQREGTESTING:-N}" == "Y" ] ; then
{ local -; set +x; } 2> /dev/null
LOGTARGETEX=$1
shift
- "$@" >"$LOGS/$LOGTARGET-$LOGTARGETEX.log" 2>"$LOGS/$LOGTARGET-$LOGTARGETEX.err"
+ "$@" >"$LOGS/$LOGTARGET-${LOGTARGETEX}_log.txt" 2>"$LOGS/$LOGTARGET-${LOGTARGETEX}_err.txt"
}
else
# If COQREGTESTING, log to log files and console
# Log command output - take log target name from command name (like log1 make => log target is "-make")
log1() {
{ local -; set +x; } 2> /dev/null
- "$@" > >(tee "$LOGS/$LOGTARGET-$1.log" | sed -e "s/^/$LOGTARGET-$1.log: /") 2> >(tee "$LOGS/$LOGTARGET-$1.err" | sed -e "s/^/$LOGTARGET-$1.err: /" 1>&2)
+ "$@" > >(tee "$LOGS/$LOGTARGET-$1_log.txt" | sed -e "s/^/$LOGTARGET-$1_log.txt: /") 2> >(tee "$LOGS/$LOGTARGET-$1_err.txt" | sed -e "s/^/$LOGTARGET-$1_err.txt: /" 1>&2)
}
# Log command output - take log target name from command name and first argument (like log2 make install => log target is "-make-install")
log2() {
{ local -; set +x; } 2> /dev/null
- "$@" > >(tee "$LOGS/$LOGTARGET-$1-$2.log" | sed -e "s/^/$LOGTARGET-$1-$2.log: /") 2> >(tee "$LOGS/$LOGTARGET-$1-$2.err" | sed -e "s/^/$LOGTARGET-$1-$2.err: /" 1>&2)
+ "$@" > >(tee "$LOGS/$LOGTARGET-$1-$2_log.txt" | sed -e "s/^/$LOGTARGET-$1-$2_log.txt: /") 2> >(tee "$LOGS/$LOGTARGET-$1-$2_err.txt" | sed -e "s/^/$LOGTARGET-$1-$2_err.txt: /" 1>&2)
}
# Log command output - take log target name from command name and second argument (like log_1_3 ocaml setup.ml -configure => log target is "-ocaml--configure")
log_1_3() {
{ local -; set +x; } 2> /dev/null
- "$@" > >(tee "$LOGS/$LOGTARGET-$1-$3.log" | sed -e "s/^/$LOGTARGET-$1-$3.log: /") 2> >(tee "$LOGS/$LOGTARGET-$1-$3.err" | sed -e "s/^/$LOGTARGET-$1-$3.err: /" 1>&2)
+ "$@" > >(tee "$LOGS/$LOGTARGET-$1-$3_log.txt" | sed -e "s/^/$LOGTARGET-$1-$3_log.txt: /") 2> >(tee "$LOGS/$LOGTARGET-$1-$3_err.txt" | sed -e "s/^/$LOGTARGET-$1-$3_err.txt: /" 1>&2)
}
# Log command output - log target name is first argument (like logn untar tar xvaf ... => log target is "-untar")
@@ -206,7 +206,7 @@ else
{ local -; set +x; } 2> /dev/null
LOGTARGETEX=$1
shift
- "$@" > >(tee "$LOGS/$LOGTARGET-$LOGTARGETEX.log" | sed -e "s/^/$LOGTARGET-$LOGTARGETEX.log: /") 2> >(tee "$LOGS/$LOGTARGET-$LOGTARGETEX.err" | sed -e "s/^/$LOGTARGET-$LOGTARGETEX.err: /" 1>&2)
+ "$@" > >(tee "$LOGS/$LOGTARGET-${LOGTARGETEX}_log.txt" | sed -e "s/^/$LOGTARGET-${LOGTARGETEX}_log.txt: /") 2> >(tee "$LOGS/$LOGTARGET-${LOGTARGETEX}_err.txt" | sed -e "s/^/$LOGTARGET-${LOGTARGETEX}_err.txt: /" 1>&2)
}
fi
@@ -238,9 +238,10 @@ fi
# $1 file server name including protocol prefix
# $2 file name (without extension)
# $3 file extension
-# $4 number of path levels to strip from tar (usually 1)
-# $5 module name (if different from archive)
-# $6 expand folder name (if different from module name)
+# $4 [optional] number of path levels to strip from tar (usually 1)
+# $5 [optional] module name (if different from archive)
+# $6 [optional] expand folder name (if different from module name)
+# $7 [optional] module base name (used as 2nd choice for patches, defaults to $5)
# ------------------------------------------------------------------------------
function get_expand_source_tar {
@@ -263,6 +264,12 @@ function get_expand_source_tar {
folder=$name
fi
+ if [ "$#" -ge 7 ] ; then
+ basename=$7
+ else
+ basename=$name
+ fi
+
# Set logging target
logtargetold=$LOGTARGET
LOGTARGET=$name
@@ -314,8 +321,11 @@ function get_expand_source_tar {
fi
# Patch if patch file exists
+ # First try specific patch file name then generic patch file name
if [ -f "$PATCHES/$name.patch" ] ; then
log1 patch -p1 -i "$PATCHES/$name.patch"
+ elif [ -f "$PATCHES/$basename.patch" ] ; then
+ log1 patch -p1 -i "$PATCHES/$basename.patch"
fi
# Go back to base folder
@@ -340,6 +350,7 @@ function get_expand_source_tar {
# $3 file extension
# $4 [optional] number of path levels to strip from tar (usually 1)
# $5 [optional] module name (if different from archive)
+# $6 [optional] module base name (used as 2nd choice for patches, defaults to $5)
# ------------------------------------------------------------------------------
function build_prep {
@@ -356,6 +367,12 @@ function build_prep {
name=$2
fi
+ if [ "$#" -ge 6 ] ; then
+ basename=$6
+ else
+ basename=$name
+ fi
+
# Set installer section to not set by default
installersection=
@@ -368,7 +385,7 @@ function build_prep {
touch "$FLAGFILES/$name.started"
- get_expand_source_tar "$1" "$2" "$3" "$strip" "$name"
+ get_expand_source_tar "$1" "$2" "$3" "$strip" "$name" "$name" "$basename"
cd "$name"
@@ -409,7 +426,7 @@ function build_prep_overlay {
# $1_CI_REF must have been a tag or hash, not a branch
ver="$ref"
fi
- build_prep "$url" "$ver" tar.gz 1 "$1-$ver"
+ build_prep "$url" "$ver" tar.gz 1 "$1-$ver" "$1"
}
# ------------------------------------------------------------------------------
@@ -666,6 +683,17 @@ function installer_addon_end {
fi
}
+# ------------------------------------------------------------------------------
+# Set all timeouts in all .v files to 1000
+# Since timeouts can lead to CI failures, this is useful
+#
+# parameters: none
+# ------------------------------------------------------------------------------
+
+function coq_set_timeouts_1000 {
+ find . -type f -name '*.v' -print0 | xargs -0 sed -i 's/timeout\s\+[0-9]\+/timeout 1000/g'
+}
+
###################### MODULE BUILD FUNCTIONS #####################
##### SED #####
@@ -1343,11 +1371,10 @@ 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
- install -D CHANGES "$PREFIXCOQ/license_readme/coq/Changes.txt"
+ # 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.md "$PREFIXCOQ/license_readme/coq/Changes.md"
install -D INSTALL "$PREFIXCOQ/license_readme/coq/Install.txt"
install -D doc/README.md "$PREFIXCOQ/license_readme/coq/ReadMeDoc.md" || true
fi
@@ -1620,7 +1647,7 @@ function make_addon_equations {
installer_addon_dependency equations
if build_prep_overlay Equations; then
installer_addon_section equations "Equations" "Coq plugin for defining functions by equations" ""
- # Note: PATH is autmatically saved/restored by build_prep / build_post
+ # Note: PATH is automatically saved/restored by build_prep / build_post
PATH=$COQBIN:$PATH
logn coq_makefile ${COQBIN}coq_makefile -f _CoqProject -o Makefile
log1 make
@@ -1668,7 +1695,7 @@ function make_addon_ssreflect {
function make_addon_ltac2 {
installer_addon_dependency ltac2
if build_prep_overlay ltac2; then
- installer_addon_section ltac2 "Ltac-2" "Coq plugin with the Ltac-2 enhanced tactics language" ""
+ installer_addon_section ltac2 "Ltac-2" "Coq plugin with the Ltac-2 enhanced tactic language" ""
log1 make all
log2 make install
build_post
@@ -1680,6 +1707,7 @@ function make_addon_ltac2 {
function make_addon_unicoq {
installer_addon_dependency unicoq
if build_prep_overlay unicoq; then
+ installer_addon_section unicoq "Unicoq" "Coq plugin for an enhanced unification algorithm" ""
log1 coq_makefile -f Make -o Makefile
log1 make
log2 make install
@@ -1694,6 +1722,7 @@ function make_addon_mtac2 {
make_addon_unicoq
installer_addon_dependency_end
if build_prep_overlay mtac2; then
+ installer_addon_section mtac2 "Mtac-2" "Coq plugin for a typed tactic language for Coq." ""
log1 coq_makefile -f _CoqProject -o Makefile
log1 make
log2 make install
@@ -1778,8 +1807,8 @@ function install_addon_vst {
install_glob "progs" '*.v' "$VSTDEST/progs/"
install_glob "progs" '*.c' "$VSTDEST/progs/"
install_glob "progs" '*.h' "$VSTDEST/progs/"
- install_glob "veric" '*.v' "$VSTDEST/msl/"
- install_glob "veric" '*.vo' "$VSTDEST/msl/"
+ install_glob "veric" '*.v' "$VSTDEST/veric/"
+ install_glob "veric" '*.vo' "$VSTDEST/veric/"
# Install VST documentation files
install_glob "." 'LICENSE' "$VSTDEST"
@@ -1792,11 +1821,20 @@ function install_addon_vst {
install_glob "." '_CoqProject-export' "$VSTDEST/progs"
}
+function vst_patch_compcert_refs {
+ find . -type f -name '*.v' -print0 | xargs -0 sed -E -i \
+ -e 's/(Require\s+(Import\s+|Export\s+)*)compcert\./\1VST.compcert./g' \
+ -e 's/From compcert Require/From VST.compcert Require/g'
+}
+
function make_addon_vst {
installer_addon_dependency vst
if build_prep_overlay VST; then
installer_addon_section vst "VST" "ATTENTION: SOME INCLUDED COMPCERT PARTS ARE NOT OPEN SOURCE! Verified Software Toolchain for verifying C code" "off"
- log1 make IGNORECOQVERSION=true $MAKE_OPT
+ # log1 coq_set_timeouts_1000
+ log1 vst_patch_compcert_refs
+ # The usage of the shell variable ARCH in VST collides with the usage in this shellscript
+ logn make env -u ARCH make IGNORECOQVERSION=true $MAKE_OPT
log1 install_addon_vst
build_post
fi
diff --git a/dev/build/windows/patches_coq/VST.patch b/dev/build/windows/patches_coq/VST.patch
new file mode 100755
index 00000000..2c8c4637
--- /dev/null
+++ b/dev/build/windows/patches_coq/VST.patch
@@ -0,0 +1,15 @@
+diff --git a/Makefile b/Makefile
+index 4a119042..fdfac13e 100755
+--- a/Makefile
++++ b/Makefile
+@@ -76,8 +76,8 @@ endif
+
+ COMPCERTDIRS=lib common $(ARCHDIRS) cfrontend flocq exportclight $(BACKEND)
+
+-COMPCERT_R_FLAGS= $(foreach d, $(COMPCERTDIRS), -R $(COMPCERT)/$(d) compcert.$(d))
+-EXTFLAGS= $(foreach d, $(COMPCERTDIRS), -Q $(COMPCERT)/$(d) compcert.$(d))
++COMPCERT_R_FLAGS= $(foreach d, $(COMPCERTDIRS), -R $(COMPCERT)/$(d) VST.compcert.$(d))
++EXTFLAGS= $(foreach d, $(COMPCERTDIRS), -Q $(COMPCERT)/$(d) VST.compcert.$(d))
+
+ # for SSReflect
+ ifdef MATHCOMP
diff --git a/dev/build/windows/patches_coq/aactactis-86ac28259030649ef51460e4de2441c8a1017751.patch b/dev/build/windows/patches_coq/aactactis-86ac28259030649ef51460e4de2441c8a1017751.patch
deleted file mode 100644
index d9b134b2..00000000
--- a/dev/build/windows/patches_coq/aactactis-86ac28259030649ef51460e4de2441c8a1017751.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- aac-tactics-v8.8.orig\Tutorial.v 2018-05-30 16:09:06.000000000 +0200
-+++ aac-tactics-v8.8\Tutorial.v 2018-08-24 19:47:25.000000000 +0200
-@@ -9,16 +9,14 @@
- (** * Tutorial for using the [aac_tactics] library.
-
- Depending on your installation, either modify the following two
- lines, or add them to your .coqrc files, replacing "." with the
- path to the [aac_tactics] library. *)
-
--Add Rec LoadPath "." as AAC_tactics.
--Add ML Path ".".
--Require Import AAC.
--Require Instances.
-+Require Import AAC_tactics.AAC.
-+Require AAC_tactics.Instances.
- Require Arith ZArith.
-
- (** ** Introductory example
-
- Here is a first example with relative numbers ([Z]): one can
- rewrite an universally quantified hypothesis modulo the
diff --git a/dev/build/windows/patches_coq/quickchick-v1.0.2.patch b/dev/build/windows/patches_coq/quickchick-v1.0.2.patch
deleted file mode 100644
index d03749ba..00000000
--- a/dev/build/windows/patches_coq/quickchick-v1.0.2.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-diff/patch file created on Mon, Aug 27, 2018 9:21:52 AM with:
-difftar-folder.sh tarballs/quickchick-v1.0.2.tar.gz quickchick-v1.0.2 1
-TARFILE= tarballs/quickchick-v1.0.2.tar.gz
-FOLDER= quickchick-v1.0.2
-TARSTRIP= 1
-TARPREFIX= QuickChick-1.0.2/
-ORIGFOLDER= quickchick-v1.0.2.orig
---- quickchick-v1.0.2.orig/Makefile 2018-08-22 18:21:39.000000000 +0200
-+++ quickchick-v1.0.2/Makefile 2018-08-27 09:21:04.710461100 +0200
-@@ -2,7 +2,7 @@
- .PHONY: plugin install install-plugin clean quickChickTool
-
- QCTOOL_DIR=quickChickTool
--QCTOOL_EXE=quickChickTool.byte
-+QCTOOL_EXE=quickChickTool.native
- QCTOOL_SRC=$(QCTOOL_DIR)/quickChickTool.ml \
- $(QCTOOL_DIR)/quickChickToolTypes.ml \
- $(QCTOOL_DIR)/quickChickToolLexer.mll \
-@@ -32,7 +32,7 @@
- install: all
- $(V)$(MAKE) -f Makefile.coq install > $(TEMPFILE)
- # Manually copying the remaining files
-- $(V)cp $(QCTOOL_EXE) $(shell opam config var bin)/quickChick
-+ $(V)cp $(QCTOOL_EXE) "$(COQBIN)/quickChick"
- # $(V)cp src/quickChickLib.cmx $(COQLIB)/user-contrib/QuickChick
- # $(V)cp src/quickChickLib.o $(COQLIB)/user-contrib/QuickChick
-
---- quickchick-v1.0.2.orig/src/Show.v 2018-08-22 18:21:39.000000000 +0200
-+++ quickchick-v1.0.2/src/Show.v 2018-08-27 09:21:35.893961900 +0200
-@@ -228,7 +228,7 @@
- match s with
- | EmptyString => (if b then ")" else "", b)
- | String a s =>
-- let (s', b) := aux s (orb b (nat_of_ascii a =? 32)) in
-+ let (s', b) := aux s (orb b (nat_of_ascii a =? 32)%nat) in
- (String a s', b)
- end in
- let (s', b) := aux s false in
diff --git a/dev/build/windows/patches_coq/quickchick.patch b/dev/build/windows/patches_coq/quickchick.patch
new file mode 100755
index 00000000..1afa6e7f
--- /dev/null
+++ b/dev/build/windows/patches_coq/quickchick.patch
@@ -0,0 +1,26 @@
+diff/patch file created on Mon, Aug 27, 2018 9:21:52 AM with:
+difftar-folder.sh tarballs/quickchick-v1.0.2.tar.gz quickchick-v1.0.2 1
+TARFILE= tarballs/quickchick-v1.0.2.tar.gz
+FOLDER= quickchick-v1.0.2
+TARSTRIP= 1
+TARPREFIX= QuickChick-1.0.2/
+ORIGFOLDER= quickchick-v1.0.2.orig
+--- quickchick-v1.0.2.orig/Makefile 2018-08-22 18:21:39.000000000 +0200
++++ quickchick-v1.0.2/Makefile 2018-08-27 09:21:04.710461100 +0200
+@@ -2,7 +2,7 @@
+ .PHONY: plugin install install-plugin clean quickChickTool
+
+ QCTOOL_DIR=quickChickTool
+-QCTOOL_EXE=quickChickTool.byte
++QCTOOL_EXE=quickChickTool.native
+ QCTOOL_SRC=$(QCTOOL_DIR)/quickChickTool.ml \
+ $(QCTOOL_DIR)/quickChickToolTypes.ml \
+ $(QCTOOL_DIR)/quickChickToolLexer.mll \
+@@ -32,7 +32,7 @@
+ install: all
+ $(V)$(MAKE) -f Makefile.coq install > $(TEMPFILE)
+ # Manually copying the remaining files
+- $(V)cp $(QCTOOL_EXE) $(shell opam config var bin)/quickChick
++ $(V)cp $(QCTOOL_EXE) "$(COQBIN)/quickChick"
+ # $(V)cp src/quickChickLib.cmx $(COQLIB)/user-contrib/QuickChick
+ # $(V)cp src/quickChickLib.o $(COQLIB)/user-contrib/QuickChick
diff --git a/dev/checker.dbg b/dev/checker.dbg
new file mode 100644
index 00000000..b2323b61
--- /dev/null
+++ b/dev/checker.dbg
@@ -0,0 +1,6 @@
+load_printer threads.cma
+load_printer str.cma
+load_printer clib.cma
+load_printer dynlink.cma
+load_printer lib.cma
+load_printer check.cma
diff --git a/dev/checker_db b/dev/checker_db
new file mode 100644
index 00000000..327e636c
--- /dev/null
+++ b/dev/checker_db
@@ -0,0 +1,39 @@
+source checker.dbg
+
+load_printer checker_printers.cmo
+
+install_printer Checker_printers.pP
+
+install_printer Checker_printers.ppfuture
+
+install_printer Checker_printers.ppid
+install_printer Checker_printers.pplab
+install_printer Checker_printers.ppmbid
+install_printer Checker_printers.ppdir
+install_printer Checker_printers.ppmp
+install_printer Checker_printers.ppcon
+install_printer Checker_printers.ppproj
+install_printer Checker_printers.ppkn
+install_printer Checker_printers.ppmind
+install_printer Checker_printers.ppind
+
+install_printer Checker_printers.ppbigint
+
+install_printer Checker_printers.ppintset
+install_printer Checker_printers.ppidset
+
+install_printer Checker_printers.ppidmapgen
+
+install_printer Checker_printers.ppididmap
+
+install_printer Checker_printers.ppuni
+install_printer Checker_printers.ppuni_level
+install_printer Checker_printers.ppuniverse_set
+install_printer Checker_printers.ppuniverse_instance
+install_printer Checker_printers.ppauniverse_context
+install_printer Checker_printers.ppuniverse_context
+install_printer Checker_printers.ppconstraints
+install_printer Checker_printers.ppuniverse_context_future
+install_printer Checker_printers.ppuniverses
+
+install_printer Checker_printers.pploc
diff --git a/dev/checker_printers.ml b/dev/checker_printers.ml
new file mode 100644
index 00000000..40ae1a7b
--- /dev/null
+++ b/dev/checker_printers.ml
@@ -0,0 +1,73 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* str "_") kx)
+
+(* name printers *)
+let ppid id = pp (Id.print id)
+let pplab l = pp (Label.print l)
+let ppmbid mbid = pp (str (MBId.debug_to_string mbid))
+let ppdir dir = pp (DirPath.print dir)
+let ppmp mp = pp(str (ModPath.debug_to_string mp))
+let ppcon con = pp(Constant.debug_print con)
+let ppproj con = pp(Constant.debug_print (Projection.constant con))
+let ppkn kn = pp(str (KerName.to_string kn))
+let ppmind kn = pp(MutInd.debug_print kn)
+let ppind (kn,i) = pp(MutInd.debug_print kn ++ str"," ++int i)
+
+(* term printers *)
+let ppbigint n = pp (str (Bigint.to_string n));;
+
+let prset pr l = str "[" ++ hov 0 (prlist_with_sep spc pr l) ++ str "]"
+let ppintset l = pp (prset int (Int.Set.elements l))
+let ppidset l = pp (prset Id.print (Id.Set.elements l))
+
+let prset' pr l = str "[" ++ hov 0 (prlist_with_sep pr_comma pr l) ++ str "]"
+
+let pridmap pr l =
+ let pr (id,b) = Id.print id ++ str "=>" ++ pr id b in
+ prset' pr (Id.Map.fold (fun a b l -> (a,b)::l) l [])
+let ppidmap pr l = pp (pridmap pr l)
+
+let pridmapgen l =
+ let dom = Id.Set.elements (Id.Map.domain l) in
+ if dom = [] then str "[]" else
+ str "[domain= " ++ hov 0 (prlist_with_sep spc Id.print dom) ++ str "]"
+let ppidmapgen l = pp (pridmapgen l)
+
+let prididmap = pridmap (fun _ -> Id.print)
+let ppididmap = ppidmap (fun _ -> Id.print)
+
+let pP s = pp (hov 0 s)
+
+(* proof printers *)
+let ppuni u = pp(Universe.pr u)
+let ppuni_level u = pp (Level.pr u)
+
+let ppuniverse_set l = pp (LSet.pr l)
+let ppuniverse_instance l = pp (Instance.pr l)
+let ppauniverse_context l = pp (AUContext.pr Level.pr l)
+let ppuniverse_context l = pp (pr_universe_context Level.pr l)
+let ppconstraints c = pp (pr_constraints Level.pr c)
+let ppuniverse_context_future c =
+ let ctx = Future.force c in
+ ppuniverse_context ctx
+let ppuniverses u = pp (Univ.pr_universes u)
+
+let pploc x = let (l,r) = Loc.unloc x in
+ print_string"(";print_int l;print_string",";print_int r;print_string")"
diff --git a/dev/checker_printers.mli b/dev/checker_printers.mli
new file mode 100644
index 00000000..2f9500c5
--- /dev/null
+++ b/dev/checker_printers.mli
@@ -0,0 +1,54 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* unit
+val pP : Pp.t -> unit (* with surrounding box *)
+
+val ppfuture : 'a Future.computation -> unit
+
+val ppid : Names.Id.t -> unit
+val pplab : Names.Label.t -> unit
+val ppmbid : Names.MBId.t -> unit
+val ppdir : Names.DirPath.t -> unit
+val ppmp : Names.ModPath.t -> unit
+val ppcon : Names.Constant.t -> unit
+val ppproj : Names.Projection.t -> unit
+val ppkn : Names.KerName.t -> unit
+val ppmind : Names.MutInd.t -> unit
+val ppind : Names.inductive -> unit
+
+val ppbigint : Bigint.bigint -> unit
+
+val ppintset : Int.Set.t -> unit
+val ppidset : Names.Id.Set.t -> unit
+
+val pridmap : (Names.Id.Map.key -> 'a -> Pp.t) -> 'a Names.Id.Map.t -> Pp.t
+val ppidmap : (Names.Id.Map.key -> 'a -> Pp.t) -> 'a Names.Id.Map.t -> unit
+
+val pridmapgen : 'a Names.Id.Map.t -> Pp.t
+val ppidmapgen : 'a Names.Id.Map.t -> unit
+
+val prididmap : Names.Id.t Names.Id.Map.t -> Pp.t
+val ppididmap : Names.Id.t Names.Id.Map.t -> unit
+
+(* Universes *)
+val ppuni : Univ.Universe.t -> unit
+val ppuni_level : Univ.Level.t -> unit (* raw *)
+val ppuniverse_set : Univ.LSet.t -> unit
+val ppuniverse_instance : Univ.Instance.t -> unit
+val ppauniverse_context : Univ.AUContext.t -> unit
+val ppuniverse_context : Univ.UContext.t -> unit
+val ppconstraints : Univ.Constraint.t -> unit
+val ppuniverse_context_future : Univ.UContext.t Future.computation -> unit
+val ppuniverses : Univ.universes -> unit
+
+val pploc : Loc.t -> unit
diff --git a/dev/ci/README.md b/dev/ci/README.md
index 43d680af..60a86362 100644
--- a/dev/ci/README.md
+++ b/dev/ci/README.md
@@ -126,7 +126,7 @@ patch (or ask someone to prepare a patch) to fix the project:
developer who merges the PR on Coq. There are plans to improve this, cf.
[#6724](https://github.com/coq/coq/issues/6724).
-Moreover your PR must absolutely update the [`CHANGES`](../../CHANGES) file.
+Moreover your PR must absolutely update the [`CHANGES.md`](../../CHANGES.md) file.
Advanced GitLab CI information
------------------------------
@@ -136,15 +136,35 @@ rebuilding Coq. In one job, Coq is built with `./configure -prefix _install_ci`
and `make install` is run, then the `_install_ci` directory
persists to and is used by the next jobs.
-Artifacts can also be downloaded from the GitLab repository.
-Currently, available artifacts are:
-- the Coq executables and stdlib, in three copies varying in
- architecture and OCaml version used to build Coq.
-- the Coq documentation, built only in the `build:base` job. When submitting
- a documentation PR, this can help reviewers checking the rendered result.
+### Artifacts
-As an exception to the above, jobs testing that compilation triggers
-no OCaml warnings build Coq in parallel with other tests.
+Build artifacts from GitLab can be linked / downloaded in a systematic
+way, see [GitLab's documentation](https://docs.gitlab.com/ce/user/project/pipelines/job_artifacts.html#downloading-the-latest-job-artifacts)
+for more information. For example, to access the documentation of the
+`master` branch, you can do:
+
+https://gitlab.com/coq/coq/-/jobs/artifacts/master/file/_install_ci/share/doc/coq/sphinx/html/index.html?job=doc:refman
+
+Browsing artifacts is also possible:
+https://gitlab.com/coq/coq/-/jobs/artifacts/master/browse/_install_ci/?job=build:base
+
+Above, you can replace `master` and `job` by the desired GitLab branch and job name.
+
+Currently available artifacts are:
+
+- the Coq executables and stdlib, in four copies varying in
+ architecture and OCaml version used to build Coq:
+ https://gitlab.com/coq/coq/-/jobs/artifacts/master/browse/_install_ci/?job=build:base
+
+- the Coq documentation, built in the `doc:*` jobs. When submitting
+ a documentation PR, this can help reviewers checking the rendered result:
+
+ + Coq's Reference Manual [master branch]
+ https://gitlab.com/coq/coq/-/jobs/artifacts/master/file/_install_ci/share/doc/coq/sphinx/html/index.html?job=doc:refman
+ + Coq's Standard Library Documentation [master branch]
+ https://gitlab.com/coq/coq/-/jobs/artifacts/master/file/_install_ci/share/doc/coq/html/stdlib/index.html?job=build:base
+ + Coq's ML API Documentation [master branch]
+ https://gitlab.com/coq/coq/-/jobs/artifacts/master/file/dev/ocamldoc/html/index.html?job=doc:ml-api
### GitLab and Windows
@@ -152,6 +172,11 @@ If your repository has access to runners tagged `windows`, setting the
secret variable `WINDOWS` to `enabled` will add jobs building Windows
versions of Coq (32bit and 64bit).
+If the secret variable `WINDOWS` is set to `enabled_all_addons`,
+an extended set of addons will be added to the Windows installer.
+This leads to a considerable runtime in CI so this is not enabled
+by default for pipelines for pull requests.
+
The Windows jobs are enabled on Coq's repository, where pipelines for
pull requests run.
@@ -171,6 +196,6 @@ but if you wish to save more time you can skip the job by setting
This means you will need to change its value when the Docker image
needs to be updated. You can do so for a single pipeline by starting
-it through the web interface..
+it through the web interface.
See also [`docker/README.md`](docker/README.md).
diff --git a/dev/ci/appveyor.sh b/dev/ci/appveyor.sh
index 8f53877f..d2176e32 100644
--- a/dev/ci/appveyor.sh
+++ b/dev/ci/appveyor.sh
@@ -10,6 +10,6 @@ bash opam64/install.sh
opam init -a mingw https://github.com/fdopen/opam-repository-mingw.git --comp $APPVEYOR_OPAM_SWITCH --switch $APPVEYOR_OPAM_SWITCH
eval "$(opam config env)"
-opam install -y num ocamlfind camlp5
+opam install -y num ocamlfind camlp5 ounit
cd "$APPVEYOR_BUILD_FOLDER" && ./configure -local && make && make byte && make -C test-suite all INTERACTIVE= && make validate
diff --git a/dev/ci/ci-basic-overlay.sh b/dev/ci/ci-basic-overlay.sh
index 13367794..dd5555e4 100755
--- a/dev/ci/ci-basic-overlay.sh
+++ b/dev/ci/ci-basic-overlay.sh
@@ -9,7 +9,8 @@
########################################################################
# MathComp
########################################################################
-: "${mathcomp_CI_REF:=mathcomp-1.7.0}"
+# Latest commit on master as of Sep 27, 2018
+: "${mathcomp_CI_REF:=5f8d45b54aa98732ec3de43d91814459d5a2f2e4}"
: "${mathcomp_CI_GITURL:=https://github.com/math-comp/math-comp}"
: "${mathcomp_CI_ARCHIVEURL:=${mathcomp_CI_GITURL}/archive}"
@@ -20,79 +21,95 @@
########################################################################
# UniMath
########################################################################
-: "${UniMath_CI_REF:=master}"
+# Latest commit on master as of Sep 27, 2018
+: "${UniMath_CI_REF:=17a5f224feb42b562ded5fec79ea937dcb45764c}"
: "${UniMath_CI_GITURL:=https://github.com/UniMath/UniMath}"
: "${UniMath_CI_ARCHIVEURL:=${UniMath_CI_GITURL}/archive}"
########################################################################
# Unicoq + Mtac2
########################################################################
-: "${unicoq_CI_REF:=v1.3-8.8}"
+# Latest commit on master as of Sep 27, 2018
+: "${unicoq_CI_REF:=1cec038ab34e03109f5587a8aecda1f6c53495dd}"
: "${unicoq_CI_GITURL:=https://github.com/unicoq/unicoq}"
: "${unicoq_CI_ARCHIVEURL:=${unicoq_CI_GITURL}/archive}"
-: "${mtac2_CI_REF:=v1.0.1-coq8.8}"
+# Latest commit on master-sync as of Sep 27, 2018
+: "${mtac2_CI_REF:=e65c2560e5098df5e7333f19db97e9f39e46c3ee}"
: "${mtac2_CI_GITURL:=https://github.com/Mtac2/Mtac2}"
: "${mtac2_CI_ARCHIVEURL:=${mtac2_CI_GITURL}/archive}"
########################################################################
# Mathclasses + Corn
########################################################################
-: "${math_classes_CI_REF:=master}"
+# Latest commit on master as of Sep 27, 2018
+: "${math_classes_CI_REF:=0f530c713db886ab692bba49862a1cbcbebc8610}"
: "${math_classes_CI_GITURL:=https://github.com/coq-community/math-classes}"
: "${math_classes_CI_ARCHIVEURL:=${math_classes_CI_GITURL}/archive}"
-: "${Corn_CI_REF:=master}"
+# Latest commit on master as of Sep 27, 2018
+: "${Corn_CI_REF:=f505e489829a968074f53fe18b70a292ad94a9d0}"
: "${Corn_CI_GITURL:=https://github.com/coq-community/corn}"
: "${Corn_CI_ARCHIVEURL:=${Corn_CI_GITURL}/archive}"
########################################################################
# Iris
########################################################################
-: "${stdpp_CI_REF:=master}"
+# std++ commit pinned in Iris
+: "${stdpp_CI_REF:=4fb641edc8d74fbba01fed33d9acbc8a423ea601}"
: "${stdpp_CI_GITURL:=https://gitlab.mpi-sws.org/robbertkrebbers/coq-stdpp}"
: "${stdpp_CI_ARCHIVEURL:=${stdpp_CI_GITURL}/-/archive}"
-: "${Iris_CI_REF:=master}"
+# Iris commit pinned in LambdaRust
+: "${Iris_CI_REF:=85425d47be677d05d74caff5e1a8a85289d96ae1}"
: "${Iris_CI_GITURL:=https://gitlab.mpi-sws.org/FP/iris-coq}"
: "${Iris_CI_ARCHIVEURL:=${Iris_CI_GITURL}/-/archive}"
-: "${lambdaRust_CI_REF:=master}"
+# Latest commit on master as of Sep 27, 2018
+: "${lambdaRust_CI_REF:=fd46e6625eef509a80896dccf6c976545b17ab90}"
: "${lambdaRust_CI_GITURL:=https://gitlab.mpi-sws.org/FP/LambdaRust-coq}"
: "${lambdaRust_CI_ARCHIVEURL:=${lambdaRust_CI_GITURL}/-/archive}"
########################################################################
# HoTT
########################################################################
-: "${HoTT_CI_REF:=V8.8}"
+# Latest commit on master as of Sep 3, 2018
+: "${HoTT_CI_REF:=333face272e39175a1b342e14c86c316f572f51f}"
: "${HoTT_CI_GITURL:=https://github.com/HoTT/HoTT}"
: "${HoTT_CI_ARCHIVEURL:=${HoTT_CI_GITURL}/archive}"
########################################################################
# Ltac2
########################################################################
-: "${ltac2_CI_REF:=0.1}"
+: "${ltac2_CI_REF:=v8.9}"
: "${ltac2_CI_GITURL:=https://github.com/ppedrot/ltac2}"
: "${ltac2_CI_ARCHIVEURL:=${ltac2_CI_GITURL}/archive}"
########################################################################
# GeoCoq
########################################################################
-: "${GeoCoq_CI_REF:=master}"
+# Latest commit on master as of Sep 27, 2018
+: "${GeoCoq_CI_REF:=a13b48840898fec207b382ab42c0bf0b2f62024b}"
: "${GeoCoq_CI_GITURL:=https://github.com/GeoCoq/GeoCoq}"
: "${GeoCoq_CI_ARCHIVEURL:=${GeoCoq_CI_GITURL}/archive}"
########################################################################
# Flocq
########################################################################
-: "${Flocq_CI_REF:=master}"
+# Latest commit on master as of Sep 27, 2018
+: "${Flocq_CI_REF:=ff6fc12f269ca055b7b6fd88247ac2697ff6e687}"
: "${Flocq_CI_GITURL:=https://gitlab.inria.fr/flocq/flocq}"
: "${Flocq_CI_ARCHIVEURL:=${Flocq_CI_GITURL}/-/archive}"
########################################################################
# Coquelicot
########################################################################
-# ATTENTION: The archive URL might depend on the version
+# The URL for downloading a tgz snapshot of the master branch is
+# https://scm.gforge.inria.fr/anonscm/gitweb?p=coquelicot/coquelicot.git;a=snapshot;h=refs/heads/master;sf=tgz
+# See https://gforge.inria.fr/scm/browser.php?group_id=3599
+# Since this URL doesn't fit to our standard mechanism and since Coquelicot doesn't seem to change frequently,
+# we use a fixed version, which has a download path which does fit to our standard mechanism.
+# ATTENTION: The archive URL might depend on the version!
: "${Coquelicot_CI_REF:=coquelicot-3.0.2}"
: "${Coquelicot_CI_GITURL:=https://scm.gforge.inria.fr/anonscm/git/coquelicot/coquelicot}"
: "${Coquelicot_CI_ARCHIVEURL:=https://gforge.inria.fr/frs/download.php/file/37523}"
@@ -100,53 +117,64 @@
########################################################################
# CompCert
########################################################################
-# Note: The latest release version of CompCert (3.3) does not compile with Coq 8.8.1
-# This is caused by a compatibility issue with OCaml 4.0.7
-: "${CompCert_CI_REF:=17f9d839df12511a7e327f2840855e70af5ede47}"
+# Latest commit on master as of Sep 27, 2018
+: "${CompCert_CI_REF:=020be062488d755236f296fff760c7491e11997b}"
: "${CompCert_CI_GITURL:=https://github.com/AbsInt/CompCert}"
: "${CompCert_CI_ARCHIVEURL:=${CompCert_CI_GITURL}/archive}"
########################################################################
# VST
########################################################################
-# Note: The latest release version of VST (2.2) does not compile with Coq 8.8.1
-# Note: newer versions of VST have issues with buildability and licensing
-: "${VST_CI_REF:=e49605cf1f1e5ae3bbec3d6554122427a94ae986}"
+# Latest commit on master as of Dec 10, 2018
+: "${VST_CI_REF:=f6afb456db69df66c366c36b2d0218d92813f546}"
: "${VST_CI_GITURL:=https://github.com/PrincetonUniversity/VST}"
: "${VST_CI_ARCHIVEURL:=${VST_CI_GITURL}/archive}"
+########################################################################
+# cross-crypto
+########################################################################
+# Latest commit on master as of Sep 27, 2018
+: "${cross_crypto_CI_REF:=453da7e0541798f36d82b6c67a3f4461cd5dc773}"
+: "${cross_crypto_CI_GITURL:=https://github.com/mit-plv/cross-crypto}"
+: "${cross_crypto_CI_ARCHIVEURL:=${cross_crypto_CI_GITURL}/archive}"
+
########################################################################
# fiat_parsers
########################################################################
-: "${fiat_parsers_CI_REF:=master}"
+# Latest commit on master as of Sep 27, 2018
+: "${fiat_parsers_CI_REF:=a41e7ee1c5152aecedb354a112d5c8121a499d30}"
: "${fiat_parsers_CI_GITURL:=https://github.com/mit-plv/fiat}"
: "${fiat_parsers_CI_ARCHIVEURL:=${fiat_parsers_CI_GITURL}/archive}"
########################################################################
# fiat_crypto
########################################################################
-: "${fiat_crypto_CI_REF:=master}"
+# Latest commit on master as of Sep 27, 2018
+: "${fiat_crypto_CI_REF:=059f186db67852ac17de78dab1987aab77dd4bdb}"
: "${fiat_crypto_CI_GITURL:=https://github.com/mit-plv/fiat-crypto}"
: "${fiat_crypto_CI_ARCHIVEURL:=${fiat_crypto_CI_GITURL}/archive}"
########################################################################
# formal-topology
########################################################################
-: "${formal_topology_CI_REF:=ci}"
+# Latest commit on ci as of Sep 27, 2018
+: "${formal_topology_CI_REF:=a2f1aa04db253e4f90fb2aae724cfca42ccd53ab}"
: "${formal_topology_CI_GITURL:=https://github.com/bmsherman/topology}"
: "${formal_topology_CI_ARCHIVEURL:=${formal_topology_CI_GITURL}/archive}"
########################################################################
# coq-dpdgraph
########################################################################
-: "${coq_dpdgraph_CI_REF:=coq-v8.8}"
+# Latest commit on coq-master as of Sep 27, 2018
+: "${coq_dpdgraph_CI_REF:=e14e2bc0108a593f7c64d9af3fc4aec9e8fb1397}"
: "${coq_dpdgraph_CI_GITURL:=https://github.com/Karmaki/coq-dpdgraph}"
: "${coq_dpdgraph_CI_ARCHIVEURL:=${coq_dpdgraph_CI_GITURL}/archive}"
########################################################################
# CoLoR
########################################################################
-: "${CoLoR_CI_REF:=master}"
+# Latest commit on master as of Nov 5, 2018
+: "${CoLoR_CI_REF:=4ce3a9fb5f58501aef3c0727c8ba8cc38917399d}"
: "${CoLoR_CI_GITURL:=https://github.com/fblanqui/color}"
: "${CoLoR_CI_ARCHIVEURL:=${CoLoR_CI_GITURL}/archive}"
@@ -160,77 +188,101 @@
########################################################################
# TLC
########################################################################
-: "${tlc_CI_REF:=master}"
+# Latest commit on master as of Sep 27, 2018
+: "${tlc_CI_REF:=6bce3c31e5c74d9f953de3620deadd9f4cc04023}"
: "${tlc_CI_GITURL:=https://gforge.inria.fr/git/tlc/tlc}"
########################################################################
# Bignums
########################################################################
-: "${bignums_CI_REF:=V8.8.0}"
+# Latest commit on master as of Sep 27, 2018
+: "${bignums_CI_REF:=f1a63cb4cce9a79e4406275fbb0ee2269947f8d2}"
: "${bignums_CI_GITURL:=https://github.com/coq/bignums}"
: "${bignums_CI_ARCHIVEURL:=${bignums_CI_GITURL}/archive}"
########################################################################
# bedrock2
########################################################################
-: "${bedrock2_CI_REF:=master}"
+# Latest commit on master as of Sep 27, 2018
+: "${bedrock2_CI_REF:=cbf50671ba2d9235060d4e4747d0860f127f3995}"
: "${bedrock2_CI_GITURL:=https://github.com/mit-plv/bedrock2}"
: "${bedrock2_CI_ARCHIVEURL:=${bedrock2_CI_GITURL}/archive}"
########################################################################
# Equations
########################################################################
-: "${Equations_CI_REF:=v1.1-8.8}"
+# Latest commit on master as of Sep 26, 2018
+: "${Equations_CI_REF:=477cb9d8aac85e03dad3f992f99646e14d803a0c}"
: "${Equations_CI_GITURL:=https://github.com/mattam82/Coq-Equations}"
: "${Equations_CI_ARCHIVEURL:=${Equations_CI_GITURL}/archive}"
########################################################################
# Elpi
########################################################################
-: "${Elpi_CI_REF:=coq-v8.8}"
+: "${Elpi_CI_REF:=coq-v8.9}"
: "${Elpi_CI_GITURL:=https://github.com/LPCIC/coq-elpi}"
: "${Elpi_CI_ARCHIVEURL:=${Elpi_CI_GITURL}/archive}"
########################################################################
# fcsl-pcm
########################################################################
-: "${fcsl_pcm_CI_REF:=master}"
+# Latest commit on master as of Sep 27, 2018
+: "${fcsl_pcm_CI_REF:=51ade0a882ae2ac7df071b41d468df1813504c81}"
: "${fcsl_pcm_CI_GITURL:=https://github.com/imdea-software/fcsl-pcm}"
: "${fcsl_pcm_CI_ARCHIVEURL:=${fcsl_pcm_CI_GITURL}/archive}"
+########################################################################
+# pidetop
+########################################################################
+# Latest commit on v8.9 as of Sep 27, 2018
+: "${pidetop_CI_REF:=ef42320bc0ab75f313e9476e8c8c945ae2116cb5}"
+: "${pidetop_CI_GITURL:=https://bitbucket.org/coqpide/pidetop}"
+: "${pidetop_CI_ARCHIVEURL:=${pidetop_CI_GITURL}/get}"
+
########################################################################
# ext-lib
########################################################################
-# Note: This is the latest commit of the v8.8 branch as of August 31st 2018
-: "${ext_lib_CI_REF:=5dd9cfa51f96fcb785c7c31d8c6bf55af5d93f27}"
+# Latest commit on master as of Sep 27, 2018
+: "${ext_lib_CI_REF:=a9c138921fb8c2601e64f1a1702a689120d456f3}"
: "${ext_lib_CI_GITURL:=https://github.com/coq-ext-lib/coq-ext-lib}"
: "${ext_lib_CI_ARCHIVEURL:=${ext_lib_CI_GITURL}/archive}"
########################################################################
# simple-io
########################################################################
-: "${simple_io_CI_REF:=0.2}"
+# Latest commit on master as of Sep 27, 2018
+: "${simple_io_CI_REF:=e627c087ed8225d70aa7aafe882448fea31fef32}"
: "${simple_io_CI_GITURL:=https://github.com/Lysxia/coq-simple-io}"
: "${simple_io_CI_ARCHIVEURL:=${simple_io_CI_GITURL}/archive}"
########################################################################
# quickchick
########################################################################
-: "${quickchick_CI_REF:=v1.0.2}"
+# Latest commit on master as of Sep 27, 2018
+: "${quickchick_CI_REF:=fae47245b75f049c462601d88e4df2e063841a3b}"
: "${quickchick_CI_GITURL:=https://github.com/QuickChick/QuickChick}"
: "${quickchick_CI_ARCHIVEURL:=${quickchick_CI_GITURL}/archive}"
+########################################################################
+# plugin_tutorial
+########################################################################
+# Latest commit on master as of Sep 27, 2018
+: "${plugin_tutorial_CI_REF:=b303b75c18734accc9cd7efe82307b0424426e3f}"
+: "${plugin_tutorial_CI_GITURL:=https://github.com/ybertot/plugin_tutorials}"
+: "${plugin_tutorial_CI_ARCHIVEURL:=${plugin_tutorial_CI_GITURL}/archive}"
+
########################################################################
# menhirlib
########################################################################
-: "${menhirlib_CI_REF:=20180827}"
+# Latest commit on master as of Sep 27, 2018
+: "${menhirlib_CI_REF:=9e4b304bdbcc1f8d433e005a46eb10480e7ae880}"
: "${menhirlib_CI_GITURL:=https://gitlab.inria.fr/fpottier/coq-menhirlib}"
: "${menhirlib_CI_ARCHIVEURL:=${menhirlib_CI_GITURL}/-/archive}"
########################################################################
# aac-tactics
########################################################################
-# Note: this is the latest commit of the v8.8 branch as of August 31st 2018
-: "${aactactis_CI_REF:=86ac28259030649ef51460e4de2441c8a1017751}"
+# Latest commit on v8.9 as of Dec 17, 2018
+: "${aactactis_CI_REF:=c469b26e409b1bde6a64546df85226079796dbe7}"
: "${aactactis_CI_GITURL:=https://github.com/coq-community/aac-tactics}"
: "${aactactis_CI_ARCHIVEURL:=${aactactis_CI_GITURL}/archive}"
diff --git a/dev/ci/ci-common.sh b/dev/ci/ci-common.sh
index 6fc4293d..7af648f0 100644
--- a/dev/ci/ci-common.sh
+++ b/dev/ci/ci-common.sh
@@ -93,7 +93,7 @@ make()
# this installs just the ssreflect library of math-comp
install_ssreflect()
{
- echo 'Installing ssreflect' && echo -en 'travis_fold:start:ssr.install\\r'
+ echo 'Installing ssreflect'
git_download mathcomp
@@ -102,14 +102,12 @@ install_ssreflect()
make -f Makefile.coq ssreflect/all_ssreflect.vo && \
make -f Makefile.coq install )
- echo -en 'travis_fold:end:ssr.install\\r'
-
}
# this installs just the ssreflect + algebra library of math-comp
install_ssralg()
{
- echo 'Installing ssralg' && echo -en 'travis_fold:start:ssralg.install\\r'
+ echo 'Installing ssralg'
git_download mathcomp
@@ -118,6 +116,4 @@ install_ssralg()
make -f Makefile.coq algebra/all_algebra.vo && \
make -f Makefile.coq install )
- echo -en 'travis_fold:end:ssralg.install\\r'
-
}
diff --git a/dev/ci/ci-cross-crypto.sh b/dev/ci/ci-cross-crypto.sh
new file mode 100755
index 00000000..900d12c1
--- /dev/null
+++ b/dev/ci/ci-cross-crypto.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+ci_dir="$(dirname "$0")"
+. "${ci_dir}/ci-common.sh"
+
+FORCE_GIT=1
+git_download cross_crypto
+
+( cd "${CI_BUILD_DIR}/cross_crypto" && git submodule update --init --recursive && make )
diff --git a/dev/ci/ci-elpi.sh b/dev/ci/ci-elpi.sh
index 7f4ef77d..9b4a06fd 100755
--- a/dev/ci/ci-elpi.sh
+++ b/dev/ci/ci-elpi.sh
@@ -3,7 +3,6 @@
ci_dir="$(dirname "$0")"
. "${ci_dir}/ci-common.sh"
-FORCE_GIT=1
git_download Elpi
( cd "${CI_BUILD_DIR}/Elpi" && make && make install )
diff --git a/dev/ci/ci-fiat-crypto-legacy.sh b/dev/ci/ci-fiat-crypto-legacy.sh
index e0395754..6bf31383 100755
--- a/dev/ci/ci-fiat-crypto-legacy.sh
+++ b/dev/ci/ci-fiat-crypto-legacy.sh
@@ -10,4 +10,5 @@ fiat_crypto_legacy_CI_TARGETS1="print-old-pipeline-lite old-pipeline-lite lite-d
fiat_crypto_legacy_CI_TARGETS2="print-old-pipeline-nobigmem old-pipeline-nobigmem nonautogenerated-specific nonautogenerated-specific-display"
( cd "${CI_BUILD_DIR}/fiat_crypto" && git submodule update --init --recursive && \
+ ./etc/ci/remove_autogenerated.sh && \
make ${fiat_crypto_legacy_CI_TARGETS1} && make -j 1 ${fiat_crypto_legacy_CI_TARGETS2} )
diff --git a/dev/ci/ci-hott.sh b/dev/ci/ci-hott.sh
index 9a0726a1..7eeeb093 100755
--- a/dev/ci/ci-hott.sh
+++ b/dev/ci/ci-hott.sh
@@ -5,4 +5,4 @@ ci_dir="$(dirname "$0")"
git_download HoTT
-( cd "${CI_BUILD_DIR}/HoTT" && ./autogen.sh && ./configure && make )
+( cd "${CI_BUILD_DIR}/HoTT" && ./autogen.sh && ./configure && make && make validate )
diff --git a/dev/ci/ci-iris-lambda-rust.sh b/dev/ci/ci-iris-lambda-rust.sh
index 6960a8b9..bc49193b 100755
--- a/dev/ci/ci-iris-lambda-rust.sh
+++ b/dev/ci/ci-iris-lambda-rust.sh
@@ -9,13 +9,15 @@ install_ssreflect
git_download lambdaRust
# Extract required version of Iris
-Iris_REF=$(grep -F coq-iris < "${CI_BUILD_DIR}/lambdaRust/opam" | sed 's/.*"dev\.[0-9.-]\+\.\([0-9a-z]\+\)".*/\1/')
+# Iris is already pinned in ci-basic-overlays.sh
+#Iris_REF=$(grep -F coq-iris < "${CI_BUILD_DIR}/lambdaRust/opam" | sed 's/.*"dev\.[0-9.-]\+\.\([0-9a-z]\+\)".*/\1/')
# Setup Iris
git_download Iris
# Extract required version of std++
-stdpp_REF=$(grep -F coq-stdpp < "${CI_BUILD_DIR}/Iris/opam" | sed 's/.*"dev\.[0-9.-]\+\.\([0-9a-z]\+\)".*/\1/')
+# std++ is already pinned in ci-basic-overlays.sh
+#stdpp_REF=$(grep -F coq-stdpp < "${CI_BUILD_DIR}/Iris/opam" | sed 's/.*"dev\.[0-9.-]\+\.\([0-9a-z]\+\)".*/\1/')
# Setup std++
git_download stdpp
diff --git a/dev/ci/ci-math-comp.sh b/dev/ci/ci-math-comp.sh
index 74f1a627..a74f9fa4 100755
--- a/dev/ci/ci-math-comp.sh
+++ b/dev/ci/ci-math-comp.sh
@@ -1,5 +1,6 @@
#!/usr/bin/env bash
+# $0 is not the safest way, but...
ci_dir="$(dirname "$0")"
. "${ci_dir}/ci-common.sh"
diff --git a/dev/ci/ci-pidetop.sh b/dev/ci/ci-pidetop.sh
new file mode 100755
index 00000000..d22b9c8f
--- /dev/null
+++ b/dev/ci/ci-pidetop.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+ci_dir="$(dirname "$0")"
+. "${ci_dir}/ci-common.sh"
+
+git_download pidetop
+
+# Travis / Gitlab have different filesystem layout due to use of
+# `-local`. We need to improve this divergence but if we use Dune this
+# "local" oddity goes away automatically so not bothering...
+if [ -d "$COQBIN/../lib/coq" ]; then
+ COQLIB="$COQBIN/../lib/coq/"
+else
+ COQLIB="$COQBIN/../"
+fi
+
+( cd "${CI_BUILD_DIR}/pidetop" && jbuilder build @install )
+
+echo -en '4\nexit' | "${CI_BUILD_DIR}/pidetop/_build/install/default/bin/pidetop" -coqlib "$COQLIB" -main-channel stdfds
diff --git a/dev/ci/ci-sf.sh b/dev/ci/ci-sf.sh
index 58bbb722..60436e67 100755
--- a/dev/ci/ci-sf.sh
+++ b/dev/ci/ci-sf.sh
@@ -8,11 +8,6 @@ wget -qO- "${sf_lf_CI_TARURL}" | tar xvz
wget -qO- "${sf_plf_CI_TARURL}" | tar xvz
wget -qO- "${sf_vfa_CI_TARURL}" | tar xvz
-sed -i.bak '1i From Coq Require Extraction.' lf/Extraction.v
-sed -i.bak '1i From Coq Require Extraction.' vfa/Extract.v
-
-( cd lf && make clean && make )
-
-( cd plf && sed -i.bak 's/(K,N)/((K,N))/' LibTactics.v && make clean && make )
-
+( cd lf && make clean && make )
+( cd plf && make clean && make )
( cd vfa && make clean && make )
diff --git a/dev/ci/ci-simple-io.sh b/dev/ci/ci-simple-io.sh
index ddc1590d..e7bcd80d 100755
--- a/dev/ci/ci-simple-io.sh
+++ b/dev/ci/ci-simple-io.sh
@@ -1,7 +1,6 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-
. "${ci_dir}/ci-common.sh"
git_download simple_io
diff --git a/dev/ci/docker/README.md b/dev/ci/docker/README.md
new file mode 100644
index 00000000..919e2a73
--- /dev/null
+++ b/dev/ci/docker/README.md
@@ -0,0 +1,36 @@
+## Overall Docker Setup for Coq's CI.
+
+This directory provides Docker images to be used by Coq's CI. The
+images do support Docker autobuild on `hub.docker.com` and Gitlab's
+private registry.
+
+Gitlab CI will build and tag a Docker by default for every job if the
+`SKIP_DOCKER` variable is not set to `false`. In Coq's CI, this
+variable is usually set to `false` indeed to avoid booting a useless
+job.
+
+## Manual Building
+
+You can also manually build and push any image:
+
+- Build the image `docker build -t base:$VERSION .`
+
+To upload/push to your hub:
+
+- Create a https://hub.docker.com account.
+- Login into your space `docker login --username=$USER`
+- Push the image:
+ + `docker tag base:$VERSION $USER/base:$VERSION`
+ + `docker push $USER/base:$VERSION`
+
+## Debugging / Misc
+
+To open a shell inside an image do `docker run -ti --entrypoint /bin/bash `
+
+Each `RUN` command creates an "layer", thus a Docker build is
+incremental and it always help to put things updated more often at the
+end.
+
+## Possible Improvements:
+
+- Use ARG for customizing versions, centralize variable setup;
diff --git a/dev/ci/docker/bionic_coq/Dockerfile b/dev/ci/docker/bionic_coq/Dockerfile
index da12f122..332597f3 100644
--- a/dev/ci/docker/bionic_coq/Dockerfile
+++ b/dev/ci/docker/bionic_coq/Dockerfile
@@ -1,4 +1,4 @@
-# CACHEKEY: "bionic_coq-v8.8-V2018-09-20"
+# CACHEKEY: "bionic_coq-v8.9-V2018-10-22"
# ^^ Update when modifying this file.
FROM ubuntu:bionic
@@ -8,52 +8,63 @@ ENV DEBIAN_FRONTEND="noninteractive"
RUN apt-get update -qq && apt-get install --no-install-recommends -y -qq \
# Dependencies of the image, the test-suite and external projects
- m4 automake autoconf time wget rsync git gcc-multilib opam \
+ m4 automake autoconf time wget rsync git gcc-multilib build-essential unzip \
# Dependencies of lablgtk (for CoqIDE)
libgtk2.0-dev libgtksourceview2.0-dev \
- texlive-latex-extra texlive-fonts-recommended texlive-xetex latexmk xindy texlive-science tipa hevea \
- python3-sphinx python3-pexpect python3-sphinx-rtd-theme python3-bs4 python3-sphinxcontrib.bibtex \
- python3-setuptools python3-wheel python3-pip
+ # Dependencies of stdlib and sphinx doc
+ texlive-latex-extra texlive-fonts-recommended texlive-xetex latexmk \
+ xindy python3-pip python3-setuptools python3-pexpect python3-bs4 \
+ python3-sphinx python3-sphinx-rtd-theme python3-sphinxcontrib.bibtex \
+ # Dependencies of source-doc and coq-makefile
+ texlive-science tipa
+# More dependencies of the sphinx doc
RUN pip3 install antlr4-python3-runtime
+# We need to install OPAM 2.0 manually for now.
+RUN wget https://github.com/ocaml/opam/releases/download/2.0.0/opam-2.0.0-x86_64-linux -O /usr/bin/opam && chmod 755 /usr/bin/opam
+
# Basic OPAM setup
ENV NJOBS="2" \
+ OPAMJOBS="2" \
OPAMROOT=/root/.opamcache \
- OPAMROOTISOK="true"
+ OPAMROOTISOK="true" \
+ OPAMYES="true"
# Base opam is the set of base packages required by Coq
ENV COMPILER="4.02.3"
-RUN opam init -a -y -j $NJOBS --compiler="$COMPILER" default https://opam.ocaml.org && eval $(opam config env) && opam update
-
# Common OPAM packages.
# `num` does not have a version number as the right version to install varies
# with the compiler version.
-ENV BASE_OPAM="num ocamlfind.1.8.0" \
- CI_OPAM="menhir.20180530 ppx_tools_versioned.5.2 ppx_deriving.4.1.5 ocaml-migrate-parsetree.1.0.11 ocamlgraph.1.8.8"
+ENV BASE_OPAM="num ocamlfind.1.8.0 dune.1.1.1 ounit.2.0.8" \
+ CI_OPAM="menhir.20180530 elpi.1.1.0 ocamlgraph.1.8.8"
# BASE switch; CI_OPAM contains Coq's CI dependencies.
ENV CAMLP5_VER="6.14" \
COQIDE_OPAM="lablgtk.2.18.5 conf-gtksourceview.2"
-RUN opam switch -y -j $NJOBS "$COMPILER" && eval $(opam config env) && \
- opam install -j $NJOBS $BASE_OPAM && \
- opam install -j $NJOBS camlp5.$CAMLP5_VER $COQIDE_OPAM $CI_OPAM
+# The separate `opam install ocamlfind` workarounds an OPAM repository bug in 4.02.3
+RUN opam init -a --disable-sandboxing --compiler="$COMPILER" default https://opam.ocaml.org && eval $(opam env) && opam update && \
+ opam install ocamlfind.1.8.0 && \
+ opam install $BASE_OPAM camlp5.$CAMLP5_VER $COQIDE_OPAM $CI_OPAM
# base+32bit switch
-RUN opam switch -y -j $NJOBS "${COMPILER}+32bit" && eval $(opam config env) && \
- opam install -j $NJOBS $BASE_OPAM camlp5.$CAMLP5_VER
+RUN opam switch create "${COMPILER}+32bit" && eval $(opam env) && \
+ opam install ocamlfind.1.8.0 && \
+ opam install $BASE_OPAM camlp5.$CAMLP5_VER
# EDGE switch
ENV COMPILER_EDGE="4.07.0" \
CAMLP5_VER_EDGE="7.06" \
COQIDE_OPAM_EDGE="lablgtk.2.18.6 conf-gtksourceview.2"
-RUN opam switch -y -j $NJOBS $COMPILER_EDGE && eval $(opam config env) && \
- opam install -j $NJOBS $BASE_OPAM camlp5.$CAMLP5_VER_EDGE $COQIDE_OPAM_EDGE
+RUN opam switch create $COMPILER_EDGE && eval $(opam env) && \
+ opam install $BASE_OPAM $BASE_OPAM_EDGE camlp5.$CAMLP5_VER_EDGE $COQIDE_OPAM_EDGE
+
+# EDGE+flambda switch, we install CI_OPAM as to be able to use
+# `ci-template-flambda` with everything.
+RUN opam switch create "${COMPILER_EDGE}+flambda" && eval $(opam env) && \
+ opam install $BASE_OPAM $BASE_OPAM_EDGE camlp5.$CAMLP5_VER_EDGE $COQIDE_OPAM_EDGE $CI_OPAM
-# BE+flambda switch
-RUN opam switch -y -j $NJOBS "${COMPILER_EDGE}+flambda" && eval $(opam config env) && \
- opam install -j $NJOBS $BASE_OPAM && \
- opam install -j $NJOBS camlp5.$CAMLP5_VER_EDGE $COQIDE_OPAM_EDGE $CI_OPAM
+RUN opam clean -a -c
diff --git a/dev/ci/gitlab.bat b/dev/ci/gitlab.bat
index ee1b17b6..66f964a3 100755
--- a/dev/ci/gitlab.bat
+++ b/dev/ci/gitlab.bat
@@ -1,131 +1,132 @@
-@ECHO OFF
-
-REM This script builds and signs the Windows packages on Gitlab
-
-ECHO "Start Time"
-TIME /T
-
-REM List currently used cygwin and target folders for debugging / maintenance purposes
-
-ECHO "Currently used cygwin folders"
-DIR C:\cygwin*
-ECHO "Currently used target folders"
-DIR C:\coq*
-
-if %ARCH% == 32 (
- SET ARCHLONG=i686
- SET CYGROOT=C:\cygwin
- SET SETUP=setup-x86.exe
-)
-
-if %ARCH% == 64 (
- SET ARCHLONG=x86_64
- SET CYGROOT=C:\cygwin64
- SET SETUP=setup-x86_64.exe
-)
-
-SET DESTCOQ=C:\coq%ARCH%_inst
-
-CALL :MakeUniqueFolder %CYGROOT% CYGROOT
-CALL :MakeUniqueFolder %DESTCOQ% DESTCOQ
-
-powershell -Command "(New-Object Net.WebClient).DownloadFile('http://www.cygwin.com/%SETUP%', '%SETUP%')"
-SET CYGCACHE=%CYGROOT%\var\cache\setup
-SET CI_PROJECT_DIR_MFMT=%CI_PROJECT_DIR:\=/%
-SET CI_PROJECT_DIR_CFMT=%CI_PROJECT_DIR_MFMT:C:/=/cygdrive/c/%
-SET COQREGTESTING=Y
-SET PATH=%PATH%;C:\Program Files\7-Zip\;C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin
-
-if exist %CYGROOT%\build\ rd /s /q %CYGROOT%\build
-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 ^
- -addon=equations ^
- -addon=ltac2 ^
- -addon=mtac2 ^
- -addon=mathcomp ^
- -addon=menhir ^
- -addon=menhirlib ^
- -addon=compcert ^
- -addon=vst ^
- -addon=aactactics ^
- -addon=extlib ^
- -addon=quickchick ^
- -addon=coquelicot ^
- -make=N ^
- -setup %CI_PROJECT_DIR%\%SETUP% || GOTO ErrorCopyLogFilesAndExit
-
-ECHO "Start Artifact Creation"
-TIME /T
-
-mkdir artifacts
-
-CALL :CopyLogFiles
-
-copy "%CYGROOT%\build\coq-local\dev\nsis\*.exe" artifacts || GOTO ErrorExit
-REM The open source archive is only required for release builds
-IF DEFINED WIN_CERTIFICATE_PATH (
- 7z a artifacts\coq-opensource-archive-windows-%ARCHLONG%.zip %CYGROOT%\build\tarballs\* || GOTO ErrorExit
-) ELSE (
- REM In non release builds, create a dummy file
- ECHO "This is not a release build - open source archive not created / uploaded" > artifacts\coq-opensource-info.txt
-)
-
-REM DO NOT echo the signing command below, as this would leak secrets in the logs
-IF DEFINED WIN_CERTIFICATE_PATH (
- IF DEFINED WIN_CERTIFICATE_PASSWORD (
- ECHO Signing package
- @signtool sign /f %WIN_CERTIFICATE_PATH% /p %WIN_CERTIFICATE_PASSWORD% dev\nsis\*.exe
- signtool verify /pa dev\nsis\*.exe
- )
-)
-
-ECHO "Finished Artifact Creation"
-TIME /T
-
-CALL :CleanupFolders
-
-ECHO "Finished Cleanup"
-TIME /T
-
-GOTO :EOF
-
-:CopyLogFiles
- ECHO Copy log files for artifact upload
- MKDIR artifacts\buildlogs
- COPY %CYGROOT%\build\buildlogs\* artifacts\buildlogs
- MKDIR artifacts\filelists
- COPY %CYGROOT%\build\filelists\* artifacts\filelists
- MKDIR artifacts\flagfiles
- COPY %CYGROOT%\build\flagfiles\* artifacts\flagfiles
- GOTO :EOF
-
-:CleanupFolders
- ECHO "Cleaning %CYGROOT%"
- DEL /S /F /Q "%CYGROOT%" > NUL
- ECHO "Cleaning %DESTCOQ%"
- DEL /S /F /Q "%DESTCOQ%" > NUL
- GOTO :EOF
-
-:MakeUniqueFolder
- REM Create a uniquely named folder
- REM This script is safe because folder creation is atomic - either we create it or fail
- REM %1 = base path or directory (_%RANDOM%_%RANDOM% is appended to this)
- REM %2 = name of the variable which receives the unique folder name
- SET "UNIQUENAME=%1_%RANDOM%_%RANDOM%"
- MKDIR "%UNIQUENAME%"
- IF ERRORLEVEL 1 GOTO :MakeUniqueFolder
- SET "%2=%UNIQUENAME%"
- GOTO :EOF
-
-:ErrorCopyLogFilesAndExit
- CALL :CopyLogFiles
- REM fall through
-
-:ErrorExit
- CALL :CleanupFolders
- ECHO ERROR %0 failed
- EXIT /b 1
+@ECHO OFF
+
+REM This script builds and signs the Windows packages on Gitlab
+
+ECHO "Start Time"
+TIME /T
+
+REM List currently used cygwin and target folders for debugging / maintenance purposes
+
+ECHO "Currently used cygwin folders"
+DIR C:\ci\cygwin*
+ECHO "Currently used target folders"
+DIR C:\ci\coq*
+ECHO "Root folders"
+DIR C:\
+
+if %ARCH% == 32 (
+ SET ARCHLONG=i686
+ SET SETUP=setup-x86.exe
+)
+
+if %ARCH% == 64 (
+ SET ARCHLONG=x86_64
+ SET SETUP=setup-x86_64.exe
+)
+
+SET CYGROOT=C:\ci\cygwin%ARCH%
+SET DESTCOQ=C:\ci\coq%ARCH%
+
+CALL :MakeUniqueFolder %CYGROOT% CYGROOT
+CALL :MakeUniqueFolder %DESTCOQ% DESTCOQ
+
+powershell -Command "(New-Object Net.WebClient).DownloadFile('http://www.cygwin.com/%SETUP%', '%SETUP%')"
+SET CYGCACHE=%CYGROOT%\var\cache\setup
+SET CI_PROJECT_DIR_MFMT=%CI_PROJECT_DIR:\=/%
+SET CI_PROJECT_DIR_CFMT=%CI_PROJECT_DIR_MFMT:C:/=/cygdrive/c/%
+SET COQREGTESTING=Y
+SET PATH=%PATH%;C:\Program Files\7-Zip\;C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin
+
+if exist %CYGROOT%\build\ rd /s /q %CYGROOT%\build
+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 ^
+ -addon=equations ^
+ -addon=ltac2 ^
+ -addon=mtac2 ^
+ -addon=mathcomp ^
+ -addon=menhir ^
+ -addon=menhirlib ^
+ -addon=compcert ^
+ -addon=extlib ^
+ -addon=quickchick ^
+ -addon=coquelicot ^
+ -addon=vst ^
+ -addon=aactactics ^
+ -make=N ^
+ -setup %CI_PROJECT_DIR%\%SETUP% || GOTO ErrorCopyLogFilesAndExit
+
+ECHO "Start Artifact Creation"
+TIME /T
+
+mkdir artifacts
+
+CALL :CopyLogFiles
+
+copy "%CYGROOT%\build\coq-local\dev\nsis\*.exe" artifacts || GOTO ErrorExit
+REM The open source archive is only required for release builds
+IF DEFINED WIN_CERTIFICATE_PATH (
+ 7z a artifacts\coq-opensource-archive-windows-%ARCHLONG%.zip %CYGROOT%\build\tarballs\* || GOTO ErrorExit
+) ELSE (
+ REM In non release builds, create a dummy file
+ ECHO "This is not a release build - open source archive not created / uploaded" > artifacts\coq-opensource-info.txt
+)
+
+REM DO NOT echo the signing command below, as this would leak secrets in the logs
+IF DEFINED WIN_CERTIFICATE_PATH (
+ IF DEFINED WIN_CERTIFICATE_PASSWORD (
+ ECHO Signing package
+ @signtool sign /f %WIN_CERTIFICATE_PATH% /p %WIN_CERTIFICATE_PASSWORD% dev\nsis\*.exe
+ signtool verify /pa dev\nsis\*.exe
+ )
+)
+
+ECHO "Finished Artifact Creation"
+TIME /T
+
+CALL :CleanupFolders
+
+ECHO "Finished Cleanup"
+TIME /T
+
+GOTO :EOF
+
+:CopyLogFiles
+ ECHO Copy log files for artifact upload
+ MKDIR artifacts\buildlogs
+ COPY %CYGROOT%\build\buildlogs\* artifacts\buildlogs
+ MKDIR artifacts\filelists
+ COPY %CYGROOT%\build\filelists\* artifacts\filelists
+ MKDIR artifacts\flagfiles
+ COPY %CYGROOT%\build\flagfiles\* artifacts\flagfiles
+ GOTO :EOF
+
+:CleanupFolders
+ ECHO "Cleaning %CYGROOT%"
+ RMDIR /S /Q "%CYGROOT%"
+ ECHO "Cleaning %DESTCOQ%"
+ RMDIR /S /Q "%DESTCOQ%"
+ GOTO :EOF
+
+:MakeUniqueFolder
+ REM Create a uniquely named folder
+ REM This script is safe because folder creation is atomic - either we create it or fail
+ REM %1 = base path or directory (_%RANDOM%_%RANDOM% is appended to this)
+ REM %2 = name of the variable which receives the unique folder name
+ SET "UNIQUENAME=%1_%RANDOM%_%RANDOM%"
+ MKDIR "%UNIQUENAME%"
+ IF ERRORLEVEL 1 GOTO :MakeUniqueFolder
+ SET "%2=%UNIQUENAME%"
+ GOTO :EOF
+
+:ErrorCopyLogFilesAndExit
+ CALL :CopyLogFiles
+ REM fall through
+
+:ErrorExit
+ CALL :CleanupFolders
+ ECHO ERROR %0 failed
+ EXIT /b 1
diff --git a/dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh b/dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh
index be0058b6..d812df3e 100644
--- a/dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh
+++ b/dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh
@@ -1,3 +1,5 @@
+#!/bin/sh
+
if [ "$CI_PULL_REQUEST" = "669" ] || [ "$CI_BRANCH" = "ssr-merge" ]; then
mathcomp_CI_REF=ssr-merge
mathcomp_CI_GITURL=https://github.com/maximedenes/math-comp
diff --git a/dev/ci/user-overlays/07085-ppedrot-pure-sharing-flag.sh b/dev/ci/user-overlays/07085-ppedrot-pure-sharing-flag.sh
new file mode 100644
index 00000000..575df074
--- /dev/null
+++ b/dev/ci/user-overlays/07085-ppedrot-pure-sharing-flag.sh
@@ -0,0 +1,8 @@
+_OVERLAY_BRANCH=pure-sharing-flag
+
+if [ "$CI_PULL_REQUEST" = "7085" ] || [ "$CI_BRANCH" = "$_OVERLAY_BRANCH" ]; then
+
+ mtac2_CI_BRANCH="$_OVERLAY_BRANCH"
+ mtac2_CI_GITURL=https://github.com/ppedrot/Mtac2
+
+fi
diff --git a/dev/ci/user-overlays/README.md b/dev/ci/user-overlays/README.md
index b8628979..68afe7ee 100644
--- a/dev/ci/user-overlays/README.md
+++ b/dev/ci/user-overlays/README.md
@@ -1,6 +1,8 @@
# Add overlays for your pull requests in this directory
-An overlay is a file containing very simple logic to test whether we are currently building a specific pull request or git branch (useful so that overlays work on your own fork) and which changes some of the variables whose default can be found in [`ci-basic-overlay.sh`](/dev/ci/ci-basic-overlay.sh).
+When your pull request breaks an external project we test in our CI and you
+have prepared a branch with the fix, you can add an "overlay" to your pull
+request to test it with the adapted version of the external project.
An overlay is a file which defines where to look for the patched version so that
testing is possible. It redefines some variables from
@@ -22,10 +24,12 @@ and the branch name), then a `.sh` extension (`[0-9]{5}-[a-zA-Z0-9-_]+.sh`).
Example: `00669-maximedenes-ssr-merge.sh` containing
```
+#!/bin/sh
+
if [ "$CI_PULL_REQUEST" = "669" ] || [ "$CI_BRANCH" = "ssr-merge" ]; then
mathcomp_CI_REF=ssr-merge
mathcomp_CI_GITURL=https://github.com/maximedenes/math-comp
fi
```
-(`CI_PULL_REQUEST` and `CI_BRANCH` are set in [`ci-common.sh`](/dev/ci/ci-common.sh))
+(`CI_PULL_REQUEST` and `CI_BRANCH` are set in [`ci-common.sh`](../ci-common.sh))
diff --git a/dev/core.dbg b/dev/core.dbg
index 57c13690..972ba701 100644
--- a/dev/core.dbg
+++ b/dev/core.dbg
@@ -2,8 +2,8 @@ source camlp5.dbg
load_printer threads.cma
load_printer str.cma
load_printer clib.cma
-load_printer lib.cma
load_printer dynlink.cma
+load_printer lib.cma
load_printer kernel.cma
load_printer library.cma
load_printer engine.cma
@@ -16,5 +16,4 @@ load_printer tactics.cma
load_printer vernac.cma
load_printer stm.cma
load_printer toplevel.cma
-load_printer intf.cma
load_printer ltac_plugin.cmo
diff --git a/dev/doc/MERGING.md b/dev/doc/MERGING.md
new file mode 100644
index 00000000..000f21c2
--- /dev/null
+++ b/dev/doc/MERGING.md
@@ -0,0 +1,136 @@
+# Merging changes in Coq
+
+This document describes how patches, submitted as pull requests (PRs) on the
+`master` branch, should be merged into the main repository
+(https://github.com/coq/coq).
+
+## Code owners
+
+The [CODEOWNERS](../../.github/CODEOWNERS) file describes, for each part of the
+system, two owners. One is the principal maintainer of the component, the other
+is the secondary maintainer.
+
+When a PR is submitted, GitHub will automatically ask the principal
+maintainer for a review. If the PR touches several parts, all the
+corresponding principal maintainers will be asked for a review.
+
+Maintainers are never assigned as reviewer on their own PRs.
+
+If a principal maintainer submits a PR that changes the component they own, they
+must assign the secondary maintainer as reviewer. They should also do it if they
+know they are not available to do the review.
+
+## Reviewing
+
+When maintainers receive a review request, they are expected to:
+
+* Put their name in the assignee field, if they are in charge of the component
+ that is the main target of the patch (or if they are the only maintainer asked
+ to review the PR).
+* Review the PR, approve it or request changes.
+* If they are the assignee, check if all reviewers approved the PR. If not,
+ regularly ping the author (if changes should be implemented) or the reviewers
+ (if reviews are missing). The assignee ensures that any requests for more
+ discussion have been granted. When the discussion has converged and ALL
+ REVIEWERS(*) have approved the PR, the assignee is expected to follow the merging
+ process described below.
+
+In all cases, maintainers can delegate reviews to the other maintainer of the
+same component, except if it would lead to a maintainer reviewing their own
+patch.
+
+A maintainer is expected to be reasonably reactive, but no specific timeframe is
+given for reviewing.
+
+(*) In case a component is touched in a trivial way (adding/removing one file in
+a `Makefile`, etc), or by applying a systematic refactoring process (global
+renaming for instance) that has been reviewed globally, the assignee can
+say in a comment they think a review is not required and proceed with the merge.
+
+### Breaking changes
+
+If the PR breaks compatibility of some external projects in CI, then fixes to
+those external projects should have been prepared (cf. the relevant sub-section
+in the [CI README](../ci/README.md#Breaking-changes) and the PR can be tested
+with these fixes thanks to ["overlays"](../ci/user-overlays/README.md).
+
+Moreover the PR must absolutely update the [`CHANGES.md`](../../CHANGES.md) file.
+
+If overlays are missing, ask the author to prepare them and label the PR with
+the [needs: overlay](https://github.com/coq/coq/labels/needs%3A%20overlay) label.
+
+When fixes are ready, there are two cases to consider:
+
+- For patches that are backward compatible (best scenario), you should get the
+ external project maintainers to integrate them before merging the PR.
+- For patches that are not backward compatible (which is often the case when
+ patching plugins after an update to the Coq API), you can proceed to merge
+ the PR and then notify the external project maintainers they can merge the
+ patch.
+
+## Merging
+
+Once all reviewers approved the PR, the assignee is expected to check that CI
+completed without relevant failures, and that the PR comes with appropriate
+documentation and test cases. If not, they should leave a comment on the PR and
+put the approriate label. Otherwise, they are expected to merge the PR using the
+[merge script](../tools/merge-pr.sh).
+
+When CI has a few failures which look spurious, restarting the corresponding
+jobs is a good way of ensuring this was indeed the case.
+To restart a job on Travis, you should connect using your GitHub account;
+being part of the Coq organization on GitHub should give you the permission
+to do so.
+To restart a job on GitLab CI, you should sign into GitLab (this can be done
+using a GitHub account); if you are part of the
+[Coq organization on GitLab](https://gitlab.com/coq), you should see a "Retry"
+button; otherwise, send a request to join the organization.
+
+When the PR has conflicts, the assignee can either:
+- ask the author to rebase the branch, fixing the conflicts
+- warn the author that they are going to rebase the branch, and push to the
+ branch directly
+
+In both cases, CI should be run again.
+
+In some rare cases (e.g. the conflicts are in the `CHANGES.md` file), it is ok to fix
+the conflicts in the merge commit (following the same steps as below), and push
+to `master` directly. Don't use the GitHub interface to fix these conflicts.
+
+To merge the PR proceed in the following way
+```
+$ git checkout master
+$ git pull
+$ dev/tools/merge-pr.sh XXXX
+$ git push upstream
+```
+where `XXXX` is the number of the PR to be merged and `upstream` is the name
+of your remote pointing to `git@github.com:coq/coq.git`.
+Note that you are only supposed to merge PRs into `master`. PRs should rarely
+target the stable branch, but when it is the case they are the responsibility
+of the release manager.
+
+This script conducts various checks before proceeding to merge. Don't bypass them
+without a good reason to, and in that case, write a comment in the PR thread to
+explain the reason.
+
+Maintainers MUST NOT merge their own patches.
+
+DON'T USE the GitHub interface for merging, since it will prevent the automated
+backport script from operating properly, generates bad commit messages, and a
+messy history when there are conflicts.
+
+### Merge script dependencies
+
+The merge script passes option `-S` to `git merge` to ensure merge commits
+are signed. Consequently, it depends on the GnuPG command utility being
+installed and a GPG key being available. Here is a short documentation on
+how to use GPG, git & GitHub: https://help.github.com/articles/signing-commits-with-gpg/.
+
+The script depends on a few other utilities. If you are a Nix user, the
+simplest way of getting them is to run `nix-shell` first.
+
+**Note for homebrew (MacOS) users:** it has been reported that installing GnuPG
+is not out of the box. Installing explicitly "pinentry-mac" seems important for
+typing of passphrase to work correctly (see also this
+[Stack Overflow Q-and-A](https://stackoverflow.com/questions/39494631/gpg-failed-to-sign-the-data-fatal-failed-to-write-commit-object-git-2-10-0)).
diff --git a/dev/doc/README.md b/dev/doc/README.md
new file mode 100644
index 00000000..223cf628
--- /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, is 4.07.0.
+# The latest version number is available at: https://ocaml.org/releases/
+
+$ opam init --comp
+
+# 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)
+
+
+
+$ make -j $JOBS states # builds just enough to run coqtop
+$ bin/coqtop -compile
+
+
+
+```
+
+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 ab78b095..ca73cd63 100644
--- a/dev/doc/changes.md
+++ b/dev/doc/changes.md
@@ -1,3 +1,205 @@
+## Changes between Coq 8.8 and Coq 8.9
+
+### ML API
+
+Names
+
+- In `Libnames`, the type `reference` and its two constructors `Qualid` and
+ `Ident` have been removed in favor of `qualid`. `Qualid` is now the identity,
+ `Ident` can be replaced by `qualid_of_ident`. Matching over `reference` can be
+ replaced by a test using `qualid_is_ident`. Extracting the `ident` part of a
+ `qualid` can be done using `qualid_basename`.
+
+Misctypes
+
+- Syntax for universe sorts and kinds has been moved from `Misctypes`
+ to `Glob_term`, as these are turned into kernel terms by
+ `Pretyping`.
+
+Proof engine
+
+- More functions have been changed to use `EConstr`, notably the
+ functions in `Evd`, and in particular `Evd.define`.
+
+ Note that the core function `EConstr.to_constr` now _enforces_ by
+ default that the resulting term is ground, that is to say, free of
+ Evars. This is usually what you want, as open terms should be of
+ type `EConstr.t` to benefit from the invariants the `EConstr` API is
+ meant to guarantee.
+
+ In case you'd like to violate this API invariant, you can use the
+ `abort_on_undefined_evars` flag to `EConstr.to_constr`, but note
+ that setting this flag to false is deprecated so it is only meant to
+ be used as to help port pre-EConstr code.
+
+- A few type alias have been deprecated, in all cases the message
+ should indicate what the canonical form is. An important change is
+ the move of `Globnames.global_reference` to `Names.GlobRef.t`.
+
+- Unification API returns `evar_map option` instead of `bool * evar_map`
+ with the guarantee that the `evar_map` was unchanged if the boolean
+ was false.
+
+ML Libraries used by Coq
+
+- Introduction of a `Smart` module for collecting `smart*` functions, e.g.
+ `Array.Smart.map`.
+- Uniformization of some names, e.g. `Array.Smart.fold_left_map` instead
+ of `Array.smartfoldmap`.
+
+Printer.ml API
+
+- The mechanism in `Printer` that allowed dynamically overriding `pr_subgoals`,
+ `pr_subgoal` and `pr_goal` was removed to simplify the code. It was
+ earlier 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
+ few interfaces files. The `intf` folder is gone, and now for example
+ `Constrexpr` is located in `interp/`, `Vernacexpr` in `vernac/` and
+ so on. Changes should be compatible, but in a few cases stricter
+ layering requirements may mean that functions have moved. In all
+ cases adapting is a matter of changing the module name.
+
+Vernacular commands
+
+- The implementation of vernacular commands has been refactored so it
+ is self-contained now, including the parsing and extension
+ mechanisms. This involves a couple of non-backward compatible
+ changes due to layering issues, where some functions have been moved
+ from `Pcoq` to `Pvernac` and from `Vernacexpr` to modules in
+ `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`).
+
+Parsing
+
+- Manual uses of the `Pcoq.Gram` module have been deprecated. Wrapper modules
+ `Pcoq.Entry` and `Pcoq.Parsable` were introduced to replace it.
+
+Termops
+
+- Internal printing functions have been placed under the
+ `Termops.Internal` namespace.
+
+### 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
@@ -16,7 +218,7 @@ All the other bugs kept their number.
General deprecation
-- All functions marked [@@ocaml.deprecated] in 8.7 have been
+- All functions marked `[@@ocaml.deprecated]` in 8.7 have been
removed. Please, make sure your plugin is warning-free in 8.7 before
trying to port it over 8.8.
@@ -44,8 +246,8 @@ We changed the type of the following functions:
- `Global.body_of_constant`: same as above.
-- `Constrinterp.*` generally, many functions that used to take an
- `evar_map ref` have been now switched to functions that will work in
+- `Constrinterp.*`: generally, many functions that used to take an
+ `evar_map ref` have now been switched to functions that will work in
a functional way. The old style of passing `evar_map`s as references
is not supported anymore.
@@ -63,16 +265,21 @@ We have changed the representation of the following types:
Some tactics and related functions now support static configurability, e.g.:
-- injectable, dEq, etc. takes an argument ~keep_proofs which,
- - if None, tells to behave as told with the flag Keep Proof Equalities
- - if Some b, tells to keep proof equalities iff b is true
+- `injectable`, `dEq`, etc. take an argument `~keep_proofs` which,
+ - if `None`, tells to behave as told with the flag `Keep Proof Equalities`
+ - if `Some b`, tells to keep proof equalities iff `b` is true
Declaration of printers for arguments used only in vernac command
-- It should now use "declare_extra_vernac_genarg_pprule" rather than
- "declare_extra_genarg_pprule", otherwise, a failure at runtime might
+- It should now use `declare_extra_vernac_genarg_pprule` rather than
+ `declare_extra_genarg_pprule`, otherwise, a failure at runtime might
happen. An alternative is to register the corresponding argument as
- a value, using "Geninterp.register_val0 wit None".
+ a value, using `Geninterp.register_val0 wit None`.
+
+Types Alias deprecation and type relocation.
+
+- A few type alias have been deprecated, in all cases the message
+ should indicate what the canonical form is.
### STM API
@@ -110,7 +317,7 @@ functions when some given constants are traversed:
* `declare_reduction_effect`: to declare a hook to be applied when some
constant are visited during the execution of some reduction functions
- (primarily cbv).
+ (primarily `cbv`).
* `set_reduction_effect`: to declare a constant on which a given effect
hook should be called.
diff --git a/dev/doc/coq-src-description.txt b/dev/doc/coq-src-description.txt
index b3d49b7e..764d4829 100644
--- a/dev/doc/coq-src-description.txt
+++ b/dev/doc/coq-src-description.txt
@@ -17,12 +17,6 @@ toplevel
Special components
------------------
-intf :
-
- Contains mli-only interfaces, many of them providing a.s.t.
- used for dialog bewteen coq components. Ex: Constrexpr.constr_expr
- produced by parsing and transformed by interp.
-
grammar :
Camlp5 syntax extensions. The file grammar/grammar.cma is used
diff --git a/dev/doc/critical-bugs b/dev/doc/critical-bugs
new file mode 100644
index 00000000..8d78559c
--- /dev/null
+++ b/dev/doc/critical-bugs
@@ -0,0 +1,262 @@
+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
+
+ component: universe polymorphism
+ summary: universe polymorphism can capture global universes
+ impacted released versions: V8.5 to V8.8
+ impacted coqchk versions: V8.5 to current (NOT FIXED)
+ fixed in: 2385b5c1ef
+ found by: Gaëtan Gilbert
+ exploit: test-suite/misc/poly-capture-global-univs
+ GH issue number: #8341
+ risk: unlikely to be activated by chance (requires a plugin)
+
+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/proof-engine.md b/dev/doc/proof-engine.md
index 8f96ac22..77455223 100644
--- a/dev/doc/proof-engine.md
+++ b/dev/doc/proof-engine.md
@@ -42,8 +42,8 @@ goal holes thanks to the `Refine` module, and in particular to the
`Refine.refine` primitive.
```ocaml
-val refine : typecheck:bool -> Constr.t Sigma.run -> unit tactic
-(** In [refine typecheck t], [t] is a term with holes under some
+val refine : typecheck:bool -> (Evd.evar_map -> Evd.evar_map * EConstr.t) -> unit tactic
+(** In [refine ~typecheck t], [t] is a term with holes under some
[evar_map] context. The term [t] is used as a partial solution
for the current goal (refine is a goal-dependent tactic), the
new holes created by [t] become the new subgoals. Exceptions
@@ -51,12 +51,11 @@ val refine : typecheck:bool -> Constr.t Sigma.run -> unit tactic
tactic failures. If [typecheck] is [true] [t] is type-checked beforehand. *)
```
-In a first approximation, we can think of `'a Sigma.run` as
-`evar_map -> 'a * evar_map`. What the function does is first evaluate the
-`Constr.t Sigma.run` argument in the current proof state, and then use the
-resulting term as a filler for the proof under focus. All evars that have been
-created by the invocation of this thunk are then turned into new goals added in
-the order of their creation.
+What the function does is first evaluate the `t` argument in the
+current proof state, and then use the resulting term as a filler for
+the proof under focus. All evars that have been created by the
+invocation of this thunk are then turned into new goals added in the
+order of their creation.
To see how we can use it, let us have a look at an idealized example, the `cut`
tactic. Assuming `X` is a type, `cut X` fills the current goal `[Γ ⊢ _ : A]`
@@ -66,8 +65,7 @@ two new holes `[e1, e2]` are added to the goal state in this order.
```ocaml
let cut c =
- let open Sigma in
- Proofview.Goal.nf_enter { enter = begin fun gl ->
+ Proofview.Goal.enter begin fun gl ->
(** In this block, we focus on one goal at a time indicated by gl *)
let env = Proofview.Goal.env gl in
(** Get the context of the goal, essentially [Γ] *)
@@ -80,25 +78,22 @@ let cut c =
let t = mkArrow c (Vars.lift 1 concl) in
(** Build [X -> A]. Note the lifting of [A] due to being on the right hand
side of the arrow. *)
- Refine.refine { run = begin fun sigma ->
+ Refine.refine begin fun sigma ->
(** All evars generated by this block will be added as goals *)
- let Sigma (f, sigma, p) = Evarutil.new_evar env sigma t in
+ let sigma, f = Evarutil.new_evar env sigma t in
(** Generate ?e1 : [Γ ⊢ _ : X -> A], add it to sigma, and return the
term [f := Γ ⊢ ?e1{Γ} : X -> A] with the updated sigma. The identity
substitution for [Γ] is extracted from the [env] argument, so that
one must be careful to pass the correct context here in order for the
resulting term to be well-typed. The [p] return value is a proof term
used to enforce sigma monotonicity. *)
- let Sigma (x, sigma, q) = Evarutil.new_evar env sigma c in
+ let sigma, x = Evarutil.new_evar env sigma c in
(** Generate ?e2 : [Γ ⊢ _ : X] in sigma and return
[x := Γ ⊢ ?e2{Γ} : X]. *)
let r = mkLetIn (Name id, x, c, mkApp (Vars.lift 1 r, [|mkRel 1|])) in
(** Build [r := Γ ⊢ let id : X := ?e2{Γ} in ?e1{Γ} id : A] *)
- Sigma (r, sigma, p +> q)
- (** Fills the current hole with [r]. The [p +> q] thingy ensures
- monotonicity of sigma. *)
- end }
- end }
+ end
+ end
```
The `Evarutil.new_evar` function is the preferred way to generate evars in
diff --git a/dev/doc/release-process.md b/dev/doc/release-process.md
new file mode 100644
index 00000000..b33a1cbd
--- /dev/null
+++ b/dev/doc/release-process.md
@@ -0,0 +1,128 @@
+# Release process #
+
+## As soon as the previous version branched off master ##
+
+- [ ] Create a new issue to track the release process where you can copy-paste
+ the present checklist.
+- [ ] Change the version name to the next major version and the magic numbers
+ (see [#7008](https://github.com/coq/coq/pull/7008/files)).
+- [ ] Update the compatibility infrastructure, which consists of doing
+ the following steps. Note that all but the final step can be
+ performed automatically by
+ [`dev/tools/update-compat.py`](/dev/tools/update-compat.py) so
+ long as you have already updated `coq_version` in
+ [`configure.ml`](/configure.ml).
+ + [ ] Add a file `theories/Compat/CoqXX.v` which contains just the header
+ from [`dev/header.ml`](/dev/header.ml)
+ + [ ] Add the line `Require Export Coq.Compat.CoqXX.` at the top of
+ `theories/Compat/CoqYY.v`, where Y.Y is the version prior to X.X.
+ + [ ] Delete the file `theories/Compat/CoqWW.v`, where W.W is three versions
+ prior to X.X.
+ + [ ] Update
+ [`doc/stdlib/index-list.html.template`](/doc/stdlib/index-list.html.template)
+ with the deleted/added files.
+ + [ ] Remove any notations in the standard library which have `compat "W.W"`.
+ + [ ] Update the type `compat_version` in [`lib/flags.ml`](/lib/flags.ml) by
+ bumping all the version numbers by one, and update the interpretations
+ of those flags in [`toplevel/coqargs.ml`](/toplevel/coqargs.ml) and
+ [`vernac/g_vernac.mlg`](/vernac/g_vernac.mlg).
+ + [ ] Update the files
+ [`test-suite/success/CompatCurrentFlag.v`](/test-suite/success/CompatCurrentFlag.v),
+ [`test-suite/success/CompatPreviousFlag.v`](/test-suite/success/CompatPreviousFlag.v),
+ and
+ [`test-suite/success/CompatOldFlag.v`](/test-suite/success/CompatOldFlag.v)
+ by bumping all version numbers by 1.
+ + [ ] Decide what to do about all test-suite files which mention `-compat
+ W.W` or `Coq.Comapt.CoqWW` (which is no longer valid, since we only
+ keep compatibility against the two previous versions)
+- [ ] Put the corresponding alpha tag using `git tag -s`.
+ The `VX.X+alpha` tag marks the first commit to be in `master` and not in the
+ branch of the previous version.
+- [ ] Create the `X.X+beta1` milestone if it did not already exist.
+- [ ] Decide the release calendar with the team (freeze date, beta date, final
+ release date) and put this information in the milestone (using the
+ description and due date fields).
+
+## About one month before the beta ##
+
+- [ ] Create the `X.X.0` milestone and set its due date.
+- [ ] Send an announcement of the upcoming freeze on Coqdev and ask people to
+ remove from the beta milestone what they already know won't be ready on time
+ (possibly postponing to the `X.X.0` milestone for minor bug fixes,
+ infrastructure and documentation updates).
+- [ ] Determine which issues should / must be fixed before the beta, add them
+ to the beta milestone, possibly with a
+ ["priority: blocker"](https://github.com/coq/coq/labels/priority%3A%20blocker)
+ label. Make sure that all these issues are assigned (and that the assignee
+ provides an ETA).
+- [ ] Ping the development coordinator (**@mattam82**) to get him started on
+ the update to the Credits chapter of the reference manual.
+ See also [#7058](https://github.com/coq/coq/issues/7058).
+ The command to get the list of contributors for this version is
+ `git shortlog -s -n VX.X+alpha..master | cut -f2 | sort -k 2`
+ (the ordering is approximative as it will misplace people with middle names).
+
+## On the date of the feature freeze ##
+
+- [ ] Create the new version branch `vX.X` and
+ [protect it](https://github.com/coq/coq/settings/branches)
+ (activate the "Protect this branch", "Require pull request reviews before
+ merging" and "Restrict who can push to this branch" guards).
+- [ ] Remove all remaining unmerged feature PRs from the beta milestone.
+- [ ] Start a new project to track PR backporting. The proposed model is to
+ have a "X.X-only PRs" column for the rare PRs on the stable branch, a
+ "Request X.X inclusion" column for the PRs that were merged in `master` that
+ are to be considered for backporting, a "Waiting for CI" column to put the
+ PRs in the process of being backported, and "Shipped in ..." columns to put
+ what was backported. (The release manager is the person responsible for
+ merging PRs that target the version branch and backporting appropriate PRs
+ that are merged into `master`).
+ A message to **@coqbot** in the milestone description tells it to
+ automatically add merged PRs to the "Request X.X inclusion" column.
+- [ ] Delay non-blocking issues to the appropriate milestone and ensure
+ blocking issues are solved. If required to solve some blocking issues,
+ it is possible to revert some feature PRs in the version branch only.
+
+## Before the beta release date ##
+
+- [ ] Ensure the Credits chapter has been updated.
+- [ ] Ensure that an appropriate version of the plugins we will distribute with
+ Coq has been tagged.
+- [ ] Have some people test the recently auto-generated Windows and MacOS
+ packages.
+- [ ] Change the version name from alpha to beta1 (see
+ [#7009](https://github.com/coq/coq/pull/7009/files)).
+ We generally do not update the magic numbers at this point.
+- [ ] Put the `VX.X+beta1` tag using `git tag -s`.
+
+### These steps are the same for all releases (beta, final, patch-level) ###
+
+- [ ] Send an e-mail on Coqdev announcing that the tag has been put so that
+ package managers can start preparing package updates.
+- [ ] Draft a release on GitHub.
+- [ ] Get **@maximedenes** to sign the Windows and MacOS packages and
+ upload them on GitHub.
+- [ ] Prepare a page of news on the website with the link to the GitHub release
+ (see [coq/www#63](https://github.com/coq/www/pull/63)).
+- [ ] Upload the new version of the reference manual to the website.
+ *TODO: setup some continuous deployment for this.*
+- [ ] Merge the website update, publish the release
+ and send annoucement e-mails.
+- [ ] Ping **@Zimmi48** to publish a new version on Zenodo.
+ *TODO: automate this.*
+- [ ] Close the milestone
+
+## At the final release time ##
+
+- [ ] Change the version name to X.X.0 and the magic numbers (see
+ [#7271](https://github.com/coq/coq/pull/7271/files)).
+- [ ] Put the `VX.X.0` tag.
+
+Repeat the generic process documented above for all releases.
+
+- [ ] Switch the default version of the reference manual on the website.
+
+## At the patch-level release time ##
+
+We generally do not update the magic numbers at this point (see
+[`2881a18`](https://github.com/coq/coq/commit/2881a18)).
diff --git a/dev/doc/setup.txt b/dev/doc/setup.txt
deleted file mode 100644
index c48c2d5d..00000000
--- 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 , 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:
-
- customize-group merlin
-
- 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 .
-
-If you want to jump back, type:
-
-If you want to learn the type of the value at current cursor's position, type:
-
-
-Enabling auto-completion in emacs
----------------------------------
-
-In Emacs, type: list-packages
-
-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 .
-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 "") 'ocamldebug-break)
- (global-set-key (kbd "") 'ocamldebug-run)
- (global-set-key (kbd "") 'ocamldebug-next)
- (global-set-key (kbd "") 'ocamldebug-step)
- (global-set-key (kbd "") 'ocamldebug-finish)
- (global-set-key (kbd "") 'ocamldebug-print)
- (global-set-key (kbd "") '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:
-
- ../bin/coqtop.byte ../dev/ocamldebug-coq
-
-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 you set a breakpoint to the cursor's position.
- 6. By pressing you start the bin/coqtop process.
- 7. Then you can:
- - step over function calls:
- - step into function calls:
- - or finish execution of the current function until it returns: .
-
-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 5b372c96..00000000
--- 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](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](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 3867d4af..8f9c3171 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 b35571e9..48671c03 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/lint-repository.sh b/dev/lint-repository.sh
index ee9c8777..cd09b6d3 100755
--- a/dev/lint-repository.sh
+++ b/dev/lint-repository.sh
@@ -31,4 +31,6 @@ fi
find . "(" -path ./.git -prune ")" -o -type f -print0 |
xargs -0 dev/tools/check-eof-newline.sh || CODE=1
+dev/tools/check-overlays.sh || CODE=1
+
exit $CODE
diff --git a/dev/ocamldebug-coq.run b/dev/ocamldebug-coq.run
index f3e60ede..bccd3fef 100644
--- a/dev/ocamldebug-coq.run
+++ b/dev/ocamldebug-coq.run
@@ -14,18 +14,26 @@
export CAML_LD_LIBRARY_PATH=$COQTOP/kernel/byterun:$CAML_LD_LIBRARY_PATH
-exec $OCAMLDEBUG \
+GUESS_CHECKER=
+for arg in "$@"; do
+ if [ "${arg##*/}" = coqchk.byte ]; then
+ GUESS_CHECKER=1
+ fi
+done
+
+if [ -z "$GUESS_CHECKER" ]; then
+ exec $OCAMLDEBUG \
-I $CAMLP5LIB -I +threads \
-I $COQTOP \
-I $COQTOP/config -I $COQTOP/printing -I $COQTOP/grammar -I $COQTOP/clib \
- -I $COQTOP/lib -I $COQTOP/intf -I $COQTOP/kernel -I $COQTOP/kernel/byterun \
+ -I $COQTOP/lib -I $COQTOP/kernel -I $COQTOP/kernel/byterun \
-I $COQTOP/library -I $COQTOP/engine \
-I $COQTOP/pretyping -I $COQTOP/parsing -I $COQTOP/vernac \
-I $COQTOP/interp -I $COQTOP/proofs -I $COQTOP/tactics -I $COQTOP/stm \
-I $COQTOP/toplevel -I $COQTOP/dev -I $COQTOP/config -I $COQTOP/ltac \
-I $COQTOP/plugins/cc -I $COQTOP/plugins/dp \
-I $COQTOP/plugins/extraction -I $COQTOP/plugins/field \
- -I $COQTOP/plugins/firstorder -I $COQTOP/plugins/fourier \
+ -I $COQTOP/plugins/firstorder \
-I $COQTOP/plugins/funind -I $COQTOP/plugins/groebner \
-I $COQTOP/plugins/interface -I $COQTOP/plugins/micromega \
-I $COQTOP/plugins/omega -I $COQTOP/plugins/quote \
@@ -35,3 +43,11 @@ exec $OCAMLDEBUG \
-I $COQTOP/plugins/xml -I $COQTOP/plugins/ltac \
-I $COQTOP/ide \
"$@"
+else
+ exec $OCAMLDEBUG \
+ -I $CAMLP5LIB -I +threads \
+ -I $COQTOP \
+ -I $COQTOP/config -I $COQTOP/clib \
+ -I $COQTOP/lib -I $COQTOP/checker \
+ "$@"
+fi
diff --git a/dev/tools/backport-pr.sh b/dev/tools/backport-pr.sh
index e4359f70..9864fd4d 100755
--- a/dev/tools/backport-pr.sh
+++ b/dev/tools/backport-pr.sh
@@ -1,11 +1,34 @@
#!/usr/bin/env bash
-# Usage: dev/tools/backport-pr.sh [--stop-before-merging]
-
set -e
-PRNUM=$1
-OPTION=$2
+if [[ $# == 0 ]]; then
+ echo "Usage: $0 [--no-conflict] [--no-signature-check] [--stop-before-merging] prnum"
+ exit 1
+fi
+
+while [[ $# -gt 0 ]]; do
+ case "$1" in
+ --no-conflict)
+ NO_CONFLICTS="true"
+ shift
+ ;;
+ --no-signature-check)
+ NO_SIGNATURE_CHECK="true"
+ shift
+ ;;
+ --stop-before-merging)
+ STOP_BEFORE_MERGING="true"
+ shift
+ ;;
+ *)
+ if [[ "$PRNUM" != "" ]]; then
+ echo "PRNUM was already set to $PRNUM and is now being overridden with $1."
+ fi
+ PRNUM="$1"
+ shift
+ esac
+done
if ! git log master --grep "Merge PR #${PRNUM}" | grep "." > /dev/null; then
echo "PR #${PRNUM} does not exist."
@@ -14,7 +37,7 @@ fi
SIGNATURE_STATUS=$(git log master --grep "Merge PR #${PRNUM}" --format="%G?")
git log master --grep "Merge PR #${PRNUM}" --format="%GG"
-if [[ "${SIGNATURE_STATUS}" != "G" ]]; then
+if [[ "$NO_SIGNATURE_CHECK" != "true" && "$SIGNATURE_STATUS" != "G" ]]; then
echo
read -p "Merge commit does not have a good (valid) signature. Bypass? [y/N] " -n 1 -r
echo
@@ -27,9 +50,17 @@ BRANCH=backport-pr-${PRNUM}
RANGE=$(git log master --grep "Merge PR #${PRNUM}" --format="%P" | sed 's/ /../')
MESSAGE=$(git log master --grep "Merge PR #${PRNUM}" --format="%s" | sed 's/Merge/Backport/')
-if git checkout -b ${BRANCH}; then
+if git checkout -b "${BRANCH}"; then
- if ! git cherry-pick -x ${RANGE}; then
+ if ! git cherry-pick -x "${RANGE}"; then
+ if [[ "$NO_CONFLICTS" == "true" ]]; then
+ git status
+ echo "Conflicts! Aborting..."
+ git cherry-pick --abort
+ git checkout -
+ git branch -d "$BRANCH"
+ exit 1
+ fi
echo "Please fix the conflicts, then exit."
bash
while ! git cherry-pick --continue; do
@@ -50,7 +81,7 @@ else
fi
-if ! git diff --exit-code HEAD ${BRANCH} -- "*.mli"; then
+if ! git diff --exit-code HEAD "${BRANCH}" -- "*.mli"; then
echo
read -p "Some mli files are modified. Bypass? [y/N] " -n 1 -r
echo
@@ -59,12 +90,12 @@ if ! git diff --exit-code HEAD ${BRANCH} -- "*.mli"; then
fi
fi
-if [[ "${OPTION}" == "--stop-before-merging" ]]; then
+if [[ "$STOP_BEFORE_MERGING" == "true" ]]; then
exit 0
fi
-git merge -S --no-ff ${BRANCH} -m "${MESSAGE}"
-git branch -d ${BRANCH}
+git merge -S --no-ff "${BRANCH}" -m "${MESSAGE}"
+git branch -d "${BRANCH}"
# To-Do:
# - Support for backporting a PR before it is merged
diff --git a/dev/tools/check-overlays.sh b/dev/tools/check-overlays.sh
new file mode 100755
index 00000000..33a9ff05
--- /dev/null
+++ b/dev/tools/check-overlays.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+for f in $(git ls-files "dev/ci/user-overlays/")
+do
+ if ! ([[ "$f" = dev/ci/user-overlays/README.md ]] || [[ "$f" == *.sh ]])
+ then
+ >&2 echo "Bad overlay '$f'."
+ >&2 echo "User overlays need to have extension .sh to be picked up!"
+ exit 1
+ fi
+done
diff --git a/dev/tools/check-owners-pr.sh b/dev/tools/check-owners-pr.sh
new file mode 100755
index 00000000..d2910279
--- /dev/null
+++ b/dev/tools/check-owners-pr.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env sh
+
+usage() {
+ { echo "usage: $0 PR [ARGS]..."
+ echo "A wrapper around check-owners.sh to check owners for a PR."
+ echo "Assumes upstream is the canonical Coq repository."
+ echo "Assumes the PR is against master."
+ echo
+ echo " PR: PR number"
+ echo " ARGS: passed through to check-owners.sh"
+ } >&2
+}
+
+case "$1" in
+ "--help"|"-h")
+ usage
+ if [ $# = 1 ]; then exit 0; else exit 1; fi;;
+ "")
+ usage
+ exit 1;;
+esac
+
+PR="$1"
+shift
+
+# this puts both refs in the FETCH_HEAD file but git rev-parse will use the first
+git fetch upstream "+refs/pull/$PR/head" master
+
+head=$(git rev-parse FETCH_HEAD)
+base=$(git merge-base upstream/master "$head")
+
+git diff --name-only -z "$base" "$head" | xargs -0 dev/tools/check-owners.sh "$@"
diff --git a/dev/tools/check-owners.sh b/dev/tools/check-owners.sh
new file mode 100755
index 00000000..1a97508a
--- /dev/null
+++ b/dev/tools/check-owners.sh
@@ -0,0 +1,138 @@
+#!/usr/bin/env bash
+
+# Determine CODEOWNERS of the files given in argument
+# For a given commit range:
+# git diff --name-only -z COMMIT1 COMMIT2 | xargs -0 dev/tools/check-owners.sh [opts]
+
+# NB: gitignore files will be messed up if you interrupt the script.
+# You should be able to just move the .gitignore.bak files back manually.
+
+usage() {
+ { echo "usage: $0 [--show-patterns] [--owner OWNER] [FILE]..."
+ echo " --show-patterns: instead of printing file names print the matching patterns (more compact)"
+ echo " --owner: show only files/patterns owned by OWNER (use Nobody to see only non-owned files)"
+ } >&2
+}
+
+case "$1" in
+ "--help"|"-h")
+ usage
+ if [ $# = 1 ]; then exit 0; else exit 1; fi
+esac
+
+if ! [ -e .github/CODEOWNERS ]; then
+ >&2 echo "No CODEOWNERS set up or calling from wrong directory."
+ exit 1
+fi
+
+files=()
+show_patterns=false
+
+target_owner=""
+
+while [[ "$#" -gt 0 ]]; do
+ case "$1" in
+ "--show-patterns")
+ show_patterns=true
+ shift;;
+ "--owner")
+ if [[ "$#" = 1 ]]; then
+ >&2 echo "Missing argument to --owner"
+ usage
+ exit 1
+ elif [[ "$target_owner" != "" ]]; then
+ >&2 echo "Only one --owner allowed"
+ usage
+ exit 1
+ fi
+ target_owner="$2"
+ shift 2;;
+ *)
+ files+=("$@")
+ break;;
+ esac
+done
+
+# CODEOWNERS uses .gitignore patterns so we want to use git to parse it
+# The only available tool for that is git check-ignore
+# However it provides no way to use alternate .gitignore files
+# so we rename them temporarily
+
+find . -name .gitignore -print0 | while IFS= read -r -d '' f; do
+ if [ -e "$f.bak" ]; then
+ >&2 echo "$f.bak exists!"
+ exit 1
+ else
+ mv "$f" "$f.bak"
+ fi
+done
+
+# CODEOWNERS is not quite .gitignore patterns:
+# after the pattern is the owner (space separated)
+# git would interpret that as a big pattern containing spaces
+# so we create a valid .gitignore by removing all but the first field
+
+while read -r pat _; do
+ printf '%s\n' "$pat" >> .gitignore
+done < .github/CODEOWNERS
+
+# associative array [file => owner]
+declare -A owners
+
+for f in "${files[@]}"; do
+ data=$(git check-ignore --verbose --no-index "./$f")
+ code=$?
+
+ if [[ "$code" = 1 ]] || ! [[ "$data" =~ .gitignore:.* ]] ; then
+ # no match, or match from non tracked gitignore (eg global gitignore)
+ if [ "$target_owner" != "" ] && [ "$target_owner" != Nobody ] ; then
+ owner=""
+ else
+ owner="Nobody"
+ pat="$f" # no patterns for unowned files
+ fi
+ else
+ # data looks like [.gitignore:$line:$pattern $file]
+ # extract the line to look it up in CODEOWNERS
+ data=${data#'.gitignore:'}
+ line=${data%%:*}
+
+ # NB: supports multiple owners
+ # Does not support secondary owners declared in comment
+ read -r pat fowners < <(sed "${line}q;d" .github/CODEOWNERS)
+
+ owner=""
+ if [ "$target_owner" != "" ]; then
+ for o in $fowners; do # do not quote: multiple owners possible
+ if [ "$o" = "$target_owner" ]; then
+ owner="$o"
+ fi
+ done
+ else
+ owner="$fowners"
+ fi
+ fi
+
+ if [ "$owner" != "" ]; then
+ if $show_patterns; then
+ owners[$pat]="$owner"
+ else
+ owners[$f]="$owner"
+ fi
+ fi
+done
+
+for f in "${!owners[@]}"; do
+ printf '%s: %s\n' "$f" "${owners[$f]}"
+done | sort -k 2 -k 1 # group by owner
+
+# restore gitignore files
+rm .gitignore
+find . -name .gitignore.bak -print0 | while IFS= read -r -d '' f; do
+ base=${f%.bak}
+ if [ -e "$base" ]; then
+ >&2 echo "$base exists!"
+ else
+ mv "$f" "$base"
+ fi
+done
diff --git a/dev/tools/coqdev.el b/dev/tools/coqdev.el
index 62fdaec8..ec72f965 100644
--- a/dev/tools/coqdev.el
+++ b/dev/tools/coqdev.el
@@ -23,7 +23,7 @@
;; If you load this file from a git repository, checking out an old
;; commit will make it disappear and cause errors for your Emacs
-;; startup. To ignore those errors use (require 'coqdev nil t). If you
+;; startup. To ignore those errors use (require 'coqdev nil t). If you
;; check out a malicious commit Emacs startup would allow it to run
;; arbitrary code, to avoid this you can copy coqdev.el to any
;; location and adjust the load path accordingly (of course if you run
@@ -33,7 +33,7 @@
(defun coqdev-default-directory ()
"Return the Coq repository containing `default-directory'."
- (let ((dir (locate-dominating-file default-directory "META.coq")))
+ (let ((dir (locate-dominating-file default-directory "META.coq.in")))
(when dir (expand-file-name dir))))
(defun coqdev-setup-compile-command ()
@@ -103,5 +103,48 @@ Note that this function is executed before _Coqproject is read if it exists."
2 (3 . 4) (5 . 6)))
(add-to-list 'compilation-error-regexp-alist 'coq-backtrace))
+(defvar bug-reference-bug-regexp)
+(defvar bug-reference-url-format)
+(defun coqdev-setup-bug-reference-mode ()
+ "Setup `bug-reference-bug-regexp' and `bug-reference-url-format' for Coq.
+
+This does not enable `bug-reference-mode'."
+ (let ((dir (coqdev-default-directory)))
+ (when dir
+ (setq-local bug-reference-bug-regexp "#\\(?2:[0-9]+\\)")
+ (setq-local bug-reference-url-format "https://github.com/coq/coq/issues/%s"))))
+(add-hook 'hack-local-variables-hook #'coqdev-setup-bug-reference-mode)
+
+(defun coqdev-sphinx-quote-coq-refman-region (left right &optional offset beg end)
+ "Add LEFT and RIGHT around the BEG..END.
+Leave the point after RIGHT. BEG and END default to the bounds
+of the current region. Leave point OFFSET characters after the
+left quote (if OFFSET is nil, leave the point after the right
+quote)."
+ (unless beg
+ (if (region-active-p)
+ (setq beg (region-beginning) end (region-end))
+ (setq beg (point) end nil)))
+ (save-excursion
+ (goto-char (or end beg))
+ (insert right))
+ (save-excursion
+ (goto-char beg)
+ (insert left))
+ (if (and end (not offset)) ;; Second test handles the ::`` case
+ (goto-char (+ end (length left) (length right)))
+ (goto-char (+ beg (or offset (length left))))))
+
+(defun coqdev-sphinx-rst-coq-action ()
+ "Insert a Sphinx role template or quote the current region."
+ (interactive)
+ (pcase (read-char "Command [gntm:`]?")
+ (?g (coqdev-sphinx-quote-coq-refman-region ":g:`" "`"))
+ (?n (coqdev-sphinx-quote-coq-refman-region ":n:`" "`"))
+ (?t (coqdev-sphinx-quote-coq-refman-region ":token:`" "`"))
+ (?m (coqdev-sphinx-quote-coq-refman-region ":math:`" "`"))
+ (?: (coqdev-sphinx-quote-coq-refman-region "::`" "`" 1))
+ (?` (coqdev-sphinx-quote-coq-refman-region "``" "``"))))
+
(provide 'coqdev)
;;; coqdev ends here
diff --git a/dev/tools/merge-pr.sh b/dev/tools/merge-pr.sh
index 9f24960f..320ef6ed 100755
--- a/dev/tools/merge-pr.sh
+++ b/dev/tools/merge-pr.sh
@@ -1,50 +1,210 @@
#!/usr/bin/env bash
set -e
+set -o pipefail
-# This script depends (at least) on git and jq.
-# It should be used like this: dev/tools/merge-pr.sh /PR number/
-
-#TODO: check arguments and show usage if relevant
-
-PR=$1
+API=https://api.github.com/repos/coq/coq
+OFFICIAL_REMOTE_GIT_URL="git@github.com:coq/coq"
+OFFICIAL_REMOTE_HTTPS_URL="github.com/coq/coq"
-CURRENT_LOCAL_BRANCH=$(git rev-parse --abbrev-ref HEAD)
-REMOTE=$(git config --get "branch.$CURRENT_LOCAL_BRANCH.remote")
-git fetch "$REMOTE" "refs/pull/$PR/head"
+# This script depends (at least) on git (>= 2.7) and jq.
+# It should be used like this: dev/tools/merge-pr.sh /PR number/
-API=https://api.github.com/repos/coq/coq
+# Set SLOW_CONF to have the confirmation output wait for a newline
+# E.g. call $ SLOW_CONF= dev/tools/merge-pr.sh /PR number/
+if [ -z ${SLOW_CONF+x} ]; then
+ QUICK_CONF="-n 1"
+else
+ QUICK_CONF=""
+fi
-BASE_BRANCH=$(curl -s "$API/pulls/$PR" | jq -r '.base.label')
+RED="\033[31m"
+RESET="\033[0m"
+GREEN="\033[32m"
+BLUE="\033[34m"
+YELLOW="\033[33m"
+info() {
+ echo -e "${GREEN}info:${RESET} $1 ${RESET}"
+}
+error() {
+ echo -e "${RED}error:${RESET} $1 ${RESET}"
+}
+warning() {
+ echo -e "${YELLOW}warning:${RESET} $1 ${RESET}"
+}
-COMMIT=$(git rev-parse FETCH_HEAD)
-STATUS=$(curl -s "$API/commits/$COMMIT/status" | jq -r '.state')
+check_util() {
+if ! command -v "$1" > /dev/null 2>&1; then
+ error "this script requires the $1 command line utility"
+ exit 1
+fi
+}
-if [ "$BASE_BRANCH" != "coq:$CURRENT_LOCAL_BRANCH" ]; then
- echo "Wrong base branch"
- read -p "Bypass? [y/N] " -n 1 -r
+ask_confirmation() {
+ read -p "Continue anyway? [y/N] " $QUICK_CONF -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
exit 1
fi
+}
+
+check_util jq
+check_util curl
+check_util git
+check_util gpg
+
+# command line parsing
+
+if [ $# != 1 ]; then
+ error "usage: $0 PR-number"
+ exit 1
+fi
+
+if [[ "$1" =~ ^[1-9][0-9]*$ ]]; then
+ PR=$1
+else
+ error "$1 is not a number"
+ exit 1
+fi
+
+# Fetching PR metadata
+
+PRDATA=$(curl -s "$API/pulls/$PR")
+
+TITLE=$(echo "$PRDATA" | jq -r '.title')
+info "title for PR $PR is ${BLUE}$TITLE"
+
+BASE_BRANCH=$(echo "$PRDATA" | jq -r '.base.label')
+info "PR $PR targets branch ${BLUE}$BASE_BRANCH"
+
+CURRENT_LOCAL_BRANCH=$(git rev-parse --abbrev-ref HEAD)
+info "you are merging in ${BLUE}$CURRENT_LOCAL_BRANCH"
+
+REMOTE=$(git config --get "branch.$CURRENT_LOCAL_BRANCH.remote")
+if [ -z "$REMOTE" ]; then
+ error "branch ${BLUE}$CURRENT_LOCAL_BRANCH${RESET} has not associated remote"
+ error "don't know where to fetch the PR from"
+ error "please run: git branch --set-upstream-to=THE_REMOTE/$CURRENT_LOCAL_BRANCH"
+ exit 1
+fi
+REMOTE_URL=$(git remote get-url "$REMOTE" --all)
+if [ "$REMOTE_URL" != "${OFFICIAL_REMOTE_GIT_URL}" ] && \
+ [ "$REMOTE_URL" != "${OFFICIAL_REMOTE_GIT_URL}.git" ] && \
+ [ "$REMOTE_URL" != "https://${OFFICIAL_REMOTE_HTTPS_URL}" ] && \
+ [ "$REMOTE_URL" != "https://${OFFICIAL_REMOTE_HTTPS_URL}.git" ] && \
+ [[ "$REMOTE_URL" != "https://"*"@${OFFICIAL_REMOTE_HTTPS_URL}" ]] && \
+ [[ "$REMOTE_URL" != "https://"*"@${OFFICIAL_REMOTE_HTTPS_URL}.git" ]] ; then
+ error "remote ${BLUE}$REMOTE${RESET} does not point to the official Coq repo"
+ error "that is ${BLUE}$OFFICIAL_REMOTE_GIT_URL"
+ error "it points to ${BLUE}$REMOTE_URL${RESET} instead"
+ ask_confirmation
+fi
+info "remote for $CURRENT_LOCAL_BRANCH is ${BLUE}$REMOTE"
+
+info "fetching from $REMOTE the PR"
+git remote update "$REMOTE"
+if ! git ls-remote "$REMOTE" | grep pull >/dev/null; then
+ error "remote $REMOTE is not configured to fetch pull requests"
+ error "run: git config remote.$REMOTE.fetch +refs/pull/*/head:refs/remotes/$REMOTE/pr/*"
+ exit 1
+fi
+git fetch "$REMOTE" "refs/pull/$PR/head"
+COMMIT=$(git rev-parse FETCH_HEAD)
+info "commit for PR $PR is ${BLUE}$COMMIT"
+
+# Sanity check: merge to a different branch
+
+if [ "$BASE_BRANCH" != "coq:$CURRENT_LOCAL_BRANCH" ]; then
+ error "PR requests merge in ${BLUE}$BASE_BRANCH${RESET} but you are merging in ${BLUE}$CURRENT_LOCAL_BRANCH"
+ ask_confirmation
fi;
-if [ "$STATUS" != "success" ]; then
- echo "CI status is \"$STATUS\""
- read -p "Bypass? [y/N] " -n 1 -r
- echo
- if [[ ! $REPLY =~ ^[Yy]$ ]]
- then
- exit 1
- fi
+# Sanity check: the local branch is up-to-date with upstream
+
+LOCAL_BRANCH_COMMIT=$(git rev-parse HEAD)
+UPSTREAM_COMMIT=$(git rev-parse @{u})
+if [ "$LOCAL_BRANCH_COMMIT" != "$UPSTREAM_COMMIT" ]; then
+
+ # Is it just that the upstream branch is behind?
+ # It could just be that we merged other PRs and we didn't push yet
+
+ if git merge-base --is-ancestor -- "$UPSTREAM_COMMIT" "$LOCAL_BRANCH_COMMIT"; then
+ warning "Your branch is ahead of ${REMOTE}."
+ warning "You should see this warning only if you've just merged another PR and did not push yet."
+ ask_confirmation
+ else
+ error "Local branch is not up-to-date with ${REMOTE}."
+ error "Pull before merging."
+ ask_confirmation
+ fi
+fi
+
+# Sanity check: PR has an outdated version of CI
+
+BASE_COMMIT=$(echo "$PRDATA" | jq -r '.base.sha')
+CI_FILES=(".travis.yml" ".gitlab-ci.yml" "appveyor.yml")
+
+if ! git diff --quiet "$BASE_COMMIT" "$LOCAL_BRANCH_COMMIT" -- "${CI_FILES[@]}"
+then
+ warning "This PR didn't run with the latest version of CI."
+ warning "It is probably a good idea to ask for a rebase."
+ read -p "Do you want to see the diff? [Y/n] " $QUICK_CONF -r
+ echo
+ if [[ ! $REPLY =~ ^[Nn]$ ]]
+ then
+ git diff "$BASE_COMMIT" "$LOCAL_BRANCH_COMMIT" -- "${CI_FILES[@]}"
+ fi
+ ask_confirmation
+fi
+
+# Sanity check: CI failed
+
+STATUS=$(curl -s "$API/commits/$COMMIT/status")
+
+if [ "$(echo "$STATUS" | jq -r '.state')" != "success" ]; then
+ error "CI unsuccessful on ${BLUE}$(echo "$STATUS" |
+ jq -r -c '.statuses|map(select(.state != "success"))|map(.context)')"
+ ask_confirmation
fi;
-git merge -S --no-ff FETCH_HEAD -m "Merge PR #$PR: $(curl -s "$API/pulls/$PR" | jq -r '.title')" -e
+# Sanity check: has labels named "needs:"
+
+NEEDS_LABELS=$(echo "$PRDATA" | jq -rc '.labels | map(select(.name | match("needs:"))) | map(.name)')
+if [ "$NEEDS_LABELS" != "[]" ]; then
+ error "needs:something labels still present: ${BLUE}$NEEDS_LABELS"
+ ask_confirmation
+fi
+
+# Sanity check: has milestone
+
+MILESTONE=$(echo "$PRDATA" | jq -rc '.milestone.title')
+if [ "$MILESTONE" = "null" ]; then
+ error "no milestone set, please set one"
+ ask_confirmation
+fi
+
+# Sanity check: has kind
+
+KIND=$(echo "$PRDATA" | jq -rc '.labels | map(select(.name | match("kind:"))) | map(.name)')
+if [ "$KIND" = "[]" ]; then
+ error "no kind:something label set, please set one"
+ ask_confirmation
+fi
+
+# Sanity check: user.signingkey
+if [ -z "$(git config user.signingkey)" ]; then
+ warning "git config user.signingkey is empty"
+ warning "gpg will guess a key out of your git config user.* data"
+fi
+
+info "merging"
+git merge -v -S --no-ff FETCH_HEAD -m "Merge PR #$PR: $TITLE" -e
# TODO: improve this check
-if ! git diff --quiet "$REMOTE/$CURRENT_LOCAL_BRANCH" -- dev/ci; then
- echo "******************************************"
- echo "** WARNING: does this PR have overlays? **"
- echo "******************************************"
+if ! git diff --quiet "$REMOTE/$CURRENT_LOCAL_BRANCH" -- dev/ci/user-overlays; then
+ warning "this PR may have overlays (sorry the check is not perfect)"
+ warning "if it has overlays please check the following:"
+ warning "- each overlay has a corresponding open PR on the upstream repo"
+ warning "- after merging please notify the upstream they can merge the PR"
fi
diff --git a/dev/tools/pre-commit b/dev/tools/pre-commit
index dfa95bac..ad2f2f93 100755
--- a/dev/tools/pre-commit
+++ b/dev/tools/pre-commit
@@ -5,6 +5,8 @@
set -e
+dev/tools/check-overlays.sh
+
if ! git diff --cached --name-only -z | xargs -0 dev/tools/check-eof-newline.sh ||
! git diff-index --check --cached HEAD >/dev/null 2>&1 ;
then
diff --git a/dev/tools/update-compat.py b/dev/tools/update-compat.py
new file mode 100755
index 00000000..7c8b9f02
--- /dev/null
+++ b/dev/tools/update-compat.py
@@ -0,0 +1,341 @@
+#!/usr/bin/env python
+from __future__ import with_statement
+import os, re, sys
+
+# Obtain the absolute path of the script being run. By assuming that
+# the script lives in dev/tools/, and basing all calls on the path of
+# the script, rather than the current working directory, we can be
+# robust to users who choose to run the script from any location.
+SCRIPT_PATH = os.path.dirname(os.path.realpath(__file__))
+ROOT_PATH = os.path.realpath(os.path.join(SCRIPT_PATH, '..', '..'))
+CONFIGURE_PATH = os.path.join(ROOT_PATH, 'configure.ml')
+HEADER_PATH = os.path.join(ROOT_PATH, 'dev', 'header.ml')
+DEFAULT_NUMBER_OF_OLD_VERSIONS = 2
+EXTRA_HEADER = '\n(** Compatibility file for making Coq act similar to Coq v%s *)\n'
+FLAGS_MLI_PATH = os.path.join(ROOT_PATH, 'lib', 'flags.mli')
+FLAGS_ML_PATH = os.path.join(ROOT_PATH, 'lib', 'flags.ml')
+COQARGS_ML_PATH = os.path.join(ROOT_PATH, 'toplevel', 'coqargs.ml')
+G_VERNAC_PATH = os.path.join(ROOT_PATH, 'vernac', 'g_vernac.mlg')
+DOC_INDEX_PATH = os.path.join(ROOT_PATH, 'doc', 'stdlib', 'index-list.html.template')
+BUG_4798_PATH = os.path.join(ROOT_PATH, 'test-suite', 'bugs', 'closed', '4798.v')
+TEST_SUITE_PATHS = tuple(os.path.join(ROOT_PATH, 'test-suite', 'success', i)
+ for i in ('CompatOldOldFlag.v', 'CompatOldFlag.v', 'CompatPreviousFlag.v', 'CompatCurrentFlag.v'))
+TEST_SUITE_DESCRIPTIONS = ('current-minus-three', 'current-minus-two', 'current-minus-one', 'current')
+# sanity check that we are where we think we are
+assert(os.path.normpath(os.path.realpath(SCRIPT_PATH)) == os.path.normpath(os.path.realpath(os.path.join(ROOT_PATH, 'dev', 'tools'))))
+assert(os.path.exists(CONFIGURE_PATH))
+
+def get_header():
+ with open(HEADER_PATH, 'r') as f: return f.read()
+
+HEADER = get_header()
+
+def get_version(cur_version=None):
+ if cur_version is not None: return cur_version
+ with open(CONFIGURE_PATH, 'r') as f:
+ for line in f.readlines():
+ found = re.findall(r'let coq_version = "([0-9]+\.[0-9]+)', line)
+ if len(found) > 0:
+ return found[0]
+ raise Exception("No line 'let coq_version = \"X.X' found in %s" % os.path.relpath(CONFIGURE_PATH, ROOT_PATH))
+
+def compat_name_to_version_name(compat_file_name):
+ assert(compat_file_name.startswith('Coq') and compat_file_name.endswith('.v'))
+ v = compat_file_name[len('Coq'):][:-len('.v')]
+ assert(len(v) == 2 or (len(v) >= 2 and v[0] in ('8', '9'))) # we'll have to change this scheme when we hit Coq 10.*
+ return '%s.%s' % (v[0], v[1:])
+
+def version_name_to_compat_name(v, ext='.v'):
+ return 'Coq%s%s%s' % tuple(v.split('.') + [ext])
+
+# returns (lines of compat files, lines of not compat files
+def get_doc_index_lines():
+ with open(DOC_INDEX_PATH, 'r') as f:
+ lines = f.readlines()
+ return (tuple(line for line in lines if 'theories/Compat/Coq' in line),
+ tuple(line for line in lines if 'theories/Compat/Coq' not in line))
+
+COMPAT_INDEX_LINES, DOC_INDEX_LINES = get_doc_index_lines()
+
+def version_to_int_pair(v):
+ return tuple(map(int, v.split('.')))
+
+def get_known_versions():
+ # We could either get the files from the doc index, or from the
+ # directory list. We assume that the doc index is more
+ # representative. If we wanted to use the directory list, we
+ # would do:
+ # compat_files = os.listdir(os.path.join(ROOT_PATH, 'theories', 'Compat'))
+ compat_files = re.findall(r'Coq[^\.]+\.v', '\n'.join(COMPAT_INDEX_LINES))
+ return tuple(sorted((compat_name_to_version_name(i) for i in compat_files if i.startswith('Coq') and i.endswith('.v')), key=version_to_int_pair))
+
+def get_new_versions(known_versions, **args):
+ if args['cur_version'] in known_versions:
+ assert(known_versions[-1] == args['cur_version'])
+ assert(len(known_versions) == args['number_of_compat_versions'])
+ return known_versions
+ assert(len(known_versions) >= args['number_of_old_versions'])
+ return tuple(list(known_versions[-args['number_of_old_versions']:]) + [args['cur_version']])
+
+def update_compat_files(old_versions, new_versions, assert_unchanged=False, **args):
+ for v in old_versions:
+ if v not in new_versions:
+ compat_file = os.path.join('theories', 'Compat', version_name_to_compat_name(v))
+ if not assert_unchanged:
+ print('Removing %s...' % compat_file)
+ compat_path = os.path.join(ROOT_PATH, compat_file)
+ os.rename(compat_path, compat_path + '.bak')
+ else:
+ raise Exception('%s exists!' % compat_file)
+ for v, next_v in zip(new_versions, list(new_versions[1:]) + [None]):
+ compat_file = os.path.join('theories', 'Compat', version_name_to_compat_name(v))
+ compat_path = os.path.join(ROOT_PATH, compat_file)
+ if not os.path.exists(compat_path):
+ print('Creating %s...' % compat_file)
+ contents = HEADER + (EXTRA_HEADER % v)
+ if next_v is not None:
+ contents += '\nRequire Export Coq.Compat.%s.\n' % version_name_to_compat_name(next_v, ext='')
+ if not assert_unchanged:
+ with open(compat_path, 'w') as f:
+ f.write(contents)
+ print(r"Don't forget to 'git add %s'!" % compat_file)
+ else:
+ raise Exception('%s does not exist!' % compat_file)
+ else:
+ # print('Checking %s...' % compat_file)
+ with open(compat_path, 'r') as f:
+ contents = f.read()
+ header = HEADER + (EXTRA_HEADER % v)
+ if not contents.startswith(HEADER):
+ raise Exception("Invalid header in %s; does not match %s" % (compat_file, os.path.relpath(HEADER_PATH, ROOT_PATH)))
+ if not contents.startswith(header):
+ raise Exception("Invalid header in %s; missing line %s" % (compat_file, EXTRA_HEADER.strip('\n') % v))
+ if next_v is not None:
+ line = 'Require Export Coq.Compat.%s.' % version_name_to_compat_name(next_v, ext='')
+ if ('\n%s\n' % line) not in contents:
+ if not contents.startswith(header + '\n'):
+ contents = contents.replace(header, header + '\n')
+ contents = contents.replace(header, '%s\n%s' % (header, line))
+ if not assert_unchanged:
+ print('Updating %s...' % compat_file)
+ with open(compat_path, 'w') as f:
+ f.write(contents)
+ else:
+ raise Exception('Compat file %s is missing line %s' % (compat_file, line))
+
+def update_compat_versions_type_line(new_versions, contents, relpath):
+ compat_version_string = ' | '.join(['V%s_%s' % tuple(v.split('.')) for v in new_versions[:-1]] + ['Current'])
+ new_compat_line = 'type compat_version = %s' % compat_version_string
+ new_contents = re.sub(r'^type compat_version = .*$', new_compat_line, contents, flags=re.MULTILINE)
+ if new_compat_line not in new_contents:
+ raise Exception("Could not find 'type compat_version =' in %s" % relpath)
+ return new_contents
+
+def update_version_compare(new_versions, contents, relpath):
+ first_line = 'let version_compare v1 v2 = match v1, v2 with'
+ new_lines = [first_line]
+ for v in new_versions[:-1]:
+ V = 'V%s_%s' % tuple(v.split('.'))
+ new_lines.append(' | %s, %s -> 0' % (V, V))
+ new_lines.append(' | %s, _ -> -1' % V)
+ new_lines.append(' | _, %s -> 1' % V)
+ new_lines.append(' | Current, Current -> 0')
+ new_lines = '\n'.join(new_lines)
+ new_contents = re.sub(first_line + '.*' + 'Current, Current -> 0', new_lines, contents, flags=re.DOTALL|re.MULTILINE)
+ if new_lines not in new_contents:
+ raise Exception('Could not find version_compare in %s' % relpath)
+ return new_contents
+
+def update_pr_version(new_versions, contents, relpath):
+ first_line = 'let pr_version = function'
+ new_lines = [first_line]
+ for v in new_versions[:-1]:
+ V = 'V%s_%s' % tuple(v.split('.'))
+ new_lines.append(' | %s -> "%s"' % (V, v))
+ new_lines.append(' | Current -> "current"')
+ new_lines = '\n'.join(new_lines)
+ new_contents = re.sub(first_line + '.*' + 'Current -> "current"', new_lines, contents, flags=re.DOTALL|re.MULTILINE)
+ if new_lines not in new_contents:
+ raise Exception('Could not find pr_version in %s' % relpath)
+ return new_contents
+
+def update_add_compat_require(new_versions, contents, relpath):
+ first_line = 'let add_compat_require opts v ='
+ new_lines = [first_line, ' match v with']
+ for v in new_versions[:-1]:
+ V = 'V%s_%s' % tuple(v.split('.'))
+ new_lines.append(' | Flags.%s -> add_vo_require opts "Coq.Compat.%s" None (Some false)' % (V, version_name_to_compat_name(v, ext='')))
+ new_lines.append(' | Flags.Current -> add_vo_require opts "Coq.Compat.%s" None (Some false)' % version_name_to_compat_name(new_versions[-1], ext=''))
+ new_lines = '\n'.join(new_lines)
+ new_contents = re.sub(first_line + '.*' + 'Flags.Current -> add_vo_require opts "Coq.Compat.[^"]+" None .Some false.', new_lines, contents, flags=re.DOTALL|re.MULTILINE)
+ if new_lines not in new_contents:
+ raise Exception('Could not find add_compat_require in %s' % relpath)
+ return new_contents
+
+def update_parse_compat_version(new_versions, contents, relpath, **args):
+ line_count = args['number_of_compat_versions']+2 # 1 for the first line, 1 for the invalid flags
+ first_line = 'let parse_compat_version = let open Flags in function'
+ old_function_lines = contents[contents.index(first_line):].split('\n')[:line_count]
+ if re.match(r'^ \| \([0-9 "\.\|]*\) as s ->$', old_function_lines[-1]) is None:
+ raise Exception('Could not recognize line %d of parse_compat_version in %s as a list of invalid versions' % (line_count, relpath))
+ all_versions = re.findall(r'"([0-9\.]+)"', ''.join(old_function_lines))
+ invalid_versions = tuple(i for i in all_versions if i not in new_versions)
+ new_function_lines = [first_line]
+ for v, V in reversed(list(zip(new_versions, ['V%s_%s' % tuple(v.split('.')) for v in new_versions[:-1]] + ['Current']))):
+ new_function_lines.append(' | "%s" -> %s' % (v, V))
+ new_function_lines.append(' | (%s) as s ->' % ' | '.join('"%s"' % v for v in invalid_versions))
+ new_lines = '\n'.join(new_function_lines)
+ new_contents = contents.replace('\n'.join(old_function_lines), new_lines)
+ if new_lines not in new_contents:
+ raise Exception('Could not find parse_compat_version in %s' % relpath)
+ return new_contents
+
+def check_no_old_versions(old_versions, new_versions, contents, relpath):
+ for v in old_versions:
+ if v not in new_versions:
+ V = 'V%s_%s' % tuple(v.split('.'))
+ if V in contents:
+ raise Exception('Unreplaced usage of %s remaining in %s' % (V, relpath))
+
+def update_if_changed(contents, new_contents, path, assert_unchanged=False, **args):
+ if contents != new_contents:
+ if not assert_unchanged:
+ print('Updating %s...' % os.path.relpath(path, ROOT_PATH))
+ with open(path, 'w') as f:
+ f.write(new_contents)
+ else:
+ raise Exception('%s changed!' % os.path.relpath(path, ROOT_PATH))
+
+def update_flags_mli(old_versions, new_versions, **args):
+ with open(FLAGS_MLI_PATH, 'r') as f: contents = f.read()
+ new_contents = update_compat_versions_type_line(new_versions, contents, os.path.relpath(FLAGS_MLI_PATH, ROOT_PATH))
+ check_no_old_versions(old_versions, new_versions, new_contents, os.path.relpath(FLAGS_MLI_PATH, ROOT_PATH))
+ update_if_changed(contents, new_contents, FLAGS_MLI_PATH, **args)
+
+def update_flags_ml(old_versions, new_versions, **args):
+ with open(FLAGS_ML_PATH, 'r') as f: contents = f.read()
+ new_contents = update_compat_versions_type_line(new_versions, contents, os.path.relpath(FLAGS_ML_PATH, ROOT_PATH))
+ new_contents = update_version_compare(new_versions, new_contents, os.path.relpath(FLAGS_ML_PATH, ROOT_PATH))
+ new_contents = update_pr_version(new_versions, new_contents, os.path.relpath(FLAGS_ML_PATH, ROOT_PATH))
+ check_no_old_versions(old_versions, new_versions, new_contents, os.path.relpath(FLAGS_ML_PATH, ROOT_PATH))
+ update_if_changed(contents, new_contents, FLAGS_ML_PATH, **args)
+
+def update_coqargs_ml(old_versions, new_versions, **args):
+ with open(COQARGS_ML_PATH, 'r') as f: contents = f.read()
+ new_contents = update_add_compat_require(new_versions, contents, os.path.relpath(COQARGS_ML_PATH, ROOT_PATH))
+ check_no_old_versions(old_versions, new_versions, new_contents, os.path.relpath(COQARGS_ML_PATH, ROOT_PATH))
+ update_if_changed(contents, new_contents, COQARGS_ML_PATH, **args)
+
+def update_g_vernac(old_versions, new_versions, **args):
+ with open(G_VERNAC_PATH, 'r') as f: contents = f.read()
+ new_contents = update_parse_compat_version(new_versions, contents, os.path.relpath(G_VERNAC_PATH, ROOT_PATH), **args)
+ check_no_old_versions(old_versions, new_versions, new_contents, os.path.relpath(G_VERNAC_PATH, ROOT_PATH))
+ update_if_changed(contents, new_contents, G_VERNAC_PATH, **args)
+
+def update_flags(old_versions, new_versions, **args):
+ update_flags_mli(old_versions, new_versions, **args)
+ update_flags_ml(old_versions, new_versions, **args)
+ update_coqargs_ml(old_versions, new_versions, **args)
+ update_g_vernac(old_versions, new_versions, **args)
+
+def update_test_suite(new_versions, assert_unchanged=False, test_suite_paths=TEST_SUITE_PATHS, test_suite_descriptions=TEST_SUITE_DESCRIPTIONS, **args):
+ assert(len(new_versions) == len(test_suite_paths))
+ assert(len(new_versions) == len(test_suite_descriptions))
+ for i, (v, path, descr) in enumerate(zip(new_versions, test_suite_paths, test_suite_descriptions)):
+ if not os.path.exists(path):
+ raise Exception('Could not find existing file %s' % os.path.relpath(path, ROOT_PATH))
+ if '%s' in descr: descr = descr % v
+ with open(path, 'r') as f: contents = f.read()
+ lines = ['(* -*- coq-prog-args: ("-compat" "%s") -*- *)' % v,
+ '(** Check that the %s compatibility flag actually requires the relevant modules. *)' % descr]
+ for imp_v in reversed(new_versions[i:]):
+ lines.append('Import Coq.Compat.%s.' % version_name_to_compat_name(imp_v, ext=''))
+ lines.append('')
+ new_contents = '\n'.join(lines)
+ update_if_changed(contents, new_contents, path, **args)
+
+def update_doc_index(new_versions, **args):
+ with open(DOC_INDEX_PATH, 'r') as f: contents = f.read()
+ firstline = ' theories/Compat/AdmitAxiom.v'
+ new_contents = ''.join(DOC_INDEX_LINES)
+ if firstline not in new_contents:
+ raise Exception("Could not find line '%s' in %s" % (firstline, os.path.relpath(DOC_INDEX_PATH, ROOT_PATH)))
+ extra_lines = [' theories/Compat/%s' % version_name_to_compat_name(v) for v in new_versions]
+ new_contents = new_contents.replace(firstline, '\n'.join([firstline] + extra_lines))
+ update_if_changed(contents, new_contents, DOC_INDEX_PATH, **args)
+
+def update_bug_4789(new_versions, **args):
+ # we always update this compat notation to oldest
+ # currently-supported compat version, which should never be the
+ # current version
+ with open(BUG_4798_PATH, 'r') as f: contents = f.read()
+ new_contents = r"""Check match 2 with 0 => 0 | S n => n end.
+Notation "|" := 1 (compat "%s").
+Check match 2 with 0 => 0 | S n => n end. (* fails *)
+""" % new_versions[0]
+ update_if_changed(contents, new_contents, BUG_4798_PATH, **args)
+
+def update_compat_notations_in(old_versions, new_versions, contents):
+ for v in old_versions:
+ if v not in new_versions:
+ reg = re.compile(r'^[ \t]*(?:Notation|Infix)[^\n]*?compat "%s"[^\n]*?\n' % v, flags=re.MULTILINE)
+ contents = re.sub(r'^[ \t]*(?:Notation|Infix)[^\n]*?compat "%s"[^\n]*?\n' % v, '', contents, flags=re.MULTILINE)
+ return contents
+
+def update_compat_notations(old_versions, new_versions, **args):
+ for root, dirs, files in os.walk(os.path.join(ROOT_PATH, 'theories')):
+ for fname in files:
+ if not fname.endswith('.v'): continue
+ with open(os.path.join(root, fname), 'r') as f: contents = f.read()
+ new_contents = update_compat_notations_in(old_versions, new_versions, contents)
+ update_if_changed(contents, new_contents, os.path.join(root, fname), **args)
+
+def display_git_grep(old_versions, new_versions):
+ Vs = ['V%s_%s' % tuple(v.split('.')) for v in old_versions if v not in new_versions]
+ compat_vs = ['compat "%s"' % v for v in old_versions if v not in new_versions]
+ all_options = tuple(Vs + compat_vs)
+ options = (['"-compat" "%s"' % v for v in old_versions if v not in new_versions] +
+ [version_name_to_compat_name(v, ext='') for v in old_versions if v not in new_versions])
+ if len(options) > 0 or len(all_options) > 0:
+ print('To discover what files require manual updating, run:')
+ if len(options) > 0: print("git grep -- '%s' test-suite/" % r'\|'.join(options))
+ if len(all_options) > 0: print("git grep -- '%s'" % r'\|'.join(all_options))
+
+def parse_args(argv):
+ args = {
+ 'assert_unchanged': False,
+ 'cur_version': None,
+ 'number_of_old_versions': DEFAULT_NUMBER_OF_OLD_VERSIONS
+ }
+ for arg in argv[1:]:
+ if arg == '--assert-unchanged':
+ args['assert_unchanged'] = True
+ elif arg.startswith('--cur-version='):
+ args['cur_version'] = arg[len('--cur-version='):]
+ assert(len(args['cur_version'].split('.')) == 2)
+ assert(all(map(str.isdigit, args['cur_version'].split('.'))))
+ elif arg.startswith('--number-of-old-versions='):
+ args['number_of_old_versions'] = int(arg[len('--number-of-old-versions='):])
+ else:
+ print('USAGE: %s [--assert-unchanged] [--cur-version=NN.NN] [--number-of-old-versions=NN]' % argv[0])
+ print('')
+ print('ERROR: Unrecognized argument: %s' % arg)
+ sys.exit(1)
+ return args
+
+if __name__ == '__main__':
+ args = parse_args(sys.argv)
+ args['cur_version'] = get_version(args['cur_version'])
+ args['number_of_compat_versions'] = args['number_of_old_versions'] + 1
+ known_versions = get_known_versions()
+ new_versions = get_new_versions(known_versions, **args)
+ assert(len(TEST_SUITE_PATHS) >= args['number_of_compat_versions'])
+ args['test_suite_paths'] = tuple(TEST_SUITE_PATHS[-args['number_of_compat_versions']:])
+ args['test_suite_descriptions'] = tuple(TEST_SUITE_DESCRIPTIONS[-args['number_of_compat_versions']:])
+ update_compat_files(known_versions, new_versions, **args)
+ update_flags(known_versions, new_versions, **args)
+ update_test_suite(new_versions, **args)
+ update_doc_index(new_versions, **args)
+ update_bug_4789(new_versions, **args)
+ update_compat_notations(known_versions, new_versions, **args)
+ display_git_grep(known_versions, new_versions)
diff --git a/dev/top_printers.ml b/dev/top_printers.ml
index ba0c5440..ced6ea26 100644
--- a/dev/top_printers.ml
+++ b/dev/top_printers.ml
@@ -64,8 +64,14 @@ let ppwf_paths x = pp (Rtree.pp_tree prrecarg x)
let envpp pp = let sigma,env = Pfedit.get_current_context () in pp env sigma
let rawdebug = ref false
let ppevar evk = pp (Evar.print evk)
-let ppconstr x = pp (Termops.print_constr (EConstr.of_constr x))
-let ppeconstr x = pp (Termops.print_constr x)
+let pr_constr t =
+ let sigma, env = Pfedit.get_current_context () in
+ Printer.pr_constr_env env sigma t
+let pr_econstr t =
+ let sigma, env = Pfedit.get_current_context () in
+ Printer.pr_econstr_env env sigma t
+let ppconstr x = pp (pr_constr x)
+let ppeconstr x = pp (pr_econstr x)
let ppconstr_expr x = pp (Ppconstr.pr_constr_expr x)
let ppsconstr x = ppconstr (Mod_subst.force_constr x)
let ppconstr_univ x = Constrextern.with_universes ppconstr x
@@ -95,9 +101,9 @@ let ppidmapgen l = pp (pridmapgen l)
let ppevarsubst = ppidmap (fun id0 -> prset (fun (c,copt,id) ->
hov 0
- (Termops.print_constr (EConstr.of_constr c) ++
+ (pr_constr c ++
(match copt with None -> mt () | Some c -> spc () ++ str "") ++
+ pr_constr c ++ str">") ++
(if id = id0 then mt ()
else spc () ++ str ""))))
@@ -106,7 +112,7 @@ let ppididmap = ppidmap (fun _ -> Id.print)
let prconstrunderbindersidmap = pridmap (fun _ (l,c) ->
hov 1 (str"[" ++ prlist_with_sep spc Id.print l ++ str"]")
- ++ str "," ++ spc () ++ Termops.print_constr c)
+ ++ str "," ++ spc () ++ pr_econstr c)
let ppconstrunderbindersidmap l = pp (prconstrunderbindersidmap l)
@@ -155,15 +161,15 @@ let ppdelta s = pp (Mod_subst.debug_pr_delta s)
let pp_idpred s = pp (pr_idpred s)
let pp_cpred s = pp (pr_cpred s)
let pp_transparent_state s = pp (pr_transparent_state s)
-let pp_stack_t n = pp (Reductionops.Stack.pr (EConstr.of_constr %> Termops.print_constr) n)
-let pp_cst_stack_t n = pp (Reductionops.Cst_stack.pr n)
-let pp_state_t n = pp (Reductionops.pr_state n)
+let pp_stack_t n = pp (Reductionops.Stack.pr (EConstr.of_constr %> pr_econstr) n)
+let pp_cst_stack_t n = pp (Reductionops.Cst_stack.pr Global.(env()) Evd.empty n)
+let pp_state_t n = pp (Reductionops.pr_state Global.(env()) Evd.empty n)
(* proof printers *)
let pr_evar ev = Pp.int (Evar.repr ev)
let ppmetas metas = pp(Termops.pr_metaset metas)
-let ppevm evd = pp(Termops.pr_evar_map ~with_univs:!Flags.univ_print (Some 2) evd)
-let ppevmall evd = pp(Termops.pr_evar_map ~with_univs:!Flags.univ_print None evd)
+let ppevm evd = pp(Termops.pr_evar_map ~with_univs:!Detyping.print_universes (Some 2) evd)
+let ppevmall evd = pp(Termops.pr_evar_map ~with_univs:!Detyping.print_universes None evd)
let pr_existentialset evars =
prlist_with_sep spc pr_evar (Evar.Set.elements evars)
let ppexistentialset evars =
@@ -181,7 +187,7 @@ let ppproofview p =
pp(pr_enum Goal.pr_goal gls ++ fnl () ++ Termops.pr_evar_map (Some 1) sigma)
let ppopenconstr (x : Evd.open_constr) =
- let (evd,c) = x in pp (Termops.pr_evar_map (Some 2) evd ++ envpp pr_constr_env c)
+ let (evd,c) = x in pp (Termops.pr_evar_map (Some 2) evd ++ envpp pr_econstr_env c)
(* spiwack: deactivated until a replacement is found
let pppftreestate p = pp(print_pftreestate p)
*)
@@ -203,17 +209,17 @@ let pproof p = pp(Proof.pr_proof p)
let ppuni u = pp(Universe.pr u)
let ppuni_level u = pp (Level.pr u)
-let prlev = Universes.pr_with_global_universes
+let prlev = UnivNames.pr_with_global_universes
let ppuniverse_set l = pp (LSet.pr prlev l)
let ppuniverse_instance l = pp (Instance.pr prlev l)
let ppuniverse_context l = pp (pr_universe_context prlev l)
let ppuniverse_context_set l = pp (pr_universe_context_set prlev l)
let ppuniverse_subst l = pp (Univ.pr_universe_subst l)
-let ppuniverse_opt_subst l = pp (Universes.pr_universe_opt_subst l)
+let ppuniverse_opt_subst l = pp (UnivSubst.pr_universe_opt_subst l)
let ppuniverse_level_subst l = pp (Univ.pr_universe_level_subst l)
let ppevar_universe_context l = pp (Termops.pr_evar_universe_context l)
let ppconstraints c = pp (pr_constraints Level.pr c)
-let ppuniverseconstraints c = pp (Universes.Constraints.pr c)
+let ppuniverseconstraints c = pp (UnivProblem.Set.pr c)
let ppuniverse_context_future c =
let ctx = Future.force c in
ppuniverse_context ctx
@@ -221,7 +227,9 @@ let ppcumulativity_info c = pp (Univ.pr_cumulativity_info Univ.Level.pr c)
let ppabstract_cumulativity_info c = pp (Univ.pr_abstract_cumulativity_info Univ.Level.pr c)
let ppuniverses u = pp (UGraph.pr_universes Level.pr u)
let ppnamedcontextval e =
- pp (pr_named_context (Global.env ()) Evd.empty (named_context_of_val e))
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ pp (pr_named_context env sigma (named_context_of_val e))
let ppenv e = pp
(str "[" ++ pr_named_context_of e Evd.empty ++ str "]" ++ spc() ++
@@ -230,7 +238,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).Pre_env.env_globals.Pre_env.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))
@@ -299,8 +307,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)^")"
@@ -421,8 +429,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()
@@ -547,8 +555,8 @@ let encode_path ?loc prefix mpdir suffix id =
| Some (mp,dir) ->
(DirPath.repr (dirpath_of_string (ModPath.to_string mp))@
DirPath.repr dir) in
- CAst.make ?loc @@ Qualid (make_qualid
- (DirPath.make (List.rev (Id.of_string prefix::dir@suffix))) id)
+ make_qualid ?loc
+ (DirPath.make (List.rev (Id.of_string prefix::dir@suffix))) id
let raw_string_of_ref ?loc _ = function
| ConstRef cst ->
@@ -567,9 +575,9 @@ let raw_string_of_ref ?loc _ = function
encode_path ?loc "SECVAR" None [] id
let short_string_of_ref ?loc _ = function
- | VarRef id -> CAst.make ?loc @@ Ident id
- | ConstRef cst -> CAst.make ?loc @@ Ident (Label.to_id (pi3 (Constant.repr3 cst)))
- | IndRef (kn,0) -> CAst.make ?loc @@ Ident (Label.to_id (pi3 (MutInd.repr3 kn)))
+ | VarRef id -> qualid_of_ident ?loc id
+ | ConstRef cst -> qualid_of_ident ?loc (Label.to_id (pi3 (Constant.repr3 cst)))
+ | IndRef (kn,0) -> qualid_of_ident ?loc (Label.to_id (pi3 (MutInd.repr3 kn)))
| IndRef (kn,i) ->
encode_path ?loc "IND" None [Label.to_id (pi3 (MutInd.repr3 kn))]
(Id.of_string ("_"^string_of_int i))
diff --git a/dev/top_printers.mli b/dev/top_printers.mli
index dad6dcc1..63d7d580 100644
--- a/dev/top_printers.mli
+++ b/dev/top_printers.mli
@@ -87,7 +87,7 @@ val ppclosedglobconstr : Ltac_pretype.closed_glob_constr -> unit
val ppclosedglobconstridmap :
Ltac_pretype.closed_glob_constr Names.Id.Map.t -> unit
-val ppglobal : Globnames.global_reference -> unit
+val ppglobal : Names.GlobRef.t -> unit
val ppconst :
Names.KerName.t * (Constr.constr, 'a) Environ.punsafe_judgment -> unit
@@ -139,11 +139,11 @@ val ppuniverse_instance : Univ.Instance.t -> unit
val ppuniverse_context : Univ.UContext.t -> unit
val ppuniverse_context_set : Univ.ContextSet.t -> unit
val ppuniverse_subst : Univ.universe_subst -> unit
-val ppuniverse_opt_subst : Universes.universe_opt_subst -> unit
+val ppuniverse_opt_subst : UnivSubst.universe_opt_subst -> unit
val ppuniverse_level_subst : Univ.universe_level_subst -> unit
val ppevar_universe_context : UState.t -> unit
val ppconstraints : Univ.Constraint.t -> unit
-val ppuniverseconstraints : Universes.Constraints.t -> unit
+val ppuniverseconstraints : UnivProblem.Set.t -> unit
val ppuniverse_context_future : Univ.UContext.t Future.computation -> unit
val ppcumulativity_info : Univ.CumulativityInfo.t -> unit
val ppabstract_cumulativity_info : Univ.ACumulativityInfo.t -> unit
diff --git a/dev/vm_printers.ml b/dev/vm_printers.ml
index 2ddf927d..ea126e27 100644
--- a/dev/vm_printers.ml
+++ b/dev/vm_printers.ml
@@ -1,7 +1,7 @@
open Format
open Term
+open Constr
open Names
-open Cbytecodes
open Cemitcodes
open Vmvalues
@@ -10,11 +10,14 @@ let ppripos (ri,pos) =
| Reloc_annot a ->
let sp,i = a.ci.ci_ind in
print_string
- ("annot : MutInd("^(MutInd.to_string sp)^","^(string_of_int i)^")\n")
+ ("annot : MutInd("^(MutInd.to_string sp)^","^(string_of_int i)^")\n")
| Reloc_const _ ->
print_string "structured constant\n"
| Reloc_getglobal kn ->
- print_string ("getglob "^(Constant.to_string kn)^"\n"));
+ print_string ("getglob "^(Constant.to_string kn)^"\n")
+ | Reloc_proj_name p ->
+ print_string ("proj "^(Projection.Repr.to_string p)^"\n")
+ );
print_flush ()
let print_vfix () = print_string "vfix"
@@ -22,8 +25,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 c223a4e1..3789d910 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 00000000..77fe617f
--- /dev/null
+++ b/doc/README.md
@@ -0,0 +1,126 @@
+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).
+
+Additionally, you can view the documentation for the current master version at
+.
+
+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
+
+To install them, you should first install pip and setuptools (for instance,
+with `apt install python3-pip python3-setuptools` on Debian / Ubuntu) then run:
+
+ pip3 install sphinx sphinx_rtd_theme beautifulsoup4 antlr4-python3-runtime \
+ pexpect sphinxcontrib-bibtex
+
+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
+ - xelatex
+ - latexmk
+ - xindy
+
+All of them are part of the TexLive distribution. E.g. on Debian / Ubuntu,
+install them with:
+
+ apt install texlive-full
+
+Or if you want to use less disk space:
+
+ apt install texlive-latex-extra texlive-fonts-recommended texlive-xetex \
+ latexmk xindy
+
+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 refman`
+ to produce the HTML and PDF versions of the reference manual
+
+- `make refman-{html,pdf}`
+ to produce only one format 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.
+
+If you're editing Sphinx documentation, set SPHINXWARNERROR to 0
+to avoid treating Sphinx warnings as errors. Otherwise, Sphinx quits
+upon detecting the first warning. You can set this on the Sphinx `make`
+command line or as an environment variable:
+
+- `make refman SPHINXWARNERROR=0`
+
+- ~~~
+ export SPHINXWARNERROR=0
+ ⋮
+ make refman
+ ~~~
+
+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/stdlib/hidden-files b/doc/stdlib/hidden-files
index 8b137891..b58148ff 100644
--- a/doc/stdlib/hidden-files
+++ b/doc/stdlib/hidden-files
@@ -1 +1,77 @@
-
+plugins/btauto/Algebra.v
+plugins/btauto/Btauto.v
+plugins/btauto/Reflect.v
+plugins/derive/Derive.v
+plugins/extraction/ExtrHaskellBasic.v
+plugins/extraction/ExtrHaskellNatInt.v
+plugins/extraction/ExtrHaskellNatInteger.v
+plugins/extraction/ExtrHaskellNatNum.v
+plugins/extraction/ExtrHaskellString.v
+plugins/extraction/ExtrHaskellZInt.v
+plugins/extraction/ExtrHaskellZInteger.v
+plugins/extraction/ExtrHaskellZNum.v
+plugins/extraction/ExtrOcamlBasic.v
+plugins/extraction/ExtrOcamlBigIntConv.v
+plugins/extraction/ExtrOcamlIntConv.v
+plugins/extraction/ExtrOcamlNatBigInt.v
+plugins/extraction/ExtrOcamlNatInt.v
+plugins/extraction/ExtrOcamlString.v
+plugins/extraction/ExtrOcamlZBigInt.v
+plugins/extraction/ExtrOcamlZInt.v
+plugins/extraction/Extraction.v
+plugins/funind/FunInd.v
+plugins/funind/Recdef.v
+plugins/ltac/Ltac.v
+plugins/micromega/Env.v
+plugins/micromega/EnvRing.v
+plugins/micromega/Fourier.v
+plugins/micromega/Fourier_util.v
+plugins/micromega/Lia.v
+plugins/micromega/Lqa.v
+plugins/micromega/Lra.v
+plugins/micromega/MExtraction.v
+plugins/micromega/OrderedRing.v
+plugins/micromega/Psatz.v
+plugins/micromega/QMicromega.v
+plugins/micromega/RMicromega.v
+plugins/micromega/Refl.v
+plugins/micromega/RingMicromega.v
+plugins/micromega/Tauto.v
+plugins/micromega/VarMap.v
+plugins/micromega/ZCoeff.v
+plugins/micromega/ZMicromega.v
+plugins/nsatz/Nsatz.v
+plugins/omega/Omega.v
+plugins/omega/OmegaLemmas.v
+plugins/omega/OmegaPlugin.v
+plugins/omega/OmegaTactic.v
+plugins/omega/PreOmega.v
+plugins/quote/Quote.v
+plugins/romega/ROmega.v
+plugins/romega/ReflOmegaCore.v
+plugins/rtauto/Bintree.v
+plugins/rtauto/Rtauto.v
+plugins/setoid_ring/Algebra_syntax.v
+plugins/setoid_ring/ArithRing.v
+plugins/setoid_ring/BinList.v
+plugins/setoid_ring/Cring.v
+plugins/setoid_ring/Field.v
+plugins/setoid_ring/Field_tac.v
+plugins/setoid_ring/Field_theory.v
+plugins/setoid_ring/InitialRing.v
+plugins/setoid_ring/Integral_domain.v
+plugins/setoid_ring/NArithRing.v
+plugins/setoid_ring/Ncring.v
+plugins/setoid_ring/Ncring_initial.v
+plugins/setoid_ring/Ncring_polynom.v
+plugins/setoid_ring/Ncring_tac.v
+plugins/setoid_ring/RealField.v
+plugins/setoid_ring/Ring.v
+plugins/setoid_ring/Ring_base.v
+plugins/setoid_ring/Ring_polynom.v
+plugins/setoid_ring/Ring_tac.v
+plugins/setoid_ring/Ring_theory.v
+plugins/setoid_ring/Rings_Q.v
+plugins/setoid_ring/Rings_R.v
+plugins/setoid_ring/Rings_Z.v
+plugins/setoid_ring/ZArithRing.v
diff --git a/doc/stdlib/index-list.html.template b/doc/stdlib/index-list.html.template
index 8c09b23a..e502cb1b 100644
--- a/doc/stdlib/index-list.html.template
+++ b/doc/stdlib/index-list.html.template
@@ -226,6 +226,7 @@ through the Require Import command.
theories/Numbers/BinNums.v
theories/Numbers/NumPrelude.v
theories/Numbers/NaryFunctions.v
+ theories/Numbers/AltBinNotations.v
theories/Numbers/DecimalFacts.v
theories/Numbers/DecimalNat.v
theories/Numbers/DecimalPos.v
@@ -498,6 +499,9 @@ through the Require Import command.
theories/Strings/Ascii.v
theories/Strings/String.v
+ theories/Strings/BinaryString.v
+ theories/Strings/HexString.v
+ theories/Strings/OctalString.v
Reals:
@@ -583,6 +587,17 @@ through the Require Import command.
theories/Program/Combinators.v
+ SSReflect:
+ Base libraries for the SSReflect proof language and the
+ small scale reflection formalization technique
+
+
+ plugins/ssrmatching/ssrmatching.v
+ plugins/ssr/ssreflect.v
+ plugins/ssr/ssrbool.v
+ plugins/ssr/ssrfun.v
+
+
Unicode:
Unicode-based notations
@@ -596,8 +611,8 @@ through the Require Import command.
theories/Compat/AdmitAxiom.v
- theories/Compat/Coq86.v
theories/Compat/Coq87.v
theories/Compat/Coq88.v
+ theories/Compat/Coq89.v
diff --git a/doc/stdlib/make-library-index b/doc/stdlib/make-library-index
index 43802efa..bea6f240 100755
--- a/doc/stdlib/make-library-index
+++ b/doc/stdlib/make-library-index
@@ -8,35 +8,32 @@ HIDDEN=$2
cp -f $FILE.template tmp
echo -n "Building file index-list.prehtml... "
-#LIBDIRS="Init Logic Structures Bool Arith PArith NArith ZArith QArith Relations Sets Classes Setoids Lists Vectors Sorting Wellfounded MSets FSets Reals Program Numbers Numbers/Natural/Abstract Numbers/Natural/Peano Numbers/Natural/Binary Numbers/Natural/BigN Numbers/Natural/SpecViaZ Numbers/Integer/Abstract Numbers/Integer/NatPairs Numbers/Integer/Binary Numbers/Integer/SpecViaZ Numbers/Integer/BigZ Numbers/NatInt Numbers/Cyclic/Abstract Numbers/Cyclic/Int31 Numbers/Cyclic/ZModulo Numbers/Cyclic/DoubleCyclic Numbers/Rational/BigQ Numbers/Rational/SpecViaQ Strings"
-LIBDIRS=`find theories/* -type d ! -name .coq-native | sed -e "s:^theories/::"`
+LIBDIRS=`find theories/* plugins/* -type d ! -name .coq-native`
for k in $LIBDIRS; do
- i=theories/$k
- d=`basename $i`
- ls $i | grep -q \.v'$'
+ d=`basename $k`
+ ls $k | grep -q \.v'$'
if [ $? = 0 ]; then
- for j in $i/*.v; do
+ for j in $k/*.v; do
b=`basename $j .v`
rm -f tmp2
- grep -q theories/$k/$b.v tmp
+ grep -q $k/$b.v tmp
a=$?
- grep -q theories/$k/$b.v $HIDDEN
+ grep -q $k/$b.v $HIDDEN
h=$?
if [ $a = 0 ]; then
if [ $h = 0 ]; then
- echo Error: $FILE and $HIDDEN both mention theories/$k/$b.v; exit 1
+ echo Error: $FILE and $HIDDEN both mention $k/$b.v; exit 1
else
- p=`echo $k | sed 's:/:.:g'`
- sed -e "s:theories/$k/$b.v:$b:g" tmp > tmp2
+ p=`echo $k | sed 's:^[^/]*/::' | sed 's:/:.:g'`
+ sed -e "s:$k/$b.v:$b:g" tmp > tmp2
mv -f tmp2 tmp
fi
else
if [ $h = 0 ]; then
- echo Error: theories/$k/$b.v is missing in the template file
- exit 1
+ echo Warning: $k/$b.v will be hidden from the index
else
- echo Error: none of $FILE and $HIDDEN mention theories/$k/$b.v
+ echo Error: none of $FILE and $HIDDEN mention $k/$b.v
exit 1
fi
diff --git a/doc/tools/coqrst/coqdomain.py b/doc/tools/coqrst/coqdomain.py
index edf4e6ec..2c69dcfe 100644
--- a/doc/tools/coqrst/coqdomain.py
+++ b/doc/tools/coqrst/coqdomain.py
@@ -560,6 +560,9 @@ class CoqtopDirective(Directive):
Print nat.
Definition a := 1.
+ The blank line after the directive is required. If you begin a proof,
+ include an ``Abort`` afterwards to reset coqtop for the next example.
+
Here is a list of permissible options:
- Display options
diff --git a/doc/tools/coqrst/repl/coqtop.py b/doc/tools/coqrst/repl/coqtop.py
index aeadce4c..3ff00eaa 100644
--- a/doc/tools/coqrst/repl/coqtop.py
+++ b/doc/tools/coqrst/repl/coqtop.py
@@ -41,10 +41,13 @@ class CoqTop:
the ansicolors module)
:param args: Additional arugments to coqtop.
"""
+ BOOT = True
+ if os.getenv('COQBOOT') == "no":
+ BOOT = False
self.coqtop_bin = coqtop_bin or os.path.join(os.getenv('COQBIN', ""), "coqtop")
if not pexpect.utils.which(self.coqtop_bin):
raise ValueError("coqtop binary not found: '{}'".format(self.coqtop_bin))
- self.args = (args or []) + ["-boot", "-color", "on"] * color
+ self.args = (args or []) + ["-boot"] * BOOT + ["-color", "on"] * color
self.coqtop = None
def __enter__(self):
diff --git a/engine/eConstr.ml b/engine/eConstr.ml
index bd47a04f..e109cbd0 100644
--- a/engine/eConstr.ml
+++ b/engine/eConstr.ml
@@ -13,132 +13,8 @@ open Util
open Names
open Constr
open Context
-open Evd
-
-module API :
-sig
-module ESorts :
-sig
-type t
-val make : Sorts.t -> t
-val kind : Evd.evar_map -> t -> Sorts.t
-val unsafe_to_sorts : t -> Sorts.t
-end
-module EInstance :
-sig
-type t
-val make : Univ.Instance.t -> t
-val kind : Evd.evar_map -> t -> Univ.Instance.t
-val empty : t
-val is_empty : t -> bool
-val unsafe_to_instance : t -> Univ.Instance.t
-end
-type t
-val kind : Evd.evar_map -> t -> (t, t, ESorts.t, EInstance.t) Constr.kind_of_term
-val kind_upto : Evd.evar_map -> constr -> (constr, types, Sorts.t, Univ.Instance.t) Constr.kind_of_term
-val kind_of_type : Evd.evar_map -> t -> (t, t) Term.kind_of_type
-val whd_evar : Evd.evar_map -> t -> t
-val of_kind : (t, t, ESorts.t, EInstance.t) Constr.kind_of_term -> t
-val of_constr : Constr.t -> t
-val to_constr : evar_map -> t -> Constr.t
-val unsafe_to_constr : t -> Constr.t
-val unsafe_eq : (t, Constr.t) eq
-val of_named_decl : (Constr.t, Constr.types) Context.Named.Declaration.pt -> (t, t) Context.Named.Declaration.pt
-val unsafe_to_named_decl : (t, t) Context.Named.Declaration.pt -> (Constr.t, Constr.types) Context.Named.Declaration.pt
-val unsafe_to_rel_decl : (t, t) Context.Rel.Declaration.pt -> (Constr.t, Constr.types) Context.Rel.Declaration.pt
-val of_rel_decl : (Constr.t, Constr.types) Context.Rel.Declaration.pt -> (t, t) Context.Rel.Declaration.pt
-val to_rel_decl : Evd.evar_map -> (t, t) Context.Rel.Declaration.pt -> (Constr.t, Constr.types) Context.Rel.Declaration.pt
-end =
-struct
-
-module ESorts =
-struct
- type t = Sorts.t
- let make s = s
- let kind sigma = function
- | Sorts.Type u -> Sorts.sort_of_univ (Evd.normalize_universe sigma u)
- | s -> s
- let unsafe_to_sorts s = s
-end
-
-module EInstance =
-struct
- type t = Univ.Instance.t
- let make i = i
- let kind sigma i =
- if Univ.Instance.is_empty i then i
- else Evd.normalize_universe_instance sigma i
- let empty = Univ.Instance.empty
- let is_empty = Univ.Instance.is_empty
- let unsafe_to_instance t = t
-end
-type t = Constr.t
-
-let safe_evar_value sigma ev =
- try Some (Evd.existential_value sigma ev)
- with NotInstantiatedEvar | Not_found -> None
-
-let rec whd_evar sigma c =
- match Constr.kind c with
- | Evar ev ->
- begin match safe_evar_value sigma ev with
- | Some c -> whd_evar sigma c
- | None -> c
- end
- | App (f, args) when isEvar f ->
- (** Enforce smart constructor invariant on applications *)
- let ev = destEvar f in
- begin match safe_evar_value sigma ev with
- | None -> c
- | Some f -> whd_evar sigma (mkApp (f, args))
- end
- | Cast (c0, k, t) when isEvar c0 ->
- (** Enforce smart constructor invariant on casts. *)
- let ev = destEvar c0 in
- begin match safe_evar_value sigma ev with
- | None -> c
- | Some c -> whd_evar sigma (mkCast (c, k, t))
- end
- | _ -> c
-
-let kind sigma c = Constr.kind (whd_evar sigma c)
-let kind_upto = kind
-let kind_of_type sigma c = Term.kind_of_type (whd_evar sigma c)
-let of_kind = Constr.of_kind
-let of_constr c = c
-let unsafe_to_constr c = c
-let unsafe_eq = Refl
-
-let rec to_constr sigma c = match Constr.kind c with
-| Evar ev ->
- begin match safe_evar_value sigma ev with
- | Some c -> to_constr sigma c
- | None -> Constr.map (fun c -> to_constr sigma c) c
- end
-| Sort (Sorts.Type u) ->
- let u' = Evd.normalize_universe sigma u in
- if u' == u then c else mkSort (Sorts.sort_of_univ u')
-| Const (c', u) when not (Univ.Instance.is_empty u) ->
- let u' = Evd.normalize_universe_instance sigma u in
- if u' == u then c else mkConstU (c', u')
-| Ind (i, u) when not (Univ.Instance.is_empty u) ->
- let u' = Evd.normalize_universe_instance sigma u in
- if u' == u then c else mkIndU (i, u')
-| Construct (co, u) when not (Univ.Instance.is_empty u) ->
- let u' = Evd.normalize_universe_instance sigma u in
- if u' == u then c else mkConstructU (co, u')
-| _ -> Constr.map (fun c -> to_constr sigma c) c
-
-let of_named_decl d = d
-let unsafe_to_named_decl d = d
-let of_rel_decl d = d
-let unsafe_to_rel_decl d = d
-let to_rel_decl sigma d = Context.Rel.Declaration.map_constr (to_constr sigma) d
-
-end
-
-include API
+include Evd.MiniEConstr
type types = t
type constr = t
@@ -201,6 +77,14 @@ let isFix sigma c = match kind sigma c with Fix _ -> true | _ -> false
let isCoFix sigma c = match kind sigma c with CoFix _ -> true | _ -> false
let isCase sigma c = match kind sigma c with Case _ -> true | _ -> false
let isProj sigma c = match kind sigma c with Proj _ -> true | _ -> false
+
+let rec isType sigma c = match kind sigma c with
+ | Sort s -> (match ESorts.kind sigma s with
+ | Sorts.Type _ -> true
+ | _ -> false )
+ | Cast (c,_,_) -> isType sigma c
+ | _ -> false
+
let isVarId sigma id c =
match kind sigma c with Var id' -> Id.equal id id' | _ -> false
let isRelN sigma n c =
@@ -381,8 +265,7 @@ let decompose_prod_n_assum sigma n c =
in
prodec_rec Context.Rel.empty n c
-let existential_type sigma (evk, args) =
- of_constr (existential_type sigma (evk, Array.map unsafe_to_constr args))
+let existential_type = Evd.existential_type
let map sigma f c = match kind sigma c with
| (Rel _ | Meta _ | Var _ | Sort _ | Const _ | Ind _
@@ -410,7 +293,7 @@ let map sigma f c = match kind sigma c with
else mkLetIn (na, b', t', k')
| App (b,l) ->
let b' = f b in
- let l' = Array.smartmap f l in
+ let l' = Array.Smart.map f l in
if b'==b && l'==l then c
else mkApp (b', l')
| Proj (p,t) ->
@@ -418,23 +301,23 @@ let map sigma f c = match kind sigma c with
if t' == t then c
else mkProj (p, t')
| Evar (e,l) ->
- let l' = Array.smartmap f l in
+ let l' = Array.Smart.map f l in
if l'==l then c
else mkEvar (e, l')
| Case (ci,p,b,bl) ->
let b' = f b in
let p' = f p in
- let bl' = Array.smartmap f bl in
+ let bl' = Array.Smart.map f bl in
if b'==b && p'==p && bl'==bl then c
else mkCase (ci, p', b', bl')
| Fix (ln,(lna,tl,bl)) ->
- let tl' = Array.smartmap f tl in
- let bl' = Array.smartmap f bl in
+ let tl' = Array.Smart.map f tl in
+ let bl' = Array.Smart.map f bl in
if tl'==tl && bl'==bl then c
else mkFix (ln,(lna,tl',bl'))
| CoFix(ln,(lna,tl,bl)) ->
- let tl' = Array.smartmap f tl in
- let bl' = Array.smartmap f bl in
+ let tl' = Array.Smart.map f tl in
+ let bl' = Array.Smart.map f bl in
if tl'==tl && bl'==bl then c
else mkCoFix (ln,(lna,tl',bl'))
@@ -464,7 +347,7 @@ let map_with_binders sigma g f l c0 = match kind sigma c0 with
else mkLetIn (na, b', t', c')
| App (c, al) ->
let c' = f l c in
- let al' = CArray.Fun1.smartmap f l al in
+ let al' = Array.Fun1.Smart.map f l al in
if c' == c && al' == al then c0
else mkApp (c', al')
| Proj (p, t) ->
@@ -472,25 +355,25 @@ let map_with_binders sigma g f l c0 = match kind sigma c0 with
if t' == t then c0
else mkProj (p, t')
| Evar (e, al) ->
- let al' = CArray.Fun1.smartmap f l al in
+ let al' = Array.Fun1.Smart.map f l al in
if al' == al then c0
else mkEvar (e, al')
| Case (ci, p, c, bl) ->
let p' = f l p in
let c' = f l c in
- let bl' = CArray.Fun1.smartmap f l bl in
+ let bl' = Array.Fun1.Smart.map f l bl in
if p' == p && c' == c && bl' == bl then c0
else mkCase (ci, p', c', bl')
| Fix (ln, (lna, tl, bl)) ->
- let tl' = CArray.Fun1.smartmap f l tl in
+ let tl' = Array.Fun1.Smart.map f l tl in
let l' = iterate g (Array.length tl) l in
- let bl' = CArray.Fun1.smartmap f l' bl in
+ let bl' = Array.Fun1.Smart.map f l' bl in
if tl' == tl && bl' == bl then c0
else mkFix (ln,(lna,tl',bl'))
| CoFix(ln,(lna,tl,bl)) ->
- let tl' = CArray.Fun1.smartmap f l tl in
+ let tl' = Array.Fun1.Smart.map f l tl in
let l' = iterate g (Array.length tl) l in
- let bl' = CArray.Fun1.smartmap f l' bl in
+ let bl' = Array.Fun1.Smart.map f l' bl in
mkCoFix (ln,(lna,tl',bl'))
let iter sigma f c = match kind sigma c with
@@ -516,9 +399,9 @@ let iter_with_full_binders sigma g f n c =
| Prod (na,t,c) -> f n t; f (g (LocalAssum (na, t)) n) c
| Lambda (na,t,c) -> f n t; f (g (LocalAssum (na, t)) n) c
| LetIn (na,b,t,c) -> f n b; f n t; f (g (LocalDef (na, b, t)) n) c
- | App (c,l) -> f n c; CArray.Fun1.iter f n l
- | Evar (_,l) -> CArray.Fun1.iter f n l
- | Case (_,p,c,bl) -> f n p; f n c; CArray.Fun1.iter f n bl
+ | App (c,l) -> f n c; Array.Fun1.iter f n l
+ | Evar (_,l) -> Array.Fun1.iter f n l
+ | Case (_,p,c,bl) -> f n p; f n c; Array.Fun1.iter f n bl
| Proj (p,c) -> f n c
| Fix (_,(lna,tl,bl)) ->
Array.iter (f n) tl;
@@ -551,10 +434,22 @@ let fold sigma f acc c = match kind sigma c with
let compare_gen k eq_inst eq_sort eq_constr nargs c1 c2 =
(c1 == c2) || Constr.compare_head_gen_with k k eq_inst eq_sort eq_constr nargs c1 c2
+let eq_einstance sigma i1 i2 =
+ let i1 = EInstance.kind sigma (EInstance.make i1) in
+ let i2 = EInstance.kind sigma (EInstance.make i2) in
+ Univ.Instance.equal i1 i2
+
+let eq_esorts sigma s1 s2 =
+ let s1 = ESorts.kind sigma (ESorts.make s1) in
+ let s2 = ESorts.kind sigma (ESorts.make s2) in
+ Sorts.equal s1 s2
+
let eq_constr sigma c1 c2 =
let kind c = kind_upto sigma c in
+ let eq_inst _ _ i1 i2 = eq_einstance sigma i1 i2 in
+ let eq_sorts s1 s2 = eq_esorts sigma s1 s2 in
let rec eq_constr nargs c1 c2 =
- compare_gen kind (fun _ _ -> Univ.Instance.equal) Sorts.equal eq_constr nargs c1 c2
+ compare_gen kind eq_inst eq_sorts eq_constr nargs c1 c2
in
eq_constr 0 (unsafe_to_constr c1) (unsafe_to_constr c2)
@@ -567,32 +462,34 @@ let eq_constr_nounivs sigma c1 c2 =
let compare_constr sigma cmp c1 c2 =
let kind c = kind_upto sigma c in
+ let eq_inst _ _ i1 i2 = eq_einstance sigma i1 i2 in
+ let eq_sorts s1 s2 = eq_esorts sigma s1 s2 in
let cmp nargs c1 c2 = cmp (of_constr c1) (of_constr c2) in
- compare_gen kind (fun _ _ -> Univ.Instance.equal) Sorts.equal cmp 0 (unsafe_to_constr c1) (unsafe_to_constr c2)
+ compare_gen kind eq_inst eq_sorts cmp 0 (unsafe_to_constr c1) (unsafe_to_constr c2)
let compare_cumulative_instances cv_pb nargs_ok variances u u' cstrs =
- let open Universes in
+ let open UnivProblem in
if not nargs_ok then enforce_eq_instances_univs false u u' cstrs
else
CArray.fold_left3
(fun cstrs v u u' ->
let open Univ.Variance in
match v with
- | Irrelevant -> Constraints.add (UWeak (u,u')) cstrs
+ | Irrelevant -> Set.add (UWeak (u,u')) cstrs
| Covariant ->
let u = Univ.Universe.make u in
let u' = Univ.Universe.make u' in
(match cv_pb with
- | Reduction.CONV -> Constraints.add (UEq (u,u')) cstrs
- | Reduction.CUMUL -> Constraints.add (ULe (u,u')) cstrs)
+ | Reduction.CONV -> Set.add (UEq (u,u')) cstrs
+ | Reduction.CUMUL -> Set.add (ULe (u,u')) cstrs)
| Invariant ->
let u = Univ.Universe.make u in
let u' = Univ.Universe.make u' in
- Constraints.add (UEq (u,u')) cstrs)
+ Set.add (UEq (u,u')) cstrs)
cstrs variances (Univ.Instance.to_array u) (Univ.Instance.to_array u')
let cmp_inductives cv_pb (mind,ind as spec) nargs u1 u2 cstrs =
- let open Universes in
+ let open UnivProblem in
match mind.Declarations.mind_universes with
| Declarations.Monomorphic_ind _ ->
assert (Univ.Instance.length u1 = 0 && Univ.Instance.length u2 = 0);
@@ -605,7 +502,7 @@ let cmp_inductives cv_pb (mind,ind as spec) nargs u1 u2 cstrs =
compare_cumulative_instances cv_pb (Int.equal num_param_arity nargs) variances u1 u2 cstrs
let cmp_constructors (mind, ind, cns as spec) nargs u1 u2 cstrs =
- let open Universes in
+ let open UnivProblem in
match mind.Declarations.mind_universes with
| Declarations.Monomorphic_ind _ ->
cstrs
@@ -616,7 +513,7 @@ let cmp_constructors (mind, ind, cns as spec) nargs u1 u2 cstrs =
if not (Int.equal num_cnstr_args nargs)
then enforce_eq_instances_univs false u1 u2 cstrs
else
- Array.fold_left2 (fun cstrs u1 u2 -> Universes.(Constraints.add (UWeak (u1,u2)) cstrs))
+ Array.fold_left2 (fun cstrs u1 u2 -> UnivProblem.(Set.add (UWeak (u1,u2)) cstrs))
cstrs (Univ.Instance.to_array u1) (Univ.Instance.to_array u2)
let eq_universes env sigma cstrs cv_pb ref nargs l l' =
@@ -624,7 +521,8 @@ let eq_universes env sigma cstrs cv_pb ref nargs l l' =
else
let l = Evd.normalize_universe_instance sigma l
and l' = Evd.normalize_universe_instance sigma l' in
- let open Universes in
+ let open GlobRef in
+ let open UnivProblem in
match ref with
| VarRef _ -> assert false (* variables don't have instances *)
| ConstRef _ ->
@@ -639,11 +537,11 @@ let eq_universes env sigma cstrs cv_pb ref nargs l l' =
true
let test_constr_universes env sigma leq m n =
- let open Universes in
+ let open UnivProblem in
let kind c = kind_upto sigma c in
- if m == n then Some Constraints.empty
+ if m == n then Some Set.empty
else
- let cstrs = ref Constraints.empty in
+ let cstrs = ref Set.empty in
let cv_pb = if leq then Reduction.CUMUL else Reduction.CONV in
let eq_universes ref nargs l l' = eq_universes env sigma cstrs Reduction.CONV ref nargs l l'
and leq_universes ref nargs l l' = eq_universes env sigma cstrs cv_pb ref nargs l l' in
@@ -651,7 +549,7 @@ let test_constr_universes env sigma leq m n =
let s1 = ESorts.kind sigma (ESorts.make s1) in
let s2 = ESorts.kind sigma (ESorts.make s2) in
if Sorts.equal s1 s2 then true
- else (cstrs := Constraints.add
+ else (cstrs := Set.add
(UEq (Sorts.univ_of_sort s1,Sorts.univ_of_sort s2)) !cstrs;
true)
in
@@ -660,7 +558,7 @@ let test_constr_universes env sigma leq m n =
let s2 = ESorts.kind sigma (ESorts.make s2) in
if Sorts.equal s1 s2 then true
else
- (cstrs := Constraints.add
+ (cstrs := Set.add
(ULe (Sorts.univ_of_sort s1,Sorts.univ_of_sort s2)) !cstrs;
true)
in
@@ -689,24 +587,23 @@ let compare_head_gen_proj env sigma equ eqs eqc' nargs m n =
| App (f, args), Proj (p, c) ->
(match kind_upto sigma f with
| Const (p', u) when Constant.equal (Projection.constant p) p' ->
- let pb = Environ.lookup_projection p env in
- let npars = pb.Declarations.proj_npars in
- if Array.length args == npars + 1 then
+ let npars = Projection.npars p in
+ if Array.length args == npars + 1 then
eqc' 0 c args.(npars)
else false
| _ -> false)
| _ -> Constr.compare_head_gen_with kind kind equ eqs eqc' nargs m n
let eq_constr_universes_proj env sigma m n =
- let open Universes in
- if m == n then Some Constraints.empty
+ let open UnivProblem in
+ if m == n then Some Set.empty
else
- let cstrs = ref Constraints.empty in
+ let cstrs = ref Set.empty in
let eq_universes ref l l' = eq_universes env sigma cstrs Reduction.CONV ref l l' in
let eq_sorts s1 s2 =
if Sorts.equal s1 s2 then true
else
- (cstrs := Constraints.add
+ (cstrs := Set.add
(UEq (Sorts.univ_of_sort s1, Sorts.univ_of_sort s2)) !cstrs;
true)
in
@@ -716,25 +613,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
@@ -743,7 +629,7 @@ let universes_of_constr env sigma c =
LSet.fold LSet.add (Universe.levels u) s
| Evar (k, args) ->
let concl = Evd.evar_concl (Evd.find sigma k) in
- fold sigma aux (aux s (of_constr concl)) c
+ fold sigma aux (aux s concl) c
| _ -> fold sigma aux s c
in aux LSet.empty c
@@ -901,9 +787,13 @@ let named_context e = cast_named_context (sym unsafe_eq) (named_context e)
let val_of_named_context e = val_of_named_context (cast_named_context unsafe_eq e)
let named_context_of_val e = cast_named_context (sym unsafe_eq) (named_context_of_val e)
+let of_existential : Constr.existential -> existential =
+ let gen : type a b. (a,b) eq -> 'c * b array -> 'c * a array = fun Refl x -> x in
+ gen unsafe_eq
+
let lookup_rel i e = cast_rel_decl (sym unsafe_eq) (lookup_rel i e)
let lookup_named n e = cast_named_decl (sym unsafe_eq) (lookup_named n e)
-let lookup_named_val n e = cast_named_decl (sym unsafe_eq) (lookup_named_val n e)
+let lookup_named_val n e = cast_named_decl (sym unsafe_eq) (lookup_named_ctxt n e)
let map_rel_context_in_env f env sign =
let rec aux env acc = function
@@ -916,7 +806,7 @@ let map_rel_context_in_env f env sign =
let fresh_global ?loc ?rigid ?names env sigma reference =
let (evd,t) = Evd.fresh_global ?loc ?rigid ?names env sigma reference in
- evd, of_constr t
+ evd, t
let is_global sigma gr c =
Globnames.is_global gr (to_constr sigma c)
@@ -928,5 +818,10 @@ let to_instance = EInstance.unsafe_to_instance
let to_constr = unsafe_to_constr
let to_rel_decl = unsafe_to_rel_decl
let to_named_decl = unsafe_to_named_decl
+let to_named_context =
+ let gen : type a b. (a, b) eq -> (a,a) Context.Named.pt -> (b,b) Context.Named.pt
+ = fun Refl x -> x
+ in
+ gen unsafe_eq
let eq = unsafe_eq
end
diff --git a/engine/eConstr.mli b/engine/eConstr.mli
index 8ee3b905..00c6d7ce 100644
--- a/engine/eConstr.mli
+++ b/engine/eConstr.mli
@@ -13,7 +13,7 @@ open Names
open Constr
open Environ
-type t
+type t = Evd.econstr
(** Type of incomplete terms. Essentially a wrapper around {!Constr.t} ensuring
that {!Constr.kind} does not observe defined evars. *)
@@ -68,11 +68,14 @@ val kind : Evd.evar_map -> t -> (t, t, ESorts.t, EInstance.t) Constr.kind_of_ter
val kind_upto : Evd.evar_map -> Constr.t -> (Constr.t, Constr.t, Sorts.t, Univ.Instance.t) Constr.kind_of_term
-val to_constr : Evd.evar_map -> t -> Constr.t
-(** Returns the evar-normal form of the argument, and cast it as a theoretically
- evar-free term. In practice this function does not check that the result
- is actually evar-free, it is currently the duty of the caller to do so.
- This might change in the future. *)
+val to_constr : ?abort_on_undefined_evars:bool -> Evd.evar_map -> t -> Constr.t
+(** Returns the evar-normal form of the argument. Note that this
+ function is supposed to be called when the original term has not
+ more free-evars anymore. If you need compatibility with the old
+ semantics, set [abort_on_undefined_evars] to [false].
+
+ For getting the evar-normal form of a term with evars see
+ {!Evarutil.nf_evar}. *)
val kind_of_type : Evd.evar_map -> t -> (t, t) Term.kind_of_type
@@ -152,6 +155,8 @@ val isCoFix : Evd.evar_map -> t -> bool
val isCase : Evd.evar_map -> t -> bool
val isProj : Evd.evar_map -> t -> bool
+val isType : Evd.evar_map -> constr -> bool
+
type arity = rel_context * ESorts.t
val destArity : Evd.evar_map -> types -> arity
val isArity : Evd.evar_map -> t -> bool
@@ -179,9 +184,21 @@ val destCoFix : Evd.evar_map -> t -> (t, t) pcofixpoint
val decompose_app : Evd.evar_map -> t -> t * t list
+(** Pops lambda abstractions until there are no more, skipping casts. *)
val decompose_lam : Evd.evar_map -> t -> (Name.t * t) list * t
+
+(** Pops lambda abstractions and letins until there are no more, skipping casts. *)
val decompose_lam_assum : Evd.evar_map -> t -> rel_context * t
+
+(** Pops [n] lambda abstractions, and pop letins only if needed to
+ expose enough lambdas, skipping casts.
+
+ @raise UserError if the term doesn't have enough lambdas. *)
val decompose_lam_n_assum : Evd.evar_map -> int -> t -> rel_context * t
+
+(** Pops [n] lambda abstractions and letins, skipping casts.
+
+ @raise UserError if the term doesn't have enough lambdas/letins. *)
val decompose_lam_n_decls : Evd.evar_map -> int -> t -> rel_context * t
val compose_lam : (Name.t * t) list -> t -> t
@@ -198,11 +215,11 @@ val whd_evar : Evd.evar_map -> constr -> constr
val eq_constr : Evd.evar_map -> t -> t -> bool
val eq_constr_nounivs : Evd.evar_map -> t -> t -> bool
-val eq_constr_universes : Environ.env -> Evd.evar_map -> t -> t -> Universes.Constraints.t option
-val leq_constr_universes : Environ.env -> Evd.evar_map -> t -> t -> Universes.Constraints.t option
+val eq_constr_universes : Environ.env -> Evd.evar_map -> t -> t -> UnivProblem.Set.t option
+val leq_constr_universes : Environ.env -> Evd.evar_map -> t -> t -> UnivProblem.Set.t option
(** [eq_constr_universes_proj] can equate projections and their eta-expanded constant form. *)
-val eq_constr_universes_proj : Environ.env -> Evd.evar_map -> t -> t -> Universes.Constraints.t option
+val eq_constr_universes_proj : Environ.env -> Evd.evar_map -> t -> t -> UnivProblem.Set.t option
val compare_constr : Evd.evar_map -> (t -> t -> bool) -> t -> t -> bool
@@ -217,7 +234,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} *)
@@ -281,12 +298,13 @@ val map_rel_context_in_env :
(* XXX Missing Sigma proxy *)
val fresh_global :
?loc:Loc.t -> ?rigid:Evd.rigid -> ?names:Univ.Instance.t -> Environ.env ->
- Evd.evar_map -> Globnames.global_reference -> Evd.evar_map * t
+ Evd.evar_map -> GlobRef.t -> Evd.evar_map * t
-val is_global : Evd.evar_map -> Globnames.global_reference -> t -> bool
+val is_global : Evd.evar_map -> GlobRef.t -> t -> bool
(** {5 Extra} *)
+val of_existential : Constr.existential -> existential
val of_named_decl : (Constr.t, Constr.types) Context.Named.Declaration.pt -> (t, types) Context.Named.Declaration.pt
val of_rel_decl : (Constr.t, Constr.types) Context.Rel.Declaration.pt -> (t, types) Context.Rel.Declaration.pt
@@ -305,6 +323,8 @@ 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 -> Constr.named_context
+
val to_sorts : ESorts.t -> Sorts.t
(** Physical identity. Does not care for normalization. *)
diff --git a/engine/engine.mllib b/engine/engine.mllib
index a3614f6c..37e83b62 100644
--- a/engine/engine.mllib
+++ b/engine/engine.mllib
@@ -1,7 +1,13 @@
+UnivNames
+UnivGen
+UnivSubst
+UnivProblem
+UnivMinim
Universes
Univops
UState
Nameops
+Evar_kinds
Evd
EConstr
Namegen
diff --git a/engine/evar_kinds.ml b/engine/evar_kinds.ml
new file mode 100644
index 00000000..ea1e5725
--- /dev/null
+++ b/engine/evar_kinds.ml
@@ -0,0 +1,52 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* None
(** Combinators *)
@@ -44,11 +44,11 @@ let evd_comb2 f evdref x y =
z
let e_new_global evdref x =
- EConstr.of_constr (evd_comb1 (Evd.fresh_global (Global.env())) evdref x)
+ evd_comb1 (Evd.fresh_global (Global.env())) evdref x
let new_global evd x =
let (evd, c) = Evd.fresh_global (Global.env()) evd x in
- (evd, EConstr.of_constr c)
+ (evd, c)
(****************************************************)
(* Expanding/testing/exposing existential variables *)
@@ -61,7 +61,7 @@ exception Uninstantiated_evar of Evar.t
let rec flush_and_check_evars sigma c =
match kind c with
| Evar (evk,_ as ev) ->
- (match existential_opt_value sigma ev with
+ (match existential_opt_value0 sigma ev with
| None -> raise (Uninstantiated_evar evk)
| Some c -> flush_and_check_evars sigma c)
| _ -> Constr.map (flush_and_check_evars sigma) c
@@ -72,9 +72,9 @@ let flush_and_check_evars sigma c =
(** Term exploration up to instantiation. *)
let kind_of_term_upto = EConstr.kind_upto
-let nf_evar0 sigma t = EConstr.to_constr sigma (EConstr.of_constr t)
+let nf_evar0 sigma t = EConstr.to_constr ~abort_on_undefined_evars:false sigma (EConstr.of_constr t)
let whd_evar = EConstr.whd_evar
-let nf_evar sigma c = EConstr.of_constr (EConstr.to_constr sigma c)
+let nf_evar sigma c = EConstr.of_constr (EConstr.to_constr ~abort_on_undefined_evars:false sigma c)
let j_nf_evar sigma j =
{ uj_val = nf_evar sigma j.uj_val;
@@ -85,7 +85,7 @@ let tj_nf_evar sigma {utj_val=v;utj_type=t} =
{utj_val=nf_evar sigma v;utj_type=t}
let nf_evars_universes evm =
- Universes.nf_evars_and_universes_opt_subst (safe_evar_value evm)
+ UnivSubst.nf_evars_and_universes_opt_subst (safe_evar_value evm)
(Evd.universe_subst evm)
let nf_evars_and_universes evm =
@@ -102,7 +102,8 @@ let nf_evar_map_universes evm =
if Univ.LMap.is_empty subst then evm, nf_evar0 evm
else
let f = nf_evars_universes evm in
- Evd.raw_map (fun _ -> map_evar_info f) evm, f
+ let f' c = EConstr.of_constr (f (EConstr.Unsafe.to_constr c)) in
+ Evd.raw_map (fun _ -> map_evar_info f') evm, f
let nf_named_context_evar sigma ctx =
Context.Named.map (nf_evar0 sigma) ctx
@@ -115,7 +116,7 @@ let nf_env_evar sigma env =
let rel' = nf_rel_context_evar sigma (EConstr.rel_context env) in
EConstr.push_rel_context rel' (reset_with_named_context (val_of_named_context nc') env)
-let nf_evar_info evc info = map_evar_info (nf_evar0 evc) info
+let nf_evar_info evc info = map_evar_info (nf_evar evc) info
let nf_evar_map evm =
Evd.raw_map (fun _ evi -> nf_evar_info evm evi) evm
@@ -212,7 +213,7 @@ let mk_new_meta () = EConstr.mkMeta(new_meta())
let non_instantiated sigma =
let listev = Evd.undefined_map sigma in
- Evar.Map.smartmap (fun evi -> nf_evar_info sigma evi) listev
+ Evar.Map.Smart.map (fun evi -> nf_evar_info sigma evi) listev
(************************)
(* Manipulating filters *)
@@ -340,7 +341,15 @@ let update_var src tgt subst =
let csubst_var = Id.Map.add id (Constr.mkVar tgt) subst.csubst_var in
{ subst with csubst_var; csubst_rev }
-let push_rel_decl_to_named_context sigma decl (subst, avoid, nc) =
+type naming_mode =
+ | KeepUserNameAndRenameExistingButSectionNames
+ | KeepUserNameAndRenameExistingEvenSectionNames
+ | KeepExistingNames
+ | FailIfConflict
+
+let push_rel_decl_to_named_context
+ ?(hypnaming=KeepUserNameAndRenameExistingButSectionNames)
+ sigma decl (subst, avoid, nc) =
let open EConstr in
let open Vars in
let map_decl f d =
@@ -371,7 +380,9 @@ let push_rel_decl_to_named_context sigma decl (subst, avoid, nc) =
next_ident_away (id_of_name_using_hdchar empty_env sigma (RelDecl.get_type decl) na) avoid
in
match extract_if_neq id na with
- | Some id0 when not (is_section_variable id0) ->
+ | Some id0 when hypnaming = KeepUserNameAndRenameExistingEvenSectionNames ||
+ hypnaming = KeepUserNameAndRenameExistingButSectionNames &&
+ not (is_section_variable id0) ->
(* spiwack: if [id<>id0], rather than introducing a new
binding named [id], we will keep [id0] (the name given
by the user) and rename [id0] into [id] in the named
@@ -380,6 +391,8 @@ let push_rel_decl_to_named_context sigma decl (subst, avoid, nc) =
let d = decl |> NamedDecl.of_rel_decl (fun _ -> id0) |> map_decl (csubst_subst subst) in
let nc = List.map (replace_var_named_declaration id0 id) nc in
(push_var id0 subst, Id.Set.add id avoid, d :: nc)
+ | Some id0 when hypnaming = FailIfConflict ->
+ user_err Pp.(Id.print id0 ++ str " is already used.")
| _ ->
(* spiwack: if [id0] is a section variable renaming it is
incorrect. We revert to a less robust behaviour where
@@ -388,7 +401,7 @@ let push_rel_decl_to_named_context sigma decl (subst, avoid, nc) =
let d = decl |> NamedDecl.of_rel_decl (fun _ -> id) |> map_decl (csubst_subst subst) in
(push_var id subst, Id.Set.add id avoid, d :: nc)
-let push_rel_context_to_named_context env sigma typ =
+let push_rel_context_to_named_context ?hypnaming env sigma typ =
(* compute the instances relative to the named context and rel_context *)
let open Context.Named.Declaration in
let open EConstr in
@@ -403,7 +416,7 @@ let push_rel_context_to_named_context env sigma typ =
(* with vars of the rel context *)
(* We do keep the instances corresponding to local definition (see above) *)
let (subst, _, env) =
- Context.Rel.fold_outside (fun d acc -> push_rel_decl_to_named_context sigma d acc)
+ Context.Rel.fold_outside (fun d acc -> push_rel_decl_to_named_context ?hypnaming sigma d acc)
(rel_context env) ~init:(empty_csubst, avoid, named_context env) in
(val_of_named_context env, csubst_subst subst typ, inst_rels@inst_vars, subst)
@@ -413,25 +426,18 @@ let push_rel_context_to_named_context env sigma typ =
let default_source = Loc.tag @@ Evar_kinds.InternalHole
-let restrict_evar evd evk filter ?src candidates =
- let candidates = Option.map (fun l -> List.map EConstr.Unsafe.to_constr l) candidates in
- 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
(evd, evk)
-let new_pure_evar sign evd ?(src=default_source) ?(filter = Filter.identity) ?candidates ?(store = Store.empty) ?naming ?(principal=false) typ =
- let typ = EConstr.Unsafe.to_constr typ in
- let candidates = Option.map (fun l -> List.map EConstr.Unsafe.to_constr l) candidates in
- let default_naming = Misctypes.IntroAnonymous in
+let new_pure_evar?(src=default_source) ?(filter = Filter.identity) ?candidates ?(store = Store.empty) ?naming ?(principal=false) sign evd typ =
+ let default_naming = IntroAnonymous in
let naming = Option.default default_naming naming in
let name = match naming with
- | Misctypes.IntroAnonymous -> None
- | Misctypes.IntroIdentifier id -> Some id
- | Misctypes.IntroFresh id ->
+ | IntroAnonymous -> None
+ | IntroIdentifier id -> Some id
+ | IntroFresh id ->
let has_name id = try let _ = Evd.evar_key id evd in true with Not_found -> false in
let id = Namegen.next_ident_away_from id has_name in
Some id
@@ -452,14 +458,14 @@ let new_pure_evar sign evd ?(src=default_source) ?(filter = Filter.identity) ?ca
in
(evd, newevk)
-let new_evar_instance sign evd typ ?src ?filter ?candidates ?store ?naming ?principal instance =
+let new_evar_instance ?src ?filter ?candidates ?store ?naming ?principal sign evd typ instance =
let open EConstr in
assert (not !Flags.debug ||
List.distinct (ids_of_named_context (named_context_of_val sign)));
let (evd, newevk) = new_pure_evar sign evd ?src ?filter ?candidates ?store ?naming ?principal typ in
evd, mkEvar (newevk,Array.of_list instance)
-let new_evar_from_context sign evd ?src ?filter ?candidates ?store ?naming ?principal typ =
+let new_evar_from_context ?src ?filter ?candidates ?store ?naming ?principal sign evd typ =
let instance = List.map (NamedDecl.get_id %> EConstr.mkVar) (named_context_of_val sign) in
let instance =
match filter with
@@ -469,8 +475,8 @@ let new_evar_from_context sign evd ?src ?filter ?candidates ?store ?naming ?prin
(* [new_evar] declares a new existential in an env env with type typ *)
(* Converting the env into the sign of the evar to define *)
-let new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
- let sign,typ',instance,subst = push_rel_context_to_named_context env evd typ in
+let new_evar ?src ?filter ?candidates ?store ?naming ?principal ?hypnaming env evd typ =
+ let sign,typ',instance,subst = push_rel_context_to_named_context ?hypnaming env evd typ in
let map c = csubst_subst subst c in
let candidates = Option.map (fun l -> List.map map l) candidates in
let instance =
@@ -479,31 +485,46 @@ let new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
| Some filter -> Filter.filter_list filter instance in
new_evar_instance sign evd typ' ?src ?filter ?candidates ?store ?naming ?principal instance
-let new_type_evar env evd ?src ?filter ?naming ?principal rigid =
+let new_type_evar ?src ?filter ?naming ?principal ?hypnaming env evd rigid =
let (evd', s) = new_sort_variable rigid evd in
- let (evd', e) = new_evar env evd' ?src ?filter ?naming ?principal (EConstr.mkSort s) in
+ let (evd', e) = new_evar env evd' ?src ?filter ?naming ?principal ?hypnaming (EConstr.mkSort s) in
evd', (e, s)
-let e_new_type_evar env evdref ?src ?filter ?naming ?principal rigid =
- let (evd, c) = new_type_evar env !evdref ?src ?filter ?naming ?principal rigid in
+let e_new_type_evar env evdref ?src ?filter ?naming ?principal ?hypnaming rigid =
+ let (evd, c) = new_type_evar env !evdref ?src ?filter ?naming ?principal ?hypnaming rigid in
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
(* The same using side-effect *)
-let e_new_evar env evdref ?(src=default_source) ?filter ?candidates ?store ?naming ?principal ty =
- let (evd',ev) = new_evar env !evdref ~src:src ?filter ?candidates ?store ?naming ?principal ty in
+let e_new_evar env evdref ?(src=default_source) ?filter ?candidates ?store ?naming ?principal ?hypnaming ty =
+ let (evd',ev) = new_evar env !evdref ~src:src ?filter ?candidates ?store ?naming ?principal ?hypnaming ty in
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) =
@@ -513,7 +534,7 @@ let generalize_evar_over_rels sigma (ev,args) =
List.fold_left2
(fun (c,inst as x) a d ->
if isRel sigma a then (mkNamedProd_or_LetIn d c,a::inst) else x)
- (EConstr.of_constr evi.evar_concl,[]) (Array.to_list args) sign
+ (evi.evar_concl,[]) (Array.to_list args) sign
(************************************)
(* Removing a dependency in an evar *)
@@ -522,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
+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
@@ -534,13 +577,13 @@ let rec check_and_clear_in_constr env evdref err ids global c =
is a section variable *)
match kind c with
| Var id' ->
- if Id.Set.mem id' ids then raise (ClearDependencyError (id', err)) else c
+ if Id.Set.mem id' ids then raise (ClearDependencyError (id', err, None)) else c
| ( Const _ | Ind _ | Construct _ ) ->
let () = if global then
let check id' =
if Id.Set.mem id' ids then
- raise (ClearDependencyError (id',err))
+ raise (ClearDependencyError (id',err,Some (Globnames.global_of_constr c)))
in
Id.Set.iter check (Environ.vars_of_global env c)
in
@@ -549,7 +592,8 @@ let rec check_and_clear_in_constr env evdref err ids global c =
| Evar (evk,l as ev) ->
if Evd.is_defined !evdref evk then
(* If evk is already defined we replace it by its definition *)
- let nc = Evd.existential_value !evdref ev in
+ let nc = Evd.existential_value !evdref (EConstr.of_existential ev) in
+ let nc = EConstr.Unsafe.to_constr nc in
(check_and_clear_in_constr env evdref err ids global nc)
else
(* We check for dependencies to elements of ids in the
@@ -559,8 +603,7 @@ let rec check_and_clear_in_constr env evdref err ids global c =
removed *)
let evi = Evd.find_undefined !evdref evk in
let ctxt = Evd.evar_filtered_context evi in
- let ctxt = List.map (fun d -> map_named_decl EConstr.of_constr d) ctxt in
- let (rids,filter) =
+ let (rids,filter) =
List.fold_right2
(fun h a (ri,filter) ->
try
@@ -586,25 +629,29 @@ let rec check_and_clear_in_constr env evdref err ids global c =
try
let nids = Id.Map.domain rids in
let global = Id.Set.exists is_section_variable nids in
- check_and_clear_in_constr env evdref (EvarTypingBreak ev) nids global (evar_concl evi)
- with ClearDependencyError (rid,err) ->
- raise (ClearDependencyError (Id.Map.find rid rids,err)) in
+ let concl = EConstr.Unsafe.to_constr (evar_concl evi) in
+ check_and_clear_in_constr env evdref (EvarTypingBreak ev) nids global concl
+ with ClearDependencyError (rid,err,where) ->
+ raise (ClearDependencyError (Id.Map.find rid rids,err,where)) in
if Id.Map.is_empty rids then c
else
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_value !evdref ev
+ Evd.existential_value0 !evdref ev
| _ -> Constr.map (check_and_clear_in_constr env evdref err ids global) c
-let clear_hyps_in_evi_main env evdref hyps terms ids =
+let clear_hyps_in_evi_main env sigma hyps terms ids =
(* clear_hyps_in_evi erases hypotheses ids in hyps, checking if some
hypothesis does not depend on a element of ids, and erases ids in
the contexts of the evars occurring in evi *)
+ let evdref = ref sigma in
let terms = List.map EConstr.Unsafe.to_constr terms in
let global = Id.Set.exists is_section_variable ids in
let terms =
@@ -627,23 +674,23 @@ let clear_hyps_in_evi_main env evdref hyps terms ids =
in
remove_hyps ids check_context check_value hyps
in
- (nhyps,List.map EConstr.of_constr terms)
+ (!evdref, nhyps,List.map EConstr.of_constr terms)
-let clear_hyps_in_evi env evdref hyps concl ids =
- match clear_hyps_in_evi_main env evdref hyps [concl] ids with
- | (nhyps,[nconcl]) -> (nhyps,nconcl)
+let clear_hyps_in_evi env sigma hyps concl ids =
+ match clear_hyps_in_evi_main env sigma hyps [concl] ids with
+ | (sigma,nhyps,[nconcl]) -> (sigma,nhyps,nconcl)
| _ -> assert false
-let clear_hyps2_in_evi env evdref hyps t concl ids =
- match clear_hyps_in_evi_main env evdref hyps [t;concl] ids with
- | (nhyps,[t;nconcl]) -> (nhyps,t,nconcl)
+let clear_hyps2_in_evi env sigma hyps t concl ids =
+ match clear_hyps_in_evi_main env sigma hyps [t;concl] ids with
+ | (sigma,nhyps,[t;nconcl]) -> (sigma,nhyps,t,nconcl)
| _ -> assert false
(* spiwack: a few functions to gather evars on which goals depend. *)
let queue_set q is_dependent set =
Evar.Set.iter (fun a -> Queue.push (is_dependent,a) q) set
let queue_term q is_dependent c =
- queue_set q is_dependent (evars_of_term c)
+ queue_set q is_dependent (evars_of_term (EConstr.Unsafe.to_constr c))
let process_dependent_evar q acc evm is_dependent e =
let evi = Evd.find evm e in
@@ -656,12 +703,12 @@ let process_dependent_evar q acc evm is_dependent e =
match decl with
| LocalAssum _ -> ()
| LocalDef (_,b,_) -> queue_term q true b
- end (Environ.named_context_of_val evi.evar_hyps);
+ end (EConstr.named_context_of_val evi.evar_hyps);
match evi.evar_body with
| Evar_empty ->
if is_dependent then Evar.Map.add e None acc else acc
| Evar_defined b ->
- let subevars = evars_of_term b in
+ let subevars = evars_of_term (EConstr.Unsafe.to_constr b) in
(* evars appearing in the definition of an evar [e] are marked
as dependent when [e] is dependent itself: if [e] is a
non-dependent goal, then, unless they are reach from another
@@ -729,11 +776,11 @@ let undefined_evars_of_named_context evd nc =
~init:Evar.Set.empty
let undefined_evars_of_evar_info evd evi =
- Evar.Set.union (undefined_evars_of_term evd (EConstr.of_constr evi.evar_concl))
+ Evar.Set.union (undefined_evars_of_term evd evi.evar_concl)
(Evar.Set.union
(match evi.evar_body with
| Evar_empty -> Evar.Set.empty
- | Evar_defined b -> undefined_evars_of_term evd (EConstr.of_constr b))
+ | Evar_defined b -> undefined_evars_of_term evd b)
(undefined_evars_of_named_context evd
(named_context_of_val evi.evar_hyps)))
@@ -781,10 +828,11 @@ let filtered_undefined_evars_of_evar_info ?cache sigma evi =
in
let accu = match evi.evar_body with
| Evar_empty -> Evar.Set.empty
- | Evar_defined b -> evars_of_term b
+ | Evar_defined b -> evars_of_term (EConstr.Unsafe.to_constr b)
in
- let accu = Evar.Set.union (undefined_evars_of_term sigma (EConstr.of_constr evi.evar_concl)) accu in
- evars_of_named_context cache accu (evar_filtered_context evi)
+ let accu = Evar.Set.union (undefined_evars_of_term sigma evi.evar_concl) accu in
+ let ctxt = EConstr.Unsafe.to_named_context (evar_filtered_context evi) in
+ evars_of_named_context cache accu ctxt
(* spiwack: this is a more complete version of
{!Termops.occur_evar}. The latter does not look recursively into an
@@ -794,7 +842,7 @@ let occur_evar_upto sigma n c =
let c = EConstr.Unsafe.to_constr c in
let rec occur_rec c = match kind c with
| Evar (sp,_) when Evar.equal sp n -> raise Occur
- | Evar e -> Option.iter occur_rec (existential_opt_value sigma e)
+ | Evar e -> Option.iter occur_rec (existential_opt_value0 sigma e)
| _ -> Constr.iter occur_rec c
in
try occur_rec c; false with Occur -> true
@@ -807,22 +855,22 @@ let judge_of_new_Type evd =
let (evd', s) = new_univ_variable univ_rigid evd in
(evd', { uj_val = mkSort (Type s); uj_type = mkSort (Type (Univ.super s)) })
-let subterm_source evk (loc,k) =
+let subterm_source evk ?where (loc,k) =
let evk = match k with
- | Evar_kinds.SubEvar (evk) -> evk
+ | Evar_kinds.SubEvar (None,evk) when where = None -> evk
| _ -> evk in
- (loc,Evar_kinds.SubEvar evk)
+ (loc,Evar_kinds.SubEvar (where,evk))
(* Add equality constraints for covariant/invariant positions. For
irrelevant positions, unify universes when flexible. *)
let compare_cumulative_instances cv_pb variances u u' sigma =
- let open Universes in
+ let open UnivProblem in
let cstrs = Univ.Constraint.empty in
- let soft = Constraints.empty in
+ let soft = Set.empty in
let cstrs, soft = Array.fold_left3 (fun (cstrs, soft) v u u' ->
let open Univ.Variance in
match v with
- | Irrelevant -> cstrs, Constraints.add (UWeak (u,u')) soft
+ | Irrelevant -> cstrs, Set.add (UWeak (u,u')) soft
| Covariant when cv_pb == Reduction.CUMUL ->
Univ.Constraint.add (u,Univ.Le,u') cstrs, soft
| Covariant | Invariant -> Univ.Constraint.add (u,Univ.Eq,u') cstrs, soft)
@@ -834,10 +882,10 @@ let compare_cumulative_instances cv_pb variances u u' sigma =
| exception Univ.UniverseInconsistency p -> Inr p
let compare_constructor_instances evd u u' =
- let open Universes in
+ let open UnivProblem in
let soft =
- Array.fold_left2 (fun cs u u' -> Constraints.add (UWeak (u,u')) cs)
- Constraints.empty (Univ.Instance.to_array u) (Univ.Instance.to_array u')
+ Array.fold_left2 (fun cs u u' -> Set.add (UWeak (u,u')) cs)
+ Set.empty (Univ.Instance.to_array u) (Univ.Instance.to_array u')
in
Evd.add_universe_constraints evd soft
@@ -849,17 +897,16 @@ let compare_constructor_instances evd u u' =
let eq_constr_univs_test sigma1 sigma2 t u =
(* spiwack: mild code duplication with {!Evd.eq_constr_univs}. *)
let open Evd in
+ let t = EConstr.Unsafe.to_constr t
+ and u = EConstr.Unsafe.to_constr u in
let fold cstr sigma =
try Some (add_universe_constraints sigma cstr)
with Univ.UniverseInconsistency _ | UniversesDiffer -> None
in
let ans =
- Universes.eq_constr_univs_infer_with
+ UnivProblem.eq_constr_univs_infer_with
(fun t -> kind_of_term_upto sigma1 t)
(fun u -> kind_of_term_upto sigma2 u)
(universes sigma2) fold t u sigma2
in
match ans with None -> false | Some _ -> true
-
-type type_constraint = EConstr.types option
-type val_constraint = EConstr.constr option
diff --git a/engine/evarutil.mli b/engine/evarutil.mli
index e289ca16..0ad323ac 100644
--- a/engine/evarutil.mli
+++ b/engine/evarutil.mli
@@ -12,6 +12,7 @@ open Names
open Constr
open Evd
open Environ
+open Namegen
open EConstr
(** This module provides useful higher-level functions for evar manipulation. *)
@@ -25,53 +26,48 @@ val mk_new_meta : unit -> constr
(** {6 Creating a fresh evar given their type and context} *)
val new_evar_from_context :
- named_context_val -> evar_map -> ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
+ ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
?candidates:constr list -> ?store:Store.t ->
- ?naming:Misctypes.intro_pattern_naming_expr ->
- ?principal:bool -> types -> evar_map * EConstr.t
+ ?naming:intro_pattern_naming_expr ->
+ ?principal:bool ->
+ named_context_val -> evar_map -> types -> evar_map * EConstr.t
+
+type naming_mode =
+ | KeepUserNameAndRenameExistingButSectionNames
+ | KeepUserNameAndRenameExistingEvenSectionNames
+ | KeepExistingNames
+ | FailIfConflict
val new_evar :
- env -> evar_map -> ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
+ ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
?candidates:constr list -> ?store:Store.t ->
- ?naming:Misctypes.intro_pattern_naming_expr ->
- ?principal:bool -> types -> evar_map * EConstr.t
+ ?naming:intro_pattern_naming_expr ->
+ ?principal:bool -> ?hypnaming:naming_mode ->
+ env -> evar_map -> types -> evar_map * EConstr.t
val new_pure_evar :
- named_context_val -> evar_map -> ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
+ ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
?candidates:constr list -> ?store:Store.t ->
- ?naming:Misctypes.intro_pattern_naming_expr ->
- ?principal:bool -> types -> evar_map * Evar.t
+ ?naming:intro_pattern_naming_expr ->
+ ?principal:bool ->
+ named_context_val -> evar_map -> types -> evar_map * Evar.t
val new_pure_evar_full : evar_map -> evar_info -> evar_map * Evar.t
-(** the same with side-effects *)
-val e_new_evar :
- env -> evar_map ref -> ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
- ?candidates:constr list -> ?store:Store.t ->
- ?naming:Misctypes.intro_pattern_naming_expr ->
- ?principal:bool -> types -> constr
-
(** Create a new Type existential variable, as we keep track of
them during type-checking and unification. *)
val new_type_evar :
- env -> evar_map -> ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
- ?naming:Misctypes.intro_pattern_naming_expr -> ?principal:bool -> rigid ->
- evar_map * (constr * Sorts.t)
-
-val e_new_type_evar : env -> evar_map ref ->
?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
- ?naming:Misctypes.intro_pattern_naming_expr -> ?principal:bool -> rigid -> constr * Sorts.t
-
-val new_Type : ?rigid:rigid -> env -> evar_map -> evar_map * constr
-val e_new_Type : ?rigid:rigid -> env -> evar_map ref -> constr
+ ?naming:intro_pattern_naming_expr ->
+ ?principal:bool -> ?hypnaming:naming_mode ->
+ env -> evar_map -> rigid ->
+ evar_map * (constr * Sorts.t)
-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 *)
-val new_global : evar_map -> Globnames.global_reference -> evar_map * constr
-val e_new_global : evar_map ref -> Globnames.global_reference -> constr
+val new_global : evar_map -> GlobRef.t -> evar_map * constr
(** Create a fresh evar in a context different from its definition context:
[new_evar_instance sign evd ty inst] creates a new evar of context
@@ -80,10 +76,10 @@ val e_new_global : evar_map ref -> Globnames.global_reference -> constr
of [inst] are typed in the occurrence context and their type (seen
as a telescope) is [sign] *)
val new_evar_instance :
- named_context_val -> evar_map -> types ->
?src:Evar_kinds.t Loc.located -> ?filter:Filter.t -> ?candidates:constr list ->
- ?store:Store.t -> ?naming:Misctypes.intro_pattern_naming_expr ->
+ ?store:Store.t -> ?naming:intro_pattern_naming_expr ->
?principal:bool ->
+ named_context_val -> evar_map -> types ->
constr list -> evar_map * constr
val make_pure_subst : evar_info -> 'a array -> (Id.t * 'a) list
@@ -132,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
@@ -165,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
@@ -178,11 +174,12 @@ val nf_evar_map_undefined : evar_map -> evar_map
val nf_evars_universes : evar_map -> Constr.constr -> Constr.constr
val nf_evars_and_universes : evar_map -> evar_map * (Constr.constr -> Constr.constr)
-val e_nf_evars_and_universes : evar_map ref -> (Constr.constr -> Constr.constr) * Universes.universe_opt_subst
+[@@ocaml.deprecated "Use Evd.minimize_universes and nf_evars_universes"]
(** Normalize the evar map w.r.t. universes, after simplification of constraints.
Return the substitution function for constrs as well. *)
val nf_evar_map_universes : evar_map -> evar_map * (Constr.constr -> Constr.constr)
+[@@ocaml.deprecated "Use Evd.minimize_universes and nf_evar_map and nf_evars_universes"]
(** Replacing all evars, possibly raising [Uninstantiated_evar] *)
exception Uninstantiated_evar of Evar.t
@@ -201,7 +198,7 @@ val kind_of_term_upto : evar_map -> Constr.constr ->
universes. The term [t] is interpreted in [sigma1] while [u] is
interpreted in [sigma2]. The universe constraints in [sigma2] are
assumed to be an extention of those in [sigma1]. *)
-val eq_constr_univs_test : evar_map -> evar_map -> Constr.constr -> Constr.constr -> bool
+val eq_constr_univs_test : evar_map -> evar_map -> constr -> constr -> bool
(** [compare_cumulative_instances cv_pb variance u1 u2 sigma] Returns
[Inl sigma'] where [sigma'] is [sigma] augmented with universe
@@ -217,20 +214,37 @@ 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
-exception ClearDependencyError of Id.t * clear_dependency_error
+(** 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 clear_hyps_in_evi : env -> evar_map ref -> named_context_val -> types ->
- Id.Set.t -> named_context_val * types
+val restrict_evar : evar_map -> Evar.t -> Filter.t ->
+ ?src:Evar_kinds.t Loc.located -> constr list option -> evar_map * Evar.t
-val clear_hyps2_in_evi : env -> evar_map ref -> named_context_val -> types -> types ->
- Id.Set.t -> named_context_val * types * types
+val clear_hyps_in_evi : env -> evar_map -> named_context_val -> types ->
+ Id.Set.t -> evar_map * named_context_val * types
+
+val clear_hyps2_in_evi : env -> evar_map -> named_context_val -> types -> types ->
+ Id.Set.t -> evar_map * named_context_val * types * types
type csubst
@@ -240,10 +254,11 @@ val csubst_subst : csubst -> constr -> constr
type ext_named_context =
csubst * Id.Set.t * named_context
-val push_rel_decl_to_named_context :
+val push_rel_decl_to_named_context : ?hypnaming:naming_mode ->
evar_map -> rel_declaration -> ext_named_context -> ext_named_context
-val push_rel_context_to_named_context : Environ.env -> evar_map -> types ->
+val push_rel_context_to_named_context : ?hypnaming:naming_mode ->
+ Environ.env -> evar_map -> types ->
named_context_val * types * constr list * csubst
val generalize_evar_over_rels : evar_map -> existential -> types * constr list
@@ -254,13 +269,29 @@ val evd_comb0 : (evar_map -> evar_map * 'a) -> evar_map ref -> 'a
val evd_comb1 : (evar_map -> 'b -> evar_map * 'a) -> evar_map ref -> 'b -> 'a
val evd_comb2 : (evar_map -> 'b -> 'c -> evar_map * 'a) -> evar_map ref -> 'b -> 'c -> 'a
-val subterm_source : Evar.t -> Evar_kinds.t Loc.located ->
+val subterm_source : Evar.t -> ?where:Evar_kinds.subevar_kind -> Evar_kinds.t Loc.located ->
Evar_kinds.t Loc.located
val meta_counter_summary_tag : int Summary.Dyn.tag
-(** Deprecated *)
-type type_constraint = types option
-[@@ocaml.deprecated "use the version in Evardefine"]
-type val_constraint = constr option
-[@@ocaml.deprecated "use the version in Evardefine"]
+val e_new_evar :
+ env -> evar_map ref -> ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
+ ?candidates:constr list -> ?store:Store.t ->
+ ?naming:intro_pattern_naming_expr ->
+ ?principal:bool -> ?hypnaming:naming_mode -> types -> constr
+[@@ocaml.deprecated "Use [Evarutil.new_evar]"]
+
+val e_new_type_evar : env -> evar_map ref ->
+ ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
+ ?naming:intro_pattern_naming_expr ->
+ ?principal:bool -> ?hypnaming:naming_mode -> rigid -> constr * Sorts.t
+[@@ocaml.deprecated "Use [Evarutil.new_type_evar]"]
+
+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
+[@@ocaml.deprecated "Use [Evarutil.new_global]"]
+
+val e_nf_evars_and_universes : evar_map ref -> (Constr.constr -> Constr.constr) * UnivSubst.universe_opt_subst
+[@@ocaml.deprecated "Use Evd.minimize_universes and nf_evars_universes"]
diff --git a/engine/evd.ml b/engine/evd.ml
index f6e13e1f..a438e059 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -21,6 +21,9 @@ open Environ
(* module RelDecl = Context.Rel.Declaration *)
module NamedDecl = Context.Named.Declaration
+type econstr = constr
+type etypes = types
+
(** Generic filters *)
module Filter :
sig
@@ -129,8 +132,6 @@ end
module Store = Store.Make ()
-type evar = Evar.t
-
let string_of_existential evk = "?X" ^ string_of_int (Evar.repr evk)
type evar_body =
@@ -170,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
@@ -507,8 +510,8 @@ let raw_map f d =
in
ans
in
- let defn_evars = EvMap.smartmapi f d.defn_evars in
- let undf_evars = EvMap.smartmapi f d.undf_evars in
+ let defn_evars = EvMap.Smart.mapi f d.defn_evars in
+ let undf_evars = EvMap.Smart.mapi f d.undf_evars in
{ d with defn_evars; undf_evars; }
let raw_map_undefined f d =
@@ -521,7 +524,7 @@ let raw_map_undefined f d =
in
ans
in
- { d with undf_evars = EvMap.smartmapi f d.undf_evars; }
+ { d with undf_evars = EvMap.Smart.mapi f d.undf_evars; }
let is_evar = mem
@@ -537,10 +540,14 @@ let existential_value d (n, args) =
| Evar_empty ->
raise NotInstantiatedEvar
+let existential_value0 = existential_value
+
let existential_opt_value d ev =
try Some (existential_value d ev)
with NotInstantiatedEvar -> None
+let existential_opt_value0 = existential_opt_value
+
let existential_type d (n, args) =
let info =
try find d n
@@ -548,6 +555,8 @@ let existential_type d (n, args) =
anomaly (str "Evar " ++ str (string_of_existential n) ++ str " was not declared.") in
instantiate_evar_array info info.evar_concl args
+let existential_type0 = existential_type
+
let add_constraints d c =
{ d with universes = UState.add_constraints d.universes c }
@@ -613,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
@@ -763,7 +774,7 @@ let universe_subst evd =
UState.subst evd.universes
let merge_context_set ?loc ?(sideff=false) rigid evd ctx' =
- {evd with universes = UState.merge ?loc sideff rigid evd.universes ctx'}
+ {evd with universes = UState.merge ?loc ~sideff ~extend:true rigid evd.universes ctx'}
let merge_universe_subst evd subst =
{evd with universes = UState.merge_subst evd.universes subst }
@@ -794,22 +805,20 @@ 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 (Universes.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 (Universes.fresh_constant_instance env c)
+ with_context_set ?loc univ_flexible evd (UnivGen.fresh_constant_instance env c)
let fresh_inductive_instance ?loc env evd i =
- with_context_set ?loc univ_flexible evd (Universes.fresh_inductive_instance env i)
+ with_context_set ?loc univ_flexible evd (UnivGen.fresh_inductive_instance env i)
let fresh_constructor_instance ?loc env evd c =
- with_context_set ?loc univ_flexible evd (Universes.fresh_constructor_instance env c)
+ with_context_set ?loc univ_flexible evd (UnivGen.fresh_constructor_instance env c)
let fresh_global ?loc ?(rigid=univ_flexible) ?names env evd gr =
- with_context_set ?loc rigid evd (Universes.fresh_global_instance ?names env gr)
-
-let whd_sort_variable evd t = t
+ with_context_set ?loc rigid evd (UnivGen.fresh_global_instance ?names env gr)
let is_sort_variable evd s = UState.is_sort_variable evd.universes s
@@ -833,18 +842,18 @@ let universe_rigidity evd l =
else UnivRigid
let normalize_universe evd =
- let vars = ref (UState.subst evd.universes) in
- let normalize = Universes.normalize_universe_opt_subst vars in
+ let vars = UState.subst evd.universes in
+ let normalize = UnivSubst.normalize_universe_opt_subst vars in
normalize
let normalize_universe_instance evd l =
- let vars = ref (UState.subst evd.universes) in
- let normalize = Universes.level_subst_of (Universes.normalize_univ_variable_opt_subst vars) in
+ let vars = UState.subst evd.universes in
+ let normalize = UnivSubst.level_subst_of (UnivSubst.normalize_univ_variable_opt_subst vars) in
Univ.Instance.subst_fn normalize 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'
@@ -857,7 +866,7 @@ let set_eq_sort env d s1 s2 =
| Some (u1, u2) ->
if not (type_in_type env) then
add_universe_constraints d
- (Universes.Constraints.singleton (Universes.UEq (u1,u2)))
+ (UnivProblem.Set.singleton (UnivProblem.UEq (u1,u2)))
else
d
@@ -869,7 +878,7 @@ let set_leq_level d u1 u2 =
let set_eq_instances ?(flex=false) d u1 u2 =
add_universe_constraints d
- (Universes.enforce_eq_instances_univs flex u1 u2 Universes.Constraints.empty)
+ (UnivProblem.enforce_eq_instances_univs flex u1 u2 UnivProblem.Set.empty)
let set_leq_sort env evd s1 s2 =
let s1 = normalize_sort evd s1
@@ -878,7 +887,7 @@ let set_leq_sort env evd s1 s2 =
| None -> evd
| Some (u1, u2) ->
if not (type_in_type env) then
- add_universe_constraints evd (Universes.Constraints.singleton (Universes.ULe (u1,u2)))
+ add_universe_constraints evd (UnivProblem.Set.singleton (UnivProblem.ULe (u1,u2)))
else evd
let check_eq evd s s' =
@@ -887,6 +896,9 @@ let check_eq evd s s' =
let check_leq evd s s' =
UGraph.check_leq (UState.ugraph evd.universes) s s'
+let check_constraints evd csts =
+ UGraph.check_constraints csts (UState.ugraph evd.universes)
+
let fix_undefined_variables evd =
{ evd with universes = UState.fix_undefined_variables evd.universes }
@@ -1031,11 +1043,11 @@ let map_metas_fvalue f evd =
| Clval(id,(c,s),typ) -> Clval(id,(mk_freelisted (f c.rebus),s),typ)
| x -> x
in
- set_metas evd (Metamap.smartmap map evd.metas)
+ set_metas evd (Metamap.Smart.map map evd.metas)
let map_metas f evd =
let map cl = map_clb f cl in
- set_metas evd (Metamap.smartmap map evd.metas)
+ set_metas evd (Metamap.Smart.map map evd.metas)
let meta_opt_fvalue evd mv =
match Metamap.find mv evd.metas with
@@ -1065,6 +1077,7 @@ let meta_ftype evd mv =
| Clval(_,_,b) -> b
let meta_type evd mv = (meta_ftype evd mv).rebus
+let meta_type0 = meta_type
let meta_declare mv v ?(name=Anonymous) evd =
let metas = Metamap.add mv (Cltyp(name,mk_freelisted v)) evd.metas in
@@ -1110,7 +1123,7 @@ let retract_coercible_metas evd =
Cltyp (na, typ)
| v -> v
in
- let metas = Metamap.smartmapi map evd.metas in
+ let metas = Metamap.Smart.mapi map evd.metas in
!mc, set_metas evd metas
let evar_source_of_meta mv evd =
@@ -1196,24 +1209,75 @@ module Monad =
type unsolvability_explanation = SeveralInstancesFound of int
-(** Deprecated *)
-type evar_universe_context = UState.t
-let empty_evar_universe_context = UState.empty
-let union_evar_universe_context = UState.union
-let evar_universe_context_set = UState.context_set
-let evar_universe_context_constraints = UState.constraints
-let evar_context_universe_context = UState.context
-let evar_universe_context_of = UState.of_context_set
-let evar_universe_context_subst = UState.subst
-let add_constraints_context = UState.add_constraints
-let constrain_variables = UState.constrain_variables
-let evar_universe_context_of_binders = UState.of_binders
-let make_evar_universe_context e l =
- let g = Environ.universes e in
- match l with
- | None -> UState.make g
- | Some l -> UState.make_with_initial_binders g l
-let normalize_evar_universe_context_variables = UState.normalize_variables
-let abstract_undefined_variables = UState.abstract_undefined_variables
-let normalize_evar_universe_context = UState.minimize
-let nf_constraints = minimize_universes
+module MiniEConstr = struct
+
+ module ESorts =
+ struct
+ type t = Sorts.t
+ let make s = s
+ let kind sigma = function
+ | Sorts.Type u -> Sorts.sort_of_univ (normalize_universe sigma u)
+ | s -> s
+ let unsafe_to_sorts s = s
+ end
+
+ module EInstance =
+ struct
+ type t = Univ.Instance.t
+ let make i = i
+ let kind sigma i =
+ if Univ.Instance.is_empty i then i
+ else normalize_universe_instance sigma i
+ let empty = Univ.Instance.empty
+ let is_empty = Univ.Instance.is_empty
+ let unsafe_to_instance t = t
+ end
+
+ type t = econstr
+
+ let safe_evar_value sigma ev =
+ try Some (existential_value sigma ev)
+ with NotInstantiatedEvar | Not_found -> None
+
+ let rec whd_evar sigma c =
+ match Constr.kind c with
+ | Evar ev ->
+ begin match safe_evar_value sigma ev with
+ | Some c -> whd_evar sigma c
+ | None -> c
+ end
+ | App (f, args) when isEvar f ->
+ (** Enforce smart constructor invariant on applications *)
+ let ev = destEvar f in
+ begin match safe_evar_value sigma ev with
+ | None -> c
+ | Some f -> whd_evar sigma (mkApp (f, args))
+ end
+ | Cast (c0, k, t) when isEvar c0 ->
+ (** Enforce smart constructor invariant on casts. *)
+ let ev = destEvar c0 in
+ begin match safe_evar_value sigma ev with
+ | None -> c
+ | Some c -> whd_evar sigma (mkCast (c, k, t))
+ end
+ | _ -> c
+
+ let kind sigma c = Constr.kind (whd_evar sigma c)
+ let kind_upto = kind
+ let kind_of_type sigma c = Term.kind_of_type (whd_evar sigma c)
+ let of_kind = Constr.of_kind
+ let of_constr c = c
+ let unsafe_to_constr c = c
+ let unsafe_eq = Refl
+
+ let to_constr ?(abort_on_undefined_evars=true) sigma c =
+ let evar_value ev = safe_evar_value sigma ev in
+ UnivSubst.nf_evars_and_universes_opt_subst evar_value (universe_subst sigma) c
+
+ let of_named_decl d = d
+ let unsafe_to_named_decl d = d
+ let of_rel_decl d = d
+ let unsafe_to_rel_decl d = d
+ let to_rel_decl sigma d = Context.Rel.Declaration.map_constr (to_constr sigma) d
+
+end
diff --git a/engine/evd.mli b/engine/evd.mli
index 911799c4..db2bd4ee 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -28,15 +28,10 @@ open Environ
It also contains conversion constraints, debugging information and
information about meta variables. *)
-(** {5 Existential variables and unification states} *)
-
-type evar = Evar.t
-[@@ocaml.deprecated "use Evar.t"]
-(** Existential variables. *)
+type econstr
+type etypes = econstr
-(** {6 Evars} *)
-val string_of_existential : Evar.t -> string
-[@@ocaml.deprecated "use Evar.print"]
+(** {5 Existential variables and unification states} *)
(** {6 Evar filters} *)
@@ -86,16 +81,16 @@ end
type evar_body =
| Evar_empty
- | Evar_defined of constr
+ | Evar_defined of econstr
module Store : Store.S
(** Datatype used to store additional information in evar maps. *)
type evar_info = {
- evar_concl : constr;
+ evar_concl : econstr;
(** Type of the evar. *)
- evar_hyps : named_context_val;
+ evar_hyps : named_context_val; (** TODO econstr? *)
(** Context of the evar. *)
evar_body : evar_body;
(** Optional content of the evar. *)
@@ -105,32 +100,29 @@ type evar_info = {
in the solution *)
evar_source : Evar_kinds.t located;
(** Information about the evar. *)
- evar_candidates : constr list option;
+ evar_candidates : econstr list option;
(** List of possible solutions when known that it is a finite list *)
evar_extra : Store.t
(** Extra store, used for clever hacks. *)
}
-val make_evar : named_context_val -> types -> evar_info
-val evar_concl : evar_info -> constr
-val evar_context : evar_info -> Context.Named.t
-val evar_filtered_context : evar_info -> Context.Named.t
+val make_evar : named_context_val -> etypes -> evar_info
+val evar_concl : evar_info -> econstr
+val evar_context : evar_info -> (econstr, etypes) Context.Named.pt
+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
-val map_evar_body : (constr -> constr) -> evar_body -> evar_body
-val map_evar_info : (constr -> constr) -> evar_info -> evar_info
+val map_evar_body : (econstr -> econstr) -> evar_body -> evar_body
+val map_evar_info : (econstr -> econstr) -> evar_info -> evar_info
(** {6 Unification state} **)
-type evar_universe_context = UState.t
-[@@ocaml.deprecated "Alias of UState.t"]
-(** The universe context associated to an evar map *)
-
type evar_map
(** Type of unification state. Essentially a bunch of state-passing data needed
to handle incremental term construction. *)
@@ -190,7 +182,7 @@ val raw_map_undefined : (Evar.t -> evar_info -> evar_info) -> evar_map -> evar_m
(** Same as {!raw_map}, but restricted to undefined evars. For efficiency
reasons. *)
-val define : Evar.t-> constr -> evar_map -> evar_map
+val define : Evar.t-> econstr -> evar_map -> evar_map
(** Set the body of an evar to the given constr. It is expected that:
{ul
{- The evar is already present in the evarmap.}
@@ -198,7 +190,7 @@ val define : Evar.t-> constr -> evar_map -> evar_map
{- All the evars present in the constr should be present in the evar map.}
} *)
-val cmap : (constr -> constr) -> evar_map -> evar_map
+val cmap : (econstr -> econstr) -> evar_map -> evar_map
(** Map the function on all terms in the evar map. *)
val is_evar : evar_map -> Evar.t-> bool
@@ -222,20 +214,26 @@ val drop_all_defined : evar_map -> evar_map
exception NotInstantiatedEvar
-val existential_value : evar_map -> existential -> constr
+val existential_value : evar_map -> econstr pexistential -> econstr
(** [existential_value sigma ev] raises [NotInstantiatedEvar] if [ev] has
no body and [Not_found] if it does not exist in [sigma] *)
-val existential_type : evar_map -> existential -> types
+val existential_value0 : evar_map -> existential -> constr
+
+val existential_type : evar_map -> econstr pexistential -> etypes
+
+val existential_type0 : evar_map -> existential -> types
-val existential_opt_value : evar_map -> existential -> constr option
+val existential_opt_value : evar_map -> econstr pexistential -> econstr option
(** Same as {!existential_value} but returns an option instead of raising an
exception. *)
-val evar_instance_array : (Context.Named.Declaration.t -> 'a -> bool) -> evar_info ->
+val existential_opt_value0 : evar_map -> existential -> constr option
+
+val evar_instance_array : (Constr.named_declaration -> 'a -> bool) -> evar_info ->
'a array -> (Id.t * 'a) list
-val instantiate_evar_array : evar_info -> constr -> constr array -> constr
+val instantiate_evar_array : evar_info -> econstr -> econstr array -> econstr
val evars_reset_evd : ?with_conv_pbs:bool -> ?with_univs:bool ->
evar_map -> evar_map -> evar_map
@@ -243,15 +241,16 @@ val evars_reset_evd : ?with_conv_pbs:bool -> ?with_univs:bool ->
(** {6 Misc} *)
-val restrict : Evar.t-> Filter.t -> ?candidates:constr list ->
+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 *)
-val downcast : Evar.t-> types -> evar_map -> evar_map
+val downcast : Evar.t-> etypes -> evar_map -> evar_map
(** Change the type of an undefined evar to a new type assumed to be a
subtype of its current type; subtyping must be ensured by caller *)
@@ -341,11 +340,9 @@ 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 -> constr -> constr
-
exception UniversesDiffer
-val add_universe_constraints : evar_map -> Universes.Constraints.t -> evar_map
+val add_universe_constraints : evar_map -> UnivProblem.Set.t -> evar_map
(** Add the given universe unification constraints to the evar map.
@raise UniversesDiffer in case a first-order unification fails.
@raise UniverseInconsistency .
@@ -397,8 +394,8 @@ type 'a freelisted = {
rebus : 'a;
freemetas : Metaset.t }
-val metavars_of : constr -> Metaset.t
-val mk_freelisted : constr -> constr freelisted
+val metavars_of : econstr -> Metaset.t
+val mk_freelisted : econstr -> econstr freelisted
val map_fl : ('a -> 'b) -> 'a freelisted -> 'b freelisted
(** Status of an instance found by unification wrt to the meta it solves:
@@ -436,13 +433,17 @@ type instance_status = instance_constraint * instance_typing_status
(** Clausal environments *)
type clbinding =
- | Cltyp of Name.t * constr freelisted
- | Clval of Name.t * (constr freelisted * instance_status) * constr freelisted
+ | Cltyp of Name.t * econstr freelisted
+ | Clval of Name.t * (econstr freelisted * instance_status) * econstr freelisted
(** Unification constraints *)
type conv_pb = Reduction.conv_pb
-type evar_constraint = conv_pb * env * constr * constr
+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) ->
@@ -457,7 +458,7 @@ val loc_of_conv_pb : evar_map -> evar_constraint -> Loc.t option
val evars_of_term : constr -> Evar.Set.t
(** including evars in instances of evars *)
-val evars_of_named_context : Context.Named.t -> Evar.Set.t
+val evars_of_named_context : (econstr, etypes) Context.Named.pt -> Evar.Set.t
val evars_of_filtered_evar_info : evar_info -> Evar.Set.t
@@ -465,19 +466,20 @@ val evars_of_filtered_evar_info : evar_info -> Evar.Set.t
val meta_list : evar_map -> (metavariable * clbinding) list
val meta_defined : evar_map -> metavariable -> bool
-val meta_value : evar_map -> metavariable -> constr
+val meta_value : evar_map -> metavariable -> econstr
(** [meta_fvalue] raises [Not_found] if meta not in map or [Anomaly] if
meta has no value *)
-val meta_fvalue : evar_map -> metavariable -> constr freelisted * instance_status
-val meta_opt_fvalue : evar_map -> metavariable -> (constr freelisted * instance_status) option
-val meta_type : evar_map -> metavariable -> types
-val meta_ftype : evar_map -> metavariable -> types freelisted
+val meta_fvalue : evar_map -> metavariable -> econstr freelisted * instance_status
+val meta_opt_fvalue : evar_map -> metavariable -> (econstr freelisted * instance_status) option
+val meta_type : evar_map -> metavariable -> etypes
+val meta_type0 : evar_map -> metavariable -> types
+val meta_ftype : evar_map -> metavariable -> etypes freelisted
val meta_name : evar_map -> metavariable -> Name.t
val meta_declare :
- metavariable -> types -> ?name:Name.t -> evar_map -> evar_map
-val meta_assign : metavariable -> constr * instance_status -> evar_map -> evar_map
-val meta_reassign : metavariable -> constr * instance_status -> evar_map -> evar_map
+ metavariable -> etypes -> ?name:Name.t -> evar_map -> evar_map
+val meta_assign : metavariable -> econstr * instance_status -> evar_map -> evar_map
+val meta_reassign : metavariable -> econstr * instance_status -> evar_map -> evar_map
val clear_metas : evar_map -> evar_map
@@ -485,10 +487,10 @@ val clear_metas : evar_map -> evar_map
val meta_merge : ?with_univs:bool -> evar_map -> evar_map -> evar_map
val undefined_metas : evar_map -> metavariable list
-val map_metas_fvalue : (constr -> constr) -> evar_map -> evar_map
-val map_metas : (constr -> constr) -> evar_map -> evar_map
+val map_metas_fvalue : (econstr -> econstr) -> evar_map -> evar_map
+val map_metas : (econstr -> econstr) -> evar_map -> evar_map
-type metabinding = metavariable * constr * instance_status
+type metabinding = metavariable * econstr * instance_status
val retract_coercible_metas : evar_map -> metabinding list * evar_map
@@ -519,48 +521,11 @@ val univ_flexible_alg : rigid
type 'a in_evar_universe_context = 'a * UState.t
-val evar_universe_context_set : UState.t -> Univ.ContextSet.t
-[@@ocaml.deprecated "Alias of UState.context_set"]
-val evar_universe_context_constraints : UState.t -> Univ.Constraint.t
-[@@ocaml.deprecated "Alias of UState.constraints"]
-val evar_context_universe_context : UState.t -> Univ.UContext.t
-[@@ocaml.deprecated "alias of UState.context"]
-
-val evar_universe_context_of : Univ.ContextSet.t -> UState.t
-[@@ocaml.deprecated "Alias of UState.of_context_set"]
-val empty_evar_universe_context : UState.t
-[@@ocaml.deprecated "Alias of UState.empty"]
-val union_evar_universe_context : UState.t -> UState.t ->
- UState.t
-[@@ocaml.deprecated "Alias of UState.union"]
-val evar_universe_context_subst : UState.t -> Universes.universe_opt_subst
-[@@ocaml.deprecated "Alias of UState.subst"]
-val constrain_variables : Univ.LSet.t -> UState.t -> UState.t
-[@@ocaml.deprecated "Alias of UState.constrain_variables"]
-
-
-val evar_universe_context_of_binders :
- Universes.universe_binders -> UState.t
-[@@ocaml.deprecated "Alias of UState.of_binders"]
-
-val make_evar_universe_context : env -> Misctypes.lident list option -> UState.t
-[@@ocaml.deprecated "Use UState.make or UState.make_with_initial_binders"]
val restrict_universe_context : evar_map -> Univ.LSet.t -> evar_map
(** Raises Not_found if not a name for a universe in this map. *)
val universe_of_name : evar_map -> Id.t -> Univ.Level.t
-val universe_binders : evar_map -> Universes.universe_binders
-val add_constraints_context : UState.t ->
- Univ.Constraint.t -> UState.t
-[@@ocaml.deprecated "Alias of UState.add_constraints"]
-
-
-val normalize_evar_universe_context_variables : UState.t ->
- Univ.universe_subst in_evar_universe_context
-[@@ocaml.deprecated "Alias of UState.normalize_variables"]
-
-val normalize_evar_universe_context : UState.t -> UState.t
-[@@ocaml.deprecated "Alias of UState.minimize"]
+val universe_binders : evar_map -> UnivNames.universe_binders
val new_univ_level_variable : ?loc:Loc.t -> ?name:Id.t -> rigid -> evar_map -> evar_map * Univ.Level.t
val new_univ_variable : ?loc:Loc.t -> ?name:Id.t -> rigid -> evar_map -> evar_map * Univ.Universe.t
@@ -591,9 +556,11 @@ val set_eq_instances : ?flex:bool ->
val check_eq : evar_map -> Univ.Universe.t -> Univ.Universe.t -> bool
val check_leq : evar_map -> Univ.Universe.t -> Univ.Universe.t -> bool
+val check_constraints : evar_map -> Univ.Constraint.t -> bool
+
val evar_universe_context : evar_map -> UState.t
val universe_context_set : evar_map -> Univ.ContextSet.t
-val universe_subst : evar_map -> Universes.universe_opt_subst
+val universe_subst : evar_map -> UnivSubst.universe_opt_subst
val universes : evar_map -> UGraph.t
(** [to_universe_context evm] extracts the local universes and
@@ -612,13 +579,11 @@ val merge_universe_context : evar_map -> UState.t -> evar_map
val set_universe_context : evar_map -> UState.t -> evar_map
val merge_context_set : ?loc:Loc.t -> ?sideff:bool -> rigid -> evar_map -> Univ.ContextSet.t -> evar_map
-val merge_universe_subst : evar_map -> Universes.universe_opt_subst -> evar_map
+val merge_universe_subst : evar_map -> UnivSubst.universe_opt_subst -> evar_map
val with_context_set : ?loc:Loc.t -> rigid -> evar_map -> 'a Univ.in_universe_context_set -> evar_map * 'a
val nf_univ_variables : evar_map -> evar_map * Univ.universe_subst
-val abstract_undefined_variables : UState.t -> UState.t
-[@@ocaml.deprecated "Alias of UState.abstract_undefined_variables"]
val fix_undefined_variables : evar_map -> evar_map
@@ -626,26 +591,24 @@ val refresh_undefined_universes : evar_map -> evar_map * Univ.universe_level_sub
(** Universe minimization *)
val minimize_universes : evar_map -> evar_map
-val nf_constraints : evar_map -> evar_map
-[@@ocaml.deprecated "Alias of Evd.minimize_universes"]
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
val fresh_global : ?loc:Loc.t -> ?rigid:rigid -> ?names:Univ.Instance.t -> env ->
- evar_map -> Globnames.global_reference -> evar_map * constr
+ evar_map -> GlobRef.t -> evar_map * econstr
(********************************************************************)
(* constr with holes and pending resolution of classes, conversion *)
(* problems, candidates, etc. *)
-type open_constr = evar_map * constr (* Special case when before is empty *)
+type open_constr = evar_map * econstr (* Special case when before is empty *)
(** Partially constructed constrs. *)
@@ -665,3 +628,50 @@ val create_evar_defs : evar_map -> evar_map
(** Create an [evar_map] with empty meta map: *)
+(** Use this module only to bootstrap EConstr *)
+module MiniEConstr : sig
+ module ESorts : sig
+ type t
+ val make : Sorts.t -> t
+ val kind : evar_map -> t -> Sorts.t
+ val unsafe_to_sorts : t -> Sorts.t
+ end
+
+ module EInstance : sig
+ type t
+ val make : Univ.Instance.t -> t
+ val kind : evar_map -> t -> Univ.Instance.t
+ val empty : t
+ val is_empty : t -> bool
+ val unsafe_to_instance : t -> Univ.Instance.t
+ end
+
+ type t = econstr
+
+ val kind : evar_map -> t -> (t, t, ESorts.t, EInstance.t) Constr.kind_of_term
+ val kind_upto : evar_map -> constr -> (constr, types, Sorts.t, Univ.Instance.t) Constr.kind_of_term
+ val kind_of_type : evar_map -> t -> (t, t) Term.kind_of_type
+
+ val whd_evar : evar_map -> t -> t
+
+ val of_kind : (t, t, ESorts.t, EInstance.t) Constr.kind_of_term -> t
+
+ val of_constr : Constr.t -> t
+
+ val to_constr : ?abort_on_undefined_evars:bool -> evar_map -> t -> Constr.t
+
+ val unsafe_to_constr : t -> Constr.t
+
+ val unsafe_eq : (t, Constr.t) eq
+
+ val of_named_decl : (Constr.t, Constr.types) Context.Named.Declaration.pt ->
+ (t, t) Context.Named.Declaration.pt
+ val unsafe_to_named_decl : (t, t) Context.Named.Declaration.pt ->
+ (Constr.t, Constr.types) Context.Named.Declaration.pt
+ val unsafe_to_rel_decl : (t, t) Context.Rel.Declaration.pt ->
+ (Constr.t, Constr.types) Context.Rel.Declaration.pt
+ val of_rel_decl : (Constr.t, Constr.types) Context.Rel.Declaration.pt ->
+ (t, t) Context.Rel.Declaration.pt
+ val to_rel_decl : evar_map -> (t, t) Context.Rel.Declaration.pt ->
+ (Constr.t, Constr.types) Context.Rel.Declaration.pt
+end
diff --git a/engine/namegen.ml b/engine/namegen.ml
index d66b77b5..978f33b6 100644
--- a/engine/namegen.ml
+++ b/engine/namegen.ml
@@ -17,6 +17,7 @@
open Util
open Names
open Term
+open Constr
open Environ
open EConstr
open Vars
@@ -28,6 +29,18 @@ open Context.Rel.Declaration
module RelDecl = Context.Rel.Declaration
+(** General evar naming using intro patterns *)
+type intro_pattern_naming_expr =
+ | IntroIdentifier of Id.t
+ | IntroFresh of Id.t
+ | IntroAnonymous
+
+let intro_pattern_naming_eq nam1 nam2 = match nam1, nam2 with
+| IntroAnonymous, IntroAnonymous -> true
+| IntroIdentifier id1, IntroIdentifier id2 -> Names.Id.equal id1 id2
+| IntroFresh id1, IntroFresh id2 -> Names.Id.equal id1 id2
+| _ -> false
+
(**********************************************************************)
(* Conventional names *)
@@ -124,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/namegen.mli b/engine/namegen.mli
index 1b70ef68..a53c3a0d 100644
--- a/engine/namegen.mli
+++ b/engine/namegen.mli
@@ -15,6 +15,16 @@ open Environ
open Evd
open EConstr
+(** General evar naming using intro patterns *)
+type intro_pattern_naming_expr =
+ | IntroIdentifier of Id.t
+ | IntroFresh of Id.t
+ | IntroAnonymous
+
+(** Equalities on [intro_pattern_naming] *)
+val intro_pattern_naming_eq :
+ intro_pattern_naming_expr -> intro_pattern_naming_expr -> bool
+
(*********************************************************************
Conventional default names *)
diff --git a/engine/nameops.ml b/engine/nameops.ml
index 53969caf..15e20134 100644
--- a/engine/nameops.ml
+++ b/engine/nameops.ml
@@ -11,10 +11,6 @@
open Util
open Names
-(* Identifiers *)
-
-let pr_id id = Id.print id
-
(* Utilities *)
let code_of_0 = Char.code '0'
@@ -73,7 +69,7 @@ let root_of_id id =
[bar0] ↦ [bar1]
[bar00] ↦ [bar01]
[bar1] ↦ [bar2]
- [bar01] ↦ [bar01]
+ [bar01] ↦ [bar02]
[bar9] ↦ [bar10]
[bar09] ↦ [bar10]
[bar99] ↦ [bar100]
@@ -191,28 +187,6 @@ struct
end
-open Name
-
-(* Compatibility *)
-let out_name = get_id
-let name_fold = fold_right
-let name_iter = iter
-let name_app = map
-let name_fold_map = fold_left_map
-let name_cons = cons
-let name_max = pick
-let pr_name = print
-
-let pr_lab l = Label.print l
-
(* Metavariables *)
let pr_meta = Pp.int
let string_of_meta = string_of_int
-
-(* Deprecated *)
-open Libnames
-let default_library = default_library
-let coq_string = coq_string
-let coq_root = coq_root
-let default_root_prefix = default_root_prefix
-
diff --git a/engine/nameops.mli b/engine/nameops.mli
index 96842dfb..8a93fad8 100644
--- a/engine/nameops.mli
+++ b/engine/nameops.mli
@@ -94,47 +94,3 @@ end
(** Metavariables *)
val pr_meta : Constr.metavariable -> Pp.t
val string_of_meta : Constr.metavariable -> string
-
-val out_name : Name.t -> Id.t
-[@@ocaml.deprecated "Same as [Name.get_id]"]
-
-val name_fold : (Id.t -> 'a -> 'a) -> Name.t -> 'a -> 'a
-[@@ocaml.deprecated "Same as [Name.fold_right]"]
-
-val name_iter : (Id.t -> unit) -> Name.t -> unit
-[@@ocaml.deprecated "Same as [Name.iter]"]
-
-val name_app : (Id.t -> Id.t) -> Name.t -> Name.t
-[@@ocaml.deprecated "Same as [Name.map]"]
-
-val name_fold_map : ('a -> Id.t -> 'a * Id.t) -> 'a -> Name.t -> 'a * Name.t
-[@@ocaml.deprecated "Same as [Name.fold_left_map]"]
-
-val name_max : Name.t -> Name.t -> Name.t
-[@@ocaml.deprecated "Same as [Name.pick]"]
-
-val name_cons : Name.t -> Id.t list -> Id.t list
-[@@ocaml.deprecated "Same as [Name.cons]"]
-
-val pr_name : Name.t -> Pp.t
-[@@ocaml.deprecated "Same as [Name.print]"]
-
-val pr_id : Id.t -> Pp.t
-[@@ocaml.deprecated "Same as [Names.Id.print]"]
-
-val pr_lab : Label.t -> Pp.t
-[@@ocaml.deprecated "Same as [Names.Label.print]"]
-
-(** Deprecated stuff to libnames *)
-val default_library : DirPath.t
-[@@ocaml.deprecated "Same as [Libnames.default_library]"]
-
-val coq_root : module_ident (** "Coq" *)
-[@@ocaml.deprecated "Same as [Libnames.coq_root]"]
-
-val coq_string : string (** "Coq" *)
-[@@ocaml.deprecated "Same as [Libnames.coq_string]"]
-
-val default_root_prefix : DirPath.t
-[@@ocaml.deprecated "Same as [Libnames.default_root_prefix]"]
-
diff --git a/engine/proofview.ml b/engine/proofview.ml
index 22271dd0..12d31e5f 100644
--- a/engine/proofview.ml
+++ b/engine/proofview.ml
@@ -39,15 +39,15 @@ let proofview p =
let compact el ({ solution } as pv) =
let nf c = Evarutil.nf_evar solution c in
- let nf0 c = EConstr.Unsafe.to_constr (Evarutil.nf_evar solution (EConstr.of_constr c)) in
+ let nf0 c = EConstr.(to_constr solution (of_constr c)) in
let size = Evd.fold (fun _ _ i -> i+1) solution 0 in
let new_el = List.map (fun (t,ty) -> nf t, nf ty) el in
let pruned_solution = Evd.drop_all_defined solution in
let apply_subst_einfo _ ei =
Evd.({ ei with
- evar_concl = nf0 ei.evar_concl;
+ evar_concl = nf ei.evar_concl;
evar_hyps = Environ.map_named_val nf0 ei.evar_hyps;
- evar_candidates = Option.map (List.map nf0) ei.evar_candidates }) in
+ evar_candidates = Option.map (List.map nf) ei.evar_candidates }) in
let new_solution = Evd.raw_map_undefined apply_subst_einfo pruned_solution in
let new_size = Evd.fold (fun _ _ i -> i+1) new_solution 0 in
Feedback.msg_info (Pp.str (Printf.sprintf "Evars: %d -> %d\n" size new_size));
@@ -710,13 +710,19 @@ let partition_unifiable sigma l =
(** Shelves the unifiable goals under focus, i.e. the goals which
appear in other goals under focus (the unfocused goals are not
considered). *)
-let shelve_unifiable =
+let shelve_unifiable_informative =
let open Proof in
Pv.get >>= fun initial ->
let (u,n) = partition_unifiable initial.solution initial.comb in
Comb.set n >>
InfoL.leaf (Info.Tactic (fun () -> Pp.str"shelve_unifiable")) >>
- Shelf.modify (fun gls -> gls @ CList.map drop_state u)
+ let u = CList.map drop_state u in
+ Shelf.modify (fun gls -> gls @ u) >>
+ tclUNIT u
+
+let shelve_unifiable =
+ let open Proof in
+ shelve_unifiable_informative >>= fun _ -> tclUNIT ()
(** [guard_no_unifiable] returns the list of unifiable goals if some
goals are unifiable (see {!shelve_unifiable}) in the current focus. *)
@@ -748,7 +754,7 @@ let mark_in_evm ~goal evd content =
- GoalEvar (morally not dependent)
- VarInstance (morally dependent of some name).
This is a heuristic for naming these evars. *)
- | loc, (Evar_kinds.QuestionMark (_,Names.Name id) |
+ | loc, (Evar_kinds.QuestionMark { Evar_kinds.qm_name=Names.Name id} |
Evar_kinds.ImplicitArg (_,(_,Some id),_)) -> loc, Evar_kinds.VarInstance id
| _, (Evar_kinds.VarInstance _ | Evar_kinds.GoalEvar) as x -> x
| loc,_ -> loc,Evar_kinds.GoalEvar }
@@ -869,8 +875,7 @@ module Progress = struct
(** equality function on hypothesis contexts *)
let eq_named_context_val sigma1 sigma2 ctx1 ctx2 =
- let open Environ in
- let c1 = named_context_of_val ctx1 and c2 = named_context_of_val ctx2 in
+ let c1 = EConstr.named_context_of_val ctx1 and c2 = EConstr.named_context_of_val ctx2 in
let eq_named_declaration d1 d2 =
match d1, d2 with
| LocalAssum (i1,t1), LocalAssum (i2,t2) ->
@@ -1035,6 +1040,8 @@ module Unsafe = struct
let advance = Evarutil.advance
+ let undefined = undefined
+
let mark_as_unresolvable p gl =
{ p with solution = mark_in_evm ~goal:false p.solution gl }
@@ -1078,8 +1085,6 @@ module Goal = struct
self : Evar.t ; (* for compatibility with old-style definitions *)
}
- let assume (gl : t) = (gl : t)
-
let print { sigma; self } = { Evd.it = self; sigma }
let state { state=state } = state
@@ -1093,7 +1098,7 @@ module Goal = struct
let gmake_with info env sigma goal state =
{ env = Environ.reset_with_named_context (Evd.evar_filtered_hyps info) env ;
sigma = sigma ;
- concl = EConstr.of_constr (Evd.evar_concl info);
+ concl = Evd.evar_concl info;
state = state ;
self = goal }
@@ -1267,11 +1272,6 @@ module V82 = struct
- (* Returns the open goals of the proofview together with the evar_map to
- interpret them. *)
- let goals { comb = comb ; solution = solution; } =
- { Evd.it = List.map drop_state comb ; sigma = solution }
-
let top_goals initial { solution=solution; } =
let goals = CList.map (fun (t,_) -> fst (Constr.destEvar (EConstr.Unsafe.to_constr t))) initial in
{ Evd.it = goals ; sigma=solution; }
diff --git a/engine/proofview.mli b/engine/proofview.mli
index e7be6655..970bf677 100644
--- a/engine/proofview.mli
+++ b/engine/proofview.mli
@@ -326,6 +326,9 @@ val unifiable : Evd.evar_map -> Evar.t -> Evar.t list -> bool
considered). *)
val shelve_unifiable : unit tactic
+(** Idem but also returns the list of shelved variables *)
+val shelve_unifiable_informative : Evar.t list tactic
+
(** [guard_no_unifiable] returns the list of unifiable goals if some
goals are unifiable (see {!shelve_unifiable}) in the current focus. *)
val guard_no_unifiable : Names.Name.t list option tactic
@@ -466,6 +469,12 @@ module Unsafe : sig
solved. *)
val advance : Evd.evar_map -> Evar.t -> Evar.t option
+ (** [undefined sigma l] applies [advance] to the goals of [l], then
+ returns the subset of resulting goals which have not yet been
+ defined *)
+ val undefined : Evd.evar_map -> Proofview_monad.goal_with_state list ->
+ Proofview_monad.goal_with_state list
+
val typeclass_resolvable : unit Evd.Store.field
end
@@ -486,10 +495,6 @@ module Goal : sig
(** Type of goals. *)
type t
- (** Assume that you do not need the goal to be normalized. *)
- val assume : t -> t
- [@@ocaml.deprecated "Normalization is enforced by EConstr, [assume] is not needed anymore"]
-
(** Normalises the argument goal. *)
val normalize : t -> t tactic
@@ -580,11 +585,6 @@ module V82 : sig
(in chronological order of insertion). *)
val grab : proofview -> proofview
- (* Returns the open goals of the proofview together with the evar_map to
- interpret them. *)
- val goals : proofview -> Evar.t list Evd.sigma
- [@@ocaml.deprecated "Use [Proofview.proofview]"]
-
val top_goals : entry -> proofview -> Evar.t list Evd.sigma
(* returns the existential variable used to start the proof *)
diff --git a/engine/termops.ml b/engine/termops.ml
index 3dfb0c34..a343ad3c 100644
--- a/engine/termops.ml
+++ b/engine/termops.ml
@@ -22,11 +22,13 @@ module RelDecl = Context.Rel.Declaration
module NamedDecl = Context.Named.Declaration
module CompactedDecl = Context.Compacted.Declaration
+module Internal = struct
+
(* 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
@@ -47,7 +49,9 @@ let pr_fix pr_constr ((t,i),(lna,tl,bl)) =
let pr_puniverses p u =
if Univ.Instance.is_empty u then p
- else p ++ str"(*" ++ Univ.Instance.pr Universes.pr_with_global_universes u ++ str"*)"
+ else p ++ str"(*" ++ Univ.Instance.pr UnivNames.pr_with_global_universes u ++ str"*)"
+
+(* Minimalistic constr printer, typically for debugging *)
let rec pr_constr c = match kind c with
| Rel n -> str "#"++int n
@@ -96,9 +100,16 @@ let rec pr_constr c = match kind c with
cut() ++ str":=" ++ pr_constr bd) (Array.to_list fixl)) ++
str"}")
-let term_printer = ref (fun _env _sigma c -> pr_constr (EConstr.Unsafe.to_constr c))
+let debug_print_constr c = pr_constr EConstr.Unsafe.(to_constr c)
+let debug_print_constr_env env sigma c = pr_constr EConstr.(to_constr sigma c)
+let term_printer = ref debug_print_constr_env
+
let print_constr_env env sigma t = !term_printer env sigma t
-let print_constr t = !term_printer (Global.env()) Evd.empty t
+let print_constr t =
+ let env = Global.env () in
+ let evd = Evd.from_env env in
+ !term_printer env evd t
+
let set_print_constr f = term_printer := f
module EvMap = Evar.Map
@@ -111,11 +122,11 @@ let pr_evar_suggested_name evk sigma =
| None -> match evi.evar_source with
| _,Evar_kinds.ImplicitArg (c,(n,Some id),b) -> id
| _,Evar_kinds.VarInstance id -> id
- | _,Evar_kinds.QuestionMark (_,Name id) -> id
+ | _,Evar_kinds.QuestionMark {Evar_kinds.qm_name = Name id} -> id
| _,Evar_kinds.GoalEvar -> Id.of_string "Goal"
| _ ->
let env = reset_with_named_context evi.evar_hyps (Global.env()) in
- Namegen.id_of_name_using_hdchar env sigma (EConstr.of_constr evi.evar_concl) Anonymous
+ Namegen.id_of_name_using_hdchar env sigma evi.evar_concl Anonymous
in
let names = EvMap.mapi base_id (undefined_map sigma) in
let id = EvMap.find evk names in
@@ -154,7 +165,7 @@ let protect f x =
with e -> str "EXCEPTION: " ++ str (Printexc.to_string e)
let print_kconstr a =
- protect (fun c -> print_constr (EConstr.of_constr c)) a
+ protect (fun c -> print_constr c) a
let pr_meta_map evd =
let open Evd in
@@ -197,17 +208,21 @@ let pr_evar_source = function
let print_constr = print_kconstr in
let id = Option.get ido in
str "parameter " ++ Id.print id ++ spc () ++ str "of" ++
- spc () ++ print_constr (printable_constr_of_global c)
+ spc () ++ print_constr (EConstr.of_constr @@ printable_constr_of_global c)
| Evar_kinds.InternalHole -> str "internal placeholder"
| Evar_kinds.TomatchTypeParameter (ind,n) ->
let print_constr = print_kconstr in
- pr_nth n ++ str " argument of type " ++ print_constr (mkInd ind)
+ pr_nth n ++ str " argument of type " ++ print_constr (EConstr.mkInd ind)
| Evar_kinds.GoalEvar -> str "goal evar"
| Evar_kinds.ImpossibleCase -> str "type of impossible pattern-matching clause"
| Evar_kinds.MatchingVar _ -> str "matching variable"
| Evar_kinds.VarInstance id -> str "instance of " ++ Id.print id
- | Evar_kinds.SubEvar evk ->
- str "subterm of " ++ Evar.print evk
+ | Evar_kinds.SubEvar (where,evk) ->
+ (match where with
+ | None -> str "subterm of "
+ | Some Evar_kinds.Body -> str "body of "
+ | Some Evar_kinds.Domain -> str "domain of "
+ | Some Evar_kinds.Codomain -> str "codomain of ") ++ Evar.print evk
let pr_evar_info evi =
let open Evd in
@@ -252,7 +267,7 @@ let compute_evar_dependency_graph sigma =
in
match evar_body evi with
| Evar_empty -> acc
- | Evar_defined c -> Evar.Set.fold fold_ev (evars_of_term c) acc
+ | Evar_defined c -> Evar.Set.fold fold_ev (evars_of_term (EConstr.Unsafe.to_constr c)) acc
in
Evd.fold fold sigma EvMap.empty
@@ -290,7 +305,7 @@ let has_no_evar sigma =
with Exit -> false
let pr_evd_level evd = UState.pr_uctx_level (Evd.evar_universe_context evd)
-let reference_of_level evd l = UState.reference_of_level (Evd.evar_universe_context evd) l
+let reference_of_level evd l = UState.qualid_of_level (Evd.evar_universe_context evd) l
let pr_evar_universe_context ctx =
let open UState in
@@ -302,7 +317,7 @@ let pr_evar_universe_context ctx =
str"ALGEBRAIC UNIVERSES:"++brk(0,1)++
h 0 (Univ.LSet.pr prl (UState.algebraics ctx)) ++ fnl() ++
str"UNDEFINED UNIVERSES:"++brk(0,1)++
- h 0 (Universes.pr_universe_opt_subst (UState.subst ctx)) ++ fnl() ++
+ h 0 (UnivSubst.pr_universe_opt_subst (UState.subst ctx)) ++ fnl() ++
str "WEAK CONSTRAINTS:"++brk(0,1)++
h 0 (UState.pr_weak prl ctx) ++ fnl ())
@@ -310,7 +325,8 @@ let print_env_short env =
let print_constr = print_kconstr in
let pr_rel_decl = function
| RelDecl.LocalAssum (n,_) -> Name.print n
- | RelDecl.LocalDef (n,b,_) -> str "(" ++ Name.print n ++ str " := " ++ print_constr b ++ str ")"
+ | RelDecl.LocalDef (n,b,_) -> str "(" ++ Name.print n ++ str " := "
+ ++ print_constr (EConstr.of_constr b) ++ str ")"
in
let pr_named_decl = NamedDecl.to_rel_decl %> pr_rel_decl in
let nc = List.rev (named_context env) in
@@ -331,11 +347,11 @@ let pr_evar_constraints sigma pbs =
Namegen.make_all_name_different env sigma
in
print_env_short env ++ spc () ++ str "|-" ++ spc () ++
- protect (print_constr_env env sigma) (EConstr.of_constr t1) ++ spc () ++
+ protect (print_constr_env env sigma) t1 ++ spc () ++
str (match pbty with
| Reduction.CONV -> "=="
| Reduction.CUMUL -> "<=") ++
- spc () ++ protect (print_constr_env env Evd.empty) (EConstr.of_constr t2)
+ spc () ++ protect (print_constr_env env @@ Evd.from_env env) t2
in
prlist_with_sep fnl pr_evconstr pbs
@@ -429,27 +445,29 @@ let pr_metaset metas =
let pr_var_decl env decl =
let open NamedDecl in
+ let evd = Evd.from_env env in
let pbody = match decl with
| LocalAssum _ -> mt ()
| LocalDef (_,c,_) ->
(* Force evaluation *)
let c = EConstr.of_constr c in
- let pb = print_constr_env env Evd.empty c in
+ let pb = print_constr_env env evd c in
(str" := " ++ pb ++ cut () ) in
- let pt = print_constr_env env Evd.empty (EConstr.of_constr (get_type decl)) in
+ let pt = print_constr_env env evd (EConstr.of_constr (get_type decl)) in
let ptyp = (str" : " ++ pt) in
(Id.print (get_id decl) ++ hov 0 (pbody ++ ptyp))
let pr_rel_decl env decl =
let open RelDecl in
+ let evd = Evd.from_env env in
let pbody = match decl with
| LocalAssum _ -> mt ()
| LocalDef (_,c,_) ->
(* Force evaluation *)
let c = EConstr.of_constr c in
- let pb = print_constr_env env Evd.empty c in
+ let pb = print_constr_env env evd c in
(str":=" ++ spc () ++ pb ++ spc ()) in
- let ptyp = print_constr_env env Evd.empty (EConstr.of_constr (get_type decl)) in
+ let ptyp = print_constr_env env evd (EConstr.of_constr (get_type decl)) in
match get_name decl with
| Anonymous -> hov 0 (str"<>" ++ spc () ++ pbody ++ str":" ++ spc () ++ ptyp)
| Name id -> hov 0 (Id.print id ++ spc () ++ pbody ++ str":" ++ spc () ++ ptyp)
@@ -771,24 +789,23 @@ let map_constr_with_full_binders sigma g f l cstr =
let fold_constr_with_full_binders sigma g f n acc c =
let open RelDecl in
- let inj c = EConstr.Unsafe.to_constr c in
match EConstr.kind sigma c with
| (Rel _ | Meta _ | Var _ | Sort _ | Const _ | Ind _
| Construct _) -> acc
| Cast (c,_, t) -> f n (f n acc c) t
- | Prod (na,t,c) -> f (g (LocalAssum (na, inj t)) n) (f n acc t) c
- | Lambda (na,t,c) -> f (g (LocalAssum (na, inj t)) n) (f n acc t) c
- | LetIn (na,b,t,c) -> f (g (LocalDef (na, inj b, inj t)) n) (f n (f n acc b) t) c
+ | Prod (na,t,c) -> f (g (LocalAssum (na, t)) n) (f n acc t) c
+ | Lambda (na,t,c) -> f (g (LocalAssum (na, t)) n) (f n acc t) c
+ | LetIn (na,b,t,c) -> f (g (LocalDef (na, b, t)) n) (f n (f n acc b) t) c
| App (c,l) -> Array.fold_left (f n) (f n acc c) l
| Proj (p,c) -> f n acc c
| Evar (_,l) -> Array.fold_left (f n) acc l
| Case (_,p,c,bl) -> Array.fold_left (f n) (f n (f n acc p) c) bl
| Fix (_,(lna,tl,bl)) ->
- let n' = CArray.fold_left2 (fun c n t -> g (LocalAssum (n, inj t)) c) n lna tl in
+ let n' = CArray.fold_left2 (fun c n t -> g (LocalAssum (n, t)) c) n lna tl in
let fd = Array.map2 (fun t b -> (t,b)) tl bl in
Array.fold_left (fun acc (t,b) -> f n' (f n acc t) b) acc fd
| CoFix (_,(lna,tl,bl)) ->
- let n' = CArray.fold_left2 (fun c n t -> g (LocalAssum (n, inj t)) c) n lna tl in
+ let n' = CArray.fold_left2 (fun c n t -> g (LocalAssum (n, t)) c) n lna tl in
let fd = Array.map2 (fun t b -> (t,b)) tl bl in
Array.fold_left (fun acc (t,b) -> f n' (f n acc t) b) acc fd
@@ -847,6 +864,13 @@ let occur_meta_or_existential sigma c =
| _ -> EConstr.iter sigma occrec c
in try occrec c; false with Occur -> true
+let occur_metavariable sigma m c =
+ let rec occrec c = match EConstr.kind sigma c with
+ | Meta m' -> if Int.equal m m' then raise Occur
+ | _ -> EConstr.iter sigma occrec c
+ in
+ try occrec c; false with Occur -> true
+
let occur_evar sigma n c =
let rec occur_rec c = match EConstr.kind sigma c with
| Evar (sp,_) when Evar.equal sp n -> raise Occur
@@ -926,7 +950,7 @@ let dependent_main noevar sigma m t =
match EConstr.kind sigma m, EConstr.kind sigma t with
| App (fm,lm), App (ft,lt) when Array.length lm < Array.length lt ->
deprec m (mkApp (ft,Array.sub lt 0 (Array.length lm)));
- CArray.Fun1.iter deprec m
+ Array.Fun1.iter deprec m
(Array.sub lt
(Array.length lm) ((Array.length lt) - (Array.length lm)))
| _, Cast (c,_,_) when noevar && isMeta sigma c -> ()
@@ -964,9 +988,6 @@ let count_occurrences sigma m t =
countrec m t;
!n
-(* Synonymous *)
-let occur_term = dependent
-
let pop t = EConstr.Vars.lift (-1) t
(***************************)
@@ -1149,15 +1170,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
@@ -1166,7 +1186,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
@@ -1369,7 +1389,7 @@ let smash_rel_context sign =
let fold_named_context_both_sides f l ~init = List.fold_right_and_left f l init
let mem_named_context_val id ctxt =
- try ignore(Environ.lookup_named_val id ctxt); true with Not_found -> false
+ try ignore(Environ.lookup_named_ctxt id ctxt); true with Not_found -> false
let map_rel_decl f = function
| RelDecl.LocalAssum (id, t) -> RelDecl.LocalAssum (id, f t)
@@ -1495,3 +1515,6 @@ let env_rel_context_chop k env =
let ctx1,ctx2 = List.chop k rels in
push_rel_context ctx2 (reset_with_named_context (named_context_val env) env),
ctx1
+end
+
+include Internal
diff --git a/engine/termops.mli b/engine/termops.mli
index 3b0c4bba..821d9041 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} *)
@@ -75,8 +75,9 @@ val fold_constr_with_binders : Evd.evar_map ->
('a -> 'a) -> ('a -> 'b -> constr -> 'b) -> 'a -> 'b -> constr -> 'b
val fold_constr_with_full_binders : Evd.evar_map ->
- (Context.Rel.Declaration.t -> 'a -> 'a) -> ('a -> 'b -> constr -> 'b) ->
- 'a -> 'b -> constr -> 'b
+ (rel_declaration -> 'a -> 'a) ->
+ ('a -> 'b -> constr -> 'b) ->
+ 'a -> 'b -> constr -> 'b
val iter_constr_with_full_binders : Evd.evar_map ->
(rel_declaration -> 'a -> 'a) ->
@@ -94,6 +95,7 @@ exception Occur
val occur_meta : Evd.evar_map -> constr -> bool
val occur_existential : Evd.evar_map -> constr -> bool
val occur_meta_or_existential : Evd.evar_map -> constr -> bool
+val occur_metavariable : Evd.evar_map -> metavariable -> constr -> bool
val occur_evar : Evd.evar_map -> Evar.t -> constr -> bool
val occur_var : env -> Evd.evar_map -> Id.t -> constr -> bool
val occur_var_in_decl :
@@ -112,9 +114,7 @@ val dependent_in_decl : Evd.evar_map -> constr -> named_declaration -> bool
val count_occurrences : Evd.evar_map -> constr -> constr -> int
val collect_metas : Evd.evar_map -> constr -> int list
val collect_vars : Evd.evar_map -> constr -> Id.Set.t (** for visible vars only *)
-val vars_of_global_reference : env -> Globnames.global_reference -> Id.Set.t
-val occur_term : Evd.evar_map -> constr -> constr -> bool (** Synonymous of dependent *)
-[@@ocaml.deprecated "alias of Termops.dependent"]
+val vars_of_global_reference : env -> GlobRef.t -> Id.Set.t
(* Substitution of metavariables *)
type meta_value_map = (metavariable * Constr.constr) list
@@ -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
@@ -261,7 +261,7 @@ val clear_named_body : Id.t -> env -> env
val global_vars : env -> Evd.evar_map -> constr -> Id.t list
val global_vars_set : env -> Evd.evar_map -> constr -> Id.Set.t
val global_vars_set_of_decl : env -> Evd.evar_map -> named_declaration -> Id.Set.t
-val global_app_of_constr : Evd.evar_map -> constr -> (Globnames.global_reference * EInstance.t) * constr option
+val global_app_of_constr : Evd.evar_map -> constr -> (GlobRef.t * EInstance.t) * constr option
(** Gives an ordered list of hypotheses, closed by dependencies,
containing a given set *)
@@ -270,9 +270,9 @@ val dependency_closure : env -> Evd.evar_map -> named_context -> Id.Set.t -> Id.
(** Test if an identifier is the basename of a global reference *)
val is_section_variable : Id.t -> bool
-val global_of_constr : Evd.evar_map -> constr -> Globnames.global_reference * EInstance.t
+val global_of_constr : Evd.evar_map -> constr -> GlobRef.t * EInstance.t
-val is_global : Evd.evar_map -> Globnames.global_reference -> constr -> bool
+val is_global : Evd.evar_map -> GlobRef.t -> constr -> bool
val isGlobalRef : Evd.evar_map -> constr -> bool
@@ -282,7 +282,7 @@ val is_Prop : Evd.evar_map -> constr -> bool
val is_Set : Evd.evar_map -> constr -> bool
val is_Type : Evd.evar_map -> constr -> bool
-val reference_of_level : Evd.evar_map -> Univ.Level.t -> Libnames.reference
+val reference_of_level : Evd.evar_map -> Univ.Level.t -> Libnames.qualid
(** Combinators on judgments *)
@@ -307,12 +307,40 @@ val pr_metaset : Metaset.t -> Pp.t
val pr_evar_universe_context : UState.t -> Pp.t
val pr_evd_level : evar_map -> Univ.Level.t -> Pp.t
-(** debug printer: do not use to display terms to the casual user... *)
+module Internal : sig
-val set_print_constr : (env -> Evd.evar_map -> constr -> Pp.t) -> unit
-val print_constr : constr -> Pp.t
+(** NOTE: to print terms you always want to use functions in
+ Printer, not these ones which are for very special cases. *)
+
+(** debug printers: print raw form for terms, both with
+ evar-substitution and without. *)
+val debug_print_constr : constr -> Pp.t
+val debug_print_constr_env : env -> evar_map -> constr -> Pp.t
+
+(** Pretty-printer hook: [print_constr_env env sigma c] will pretty
+ print c if the pretty printing layer has been linked into the Coq
+ binary. *)
val print_constr_env : env -> Evd.evar_map -> constr -> Pp.t
+
+(** [set_print_constr f] sets f to be the pretty printer *)
+val set_print_constr : (env -> Evd.evar_map -> constr -> Pp.t) -> unit
+
+(** Printers for contexts *)
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
+
+val print_constr : constr -> Pp.t
+[@@deprecated "use print_constr_env"]
+
+end
+
+val print_constr : constr -> Pp.t
+[@@deprecated "This is an internal, debug printer. WARNING, it is *extremely* likely that you want to use [Printer.pr_econstr_env] instead"]
+
+val print_constr_env : env -> Evd.evar_map -> constr -> Pp.t
+[@@deprecated "This is an internal, debug printer. WARNING, it is *extremely* likely that you want to use [Printer.pr_econstr_env] instead"]
+
+val print_rel_context : env -> Pp.t
+[@@deprecated "This is an internal, debug printer. WARNING, this function is not suitable for plugin code, if you still want to use it then call [Internal.print_rel_context] instead"]
diff --git a/engine/uState.ml b/engine/uState.ml
index 6c8dbe3f..29cb3c9b 100644
--- a/engine/uState.ml
+++ b/engine/uState.ml
@@ -20,14 +20,14 @@ type uinfo = {
uloc : Loc.t option;
}
-module UPairSet = Universes.UPairSet
+module UPairSet = UnivMinim.UPairSet
(* 2nd part used to check consistency on the fly. *)
type t =
- { uctx_names : Universes.universe_binders * uinfo Univ.LMap.t;
+ { uctx_names : UnivNames.universe_binders * uinfo Univ.LMap.t;
uctx_local : Univ.ContextSet.t; (** The local context of variables *)
uctx_seff_univs : Univ.LSet.t; (** Local universes used through private constants *)
- uctx_univ_variables : Universes.universe_opt_subst;
+ uctx_univ_variables : UnivSubst.universe_opt_subst;
(** The local universes that are unification variables *)
uctx_univ_algebraic : Univ.LSet.t;
(** The subset of unification variables that can be instantiated with
@@ -152,11 +152,12 @@ let drop_weak_constraints = ref false
let process_universe_constraints ctx cstrs =
let open Univ in
- let open Universes in
+ let open UnivSubst in
+ let open UnivProblem in
let univs = ctx.uctx_universes in
let vars = ref ctx.uctx_univ_variables in
let weak = ref ctx.uctx_weak_constraints in
- let normalize = normalize_univ_variable_opt_subst vars in
+ let normalize u = normalize_univ_variable_opt_subst !vars u in
let nf_constraint = function
| ULub (u, v) -> ULub (level_subst_of normalize u, level_subst_of normalize v)
| UWeak (u, v) -> UWeak (level_subst_of normalize u, level_subst_of normalize v)
@@ -203,7 +204,7 @@ let process_universe_constraints ctx cstrs =
in
let unify_universes cst local =
let cst = nf_constraint cst in
- if Constraints.is_trivial cst then local
+ if UnivProblem.is_trivial cst then local
else
match cst with
| ULe (l, r) ->
@@ -241,7 +242,7 @@ let process_universe_constraints ctx cstrs =
| UEq (l, r) -> equalize_universes l r local
in
let local =
- Constraints.fold unify_universes cstrs Univ.Constraint.empty
+ UnivProblem.Set.fold unify_universes cstrs Univ.Constraint.empty
in
!vars, !weak, local
@@ -249,13 +250,14 @@ let add_constraints ctx cstrs =
let univs, local = ctx.uctx_local in
let cstrs' = Univ.Constraint.fold (fun (l,d,r) acc ->
let l = Univ.Universe.make l and r = Univ.Universe.make r in
- let cstr' = match d with
+ let cstr' = let open UnivProblem in
+ match d with
| Univ.Lt ->
- Universes.ULe (Univ.Universe.super l, r)
- | Univ.Le -> Universes.ULe (l, r)
- | Univ.Eq -> Universes.UEq (l, r)
- in Universes.Constraints.add cstr' acc)
- cstrs Universes.Constraints.empty
+ ULe (Univ.Universe.super l, r)
+ | Univ.Le -> ULe (l, r)
+ | Univ.Eq -> UEq (l, r)
+ in UnivProblem.Set.add cstr' acc)
+ cstrs UnivProblem.Set.empty
in
let vars, weak, local' = process_universe_constraints ctx cstrs' in
{ ctx with
@@ -293,18 +295,30 @@ let constrain_variables diff ctx =
in
{ ctx with uctx_local = (univs, local); uctx_univ_variables = vars }
-let reference_of_level uctx =
+let qualid_of_level uctx =
let map, map_rev = uctx.uctx_names in
fun l ->
- try CAst.make @@ Libnames.Ident (Option.get (Univ.LMap.find l map_rev).uname)
+ try Libnames.qualid_of_ident (Option.get (Univ.LMap.find l map_rev).uname)
with Not_found | Option.IsNone ->
- Universes.reference_of_level l
+ UnivNames.qualid_of_level l
let pr_uctx_level uctx l =
- Libnames.pr_reference (reference_of_level uctx l)
+ Libnames.pr_qualid (qualid_of_level uctx l)
+
+type ('a, 'b) gen_universe_decl = {
+ univdecl_instance : 'a; (* Declared universes *)
+ univdecl_extensible_instance : bool; (* Can new universes be added *)
+ univdecl_constraints : 'b; (* Declared constraints *)
+ univdecl_extensible_constraints : bool (* Can new constraints be added *) }
type universe_decl =
- (Misctypes.lident list, Univ.Constraint.t) Misctypes.gen_universe_decl
+ (lident list, Univ.Constraint.t) gen_universe_decl
+
+let default_univ_decl =
+ { univdecl_instance = [];
+ univdecl_extensible_instance = true;
+ univdecl_constraints = Univ.Constraint.empty;
+ univdecl_extensible_constraints = true }
let error_unbound_universes left uctx =
let open Univ in
@@ -365,7 +379,6 @@ let check_implication uctx cstrs cstrs' =
(str "Universe constraints are not implied by the ones declared.")
let check_mono_univ_decl uctx decl =
- let open Misctypes in
let () =
let names = decl.univdecl_instance in
let extensible = decl.univdecl_extensible_instance in
@@ -378,7 +391,6 @@ let check_mono_univ_decl uctx decl =
uctx.uctx_local
let check_univ_decl ~poly uctx decl =
- let open Misctypes in
let ctx =
let names = decl.univdecl_instance in
let extensible = decl.univdecl_extensible_instance in
@@ -418,10 +430,17 @@ let univ_rigid = UnivRigid
let univ_flexible = UnivFlexible false
let univ_flexible_alg = UnivFlexible true
-let merge ?loc sideff rigid uctx ctx' =
+(** ~sideff indicates that it is ok to redeclare a universe.
+ ~extend also merges the universe context in the local constraint structures
+ and not only in the graph. This depends if the
+ context we merge comes from a side effect that is already inlined
+ or defined separately. In the later case, there is no extension,
+ see [emit_side_effects] for example. *)
+let merge ?loc ~sideff ~extend rigid uctx ctx' =
let open Univ in
let levels = ContextSet.levels ctx' in
- let uctx = if sideff then uctx else
+ let uctx =
+ if not extend then uctx else
match rigid with
| UnivRigid -> uctx
| UnivFlexible b ->
@@ -436,9 +455,8 @@ let merge ?loc sideff rigid uctx ctx' =
else { uctx with uctx_univ_variables = uvars' }
in
let uctx_local =
- if sideff then uctx.uctx_local
- else ContextSet.append ctx' uctx.uctx_local
- in
+ if not extend then uctx.uctx_local
+ else ContextSet.append ctx' uctx.uctx_local in
let declare g =
LSet.fold (fun u g ->
try UGraph.add_universe u false g
@@ -467,11 +485,11 @@ let merge_subst uctx s =
let emit_side_effects eff u =
let uctxs = Safe_typing.universes_of_private eff in
- List.fold_left (merge true univ_rigid) u uctxs
+ List.fold_left (merge ~sideff:true ~extend:false univ_rigid) u uctxs
let new_univ_variable ?loc rigid name
({ uctx_local = ctx; uctx_univ_variables = uvars; uctx_univ_algebraic = avars} as uctx) =
- let u = Universes.new_univ_level () in
+ let u = UnivGen.new_univ_level () in
let ctx' = Univ.ContextSet.add_universe u ctx in
let uctx', pred =
match rigid with
@@ -549,14 +567,33 @@ let is_sort_variable uctx s =
| _ -> None
let subst_univs_context_with_def def usubst (ctx, cst) =
- (Univ.LSet.diff ctx def, Universes.subst_univs_constraints usubst cst)
+ (Univ.LSet.diff ctx def, UnivSubst.subst_univs_constraints usubst cst)
+
+let is_trivial_leq (l,d,r) =
+ Univ.Level.is_prop l && (d == Univ.Le || (d == Univ.Lt && Univ.Level.is_set r))
+
+(* Prop < i <-> Set+1 <= i <-> Set < i *)
+let translate_cstr (l,d,r as cstr) =
+ let open Univ in
+ if Level.equal Level.prop l && d == Univ.Lt && not (Level.equal Level.set r) then
+ (Level.set, d, r)
+ else cstr
+
+let refresh_constraints univs (ctx, cstrs) =
+ let cstrs', univs' =
+ Univ.Constraint.fold (fun c (cstrs', univs as acc) ->
+ let c = translate_cstr c in
+ if is_trivial_leq c then acc
+ else (Univ.Constraint.add c cstrs', UGraph.enforce_constraint c univs))
+ cstrs (Univ.Constraint.empty, univs)
+ in ((ctx, cstrs'), univs')
let normalize_variables uctx =
- let normalized_variables, undef, def, subst =
- Universes.normalize_univ_variables uctx.uctx_univ_variables
+ 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
- let ctx_local', univs = Universes.refresh_constraints uctx.uctx_initial_universes ctx_local in
+ let ctx_local', univs = refresh_constraints uctx.uctx_initial_universes ctx_local in
subst, { uctx with uctx_local = ctx_local';
uctx_univ_variables = normalized_variables;
uctx_universes = univs }
@@ -582,7 +619,7 @@ let fix_undefined_variables uctx =
uctx_univ_algebraic = algs' }
let refresh_undefined_univ_variables uctx =
- let subst, ctx' = Universes.fresh_universe_context_set_instance uctx.uctx_local in
+ let subst, ctx' = UnivGen.fresh_universe_context_set_instance uctx.uctx_local in
let subst_fn u = Univ.subst_univs_level_level subst u in
let alg = Univ.LSet.fold (fun u acc -> Univ.LSet.add (subst_fn u) acc)
uctx.uctx_univ_algebraic Univ.LSet.empty
@@ -609,7 +646,7 @@ let refresh_undefined_univ_variables uctx =
uctx', subst
let minimize uctx =
- let open Universes in
+ let open UnivMinim in
let ((vars',algs'), us') =
normalize_context_set uctx.uctx_universes uctx.uctx_local uctx.uctx_univ_variables
uctx.uctx_univ_algebraic uctx.uctx_weak_constraints
@@ -637,11 +674,8 @@ let update_sigma_env uctx env =
{ uctx with uctx_initial_universes = univs;
uctx_universes = univs }
in
- merge true univ_rigid eunivs eunivs.uctx_local
+ merge ~sideff:true ~extend:false univ_rigid eunivs eunivs.uctx_local
let pr_weak prl {uctx_weak_constraints=weak} =
let open Pp in
prlist_with_sep fnl (fun (u,v) -> prl u ++ str " ~ " ++ prl v) (UPairSet.elements weak)
-
-(** Deprecated *)
-let normalize = minimize
diff --git a/engine/uState.mli b/engine/uState.mli
index 48c38faf..f833508e 100644
--- a/engine/uState.mli
+++ b/engine/uState.mli
@@ -26,7 +26,7 @@ val empty : t
val make : UGraph.t -> t
-val make_with_initial_binders : UGraph.t -> Misctypes.lident list -> t
+val make_with_initial_binders : UGraph.t -> lident list -> t
val is_empty : t -> bool
@@ -34,9 +34,9 @@ val union : t -> t -> t
val of_context_set : Univ.ContextSet.t -> t
-val of_binders : Universes.universe_binders -> t
+val of_binders : UnivNames.universe_binders -> t
-val universe_binders : t -> Universes.universe_binders
+val universe_binders : t -> UnivNames.universe_binders
(** {5 Projections} *)
@@ -44,7 +44,7 @@ val context_set : t -> Univ.ContextSet.t
(** The local context of the state, i.e. a set of bound variables together
with their associated constraints. *)
-val subst : t -> Universes.universe_opt_subst
+val subst : t -> UnivSubst.universe_opt_subst
(** The local universes that are unification variables *)
val ugraph : t -> UGraph.t
@@ -79,7 +79,7 @@ val add_constraints : t -> Univ.Constraint.t -> t
@raise UniversesDiffer when universes differ
*)
-val add_universe_constraints : t -> Universes.Constraints.t -> t
+val add_universe_constraints : t -> UnivProblem.Set.t -> t
(**
@raise UniversesDiffer when universes differ
*)
@@ -103,8 +103,8 @@ val univ_rigid : rigid
val univ_flexible : rigid
val univ_flexible_alg : rigid
-val merge : ?loc:Loc.t -> bool -> rigid -> t -> Univ.ContextSet.t -> t
-val merge_subst : t -> Universes.universe_opt_subst -> t
+val merge : ?loc:Loc.t -> sideff:bool -> extend:bool -> rigid -> t -> Univ.ContextSet.t -> t
+val merge_subst : t -> UnivSubst.universe_opt_subst -> t
val emit_side_effects : Safe_typing.private_constants -> t -> t
val new_univ_variable : ?loc:Loc.t -> rigid -> Id.t option -> t -> t * Univ.Level.t
@@ -137,11 +137,17 @@ val refresh_undefined_univ_variables : t -> t * Univ.universe_level_subst
(** Universe minimization *)
val minimize : t -> t
-val normalize : t -> t
-[@@ocaml.deprecated "Alias of UState.minimize"]
+
+type ('a, 'b) gen_universe_decl = {
+ univdecl_instance : 'a; (* Declared universes *)
+ univdecl_extensible_instance : bool; (* Can new universes be added *)
+ univdecl_constraints : 'b; (* Declared constraints *)
+ univdecl_extensible_constraints : bool (* Can new constraints be added *) }
type universe_decl =
- (Misctypes.lident list, Univ.Constraint.t) Misctypes.gen_universe_decl
+ (lident list, Univ.Constraint.t) gen_universe_decl
+
+val default_univ_decl : universe_decl
(** [check_univ_decl ctx decl]
@@ -165,6 +171,6 @@ val update_sigma_env : t -> Environ.env -> t
(** {5 Pretty-printing} *)
val pr_uctx_level : t -> Univ.Level.t -> Pp.t
-val reference_of_level : t -> Univ.Level.t -> Libnames.reference
+val qualid_of_level : t -> Univ.Level.t -> Libnames.qualid
val pr_weak : (Univ.Level.t -> Pp.t) -> t -> Pp.t
diff --git a/engine/univGen.ml b/engine/univGen.ml
new file mode 100644
index 00000000..b07d4848
--- /dev/null
+++ b/engine/univGen.ml
@@ -0,0 +1,246 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* Global.current_dirpath (), n)
+
+let new_univ_level () =
+ let dp, id = new_univ_id () in
+ Univ.Level.make dp id
+
+let fresh_level () = new_univ_level ()
+
+(* TODO: remove *)
+let new_univ dp = Univ.Universe.make (new_univ_level dp)
+let new_Type dp = mkType (new_univ dp)
+let new_Type_sort dp = Type (new_univ dp)
+
+let fresh_universe_instance ctx =
+ let init _ = new_univ_level () in
+ Instance.of_array (Array.init (AUContext.size ctx) init)
+
+let fresh_instance_from_context ctx =
+ let inst = fresh_universe_instance ctx in
+ let constraints = AUContext.instantiate inst ctx in
+ inst, constraints
+
+let fresh_instance ctx =
+ let ctx' = ref LSet.empty in
+ let init _ =
+ let u = new_univ_level () in
+ ctx' := LSet.add u !ctx'; u
+ in
+ let inst = Instance.of_array (Array.init (AUContext.size ctx) init)
+ in !ctx', inst
+
+let existing_instance ctx inst =
+ let () =
+ let len1 = Array.length (Instance.to_array inst)
+ and len2 = AUContext.size ctx in
+ if not (len1 == len2) then
+ CErrors.user_err ~hdr:"Universes"
+ Pp.(str "Polymorphic constant expected " ++ int len2 ++
+ str" levels but was given " ++ int len1)
+ else ()
+ in LSet.empty, inst
+
+let fresh_instance_from ctx inst =
+ let ctx', inst =
+ match inst with
+ | Some inst -> existing_instance ctx inst
+ | None -> fresh_instance ctx
+ in
+ let constraints = AUContext.instantiate inst ctx in
+ inst, (ctx', constraints)
+
+(** Fresh universe polymorphic construction *)
+
+let fresh_constant_instance env c inst =
+ let cb = lookup_constant c env in
+ match cb.Declarations.const_universes with
+ | Declarations.Monomorphic_const _ -> ((c,Instance.empty), ContextSet.empty)
+ | Declarations.Polymorphic_const auctx ->
+ let inst, ctx =
+ fresh_instance_from auctx inst
+ in
+ ((c, inst), ctx)
+
+let fresh_inductive_instance env ind inst =
+ let mib, mip = Inductive.lookup_mind_specif env ind in
+ match mib.Declarations.mind_universes with
+ | Declarations.Monomorphic_ind _ ->
+ ((ind,Instance.empty), ContextSet.empty)
+ | Declarations.Polymorphic_ind uactx ->
+ let inst, ctx = (fresh_instance_from uactx) inst in
+ ((ind,inst), ctx)
+ | Declarations.Cumulative_ind acumi ->
+ let inst, ctx =
+ fresh_instance_from (Univ.ACumulativityInfo.univ_context acumi) inst
+ in ((ind,inst), ctx)
+
+let fresh_constructor_instance env (ind,i) inst =
+ let mib, mip = Inductive.lookup_mind_specif env ind in
+ match mib.Declarations.mind_universes with
+ | Declarations.Monomorphic_ind _ -> (((ind,i),Instance.empty), ContextSet.empty)
+ | Declarations.Polymorphic_ind auctx ->
+ let inst, ctx = fresh_instance_from auctx inst in
+ (((ind,i),inst), ctx)
+ | Declarations.Cumulative_ind acumi ->
+ let inst, ctx = fresh_instance_from (ACumulativityInfo.univ_context acumi) inst in
+ (((ind,i),inst), ctx)
+
+open Globnames
+
+let fresh_global_instance ?names env gr =
+ match gr with
+ | VarRef id -> mkVar id, ContextSet.empty
+ | ConstRef sp ->
+ let c, ctx = fresh_constant_instance env sp names in
+ mkConstU c, ctx
+ | ConstructRef sp ->
+ let c, ctx = fresh_constructor_instance env sp names in
+ mkConstructU c, ctx
+ | IndRef sp ->
+ let c, ctx = fresh_inductive_instance env sp names in
+ mkIndU c, ctx
+
+let fresh_constant_instance env sp =
+ fresh_constant_instance env sp None
+
+let fresh_inductive_instance env sp =
+ fresh_inductive_instance env sp None
+
+let fresh_constructor_instance env sp =
+ fresh_constructor_instance env sp None
+
+let constr_of_global gr =
+ let c, ctx = fresh_global_instance (Global.env ()) gr in
+ if not (Univ.ContextSet.is_empty ctx) then
+ if Univ.LSet.is_empty (Univ.ContextSet.levels ctx) then
+ (* Should be an error as we might forget constraints, allow for now
+ to make firstorder work with "using" clauses *)
+ c
+ else CErrors.user_err ~hdr:"constr_of_global"
+ Pp.(str "globalization of polymorphic reference " ++ Nametab.pr_global_env Id.Set.empty gr ++
+ str " would forget universes.")
+ else c
+
+let constr_of_global_univ (gr,u) =
+ match gr with
+ | VarRef id -> mkVar id
+ | ConstRef sp -> mkConstU (sp,u)
+ | ConstructRef sp -> mkConstructU (sp,u)
+ | IndRef sp -> mkIndU (sp,u)
+
+let fresh_global_or_constr_instance env = function
+ | IsConstr c -> c, ContextSet.empty
+ | IsGlobal gr -> fresh_global_instance env gr
+
+let global_of_constr c =
+ match kind c with
+ | Const (c, u) -> ConstRef c, u
+ | Ind (i, u) -> IndRef i, u
+ | Construct (c, u) -> ConstructRef c, u
+ | Var id -> VarRef id, Instance.empty
+ | _ -> raise Not_found
+
+open Declarations
+
+let type_of_reference env r =
+ match r with
+ | VarRef id -> Environ.named_type id env, ContextSet.empty
+ | ConstRef c ->
+ let cb = Environ.lookup_constant c env in
+ let ty = cb.const_type in
+ begin
+ match cb.const_universes with
+ | Monomorphic_const _ -> ty, ContextSet.empty
+ | Polymorphic_const auctx ->
+ let inst, ctx = fresh_instance_from auctx None in
+ Vars.subst_instance_constr inst ty, ctx
+ end
+ | IndRef ind ->
+ let (mib, oib as specif) = Inductive.lookup_mind_specif env ind in
+ begin
+ match mib.mind_universes with
+ | Monomorphic_ind _ ->
+ let ty = Inductive.type_of_inductive env (specif, Univ.Instance.empty) in
+ ty, ContextSet.empty
+ | Polymorphic_ind auctx ->
+ let inst, ctx = fresh_instance_from auctx None in
+ let ty = Inductive.type_of_inductive env (specif, inst) in
+ ty, ctx
+ | Cumulative_ind cumi ->
+ let inst, ctx =
+ fresh_instance_from (ACumulativityInfo.univ_context cumi) None
+ in
+ let ty = Inductive.type_of_inductive env (specif, inst) in
+ ty, ctx
+ end
+
+ | ConstructRef cstr ->
+ let (mib,oib as specif) =
+ Inductive.lookup_mind_specif env (inductive_of_constructor cstr)
+ in
+ begin
+ match mib.mind_universes with
+ | Monomorphic_ind _ ->
+ Inductive.type_of_constructor (cstr,Instance.empty) specif, ContextSet.empty
+ | Polymorphic_ind auctx ->
+ let inst, ctx = fresh_instance_from auctx None in
+ Inductive.type_of_constructor (cstr,inst) specif, ctx
+ | Cumulative_ind cumi ->
+ let inst, ctx =
+ fresh_instance_from (ACumulativityInfo.univ_context cumi) None
+ in
+ Inductive.type_of_constructor (cstr,inst) specif, ctx
+ end
+
+let type_of_global t = type_of_reference (Global.env ()) t
+
+let fresh_sort_in_family = function
+ | InProp -> Sorts.prop, ContextSet.empty
+ | InSet -> Sorts.set, ContextSet.empty
+ | InType ->
+ let u = fresh_level () in
+ Type (Univ.Universe.make u), ContextSet.singleton u
+
+let new_sort_in_family sf =
+ fst (fresh_sort_in_family sf)
+
+let extend_context (a, ctx) (ctx') =
+ (a, ContextSet.union ctx ctx')
+
+let new_global_univ () =
+ let u = fresh_level () in
+ (Univ.Universe.make u, ContextSet.singleton u)
+
+let fresh_universe_context_set_instance ctx =
+ if ContextSet.is_empty ctx then LMap.empty, ctx
+ else
+ let (univs, cst) = ContextSet.levels ctx, ContextSet.constraints ctx in
+ let univs',subst = LSet.fold
+ (fun u (univs',subst) ->
+ let u' = fresh_level () in
+ (LSet.add u' univs', LMap.add u u' subst))
+ univs (LSet.empty, LMap.empty)
+ in
+ let cst' = subst_univs_level_constraints subst cst in
+ subst, (univs', cst')
diff --git a/engine/univGen.mli b/engine/univGen.mli
new file mode 100644
index 00000000..43942493
--- /dev/null
+++ b/engine/univGen.mli
@@ -0,0 +1,80 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* universe_id
+val new_univ_level : unit -> Level.t
+val new_univ : unit -> Universe.t
+val new_Type : unit -> types
+val new_Type_sort : unit -> Sorts.t
+
+val new_global_univ : unit -> Universe.t in_universe_context_set
+val new_sort_in_family : Sorts.family -> Sorts.t
+
+(** Build a fresh instance for a given context, its associated substitution and
+ the instantiated constraints. *)
+
+val fresh_instance_from_context : AUContext.t ->
+ Instance.t constrained
+
+val fresh_instance_from : AUContext.t -> Instance.t option ->
+ Instance.t in_universe_context_set
+
+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
+val fresh_inductive_instance : env -> inductive ->
+ pinductive in_universe_context_set
+val fresh_constructor_instance : env -> constructor ->
+ pconstructor in_universe_context_set
+
+val fresh_global_instance : ?names:Univ.Instance.t -> env -> GlobRef.t ->
+ constr in_universe_context_set
+
+val fresh_global_or_constr_instance : env -> Globnames.global_reference_or_constr ->
+ constr in_universe_context_set
+
+(** Get fresh variables for the universe context.
+ Useful to make tactics that manipulate constrs in universe contexts polymorphic. *)
+val fresh_universe_context_set_instance : ContextSet.t ->
+ universe_level_subst * ContextSet.t
+
+(** Raises [Not_found] if not a global reference. *)
+val global_of_constr : constr -> GlobRef.t puniverses
+
+val constr_of_global_univ : GlobRef.t puniverses -> constr
+
+val extend_context : 'a in_universe_context_set -> ContextSet.t ->
+ 'a in_universe_context_set
+
+(** Create a fresh global in the global environment, without side effects.
+ BEWARE: this raises an ANOMALY on polymorphic constants/inductives:
+ the constraints should be properly added to an evd.
+ See Evd.fresh_global, Evarutil.new_global, and pf_constr_of_global for
+ the proper way to get a fresh copy of a global reference. *)
+val constr_of_global : GlobRef.t -> constr
+
+(** Returns the type of the global reference, by creating a fresh instance of polymorphic
+ references and computing their instantiated universe context. (side-effect on the
+ universe counter, use with care). *)
+val type_of_global : GlobRef.t -> types in_universe_context_set
diff --git a/engine/univMinim.ml b/engine/univMinim.ml
new file mode 100644
index 00000000..f10e6d2e
--- /dev/null
+++ b/engine/univMinim.ml
@@ -0,0 +1,383 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(*
+ LMap.add u [t] map
+
+(** Precondition: flexible <= ctx *)
+let choose_canonical ctx flexible algs s =
+ let global = LSet.diff s ctx in
+ let flexible, rigid = LSet.partition flexible (LSet.inter s ctx) in
+ (** If there is a global universe in the set, choose it *)
+ if not (LSet.is_empty global) then
+ let canon = LSet.choose global in
+ canon, (LSet.remove canon global, rigid, flexible)
+ else (** No global in the equivalence class, choose a rigid one *)
+ if not (LSet.is_empty rigid) then
+ let canon = LSet.choose rigid in
+ canon, (global, LSet.remove canon rigid, flexible)
+ else (** There are only flexible universes in the equivalence
+ class, choose a non-algebraic. *)
+ let algs, nonalgs = LSet.partition (fun x -> LSet.mem x algs) flexible in
+ if not (LSet.is_empty nonalgs) then
+ let canon = LSet.choose nonalgs in
+ canon, (global, rigid, LSet.remove canon flexible)
+ else
+ let canon = LSet.choose algs in
+ canon, (global, rigid, LSet.remove canon flexible)
+
+(* Eq < Le < Lt *)
+let compare_constraint_type d d' =
+ match d, d' with
+ | Eq, Eq -> 0
+ | Eq, _ -> -1
+ | _, Eq -> 1
+ | Le, Le -> 0
+ | Le, _ -> -1
+ | _, Le -> 1
+ | Lt, Lt -> 0
+
+type lowermap = constraint_type LMap.t
+
+let lower_union =
+ let merge k a b =
+ match a, b with
+ | Some _, None -> a
+ | None, Some _ -> b
+ | None, None -> None
+ | Some l, Some r ->
+ if compare_constraint_type l r >= 0 then a
+ else b
+ in LMap.merge merge
+
+let lower_add l c m =
+ try let c' = LMap.find l m in
+ if compare_constraint_type c c' > 0 then
+ LMap.add l c m
+ else m
+ with Not_found -> LMap.add l c m
+
+let lower_of_list l =
+ List.fold_left (fun acc (d,l) -> LMap.add l d acc) LMap.empty l
+
+type lbound = { enforce : bool; alg : bool; lbound: Universe.t; lower : lowermap }
+
+exception Found of Level.t * lowermap
+let find_inst insts v =
+ try LMap.iter (fun k {enforce;alg;lbound=v';lower} ->
+ if not alg && enforce && Universe.equal v' v then raise (Found (k, lower)))
+ insts; raise Not_found
+ with Found (f,l) -> (f,l)
+
+let compute_lbound left =
+ (** The universe variable was not fixed yet.
+ Compute its level using its lower bound. *)
+ let sup l lbound =
+ match lbound with
+ | None -> Some l
+ | Some l' -> Some (Universe.sup l l')
+ in
+ List.fold_left (fun lbound (d, l) ->
+ if d == Le (* l <= ?u *) then sup l lbound
+ else (* l < ?u *)
+ (assert (d == Lt);
+ if not (Universe.level l == None) then
+ sup (Universe.super l) lbound
+ else None))
+ None left
+
+let instantiate_with_lbound u lbound lower ~alg ~enforce (ctx, us, algs, insts, cstrs) =
+ if enforce then
+ let inst = Universe.make u in
+ let cstrs' = enforce_leq lbound inst cstrs in
+ (ctx, us, LSet.remove u algs,
+ LMap.add u {enforce;alg;lbound;lower} insts, cstrs'),
+ {enforce; alg; lbound=inst; lower}
+ else (* Actually instantiate *)
+ (Univ.LSet.remove u ctx, Univ.LMap.add u (Some lbound) us, algs,
+ LMap.add u {enforce;alg;lbound;lower} insts, cstrs),
+ {enforce; alg; lbound; lower}
+
+type constraints_map = (Univ.constraint_type * Univ.LMap.key) list Univ.LMap.t
+
+let _pr_constraints_map (cmap:constraints_map) =
+ let open Pp in
+ LMap.fold (fun l cstrs acc ->
+ Level.pr l ++ str " => " ++
+ prlist_with_sep spc (fun (d,r) -> pr_constraint_type d ++ Level.pr r) cstrs ++
+ fnl () ++ acc)
+ cmap (mt ())
+
+let remove_alg l (ctx, us, algs, insts, cstrs) =
+ (ctx, us, LSet.remove l algs, insts, cstrs)
+
+let not_lower lower (d,l) =
+ (* We're checking if (d,l) is already implied by the lower
+ constraints on some level u. If it represents l < u (d is Lt
+ or d is Le and i > 0, the i < 0 case is impossible due to
+ invariants of Univ), and the lower constraints only have l <=
+ u then it is not implied. *)
+ Univ.Universe.exists
+ (fun (l,i) ->
+ let d =
+ if i == 0 then d
+ else match d with
+ | Le -> Lt
+ | d -> d
+ in
+ try let d' = LMap.find l lower in
+ (* If d is stronger than the already implied lower
+ * constraints we must keep it. *)
+ compare_constraint_type d d' > 0
+ with Not_found ->
+ (** No constraint existing on l *) true) l
+
+exception UpperBoundedAlg
+(** [enforce_uppers upper lbound cstrs] interprets [upper] as upper
+ constraints to [lbound], adding them to [cstrs].
+
+ @raise UpperBoundedAlg if any [upper] constraints are strict and
+ [lbound] algebraic. *)
+let enforce_uppers upper lbound cstrs =
+ List.fold_left (fun cstrs (d, r) ->
+ if d == Univ.Le then
+ enforce_leq lbound (Universe.make r) cstrs
+ else
+ match Universe.level lbound with
+ | Some lev -> Constraint.add (lev, d, r) cstrs
+ | None -> raise UpperBoundedAlg)
+ cstrs upper
+
+let minimize_univ_variables ctx us algs left right cstrs =
+ let left, lbounds =
+ Univ.LMap.fold (fun r lower (left, lbounds as acc) ->
+ if Univ.LMap.mem r us || not (Univ.LSet.mem r ctx) then acc
+ else (* Fixed universe, just compute its glb for sharing *)
+ let lbounds =
+ match compute_lbound (List.map (fun (d,l) -> d, Universe.make l) lower) with
+ | None -> lbounds
+ | Some lbound -> LMap.add r {enforce=true; alg=false; lbound; lower=lower_of_list lower}
+ lbounds
+ in (Univ.LMap.remove r left, lbounds))
+ left (left, Univ.LMap.empty)
+ in
+ let rec instance (ctx, us, algs, insts, cstrs as acc) u =
+ let acc, left, lower =
+ match LMap.find u left with
+ | exception Not_found -> acc, [], LMap.empty
+ | l ->
+ let acc, left, newlow, lower =
+ List.fold_left
+ (fun (acc, left, newlow, lower') (d, l) ->
+ let acc', {enforce=enf;alg;lbound=l';lower} = aux acc l in
+ let l' =
+ if enf then Universe.make l
+ else l'
+ in acc', (d, l') :: left,
+ lower_add l d newlow, lower_union lower lower')
+ (acc, [], LMap.empty, LMap.empty) l
+ in
+ let left = CList.uniquize (List.filter (not_lower lower) left) in
+ (acc, left, LMap.union newlow lower)
+ in
+ let instantiate_lbound lbound =
+ let alg = LSet.mem u algs in
+ if alg then
+ (* u is algebraic: we instantiate it with its lower bound, if any,
+ or enforce the constraints if it is bounded from the top. *)
+ let lower = LSet.fold LMap.remove (Universe.levels lbound) lower in
+ instantiate_with_lbound u lbound lower ~alg:true ~enforce:false acc
+ else (* u is non algebraic *)
+ match Universe.level lbound with
+ | Some l -> (* The lowerbound is directly a level *)
+ (* u is not algebraic but has no upper bounds,
+ we instantiate it with its lower bound if it is a
+ different level, otherwise we keep it. *)
+ let lower = LMap.remove l lower in
+ if not (Level.equal l u) then
+ (* Should check that u does not
+ have upper constraints that are not already in right *)
+ let acc = remove_alg l acc in
+ instantiate_with_lbound u lbound lower ~alg:false ~enforce:false acc
+ else acc, {enforce=true; alg=false; lbound; lower}
+ | None ->
+ begin match find_inst insts lbound with
+ | can, lower ->
+ (* Another universe represents the same lower bound,
+ we can share them with no harm. *)
+ let lower = LMap.remove can lower in
+ instantiate_with_lbound u (Universe.make can) lower ~alg:false ~enforce:false acc
+ | exception Not_found ->
+ (* We set u as the canonical universe representing lbound *)
+ instantiate_with_lbound u lbound lower ~alg:false ~enforce:true acc
+ end
+ in
+ let enforce_uppers ((ctx,us,algs,insts,cstrs), b as acc) =
+ match LMap.find u right with
+ | exception Not_found -> acc
+ | upper ->
+ let upper = List.filter (fun (d, r) -> not (LMap.mem r us)) upper in
+ let cstrs = enforce_uppers upper b.lbound cstrs in
+ (ctx, us, algs, insts, cstrs), b
+ in
+ if not (LSet.mem u ctx)
+ then enforce_uppers (acc, {enforce=true; alg=false; lbound=Universe.make u; lower})
+ else
+ let lbound = compute_lbound left in
+ match lbound with
+ | None -> (* Nothing to do *)
+ enforce_uppers (acc, {enforce=true;alg=false;lbound=Universe.make u; lower})
+ | Some lbound ->
+ try enforce_uppers (instantiate_lbound lbound)
+ with UpperBoundedAlg ->
+ enforce_uppers (acc, {enforce=true; alg=false; lbound=Universe.make u; lower})
+ and aux (ctx, us, algs, seen, cstrs as acc) u =
+ try acc, LMap.find u seen
+ with Not_found -> instance acc u
+ in
+ LMap.fold (fun u v (ctx, us, algs, seen, cstrs as acc) ->
+ if v == None then fst (aux acc u)
+ else LSet.remove u ctx, us, LSet.remove u algs, seen, cstrs)
+ us (ctx, us, algs, lbounds, cstrs)
+
+module UPairs = OrderedType.UnorderedPair(Univ.Level)
+module UPairSet = Set.Make (UPairs)
+
+let normalize_context_set g ctx us algs weak =
+ let (ctx, csts) = ContextSet.levels ctx, ContextSet.constraints ctx in
+ (** Keep the Prop/Set <= i constraints separate for minimization *)
+ let smallles, csts =
+ Constraint.partition (fun (l,d,r) -> d == Le && Level.is_small l) csts
+ in
+ let smallles = if is_set_minimization ()
+ then Constraint.filter (fun (l,d,r) -> LSet.mem r ctx) smallles
+ else Constraint.empty
+ in
+ let csts, partition =
+ (* We first put constraints in a normal-form: all self-loops are collapsed
+ to equalities. *)
+ let g = LSet.fold (fun v g -> UGraph.add_universe v false g)
+ ctx UGraph.initial_universes
+ in
+ let add_soft u g =
+ if not (Level.is_small u || LSet.mem u ctx)
+ then try UGraph.add_universe u false g with UGraph.AlreadyDeclared -> g
+ else g
+ in
+ let g = Constraint.fold
+ (fun (l, d, r) g -> add_soft r (add_soft l g))
+ csts g
+ in
+ let g = UGraph.merge_constraints csts g in
+ UGraph.constraints_of_universes g
+ in
+ (* We ignore the trivial Prop/Set <= i constraints. *)
+ let noneqs =
+ Constraint.filter
+ (fun (l,d,r) -> not ((d == Le && Level.is_small l) ||
+ (Level.is_prop l && d == Lt && Level.is_set r)))
+ csts
+ in
+ let noneqs = Constraint.union noneqs smallles in
+ let flex x = LMap.mem x us in
+ let ctx, us, eqs = List.fold_left (fun (ctx, us, cstrs) s ->
+ let canon, (global, rigid, flexible) = choose_canonical ctx flex algs s in
+ (* Add equalities for globals which can't be merged anymore. *)
+ let cstrs = LSet.fold (fun g cst ->
+ Constraint.add (canon, Eq, g) cst) global
+ cstrs
+ in
+ (* Also add equalities for rigid variables *)
+ let cstrs = LSet.fold (fun g cst ->
+ Constraint.add (canon, Eq, g) cst) rigid
+ cstrs
+ in
+ let canonu = Some (Universe.make canon) in
+ let us = LSet.fold (fun f -> LMap.add f canonu) flexible us in
+ (LSet.diff ctx flexible, us, cstrs))
+ (ctx, us, Constraint.empty) partition
+ in
+ (* Process weak constraints: when one side is flexible and the 2
+ universes are unrelated unify them. *)
+ let ctx, us, g = UPairSet.fold (fun (u,v) (ctx, us, g as acc) ->
+ let norm = level_subst_of (normalize_univ_variable_opt_subst us) in
+ let u = norm u and v = norm v in
+ let set_to a b =
+ (LSet.remove a ctx,
+ LMap.add a (Some (Universe.make b)) us,
+ UGraph.enforce_constraint (a,Eq,b) g)
+ in
+ if UGraph.check_constraint g (u,Le,v) || UGraph.check_constraint g (v,Le,u)
+ then acc
+ else
+ if LMap.mem u us
+ then set_to u v
+ else if LMap.mem v us
+ then set_to v u
+ else acc)
+ weak (ctx, us, g) in
+ (* Noneqs is now in canonical form w.r.t. equality constraints,
+ and contains only inequality constraints. *)
+ let noneqs =
+ let norm = level_subst_of (normalize_univ_variable_opt_subst us) in
+ Constraint.fold (fun (u,d,v) noneqs ->
+ let u = norm u and v = norm v in
+ if d != Lt && Level.equal u v then noneqs
+ else Constraint.add (u,d,v) noneqs)
+ noneqs Constraint.empty
+ in
+ (* Compute the left and right set of flexible variables, constraints
+ mentionning other variables remain in noneqs. *)
+ let noneqs, ucstrsl, ucstrsr =
+ Constraint.fold (fun (l,d,r as cstr) (noneq, ucstrsl, ucstrsr) ->
+ let lus = LMap.mem l us and rus = LMap.mem r us in
+ let ucstrsl' =
+ if lus then add_list_map l (d, r) ucstrsl
+ else ucstrsl
+ and ucstrsr' =
+ add_list_map r (d, l) ucstrsr
+ in
+ let noneqs =
+ if lus || rus then noneq
+ else Constraint.add cstr noneq
+ in (noneqs, ucstrsl', ucstrsr'))
+ noneqs (Constraint.empty, LMap.empty, LMap.empty)
+ in
+ (* Now we construct the instantiation of each variable. *)
+ let ctx', us, algs, inst, noneqs =
+ minimize_univ_variables ctx us algs ucstrsr ucstrsl noneqs
+ in
+ let us = normalize_opt_subst us in
+ (us, algs), (ctx', Constraint.union noneqs eqs)
+
+(* let normalize_conkey = CProfile.declare_profile "normalize_context_set" *)
+(* let normalize_context_set a b c = CProfile.profile3 normalize_conkey normalize_context_set a b c *)
diff --git a/engine/univMinim.mli b/engine/univMinim.mli
new file mode 100644
index 00000000..9f80b7ac
--- /dev/null
+++ b/engine/univMinim.mli
@@ -0,0 +1,32 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* ContextSet.t ->
+ universe_opt_subst (* The defined and undefined variables *) ->
+ LSet.t (* univ variables that can be substituted by algebraics *) ->
+ UPairSet.t (* weak equality constraints *) ->
+ (universe_opt_subst * LSet.t) in_universe_context_set
diff --git a/engine/univNames.ml b/engine/univNames.ml
new file mode 100644
index 00000000..a6884017
--- /dev/null
+++ b/engine/univNames.ml
@@ -0,0 +1,106 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(*
+ begin
+ try Nametab.shortest_qualid_of_universe na
+ with Not_found ->
+ let name = Id.of_string_soft (string_of_int n) in
+ Libnames.make_qualid d name
+ end
+ | None ->
+ Libnames.qualid_of_ident @@ Id.of_string_soft (Level.to_string l)
+
+let pr_with_global_universes l = Libnames.pr_qualid (qualid_of_level l)
+
+(** Global universe information outside the kernel, to handle
+ polymorphic universe names in sections that have to be discharged. *)
+
+let universe_map = (Summary.ref UnivIdMap.empty ~name:"global universe info" : bool Nametab.UnivIdMap.t ref)
+
+let add_global_universe u p =
+ match Level.name u with
+ | Some n -> universe_map := Nametab.UnivIdMap.add n p !universe_map
+ | None -> ()
+
+let is_polymorphic l =
+ match Level.name l with
+ | Some n ->
+ (try Nametab.UnivIdMap.find n !universe_map
+ with Not_found -> false)
+ | None -> false
+
+(** Local universe names of polymorphic references *)
+
+type universe_binders = Univ.Level.t Names.Id.Map.t
+
+let empty_binders = Id.Map.empty
+
+let universe_binders_table = Summary.ref Refmap.empty ~name:"universe binders"
+
+let universe_binders_of_global ref : universe_binders =
+ try
+ let l = Refmap.find ref !universe_binders_table in l
+ with Not_found -> Names.Id.Map.empty
+
+let cache_ubinder (_,(ref,l)) =
+ universe_binders_table := Refmap.add ref l !universe_binders_table
+
+let subst_ubinder (subst,(ref,l as orig)) =
+ let ref' = fst (Globnames.subst_global subst ref) in
+ if ref == ref' then orig else ref', l
+
+let discharge_ubinder (_,(ref,l)) =
+ Some (Lib.discharge_global ref, l)
+
+let ubinder_obj : GlobRef.t * universe_binders -> Libobject.obj =
+ let open Libobject in
+ declare_object { (default_object "universe binder") with
+ cache_function = cache_ubinder;
+ load_function = (fun _ x -> cache_ubinder x);
+ classify_function = (fun x -> Substitute x);
+ subst_function = subst_ubinder;
+ discharge_function = discharge_ubinder;
+ rebuild_function = (fun x -> x); }
+
+let register_universe_binders ref ubinders =
+ (* Add the polymorphic (section) universes *)
+ let ubinders = UnivIdMap.fold (fun lvl poly ubinders ->
+ let qid = Nametab.shortest_qualid_of_universe lvl in
+ let level = Level.make (fst lvl) (snd lvl) in
+ if poly then Id.Map.add (snd (Libnames.repr_qualid qid)) level ubinders
+ else ubinders)
+ !universe_map ubinders
+ in
+ if not (Id.Map.is_empty ubinders)
+ then Lib.add_anonymous_leaf (ubinder_obj (ref,ubinders))
+
+type univ_name_list = Names.lname list
+
+let universe_binders_with_opt_names ref levels = function
+ | None -> universe_binders_of_global ref
+ | Some udecl ->
+ if Int.equal(List.length levels) (List.length udecl)
+ then
+ List.fold_left2 (fun acc { CAst.v = na} lvl -> match na with
+ | Anonymous -> acc
+ | Name na -> Names.Id.Map.add na lvl acc)
+ empty_binders udecl levels
+ else
+ CErrors.user_err ~hdr:"universe_binders_with_opt_names"
+ Pp.(str "Universe instance should have length " ++ int (List.length levels))
diff --git a/engine/univNames.mli b/engine/univNames.mli
new file mode 100644
index 00000000..837beac2
--- /dev/null
+++ b/engine/univNames.mli
@@ -0,0 +1,41 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* Pp.t
+val qualid_of_level : Level.t -> Libnames.qualid
+
+(** Global universe information outside the kernel, to handle
+ polymorphic universes in sections that have to be discharged. *)
+val add_global_universe : Level.t -> Decl_kinds.polymorphic -> unit
+
+(** Is [lvl] a global polymorphic universe? (ie section polymorphic universe) *)
+val is_polymorphic : Level.t -> bool
+
+(** Local universe name <-> level mapping *)
+
+type universe_binders = Univ.Level.t Names.Id.Map.t
+
+val empty_binders : universe_binders
+
+val register_universe_binders : Names.GlobRef.t -> universe_binders -> unit
+val universe_binders_of_global : Names.GlobRef.t -> universe_binders
+
+type univ_name_list = Names.lname list
+
+(** [universe_binders_with_opt_names ref u l]
+
+ If [l] is [Some univs] return the universe binders naming the levels of [u] by [univs] (skipping Anonymous).
+ May error if the lengths mismatch.
+
+ Otherwise return [universe_binders_of_global ref]. *)
+val universe_binders_with_opt_names : Names.GlobRef.t ->
+ Univ.Level.t list -> univ_name_list option -> universe_binders
diff --git a/engine/univProblem.ml b/engine/univProblem.ml
new file mode 100644
index 00000000..bc2edc13
--- /dev/null
+++ b/engine/univProblem.ml
@@ -0,0 +1,166 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* Universe.equal u v
+ | ULub (u, v) | UWeak (u, v) -> Level.equal u v
+
+let subst_univs fn = function
+ | ULe (u, v) ->
+ let u' = subst_univs_universe fn u and v' = subst_univs_universe fn v in
+ if Universe.equal u' v' then None
+ else Some (ULe (u',v'))
+ | UEq (u, v) ->
+ let u' = subst_univs_universe fn u and v' = subst_univs_universe fn v in
+ if Universe.equal u' v' then None
+ else Some (ULe (u',v'))
+ | ULub (u, v) ->
+ let u' = level_subst_of fn u and v' = level_subst_of fn v in
+ if Level.equal u' v' then None
+ else Some (ULub (u',v'))
+ | UWeak (u, v) ->
+ let u' = level_subst_of fn u and v' = level_subst_of fn v in
+ if Level.equal u' v' then None
+ else Some (UWeak (u',v'))
+
+module Set = struct
+ module S = Set.Make(
+ struct
+ type nonrec t = t
+
+ let compare x y =
+ match x, y with
+ | ULe (u, v), ULe (u', v') ->
+ let i = Universe.compare u u' in
+ if Int.equal i 0 then Universe.compare v v'
+ else i
+ | UEq (u, v), UEq (u', v') ->
+ let i = Universe.compare u u' in
+ if Int.equal i 0 then Universe.compare v v'
+ else if Universe.equal u v' && Universe.equal v u' then 0
+ else i
+ | ULub (u, v), ULub (u', v') | UWeak (u, v), UWeak (u', v') ->
+ let i = Level.compare u u' in
+ if Int.equal i 0 then Level.compare v v'
+ else if Level.equal u v' && Level.equal v u' then 0
+ else i
+ | ULe _, _ -> -1
+ | _, ULe _ -> 1
+ | UEq _, _ -> -1
+ | _, UEq _ -> 1
+ | ULub _, _ -> -1
+ | _, ULub _ -> 1
+ end)
+
+ include S
+
+ let add cst s =
+ if is_trivial cst then s
+ else add cst s
+
+ let pr_one = let open Pp in function
+ | ULe (u, v) -> Universe.pr u ++ str " <= " ++ Universe.pr v
+ | UEq (u, v) -> Universe.pr u ++ str " = " ++ Universe.pr v
+ | ULub (u, v) -> Level.pr u ++ str " /\\ " ++ Level.pr v
+ | UWeak (u, v) -> Level.pr u ++ str " ~ " ++ Level.pr v
+
+ let pr c =
+ let open Pp in
+ fold (fun cst pp_std ->
+ pp_std ++ pr_one cst ++ fnl ()) c (str "")
+
+ let equal x y =
+ x == y || equal x y
+
+ let subst_univs subst csts =
+ fold
+ (fun c -> Option.fold_right add (subst_univs subst c))
+ csts empty
+end
+
+type 'a accumulator = Set.t -> 'a -> 'a option
+type 'a constrained = 'a * Set.t
+
+type 'a constraint_function = 'a -> 'a -> Set.t -> Set.t
+
+let enforce_eq_instances_univs strict x y c =
+ let mk u v = if strict then ULub (u, v) else UEq (Universe.make u, Universe.make v) in
+ let ax = Instance.to_array x and ay = Instance.to_array y in
+ if Array.length ax != Array.length ay then
+ CErrors.anomaly Pp.(str "Invalid argument: enforce_eq_instances_univs called with" ++
+ str " instances of different lengths.");
+ CArray.fold_right2
+ (fun x y -> Set.add (mk x y))
+ ax ay c
+
+let to_constraints ~force_weak g s =
+ let invalid () =
+ raise (Invalid_argument "to_constraints: non-trivial algebraic constraint between universes")
+ in
+ let tr cst acc =
+ match cst with
+ | ULub (l, l') -> Constraint.add (l, Eq, l') acc
+ | UWeak (l, l') when force_weak -> Constraint.add (l, Eq, l') acc
+ | UWeak _-> acc
+ | ULe (l, l') ->
+ begin match Universe.level l, Universe.level l' with
+ | Some l, Some l' -> Constraint.add (l, Le, l') acc
+ | None, Some _ -> enforce_leq l l' acc
+ | _, None ->
+ if UGraph.check_leq g l l'
+ then acc
+ else invalid ()
+ end
+ | UEq (l, l') ->
+ begin match Universe.level l, Universe.level l' with
+ | Some l, Some l' -> Constraint.add (l, Eq, l') acc
+ | None, _ | _, None ->
+ if UGraph.check_eq g l l'
+ then acc
+ else invalid ()
+ end
+ in
+ Set.fold tr s Constraint.empty
+
+
+(** Variant of [eq_constr_univs_infer] taking kind-of-term functions,
+ to expose subterms of [m] and [n], arguments. *)
+let eq_constr_univs_infer_with kind1 kind2 univs fold m n accu =
+ (* spiwack: duplicates the code of [eq_constr_univs_infer] because I
+ haven't find a way to factor the code without destroying
+ pointer-equality optimisations in [eq_constr_univs_infer].
+ Pointer equality is not sufficient to ensure equality up to
+ [kind1,kind2], because [kind1] and [kind2] may be different,
+ typically evaluating [m] and [n] in different evar maps. *)
+ let cstrs = ref accu in
+ let eq_universes _ _ = UGraph.check_eq_instances univs in
+ let eq_sorts s1 s2 =
+ if Sorts.equal s1 s2 then true
+ else
+ let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
+ match fold (Set.singleton (UEq (u1, u2))) !cstrs with
+ | None -> false
+ | Some accu -> cstrs := accu; true
+ in
+ let rec eq_constr' nargs m n =
+ Constr.compare_head_gen_with kind1 kind2 eq_universes eq_sorts eq_constr' nargs m n
+ in
+ let res = Constr.compare_head_gen_with kind1 kind2 eq_universes eq_sorts eq_constr' 0 m n in
+ if res then Some !cstrs else None
diff --git a/engine/univProblem.mli b/engine/univProblem.mli
new file mode 100644
index 00000000..ffaebe15
--- /dev/null
+++ b/engine/univProblem.mli
@@ -0,0 +1,55 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* bool
+
+module Set : sig
+ include Set.S with type elt = t
+
+ val pr : t -> Pp.t
+
+ val subst_univs : universe_subst_fn -> t -> t
+end
+
+type 'a accumulator = Set.t -> 'a -> 'a option
+type 'a constrained = 'a * Set.t
+type 'a constraint_function = 'a -> 'a -> Set.t -> Set.t
+
+val enforce_eq_instances_univs : bool -> Instance.t constraint_function
+
+(** With [force_weak] UWeak constraints are turned into equalities,
+ otherwise they're forgotten. *)
+val to_constraints : force_weak:bool -> UGraph.t -> Set.t -> Constraint.t
+
+(** [eq_constr_univs_infer_With kind1 kind2 univs m n] is a variant of
+ {!eq_constr_univs_infer} taking kind-of-term functions, to expose
+ subterms of [m] and [n], arguments. *)
+val eq_constr_univs_infer_with :
+ (constr -> (constr, types, Sorts.t, Univ.Instance.t) kind_of_term) ->
+ (constr -> (constr, types, Sorts.t, Univ.Instance.t) kind_of_term) ->
+ UGraph.t -> 'a accumulator -> constr -> constr -> 'a -> 'a option
diff --git a/engine/univSubst.ml b/engine/univSubst.ml
new file mode 100644
index 00000000..2f59a3fa
--- /dev/null
+++ b/engine/univSubst.ml
@@ -0,0 +1,177 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* enforce_eq u v
+ | Le -> enforce_leq u v
+ | Lt -> enforce_leq (super u) v
+
+let subst_univs_level fn l =
+ try Some (fn l)
+ with Not_found -> None
+
+let subst_univs_constraint fn (u,d,v as c) cstrs =
+ let u' = subst_univs_level fn u in
+ let v' = subst_univs_level fn v in
+ match u', v' with
+ | None, None -> Constraint.add c cstrs
+ | Some u, None -> enforce_univ_constraint (u,d,Universe.make v) cstrs
+ | None, Some v -> enforce_univ_constraint (Universe.make u,d,v) cstrs
+ | Some u, Some v -> enforce_univ_constraint (u,d,v) cstrs
+
+let subst_univs_constraints subst csts =
+ Constraint.fold
+ (fun c cstrs -> subst_univs_constraint subst c cstrs)
+ csts Constraint.empty
+
+let level_subst_of f =
+ fun l ->
+ try let u = f l in
+ match Universe.level u with
+ | None -> l
+ | Some l -> l
+ with Not_found -> l
+
+let subst_univs_fn_constr f c =
+ let changed = ref false in
+ let fu = Univ.subst_univs_universe f in
+ let fi = Univ.Instance.subst_fn (level_subst_of f) in
+ let rec aux t =
+ match kind t with
+ | Sort (Sorts.Type u) ->
+ let u' = fu u in
+ if u' == u then t else
+ (changed := true; mkSort (Sorts.sort_of_univ u'))
+ | Const (c, u) ->
+ let u' = fi u in
+ if u' == u then t
+ else (changed := true; mkConstU (c, u'))
+ | Ind (i, u) ->
+ let u' = fi u in
+ if u' == u then t
+ else (changed := true; mkIndU (i, u'))
+ | Construct (c, u) ->
+ let u' = fi u in
+ if u' == u then t
+ else (changed := true; mkConstructU (c, u'))
+ | _ -> map aux t
+ in
+ let c' = aux c in
+ if !changed then c' else c
+
+let subst_univs_constr subst c =
+ if Univ.is_empty_subst subst then c
+ else
+ let f = Univ.make_subst subst in
+ subst_univs_fn_constr f c
+
+let subst_univs_constr =
+ if Flags.profile then
+ let subst_univs_constr_key = CProfile.declare_profile "subst_univs_constr" in
+ CProfile.profile2 subst_univs_constr_key subst_univs_constr
+ else subst_univs_constr
+
+let normalize_univ_variable ~find =
+ let rec aux cur =
+ let b = find cur in
+ let b' = subst_univs_universe aux b in
+ if Universe.equal b' b then b
+ else b'
+ in aux
+
+let normalize_univ_variable_opt_subst ectx =
+ let find l =
+ match Univ.LMap.find l ectx with
+ | Some b -> b
+ | None -> raise Not_found
+ in
+ normalize_univ_variable ~find
+
+let normalize_univ_variable_subst subst =
+ let find l = Univ.LMap.find l subst in
+ normalize_univ_variable ~find
+
+let normalize_universe_opt_subst subst =
+ let normlevel = normalize_univ_variable_opt_subst subst in
+ subst_univs_universe normlevel
+
+let normalize_universe_subst subst =
+ let normlevel = normalize_univ_variable_subst subst in
+ subst_univs_universe normlevel
+
+let normalize_opt_subst ctx =
+ let normalize = normalize_universe_opt_subst ctx in
+ Univ.LMap.mapi (fun u -> function
+ | None -> None
+ | Some v -> Some (normalize v)) ctx
+
+type universe_opt_subst = Universe.t option universe_map
+
+let subst_univs_fn_puniverses f (c, u as cu) =
+ let u' = Instance.subst_fn f u in
+ if u' == u then cu else (c, u')
+
+let nf_evars_and_universes_opt_subst f subst =
+ let subst = normalize_univ_variable_opt_subst subst in
+ let lsubst = level_subst_of subst in
+ let rec aux c =
+ match kind c with
+ | Evar (evk, args) ->
+ let args = Array.map aux args in
+ (match try f (evk, args) with Not_found -> None with
+ | None -> mkEvar (evk, args)
+ | Some c -> aux c)
+ | Const pu ->
+ let pu' = subst_univs_fn_puniverses lsubst pu in
+ if pu' == pu then c else mkConstU pu'
+ | Ind pu ->
+ let pu' = subst_univs_fn_puniverses lsubst pu in
+ if pu' == pu then c else mkIndU pu'
+ | Construct pu ->
+ let pu' = subst_univs_fn_puniverses lsubst pu in
+ if pu' == pu then c else mkConstructU pu'
+ | Sort (Type u) ->
+ let u' = Univ.subst_univs_universe subst u in
+ if u' == u then c else mkSort (sort_of_univ u')
+ | _ -> Constr.map aux c
+ in aux
+
+let make_opt_subst s =
+ fun x ->
+ (match Univ.LMap.find x s with
+ | Some u -> u
+ | None -> raise Not_found)
+
+let subst_opt_univs_constr s =
+ let f = make_opt_subst s in
+ subst_univs_fn_constr f
+
+let normalize_univ_variables ctx =
+ let ctx = normalize_opt_subst ctx in
+ let def, subst =
+ Univ.LMap.fold (fun u v (def, subst) ->
+ match v with
+ | 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 ()
+ | Some v -> str" := " ++ Univ.Universe.pr v
+
+let pr_universe_opt_subst = Univ.LMap.pr pr_universe_body
diff --git a/engine/univSubst.mli b/engine/univSubst.mli
new file mode 100644
index 00000000..e76d2533
--- /dev/null
+++ b/engine/univSubst.mli
@@ -0,0 +1,53 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* universe_level_subst_fn
+val subst_univs_constraints : universe_subst_fn -> Constraint.t -> Constraint.t
+
+val subst_univs_constr : universe_subst -> constr -> constr
+
+type universe_opt_subst = Universe.t option universe_map
+
+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 * universe_subst
+
+val normalize_univ_variable :
+ find:(Level.t -> Universe.t) ->
+ Level.t -> Universe.t
+
+val normalize_univ_variable_opt_subst : universe_opt_subst ->
+ (Level.t -> Universe.t)
+
+val normalize_univ_variable_subst : universe_subst ->
+ (Level.t -> Universe.t)
+
+val normalize_universe_opt_subst : universe_opt_subst ->
+ (Universe.t -> Universe.t)
+
+val normalize_universe_subst : universe_subst ->
+ (Universe.t -> Universe.t)
+
+val normalize_opt_subst : universe_opt_subst -> universe_opt_subst
+
+(** Full universes substitutions into terms *)
+
+val nf_evars_and_universes_opt_subst : (existential -> constr option) ->
+ universe_opt_subst -> constr -> constr
+
+(** Pretty-printing *)
+
+val pr_universe_opt_subst : universe_opt_subst -> Pp.t
diff --git a/engine/universes.ml b/engine/universes.ml
index fb64a642..ee966843 100644
--- a/engine/universes.ml
+++ b/engine/universes.ml
@@ -8,1129 +8,90 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Sorts
-open Util
-open Pp
-open Names
-open Constr
-open Environ
open Univ
-open Globnames
-open Nametab
-module UPairs = OrderedType.UnorderedPair(Univ.Level)
-module UPairSet = Set.Make (UPairs)
-
-let reference_of_level l = CAst.make @@
- match Level.name l with
- | Some (d, n as na) ->
- let qid =
- try Nametab.shortest_qualid_of_universe na
- with Not_found ->
- let name = Id.of_string_soft (string_of_int n) in
- Libnames.make_qualid d name
- in Libnames.Qualid qid
- | None -> Libnames.Ident Id.(of_string_soft (Level.to_string l))
-
-let pr_with_global_universes l = Libnames.pr_reference (reference_of_level l)
-
-(** Global universe information outside the kernel, to handle
- polymorphic universe names in sections that have to be discharged. *)
-
-let universe_map = (Summary.ref UnivIdMap.empty ~name:"global universe info" : bool Nametab.UnivIdMap.t ref)
-
-let add_global_universe u p =
- match Level.name u with
- | Some n -> universe_map := Nametab.UnivIdMap.add n p !universe_map
- | None -> ()
-
-let is_polymorphic l =
- match Level.name l with
- | Some n ->
- (try Nametab.UnivIdMap.find n !universe_map
- with Not_found -> false)
- | None -> false
-
-(** Local universe names of polymorphic references *)
-
-type universe_binders = Univ.Level.t Names.Id.Map.t
-
-let empty_binders = Id.Map.empty
-
-let universe_binders_table = Summary.ref Refmap.empty ~name:"universe binders"
-
-let universe_binders_of_global ref : universe_binders =
- try
- let l = Refmap.find ref !universe_binders_table in l
- with Not_found -> Names.Id.Map.empty
-
-let cache_ubinder (_,(ref,l)) =
- universe_binders_table := Refmap.add ref l !universe_binders_table
-
-let subst_ubinder (subst,(ref,l as orig)) =
- let ref' = fst (Globnames.subst_global subst ref) in
- if ref == ref' then orig else ref', l
-
-let discharge_ubinder (_,(ref,l)) =
- Some (Lib.discharge_global ref, l)
-
-let ubinder_obj : Globnames.global_reference * universe_binders -> Libobject.obj =
- let open Libobject in
- declare_object { (default_object "universe binder") with
- cache_function = cache_ubinder;
- load_function = (fun _ x -> cache_ubinder x);
- classify_function = (fun x -> Substitute x);
- subst_function = subst_ubinder;
- discharge_function = discharge_ubinder;
- rebuild_function = (fun x -> x); }
-
-let register_universe_binders ref ubinders =
- let open Names in
- (* Add the polymorphic (section) universes *)
- let ubinders = UnivIdMap.fold (fun lvl poly ubinders ->
- let qid = Nametab.shortest_qualid_of_universe lvl in
- let level = Level.make (fst lvl) (snd lvl) in
- if poly then Id.Map.add (snd (Libnames.repr_qualid qid)) level ubinders
- else ubinders)
- !universe_map ubinders
- in
- if not (Id.Map.is_empty ubinders)
- then Lib.add_anonymous_leaf (ubinder_obj (ref,ubinders))
-
-type univ_name_list = Misctypes.lname list
-
-let universe_binders_with_opt_names ref levels = function
- | None -> universe_binders_of_global ref
- | Some udecl ->
- if Int.equal(List.length levels) (List.length udecl)
- then
- List.fold_left2 (fun acc { CAst.v = na} lvl -> match na with
- | Anonymous -> acc
- | Name na -> Names.Id.Map.add na lvl acc)
- empty_binders udecl levels
- else
- CErrors.user_err ~hdr:"universe_binders_with_opt_names"
- Pp.(str "Universe instance should have length " ++ int (List.length levels))
-
-(* To disallow minimization to Set *)
-
-let set_minimization = ref true
-let is_set_minimization () = !set_minimization
-
-type universe_constraint =
+(** Deprecated *)
+
+(** UnivNames *)
+type universe_binders = UnivNames.universe_binders
+type univ_name_list = UnivNames.univ_name_list
+
+let pr_with_global_universes = UnivNames.pr_with_global_universes
+let reference_of_level = UnivNames.qualid_of_level
+
+let add_global_universe = UnivNames.add_global_universe
+
+let is_polymorphic = UnivNames.is_polymorphic
+
+let empty_binders = UnivNames.empty_binders
+
+let register_universe_binders = UnivNames.register_universe_binders
+let universe_binders_of_global = UnivNames.universe_binders_of_global
+
+let universe_binders_with_opt_names = UnivNames.universe_binders_with_opt_names
+
+(** UnivGen *)
+type universe_id = UnivGen.universe_id
+
+let set_remote_new_univ_id = UnivGen.set_remote_new_univ_id
+let new_univ_id = UnivGen.new_univ_id
+let new_univ_level = UnivGen.new_univ_level
+let new_univ = UnivGen.new_univ
+let new_Type = UnivGen.new_Type
+let new_Type_sort = UnivGen.new_Type_sort
+let new_global_univ = UnivGen.new_global_univ
+let new_sort_in_family = UnivGen.new_sort_in_family
+let fresh_instance_from_context = UnivGen.fresh_instance_from_context
+let fresh_instance_from = UnivGen.fresh_instance_from
+let fresh_sort_in_family = UnivGen.fresh_sort_in_family
+let fresh_constant_instance = UnivGen.fresh_constant_instance
+let fresh_inductive_instance = UnivGen.fresh_inductive_instance
+let fresh_constructor_instance = UnivGen.fresh_constructor_instance
+let fresh_global_instance = UnivGen.fresh_global_instance
+let fresh_global_or_constr_instance = UnivGen.fresh_global_or_constr_instance
+let fresh_universe_context_set_instance = UnivGen.fresh_universe_context_set_instance
+let global_of_constr = UnivGen.global_of_constr
+let constr_of_global_univ = UnivGen.constr_of_global_univ
+let extend_context = UnivGen.extend_context
+let constr_of_global = UnivGen.constr_of_global
+let constr_of_reference = UnivGen.constr_of_global
+let type_of_global = UnivGen.type_of_global
+
+(** UnivSubst *)
+
+let level_subst_of = UnivSubst.level_subst_of
+let subst_univs_constraints = UnivSubst.subst_univs_constraints
+let subst_univs_constr = UnivSubst.subst_univs_constr
+type universe_opt_subst = UnivSubst.universe_opt_subst
+let make_opt_subst = UnivSubst.make_opt_subst
+let subst_opt_univs_constr = UnivSubst.subst_opt_univs_constr
+let normalize_univ_variables = UnivSubst.normalize_univ_variables
+let normalize_univ_variable = UnivSubst.normalize_univ_variable
+let normalize_univ_variable_opt_subst = UnivSubst.normalize_univ_variable_opt_subst
+let normalize_univ_variable_subst = UnivSubst.normalize_univ_variable_subst
+let normalize_universe_opt_subst = UnivSubst.normalize_universe_opt_subst
+let normalize_universe_subst = UnivSubst.normalize_universe_subst
+let nf_evars_and_universes_opt_subst = UnivSubst.nf_evars_and_universes_opt_subst
+let pr_universe_opt_subst = UnivSubst.pr_universe_opt_subst
+
+(** UnivProblem *)
+
+type universe_constraint = UnivProblem.t =
| ULe of Universe.t * Universe.t
| UEq of Universe.t * Universe.t
| ULub of Level.t * Level.t
| UWeak of Level.t * Level.t
-module Constraints = struct
- module S = Set.Make(
- struct
- type t = universe_constraint
-
- let compare x y =
- match x, y with
- | ULe (u, v), ULe (u', v') ->
- let i = Universe.compare u u' in
- if Int.equal i 0 then Universe.compare v v'
- else i
- | UEq (u, v), UEq (u', v') ->
- let i = Universe.compare u u' in
- if Int.equal i 0 then Universe.compare v v'
- else if Universe.equal u v' && Universe.equal v u' then 0
- else i
- | ULub (u, v), ULub (u', v') | UWeak (u, v), UWeak (u', v') ->
- let i = Level.compare u u' in
- if Int.equal i 0 then Level.compare v v'
- else if Level.equal u v' && Level.equal v u' then 0
- else i
- | ULe _, _ -> -1
- | _, ULe _ -> 1
- | UEq _, _ -> -1
- | _, UEq _ -> 1
- | ULub _, _ -> -1
- | _, ULub _ -> 1
- end)
-
- include S
-
- let is_trivial = function
- | ULe (u, v) | UEq (u, v) -> Universe.equal u v
- | ULub (u, v) | UWeak (u, v) -> Level.equal u v
-
- let add cst s =
- if is_trivial cst then s
- else add cst s
-
- let pr_one = function
- | ULe (u, v) -> Universe.pr u ++ str " <= " ++ Universe.pr v
- | UEq (u, v) -> Universe.pr u ++ str " = " ++ Universe.pr v
- | ULub (u, v) -> Level.pr u ++ str " /\\ " ++ Level.pr v
- | UWeak (u, v) -> Level.pr u ++ str " ~ " ++ Level.pr v
-
- let pr c =
- fold (fun cst pp_std ->
- pp_std ++ pr_one cst ++ fnl ()) c (str "")
-
- let equal x y =
- x == y || equal x y
-
-end
-
-type universe_constraints = Constraints.t
-type 'a constraint_accumulator = universe_constraints -> 'a -> 'a option
-type 'a universe_constrained = 'a * universe_constraints
-
-type 'a universe_constraint_function = 'a -> 'a -> universe_constraints -> universe_constraints
-
-let enforce_eq_instances_univs strict x y c =
- let mk u v = if strict then ULub (u, v) else UEq (Universe.make u, Universe.make v) in
- let ax = Instance.to_array x and ay = Instance.to_array y in
- if Array.length ax != Array.length ay then
- CErrors.anomaly (Pp.str "Invalid argument: enforce_eq_instances_univs called with" ++
- Pp.str " instances of different lengths.");
- CArray.fold_right2
- (fun x y -> Constraints.add (mk x y))
- ax ay c
-
-let enforce_univ_constraint (u,d,v) =
- match d with
- | Eq -> enforce_eq u v
- | Le -> enforce_leq u v
- | Lt -> enforce_leq (super u) v
-
-let subst_univs_level fn l =
- try Some (fn l)
- with Not_found -> None
-
-let subst_univs_constraint fn (u,d,v as c) cstrs =
- let u' = subst_univs_level fn u in
- let v' = subst_univs_level fn v in
- match u', v' with
- | None, None -> Constraint.add c cstrs
- | Some u, None -> enforce_univ_constraint (u,d,Universe.make v) cstrs
- | None, Some v -> enforce_univ_constraint (Universe.make u,d,v) cstrs
- | Some u, Some v -> enforce_univ_constraint (u,d,v) cstrs
-
-let subst_univs_constraints subst csts =
- Constraint.fold
- (fun c cstrs -> subst_univs_constraint subst c cstrs)
- csts Constraint.empty
-
-let level_subst_of f =
- fun l ->
- try let u = f l in
- match Universe.level u with
- | None -> l
- | Some l -> l
- with Not_found -> l
-
-let subst_univs_universe_constraint fn = function
- | ULe (u, v) ->
- let u' = subst_univs_universe fn u and v' = subst_univs_universe fn v in
- if Universe.equal u' v' then None
- else Some (ULe (u',v'))
- | UEq (u, v) ->
- let u' = subst_univs_universe fn u and v' = subst_univs_universe fn v in
- if Universe.equal u' v' then None
- else Some (ULe (u',v'))
- | ULub (u, v) ->
- let u' = level_subst_of fn u and v' = level_subst_of fn v in
- if Level.equal u' v' then None
- else Some (ULub (u',v'))
- | UWeak (u, v) ->
- let u' = level_subst_of fn u and v' = level_subst_of fn v in
- if Level.equal u' v' then None
- else Some (UWeak (u',v'))
-
-let subst_univs_universe_constraints subst csts =
- Constraints.fold
- (fun c -> Option.fold_right Constraints.add (subst_univs_universe_constraint subst c))
- csts Constraints.empty
-
-let to_constraints ~force_weak g s =
- let invalid () =
- raise (Invalid_argument "to_constraints: non-trivial algebraic constraint between universes")
- in
- let tr cst acc =
- match cst with
- | ULub (l, l') -> Constraint.add (l, Eq, l') acc
- | UWeak (l, l') when force_weak -> Constraint.add (l, Eq, l') acc
- | UWeak _-> acc
- | ULe (l, l') ->
- begin match Universe.level l, Universe.level l' with
- | Some l, Some l' -> Constraint.add (l, Le, l') acc
- | None, Some _ -> enforce_leq l l' acc
- | _, None ->
- if UGraph.check_leq g l l'
- then acc
- else invalid ()
- end
- | UEq (l, l') ->
- begin match Universe.level l, Universe.level l' with
- | Some l, Some l' -> Constraint.add (l, Eq, l') acc
- | None, _ | _, None ->
- if UGraph.check_eq g l l'
- then acc
- else invalid ()
- end
- in
- Constraints.fold tr s Constraint.empty
-
-(** Variant of [eq_constr_univs_infer] taking kind-of-term functions,
- to expose subterms of [m] and [n], arguments. *)
-let eq_constr_univs_infer_with kind1 kind2 univs fold m n accu =
- (* spiwack: duplicates the code of [eq_constr_univs_infer] because I
- haven't find a way to factor the code without destroying
- pointer-equality optimisations in [eq_constr_univs_infer].
- Pointer equality is not sufficient to ensure equality up to
- [kind1,kind2], because [kind1] and [kind2] may be different,
- typically evaluating [m] and [n] in different evar maps. *)
- let cstrs = ref accu in
- let eq_universes _ _ = UGraph.check_eq_instances univs in
- let eq_sorts s1 s2 =
- if Sorts.equal s1 s2 then true
- else
- let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
- match fold (Constraints.singleton (UEq (u1, u2))) !cstrs with
- | None -> false
- | Some accu -> cstrs := accu; true
- in
- let rec eq_constr' nargs m n =
- Constr.compare_head_gen_with kind1 kind2 eq_universes eq_sorts eq_constr' nargs m n
- in
- let res = Constr.compare_head_gen_with kind1 kind2 eq_universes eq_sorts eq_constr' 0 m n in
- if res then Some !cstrs else None
-
-(* Generator of levels *)
-type universe_id = DirPath.t * int
-
-let new_univ_id, set_remote_new_univ_id =
- RemoteCounter.new_counter ~name:"Universes" 0 ~incr:((+) 1)
- ~build:(fun n -> Global.current_dirpath (), n)
-
-let new_univ_level () =
- let dp, id = new_univ_id () in
- Univ.Level.make dp id
-
-let fresh_level () = new_univ_level ()
-
-(* TODO: remove *)
-let new_univ dp = Univ.Universe.make (new_univ_level dp)
-let new_Type dp = mkType (new_univ dp)
-let new_Type_sort dp = Type (new_univ dp)
-
-let fresh_universe_instance ctx =
- let init _ = new_univ_level () in
- Instance.of_array (Array.init (AUContext.size ctx) init)
-
-let fresh_instance_from_context ctx =
- let inst = fresh_universe_instance ctx in
- let constraints = AUContext.instantiate inst ctx in
- inst, constraints
-
-let fresh_instance ctx =
- let ctx' = ref LSet.empty in
- let init _ =
- let u = new_univ_level () in
- ctx' := LSet.add u !ctx'; u
- in
- let inst = Instance.of_array (Array.init (AUContext.size ctx) init)
- in !ctx', inst
-
-let existing_instance ctx inst =
- let () =
- let len1 = Array.length (Instance.to_array inst)
- and len2 = AUContext.size ctx in
- if not (len1 == len2) then
- CErrors.user_err ~hdr:"Universes"
- (str "Polymorphic constant expected " ++ int len2 ++
- str" levels but was given " ++ int len1)
- else ()
- in LSet.empty, inst
-
-let fresh_instance_from ctx inst =
- let ctx', inst =
- match inst with
- | Some inst -> existing_instance ctx inst
- | None -> fresh_instance ctx
- in
- let constraints = AUContext.instantiate inst ctx in
- inst, (ctx', constraints)
-
-(** Fresh universe polymorphic construction *)
-
-let fresh_constant_instance env c inst =
- let cb = lookup_constant c env in
- match cb.Declarations.const_universes with
- | Declarations.Monomorphic_const _ -> ((c,Instance.empty), ContextSet.empty)
- | Declarations.Polymorphic_const auctx ->
- let inst, ctx =
- fresh_instance_from auctx inst
- in
- ((c, inst), ctx)
-
-let fresh_inductive_instance env ind inst =
- let mib, mip = Inductive.lookup_mind_specif env ind in
- match mib.Declarations.mind_universes with
- | Declarations.Monomorphic_ind _ ->
- ((ind,Instance.empty), ContextSet.empty)
- | Declarations.Polymorphic_ind uactx ->
- let inst, ctx = (fresh_instance_from uactx) inst in
- ((ind,inst), ctx)
- | Declarations.Cumulative_ind acumi ->
- let inst, ctx =
- fresh_instance_from (Univ.ACumulativityInfo.univ_context acumi) inst
- in ((ind,inst), ctx)
-
-let fresh_constructor_instance env (ind,i) inst =
- let mib, mip = Inductive.lookup_mind_specif env ind in
- match mib.Declarations.mind_universes with
- | Declarations.Monomorphic_ind _ -> (((ind,i),Instance.empty), ContextSet.empty)
- | Declarations.Polymorphic_ind auctx ->
- let inst, ctx = fresh_instance_from auctx inst in
- (((ind,i),inst), ctx)
- | Declarations.Cumulative_ind acumi ->
- let inst, ctx = fresh_instance_from (ACumulativityInfo.univ_context acumi) inst in
- (((ind,i),inst), ctx)
-
-open Globnames
-
-let fresh_global_instance ?names env gr =
- match gr with
- | VarRef id -> mkVar id, ContextSet.empty
- | ConstRef sp ->
- let c, ctx = fresh_constant_instance env sp names in
- mkConstU c, ctx
- | ConstructRef sp ->
- let c, ctx = fresh_constructor_instance env sp names in
- mkConstructU c, ctx
- | IndRef sp ->
- let c, ctx = fresh_inductive_instance env sp names in
- mkIndU c, ctx
-
-let fresh_constant_instance env sp =
- fresh_constant_instance env sp None
-
-let fresh_inductive_instance env sp =
- fresh_inductive_instance env sp None
-
-let fresh_constructor_instance env sp =
- fresh_constructor_instance env sp None
-
-let constr_of_global gr =
- let c, ctx = fresh_global_instance (Global.env ()) gr in
- if not (Univ.ContextSet.is_empty ctx) then
- if Univ.LSet.is_empty (Univ.ContextSet.levels ctx) then
- (* Should be an error as we might forget constraints, allow for now
- to make firstorder work with "using" clauses *)
- c
- else CErrors.user_err ~hdr:"constr_of_global"
- Pp.(str "globalization of polymorphic reference " ++ Nametab.pr_global_env Id.Set.empty gr ++
- str " would forget universes.")
- else c
-
-let constr_of_reference = constr_of_global
-
-let constr_of_global_univ (gr,u) =
- match gr with
- | VarRef id -> mkVar id
- | ConstRef sp -> mkConstU (sp,u)
- | ConstructRef sp -> mkConstructU (sp,u)
- | IndRef sp -> mkIndU (sp,u)
-
-let fresh_global_or_constr_instance env = function
- | IsConstr c -> c, ContextSet.empty
- | IsGlobal gr -> fresh_global_instance env gr
-
-let global_of_constr c =
- match kind c with
- | Const (c, u) -> ConstRef c, u
- | Ind (i, u) -> IndRef i, u
- | Construct (c, u) -> ConstructRef c, u
- | Var id -> VarRef id, Instance.empty
- | _ -> raise Not_found
-
-open Declarations
-
-let type_of_reference env r =
- match r with
- | VarRef id -> Environ.named_type id env, ContextSet.empty
- | ConstRef c ->
- let cb = Environ.lookup_constant c env in
- let ty = cb.const_type in
- begin
- match cb.const_universes with
- | Monomorphic_const _ -> ty, ContextSet.empty
- | Polymorphic_const auctx ->
- let inst, ctx = fresh_instance_from auctx None in
- Vars.subst_instance_constr inst ty, ctx
- end
- | IndRef ind ->
- let (mib, oib as specif) = Inductive.lookup_mind_specif env ind in
- begin
- match mib.mind_universes with
- | Monomorphic_ind _ ->
- let ty = Inductive.type_of_inductive env (specif, Univ.Instance.empty) in
- ty, ContextSet.empty
- | Polymorphic_ind auctx ->
- let inst, ctx = fresh_instance_from auctx None in
- let ty = Inductive.type_of_inductive env (specif, inst) in
- ty, ctx
- | Cumulative_ind cumi ->
- let inst, ctx =
- fresh_instance_from (ACumulativityInfo.univ_context cumi) None
- in
- let ty = Inductive.type_of_inductive env (specif, inst) in
- ty, ctx
- end
-
- | ConstructRef cstr ->
- let (mib,oib as specif) =
- Inductive.lookup_mind_specif env (inductive_of_constructor cstr)
- in
- begin
- match mib.mind_universes with
- | Monomorphic_ind _ ->
- Inductive.type_of_constructor (cstr,Instance.empty) specif, ContextSet.empty
- | Polymorphic_ind auctx ->
- let inst, ctx = fresh_instance_from auctx None in
- Inductive.type_of_constructor (cstr,inst) specif, ctx
- | Cumulative_ind cumi ->
- let inst, ctx =
- fresh_instance_from (ACumulativityInfo.univ_context cumi) None
- in
- Inductive.type_of_constructor (cstr,inst) specif, ctx
- end
-
-let type_of_global t = type_of_reference (Global.env ()) t
-
-let fresh_sort_in_family env = function
- | InProp -> Sorts.prop, ContextSet.empty
- | InSet -> Sorts.set, ContextSet.empty
- | InType ->
- let u = fresh_level () in
- Type (Univ.Universe.make u), ContextSet.singleton u
-
-let new_sort_in_family sf =
- fst (fresh_sort_in_family (Global.env ()) sf)
-
-let extend_context (a, ctx) (ctx') =
- (a, ContextSet.union ctx ctx')
-
-let new_global_univ () =
- let u = fresh_level () in
- (Univ.Universe.make u, ContextSet.singleton u)
-
-(** Simplification *)
-
-module LevelUnionFind = Unionfind.Make (Univ.LSet) (Univ.LMap)
-
-let add_list_map u t map =
- try
- let l = LMap.find u map in
- LMap.set u (t :: l) map
- with Not_found ->
- LMap.add u [t] map
-
-module UF = LevelUnionFind
-
-(** Precondition: flexible <= ctx *)
-let choose_canonical ctx flexible algs s =
- let global = LSet.diff s ctx in
- let flexible, rigid = LSet.partition flexible (LSet.inter s ctx) in
- (** If there is a global universe in the set, choose it *)
- if not (LSet.is_empty global) then
- let canon = LSet.choose global in
- canon, (LSet.remove canon global, rigid, flexible)
- else (** No global in the equivalence class, choose a rigid one *)
- if not (LSet.is_empty rigid) then
- let canon = LSet.choose rigid in
- canon, (global, LSet.remove canon rigid, flexible)
- else (** There are only flexible universes in the equivalence
- class, choose a non-algebraic. *)
- let algs, nonalgs = LSet.partition (fun x -> LSet.mem x algs) flexible in
- if not (LSet.is_empty nonalgs) then
- let canon = LSet.choose nonalgs in
- canon, (global, rigid, LSet.remove canon flexible)
- else
- let canon = LSet.choose algs in
- canon, (global, rigid, LSet.remove canon flexible)
-
-let subst_univs_fn_constr f c =
- let changed = ref false in
- let fu = Univ.subst_univs_universe f in
- let fi = Univ.Instance.subst_fn (level_subst_of f) in
- let rec aux t =
- match kind t with
- | Sort (Sorts.Type u) ->
- let u' = fu u in
- if u' == u then t else
- (changed := true; mkSort (Sorts.sort_of_univ u'))
- | Const (c, u) ->
- let u' = fi u in
- if u' == u then t
- else (changed := true; mkConstU (c, u'))
- | Ind (i, u) ->
- let u' = fi u in
- if u' == u then t
- else (changed := true; mkIndU (i, u'))
- | Construct (c, u) ->
- let u' = fi u in
- if u' == u then t
- else (changed := true; mkConstructU (c, u'))
- | _ -> map aux t
- in
- let c' = aux c in
- if !changed then c' else c
-
-let subst_univs_constr subst c =
- if Univ.is_empty_subst subst then c
- else
- let f = Univ.make_subst subst in
- subst_univs_fn_constr f c
-
-let subst_univs_constr =
- if Flags.profile then
- let subst_univs_constr_key = CProfile.declare_profile "subst_univs_constr" in
- CProfile.profile2 subst_univs_constr_key subst_univs_constr
- else subst_univs_constr
-
-let fresh_universe_context_set_instance ctx =
- if ContextSet.is_empty ctx then LMap.empty, ctx
- else
- let (univs, cst) = ContextSet.levels ctx, ContextSet.constraints ctx in
- let univs',subst = LSet.fold
- (fun u (univs',subst) ->
- let u' = fresh_level () in
- (LSet.add u' univs', LMap.add u u' subst))
- univs (LSet.empty, LMap.empty)
- in
- let cst' = subst_univs_level_constraints subst cst in
- subst, (univs', cst')
-
-let normalize_univ_variable ~find ~update =
- let rec aux cur =
- let b = find cur in
- let b' = subst_univs_universe aux b in
- if Universe.equal b' b then b
- else update cur b'
- in aux
-
-let normalize_univ_variable_opt_subst ectx =
- let find l =
- match Univ.LMap.find l !ectx with
- | Some b -> b
- | None -> raise Not_found
- in
- let update l b =
- assert (match Universe.level b with Some l' -> not (Level.equal l l') | None -> true);
- try ectx := Univ.LMap.add l (Some b) !ectx; b with Not_found -> assert false
- in normalize_univ_variable ~find ~update
-
-let normalize_univ_variable_subst subst =
- let find l = Univ.LMap.find l !subst in
- let update l b =
- assert (match Universe.level b with Some l' -> not (Level.equal l l') | None -> true);
- try subst := Univ.LMap.set l b !subst; b with Not_found -> assert false in
- normalize_univ_variable ~find ~update
-
-let normalize_universe_opt_subst subst =
- let normlevel = normalize_univ_variable_opt_subst subst in
- subst_univs_universe normlevel
-
-let normalize_universe_subst subst =
- let normlevel = normalize_univ_variable_subst subst in
- subst_univs_universe normlevel
-
-let normalize_opt_subst ctx =
- let ectx = ref ctx in
- let normalize = normalize_univ_variable_opt_subst ectx in
- let () =
- Univ.LMap.iter (fun u v ->
- if Option.is_empty v then ()
- else try ignore(normalize u) with Not_found -> assert(false)) ctx
- in !ectx
-
-type universe_opt_subst = Universe.t option universe_map
-
-let subst_univs_fn_puniverses f (c, u as cu) =
- let u' = Instance.subst_fn f u in
- if u' == u then cu else (c, u')
-
-let nf_evars_and_universes_opt_subst f subst =
- let subst = normalize_univ_variable_opt_subst (ref subst) in
- let lsubst = level_subst_of subst in
- let rec aux c =
- match kind c with
- | Evar (evk, args) ->
- let args = Array.map aux args in
- (match try f (evk, args) with Not_found -> None with
- | None -> mkEvar (evk, args)
- | Some c -> aux c)
- | Const pu ->
- let pu' = subst_univs_fn_puniverses lsubst pu in
- if pu' == pu then c else mkConstU pu'
- | Ind pu ->
- let pu' = subst_univs_fn_puniverses lsubst pu in
- if pu' == pu then c else mkIndU pu'
- | Construct pu ->
- let pu' = subst_univs_fn_puniverses lsubst pu in
- if pu' == pu then c else mkConstructU pu'
- | Sort (Type u) ->
- let u' = Univ.subst_univs_universe subst u in
- if u' == u then c else mkSort (sort_of_univ u')
- | _ -> Constr.map aux c
- in aux
-
-let make_opt_subst s =
- fun x ->
- (match Univ.LMap.find x s with
- | Some u -> u
- | None -> raise Not_found)
-
-let subst_opt_univs_constr s =
- let f = make_opt_subst s in
- subst_univs_fn_constr f
-
-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) ->
- 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
-
-let pr_universe_body = function
- | None -> mt ()
- | Some v -> str" := " ++ Univ.Universe.pr v
-
-let pr_universe_opt_subst = Univ.LMap.pr pr_universe_body
-
-let compare_constraint_type d d' =
- match d, d' with
- | Eq, Eq -> 0
- | Eq, _ -> -1
- | _, Eq -> 1
- | Le, Le -> 0
- | Le, _ -> -1
- | _, Le -> 1
- | Lt, Lt -> 0
-
-type lowermap = constraint_type LMap.t
-
-let lower_union =
- let merge k a b =
- match a, b with
- | Some _, None -> a
- | None, Some _ -> b
- | None, None -> None
- | Some l, Some r ->
- if compare_constraint_type l r >= 0 then a
- else b
- in LMap.merge merge
-
-let lower_add l c m =
- try let c' = LMap.find l m in
- if compare_constraint_type c c' > 0 then
- LMap.add l c m
- else m
- with Not_found -> LMap.add l c m
-
-let lower_of_list l =
- List.fold_left (fun acc (d,l) -> LMap.add l d acc) LMap.empty l
-
-exception Found of Level.t * lowermap
-let find_inst insts v =
- try LMap.iter (fun k (enf,alg,v',lower) ->
- if not alg && enf && Universe.equal v' v then raise (Found (k, lower)))
- insts; raise Not_found
- with Found (f,l) -> (f,l)
-
-let compute_lbound left =
- (** The universe variable was not fixed yet.
- Compute its level using its lower bound. *)
- let sup l lbound =
- match lbound with
- | None -> Some l
- | Some l' -> Some (Universe.sup l l')
- in
- List.fold_left (fun lbound (d, l) ->
- if d == Le (* l <= ?u *) then sup l lbound
- else (* l < ?u *)
- (assert (d == Lt);
- if not (Universe.level l == None) then
- sup (Universe.super l) lbound
- else None))
- None left
-
-let instantiate_with_lbound u lbound lower alg enforce (ctx, us, algs, insts, cstrs) =
- if enforce then
- let inst = Universe.make u in
- let cstrs' = enforce_leq lbound inst cstrs in
- (ctx, us, LSet.remove u algs,
- LMap.add u (enforce,alg,lbound,lower) insts, cstrs'),
- (enforce, alg, inst, lower)
- else (* Actually instantiate *)
- (Univ.LSet.remove u ctx, Univ.LMap.add u (Some lbound) us, algs,
- LMap.add u (enforce,alg,lbound,lower) insts, cstrs),
- (enforce, alg, lbound, lower)
-
-type constraints_map = (Univ.constraint_type * Univ.LMap.key) list Univ.LMap.t
-
-let _pr_constraints_map (cmap:constraints_map) =
- LMap.fold (fun l cstrs acc ->
- Level.pr l ++ str " => " ++
- prlist_with_sep spc (fun (d,r) -> pr_constraint_type d ++ Level.pr r) cstrs ++
- fnl () ++ acc)
- cmap (mt ())
-
-let remove_alg l (ctx, us, algs, insts, cstrs) =
- (ctx, us, LSet.remove l algs, insts, cstrs)
-
-let remove_lower u lower =
- let levels = Universe.levels u in
- LSet.fold (fun l acc -> LMap.remove l acc) levels lower
-
-let minimize_univ_variables ctx us algs left right cstrs =
- let left, lbounds =
- Univ.LMap.fold (fun r lower (left, lbounds as acc) ->
- if Univ.LMap.mem r us || not (Univ.LSet.mem r ctx) then acc
- else (* Fixed universe, just compute its glb for sharing *)
- let lbounds' =
- match compute_lbound (List.map (fun (d,l) -> d, Universe.make l) lower) with
- | None -> lbounds
- | Some lbound -> LMap.add r (true, false, lbound, lower_of_list lower)
- lbounds
- in (Univ.LMap.remove r left, lbounds'))
- left (left, Univ.LMap.empty)
- in
- let rec instance (ctx', us, algs, insts, cstrs as acc) u =
- let acc, left, lower =
- try
- let l = LMap.find u left in
- let acc, left, newlow, lower =
- List.fold_left
- (fun (acc, left', newlow, lower') (d, l) ->
- let acc', (enf,alg,l',lower) = aux acc l in
- let l' =
- if enf then Universe.make l
- else l'
- in acc', (d, l') :: left',
- lower_add l d newlow, lower_union lower lower')
- (acc, [], LMap.empty, LMap.empty) l
- in
- let not_lower (d,l) =
- (* We're checking if (d,l) is already implied by the lower
- constraints on some level u. If it represents l < u (d is Lt
- or d is Le and i > 0, the i < 0 case is impossible due to
- invariants of Univ), and the lower constraints only have l <=
- u then it is not implied. *)
- Univ.Universe.exists
- (fun (l,i) ->
- let d =
- if i == 0 then d
- else match d with
- | Le -> Lt
- | d -> d
- in
- try let d' = LMap.find l lower in
- (* If d is stronger than the already implied lower
- * constraints we must keep it. *)
- compare_constraint_type d d' > 0
- with Not_found ->
- (** No constraint existing on l *) true) l
- in
- let left = List.uniquize (List.filter not_lower left) in
- (acc, left, LMap.union newlow lower)
- with Not_found -> acc, [], LMap.empty
- and right =
- try Some (LMap.find u right)
- with Not_found -> None
- in
- let instantiate_lbound lbound =
- let alg = LSet.mem u algs in
- if alg then
- (* u is algebraic: we instantiate it with its lower bound, if any,
- or enforce the constraints if it is bounded from the top. *)
- let lower = remove_lower lbound lower in
- instantiate_with_lbound u lbound lower true false acc
- else (* u is non algebraic *)
- match Universe.level lbound with
- | Some l -> (* The lowerbound is directly a level *)
- (* u is not algebraic but has no upper bounds,
- we instantiate it with its lower bound if it is a
- different level, otherwise we keep it. *)
- let lower = LMap.remove l lower in
- if not (Level.equal l u) then
- (* Should check that u does not
- have upper constraints that are not already in right *)
- let acc' = remove_alg l acc in
- instantiate_with_lbound u lbound lower false false acc'
- else acc, (true, false, lbound, lower)
- | None ->
- try
- (* Another universe represents the same lower bound,
- we can share them with no harm. *)
- let can, lower = find_inst insts lbound in
- let lower = LMap.remove can lower in
- instantiate_with_lbound u (Universe.make can) lower false false acc
- with Not_found ->
- (* We set u as the canonical universe representing lbound *)
- instantiate_with_lbound u lbound lower false true acc
- in
- let acc' acc =
- match right with
- | None -> acc
- | Some cstrs ->
- let dangling = List.filter (fun (d, r) -> not (LMap.mem r us)) cstrs in
- if List.is_empty dangling then acc
- else
- let ((ctx', us, algs, insts, cstrs), (enf,_,inst,lower as b)) = acc in
- let cstrs' = List.fold_left (fun cstrs (d, r) ->
- if d == Univ.Le then
- enforce_leq inst (Universe.make r) cstrs
- else
- try let lev = Option.get (Universe.level inst) in
- Constraint.add (lev, d, r) cstrs
- with Option.IsNone -> failwith "")
- cstrs dangling
- in
- (ctx', us, algs, insts, cstrs'), b
- in
- if not (LSet.mem u ctx) then acc' (acc, (true, false, Universe.make u, lower))
- else
- let lbound = compute_lbound left in
- match lbound with
- | None -> (* Nothing to do *)
- acc' (acc, (true, false, Universe.make u, lower))
- | Some lbound ->
- try acc' (instantiate_lbound lbound)
- with Failure _ -> acc' (acc, (true, false, Universe.make u, lower))
- and aux (ctx', us, algs, seen, cstrs as acc) u =
- try acc, LMap.find u seen
- with Not_found -> instance acc u
- in
- LMap.fold (fun u v (ctx', us, algs, seen, cstrs as acc) ->
- if v == None then fst (aux acc u)
- else LSet.remove u ctx', us, LSet.remove u algs, seen, cstrs)
- us (ctx, us, algs, lbounds, cstrs)
-
-let normalize_context_set g ctx us algs weak =
- let (ctx, csts) = ContextSet.levels ctx, ContextSet.constraints ctx in
- let uf = UF.create () in
- (** Keep the Prop/Set <= i constraints separate for minimization *)
- let smallles, csts =
- Constraint.fold (fun (l,d,r as cstr) (smallles, noneqs) ->
- if d == Le then
- if Univ.Level.is_small l then
- if is_set_minimization () && LSet.mem r ctx then
- (Constraint.add cstr smallles, noneqs)
- else (smallles, noneqs)
- else if Level.is_small r then
- if Level.is_prop r then
- raise (Univ.UniverseInconsistency
- (Le,Universe.make l,Universe.make r,None))
- else (smallles, Constraint.add (l,Eq,r) noneqs)
- else (smallles, Constraint.add cstr noneqs)
- else (smallles, Constraint.add cstr noneqs))
- csts (Constraint.empty, Constraint.empty)
- in
- let csts =
- (* We first put constraints in a normal-form: all self-loops are collapsed
- to equalities. *)
- let g = Univ.LSet.fold (fun v g -> UGraph.add_universe v false g)
- ctx UGraph.initial_universes
- in
- let g =
- Univ.Constraint.fold
- (fun (l, d, r) g ->
- let g =
- if not (Level.is_small l || LSet.mem l ctx) then
- try UGraph.add_universe l false g
- with UGraph.AlreadyDeclared -> g
- else g
- in
- let g =
- if not (Level.is_small r || LSet.mem r ctx) then
- try UGraph.add_universe r false g
- with UGraph.AlreadyDeclared -> g
- else g
- in g) csts g
- in
- let g = Univ.Constraint.fold UGraph.enforce_constraint csts g in
- UGraph.constraints_of_universes g
- in
- let noneqs =
- Constraint.fold (fun (l,d,r as cstr) noneqs ->
- if d == Eq then (UF.union l r uf; noneqs)
- else (* We ignore the trivial Prop/Set <= i constraints. *)
- if d == Le && Univ.Level.is_small l then noneqs
- else if Univ.Level.is_prop l && d == Lt && Univ.Level.is_set r
- then noneqs
- else Constraint.add cstr noneqs)
- csts Constraint.empty
- in
- let noneqs = Constraint.union noneqs smallles in
- let partition = UF.partition uf in
- let flex x = LMap.mem x us in
- let ctx, us, eqs = List.fold_left (fun (ctx, us, cstrs) s ->
- let canon, (global, rigid, flexible) = choose_canonical ctx flex algs s in
- (* Add equalities for globals which can't be merged anymore. *)
- let cstrs = LSet.fold (fun g cst ->
- Constraint.add (canon, Univ.Eq, g) cst) global
- cstrs
- in
- (* Also add equalities for rigid variables *)
- let cstrs = LSet.fold (fun g cst ->
- Constraint.add (canon, Univ.Eq, g) cst) rigid
- cstrs
- in
- let canonu = Some (Universe.make canon) in
- let us = LSet.fold (fun f -> LMap.add f canonu) flexible us in
- (LSet.diff ctx flexible, us, cstrs))
- (ctx, us, Constraint.empty) partition
- in
- (* Process weak constraints: when one side is flexible and the 2
- universes are unrelated unify them. *)
- let ctx, us, g = UPairSet.fold (fun (u,v) (ctx, us, g as acc) ->
- let norm = let us = ref us in level_subst_of (normalize_univ_variable_opt_subst us) in
- let u = norm u and v = norm v in
- let set_to a b =
- (LSet.remove a ctx,
- LMap.add a (Some (Universe.make b)) us,
- UGraph.enforce_constraint (a,Eq,b) g)
- in
- if UGraph.check_constraint g (u,Le,v) || UGraph.check_constraint g (v,Le,u)
- then acc
- else
- if LMap.mem u us
- then set_to u v
- else if LMap.mem v us
- then set_to v u
- else acc)
- weak (ctx, us, g) in
- (* Noneqs is now in canonical form w.r.t. equality constraints,
- and contains only inequality constraints. *)
- let noneqs =
- let us = ref us in
- let norm = level_subst_of (normalize_univ_variable_opt_subst us) in
- Constraint.fold (fun (u,d,v) noneqs ->
- let u = norm u and v = norm v in
- if d != Lt && Level.equal u v then noneqs
- else Constraint.add (u,d,v) noneqs)
- noneqs Constraint.empty
- in
- (* Compute the left and right set of flexible variables, constraints
- mentionning other variables remain in noneqs. *)
- let noneqs, ucstrsl, ucstrsr =
- Constraint.fold (fun (l,d,r as cstr) (noneq, ucstrsl, ucstrsr) ->
- let lus = LMap.mem l us and rus = LMap.mem r us in
- let ucstrsl' =
- if lus then add_list_map l (d, r) ucstrsl
- else ucstrsl
- and ucstrsr' =
- add_list_map r (d, l) ucstrsr
- in
- let noneqs =
- if lus || rus then noneq
- else Constraint.add cstr noneq
- in (noneqs, ucstrsl', ucstrsr'))
- noneqs (Constraint.empty, LMap.empty, LMap.empty)
- in
- (* Now we construct the instantiation of each variable. *)
- let ctx', us, algs, inst, noneqs =
- minimize_univ_variables ctx us algs ucstrsr ucstrsl noneqs
- in
- let us = normalize_opt_subst us in
- (us, algs), (ctx', Constraint.union noneqs eqs)
-
-(* let normalize_conkey = CProfile.declare_profile "normalize_context_set" *)
-(* let normalize_context_set a b c = CProfile.profile3 normalize_conkey normalize_context_set a b c *)
-
-let is_trivial_leq (l,d,r) =
- Univ.Level.is_prop l && (d == Univ.Le || (d == Univ.Lt && Univ.Level.is_set r))
-
-(* Prop < i <-> Set+1 <= i <-> Set < i *)
-let translate_cstr (l,d,r as cstr) =
- if Level.equal Level.prop l && d == Univ.Lt && not (Level.equal Level.set r) then
- (Level.set, d, r)
- else cstr
-
-let refresh_constraints univs (ctx, cstrs) =
- let cstrs', univs' =
- Univ.Constraint.fold (fun c (cstrs', univs as acc) ->
- let c = translate_cstr c in
- if is_trivial_leq c then acc
- else (Univ.Constraint.add c cstrs', UGraph.enforce_constraint c univs))
- cstrs (Univ.Constraint.empty, univs)
- in ((ctx, cstrs'), univs')
-
-
-(**********************************************************************)
-(* Tools for sort-polymorphic inductive types *)
-
-(* Miscellaneous functions to remove or test local univ assumed to
- occur only in the le constraints *)
-
-(*
- Solve a system of universe constraint of the form
-
- u_s11, ..., u_s1p1, w1 <= u1
- ...
- u_sn1, ..., u_snpn, wn <= un
-
-where
-
- - the ui (1 <= i <= n) are universe variables,
- - the sjk select subsets of the ui for each equations,
- - the wi are arbitrary complex universes that do not mention the ui.
-*)
+module Constraints = UnivProblem.Set
+type 'a constraint_accumulator = 'a UnivProblem.accumulator
+type 'a universe_constrained = 'a UnivProblem.constrained
+type 'a universe_constraint_function = 'a UnivProblem.constraint_function
+let subst_univs_universe_constraints = UnivProblem.Set.subst_univs
+let enforce_eq_instances_univs = UnivProblem.enforce_eq_instances_univs
+let to_constraints = UnivProblem.to_constraints
+let eq_constr_univs_infer_with = UnivProblem.eq_constr_univs_infer_with
-let is_direct_sort_constraint s v = match s with
- | Some u -> univ_level_mem u v
- | None -> false
+(** UnivMinim *)
+module UPairSet = UnivMinim.UPairSet
-let solve_constraints_system levels level_bounds level_min =
- let open Univ in
- let levels =
- Array.mapi (fun i o ->
- match o with
- | Some u ->
- (match Universe.level u with
- | Some u -> Some u
- | _ -> level_bounds.(i) <- Universe.sup level_bounds.(i) u; None)
- | None -> None)
- levels in
- let v = Array.copy level_bounds in
- let nind = Array.length v in
- let clos = Array.map (fun _ -> Int.Set.empty) levels in
- (* First compute the transitive closure of the levels dependencies *)
- for i=0 to nind-1 do
- for j=0 to nind-1 do
- if not (Int.equal i j) && is_direct_sort_constraint levels.(j) v.(i) then
- clos.(i) <- Int.Set.add j clos.(i);
- done;
- done;
- let rec closure () =
- let continue = ref false in
- Array.iteri (fun i deps ->
- let deps' =
- Int.Set.fold (fun j acc -> Int.Set.union acc clos.(j)) deps deps
- in
- if Int.Set.equal deps deps' then ()
- else (clos.(i) <- deps'; continue := true))
- clos;
- if !continue then closure ()
- else ()
- in
- closure ();
- for i=0 to nind-1 do
- for j=0 to nind-1 do
- if not (Int.equal i j) && Int.Set.mem j clos.(i) then
- (v.(i) <- Universe.sup v.(i) level_bounds.(j));
- done;
- done;
- v
+let normalize_context_set = UnivMinim.normalize_context_set
diff --git a/engine/universes.mli b/engine/universes.mli
index 4823c574..ad937471 100644
--- a/engine/universes.mli
+++ b/engine/universes.mli
@@ -8,227 +8,231 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Util
open Names
open Constr
open Environ
open Univ
-(** Unordered pairs of universe levels (ie (u,v) = (v,u)) *)
-module UPairSet : CSet.S with type elt = (Level.t * Level.t)
+(** ************************************** *)
+(** This entire module is deprecated. **** *)
+(** ************************************** *)
+[@@@ocaml.warning "-3"]
-val set_minimization : bool ref
-val is_set_minimization : unit -> bool
-
-(** Universes *)
+(** ****** Deprecated: moved to [UnivNames] *)
val pr_with_global_universes : Level.t -> Pp.t
-val reference_of_level : Level.t -> Libnames.reference
+[@@ocaml.deprecated "Use [UnivNames.pr_with_global_universes]"]
+val reference_of_level : Level.t -> Libnames.qualid
+[@@ocaml.deprecated "Use [UnivNames.qualid_of_level]"]
-(** Global universe information outside the kernel, to handle
- polymorphic universes in sections that have to be discharged. *)
val add_global_universe : Level.t -> Decl_kinds.polymorphic -> unit
+[@@ocaml.deprecated "Use [UnivNames.add_global_universe]"]
val is_polymorphic : Level.t -> bool
+[@@ocaml.deprecated "Use [UnivNames.is_polymorphic]"]
-(** Local universe name <-> level mapping *)
-
-type universe_binders = Univ.Level.t Names.Id.Map.t
+type universe_binders = UnivNames.universe_binders
+[@@ocaml.deprecated "Use [UnivNames.universe_binders]"]
val empty_binders : universe_binders
+[@@ocaml.deprecated "Use [UnivNames.empty_binders]"]
val register_universe_binders : Globnames.global_reference -> universe_binders -> unit
+[@@ocaml.deprecated "Use [UnivNames.register_universe_binders]"]
val universe_binders_of_global : Globnames.global_reference -> universe_binders
+[@@ocaml.deprecated "Use [UnivNames.universe_binders_of_global]"]
-type univ_name_list = Misctypes.lname list
-
-(** [universe_binders_with_opt_names ref u l]
+type univ_name_list = UnivNames.univ_name_list
+[@@ocaml.deprecated "Use [UnivNames.univ_name_list]"]
- If [l] is [Some univs] return the universe binders naming the levels of [u] by [univs] (skipping Anonymous).
- May error if the lengths mismatch.
-
- Otherwise return [universe_binders_of_global ref]. *)
val universe_binders_with_opt_names : Globnames.global_reference ->
Univ.Level.t list -> univ_name_list option -> universe_binders
+[@@ocaml.deprecated "Use [UnivNames.universe_binders_with_opt_names]"]
-(** The global universe counter *)
-type universe_id = DirPath.t * int
+(** ****** Deprecated: moved to [UnivGen] *)
-val set_remote_new_univ_id : universe_id RemoteCounter.installer
+type universe_id = UnivGen.universe_id
+[@@ocaml.deprecated "Use [UnivGen.universe_id]"]
-(** Side-effecting functions creating new universe levels. *)
+val set_remote_new_univ_id : universe_id RemoteCounter.installer
+[@@ocaml.deprecated "Use [UnivGen.set_remote_new_univ_id]"]
val new_univ_id : unit -> universe_id
+[@@ocaml.deprecated "Use [UnivGen.new_univ_id]"]
+
val new_univ_level : unit -> Level.t
+[@@ocaml.deprecated "Use [UnivGen.new_univ_level]"]
+
val new_univ : unit -> Universe.t
+[@@ocaml.deprecated "Use [UnivGen.new_univ]"]
+
val new_Type : unit -> types
+[@@ocaml.deprecated "Use [UnivGen.new_Type]"]
+
val new_Type_sort : unit -> Sorts.t
+[@@ocaml.deprecated "Use [UnivGen.new_Type_sort]"]
val new_global_univ : unit -> Universe.t in_universe_context_set
-val new_sort_in_family : Sorts.family -> Sorts.t
-
-(** {6 Constraints for type inference}
-
- When doing conversion of universes, not only do we have =/<= constraints but
- also Lub constraints which correspond to unification of two levels which might
- not be necessary if unfolding is performed.
-
- UWeak constraints come from irrelevant universes in cumulative polymorphism.
-*)
-
-type universe_constraint =
- | ULe of Universe.t * Universe.t
- | UEq of Universe.t * Universe.t
- | ULub of Level.t * Level.t
- | UWeak of Level.t * Level.t
-
-module Constraints : sig
- include Set.S with type elt = universe_constraint
-
- val is_trivial : universe_constraint -> bool
-
- val pr : t -> Pp.t
-end
-
-type universe_constraints = Constraints.t
-[@@ocaml.deprecated "Use Constraints.t"]
-
-type 'a constraint_accumulator = Constraints.t -> 'a -> 'a option
-type 'a universe_constrained = 'a * Constraints.t
-type 'a universe_constraint_function = 'a -> 'a -> Constraints.t -> Constraints.t
+[@@ocaml.deprecated "Use [UnivGen.new_global_univ]"]
-val subst_univs_universe_constraints : universe_subst_fn ->
- Constraints.t -> Constraints.t
-
-val enforce_eq_instances_univs : bool -> Instance.t universe_constraint_function
-
-(** With [force_weak] UWeak constraints are turned into equalities,
- otherwise they're forgotten. *)
-val to_constraints : force_weak:bool -> UGraph.t -> Constraints.t -> Constraint.t
-
-(** [eq_constr_univs_infer_With kind1 kind2 univs m n] is a variant of
- {!eq_constr_univs_infer} taking kind-of-term functions, to expose
- subterms of [m] and [n], arguments. *)
-val eq_constr_univs_infer_with :
- (constr -> (constr, types, Sorts.t, Univ.Instance.t) kind_of_term) ->
- (constr -> (constr, types, Sorts.t, Univ.Instance.t) kind_of_term) ->
- UGraph.t -> 'a constraint_accumulator -> constr -> constr -> 'a -> 'a option
-
-(** Build a fresh instance for a given context, its associated substitution and
- the instantiated constraints. *)
+val new_sort_in_family : Sorts.family -> Sorts.t
+[@@ocaml.deprecated "Use [UnivGen.new_sort_in_family]"]
-val fresh_instance_from_context : AUContext.t ->
+val fresh_instance_from_context : AUContext.t ->
Instance.t constrained
+[@@ocaml.deprecated "Use [UnivGen.fresh_instance_from_context]"]
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]"]
+
val fresh_constant_instance : env -> Constant.t ->
pconstant in_universe_context_set
+[@@ocaml.deprecated "Use [UnivGen.fresh_constant_instance]"]
+
val fresh_inductive_instance : env -> inductive ->
pinductive in_universe_context_set
+[@@ocaml.deprecated "Use [UnivGen.fresh_inductive_instance]"]
+
val fresh_constructor_instance : env -> constructor ->
pconstructor in_universe_context_set
+[@@ocaml.deprecated "Use [UnivGen.fresh_constructor_instance]"]
-val fresh_global_instance : ?names:Univ.Instance.t -> env -> Globnames.global_reference ->
+val fresh_global_instance : ?names:Univ.Instance.t -> env -> Globnames.global_reference ->
constr in_universe_context_set
+[@@ocaml.deprecated "Use [UnivGen.fresh_global_instance]"]
-val fresh_global_or_constr_instance : env -> Globnames.global_reference_or_constr ->
+val fresh_global_or_constr_instance : env -> Globnames.global_reference_or_constr ->
constr in_universe_context_set
+[@@ocaml.deprecated "Use [UnivGen.fresh_global_or_constr_instance]"]
-(** Get fresh variables for the universe context.
- Useful to make tactics that manipulate constrs in universe contexts polymorphic. *)
-val fresh_universe_context_set_instance : ContextSet.t ->
+val fresh_universe_context_set_instance : ContextSet.t ->
universe_level_subst * ContextSet.t
+[@@ocaml.deprecated "Use [UnivGen.fresh_universe_context_set_instance]"]
-(** Raises [Not_found] if not a global reference. *)
val global_of_constr : constr -> Globnames.global_reference puniverses
+[@@ocaml.deprecated "Use [UnivGen.global_of_constr]"]
val constr_of_global_univ : Globnames.global_reference puniverses -> constr
+[@@ocaml.deprecated "Use [UnivGen.constr_of_global_univ]"]
-val extend_context : 'a in_universe_context_set -> ContextSet.t ->
+val extend_context : 'a in_universe_context_set -> ContextSet.t ->
'a in_universe_context_set
+[@@ocaml.deprecated "Use [UnivGen.extend_context]"]
-(** Simplification and pruning of constraints:
- [normalize_context_set ctx us]
+val constr_of_global : Globnames.global_reference -> constr
+[@@ocaml.deprecated "Use [UnivGen.constr_of_global]"]
- - Instantiate the variables in [us] with their most precise
- universe levels respecting the constraints.
+val constr_of_reference : Globnames.global_reference -> constr
+[@@ocaml.deprecated "Use [UnivGen.constr_of_global]"]
- - Normalizes the context [ctx] w.r.t. equality constraints,
- choosing a canonical universe in each equivalence class
- (a global one if there is one) and transitively saturate
- the constraints w.r.t to the equalities. *)
+val type_of_global : Globnames.global_reference -> types in_universe_context_set
+[@@ocaml.deprecated "Use [UnivGen.type_of_global]"]
-module UF : Unionfind.PartitionSig with type elt = Level.t
+(** ****** Deprecated: moved to [UnivSubst] *)
val level_subst_of : universe_subst_fn -> universe_level_subst_fn
+[@@ocaml.deprecated "Use [UnivSubst.level_subst_of]"]
+
val subst_univs_constraints : universe_subst_fn -> Constraint.t -> Constraint.t
+[@@ocaml.deprecated "Use [UnivSubst.subst_univs_constraints]"]
val subst_univs_constr : universe_subst -> constr -> constr
+[@@ocaml.deprecated "Use [UnivSubst.subst_univs_constr]"]
-type universe_opt_subst = Universe.t option universe_map
+type universe_opt_subst = UnivSubst.universe_opt_subst
+[@@ocaml.deprecated "Use [UnivSubst.universe_opt_subst]"]
val make_opt_subst : universe_opt_subst -> universe_subst_fn
+[@@ocaml.deprecated "Use [UnivSubst.make_opt_subst]"]
val subst_opt_univs_constr : universe_opt_subst -> constr -> constr
+[@@ocaml.deprecated "Use [UnivSubst.subst_opt_univs_constr]"]
-val normalize_context_set : UGraph.t -> ContextSet.t ->
- universe_opt_subst (* The defined and undefined variables *) ->
- LSet.t (* univ variables that can be substituted by algebraics *) ->
- UPairSet.t (* weak equality constraints *) ->
- (universe_opt_subst * LSet.t) in_universe_context_set
+val normalize_univ_variables : universe_opt_subst ->
+ universe_opt_subst * LSet.t * universe_subst
+[@@ocaml.deprecated "Use [UnivSubst.normalize_univ_variables]"]
-val normalize_univ_variables : universe_opt_subst ->
- universe_opt_subst * LSet.t * LSet.t * universe_subst
-
-val normalize_univ_variable :
+val normalize_univ_variable :
find:(Level.t -> Universe.t) ->
- update:(Level.t -> Universe.t -> Universe.t) ->
Level.t -> Universe.t
+[@@ocaml.deprecated "Use [UnivSubst.normalize_univ_variable]"]
-val normalize_univ_variable_opt_subst : universe_opt_subst ref ->
+val normalize_univ_variable_opt_subst : universe_opt_subst ->
(Level.t -> Universe.t)
+[@@ocaml.deprecated "Use [UnivSubst.normalize_univ_variable_opt_subst]"]
-val normalize_univ_variable_subst : universe_subst ref ->
+val normalize_univ_variable_subst : universe_subst ->
(Level.t -> Universe.t)
+[@@ocaml.deprecated "Use [UnivSubst.normalize_univ_variable_subst]"]
-val normalize_universe_opt_subst : universe_opt_subst ref ->
+val normalize_universe_opt_subst : universe_opt_subst ->
(Universe.t -> Universe.t)
+[@@ocaml.deprecated "Use [UnivSubst.normalize_universe_opt_subst]"]
-val normalize_universe_subst : universe_subst ref ->
+val normalize_universe_subst : universe_subst ->
(Universe.t -> Universe.t)
+[@@ocaml.deprecated "Use [UnivSubst.normalize_universe_subst]"]
-(** Create a fresh global in the global environment, without side effects.
- BEWARE: this raises an ANOMALY on polymorphic constants/inductives:
- the constraints should be properly added to an evd.
- See Evd.fresh_global, Evarutil.new_global, and pf_constr_of_global for
- the proper way to get a fresh copy of a global reference. *)
-val constr_of_global : Globnames.global_reference -> constr
+val nf_evars_and_universes_opt_subst : (existential -> constr option) ->
+ universe_opt_subst -> constr -> constr
+[@@ocaml.deprecated "Use [UnivSubst.nf_evars_and_universes_opt_subst]"]
-(** ** DEPRECATED ** synonym of [constr_of_global] *)
-val constr_of_reference : Globnames.global_reference -> constr
-[@@ocaml.deprecated "synonym of [constr_of_global]"]
+val pr_universe_opt_subst : universe_opt_subst -> Pp.t
+[@@ocaml.deprecated "Use [UnivSubst.pr_universe_opt_subst]"]
-(** Returns the type of the global reference, by creating a fresh instance of polymorphic
- references and computing their instantiated universe context. (side-effect on the
- universe counter, use with care). *)
-val type_of_global : Globnames.global_reference -> types in_universe_context_set
+(** ****** Deprecated: moved to [UnivProblem] *)
-(** Full universes substitutions into terms *)
+type universe_constraint = UnivProblem.t =
+ | ULe of Universe.t * Universe.t [@ocaml.deprecated "Use [UnivProblem.ULe]"]
+ | UEq of Universe.t * Universe.t [@ocaml.deprecated "Use [UnivProblem.UEq]"]
+ | ULub of Level.t * Level.t [@ocaml.deprecated "Use [UnivProblem.ULub]"]
+ | UWeak of Level.t * Level.t [@ocaml.deprecated "Use [UnivProblem.UWeak]"]
+[@@ocaml.deprecated "Use [UnivProblem.t]"]
-val nf_evars_and_universes_opt_subst : (existential -> constr option) ->
- universe_opt_subst -> constr -> constr
+module Constraints = UnivProblem.Set
+[@@ocaml.deprecated "Use [UnivProblem.Set]"]
-val refresh_constraints : UGraph.t -> ContextSet.t -> ContextSet.t * UGraph.t
+type 'a constraint_accumulator = 'a UnivProblem.accumulator
+[@@ocaml.deprecated "Use [UnivProblem.accumulator]"]
+type 'a universe_constrained = 'a UnivProblem.constrained
+[@@ocaml.deprecated "Use [UnivProblem.constrained]"]
+type 'a universe_constraint_function = 'a UnivProblem.constraint_function
+[@@ocaml.deprecated "Use [UnivProblem.constraint_function]"]
-(** Pretty-printing *)
+val subst_univs_universe_constraints : universe_subst_fn ->
+ Constraints.t -> Constraints.t
+[@@ocaml.deprecated "Use [UnivProblem.Set.subst_univs]"]
-val pr_universe_opt_subst : universe_opt_subst -> Pp.t
+val enforce_eq_instances_univs : bool -> Instance.t universe_constraint_function
+[@@ocaml.deprecated "Use [UnivProblem.enforce_eq_instances_univs]"]
-(** {6 Support for template polymorphism } *)
+(** With [force_weak] UWeak constraints are turned into equalities,
+ otherwise they're forgotten. *)
+val to_constraints : force_weak:bool -> UGraph.t -> Constraints.t -> Constraint.t
+[@@ocaml.deprecated "Use [UnivProblem.to_constraints]"]
-val solve_constraints_system : Universe.t option array -> Universe.t array -> Universe.t array ->
- Universe.t array
+(** [eq_constr_univs_infer_With kind1 kind2 univs m n] is a variant of
+ {!eq_constr_univs_infer} taking kind-of-term functions, to expose
+ subterms of [m] and [n], arguments. *)
+val eq_constr_univs_infer_with :
+ (constr -> (constr, types, Sorts.t, Univ.Instance.t) kind_of_term) ->
+ (constr -> (constr, types, Sorts.t, Univ.Instance.t) kind_of_term) ->
+ UGraph.t -> 'a constraint_accumulator -> constr -> constr -> 'a -> 'a option
+[@@ocaml.deprecated "Use [UnivProblem.eq_constr_univs_infer_with]"]
+
+(** ****** Deprecated: moved to [UnivMinim] *)
+
+module UPairSet = UnivMinim.UPairSet
+[@@ocaml.deprecated "Use [UnivMinim.UPairSet]"]
+
+val normalize_context_set : UGraph.t -> ContextSet.t ->
+ universe_opt_subst (* The defined and undefined variables *) ->
+ LSet.t (* univ variables that can be substituted by algebraics *) ->
+ UPairSet.t (* weak equality constraints *) ->
+ (universe_opt_subst * LSet.t) in_universe_context_set
+[@@ocaml.deprecated "Use [UnivMinim.normalize_context_set]"]
diff --git a/engine/univops.ml b/engine/univops.ml
index 76dbaa25..7f9672f8 100644
--- a/engine/univops.ml
+++ b/engine/univops.ml
@@ -11,103 +11,27 @@
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
| _ -> Constr.fold aux s c
in aux LSet.empty c
-type graphnode = {
- mutable up : constraint_type LMap.t;
- mutable visited : bool
-}
-
-let merge_types d d0 =
- match d, d0 with
- | _, Lt | Lt, _ -> Lt
- | Le, _ | _, Le -> Le
- | Eq, Eq -> Eq
-
-let merge_up d b up =
- let find = try Some (LMap.find b up) with Not_found -> None in
- match find with
- | Some d0 ->
- let d = merge_types d d0 in
- if d == d0 then up else LMap.add b d up
- | None -> LMap.add b d up
-
-let add_up a d b graph =
- let node, graph =
- try LMap.find a graph, graph
- with Not_found ->
- let node = { up = LMap.empty; visited = false } in
- node, LMap.add a node graph
- in
- node.up <- merge_up d b node.up;
- graph
-
-(* for each node transitive close until you find a non removable, discard the rest *)
-let transitive_close removable graph =
- let rec do_node a node =
- if not node.visited
- then
- let keepup =
- LMap.fold (fun b d keepup ->
- if not (LSet.mem b removable)
- then merge_up d b keepup
- else
- begin
- match LMap.find b graph with
- | bnode ->
- do_node b bnode;
- LMap.fold (fun k d' keepup ->
- merge_up (merge_types d d') k keepup)
- bnode.up keepup
- | exception Not_found -> keepup
- end
- )
- node.up LMap.empty
- in
- node.up <- keepup;
- node.visited <- true
- in
- LMap.iter do_node graph
-
-let restrict_universe_context (univs,csts) keep =
- let removable = LSet.diff univs keep in
- let (csts, rem) =
- Constraint.fold (fun (a,d,b as cst) (csts, rem) ->
- if LSet.mem a removable || LSet.mem b removable
- then (csts, add_up a d b rem)
- else (Constraint.add cst csts, rem))
- csts (Constraint.empty, LMap.empty)
- in
- transitive_close removable rem;
- let csts =
- LMap.fold (fun a node csts ->
- if LSet.mem a removable
- then csts
- else
- LMap.fold (fun b d csts -> Constraint.add (a,d,b) csts)
- node.up csts)
- rem csts
- in
+let restrict_universe_context (univs, csts) keep =
+ let removed = LSet.diff univs keep in
+ if LSet.is_empty removed then univs, csts
+ else
+ let allunivs = Constraint.fold (fun (u,_,v) all -> LSet.add u (LSet.add v all)) csts univs in
+ let g = UGraph.empty_universes in
+ let g = LSet.fold UGraph.add_universe_unconstrained allunivs g in
+ let g = UGraph.merge_constraints csts g in
+ let allkept = LSet.diff allunivs removed in
+ let csts = UGraph.constraints_for ~kept:allkept g in
(LSet.inter univs keep, csts)
diff --git a/engine/univops.mli b/engine/univops.mli
index d1585414..57a53597 100644
--- a/engine/univops.mli
+++ b/engine/univops.mli
@@ -11,8 +11,11 @@
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
-(** Shrink a universe context to a restricted set of variables *)
+(** [restrict_universe_context (univs,csts) keep] restricts [univs] to
+ the universes in [keep]. The constraints [csts] are adjusted so
+ that transitive constraints between remaining universes (those in
+ [keep] and those not in [univs]) are preserved. *)
val restrict_universe_context : ContextSet.t -> LSet.t -> ContextSet.t
diff --git a/grammar/q_util.mli b/grammar/q_util.mli
index 323a1235..f3af318b 100644
--- a/grammar/q_util.mli
+++ b/grammar/q_util.mli
@@ -48,3 +48,5 @@ val mlexpr_of_prod_entry_key : (string -> MLast.expr) -> user_symbol -> MLast.ex
val type_of_user_symbol : user_symbol -> argument_type
val parse_user_entry : string -> string -> user_symbol
+
+val mlexpr_of_symbol : user_symbol -> MLast.expr
diff --git a/grammar/q_util.mlp b/grammar/q_util.mlp
index 6cdd2ec1..0e2bf55d 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, _) ->
@@ -128,3 +128,17 @@ let rec parse_user_entry s sep =
let s = match s with "hyp" -> "var" | _ -> s in
check_separator sep;
Uentry s
+
+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$ >>
+| Ulist0 s -> <:expr< Extend.TUlist0 $mlexpr_of_symbol s$ >>
+| Ulist0sep (s,sep) -> <:expr< Extend.TUlist0sep $mlexpr_of_symbol s$ $str:sep$ >>
+| Uopt s -> <:expr< Extend.TUopt $mlexpr_of_symbol s$ >>
+| Uentry e ->
+ let wit = <:expr< $lid:"wit_"^e$ >> in
+ <:expr< Extend.TUentry (Genarg.get_arg_tag $wit$) >>
+| Uentryl (e, l) ->
+ assert (e = "tactic");
+ let wit = <:expr< $lid:"wit_"^e$ >> in
+ <:expr< Extend.TUentryl (Genarg.get_arg_tag $wit$) $mlexpr_of_int l$>>
diff --git a/grammar/tacextend.mlp b/grammar/tacextend.mlp
index 525be643..5943600b 100644
--- a/grammar/tacextend.mlp
+++ b/grammar/tacextend.mlp
@@ -8,6 +8,8 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+(** WARNING: this file is deprecated; consider modifying coqpp instead. *)
+
(** Implementation of the TACTIC EXTEND macro. *)
open Q_util
@@ -15,32 +17,13 @@ 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$ >>
-| Ulist0 s -> <:expr< Extend.TUlist0 $mlexpr_of_symbol s$ >>
-| Ulist0sep (s,sep) -> <:expr< Extend.TUlist0sep $mlexpr_of_symbol s$ $str:sep$ >>
-| Uopt s -> <:expr< Extend.TUopt $mlexpr_of_symbol s$ >>
-| Uentry e ->
- let wit = <:expr< $lid:"wit_"^e$ >> in
- <:expr< Extend.TUentry (Genarg.get_arg_tag $wit$) >>
-| Uentryl (e, l) ->
- assert (e = "tactic");
- let wit = <:expr< $lid:"wit_"^e$ >> in
- <:expr< Extend.TUentryl (Genarg.get_arg_tag $wit$) $mlexpr_of_int l$>>
-
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$ >>
@@ -54,13 +37,17 @@ EXTEND
GLOBAL: str_item;
str_item:
[ [ "TACTIC"; "EXTEND"; s = tac_name;
+ depr = OPT [ "DEPRECATED"; depr = LIDENT -> depr ];
level = OPT [ "AT"; UIDENT "LEVEL"; level = INT -> level ];
OPT "|"; l = LIST1 tacrule SEP "|";
"END" ->
let level = match level with Some i -> int_of_string i | None -> 0 in
let level = mlexpr_of_int level in
+ let depr = mlexpr_of_option (fun l -> <:expr< $lid:l$ >>) depr in
let l = <:expr< Tacentries.($mlexpr_of_list (fun x -> x) l$) >> in
- declare_str_items loc [ <:str_item< Tacentries.tactic_extend $plugin_name$ $str:s$ ~{ level = $level$ } $l$ >> ] ] ]
+ declare_str_items loc [ <:str_item< Tacentries.tactic_extend
+ $plugin_name$ $str:s$ ~{ level = $level$ } ?{ deprecation =
+ $depr$ } $l$ >> ] ] ]
;
tacrule:
[ [ "["; l = LIST1 tacargs; "]";
diff --git a/grammar/vernacextend.mlp b/grammar/vernacextend.mlp
index a2872d07..f30c96a7 100644
--- a/grammar/vernacextend.mlp
+++ b/grammar/vernacextend.mlp
@@ -14,134 +14,42 @@ open Q_util
open Argextend
type rule = {
- r_head : string option;
- (** The first terminal grammar token *)
r_patt : extend_token list;
(** The remaining tokens of the parsing rule *)
r_class : MLast.expr option;
(** An optional classifier for the STM *)
r_branch : MLast.expr;
(** The action performed by this rule. *)
- r_depr : unit option;
+ r_depr : bool;
(** Whether this entry is deprecated *)
}
-(** Quotation difference for match clauses *)
-
-let default_patt loc =
- (<:patt< _ >>, ploc_vala None, <:expr< failwith "Extension: cannot occur" >>)
-
-let make_fun loc cl =
- let l = cl @ [default_patt loc] in
- MLast.ExFun (loc, ploc_vala l) (* correspond to <:expr< fun [ $list:l$ ] >> *)
-
-let rec make_patt = function
- | [] -> <:patt< [] >>
- | ExtNonTerminal (_, Some p) :: l ->
- <:patt< [ $lid:p$ :: $make_patt l$ ] >>
- | _::l -> make_patt l
-
-let rec make_let e = function
- | [] -> e
- | ExtNonTerminal (g, Some p) :: l ->
- let t = type_of_user_symbol g in
- let loc = MLast.loc_of_expr e in
- let e = make_let e l in
- <:expr< let $lid:p$ = Genarg.out_gen $make_rawwit loc t$ $lid:p$ in $e$ >>
- | _::l -> make_let e l
-
-let make_clause { r_patt = pt; r_branch = e; } =
- (make_patt pt,
- ploc_vala None,
- make_let e pt)
-
-(* To avoid warnings *)
-let mk_ignore c pt =
- let fold accu = function
- | ExtNonTerminal (_, Some p) -> p :: accu
- | _ -> accu
- in
- let names = List.fold_left fold [] pt in
- let fold accu id = <:expr< let _ = $lid:id$ in $accu$ >> in
- let names = List.fold_left fold <:expr< () >> names in
- <:expr< do { let _ = $names$ in $c$ } >>
-
-let make_clause_classifier cg s { r_patt = pt; r_class = c; } =
- match c ,cg with
- | Some c, _ ->
- (make_patt pt,
- ploc_vala None,
- make_let (mk_ignore c pt) pt)
- | None, Some cg ->
- (make_patt pt,
- ploc_vala None,
- <:expr< fun loc -> $cg$ $str:s$ >>)
- | None, None -> prerr_endline
- (("Vernac entry \""^s^"\" misses a classifier. "^
- "A classifier is a function that returns an expression "^
- "of type vernac_classification (see Vernacexpr). You can: ") ^
- "- " ^ (
- ("Use '... EXTEND "^s^" CLASSIFIED AS QUERY ...' if the "^
- "new vernacular command does not alter the system state;"))^ "\n" ^
- "- " ^ (
- ("Use '... EXTEND "^s^" CLASSIFIED AS SIDEFF ...' if the "^
- "new vernacular command alters the system state but not the "^
- "parser nor it starts a proof or ends one;"))^ "\n" ^
- "- " ^ (
- ("Use '... EXTEND "^s^" CLASSIFIED BY f ...' to specify "^
- "a global function f. The function f will be called passing "^
- "\""^s^"\" as the only argument;")) ^ "\n" ^
- "- " ^ (
- "Add a specific classifier in each clause using the syntax:"
- ^ "\n" ^("'[...] => [ f ] -> [...]'. "))^ "\n" ^
- ("Specific classifiers have precedence over global "^
- "classifiers. Only one classifier is called.") ^ "\n");
- (make_patt pt,
- ploc_vala None,
- <:expr< fun () -> ( CErrors.anomaly (Pp.str "No classification given for command " ^ s ) ) >>)
-
-let make_fun_clauses loc s l =
- let map c =
- let depr = match c.r_depr with
- | None -> false
- | Some () -> true
- in
- let cl = make_fun loc [make_clause c] in
- <:expr< ($mlexpr_of_bool depr$, $cl$)>>
- in
- mlexpr_of_list map l
-
-let make_fun_classifiers loc s c l =
- let cl = List.map (fun x -> make_fun loc [make_clause_classifier c s x]) l in
- mlexpr_of_list (fun x -> x) cl
-
-let make_prod_item = function
- | ExtTerminal s -> <:expr< Egramml.GramTerminal $str:s$ >>
- | ExtNonTerminal (g, ido) ->
- let nt = type_of_user_symbol g in
- let base s = <:expr< Pcoq.genarg_grammar ($mk_extraarg loc s$) >> in
- let typ = match ido with None -> None | Some _ -> Some nt in
- <:expr< Egramml.GramNonTerminal ( Loc.tag ( $mlexpr_of_option (make_rawwit loc) typ$ ,
- $mlexpr_of_prod_entry_key base g$ ) ) >>
-
-let mlexpr_of_clause cl =
- let mkexpr { r_head = a; r_patt = b; } = match a with
- | None -> mlexpr_of_list make_prod_item b
- | Some a -> mlexpr_of_list make_prod_item (ExtTerminal a :: b)
- in
- mlexpr_of_list mkexpr cl
+let rec make_patt r = function
+| [] -> r
+| ExtNonTerminal (_, Some p) :: l -> <:expr< fun $lid:p$ -> $make_patt r l$ >>
+| ExtNonTerminal (_, None) :: l -> <:expr< fun _ -> $make_patt r l$ >>
+| ExtTerminal _ :: l -> make_patt r l
+
+let rec mlexpr_of_clause = function
+| [] -> <:expr< Vernacentries.TyNil >>
+| ExtTerminal s :: cl -> <:expr< Vernacentries.TyTerminal ($str:s$, $mlexpr_of_clause cl$) >>
+| ExtNonTerminal (g, id) :: cl ->
+ let id = mlexpr_of_option mlexpr_of_string id in
+ <:expr< Vernacentries.TyNonTerminal ($id$, $mlexpr_of_symbol g$, $mlexpr_of_clause cl$) >>
+
+let make_rule r =
+ let ty = mlexpr_of_clause r.r_patt in
+ let cmd = make_patt r.r_branch r.r_patt in
+ let make_classifier c = make_patt c r.r_patt in
+ let classif = mlexpr_of_option make_classifier r.r_class in
+ <:expr< Vernacentries.TyML ($mlexpr_of_bool r.r_depr$, $ty$, $cmd$, $classif$) >>
let declare_command loc s c nt cl =
let se = mlexpr_of_string s in
- let gl = mlexpr_of_clause cl in
- let funcl = make_fun_clauses loc s cl in
- let classl = make_fun_classifiers loc s c cl in
+ let c = mlexpr_of_option (fun x -> x) c in
+ let rules = mlexpr_of_list make_rule cl in
declare_str_items loc
- [ <:str_item< do {
- CList.iteri (fun i (depr, f) -> Vernacinterp.vinterp_add depr ($se$, i) f) $funcl$;
- CList.iteri (fun i f -> Vernac_classifier.declare_vernac_classifier ($se$, i) f) $classl$;
- CList.iteri (fun i r -> Egramml.extend_vernac_command_grammar ($se$, i) $nt$ r) $gl$;
- } >> ]
+ [ <:str_item< Vernacentries.vernac_extend ?{ classifier = $c$ } ~{ command = $se$ } ?{ entry = $nt$ } $rules$ >> ]
open Pcaml
@@ -176,38 +84,25 @@ EXTEND
] ]
;
deprecation:
- [ [ "DEPRECATED" -> () ] ]
+ [ [ -> false | "DEPRECATED" -> true ] ]
;
- (* spiwack: comment-by-guessing: it seems that the isolated string
- (which otherwise could have been another argument) is not passed
- to the VernacExtend interpreter function to discriminate between
- the clauses. *)
rule:
- [ [ "["; s = STRING; l = LIST0 args; "]";
- d = OPT deprecation; c = OPT classifier; "->"; "["; e = Pcaml.expr; "]" ->
- let () = if s = "" then failwith "Command name is empty." in
- let b = <:expr< fun ~{atts} ~{st} -> ( let () = $e$ in st ) >> in
- { r_head = Some s; r_patt = l; r_class = c; r_branch = b; r_depr = d; }
- | "[" ; "-" ; l = LIST1 args ; "]" ;
- d = OPT deprecation; c = OPT classifier; "->"; "["; e = Pcaml.expr; "]" ->
+ [ [ "["; OPT "-"; l = LIST1 args; "]";
+ d = deprecation; c = OPT classifier; "->"; "["; e = Pcaml.expr; "]" ->
let b = <:expr< fun ~{atts} ~{st} -> ( let () = $e$ in st ) >> in
- { r_head = None; r_patt = l; r_class = c; r_branch = b; r_depr = d; }
+ { r_patt = l; r_class = c; r_branch = b; r_depr = d; }
] ]
;
+ (** The [OPT "-"] argument serves no purpose nowadays, it is left here for
+ backward compatibility. *)
fun_rule:
- [ [ "["; s = STRING; l = LIST0 args; "]";
- d = OPT deprecation; c = OPT classifier; "->"; "["; e = Pcaml.expr; "]" ->
- let () = if s = "" then failwith "Command name is empty." in
- let b = <:expr< $e$ >> in
- { r_head = Some s; r_patt = l; r_class = c; r_branch = b; r_depr = d; }
- | "[" ; "-" ; l = LIST1 args ; "]" ;
- d = OPT deprecation; c = OPT classifier; "->"; "["; e = Pcaml.expr; "]" ->
- let b = <:expr< $e$ >> in
- { r_head = None; r_patt = l; r_class = c; r_branch = b; r_depr = d; }
+ [ [ "["; OPT "-"; l = LIST1 args; "]";
+ d = deprecation; c = OPT classifier; "->"; "["; e = Pcaml.expr; "]" ->
+ { r_patt = l; r_class = c; r_branch = e; r_depr = d; }
] ]
;
classifier:
- [ [ "=>"; "["; c = Pcaml.expr; "]" -> <:expr< fun loc -> $c$>> ] ]
+ [ [ "=>"; "["; c = Pcaml.expr; "]" -> <:expr< $c$>> ] ]
;
args:
[ [ e = LIDENT; "("; s = LIDENT; ")" ->
diff --git a/ide/.merlin b/ide/.merlin
deleted file mode 100644
index 953b5dce..00000000
--- a/ide/.merlin
+++ /dev/null
@@ -1,6 +0,0 @@
-PKG unix laglgtk2 lablgtk2.sourceview2
-
-S utils
-B utils
-
-REC
diff --git a/ide/.merlin.in b/ide/.merlin.in
new file mode 100644
index 00000000..4dc6f455
--- /dev/null
+++ b/ide/.merlin.in
@@ -0,0 +1,8 @@
+PKG unix laglgtk2 lablgtk2.sourceview2
+
+S utils
+B utils
+S protocol
+B protocol
+
+REC
diff --git a/ide/MacOS/default_accel_map b/ide/MacOS/default_accel_map
index 47612cdf..54a592a0 100644
--- a/ide/MacOS/default_accel_map
+++ b/ide/MacOS/default_accel_map
@@ -217,7 +217,6 @@
; (gtk_accel_path "/Tactics/Tactic casetype" "")
; (gtk_accel_path "/Tactics/Tactic cbv in" "")
; (gtk_accel_path "/Templates/Template Load" "")
-; (gtk_accel_path "/Tactics/Tactic fourier" "")
; (gtk_accel_path "/Templates/Template Goal" "")
; (gtk_accel_path "/Tactics/Tactic exists" "")
; (gtk_accel_path "/Tactics/Tactic decompose record" "")
diff --git a/ide/MacOS/relatify_with-respect-to_.sh b/ide/MacOS/relatify_with-respect-to_.sh
deleted file mode 100755
index a24af939..00000000
--- a/ide/MacOS/relatify_with-respect-to_.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-set -e
-
-for i in "$3/"*.dylib
-do install_name_tool -change "$2"/$(basename $i) @executable_path/../Resources/lib/$(basename $i) "$1"
-done
-case "$1" in
- *.dylib)
- install_name_tool -id @executable_path/../Resources/lib/$(basename $1) $1
- for i in "$3"/*.dylib
- do install_name_tool -change "$2/"$(basename $1) @executable_path/../Resources/lib/$(basename $1) $i
- done;;
- *)
-esac
diff --git a/ide/configwin.ml b/ide/configwin.ml
new file mode 100644
index 00000000..69e8b647
--- /dev/null
+++ b/ide/configwin.ml
@@ -0,0 +1,51 @@
+(*********************************************************************************)
+(* Cameleon *)
+(* *)
+(* Copyright (C) 2005 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. *)
+(* *)
+(* This program is free software; you can redistribute it and/or modify *)
+(* it under the terms of the GNU Library General Public License as *)
+(* published by the Free Software Foundation; either version 2 of the *)
+(* License, or any later version. *)
+(* *)
+(* This program 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 Library General Public License for more details. *)
+(* *)
+(* You should have received a copy of the GNU Library General Public *)
+(* License along with this program; if not, write to the Free Software *)
+(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)
+(* 02111-1307 USA *)
+(* *)
+(* Contact: Maxence.Guesdon@inria.fr *)
+(* *)
+(*********************************************************************************)
+
+type parameter_kind = Configwin_types.parameter_kind
+
+type configuration_structure =
+ Configwin_types.configuration_structure =
+ Section of string * GtkStock.id option * parameter_kind list
+ | Section_list of string * GtkStock.id option * configuration_structure list
+
+type return_button =
+ Configwin_types.return_button =
+ Return_apply
+ | Return_ok
+ | Return_cancel
+
+let string = Configwin_ihm.string
+let strings = Configwin_ihm.strings
+let list = Configwin_ihm.list
+let bool = Configwin_ihm.bool
+let combo = Configwin_ihm.combo
+let custom = Configwin_ihm.custom
+let modifiers = Configwin_ihm.modifiers
+
+let edit
+ ?(apply=(fun () -> ()))
+ title ?width ?height
+ conf_struct_list =
+ Configwin_ihm.edit ~with_apply: true ~apply title ?width ?height conf_struct_list
diff --git a/ide/configwin.mli b/ide/configwin.mli
new file mode 100644
index 00000000..7616e471
--- /dev/null
+++ b/ide/configwin.mli
@@ -0,0 +1,164 @@
+(*********************************************************************************)
+(* Cameleon *)
+(* *)
+(* Copyright (C) 2005 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. *)
+(* *)
+(* This program is free software; you can redistribute it and/or modify *)
+(* it under the terms of the GNU Library General Public License as *)
+(* published by the Free Software Foundation; either version 2 of the *)
+(* License, or any later version. *)
+(* *)
+(* This program 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 Library General Public License for more details. *)
+(* *)
+(* You should have received a copy of the GNU Library General Public *)
+(* License along with this program; if not, write to the Free Software *)
+(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)
+(* 02111-1307 USA *)
+(* *)
+(* Contact: Maxence.Guesdon@inria.fr *)
+(* *)
+(*********************************************************************************)
+
+(** This module is the interface of the Configwin library. *)
+
+(** {2 Types} *)
+
+(** This type represents the different kinds of parameters. *)
+type parameter_kind;;
+
+(** This type represents the structure of the configuration window. *)
+type configuration_structure =
+ | Section of string * GtkStock.id option * parameter_kind list
+ (** label of the section, icon, parameters *)
+ | Section_list of string * GtkStock.id option * configuration_structure list
+ (** label of the section, icon, list of the sub sections *)
+;;
+
+(** To indicate what button pushed the user when the window is closed. *)
+type return_button =
+ Return_apply
+ (** The user clicked on Apply at least once before
+ closing the window with Cancel or the window manager. *)
+ | Return_ok
+ (** The user closed the window with the ok button. *)
+ | Return_cancel
+ (** The user closed the window with the cancel
+ button or the window manager but never clicked
+ on the apply button.*)
+
+(** {2 Functions to create parameters} *)
+
+(** [string label value] creates a string parameter.
+ @param editable indicate if the value is editable (default is [true]).
+ @param expand indicate if the entry widget must expand or not (default is [true]).
+ @param help an optional help message.
+ @param f the function called to apply the value (default function does nothing).
+*)
+val string : ?editable: bool -> ?expand: bool -> ?help: string ->
+ ?f: (string -> unit) -> string -> string -> parameter_kind
+
+(** [bool label value] creates a boolean parameter.
+ @param editable indicate if the value is editable (default is [true]).
+ @param help an optional help message.
+ @param f the function called to apply the value (default function does nothing).
+*)
+val bool : ?editable: bool -> ?help: string ->
+ ?f: (bool -> unit) -> string -> bool -> parameter_kind
+
+(** [strings label value] creates a string list parameter.
+ @param editable indicate if the value is editable (default is [true]).
+ @param help an optional help message.
+ @param f the function called to apply the value (default function does nothing).
+ @param add the function returning a list of strings when the user wants to add strings
+ (default returns an empty list).
+ @param eq the comparison function, used not to have doubles in list. Default
+ is [Pervasives.(=)]. If you want to allow doubles in the list, give a function
+ always returning false.
+*)
+val strings : ?editable: bool -> ?help: string ->
+ ?f: (string list -> unit) ->
+ ?eq: (string -> string -> bool) ->
+ ?add: (unit -> string list) ->
+ string -> string list -> parameter_kind
+
+(** [list label f_strings value] creates a list parameter.
+ [f_strings] is a function taking a value and returning a list
+ of strings to display it. The list length should be the same for
+ any value, and the same as the titles list length. The [value]
+ is the initial list.
+ @param editable indicate if the value is editable (default is [true]).
+ @param help an optional help message.
+ @param f the function called to apply the value (default function does nothing).
+ @param eq the comparison function, used not to have doubles in list. Default
+ is [Pervasives.(=)]. If you want to allow doubles in the list, give a function
+ always returning false.
+ @param edit an optional function to use to edit an element of the list.
+ The function returns an element, no matter if element was changed or not.
+ When this function is given, a "Edit" button appears next to the list.
+ @param add the function returning a list of values when the user wants to add values
+ (default returns an empty list).
+ @param titles an optional list of titles for the list. If the [f_strings]
+ function returns a list with more than one element, then you must give
+ a list of titles.
+ @param color an optional function returning the optional color for a given element.
+ This color is used to display the element in the list. The default function returns
+ no color for any element.
+*)
+val list : ?editable: bool -> ?help: string ->
+ ?f: ('a list -> unit) ->
+ ?eq: ('a -> 'a -> bool) ->
+ ?edit: ('a -> 'a) ->
+ ?add: (unit -> 'a list) ->
+ ?titles: string list ->
+ ?color: ('a -> string option) ->
+ string ->
+ ('a -> string list) ->
+ 'a list ->
+ parameter_kind
+
+(** [combo label choices value] creates a combo parameter.
+ @param editable indicate if the value is editable (default is [true]).
+ @param expand indicate if the entry widget must expand or not (default is [true]).
+ @param help an optional help message.
+ @param f the function called to apply the value (default function does nothing).
+ @param new_allowed indicate if a entry not in the list of choices is accepted
+ (default is [false]).
+ @param blank_allowed indicate if the empty selection [""] is accepted
+ (default is [false]).
+*)
+val combo : ?editable: bool -> ?expand: bool -> ?help: string ->
+ ?f: (string -> unit) ->
+ ?new_allowed: bool -> ?blank_allowed: bool ->
+ string -> string list -> string -> parameter_kind
+
+val modifiers : ?editable: bool -> ?expand: bool -> ?help: string ->
+ ?allow:(Gdk.Tags.modifier list) ->
+ ?f: (Gdk.Tags.modifier list -> unit) ->
+ string -> Gdk.Tags.modifier list -> parameter_kind
+
+(** [custom box f expand] creates a custom parameter, with
+ the given [box], the [f] function is called when the user
+ wants to apply his changes, and [expand] indicates if the box
+ must expand in its father.
+ @param label if a value is specified, a the box is packed into a frame.
+*)
+val custom : ?label: string -> GPack.box -> (unit -> unit) -> bool -> parameter_kind
+
+(** {2 Functions creating configuration windows and boxes} *)
+
+(** This function takes a configuration structure and creates a window
+ to configure the various parameters.
+ @param apply this function is called when the apply button is clicked, after
+ giving new values to parameters.
+*)
+val edit :
+ ?apply: (unit -> unit) ->
+ string ->
+ ?width:int ->
+ ?height:int ->
+ configuration_structure list ->
+ return_button
diff --git a/ide/configwin_ihm.ml b/ide/configwin_ihm.ml
new file mode 100644
index 00000000..d16efa60
--- /dev/null
+++ b/ide/configwin_ihm.ml
@@ -0,0 +1,809 @@
+(*********************************************************************************)
+(* Cameleon *)
+(* *)
+(* Copyright (C) 2005 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. *)
+(* *)
+(* This program is free software; you can redistribute it and/or modify *)
+(* it under the terms of the GNU Library General Public License as *)
+(* published by the Free Software Foundation; either version 2 of the *)
+(* License, or any later version. *)
+(* *)
+(* This program 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 Library General Public License for more details. *)
+(* *)
+(* You should have received a copy of the GNU Library General Public *)
+(* License along with this program; if not, write to the Free Software *)
+(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)
+(* 02111-1307 USA *)
+(* *)
+(* Contact: Maxence.Guesdon@inria.fr *)
+(* *)
+(*********************************************************************************)
+
+(** This module contains the gui functions of Configwin.*)
+
+open Configwin_types
+
+let modifiers_to_string m =
+ let rec iter m s =
+ match m with
+ [] -> s
+ | c :: m ->
+ iter m ((
+ match c with
+ `CONTROL -> ""
+ | `SHIFT -> ""
+ | `LOCK -> ""
+ | `MOD1 -> ""
+ | `MOD2 -> ""
+ | `MOD3 -> ""
+ | `MOD4 -> ""
+ | `MOD5 -> ""
+ | _ -> raise Not_found
+ ) ^ s)
+ in
+ iter m ""
+
+class type widget =
+ object
+ method box : GObj.widget
+ method apply : unit -> unit
+ end
+
+let debug = false
+let dbg s = if debug then Minilib.log s else ()
+
+(** This class builds a frame with a clist and two buttons :
+ one to add items and one to remove the selected items.
+ The class takes in parameter a function used to add items and
+ a string list ref which is used to store the content of the clist.
+ At last, a title for the frame is also in parameter, so that
+ each instance of the class creates a frame. *)
+class ['a] list_selection_box
+ (listref : 'a list ref)
+ titles_opt
+ help_opt
+ f_edit_opt
+ f_strings
+ f_color
+ (eq : 'a -> 'a -> bool)
+ add_function title editable
+ (tt:GData.tooltips)
+ =
+ let _ = dbg "list_selection_box" in
+ let wev = GBin.event_box () in
+ let wf = GBin.frame ~label: title ~packing: wev#add () in
+ let hbox = GPack.hbox ~packing: wf#add () in
+ (* the scroll window and the clist *)
+ let wscroll = GBin.scrolled_window
+ ~vpolicy: `AUTOMATIC
+ ~hpolicy: `AUTOMATIC
+ ~packing: (hbox#pack ~expand: true) ()
+ in
+ let wlist = match titles_opt with
+ None ->
+ GList.clist ~selection_mode: `MULTIPLE
+ ~titles_show: false
+ ~packing: wscroll#add ()
+ | Some l ->
+ GList.clist ~selection_mode: `MULTIPLE
+ ~titles: l
+ ~titles_show: true
+ ~packing: wscroll#add ()
+ in
+ let _ =
+ match help_opt with
+ None -> ()
+ | Some help ->
+ tt#set_tip ~text: help ~privat: help wev#coerce
+ in (* the vbox for the buttons *)
+ let vbox_buttons = GPack.vbox () in
+ let _ =
+ if editable then
+ let _ = hbox#pack ~expand: false vbox_buttons#coerce in
+ ()
+ else
+ ()
+ in
+ let _ = dbg "list_selection_box: wb_add" in
+ let wb_add = GButton.button
+ ~label: Configwin_messages.mAdd
+ ~packing: (vbox_buttons#pack ~expand:false ~padding:2)
+ ()
+ in
+ let wb_edit = GButton.button
+ ~label: Configwin_messages.mEdit
+ ()
+ in
+ let _ = match f_edit_opt with
+ None -> ()
+ | Some _ -> vbox_buttons#pack ~expand:false ~padding:2 wb_edit#coerce
+ in
+ let wb_up = GButton.button
+ ~label: Configwin_messages.mUp
+ ~packing: (vbox_buttons#pack ~expand:false ~padding:2)
+ ()
+ in
+ let wb_remove = GButton.button
+ ~label: Configwin_messages.mRemove
+ ~packing: (vbox_buttons#pack ~expand:false ~padding:2)
+ ()
+ in
+ let _ = dbg "list_selection_box: object(self)" in
+ object (self)
+ (** the list of selected rows *)
+ val mutable list_select = []
+
+ (** This method returns the frame created. *)
+ method box = wev
+
+ method update l =
+ (* set the new list in the provided listref *)
+ listref := l;
+ (* insert the elements in the clist *)
+ wlist#freeze ();
+ wlist#clear ();
+ List.iter
+ (fun ele ->
+ ignore (wlist#append (f_strings ele));
+ match f_color ele with
+ None -> ()
+ | Some c ->
+ try wlist#set_row ~foreground: (`NAME c) (wlist#rows - 1)
+ with _ -> ()
+ )
+ !listref;
+
+ (match titles_opt with
+ None -> wlist#columns_autosize ()
+ | Some _ -> GToolbox.autosize_clist wlist);
+ wlist#thaw ();
+ (* the list of selectd elements is now empty *)
+ list_select <- []
+
+ (** Move up the selected rows. *)
+ method up_selected =
+ let rec iter n selrows l =
+ match selrows with
+ [] -> (l, [])
+ | m :: qrows ->
+ match l with
+ [] -> ([],[])
+ | [_] -> (l,[])
+ | e1 :: e2 :: q when m = n + 1 ->
+ let newl, newrows = iter (n+1) qrows (e1 :: q) in
+ (e2 :: newl, n :: newrows)
+ | e1 :: q ->
+ let newl, newrows = iter (n+1) selrows q in
+ (e1 :: newl, newrows)
+ in
+ let sorted_select = List.sort compare list_select in
+ let new_list, new_rows = iter 0 sorted_select !listref in
+ self#update new_list;
+ List.iter (fun n -> wlist#select n 0) new_rows
+
+ (** Make the user edit the first selected row. *)
+ method edit_selected f_edit =
+ let sorted_select = List.sort compare list_select in
+ match sorted_select with
+ [] -> ()
+ | n :: _ ->
+ try
+ let ele = List.nth !listref n in
+ let ele2 = f_edit ele in
+ let rec iter m = function
+ [] -> []
+ | e :: q ->
+ if n = m then
+ ele2 :: q
+ else
+ e :: (iter (m+1) q)
+ in
+ self#update (iter 0 !listref);
+ wlist#select n 0
+ with
+ Not_found ->
+ ()
+
+ initializer
+ (** create the functions called when the buttons are clicked *)
+ let f_add () =
+ (* get the files to add with the function provided *)
+ let l = add_function () in
+ (* remove from the list the ones which are already in
+ the listref, using the eq predicate *)
+ let l2 = List.fold_left
+ (fun acc -> fun ele ->
+ if List.exists (eq ele) acc then
+ acc
+ else
+ acc @ [ele])
+ !listref
+ l
+ in
+ self#update l2
+ in
+ let f_remove () =
+ (* remove the selected items from the listref and the clist *)
+ let rec iter n = function
+ [] -> []
+ | h :: q ->
+ if List.mem n list_select then
+ iter (n+1) q
+ else
+ h :: (iter (n+1) q)
+ in
+ let new_list = iter 0 !listref in
+ self#update new_list
+ in
+ let _ = dbg "list_selection_box: connecting wb_add" in
+ (* connect the functions to the buttons *)
+ ignore (wb_add#connect#clicked ~callback:f_add);
+ let _ = dbg "list_selection_box: connecting wb_remove" in
+ ignore (wb_remove#connect#clicked ~callback:f_remove);
+ let _ = dbg "list_selection_box: connecting wb_up" in
+ ignore (wb_up#connect#clicked ~callback:(fun () -> self#up_selected));
+ (
+ match f_edit_opt with
+ None -> ()
+ | Some f ->
+ let _ = dbg "list_selection_box: connecting wb_edit" in
+ ignore (wb_edit#connect#clicked ~callback:(fun () -> self#edit_selected f))
+ );
+ (* connect the selection and deselection of items in the clist *)
+ let f_select ~row ~column ~event =
+ try
+ list_select <- row :: list_select
+ with
+ Failure _ ->
+ ()
+ in
+ let f_unselect ~row ~column ~event =
+ try
+ let new_list_select = List.filter (fun n -> n <> row) list_select in
+ list_select <- new_list_select
+ with
+ Failure _ ->
+ ()
+ in
+ (* connect the select and deselect events *)
+ let _ = dbg "list_selection_box: connecting select_row" in
+ ignore(wlist#connect#select_row ~callback:f_select);
+ let _ = dbg "list_selection_box: connecting unselect_row" in
+ ignore(wlist#connect#unselect_row ~callback:f_unselect);
+
+ (* initialize the clist with the listref *)
+ self#update !listref
+ end;;
+
+
+(** This class is used to build a box for a string parameter.*)
+class string_param_box param (tt:GData.tooltips) =
+ let _ = dbg "string_param_box" in
+ let hbox = GPack.hbox () in
+ let wev = GBin.event_box ~packing: (hbox#pack ~expand: false ~padding: 2) () in
+ let _wl = GMisc.label ~text: param.string_label ~packing: wev#add () in
+ let we = GEdit.entry
+ ~editable: param.string_editable
+ ~packing: (hbox#pack ~expand: param.string_expand ~padding: 2)
+ ()
+ in
+ let _ =
+ match param.string_help with
+ None -> ()
+ | Some help ->
+ tt#set_tip ~text: help ~privat: help wev#coerce
+ in
+ let _ = we#set_text (param.string_to_string param.string_value) in
+
+ object (self)
+ (** This method returns the main box ready to be packed. *)
+ method box = hbox#coerce
+ (** This method applies the new value of the parameter. *)
+ method apply =
+ let new_value = param.string_of_string we#text in
+ if new_value <> param.string_value then
+ let _ = param.string_f_apply new_value in
+ param.string_value <- new_value
+ else
+ ()
+ end ;;
+
+(** This class is used to build a box for a combo parameter.*)
+class combo_param_box param (tt:GData.tooltips) =
+ let _ = dbg "combo_param_box" in
+ let hbox = GPack.hbox () in
+ let wev = GBin.event_box ~packing: (hbox#pack ~expand: false ~padding: 2) () in
+ let _wl = GMisc.label ~text: param.combo_label ~packing: wev#add () in
+ let _ =
+ match param.combo_help with
+ None -> ()
+ | Some help ->
+ tt#set_tip ~text: help ~privat: help wev#coerce
+ in
+ let get_value = if not param.combo_new_allowed then
+ let wc = GEdit.combo_box_text
+ ~strings: param.combo_choices
+ ?active:(let rec aux i = function
+ |[] -> None
+ |h::_ when h = param.combo_value -> Some i
+ |_::t -> aux (succ i) t
+ in aux 0 param.combo_choices)
+ ~packing: (hbox#pack ~expand: param.combo_expand ~padding: 2)
+ ()
+ in
+ fun () -> match GEdit.text_combo_get_active wc with |None -> "" |Some s -> s
+ else
+ let (wc,_) = GEdit.combo_box_entry_text
+ ~strings: param.combo_choices
+ ~packing: (hbox#pack ~expand: param.combo_expand ~padding: 2)
+ ()
+ in
+ let _ = wc#entry#set_editable param.combo_editable in
+ let _ = wc#entry#set_text param.combo_value in
+ fun () -> wc#entry#text
+ in
+object (self)
+ (** This method returns the main box ready to be packed. *)
+ method box = hbox#coerce
+ (** This method applies the new value of the parameter. *)
+ method apply =
+ let new_value = get_value () in
+ if new_value <> param.combo_value then
+ let _ = param.combo_f_apply new_value in
+ param.combo_value <- new_value
+ else
+ ()
+end ;;
+
+(** Class used to pack a custom box. *)
+class custom_param_box param (tt:GData.tooltips) =
+ let _ = dbg "custom_param_box" in
+ let top =
+ match param.custom_framed with
+ None -> param.custom_box#coerce
+ | Some l ->
+ let wf = GBin.frame ~label: l () in
+ wf#add param.custom_box#coerce;
+ wf#coerce
+ in
+ object (self)
+ method box = top
+ method apply = param.custom_f_apply ()
+ end
+
+(** This class is used to build a box for a text parameter.*)
+class text_param_box param (tt:GData.tooltips) =
+ let _ = dbg "text_param_box" in
+ let wf = GBin.frame ~label: param.string_label ~height: 100 () in
+ let wev = GBin.event_box ~packing: wf#add () in
+ let wscroll = GBin.scrolled_window
+ ~vpolicy: `AUTOMATIC
+ ~hpolicy: `AUTOMATIC
+ ~packing: wev#add ()
+ in
+ let wview = GText.view
+ ~editable: param.string_editable
+ ~packing: wscroll#add
+ ()
+ in
+ let _ =
+ match param.string_help with
+ None -> ()
+ | Some help ->
+ tt#set_tip ~text: help ~privat: help wev#coerce
+ in
+ let _ = dbg "text_param_box: buffer creation" in
+ let buffer = GText.buffer () in
+
+ let _ = wview#set_buffer buffer in
+ let _ = buffer#insert (param.string_to_string param.string_value) in
+ let _ = dbg "text_param_box: object(self)" in
+ object (self)
+ val wview = wview
+ (** This method returns the main box ready to be packed. *)
+ method box = wf#coerce
+ (** This method applies the new value of the parameter. *)
+ method apply =
+ let v = param.string_of_string (buffer#get_text ()) in
+ if v <> param.string_value then
+ (
+ dbg "apply new value!";
+ let _ = param.string_f_apply v in
+ param.string_value <- v
+ )
+ else
+ ()
+ end ;;
+
+(** This class is used to build a box for a boolean parameter.*)
+class bool_param_box param (tt:GData.tooltips) =
+ let _ = dbg "bool_param_box" in
+ let wchk = GButton.check_button
+ ~label: param.bool_label
+ ()
+ in
+ let _ =
+ match param.bool_help with
+ None -> ()
+ | Some help -> tt#set_tip ~text: help ~privat: help wchk#coerce
+ in
+ let _ = wchk#set_active param.bool_value in
+ let _ = wchk#misc#set_sensitive param.bool_editable in
+
+ object (self)
+ (** This method returns the check button ready to be packed. *)
+ method box = wchk#coerce
+ (** This method applies the new value of the parameter. *)
+ method apply =
+ let new_value = wchk#active in
+ if new_value <> param.bool_value then
+ let _ = param.bool_f_apply new_value in
+ param.bool_value <- new_value
+ else
+ ()
+ end ;;
+
+class modifiers_param_box param =
+ let hbox = GPack.hbox () in
+ let wev = GBin.event_box ~packing: (hbox#pack ~expand:true ~fill:true ~padding: 2) () in
+ let _wl = GMisc.label ~text: param.md_label ~packing: wev#add () in
+ let value = ref param.md_value in
+ let _ = List.map (fun modifier ->
+ let but = GButton.toggle_button
+ ~label:(modifiers_to_string [modifier])
+ ~active:(List.mem modifier param.md_value)
+ ~packing:(hbox#pack ~expand:false) () in
+ ignore (but#connect#toggled
+ ~callback:(fun _ -> if but#active then value := modifier::!value
+ else value := List.filter ((<>) modifier) !value)))
+ param.md_allow
+ in
+ let _ =
+ match param.md_help with
+ None -> ()
+ | Some help ->
+ let tooltips = GData.tooltips () in
+ ignore (hbox#connect#destroy ~callback: tooltips#destroy);
+ tooltips#set_tip wev#coerce ~text: help ~privat: help
+ in
+ object (self)
+ (** This method returns the main box ready to be packed. *)
+ method box = hbox#coerce
+ (** This method applies the new value of the parameter. *)
+ method apply =
+ let new_value = !value in
+ if new_value <> param.md_value then
+ let _ = param.md_f_apply new_value in
+ param.md_value <- new_value
+ else
+ ()
+ end ;;
+
+(** This class is used to build a box for a parameter whose values are a list.*)
+class ['a] list_param_box (param : 'a list_param) (tt:GData.tooltips) =
+ let _ = dbg "list_param_box" in
+ let listref = ref param.list_value in
+ let frame_selection = new list_selection_box
+ listref
+ param.list_titles
+ param.list_help
+ param.list_f_edit
+ param.list_strings
+ param.list_color
+ param.list_eq
+ param.list_f_add param.list_label param.list_editable
+ tt
+ in
+
+ object (self)
+ (** This method returns the main box ready to be packed. *)
+ method box = frame_selection#box#coerce
+ (** This method applies the new value of the parameter. *)
+ method apply =
+ param.list_f_apply !listref ;
+ param.list_value <- !listref
+ end ;;
+
+(** This class creates a configuration box from a configuration structure *)
+class configuration_box (tt : GData.tooltips) conf_struct =
+
+ let main_box = GPack.hbox () in
+
+ let columns = new GTree.column_list in
+ let icon_col = columns#add GtkStock.conv in
+ let label_col = columns#add Gobject.Data.string in
+ let box_col = columns#add Gobject.Data.caml in
+ let () = columns#lock () in
+
+ let pane = GPack.paned `HORIZONTAL ~packing:main_box#add () in
+
+ (* Tree view part *)
+ let scroll = GBin.scrolled_window ~hpolicy:`NEVER ~packing:pane#pack1 () in
+ let tree = GTree.tree_store columns in
+ let view = GTree.view ~model:tree ~headers_visible:false ~packing:scroll#add_with_viewport () in
+ let selection = view#selection in
+ let _ = selection#set_mode `SINGLE in
+
+ let menu_box = GPack.vbox ~packing:pane#pack2 () in
+
+ let renderer = (GTree.cell_renderer_pixbuf [], ["stock-id", icon_col]) in
+ let col = GTree.view_column ~renderer () in
+ let _ = view#append_column col in
+
+ let renderer = (GTree.cell_renderer_text [], ["text", label_col]) in
+ let col = GTree.view_column ~renderer () in
+ let _ = view#append_column col in
+
+ let make_param (main_box : #GPack.box) = function
+ | String_param p ->
+ let box = new string_param_box p tt in
+ let _ = main_box#pack ~expand: false ~padding: 2 box#box in
+ box
+ | Combo_param p ->
+ let box = new combo_param_box p tt in
+ let _ = main_box#pack ~expand: false ~padding: 2 box#box in
+ box
+ | Text_param p ->
+ let box = new text_param_box p tt in
+ let _ = main_box#pack ~expand: p.string_expand ~padding: 2 box#box in
+ box
+ | Bool_param p ->
+ let box = new bool_param_box p tt in
+ let _ = main_box#pack ~expand: false ~padding: 2 box#box in
+ box
+ | List_param f ->
+ let box = f tt in
+ let _ = main_box#pack ~expand: true ~padding: 2 box#box in
+ box
+ | Custom_param p ->
+ let box = new custom_param_box p tt in
+ let _ = main_box#pack ~expand: p.custom_expand ~padding: 2 box#box in
+ box
+ | Modifiers_param p ->
+ let box = new modifiers_param_box p in
+ let _ = main_box#pack ~expand: false ~padding: 2 box#box in
+ box
+ in
+
+ let set_icon iter = function
+ | None -> ()
+ | Some icon -> tree#set ~row:iter ~column:icon_col icon
+ in
+
+ (* Populate the tree *)
+
+ let rec make_tree iter conf_struct =
+ (* box is not shown at first *)
+ let box = GPack.vbox ~packing:(menu_box#pack ~expand:true) ~show:false () in
+ let new_iter = match iter with
+ | None -> tree#append ()
+ | Some parent -> tree#append ~parent ()
+ in
+ match conf_struct with
+ | Section (label, icon, param_list) ->
+ let params = List.map (make_param box) param_list in
+ let widget =
+ object
+ method box = box#coerce
+ method apply () = List.iter (fun param -> param#apply) params
+ end
+ in
+ let () = tree#set ~row:new_iter ~column:label_col label in
+ let () = set_icon new_iter icon in
+ let () = tree#set ~row:new_iter ~column:box_col widget in
+ ()
+ | Section_list (label, icon, struct_list) ->
+ let widget =
+ object
+ (* Section_list does not contain any effect widget, so we do not have to
+ apply anything. *)
+ method apply () = ()
+ method box = box#coerce
+ end
+ in
+ let () = tree#set ~row:new_iter ~column:label_col label in
+ let () = set_icon new_iter icon in
+ let () = tree#set ~row:new_iter ~column:box_col widget in
+ List.iter (make_tree (Some new_iter)) struct_list
+ in
+
+ let () = List.iter (make_tree None) conf_struct in
+
+ (* Dealing with signals *)
+
+ let current_prop : widget option ref = ref None in
+
+ let select_iter iter =
+ let () = match !current_prop with
+ | None -> ()
+ | Some box -> box#box#misc#hide ()
+ in
+ let box = tree#get ~row:iter ~column:box_col in
+ let () = box#box#misc#show () in
+ current_prop := Some box
+ in
+
+ let when_selected () =
+ let rows = selection#get_selected_rows in
+ match rows with
+ | [] -> ()
+ | row :: _ ->
+ let iter = tree#get_iter row in
+ select_iter iter
+ in
+
+ (* Focus on a box when selected *)
+
+ let _ = selection#connect#changed ~callback:when_selected in
+
+ let _ = match tree#get_iter_first with
+ | None -> ()
+ | Some iter -> select_iter iter
+ in
+
+ object
+
+ method box = main_box
+
+ method apply =
+ let foreach _ iter =
+ let widget = tree#get ~row:iter ~column:box_col in
+ widget#apply(); false
+ in
+ tree#foreach foreach
+
+ end
+
+(** This function takes a configuration structure list and creates a window
+ to configure the various parameters. *)
+let edit ?(with_apply=true)
+ ?(apply=(fun () -> ()))
+ title ?width ?height
+ conf_struct =
+ let dialog = GWindow.dialog
+ ~position:`CENTER
+ ~modal: true ~title: title
+ ?height ?width
+ ()
+ in
+ let tooltips = GData.tooltips () in
+
+ let config_box = new configuration_box tooltips conf_struct in
+
+ let _ = dialog#vbox#add config_box#box#coerce in
+
+ if with_apply then
+ dialog#add_button Configwin_messages.mApply `APPLY;
+
+ dialog#add_button Configwin_messages.mOk `OK;
+ dialog#add_button Configwin_messages.mCancel `CANCEL;
+
+ let destroy () =
+ tooltips#destroy () ;
+ dialog#destroy ();
+ in
+ let rec iter rep =
+ try
+ match dialog#run () with
+ | `APPLY -> config_box#apply; iter Return_apply
+ | `OK -> config_box#apply; destroy (); Return_ok
+ | _ -> destroy (); rep
+ with
+ Failure s ->
+ GToolbox.message_box ~title:"Error" s; iter rep
+ | e ->
+ GToolbox.message_box ~title:"Error" (Printexc.to_string e); iter rep
+ in
+ iter Return_cancel
+
+let edit_string l s =
+ match GToolbox.input_string ~title: l ~text: s Configwin_messages.mValue with
+ None -> s
+ | Some s2 -> s2
+
+(** Create a string param. *)
+let string ?(editable=true) ?(expand=true) ?help ?(f=(fun _ -> ())) label v =
+ String_param
+ {
+ string_label = label ;
+ string_help = help ;
+ string_value = v ;
+ string_editable = editable ;
+ string_f_apply = f ;
+ string_expand = expand ;
+ string_to_string = (fun x -> x) ;
+ string_of_string = (fun x -> x) ;
+ }
+
+(** Create a bool param. *)
+let bool ?(editable=true) ?help ?(f=(fun _ -> ())) label v =
+ Bool_param
+ {
+ bool_label = label ;
+ bool_help = help ;
+ bool_value = v ;
+ bool_editable = editable ;
+ bool_f_apply = f ;
+ }
+
+(** Create a list param. *)
+let list ?(editable=true) ?help
+ ?(f=(fun (_:'a list) -> ()))
+ ?(eq=Pervasives.(=))
+ ?(edit:('a -> 'a) option)
+ ?(add=(fun () -> ([] : 'a list)))
+ ?titles ?(color=(fun (_:'a) -> (None : string option)))
+ label (f_strings : 'a -> string list) v =
+ List_param
+ (fun tt ->
+ new list_param_box
+ {
+ list_label = label ;
+ list_help = help ;
+ list_value = v ;
+ list_editable = editable ;
+ list_titles = titles;
+ list_eq = eq ;
+ list_strings = f_strings ;
+ list_color = color ;
+ list_f_edit = edit ;
+ list_f_add = add ;
+ list_f_apply = f ;
+ }
+ tt
+ )
+
+(** Create a strings param. *)
+let strings ?(editable=true) ?help
+ ?(f=(fun _ -> ()))
+ ?(eq=Pervasives.(=))
+ ?(add=(fun () -> [])) label v =
+ list ~editable ?help ~f ~eq ~edit: (edit_string label) ~add label (fun s -> [s]) v
+
+(** Create a combo param. *)
+let combo ?(editable=true) ?(expand=true) ?help ?(f=(fun _ -> ()))
+ ?(new_allowed=false)
+ ?(blank_allowed=false) label choices v =
+ Combo_param
+ {
+ combo_label = label ;
+ combo_help = help ;
+ combo_value = v ;
+ combo_editable = editable ;
+ combo_choices = choices ;
+ combo_new_allowed = new_allowed ;
+ combo_blank_allowed = blank_allowed ;
+ combo_f_apply = f ;
+ combo_expand = expand ;
+ }
+
+let modifiers
+ ?(editable=true)
+ ?(expand=true)
+ ?help
+ ?(allow=[`CONTROL;`SHIFT;`LOCK;`MOD1;`MOD2;`MOD3;`MOD4;`MOD5])
+ ?(f=(fun _ -> ())) label v =
+ Modifiers_param
+ {
+ md_label = label ;
+ md_help = help ;
+ md_value = v ;
+ md_editable = editable ;
+ md_f_apply = f ;
+ md_expand = expand ;
+ md_allow = allow ;
+ }
+
+(** Create a custom param.*)
+let custom ?label box f expand =
+ Custom_param
+ {
+ custom_box = box ;
+ custom_f_apply = f ;
+ custom_expand = expand ;
+ custom_framed = label ;
+ }
diff --git a/ide/configwin_ihm.mli b/ide/configwin_ihm.mli
new file mode 100644
index 00000000..c867ad91
--- /dev/null
+++ b/ide/configwin_ihm.mli
@@ -0,0 +1,66 @@
+(*********************************************************************************)
+(* Cameleon *)
+(* *)
+(* Copyright (C) 2005 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. *)
+(* *)
+(* This program is free software; you can redistribute it and/or modify *)
+(* it under the terms of the GNU Library General Public License as *)
+(* published by the Free Software Foundation; either version 2 of the *)
+(* License, or any later version. *)
+(* *)
+(* This program 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 Library General Public License for more details. *)
+(* *)
+(* You should have received a copy of the GNU Library General Public *)
+(* License along with this program; if not, write to the Free Software *)
+(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)
+(* 02111-1307 USA *)
+(* *)
+(* Contact: Maxence.Guesdon@inria.fr *)
+(* *)
+(*********************************************************************************)
+
+open Configwin_types
+
+val string : ?editable: bool -> ?expand: bool -> ?help: string ->
+ ?f: (string -> unit) -> string -> string -> parameter_kind
+val bool : ?editable: bool -> ?help: string ->
+ ?f: (bool -> unit) -> string -> bool -> parameter_kind
+val strings : ?editable: bool -> ?help: string ->
+ ?f: (string list -> unit) ->
+ ?eq: (string -> string -> bool) ->
+ ?add: (unit -> string list) ->
+ string -> string list -> parameter_kind
+val list : ?editable: bool -> ?help: string ->
+ ?f: ('a list -> unit) ->
+ ?eq: ('a -> 'a -> bool) ->
+ ?edit: ('a -> 'a) ->
+ ?add: (unit -> 'a list) ->
+ ?titles: string list ->
+ ?color: ('a -> string option) ->
+ string ->
+ ('a -> string list) ->
+ 'a list ->
+ parameter_kind
+val combo : ?editable: bool -> ?expand: bool -> ?help: string ->
+ ?f: (string -> unit) ->
+ ?new_allowed: bool -> ?blank_allowed: bool ->
+ string -> string list -> string -> parameter_kind
+
+val modifiers : ?editable: bool -> ?expand: bool -> ?help: string ->
+ ?allow:(Gdk.Tags.modifier list) ->
+ ?f: (Gdk.Tags.modifier list -> unit) ->
+ string -> Gdk.Tags.modifier list -> parameter_kind
+val custom : ?label: string -> GPack.box -> (unit -> unit) -> bool -> parameter_kind
+
+val edit :
+ ?with_apply:bool ->
+ ?apply:(unit -> unit) ->
+ string ->
+ ?width:int ->
+ ?height:int ->
+ configuration_structure list ->
+ return_button
diff --git a/ide/configwin_messages.ml b/ide/configwin_messages.ml
new file mode 100644
index 00000000..de1b4721
--- /dev/null
+++ b/ide/configwin_messages.ml
@@ -0,0 +1,50 @@
+(*********************************************************************************)
+(* Cameleon *)
+(* *)
+(* Copyright (C) 2005 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. *)
+(* *)
+(* This program is free software; you can redistribute it and/or modify *)
+(* it under the terms of the GNU Library General Public License as *)
+(* published by the Free Software Foundation; either version 2 of the *)
+(* License, or any later version. *)
+(* *)
+(* This program 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 Library General Public License for more details. *)
+(* *)
+(* You should have received a copy of the GNU Library General Public *)
+(* License along with this program; if not, write to the Free Software *)
+(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)
+(* 02111-1307 USA *)
+(* *)
+(* Contact: Maxence.Guesdon@inria.fr *)
+(* *)
+(*********************************************************************************)
+
+(** Module containing the messages of Configwin.*)
+
+let software = "Configwin";;
+let version = "1.2";;
+
+let html_config = "Configwin bindings configurator for html parameters"
+
+let home = Option.default "" (Glib.get_home_dir ())
+
+let mCapture = "Capture";;
+let mType_key = "Type key" ;;
+let mAdd = "Add";;
+let mRemove = "Remove";;
+let mUp = "Up";;
+let mEdit = "Edit";;
+let mOk = "Ok";;
+let mCancel = "Cancel";;
+let mApply = "Apply";;
+let mValue = "Value"
+let mKey = "Key"
+
+let shortcuts = "Shortcuts"
+let html_end = "End with"
+let html_begin = "Begin with"
+
diff --git a/ide/configwin_types.ml b/ide/configwin_types.ml
new file mode 100644
index 00000000..9e339d13
--- /dev/null
+++ b/ide/configwin_types.ml
@@ -0,0 +1,121 @@
+(*********************************************************************************)
+(* Cameleon *)
+(* *)
+(* Copyright (C) 2005 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. *)
+(* *)
+(* This program is free software; you can redistribute it and/or modify *)
+(* it under the terms of the GNU Library General Public License as *)
+(* published by the Free Software Foundation; either version 2 of the *)
+(* License, or any later version. *)
+(* *)
+(* This program 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 Library General Public License for more details. *)
+(* *)
+(* You should have received a copy of the GNU Library General Public *)
+(* License along with this program; if not, write to the Free Software *)
+(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)
+(* 02111-1307 USA *)
+(* *)
+(* Contact: Maxence.Guesdon@inria.fr *)
+(* *)
+(*********************************************************************************)
+
+(** This module contains the types used in Configwin. *)
+
+(** This type represents a string or filename parameter, or
+ any other type, depending on the given conversion functions. *)
+type 'a string_param = {
+ string_label : string; (** the label of the parameter *)
+ mutable string_value : 'a; (** the current value of the parameter *)
+ string_editable : bool ; (** indicates if the value can be changed *)
+ string_f_apply : ('a -> unit) ; (** the function to call to apply the new value of the parameter *)
+ string_help : string option ; (** optional help string *)
+ string_expand : bool ; (** expand or not *)
+ string_to_string : 'a -> string ;
+ string_of_string : string -> 'a ;
+ } ;;
+
+(** This type represents a boolean parameter. *)
+type bool_param = {
+ bool_label : string; (** the label of the parameter *)
+ mutable bool_value : bool; (** the current value of the parameter *)
+ bool_editable : bool ; (** indicates if the value can be changed *)
+ bool_f_apply : (bool -> unit) ; (** the function to call to apply the new value of the parameter *)
+ bool_help : string option ; (** optional help string *)
+ } ;;
+
+(** This type represents a parameter whose value is a list of ['a]. *)
+type 'a list_param = {
+ list_label : string; (** the label of the parameter *)
+ mutable list_value : 'a list; (** the current value of the parameter *)
+ list_titles : string list option; (** the titles of columns, if they must be displayed *)
+ list_f_edit : ('a -> 'a) option; (** optional edition function *)
+ list_eq : ('a -> 'a -> bool) ; (** the comparison function used to get list without doubles *)
+ list_strings : ('a -> string list); (** the function to get a string list from a ['a]. *)
+ list_color : ('a -> string option) ; (** a function to get the optional color of an element *)
+ list_editable : bool ; (** indicates if the value can be changed *)
+ list_f_add : unit -> 'a list ; (** the function to call to add list *)
+ list_f_apply : ('a list -> unit) ; (** the function to call to apply the new value of the parameter *)
+ list_help : string option ; (** optional help string *)
+ } ;;
+
+type combo_param = {
+ combo_label : string ;
+ mutable combo_value : string ;
+ combo_choices : string list ;
+ combo_editable : bool ;
+ combo_blank_allowed : bool ;
+ combo_new_allowed : bool ;
+ combo_f_apply : (string -> unit);
+ combo_help : string option ; (** optional help string *)
+ combo_expand : bool ; (** expand the entry widget or not *)
+ } ;;
+
+type custom_param = {
+ custom_box : GPack.box ;
+ custom_f_apply : (unit -> unit) ;
+ custom_expand : bool ;
+ custom_framed : string option ; (** optional label for an optional frame *)
+ } ;;
+
+type modifiers_param = {
+ md_label : string ; (** the label of the parameter *)
+ mutable md_value : Gdk.Tags.modifier list ;
+ (** The value, as a list of modifiers and a key code *)
+ md_editable : bool ; (** indicates if the value can be changed *)
+ md_f_apply : Gdk.Tags.modifier list -> unit ;
+ (** the function to call to apply the new value of the paramter *)
+ md_help : string option ; (** optional help string *)
+ md_expand : bool ; (** expand or not *)
+ md_allow : Gdk.Tags.modifier list
+ }
+
+
+(** This type represents the different kinds of parameters. *)
+type parameter_kind =
+ String_param of string string_param
+ | List_param of (GData.tooltips -> )
+ | Bool_param of bool_param
+ | Text_param of string string_param
+ | Combo_param of combo_param
+ | Custom_param of custom_param
+ | Modifiers_param of modifiers_param
+;;
+
+(** This type represents the structure of the configuration window. *)
+type configuration_structure =
+ | Section of string * GtkStock.id option * parameter_kind list (** label of the section, icon, parameters *)
+ | Section_list of string * GtkStock.id option * configuration_structure list (** label of the section, list of the sub sections *)
+;;
+
+(** To indicate what button was pushed by the user when the window is closed. *)
+type return_button =
+ Return_apply (** The user clicked on Apply at least once before
+ closing the window with Cancel or the window manager. *)
+ | Return_ok (** The user closed the window with the ok button. *)
+ | Return_cancel (** The user closed the window with the cancel
+ button or the window manager but never clicked
+ on the apply button.*)
diff --git a/ide/coq.ml b/ide/coq.ml
index 65456d68..e9483601 100644
--- a/ide/coq.ml
+++ b/ide/coq.ml
@@ -152,7 +152,7 @@ let print_status = function
let check_connection args =
let lines = ref [] in
let argstr = String.concat " " (List.map Filename.quote args) in
- let cmd = Filename.quote (coqtop_path ()) ^ " -batch -ideslave " ^ argstr in
+ let cmd = Filename.quote (coqtop_path ()) ^ " -batch " ^ argstr in
let cmd = requote cmd in
try
let oc,ic,ec = Unix.open_process_full cmd (Unix.environment ()) in
@@ -377,7 +377,7 @@ let spawn_handle args respawner feedback_processor =
else
"on"
in
- let args = Array.of_list ("--xml_format=Ppcmds" :: "-async-proofs" :: async_default :: "-ideslave" :: args) in
+ let args = Array.of_list ("--xml_format=Ppcmds" :: "-async-proofs" :: async_default :: args) in
let env =
match !ideslave_coqtop_flags with
| None -> None
@@ -530,20 +530,31 @@ let break_coqtop coqtop workers =
module PrintOpt =
struct
- type t = string list
+ type _ t =
+ | BoolOpt : string list -> bool t
+ | StringOpt : string list -> string t
+
+ let opt_name (type a) : a t -> string list = function
+ | BoolOpt l -> l
+ | StringOpt l -> l
+
+ let opt_data (type a) (key : a t) (v : a) = match key with
+ | BoolOpt l -> Interface.BoolValue v
+ | StringOpt l -> Interface.StringValue v
(* Boolean options *)
- let implicit = ["Printing"; "Implicit"]
- let coercions = ["Printing"; "Coercions"]
- let raw_matching = ["Printing"; "Matching"]
- let notations = ["Printing"; "Notations"]
- let all_basic = ["Printing"; "All"]
- let existential = ["Printing"; "Existential"; "Instances"]
- let universes = ["Printing"; "Universes"]
- let unfocused = ["Printing"; "Unfocused"]
+ let implicit = BoolOpt ["Printing"; "Implicit"]
+ let coercions = BoolOpt ["Printing"; "Coercions"]
+ let raw_matching = BoolOpt ["Printing"; "Matching"]
+ let notations = BoolOpt ["Printing"; "Notations"]
+ let all_basic = BoolOpt ["Printing"; "All"]
+ let existential = BoolOpt ["Printing"; "Existential"; "Instances"]
+ let universes = BoolOpt ["Printing"; "Universes"]
+ let unfocused = BoolOpt ["Printing"; "Unfocused"]
+ let diff = StringOpt ["Diffs"]
- type bool_descr = { opts : t list; init : bool; label : string }
+ type 'a descr = { opts : 'a t list; init : 'a; label : string }
let bool_items = [
{ opts = [implicit]; init = false; label = "Display _implicit arguments" };
@@ -561,24 +572,32 @@ struct
{ opts = [unfocused]; init = false; label = "Display _unfocused goals" }
]
+ let diff_item = { opts = [diff]; init = "off"; label = "Display _proof diffs" }
+
(** The current status of the boolean options *)
let current_state = Hashtbl.create 11
- let set opt v = Hashtbl.replace current_state opt v
+ let set (type a) (opt : a t) (v : a) =
+ Hashtbl.replace current_state (opt_name opt) (opt_data opt v)
let reset () =
let init_descr d = List.iter (fun o -> set o d.init) d.opts in
- List.iter init_descr bool_items
+ List.iter init_descr bool_items;
+ List.iter (fun o -> set o diff_item.init) diff_item.opts
let _ = reset ()
- let printing_unfocused () = Hashtbl.find current_state unfocused
+ let printing_unfocused () =
+ let BoolOpt unfocused = unfocused in
+ match Hashtbl.find current_state unfocused with
+ | Interface.BoolValue b -> b
+ | _ -> assert false
(** Transmitting options to coqtop *)
let enforce h k =
- let mkopt o v acc = (o, Interface.BoolValue v) :: acc in
+ let mkopt o v acc = (o, v) :: acc in
let opts = Hashtbl.fold mkopt current_state [] in
eval_call (Xmlprotocol.set_options opts) h
(function
diff --git a/ide/coq.mli b/ide/coq.mli
index 40a6dea8..3af0aa69 100644
--- a/ide/coq.mli
+++ b/ide/coq.mli
@@ -134,13 +134,15 @@ val stop_worker: Interface.stop_worker_sty-> Interface.stop_worker_rty query
module PrintOpt :
sig
- type t (** Representation of an option *)
+ type 'a t (** Representation of an option *)
- type bool_descr = { opts : t list; init : bool; label : string }
+ type 'a descr = { opts : 'a t list; init : 'a; label : string }
- val bool_items : bool_descr list
+ val bool_items : bool descr list
- val set : t -> bool -> unit
+ val diff_item : string descr
+
+ val set : 'a t -> 'a -> unit
val printing_unfocused: unit -> bool
diff --git a/ide/coq_commands.ml b/ide/coq_commands.ml
index f5dba208..b0bafb79 100644
--- a/ide/coq_commands.ml
+++ b/ide/coq_commands.ml
@@ -311,7 +311,6 @@ let tactics =
"fix __ with";
"fold";
"fold __ in";
- "fourier";
"functional induction";
];
diff --git a/ide/coq_lex.mll b/ide/coq_lex.mll
index 1fdd7317..b6654f6d 100644
--- a/ide/coq_lex.mll
+++ b/ide/coq_lex.mll
@@ -23,7 +23,11 @@ let number = [ '0'-'9' ]+
let string = "\"" _+ "\""
-let undotted_sep = (number space* ':' space*)? '{' | '}' | '-'+ | '+'+ | '*'+
+let alpha = ['a'-'z' 'A'-'Z']
+
+let ident = alpha (alpha | number | '_' | "'")*
+
+let undotted_sep = ((number | '[' ident ']') space* ':' space*)? '{' | '}' | '-'+ | '+'+ | '*'+
let vernac_control = "Fail" | "Time" | "Redirect" space+ string | "Timeout" space+ number
diff --git a/ide/coqide.ml b/ide/coqide.ml
index f5ff0899..a4d45c6d 100644
--- a/ide/coqide.ml
+++ b/ide/coqide.ml
@@ -826,6 +826,7 @@ let refresh_notebook_pos () =
let menu = GAction.add_actions
let item = GAction.add_action
+let radio = GAction.add_radio_action
(** Toggle items in menus for printing options *)
@@ -1003,8 +1004,6 @@ let build_ui () =
item "Find Previous" ~label:"Find _Previous" ~stock:`GO_UP
~accel:"F3"
~callback:(cb_on_current_term (fun t -> t.finder#find_backward ()));
- item "Complete Word" ~label:"Complete Word" ~accel:"slash"
- ~callback:(fun _ -> ());
item "External editor" ~label:"External editor" ~stock:`EDIT
~callback:External.editor;
item "Preferences" ~accel:"comma" ~stock:`PREFERENCES
@@ -1043,7 +1042,27 @@ let build_ui () =
~callback:(fun _ -> show_toolbar#set (not show_toolbar#get));
item "Query Pane" ~label:"_Query Pane"
~accel:"F1"
- ~callback:(cb_on_current_term MiscMenu.show_hide_query_pane)
+ ~callback:(cb_on_current_term MiscMenu.show_hide_query_pane);
+ GAction.group_radio_actions
+ ~init_value:(
+ let v = diffs#get in
+ List.iter (fun o -> Opt.set o v) Opt.diff_item.Opt.opts;
+ if v = "on" then 1
+ else if v = "removed" then 2
+ else 0)
+ ~callback:begin fun n ->
+ (match n with
+ | 0 -> List.iter (fun o -> Opt.set o "off"; diffs#set "off") Opt.diff_item.Opt.opts
+ | 1 -> List.iter (fun o -> Opt.set o "on"; diffs#set "on") Opt.diff_item.Opt.opts
+ | 2 -> List.iter (fun o -> Opt.set o "removed"; diffs#set "removed") Opt.diff_item.Opt.opts
+ | _ -> assert false);
+ send_to_coq (fun sn -> sn.coqops#show_goals)
+ end
+ [
+ radio "Unset diff" 0 ~label:"_Don't show diffs";
+ radio "Set diff" 1 ~label:"Show diffs: only _added";
+ radio "Set removed diff" 2 ~label:"Show diffs: added and _removed";
+ ];
];
toggle_items view_menu Coq.PrintOpt.bool_items;
diff --git a/ide/coqide_ui.ml b/ide/coqide_ui.ml
index 717c4000..c994898a 100644
--- a/ide/coqide_ui.ml
+++ b/ide/coqide_ui.ml
@@ -60,7 +60,6 @@ let init () =
\n \
\n \
\n \
-\n \
\n \
\n \
\n \
@@ -86,6 +85,10 @@ let init () =
\n \
\n \
\n \
+\n \
+\n \
+\n \
+\n \
\n \
\n