summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@debian.org>2019-02-02 19:29:28 -0500
committerGravatar Benjamin Barenblat <bbaren@debian.org>2019-02-02 19:29:28 -0500
commit1ef7f1c0c6897535a86daa77799714e25638f5e9 (patch)
tree5bcca733632ecc84d2c6b1ee48cb2e557a7adba5
parent3a2fac7bcee36fd9dcb4f39a615c8ac0349abcc9 (diff)
parent9ebf44d84754adc5b64fcf612c6816c02c80462d (diff)
Updated version 8.9.0 from 'upstream/8.9.0'
-rw-r--r--.bintray.json20
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md7
-rw-r--r--.gitlab-ci.yml86
-rw-r--r--.merlin.in (renamed from .merlin)4
-rw-r--r--CHANGES.md (renamed from CHANGES)271
-rw-r--r--CONTRIBUTING.md75
-rw-r--r--CREDITS4
-rw-r--r--INSTALL4
-rw-r--r--INSTALL.doc105
-rw-r--r--INSTALL.ide123
-rw-r--r--META.coq.in (renamed from META.coq)138
-rw-r--r--Makefile112
-rw-r--r--Makefile.build158
-rw-r--r--Makefile.checker39
-rw-r--r--Makefile.ci2
-rw-r--r--Makefile.common84
-rw-r--r--Makefile.dev6
-rw-r--r--Makefile.doc125
-rw-r--r--Makefile.ide61
-rw-r--r--Makefile.install22
-rw-r--r--Makefile.vofiles43
-rw-r--r--README.md17
-rw-r--r--checker/check.mllib1
-rw-r--r--checker/checker.ml4
-rw-r--r--checker/cic.mli32
-rw-r--r--checker/closure.ml48
-rw-r--r--checker/closure.mli2
-rw-r--r--checker/declarations.ml51
-rw-r--r--checker/declarations.mli3
-rw-r--r--checker/environ.ml27
-rw-r--r--checker/environ.mli4
-rw-r--r--checker/indtypes.ml35
-rw-r--r--checker/inductive.ml26
-rw-r--r--checker/mod_checking.ml13
-rw-r--r--checker/modops.ml22
-rw-r--r--checker/print.ml4
-rw-r--r--checker/reduction.ml70
-rw-r--r--checker/subtyping.ml32
-rw-r--r--checker/term.ml22
-rw-r--r--checker/typeops.ml25
-rw-r--r--checker/univ.ml25
-rw-r--r--checker/univ.mli12
-rw-r--r--checker/values.ml29
-rw-r--r--clib/cArray.ml300
-rw-r--r--clib/cArray.mli84
-rw-r--r--clib/cList.ml1199
-rw-r--r--clib/cList.mli380
-rw-r--r--clib/cMap.ml58
-rw-r--r--clib/cMap.mli13
-rw-r--r--clib/clib.mllib3
-rw-r--r--clib/diff2.ml158
-rw-r--r--clib/diff2.mli101
-rw-r--r--clib/dyn.ml194
-rw-r--r--clib/dyn.mli63
-rw-r--r--clib/hMap.ml20
-rw-r--r--clib/hashcons.ml40
-rw-r--r--clib/hashcons.mli3
-rw-r--r--clib/option.ml21
-rw-r--r--clib/option.mli13
-rw-r--r--clib/terminal.ml48
-rw-r--r--clib/terminal.mli6
-rw-r--r--configure.ml99
-rw-r--r--coqpp/coqpp_ast.mli96
-rw-r--r--coqpp/coqpp_lex.mll168
-rw-r--r--coqpp/coqpp_main.ml360
-rw-r--r--coqpp/coqpp_parse.mly261
-rw-r--r--default.nix10
-rw-r--r--dev/README50
-rw-r--r--dev/README.md46
-rw-r--r--dev/base_include13
-rwxr-xr-xdev/build/osx/make-macos-dmg.sh54
-rwxr-xr-xdev/build/windows/MakeCoq_MinGW.bat976
-rw-r--r--dev/build/windows/configure_profile.sh24
-rw-r--r--dev/build/windows/difftar-folder.sh22
-rwxr-xr-xdev/build/windows/makecoq_mingw.sh84
-rwxr-xr-xdev/build/windows/patches_coq/VST.patch15
-rw-r--r--dev/build/windows/patches_coq/aactactis-86ac28259030649ef51460e4de2441c8a1017751.patch21
-rwxr-xr-x[-rw-r--r--]dev/build/windows/patches_coq/quickchick.patch (renamed from dev/build/windows/patches_coq/quickchick-v1.0.2.patch)12
-rw-r--r--dev/checker.dbg6
-rw-r--r--dev/checker_db39
-rw-r--r--dev/checker_printers.ml73
-rw-r--r--dev/checker_printers.mli54
-rw-r--r--dev/ci/README.md45
-rw-r--r--dev/ci/appveyor.sh2
-rwxr-xr-xdev/ci/ci-basic-overlay.sh128
-rw-r--r--dev/ci/ci-common.sh8
-rwxr-xr-xdev/ci/ci-cross-crypto.sh9
-rwxr-xr-xdev/ci/ci-elpi.sh1
-rwxr-xr-xdev/ci/ci-fiat-crypto-legacy.sh1
-rwxr-xr-xdev/ci/ci-hott.sh2
-rwxr-xr-xdev/ci/ci-iris-lambda-rust.sh6
-rwxr-xr-xdev/ci/ci-math-comp.sh1
-rwxr-xr-xdev/ci/ci-pidetop.sh19
-rwxr-xr-xdev/ci/ci-sf.sh9
-rwxr-xr-xdev/ci/ci-simple-io.sh1
-rw-r--r--dev/ci/docker/README.md36
-rw-r--r--dev/ci/docker/bionic_coq/Dockerfile53
-rwxr-xr-xdev/ci/gitlab.bat263
-rw-r--r--dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh2
-rw-r--r--dev/ci/user-overlays/07085-ppedrot-pure-sharing-flag.sh8
-rw-r--r--dev/ci/user-overlays/README.md8
-rw-r--r--dev/core.dbg3
-rw-r--r--dev/doc/MERGING.md136
-rw-r--r--dev/doc/README.md77
-rw-r--r--dev/doc/changes.md227
-rw-r--r--dev/doc/coq-src-description.txt6
-rw-r--r--dev/doc/critical-bugs262
-rw-r--r--dev/doc/proof-engine.md31
-rw-r--r--dev/doc/release-process.md128
-rw-r--r--dev/doc/setup.txt269
-rw-r--r--dev/doc/translate.txt495
-rw-r--r--dev/doc/versions-history.tex12
-rw-r--r--dev/doc/xml-protocol.md4
-rwxr-xr-xdev/lint-repository.sh2
-rw-r--r--dev/ocamldebug-coq.run22
-rwxr-xr-xdev/tools/backport-pr.sh53
-rwxr-xr-xdev/tools/check-overlays.sh11
-rwxr-xr-xdev/tools/check-owners-pr.sh32
-rwxr-xr-xdev/tools/check-owners.sh138
-rw-r--r--dev/tools/coqdev.el47
-rwxr-xr-xdev/tools/merge-pr.sh218
-rwxr-xr-xdev/tools/pre-commit2
-rwxr-xr-xdev/tools/update-compat.py341
-rw-r--r--dev/top_printers.ml58
-rw-r--r--dev/top_printers.mli6
-rw-r--r--dev/vm_printers.ml13
-rw-r--r--doc/LICENSE23
-rw-r--r--doc/README.md126
-rw-r--r--doc/stdlib/hidden-files78
-rw-r--r--doc/stdlib/index-list.html.template17
-rwxr-xr-xdoc/stdlib/make-library-index25
-rw-r--r--doc/tools/coqrst/coqdomain.py3
-rw-r--r--doc/tools/coqrst/repl/coqtop.py5
-rw-r--r--engine/eConstr.ml259
-rw-r--r--engine/eConstr.mli44
-rw-r--r--engine/engine.mllib6
-rw-r--r--engine/evar_kinds.ml (renamed from intf/evar_kinds.ml)27
-rw-r--r--engine/evar_kinds.mli51
-rw-r--r--engine/evarutil.ml209
-rw-r--r--engine/evarutil.mli127
-rw-r--r--engine/evd.ml158
-rw-r--r--engine/evd.mli208
-rw-r--r--engine/namegen.ml18
-rw-r--r--engine/namegen.mli10
-rw-r--r--engine/nameops.ml28
-rw-r--r--engine/nameops.mli44
-rw-r--r--engine/proofview.ml32
-rw-r--r--engine/proofview.mli18
-rw-r--r--engine/termops.ml101
-rw-r--r--engine/termops.mli76
-rw-r--r--engine/uState.ml108
-rw-r--r--engine/uState.mli28
-rw-r--r--engine/univGen.ml246
-rw-r--r--engine/univGen.mli80
-rw-r--r--engine/univMinim.ml383
-rw-r--r--engine/univMinim.mli32
-rw-r--r--engine/univNames.ml106
-rw-r--r--engine/univNames.mli41
-rw-r--r--engine/univProblem.ml166
-rw-r--r--engine/univProblem.mli55
-rw-r--r--engine/univSubst.ml177
-rw-r--r--engine/univSubst.mli53
-rw-r--r--engine/universes.ml1195
-rw-r--r--engine/universes.mli262
-rw-r--r--engine/univops.ml100
-rw-r--r--engine/univops.mli9
-rw-r--r--grammar/q_util.mli2
-rw-r--r--grammar/q_util.mlp16
-rw-r--r--grammar/tacextend.mlp31
-rw-r--r--grammar/vernacextend.mlp171
-rw-r--r--ide/.merlin.in (renamed from ide/.merlin)2
-rw-r--r--ide/MacOS/default_accel_map1
-rwxr-xr-xide/MacOS/relatify_with-respect-to_.sh15
-rw-r--r--ide/configwin.ml (renamed from ide/utils/configwin.ml)0
-rw-r--r--ide/configwin.mli (renamed from ide/utils/configwin.mli)0
-rw-r--r--ide/configwin_ihm.ml (renamed from ide/utils/configwin_ihm.ml)0
-rw-r--r--ide/configwin_ihm.mli (renamed from ide/utils/configwin_ihm.mli)0
-rw-r--r--ide/configwin_messages.ml (renamed from ide/utils/configwin_messages.ml)0
-rw-r--r--ide/configwin_types.ml (renamed from ide/utils/configwin_types.mli)0
-rw-r--r--ide/coq.ml51
-rw-r--r--ide/coq.mli10
-rw-r--r--ide/coq_commands.ml1
-rw-r--r--ide/coq_lex.mll6
-rw-r--r--ide/coqide.ml25
-rw-r--r--ide/coqide_ui.ml5
-rw-r--r--ide/gtk_parsing.ml7
-rw-r--r--ide/ide.mllib8
-rw-r--r--ide/ide_common.mllib (renamed from ide/coqidetop.mllib)1
-rw-r--r--ide/idetop.ml (renamed from ide/ide_slave.ml)84
-rw-r--r--ide/ideutils.ml61
-rw-r--r--ide/nanoPG.ml6
-rw-r--r--ide/preferences.ml28
-rw-r--r--ide/preferences.mli2
-rw-r--r--ide/protocol/ideprotocol.mllib7
-rw-r--r--ide/protocol/interface.ml (renamed from ide/interface.mli)0
-rw-r--r--ide/protocol/richpp.ml (renamed from ide/richpp.ml)0
-rw-r--r--ide/protocol/richpp.mli (renamed from ide/richpp.mli)0
-rw-r--r--ide/protocol/serialize.ml (renamed from ide/serialize.ml)0
-rw-r--r--ide/protocol/serialize.mli (renamed from ide/serialize.mli)0
-rw-r--r--ide/protocol/xml_lexer.mli (renamed from ide/xml_lexer.mli)0
-rw-r--r--ide/protocol/xml_lexer.mll (renamed from ide/xml_lexer.mll)0
-rw-r--r--ide/protocol/xml_parser.ml (renamed from ide/xml_parser.ml)0
-rw-r--r--ide/protocol/xml_parser.mli (renamed from ide/xml_parser.mli)0
-rw-r--r--ide/protocol/xml_printer.ml (renamed from ide/xml_printer.ml)0
-rw-r--r--ide/protocol/xml_printer.mli (renamed from ide/xml_printer.mli)0
-rw-r--r--ide/protocol/xmlprotocol.ml (renamed from ide/xmlprotocol.ml)0
-rw-r--r--ide/protocol/xmlprotocol.mli (renamed from ide/xmlprotocol.mli)0
-rw-r--r--ide/wg_Command.ml8
-rw-r--r--interp/constrexpr.ml (renamed from intf/constrexpr.ml)42
-rw-r--r--interp/constrexpr_ops.ml107
-rw-r--r--interp/constrexpr_ops.mli26
-rw-r--r--interp/constrextern.ml285
-rw-r--r--interp/constrextern.mli8
-rw-r--r--interp/constrintern.ml238
-rw-r--r--interp/constrintern.mli14
-rw-r--r--interp/declare.ml117
-rw-r--r--interp/declare.mli6
-rw-r--r--interp/discharge.ml7
-rw-r--r--interp/dumpglob.ml10
-rw-r--r--interp/dumpglob.mli10
-rw-r--r--interp/genintern.ml8
-rw-r--r--interp/genintern.mli8
-rw-r--r--interp/genredexpr.ml (renamed from intf/genredexpr.ml)5
-rw-r--r--interp/impargs.ml310
-rw-r--r--interp/impargs.mli9
-rw-r--r--interp/implicit_quantifiers.ml25
-rw-r--r--interp/implicit_quantifiers.mli17
-rw-r--r--interp/interp.mllib6
-rw-r--r--interp/modintern.ml12
-rw-r--r--interp/modintern.mli3
-rw-r--r--interp/notation.ml961
-rw-r--r--interp/notation.mli179
-rw-r--r--interp/notation_ops.ml83
-rw-r--r--interp/notation_ops.mli10
-rw-r--r--interp/notation_term.ml (renamed from intf/notation_term.ml)47
-rw-r--r--interp/ppextend.ml43
-rw-r--r--interp/redops.ml (renamed from pretyping/redops.ml)20
-rw-r--r--interp/redops.mli (renamed from pretyping/redops.mli)5
-rw-r--r--interp/reserve.ml6
-rw-r--r--interp/reserve.mli2
-rw-r--r--interp/smartlocate.ml19
-rw-r--r--interp/smartlocate.mli13
-rw-r--r--interp/stdarg.ml15
-rw-r--r--interp/stdarg.mli38
-rw-r--r--interp/syntax_def.ml4
-rw-r--r--interp/topconstr.ml23
-rw-r--r--interp/topconstr.mli53
-rw-r--r--intf/intf.mllib11
-rw-r--r--intf/misctypes.ml162
-rw-r--r--kernel/byterun/coq_fix_code.c51
-rw-r--r--kernel/byterun/coq_fix_code.h2
-rw-r--r--kernel/byterun/coq_interp.c55
-rw-r--r--kernel/byterun/coq_interp.h9
-rw-r--r--kernel/byterun/coq_memory.c92
-rw-r--r--kernel/byterun/coq_memory.h7
-rw-r--r--kernel/byterun/coq_values.c31
-rw-r--r--kernel/cClosure.ml233
-rw-r--r--kernel/cClosure.mli17
-rw-r--r--kernel/cbytecodes.ml100
-rw-r--r--kernel/cbytecodes.mli40
-rw-r--r--kernel/cbytegen.ml204
-rw-r--r--kernel/cbytegen.mli5
-rw-r--r--kernel/cemitcodes.ml23
-rw-r--r--kernel/cemitcodes.mli2
-rw-r--r--kernel/cinstr.mli6
-rw-r--r--kernel/clambda.ml87
-rw-r--r--kernel/clambda.mli9
-rw-r--r--kernel/constr.ml97
-rw-r--r--kernel/constr.mli41
-rw-r--r--kernel/context.ml25
-rw-r--r--kernel/context.mli21
-rw-r--r--kernel/cooking.ml79
-rw-r--r--kernel/cooking.mli6
-rw-r--r--kernel/csymtable.ml55
-rw-r--r--kernel/csymtable.mli4
-rw-r--r--kernel/declarations.ml43
-rw-r--r--kernel/declareops.ml78
-rw-r--r--kernel/declareops.mli10
-rw-r--r--kernel/entries.ml32
-rw-r--r--kernel/environ.ml376
-rw-r--r--kernel/environ.mli112
-rw-r--r--kernel/esubst.ml35
-rw-r--r--kernel/esubst.mli13
-rw-r--r--kernel/indtypes.ml141
-rw-r--r--kernel/indtypes.mli5
-rw-r--r--kernel/inductive.ml30
-rw-r--r--kernel/inductive.mli8
-rw-r--r--kernel/kernel.mllib17
-rw-r--r--kernel/mod_subst.ml35
-rw-r--r--kernel/mod_subst.mli5
-rw-r--r--kernel/mod_typing.ml2
-rw-r--r--kernel/modops.ml25
-rw-r--r--kernel/modops.mli2
-rw-r--r--kernel/names.ml305
-rw-r--r--kernel/names.mli333
-rw-r--r--kernel/nativecode.ml185
-rw-r--r--kernel/nativecode.mli6
-rw-r--r--kernel/nativeconv.ml19
-rw-r--r--kernel/nativeconv.mli4
-rw-r--r--kernel/nativeinstr.mli6
-rw-r--r--kernel/nativelambda.ml277
-rw-r--r--kernel/nativelambda.mli5
-rw-r--r--kernel/nativelibrary.ml7
-rw-r--r--kernel/nativevalues.ml38
-rw-r--r--kernel/nativevalues.mli11
-rw-r--r--kernel/opaqueproof.ml2
-rw-r--r--kernel/opaqueproof.mli2
-rw-r--r--kernel/pre_env.ml213
-rw-r--r--kernel/pre_env.mli108
-rw-r--r--kernel/reduction.ml96
-rw-r--r--kernel/reduction.mli14
-rw-r--r--kernel/retroknowledge.ml19
-rw-r--r--kernel/retroknowledge.mli22
-rw-r--r--kernel/safe_typing.ml202
-rw-r--r--kernel/safe_typing.mli18
-rw-r--r--kernel/sorts.ml57
-rw-r--r--kernel/sorts.mli7
-rw-r--r--kernel/subtyping.ml9
-rw-r--r--kernel/term.ml255
-rw-r--r--kernel/term.mli433
-rw-r--r--kernel/term_typing.ml244
-rw-r--r--kernel/term_typing.mli10
-rw-r--r--kernel/type_errors.ml4
-rw-r--r--kernel/type_errors.mli3
-rw-r--r--kernel/typeops.ml59
-rw-r--r--kernel/typeops.mli7
-rw-r--r--kernel/uGraph.ml74
-rw-r--r--kernel/uGraph.mli21
-rw-r--r--kernel/univ.ml29
-rw-r--r--kernel/univ.mli2
-rw-r--r--kernel/vars.mli14
-rw-r--r--kernel/vconv.ml21
-rw-r--r--kernel/vconv.mli4
-rw-r--r--kernel/vm.ml10
-rw-r--r--kernel/vmvalues.ml203
-rw-r--r--kernel/vmvalues.mli50
-rw-r--r--lib/cErrors.ml4
-rw-r--r--lib/cErrors.mli2
-rw-r--r--lib/cWarnings.ml6
-rw-r--r--lib/coqProject_file.ml (renamed from lib/coqProject_file.ml4)79
-rw-r--r--lib/envars.ml2
-rw-r--r--lib/flags.ml21
-rw-r--r--lib/flags.mli37
-rw-r--r--lib/future.ml6
-rw-r--r--lib/future.mli4
-rw-r--r--lib/lib.mllib1
-rw-r--r--lib/pp.ml75
-rw-r--r--lib/pp.mli19
-rw-r--r--lib/pp_diff.ml303
-rw-r--r--lib/pp_diff.mli116
-rw-r--r--lib/rtree.ml28
-rw-r--r--lib/rtree.mli11
-rw-r--r--lib/spawn.ml59
-rw-r--r--lib/spawn.mli4
-rw-r--r--lib/stateid.ml10
-rw-r--r--lib/system.ml22
-rw-r--r--lib/system.mli20
-rw-r--r--lib/util.ml4
-rw-r--r--library/coqlib.ml34
-rw-r--r--library/coqlib.mli123
-rw-r--r--library/decl_kinds.ml (renamed from intf/decl_kinds.ml)11
-rw-r--r--library/declaremods.ml23
-rw-r--r--library/declaremods.mli26
-rw-r--r--library/global.ml7
-rw-r--r--library/global.mli19
-rw-r--r--library/globnames.ml15
-rw-r--r--library/globnames.mli57
-rw-r--r--library/goptions.ml23
-rw-r--r--library/goptions.mli8
-rw-r--r--library/keys.ml9
-rw-r--r--library/keys.mli4
-rw-r--r--library/lib.ml52
-rw-r--r--library/lib.mli80
-rw-r--r--library/libnames.ml90
-rw-r--r--library/libnames.mli46
-rw-r--r--library/libobject.ml16
-rw-r--r--library/library.ml50
-rw-r--r--library/library.mli2
-rw-r--r--library/library.mllib2
-rw-r--r--library/nametab.ml50
-rw-r--r--library/nametab.mli36
-rw-r--r--library/summary.ml44
-rw-r--r--library/summary.mli20
-rw-r--r--man/gallina.174
-rw-r--r--parsing/extend.ml (renamed from intf/extend.ml)24
-rw-r--r--parsing/g_constr.mlg (renamed from parsing/g_constr.ml4)357
-rw-r--r--parsing/g_prim.ml4122
-rw-r--r--parsing/g_prim.mlg123
-rw-r--r--parsing/g_proofs.ml4133
-rw-r--r--parsing/g_vernac.ml41195
-rw-r--r--parsing/notation_gram.ml43
-rw-r--r--parsing/notgram_ops.ml71
-rw-r--r--parsing/notgram_ops.mli20
-rw-r--r--parsing/parsing.mllib8
-rw-r--r--parsing/pcoq.ml299
-rw-r--r--parsing/pcoq.mli252
-rw-r--r--parsing/ppextend.ml77
-rw-r--r--parsing/ppextend.mli (renamed from interp/ppextend.mli)17
-rw-r--r--plugins/.merlin.in (renamed from plugins/.merlin)0
-rw-r--r--plugins/btauto/Algebra.v24
-rw-r--r--plugins/btauto/g_btauto.mlg (renamed from plugins/btauto/g_btauto.ml4)6
-rw-r--r--plugins/btauto/refl_btauto.ml30
-rw-r--r--plugins/cc/ccalgo.ml20
-rw-r--r--plugins/cc/cctac.ml15
-rw-r--r--plugins/cc/g_congruence.mlg (renamed from plugins/cc/g_congruence.ml4)14
-rw-r--r--plugins/derive/derive.ml2
-rw-r--r--plugins/extraction/ExtrHaskellString.v2
-rw-r--r--plugins/extraction/ExtrOcamlString.v1
-rw-r--r--plugins/extraction/common.mli3
-rw-r--r--plugins/extraction/extract_env.ml15
-rw-r--r--plugins/extraction/extract_env.mli11
-rw-r--r--plugins/extraction/extraction.ml22
-rw-r--r--plugins/extraction/miniml.ml25
-rw-r--r--plugins/extraction/miniml.mli25
-rw-r--r--plugins/extraction/mlutil.ml26
-rw-r--r--plugins/extraction/mlutil.mli5
-rw-r--r--plugins/extraction/modutil.ml2
-rw-r--r--plugins/extraction/modutil.mli7
-rw-r--r--plugins/extraction/table.ml8
-rw-r--r--plugins/extraction/table.mli77
-rw-r--r--plugins/firstorder/formula.ml2
-rw-r--r--plugins/firstorder/formula.mli8
-rw-r--r--plugins/firstorder/g_ground.ml43
-rw-r--r--plugins/firstorder/ground.ml16
-rw-r--r--plugins/firstorder/instances.ml7
-rw-r--r--plugins/firstorder/instances.mli4
-rw-r--r--plugins/firstorder/rules.ml4
-rw-r--r--plugins/firstorder/rules.mli9
-rw-r--r--plugins/firstorder/sequent.ml32
-rw-r--r--plugins/firstorder/sequent.mli22
-rw-r--r--plugins/firstorder/unify.ml6
-rw-r--r--plugins/fourier/Fourier_util.v222
-rw-r--r--plugins/fourier/fourier.ml204
-rw-r--r--plugins/fourier/fourierR.ml644
-rw-r--r--plugins/fourier/fourier_plugin.mlpack3
-rw-r--r--plugins/funind/functional_principles_proofs.ml60
-rw-r--r--plugins/funind/functional_principles_types.ml36
-rw-r--r--plugins/funind/functional_principles_types.mli4
-rw-r--r--plugins/funind/g_indfun.ml415
-rw-r--r--plugins/funind/glob_term_to_relation.ml11
-rw-r--r--plugins/funind/glob_termops.ml25
-rw-r--r--plugins/funind/glob_termops.mli2
-rw-r--r--plugins/funind/indfun.ml63
-rw-r--r--plugins/funind/indfun.mli5
-rw-r--r--plugins/funind/indfun_common.ml38
-rw-r--r--plugins/funind/indfun_common.mli14
-rw-r--r--plugins/funind/invfun.ml32
-rw-r--r--plugins/funind/invfun.mli4
-rw-r--r--plugins/funind/recdef.ml52
-rw-r--r--plugins/funind/recdef.mli2
-rw-r--r--plugins/ltac/coretactics.mlg (renamed from plugins/ltac/coretactics.ml4)190
-rw-r--r--plugins/ltac/evar_tactics.ml10
-rw-r--r--plugins/ltac/extraargs.ml451
-rw-r--r--plugins/ltac/extraargs.mli23
-rw-r--r--plugins/ltac/extratactics.ml4137
-rw-r--r--plugins/ltac/g_auto.ml49
-rw-r--r--plugins/ltac/g_eqdecide.mlg (renamed from plugins/ltac/g_eqdecide.ml4)8
-rw-r--r--plugins/ltac/g_ltac.ml469
-rw-r--r--plugins/ltac/g_obligations.ml45
-rw-r--r--plugins/ltac/g_rewrite.ml48
-rw-r--r--plugins/ltac/g_tactic.mlg (renamed from plugins/ltac/g_tactic.ml4)464
-rw-r--r--plugins/ltac/pltac.ml9
-rw-r--r--plugins/ltac/pltac.mli40
-rw-r--r--plugins/ltac/pptactic.ml83
-rw-r--r--plugins/ltac/pptactic.mli10
-rw-r--r--plugins/ltac/rewrite.ml60
-rw-r--r--plugins/ltac/rewrite.mli4
-rw-r--r--plugins/ltac/tacarg.ml8
-rw-r--r--plugins/ltac/tacarg.mli34
-rw-r--r--plugins/ltac/taccoerce.ml38
-rw-r--r--plugins/ltac/taccoerce.mli18
-rw-r--r--plugins/ltac/tacentries.ml87
-rw-r--r--plugins/ltac/tacentries.mli21
-rw-r--r--plugins/ltac/tacenv.ml49
-rw-r--r--plugins/ltac/tacenv.mli18
-rw-r--r--plugins/ltac/tacexpr.ml54
-rw-r--r--plugins/ltac/tacexpr.mli54
-rw-r--r--plugins/ltac/tacintern.ml164
-rw-r--r--plugins/ltac/tacintern.mli2
-rw-r--r--plugins/ltac/tacinterp.ml99
-rw-r--r--plugins/ltac/tacinterp.mli5
-rw-r--r--plugins/ltac/tacsubst.ml7
-rw-r--r--plugins/ltac/tacsubst.mli2
-rw-r--r--plugins/ltac/tactic_debug.ml18
-rw-r--r--plugins/ltac/tactic_debug.mli2
-rw-r--r--plugins/ltac/tactic_matching.ml2
-rw-r--r--plugins/ltac/tauto.ml11
-rw-r--r--plugins/micromega/Fourier.v5
-rw-r--r--plugins/micromega/Fourier_util.v31
-rw-r--r--plugins/micromega/Tauto.v4
-rw-r--r--plugins/micromega/certificate.ml194
-rw-r--r--plugins/micromega/certificate.mli22
-rw-r--r--plugins/micromega/coq_micromega.ml323
-rw-r--r--plugins/micromega/coq_micromega.mli22
-rw-r--r--plugins/micromega/csdpcert.ml36
-rw-r--r--plugins/micromega/csdpcert.mli9
-rw-r--r--plugins/micromega/g_micromega.mlg (renamed from plugins/micromega/g_micromega.ml4)38
-rw-r--r--plugins/micromega/g_micromega.mli9
-rw-r--r--plugins/micromega/mfourier.ml85
-rw-r--r--plugins/micromega/mfourier.mli49
-rw-r--r--plugins/micromega/mutils.ml109
-rw-r--r--plugins/micromega/mutils.mli70
-rw-r--r--plugins/micromega/persistent_cache.mli47
-rw-r--r--plugins/micromega/polynomial.ml68
-rw-r--r--plugins/micromega/polynomial.mli118
-rw-r--r--plugins/micromega/sos.ml616
-rw-r--r--plugins/micromega/sos_lib.ml105
-rw-r--r--plugins/micromega/sos_lib.mli79
-rw-r--r--plugins/nsatz/g_nsatz.mlg (renamed from plugins/nsatz/g_nsatz.ml4)6
-rw-r--r--plugins/nsatz/nsatz.ml2
-rw-r--r--plugins/omega/PreOmega.v8
-rw-r--r--plugins/omega/coq_omega.ml23
-rw-r--r--plugins/omega/g_omega.mlg (renamed from plugins/omega/g_omega.ml4)9
-rw-r--r--plugins/omega/omega.ml2
-rw-r--r--plugins/quote/g_quote.mlg (renamed from plugins/quote/g_quote.ml4)19
-rw-r--r--plugins/quote/quote.ml2
-rw-r--r--plugins/romega/const_omega.ml10
-rw-r--r--plugins/romega/g_romega.mlg (renamed from plugins/romega/g_romega.ml4)20
-rw-r--r--plugins/romega/refl_omega.ml5
-rw-r--r--plugins/rtauto/g_rtauto.mlg (renamed from plugins/rtauto/g_rtauto.ml4)5
-rw-r--r--plugins/rtauto/refl_tauto.ml8
-rw-r--r--plugins/setoid_ring/g_newring.ml49
-rw-r--r--plugins/setoid_ring/newring.ml196
-rw-r--r--plugins/setoid_ring/newring.mli3
-rw-r--r--plugins/setoid_ring/newring_ast.ml2
-rw-r--r--plugins/setoid_ring/newring_ast.mli2
-rw-r--r--plugins/ssr/ssrast.mli6
-rw-r--r--plugins/ssr/ssrbool.v936
-rw-r--r--plugins/ssr/ssrcommon.ml43
-rw-r--r--plugins/ssr/ssrcommon.mli4
-rw-r--r--plugins/ssr/ssreflect.v439
-rw-r--r--plugins/ssr/ssrelim.ml7
-rw-r--r--plugins/ssr/ssrequality.ml32
-rw-r--r--plugins/ssr/ssrfun.v487
-rw-r--r--plugins/ssr/ssrfwd.ml15
-rw-r--r--plugins/ssr/ssripats.ml85
-rw-r--r--plugins/ssr/ssrparser.ml474
-rw-r--r--plugins/ssr/ssrparser.mli8
-rw-r--r--plugins/ssr/ssrprinters.ml5
-rw-r--r--plugins/ssr/ssrtacticals.ml15
-rw-r--r--plugins/ssr/ssrtacticals.mli4
-rw-r--r--plugins/ssr/ssrvernac.ml438
-rw-r--r--plugins/ssr/ssrview.ml99
-rw-r--r--plugins/ssr/ssrview.mli6
-rw-r--r--plugins/ssrmatching/g_ssrmatching.ml4101
-rw-r--r--plugins/ssrmatching/ssrmatching.ml (renamed from plugins/ssrmatching/ssrmatching.ml4)184
-rw-r--r--plugins/ssrmatching/ssrmatching.mli258
-rw-r--r--plugins/ssrmatching/ssrmatching.v36
-rw-r--r--plugins/ssrmatching/ssrmatching_plugin.mlpack1
-rw-r--r--plugins/syntax/ascii_syntax.ml20
-rw-r--r--plugins/syntax/g_numeral.ml438
-rw-r--r--plugins/syntax/int31_syntax.ml23
-rw-r--r--plugins/syntax/nat_syntax.ml84
-rw-r--r--plugins/syntax/nat_syntax_plugin.mlpack1
-rw-r--r--plugins/syntax/numeral.ml142
-rw-r--r--plugins/syntax/numeral.mli17
-rw-r--r--plugins/syntax/numeral_notation_plugin.mlpack2
-rw-r--r--plugins/syntax/r_syntax.ml28
-rw-r--r--plugins/syntax/string_syntax.ml25
-rw-r--r--plugins/syntax/z_syntax.ml202
-rw-r--r--plugins/syntax/z_syntax_plugin.mlpack1
-rw-r--r--pretyping/arguments_renaming.ml2
-rw-r--r--pretyping/arguments_renaming.mli5
-rw-r--r--pretyping/cases.ml101
-rw-r--r--pretyping/cbv.ml31
-rw-r--r--pretyping/cbv.mli2
-rw-r--r--pretyping/classops.ml126
-rw-r--r--pretyping/classops.mli24
-rw-r--r--pretyping/coercion.ml85
-rw-r--r--pretyping/constr_matching.ml60
-rw-r--r--pretyping/constr_matching.mli2
-rw-r--r--pretyping/detyping.ml234
-rw-r--r--pretyping/detyping.mli12
-rw-r--r--pretyping/evarconv.ml109
-rw-r--r--pretyping/evarconv.mli8
-rw-r--r--pretyping/evardefine.ml23
-rw-r--r--pretyping/evarsolve.ml147
-rw-r--r--pretyping/geninterp.mli4
-rw-r--r--pretyping/glob_ops.ml60
-rw-r--r--pretyping/glob_ops.mli9
-rw-r--r--pretyping/glob_term.ml (renamed from intf/glob_term.ml)33
-rw-r--r--pretyping/heads.ml (renamed from library/heads.ml)4
-rw-r--r--pretyping/heads.mli (renamed from library/heads.mli)0
-rw-r--r--pretyping/indrec.ml13
-rw-r--r--pretyping/indrec.mli2
-rw-r--r--pretyping/inductiveops.ml154
-rw-r--r--pretyping/inductiveops.mli30
-rw-r--r--pretyping/locus.ml (renamed from intf/locus.ml)5
-rw-r--r--pretyping/locusops.ml4
-rw-r--r--pretyping/miscops.ml76
-rw-r--r--pretyping/miscops.mli36
-rw-r--r--pretyping/nativenorm.ml109
-rw-r--r--pretyping/nativenorm.mli2
-rw-r--r--pretyping/pattern.ml (renamed from intf/pattern.ml)16
-rw-r--r--pretyping/patternops.ml169
-rw-r--r--pretyping/patternops.mli11
-rw-r--r--pretyping/pretype_errors.ml2
-rw-r--r--pretyping/pretyping.ml158
-rw-r--r--pretyping/pretyping.mli2
-rw-r--r--pretyping/pretyping.mllib8
-rw-r--r--pretyping/program.ml4
-rw-r--r--pretyping/program.mli38
-rw-r--r--pretyping/recordops.ml72
-rw-r--r--pretyping/recordops.mli20
-rw-r--r--pretyping/reductionops.ml167
-rw-r--r--pretyping/reductionops.mli27
-rw-r--r--pretyping/retyping.ml23
-rw-r--r--pretyping/tacred.ml45
-rw-r--r--pretyping/tacred.mli11
-rw-r--r--pretyping/typeclasses.ml47
-rw-r--r--pretyping/typeclasses.mli50
-rw-r--r--pretyping/typeclasses_errors.ml8
-rw-r--r--pretyping/typeclasses_errors.mli10
-rw-r--r--pretyping/typing.ml428
-rw-r--r--pretyping/typing.mli12
-rw-r--r--pretyping/unification.ml182
-rw-r--r--pretyping/unification.mli3
-rw-r--r--pretyping/univdecls.ml52
-rw-r--r--pretyping/univdecls.mli21
-rw-r--r--pretyping/vnorm.ml73
-rw-r--r--printing/genprint.ml8
-rw-r--r--printing/genprint.mli8
-rw-r--r--printing/ppconstr.ml51
-rw-r--r--printing/ppconstr.mli13
-rw-r--r--printing/pputils.ml5
-rw-r--r--printing/pputils.mli3
-rw-r--r--printing/prettyp.ml61
-rw-r--r--printing/prettyp.mli34
-rw-r--r--printing/printer.ml217
-rw-r--r--printing/printer.mli97
-rw-r--r--printing/printing.mllib2
-rw-r--r--printing/printmod.ml19
-rw-r--r--printing/printmod.mli2
-rw-r--r--printing/proof_diffs.ml635
-rw-r--r--printing/proof_diffs.mli84
-rw-r--r--proofs/clenv.ml31
-rw-r--r--proofs/clenv.mli2
-rw-r--r--proofs/clenvtac.ml12
-rw-r--r--proofs/clenvtac.mli7
-rw-r--r--proofs/evar_refiner.ml8
-rw-r--r--proofs/goal.ml25
-rw-r--r--proofs/goal.mli5
-rw-r--r--proofs/goal_select.ml68
-rw-r--r--proofs/goal_select.mli26
-rw-r--r--proofs/logic.ml97
-rw-r--r--proofs/logic.mli15
-rw-r--r--proofs/miscprint.ml12
-rw-r--r--proofs/miscprint.mli7
-rw-r--r--proofs/pfedit.ml52
-rw-r--r--proofs/pfedit.mli9
-rw-r--r--proofs/proof.ml45
-rw-r--r--proofs/proof.mli6
-rw-r--r--proofs/proof_bullet.ml68
-rw-r--r--proofs/proof_bullet.mli19
-rw-r--r--proofs/proof_global.ml35
-rw-r--r--proofs/proof_global.mli18
-rw-r--r--proofs/proofs.mllib1
-rw-r--r--proofs/redexpr.ml15
-rw-r--r--proofs/refine.ml51
-rw-r--r--proofs/refiner.mli3
-rw-r--r--proofs/tacmach.ml8
-rw-r--r--proofs/tacmach.mli5
-rw-r--r--proofs/tactypes.ml (renamed from interp/tactypes.ml)38
-rw-r--r--stm/asyncTaskQueue.ml18
-rw-r--r--stm/coqworkmgrApi.ml4
-rw-r--r--stm/coqworkmgrApi.mli3
-rw-r--r--stm/proofBlockDelimiter.ml6
-rw-r--r--stm/proofBlockDelimiter.mli4
-rw-r--r--stm/proofworkertop.mllib1
-rw-r--r--stm/queryworkertop.mllib1
-rw-r--r--stm/spawned.ml4
-rw-r--r--stm/stm.ml234
-rw-r--r--stm/stm.mli18
-rw-r--r--stm/stm.mllib1
-rw-r--r--stm/tacworkertop.mllib1
-rw-r--r--stm/vernac_classifier.ml41
-rw-r--r--stm/vernac_classifier.mli6
-rw-r--r--tactics/auto.ml9
-rw-r--r--tactics/autorewrite.ml26
-rw-r--r--tactics/btermdn.ml4
-rw-r--r--tactics/class_tactics.ml54
-rw-r--r--tactics/contradiction.ml5
-rw-r--r--tactics/contradiction.mli2
-rw-r--r--tactics/eauto.ml11
-rw-r--r--tactics/elim.mli3
-rw-r--r--tactics/elimschemes.ml6
-rw-r--r--tactics/eqdecide.ml12
-rw-r--r--tactics/eqschemes.ml43
-rw-r--r--tactics/equality.ml63
-rw-r--r--tactics/equality.mli18
-rw-r--r--tactics/hints.ml241
-rw-r--r--tactics/hints.mli76
-rw-r--r--tactics/hipattern.ml12
-rw-r--r--tactics/hipattern.mli2
-rw-r--r--tactics/ind_tables.ml10
-rw-r--r--tactics/inv.ml33
-rw-r--r--tactics/inv.mli6
-rw-r--r--tactics/leminv.ml9
-rw-r--r--tactics/leminv.mli2
-rw-r--r--tactics/tacticals.ml73
-rw-r--r--tactics/tacticals.mli11
-rw-r--r--tactics/tactics.ml296
-rw-r--r--tactics/tactics.mli44
-rw-r--r--tactics/term_dnet.ml4
-rw-r--r--tactics/term_dnet.mli2
-rw-r--r--test-suite/Makefile148
-rw-r--r--test-suite/README.md31
-rw-r--r--test-suite/bugs/closed/1341.v2
-rw-r--r--test-suite/bugs/closed/1844.v2
-rw-r--r--test-suite/bugs/closed/1891.v2
-rw-r--r--test-suite/bugs/closed/1951.v2
-rw-r--r--test-suite/bugs/closed/1981.v2
-rw-r--r--test-suite/bugs/closed/2362.v2
-rw-r--r--test-suite/bugs/closed/2378.v96
-rw-r--r--test-suite/bugs/closed/2404.v4
-rw-r--r--test-suite/bugs/closed/2456.v2
-rw-r--r--test-suite/bugs/closed/2584.v2
-rw-r--r--test-suite/bugs/closed/2667.v4
-rw-r--r--test-suite/bugs/closed/2670.v8
-rw-r--r--test-suite/bugs/closed/2729.v4
-rw-r--r--test-suite/bugs/closed/2733.v15
-rw-r--r--test-suite/bugs/closed/2830.v10
-rw-r--r--test-suite/bugs/closed/2969.v2
-rw-r--r--test-suite/bugs/closed/3068.v2
-rw-r--r--test-suite/bugs/closed/3377.v3
-rw-r--r--test-suite/bugs/closed/3513.v2
-rw-r--r--test-suite/bugs/closed/3647.v6
-rw-r--r--test-suite/bugs/closed/3690.v7
-rw-r--r--test-suite/bugs/closed/3732.v2
-rw-r--r--test-suite/bugs/closed/3956.v8
-rw-r--r--test-suite/bugs/closed/4069.v2
-rw-r--r--test-suite/bugs/closed/4095.v2
-rw-r--r--test-suite/bugs/closed/4132.v2
-rw-r--r--test-suite/bugs/closed/4198.v2
-rw-r--r--test-suite/bugs/closed/4306.v6
-rw-r--r--test-suite/bugs/closed/4527.v8
-rw-r--r--test-suite/bugs/closed/4533.v11
-rw-r--r--test-suite/bugs/closed/4544.v3
-rw-r--r--test-suite/bugs/closed/4782.v2
-rw-r--r--test-suite/bugs/closed/4798.v2
-rw-r--r--test-suite/bugs/closed/4865.v2
-rw-r--r--test-suite/bugs/closed/4882.v50
-rw-r--r--test-suite/bugs/closed/5012.v17
-rw-r--r--test-suite/bugs/closed/5500.v35
-rw-r--r--test-suite/bugs/closed/5547.v16
-rw-r--r--test-suite/bugs/closed/5696.v5
-rw-r--r--test-suite/bugs/closed/5719.v9
-rw-r--r--test-suite/bugs/closed/7011.v16
-rw-r--r--test-suite/bugs/closed/7068.v6
-rw-r--r--test-suite/bugs/closed/7076.v4
-rw-r--r--test-suite/bugs/closed/7092.v70
-rw-r--r--test-suite/bugs/closed/7421.v39
-rw-r--r--test-suite/bugs/closed/7631.v2
-rw-r--r--test-suite/bugs/closed/7900.v53
-rw-r--r--test-suite/bugs/closed/7903.v4
-rw-r--r--test-suite/bugs/closed/8081.v4
-rw-r--r--test-suite/bugs/closed/8106.v4
-rw-r--r--test-suite/bugs/closed/8126.v13
-rw-r--r--test-suite/bugs/closed/8270.v15
-rw-r--r--test-suite/bugs/closed/8553.v7
-rw-r--r--test-suite/bugs/closed/8672.v5
-rw-r--r--test-suite/bugs/closed/bug_8544.v6
-rw-r--r--test-suite/bugs/closed/bug_8755.v6
-rw-r--r--test-suite/bugs/closed/bug_8794.v11
-rw-r--r--test-suite/bugs/closed/bug_8885.v8
-rw-r--r--test-suite/bugs/opened/3295.v4
-rwxr-xr-xtest-suite/check7
-rw-r--r--test-suite/complexity/injection.v2
-rwxr-xr-xtest-suite/coq-makefile/coqdoc1/run.sh10
-rwxr-xr-xtest-suite/coq-makefile/coqdoc2/run.sh8
-rwxr-xr-xtest-suite/coq-makefile/findlib-package/run.sh3
-rwxr-xr-xtest-suite/coq-makefile/mlpack1/run.sh2
-rwxr-xr-xtest-suite/coq-makefile/mlpack2/run.sh2
-rwxr-xr-xtest-suite/coq-makefile/multiroot/run.sh7
-rwxr-xr-xtest-suite/coq-makefile/native1/run.sh8
-rwxr-xr-xtest-suite/coq-makefile/plugin1/run.sh2
-rwxr-xr-xtest-suite/coq-makefile/plugin2/run.sh2
-rwxr-xr-xtest-suite/coq-makefile/plugin3/run.sh2
-rwxr-xr-xtest-suite/coq-makefile/quick2vo/run.sh4
-rwxr-xr-xtest-suite/coq-makefile/template/init.sh3
-rwxr-xr-xtest-suite/coq-makefile/template/path-init.sh1
-rwxr-xr-xtest-suite/coq-makefile/timing/precomputed-time-tests/run.sh7
-rwxr-xr-xtest-suite/coq-makefile/timing/run.sh27
-rwxr-xr-xtest-suite/coq-makefile/uninstall1/run.sh7
-rwxr-xr-xtest-suite/coq-makefile/uninstall2/run.sh7
-rwxr-xr-xtest-suite/coq-makefile/vio2vo/run.sh4
-rw-r--r--test-suite/coqchk/bug_8655.v1
-rw-r--r--test-suite/coqchk/bug_8876.v19
-rw-r--r--test-suite/coqchk/bug_8881.v23
-rw-r--r--test-suite/coqchk/include_primproj.v13
-rw-r--r--test-suite/coqdoc/links.html.out34
-rw-r--r--test-suite/coqdoc/links.tex.out34
-rw-r--r--test-suite/failure/check.v2
-rw-r--r--test-suite/ide/undo012.fake1
-rw-r--r--test-suite/ide/undo013.fake1
-rw-r--r--test-suite/ide/undo014.fake1
-rw-r--r--test-suite/ide/undo015.fake1
-rw-r--r--test-suite/ide/undo016.fake1
-rw-r--r--test-suite/interactive/PrimNotation.v64
-rwxr-xr-xtest-suite/misc/7595.sh5
-rw-r--r--test-suite/misc/7595/FOO.v39
-rw-r--r--test-suite/misc/7595/base.v28
-rwxr-xr-xtest-suite/misc/7704.sh7
-rw-r--r--test-suite/misc/aux7704.v6
-rwxr-xr-xtest-suite/misc/deps-checksum.sh1
-rwxr-xr-xtest-suite/misc/deps-order.sh9
-rwxr-xr-xtest-suite/misc/deps-utf8.sh9
-rwxr-xr-xtest-suite/misc/exitstatus.sh7
-rwxr-xr-xtest-suite/misc/poly-capture-global-univs.sh19
-rw-r--r--test-suite/misc/poly-capture-global-univs/_CoqProject9
-rw-r--r--test-suite/misc/poly-capture-global-univs/src/evil.ml49
-rw-r--r--test-suite/misc/poly-capture-global-univs/src/evilImpl.ml22
-rw-r--r--test-suite/misc/poly-capture-global-univs/src/evilImpl.mli2
-rw-r--r--test-suite/misc/poly-capture-global-univs/src/evil_plugin.mlpack2
-rw-r--r--test-suite/misc/poly-capture-global-univs/theories/evil.v13
-rwxr-xr-xtest-suite/misc/printers.sh5
-rwxr-xr-xtest-suite/misc/universes.sh5
-rw-r--r--test-suite/modules/PO.v4
-rw-r--r--test-suite/modules/Przyklad.v2
-rw-r--r--test-suite/output/Arguments_renaming.out6
-rw-r--r--test-suite/output/BadOptionValueType.out8
-rw-r--r--test-suite/output/BadOptionValueType.v4
-rw-r--r--test-suite/output/Cases.out2
-rw-r--r--test-suite/output/Cases.v4
-rw-r--r--test-suite/output/Deprecation.out3
-rw-r--r--test-suite/output/Deprecation.v6
-rw-r--r--test-suite/output/Errors.out8
-rw-r--r--test-suite/output/Errors.v6
-rw-r--r--test-suite/output/Notations.out14
-rw-r--r--test-suite/output/Notations3.out6
-rw-r--r--test-suite/output/Notations3.v11
-rw-r--r--test-suite/output/Notations4.out19
-rw-r--r--test-suite/output/Notations4.v72
-rw-r--r--test-suite/output/PrintInfos.out4
-rw-r--r--test-suite/output/PrintInfos.v4
-rw-r--r--test-suite/output/RecordMissingField.out4
-rw-r--r--test-suite/output/RecordMissingField.v8
-rw-r--r--test-suite/output/UnclosedBlocks.out1
-rw-r--r--test-suite/output/Unicode.out41
-rw-r--r--test-suite/output/Unicode.v28
-rw-r--r--test-suite/output/bug5778.out4
-rw-r--r--test-suite/output/bug6404.out4
-rw-r--r--test-suite/output/bug6404.v7
-rw-r--r--test-suite/output/ltac.v3
-rw-r--r--test-suite/output/ltac_missing_args.out14
-rw-r--r--test-suite/output/ssr_explain_match.out55
-rw-r--r--test-suite/output/ssr_explain_match.v23
-rw-r--r--test-suite/prerequisite/make_local.v3
-rw-r--r--test-suite/prerequisite/ssr_mini_mathcomp.v1472
-rw-r--r--test-suite/prerequisite/ssr_ssrsyntax1.v (renamed from clib/canary.mli)37
-rwxr-xr-xtest-suite/report.sh55
-rwxr-xr-xtest-suite/save-logs.sh19
-rw-r--r--test-suite/ssr/absevarprop.v96
-rw-r--r--test-suite/ssr/abstract_var2.v25
-rw-r--r--test-suite/ssr/binders.v55
-rw-r--r--test-suite/ssr/binders_of.v23
-rw-r--r--test-suite/ssr/caseview.v17
-rw-r--r--test-suite/ssr/congr.v34
-rw-r--r--test-suite/ssr/deferclear.v37
-rw-r--r--test-suite/ssr/delayed_clear_rename.v (renamed from test-suite/success/ssr_delayed_clear_rename.v)0
-rw-r--r--test-suite/ssr/dependent_type_err.v20
-rw-r--r--test-suite/ssr/derive_inversion.v29
-rw-r--r--test-suite/ssr/elim.v279
-rw-r--r--test-suite/ssr/elim2.v74
-rw-r--r--test-suite/ssr/elim_pattern.v27
-rw-r--r--test-suite/ssr/first_n.v21
-rw-r--r--test-suite/ssr/gen_have.v174
-rw-r--r--test-suite/ssr/gen_pattern.v33
-rw-r--r--test-suite/ssr/have_TC.v50
-rw-r--r--test-suite/ssr/have_transp.v48
-rw-r--r--test-suite/ssr/have_view_idiom.v18
-rw-r--r--test-suite/ssr/havesuff.v85
-rw-r--r--test-suite/ssr/if_isnt.v (renamed from plugins/fourier/Fourier.v)16
-rw-r--r--test-suite/ssr/intro_beta.v25
-rw-r--r--test-suite/ssr/intro_noop.v37
-rw-r--r--test-suite/ssr/ipat_clear_if_id.v23
-rw-r--r--test-suite/ssr/ipatalternation.v18
-rw-r--r--test-suite/ssr/ltac_have.v39
-rw-r--r--test-suite/ssr/ltac_in.v26
-rw-r--r--test-suite/ssr/move_after.v (renamed from theories/Compat/Coq86.v)12
-rw-r--r--test-suite/ssr/multiview.v58
-rw-r--r--test-suite/ssr/occarrow.v (renamed from clib/canary.ml)25
-rw-r--r--test-suite/ssr/patnoX.v18
-rw-r--r--test-suite/ssr/pattern.v32
-rw-r--r--test-suite/ssr/primproj.v164
-rw-r--r--test-suite/ssr/rewpatterns.v146
-rw-r--r--test-suite/ssr/rewrite_illtyped.v9
-rw-r--r--test-suite/ssr/set_lamda.v27
-rw-r--r--test-suite/ssr/set_pattern.v64
-rw-r--r--test-suite/ssr/ssrpattern.v7
-rw-r--r--test-suite/ssr/ssrsyntax2.v20
-rw-r--r--test-suite/ssr/tc.v39
-rw-r--r--test-suite/ssr/typeof.v22
-rw-r--r--test-suite/ssr/unfold_Opaque.v (renamed from plugins/fourier/g_fourier.ml4)12
-rw-r--r--test-suite/ssr/unkeyed.v31
-rw-r--r--test-suite/ssr/view_case.v31
-rw-r--r--test-suite/ssr/wlog_suff.v28
-rw-r--r--test-suite/ssr/wlogletin.v50
-rw-r--r--test-suite/ssr/wlong_intro.v20
-rw-r--r--test-suite/stm/Nijmegen_QArithSternBrocot_Zaux.v714
-rw-r--r--test-suite/success/AdvancedTypeClasses.v4
-rw-r--r--test-suite/success/BracketsWithGoalSelector.v9
-rw-r--r--test-suite/success/Case11.v4
-rw-r--r--test-suite/success/Case17.v14
-rw-r--r--test-suite/success/Compat88.v18
-rw-r--r--test-suite/success/CompatCurrentFlag.v4
-rw-r--r--test-suite/success/CompatOldFlag.v4
-rw-r--r--test-suite/success/CompatPreviousFlag.v4
-rw-r--r--test-suite/success/FunindExtraction_compat86.v506
-rw-r--r--test-suite/success/Hints.v30
-rw-r--r--test-suite/success/ImplicitArguments.v2
-rw-r--r--test-suite/success/ImplicitTactic.v16
-rw-r--r--test-suite/success/Inductive.v4
-rw-r--r--test-suite/success/Injection.v12
-rw-r--r--test-suite/success/Inversion.v4
-rw-r--r--test-suite/success/LraTest.v (renamed from test-suite/success/Fourier.v)10
-rw-r--r--test-suite/success/LtacDeprecation.v32
-rw-r--r--test-suite/success/Notations2.v28
-rw-r--r--test-suite/success/NumeralNotations.v302
-rw-r--r--test-suite/success/ROmega4.v6
-rw-r--r--test-suite/success/RecTutorial.v14
-rw-r--r--test-suite/success/Record.v2
-rw-r--r--test-suite/success/Scopes.v2
-rw-r--r--test-suite/success/Typeclasses.v4
-rw-r--r--test-suite/success/apply.v25
-rw-r--r--test-suite/success/attribute-syntax.v23
-rw-r--r--test-suite/success/dependentind.v2
-rw-r--r--test-suite/success/destruct.v1
-rw-r--r--test-suite/success/evars.v2
-rw-r--r--test-suite/success/goal_selector.v14
-rw-r--r--test-suite/success/implicit.v12
-rw-r--r--test-suite/success/intros.v24
-rw-r--r--test-suite/success/letproj.v2
-rw-r--r--test-suite/success/mutual_record.v57
-rw-r--r--test-suite/success/primitiveproj.v30
-rw-r--r--test-suite/success/refine.v4
-rw-r--r--test-suite/success/rewrite.v6
-rw-r--r--test-suite/success/sideff.v2
-rw-r--r--test-suite/success/uniform_inductive_parameters.v13
-rw-r--r--test-suite/success/univers.v2
-rw-r--r--test-suite/success/vm_records.v40
-rwxr-xr-xtest-suite/tools/update-compat/run.sh9
-rw-r--r--test-suite/unit-tests/.merlin.in6
-rw-r--r--test-suite/unit-tests/clib/inteq.ml15
-rw-r--r--test-suite/unit-tests/clib/unicode_tests.ml17
-rw-r--r--test-suite/unit-tests/printing/proof_diffs_test.ml333
-rw-r--r--test-suite/unit-tests/src/utest.ml76
-rw-r--r--test-suite/unit-tests/src/utest.mli18
-rw-r--r--test-suite/vio/numeral.v21
-rw-r--r--theories/Arith/Compare_dec.v6
-rw-r--r--theories/Bool/Bool.v7
-rw-r--r--theories/Compat/Coq88.v16
-rw-r--r--theories/Compat/Coq89.v (renamed from ide/ide_slave.mli)3
-rw-r--r--theories/FSets/FMapFacts.v2
-rw-r--r--theories/FSets/FMapFullAVL.v6
-rw-r--r--theories/FSets/FSetEqProperties.v4
-rw-r--r--theories/Init/Datatypes.v1
-rw-r--r--theories/Init/Decimal.v14
-rw-r--r--theories/Init/Logic.v7
-rw-r--r--theories/Init/Nat.v4
-rw-r--r--theories/Init/Peano.v1
-rw-r--r--theories/Init/Prelude.v19
-rw-r--r--theories/Init/Specif.v26
-rw-r--r--theories/Logic/Berardi.v7
-rw-r--r--theories/Logic/Diaconescu.v2
-rw-r--r--theories/Logic/EqdepFacts.v2
-rw-r--r--theories/MSets/MSetEqProperties.v4
-rw-r--r--theories/NArith/BinNat.v80
-rw-r--r--theories/NArith/BinNatDef.v9
-rw-r--r--theories/NArith/Ndec.v4
-rw-r--r--theories/NArith/Ndigits.v43
-rw-r--r--theories/NArith/Ndiv_def.v6
-rw-r--r--theories/NArith/Nsqrt_def.v8
-rw-r--r--theories/Numbers/AltBinNotations.v69
-rw-r--r--theories/Numbers/BinNums.v14
-rw-r--r--theories/Numbers/Cyclic/Int31/Cyclic31.v20
-rw-r--r--theories/Numbers/Cyclic/Int31/Int31.v10
-rw-r--r--theories/Numbers/DecimalString.v20
-rw-r--r--theories/Numbers/Integer/Abstract/ZBits.v6
-rw-r--r--theories/Numbers/Integer/Abstract/ZDivEucl.v2
-rw-r--r--theories/Numbers/Natural/Abstract/NBits.v6
-rw-r--r--theories/PArith/BinPos.v82
-rw-r--r--theories/PArith/BinPosDef.v13
-rw-r--r--theories/Program/Tactics.v2
-rw-r--r--theories/Reals/Machin.v36
-rw-r--r--theories/Reals/PSeries_reg.v29
-rw-r--r--theories/Reals/R_sqrt.v20
-rw-r--r--theories/Reals/Ranalysis5.v90
-rw-r--r--theories/Reals/Ratan.v238
-rw-r--r--theories/Reals/Rbasic_fun.v4
-rw-r--r--theories/Reals/Rderiv.v6
-rw-r--r--theories/Reals/Reals.v1
-rw-r--r--theories/Reals/Rlimit.v8
-rw-r--r--theories/Reals/Rpower.v24
-rw-r--r--theories/Reals/Rsqrt_def.v2
-rw-r--r--theories/Reals/Rtrigo.v2
-rw-r--r--theories/Reals/Rtrigo1.v40
-rw-r--r--theories/Reals/Rtrigo_calc.v1
-rw-r--r--theories/Strings/Ascii.v34
-rw-r--r--theories/Strings/BinaryString.v147
-rw-r--r--theories/Strings/HexString.v229
-rw-r--r--theories/Strings/OctalString.v179
-rw-r--r--theories/Strings/String.v34
-rw-r--r--theories/Structures/GenericMinMax.v2
-rw-r--r--theories/Unicode/Utf8_core.v6
-rw-r--r--theories/Vectors/VectorDef.v1
-rw-r--r--theories/ZArith/BinInt.v56
-rw-r--r--theories/ZArith/BinIntDef.v15
-rw-r--r--theories/ZArith/ZArith_dec.v2
-rw-r--r--theories/ZArith/Zabs.v8
-rw-r--r--theories/ZArith/Zcompare.v14
-rw-r--r--theories/ZArith/Zdiv.v6
-rw-r--r--theories/ZArith/Zeven.v4
-rw-r--r--theories/ZArith/Zmax.v18
-rw-r--r--theories/ZArith/Zmin.v18
-rw-r--r--theories/ZArith/Znumtheory.v28
-rw-r--r--theories/ZArith/Zorder.v28
-rw-r--r--theories/ZArith/Zpow_facts.v4
-rw-r--r--theories/ZArith/Zquot.v46
-rw-r--r--tools/CoqMakefile.in45
-rw-r--r--tools/coq-font-lock.el137
-rw-r--r--tools/coq_makefile.ml6
-rw-r--r--tools/coqdep.ml53
-rw-r--r--tools/coqdep_common.ml37
-rw-r--r--tools/coqdep_common.mli2
-rw-r--r--tools/coqdoc/index.ml16
-rw-r--r--tools/coqdoc/index.mli2
-rw-r--r--tools/coqdoc/output.ml6
-rw-r--r--tools/coqworkmgr.ml2
-rw-r--r--tools/fake_ide.ml22
-rw-r--r--tools/gallina-db.el240
-rw-r--r--tools/gallina-syntax.el980
-rw-r--r--tools/gallina.el142
-rw-r--r--tools/gallina.ml63
-rw-r--r--tools/gallina_lexer.mll126
-rw-r--r--tools/inferior-coq.el324
-rw-r--r--topbin/coqproofworker_bin.ml (renamed from stm/proofworkertop.ml)6
-rw-r--r--topbin/coqqueryworker_bin.ml (renamed from stm/queryworkertop.ml)5
-rw-r--r--topbin/coqtacticworker_bin.ml (renamed from stm/tacworkertop.ml)5
-rw-r--r--topbin/coqtop_bin.ml (renamed from toplevel/coqtop_opt_bin.ml)2
-rw-r--r--topbin/coqtop_byte_bin.ml (renamed from toplevel/coqtop_byte_bin.ml)2
-rw-r--r--toplevel/coqargs.ml51
-rw-r--r--toplevel/coqargs.mli4
-rw-r--r--toplevel/coqinit.ml32
-rw-r--r--toplevel/coqinit.mli4
-rw-r--r--toplevel/coqloop.ml217
-rw-r--r--toplevel/coqloop.mli17
-rw-r--r--toplevel/coqtop.ml220
-rw-r--r--toplevel/coqtop.mli24
-rw-r--r--toplevel/g_toplevel.mlg54
-rw-r--r--toplevel/toplevel.mllib4
-rw-r--r--toplevel/usage.ml3
-rw-r--r--toplevel/vernac.ml36
-rw-r--r--toplevel/vernac.mli5
-rw-r--r--toplevel/workerLoop.ml (renamed from stm/workerLoop.ml)20
-rw-r--r--toplevel/workerLoop.mli (renamed from stm/workerLoop.mli)8
-rw-r--r--vernac/assumptions.mli4
-rw-r--r--vernac/auto_ind_decl.ml54
-rw-r--r--vernac/auto_ind_decl.mli2
-rw-r--r--vernac/class.ml24
-rw-r--r--vernac/class.mli9
-rw-r--r--vernac/classes.ml63
-rw-r--r--vernac/classes.mli16
-rw-r--r--vernac/comAssumption.ml11
-rw-r--r--vernac/comAssumption.mli9
-rw-r--r--vernac/comDefinition.ml48
-rw-r--r--vernac/comDefinition.mli2
-rw-r--r--vernac/comFixpoint.ml22
-rw-r--r--vernac/comFixpoint.mli14
-rw-r--r--vernac/comInductive.ml157
-rw-r--r--vernac/comInductive.mli11
-rw-r--r--vernac/comProgramFixpoint.ml24
-rw-r--r--vernac/declareDef.mli10
-rw-r--r--vernac/egramcoq.ml (renamed from parsing/egramcoq.ml)152
-rw-r--r--vernac/egramcoq.mli (renamed from parsing/egramcoq.mli)5
-rw-r--r--vernac/egramml.ml (renamed from parsing/egramml.ml)11
-rw-r--r--vernac/egramml.mli (renamed from parsing/egramml.mli)4
-rw-r--r--vernac/explainErr.ml6
-rw-r--r--vernac/g_proofs.mlg140
-rw-r--r--vernac/g_vernac.mlg1208
-rw-r--r--vernac/himsg.ml121
-rw-r--r--vernac/himsg.mli4
-rw-r--r--vernac/indschemes.ml2
-rw-r--r--vernac/indschemes.mli6
-rw-r--r--vernac/lemmas.ml30
-rw-r--r--vernac/lemmas.mli10
-rw-r--r--vernac/metasyntax.ml413
-rw-r--r--vernac/metasyntax.mli3
-rw-r--r--vernac/misctypes.ml75
-rw-r--r--vernac/mltop.ml9
-rw-r--r--vernac/mltop.mli3
-rw-r--r--vernac/obligations.ml68
-rw-r--r--vernac/obligations.mli11
-rw-r--r--vernac/ppvernac.ml (renamed from printing/ppvernac.ml)173
-rw-r--r--vernac/ppvernac.mli (renamed from printing/ppvernac.mli)0
-rw-r--r--vernac/proof_using.ml12
-rw-r--r--vernac/pvernac.ml55
-rw-r--r--vernac/pvernac.mli36
-rw-r--r--vernac/record.ml307
-rw-r--r--vernac/record.mli18
-rw-r--r--vernac/search.ml25
-rw-r--r--vernac/search.mli5
-rw-r--r--vernac/topfmt.ml155
-rw-r--r--vernac/topfmt.mli11
-rw-r--r--vernac/vernac.mllib17
-rw-r--r--vernac/vernacentries.ml534
-rw-r--r--vernac/vernacentries.mli40
-rw-r--r--vernac/vernacexpr.ml (renamed from intf/vernacexpr.ml)250
-rw-r--r--vernac/vernacinterp.ml12
-rw-r--r--vernac/vernacinterp.mli10
-rw-r--r--vernac/vernacprop.ml1
1111 files changed, 35436 insertions, 26659 deletions
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 #????
+<!-- If there is a user-visible change in coqc/coqtop/coqchk/coq_makefile behavior and testing is not prohibitively expensive: -->
+<!-- (Otherwise, remove this line.) -->
+- [ ] Added / updated test-suite
<!-- If this is a feature pull request / breaks compatibility: -->
<!-- (Otherwise, remove these lines.) -->
-- [ ] 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.in
index d60f5037..404a7e79 100644
--- a/.merlin
+++ b/.merlin.in
@@ -10,8 +10,6 @@ S kernel
B kernel
S kernel/byterun
B kernel/byterun
-S intf
-B intf
S library
B library
S engine
@@ -34,6 +32,8 @@ S vernac
B vernac
S toplevel
B toplevel
+S topbin
+B topbin
S plugins/ltac
B plugins/ltac
S API
diff --git a/CHANGES b/CHANGES.md
index ab63d8ec..56e185e8 100644
--- a/CHANGES
+++ b/CHANGES.md
@@ -1,3 +1,216 @@
+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
+ <https://gist.github.com/JasonGross/5d4558edf8f5c2c548a3d96c17820169>
+ 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
===========================
@@ -20,7 +233,7 @@ Kernel
Windows installer
- The Windows installer now includes many more external packages that can be
-individually selected for installation.
+ 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).
@@ -30,10 +243,10 @@ 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 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
+- Fix a critical bug with universe polymorphism and `vm_compute` (#7723). Was
present since 8.5.
Notations
@@ -57,14 +270,14 @@ 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
+ 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.
+- 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
@@ -114,7 +327,7 @@ Tactics
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
+ 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.
@@ -299,7 +512,7 @@ Improvements around some error messages.
Many bug fixes including two important ones:
-- BZ#5730: CoqIDE becomes unresponsive on file open.
+- 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).
@@ -349,7 +562,7 @@ Tactics
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
+- 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.
@@ -395,7 +608,7 @@ Standard Library
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).
+- 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
@@ -470,12 +683,12 @@ 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 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).
@@ -2651,7 +2864,7 @@ Tactics
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)
+- 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
@@ -3228,11 +3441,11 @@ Incompatibilities
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)
+- 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
@@ -3245,18 +3458,18 @@ 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)
+ - 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 (BZ#192)
+ LetTac (#1402)
Changes from V7.2 to V7.3
=========================
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/<user>/.config/coq/coqiderc under Linux, or
- C:\Documents and Settings\<user>\.config\coq\coqiderc under Windows)
- and replace any occurrence of MOD4 by MOD1.
-
diff --git a/META.coq b/META.coq.in
index 30bfdd67..b2924e32 100644
--- a/META.coq
+++ b/META.coq.in
@@ -1,15 +1,27 @@
# TODO: Generate automatically with Dune
description = "The Coq Proof Assistant Plugin API"
-version = "8.8"
+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.8"
+ version = "8.9"
directory = "config"
@@ -17,7 +29,7 @@ package "config" (
package "clib" (
description = "Base General Coq Library"
- version = "8.8"
+ version = "8.9"
directory = "clib"
requires = "num, str, unix, threads"
@@ -29,7 +41,7 @@ package "clib" (
package "lib" (
description = "Base Coq-Specific Library"
- version = "8.8"
+ version = "8.9"
directory = "lib"
@@ -43,7 +55,7 @@ package "lib" (
package "vm" (
description = "Coq VM"
- version = "8.8"
+ version = "8.9"
directory = "kernel/byterun"
@@ -57,15 +69,12 @@ package "vm" (
# 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"
+ version = "8.9"
directory = "kernel"
@@ -79,7 +88,7 @@ package "kernel" (
package "library" (
description = "Coq Libraries (vo) support"
- version = "8.8"
+ version = "8.9"
requires = "coq.kernel"
@@ -90,23 +99,10 @@ package "library" (
)
-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"
+ version = "8.9"
requires = "coq.library"
directory = "engine"
@@ -119,7 +115,7 @@ package "engine" (
package "pretyping" (
description = "Coq Pretyper"
- version = "8.8"
+ version = "8.9"
requires = "coq.engine"
directory = "pretyping"
@@ -132,7 +128,7 @@ package "pretyping" (
package "interp" (
description = "Coq Term Interpretation"
- version = "8.8"
+ version = "8.9"
requires = "coq.pretyping"
directory = "interp"
@@ -142,22 +138,10 @@ package "interp" (
)
-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"
+ version = "8.9"
requires = "coq.interp"
directory = "proofs"
@@ -170,7 +154,7 @@ package "proofs" (
package "parsing" (
description = "Coq Parsing Engine"
- version = "8.8"
+ version = "8.9"
requires = "camlp5.gramlib, coq.proofs"
directory = "parsing"
@@ -183,7 +167,7 @@ package "parsing" (
package "printing" (
description = "Coq Printing Engine"
- version = "8.8"
+ version = "8.9"
requires = "coq.parsing"
directory = "printing"
@@ -196,7 +180,7 @@ package "printing" (
package "tactics" (
description = "Coq Basic Tactics"
- version = "8.8"
+ version = "8.9"
requires = "coq.printing"
directory = "tactics"
@@ -209,7 +193,7 @@ package "tactics" (
package "vernac" (
description = "Coq Vernacular Interpreter"
- version = "8.8"
+ version = "8.9"
requires = "coq.tactics"
directory = "vernac"
@@ -222,7 +206,7 @@ package "vernac" (
package "stm" (
description = "Coq State Transactional Machine"
- version = "8.8"
+ version = "8.9"
requires = "coq.vernac"
directory = "stm"
@@ -235,7 +219,7 @@ package "stm" (
package "toplevel" (
description = "Coq Toplevel"
- version = "8.8"
+ version = "8.9"
requires = "coq.stm"
directory = "toplevel"
@@ -248,7 +232,7 @@ package "toplevel" (
package "idetop" (
description = "Coq IDE Libraries"
- version = "8.8"
+ version = "8.9"
requires = "coq.toplevel"
directory = "ide"
@@ -262,7 +246,7 @@ package "idetop" (
package "ide" (
description = "Coq IDE Libraries"
- version = "8.8"
+ version = "8.9"
# XXX Add GTK
requires = "coq.toplevel"
@@ -276,14 +260,14 @@ package "ide" (
package "plugins" (
description = "Coq built-in plugins"
- version = "8.8"
+ version = "8.9"
directory = "plugins"
package "ltac" (
description = "Coq LTAC Plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.stm"
directory = "ltac"
@@ -296,7 +280,7 @@ package "plugins" (
package "tauto" (
description = "Coq tauto plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.ltac"
directory = "ltac"
@@ -308,7 +292,7 @@ package "plugins" (
package "omega" (
description = "Coq omega plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.ltac"
directory = "omega"
@@ -320,7 +304,7 @@ package "plugins" (
package "romega" (
description = "Coq romega plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.omega"
directory = "romega"
@@ -332,7 +316,7 @@ package "plugins" (
package "micromega" (
description = "Coq micromega plugin"
- version = "8.8"
+ version = "8.9"
requires = "num,coq.plugins.ltac"
directory = "micromega"
@@ -344,7 +328,7 @@ package "plugins" (
package "quote" (
description = "Coq quote plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.ltac"
directory = "quote"
@@ -356,7 +340,7 @@ package "plugins" (
package "newring" (
description = "Coq newring plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.quote"
directory = "setoid_ring"
@@ -365,22 +349,10 @@ package "plugins" (
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"
+ version = "8.9"
requires = "coq.plugins.ltac"
directory = "extraction"
@@ -392,7 +364,7 @@ package "plugins" (
package "cc" (
description = "Coq cc plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.ltac"
directory = "cc"
@@ -404,7 +376,7 @@ package "plugins" (
package "ground" (
description = "Coq ground plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.ltac"
directory = "firstorder"
@@ -416,7 +388,7 @@ package "plugins" (
package "rtauto" (
description = "Coq rtauto plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.ltac"
directory = "rtauto"
@@ -428,7 +400,7 @@ package "plugins" (
package "btauto" (
description = "Coq btauto plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.ltac"
directory = "btauto"
@@ -440,7 +412,7 @@ package "plugins" (
package "recdef" (
description = "Coq recdef plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.extraction"
directory = "funind"
@@ -452,7 +424,7 @@ package "plugins" (
package "nsatz" (
description = "Coq nsatz plugin"
- version = "8.8"
+ version = "8.9"
requires = "num,coq.plugins.ltac"
directory = "nsatz"
@@ -464,7 +436,7 @@ package "plugins" (
package "natsyntax" (
description = "Coq natsyntax plugin"
- version = "8.8"
+ version = "8.9"
requires = ""
directory = "syntax"
@@ -476,7 +448,7 @@ package "plugins" (
package "zsyntax" (
description = "Coq zsyntax plugin"
- version = "8.8"
+ version = "8.9"
requires = ""
directory = "syntax"
@@ -488,7 +460,7 @@ package "plugins" (
package "rsyntax" (
description = "Coq rsyntax plugin"
- version = "8.8"
+ version = "8.9"
requires = ""
directory = "syntax"
@@ -500,7 +472,7 @@ package "plugins" (
package "int31syntax" (
description = "Coq int31syntax plugin"
- version = "8.8"
+ version = "8.9"
requires = ""
directory = "syntax"
@@ -512,7 +484,7 @@ package "plugins" (
package "asciisyntax" (
description = "Coq asciisyntax plugin"
- version = "8.8"
+ version = "8.9"
requires = ""
directory = "syntax"
@@ -524,7 +496,7 @@ package "plugins" (
package "stringsyntax" (
description = "Coq stringsyntax plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.asciisyntax"
directory = "syntax"
@@ -536,7 +508,7 @@ package "plugins" (
package "derive" (
description = "Coq derive plugin"
- version = "8.8"
+ version = "8.9"
requires = ""
directory = "derive"
@@ -548,7 +520,7 @@ package "plugins" (
package "ssrmatching" (
description = "Coq ssrmatching plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.ltac"
directory = "ssrmatching"
@@ -560,7 +532,7 @@ package "plugins" (
package "ssreflect" (
description = "Coq ssreflect plugin"
- version = "8.8"
+ version = "8.9"
requires = "coq.plugins.ssrmatching"
directory = "ssr"
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:
@@ -198,12 +173,29 @@ 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,32 +89,14 @@ 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
######################################################################
@@ -139,23 +106,6 @@ 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
######################################################################
@@ -229,34 +179,13 @@ doc/stdlib/FullLibrary.pdf: $(DOCCOMMON) doc/stdlib/FullLibrary.coqdoc.tex doc/s
../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
+(** {6 Lists as arrays} *)
-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 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 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 mem_f cmp x l = List.exists (cmp x) l
+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 intersect cmp l1 l2 =
- filter (fun x -> mem_f cmp x l2) l1
+let map_filter_i f l =
+ map_filter_i_loop' f 0 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
+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 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 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 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
+ if l2 = [] then x else raise e
-let iteri f l = fold_left_i (fun i _ x -> f i x) 0 () l
+(* 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_all_i p =
- let rec for_all_p i = function
- | [] -> true
- | a::l -> p i a && for_all_p (i+1) l
+let fold_map = fold_left_map
+
+(* (* 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
- for_all_p
+ let (e',lrev) = List.fold_left g (e,[]) l in
+ (e',List.rev lrev)
+*)
+
+(* 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 fold_map' = fold_right_map
+
+let on_snd f (x,y) = (x,f y)
+
+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 fold_right2_map f l l' e =
+ List.fold_right2 (fun x x' (l,e) -> let (y,e) = f x x' e in (y::l,e)) l l' ([],e)
+
+let fold_left3_map f e l l' l'' =
+ on_snd List.rev @@
+ fold_left3 (fun (e,l) x x' x'' -> let (e,y) = f e x x' x'' in (e,y::l)) (e,[]) l l' l''
+
+let fold_left4_map f e l1 l2 l3 l4 =
+ on_snd List.rev @@
+ fold_left4 (fun (e,l) x1 x2 x3 x4 -> let (e,y) = f e x1 x2 x3 x4 in (e,y::l)) (e,[]) l1 l2 l3 l4
+
+(** {6 Splitting} *)
-let except cmp x l = List.filter (fun y -> not (cmp x y)) l
+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
+ | b :: l when p b -> l
+ | b :: l -> b :: remove_first p l
| [] -> raise Not_found
let extract_first p li =
let rec loop rev_left = function
| [] -> raise Not_found
- | x::right ->
+ | x :: right ->
if p x then List.rev_append rev_left right, x
else loop (x :: rev_left) right
- in loop [] li
+ 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
+ | 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
-
-let for_all2eq f l1 l2 =
- try List.for_all2 f l1 l2 with Invalid_argument _ -> false
-
-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 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 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
-
-(* FIXME: again, generic hash function *)
-
-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)
-
-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 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 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 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)
-
-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 map_filter f l =
- let c = { head = Obj.magic 0; tail = [] } in
- map_filter_loop f c l;
- c.tail
-
-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 map_filter_i f l =
- let c = { head = Obj.magic 0; tail = [] } in
- map_filter_i_loop f 0 c l;
- c.tail
-
-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"
+ | 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/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 [
"<dir> Where to install man files";
"-docdir", arg_string_option (fun p docdir -> { p with docdir }),
"<dir> Where to install doc files";
- "-emacslib", arg_string_option (fun p emacslib -> { p with emacslib }),
- "<dir> Where to install emacs files";
"-coqdocdir", arg_string_option (fun p coqdocdir -> { p with coqdocdir }),
"<dir> Where to install Coqdoc style files";
"-ocamlfind", arg_string_option (fun p ocamlfindcmd -> { p with ocamlfindcmd }),
@@ -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"
@@ -572,6 +576,9 @@ let camlbin, caml_version, camllib, findlib_version =
if is_executable (camlbin / "ocamllex")
then reset_caml_lex camlexec (camlbin / "ocamllex") in
let () =
+ if is_executable (camlbin / "ocamlyacc")
+ then reset_caml_yacc camlexec (camlbin / "ocamlyacc") in
+ let () =
if is_executable (camlbin / "ocaml")
then reset_caml_top camlexec (camlbin / "ocaml") in
camlbin, caml_version, camllib, findlib_version
@@ -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 *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+type loc = {
+ loc_start : Lexing.position;
+ loc_end : Lexing.position;
+}
+
+type code = { code : string }
+
+type user_symbol =
+| Ulist1 of user_symbol
+| Ulist1sep of user_symbol * string
+| Ulist0 of user_symbol
+| Ulist0sep of user_symbol * string
+| Uopt of user_symbol
+| Uentry of string
+| Uentryl of string * int
+
+type token_data =
+| TokNone
+| TokName of string
+
+type ext_token =
+| ExtTerminal of string
+| ExtNonTerminal of user_symbol * token_data
+
+type tactic_rule = {
+ tac_toks : ext_token list;
+ tac_body : code;
+}
+
+type level = string
+
+type position =
+| First
+| Last
+| Before of level
+| After of level
+| Level of level
+
+type assoc =
+| LeftA
+| RightA
+| NonA
+
+type gram_symbol =
+| GSymbString of string
+| GSymbQualid of string * level option
+| GSymbParen of gram_symbol list
+| GSymbProd of gram_prod list
+
+and gram_prod = {
+ gprod_symbs : (string option * gram_symbol list) list;
+ gprod_body : code;
+}
+
+type gram_rule = {
+ grule_label : string option;
+ grule_assoc : assoc option;
+ grule_prods : gram_prod list;
+}
+
+type grammar_entry = {
+ gentry_name : string;
+ gentry_pos : position option;
+ gentry_rules : gram_rule list;
+}
+
+type grammar_ext = {
+ gramext_name : string;
+ gramext_globals : string list;
+ gramext_entries : grammar_entry list;
+}
+
+type tactic_ext = {
+ tacext_name : string;
+ tacext_level : int option;
+ tacext_deprecated : code option;
+ tacext_rules : tactic_rule list;
+}
+
+type node =
+| Code of code
+| Comment of string
+| DeclarePlugin of string
+| GramExt of grammar_ext
+| VernacExt
+| TacticExt of tactic_ext
+
+type t = node list
diff --git a/coqpp/coqpp_lex.mll b/coqpp/coqpp_lex.mll
new file mode 100644
index 00000000..bfa4e2b5
--- /dev/null
+++ b/coqpp/coqpp_lex.mll
@@ -0,0 +1,168 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+{
+
+open Lexing
+open Coqpp_parse
+
+type mode =
+| OCaml
+| Extend
+
+exception Lex_error of Coqpp_ast.loc * string
+
+let loc lexbuf = {
+ Coqpp_ast.loc_start = lexeme_start_p lexbuf;
+ Coqpp_ast.loc_end = lexeme_end_p lexbuf;
+}
+
+let newline lexbuf =
+ let pos = lexbuf.lex_curr_p in
+ let pos = { pos with pos_lnum = pos.pos_lnum + 1; pos_bol = pos.pos_cnum } in
+ lexbuf.lex_curr_p <- pos
+
+let num_comments = ref 0
+let num_braces = ref 0
+
+let mode () = if !num_braces = 0 then Extend else OCaml
+
+let comment_buf = Buffer.create 512
+let ocaml_buf = Buffer.create 512
+let string_buf = Buffer.create 512
+
+let lex_error lexbuf msg =
+ raise (Lex_error (loc lexbuf, msg))
+
+let lex_unexpected_eof lexbuf where =
+ lex_error lexbuf (Printf.sprintf "Unexpected end of file in %s" where)
+
+let start_comment _ =
+ let () = incr num_comments in
+ Buffer.add_string comment_buf "(*"
+
+let end_comment lexbuf =
+ let () = decr num_comments in
+ let () = Buffer.add_string comment_buf "*)" in
+ if !num_comments < 0 then lex_error lexbuf "Unexpected end of comment"
+ else if !num_comments = 0 then
+ let s = Buffer.contents comment_buf in
+ let () = Buffer.reset comment_buf in
+ Some (COMMENT s)
+ else
+ None
+
+let start_ocaml _ =
+ let () = match mode () with
+ | OCaml -> Buffer.add_string ocaml_buf "{"
+ | Extend -> ()
+ in
+ incr num_braces
+
+let end_ocaml lexbuf =
+ let () = decr num_braces in
+ if !num_braces < 0 then lex_error lexbuf "Unexpected end of OCaml code"
+ else if !num_braces = 0 then
+ let s = Buffer.contents ocaml_buf in
+ let () = Buffer.reset ocaml_buf in
+ Some (CODE { Coqpp_ast.code = s })
+ else
+ let () = Buffer.add_string ocaml_buf "}" in
+ None
+
+}
+
+let letter = ['a'-'z' 'A'-'Z']
+let letterlike = ['_' 'a'-'z' 'A'-'Z']
+let alphanum = ['_' 'a'-'z' 'A'-'Z' '0'-'9' '\'']
+let ident = letterlike alphanum*
+let qualid = ident ('.' ident)*
+let space = [' ' '\t' '\r']
+let number = [ '0'-'9' ]
+
+rule extend = parse
+| "(*" { start_comment (); comment lexbuf }
+| "{" { start_ocaml (); ocaml lexbuf }
+| "GRAMMAR" { GRAMMAR }
+| "VERNAC" { VERNAC }
+| "TACTIC" { TACTIC }
+| "EXTEND" { EXTEND }
+| "END" { END }
+| "DECLARE" { DECLARE }
+| "PLUGIN" { PLUGIN }
+| "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 *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Lexing
+open Coqpp_ast
+open Format
+
+let fatal msg =
+ let () = Format.eprintf "Error: %s@\n%!" msg in
+ exit 1
+
+let pr_loc loc =
+ let file = loc.loc_start.pos_fname in
+ let line = loc.loc_start.pos_lnum in
+ let bpos = loc.loc_start.pos_cnum - loc.loc_start.pos_bol in
+ let epos = loc.loc_end.pos_cnum - loc.loc_start.pos_bol in
+ Printf.sprintf "File \"%s\", line %d, characters %d-%d:" file line bpos epos
+
+let parse_file f =
+ let chan = open_in f in
+ let lexbuf = Lexing.from_channel chan in
+ let () = lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = f } in
+ let ans =
+ try Coqpp_parse.file Coqpp_lex.token lexbuf
+ with
+ | Coqpp_lex.Lex_error (loc, msg) ->
+ let () = close_in chan in
+ let () = Printf.eprintf "%s\n%!" (pr_loc loc) in
+ fatal msg
+ | Parsing.Parse_error ->
+ let () = close_in chan in
+ let loc = Coqpp_lex.loc lexbuf in
+ let () = Printf.eprintf "%s\n%!" (pr_loc loc) in
+ fatal "syntax error"
+ in
+ let () = close_in chan in
+ ans
+
+module StringSet = Set.Make(String)
+
+let string_split s =
+ let len = String.length s in
+ let rec split n =
+ try
+ let pos = String.index_from s n '.' in
+ let dir = String.sub s n (pos-n) in
+ dir :: split (succ pos)
+ with
+ | Not_found -> [String.sub s n (len-n)]
+ in
+ if len == 0 then [] else split 0
+
+let plugin_name = "__coq_plugin_name"
+
+module GramExt :
+sig
+
+val print_ast : Format.formatter -> grammar_ext -> unit
+
+end =
+struct
+
+let is_uident s = match s.[0] with
+| 'A'..'Z' -> true
+| _ -> false
+
+let is_qualified = is_uident
+
+let get_local_entries ext =
+ let global = StringSet.of_list ext.gramext_globals in
+ let map e = e.gentry_name in
+ let entries = List.map map ext.gramext_entries in
+ let local = List.filter (fun e -> not (is_qualified e || StringSet.mem e global)) entries in
+ let rec uniquize seen = function
+ | [] -> []
+ | id :: rem ->
+ let rem = uniquize (StringSet.add id seen) rem in
+ if StringSet.mem id seen then rem else id :: rem
+ in
+ uniquize StringSet.empty local
+
+let print_local fmt ext =
+ let locals = get_local_entries ext in
+ match locals with
+ | [] -> ()
+ | e :: locals ->
+ let mk_e fmt e = fprintf fmt "%s.Entry.create \"%s\"" ext.gramext_name e in
+ let () = fprintf fmt "@[<hv 2>let %s =@ @[%a@]@]@ " e mk_e e in
+ let iter e = fprintf fmt "@[<hv 2>and %s =@ @[%a@]@]@ " e mk_e e in
+ let () = List.iter iter locals in
+ fprintf fmt "in@ "
+
+let print_string fmt s = fprintf fmt "\"%s\"" s
+
+let print_list fmt pr l =
+ let rec prl fmt = function
+ | [] -> ()
+ | [x] -> fprintf fmt "%a" pr x
+ | x :: l -> fprintf fmt "%a;@ %a" pr x prl l
+ in
+ fprintf fmt "@[<hv>[%a]@]" prl l
+
+let print_opt fmt pr = function
+| None -> fprintf fmt "None"
+| Some x -> fprintf fmt "Some@ (%a)" pr x
+
+let print_position fmt pos = match pos with
+| First -> fprintf fmt "Extend.First"
+| Last -> fprintf fmt "Extend.Last"
+| Before s -> fprintf fmt "Extend.Before@ \"%s\"" s
+| After s -> fprintf fmt "Extend.After@ \"%s\"" s
+| Level s -> fprintf fmt "Extend.Level@ \"%s\"" s
+
+let print_assoc fmt = function
+| LeftA -> fprintf fmt "Extend.LeftA"
+| RightA -> fprintf fmt "Extend.RightA"
+| NonA -> fprintf fmt "Extend.NonA"
+
+type symb =
+| SymbToken of string * string option
+| SymbEntry of string * string option
+| SymbSelf
+| SymbNext
+| SymbList0 of symb * symb option
+| SymbList1 of symb * symb option
+| SymbOpt of symb
+| SymbRules of ((string option * symb) list * code) list
+
+let is_token s = match string_split s with
+| [s] -> is_uident s
+| _ -> false
+
+let rec parse_tokens = function
+| [GSymbString s] -> SymbToken ("", Some s)
+| [GSymbQualid ("SELF", None)] -> SymbSelf
+| [GSymbQualid ("NEXT", None)] -> SymbNext
+| [GSymbQualid ("LIST0", None); tkn] ->
+ SymbList0 (parse_token tkn, None)
+| [GSymbQualid ("LIST1", None); tkn] ->
+ SymbList1 (parse_token tkn, None)
+| [GSymbQualid ("LIST0", None); tkn; GSymbQualid ("SEP", None); tkn'] ->
+ SymbList0 (parse_token tkn, Some (parse_token tkn'))
+| [GSymbQualid ("LIST1", None); tkn; GSymbQualid ("SEP", None); tkn'] ->
+ SymbList1 (parse_token tkn, Some (parse_token tkn'))
+| [GSymbQualid ("OPT", None); tkn] ->
+ SymbOpt (parse_token tkn)
+| [GSymbQualid (e, None)] when is_token e -> SymbToken (e, None)
+| [GSymbQualid (e, None); GSymbString s] when is_token e -> SymbToken (e, Some s)
+| [GSymbQualid (e, lvl)] when not (is_token e) -> SymbEntry (e, lvl)
+| [GSymbParen tkns] -> parse_tokens tkns
+| [GSymbProd prds] ->
+ let map p =
+ let map (pat, tkns) = (pat, parse_tokens tkns) in
+ (List.map map p.gprod_symbs, p.gprod_body)
+ in
+ SymbRules (List.map map prds)
+| t ->
+ let rec db_token = function
+ | GSymbString s -> Printf.sprintf "\"%s\"" s
+ | GSymbQualid (s, _) -> Printf.sprintf "%s" s
+ | GSymbParen s -> Printf.sprintf "(%s)" (db_tokens s)
+ | GSymbProd _ -> Printf.sprintf "[...]"
+ and db_tokens tkns =
+ let s = List.map db_token tkns in
+ String.concat " " s
+ in
+ fatal (Printf.sprintf "Invalid token: %s" (db_tokens t))
+
+and parse_token tkn = parse_tokens [tkn]
+
+let print_fun fmt (vars, body) =
+ let vars = List.rev vars in
+ let iter = function
+ | None -> fprintf fmt "_@ "
+ | Some id -> fprintf fmt "%s@ " id
+ in
+ let () = fprintf fmt "fun@ " in
+ let () = List.iter iter vars in
+ (** FIXME: use Coq locations in the macros *)
+ let () = fprintf fmt "loc ->@ @[%s@]" body.code in
+ ()
+
+(** Meta-program instead of calling Tok.of_pattern here because otherwise
+ violates value restriction *)
+let print_tok fmt = function
+| "", s -> fprintf fmt "Tok.KEYWORD %a" print_string s
+| "IDENT", s -> fprintf fmt "Tok.IDENT %a" print_string s
+| "PATTERNIDENT", s -> fprintf fmt "Tok.PATTERNIDENT %a" print_string s
+| "FIELD", s -> fprintf fmt "Tok.FIELD %a" print_string s
+| "INT", s -> fprintf fmt "Tok.INT %a" print_string s
+| "STRING", s -> fprintf fmt "Tok.STRING %a" print_string s
+| "LEFTQMARK", _ -> fprintf fmt "Tok.LEFTQMARK"
+| "BULLET", s -> fprintf fmt "Tok.BULLET %a" print_string s
+| "EOI", _ -> fprintf fmt "Tok.EOI"
+| _ -> failwith "Tok.of_pattern: not a constructor"
+
+let rec print_prod fmt p =
+ let (vars, tkns) = List.split p.gprod_symbs in
+ let f = (vars, p.gprod_body) in
+ let tkn = List.rev_map parse_tokens tkns in
+ fprintf fmt "@[Extend.Rule@ (@[%a@],@ @[(%a)@])@]" print_symbols tkn print_fun f
+
+and print_symbols fmt = function
+| [] -> fprintf fmt "Extend.Stop"
+| tkn :: tkns ->
+ fprintf fmt "Extend.Next @[(%a,@ %a)@]" print_symbols tkns print_symbol tkn
+
+and print_symbol fmt tkn = match tkn with
+| SymbToken (t, s) ->
+ let s = match s with None -> "" | Some s -> s in
+ fprintf fmt "(Extend.Atoken (%a))" print_tok (t, s)
+| SymbEntry (e, None) ->
+ fprintf fmt "(Extend.Aentry %s)" e
+| SymbEntry (e, Some l) ->
+ fprintf fmt "(Extend.Aentryl (%s, %a))" e print_string l
+| SymbSelf ->
+ fprintf fmt "Extend.Aself"
+| SymbNext ->
+ fprintf fmt "Extend.Anext"
+| SymbList0 (s, None) ->
+ fprintf fmt "(Extend.Alist0 %a)" print_symbol s
+| SymbList0 (s, Some sep) ->
+ fprintf fmt "(Extend.Alist0sep (%a, %a))" print_symbol s print_symbol sep
+| SymbList1 (s, None) ->
+ fprintf fmt "(Extend.Alist1 %a)" print_symbol s
+| SymbList1 (s, Some sep) ->
+ fprintf fmt "(Extend.Alist1sep (%a, %a))" print_symbol s print_symbol sep
+| SymbOpt s ->
+ fprintf fmt "(Extend.Aopt %a)" print_symbol s
+| SymbRules rules ->
+ let pr fmt (r, body) =
+ let (vars, tkn) = List.split r in
+ let tkn = List.rev tkn in
+ fprintf fmt "Extend.Rules @[({ Extend.norec_rule = %a },@ (%a))@]" print_symbols tkn print_fun (vars, body)
+ in
+ let pr fmt rules = print_list fmt pr rules in
+ fprintf fmt "(Extend.Arules %a)" pr (List.rev rules)
+
+let print_rule fmt r =
+ let pr_lvl fmt lvl = print_opt fmt print_string lvl in
+ let pr_asc fmt asc = print_opt fmt print_assoc asc in
+ let pr_prd fmt prd = print_list fmt print_prod prd in
+ fprintf fmt "@[(%a,@ %a,@ %a)@]" pr_lvl r.grule_label pr_asc r.grule_assoc pr_prd (List.rev r.grule_prods)
+
+let print_entry fmt gram e =
+ let print_position_opt fmt pos = print_opt fmt print_position pos in
+ let print_rules fmt rules = print_list fmt print_rule rules in
+ fprintf fmt "let () =@ @[%s.gram_extend@ %s@ @[(%a, %a)@]@]@ in@ "
+ gram e.gentry_name print_position_opt e.gentry_pos print_rules e.gentry_rules
+
+let print_ast fmt ext =
+ let () = fprintf fmt "let _ = @[" in
+ let () = fprintf fmt "@[<v>%a@]" print_local ext in
+ let () = List.iter (fun e -> print_entry fmt ext.gramext_name e) ext.gramext_entries in
+ let () = fprintf fmt "()@]@\n" in
+ ()
+
+end
+
+module TacticExt :
+sig
+
+val print_ast : Format.formatter -> tactic_ext -> unit
+
+end =
+struct
+
+let rec print_symbol fmt = function
+| Ulist1 s ->
+ fprintf fmt "@[Extend.TUlist1 (%a)@]" print_symbol s
+| Ulist1sep (s, sep) ->
+ fprintf fmt "@[Extend.TUlist1sep (%a, \"%s\")@]" print_symbol s sep
+| Ulist0 s ->
+ fprintf fmt "@[Extend.TUlist0 (%a)@]" print_symbol s
+| Ulist0sep (s, sep) ->
+ fprintf fmt "@[Extend.TUlist0sep (%a, \"%s\")@]" print_symbol s sep
+| Uopt s ->
+ fprintf fmt "@[Extend.TUopt (%a)@]" print_symbol s
+| Uentry e ->
+ fprintf fmt "@[Extend.TUentry (Genarg.get_arg_tag wit_%s)@]" e
+| Uentryl (e, l) ->
+ assert (e = "tactic");
+ fprintf fmt "@[Extend.TUentryl (Genarg.get_arg_tag wit_%s, %i)@]" e l
+
+let rec print_clause fmt = function
+| [] -> fprintf fmt "@[TyNil@]"
+| ExtTerminal s :: cl -> fprintf fmt "@[TyIdent (\"%s\", %a)@]" s print_clause cl
+| ExtNonTerminal (g, TokNone) :: cl ->
+ fprintf fmt "@[TyAnonArg (%a, %a)@]"
+ print_symbol g print_clause cl
+| ExtNonTerminal (g, TokName id) :: cl ->
+ fprintf fmt "@[TyArg (%a, \"%s\", %a)@]"
+ print_symbol g id print_clause cl
+
+let rec print_binders fmt = function
+| [] -> fprintf fmt "ist@ "
+| (ExtTerminal _ | ExtNonTerminal (_, TokNone)) :: rem -> print_binders fmt rem
+| (ExtNonTerminal (_, TokName id)) :: rem ->
+ fprintf fmt "%s@ %a" id print_binders rem
+
+let print_rule fmt r =
+ fprintf fmt "@[TyML (%a, @[fun %a -> %s@])@]"
+ print_clause r.tac_toks print_binders r.tac_toks r.tac_body.code
+
+let rec print_rules fmt = function
+| [] -> ()
+| [r] -> fprintf fmt "(%a)@\n" print_rule r
+| r :: rem -> fprintf fmt "(%a);@\n%a" print_rule r print_rules rem
+
+let print_rules fmt rules =
+ fprintf fmt "Tacentries.([@[<v>%a@]])" print_rules rules
+
+let print_ast fmt ext =
+ let 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 */
+/* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 */
+/* \VV/ **************************************************************/
+/* // * This file is distributed under the terms of the */
+/* * GNU Lesser General Public License Version 2.1 */
+/************************************************************************/
+
+%{
+
+open Coqpp_ast
+
+let starts s pat =
+ let len = String.length s in
+ let patlen = String.length pat in
+ if patlen <= len && String.sub s 0 patlen = pat then
+ Some (String.sub s patlen (len - patlen))
+ else None
+
+let ends s pat =
+ let len = String.length s in
+ let patlen = String.length pat in
+ if patlen <= len && String.sub s (len - patlen) patlen = pat then
+ Some (String.sub s 0 (len - patlen))
+ else None
+
+let between s pat1 pat2 = match starts s pat1 with
+| None -> None
+| Some s -> ends s pat2
+
+let without_sep k sep r =
+ if sep <> "" then raise Parsing.Parse_error else k r
+
+let parse_user_entry s sep =
+ let table = [
+ "ne_", "_list", without_sep (fun r -> Ulist1 r);
+ "ne_", "_list_sep", (fun sep r -> Ulist1sep (r, sep));
+ "", "_list", without_sep (fun r -> Ulist0 r);
+ "", "_list_sep", (fun sep r -> Ulist0sep (r, sep));
+ "", "_opt", without_sep (fun r -> Uopt r);
+ ] in
+ let rec parse s sep = function
+ | [] ->
+ let () = without_sep ignore sep () in
+ begin match starts s "tactic" with
+ | Some ("0"|"1"|"2"|"3"|"4"|"5") -> Uentryl ("tactic", int_of_string s)
+ | Some _ | None -> Uentry s
+ end
+ | (pat1, pat2, k) :: rem ->
+ match between s pat1 pat2 with
+ | None -> parse s sep rem
+ | Some s ->
+ let r = parse s "" table in
+ k sep r
+ in
+ parse s sep table
+
+%}
+
+%token <Coqpp_ast.code> CODE
+%token <string> COMMENT
+%token <string> IDENT QUALID
+%token <string> STRING
+%token <int> INT
+%token VERNAC TACTIC GRAMMAR EXTEND END DECLARE PLUGIN 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 <Coqpp_ast.t> file
+%start file
+
+%%
+
+file:
+| nodes EOF
+ { $1 }
+;
+
+nodes:
+|
+ { [] }
+| node nodes
+ { $1 :: $2 }
+;
+
+node:
+| CODE { Code $1 }
+| COMMENT { Comment $1 }
+| declare_plugin { $1 }
+| grammar_extend { $1 }
+| vernac_extend { $1 }
+| tactic_extend { $1 }
+;
+
+declare_plugin:
+| DECLARE PLUGIN STRING { DeclarePlugin $3 }
+;
+
+grammar_extend:
+| GRAMMAR EXTEND qualid_or_ident globals gram_entries END
+ { GramExt { gramext_name = $3; gramext_globals = $4; gramext_entries = $5 } }
+;
+
+vernac_extend:
+| VERNAC EXTEND IDENT END { VernacExt }
+;
+
+tactic_extend:
+| TACTIC EXTEND IDENT tactic_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 ^<i686 or x86_64^> Set cygwin, ocaml and coq to 32 or 64 bit
- ECHO -mode ^<mingwincygwin = install coq in default cygwin mingw sysroot^>
- ECHO ^<absoloute = install coq in -destcoq absulute path^>
- ECHO ^<relocatable = install relocatable coq in -destcoq path^>
- ECHO -installer^<Y or N^> create a windows installer (will be in /build/coq/dev/nsis)
- ECHO -ocaml ^<Y or N^> install OCaml in Coq folder (Y) or just in cygwin folder (N)
- ECHO -make ^<Y or N^> install GNU Make in Coq folder (Y) or not (N)
- ECHO -destcyg ^<path to cygwin destination folder^>
- ECHO -destcoq ^<path to coq destination folder (mode=absoloute/relocatable)^>
- ECHO -setup ^<cygwin setup program name^> (auto adjusted to -arch)
- ECHO -proxy ^<internet proxy^>
- ECHO -cygrepo ^<cygwin download repository^>
- ECHO -cygcache ^<local cygwin repository/cache^>
- ECHO -cyglocal ^<Y or N^> install cygwin from cache
- ECHO -cygquiet ^<Y or N^> install cygwin without user interaction
- ECHO -srccache ^<local source code repository/cache^>
- ECHO -coqver ^<Coq version to install^>
- ECHO -gtksrc ^<Y or N^> build GTK ^(90 min^) or use cygwin version
- ECHO -threads ^<1..N^> Number of make threads
- ECHO -addon ^<name^> 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 ^<i686 or x86_64^> Set cygwin, ocaml and coq to 32 or 64 bit
+ ECHO -mode ^<mingwincygwin = install coq in default cygwin mingw sysroot^>
+ ECHO ^<absoloute = install coq in -destcoq absulute path^>
+ ECHO ^<relocatable = install relocatable coq in -destcoq path^>
+ ECHO -installer^<Y or N^> create a windows installer (will be in /build/coq/dev/nsis)
+ ECHO -ocaml ^<Y or N^> install OCaml in Coq folder (Y) or just in cygwin folder (N)
+ ECHO -make ^<Y or N^> install GNU Make in Coq folder (Y) or not (N)
+ ECHO -destcyg ^<path to cygwin destination folder^>
+ ECHO -destcoq ^<path to coq destination folder (mode=absoloute/relocatable)^>
+ ECHO -setup ^<cygwin setup program name^> (auto adjusted to -arch)
+ ECHO -proxy ^<internet proxy^>
+ ECHO -cygrepo ^<cygwin download repository^>
+ ECHO -cygcache ^<local cygwin repository/cache^>
+ ECHO -cyglocal ^<Y or N^> install cygwin from cache
+ ECHO -cygquiet ^<Y or N^> install cygwin without user interaction
+ ECHO -srccache ^<local source code repository/cache^>
+ ECHO -coqver ^<Coq version to install^>
+ ECHO -gtksrc ^<Y or N^> build GTK ^(90 min^) or use cygwin version
+ ECHO -threads ^<1..N^> Number of make threads
+ ECHO -addon ^<name^> 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 "<module>-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 "<module>-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 "<module>-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 "<module>-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 "<module>-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 "<module>-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 "<module>-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 "<module>-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.patch
index d03749ba..1afa6e7f 100644..100755
--- a/dev/build/windows/patches_coq/quickchick-v1.0.2.patch
+++ b/dev/build/windows/patches_coq/quickchick.patch
@@ -24,15 +24,3 @@ ORIGFOLDER= quickchick-v1.0.2.orig
+ $(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/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 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Pp
+open Names
+open Univ
+
+let pp x = Pp.pp_with Format.std_formatter x
+
+(** Future printer *)
+
+let ppfuture kx = pp (Future.print (fun _ -> 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 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Printers for the ocaml toplevel. *)
+
+val pp : Pp.t -> 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 <imageID>`
+
+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, <latest-ocaml-version> is 4.07.0.
+# The latest version number is available at: https://ocaml.org/releases/
+
+$ opam init --comp <latest-ocaml-version>
+
+# Then follow the advice displayed at the end as how to update your
+ ~/.bashrc and ~/.ocamlinit files.
+
+$ source ~/.bashrc
+$ opam install camlp5
+
+# needed if you want to build "coqide" target
+
+$ sudo apt-get install liblablgtksourceview2-ocaml-dev \
+ libgtk2.0-dev libgtksourceview2.0-dev
+$ opam install lablgtk
+```
+
+## Building `coqtop`
+The general workflow is to first setup a development environment with
+the correct `configure` settings, then hacking on Coq, make-ing, and testing.
+
+
+This document will use `$JOBS` to refer to the number of parallel jobs one
+is willing to have with `make`.
+
+
+```
+$ git clone git clone https://github.com/coq/coq.git
+$ cd coq
+$ ./configure -profile devel
+$ make -j $JOBS # Make once for `merlin`(autocompletion tool)
+
+<hack>
+
+$ make -j $JOBS states # builds just enough to run coqtop
+$ bin/coqtop -compile <test_file_name.v>
+<goto hack until stuff works>
+
+<run test-suite>
+```
+
+To learn how to run the test suite, you can read
+[`test-suite/README.md`](../../test-suite/README.md).
+
+## Coq functions of interest
+- `Coqtop.start`: This function is the main entry point of coqtop.
+- `Coqtop.parse_args `: This function is responsible for parsing command-line arguments.
+- `Coqloop.loop`: This function implements the read-eval-print loop.
+- `Vernacentries.interp`: This function is called to execute the Vernacular command user have typed.
+ It dispatches the control to specific functions handling different Vernacular command.
+- `Vernacentries.vernac_check_may_eval`: This function handles the `Check ...` command.
+
+
+## Development environment + tooling
+- [`Merlin`](https://github.com/ocaml/merlin) for autocomplete.
+- [Wiki pages on tooling containing `emacs`, `vim`, and `git` information](https://github.com/coq/coq/wiki/DevelSetup)
+
+## A note about rlwrap
+
+When using `rlwrap coqtop` make sure the version of `rlwrap` is at least
+`0.42`, otherwise you will get
+
+```
+rlwrap: error: Couldn't read completions from /usr/share/rlwrap/completions/coqtop: No such file or directory
+```
+
+If this happens either update or use an alternate readline wrapper like `ledit`.
diff --git a/dev/doc/changes.md b/dev/doc/changes.md
index 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 <Ctrl+L>, Merlin will show the definition of the symbol in a separate window.
-If you prefer to jump to the definition within the same window, do this:
-
- <Alt+X> customize-group <ENTER> merlin <ENTER>
-
- Merlin Locate In New Window
-
- Value Menu
-
- Never Open In New Window
-
- State
-
- Set For Future Sessions
-
-Testing (Merlin):
-
- cd ~/git/coq
- emacs toplevel/coqtop.ml &
-
-Go to the end of the file where you will see the "start" function.
-
-Go to a line where "init_toplevel" function is called.
-
-If you want to jump to the position where that function or datatype under the cursor is defined, press <Ctrl+L>.
-
-If you want to jump back, type: <Ctrl+B>
-
-If you want to learn the type of the value at current cursor's position, type: <Ctrl+T>
-
-
-Enabling auto-completion in emacs
----------------------------------
-
-In Emacs, type: <Alt+M> list-packages <ENTER>
-
-In the list that is displayed, click on "company".
-
-A new window appears where just click on "Install" and then answer "Yes".
-
-These lines:
-
- (package-initialize)
- (require 'company)
- ; Make company aware of merlin
- (add-to-list 'company-backends 'merlin-company-backend)
- ; Enable company on merlin managed buffers
- (add-hook 'merlin-mode-hook 'company-mode)
- (global-set-key [C-tab] 'company-complete)
-
-then need to be added to your "~/.emacs" file.
-
-Next time when you start emacs and partially type some identifier,
-emacs will offer the corresponding completions.
-Auto-completion can also be manually invoked by typing <Ctrl+TAB>.
-Description of various other shortcuts is here.
-
- http://company-mode.github.io/
-
-
-Getting along with ocamldebug
------------------------------
-
-The default ocamldebug key-bindings are described here.
-
- http://caml.inria.fr/pub/docs/manual-ocaml/debugger.html#sec369
-
-If you want, you can customize them by putting the following commands:
-
- (global-set-key (kbd "<f5>") 'ocamldebug-break)
- (global-set-key (kbd "<f6>") 'ocamldebug-run)
- (global-set-key (kbd "<f7>") 'ocamldebug-next)
- (global-set-key (kbd "<f8>") 'ocamldebug-step)
- (global-set-key (kbd "<f9>") 'ocamldebug-finish)
- (global-set-key (kbd "<f10>") 'ocamldebug-print)
- (global-set-key (kbd "<f12>") 'camldebug)
-
-to your "~/.emacs" file.
-
-Let us try whether ocamldebug in Emacs works for us.
-(If necessary, re-)compile coqtop:
-
- cd ~/git/coq
- make -j4 coqide printers
-
-open Emacs:
-
- emacs toplevel/coqtop.ml &
-
-and type:
-
- <F12> ../bin/coqtop.byte <ENTER> ../dev/ocamldebug-coq <ENTER>
-
-As a result, a new window is open at the bottom where you should see:
-
- (ocd)
-
-i.e. an ocamldebug shell.
-
- 1. Switch to the window that contains the "coqtop.ml" file.
- 2. Go to the end of the file.
- 3. Find the definition of the "start" function.
- 4. Go to the "let" keyword that is at the beginning of the first line.
- 5. By pressing <F5> you set a breakpoint to the cursor's position.
- 6. By pressing <F6> you start the bin/coqtop process.
- 7. Then you can:
- - step over function calls: <F7>
- - step into function calls: <F8>
- - or finish execution of the current function until it returns: <F9>.
-
-Other ocamldebug commands, can be typed to the window that holds the ocamldebug shell.
-
-The points at which the execution of Ocaml program can stop are defined here:
-
- http://caml.inria.fr/pub/docs/manual-ocaml/debugger.html#sec350
-
-
-Installing printers to ocamldebug
----------------------------------
-
-There is a pretty comprehensive set of printers defined for many common data types.
-You can load them by switching to the window holding the "ocamldebug" shell and typing:
-
- (ocd) source "../dev/db"
-
-
-Some of the functions were you might want to set a breakpoint and see what happens next
----------------------------------------------------------------------------------------
-
-- Coqtop.start : This function is the main entry point of coqtop.
-- Coqtop.parse_args : This function is responsible for parsing command-line arguments.
-- Coqloop.loop : This function implements the read-eval-print loop.
-- Vernacentries.interp : This function is called to execute the Vernacular command user have typed.\
- It dispatches the control to specific functions handling different Vernacular command.
-- Vernacentries.vernac_check_may_eval : This function handles the "Check ..." command.
diff --git a/dev/doc/translate.txt b/dev/doc/translate.txt
deleted file mode 100644
index 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](<quasiterm>Case m of t [p:nat](f m) end)
-
- The solution is then to replace the invocation of the sequence of
- tactics into several invocation of the elementary tactics as follows
-
- Intros. Exists [m:nat](<quasiterm>Case m of t [p:nat](f m) end)
- ^^^
-
-3) Change of definition or theorem names
-
- Type "entier" from fast_integer.v is renamed into "N" by the
-translator. As a consequence, user-defined objects of same name "N"
-are systematically qualified even tough it may not be necessary. The
-same apply for names "GREATER", "EQUAL", "LESS", etc... [COMPLETE LIST
-TO GIVE].
-
-4) Change of tactics names
-
- Since tactics names are now lowercase, this can clash with
-user-defined tactic definitions. To pally this, clashing names are
-renamed by adding an extra "_" to their name.
-
-======================================================================
-Main examples for new syntax
-----------------------------
-
-1) Constructions
-
- Applicative terms don't any longer require to be surrounded by parentheses as
-e.g in
-
- "x = f y -> S x = S (f y)"
-
-
- Product is written
-
- "forall x y : T, U"
- "forall x y, U"
- "forall (x y : T) z (v w : V), U"
- etc.
-
- Abstraction is written
-
- "fun x y : T, U"
- "fun x y, U"
- "fun (x y : T) z (v w : V), U"
- etc.
-
- Pattern-matching is written
-
- "match x with c1 x1 x2 => t | c2 y as z => u end"
- "match v1, v2 with c1 x1 x2, _ => t | c2 y, d z => u end"
- "match v1 as y in le _ n, v2 as z in I p q return P n y p q z with
- c1 x1 x2, _ => t | c2 y, d z => u end"
-
- The last example is the new form of what was written
-
- "<[n;y:(le ? n);p;q;z:(I p q)](P n y p q z)>Cases v1 v2 of
- (c1 x1 x2) _ => t | (c2 y) (d z) => u end"
-
- Pattern-matching of type with one constructors and no dependencies
-of the arguments in the resulting type can be written
-
- "let (x,y,z) as u return P u := t in v"
-
- Local fixpoints are written
-
- "fix f (n m:nat) z (x : X) {struct m} : nat := ...
- with ..."
-
- and "struct" tells which argument is structurally decreasing.
-
- Explicitation of implicit arguments is written
-
- "f @1:=u v @3:=w t"
- "@f u v w t"
-
-2) Tactics
-
- The main change is that tactics names are now lowercase. Besides
-this, the following renaming are applied:
-
- "NewDestruct" -> "destruct"
- "NewInduction" -> "induction"
- "Induction" -> "simple induction"
- "Destruct" -> "simple destruct"
-
- For tactics with occurrences, the occurrences now comes after and
- repeated use is separated by comma as in
-
- "Pattern 1 3 c d 4 e" -> "pattern c at 3 1, d, e at 4"
- "Unfold 1 3 f 4 g" -> "unfold f at 1 3, g at 4"
- "Simpl 1 3 e" -> "simpl e at 1 3"
-
-3) Tactic language
-
- Definitions are now introduced with keyword "Ltac" (instead of
-"Tactic"/"Meta" "Definition") and are implicitly recursive
-("Recursive" is no longer used).
-
- The new rule for distinguishing terms from ltac expressions is:
-
- Write "ltac:" in front of any tactic in argument position and
- "constr:" in front of any construction in head position
-
-4) Vernacular language
-
-a) Assumptions
-
- The syntax for commands is mainly unchanged. Declaration of
-assumptions is now done as follows
-
- Variable m : t.
- Variables m n p : t.
- Variables (m n : t) (u v : s) (w : r).
-
-b) Definitions
-
- Definitions are done as follows
-
- Definition f m n : t := ... .
- Definition f m n := ... .
- Definition f m n := ... : t.
- Definition f (m n : u) : t := ... .
- Definition f (m n : u) := ... : t.
- Definition f (m n : u) := ... .
- Definition f a b (p q : v) r s (m n : t) : t := ... .
- Definition f a b (p q : v) r s (m n : t) := ... .
- Definition f a b (p q : v) r s (m n : t) := ... : t.
-
-c) Fixpoints
-
- Fixpoints are done this way
-
- Fixpoint f x (y : t) z a (b c : u) {struct z} : v := ... with ... .
- Fixpoint f x : v := ... .
- Fixpoint f (x : t) : v := ... .
-
- It is possible to give a concrete notation to a fixpoint as follows
-
- Fixpoint plus (n m:nat) {struct n} : nat as "n + m" :=
- match n with
- | O => m
- | S p => S (p + m)
- end.
-
-d) Inductive types
-
- The syntax for inductive types is as follows
-
- Inductive t (a b : u) (d : e) : v :=
- c1 : w1 | c2 : w2 | ... .
-
- Inductive t (a b : u) (d : e) : v :=
- c1 : w1 | c2 : w2 | ... .
-
- Inductive t (a b : u) (d : e) : v :=
- c1 (x y : t) : w1 | c2 (z : r) : w2 | ... .
-
- As seen in the last example, arguments of the constructors can be
-given before the colon. If the type itself is omitted (allowed only in
-case the inductive type has no real arguments), this yields an
-ML-style notation as follows
-
- Inductive nat : Set := O | S (n:nat).
- Inductive bool : Set := true | false.
-
- It is even possible to define a syntax at the same time, as follows:
-
- Inductive or (A B:Prop) : Prop as "A \/ B":=
- | or_introl (a:A) : A \/ B
- | or_intror (b:B) : A \/ B.
-
- Inductive and (A B:Prop) : Prop as "A /\ B" := conj (a:A) (b:B).
-
diff --git a/dev/doc/versions-history.tex b/dev/doc/versions-history.tex
index 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 <PR number> [--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 "<expanded: " ++
- Termops.print_constr (EConstr.of_constr c) ++ str">") ++
+ pr_constr c ++ str">") ++
(if id = id0 then mt ()
else spc () ++ str "<canonical: " ++ Id.print id ++ 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
+<https://gitlab.com/coq/coq/-/jobs/artifacts/master/file/_install_ci/share/doc/coq/sphinx/html/index.html?job=doc:refman>.
+
+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 <tt>Require Import</tt> command.</p>
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 <tt>Require Import</tt> command.</p>
<dd>
theories/Strings/Ascii.v
theories/Strings/String.v
+ theories/Strings/BinaryString.v
+ theories/Strings/HexString.v
+ theories/Strings/OctalString.v
</dd>
<dt> <b>Reals</b>:
@@ -583,6 +587,17 @@ through the <tt>Require Import</tt> command.</p>
theories/Program/Combinators.v
</dd>
+ <dt> <b>SSReflect</b>:
+ Base libraries for the SSReflect proof language and the
+ small scale reflection formalization technique
+ </dt>
+ <dd>
+ plugins/ssrmatching/ssrmatching.v
+ plugins/ssr/ssreflect.v
+ plugins/ssr/ssrbool.v
+ plugins/ssr/ssrfun.v
+ </dd>
+
<dt> <b>Unicode</b>:
Unicode-based notations
</dt>
@@ -596,8 +611,8 @@ through the <tt>Require Import</tt> command.</p>
</dt>
<dd>
theories/Compat/AdmitAxiom.v
- theories/Compat/Coq86.v
theories/Compat/Coq87.v
theories/Compat/Coq88.v
+ theories/Compat/Coq89.v
</dd>
</dl>
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:<a href=\"Coq.$p.$b.html\">$b</a>:g" tmp > tmp2
+ p=`echo $k | sed 's:^[^/]*/::' | sed 's:/:.:g'`
+ sed -e "s:$k/$b.v:<a href=\"Coq.$p.$b.html\">$b</a>: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/intf/evar_kinds.ml b/engine/evar_kinds.ml
index c5de383b..ea1e5725 100644
--- a/intf/evar_kinds.ml
+++ b/engine/evar_kinds.ml
@@ -9,8 +9,6 @@
(************************************************************************)
open Names
-open Globnames
-open Misctypes
(** The kinds of existential variable *)
@@ -19,14 +17,31 @@ open Misctypes
type obligation_definition_status = Define of bool | Expand
-type matching_var_kind = FirstOrderPatVar of patvar | SecondOrderPatVar of patvar
+type matching_var_kind = FirstOrderPatVar of Id.t | SecondOrderPatVar of Id.t
+
+type subevar_kind = Domain | Codomain | Body
+
+(* maybe this should be a Projection.t *)
+type record_field = { fieldname : Constant.t; recordname : Names.inductive }
+
+type question_mark = {
+ qm_obligation: obligation_definition_status;
+ qm_name: Name.t;
+ qm_record_field: record_field option;
+}
+
+let default_question_mark = {
+ qm_obligation=Define true;
+ qm_name=Anonymous;
+ qm_record_field=None;
+}
type t =
- | ImplicitArg of global_reference * (int * Id.t option)
+ | ImplicitArg of GlobRef.t * (int * Id.t option)
* bool (** Force inference *)
| BinderType of Name.t
| NamedHole of Id.t (* coming from some ?[id] syntax *)
- | QuestionMark of obligation_definition_status * Name.t
+ | QuestionMark of question_mark
| CasesType of bool (* true = a subterm of the type *)
| InternalHole
| TomatchTypeParameter of inductive * int
@@ -34,4 +49,4 @@ type t =
| ImpossibleCase
| MatchingVar of matching_var_kind
| VarInstance of Id.t
- | SubEvar of Evar.t
+ | SubEvar of subevar_kind option * Evar.t
diff --git a/engine/evar_kinds.mli b/engine/evar_kinds.mli
new file mode 100644
index 00000000..4facdb20
--- /dev/null
+++ b/engine/evar_kinds.mli
@@ -0,0 +1,51 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Names
+
+(** The kinds of existential variable *)
+
+(** Should the obligation be defined (opaque or transparent (default)) or
+ defined transparent and expanded in the term? *)
+
+type obligation_definition_status = Define of bool | Expand
+
+type matching_var_kind = FirstOrderPatVar of Id.t | SecondOrderPatVar of Id.t
+
+type subevar_kind = Domain | Codomain | Body
+
+(* maybe this should be a Projection.t *)
+(* Represents missing record field *)
+type record_field = { fieldname : Constant.t; recordname : Names.inductive }
+
+type question_mark = {
+ qm_obligation: obligation_definition_status;
+ qm_name: Name.t;
+ (* Tracks if the evar represents a missing record field *)
+ qm_record_field: record_field option;
+}
+
+(* Default value of question_mark which is used most often *)
+val default_question_mark : question_mark
+
+type t =
+ | ImplicitArg of GlobRef.t * (int * Id.t option)
+ * bool (** Force inference *)
+ | BinderType of Name.t
+ | NamedHole of Id.t (* coming from some ?[id] syntax *)
+ | QuestionMark of question_mark
+ | CasesType of bool (* true = a subterm of the type *)
+ | InternalHole
+ | TomatchTypeParameter of inductive * int
+ | GoalEvar
+ | ImpossibleCase
+ | MatchingVar of matching_var_kind
+ | VarInstance of Id.t
+ | SubEvar of subevar_kind option * Evar.t
diff --git a/engine/evarutil.ml b/engine/evarutil.ml
index 9cf81ecc..b77bf55d 100644
--- a/engine/evarutil.ml
+++ b/engine/evarutil.ml
@@ -13,7 +13,6 @@ open Util
open Names
open Term
open Constr
-open Pre_env
open Environ
open Evd
open Termops
@@ -23,7 +22,8 @@ module RelDecl = Context.Rel.Declaration
module NamedDecl = Context.Named.Declaration
let safe_evar_value sigma ev =
- try Some (Evd.existential_value sigma ev)
+ let ev = EConstr.of_existential ev in
+ try Some (EConstr.Unsafe.to_constr @@ Evd.existential_value sigma ev)
with NotInstantiatedEvar | Not_found -> 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 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Sorts
+open Names
+open Constr
+open Environ
+open Univ
+
+(* 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"
+ 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 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Names
+open Constr
+open Environ
+open Univ
+
+
+(** The global universe counter *)
+type universe_id = DirPath.t * int
+
+val set_remote_new_univ_id : universe_id RemoteCounter.installer
+
+(** Side-effecting functions creating new universe levels. *)
+
+val new_univ_id : unit -> 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 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Univ
+open UnivSubst
+
+(* To disallow minimization to Set *)
+let set_minimization = ref true
+let is_set_minimization () = !set_minimization
+
+let _ =
+ Goptions.(declare_bool_option
+ { optdepr = false;
+ optname = "minimization to Set";
+ optkey = ["Universe";"Minimization";"ToSet"];
+ optread = is_set_minimization;
+ optwrite = (:=) set_minimization })
+
+
+(** Simplification *)
+
+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
+
+(** 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 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Univ
+open UnivSubst
+
+(** Unordered pairs of universe levels (ie (u,v) = (v,u)) *)
+module UPairSet : CSet.S with type elt = (Level.t * Level.t)
+
+(** Simplification and pruning of constraints:
+ [normalize_context_set ctx us]
+
+ - Instantiate the variables in [us] with their most precise
+ universe levels respecting the constraints.
+
+ - 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 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
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 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Names
+open Univ
+open Globnames
+open Nametab
+
+
+let qualid_of_level l =
+ match Level.name l with
+ | Some (d, n as na) ->
+ 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 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Univ
+
+val pr_with_global_universes : Level.t -> 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 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Univ
+open UnivSubst
+
+type 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
+
+
+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 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 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Constr
+open Univ
+
+(** {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 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
+
+val is_trivial : t -> 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 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Sorts
+open Util
+open Pp
+open Constr
+open Univ
+
+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_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 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Constr
+open Univ
+
+val level_subst_of : universe_subst_fn -> 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.in
index 953b5dce..4dc6f455 100644
--- a/ide/.merlin
+++ b/ide/.merlin.in
@@ -2,5 +2,7 @@ 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 "<Actions>/Tactics/Tactic casetype" "")
; (gtk_accel_path "<Actions>/Tactics/Tactic cbv in" "")
; (gtk_accel_path "<Actions>/Templates/Template Load" "")
-; (gtk_accel_path "<Actions>/Tactics/Tactic fourier" "")
; (gtk_accel_path "<Actions>/Templates/Template Goal" "")
; (gtk_accel_path "<Actions>/Tactics/Tactic exists" "")
; (gtk_accel_path "<Actions>/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/utils/configwin.ml b/ide/configwin.ml
index 69e8b647..69e8b647 100644
--- a/ide/utils/configwin.ml
+++ b/ide/configwin.ml
diff --git a/ide/utils/configwin.mli b/ide/configwin.mli
index 7616e471..7616e471 100644
--- a/ide/utils/configwin.mli
+++ b/ide/configwin.mli
diff --git a/ide/utils/configwin_ihm.ml b/ide/configwin_ihm.ml
index d16efa60..d16efa60 100644
--- a/ide/utils/configwin_ihm.ml
+++ b/ide/configwin_ihm.ml
diff --git a/ide/utils/configwin_ihm.mli b/ide/configwin_ihm.mli
index c867ad91..c867ad91 100644
--- a/ide/utils/configwin_ihm.mli
+++ b/ide/configwin_ihm.mli
diff --git a/ide/utils/configwin_messages.ml b/ide/configwin_messages.ml
index de1b4721..de1b4721 100644
--- a/ide/utils/configwin_messages.ml
+++ b/ide/configwin_messages.ml
diff --git a/ide/utils/configwin_types.mli b/ide/configwin_types.ml
index 9e339d13..9e339d13 100644
--- a/ide/utils/configwin_types.mli
+++ b/ide/configwin_types.ml
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:"<Shift>F3"
~callback:(cb_on_current_term (fun t -> t.finder#find_backward ()));
- item "Complete Word" ~label:"Complete Word" ~accel:"<Ctrl>slash"
- ~callback:(fun _ -> ());
item "External editor" ~label:"External editor" ~stock:`EDIT
~callback:External.editor;
item "Preferences" ~accel:"<Ctrl>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 <menuitem action='Find' />\
\n <menuitem action='Find Next' />\
\n <menuitem action='Find Previous' />\
-\n <menuitem action='Complete Word' />\
\n <separator />\
\n <menuitem action='External editor' />\
\n <separator />\
@@ -86,6 +85,10 @@ let init () =
\n <menuitem action='Display universe levels' />\
\n <menuitem action='Display all low-level contents' />\
\n <menuitem action='Display unfocused goals' />\
+\n <separator/>\
+\n <menuitem action='Unset diff' />\
+\n <menuitem action='Set diff' />\
+\n <menuitem action='Set removed diff' />\
\n </menu>\
\n <menu action='Navigation'>\
\n <menuitem action='Forward' />\
diff --git a/ide/gtk_parsing.ml b/ide/gtk_parsing.ml
index 9f5c9924..d554bebd 100644
--- a/ide/gtk_parsing.ml
+++ b/ide/gtk_parsing.ml
@@ -35,8 +35,11 @@ let find_word_start (it:GText.iter) =
(Minilib.log "find_word_start: cannot backward"; it)
else if is_word_char it#char
then step_to_start it
- else (it#nocopy#forward_char;
- Minilib.log ("Word start at: "^(string_of_int it#offset));it)
+ else begin
+ ignore(it#nocopy#forward_char);
+ Minilib.log ("Word start at: "^(string_of_int it#offset));
+ it
+ end
in
step_to_start it#copy
diff --git a/ide/ide.mllib b/ide/ide.mllib
index 96ea8c41..a7ade713 100644
--- a/ide/ide.mllib
+++ b/ide/ide.mllib
@@ -9,15 +9,7 @@ Config_lexer
Utf8_convert
Preferences
Project_file
-Serialize
-Richprinter
-Xml_lexer
-Xml_parser
-Xml_printer
-Serialize
-Richpp
Topfmt
-Xmlprotocol
Ideutils
Coq
Coq_lex
diff --git a/ide/coqidetop.mllib b/ide/ide_common.mllib
index df988d8f..050c282e 100644
--- a/ide/coqidetop.mllib
+++ b/ide/ide_common.mllib
@@ -5,4 +5,3 @@ Serialize
Richpp
Xmlprotocol
Document
-Ide_slave
diff --git a/ide/ide_slave.ml b/ide/idetop.ml
index 6b7efc83..8a221a93 100644
--- a/ide/ide_slave.ml
+++ b/ide/idetop.ml
@@ -18,9 +18,8 @@ open Printer
module NamedDecl = Context.Named.Declaration
module CompactedDecl = Context.Compacted.Declaration
-(** Ide_slave : an implementation of [Interface], i.e. mainly an interp
- function and a rewind function. This specialized loop is triggered
- when the -ideslave option is passed to Coqtop. *)
+(** Idetop : an implementation of [Interface], i.e. mainly an interp
+ function and a rewind function. *)
(** Signal handling: we postpone ^C during input and output phases,
@@ -54,10 +53,12 @@ let coqide_known_option table = List.mem table [
["Printing";"Records"];
["Printing";"Existential";"Instances"];
["Printing";"Universes"];
- ["Printing";"Unfocused"]]
+ ["Printing";"Unfocused"];
+ ["Diffs"]]
let is_known_option cmd = match Vernacprop.under_control cmd with
| VernacSetOption (_, o, BoolValue true)
+ | VernacSetOption (_, o, StringValue _)
| VernacUnsetOption (_, o) -> coqide_known_option o
| _ -> false
@@ -81,7 +82,7 @@ let set_doc doc = ide_doc := Some doc
let add ((s,eid),(sid,verbose)) =
let doc = get_doc () in
- let pa = Pcoq.Gram.parsable (Stream.of_string s) in
+ let pa = Pcoq.Parsable.make (Stream.of_string s) in
let loc_ast = Stm.parse_sentence ~doc sid pa in
let doc, newid, rc = Stm.add ~doc ~ontop:sid verbose loc_ast in
set_doc doc;
@@ -114,14 +115,14 @@ let edit_at id =
* be removed in the next version of the protocol.
*)
let query (route, (s,id)) =
- let pa = Pcoq.Gram.parsable (Stream.of_string s) in
+ let pa = Pcoq.Parsable.make (Stream.of_string s) in
let doc = get_doc () in
Stm.query ~at:id ~doc ~route pa
let annotate phrase =
let doc = get_doc () in
let {CAst.loc;v=ast} =
- let pa = Pcoq.Gram.parsable (Stream.of_string phrase) in
+ let pa = Pcoq.Parsable.make (Stream.of_string phrase) in
Stm.parse_sentence ~doc (Stm.get_current_state ~doc) pa
in
(* XXX: Width should be a parameter of annotate... *)
@@ -152,7 +153,7 @@ let hyp_next_tac sigma env decl =
("inversion clear "^id_s), ("inversion_clear "^id_s^".")
]
-let concl_next_tac sigma concl =
+let concl_next_tac =
let expand s = (s,s^".") in
List.map expand ([
"intro";
@@ -207,9 +208,32 @@ let goals () =
let doc = get_doc () in
set_doc @@ Stm.finish ~doc;
try
- let pfts = Proof_global.give_me_the_proof () in
- Some (export_pre_goals (Proof.map_structured_proof pfts process_goal))
- with Proof_global.NoCurrentProof -> None
+ let newp = Proof_global.give_me_the_proof () in
+ if Proof_diffs.show_diffs () then begin
+ let oldp = Stm.get_prev_proof ~doc (Stm.get_current_state ~doc) in
+ let diff_goal_map = Proof_diffs.make_goal_map oldp newp in
+ let map_goal_for_diff ng = (* todo: move to proof_diffs.ml *)
+ try Evar.Map.find ng diff_goal_map with Not_found -> ng
+ in
+
+ let process_goal_diffs nsigma ng =
+ let open Evd in
+ let og = map_goal_for_diff ng in
+ let og_s = match oldp with
+ | Some oldp ->
+ let (_,_,_,_,osigma) = Proof.proof oldp in
+ Some { it = og; sigma = osigma }
+ | None -> None
+ in
+ let (hyps_pp_list, concl_pp) = Proof_diffs.diff_goal_ide og_s ng nsigma in
+ { Interface.goal_hyp = hyps_pp_list; Interface.goal_ccl = concl_pp; Interface.goal_id = Goal.uid ng }
+ in
+ try
+ Some (export_pre_goals (Proof.map_structured_proof newp process_goal_diffs))
+ with Pp_diff.Diff_Failure _ -> Some (export_pre_goals (Proof.map_structured_proof newp process_goal))
+ end else
+ Some (export_pre_goals (Proof.map_structured_proof newp process_goal))
+ with Proof_global.NoCurrentProof -> None;;
let evars () =
try
@@ -231,10 +255,9 @@ let hints () =
| [] -> None
| g :: _ ->
let env = Goal.V82.env sigma g in
- let hint_goal = concl_next_tac sigma g in
let get_hint_hyp env d accu = hyp_next_tac sigma env d :: accu in
let hint_hyps = List.rev (Environ.fold_named_context get_hint_hyp env ~init: []) in
- Some (hint_hyps, hint_goal)
+ Some (hint_hyps, concl_next_tac)
with Proof_global.NoCurrentProof -> None
@@ -273,7 +296,10 @@ let status force =
let export_coq_object t = {
Interface.coq_object_prefix = t.Search.coq_object_prefix;
Interface.coq_object_qualid = t.Search.coq_object_qualid;
- Interface.coq_object_object = Pp.string_of_ppcmds (pr_lconstr_env (Global.env ()) Evd.empty t.Search.coq_object_object)
+ Interface.coq_object_object =
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ Pp.string_of_ppcmds (pr_lconstr_env env sigma t.Search.coq_object_object)
}
let pattern_of_string ?env s =
@@ -283,13 +309,12 @@ let pattern_of_string ?env s =
| Some e -> e
in
let constr = Pcoq.parse_string Pcoq.Constr.lconstr_pattern s in
- let (_, pat) = Constrintern.intern_constr_pattern env Evd.empty constr in
+ let (_, pat) = Constrintern.intern_constr_pattern env (Evd.from_env env) constr in
pat
let dirpath_of_string_list s =
let path = String.concat "." s in
- let m = Pcoq.parse_string Pcoq.Constr.global path in
- let {CAst.v=qid} = Libnames.qualid_of_reference m in
+ let qid = Pcoq.parse_string Pcoq.Constr.global path in
let id =
try Nametab.full_name_module qid
with Not_found ->
@@ -352,15 +377,12 @@ let about () = {
}
let handle_exn (e, info) =
- let (e, info) = ExplainErr.process_vernac_interp_error (e, info) in
let dummy = Stateid.dummy in
let loc_of e = match Loc.get_loc e with
| Some loc -> Some (Loc.unloc loc)
| _ -> None in
let mk_msg () = CErrors.print ~info e in
match e with
- | CErrors.Drop -> dummy, None, Pp.str "Drop is not allowed by coqide!"
- | CErrors.Quit -> dummy, None, Pp.str "Quit is not allowed by coqide!"
| e ->
match Stateid.get info with
| Some (valid, _) -> valid, loc_of info, mk_msg ()
@@ -432,7 +454,7 @@ let eval_call c =
Xmlprotocol.abstract_eval_call handler c
(** Message dispatching.
- Since coqtop -ideslave starts 1 thread per slave, and each
+ Since [coqidetop] starts 1 thread per slave, and each
thread forwards feedback messages from the slave to the GUI on the same
xml channel, we need mutual exclusion. The mutex should be per-channel, but
here we only use 1 channel. *)
@@ -460,7 +482,7 @@ let msg_format = ref (fun () ->
(* The loop ignores the command line arguments as the current model delegates
its handing to the toplevel container. *)
-let loop _args ~state =
+let loop ~opts:_ ~state =
let open Vernac.State in
set_doc state.doc;
init_signal_handler ();
@@ -509,14 +531,16 @@ let rec parse = function
| x :: rest -> x :: parse rest
| [] -> []
-let () = Coqtop.toploop_init := (fun coq_args extra_args ->
- let args = parse extra_args in
- Flags.quiet := true;
- CoqworkmgrApi.(init High);
- args)
-
-let () = Coqtop.toploop_run := loop
-
let () = Usage.add_to_usage "coqidetop"
" --xml_format=Ppcmds serialize pretty printing messages using the std_ppcmds format\
\n --help-XML-protocol print documentation of the Coq XML protocol\n"
+
+let islave_init ~opts extra_args =
+ let args = parse extra_args in
+ CoqworkmgrApi.(init High);
+ opts, args
+
+let () =
+ let open Coqtop in
+ let custom = { init = islave_init; run = loop; } in
+ start_coq custom
diff --git a/ide/ideutils.ml b/ide/ideutils.ml
index bdb39e94..03396a5a 100644
--- a/ide/ideutils.ml
+++ b/ide/ideutils.ml
@@ -37,6 +37,11 @@ let flash_info =
let flash_context = status#new_context ~name:"Flash" in
(fun ?(delay=5000) s -> flash_context#flash ~delay s)
+(* Note: Setting the same attribute with two separate tags appears to use
+the first value applied and not the second. I saw this trying to set the background
+color on Windows. A clean fix, if ever needed, would be to combine the attributes
+of the tags into a single composite tag before applying. This is left as an
+exercise for the reader. *)
let insert_with_tags (buf : #GText.buffer_skel) mark rmark tags text =
(** FIXME: LablGTK2 does not export the C insert_with_tags function, so that
it has to reimplement its own helper function. Unluckily, it relies on
@@ -50,21 +55,51 @@ let insert_with_tags (buf : #GText.buffer_skel) mark rmark tags text =
let start = buf#get_iter_at_mark mark in
let stop = buf#get_iter_at_mark rmark in
let iter tag = buf#apply_tag tag ~start ~stop in
- List.iter iter tags
+ List.iter iter (List.rev tags)
+
+let nl_white_regex = Str.regexp "^\\( *\n *\\)"
+let diff_regex = Str.regexp "^diff."
let insert_xml ?(mark = `INSERT) ?(tags = []) (buf : #GText.buffer_skel) msg =
let open Xml_datatype in
+ let dtags = ref [] in
let tag name =
match GtkText.TagTable.lookup buf#tag_table name with
| None -> raise Not_found
| Some tag -> new GText.tag tag
in
let rmark = `MARK (buf#create_mark buf#start_iter) in
+ (* insert the string, but don't apply diff highlights to white space at the begin/end of line *)
+ let rec insert_str tags s =
+ let etags = try List.hd !dtags :: tags with hd -> tags in
+ try
+ let start = Str.search_forward nl_white_regex s 0 in
+ insert_with_tags buf mark rmark etags (String.sub s 0 start);
+ insert_with_tags buf mark rmark tags (Str.matched_group 1 s);
+ let mend = Str.match_end () in
+ insert_str tags (String.sub s mend (String.length s - mend))
+ with Not_found ->
+ insert_with_tags buf mark rmark etags s
+ in
let rec insert tags = function
- | PCData s -> insert_with_tags buf mark rmark tags s
+ | PCData s -> insert_str tags s
| Element (t, _, children) ->
- let tags = try tag t :: tags with Not_found -> tags in
- List.iter (fun xml -> insert tags xml) children
+ let (pfx, tname) = Pp.split_tag t in
+ let is_diff = try let _ = Str.search_forward diff_regex tname 0 in true with Not_found -> false in
+ let (tags, have_tag) =
+ try
+ let t = tag tname in
+ if is_diff && pfx <> Pp.end_pfx then
+ dtags := t :: !dtags;
+ if pfx = "" then
+ ((if is_diff then tags else t :: tags), true)
+ else
+ (tags, true)
+ with Not_found -> (tags, false)
+ in
+ List.iter (fun xml -> insert tags xml) children;
+ if have_tag && is_diff && pfx <> Pp.start_pfx then
+ dtags := (try List.tl !dtags with tl -> []);
in
let () = try insert tags msg with _ -> () in
buf#delete_mark rmark
@@ -289,16 +324,10 @@ let coqtop_path () =
| Some s -> s
| None ->
match cmd_coqtop#get with
- | Some s -> s
- | None ->
- try
- let old_prog = Sys.executable_name in
- let pos = String.length old_prog - 6 in
- let i = Str.search_backward (Str.regexp_string "coqide") old_prog pos
- in
- let new_prog = Bytes.of_string old_prog in
- Bytes.blit_string "coqtop" 0 new_prog i 6;
- let new_prog = Bytes.to_string new_prog in
+ | Some s -> s
+ | None ->
+ try
+ let new_prog = System.get_toplevel_path "coqidetop" in
if Sys.file_exists new_prog then new_prog
else
let in_macos_bundle =
@@ -306,8 +335,8 @@ let coqtop_path () =
(Filename.dirname new_prog)
(Filename.concat "../Resources/bin" (Filename.basename new_prog))
in if Sys.file_exists in_macos_bundle then in_macos_bundle
- else "coqtop"
- with Not_found -> "coqtop"
+ else "coqidetop"
+ with Not_found -> "coqidetop"
in file
(* In win32, when a command-line is to be executed via cmd.exe
diff --git a/ide/nanoPG.ml b/ide/nanoPG.ml
index 2be5dce4..f2913b1d 100644
--- a/ide/nanoPG.ml
+++ b/ide/nanoPG.ml
@@ -153,13 +153,13 @@ let emacs = insert emacs "Emacs" [] [
i#forward_sentence_end, { s with move = None }));
mkE ~mods:mM _a "a" "Move to beginning of sentence" (Motion(fun s i ->
i#backward_sentence_start, { s with move = None }));
- mkE _n "n" "Move to next line" ~alias:[[],_Down,"DOWN"] (Motion(fun s i ->
+ mkE _n "n" "Move to next line" (Motion(fun s i ->
let orig_off = Option.default i#line_offset s.move in
let i = i#forward_line in
let new_off = min (i#chars_in_line - 1) orig_off in
(if new_off > 0 then i#set_line_offset new_off else i),
{ s with move = Some orig_off }));
- mkE _p "p" "Move to previous line" ~alias:[[],_Up,"UP"] (Motion(fun s i ->
+ mkE _p "p" "Move to previous line" (Motion(fun s i ->
let orig_off = Option.default i#line_offset s.move in
let i = i#backward_line in
let new_off = min (i#chars_in_line - 1) orig_off in
@@ -189,7 +189,7 @@ let emacs = insert emacs "Emacs" [] [
run "Edit" "Cut";
{ s with kill = Some(txt,false); sel = false }
else s));
- mkE _k "k" "Kill untill the end of line" (Edit(fun s b i _ ->
+ mkE _k "k" "Kill until the end of line" (Edit(fun s b i _ ->
let already_killed = match s.kill with Some (k,true) -> k | _ -> "" in
let k =
if i#ends_line then begin
diff --git a/ide/preferences.ml b/ide/preferences.ml
index 11aaf6e8..955ee878 100644
--- a/ide/preferences.ml
+++ b/ide/preferences.ml
@@ -25,6 +25,7 @@ type tag = {
tag_bold : bool;
tag_italic : bool;
tag_underline : bool;
+ tag_strikethrough : bool;
}
(** Generic preferences *)
@@ -215,15 +216,17 @@ object
string_of_bool tag.tag_bold;
string_of_bool tag.tag_italic;
string_of_bool tag.tag_underline;
+ string_of_bool tag.tag_strikethrough;
]
method into = function
- | [fg; bg; bd; it; ul] ->
+ | [fg; bg; bd; it; ul; st] ->
(try Some {
tag_fg_color = _to fg;
tag_bg_color = _to bg;
tag_bold = bool_of_string bd;
tag_italic = bool_of_string it;
tag_underline = bool_of_string ul;
+ tag_strikethrough = bool_of_string st;
}
with _ -> None)
| _ -> None
@@ -429,12 +432,13 @@ let tags = ref Util.String.Map.empty
let list_tags () = !tags
-let make_tag ?fg ?bg ?(bold = false) ?(italic = false) ?(underline = false) () = {
+let make_tag ?fg ?bg ?(bold = false) ?(italic = false) ?(underline = false) ?(strikethrough = false) () = {
tag_fg_color = fg;
tag_bg_color = bg;
tag_bold = bold;
tag_italic = italic;
tag_underline = underline;
+ tag_strikethrough = strikethrough;
}
let create_tag name default =
@@ -470,6 +474,12 @@ let create_tag name default =
tag#set_property (`UNDERLINE_SET true);
tag#set_property (`UNDERLINE `SINGLE)
end;
+ begin match pref#get.tag_strikethrough with
+ | false -> tag#set_property (`STRIKETHROUGH_SET false)
+ | true ->
+ tag#set_property (`STRIKETHROUGH_SET true);
+ tag#set_property (`STRIKETHROUGH true)
+ end;
in
let iter table =
let tag = GText.tag ~name () in
@@ -480,6 +490,8 @@ let create_tag name default =
List.iter iter [Tags.Script.table; Tags.Proof.table; Tags.Message.table];
tags := Util.String.Map.add name pref !tags
+(* note these appear to only set the defaults; they don't override
+the user selection from the Edit/Preferences/Tags dialog *)
let () =
let iter (name, tag) = create_tag name tag in
List.iter iter [
@@ -498,6 +510,10 @@ let () =
("tactic.keyword", make_tag ());
("tactic.primitive", make_tag ());
("tactic.string", make_tag ());
+ ("diff.added", make_tag ~bg:"#b6f1c0" ~underline:true ());
+ ("diff.removed", make_tag ~bg:"#f6b9c1" ~strikethrough:true ());
+ ("diff.added.bg", make_tag ~bg:"#e9feee" ());
+ ("diff.removed.bg", make_tag ~bg:"#fce9eb" ());
]
let processed_color =
@@ -549,6 +565,9 @@ let nanoPG =
let user_queries =
new preference ~name:["user_queries"] ~init:[] ~repr:Repr.(string_pair_list '$')
+let diffs =
+ new preference ~name:["diffs"] ~init:"off" ~repr:Repr.(string)
+
class tag_button (box : Gtk.box Gtk.obj) =
object (self)
@@ -561,6 +580,7 @@ object (self)
val bold = GButton.toggle_button ()
val italic = GButton.toggle_button ()
val underline = GButton.toggle_button ()
+ val strikethrough = GButton.toggle_button ()
method set_tag tag =
let track c but set = match c with
@@ -574,6 +594,7 @@ object (self)
bold#set_active tag.tag_bold;
italic#set_active tag.tag_italic;
underline#set_active tag.tag_underline;
+ strikethrough#set_active tag.tag_strikethrough;
method tag =
let get but set =
@@ -586,6 +607,7 @@ object (self)
tag_bold = bold#active;
tag_italic = italic#active;
tag_underline = underline#active;
+ tag_strikethrough = strikethrough#active;
}
initializer
@@ -599,6 +621,7 @@ object (self)
set_stock bold `BOLD;
set_stock italic `ITALIC;
set_stock underline `UNDERLINE;
+ set_stock strikethrough `STRIKETHROUGH;
box#pack fg_color#coerce;
box#pack fg_unset#coerce;
box#pack bg_color#coerce;
@@ -606,6 +629,7 @@ object (self)
box#pack bold#coerce;
box#pack italic#coerce;
box#pack underline#coerce;
+ box#pack strikethrough#coerce;
let cb but obj = obj#set_sensitive (not but#active) in
let _ = fg_unset#connect#toggled ~callback:(fun () -> cb fg_unset fg_color#misc) in
let _ = bg_unset#connect#toggled ~callback:(fun () -> cb bg_unset bg_color#misc) in
diff --git a/ide/preferences.mli b/ide/preferences.mli
index ccf028ae..dd2976ef 100644
--- a/ide/preferences.mli
+++ b/ide/preferences.mli
@@ -21,6 +21,7 @@ type tag = {
tag_bold : bool;
tag_italic : bool;
tag_underline : bool;
+ tag_strikethrough : bool;
}
class type ['a] repr =
@@ -101,6 +102,7 @@ val tab_length : int preference
val highlight_current_line : bool preference
val nanoPG : bool preference
val user_queries : (string * string) list preference
+val diffs : string preference
val save_pref : unit -> unit
val load_pref : unit -> unit
diff --git a/ide/protocol/ideprotocol.mllib b/ide/protocol/ideprotocol.mllib
new file mode 100644
index 00000000..8317a086
--- /dev/null
+++ b/ide/protocol/ideprotocol.mllib
@@ -0,0 +1,7 @@
+Xml_lexer
+Xml_parser
+Xml_printer
+Serialize
+Richpp
+Interface
+Xmlprotocol
diff --git a/ide/interface.mli b/ide/protocol/interface.ml
index debbc830..debbc830 100644
--- a/ide/interface.mli
+++ b/ide/protocol/interface.ml
diff --git a/ide/richpp.ml b/ide/protocol/richpp.ml
index 19e9799c..19e9799c 100644
--- a/ide/richpp.ml
+++ b/ide/protocol/richpp.ml
diff --git a/ide/richpp.mli b/ide/protocol/richpp.mli
index 31fc7b56..31fc7b56 100644
--- a/ide/richpp.mli
+++ b/ide/protocol/richpp.mli
diff --git a/ide/serialize.ml b/ide/protocol/serialize.ml
index 86074d44..86074d44 100644
--- a/ide/serialize.ml
+++ b/ide/protocol/serialize.ml
diff --git a/ide/serialize.mli b/ide/protocol/serialize.mli
index af082f25..af082f25 100644
--- a/ide/serialize.mli
+++ b/ide/protocol/serialize.mli
diff --git a/ide/xml_lexer.mli b/ide/protocol/xml_lexer.mli
index e61cb055..e61cb055 100644
--- a/ide/xml_lexer.mli
+++ b/ide/protocol/xml_lexer.mli
diff --git a/ide/xml_lexer.mll b/ide/protocol/xml_lexer.mll
index 4a52147e..4a52147e 100644
--- a/ide/xml_lexer.mll
+++ b/ide/protocol/xml_lexer.mll
diff --git a/ide/xml_parser.ml b/ide/protocol/xml_parser.ml
index 8db3f9e8..8db3f9e8 100644
--- a/ide/xml_parser.ml
+++ b/ide/protocol/xml_parser.ml
diff --git a/ide/xml_parser.mli b/ide/protocol/xml_parser.mli
index ac2eab35..ac2eab35 100644
--- a/ide/xml_parser.mli
+++ b/ide/protocol/xml_parser.mli
diff --git a/ide/xml_printer.ml b/ide/protocol/xml_printer.ml
index 488ef7bf..488ef7bf 100644
--- a/ide/xml_printer.ml
+++ b/ide/protocol/xml_printer.ml
diff --git a/ide/xml_printer.mli b/ide/protocol/xml_printer.mli
index 178f7c80..178f7c80 100644
--- a/ide/xml_printer.mli
+++ b/ide/protocol/xml_printer.mli
diff --git a/ide/xmlprotocol.ml b/ide/protocol/xmlprotocol.ml
index e1821921..e1821921 100644
--- a/ide/xmlprotocol.ml
+++ b/ide/protocol/xmlprotocol.ml
diff --git a/ide/xmlprotocol.mli b/ide/protocol/xmlprotocol.mli
index ba6000f0..ba6000f0 100644
--- a/ide/xmlprotocol.mli
+++ b/ide/protocol/xmlprotocol.mli
diff --git a/ide/wg_Command.ml b/ide/wg_Command.ml
index 8eddfb31..06281d62 100644
--- a/ide/wg_Command.ml
+++ b/ide/wg_Command.ml
@@ -98,7 +98,7 @@ object(self)
~packing:(vbox#pack ~fill:true ~expand:true) () in
let result = Wg_MessageView.message_view () in
router#register_route route_id result;
- r_bin#add (result :> GObj.widget);
+ r_bin#add_with_viewport (result :> GObj.widget);
views <- (frame#coerce, result, combo#entry) :: views;
let cb clr = result#misc#modify_base [`NORMAL, `NAME clr] in
let _ = background_color#connect#changed ~callback:cb in
@@ -152,9 +152,9 @@ object(self)
method show =
frame#show;
let cur_page = notebook#get_nth_page notebook#current_page in
- let _, _, e =
- List.find (fun (p,_,_) -> p#get_oid == cur_page#get_oid) views in
- e#misc#grab_focus ()
+ match List.find (fun (p,_,_) -> p#get_oid == cur_page#get_oid) views with
+ | (_, _, e) -> e#misc#grab_focus ()
+ | exception Not_found -> ()
method hide =
frame#hide
diff --git a/intf/constrexpr.ml b/interp/constrexpr.ml
index 542eb38a..77d612cf 100644
--- a/intf/constrexpr.ml
+++ b/interp/constrexpr.ml
@@ -10,19 +10,29 @@
open Names
open Libnames
-open Misctypes
open Decl_kinds
(** {6 Concrete syntax for terms } *)
(** [constr_expr] is the abstract syntax tree produced by the parser *)
-
-type universe_decl_expr = (lident list, glob_constraint list) gen_universe_decl
+type universe_decl_expr = (lident list, Glob_term.glob_constraint list) UState.gen_universe_decl
type ident_decl = lident * universe_decl_expr option
type name_decl = lname * universe_decl_expr option
-type notation = string
+type notation_entry = InConstrEntry | InCustomEntry of string
+type notation_entry_level = InConstrEntrySomeLevel | InCustomEntryLevel of string * int
+type notation_key = string
+type notation = notation_entry_level * notation_key
+
+type 'a or_by_notation_r =
+ | AN of 'a
+ | ByNotation of (string * string option)
+
+type 'a or_by_notation = 'a or_by_notation_r CAst.t
+
+(* NB: the last string in [ByNotation] is actually a [Notation.delimiters],
+ but this formulation avoids a useless dependency. *)
type explicitation =
| ExplByPos of int * Id.t option (* a reference to the n-th product starting from left *)
@@ -50,21 +60,21 @@ type prim_token =
| Numeral of raw_natural_number * sign
| String of string
-type instance_expr = Misctypes.glob_level list
+type instance_expr = Glob_term.glob_level list
type cases_pattern_expr_r =
| CPatAlias of cases_pattern_expr * lname
- | CPatCstr of reference
+ | CPatCstr of qualid
* cases_pattern_expr list option * cases_pattern_expr list
(** [CPatCstr (_, c, Some l1, l2)] represents [(@ c l1) l2] *)
- | CPatAtom of reference option
+ | CPatAtom of qualid option
| CPatOr of cases_pattern_expr list
| CPatNotation of notation * cases_pattern_notation_substitution
* cases_pattern_expr list (** CPatNotation (_, n, l1 ,l2) represents
(notation n applied with substitution l1)
applied to arguments l2 *)
| CPatPrim of prim_token
- | CPatRecord of (reference * cases_pattern_expr) list
+ | CPatRecord of (qualid * cases_pattern_expr) list
| CPatDelimiters of string * cases_pattern_expr
| CPatCast of cases_pattern_expr * constr_expr
and cases_pattern_expr = cases_pattern_expr_r CAst.t
@@ -74,16 +84,16 @@ and cases_pattern_notation_substitution =
cases_pattern_expr list list (** for recursive notations *)
and constr_expr_r =
- | CRef of reference * instance_expr option
+ | CRef of qualid * instance_expr option
| CFix of lident * fix_expr list
| CCoFix of lident * cofix_expr list
| CProdN of local_binder_expr list * constr_expr
| CLambdaN of local_binder_expr list * constr_expr
| CLetIn of lname * constr_expr * constr_expr option * constr_expr
- | CAppExpl of (proj_flag * reference * instance_expr option) * constr_expr list
+ | CAppExpl of (proj_flag * qualid * instance_expr option) * constr_expr list
| CApp of (proj_flag * constr_expr) *
(constr_expr * explicitation CAst.t option) list
- | CRecord of (reference * constr_expr) list
+ | CRecord of (qualid * constr_expr) list
(* representation of the "let" and "match" constructs *)
| CCases of Constr.case_style (* determines whether this value represents "let" or "match" construct *)
@@ -95,11 +105,11 @@ and constr_expr_r =
constr_expr * constr_expr
| CIf of constr_expr * (lname option * constr_expr option)
* constr_expr * constr_expr
- | CHole of Evar_kinds.t option * intro_pattern_naming_expr * Genarg.raw_generic_argument option
- | CPatVar of patvar
+ | CHole of Evar_kinds.t option * Namegen.intro_pattern_naming_expr * Genarg.raw_generic_argument option
+ | CPatVar of Pattern.patvar
| CEvar of Glob_term.existential_name * (Id.t * constr_expr) list
- | CSort of glob_sort
- | CCast of constr_expr * constr_expr cast_type
+ | CSort of Glob_term.glob_sort
+ | CCast of constr_expr * constr_expr Glob_term.cast_type
| CNotation of notation * constr_notation_substitution
| CGeneralization of binding_kind * abstraction_kind option * constr_expr
| CPrim of prim_token
@@ -142,7 +152,7 @@ type constr_pattern_expr = constr_expr
(** Concrete syntax for modules and module types *)
type with_declaration_ast =
- | CWith_Module of Id.t list CAst.t * qualid CAst.t
+ | CWith_Module of Id.t list CAst.t * qualid
| CWith_Definition of Id.t list CAst.t * universe_decl_expr option * constr_expr
type module_ast_r =
diff --git a/interp/constrexpr_ops.ml b/interp/constrexpr_ops.ml
index 004c9356..23d0536d 100644
--- a/interp/constrexpr_ops.ml
+++ b/interp/constrexpr_ops.ml
@@ -10,12 +10,13 @@
open Pp
open Util
-open CAst
open Names
open Nameops
open Libnames
+open Namegen
+open Glob_term
open Constrexpr
-open Misctypes
+open Notation
open Decl_kinds
(***********************)
@@ -72,22 +73,22 @@ let rec cases_pattern_expr_eq p1 p2 =
| CPatAlias(a1,i1), CPatAlias(a2,i2) ->
eq_ast Name.equal i1 i2 && cases_pattern_expr_eq a1 a2
| CPatCstr(c1,a1,b1), CPatCstr(c2,a2,b2) ->
- eq_reference c1 c2 &&
+ qualid_eq c1 c2 &&
Option.equal (List.equal cases_pattern_expr_eq) a1 a2 &&
List.equal cases_pattern_expr_eq b1 b2
| CPatAtom(r1), CPatAtom(r2) ->
- Option.equal eq_reference r1 r2
+ Option.equal qualid_eq r1 r2
| CPatOr a1, CPatOr a2 ->
List.equal cases_pattern_expr_eq a1 a2
| CPatNotation (n1, s1, l1), CPatNotation (n2, s2, l2) ->
- String.equal n1 n2 &&
+ notation_eq n1 n2 &&
cases_pattern_notation_substitution_eq s1 s2 &&
List.equal cases_pattern_expr_eq l1 l2
| CPatPrim i1, CPatPrim i2 ->
prim_token_eq i1 i2
| CPatRecord l1, CPatRecord l2 ->
let equal (r1, e1) (r2, e2) =
- eq_reference r1 r2 && cases_pattern_expr_eq e1 e2
+ qualid_eq r1 r2 && cases_pattern_expr_eq e1 e2
in
List.equal equal l1 l2
| CPatDelimiters(s1,e1), CPatDelimiters(s2,e2) ->
@@ -107,7 +108,7 @@ let eq_universes u1 u2 =
let rec constr_expr_eq e1 e2 =
if CAst.(e1.v == e2.v) then true
else match CAst.(e1.v, e2.v) with
- | CRef (r1,u1), CRef (r2,u2) -> eq_reference r1 r2 && eq_universes u1 u2
+ | CRef (r1,u1), CRef (r2,u2) -> qualid_eq r1 r2 && eq_universes u1 u2
| CFix(id1,fl1), CFix(id2,fl2) ->
eq_ast Id.equal id1 id2 &&
List.equal fix_expr_eq fl1 fl2
@@ -127,7 +128,7 @@ let rec constr_expr_eq e1 e2 =
constr_expr_eq b1 b2
| CAppExpl((proj1,r1,_),al1), CAppExpl((proj2,r2,_),al2) ->
Option.equal Int.equal proj1 proj2 &&
- eq_reference r1 r2 &&
+ qualid_eq r1 r2 &&
List.equal constr_expr_eq al1 al2
| CApp((proj1,e1),al1), CApp((proj2,e2),al2) ->
Option.equal Int.equal proj1 proj2 &&
@@ -135,7 +136,7 @@ let rec constr_expr_eq e1 e2 =
List.equal args_eq al1 al2
| CRecord l1, CRecord l2 ->
let field_eq (r1, e1) (r2, e2) =
- eq_reference r1 r2 && constr_expr_eq e1 e2
+ qualid_eq r1 r2 && constr_expr_eq e1 e2
in
List.equal field_eq l1 l2
| CCases(_,r1,a1,brl1), CCases(_,r2,a2,brl2) ->
@@ -161,11 +162,11 @@ let rec constr_expr_eq e1 e2 =
| CEvar (id1, c1), CEvar (id2, c2) ->
Id.equal id1 id2 && List.equal instance_eq c1 c2
| CSort s1, CSort s2 ->
- Miscops.glob_sort_eq s1 s2
+ Glob_ops.glob_sort_eq s1 s2
| CCast(t1,c1), CCast(t2,c2) ->
constr_expr_eq t1 t2 && cast_expr_eq c1 c2
| CNotation(n1, s1), CNotation(n2, s2) ->
- String.equal n1 n2 &&
+ notation_eq n1 n2 &&
constr_notation_substitution_eq s1 s2
| CPrim i1, CPrim i2 ->
prim_token_eq i1 i2
@@ -179,7 +180,7 @@ let rec constr_expr_eq e1 e2 =
| (CRef _ | CFix _ | CCoFix _ | CProdN _ | CLambdaN _ | CLetIn _ | CAppExpl _
| CApp _ | CRecord _ | CCases _ | CLetTuple _ | CIf _ | CHole _
| CPatVar _ | CEvar _ | CSort _ | CCast _ | CNotation _ | CPrim _
- | CGeneralization _ | CDelimiters _), _ -> false
+ | CGeneralization _ | CDelimiters _ ), _ -> false
and args_eq (a1,e1) (a2,e2) =
Option.equal (eq_ast explicitation_eq) e1 e2 &&
@@ -277,7 +278,9 @@ let rec cases_pattern_fold_names f a pt = match CAst.(pt.v) with
List.fold_left (cases_pattern_fold_names f)
(List.fold_left (cases_pattern_fold_names f) a (patl@List.flatten patll)) patl'
| CPatDelimiters (_,pat) -> cases_pattern_fold_names f a pat
- | CPatAtom (Some {v=Ident id}) when not (is_constructor id) -> f id a
+ | CPatAtom (Some qid)
+ when qualid_is_ident qid && not (is_constructor @@ qualid_basename qid) ->
+ f (qualid_basename qid) a
| CPatPrim _ | CPatAtom _ -> a
| CPatCast ({CAst.loc},_) ->
CErrors.user_err ?loc ~hdr:"cases_pattern_fold_names"
@@ -358,7 +361,9 @@ let fold_constr_expr_with_binders g f n acc = CAst.with_val (function
let free_vars_of_constr_expr c =
let rec aux bdvars l = function
- | { CAst.v = CRef ({v=Ident id},_) } -> if Id.List.mem id bdvars then l else Id.Set.add id l
+ | { CAst.v = CRef (qid, _) } when qualid_is_ident qid ->
+ let id = qualid_basename qid in
+ if Id.List.mem id bdvars then l else Id.Set.add id l
| c -> fold_constr_expr_with_binders (fun a l -> a::l) aux bdvars l c
in aux [] Id.Set.empty c
@@ -391,7 +396,7 @@ let map_constr_expr_with_binders g f e = CAst.map (function
let (e,bl) = map_local_binders f g e bl in CLambdaN (bl,f e b)
| CLetIn (na,a,t,b) ->
CLetIn (na,f e a,Option.map (f e) t,f (Name.fold_right g (na.CAst.v) e) b)
- | CCast (a,c) -> CCast (f e a, Miscops.map_cast_type (f e) c)
+ | CCast (a,c) -> CCast (f e a, Glob_ops.map_cast_type (f e) c)
| CNotation (n,(l,ll,bl,bll)) ->
(* This is an approximation because we don't know what binds what *)
CNotation (n,(List.map (f e) l,List.map (List.map (f e)) ll, bl,
@@ -433,11 +438,13 @@ let map_constr_expr_with_binders g f e = CAst.map (function
)
(* Used in constrintern *)
-let rec replace_vars_constr_expr l = function
- | { CAst.loc; v = CRef ({v=Ident id},us) } as x ->
- (try CAst.make ?loc @@ CRef (make ?loc @@ Ident (Id.Map.find id l),us) with Not_found -> x)
- | c -> map_constr_expr_with_binders Id.Map.remove
- replace_vars_constr_expr l c
+let rec replace_vars_constr_expr l r =
+ match r with
+ | { CAst.loc; v = CRef (qid,us) } as x when qualid_is_ident qid ->
+ let id = qualid_basename qid in
+ (try CAst.make ?loc @@ CRef (qualid_of_ident ?loc (Id.Map.find id l),us)
+ with Not_found -> x)
+ | cn -> map_constr_expr_with_binders Id.Map.remove replace_vars_constr_expr l cn
(* Returns the ranges of locs of the notation that are not occupied by args *)
(* and which are then occupied by proper symbols of the notation (or spaces) *)
@@ -506,7 +513,7 @@ let split_at_annot bl na =
(** Pseudo-constructors *)
-let mkIdentC id = CAst.make @@ CRef (make @@ Ident id,None)
+let mkIdentC id = CAst.make @@ CRef (qualid_of_ident id,None)
let mkRefC r = CAst.make @@ CRef (r,None)
let mkCastC (a,k) = CAst.make @@ CCast (a,k)
let mkLambdaC (idl,bk,a,b) = CAst.make @@ CLambdaN ([CLocalAssum (idl,bk,a)],b)
@@ -525,21 +532,23 @@ let mkCProdN ?loc bll c =
let mkCLambdaN ?loc bll c =
CAst.make ?loc @@ CLambdaN (bll,c)
-let coerce_reference_to_id = CAst.with_loc_val (fun ?loc -> function
- | Ident id -> id
- | Qualid _ ->
- CErrors.user_err ?loc ~hdr:"coerce_reference_to_id"
- (str "This expression should be a simple identifier."))
+let coerce_reference_to_id qid =
+ if qualid_is_ident qid then qualid_basename qid
+ else
+ CErrors.user_err ?loc:qid.CAst.loc ~hdr:"coerce_reference_to_id"
+ (str "This expression should be a simple identifier.")
let coerce_to_id = function
- | { CAst.loc; v = CRef ({v=Ident id},None) } -> CAst.make ?loc id
+ | { CAst.loc; v = CRef (qid,None) } when qualid_is_ident qid ->
+ CAst.make ?loc @@ qualid_basename qid
| { CAst.loc; _ } -> CErrors.user_err ?loc
~hdr:"coerce_to_id"
(str "This expression should be a simple identifier.")
let coerce_to_name = function
- | { CAst.loc; v = CRef ({v=Ident id},None) } -> CAst.make ?loc @@ Name id
- | { CAst.loc; v = CHole (None,Misctypes.IntroAnonymous,None) } -> CAst.make ?loc Anonymous
+ | { CAst.loc; v = CRef (qid,None) } when qualid_is_ident qid ->
+ CAst.make ?loc @@ Name (qualid_basename qid)
+ | { CAst.loc; v = CHole (None,IntroAnonymous,None) } -> CAst.make ?loc Anonymous
| { CAst.loc; _ } -> CErrors.user_err ?loc ~hdr:"coerce_to_name"
(str "This expression should be a name.")
@@ -563,9 +572,10 @@ let mkAppPattern ?loc p lp =
let rec coerce_to_cases_pattern_expr c = CAst.map_with_loc (fun ?loc -> function
| CRef (r,None) ->
CPatAtom (Some r)
- | CHole (None,Misctypes.IntroAnonymous,None) ->
+ | CHole (None,IntroAnonymous,None) ->
CPatAtom None
- | CLetIn ({CAst.loc;v=Name id},b,None,{ CAst.v = CRef ({v=Ident id'},None) }) when Id.equal id id' ->
+ | CLetIn ({CAst.loc;v=Name id},b,None,{ CAst.v = CRef (qid,None) })
+ when qualid_is_ident qid && Id.equal id (qualid_basename qid) ->
CPatAlias (coerce_to_cases_pattern_expr b, CAst.(make ?loc @@ Name id))
| CApp ((None,p),args) when List.for_all (fun (_,e) -> e=None) args ->
(mkAppPattern (coerce_to_cases_pattern_expr p) (List.map (fun (a,_) -> coerce_to_cases_pattern_expr a) args)).CAst.v
@@ -595,7 +605,34 @@ let _ = Goptions.declare_bool_option {
Goptions.optwrite = (fun a -> asymmetric_patterns:=a);
}
-(************************************************************************)
-(* Deprecated *)
-let abstract_constr_expr c bl = mkCLambdaN ?loc:(local_binders_loc bl) bl c
-let prod_constr_expr c bl = mkCProdN ?loc:(local_binders_loc bl) bl c
+(** Local universe and constraint declarations. *)
+
+let interp_univ_constraints env evd cstrs =
+ let interp (evd,cstrs) (u, d, u') =
+ let ul = Pretyping.interp_known_glob_level evd u in
+ let u'l = Pretyping.interp_known_glob_level evd u' in
+ let cstr = (ul,d,u'l) in
+ let cstrs' = Univ.Constraint.add cstr cstrs in
+ try let evd = Evd.add_constraints evd (Univ.Constraint.singleton cstr) in
+ evd, cstrs'
+ with Univ.UniverseInconsistency e ->
+ CErrors.user_err ~hdr:"interp_constraint"
+ (Univ.explain_universe_inconsistency (Termops.pr_evd_level evd) e)
+ in
+ List.fold_left interp (evd,Univ.Constraint.empty) cstrs
+
+let interp_univ_decl env decl =
+ let open UState in
+ let pl : lident list = decl.univdecl_instance in
+ let evd = Evd.from_ctx (UState.make_with_initial_binders (Environ.universes env) pl) in
+ let evd, cstrs = interp_univ_constraints env evd decl.univdecl_constraints in
+ let decl = { univdecl_instance = pl;
+ univdecl_extensible_instance = decl.univdecl_extensible_instance;
+ univdecl_constraints = cstrs;
+ univdecl_extensible_constraints = decl.univdecl_extensible_constraints }
+ in evd, decl
+
+let interp_univ_decl_opt env l =
+ match l with
+ | None -> Evd.from_env env, UState.default_univ_decl
+ | Some decl -> interp_univ_decl env decl
diff --git a/interp/constrexpr_ops.mli b/interp/constrexpr_ops.mli
index d038bd71..61e8aa1b 100644
--- a/interp/constrexpr_ops.mli
+++ b/interp/constrexpr_ops.mli
@@ -10,7 +10,6 @@
open Names
open Libnames
-open Misctypes
open Constrexpr
(** Constrexpr_ops: utilities on [constr_expr] *)
@@ -42,9 +41,9 @@ val local_binders_loc : local_binder_expr list -> Loc.t option
(** {6 Constructors}*)
val mkIdentC : Id.t -> constr_expr
-val mkRefC : reference -> constr_expr
+val mkRefC : qualid -> constr_expr
val mkAppC : constr_expr * constr_expr list -> constr_expr
-val mkCastC : constr_expr * constr_expr cast_type -> constr_expr
+val mkCastC : constr_expr * constr_expr Glob_term.cast_type -> constr_expr
val mkLambdaC : lname list * binder_kind * constr_expr * constr_expr -> constr_expr
val mkLetInC : lname * constr_expr * constr_expr option * constr_expr -> constr_expr
val mkProdC : lname list * binder_kind * constr_expr * constr_expr -> constr_expr
@@ -60,17 +59,9 @@ val mkCPatOr : ?loc:Loc.t -> cases_pattern_expr list -> cases_pattern_expr
val mkAppPattern : ?loc:Loc.t -> cases_pattern_expr -> cases_pattern_expr list -> cases_pattern_expr
(** Apply a list of pattern arguments to a pattern *)
-(** @deprecated variant of mkCLambdaN *)
-val abstract_constr_expr : constr_expr -> local_binder_expr list -> constr_expr
-[@@ocaml.deprecated "deprecated variant of mkCLambdaN"]
-
-(** @deprecated variant of mkCProdN *)
-val prod_constr_expr : constr_expr -> local_binder_expr list -> constr_expr
-[@@ocaml.deprecated "deprecated variant of mkCProdN"]
-
(** {6 Destructors}*)
-val coerce_reference_to_id : reference -> Id.t
+val coerce_reference_to_id : qualid -> Id.t
(** FIXME: nothing to do here *)
val coerce_to_id : constr_expr -> lident
@@ -116,11 +107,18 @@ val occur_var_constr_expr : Id.t -> constr_expr -> bool
val split_at_annot : local_binder_expr list -> lident option -> local_binder_expr list * local_binder_expr list
-val ntn_loc : ?loc:Loc.t -> constr_notation_substitution -> string -> (int * int) list
-val patntn_loc : ?loc:Loc.t -> cases_pattern_notation_substitution -> string -> (int * int) list
+val ntn_loc : ?loc:Loc.t -> constr_notation_substitution -> notation -> (int * int) list
+val patntn_loc : ?loc:Loc.t -> cases_pattern_notation_substitution -> notation -> (int * int) list
(** For cases pattern parsing errors *)
val error_invalid_pattern_notation : ?loc:Loc.t -> unit -> 'a
(** Placeholder for global option, should be moved to a parameter *)
val asymmetric_patterns : bool ref
+
+(** Local universe and constraint declarations. *)
+val interp_univ_decl : Environ.env -> universe_decl_expr ->
+ Evd.evar_map * UState.universe_decl
+
+val interp_univ_decl_opt : Environ.env -> universe_decl_expr option ->
+ Evd.evar_map * UState.universe_decl
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index af44921e..754fb3b9 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -14,10 +14,10 @@ open CErrors
open Util
open Names
open Nameops
-open Constr
open Termops
open Libnames
open Globnames
+open Namegen
open Impargs
open CAst
open Constrexpr
@@ -29,7 +29,6 @@ open Pattern
open Nametab
open Notation
open Detyping
-open Misctypes
open Decl_kinds
module NamedDecl = Context.Named.Declaration
@@ -102,8 +101,8 @@ let _show_inactive_notations () =
IRuleSet.iter
(function
| NotationRule (scopt, ntn) ->
- Feedback.msg_notice (str ntn ++ show_scope scopt)
- | SynDefRule kn -> Feedback.msg_notice (str (Names.KerName.to_string kn)))
+ Feedback.msg_notice (pr_notation ntn ++ show_scope scopt)
+ | SynDefRule kn -> Feedback.msg_notice (str (string_of_qualid (Nametab.shortest_qualid_of_syndef Id.Set.empty kn))))
!inactive_notations_table
let deactivate_notation nr =
@@ -114,14 +113,14 @@ let deactivate_notation nr =
| NotationRule (scopt, ntn) ->
match availability_of_notation (scopt, ntn) (scopt, []) with
| None -> user_err ~hdr:"Notation"
- (str ntn ++ spc () ++ str "does not exist"
+ (pr_notation ntn ++ spc () ++ str "does not exist"
++ (match scopt with
| None -> spc () ++ str "in the empty scope."
| Some _ -> show_scope scopt ++ str "."))
| Some _ ->
if IRuleSet.mem nr !inactive_notations_table then
Feedback.msg_warning
- (str "Notation" ++ spc () ++ str ntn ++ spc ()
+ (str "Notation" ++ spc () ++ pr_notation ntn ++ spc ()
++ str "is already inactive" ++ show_scope scopt ++ str ".")
else inactive_notations_table := IRuleSet.add nr !inactive_notations_table
@@ -132,12 +131,13 @@ let reactivate_notation nr =
with Not_found ->
match nr with
| NotationRule (scopt, ntn) ->
- Feedback.msg_warning (str "Notation" ++ spc () ++ str ntn ++ spc ()
+ Feedback.msg_warning (str "Notation" ++ spc () ++ pr_notation ntn ++ spc ()
++ str "is already active" ++ show_scope scopt ++
str ".")
| SynDefRule kn ->
+ let s = string_of_qualid (Nametab.shortest_qualid_of_syndef Id.Set.empty kn) in
Feedback.msg_warning
- (str "Notation" ++ spc () ++ str (Names.KerName.to_string kn)
+ (str "Notation" ++ spc () ++ str s
++ spc () ++ str "is already active.")
@@ -261,6 +261,14 @@ let insert_pat_alias ?loc p = function
| Anonymous -> p
| Name _ as na -> CAst.make ?loc @@ CPatAlias (p,(CAst.make ?loc na))
+let rec insert_coercion ?loc l c = match l with
+ | [] -> c
+ | ntn::l -> CAst.make ?loc @@ CNotation (ntn,([insert_coercion ?loc l c],[],[],[]))
+
+let rec insert_pat_coercion ?loc l c = match l with
+ | [] -> c
+ | ntn::l -> CAst.make ?loc @@ CPatNotation (ntn,([insert_pat_coercion ?loc l c],[]),[])
+
(**********************************************************************)
(* conversion of references *)
@@ -271,7 +279,7 @@ let extern_evar n l = CEvar (n,l)
may be inaccurate *)
let default_extern_reference ?loc vars r =
- make @@ Qualid (shortest_qualid_of_global vars r)
+ shortest_qualid_of_global ?loc vars r
let my_extern_reference = ref default_extern_reference
@@ -326,16 +334,16 @@ let is_zero s =
in aux 0
let make_notation_gen loc ntn mknot mkprim destprim l bl =
- match ntn,List.map destprim l with
+ match snd ntn,List.map destprim l with
(* Special case to avoid writing "- 3" for e.g. (Z.opp 3) *)
| "- _", [Some (Numeral (p,true))] when not (is_zero p) ->
assert (bl=[]);
- mknot (loc,ntn,([mknot (loc,"( _ )",l,[])]),[])
+ mknot (loc,ntn,([mknot (loc,(InConstrEntrySomeLevel,"( _ )"),l,[])]),[])
| _ ->
match decompose_notation_key ntn, l with
- | [Terminal "-"; Terminal x], [] when is_number x ->
+ | (InConstrEntrySomeLevel,[Terminal "-"; Terminal x]), [] when is_number x ->
mkprim (loc, Numeral (x,false))
- | [Terminal x], [] when is_number x ->
+ | (InConstrEntrySomeLevel,[Terminal x]), [] when is_number x ->
mkprim (loc, Numeral (x,true))
| _ -> mknot (loc,ntn,l,bl)
@@ -368,31 +376,39 @@ let pattern_printable_in_both_syntax (ind,_ as c) =
(List.for_all is_status_implicit params)&&(List.for_all (fun x -> not (is_status_implicit x)) args)
) impl_st
-let lift f c =
- let loc = c.CAst.loc in
- CAst.make ?loc (f ?loc (DAst.get c))
-
(* Better to use extern_glob_constr composed with injection/retraction ?? *)
-let rec extern_cases_pattern_in_scope (scopes:local_scopes) vars pat =
+let rec extern_cases_pattern_in_scope (custom,scopes as allscopes) vars pat =
try
if !Flags.in_debugger || !Flags.raw_print || !print_no_symbol then raise No_match;
let (na,sc,p) = uninterp_prim_token_cases_pattern pat in
+ match availability_of_entry_coercion custom InConstrEntrySomeLevel with
+ | None -> raise No_match
+ | Some coercion ->
match availability_of_prim_token p sc scopes with
| None -> raise No_match
| Some key ->
let loc = cases_pattern_loc pat in
- insert_pat_alias ?loc (insert_pat_delimiters ?loc (CAst.make ?loc @@ CPatPrim p) key) na
+ insert_pat_coercion ?loc coercion
+ (insert_pat_alias ?loc (insert_pat_delimiters ?loc (CAst.make ?loc @@ CPatPrim p) key) na)
with No_match ->
try
if !Flags.in_debugger || !Flags.raw_print || !print_no_symbol then raise No_match;
- extern_notation_pattern scopes vars pat
+ extern_notation_pattern allscopes vars pat
(uninterp_cases_pattern_notations pat)
with No_match ->
- lift (fun ?loc -> function
- | PatVar (Name id) -> CPatAtom (Some (make ?loc @@ Ident id))
- | PatVar (Anonymous) -> CPatAtom None
+ let loc = pat.CAst.loc in
+ match DAst.get pat with
+ | PatVar (Name id) when entry_has_ident custom -> CAst.make ?loc (CPatAtom (Some (qualid_of_ident ?loc id)))
+ | pat ->
+ match availability_of_entry_coercion custom InConstrEntrySomeLevel with
+ | None -> raise No_match
+ | Some coercion ->
+ let allscopes = (InConstrEntrySomeLevel,scopes) in
+ let pat = match pat with
+ | PatVar (Name id) -> CAst.make ?loc (CPatAtom (Some (qualid_of_ident ?loc id)))
+ | PatVar (Anonymous) -> CAst.make ?loc (CPatAtom None)
| PatCstr(cstrsp,args,na) ->
- let args = List.map (extern_cases_pattern_in_scope scopes vars) args in
+ let args = List.map (extern_cases_pattern_in_scope allscopes vars) args in
let p =
try
if !Flags.raw_print then raise Exit;
@@ -425,26 +441,32 @@ let rec extern_cases_pattern_in_scope (scopes:local_scopes) vars pat =
match drop_implicits_in_patt (ConstructRef cstrsp) 0 full_args with
| Some true_args -> CPatCstr (c, None, true_args)
| None -> CPatCstr (c, Some full_args, [])
- in (insert_pat_alias ?loc (CAst.make ?loc p) na).v
- ) pat
+ in
+ insert_pat_alias ?loc (CAst.make ?loc p) na
+ in
+ insert_pat_coercion coercion pat
+
and apply_notation_to_pattern ?loc gr ((subst,substlist),(nb_to_drop,more_args))
- (tmp_scope, scopes as allscopes) vars =
+ (custom, (tmp_scope, scopes) as allscopes) vars =
function
| NotationRule (sc,ntn) ->
begin
- match availability_of_notation (sc,ntn) allscopes with
+ match availability_of_entry_coercion custom (fst ntn) with
+ | None -> raise No_match
+ | Some coercion ->
+ match availability_of_notation (sc,ntn) (tmp_scope,scopes) with
(* Uninterpretation is not allowed in current context *)
| None -> raise No_match
(* Uninterpretation is allowed in current context *)
| Some (scopt,key) ->
let scopes' = Option.List.cons scopt scopes in
let l =
- List.map (fun (c,(scopt,scl)) ->
- extern_cases_pattern_in_scope (scopt,scl@scopes') vars c)
+ List.map (fun (c,(subentry,(scopt,scl))) ->
+ extern_cases_pattern_in_scope (subentry,(scopt,scl@scopes')) vars c)
subst in
let ll =
- List.map (fun (c,(scopt,scl)) ->
- let subscope = (scopt,scl@scopes') in
+ List.map (fun (c,(subentry,(scopt,scl))) ->
+ let subscope = (subentry,(scopt,scl@scopes')) in
List.map (extern_cases_pattern_in_scope subscope vars) c)
substlist in
let l2 = List.map (extern_cases_pattern_in_scope allscopes vars) more_args in
@@ -454,14 +476,18 @@ and apply_notation_to_pattern ?loc gr ((subst,substlist),(nb_to_drop,more_args))
|Some true_args -> true_args
|None -> raise No_match
in
- insert_pat_delimiters ?loc
- (make_pat_notation ?loc ntn (l,ll) l2') key
+ insert_pat_coercion coercion
+ (insert_pat_delimiters ?loc
+ (make_pat_notation ?loc ntn (l,ll) l2') key)
end
| SynDefRule kn ->
- let qid = make ?loc @@ Qualid (shortest_qualid_of_syndef vars kn) in
+ match availability_of_entry_coercion custom InConstrEntrySomeLevel with
+ | None -> raise No_match
+ | Some coercion ->
+ let qid = shortest_qualid_of_syndef ?loc vars kn in
let l1 =
- List.rev_map (fun (c,(scopt,scl)) ->
- extern_cases_pattern_in_scope (scopt,scl@scopes) vars c)
+ List.rev_map (fun (c,(subentry,(scopt,scl))) ->
+ extern_cases_pattern_in_scope (subentry,(scopt,scl@scopes)) vars c)
subst in
let l2 = List.map (extern_cases_pattern_in_scope allscopes vars) more_args in
let l2' = if !asymmetric_patterns then l2
@@ -471,8 +497,8 @@ and apply_notation_to_pattern ?loc gr ((subst,substlist),(nb_to_drop,more_args))
|None -> raise No_match
in
assert (List.is_empty substlist);
- mkPat ?loc qid (List.rev_append l1 l2')
-and extern_notation_pattern (tmp_scope,scopes as allscopes) vars t = function
+ insert_pat_coercion ?loc coercion (mkPat ?loc qid (List.rev_append l1 l2'))
+and extern_notation_pattern allscopes vars t = function
| [] -> raise No_match
| (keyrule,pat,n as _rule)::rules ->
try
@@ -485,7 +511,7 @@ and extern_notation_pattern (tmp_scope,scopes as allscopes) vars t = function
(match_notation_constr_cases_pattern t pat) allscopes vars keyrule in
insert_pat_alias ?loc p na
| PatVar Anonymous -> CAst.make ?loc @@ CPatAtom None
- | PatVar (Name id) -> CAst.make ?loc @@ CPatAtom (Some (make ?loc @@ Ident id))
+ | PatVar (Name id) -> CAst.make ?loc @@ CPatAtom (Some (qualid_of_ident ?loc id))
with
No_match -> extern_notation_pattern allscopes vars t rules
@@ -499,35 +525,27 @@ let rec extern_notation_ind_pattern allscopes vars ind args = function
with
No_match -> extern_notation_ind_pattern allscopes vars ind args rules
-let extern_ind_pattern_in_scope (scopes:local_scopes) vars ind args =
+let extern_ind_pattern_in_scope (custom,scopes as allscopes) vars ind args =
(* pboutill: There are letins in pat which is incompatible with notations and
not explicit application. *)
if !Flags.in_debugger||Inductiveops.inductive_has_local_defs ind then
let c = extern_reference vars (IndRef ind) in
- let args = List.map (extern_cases_pattern_in_scope scopes vars) args in
+ let args = List.map (extern_cases_pattern_in_scope allscopes vars) args in
CAst.make @@ CPatCstr (c, Some (add_patt_for_params ind args), [])
else
try
if !Flags.raw_print || !print_no_symbol then raise No_match;
- let (sc,p) = uninterp_prim_token_ind_pattern ind args in
- match availability_of_prim_token p sc scopes with
- | None -> raise No_match
- | Some key ->
- insert_pat_delimiters (CAst.make @@ CPatPrim p) key
- with No_match ->
- try
- if !Flags.raw_print || !print_no_symbol then raise No_match;
- extern_notation_ind_pattern scopes vars ind args
+ extern_notation_ind_pattern allscopes vars ind args
(uninterp_ind_pattern_notations ind)
with No_match ->
let c = extern_reference vars (IndRef ind) in
- let args = List.map (extern_cases_pattern_in_scope scopes vars) args in
+ let args = List.map (extern_cases_pattern_in_scope allscopes vars) args in
match drop_implicits_in_patt (IndRef ind) 0 args with
|Some true_args -> CAst.make @@ CPatCstr (c, None, true_args)
|None -> CAst.make @@ CPatCstr (c, Some args, [])
let extern_cases_pattern vars p =
- extern_cases_pattern_in_scope (None,[]) vars p
+ extern_cases_pattern_in_scope (InConstrEntrySomeLevel,(None,[])) vars p
(**********************************************************************)
(* Externalising applications *)
@@ -641,12 +659,12 @@ let extern_app inctx impl (cf,f) us args =
else
explicitize inctx impl (cf, CAst.make @@ CRef (f,us)) args
-let rec fill_arg_scopes args subscopes scopes = match args, subscopes with
+let rec fill_arg_scopes args subscopes (entry,(_,scopes) as all) = match args, subscopes with
| [], _ -> []
| a :: args, scopt :: subscopes ->
- (a, (scopt, scopes)) :: fill_arg_scopes args subscopes scopes
+ (a, (entry, (scopt, scopes))) :: fill_arg_scopes args subscopes all
| a :: args, [] ->
- (a, (None, scopes)) :: fill_arg_scopes args [] scopes
+ (a, (entry, (None, scopes))) :: fill_arg_scopes args [] all
let extern_args extern env args =
let map (arg, argscopes) = lazy (extern argscopes env arg) in
@@ -698,12 +716,15 @@ let rec flatten_application c = match DAst.get c with
(* mapping glob_constr to numerals (in presence of coercions, choose the *)
(* one with no delimiter if possible) *)
-let extern_possible_prim_token scopes r =
+let extern_possible_prim_token (custom,scopes) r =
try
let (sc,n) = uninterp_prim_token r in
+ match availability_of_entry_coercion custom InConstrEntrySomeLevel with
+ | None -> raise No_match
+ | Some coercion ->
match availability_of_prim_token n sc scopes with
| None -> None
- | Some key -> Some (insert_delimiters (CAst.make ?loc:(loc_of_glob_constr r) @@ CPrim n) key)
+ | Some key -> Some (insert_coercion coercion (insert_delimiters (CAst.make ?loc:(loc_of_glob_constr r) @@ CPrim n) key))
with No_match ->
None
@@ -721,7 +742,7 @@ let extended_glob_local_binder_of_decl loc = function
| (p,bk,None,t) -> GLocalAssum (p,bk,t)
| (p,bk,Some x, t) ->
match DAst.get t with
- | GHole (_, Misctypes.IntroAnonymous, None) -> GLocalDef (p,bk,x,None)
+ | GHole (_, IntroAnonymous, None) -> GLocalDef (p,bk,x,None)
| _ -> GLocalDef (p,bk,x,Some t)
let extended_glob_local_binder_of_decl ?loc u = DAst.make ?loc (extended_glob_local_binder_of_decl loc u)
@@ -738,7 +759,13 @@ let extern_glob_sort = function
let extern_universes = function
| Some _ as l when !print_universes -> l
| _ -> None
-
+
+let extern_ref vars ref us =
+ extern_global (select_stronger_impargs (implicits_of_global ref))
+ (extern_reference vars ref) (extern_universes us)
+
+let extern_var ?loc id = CRef (qualid_of_ident ?loc id,None)
+
let rec extern inctx scopes vars r =
let r' = remove_coercions inctx r in
try
@@ -749,20 +776,35 @@ let rec extern inctx scopes vars r =
let r'' = flatten_application r' in
if !Flags.raw_print || !print_no_symbol then raise No_match;
extern_notation scopes vars r'' (uninterp_notations r'')
- with No_match -> lift (fun ?loc -> function
- | GRef (ref,us) ->
- extern_global (select_stronger_impargs (implicits_of_global ref))
- (extern_reference vars ref) (extern_universes us)
+ with No_match ->
+ let loc = r'.CAst.loc in
+ match DAst.get r' with
+ | GRef (ref,us) when entry_has_global (fst scopes) -> CAst.make ?loc (extern_ref vars ref us)
+
+ | GVar id when entry_has_ident (fst scopes) -> CAst.make ?loc (extern_var ?loc id)
+
+ | c ->
- | GVar id -> CRef (make ?loc @@ Ident id,None)
+ match availability_of_entry_coercion (fst scopes) InConstrEntrySomeLevel with
+ | None -> raise No_match
+ | Some coercion ->
- | GEvar (n,[]) when !print_meta_as_hole -> CHole (None, Misctypes.IntroAnonymous, None)
+ let scopes = (InConstrEntrySomeLevel, snd scopes) in
+ let c = match c with
+
+ (* The remaining cases are only for the constr entry *)
+
+ | GRef (ref,us) -> extern_ref vars ref us
+
+ | GVar id -> extern_var ?loc id
+
+ | GEvar (n,[]) when !print_meta_as_hole -> CHole (None, IntroAnonymous, None)
| GEvar (n,l) ->
extern_evar n (List.map (on_snd (extern false scopes vars)) l)
| GPatVar kind ->
- if !print_meta_as_hole then CHole (None, Misctypes.IntroAnonymous, None) else
+ if !print_meta_as_hole then CHole (None, IntroAnonymous, None) else
(match kind with
| Evar_kinds.SecondOrderPatVar n -> CPatVar n
| Evar_kinds.FirstOrderPatVar n -> CEvar (n,[]))
@@ -771,7 +813,7 @@ let rec extern inctx scopes vars r =
(match DAst.get f with
| GRef (ref,us) ->
let subscopes = find_arguments_scope ref in
- let args = fill_arg_scopes args subscopes (snd scopes) in
+ let args = fill_arg_scopes args subscopes scopes in
begin
try
if !Flags.raw_print then raise Exit;
@@ -918,18 +960,19 @@ let rec extern inctx scopes vars r =
| GCast (c, c') ->
CCast (sub_extern true scopes vars c,
- Miscops.map_cast_type (extern_typ scopes vars) c')
- ) r'
+ map_cast_type (extern_typ scopes vars) c')
+
+ in insert_coercion coercion (CAst.make ?loc c)
-and extern_typ (_,scopes) =
- extern true (Notation.current_type_scope_name (),scopes)
+and extern_typ (subentry,(_,scopes)) =
+ extern true (subentry,(Notation.current_type_scope_name (),scopes))
-and sub_extern inctx (_,scopes) = extern inctx (None,scopes)
+and sub_extern inctx (subentry,(_,scopes)) = extern inctx (subentry,(None,scopes))
and factorize_prod scopes vars na bk aty c =
let store, get = set_temporary_memory () in
match na, DAst.get c with
- | Name id, GCases (LetPatternStyle, None, [(e,(Anonymous,None))],(_::_ as eqns))
+ | Name id, GCases (Constr.LetPatternStyle, None, [(e,(Anonymous,None))],(_::_ as eqns))
when is_gvar id e && List.length (store (factorize_eqns eqns)) = 1 ->
(match get () with
| [{CAst.v=(ids,disj_of_patl,b)}] ->
@@ -957,7 +1000,7 @@ and factorize_prod scopes vars na bk aty c =
and factorize_lambda inctx scopes vars na bk aty c =
let store, get = set_temporary_memory () in
match na, DAst.get c with
- | Name id, GCases (LetPatternStyle, None, [(e,(Anonymous,None))],(_::_ as eqns))
+ | Name id, GCases (Constr.LetPatternStyle, None, [(e,(Anonymous,None))],(_::_ as eqns))
when is_gvar id e && List.length (store (factorize_eqns eqns)) = 1 ->
(match get () with
| [{CAst.v=(ids,disj_of_patl,b)}] ->
@@ -1017,7 +1060,7 @@ and extern_eqn inctx scopes vars {CAst.loc;v=(ids,pll,c)} =
let pll = List.map (List.map (extern_cases_pattern_in_scope scopes vars)) pll in
make ?loc (pll,extern inctx scopes vars c)
-and extern_notation (tmp_scope,scopes as allscopes) vars t = function
+and extern_notation (custom,scopes as allscopes) vars t = function
| [] -> raise No_match
| (keyrule,pat,n as _rule)::rules ->
let loc = Glob_ops.loc_of_glob_constr t in
@@ -1064,40 +1107,46 @@ and extern_notation (tmp_scope,scopes as allscopes) vars t = function
let e =
match keyrule with
| NotationRule (sc,ntn) ->
- (match availability_of_notation (sc,ntn) allscopes with
+ (match availability_of_entry_coercion custom (fst ntn) with
+ | None -> raise No_match
+ | Some coercion ->
+ match availability_of_notation (sc,ntn) scopes with
(* Uninterpretation is not allowed in current context *)
| None -> raise No_match
(* Uninterpretation is allowed in current context *)
| Some (scopt,key) ->
- let scopes' = Option.List.cons scopt scopes in
+ let scopes' = Option.List.cons scopt (snd scopes) in
let l =
- List.map (fun (c,(scopt,scl)) ->
+ List.map (fun (c,(subentry,(scopt,scl))) ->
extern (* assuming no overloading: *) true
- (scopt,scl@scopes') vars c)
+ (subentry,(scopt,scl@scopes')) vars c)
terms in
let ll =
- List.map (fun (c,(scopt,scl)) ->
- List.map (extern true (scopt,scl@scopes') vars) c)
+ List.map (fun (c,(subentry,(scopt,scl))) ->
+ List.map (extern true (subentry,(scopt,scl@scopes')) vars) c)
termlists in
let bl =
- List.map (fun (bl,(scopt,scl)) ->
- mkCPatOr (List.map (extern_cases_pattern_in_scope (scopt,scl@scopes') vars) bl))
+ List.map (fun (bl,(subentry,(scopt,scl))) ->
+ mkCPatOr (List.map (extern_cases_pattern_in_scope (subentry,(scopt,scl@scopes')) vars) bl))
binders in
let bll =
- List.map (fun (bl,(scopt,scl)) ->
- pi3 (extern_local_binder (scopt,scl@scopes') vars bl))
+ List.map (fun (bl,(subentry,(scopt,scl))) ->
+ pi3 (extern_local_binder (subentry,(scopt,scl@scopes')) vars bl))
binderlists in
- insert_delimiters (make_notation loc ntn (l,ll,bl,bll)) key)
+ insert_coercion coercion (insert_delimiters (make_notation loc ntn (l,ll,bl,bll)) key))
| SynDefRule kn ->
+ match availability_of_entry_coercion custom InConstrEntrySomeLevel with
+ | None -> raise No_match
+ | Some coercion ->
let l =
- List.map (fun (c,(scopt,scl)) ->
- extern true (scopt,scl@scopes) vars c, None)
+ List.map (fun (c,(subentry,(scopt,scl))) ->
+ extern true (subentry,(scopt,scl@snd scopes)) vars c, None)
terms in
- let a = CRef (make ?loc @@ Qualid (shortest_qualid_of_syndef vars kn),None) in
- CAst.make ?loc @@ if List.is_empty l then a else CApp ((None, CAst.make a),l) in
+ let a = CRef (shortest_qualid_of_syndef ?loc vars kn,None) in
+ insert_coercion coercion (CAst.make ?loc @@ if List.is_empty l then a else CApp ((None, CAst.make a),l)) in
if List.is_empty args then e
else
- let args = fill_arg_scopes args argsscopes scopes in
+ let args = fill_arg_scopes args argsscopes allscopes in
let args = extern_args (extern true) vars args in
CAst.make ?loc @@ explicitize false argsimpls (None,e) args
with
@@ -1111,10 +1160,10 @@ and extern_recursion_order scopes vars = function
let extern_glob_constr vars c =
- extern false (None,[]) vars c
+ extern false (InConstrEntrySomeLevel,(None,[])) vars c
let extern_glob_type vars c =
- extern_typ (None,[]) vars c
+ extern_typ (InConstrEntrySomeLevel,(None,[])) vars c
(******************************************************************)
(* Main translation function from constr -> constr_expr *)
@@ -1130,7 +1179,7 @@ let extern_constr_gen lax goal_concl_style scopt env sigma t =
let avoid = if goal_concl_style then vars_of_env env else Id.Set.empty in
let r = Detyping.detype Detyping.Later ~lax:lax goal_concl_style avoid env sigma t in
let vars = vars_of_env env in
- extern false (scopt,[]) vars r
+ extern false (InConstrEntrySomeLevel,(scopt,[])) vars r
let extern_constr_in_scope goal_concl_style scope env sigma t =
extern_constr_gen false goal_concl_style (Some scope) env sigma t
@@ -1151,14 +1200,14 @@ let extern_closed_glob ?lax goal_concl_style env sigma t =
Detyping.detype_closed_glob ?lax goal_concl_style avoid env sigma t
in
let vars = vars_of_env env in
- extern false (None,[]) vars r
+ extern false (InConstrEntrySomeLevel,(None,[])) vars r
(******************************************************************)
(* Main translation function from pattern -> constr_expr *)
let any_any_branch =
(* | _ => _ *)
- CAst.make ([],[DAst.make @@ PatVar Anonymous], DAst.make @@ GHole (Evar_kinds.InternalHole,Misctypes.IntroAnonymous,None))
+ CAst.make ([],[DAst.make @@ PatVar Anonymous], DAst.make @@ GHole (Evar_kinds.InternalHole,IntroAnonymous,None))
let compute_displayed_name_in_pattern sigma avoid na c =
let open Namegen in
@@ -1182,7 +1231,7 @@ let rec glob_of_pat avoid env sigma pat = DAst.make @@ match pat with
anomaly ~label:"glob_constr_of_pattern" (Pp.str "index to an anonymous variable.")
with Not_found -> Id.of_string ("_UNBOUND_REL_"^(string_of_int n)) in
GVar id
- | PMeta None -> GHole (Evar_kinds.InternalHole, Misctypes.IntroAnonymous,None)
+ | PMeta None -> GHole (Evar_kinds.InternalHole, IntroAnonymous,None)
| PMeta (Some n) -> GPatVar (Evar_kinds.FirstOrderPatVar n)
| PProj (p,c) -> GApp (DAst.make @@ GRef (ConstRef (Projection.constant p),None),
[glob_of_pat avoid env sigma c])
@@ -1207,7 +1256,7 @@ let rec glob_of_pat avoid env sigma pat = DAst.make @@ match pat with
| PIf (c,b1,b2) ->
GIf (glob_of_pat avoid env sigma c, (Anonymous,None),
glob_of_pat avoid env sigma b1, glob_of_pat avoid env sigma b2)
- | PCase ({cip_style=LetStyle; cip_ind_tags=None},PMeta None,tm,[(0,n,b)]) ->
+ | PCase ({cip_style=Constr.LetStyle; cip_ind_tags=None},PMeta None,tm,[(0,n,b)]) ->
let nal,b = it_destRLambda_or_LetIn_names n (glob_of_pat avoid env sigma b) in
GLetTuple (nal,(Anonymous,None),glob_of_pat avoid env sigma tm,b)
| PCase (info,p,tm,bl) ->
@@ -1226,16 +1275,44 @@ let rec glob_of_pat avoid env sigma pat = DAst.make @@ match pat with
return_type_of_predicate ind nargs (glob_of_pat avoid env sigma p)
| _ -> anomaly (Pp.str "PCase with non-trivial predicate but unknown inductive.")
in
- GCases (RegularStyle,rtn,[glob_of_pat avoid env sigma tm,indnames],mat)
- | PFix f -> DAst.get (Detyping.detype_names false avoid env (Global.env()) sigma (EConstr.of_constr (mkFix f))) (** FIXME bad env *)
- | PCoFix c -> DAst.get (Detyping.detype_names false avoid env (Global.env()) sigma (EConstr.of_constr (mkCoFix c)))
+ GCases (Constr.RegularStyle,rtn,[glob_of_pat avoid env sigma tm,indnames],mat)
+ | PFix ((ln,i),(lna,tl,bl)) ->
+ let def_avoid, def_env, lfi =
+ Array.fold_left
+ (fun (avoid, env, l) na ->
+ let id = Namegen.next_name_away na avoid in
+ (Id.Set.add id avoid, Name id :: env, id::l))
+ (avoid, env, []) lna in
+ let n = Array.length tl in
+ let v = Array.map3
+ (fun c t i -> Detyping.share_pattern_names glob_of_pat (i+1) [] def_avoid def_env sigma c (Patternops.lift_pattern n t))
+ bl tl ln in
+ GRec(GFix (Array.map (fun i -> Some i, GStructRec) ln,i),Array.of_list (List.rev lfi),
+ Array.map (fun (bl,_,_) -> bl) v,
+ Array.map (fun (_,_,ty) -> ty) v,
+ Array.map (fun (_,bd,_) -> bd) v)
+ | PCoFix (ln,(lna,tl,bl)) ->
+ let def_avoid, def_env, lfi =
+ Array.fold_left
+ (fun (avoid, env, l) na ->
+ let id = Namegen.next_name_away na avoid in
+ (Id.Set.add id avoid, Name id :: env, id::l))
+ (avoid, env, []) lna in
+ let ntys = Array.length tl in
+ let v = Array.map2
+ (fun c t -> share_pattern_names glob_of_pat 0 [] def_avoid def_env sigma c (Patternops.lift_pattern ntys t))
+ bl tl in
+ GRec(GCoFix ln,Array.of_list (List.rev lfi),
+ Array.map (fun (bl,_,_) -> bl) v,
+ Array.map (fun (_,_,ty) -> ty) v,
+ Array.map (fun (_,bd,_) -> bd) v)
| PSort s -> GSort s
let extern_constr_pattern env sigma pat =
- extern true (None,[]) Id.Set.empty (glob_of_pat Id.Set.empty env sigma pat)
+ extern true (InConstrEntrySomeLevel,(None,[])) Id.Set.empty (glob_of_pat Id.Set.empty env sigma pat)
let extern_rel_context where env sigma sign =
let a = detype_rel_context Detyping.Later where Id.Set.empty (names_of_rel_context env,env) sigma sign in
let vars = vars_of_env env in
let a = List.map (extended_glob_local_binder_of_decl) a in
- pi3 (extern_local_binder (None,[]) vars a)
+ pi3 (extern_local_binder (InConstrEntrySomeLevel,(None,[])) vars a)
diff --git a/interp/constrextern.mli b/interp/constrextern.mli
index 8ab70283..f09b316c 100644
--- a/interp/constrextern.mli
+++ b/interp/constrextern.mli
@@ -13,13 +13,11 @@ open Termops
open EConstr
open Environ
open Libnames
-open Globnames
open Glob_term
open Pattern
open Constrexpr
open Notation_term
open Notation
-open Misctypes
open Ltac_pretype
(** Translation of pattern, cases pattern, glob_constr and term into syntax
@@ -40,7 +38,7 @@ val extern_closed_glob : ?lax:bool -> bool -> env -> Evd.evar_map -> closed_glob
val extern_constr : ?lax:bool -> bool -> env -> Evd.evar_map -> constr -> constr_expr
val extern_constr_in_scope : bool -> scope_name -> env -> Evd.evar_map -> constr -> constr_expr
-val extern_reference : ?loc:Loc.t -> Id.Set.t -> global_reference -> reference
+val extern_reference : ?loc:Loc.t -> Id.Set.t -> GlobRef.t -> qualid
val extern_type : bool -> env -> Evd.evar_map -> types -> constr_expr
val extern_sort : Evd.evar_map -> Sorts.t -> glob_sort
val extern_rel_context : constr option -> env -> Evd.evar_map ->
@@ -58,9 +56,9 @@ val print_projections : bool ref
(** Customization of the global_reference printer *)
val set_extern_reference :
- (?loc:Loc.t -> Id.Set.t -> global_reference -> reference) -> unit
+ (?loc:Loc.t -> Id.Set.t -> GlobRef.t -> qualid) -> unit
val get_extern_reference :
- unit -> (?loc:Loc.t -> Id.Set.t -> global_reference -> reference)
+ unit -> (?loc:Loc.t -> Id.Set.t -> GlobRef.t -> qualid)
(** WARNING: The following functions are evil due to
side-effects. Think of the following case as used in the printer:
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 83ace93c..d02f5941 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -15,6 +15,7 @@ open CAst
open Names
open Nameops
open Namegen
+open Constr
open Libnames
open Globnames
open Impargs
@@ -95,8 +96,8 @@ let is_global id =
with Not_found ->
false
-let global_reference_of_reference ref =
- locate_reference (qualid_of_reference ref).CAst.v
+let global_reference_of_reference qid =
+ locate_reference qid
let global_reference id =
locate_reference (qualid_of_ident id)
@@ -116,7 +117,7 @@ let global_reference_in_absolute_module dir id =
type internalization_error =
| VariableCapture of Id.t * Id.t
| IllegalMetavariable
- | NotAConstructor of reference
+ | NotAConstructor of qualid
| UnboundFixName of bool * Id.t
| NonLinearPattern of Id.t
| BadPatternsNumber of int * int
@@ -130,8 +131,8 @@ let explain_variable_capture id id' =
let explain_illegal_metavariable =
str "Metavariables allowed only in patterns"
-let explain_not_a_constructor ref =
- str "Unknown constructor: " ++ pr_reference ref
+let explain_not_a_constructor qid =
+ str "Unknown constructor: " ++ pr_qualid qid
let explain_unbound_fix_name is_cofix id =
str "The name" ++ spc () ++ Id.print id ++
@@ -217,30 +218,36 @@ let expand_notation_string ntn n =
(* This contracts the special case of "{ _ }" for sumbool, sumor notations *)
(* Remark: expansion of squash at definition is done in metasyntax.ml *)
let contract_curly_brackets ntn (l,ll,bl,bll) =
+ match ntn with
+ | InCustomEntryLevel _,_ -> ntn,(l,ll,bl,bll)
+ | InConstrEntrySomeLevel, ntn ->
let ntn' = ref ntn in
let rec contract_squash n = function
| [] -> []
- | { CAst.v = CNotation ("{ _ }",([a],[],[],[])) } :: l ->
+ | { CAst.v = CNotation ((InConstrEntrySomeLevel,"{ _ }"),([a],[],[],[])) } :: l ->
ntn' := expand_notation_string !ntn' n;
contract_squash n (a::l)
| a :: l ->
a::contract_squash (n+1) l in
let l = contract_squash 0 l in
(* side effect; don't inline *)
- !ntn',(l,ll,bl,bll)
+ (InConstrEntrySomeLevel,!ntn'),(l,ll,bl,bll)
let contract_curly_brackets_pat ntn (l,ll) =
+ match ntn with
+ | InCustomEntryLevel _,_ -> ntn,(l,ll)
+ | InConstrEntrySomeLevel, ntn ->
let ntn' = ref ntn in
let rec contract_squash n = function
| [] -> []
- | { CAst.v = CPatNotation ("{ _ }",([a],[]),[]) } :: l ->
+ | { CAst.v = CPatNotation ((InConstrEntrySomeLevel,"{ _ }"),([a],[]),[]) } :: l ->
ntn' := expand_notation_string !ntn' n;
contract_squash n (a::l)
| a :: l ->
a::contract_squash (n+1) l in
let l = contract_squash 0 l in
(* side effect; don't inline *)
- !ntn',(l,ll)
+ (InConstrEntrySomeLevel,!ntn'),(l,ll)
type intern_env = {
ids: Names.Id.Set.t;
@@ -393,7 +400,7 @@ let intern_generalized_binder ?(global_level=false) intern_type ntnvars
env fvs in
let bl = List.map
CAst.(map (fun id ->
- (Name id, b, DAst.make ?loc @@ GHole (Evar_kinds.BinderType (Name id), Misctypes.IntroAnonymous, None))))
+ (Name id, b, DAst.make ?loc @@ GHole (Evar_kinds.BinderType (Name id), IntroAnonymous, None))))
fvs
in
let na = match na with
@@ -403,7 +410,8 @@ let intern_generalized_binder ?(global_level=false) intern_type ntnvars
let name =
let id =
match ty with
- | { v = CApp ((_, { v = CRef ({v=Ident id},_) } ), _) } -> id
+ | { v = CApp ((_, { v = CRef (qid,_) } ), _) } when qualid_is_ident qid ->
+ qualid_basename qid
| _ -> default_non_dependent_ident
in Implicit_quantifiers.make_fresh ids' (Global.env ()) id
in Name name
@@ -430,7 +438,7 @@ let glob_local_binder_of_extended = DAst.with_loc_val (fun ?loc -> function
| GLocalAssum (na,bk,t) -> (na,bk,None,t)
| GLocalDef (na,bk,c,Some t) -> (na,bk,Some c,t)
| GLocalDef (na,bk,c,None) ->
- let t = DAst.make ?loc @@ GHole(Evar_kinds.BinderType na,Misctypes.IntroAnonymous,None) in
+ let t = DAst.make ?loc @@ GHole(Evar_kinds.BinderType na,IntroAnonymous,None) in
(na,bk,Some c,t)
| GLocalPattern (_,_,_,_) ->
Loc.raise ?loc (Stream.Error "pattern with quote not allowed here")
@@ -471,7 +479,7 @@ let intern_local_binder_aux ?(global_level=false) intern ntnvars (env,bl) = func
let tyc =
match ty with
| Some ty -> ty
- | None -> CAst.make ?loc @@ CHole(None,Misctypes.IntroAnonymous,None)
+ | None -> CAst.make ?loc @@ CHole(None,IntroAnonymous,None)
in
let env, ((disjpat,il),id),na = intern_cases_pattern_as_binder ?loc ntnvars env p in
let bk = Default Explicit in
@@ -501,11 +509,11 @@ let intern_generalization intern env ntnvars loc bk ak c =
if pi then
(fun {loc=loc';v=id} acc ->
DAst.make ?loc:(Loc.merge_opt loc' loc) @@
- GProd (Name id, bk, DAst.make ?loc:loc' @@ GHole (Evar_kinds.BinderType (Name id), Misctypes.IntroAnonymous, None), acc))
+ GProd (Name id, bk, DAst.make ?loc:loc' @@ GHole (Evar_kinds.BinderType (Name id), IntroAnonymous, None), acc))
else
(fun {loc=loc';v=id} acc ->
DAst.make ?loc:(Loc.merge_opt loc' loc) @@
- GLambda (Name id, bk, DAst.make ?loc:loc' @@ GHole (Evar_kinds.BinderType (Name id), Misctypes.IntroAnonymous, None), acc))
+ GLambda (Name id, bk, DAst.make ?loc:loc' @@ GHole (Evar_kinds.BinderType (Name id), IntroAnonymous, None), acc))
in
List.fold_right (fun ({loc;v=id} as lid) (env, acc) ->
let env' = push_name_env ntnvars (Variable,[],[],[]) env CAst.(make @@ Name id) in
@@ -525,7 +533,7 @@ let rec expand_binders ?loc mk bl c =
let tm = DAst.make ?loc (GVar id) in
(* Distribute the disjunctive patterns over the shared right-hand side *)
let eqnl = List.map (fun pat -> CAst.make ?loc (ids,[pat],c)) disjpat in
- let c = DAst.make ?loc @@ GCases (Misctypes.LetPatternStyle, None, [tm,(Anonymous,None)], eqnl) in
+ let c = DAst.make ?loc @@ GCases (LetPatternStyle, None, [tm,(Anonymous,None)], eqnl) in
expand_binders ?loc mk bl (mk ?loc (Name id,Explicit,ty) c)
(**********************************************************************)
@@ -550,12 +558,13 @@ let find_fresh_name renaming (terms,termlists,binders,binderlists) avoid id =
let is_var store pat =
match DAst.get pat with
- | PatVar na -> store na; true
+ | PatVar na -> ignore(store na); true
| _ -> false
let out_var pat =
match pat.v with
- | CPatAtom (Some ({v=Ident id})) -> Name id
+ | CPatAtom (Some qid) when qualid_is_ident qid ->
+ Name (qualid_basename qid)
| CPatAtom None -> Anonymous
| _ -> assert false
@@ -563,7 +572,7 @@ let term_of_name = function
| Name id -> DAst.make (GVar id)
| Anonymous ->
let st = Evar_kinds.Define (not (Program.get_proofs_transparency ())) in
- DAst.make (GHole (Evar_kinds.QuestionMark (st,Anonymous), Misctypes.IntroAnonymous, None))
+ DAst.make (GHole (Evar_kinds.QuestionMark { Evar_kinds.default_question_mark with Evar_kinds.qm_obligation=st }, IntroAnonymous, None))
let traverse_binder intern_pat ntnvars (terms,_,binders,_ as subst) avoid (renaming,env) = function
| Anonymous -> (renaming,env), None, Anonymous
@@ -605,7 +614,7 @@ let traverse_binder intern_pat ntnvars (terms,_,binders,_ as subst) avoid (renam
(renaming',env), None, Name id'
type binder_action =
-| AddLetIn of Misctypes.lname * constr_expr * constr_expr option
+| AddLetIn of lname * constr_expr * constr_expr option
| AddTermIter of (constr_expr * subscopes) Names.Id.Map.t
| AddPreBinderIter of Id.t * local_binder_expr (* A binder to be internalized *)
| AddBinderIter of Id.t * extended_glob_local_binder (* A binder already internalized - used for generalized binders *)
@@ -621,18 +630,18 @@ let error_cannot_coerce_disjunctive_pattern_term ?loc () =
let terms_of_binders bl =
let rec term_of_pat pt = dmap_with_loc (fun ?loc -> function
- | PatVar (Name id) -> CRef (make @@ Ident id, None)
+ | PatVar (Name id) -> CRef (qualid_of_ident id, None)
| PatVar (Anonymous) -> error_cannot_coerce_wildcard_term ?loc ()
| PatCstr (c,l,_) ->
- let r = make ?loc @@ Qualid (qualid_of_path (path_of_global (ConstructRef c))) in
- let hole = CAst.make ?loc @@ CHole (None,Misctypes.IntroAnonymous,None) in
+ let qid = qualid_of_path ?loc (path_of_global (ConstructRef c)) in
+ let hole = CAst.make ?loc @@ CHole (None,IntroAnonymous,None) in
let params = List.make (Inductiveops.inductive_nparams (fst c)) hole in
- CAppExpl ((None,r,None),params @ List.map term_of_pat l)) pt in
+ CAppExpl ((None,qid,None),params @ List.map term_of_pat l)) pt in
let rec extract_variables l = match l with
| bnd :: l ->
let loc = bnd.loc in
begin match DAst.get bnd with
- | GLocalAssum (Name id,_,_) -> (CAst.make ?loc @@ CRef (make ?loc @@ Ident id, None)) :: extract_variables l
+ | GLocalAssum (Name id,_,_) -> (CAst.make ?loc @@ CRef (qualid_of_ident ?loc id, None)) :: extract_variables l
| GLocalDef (Name id,_,_,_) -> extract_variables l
| GLocalDef (Anonymous,_,_,_)
| GLocalAssum (Anonymous,_,_) -> user_err Pp.(str "Cannot turn \"_\" into a term.")
@@ -707,10 +716,12 @@ let instantiate_notation_constr loc intern intern_pat ntnvars subst infos c =
let arg = match arg with
| None -> None
| Some arg ->
- let mk_env (c, (tmp_scope, subscopes)) =
+ let mk_env id (c, (tmp_scope, subscopes)) map =
let nenv = {env with tmp_scope; scopes = subscopes @ env.scopes} in
- let gc = intern nenv c in
- (gc, Some c)
+ try
+ let gc = intern nenv c in
+ Id.Map.add id (gc, Some c) map
+ with GlobalizationError _ -> map
in
let mk_env' (c, (onlyident,(tmp_scope,subscopes))) =
let nenv = {env with tmp_scope; scopes = subscopes @ env.scopes} in
@@ -722,7 +733,7 @@ let instantiate_notation_constr loc intern intern_pat ntnvars subst infos c =
| [pat] -> (glob_constr_of_cases_pattern pat, None)
| _ -> error_cannot_coerce_disjunctive_pattern_term ?loc:c.loc ()
in
- let terms = Id.Map.map mk_env terms in
+ let terms = Id.Map.fold mk_env terms Id.Map.empty in
let binders = Id.Map.map mk_env' binders in
let bindings = Id.Map.fold Id.Map.add terms binders in
Some (Genintern.generic_substitute_notation bindings arg)
@@ -805,7 +816,7 @@ let instantiate_notation_constr loc intern intern_pat ntnvars subst infos c =
distinction *)
let cases_pattern_of_name {loc;v=na} =
- let atom = match na with Name id -> Some (make ?loc @@ Ident id) | Anonymous -> None in
+ let atom = match na with Name id -> Some (qualid_of_ident ?loc id) | Anonymous -> None in
CAst.make ?loc (CPatAtom atom)
let split_by_type ids subst =
@@ -814,16 +825,16 @@ let split_by_type ids subst =
| [] -> assert false
| a::l -> l, Id.Map.add id (a,scl) s in
let (terms,termlists,binders,binderlists),subst =
- List.fold_left (fun ((terms,termlists,binders,binderlists),(terms',termlists',binders',binderlists')) (id,(scl,typ)) ->
+ List.fold_left (fun ((terms,termlists,binders,binderlists),(terms',termlists',binders',binderlists')) (id,((_,scl),typ)) ->
match typ with
| NtnTypeConstr ->
let terms,terms' = bind id scl terms terms' in
(terms,termlists,binders,binderlists),(terms',termlists',binders',binderlists')
- | NtnTypeBinder NtnBinderParsedAsConstr (Extend.AsIdentOrPattern | Extend.AsStrictPattern) ->
+ | NtnTypeBinder NtnBinderParsedAsConstr (AsIdentOrPattern | AsStrictPattern) ->
let a,terms = match terms with a::terms -> a,terms | _ -> assert false in
let binders' = Id.Map.add id (coerce_to_cases_pattern_expr a,(false,scl)) binders' in
(terms,termlists,binders,binderlists),(terms',termlists',binders',binderlists')
- | NtnTypeBinder NtnBinderParsedAsConstr Extend.AsIdent ->
+ | NtnTypeBinder NtnBinderParsedAsConstr AsIdent ->
let a,terms = match terms with a::terms -> a,terms | _ -> assert false in
let binders' = Id.Map.add id (cases_pattern_of_name (coerce_to_name a),(true,scl)) binders' in
(terms,termlists,binders,binderlists),(terms',termlists',binders',binderlists')
@@ -842,10 +853,10 @@ let split_by_type ids subst =
subst
let split_by_type_pat ?loc ids subst =
- let bind id scl l s =
+ let bind id (_,scopes) l s =
match l with
| [] -> assert false
- | a::l -> l, Id.Map.add id (a,scl) s in
+ | a::l -> l, Id.Map.add id (a,scopes) s in
let (terms,termlists),subst =
List.fold_left (fun ((terms,termlists),(terms',termlists')) (id,(scl,typ)) ->
match typ with
@@ -861,7 +872,7 @@ let split_by_type_pat ?loc ids subst =
subst
let make_subst ids l =
- let fold accu (id, scl) a = Id.Map.add id (a, scl) accu in
+ let fold accu (id, scopes) a = Id.Map.add id (a, scopes) accu in
List.fold_left2 fold Id.Map.empty ids l
let intern_notation intern env ntnvars loc ntn fullargs =
@@ -902,7 +913,7 @@ let intern_var env (ltacvars,ntnvars) namedctx loc id us =
try
let ty,expl_impls,impls,argsc = Id.Map.find id env.impls in
let expl_impls = List.map
- (fun id -> CAst.make ?loc @@ CRef (make ?loc @@ Ident id,None), Some (make ?loc @@ ExplByName id)) expl_impls in
+ (fun id -> CAst.make ?loc @@ CRef (qualid_of_ident ?loc id,None), Some (make ?loc @@ ExplByName id)) expl_impls in
let tys = string_of_ty ty in
Dumpglob.dump_reference ?loc "<>" (Id.to_string id) tys;
gvar (loc,id) us, make_implicits_list impls, argsc, expl_impls
@@ -969,28 +980,27 @@ let dump_extended_global loc = function
| TrueGlobal ref -> (*feedback_global loc ref;*) Dumpglob.add_glob ?loc ref
| SynDef sp -> Dumpglob.add_glob_kn ?loc sp
-let intern_extended_global_of_qualid {loc;v=qid} =
- let r = Nametab.locate_extended qid in dump_extended_global loc r; r
+let intern_extended_global_of_qualid qid =
+ let r = Nametab.locate_extended qid in dump_extended_global qid.CAst.loc r; r
-let intern_reference ref =
- let qid = qualid_of_reference ref in
+let intern_reference qid =
let r =
try intern_extended_global_of_qualid qid
with Not_found -> error_global_not_found qid
in
Smartlocate.global_of_extended_global r
-let sort_info_of_level_info (info: Misctypes.level_info) : (Libnames.reference * int) option =
+let sort_info_of_level_info (info: level_info) : (Libnames.qualid * int) option =
match info with
- | Misctypes.UAnonymous -> None
- | Misctypes.UUnknown -> None
- | Misctypes.UNamed id -> Some (id, 0)
+ | UAnonymous -> None
+ | UUnknown -> None
+ | UNamed id -> Some (id, 0)
-let glob_sort_of_level (level: Misctypes.glob_level) : Misctypes.glob_sort =
+let glob_sort_of_level (level: glob_level) : glob_sort =
match level with
- | Misctypes.GProp -> Misctypes.GProp
- | Misctypes.GSet -> Misctypes.GSet
- | Misctypes.GType info -> Misctypes.GType [sort_info_of_level_info info]
+ | GProp -> GProp
+ | GSet -> GSet
+ | GType info -> GType [sort_info_of_level_info info]
(* Is it a global reference or a syntactic definition? *)
let intern_qualid ?(no_secvar=false) qid intern env ntnvars us args =
@@ -1013,7 +1023,7 @@ let intern_qualid ?(no_secvar=false) qid intern env ntnvars us args =
let c = instantiate_notation_constr loc intern intern_cases_pattern_as_binder ntnvars subst infos c in
let loc = c.loc in
let err () =
- user_err ?loc (str "Notation " ++ pr_qualid qid.v
+ user_err ?loc (str "Notation " ++ pr_qualid qid
++ str " cannot have a universe instance,"
++ str " its expanded head does not start with a reference")
in
@@ -1027,37 +1037,35 @@ let intern_qualid ?(no_secvar=false) qid intern env ntnvars us args =
DAst.make ?loc @@ GApp (DAst.make ?loc:loc' @@ GRef (ref, us), arg)
| _ -> err ()
end
- | Some [s], GSort (Misctypes.GType []) -> DAst.make ?loc @@ GSort (glob_sort_of_level s)
+ | Some [s], GSort (GType []) -> DAst.make ?loc @@ GSort (glob_sort_of_level s)
| Some [_old_level], GSort _new_sort ->
(* TODO: add old_level and new_sort to the error message *)
- user_err ?loc (str "Cannot change universe level of notation " ++ pr_qualid qid.v)
+ user_err ?loc (str "Cannot change universe level of notation " ++ pr_qualid qid)
| Some _, _ -> err ()
in
c, projapp, args2
-let intern_applied_reference intern env namedctx (_, ntnvars as lvar) us args =
-function
- | {loc; v=Qualid qid} ->
- let qid = make ?loc qid in
- let r,projapp,args2 =
- try intern_qualid qid intern env ntnvars us args
- with Not_found -> error_global_not_found qid
- in
- let x, imp, scopes, l = find_appl_head_data r in
- (x,imp,scopes,l), args2
- | {loc; v=Ident id} ->
- try intern_var env lvar namedctx loc id us, args
+let intern_applied_reference intern env namedctx (_, ntnvars as lvar) us args qid =
+ let loc = qid.CAst.loc in
+ if qualid_is_ident qid then
+ try intern_var env lvar namedctx loc (qualid_basename qid) us, args
with Not_found ->
- let qid = make ?loc @@ qualid_of_ident id in
try
let r, projapp, args2 = intern_qualid ~no_secvar:true qid intern env ntnvars us args in
let x, imp, scopes, l = find_appl_head_data r in
(x,imp,scopes,l), args2
with Not_found ->
- (* Extra allowance for non globalizing functions *)
- if !interning_grammar || env.unb then
- (gvar (loc,id) us, [], [], []), args
+ (* Extra allowance for non globalizing functions *)
+ if !interning_grammar || env.unb then
+ (gvar (loc,qualid_basename qid) us, [], [], []), args
else error_global_not_found qid
+ else
+ let r,projapp,args2 =
+ try intern_qualid qid intern env ntnvars us args
+ with Not_found -> error_global_not_found qid
+ in
+ let x, imp, scopes, l = find_appl_head_data r in
+ (x,imp,scopes,l), args2
let interp_reference vars r =
let (r,_,_,_),_ =
@@ -1072,11 +1080,11 @@ let interp_reference vars r =
(** Private internalization patterns *)
type 'a raw_cases_pattern_expr_r =
- | RCPatAlias of 'a raw_cases_pattern_expr * Misctypes.lname
- | RCPatCstr of Globnames.global_reference
+ | RCPatAlias of 'a raw_cases_pattern_expr * lname
+ | RCPatCstr of GlobRef.t
* 'a raw_cases_pattern_expr list * 'a raw_cases_pattern_expr list
(** [RCPatCstr (loc, c, l1, l2)] represents [((@ c l1) l2)] *)
- | RCPatAtom of (Misctypes.lident * (Notation_term.tmp_scope_name option * Notation_term.scope_name list)) option
+ | RCPatAtom of (lident * (Notation_term.tmp_scope_name option * Notation_term.scope_name list)) option
| RCPatOr of 'a raw_cases_pattern_expr list
and 'a raw_cases_pattern_expr = ('a raw_cases_pattern_expr_r, 'a) DAst.t
@@ -1261,18 +1269,18 @@ let find_constructor loc add_params ref =
List.make nb ([], [(Id.Map.empty, DAst.make @@ PatVar Anonymous)])
| None -> []
-let find_pattern_variable = function
- | {v=Ident id} -> id
- | {loc;v=Qualid _} as x -> raise (InternalizationError(loc,NotAConstructor x))
+let find_pattern_variable qid =
+ if qualid_is_ident qid then qualid_basename qid
+ else raise (InternalizationError(qid.CAst.loc,NotAConstructor qid))
let check_duplicate loc fields =
- let eq (ref1, _) (ref2, _) = eq_reference ref1 ref2 in
+ let eq (ref1, _) (ref2, _) = qualid_eq ref1 ref2 in
let dups = List.duplicates eq fields in
match dups with
| [] -> ()
| (r, _) :: _ ->
user_err ?loc (str "This record defines several times the field " ++
- pr_reference r ++ str ".")
+ pr_qualid r ++ str ".")
(** [sort_fields ~complete loc fields completer] expects a list
[fields] of field assignments [f = e1; g = e2; ...], where [f, g]
@@ -1297,14 +1305,14 @@ let sort_fields ~complete loc fields completer =
(gr, Recordops.find_projection gr)
with Not_found ->
user_err ?loc ~hdr:"intern"
- (pr_reference first_field_ref ++ str": Not a projection")
+ (pr_qualid first_field_ref ++ str": Not a projection")
in
(* the number of parameters *)
let nparams = record.Recordops.s_EXPECTEDPARAM in
(* the reference constructor of the record *)
let base_constructor =
let global_record_id = ConstructRef record.Recordops.s_CONST in
- try make ?loc @@ Qualid (shortest_qualid_of_global Id.Set.empty global_record_id)
+ try shortest_qualid_of_global ?loc Id.Set.empty global_record_id
with Not_found ->
anomaly (str "Environment corruption for records.") in
let () = check_duplicate loc fields in
@@ -1312,14 +1320,14 @@ let sort_fields ~complete loc fields completer =
first_field_index, (* index of the first field of the record *)
proj_list) (* list of projections *)
=
- (* elimitate the first field from the projections,
+ (* eliminate the first field from the projections,
but keep its index *)
let rec build_proj_list projs proj_kinds idx ~acc_first_idx acc =
match projs with
| [] -> (idx, acc_first_idx, acc)
| (Some field_glob_id) :: projs ->
let field_glob_ref = ConstRef field_glob_id in
- let first_field = eq_gr field_glob_ref first_field_glob_ref in
+ let first_field = GlobRef.equal field_glob_ref first_field_glob_ref in
begin match proj_kinds with
| [] -> anomaly (Pp.str "Number of projections mismatch.")
| (_, regular) :: proj_kinds ->
@@ -1355,9 +1363,9 @@ let sort_fields ~complete loc fields completer =
let field_glob_ref = try global_reference_of_reference field_ref
with Not_found ->
user_err ?loc ~hdr:"intern"
- (str "The field \"" ++ pr_reference field_ref ++ str "\" does not exist.") in
+ (str "The field \"" ++ pr_qualid field_ref ++ str "\" does not exist.") in
let remaining_projs, (field_index, _) =
- let the_proj (idx, glob_id) = eq_gr field_glob_ref (ConstRef glob_id) in
+ let the_proj (idx, glob_id) = GlobRef.equal field_glob_ref (ConstRef glob_id) in
try CList.extract_first the_proj remaining_projs
with Not_found ->
user_err ?loc
@@ -1368,7 +1376,8 @@ let sort_fields ~complete loc fields completer =
(* the order does not matter as we sort them next,
List.rev_* is just for efficiency *)
let remaining_fields =
- let complete_field (idx, _field_ref) = (idx, completer idx) in
+ let complete_field (idx, field_ref) = (idx,
+ completer idx field_ref record.Recordops.s_CONST) in
List.rev_map complete_field remaining_projs in
List.rev_append remaining_fields acc
in
@@ -1384,7 +1393,7 @@ let sort_fields ~complete loc fields completer =
(** {6 Manage multiple aliases} *)
type alias = {
- alias_ids : Misctypes.lident list;
+ alias_ids : lident list;
alias_map : Id.t Id.Map.t;
}
@@ -1482,10 +1491,9 @@ let drop_notations_pattern looked_for genv =
end
| _ -> CErrors.anomaly Pp.(str "Invalid return pattern from Notation.interp_prim_token_cases_pattern_expr."))) x
in
- let rec drop_syndef top scopes re pats =
- let qid = qualid_of_reference re in
+ let rec drop_syndef top scopes qid pats =
try
- match locate_extended qid.v with
+ match locate_extended qid with
| SynDef sp ->
let (vars,a) = Syntax_def.search_syntactic_definition sp in
(match a with
@@ -1523,7 +1531,7 @@ let drop_notations_pattern looked_for genv =
| CPatAlias (p, id) -> DAst.make ?loc @@ RCPatAlias (in_pat top scopes p, id)
| CPatRecord l ->
let sorted_fields =
- sort_fields ~complete:false loc l (fun _idx -> CAst.make ?loc @@ CPatAtom None) in
+ sort_fields ~complete:false loc l (fun _idx fieldname constructor -> CAst.make ?loc @@ CPatAtom None) in
begin match sorted_fields with
| None -> DAst.make ?loc @@ RCPatAtom None
| Some (n, head, pl) ->
@@ -1541,10 +1549,10 @@ let drop_notations_pattern looked_for genv =
| Some (a,b,c) -> DAst.make ?loc @@ RCPatCstr(a, b, c)
| None -> raise (InternalizationError (loc,NotAConstructor head))
end
- | CPatCstr (r, Some expl_pl, pl) ->
- let g = try locate (qualid_of_reference r).v
+ | CPatCstr (qid, Some expl_pl, pl) ->
+ let g = try locate qid
with Not_found ->
- raise (InternalizationError (loc,NotAConstructor r)) in
+ raise (InternalizationError (loc,NotAConstructor qid)) in
if expl_pl == [] then
(* Convention: (@r) deactivates all further implicit arguments and scopes *)
DAst.make ?loc @@ RCPatCstr (g, List.map (in_pat false scopes) pl, [])
@@ -1553,11 +1561,11 @@ let drop_notations_pattern looked_for genv =
(* but not scopes in expl_pl *)
let (argscs1,_) = find_remaining_scopes expl_pl pl g in
DAst.make ?loc @@ RCPatCstr (g, List.map2 (in_pat_sc scopes) argscs1 expl_pl @ List.map (in_pat false scopes) pl, [])
- | CPatNotation ("- _",([a],[]),[]) when is_non_zero_pat a ->
+ | CPatNotation ((InConstrEntrySomeLevel,"- _"),([a],[]),[]) when is_non_zero_pat a ->
let p = match a.CAst.v with CPatPrim (Numeral (p, _)) -> p | _ -> assert false in
let pat, _df = Notation.interp_prim_token_cases_pattern_expr ?loc (ensure_kind false loc) (Numeral (p,false)) scopes in
rcp_of_glob scopes pat
- | CPatNotation ("( _ )",([a],[]),[]) ->
+ | CPatNotation ((InConstrEntrySomeLevel,"( _ )"),([a],[]),[]) ->
in_pat top scopes a
| CPatNotation (ntn,fullargs,extrargs) ->
let ntn,(terms,termlists) = contract_curly_brackets_pat ntn fullargs in
@@ -1724,15 +1732,15 @@ let get_implicit_name n imps =
let set_hole_implicit i b c =
let loc = c.CAst.loc in
match DAst.get c with
- | GRef (r, _) -> Loc.tag ?loc (Evar_kinds.ImplicitArg (r,i,b),Misctypes.IntroAnonymous,None)
+ | GRef (r, _) -> Loc.tag ?loc (Evar_kinds.ImplicitArg (r,i,b),IntroAnonymous,None)
| GApp (r, _) ->
let loc = r.CAst.loc in
begin match DAst.get r with
| GRef (r, _) ->
- Loc.tag ?loc (Evar_kinds.ImplicitArg (r,i,b),Misctypes.IntroAnonymous,None)
+ Loc.tag ?loc (Evar_kinds.ImplicitArg (r,i,b),IntroAnonymous,None)
| _ -> anomaly (Pp.str "Only refs have implicits.")
end
- | GVar id -> Loc.tag ?loc (Evar_kinds.ImplicitArg (VarRef id,i,b),Misctypes.IntroAnonymous,None)
+ | GVar id -> Loc.tag ?loc (Evar_kinds.ImplicitArg (VarRef id,i,b),IntroAnonymous,None)
| _ -> anomaly (Pp.str "Only refs have implicits.")
let exists_implicit_name id =
@@ -1870,10 +1878,10 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
DAst.make ?loc @@
GLetIn (na.CAst.v, inc1, int,
intern (push_name_env ntnvars (impls_term_list inc1) env na) c2)
- | CNotation ("- _", ([a],[],[],[])) when is_non_zero a ->
+ | CNotation ((InConstrEntrySomeLevel,"- _"), ([a],[],[],[])) when is_non_zero a ->
let p = match a.CAst.v with CPrim (Numeral (p, _)) -> p | _ -> assert false in
intern env (CAst.make ?loc @@ CPrim (Numeral (p,false)))
- | CNotation ("( _ )",([a],[],[],[])) -> intern env a
+ | CNotation ((InConstrEntrySomeLevel,"( _ )"),([a],[],[],[])) -> intern env a
| CNotation (ntn,args) ->
intern_notation intern env ntnvars loc ntn args
| CGeneralization (b,a,c) ->
@@ -1889,9 +1897,9 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
intern_applied_reference intern env (Environ.named_context globalenv)
lvar us args ref
in
- (* Rem: GApp(_,f,[]) stands for @f *)
- DAst.make ?loc @@
- GApp (f, intern_args env args_scopes (List.map fst args))
+ (* Rem: GApp(_,f,[]) stands for @f *)
+ if args = [] then DAst.make ?loc @@ GApp (f,[]) else
+ smart_gapp f loc (intern_args env args_scopes (List.map fst args))
| CApp ((isproj,f), args) ->
let f,args = match f.CAst.v with
@@ -1917,14 +1925,22 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
let st = Evar_kinds.Define (not (Program.get_proofs_transparency ())) in
let fields =
sort_fields ~complete:true loc fs
- (fun _idx -> CAst.make ?loc @@ CHole (Some (Evar_kinds.QuestionMark (st,Anonymous)),
- Misctypes.IntroAnonymous, None))
+ (fun _idx fieldname constructorname ->
+ let open Evar_kinds in
+ let fieldinfo : Evar_kinds.record_field =
+ {fieldname=fieldname; recordname=inductive_of_constructor constructorname}
+ in
+ CAst.make ?loc @@ CHole (Some
+ (Evar_kinds.QuestionMark { Evar_kinds.default_question_mark with
+ Evar_kinds.qm_obligation=st;
+ Evar_kinds.qm_record_field=Some fieldinfo
+ }) , IntroAnonymous, None))
in
begin
match fields with
| None -> user_err ?loc ~hdr:"intern" (str"No constructor inference.")
| Some (n, constrname, args) ->
- let pars = List.make n (CAst.make ?loc @@ CHole (None, Misctypes.IntroAnonymous, None)) in
+ let pars = List.make n (CAst.make ?loc @@ CHole (None, IntroAnonymous, None)) in
let app = CAst.make ?loc @@ CAppExpl ((None, constrname,None), List.rev_append pars args) in
intern env app
end
@@ -1964,13 +1980,13 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
let main_sub_eqn = CAst.make @@
([],thepats, (* "|p1,..,pn" *)
Option.cata (intern_type env')
- (DAst.make ?loc @@ GHole(Evar_kinds.CasesType false,Misctypes.IntroAnonymous,None))
+ (DAst.make ?loc @@ GHole(Evar_kinds.CasesType false,IntroAnonymous,None))
rtnpo) (* "=> P" if there were a return predicate P, and "=> _" otherwise *) in
let catch_all_sub_eqn =
if List.for_all (irrefutable globalenv) thepats then [] else
[CAst.make @@ ([],List.make (List.length thepats) (DAst.make @@ PatVar Anonymous), (* "|_,..,_" *)
- DAst.make @@ GHole(Evar_kinds.ImpossibleCase,Misctypes.IntroAnonymous,None))] (* "=> _" *) in
- Some (DAst.make @@ GCases(Term.RegularStyle,sub_rtn,sub_tms,main_sub_eqn::catch_all_sub_eqn))
+ DAst.make @@ GHole(Evar_kinds.ImpossibleCase,IntroAnonymous,None))] (* "=> _" *) in
+ Some (DAst.make @@ GCases(RegularStyle,sub_rtn,sub_tms,main_sub_eqn::catch_all_sub_eqn))
in
let eqns' = List.map (intern_eqn (List.length tms) env) eqns in
DAst.make ?loc @@
@@ -2000,8 +2016,8 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
| None ->
let st = Evar_kinds.Define (not (Program.get_proofs_transparency ())) in
(match naming with
- | Misctypes.IntroIdentifier id -> Evar_kinds.NamedHole id
- | _ -> Evar_kinds.QuestionMark (st,Anonymous))
+ | IntroIdentifier id -> Evar_kinds.NamedHole id
+ | _ -> Evar_kinds.QuestionMark { Evar_kinds.default_question_mark with Evar_kinds.qm_obligation=st; })
| Some k -> k
in
let solve = match solve with
@@ -2045,8 +2061,8 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
GSort s
| CCast (c1, c2) ->
DAst.make ?loc @@
- GCast (intern env c1, Miscops.map_cast_type (intern_type env) c2)
- )
+ GCast (intern env c1, map_cast_type (intern_type env) c2)
+ )
and intern_type env = intern (set_type_scope env)
and intern_local_binder env bind : intern_env * Glob_term.extended_glob_local_binder list =
diff --git a/interp/constrintern.mli b/interp/constrintern.mli
index f5e32dc4..dd0944cc 100644
--- a/interp/constrintern.mli
+++ b/interp/constrintern.mli
@@ -11,9 +11,7 @@
open Names
open Evd
open Environ
-open Misctypes
open Libnames
-open Globnames
open Glob_term
open Pattern
open EConstr
@@ -143,10 +141,10 @@ val intern_constr_pattern :
constr_pattern_expr -> patvar list * constr_pattern
(** Raise Not_found if syndef not bound to a name and error if unexisting ref *)
-val intern_reference : reference -> global_reference
+val intern_reference : qualid -> GlobRef.t
(** Expands abbreviations (syndef); raise an error if not existing *)
-val interp_reference : ltac_sign -> reference -> glob_constr
+val interp_reference : ltac_sign -> qualid -> glob_constr
(** Interpret binders *)
@@ -175,11 +173,11 @@ val interp_context_evars :
(** Locating references of constructions, possibly via a syntactic definition
(these functions do not modify the glob file) *)
-val locate_reference : Libnames.qualid -> Globnames.global_reference
+val locate_reference : Libnames.qualid -> GlobRef.t
val is_global : Id.t -> bool
-val construct_reference : ('c, 't) Context.Named.pt -> Id.t -> Globnames.global_reference
-val global_reference : Id.t -> Globnames.global_reference
-val global_reference_in_absolute_module : DirPath.t -> Id.t -> Globnames.global_reference
+val construct_reference : ('c, 't) Context.Named.pt -> Id.t -> GlobRef.t
+val global_reference : Id.t -> GlobRef.t
+val global_reference_in_absolute_module : DirPath.t -> Id.t -> GlobRef.t
(** Interprets a term as the left-hand side of a notation. The returned map is
guaranteed to have the same domain as the input one. *)
diff --git a/interp/declare.ml b/interp/declare.ml
index c55a6c69..a82e6b35 100644
--- a/interp/declare.ml
+++ b/interp/declare.ml
@@ -150,8 +150,8 @@ let register_side_effect (c, role) =
ignore(add_leaf id o);
update_tables c;
match role with
- | Safe_typing.Subproof -> ()
- | Safe_typing.Schema (ind, kind) -> !declare_scheme kind [|ind,c|]
+ | Subproof -> ()
+ | Schema (ind, kind) -> !declare_scheme kind [|ind,c|]
let declare_constant_common id cst =
let o = inConstant cst in
@@ -382,19 +382,44 @@ let inInductive : inductive_obj -> obj =
discharge_function = discharge_inductive;
rebuild_function = infer_inductive_subtyping }
-let declare_projections mind =
- let spec,_ = Inductive.lookup_mind_specif (Global.env ()) (mind,0) in
- match spec.mind_record with
- | Some (Some (_, kns, pjs)) ->
- Array.iteri (fun i kn ->
- let id = Label.to_id (Constant.label kn) in
- let entry = {proj_entry_ind = mind; proj_entry_arg = i} in
- let kn' = declare_constant id (ProjectionEntry entry,
- IsDefinition StructureComponent)
- in
- assert(Constant.equal kn kn')) kns; true,true
- | Some None -> true,false
- | None -> false,false
+let declare_one_projection univs (mind,_ as ind) ~proj_npars proj_arg label (term,types) =
+ let id = Label.to_id label in
+ let p = Projection.Repr.make ind ~proj_npars ~proj_arg label in
+ Recordops.declare_primitive_projection p;
+ (* ^ needs to happen before declaring the constant, otherwise
+ Heads gets confused. *)
+ let univs = match univs with
+ | Monomorphic_ind_entry _ ->
+ (** Global constraints already defined through the inductive *)
+ Monomorphic_const_entry Univ.ContextSet.empty
+ | Polymorphic_ind_entry ctx ->
+ Polymorphic_const_entry ctx
+ | Cumulative_ind_entry ctx ->
+ Polymorphic_const_entry (Univ.CumulativityInfo.univ_context ctx)
+ in
+ let term, types = match univs with
+ | Monomorphic_const_entry _ -> term, types
+ | Polymorphic_const_entry ctx ->
+ let u = Univ.UContext.instance ctx in
+ Vars.subst_instance_constr u term, Vars.subst_instance_constr u types
+ in
+ let entry = definition_entry ~types ~univs term in
+ ignore(declare_constant id (DefinitionEntry entry, IsDefinition StructureComponent))
+
+let declare_projections univs mind =
+ let env = Global.env () in
+ let mib = Environ.lookup_mind mind env in
+ match mib.mind_record with
+ | PrimRecord info ->
+ let iter_ind i (_, labs, _) =
+ let ind = (mind, i) in
+ let projs = Inductiveops.compute_projections env ind in
+ Array.iter2_i (declare_one_projection univs ind ~proj_npars:mib.mind_nparams) labs projs
+ in
+ let () = Array.iteri iter_ind info in
+ true
+ | FakeRecord -> false
+ | NotRecord -> false
(* for initial declaration *)
let declare_mind mie =
@@ -403,7 +428,7 @@ let declare_mind mie =
| [] -> anomaly (Pp.str "cannot declare an empty list of inductives.") in
let (sp,kn as oname) = add_leaf id (inInductive ([],mie)) in
let mind = Global.mind_of_delta_kn kn in
- let isrecord,isprim = declare_projections mind in
+ let isprim = declare_projections mie.mind_entry_universes mind in
declare_mib_implicits mind;
declare_inductive_argument_scopes mind mie;
oname, isprim
@@ -446,24 +471,20 @@ let assumption_message id =
discussion on coqdev: "Chapter 4 of the Reference Manual", 8/10/2015) *)
Flags.if_verbose Feedback.msg_info (Id.print id ++ str " is declared")
-(** Global universe names, in a different summary *)
-
-type universe_context_decl = polymorphic * Univ.ContextSet.t
-
-let cache_universe_context (p, ctx) =
- Global.push_context_set p ctx;
- if p then Lib.add_section_context ctx
+(** Monomorphic universes need to survive sections. *)
-let input_universe_context : universe_context_decl -> Libobject.obj =
+let input_universe_context : Univ.ContextSet.t -> Libobject.obj =
declare_object
- { (default_object "Global universe context state") with
- cache_function = (fun (na, pi) -> cache_universe_context pi);
- load_function = (fun _ (_, pi) -> cache_universe_context pi);
- discharge_function = (fun (_, (p, _ as x)) -> if p then None else Some x);
- classify_function = (fun a -> Keep a) }
+ { (default_object "Monomorphic section universes") with
+ cache_function = (fun (na, uctx) -> Global.push_context_set false uctx);
+ discharge_function = (fun (_, x) -> Some x);
+ classify_function = (fun a -> Dispose) }
let declare_universe_context poly ctx =
- Lib.add_anonymous_leaf (input_universe_context (poly, ctx))
+ if poly then
+ (Global.push_context_set true ctx; Lib.add_section_context ctx)
+ else
+ Lib.add_anonymous_leaf (input_universe_context ctx)
(** Global universes are not substitutive objects but global objects
bound at the *library* or *module* level. The polymorphic flag is
@@ -487,7 +508,7 @@ let add_universe src (dp, i) =
Option.iter (fun poly ->
let ctx = Univ.ContextSet.add_universe level Univ.ContextSet.empty in
Global.push_context_set poly ctx;
- Universes.add_global_universe level poly;
+ UnivNames.add_global_universe level poly;
if poly then Lib.add_section_context ctx)
optpoly
@@ -538,7 +559,7 @@ let input_universe : universe_decl -> Libobject.obj =
let declare_univ_binders gr pl =
if Global.is_polymorphic gr then
- Universes.register_universe_binders gr pl
+ UnivNames.register_universe_binders gr pl
else
let l = match gr with
| ConstRef c -> Label.to_id @@ Constant.label c
@@ -564,7 +585,7 @@ let do_universe poly l =
in
let l =
List.map (fun {CAst.v=id} ->
- let lev = Universes.new_univ_id () in
+ let lev = UnivGen.new_univ_id () in
(id, lev)) l
in
let src = if poly then BoundUniv else UnqualifiedUniv in
@@ -572,30 +593,11 @@ let do_universe poly l =
ignore(Lib.add_leaf id (input_universe (src, lev))))
l
-type constraint_decl = polymorphic * Univ.Constraint.t
-
-let cache_constraints (na, (p, c)) =
- let ctx =
- Univ.ContextSet.add_constraints c
- Univ.ContextSet.empty (* No declared universes here, just constraints *)
- in cache_universe_context (p,ctx)
-
-let discharge_constraints (_, (p, c as a)) =
- if p then None else Some a
-
-let input_constraints : constraint_decl -> Libobject.obj =
- let open Libobject in
- declare_object
- { (default_object "Global universe constraints") with
- cache_function = cache_constraints;
- load_function = (fun _ -> cache_constraints);
- discharge_function = discharge_constraints;
- classify_function = (fun a -> Keep a) }
-
let do_constraint poly l =
+ let open Univ in
let u_of_id x =
let level = Pretyping.interp_known_glob_level (Evd.from_env (Global.env ())) x in
- Universes.is_polymorphic level, level
+ UnivNames.is_polymorphic level, level
in
let in_section = Lib.sections_are_opened () in
let () =
@@ -614,7 +616,8 @@ let do_constraint poly l =
let constraints = List.fold_left (fun acc (l, d, r) ->
let p, lu = u_of_id l and p', ru = u_of_id r in
check_poly p p';
- Univ.Constraint.add (lu, d, ru) acc)
- Univ.Constraint.empty l
+ Constraint.add (lu, d, ru) acc)
+ Constraint.empty l
in
- Lib.add_anonymous_leaf (input_constraints (poly, constraints))
+ let uctx = ContextSet.add_constraints constraints ContextSet.empty in
+ declare_universe_context poly uctx
diff --git a/interp/declare.mli b/interp/declare.mli
index 084d746e..02e73cd6 100644
--- a/interp/declare.mli
+++ b/interp/declare.mli
@@ -83,10 +83,10 @@ val recursive_message : bool (** true = fixpoint *) ->
val exists_name : Id.t -> bool
(** Global universe contexts, names and constraints *)
-val declare_univ_binders : Globnames.global_reference -> Universes.universe_binders -> unit
+val declare_univ_binders : GlobRef.t -> UnivNames.universe_binders -> unit
val declare_universe_context : polymorphic -> Univ.ContextSet.t -> unit
-val do_universe : polymorphic -> Misctypes.lident list -> unit
-val do_constraint : polymorphic -> (Misctypes.glob_level * Univ.constraint_type * Misctypes.glob_level) list ->
+val do_universe : polymorphic -> lident list -> unit
+val do_constraint : polymorphic -> (Glob_term.glob_level * Univ.constraint_type * Glob_term.glob_level) list ->
unit
diff --git a/interp/discharge.ml b/interp/discharge.ml
index e16a955d..0e44a8b4 100644
--- a/interp/discharge.ml
+++ b/interp/discharge.ml
@@ -111,9 +111,10 @@ let process_inductive info modlist mib =
let section_decls' = Context.Named.map discharge section_decls in
let (params',inds') = abstract_inductive section_decls' nparamdecls inds in
let record = match mib.mind_record with
- | Some (Some (id, _, _)) -> Some (Some id)
- | Some None -> Some None
- | None -> None
+ | PrimRecord info ->
+ Some (Some (Array.map pi1 info))
+ | FakeRecord -> Some None
+ | NotRecord -> None
in
{ mind_entry_record = record;
mind_entry_finite = mib.mind_finite;
diff --git a/interp/dumpglob.ml b/interp/dumpglob.ml
index bc6a1ef3..ccad6b19 100644
--- a/interp/dumpglob.ml
+++ b/interp/dumpglob.ml
@@ -113,7 +113,7 @@ let type_of_global_ref gr =
"var" ^ type_of_logical_kind (Decls.variable_kind v)
| Globnames.IndRef ind ->
let (mib,oib) = Inductive.lookup_mind_specif (Global.env ()) ind in
- if mib.Declarations.mind_record <> None then
+ if mib.Declarations.mind_record <> Declarations.NotRecord then
begin match mib.Declarations.mind_finite with
| Finite -> "indrec"
| BiFinite -> "rec"
@@ -167,7 +167,7 @@ let dump_modref ?loc mp ty =
let dump_libref ?loc dp ty =
dump_ref ?loc (Names.DirPath.to_string dp) "<>" "<>" ty
-let cook_notation df sc =
+let cook_notation (from,df) sc =
(* We encode notations so that they are space-free and still human-readable *)
(* - all spaces are replaced by _ *)
(* - all _ denoting a non-terminal symbol are replaced by x *)
@@ -203,7 +203,9 @@ let cook_notation df sc =
if !i <= l then (set ntn !j '_'; incr j; incr i)
done;
let df = Bytes.sub_string ntn 0 !j in
- match sc with Some sc -> ":" ^ sc ^ ":" ^ df | _ -> "::" ^ df
+ let df_sc = match sc with Some sc -> ":" ^ sc ^ ":" ^ df | _ -> "::" ^ df in
+ let from_df_sc = match from with Constrexpr.InCustomEntryLevel (from,_) -> ":" ^ from ^ df_sc | Constrexpr.InConstrEntrySomeLevel -> ":" ^ df_sc in
+ from_df_sc
let dump_notation_location posl df (((path,secpath),_),sc) =
if dump () then
@@ -254,7 +256,7 @@ let dump_def ?loc ty secpath id = Option.iter (fun loc ->
let dump_definition {CAst.loc;v=id} sec s =
dump_def ?loc s (Names.DirPath.to_string (Lib.current_dirpath sec)) (Names.Id.to_string id)
-let dump_constraint (({ CAst.loc; v = n },_), _, _) sec ty =
+let dump_constraint { CAst.loc; v = n } sec ty =
match n with
| Names.Name id -> dump_definition CAst.(make ?loc id) sec ty
| Names.Anonymous -> ()
diff --git a/interp/dumpglob.mli b/interp/dumpglob.mli
index 43c10000..931d05a9 100644
--- a/interp/dumpglob.mli
+++ b/interp/dumpglob.mli
@@ -24,10 +24,10 @@ val feedback_glob : unit -> unit
val pause : unit -> unit
val continue : unit -> unit
-val add_glob : ?loc:Loc.t -> Globnames.global_reference -> unit
+val add_glob : ?loc:Loc.t -> Names.GlobRef.t -> unit
val add_glob_kn : ?loc:Loc.t -> Names.KerName.t -> unit
-val dump_definition : Misctypes.lident -> bool -> string -> unit
+val dump_definition : Names.lident -> bool -> string -> unit
val dump_moddef : ?loc:Loc.t -> Names.ModPath.t -> string -> unit
val dump_modref : ?loc:Loc.t -> Names.ModPath.t -> string -> unit
val dump_reference : ?loc:Loc.t -> string -> string -> string -> unit
@@ -38,9 +38,9 @@ val dump_binding : ?loc:Loc.t -> Names.Id.Set.elt -> unit
val dump_notation :
(Constrexpr.notation * Notation.notation_location) Loc.located ->
Notation_term.scope_name option -> bool -> unit
-val dump_constraint :
- Vernacexpr.typeclass_constraint -> bool -> string -> unit
+
+val dump_constraint : Names.lname -> bool -> string -> unit
val dump_string : string -> unit
-val type_of_global_ref : Globnames.global_reference -> string
+val type_of_global_ref : Names.GlobRef.t -> string
diff --git a/interp/genintern.ml b/interp/genintern.ml
index 161201c4..d9a0db04 100644
--- a/interp/genintern.ml
+++ b/interp/genintern.ml
@@ -26,9 +26,15 @@ let empty_glob_sign env = {
extra = Store.empty;
}
+(** In globalize tactics, we need to keep the initial [constr_expr] to recompute
+ in the environment by the effective calls to Intro, Inversion, etc
+ The [constr_expr] field is [None] in TacDef though *)
+type glob_constr_and_expr = Glob_term.glob_constr * Constrexpr.constr_expr option
+type glob_constr_pattern_and_expr = Id.Set.t * glob_constr_and_expr * Pattern.constr_pattern
+
type ('raw, 'glb) intern_fun = glob_sign -> 'raw -> glob_sign * 'glb
type 'glb subst_fun = substitution -> 'glb -> 'glb
-type 'glb ntn_subst_fun = Tactypes.glob_constr_and_expr Id.Map.t -> 'glb -> 'glb
+type 'glb ntn_subst_fun = glob_constr_and_expr Id.Map.t -> 'glb -> 'glb
module InternObj =
struct
diff --git a/interp/genintern.mli b/interp/genintern.mli
index d818713f..f4f064bc 100644
--- a/interp/genintern.mli
+++ b/interp/genintern.mli
@@ -22,6 +22,12 @@ type glob_sign = {
val empty_glob_sign : Environ.env -> glob_sign
+(** In globalize tactics, we need to keep the initial [constr_expr] to recompute
+ in the environment by the effective calls to Intro, Inversion, etc
+ The [constr_expr] field is [None] in TacDef though *)
+type glob_constr_and_expr = Glob_term.glob_constr * Constrexpr.constr_expr option
+type glob_constr_pattern_and_expr = Id.Set.t * glob_constr_and_expr * Pattern.constr_pattern
+
(** {5 Internalization functions} *)
type ('raw, 'glb) intern_fun = glob_sign -> 'raw -> glob_sign * 'glb
@@ -42,7 +48,7 @@ val generic_substitute : glob_generic_argument subst_fun
(** {5 Notation functions} *)
-type 'glb ntn_subst_fun = Tactypes.glob_constr_and_expr Id.Map.t -> 'glb -> 'glb
+type 'glb ntn_subst_fun = glob_constr_and_expr Id.Map.t -> 'glb -> 'glb
val substitute_notation : ('raw, 'glb, 'top) genarg_type -> 'glb ntn_subst_fun
diff --git a/intf/genredexpr.ml b/interp/genredexpr.ml
index 80697461..607f2258 100644
--- a/intf/genredexpr.ml
+++ b/interp/genredexpr.ml
@@ -52,15 +52,14 @@ type ('a,'b,'c) red_expr_gen =
type ('a,'b,'c) may_eval =
| ConstrTerm of 'a
| ConstrEval of ('a,'b,'c) red_expr_gen * 'a
- | ConstrContext of Misctypes.lident * 'a
+ | ConstrContext of Names.lident * 'a
| ConstrTypeOf of 'a
open Libnames
open Constrexpr
-open Misctypes
type r_trm = constr_expr
type r_pat = constr_pattern_expr
-type r_cst = reference or_by_notation
+type r_cst = qualid or_by_notation
type raw_red_expr = (r_trm, r_cst, r_pat) red_expr_gen
diff --git a/interp/impargs.ml b/interp/impargs.ml
index 9ad62c0d..e542b818 100644
--- a/interp/impargs.ml
+++ b/interp/impargs.ml
@@ -139,7 +139,7 @@ let argument_less = function
| Hyp _, Conclusion -> true
| Conclusion, _ -> false
-let update pos rig (na,st) =
+let update pos rig st =
let e =
if rig then
match st with
@@ -163,7 +163,7 @@ let update pos rig (na,st) =
| Some (DepFlex fpos as x) ->
if argument_less (pos,fpos) then DepFlex pos else x
| Some Manual -> assert false
- in na, Some e
+ in Some e
(* modified is_rigid_reference with a truncated env *)
let is_flexible_reference env sigma bound depth f =
@@ -214,6 +214,8 @@ let add_free_rels_until strict strongly_strict revpat bound env sigma m pos acc
let () = if not (Vars.noccur_between sigma 1 bound m) then frec true (env,1) m in
acc
+(* compute the list of implicit arguments *)
+
let rec is_rigid_head sigma t = match kind sigma t with
| Rel _ | Evar _ -> false
| Ind _ | Const _ | Var _ | Sort _ -> true
@@ -226,51 +228,69 @@ let rec is_rigid_head sigma t = match kind sigma t with
| Lambda _ | LetIn _ | Construct _ | CoFix _ | Fix _
| Prod _ | Meta _ | Cast _ -> assert false
-(* calcule la liste des arguments implicites *)
+let is_rigid env sigma t =
+ let open Context.Rel.Declaration in
+ let t = whd_all env sigma t in
+ match kind sigma t with
+ | Prod (na,a,b) ->
+ let (_,t) = splay_prod (push_rel (LocalAssum (na,a)) env) sigma b in
+ is_rigid_head sigma t
+ | _ -> true
-let find_displayed_name_in all avoid na (env, b) =
+let find_displayed_name_in sigma all avoid na (env, b) =
let envnames_b = (env, b) in
let flag = RenamingElsewhereFor envnames_b in
- if all then compute_and_force_displayed_name_in Evd.empty flag avoid na b
- else compute_displayed_name_in Evd.empty flag avoid na b
+ if all then compute_and_force_displayed_name_in sigma flag avoid na b
+ else compute_displayed_name_in sigma flag avoid na b
+
+let compute_implicits_names_gen all env sigma t =
+ let open Context.Rel.Declaration in
+ let rec aux env avoid names t =
+ let t = whd_all env sigma t in
+ match kind sigma t with
+ | Prod (na,a,b) ->
+ let na',avoid' = find_displayed_name_in sigma all avoid na (names,b) in
+ aux (push_rel (LocalAssum (na,a)) env) avoid' (na'::names) b
+ | _ -> List.rev names
+ in aux env Id.Set.empty [] t
+
+let compute_implicits_names = compute_implicits_names_gen true
-let compute_implicits_gen strict strongly_strict revpat contextual all env sigma (t : EConstr.t) =
- let rigid = ref true in
+let compute_implicits_explanation_gen strict strongly_strict revpat contextual env sigma t =
let open Context.Rel.Declaration in
- let rec aux env avoid n names (t : EConstr.t) =
+ let rec aux env n t =
let t = whd_all env sigma t in
match kind sigma t with
- | Prod (na,a,b) ->
- let na',avoid' = find_displayed_name_in all avoid na (names,b) in
- add_free_rels_until strict strongly_strict revpat n env sigma a (Hyp (n+1))
- (aux (push_rel (LocalAssum (na',a)) env) avoid' (n+1) (na'::names) b)
- | _ ->
- rigid := is_rigid_head sigma t;
- let names = List.rev names in
- let v = Array.map (fun na -> na,None) (Array.of_list names) in
- if contextual then
- add_free_rels_until strict strongly_strict revpat n env sigma t Conclusion v
- else v
+ | Prod (na,a,b) ->
+ add_free_rels_until strict strongly_strict revpat n env sigma a (Hyp (n+1))
+ (aux (push_rel (LocalAssum (na,a)) env) (n+1) b)
+ | _ ->
+ let v = Array.make n None in
+ if contextual then
+ add_free_rels_until strict strongly_strict revpat n env sigma t Conclusion v
+ else v
in
match kind sigma (whd_all env sigma t) with
- | Prod (na,a,b) ->
- let na',avoid = find_displayed_name_in all Id.Set.empty na ([],b) in
- let v = aux (push_rel (LocalAssum (na',a)) env) avoid 1 [na'] b in
- !rigid, Array.to_list v
- | _ -> true, []
+ | Prod (na,a,b) ->
+ let v = aux (push_rel (LocalAssum (na,a)) env) 1 b in
+ Array.to_list v
+ | _ -> []
-let compute_implicits_flags env sigma f all t =
- compute_implicits_gen
+let compute_implicits_explanation_flags env sigma f t =
+ compute_implicits_explanation_gen
(f.strict || f.strongly_strict) f.strongly_strict
- f.reversible_pattern f.contextual all env sigma t
+ f.reversible_pattern f.contextual env sigma t
-let compute_auto_implicits env sigma flags enriching t =
- if enriching then compute_implicits_flags env sigma flags true t
- else compute_implicits_gen false false false true true env sigma t
+let compute_implicits_flags env sigma f all t =
+ List.combine
+ (compute_implicits_names_gen all env sigma t)
+ (compute_implicits_explanation_flags env sigma f t)
-let compute_implicits_names env sigma t =
- let _, impls = compute_implicits_gen false false false false true env sigma t in
- List.map fst impls
+let compute_auto_implicits env sigma flags enriching t =
+ List.combine
+ (compute_implicits_names env sigma t)
+ (if enriching then compute_implicits_explanation_flags env sigma flags t
+ else compute_implicits_explanation_gen false false false true env sigma t)
(* Extra information about implicit arguments *)
@@ -329,13 +349,16 @@ let rec prepare_implicits f = function
Some (id,imp,(set_maximality imps' f.maximal,true)) :: imps'
| _::imps -> None :: prepare_implicits f imps
-let set_implicit id imp insmax =
- (id,(match imp with None -> Manual | Some imp -> imp),insmax)
-
-let rec assoc_by_pos k = function
- (ExplByPos (k', x), b) :: tl when Int.equal k k' -> (x,b), tl
- | hd :: tl -> let (x, tl) = assoc_by_pos k tl in x, hd :: tl
- | [] -> raise Not_found
+(*
+If found, returns Some (x,(b,fi,fo)) and l with the entry removed,
+otherwise returns None and l unchanged.
+ *)
+let assoc_by_pos k l =
+ let rec aux = function
+ (ExplByPos (k', x), b) :: tl when Int.equal k k' -> Some (x,b), tl
+ | hd :: tl -> let (x, tl) = aux tl in x, hd :: tl
+ | [] -> raise Not_found
+ in try aux l with Not_found -> None, l
let check_correct_manual_implicits autoimps l =
List.iter (function
@@ -352,70 +375,65 @@ let check_correct_manual_implicits autoimps l =
(str "Cannot set implicit argument number " ++ int i ++
str ": it has no name.")) l
-let set_manual_implicits env flags enriching autoimps l =
- let try_forced k l =
- try
- let (id, (b, fi, fo)), l' = assoc_by_pos k l in
- if fo then
- let id = match id with Some id -> id | None -> Id.of_string ("arg_" ^ string_of_int k) in
- l', Some (id,Manual,(b,fi))
- else l, None
- with Not_found -> l, None
- in
+(* Take a list l of explicitations, and map them to positions. *)
+let flatten_explicitations l autoimps =
+ let rec aux k l = function
+ | (Name id,_)::imps ->
+ let value, l' =
+ try
+ let eq = explicitation_eq in
+ let flags = List.assoc_f eq (ExplByName id) l in
+ Some (Some id, flags), List.remove_assoc_f eq (ExplByName id) l
+ with Not_found -> assoc_by_pos k l
+ in value :: aux (k+1) l' imps
+ | (Anonymous,_)::imps ->
+ let value, l' = assoc_by_pos k l
+ in value :: aux (k+1) l' imps
+ | [] when List.is_empty l -> []
+ | [] ->
+ check_correct_manual_implicits autoimps l;
+ []
+ in aux 1 l autoimps
+
+let set_manual_implicits flags enriching autoimps l =
if not (List.distinct l) then
user_err Pp.(str "Some parameters are referred more than once.");
(* Compare with automatic implicits to recover printing data and names *)
- let rec merge k l = function
- | (Name id,imp)::imps ->
- let l',imp,m =
- try
- let eq = explicitation_eq in
- let (b, fi, fo) = List.assoc_f eq (ExplByName id) l in
- List.remove_assoc_f eq (ExplByName id) l, (Some Manual), (Some (b, fi))
- with Not_found ->
- try
- let (id, (b, fi, fo)), l' = assoc_by_pos k l in
- l', (Some Manual), (Some (b,fi))
- with Not_found ->
- let m = match enriching, imp with
- | true, Some _ -> Some (flags.maximal, true)
- | _ -> None
- in
- l, imp, m
- in
- let imps' = merge (k+1) l' imps in
- let m = Option.map (fun (b,f) ->
- (* match imp with Some Manual -> (b,f) *)
- (* | _ -> *)set_maximality imps' b, f) m in
- Option.map (set_implicit id imp) m :: imps'
- | (Anonymous,imp)::imps ->
- let l', forced = try_forced k l in
- forced :: merge (k+1) l' imps
- | [] when begin match l with [] -> true | _ -> false end -> []
- | [] ->
- check_correct_manual_implicits autoimps l;
- []
- in
- merge 1 l autoimps
-
-let compute_semi_auto_implicits env sigma f manual t =
- match manual with
- | [] ->
- if not f.auto then [DefaultImpArgs, []]
- else let _,l = compute_implicits_flags env sigma f false t in
- [DefaultImpArgs, prepare_implicits f l]
- | _ ->
- let _,autoimpls = compute_auto_implicits env sigma f f.auto t in
- [DefaultImpArgs, set_manual_implicits env f f.auto autoimpls manual]
+ let rec merge k autoimps explimps = match autoimps, explimps with
+ | autoimp::autoimps, explimp::explimps ->
+ let imps' = merge (k+1) autoimps explimps in
+ begin match autoimp, explimp with
+ | (Name id,_), Some (_, (b, fi, _)) ->
+ Some (id, Manual, (set_maximality imps' b, fi))
+ | (Name id,Some exp), None when enriching ->
+ Some (id, exp, (set_maximality imps' flags.maximal, true))
+ | (Name _,_), None -> None
+ | (Anonymous,_), Some (Some id, (b, fi, true)) ->
+ Some (id,Manual,(b,fi))
+ | (Anonymous,_), Some (None, (b, fi, true)) ->
+ let id = Id.of_string ("arg_" ^ string_of_int k) in
+ Some (id,Manual,(b,fi))
+ | (Anonymous,_), Some (_, (_, _, false)) -> None
+ | (Anonymous,_), None -> None
+ end :: imps'
+ | [], [] -> []
+ (* flatten_explicitations returns a list of the same length as autoimps *)
+ | _ -> assert false
+ in merge 1 autoimps (flatten_explicitations l autoimps)
+
+let compute_semi_auto_implicits env sigma f t =
+ if not f.auto then [DefaultImpArgs, []]
+ else let l = compute_implicits_flags env sigma f false t in
+ [DefaultImpArgs, prepare_implicits f l]
(*s Constants. *)
-let compute_constant_implicits flags manual cst =
+let compute_constant_implicits flags cst =
let env = Global.env () in
let sigma = Evd.from_env env in
let cb = Environ.lookup_constant cst env in
let ty = of_constr cb.const_type in
- let impls = compute_semi_auto_implicits env sigma flags manual ty in
+ let impls = compute_semi_auto_implicits env sigma flags ty in
impls
(*s Inductives and constructors. Their implicit arguments are stored
@@ -423,7 +441,7 @@ let compute_constant_implicits flags manual cst =
$i$ are the implicit arguments of the inductive and $v$ the array of
implicit arguments of the constructors. *)
-let compute_mib_implicits flags manual kn =
+let compute_mib_implicits flags kn =
let env = Global.env () in
let sigma = Evd.from_env env in
let mib = Environ.lookup_mind kn env in
@@ -439,34 +457,34 @@ let compute_mib_implicits flags manual kn =
let imps_one_inductive i mip =
let ind = (kn,i) in
let ar, _ = Global.type_of_global_in_context env (IndRef ind) in
- ((IndRef ind,compute_semi_auto_implicits env sigma flags manual (of_constr ar)),
+ ((IndRef ind,compute_semi_auto_implicits env sigma flags (of_constr ar)),
Array.mapi (fun j c ->
- (ConstructRef (ind,j+1),compute_semi_auto_implicits env_ar sigma flags manual c))
+ (ConstructRef (ind,j+1),compute_semi_auto_implicits env_ar sigma flags c))
(Array.map of_constr mip.mind_nf_lc))
in
Array.mapi imps_one_inductive mib.mind_packets
-let compute_all_mib_implicits flags manual kn =
- let imps = compute_mib_implicits flags manual kn in
+let compute_all_mib_implicits flags kn =
+ let imps = compute_mib_implicits flags kn in
List.flatten
(Array.map_to_list (fun (ind,cstrs) -> ind::Array.to_list cstrs) imps)
(*s Variables. *)
-let compute_var_implicits flags manual id =
+let compute_var_implicits flags id =
let env = Global.env () in
let sigma = Evd.from_env env in
- compute_semi_auto_implicits env sigma flags manual (NamedDecl.get_type (lookup_named id env))
+ compute_semi_auto_implicits env sigma flags (NamedDecl.get_type (lookup_named id env))
(* Implicits of a global reference. *)
-let compute_global_implicits flags manual = function
- | VarRef id -> compute_var_implicits flags manual id
- | ConstRef kn -> compute_constant_implicits flags manual kn
+let compute_global_implicits flags = function
+ | VarRef id -> compute_var_implicits flags id
+ | ConstRef kn -> compute_constant_implicits flags kn
| IndRef (kn,i) ->
- let ((_,imps),_) = (compute_mib_implicits flags manual kn).(i) in imps
+ let ((_,imps),_) = (compute_mib_implicits flags kn).(i) in imps
| ConstructRef ((kn,i),j) ->
- let (_,cimps) = (compute_mib_implicits flags manual kn).(i) in snd cimps.(j-1)
+ let (_,cimps) = (compute_mib_implicits flags kn).(i) in snd cimps.(j-1)
(* Merge a manual explicitation with an implicit_status list *)
@@ -487,7 +505,7 @@ type implicit_discharge_request =
| ImplLocal
| ImplConstant of Constant.t * implicits_flags
| ImplMutualInductive of MutInd.t * implicits_flags
- | ImplInteractive of global_reference * implicits_flags *
+ | ImplInteractive of GlobRef.t * implicits_flags *
implicit_interactive_request
let implicits_table = Summary.ref Refmap.empty ~name:"implicits"
@@ -520,7 +538,7 @@ let subst_implicits_decl subst (r,imps as o) =
let r' = fst (subst_global subst r) in if r==r' then o else (r',imps)
let subst_implicits (subst,(req,l)) =
- (ImplLocal,List.smartmap (subst_implicits_decl subst) l)
+ (ImplLocal,List.Smart.map (subst_implicits_decl subst) l)
let impls_of_context ctx =
let map (decl, impl) = match impl with
@@ -573,34 +591,34 @@ let rebuild_implicits (req,l) =
| ImplLocal -> assert false
| ImplConstant (con,flags) ->
let oldimpls = snd (List.hd l) in
- let newimpls = compute_constant_implicits flags [] con in
+ let newimpls = compute_constant_implicits flags con in
req, [ConstRef con, List.map2 merge_impls oldimpls newimpls]
| ImplMutualInductive (kn,flags) ->
- let newimpls = compute_all_mib_implicits flags [] kn in
+ let newimpls = compute_all_mib_implicits flags kn in
let rec aux olds news =
- match olds, news with
- | (_, oldimpls) :: old, (gr, newimpls) :: tl ->
- (gr, List.map2 merge_impls oldimpls newimpls) :: aux old tl
- | [], [] -> []
- | _, _ -> assert false
+ match olds, news with
+ | (_, oldimpls) :: old, (gr, newimpls) :: tl ->
+ (gr, List.map2 merge_impls oldimpls newimpls) :: aux old tl
+ | [], [] -> []
+ | _, _ -> assert false
in req, aux l newimpls
| ImplInteractive (ref,flags,o) ->
(if isVarRef ref && is_in_section ref then ImplLocal else req),
match o with
| ImplAuto ->
- let oldimpls = snd (List.hd l) in
- let newimpls = compute_global_implicits flags [] ref in
- [ref,List.map2 merge_impls oldimpls newimpls]
+ let oldimpls = snd (List.hd l) in
+ let newimpls = compute_global_implicits flags ref in
+ [ref,List.map2 merge_impls oldimpls newimpls]
| ImplManual userimplsize ->
- let oldimpls = snd (List.hd l) in
- if flags.auto then
- let newimpls = List.hd (compute_global_implicits flags [] ref) in
- let p = List.length (snd newimpls) - userimplsize in
- let newimpls = on_snd (List.firstn p) newimpls in
- [ref,List.map (fun o -> merge_impls o newimpls) oldimpls]
- else
- [ref,oldimpls]
+ let oldimpls = snd (List.hd l) in
+ if flags.auto then
+ let newimpls = List.hd (compute_global_implicits flags ref) in
+ let p = List.length (snd newimpls) - userimplsize in
+ let newimpls = on_snd (List.firstn p) newimpls in
+ [ref,List.map (fun o -> merge_impls o newimpls) oldimpls]
+ else
+ [ref,oldimpls]
let classify_implicits (req,_ as obj) = match req with
| ImplLocal -> Dispose
@@ -608,7 +626,7 @@ let classify_implicits (req,_ as obj) = match req with
type implicits_obj =
implicit_discharge_request *
- (global_reference * implicits_list list) list
+ (GlobRef.t * implicits_list list) list
let inImplicits : implicits_obj -> obj =
declare_object {(default_object "IMPLICITS") with
@@ -622,7 +640,7 @@ let inImplicits : implicits_obj -> obj =
let is_local local ref = local || isVarRef ref && is_in_section ref
let declare_implicits_gen req flags ref =
- let imps = compute_global_implicits flags [] ref in
+ let imps = compute_global_implicits flags ref in
add_anonymous_leaf (inImplicits (req,[ref,imps]))
let declare_implicits local ref =
@@ -643,7 +661,7 @@ let declare_mib_implicits kn =
let flags = !implicit_args in
let imps = Array.map_to_list
(fun (ind,cstrs) -> ind::(Array.to_list cstrs))
- (compute_mib_implicits flags [] kn) in
+ (compute_mib_implicits flags kn) in
add_anonymous_leaf
(inImplicits (ImplMutualInductive (kn,flags),List.flatten imps))
@@ -653,8 +671,8 @@ type manual_explicitation = Constrexpr.explicitation * (bool * bool * bool)
type manual_implicits = manual_explicitation list
let compute_implicits_with_manual env sigma typ enriching l =
- let _,autoimpls = compute_auto_implicits env sigma !implicit_args enriching typ in
- set_manual_implicits env !implicit_args enriching autoimpls l
+ let autoimpls = compute_auto_implicits env sigma !implicit_args enriching typ in
+ set_manual_implicits !implicit_args enriching autoimpls l
let check_inclusion l =
(* Check strict inclusion *)
@@ -671,34 +689,34 @@ let check_rigidity isrigid =
user_err (strbrk "Multiple sequences of implicit arguments available only for references that cannot be applied to an arbitrarily large number of arguments.")
let projection_implicits env p impls =
- let pb = Environ.lookup_projection p env in
- CList.skipn_at_least pb.Declarations.proj_npars impls
+ let npars = Projection.npars p in
+ CList.skipn_at_least npars impls
let declare_manual_implicits local ref ?enriching l =
let flags = !implicit_args in
let env = Global.env () in
let sigma = Evd.from_env env in
let t, _ = Global.type_of_global_in_context env ref in
+ let t = of_constr t in
let enriching = Option.default flags.auto enriching in
- let isrigid,autoimpls = compute_auto_implicits env sigma flags enriching (of_constr t) in
+ let autoimpls = compute_auto_implicits env sigma flags enriching t in
let l' = match l with
| [] -> assert false
| [l] ->
- [DefaultImpArgs, set_manual_implicits env flags enriching autoimpls l]
+ [DefaultImpArgs, set_manual_implicits flags enriching autoimpls l]
| _ ->
- check_rigidity isrigid;
- let l = List.map (fun imps -> (imps,List.length imps)) l in
- let l = List.sort (fun (_,n1) (_,n2) -> n2 - n1) l in
- check_inclusion l;
- let nargs = List.length autoimpls in
- List.map (fun (imps,n) ->
- (LessArgsThan (nargs-n),
- set_manual_implicits env flags enriching autoimpls imps)) l in
+ check_rigidity (is_rigid env sigma t);
+ let l = List.map (fun imps -> (imps,List.length imps)) l in
+ let l = List.sort (fun (_,n1) (_,n2) -> n2 - n1) l in
+ check_inclusion l;
+ let nargs = List.length autoimpls in
+ List.map (fun (imps,n) ->
+ (LessArgsThan (nargs-n),
+ set_manual_implicits flags enriching autoimpls imps)) l in
let req =
if is_local local ref then ImplLocal
else ImplInteractive(ref,flags,ImplManual (List.length autoimpls))
- in
- add_anonymous_leaf (inImplicits (req,[ref,l']))
+ in add_anonymous_leaf (inImplicits (req,[ref,l']))
let maybe_declare_manual_implicits local ref ?enriching l =
match l with
diff --git a/interp/impargs.mli b/interp/impargs.mli
index 103a4f9e..ea5aa90f 100644
--- a/interp/impargs.mli
+++ b/interp/impargs.mli
@@ -10,7 +10,6 @@
open Names
open EConstr
-open Globnames
open Environ
(** {6 Implicit Arguments } *)
@@ -103,7 +102,7 @@ val declare_var_implicits : variable -> unit
val declare_constant_implicits : Constant.t -> unit
val declare_mib_implicits : MutInd.t -> unit
-val declare_implicits : bool -> global_reference -> unit
+val declare_implicits : bool -> GlobRef.t -> unit
(** [declare_manual_implicits local ref enriching l]
Manual declaration of which arguments are expected implicit.
@@ -111,15 +110,15 @@ val declare_implicits : bool -> global_reference -> unit
implicits depending on the current state.
Unsets implicits if [l] is empty. *)
-val declare_manual_implicits : bool -> global_reference -> ?enriching:bool ->
+val declare_manual_implicits : bool -> GlobRef.t -> ?enriching:bool ->
manual_implicits list -> unit
(** If the list is empty, do nothing, otherwise declare the implicits. *)
-val maybe_declare_manual_implicits : bool -> global_reference -> ?enriching:bool ->
+val maybe_declare_manual_implicits : bool -> GlobRef.t -> ?enriching:bool ->
manual_implicits -> unit
-val implicits_of_global : global_reference -> implicits_list list
+val implicits_of_global : GlobRef.t -> implicits_list list
val extract_impargs_data :
implicits_list list -> ((int * int) option * implicit_status list) list
diff --git a/interp/implicit_quantifiers.ml b/interp/implicit_quantifiers.ml
index 58df9abc..4f3037b1 100644
--- a/interp/implicit_quantifiers.ml
+++ b/interp/implicit_quantifiers.ml
@@ -17,12 +17,14 @@ open Glob_term
open Constrexpr
open Libnames
open Typeclasses
-open Typeclasses_errors
open Pp
open Libobject
open Nameops
open Context.Rel.Declaration
+exception MismatchedContextInstance of Environ.env * Typeclasses_errors.contexts * constr_expr list * Constr.rel_context (* found, expected *)
+let mismatched_ctx_inst_err env c n m = raise (MismatchedContextInstance (env, c, n, m))
+
module RelDecl = Context.Rel.Declaration
(*i*)
@@ -51,14 +53,14 @@ let cache_generalizable_type (_,(local,cmd)) =
let load_generalizable_type _ (_,(local,cmd)) =
generalizable_table := add_generalizable cmd !generalizable_table
-let in_generalizable : bool * Misctypes.lident list option -> obj =
+let in_generalizable : bool * lident list option -> obj =
declare_object {(default_object "GENERALIZED-IDENT") with
load_function = load_generalizable_type;
cache_function = cache_generalizable_type;
classify_function = (fun (local, _ as obj) -> if local then Dispose else Keep obj)
}
-let declare_generalizable local gen =
+let declare_generalizable ~local gen =
Lib.add_anonymous_leaf (in_generalizable (local, gen))
let find_generalizable_ident id = Id.Pred.mem (root_of_id id) !generalizable_table
@@ -94,9 +96,11 @@ let free_vars_of_constr_expr c ?(bound=Id.Set.empty) l =
else l
in
let rec aux bdvars l c = match CAst.(c.v) with
- | CRef ({CAst.v=Ident id},_) -> found c.CAst.loc id bdvars l
- | CNotation ("{ _ : _ | _ }", ({ CAst.v = CRef ({CAst.v=Ident id},_) } :: _, [], [], [])) when not (Id.Set.mem id bdvars) ->
- Constrexpr_ops.fold_constr_expr_with_binders (fun a l -> Id.Set.add a l) aux (Id.Set.add id bdvars) l c
+ | CRef (qid,_) when qualid_is_ident qid ->
+ found c.CAst.loc (qualid_basename qid) bdvars l
+ | CNotation ((InConstrEntrySomeLevel,"{ _ : _ | _ }"), ({ CAst.v = CRef (qid,_) } :: _, [], [], [])) when
+ qualid_is_ident qid && not (Id.Set.mem (qualid_basename qid) bdvars) ->
+ Constrexpr_ops.fold_constr_expr_with_binders (fun a l -> Id.Set.add a l) aux (Id.Set.add (qualid_basename qid) bdvars) l c
| _ -> Constrexpr_ops.fold_constr_expr_with_binders (fun a l -> Id.Set.add a l) aux bdvars l c
in aux bound l c
@@ -194,7 +198,7 @@ let combine_params avoid fn applied needed =
let combine_params_freevar =
fun avoid (_, decl) ->
let id' = next_name_away_from (RelDecl.get_name decl) avoid in
- (CAst.make @@ CRef (CAst.make @@ Ident id',None), Id.Set.add id' avoid)
+ (CAst.make @@ CRef (qualid_of_ident id',None), Id.Set.add id' avoid)
let destClassApp cl =
let open CAst in
@@ -216,9 +220,8 @@ let destClassAppExpl cl =
let implicit_application env ?(allow_partial=true) f ty =
let is_class =
try
- let ({CAst.v=(r, _, _)} as clapp) = destClassAppExpl ty in
- let qid = qualid_of_reference r in
- let gr = Nametab.locate qid.CAst.v in
+ let ({CAst.v=(qid, _, _)} as clapp) = destClassAppExpl ty in
+ let gr = Nametab.locate qid in
if Typeclasses.is_class gr then Some (clapp, gr) else None
with Not_found -> None
in
@@ -238,7 +241,7 @@ let implicit_application env ?(allow_partial=true) f ty =
let applen = List.fold_left (fun acc (x, y) -> opt_succ y acc) 0 par in
let needlen = List.fold_left (fun acc x -> opt_succ x acc) 0 ci in
if not (Int.equal needlen applen) then
- Typeclasses_errors.mismatched_ctx_inst (Global.env ()) Parameters (List.map fst par) rd
+ mismatched_ctx_inst_err (Global.env ()) Typeclasses_errors.Parameters (List.map fst par) rd
end;
let pars = List.rev (List.combine ci rd) in
let args, avoid = combine_params avoid f par pars in
diff --git a/interp/implicit_quantifiers.mli b/interp/implicit_quantifiers.mli
index b9815f34..437fef17 100644
--- a/interp/implicit_quantifiers.mli
+++ b/interp/implicit_quantifiers.mli
@@ -12,13 +12,12 @@ open Names
open Glob_term
open Constrexpr
open Libnames
-open Globnames
-val declare_generalizable : Vernacexpr.locality_flag -> Misctypes.lident list option -> unit
+val declare_generalizable : local:bool -> lident list option -> unit
val ids_of_list : Id.t list -> Id.Set.t
-val destClassApp : constr_expr -> (reference * constr_expr list * instance_expr option) CAst.t
-val destClassAppExpl : constr_expr -> (reference * (constr_expr * explicitation CAst.t option) list * instance_expr option) CAst.t
+val destClassApp : constr_expr -> (qualid * constr_expr list * instance_expr option) CAst.t
+val destClassAppExpl : constr_expr -> (qualid * (constr_expr * explicitation CAst.t option) list * instance_expr option) CAst.t
(** Fragile, should be used only for construction a set of identifiers to avoid *)
@@ -32,17 +31,21 @@ val free_vars_of_binders :
order with the location of their first occurrence *)
val generalizable_vars_of_glob_constr : ?bound:Id.Set.t -> ?allowed:Id.Set.t ->
- glob_constr -> Misctypes.lident list
+ glob_constr -> lident list
val make_fresh : Id.Set.t -> Environ.env -> Id.t -> Id.t
val implicits_of_glob_constr : ?with_products:bool -> Glob_term.glob_constr -> Impargs.manual_implicits
val combine_params_freevar :
- Id.Set.t -> global_reference option * Context.Rel.Declaration.t ->
+ Id.Set.t -> GlobRef.t option * Constr.rel_declaration ->
Constrexpr.constr_expr * Id.Set.t
val implicit_application : Id.Set.t -> ?allow_partial:bool ->
- (Id.Set.t -> global_reference option * Context.Rel.Declaration.t ->
+ (Id.Set.t -> GlobRef.t option * Constr.rel_declaration ->
Constrexpr.constr_expr * Id.Set.t) ->
constr_expr -> constr_expr * Id.Set.t
+
+(* Should be likely located elsewhere *)
+exception MismatchedContextInstance of Environ.env * Typeclasses_errors.contexts * constr_expr list * Constr.rel_context (* found, expected *)
+val mismatched_ctx_inst_err : Environ.env -> Typeclasses_errors.contexts -> constr_expr list -> Constr.rel_context -> 'a
diff --git a/interp/interp.mllib b/interp/interp.mllib
index bb22cf46..3668455a 100644
--- a/interp/interp.mllib
+++ b/interp/interp.mllib
@@ -1,14 +1,16 @@
+Constrexpr
+Genredexpr
+Redops
Tactypes
Stdarg
Genintern
+Notation_term
Notation_ops
Notation
Syntax_def
Smartlocate
Constrexpr_ops
-Ppextend
Dumpglob
-Topconstr
Reserve
Impargs
Implicit_quantifiers
diff --git a/interp/modintern.ml b/interp/modintern.ml
index dc93d8dc..c27cc9cc 100644
--- a/interp/modintern.ml
+++ b/interp/modintern.ml
@@ -12,7 +12,7 @@ open Declarations
open Libnames
open Constrexpr
open Constrintern
-open Misctypes
+open Declaremods
type module_internalization_error =
| NotAModuleNorModtype of string
@@ -23,7 +23,7 @@ exception ModuleInternalizationError of module_internalization_error
let error_not_a_module_loc kind loc qid =
let s = string_of_qualid qid in
- let e = match kind with
+ let e = let open Declaremods in match kind with
| Module -> Modops.ModuleTypingError (Modops.NotAModule s)
| ModType -> Modops.ModuleTypingError (Modops.NotAModuleType s)
| ModAny -> ModuleInternalizationError (NotAModuleNorModtype s)
@@ -45,7 +45,9 @@ let error_application_to_module_type loc =
or both are searched. The returned kind is never ModAny, and
it is equal to the input kind when this one isn't ModAny. *)
-let lookup_module_or_modtype kind {CAst.loc;v=qid} =
+let lookup_module_or_modtype kind qid =
+ let open Declaremods in
+ let loc = qid.CAst.loc in
try
if kind == ModType then raise Not_found;
let mp = Nametab.locate_module qid in
@@ -63,7 +65,7 @@ let transl_with_decl env = function
| CWith_Module ({CAst.v=fqid},qid) ->
WithMod (fqid,lookup_module qid), Univ.ContextSet.empty
| CWith_Definition ({CAst.v=fqid},udecl,c) ->
- let sigma, udecl = Univdecls.interp_univ_decl_opt env udecl in
+ let sigma, udecl = Constrexpr_ops.interp_univ_decl_opt env udecl in
let c, ectx = interp_constr env sigma c in
begin match UState.check_univ_decl ~poly:(Flags.is_universe_polymorphism()) ectx udecl with
| Entries.Polymorphic_const_entry ctx ->
@@ -83,7 +85,7 @@ let loc_of_module l = l.CAst.loc
let rec interp_module_ast env kind m cst = match m with
| {CAst.loc;v=CMident qid} ->
- let (mp,kind) = lookup_module_or_modtype kind CAst.(make ?loc qid) in
+ let (mp,kind) = lookup_module_or_modtype kind qid in
(MEident mp, kind, cst)
| {CAst.loc;v=CMapply (me1,me2)} ->
let me1',kind1, cst = interp_module_ast env kind me1 cst in
diff --git a/interp/modintern.mli b/interp/modintern.mli
index ef37aead..529c438c 100644
--- a/interp/modintern.mli
+++ b/interp/modintern.mli
@@ -11,7 +11,6 @@
open Environ
open Entries
open Constrexpr
-open Misctypes
(** Module internalization errors *)
@@ -30,4 +29,4 @@ exception ModuleInternalizationError of module_internalization_error
isn't ModAny. *)
val interp_module_ast :
- env -> module_kind -> module_ast -> module_struct_entry * module_kind * Univ.ContextSet.t
+ env -> Declaremods.module_kind -> module_ast -> module_struct_entry * Declaremods.module_kind * Univ.ContextSet.t
diff --git a/interp/notation.ml b/interp/notation.ml
index bb58f00c..e2751865 100644
--- a/interp/notation.ml
+++ b/interp/notation.ml
@@ -20,7 +20,6 @@ open Constrexpr
open Notation_term
open Glob_term
open Glob_ops
-open Ppextend
open Context.Named.Declaration
(*i*)
@@ -40,6 +39,30 @@ open Context.Named.Declaration
expression, set this scope to be the current scope
*)
+let notation_entry_eq s1 s2 = match (s1,s2) with
+| InConstrEntry, InConstrEntry -> true
+| InCustomEntry s1, InCustomEntry s2 -> String.equal s1 s2
+| (InConstrEntry | InCustomEntry _), _ -> false
+
+let notation_entry_level_eq s1 s2 = match (s1,s2) with
+| InConstrEntrySomeLevel, InConstrEntrySomeLevel -> true
+| InCustomEntryLevel (s1,n1), InCustomEntryLevel (s2,n2) -> String.equal s1 s2 && n1 = n2
+| (InConstrEntrySomeLevel | InCustomEntryLevel _), _ -> false
+
+let notation_eq (from1,ntn1) (from2,ntn2) =
+ notation_entry_level_eq from1 from2 && String.equal ntn1 ntn2
+
+let pr_notation (from,ntn) = qstring ntn ++ match from with InConstrEntrySomeLevel -> mt () | InCustomEntryLevel (s,n) -> str " in custom " ++ str s
+
+module NotationOrd =
+ struct
+ type t = notation
+ let compare = Pervasives.compare
+ end
+
+module NotationSet = Set.Make(NotationOrd)
+module NotationMap = CMap.Make(NotationOrd)
+
(**********************************************************************)
(* Scope of symbols *)
@@ -52,13 +75,10 @@ type notation_data = {
}
type scope = {
- notations: notation_data String.Map.t;
+ notations: notation_data NotationMap.t;
delimiters: delimiters option
}
-(* Uninterpreted notation map: notation -> level * DirPath.t *)
-let notation_level_map = ref String.Map.empty
-
(* Scopes table: scope_name -> symbol_interpretation *)
let scope_map = ref String.Map.empty
@@ -66,7 +86,7 @@ let scope_map = ref String.Map.empty
let delimiters_map = ref String.Map.empty
let empty_scope = {
- notations = String.Map.empty;
+ notations = NotationMap.empty;
delimiters = None
}
@@ -78,41 +98,6 @@ let init_scope_map () =
(**********************************************************************)
(* Operations on scopes *)
-let parenRelation_eq t1 t2 = match t1, t2 with
-| L, L | E, E | Any, Any -> true
-| Prec l1, Prec l2 -> Int.equal l1 l2
-| _ -> false
-
-open Extend
-
-let production_level_eq l1 l2 = true (* (l1 = l2) *)
-
-let production_position_eq pp1 pp2 = true (* pp1 = pp2 *) (* match pp1, pp2 with
-| NextLevel, NextLevel -> true
-| NumLevel n1, NumLevel n2 -> Int.equal n1 n2
-| (NextLevel | NumLevel _), _ -> false *)
-
-let constr_entry_key_eq eq v1 v2 = match v1, v2 with
-| ETName, ETName -> true
-| ETReference, ETReference -> true
-| ETBigint, ETBigint -> true
-| ETBinder b1, ETBinder b2 -> b1 == b2
-| ETConstr lev1, ETConstr lev2 -> eq lev1 lev2
-| ETConstrAsBinder (bk1,lev1), ETConstrAsBinder (bk2,lev2) -> eq lev1 lev2 && bk1 = bk2
-| ETPattern (b1,n1), ETPattern (b2,n2) -> b1 = b2 && Option.equal Int.equal n1 n2
-| ETOther (s1,s1'), ETOther (s2,s2') -> String.equal s1 s2 && String.equal s1' s2'
-| (ETName | ETReference | ETBigint | ETBinder _ | ETConstr _ | ETPattern _ | ETOther _ | ETConstrAsBinder _), _ -> false
-
-let level_eq_gen strict (l1, t1, u1) (l2, t2, u2) =
- let tolerability_eq (i1, r1) (i2, r2) = Int.equal i1 i2 && parenRelation_eq r1 r2 in
- let prod_eq (l1,pp1) (l2,pp2) =
- if strict then production_level_eq l1 l2 && production_position_eq pp1 pp2
- else production_level_eq l1 l2 in
- Int.equal l1 l2 && List.equal tolerability_eq t1 t2
- && List.equal (constr_entry_key_eq prod_eq) u1 u2
-
-let level_eq = level_eq_gen false
-
let declare_scope scope =
try let _ = String.Map.find scope !scope_map in ()
with Not_found ->
@@ -143,12 +128,12 @@ let normalize_scope sc =
(**********************************************************************)
(* The global stack of scopes *)
-type scope_elem = Scope of scope_name | SingleNotation of string
+type scope_elem = Scope of scope_name | SingleNotation of notation
type scopes = scope_elem list
let scope_eq s1 s2 = match s1, s2 with
-| Scope s1, Scope s2
-| SingleNotation s1, SingleNotation s2 -> String.equal s1 s2
+| Scope s1, Scope s2 -> String.equal s1 s2
+| SingleNotation s1, SingleNotation s2 -> notation_eq s1 s2
| Scope _, SingleNotation _
| SingleNotation _, Scope _ -> false
@@ -200,8 +185,6 @@ let push_scope sc scopes = Scope sc :: scopes
let push_scopes = List.fold_right push_scope
-type local_scopes = tmp_scope_name option * scope_name list
-
let make_current_scopes (tmp_scope,scopes) =
Option.fold_right push_scope tmp_scope (push_scopes scopes !scope_stack)
@@ -258,7 +241,7 @@ type interp_rule =
according to the key of the pattern (adapted from Chet Murthy by HH) *)
type key =
- | RefKey of global_reference
+ | RefKey of GlobRef.t
| Oth
let key_compare k1 k2 = match k1, k2 with
@@ -283,16 +266,14 @@ let keymap_find key map =
(* Scopes table : interpretation -> scope_name *)
let notations_key_table = ref (KeyMap.empty : notation_rule list KeyMap.t)
-let prim_token_key_table = ref (KeyMap.empty : (string * (any_glob_constr -> prim_token option) * bool) KeyMap.t)
-
let glob_prim_constr_key c = match DAst.get c with
- | GRef (ref, _) -> RefKey (canonical_gr ref)
+ | GRef (ref, _) -> Some (canonical_gr ref)
| GApp (c, _) ->
begin match DAst.get c with
- | GRef (ref, _) -> RefKey (canonical_gr ref)
- | _ -> Oth
+ | GRef (ref, _) -> Some (canonical_gr ref)
+ | _ -> None
end
- | _ -> Oth
+ | _ -> None
let glob_constr_keys c = match DAst.get c with
| GApp (c, _) ->
@@ -320,77 +301,521 @@ let notation_constr_key = function (* Rem: NApp(NRef ref,[]) stands for @ref *)
(* Interpreting numbers (not in summary because functional objects) *)
type required_module = full_path * string list
+type rawnum = Constrexpr.raw_natural_number * Constrexpr.sign
-type 'a prim_token_interpreter =
- ?loc:Loc.t -> 'a -> glob_constr
+type prim_token_uid = string
-type cases_pattern_status = bool (* true = use prim token in patterns *)
+type 'a prim_token_interpreter = ?loc:Loc.t -> 'a -> glob_constr
+type 'a prim_token_uninterpreter = any_glob_constr -> 'a option
-type 'a prim_token_uninterpreter =
- glob_constr list * (any_glob_constr -> 'a option) * cases_pattern_status
+type 'a prim_token_interpretation =
+ 'a prim_token_interpreter * 'a prim_token_uninterpreter
-type internal_prim_token_interpreter =
- ?loc:Loc.t -> prim_token -> required_module * (unit -> glob_constr)
+module InnerPrimToken = struct
-let prim_token_interpreter_tab =
- (Hashtbl.create 7 : (scope_name, internal_prim_token_interpreter) Hashtbl.t)
+ type interpreter =
+ | RawNumInterp of (?loc:Loc.t -> rawnum -> glob_constr)
+ | BigNumInterp of (?loc:Loc.t -> Bigint.bigint -> glob_constr)
+ | StringInterp of (?loc:Loc.t -> string -> glob_constr)
-let add_prim_token_interpreter sc interp =
- try
- let cont = Hashtbl.find prim_token_interpreter_tab sc in
- Hashtbl.replace prim_token_interpreter_tab sc (interp cont)
- with Not_found ->
- let cont = (fun ?loc _p -> raise Not_found) in
- Hashtbl.add prim_token_interpreter_tab sc (interp cont)
+ let interp_eq f f' = match f,f' with
+ | RawNumInterp f, RawNumInterp f' -> f == f'
+ | BigNumInterp f, BigNumInterp f' -> f == f'
+ | StringInterp f, StringInterp f' -> f == f'
+ | _ -> false
-let declare_prim_token_interpreter sc interp (patl,uninterp,b) =
- declare_scope sc;
- add_prim_token_interpreter sc interp;
- List.iter (fun pat ->
- prim_token_key_table := KeyMap.add
- (glob_prim_constr_key pat) (sc,uninterp,b) !prim_token_key_table)
- patl
+ let ofNumeral n s =
+ if s then Bigint.of_string n else Bigint.neg (Bigint.of_string n)
+
+ let do_interp ?loc interp primtok =
+ match primtok, interp with
+ | Numeral (n,s), RawNumInterp interp -> interp ?loc (n,s)
+ | Numeral (n,s), BigNumInterp interp -> interp ?loc (ofNumeral n s)
+ | String s, StringInterp interp -> interp ?loc s
+ | _ -> raise Not_found
+
+ type uninterpreter =
+ | RawNumUninterp of (any_glob_constr -> rawnum option)
+ | BigNumUninterp of (any_glob_constr -> Bigint.bigint option)
+ | StringUninterp of (any_glob_constr -> string option)
+
+ let uninterp_eq f f' = match f,f' with
+ | RawNumUninterp f, RawNumUninterp f' -> f == f'
+ | BigNumUninterp f, BigNumUninterp f' -> f == f'
+ | StringUninterp f, StringUninterp f' -> f == f'
+ | _ -> false
+
+ let mkNumeral n =
+ if Bigint.is_pos_or_zero n then Numeral (Bigint.to_string n, true)
+ else Numeral (Bigint.to_string (Bigint.neg n), false)
-let mkNumeral n =
- if Bigint.is_pos_or_zero n then Numeral (Bigint.to_string n, true)
- else Numeral (Bigint.to_string (Bigint.neg n), false)
+ let mkString = function
+ | None -> None
+ | Some s -> if Unicode.is_utf8 s then Some (String s) else None
-let ofNumeral n s =
+ let do_uninterp uninterp g = match uninterp with
+ | RawNumUninterp u -> Option.map (fun (n,s) -> Numeral (n,s)) (u g)
+ | BigNumUninterp u -> Option.map mkNumeral (u g)
+ | StringUninterp u -> mkString (u g)
+
+end
+
+(* The following two tables of (un)interpreters will *not* be
+ synchronized. But their indexes will be checked to be unique.
+ These tables contain primitive token interpreters which are
+ registered in plugins, such as string and ascii syntax. It is
+ essential that only plugins add to these tables, and that
+ vernacular commands do not. See
+ https://github.com/coq/coq/issues/8401 for details of what goes
+ wrong when vernacular commands add to these tables. *)
+let prim_token_interpreters =
+ (Hashtbl.create 7 : (prim_token_uid, InnerPrimToken.interpreter) Hashtbl.t)
+
+let prim_token_uninterpreters =
+ (Hashtbl.create 7 : (prim_token_uid, InnerPrimToken.uninterpreter) Hashtbl.t)
+
+(*******************************************************)
+(* Numeral notation interpretation *)
+type numeral_notation_error =
+ | UnexpectedTerm of Constr.t
+ | UnexpectedNonOptionTerm of Constr.t
+
+exception NumeralNotationError of Environ.env * Evd.evar_map * numeral_notation_error
+
+type numnot_option =
+ | Nop
+ | Warning of raw_natural_number
+ | Abstract of raw_natural_number
+
+type int_ty =
+ { uint : Names.inductive;
+ int : Names.inductive }
+
+type z_pos_ty =
+ { z_ty : Names.inductive;
+ pos_ty : Names.inductive }
+
+type target_kind =
+ | Int of int_ty (* Coq.Init.Decimal.int + uint *)
+ | UInt of Names.inductive (* Coq.Init.Decimal.uint *)
+ | Z of z_pos_ty (* Coq.Numbers.BinNums.Z and positive *)
+
+type option_kind = Option | Direct
+type conversion_kind = target_kind * option_kind
+
+type numeral_notation_obj =
+ { to_kind : conversion_kind;
+ to_ty : GlobRef.t;
+ of_kind : conversion_kind;
+ of_ty : GlobRef.t;
+ num_ty : Libnames.qualid; (* for warnings / error messages *)
+ warning : numnot_option }
+
+module Numeral = struct
+(** * Numeral notation *)
+
+(** Reduction
+
+ The constr [c] below isn't necessarily well-typed, since we
+ built it via an [mkApp] of a conversion function on a term
+ that starts with the right constructor but might be partially
+ applied.
+
+ At least [c] is known to be evar-free, since it comes from
+ our own ad-hoc [constr_of_glob] or from conversions such
+ as [coqint_of_rawnum].
+*)
+
+let eval_constr env sigma (c : Constr.t) =
+ let c = EConstr.of_constr c in
+ let sigma,t = Typing.type_of env sigma c in
+ let c' = Vnorm.cbv_vm env sigma c t in
+ EConstr.Unsafe.to_constr c'
+
+(* For testing with "compute" instead of "vm_compute" :
+let eval_constr env sigma (c : Constr.t) =
+ let c = EConstr.of_constr c in
+ let c' = Tacred.compute env sigma c in
+ EConstr.Unsafe.to_constr c'
+*)
+
+let eval_constr_app env sigma c1 c2 =
+ eval_constr env sigma (mkApp (c1,[| c2 |]))
+
+exception NotANumber
+
+let warn_large_num =
+ CWarnings.create ~name:"large-number" ~category:"numbers"
+ (fun ty ->
+ strbrk "Stack overflow or segmentation fault happens when " ++
+ strbrk "working with large numbers in " ++ pr_qualid ty ++
+ strbrk " (threshold may vary depending" ++
+ strbrk " on your system limits and on the command executed).")
+
+let warn_abstract_large_num =
+ CWarnings.create ~name:"abstract-large-number" ~category:"numbers"
+ (fun (ty,f) ->
+ strbrk "To avoid stack overflow, large numbers in " ++
+ pr_qualid ty ++ strbrk " are interpreted as applications of " ++
+ Nametab.pr_global_env (Termops.vars_of_env (Global.env ())) f ++ strbrk ".")
+
+(** Comparing two raw numbers (base 10, big-endian, non-negative).
+ A bit nasty, but not critical: only used to decide when a
+ number is considered as large (see warnings above). *)
+
+exception Comp of int
+
+let rec rawnum_compare s s' =
+ let l = String.length s and l' = String.length s' in
+ if l < l' then - rawnum_compare s' s
+ else
+ let d = l-l' in
+ try
+ for i = 0 to d-1 do if s.[i] != '0' then raise (Comp 1) done;
+ for i = d to l-1 do
+ let c = Pervasives.compare s.[i] s'.[i-d] in
+ if c != 0 then raise (Comp c)
+ done;
+ 0
+ with Comp c -> c
+
+(***********************************************************************)
+
+(** ** Conversion between Coq [Decimal.int] and internal raw string *)
+
+(** Decimal.Nil has index 1, then Decimal.D0 has index 2 .. Decimal.D9 is 11 *)
+
+let digit_of_char c =
+ assert ('0' <= c && c <= '9');
+ Char.code c - Char.code '0' + 2
+
+let char_of_digit n =
+ assert (2<=n && n<=11);
+ Char.chr (n-2 + Char.code '0')
+
+let coquint_of_rawnum uint str =
+ let nil = mkConstruct (uint,1) in
+ let rec do_chars s i acc =
+ if i < 0 then acc
+ else
+ let dg = mkConstruct (uint, digit_of_char s.[i]) in
+ do_chars s (i-1) (mkApp(dg,[|acc|]))
+ in
+ do_chars str (String.length str - 1) nil
+
+let coqint_of_rawnum inds (str,sign) =
+ let uint = coquint_of_rawnum inds.uint str in
+ mkApp (mkConstruct (inds.int, if sign then 1 else 2), [|uint|])
+
+let rawnum_of_coquint c =
+ let rec of_uint_loop c buf =
+ match Constr.kind c with
+ | Construct ((_,1), _) (* Nil *) -> ()
+ | App (c, [|a|]) ->
+ (match Constr.kind c with
+ | Construct ((_,n), _) (* D0 to D9 *) ->
+ let () = Buffer.add_char buf (char_of_digit n) in
+ of_uint_loop a buf
+ | _ -> raise NotANumber)
+ | _ -> raise NotANumber
+ in
+ let buf = Buffer.create 64 in
+ let () = of_uint_loop c buf in
+ if Int.equal (Buffer.length buf) 0 then
+ (* To avoid ambiguities between Nil and (D0 Nil), we choose
+ to not display Nil alone as "0" *)
+ raise NotANumber
+ else Buffer.contents buf
+
+let rawnum_of_coqint c =
+ match Constr.kind c with
+ | App (c,[|c'|]) ->
+ (match Constr.kind c with
+ | Construct ((_,1), _) (* Pos *) -> (rawnum_of_coquint c', true)
+ | Construct ((_,2), _) (* Neg *) -> (rawnum_of_coquint c', false)
+ | _ -> raise NotANumber)
+ | _ -> raise NotANumber
+
+
+(***********************************************************************)
+
+(** ** Conversion between Coq [Z] and internal bigint *)
+
+(** First, [positive] from/to bigint *)
+
+let rec pos_of_bigint posty n =
+ match Bigint.div2_with_rest n with
+ | (q, false) ->
+ let c = mkConstruct (posty, 2) in (* xO *)
+ mkApp (c, [| pos_of_bigint posty q |])
+ | (q, true) when not (Bigint.equal q Bigint.zero) ->
+ let c = mkConstruct (posty, 1) in (* xI *)
+ mkApp (c, [| pos_of_bigint posty q |])
+ | (q, true) ->
+ mkConstruct (posty, 3) (* xH *)
+
+let rec bigint_of_pos c = match Constr.kind c with
+ | Construct ((_, 3), _) -> (* xH *) Bigint.one
+ | App (c, [| d |]) ->
+ begin match Constr.kind c with
+ | Construct ((_, n), _) ->
+ begin match n with
+ | 1 -> (* xI *) Bigint.add_1 (Bigint.mult_2 (bigint_of_pos d))
+ | 2 -> (* xO *) Bigint.mult_2 (bigint_of_pos d)
+ | n -> assert false (* no other constructor of type positive *)
+ end
+ | x -> raise NotANumber
+ end
+ | x -> raise NotANumber
+
+(** Now, [Z] from/to bigint *)
+
+let z_of_bigint { z_ty; pos_ty } n =
+ if Bigint.equal n Bigint.zero then
+ mkConstruct (z_ty, 1) (* Z0 *)
+ else
+ let (s, n) =
+ if Bigint.is_pos_or_zero n then (2, n) (* Zpos *)
+ else (3, Bigint.neg n) (* Zneg *)
+ in
+ let c = mkConstruct (z_ty, s) in
+ mkApp (c, [| pos_of_bigint pos_ty n |])
+
+let bigint_of_z z = match Constr.kind z with
+ | Construct ((_, 1), _) -> (* Z0 *) Bigint.zero
+ | App (c, [| d |]) ->
+ begin match Constr.kind c with
+ | Construct ((_, n), _) ->
+ begin match n with
+ | 2 -> (* Zpos *) bigint_of_pos d
+ | 3 -> (* Zneg *) Bigint.neg (bigint_of_pos d)
+ | n -> assert false (* no other constructor of type Z *)
+ end
+ | _ -> raise NotANumber
+ end
+ | _ -> raise NotANumber
+
+(** The uninterp function below work at the level of [glob_constr]
+ which is too low for us here. So here's a crude conversion back
+ to [constr] for the subset that concerns us. *)
+
+let rec constr_of_glob env sigma g = match DAst.get g with
+ | Glob_term.GRef (ConstructRef c, _) ->
+ let sigma,c = Evd.fresh_constructor_instance env sigma c in
+ sigma,mkConstructU c
+ | Glob_term.GApp (gc, gcl) ->
+ let sigma,c = constr_of_glob env sigma gc in
+ let sigma,cl = List.fold_left_map (constr_of_glob env) sigma gcl in
+ sigma,mkApp (c, Array.of_list cl)
+ | _ ->
+ raise NotANumber
+
+let rec glob_of_constr ?loc env sigma c = match Constr.kind c with
+ | App (c, ca) ->
+ let c = glob_of_constr ?loc env sigma c in
+ let cel = List.map (glob_of_constr ?loc env sigma) (Array.to_list ca) in
+ DAst.make ?loc (Glob_term.GApp (c, cel))
+ | Construct (c, _) -> DAst.make ?loc (Glob_term.GRef (ConstructRef c, None))
+ | Const (c, _) -> DAst.make ?loc (Glob_term.GRef (ConstRef c, None))
+ | Ind (ind, _) -> DAst.make ?loc (Glob_term.GRef (IndRef ind, None))
+ | Var id -> DAst.make ?loc (Glob_term.GRef (VarRef id, None))
+ | _ -> Loc.raise ?loc (NumeralNotationError(env,sigma,UnexpectedTerm c))
+
+let no_such_number ?loc ty =
+ CErrors.user_err ?loc
+ (str "Cannot interpret this number as a value of type " ++
+ pr_qualid ty)
+
+let interp_option ty ?loc env sigma c =
+ match Constr.kind c with
+ | App (_Some, [| _; c |]) -> glob_of_constr ?loc env sigma c
+ | App (_None, [| _ |]) -> no_such_number ?loc ty
+ | x -> Loc.raise ?loc (NumeralNotationError(env,sigma,UnexpectedNonOptionTerm c))
+
+let uninterp_option c =
+ match Constr.kind c with
+ | App (_Some, [| _; x |]) -> x
+ | _ -> raise NotANumber
+
+let big2raw n =
+ if Bigint.is_pos_or_zero n then (Bigint.to_string n, true)
+ else (Bigint.to_string (Bigint.neg n), false)
+
+let raw2big (n,s) =
if s then Bigint.of_string n else Bigint.neg (Bigint.of_string n)
-let mkString = function
-| None -> None
-| Some s -> if Unicode.is_utf8 s then Some (String s) else None
+let interp o ?loc n =
+ begin match o.warning with
+ | Warning threshold when snd n && rawnum_compare (fst n) threshold >= 0 ->
+ warn_large_num o.num_ty
+ | _ -> ()
+ end;
+ let c = match fst o.to_kind with
+ | Int int_ty -> coqint_of_rawnum int_ty n
+ | UInt uint_ty when snd n -> coquint_of_rawnum uint_ty (fst n)
+ | UInt _ (* n <= 0 *) -> no_such_number ?loc o.num_ty
+ | Z z_pos_ty -> z_of_bigint z_pos_ty (raw2big n)
+ in
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ let sigma,to_ty = Evd.fresh_global env sigma o.to_ty in
+ let to_ty = EConstr.Unsafe.to_constr to_ty in
+ match o.warning, snd o.to_kind with
+ | Abstract threshold, Direct when rawnum_compare (fst n) threshold >= 0 ->
+ warn_abstract_large_num (o.num_ty,o.to_ty);
+ glob_of_constr ?loc env sigma (mkApp (to_ty,[|c|]))
+ | _ ->
+ let res = eval_constr_app env sigma to_ty c in
+ match snd o.to_kind with
+ | Direct -> glob_of_constr ?loc env sigma res
+ | Option -> interp_option o.num_ty ?loc env sigma res
+
+let uninterp o (Glob_term.AnyGlobConstr n) =
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ let sigma,of_ty = Evd.fresh_global env sigma o.of_ty in
+ let of_ty = EConstr.Unsafe.to_constr of_ty in
+ try
+ let sigma,n = constr_of_glob env sigma n in
+ let c = eval_constr_app env sigma of_ty n in
+ let c = if snd o.of_kind == Direct then c else uninterp_option c in
+ match fst o.of_kind with
+ | Int _ -> Some (rawnum_of_coqint c)
+ | UInt _ -> Some (rawnum_of_coquint c, true)
+ | Z _ -> Some (big2raw (bigint_of_z c))
+ with
+ | Type_errors.TypeError _ | Pretype_errors.PretypeError _ -> None (* cf. eval_constr_app *)
+ | NotANumber -> None (* all other functions except big2raw *)
+end
+
+(* A [prim_token_infos], which is synchronized with the document
+ state, either contains a unique id pointing to an unsynchronized
+ prim token function, or a numeral notation object describing how to
+ interpret and uninterpret. We provide [prim_token_infos] because
+ we expect plugins to provide their own interpretation functions,
+ rather than going through numeral notations, which are available as
+ a vernacular. *)
+
+type prim_token_interp_info =
+ Uid of prim_token_uid
+ | NumeralNotation of numeral_notation_obj
+
+type prim_token_infos = {
+ pt_local : bool; (** Is this interpretation local? *)
+ pt_scope : scope_name; (** Concerned scope *)
+ pt_interp_info : prim_token_interp_info; (** Unique id "pointing" to (un)interp functions, OR a numeral notation object describing (un)interp functions *)
+ pt_required : required_module; (** Module that should be loaded first *)
+ pt_refs : GlobRef.t list; (** Entry points during uninterpretation *)
+ pt_in_match : bool (** Is this prim token legal in match patterns ? *)
+}
-let delay dir int ?loc x = (dir, (fun () -> int ?loc x))
+(* Table from scope_name to backtrack-able informations about interpreters
+ (in particular interpreter unique id). *)
+let prim_token_interp_infos =
+ ref (String.Map.empty : (required_module * prim_token_interp_info) String.Map.t)
+
+(* Table from global_reference to backtrack-able informations about
+ prim_token uninterpretation (in particular uninterpreter unique id). *)
+let prim_token_uninterp_infos =
+ ref (Refmap.empty : (scope_name * prim_token_interp_info * bool) Refmap.t)
+
+let hashtbl_check_and_set allow_overwrite uid f h eq =
+ match Hashtbl.find h uid with
+ | exception Not_found -> Hashtbl.add h uid f
+ | _ when allow_overwrite -> Hashtbl.add h uid f
+ | g when eq f g -> ()
+ | _ ->
+ user_err ~hdr:"prim_token_interpreter"
+ (str "Unique identifier " ++ str uid ++
+ str " already used to register a numeral or string (un)interpreter.")
+
+let register_gen_interpretation allow_overwrite uid (interp, uninterp) =
+ hashtbl_check_and_set
+ allow_overwrite uid interp prim_token_interpreters InnerPrimToken.interp_eq;
+ hashtbl_check_and_set
+ allow_overwrite uid uninterp prim_token_uninterpreters InnerPrimToken.uninterp_eq
+
+let register_rawnumeral_interpretation ?(allow_overwrite=false) uid (interp, uninterp) =
+ register_gen_interpretation allow_overwrite uid
+ (InnerPrimToken.RawNumInterp interp, InnerPrimToken.RawNumUninterp uninterp)
+
+let register_bignumeral_interpretation ?(allow_overwrite=false) uid (interp, uninterp) =
+ register_gen_interpretation allow_overwrite uid
+ (InnerPrimToken.BigNumInterp interp, InnerPrimToken.BigNumUninterp uninterp)
+
+let register_string_interpretation ?(allow_overwrite=false) uid (interp, uninterp) =
+ register_gen_interpretation allow_overwrite uid
+ (InnerPrimToken.StringInterp interp, InnerPrimToken.StringUninterp uninterp)
+
+let cache_prim_token_interpretation (_,infos) =
+ let ptii = infos.pt_interp_info in
+ let sc = infos.pt_scope in
+ declare_scope sc;
+ prim_token_interp_infos :=
+ String.Map.add sc (infos.pt_required,ptii) !prim_token_interp_infos;
+ List.iter (fun r -> prim_token_uninterp_infos :=
+ Refmap.add r (sc,ptii,infos.pt_in_match)
+ !prim_token_uninterp_infos)
+ infos.pt_refs
+
+let subst_prim_token_interpretation (subs,infos) =
+ { infos with
+ pt_refs = List.map (subst_global_reference subs) infos.pt_refs }
+
+let classify_prim_token_interpretation infos =
+ if infos.pt_local then Dispose else Substitute infos
+
+let inPrimTokenInterp : prim_token_infos -> obj =
+ declare_object {(default_object "PRIM-TOKEN-INTERP") with
+ open_function = (fun i o -> if Int.equal i 1 then cache_prim_token_interpretation o);
+ cache_function = cache_prim_token_interpretation;
+ subst_function = subst_prim_token_interpretation;
+ classify_function = classify_prim_token_interpretation}
+
+let enable_prim_token_interpretation infos =
+ Lib.add_anonymous_leaf (inPrimTokenInterp infos)
+
+(** Compatibility.
+ Avoid the next two functions, they will now store unnecessary
+ objects in the library segment. Instead, combine
+ [register_*_interpretation] and [enable_prim_token_interpretation]
+ (the latter inside a [Mltop.declare_cache_obj]).
+*)
-type rawnum = Constrexpr.raw_natural_number * Constrexpr.sign
+let fresh_string_of =
+ let count = ref 0 in
+ fun root -> count := !count+1; (string_of_int !count)^"_"^root
+
+let declare_numeral_interpreter ?(local=false) sc dir interp (patl,uninterp,b) =
+ let uid = fresh_string_of sc in
+ register_bignumeral_interpretation uid (interp,uninterp);
+ enable_prim_token_interpretation
+ { pt_local = local;
+ pt_scope = sc;
+ pt_interp_info = Uid uid;
+ pt_required = dir;
+ pt_refs = List.map_filter glob_prim_constr_key patl;
+ pt_in_match = b }
+let declare_string_interpreter ?(local=false) sc dir interp (patl,uninterp,b) =
+ let uid = fresh_string_of sc in
+ register_string_interpretation uid (interp,uninterp);
+ enable_prim_token_interpretation
+ { pt_local = local;
+ pt_scope = sc;
+ pt_interp_info = Uid uid;
+ pt_required = dir;
+ pt_refs = List.map_filter glob_prim_constr_key patl;
+ pt_in_match = b }
-let declare_rawnumeral_interpreter sc dir interp (patl,uninterp,inpat) =
- declare_prim_token_interpreter sc
- (fun cont ?loc -> function Numeral (n,s) -> delay dir interp ?loc (n,s)
- | p -> cont ?loc p)
- (patl, (fun r -> match uninterp r with
- | None -> None
- | Some (n,s) -> Some (Numeral (n,s))), inpat)
-
-let declare_numeral_interpreter sc dir interp (patl,uninterp,inpat) =
- let interp' ?loc (n,s) = interp ?loc (ofNumeral n s) in
- declare_prim_token_interpreter sc
- (fun cont ?loc -> function Numeral (n,s) -> delay dir interp' ?loc (n,s)
- | p -> cont ?loc p)
- (patl, (fun r -> Option.map mkNumeral (uninterp r)), inpat)
-
-let declare_string_interpreter sc dir interp (patl,uninterp,inpat) =
- declare_prim_token_interpreter sc
- (fun cont ?loc -> function String s -> delay dir interp ?loc s | p -> cont ?loc p)
- (patl, (fun r -> mkString (uninterp r)), inpat)
let check_required_module ?loc sc (sp,d) =
try let _ = Nametab.global_of_path sp in ()
with Not_found ->
- user_err ?loc ~hdr:"prim_token_interpreter"
- (str "Cannot interpret in " ++ str sc ++ str " without requiring first module " ++ str (List.last d) ++ str ".")
+ match d with
+ | [] -> user_err ?loc ~hdr:"prim_token_interpreter"
+ (str "Cannot interpret in " ++ str sc ++ str " because " ++ pr_path sp ++ str " could not be found in the current environment.")
+ | _ -> user_err ?loc ~hdr:"prim_token_interpreter"
+ (str "Cannot interpret in " ++ str sc ++ str " without requiring first module " ++ str (List.last d) ++ str ".")
(* Look if some notation or numeral printer in [scope] can be used in
the scope stack [scopes], and if yes, using delimiters or not *)
@@ -418,7 +843,7 @@ let rec find_without_delimiters find (ntn_scope,ntn) = function
end
| SingleNotation ntn' :: scopes ->
begin match ntn_scope, ntn with
- | None, Some ntn when String.equal ntn ntn' ->
+ | None, Some ntn when notation_eq ntn ntn' ->
Some (None, None)
| _ ->
find_without_delimiters find (ntn_scope,ntn) scopes
@@ -427,24 +852,12 @@ let rec find_without_delimiters find (ntn_scope,ntn) = function
(* Can we switch to [scope]? Yes if it has defined delimiters *)
find_with_delimiters ntn_scope
-(* Uninterpreted notation levels *)
-
-let declare_notation_level ?(onlyprint=false) ntn level =
- if String.Map.mem ntn !notation_level_map then
- anomaly (str "Notation " ++ str ntn ++ str " is already assigned a level.");
- notation_level_map := String.Map.add ntn (level,onlyprint) !notation_level_map
-
-let level_of_notation ?(onlyprint=false) ntn =
- let (level,onlyprint') = String.Map.find ntn !notation_level_map in
- if onlyprint' && not onlyprint then raise Not_found;
- level
-
(* The mapping between notations and their interpretation *)
let warn_notation_overridden =
CWarnings.create ~name:"notation-overridden" ~category:"parsing"
(fun (ntn,which_scope) ->
- str "Notation" ++ spc () ++ str ntn ++ spc ()
+ str "Notation" ++ spc () ++ pr_notation ntn ++ spc ()
++ strbrk "was already used" ++ which_scope ++ str ".")
let declare_notation_interpretation ntn scopt pat df ~onlyprint =
@@ -452,7 +865,7 @@ let declare_notation_interpretation ntn scopt pat df ~onlyprint =
let sc = find_scope scope in
if not onlyprint then begin
let () =
- if String.Map.mem ntn sc.notations then
+ if NotationMap.mem ntn sc.notations then
let which_scope = match scopt with
| None -> mt ()
| Some _ -> spc () ++ strbrk "in scope" ++ spc () ++ str scope in
@@ -462,7 +875,7 @@ let declare_notation_interpretation ntn scopt pat df ~onlyprint =
not_interp = pat;
not_location = df;
} in
- let sc = { sc with notations = String.Map.add ntn notdata sc.notations } in
+ let sc = { sc with notations = NotationMap.add ntn notdata sc.notations } in
scope_map := String.Map.add scope sc !scope_map
end;
begin match scopt with
@@ -479,7 +892,7 @@ let rec find_interpretation ntn find = function
| Scope scope :: scopes ->
(try let (pat,df) = find scope in pat,(df,Some scope)
with Not_found -> find_interpretation ntn find scopes)
- | SingleNotation ntn'::scopes when String.equal ntn' ntn ->
+ | SingleNotation ntn'::scopes when notation_eq ntn' ntn ->
(try let (pat,df) = find default_scope in pat,(df,None)
with Not_found ->
(* e.g. because single notation only for constr, not cases_pattern *)
@@ -488,12 +901,12 @@ let rec find_interpretation ntn find = function
find_interpretation ntn find scopes
let find_notation ntn sc =
- let n = String.Map.find ntn (find_scope sc).notations in
+ let n = NotationMap.find ntn (find_scope sc).notations in
(n.not_interp, n.not_location)
let notation_of_prim_token = function
- | Numeral (n,true) -> n
- | Numeral (n,false) -> "- "^n
+ | Numeral (n,true) -> InConstrEntrySomeLevel, n
+ | Numeral (n,false) -> InConstrEntrySomeLevel, "- "^n
| String _ -> raise Not_found
let find_prim_token check_allowed ?loc p sc =
@@ -505,21 +918,25 @@ let find_prim_token check_allowed ?loc p sc =
pat, df
with Not_found ->
(* Try for a primitive numerical notation *)
- let (spdir,interp) = Hashtbl.find prim_token_interpreter_tab sc ?loc p in
+ let (spdir,info) = String.Map.find sc !prim_token_interp_infos in
check_required_module ?loc sc spdir;
- let pat = interp () in
+ let interp = match info with
+ | Uid uid -> Hashtbl.find prim_token_interpreters uid
+ | NumeralNotation o -> InnerPrimToken.RawNumInterp (Numeral.interp o)
+ in
+ let pat = InnerPrimToken.do_interp ?loc interp p in
check_allowed pat;
pat, ((dirpath (fst spdir),DirPath.empty),"")
let interp_prim_token_gen ?loc g p local_scopes =
let scopes = make_current_scopes local_scopes in
- let p_as_ntn = try notation_of_prim_token p with Not_found -> "" in
+ let p_as_ntn = try notation_of_prim_token p with Not_found -> InConstrEntrySomeLevel,"" in
try find_interpretation p_as_ntn (find_prim_token ?loc g p) scopes
with Not_found ->
user_err ?loc ~hdr:"interp_prim_token"
((match p with
| Numeral _ ->
- str "No interpretation for numeral " ++ str (notation_of_prim_token p)
+ str "No interpretation for numeral " ++ pr_notation (notation_of_prim_token p)
| String s -> str "No interpretation for string " ++ qs s) ++ str ".")
let interp_prim_token ?loc =
@@ -544,7 +961,7 @@ let interp_notation ?loc ntn local_scopes =
try find_interpretation ntn (find_notation ntn) scopes
with Not_found ->
user_err ?loc
- (str "Unknown interpretation for notation \"" ++ str ntn ++ str "\".")
+ (str "Unknown interpretation for notation " ++ pr_notation ntn ++ str ".")
let uninterp_notations c =
List.map_append (fun key -> keymap_find key !notations_key_table)
@@ -558,47 +975,161 @@ let uninterp_ind_pattern_notations ind =
let availability_of_notation (ntn_scope,ntn) scopes =
let f scope =
- String.Map.mem ntn (String.Map.find scope !scope_map).notations in
+ NotationMap.mem ntn (String.Map.find scope !scope_map).notations in
find_without_delimiters f (ntn_scope,Some ntn) (make_current_scopes scopes)
-let uninterp_prim_token c =
+(* We support coercions from a custom entry at some level to an entry
+ at some level (possibly the same), and from and to the constr entry. E.g.:
+
+ Notation "[ expr ]" := expr (expr custom group at level 1).
+ Notation "( x )" := x (in custom group at level 0, x at level 1).
+ Notation "{ x }" := x (in custom group at level 0, x constr).
+
+ Supporting any level is maybe overkill in that coercions are
+ commonly from the lowest level of the source entry to the highest
+ level of the target entry. *)
+
+type entry_coercion = notation list
+
+module EntryCoercionOrd =
+ struct
+ type t = notation_entry * notation_entry
+ let compare = Pervasives.compare
+ end
+
+module EntryCoercionMap = Map.Make(EntryCoercionOrd)
+
+let entry_coercion_map = ref EntryCoercionMap.empty
+
+let level_ord lev lev' =
+ match lev, lev' with
+ | None, _ -> true
+ | _, None -> true
+ | Some n, Some n' -> n <= n'
+
+let rec search nfrom nto = function
+ | [] -> raise Not_found
+ | ((pfrom,pto),coe)::l ->
+ if level_ord pfrom nfrom && level_ord nto pto then coe else search nfrom nto l
+
+let decompose_custom_entry = function
+ | InConstrEntrySomeLevel -> InConstrEntry, None
+ | InCustomEntryLevel (s,n) -> InCustomEntry s, Some n
+
+let availability_of_entry_coercion entry entry' =
+ let entry, lev = decompose_custom_entry entry in
+ let entry', lev' = decompose_custom_entry entry' in
+ if notation_entry_eq entry entry' && level_ord lev' lev then Some []
+ else
+ try Some (search lev lev' (EntryCoercionMap.find (entry,entry') !entry_coercion_map))
+ with Not_found -> None
+
+let better_path ((lev1,lev2),path) ((lev1',lev2'),path') =
+ (* better = shorter and lower source and higher target *)
+ level_ord lev1 lev1' && level_ord lev2' lev2 && List.length path <= List.length path'
+
+let shorter_path (_,path) (_,path') =
+ List.length path <= List.length path'
+
+let rec insert_coercion_path path = function
+ | [] -> [path]
+ | path'::paths as allpaths ->
+ (* If better or equal we keep the more recent one *)
+ if better_path path path' then path::paths
+ else if better_path path' path then allpaths
+ else if shorter_path path path' then path::allpaths
+ else path'::insert_coercion_path path paths
+
+let declare_entry_coercion (entry,_ as ntn) entry' =
+ let entry, lev = decompose_custom_entry entry in
+ let entry', lev' = decompose_custom_entry entry' in
+ (* Transitive closure *)
+ let toaddleft =
+ EntryCoercionMap.fold (fun (entry'',entry''') paths l ->
+ List.fold_right (fun ((lev'',lev'''),path) l ->
+ if notation_entry_eq entry entry''' && level_ord lev lev''' &&
+ not (notation_entry_eq entry' entry'')
+ then ((entry'',entry'),((lev'',lev'),path@[ntn]))::l else l) paths l)
+ !entry_coercion_map [] in
+ let toaddright =
+ EntryCoercionMap.fold (fun (entry'',entry''') paths l ->
+ List.fold_right (fun ((lev'',lev'''),path) l ->
+ if entry' = entry'' && level_ord lev' lev'' && entry <> entry'''
+ then ((entry,entry'''),((lev,lev'''),path@[ntn]))::l else l) paths l)
+ !entry_coercion_map [] in
+ entry_coercion_map :=
+ List.fold_right (fun (pair,path) ->
+ let olds = try EntryCoercionMap.find pair !entry_coercion_map with Not_found -> [] in
+ EntryCoercionMap.add pair (insert_coercion_path path olds))
+ (((entry,entry'),((lev,lev'),[ntn]))::toaddright@toaddleft)
+ !entry_coercion_map
+
+let entry_has_global_map = ref String.Map.empty
+
+let declare_custom_entry_has_global s n =
try
- let (sc,numpr,_) =
- KeyMap.find (glob_prim_constr_key c) !prim_token_key_table in
- match numpr (AnyGlobConstr c) with
- | None -> raise Notation_ops.No_match
- | Some n -> (sc,n)
- with Not_found -> raise Notation_ops.No_match
-
-let uninterp_prim_token_ind_pattern ind args =
- let ref = IndRef ind in
+ let p = String.Map.find s !entry_has_global_map in
+ user_err (str "Custom entry " ++ str s ++
+ str " has already a rule for global references at level " ++ int p ++ str ".")
+ with Not_found ->
+ entry_has_global_map := String.Map.add s n !entry_has_global_map
+
+let entry_has_global = function
+ | InConstrEntrySomeLevel -> true
+ | InCustomEntryLevel (s,n) ->
+ try String.Map.find s !entry_has_global_map <= n with Not_found -> false
+
+let entry_has_ident_map = ref String.Map.empty
+
+let declare_custom_entry_has_ident s n =
try
- let k = RefKey (canonical_gr ref) in
- let (sc,numpr,b) = KeyMap.find k !prim_token_key_table in
- if not b then raise Notation_ops.No_match;
- let args' = List.map
- (fun x -> snd (glob_constr_of_closed_cases_pattern x)) args in
- let ref = DAst.make @@ GRef (ref,None) in
- match numpr (AnyGlobConstr (DAst.make @@ GApp (ref,args'))) with
- | None -> raise Notation_ops.No_match
- | Some n -> (sc,n)
- with Not_found -> raise Notation_ops.No_match
+ let p = String.Map.find s !entry_has_ident_map in
+ user_err (str "Custom entry " ++ str s ++
+ str " has already a rule for global references at level " ++ int p ++ str ".")
+ with Not_found ->
+ entry_has_ident_map := String.Map.add s n !entry_has_ident_map
+
+let entry_has_ident = function
+ | InConstrEntrySomeLevel -> true
+ | InCustomEntryLevel (s,n) ->
+ try String.Map.find s !entry_has_ident_map <= n with Not_found -> false
+
+let uninterp_prim_token c =
+ match glob_prim_constr_key c with
+ | None -> raise Notation_ops.No_match
+ | Some r ->
+ try
+ let (sc,info,_) = Refmap.find r !prim_token_uninterp_infos in
+ let uninterp = match info with
+ | Uid uid -> Hashtbl.find prim_token_uninterpreters uid
+ | NumeralNotation o -> InnerPrimToken.RawNumUninterp (Numeral.uninterp o)
+ in
+ match InnerPrimToken.do_uninterp uninterp (AnyGlobConstr c) with
+ | None -> raise Notation_ops.No_match
+ | Some n -> (sc,n)
+ with Not_found -> raise Notation_ops.No_match
let uninterp_prim_token_cases_pattern c =
- try
- let k = cases_pattern_key c in
- let (sc,numpr,b) = KeyMap.find k !prim_token_key_table in
- if not b then raise Notation_ops.No_match;
- let na,c = glob_constr_of_closed_cases_pattern c in
- match numpr (AnyGlobConstr c) with
- | None -> raise Notation_ops.No_match
- | Some n -> (na,sc,n)
- with Not_found -> raise Notation_ops.No_match
+ match glob_constr_of_closed_cases_pattern c with
+ | exception Not_found -> raise Notation_ops.No_match
+ | na,c -> let (sc,n) = uninterp_prim_token c in (na,sc,n)
let availability_of_prim_token n printer_scope local_scopes =
let f scope =
- try ignore ((Hashtbl.find prim_token_interpreter_tab scope) n); true
- with Not_found -> false in
+ try
+ let uid = snd (String.Map.find scope !prim_token_interp_infos) in
+ let open InnerPrimToken in
+ match n, uid with
+ | Numeral _, NumeralNotation _ -> true
+ | _, NumeralNotation _ -> false
+ | _, Uid uid ->
+ let interp = Hashtbl.find prim_token_interpreters uid in
+ match n, interp with
+ | Numeral _, (RawNumInterp _ | BigNumInterp _) -> true
+ | String _, StringInterp _ -> true
+ | _ -> false
+ with Not_found -> false
+ in
let scopes = make_current_scopes local_scopes in
Option.map snd (find_without_delimiters f (Some printer_scope,None) scopes)
@@ -619,7 +1150,8 @@ let ntpe_eq t1 t2 = match t1, t2 with
| NtnTypeBinderList, NtnTypeBinderList -> true
| (NtnTypeConstr | NtnTypeBinder _ | NtnTypeConstrList | NtnTypeBinderList), _ -> false
-let var_attributes_eq (_, (sc1, tp1)) (_, (sc2, tp2)) =
+let var_attributes_eq (_, ((entry1, sc1), tp1)) (_, ((entry2, sc2), tp2)) =
+ notation_entry_level_eq entry1 entry2 &&
pair_eq (Option.equal String.equal) (List.equal String.equal) sc1 sc2 &&
ntpe_eq tp1 tp2
@@ -631,7 +1163,7 @@ let exists_notation_in_scope scopt ntn onlyprint r =
let scope = match scopt with Some s -> s | None -> default_scope in
try
let sc = String.Map.find scope !scope_map in
- let n = String.Map.find ntn sc.notations in
+ let n = NotationMap.find ntn sc.notations in
interpretation_eq n.not_interp r
with Not_found -> false
@@ -741,7 +1273,7 @@ let subst_arguments_scope (subst,(req,r,n,scl,cls)) =
match subst_scope_class subst cl with
| Some cl' as ocl' when cl' != cl -> ocl'
| _ -> ocl in
- let cls' = List.smartmap subst_cl cls in
+ let cls' = List.Smart.map subst_cl cls in
(ArgsScopeNoDischarge,r',n,scl,cls')
let discharge_arguments_scope (_,(req,r,n,l,_)) =
@@ -778,7 +1310,7 @@ let rebuild_arguments_scope sigma (req,r,n,l,_) =
(req,r,0,l1@l,cls1)
type arguments_scope_obj =
- arguments_scope_discharge_request * global_reference *
+ arguments_scope_discharge_request * GlobRef.t *
(* Used to communicate information from discharge to rebuild *)
(* set to 0 otherwise *) int *
scope_name option list * scope_class option list
@@ -847,10 +1379,10 @@ let rec string_of_symbol = function
let l = List.flatten (List.map string_of_symbol l) in "_"::l@".."::l@["_"]
| Break _ -> []
-let make_notation_key symbols =
- String.concat " " (List.flatten (List.map string_of_symbol symbols))
+let make_notation_key from symbols =
+ (from,String.concat " " (List.flatten (List.map string_of_symbol symbols)))
-let decompose_notation_key s =
+let decompose_notation_key (from,s) =
let len = String.length s in
let rec decomp_ntn dirs n =
if n>=len then List.rev dirs else
@@ -865,7 +1397,7 @@ let decompose_notation_key s =
| s -> Terminal (String.drop_simple_quotes s) in
decomp_ntn (tok::dirs) (pos+1)
in
- decomp_ntn [] 0
+ from, decomp_ntn [] 0
(************)
(* Printing *)
@@ -894,14 +1426,14 @@ let pr_notation_info prglob ntn c =
let pr_named_scope prglob scope sc =
(if String.equal scope default_scope then
- match String.Map.cardinal sc.notations with
+ match NotationMap.cardinal sc.notations with
| 0 -> str "No lonely notation"
| n -> str "Lonely notation" ++ (if Int.equal n 1 then mt() else str"s")
else
str "Scope " ++ str scope ++ fnl () ++ pr_delimiters_info sc.delimiters)
++ fnl ()
++ pr_scope_classes scope
- ++ String.Map.fold
+ ++ NotationMap.fold
(fun ntn { not_interp = (_, r); not_location = (_, df) } strm ->
pr_notation_info prglob df r ++ fnl () ++ strm)
sc.notations (mt ())
@@ -916,11 +1448,11 @@ let pr_scopes prglob =
let rec find_default ntn = function
| [] -> None
| Scope scope :: scopes ->
- if String.Map.mem ntn (find_scope scope).notations then
+ if NotationMap.mem ntn (find_scope scope).notations then
Some scope
else find_default ntn scopes
| SingleNotation ntn' :: scopes ->
- if String.equal ntn ntn' then Some default_scope
+ if notation_eq ntn ntn' then Some default_scope
else find_default ntn scopes
let factorize_entries = function
@@ -929,7 +1461,7 @@ let factorize_entries = function
let (ntn,l_of_ntn,rest) =
List.fold_left
(fun (a',l,rest) (a,c) ->
- if String.equal a a' then (a',c::l,rest) else (a,[c],(a',l)::rest))
+ if notation_eq a a' then (a',c::l,rest) else (a,[c],(a',l)::rest))
(ntn,[c],[]) l in
(ntn,l_of_ntn)::rest
@@ -984,15 +1516,15 @@ let possible_notations ntn =
(* Only "_ U _" format *)
[ntn]
else
- let ntn' = make_notation_key (raw_analyze_notation_tokens toks) in
+ let _,ntn' = make_notation_key None (raw_analyze_notation_tokens toks) in
if String.equal ntn ntn' then (* Only symbols *) [ntn] else [ntn;ntn']
let browse_notation strict ntn map =
let ntns = possible_notations ntn in
- let find ntn' ntn =
+ let find (from,ntn' as fullntn') ntn =
if String.contains ntn ' ' then String.equal ntn ntn'
else
- let toks = decompose_notation_key ntn' in
+ let _,toks = decompose_notation_key fullntn' in
let get_terminals = function Terminal ntn -> Some ntn | _ -> None in
let trms = List.map_filter get_terminals toks in
if strict then String.List.equal [ntn] trms
@@ -1001,10 +1533,10 @@ let browse_notation strict ntn map =
let l =
String.Map.fold
(fun scope_name sc ->
- String.Map.fold (fun ntn { not_interp = (_, r); not_location = df } l ->
+ NotationMap.fold (fun ntn { not_interp = (_, r); not_location = df } l ->
if List.exists (find ntn) ntns then (ntn,(scope_name,r,df))::l else l) sc.notations)
map [] in
- List.sort (fun x y -> String.compare (fst x) (fst y)) l
+ List.sort (fun x y -> String.compare (snd (fst x)) (snd (fst y))) l
let global_reference_of_notation test (ntn,(sc,c,_)) =
match c with
@@ -1065,9 +1597,9 @@ let locate_notation prglob ntn scope =
let collect_notation_in_scope scope sc known =
assert (not (String.equal scope default_scope));
- String.Map.fold
+ NotationMap.fold
(fun ntn { not_interp = (_, r); not_location = (_, df) } (l,known as acc) ->
- if String.List.mem ntn known then acc else ((df,r)::l,ntn::known))
+ if List.mem_f notation_eq ntn known then acc else ((df,r)::l,ntn::known))
sc.notations ([],known)
let collect_notations stack =
@@ -1080,10 +1612,10 @@ let collect_notations stack =
collect_notation_in_scope scope (find_scope scope) knownntn in
((scope,l)::all,knownntn)
| SingleNotation ntn ->
- if String.List.mem ntn knownntn then (all,knownntn)
+ if List.mem_f notation_eq ntn knownntn then (all,knownntn)
else
let { not_interp = (_, r); not_location = (_, df) } =
- String.Map.find ntn (find_scope default_scope).notations in
+ NotationMap.find ntn (find_scope default_scope).notations in
let all' = match all with
| (s,lonelyntn)::rest when String.equal s default_scope ->
(s,(df,r)::lonelyntn)::rest
@@ -1113,64 +1645,35 @@ let pr_visibility prglob = function
| None -> pr_scope_stack prglob !scope_stack
(**********************************************************************)
-(* Mapping notations to concrete syntax *)
-
-type unparsing_rule = unparsing list * precedence
-type extra_unparsing_rules = (string * string) list
-(* Concrete syntax for symbolic-extension table *)
-let notation_rules =
- ref (String.Map.empty : (unparsing_rule * extra_unparsing_rules * notation_grammar) String.Map.t)
-
-let declare_notation_rule ntn ~extra unpl gram =
- notation_rules := String.Map.add ntn (unpl,extra,gram) !notation_rules
-
-let find_notation_printing_rule ntn =
- try pi1 (String.Map.find ntn !notation_rules)
- with Not_found -> anomaly (str "No printing rule found for " ++ str ntn ++ str ".")
-let find_notation_extra_printing_rules ntn =
- try pi2 (String.Map.find ntn !notation_rules)
- with Not_found -> []
-let find_notation_parsing_rules ntn =
- try pi3 (String.Map.find ntn !notation_rules)
- with Not_found -> anomaly (str "No parsing rule found for " ++ str ntn ++ str ".")
-
-let get_defined_notations () =
- String.Set.elements @@ String.Map.domain !notation_rules
-
-let add_notation_extra_printing_rule ntn k v =
- try
- notation_rules :=
- let p, pp, gr = String.Map.find ntn !notation_rules in
- String.Map.add ntn (p, (k,v) :: pp, gr) !notation_rules
- with Not_found ->
- user_err ~hdr:"add_notation_extra_printing_rule"
- (str "No such Notation.")
-
-(**********************************************************************)
(* Synchronisation with reset *)
let freeze _ =
- (!scope_map, !notation_level_map, !scope_stack, !arguments_scope,
- !delimiters_map, !notations_key_table, !notation_rules,
- !scope_class_map)
+ (!scope_map, !scope_stack, !arguments_scope,
+ !delimiters_map, !notations_key_table, !scope_class_map,
+ !prim_token_interp_infos, !prim_token_uninterp_infos,
+ !entry_coercion_map, !entry_has_global_map,
+ !entry_has_ident_map)
-let unfreeze (scm,nlm,scs,asc,dlm,fkm,pprules,clsc) =
+let unfreeze (scm,scs,asc,dlm,fkm,clsc,ptii,ptui,coe,globs,ids) =
scope_map := scm;
- notation_level_map := nlm;
scope_stack := scs;
delimiters_map := dlm;
arguments_scope := asc;
notations_key_table := fkm;
- notation_rules := pprules;
- scope_class_map := clsc
+ scope_class_map := clsc;
+ prim_token_interp_infos := ptii;
+ prim_token_uninterp_infos := ptui;
+ entry_coercion_map := coe;
+ entry_has_global_map := globs;
+ entry_has_ident_map := ids
let init () =
init_scope_map ();
- notation_level_map := String.Map.empty;
delimiters_map := String.Map.empty;
notations_key_table := KeyMap.empty;
- notation_rules := String.Map.empty;
- scope_class_map := initial_scope_class_map
+ scope_class_map := initial_scope_class_map;
+ prim_token_interp_infos := String.Map.empty;
+ prim_token_uninterp_infos := Refmap.empty
let _ =
Summary.declare_summary "symbols"
diff --git a/interp/notation.mli b/interp/notation.mli
index 18671feb..eb080f57 100644
--- a/interp/notation.mli
+++ b/interp/notation.mli
@@ -8,17 +8,29 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Bigint
open Names
open Libnames
-open Globnames
open Constrexpr
open Glob_term
open Notation_term
-open Ppextend
(** Notations *)
+val pr_notation : notation -> Pp.t
+(** Printing *)
+
+val notation_entry_eq : notation_entry -> notation_entry -> bool
+(** Equality on [notation_entry]. *)
+
+val notation_entry_level_eq : notation_entry_level -> notation_entry_level -> bool
+(** Equality on [notation_entry_level]. *)
+
+val notation_eq : notation -> notation -> bool
+(** Equality on [notation]. *)
+
+module NotationSet : Set.S with type elt = notation
+module NotationMap : CMap.ExtS with type key = notation and module Set := NotationSet
+
(** {6 Scopes } *)
(** A scope is a set of interpreters for symbols + optional
interpreter and printers for integers + optional delimiters *)
@@ -27,14 +39,10 @@ type delimiters = string
type scope
type scopes (** = [scope_name list] *)
-type local_scopes = tmp_scope_name option * scope_name list
-
val declare_scope : scope_name -> unit
val current_scopes : unit -> scopes
-val level_eq : level -> level -> bool
-
(** Check where a scope is opened or not in a scope list, or in
* the current opened scopes *)
val scope_is_open_in_scopes : scope_name -> scopes -> bool
@@ -66,33 +74,112 @@ val find_delimiters_scope : ?loc:Loc.t -> delimiters -> scope_name
type notation_location = (DirPath.t * DirPath.t) * string
type required_module = full_path * string list
-type cases_pattern_status = bool (** true = use prim token in patterns *)
+type rawnum = Constrexpr.raw_natural_number * Constrexpr.sign
-type 'a prim_token_interpreter =
- ?loc:Loc.t -> 'a -> glob_constr
+(** The unique id string below will be used to refer to a particular
+ registered interpreter/uninterpreter of numeral or string notation.
+ Using the same uid for different (un)interpreters will fail.
+ If at most one interpretation of prim token is used per scope,
+ then the scope name could be used as unique id. *)
-type 'a prim_token_uninterpreter =
- glob_constr list * (any_glob_constr -> 'a option) * cases_pattern_status
+type prim_token_uid = string
-type rawnum = Constrexpr.raw_natural_number * Constrexpr.sign
+type 'a prim_token_interpreter = ?loc:Loc.t -> 'a -> glob_constr
+type 'a prim_token_uninterpreter = any_glob_constr -> 'a option
+
+type 'a prim_token_interpretation =
+ 'a prim_token_interpreter * 'a prim_token_uninterpreter
+
+val register_rawnumeral_interpretation :
+ ?allow_overwrite:bool -> prim_token_uid -> rawnum prim_token_interpretation -> unit
+
+val register_bignumeral_interpretation :
+ ?allow_overwrite:bool -> prim_token_uid -> Bigint.bigint prim_token_interpretation -> unit
+
+val register_string_interpretation :
+ ?allow_overwrite:bool -> prim_token_uid -> string prim_token_interpretation -> unit
+
+(** * Numeral notation *)
-val declare_rawnumeral_interpreter : scope_name -> required_module ->
- rawnum prim_token_interpreter -> rawnum prim_token_uninterpreter -> unit
+type numeral_notation_error =
+ | UnexpectedTerm of Constr.t
+ | UnexpectedNonOptionTerm of Constr.t
-val declare_numeral_interpreter : scope_name -> required_module ->
- bigint prim_token_interpreter -> bigint prim_token_uninterpreter -> unit
+exception NumeralNotationError of Environ.env * Evd.evar_map * numeral_notation_error
-val declare_string_interpreter : scope_name -> required_module ->
- string prim_token_interpreter -> string prim_token_uninterpreter -> unit
+type numnot_option =
+ | Nop
+ | Warning of raw_natural_number
+ | Abstract of raw_natural_number
+
+type int_ty =
+ { uint : Names.inductive;
+ int : Names.inductive }
+
+type z_pos_ty =
+ { z_ty : Names.inductive;
+ pos_ty : Names.inductive }
+
+type target_kind =
+ | Int of int_ty (* Coq.Init.Decimal.int + uint *)
+ | UInt of Names.inductive (* Coq.Init.Decimal.uint *)
+ | Z of z_pos_ty (* Coq.Numbers.BinNums.Z and positive *)
+
+type option_kind = Option | Direct
+type conversion_kind = target_kind * option_kind
+
+type numeral_notation_obj =
+ { to_kind : conversion_kind;
+ to_ty : GlobRef.t;
+ of_kind : conversion_kind;
+ of_ty : GlobRef.t;
+ num_ty : Libnames.qualid; (* for warnings / error messages *)
+ warning : numnot_option }
+
+type prim_token_interp_info =
+ Uid of prim_token_uid
+ | NumeralNotation of numeral_notation_obj
+
+type prim_token_infos = {
+ pt_local : bool; (** Is this interpretation local? *)
+ pt_scope : scope_name; (** Concerned scope *)
+ pt_interp_info : prim_token_interp_info; (** Unique id "pointing" to (un)interp functions, OR a numeral notation object describing (un)interp functions *)
+ pt_required : required_module; (** Module that should be loaded first *)
+ pt_refs : GlobRef.t list; (** Entry points during uninterpretation *)
+ pt_in_match : bool (** Is this prim token legal in match patterns ? *)
+}
+
+(** Note: most of the time, the [pt_refs] field above will contain
+ inductive constructors (e.g. O and S for nat). But it could also be
+ injection functions such as IZR for reals. *)
+
+(** Activate a prim token interpretation whose unique id and functions
+ have already been registered. *)
+
+val enable_prim_token_interpretation : prim_token_infos -> unit
+
+(** Compatibility.
+ Avoid the next two functions, they will now store unnecessary
+ objects in the library segment. Instead, combine
+ [register_*_interpretation] and [enable_prim_token_interpretation]
+ (the latter inside a [Mltop.declare_cache_obj]).
+*)
+
+val declare_numeral_interpreter : ?local:bool -> scope_name -> required_module ->
+ Bigint.bigint prim_token_interpreter ->
+ glob_constr list * Bigint.bigint prim_token_uninterpreter * bool -> unit
+val declare_string_interpreter : ?local:bool -> scope_name -> required_module ->
+ string prim_token_interpreter ->
+ glob_constr list * string prim_token_uninterpreter * bool -> unit
(** Return the [term]/[cases_pattern] bound to a primitive token in a
given scope context*)
-val interp_prim_token : ?loc:Loc.t -> prim_token -> local_scopes ->
+val interp_prim_token : ?loc:Loc.t -> prim_token -> subscopes ->
glob_constr * (notation_location * scope_name option)
(* This function returns a glob_const representing a pattern *)
-val interp_prim_token_cases_pattern_expr : ?loc:Loc.t -> (global_reference -> unit) -> prim_token ->
- local_scopes -> glob_constr * (notation_location * scope_name option)
+val interp_prim_token_cases_pattern_expr : ?loc:Loc.t -> (GlobRef.t -> unit) -> prim_token ->
+ subscopes -> glob_constr * (notation_location * scope_name option)
(** Return the primitive token associated to a [term]/[cases_pattern];
raise [No_match] if no such token *)
@@ -101,11 +188,9 @@ val uninterp_prim_token :
'a glob_constr_g -> scope_name * prim_token
val uninterp_prim_token_cases_pattern :
'a cases_pattern_g -> Name.t * scope_name * prim_token
-val uninterp_prim_token_ind_pattern :
- inductive -> cases_pattern list -> scope_name * prim_token
val availability_of_prim_token :
- prim_token -> scope_name -> local_scopes -> delimiters option option
+ prim_token -> scope_name -> subscopes -> delimiters option option
(** {6 Declare and interpret back and forth a notation } *)
@@ -120,7 +205,7 @@ val declare_notation_interpretation : notation -> scope_name option ->
val declare_uninterpretation : interp_rule -> interpretation -> unit
(** Return the interpretation bound to a notation *)
-val interp_notation : ?loc:Loc.t -> notation -> local_scopes ->
+val interp_notation : ?loc:Loc.t -> notation -> subscopes ->
interpretation * (notation_location * scope_name option)
type notation_rule = interp_rule * interpretation * int option
@@ -133,18 +218,13 @@ val uninterp_ind_pattern_notations : inductive -> notation_rule list
(** Test if a notation is available in the scopes
context [scopes]; if available, the result is not None; the first
argument is itself not None if a delimiters is needed *)
-val availability_of_notation : scope_name option * notation -> local_scopes ->
+val availability_of_notation : scope_name option * notation -> subscopes ->
(scope_name option * delimiters option) option
-(** {6 Declare and test the level of a (possibly uninterpreted) notation } *)
-
-val declare_notation_level : ?onlyprint:bool -> notation -> level -> unit
-val level_of_notation : ?onlyprint:bool -> notation -> level (** raise [Not_found] if no level or not respecting onlyprint *)
-
(** {6 Miscellaneous} *)
-val interp_notation_as_global_reference : ?loc:Loc.t -> (global_reference -> bool) ->
- notation -> delimiters option -> global_reference
+val interp_notation_as_global_reference : ?loc:Loc.t -> (GlobRef.t -> bool) ->
+ notation_key -> delimiters option -> GlobRef.t
(** Checks for already existing notations *)
val exists_notation_in_scope : scope_name option -> notation ->
@@ -152,9 +232,9 @@ val exists_notation_in_scope : scope_name option -> notation ->
(** Declares and looks for scopes associated to arguments of a global ref *)
val declare_arguments_scope :
- bool (** true=local *) -> global_reference -> scope_name option list -> unit
+ bool (** true=local *) -> GlobRef.t -> scope_name option list -> unit
-val find_arguments_scope : global_reference -> scope_name option list
+val find_arguments_scope : GlobRef.t -> scope_name option list
type scope_class
@@ -165,7 +245,7 @@ val subst_scope_class :
Mod_subst.substitution -> scope_class -> scope_class option
val declare_scope_class : scope_name -> scope_class -> unit
-val declare_ref_arguments_scope : Evd.evar_map -> global_reference -> unit
+val declare_ref_arguments_scope : Evd.evar_map -> GlobRef.t -> unit
val compute_arguments_scope : Evd.evar_map -> EConstr.types -> scope_name option list
val compute_type_scope : Evd.evar_map -> EConstr.types -> scope_name option
@@ -186,8 +266,8 @@ type symbol =
val symbol_eq : symbol -> symbol -> bool
(** Make/decompose a notation of the form "_ U _" *)
-val make_notation_key : symbol list -> notation
-val decompose_notation_key : notation -> symbol list
+val make_notation_key : notation_entry_level -> symbol list -> notation
+val decompose_notation_key : notation -> notation_entry_level * symbol list
(** Decompose a notation of the form "a 'U' b" *)
val decompose_raw_notation : string -> symbol list
@@ -196,25 +276,20 @@ val decompose_raw_notation : string -> symbol list
val pr_scope_class : scope_class -> Pp.t
val pr_scope : (glob_constr -> Pp.t) -> scope_name -> Pp.t
val pr_scopes : (glob_constr -> Pp.t) -> Pp.t
-val locate_notation : (glob_constr -> Pp.t) -> notation ->
+val locate_notation : (glob_constr -> Pp.t) -> notation_key ->
scope_name option -> Pp.t
val pr_visibility: (glob_constr -> Pp.t) -> scope_name option -> Pp.t
-(** {6 Printing rules for notations} *)
+type entry_coercion = notation list
+val declare_entry_coercion : notation -> notation_entry_level -> unit
+val availability_of_entry_coercion : notation_entry_level -> notation_entry_level -> entry_coercion option
-(** Declare and look for the printing rule for symbolic notations *)
-type unparsing_rule = unparsing list * precedence
-type extra_unparsing_rules = (string * string) list
-val declare_notation_rule :
- notation -> extra:extra_unparsing_rules -> unparsing_rule -> notation_grammar -> unit
-val find_notation_printing_rule : notation -> unparsing_rule
-val find_notation_extra_printing_rules : notation -> extra_unparsing_rules
-val find_notation_parsing_rules : notation -> notation_grammar
-val add_notation_extra_printing_rule : notation -> string -> string -> unit
+val declare_custom_entry_has_global : string -> int -> unit
+val declare_custom_entry_has_ident : string -> int -> unit
-(** Returns notations with defined parsing/printing rules *)
-val get_defined_notations : unit -> notation list
+val entry_has_global : notation_entry_level -> bool
+val entry_has_ident : notation_entry_level -> bool
(** Rem: printing rules for primitive token are canonical *)
diff --git a/interp/notation_ops.ml b/interp/notation_ops.ml
index 55e532dc..7a525f84 100644
--- a/interp/notation_ops.ml
+++ b/interp/notation_ops.ml
@@ -13,9 +13,10 @@ open CErrors
open Util
open Names
open Nameops
+open Constr
open Globnames
open Decl_kinds
-open Misctypes
+open Namegen
open Glob_term
open Glob_ops
open Mod_subst
@@ -28,7 +29,7 @@ open Notation_term
let get_var_ndx id vs = try Some (List.index Id.equal id vs) with Not_found -> None
let rec eq_notation_constr (vars1,vars2 as vars) t1 t2 = match t1, t2 with
-| NRef gr1, NRef gr2 -> eq_gr gr1 gr2
+| NRef gr1, NRef gr2 -> GlobRef.equal gr1 gr2
| NVar id1, NVar id2 -> (
match (get_var_ndx id1 vars1,get_var_ndx id2 vars2) with
| Some n,Some m -> Int.equal n m
@@ -85,12 +86,12 @@ let rec eq_notation_constr (vars1,vars2 as vars) t1 t2 = match t1, t2 with
Array.equal (eq_notation_constr vars) us1 us2 &&
Array.equal (eq_notation_constr vars) rs1 rs2
| NSort s1, NSort s2 ->
- Miscops.glob_sort_eq s1 s2
+ glob_sort_eq s1 s2
| NCast (t1, c1), NCast (t2, c2) ->
(eq_notation_constr vars) t1 t2 && cast_type_eq (eq_notation_constr vars) c1 c2
| (NRef _ | NVar _ | NApp _ | NHole _ | NList _ | NLambda _ | NProd _
| NBinderList _ | NLetIn _ | NCases _ | NLetTuple _ | NIf _
- | NRec _ | NSort _ | NCast _), _ -> false
+ | NRec _ | NSort _ | NCast _ ), _ -> false
(**********************************************************************)
(* Re-interpret a notation as a glob_constr, taking care of binders *)
@@ -152,10 +153,12 @@ let protect g e na =
if disjpat <> None then user_err (Pp.str "Unsupported substitution of an arbitrary pattern.");
e',na
-let apply_cases_pattern ?loc ((ids,disjpat),id) c =
- let tm = DAst.make ?loc (GVar id) in
+let apply_cases_pattern_term ?loc (ids,disjpat) tm c =
let eqns = List.map (fun pat -> (CAst.make ?loc (ids,[pat],c))) disjpat in
- DAst.make ?loc @@ GCases (LetPatternStyle, None, [tm,(Anonymous,None)], eqns)
+ DAst.make ?loc @@ GCases (Constr.LetPatternStyle, None, [tm,(Anonymous,None)], eqns)
+
+let apply_cases_pattern ?loc (ids_disjpat,id) c =
+ apply_cases_pattern_term ?loc ids_disjpat (DAst.make ?loc (GVar id)) c
let glob_constr_of_notation_constr_with_binders ?loc g f e nc =
let lt x = DAst.make ?loc x in lt @@ match nc with
@@ -181,7 +184,7 @@ let glob_constr_of_notation_constr_with_binders ?loc g f e nc =
let e',disjpat,na = g e na in
(match disjpat with
| None -> GLetIn (na,f e b,Option.map (f e) t,f e' c)
- | Some disjpat -> DAst.get (apply_cases_pattern ?loc disjpat (f e' c)))
+ | Some (disjpat,_id) -> DAst.get (apply_cases_pattern_term ?loc disjpat (f e b) (f e' c)))
| NCases (sty,rtntypopt,tml,eqnl) ->
let e',tml' = List.fold_right (fun (tm,(na,t)) (e',tml') ->
let e',t' = match t with
@@ -213,7 +216,7 @@ let glob_constr_of_notation_constr_with_binders ?loc g f e nc =
(e,(na,Explicit,Option.map (f e) oc,f e b)))) e dll in
let e',idl = Array.fold_left_map (to_id (protect g)) e idl in
GRec (fk,idl,dll,Array.map (f e) tl,Array.map (f e') bl)
- | NCast (c,k) -> GCast (f e c,Miscops.map_cast_type (f e) k)
+ | NCast (c,k) -> GCast (f e c,map_cast_type (f e) k)
| NSort x -> GSort x
| NHole (x, naming, arg) -> GHole (x, naming, arg)
| NRef x -> GRef (x,None)
@@ -430,7 +433,7 @@ let notation_constr_and_vars_of_glob_constr recvars a =
user_err Pp.(str "Binders marked as implicit not allowed in notations.");
add_name found na; (na,Option.map aux oc,aux b))) dll in
NRec (fk,idl,dll,Array.map aux tl,Array.map aux bl)
- | GCast (c,k) -> NCast (aux c,Miscops.map_cast_type aux k)
+ | GCast (c,k) -> NCast (aux c,map_cast_type aux k)
| GSort s -> NSort s
| GHole (w,naming,arg) ->
if arg != None then has_ltac := true;
@@ -505,7 +508,9 @@ let notation_constr_of_glob_constr nenv a =
let notation_constr_of_constr avoiding t =
let t = EConstr.of_constr t in
- let t = Detyping.detype Detyping.Now false avoiding (Global.env()) Evd.empty t in
+ let env = Global.env () in
+ let evd = Evd.from_env env in
+ let t = Detyping.detype Detyping.Now false avoiding env evd t in
let nenv = {
ninterp_var_type = Id.Map.empty;
ninterp_rec_vars = Id.Map.empty;
@@ -517,7 +522,7 @@ let rec subst_pat subst pat =
| PatVar _ -> pat
| PatCstr (((kn,i),j),cpl,n) ->
let kn' = subst_mind subst kn
- and cpl' = List.smartmap (subst_pat subst) cpl in
+ and cpl' = List.Smart.map (subst_pat subst) cpl in
if kn' == kn && cpl' == cpl then pat else
DAst.make ?loc:pat.CAst.loc @@ PatCstr (((kn',i),j),cpl',n)
@@ -532,7 +537,7 @@ let rec subst_notation_constr subst bound raw =
| NApp (r,rl) ->
let r' = subst_notation_constr subst bound r
- and rl' = List.smartmap (subst_notation_constr subst bound) rl in
+ and rl' = List.Smart.map (subst_notation_constr subst bound) rl in
if r' == r && rl' == rl then raw else
NApp(r',rl')
@@ -562,14 +567,14 @@ let rec subst_notation_constr subst bound raw =
| NLetIn (n,r1,t,r2) ->
let r1' = subst_notation_constr subst bound r1 in
- let t' = Option.smartmap (subst_notation_constr subst bound) t in
+ let t' = Option.Smart.map (subst_notation_constr subst bound) t in
let r2' = subst_notation_constr subst bound r2 in
if r1' == r1 && t == t' && r2' == r2 then raw else
NLetIn (n,r1',t',r2')
| NCases (sty,rtntypopt,rl,branches) ->
- let rtntypopt' = Option.smartmap (subst_notation_constr subst bound) rtntypopt
- and rl' = List.smartmap
+ let rtntypopt' = Option.Smart.map (subst_notation_constr subst bound) rtntypopt
+ and rl' = List.Smart.map
(fun (a,(n,signopt) as x) ->
let a' = subst_notation_constr subst bound a in
let signopt' = Option.map (fun ((indkn,i),nal as z) ->
@@ -577,9 +582,9 @@ let rec subst_notation_constr subst bound raw =
if indkn == indkn' then z else ((indkn',i),nal)) signopt in
if a' == a && signopt' == signopt then x else (a',(n,signopt')))
rl
- and branches' = List.smartmap
+ and branches' = List.Smart.map
(fun (cpl,r as branch) ->
- let cpl' = List.smartmap (subst_pat subst) cpl
+ let cpl' = List.Smart.map (subst_pat subst) cpl
and r' = subst_notation_constr subst bound r in
if cpl' == cpl && r' == r then branch else
(cpl',r'))
@@ -590,14 +595,14 @@ let rec subst_notation_constr subst bound raw =
NCases (sty,rtntypopt',rl',branches')
| NLetTuple (nal,(na,po),b,c) ->
- let po' = Option.smartmap (subst_notation_constr subst bound) po
+ let po' = Option.Smart.map (subst_notation_constr subst bound) po
and b' = subst_notation_constr subst bound b
and c' = subst_notation_constr subst bound c in
if po' == po && b' == b && c' == c then raw else
NLetTuple (nal,(na,po'),b',c')
| NIf (c,(na,po),b1,b2) ->
- let po' = Option.smartmap (subst_notation_constr subst bound) po
+ let po' = Option.Smart.map (subst_notation_constr subst bound) po
and b1' = subst_notation_constr subst bound b1
and b2' = subst_notation_constr subst bound b2
and c' = subst_notation_constr subst bound c in
@@ -606,12 +611,12 @@ let rec subst_notation_constr subst bound raw =
| NRec (fk,idl,dll,tl,bl) ->
let dll' =
- Array.smartmap (List.smartmap (fun (na,oc,b as x) ->
- let oc' = Option.smartmap (subst_notation_constr subst bound) oc in
+ Array.Smart.map (List.Smart.map (fun (na,oc,b as x) ->
+ let oc' = Option.Smart.map (subst_notation_constr subst bound) oc in
let b' = subst_notation_constr subst bound b in
if oc' == oc && b' == b then x else (na,oc',b'))) dll in
- let tl' = Array.smartmap (subst_notation_constr subst bound) tl in
- let bl' = Array.smartmap (subst_notation_constr subst bound) bl in
+ let tl' = Array.Smart.map (subst_notation_constr subst bound) tl in
+ let bl' = Array.Smart.map (subst_notation_constr subst bound) bl in
if dll' == dll && tl' == tl && bl' == bl then raw else
NRec (fk,idl,dll',tl',bl')
@@ -624,13 +629,13 @@ let rec subst_notation_constr subst bound raw =
if nref == ref then knd else Evar_kinds.ImplicitArg (nref, i, b)
| _ -> knd
in
- let nsolve = Option.smartmap (Genintern.generic_substitute subst) solve in
+ let nsolve = Option.Smart.map (Genintern.generic_substitute subst) solve in
if nsolve == solve && nknd == knd then raw
else NHole (nknd, naming, nsolve)
| NCast (r1,k) ->
let r1' = subst_notation_constr subst bound r1 in
- let k' = Miscops.smartmap_cast_type (subst_notation_constr subst bound) k in
+ let k' = smartmap_cast_type (subst_notation_constr subst bound) k in
if r1' == r1 && k' == k then raw else NCast(r1',k')
let subst_interpretation subst (metas,pat) =
@@ -651,11 +656,11 @@ let abstract_return_type_context pi mklam tml rtno =
let abstract_return_type_context_glob_constr tml rtn =
abstract_return_type_context (fun {CAst.v=(_,nal)} -> nal)
(fun na c -> DAst.make @@
- GLambda(na,Explicit,DAst.make @@ GHole(Evar_kinds.InternalHole,Misctypes.IntroAnonymous,None),c)) tml rtn
+ GLambda(na,Explicit,DAst.make @@ GHole(Evar_kinds.InternalHole,IntroAnonymous,None),c)) tml rtn
let abstract_return_type_context_notation_constr tml rtn =
abstract_return_type_context snd
- (fun na c -> NLambda(na,NHole (Evar_kinds.InternalHole, Misctypes.IntroAnonymous, None),c)) tml rtn
+ (fun na c -> NLambda(na,NHole (Evar_kinds.InternalHole, IntroAnonymous, None),c)) tml rtn
let is_term_meta id metas =
try match Id.List.assoc id metas with _,(NtnTypeConstr | NtnTypeConstrList) -> true | _ -> false
@@ -672,7 +677,7 @@ let is_onlybinding_meta id metas =
let is_onlybinding_pattern_like_meta isvar id metas =
try match Id.List.assoc id metas with
| _,NtnTypeBinder (NtnBinderParsedAsConstr
- (Extend.AsIdentOrPattern | Extend.AsStrictPattern)) -> true
+ (AsIdentOrPattern | AsStrictPattern)) -> true
| _,NtnTypeBinder (NtnParsedAsPattern strict) -> not (strict && isvar)
| _ -> false
with Not_found -> false
@@ -887,7 +892,9 @@ let bind_term_as_binding_env alp (terms,termlists,binders,binderlists as sigma)
| GVar id' ->
(if not (Id.equal id id') then (fst alp,(id,id')::snd alp) else alp),
sigma
- | _ -> anomaly (str "A term which can be a binder has to be a variable.")
+ | t ->
+ (* The term is a non-variable pattern *)
+ raise No_match
with Not_found ->
(* The matching against a term allowing to find the instance has not been found yet *)
(* If it will be a different name, we shall unfortunately fail *)
@@ -995,9 +1002,9 @@ let remove_sigma x (terms,termlists,binders,binderlists) =
let remove_bindinglist_sigma x (terms,termlists,binders,binderlists) =
(terms,termlists,binders,Id.List.remove_assoc x binderlists)
-let add_ldots_var metas = (ldots_var,((None,[]),NtnTypeConstr))::metas
+let add_ldots_var metas = (ldots_var,((Constrexpr.InConstrEntrySomeLevel,(None,[])),NtnTypeConstr))::metas
-let add_meta_bindinglist x metas = (x,((None,[]),NtnTypeBinderList))::metas
+let add_meta_bindinglist x metas = (x,((Constrexpr.InConstrEntrySomeLevel,(None,[])),NtnTypeBinderList))::metas
(* This tells if letins in the middle of binders should be included in
the sequence of binders *)
@@ -1042,7 +1049,7 @@ let match_binderlist match_fun alp metas sigma rest x y iter termin revert =
let alp,sigma = bind_bindinglist_env alp sigma x bl in
match_fun alp metas sigma rest termin
-let add_meta_term x metas = (x,((None,[]),NtnTypeConstr))::metas
+let add_meta_term x metas = (x,((Constrexpr.InConstrEntrySomeLevel,(None,[])),NtnTypeConstr))::metas (* Should reuse the scope of the partner of x! *)
let match_termlist match_fun alp metas sigma rest x y iter termin revert =
let rec aux sigma acc rest =
@@ -1111,7 +1118,7 @@ let rec match_ inner u alp metas sigma a1 a2 =
(* Matching compositionally *)
| GVar id1, NVar id2 when alpha_var id1 id2 (fst alp) -> sigma
- | GRef (r1,_), NRef r2 when (eq_gr r1 r2) -> sigma
+ | GRef (r1,_), NRef r2 when (GlobRef.equal r1 r2) -> sigma
| GApp (f1,l1), NApp (f2,l2) ->
let n1 = List.length l1 and n2 = List.length l2 in
let f1,l1,f2,l2 =
@@ -1179,7 +1186,7 @@ let rec match_ inner u alp metas sigma a1 a2 =
| GCast(t1, c1), NCast(t2, c2) ->
match_cast (match_in u alp metas) (match_in u alp metas sigma t1 t2) c1 c2
| GSort (GType _), NSort (GType _) when not u -> sigma
- | GSort s1, NSort s2 when Miscops.glob_sort_eq s1 s2 -> sigma
+ | GSort s1, NSort s2 when glob_sort_eq s1 s2 -> sigma
| GPatVar _, NHole _ -> (*Don't hide Metas, they bind in ltac*) raise No_match
| a, NHole _ -> sigma
@@ -1193,7 +1200,7 @@ let rec match_ inner u alp metas sigma a1 a2 =
let avoid =
Id.Set.union (free_glob_vars a1) (* as in Namegen: *) (glob_visible_short_qualid a1) in
let id' = Namegen.next_ident_away id avoid in
- let t1 = DAst.make @@ GHole(Evar_kinds.BinderType (Name id'),Misctypes.IntroAnonymous,None) in
+ let t1 = DAst.make @@ GHole(Evar_kinds.BinderType (Name id'),IntroAnonymous,None) in
let sigma = match t2 with
| NHole _ -> sigma
| NVar id2 -> bind_term_env alp sigma id2 t1
@@ -1207,7 +1214,7 @@ let rec match_ inner u alp metas sigma a1 a2 =
| (GRef _ | GVar _ | GEvar _ | GPatVar _ | GApp _ | GLambda _ | GProd _
| GLetIn _ | GCases _ | GLetTuple _ | GIf _ | GRec _ | GSort _ | GHole _
- | GCast _), _ -> raise No_match
+ | GCast _ ), _ -> raise No_match
and match_in u = match_ true u
@@ -1223,7 +1230,7 @@ and match_extended_binders ?loc isprod u alp metas na1 na2 bk t sigma b1 b2 =
let store, get = set_temporary_memory () in
match na1, DAst.get b1, na2 with
(* Matching individual binders as part of a recursive pattern *)
- | Name p, GCases (LetPatternStyle,None,[(e,_)],(_::_ as eqns)), Name id
+ | Name p, GCases (Constr.LetPatternStyle,None,[(e,_)],(_::_ as eqns)), Name id
when is_gvar p e && is_bindinglist_meta id metas && List.length (store (Detyping.factorize_eqns eqns)) = 1 ->
(match get () with
| [{CAst.v=(ids,disj_of_patl,b1)}] ->
diff --git a/interp/notation_ops.mli b/interp/notation_ops.mli
index f038b5be..58fa221b 100644
--- a/interp/notation_ops.mli
+++ b/interp/notation_ops.mli
@@ -53,18 +53,18 @@ val glob_constr_of_notation_constr : ?loc:Loc.t -> notation_constr -> glob_const
exception No_match
val match_notation_constr : bool -> 'a glob_constr_g -> interpretation ->
- ('a glob_constr_g * subscopes) list * ('a glob_constr_g list * subscopes) list *
- ('a cases_pattern_disjunction_g * subscopes) list *
- ('a extended_glob_local_binder_g list * subscopes) list
+ ('a glob_constr_g * extended_subscopes) list * ('a glob_constr_g list * extended_subscopes) list *
+ ('a cases_pattern_disjunction_g * extended_subscopes) list *
+ ('a extended_glob_local_binder_g list * extended_subscopes) list
val match_notation_constr_cases_pattern :
'a cases_pattern_g -> interpretation ->
- (('a cases_pattern_g * subscopes) list * ('a cases_pattern_g list * subscopes) list) *
+ (('a cases_pattern_g * extended_subscopes) list * ('a cases_pattern_g list * extended_subscopes) list) *
(int * 'a cases_pattern_g list)
val match_notation_constr_ind_pattern :
inductive -> 'a cases_pattern_g list -> interpretation ->
- (('a cases_pattern_g * subscopes) list * ('a cases_pattern_g list * subscopes) list) *
+ (('a cases_pattern_g * extended_subscopes) list * ('a cases_pattern_g list * extended_subscopes) list) *
(int * 'a cases_pattern_g list)
(** {5 Matching a notation pattern against a [glob_constr]} *)
diff --git a/intf/notation_term.ml b/interp/notation_term.ml
index af9d6918..5fb0ca1b 100644
--- a/intf/notation_term.ml
+++ b/interp/notation_term.ml
@@ -9,8 +9,6 @@
(************************************************************************)
open Names
-open Globnames
-open Misctypes
open Glob_term
(** [notation_constr] *)
@@ -23,10 +21,10 @@ open Glob_term
type notation_constr =
(** Part common to [glob_constr] and [cases_pattern] *)
- | NRef of global_reference
+ | NRef of GlobRef.t
| NVar of Id.t
| NApp of notation_constr * notation_constr list
- | NHole of Evar_kinds.t * Misctypes.intro_pattern_naming_expr * Genarg.glob_generic_argument option
+ | NHole of Evar_kinds.t * Namegen.intro_pattern_naming_expr * Genarg.glob_generic_argument option
| NList of Id.t * Id.t * notation_constr * notation_constr * (* associativity: *) bool
(** Part only in [glob_constr] *)
| NLambda of Name.t * notation_constr * notation_constr
@@ -59,9 +57,16 @@ type tmp_scope_name = scope_name
type subscopes = tmp_scope_name option * scope_name list
+type extended_subscopes = Constrexpr.notation_entry_level * subscopes
+
(** Type of the meta-variables of an notation_constr: in a recursive pattern x..y,
x carries the sequence of objects bound to the list x..y *)
+type constr_as_binder_kind =
+ | AsIdent
+ | AsIdentOrPattern
+ | AsStrictPattern
+
type notation_binder_source =
(* This accepts only pattern *)
(* NtnParsedAsPattern true means only strict pattern (no single variable) at printing *)
@@ -69,7 +74,7 @@ type notation_binder_source =
(* This accepts only ident *)
| NtnParsedAsIdent
(* This accepts ident, or pattern, or both *)
- | NtnBinderParsedAsConstr of Extend.constr_as_binder_kind
+ | NtnBinderParsedAsConstr of constr_as_binder_kind
type notation_var_instance_type =
| NtnTypeConstr | NtnTypeBinder of notation_binder_source | NtnTypeConstrList | NtnTypeBinderList
@@ -82,7 +87,7 @@ type notation_var_internalization_type =
(** This characterizes to what a notation is interpreted to *)
type interpretation =
- (Id.t * (subscopes * notation_var_instance_type)) list *
+ (Id.t * (extended_subscopes * notation_var_instance_type)) list *
notation_constr
type reversibility_status = APrioriReversible | HasLtac | NonInjective of Id.t list
@@ -91,33 +96,3 @@ type notation_interp_env = {
ninterp_var_type : notation_var_internalization_type Id.Map.t;
ninterp_rec_vars : Id.t Id.Map.t;
}
-
-type grammar_constr_prod_item =
- | GramConstrTerminal of Tok.t
- | GramConstrNonTerminal of Extend.constr_prod_entry_key * Id.t option
- | GramConstrListMark of int * bool * int
- (* tells action rule to make a list of the n previous parsed items;
- concat with last parsed list when true; additionally release
- the p last items as if they were parsed autonomously *)
-
-(** Dealing with precedences *)
-
-type precedence = int
-type parenRelation = L | E | Any | Prec of precedence
-type tolerability = precedence * parenRelation
-
-type level = precedence * tolerability list * Extend.constr_entry_key list
-
-(** Grammar rules for a notation *)
-
-type one_notation_grammar = {
- notgram_level : level;
- notgram_assoc : Extend.gram_assoc option;
- notgram_notation : Constrexpr.notation;
- notgram_prods : grammar_constr_prod_item list list;
-}
-
-type notation_grammar = {
- notgram_onlyprinting : bool;
- notgram_rules : one_notation_grammar list
-}
diff --git a/interp/ppextend.ml b/interp/ppextend.ml
deleted file mode 100644
index c75d9e12..00000000
--- a/interp/ppextend.ml
+++ /dev/null
@@ -1,43 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Pp
-open Notation_term
-
-(*s Pretty-print. *)
-
-type ppbox =
- | PpHB of int
- | PpHOVB of int
- | PpHVB of int
- | PpVB of int
-
-type ppcut =
- | PpBrk of int * int
- | PpFnl
-
-let ppcmd_of_box = function
- | PpHB n -> h n
- | PpHOVB n -> hov n
- | PpHVB n -> hv n
- | PpVB n -> v n
-
-let ppcmd_of_cut = function
- | PpFnl -> fnl ()
- | PpBrk(n1,n2) -> brk(n1,n2)
-
-type unparsing =
- | UnpMetaVar of int * parenRelation
- | UnpBinderMetaVar of int * parenRelation
- | UnpListMetaVar of int * parenRelation * unparsing list
- | UnpBinderListMetaVar of int * bool * unparsing list
- | UnpTerminal of string
- | UnpBox of ppbox * unparsing Loc.located list
- | UnpCut of ppcut
diff --git a/pretyping/redops.ml b/interp/redops.ml
index 90c3bdfa..b9a74136 100644
--- a/pretyping/redops.ml
+++ b/interp/redops.ml
@@ -42,3 +42,23 @@ let make_red_flag l =
let all_flags =
{rBeta = true; rMatch = true; rFix = true; rCofix = true;
rZeta = true; rDelta = true; rConst = []}
+
+(** Mapping [red_expr_gen] *)
+
+let map_flags f flags =
+ { flags with rConst = List.map f flags.rConst }
+
+let map_occs f (occ,e) = (occ,f e)
+
+let map_red_expr_gen f g h = function
+ | Fold l -> Fold (List.map f l)
+ | Pattern occs_l -> Pattern (List.map (map_occs f) occs_l)
+ | Simpl (flags,occs_o) ->
+ Simpl (map_flags g flags, Option.map (map_occs (Util.map_union g h)) occs_o)
+ | Unfold occs_l -> Unfold (List.map (map_occs g) occs_l)
+ | Cbv flags -> Cbv (map_flags g flags)
+ | Lazy flags -> Lazy (map_flags g flags)
+ | CbvVm occs_o -> CbvVm (Option.map (map_occs (Util.map_union g h)) occs_o)
+ | CbvNative occs_o -> CbvNative (Option.map (map_occs (Util.map_union g h)) occs_o)
+ | Cbn flags -> Cbn (map_flags g flags)
+ | ExtraRedExpr _ | Red _ | Hnf as x -> x
diff --git a/pretyping/redops.mli b/interp/redops.mli
index 285931ec..7254f29b 100644
--- a/pretyping/redops.mli
+++ b/interp/redops.mli
@@ -13,3 +13,8 @@ open Genredexpr
val make_red_flag : 'a red_atom list -> 'a glob_red_flag
val all_flags : 'a glob_red_flag
+
+(** Mapping [red_expr_gen] *)
+
+val map_red_expr_gen : ('a -> 'd) -> ('b -> 'e) -> ('c -> 'f) ->
+ ('a,'b,'c) red_expr_gen -> ('d,'e,'f) red_expr_gen
diff --git a/interp/reserve.ml b/interp/reserve.ml
index 36005121..071248f0 100644
--- a/interp/reserve.ml
+++ b/interp/reserve.ml
@@ -22,7 +22,7 @@ open Notation_ops
open Globnames
type key =
- | RefKey of global_reference
+ | RefKey of GlobRef.t
| Oth
(** TODO: share code from Notation *)
@@ -112,7 +112,9 @@ let revert_reserved_type t =
let t = EConstr.Unsafe.to_constr t in
let reserved = KeyMap.find (constr_key t) !reserve_revtable in
let t = EConstr.of_constr t in
- let t = Detyping.detype Detyping.Now false Id.Set.empty (Global.env()) Evd.empty t in
+ let env = Global.env () in
+ let evd = Evd.from_env env in
+ let t = Detyping.detype Detyping.Now false Id.Set.empty env evd t in
(* pedrot: if [Notation_ops.match_notation_constr] may raise [Failure _]
then I've introduced a bug... *)
let filter _ pat =
diff --git a/interp/reserve.mli b/interp/reserve.mli
index daee5863..a10858e7 100644
--- a/interp/reserve.mli
+++ b/interp/reserve.mli
@@ -11,5 +11,5 @@
open Names
open Notation_term
-val declare_reserved_type : Misctypes.lident list -> notation_constr -> unit
+val declare_reserved_type : lident list -> notation_constr -> unit
val find_reserved_type : Id.t -> notation_constr
diff --git a/interp/smartlocate.ml b/interp/smartlocate.ml
index 1f4a93a6..91491bdf 100644
--- a/interp/smartlocate.ml
+++ b/interp/smartlocate.ml
@@ -18,7 +18,6 @@ open Pp
open CErrors
open Libnames
open Globnames
-open Misctypes
open Syntax_def
open Notation_term
@@ -42,36 +41,34 @@ let global_of_extended_global = function
| [],NApp (NRef ref,[]) -> ref
| _ -> raise Not_found
-let locate_global_with_alias ?(head=false) {CAst.loc; v=qid} =
+let locate_global_with_alias ?(head=false) qid =
let ref = Nametab.locate_extended qid in
try
if head then global_of_extended_global_head ref
else global_of_extended_global ref
with Not_found ->
- user_err ?loc (pr_qualid qid ++
+ user_err ?loc:qid.CAst.loc (pr_qualid qid ++
str " is bound to a notation that does not denote a reference.")
-let global_inductive_with_alias ({CAst.loc} as lr) =
- let qid = qualid_of_reference lr in
+let global_inductive_with_alias qid =
try match locate_global_with_alias qid with
| IndRef ind -> ind
| ref ->
- user_err ?loc ~hdr:"global_inductive"
- (pr_reference lr ++ spc () ++ str "is not an inductive type.")
+ user_err ?loc:qid.CAst.loc ~hdr:"global_inductive"
+ (pr_qualid qid ++ spc () ++ str "is not an inductive type.")
with Not_found -> Nametab.error_global_not_found qid
-let global_with_alias ?head r =
- let qid = qualid_of_reference r in
+let global_with_alias ?head qid =
try locate_global_with_alias ?head qid
with Not_found -> Nametab.error_global_not_found qid
-let smart_global ?head = CAst.with_loc_val (fun ?loc -> function
+let smart_global ?head = let open Constrexpr in CAst.with_loc_val (fun ?loc -> function
| AN r ->
global_with_alias ?head r
| ByNotation (ntn,sc) ->
Notation.interp_notation_as_global_reference ?loc (fun _ -> true) ntn sc)
-let smart_global_inductive = CAst.with_loc_val (fun ?loc -> function
+let smart_global_inductive = let open Constrexpr in CAst.with_loc_val (fun ?loc -> function
| AN r ->
global_inductive_with_alias r
| ByNotation (ntn,sc) ->
diff --git a/interp/smartlocate.mli b/interp/smartlocate.mli
index 7ff7e899..e41ef789 100644
--- a/interp/smartlocate.mli
+++ b/interp/smartlocate.mli
@@ -11,29 +11,28 @@
open Names
open Libnames
open Globnames
-open Misctypes
(** [locate_global_with_alias] locates global reference possibly following
a notation if this notation has a role of aliasing; raise [Not_found]
if not bound in the global env; raise a [UserError] if bound to a
syntactic def that does not denote a reference *)
-val locate_global_with_alias : ?head:bool -> qualid CAst.t -> global_reference
+val locate_global_with_alias : ?head:bool -> qualid -> GlobRef.t
(** Extract a global_reference from a reference that can be an "alias" *)
-val global_of_extended_global : extended_global_reference -> global_reference
+val global_of_extended_global : extended_global_reference -> GlobRef.t
(** Locate a reference taking into account possible "alias" notations.
May raise [Nametab.GlobalizationError _] for an unknown reference,
or a [UserError] if bound to a syntactic def that does not denote
a reference. *)
-val global_with_alias : ?head:bool -> reference -> global_reference
+val global_with_alias : ?head:bool -> qualid -> GlobRef.t
(** The same for inductive types *)
-val global_inductive_with_alias : reference -> inductive
+val global_inductive_with_alias : qualid -> inductive
(** Locate a reference taking into account notations and "aliases" *)
-val smart_global : ?head:bool -> reference or_by_notation -> global_reference
+val smart_global : ?head:bool -> qualid Constrexpr.or_by_notation -> GlobRef.t
(** The same for inductive types *)
-val smart_global_inductive : reference or_by_notation -> inductive
+val smart_global_inductive : qualid Constrexpr.or_by_notation -> inductive
diff --git a/interp/stdarg.ml b/interp/stdarg.ml
index e5ed58be..7b01b6dc 100644
--- a/interp/stdarg.ml
+++ b/interp/stdarg.ml
@@ -11,6 +11,8 @@
open Genarg
open Geninterp
+type 'a and_short_name = 'a * Names.lident option
+
let make0 ?dyn name =
let wit = Genarg.make0 name in
let () = register_val0 wit dyn in
@@ -34,9 +36,6 @@ let wit_pre_ident : string uniform_genarg_type =
let wit_int_or_var =
make0 ~dyn:(val_tag (topwit wit_int)) "int_or_var"
-let wit_intro_pattern =
- make0 "intropattern"
-
let wit_ident =
make0 "ident"
@@ -45,8 +44,6 @@ let wit_var =
let wit_ref = make0 "ref"
-let wit_quant_hyp = make0 "quant_hyp"
-
let wit_sort_family = make0 "sort_family"
let wit_constr =
@@ -56,12 +53,6 @@ let wit_uconstr = make0 "uconstr"
let wit_open_constr = make0 ~dyn:(val_tag (topwit wit_constr)) "open_constr"
-let wit_constr_with_bindings = make0 "constr_with_bindings"
-
-let wit_open_constr_with_bindings = make0 "open_constr_with_bindings"
-
-let wit_bindings = make0 "bindings"
-
let wit_red_expr = make0 "redexpr"
let wit_clause_dft_concl =
@@ -74,6 +65,4 @@ let wit_preident = wit_pre_ident
let wit_reference = wit_ref
let wit_global = wit_ref
let wit_clause = wit_clause_dft_concl
-let wit_quantified_hypothesis = wit_quant_hyp
-let wit_intropattern = wit_intro_pattern
let wit_redexpr = wit_red_expr
diff --git a/interp/stdarg.mli b/interp/stdarg.mli
index 53d1a522..5e5e43ed 100644
--- a/interp/stdarg.mli
+++ b/interp/stdarg.mli
@@ -14,13 +14,14 @@ open Loc
open Names
open EConstr
open Libnames
-open Globnames
open Genredexpr
open Pattern
open Constrexpr
-open Misctypes
-open Tactypes
open Genarg
+open Genintern
+open Locus
+
+type 'a and_short_name = 'a * lident option
val wit_unit : unit uniform_genarg_type
@@ -36,15 +37,11 @@ val wit_pre_ident : string uniform_genarg_type
val wit_int_or_var : (int or_var, int or_var, int) genarg_type
-val wit_intro_pattern : (constr_expr intro_pattern_expr CAst.t, glob_constr_and_expr intro_pattern_expr CAst.t, intro_pattern) genarg_type
-
val wit_ident : Id.t uniform_genarg_type
val wit_var : (lident, lident, Id.t) genarg_type
-val wit_ref : (reference, global_reference located or_var, global_reference) genarg_type
-
-val wit_quant_hyp : quantified_hypothesis uniform_genarg_type
+val wit_ref : (qualid, GlobRef.t located or_var, GlobRef.t) genarg_type
val wit_sort_family : (Sorts.family, unit, unit) genarg_type
@@ -55,23 +52,8 @@ val wit_uconstr : (constr_expr , glob_constr_and_expr, Ltac_pretype.closed_glob_
val wit_open_constr :
(constr_expr, glob_constr_and_expr, constr) genarg_type
-val wit_constr_with_bindings :
- (constr_expr with_bindings,
- glob_constr_and_expr with_bindings,
- constr with_bindings delayed_open) genarg_type
-
-val wit_open_constr_with_bindings :
- (constr_expr with_bindings,
- glob_constr_and_expr with_bindings,
- constr with_bindings delayed_open) genarg_type
-
-val wit_bindings :
- (constr_expr bindings,
- glob_constr_and_expr bindings,
- constr bindings delayed_open) genarg_type
-
val wit_red_expr :
- ((constr_expr,reference or_by_notation,constr_expr) red_expr_gen,
+ ((constr_expr,qualid or_by_notation,constr_expr) red_expr_gen,
(glob_constr_and_expr,evaluable_global_reference and_short_name or_var,glob_constr_pattern_and_expr) red_expr_gen,
(constr,evaluable_global_reference,constr_pattern) red_expr_gen) genarg_type
@@ -81,12 +63,10 @@ val wit_clause_dft_concl : (lident Locus.clause_expr, lident Locus.clause_expr,
val wit_integer : int uniform_genarg_type
val wit_preident : string uniform_genarg_type
-val wit_reference : (reference, global_reference located or_var, global_reference) genarg_type
-val wit_global : (reference, global_reference located or_var, global_reference) genarg_type
+val wit_reference : (qualid, GlobRef.t located or_var, GlobRef.t) genarg_type
+val wit_global : (qualid, GlobRef.t located or_var, GlobRef.t) genarg_type
val wit_clause : (lident Locus.clause_expr, lident Locus.clause_expr, Names.Id.t Locus.clause_expr) genarg_type
-val wit_quantified_hypothesis : quantified_hypothesis uniform_genarg_type
-val wit_intropattern : (constr_expr intro_pattern_expr CAst.t, glob_constr_and_expr intro_pattern_expr CAst.t, intro_pattern) genarg_type
val wit_redexpr :
- ((constr_expr,reference or_by_notation,constr_expr) red_expr_gen,
+ ((constr_expr,qualid or_by_notation,constr_expr) red_expr_gen,
(glob_constr_and_expr,evaluable_global_reference and_short_name or_var,glob_constr_pattern_and_expr) red_expr_gen,
(constr,evaluable_global_reference,constr_pattern) red_expr_gen) genarg_type
diff --git a/interp/syntax_def.ml b/interp/syntax_def.ml
index a4f20fd7..e3d490a1 100644
--- a/interp/syntax_def.ml
+++ b/interp/syntax_def.ml
@@ -77,8 +77,8 @@ type syndef_interpretation = (Id.t * subscopes) list * notation_constr
(* Coercions to the general format of notation that also supports
variables bound to list of expressions *)
-let in_pat (ids,ac) = (List.map (fun (id,sc) -> (id,(sc,NtnTypeConstr))) ids,ac)
-let out_pat (ids,ac) = (List.map (fun (id,(sc,typ)) -> (id,sc)) ids,ac)
+let in_pat (ids,ac) = (List.map (fun (id,sc) -> (id,((Constrexpr.InConstrEntrySomeLevel,sc),NtnTypeConstr))) ids,ac)
+let out_pat (ids,ac) = (List.map (fun (id,((_,sc),typ)) -> (id,sc)) ids,ac)
let declare_syntactic_definition local id onlyparse pat =
let _ = add_leaf id (in_syntax_constant (local,in_pat pat,onlyparse)) in ()
diff --git a/interp/topconstr.ml b/interp/topconstr.ml
deleted file mode 100644
index 7d2d75d9..00000000
--- a/interp/topconstr.ml
+++ /dev/null
@@ -1,23 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Constrexpr_ops
-
-let asymmetric_patterns = asymmetric_patterns
-let error_invalid_pattern_notation = error_invalid_pattern_notation
-let split_at_annot = split_at_annot
-let ntn_loc = ntn_loc
-let patntn_loc = patntn_loc
-let map_constr_expr_with_binders = map_constr_expr_with_binders
-let fold_constr_expr_with_binders = fold_constr_expr_with_binders
-let ids_of_cases_indtype = ids_of_cases_indtype
-let occur_var_constr_expr = occur_var_constr_expr
-let free_vars_of_constr_expr = free_vars_of_constr_expr
-let replace_vars_constr_expr = replace_vars_constr_expr
diff --git a/interp/topconstr.mli b/interp/topconstr.mli
deleted file mode 100644
index c8650201..00000000
--- a/interp/topconstr.mli
+++ /dev/null
@@ -1,53 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Names
-open Constrexpr
-
-(** Topconstr: This whole module is deprecated in favor of Constrexpr_ops *)
-val asymmetric_patterns : bool ref
-[@@ocaml.deprecated "use Constrexpr_ops.asymmetric_patterns"]
-
-(** Utilities on constr_expr *)
-val split_at_annot : local_binder_expr list -> Misctypes.lident option -> local_binder_expr list * local_binder_expr list
-[@@ocaml.deprecated "use Constrexpr_ops.split_at_annot"]
-
-val ntn_loc : ?loc:Loc.t -> constr_notation_substitution -> string -> (int * int) list
-[@@ocaml.deprecated "use Constrexpr_ops.ntn_loc"]
-val patntn_loc : ?loc:Loc.t -> cases_pattern_notation_substitution -> string -> (int * int) list
-[@@ocaml.deprecated "use Constrexpr_ops.patntn_loc"]
-
-(** For cases pattern parsing errors *)
-val error_invalid_pattern_notation : ?loc:Loc.t -> unit -> 'a
-[@@ocaml.deprecated "use Constrexpr_ops.error_invalid_pattern_notation"]
-
-(*************************************************************************)
-val replace_vars_constr_expr : Id.t Id.Map.t -> constr_expr -> constr_expr
-[@@ocaml.deprecated "use Constrexpr_ops.free_vars_of_constr_expr"]
-
-val free_vars_of_constr_expr : constr_expr -> Id.Set.t
-[@@ocaml.deprecated "use Constrexpr_ops.free_vars_of_constr_expr"]
-
-val occur_var_constr_expr : Id.t -> constr_expr -> bool
-[@@ocaml.deprecated "use Constrexpr_ops.occur_var_constr_expr"]
-
-(** Specific function for interning "in indtype" syntax of "match" *)
-val ids_of_cases_indtype : cases_pattern_expr -> Id.Set.t
-[@@ocaml.deprecated "use Constrexpr_ops.ids_of_cases_indtype"]
-
-(** Used in typeclasses *)
-val fold_constr_expr_with_binders : (Id.t -> 'a -> 'a) ->
- ('a -> 'b -> constr_expr -> 'b) -> 'a -> 'b -> constr_expr -> 'b
-[@@ocaml.deprecated "use Constrexpr_ops.fold_constr_expr_with_binders"]
-
-val map_constr_expr_with_binders :
- (Id.t -> 'a -> 'a) -> ('a -> constr_expr -> constr_expr) ->
- 'a -> constr_expr -> constr_expr
-[@@ocaml.deprecated "use Constrexpr_ops.map_constr_expr_with_binders"]
diff --git a/intf/intf.mllib b/intf/intf.mllib
deleted file mode 100644
index 2b8960d3..00000000
--- a/intf/intf.mllib
+++ /dev/null
@@ -1,11 +0,0 @@
-Constrexpr
-Evar_kinds
-Genredexpr
-Locus
-Extend
-Notation_term
-Decl_kinds
-Glob_term
-Misctypes
-Pattern
-Vernacexpr
diff --git a/intf/misctypes.ml b/intf/misctypes.ml
deleted file mode 100644
index 9eb6f62c..00000000
--- a/intf/misctypes.ml
+++ /dev/null
@@ -1,162 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Names
-
-(** Basic types used both in [constr_expr], [glob_constr], and [vernacexpr] *)
-
-(** Located identifiers and objects with syntax. *)
-
-type lident = Id.t CAst.t
-type lname = Name.t CAst.t
-type lstring = string CAst.t
-
-(** Cases pattern variables *)
-
-type patvar = Id.t
-
-(** Introduction patterns *)
-
-type 'constr intro_pattern_expr =
- | IntroForthcoming of bool
- | IntroNaming of intro_pattern_naming_expr
- | IntroAction of 'constr intro_pattern_action_expr
-and intro_pattern_naming_expr =
- | IntroIdentifier of Id.t
- | IntroFresh of Id.t
- | IntroAnonymous
-and 'constr intro_pattern_action_expr =
- | IntroWildcard
- | IntroOrAndPattern of 'constr or_and_intro_pattern_expr
- | IntroInjection of ('constr intro_pattern_expr) CAst.t list
- | IntroApplyOn of 'constr CAst.t * 'constr intro_pattern_expr CAst.t
- | IntroRewrite of bool
-and 'constr or_and_intro_pattern_expr =
- | IntroOrPattern of ('constr intro_pattern_expr) CAst.t list list
- | IntroAndPattern of ('constr intro_pattern_expr) CAst.t list
-
-(** Move destination for hypothesis *)
-
-type 'id move_location =
- | MoveAfter of 'id
- | MoveBefore of 'id
- | MoveFirst
- | MoveLast (** can be seen as "no move" when doing intro *)
-
-(** Sorts *)
-
-type 'a glob_sort_gen =
- | GProp (** representation of [Prop] literal *)
- | GSet (** representation of [Set] literal *)
- | GType of 'a (** representation of [Type] literal *)
-
-type 'a universe_kind =
- | UAnonymous
- | UUnknown
- | UNamed of 'a
-
-type level_info = Libnames.reference universe_kind
-type glob_level = level_info glob_sort_gen
-type glob_constraint = glob_level * Univ.constraint_type * glob_level
-
-type sort_info = (Libnames.reference * int) option list
-type glob_sort = sort_info glob_sort_gen
-
-(** A synonym of [Evar.t], also defined in Term *)
-
-type existential_key = Evar.t
-
-(** Case style, shared with Term *)
-
-type case_style = Constr.case_style =
- | LetStyle
- | IfStyle
- | LetPatternStyle
- | MatchStyle
- | RegularStyle (** infer printing form from number of constructor *)
-[@@ocaml.deprecated "Alias for Constr.case_style"]
-
-(** Casts *)
-
-type 'a cast_type =
- | CastConv of 'a
- | CastVM of 'a
- | CastCoerce (** Cast to a base type (eg, an underlying inductive type) *)
- | CastNative of 'a
-
-(** Bindings *)
-
-type quantified_hypothesis = AnonHyp of int | NamedHyp of Id.t
-
-type 'a explicit_bindings = (quantified_hypothesis * 'a) CAst.t list
-
-type 'a bindings =
- | ImplicitBindings of 'a list
- | ExplicitBindings of 'a explicit_bindings
- | NoBindings
-
-type 'a with_bindings = 'a * 'a bindings
-
-
-(** Some utility types for parsing *)
-
-type 'a or_var =
- | ArgArg of 'a
- | ArgVar of lident
-
-type 'a and_short_name = 'a * lident option
-
-type 'a or_by_notation_r =
- | AN of 'a
- | ByNotation of (string * string option)
-
-type 'a or_by_notation = 'a or_by_notation_r CAst.t
-
-(* NB: the last string in [ByNotation] is actually a [Notation.delimiters],
- but this formulation avoids a useless dependency. *)
-
-
-(** Kinds of modules *)
-
-type module_kind = Module | ModType | ModAny
-
-(** Various flags *)
-
-type direction_flag = bool (* true = Left-to-right false = right-to-right *)
-type evars_flag = bool (* true = pose evars false = fail on evars *)
-type rec_flag = bool (* true = recursive false = not recursive *)
-type advanced_flag = bool (* true = advanced false = basic *)
-type letin_flag = bool (* true = use local def false = use Leibniz *)
-type clear_flag = bool option (* true = clear hyp, false = keep hyp, None = use default *)
-
-type multi =
- | Precisely of int
- | UpTo of int
- | RepeatStar
- | RepeatPlus
-
-type 'a core_destruction_arg =
- | ElimOnConstr of 'a
- | ElimOnIdent of lident
- | ElimOnAnonHyp of int
-
-type 'a destruction_arg =
- clear_flag * 'a core_destruction_arg
-
-type inversion_kind =
- | SimpleInversion
- | FullInversion
- | FullInversionClear
-
-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 *) }
diff --git a/kernel/byterun/coq_fix_code.c b/kernel/byterun/coq_fix_code.c
index d5feafbf..be2b05da 100644
--- a/kernel/byterun/coq_fix_code.c
+++ b/kernel/byterun/coq_fix_code.c
@@ -18,6 +18,7 @@
#include <caml/misc.h>
#include <caml/mlvalues.h>
#include <caml/fail.h>
+#include <caml/alloc.h>
#include <caml/memory.h>
#include "coq_instruct.h"
#include "coq_fix_code.h"
@@ -78,38 +79,41 @@ void * coq_stat_alloc (asize_t sz)
}
value coq_makeaccu (value i) {
- code_t q;
- code_t res = coq_stat_alloc(2 * sizeof(opcode_t));
- q = res;
+ CAMLparam1(i);
+ CAMLlocal1(res);
+ code_t q = coq_stat_alloc(2 * sizeof(opcode_t));
+ res = caml_alloc_small(1, Abstract_tag);
+ Code_val(res) = q;
*q++ = VALINSTR(MAKEACCU);
*q = (opcode_t)Int_val(i);
- return (value)res;
+ CAMLreturn(res);
}
value coq_pushpop (value i) {
- code_t res;
- int n;
- n = Int_val(i);
+ CAMLparam1(i);
+ CAMLlocal1(res);
+ code_t q;
+ res = caml_alloc_small(1, Abstract_tag);
+ int n = Int_val(i);
if (n == 0) {
- res = coq_stat_alloc(sizeof(opcode_t));
- *res = VALINSTR(STOP);
- return (value)res;
+ q = coq_stat_alloc(sizeof(opcode_t));
+ Code_val(res) = q;
+ *q = VALINSTR(STOP);
+ CAMLreturn(res);
}
else {
- code_t q;
- res = coq_stat_alloc(3 * sizeof(opcode_t));
- q = res;
+ q = coq_stat_alloc(3 * sizeof(opcode_t));
+ Code_val(res) = q;
*q++ = VALINSTR(POP);
*q++ = (opcode_t)n;
*q = VALINSTR(STOP);
- return (value)res;
+ CAMLreturn(res);
}
}
value coq_is_accumulate_code(value code){
- code_t q;
+ code_t q = Code_val(code);
int res;
- q = (code_t)code;
res = Is_instruction(q,ACCUMULATE);
return Val_bool(res);
}
@@ -132,11 +136,14 @@ value coq_is_accumulate_code(value code){
#define COPY32(dst,src) (*dst=*src)
#endif /* ARCH_BIG_ENDIAN */
-value coq_tcode_of_code (value code, value size) {
- code_t p, q, res;
- asize_t len = (asize_t) Long_val(size);
- res = coq_stat_alloc(len);
- q = res;
+value coq_tcode_of_code (value code) {
+ CAMLparam1 (code);
+ CAMLlocal1 (res);
+ code_t p, q;
+ asize_t len = (asize_t) caml_string_length(code);
+ res = caml_alloc_small(1, Abstract_tag);
+ q = coq_stat_alloc(len);
+ Code_val(res) = q;
len /= sizeof(opcode_t);
for (p = (code_t)code; p < (code_t)code + len; /*nothing*/) {
opcode_t instr;
@@ -166,5 +173,5 @@ value coq_tcode_of_code (value code, value size) {
for(i=0; i<ar; i++) { COPY32(q,p); p++; q++; };
}
}
- return (value)res;
+ CAMLreturn(res);
}
diff --git a/kernel/byterun/coq_fix_code.h b/kernel/byterun/coq_fix_code.h
index 5c85389d..638d6b5a 100644
--- a/kernel/byterun/coq_fix_code.h
+++ b/kernel/byterun/coq_fix_code.h
@@ -26,7 +26,7 @@ void init_arity();
#define Is_instruction(pc,instr) (*pc == VALINSTR(instr))
-value coq_tcode_of_code(value code, value len);
+value coq_tcode_of_code(value code);
value coq_makeaccu (value i);
value coq_pushpop (value i);
value coq_is_accumulate_code(value code);
diff --git a/kernel/byterun/coq_interp.c b/kernel/byterun/coq_interp.c
index af89712d..a944dbb0 100644
--- a/kernel/byterun/coq_interp.c
+++ b/kernel/byterun/coq_interp.c
@@ -16,6 +16,7 @@
#include <stdio.h>
#include <signal.h>
#include <stdint.h>
+#include <caml/memory.h>
#include "coq_gc.h"
#include "coq_instruct.h"
#include "coq_fix_code.h"
@@ -163,8 +164,11 @@ extern void caml_process_pending_signals(void);
/* The interpreter itself */
value coq_interprete
-(code_t coq_pc, value coq_accu, value coq_env, long coq_extra_args)
+(code_t coq_pc, value coq_accu, value coq_atom_tbl, value coq_global_data, value coq_env, long coq_extra_args)
{
+ /* coq_accu is not allocated on the OCaml heap */
+ CAMLparam2(coq_atom_tbl, coq_global_data);
+
/*Declaration des variables */
#ifdef PC_REG
register code_t pc PC_REG;
@@ -196,7 +200,7 @@ value coq_interprete
coq_instr_table = (char **) coq_jumptable;
coq_instr_base = coq_Jumptbl_base;
#endif
- return Val_unit;
+ CAMLreturn(Val_unit);
}
#if defined(THREADED_CODE) && defined(ARCH_SIXTYFOUR) && !defined(ARCH_CODE32)
coq_jumptbl_base = coq_Jumptbl_base;
@@ -626,7 +630,7 @@ value coq_interprete
print_instr("CLOSUREREC");
if (nvars > 0) *--sp = accu;
/* construction du vecteur de type */
- Alloc_small(accu, nfuncs, 0);
+ Alloc_small(accu, nfuncs, Abstract_tag);
for(i = 0; i < nfuncs; i++) {
Field(accu,i) = (value)(pc+pc[i]);
}
@@ -662,7 +666,7 @@ value coq_interprete
print_instr("CLOSURECOFIX");
if (nvars > 0) *--sp = accu;
/* construction du vecteur de type */
- Alloc_small(accu, nfunc, 0);
+ Alloc_small(accu, nfunc, Abstract_tag);
for(i = 0; i < nfunc; i++) {
Field(accu,i) = (value)(pc+pc[i]);
}
@@ -1028,7 +1032,7 @@ value coq_interprete
CHECK_STACK(nargs+1);
sp -= nargs;
for (i = 0; i < nargs; i++) sp[i] = Field(accu, i + 2);
- *--sp = accu; // Last argument is the pointer to the suspension
+ *--sp = accu; // Leftmost argument is the pointer to the suspension
print_lint(nargs);
coq_extra_args = nargs;
pc = Code_val(coq_env); // Trigger evaluation
@@ -1068,12 +1072,22 @@ value coq_interprete
}
}
*--sp = accu;
- /* We create the switch zipper */
- Alloc_small(accu, 5, Default_tag);
- Field(accu, 0) = (value)typlbl; Field(accu, 1) = (value)swlbl;
- Field(accu, 2) = sp[1]; Field(accu, 3) = sp[0];
- Field(accu, 4) = coq_env;
- sp++;sp[0] = accu;
+ /* Create bytecode wrappers */
+ Alloc_small(accu, 1, Abstract_tag);
+ Code_val(accu) = typlbl;
+ *--sp = accu;
+ Alloc_small(accu, 1, Abstract_tag);
+ Code_val(accu) = swlbl;
+ *--sp = accu;
+ /* We create the switch zipper */
+ Alloc_small(accu, 5, Default_tag);
+ Field(accu, 0) = sp[1];
+ Field(accu, 1) = sp[0];
+ Field(accu, 2) = sp[3];
+ Field(accu, 3) = sp[2];
+ Field(accu, 4) = coq_env;
+ sp += 3;
+ sp[0] = accu;
/* We create the atom */
Alloc_small(accu, 2, ATOM_SWITCH_TAG);
Field(accu, 0) = sp[1]; Field(accu, 1) = sp[0];
@@ -1460,7 +1474,7 @@ value coq_interprete
Instruct(STOP){
print_instr("STOP");
coq_sp = sp;
- return accu;
+ CAMLreturn(accu);
}
@@ -1473,7 +1487,8 @@ value coq_interprete
#endif
}
-value coq_push_ra(value tcode) {
+value coq_push_ra(value code) {
+ code_t tcode = Code_val(code);
print_instr("push_ra");
coq_sp -= 3;
coq_sp[0] = (value) tcode;
@@ -1512,12 +1527,18 @@ value coq_push_vstack(value stk, value max_stack_size) {
return Val_unit;
}
-value coq_interprete_ml(value tcode, value a, value e, value ea) {
+value coq_interprete_ml(value tcode, value a, value t, value g, value e, value ea) {
+ // Registering the other arguments w.r.t. the OCaml GC is done by coq_interprete
+ CAMLparam1(tcode);
print_instr("coq_interprete");
- return coq_interprete((code_t)tcode, a, e, Long_val(ea));
+ CAMLreturn (coq_interprete(Code_val(tcode), a, t, g, e, Long_val(ea)));
print_instr("end coq_interprete");
}
-value coq_eval_tcode (value tcode, value e) {
- return coq_interprete_ml(tcode, Val_unit, e, 0);
+value coq_interprete_byte(value* argv, int argn){
+ return coq_interprete_ml(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+}
+
+value coq_eval_tcode (value tcode, value t, value g, value e) {
+ return coq_interprete_ml(tcode, Val_unit, t, g, e, 0);
}
diff --git a/kernel/byterun/coq_interp.h b/kernel/byterun/coq_interp.h
index 60865c32..c04e9e00 100644
--- a/kernel/byterun/coq_interp.h
+++ b/kernel/byterun/coq_interp.h
@@ -17,11 +17,10 @@ value coq_push_arguments(value args);
value coq_push_vstack(value stk);
-value coq_interprete_ml(value tcode, value a, value e, value ea);
+value coq_interprete_ml(value tcode, value a, value t, value g, value e, value ea);
+value coq_interprete_byte(value* argv, int argn);
value coq_interprete
- (code_t coq_pc, value coq_accu, value coq_env, long coq_extra_args);
-
-value coq_eval_tcode (value tcode, value e);
-
+ (code_t coq_pc, value coq_accu, value coq_atom_tbl, value coq_global_data, value coq_env, long coq_extra_args);
+value coq_eval_tcode (value tcode, value t, value g, value e);
diff --git a/kernel/byterun/coq_memory.c b/kernel/byterun/coq_memory.c
index 45cfae50..542a05fd 100644
--- a/kernel/byterun/coq_memory.c
+++ b/kernel/byterun/coq_memory.c
@@ -10,6 +10,8 @@
#include <stdio.h>
#include <string.h>
+#include <caml/alloc.h>
+#include <caml/address_class.h>
#include "coq_gc.h"
#include "coq_instruct.h"
#include "coq_fix_code.h"
@@ -24,10 +26,6 @@ value * coq_stack_threshold;
asize_t coq_max_stack_size = Coq_max_stack_size;
/* global_data */
-
-value coq_global_data;
-value coq_atom_tbl;
-
int drawinstr;
/* interp state */
@@ -50,7 +48,11 @@ value coq_static_alloc(value size) /* ML */
value accumulate_code(value unit) /* ML */
{
- return (value) accumulate;
+ CAMLparam1(unit);
+ CAMLlocal1(res);
+ res = caml_alloc_small(1, Abstract_tag);
+ Code_val(res) = accumulate;
+ CAMLreturn(res);
}
static void (*coq_prev_scan_roots_hook) (scanning_action);
@@ -58,11 +60,12 @@ static void (*coq_prev_scan_roots_hook) (scanning_action);
static void coq_scan_roots(scanning_action action)
{
register value * i;
- /* Scan the global variables */
- (*action)(coq_global_data, &coq_global_data);
- (*action)(coq_atom_tbl, &coq_atom_tbl);
/* Scan the stack */
for (i = coq_sp; i < coq_stack_high; i++) {
+#ifdef NO_NAKED_POINTERS
+ /* The VM stack may contain C-allocated bytecode */
+ if (Is_block(*i) && !Is_in_heap_or_young(*i)) continue;
+#endif
(*action) (*i, i);
};
/* Hook */
@@ -79,24 +82,10 @@ void init_coq_stack()
coq_max_stack_size = Coq_max_stack_size;
}
-void init_coq_global_data(long requested_size)
-{
- int i;
- coq_global_data = alloc_shr(requested_size, 0);
- for (i = 0; i < requested_size; i++)
- Field (coq_global_data, i) = Val_unit;
-}
-
-void init_coq_atom_tbl(long requested_size){
- int i;
- coq_atom_tbl = alloc_shr(requested_size, 0);
- for (i = 0; i < requested_size; i++) Field (coq_atom_tbl, i) = Val_unit;
-}
-
void init_coq_interpreter()
{
coq_sp = coq_stack_high;
- coq_interprete(NULL, Val_unit, Val_unit, 0);
+ coq_interprete(NULL, Val_unit, Atom(0), Atom(0), Val_unit, 0);
}
static int coq_vm_initialized = 0;
@@ -112,13 +101,15 @@ value init_coq_vm(value unit) /* ML */
#endif /* THREADED_CODE */
/* Allocate the table of global and the stack */
init_coq_stack();
- init_coq_global_data(Coq_global_data_Size);
- init_coq_atom_tbl(40);
/* Initialing the interpreter */
init_coq_interpreter();
- /* Some predefined pointer code */
- accumulate = (code_t) coq_stat_alloc(sizeof(opcode_t));
+ /* Some predefined pointer code.
+ * It is typically contained in accumlator blocks whose tag is 0 and thus
+ * scanned by the GC, so make it look like an OCaml block. */
+ value accu_block = (value) coq_stat_alloc(2 * sizeof(value));
+ Hd_hp (accu_block) = Make_header (1, Abstract_tag, Caml_black); \
+ accumulate = (code_t) Val_hp(accu_block);
*accumulate = VALINSTR(ACCUMULATE);
/* Initialize GC */
@@ -157,53 +148,6 @@ void realloc_coq_stack(asize_t required_space)
#undef shift
}
-value get_coq_global_data(value unit) /* ML */
-{
- return coq_global_data;
-}
-
-value get_coq_atom_tbl(value unit) /* ML */
-{
- return coq_atom_tbl;
-}
-
-value realloc_coq_global_data(value size) /* ML */
-{
- mlsize_t requested_size, actual_size, i;
- value new_global_data;
- requested_size = Long_val(size);
- actual_size = Wosize_val(coq_global_data);
- if (requested_size >= actual_size) {
- requested_size = (requested_size + 0x100) & 0xFFFFFF00;
- new_global_data = alloc_shr(requested_size, 0);
- for (i = 0; i < actual_size; i++)
- initialize(&Field(new_global_data, i), Field(coq_global_data, i));
- for (i = actual_size; i < requested_size; i++){
- Field (new_global_data, i) = Val_long (0);
- }
- coq_global_data = new_global_data;
- }
- return Val_unit;
-}
-
-value realloc_coq_atom_tbl(value size) /* ML */
-{
- mlsize_t requested_size, actual_size, i;
- value new_atom_tbl;
- requested_size = Long_val(size);
- actual_size = Wosize_val(coq_atom_tbl);
- if (requested_size >= actual_size) {
- requested_size = (requested_size + 0x100) & 0xFFFFFF00;
- new_atom_tbl = alloc_shr(requested_size, 0);
- for (i = 0; i < actual_size; i++)
- initialize(&Field(new_atom_tbl, i), Field(coq_atom_tbl, i));
- for (i = actual_size; i < requested_size; i++)
- Field (new_atom_tbl, i) = Val_long (0);
- coq_atom_tbl = new_atom_tbl;
- }
- return Val_unit;
-}
-
value coq_set_drawinstr(value unit)
{
drawinstr = 1;
diff --git a/kernel/byterun/coq_memory.h b/kernel/byterun/coq_memory.h
index cec34f56..9375b15d 100644
--- a/kernel/byterun/coq_memory.h
+++ b/kernel/byterun/coq_memory.h
@@ -20,7 +20,6 @@
#define Coq_stack_size (4096 * sizeof(value))
#define Coq_stack_threshold (256 * sizeof(value))
-#define Coq_global_data_Size (4096 * sizeof(value))
#define Coq_max_stack_size (256 * 1024)
#define TRANSP 0
@@ -34,9 +33,7 @@ extern value * coq_stack_threshold;
/* global_data */
-extern value coq_global_data;
extern int coq_all_transp;
-extern value coq_atom_tbl;
extern int drawinstr;
/* interp state */
@@ -53,10 +50,6 @@ value init_coq_vm(value unit); /* ML */
value re_init_coq_vm(value unit); /* ML */
void realloc_coq_stack(asize_t required_space);
-value get_coq_global_data(value unit); /* ML */
-value realloc_coq_global_data(value size); /* ML */
-value get_coq_atom_tbl(value unit); /* ML */
-value realloc_coq_atom_tbl(value size); /* ML */
value coq_set_transp_value(value transp); /* ML */
value get_coq_transp_value(value unit); /* ML */
#endif /* _COQ_MEMORY_ */
diff --git a/kernel/byterun/coq_values.c b/kernel/byterun/coq_values.c
index 528babeb..e05f3fb8 100644
--- a/kernel/byterun/coq_values.c
+++ b/kernel/byterun/coq_values.c
@@ -9,6 +9,7 @@
/***********************************************************************/
#include <stdio.h>
+#include <caml/memory.h>
#include "coq_fix_code.h"
#include "coq_instruct.h"
#include "coq_memory.h"
@@ -58,10 +59,36 @@ value coq_offset_closure(value v, value offset){
return (value)&Field(v, Int_val(offset));
}
+value coq_set_bytecode_field(value v, value i, value code) {
+ // No write barrier because the bytecode does not live on the OCaml heap
+ Field(v, Long_val(i)) = (value) Code_val(code);
+ return Val_unit;
+}
+
value coq_offset_tcode(value code,value offset){
- return((value)((code_t)code + Int_val(offset)));
+ CAMLparam1(code);
+ CAMLlocal1(res);
+ res = caml_alloc_small(1, Abstract_tag);
+ Code_val(res) = Code_val(code) + Int_val(offset);
+ CAMLreturn(res);
}
-value coq_int_tcode(value code, value offset) {
+value coq_int_tcode(value pc, value offset) {
+ code_t code = Code_val(pc);
return Val_int(*((code_t) code + Int_val(offset)));
}
+
+value coq_tcode_array(value tcodes) {
+ CAMLparam1(tcodes);
+ CAMLlocal2(res, tmp);
+ int i;
+ /* Assumes that the vector of types is small. This was implicit in the
+ previous code which was building the type array using Alloc_small. */
+ res = caml_alloc_small(Wosize_val(tcodes), Default_tag);
+ for (i = 0; i < Wosize_val(tcodes); i++) {
+ tmp = caml_alloc_small(1, Abstract_tag);
+ Code_val(tmp) = (code_t) Field(tcodes, i);
+ Store_field(res, i, tmp);
+ }
+ CAMLreturn(res);
+}
diff --git a/kernel/cClosure.ml b/kernel/cClosure.ml
index 08114abc..fd939402 100644
--- a/kernel/cClosure.ml
+++ b/kernel/cClosure.ml
@@ -31,7 +31,6 @@ open Environ
open Esubst
let stats = ref false
-let share = ref true
(* Profiling *)
let beta = ref 0
@@ -265,7 +264,8 @@ type 'a infos_cache = {
i_repr : 'a infos -> 'a infos_tab -> constr -> 'a;
i_env : env;
i_sigma : existential -> constr option;
- i_rels : (Context.Rel.Declaration.t * Pre_env.lazy_val) Range.t;
+ i_rels : (Constr.rel_declaration * lazy_val) Range.t;
+ i_share : bool;
}
and 'a infos = {
@@ -313,13 +313,13 @@ let ref_value_cache ({i_cache = cache} as infos) tab ref =
let evar_value cache ev =
cache.i_sigma ev
-let create mk_cl flgs env evars =
- let open Pre_env in
+let create ~repr ~share flgs env evars =
let cache =
- { i_repr = mk_cl;
+ { i_repr = repr;
i_env = env;
i_sigma = evars;
- i_rels = (Environ.pre_env env).env_rel_context.env_rel_map;
+ i_rels = env.env_rel_context.env_rel_map;
+ i_share = share;
}
in { i_flags = flgs; i_cache = cache }
@@ -385,8 +385,8 @@ let mk_red f = {norm=Red;term=f}
(* Could issue a warning if no is still Red, pointing out that we loose
sharing. *)
-let update v1 no t =
- if !share then
+let update ~share v1 no t =
+ if share then
(v1.norm <- no;
v1.term <- t;
v1)
@@ -398,7 +398,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 * Constant.t
+ | Zproj of Projection.Repr.t
| Zfix of fconstr * stack
| Zshift of int
| Zupdate of fconstr
@@ -482,7 +482,7 @@ let rec lft_fconstr n ft =
let lift_fconstr k f =
if Int.equal k 0 then f else lft_fconstr k f
let lift_fconstr_vect k v =
- if Int.equal k 0 then v else CArray.Fun1.map lft_fconstr k v
+ if Int.equal k 0 then v else Array.Fun1.map lft_fconstr k v
let clos_rel e i =
match expand_rel i e with
@@ -499,14 +499,16 @@ let compact_stack head stk =
(* Be sure to create a new cell otherwise sharing would be
lost by the update operation *)
let h' = lft_fconstr depth head in
- let _ = update m h'.norm h'.term in
+ (** The stack contains [Zupdate] marks only if in sharing mode *)
+ let _ = update ~share:true m h'.norm h'.term in
strip_rec depth s
| stk -> zshift depth stk in
strip_rec 0 stk
(* Put an update mark in the stack, only if needed *)
-let zupdate m s =
- if !share && begin match m.norm with Red -> true | _ -> false end
+let zupdate info m s =
+ let share = info.i_cache.i_share in
+ if share && begin match m.norm with Red -> true | _ -> false end
then
let s' = compact_stack m s in
let _ = m.term <- FLOCKED in
@@ -547,7 +549,7 @@ let mk_clos_vect env v = match v with
| [|v0; v1; v2|] -> [|mk_clos env v0; mk_clos env v1; mk_clos env v2|]
| [|v0; v1; v2; v3|] ->
[|mk_clos env v0; mk_clos env v1; mk_clos env v2; mk_clos env v3|]
-| v -> CArray.Fun1.map mk_clos env v
+| v -> Array.Fun1.map mk_clos env v
(* Translate the head constructor of t from constr to fconstr. This
function is parameterized by the function to apply on the direct
@@ -562,7 +564,7 @@ let mk_clos_deep clos_fun env t =
term = FCast (clos_fun env a, k, clos_fun env b)}
| App (f,v) ->
{ norm = Red;
- term = FApp (clos_fun env f, CArray.Fun1.map clos_fun env v) }
+ term = FApp (clos_fun env f, Array.Fun1.map clos_fun env v) }
| Proj (p,c) ->
{ norm = Red;
term = FProj (p, clos_fun env c) }
@@ -588,78 +590,95 @@ let mk_clos_deep clos_fun env t =
let mk_clos2 = mk_clos_deep mk_clos
(* The inverse of mk_clos_deep: move back to constr *)
-let rec to_constr constr_fun lfts v =
+let rec to_constr lfts v =
match v.term with
| FRel i -> mkRel (reloc_rel i lfts)
| FFlex (RelKey p) -> mkRel (reloc_rel p lfts)
| FFlex (VarKey x) -> mkVar x
| FAtom c -> exliftn lfts c
| FCast (a,k,b) ->
- mkCast (constr_fun lfts a, k, constr_fun lfts b)
+ mkCast (to_constr lfts a, k, to_constr lfts b)
| FFlex (ConstKey op) -> mkConstU op
| FInd op -> mkIndU op
| FConstruct op -> mkConstructU op
| FCaseT (ci,p,c,ve,env) ->
- mkCase (ci, constr_fun lfts (mk_clos env p),
- constr_fun lfts c,
- Array.map (fun b -> constr_fun lfts (mk_clos env b)) ve)
- | FFix ((op,(lna,tys,bds)),e) ->
+ if is_subs_id env && is_lift_id lfts then
+ mkCase (ci, p, to_constr lfts c, ve)
+ else
+ let subs = comp_subs lfts env in
+ mkCase (ci, subst_constr subs p,
+ to_constr lfts c,
+ Array.map (fun b -> subst_constr subs b) ve)
+ | FFix ((op,(lna,tys,bds)) as fx, e) ->
+ if is_subs_id e && is_lift_id lfts then
+ mkFix fx
+ else
let n = Array.length bds in
- let ftys = CArray.Fun1.map mk_clos e tys in
- let fbds = CArray.Fun1.map mk_clos (subs_liftn n e) bds in
- let lfts' = el_liftn n lfts in
- mkFix (op, (lna, CArray.Fun1.map constr_fun lfts ftys,
- CArray.Fun1.map constr_fun lfts' fbds))
- | FCoFix ((op,(lna,tys,bds)),e) ->
+ let subs_ty = comp_subs lfts e in
+ let subs_bd = comp_subs (el_liftn n lfts) (subs_liftn n e) in
+ let tys = Array.Fun1.map subst_constr subs_ty tys in
+ let bds = Array.Fun1.map subst_constr subs_bd bds in
+ mkFix (op, (lna, tys, bds))
+ | FCoFix ((op,(lna,tys,bds)) as cfx, e) ->
+ if is_subs_id e && is_lift_id lfts then
+ mkCoFix cfx
+ else
let n = Array.length bds in
- let ftys = CArray.Fun1.map mk_clos e tys in
- let fbds = CArray.Fun1.map mk_clos (subs_liftn n e) bds in
- let lfts' = el_liftn (Array.length bds) lfts in
- mkCoFix (op, (lna, CArray.Fun1.map constr_fun lfts ftys,
- CArray.Fun1.map constr_fun lfts' fbds))
+ let subs_ty = comp_subs lfts e in
+ let subs_bd = comp_subs (el_liftn n lfts) (subs_liftn n e) in
+ let tys = Array.Fun1.map subst_constr subs_ty tys in
+ let bds = Array.Fun1.map subst_constr subs_bd bds in
+ mkCoFix (op, (lna, tys, bds))
| FApp (f,ve) ->
- mkApp (constr_fun lfts f,
- CArray.Fun1.map constr_fun lfts ve)
+ mkApp (to_constr lfts f,
+ Array.Fun1.map to_constr lfts ve)
| FProj (p,c) ->
- mkProj (p,constr_fun lfts c)
+ mkProj (p,to_constr lfts c)
- | FLambda _ ->
- let (na,ty,bd) = destFLambda mk_clos2 v in
- mkLambda (na, constr_fun lfts ty,
- constr_fun (el_lift lfts) bd)
+ | FLambda (len, tys, f, e) ->
+ if is_subs_id e && is_lift_id lfts then
+ Term.compose_lam (List.rev tys) f
+ else
+ let subs = comp_subs lfts e in
+ let tys = List.mapi (fun i (na, c) -> na, subst_constr (subs_liftn i subs) c) tys in
+ let f = subst_constr (subs_liftn len subs) f in
+ Term.compose_lam (List.rev tys) f
| FProd (n,t,c) ->
- mkProd (n, constr_fun lfts t,
- constr_fun (el_lift lfts) c)
+ mkProd (n, to_constr lfts t,
+ to_constr (el_lift lfts) c)
| FLetIn (n,b,t,f,e) ->
- let fc = mk_clos2 (subs_lift e) f in
- mkLetIn (n, constr_fun lfts b,
- constr_fun lfts t,
- constr_fun (el_lift lfts) fc)
+ let subs = comp_subs (el_lift lfts) (subs_lift e) in
+ mkLetIn (n, to_constr lfts b,
+ to_constr lfts t,
+ subst_constr subs f)
| FEvar ((ev,args),env) ->
- mkEvar(ev,Array.map (fun a -> constr_fun lfts (mk_clos2 env a)) args)
- | FLIFT (k,a) -> to_constr constr_fun (el_shft k lfts) a
+ let subs = comp_subs lfts env in
+ mkEvar(ev,Array.map (fun a -> subst_constr subs a) args)
+ | FLIFT (k,a) -> to_constr (el_shft k lfts) a
| FCLOS (t,env) ->
- let fr = mk_clos2 env t in
- let unfv = update v fr.norm fr.term in
- to_constr constr_fun lfts unfv
+ if is_subs_id env && is_lift_id lfts then t
+ else
+ let subs = comp_subs lfts env in
+ subst_constr subs t
| FLOCKED -> assert false (*mkVar(Id.of_string"_LOCK_")*)
+and subst_constr subst c = match Constr.kind c with
+| Rel i ->
+ begin match expand_rel i subst with
+ | Inl (k, lazy v) -> Vars.lift k v
+ | Inr (m, _) -> mkRel m
+ end
+| _ ->
+ Constr.map_with_binders Esubst.subs_lift subst_constr subst c
+
+and comp_subs el s =
+ Esubst.lift_subst (fun el c -> lazy (to_constr el c)) el s
+
(* This function defines the correspondance between constr and
fconstr. When we find a closure whose substitution is the identity,
then we directly return the constr to avoid possibly huge
reallocation. *)
-let term_of_fconstr =
- let rec term_of_fconstr_lift lfts v =
- match v.term with
- | FCLOS(t,env) when is_subs_id env && is_lift_id lfts -> t
- | FLambda(_,tys,f,e) when is_subs_id e && is_lift_id lfts ->
- Term.compose_lam (List.rev tys) f
- | FFix(fx,e) when is_subs_id e && is_lift_id lfts -> mkFix fx
- | FCoFix(cfx,e) when is_subs_id e && is_lift_id lfts -> mkCoFix cfx
- | _ -> to_constr term_of_fconstr_lift lfts v in
- term_of_fconstr_lift el_id
-
-
+let term_of_fconstr c = to_constr el_id c
(* fstrong applies unfreeze_fun recursively on the (freeze) term and
* yields a term. Assumes that the unfreeze_fun never returns a
@@ -675,14 +694,15 @@ 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(Projection.make cst true,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 ->
zip (lift_fconstr n m) s
| Zupdate(rf)::s ->
- zip (update rf m.norm m.term) s
+ (** The stack contains [Zupdate] marks only if in sharing mode *)
+ zip (update ~share:true rf m.norm m.term) s
let fapp_stack (m,stk) = zip m stk
@@ -702,7 +722,8 @@ let strip_update_shift_app_red head stk =
strip_rec (Zapp args :: rstk)
{norm=h.norm;term=FApp(h,args)} depth s
| Zupdate(m)::s ->
- strip_rec rstk (update m h.norm h.term) depth s
+ (** The stack contains [Zupdate] marks only if in sharing mode *)
+ strip_rec rstk (update ~share:true m h.norm h.term) depth s
| stk -> (depth,List.rev rstk, stk) in
strip_rec [] head 0 stk
@@ -727,7 +748,8 @@ let get_nth_arg head n stk =
List.rev (if Int.equal n 0 then rstk else (Zapp bef :: rstk)) in
(Some (stk', args.(n)), append_stack aft s')
| Zupdate(m)::s ->
- strip_rec rstk (update m h.norm h.term) n s
+ (** The stack contains [Zupdate] mark only if in sharing mode *)
+ strip_rec rstk (update ~share:true m h.norm h.term) n s
| s -> (None, List.rev rstk @ s) in
strip_rec [] head n stk
@@ -736,7 +758,8 @@ let get_nth_arg head n stk =
let rec get_args n tys f e stk =
match stk with
Zupdate r :: s ->
- let _hd = update r Cstr (FLambda(n,tys,f,e)) in
+ (** The stack contains [Zupdate] mark only if in sharing mode *)
+ let _hd = update ~share:true r Cstr (FLambda(n,tys,f,e)) in
get_args n tys f e s
| Zshift k :: s ->
get_args n tys f (subs_shft (k,e)) s
@@ -804,21 +827,26 @@ let drop_parameters depth n argstk =
constructor is partially applied.
*)
let eta_expand_ind_stack env ind m s (f, s') =
+ let open Declarations in
let mib = lookup_mind (fst ind) env in
- match mib.Declarations.mind_record with
- | Some (Some (_,projs,pbs)) when
- mib.Declarations.mind_finite == Declarations.BiFinite ->
- (* (Construct, pars1 .. parsm :: arg1...argn :: []) ~= (f, s') ->
+ (* disallow eta-exp for non-primitive records *)
+ if not (mib.mind_finite == BiFinite) then raise Not_found;
+ match Declareops.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.Declarations.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 true, right) }) projs in
- argss, [Zapp hstack]
- | _ -> raise Not_found (* disallow eta-exp for non-primitive records *)
+ let pars = mib.Declarations.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 true, 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
@@ -857,9 +885,7 @@ let contract_fix_vect fix =
let unfold_projection info p =
if red_projection info.i_flags p
then
- let open Declarations in
- let pb = lookup_projection p (info_env info) in
- Some (Zproj (pb.proj_npars, pb.proj_arg, Projection.constant p))
+ Some (Zproj (Projection.repr p))
else None
(*********************************************************************)
@@ -870,10 +896,10 @@ let unfold_projection info p =
let rec knh info m stk =
match m.term with
| FLIFT(k,a) -> knh info a (zshift k stk)
- | FCLOS(t,e) -> knht info e t (zupdate m stk)
+ | FCLOS(t,e) -> knht info e t (zupdate info m stk)
| FLOCKED -> assert false
- | FApp(a,b) -> knh info a (append_stack b (zupdate m stk))
- | FCaseT(ci,p,t,br,e) -> knh info t (ZcaseT(ci,p,br,e)::zupdate m stk)
+ | FApp(a,b) -> knh info a (append_stack b (zupdate info m stk))
+ | FCaseT(ci,p,t,br,e) -> knh info t (ZcaseT(ci,p,br,e)::zupdate info m stk)
| FFix(((ri,n),(_,_,_)),_) ->
(match get_nth_arg m ri.(n) stk with
(Some(pars,arg),stk') -> knh info arg (Zfix(m,pars)::stk')
@@ -882,7 +908,7 @@ let rec knh info m stk =
| FProj (p,c) ->
(match unfold_projection info p with
| None -> (m, stk)
- | Some s -> knh info c (s :: zupdate m stk))
+ | Some s -> knh info c (s :: zupdate info m stk))
(* cases where knh stops *)
| (FFlex _|FLetIn _|FConstruct _|FEvar _|
@@ -940,9 +966,9 @@ let rec knr info tab m stk =
let stk' = par @ append_stack [|rarg|] s in
let (fxe,fxbd) = contract_fix_vect fx.term in
knit info tab fxe fxbd stk'
- | (depth, args, Zproj (n, m, cst)::s) when use_match ->
- let rargs = drop_parameters depth n args in
- let rarg = project_nth_arg m rargs in
+ | (depth, args, Zproj p::s) when use_match ->
+ let rargs = drop_parameters depth (Projection.Repr.npars p) args in
+ let rarg = project_nth_arg (Projection.Repr.arg p) rargs in
kni info tab rarg s
| (_,args,s) -> (m,args@s))
else (m,stk)
@@ -984,7 +1010,7 @@ let rec zip_term zfun m stk =
let t = mkCase(ci, zfun (mk_clos e p), m,
Array.map (fun b -> zfun (mk_clos e b)) br) in
zip_term zfun t s
- | Zproj(_,_,p)::s ->
+ | Zproj p::s ->
let t = mkProj (Projection.make p true, m) in
zip_term zfun t s
| Zfix(fx,par)::s ->
@@ -1000,10 +1026,11 @@ let rec zip_term zfun m stk =
2- tries to rebuild the term. If a closure still has to be computed,
calls itself recursively. *)
let rec kl info tab m =
+ let share = info.i_cache.i_share in
if is_val m then (incr prune; term_of_fconstr m)
else
let (nm,s) = kni info tab m [] in
- let () = if !share then ignore (fapp_stack (nm, s)) in (* to unlock Zupdates! *)
+ let () = if share then ignore (fapp_stack (nm, s)) in (* to unlock Zupdates! *)
zip_term (kl info tab) (norm_head info tab nm) s
(* no redex: go up for atoms and already normalized terms, go down
@@ -1024,14 +1051,14 @@ and norm_head info tab m =
| FProd(na,dom,rng) ->
mkProd(na, kl info tab dom, kl info tab rng)
| FCoFix((n,(na,tys,bds)),e) ->
- let ftys = CArray.Fun1.map mk_clos e tys in
+ let ftys = Array.Fun1.map mk_clos e tys in
let fbds =
- CArray.Fun1.map mk_clos (subs_liftn (Array.length na) e) bds in
+ Array.Fun1.map mk_clos (subs_liftn (Array.length na) e) bds in
mkCoFix(n,(na, CArray.map (kl info tab) ftys, CArray.map (kl info tab) fbds))
| FFix((n,(na,tys,bds)),e) ->
- let ftys = CArray.Fun1.map mk_clos e tys in
+ let ftys = Array.Fun1.map mk_clos e tys in
let fbds =
- CArray.Fun1.map mk_clos (subs_liftn (Array.length na) e) bds in
+ Array.Fun1.map mk_clos (subs_liftn (Array.length na) e) bds in
mkFix(n,(na, CArray.map (kl info tab) ftys, CArray.map (kl info tab) fbds))
| FEvar((i,args),env) ->
mkEvar(i, Array.map (fun a -> kl info tab (mk_clos env a)) args)
@@ -1052,16 +1079,22 @@ let norm_val info tab v =
let inject c = mk_clos (subs_id 0) c
-let whd_stack infos tab m stk =
+let whd_stack infos tab m stk = match m.norm with
+| Whnf | Norm ->
+ (** No need to perform [kni] nor to unlock updates because
+ every head subterm of [m] is [Whnf] or [Norm] *)
+ knh infos m stk
+| Red | Cstr ->
let k = kni infos tab m stk in
- let () = if !share then ignore (fapp_stack k) in (* to unlock Zupdates! *)
+ let () = if infos.i_cache.i_share then ignore (fapp_stack k) in (* to unlock Zupdates! *)
k
(* cache of constants: the body is computed only when needed. *)
type clos_infos = fconstr infos
let create_clos_infos ?(evars=fun _ -> None) flgs env =
- create (fun _ _ c -> inject c) flgs env evars
+ let share = (Environ.typing_flags env).Declarations.share_reduction in
+ create ~share ~repr:(fun _ _ c -> inject c) flgs env evars
let create_tab () = KeyTable.create 17
diff --git a/kernel/cClosure.mli b/kernel/cClosure.mli
index e2f5a3b8..6121b3a1 100644
--- a/kernel/cClosure.mli
+++ b/kernel/cClosure.mli
@@ -15,7 +15,6 @@ open Esubst
(** Flags for profiling reductions. *)
val stats : bool ref
-val share : bool ref
val with_stats: 'a Lazy.t -> 'a
@@ -106,8 +105,13 @@ type 'a infos = {
i_cache : 'a infos_cache }
val ref_value_cache: 'a infos -> 'a infos_tab -> table_key -> 'a option
-val create: ('a infos -> 'a infos_tab -> constr -> 'a) -> reds -> env ->
- (existential -> constr option) -> 'a infos
+val create:
+ repr:('a infos -> 'a infos_tab -> constr -> 'a) ->
+ share:bool ->
+ reds ->
+ env ->
+ (existential -> constr option) ->
+ 'a infos
val create_tab : unit -> 'a infos_tab
val evar_value : 'a infos_cache -> existential -> constr option
@@ -152,7 +156,7 @@ type fterm =
type stack_member =
| Zapp of fconstr array
| ZcaseT of case_info * constr * constr array * fconstr subs
- | Zproj of int * int * Constant.t
+ | Zproj of Projection.Repr.t
| Zfix of fconstr * stack
| Zshift of int
| Zupdate of fconstr
@@ -239,14 +243,11 @@ val lift_fconstr_vect : int -> fconstr array -> fconstr array
val mk_clos : fconstr subs -> constr -> fconstr
val mk_clos_vect : fconstr subs -> constr array -> fconstr array
-val mk_clos_deep :
- (fconstr subs -> constr -> fconstr) ->
- fconstr subs -> constr -> fconstr
val kni: clos_infos -> fconstr infos_tab -> fconstr -> stack -> fconstr * stack
val knr: clos_infos -> fconstr infos_tab -> fconstr -> stack -> fconstr * stack
val kl : clos_infos -> fconstr infos_tab -> fconstr -> constr
-val to_constr : (lift -> fconstr -> constr) -> lift -> fconstr -> constr
+val to_constr : lift -> fconstr -> constr
(** End of cbn debug section i*)
diff --git a/kernel/cbytecodes.ml b/kernel/cbytecodes.ml
index 0f3a43d5..ed3bd866 100644
--- a/kernel/cbytecodes.ml
+++ b/kernel/cbytecodes.ml
@@ -15,82 +15,7 @@
(* This file defines the type of bytecode instructions *)
open Names
-open Constr
-
-type tag = int
-
-let accu_tag = 0
-
-let type_atom_tag = 2
-let max_atom_tag = 2
-let proj_tag = 3
-let fix_app_tag = 4
-let switch_tag = 5
-let cofix_tag = 6
-let cofix_evaluated_tag = 7
-
-(* It would be great if OCaml exported this value,
- So fixme if this happens in a new version of OCaml *)
-let last_variant_tag = 245
-
-type structured_constant =
- | Const_sort of Sorts.t
- | Const_ind of inductive
- | Const_proj of Constant.t
- | Const_b0 of tag
- | Const_bn of tag * structured_constant array
- | Const_univ_level of Univ.Level.t
-
-type reloc_table = (tag * int) array
-
-type annot_switch =
- {ci : case_info; rtbl : reloc_table; tailcall : bool; max_stack_size : int}
-
-let rec eq_structured_constant c1 c2 = match c1, c2 with
-| Const_sort s1, Const_sort s2 -> Sorts.equal s1 s2
-| Const_sort _, _ -> false
-| Const_ind i1, Const_ind i2 -> eq_ind i1 i2
-| Const_ind _, _ -> false
-| Const_proj p1, Const_proj p2 -> Constant.equal p1 p2
-| Const_proj _, _ -> false
-| Const_b0 t1, Const_b0 t2 -> Int.equal t1 t2
-| Const_b0 _, _ -> false
-| Const_bn (t1, a1), Const_bn (t2, a2) ->
- Int.equal t1 t2 && CArray.equal eq_structured_constant a1 a2
-| Const_bn _, _ -> false
-| Const_univ_level l1 , Const_univ_level l2 -> Univ.Level.equal l1 l2
-| Const_univ_level _ , _ -> false
-
-let rec hash_structured_constant c =
- let open Hashset.Combine in
- match c with
- | Const_sort s -> combinesmall 1 (Sorts.hash s)
- | Const_ind i -> combinesmall 2 (ind_hash i)
- | Const_proj p -> combinesmall 3 (Constant.hash p)
- | Const_b0 t -> combinesmall 4 (Int.hash t)
- | Const_bn (t, a) ->
- let fold h c = combine h (hash_structured_constant c) in
- let h = Array.fold_left fold 0 a in
- combinesmall 5 (combine (Int.hash t) h)
- | Const_univ_level l -> combinesmall 6 (Univ.Level.hash l)
-
-let eq_annot_switch asw1 asw2 =
- let eq_ci ci1 ci2 =
- eq_ind ci1.ci_ind ci2.ci_ind &&
- Int.equal ci1.ci_npar ci2.ci_npar &&
- CArray.equal Int.equal ci1.ci_cstr_ndecls ci2.ci_cstr_ndecls
- in
- let eq_rlc (i1, j1) (i2, j2) = Int.equal i1 i2 && Int.equal j1 j2 in
- eq_ci asw1.ci asw2.ci &&
- CArray.equal eq_rlc asw1.rtbl asw2.rtbl &&
- (asw1.tailcall : bool) == asw2.tailcall
-
-let hash_annot_switch asw =
- let open Hashset.Combine in
- let h1 = Constr.case_info_hash asw.ci in
- let h2 = Array.fold_left (fun h (t, i) -> combine3 h t i) 0 asw.rtbl in
- let h3 = if asw.tailcall then 1 else 0 in
- combine3 h1 h2 h3
+open Vmvalues
module Label =
struct
@@ -132,8 +57,7 @@ type instruction =
| Ksetfield of int
| Kstop
| Ksequence of bytecodes * bytecodes
- | Kproj of int * Constant.t (* index of the projected argument,
- name of projection *)
+ | Kproj of Projection.Repr.t
| Kensurestackcapacity of int
(* spiwack: instructions concerning integers *)
| Kbranch of Label.t (* jump to label *)
@@ -237,22 +161,6 @@ type comp_env = {
open Pp
open Util
-let pp_sort s =
- let open Sorts in
- match s with
- | Prop Null -> str "Prop"
- | Prop Pos -> str "Set"
- | Type u -> str "Type@{" ++ Univ.pr_uni u ++ str "}"
-
-let rec pp_struct_const = function
- | Const_sort s -> pp_sort s
- | Const_ind (mind, i) -> MutInd.print mind ++ str"#" ++ int i
- | Const_proj p -> Constant.print p
- | Const_b0 i -> int i
- | Const_bn (i,t) ->
- int i ++ surround (prvect_with_sep pr_comma pp_struct_const t)
- | Const_univ_level l -> Univ.Level.pr l
-
let pp_lbl lbl = str "L" ++ int lbl
let pp_fv_elem = function
@@ -310,13 +218,13 @@ let rec pp_instr i =
prlist_with_sep spc pp_lbl (Array.to_list lblb))
| Kpushfields n -> str "pushfields " ++ int n
| Kfield n -> str "field " ++ int n
- | Ksetfield n -> str "set field" ++ int n
+ | Ksetfield n -> str "setfield " ++ int n
| Kstop -> str "stop"
| Kbranch lbl -> str "branch " ++ pp_lbl lbl
- | Kproj(n,p) -> str "proj " ++ int n ++ str " " ++ Constant.print p
+ | Kproj p -> str "proj " ++ Projection.Repr.print p
| Kensurestackcapacity size -> str "growstack " ++ int size
diff --git a/kernel/cbytecodes.mli b/kernel/cbytecodes.mli
index f87090c7..9c04c166 100644
--- a/kernel/cbytecodes.mli
+++ b/kernel/cbytecodes.mli
@@ -11,42 +11,7 @@
(* $Id$ *)
open Names
-open Constr
-
-type tag = int
-
-val accu_tag : tag
-
-val type_atom_tag : tag
-val max_atom_tag : tag
-val proj_tag : tag
-val fix_app_tag : tag
-val switch_tag : tag
-val cofix_tag : tag
-val cofix_evaluated_tag : tag
-
-val last_variant_tag : tag
-
-type structured_constant =
- | Const_sort of Sorts.t
- | Const_ind of inductive
- | Const_proj of Constant.t
- | Const_b0 of tag
- | Const_bn of tag * structured_constant array
- | Const_univ_level of Univ.Level.t
-
-val pp_struct_const : structured_constant -> Pp.t
-
-type reloc_table = (tag * int) array
-
-type annot_switch =
- {ci : case_info; rtbl : reloc_table; tailcall : bool; max_stack_size : int}
-
-val eq_structured_constant : structured_constant -> structured_constant -> bool
-val hash_structured_constant : structured_constant -> int
-
-val eq_annot_switch : annot_switch -> annot_switch -> bool
-val hash_annot_switch : annot_switch -> int
+open Vmvalues
module Label :
sig
@@ -89,8 +54,7 @@ type instruction =
| Ksetfield of int (** accu[n] = sp[0] ; sp = pop sp *)
| Kstop
| Ksequence of bytecodes * bytecodes
- | Kproj of int * Constant.t (** index of the projected argument,
- name of projection *)
+ | Kproj of Projection.Repr.t
| Kensurestackcapacity of int
(** spiwack: instructions concerning integers *)
diff --git a/kernel/cbytegen.ml b/kernel/cbytegen.ml
index e2c535e9..5362f9a8 100644
--- a/kernel/cbytegen.ml
+++ b/kernel/cbytegen.ml
@@ -14,13 +14,14 @@
open Util
open Names
+open Vmvalues
open Cbytecodes
open Cemitcodes
open Cinstr
open Clambda
open Constr
open Declarations
-open Pre_env
+open Environ
(* Compilation of variables + computing free variables *)
@@ -77,6 +78,7 @@ open Pre_env
(* ai' = [A_t | accumulate | [Cfx_t | fcofixi] | arg1 | ... | argp ] *)
(* If such a block is matched against, we have to force evaluation, *)
(* function [fcofixi] is then applied to [ai'] [arg1] ... [argp] *)
+(* (note that [ai'] is a pointer to the closure, passed as argument) *)
(* Once evaluation is completed [ai'] is updated with the result: *)
(* ai' <-- *)
(* [A_t | accumulate | [Cfxe_t |fcofixi|result] | arg1 | ... | argp ] *)
@@ -394,72 +396,72 @@ let init_fun_code () = fun_code := []
(*
If [tag] hits the OCaml limitation for non constant constructors, we switch to
another representation for the remaining constructors:
-[last_variant_tag|tag - last_variant_tag|args]
+[last_variant_tag|tag - Obj.last_non_constant_constructor_tag|args]
-We subtract last_variant_tag for efficiency of match interpretation.
+We subtract Obj.last_non_constant_constructor_tag for efficiency of match interpretation.
*)
let nest_block tag arity cont =
- Kconst (Const_b0 (tag - last_variant_tag)) ::
- Kmakeblock(arity+1, last_variant_tag) :: cont
+ Kconst (Const_b0 (tag - Obj.last_non_constant_constructor_tag)) ::
+ Kmakeblock(arity+1, Obj.last_non_constant_constructor_tag) :: cont
let code_makeblock ~stack_size ~arity ~tag cont =
- if tag < last_variant_tag then
+ if tag < Obj.last_non_constant_constructor_tag then
Kmakeblock(arity, tag) :: cont
else begin
set_max_stack_size (stack_size + 1);
Kpush :: nest_block tag arity cont
end
-let compile_structured_constant reloc sc sz cont =
+let compile_structured_constant cenv sc sz cont =
set_max_stack_size sz;
Kconst sc :: cont
(* compiling application *)
-let comp_args comp_expr reloc args sz cont =
+let comp_args comp_expr cenv args sz cont =
let nargs_m_1 = Array.length args - 1 in
- let c = ref (comp_expr reloc args.(0) (sz + nargs_m_1) cont) in
+ let c = ref (comp_expr cenv args.(0) (sz + nargs_m_1) cont) in
for i = 1 to nargs_m_1 do
- c := comp_expr reloc args.(i) (sz + nargs_m_1 - i) (Kpush :: !c)
+ c := comp_expr cenv args.(i) (sz + nargs_m_1 - i) (Kpush :: !c)
done;
!c
-let comp_app comp_fun comp_arg reloc f args sz cont =
+let comp_app comp_fun comp_arg cenv f args sz cont =
let nargs = Array.length args in
- if Int.equal nargs 0 then comp_fun reloc f sz cont
+ if Int.equal nargs 0 then comp_fun cenv f sz cont
else
match is_tailcall cont with
| Some k ->
- comp_args comp_arg reloc args sz
+ comp_args comp_arg cenv args sz
(Kpush ::
- comp_fun reloc f (sz + nargs)
+ comp_fun cenv f (sz + nargs)
(Kappterm(nargs, k + nargs) :: (discard_dead_code cont)))
| None ->
if nargs < 4 then
- comp_args comp_arg reloc args sz
- (Kpush :: (comp_fun reloc f (sz+nargs) (Kapply nargs :: cont)))
+ comp_args comp_arg cenv args sz
+ (Kpush :: (comp_fun cenv f (sz+nargs) (Kapply nargs :: cont)))
else
let lbl,cont1 = label_code cont in
Kpush_retaddr lbl ::
- (comp_args comp_arg reloc args (sz + 3)
- (Kpush :: (comp_fun reloc f (sz+3+nargs) (Kapply nargs :: cont1))))
+ (comp_args comp_arg cenv args (sz + 3)
+ (Kpush :: (comp_fun cenv f (sz+3+nargs) (Kapply nargs :: cont1))))
(* Compiling free variables *)
-let compile_fv_elem reloc fv sz cont =
+let compile_fv_elem cenv fv sz cont =
match fv with
- | FVrel i -> pos_rel i reloc sz :: cont
- | FVnamed id -> pos_named id reloc :: cont
- | FVuniv_var i -> pos_universe_var i reloc sz :: cont
- | FVevar evk -> pos_evar evk reloc :: cont
+ | FVrel i -> pos_rel i cenv sz :: cont
+ | FVnamed id -> pos_named id cenv :: cont
+ | FVuniv_var i -> pos_universe_var i cenv sz :: cont
+ | FVevar evk -> pos_evar evk cenv :: cont
-let rec compile_fv reloc l sz cont =
+let rec compile_fv cenv l sz cont =
match l with
| [] -> cont
- | [fvn] -> set_max_stack_size (sz + 1); compile_fv_elem reloc fvn sz cont
+ | [fvn] -> set_max_stack_size (sz + 1); compile_fv_elem cenv fvn sz cont
| fvn :: tl ->
- compile_fv_elem reloc fvn sz
- (Kpush :: compile_fv reloc tl (sz + 1) cont)
+ compile_fv_elem cenv fvn sz
+ (Kpush :: compile_fv cenv tl (sz + 1) cont)
(* Compiling constants *)
@@ -484,61 +486,63 @@ let make_areconst n else_lbl cont =
Kareconst (n, else_lbl)::cont
(* sz is the size of the local stack *)
-let rec compile_lam env reloc lam sz cont =
+let rec compile_lam env cenv lam sz cont =
set_max_stack_size sz;
match lam with
- | Lrel(_, i) -> pos_rel i reloc sz :: cont
+ | Lrel(_, i) -> pos_rel i cenv sz :: cont
- | Lval v -> compile_structured_constant reloc v sz cont
+ | Lint i -> compile_structured_constant cenv (Const_b0 i) sz cont
- | Lproj (n,kn,arg) ->
- compile_lam env reloc arg sz (Kproj (n,kn) :: cont)
+ | Lval v -> compile_structured_constant cenv (Const_val v) sz cont
- | Lvar id -> pos_named id reloc :: cont
+ | Lproj (p,arg) ->
+ compile_lam env cenv arg sz (Kproj p :: cont)
+
+ | Lvar id -> pos_named id cenv :: cont
| Levar (evk, args) ->
if Array.is_empty args then
- compile_fv_elem reloc (FVevar evk) sz cont
+ compile_fv_elem cenv (FVevar evk) sz cont
else
(** Arguments are reversed in evar instances *)
let args = Array.copy args in
let () = Array.rev args in
- comp_app compile_fv_elem (compile_lam env) reloc (FVevar evk) args sz cont
+ comp_app compile_fv_elem (compile_lam env) cenv (FVevar evk) args sz cont
- | Lconst (kn,u) -> compile_constant env reloc kn u [||] sz cont
+ | Lconst (kn,u) -> compile_constant env cenv kn u [||] sz cont
| Lind (ind,u) ->
if Univ.Instance.is_empty u then
- compile_structured_constant reloc (Const_ind ind) sz cont
- else comp_app compile_structured_constant compile_universe reloc
+ compile_structured_constant cenv (Const_ind ind) sz cont
+ else comp_app compile_structured_constant compile_universe cenv
(Const_ind ind) (Univ.Instance.to_array u) sz cont
- | Lsort (Sorts.Prop _ as s) ->
- compile_structured_constant reloc (Const_sort s) sz cont
+ | Lsort (Sorts.Prop | Sorts.Set as s) ->
+ compile_structured_constant cenv (Const_sort s) sz cont
| Lsort (Sorts.Type u) ->
(* We represent universes as a global constant with local universes
"compacted", i.e. as [u arg0 ... argn] where we will substitute (after
evaluation) [Var 0,...,Var n] with values of [arg0,...,argn] *)
let u,s = Univ.compact_univ u in
- let compile_get_univ reloc idx sz cont =
+ let compile_get_univ cenv idx sz cont =
set_max_stack_size sz;
- compile_fv_elem reloc (FVuniv_var idx) sz cont
+ compile_fv_elem cenv (FVuniv_var idx) sz cont
in
if List.is_empty s then
- compile_structured_constant reloc (Const_sort (Sorts.Type u)) sz cont
+ compile_structured_constant cenv (Const_sort (Sorts.Type u)) sz cont
else
- comp_app compile_structured_constant compile_get_univ reloc
+ comp_app compile_structured_constant compile_get_univ cenv
(Const_sort (Sorts.Type u)) (Array.of_list s) sz cont
| Llet (id,def,body) ->
- compile_lam env reloc def sz
+ compile_lam env cenv def sz
(Kpush ::
- compile_lam env (push_local sz reloc) body (sz+1) (add_pop 1 cont))
+ compile_lam env (push_local sz cenv) body (sz+1) (add_pop 1 cont))
| Lprod (dom,codom) ->
let cont1 =
- Kpush :: compile_lam env reloc dom (sz+1) (Kmakeprod :: cont) in
- compile_lam env reloc codom sz cont1
+ Kpush :: compile_lam env cenv dom (sz+1) (Kmakeprod :: cont) in
+ compile_lam env cenv codom sz cont1
| Llam (ids,body) ->
let arity = Array.length ids in
@@ -549,12 +553,12 @@ let rec compile_lam env reloc lam sz cont =
in
fun_code := [Ksequence(add_grab arity lbl_fun cont_fun,!fun_code)];
let fv = fv r_fun in
- compile_fv reloc fv.fv_rev sz (Kclosure(lbl_fun,fv.size) :: cont)
+ compile_fv cenv fv.fv_rev sz (Kclosure(lbl_fun,fv.size) :: cont)
| Lapp (f, args) ->
begin match f with
- | Lconst (kn,u) -> compile_constant env reloc kn u args sz cont
- | _ -> comp_app (compile_lam env) (compile_lam env) reloc f args sz cont
+ | Lconst (kn,u) -> compile_constant env cenv kn u args sz cont
+ | _ -> comp_app (compile_lam env) (compile_lam env) cenv f args sz cont
end
| Lfix ((rec_args, init), (decl, types, bodies)) ->
@@ -586,7 +590,7 @@ let rec compile_lam env reloc lam sz cont =
fun_code := [Ksequence(fcode,!fun_code)]
done;
let fv = !rfv in
- compile_fv reloc fv.fv_rev sz
+ compile_fv cenv fv.fv_rev sz
(Kclosurerec(fv.size,init,lbl_types,lbl_bodies) :: cont)
@@ -622,7 +626,7 @@ let rec compile_lam env reloc lam sz cont =
done;
let fv = !rfv in
set_max_stack_size (sz + fv.size + ndef + 2);
- compile_fv reloc fv.fv_rev sz
+ compile_fv cenv fv.fv_rev sz
(Kclosurecofix(fv.size, init, lbl_types, lbl_bodies) :: cont)
@@ -633,14 +637,14 @@ let rec compile_lam env reloc lam sz cont =
let lbl_consts = Array.make oib.mind_nb_constant Label.no in
let nallblock = oib.mind_nb_args + 1 in (* +1 : accumulate *)
let nconst = Array.length branches.constant_branches in
- let nblock = min nallblock (last_variant_tag + 1) in
+ let nblock = min nallblock (Obj.last_non_constant_constructor_tag + 1) in
let lbl_blocks = Array.make nblock Label.no in
- let neblock = max 0 (nallblock - last_variant_tag) in
+ let neblock = max 0 (nallblock - Obj.last_non_constant_constructor_tag) in
let lbl_eblocks = Array.make neblock Label.no in
let branch1, cont = make_branch cont in
(* Compilation of the return type *)
let fcode =
- ensure_stack_capacity (compile_lam env reloc t sz) [Kpop sz; Kstop]
+ ensure_stack_capacity (compile_lam env cenv t sz) [Kpop sz; Kstop]
in
let lbl_typ,fcode = label_code fcode in
fun_code := [Ksequence(fcode,!fun_code)];
@@ -661,14 +665,14 @@ let rec compile_lam env reloc lam sz cont =
let lbl_b, code_b =
label_code (
Kpush :: Kfield 0 :: Kswitch(lbl_eblocks, [||]) :: !c) in
- lbl_blocks.(last_variant_tag) <- lbl_b;
+ lbl_blocks.(Obj.last_non_constant_constructor_tag) <- lbl_b;
c := code_b
end;
(* Compilation of constant branches *)
for i = nconst - 1 downto 0 do
let aux =
- compile_lam env reloc branches.constant_branches.(i) sz_b (branch::!c)
+ compile_lam env cenv branches.constant_branches.(i) sz_b (branch::!c)
in
let lbl_b,code_b = label_code aux in
lbl_consts.(i) <- lbl_b;
@@ -680,10 +684,10 @@ let rec compile_lam env reloc lam sz cont =
let (ids, body) = branches.nonconstant_branches.(i) in
let arity = Array.length ids in
let code_b =
- compile_lam env (push_param arity sz_b reloc)
+ compile_lam env (push_param arity sz_b cenv)
body (sz_b+arity) (add_pop arity (branch::!c)) in
let code_b =
- if tag < last_variant_tag then begin
+ if tag < Obj.last_non_constant_constructor_tag then begin
set_max_stack_size (sz_b + arity);
Kpushfields arity :: code_b
end
@@ -693,8 +697,8 @@ let rec compile_lam env reloc lam sz cont =
end
in
let lbl_b, code_b = label_code code_b in
- if tag < last_variant_tag then lbl_blocks.(tag) <- lbl_b
- else lbl_eblocks.(tag - last_variant_tag) <- lbl_b;
+ if tag < Obj.last_non_constant_constructor_tag then lbl_blocks.(tag) <- lbl_b
+ else lbl_eblocks.(tag - Obj.last_non_constant_constructor_tag) <- lbl_b;
c := code_b
done;
@@ -718,25 +722,25 @@ let rec compile_lam env reloc lam sz cont =
| Kbranch lbl -> Kpush_retaddr lbl :: !c
| _ -> !c
in
- compile_lam env reloc a sz code_sw
+ compile_lam env cenv a sz code_sw
| Lmakeblock (tag,args) ->
let arity = Array.length args in
let cont = code_makeblock ~stack_size:(sz+arity-1) ~arity ~tag cont in
- comp_args (compile_lam env) reloc args sz cont
+ comp_args (compile_lam env) cenv args sz cont
| Lprim (kn, ar, op, args) ->
- op_compilation env ar op kn reloc args sz cont
+ op_compilation env ar op kn cenv args sz cont
| Luint v ->
(match v with
- | UintVal i -> compile_structured_constant reloc (Const_b0 (Uint31.to_int i)) sz cont
+ | UintVal i -> compile_structured_constant cenv (Const_b0 (Uint31.to_int i)) sz cont
| UintDigits ds ->
let nargs = Array.length ds in
if Int.equal nargs 31 then
let (escape,labeled_cont) = make_branch cont in
let else_lbl = Label.create() in
- comp_args (compile_lam env) reloc ds sz
+ comp_args (compile_lam env) cenv ds sz
( Kisconst else_lbl::Kareconst(30,else_lbl)::Kcompint31::escape::Klabel else_lbl::Kmakeblock(31, 1)::labeled_cont)
else
let code_construct cont = (* spiwack: variant of the global code_construct
@@ -752,40 +756,40 @@ let rec compile_lam env reloc lam sz cont =
Kclosure(lbl,0) :: cont
in
comp_app (fun _ _ _ cont -> code_construct cont)
- (compile_lam env) reloc () ds sz cont
+ (compile_lam env) cenv () ds sz cont
| UintDecomp t ->
let escape_lbl, labeled_cont = label_code cont in
- compile_lam env reloc t sz ((Kisconst escape_lbl)::Kdecompint31::labeled_cont))
+ compile_lam env cenv t sz ((Kisconst escape_lbl)::Kdecompint31::labeled_cont))
(* spiwack : compilation of constants with their arguments.
Makes a special treatment with 31-bit integer addition *)
-and compile_get_global reloc (kn,u) sz cont =
+and compile_get_global cenv (kn,u) sz cont =
set_max_stack_size sz;
if Univ.Instance.is_empty u then
Kgetglobal kn :: cont
else
comp_app (fun _ _ _ cont -> Kgetglobal kn :: cont)
- compile_universe reloc () (Univ.Instance.to_array u) sz cont
+ compile_universe cenv () (Univ.Instance.to_array u) sz cont
-and compile_universe reloc uni sz cont =
+and compile_universe cenv uni sz cont =
set_max_stack_size sz;
match Univ.Level.var_index uni with
- | None -> compile_structured_constant reloc (Const_univ_level uni) sz cont
- | Some idx -> pos_universe_var idx reloc sz :: cont
+ | None -> compile_structured_constant cenv (Const_univ_level uni) sz cont
+ | Some idx -> pos_universe_var idx cenv sz :: cont
-and compile_constant env reloc kn u args sz cont =
+and compile_constant env cenv kn u args sz cont =
set_max_stack_size sz;
if Univ.Instance.is_empty u then
(* normal compilation *)
comp_app (fun _ _ sz cont ->
- compile_get_global reloc (kn,u) sz cont)
- (compile_lam env) reloc () args sz cont
+ compile_get_global cenv (kn,u) sz cont)
+ (compile_lam env) cenv () args sz cont
else
- let compile_arg reloc constr_or_uni sz cont =
+ let compile_arg cenv constr_or_uni sz cont =
match constr_or_uni with
- | ArgLambda t -> compile_lam env reloc t sz cont
- | ArgUniv uni -> compile_universe reloc uni sz cont
+ | ArgLambda t -> compile_lam env cenv t sz cont
+ | ArgUniv uni -> compile_universe cenv uni sz cont
in
let u = Univ.Instance.to_array u in
let lu = Array.length u in
@@ -794,7 +798,7 @@ and compile_constant env reloc kn u args sz cont =
(fun i -> if i < lu then ArgUniv u.(i) else ArgLambda args.(i-lu))
in
comp_app (fun _ _ _ cont -> Kgetglobal kn :: cont)
- compile_arg reloc () all sz cont
+ compile_arg cenv () all sz cont
(*template for n-ary operation, invariant: n>=1,
the operations does the following :
@@ -803,34 +807,34 @@ and compile_constant env reloc kn u args sz cont =
3/ if at least one is not, branches to the normal behavior:
Kgetglobal (get_alias !global_env kn) *)
and op_compilation env n op =
- let code_construct reloc kn sz cont =
+ let code_construct cenv kn sz cont =
let f_cont =
let else_lbl = Label.create () in
Kareconst(n, else_lbl):: Kacc 0:: Kpop 1::
op:: Kreturn 0:: Klabel else_lbl::
(* works as comp_app with nargs = n and tailcall cont [Kreturn 0]*)
- compile_get_global reloc kn sz (
+ compile_get_global cenv kn sz (
Kappterm(n, n):: []) (* = discard_dead_code [Kreturn 0] *)
in
let lbl = Label.create () in
fun_code := [Ksequence (add_grab n lbl f_cont, !fun_code)];
Kclosure(lbl, 0)::cont
in
- fun kn reloc args sz cont ->
+ fun kn cenv args sz cont ->
let nargs = Array.length args in
if Int.equal nargs n then (*if it is a fully applied addition*)
let (escape, labeled_cont) = make_branch cont in
let else_lbl = Label.create () in
assert (n < 4);
- comp_args (compile_lam env) reloc args sz
+ comp_args (compile_lam env) cenv args sz
(Kisconst else_lbl::(make_areconst (n-1) else_lbl
(*Kaddint31::escape::Klabel else_lbl::Kpush::*)
(op::escape::Klabel else_lbl::Kpush::
(* works as comp_app with nargs < 4 and non-tailcall cont*)
- compile_get_global reloc kn (sz+n) (Kapply n::labeled_cont))))
+ compile_get_global cenv kn (sz+n) (Kapply n::labeled_cont))))
else
- comp_app (fun reloc _ sz cont -> code_construct reloc kn sz cont)
- (compile_lam env) reloc () args sz cont
+ comp_app (fun cenv _ sz cont -> code_construct cenv kn sz cont)
+ (compile_lam env) cenv () args sz cont
let is_univ_copy max u =
@@ -845,6 +849,8 @@ let is_univ_copy max u =
else
false
+let dump_bytecode = ref false
+
let dump_bytecodes init code fvs =
let open Pp in
(str "code =" ++ fnl () ++
@@ -859,11 +865,11 @@ let compile ~fail_on_error ?universes:(universes=0) env c =
Label.reset_label_counter ();
let cont = [Kstop] in
try
- let reloc, init_code =
+ let cenv, init_code =
if Int.equal universes 0 then
let lam = lambda_of_constr ~optimize:true env c in
- let reloc = empty_comp_env () in
- reloc, ensure_stack_capacity (compile_lam env reloc lam 0) cont
+ let cenv = empty_comp_env () in
+ cenv, ensure_stack_capacity (compile_lam env cenv lam 0) cont
else
(* We are going to generate a lambda, but merge the universe closure
* with the function closure if it exists.
@@ -871,7 +877,7 @@ let compile ~fail_on_error ?universes:(universes=0) env c =
let lam = lambda_of_constr ~optimize:true env c in
let params, body = decompose_Llam lam in
let arity = Array.length params in
- let reloc = empty_comp_env () in
+ let cenv = empty_comp_env () in
let full_arity = arity + universes in
let r_fun = comp_env_fun ~univs:universes arity in
let lbl_fun = Label.create () in
@@ -882,13 +888,13 @@ let compile ~fail_on_error ?universes:(universes=0) env c =
fun_code := [Ksequence(add_grab full_arity lbl_fun cont_fun,!fun_code)];
let fv = fv r_fun in
let init_code =
- ensure_stack_capacity (compile_fv reloc fv.fv_rev 0)
+ ensure_stack_capacity (compile_fv cenv fv.fv_rev 0)
(Kclosure(lbl_fun,fv.size) :: cont)
in
- reloc, init_code
+ cenv, init_code
in
- let fv = List.rev (!(reloc.in_env).fv_rev) in
- (if !Flags.dump_bytecode then
+ let fv = List.rev (!(cenv.in_env).fv_rev) in
+ (if !dump_bytecode then
Feedback.msg_debug (dump_bytecodes init_code !fun_code fv)) ;
Some (init_code,!fun_code, Array.of_list fv)
with TooLargeInductive msg ->
@@ -935,13 +941,13 @@ let op2_compilation op =
fun_code := [Ksequence (add_grab 2 lbl f_cont, !fun_code)];
Kclosure(lbl, 0)::cont
in
- fun normal fc _ reloc args sz cont ->
+ fun normal fc _ cenv args sz cont ->
if not fc then raise Not_found else
let nargs = Array.length args in
if nargs=2 then (*if it is a fully applied addition*)
let (escape, labeled_cont) = make_branch cont in
let else_lbl = Label.create () in
- comp_args compile_constr reloc args sz
+ comp_args compile_constr cenv args sz
(Kisconst else_lbl::(make_areconst 1 else_lbl
(*Kaddint31::escape::Klabel else_lbl::Kpush::*)
(op::escape::Klabel else_lbl::Kpush::
@@ -953,5 +959,5 @@ let op2_compilation op =
code_construct normal cont
else
comp_app (fun _ _ _ cont -> code_construct normal cont)
- compile_constr reloc () args sz cont *)
+ compile_constr cenv () args sz cont *)
diff --git a/kernel/cbytegen.mli b/kernel/cbytegen.mli
index abab58b6..57d3e6fc 100644
--- a/kernel/cbytegen.mli
+++ b/kernel/cbytegen.mli
@@ -12,7 +12,7 @@ open Cbytecodes
open Cemitcodes
open Constr
open Declarations
-open Pre_env
+open Environ
(** Should only be used for monomorphic terms *)
val compile : fail_on_error:bool ->
@@ -25,3 +25,6 @@ val compile_constant_body : fail_on_error:bool ->
(** Shortcut of the previous function used during module strengthening *)
val compile_alias : Names.Constant.t -> body_code
+
+(** Dump the bytecode after compilation (for debugging purposes) *)
+val dump_bytecode : bool ref
diff --git a/kernel/cemitcodes.ml b/kernel/cemitcodes.ml
index 14f4f27c..50f5607e 100644
--- a/kernel/cemitcodes.ml
+++ b/kernel/cemitcodes.ml
@@ -13,20 +13,22 @@
(* Extension: Arnaud Spiwack (support for native arithmetic), May 2005 *)
open Names
-open Term
+open Constr
+open Vmvalues
open Cbytecodes
open Copcodes
open Mod_subst
type emitcodes = String.t
-external tcode_of_code : Bytes.t -> int -> Vmvalues.tcode = "coq_tcode_of_code"
+external tcode_of_code : Bytes.t -> Vmvalues.tcode = "coq_tcode_of_code"
(* Relocation information *)
type reloc_info =
| Reloc_annot of annot_switch
| Reloc_const of structured_constant
| Reloc_getglobal of Names.Constant.t
+ | Reloc_proj_name of Projection.Repr.t
let eq_reloc_info r1 r2 = match r1, r2 with
| Reloc_annot sw1, Reloc_annot sw2 -> eq_annot_switch sw1 sw2
@@ -35,6 +37,8 @@ let eq_reloc_info r1 r2 = match r1, r2 with
| Reloc_const _, _ -> false
| Reloc_getglobal c1, Reloc_getglobal c2 -> Constant.equal c1 c2
| Reloc_getglobal _, _ -> false
+| Reloc_proj_name p1, Reloc_proj_name p2 -> Projection.Repr.equal p1 p2
+| Reloc_proj_name _, _ -> false
let hash_reloc_info r =
let open Hashset.Combine in
@@ -42,6 +46,7 @@ let hash_reloc_info r =
| Reloc_annot sw -> combinesmall 1 (hash_annot_switch sw)
| Reloc_const c -> combinesmall 2 (hash_structured_constant c)
| Reloc_getglobal c -> combinesmall 3 (Constant.hash c)
+ | Reloc_proj_name p -> combinesmall 4 (Projection.Repr.hash p)
module RelocTable = Hashtbl.Make(struct
type t = reloc_info
@@ -82,7 +87,7 @@ let patch buff pl f =
(** Order seems important here? *)
let reloc = CArray.map (fun (r, pos) -> (f r, pos)) pl.reloc_infos in
let buff = patch_int buff reloc in
- tcode_of_code buff (Bytes.length buff)
+ tcode_of_code buff
(* Buffering of bytecode *)
@@ -187,6 +192,9 @@ let slot_for_getglobal env p =
enter env (Reloc_getglobal p);
out_int env 0
+let slot_for_proj_name env p =
+ enter env (Reloc_proj_name p);
+ out_int env 0
(* Emission of one instruction *)
@@ -277,7 +285,7 @@ let emit_instr env = function
if n <= 1 then out env (opSETFIELD0+n)
else (out env opSETFIELD;out_int env n)
| Ksequence _ -> invalid_arg "Cemitcodes.emit_instr"
- | Kproj (n,p) -> out env opPROJ; out_int env n; slot_for_const env (Const_proj p)
+ | Kproj p -> out env opPROJ; out_int env (Projection.Repr.arg p); slot_for_proj_name env p
| Kensurestackcapacity size -> out env opENSURESTACKCAPACITY; out_int env size
(* spiwack *)
| Kbranch lbl -> out env opBRANCH; out_label env lbl
@@ -350,11 +358,9 @@ let rec emit env insns remaining = match insns with
type to_patch = emitcodes * patches * fv
(* Substitution *)
-let rec subst_strcst s sc =
+let subst_strcst s sc =
match sc with
- | Const_sort _ | Const_b0 _ | Const_univ_level _ -> sc
- | Const_proj p -> Const_proj (subst_constant s p)
- | Const_bn(tag,args) -> Const_bn(tag,Array.map (subst_strcst s) args)
+ | Const_sort _ | Const_b0 _ | Const_univ_level _ | Const_val _ -> sc
| Const_ind ind -> let kn,i = ind in Const_ind (subst_mind s kn, i)
let subst_reloc s ri =
@@ -365,6 +371,7 @@ let subst_reloc s ri =
Reloc_annot {a with ci = ci}
| Reloc_const sc -> Reloc_const (subst_strcst s sc)
| Reloc_getglobal kn -> Reloc_getglobal (subst_constant s kn)
+ | Reloc_proj_name p -> Reloc_proj_name (subst_proj_repr s p)
let subst_patches subst p =
let infos = CArray.map (fun (r, pos) -> (subst_reloc subst r, pos)) p.reloc_infos in
diff --git a/kernel/cemitcodes.mli b/kernel/cemitcodes.mli
index 03920dc1..39ddf4a0 100644
--- a/kernel/cemitcodes.mli
+++ b/kernel/cemitcodes.mli
@@ -1,10 +1,12 @@
open Names
+open Vmvalues
open Cbytecodes
type reloc_info =
| Reloc_annot of annot_switch
| Reloc_const of structured_constant
| Reloc_getglobal of Constant.t
+ | Reloc_proj_name of Projection.Repr.t
type patches
type emitcodes
diff --git a/kernel/cinstr.mli b/kernel/cinstr.mli
index f42c4617..dca1757b 100644
--- a/kernel/cinstr.mli
+++ b/kernel/cinstr.mli
@@ -9,6 +9,7 @@
(************************************************************************)
open Names
open Constr
+open Vmvalues
open Cbytecodes
(** This file defines the lambda code for the bytecode compiler. It has been
@@ -33,10 +34,11 @@ and lambda =
| Lfix of (int array * int) * fix_decl
| Lcofix of int * fix_decl (* must be in eta-expanded form *)
| Lmakeblock of int * lambda array
- | Lval of structured_constant
+ | Lval of structured_values
| Lsort of Sorts.t
| Lind of pinductive
- | Lproj of int * Constant.t * lambda
+ | Lproj of Projection.Repr.t * lambda
+ | Lint of int
| Luint of uint
(* Cofixpoints have to be in eta-expanded form for their call-by-need evaluation
diff --git a/kernel/clambda.ml b/kernel/clambda.ml
index c39f4259..7c930b3f 100644
--- a/kernel/clambda.ml
+++ b/kernel/clambda.ml
@@ -4,9 +4,10 @@ open Esubst
open Term
open Constr
open Declarations
+open Vmvalues
open Cbytecodes
open Cinstr
-open Pre_env
+open Environ
open Pp
let pr_con sp = str(Names.Label.to_string (Constant.label sp))
@@ -111,10 +112,12 @@ let rec pp_lam lam =
(str "(PRIM " ++ pr_con kn ++ spc() ++
prlist_with_sep spc pp_lam (Array.to_list args) ++
str")")
- | Lproj(i,kn,arg) ->
+ | Lproj(p,arg) ->
hov 1
- (str "(proj#" ++ int i ++ spc() ++ pr_con kn ++ str "(" ++ pp_lam arg
+ (str "(proj " ++ Projection.Repr.print p ++ str "(" ++ pp_lam arg
++ str ")")
+ | Lint i ->
+ Pp.(str "(int:" ++ int i ++ str ")")
| Luint _ ->
str "(uint)"
@@ -150,9 +153,9 @@ let shift subst = subs_shft (1, subst)
let rec map_lam_with_binders g f n lam =
match lam with
- | Lrel _ | Lvar _ | Lconst _ | Lval _ | Lsort _ | Lind _ -> lam
+ | Lrel _ | Lvar _ | Lconst _ | Lval _ | Lsort _ | Lind _ | Lint _ -> lam
| Levar (evk, args) ->
- let args' = Array.smartmap (f n) args in
+ let args' = Array.Smart.map (f n) args in
if args == args' then lam else Levar (evk, args')
| Lprod(dom,codom) ->
let dom' = f n dom in
@@ -167,19 +170,19 @@ let rec map_lam_with_binders g f n lam =
if body == body' && def == def' then lam else Llet(id,def',body')
| Lapp(fct,args) ->
let fct' = f n fct in
- let args' = Array.smartmap (f n) args in
+ let args' = Array.Smart.map (f n) args in
if fct == fct' && args == args' then lam else mkLapp fct' args'
| Lcase(ci,rtbl,t,a,branches) ->
let const = branches.constant_branches in
let nonconst = branches.nonconstant_branches in
let t' = f n t in
let a' = f n a in
- let const' = Array.smartmap (f n) const in
+ let const' = Array.Smart.map (f n) const in
let on_b b =
let (ids,body) = b in
let body' = f (g (Array.length ids) n) body in
if body == body' then b else (ids,body') in
- let nonconst' = Array.smartmap on_b nonconst in
+ let nonconst' = Array.Smart.map on_b nonconst in
let branches' =
if const == const' && nonconst == nonconst' then
branches
@@ -190,24 +193,24 @@ let rec map_lam_with_binders g f n lam =
if t == t' && a == a' && branches == branches' then lam else
Lcase(ci,rtbl,t',a',branches')
| Lfix(init,(ids,ltypes,lbodies)) ->
- let ltypes' = Array.smartmap (f n) ltypes in
- let lbodies' = Array.smartmap (f (g (Array.length ids) n)) lbodies in
+ let ltypes' = Array.Smart.map (f n) ltypes in
+ let lbodies' = Array.Smart.map (f (g (Array.length ids) n)) lbodies in
if ltypes == ltypes' && lbodies == lbodies' then lam
else Lfix(init,(ids,ltypes',lbodies'))
| Lcofix(init,(ids,ltypes,lbodies)) ->
- let ltypes' = Array.smartmap (f n) ltypes in
- let lbodies' = Array.smartmap (f (g (Array.length ids) n)) lbodies in
+ let ltypes' = Array.Smart.map (f n) ltypes in
+ let lbodies' = Array.Smart.map (f (g (Array.length ids) n)) lbodies in
if ltypes == ltypes' && lbodies == lbodies' then lam
else Lcofix(init,(ids,ltypes',lbodies'))
| Lmakeblock(tag,args) ->
- let args' = Array.smartmap (f n) args in
+ let args' = Array.Smart.map (f n) args in
if args == args' then lam else Lmakeblock(tag,args')
| Lprim(kn,ar,op,args) ->
- let args' = Array.smartmap (f n) args in
+ let args' = Array.Smart.map (f n) args in
if args == args' then lam else Lprim(kn,ar,op,args')
- | Lproj(i,kn,arg) ->
+ | Lproj(p,arg) ->
let arg' = f n arg in
- if arg == arg' then lam else Lproj(i,kn,arg')
+ if arg == arg' then lam else Lproj(p,arg')
| Luint u ->
let u' = map_uint g f n u in
if u == u' then lam else Luint u'
@@ -216,7 +219,7 @@ and map_uint g f n u =
match u with
| UintVal _ -> u
| UintDigits(args) ->
- let args' = Array.smartmap (f n) args in
+ let args' = Array.Smart.map (f n) args in
if args == args' then u else UintDigits(args')
| UintDecomp(a) ->
let a' = f n a in
@@ -250,7 +253,7 @@ let rec lam_exsubst subst lam =
let lam_subst_args subst args =
if is_subs_id subst then args
- else Array.smartmap (lam_exsubst subst) args
+ else Array.Smart.map (lam_exsubst subst) args
(** Simplification of lambda expression *)
@@ -316,7 +319,7 @@ and simplify_app substf f substa args =
simplify_app substf f subst_id args
| _ -> mkLapp (simplify substf f) (simplify_args substa args)
-and simplify_args subst args = Array.smartmap (simplify subst) args
+and simplify_args subst args = Array.Smart.map (simplify subst) args
and reduce_lapp substf lids body substa largs =
match lids, largs with
@@ -349,7 +352,7 @@ let rec occurrence k kind lam =
if n = k then
if kind then false else raise Not_found
else kind
- | Lvar _ | Lconst _ | Lval _ | Lsort _ | Lind _ -> kind
+ | Lvar _ | Lconst _ | Lval _ | Lsort _ | Lind _ | Lint _ -> kind
| Levar (_, args) ->
occurrence_args k kind args
| Lprod(dom, codom) ->
@@ -376,7 +379,7 @@ let rec occurrence k kind lam =
let kind = occurrence_args k kind ltypes in
let _ = occurrence_args (k+Array.length ids) false lbodies in
kind
- | Lproj(_,_,arg) ->
+ | Lproj(_,arg) ->
occurrence k kind arg
| Luint u -> occurrence_uint k kind u
@@ -419,7 +422,7 @@ let rec remove_let subst lam =
exception TooLargeInductive of Pp.t
let max_nb_const = 0x1000000
-let max_nb_block = 0x1000000 + last_variant_tag - 1
+let max_nb_block = 0x1000000 + Obj.last_non_constant_constructor_tag - 1
let str_max_constructors =
Format.sprintf
@@ -436,23 +439,22 @@ let check_compilable ib =
let is_value lc =
match lc with
- | Lval _ -> true
+ | Lval _ | Lint _ -> true
| _ -> false
let get_value lc =
match lc with
| Lval v -> v
+ | Lint i -> val_of_int i
| _ -> raise Not_found
-let mkConst_b0 n = Lval (Cbytecodes.Const_b0 n)
-
let make_args start _end =
Array.init (start - _end + 1) (fun i -> Lrel (Anonymous, start - i))
(* Translation of constructors *)
let expand_constructor tag nparams arity =
let ids = Array.make (nparams + arity) Anonymous in
- if arity = 0 then mkLlam ids (mkConst_b0 tag)
+ if arity = 0 then mkLlam ids (Lint tag)
else
let args = make_args arity 1 in
Llam(ids, Lmakeblock (tag, args))
@@ -463,15 +465,15 @@ let makeblock tag nparams arity args =
mkLapp (expand_constructor tag nparams arity) args
else
(* The constructor is fully applied *)
- if arity = 0 then mkConst_b0 tag
+ if arity = 0 then Lint tag
else
if Array.for_all is_value args then
- if tag < last_variant_tag then
- Lval(Cbytecodes.Const_bn(tag, Array.map get_value args))
+ if tag < Obj.last_non_constant_constructor_tag then
+ Lval(val_of_block tag (Array.map get_value args))
else
let args = Array.map get_value args in
- let args = Array.append [|Cbytecodes.Const_b0 (tag - last_variant_tag) |] args in
- Lval(Cbytecodes.Const_bn(last_variant_tag, args))
+ let args = Array.append [| val_of_int (tag - Obj.last_non_constant_constructor_tag) |] args in
+ Lval(val_of_block Obj.last_non_constant_constructor_tag args)
else Lmakeblock(tag, args)
@@ -605,8 +607,6 @@ end
open Renv
-let (eta_expand,eta_expand_hook) = Hook.make ()
-
let rec lambda_of_constr env c =
match Constr.kind c with
| Meta _ -> raise (Invalid_argument "Cbytegen.lambda_of_constr: Meta")
@@ -702,7 +702,7 @@ let rec lambda_of_constr env c =
Lfix(rec_init, (names, ltypes, lbodies))
| CoFix(init,(names,type_bodies,rec_bodies)) ->
- let rec_bodies = Array.map2 (Hook.get eta_expand env.global_env) rec_bodies type_bodies in
+ let rec_bodies = Array.map2 (Reduction.eta_expand env.global_env) rec_bodies type_bodies in
let ltypes = lambda_of_args env 0 type_bodies in
Renv.push_rels env names;
let lbodies = lambda_of_args env 0 rec_bodies in
@@ -710,12 +710,8 @@ let rec lambda_of_constr env c =
Lcofix(init, (names, ltypes, lbodies))
| Proj (p,c) ->
- let kn = Projection.constant p in
- let cb = lookup_constant kn env.global_env in
- let pb = Option.get cb.const_proj in
- let n = pb.proj_arg in
let lc = lambda_of_constr env c in
- Lproj (n,kn,lc)
+ Lproj (Projection.repr p,lc)
and lambda_of_app env f args =
match Constr.kind f with
@@ -767,7 +763,7 @@ and lambda_of_app env f args =
and such, which can't be done at this time.
for instance, for int31: if one of the digit is
not closed, it's not impossible that the number
- gets fully instanciated at run-time, thus to ensure
+ gets fully instantiated at run-time, thus to ensure
uniqueness of the representation in the vm
it is necessary to try and build a caml integer
during the execution *)
@@ -810,7 +806,7 @@ and lambda_of_args env start args =
(*********************************)
-
+let dump_lambda = ref false
let optimize_lambda lam =
let lam = simplify subst_id lam in
@@ -818,11 +814,11 @@ let optimize_lambda lam =
let lambda_of_constr ~optimize genv c =
let env = Renv.make genv in
- let ids = List.rev_map Context.Rel.Declaration.get_name genv.env_rel_context.env_rel_ctx in
+ let ids = List.rev_map Context.Rel.Declaration.get_name (rel_context genv) in
Renv.push_rels env (Array.of_list ids);
let lam = lambda_of_constr env c in
let lam = if optimize then optimize_lambda lam else lam in
- if !Flags.dump_lambda then
+ if !dump_lambda then
Feedback.msg_debug (pp_lam lam);
lam
@@ -840,10 +836,11 @@ let dynamic_int31_compilation fc args =
if not fc then raise Not_found else
Luint (UintDigits args)
+let d0 = Lint 0
+let d1 = Lint 1
+
(* We are relying here on the tags of digits constructors *)
let digits_from_uint i =
- let d0 = mkConst_b0 0 in
- let d1 = mkConst_b0 1 in
let digits = Array.make 31 d0 in
for k = 0 to 30 do
if Int.equal ((Uint31.to_int i lsr k) land 1) 1 then
diff --git a/kernel/clambda.mli b/kernel/clambda.mli
index 827eb550..8ff10b45 100644
--- a/kernel/clambda.mli
+++ b/kernel/clambda.mli
@@ -1,13 +1,14 @@
open Names
open Cinstr
+open Environ
exception TooLargeInductive of Pp.t
-val lambda_of_constr : optimize:bool -> Pre_env.env -> Constr.t -> lambda
+val lambda_of_constr : optimize:bool -> env -> Constr.t -> lambda
val decompose_Llam : lambda -> Name.t array * lambda
-val get_alias : Pre_env.env -> Constant.t -> Constant.t
+val get_alias : env -> Constant.t -> Constant.t
val compile_prim : int -> Cbytecodes.instruction -> Constr.pconstant -> bool -> lambda array -> lambda
@@ -26,5 +27,5 @@ val dynamic_int31_compilation : bool -> lambda array -> lambda
matching integers (in case they are in processor representation) *)
val int31_escape_before_match : bool -> lambda -> lambda
-val eta_expand : (Pre_env.env -> Constr.t -> Constr.types -> Constr.t) Hook.value
-val eta_expand_hook : (Pre_env.env -> Constr.t -> Constr.types -> Constr.t) Hook.t
+(** Dump the VM lambda code after compilation (for debugging purposes) *)
+val dump_lambda : bool ref
diff --git a/kernel/constr.ml b/kernel/constr.ml
index de4e7c18..9bf74315 100644
--- a/kernel/constr.ml
+++ b/kernel/constr.ml
@@ -107,21 +107,13 @@ type t = (t, t, Sorts.t, Instance.t) kind_of_term
type constr = t
type existential = existential_key * constr array
-type rec_declaration = Name.t array * constr array * constr array
-type fixpoint = (int array * int) * rec_declaration
- (* The array of [int]'s tells for each component of the array of
- mutual fixpoints the number of lambdas to skip before finding the
- recursive argument (e.g., value is 2 in "fix f (x:A) (y:=t) (z:B)
- (v:=u) (w:I) {struct w}"), telling to skip x and z and that w is
- the recursive argument);
- The second component [int] tells which component of the block is
- returned *)
-type cofixpoint = int * rec_declaration
- (* The component [int] tells which component of the block of
- cofixpoint is returned *)
type types = constr
+type rec_declaration = (constr, types) prec_declaration
+type fixpoint = (constr, types) pfixpoint
+type cofixpoint = (constr, types) pcofixpoint
+
(*********************)
(* Term constructors *)
(*********************)
@@ -138,8 +130,8 @@ let mkProp = Sort Sorts.prop
let mkSet = Sort Sorts.set
let mkType u = Sort (Sorts.Type u)
let mkSort = function
- | Sorts.Prop Sorts.Null -> mkProp (* Easy sharing *)
- | Sorts.Prop Sorts.Pos -> mkSet
+ | Sorts.Prop -> mkProp (* Easy sharing *)
+ | Sorts.Set -> mkSet
| s -> Sort s
(* Constructs the term t1::t2, i.e. the term t1 casted with the type t2 *)
@@ -268,17 +260,17 @@ let isSort c = match kind c with
| _ -> false
let rec isprop c = match kind c with
- | Sort (Sorts.Prop _) -> true
+ | Sort (Sorts.Prop | Sorts.Set) -> true
| Cast (c,_,_) -> isprop c
| _ -> false
let rec is_Prop c = match kind c with
- | Sort (Sorts.Prop Sorts.Null) -> true
+ | Sort Sorts.Prop -> true
| Cast (c,_,_) -> is_Prop c
| _ -> false
let rec is_Set c = match kind c with
- | Sort (Sorts.Prop Sorts.Pos) -> true
+ | Sort Sorts.Set -> true
| Cast (c,_,_) -> is_Set c
| _ -> false
@@ -468,16 +460,16 @@ let iter_with_binders g f n c = match kind c with
| Prod (_,t,c) -> f n t; f (g n) c
| Lambda (_,t,c) -> f n t; f (g n) c
| LetIn (_,b,t,c) -> f n b; f n t; f (g 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 (_,(_,tl,bl)) ->
- CArray.Fun1.iter f n tl;
- CArray.Fun1.iter f (iterate g (Array.length tl) n) bl
+ Array.Fun1.iter f n tl;
+ Array.Fun1.iter f (iterate g (Array.length tl) n) bl
| CoFix (_,(_,tl,bl)) ->
- CArray.Fun1.iter f n tl;
- CArray.Fun1.iter f (iterate g (Array.length tl) n) bl
+ Array.Fun1.iter f n tl;
+ Array.Fun1.iter f (iterate g (Array.length tl) n) bl
(* [fold_constr_with_binders g f n acc c] folds [f n] on the immediate
subterms of [c] starting from [acc] and proceeding from left to
@@ -537,7 +529,7 @@ let map f c = match kind 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) ->
@@ -545,23 +537,23 @@ let map f c = match kind 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'))
@@ -593,7 +585,7 @@ let fold_map f accu c = match kind c with
else accu, mkLetIn (na, b', t', k')
| App (b,l) ->
let accu, b' = f accu b in
- let accu, l' = Array.smartfoldmap f accu l in
+ let accu, l' = Array.Smart.fold_left_map f accu l in
if b'==b && l'==l then accu, c
else accu, mkApp (b', l')
| Proj (p,t) ->
@@ -601,23 +593,23 @@ let fold_map f accu c = match kind c with
if t' == t then accu, c
else accu, mkProj (p, t')
| Evar (e,l) ->
- let accu, l' = Array.smartfoldmap f accu l in
+ let accu, l' = Array.Smart.fold_left_map f accu l in
if l'==l then accu, c
else accu, mkEvar (e, l')
| Case (ci,p,b,bl) ->
let accu, b' = f accu b in
let accu, p' = f accu p in
- let accu, bl' = Array.smartfoldmap f accu bl in
+ let accu, bl' = Array.Smart.fold_left_map f accu bl in
if b'==b && p'==p && bl'==bl then accu, c
else accu, mkCase (ci, p', b', bl')
| Fix (ln,(lna,tl,bl)) ->
- let accu, tl' = Array.smartfoldmap f accu tl in
- let accu, bl' = Array.smartfoldmap f accu bl in
+ let accu, tl' = Array.Smart.fold_left_map f accu tl in
+ let accu, bl' = Array.Smart.fold_left_map f accu bl in
if tl'==tl && bl'==bl then accu, c
else accu, mkFix (ln,(lna,tl',bl'))
| CoFix(ln,(lna,tl,bl)) ->
- let accu, tl' = Array.smartfoldmap f accu tl in
- let accu, bl' = Array.smartfoldmap f accu bl in
+ let accu, tl' = Array.Smart.fold_left_map f accu tl in
+ let accu, bl' = Array.Smart.fold_left_map f accu bl in
if tl'==tl && bl'==bl then accu, c
else accu, mkCoFix (ln,(lna,tl',bl'))
@@ -653,7 +645,7 @@ let map_with_binders g f l c0 = match kind 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) ->
@@ -661,28 +653,28 @@ let map_with_binders g f l c0 = match kind 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'))
-type instance_compare_fn = global_reference -> int ->
+type instance_compare_fn = GlobRef.t -> int ->
Univ.Instance.t -> Univ.Instance.t -> bool
type constr_compare_fn = int -> constr -> constr -> bool
@@ -720,10 +712,10 @@ let compare_head_gen_leq_with kind1 kind2 leq_universes leq_sorts eq leq nargs t
| Evar (e1,l1), Evar (e2,l2) -> Evar.equal e1 e2 && Array.equal (eq 0) l1 l2
| Const (c1,u1), Const (c2,u2) ->
(* The args length currently isn't used but may as well pass it. *)
- Constant.equal c1 c2 && leq_universes (ConstRef c1) nargs u1 u2
- | Ind (c1,u1), Ind (c2,u2) -> eq_ind c1 c2 && leq_universes (IndRef c1) nargs u1 u2
+ Constant.equal c1 c2 && leq_universes (GlobRef.ConstRef c1) nargs u1 u2
+ | Ind (c1,u1), Ind (c2,u2) -> eq_ind c1 c2 && leq_universes (GlobRef.IndRef c1) nargs u1 u2
| Construct (c1,u1), Construct (c2,u2) ->
- eq_constructor c1 c2 && leq_universes (ConstructRef c1) nargs u1 u2
+ eq_constructor c1 c2 && leq_universes (GlobRef.ConstructRef c1) nargs u1 u2
| Case (_,p1,c1,bl1), Case (_,p2,c2,bl2) ->
eq 0 p1 p2 && eq 0 c1 c2 && Array.equal (eq 0) bl1 bl2
| Fix ((ln1, i1),(_,tl1,bl1)), Fix ((ln2, i2),(_,tl2,bl2)) ->
@@ -1217,3 +1209,10 @@ let hcons =
Id.hcons)
(* let hcons_types = hcons_constr *)
+
+type rel_declaration = (constr, types) Context.Rel.Declaration.pt
+type named_declaration = (constr, types) Context.Named.Declaration.pt
+type compacted_declaration = (constr, types) Context.Compacted.Declaration.pt
+type rel_context = rel_declaration list
+type named_context = named_declaration list
+type compacted_context = compacted_declaration list
diff --git a/kernel/constr.mli b/kernel/constr.mli
index c1d1f988..70acf193 100644
--- a/kernel/constr.mli
+++ b/kernel/constr.mli
@@ -161,8 +161,26 @@ val mkCase : case_info * constr * constr * constr array -> constr
where the length of the {% $ %}j{% $ %}th context is {% $ %}ij{% $ %}.
*)
-type rec_declaration = Name.t array * types array * constr array
-type fixpoint = (int array * int) * rec_declaration
+type ('constr, 'types) prec_declaration =
+ Name.t array * 'types array * 'constr array
+type ('constr, 'types) pfixpoint =
+ (int array * int) * ('constr, 'types) prec_declaration
+ (* The array of [int]'s tells for each component of the array of
+ mutual fixpoints the number of lambdas to skip before finding the
+ recursive argument (e.g., value is 2 in "fix f (x:A) (y:=t) (z:B)
+ (v:=u) (w:I) {struct w}"), telling to skip x and z and that w is
+ the recursive argument);
+ The second component [int] tells which component of the block is
+ returned *)
+
+type ('constr, 'types) pcofixpoint =
+ int * ('constr, 'types) prec_declaration
+ (* The component [int] tells which component of the block of
+ cofixpoint is returned *)
+
+type rec_declaration = (constr, types) prec_declaration
+
+type fixpoint = (constr, types) pfixpoint
val mkFix : fixpoint -> constr
(** If [funnames = [|f1,.....fn|]]
@@ -176,7 +194,7 @@ val mkFix : fixpoint -> constr
...
with fn = bn.]
*)
-type cofixpoint = int * rec_declaration
+type cofixpoint = (constr, types) pcofixpoint
val mkCoFix : cofixpoint -> constr
@@ -185,12 +203,6 @@ val mkCoFix : cofixpoint -> constr
(** [constr array] is an instance matching definitional [named_context] in
the same order (i.e. last argument first) *)
type 'constr pexistential = Evar.t * 'constr array
-type ('constr, 'types) prec_declaration =
- Name.t array * 'types array * 'constr array
-type ('constr, 'types) pfixpoint =
- (int array * int) * ('constr, 'types) prec_declaration
-type ('constr, 'types) pcofixpoint =
- int * ('constr, 'types) prec_declaration
type ('constr, 'types, 'sort, 'univs) kind_of_term =
| Rel of int (** Gallina-variable introduced by [forall], [fun], [let-in], [fix], or [cofix]. *)
@@ -360,6 +372,15 @@ val eq_constr_nounivs : constr -> constr -> bool
(** Total ordering compatible with [equal] *)
val compare : constr -> constr -> int
+(** {6 Extension of Context with declarations on constr} *)
+
+type rel_declaration = (constr, types) Context.Rel.Declaration.pt
+type named_declaration = (constr, types) Context.Named.Declaration.pt
+type compacted_declaration = (constr, types) Context.Compacted.Declaration.pt
+type rel_context = rel_declaration list
+type named_context = named_declaration list
+type compacted_context = compacted_declaration list
+
(** {6 Functionals working on the immediate subterm of a construction } *)
(** [fold f acc c] folds [f] on the immediate subterms of [c]
@@ -422,7 +443,7 @@ val compare_head : constr_compare_fn -> constr_compare_fn
(** Convert a global reference applied to 2 instances. The int says
how many arguments are given (as we can only use cumulativity for
fully applied inductives/constructors) .*)
-type instance_compare_fn = global_reference -> int ->
+type instance_compare_fn = GlobRef.t -> int ->
Univ.Instance.t -> Univ.Instance.t -> bool
(** [compare_head_gen u s f c1 c2] compare [c1] and [c2] using [f] to
diff --git a/kernel/context.ml b/kernel/context.ml
index 4f3f649c..4a7204b7 100644
--- a/kernel/context.ml
+++ b/kernel/context.ml
@@ -43,8 +43,6 @@ struct
| LocalAssum of Name.t * 'types (** name, type *)
| LocalDef of Name.t * 'constr * 'types (** name, value, type *)
- type t = (Constr.constr, Constr.types) pt
-
(** Return the name bound by a given declaration. *)
let get_name = function
| LocalAssum (na,_)
@@ -151,13 +149,16 @@ struct
| LocalAssum (na, ty) -> na, None, ty
| LocalDef (na, v, ty) -> na, Some v, ty
+ let drop_body = function
+ | LocalAssum _ as d -> d
+ | LocalDef (na, v, ty) -> LocalAssum (na, ty)
+
end
(** Rel-context is represented as a list of declarations.
Inner-most declarations are at the beginning of the list.
Outer-most declarations are at the end of the list. *)
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
- type t = Declaration.t list
(** empty rel-context *)
let empty = []
@@ -192,7 +193,7 @@ struct
let equal eq l = List.equal (fun c -> Declaration.equal eq c) l
(** Map all terms in a given rel-context. *)
- let map f = List.smartmap (Declaration.map_constr f)
+ let map f = List.Smart.map (Declaration.map_constr f)
(** Perform a given action on every declaration in a given rel-context. *)
let iter f = List.iter (Declaration.iter_constr f)
@@ -214,6 +215,8 @@ struct
| Declaration.LocalAssum _ :: ctx -> aux (false::l) ctx
in aux [] l
+ let drop_bodies l = List.Smart.map Declaration.drop_body l
+
(** [extended_list n Γ] builds an instance [args] such that [Γ,Δ ⊢ args:Γ]
with n = |Δ| and with the {e local definitions} of [Γ] skipped in
[args]. Example: for [x:T, y:=c, z:U] and [n]=2, it gives [Rel 5, Rel 3]. *)
@@ -241,8 +244,6 @@ struct
| LocalAssum of Id.t * 'types (** identifier, type *)
| LocalDef of Id.t * 'constr * 'types (** identifier, value, type *)
- type t = (Constr.constr, Constr.types) pt
-
(** Return the identifier bound by a given declaration. *)
let get_id = function
| LocalAssum (id,_) -> id
@@ -353,6 +354,10 @@ struct
| id, None, ty -> LocalAssum (id, ty)
| id, Some v, ty -> LocalDef (id, v, ty)
+ let drop_body = function
+ | LocalAssum _ as d -> d
+ | LocalDef (id, v, ty) -> LocalAssum (id, ty)
+
let of_rel_decl f = function
| Rel.Declaration.LocalAssum (na,t) ->
LocalAssum (f na, t)
@@ -370,7 +375,6 @@ struct
Inner-most declarations are at the beginning of the list.
Outer-most declarations are at the end of the list. *)
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
- type t = Declaration.t list
(** empty named-context *)
let empty = []
@@ -392,7 +396,7 @@ struct
let equal eq l = List.equal (fun c -> Declaration.equal eq c) l
(** Map all terms in a given named-context. *)
- let map f = List.smartmap (Declaration.map_constr f)
+ let map f = List.Smart.map (Declaration.map_constr f)
(** Perform a given action on every declaration in a given named-context. *)
let iter f = List.iter (Declaration.iter_constr f)
@@ -409,6 +413,8 @@ struct
let to_vars l =
List.fold_left (fun accu decl -> Id.Set.add (Declaration.get_id decl) accu) Id.Set.empty l
+ let drop_bodies l = List.Smart.map Declaration.drop_body l
+
(** [instance_from_named_context Ω] builds an instance [args] such
that [Ω ⊢ args:Ω] where [Ω] is a named context and with the local
definitions of [Ω] skipped. Example: for [id1:T,id2:=c,id3:U], it
@@ -429,8 +435,6 @@ module Compacted =
| LocalAssum of Id.t list * 'types
| LocalDef of Id.t list * 'constr * 'types
- type t = (Constr.constr, Constr.types) pt
-
let map_constr f = function
| LocalAssum (ids, ty) as decl ->
let ty' = f ty in
@@ -454,7 +458,6 @@ module Compacted =
end
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
- type t = Declaration.t list
let fold f l ~init = List.fold_right f l init
end
diff --git a/kernel/context.mli b/kernel/context.mli
index c97db434..2b0d36cb 100644
--- a/kernel/context.mli
+++ b/kernel/context.mli
@@ -35,8 +35,6 @@ sig
| LocalAssum of Name.t * 'types (** name, type *)
| LocalDef of Name.t * 'constr * 'types (** name, value, type *)
- type t = (Constr.constr, Constr.types) pt
-
(** Return the name bound by a given declaration. *)
val get_name : ('c, 't) pt -> Name.t
@@ -87,13 +85,15 @@ sig
val fold_constr : ('c -> 'a -> 'a) -> ('c, 'c) pt -> 'a -> 'a
val to_tuple : ('c, 't) pt -> Name.t * 'c option * 't
+
+ (** Turn [LocalDef] into [LocalAssum], identity otherwise. *)
+ val drop_body : ('c, 't) pt -> ('c, 't) pt
end
(** Rel-context is represented as a list of declarations.
Inner-most declarations are at the beginning of the list.
Outer-most declarations are at the end of the list. *)
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
- type t = Declaration.t list
(** empty rel-context *)
val empty : ('c, 't) pt
@@ -132,6 +132,9 @@ sig
and each {e local definition} is mapped to [false]. *)
val to_tags : ('c, 't) pt -> bool list
+ (** Turn all [LocalDef] into [LocalAssum], leave [LocalAssum] unchanged. *)
+ val drop_bodies : ('c, 't) pt -> ('c, 't) pt
+
(** [extended_list mk n Γ] builds an instance [args] such that [Γ,Δ ⊢ args:Γ]
with n = |Δ| and with the {e local definitions} of [Γ] skipped in
[args] where [mk] is used to build the corresponding variables.
@@ -153,8 +156,6 @@ sig
| LocalAssum of Id.t * 'types (** identifier, type *)
| LocalDef of Id.t * 'constr * 'types (** identifier, value, type *)
- type t = (Constr.constr, Constr.types) pt
-
(** Return the identifier bound by a given declaration. *)
val get_id : ('c, 't) pt -> Id.t
@@ -207,6 +208,9 @@ sig
val to_tuple : ('c, 't) pt -> Id.t * 'c option * 't
val of_tuple : Id.t * 'c option * 't -> ('c, 't) pt
+ (** Turn [LocalDef] into [LocalAssum], identity otherwise. *)
+ val drop_body : ('c, 't) pt -> ('c, 't) pt
+
(** Convert [Rel.Declaration.t] value to the corresponding [Named.Declaration.t] value.
The function provided as the first parameter determines how to translate "names" to "ids". *)
val of_rel_decl : (Name.t -> Id.t) -> ('c, 't) Rel.Declaration.pt -> ('c, 't) pt
@@ -220,7 +224,6 @@ sig
Inner-most declarations are at the beginning of the list.
Outer-most declarations are at the end of the list. *)
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
- type t = Declaration.t list
(** empty named-context *)
val empty : ('c, 't) pt
@@ -255,6 +258,9 @@ sig
(** Return the set of all identifiers bound in a given named-context. *)
val to_vars : ('c, 't) pt -> Id.Set.t
+ (** Turn all [LocalDef] into [LocalAssum], leave [LocalAssum] unchanged. *)
+ val drop_bodies : ('c, 't) pt -> ('c, 't) pt
+
(** [to_instance Ω] builds an instance [args] such
that [Ω ⊢ args:Ω] where [Ω] is a named-context and with the local
definitions of [Ω] skipped. Example: for [id1:T,id2:=c,id3:U], it
@@ -270,15 +276,12 @@ sig
| LocalAssum of Id.t list * 'types
| LocalDef of Id.t list * 'constr * 'types
- type t = (Constr.constr, Constr.types) pt
-
val map_constr : ('c -> 'c) -> ('c, 'c) pt -> ('c, 'c) pt
val of_named_decl : ('c, 't) Named.Declaration.pt -> ('c, 't) pt
val to_named_context : ('c, 't) pt -> ('c, 't) Named.pt
end
type ('constr, 'types) pt = ('constr, 'types) Declaration.pt list
- type t = Declaration.t list
val fold : (('c, 't) Declaration.pt -> 'a -> 'a) -> ('c, 't) pt -> init:'a -> 'a
end
diff --git a/kernel/cooking.ml b/kernel/cooking.ml
index 6f4541e9..657478a1 100644
--- a/kernel/cooking.ml
+++ b/kernel/cooking.ml
@@ -24,6 +24,7 @@ open Declarations
open Univ
module NamedDecl = Context.Named.Declaration
+module RelDecl = Context.Rel.Declaration
(*s Cooking the constants. *)
@@ -126,17 +127,13 @@ let expmod_constr cache modlist c =
| Not_found -> Constr.map substrec c)
| Proj (p, c') ->
- (try
- let p' = share_univs (ConstRef (Projection.constant p)) Univ.Instance.empty modlist in
- let make c = Projection.make c (Projection.unfolded p) in
- match kind p' with
- | Const (p',_) -> mkProj (make p', substrec c')
- | App (f, args) ->
- (match kind f with
- | Const (p', _) -> mkProj (make p', substrec c')
- | _ -> assert false)
- | _ -> assert false
- with Not_found -> Constr.map substrec c)
+ let map cst npars =
+ let _, newpars = Mindmap.find cst (snd modlist) in
+ pop_mind cst, npars + Array.length newpars
+ in
+ let p' = try Projection.map_npars map p with Not_found -> p in
+ let c'' = substrec c' in
+ if p == p' && c' == c'' then c else mkProj (p', c'')
| _ -> Constr.map substrec c
@@ -144,11 +141,31 @@ let expmod_constr cache modlist c =
if is_empty_modlist modlist then c
else substrec c
-let abstract_constant_type =
- List.fold_left (fun c d -> mkNamedProd_wo_LetIn d c)
+(** Transforms a named context into a rel context. Also returns the list of
+ variables [id1 ... idn] that need to be replaced by [Rel 1 ... Rel n] to
+ abstract a term that lived in that context. *)
+let abstract_context hyps =
+ let fold decl (ctx, subst) =
+ let id, decl = match decl with
+ | NamedDecl.LocalDef (id, b, t) ->
+ let b = Vars.subst_vars subst b in
+ let t = Vars.subst_vars subst t in
+ id, RelDecl.LocalDef (Name id, b, t)
+ | NamedDecl.LocalAssum (id, t) ->
+ let t = Vars.subst_vars subst t in
+ id, RelDecl.LocalAssum (Name id, t)
+ in
+ (decl :: ctx, id :: subst)
+ in
+ Context.Named.fold_outside fold hyps ~init:([], [])
+
+let abstract_constant_type t (hyps, subst) =
+ let t = Vars.subst_vars subst t in
+ List.fold_left (fun c d -> mkProd_wo_LetIn d c) t hyps
-let abstract_constant_body =
- List.fold_left (fun c d -> mkNamedLambda_or_LetIn d c)
+let abstract_constant_body c (hyps, subst) =
+ let c = Vars.subst_vars subst c in
+ it_mkLambda_or_LetIn c hyps
type recipe = { from : constant_body; info : Opaqueproof.cooking_info }
type inline = bool
@@ -156,10 +173,9 @@ type inline = bool
type result = {
cook_body : constant_def;
cook_type : types;
- cook_proj : projection_body option;
cook_universes : constant_universes;
cook_inline : inline;
- cook_context : Context.Named.t option;
+ cook_context : Constr.named_context option;
}
let on_body ml hy f = function
@@ -178,6 +194,7 @@ let cook_constr { Opaqueproof.modlist ; abstract = (vars, subst, _) } c =
let cache = RefTable.create 13 in
let expmod = expmod_constr_subst cache modlist subst in
let hyps = Context.Named.map expmod vars in
+ let hyps = abstract_context hyps in
abstract_constant_body (expmod c) hyps
let lift_univs cb subst auctx0 =
@@ -206,18 +223,19 @@ let lift_univs cb subst auctx0 =
let auctx' = Univ.subst_univs_level_abstract_universe_context (Univ.make_instance_subst subst) auctx in
subst, (Polymorphic_const (AUContext.union auctx0 auctx'))
-let cook_constant ~hcons env { from = cb; info } =
+let cook_constant ~hcons { from = cb; info } =
let { Opaqueproof.modlist; abstract } = info in
let cache = RefTable.create 13 in
let abstract, usubst, abs_ctx = abstract in
let usubst, univs = lift_univs cb usubst abs_ctx in
let expmod = expmod_constr_subst cache modlist usubst in
- let hyps = Context.Named.map expmod abstract in
+ let hyps0 = Context.Named.map expmod abstract in
+ let hyps = abstract_context hyps0 in
let map c =
let c = abstract_constant_body (expmod c) hyps in
if hcons then Constr.hcons c else c
in
- let body = on_body modlist (hyps, usubst, abs_ctx)
+ let body = on_body modlist (hyps0, usubst, abs_ctx)
map
cb.const_body
in
@@ -225,30 +243,11 @@ let cook_constant ~hcons env { from = cb; info } =
Context.Named.fold_outside (fun decl hyps ->
List.filter (fun decl' -> not (Id.equal (NamedDecl.get_id decl) (NamedDecl.get_id decl')))
hyps)
- hyps ~init:cb.const_hyps in
+ hyps0 ~init:cb.const_hyps in
let typ = abstract_constant_type (expmod cb.const_type) hyps in
- let projection pb =
- let c' = abstract_constant_body (expmod pb.proj_body) hyps in
- let etab = abstract_constant_body (expmod (fst pb.proj_eta)) hyps in
- let etat = abstract_constant_body (expmod (snd pb.proj_eta)) hyps in
- let ((mind, _), _), n' =
- try
- let c' = share_univs cache (IndRef (pb.proj_ind,0)) Univ.Instance.empty modlist in
- match kind c' with
- | App (f,l) -> (destInd f, Array.length l)
- | Ind ind -> ind, 0
- | _ -> assert false
- with Not_found -> (((pb.proj_ind,0),Univ.Instance.empty), 0)
- in
- let ctx, ty' = decompose_prod_n (n' + pb.proj_npars + 1) typ in
- { proj_ind = mind; proj_npars = pb.proj_npars + n'; proj_arg = pb.proj_arg;
- proj_eta = etab, etat;
- proj_type = ty'; proj_body = c' }
- in
{
cook_body = body;
cook_type = typ;
- cook_proj = Option.map projection cb.const_proj;
cook_universes = univs;
cook_inline = cb.const_inline_code;
cook_context = Some const_hyps;
diff --git a/kernel/cooking.mli b/kernel/cooking.mli
index 7bd0ae56..6ebe691b 100644
--- a/kernel/cooking.mli
+++ b/kernel/cooking.mli
@@ -10,7 +10,6 @@
open Constr
open Declarations
-open Environ
(** {6 Cooking the constants. } *)
@@ -21,13 +20,12 @@ type inline = bool
type result = {
cook_body : constant_def;
cook_type : types;
- cook_proj : projection_body option;
cook_universes : constant_universes;
cook_inline : inline;
- cook_context : Context.Named.t option;
+ cook_context : Constr.named_context option;
}
-val cook_constant : hcons:bool -> env -> recipe -> result
+val cook_constant : hcons:bool -> recipe -> result
val cook_constr : Opaqueproof.cooking_info -> constr -> constr
(** {6 Utility functions used in module [Discharge]. } *)
diff --git a/kernel/csymtable.ml b/kernel/csymtable.ml
index 01294895..bb9231d0 100644
--- a/kernel/csymtable.ml
+++ b/kernel/csymtable.ml
@@ -20,13 +20,15 @@ open Vmvalues
open Cemitcodes
open Cbytecodes
open Declarations
-open Pre_env
+open Environ
open Cbytegen
module NamedDecl = Context.Named.Declaration
module RelDecl = Context.Rel.Declaration
-external eval_tcode : tcode -> values array -> values = "coq_eval_tcode"
+external eval_tcode : tcode -> atom array -> vm_global -> values array -> values = "coq_eval_tcode"
+
+type global_data = { mutable glob_len : int; mutable glob_val : values array }
(*******************)
(* Linkage du code *)
@@ -37,21 +39,28 @@ external eval_tcode : tcode -> values array -> values = "coq_eval_tcode"
(* [global_data] contient les valeurs des constantes globales
(axiomes,definitions), les annotations des switch et les structured
constant *)
-external global_data : unit -> values array = "get_coq_global_data"
+let global_data = {
+ glob_len = 0;
+ glob_val = Array.make 4096 crazy_val;
+}
-(* [realloc_global_data n] augmente de n la taille de [global_data] *)
-external realloc_global_data : int -> unit = "realloc_coq_global_data"
+let get_global_data () = Vmvalues.vm_global global_data.glob_val
-let check_global_data n =
- if n >= Array.length (global_data()) then realloc_global_data n
+let realloc_global_data n =
+ let n = min (2 * n + 0x100) Sys.max_array_length in
+ let ans = Array.make n crazy_val in
+ let src = global_data.glob_val in
+ let () = Array.blit src 0 ans 0 (Array.length src) in
+ global_data.glob_val <- ans
-let num_global = ref 0
+let check_global_data n =
+ if n >= Array.length global_data.glob_val then realloc_global_data n
let set_global v =
- let n = !num_global in
+ let n = global_data.glob_len in
check_global_data n;
- (global_data()).(n) <- v;
- incr num_global;
+ global_data.glob_val.(n) <- v;
+ global_data.glob_len <- global_data.glob_len + 1;
n
(* table pour les structured_constant et les annotations des switchs *)
@@ -68,11 +77,15 @@ module AnnotTable = Hashtbl.Make (struct
let hash = hash_annot_switch
end)
+module ProjNameTable = Hashtbl.Make (Projection.Repr)
+
let str_cst_tbl : int SConstTable.t = SConstTable.create 31
let annot_tbl : int AnnotTable.t = AnnotTable.create 31
(* (annot_switch * int) Hashtbl.t *)
+let proj_name_tbl : int ProjNameTable.t = ProjNameTable.create 31
+
(*************************************************************)
(*** Mise a jour des valeurs des variables et des constantes *)
(*************************************************************)
@@ -106,6 +119,13 @@ let slot_for_annot key =
AnnotTable.add annot_tbl key n;
n
+let slot_for_proj_name key =
+ try ProjNameTable.find proj_name_tbl key
+ with Not_found ->
+ let n = set_global (val_of_proj_name key) in
+ ProjNameTable.add proj_name_tbl key n;
+ n
+
let rec slot_for_getglobal env kn =
let (cb,(_,rk)) = lookup_constant_key kn env in
try key rk
@@ -133,23 +153,23 @@ and slot_for_fv env fv =
| None -> v_of_id id, Id.Set.empty
| Some c ->
val_of_constr (env_of_id id env) c,
- Environ.global_vars_set (Environ.env_of_pre_env env) c in
+ Environ.global_vars_set env c in
build_lazy_val cache (v, d); v in
let val_of_rel i = val_of_rel (nb_rel env - i) in
let idfun _ x = x in
match fv with
| FVnamed id ->
- let nv = Pre_env.lookup_named_val id env in
+ let nv = lookup_named_val id env in
begin match force_lazy_val nv with
| None ->
- env |> Pre_env.lookup_named id |> NamedDecl.get_value |> fill_fv_cache nv id val_of_named idfun
+ env |> lookup_named id |> NamedDecl.get_value |> fill_fv_cache nv id val_of_named idfun
| Some (v, _) -> v
end
| FVrel i ->
- let rv = Pre_env.lookup_rel_val i env in
+ let rv = lookup_rel_val i env in
begin match force_lazy_val rv with
| None ->
- env |> Pre_env.lookup_rel i |> RelDecl.get_value |> fill_fv_cache rv i val_of_rel env_of_rel
+ env |> lookup_rel i |> RelDecl.get_value |> fill_fv_cache rv i val_of_rel env_of_rel
| Some (v, _) -> v
end
| FVevar evk -> val_of_evar evk
@@ -161,10 +181,11 @@ and eval_to_patch env (buff,pl,fv) =
| Reloc_annot a -> slot_for_annot a
| Reloc_const sc -> slot_for_str_cst sc
| Reloc_getglobal kn -> slot_for_getglobal env kn
+ | Reloc_proj_name p -> slot_for_proj_name p
in
let tc = patch buff pl slots in
let vm_env = Array.map (slot_for_fv env) fv in
- eval_tcode tc vm_env
+ eval_tcode tc (get_atom_rel ()) (vm_global global_data.glob_val) vm_env
and val_of_constr env c =
match compile ~fail_on_error:true env c with
diff --git a/kernel/csymtable.mli b/kernel/csymtable.mli
index 19b2b8b5..72c96b0b 100644
--- a/kernel/csymtable.mli
+++ b/kernel/csymtable.mli
@@ -12,9 +12,11 @@
open Names
open Constr
-open Pre_env
+open Environ
val val_of_constr : env -> constr -> Vmvalues.values
val set_opaque_const : Constant.t -> unit
val set_transparent_const : Constant.t -> unit
+
+val get_global_data : unit -> Vmvalues.vm_global
diff --git a/kernel/declarations.ml b/kernel/declarations.ml
index b7427d20..61fcb483 100644
--- a/kernel/declarations.ml
+++ b/kernel/declarations.ml
@@ -46,18 +46,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 : types; (* Type under params *)
- proj_eta : constr * types; (* Eta-expanded term and type *)
- proj_body : constr; (* For compatibility with VMs only, the match version *)
-}
-
(* Global declarations (i.e. constants) can be either: *)
type constant_def =
| Undef of inline (** a global assumption *)
@@ -77,17 +65,17 @@ type typing_flags = {
points are assumed to be total. *)
check_universes : bool; (** If [false] universe constraints are not checked *)
conv_oracle : Conv_oracle.oracle; (** Unfolding strategies for conversion *)
+ share_reduction : bool; (** Use by-need reduction algorithm *)
}
(* some contraints are in constant_constraints, some other may be in
* the OpaqueDef *)
type constant_body = {
- const_hyps : Context.Named.t; (** New: younger hyp at top *)
+ const_hyps : Constr.named_context; (** New: younger hyp at top *)
const_body : constant_def;
const_type : types;
const_body_code : Cemitcodes.to_patch_substituted option;
const_universes : constant_universes;
- const_proj : projection_body option;
const_inline_code : bool;
const_typing_flags : typing_flags; (** The typing options which
were used for
@@ -112,13 +100,22 @@ v}
*)
(** Record information:
- If the record is not primitive, then None
- Otherwise, we get:
+ If the type is not a record, then NotRecord
+ If the type is a non-primitive record, then FakeRecord
+ If it is a primitive record, for every type in the block, we get:
- The identifier for the binder name of the record in primitive projections.
- The constants associated to each projection.
- - The checked projection bodies. *)
+ - The projection types (under parameters).
+
+ The kernel does not exploit the difference between [NotRecord] and
+ [FakeRecord]. It is mostly used by extraction, and should be extruded from
+ the kernel at some point.
+*)
-type record_body = (Id.t * Constant.t array * projection_body array) option
+type record_info =
+| NotRecord
+| FakeRecord
+| PrimRecord of (Id.t * Label.t array * types array) array
type regular_inductive_arity = {
mind_user_arity : types;
@@ -132,7 +129,7 @@ type one_inductive_body = {
mind_typename : Id.t; (** Name of the type: [Ii] *)
- mind_arity_ctxt : Context.Rel.t; (** Arity context of [Ii] with parameters: [forall params, Ui] *)
+ mind_arity_ctxt : Constr.rel_context; (** Arity context of [Ii] with parameters: [forall params, Ui] *)
mind_arity : inductive_arity; (** Arity sort and original user arity *)
@@ -167,7 +164,7 @@ type one_inductive_body = {
mind_nb_args : int; (** number of no constant constructor *)
- mind_reloc_tbl : Cbytecodes.reloc_table;
+ mind_reloc_tbl : Vmvalues.reloc_table;
}
type abstract_inductive_universes =
@@ -184,19 +181,19 @@ type mutual_inductive_body = {
mind_packets : one_inductive_body array; (** The component of the mutual inductive block *)
- mind_record : record_body option; (** The record information *)
+ mind_record : record_info; (** The record information *)
mind_finite : recursivity_kind; (** Whether the type is inductive or coinductive *)
mind_ntypes : int; (** Number of types in the block *)
- mind_hyps : Context.Named.t; (** Section hypotheses on which the block depends *)
+ mind_hyps : Constr.named_context; (** Section hypotheses on which the block depends *)
mind_nparams : int; (** Number of expected parameters including non-uniform ones (i.e. length of mind_params_ctxt w/o let-in) *)
mind_nparams_rec : int; (** Number of recursively uniform (i.e. ordinary) parameters *)
- mind_params_ctxt : Context.Rel.t; (** The context of parameters (includes let-in declaration) *)
+ mind_params_ctxt : Constr.rel_context; (** The context of parameters (includes let-in declaration) *)
mind_universes : abstract_inductive_universes; (** Information about monomorphic/polymorphic/cumulative inductives and their universes *)
diff --git a/kernel/declareops.ml b/kernel/declareops.ml
index 3652a1ce..51ec3def 100644
--- a/kernel/declareops.ml
+++ b/kernel/declareops.ml
@@ -21,6 +21,7 @@ let safe_flags oracle = {
check_guarded = true;
check_universes = true;
conv_oracle = oracle;
+ share_reduction = true;
}
(** {6 Arities } *)
@@ -42,7 +43,7 @@ let map_decl_arity f g = function
let hcons_template_arity ar =
{ template_param_levels = ar.template_param_levels;
- (* List.smartmap (Option.smartmap Univ.hcons_univ_level) ar.template_param_levels; *)
+ (* List.Smart.map (Option.Smart.map Univ.hcons_univ_level) ar.template_param_levels; *)
template_level = Univ.hcons_univ ar.template_level }
(** {6 Constants } *)
@@ -70,7 +71,7 @@ let is_opaque cb = match cb.const_body with
let subst_rel_declaration sub =
RelDecl.map_constr (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 subst_const_type sub arity =
if is_empty_subst sub then arity
@@ -83,25 +84,18 @@ let subst_const_def sub def = match def with
| Def c -> Def (subst_constr sub c)
| OpaqueDef o -> OpaqueDef (Opaqueproof.subst_opaque sub o)
-let subst_const_proj sub pb =
- { pb with proj_ind = subst_mind sub pb.proj_ind;
- proj_type = subst_mps sub pb.proj_type;
- proj_body = subst_const_type sub pb.proj_body }
-
let subst_const_body sub cb =
assert (List.is_empty cb.const_hyps); (* we're outside sections *)
if is_empty_subst sub then cb
else
let body' = subst_const_def sub cb.const_body in
let type' = subst_const_type sub cb.const_type in
- let proj' = Option.smartmap (subst_const_proj sub) cb.const_proj in
if body' == cb.const_body && type' == cb.const_type
- && proj' == cb.const_proj then cb
+ then cb
else
{ const_hyps = [];
const_body = body';
const_type = type';
- const_proj = proj';
const_body_code =
Option.map (Cemitcodes.subst_to_patch_subst sub) cb.const_body_code;
const_universes = cb.const_universes;
@@ -117,7 +111,7 @@ let subst_const_body sub cb =
let hcons_rel_decl =
RelDecl.map_name Names.Name.hcons %> RelDecl.map_value Constr.hcons %> RelDecl.map_type Constr.hcons
-let hcons_rel_context l = List.smartmap hcons_rel_decl l
+let hcons_rel_context l = List.Smart.map hcons_rel_decl l
let hcons_const_def = function
| Undef inl -> Undef inl
@@ -178,7 +172,7 @@ let recarg_length p j =
let (_,cstrs) = Rtree.dest_node p in
Array.length (snd (Rtree.dest_node cstrs.(j-1)))
-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
(** {7 Substitution of inductive declarations } *)
@@ -198,10 +192,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;
@@ -210,14 +204,20 @@ let subst_mind_packet sub mbp =
mind_nb_args = mbp.mind_nb_args;
mind_reloc_tbl = mbp.mind_reloc_tbl }
-let subst_mind_record sub (id, ps, pb as r) =
- let ps' = Array.smartmap (subst_constant sub) ps in
- let pb' = Array.smartmap (subst_const_proj sub) pb in
- if ps' == ps && pb' == pb then r
- else (id, ps', pb')
+let subst_mind_record sub r = match r with
+| NotRecord -> NotRecord
+| FakeRecord -> FakeRecord
+| PrimRecord infos ->
+ let map (id, ps, pb as info) =
+ let pb' = Array.Smart.map (subst_mps sub) pb in
+ if pb' == pb then info
+ else (id, ps, pb')
+ in
+ let infos' = Array.Smart.map map infos in
+ if infos' == infos then r else PrimRecord infos'
let subst_mind_body sub mib =
- { mind_record = Option.smartmap (Option.smartmap (subst_mind_record sub)) mib.mind_record ;
+ { mind_record = subst_mind_record sub mib.mind_record ;
mind_finite = mib.mind_finite ;
mind_ntypes = mib.mind_ntypes ;
mind_hyps = (match mib.mind_hyps with [] -> [] | _ -> assert false);
@@ -225,7 +225,7 @@ let subst_mind_body sub mib =
mind_nparams_rec = mib.mind_nparams_rec;
mind_params_ctxt =
Context.Rel.map (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 ;
mind_universes = mib.mind_universes;
mind_private = mib.mind_private;
mind_typing_flags = mib.mind_typing_flags;
@@ -249,6 +249,25 @@ let inductive_is_cumulative mib =
| Polymorphic_ind ctx -> false
| Cumulative_ind cumi -> true
+let inductive_make_projection ind mib ~proj_arg =
+ match mib.mind_record with
+ | NotRecord | FakeRecord -> None
+ | PrimRecord infos ->
+ Some (Names.Projection.Repr.make ind
+ ~proj_npars:mib.mind_nparams
+ ~proj_arg
+ (pi2 infos.(snd ind)).(proj_arg))
+
+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
+
(** {6 Hash-consing of inductive declarations } *)
let hcons_regular_ind_arity a =
@@ -263,15 +282,15 @@ let hcons_ind_arity =
(** Substitution of inductive declarations *)
let hcons_mind_packet oib =
- let user = Array.smartmap Constr.hcons oib.mind_user_lc in
- let nf = Array.smartmap Constr.hcons oib.mind_nf_lc in
+ let user = Array.Smart.map Constr.hcons oib.mind_user_lc in
+ let nf = Array.Smart.map Constr.hcons oib.mind_nf_lc in
(* Special optim : merge [mind_user_lc] and [mind_nf_lc] if possible *)
let nf = if Array.equal (==) user nf then user else nf in
{ oib with
mind_typename = Names.Id.hcons oib.mind_typename;
mind_arity_ctxt = hcons_rel_context oib.mind_arity_ctxt;
mind_arity = hcons_ind_arity oib.mind_arity;
- mind_consnames = Array.smartmap Names.Id.hcons oib.mind_consnames;
+ mind_consnames = Array.Smart.map Names.Id.hcons oib.mind_consnames;
mind_user_lc = user;
mind_nf_lc = nf }
@@ -283,17 +302,10 @@ let hcons_mind_universes miu =
let hcons_mind mib =
{ mib with
- mind_packets = Array.smartmap hcons_mind_packet mib.mind_packets;
+ mind_packets = Array.Smart.map hcons_mind_packet mib.mind_packets;
mind_params_ctxt = hcons_rel_context mib.mind_params_ctxt;
mind_universes = hcons_mind_universes mib.mind_universes }
-(** {6 Stm machinery } *)
-
-let string_of_side_effect { Entries.eff } = match eff with
- | Entries.SEsubproof (c,_,_) -> "P(" ^ Names.Constant.to_string c ^ ")"
- | Entries.SEscheme (cl,_) ->
- "S(" ^ String.concat ", " (List.map (fun (_,c,_,_) -> Names.Constant.to_string c) cl) ^ ")"
-
(** Hashconsing of modules *)
let hcons_functorize hty he hself f = match f with
@@ -331,7 +343,7 @@ and hcons_structure_body sb =
let sfb' = hcons_structure_field_body sfb in
if l == l' && sfb == sfb' then fb else (l', sfb')
in
- List.smartmap map sb
+ List.Smart.map map sb
and hcons_module_signature ms =
hcons_functorize hcons_module_type hcons_structure_body hcons_module_signature ms
diff --git a/kernel/declareops.mli b/kernel/declareops.mli
index fb46112e..35490cee 100644
--- a/kernel/declareops.mli
+++ b/kernel/declareops.mli
@@ -11,7 +11,6 @@
open Declarations
open Mod_subst
open Univ
-open Entries
(** Operations concerning types in [Declarations] :
[constant_body], [mutual_inductive_body], [module_body] ... *)
@@ -39,10 +38,6 @@ val constant_is_polymorphic : constant_body -> bool
val is_opaque : constant_body -> bool
-(** Side effects *)
-
-val string_of_side_effect : side_effect -> string
-
(** {6 Inductive types} *)
val eq_recarg : recarg -> recarg -> bool
@@ -66,6 +61,11 @@ val inductive_is_polymorphic : mutual_inductive_body -> bool
(** Is the inductive cumulative? *)
val inductive_is_cumulative : mutual_inductive_body -> bool
+val inductive_make_projection : Names.inductive -> mutual_inductive_body -> proj_arg:int ->
+ Names.Projection.Repr.t option
+val inductive_make_projections : Names.inductive -> mutual_inductive_body ->
+ Names.Projection.Repr.t array option
+
(** {6 Kernel flags} *)
(** A default, safe set of flags for kernel type-checking *)
diff --git a/kernel/entries.ml b/kernel/entries.ml
index 94da00c7..94248ad2 100644
--- a/kernel/entries.ml
+++ b/kernel/entries.ml
@@ -49,9 +49,9 @@ type one_inductive_entry = {
mind_entry_lc : constr list }
type mutual_inductive_entry = {
- mind_entry_record : (Id.t option) option;
- (** Some (Some id): primitive record with id the binder name of the record
- in projections.
+ mind_entry_record : (Id.t array option) option;
+ (** Some (Some ids): primitive records with ids the binder name of each
+ record in their respective projections. Not used by the kernel.
Some None: non-primitive record *)
mind_entry_finite : Declarations.recursivity_kind;
mind_entry_params : (Id.t * local_entry) list;
@@ -75,7 +75,7 @@ type 'a in_constant_universes_entry = 'a * constant_universes_entry
type 'a definition_entry = {
const_entry_body : 'a const_entry_body;
(* List of section variables *)
- const_entry_secctx : Context.Named.t option;
+ const_entry_secctx : Constr.named_context option;
(* State id on which the completion of type checking is reported *)
const_entry_feedback : Stateid.t option;
const_entry_type : types option;
@@ -85,7 +85,7 @@ type 'a definition_entry = {
type section_def_entry = {
secdef_body : constr;
- secdef_secctx : Context.Named.t option;
+ secdef_secctx : Constr.named_context option;
secdef_feedback : Stateid.t option;
secdef_type : types option;
}
@@ -93,16 +93,11 @@ type section_def_entry = {
type inline = int option (* inlining level, None for no inlining *)
type parameter_entry =
- Context.Named.t option * types in_constant_universes_entry * inline
-
-type projection_entry = {
- proj_entry_ind : MutInd.t;
- proj_entry_arg : int }
+ Constr.named_context option * types in_constant_universes_entry * inline
type 'a constant_entry =
| DefinitionEntry of 'a definition_entry
| ParameterEntry of parameter_entry
- | ProjectionEntry of projection_entry
(** {6 Modules } *)
@@ -125,11 +120,14 @@ type seff_env =
Same as the constant_body's but not in an ephemeron *)
| `Opaque of Constr.t * Univ.ContextSet.t ]
-type side_eff =
- | SEsubproof of Constant.t * Declarations.constant_body * seff_env
- | SEscheme of (inductive * Constant.t * Declarations.constant_body * seff_env) list * string
+(** Not used by the kernel. *)
+type side_effect_role =
+ | Subproof
+ | Schema of inductive * string
-type side_effect = {
- from_env : Declarations.structure_body CEphemeron.key;
- eff : side_eff;
+type side_eff = {
+ seff_constant : Constant.t;
+ seff_body : Declarations.constant_body;
+ seff_env : seff_env;
+ seff_role : side_effect_role;
}
diff --git a/kernel/environ.ml b/kernel/environ.ml
index 89ba6f65..778c9a24 100644
--- a/kernel/environ.ml
+++ b/kernel/environ.ml
@@ -28,26 +28,208 @@ open Names
open Constr
open Vars
open Declarations
-open Pre_env
open Context.Rel.Declaration
+module NamedDecl = Context.Named.Declaration
+
(* The type of environments. *)
-type named_context_val = Pre_env.named_context_val
+(* The key attached to each constant is used by the VM to retrieve previous *)
+(* evaluations of the constant. It is essentially an index in the symbols table *)
+(* used by the VM. *)
+type key = int CEphemeron.key option ref
+
+(** Linking information for the native compiler. *)
+
+type link_info =
+ | Linked of string
+ | LinkedInteractive of string
+ | NotLinked
+
+type constant_key = constant_body * (link_info ref * key)
+
+type mind_key = mutual_inductive_body * link_info ref
+
+type globals = {
+ env_constants : constant_key Cmap_env.t;
+ env_inductives : mind_key Mindmap_env.t;
+ env_modules : module_body MPmap.t;
+ env_modtypes : module_type_body MPmap.t;
+}
+
+type stratification = {
+ env_universes : UGraph.t;
+ env_engagement : engagement
+}
+
+type val_kind =
+ | VKvalue of (Vmvalues.values * Id.Set.t) CEphemeron.key
+ | VKnone
+
+type lazy_val = val_kind ref
+
+let force_lazy_val vk = match !vk with
+| VKnone -> None
+| VKvalue v -> try Some (CEphemeron.get v) with CEphemeron.InvalidKey -> None
+
+let dummy_lazy_val () = ref VKnone
+let build_lazy_val vk key = vk := VKvalue (CEphemeron.create key)
+
+type named_context_val = {
+ env_named_ctx : Constr.named_context;
+ env_named_map : (Constr.named_declaration * lazy_val) Id.Map.t;
+}
+
+type rel_context_val = {
+ env_rel_ctx : Constr.rel_context;
+ env_rel_map : (Constr.rel_declaration * lazy_val) Range.t;
+}
+
+type env = {
+ env_globals : globals;
+ env_named_context : named_context_val; (* section variables *)
+ env_rel_context : rel_context_val;
+ env_nb_rel : int;
+ env_stratification : stratification;
+ env_typing_flags : typing_flags;
+ retroknowledge : Retroknowledge.retroknowledge;
+ indirect_pterms : Opaqueproof.opaquetab;
+}
+
+let empty_named_context_val = {
+ env_named_ctx = [];
+ env_named_map = Id.Map.empty;
+}
+
+let empty_rel_context_val = {
+ env_rel_ctx = [];
+ env_rel_map = Range.empty;
+}
+
+let empty_env = {
+ env_globals = {
+ env_constants = Cmap_env.empty;
+ env_inductives = Mindmap_env.empty;
+ env_modules = MPmap.empty;
+ env_modtypes = MPmap.empty};
+ env_named_context = empty_named_context_val;
+ env_rel_context = empty_rel_context_val;
+ env_nb_rel = 0;
+ env_stratification = {
+ env_universes = UGraph.initial_universes;
+ env_engagement = PredicativeSet };
+ env_typing_flags = Declareops.safe_flags Conv_oracle.empty;
+ retroknowledge = Retroknowledge.initial_retroknowledge;
+ indirect_pterms = Opaqueproof.empty_opaquetab }
+
+
+(* Rel context *)
+
+let push_rel_context_val d ctx = {
+ env_rel_ctx = Context.Rel.add d ctx.env_rel_ctx;
+ env_rel_map = Range.cons (d, ref VKnone) ctx.env_rel_map;
+}
+
+let match_rel_context_val ctx = match ctx.env_rel_ctx with
+| [] -> None
+| decl :: rem ->
+ let (_, lval) = Range.hd ctx.env_rel_map in
+ let ctx = { env_rel_ctx = rem; env_rel_map = Range.tl ctx.env_rel_map } in
+ Some (decl, lval, ctx)
+
+let push_rel d env =
+ { env with
+ env_rel_context = push_rel_context_val d env.env_rel_context;
+ env_nb_rel = env.env_nb_rel + 1 }
+
+let lookup_rel n env =
+ try fst (Range.get env.env_rel_context.env_rel_map (n - 1))
+ with Invalid_argument _ -> raise Not_found
+
+let lookup_rel_val n env =
+ try snd (Range.get env.env_rel_context.env_rel_map (n - 1))
+ with Invalid_argument _ -> raise Not_found
+
+let rel_skipn n ctx = {
+ env_rel_ctx = Util.List.skipn n ctx.env_rel_ctx;
+ env_rel_map = Range.skipn n ctx.env_rel_map;
+}
+
+let env_of_rel n env =
+ { env with
+ env_rel_context = rel_skipn n env.env_rel_context;
+ env_nb_rel = env.env_nb_rel - n
+ }
+
+(* Named context *)
+
+let push_named_context_val_val d rval ctxt =
+(* assert (not (Id.Map.mem (NamedDecl.get_id d) ctxt.env_named_map)); *)
+ {
+ env_named_ctx = Context.Named.add d ctxt.env_named_ctx;
+ env_named_map = Id.Map.add (NamedDecl.get_id d) (d, rval) ctxt.env_named_map;
+ }
+
+let push_named_context_val d ctxt =
+ push_named_context_val_val d (ref VKnone) ctxt
+
+let match_named_context_val c = match c.env_named_ctx with
+| [] -> None
+| decl :: ctx ->
+ let (_, v) = Id.Map.find (NamedDecl.get_id decl) c.env_named_map in
+ let map = Id.Map.remove (NamedDecl.get_id decl) c.env_named_map in
+ let cval = { env_named_ctx = ctx; env_named_map = map } in
+ Some (decl, v, cval)
+
+let map_named_val f ctxt =
+ let open Context.Named.Declaration in
+ let fold accu d =
+ let d' = map_constr f d in
+ let accu =
+ if d == d' then accu
+ else Id.Map.modify (get_id d) (fun _ (_, v) -> (d', v)) accu
+ in
+ (accu, d')
+ in
+ let map, ctx = List.fold_left_map fold ctxt.env_named_map ctxt.env_named_ctx in
+ if map == ctxt.env_named_map then ctxt
+ else { env_named_ctx = ctx; env_named_map = map }
+
+let push_named d env =
+ {env with env_named_context = push_named_context_val d env.env_named_context}
-type env = Pre_env.env
+let lookup_named id env =
+ fst (Id.Map.find id env.env_named_context.env_named_map)
+
+let lookup_named_val id env =
+ snd(Id.Map.find id env.env_named_context.env_named_map)
+
+let lookup_named_ctxt id ctxt =
+ fst (Id.Map.find id ctxt.env_named_map)
+
+let fold_constants f env acc =
+ Cmap_env.fold (fun c (body,_) acc -> f c body acc) env.env_globals.env_constants acc
+
+(* Global constants *)
+
+let lookup_constant_key kn env =
+ Cmap_env.find kn env.env_globals.env_constants
+
+let lookup_constant kn env =
+ fst (Cmap_env.find kn env.env_globals.env_constants)
+
+(* Mutual Inductives *)
+let lookup_mind kn env =
+ fst (Mindmap_env.find kn env.env_globals.env_inductives)
+
+let lookup_mind_key kn env =
+ Mindmap_env.find kn env.env_globals.env_inductives
-let pre_env env = env
-let env_of_pre_env env = env
let oracle env = env.env_typing_flags.conv_oracle
let set_oracle env o =
let env_typing_flags = { env.env_typing_flags with conv_oracle = o } in
{ env with env_typing_flags }
-let empty_named_context_val = empty_named_context_val
-
-let empty_env = empty_env
-
let engagement env = env.env_stratification.env_engagement
let typing_flags env = env.env_typing_flags
@@ -72,15 +254,11 @@ let empty_context env =
| _ -> false
(* Rel context *)
-let lookup_rel = lookup_rel
-
let evaluable_rel n env =
is_local_def (lookup_rel n env)
let nb_rel env = env.env_nb_rel
-let push_rel = push_rel
-
let push_rel_context ctxt x = Context.Rel.fold_outside push_rel ctxt ~init:x
let push_rec_types (lna,typarray,_) env =
@@ -105,24 +283,14 @@ let named_context_of_val c = c.env_named_ctx
let ids_of_named_context_val c = Id.Map.domain c.env_named_map
-(* [map_named_val f ctxt] apply [f] to the body and the type of
- each declarations.
- *** /!\ *** [f t] should be convertible with t *)
-let map_named_val = map_named_val
-
let empty_named_context = Context.Named.empty
-let push_named = push_named
let push_named_context = List.fold_right push_named
-let push_named_context_val = push_named_context_val
let val_of_named_context ctxt =
List.fold_right push_named_context_val ctxt empty_named_context_val
-let lookup_named = lookup_named
-let lookup_named_val id ctxt = fst (Id.Map.find id ctxt.env_named_map)
-
let eq_named_context_val c1 c2 =
c1 == c2 || Context.Named.equal Constr.equal (named_context_of_val c1) (named_context_of_val c2)
@@ -181,7 +349,10 @@ let map_universes f env =
let s = env.env_stratification in
{ env with env_stratification =
{ s with env_universes = f s.env_universes } }
-
+
+let set_universes env u =
+ { env with env_stratification = { env.env_stratification with env_universes = u } }
+
let add_constraints c env =
if Univ.Constraint.is_empty c then env
else map_universes (UGraph.merge_constraints c) env
@@ -221,8 +392,6 @@ let set_typing_flags c env = (* Unsafe *)
(* Global constants *)
-let lookup_constant = lookup_constant
-
let no_link_info = NotLinked
let add_constant_key kn cb linkinfo env =
@@ -319,19 +488,26 @@ let polymorphic_pconstant (cst,u) env =
let type_in_type_constant cst env =
not (lookup_constant cst env).const_typing_flags.check_universes
-let lookup_projection cst env =
- match (lookup_constant (Projection.constant cst) env).const_proj with
- | Some pb -> pb
- | None -> anomaly (Pp.str "lookup_projection: constant is not a projection.")
-
-let is_projection cst env =
- match (lookup_constant cst env).const_proj with
- | Some _ -> true
- | None -> false
+let lookup_projection p env =
+ let mind,i = Projection.inductive p in
+ let mib = lookup_mind mind env in
+ (if not (Int.equal mib.mind_nparams (Projection.npars p))
+ then anomaly ~label:"lookup_projection" Pp.(str "Bad number of parameters on projection."));
+ match mib.mind_record with
+ | NotRecord | FakeRecord -> anomaly ~label:"lookup_projection" Pp.(str "not a projection")
+ | PrimRecord infos ->
+ let _,_,typs = infos.(i) in
+ typs.(Projection.arg p)
+
+let get_projection env ind ~proj_arg =
+ let mib = lookup_mind (fst ind) env in
+ Declareops.inductive_make_projection ind mib ~proj_arg
+
+let get_projections env ind =
+ let mib = lookup_mind (fst ind) env in
+ Declareops.inductive_make_projections ind mib
(* Mutual Inductives *)
-let lookup_mind = lookup_mind
-
let polymorphic_ind (mind,i) env =
Declareops.inductive_is_polymorphic (lookup_mind mind env)
@@ -351,11 +527,11 @@ let template_polymorphic_pind (ind,u) env =
if not (Univ.Instance.is_empty u) then false
else template_polymorphic_ind ind env
-let add_mind_key kn mind_key env =
+let add_mind_key kn (mind, _ as mind_key) env =
let new_inds = Mindmap_env.add kn mind_key env.env_globals.env_inductives in
let new_globals =
{ env.env_globals with
- env_inductives = new_inds } in
+ env_inductives = new_inds; } in
{ env with env_globals = new_globals }
let add_mind kn mib env =
@@ -468,10 +644,6 @@ type 'types punsafe_type_judgment = {
type unsafe_type_judgment = types punsafe_type_judgment
-(*s Compilation of global declaration *)
-
-let compile_constant_body = Cbytegen.compile_constant_body ~fail_on_error:false
-
exception Hyp_not_found
let apply_to_hyp ctxt id f =
@@ -530,121 +702,3 @@ let register env field entry =
in
register_one (register_one env (KInt31 (grp,Int31Constructor)) i31c) field entry
| field -> register_one env field entry
-
-(* the Environ.register function syncrhonizes the proactive and reactive
- retroknowledge. *)
-let dispatch =
-
- (* subfunction used for static decompilation of int31 (after a vm_compute,
- see pretyping/vnorm.ml for more information) *)
- let constr_of_int31 =
- let nth_digit_plus_one i n = (* calculates the nth (starting with 0)
- digit of i and adds 1 to it
- (nth_digit_plus_one 1 3 = 2) *)
- if Int.equal (i land (1 lsl n)) 0 then
- 1
- else
- 2
- in
- fun ind -> fun digit_ind -> fun tag ->
- let array_of_int i =
- Array.init 31 (fun n -> mkConstruct
- (digit_ind, nth_digit_plus_one i (30-n)))
- in
- (* We check that no bit above 31 is set to one. This assertion used to
- fail in the VM, and led to conversion tests failing at Qed. *)
- assert (Int.equal (tag lsr 31) 0);
- mkApp(mkConstruct(ind, 1), array_of_int tag)
- in
-
- (* subfunction which dispatches the compiling information of an
- int31 operation which has a specific vm instruction (associates
- it to the name of the coq definition in the reactive retroknowledge) *)
- let int31_op n op prim kn =
- { empty_reactive_info with
- vm_compiling = Some (Clambda.compile_prim n op kn);
- native_compiling = Some (Nativelambda.compile_prim prim (Univ.out_punivs kn));
- }
- in
-
-fun rk value field ->
- (* subfunction which shortens the (very common) dispatch of operations *)
- let int31_op_from_const n op prim =
- match kind value with
- | Const kn -> int31_op n op prim kn
- | _ -> anomaly ~label:"Environ.register" (Pp.str "should be a constant.")
- in
- let int31_binop_from_const op prim = int31_op_from_const 2 op prim in
- let int31_unop_from_const op prim = int31_op_from_const 1 op prim in
- match field with
- | KInt31 (grp, Int31Type) ->
- let int31bit =
- (* invariant : the type of bits is registered, otherwise the function
- would raise Not_found. The invariant is enforced in safe_typing.ml *)
- match field with
- | KInt31 (grp, Int31Type) -> Retroknowledge.find rk (KInt31 (grp,Int31Bits))
- | _ -> anomaly ~label:"Environ.register"
- (Pp.str "add_int31_decompilation_from_type called with an abnormal field.")
- in
- let i31bit_type =
- match kind int31bit with
- | Ind (i31bit_type,_) -> i31bit_type
- | _ -> anomaly ~label:"Environ.register"
- (Pp.str "Int31Bits should be an inductive type.")
- in
- let int31_decompilation =
- match kind value with
- | Ind (i31t,_) ->
- constr_of_int31 i31t i31bit_type
- | _ -> anomaly ~label:"Environ.register"
- (Pp.str "should be an inductive type.")
- in
- { empty_reactive_info with
- vm_decompile_const = Some int31_decompilation;
- vm_before_match = Some Clambda.int31_escape_before_match;
- native_before_match = Some (Nativelambda.before_match_int31 i31bit_type);
- }
- | KInt31 (_, Int31Constructor) ->
- { empty_reactive_info with
- vm_constant_static = Some Clambda.compile_structured_int31;
- vm_constant_dynamic = Some Clambda.dynamic_int31_compilation;
- native_constant_static = Some Nativelambda.compile_static_int31;
- native_constant_dynamic = Some Nativelambda.compile_dynamic_int31;
- }
- | KInt31 (_, Int31Plus) -> int31_binop_from_const Cbytecodes.Kaddint31
- CPrimitives.Int31add
- | KInt31 (_, Int31PlusC) -> int31_binop_from_const Cbytecodes.Kaddcint31
- CPrimitives.Int31addc
- | KInt31 (_, Int31PlusCarryC) -> int31_binop_from_const Cbytecodes.Kaddcarrycint31
- CPrimitives.Int31addcarryc
- | KInt31 (_, Int31Minus) -> int31_binop_from_const Cbytecodes.Ksubint31
- CPrimitives.Int31sub
- | KInt31 (_, Int31MinusC) -> int31_binop_from_const Cbytecodes.Ksubcint31
- CPrimitives.Int31subc
- | KInt31 (_, Int31MinusCarryC) -> int31_binop_from_const
- Cbytecodes.Ksubcarrycint31 CPrimitives.Int31subcarryc
- | KInt31 (_, Int31Times) -> int31_binop_from_const Cbytecodes.Kmulint31
- CPrimitives.Int31mul
- | KInt31 (_, Int31TimesC) -> int31_binop_from_const Cbytecodes.Kmulcint31
- CPrimitives.Int31mulc
- | KInt31 (_, Int31Div21) -> int31_op_from_const 3 Cbytecodes.Kdiv21int31
- CPrimitives.Int31div21
- | KInt31 (_, Int31Diveucl) -> int31_binop_from_const Cbytecodes.Kdivint31
- CPrimitives.Int31diveucl
- | KInt31 (_, Int31AddMulDiv) -> int31_op_from_const 3 Cbytecodes.Kaddmuldivint31
- CPrimitives.Int31addmuldiv
- | KInt31 (_, Int31Compare) -> int31_binop_from_const Cbytecodes.Kcompareint31
- CPrimitives.Int31compare
- | KInt31 (_, Int31Head0) -> int31_unop_from_const Cbytecodes.Khead0int31
- CPrimitives.Int31head0
- | KInt31 (_, Int31Tail0) -> int31_unop_from_const Cbytecodes.Ktail0int31
- CPrimitives.Int31tail0
- | KInt31 (_, Int31Lor) -> int31_binop_from_const Cbytecodes.Klorint31
- CPrimitives.Int31lor
- | KInt31 (_, Int31Land) -> int31_binop_from_const Cbytecodes.Klandint31
- CPrimitives.Int31land
- | KInt31 (_, Int31Lxor) -> int31_binop_from_const Cbytecodes.Klxorint31
- CPrimitives.Int31lxor
- | _ -> empty_reactive_info
-
-let _ = Hook.set Retroknowledge.dispatch_hook dispatch
diff --git a/kernel/environ.mli b/kernel/environ.mli
index fdd84b25..f45b7be8 100644
--- a/kernel/environ.mli
+++ b/kernel/environ.mli
@@ -28,23 +28,63 @@ open Declarations
- a set of universe constraints
- a flag telling if Set is, can be, or cannot be set impredicative *)
+type lazy_val
+val build_lazy_val : lazy_val -> (Vmvalues.values * Id.Set.t) -> unit
+val force_lazy_val : lazy_val -> (Vmvalues.values * Id.Set.t) option
+val dummy_lazy_val : unit -> lazy_val
+(** Linking information for the native compiler *)
+type link_info =
+ | Linked of string
+ | LinkedInteractive of string
+ | NotLinked
+
+type key = int CEphemeron.key option ref
+
+type constant_key = constant_body * (link_info ref * key)
+
+type mind_key = mutual_inductive_body * link_info ref
+
+type globals
+(** globals = constants + projections + inductive types + modules + module-types *)
+
+type stratification = {
+ env_universes : UGraph.t;
+ env_engagement : engagement
+}
+
+type named_context_val = private {
+ env_named_ctx : Constr.named_context;
+ env_named_map : (Constr.named_declaration * lazy_val) Id.Map.t;
+}
+
+type rel_context_val = private {
+ env_rel_ctx : Constr.rel_context;
+ env_rel_map : (Constr.rel_declaration * lazy_val) Range.t;
+}
+
+type env = private {
+ env_globals : globals;
+ env_named_context : named_context_val; (* section variables *)
+ env_rel_context : rel_context_val;
+ env_nb_rel : int;
+ env_stratification : stratification;
+ env_typing_flags : typing_flags;
+ retroknowledge : Retroknowledge.retroknowledge;
+ indirect_pterms : Opaqueproof.opaquetab;
+}
-type env
-val pre_env : env -> Pre_env.env
-val env_of_pre_env : Pre_env.env -> env
val oracle : env -> Conv_oracle.oracle
val set_oracle : env -> Conv_oracle.oracle -> env
-type named_context_val
val eq_named_context_val : named_context_val -> named_context_val -> bool
val empty_env : env
val universes : env -> UGraph.t
-val rel_context : env -> Context.Rel.t
-val named_context : env -> Context.Named.t
+val rel_context : env -> Constr.rel_context
+val named_context : env -> Constr.named_context
val named_context_val : env -> named_context_val
val opaque_tables : env -> Opaqueproof.opaquetab
@@ -63,24 +103,26 @@ val empty_context : env -> bool
(** {5 Context of de Bruijn variables ([rel_context]) } *)
val nb_rel : env -> int
-val push_rel : Context.Rel.Declaration.t -> env -> env
-val push_rel_context : Context.Rel.t -> env -> env
+val push_rel : Constr.rel_declaration -> env -> env
+val push_rel_context : Constr.rel_context -> env -> env
val push_rec_types : rec_declaration -> env -> env
(** Looks up in the context of local vars referred by indice ([rel_context])
raises [Not_found] if the index points out of the context *)
-val lookup_rel : int -> env -> Context.Rel.Declaration.t
+val lookup_rel : int -> env -> Constr.rel_declaration
+val lookup_rel_val : int -> env -> lazy_val
val evaluable_rel : int -> env -> bool
+val env_of_rel : int -> env -> env
(** {6 Recurrence on [rel_context] } *)
val fold_rel_context :
- (env -> Context.Rel.Declaration.t -> 'a -> 'a) -> env -> init:'a -> 'a
+ (env -> Constr.rel_declaration -> 'a -> 'a) -> env -> init:'a -> 'a
(** {5 Context of variables (section variables and goal assumptions) } *)
-val named_context_of_val : named_context_val -> Context.Named.t
-val val_of_named_context : Context.Named.t -> named_context_val
+val named_context_of_val : named_context_val -> Constr.named_context
+val val_of_named_context : Constr.named_context -> named_context_val
val empty_named_context_val : named_context_val
val ids_of_named_context_val : named_context_val -> Id.Set.t
@@ -91,18 +133,19 @@ val ids_of_named_context_val : named_context_val -> Id.Set.t
val map_named_val :
(constr -> constr) -> named_context_val -> named_context_val
-val push_named : Context.Named.Declaration.t -> env -> env
-val push_named_context : Context.Named.t -> env -> env
+val push_named : Constr.named_declaration -> env -> env
+val push_named_context : Constr.named_context -> env -> env
val push_named_context_val :
- Context.Named.Declaration.t -> named_context_val -> named_context_val
+ Constr.named_declaration -> named_context_val -> named_context_val
(** Looks up in the context of local vars referred by names ([named_context])
raises [Not_found] if the Id.t is not found *)
-val lookup_named : variable -> env -> Context.Named.Declaration.t
-val lookup_named_val : variable -> named_context_val -> Context.Named.Declaration.t
+val lookup_named : variable -> env -> Constr.named_declaration
+val lookup_named_val : variable -> env -> lazy_val
+val lookup_named_ctxt : variable -> named_context_val -> Constr.named_declaration
val evaluable_named : variable -> env -> bool
val named_type : variable -> env -> types
val named_body : variable -> env -> constr option
@@ -110,11 +153,13 @@ val named_body : variable -> env -> constr option
(** {6 Recurrence on [named_context]: older declarations processed first } *)
val fold_named_context :
- (env -> Context.Named.Declaration.t -> 'a -> 'a) -> env -> init:'a -> 'a
+ (env -> Constr.named_declaration -> 'a -> 'a) -> env -> init:'a -> 'a
+
+val set_universes : env -> UGraph.t -> env
(** Recurrence on [named_context] starting from younger decl *)
val fold_named_context_reverse :
- ('a -> Context.Named.Declaration.t -> 'a) -> init:'a -> env -> 'a
+ ('a -> Constr.named_declaration -> 'a) -> init:'a -> env -> 'a
(** This forgets named and rel contexts *)
val reset_context : env -> env
@@ -125,12 +170,16 @@ val reset_with_named_context : named_context_val -> env -> env
(** This removes the [n] last declarations from the rel context *)
val pop_rel_context : int -> env -> env
+(** Useful for printing *)
+val fold_constants : (Constant.t -> constant_body -> 'a -> 'a) -> env -> 'a -> 'a
+
(** {5 Global constants }
{6 Add entries to global environment } *)
val add_constant : Constant.t -> constant_body -> env -> env
-val add_constant_key : Constant.t -> constant_body -> Pre_env.link_info ->
+val add_constant_key : Constant.t -> constant_body -> link_info ->
env -> env
+val lookup_constant_key : Constant.t -> env -> constant_key
(** Looks up in the context of global constant names
raises [Not_found] if the required path is not found *)
@@ -168,11 +217,15 @@ val constant_opt_value_in : env -> Constant.t puniverses -> constr option
(** {6 Primitive projections} *)
-val lookup_projection : Names.Projection.t -> env -> projection_body
-val is_projection : Constant.t -> env -> bool
+(** Checks that the number of parameters is correct. *)
+val lookup_projection : Names.Projection.t -> env -> types
+
+val get_projection : env -> inductive -> proj_arg:int -> Names.Projection.Repr.t option
+val get_projections : env -> inductive -> Names.Projection.Repr.t array option
(** {5 Inductive types } *)
-val add_mind_key : MutInd.t -> Pre_env.mind_key -> env -> env
+val lookup_mind_key : MutInd.t -> env -> mind_key
+val add_mind_key : MutInd.t -> mind_key -> env -> env
val add_mind : MutInd.t -> mutual_inductive_body -> env -> env
(** Looks up in the context of global inductive names
@@ -228,7 +281,7 @@ val vars_of_global : env -> constr -> Id.Set.t
val really_needed : env -> Id.Set.t -> Id.Set.t
(** like [really_needed] but computes a well ordered named context *)
-val keep_hyps : env -> Id.Set.t -> Context.Named.t
+val keep_hyps : env -> Id.Set.t -> Constr.named_context
(** {5 Unsafe judgments. }
We introduce here the pre-type of judgments, which is
@@ -251,20 +304,16 @@ type 'types punsafe_type_judgment = {
type unsafe_type_judgment = types punsafe_type_judgment
-(** {6 Compilation of global declaration } *)
-
-val compile_constant_body : env -> constant_universes -> constant_def -> Cemitcodes.body_code option
-
exception Hyp_not_found
(** [apply_to_hyp sign id f] split [sign] into [tail::(id,_,_)::head] and
return [tail::(f head (id,_,_) (rev tail))::head].
the value associated to id should not change *)
val apply_to_hyp : named_context_val -> variable ->
- (Context.Named.t -> Context.Named.Declaration.t -> Context.Named.t -> Context.Named.Declaration.t) ->
+ (Constr.named_context -> Constr.named_declaration -> Constr.named_context -> Constr.named_declaration) ->
named_context_val
-val remove_hyps : Id.Set.t -> (Context.Named.Declaration.t -> Context.Named.Declaration.t) -> (Pre_env.lazy_val -> Pre_env.lazy_val) -> named_context_val -> named_context_val
+val remove_hyps : Id.Set.t -> (Constr.named_declaration -> Constr.named_declaration) -> (lazy_val -> lazy_val) -> named_context_val -> named_context_val
@@ -272,10 +321,11 @@ open Retroknowledge
(** functions manipulating the retroknowledge
@author spiwack *)
val retroknowledge : (retroknowledge->'a) -> env -> 'a
+[@@ocaml.deprecated "Use the record projection."]
val registered : env -> field -> bool
val register : env -> field -> Retroknowledge.entry -> env
(** Native compiler *)
-val no_link_info : Pre_env.link_info
+val no_link_info : link_info
diff --git a/kernel/esubst.ml b/kernel/esubst.ml
index a11a0dc0..9fc3b11d 100644
--- a/kernel/esubst.ml
+++ b/kernel/esubst.ml
@@ -19,6 +19,8 @@ open Util
(*********************)
(* Explicit lifts and basic operations *)
+(* Invariant to preserve in this module: no lift contains two consecutive
+ [ELSHFT] nor two consecutive [ELLFT]. *)
type lift =
| ELID
| ELSHFT of lift * int (* ELSHFT(l,n) == lift of n, then apply lift l *)
@@ -28,15 +30,15 @@ type lift =
let el_id = ELID
(* compose a relocation of magnitude n *)
-let rec el_shft_rec n = function
- | ELSHFT(el,k) -> el_shft_rec (k+n) el
+let el_shft_rec n = function
+ | ELSHFT(el,k) -> ELSHFT(el,k+n)
| el -> ELSHFT(el,n)
let el_shft n el = if Int.equal n 0 then el else el_shft_rec n el
(* cross n binders *)
-let rec el_liftn_rec n = function
+let el_liftn_rec n = function
| ELID -> ELID
- | ELLFT(k,el) -> el_liftn_rec (n+k) el
+ | ELLFT(k,el) -> ELLFT(n+k, el)
| el -> ELLFT(n, el)
let el_liftn n el = if Int.equal n 0 then el else el_liftn_rec n el
@@ -132,13 +134,36 @@ let rec exp_rel lams k subs =
let expand_rel k subs = exp_rel 0 k subs
+let rec subs_map f = function
+| ESID _ as s -> s
+| CONS (x, s) -> CONS (Array.map f x, subs_map f s)
+| SHIFT (n, s) -> SHIFT (n, subs_map f s)
+| LIFT (n, s) -> LIFT (n, subs_map f s)
+
+let rec lift_subst mk_cl s1 s2 = match s1 with
+| ELID -> subs_map (fun c -> mk_cl ELID c) s2
+| ELSHFT(s, k) -> subs_shft(k, lift_subst mk_cl s s2)
+| ELLFT (k, s) ->
+ match s2 with
+ | CONS(x,s') ->
+ CONS(CArray.Fun1.map mk_cl s1 x, lift_subst mk_cl s1 s')
+ | ESID n -> lift_subst mk_cl s (ESID (n + k))
+ | SHIFT(k',s') ->
+ if k<k'
+ then subs_shft(k, lift_subst mk_cl s (subs_shft(k'-k, s')))
+ else subs_shft(k', lift_subst mk_cl (el_liftn (k-k') s) s')
+ | LIFT(k',s') ->
+ if k<k'
+ then subs_liftn k (lift_subst mk_cl s (subs_liftn (k'-k) s'))
+ else subs_liftn k' (lift_subst mk_cl (el_liftn (k-k') s) s')
+
let rec comp mk_cl s1 s2 =
match (s1, s2) with
| _, ESID _ -> s1
| ESID _, _ -> s2
| SHIFT(k,s), _ -> subs_shft(k, comp mk_cl s s2)
| _, CONS(x,s') ->
- CONS(CArray.Fun1.map (fun s t -> mk_cl(s,t)) s1 x, comp mk_cl s1 s')
+ CONS(Array.Fun1.map (fun s t -> mk_cl(s,t)) s1 x, comp mk_cl s1 s')
| CONS(x,s), SHIFT(k,s') ->
let lg = Array.length x in
if k == lg then comp mk_cl s s'
diff --git a/kernel/esubst.mli b/kernel/esubst.mli
index b82d6fdf..475b64f4 100644
--- a/kernel/esubst.mli
+++ b/kernel/esubst.mli
@@ -56,7 +56,11 @@ val comp : ('a subs * 'a -> 'a) -> 'a subs -> 'a subs -> 'a subs
(** {6 Compact representation } *)
(** Compact representation of explicit relocations
- [ELSHFT(l,n)] == lift of [n], then apply [lift l].
- - [ELLFT(n,l)] == apply [l] to de Bruijn > [n] i.e under n binders. *)
+ - [ELLFT(n,l)] == apply [l] to de Bruijn > [n] i.e under n binders.
+
+ Invariant ensured by the private flag: no lift contains two consecutive
+ [ELSHFT] nor two consecutive [ELLFT].
+*)
type lift = private
| ELID
| ELSHFT of lift * int
@@ -68,3 +72,10 @@ val el_liftn : int -> lift -> lift
val el_lift : lift -> lift
val reloc_rel : int -> lift -> int
val is_lift_id : lift -> bool
+
+(** Lift applied to substitution: [lift_subst mk_clos el s] computes a
+ substitution equivalent to applying el then s. Argument
+ mk_clos is used when a closure has to be created, i.e. when
+ el is applied on an element of s.
+*)
+val lift_subst : (lift -> 'a -> 'b) -> lift -> 'a subs -> 'b subs
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml
index 85be2146..14decafc 100644
--- a/kernel/indtypes.ml
+++ b/kernel/indtypes.ml
@@ -120,16 +120,6 @@ let mind_check_names mie =
(* Typing the arities and constructor types *)
-(* An inductive definition is a "unit" if it has only one constructor
- and that all arguments expected by this constructor are
- logical, this is the case for equality, conjunction of logical properties
-*)
-let is_unit constrsinfos =
- match constrsinfos with (* One info = One constructor *)
- | [level] -> is_type0m_univ level
- | [] -> (* type without constructors *) true
- | _ -> false
-
let infos_and_sort env t =
let rec aux env t max =
let t = whd_all env t in
@@ -174,10 +164,9 @@ let infer_constructor_packet env_ar_par params lc =
let lc'' = Array.map (fun j -> Term.it_mkProd_or_LetIn j.utj_val params) jlc in
(* compute the max of the sorts of the products of the constructors types *)
let levels = List.map (infos_and_sort env_ar_par) lc in
- let isunit = is_unit levels in
let min = if Array.length jlc > 1 then Universe.type0 else Universe.type0m in
let level = List.fold_left (fun max l -> Universe.sup max l) min levels in
- (lc'', (isunit, level))
+ (lc'', level)
(* If indices matter *)
let cumulate_arity_large_levels env sign =
@@ -353,7 +342,7 @@ let typecheck_inductive env mie =
(* Compute/check the sorts of the inductive types *)
let inds =
- Array.map (fun ((id,full_arity,sign,expltype,def_level,inf_level),cn,lc,(is_unit,clev)) ->
+ Array.map (fun ((id,full_arity,sign,expltype,def_level,inf_level),cn,lc,clev) ->
let infu =
(** Inferred level, with parameters and constructors. *)
match inf_level with
@@ -424,7 +413,7 @@ let typecheck_inductive env mie =
type ill_formed_ind =
| LocalNonPos of int
| LocalNotEnoughArgs of int
- | LocalNotConstructor of Context.Rel.t * int
+ | LocalNotConstructor of Constr.rel_context * int
| LocalNonPar of int * int * int
exception IllFormedInd of ill_formed_ind
@@ -796,69 +785,47 @@ exception UndefinableExpansion
build an expansion function.
The term built is expecting to be substituted first by
a substitution of the form [params, x : ind params] *)
-let compute_projections ((kn, _ as ind), u as indu) n x nparamargs params
- mind_consnrealdecls mind_consnrealargs paramslet ctx =
- let mp, dp, l = MutInd.repr3 kn in
+let compute_projections (kn, i as ind) mib =
+ let pkt = mib.mind_packets.(i) in
+ let u = match mib.mind_universes with
+ | Monomorphic_ind _ -> Univ.Instance.empty
+ | Polymorphic_ind auctx -> Univ.make_abstract_instance auctx
+ | Cumulative_ind acumi -> Univ.make_abstract_instance (Univ.ACumulativityInfo.univ_context acumi)
+ in
+ let subst = List.init mib.mind_ntypes (fun i -> mkIndU ((kn, mib.mind_ntypes - i - 1), u)) in
+ let rctx, _ = decompose_prod_assum (substl subst pkt.mind_nf_lc.(0)) in
+ let ctx, paramslet = List.chop pkt.mind_consnrealdecls.(0) rctx in
(** We build a substitution smashing the lets in the record parameters so
that typechecking projections requires just a substitution and not
matching with a parameter context. *)
- let indty, paramsletsubst =
- (* [ty] = [Ind inst] is typed in context [params] *)
- let inst = Context.Rel.to_extended_vect mkRel 0 paramslet in
- let ty = mkApp (mkIndU indu, inst) in
+ let paramsletsubst =
(* [Ind inst] is typed in context [params-wo-let] *)
- let inst' = rel_list 0 nparamargs in
+ let inst' = rel_list 0 mib.mind_nparams in
(* {params-wo-let |- subst:params] *)
let subst = subst_of_rel_context_instance paramslet inst' in
(* {params-wo-let, x:Ind inst' |- subst':(params,x:Ind inst)] *)
let subst = (* For the record parameter: *)
mkRel 1 :: List.map (lift 1) subst in
- ty, subst
+ subst
in
- let ci =
- let print_info =
- { ind_tags = []; cstr_tags = [|Context.Rel.to_tags ctx|]; style = LetStyle } in
- { ci_ind = ind;
- ci_npar = nparamargs;
- ci_cstr_ndecls = mind_consnrealdecls;
- ci_cstr_nargs = mind_consnrealargs;
- ci_pp_info = print_info }
- in
- let len = List.length ctx in
- let x = Name x in
- let compat_body ccl i =
- (* [ccl] is defined in context [params;x:indty] *)
- (* [ccl'] is defined in context [params;x:indty;x:indty] *)
- let ccl' = liftn 1 2 ccl in
- let p = mkLambda (x, lift 1 indty, ccl') in
- let branch = it_mkLambda_or_LetIn (mkRel (len - i)) ctx in
- let body = mkCase (ci, p, mkRel 1, [|lift 1 branch|]) in
- it_mkLambda_or_LetIn (mkLambda (x,indty,body)) params
- in
- let projections decl (i, j, kns, pbs, subst, letsubst) =
+ let projections decl (i, j, labs, pbs, letsubst) =
match decl with
| LocalDef (na,c,t) ->
(* From [params, field1,..,fieldj |- c(params,field1,..,fieldj)]
to [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)] *)
let c = liftn 1 j c in
(* From [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)]
- to [params, x:I |- c(params,proj1 x,..,projj x)] *)
- let c1 = substl subst c in
- (* From [params, x:I |- subst:field1,..,fieldj]
- to [params, x:I |- subst:field1,..,fieldj+1] where [subst]
- is represented with instance of field1 last *)
- let subst = c1 :: subst in
- (* From [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)]
to [params-wo-let, x:I |- c(params,proj1 x,..,projj x)] *)
let c2 = substl letsubst c in
(* From [params-wo-let, x:I |- subst:(params, x:I, field1,..,fieldj)]
to [params-wo-let, x:I |- subst:(params, x:I, field1,..,fieldj+1)] *)
let letsubst = c2 :: letsubst in
- (i, j+1, kns, pbs, subst, letsubst)
+ (i, j+1, labs, pbs, letsubst)
| LocalAssum (na,t) ->
match na with
| Name id ->
- let kn = Constant.make1 (KerName.make mp dp (Label.of_id id)) in
+ let lab = Label.of_id id in
+ let kn = Projection.Repr.make ind ~proj_npars:mib.mind_nparams ~proj_arg:i lab in
(* from [params, field1,..,fieldj |- t(params,field1,..,fieldj)]
to [params, x:I, field1,..,fieldj |- t(params,field1,..,fieldj] *)
let t = liftn 1 j t in
@@ -867,23 +834,14 @@ let compute_projections ((kn, _ as ind), u as indu) n x nparamargs params
let projty = substl letsubst t in
(* from [params, x:I, field1,..,fieldj |- t(field1,..,fieldj)]
to [params, x:I |- t(proj1 x,..,projj x)] *)
- let ty = substl subst t in
- let term = mkProj (Projection.make kn true, mkRel 1) in
let fterm = mkProj (Projection.make kn false, mkRel 1) in
- let compat = compat_body ty (j - 1) in
- let etab = it_mkLambda_or_LetIn (mkLambda (x, indty, term)) params in
- let etat = it_mkProd_or_LetIn (mkProd (x, indty, ty)) params in
- let body = { proj_ind = fst ind; proj_npars = nparamargs;
- proj_arg = i; proj_type = projty; proj_eta = etab, etat;
- proj_body = compat } in
- (i + 1, j + 1, kn :: kns, body :: pbs,
- fterm :: subst, fterm :: letsubst)
+ (i + 1, j + 1, lab :: labs, projty :: pbs, fterm :: letsubst)
| Anonymous -> raise UndefinableExpansion
in
- let (_, _, kns, pbs, subst, letsubst) =
- List.fold_right projections ctx (0, 1, [], [], [], paramsletsubst)
+ let (_, _, labs, pbs, letsubst) =
+ List.fold_right projections ctx (0, 1, [], [], paramsletsubst)
in
- Array.of_list (List.rev kns),
+ Array.of_list (List.rev labs),
Array.of_list (List.rev pbs)
let abstract_inductive_universes iu =
@@ -968,33 +926,9 @@ let build_inductive env prv iu env_ar paramsctxt kn isrecord isfinite inds nmr r
mind_reloc_tbl = rtbl;
} in
let packets = Array.map2 build_one_packet inds recargs in
- let pkt = packets.(0) in
- let isrecord =
- match isrecord with
- | Some (Some rid) when pkt.mind_kelim == all_sorts
- && Array.length pkt.mind_consnames == 1
- && pkt.mind_consnrealargs.(0) > 0 ->
- (** The elimination criterion ensures that all projections can be defined. *)
- let u =
- match aiu with
- | Monomorphic_ind _ -> Univ.Instance.empty
- | Polymorphic_ind auctx -> Univ.make_abstract_instance auctx
- | Cumulative_ind acumi -> Univ.make_abstract_instance (Univ.ACumulativityInfo.univ_context acumi)
- in
- let indsp = ((kn, 0), u) in
- let rctx, indty = decompose_prod_assum (subst1 (mkIndU indsp) pkt.mind_nf_lc.(0)) in
- (try
- let fields, paramslet = List.chop pkt.mind_consnrealdecls.(0) rctx in
- let kns, projs =
- compute_projections indsp pkt.mind_typename rid nparamargs paramsctxt
- pkt.mind_consnrealdecls pkt.mind_consnrealargs paramslet fields
- in Some (Some (rid, kns, projs))
- with UndefinableExpansion -> Some None)
- | Some _ -> Some None
- | None -> None
- in
- (* Build the mutual inductive *)
- { mind_record = isrecord;
+ let mib =
+ (* Build the mutual inductive *)
+ { mind_record = NotRecord;
mind_ntypes = ntypes;
mind_finite = isfinite;
mind_hyps = hyps;
@@ -1006,6 +940,27 @@ let build_inductive env prv iu env_ar paramsctxt kn isrecord isfinite inds nmr r
mind_private = prv;
mind_typing_flags = Environ.typing_flags env;
}
+ in
+ let record_info = match isrecord with
+ | Some (Some rid) ->
+ let is_record pkt =
+ pkt.mind_kelim == all_sorts
+ && Array.length pkt.mind_consnames == 1
+ && pkt.mind_consnrealargs.(0) > 0
+ in
+ (** The elimination criterion ensures that all projections can be defined. *)
+ if Array.for_all is_record packets then
+ let map i id =
+ let labs, projs = compute_projections (kn, i) mib in
+ (id, labs, projs)
+ in
+ try PrimRecord (Array.mapi map rid)
+ with UndefinableExpansion -> FakeRecord
+ else FakeRecord
+ | Some None -> FakeRecord
+ | None -> NotRecord
+ in
+ { mib with mind_record = record_info }
(************************************************************************)
(************************************************************************)
diff --git a/kernel/indtypes.mli b/kernel/indtypes.mli
index 5a38172c..cb09cfa8 100644
--- a/kernel/indtypes.mli
+++ b/kernel/indtypes.mli
@@ -42,8 +42,3 @@ val check_inductive : env -> MutInd.t -> mutual_inductive_entry -> mutual_induct
val enforce_indices_matter : unit -> unit
val is_indices_matter : unit -> bool
-
-val compute_projections : pinductive -> Id.t -> Id.t ->
- int -> Context.Rel.t -> int array -> int array ->
- Context.Rel.t -> Context.Rel.t ->
- (Constant.t array * projection_body array)
diff --git a/kernel/inductive.ml b/kernel/inductive.ml
index 9bed598b..4d13a5fc 100644
--- a/kernel/inductive.ml
+++ b/kernel/inductive.ml
@@ -130,11 +130,6 @@ where
Remark: Set (predicative) is encoded as Type(0)
*)
-let sort_as_univ = let open Sorts in function
-| Type u -> u
-| Prop Null -> Universe.type0m
-| Prop Pos -> Universe.type0
-
(* Template polymorphism *)
(* cons_subst add the mapping [u |-> su] in subst if [u] is not *)
@@ -168,7 +163,7 @@ let make_subst env =
(* arity is a global level which, at typing time, will be enforce *)
(* to be greater than the level of the argument; this is probably *)
(* a useless extra constraint *)
- let s = sort_as_univ (snd (dest_arity env (Lazy.force a))) in
+ let s = Sorts.univ_of_sort (snd (dest_arity env (Lazy.force a))) in
make (cons_subst u s subst) (sign, exp, args)
| LocalAssum (na,t) :: sign, Some u::exp, [] ->
(* No more argument here: we add the remaining universes to the *)
@@ -236,8 +231,8 @@ let type_of_inductive_knowing_parameters env ?(polyprop=true) mip args =
(* The max of an array of universes *)
let cumulate_constructor_univ u = let open Sorts in function
- | Prop Null -> u
- | Prop Pos -> Universe.sup Universe.type0 u
+ | Prop -> u
+ | Set -> Universe.sup Universe.type0 u
| Type u' -> Universe.sup u u'
let max_inductive_sort =
@@ -293,8 +288,8 @@ let elim_sorts (_,mip) = mip.mind_kelim
let is_private (mib,_) = mib.mind_private = Some true
let is_primitive_record (mib,_) =
match mib.mind_record with
- | Some (Some _) -> true
- | _ -> false
+ | PrimRecord _ -> true
+ | NotRecord | FakeRecord -> false
let build_dependent_inductive ind (_,mip) params =
let realargs,_ = List.chop mip.mind_nrealdecls mip.mind_arity_ctxt in
@@ -790,7 +785,7 @@ let rec subterm_specif renv stack t =
| Lambda (x,a,b) ->
let () = assert (List.is_empty l) in
- let spec,stack' = extract_stack renv a stack in
+ let spec,stack' = extract_stack stack in
subterm_specif (push_var renv (x,a,spec)) stack' b
(* Metas and evars are considered OK *)
@@ -803,10 +798,7 @@ let rec subterm_specif renv stack t =
(* We take the subterm specs of the constructor of the record *)
let wf_args = (dest_subterms wf).(0) in
(* We extract the tree of the projected argument *)
- let kn = Projection.constant p in
- let cb = lookup_constant kn renv.env in
- let pb = Option.get cb.const_proj in
- let n = pb.proj_arg in
+ let n = Projection.arg p in
spec_of_tree (List.nth wf_args n)
| Dead_code -> Dead_code
| Not_subterm -> Not_subterm)
@@ -824,7 +816,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
@@ -855,7 +847,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. *)
@@ -940,7 +932,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
@@ -983,7 +975,7 @@ let check_one_fix renv recpos trees def =
| Lambda (x,a,b) ->
let () = assert (List.is_empty l) in
check_rec_call renv [] a ;
- let spec, stack' = extract_stack renv a stack in
+ let spec, stack' = extract_stack stack in
check_rec_call (push_var renv (x,a,spec)) stack' b
| Prod (x,a,b) ->
diff --git a/kernel/inductive.mli b/kernel/inductive.mli
index c7982f1f..3c1464c6 100644
--- a/kernel/inductive.mli
+++ b/kernel/inductive.mli
@@ -36,7 +36,7 @@ val lookup_mind_specif : env -> inductive -> mind_specif
(** {6 Functions to build standard types related to inductive } *)
val ind_subst : MutInd.t -> mutual_inductive_body -> Instance.t -> constr list
-val inductive_paramdecls : mutual_inductive_body puniverses -> Context.Rel.t
+val inductive_paramdecls : mutual_inductive_body puniverses -> Constr.rel_context
val instantiate_inductive_constraints :
mutual_inductive_body -> Instance.t -> Constraint.t
@@ -87,7 +87,7 @@ val build_branches_type :
constr list -> constr -> types array
(** Return the arity of an inductive type *)
-val mind_arity : one_inductive_body -> Context.Rel.t * Sorts.family
+val mind_arity : one_inductive_body -> Constr.rel_context * Sorts.family
val inductive_sort_family : one_inductive_body -> Sorts.family
@@ -115,8 +115,8 @@ exception SingletonInductiveBecomesProp of Id.t
val max_inductive_sort : Sorts.t array -> Universe.t
-val instantiate_universes : env -> Context.Rel.t ->
- template_arity -> constr Lazy.t array -> Context.Rel.t * Sorts.t
+val instantiate_universes : env -> Constr.rel_context ->
+ template_arity -> constr Lazy.t array -> Constr.rel_context * Sorts.t
(** {6 Debug} *)
diff --git a/kernel/kernel.mllib b/kernel/kernel.mllib
index 370185a7..a18c5d1e 100644
--- a/kernel/kernel.mllib
+++ b/kernel/kernel.mllib
@@ -5,32 +5,34 @@ UGraph
Esubst
Sorts
Evar
-Constr
Context
+Constr
Vars
Term
Mod_subst
+Vmvalues
Cbytecodes
Copcodes
Cemitcodes
Opaqueproof
Declarations
Entries
-Vmvalues
Nativevalues
CPrimitives
Declareops
Retroknowledge
Conv_oracle
-Pre_env
+Environ
+CClosure
+Reduction
Clambda
Nativelambda
Cbytegen
Nativecode
Nativelib
-Environ
-CClosure
-Reduction
+Csymtable
+Vm
+Vconv
Nativeconv
Type_errors
Modops
@@ -43,6 +45,3 @@ Subtyping
Mod_typing
Nativelibrary
Safe_typing
-Vm
-Csymtable
-Vconv
diff --git a/kernel/mod_subst.ml b/kernel/mod_subst.ml
index b3d06ce7..b35b9dda 100644
--- a/kernel/mod_subst.ml
+++ b/kernel/mod_subst.ml
@@ -24,7 +24,7 @@ open Constr
is the term into which we should inline. *)
type delta_hint =
- | Inline of int * constr option
+ | Inline of int * (Univ.AUContext.t * constr) option
| Equiv of KerName.t
(* NB: earlier constructor Prefix_equiv of ModPath.t
@@ -158,7 +158,7 @@ let find_prefix resolve mp =
(** Applying a resolver to a kernel name *)
-exception Change_equiv_to_inline of (int * constr)
+exception Change_equiv_to_inline of (int * (Univ.AUContext.t * constr))
let solve_delta_kn resolve kn =
try
@@ -300,8 +300,9 @@ let subst_con0 sub (cst,u) =
let knu = KerName.make mpu dir l in
let knc = if mpu == mpc then knu else KerName.make mpc dir l in
match search_delta_inline resolve knu knc with
- | Some t ->
+ | Some (ctx, t) ->
(* In case of inlining, discard the canonical part (cf #2608) *)
+ let () = assert (Int.equal (Univ.AUContext.size ctx) (Univ.Instance.length u)) in
Constant.make1 knu, Vars.subst_instance_constr u t
| None ->
let knc' =
@@ -331,6 +332,12 @@ let subst_constant sub con =
try fst (subst_con0 sub (con,Univ.Instance.empty))
with No_subst -> con
+let subst_proj_repr sub p =
+ Projection.Repr.map (subst_mind sub) p
+
+let subst_proj sub p =
+ Projection.map (subst_mind sub) p
+
(* Here the semantics is completely unclear.
What does "Hint Unfold t" means when "t" is a parameter?
Does the user mean "Unfold X.t" or does she mean "Unfold y"
@@ -345,11 +352,7 @@ let rec map_kn f f' c =
match kind c with
| Const kn -> (try snd (f' kn) with No_subst -> c)
| Proj (p,t) ->
- let p' =
- try
- Projection.map (fun kn -> fst (f' (kn,Univ.Instance.empty))) p
- with No_subst -> p
- in
+ let p' = Projection.map f p in
let t' = func t in
if p' == p && t' == t then c
else mkProj (p', t')
@@ -367,7 +370,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
@@ -396,21 +399,21 @@ let rec map_kn f f' c =
else mkLetIn (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 mkApp (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 mkEvar (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 mkFix (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 mkCoFix (ln,(lna,tl',bl'))
| _ -> c
@@ -482,7 +485,7 @@ let gen_subst_delta_resolver dom subst resolver =
| Equiv kequ ->
(try Equiv (subst_kn_delta subst kequ)
with Change_equiv_to_inline (lev,c) -> Inline (lev,Some c))
- | 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
diff --git a/kernel/mod_subst.mli b/kernel/mod_subst.mli
index b14d3920..2e5211c7 100644
--- a/kernel/mod_subst.mli
+++ b/kernel/mod_subst.mli
@@ -28,7 +28,7 @@ val add_kn_delta_resolver :
KerName.t -> KerName.t -> delta_resolver -> delta_resolver
val add_inline_delta_resolver :
- KerName.t -> (int * constr option) -> delta_resolver -> delta_resolver
+ KerName.t -> (int * (Univ.AUContext.t * constr) option) -> delta_resolver -> delta_resolver
val add_delta_resolver : delta_resolver -> delta_resolver -> delta_resolver
@@ -147,6 +147,9 @@ val subst_con_kn :
val subst_constant :
substitution -> Constant.t -> Constant.t
+val subst_proj_repr : substitution -> Projection.Repr.t -> Projection.Repr.t
+val subst_proj : substitution -> Projection.t -> Projection.t
+
(** Here the semantics is completely unclear.
What does "Hint Unfold t" means when "t" is a parameter?
Does the user mean "Unfold X.t" or does she mean "Unfold y"
diff --git a/kernel/mod_typing.ml b/kernel/mod_typing.ml
index 1baab7c9..d63dc057 100644
--- a/kernel/mod_typing.ml
+++ b/kernel/mod_typing.ml
@@ -120,7 +120,7 @@ let rec check_with_def env struc (idl,(c,ctx)) mp equiv =
const_body = def;
const_universes = univs ;
const_body_code = Option.map Cemitcodes.from_val
- (compile_constant_body env' cb.const_universes def) }
+ (Cbytegen.compile_constant_body ~fail_on_error:false env' cb.const_universes def) }
in
before@(lab,SFBconst(cb'))::after, c', ctx'
else
diff --git a/kernel/modops.ml b/kernel/modops.ml
index ab187dba..98a99731 100644
--- a/kernel/modops.ml
+++ b/kernel/modops.ml
@@ -129,10 +129,10 @@ let destr_nofunctor = function
|NoFunctor a -> a
|MoreFunctor _ -> error_is_a_functor ()
-let rec functor_smartmap fty f0 funct = match funct with
+let rec functor_smart_map fty f0 funct = match funct with
|MoreFunctor (mbid,ty,e) ->
let ty' = fty ty in
- let e' = functor_smartmap fty f0 e in
+ let e' = functor_smart_map fty f0 e in
if ty==ty' && e==e' then funct else MoreFunctor (mbid,ty',e')
|NoFunctor a ->
let a' = f0 a in if a==a' then funct else NoFunctor a'
@@ -196,7 +196,7 @@ let rec subst_structure sub do_delta sign =
let mtb' = subst_modtype sub do_delta mtb in
if mtb==mtb' then orig else (l,SFBmodtype mtb')
in
- List.smartmap subst_body sign
+ List.Smart.map subst_body sign
and subst_body : 'a. _ -> _ -> (_ -> 'a -> 'a) -> _ -> 'a generic_module_body -> 'a generic_module_body =
fun is_mod sub subst_impl do_delta mb ->
@@ -209,7 +209,7 @@ and subst_body : 'a. _ -> _ -> (_ -> 'a -> 'a) -> _ -> 'a generic_module_body ->
in
let ty' = subst_signature sub do_delta ty in
let me' = subst_impl sub me in
- let aty' = Option.smartmap (subst_expression sub id_delta) aty in
+ let aty' = Option.Smart.map (subst_expression sub id_delta) aty in
let delta' = do_delta mb.mod_delta sub in
if mp==mp' && me==me' && ty==ty' && aty==aty' && delta'==mb.mod_delta
then mb
@@ -244,12 +244,12 @@ and subst_expr sub do_delta seb = match seb with
if meb==meb' && wdb==wdb' then seb else MEwith(meb',wdb')
and subst_expression sub do_delta =
- functor_smartmap
+ functor_smart_map
(subst_modtype sub do_delta)
(subst_expr sub do_delta)
and subst_signature sub do_delta =
- functor_smartmap
+ functor_smart_map
(subst_modtype sub do_delta)
(subst_structure sub do_delta)
@@ -265,7 +265,7 @@ let subst_structure subst = subst_structure subst do_delta_codom
(* spiwack: here comes the function which takes care of importing
the retroknowledge declared in the library *)
(* lclrk : retroknowledge_action list, rkaction : retroknowledge action *)
-let add_retroknowledge mp =
+let add_retroknowledge =
let perform rkaction env = match rkaction with
| Retroknowledge.RKRegister (f, e) when (isConst e || isInd e) ->
Environ.register env f e
@@ -309,7 +309,7 @@ and add_module mb linkinfo env =
let env = Environ.shallow_add_module mb env in
match mb.mod_type with
|NoFunctor struc ->
- add_retroknowledge mp mb.mod_retroknowledge
+ add_retroknowledge mb.mod_retroknowledge
(add_structure mp struc mb.mod_delta linkinfo env)
|MoreFunctor _ -> env
@@ -402,7 +402,8 @@ let inline_delta_resolver env inl mp mbid mtb delta =
| Undef _ | OpaqueDef _ -> l
| Def body ->
let constr = Mod_subst.force_constr body in
- add_inline_delta_resolver kn (lev, Some constr) l
+ let ctx = Declareops.constant_polymorphic_context constant in
+ add_inline_delta_resolver kn (lev, Some (ctx, constr)) l
with Not_found ->
error_no_such_label_sub (Constant.label con)
(ModPath.to_string (Constant.modpath con))
@@ -594,13 +595,13 @@ and clean_field l field = match field with
if mb==mb' then field else (lab,SFBmodule mb')
|_ -> field
-and clean_structure l = List.smartmap (clean_field l)
+and clean_structure l = List.Smart.map (clean_field l)
and clean_signature l =
- functor_smartmap (clean_module_type l) (clean_structure l)
+ functor_smart_map (clean_module_type l) (clean_structure l)
and clean_expression l =
- functor_smartmap (clean_module_type l) (fun me -> me)
+ functor_smart_map (clean_module_type l) (fun me -> me)
let rec collect_mbid l sign = match sign with
|MoreFunctor (mbid,ty,m) ->
diff --git a/kernel/modops.mli b/kernel/modops.mli
index 1db489e6..8e7e618f 100644
--- a/kernel/modops.mli
+++ b/kernel/modops.mli
@@ -52,7 +52,7 @@ val add_module : module_body -> env -> env
(** same as add_module, but for a module whose native code has been linked by
the native compiler. The linking information is updated. *)
-val add_linked_module : module_body -> Pre_env.link_info -> env -> env
+val add_linked_module : module_body -> link_info -> env -> env
(** same, for a module type *)
val add_module_type : ModPath.t -> module_type_body -> env -> env
diff --git a/kernel/names.ml b/kernel/names.ml
index a3aa71f2..e1d70e81 100644
--- a/kernel/names.ml
+++ b/kernel/names.ml
@@ -17,7 +17,7 @@
the module system, Aug 2002 *)
(* Abstraction over the type of constant for module inlining by Claudio
Sacerdoti, Nov 2004 *)
-(* Miscellaneous features or improvements by Hugo Herbelin,
+(* Miscellaneous features or improvements by Hugo Herbelin,
Élie Soubiran, ... *)
open Pp
@@ -364,7 +364,6 @@ module MPmap = CMap.Make(ModPath)
module KerName = struct
type t = {
- canary : Canary.t;
modpath : ModPath.t;
dirpath : DirPath.t;
knlabel : Label.t;
@@ -372,16 +371,14 @@ module KerName = struct
(** Lazily computed hash. If unset, it is set to negative values. *)
}
- let canary = Canary.obj
-
type kernel_name = t
let make modpath dirpath knlabel =
- { modpath; dirpath; knlabel; refhash = -1; canary; }
+ { modpath; dirpath; knlabel; refhash = -1; }
let repr kn = (kn.modpath, kn.dirpath, kn.knlabel)
let make2 modpath knlabel =
- { modpath; dirpath = DirPath.empty; knlabel; refhash = -1; canary; }
+ { modpath; dirpath = DirPath.empty; knlabel; refhash = -1; }
let modpath kn = kn.modpath
let label kn = kn.knlabel
@@ -437,7 +434,7 @@ module KerName = struct
* (string -> string)
let hashcons (hmod,hdir,hstr) kn =
let { modpath = mp; dirpath = dp; knlabel = l; refhash; } = kn in
- { modpath = hmod mp; dirpath = hdir dp; knlabel = hstr l; refhash; canary; }
+ { modpath = hmod mp; dirpath = hdir dp; knlabel = hstr l; refhash; }
let eq kn1 kn2 =
kn1.modpath == kn2.modpath && kn1.dirpath == kn2.dirpath &&
kn1.knlabel == kn2.knlabel
@@ -701,22 +698,6 @@ end
module Constrmap = Map.Make(ConstructorOrdered)
module Constrmap_env = Map.Make(ConstructorOrdered_env)
-type global_reference =
- | VarRef of variable (** A reference to the section-context. *)
- | ConstRef of Constant.t (** A reference to the environment. *)
- | IndRef of inductive (** A reference to an inductive type. *)
- | ConstructRef of constructor (** A reference to a constructor of an inductive type. *)
-
-(* Better to have it here that in closure, since used in grammar.cma *)
-type evaluable_global_reference =
- | EvalVarRef of Id.t
- | EvalConstRef of Constant.t
-
-let eq_egr e1 e2 = match e1, e2 with
- EvalConstRef con1, EvalConstRef con2 -> Constant.equal con1 con2
- | EvalVarRef id1, EvalVarRef id2 -> Id.equal id1 id2
- | _, _ -> false
-
(** {6 Hash-consing of name objects } *)
module Hind = Hashcons.Make(
@@ -776,109 +757,155 @@ let eq_ind_chk (kn1,i1) (kn2,i2) = Int.equal i1 i2 && eq_mind_chk kn1 kn2
(*******************************************************************)
(** Compatibility layers *)
-(** Backward compatibility for [Id] *)
+type mod_bound_id = MBId.t
+let eq_constant_key = Constant.UserOrd.equal
+
+(** Compatibility layer for [ModPath] *)
+
+type module_path = ModPath.t =
+ | MPfile of DirPath.t
+ | MPbound of MBId.t
+ | MPdot of module_path * Label.t
+
+(** Compatibility layer for [Constant] *)
-type identifier = Id.t
+module Projection =
+struct
+ module Repr = struct
+ type t =
+ { proj_ind : inductive;
+ proj_npars : int;
+ proj_arg : int;
+ proj_name : Label.t; }
-let id_eq = Id.equal
-let id_ord = Id.compare
-let string_of_id = Id.to_string
-let id_of_string = Id.of_string
+ let make proj_ind ~proj_npars ~proj_arg proj_name =
+ {proj_ind;proj_npars;proj_arg;proj_name}
-module Idset = Id.Set
-module Idmap = Id.Map
-module Idpred = Id.Pred
+ let inductive c = c.proj_ind
-(** Compatibility layer for [Name] *)
+ let mind c = fst c.proj_ind
-let name_eq = Name.equal
+ let constant c = KerPair.change_label (mind c) c.proj_name
-(** Compatibility layer for [DirPath] *)
+ let label c = c.proj_name
-type dir_path = DirPath.t
-let dir_path_ord = DirPath.compare
-let dir_path_eq = DirPath.equal
-let make_dirpath = DirPath.make
-let repr_dirpath = DirPath.repr
-let empty_dirpath = DirPath.empty
-let is_empty_dirpath = DirPath.is_empty
-let string_of_dirpath = DirPath.to_string
-let initial_dir = DirPath.initial
+ let npars c = c.proj_npars
-(** Compatibility layer for [MBId] *)
+ let arg c = c.proj_arg
-type mod_bound_id = MBId.t
-let mod_bound_id_ord = MBId.compare
-let mod_bound_id_eq = MBId.equal
-let make_mbid = MBId.make
-let repr_mbid = MBId.repr
-let debug_string_of_mbid = MBId.debug_to_string
-let string_of_mbid = MBId.to_string
-let id_of_mbid = MBId.to_id
-
-(** Compatibility layer for [Label] *)
-
-type label = Id.t
-let mk_label = Label.make
-let string_of_label = Label.to_string
-let pr_label = Label.print
-let id_of_label = Label.to_id
-let label_of_id = Label.of_id
-let eq_label = Label.equal
+ let equal a b =
+ eq_ind a.proj_ind b.proj_ind && Int.equal a.proj_arg b.proj_arg
-(** Compatibility layer for [ModPath] *)
+ let hash p =
+ Hashset.Combine.combinesmall p.proj_arg (ind_hash p.proj_ind)
-type module_path = ModPath.t =
- | MPfile of DirPath.t
- | MPbound of MBId.t
- | MPdot of module_path * Label.t
-let check_bound_mp = ModPath.is_bound
-let string_of_mp = ModPath.to_string
-let mp_ord = ModPath.compare
-let mp_eq = ModPath.equal
-let initial_path = ModPath.initial
-
-(** Compatibility layer for [KerName] *)
-
-type kernel_name = KerName.t
-let make_kn = KerName.make
-let repr_kn = KerName.repr
-let modpath = KerName.modpath
-let label = KerName.label
-let string_of_kn = KerName.to_string
-let pr_kn = KerName.print
-let kn_ord = KerName.compare
+ module SyntacticOrd = struct
+ let compare a b =
+ let c = ind_syntactic_ord a.proj_ind b.proj_ind in
+ if c == 0 then Int.compare a.proj_arg b.proj_arg
+ else c
-(** Compatibility layer for [Constant] *)
+ let equal a b =
+ a.proj_arg == b.proj_arg && eq_syntactic_ind a.proj_ind b.proj_ind
-type constant = Constant.t
+ let hash p =
+ Hashset.Combine.combinesmall p.proj_arg (ind_hash p.proj_ind)
+ end
+ module CanOrd = struct
+ let compare a b =
+ let c = ind_ord a.proj_ind b.proj_ind in
+ if c == 0 then Int.compare a.proj_arg b.proj_arg
+ else c
+ let equal a b =
+ a.proj_arg == b.proj_arg && eq_ind a.proj_ind b.proj_ind
+
+ let hash p =
+ Hashset.Combine.combinesmall p.proj_arg (ind_hash p.proj_ind)
+ end
+ module UserOrd = struct
+ let compare a b =
+ let c = ind_user_ord a.proj_ind b.proj_ind in
+ if c == 0 then Int.compare a.proj_arg b.proj_arg
+ else c
+
+ let equal a b =
+ a.proj_arg == b.proj_arg && eq_user_ind a.proj_ind b.proj_ind
+
+ let hash p =
+ Hashset.Combine.combinesmall p.proj_arg (ind_user_hash p.proj_ind)
+ end
+
+ let compare a b =
+ let c = ind_ord a.proj_ind b.proj_ind in
+ if c == 0 then Int.compare a.proj_arg b.proj_arg
+ else c
+
+ module Self_Hashcons = struct
+ type nonrec t = t
+ type u = (inductive -> inductive) * (Id.t -> Id.t)
+ let hashcons (hind,hid) p =
+ { proj_ind = hind p.proj_ind;
+ proj_npars = p.proj_npars;
+ proj_arg = p.proj_arg;
+ proj_name = hid p.proj_name }
+ let eq p p' =
+ p == p' || (p.proj_ind == p'.proj_ind && p.proj_npars == p'.proj_npars && p.proj_arg == p'.proj_arg && p.proj_name == p'.proj_name)
+ let hash = hash
+ end
+ module HashRepr = Hashcons.Make(Self_Hashcons)
+ let hcons = Hashcons.simple_hcons HashRepr.generate HashRepr.hcons (hcons_ind,Id.hcons)
+
+ let map_npars f p =
+ let ind = fst p.proj_ind in
+ let npars = p.proj_npars in
+ let ind', npars' = f ind npars in
+ if ind == ind' && npars == npars' then p
+ else {p with proj_ind = (ind',snd p.proj_ind); proj_npars = npars'}
+
+ let map f p = map_npars (fun mind n -> f mind, n) p
+
+ let to_string p = Constant.to_string (constant p)
+ let print p = Constant.print (constant p)
+ end
+
+ type t = Repr.t * bool
-module Projection =
-struct
- type t = constant * bool
-
let make c b = (c, b)
- let constant = fst
+ let mind (c,_) = Repr.mind c
+ let inductive (c,_) = Repr.inductive c
+ let npars (c,_) = Repr.npars c
+ let arg (c,_) = Repr.arg c
+ let constant (c,_) = Repr.constant c
+ let label (c,_) = Repr.label c
+ let repr = fst
let unfolded = snd
let unfold (c, b as p) = if b then p else (c, true)
- let equal (c, b) (c', b') = Constant.equal c c' && b == b'
- let hash (c, b) = (if b then 0 else 1) + Constant.hash c
+ let equal (c, b) (c', b') = Repr.equal c c' && b == b'
+
+ let hash (c, b) = (if b then 0 else 1) + Repr.hash c
module SyntacticOrd = struct
let compare (c, b) (c', b') =
- if b = b' then Constant.SyntacticOrd.compare c c' else -1
+ if b = b' then Repr.SyntacticOrd.compare c c' else -1
let equal (c, b as x) (c', b' as x') =
- x == x' || b = b' && Constant.SyntacticOrd.equal c c'
- let hash (c, b) = (if b then 0 else 1) + Constant.SyntacticOrd.hash c
+ x == x' || b = b' && Repr.SyntacticOrd.equal c c'
+ let hash (c, b) = (if b then 0 else 1) + Repr.SyntacticOrd.hash c
+ end
+ module CanOrd = struct
+ let compare (c, b) (c', b') =
+ if b = b' then Repr.CanOrd.compare c c' else -1
+ let equal (c, b as x) (c', b' as x') =
+ x == x' || b = b' && Repr.CanOrd.equal c c'
+ let hash (c, b) = (if b then 0 else 1) + Repr.CanOrd.hash c
end
module Self_Hashcons =
struct
type nonrec t = t
- type u = Constant.t -> Constant.t
+ type u = Repr.t -> Repr.t
let hashcons hc (c,b) = (hc c,b)
let eq ((c,b) as x) ((c',b') as y) =
x == y || (c == c' && b == b')
@@ -887,15 +914,19 @@ struct
module HashProjection = Hashcons.Make(Self_Hashcons)
- let hcons = Hashcons.simple_hcons HashProjection.generate HashProjection.hcons hcons_con
+ let hcons = Hashcons.simple_hcons HashProjection.generate HashProjection.hcons Repr.hcons
let compare (c, b) (c', b') =
- if b == b' then Constant.CanOrd.compare c c'
+ if b == b' then Repr.compare c c'
else if b then 1 else -1
let map f (c, b as x) =
- let c' = f c in
- if c' == c then x else (c', b)
+ let c' = Repr.map f c in
+ if c' == c then x else (c', b)
+
+ let map_npars f (c, b as x) =
+ let c' = Repr.map_npars f c in
+ if c' == c then x else (c', b)
let to_string p = Constant.to_string (constant p)
let print p = Constant.print (constant p)
@@ -904,39 +935,39 @@ end
type projection = Projection.t
-let constant_of_kn = Constant.make1
-let constant_of_kn_equiv = Constant.make
-let make_con = Constant.make3
-let repr_con = Constant.repr3
-let canonical_con = Constant.canonical
-let user_con = Constant.user
-let con_label = Constant.label
-let con_modpath = Constant.modpath
-let eq_constant = Constant.equal
-let eq_constant_key = Constant.UserOrd.equal
-let con_ord = Constant.CanOrd.compare
-let con_user_ord = Constant.UserOrd.compare
-let string_of_con = Constant.to_string
-let pr_con = Constant.print
-let debug_string_of_con = Constant.debug_to_string
-let debug_pr_con = Constant.debug_print
-let con_with_label = Constant.change_label
-
-(** Compatibility layer for [MutInd] *)
-
-type mutual_inductive = MutInd.t
-let mind_of_kn = MutInd.make1
-let mind_of_kn_equiv = MutInd.make
-let make_mind = MutInd.make3
-let canonical_mind = MutInd.canonical
-let user_mind = MutInd.user
-let repr_mind = MutInd.repr3
-let mind_label = MutInd.label
-let mind_modpath = MutInd.modpath
-let eq_mind = MutInd.equal
-let mind_ord = MutInd.CanOrd.compare
-let mind_user_ord = MutInd.UserOrd.compare
-let string_of_mind = MutInd.to_string
-let pr_mind = MutInd.print
-let debug_string_of_mind = MutInd.debug_to_string
-let debug_pr_mind = MutInd.debug_print
+module GlobRef = struct
+
+ type t =
+ | VarRef of variable (** A reference to the section-context. *)
+ | ConstRef of Constant.t (** A reference to the environment. *)
+ | IndRef of inductive (** A reference to an inductive type. *)
+ | ConstructRef of constructor (** A reference to a constructor of an inductive type. *)
+
+ let equal gr1 gr2 =
+ gr1 == gr2 || match gr1,gr2 with
+ | ConstRef con1, ConstRef con2 -> Constant.equal con1 con2
+ | IndRef kn1, IndRef kn2 -> eq_ind kn1 kn2
+ | ConstructRef kn1, ConstructRef kn2 -> eq_constructor kn1 kn2
+ | VarRef v1, VarRef v2 -> Id.equal v1 v2
+ | (ConstRef _ | IndRef _ | ConstructRef _ | VarRef _), _ -> false
+
+end
+
+type global_reference = GlobRef.t
+[@@ocaml.deprecated "Alias for [GlobRef.t]"]
+
+type evaluable_global_reference =
+ | EvalVarRef of Id.t
+ | EvalConstRef of Constant.t
+
+(* Better to have it here that in closure, since used in grammar.cma *)
+let eq_egr e1 e2 = match e1, e2 with
+ EvalConstRef con1, EvalConstRef con2 -> Constant.equal con1 con2
+ | EvalVarRef id1, EvalVarRef id2 -> Id.equal id1 id2
+ | _, _ -> false
+
+(** Located identifiers and objects with syntax. *)
+
+type lident = Id.t CAst.t
+type lname = Name.t CAst.t
+type lstring = string CAst.t
diff --git a/kernel/names.mli b/kernel/names.mli
index 96e020ae..1cdf5c24 100644
--- a/kernel/names.mli
+++ b/kernel/names.mli
@@ -500,21 +500,6 @@ val constructor_user_hash : constructor -> int
val constructor_syntactic_ord : constructor -> constructor -> int
val constructor_syntactic_hash : constructor -> int
-(** {6 Global reference is a kernel side type for all references together } *)
-type global_reference =
- | VarRef of variable (** A reference to the section-context. *)
- | ConstRef of Constant.t (** A reference to the environment. *)
- | IndRef of inductive (** A reference to an inductive type. *)
- | ConstructRef of constructor (** A reference to a constructor of an inductive type. *)
-
-(** Better to have it here that in Closure, since required in grammar.cma *)
-type evaluable_global_reference =
- | EvalVarRef of Id.t
- | EvalConstRef of Constant.t
-
-val eq_egr : evaluable_global_reference -> evaluable_global_reference
- -> bool
-
(** {6 Hash-consing } *)
val hcons_con : Constant.t -> Constant.t
@@ -553,116 +538,8 @@ val eq_ind_chk : inductive -> inductive -> bool
(** {6 Deprecated functions. For backward compatibility.} *)
-(** {5 Identifiers} *)
-
-type identifier = Id.t
-[@@ocaml.deprecated "Alias for [Id.t]"]
-
-val string_of_id : Id.t -> string
-[@@ocaml.deprecated "Same as [Id.to_string]."]
-
-val id_of_string : string -> Id.t
-[@@ocaml.deprecated "Same as [Id.of_string]."]
-
-val id_ord : Id.t -> Id.t -> int
-[@@ocaml.deprecated "Same as [Id.compare]."]
-
-val id_eq : Id.t -> Id.t -> bool
-[@@ocaml.deprecated "Same as [Id.equal]."]
-
-module Idset : Set.S with type elt = Id.t and type t = Id.Set.t
-[@@ocaml.deprecated "Same as [Id.Set]."]
-
-module Idpred : Predicate.S with type elt = Id.t and type t = Id.Pred.t
-[@@ocaml.deprecated "Same as [Id.Pred]."]
-
-module Idmap : module type of Id.Map
-[@@ocaml.deprecated "Same as [Id.Map]."]
-
-(** {5 Directory paths} *)
-
-type dir_path = DirPath.t
-[@@ocaml.deprecated "Alias for [DirPath.t]."]
-
-val dir_path_ord : DirPath.t -> DirPath.t -> int
-[@@ocaml.deprecated "Same as [DirPath.compare]."]
-
-val dir_path_eq : DirPath.t -> DirPath.t -> bool
-[@@ocaml.deprecated "Same as [DirPath.equal]."]
-
-val make_dirpath : module_ident list -> DirPath.t
-[@@ocaml.deprecated "Same as [DirPath.make]."]
-
-val repr_dirpath : DirPath.t -> module_ident list
-[@@ocaml.deprecated "Same as [DirPath.repr]."]
-
-val empty_dirpath : DirPath.t
-[@@ocaml.deprecated "Same as [DirPath.empty]."]
-
-val is_empty_dirpath : DirPath.t -> bool
-[@@ocaml.deprecated "Same as [DirPath.is_empty]."]
-
-val string_of_dirpath : DirPath.t -> string
-[@@ocaml.deprecated "Same as [DirPath.to_string]."]
-
-val initial_dir : DirPath.t
-[@@ocaml.deprecated "Same as [DirPath.initial]."]
-
-(** {5 Labels} *)
-
-type label = Label.t
-[@@ocaml.deprecated "Same as [Label.t]."]
-(** Alias type *)
-
-val mk_label : string -> Label.t
-[@@ocaml.deprecated "Same as [Label.make]."]
-
-val string_of_label : Label.t -> string
-[@@ocaml.deprecated "Same as [Label.to_string]."]
-
-val pr_label : Label.t -> Pp.t
-[@@ocaml.deprecated "Same as [Label.print]."]
-
-val label_of_id : Id.t -> Label.t
-[@@ocaml.deprecated "Same as [Label.of_id]."]
-
-val id_of_label : Label.t -> Id.t
-[@@ocaml.deprecated "Same as [Label.to_id]."]
-
-val eq_label : Label.t -> Label.t -> bool
-[@@ocaml.deprecated "Same as [Label.equal]."]
-
-(** {5 Unique bound module names} *)
-
type mod_bound_id = MBId.t
[@@ocaml.deprecated "Same as [MBId.t]."]
-
-val mod_bound_id_ord : MBId.t -> MBId.t -> int
-[@@ocaml.deprecated "Same as [MBId.compare]."]
-
-val mod_bound_id_eq : MBId.t -> MBId.t -> bool
-[@@ocaml.deprecated "Same as [MBId.equal]."]
-
-val make_mbid : DirPath.t -> Id.t -> MBId.t
-[@@ocaml.deprecated "Same as [MBId.make]."]
-
-val repr_mbid : MBId.t -> int * Id.t * DirPath.t
-[@@ocaml.deprecated "Same as [MBId.repr]."]
-
-val id_of_mbid : MBId.t -> Id.t
-[@@ocaml.deprecated "Same as [MBId.to_id]."]
-
-val string_of_mbid : MBId.t -> string
-[@@ocaml.deprecated "Same as [MBId.to_string]."]
-
-val debug_string_of_mbid : MBId.t -> string
-[@@ocaml.deprecated "Same as [MBId.debug_to_string]."]
-
-(** {5 Names} *)
-
-val name_eq : Name.t -> Name.t -> bool
-[@@ocaml.deprecated "Same as [Name.equal]."]
-
(** {5 Module paths} *)
type module_path = ModPath.t =
@@ -671,64 +548,69 @@ type module_path = ModPath.t =
| MPdot of ModPath.t * Label.t
[@@ocaml.deprecated "Alias type"]
-val mp_ord : ModPath.t -> ModPath.t -> int
-[@@ocaml.deprecated "Same as [ModPath.compare]."]
-
-val mp_eq : ModPath.t -> ModPath.t -> bool
-[@@ocaml.deprecated "Same as [ModPath.equal]."]
-
-val check_bound_mp : ModPath.t -> bool
-[@@ocaml.deprecated "Same as [ModPath.is_bound]."]
-
-val string_of_mp : ModPath.t -> string
-[@@ocaml.deprecated "Same as [ModPath.to_string]."]
-
-val initial_path : ModPath.t
-[@@ocaml.deprecated "Same as [ModPath.initial]."]
-
-(** {5 Kernel names} *)
-
-type kernel_name = KerName.t
-[@@ocaml.deprecated "Alias type"]
-
-val make_kn : ModPath.t -> DirPath.t -> Label.t -> KerName.t
-[@@ocaml.deprecated "Same as [KerName.make]."]
-
-val repr_kn : KerName.t -> ModPath.t * DirPath.t * Label.t
-[@@ocaml.deprecated "Same as [KerName.repr]."]
-
-val modpath : KerName.t -> ModPath.t
-[@@ocaml.deprecated "Same as [KerName.modpath]."]
-
-val label : KerName.t -> Label.t
-[@@ocaml.deprecated "Same as [KerName.label]."]
-
-val string_of_kn : KerName.t -> string
-[@@ocaml.deprecated "Same as [KerName.to_string]."]
-
-val pr_kn : KerName.t -> Pp.t
-[@@ocaml.deprecated "Same as [KerName.print]."]
-
-val kn_ord : KerName.t -> KerName.t -> int
-[@@ocaml.deprecated "Same as [KerName.compare]."]
+module Projection : sig
+ module Repr : sig
+ type t
+
+ val make : inductive -> proj_npars:int -> proj_arg:int -> Label.t -> t
+
+ module SyntacticOrd : sig
+ val compare : t -> t -> int
+ val equal : t -> t -> bool
+ val hash : t -> int
+ end
+ module CanOrd : sig
+ val compare : t -> t -> int
+ val equal : t -> t -> bool
+ val hash : t -> int
+ end
+ module UserOrd : sig
+ val compare : t -> t -> int
+ val equal : t -> t -> bool
+ val hash : t -> int
+ end
+
+ val constant : t -> Constant.t
+ (** Don't use this if you don't have to. *)
+
+ val inductive : t -> inductive
+ val mind : t -> MutInd.t
+ val npars : t -> int
+ val arg : t -> int
+ val label : t -> Label.t
-(** {5 Constant names} *)
+ val equal : t -> t -> bool
+ val hash : t -> int
+ val compare : t -> t -> int
-type constant = Constant.t
-[@@ocaml.deprecated "Alias type"]
+ val map : (MutInd.t -> MutInd.t) -> t -> t
+ val map_npars : (MutInd.t -> int -> MutInd.t * int) -> t -> t
-module Projection : sig
- type t
+ val print : t -> Pp.t
+ val to_string : t -> string
+ end
+ type t (* = Repr.t * bool *)
- val make : Constant.t -> bool -> t
+ val make : Repr.t -> bool -> t
+ val repr : t -> Repr.t
module SyntacticOrd : sig
val compare : t -> t -> int
val equal : t -> t -> bool
val hash : t -> int
end
+ module CanOrd : sig
+ val compare : t -> t -> int
+ val equal : t -> t -> bool
+ val hash : t -> int
+ end
val constant : t -> Constant.t
+ val mind : t -> MutInd.t
+ val inductive : t -> inductive
+ val npars : t -> int
+ val arg : t -> int
+ val label : t -> Label.t
val unfolded : t -> bool
val unfold : t -> t
@@ -739,7 +621,8 @@ module Projection : sig
val compare : t -> t -> int
- val map : (Constant.t -> Constant.t) -> t -> t
+ val map : (MutInd.t -> MutInd.t) -> t -> t
+ val map_npars : (MutInd.t -> int -> MutInd.t * int) -> t -> t
val to_string : t -> string
val print : t -> Pp.t
@@ -749,100 +632,34 @@ end
type projection = Projection.t
[@@ocaml.deprecated "Alias for [Projection.t]"]
-val constant_of_kn_equiv : KerName.t -> KerName.t -> Constant.t
-[@@ocaml.deprecated "Same as [Constant.make]"]
-
-val constant_of_kn : KerName.t -> Constant.t
-[@@ocaml.deprecated "Same as [Constant.make1]"]
-
-val make_con : ModPath.t -> DirPath.t -> Label.t -> Constant.t
-[@@ocaml.deprecated "Same as [Constant.make3]"]
-
-val repr_con : Constant.t -> ModPath.t * DirPath.t * Label.t
-[@@ocaml.deprecated "Same as [Constant.repr3]"]
-
-val user_con : Constant.t -> KerName.t
-[@@ocaml.deprecated "Same as [Constant.user]"]
-
-val canonical_con : Constant.t -> KerName.t
-[@@ocaml.deprecated "Same as [Constant.canonical]"]
-
-val con_modpath : Constant.t -> ModPath.t
-[@@ocaml.deprecated "Same as [Constant.modpath]"]
-
-val con_label : Constant.t -> Label.t
-[@@ocaml.deprecated "Same as [Constant.label]"]
-
-val eq_constant : Constant.t -> Constant.t -> bool
-[@@ocaml.deprecated "Same as [Constant.equal]"]
-
-val con_ord : Constant.t -> Constant.t -> int
-[@@ocaml.deprecated "Same as [Constant.CanOrd.compare]"]
-
-val con_user_ord : Constant.t -> Constant.t -> int
-[@@ocaml.deprecated "Same as [Constant.UserOrd.compare]"]
-
-val con_with_label : Constant.t -> Label.t -> Constant.t
-[@@ocaml.deprecated "Same as [Constant.change_label]"]
-
-val string_of_con : Constant.t -> string
-[@@ocaml.deprecated "Same as [Constant.to_string]"]
-
-val pr_con : Constant.t -> Pp.t
-[@@ocaml.deprecated "Same as [Constant.print]"]
-
-val debug_pr_con : Constant.t -> Pp.t
-[@@ocaml.deprecated "Same as [Constant.debug_print]"]
-
-val debug_string_of_con : Constant.t -> string
-[@@ocaml.deprecated "Same as [Constant.debug_to_string]"]
-
-(** {5 Mutual Inductive names} *)
-
-type mutual_inductive = MutInd.t
-[@@ocaml.deprecated "Alias type"]
-
-val mind_of_kn : KerName.t -> MutInd.t
-[@@ocaml.deprecated "Same as [MutInd.make1]"]
-
-val mind_of_kn_equiv : KerName.t -> KerName.t -> MutInd.t
-[@@ocaml.deprecated "Same as [MutInd.make]"]
-
-val make_mind : ModPath.t -> DirPath.t -> Label.t -> MutInd.t
-[@@ocaml.deprecated "Same as [MutInd.make3]"]
-
-val user_mind : MutInd.t -> KerName.t
-[@@ocaml.deprecated "Same as [MutInd.user]"]
-
-val canonical_mind : MutInd.t -> KerName.t
-[@@ocaml.deprecated "Same as [MutInd.canonical]"]
-
-val repr_mind : MutInd.t -> ModPath.t * DirPath.t * Label.t
-[@@ocaml.deprecated "Same as [MutInd.repr3]"]
+(** {6 Global reference is a kernel side type for all references together } *)
-val eq_mind : MutInd.t -> MutInd.t -> bool
-[@@ocaml.deprecated "Same as [MutInd.equal]"]
+(* XXX: Should we define GlobRefCan GlobRefUser? *)
+module GlobRef : sig
-val mind_ord : MutInd.t -> MutInd.t -> int
-[@@ocaml.deprecated "Same as [MutInd.CanOrd.compare]"]
+ type t =
+ | VarRef of variable (** A reference to the section-context. *)
+ | ConstRef of Constant.t (** A reference to the environment. *)
+ | IndRef of inductive (** A reference to an inductive type. *)
+ | ConstructRef of constructor (** A reference to a constructor of an inductive type. *)
-val mind_user_ord : MutInd.t -> MutInd.t -> int
-[@@ocaml.deprecated "Same as [MutInd.UserOrd.compare]"]
+ val equal : t -> t -> bool
-val mind_label : MutInd.t -> Label.t
-[@@ocaml.deprecated "Same as [MutInd.label]"]
+end
-val mind_modpath : MutInd.t -> ModPath.t
-[@@ocaml.deprecated "Same as [MutInd.modpath]"]
+type global_reference = GlobRef.t
+[@@ocaml.deprecated "Alias for [GlobRef.t]"]
-val string_of_mind : MutInd.t -> string
-[@@ocaml.deprecated "Same as [MutInd.to_string]"]
+(** Better to have it here that in Closure, since required in grammar.cma *)
+(* XXX: Move to a module *)
+type evaluable_global_reference =
+ | EvalVarRef of Id.t
+ | EvalConstRef of Constant.t
-val pr_mind : MutInd.t -> Pp.t
-[@@ocaml.deprecated "Same as [MutInd.print]"]
+val eq_egr : evaluable_global_reference -> evaluable_global_reference -> bool
-val debug_pr_mind : MutInd.t -> Pp.t
-[@@ocaml.deprecated "Same as [MutInd.debug_print]"]
+(** Located identifiers and objects with syntax. *)
-val debug_string_of_mind : MutInd.t -> string
-[@@ocaml.deprecated "Same as [MutInd.debug_to_string]"]
+type lident = Id.t CAst.t
+type lname = Name.t CAst.t
+type lstring = string CAst.t
diff --git a/kernel/nativecode.ml b/kernel/nativecode.ml
index 123e7a6d..eed25a4c 100644
--- a/kernel/nativecode.ml
+++ b/kernel/nativecode.ml
@@ -16,7 +16,7 @@ open Util
open Nativevalues
open Nativeinstr
open Nativelambda
-open Pre_env
+open Environ
[@@@ocaml.warning "-32-37"]
@@ -53,7 +53,7 @@ type gname =
| Gind of string * inductive (* prefix, inductive name *)
| Gconstruct of string * constructor (* prefix, constructor name *)
| Gconstant of string * Constant.t (* prefix, constant name *)
- | Gproj of string * Constant.t (* prefix, constant name *)
+ | Gproj of string * inductive * int (* prefix, inductive, index (start from 0) *)
| Gcase of Label.t option * int
| Gpred of Label.t option * int
| Gfixtype of Label.t option * int
@@ -71,8 +71,8 @@ let eq_gname gn1 gn2 =
String.equal s1 s2 && eq_constructor c1 c2
| Gconstant (s1, c1), Gconstant (s2, c2) ->
String.equal s1 s2 && Constant.equal c1 c2
- | Gproj (s1, c1), Gproj (s2, c2) ->
- String.equal s1 s2 && Constant.equal c1 c2
+ | Gproj (s1, ind1, i1), Gproj (s2, ind2, i2) ->
+ String.equal s1 s2 && eq_ind ind1 ind2 && Int.equal i1 i2
| Gcase (None, i1), Gcase (None, i2) -> Int.equal i1 i2
| Gcase (Some l1, i1), Gcase (Some l2, i2) -> Int.equal i1 i2 && Label.equal l1 l2
| Gpred (None, i1), Gpred (None, i2) -> Int.equal i1 i2
@@ -112,7 +112,7 @@ let gname_hash gn = match gn with
| Ginternal s -> combinesmall 9 (String.hash s)
| Grel i -> combinesmall 10 (Int.hash i)
| Gnamed id -> combinesmall 11 (Id.hash id)
-| Gproj (s, p) -> combinesmall 12 (combine (String.hash s) (Constant.hash p))
+| Gproj (s, p, i) -> combinesmall 12 (combine (String.hash s) (combine (ind_hash p) i))
let case_ctr = ref (-1)
@@ -156,6 +156,7 @@ type symbol =
| SymbMeta of metavariable
| SymbEvar of Evar.t
| SymbLevel of Univ.Level.t
+ | SymbProj of (inductive * int)
let dummy_symb = SymbValue (dummy_value ())
@@ -170,6 +171,7 @@ let eq_symbol sy1 sy2 =
| SymbMeta m1, SymbMeta m2 -> Int.equal m1 m2
| SymbEvar evk1, SymbEvar evk2 -> Evar.equal evk1 evk2
| SymbLevel l1, SymbLevel l2 -> Univ.Level.equal l1 l2
+ | SymbProj (i1, k1), SymbProj (i2, k2) -> eq_ind i1 i2 && Int.equal k1 k2
| _, _ -> false
let hash_symbol symb =
@@ -183,6 +185,7 @@ let hash_symbol symb =
| SymbMeta m -> combinesmall 7 m
| SymbEvar evk -> combinesmall 8 (Evar.hash evk)
| SymbLevel l -> combinesmall 9 (Univ.Level.hash l)
+ | SymbProj (i, k) -> combinesmall 10 (combine (ind_hash i) k)
module HashedTypeSymbol = struct
type t = symbol
@@ -245,6 +248,11 @@ let get_level tbl i =
| SymbLevel u -> u
| _ -> anomaly (Pp.str "get_level failed.")
+let get_proj tbl i =
+ match tbl.(i) with
+ | SymbProj p -> p
+ | _ -> anomaly (Pp.str "get_proj failed.")
+
let push_symbol x =
try HashtblSymbol.find symb_tbl x
with Not_found ->
@@ -270,7 +278,6 @@ type primitive =
| Mk_rel of int
| Mk_var of Id.t
| Mk_proj
- | Is_accu
| Is_int
| Cast_accu
| Upd_cofix
@@ -311,7 +318,6 @@ let eq_primitive p1 p2 =
| Mk_cofix i1, Mk_cofix i2 -> Int.equal i1 i2
| Mk_rel i1, Mk_rel i2 -> Int.equal i1 i2
| Mk_var id1, Mk_var id2 -> Id.equal id1 id2
- | Is_accu, Is_accu -> true
| Cast_accu, Cast_accu -> true
| Upd_cofix, Upd_cofix -> true
| Force_cofix, Force_cofix -> true
@@ -337,7 +343,6 @@ let primitive_hash = function
combinesmall 8 (Int.hash i)
| Mk_var id ->
combinesmall 9 (Id.hash id)
- | Is_accu -> 10
| Is_int -> 11
| Cast_accu -> 12
| Upd_cofix -> 13
@@ -388,6 +393,7 @@ type mllambda =
| MLsetref of string * mllambda
| MLsequence of mllambda * mllambda
| MLarray of mllambda array
+ | MLisaccu of string * inductive * mllambda
and mllam_branches = ((constructor * lname option array) list * mllambda) array
@@ -459,7 +465,12 @@ let rec eq_mllambda gn1 gn2 n env1 env2 t1 t2 =
| MLarray arr1, MLarray arr2 ->
Array.equal (eq_mllambda gn1 gn2 n env1 env2) arr1 arr2
- | _, _ -> false
+ | MLisaccu (s1, ind1, ml1), MLisaccu (s2, ind2, ml2) ->
+ String.equal s1 s2 && eq_ind ind1 ind2 &&
+ eq_mllambda gn1 gn2 n env1 env2 ml1 ml2
+ | (MLlocal _ | MLglobal _ | MLprimitive _ | MLlam _ | MLletrec _ | MLlet _ |
+ MLapp _ | MLif _ | MLmatch _ | MLconstruct _ | MLint _ | MLuint _ |
+ MLsetref _ | MLsequence _ | MLarray _ | MLisaccu _), _ -> false
and eq_letrec gn1 gn2 n env1 env2 defs1 defs2 =
let eq_def (_,args1,ml1) (_,args2,ml2) =
@@ -534,6 +545,8 @@ let rec hash_mllambda gn n env t =
combinesmall 14 (combine hml hml')
| MLarray arr ->
combinesmall 15 (hash_mllambda_array gn n env 1 arr)
+ | MLisaccu (s, ind, c) ->
+ combinesmall 16 (combine (String.hash s) (combine (ind_hash ind) (hash_mllambda gn n env c)))
and hash_mllambda_letrec gn n env init defs =
let hash_def (_,args,ml) =
@@ -600,6 +613,7 @@ let fv_lam l =
| MLsetref(_,l) -> aux l bind fv
| MLsequence(l1,l2) -> aux l1 bind (aux l2 bind fv)
| MLarray arr -> Array.fold_right (fun a fv -> aux a bind fv) arr fv
+ | MLisaccu (_, _, body) -> aux body bind fv
in
aux l LNset.empty LNset.empty
@@ -618,6 +632,14 @@ let mkMLapp f args =
| MLapp(f,args') -> MLapp(f,Array.append args' args)
| _ -> MLapp(f,args)
+let mkForceCofix prefix ind arg =
+ let name = fresh_lname Anonymous in
+ MLlet (name, arg,
+ MLif (
+ MLisaccu (prefix, ind, MLlocal name),
+ MLapp (MLprimitive Force_cofix, [|MLlocal name|]),
+ MLlocal name))
+
let empty_params = [||]
let decompose_MLlam c =
@@ -889,6 +911,10 @@ let get_level_code i =
MLapp (MLglobal (Ginternal "get_level"),
[|MLglobal symbols_tbl_name; MLint i|])
+let get_proj_code i =
+ MLapp (MLglobal (Ginternal "get_proj"),
+ [|MLglobal symbols_tbl_name; MLint i|])
+
type rlist =
| Rnil
| Rcons of (constructor * lname option array) list ref * LNset.t * mllambda * rlist'
@@ -1049,12 +1075,11 @@ let ml_of_instance instance u =
let tyn = fresh_lname Anonymous in
let i = push_symbol (SymbMeta mv) in
MLapp(MLprimitive Mk_meta, [|get_meta_code i; MLlocal tyn|])
- | Levar(evk,ty,args) ->
- let tyn = fresh_lname Anonymous in
+ | Levar(evk, args) ->
let i = push_symbol (SymbEvar evk) in
+ (** Arguments are *not* reversed in evar instances in native compilation *)
let args = MLarray(Array.map (ml_of_lam env l) args) in
- MLlet(tyn, ml_of_lam env l ty,
- MLapp(MLprimitive Mk_evar, [|get_evar_code i;MLlocal tyn; args|]))
+ MLapp(MLprimitive Mk_evar, [|get_evar_code i; args|])
| Lprod(dom,codom) ->
let dom = ml_of_lam env l dom in
let codom = ml_of_lam env l codom in
@@ -1074,7 +1099,7 @@ let ml_of_instance instance u =
| Lconst (prefix, (c, u)) ->
let args = ml_of_instance env.env_univ u in
mkMLapp (MLglobal(Gconstant (prefix, c))) args
- | Lproj (prefix,c) -> MLglobal(Gproj (prefix,c))
+ | Lproj (prefix, ind, i) -> MLglobal(Gproj (prefix, ind, i))
| Lprim _ ->
let decl,cond,paux = extract_prim (ml_of_lam env l) t in
compile_prim decl cond paux
@@ -1126,11 +1151,11 @@ let ml_of_instance instance u =
let arg = ml_of_lam env l a in
let force =
if annot.asw_finite then arg
- else MLapp(MLprimitive Force_cofix, [|arg|]) in
+ else mkForceCofix annot.asw_prefix annot.asw_ind arg in
mkMLapp (MLapp (MLglobal cn, fv_args env fvn fvr)) [|force|]
| Lif(t,bt,bf) ->
MLif(ml_of_lam env l t, ml_of_lam env l bt, ml_of_lam env l bf)
- | Lfix ((rec_pos,start), (ids, tt, tb)) ->
+ | Lfix ((rec_pos, inds, start), (ids, tt, tb)) ->
(* let type_f fvt = [| type fix |]
let norm_f1 fv f1 .. fn params1 = body1
..
@@ -1199,8 +1224,9 @@ let ml_of_instance instance u =
let paramsi = t_params.(i) in
let reci = MLlocal (paramsi.(rec_pos.(i))) in
let pargsi = Array.map (fun id -> MLlocal id) paramsi in
+ let (prefix, ind) = inds.(i) in
let body =
- MLif(MLapp(MLprimitive Is_accu,[|reci|]),
+ MLif(MLisaccu (prefix, ind, reci),
mkMLapp
(MLapp(MLprimitive (Mk_fix(rec_pos,i)),
[|mk_type; mk_norm|]))
@@ -1362,6 +1388,7 @@ let subst s l =
| MLsetref(s,l1) -> MLsetref(s,aux l1)
| MLsequence(l1,l2) -> MLsequence(aux l1, aux l2)
| MLarray arr -> MLarray (Array.map aux arr)
+ | MLisaccu (s, ind, l) -> MLisaccu (s, ind, aux l)
in
aux l
@@ -1459,7 +1486,7 @@ let optimize gdef l =
let b1 = optimize s b1 in
let b2 = optimize s b2 in
begin match t, b2 with
- | MLapp(MLprimitive Is_accu,[| l1 |]), MLmatch(annot, l2, _, bs)
+ | MLisaccu (_, _, l1), MLmatch(annot, l2, _, bs)
when eq_mllambda l1 l2 -> MLmatch(annot, l1, b1, bs)
| _, _ -> MLif(t, b1, b2)
end
@@ -1471,6 +1498,7 @@ let optimize gdef l =
| MLsetref(r,l) -> MLsetref(r, optimize s l)
| MLsequence(l1,l2) -> MLsequence(optimize s l1, optimize s l2)
| MLarray arr -> MLarray (Array.map (optimize s) arr)
+ | MLisaccu (pf, ind, l) -> MLisaccu (pf, ind, optimize s l)
in
optimize LNmap.empty l
@@ -1548,8 +1576,8 @@ let string_of_gname g =
Format.sprintf "%sconstruct_%s_%i_%i" prefix (string_of_mind mind) i (j-1)
| Gconstant (prefix, c) ->
Format.sprintf "%sconst_%s" prefix (string_of_con c)
- | Gproj (prefix, c) ->
- Format.sprintf "%sproj_%s" prefix (string_of_con c)
+ | Gproj (prefix, (mind, n), i) ->
+ Format.sprintf "%sproj_%s_%i_%i" prefix (string_of_mind mind) n i
| Gcase (l,i) ->
Format.sprintf "case_%s_%i" (string_of_label_def l) i
| Gpred (l,i) ->
@@ -1633,19 +1661,23 @@ let pp_mllam fmt l =
pp_mllam fmt arr.(len-1)
end;
Format.fprintf fmt "|]@]"
-
+ | MLisaccu (prefix, (mind, i), c) ->
+ let accu = Format.sprintf "%sAccu_%s_%i" prefix (string_of_mind mind) i in
+ Format.fprintf fmt
+ "@[begin match Obj.magic (%a) with@\n| %s _ ->@\n true@\n| _ ->@\n false@\nend@]"
+ pp_mllam c accu
and pp_letrec fmt defs =
let len = Array.length defs in
- let pp_one_rec i (fn, argsn, body) =
+ let pp_one_rec (fn, argsn, body) =
Format.fprintf fmt "%a%a =@\n %a"
pp_lname fn
pp_ldecls argsn pp_mllam body in
Format.fprintf fmt "@[let rec ";
- pp_one_rec 0 defs.(0);
+ pp_one_rec defs.(0);
for i = 1 to len - 1 do
Format.fprintf fmt "@\nand ";
- pp_one_rec i defs.(i)
+ pp_one_rec defs.(i)
done;
and pp_blam fmt l =
@@ -1726,7 +1758,6 @@ let pp_mllam fmt l =
| Mk_var id ->
Format.fprintf fmt "mk_var_accu (Names.Id.of_string \"%s\")" (string_of_id id)
| Mk_proj -> Format.fprintf fmt "mk_proj_accu"
- | Is_accu -> Format.fprintf fmt "is_accu"
| Is_int -> Format.fprintf fmt "is_int"
| Cast_accu -> Format.fprintf fmt "cast_accu"
| Upd_cofix -> Format.fprintf fmt "upd_cofix"
@@ -1833,7 +1864,7 @@ and apply_fv env sigma univ (fv_named,fv_rel) auxdefs ml =
in
let auxdefs = List.fold_right get_rel_val fv_rel auxdefs in
let auxdefs = List.fold_right get_named_val fv_named auxdefs in
- let lvl = Context.Rel.length env.env_rel_context.env_rel_ctx in
+ let lvl = Context.Rel.length (rel_context env) in
let fv_rel = List.map (fun (n,_) -> MLglobal (Grel (lvl-n))) fv_rel in
let fv_named = List.map (fun (id,_) -> MLglobal (Gnamed id)) fv_named in
let aux_name = fresh_lname Anonymous in
@@ -1841,8 +1872,8 @@ and apply_fv env sigma univ (fv_named,fv_rel) auxdefs ml =
and compile_rel env sigma univ auxdefs n =
let open Context.Rel.Declaration in
- let decl = Pre_env.lookup_rel n env in
- let n = List.length env.env_rel_context.env_rel_ctx - n in
+ let decl = lookup_rel n env in
+ let n = List.length (rel_context env) - n in
match decl with
| LocalDef (_,t,_) ->
let code = lambda_of_constr env sigma t in
@@ -1862,8 +1893,6 @@ and compile_named env sigma univ auxdefs id =
Glet(Gnamed id, MLprimitive (Mk_var id))::auxdefs
let compile_constant env sigma prefix ~interactive con cb =
- match cb.const_proj with
- | None ->
let no_univs =
match cb.const_universes with
| Monomorphic_const _ -> true
@@ -1874,7 +1903,7 @@ let compile_constant env sigma prefix ~interactive con cb =
let t = Mod_subst.force_constr t in
let code = lambda_of_constr env sigma t in
if !Flags.debug then Feedback.msg_debug (Pp.str "Generated lambda code");
- let is_lazy = is_lazy prefix t in
+ let is_lazy = is_lazy env prefix t in
let code = if is_lazy then mk_lazy code else code in
let name =
if interactive then LinkedInteractive prefix
@@ -1907,38 +1936,6 @@ let compile_constant env sigma prefix ~interactive con cb =
if interactive then LinkedInteractive prefix
else Linked prefix
end
- | Some pb ->
- let mind = pb.proj_ind in
- let ind = (mind,0) in
- let mib = lookup_mind mind env in
- let oib = mib.mind_packets.(0) in
- let tbl = oib.mind_reloc_tbl in
- (* Building info *)
- let prefix = get_mind_prefix env mind in
- let ci = { ci_ind = ind; ci_npar = mib.mind_nparams;
- ci_cstr_nargs = [|0|];
- ci_cstr_ndecls = [||] (*FIXME*);
- ci_pp_info = { ind_tags = []; cstr_tags = [||] (*FIXME*); style = RegularStyle } } in
- let asw = { asw_ind = ind; asw_prefix = prefix; asw_ci = ci;
- asw_reloc = tbl; asw_finite = true } in
- let c_uid = fresh_lname Anonymous in
- let cf_uid = fresh_lname Anonymous in
- let _, arity = tbl.(0) in
- let ci_uid = fresh_lname Anonymous in
- let cargs = Array.init arity
- (fun i -> if Int.equal i pb.proj_arg then Some ci_uid else None)
- in
- let i = push_symbol (SymbConst con) in
- let accu = MLapp (MLprimitive Cast_accu, [|MLlocal cf_uid|]) in
- let accu_br = MLapp (MLprimitive Mk_proj, [|get_const_code i;accu|]) in
- let code = MLmatch(asw,MLlocal cf_uid,accu_br,[|[((ind,1),cargs)],MLlocal ci_uid|]) in
- let code = MLlet(cf_uid, MLapp (MLprimitive Force_cofix, [|MLlocal c_uid|]), code) in
- let gn = Gproj ("",con) in
- let fargs = Array.init (pb.proj_npars + 1) (fun _ -> fresh_lname Anonymous) in
- let arg = fargs.(pb.proj_npars) in
- Glet(Gconstant ("", con), mkMLlam fargs (MLapp (MLglobal gn, [|MLlocal
- arg|])))::
- [Glet(gn, mkMLlam [|c_uid|] code)], Linked prefix
module StringOrd = struct type t = string let compare = String.compare end
module StringSet = Set.Make(StringOrd)
@@ -1963,12 +1960,14 @@ let is_code_loaded ~interactive name =
let param_name = Name (Id.of_string "params")
let arg_name = Name (Id.of_string "arg")
-let compile_mind prefix ~interactive mb mind stack =
+let compile_mind mb mind stack =
let u = Declareops.inductive_polymorphic_context mb in
+ (** Generate data for every block *)
let f i stack ob =
- let gtype = Gtype((mind, i), Array.map snd ob.mind_reloc_tbl) in
- let j = push_symbol (SymbInd (mind,i)) in
- let name = Gind ("", (mind, i)) in
+ let ind = (mind, i) in
+ let gtype = Gtype(ind, Array.map snd ob.mind_reloc_tbl) in
+ let j = push_symbol (SymbInd ind) in
+ let name = Gind ("", ind) in
let accu =
let args =
if Int.equal (Univ.AUContext.size u) 0 then
@@ -1982,12 +1981,43 @@ let compile_mind prefix ~interactive mb mind stack =
Array.init nparams (fun i -> {lname = param_name; luid = i}) in
let add_construct j acc (_,arity) =
let args = Array.init arity (fun k -> {lname = arg_name; luid = k}) in
- let c = (mind,i), (j+1) in
+ let c = ind, (j+1) in
Glet(Gconstruct ("", c),
mkMLlam (Array.append params args)
(MLconstruct("", c, Array.map (fun id -> MLlocal id) args)))::acc
in
- Array.fold_left_i add_construct (gtype::accu::stack) ob.mind_reloc_tbl
+ let constructors = Array.fold_left_i add_construct [] ob.mind_reloc_tbl in
+ let add_proj proj_arg acc pb =
+ let tbl = ob.mind_reloc_tbl in
+ (* Building info *)
+ let ci = { ci_ind = ind; ci_npar = nparams;
+ ci_cstr_nargs = [|0|];
+ ci_cstr_ndecls = [||] (*FIXME*);
+ ci_pp_info = { ind_tags = []; cstr_tags = [||] (*FIXME*); style = RegularStyle } } in
+ let asw = { asw_ind = ind; asw_prefix = ""; asw_ci = ci;
+ asw_reloc = tbl; asw_finite = true } in
+ let c_uid = fresh_lname Anonymous in
+ let cf_uid = fresh_lname Anonymous in
+ let _, arity = tbl.(0) in
+ let ci_uid = fresh_lname Anonymous in
+ let cargs = Array.init arity
+ (fun i -> if Int.equal i proj_arg then Some ci_uid else None)
+ in
+ let i = push_symbol (SymbProj (ind, j)) in
+ let accu = MLapp (MLprimitive Cast_accu, [|MLlocal cf_uid|]) in
+ let accu_br = MLapp (MLprimitive Mk_proj, [|get_proj_code i;accu|]) in
+ let code = MLmatch(asw,MLlocal cf_uid,accu_br,[|[((ind,1),cargs)],MLlocal ci_uid|]) in
+ let code = MLlet(cf_uid, mkForceCofix "" ind (MLlocal c_uid), code) in
+ let gn = Gproj ("", ind, proj_arg) in
+ Glet (gn, mkMLlam [|c_uid|] code) :: acc
+ in
+ let projs = match mb.mind_record with
+ | NotRecord | FakeRecord -> []
+ | PrimRecord info ->
+ let _, _, pbs = info.(i) in
+ Array.fold_left_i add_proj [] pbs
+ in
+ projs @ constructors @ gtype :: accu :: stack
in
Array.fold_left_i f stack mb.mind_packets
@@ -2008,7 +2038,7 @@ let compile_mind_deps env prefix ~interactive
then init
else
let comp_stack =
- compile_mind prefix ~interactive mib mind comp_stack
+ compile_mind mib mind comp_stack
in
let name =
if interactive then LinkedInteractive prefix
@@ -2033,12 +2063,9 @@ let compile_deps env sigma prefix ~interactive init t =
then init
else
let comp_stack, (mind_updates, const_updates) =
- match cb.const_proj, cb.const_body with
- | None, Def t ->
+ match cb.const_body with
+ | Def t ->
aux env lvl init (Mod_subst.force_constr t)
- | Some pb, _ ->
- let mind = pb.proj_ind in
- compile_mind_deps env prefix ~interactive init mind
| _ -> init
in
let code, name =
@@ -2049,8 +2076,8 @@ let compile_deps env sigma prefix ~interactive init t =
comp_stack, (mind_updates, const_updates)
| Construct (((mind,_),_),u) -> compile_mind_deps env prefix ~interactive init mind
| Proj (p,c) ->
- let term = mkApp (mkConst (Projection.constant p), [|c|]) in
- aux env lvl init term
+ let init = compile_mind_deps env prefix ~interactive init (Projection.mind p) in
+ aux env lvl init c
| Case (ci, p, c, ac) ->
let mind = fst ci.ci_ind in
let init = compile_mind_deps env prefix ~interactive init mind in
@@ -2082,9 +2109,9 @@ let compile_constant_field env prefix con acc cb =
in
gl@acc
-let compile_mind_field prefix mp l acc mb =
+let compile_mind_field mp l acc mb =
let mind = MutInd.make2 mp l in
- compile_mind prefix ~interactive:false mb mind acc
+ compile_mind mb mind acc
let mk_open s = Gopen s
diff --git a/kernel/nativecode.mli b/kernel/nativecode.mli
index 4b23cc5f..96efa7fa 100644
--- a/kernel/nativecode.mli
+++ b/kernel/nativecode.mli
@@ -10,7 +10,7 @@
open Names
open Constr
open Declarations
-open Pre_env
+open Environ
open Nativelambda
(** This file defines the mllambda code generation phase of the native
@@ -50,6 +50,8 @@ val get_evar : symbols -> int -> Evar.t
val get_level : symbols -> int -> Univ.Level.t
+val get_proj : symbols -> int -> inductive * int
+
val get_symbols : unit -> symbols
type code_location_update
@@ -65,7 +67,7 @@ val register_native_file : string -> unit
val compile_constant_field : env -> string -> Constant.t ->
global list -> constant_body -> global list
-val compile_mind_field : string -> ModPath.t -> Label.t ->
+val compile_mind_field : ModPath.t -> Label.t ->
global list -> mutual_inductive_body -> global list
val mk_conv_code : env -> evars -> string -> constr -> constr -> linkable_code
diff --git a/kernel/nativeconv.ml b/kernel/nativeconv.ml
index 2a7afdca..c75dde84 100644
--- a/kernel/nativeconv.ml
+++ b/kernel/nativeconv.ml
@@ -64,7 +64,7 @@ and conv_atom env pb lvl a1 a2 cu =
match a1, a2 with
| Ameta (m1,_), Ameta (m2,_) ->
if Int.equal m1 m2 then cu else raise NotConvertible
- | Aevar (ev1,_,args1), Aevar (ev2,_,args2) ->
+ | Aevar (ev1, args1), Aevar (ev2, args2) ->
if Evar.equal ev1 ev2 then
Array.fold_right2 (conv_val env CONV lvl) args1 args2 cu
else raise NotConvertible
@@ -114,8 +114,8 @@ and conv_atom env pb lvl a1 a2 cu =
let cu = conv_val env CONV lvl d1 d2 cu in
let v = mk_rel_accu lvl in
conv_val env pb (lvl + 1) (d1 v) (d2 v) cu
- | Aproj(p1,ac1), Aproj(p2,ac2) ->
- if not (Constant.equal p1 p2) then raise NotConvertible
+ | Aproj((ind1, i1), ac1), Aproj((ind2, i2), ac2) ->
+ if not (eq_ind ind1 ind2 && Int.equal i1 i2) then raise NotConvertible
else conv_accu env CONV lvl ac1 ac2 cu
| Arel _, _ | Aind _, _ | Aconstant _, _ | Asort _, _ | Avar _, _
| Acase _, _ | Afix _, _ | Acofix _, _ | Acofixe _, _ | Aprod _, _
@@ -141,23 +141,14 @@ let warn_no_native_compiler =
(fun () -> strbrk "Native compiler is disabled," ++
strbrk " falling back to VM conversion test.")
-type vm_conv_gen = { vm_conv_gen : 'a. conv_pb -> (Constr.types, 'a) generic_conversion_function }
-
-let vm_conv_gen =
- ref { vm_conv_gen = fun cv_pb env univs t1 t2 ->
- generic_conv cv_pb ~l2r:false (fun _ -> None) full_transparent_state env univs t1 t2 }
-
-let set_vm_conv_gen f = vm_conv_gen := f
-
let native_conv_gen pb sigma env univs t1 t2 =
if not Coq_config.native_compiler then begin
warn_no_native_compiler ();
- vm_conv_gen.contents.vm_conv_gen pb env univs t1 t2
+ Vconv.vm_conv_gen pb env univs t1 t2
end
else
- let penv = Environ.pre_env env in
let ml_filename, prefix = get_ml_filename () in
- let code, upds = mk_conv_code penv sigma prefix t1 t2 in
+ let code, upds = mk_conv_code env sigma prefix t1 t2 in
match compile ml_filename code ~profile:false with
| (true, fn) ->
begin
diff --git a/kernel/nativeconv.mli b/kernel/nativeconv.mli
index b603e3bd..2111739d 100644
--- a/kernel/nativeconv.mli
+++ b/kernel/nativeconv.mli
@@ -18,7 +18,3 @@ val native_conv : conv_pb -> evars -> types kernel_conversion_function
(** A conversion function parametrized by a universe comparator. Used outside of
the kernel. *)
val native_conv_gen : conv_pb -> evars -> (types, 'a) generic_conversion_function
-
-type vm_conv_gen = { vm_conv_gen : 'a. conv_pb -> (Constr.types, 'a) generic_conversion_function }
-
-val set_vm_conv_gen : vm_conv_gen -> unit
diff --git a/kernel/nativeinstr.mli b/kernel/nativeinstr.mli
index c319be32..2d8e2ba2 100644
--- a/kernel/nativeinstr.mli
+++ b/kernel/nativeinstr.mli
@@ -25,18 +25,18 @@ and lambda =
| Lrel of Name.t * int
| Lvar of Id.t
| Lmeta of metavariable * lambda (* type *)
- | Levar of Evar.t * lambda (* type *) * lambda array (* arguments *)
+ | Levar of Evar.t * lambda array (* arguments *)
| Lprod of lambda * lambda
| Llam of Name.t array * lambda
| Llet of Name.t * lambda * lambda
| Lapp of lambda * lambda array
| Lconst of prefix * pconstant
- | Lproj of prefix * Constant.t (* prefix, projection name *)
+ | Lproj of prefix * inductive * int (* prefix, inductive, index starting from 0 *)
| Lprim of prefix * Constant.t * CPrimitives.t * lambda array
| Lcase of annot_sw * lambda * lambda * lam_branches
(* annotations, term being matched, accu, branches *)
| Lif of lambda * lambda * lambda
- | Lfix of (int array * int) * fix_decl
+ | Lfix of (int array * (string * inductive) array * int) * fix_decl
| Lcofix of int * fix_decl (* must be in eta-expanded form *)
| Lmakeblock of prefix * pconstructor * int * lambda array
(* prefix, constructor name, constructor tag, arguments *)
diff --git a/kernel/nativelambda.ml b/kernel/nativelambda.ml
index b34eede6..122fe95d 100644
--- a/kernel/nativelambda.ml
+++ b/kernel/nativelambda.ml
@@ -12,7 +12,7 @@ open Names
open Esubst
open Constr
open Declarations
-open Pre_env
+open Environ
open Nativevalues
open Nativeinstr
@@ -23,7 +23,6 @@ exception NotClosed
type evars =
{ evars_val : existential -> constr option;
- evars_typ : existential -> types;
evars_metas : metavariable -> types }
(*s Constructors *)
@@ -102,10 +101,10 @@ let rec map_lam_with_binders g f n lam =
if body == body' && def == def' then lam else Llet(id,def',body')
| Lapp(fct,args) ->
let fct' = f n fct in
- let args' = Array.smartmap (f n) args in
+ let args' = Array.Smart.map (f n) args in
if fct == fct' && args == args' then lam else mkLapp fct' args'
| Lprim(prefix,kn,op,args) ->
- let args' = Array.smartmap (f n) args in
+ let args' = Array.Smart.map (f n) args in
if args == args' then lam else Lprim(prefix,kn,op,args')
| Lcase(annot,t,a,br) ->
let t' = f n t in
@@ -116,7 +115,7 @@ let rec map_lam_with_binders g f n lam =
if Array.is_empty ids then f n body
else f (g (Array.length ids) n) body in
if body == body' then b else (cn,ids,body') in
- let br' = Array.smartmap on_b br in
+ let br' = Array.Smart.map on_b br in
if t == t' && a == a' && br == br' then lam else Lcase(annot,t',a',br')
| Lif(t,bt,bf) ->
let t' = f n t in
@@ -124,31 +123,30 @@ let rec map_lam_with_binders g f n lam =
let bf' = f n bf in
if t == t' && bt == bt' && bf == bf' then lam else Lif(t',bt',bf')
| Lfix(init,(ids,ltypes,lbodies)) ->
- let ltypes' = Array.smartmap (f n) ltypes in
- let lbodies' = Array.smartmap (f (g (Array.length ids) n)) lbodies in
+ let ltypes' = Array.Smart.map (f n) ltypes in
+ let lbodies' = Array.Smart.map (f (g (Array.length ids) n)) lbodies in
if ltypes == ltypes' && lbodies == lbodies' then lam
else Lfix(init,(ids,ltypes',lbodies'))
| Lcofix(init,(ids,ltypes,lbodies)) ->
- let ltypes' = Array.smartmap (f n) ltypes in
- let lbodies' = Array.smartmap (f (g (Array.length ids) n)) lbodies in
+ let ltypes' = Array.Smart.map (f n) ltypes in
+ let lbodies' = Array.Smart.map (f (g (Array.length ids) n)) lbodies in
if ltypes == ltypes' && lbodies == lbodies' then lam
else Lcofix(init,(ids,ltypes',lbodies'))
| Lmakeblock(prefix,cn,tag,args) ->
- let args' = Array.smartmap (f n) args in
+ let args' = Array.Smart.map (f n) args in
if args == args' then lam else Lmakeblock(prefix,cn,tag,args')
| Luint u ->
let u' = map_uint g f n u in
if u == u' then lam else Luint u'
- | Levar (evk, ty, args) ->
- let ty' = f n ty in
- let args' = Array.smartmap (f n) args in
- if ty == ty' && args == args' then lam else Levar (evk, ty', args')
+ | Levar (evk, args) ->
+ let args' = Array.Smart.map (f n) args in
+ if args == args' then lam else Levar (evk, args')
and map_uint g f n u =
match u with
| UintVal _ -> u
| UintDigits(prefix,c,args) ->
- let args' = Array.smartmap (f n) args in
+ let args' = Array.Smart.map (f n) args in
if args == args' then u else UintDigits(prefix,c,args')
| UintDecomp(prefix,c,a) ->
let a' = f n a in
@@ -181,7 +179,7 @@ let rec lam_exsubst subst lam =
let lam_subst_args subst args =
if is_subs_id subst then args
- else Array.smartmap (lam_exsubst subst) args
+ else Array.Smart.map (lam_exsubst subst) args
(** Simplification of lambda expression *)
@@ -276,7 +274,7 @@ and simplify_app substf f substa args =
(* TODO | Lproj -> simplify if the argument is known or a known global *)
| _ -> mkLapp (simplify substf f) (simplify_args substa args)
-and simplify_args subst args = Array.smartmap (simplify subst) args
+and simplify_args subst args = Array.Smart.map (simplify subst) args
and reduce_lapp substf lids body substa largs =
match lids, largs with
@@ -337,54 +335,13 @@ let rec get_alias env (kn, u as p) =
(*i Global environment *)
-let global_env = ref empty_env
-
-let set_global_env env = global_env := env
-
let get_names decl =
let decl = Array.of_list decl in
Array.map fst decl
-(* Rel Environment *)
-module Vect =
- struct
- type 'a t = {
- mutable elems : 'a array;
- mutable size : int;
- }
-
- let make n a = {
- elems = Array.make n a;
- size = 0;
- }
-
- let extend v =
- if Int.equal v.size (Array.length v.elems) then
- let new_size = min (2*v.size) Sys.max_array_length in
- if new_size <= v.size then invalid_arg "Vect.extend";
- let new_elems = Array.make new_size v.elems.(0) in
- Array.blit v.elems 0 new_elems 0 (v.size);
- v.elems <- new_elems
-
- let push v a =
- extend v;
- v.elems.(v.size) <- a;
- v.size <- v.size + 1
-
- let popn v n =
- v.size <- max 0 (v.size - n)
-
- let pop v = popn v 1
-
- let get_last v n =
- if v.size <= n then invalid_arg "Vect.get:index out of bounds";
- v.elems.(v.size - n - 1)
-
- end
-
let empty_args = [||]
-module Renv =
+module Cache =
struct
module ConstrHash =
@@ -398,46 +355,20 @@ module Renv =
type constructor_info = tag * int * int (* nparam nrealargs *)
- type t = {
- name_rel : Name.t Vect.t;
- construct_tbl : constructor_info ConstrTable.t;
-
- }
-
-
- let make () = {
- name_rel = Vect.make 16 Anonymous;
- construct_tbl = ConstrTable.create 111
- }
-
- let push_rel env id = Vect.push env.name_rel id
-
- let push_rels env ids =
- Array.iter (push_rel env) ids
-
- let pop env = Vect.pop env.name_rel
-
- let popn env n =
- for _i = 1 to n do pop env done
-
- let get env n =
- Lrel (Vect.get_last env.name_rel (n-1), n)
-
- let get_construct_info env c =
- try ConstrTable.find env.construct_tbl c
+ let get_construct_info cache env c : constructor_info =
+ try ConstrTable.find cache c
with Not_found ->
let ((mind,j), i) = c in
- let oib = lookup_mind mind !global_env in
+ let oib = lookup_mind mind env in
let oip = oib.mind_packets.(j) in
let tag,arity = oip.mind_reloc_tbl.(i-1) in
let nparams = oib.mind_nparams in
let r = (tag, nparams, arity) in
- ConstrTable.add env.construct_tbl c r;
+ ConstrTable.add cache c r;
r
end
-(* What about pattern matching ?*)
-let is_lazy prefix t =
+let is_lazy env prefix t =
match kind t with
| App (f,args) ->
begin match kind f with
@@ -445,94 +376,103 @@ let is_lazy prefix t =
let entry = mkInd (fst c) in
(try
let _ =
- Retroknowledge.get_native_before_match_info (!global_env).retroknowledge
+ Retroknowledge.get_native_before_match_info env.retroknowledge
entry prefix c Llazy;
in
false
with Not_found -> true)
| _ -> true
end
- | LetIn _ -> true
+ | LetIn _ | Case _ | Proj _ -> true
| _ -> false
let evar_value sigma ev = sigma.evars_val ev
-let evar_type sigma ev = sigma.evars_typ ev
-
let meta_type sigma mv = sigma.evars_metas mv
let empty_evars =
{ evars_val = (fun _ -> None);
- evars_typ = (fun _ -> assert false);
evars_metas = (fun _ -> assert false) }
let empty_ids = [||]
-let rec lambda_of_constr env sigma c =
+(** Extract the inductive type over which a fixpoint is decreasing *)
+let rec get_fix_struct env i t = match kind (Reduction.whd_all env t) with
+| Prod (na, dom, t) ->
+ if Int.equal i 0 then
+ let dom = Reduction.whd_all env dom in
+ let (dom, _) = decompose_appvect dom in
+ match kind dom with
+ | Ind (ind, _) -> ind
+ | _ -> assert false
+ else
+ let env = Environ.push_rel (RelDecl.LocalAssum (na, dom)) env in
+ get_fix_struct env (i - 1) t
+| _ -> assert false
+
+let rec lambda_of_constr cache env sigma c =
match kind c with
| Meta mv ->
let ty = meta_type sigma mv in
- Lmeta (mv, lambda_of_constr env sigma ty)
+ Lmeta (mv, lambda_of_constr cache env sigma ty)
| Evar (evk,args as ev) ->
(match evar_value sigma ev with
| None ->
- let ty = evar_type sigma ev in
- let args = Array.map (lambda_of_constr env sigma) args in
- Levar(evk, lambda_of_constr env sigma ty, args)
- | Some t -> lambda_of_constr env sigma t)
+ let args = Array.map (lambda_of_constr cache env sigma) args in
+ Levar(evk, args)
+ | Some t -> lambda_of_constr cache env sigma t)
- | Cast (c, _, _) -> lambda_of_constr env sigma c
+ | Cast (c, _, _) -> lambda_of_constr cache env sigma c
- | Rel i -> Renv.get env i
+ | Rel i -> Lrel (RelDecl.get_name (Environ.lookup_rel i env), i)
| Var id -> Lvar id
| Sort s -> Lsort s
| Ind (ind,u as pind) ->
- let prefix = get_mind_prefix !global_env (fst ind) in
+ let prefix = get_mind_prefix env (fst ind) in
Lind (prefix, pind)
| Prod(id, dom, codom) ->
- let ld = lambda_of_constr env sigma dom in
- Renv.push_rel env id;
- let lc = lambda_of_constr env sigma codom in
- Renv.pop env;
+ let ld = lambda_of_constr cache env sigma dom in
+ let env = Environ.push_rel (RelDecl.LocalAssum (id, dom)) env in
+ let lc = lambda_of_constr cache env sigma codom in
Lprod(ld, Llam([|id|], lc))
| Lambda _ ->
let params, body = Term.decompose_lam c in
+ let fold (na, t) env = Environ.push_rel (RelDecl.LocalAssum (na, t)) env in
+ let env = List.fold_right fold params env in
+ let lb = lambda_of_constr cache env sigma body in
let ids = get_names (List.rev params) in
- Renv.push_rels env ids;
- let lb = lambda_of_constr env sigma body in
- Renv.popn env (Array.length ids);
mkLlam ids lb
- | LetIn(id, def, _, body) ->
- let ld = lambda_of_constr env sigma def in
- Renv.push_rel env id;
- let lb = lambda_of_constr env sigma body in
- Renv.pop env;
+ | LetIn(id, def, t, body) ->
+ let ld = lambda_of_constr cache env sigma def in
+ let env = Environ.push_rel (RelDecl.LocalDef (id, def, t)) env in
+ let lb = lambda_of_constr cache env sigma body in
Llet(id, ld, lb)
- | App(f, args) -> lambda_of_app env sigma f args
+ | App(f, args) -> lambda_of_app cache env sigma f args
- | Const _ -> lambda_of_app env sigma c empty_args
+ | Const _ -> lambda_of_app cache env sigma c empty_args
- | Construct _ -> lambda_of_app env sigma c empty_args
+ | Construct _ -> lambda_of_app cache env sigma c empty_args
| Proj (p, c) ->
- let kn = Projection.constant p in
- mkLapp (Lproj (get_const_prefix !global_env kn, kn)) [|lambda_of_constr env sigma c|]
+ let ind = Projection.inductive p in
+ let prefix = get_mind_prefix env (fst ind) in
+ mkLapp (Lproj (prefix, ind, Projection.arg p)) [|lambda_of_constr cache env sigma c|]
| Case(ci,t,a,branches) ->
let (mind,i as ind) = ci.ci_ind in
- let mib = lookup_mind mind !global_env in
+ let mib = lookup_mind mind env in
let oib = mib.mind_packets.(i) in
let tbl = oib.mind_reloc_tbl in
(* Building info *)
- let prefix = get_mind_prefix !global_env mind in
+ let prefix = get_mind_prefix env mind in
let annot_sw =
{ asw_ind = ind;
asw_ci = ci;
@@ -541,21 +481,21 @@ let rec lambda_of_constr env sigma c =
asw_prefix = prefix}
in
(* translation of the argument *)
- let la = lambda_of_constr env sigma a in
+ let la = lambda_of_constr cache env sigma a in
let entry = mkInd ind in
let la =
try
- Retroknowledge.get_native_before_match_info (!global_env).retroknowledge
+ Retroknowledge.get_native_before_match_info (env).retroknowledge
entry prefix (ind,1) la
with Not_found -> la
in
(* translation of the type *)
- let lt = lambda_of_constr env sigma t in
+ let lt = lambda_of_constr cache env sigma t in
(* translation of branches *)
let mk_branch i b =
let cn = (ind,i+1) in
let _, arity = tbl.(i) in
- let b = lambda_of_constr env sigma b in
+ let b = lambda_of_constr cache env sigma b in
if Int.equal arity 0 then (cn, empty_ids, b)
else
match b with
@@ -568,86 +508,90 @@ let rec lambda_of_constr env sigma c =
let bs = Array.mapi mk_branch branches in
Lcase(annot_sw, lt, la, bs)
- | Fix(rec_init,(names,type_bodies,rec_bodies)) ->
- let ltypes = lambda_of_args env sigma 0 type_bodies in
- Renv.push_rels env names;
- let lbodies = lambda_of_args env sigma 0 rec_bodies in
- Renv.popn env (Array.length names);
- Lfix(rec_init, (names, ltypes, lbodies))
+ | Fix((pos, i), (names,type_bodies,rec_bodies)) ->
+ let ltypes = lambda_of_args cache env sigma 0 type_bodies in
+ let map i t =
+ let ind = get_fix_struct env i t in
+ let prefix = get_mind_prefix env (fst ind) in
+ (prefix, ind)
+ in
+ let inds = Array.map2 map pos type_bodies in
+ let env = Environ.push_rec_types (names, type_bodies, rec_bodies) env in
+ let lbodies = lambda_of_args cache env sigma 0 rec_bodies in
+ Lfix((pos, inds, i), (names, ltypes, lbodies))
| CoFix(init,(names,type_bodies,rec_bodies)) ->
- let rec_bodies = Array.map2 (Hook.get Clambda.eta_expand !global_env) rec_bodies type_bodies in
- let ltypes = lambda_of_args env sigma 0 type_bodies in
- Renv.push_rels env names;
- let lbodies = lambda_of_args env sigma 0 rec_bodies in
- Renv.popn env (Array.length names);
+ let rec_bodies = Array.map2 (Reduction.eta_expand env) rec_bodies type_bodies in
+ let ltypes = lambda_of_args cache env sigma 0 type_bodies in
+ let env = Environ.push_rec_types (names, type_bodies, rec_bodies) env in
+ let lbodies = lambda_of_args cache env sigma 0 rec_bodies in
Lcofix(init, (names, ltypes, lbodies))
-and lambda_of_app env sigma f args =
+and lambda_of_app cache env sigma f args =
match kind f with
| Const (kn,u as c) ->
- let kn,u = get_alias !global_env c in
- let cb = lookup_constant kn !global_env in
+ let kn,u = get_alias env c in
+ let cb = lookup_constant kn env in
(try
- let prefix = get_const_prefix !global_env kn in
+ let prefix = get_const_prefix env kn in
(* We delay the compilation of arguments to avoid an exponential behavior *)
let f = Retroknowledge.get_native_compiling_info
- (!global_env).retroknowledge (mkConst kn) prefix in
- let args = lambda_of_args env sigma 0 args in
+ (env).retroknowledge (mkConst kn) prefix in
+ let args = lambda_of_args cache env sigma 0 args in
f args
with Not_found ->
begin match cb.const_body with
| Def csubst -> (* TODO optimize if f is a proj and argument is known *)
if cb.const_inline_code then
- lambda_of_app env sigma (Mod_subst.force_constr csubst) args
+ lambda_of_app cache env sigma (Mod_subst.force_constr csubst) args
else
- let prefix = get_const_prefix !global_env kn in
+ let prefix = get_const_prefix env kn in
let t =
- if is_lazy prefix (Mod_subst.force_constr csubst) then
+ if is_lazy env prefix (Mod_subst.force_constr csubst) then
mkLapp Lforce [|Lconst (prefix, (kn,u))|]
else Lconst (prefix, (kn,u))
in
- mkLapp t (lambda_of_args env sigma 0 args)
+ mkLapp t (lambda_of_args cache env sigma 0 args)
| OpaqueDef _ | Undef _ ->
- let prefix = get_const_prefix !global_env kn in
- mkLapp (Lconst (prefix, (kn,u))) (lambda_of_args env sigma 0 args)
+ let prefix = get_const_prefix env kn in
+ mkLapp (Lconst (prefix, (kn,u))) (lambda_of_args cache env sigma 0 args)
end)
| Construct (c,u) ->
- let tag, nparams, arity = Renv.get_construct_info env c in
+ let tag, nparams, arity = Cache.get_construct_info cache env c in
let expected = nparams + arity in
let nargs = Array.length args in
- let prefix = get_mind_prefix !global_env (fst (fst c)) in
+ let prefix = get_mind_prefix env (fst (fst c)) in
if Int.equal nargs expected then
try
try
Retroknowledge.get_native_constant_static_info
- (!global_env).retroknowledge
+ (env).retroknowledge
f args
with NotClosed ->
assert (Int.equal nparams 0); (* should be fine for int31 *)
- let args = lambda_of_args env sigma nparams args in
+ let args = lambda_of_args cache env sigma nparams args in
Retroknowledge.get_native_constant_dynamic_info
- (!global_env).retroknowledge f prefix c args
+ (env).retroknowledge f prefix c args
with Not_found ->
- let args = lambda_of_args env sigma nparams args in
- makeblock !global_env c u tag args
+ let args = lambda_of_args cache env sigma nparams args in
+ makeblock env c u tag args
else
- let args = lambda_of_args env sigma 0 args in
+ let args = lambda_of_args cache env sigma 0 args in
(try
Retroknowledge.get_native_constant_dynamic_info
- (!global_env).retroknowledge f prefix c args
+ (env).retroknowledge f prefix c args
with Not_found ->
mkLapp (Lconstruct (prefix, (c,u))) args)
| _ ->
- let f = lambda_of_constr env sigma f in
- let args = lambda_of_args env sigma 0 args in
+ let f = lambda_of_constr cache env sigma f in
+ let args = lambda_of_args cache env sigma 0 args in
mkLapp f args
-and lambda_of_args env sigma start args =
+and lambda_of_args cache env sigma start args =
let nargs = Array.length args in
if start < nargs then
Array.init (nargs - start)
- (fun i -> lambda_of_constr env sigma args.(start + i))
+ (fun i -> lambda_of_constr cache env sigma args.(start + i))
else empty_args
let optimize lam =
@@ -660,11 +604,8 @@ let optimize lam =
lam
let lambda_of_constr env sigma c =
- set_global_env env;
- let env = Renv.make () in
- let ids = List.rev_map RelDecl.get_name !global_env.env_rel_context.env_rel_ctx in
- Renv.push_rels env (Array.of_list ids);
- let lam = lambda_of_constr env sigma c in
+ let cache = Cache.ConstrTable.create 91 in
+ let lam = lambda_of_constr cache env sigma c in
(* if Flags.vm_draw_opt () then begin
(msgerrnl (str "Constr = \n" ++ pr_constr c);flush_all());
(msgerrnl (str "Lambda = \n" ++ pp_lam lam);flush_all());
diff --git a/kernel/nativelambda.mli b/kernel/nativelambda.mli
index 9a1e19b3..7b202589 100644
--- a/kernel/nativelambda.mli
+++ b/kernel/nativelambda.mli
@@ -9,13 +9,12 @@
(************************************************************************)
open Names
open Constr
-open Pre_env
+open Environ
open Nativeinstr
(** This file defines the lambda code generation phase of the native compiler *)
type evars =
{ evars_val : existential -> constr option;
- evars_typ : existential -> types;
evars_metas : metavariable -> types }
val empty_evars : evars
@@ -23,7 +22,7 @@ val empty_evars : evars
val decompose_Llam : lambda -> Name.t array * lambda
val decompose_Llam_Llet : lambda -> (Name.t * lambda option) array * lambda
-val is_lazy : prefix -> constr -> bool
+val is_lazy : env -> prefix -> constr -> bool
val mk_lazy : lambda -> lambda
val get_mind_prefix : env -> MutInd.t -> string
diff --git a/kernel/nativelibrary.ml b/kernel/nativelibrary.ml
index c69cf722..8ac3538f 100644
--- a/kernel/nativelibrary.ml
+++ b/kernel/nativelibrary.ml
@@ -10,7 +10,6 @@
open Names
open Declarations
-open Environ
open Mod_subst
open Modops
open Nativecode
@@ -30,15 +29,15 @@ and translate_field prefix mp env acc (l,x) =
| SFBconst cb ->
let con = Constant.make3 mp DirPath.empty l in
(if !Flags.debug then
- let msg = Printf.sprintf "Compiling constant %s..." (Constant.to_string con) in
+ let msg = Printf.sprintf "Compiling constant %s..." (Constant.to_string con) in
Feedback.msg_debug (Pp.str msg));
- compile_constant_field (pre_env env) prefix con acc cb
+ compile_constant_field env prefix con acc cb
| SFBmind mb ->
(if !Flags.debug then
let id = mb.mind_packets.(0).mind_typename in
let msg = Printf.sprintf "Compiling inductive %s..." (Id.to_string id) in
Feedback.msg_debug (Pp.str msg));
- compile_mind_field prefix mp l acc mb
+ compile_mind_field mp l acc mb
| SFBmodule md ->
let mp = md.mod_mp in
(if !Flags.debug then
diff --git a/kernel/nativevalues.ml b/kernel/nativevalues.ml
index 066dfc39..93e74af8 100644
--- a/kernel/nativevalues.ml
+++ b/kernel/nativevalues.ml
@@ -63,8 +63,8 @@ type atom =
| Acofixe of t array * t array * int * t
| Aprod of Name.t * t * (t -> t)
| Ameta of metavariable * t
- | Aevar of Evar.t * t * t array
- | Aproj of Constant.t * accumulator
+ | Aevar of Evar.t * t array
+ | Aproj of (inductive * int) * accumulator
let accumulate_tag = 0
@@ -117,7 +117,7 @@ let mk_ind_accu ind u =
let mk_sort_accu s u =
let open Sorts in
match s with
- | Prop _ -> mk_accu (Asort s)
+ | Prop | Set -> mk_accu (Asort s)
| Type s ->
let u = Univ.Instance.of_array u in
let s = Univ.subst_instance_universe u s in
@@ -135,8 +135,8 @@ let mk_prod_accu s dom codom =
let mk_meta_accu mv ty =
mk_accu (Ameta (mv,ty))
-let mk_evar_accu ev ty args =
- mk_accu (Aevar (ev,ty,args))
+let mk_evar_accu ev args =
+ mk_accu (Aevar (ev, args))
let mk_proj_accu kn c =
mk_accu (Aproj (kn,c))
@@ -154,10 +154,6 @@ let args_of_accu (k:accumulator) =
let acc = (get_accu k).acc_arg in
(Obj.magic (Array.of_list acc) : t array)
-let is_accu x =
- let o = Obj.repr x in
- Obj.is_block o && Int.equal (Obj.tag o) accumulate_tag
-
let mk_fix_accu rec_pos pos types bodies =
mk_accu (Afix(types,bodies,rec_pos, pos))
@@ -172,19 +168,17 @@ let upd_cofix (cofix :t) (cofix_fun : t) =
| _ -> assert false
let force_cofix (cofix : t) =
- if is_accu cofix then
- let accu = (Obj.magic cofix : accumulator) in
- let atom = atom_of_accu accu in
- match atom with
- | Acofix(typ,norm,pos,f) ->
- let args = args_of_accu accu in
- let f = Array.fold_right (fun arg f -> f arg) args f in
- let v = f (Obj.magic ()) in
- set_atom_of_accu accu (Acofixe(typ,norm,pos,v));
- v
- | Acofixe(_,_,_,v) -> v
- | _ -> cofix
- else cofix
+ let accu = (Obj.magic cofix : accumulator) in
+ let atom = atom_of_accu accu in
+ match atom with
+ | Acofix(typ,norm,pos,f) ->
+ let args = args_of_accu accu in
+ let f = Array.fold_right (fun arg f -> f arg) args f in
+ let v = f (Obj.magic ()) in
+ set_atom_of_accu accu (Acofixe(typ,norm,pos,v));
+ v
+ | Acofixe(_,_,_,v) -> v
+ | _ -> cofix
let mk_const tag = Obj.magic tag
diff --git a/kernel/nativevalues.mli b/kernel/nativevalues.mli
index 4a58a3c7..10689941 100644
--- a/kernel/nativevalues.mli
+++ b/kernel/nativevalues.mli
@@ -53,8 +53,8 @@ type atom =
| Acofixe of t array * t array * int * t
| Aprod of Name.t * t * (t -> t)
| Ameta of metavariable * t
- | Aevar of Evar.t * t (* type *) * t array (* arguments *)
- | Aproj of Constant.t * accumulator
+ | Aevar of Evar.t * t array (* arguments *)
+ | Aproj of (inductive * int) * accumulator
(* Constructors *)
@@ -70,8 +70,8 @@ val mk_prod_accu : Name.t -> t -> t -> t
val mk_fix_accu : rec_pos -> int -> t array -> t array -> t
val mk_cofix_accu : int -> t array -> t array -> t
val mk_meta_accu : metavariable -> t
-val mk_evar_accu : Evar.t -> t -> t array -> t
-val mk_proj_accu : Constant.t -> accumulator -> t
+val mk_evar_accu : Evar.t -> t array -> t
+val mk_proj_accu : (inductive * int) -> accumulator -> t
val upd_cofix : t -> t -> unit
val force_cofix : t -> t
val mk_const : tag -> t
@@ -110,9 +110,6 @@ type kind_of_value =
val kind_of_value : t -> kind_of_value
-(* *)
-val is_accu : t -> bool
-
val str_encode : 'a -> string
val str_decode : string -> 'a
diff --git a/kernel/opaqueproof.ml b/kernel/opaqueproof.ml
index a484c08e..f8b71e45 100644
--- a/kernel/opaqueproof.ml
+++ b/kernel/opaqueproof.ml
@@ -18,7 +18,7 @@ type work_list = (Instance.t * Id.t array) Cmap.t *
type cooking_info = {
modlist : work_list;
- abstract : Context.Named.t * Univ.Instance.t * Univ.AUContext.t }
+ abstract : Constr.named_context * Univ.Instance.t * Univ.AUContext.t }
type proofterm = (constr * Univ.ContextSet.t) Future.computation
type opaque =
| Indirect of substitution list * DirPath.t * int (* subst, lib, index *)
diff --git a/kernel/opaqueproof.mli b/kernel/opaqueproof.mli
index b6ae80b4..5ea6da64 100644
--- a/kernel/opaqueproof.mli
+++ b/kernel/opaqueproof.mli
@@ -51,7 +51,7 @@ type work_list = (Univ.Instance.t * Id.t array) Cmap.t *
type cooking_info = {
modlist : work_list;
- abstract : Context.Named.t * Univ.Instance.t * Univ.AUContext.t }
+ abstract : Constr.named_context * Univ.Instance.t * Univ.AUContext.t }
(* The type has two caveats:
1) cook_constr is defined after
diff --git a/kernel/pre_env.ml b/kernel/pre_env.ml
deleted file mode 100644
index 8ebe48e2..00000000
--- a/kernel/pre_env.ml
+++ /dev/null
@@ -1,213 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-(* Created by Benjamin Grégoire out of environ.ml for better
- modularity in the design of the bytecode virtual evaluation
- machine, Dec 2005 *)
-(* Bug fix by Jean-Marc Notin *)
-
-(* This file defines the type of kernel environments *)
-
-open Util
-open Names
-open Declarations
-
-module NamedDecl = Context.Named.Declaration
-
-(* The type of environments. *)
-
-(* The key attached to each constant is used by the VM to retrieve previous *)
-(* evaluations of the constant. It is essentially an index in the symbols table *)
-(* used by the VM. *)
-type key = int CEphemeron.key option ref
-
-(** Linking information for the native compiler. *)
-
-type link_info =
- | Linked of string
- | LinkedInteractive of string
- | NotLinked
-
-type constant_key = constant_body * (link_info ref * key)
-
-type mind_key = mutual_inductive_body * link_info ref
-
-type globals = {
- env_constants : constant_key Cmap_env.t;
- env_inductives : mind_key Mindmap_env.t;
- env_modules : module_body MPmap.t;
- env_modtypes : module_type_body MPmap.t}
-
-type stratification = {
- env_universes : UGraph.t;
- env_engagement : engagement
-}
-
-type val_kind =
- | VKvalue of (Vmvalues.values * Id.Set.t) CEphemeron.key
- | VKnone
-
-type lazy_val = val_kind ref
-
-let force_lazy_val vk = match !vk with
-| VKnone -> None
-| VKvalue v -> try Some (CEphemeron.get v) with CEphemeron.InvalidKey -> None
-
-let dummy_lazy_val () = ref VKnone
-let build_lazy_val vk key = vk := VKvalue (CEphemeron.create key)
-
-type named_context_val = {
- env_named_ctx : Context.Named.t;
- env_named_map : (Context.Named.Declaration.t * lazy_val) Id.Map.t;
-}
-
-type rel_context_val = {
- env_rel_ctx : Context.Rel.t;
- env_rel_map : (Context.Rel.Declaration.t * lazy_val) Range.t;
-}
-
-type env = {
- env_globals : globals; (* globals = constants + inductive types + modules + module-types *)
- env_named_context : named_context_val; (* section variables *)
- env_rel_context : rel_context_val;
- env_nb_rel : int;
- env_stratification : stratification;
- env_typing_flags : typing_flags;
- retroknowledge : Retroknowledge.retroknowledge;
- indirect_pterms : Opaqueproof.opaquetab;
-}
-
-let empty_named_context_val = {
- env_named_ctx = [];
- env_named_map = Id.Map.empty;
-}
-
-let empty_rel_context_val = {
- env_rel_ctx = [];
- env_rel_map = Range.empty;
-}
-
-let empty_env = {
- env_globals = {
- env_constants = Cmap_env.empty;
- env_inductives = Mindmap_env.empty;
- env_modules = MPmap.empty;
- env_modtypes = MPmap.empty};
- env_named_context = empty_named_context_val;
- env_rel_context = empty_rel_context_val;
- env_nb_rel = 0;
- env_stratification = {
- env_universes = UGraph.initial_universes;
- env_engagement = PredicativeSet };
- env_typing_flags = Declareops.safe_flags Conv_oracle.empty;
- retroknowledge = Retroknowledge.initial_retroknowledge;
- indirect_pterms = Opaqueproof.empty_opaquetab }
-
-
-(* Rel context *)
-
-let nb_rel env = env.env_nb_rel
-
-let push_rel_context_val d ctx = {
- env_rel_ctx = Context.Rel.add d ctx.env_rel_ctx;
- env_rel_map = Range.cons (d, ref VKnone) ctx.env_rel_map;
-}
-
-let match_rel_context_val ctx = match ctx.env_rel_ctx with
-| [] -> None
-| decl :: rem ->
- let (_, lval) = Range.hd ctx.env_rel_map in
- let ctx = { env_rel_ctx = rem; env_rel_map = Range.tl ctx.env_rel_map } in
- Some (decl, lval, ctx)
-
-let push_rel d env =
- { env with
- env_rel_context = push_rel_context_val d env.env_rel_context;
- env_nb_rel = env.env_nb_rel + 1 }
-
-let lookup_rel n env =
- try fst (Range.get env.env_rel_context.env_rel_map (n - 1))
- with Invalid_argument _ -> raise Not_found
-
-let lookup_rel_val n env =
- try snd (Range.get env.env_rel_context.env_rel_map (n - 1))
- with Invalid_argument _ -> raise Not_found
-
-let rel_skipn n ctx = {
- env_rel_ctx = Util.List.skipn n ctx.env_rel_ctx;
- env_rel_map = Range.skipn n ctx.env_rel_map;
-}
-
-let env_of_rel n env =
- { env with
- env_rel_context = rel_skipn n env.env_rel_context;
- env_nb_rel = env.env_nb_rel - n
- }
-
-(* Named context *)
-
-let push_named_context_val_val d rval ctxt =
-(* assert (not (Id.Map.mem (NamedDecl.get_id d) ctxt.env_named_map)); *)
- {
- env_named_ctx = Context.Named.add d ctxt.env_named_ctx;
- env_named_map = Id.Map.add (NamedDecl.get_id d) (d, rval) ctxt.env_named_map;
- }
-
-let push_named_context_val d ctxt =
- push_named_context_val_val d (ref VKnone) ctxt
-
-let match_named_context_val c = match c.env_named_ctx with
-| [] -> None
-| decl :: ctx ->
- let (_, v) = Id.Map.find (NamedDecl.get_id decl) c.env_named_map in
- let map = Id.Map.remove (NamedDecl.get_id decl) c.env_named_map in
- let cval = { env_named_ctx = ctx; env_named_map = map } in
- Some (decl, v, cval)
-
-let map_named_val f ctxt =
- let open Context.Named.Declaration in
- let fold accu d =
- let d' = map_constr f d in
- let accu =
- if d == d' then accu
- else Id.Map.modify (get_id d) (fun _ (_, v) -> (d', v)) accu
- in
- (accu, d')
- in
- let map, ctx = List.fold_left_map fold ctxt.env_named_map ctxt.env_named_ctx in
- if map == ctxt.env_named_map then ctxt
- else { env_named_ctx = ctx; env_named_map = map }
-
-let push_named d env =
- {env with env_named_context = push_named_context_val d env.env_named_context}
-
-let lookup_named id env =
- fst (Id.Map.find id env.env_named_context.env_named_map)
-
-let lookup_named_val id env =
- snd(Id.Map.find id env.env_named_context.env_named_map)
-
-(* Warning all the names should be different *)
-let env_of_named id env = env
-
-(* Global constants *)
-
-let lookup_constant_key kn env =
- Cmap_env.find kn env.env_globals.env_constants
-
-let lookup_constant kn env =
- fst (Cmap_env.find kn env.env_globals.env_constants)
-
-(* Mutual Inductives *)
-let lookup_mind kn env =
- fst (Mindmap_env.find kn env.env_globals.env_inductives)
-
-let lookup_mind_key kn env =
- Mindmap_env.find kn env.env_globals.env_inductives
diff --git a/kernel/pre_env.mli b/kernel/pre_env.mli
deleted file mode 100644
index b0507481..00000000
--- a/kernel/pre_env.mli
+++ /dev/null
@@ -1,108 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Names
-open Constr
-open Declarations
-
-(** The type of environments. *)
-
-type link_info =
- | Linked of string
- | LinkedInteractive of string
- | NotLinked
-
-type key = int CEphemeron.key option ref
-
-type constant_key = constant_body * (link_info ref * key)
-
-type mind_key = mutual_inductive_body * link_info ref
-
-type globals = {
- env_constants : constant_key Cmap_env.t;
- env_inductives : mind_key Mindmap_env.t;
- env_modules : module_body MPmap.t;
- env_modtypes : module_type_body MPmap.t}
-
-type stratification = {
- env_universes : UGraph.t;
- env_engagement : engagement
-}
-
-type lazy_val
-
-val force_lazy_val : lazy_val -> (Vmvalues.values * Id.Set.t) option
-val dummy_lazy_val : unit -> lazy_val
-val build_lazy_val : lazy_val -> (Vmvalues.values * Id.Set.t) -> unit
-
-type named_context_val = private {
- env_named_ctx : Context.Named.t;
- env_named_map : (Context.Named.Declaration.t * lazy_val) Id.Map.t;
-}
-
-type rel_context_val = private {
- env_rel_ctx : Context.Rel.t;
- env_rel_map : (Context.Rel.Declaration.t * lazy_val) Range.t;
-}
-
-type env = {
- env_globals : globals;
- env_named_context : named_context_val;
- env_rel_context : rel_context_val;
- env_nb_rel : int;
- env_stratification : stratification;
- env_typing_flags : typing_flags;
- retroknowledge : Retroknowledge.retroknowledge;
- indirect_pterms : Opaqueproof.opaquetab;
-}
-
-val empty_named_context_val : named_context_val
-
-val empty_env : env
-
-(** Rel context *)
-
-val empty_rel_context_val : rel_context_val
-val push_rel_context_val :
- Context.Rel.Declaration.t -> rel_context_val -> rel_context_val
-val match_rel_context_val :
- rel_context_val -> (Context.Rel.Declaration.t * lazy_val * rel_context_val) option
-
-val nb_rel : env -> int
-val push_rel : Context.Rel.Declaration.t -> env -> env
-val lookup_rel : int -> env -> Context.Rel.Declaration.t
-val lookup_rel_val : int -> env -> lazy_val
-val env_of_rel : int -> env -> env
-
-(** Named context *)
-
-val push_named_context_val :
- Context.Named.Declaration.t -> named_context_val -> named_context_val
-val push_named_context_val_val :
- Context.Named.Declaration.t -> lazy_val -> named_context_val -> named_context_val
-val match_named_context_val :
- named_context_val -> (Context.Named.Declaration.t * lazy_val * named_context_val) option
-val map_named_val :
- (constr -> constr) -> named_context_val -> named_context_val
-
-val push_named : Context.Named.Declaration.t -> env -> env
-val lookup_named : Id.t -> env -> Context.Named.Declaration.t
-val lookup_named_val : Id.t -> env -> lazy_val
-val env_of_named : Id.t -> env -> env
-
-(** Global constants *)
-
-
-val lookup_constant_key : Constant.t -> env -> constant_key
-val lookup_constant : Constant.t -> env -> constant_body
-
-(** Mutual Inductives *)
-val lookup_mind_key : MutInd.t -> env -> mind_key
-val lookup_mind : MutInd.t -> env -> mutual_inductive_body
diff --git a/kernel/reduction.ml b/kernel/reduction.ml
index 2ae676bc..c701b53f 100644
--- a/kernel/reduction.ml
+++ b/kernel/reduction.ml
@@ -53,7 +53,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) ->
Int.equal bal 0 (* && c1.ci_ind = c2.ci_ind *) && compare_rec 0 s1 s2
@@ -66,7 +66,7 @@ let compare_stack_shape stk1 stk2 =
type lft_constr_stack_elt =
Zlapp of (lift * fconstr) array
- | Zlproj of Constant.t * lift
+ | Zlproj of 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
@@ -84,7 +84,7 @@ let map_lift (l : lift) (v : fconstr array) = match v with
| [|c0; c1|] -> [|(l, c0); (l, c1)|]
| [|c0; c1; c2|] -> [|(l, c0); (l, c1); (l, c2)|]
| [|c0; c1; c2; c3|] -> [|(l, c0); (l, c1); (l, c2); (l, c3)|]
-| v -> CArray.Fun1.map (fun l t -> (l, t)) l v
+| v -> Array.Fun1.map (fun l t -> (l, t)) l v
let pure_stack lfts stk =
let rec pure_rec lfts stk =
@@ -96,8 +96,8 @@ let pure_stack lfts stk =
| (Zshift n,(l,pstk)) -> (el_shft n l, pstk)
| (Zapp a, (l,pstk)) ->
(l,zlapp (map_lift l 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)
@@ -297,7 +297,7 @@ let compare_stacks f fmind lft1 stk1 lft2 stk2 cuniv =
| (Zlapp a1,Zlapp a2) ->
Array.fold_right2 f a1 a2 cu1
| (Zlproj (c1,l1),Zlproj (c2,l2)) ->
- if not (Constant.equal c1 c2) then
+ if not (Projection.Repr.equal c1 c2) then
raise NotConvertible
else cu1
| (Zlfix(fx1,a1),Zlfix(fx2,a2)) ->
@@ -408,7 +408,7 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
| Some s2 ->
eqappr cv_pb l2r infos appr1 (lft2, (c2, (s2 :: v2))) cuniv
| None ->
- if Constant.equal (Projection.constant p1) (Projection.constant p2)
+ if Projection.Repr.equal (Projection.repr p1) (Projection.repr p2)
&& compare_stack_shape v1 v2 then
let el1 = el_stack lft1 v1 in
let el2 = el_stack lft2 v2 in
@@ -649,23 +649,19 @@ let check_leq univs u u' =
let check_sort_cmp_universes env pb s0 s1 univs =
let open Sorts in
if not (type_in_type env) then
+ let check_pb u0 u1 =
+ match pb with
+ | CUMUL -> check_leq univs u0 u1
+ | CONV -> check_eq univs u0 u1
+ in
match (s0,s1) with
- | (Prop c1, Prop c2) when is_cumul pb ->
- begin match c1, c2 with
- | Null, _ | _, Pos -> () (* Prop <= Set *)
- | _ -> raise NotConvertible
- end
- | (Prop c1, Prop c2) -> if c1 != c2 then raise NotConvertible
- | (Prop c1, Type u) ->
- let u0 = univ_of_sort s0 in
- (match pb with
- | CUMUL -> check_leq univs u0 u
- | CONV -> check_eq univs u0 u)
- | (Type u, Prop c) -> raise NotConvertible
- | (Type u1, Type u2) ->
- (match pb with
- | CUMUL -> check_leq univs u1 u2
- | CONV -> check_eq univs u1 u2)
+ | Prop, Prop | Set, Set -> ()
+ | Prop, (Set | Type _) -> if not (is_cumul pb) then raise NotConvertible
+ | Set, Prop -> raise NotConvertible
+ | Set, Type u -> check_pb Univ.type0_univ u
+ | Type u, Prop -> raise NotConvertible
+ | Type u, Set -> check_pb u Univ.type0_univ
+ | Type u0, Type u1 -> check_pb u0 u1
let checked_sort_cmp_universes env pb s0 s1 univs =
check_sort_cmp_universes env pb s0 s1 univs; univs
@@ -697,26 +693,23 @@ let infer_leq (univs, cstrs as cuniv) u u' =
univs, Univ.Constraint.union cstrs cstrs'
let infer_cmp_universes env pb s0 s1 univs =
- let open Sorts in
- if type_in_type env then univs
+ if type_in_type env
+ then univs
else
+ let open Sorts in
+ let infer_pb u0 u1 =
+ match pb with
+ | CUMUL -> infer_leq univs u0 u1
+ | CONV -> infer_eq univs u0 u1
+ in
match (s0,s1) with
- | (Prop c1, Prop c2) when is_cumul pb ->
- begin match c1, c2 with
- | Null, _ | _, Pos -> univs (* Prop <= Set *)
- | _ -> raise NotConvertible
- end
- | (Prop c1, Prop c2) -> if c1 == c2 then univs else raise NotConvertible
- | (Prop c1, Type u) ->
- let u0 = univ_of_sort s0 in
- (match pb with
- | CUMUL -> infer_leq univs u0 u
- | CONV -> infer_eq univs u0 u)
- | (Type u, Prop c) -> raise NotConvertible
- | (Type u1, Type u2) ->
- (match pb with
- | CUMUL -> infer_leq univs u1 u2
- | CONV -> infer_eq univs u1 u2)
+ | Prop, Prop | Set, Set -> univs
+ | Prop, (Set | Type _) -> if not (is_cumul pb) then raise NotConvertible else univs
+ | Set, Prop -> raise NotConvertible
+ | Set, Type u -> infer_pb Univ.type0_univ u
+ | Type u, Prop -> raise NotConvertible
+ | Type u, Set -> infer_pb u Univ.type0_univ
+ | Type u0, Type u1 -> infer_pb u0 u1
let infer_convert_instances ~flex u u' (univs,cstrs) =
let cstrs' =
@@ -788,24 +781,6 @@ let infer_conv_leq ?(l2r=false) ?(evars=fun _ -> None) ?(ts=full_transparent_sta
env univs t1 t2 =
infer_conv_universes CUMUL l2r evars ts env univs t1 t2
-(* This reference avoids always having to link C code with the kernel *)
-let vm_conv = ref (fun cv_pb env ->
- gen_conv cv_pb env ~evars:((fun _->None), universes env))
-
-let warn_bytecode_compiler_failed =
- let open Pp in
- CWarnings.create ~name:"bytecode-compiler-failed" ~category:"bytecode-compiler"
- (fun () -> strbrk "Bytecode compiler failed, " ++
- strbrk "falling back to standard conversion")
-
-let set_vm_conv (f:conv_pb -> types kernel_conversion_function) = vm_conv := f
-let vm_conv cv_pb env t1 t2 =
- try
- !vm_conv cv_pb env t1 t2
- with Not_found | Invalid_argument _ ->
- warn_bytecode_compiler_failed ();
- gen_conv cv_pb env t1 t2
-
let default_conv cv_pb ?(l2r=false) env t1 t2 =
gen_conv cv_pb env t1 t2
@@ -937,7 +912,6 @@ let is_arity env c =
with NotArity -> false
let eta_expand env t ty =
- let env = env_of_pre_env env in
let ctxt, codom = dest_prod env ty in
let ctxt',t = dest_lam env t in
let d = Context.Rel.nhyps ctxt - Context.Rel.nhyps ctxt' in
@@ -945,5 +919,3 @@ let eta_expand env t ty =
let t = Term.applistc (Vars.lift d t) eta_args in
let t = Term.it_mkLambda_or_LetIn t (List.firstn d ctxt) in
Term.it_mkLambda_or_LetIn t ctxt'
-
-let _ = Hook.set Clambda.eta_expand_hook eta_expand
diff --git a/kernel/reduction.mli b/kernel/reduction.mli
index 49384340..581e8bd8 100644
--- a/kernel/reduction.mli
+++ b/kernel/reduction.mli
@@ -87,10 +87,6 @@ val infer_conv_leq : ?l2r:bool -> ?evars:(existential->constr option) ->
val generic_conv : conv_pb -> l2r:bool -> (existential->constr option) ->
Names.transparent_state -> (constr,'a) generic_conversion_function
-(** option for conversion *)
-val set_vm_conv : (conv_pb -> types kernel_conversion_function) -> unit
-val vm_conv : conv_pb -> types kernel_conversion_function
-
val default_conv : conv_pb -> ?l2r:bool -> types kernel_conversion_function
val default_conv_leq : ?l2r:bool -> types kernel_conversion_function
@@ -120,14 +116,14 @@ val betazeta_appvect : int -> constr -> constr array -> constr
(***********************************************************************
s Recognizing products and arities modulo reduction *)
-val dest_prod : env -> types -> Context.Rel.t * types
-val dest_prod_assum : env -> types -> Context.Rel.t * types
-val dest_lam : env -> types -> Context.Rel.t * constr
-val dest_lam_assum : env -> types -> Context.Rel.t * types
+val dest_prod : env -> types -> Constr.rel_context * types
+val dest_prod_assum : env -> types -> Constr.rel_context * types
+val dest_lam : env -> constr -> Constr.rel_context * constr
+val dest_lam_assum : env -> constr -> Constr.rel_context * constr
exception NotArity
val dest_arity : env -> types -> Term.arity (* raises NotArity if not an arity *)
val is_arity : env -> types -> bool
-val warn_bytecode_compiler_failed : ?loc:Loc.t -> unit -> unit
+val eta_expand : env -> constr -> types -> constr
diff --git a/kernel/retroknowledge.ml b/kernel/retroknowledge.ml
index d76b05a8..34f62def 100644
--- a/kernel/retroknowledge.ml
+++ b/kernel/retroknowledge.ml
@@ -25,22 +25,6 @@ open Constr
(* aliased type for clarity purpose*)
type entry = Constr.t
-(* [field]-s are the roles the kernel can learn of. *)
-type nat_field =
- | NatType
- | NatPlus
- | NatTimes
-
-type n_field =
- | NPositive
- | NType
- | NTwice
- | NTwicePlusOne
- | NPhi
- | NPhiInv
- | NPlus
- | NTimes
-
type int31_field =
| Int31Bits
| Int31Type
@@ -69,9 +53,6 @@ type int31_field =
| Int31Lxor
type field =
- (* | KEq
- | KNat of nat_field
- | KN of n_field *)
| KInt31 of string*int31_field
diff --git a/kernel/retroknowledge.mli b/kernel/retroknowledge.mli
index 0334e7a9..02d961d8 100644
--- a/kernel/retroknowledge.mli
+++ b/kernel/retroknowledge.mli
@@ -18,21 +18,6 @@ type entry = Constr.t
(** the following types correspond to the different "things"
the kernel can learn about.*)
-type nat_field =
- | NatType
- | NatPlus
- | NatTimes
-
-type n_field =
- | NPositive
- | NType
- | NTwice
- | NTwicePlusOne
- | NPhi
- | NPhiInv
- | NPlus
- | NTimes
-
type int31_field =
| Int31Bits
| Int31Type
@@ -61,13 +46,8 @@ type int31_field =
| Int31Lxor
type field =
-
-(** | KEq
- | KNat of nat_field
- | KN of n_field *)
| KInt31 of string*int31_field
-
(** This type represent an atomic action of the retroknowledge. It
is stored in the compiled libraries
As per now, there is only the possibility of registering things
@@ -134,7 +114,7 @@ val get_native_before_match_info : retroknowledge -> entry ->
Nativeinstr.lambda -> Nativeinstr.lambda
-(** the following functions are solely used in Pre_env and Environ to implement
+(** the following functions are solely used in Environ and Safe_typing to implement
the functions register and unregister (and mem) of Environ *)
val add_field : retroknowledge -> field -> entry -> retroknowledge
val mem : retroknowledge -> field -> bool
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index de2a890f..6c87ff57 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -59,6 +59,7 @@
etc.
*)
+open CErrors
open Util
open Names
open Declarations
@@ -209,13 +210,8 @@ let get_opaque_body env cbo =
(Opaqueproof.force_proof (Environ.opaque_tables env) opaque,
Opaqueproof.force_constraints (Environ.opaque_tables env) opaque)
-type private_constant = Entries.side_effect
type private_constants = Term_typing.side_effects
-type private_constant_role = Term_typing.side_effect_role =
- | Subproof
- | Schema of inductive * string
-
let empty_private_constants = Term_typing.empty_seff
let add_private = Term_typing.add_seff
let concat_private = Term_typing.concat_seff
@@ -224,44 +220,38 @@ let inline_private_constants_in_constr = Term_typing.inline_side_effects
let inline_private_constants_in_definition_entry = Term_typing.inline_entry_side_effects
let side_effects_of_private_constants = Term_typing.uniq_seff
+let make_eff env cst r =
+ let open Entries in
+ let cbo = Environ.lookup_constant cst env.env in
+ {
+ seff_constant = cst;
+ seff_body = cbo;
+ seff_env = get_opaque_body env.env cbo;
+ seff_role = r;
+ }
+
let private_con_of_con env c =
- let cbo = Environ.lookup_constant c env.env in
- { Entries.from_env = CEphemeron.create env.revstruct;
- Entries.eff = Entries.SEsubproof (c,cbo,get_opaque_body env.env cbo) }
+ let open Entries in
+ let eff = [make_eff env c Subproof] in
+ add_private env.revstruct eff empty_private_constants
let private_con_of_scheme ~kind env cl =
- { Entries.from_env = CEphemeron.create env.revstruct;
- Entries.eff = Entries.SEscheme(
- List.map (fun (i,c) ->
- let cbo = Environ.lookup_constant c env.env in
- i, c, cbo, get_opaque_body env.env cbo) cl,
- kind) }
+ let open Entries in
+ let eff = List.map (fun (i, c) -> make_eff env c (Schema (i, kind))) cl in
+ add_private env.revstruct eff empty_private_constants
let universes_of_private eff =
- let open Declarations in
- List.fold_left
- (fun acc { Entries.eff } ->
- match eff with
- | Entries.SEscheme (l,s) ->
- List.fold_left
- (fun acc (_,_,cb,c) ->
- let acc = match c with
- | `Nothing -> acc
- | `Opaque (_, ctx) -> ctx :: acc
- in
- match cb.const_universes with
- | Monomorphic_const ctx ->
- ctx :: acc
- | Polymorphic_const _ -> acc
- )
- acc l
- | Entries.SEsubproof (c, cb, e) ->
- match cb.const_universes with
- | Monomorphic_const ctx ->
- ctx :: acc
- | Polymorphic_const _ -> acc
- )
- [] (Term_typing.uniq_seff eff)
+ let open Entries in
+ let fold acc eff =
+ let acc = match eff.seff_env with
+ | `Nothing -> acc
+ | `Opaque (_, ctx) -> ctx :: acc
+ in
+ match eff.seff_body.const_universes with
+ | Monomorphic_const ctx -> ctx :: acc
+ | Polymorphic_const _ -> acc
+ in
+ List.fold_left fold [] (Term_typing.uniq_seff eff)
let env_of_safe_env senv = senv.env
let env_of_senv = env_of_safe_env
@@ -488,7 +478,7 @@ type global_declaration =
| GlobalRecipe of Cooking.recipe
type exported_private_constant =
- Constant.t * private_constant_role
+ Constant.t * Entries.side_effect_role
let add_constant_aux no_section senv (kn, cb) =
let l = pi3 (Constant.repr3 kn) in
@@ -896,9 +886,11 @@ let typing senv = Typeops.infer (env_of_senv senv)
(** {6 Retroknowledge / native compiler } *)
+[@@@ocaml.warning "-3"]
(** universal lifting, used for the "get" operations mostly *)
let retroknowledge f senv =
Environ.retroknowledge f (env_of_senv senv)
+[@@@ocaml.warning "+3"]
let register field value by_clause senv =
(* todo : value closed, by_clause safe, by_clause of the proper type*)
@@ -914,16 +906,12 @@ let register field value by_clause senv =
but it is meant to become a replacement for environ.register *)
let register_inline kn senv =
let open Environ in
- let open Pre_env in
if not (evaluable_constant kn senv.env) then
CErrors.user_err Pp.(str "Register inline: an evaluable constant is expected");
- let env = pre_env senv.env in
- let (cb,r) = Cmap_env.find kn env.env_globals.env_constants in
+ let env = senv.env in
+ let cb = lookup_constant kn env in
let cb = {cb with const_inline_code = true} in
- let new_constants = Cmap_env.add kn (cb,r) env.env_globals.env_constants in
- let new_globals = { env.env_globals with env_constants = new_constants } in
- let env = { env with env_globals = new_globals } in
- { senv with env = env_of_pre_env env }
+ let env = add_constant kn cb env in { senv with env}
let add_constraints c =
add_constraints
@@ -953,3 +941,125 @@ Would this be correct with respect to undo's and stuff ?
let set_strategy e k l = { e with env =
(Environ.set_oracle e.env
(Conv_oracle.set_strategy (Environ.oracle e.env) k l)) }
+
+(** Register retroknowledge hooks *)
+
+open Retroknowledge
+
+(* the Environ.register function synchronizes the proactive and reactive
+ retroknowledge. *)
+let dispatch =
+
+ (* subfunction used for static decompilation of int31 (after a vm_compute,
+ see pretyping/vnorm.ml for more information) *)
+ let constr_of_int31 =
+ let nth_digit_plus_one i n = (* calculates the nth (starting with 0)
+ digit of i and adds 1 to it
+ (nth_digit_plus_one 1 3 = 2) *)
+ if Int.equal (i land (1 lsl n)) 0 then
+ 1
+ else
+ 2
+ in
+ fun ind -> fun digit_ind -> fun tag ->
+ let array_of_int i =
+ Array.init 31 (fun n -> Constr.mkConstruct
+ (digit_ind, nth_digit_plus_one i (30-n)))
+ in
+ (* We check that no bit above 31 is set to one. This assertion used to
+ fail in the VM, and led to conversion tests failing at Qed. *)
+ assert (Int.equal (tag lsr 31) 0);
+ Constr.mkApp(Constr.mkConstruct(ind, 1), array_of_int tag)
+ in
+
+ (* subfunction which dispatches the compiling information of an
+ int31 operation which has a specific vm instruction (associates
+ it to the name of the coq definition in the reactive retroknowledge) *)
+ let int31_op n op prim kn =
+ { empty_reactive_info with
+ vm_compiling = Some (Clambda.compile_prim n op kn);
+ native_compiling = Some (Nativelambda.compile_prim prim (Univ.out_punivs kn));
+ }
+ in
+
+fun rk value field ->
+ (* subfunction which shortens the (very common) dispatch of operations *)
+ let int31_op_from_const n op prim =
+ match Constr.kind value with
+ | Constr.Const kn -> int31_op n op prim kn
+ | _ -> anomaly ~label:"Environ.register" (Pp.str "should be a constant.")
+ in
+ let int31_binop_from_const op prim = int31_op_from_const 2 op prim in
+ let int31_unop_from_const op prim = int31_op_from_const 1 op prim in
+ match field with
+ | KInt31 (grp, Int31Type) ->
+ let int31bit =
+ (* invariant : the type of bits is registered, otherwise the function
+ would raise Not_found. The invariant is enforced in safe_typing.ml *)
+ match field with
+ | KInt31 (grp, Int31Type) -> Retroknowledge.find rk (KInt31 (grp,Int31Bits))
+ | _ -> anomaly ~label:"Environ.register"
+ (Pp.str "add_int31_decompilation_from_type called with an abnormal field.")
+ in
+ let i31bit_type =
+ match Constr.kind int31bit with
+ | Constr.Ind (i31bit_type,_) -> i31bit_type
+ | _ -> anomaly ~label:"Environ.register"
+ (Pp.str "Int31Bits should be an inductive type.")
+ in
+ let int31_decompilation =
+ match Constr.kind value with
+ | Constr.Ind (i31t,_) ->
+ constr_of_int31 i31t i31bit_type
+ | _ -> anomaly ~label:"Environ.register"
+ (Pp.str "should be an inductive type.")
+ in
+ { empty_reactive_info with
+ vm_decompile_const = Some int31_decompilation;
+ vm_before_match = Some Clambda.int31_escape_before_match;
+ native_before_match = Some (Nativelambda.before_match_int31 i31bit_type);
+ }
+ | KInt31 (_, Int31Constructor) ->
+ { empty_reactive_info with
+ vm_constant_static = Some Clambda.compile_structured_int31;
+ vm_constant_dynamic = Some Clambda.dynamic_int31_compilation;
+ native_constant_static = Some Nativelambda.compile_static_int31;
+ native_constant_dynamic = Some Nativelambda.compile_dynamic_int31;
+ }
+ | KInt31 (_, Int31Plus) -> int31_binop_from_const Cbytecodes.Kaddint31
+ CPrimitives.Int31add
+ | KInt31 (_, Int31PlusC) -> int31_binop_from_const Cbytecodes.Kaddcint31
+ CPrimitives.Int31addc
+ | KInt31 (_, Int31PlusCarryC) -> int31_binop_from_const Cbytecodes.Kaddcarrycint31
+ CPrimitives.Int31addcarryc
+ | KInt31 (_, Int31Minus) -> int31_binop_from_const Cbytecodes.Ksubint31
+ CPrimitives.Int31sub
+ | KInt31 (_, Int31MinusC) -> int31_binop_from_const Cbytecodes.Ksubcint31
+ CPrimitives.Int31subc
+ | KInt31 (_, Int31MinusCarryC) -> int31_binop_from_const
+ Cbytecodes.Ksubcarrycint31 CPrimitives.Int31subcarryc
+ | KInt31 (_, Int31Times) -> int31_binop_from_const Cbytecodes.Kmulint31
+ CPrimitives.Int31mul
+ | KInt31 (_, Int31TimesC) -> int31_binop_from_const Cbytecodes.Kmulcint31
+ CPrimitives.Int31mulc
+ | KInt31 (_, Int31Div21) -> int31_op_from_const 3 Cbytecodes.Kdiv21int31
+ CPrimitives.Int31div21
+ | KInt31 (_, Int31Diveucl) -> int31_binop_from_const Cbytecodes.Kdivint31
+ CPrimitives.Int31diveucl
+ | KInt31 (_, Int31AddMulDiv) -> int31_op_from_const 3 Cbytecodes.Kaddmuldivint31
+ CPrimitives.Int31addmuldiv
+ | KInt31 (_, Int31Compare) -> int31_binop_from_const Cbytecodes.Kcompareint31
+ CPrimitives.Int31compare
+ | KInt31 (_, Int31Head0) -> int31_unop_from_const Cbytecodes.Khead0int31
+ CPrimitives.Int31head0
+ | KInt31 (_, Int31Tail0) -> int31_unop_from_const Cbytecodes.Ktail0int31
+ CPrimitives.Int31tail0
+ | KInt31 (_, Int31Lor) -> int31_binop_from_const Cbytecodes.Klorint31
+ CPrimitives.Int31lor
+ | KInt31 (_, Int31Land) -> int31_binop_from_const Cbytecodes.Klandint31
+ CPrimitives.Int31land
+ | KInt31 (_, Int31Lxor) -> int31_binop_from_const Cbytecodes.Klxorint31
+ CPrimitives.Int31lxor
+ | _ -> empty_reactive_info
+
+let _ = Hook.set Retroknowledge.dispatch_hook dispatch
diff --git a/kernel/safe_typing.mli b/kernel/safe_typing.mli
index 4078a909..502e2970 100644
--- a/kernel/safe_typing.mli
+++ b/kernel/safe_typing.mli
@@ -41,29 +41,20 @@ type 'a safe_transformer = safe_environment -> 'a * safe_environment
(** {6 Stm machinery } *)
-type private_constant
type private_constants
-type private_constant_role =
- | Subproof
- | Schema of inductive * string
-
val side_effects_of_private_constants :
- private_constants -> Entries.side_effect list
+ private_constants -> Entries.side_eff list
(** Return the list of individual side-effects in the order of their
creation. *)
val empty_private_constants : private_constants
-val add_private : private_constant -> private_constants -> private_constants
-(** Add a constant to a list of private constants. The former must be more
- recent than all constants appearing in the latter, i.e. one should not
- create a dependency cycle. *)
val concat_private : private_constants -> private_constants -> private_constants
(** [concat_private e1 e2] adds the constants of [e1] to [e2], i.e. constants in
[e1] must be more recent than those of [e2]. *)
-val private_con_of_con : safe_environment -> Constant.t -> private_constant
-val private_con_of_scheme : kind:string -> safe_environment -> (inductive * Constant.t) list -> private_constant
+val private_con_of_con : safe_environment -> Constant.t -> private_constants
+val private_con_of_scheme : kind:string -> safe_environment -> (inductive * Constant.t) list -> private_constants
val mk_pure_proof : Constr.constr -> private_constants Entries.proof_output
val inline_private_constants_in_constr :
@@ -105,7 +96,7 @@ type global_declaration =
| GlobalRecipe of Cooking.recipe
type exported_private_constant =
- Constant.t * private_constant_role
+ Constant.t * Entries.side_effect_role
val export_private_constants : in_section:bool ->
private_constants Entries.definition_entry ->
@@ -221,6 +212,7 @@ val delta_of_senv :
open Retroknowledge
val retroknowledge : (retroknowledge-> 'a) -> safe_environment -> 'a
+[@@ocaml.deprecated "Use the projection of Environ.env"]
val register :
field -> Retroknowledge.entry -> Constr.constr -> safe_transformer0
diff --git a/kernel/sorts.ml b/kernel/sorts.ml
index daeb90be..a7bb08f5 100644
--- a/kernel/sorts.ml
+++ b/kernel/sorts.ml
@@ -10,22 +10,21 @@
open Univ
-type contents = Pos | Null
-
type family = InProp | InSet | InType
type t =
- | Prop of contents (* proposition types *)
+ | Prop
+ | Set
| Type of Universe.t
-let prop = Prop Null
-let set = Prop Pos
+let prop = Prop
+let set = Set
let type1 = Type type1_univ
let univ_of_sort = function
| Type u -> u
- | Prop Pos -> Universe.type0
- | Prop Null -> Universe.type0m
+ | Set -> Universe.type0
+ | Prop -> Universe.type0m
let sort_of_univ u =
if is_type0m_univ u then prop
@@ -34,36 +33,34 @@ let sort_of_univ u =
let compare s1 s2 =
if s1 == s2 then 0 else
- match s1, s2 with
- | Prop c1, Prop c2 ->
- begin match c1, c2 with
- | Pos, Pos | Null, Null -> 0
- | Pos, Null -> -1
- | Null, Pos -> 1
- end
- | Type u1, Type u2 -> Universe.compare u1 u2
- | Prop _, Type _ -> -1
- | Type _, Prop _ -> 1
+ match s1, s2 with
+ | Prop, Prop -> 0
+ | Prop, _ -> -1
+ | Set, Prop -> 1
+ | Set, Set -> 0
+ | Set, _ -> -1
+ | Type u1, Type u2 -> Universe.compare u1 u2
+ | Type _, _ -> -1
let equal s1 s2 = Int.equal (compare s1 s2) 0
let is_prop = function
- | Prop Null -> true
+ | Prop -> true
| Type u when Universe.equal Universe.type0m u -> true
| _ -> false
let is_set = function
- | Prop Pos -> true
+ | Set -> true
| Type u when Universe.equal Universe.type0 u -> true
| _ -> false
let is_small = function
- | Prop _ -> true
+ | Prop | Set -> true
| Type u -> is_small_univ u
let family = function
- | Prop Null -> InProp
- | Prop Pos -> InSet
+ | Prop -> InProp
+ | Set -> InSet
| Type u when is_type0m_univ u -> InProp
| Type u when is_type0_univ u -> InSet
| Type _ -> InType
@@ -73,15 +70,11 @@ let family_equal = (==)
open Hashset.Combine
let hash = function
-| Prop p ->
- let h = match p with
- | Pos -> 0
- | Null -> 1
- in
- combinesmall 1 h
-| Type u ->
- let h = Univ.Universe.hash u in
- combinesmall 2 h
+ | Prop -> combinesmall 1 0
+ | Set -> combinesmall 1 1
+ | Type u ->
+ let h = Univ.Universe.hash u in
+ combinesmall 2 h
module List = struct
let mem = List.memq
@@ -101,7 +94,7 @@ module Hsorts =
if u' == u then c else Type u'
| s -> s
let eq s1 s2 = match (s1,s2) with
- | (Prop c1, Prop c2) -> c1 == c2
+ | Prop, Prop | Set, Set -> true
| (Type u1, Type u2) -> u1 == u2
|_ -> false
diff --git a/kernel/sorts.mli b/kernel/sorts.mli
index 1bbde260..cac6229b 100644
--- a/kernel/sorts.mli
+++ b/kernel/sorts.mli
@@ -10,13 +10,12 @@
(** {6 The sorts of CCI. } *)
-type contents = Pos | Null
-
type family = InProp | InSet | InType
type t =
-| Prop of contents (** Prop and Set *)
-| Type of Univ.Universe.t (** Type *)
+ | Prop
+ | Set
+ | Type of Univ.Universe.t
val set : t
val prop : t
diff --git a/kernel/subtyping.ml b/kernel/subtyping.ml
index 2e9a33a9..74042f9e 100644
--- a/kernel/subtyping.ml
+++ b/kernel/subtyping.ml
@@ -194,8 +194,9 @@ let check_inductive cst env mp1 l info1 mp2 mib2 spec2 subst1 subst2 reso1 reso2
else error NotEqualInductiveAliases
end;
(* we check that records and their field names are preserved. *)
- check (fun mib -> mib.mind_record <> None) (==) (fun x -> RecordFieldExpected x);
- if mib1.mind_record <> None then begin
+ (** FIXME: this check looks nonsense *)
+ check (fun mib -> mib.mind_record <> NotRecord) (==) (fun x -> RecordFieldExpected x);
+ if mib1.mind_record <> NotRecord then begin
let rec names_prod_letin t = match kind t with
| Prod(n,_,t) -> n::(names_prod_letin t)
| LetIn(n,_,_,t) -> n::(names_prod_letin t)
@@ -223,7 +224,7 @@ let check_inductive cst env mp1 l info1 mp2 mib2 spec2 subst1 subst2 reso1 reso2
cst
-let check_constant cst env mp1 l info1 cb2 spec2 subst1 subst2 =
+let check_constant cst env l info1 cb2 spec2 subst1 subst2 =
let error why = error_signature_mismatch l spec2 why in
let check_conv cst poly f = check_conv_error error cst poly f in
let check_type poly cst env t1 t2 =
@@ -291,7 +292,7 @@ and check_signatures cst env mp1 sig1 mp2 sig2 subst1 subst2 reso1 reso2=
let check_one_body cst (l,spec2) =
match spec2 with
| SFBconst cb2 ->
- check_constant cst env mp1 l (get_obj mp1 map1 l)
+ check_constant cst env l (get_obj mp1 map1 l)
cb2 spec2 subst1 subst2
| SFBmind mib2 ->
check_inductive cst env mp1 l (get_obj mp1 map1 l)
diff --git a/kernel/term.ml b/kernel/term.ml
index e1affb1c..4851a9c0 100644
--- a/kernel/term.ml
+++ b/kernel/term.ml
@@ -15,219 +15,14 @@ open Names
open Vars
open Constr
-(**********************************************************************)
-(** Redeclaration of types from module Constr *)
-(**********************************************************************)
-
-type contents = Sorts.contents = Pos | Null
+(* Deprecated *)
+type sorts_family = Sorts.family = InProp | InSet | InType
+[@@ocaml.deprecated "Alias for Sorts.family"]
type sorts = Sorts.t =
- | Prop of contents (** Prop and Set *)
+ | Prop | Set
| Type of Univ.Universe.t (** Type *)
-
-type sorts_family = Sorts.family = InProp | InSet | InType
-
-type constr = Constr.t
-(** Alias types, for compatibility. *)
-
-type types = Constr.t
-(** Same as [constr], for documentation purposes. *)
-
-type existential_key = Evar.t
-type existential = Constr.existential
-
-type metavariable = Constr.metavariable
-
-type case_style = Constr.case_style =
- LetStyle | IfStyle | LetPatternStyle | MatchStyle | RegularStyle
-
-type case_printing = Constr.case_printing =
- { ind_tags : bool list; cstr_tags : bool list array; style : case_style }
-
-type case_info = Constr.case_info =
- { ci_ind : inductive;
- ci_npar : int;
- ci_cstr_ndecls : int array;
- ci_cstr_nargs : int array;
- ci_pp_info : case_printing
- }
-
-type cast_kind = Constr.cast_kind =
- VMcast | NATIVEcast | DEFAULTcast | REVERTcast
-
-(********************************************************************)
-(* Constructions as implemented *)
-(********************************************************************)
-
-type rec_declaration = Constr.rec_declaration
-type fixpoint = Constr.fixpoint
-type cofixpoint = Constr.cofixpoint
-type 'constr pexistential = 'constr Constr.pexistential
-type ('constr, 'types) prec_declaration =
- ('constr, 'types) Constr.prec_declaration
-type ('constr, 'types) pfixpoint = ('constr, 'types) Constr.pfixpoint
-type ('constr, 'types) pcofixpoint = ('constr, 'types) Constr.pcofixpoint
-type 'a puniverses = 'a Univ.puniverses
-
-(** Simply type aliases *)
-type pconstant = Constant.t puniverses
-type pinductive = inductive puniverses
-type pconstructor = constructor puniverses
-
-type ('constr, 'types, 'sort, 'univs) kind_of_term =
- ('constr, 'types, 'sort, 'univs) Constr.kind_of_term =
- | Rel of int
- | Var of Id.t
- | Meta of metavariable
- | Evar of 'constr pexistential
- | Sort of 'sort
- | Cast of 'constr * cast_kind * 'types
- | Prod of Name.t * 'types * 'types
- | Lambda of Name.t * 'types * 'constr
- | LetIn of Name.t * 'constr * 'types * 'constr
- | App of 'constr * 'constr array
- | Const of (Constant.t * 'univs)
- | Ind of (inductive * 'univs)
- | Construct of (constructor * 'univs)
- | Case of case_info * 'constr * 'constr * 'constr array
- | Fix of ('constr, 'types) pfixpoint
- | CoFix of ('constr, 'types) pcofixpoint
- | Proj of Projection.t * 'constr
-
-type values = Vmvalues.values
-
-(**********************************************************************)
-(** Redeclaration of functions from module Constr *)
-(**********************************************************************)
-
-let set_sort = Sorts.set
-let prop_sort = Sorts.prop
-let type1_sort = Sorts.type1
-let sorts_ord = Sorts.compare
-let is_prop_sort = Sorts.is_prop
-let family_of_sort = Sorts.family
-let univ_of_sort = Sorts.univ_of_sort
-let sort_of_univ = Sorts.sort_of_univ
-
-(** {6 Term constructors. } *)
-
-let mkRel = Constr.mkRel
-let mkVar = Constr.mkVar
-let mkMeta = Constr.mkMeta
-let mkEvar = Constr.mkEvar
-let mkSort = Constr.mkSort
-let mkProp = Constr.mkProp
-let mkSet = Constr.mkSet
-let mkType = Constr.mkType
-let mkCast = Constr.mkCast
-let mkProd = Constr.mkProd
-let mkLambda = Constr.mkLambda
-let mkLetIn = Constr.mkLetIn
-let mkApp = Constr.mkApp
-let mkConst = Constr.mkConst
-let mkProj = Constr.mkProj
-let mkInd = Constr.mkInd
-let mkConstruct = Constr.mkConstruct
-let mkConstU = Constr.mkConstU
-let mkIndU = Constr.mkIndU
-let mkConstructU = Constr.mkConstructU
-let mkConstructUi = Constr.mkConstructUi
-let mkCase = Constr.mkCase
-let mkFix = Constr.mkFix
-let mkCoFix = Constr.mkCoFix
-
-(**********************************************************************)
-(** Aliases of functions from module Constr *)
-(**********************************************************************)
-
-let eq_constr = Constr.equal
-let eq_constr_univs = Constr.eq_constr_univs
-let leq_constr_univs = Constr.leq_constr_univs
-let eq_constr_nounivs = Constr.eq_constr_nounivs
-
-let kind_of_term = Constr.kind
-let compare = Constr.compare
-let constr_ord = compare
-let fold_constr = Constr.fold
-let map_puniverses = Constr.map_puniverses
-let map_constr = Constr.map
-let map_constr_with_binders = Constr.map_with_binders
-let iter_constr = Constr.iter
-let iter_constr_with_binders = Constr.iter_with_binders
-let compare_constr = Constr.compare_head
-let hash_constr = Constr.hash
-let hcons_sorts = Sorts.hcons
-let hcons_constr = Constr.hcons
-let hcons_types = Constr.hcons
-
-(**********************************************************************)
-(** HERE BEGINS THE INTERESTING STUFF *)
-(**********************************************************************)
-
-(**********************************************************************)
-(* Non primitive term destructors *)
-(**********************************************************************)
-
-exception DestKO = DestKO
-(* Destructs a de Bruijn index *)
-let destRel = destRel
-let destMeta = destRel
-let isMeta = isMeta
-let destVar = destVar
-let isSort = isSort
-let destSort = destSort
-let isprop = isprop
-let is_Prop = is_Prop
-let is_Set = is_Set
-let is_Type = is_Type
-let is_small = is_small
-let iskind = iskind
-let isEvar = isEvar
-let isEvar_or_Meta = isEvar_or_Meta
-let destCast = destCast
-let isCast = isCast
-let isRel = isRel
-let isRelN = isRelN
-let isVar = isVar
-let isVarId = isVarId
-let isInd = isInd
-let destProd = destProd
-let isProd = isProd
-let destLambda = destLambda
-let isLambda = isLambda
-let destLetIn = destLetIn
-let isLetIn = isLetIn
-let destApp = destApp
-let destApplication = destApp
-let isApp = isApp
-let destConst = destConst
-let isConst = isConst
-let destEvar = destEvar
-let destInd = destInd
-let destConstruct = destConstruct
-let isConstruct = isConstruct
-let destCase = destCase
-let isCase = isCase
-let isProj = isProj
-let destProj = destProj
-let destFix = destFix
-let isFix = isFix
-let destCoFix = destCoFix
-let isCoFix = isCoFix
-
-(******************************************************************)
-(* Flattening and unflattening of embedded applications and casts *)
-(******************************************************************)
-
-let decompose_app c =
- match kind_of_term c with
- | App (f,cl) -> (f, Array.to_list cl)
- | _ -> (c,[])
-
-let decompose_appvect c =
- match kind_of_term c with
- | App (f,cl) -> (f, cl)
- | _ -> (c,[||])
+[@@ocaml.deprecated "Alias for Sorts.t"]
(****************************************************************************)
(* Functions for dealing with constr terms *)
@@ -321,7 +116,7 @@ let rec to_lambda n prod =
if Int.equal n 0 then
prod
else
- match kind_of_term prod with
+ match kind prod with
| Prod (na,ty,bd) -> mkLambda (na,ty,to_lambda (n-1) bd)
| Cast (c,_,_) -> to_lambda n c
| _ -> user_err ~hdr:"to_lambda" (mt ())
@@ -330,7 +125,7 @@ let rec to_prod n lam =
if Int.equal n 0 then
lam
else
- match kind_of_term lam with
+ match kind lam with
| Lambda (na,ty,bd) -> mkProd (na,ty,to_prod (n-1) bd)
| Cast (c,_,_) -> to_prod n c
| _ -> user_err ~hdr:"to_prod" (mt ())
@@ -342,7 +137,7 @@ let it_mkLambda_or_LetIn = List.fold_left (fun c d -> mkLambda_or_LetIn d c)
let lambda_applist c l =
let rec app subst c l =
- match kind_of_term c, l with
+ match kind c, l with
| Lambda(_,_,c), arg::l -> app (arg::subst) c l
| _, [] -> substl subst c
| _ -> anomaly (Pp.str "Not enough lambda's.") in
@@ -355,7 +150,7 @@ let lambda_applist_assum n c l =
if Int.equal n 0 then
if l == [] then substl subst t
else anomaly (Pp.str "Too many arguments.")
- else match kind_of_term t, l with
+ else match kind t, l with
| Lambda(_,_,c), arg::l -> app (n-1) (arg::subst) c l
| LetIn(_,b,_,c), _ -> app (n-1) (substl subst b::subst) c l
| _, [] -> anomaly (Pp.str "Not enough arguments.")
@@ -367,7 +162,7 @@ let lambda_appvect_assum n c v = lambda_applist_assum n c (Array.to_list v)
(* prod_applist T [ a1 ; ... ; an ] -> (T a1 ... an) *)
let prod_applist c l =
let rec app subst c l =
- match kind_of_term c, l with
+ match kind c, l with
| Prod(_,_,c), arg::l -> app (arg::subst) c l
| _, [] -> substl subst c
| _ -> anomaly (Pp.str "Not enough prod's.") in
@@ -381,7 +176,7 @@ let prod_applist_assum n c l =
if Int.equal n 0 then
if l == [] then substl subst t
else anomaly (Pp.str "Too many arguments.")
- else match kind_of_term t, l with
+ else match kind t, l with
| Prod(_,_,c), arg::l -> app (n-1) (arg::subst) c l
| LetIn(_,b,_,c), _ -> app (n-1) (substl subst b::subst) c l
| _, [] -> anomaly (Pp.str "Not enough arguments.")
@@ -397,7 +192,7 @@ let prod_appvect_assum n c v = prod_applist_assum n c (Array.to_list v)
(* Transforms a product term (x1:T1)..(xn:Tn)T into the pair
([(xn,Tn);...;(x1,T1)],T), where T is not a product *)
let decompose_prod =
- let rec prodec_rec l c = match kind_of_term c with
+ let rec prodec_rec l c = match kind c with
| Prod (x,t,c) -> prodec_rec ((x,t)::l) c
| Cast (c,_,_) -> prodec_rec l c
| _ -> l,c
@@ -407,7 +202,7 @@ let decompose_prod =
(* Transforms a lambda term [x1:T1]..[xn:Tn]T into the pair
([(xn,Tn);...;(x1,T1)],T), where T is not a lambda *)
let decompose_lam =
- let rec lamdec_rec l c = match kind_of_term c with
+ let rec lamdec_rec l c = match kind c with
| Lambda (x,t,c) -> lamdec_rec ((x,t)::l) c
| Cast (c,_,_) -> lamdec_rec l c
| _ -> l,c
@@ -420,7 +215,7 @@ let decompose_prod_n n =
if n < 0 then user_err (str "decompose_prod_n: integer parameter must be positive");
let rec prodec_rec l n c =
if Int.equal n 0 then l,c
- else match kind_of_term c with
+ else match kind c with
| Prod (x,t,c) -> prodec_rec ((x,t)::l) (n-1) c
| Cast (c,_,_) -> prodec_rec l n c
| _ -> user_err (str "decompose_prod_n: not enough products")
@@ -433,7 +228,7 @@ let decompose_lam_n n =
if n < 0 then user_err (str "decompose_lam_n: integer parameter must be positive");
let rec lamdec_rec l n c =
if Int.equal n 0 then l,c
- else match kind_of_term c with
+ else match kind c with
| Lambda (x,t,c) -> lamdec_rec ((x,t)::l) (n-1) c
| Cast (c,_,_) -> lamdec_rec l n c
| _ -> user_err (str "decompose_lam_n: not enough abstractions")
@@ -445,7 +240,7 @@ let decompose_lam_n n =
let decompose_prod_assum =
let open Context.Rel.Declaration in
let rec prodec_rec l c =
- match kind_of_term c with
+ match kind c with
| Prod (x,t,c) -> prodec_rec (Context.Rel.add (LocalAssum (x,t)) l) c
| LetIn (x,b,t,c) -> prodec_rec (Context.Rel.add (LocalDef (x,b,t)) l) c
| Cast (c,_,_) -> prodec_rec l c
@@ -458,7 +253,7 @@ let decompose_prod_assum =
let decompose_lam_assum =
let rec lamdec_rec l c =
let open Context.Rel.Declaration in
- match kind_of_term c with
+ match kind c with
| Lambda (x,t,c) -> lamdec_rec (Context.Rel.add (LocalAssum (x,t)) l) c
| LetIn (x,b,t,c) -> lamdec_rec (Context.Rel.add (LocalDef (x,b,t)) l) c
| Cast (c,_,_) -> lamdec_rec l c
@@ -477,7 +272,7 @@ let decompose_prod_n_assum n =
if Int.equal n 0 then l,c
else
let open Context.Rel.Declaration in
- match kind_of_term c with
+ match kind c with
| Prod (x,t,c) -> prodec_rec (Context.Rel.add (LocalAssum (x,t)) l) (n-1) c
| LetIn (x,b,t,c) -> prodec_rec (Context.Rel.add (LocalDef (x,b,t)) l) (n-1) c
| Cast (c,_,_) -> prodec_rec l n c
@@ -498,7 +293,7 @@ let decompose_lam_n_assum n =
if Int.equal n 0 then l,c
else
let open Context.Rel.Declaration in
- match kind_of_term c with
+ match kind c with
| Lambda (x,t,c) -> lamdec_rec (Context.Rel.add (LocalAssum (x,t)) l) (n-1) c
| LetIn (x,b,t,c) -> lamdec_rec (Context.Rel.add (LocalDef (x,b,t)) l) n c
| Cast (c,_,_) -> lamdec_rec l n c
@@ -514,7 +309,7 @@ let decompose_lam_n_decls n =
if Int.equal n 0 then l,c
else
let open Context.Rel.Declaration in
- match kind_of_term c with
+ match kind c with
| Lambda (x,t,c) -> lamdec_rec (Context.Rel.add (LocalAssum (x,t)) l) (n-1) c
| LetIn (x,b,t,c) -> lamdec_rec (Context.Rel.add (LocalDef (x,b,t)) l) (n-1) c
| Cast (c,_,_) -> lamdec_rec l n c
@@ -541,12 +336,12 @@ let strip_lam_n n t = snd (decompose_lam_n n t)
Such a term can canonically be seen as the pair of a context of types
and of a sort *)
-type arity = Context.Rel.t * sorts
+type arity = Constr.rel_context * Sorts.t
let destArity =
let open Context.Rel.Declaration in
let rec prodec_rec l c =
- match kind_of_term c with
+ match kind c with
| Prod (x,t,c) -> prodec_rec (LocalAssum (x,t) :: l) c
| LetIn (x,b,t,c) -> prodec_rec (LocalDef (x,b,t) :: l) c
| Cast (c,_,_) -> prodec_rec l c
@@ -558,7 +353,7 @@ let destArity =
let mkArity (sign,s) = it_mkProd_or_LetIn (mkSort s) sign
let rec isArity c =
- match kind_of_term c with
+ match kind c with
| Prod (_,_,c) -> isArity c
| LetIn (_,b,_,c) -> isArity (subst1 b c)
| Cast (c,_,_) -> isArity c
@@ -569,13 +364,13 @@ let rec isArity c =
(* Experimental, used in Presburger contrib *)
type ('constr, 'types) kind_of_type =
- | SortType of sorts
+ | SortType of Sorts.t
| CastType of 'types * 'types
| ProdType of Name.t * 'types * 'types
| LetInType of Name.t * 'constr * 'types * 'types
| AtomicType of 'constr * 'constr array
-let kind_of_type t = match kind_of_term t with
+let kind_of_type t = match kind t with
| Sort s -> SortType s
| Cast (c,_,t) -> CastType (c, t)
| Prod (na,t,c) -> ProdType (na, t, c)
diff --git a/kernel/term.mli b/kernel/term.mli
index ee84dcb2..181d714e 100644
--- a/kernel/term.mli
+++ b/kernel/term.mli
@@ -11,166 +11,6 @@
open Names
open Constr
-(** {5 Redeclaration of types from module Constr and Sorts}
-
- This reexports constructors of inductive types defined in module [Constr],
- for compatibility purposes. Refer to this module for further info.
-
-*)
-
-exception DestKO
-[@@ocaml.deprecated "Alias for [Constr.DestKO]"]
-
-(** {5 Simple term case analysis. } *)
-val isRel : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isRel]"]
-val isRelN : int -> constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isRelN]"]
-val isVar : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isVar]"]
-val isVarId : Id.t -> constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isVarId]"]
-val isInd : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isInd]"]
-val isEvar : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isEvar]"]
-val isMeta : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isMeta]"]
-val isEvar_or_Meta : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isEvar_or_Meta]"]
-val isSort : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isSort]"]
-val isCast : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isCast]"]
-val isApp : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isApp]"]
-val isLambda : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isLambda]"]
-val isLetIn : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isletIn]"]
-val isProd : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isProp]"]
-val isConst : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isConst]"]
-val isConstruct : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isConstruct]"]
-val isFix : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isFix]"]
-val isCoFix : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isCoFix]"]
-val isCase : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isCase]"]
-val isProj : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isProj]"]
-
-val is_Prop : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.is_Prop]"]
-val is_Set : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.is_Set]"]
-val isprop : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.isprop]"]
-val is_Type : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.is_Type]"]
-val iskind : constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.is_kind]"]
-val is_small : Sorts.t -> bool
-[@@ocaml.deprecated "Alias for [Constr.is_small]"]
-
-
-(** {5 Term destructors } *)
-(** Destructor operations are partial functions and
- @raise DestKO if the term has not the expected form. *)
-
-(** Destructs a de Bruijn index *)
-val destRel : constr -> int
-[@@ocaml.deprecated "Alias for [Constr.destRel]"]
-
-(** Destructs an existential variable *)
-val destMeta : constr -> metavariable
-[@@ocaml.deprecated "Alias for [Constr.destMeta]"]
-
-(** Destructs a variable *)
-val destVar : constr -> Id.t
-[@@ocaml.deprecated "Alias for [Constr.destVar]"]
-
-(** Destructs a sort. [is_Prop] recognizes the sort {% \textsf{%}Prop{% }%}, whether
- [isprop] recognizes both {% \textsf{%}Prop{% }%} and {% \textsf{%}Set{% }%}. *)
-val destSort : constr -> Sorts.t
-[@@ocaml.deprecated "Alias for [Constr.destSort]"]
-
-(** Destructs a casted term *)
-val destCast : constr -> constr * cast_kind * constr
-[@@ocaml.deprecated "Alias for [Constr.destCast]"]
-
-(** Destructs the product {% $ %}(x:t_1)t_2{% $ %} *)
-val destProd : types -> Name.t * types * types
-[@@ocaml.deprecated "Alias for [Constr.destProd]"]
-
-(** Destructs the abstraction {% $ %}[x:t_1]t_2{% $ %} *)
-val destLambda : constr -> Name.t * types * constr
-[@@ocaml.deprecated "Alias for [Constr.destLambda]"]
-
-(** Destructs the let {% $ %}[x:=b:t_1]t_2{% $ %} *)
-val destLetIn : constr -> Name.t * constr * types * constr
-[@@ocaml.deprecated "Alias for [Constr.destLetIn]"]
-
-(** Destructs an application *)
-val destApp : constr -> constr * constr array
-[@@ocaml.deprecated "Alias for [Constr.destApp]"]
-
-(** Obsolete synonym of destApp *)
-val destApplication : constr -> constr * constr array
-[@@ocaml.deprecated "Alias for [Constr.destApplication]"]
-
-(** Decompose any term as an applicative term; the list of args can be empty *)
-val decompose_app : constr -> constr * constr list
-[@@ocaml.deprecated "Alias for [Constr.decompose_app]"]
-
-(** Same as [decompose_app], but returns an array. *)
-val decompose_appvect : constr -> constr * constr array
-[@@ocaml.deprecated "Alias for [Constr.decompose_appvect]"]
-
-(** Destructs a constant *)
-val destConst : constr -> Constant.t Univ.puniverses
-[@@ocaml.deprecated "Alias for [Constr.destConst]"]
-
-(** Destructs an existential variable *)
-val destEvar : constr -> existential
-[@@ocaml.deprecated "Alias for [Constr.destEvar]"]
-
-(** Destructs a (co)inductive type *)
-val destInd : constr -> inductive Univ.puniverses
-[@@ocaml.deprecated "Alias for [Constr.destInd]"]
-
-(** Destructs a constructor *)
-val destConstruct : constr -> constructor Univ.puniverses
-[@@ocaml.deprecated "Alias for [Constr.destConstruct]"]
-
-(** Destructs a [match c as x in I args return P with ... |
-Ci(...yij...) => ti | ... end] (or [let (..y1i..) := c as x in I args
-return P in t1], or [if c then t1 else t2])
-@return [(info,c,fun args x => P,[|...|fun yij => ti| ...|])]
-where [info] is pretty-printing information *)
-val destCase : constr -> case_info * constr * constr * constr array
-[@@ocaml.deprecated "Alias for [Constr.destCase]"]
-
-(** Destructs a projection *)
-val destProj : constr -> Projection.t * constr
-[@@ocaml.deprecated "Alias for [Constr.destProj]"]
-
-(** Destructs the {% $ %}i{% $ %}th function of the block
- [Fixpoint f{_ 1} ctx{_ 1} = b{_ 1}
- with f{_ 2} ctx{_ 2} = b{_ 2}
- ...
- with f{_ n} ctx{_ n} = b{_ n}],
- where the length of the {% $ %}j{% $ %}th context is {% $ %}ij{% $ %}.
-*)
-val destFix : constr -> fixpoint
-[@@ocaml.deprecated "Alias for [Constr.destFix]"]
-
-val destCoFix : constr -> cofixpoint
-[@@ocaml.deprecated "Alias for [Constr.destCoFix]"]
-
(** {5 Derived constructors} *)
(** non-dependent product [t1 -> t2], an alias for
@@ -185,14 +25,14 @@ val mkNamedLetIn : Id.t -> constr -> types -> constr -> constr
val mkNamedProd : Id.t -> types -> types -> types
(** Constructs either [(x:t)c] or [[x=b:t]c] *)
-val mkProd_or_LetIn : Context.Rel.Declaration.t -> types -> types
-val mkProd_wo_LetIn : Context.Rel.Declaration.t -> types -> types
-val mkNamedProd_or_LetIn : Context.Named.Declaration.t -> types -> types
-val mkNamedProd_wo_LetIn : Context.Named.Declaration.t -> types -> types
+val mkProd_or_LetIn : Constr.rel_declaration -> types -> types
+val mkProd_wo_LetIn : Constr.rel_declaration -> types -> types
+val mkNamedProd_or_LetIn : Constr.named_declaration -> types -> types
+val mkNamedProd_wo_LetIn : Constr.named_declaration -> types -> types
(** Constructs either [[x:t]c] or [[x=b:t]c] *)
-val mkLambda_or_LetIn : Context.Rel.Declaration.t -> constr -> constr
-val mkNamedLambda_or_LetIn : Context.Named.Declaration.t -> constr -> constr
+val mkLambda_or_LetIn : Constr.rel_declaration -> constr -> constr
+val mkNamedLambda_or_LetIn : Constr.named_declaration -> constr -> constr
(** {5 Other term constructors. } *)
@@ -234,8 +74,8 @@ val to_lambda : int -> constr -> constr
where [l] is [fun (x_1:T_1)...(x_n:T_n) => T] *)
val to_prod : int -> constr -> constr
-val it_mkLambda_or_LetIn : constr -> Context.Rel.t -> constr
-val it_mkProd_or_LetIn : types -> Context.Rel.t -> types
+val it_mkLambda_or_LetIn : constr -> Constr.rel_context -> constr
+val it_mkProd_or_LetIn : types -> Constr.rel_context -> types
(** In [lambda_applist c args], [c] is supposed to have the form
[λΓ.c] with [Γ] without let-in; it returns [c] with the variables
@@ -286,29 +126,29 @@ val decompose_lam_n : int -> constr -> (Name.t * constr) list * constr
(** Extract the premisses and the conclusion of a term of the form
"(xi:Ti) ... (xj:=cj:Tj) ..., T" where T is not a product nor a let *)
-val decompose_prod_assum : types -> Context.Rel.t * types
+val decompose_prod_assum : types -> Constr.rel_context * types
(** Idem with lambda's and let's *)
-val decompose_lam_assum : constr -> Context.Rel.t * constr
+val decompose_lam_assum : constr -> Constr.rel_context * constr
(** Idem but extract the first [n] premisses, counting let-ins. *)
-val decompose_prod_n_assum : int -> types -> Context.Rel.t * types
+val decompose_prod_n_assum : int -> types -> Constr.rel_context * types
(** Idem for lambdas, _not_ counting let-ins *)
-val decompose_lam_n_assum : int -> constr -> Context.Rel.t * constr
+val decompose_lam_n_assum : int -> constr -> Constr.rel_context * constr
(** Idem, counting let-ins *)
-val decompose_lam_n_decls : int -> constr -> Context.Rel.t * constr
+val decompose_lam_n_decls : int -> constr -> Constr.rel_context * constr
(** Return the premisses/parameters of a type/term (let-in included) *)
-val prod_assum : types -> Context.Rel.t
-val lam_assum : constr -> Context.Rel.t
+val prod_assum : types -> Constr.rel_context
+val lam_assum : constr -> Constr.rel_context
(** Return the first n-th premisses/parameters of a type (let included and counted) *)
-val prod_n_assum : int -> types -> Context.Rel.t
+val prod_n_assum : int -> types -> Constr.rel_context
(** Return the first n-th premisses/parameters of a term (let included but not counted) *)
-val lam_n_assum : int -> constr -> Context.Rel.t
+val lam_n_assum : int -> constr -> Constr.rel_context
(** Remove the premisses/parameters of a type/term *)
val strip_prod : types -> types
@@ -327,7 +167,7 @@ val strip_lam_assum : constr -> constr
Such a term can canonically be seen as the pair of a context of types
and of a sort *)
-type arity = Context.Rel.t * Sorts.t
+type arity = Constr.rel_context * Sorts.t
(** Build an "arity" from its canonical form *)
val mkArity : arity -> types
@@ -349,242 +189,11 @@ type ('constr, 'types) kind_of_type =
val kind_of_type : types -> (constr, types) kind_of_type
-(** {5 Redeclaration of stuff from module [Sorts]} *)
-
-val set_sort : Sorts.t
-[@@ocaml.deprecated "Alias for Sorts.set"]
-
-val prop_sort : Sorts.t
-[@@ocaml.deprecated "Alias for Sorts.prop"]
-
-val type1_sort : Sorts.t
-[@@ocaml.deprecated "Alias for Sorts.type1"]
-
-val sorts_ord : Sorts.t -> Sorts.t -> int
-[@@ocaml.deprecated "Alias for Sorts.compare"]
-
-val is_prop_sort : Sorts.t -> bool
-[@@ocaml.deprecated "Alias for Sorts.is_prop"]
-
-val family_of_sort : Sorts.t -> Sorts.family
+(* Deprecated *)
+type sorts_family = Sorts.family = InProp | InSet | InType
[@@ocaml.deprecated "Alias for Sorts.family"]
-(** {5 Redeclaration of stuff from module [Constr]}
-
- See module [Constr] for further info. *)
-
-(** {6 Term constructors. } *)
-
-val mkRel : int -> constr
-[@@ocaml.deprecated "Alias for Constr.mkRel"]
-val mkVar : Id.t -> constr
-[@@ocaml.deprecated "Alias for Constr.mkVar"]
-val mkMeta : metavariable -> constr
-[@@ocaml.deprecated "Alias for Constr.mkMeta"]
-val mkEvar : existential -> constr
-[@@ocaml.deprecated "Alias for Constr.mkEvar"]
-val mkSort : Sorts.t -> types
-[@@ocaml.deprecated "Alias for Constr.mkSort"]
-val mkProp : types
-[@@ocaml.deprecated "Alias for Constr.mkProp"]
-val mkSet : types
-[@@ocaml.deprecated "Alias for Constr.mkSet"]
-val mkType : Univ.Universe.t -> types
-[@@ocaml.deprecated "Alias for Constr.mkType"]
-val mkCast : constr * cast_kind * constr -> constr
-[@@ocaml.deprecated "Alias for Constr"]
-val mkProd : Name.t * types * types -> types
-[@@ocaml.deprecated "Alias for Constr"]
-val mkLambda : Name.t * types * constr -> constr
-[@@ocaml.deprecated "Alias for Constr"]
-val mkLetIn : Name.t * constr * types * constr -> constr
-[@@ocaml.deprecated "Alias for Constr"]
-val mkApp : constr * constr array -> constr
-[@@ocaml.deprecated "Alias for Constr"]
-val mkConst : Constant.t -> constr
-[@@ocaml.deprecated "Alias for Constr"]
-val mkProj : Projection.t * constr -> constr
-[@@ocaml.deprecated "Alias for Constr"]
-val mkInd : inductive -> constr
-[@@ocaml.deprecated "Alias for Constr"]
-val mkConstruct : constructor -> constr
-[@@ocaml.deprecated "Alias for Constr"]
-val mkConstU : Constant.t Univ.puniverses -> constr
-[@@ocaml.deprecated "Alias for Constr"]
-val mkIndU : inductive Univ.puniverses -> constr
-[@@ocaml.deprecated "Alias for Constr"]
-val mkConstructU : constructor Univ.puniverses -> constr
-[@@ocaml.deprecated "Alias for Constr"]
-val mkConstructUi : (pinductive * int) -> constr
-[@@ocaml.deprecated "Alias for Constr"]
-val mkCase : case_info * constr * constr * constr array -> constr
-[@@ocaml.deprecated "Alias for Constr.mkCase"]
-val mkFix : fixpoint -> constr
-[@@ocaml.deprecated "Alias for Constr.mkFix"]
-val mkCoFix : cofixpoint -> constr
-[@@ocaml.deprecated "Alias for Constr.mkCoFix"]
-
-(** {6 Aliases} *)
-
-val eq_constr : constr -> constr -> bool
-[@@ocaml.deprecated "Alias for Constr.equal"]
-
-(** [eq_constr_univs u a b] is [true] if [a] equals [b] modulo alpha, casts,
- application grouping and the universe constraints in [u]. *)
-val eq_constr_univs : constr UGraph.check_function
-[@@ocaml.deprecated "Alias for Constr.eq_constr_univs"]
-
-(** [leq_constr_univs u a b] is [true] if [a] is convertible to [b] modulo
- alpha, casts, application grouping and the universe constraints in [u]. *)
-val leq_constr_univs : constr UGraph.check_function
-[@@ocaml.deprecated "Alias for Constr.leq_constr_univs"]
-
-(** [eq_constr_univs a b] [true, c] if [a] equals [b] modulo alpha, casts,
- application grouping and ignoring universe instances. *)
-val eq_constr_nounivs : constr -> constr -> bool
-[@@ocaml.deprecated "Alias for Constr.qe_constr_nounivs"]
-
-val kind_of_term : constr -> (constr, types, Sorts.t, Univ.Instance.t) kind_of_term
-[@@ocaml.deprecated "Alias for Constr.kind"]
-
-val compare : constr -> constr -> int
-[@@ocaml.deprecated "Alias for [Constr.compare]"]
-
-val constr_ord : constr -> constr -> int
-[@@ocaml.deprecated "Alias for [Term.compare]"]
-
-val fold_constr : ('a -> constr -> 'a) -> 'a -> constr -> 'a
-[@@ocaml.deprecated "Alias for [Constr.fold]"]
-
-val map_constr : (constr -> constr) -> constr -> constr
-[@@ocaml.deprecated "Alias for [Constr.map]"]
-
-val map_constr_with_binders :
- ('a -> 'a) -> ('a -> constr -> constr) -> 'a -> constr -> constr
-[@@ocaml.deprecated "Alias for [Constr.map_with_binders]"]
-
-val map_puniverses : ('a -> 'b) -> 'a Univ.puniverses -> 'b Univ.puniverses
-[@@ocaml.deprecated "Alias for [Constr.map_puniverses]"]
-val univ_of_sort : Sorts.t -> Univ.Universe.t
-[@@ocaml.deprecated "Alias for [Sorts.univ_of_sort]"]
-val sort_of_univ : Univ.Universe.t -> Sorts.t
-[@@ocaml.deprecated "Alias for [Sorts.sort_of_univ]"]
-
-val iter_constr : (constr -> unit) -> constr -> unit
-[@@ocaml.deprecated "Alias for [Constr.iter]"]
-
-val iter_constr_with_binders :
- ('a -> 'a) -> ('a -> constr -> unit) -> 'a -> constr -> unit
-[@@ocaml.deprecated "Alias for [Constr.iter_with_binders]"]
-
-val compare_constr : (int -> constr -> constr -> bool) -> int -> constr -> constr -> bool
-[@@ocaml.deprecated "Alias for [Constr.compare_head]"]
-
-type constr = Constr.constr
-[@@ocaml.deprecated "Alias for Constr.t"]
-
-(** Alias types, for compatibility. *)
-
-type types = Constr.types
-[@@ocaml.deprecated "Alias for Constr.types"]
-
-type contents = Sorts.contents = Pos | Null
-[@@ocaml.deprecated "Alias for Sorts.contents"]
-
type sorts = Sorts.t =
- | Prop of Sorts.contents (** Prop and Set *)
+ | Prop | Set
| Type of Univ.Universe.t (** Type *)
[@@ocaml.deprecated "Alias for Sorts.t"]
-
-type sorts_family = Sorts.family = InProp | InSet | InType
-[@@ocaml.deprecated "Alias for Sorts.family"]
-
-type 'a puniverses = 'a Univ.puniverses
-[@@ocaml.deprecated "Alias for Constr.puniverses"]
-
-(** Simply type aliases *)
-type pconstant = Constr.pconstant
-[@@ocaml.deprecated "Alias for Constr.pconstant"]
-type pinductive = Constr.pinductive
-[@@ocaml.deprecated "Alias for Constr.pinductive"]
-type pconstructor = Constr.pconstructor
-[@@ocaml.deprecated "Alias for Constr.pconstructor"]
-type existential_key = Evar.t
-[@@ocaml.deprecated "Alias for Evar.t"]
-type existential = Constr.existential
-[@@ocaml.deprecated "Alias for Constr.existential"]
-type metavariable = Constr.metavariable
-[@@ocaml.deprecated "Alias for Constr.metavariable"]
-
-type case_style = Constr.case_style =
- LetStyle | IfStyle | LetPatternStyle | MatchStyle | RegularStyle
-[@@ocaml.deprecated "Alias for Constr.case_style"]
-
-type case_printing = Constr.case_printing =
- { ind_tags : bool list; cstr_tags : bool list array; style : Constr.case_style }
-[@@ocaml.deprecated "Alias for Constr.case_printing"]
-
-type case_info = Constr.case_info =
- { ci_ind : inductive;
- ci_npar : int;
- ci_cstr_ndecls : int array;
- ci_cstr_nargs : int array;
- ci_pp_info : Constr.case_printing
- }
-[@@ocaml.deprecated "Alias for Constr.case_info"]
-
-type cast_kind = Constr.cast_kind =
- VMcast | NATIVEcast | DEFAULTcast | REVERTcast
-[@@ocaml.deprecated "Alias for Constr.cast_kind"]
-
-type rec_declaration = Constr.rec_declaration
-[@@ocaml.deprecated "Alias for Constr.rec_declaration"]
-type fixpoint = Constr.fixpoint
-[@@ocaml.deprecated "Alias for Constr.fixpoint"]
-type cofixpoint = Constr.cofixpoint
-[@@ocaml.deprecated "Alias for Constr.cofixpoint"]
-type 'constr pexistential = 'constr Constr.pexistential
-[@@ocaml.deprecated "Alias for Constr.pexistential"]
-type ('constr, 'types) prec_declaration =
- ('constr, 'types) Constr.prec_declaration
-[@@ocaml.deprecated "Alias for Constr.prec_declaration"]
-type ('constr, 'types) pfixpoint = ('constr, 'types) Constr.pfixpoint
-[@@ocaml.deprecated "Alias for Constr.pfixpoint"]
-type ('constr, 'types) pcofixpoint = ('constr, 'types) Constr.pcofixpoint
-[@@ocaml.deprecated "Alias for Constr.pcofixpoint"]
-
-type ('constr, 'types, 'sort, 'univs) kind_of_term =
- ('constr, 'types, 'sort, 'univs) Constr.kind_of_term =
- | Rel of int
- | Var of Id.t
- | Meta of Constr.metavariable
- | Evar of 'constr Constr.pexistential
- | Sort of 'sort
- | Cast of 'constr * Constr.cast_kind * 'types
- | Prod of Name.t * 'types * 'types
- | Lambda of Name.t * 'types * 'constr
- | LetIn of Name.t * 'constr * 'types * 'constr
- | App of 'constr * 'constr array
- | Const of (Constant.t * 'univs)
- | Ind of (inductive * 'univs)
- | Construct of (constructor * 'univs)
- | Case of Constr.case_info * 'constr * 'constr * 'constr array
- | Fix of ('constr, 'types) Constr.pfixpoint
- | CoFix of ('constr, 'types) Constr.pcofixpoint
- | Proj of Projection.t * 'constr
-[@@ocaml.deprecated "Alias for Constr.kind_of_term"]
-
-type values = Vmvalues.values
-[@@ocaml.deprecated "Alias for Vmvalues.values"]
-
-val hash_constr : Constr.constr -> int
-[@@ocaml.deprecated "Alias for Constr.hash"]
-
-val hcons_sorts : Sorts.t -> Sorts.t
-[@@ocaml.deprecated "Alias for [Sorts.hcons]"]
-
-val hcons_constr : Constr.constr -> Constr.constr
-[@@ocaml.deprecated "Alias for [Constr.hcons]"]
-
-val hcons_types : Constr.types -> Constr.types
-[@@ocaml.deprecated "Alias for [Constr.hcons]"]
diff --git a/kernel/term_typing.ml b/kernel/term_typing.ml
index e621a61c..2e84f625 100644
--- a/kernel/term_typing.ml
+++ b/kernel/term_typing.ml
@@ -27,16 +27,10 @@ module NamedDecl = Context.Named.Declaration
(* Insertion of constants and parameters in environment. *)
-let equal_eff e1 e2 =
- let open Entries in
- match e1, e2 with
- | { eff = SEsubproof (c1,_,_) }, { eff = SEsubproof (c2,_,_) } ->
- Names.Constant.equal c1 c2
- | { eff = SEscheme (cl1,_) }, { eff = SEscheme (cl2,_) } ->
- CList.for_all2eq
- (fun (_,c1,_,_) (_,c2,_,_) -> Names.Constant.equal c1 c2)
- cl1 cl2
- | _ -> false
+type side_effect = {
+ from_env : Declarations.structure_body CEphemeron.key;
+ eff : side_eff list;
+}
module SideEffects :
sig
@@ -48,17 +42,11 @@ sig
end =
struct
-let compare_seff e1 e2 = match e1, e2 with
-| SEsubproof (c1, _, _), SEsubproof (c2, _, _) -> Constant.CanOrd.compare c1 c2
-| SEscheme (cl1, _), SEscheme (cl2, _) ->
- let cmp (_, c1, _, _) (_, c2, _, _) = Constant.CanOrd.compare c1 c2 in
- CList.compare cmp cl1 cl2
-| SEsubproof _, SEscheme _ -> -1
-| SEscheme _, SEsubproof _ -> 1
-
module SeffOrd = struct
type t = side_effect
-let compare e1 e2 = compare_seff e1.eff e2.eff
+let compare e1 e2 =
+ let cmp e1 e2 = Constant.CanOrd.compare e1.seff_constant e2.seff_constant in
+ List.compare cmp e1.eff e2.eff
end
module SeffSet = Set.Make(SeffOrd)
@@ -83,10 +71,14 @@ type _ trust =
| SideEffects : structure_body -> side_effects trust
let uniq_seff_rev = SideEffects.repr
-let uniq_seff l = List.rev (SideEffects.repr l)
+let uniq_seff l =
+ let ans = List.rev (SideEffects.repr l) in
+ List.map_append (fun { eff } -> eff) ans
let empty_seff = SideEffects.empty
-let add_seff = SideEffects.add
+let add_seff mb eff effs =
+ let from_env = CEphemeron.create mb in
+ SideEffects.add { eff; from_env } effs
let concat_seff = SideEffects.concat
let mk_pure_proof c = (c, Univ.ContextSet.empty), empty_seff
@@ -94,11 +86,8 @@ let mk_pure_proof c = (c, Univ.ContextSet.empty), empty_seff
let inline_side_effects env body ctx side_eff =
(** First step: remove the constants that are still in the environment *)
let filter { eff = se; from_env = mb } =
- let cbl = match se with
- | SEsubproof (c, cb, b) -> [c, cb, b]
- | SEscheme (cl,_) ->
- List.map (fun (_, c, cb, b) -> c, cb, b) cl
- in
+ let map e = (e.seff_constant, e.seff_body, e.seff_env) in
+ let cbl = List.map map se in
let not_exists (c,_,_) =
try ignore(Environ.lookup_constant c env); false
with Not_found -> true in
@@ -114,12 +103,7 @@ let inline_side_effects env body ctx side_eff =
if List.is_empty side_eff then (body, ctx, sigs)
else
(** Second step: compute the lifts and substitutions to apply *)
- let cname c =
- let name = Constant.to_string c in
- let map c = if c == '.' || c == '#' then '_' else c in
- let name = String.map map name in
- Name (Id.of_string name)
- in
+ let cname c = Name (Label.to_id (Constant.label c)) in
let fold (subst, var, ctx, args) (c, cb, b) =
let (b, opaque) = match cb.const_body, b with
| Def b, _ -> (Mod_subst.force_constr b, false)
@@ -179,36 +163,36 @@ let rec is_nth_suffix n l suf =
| _ :: l -> is_nth_suffix (pred n) l suf
(* Given the list of signatures of side effects, checks if they match.
- * I.e. if they are ordered descendants of the current revstruct *)
+ * I.e. if they are ordered descendants of the current revstruct.
+ Returns the number of effects that can be trusted. *)
let check_signatures curmb sl =
- let is_direct_ancestor (sl, curmb) (mb, how_many) =
- match curmb with
- | None -> None, None
- | Some curmb ->
+ let is_direct_ancestor accu (mb, how_many) =
+ match accu with
+ | None -> None
+ | Some (n, curmb) ->
try
let mb = CEphemeron.get mb in
- match sl with
- | None -> sl, None
- | Some n ->
- if is_nth_suffix how_many mb curmb
- then Some (n + how_many), Some mb
- else None, None
- with CEphemeron.InvalidKey -> None, None in
- let sl, _ = List.fold_left is_direct_ancestor (Some 0,Some curmb) sl in
- sl
+ if is_nth_suffix how_many mb curmb
+ then Some (n + how_many, mb)
+ else None
+ with CEphemeron.InvalidKey -> None in
+ let sl = List.fold_left is_direct_ancestor (Some (0, curmb)) sl in
+ match sl with
+ | None -> 0
+ | Some (n, _) -> n
let skip_trusted_seff sl b e =
let rec aux sl b e acc =
let open Context.Rel.Declaration in
- match sl, kind b with
- | (None|Some 0), _ -> b, e, acc
- | Some sl, LetIn (n,c,ty,bo) ->
- aux (Some (sl-1)) bo
+ if Int.equal sl 0 then b, e, acc
+ else match kind b with
+ | LetIn (n,c,ty,bo) ->
+ aux (sl - 1) bo
(Environ.push_rel (LocalDef (n,c,ty)) e) (`Let(n,c,ty)::acc)
- | Some sl, App(hd,arg) ->
+ | App(hd,arg) ->
begin match kind hd with
| Lambda (n,ty,bo) ->
- aux (Some (sl-1)) bo
+ aux (sl - 1) bo
(Environ.push_rel (LocalAssum (n,ty)) e) (`Cut(n,ty,arg)::acc)
| _ -> assert false
end
@@ -250,7 +234,6 @@ let infer_declaration (type a) ~(trust : a trust) env (dcl : a constant_entry) =
{
Cooking.cook_body = Undef nl;
cook_type = t;
- cook_proj = None;
cook_universes = univs;
cook_inline = false;
cook_context = ctx;
@@ -268,6 +251,8 @@ let infer_declaration (type a) ~(trust : a trust) env (dcl : a constant_entry) =
let tyj = infer_type env typ in
let proofterm =
Future.chain body (fun ((body,uctx),side_eff) ->
+ (* don't redeclare universes which are declared for the type *)
+ let uctx = Univ.ContextSet.diff uctx univs in
let j, uctx = match trust with
| Pure ->
let env = push_context_set uctx env in
@@ -291,7 +276,6 @@ let infer_declaration (type a) ~(trust : a trust) env (dcl : a constant_entry) =
{
Cooking.cook_body = def;
cook_type = typ;
- cook_proj = None;
cook_universes = Monomorphic_const univs;
cook_inline = c.const_entry_inline_code;
cook_context = c.const_entry_secctx;
@@ -343,39 +327,11 @@ let infer_declaration (type a) ~(trust : a trust) env (dcl : a constant_entry) =
{
Cooking.cook_body = def;
cook_type = typ;
- cook_proj = None;
cook_universes = univs;
cook_inline = c.const_entry_inline_code;
cook_context = c.const_entry_secctx;
}
- | ProjectionEntry {proj_entry_ind = ind; proj_entry_arg = i} ->
- let mib, _ = Inductive.lookup_mind_specif env (ind,0) in
- let kn, pb =
- match mib.mind_record with
- | Some (Some (id, kns, pbs)) ->
- if i < Array.length pbs then
- kns.(i), pbs.(i)
- else assert false
- | _ -> assert false
- in
- let univs =
- match mib.mind_universes with
- | Monomorphic_ind ctx -> Monomorphic_const ctx
- | Polymorphic_ind auctx -> Polymorphic_const auctx
- | Cumulative_ind acumi ->
- Polymorphic_const (Univ.ACumulativityInfo.univ_context acumi)
- in
- let term, typ = pb.proj_eta in
- {
- Cooking.cook_body = Def (Mod_subst.from_val (Constr.hcons term));
- cook_type = typ;
- cook_proj = Some pb;
- cook_universes = univs;
- cook_inline = false;
- cook_context = None;
- }
-
let record_aux env s_ty s_bo =
let in_ty = keep_hyps env s_ty in
let v =
@@ -408,7 +364,7 @@ let build_constant_declaration kn env result =
str "Proof using " ++ declared_vars ++ fnl () ++
str "to" ++ fnl () ++
str "Proof using " ++ inferred_vars) in
- let sort evn l =
+ let sort l =
List.filter (fun decl ->
let id = NamedDecl.get_id decl in
List.exists (NamedDecl.get_id %> Names.Id.equal id) l)
@@ -441,7 +397,7 @@ let build_constant_declaration kn env result =
[], def (* Empty section context: no need to check *)
| Some declared ->
(* We use the declared set and chain a check of correctness *)
- sort env declared,
+ sort declared,
match def with
| Undef _ as x -> x (* nothing to check *)
| Def cs as x ->
@@ -458,35 +414,12 @@ let build_constant_declaration kn env result =
check declared inferred) lc) in
let univs = result.cook_universes in
let tps =
- let res =
- match result.cook_proj with
- | None -> compile_constant_body env univs def
- | Some pb ->
- (* The compilation of primitive projections is a bit tricky, because
- they refer to themselves (the body of p looks like fun c =>
- Proj(p,c)). We break the cycle by building an ad-hoc compilation
- environment. A cleaner solution would be that kernel projections are
- simply Proj(i,c) with i an int and c a constr, but we would have to
- get rid of the compatibility layer. *)
- let cb =
- { const_hyps = hyps;
- const_body = def;
- const_type = typ;
- const_proj = result.cook_proj;
- const_body_code = None;
- const_universes = univs;
- const_inline_code = result.cook_inline;
- const_typing_flags = Environ.typing_flags env;
- }
- in
- let env = add_constant kn cb env in
- compile_constant_body env univs def
- in Option.map Cemitcodes.from_val res
+ let res = Cbytegen.compile_constant_body ~fail_on_error:false env univs def in
+ Option.map Cemitcodes.from_val res
in
{ const_hyps = hyps;
const_body = def;
const_type = typ;
- const_proj = result.cook_proj;
const_body_code = tps;
const_universes = univs;
const_inline_code = result.cook_inline;
@@ -521,77 +454,74 @@ let constant_entry_of_side_effect cb u =
const_entry_inline_code = cb.const_inline_code }
;;
-let turn_direct (kn,cb,u,r as orig) =
- match cb.const_body, u with
- | OpaqueDef _, `Opaque (b,c) ->
- let pt = Future.from_val (b,c) in
- kn, { cb with const_body = OpaqueDef (Opaqueproof.create pt) }, u, r
- | _ -> orig
-;;
-
-type side_effect_role =
- | Subproof
- | Schema of inductive * string
+let turn_direct orig =
+ let cb = orig.seff_body in
+ if Declareops.is_opaque cb then
+ let p = match orig.seff_env with
+ | `Opaque (b, c) -> (b, c)
+ | _ -> assert false
+ in
+ let const_body = OpaqueDef (Opaqueproof.create (Future.from_val p)) in
+ let cb = { cb with const_body } in
+ { orig with seff_body = cb }
+ else orig
type exported_side_effect =
Constant.t * constant_body * side_effect_role
+let export_eff eff =
+ (eff.seff_constant, eff.seff_body, eff.seff_role)
+
let export_side_effects mb env c =
let { const_entry_body = body } = c in
let _, eff = Future.force body in
let ce = { c with
const_entry_body = Future.chain body
(fun (b_ctx, _) -> b_ctx, ()) } in
- let not_exists (c,_,_,_) =
- try ignore(Environ.lookup_constant c env); false
+ let not_exists e =
+ try ignore(Environ.lookup_constant e.seff_constant env); false
with Not_found -> true in
let aux (acc,sl) { eff = se; from_env = mb } =
- let cbl = match se with
- | SEsubproof (c,cb,b) -> [c,cb,b,Subproof]
- | SEscheme (cl,k) ->
- List.map (fun (i,c,cb,b) -> c,cb,b,Schema(i,k)) cl in
- let cbl = List.filter not_exists cbl in
- if cbl = [] then acc, sl
+ let cbl = List.filter not_exists se in
+ if List.is_empty cbl then acc, sl
else cbl :: acc, (mb,List.length cbl) :: sl in
let seff, signatures = List.fold_left aux ([],[]) (uniq_seff_rev eff) in
let trusted = check_signatures mb signatures in
- let push_seff env = function
- | kn, cb, `Nothing, _ ->
- begin
- let env = Environ.add_constant kn cb env in
- match cb.const_universes with
- | Monomorphic_const ctx ->
- Environ.push_context_set ~strict:true ctx env
- | Polymorphic_const _ -> env
- end
- | kn, cb, `Opaque(_, ctx), _ ->
- begin
- let env = Environ.add_constant kn cb env in
- match cb.const_universes with
- | Monomorphic_const cstctx ->
- let env = Environ.push_context_set ~strict:true cstctx env in
- Environ.push_context_set ~strict:true ctx env
- | Polymorphic_const _ -> env
- end
+ let push_seff env eff =
+ let { seff_constant = kn; seff_body = cb } = eff in
+ let env = Environ.add_constant kn cb env in
+ match cb.const_universes with
+ | Polymorphic_const _ -> env
+ | Monomorphic_const ctx ->
+ let ctx = match eff.seff_env with
+ | `Nothing -> ctx
+ | `Opaque(_, ctx') -> Univ.ContextSet.union ctx' ctx
+ in
+ Environ.push_context_set ~strict:true ctx env
in
let rec translate_seff sl seff acc env =
- match sl, seff with
- | _, [] -> List.rev acc, ce
- | (None | Some 0), cbs :: rest ->
+ match seff with
+ | [] -> List.rev acc, ce
+ | cbs :: rest ->
+ if Int.equal sl 0 then
let env, cbs =
- List.fold_left (fun (env,cbs) (kn, ocb, u, r) ->
+ List.fold_left (fun (env,cbs) eff ->
+ let { seff_constant = kn; seff_body = ocb; seff_env = u } = eff in
let ce = constant_entry_of_side_effect ocb u in
let cb = translate_constant Pure env kn ce in
- (push_seff env (kn, cb,`Nothing, Subproof),(kn,cb,r) :: cbs))
+ let eff = { eff with
+ seff_body = cb;
+ seff_env = `Nothing;
+ } in
+ (push_seff env eff, export_eff eff :: cbs))
(env,[]) cbs in
- translate_seff sl rest (cbs @ acc) env
- | Some sl, cbs :: rest ->
+ translate_seff 0 rest (cbs @ acc) env
+ else
let cbs_len = List.length cbs in
let cbs = List.map turn_direct cbs in
let env = List.fold_left push_seff env cbs in
- let ecbs = List.map (fun (kn,cb,u,r) ->
- kn, cb, r) cbs in
- translate_seff (Some (sl-cbs_len)) rest (ecbs @ acc) env
+ let ecbs = List.map export_eff cbs in
+ translate_seff (sl - cbs_len) rest (ecbs @ acc) env
in
translate_seff trusted seff [] env
;;
@@ -606,7 +536,7 @@ let translate_recipe env kn r =
be useless. It is detected by the dirpath of the constant being empty. *)
let (_, dir, _) = Constant.repr3 kn in
let hcons = DirPath.is_empty dir in
- build_constant_declaration kn env (Cooking.cook_constant ~hcons env r)
+ build_constant_declaration kn env (Cooking.cook_constant ~hcons r)
let translate_local_def env id centry =
let open Cooking in
diff --git a/kernel/term_typing.mli b/kernel/term_typing.mli
index 6a0ff072..b05e05e4 100644
--- a/kernel/term_typing.mli
+++ b/kernel/term_typing.mli
@@ -38,24 +38,18 @@ val inline_entry_side_effects :
yet type checked proof. *)
val empty_seff : side_effects
-val add_seff : side_effect -> side_effects -> side_effects
+val add_seff : Declarations.structure_body -> Entries.side_eff list -> side_effects -> side_effects
val concat_seff : side_effects -> side_effects -> side_effects
(** [concat_seff e1 e2] adds the side-effects of [e1] to [e2], i.e. effects in
[e1] must be more recent than those of [e2]. *)
-val uniq_seff : side_effects -> side_effect list
+val uniq_seff : side_effects -> side_eff list
(** Return the list of individual side-effects in the order of their
creation. *)
-val equal_eff : side_effect -> side_effect -> bool
-
val translate_constant :
'a trust -> env -> Constant.t -> 'a constant_entry ->
constant_body
-type side_effect_role =
- | Subproof
- | Schema of inductive * string
-
type exported_side_effect =
Constant.t * constant_body * side_effect_role
diff --git a/kernel/type_errors.ml b/kernel/type_errors.ml
index 1c323e3e..60293fe8 100644
--- a/kernel/type_errors.ml
+++ b/kernel/type_errors.ml
@@ -62,6 +62,7 @@ type ('constr, 'types) ptype_error =
| IllTypedRecBody of
int * Name.t array * ('constr, 'types) punsafe_judgment array * 'types array
| UnsatisfiedConstraints of Univ.Constraint.t
+ | UndeclaredUniverse of Univ.Level.t
type type_error = (constr, types) ptype_error
@@ -125,3 +126,6 @@ let error_elim_explain kp ki =
let error_unsatisfied_constraints env c =
raise (TypeError (env, UnsatisfiedConstraints c))
+
+let error_undeclared_universe env l =
+ raise (TypeError (env, UndeclaredUniverse l))
diff --git a/kernel/type_errors.mli b/kernel/type_errors.mli
index 20bf300a..9c6ef64b 100644
--- a/kernel/type_errors.mli
+++ b/kernel/type_errors.mli
@@ -63,6 +63,7 @@ type ('constr, 'types) ptype_error =
| IllTypedRecBody of
int * Name.t array * ('constr, 'types) punsafe_judgment array * 'types array
| UnsatisfiedConstraints of Univ.Constraint.t
+ | UndeclaredUniverse of Univ.Level.t
type type_error = (constr, types) ptype_error
@@ -108,3 +109,5 @@ val error_ill_typed_rec_body :
val error_elim_explain : Sorts.family -> Sorts.family -> arity_error
val error_unsatisfied_constraints : env -> Univ.Constraint.t -> 'a
+
+val error_undeclared_universe : env -> Univ.Level.t -> 'a
diff --git a/kernel/typeops.ml b/kernel/typeops.ml
index be4c0e1e..25c1cbff 100644
--- a/kernel/typeops.ml
+++ b/kernel/typeops.ml
@@ -69,7 +69,7 @@ let type_of_type u =
mkType uu
let type_of_sort = function
- | Prop c -> type1
+ | Prop | Set -> type1
| Type u -> type_of_type u
(*s Type of a de Bruijn index. *)
@@ -178,11 +178,11 @@ let type_of_apply env func funt argsv argstv =
let sort_of_product env domsort rangsort =
match (domsort, rangsort) with
(* Product rule (s,Prop,Prop) *)
- | (_, Prop Null) -> rangsort
+ | (_, Prop) -> rangsort
(* Product rule (Prop/Set,Set,Set) *)
- | (Prop _, Prop Pos) -> rangsort
+ | ((Prop | Set), Set) -> rangsort
(* Product rule (Type,Set,?) *)
- | (Type u1, Prop Pos) ->
+ | (Type u1, Set) ->
if is_impredicative_set env then
(* Rule is (Type,Set,Set) in the Set-impredicative calculus *)
rangsort
@@ -190,9 +190,9 @@ let sort_of_product env domsort rangsort =
(* Rule is (Type_i,Set,Type_i) in the Set-predicative calculus *)
Type (Universe.sup Universe.type0 u1)
(* Product rule (Prop,Type_i,Type_i) *)
- | (Prop Pos, Type u2) -> Type (Universe.sup Universe.type0 u2)
+ | (Set, Type u2) -> Type (Universe.sup Universe.type0 u2)
(* Product rule (Prop,Type_i,Type_i) *)
- | (Prop Null, Type _) -> rangsort
+ | (Prop, Type _) -> rangsort
(* Product rule (Type_i,Type_i,Type_i) *)
| (Type u1, Type u2) -> Type (Universe.sup u1 u2)
@@ -221,7 +221,7 @@ let check_cast env c ct k expected_type =
try
match k with
| VMcast ->
- vm_conv CUMUL env ct expected_type
+ Vconv.vm_conv CUMUL env ct expected_type
| DEFAULTcast ->
default_conv ~l2r:false CUMUL env ct expected_type
| REVERTcast ->
@@ -296,13 +296,13 @@ let type_of_case env ci p pt c ct lf lft =
rslty
let type_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 (make_judge c ct)
in
- assert(MutInd.equal pb.proj_ind (fst ind));
- let ty = Vars.subst_instance_constr u pb.Declarations.proj_type in
+ assert(eq_ind (Projection.inductive p) ind);
+ let ty = Vars.subst_instance_constr u pty in
substl (c :: CList.rev args) ty
@@ -431,7 +431,28 @@ and execute_recdef env (names,lar,vdef) i =
and execute_array env = Array.map (execute env)
(* Derived functions *)
+
+let universe_levels_of_constr env c =
+ let rec aux s c =
+ match kind c with
+ | Const (c, u) ->
+ LSet.fold LSet.add (Instance.levels u) s
+ | Ind ((mind,_), u) | Construct (((mind,_),_), u) ->
+ LSet.fold LSet.add (Instance.levels u) s
+ | 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
+
+let check_wellformed_universes env c =
+ let univs = universe_levels_of_constr env c in
+ try UGraph.check_declared_universes (universes env) univs
+ with UGraph.UndeclaredLevel u ->
+ error_undeclared_universe env u
+
let infer env constr =
+ let () = check_wellformed_universes env constr in
let t = execute env constr in
make_judge constr t
@@ -449,11 +470,13 @@ let type_judgment env {uj_val=c; uj_type=t} =
{utj_val = c; utj_type = s }
let infer_type env constr =
+ let () = check_wellformed_universes env constr in
let t = execute env constr in
let s = check_type env constr t in
{utj_val = constr; utj_type = s}
let infer_v env cv =
+ let () = Array.iter (check_wellformed_universes env) cv in
let jv = execute_array env cv in
make_judgev cv jv
@@ -461,9 +484,11 @@ let infer_v env cv =
let infer_local_decl env id = function
| Entries.LocalDefEntry c ->
+ let () = check_wellformed_universes env c in
let t = execute env c in
RelDecl.LocalDef (Name id, c, t)
| Entries.LocalAssumEntry c ->
+ let () = check_wellformed_universes env c in
let t = execute env c in
RelDecl.LocalAssum (Name id, check_assumption env c t)
@@ -481,10 +506,6 @@ let judge_of_prop = make_judge mkProp type1
let judge_of_set = make_judge mkSet type1
let judge_of_type u = make_judge (mkType u) (type_of_type u)
-let judge_of_prop_contents = function
- | Null -> judge_of_prop
- | Pos -> judge_of_set
-
let judge_of_relative env k = make_judge (mkRel k) (type_of_relative env k)
let judge_of_variable env x = make_judge (mkVar x) (type_of_variable env x)
@@ -528,13 +549,3 @@ let judge_of_case env ci pj cj lfj =
let lf, lft = dest_judgev lfj in
make_judge (mkCase (ci, (*nf_betaiota*) pj.uj_val, cj.uj_val, lft))
(type_of_case env ci pj.uj_val pj.uj_type cj.uj_val cj.uj_type lf lft)
-
-let type_of_projection_constant env (p,u) =
- let cst = Projection.constant p in
- let cb = lookup_constant cst env in
- match cb.const_proj with
- | Some pb ->
- if Declareops.constant_is_polymorphic cb then
- Vars.subst_instance_constr u pb.proj_type
- else pb.proj_type
- | None -> raise (Invalid_argument "type_of_projection: not a projection")
diff --git a/kernel/typeops.mli b/kernel/typeops.mli
index 85b2cfff..57acdfe4 100644
--- a/kernel/typeops.mli
+++ b/kernel/typeops.mli
@@ -28,7 +28,7 @@ val infer_v : env -> constr array -> unsafe_judgment array
val infer_type : env -> types -> unsafe_type_judgment
val infer_local_decls :
- env -> (Id.t * local_entry) list -> (env * Context.Rel.t)
+ env -> (Id.t * local_entry) list -> (env * Constr.rel_context)
(** {6 Basic operations of the typing machine. } *)
@@ -43,7 +43,6 @@ val type1 : types
val type_of_sort : Sorts.t -> types
val judge_of_prop : unsafe_judgment
val judge_of_set : unsafe_judgment
-val judge_of_prop_contents : Sorts.contents -> unsafe_judgment
val judge_of_type : Universe.t -> unsafe_judgment
(** {6 Type of a bound variable. } *)
@@ -100,9 +99,7 @@ val judge_of_case : env -> case_info
-> unsafe_judgment -> unsafe_judgment -> unsafe_judgment array
-> unsafe_judgment
-val type_of_projection_constant : env -> Projection.t puniverses -> types
-
val type_of_constant_in : env -> pconstant -> types
(** Check that hyps are included in env and fails with error otherwise *)
-val check_hyps_inclusion : env -> ('a -> constr) -> 'a -> Context.Named.t -> unit
+val check_hyps_inclusion : env -> ('a -> constr) -> 'a -> Constr.named_context -> unit
diff --git a/kernel/uGraph.ml b/kernel/uGraph.ml
index 5d5c4831..95d71965 100644
--- a/kernel/uGraph.ml
+++ b/kernel/uGraph.ml
@@ -21,7 +21,7 @@ open Univ
(* Revisions by Bruno Barras, Hugo Herbelin, Pierre Letouzey, Matthieu
Sozeau, Pierre-Marie Pédrot, Jacques-Henri Jourdan *)
-let error_inconsistency o u v (p:explanation option) =
+let error_inconsistency o u v p =
raise (UniverseInconsistency (o,Universe.make u,Universe.make v,p))
(* Universes are stratified by a partial ordering $\le$.
@@ -503,7 +503,7 @@ let insert_edge strict ucan vcan g =
let () = cleanup_universes g in
raise e
-let add_universe vlev strict g =
+let add_universe_gen vlev g =
try
let _arcv = UMap.find vlev g.entries in
raise AlreadyDeclared
@@ -520,8 +520,19 @@ let add_universe vlev strict g =
}
in
let entries = UMap.add vlev (Canonical v) g.entries in
- let g = { entries; index = g.index - 1; n_nodes = g.n_nodes + 1; n_edges = g.n_edges } in
- insert_edge strict (get_set_arc g) v g
+ { entries; index = g.index - 1; n_nodes = g.n_nodes + 1; n_edges = g.n_edges }, v
+
+let add_universe vlev strict g =
+ let g, v = add_universe_gen vlev g in
+ insert_edge strict (get_set_arc g) v g
+
+let add_universe_unconstrained vlev g =
+ fst (add_universe_gen vlev g)
+
+exception UndeclaredLevel of Univ.Level.t
+let check_declared_universes g us =
+ let check l = if not (UMap.mem l g.entries) then raise (UndeclaredLevel l) in
+ Univ.LSet.iter check us
exception Found_explanation of explanation
@@ -557,8 +568,7 @@ let get_explanation strict u v g =
else match traverse strict u with Some exp -> exp | None -> assert false
let get_explanation strict u v g =
- if !Flags.univ_print then Some (get_explanation strict u v g)
- else None
+ Some (lazy (get_explanation strict u v g))
(* To compare two nodes, we simply do a forward search.
We implement two improvements:
@@ -697,6 +707,9 @@ let enforce_univ_lt u v g =
error_inconsistency Lt u v (get_explanation false v u g)
let empty_universes =
+ { entries = UMap.empty; index = 0; n_nodes = 0; n_edges = 0 }
+
+let initial_universes =
let set_arc = Canonical {
univ = Level.set;
ltle = LMap.empty;
@@ -719,9 +732,6 @@ let empty_universes =
let empty = { entries; index = (-2); n_nodes = 2; n_edges = 0 } in
enforce_univ_lt Level.prop Level.set empty
-(* Prop = Set is forbidden here. *)
-let initial_universes = empty_universes
-
let is_initial_universes g = UMap.equal (==) g.entries initial_universes.entries
let enforce_constraint cst g =
@@ -807,18 +817,54 @@ let normalize_universes g =
g.entries g
let constraints_of_universes g =
+ let module UF = Unionfind.Make (LSet) (LMap) in
+ let uf = UF.create () in
let constraints_of u v acc =
match v with
| Canonical {univ=u; ltle} ->
UMap.fold (fun v strict acc->
let typ = if strict then Lt else Le in
Constraint.add (u,typ,v) acc) ltle acc
- | Equiv v -> Constraint.add (u,Eq,v) acc
+ | Equiv v -> UF.union u v uf; acc
in
- UMap.fold constraints_of g.entries Constraint.empty
-
-let constraints_of_universes g =
- constraints_of_universes (normalize_universes g)
+ let csts = UMap.fold constraints_of g.entries Constraint.empty in
+ csts, UF.partition uf
+
+(* domain g.entries = kept + removed *)
+let constraints_for ~kept g =
+ (* rmap: partial map from canonical universes to kept universes *)
+ let rmap, csts = LSet.fold (fun u (rmap,csts) ->
+ let arcu = repr g u in
+ if LSet.mem arcu.univ kept then
+ LMap.add arcu.univ arcu.univ rmap, enforce_eq_level u arcu.univ csts
+ else
+ match LMap.find arcu.univ rmap with
+ | v -> rmap, enforce_eq_level u v csts
+ | exception Not_found -> LMap.add arcu.univ u rmap, csts)
+ kept (LMap.empty,Constraint.empty)
+ in
+ let rec add_from u csts todo = match todo with
+ | [] -> csts
+ | (v,strict)::todo ->
+ let v = repr g v in
+ (match LMap.find v.univ rmap with
+ | v ->
+ let d = if strict then Lt else Le in
+ let csts = Constraint.add (u,d,v) csts in
+ add_from u csts todo
+ | exception Not_found ->
+ (* v is not equal to any kept universe *)
+ let todo = LMap.fold (fun v' strict' todo ->
+ (v',strict || strict') :: todo)
+ v.ltle todo
+ in
+ add_from u csts todo)
+ in
+ LSet.fold (fun u csts ->
+ let arc = repr g u in
+ LMap.fold (fun v strict csts -> add_from u csts [v,strict])
+ arc.ltle csts)
+ kept csts
(** [sort_universes g] builds a totally ordered universe graph. The
output graph should imply the input graph (and the implication
diff --git a/kernel/uGraph.mli b/kernel/uGraph.mli
index 0f078255..752bf762 100644
--- a/kernel/uGraph.mli
+++ b/kernel/uGraph.mli
@@ -52,17 +52,34 @@ exception AlreadyDeclared
val add_universe : Level.t -> bool -> t -> t
+(** Add a universe without (Prop,Set) <= u *)
+val add_universe_unconstrained : Level.t -> t -> t
+
+(** Check that the universe levels are declared. Otherwise
+ @raise UndeclaredLevel l for the first undeclared level found. *)
+exception UndeclaredLevel of Univ.Level.t
+
+val check_declared_universes : t -> Univ.LSet.t -> unit
+
(** {6 Pretty-printing of universes. } *)
val pr_universes : (Level.t -> Pp.t) -> t -> Pp.t
(** The empty graph of universes *)
val empty_universes : t
-[@@ocaml.deprecated "Use UGraph.initial_universes"]
val sort_universes : t -> t
-val constraints_of_universes : t -> Constraint.t
+(** [constraints_of_universes g] returns [csts] and [partition] where
+ [csts] are the non-Eq constraints and [partition] is the partition
+ of the universes into equivalence classes. *)
+val constraints_of_universes : t -> Constraint.t * LSet.t list
+
+(** [constraints_for ~kept g] returns the constraints about the
+ universes [kept] in [g] up to transitivity.
+
+ eg if [g] is [a <= b <= c] then [constraints_for ~kept:{a, c} g] is [a <= c]. *)
+val constraints_for : kept:LSet.t -> t -> Constraint.t
val check_subtype : AUContext.t check_function
(** [check_subtype univ ctx1 ctx2] checks whether [ctx2] is an instance of
diff --git a/kernel/univ.ml b/kernel/univ.ml
index 3158db52..311477da 100644
--- a/kernel/univ.ml
+++ b/kernel/univ.ml
@@ -456,10 +456,10 @@ struct
let super l =
if is_small l then type1
else
- List.smartmap (fun x -> Expr.successor x) l
+ List.Smart.map (fun x -> Expr.successor x) l
let addn n l =
- List.smartmap (fun x -> Expr.addn n x) l
+ List.Smart.map (fun x -> Expr.addn n x) l
let rec merge_univs l1 l2 =
match l1, l2 with
@@ -500,7 +500,7 @@ struct
let for_all = List.for_all
- let smartmap = List.smartmap
+ let smart_map = List.Smart.map
let map = List.map
end
@@ -541,11 +541,11 @@ let constraint_type_ord c1 c2 = match c1, c2 with
(* Universe inconsistency: error raised when trying to enforce a relation
that would create a cycle in the graph of universes. *)
-type univ_inconsistency = constraint_type * universe * universe * explanation option
+type univ_inconsistency = constraint_type * universe * universe * explanation Lazy.t option
exception UniverseInconsistency of univ_inconsistency
-let error_inconsistency o u v (p:explanation option) =
+let error_inconsistency o u v p =
raise (UniverseInconsistency (o,make u,make v,p))
(* Constraints and sets of constraints. *)
@@ -848,7 +848,7 @@ struct
let length a = Array.length a
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 of_array t'
let levels x = LSet.of_array x
@@ -885,11 +885,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'
@@ -1095,7 +1095,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'
@@ -1230,13 +1230,16 @@ let explain_universe_inconsistency prl (o,u,v,p) =
| Eq -> str"=" | Lt -> str"<" | Le -> str"<="
in
let reason = match p with
- | None | Some [] -> mt()
+ | None -> mt()
| Some p ->
- str " because" ++ spc() ++ pr_uni v ++
+ let p = Lazy.force p in
+ if p = [] then mt ()
+ else
+ str " because" ++ spc() ++ pr_uni v ++
prlist (fun (r,v) -> spc() ++ pr_rel r ++ str" " ++ pr_uni v)
- p ++
+ p ++
(if Universe.equal (snd (List.last p)) u then mt() else
- (spc() ++ str "= " ++ pr_uni u))
+ (spc() ++ str "= " ++ pr_uni u))
in
str "Cannot enforce" ++ spc() ++ pr_uni u ++ spc() ++
pr_rel o ++ spc() ++ pr_uni v ++ reason
diff --git a/kernel/univ.mli b/kernel/univ.mli
index aaed899b..b68bbdf3 100644
--- a/kernel/univ.mli
+++ b/kernel/univ.mli
@@ -205,7 +205,7 @@ val enforce_leq_level : Level.t constraint_function
Constraint.t...
*)
type explanation = (constraint_type * Universe.t) list
-type univ_inconsistency = constraint_type * Universe.t * Universe.t * explanation option
+type univ_inconsistency = constraint_type * Universe.t * Universe.t * explanation Lazy.t option
exception UniverseInconsistency of univ_inconsistency
diff --git a/kernel/vars.mli b/kernel/vars.mli
index a0c7ba4b..fdddbdb3 100644
--- a/kernel/vars.mli
+++ b/kernel/vars.mli
@@ -70,10 +70,10 @@ type substl = constr list
as if usable in [applist] while the substitution is
represented the other way round, i.e. ending with either [u₁] or
[c₁], as if usable for [substl]. *)
-val subst_of_rel_context_instance : Context.Rel.t -> constr list -> substl
+val subst_of_rel_context_instance : Constr.rel_context -> constr list -> substl
(** For compatibility: returns the substitution reversed *)
-val adjust_subst_to_rel_context : Context.Rel.t -> constr list -> constr list
+val adjust_subst_to_rel_context : Constr.rel_context -> constr list -> constr list
(** Take an index in an instance of a context and returns its index wrt to
the full context (e.g. 2 in [x:A;y:=b;z:C] is 3, i.e. a reference to z) *)
@@ -97,13 +97,13 @@ val subst1 : constr -> constr -> constr
accordingly indexes in [a₁],...,[an] and [c]. In terms of typing, if
Γ ⊢ a{_n}..a₁ : Δ and Γ, Δ, Γ', Ω ⊢ with |Γ'|=[k], then
Γ, Γ', [substnl_decl [a₁;...;an]] k Ω ⊢. *)
-val substnl_decl : substl -> int -> Context.Rel.Declaration.t -> Context.Rel.Declaration.t
+val substnl_decl : substl -> int -> Constr.rel_declaration -> Constr.rel_declaration
(** [substl_decl σ Ω] is a short-hand for [substnl_decl σ 0 Ω] *)
-val substl_decl : substl -> Context.Rel.Declaration.t -> Context.Rel.Declaration.t
+val substl_decl : substl -> Constr.rel_declaration -> Constr.rel_declaration
(** [subst1_decl a Ω] is a short-hand for [substnl_decl [a] 0 Ω] *)
-val subst1_decl : constr -> Context.Rel.Declaration.t -> Context.Rel.Declaration.t
+val subst1_decl : constr -> Constr.rel_declaration -> Constr.rel_declaration
(** [replace_vars k [(id₁,c₁);...;(idn,cn)] t] substitutes [Var idj] by
[cj] in [t]. *)
@@ -134,8 +134,8 @@ open Univ
(** Level substitutions for polymorphism. *)
val subst_univs_level_constr : universe_level_subst -> constr -> constr
-val subst_univs_level_context : Univ.universe_level_subst -> Context.Rel.t -> Context.Rel.t
+val subst_univs_level_context : Univ.universe_level_subst -> Constr.rel_context -> Constr.rel_context
(** Instance substitution for polymorphism. *)
val subst_instance_constr : Instance.t -> constr -> constr
-val subst_instance_context : Instance.t -> Context.Rel.t -> Context.Rel.t
+val subst_instance_context : Instance.t -> Constr.rel_context -> Constr.rel_context
diff --git a/kernel/vconv.ml b/kernel/vconv.ml
index 437de99e..d19bea51 100644
--- a/kernel/vconv.ml
+++ b/kernel/vconv.ml
@@ -6,9 +6,6 @@ open Vm
open Vmvalues
open Csymtable
-let val_of_constr env c =
- val_of_constr (pre_env env) c
-
(* Test la structure des piles *)
let compare_zipper z1 z2 =
@@ -142,7 +139,7 @@ and conv_stack env k stk1 stk2 cu =
conv_stack env k stk1 stk2 !rcu
else raise NotConvertible
| Zproj p1 :: stk1, Zproj p2 :: stk2 ->
- if Constant.equal p1 p2 then conv_stack env k stk1 stk2 cu
+ if Projection.Repr.equal p1 p2 then conv_stack env k stk1 stk2 cu
else raise NotConvertible
| [], _ | Zapp _ :: _, _ | Zfix _ :: _, _ | Zswitch _ :: _, _
| Zproj _ :: _, _ -> raise NotConvertible
@@ -185,8 +182,18 @@ and conv_arguments env ?from:(from=0) k args1 args2 cu =
!rcu
else raise NotConvertible
+let warn_bytecode_compiler_failed =
+ let open Pp in
+ CWarnings.create ~name:"bytecode-compiler-failed" ~category:"bytecode-compiler"
+ (fun () -> strbrk "Bytecode compiler failed, " ++
+ strbrk "falling back to standard conversion")
+
let vm_conv_gen cv_pb env univs t1 t2 =
- try
+ if not Coq_config.bytecode_compiler then
+ Reduction.generic_conv cv_pb ~l2r:false (fun _ -> None)
+ full_transparent_state env univs t1 t2
+ else
+ try
let v1 = val_of_constr env t1 in
let v2 = val_of_constr env t2 in
fst (conv_val env cv_pb (nb_rel env) v1 v2 univs)
@@ -204,7 +211,3 @@ let vm_conv cv_pb env t1 t2 =
if not b then
let univs = (univs, checked_universes) in
let _ = vm_conv_gen cv_pb env univs t1 t2 in ()
-
-let _ = if Coq_config.bytecode_compiler then Reduction.set_vm_conv vm_conv
-let _ = if Coq_config.bytecode_compiler then
- Nativeconv.set_vm_conv_gen { Nativeconv.vm_conv_gen = vm_conv_gen }
diff --git a/kernel/vconv.mli b/kernel/vconv.mli
index 620f6b5e..1a318489 100644
--- a/kernel/vconv.mli
+++ b/kernel/vconv.mli
@@ -9,7 +9,6 @@
(************************************************************************)
open Constr
-open Environ
open Reduction
(**********************************************************************
@@ -19,6 +18,3 @@ val vm_conv : conv_pb -> types kernel_conversion_function
(** A conversion function parametrized by a universe comparator. Used outside of
the kernel. *)
val vm_conv_gen : conv_pb -> (types, 'a) generic_conversion_function
-
-(** Precompute a VM value from a constr *)
-val val_of_constr : env -> constr -> Vmvalues.values
diff --git a/kernel/vm.ml b/kernel/vm.ml
index 14aeb732..9917e94a 100644
--- a/kernel/vm.ml
+++ b/kernel/vm.ml
@@ -8,7 +8,6 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Cbytecodes
open Vmvalues
external set_drawinstr : unit -> unit = "coq_set_drawinstr"
@@ -42,8 +41,11 @@ external push_vstack : vstack -> int -> unit = "coq_push_vstack"
(* interpreteur *)
-external interprete : tcode -> values -> vm_env -> int -> values =
- "coq_interprete_ml"
+external coq_interprete : tcode -> values -> atom array -> vm_global -> vm_env -> int -> values =
+ "coq_interprete_byte" "coq_interprete_ml"
+
+let interprete code v env k =
+ coq_interprete code v (get_atom_rel ()) (Csymtable.get_global_data ()) env k
(* Functions over arguments *)
@@ -184,6 +186,6 @@ let apply_whd k whd =
push_val v;
interprete (cofix_upd_code to_up) (cofix_upd_val to_up) (cofix_upd_env to_up) 0
| Vatom_stk(a,stk) ->
- apply_stack (val_of_atom a) stk v
+ apply_stack (val_of_atom a) stk v
| Vuniv_level lvl -> assert false
diff --git a/kernel/vmvalues.ml b/kernel/vmvalues.ml
index 0e0cb4e5..8edd49f7 100644
--- a/kernel/vmvalues.ml
+++ b/kernel/vmvalues.ml
@@ -9,8 +9,8 @@
(************************************************************************)
open Names
open Sorts
-open Cbytecodes
open Univ
+open Constr
(*******************************************)
(* Initalization of the abstract machine ***)
@@ -25,11 +25,124 @@ let _ = init_vm ()
(* Abstract data types and utility functions **********)
(******************************************************)
+(* The representation of values relies on this assertion *)
+let _ = assert (Int.equal Obj.first_non_constant_constructor_tag 0)
+
(* Values of the abstract machine *)
type values
+type structured_values = values
let val_of_obj v = ((Obj.obj v):values)
let crazy_val = (val_of_obj (Obj.repr 0))
+type tag = int
+
+let accu_tag = 0
+
+let type_atom_tag = 2
+let max_atom_tag = 2
+let proj_tag = 3
+let fix_app_tag = 4
+let switch_tag = 5
+let cofix_tag = 6
+let cofix_evaluated_tag = 7
+
+(** Structured constants are constants whose construction is done once. Their
+occurrences share the same value modulo kernel name substitutions (for functor
+application). Structured values have the additional property that no
+substitution will need to be performed, so their runtime value can directly be
+shared without reallocating a more structured representation. *)
+type structured_constant =
+ | Const_sort of Sorts.t
+ | Const_ind of inductive
+ | Const_b0 of tag
+ | Const_univ_level of Univ.Level.t
+ | Const_val of structured_values
+
+type reloc_table = (tag * int) array
+
+type annot_switch =
+ {ci : case_info; rtbl : reloc_table; tailcall : bool; max_stack_size : int}
+
+let rec eq_structured_values v1 v2 =
+ v1 == v2 ||
+ let o1 = Obj.repr v1 in
+ let o2 = Obj.repr v2 in
+ if Obj.is_int o1 && Obj.is_int o2 then o1 == o2
+ else
+ let t1 = Obj.tag o1 in
+ let t2 = Obj.tag o2 in
+ if Int.equal t1 t2 &&
+ Int.equal (Obj.size o1) (Obj.size o2)
+ then begin
+ assert (t1 <= Obj.last_non_constant_constructor_tag &&
+ t2 <= Obj.last_non_constant_constructor_tag);
+ let i = ref 0 in
+ while (!i < Obj.size o1 && eq_structured_values
+ (Obj.magic (Obj.field o1 !i) : structured_values)
+ (Obj.magic (Obj.field o2 !i) : structured_values)) do
+ incr i
+ done;
+ !i >= Obj.size o1
+ end
+ else false
+
+let hash_structured_values (v : structured_values) =
+ (* We may want a better hash function here *)
+ Hashtbl.hash v
+
+let eq_structured_constant c1 c2 = match c1, c2 with
+| Const_sort s1, Const_sort s2 -> Sorts.equal s1 s2
+| Const_sort _, _ -> false
+| Const_ind i1, Const_ind i2 -> eq_ind i1 i2
+| Const_ind _, _ -> false
+| Const_b0 t1, Const_b0 t2 -> Int.equal t1 t2
+| Const_b0 _, _ -> false
+| Const_univ_level l1 , Const_univ_level l2 -> Univ.Level.equal l1 l2
+| Const_univ_level _ , _ -> false
+| Const_val v1, Const_val v2 -> eq_structured_values v1 v2
+| Const_val v1, _ -> false
+
+let hash_structured_constant c =
+ let open Hashset.Combine in
+ match c with
+ | Const_sort s -> combinesmall 1 (Sorts.hash s)
+ | Const_ind i -> combinesmall 2 (ind_hash i)
+ | Const_b0 t -> combinesmall 3 (Int.hash t)
+ | Const_univ_level l -> combinesmall 4 (Univ.Level.hash l)
+ | Const_val v -> combinesmall 5 (hash_structured_values v)
+
+let eq_annot_switch asw1 asw2 =
+ let eq_ci ci1 ci2 =
+ eq_ind ci1.ci_ind ci2.ci_ind &&
+ Int.equal ci1.ci_npar ci2.ci_npar &&
+ CArray.equal Int.equal ci1.ci_cstr_ndecls ci2.ci_cstr_ndecls
+ in
+ let eq_rlc (i1, j1) (i2, j2) = Int.equal i1 i2 && Int.equal j1 j2 in
+ eq_ci asw1.ci asw2.ci &&
+ CArray.equal eq_rlc asw1.rtbl asw2.rtbl &&
+ (asw1.tailcall : bool) == asw2.tailcall
+
+let hash_annot_switch asw =
+ let open Hashset.Combine in
+ let h1 = Constr.case_info_hash asw.ci in
+ let h2 = Array.fold_left (fun h (t, i) -> combine3 h t i) 0 asw.rtbl in
+ let h3 = if asw.tailcall then 1 else 0 in
+ combine3 h1 h2 h3
+
+let pp_sort s =
+ let open Sorts in
+ match s with
+ | Prop -> Pp.str "Prop"
+ | Set -> Pp.str "Set"
+ | Type u -> Pp.(str "Type@{" ++ Univ.pr_uni u ++ str "}")
+
+let pp_struct_const = function
+ | Const_sort s -> pp_sort s
+ | Const_ind (mind, i) -> Pp.(MutInd.print mind ++ str"#" ++ int i)
+ | Const_b0 i -> Pp.int i
+ | Const_univ_level l -> Univ.Level.pr l
+ | Const_val _ -> Pp.str "(value)"
+
(* Abstract data *)
type vprod
type vfun
@@ -43,6 +156,7 @@ let fix_val v = (Obj.magic v : values)
let cofix_upd_val v = (Obj.magic v : values)
type vm_env
+type vm_global
let fun_env v = (Obj.magic v : vm_env)
let fix_env v = (Obj.magic v : vm_env)
let cofix_env v = (Obj.magic v : vm_env)
@@ -51,19 +165,24 @@ type vstack = values array
let fun_of_val v = (Obj.magic v : vfun)
+let vm_global (v : values array) = (Obj.magic v : vm_global)
+
(*******************************************)
(* Machine code *** ************************)
(*******************************************)
type tcode
+(** A block whose first field is a C-allocated VM bytecode, encoded as char*.
+ This is compatible with the representation of the Coq VM closures. *)
+
+type tcode_array
external mkAccuCode : int -> tcode = "coq_makeaccu"
external offset_tcode : tcode -> int -> tcode = "coq_offset_tcode"
-let tcode_of_obj v = ((Obj.obj v):tcode)
-let fun_code v = tcode_of_obj (Obj.field (Obj.repr v) 0)
-let fix_code v = fun_code v
-let cofix_upd_code v = fun_code v
+let fun_code v = (Obj.magic v : tcode)
+let fix_code = fun_code
+let cofix_upd_code = fun_code
type vswitch = {
@@ -144,7 +263,7 @@ type zipper =
| Zapp of arguments
| Zfix of vfix*arguments (* Possibly empty *)
| Zswitch of vswitch
- | Zproj of Constant.t (* name of the projection *)
+ | Zproj of Projection.Repr.t (* name of the projection *)
type stack = zipper list
@@ -252,6 +371,7 @@ external kind_of_closure : Obj.t -> int = "coq_kind_of_closure"
external is_accumulate : tcode -> bool = "coq_is_accumulate_code"
external int_tcode : tcode -> int -> int = "coq_int_tcode"
external accumulate : unit -> tcode = "accumulate_code"
+external set_bytecode_field : Obj.t -> int -> tcode -> unit = "coq_set_bytecode_field"
let accumulate = accumulate ()
let whd_val : values -> whd =
@@ -281,25 +401,26 @@ let whd_val : values -> whd =
let obj_of_atom : atom -> Obj.t =
fun a ->
let res = Obj.new_block accu_tag 2 in
- Obj.set_field res 0 (Obj.repr accumulate);
+ set_bytecode_field res 0 accumulate;
Obj.set_field res 1 (Obj.repr a);
res
(* obj_of_str_const : structured_constant -> Obj.t *)
-let rec obj_of_str_const str =
+let obj_of_str_const str =
match str with
| Const_sort s -> obj_of_atom (Asort s)
| Const_ind ind -> obj_of_atom (Aind ind)
- | Const_proj p -> Obj.repr p
| Const_b0 tag -> Obj.repr tag
- | Const_bn(tag, args) ->
- let len = Array.length args in
- let res = Obj.new_block tag len in
- for i = 0 to len - 1 do
- Obj.set_field res i (obj_of_str_const args.(i))
- done;
- res
| Const_univ_level l -> Obj.repr (Vuniv_level l)
+ | Const_val v -> Obj.repr v
+
+let val_of_block tag (args : structured_values array) =
+ let nargs = Array.length args in
+ let r = Obj.new_block tag nargs in
+ for i = 0 to nargs - 1 do
+ Obj.set_field r i (Obj.repr args.(i))
+ done;
+ (Obj.magic r : structured_values)
let val_of_obj o = ((Obj.obj o) : values)
@@ -307,6 +428,8 @@ let val_of_str_const str = val_of_obj (obj_of_str_const str)
let val_of_atom a = val_of_obj (obj_of_atom a)
+let val_of_int i = (Obj.magic i : values)
+
let atom_of_proj kn v =
let r = Obj.new_block proj_tag 2 in
Obj.set_field r 0 (Obj.repr kn);
@@ -348,6 +471,7 @@ let val_of_constant c = val_of_idkey (ConstKey c)
let val_of_evar evk = val_of_idkey (EvarKey evk)
external val_of_annot_switch : annot_switch -> values = "%identity"
+external val_of_proj_name : Projection.Repr.t -> values = "%identity"
(*************************************************)
(** Operations manipulating data types ***********)
@@ -367,17 +491,20 @@ external closure_arity : vfun -> int = "coq_closure_arity"
external offset : Obj.t -> int = "coq_offset"
external offset_closure : Obj.t -> int -> Obj.t = "coq_offset_closure"
external offset_closure_fix : vfix -> int -> vm_env = "coq_offset_closure"
+external tcode_array : tcode_array -> tcode array = "coq_tcode_array"
let first o = (offset_closure o (offset o))
let first_fix (v:vfix) = (Obj.magic (first (Obj.repr v)) : vfix)
let last o = (Obj.field o (Obj.size o - 1))
-let fix_types (v:vfix) = (Obj.magic (last (Obj.repr v)) : tcode array)
-let cofix_types (v:vcofix) = (Obj.magic (last (Obj.repr v)) : tcode array)
+let fix_types (v:vfix) = tcode_array (Obj.magic (last (Obj.repr v)) : tcode_array)
+let cofix_types (v:vcofix) = tcode_array (Obj.magic (last (Obj.repr v)) : tcode_array)
let current_fix vf = - (offset (Obj.repr vf) / 2)
-let unsafe_fb_code fb i = tcode_of_obj (Obj.field (Obj.repr fb) (2 * i))
+let unsafe_fb_code fb i =
+ let off = (2 * i) * (Sys.word_size / 8) in
+ Obj.obj (Obj.add_offset (Obj.repr fb) (Int32.of_int off))
let unsafe_rec_arg fb i = int_tcode (unsafe_fb_code fb i) 1
@@ -407,13 +534,20 @@ let check_fix f1 f2 =
else false
else false
-external atom_rel : unit -> atom array = "get_coq_atom_tbl"
-external realloc_atom_rel : int -> unit = "realloc_coq_atom_tbl"
+let atom_rel : atom array ref =
+ let init i = Aid (RelKey i) in
+ ref (Array.init 40 init)
+
+let get_atom_rel () = !atom_rel
+
+let realloc_atom_rel n =
+ let n = min (2 * n + 0x100) Sys.max_array_length in
+ let init i = Aid (RelKey i) in
+ let ans = Array.init n init in
+ atom_rel := ans
let relaccu_tbl =
- let atom_rel = atom_rel() in
- let len = Array.length atom_rel in
- for i = 0 to len - 1 do atom_rel.(i) <- Aid (RelKey i) done;
+ let len = Array.length !atom_rel in
ref (Array.init len mkAccuCode)
let relaccu_code i =
@@ -422,9 +556,7 @@ let relaccu_code i =
else
begin
realloc_atom_rel i;
- let atom_rel = atom_rel () in
- let nl = Array.length atom_rel in
- for j = len to nl - 1 do atom_rel.(j) <- Aid(RelKey j) done;
+ let nl = Array.length !atom_rel in
relaccu_tbl :=
Array.init nl
(fun j -> if j < len then !relaccu_tbl.(j) else mkAccuCode j);
@@ -434,13 +566,12 @@ let relaccu_code i =
let mk_fix_body k ndef fb =
let e = Obj.dup (Obj.repr fb) in
for i = 0 to ndef - 1 do
- Obj.set_field e (2 * i) (Obj.repr (relaccu_code (k + i)))
+ set_bytecode_field e (2 * i) (relaccu_code (k + i))
done;
let fix_body i =
- let jump_grabrec c = offset_tcode c 2 in
- let c = jump_grabrec (unsafe_fb_code fb i) in
+ let c = offset_tcode (unsafe_fb_code fb i) 2 in
let res = Obj.new_block Obj.closure_tag 2 in
- Obj.set_field res 0 (Obj.repr c);
+ set_bytecode_field res 0 c;
Obj.set_field res 1 (offset_closure e (2*i));
((Obj.obj res) : vfun) in
Array.init ndef fix_body
@@ -478,7 +609,7 @@ let mk_cofix_body apply_varray k ndef vcf =
Obj.set_field e 0 c;
let atom = Obj.new_block cofix_tag 1 in
let self = Obj.new_block accu_tag 2 in
- Obj.set_field self 0 (Obj.repr accumulate);
+ set_bytecode_field self 0 accumulate;
Obj.set_field self 1 (Obj.repr atom);
apply_varray (Obj.obj e) [|Obj.obj self|] in
Array.init ndef cofix_body
@@ -500,10 +631,10 @@ let branch_arg k (tag,arity) =
if Int.equal arity 0 then ((Obj.magic tag):values)
else
let b, ofs =
- if tag < last_variant_tag then Obj.new_block tag arity, 0
+ if tag < Obj.last_non_constant_constructor_tag then Obj.new_block tag arity, 0
else
- let b = Obj.new_block last_variant_tag (arity+1) in
- Obj.set_field b 0 (Obj.repr (tag-last_variant_tag));
+ let b = Obj.new_block Obj.last_non_constant_constructor_tag (arity+1) in
+ Obj.set_field b 0 (Obj.repr (tag-Obj.last_non_constant_constructor_tag));
b,1 in
for i = ofs to ofs + arity - 1 do
Obj.set_field b i (Obj.repr (val_of_rel (k+i)))
@@ -539,4 +670,4 @@ and pr_zipper z =
| Zapp args -> str "Zapp(len = " ++ int (nargs args) ++ str ")"
| Zfix (f,args) -> str "Zfix(..., len=" ++ int (nargs args) ++ str ")"
| Zswitch s -> str "Zswitch(...)"
- | Zproj c -> str "Zproj(" ++ Constant.print c ++ str ")")
+ | Zproj c -> str "Zproj(" ++ Projection.Repr.print c ++ str ")")
diff --git a/kernel/vmvalues.mli b/kernel/vmvalues.mli
index c6e342a9..ae1d416e 100644
--- a/kernel/vmvalues.mli
+++ b/kernel/vmvalues.mli
@@ -9,12 +9,14 @@
(************************************************************************)
open Names
-open Cbytecodes
+open Constr
(** Values *)
type values
+type structured_values
type vm_env
+type vm_global
type vprod
type vfun
type vfix
@@ -24,6 +26,38 @@ type arguments
type vstack = values array
type to_update
+type tag = int
+
+val accu_tag : tag
+
+val type_atom_tag : tag
+val max_atom_tag : tag
+val proj_tag : tag
+val fix_app_tag : tag
+val switch_tag : tag
+val cofix_tag : tag
+val cofix_evaluated_tag : tag
+
+type structured_constant =
+ | Const_sort of Sorts.t
+ | Const_ind of inductive
+ | Const_b0 of tag
+ | Const_univ_level of Univ.Level.t
+ | Const_val of structured_values
+
+val pp_struct_const : structured_constant -> Pp.t
+
+type reloc_table = (tag * int) array
+
+type annot_switch =
+ {ci : case_info; rtbl : reloc_table; tailcall : bool; max_stack_size : int}
+
+val eq_structured_constant : structured_constant -> structured_constant -> bool
+val hash_structured_constant : structured_constant -> int
+
+val eq_annot_switch : annot_switch -> annot_switch -> bool
+val hash_annot_switch : annot_switch -> int
+
val fun_val : vfun -> values
val fix_val : vfix -> values
val cofix_upd_val : to_update -> values
@@ -33,6 +67,8 @@ val fix_env : vfix -> vm_env
val cofix_env : vcofix -> vm_env
val cofix_upd_env : to_update -> vm_env
+val vm_global : values array -> vm_global
+
(** Cast a value known to be a function, unsafe in general *)
val fun_of_val : values -> vfun
@@ -69,13 +105,16 @@ type atom =
| Aind of inductive
| Asort of Sorts.t
+val get_atom_rel : unit -> atom array
+(** Global table of rels *)
+
(** Zippers *)
type zipper =
| Zapp of arguments
| Zfix of vfix * arguments (** might be empty *)
| Zswitch of vswitch
- | Zproj of Constant.t (* name of the projection *)
+ | Zproj of Projection.Repr.t (* name of the projection *)
type stack = zipper list
@@ -102,10 +141,13 @@ val val_of_rel : int -> values
val val_of_named : Id.t -> values
val val_of_constant : Constant.t -> values
val val_of_evar : Evar.t -> values
-val val_of_proj : Constant.t -> values -> values
+val val_of_proj : Projection.Repr.t -> values -> values
val val_of_atom : atom -> values
+val val_of_int : int -> structured_values
+val val_of_block : tag -> structured_values array -> structured_values
external val_of_annot_switch : annot_switch -> values = "%identity"
+external val_of_proj_name : Projection.Repr.t -> values = "%identity"
(** Destructors *)
@@ -151,4 +193,4 @@ val bfield : vblock -> int -> values
(** Switch *)
val check_switch : vswitch -> vswitch -> bool
-val branch_arg : int -> Cbytecodes.tag * int -> values
+val branch_arg : int -> tag * int -> values
diff --git a/lib/cErrors.ml b/lib/cErrors.ml
index 97502211..811fcf40 100644
--- a/lib/cErrors.ml
+++ b/lib/cErrors.ml
@@ -47,8 +47,6 @@ exception AlreadyDeclared of Pp.t (* for already declared Schemes *)
let alreadydeclared pps = raise (AlreadyDeclared(pps))
exception Timeout
-exception Drop
-exception Quit
let handle_stack = ref []
@@ -126,7 +124,7 @@ end
let noncritical = function
| Sys.Break | Out_of_memory | Stack_overflow
| Assert_failure _ | Match_failure _ | Anomaly _
- | Timeout | Drop | Quit -> false
+ | Timeout -> false
| Invalid_argument "equal: functional value" -> false
| _ -> true
[@@@ocaml.warning "+52"]
diff --git a/lib/cErrors.mli b/lib/cErrors.mli
index ec34dd62..4e2fe762 100644
--- a/lib/cErrors.mli
+++ b/lib/cErrors.mli
@@ -53,8 +53,6 @@ val invalid_arg : ?loc:Loc.t -> string -> 'a
val todo : string -> unit
exception Timeout
-exception Drop
-exception Quit
(** [register_handler h] registers [h] as a handler.
When an expression is printed with [print e], it
diff --git a/lib/cWarnings.ml b/lib/cWarnings.ml
index fda25a0a..0cf989e4 100644
--- a/lib/cWarnings.ml
+++ b/lib/cWarnings.ml
@@ -120,7 +120,7 @@ let uniquize_flags_rev flags =
(** [normalize_flags] removes redundant warnings. Unknown warnings are kept
because they may be declared in a plugin that will be linked later. *)
-let normalize_flags ~silent warnings =
+let normalize_flags warnings =
let warnings = cut_before_all_rev warnings in
uniquize_flags_rev warnings
@@ -130,7 +130,7 @@ let normalize_flags_string s =
if is_none_keyword s then s
else
let flags = flags_of_string s in
- let flags = normalize_flags ~silent:false flags in
+ let flags = normalize_flags flags in
string_of_flags flags
let parse_warnings items =
@@ -146,7 +146,7 @@ let parse_flags s =
else begin
Flags.make_warn true;
let flags = flags_of_string s in
- let flags = normalize_flags ~silent:true flags in
+ let flags = normalize_flags flags in
parse_warnings flags;
string_of_flags flags
end
diff --git a/lib/coqProject_file.ml4 b/lib/coqProject_file.ml
index d6c340f6..c2bcd73f 100644
--- a/lib/coqProject_file.ml4
+++ b/lib/coqProject_file.ml
@@ -8,6 +8,14 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+(* This needs to go trou feedback as it is invoked from IDEs, but
+ ideally we would like to make this independent so it can be
+ bootstrapped. *)
+
+(* Note the problem with the error invokation below calling exit... *)
+(* let error msg = Feedback.msg_error msg *)
+let warning msg = Feedback.msg_warning Pp.(str msg)
+
type arg_source = CmdLine | ProjectFile
type 'a sourced = { thing : 'a; source : arg_source }
@@ -82,30 +90,50 @@ let rec post_canonize f =
exception Parsing_error of string
-let rec parse_string = parser
- | [< '' ' | '\n' | '\t' >] -> ""
- | [< 'c; s >] -> (String.make 1 c)^(parse_string s)
- | [< >] -> ""
-and parse_string2 = parser
- | [< ''"' >] -> ""
- | [< 'c; s >] -> (String.make 1 c)^(parse_string2 s)
- | [< >] -> raise (Parsing_error "unterminated string")
-and parse_skip_comment = parser
- | [< ''\n'; s >] -> s
- | [< 'c; s >] -> parse_skip_comment s
- | [< >] -> [< >]
-and parse_args = parser
- | [< '' ' | '\n' | '\t'; s >] -> parse_args s
- | [< ''#'; s >] -> parse_args (parse_skip_comment s)
- | [< ''"'; str = parse_string2; s >] -> ("" ^ str) :: parse_args s
- | [< 'c; str = parse_string; s >] -> ((String.make 1 c) ^ str) :: (parse_args s)
- | [< >] -> []
+let buffer buf =
+ let ans = Buffer.contents buf in
+ let () = Buffer.clear buf in
+ ans
+
+let rec parse_string buf s = match Stream.next s with
+| ' ' | '\n' | '\t' -> buffer buf
+| c ->
+ let () = Buffer.add_char buf c in
+ parse_string buf s
+| exception Stream.Failure -> buffer buf
+
+and parse_string2 buf s = match Stream.next s with
+| '"' -> buffer buf
+| c ->
+ let () = Buffer.add_char buf c in
+ parse_string2 buf s
+| exception Stream.Failure -> raise (Parsing_error "unterminated string")
+
+and parse_skip_comment s = match Stream.next s with
+| '\n' -> ()
+| _ -> parse_skip_comment s
+| exception Stream.Failure -> ()
+
+and parse_args buf accu s = match Stream.next s with
+| ' ' | '\n' | '\t' -> parse_args buf accu s
+| '#' ->
+ let () = parse_skip_comment s in
+ parse_args buf accu s
+| '"' ->
+ let str = parse_string2 buf s in
+ parse_args buf (str :: accu) s
+| c ->
+ let () = Buffer.add_char buf c in
+ let str = parse_string buf s in
+ parse_args buf (str :: accu) s
+| exception Stream.Failure -> accu
let parse f =
let c = open_in f in
- let res = parse_args (Stream.of_channel c) in
+ let buf = Buffer.create 64 in
+ let res = parse_args buf [] (Stream.of_channel c) in
close_in c;
- res
+ List.rev res
;;
(* Copy from minisys.ml, since we don't see that file here *)
@@ -122,7 +150,7 @@ let process_cmd_line orig_dir proj args =
let sourced x = { thing = x; source = if !parsing_project_file then ProjectFile else CmdLine } in
let orig_dir = (* avoids turning foo.v in ./foo.v *)
if orig_dir = "." then "" else orig_dir in
- let error s = Format.eprintf "@[%a]@@\n%!" Pp.pp_with Pp.(str (s^".")); exit 1 in
+ let error s = (Format.eprintf "Error: @[%s@].@\n%!" s; exit 1) in
let mk_path d =
let p = CUnix.correct_path d orig_dir in
{ path = CUnix.remove_path_dot (post_canonize p);
@@ -135,12 +163,12 @@ let process_cmd_line orig_dir proj args =
error "Use \"-install none\" instead of \"-no-install\""
| "-custom" :: _ ->
error "Use \"-extra[-phony] target deps command\" instead of \"-custom command deps target\""
-
+
| ("-no-opt"|"-byte") :: r -> aux { proj with use_ocamlopt = false } r
| ("-full"|"-opt") :: r -> aux { proj with use_ocamlopt = true } r
| "-install" :: d :: r ->
if proj.install_kind <> None then
- Feedback.msg_warning (Pp.str "-install set more than once.");
+ (warning "-install set more than once.@\n%!");
let install = match d with
| "user" -> UserInstall
| "none" -> NoInstall
@@ -167,8 +195,7 @@ let process_cmd_line orig_dir proj args =
let file = CUnix.remove_path_dot (CUnix.correct_path file orig_dir) in
let () = match proj.project_file with
| None -> ()
- | Some _ -> Feedback.msg_warning (Pp.str
- "Multiple project files are deprecated.")
+ | Some _ -> warning "Multiple project files are deprecated.@\n%!"
in
parsing_project_file := true;
let proj = aux { proj with project_file = Some file } (parse file) in
@@ -182,7 +209,7 @@ let process_cmd_line orig_dir proj args =
error "Output file must be in the current directory";
if proj.makefile <> None then
error "Option -o given more than once";
- aux { proj with makefile = Some file } r
+ aux { proj with makefile = Some file } r
| v :: "=" :: def :: r ->
aux { proj with defs = proj.defs @ [sourced (v,def)] } r
| "-arg" :: a :: r ->
diff --git a/lib/envars.ml b/lib/envars.ml
index be82bfe9..3ee0c710 100644
--- a/lib/envars.ml
+++ b/lib/envars.ml
@@ -110,6 +110,7 @@ let check_file_else ~dir ~file oth =
if Sys.file_exists (path / file) then path else oth ()
let guess_coqlib fail =
+ getenv_else "COQLIB" (fun () ->
let prelude = "theories/Init/Prelude.vo" in
check_file_else ~dir:Coq_config.coqlibsuffix ~file:prelude
(fun () ->
@@ -117,6 +118,7 @@ let guess_coqlib fail =
then Coq_config.coqlib
else
fail "cannot guess a path for Coq libraries; please use -coqlib option")
+ )
(** coqlib is now computed once during coqtop initialization *)
diff --git a/lib/flags.ml b/lib/flags.ml
index 8491873e..458186b7 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -57,10 +57,7 @@ let in_toplevel = ref false
let profile = false
-let ide_slave = ref false
-
let raw_print = ref false
-let univ_print = ref false
let we_are_parsing = ref false
@@ -69,25 +66,25 @@ let we_are_parsing = ref false
(* Current means no particular compatibility consideration.
For correct comparisons, this constructor should remain the last one. *)
-type compat_version = V8_6 | V8_7 | Current
+type compat_version = V8_7 | V8_8 | Current
let compat_version = ref Current
let version_compare v1 v2 = match v1, v2 with
- | V8_6, V8_6 -> 0
- | V8_6, _ -> -1
- | _, V8_6 -> 1
| V8_7, V8_7 -> 0
| V8_7, _ -> -1
| _, V8_7 -> 1
+ | V8_8, V8_8 -> 0
+ | V8_8, _ -> -1
+ | _, V8_8 -> 1
| Current, Current -> 0
let version_strictly_greater v = version_compare !compat_version v > 0
let version_less_or_equal v = not (version_strictly_greater v)
let pr_version = function
- | V8_6 -> "8.6"
| V8_7 -> "8.7"
+ | V8_8 -> "8.8"
| Current -> "current"
(* Translate *)
@@ -160,11 +157,3 @@ let print_mod_uid = ref false
let profile_ltac = ref false
let profile_ltac_cutoff = ref 2.0
-
-let dump_bytecode = ref false
-let set_dump_bytecode = (:=) dump_bytecode
-let get_dump_bytecode () = !dump_bytecode
-
-let dump_lambda = ref false
-let set_dump_lambda = (:=) dump_lambda
-let get_dump_lambda () = !dump_lambda
diff --git a/lib/flags.mli b/lib/flags.mli
index 85aaf879..9562e8fc 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -10,6 +10,25 @@
(** Global options of the system. *)
+(** WARNING: don't add new entries to this file!
+
+ This file is own its way to deprecation in favor of a purely
+ functional state, but meanwhile it will contain options that are
+ truly global to the system such as [compat] or [debug]
+
+ If you are thinking about adding a global flag, well, just
+ don't. First of all, options make testins exponentially more
+ expensive, due to the growth of flag combinations. So please make
+ some effort in order for your idea to work in a configuration-free
+ manner.
+
+ If you absolutely must pass an option to your new system, then do
+ so as a functional argument so flags are exposed to unit
+ testing. Then, register such parameters with the proper
+ state-handling mechanism of the top-level subsystem of Coq.
+
+ *)
+
(** Command-line flags *)
val boot : bool ref
@@ -33,19 +52,13 @@ val in_toplevel : bool ref
val profile : bool
-(* -ide_slave: printing will be more verbose, will affect stm caching *)
-val ide_slave : bool ref
-
(* development flag to detect race conditions, it should go away. *)
val we_are_parsing : bool ref
(* Set Printing All flag. For some reason it is a global flag *)
val raw_print : bool ref
-(* Univ print flag, never set anywere. Maybe should belong to Univ? *)
-val univ_print : bool ref
-
-type compat_version = V8_6 | V8_7 | Current
+type compat_version = V8_7 | V8_8 | Current
val compat_version : compat_version ref
val version_compare : compat_version -> compat_version -> int
val version_strictly_greater : compat_version -> bool
@@ -129,13 +142,3 @@ val print_mod_uid : bool ref
val profile_ltac : bool ref
val profile_ltac_cutoff : float ref
-
-(** Dump the bytecode after compilation (for debugging purposes) *)
-val dump_bytecode : bool ref
-val set_dump_bytecode : bool -> unit
-val get_dump_bytecode : unit -> bool
-
-(** Dump the VM lambda code after compilation (for debugging purposes) *)
-val dump_lambda : bool ref
-val set_dump_lambda : bool -> unit
-val get_dump_lambda : unit -> bool
diff --git a/lib/future.ml b/lib/future.ml
index 7a5b6f69..b372bedc 100644
--- a/lib/future.ml
+++ b/lib/future.ml
@@ -49,7 +49,7 @@ end
module UUIDMap = Map.Make(UUID)
module UUIDSet = Set.Make(UUID)
-type 'a assignement = [ `Val of 'a | `Exn of Exninfo.iexn | `Comp of 'a computation]
+type 'a assignment = [ `Val of 'a | `Exn of Exninfo.iexn | `Comp of 'a computation]
(* Val is not necessarily a final state, so the
computation restarts from the state stocked into Val *)
@@ -103,7 +103,7 @@ let from_here ?(fix_exn=id) v = create fix_exn (Val v)
let fix_exn_of ck = let _, _, fix_exn, _ = get ck in fix_exn
let create_delegate ?(blocking=true) ~name fix_exn =
- let assignement signal ck = fun v ->
+ let assignment signal ck = fun v ->
let _, _, fix_exn, c = get ck in
assert (match !c with Delegated _ -> true | _ -> false);
begin match v with
@@ -118,7 +118,7 @@ let create_delegate ?(blocking=true) ~name fix_exn =
(fun () -> Mutex.lock lock; Condition.wait cond lock; Mutex.unlock lock),
(fun () -> Mutex.lock lock; Condition.broadcast cond; Mutex.unlock lock) in
let ck = create ~name fix_exn (Delegated wait) in
- ck, assignement signal ck
+ ck, assignment signal ck
(* TODO: get rid of try/catch to be stackless *)
let rec compute ck : 'a value =
diff --git a/lib/future.mli b/lib/future.mli
index d9e8c87b..55f05518 100644
--- a/lib/future.mli
+++ b/lib/future.mli
@@ -70,10 +70,10 @@ val fix_exn_of : 'a computation -> fix_exn
(* Run remotely, returns the function to assign.
If not blocking (the default) it raises NotReady if forced before the
delegate assigns it. *)
-type 'a assignement = [ `Val of 'a | `Exn of Exninfo.iexn | `Comp of 'a computation]
+type 'a assignment = [ `Val of 'a | `Exn of Exninfo.iexn | `Comp of 'a computation]
val create_delegate :
?blocking:bool -> name:string ->
- fix_exn -> 'a computation * ('a assignement -> unit)
+ fix_exn -> 'a computation * ('a assignment -> unit)
(* Given a computation that is_exn, replace it by another one *)
val replace : 'a computation -> 'a computation -> unit
diff --git a/lib/lib.mllib b/lib/lib.mllib
index 08918594..41b3622a 100644
--- a/lib/lib.mllib
+++ b/lib/lib.mllib
@@ -6,6 +6,7 @@ Control
Util
Pp
+Pp_diff
Stateid
Loc
Feedback
diff --git a/lib/pp.ml b/lib/pp.ml
index cd81f6e7..7f132686 100644
--- a/lib/pp.ml
+++ b/lib/pp.ml
@@ -139,7 +139,7 @@ let v n s = Ppcmd_box(Pp_vbox n,s)
let hv n s = Ppcmd_box(Pp_hvbox n,s)
let hov n s = Ppcmd_box(Pp_hovbox n,s)
-(* Opening and closed of tags *)
+(* Opening and closing of tags *)
let tag t s = Ppcmd_tag(t,s)
(* In new syntax only double quote char is escaped by repeating it *)
@@ -167,6 +167,20 @@ let rec pr_com ft s =
Some s2 -> Format.pp_force_newline ft (); pr_com ft s2
| None -> ()
+let start_pfx = "start."
+let end_pfx = "end."
+
+let split_pfx pfx str =
+ let (str_len, pfx_len) = (String.length str, String.length pfx) in
+ if str_len >= pfx_len && (String.sub str 0 pfx_len) = pfx then
+ (pfx, String.sub str pfx_len (str_len - pfx_len)) else ("", str);;
+
+let split_tag tag =
+ let (pfx, ttag) = split_pfx start_pfx tag in
+ if pfx <> "" then (pfx, ttag) else
+ let (pfx, ttag) = split_pfx end_pfx tag in
+ (pfx, ttag);;
+
(* pretty printing functions *)
let pp_with ft pp =
let cpp_open_box = function
@@ -297,3 +311,62 @@ let prvect_with_sep sep elem v = prvecti_with_sep sep (fun _ -> elem) v
let prvect elem v = prvect_with_sep mt elem v
let surround p = hov 1 (str"(" ++ p ++ str")")
+
+(*** DEBUG code ***)
+
+let db_print_pp fmt pp =
+ let open Format in
+ let block_type fmt btype =
+ let (bt, v) =
+ match btype with
+ | Pp_hbox v -> ("Pp_hbox", v)
+ | Pp_vbox v -> ("Pp_vbox", v)
+ | Pp_hvbox v -> ("Pp_hvbox", v)
+ | Pp_hovbox v -> ("Pp_hovbox", v)
+ in
+ fprintf fmt "%s %d" bt v
+ in
+ let rec db_print_pp_r indent pp =
+ let ind () = fprintf fmt "%s" (String.make (2 * indent) ' ') in
+ ind();
+ match pp with
+ | Ppcmd_empty ->
+ fprintf fmt "Ppcmd_empty@;"
+ | Ppcmd_string str ->
+ fprintf fmt "Ppcmd_string '%s'@;" str
+ | Ppcmd_glue list ->
+ fprintf fmt "Ppcmd_glue@;";
+ List.iter (fun x -> db_print_pp_r (indent + 1) (repr x)) list;
+ | Ppcmd_box (block, pp) ->
+ fprintf fmt "Ppcmd_box %a@;" block_type block;
+ db_print_pp_r (indent + 1) (repr pp);
+ | Ppcmd_tag (tag, pp) ->
+ fprintf fmt "Ppcmd_tag %s@;" tag;
+ db_print_pp_r (indent + 1) (repr pp);
+ | Ppcmd_print_break (i, j) ->
+ fprintf fmt "Ppcmd_print_break %d %d@;" i j
+ | Ppcmd_force_newline ->
+ fprintf fmt "Ppcmd_force_newline@;"
+ | Ppcmd_comment list ->
+ fprintf fmt "Ppcmd_comment@;";
+ List.iter (fun x -> ind(); (fprintf fmt "%s@;" x)) list
+ in
+ pp_open_vbox fmt 0;
+ db_print_pp_r 0 pp;
+ pp_close_box fmt ();
+ pp_print_flush fmt ()
+
+let db_string_of_pp pp =
+ Format.asprintf "%a" db_print_pp pp
+
+let rec flatten pp =
+ match pp with
+ | Ppcmd_glue l -> Ppcmd_glue (List.concat (List.map
+ (fun x -> let x = flatten x in
+ match x with
+ | Ppcmd_glue l2 -> l2
+ | p -> [p])
+ l))
+ | Ppcmd_box (block, pp) -> Ppcmd_box (block, flatten pp)
+ | Ppcmd_tag (tag, pp) -> Ppcmd_tag (tag, flatten pp)
+ | p -> p
diff --git a/lib/pp.mli b/lib/pp.mli
index f3a0a29b..ed31daa5 100644
--- a/lib/pp.mli
+++ b/lib/pp.mli
@@ -189,3 +189,22 @@ val pr_vertical_list : ('b -> t) -> 'b list -> t
val pp_with : Format.formatter -> t -> unit
val string_of_ppcmds : t -> string
+
+
+(** Tag prefix to start a multi-token diff span *)
+val start_pfx : string
+
+(** Tag prefix to end a multi-token diff span *)
+val end_pfx : string
+
+(** Split a tag into prefix and base tag *)
+val split_tag : string -> string * string
+
+(** Print the Pp in tree form for debugging *)
+val db_print_pp : Format.formatter -> t -> unit
+
+(** Print the Pp in tree form for debugging, return as a string *)
+val db_string_of_pp : t -> string
+
+(** Combine nested Ppcmd_glues *)
+val flatten : t -> t
diff --git a/lib/pp_diff.ml b/lib/pp_diff.ml
new file mode 100644
index 00000000..7b4b1eab
--- /dev/null
+++ b/lib/pp_diff.ml
@@ -0,0 +1,303 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* DEBUG/UNIT TEST *)
+let cfprintf oc = Printf.(kfprintf (fun oc -> fprintf oc "") oc)
+let log_out_ch = ref stdout
+let cprintf s = cfprintf !log_out_ch s
+
+
+module StringDiff = Diff2.Make(struct
+ type elem = String.t
+ type t = elem array
+ let get t i = Array.get t i
+ let length t = Array.length t
+end)
+
+type diff_type =
+ [ `Removed
+ | `Added
+ | `Common
+ ]
+
+type diff_list = StringDiff.elem Diff2.edit list
+
+(* debug print diff data structure *)
+let db_print_diffs fmt diffs =
+ let open Format in
+ let print_diff = function
+ | `Common (opos, npos, s) ->
+ fprintf fmt "Common '%s' opos = %d npos = %d\n" s opos npos;
+ | `Removed (pos, s) ->
+ fprintf fmt "Removed '%s' opos = %d\n" s pos;
+ | `Added (pos, s) ->
+ fprintf fmt "Added '%s' npos = %d\n" s pos;
+ in
+ pp_open_vbox fmt 0;
+ List.iter print_diff diffs;
+ pp_close_box fmt ();
+ pp_print_flush fmt ()
+
+let string_of_diffs diffs =
+ Format.asprintf "%a" db_print_diffs diffs
+
+(* Adjust the diffs returned by the Myers algorithm to reduce the span of the
+changes. This gives more natural-looking diffs.
+
+While the Myers algorithm minimizes the number of changes between two
+sequences, it doesn't minimize the span of the changes. For example,
+representing elements in common in lower case and inserted elements in upper
+case (but ignoring case in the algorithm), ABabC and abABC both have 3 changes
+(A, B and C). However the span of the first sequence is 5 elements (ABabC)
+while the span of the second is 3 elements (ABC).
+
+The algorithm modifies the changes iteratively, for example ABabC -> aBAbC -> abABC
+
+dtype: identifies which of Added OR Removed to use; the other one is ignored.
+diff_list: output from the Myers algorithm
+*)
+let shorten_diff_span dtype diff_list =
+ let changed = ref false in
+ let diffs = Array.of_list diff_list in
+ let len = Array.length diffs in
+ let vinfo index =
+ match diffs.(index) with
+ | `Common (opos, npos, s) -> (`Common, opos, npos, s)
+ | `Removed (pos, s) -> (`Removed, pos, 0, s)
+ | `Added (pos, s) -> (`Added, 0, pos, s) in
+ let get_variant index =
+ let (v, _, _, _) = vinfo index in
+ v in
+ let get_str index =
+ let (_, _, _, s) = vinfo index in
+ s in
+
+ let iter start len lt incr = begin
+ let src = ref start in
+ let dst = ref start in
+ while (lt !src len) do
+ if (get_variant !src) = dtype then begin
+ if (lt !dst !src) then
+ dst := !src;
+ while (lt !dst len) && (get_variant !dst) <> `Common do
+ dst := !dst + incr;
+ done;
+ if (lt !dst len) && (get_str !src) = (get_str !dst) then begin
+ (* swap diff *)
+ let (_, c_opos, c_npos, str) = vinfo !dst
+ and (_, v_opos, v_npos, _) = vinfo !src in
+ changed := true;
+ if dtype = `Added then begin
+ diffs.(!src) <- `Common (c_opos, v_npos, str);
+ diffs.(!dst) <- `Added (c_npos, str);
+ end else begin
+ diffs.(!src) <- `Common (v_opos, c_npos, str);
+ diffs.(!dst) <- `Removed (c_opos, str)
+ end
+ end
+ end;
+ src := !src + incr
+ done
+ end in
+
+ iter 0 len (<) 1; (* left to right *)
+ iter (len-1) (-1) (>) (-1); (* right to left *)
+ if !changed then Array.to_list diffs else diff_list;;
+
+let has_changes diffs =
+ let rec has_changes_r diffs added removed =
+ match diffs with
+ | `Added _ :: t -> has_changes_r t true removed
+ | `Removed _ :: t -> has_changes_r t added true
+ | h :: t -> has_changes_r t added removed
+ | [] -> (added, removed) in
+ has_changes_r diffs false false;;
+
+(* get the Myers diff of 2 lists of strings *)
+let diff_strs old_strs new_strs =
+ let diffs = List.rev (StringDiff.diff old_strs new_strs) in
+ shorten_diff_span `Removed (shorten_diff_span `Added diffs);;
+
+(* Default string tokenizer. Makes each character a separate strin.
+Whitespace is not ignored. Doesn't handle UTF-8 differences well. *)
+let def_tokenize_string s =
+ let limit = (String.length s) - 1 in
+ let strs : string list ref = ref [] in
+ for i = 0 to limit do
+ strs := (String.make 1 s.[i]) :: !strs
+ done;
+ List.rev !strs
+
+(* get the Myers diff of 2 strings *)
+let diff_str ?(tokenize_string=def_tokenize_string) old_str new_str =
+ let old_toks = Array.of_list (tokenize_string old_str)
+ and new_toks = Array.of_list (tokenize_string new_str) in
+ diff_strs old_toks new_toks;;
+
+let get_dinfo = function
+ | `Common (_, _, s) -> (`Common, s)
+ | `Removed (_, s) -> (`Removed, s)
+ | `Added (_, s) -> (`Added, s)
+
+[@@@ocaml.warning "-32"]
+let string_of_diff_type = function
+ | `Common -> "Common"
+ | `Removed -> "Removed"
+ | `Added -> "Added"
+[@@@ocaml.warning "+32"]
+
+let wrap_in_bg diff_tag pp =
+ let open Pp in
+ (tag (Pp.start_pfx ^ diff_tag ^ ".bg") (str "")) ++ pp ++
+ (tag (Pp.end_pfx ^ diff_tag ^ ".bg") (str ""))
+
+exception Diff_Failure of string
+
+let add_diff_tags which pp diffs =
+ let open Pp in
+ let diff_tag = if which = `Added then "diff.added" else "diff.removed" in
+ let diffs : diff_list ref = ref diffs in
+ let in_diff = ref false in (* true = buf chars need a tag *)
+ let in_span = ref false in (* true = last pp had a start tag *)
+ let trans = ref false in (* true = this diff starts/ends highlight *)
+ let buf = Buffer.create 16 in
+ let acc_pp = ref [] in
+ let diff_str, diff_ind, diff_len = ref "", ref 0, ref 0 in
+ let prev_dtype, dtype, next_dtype = ref `Common, ref `Common, ref `Common in
+ let is_white c = List.mem c [' '; '\t'; '\n'; '\r'] in
+
+ let skip () =
+ while !diffs <> [] &&
+ (let (t, _) = get_dinfo (List.hd !diffs) in
+ t <> `Common && t <> which)
+ do
+ diffs := List.tl !diffs
+ done
+ in
+
+ let put_tagged case =
+ if Buffer.length buf > 0 then begin
+ let pp = str (Buffer.contents buf) in
+ Buffer.clear buf;
+ let tagged = match case with
+ | "" -> pp
+ | "tag" -> tag diff_tag pp
+ | "start" -> in_span := true; tag (start_pfx ^ diff_tag) pp
+ | "end" -> in_span := false; tag (end_pfx ^ diff_tag) pp
+ | _ -> raise (Diff_Failure "invalid tag id in put_tagged, should be impossible") in
+ acc_pp := tagged :: !acc_pp
+ end
+ in
+
+ let output_pps () =
+ let next_diff_char_hl = if !diff_ind < !diff_len then !dtype = which else !next_dtype = which in
+ let tag = if not !in_diff then ""
+ else if !in_span then
+ if next_diff_char_hl then "" else "end"
+ else
+ if next_diff_char_hl then "start" else "tag" in
+ put_tagged tag; (* flush any remainder *)
+ let l = !acc_pp in
+ acc_pp := [];
+ match List.length l with
+ | 0 -> str ""
+ | 1 -> List.hd l
+ | _ -> seq (List.rev l)
+ in
+
+ let maybe_next_diff () =
+ if !diff_ind = !diff_len && (skip(); !diffs <> []) then begin
+ let (t, s) = get_dinfo (List.hd !diffs) in
+ diff_str := s; diff_ind := 0; diff_len := String.length !diff_str;
+ diffs := List.tl !diffs; skip();
+ prev_dtype := !dtype;
+ dtype := t;
+ next_dtype := (match !diffs with
+ | diff2 :: _ -> let (nt, _) = get_dinfo diff2 in nt
+ | [] -> `Common);
+ trans := !dtype <> !prev_dtype
+ end;
+ in
+
+ let s_char c =
+ maybe_next_diff ();
+ (* matching first should handle tokens with spaces, e.g. in comments/strings *)
+ if !diff_ind < !diff_len && c = !diff_str.[!diff_ind] then begin
+ if !dtype = which && !trans && !diff_ind = 0 then begin
+ put_tagged "";
+ in_diff := true
+ end;
+ Buffer.add_char buf c;
+ diff_ind := !diff_ind + 1;
+ if !dtype = which && !dtype <> !next_dtype && !diff_ind = !diff_len then begin
+ put_tagged (if !in_span then "end" else "tag");
+ in_diff := false
+ end
+ end else if is_white c then
+ Buffer.add_char buf c
+ else begin
+ cprintf "mismatch: expected '%c' but got '%c'\n" !diff_str.[!diff_ind] c;
+ raise (Diff_Failure "string mismatch, shouldn't happen")
+ end
+ in
+
+ (* rearrange so existing tags are inside diff tags, provided that those tags
+ only contain Ppcmd_string's. Other cases (e.g. tag of a box) are not supported. *)
+ (* todo: Is there a better way to do this in OCaml without multiple 'repr's? *)
+ let reorder_tags child pp_tag pp =
+ match repr child with
+ | Ppcmd_tag (t1, pp) -> tag t1 (tag pp_tag pp)
+ | Ppcmd_glue l ->
+ if List.exists (fun x ->
+ match repr x with
+ | Ppcmd_tag (_, _) -> true
+ | _ -> false) l
+ then seq (List.map (fun x ->
+ match repr x with
+ | Ppcmd_tag (t2, pp2) -> tag t2 (tag pp_tag pp2)
+ | pp2 -> tag pp_tag (unrepr pp2)) l)
+ else child
+ | _ -> tag pp_tag child
+ in
+
+ let rec add_tags_r pp =
+ let r_pp = repr pp in
+ match r_pp with
+ | Ppcmd_string s -> String.iter s_char s; output_pps ()
+ | Ppcmd_glue l -> seq (List.map add_tags_r l)
+ | Ppcmd_box (block_type, pp) -> unrepr (Ppcmd_box (block_type, add_tags_r pp))
+ | Ppcmd_tag (pp_tag, pp) -> reorder_tags (add_tags_r pp) pp_tag pp
+ | _ -> pp
+ in
+ let (has_added, has_removed) = has_changes !diffs in
+ let rv = add_tags_r pp in
+ skip ();
+ if !diffs <> [] then
+ raise (Diff_Failure "left-over diff info at end of Pp.t, should be impossible");
+ if has_added || has_removed then wrap_in_bg diff_tag rv else rv;;
+
+let diff_pp ?(tokenize_string=def_tokenize_string) o_pp n_pp =
+ let open Pp in
+ let o_str = string_of_ppcmds o_pp in
+ let n_str = string_of_ppcmds n_pp in
+ let diffs = diff_str ~tokenize_string o_str n_str in
+ (add_diff_tags `Removed o_pp diffs, add_diff_tags `Added n_pp diffs);;
+
+let diff_pp_combined ?(tokenize_string=def_tokenize_string) ?(show_removed=false) o_pp n_pp =
+ let open Pp in
+ let o_str = string_of_ppcmds o_pp in
+ let n_str = string_of_ppcmds n_pp in
+ let diffs = diff_str ~tokenize_string o_str n_str in
+ let (_, has_removed) = has_changes diffs in
+ let added = add_diff_tags `Added n_pp diffs in
+ if show_removed && has_removed then
+ let removed = add_diff_tags `Removed o_pp diffs in
+ (v 0 (removed ++ cut() ++ added))
+ else added;;
diff --git a/lib/pp_diff.mli b/lib/pp_diff.mli
new file mode 100644
index 00000000..03468271
--- /dev/null
+++ b/lib/pp_diff.mli
@@ -0,0 +1,116 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(**
+Computes the differences between 2 Pp's and adds additional tags to a Pp
+to highlight them. Strings are split into tokens using the Coq lexer,
+then the lists of tokens are diffed using the Myers algorithm. A fixup routine,
+shorten_diff_span, shortens the span of the diff result in some cases.
+
+Highlights use 4 tags to specify the color and underline/strikeout. These are
+"diffs.added", "diffs.removed", "diffs.added.bg" and "diffs.removed.bg". The
+first two are for added or removed text; the last two are for unmodified parts
+of a modified item. Diffs that span multiple strings in the Pp are tagged with
+"start.diff.*" and "end.diff.*", but only on the first and last strings of the span.
+
+If the inputs are not acceptable to the lexer, break the strings into
+lists of tokens and call diff_strs, then add_diff_tags with a Pp.t that matches
+the input lists of strings. Tokens that the lexer doesn't return exactly as they
+appeared in the input will raise an exception in add_diff_tags (e.g. comments
+and quoted strings). Fixing that requires tweaking the lexer.
+
+Limitations/Possible enhancements:
+
+- Make diff_pp immune to unlexable strings by adding a flag to the lexer.
+*)
+
+(** Compute the diff between two Pp.t structures and return
+versions of each with diffs highlighted as (old, new) *)
+val diff_pp : ?tokenize_string:(string -> string list) -> Pp.t -> Pp.t -> Pp.t * Pp.t
+
+(** Compute the diff between two Pp.t structures and return
+a highlighted Pp.t. If [show_removed] is true, show separate lines for
+removals and additions, otherwise only show additions *)
+val diff_pp_combined : ?tokenize_string:(string -> string list) -> ?show_removed:bool -> Pp.t -> Pp.t -> Pp.t
+
+(** Raised if the diff fails *)
+exception Diff_Failure of string
+
+module StringDiff :
+sig
+ type elem = String.t
+ type t = elem array
+end
+
+type diff_type =
+ [ `Removed
+ | `Added
+ | `Common
+ ]
+
+type diff_list = StringDiff.elem Diff2.edit list
+
+(** Compute the difference between 2 strings in terms of tokens, using the
+lexer to identify tokens.
+
+If the strings are not lexable, this routine will raise Diff_Failure.
+(I expect to modify the lexer soon so this won't happen.)
+
+Therefore you should catch any exceptions. The workaround for now is for the
+caller to tokenize the strings itself and then call diff_strs.
+*)
+val diff_str : ?tokenize_string:(string -> string list) -> string -> string -> StringDiff.elem Diff2.edit list
+
+(** Compute the differences between 2 lists of strings, treating the strings
+in the lists as indivisible units.
+*)
+val diff_strs : StringDiff.t -> StringDiff.t -> StringDiff.elem Diff2.edit list
+
+(** Generate a new Pp that adds tags marking diffs to a Pp structure:
+which: either `Added or `Removed, indicates which type of diffs to add
+pp: the original structure. For `Added, must be the new pp passed to diff_pp
+ For `Removed, must be the old pp passed to diff_pp. Passing the wrong one
+ will likely raise Diff_Failure.
+diffs: the diff list returned by diff_pp
+
+Diffs of single strings in the Pp are tagged with "diff.added" or "diff.removed".
+Diffs that span multiple strings in the Pp are tagged with "start.diff.*" or
+"end.diff.*", but only on the first and last strings of the span.
+
+Ppcmd_strings will be split into multiple Ppcmd_strings if a diff starts or ends
+in the middle of the string. Whitespace just before or just after a diff will
+not be part of the highlight.
+
+Prexisting tags in pp may contain only a single Ppcmd_string. Those tags will be
+placed inside the diff tags to ensure proper nesting of tags within spans of
+"start.diff.*" ... "end.diff.*".
+
+Under some "impossible" conditions, this routine may raise Diff_Failure.
+If you want to make your call especially bulletproof, catch this
+exception, print a user-visible message, then recall this routine with
+the first argument set to None, which will skip the diff.
+*)
+val add_diff_tags : diff_type -> Pp.t -> StringDiff.elem Diff2.edit list -> Pp.t
+
+(** Returns a boolean pair (added, removed) for [diffs] where a true value
+indicates that something was added/removed in the diffs.
+*)
+val has_changes : diff_list -> bool * bool
+
+val get_dinfo : StringDiff.elem Diff2.edit -> diff_type * string
+
+(** Returns a modified [pp] with the background highlighted with
+"start.<diff_tag>.bg" and "end.<diff_tag>.bg" tags at the beginning
+and end of the returned Pp.t
+*)
+val wrap_in_bg : string -> Pp.t -> Pp.t
+
+(** Displays the diffs to a printable format for debugging *)
+val string_of_diffs : diff_list -> string
diff --git a/lib/rtree.ml b/lib/rtree.ml
index 0e371025..e1c6a4c4 100644
--- a/lib/rtree.ml
+++ b/lib/rtree.ml
@@ -94,22 +94,28 @@ let is_node t =
Node _ -> true
| _ -> false
-
let rec map f t = match t with
Param(i,j) -> Param(i,j)
| Node (a,sons) -> Node (f a, Array.map (map f) sons)
| Rec(j,defs) -> Rec (j, Array.map (map f) defs)
-let smartmap f t = match t with
- Param _ -> t
- | Node (a,sons) ->
- let a'=f a and sons' = Array.smartmap (map f) sons in
- if a'==a && sons'==sons then t
- else Node (a',sons')
- | Rec(j,defs) ->
- let defs' = Array.smartmap (map f) defs in
- if defs'==defs then t
- else Rec(j,defs')
+module Smart =
+struct
+
+ let map f t = match t with
+ Param _ -> t
+ | Node (a,sons) ->
+ let a'=f a and sons' = Array.Smart.map (map f) sons in
+ if a'==a && sons'==sons then t
+ else Node (a',sons')
+ | Rec(j,defs) ->
+ let defs' = Array.Smart.map (map f) defs in
+ if defs'==defs then t
+ else Rec(j,defs')
+
+end
+
+let smartmap = Smart.map
(** Structural equality test, parametrized by an equality on elements *)
diff --git a/lib/rtree.mli b/lib/rtree.mli
index 8edfc3d3..5ab14f60 100644
--- a/lib/rtree.mli
+++ b/lib/rtree.mli
@@ -74,13 +74,22 @@ val incl : ('a -> 'a -> bool) -> ('a -> 'a -> 'a option) -> 'a -> 'a t -> 'a t -
(** Iterators *)
+(** See also [Smart.map] *)
val map : ('a -> 'b) -> 'a t -> 'b t
-(** [(smartmap f t) == t] if [(f a) ==a ] for all nodes *)
val smartmap : ('a -> 'a) -> 'a t -> 'a t
+(** @deprecated Same as [Smart.map] *)
(** A rather simple minded pretty-printer *)
val pp_tree : ('a -> Pp.t) -> 'a t -> Pp.t
val eq_rtree : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
(** @deprecated Same as [Rtree.equal] *)
+
+module Smart :
+sig
+
+ (** [(Smart.map f t) == t] if [(f a) ==a ] for all nodes *)
+ val map : ('a -> 'a) -> 'a t -> 'a t
+
+end
diff --git a/lib/spawn.ml b/lib/spawn.ml
index 63e9e452..0652623b 100644
--- a/lib/spawn.ml
+++ b/lib/spawn.ml
@@ -15,14 +15,12 @@ let accept_timeout = 10.0
let pr_err s = Printf.eprintf "(Spawn ,%d) %s\n%!" (Unix.getpid ()) s
let prerr_endline s = if !Flags.debug then begin pr_err s end else ()
-type req = ReqDie | ReqStats | Hello of int * int
-type resp = RespStats of Gc.stat
+type req = ReqDie | Hello of int * int
module type Control = sig
type handle
val kill : handle -> unit
- val stats : handle -> Gc.stat
val wait : handle -> Unix.process_status
val unixpid : handle -> int
val uid : handle -> string
@@ -43,7 +41,6 @@ module type MainLoopModel = sig
end
(* Common code *)
-let assert_ b s = if not b then CErrors.anomaly (Pp.str s)
(* According to http://caml.inria.fr/mantis/view.php?id=5325
* you can't use the same socket for both writing and reading (may change
@@ -125,14 +122,26 @@ let filter_args args =
Array.of_list (aux (Array.to_list args))
let spawn_with_control prefer_sock env prog args =
- let control_sock, control_sock_name = mk_socket_channel () in
- let extra = [| "-control-channel"; control_sock_name |] in
- let args = Array.append extra (filter_args args) in
+ (* on non-Unix systems we create a control channel *)
+ let not_Unix = Sys.os_type <> "Unix" in
+ let args = filter_args args in
+ let args, control_sock =
+ if not_Unix then
+ let control_sock, control_sock_name = mk_socket_channel () in
+ let extra = [| "-control-channel"; control_sock_name |] in
+ Array.append extra args, Some control_sock
+ else
+ args, None in
let (pid, cin, cout, s), is_sock =
- if Sys.os_type <> "Unix" || prefer_sock
+ if not_Unix (* pipes only work well on Unix *) || prefer_sock
then spawn_sock env prog args, true
else spawn_pipe env prog args, false in
- let _, oob_resp, oob_req = accept control_sock in
+ let oob_resp, oob_req =
+ if not_Unix then
+ let _, oob_resp, oob_req = accept (Option.get control_sock) in
+ Some oob_resp, Some oob_req
+ else
+ None, None in
pid, oob_resp, oob_req, cin, cout, s, is_sock
let output_death_sentence pid oob_req =
@@ -146,8 +155,8 @@ module Async(ML : MainLoopModel) = struct
type process = {
cin : in_channel;
cout : out_channel;
- oob_resp : in_channel;
- oob_req : out_channel;
+ oob_resp : in_channel option;
+ oob_req : out_channel option;
gchan : ML.async_chan;
pid : int;
mutable watch : ML.watch_id option;
@@ -166,11 +175,11 @@ let kill ({ pid = unixpid; oob_resp; oob_req; cin; cout; alive; watch } as p) =
if not alive then prerr_endline "This process is already dead"
else begin try
Option.iter ML.remove_watch watch;
- output_death_sentence (uid p) oob_req;
+ Option.iter (output_death_sentence (uid p)) oob_req;
close_in_noerr cin;
close_out_noerr cout;
- close_in_noerr oob_resp;
- close_out_noerr oob_req;
+ Option.iter close_in_noerr oob_resp;
+ Option.iter close_out_noerr oob_req;
if Sys.os_type = "Unix" then Unix.kill unixpid 9;
p.watch <- None
with e -> prerr_endline ("kill: "^Printexc.to_string e) end
@@ -199,12 +208,6 @@ let spawn ?(prefer_sock=prefer_sock) ?(env=Unix.environment ())
);
p, cout
-let stats { oob_req; oob_resp; alive } =
- assert_ alive "This process is dead.";
- output_value oob_req ReqStats;
- flush oob_req;
- input_value oob_resp
-
let rec wait p =
(* On windows kill is not reliable, so wait may never return. *)
if Sys.os_type = "Unix" then
@@ -221,8 +224,8 @@ module Sync () = struct
type process = {
cin : in_channel;
cout : out_channel;
- oob_resp : in_channel;
- oob_req : out_channel;
+ oob_resp : in_channel option;
+ oob_req : out_channel option;
pid : int;
mutable alive : bool;
}
@@ -242,20 +245,14 @@ let kill ({ pid = unixpid; oob_req; oob_resp; cin; cout; alive } as p) =
p.alive <- false;
if not alive then prerr_endline "This process is already dead"
else begin try
- output_death_sentence (uid p) oob_req;
+ Option.iter (output_death_sentence (uid p)) oob_req;
close_in_noerr cin;
close_out_noerr cout;
- close_in_noerr oob_resp;
- close_out_noerr oob_req;
+ Option.iter close_in_noerr oob_resp;
+ Option.iter close_out_noerr oob_req;
if Sys.os_type = "Unix" then Unix.kill unixpid 9;
with e -> prerr_endline ("kill: "^Printexc.to_string e) end
-let stats { oob_req; oob_resp; alive } =
- assert_ alive "This process is dead.";
- output_value oob_req ReqStats;
- flush oob_req;
- let RespStats g = input_value oob_resp in g
-
let rec wait p =
(* On windows kill is not reliable, so wait may never return. *)
if Sys.os_type = "Unix" then
diff --git a/lib/spawn.mli b/lib/spawn.mli
index c7a56349..944aa27a 100644
--- a/lib/spawn.mli
+++ b/lib/spawn.mli
@@ -25,7 +25,6 @@ module type Control = sig
type handle
val kill : handle -> unit
- val stats : handle -> Gc.stat
val wait : handle -> Unix.process_status
val unixpid : handle -> int
@@ -76,6 +75,5 @@ end
(* This is exported to separate the Spawned module, that for simplicity assumes
* Threads so it is in a separate file *)
-type req = ReqDie | ReqStats | Hello of int * int
+type req = ReqDie | Hello of int * int
val proto_version : int
-type resp = RespStats of Gc.stat
diff --git a/lib/stateid.ml b/lib/stateid.ml
index a258d505..5485c4bf 100644
--- a/lib/stateid.ml
+++ b/lib/stateid.ml
@@ -11,15 +11,11 @@
type t = int
let initial = 1
let dummy = 0
-let fresh, in_range =
+let fresh =
let cur = ref initial in
- (fun () -> incr cur; !cur), (fun id -> id >= 0 && id <= !cur)
+ fun () -> incr cur; !cur
let to_string = string_of_int
-let of_int id =
- (* Coqide too to parse ids too, but cannot check if they are valid.
- * Hence we check for validity only if we are an ide slave. *)
- if !Flags.ide_slave then assert (in_range id);
- id
+let of_int id = id
let to_int id = id
let newer_than id1 id2 = id1 > id2
diff --git a/lib/system.ml b/lib/system.ml
index dfede29e..4bc56beb 100644
--- a/lib/system.ml
+++ b/lib/system.ml
@@ -83,7 +83,9 @@ let file_exists_respecting_case path f =
let rec aux f =
let bf = Filename.basename f in
let df = Filename.dirname f in
- (String.equal df "." || aux df)
+ (* When [df] is the same as [f], it means that the root of the file system
+ has been reached. There is no point in looking further up. *)
+ (String.equal df "." || String.equal f df || aux df)
&& exists_in_dir_respecting_case (Filename.concat path df) bf
in (!trust_file_cache || Sys.file_exists (Filename.concat path f)) && aux f
@@ -116,18 +118,6 @@ let where_in_path ?(warn=true) path filename =
let f = Filename.concat lpe filename in
if file_exists_respecting_case lpe filename then [lpe,f] else []))
-let where_in_path_rex path rex =
- search path (fun lpe ->
- try
- let files = Sys.readdir lpe in
- CList.map_filter (fun name ->
- try
- ignore(Str.search_forward rex name 0);
- Some (lpe,Filename.concat lpe name)
- with Not_found -> None)
- (Array.to_list files)
- with Sys_error _ -> [])
-
let find_file_in_path ?(warn=true) paths filename =
if not (Filename.is_implicit filename) then
(* the name is considered to be a physical name and we use the file
@@ -312,3 +302,9 @@ let with_time ~batch f x =
let msg2 = if batch then "" else " (failure)" in
Feedback.msg_info (str msg ++ fmt_time_difference tstart tend ++ str msg2);
raise e
+
+let get_toplevel_path top =
+ let dir = Filename.dirname Sys.executable_name in
+ let exe = if Sys.(os_type = "Win32" || os_type = "Cygwin") then ".exe" else "" in
+ let eff = if Dynlink.is_native then ".opt" else ".byte" in
+ dir ^ Filename.dir_sep ^ top ^ eff ^ exe
diff --git a/lib/system.mli b/lib/system.mli
index 3349dfea..a3428003 100644
--- a/lib/system.mli
+++ b/lib/system.mli
@@ -50,8 +50,6 @@ val is_in_path : CUnix.load_path -> string -> bool
val is_in_system_path : string -> bool
val where_in_path :
?warn:bool -> CUnix.load_path -> string -> CUnix.physical_path * string
-val where_in_path_rex :
- CUnix.load_path -> Str.regexp -> (CUnix.physical_path * string) list
val find_file_in_path :
?warn:bool -> CUnix.load_path -> string -> CUnix.physical_path * string
@@ -107,3 +105,21 @@ val time_difference : time -> time -> float (** in seconds *)
val fmt_time_difference : time -> time -> Pp.t
val with_time : batch:bool -> ('a -> 'b) -> 'a -> 'b
+
+(** [get_toplevel_path program] builds a complete path to the
+ executable denoted by [program]. This involves:
+
+ - locating the directory: we don't rely on PATH as to make calls to
+ /foo/bin/coqtop chose the right /foo/bin/coqproofworker
+
+ - adding the proper suffixes: .opt/.byte depending on the current
+ mode, + .exe if in windows.
+
+ Note that this function doesn't check that the executable actually
+ exists. This is left back to caller, as well as the choice of
+ fallback strategy. We could add a fallback strategy here but it is
+ better not to as in most cases if this function fails to construct
+ the right name you want you execution to fail rather than fall into
+ choosing some random binary from the system-wide installation of
+ Coq. *)
+val get_toplevel_path : string -> string
diff --git a/lib/util.ml b/lib/util.ml
index 7d7d380b..38d73d34 100644
--- a/lib/util.ml
+++ b/lib/util.ml
@@ -38,8 +38,8 @@ let is_blank = function
module Empty =
struct
- type t
- let abort (x : t) = assert false
+ type t = { abort : 'a. 'a }
+ let abort (x : t) = x.abort
end
(* Strings *)
diff --git a/library/coqlib.ml b/library/coqlib.ml
index 3f01c617..408e2591 100644
--- a/library/coqlib.ml
+++ b/library/coqlib.ml
@@ -171,16 +171,16 @@ let jmeq_kn = make_ind jmeq_module "JMeq"
let glob_jmeq = IndRef (jmeq_kn,0)
type coq_sigma_data = {
- proj1 : global_reference;
- proj2 : global_reference;
- elim : global_reference;
- intro : global_reference;
- typ : global_reference }
+ proj1 : GlobRef.t;
+ proj2 : GlobRef.t;
+ elim : GlobRef.t;
+ intro : GlobRef.t;
+ typ : GlobRef.t }
type coq_bool_data = {
- andb : global_reference;
- andb_prop : global_reference;
- andb_true_intro : global_reference}
+ andb : GlobRef.t;
+ andb_prop : GlobRef.t;
+ andb_true_intro : GlobRef.t}
let build_bool_type () =
{ andb = init_reference ["Datatypes"] "andb";
@@ -213,18 +213,18 @@ let build_prod () =
(* Equalities *)
type coq_eq_data = {
- eq : global_reference;
- ind : global_reference;
- refl : global_reference;
- sym : global_reference;
- trans: global_reference;
- congr: global_reference }
+ eq : GlobRef.t;
+ ind : GlobRef.t;
+ refl : GlobRef.t;
+ sym : GlobRef.t;
+ trans: GlobRef.t;
+ congr: GlobRef.t }
(* Data needed for discriminate and injection *)
type coq_inversion_data = {
- inv_eq : global_reference; (* : forall params, t -> Prop *)
- inv_ind : global_reference; (* : forall params P y, eq params y -> P y *)
- inv_congr: global_reference (* : forall params B (f:t->B) y, eq params y -> f c=f y *)
+ inv_eq : GlobRef.t; (* : forall params, t -> Prop *)
+ inv_ind : GlobRef.t; (* : forall params P y, eq params y -> P y *)
+ inv_congr: GlobRef.t (* : forall params B (f:t->B) y, eq params y -> f c=f y *)
}
let lazy_init_reference dir id = lazy (init_reference dir id)
diff --git a/library/coqlib.mli b/library/coqlib.mli
index 8077c47c..b4bd1b0e 100644
--- a/library/coqlib.mli
+++ b/library/coqlib.mli
@@ -8,10 +8,9 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+open Util
open Names
open Libnames
-open Globnames
-open Util
(** This module collects the global references, constructions and
patterns of the standard library used in ocaml files *)
@@ -44,14 +43,14 @@ open Util
type message = string
-val find_reference : message -> string list -> string -> global_reference
-val coq_reference : message -> string list -> string -> global_reference
+val find_reference : message -> string list -> string -> GlobRef.t
+val coq_reference : message -> string list -> string -> GlobRef.t
(** For tactics/commands requiring vernacular libraries *)
val check_required_library : string list -> unit
(** Search in several modules (not prefixed by "Coq") *)
-val gen_reference_in_modules : string->string list list-> string -> global_reference
+val gen_reference_in_modules : string->string list list-> string -> GlobRef.t
val arith_modules : string list list
val zarith_base_modules : string list list
@@ -78,24 +77,24 @@ val type_of_id : Constant.t
(** Natural numbers *)
val nat_path : full_path
-val glob_nat : global_reference
+val glob_nat : GlobRef.t
val path_of_O : constructor
val path_of_S : constructor
-val glob_O : global_reference
-val glob_S : global_reference
+val glob_O : GlobRef.t
+val glob_S : GlobRef.t
(** Booleans *)
-val glob_bool : global_reference
+val glob_bool : GlobRef.t
val path_of_true : constructor
val path_of_false : constructor
-val glob_true : global_reference
-val glob_false : global_reference
+val glob_true : GlobRef.t
+val glob_false : GlobRef.t
(** Equality *)
-val glob_eq : global_reference
-val glob_identity : global_reference
-val glob_jmeq : global_reference
+val glob_eq : GlobRef.t
+val glob_identity : GlobRef.t
+val glob_jmeq : GlobRef.t
(** {6 ... } *)
(** Constructions and patterns related to Coq initial state are unknown
@@ -106,18 +105,18 @@ val glob_jmeq : global_reference
at runtime. *)
type coq_bool_data = {
- andb : global_reference;
- andb_prop : global_reference;
- andb_true_intro : global_reference}
+ andb : GlobRef.t;
+ andb_prop : GlobRef.t;
+ andb_true_intro : GlobRef.t}
val build_bool_type : coq_bool_data delayed
(** {6 For Equality tactics } *)
type coq_sigma_data = {
- proj1 : global_reference;
- proj2 : global_reference;
- elim : global_reference;
- intro : global_reference;
- typ : global_reference }
+ proj1 : GlobRef.t;
+ proj2 : GlobRef.t;
+ elim : GlobRef.t;
+ intro : GlobRef.t;
+ typ : GlobRef.t }
val build_sigma_set : coq_sigma_data delayed
val build_sigma_type : coq_sigma_data delayed
@@ -132,30 +131,30 @@ val build_sigma : coq_sigma_data delayed
val build_prod : coq_sigma_data delayed
type coq_eq_data = {
- eq : global_reference;
- ind : global_reference;
- refl : global_reference;
- sym : global_reference;
- trans: global_reference;
- congr: global_reference }
+ eq : GlobRef.t;
+ ind : GlobRef.t;
+ refl : GlobRef.t;
+ sym : GlobRef.t;
+ trans: GlobRef.t;
+ congr: GlobRef.t }
val build_coq_eq_data : coq_eq_data delayed
val build_coq_identity_data : coq_eq_data delayed
val build_coq_jmeq_data : coq_eq_data delayed
-val build_coq_eq : global_reference delayed (** = [(build_coq_eq_data()).eq] *)
-val build_coq_eq_refl : global_reference delayed (** = [(build_coq_eq_data()).refl] *)
-val build_coq_eq_sym : global_reference delayed (** = [(build_coq_eq_data()).sym] *)
-val build_coq_f_equal2 : global_reference delayed
+val build_coq_eq : GlobRef.t delayed (** = [(build_coq_eq_data()).eq] *)
+val build_coq_eq_refl : GlobRef.t delayed (** = [(build_coq_eq_data()).refl] *)
+val build_coq_eq_sym : GlobRef.t delayed (** = [(build_coq_eq_data()).sym] *)
+val build_coq_f_equal2 : GlobRef.t delayed
(** Data needed for discriminate and injection *)
type coq_inversion_data = {
- inv_eq : global_reference; (** : forall params, args -> Prop *)
- inv_ind : global_reference; (** : forall params P (H : P params) args, eq params args
+ inv_eq : GlobRef.t; (** : forall params, args -> Prop *)
+ inv_ind : GlobRef.t; (** : forall params P (H : P params) args, eq params args
-> P args *)
- inv_congr: global_reference (** : forall params B (f:t->B) args, eq params args ->
+ inv_congr: GlobRef.t (** : forall params B (f:t->B) args, eq params args ->
f params = f args *)
}
@@ -165,45 +164,45 @@ val build_coq_inversion_jmeq_data : coq_inversion_data delayed
val build_coq_inversion_eq_true_data : coq_inversion_data delayed
(** Specif *)
-val build_coq_sumbool : global_reference delayed
+val build_coq_sumbool : GlobRef.t delayed
(** {6 ... } *)
(** Connectives
The False proposition *)
-val build_coq_False : global_reference delayed
+val build_coq_False : GlobRef.t delayed
(** The True proposition and its unique proof *)
-val build_coq_True : global_reference delayed
-val build_coq_I : global_reference delayed
+val build_coq_True : GlobRef.t delayed
+val build_coq_I : GlobRef.t delayed
(** Negation *)
-val build_coq_not : global_reference delayed
+val build_coq_not : GlobRef.t delayed
(** Conjunction *)
-val build_coq_and : global_reference delayed
-val build_coq_conj : global_reference delayed
-val build_coq_iff : global_reference delayed
+val build_coq_and : GlobRef.t delayed
+val build_coq_conj : GlobRef.t delayed
+val build_coq_iff : GlobRef.t delayed
-val build_coq_iff_left_proj : global_reference delayed
-val build_coq_iff_right_proj : global_reference delayed
+val build_coq_iff_left_proj : GlobRef.t delayed
+val build_coq_iff_right_proj : GlobRef.t delayed
(** Disjunction *)
-val build_coq_or : global_reference delayed
+val build_coq_or : GlobRef.t delayed
(** Existential quantifier *)
-val build_coq_ex : global_reference delayed
-
-val coq_eq_ref : global_reference lazy_t
-val coq_identity_ref : global_reference lazy_t
-val coq_jmeq_ref : global_reference lazy_t
-val coq_eq_true_ref : global_reference lazy_t
-val coq_existS_ref : global_reference lazy_t
-val coq_existT_ref : global_reference lazy_t
-val coq_exist_ref : global_reference lazy_t
-val coq_not_ref : global_reference lazy_t
-val coq_False_ref : global_reference lazy_t
-val coq_sumbool_ref : global_reference lazy_t
-val coq_sig_ref : global_reference lazy_t
-
-val coq_or_ref : global_reference lazy_t
-val coq_iff_ref : global_reference lazy_t
+val build_coq_ex : GlobRef.t delayed
+
+val coq_eq_ref : GlobRef.t lazy_t
+val coq_identity_ref : GlobRef.t lazy_t
+val coq_jmeq_ref : GlobRef.t lazy_t
+val coq_eq_true_ref : GlobRef.t lazy_t
+val coq_existS_ref : GlobRef.t lazy_t
+val coq_existT_ref : GlobRef.t lazy_t
+val coq_exist_ref : GlobRef.t lazy_t
+val coq_not_ref : GlobRef.t lazy_t
+val coq_False_ref : GlobRef.t lazy_t
+val coq_sumbool_ref : GlobRef.t lazy_t
+val coq_sig_ref : GlobRef.t lazy_t
+
+val coq_or_ref : GlobRef.t lazy_t
+val coq_iff_ref : GlobRef.t lazy_t
diff --git a/intf/decl_kinds.ml b/library/decl_kinds.ml
index 0d328531..c1a673ed 100644
--- a/intf/decl_kinds.ml
+++ b/library/decl_kinds.ml
@@ -74,14 +74,3 @@ type logical_kind =
| IsAssumption of assumption_object_kind
| IsDefinition of definition_object_kind
| IsProof of theorem_kind
-
-(** Recursive power of type declarations *)
-
-type recursivity_kind = Declarations.recursivity_kind =
- | Finite (** = inductive *)
- [@ocaml.deprecated "Please use [Declarations.Finite"]
- | CoFinite (** = coinductive *)
- [@ocaml.deprecated "Please use [Declarations.CoFinite"]
- | BiFinite (** = non-recursive, like in "Record" definitions *)
- [@ocaml.deprecated "Please use [Declarations.BiFinite"]
-[@@ocaml.deprecated "Please use [Declarations.recursivity_kind"]
diff --git a/library/declaremods.ml b/library/declaremods.ml
index 762efc5e..0b3b461e 100644
--- a/library/declaremods.ml
+++ b/library/declaremods.ml
@@ -17,11 +17,26 @@ open Entries
open Libnames
open Libobject
open Mod_subst
-open Vernacexpr
-open Misctypes
(** {6 Inlining levels} *)
+(** Rigid / flexible module signature *)
+
+type 'a module_signature =
+ | Enforce of 'a (** ... : T *)
+ | Check of 'a list (** ... <: T1 <: T2, possibly empty *)
+
+(** Which module inline annotations should we honor,
+ either None or the ones whose level is less or equal
+ to the given integer *)
+
+type inline =
+ | NoInline
+ | DefaultInline
+ | InlineAt of int
+
+type module_kind = Module | ModType | ModAny
+
let default_inline () = Some (Flags.get_inline_level ())
let inl2intopt = function
@@ -980,8 +995,8 @@ let iter_all_segments f =
(** {6 Some types used to shorten declaremods.mli} *)
type 'modast module_interpretor =
- Environ.env -> Misctypes.module_kind -> 'modast ->
- Entries.module_struct_entry * Misctypes.module_kind * Univ.ContextSet.t
+ Environ.env -> module_kind -> 'modast ->
+ Entries.module_struct_entry * module_kind * Univ.ContextSet.t
type 'modast module_params =
(lident list * ('modast * inline)) list
diff --git a/library/declaremods.mli b/library/declaremods.mli
index fd8d2961..b42a59bf 100644
--- a/library/declaremods.mli
+++ b/library/declaremods.mli
@@ -9,16 +9,34 @@
(************************************************************************)
open Names
-open Vernacexpr
(** {6 Modules } *)
+(** Rigid / flexible module signature *)
+
+type 'a module_signature =
+ | Enforce of 'a (** ... : T *)
+ | Check of 'a list (** ... <: T1 <: T2, possibly empty *)
+
+(** Which module inline annotations should we honor,
+ either None or the ones whose level is less or equal
+ to the given integer *)
+
+type inline =
+ | NoInline
+ | DefaultInline
+ | InlineAt of int
+
+(** Kinds of modules *)
+
+type module_kind = Module | ModType | ModAny
+
type 'modast module_interpretor =
- Environ.env -> Misctypes.module_kind -> 'modast ->
- Entries.module_struct_entry * Misctypes.module_kind * Univ.ContextSet.t
+ Environ.env -> module_kind -> 'modast ->
+ Entries.module_struct_entry * module_kind * Univ.ContextSet.t
type 'modast module_params =
- (Misctypes.lident list * ('modast * inline)) list
+ (lident list * ('modast * inline)) list
(** [declare_module interp_modast id fargs typ exprs]
declares module [id], with structure constructed by [interp_modast]
diff --git a/library/global.ml b/library/global.ml
index dcb20a28..e833f711 100644
--- a/library/global.ml
+++ b/library/global.ml
@@ -90,6 +90,7 @@ let push_context b c = globalize0 (Safe_typing.push_context b c)
let set_engagement c = globalize0 (Safe_typing.set_engagement c)
let set_typing_flags c = globalize0 (Safe_typing.set_typing_flags c)
+let typing_flags () = Environ.typing_flags (env ())
let export_private_constants ~in_section cd = globalize (Safe_typing.export_private_constants ~in_section cd)
let add_constant dir id d = globalize (Safe_typing.add_constant dir (i2l id) d)
let add_mind dir id mie = globalize (Safe_typing.add_mind dir (i2l id) mie)
@@ -278,3 +279,9 @@ let register_inline c = globalize0 (Safe_typing.register_inline c)
let set_strategy k l =
GlobalSafeEnv.set_safe_env (Safe_typing.set_strategy (safe_env ()) k l)
+let set_reduction_sharing b =
+ let env = safe_env () in
+ let flags = Environ.typing_flags (Safe_typing.env_of_safe_env env) in
+ let flags = { flags with Declarations.share_reduction = b } in
+ let env = Safe_typing.set_typing_flags flags env in
+ GlobalSafeEnv.set_safe_env env
diff --git a/library/global.mli b/library/global.mli
index b82039a0..2819c187 100644
--- a/library/global.mli
+++ b/library/global.mli
@@ -23,13 +23,14 @@ val env_is_initial : unit -> bool
val universes : unit -> UGraph.t
val named_context_val : unit -> Environ.named_context_val
-val named_context : unit -> Context.Named.t
+val named_context : unit -> Constr.named_context
(** {6 Enriching the global environment } *)
(** Changing the (im)predicativity of the system *)
val set_engagement : Declarations.engagement -> unit
val set_typing_flags : Declarations.typing_flags -> unit
+val typing_flags : unit -> Declarations.typing_flags
(** Variables, Local definitions, constants, inductive types *)
@@ -79,7 +80,7 @@ val add_module_parameter :
(** {6 Queries in the global environment } *)
-val lookup_named : variable -> Context.Named.Declaration.t
+val lookup_named : variable -> Constr.named_declaration
val lookup_constant : Constant.t -> Declarations.constant_body
val lookup_inductive : inductive ->
Declarations.mutual_inductive_body * Declarations.one_inductive_body
@@ -123,26 +124,26 @@ val env_of_context : Environ.named_context_val -> Environ.env
val join_safe_environment : ?except:Future.UUIDSet.t -> unit -> unit
val is_joined_environment : unit -> bool
-val is_polymorphic : Globnames.global_reference -> bool
-val is_template_polymorphic : Globnames.global_reference -> bool
-val is_type_in_type : Globnames.global_reference -> bool
+val is_polymorphic : GlobRef.t -> bool
+val is_template_polymorphic : GlobRef.t -> bool
+val is_type_in_type : GlobRef.t -> bool
val constr_of_global_in_context : Environ.env ->
- Globnames.global_reference -> Constr.types * Univ.AUContext.t
+ GlobRef.t -> Constr.types * Univ.AUContext.t
(** Returns the type of the constant in its local universe
context. The type should not be used without pushing it's universe
context in the environmnent of usage. For non-universe-polymorphic
constants, it does not matter. *)
val type_of_global_in_context : Environ.env ->
- Globnames.global_reference -> Constr.types * Univ.AUContext.t
+ GlobRef.t -> Constr.types * Univ.AUContext.t
(** Returns the type of the constant in its local universe
context. The type should not be used without pushing it's universe
context in the environmnent of usage. For non-universe-polymorphic
constants, it does not matter. *)
(** Returns the universe context of the global reference (whatever its polymorphic status is). *)
-val universes_of_global : Globnames.global_reference -> Univ.AUContext.t
+val universes_of_global : GlobRef.t -> Univ.AUContext.t
(** {6 Retroknowledge } *)
@@ -155,6 +156,8 @@ val register_inline : Constant.t -> unit
val set_strategy : Constant.t Names.tableKey -> Conv_oracle.level -> unit
+val set_reduction_sharing : bool -> unit
+
(* Modifies the global state, registering new universes *)
val current_modpath : unit -> ModPath.t
diff --git a/library/globnames.ml b/library/globnames.ml
index 6c9c813e..6383a1f8 100644
--- a/library/globnames.ml
+++ b/library/globnames.ml
@@ -15,7 +15,7 @@ open Mod_subst
open Libnames
(*s Global reference is a kernel side type for all references together *)
-type global_reference = Names.global_reference =
+type global_reference = GlobRef.t =
| VarRef of variable (** A reference to the section-context. *)
| ConstRef of Constant.t (** A reference to the environment. *)
| IndRef of inductive (** A reference to an inductive type. *)
@@ -26,14 +26,6 @@ let isConstRef = function ConstRef _ -> true | _ -> false
let isIndRef = function IndRef _ -> true | _ -> false
let isConstructRef = function ConstructRef _ -> true | _ -> false
-let eq_gr gr1 gr2 =
- gr1 == gr2 || match gr1,gr2 with
- | ConstRef con1, ConstRef con2 -> Constant.equal con1 con2
- | IndRef kn1, IndRef kn2 -> eq_ind kn1 kn2
- | ConstructRef kn1, ConstructRef kn2 -> eq_constructor kn1 kn2
- | VarRef v1, VarRef v2 -> Id.equal v1 v2
- | _ -> false
-
let destVarRef = function VarRef ind -> ind | _ -> failwith "destVarRef"
let destConstRef = function ConstRef ind -> ind | _ -> failwith "destConstRef"
let destIndRef = function IndRef ind -> ind | _ -> failwith "destIndRef"
@@ -95,8 +87,6 @@ let printable_constr_of_global = function
| ConstructRef sp -> mkConstruct sp
| IndRef sp -> mkInd sp
-let reference_of_constr = global_of_constr
-
let global_eq_gen eq_cst eq_ind eq_cons x y =
x == y ||
match x, y with
@@ -245,3 +235,6 @@ let pop_global_reference = function
| IndRef (kn,i) -> IndRef (pop_kn kn,i)
| ConstructRef ((kn,i),j) -> ConstructRef ((pop_kn kn,i),j)
| VarRef id -> anomaly (Pp.str "VarRef not poppable.")
+
+(* Deprecated *)
+let eq_gr = GlobRef.equal
diff --git a/library/globnames.mli b/library/globnames.mli
index f2b88b87..15fcd5bd 100644
--- a/library/globnames.mli
+++ b/library/globnames.mli
@@ -14,71 +14,69 @@ open Constr
open Mod_subst
(** {6 Global reference is a kernel side type for all references together } *)
-type global_reference = Names.global_reference =
+type global_reference = GlobRef.t =
| VarRef of variable (** A reference to the section-context. *)
| ConstRef of Constant.t (** A reference to the environment. *)
| IndRef of inductive (** A reference to an inductive type. *)
| ConstructRef of constructor (** A reference to a constructor of an inductive type. *)
+[@@ocaml.deprecated "Use Names.GlobRef.t"]
-val isVarRef : global_reference -> bool
-val isConstRef : global_reference -> bool
-val isIndRef : global_reference -> bool
-val isConstructRef : global_reference -> bool
+val isVarRef : GlobRef.t -> bool
+val isConstRef : GlobRef.t -> bool
+val isIndRef : GlobRef.t -> bool
+val isConstructRef : GlobRef.t -> bool
-val eq_gr : global_reference -> global_reference -> bool
-val canonical_gr : global_reference -> global_reference
+val eq_gr : GlobRef.t -> GlobRef.t -> bool
+[@@ocaml.deprecated "Use Names.GlobRef.equal"]
+val canonical_gr : GlobRef.t -> GlobRef.t
-val destVarRef : global_reference -> variable
-val destConstRef : global_reference -> Constant.t
-val destIndRef : global_reference -> inductive
-val destConstructRef : global_reference -> constructor
+val destVarRef : GlobRef.t -> variable
+val destConstRef : GlobRef.t -> Constant.t
+val destIndRef : GlobRef.t -> inductive
+val destConstructRef : GlobRef.t -> constructor
-val is_global : global_reference -> constr -> bool
+val is_global : GlobRef.t -> constr -> bool
val subst_constructor : substitution -> constructor -> constructor * constr
-val subst_global : substitution -> global_reference -> global_reference * constr
-val subst_global_reference : substitution -> global_reference -> global_reference
+val subst_global : substitution -> GlobRef.t -> GlobRef.t * constr
+val subst_global_reference : substitution -> GlobRef.t -> GlobRef.t
(** This constr is not safe to be typechecked, universe polymorphism is not
handled here: just use for printing *)
-val printable_constr_of_global : global_reference -> constr
+val printable_constr_of_global : GlobRef.t -> constr
(** Turn a construction denoting a global reference into a global reference;
raise [Not_found] if not a global reference *)
-val global_of_constr : constr -> global_reference
-
-(** Obsolete synonyms for constr_of_global and global_of_constr *)
-val reference_of_constr : constr -> global_reference
-[@@ocaml.deprecated "Alias of Globnames.global_of_constr"]
+val global_of_constr : constr -> GlobRef.t
module RefOrdered : sig
- type t = global_reference
+ type t = GlobRef.t
val compare : t -> t -> int
val equal : t -> t -> bool
val hash : t -> int
end
module RefOrdered_env : sig
- type t = global_reference
+ type t = GlobRef.t
val compare : t -> t -> int
val equal : t -> t -> bool
val hash : t -> int
end
-module Refset : CSig.SetS with type elt = global_reference
+module Refset : CSig.SetS with type elt = GlobRef.t
module Refmap : Map.ExtS
- with type key = global_reference and module Set := Refset
+ with type key = GlobRef.t and module Set := Refset
-module Refset_env : CSig.SetS with type elt = global_reference
+module Refset_env : CSig.SetS with type elt = GlobRef.t
module Refmap_env : Map.ExtS
- with type key = global_reference and module Set := Refset_env
+ with type key = GlobRef.t and module Set := Refset_env
(** {6 Extended global references } *)
type syndef_name = KerName.t
type extended_global_reference =
- | TrueGlobal of global_reference
+ | TrueGlobal of GlobRef.t
| SynDef of syndef_name
module ExtRefOrdered : sig
@@ -89,7 +87,7 @@ module ExtRefOrdered : sig
end
type global_reference_or_constr =
- | IsGlobal of global_reference
+ | IsGlobal of GlobRef.t
| IsConstr of constr
(** {6 Temporary function to brutally form kernel names from section paths } *)
@@ -100,7 +98,6 @@ val encode_con : DirPath.t -> Id.t -> Constant.t
val decode_con : Constant.t -> DirPath.t * Id.t
(** {6 Popping one level of section in global names } *)
-
val pop_con : Constant.t -> Constant.t
val pop_kn : MutInd.t-> MutInd.t
-val pop_global_reference : global_reference -> global_reference
+val pop_global_reference : GlobRef.t -> GlobRef.t
diff --git a/library/goptions.ml b/library/goptions.ml
index eb7bb5b4..dcbc46ab 100644
--- a/library/goptions.ml
+++ b/library/goptions.ml
@@ -161,7 +161,7 @@ module type RefConvertArg =
sig
type t
val compare : t -> t -> int
- val encode : reference -> t
+ val encode : qualid -> t
val subst : substitution -> t -> t
val printer : t -> Pp.t
val key : option_name
@@ -172,7 +172,7 @@ end
module RefConvert = functor (A : RefConvertArg) ->
struct
type t = A.t
- type key = reference
+ type key = qualid
let compare = A.compare
let table = ref_table
let encode = A.encode
@@ -318,26 +318,35 @@ let set_option_value ?(locality = OptDefault) check_and_cast key v =
| Some (name, depr, (read,write,append)) ->
write locality (check_and_cast v (read ()))
-let bad_type_error () = user_err Pp.(str "Bad type of value for this option.")
+let show_value_type = function
+ | BoolValue _ -> "bool"
+ | IntValue _ -> "int"
+ | StringValue _ -> "string"
+ | StringOptValue _ -> "string"
+
+let bad_type_error opt_value actual_type =
+ user_err Pp.(str "Bad type of value for this option:" ++ spc() ++
+ str "expected " ++ str (show_value_type opt_value) ++
+ str ", got " ++ str actual_type ++ str ".")
let check_int_value v = function
| IntValue _ -> IntValue v
- | _ -> bad_type_error ()
+ | optv -> bad_type_error optv "int"
let check_bool_value v = function
| BoolValue _ -> BoolValue v
- | _ -> bad_type_error ()
+ | optv -> bad_type_error optv "bool"
let check_string_value v = function
| StringValue _ -> StringValue v
| StringOptValue _ -> StringOptValue (Some v)
- | _ -> bad_type_error ()
+ | optv -> bad_type_error optv "string"
let check_unset_value v = function
| BoolValue _ -> BoolValue false
| IntValue _ -> IntValue None
| StringOptValue _ -> StringOptValue None
- | _ -> bad_type_error ()
+ | optv -> bad_type_error optv "nothing"
(* Nota: For compatibility reasons, some errors are treated as
warning. This allows a script to refer to an option that doesn't
diff --git a/library/goptions.mli b/library/goptions.mli
index 6c14d19e..3d7df18f 100644
--- a/library/goptions.mli
+++ b/library/goptions.mli
@@ -89,7 +89,7 @@ module MakeRefTable :
(A : sig
type t
val compare : t -> t -> int
- val encode : reference -> t
+ val encode : qualid -> t
val subst : substitution -> t -> t
val printer : t -> Pp.t
val key : option_name
@@ -147,9 +147,9 @@ val get_string_table :
val get_ref_table :
option_name ->
- < add : reference -> unit;
- remove : reference -> unit;
- mem : reference -> unit;
+ < add : qualid -> unit;
+ remove : qualid -> unit;
+ mem : qualid -> unit;
print : unit >
(** The first argument is a locality flag. *)
diff --git a/library/keys.ml b/library/keys.ml
index 34a6adab..3cadcb64 100644
--- a/library/keys.ml
+++ b/library/keys.ml
@@ -10,12 +10,13 @@
(** Keys for unification and indexing *)
-open Globnames
-open Term
+open Names
+open Constr
open Libobject
+open Globnames
type key =
- | KGlob of global_reference
+ | KGlob of GlobRef.t
| KLam
| KLet
| KProd
@@ -126,7 +127,7 @@ let constr_key kind c =
| Construct (c,u) -> KGlob (ConstructRef c)
| Var id -> KGlob (VarRef id)
| App (f, _) -> aux f
- | Proj (p, _) -> KGlob (ConstRef (Names.Projection.constant p))
+ | Proj (p, _) -> KGlob (ConstRef (Projection.constant p))
| Cast (p, _, _) -> aux p
| Lambda _ -> KLam
| Prod _ -> KProd
diff --git a/library/keys.mli b/library/keys.mli
index 1fb9a3de..19838365 100644
--- a/library/keys.mli
+++ b/library/keys.mli
@@ -8,8 +8,6 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Globnames
-
type key
val declare_equiv_keys : key -> key -> unit
@@ -21,5 +19,5 @@ val equiv_keys : key -> key -> bool
val constr_key : ('a -> ('a, 't, 'u, 'i) Constr.kind_of_term) -> 'a -> key option
(** Compute the head key of a term. *)
-val pr_keys : (global_reference -> Pp.t) -> Pp.t
+val pr_keys : (Names.GlobRef.t -> Pp.t) -> Pp.t
(** Pretty-print the mapping *)
diff --git a/library/lib.ml b/library/lib.ml
index 543cb45b..8ebe4489 100644
--- a/library/lib.ml
+++ b/library/lib.ml
@@ -26,13 +26,11 @@ type node =
| Leaf of obj
| CompilingLibrary of object_prefix
| OpenedModule of is_type * export * object_prefix * Summary.frozen
- | ClosedModule of library_segment
| OpenedSection of object_prefix * Summary.frozen
- | ClosedSection of library_segment
-and library_entry = object_name * node
+type library_entry = object_name * node
-and library_segment = library_entry list
+type library_segment = library_entry list
type lib_objects = (Names.Id.t * obj) list
@@ -51,7 +49,7 @@ let subst_objects subst seg =
if obj' == obj then node else
(id, obj')
in
- List.smartmap subst_one seg
+ List.Smart.map subst_one seg
(*let load_and_subst_objects i prefix subst seg =
List.rev (List.fold_left (fun seg (id,obj as node) ->
@@ -73,10 +71,6 @@ let classify_segment seg =
clean ((id,o')::substl, keepl, anticipl) stk
| Anticipate o' ->
clean (substl, keepl, o'::anticipl) stk)
- | (_,ClosedSection _) :: stk -> clean acc stk
- (* LEM; TODO: Understand what this does and see if what I do is the
- correct thing for ClosedMod(ule|type) *)
- | (_,ClosedModule _) :: stk -> clean acc stk
| (_,OpenedSection _) :: _ -> user_err Pp.(str "there are still opened sections")
| (_,OpenedModule (ty,_,_,_)) :: _ ->
user_err ~hdr:"Lib.classify_segment"
@@ -183,22 +177,11 @@ let split_lib_gen test =
| before -> after,equal,before
in
let rec findeq after = function
- | hd :: before ->
- if test hd
- then Some (collect after [hd] before)
- else (match hd with
- | (sp,ClosedModule seg)
- | (sp,ClosedSection seg) ->
- (match findeq after seg with
- | None -> findeq (hd::after) before
- | Some (sub_after,sub_equal,sub_before) ->
- Some (sub_after, sub_equal, (List.append sub_before before)))
- | _ -> findeq (hd::after) before)
- | [] -> None
+ | hd :: before when test hd -> collect after [hd] before
+ | hd :: before -> findeq (hd::after) before
+ | [] -> user_err Pp.(str "no such entry")
in
- match findeq [] !lib_state.lib_stk with
- | None -> user_err Pp.(str "no such entry")
- | Some r -> r
+ findeq [] !lib_state.lib_stk
let eq_object_name (fp1, kn1) (fp2, kn2) =
eq_full_path fp1 fp2 && Names.KerName.equal kn1 kn2
@@ -318,7 +301,6 @@ let end_mod is_type =
in
let (after,mark,before) = split_lib_at_opening oname in
lib_state := { !lib_state with lib_stk = before };
- add_entry oname (ClosedModule (List.rev (mark::after)));
let prefix = !lib_state.path_prefix in
recalc_path_prefix ();
(oname, prefix, fs, after)
@@ -416,7 +398,7 @@ let find_opening_node id =
- the list of substitution to do at section closing
*)
-type variable_info = Context.Named.Declaration.t * Decl_kinds.binding_kind
+type variable_info = Constr.named_declaration * Decl_kinds.binding_kind
type variable_context = variable_info list
type abstr_info = {
@@ -566,7 +548,6 @@ let discharge_item ((sp,_ as oname),e) =
match e with
| Leaf lobj ->
Option.map (fun o -> (basename sp,o)) (discharge_object (oname,lobj))
- | ClosedSection _ | ClosedModule _ -> None
| OpenedSection _ | OpenedModule _ | CompilingLibrary _ ->
anomaly (Pp.str "discharge_item.")
@@ -580,13 +561,10 @@ let close_section () =
in
let (secdecls,mark,before) = split_lib_at_opening oname in
lib_state := { !lib_state with lib_stk = before };
- let full_olddir = !lib_state.path_prefix.obj_dir in
pop_path_prefix ();
- add_entry oname (ClosedSection (List.rev (mark::secdecls)));
let newdecls = List.map discharge_item secdecls in
Summary.unfreeze_summaries fs;
- List.iter (Option.iter (fun (id,o) -> add_discharged_leaf id o)) newdecls;
- Nametab.push_dir (Nametab.Until 1) full_olddir (DirClosedSection full_olddir)
+ List.iter (Option.iter (fun (id,o) -> add_discharged_leaf id o)) newdecls
(* State and initialization. *)
@@ -602,10 +580,8 @@ let freeze ~marshallable =
| n, (CompilingLibrary _ as x) -> Some (n,x)
| n, OpenedModule (it,e,op,_) ->
Some(n,OpenedModule(it,e,op,Summary.empty_frozen))
- | n, ClosedModule _ -> Some (n,ClosedModule [])
| n, OpenedSection (op, _) ->
- Some(n,OpenedSection(op,Summary.empty_frozen))
- | n, ClosedSection _ -> Some (n,ClosedSection []))
+ Some(n,OpenedSection(op,Summary.empty_frozen)))
!lib_state.lib_stk in
{ !lib_state with lib_stk }
| _ ->
@@ -669,6 +645,14 @@ let discharge_kn kn =
let discharge_con cst =
if con_defined_in_sec cst then Globnames.pop_con cst else cst
+let discharge_proj_repr =
+ Projection.Repr.map_npars (fun mind npars ->
+ if not (defined_in_sec mind) then mind, npars
+ else
+ let modlist = replacement_context () in
+ let _, newpars = Mindmap.find mind (snd modlist) in
+ Globnames.pop_kn mind, npars + Array.length newpars)
+
let discharge_inductive (kn,i) =
(discharge_kn kn,i)
diff --git a/library/lib.mli b/library/lib.mli
index 26f1718c..9933b762 100644
--- a/library/lib.mli
+++ b/library/lib.mli
@@ -8,6 +8,7 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+open Names
(** Lib: record of operations, backtrack, low-level sections *)
@@ -22,13 +23,11 @@ type node =
| Leaf of Libobject.obj
| CompilingLibrary of Libnames.object_prefix
| OpenedModule of is_type * export * Libnames.object_prefix * Summary.frozen
- | ClosedModule of library_segment
| OpenedSection of Libnames.object_prefix * Summary.frozen
- | ClosedSection of library_segment
-and library_segment = (Libnames.object_name * node) list
+type library_segment = (Libnames.object_name * node) list
-type lib_objects = (Names.Id.t * Libobject.obj) list
+type lib_objects = (Id.t * Libobject.obj) list
(** {6 Object iteration functions. } *)
@@ -54,13 +53,13 @@ val segment_of_objects :
(** Adding operations (which call the [cache] method, and getting the
current list of operations (most recent ones coming first). *)
-val add_leaf : Names.Id.t -> Libobject.obj -> Libnames.object_name
+val add_leaf : Id.t -> Libobject.obj -> Libnames.object_name
val add_anonymous_leaf : ?cache_first:bool -> Libobject.obj -> unit
val pull_to_head : Libnames.object_name -> unit
(** this operation adds all objects with the same name and calls [load_object]
for each of them *)
-val add_leaves : Names.Id.t -> Libobject.obj list -> Libnames.object_name
+val add_leaves : Id.t -> Libobject.obj list -> Libnames.object_name
(** {6 ... } *)
@@ -76,15 +75,15 @@ val contents_after : Libnames.object_name -> library_segment
(** {6 Functions relative to current path } *)
(** User-side names *)
-val cwd : unit -> Names.DirPath.t
-val cwd_except_section : unit -> Names.DirPath.t
-val current_dirpath : bool -> Names.DirPath.t (* false = except sections *)
-val make_path : Names.Id.t -> Libnames.full_path
-val make_path_except_section : Names.Id.t -> Libnames.full_path
+val cwd : unit -> DirPath.t
+val cwd_except_section : unit -> DirPath.t
+val current_dirpath : bool -> DirPath.t (* false = except sections *)
+val make_path : Id.t -> Libnames.full_path
+val make_path_except_section : Id.t -> Libnames.full_path
(** Kernel-side names *)
-val current_mp : unit -> Names.ModPath.t
-val make_kn : Names.Id.t -> Names.KerName.t
+val current_mp : unit -> ModPath.t
+val make_kn : Id.t -> KerName.t
(** Are we inside an opened section *)
val sections_are_opened : unit -> bool
@@ -97,19 +96,19 @@ val is_modtype : unit -> bool
if the latest module started is a module type. *)
val is_modtype_strict : unit -> bool
val is_module : unit -> bool
-val current_mod_id : unit -> Names.module_ident
+val current_mod_id : unit -> module_ident
(** Returns the opening node of a given name *)
-val find_opening_node : Names.Id.t -> node
+val find_opening_node : Id.t -> node
(** {6 Modules and module types } *)
val start_module :
- export -> Names.module_ident -> Names.ModPath.t ->
+ export -> module_ident -> ModPath.t ->
Summary.frozen -> Libnames.object_prefix
val start_modtype :
- Names.module_ident -> Names.ModPath.t ->
+ module_ident -> ModPath.t ->
Summary.frozen -> Libnames.object_prefix
val end_module :
@@ -124,23 +123,23 @@ val end_modtype :
(** {6 Compilation units } *)
-val start_compilation : Names.DirPath.t -> Names.ModPath.t -> unit
-val end_compilation_checks : Names.DirPath.t -> Libnames.object_name
+val start_compilation : DirPath.t -> ModPath.t -> unit
+val end_compilation_checks : DirPath.t -> Libnames.object_name
val end_compilation :
Libnames.object_name-> Libnames.object_prefix * library_segment
(** The function [library_dp] returns the [DirPath.t] of the current
compiling library (or [default_library]) *)
-val library_dp : unit -> Names.DirPath.t
+val library_dp : unit -> DirPath.t
(** Extract the library part of a name even if in a section *)
-val dp_of_mp : Names.ModPath.t -> Names.DirPath.t
-val split_modpath : Names.ModPath.t -> Names.DirPath.t * Names.Id.t list
-val library_part : Globnames.global_reference -> Names.DirPath.t
+val dp_of_mp : ModPath.t -> DirPath.t
+val split_modpath : ModPath.t -> DirPath.t * Id.t list
+val library_part : GlobRef.t -> DirPath.t
(** {6 Sections } *)
-val open_section : Names.Id.t -> unit
+val open_section : Id.t -> unit
val close_section : unit -> unit
(** {6 We can get and set the state of the operations (used in [States]). } *)
@@ -153,7 +152,7 @@ val unfreeze : frozen -> unit
val init : unit -> unit
(** {6 Section management for discharge } *)
-type variable_info = Context.Named.Declaration.t * Decl_kinds.binding_kind
+type variable_info = Constr.named_declaration * Decl_kinds.binding_kind
type variable_context = variable_info list
type abstr_info = private {
abstr_ctx : variable_context;
@@ -164,31 +163,32 @@ type abstr_info = private {
(** Universe quantification, same length as the substitution *)
}
-val instance_from_variable_context : variable_context -> Names.Id.t array
-val named_of_variable_context : variable_context -> Context.Named.t
+val instance_from_variable_context : variable_context -> Id.t array
+val named_of_variable_context : variable_context -> Constr.named_context
-val section_segment_of_constant : Names.Constant.t -> abstr_info
-val section_segment_of_mutual_inductive: Names.MutInd.t -> abstr_info
-val section_segment_of_reference : Globnames.global_reference -> abstr_info
+val section_segment_of_constant : Constant.t -> abstr_info
+val section_segment_of_mutual_inductive: MutInd.t -> abstr_info
+val section_segment_of_reference : GlobRef.t -> abstr_info
-val variable_section_segment_of_reference : Globnames.global_reference -> variable_context
+val variable_section_segment_of_reference : GlobRef.t -> variable_context
-val section_instance : Globnames.global_reference -> Univ.Instance.t * Names.Id.t array
-val is_in_section : Globnames.global_reference -> bool
+val section_instance : GlobRef.t -> Univ.Instance.t * Id.t array
+val is_in_section : GlobRef.t -> bool
-val add_section_variable : Names.Id.t -> Decl_kinds.binding_kind -> Decl_kinds.polymorphic -> Univ.ContextSet.t -> unit
+val add_section_variable : Id.t -> Decl_kinds.binding_kind -> Decl_kinds.polymorphic -> Univ.ContextSet.t -> unit
val add_section_context : Univ.ContextSet.t -> unit
val add_section_constant : Decl_kinds.polymorphic ->
- Names.Constant.t -> Context.Named.t -> unit
+ Constant.t -> Constr.named_context -> unit
val add_section_kn : Decl_kinds.polymorphic ->
- Names.MutInd.t -> Context.Named.t -> unit
+ MutInd.t -> Constr.named_context -> unit
val replacement_context : unit -> Opaqueproof.work_list
(** {6 Discharge: decrease the section level if in the current section } *)
-val discharge_kn : Names.MutInd.t -> Names.MutInd.t
-val discharge_con : Names.Constant.t -> Names.Constant.t
-val discharge_global : Globnames.global_reference -> Globnames.global_reference
-val discharge_inductive : Names.inductive -> Names.inductive
+val discharge_kn : MutInd.t -> MutInd.t
+val discharge_con : Constant.t -> Constant.t
+val discharge_proj_repr : Projection.Repr.t -> Projection.Repr.t
+val discharge_global : GlobRef.t -> GlobRef.t
+val discharge_inductive : inductive -> inductive
val discharge_abstract_universe_context :
abstr_info -> Univ.AUContext.t -> Univ.universe_level_subst * Univ.AUContext.t
diff --git a/library/libnames.ml b/library/libnames.ml
index d8473132..23085048 100644
--- a/library/libnames.ml
+++ b/library/libnames.ml
@@ -15,8 +15,6 @@ open Names
(**********************************************)
-let pr_dirpath sl = DirPath.print sl
-
(*s Operations on dirpaths *)
let split_dirpath d = match DirPath.repr d with
@@ -80,8 +78,6 @@ let dirpath_of_string s =
in
DirPath.make path
-let string_of_dirpath = Names.DirPath.to_string
-
module Dirset = Set.Make(DirPath)
module Dirmap = Map.Make(DirPath)
@@ -138,23 +134,33 @@ let restrict_path n sp =
make_path (DirPath.make dir') s
(*s qualified names *)
-type qualid = full_path
+type qualid_r = full_path
+type qualid = qualid_r CAst.t
-let make_qualid = make_path
-let repr_qualid = repr_path
+let make_qualid ?loc pa id = CAst.make ?loc (make_path pa id)
+let repr_qualid {CAst.v=qid} = repr_path qid
-let qualid_eq = eq_full_path
+let qualid_eq qid1 qid2 = eq_full_path qid1.CAst.v qid2.CAst.v
-let string_of_qualid = string_of_path
-let pr_qualid = pr_path
+let string_of_qualid qid = string_of_path qid.CAst.v
+let pr_qualid qid = pr_path qid.CAst.v
-let qualid_of_string = path_of_string
+let qualid_of_string ?loc s = CAst.make ?loc @@ path_of_string s
-let qualid_of_path sp = sp
-let qualid_of_ident id = make_qualid DirPath.empty id
-let qualid_of_dirpath dir =
+let qualid_of_path ?loc sp = CAst.make ?loc sp
+let qualid_of_ident ?loc id = make_qualid ?loc DirPath.empty id
+let qualid_of_dirpath ?loc dir =
let (l,a) = split_dirpath dir in
- make_qualid l a
+ make_qualid ?loc l a
+
+let qualid_is_ident qid =
+ DirPath.is_empty qid.CAst.v.dirpath
+
+let qualid_basename qid =
+ qid.CAst.v.basename
+
+let qualid_path qid =
+ qid.CAst.v.dirpath
type object_name = full_path * KerName.t
@@ -174,8 +180,6 @@ type global_dir_reference =
| DirOpenModtype of object_prefix
| DirOpenSection of object_prefix
| DirModule of object_prefix
- | DirClosedSection of DirPath.t
- (* this won't last long I hope! *)
let eq_op op1 op2 =
DirPath.equal op1.obj_dir op2.obj_dir &&
@@ -187,55 +191,8 @@ let eq_global_dir_reference r1 r2 = match r1, r2 with
| DirOpenModtype op1, DirOpenModtype op2 -> eq_op op1 op2
| DirOpenSection op1, DirOpenSection op2 -> eq_op op1 op2
| DirModule op1, DirModule op2 -> eq_op op1 op2
-| DirClosedSection dp1, DirClosedSection dp2 -> DirPath.equal dp1 dp2
-| _ -> false
-
-type reference_r =
- | Qualid of qualid
- | Ident of Id.t
-type reference = reference_r CAst.t
-
-let qualid_of_reference = CAst.map (function
- | Qualid qid -> qid
- | Ident id -> qualid_of_ident id)
-
-let string_of_reference = CAst.with_val (function
- | Qualid qid -> string_of_qualid qid
- | Ident id -> Id.to_string id)
-
-let pr_reference = CAst.with_val (function
- | Qualid qid -> pr_qualid qid
- | Ident id -> Id.print id)
-
-let eq_reference {CAst.v=r1} {CAst.v=r2} = match r1, r2 with
-| Qualid q1, Qualid q2 -> qualid_eq q1 q2
-| Ident id1, Ident id2 -> Id.equal id1 id2
| _ -> false
-let join_reference {CAst.loc=l1;v=ns} {CAst.loc=l2;v=r} =
- CAst.make ?loc:(Loc.merge_opt l1 l2) (
- match ns , r with
- Qualid q1, Qualid q2 ->
- let (dp1,id1) = repr_qualid q1 in
- let (dp2,id2) = repr_qualid q2 in
- Qualid (make_qualid
- (append_dirpath (append_dirpath dp1 (dirpath_of_string (Names.Id.to_string id1))) dp2)
- id2)
- | Qualid q1, Ident id2 ->
- let (dp1,id1) = repr_qualid q1 in
- Qualid (make_qualid
- (append_dirpath dp1 (dirpath_of_string (Names.Id.to_string id1)))
- id2)
- | Ident id1, Qualid q2 ->
- let (dp2,id2) = repr_qualid q2 in
- Qualid (make_qualid
- (append_dirpath (dirpath_of_string (Names.Id.to_string id1)) dp2)
- id2)
- | Ident id1, Ident id2 ->
- Qualid (make_qualid
- (dirpath_of_string (Names.Id.to_string id1)) id2)
- )
-
(* Default paths *)
let default_library = Names.DirPath.initial (* = ["Top"] *)
@@ -243,8 +200,3 @@ let default_library = Names.DirPath.initial (* = ["Top"] *)
let coq_string = "Coq"
let coq_root = Id.of_string coq_string
let default_root_prefix = DirPath.empty
-
-(* Deprecated synonyms *)
-
-let make_short_qualid = qualid_of_ident
-let qualid_of_sp = qualid_of_path
diff --git a/library/libnames.mli b/library/libnames.mli
index 9dad2612..447eecbb 100644
--- a/library/libnames.mli
+++ b/library/libnames.mli
@@ -14,12 +14,6 @@ open Names
(** {6 Dirpaths } *)
val dirpath_of_string : string -> DirPath.t
-val pr_dirpath : DirPath.t -> Pp.t
-[@@ocaml.deprecated "Alias for DirPath.print"]
-
-val string_of_dirpath : DirPath.t -> string
-[@@ocaml.deprecated "Alias for DirPath.to_string"]
-
(** Pop the suffix of a [DirPath.t]. Raises a [Failure] for an empty path *)
val pop_dirpath : DirPath.t -> DirPath.t
@@ -71,23 +65,28 @@ val restrict_path : int -> full_path -> full_path
qualifications of absolute names, including single identifiers.
The [qualid] are used to access the name table. *)
-type qualid
+type qualid_r
+type qualid = qualid_r CAst.t
-val make_qualid : DirPath.t -> Id.t -> qualid
+val make_qualid : ?loc:Loc.t -> DirPath.t -> Id.t -> qualid
val repr_qualid : qualid -> DirPath.t * Id.t
val qualid_eq : qualid -> qualid -> bool
val pr_qualid : qualid -> Pp.t
val string_of_qualid : qualid -> string
-val qualid_of_string : string -> qualid
+val qualid_of_string : ?loc:Loc.t -> string -> qualid
(** Turns an absolute name, a dirpath, or an Id.t into a
qualified name denoting the same name *)
-val qualid_of_path : full_path -> qualid
-val qualid_of_dirpath : DirPath.t -> qualid
-val qualid_of_ident : Id.t -> qualid
+val qualid_of_path : ?loc:Loc.t -> full_path -> qualid
+val qualid_of_dirpath : ?loc:Loc.t -> DirPath.t -> qualid
+val qualid_of_ident : ?loc:Loc.t -> Id.t -> qualid
+
+val qualid_is_ident : qualid -> bool
+val qualid_path : qualid -> DirPath.t
+val qualid_basename : qualid -> Id.t
(** Both names are passed to objects: a "semantic" [kernel_name], which
can be substituted and a "syntactic" [full_path] which can be printed
@@ -125,27 +124,11 @@ type global_dir_reference =
| DirOpenModtype of object_prefix
| DirOpenSection of object_prefix
| DirModule of object_prefix
- | DirClosedSection of DirPath.t
- (** this won't last long I hope! *)
val eq_global_dir_reference :
global_dir_reference -> global_dir_reference -> bool
(** {6 ... } *)
-(** A [reference] is the user-level notion of name. It denotes either a
- global name (referred either by a qualified name or by a single
- name) or a variable *)
-
-type reference_r =
- | Qualid of qualid
- | Ident of Id.t
-type reference = reference_r CAst.t
-
-val eq_reference : reference -> reference -> bool
-val qualid_of_reference : reference -> qualid CAst.t
-val string_of_reference : reference -> string
-val pr_reference : reference -> Pp.t
-val join_reference : reference -> reference -> reference
(** some preset paths *)
val default_library : DirPath.t
@@ -157,10 +140,3 @@ val coq_string : string (** "Coq" *)
(** This is the default root prefix for developments which doesn't
mention a root *)
val default_root_prefix : DirPath.t
-
-(** Deprecated synonyms *)
-val make_short_qualid : Id.t -> qualid (** = qualid_of_ident *)
-[@@ocaml.deprecated "Alias for qualid_of_ident"]
-
-val qualid_of_sp : full_path -> qualid (** = qualid_of_path *)
-[@@ocaml.deprecated "Alias for qualid_of_sp"]
diff --git a/library/libobject.ml b/library/libobject.ml
index c5cd0152..79a3fed1 100644
--- a/library/libobject.ml
+++ b/library/libobject.ml
@@ -98,7 +98,7 @@ let declare_object_full odecl = declare_object_full odecl
(* this function describes how the cache, load, open, and export functions
are triggered. *)
-let apply_dyn_fun deflt f lobj =
+let apply_dyn_fun f lobj =
let tag = object_tag lobj in
let dodecl =
try Hashtbl.find cache_tab tag
@@ -107,24 +107,24 @@ let apply_dyn_fun deflt f lobj =
f dodecl
let cache_object ((_,lobj) as node) =
- apply_dyn_fun () (fun d -> d.dyn_cache_function node) lobj
+ apply_dyn_fun (fun d -> d.dyn_cache_function node) lobj
let load_object i ((_,lobj) as node) =
- apply_dyn_fun () (fun d -> d.dyn_load_function i node) lobj
+ apply_dyn_fun (fun d -> d.dyn_load_function i node) lobj
let open_object i ((_,lobj) as node) =
- apply_dyn_fun () (fun d -> d.dyn_open_function i node) lobj
+ apply_dyn_fun (fun d -> d.dyn_open_function i node) lobj
let subst_object ((_,lobj) as node) =
- apply_dyn_fun lobj (fun d -> d.dyn_subst_function node) lobj
+ apply_dyn_fun (fun d -> d.dyn_subst_function node) lobj
let classify_object lobj =
- apply_dyn_fun Dispose (fun d -> d.dyn_classify_function lobj) lobj
+ apply_dyn_fun (fun d -> d.dyn_classify_function lobj) lobj
let discharge_object ((_,lobj) as node) =
- apply_dyn_fun None (fun d -> d.dyn_discharge_function node) lobj
+ apply_dyn_fun (fun d -> d.dyn_discharge_function node) lobj
let rebuild_object lobj =
- apply_dyn_fun lobj (fun d -> d.dyn_rebuild_function lobj) lobj
+ apply_dyn_fun (fun d -> d.dyn_rebuild_function lobj) lobj
let dump = Dyn.dump
diff --git a/library/library.ml b/library/library.ml
index 56d2709d..0ff82d7c 100644
--- a/library/library.ml
+++ b/library/library.ml
@@ -167,7 +167,7 @@ let opened_libraries () = !libraries_imports_list
let register_loaded_library m =
let libname = m.libsum_name in
- let link m =
+ let link () =
let dirname = Filename.dirname (library_full_filename libname) in
let prefix = Nativecode.mod_uid_of_dirpath libname ^ "." in
let f = prefix ^ "cmo" in
@@ -176,7 +176,7 @@ let register_loaded_library m =
Nativelib.link_library ~prefix ~dirname ~basename:f
in
let rec aux = function
- | [] -> link m; [libname]
+ | [] -> link (); [libname]
| m'::_ as l when DirPath.equal m' libname -> l
| m'::l' -> m' :: aux l' in
libraries_loaded_list := aux !libraries_loaded_list;
@@ -288,16 +288,15 @@ let locate_absolute_library dir =
try
let name = Id.to_string base ^ ext in
let _, file = System.where_in_path ~warn:false loadpath name in
- [file]
- with Not_found -> [] in
- match find ".vo" @ find ".vio" with
- | [] -> raise LibNotFound
- | [file] -> file
- | [vo;vi] when Unix.((stat vo).st_mtime < (stat vi).st_mtime) ->
+ Some file
+ with Not_found -> None in
+ match find ".vo", find ".vio" with
+ | None, None -> raise LibNotFound
+ | Some file, None | None, Some file -> file
+ | Some vo, Some vi when Unix.((stat vo).st_mtime < (stat vi).st_mtime) ->
warn_several_object_files (vi, vo);
vi
- | [vo;vi] -> vo
- | _ -> assert false
+ | Some vo, Some _ -> vo
let locate_qualified_library ?root ?(warn = true) qid =
(* Search library in loadpath *)
@@ -309,18 +308,17 @@ let locate_qualified_library ?root ?(warn = true) qid =
let name = Id.to_string base ^ ext in
let lpath, file =
System.where_in_path ~warn (List.map fst loadpath) name in
- [lpath, file]
- with Not_found -> [] in
+ Some (lpath, file)
+ with Not_found -> None in
let lpath, file =
- match find ".vo" @ find ".vio" with
- | [] -> raise LibNotFound
- | [lpath, file] -> lpath, file
- | [lpath_vo, vo; lpath_vi, vi]
+ match find ".vo", find ".vio" with
+ | None, None -> raise LibNotFound
+ | Some res, None | None, Some res -> res
+ | Some (_, vo), Some (_, vi as resvi)
when Unix.((stat vo).st_mtime < (stat vi).st_mtime) ->
warn_several_object_files (vi, vo);
- lpath_vi, vi
- | [lpath_vo, vo; _ ] -> lpath_vo, vo
- | _ -> assert false
+ resvi
+ | Some resvo, Some _ -> resvo
in
let dir = add_dirpath_suffix (String.List.assoc lpath loadpath) base in
(* Look if loaded *)
@@ -577,10 +575,10 @@ let require_library_from_dirpath modrefl export =
(* the function called by Vernacentries.vernac_import *)
-let safe_locate_module {CAst.loc;v=qid} =
+let safe_locate_module qid =
try Nametab.locate_module qid
with Not_found ->
- user_err ?loc ~hdr:"import_library"
+ user_err ?loc:qid.CAst.loc ~hdr:"import_library"
(pr_qualid qid ++ str " is not a module")
let import_module export modl =
@@ -595,18 +593,18 @@ let import_module export modl =
| [] -> ()
| modl -> add_anonymous_leaf (in_import_library (List.rev modl, export)) in
let rec aux acc = function
- | ({CAst.loc; v=dir} as m) :: l ->
+ | qid :: l ->
let m,acc =
- try Nametab.locate_module dir, acc
- with Not_found-> flush acc; safe_locate_module m, [] in
+ try Nametab.locate_module qid, acc
+ with Not_found-> flush acc; safe_locate_module qid, [] in
(match m with
| MPfile dir -> aux (dir::acc) l
| mp ->
flush acc;
try Declaremods.import_module export mp; aux [] l
with Not_found ->
- user_err ?loc ~hdr:"import_library"
- (pr_qualid dir ++ str " is not a module"))
+ user_err ?loc:qid.CAst.loc ~hdr:"import_library"
+ (pr_qualid qid ++ str " is not a module"))
| [] -> flush acc
in aux [] modl
diff --git a/library/library.mli b/library/library.mli
index 0877ebb5..d5815afc 100644
--- a/library/library.mli
+++ b/library/library.mli
@@ -36,7 +36,7 @@ type seg_proofs = Constr.constr Future.computation array
(** Open a module (or a library); if the boolean is true then it's also
an export otherwise just a simple import *)
-val import_module : bool -> qualid CAst.t list -> unit
+val import_module : bool -> qualid list -> unit
(** Start the compilation of a file as a library. The first argument must be
output file, and the
diff --git a/library/library.mllib b/library/library.mllib
index e43bfb5a..9cacaba4 100644
--- a/library/library.mllib
+++ b/library/library.mllib
@@ -4,6 +4,7 @@ Libobject
Summary
Nametab
Global
+Decl_kinds
Lib
Declaremods
Loadpath
@@ -13,6 +14,5 @@ Kindops
Dischargedhypsmap
Goptions
Decls
-Heads
Keys
Coqlib
diff --git a/library/nametab.ml b/library/nametab.ml
index 2046bf75..a3b3ca6e 100644
--- a/library/nametab.ml
+++ b/library/nametab.ml
@@ -18,8 +18,8 @@ open Globnames
exception GlobalizationError of qualid
-let error_global_not_found {CAst.loc;v} =
- Loc.raise ?loc (GlobalizationError v)
+let error_global_not_found qid =
+ Loc.raise ?loc:qid.CAst.loc (GlobalizationError qid)
(* The visibility can be registered either
- for all suffixes not shorter then a given int - when the object
@@ -69,7 +69,7 @@ module type NAMETREE = sig
val find : user_name -> t -> elt
val exists : user_name -> t -> bool
val user_name : qualid -> t -> user_name
- val shortest_qualid : Id.Set.t -> user_name -> t -> qualid
+ val shortest_qualid : ?loc:Loc.t -> Id.Set.t -> user_name -> t -> qualid
val find_prefixes : qualid -> t -> elt list
end
@@ -220,7 +220,7 @@ let exists uname tab =
with
Not_found -> false
-let shortest_qualid ctx uname tab =
+let shortest_qualid ?loc ctx uname tab =
let id,dir = U.repr uname in
let hidden = Id.Set.mem id ctx in
let rec find_uname pos dir tree =
@@ -235,7 +235,7 @@ let shortest_qualid ctx uname tab =
in
let ptab = Id.Map.find id tab in
let found_dir = find_uname [] dir ptab in
- make_qualid (DirPath.make found_dir) id
+ make_qualid ?loc (DirPath.make found_dir) id
let push_node node l =
match node with
@@ -432,7 +432,6 @@ let full_name_module qid =
let locate_section qid =
match locate_dir qid with
| DirOpenSection { obj_dir; _ } -> obj_dir
- | DirClosedSection dir -> dir
| _ -> raise Not_found
let locate_all qid =
@@ -459,14 +458,13 @@ let global_of_path sp =
let extended_global_of_path sp = ExtRefTab.find sp !the_ccitab
-let global ({CAst.loc;v=r} as lr)=
- let {CAst.loc; v} as qid = qualid_of_reference lr in
- try match locate_extended v with
+let global qid =
+ try match locate_extended qid with
| TrueGlobal ref -> ref
| SynDef _ ->
- user_err ?loc ~hdr:"global"
+ user_err ?loc:qid.CAst.loc ~hdr:"global"
(str "Unexpected reference to a notation: " ++
- pr_qualid v)
+ pr_qualid qid)
with Not_found ->
error_global_not_found qid
@@ -511,40 +509,40 @@ let path_of_universe mp =
(* Shortest qualid functions **********************************************)
-let shortest_qualid_of_global ctx ref =
+let shortest_qualid_of_global ?loc ctx ref =
match ref with
- | VarRef id -> make_qualid DirPath.empty id
+ | VarRef id -> make_qualid ?loc DirPath.empty id
| _ ->
let sp = Globrevtab.find (TrueGlobal ref) !the_globrevtab in
- ExtRefTab.shortest_qualid ctx sp !the_ccitab
+ ExtRefTab.shortest_qualid ?loc ctx sp !the_ccitab
-let shortest_qualid_of_syndef ctx kn =
+let shortest_qualid_of_syndef ?loc ctx kn =
let sp = path_of_syndef kn in
- ExtRefTab.shortest_qualid ctx sp !the_ccitab
+ ExtRefTab.shortest_qualid ?loc ctx sp !the_ccitab
-let shortest_qualid_of_module mp =
+let shortest_qualid_of_module ?loc mp =
let dir = MPmap.find mp !the_modrevtab in
- DirTab.shortest_qualid Id.Set.empty dir !the_dirtab
+ DirTab.shortest_qualid ?loc Id.Set.empty dir !the_dirtab
-let shortest_qualid_of_modtype kn =
+let shortest_qualid_of_modtype ?loc kn =
let sp = MPmap.find kn !the_modtyperevtab in
- MPTab.shortest_qualid Id.Set.empty sp !the_modtypetab
+ MPTab.shortest_qualid ?loc Id.Set.empty sp !the_modtypetab
-let shortest_qualid_of_universe kn =
+let shortest_qualid_of_universe ?loc kn =
let sp = UnivIdMap.find kn !the_univrevtab in
- UnivTab.shortest_qualid Id.Set.empty sp !the_univtab
+ UnivTab.shortest_qualid ?loc Id.Set.empty sp !the_univtab
let pr_global_env env ref =
try pr_qualid (shortest_qualid_of_global env ref)
with Not_found as e ->
if !Flags.debug then Feedback.msg_debug (Pp.str "pr_global_env not found"); raise e
-let global_inductive ({CAst.loc; v=r} as lr) =
- match global lr with
+let global_inductive qid =
+ match global qid with
| IndRef ind -> ind
| ref ->
- user_err ?loc ~hdr:"global_inductive"
- (pr_reference lr ++ spc () ++ str "is not an inductive type")
+ user_err ?loc:qid.CAst.loc ~hdr:"global_inductive"
+ (pr_qualid qid ++ spc () ++ str "is not an inductive type")
(********************************************************************)
diff --git a/library/nametab.mli b/library/nametab.mli
index cd28518a..57e9141d 100644
--- a/library/nametab.mli
+++ b/library/nametab.mli
@@ -61,7 +61,7 @@ open Globnames
exception GlobalizationError of qualid
(** Raises a globalization error *)
-val error_global_not_found : qualid CAst.t -> 'a
+val error_global_not_found : qualid -> 'a
(** {6 Register visibility of things } *)
@@ -75,7 +75,7 @@ val error_global_not_found : qualid CAst.t -> 'a
type visibility = Until of int | Exactly of int
-val push : visibility -> full_path -> global_reference -> unit
+val push : visibility -> full_path -> GlobRef.t -> unit
val push_modtype : visibility -> full_path -> ModPath.t -> unit
val push_dir : visibility -> DirPath.t -> global_dir_reference -> unit
val push_syndef : visibility -> full_path -> syndef_name -> unit
@@ -91,7 +91,7 @@ val push_universe : visibility -> full_path -> universe_id -> unit
(** These functions globalize a (partially) qualified name or fail with
[Not_found] *)
-val locate : qualid -> global_reference
+val locate : qualid -> GlobRef.t
val locate_extended : qualid -> extended_global_reference
val locate_constant : qualid -> Constant.t
val locate_syndef : qualid -> syndef_name
@@ -105,20 +105,20 @@ val locate_universe : qualid -> universe_id
references, like [locate] and co, but raise a nice error message
in case of failure *)
-val global : reference -> global_reference
-val global_inductive : reference -> inductive
+val global : qualid -> GlobRef.t
+val global_inductive : qualid -> inductive
(** These functions locate all global references with a given suffix;
if [qualid] is valid as such, it comes first in the list *)
-val locate_all : qualid -> global_reference list
+val locate_all : qualid -> GlobRef.t list
val locate_extended_all : qualid -> extended_global_reference list
val locate_extended_all_dir : qualid -> global_dir_reference list
val locate_extended_all_modtype : qualid -> ModPath.t list
(** Mapping a full path to a global reference *)
-val global_of_path : full_path -> global_reference
+val global_of_path : full_path -> GlobRef.t
val extended_global_of_path : full_path -> extended_global_reference
(** {6 These functions tell if the given absolute name is already taken } *)
@@ -144,7 +144,7 @@ val full_name_module : qualid -> DirPath.t
definition, and the (full) dirpath associated to a module path *)
val path_of_syndef : syndef_name -> full_path
-val path_of_global : global_reference -> full_path
+val path_of_global : GlobRef.t -> full_path
val dirpath_of_module : ModPath.t -> DirPath.t
val path_of_modtype : ModPath.t -> full_path
@@ -155,12 +155,12 @@ val path_of_universe : universe_id -> full_path
(** Returns in particular the dirpath or the basename of the full path
associated to global reference *)
-val dirpath_of_global : global_reference -> DirPath.t
-val basename_of_global : global_reference -> Id.t
+val dirpath_of_global : GlobRef.t -> DirPath.t
+val basename_of_global : GlobRef.t -> Id.t
(** Printing of global references using names as short as possible.
@raise Not_found when the reference is not in the global tables. *)
-val pr_global_env : Id.Set.t -> global_reference -> Pp.t
+val pr_global_env : Id.Set.t -> GlobRef.t -> Pp.t
(** The [shortest_qualid] functions given an object with [user_name]
@@ -168,16 +168,16 @@ val pr_global_env : Id.Set.t -> global_reference -> Pp.t
Coq.A.B.x that denotes the same object.
@raise Not_found for unknown objects. *)
-val shortest_qualid_of_global : Id.Set.t -> global_reference -> qualid
-val shortest_qualid_of_syndef : Id.Set.t -> syndef_name -> qualid
-val shortest_qualid_of_modtype : ModPath.t -> qualid
-val shortest_qualid_of_module : ModPath.t -> qualid
-val shortest_qualid_of_universe : universe_id -> qualid
+val shortest_qualid_of_global : ?loc:Loc.t -> Id.Set.t -> GlobRef.t -> qualid
+val shortest_qualid_of_syndef : ?loc:Loc.t -> Id.Set.t -> syndef_name -> qualid
+val shortest_qualid_of_modtype : ?loc:Loc.t -> ModPath.t -> qualid
+val shortest_qualid_of_module : ?loc:Loc.t -> ModPath.t -> qualid
+val shortest_qualid_of_universe : ?loc:Loc.t -> universe_id -> qualid
(** Deprecated synonyms *)
val extended_locate : qualid -> extended_global_reference (*= locate_extended *)
-val absolute_reference : full_path -> global_reference (** = global_of_path *)
+val absolute_reference : full_path -> GlobRef.t (** = global_of_path *)
(** {5 Generic name handling} *)
@@ -207,7 +207,7 @@ module type NAMETREE = sig
val find : user_name -> t -> elt
val exists : user_name -> t -> bool
val user_name : qualid -> t -> user_name
- val shortest_qualid : Id.Set.t -> user_name -> t -> qualid
+ val shortest_qualid : ?loc:Loc.t -> Id.Set.t -> user_name -> t -> qualid
val find_prefixes : qualid -> t -> elt list
end
diff --git a/library/summary.ml b/library/summary.ml
index 7ef19fbf..9b229459 100644
--- a/library/summary.ml
+++ b/library/summary.ml
@@ -75,20 +75,6 @@ let freeze_summaries ~marshallable : frozen =
ml_module = Option.map (fun decl -> decl.freeze_function marshallable) !sum_mod;
}
-let unfreeze_single name state =
- let decl =
- try String.Map.find name !sum_map
- with
- | Not_found ->
- CErrors.anomaly Pp.(str "trying to unfreeze unregistered summary " ++ str name)
- in
- try decl.unfreeze_function state
- with e when CErrors.noncritical e ->
- let e = CErrors.push e in
- Feedback.msg_warning
- Pp.(seq [str "Error unfreezing summary "; str name; fnl (); CErrors.iprint e]);
- iraise e
-
let warn_summary_out_of_scope =
let name = "summary-out-of-scope" in
let category = "dev" in
@@ -142,36 +128,6 @@ let remove_from_summary st tag =
let summaries = String.Map.remove id st.summaries in
{st with summaries}
-(** Selective freeze *)
-
-type frozen_bits = Dyn.t String.Map.t
-
-let freeze_summary ~marshallable ?(complement=false) ids =
- let sub_map = String.Map.filter (fun id _ -> complement <> List.(mem id ids)) !sum_map in
- String.Map.map (fun decl -> decl.freeze_function marshallable) sub_map
-
-let unfreeze_summary = String.Map.iter unfreeze_single
-
-let surgery_summary { summaries; ml_module } bits =
- let summaries =
- String.Map.fold (fun hash state sum -> String.Map.set hash state sum ) summaries bits in
- { summaries; ml_module }
-
-let project_summary { summaries; ml_module } ?(complement=false) ids =
- String.Map.filter (fun name _ -> complement <> List.(mem name ids)) summaries
-
-let pointer_equal l1 l2 =
- let ptr_equal d1 d2 =
- let Dyn.Dyn (t1, x1) = d1 in
- let Dyn.Dyn (t2, x2) = d2 in
- match Dyn.eq t1 t2 with
- | None -> false
- | Some Refl -> x1 == x2
- in
- let l1, l2 = String.Map.bindings l1, String.Map.bindings l2 in
- CList.for_all2eq
- (fun (id1,v1) (id2,v2) -> id1 = id2 && ptr_equal v1 v2) l1 l2
-
(** All-in-one reference declaration + registration *)
let ref_tag ?(freeze=fun _ r -> r) ~name x =
diff --git a/library/summary.mli b/library/summary.mli
index ed6c26b1..7d91a791 100644
--- a/library/summary.mli
+++ b/library/summary.mli
@@ -91,25 +91,5 @@ val modify_summary : frozen -> 'a Dyn.tag -> 'a -> frozen
val project_from_summary : frozen -> 'a Dyn.tag -> 'a
val remove_from_summary : frozen -> 'a Dyn.tag -> frozen
-(** The type [frozen_bits] is a snapshot of some of the registered
- tables. It is DEPRECATED in favor of the typed projection
- version. *)
-
-type frozen_bits
-[@@ocaml.deprecated "Please use the typed version of summary projection"]
-
-[@@@ocaml.warning "-3"]
-val freeze_summary : marshallable:marshallable -> ?complement:bool -> string list -> frozen_bits
-[@@ocaml.deprecated "Please use the typed version of summary projection"]
-val unfreeze_summary : frozen_bits -> unit
-[@@ocaml.deprecated "Please use the typed version of summary projection"]
-val surgery_summary : frozen -> frozen_bits -> frozen
-[@@ocaml.deprecated "Please use the typed version of summary projection"]
-val project_summary : frozen -> ?complement:bool -> string list -> frozen_bits
-[@@ocaml.deprecated "Please use the typed version of summary projection"]
-val pointer_equal : frozen_bits -> frozen_bits -> bool
-[@@ocaml.deprecated "Please use the typed version of summary projection"]
-[@@@ocaml.warning "+3"]
-
(** {6 Debug} *)
val dump : unit -> (int * string) list
diff --git a/man/gallina.1 b/man/gallina.1
deleted file mode 100644
index f8879c45..00000000
--- a/man/gallina.1
+++ /dev/null
@@ -1,74 +0,0 @@
-.TH COQ 1 "29 March 1995" "Coq tools"
-
-.SH NAME
-gallina \- extracts specification from Coq vernacular files
-
-.SH SYNOPSIS
-.B gallina
-[
-.BI \-
-]
-[
-.BI \-stdout
-]
-[
-.BI \-nocomments
-]
-.I file ...
-
-.SH DESCRIPTION
-
-.B gallina
-takes Coq files as arguments and builds the corresponding
-specification files.
-The Coq file
-.IR foo.v \&
-gives bearth to the specification file
-.IR foo.g. \&
-The suffix '.g' stands for Gallina.
-
-For that purpose, gallina removes all commands that follow a
-"Theorem", "Lemma", "Fact", "Remark" or "Goal" statement until it
-reaches a command "Abort.", "Qed.", "Defined." or "Proof
-<...>.". It also removes every "Hint", "Syntax",
-"Immediate" or "Transparent" command.
-
-Files without the .v suffix are ignored.
-
-
-.SH OPTIONS
-
-.TP
-.BI \-stdout
-Prints the result on standard output.
-.TP
-.BI \-
-Coq source is taken on standard input. The result is printed on
-standard output.
-.TP
-.BI \-nocomments
-Comments are removed in the *.g file.
-
-.SH NOTES
-
-Nested comments are correctly handled. In particular, every command
-"Qed." or "Abort." in a comment is not taken into account.
-
-
-.SH BUGS
-
-Please report any bug to
-.B coq@pauillac.inria.fr
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/intf/extend.ml b/parsing/extend.ml
index 734b859f..6fe29566 100644
--- a/intf/extend.ml
+++ b/parsing/extend.ml
@@ -31,22 +31,15 @@ type production_level =
| NextLevel
| NumLevel of int
-type constr_as_binder_kind =
- | AsIdent
- | AsIdentOrPattern
- | AsStrictPattern
-
(** User-level types used to tell how to parse or interpret of the non-terminal *)
type 'a constr_entry_key_gen =
- | ETName
- | ETReference
+ | ETIdent
+ | ETGlobal
| ETBigint
| ETBinder of bool (* open list of binders if true, closed list of binders otherwise *)
- | ETConstr of 'a
- | ETConstrAsBinder of constr_as_binder_kind * 'a
+ | ETConstr of Constrexpr.notation_entry * Notation_term.constr_as_binder_kind option * 'a
| ETPattern of bool * int option (* true = strict pattern, i.e. not a single variable *)
- | ETOther of string * string
(** Entries level (left-hand side of grammar rules) *)
@@ -68,9 +61,8 @@ type constr_prod_entry_key =
| ETProdName (* Parsed as a name (ident or _) *)
| ETProdReference (* Parsed as a global reference *)
| ETProdBigint (* Parsed as an (unbounded) integer *)
- | ETProdConstr of (production_level * production_position) (* Parsed as constr or pattern *)
+ | ETProdConstr of Constrexpr.notation_entry * (production_level * production_position) (* Parsed as constr or pattern, or a subentry of those *)
| ETProdPattern of int (* Parsed as pattern as a binder (as subpart of a constr) *)
- | ETProdOther of string * string (* Intended for embedding custom entries in constr or pattern *)
| ETProdConstrList of (production_level * production_position) * Tok.t list (* Parsed as non-empty list of constr *)
| ETProdBinderList of binder_entry_kind (* Parsed as non-empty list of local binders *)
@@ -106,7 +98,7 @@ type ('self, 'a) symbol =
| Aself : ('self, 'self) symbol
| Anext : ('self, 'self) symbol
| Aentry : 'a entry -> ('self, 'a) symbol
-| Aentryl : 'a entry * int -> ('self, 'a) symbol
+| Aentryl : 'a entry * string -> ('self, 'a) symbol
| Arules : 'a rules list -> ('self, 'a) symbol
and ('self, _, 'r) rule =
@@ -121,7 +113,7 @@ and 'a rules =
type 'a production_rule =
| Rule : ('a, 'act, Loc.t -> 'a) rule * 'act -> 'a production_rule
-type 'a single_extend_statment =
+type 'a single_extend_statement =
string option *
(** Level *)
gram_assoc option *
@@ -129,6 +121,6 @@ type 'a single_extend_statment =
'a production_rule list
(** Symbol list with the interpretation function *)
-type 'a extend_statment =
+type 'a extend_statement =
gram_position option *
- 'a single_extend_statment list
+ 'a single_extend_statement list
diff --git a/parsing/g_constr.ml4 b/parsing/g_constr.mlg
index 59b74545..7cb5af78 100644
--- a/parsing/g_constr.ml4
+++ b/parsing/g_constr.mlg
@@ -8,13 +8,17 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Names
+open Constr
open Libnames
+open Glob_term
open Constrexpr
open Constrexpr_ops
open Util
open Tok
-open Misctypes
+open Namegen
open Decl_kinds
open Pcoq
@@ -124,396 +128,399 @@ let name_colon =
let aliasvar = function { CAst.v = CPatAlias (_, na) } -> Some na | _ -> None
-GEXTEND Gram
+}
+
+GRAMMAR EXTEND Gram
GLOBAL: binder_constr lconstr constr operconstr universe_level sort sort_family
global constr_pattern lconstr_pattern Constr.ident
closed_binder open_binders binder binders binders_fixannot
record_declaration typeclass_constraint pattern appl_arg;
Constr.ident:
- [ [ id = Prim.ident -> id ] ]
+ [ [ id = Prim.ident -> { id } ] ]
;
Prim.name:
- [ [ "_" -> CAst.make ~loc:!@loc Anonymous ] ]
+ [ [ "_" -> { CAst.make ~loc Anonymous } ] ]
;
global:
- [ [ r = Prim.reference -> r ] ]
+ [ [ r = Prim.reference -> { r } ] ]
;
constr_pattern:
- [ [ c = constr -> c ] ]
+ [ [ c = constr -> { c } ] ]
;
lconstr_pattern:
- [ [ c = lconstr -> c ] ]
+ [ [ c = lconstr -> { c } ] ]
;
sort:
- [ [ "Set" -> GSet
- | "Prop" -> GProp
- | "Type" -> GType []
- | "Type"; "@{"; u = universe; "}" -> GType u
+ [ [ "Set" -> { GSet }
+ | "Prop" -> { GProp }
+ | "Type" -> { GType [] }
+ | "Type"; "@{"; u = universe; "}" -> { GType u }
] ]
;
sort_family:
- [ [ "Set" -> Sorts.InSet
- | "Prop" -> Sorts.InProp
- | "Type" -> Sorts.InType
+ [ [ "Set" -> { Sorts.InSet }
+ | "Prop" -> { Sorts.InProp }
+ | "Type" -> { Sorts.InType }
] ]
;
universe_expr:
- [ [ id = global; "+"; n = natural -> Some (id,n)
- | id = global -> Some (id,0)
- | "_" -> None
+ [ [ id = global; "+"; n = natural -> { Some (id,n) }
+ | id = global -> { Some (id,0) }
+ | "_" -> { None }
] ]
;
universe:
- [ [ IDENT "max"; "("; ids = LIST1 universe_expr SEP ","; ")" -> ids
- | u = universe_expr -> [u]
+ [ [ IDENT "max"; "("; ids = LIST1 universe_expr SEP ","; ")" -> { ids }
+ | u = universe_expr -> { [u] }
] ]
;
lconstr:
- [ [ c = operconstr LEVEL "200" -> c ] ]
+ [ [ c = operconstr LEVEL "200" -> { c } ] ]
;
constr:
- [ [ c = operconstr LEVEL "8" -> c
- | "@"; f=global; i = instance -> CAst.make ~loc:!@loc @@ CAppExpl((None,f,i),[]) ] ]
+ [ [ c = operconstr LEVEL "8" -> { c }
+ | "@"; f=global; i = instance -> { CAst.make ~loc @@ CAppExpl((None,f,i),[]) } ] ]
;
operconstr:
[ "200" RIGHTA
- [ c = binder_constr -> c ]
+ [ c = binder_constr -> { c } ]
| "100" RIGHTA
[ c1 = operconstr; "<:"; c2 = binder_constr ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastVM c2)
+ { CAst.make ~loc @@ CCast(c1, CastVM c2) }
| c1 = operconstr; "<:"; c2 = SELF ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastVM c2)
+ { CAst.make ~loc @@ CCast(c1, CastVM c2) }
| c1 = operconstr; "<<:"; c2 = binder_constr ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastNative c2)
+ { CAst.make ~loc @@ CCast(c1, CastNative c2) }
| c1 = operconstr; "<<:"; c2 = SELF ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastNative c2)
+ { CAst.make ~loc @@ CCast(c1, CastNative c2) }
| c1 = operconstr; ":";c2 = binder_constr ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastConv c2)
+ { CAst.make ~loc @@ CCast(c1, CastConv c2) }
| c1 = operconstr; ":"; c2 = SELF ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastConv c2)
+ { CAst.make ~loc @@ CCast(c1, CastConv c2) }
| c1 = operconstr; ":>" ->
- CAst.make ~loc:(!@loc) @@ CCast(c1, CastCoerce) ]
+ { CAst.make ~loc @@ CCast(c1, CastCoerce) } ]
| "99" RIGHTA [ ]
| "90" RIGHTA [ ]
| "10" LEFTA
- [ f=operconstr; args=LIST1 appl_arg -> CAst.make ~loc:(!@loc) @@ CApp((None,f),args)
- | "@"; f=global; i = instance; args=LIST0 NEXT -> CAst.make ~loc:!@loc @@ CAppExpl((None,f,i),args)
+ [ f=operconstr; args=LIST1 appl_arg -> { CAst.make ~loc @@ CApp((None,f),args) }
+ | "@"; f=global; i = instance; args=LIST0 NEXT -> { CAst.make ~loc @@ CAppExpl((None,f,i),args) }
| "@"; lid = pattern_identref; args=LIST1 identref ->
- let { CAst.loc = locid; v = id } = lid in
- let args = List.map (fun x -> CAst.make @@ CRef (CAst.make ?loc:x.CAst.loc @@ Ident x.CAst.v, None), None) args in
- CAst.make ~loc:(!@loc) @@ CApp((None, CAst.make ?loc:locid @@ CPatVar id),args) ]
+ { let { CAst.loc = locid; v = id } = lid in
+ let args = List.map (fun x -> CAst.make @@ CRef (qualid_of_ident ?loc:x.CAst.loc x.CAst.v, None), None) args in
+ CAst.make ~loc @@ CApp((None, CAst.make ?loc:locid @@ CPatVar id),args) } ]
| "9"
[ ".."; c = operconstr LEVEL "0"; ".." ->
- CAst.make ~loc:!@loc @@ CAppExpl ((None, CAst.make ~loc:!@loc @@ Ident ldots_var, None),[c]) ]
+ { CAst.make ~loc @@ CAppExpl ((None, (qualid_of_ident ~loc ldots_var), None),[c]) } ]
| "8" [ ]
| "1" LEFTA
[ c=operconstr; ".("; f=global; args=LIST0 appl_arg; ")" ->
- CAst.make ~loc:(!@loc) @@ CApp((Some (List.length args+1), CAst.make @@ CRef (f,None)),args@[c,None])
+ { CAst.make ~loc @@ CApp((Some (List.length args+1), CAst.make @@ CRef (f,None)),args@[c,None]) }
| c=operconstr; ".("; "@"; f=global;
args=LIST0 (operconstr LEVEL "9"); ")" ->
- CAst.make ~loc:(!@loc) @@ CAppExpl((Some (List.length args+1),f,None),args@[c])
- | c=operconstr; "%"; key=IDENT -> CAst.make ~loc:(!@loc) @@ CDelimiters (key,c) ]
+ { CAst.make ~loc @@ CAppExpl((Some (List.length args+1),f,None),args@[c]) }
+ | c=operconstr; "%"; key=IDENT -> { CAst.make ~loc @@ CDelimiters (key,c) } ]
| "0"
- [ c=atomic_constr -> c
- | c=match_constr -> c
+ [ c=atomic_constr -> { c }
+ | c=match_constr -> { c }
| "("; c = operconstr LEVEL "200"; ")" ->
- (match c.CAst.v with
+ { (match c.CAst.v with
| CPrim (Numeral (n,true)) ->
- CAst.make ~loc:(!@loc) @@ CNotation("( _ )",([c],[],[],[]))
- | _ -> c)
- | "{|"; c = record_declaration; "|}" -> c
+ CAst.make ~loc @@ CNotation((InConstrEntrySomeLevel,"( _ )"),([c],[],[],[]))
+ | _ -> c) }
+ | "{|"; c = record_declaration; "|}" -> { c }
| "{"; c = binder_constr ; "}" ->
- CAst.make ~loc:(!@loc) @@ CNotation(("{ _ }"),([c],[],[],[]))
+ { CAst.make ~loc @@ CNotation((InConstrEntrySomeLevel,"{ _ }"),([c],[],[],[])) }
| "`{"; c = operconstr LEVEL "200"; "}" ->
- CAst.make ~loc:(!@loc) @@ CGeneralization (Implicit, None, c)
+ { CAst.make ~loc @@ CGeneralization (Implicit, None, c) }
| "`("; c = operconstr LEVEL "200"; ")" ->
- CAst.make ~loc:(!@loc) @@ CGeneralization (Explicit, None, c)
+ { CAst.make ~loc @@ CGeneralization (Explicit, None, c) }
] ]
;
record_declaration:
- [ [ fs = record_fields -> CAst.make ~loc:(!@loc) @@ CRecord fs ] ]
+ [ [ fs = record_fields -> { CAst.make ~loc @@ CRecord fs } ] ]
;
record_fields:
- [ [ f = record_field_declaration; ";"; fs = record_fields -> f :: fs
- | f = record_field_declaration -> [f]
- | -> []
+ [ [ f = record_field_declaration; ";"; fs = record_fields -> { f :: fs }
+ | f = record_field_declaration -> { [f] }
+ | -> { [] }
] ]
;
record_field_declaration:
[ [ id = global; bl = binders; ":="; c = lconstr ->
- (id, if bl = [] then c else mkCLambdaN ~loc:!@loc bl c) ] ]
+ { (id, if bl = [] then c else mkCLambdaN ~loc bl c) } ] ]
;
binder_constr:
[ [ "forall"; bl = open_binders; ","; c = operconstr LEVEL "200" ->
- mkCProdN ~loc:!@loc bl c
+ { mkCProdN ~loc bl c }
| "fun"; bl = open_binders; "=>"; c = operconstr LEVEL "200" ->
- mkCLambdaN ~loc:!@loc bl c
+ { mkCLambdaN ~loc bl c }
| "let"; id=name; bl = binders; ty = type_cstr; ":=";
c1 = operconstr LEVEL "200"; "in"; c2 = operconstr LEVEL "200" ->
- let ty,c1 = match ty, c1 with
+ { let ty,c1 = match ty, c1 with
| (_,None), { CAst.v = CCast(c, CastConv t) } -> (Loc.tag ?loc:(constr_loc t) @@ Some t), c (* Tolerance, see G_vernac.def_body *)
| _, _ -> ty, c1 in
- CAst.make ~loc:!@loc @@ CLetIn(id,mkCLambdaN ?loc:(constr_loc c1) bl c1,
- Option.map (mkCProdN ?loc:(fst ty) bl) (snd ty), c2)
+ CAst.make ~loc @@ CLetIn(id,mkCLambdaN ?loc:(constr_loc c1) bl c1,
+ Option.map (mkCProdN ?loc:(fst ty) bl) (snd ty), c2) }
| "let"; fx = single_fix; "in"; c = operconstr LEVEL "200" ->
- let fixp = mk_single_fix fx in
+ { let fixp = mk_single_fix fx in
let { CAst.loc = li; v = id } = match fixp.CAst.v with
CFix(id,_) -> id
| CCoFix(id,_) -> id
| _ -> assert false in
- CAst.make ~loc:!@loc @@ CLetIn( CAst.make ?loc:li @@ Name id,fixp,None,c)
- | "let"; lb = ["("; l=LIST0 name SEP ","; ")" -> l | "()" -> []];
+ CAst.make ~loc @@ CLetIn( CAst.make ?loc:li @@ Name id,fixp,None,c) }
+ | "let"; lb = ["("; l=LIST0 name SEP ","; ")" -> { l } | "()" -> { [] } ];
po = return_type;
":="; c1 = operconstr LEVEL "200"; "in";
c2 = operconstr LEVEL "200" ->
- CAst.make ~loc:!@loc @@ CLetTuple (lb,po,c1,c2)
+ { CAst.make ~loc @@ CLetTuple (lb,po,c1,c2) }
| "let"; "'"; p=pattern; ":="; c1 = operconstr LEVEL "200";
"in"; c2 = operconstr LEVEL "200" ->
- CAst.make ~loc:!@loc @@
- CCases (LetPatternStyle, None, [c1, None, None], [CAst.make ~loc:!@loc ([[p]], c2)])
+ { CAst.make ~loc @@
+ CCases (LetPatternStyle, None, [c1, None, None], [CAst.make ~loc ([[p]], c2)]) }
| "let"; "'"; p=pattern; ":="; c1 = operconstr LEVEL "200";
rt = case_type; "in"; c2 = operconstr LEVEL "200" ->
- CAst.make ~loc:!@loc @@
- CCases (LetPatternStyle, Some rt, [c1, aliasvar p, None], [CAst.make ~loc:!@loc ([[p]], c2)])
+ { CAst.make ~loc @@
+ CCases (LetPatternStyle, Some rt, [c1, aliasvar p, None], [CAst.make ~loc ([[p]], c2)]) }
| "let"; "'"; p=pattern; "in"; t = pattern LEVEL "200";
":="; c1 = operconstr LEVEL "200"; rt = case_type;
"in"; c2 = operconstr LEVEL "200" ->
- CAst.make ~loc:!@loc @@
- CCases (LetPatternStyle, Some rt, [c1, aliasvar p, Some t], [CAst.make ~loc:!@loc ([[p]], c2)])
+ { CAst.make ~loc @@
+ CCases (LetPatternStyle, Some rt, [c1, aliasvar p, Some t], [CAst.make ~loc ([[p]], c2)]) }
| "if"; c=operconstr LEVEL "200"; po = return_type;
"then"; b1=operconstr LEVEL "200";
"else"; b2=operconstr LEVEL "200" ->
- CAst.make ~loc:(!@loc) @@ CIf (c, po, b1, b2)
- | c=fix_constr -> c ] ]
+ { CAst.make ~loc @@ CIf (c, po, b1, b2) }
+ | c=fix_constr -> { c } ] ]
;
appl_arg:
[ [ id = lpar_id_coloneq; c=lconstr; ")" ->
- (c,Some (CAst.make ~loc:!@loc @@ ExplByName id))
- | c=operconstr LEVEL "9" -> (c,None) ] ]
+ { (c,Some (CAst.make ~loc @@ ExplByName id)) }
+ | c=operconstr LEVEL "9" -> { (c,None) } ] ]
;
atomic_constr:
- [ [ g=global; i=instance -> CAst.make ~loc:!@loc @@ CRef (g,i)
- | s=sort -> CAst.make ~loc:!@loc @@ CSort s
- | n=INT -> CAst.make ~loc:!@loc @@ CPrim (Numeral (n,true))
- | s=string -> CAst.make ~loc:!@loc @@ CPrim (String s)
- | "_" -> CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None)
- | "?"; "["; id=ident; "]" -> CAst.make ~loc:!@loc @@ CHole (None, IntroIdentifier id, None)
- | "?"; "["; id=pattern_ident; "]" -> CAst.make ~loc:!@loc @@ CHole (None, IntroFresh id, None)
- | id=pattern_ident; inst = evar_instance -> CAst.make ~loc:!@loc @@ CEvar(id,inst) ] ]
+ [ [ g=global; i=instance -> { CAst.make ~loc @@ CRef (g,i) }
+ | s=sort -> { CAst.make ~loc @@ CSort s }
+ | n=INT -> { CAst.make ~loc @@ CPrim (Numeral (n,true)) }
+ | s=string -> { CAst.make ~loc @@ CPrim (String s) }
+ | "_" -> { CAst.make ~loc @@ CHole (None, IntroAnonymous, None) }
+ | "?"; "["; id=ident; "]" -> { CAst.make ~loc @@ CHole (None, IntroIdentifier id, None) }
+ | "?"; "["; id=pattern_ident; "]" -> { CAst.make ~loc @@ CHole (None, IntroFresh id, None) }
+ | id=pattern_ident; inst = evar_instance -> { CAst.make ~loc @@ CEvar(id,inst) } ] ]
;
inst:
- [ [ id = ident; ":="; c = lconstr -> (id,c) ] ]
+ [ [ id = ident; ":="; c = lconstr -> { (id,c) } ] ]
;
evar_instance:
- [ [ "@{"; l = LIST1 inst SEP ";"; "}" -> l
- | -> [] ] ]
+ [ [ "@{"; l = LIST1 inst SEP ";"; "}" -> { l }
+ | -> { [] } ] ]
;
instance:
- [ [ "@{"; l = LIST0 universe_level; "}" -> Some l
- | -> None ] ]
+ [ [ "@{"; l = LIST0 universe_level; "}" -> { Some l }
+ | -> { None } ] ]
;
universe_level:
- [ [ "Set" -> GSet
- | "Prop" -> GProp
- | "Type" -> GType UUnknown
- | "_" -> GType UAnonymous
- | id = global -> GType (UNamed id)
+ [ [ "Set" -> { GSet }
+ | "Prop" -> { GProp }
+ | "Type" -> { GType UUnknown }
+ | "_" -> { GType UAnonymous }
+ | id = global -> { GType (UNamed id) }
] ]
;
fix_constr:
- [ [ fx1=single_fix -> mk_single_fix fx1
- | (_,kw,dcl1)=single_fix; "with"; dcls=LIST1 fix_decl SEP "with";
+ [ [ fx1=single_fix -> { mk_single_fix fx1 }
+ | f=single_fix; "with"; dcls=LIST1 fix_decl SEP "with";
"for"; id=identref ->
- mk_fix(!@loc,kw,id,dcl1::dcls)
+ { let (_,kw,dcl1) = f in
+ mk_fix(loc,kw,id,dcl1::dcls) }
] ]
;
single_fix:
- [ [ kw=fix_kw; dcl=fix_decl -> (!@loc,kw,dcl) ] ]
+ [ [ kw=fix_kw; dcl=fix_decl -> { (loc,kw,dcl) } ] ]
;
fix_kw:
- [ [ "fix" -> true
- | "cofix" -> false ] ]
+ [ [ "fix" -> { true }
+ | "cofix" -> { false } ] ]
;
fix_decl:
[ [ id=identref; bl=binders_fixannot; ty=type_cstr; ":=";
c=operconstr LEVEL "200" ->
- (id,fst bl,snd bl,c,ty) ] ]
+ { (id,fst bl,snd bl,c,ty) } ] ]
;
match_constr:
[ [ "match"; ci=LIST1 case_item SEP ","; ty=OPT case_type; "with";
- br=branches; "end" -> CAst.make ~loc:!@loc @@ CCases(RegularStyle,ty,ci,br) ] ]
+ br=branches; "end" -> { CAst.make ~loc @@ CCases(RegularStyle,ty,ci,br) } ] ]
;
case_item:
[ [ c=operconstr LEVEL "100";
- ona = OPT ["as"; id=name -> id];
- ty = OPT ["in"; t=pattern -> t] ->
- (c,ona,ty) ] ]
+ ona = OPT ["as"; id=name -> { id } ];
+ ty = OPT ["in"; t=pattern -> { t } ] ->
+ { (c,ona,ty) } ] ]
;
case_type:
- [ [ "return"; ty = operconstr LEVEL "100" -> ty ] ]
+ [ [ "return"; ty = operconstr LEVEL "100" -> { ty } ] ]
;
return_type:
- [ [ a = OPT [ na = OPT["as"; na=name -> na];
- ty = case_type -> (na,ty) ] ->
- match a with
+ [ [ a = OPT [ na = OPT["as"; na=name -> { na } ];
+ ty = case_type -> { (na,ty) } ] ->
+ { match a with
| None -> None, None
- | Some (na,t) -> (na, Some t)
+ | Some (na,t) -> (na, Some t) }
] ]
;
branches:
- [ [ OPT"|"; br=LIST0 eqn SEP "|" -> br ] ]
+ [ [ OPT"|"; br=LIST0 eqn SEP "|" -> { br } ] ]
;
mult_pattern:
- [ [ pl = LIST1 pattern LEVEL "99" SEP "," -> pl ] ]
+ [ [ pl = LIST1 pattern LEVEL "99" SEP "," -> { pl } ] ]
;
eqn:
[ [ pll = LIST1 mult_pattern SEP "|";
- "=>"; rhs = lconstr -> (CAst.make ~loc:!@loc (pll,rhs)) ] ]
+ "=>"; rhs = lconstr -> { (CAst.make ~loc (pll,rhs)) } ] ]
;
record_pattern:
- [ [ id = global; ":="; pat = pattern -> (id, pat) ] ]
+ [ [ id = global; ":="; pat = pattern -> { (id, pat) } ] ]
;
record_patterns:
- [ [ p = record_pattern; ";"; ps = record_patterns -> p :: ps
- | p = record_pattern; ";" -> [p]
- | p = record_pattern-> [p]
- | -> []
+ [ [ p = record_pattern; ";"; ps = record_patterns -> { p :: ps }
+ | p = record_pattern; ";" -> { [p] }
+ | p = record_pattern-> { [p] }
+ | -> { [] }
] ]
;
pattern:
[ "200" RIGHTA [ ]
| "100" RIGHTA
- [ p = pattern; "|"; pl = LIST1 pattern SEP "|" -> CAst.make ~loc:!@loc @@ CPatOr (p::pl) ]
+ [ p = pattern; "|"; pl = LIST1 pattern SEP "|" -> { CAst.make ~loc @@ CPatOr (p::pl) } ]
| "99" RIGHTA [ ]
| "90" RIGHTA [ ]
| "10" LEFTA
[ p = pattern; "as"; na = name ->
- CAst.make ~loc:!@loc @@ CPatAlias (p, na)
- | p = pattern; lp = LIST1 NEXT -> mkAppPattern ~loc:!@loc p lp
+ { CAst.make ~loc @@ CPatAlias (p, na) }
+ | p = pattern; lp = LIST1 NEXT -> { mkAppPattern ~loc p lp }
| "@"; r = Prim.reference; lp = LIST0 NEXT ->
- CAst.make ~loc:!@loc @@ CPatCstr (r, Some lp, []) ]
+ { CAst.make ~loc @@ CPatCstr (r, Some lp, []) } ]
| "1" LEFTA
- [ c = pattern; "%"; key=IDENT -> CAst.make ~loc:!@loc @@ CPatDelimiters (key,c) ]
+ [ c = pattern; "%"; key=IDENT -> { CAst.make ~loc @@ CPatDelimiters (key,c) } ]
| "0"
- [ r = Prim.reference -> CAst.make ~loc:!@loc @@ CPatAtom (Some r)
- | "{|"; pat = record_patterns; "|}" -> CAst.make ~loc:!@loc @@ CPatRecord pat
- | "_" -> CAst.make ~loc:!@loc @@ CPatAtom None
+ [ r = Prim.reference -> { CAst.make ~loc @@ CPatAtom (Some r) }
+ | "{|"; pat = record_patterns; "|}" -> { CAst.make ~loc @@ CPatRecord pat }
+ | "_" -> { CAst.make ~loc @@ CPatAtom None }
| "("; p = pattern LEVEL "200"; ")" ->
- (match p.CAst.v with
+ { (match p.CAst.v with
| CPatPrim (Numeral (n,true)) ->
- CAst.make ~loc:!@loc @@ CPatNotation("( _ )",([p],[]),[])
- | _ -> p)
+ CAst.make ~loc @@ CPatNotation((InConstrEntrySomeLevel,"( _ )"),([p],[]),[])
+ | _ -> p) }
| "("; p = pattern LEVEL "200"; ":"; ty = lconstr; ")" ->
- let p =
+ { let p =
match p with
| { CAst.v = CPatPrim (Numeral (n,true)) } ->
- CAst.make ~loc:!@loc @@ CPatNotation("( _ )",([p],[]),[])
+ CAst.make ~loc @@ CPatNotation((InConstrEntrySomeLevel,"( _ )"),([p],[]),[])
| _ -> p
in
- CAst.make ~loc:!@loc @@ CPatCast (p, ty)
- | n = INT -> CAst.make ~loc:!@loc @@ CPatPrim (Numeral (n,true))
- | s = string -> CAst.make ~loc:!@loc @@ CPatPrim (String s) ] ]
+ CAst.make ~loc @@ CPatCast (p, ty) }
+ | n = INT -> { CAst.make ~loc @@ CPatPrim (Numeral (n,true)) }
+ | s = string -> { CAst.make ~loc @@ CPatPrim (String s) } ] ]
;
impl_ident_tail:
- [ [ "}" -> binder_of_name Implicit
+ [ [ "}" -> { binder_of_name Implicit }
| nal=LIST1 name; ":"; c=lconstr; "}" ->
- (fun na -> CLocalAssum (na::nal,Default Implicit,c))
+ { (fun na -> CLocalAssum (na::nal,Default Implicit,c)) }
| nal=LIST1 name; "}" ->
- (fun na -> CLocalAssum (na::nal,Default Implicit,
- CAst.make ?loc:(Loc.merge_opt na.CAst.loc (Some !@loc)) @@
- CHole (Some (Evar_kinds.BinderType na.CAst.v), IntroAnonymous, None)))
+ { (fun na -> CLocalAssum (na::nal,Default Implicit,
+ CAst.make ?loc:(Loc.merge_opt na.CAst.loc (Some loc)) @@
+ CHole (Some (Evar_kinds.BinderType na.CAst.v), IntroAnonymous, None))) }
| ":"; c=lconstr; "}" ->
- (fun na -> CLocalAssum ([na],Default Implicit,c))
+ { (fun na -> CLocalAssum ([na],Default Implicit,c)) }
] ]
;
fixannot:
- [ [ "{"; IDENT "struct"; id=identref; "}" -> (Some id, CStructRec)
- | "{"; IDENT "wf"; rel=constr; id=OPT identref; "}" -> (id, CWfRec rel)
+ [ [ "{"; IDENT "struct"; id=identref; "}" -> { (Some id, CStructRec) }
+ | "{"; IDENT "wf"; rel=constr; id=OPT identref; "}" -> { (id, CWfRec rel) }
| "{"; IDENT "measure"; m=constr; id=OPT identref;
- rel=OPT constr; "}" -> (id, CMeasureRec (m,rel))
+ rel=OPT constr; "}" -> { (id, CMeasureRec (m,rel)) }
] ]
;
impl_name_head:
- [ [ id = impl_ident_head -> (CAst.make ~loc:!@loc @@ Name id) ] ]
+ [ [ id = impl_ident_head -> { CAst.make ~loc @@ Name id } ] ]
;
binders_fixannot:
[ [ na = impl_name_head; assum = impl_ident_tail; bl = binders_fixannot ->
- (assum na :: fst bl), snd bl
- | f = fixannot -> [], f
- | b = binder; bl = binders_fixannot -> b @ fst bl, snd bl
- | -> [], (None, CStructRec)
+ { (assum na :: fst bl), snd bl }
+ | f = fixannot -> { [], f }
+ | b = binder; bl = binders_fixannot -> { b @ fst bl, snd bl }
+ | -> { [], (None, CStructRec) }
] ]
;
open_binders:
(* Same as binders but parentheses around a closed binder are optional if
the latter is unique *)
- [ [ (* open binder *)
+ [ [
id = name; idl = LIST0 name; ":"; c = lconstr ->
- [CLocalAssum (id::idl,Default Explicit,c)]
- (* binders factorized with open binder *)
+ { [CLocalAssum (id::idl,Default Explicit,c)]
+ (* binders factorized with open binder *) }
| id = name; idl = LIST0 name; bl = binders ->
- binders_of_names (id::idl) @ bl
+ { binders_of_names (id::idl) @ bl }
| id1 = name; ".."; id2 = name ->
- [CLocalAssum ([id1;(CAst.make ~loc:!@loc (Name ldots_var));id2],
- Default Explicit, CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None))]
+ { [CLocalAssum ([id1;(CAst.make ~loc (Name ldots_var));id2],
+ Default Explicit, CAst.make ~loc @@ CHole (None, IntroAnonymous, None))] }
| bl = closed_binder; bl' = binders ->
- bl@bl'
+ { bl@bl' }
] ]
;
binders:
- [ [ l = LIST0 binder -> List.flatten l ] ]
+ [ [ l = LIST0 binder -> { List.flatten l } ] ]
;
binder:
- [ [ id = name -> [CLocalAssum ([id],Default Explicit, CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None))]
- | bl = closed_binder -> bl ] ]
+ [ [ id = name -> { [CLocalAssum ([id],Default Explicit, CAst.make ~loc @@ CHole (None, IntroAnonymous, None))] }
+ | bl = closed_binder -> { bl } ] ]
;
closed_binder:
[ [ "("; id=name; idl=LIST1 name; ":"; c=lconstr; ")" ->
- [CLocalAssum (id::idl,Default Explicit,c)]
+ { [CLocalAssum (id::idl,Default Explicit,c)] }
| "("; id=name; ":"; c=lconstr; ")" ->
- [CLocalAssum ([id],Default Explicit,c)]
+ { [CLocalAssum ([id],Default Explicit,c)] }
| "("; id=name; ":="; c=lconstr; ")" ->
- (match c.CAst.v with
+ { (match c.CAst.v with
| CCast(c, CastConv t) -> [CLocalDef (id,c,Some t)]
- | _ -> [CLocalDef (id,c,None)])
+ | _ -> [CLocalDef (id,c,None)]) }
| "("; id=name; ":"; t=lconstr; ":="; c=lconstr; ")" ->
- [CLocalDef (id,c,Some t)]
+ { [CLocalDef (id,c,Some t)] }
| "{"; id=name; "}" ->
- [CLocalAssum ([id],Default Implicit, CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None))]
+ { [CLocalAssum ([id],Default Implicit, CAst.make ~loc @@ CHole (None, IntroAnonymous, None))] }
| "{"; id=name; idl=LIST1 name; ":"; c=lconstr; "}" ->
- [CLocalAssum (id::idl,Default Implicit,c)]
+ { [CLocalAssum (id::idl,Default Implicit,c)] }
| "{"; id=name; ":"; c=lconstr; "}" ->
- [CLocalAssum ([id],Default Implicit,c)]
+ { [CLocalAssum ([id],Default Implicit,c)] }
| "{"; id=name; idl=LIST1 name; "}" ->
- List.map (fun id -> CLocalAssum ([id],Default Implicit, CAst.make ~loc:!@loc @@ CHole (None, IntroAnonymous, None))) (id::idl)
+ { List.map (fun id -> CLocalAssum ([id],Default Implicit, CAst.make ~loc @@ CHole (None, IntroAnonymous, None))) (id::idl) }
| "`("; tc = LIST1 typeclass_constraint SEP "," ; ")" ->
- List.map (fun (n, b, t) -> CLocalAssum ([n], Generalized (Implicit, Explicit, b), t)) tc
+ { List.map (fun (n, b, t) -> CLocalAssum ([n], Generalized (Implicit, Explicit, b), t)) tc }
| "`{"; tc = LIST1 typeclass_constraint SEP "," ; "}" ->
- List.map (fun (n, b, t) -> CLocalAssum ([n], Generalized (Implicit, Implicit, b), t)) tc
+ { List.map (fun (n, b, t) -> CLocalAssum ([n], Generalized (Implicit, Implicit, b), t)) tc }
| "'"; p = pattern LEVEL "0" ->
- let (p, ty) =
+ { let (p, ty) =
match p.CAst.v with
| CPatCast (p, ty) -> (p, Some ty)
| _ -> (p, None)
in
- [CLocalPattern (CAst.make ~loc:!@loc (p, ty))]
+ [CLocalPattern (CAst.make ~loc (p, ty))] }
] ]
;
typeclass_constraint:
- [ [ "!" ; c = operconstr LEVEL "200" -> (CAst.make ~loc:!@loc Anonymous), true, c
- | "{"; id = name; "}"; ":" ; expl = [ "!" -> true | -> false ] ; c = operconstr LEVEL "200" ->
- id, expl, c
- | iid=name_colon ; expl = [ "!" -> true | -> false ] ; c = operconstr LEVEL "200" ->
- (CAst.make ~loc:!@loc iid), expl, c
+ [ [ "!" ; c = operconstr LEVEL "200" -> { (CAst.make ~loc Anonymous), true, c }
+ | "{"; id = name; "}"; ":" ; expl = [ "!" -> { true } | -> { false } ] ; c = operconstr LEVEL "200" ->
+ { id, expl, c }
+ | iid=name_colon ; expl = [ "!" -> { true } | -> { false } ] ; c = operconstr LEVEL "200" ->
+ { (CAst.make ~loc iid), expl, c }
| c = operconstr LEVEL "200" ->
- (CAst.make ~loc:!@loc Anonymous), false, c
+ { (CAst.make ~loc Anonymous), false, c }
] ]
;
type_cstr:
- [ [ c=OPT [":"; c=lconstr -> c] -> Loc.tag ~loc:!@loc c ] ]
+ [ [ c=OPT [":"; c=lconstr -> { c } ] -> { Loc.tag ~loc c } ] ]
;
- END;;
+ END
diff --git a/parsing/g_prim.ml4 b/parsing/g_prim.ml4
deleted file mode 100644
index b25ea766..00000000
--- a/parsing/g_prim.ml4
+++ /dev/null
@@ -1,122 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Names
-open Libnames
-
-open Pcoq
-open Pcoq.Prim
-
-let prim_kw = ["{"; "}"; "["; "]"; "("; ")"; "'"]
-let _ = List.iter CLexer.add_keyword prim_kw
-
-
-let local_make_qualid l id = make_qualid (DirPath.make l) id
-
-let my_int_of_string loc s =
- try
- let n = int_of_string s in
- (* To avoid Array.make errors (that e.g. Undo uses), we set a *)
- (* more restricted limit than int_of_string does *)
- if n > 1024 * 2048 then raise Exit;
- n
- with Failure _ | Exit ->
- CErrors.user_err ~loc (Pp.str "Cannot support a so large number.")
-
-GEXTEND Gram
- GLOBAL:
- bigint natural integer identref name ident var preident
- fullyqualid qualid reference dirpath ne_lstring
- ne_string string lstring pattern_ident pattern_identref by_notation smart_global;
- preident:
- [ [ s = IDENT -> s ] ]
- ;
- ident:
- [ [ s = IDENT -> Id.of_string s ] ]
- ;
- pattern_ident:
- [ [ LEFTQMARK; id = ident -> id ] ]
- ;
- pattern_identref:
- [ [ id = pattern_ident -> CAst.make ~loc:!@loc id ] ]
- ;
- var: (* as identref, but interpret as a term identifier in ltac *)
- [ [ id = ident -> CAst.make ~loc:!@loc id ] ]
- ;
- identref:
- [ [ id = ident -> CAst.make ~loc:!@loc id ] ]
- ;
- field:
- [ [ s = FIELD -> Id.of_string s ] ]
- ;
- fields:
- [ [ id = field; (l,id') = fields -> (l@[id],id')
- | id = field -> ([],id)
- ] ]
- ;
- fullyqualid:
- [ [ id = ident; (l,id')=fields -> CAst.make ~loc:!@loc @@ id::List.rev (id'::l)
- | id = ident -> CAst.make ~loc:!@loc [id]
- ] ]
- ;
- basequalid:
- [ [ id = ident; (l,id')=fields -> local_make_qualid (l@[id]) id'
- | id = ident -> qualid_of_ident id
- ] ]
- ;
- name:
- [ [ IDENT "_" -> CAst.make ~loc:!@loc Anonymous
- | id = ident -> CAst.make ~loc:!@loc @@ Name id ] ]
- ;
- reference:
- [ [ id = ident; (l,id') = fields ->
- CAst.make ~loc:!@loc @@ Qualid (local_make_qualid (l@[id]) id')
- | id = ident -> CAst.make ~loc:!@loc @@ Ident id
- ] ]
- ;
- by_notation:
- [ [ s = ne_string; sc = OPT ["%"; key = IDENT -> key ] -> (s, sc) ] ]
- ;
- smart_global:
- [ [ c = reference -> CAst.make ~loc:!@loc @@ Misctypes.AN c
- | ntn = by_notation -> CAst.make ~loc:!@loc @@ Misctypes.ByNotation ntn ] ]
- ;
- qualid:
- [ [ qid = basequalid -> CAst.make ~loc:!@loc qid ] ]
- ;
- ne_string:
- [ [ s = STRING ->
- if s="" then CErrors.user_err ~loc:!@loc (Pp.str"Empty string."); s
- ] ]
- ;
- ne_lstring:
- [ [ s = ne_string -> CAst.make ~loc:!@loc s ] ]
- ;
- dirpath:
- [ [ id = ident; l = LIST0 field ->
- DirPath.make (List.rev (id::l)) ] ]
- ;
- string:
- [ [ s = STRING -> s ] ]
- ;
- lstring:
- [ [ s = string -> (CAst.make ~loc:!@loc s) ] ]
- ;
- integer:
- [ [ i = INT -> my_int_of_string (!@loc) i
- | "-"; i = INT -> - my_int_of_string (!@loc) i ] ]
- ;
- natural:
- [ [ i = INT -> my_int_of_string (!@loc) i ] ]
- ;
- bigint: (* Negative numbers are dealt with elsewhere *)
- [ [ i = INT -> i ] ]
- ;
-END
diff --git a/parsing/g_prim.mlg b/parsing/g_prim.mlg
new file mode 100644
index 00000000..dfb78890
--- /dev/null
+++ b/parsing/g_prim.mlg
@@ -0,0 +1,123 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+{
+
+open Names
+open Libnames
+
+open Pcoq
+open Pcoq.Prim
+
+let prim_kw = ["{"; "}"; "["; "]"; "("; ")"; "'"]
+let _ = List.iter CLexer.add_keyword prim_kw
+
+
+let local_make_qualid loc l id = make_qualid ~loc (DirPath.make l) id
+
+let my_int_of_string loc s =
+ try
+ int_of_string s
+ with Failure _ ->
+ CErrors.user_err ~loc (Pp.str "This number is too large.")
+
+}
+
+GRAMMAR EXTEND Gram
+ GLOBAL:
+ bigint natural integer identref name ident var preident
+ fullyqualid qualid reference dirpath ne_lstring
+ ne_string string lstring pattern_ident pattern_identref by_notation smart_global;
+ preident:
+ [ [ s = IDENT -> { s } ] ]
+ ;
+ ident:
+ [ [ s = IDENT -> { Id.of_string s } ] ]
+ ;
+ pattern_ident:
+ [ [ LEFTQMARK; id = ident -> { id } ] ]
+ ;
+ pattern_identref:
+ [ [ id = pattern_ident -> { CAst.make ~loc id } ] ]
+ ;
+ var: (* as identref, but interpret as a term identifier in ltac *)
+ [ [ id = ident -> { CAst.make ~loc id } ] ]
+ ;
+ identref:
+ [ [ id = ident -> { CAst.make ~loc id } ] ]
+ ;
+ field:
+ [ [ s = FIELD -> { Id.of_string s } ] ]
+ ;
+ fields:
+ [ [ id = field; f = fields -> { let (l,id') = f in (l@[id],id') }
+ | id = field -> { ([],id) }
+ ] ]
+ ;
+ fullyqualid:
+ [ [ id = ident; f=fields -> { let (l,id') = f in CAst.make ~loc @@ id::List.rev (id'::l) }
+ | id = ident -> { CAst.make ~loc [id] }
+ ] ]
+ ;
+ basequalid:
+ [ [ id = ident; f=fields -> { let (l,id') = f in local_make_qualid loc (l@[id]) id' }
+ | id = ident -> { qualid_of_ident ~loc id }
+ ] ]
+ ;
+ name:
+ [ [ IDENT "_" -> { CAst.make ~loc Anonymous }
+ | id = ident -> { CAst.make ~loc @@ Name id } ] ]
+ ;
+ reference:
+ [ [ id = ident; f = fields -> {
+ let (l,id') = f in
+ local_make_qualid loc (l@[id]) id' }
+ | id = ident -> { local_make_qualid loc [] id }
+ ] ]
+ ;
+ by_notation:
+ [ [ s = ne_string; sc = OPT ["%"; key = IDENT -> { key } ] -> { (s, sc) } ] ]
+ ;
+ smart_global:
+ [ [ c = reference -> { CAst.make ~loc @@ Constrexpr.AN c }
+ | ntn = by_notation -> { CAst.make ~loc @@ Constrexpr.ByNotation ntn } ] ]
+ ;
+ qualid:
+ [ [ qid = basequalid -> { qid } ] ]
+ ;
+ ne_string:
+ [ [ s = STRING ->
+ { if s="" then CErrors.user_err ~loc (Pp.str"Empty string."); s }
+ ] ]
+ ;
+ ne_lstring:
+ [ [ s = ne_string -> { CAst.make ~loc s } ] ]
+ ;
+ dirpath:
+ [ [ id = ident; l = LIST0 field ->
+ { DirPath.make (List.rev (id::l)) } ] ]
+ ;
+ string:
+ [ [ s = STRING -> { s } ] ]
+ ;
+ lstring:
+ [ [ s = string -> { CAst.make ~loc s } ] ]
+ ;
+ integer:
+ [ [ i = INT -> { my_int_of_string loc i }
+ | "-"; i = INT -> { - my_int_of_string loc i } ] ]
+ ;
+ natural:
+ [ [ i = INT -> { my_int_of_string loc i } ] ]
+ ;
+ bigint: (* Negative numbers are dealt with elsewhere *)
+ [ [ i = INT -> { i } ] ]
+ ;
+END
diff --git a/parsing/g_proofs.ml4 b/parsing/g_proofs.ml4
deleted file mode 100644
index e393c2bb..00000000
--- a/parsing/g_proofs.ml4
+++ /dev/null
@@ -1,133 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Constrexpr
-open Vernacexpr
-open Misctypes
-
-open Pcoq
-open Pcoq.Prim
-open Pcoq.Constr
-open Pcoq.Vernac_
-
-let thm_token = G_vernac.thm_token
-
-let hint = Gram.entry_create "hint"
-
-let warn_deprecated_focus =
- CWarnings.create ~name:"deprecated-focus" ~category:"deprecated"
- (fun () ->
- Pp.strbrk
- "The Focus command is deprecated; use bullets or focusing brackets instead"
- )
-
-let warn_deprecated_focus_n n =
- CWarnings.create ~name:"deprecated-focus" ~category:"deprecated"
- (fun () ->
- Pp.(str "The Focus command is deprecated;" ++ spc ()
- ++ str "use '" ++ int n ++ str ": {' instead")
- )
-
-let warn_deprecated_unfocus =
- CWarnings.create ~name:"deprecated-unfocus" ~category:"deprecated"
- (fun () -> Pp.strbrk "The Unfocus command is deprecated")
-
-(* Proof commands *)
-GEXTEND Gram
- GLOBAL: hint command;
-
- opt_hintbases:
- [ [ -> []
- | ":"; l = LIST1 [id = IDENT -> id ] -> l ] ]
- ;
- command:
- [ [ IDENT "Goal"; c = lconstr ->
- VernacDefinition (Decl_kinds.(NoDischarge, Definition), ((CAst.make ~loc:!@loc Names.Anonymous), None), ProveBody ([], c))
- | IDENT "Proof" -> VernacProof (None,None)
- | IDENT "Proof" ; IDENT "Mode" ; mn = string -> VernacProofMode mn
- | IDENT "Proof"; c = lconstr -> VernacExactProof c
- | IDENT "Abort" -> VernacAbort None
- | IDENT "Abort"; IDENT "All" -> VernacAbortAll
- | IDENT "Abort"; id = identref -> VernacAbort (Some id)
- | IDENT "Existential"; n = natural; c = constr_body ->
- VernacSolveExistential (n,c)
- | IDENT "Admitted" -> VernacEndProof Admitted
- | IDENT "Qed" -> VernacEndProof (Proved (Opaque,None))
- | IDENT "Save"; id = identref ->
- VernacEndProof (Proved (Opaque, Some id))
- | IDENT "Defined" -> VernacEndProof (Proved (Transparent,None))
- | IDENT "Defined"; id=identref ->
- VernacEndProof (Proved (Transparent,Some id))
- | IDENT "Restart" -> VernacRestart
- | IDENT "Undo" -> VernacUndo 1
- | IDENT "Undo"; n = natural -> VernacUndo n
- | IDENT "Undo"; IDENT "To"; n = natural -> VernacUndoTo n
- | IDENT "Focus" ->
- warn_deprecated_focus ~loc:!@loc ();
- VernacFocus None
- | IDENT "Focus"; n = natural ->
- warn_deprecated_focus_n n ~loc:!@loc ();
- VernacFocus (Some n)
- | IDENT "Unfocus" ->
- warn_deprecated_unfocus ~loc:!@loc ();
- VernacUnfocus
- | IDENT "Unfocused" -> VernacUnfocused
- | IDENT "Show" -> VernacShow (ShowGoal OpenSubgoals)
- | IDENT "Show"; n = natural -> VernacShow (ShowGoal (NthGoal n))
- | IDENT "Show"; id = ident -> VernacShow (ShowGoal (GoalId id))
- | IDENT "Show"; IDENT "Script" -> VernacShow ShowScript
- | IDENT "Show"; IDENT "Existentials" -> VernacShow ShowExistentials
- | IDENT "Show"; IDENT "Universes" -> VernacShow ShowUniverses
- | IDENT "Show"; IDENT "Conjectures" -> VernacShow ShowProofNames
- | IDENT "Show"; IDENT "Proof" -> VernacShow ShowProof
- | IDENT "Show"; IDENT "Intro" -> VernacShow (ShowIntros false)
- | IDENT "Show"; IDENT "Intros" -> VernacShow (ShowIntros true)
- | IDENT "Show"; IDENT "Match"; id = reference -> VernacShow (ShowMatch id)
- | IDENT "Guarded" -> VernacCheckGuard
- (* Hints for Auto and EAuto *)
- | IDENT "Create"; IDENT "HintDb" ;
- id = IDENT ; b = [ "discriminated" -> true | -> false ] ->
- VernacCreateHintDb (id, b)
- | IDENT "Remove"; IDENT "Hints"; ids = LIST1 global; dbnames = opt_hintbases ->
- VernacRemoveHints (dbnames, ids)
- | IDENT "Hint"; h = hint;
- dbnames = opt_hintbases ->
- VernacHints (dbnames, h)
- (* Declare "Resolve" explicitly so as to be able to later extend with
- "Resolve ->" and "Resolve <-" *)
- | IDENT "Hint"; IDENT "Resolve"; lc = LIST1 reference_or_constr;
- info = hint_info; dbnames = opt_hintbases ->
- VernacHints (dbnames,
- HintsResolve (List.map (fun x -> (info, true, x)) lc))
- ] ];
- reference_or_constr:
- [ [ r = global -> HintsReference r
- | c = constr -> HintsConstr c ] ]
- ;
- hint:
- [ [ IDENT "Resolve"; lc = LIST1 reference_or_constr; info = hint_info ->
- HintsResolve (List.map (fun x -> (info, true, x)) lc)
- | IDENT "Immediate"; lc = LIST1 reference_or_constr -> HintsImmediate lc
- | IDENT "Transparent"; lc = LIST1 global -> HintsTransparency (lc, true)
- | IDENT "Opaque"; lc = LIST1 global -> HintsTransparency (lc, false)
- | IDENT "Mode"; l = global; m = mode -> HintsMode (l, m)
- | IDENT "Unfold"; lqid = LIST1 global -> HintsUnfold lqid
- | IDENT "Constructors"; lc = LIST1 global -> HintsConstructors lc ] ]
- ;
- constr_body:
- [ [ ":="; c = lconstr -> c
- | ":"; t = lconstr; ":="; c = lconstr -> CAst.make ~loc:!@loc @@ CCast(c,CastConv t) ] ]
- ;
- mode:
- [ [ l = LIST1 [ "+" -> ModeInput
- | "!" -> ModeNoHeadEvar
- | "-" -> ModeOutput ] -> l ] ]
- ;
-END
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
deleted file mode 100644
index 61b1de82..00000000
--- a/parsing/g_vernac.ml4
+++ /dev/null
@@ -1,1195 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Pp
-open CErrors
-open Util
-open Names
-open Vernacexpr
-open Constrexpr
-open Constrexpr_ops
-open Extend
-open Decl_kinds
-open Declarations
-open Misctypes
-open Tok (* necessary for camlp5 *)
-
-open Pcoq
-open Pcoq.Prim
-open Pcoq.Constr
-open Pcoq.Vernac_
-open Pcoq.Module
-
-let vernac_kw = [ ";"; ","; ">->"; ":<"; "<:"; "where"; "at" ]
-let _ = List.iter CLexer.add_keyword vernac_kw
-
-(* Rem: do not join the different GEXTEND into one, it breaks native *)
-(* compilation on PowerPC and Sun architectures *)
-
-let query_command = Gram.entry_create "vernac:query_command"
-
-let subprf = Gram.entry_create "vernac:subprf"
-
-let class_rawexpr = Gram.entry_create "vernac:class_rawexpr"
-let thm_token = Gram.entry_create "vernac:thm_token"
-let def_body = Gram.entry_create "vernac:def_body"
-let decl_notation = Gram.entry_create "vernac:decl_notation"
-let record_field = Gram.entry_create "vernac:record_field"
-let of_type_with_opt_coercion = Gram.entry_create "vernac:of_type_with_opt_coercion"
-let instance_name = Gram.entry_create "vernac:instance_name"
-let section_subset_expr = Gram.entry_create "vernac:section_subset_expr"
-
-let make_bullet s =
- let n = String.length s in
- match s.[0] with
- | '-' -> Dash n
- | '+' -> Plus n
- | '*' -> Star n
- | _ -> assert false
-
-let parse_compat_version ?(allow_old = true) = let open Flags in function
- | "8.8" -> Current
- | "8.7" -> V8_7
- | "8.6" -> V8_6
- | ("8.5" | "8.4" | "8.3" | "8.2" | "8.1" | "8.0") as s ->
- CErrors.user_err ~hdr:"get_compat_version"
- Pp.(str "Compatibility with version " ++ str s ++ str " not supported.")
- | s ->
- CErrors.user_err ~hdr:"get_compat_version"
- Pp.(str "Unknown compatibility version \"" ++ str s ++ str "\".")
-
-GEXTEND Gram
- GLOBAL: vernac_control gallina_ext noedit_mode subprf;
- vernac_control: FIRST
- [ [ IDENT "Time"; c = located_vernac -> VernacTime (false,c)
- | IDENT "Redirect"; s = ne_string; c = located_vernac -> VernacRedirect (s, c)
- | IDENT "Timeout"; n = natural; v = vernac_control -> VernacTimeout(n,v)
- | IDENT "Fail"; v = vernac_control -> VernacFail v
- | (f, v) = vernac -> VernacExpr(f, v) ]
- ]
- ;
- vernac:
- [ [ IDENT "Local"; (f, v) = vernac_poly -> (VernacLocal true :: f, v)
- | IDENT "Global"; (f, v) = vernac_poly -> (VernacLocal false :: f, v)
-
- | v = vernac_poly -> v ]
- ]
- ;
- vernac_poly:
- [ [ IDENT "Polymorphic"; (f, v) = vernac_aux -> (VernacPolymorphic true :: f, v)
- | IDENT "Monomorphic"; (f, v) = vernac_aux -> (VernacPolymorphic false :: f, v)
- | v = vernac_aux -> v ]
- ]
- ;
- vernac_aux:
- (* Better to parse "." here: in case of failure (e.g. in coerce_to_var), *)
- (* "." is still in the stream and discard_to_dot works correctly *)
- [ [ IDENT "Program"; g = gallina; "." -> ([VernacProgram], g)
- | IDENT "Program"; g = gallina_ext; "." -> ([VernacProgram], g)
- | g = gallina; "." -> ([], g)
- | g = gallina_ext; "." -> ([], g)
- | c = command; "." -> ([], c)
- | c = syntax; "." -> ([], c)
- | c = subprf -> ([], c)
- ] ]
- ;
- vernac_aux: LAST
- [ [ prfcom = command_entry -> ([], prfcom) ] ]
- ;
- noedit_mode:
- [ [ c = query_command -> c None] ]
- ;
-
- subprf:
- [ [ s = BULLET -> VernacBullet (make_bullet s)
- | "{" -> VernacSubproof None
- | "}" -> VernacEndSubproof
- ] ]
- ;
-
- located_vernac:
- [ [ v = vernac_control -> CAst.make ~loc:!@loc v ] ]
- ;
-END
-
-let warn_plural_command =
- CWarnings.create ~name:"plural-command" ~category:"pedantic" ~default:CWarnings.Disabled
- (fun kwd -> strbrk (Printf.sprintf "Command \"%s\" expects more than one assumption." kwd))
-
-let test_plural_form loc kwd = function
- | [(_,([_],_))] ->
- warn_plural_command ~loc:!@loc kwd
- | _ -> ()
-
-let test_plural_form_types loc kwd = function
- | [([_],_)] ->
- warn_plural_command ~loc:!@loc kwd
- | _ -> ()
-
-let lname_of_lident : lident -> lname =
- CAst.map (fun s -> Name s)
-
-let name_of_ident_decl : ident_decl -> name_decl =
- on_fst lname_of_lident
-
-(* Gallina declarations *)
-GEXTEND Gram
- GLOBAL: gallina gallina_ext thm_token def_body of_type_with_opt_coercion
- record_field decl_notation rec_definition ident_decl univ_decl;
-
- gallina:
- (* Definition, Theorem, Variable, Axiom, ... *)
- [ [ thm = thm_token; id = ident_decl; bl = binders; ":"; c = lconstr;
- l = LIST0
- [ "with"; id = ident_decl; bl = binders; ":"; c = lconstr ->
- (id,(bl,c)) ] ->
- VernacStartTheoremProof (thm, (id,(bl,c))::l)
- | stre = assumption_token; nl = inline; bl = assum_list ->
- VernacAssumption (stre, nl, bl)
- | (kwd,stre) = assumptions_token; nl = inline; bl = assum_list ->
- test_plural_form loc kwd bl;
- VernacAssumption (stre, nl, bl)
- | d = def_token; id = ident_decl; b = def_body ->
- VernacDefinition (d, name_of_ident_decl id, b)
- | IDENT "Let"; id = identref; b = def_body ->
- VernacDefinition ((DoDischarge, Let), (lname_of_lident id, None), b)
- (* Gallina inductive declarations *)
- | cum = cumulativity_token; priv = private_token; f = finite_token;
- indl = LIST1 inductive_definition SEP "with" ->
- let (k,f) = f in
- let indl=List.map (fun ((a,b,c,d),e) -> ((a,b,c,k,d),e)) indl in
- let cum =
- match cum with
- Some true -> LocalCumulativity
- | Some false -> LocalNonCumulativity
- | None ->
- if Flags.is_polymorphic_inductive_cumulativity () then
- GlobalCumulativity
- else
- GlobalNonCumulativity
- in
- VernacInductive (cum, priv,f,indl)
- | "Fixpoint"; recs = LIST1 rec_definition SEP "with" ->
- VernacFixpoint (NoDischarge, recs)
- | IDENT "Let"; "Fixpoint"; recs = LIST1 rec_definition SEP "with" ->
- VernacFixpoint (DoDischarge, recs)
- | "CoFixpoint"; corecs = LIST1 corec_definition SEP "with" ->
- VernacCoFixpoint (NoDischarge, corecs)
- | IDENT "Let"; "CoFixpoint"; corecs = LIST1 corec_definition SEP "with" ->
- VernacCoFixpoint (DoDischarge, corecs)
- | IDENT "Scheme"; l = LIST1 scheme SEP "with" -> VernacScheme l
- | IDENT "Combined"; IDENT "Scheme"; id = identref; IDENT "from";
- l = LIST1 identref SEP "," -> VernacCombinedScheme (id, l)
- | IDENT "Register"; IDENT "Inline"; id = identref ->
- VernacRegister(id, RegisterInline)
- | IDENT "Universe"; l = LIST1 identref -> VernacUniverse l
- | IDENT "Universes"; l = LIST1 identref -> VernacUniverse l
- | IDENT "Constraint"; l = LIST1 univ_constraint SEP "," -> VernacConstraint l
- ] ]
- ;
-
- thm_token:
- [ [ "Theorem" -> Theorem
- | IDENT "Lemma" -> Lemma
- | IDENT "Fact" -> Fact
- | IDENT "Remark" -> Remark
- | IDENT "Corollary" -> Corollary
- | IDENT "Proposition" -> Proposition
- | IDENT "Property" -> Property ] ]
- ;
- def_token:
- [ [ "Definition" -> (NoDischarge,Definition)
- | IDENT "Example" -> (NoDischarge,Example)
- | IDENT "SubClass" -> (NoDischarge,SubClass) ] ]
- ;
- assumption_token:
- [ [ "Hypothesis" -> (DoDischarge, Logical)
- | "Variable" -> (DoDischarge, Definitional)
- | "Axiom" -> (NoDischarge, Logical)
- | "Parameter" -> (NoDischarge, Definitional)
- | IDENT "Conjecture" -> (NoDischarge, Conjectural) ] ]
- ;
- assumptions_token:
- [ [ IDENT "Hypotheses" -> ("Hypotheses", (DoDischarge, Logical))
- | IDENT "Variables" -> ("Variables", (DoDischarge, Definitional))
- | IDENT "Axioms" -> ("Axioms", (NoDischarge, Logical))
- | IDENT "Parameters" -> ("Parameters", (NoDischarge, Definitional))
- | IDENT "Conjectures" -> ("Conjectures", (NoDischarge, Conjectural)) ] ]
- ;
- inline:
- [ [ IDENT "Inline"; "("; i = INT; ")" -> InlineAt (int_of_string i)
- | IDENT "Inline" -> DefaultInline
- | -> NoInline] ]
- ;
- univ_constraint:
- [ [ l = universe_level; ord = [ "<" -> Univ.Lt | "=" -> Univ.Eq | "<=" -> Univ.Le ];
- r = universe_level -> (l, ord, r) ] ]
- ;
- univ_decl :
- [ [ "@{" ; l = LIST0 identref; ext = [ "+" -> true | -> false ];
- cs = [ "|"; l' = LIST0 univ_constraint SEP ",";
- ext = [ "+" -> true | -> false ]; "}" -> (l',ext)
- | ext = [ "}" -> true | "|}" -> false ] -> ([], ext) ]
- ->
- { univdecl_instance = l;
- univdecl_extensible_instance = ext;
- univdecl_constraints = fst cs;
- univdecl_extensible_constraints = snd cs }
- ] ]
- ;
- ident_decl:
- [ [ i = identref; l = OPT univ_decl -> (i, l)
- ] ]
- ;
- finite_token:
- [ [ IDENT "Inductive" -> (Inductive_kw,Finite)
- | IDENT "CoInductive" -> (CoInductive,CoFinite)
- | IDENT "Variant" -> (Variant,BiFinite)
- | IDENT "Record" -> (Record,BiFinite)
- | IDENT "Structure" -> (Structure,BiFinite)
- | IDENT "Class" -> (Class true,BiFinite) ] ]
- ;
- cumulativity_token:
- [ [ IDENT "Cumulative" -> Some true | IDENT "NonCumulative" -> Some false | -> None ] ]
- ;
- private_token:
- [ [ IDENT "Private" -> true | -> false ] ]
- ;
- (* Simple definitions *)
- def_body:
- [ [ bl = binders; ":="; red = reduce; c = lconstr ->
- if List.exists (function CLocalPattern _ -> true | _ -> false) bl
- then
- (* FIXME: "red" will be applied to types in bl and Cast with remain *)
- let c = mkCLambdaN ~loc:!@loc bl c in
- DefineBody ([], red, c, None)
- else
- (match c with
- | { CAst.v = CCast(c, CastConv t) } -> DefineBody (bl, red, c, Some t)
- | _ -> DefineBody (bl, red, c, None))
- | bl = binders; ":"; t = lconstr; ":="; red = reduce; c = lconstr ->
- let ((bl, c), tyo) =
- if List.exists (function CLocalPattern _ -> true | _ -> false) bl
- then
- (* FIXME: "red" will be applied to types in bl and Cast with remain *)
- let c = CAst.make ~loc:!@loc @@ CCast (c, CastConv t) in
- (([],mkCLambdaN ~loc:!@loc bl c), None)
- else ((bl, c), Some t)
- in
- DefineBody (bl, red, c, tyo)
- | bl = binders; ":"; t = lconstr ->
- ProveBody (bl, t) ] ]
- ;
- reduce:
- [ [ IDENT "Eval"; r = red_expr; "in" -> Some r
- | -> None ] ]
- ;
- one_decl_notation:
- [ [ ntn = ne_lstring; ":="; c = constr;
- scopt = OPT [ ":"; sc = IDENT -> sc] -> (ntn,c,scopt) ] ]
- ;
- decl_notation:
- [ [ "where"; l = LIST1 one_decl_notation SEP IDENT "and" -> l
- | -> [] ] ]
- ;
- (* Inductives and records *)
- opt_constructors_or_fields:
- [ [ ":="; lc = constructor_list_or_record_decl -> lc
- | -> RecordDecl (None, []) ] ]
- ;
- inductive_definition:
- [ [ oc = opt_coercion; id = ident_decl; indpar = binders;
- c = OPT [ ":"; c = lconstr -> c ];
- lc=opt_constructors_or_fields; ntn = decl_notation ->
- (((oc,id),indpar,c,lc),ntn) ] ]
- ;
- constructor_list_or_record_decl:
- [ [ "|"; l = LIST1 constructor SEP "|" -> Constructors l
- | id = identref ; c = constructor_type; "|"; l = LIST0 constructor SEP "|" ->
- Constructors ((c id)::l)
- | id = identref ; c = constructor_type -> Constructors [ c id ]
- | cstr = identref; "{"; fs = record_fields; "}" ->
- RecordDecl (Some cstr,fs)
- | "{";fs = record_fields; "}" -> RecordDecl (None,fs)
- | -> Constructors [] ] ]
- ;
-(*
- csort:
- [ [ s = sort -> CSort (loc,s) ] ]
- ;
-*)
- opt_coercion:
- [ [ ">" -> true
- | -> false ] ]
- ;
- (* (co)-fixpoints *)
- rec_definition:
- [ [ id = ident_decl;
- bl = binders_fixannot;
- ty = type_cstr;
- def = OPT [":="; def = lconstr -> def]; ntn = decl_notation ->
- let bl, annot = bl in ((id,annot,bl,ty,def),ntn) ] ]
- ;
- corec_definition:
- [ [ id = ident_decl; bl = binders; ty = type_cstr;
- def = OPT [":="; def = lconstr -> def]; ntn = decl_notation ->
- ((id,bl,ty,def),ntn) ] ]
- ;
- type_cstr:
- [ [ ":"; c=lconstr -> c
- | -> CAst.make ~loc:!@loc @@ CHole (None, Misctypes.IntroAnonymous, None) ] ]
- ;
- (* Inductive schemes *)
- scheme:
- [ [ kind = scheme_kind -> (None,kind)
- | id = identref; ":="; kind = scheme_kind -> (Some id,kind) ] ]
- ;
- scheme_kind:
- [ [ IDENT "Induction"; "for"; ind = smart_global;
- IDENT "Sort"; s = sort_family-> InductionScheme(true,ind,s)
- | IDENT "Minimality"; "for"; ind = smart_global;
- IDENT "Sort"; s = sort_family-> InductionScheme(false,ind,s)
- | IDENT "Elimination"; "for"; ind = smart_global;
- IDENT "Sort"; s = sort_family-> CaseScheme(true,ind,s)
- | IDENT "Case"; "for"; ind = smart_global;
- IDENT "Sort"; s = sort_family-> CaseScheme(false,ind,s)
- | IDENT "Equality"; "for" ; ind = smart_global -> EqualityScheme(ind) ] ]
- ;
- (* Various Binders *)
-(*
- (* ... without coercions *)
- binder_nodef:
- [ [ b = binder_let ->
- (match b with
- CLocalAssum(l,ty) -> (l,ty)
- | CLocalDef _ ->
- Util.user_err_loc
- (loc,"fix_param",Pp.str"defined binder not allowed here.")) ] ]
- ;
-*)
- (* ... with coercions *)
- record_field:
- [ [ bd = record_binder; pri = OPT [ "|"; n = natural -> n ];
- ntn = decl_notation -> (bd,pri),ntn ] ]
- ;
- record_fields:
- [ [ f = record_field; ";"; fs = record_fields -> f :: fs
- | f = record_field; ";" -> [f]
- | f = record_field -> [f]
- | -> []
- ] ]
- ;
- record_binder_body:
- [ [ l = binders; oc = of_type_with_opt_coercion;
- t = lconstr -> fun id -> (oc,AssumExpr (id,mkCProdN ~loc:!@loc l t))
- | l = binders; oc = of_type_with_opt_coercion;
- t = lconstr; ":="; b = lconstr -> fun id ->
- (oc,DefExpr (id,mkCLambdaN ~loc:!@loc l b,Some (mkCProdN ~loc:!@loc l t)))
- | l = binders; ":="; b = lconstr -> fun id ->
- match b.CAst.v with
- | CCast(b', (CastConv t|CastVM t|CastNative t)) ->
- (None,DefExpr(id,mkCLambdaN ~loc:!@loc l b',Some (mkCProdN ~loc:!@loc l t)))
- | _ ->
- (None,DefExpr(id,mkCLambdaN ~loc:!@loc l b,None)) ] ]
- ;
- record_binder:
- [ [ id = name -> (None,AssumExpr(id, CAst.make ~loc:!@loc @@ CHole (None, Misctypes.IntroAnonymous, None)))
- | id = name; f = record_binder_body -> f id ] ]
- ;
- assum_list:
- [ [ bl = LIST1 assum_coe -> bl | b = simple_assum_coe -> [b] ] ]
- ;
- assum_coe:
- [ [ "("; a = simple_assum_coe; ")" -> a ] ]
- ;
- simple_assum_coe:
- [ [ idl = LIST1 ident_decl; oc = of_type_with_opt_coercion; c = lconstr ->
- (not (Option.is_empty oc),(idl,c)) ] ]
- ;
-
- constructor_type:
- [[ l = binders;
- t= [ coe = of_type_with_opt_coercion; c = lconstr ->
- fun l id -> (not (Option.is_empty coe),(id,mkCProdN ~loc:!@loc l c))
- | ->
- fun l id -> (false,(id,mkCProdN ~loc:!@loc l (CAst.make ~loc:!@loc @@ CHole (None, Misctypes.IntroAnonymous, None)))) ]
- -> t l
- ]]
-;
-
- constructor:
- [ [ id = identref; c=constructor_type -> c id ] ]
- ;
- of_type_with_opt_coercion:
- [ [ ":>>" -> Some false
- | ":>"; ">" -> Some false
- | ":>" -> Some true
- | ":"; ">"; ">" -> Some false
- | ":"; ">" -> Some true
- | ":" -> None ] ]
- ;
-END
-
-let only_starredidentrefs =
- Gram.Entry.of_parser "test_only_starredidentrefs"
- (fun strm ->
- let rec aux n =
- match Util.stream_nth n strm with
- | KEYWORD "." -> ()
- | KEYWORD ")" -> ()
- | (IDENT _ | KEYWORD "Type" | KEYWORD "*") -> aux (n+1)
- | _ -> raise Stream.Failure in
- aux 0)
-let starredidentreflist_to_expr l =
- match l with
- | [] -> SsEmpty
- | x :: xs -> List.fold_right (fun i acc -> SsUnion(i,acc)) xs x
-
-let warn_deprecated_include_type =
- CWarnings.create ~name:"deprecated-include-type" ~category:"deprecated"
- (fun () -> strbrk "Include Type is deprecated; use Include instead")
-
-(* Modules and Sections *)
-GEXTEND Gram
- GLOBAL: gallina_ext module_expr module_type section_subset_expr;
-
- gallina_ext:
- [ [ (* Interactive module declaration *)
- IDENT "Module"; export = export_token; id = identref;
- bl = LIST0 module_binder; sign = of_module_type;
- body = is_module_expr ->
- VernacDefineModule (export, id, bl, sign, body)
- | IDENT "Module"; "Type"; id = identref;
- bl = LIST0 module_binder; sign = check_module_types;
- body = is_module_type ->
- VernacDeclareModuleType (id, bl, sign, body)
- | IDENT "Declare"; IDENT "Module"; export = export_token; id = identref;
- bl = LIST0 module_binder; ":"; mty = module_type_inl ->
- VernacDeclareModule (export, id, bl, mty)
- (* Section beginning *)
- | IDENT "Section"; id = identref -> VernacBeginSection id
- | IDENT "Chapter"; id = identref -> VernacBeginSection id
-
- (* This end a Section a Module or a Module Type *)
- | IDENT "End"; id = identref -> VernacEndSegment id
-
- (* Naming a set of section hyps *)
- | IDENT "Collection"; id = identref; ":="; expr = section_subset_expr ->
- VernacNameSectionHypSet (id, expr)
-
- (* Requiring an already compiled module *)
- | IDENT "Require"; export = export_token; qidl = LIST1 global ->
- VernacRequire (None, export, qidl)
- | IDENT "From" ; ns = global ; IDENT "Require"; export = export_token
- ; qidl = LIST1 global ->
- VernacRequire (Some ns, export, qidl)
- | IDENT "Import"; qidl = LIST1 global -> VernacImport (false,qidl)
- | IDENT "Export"; qidl = LIST1 global -> VernacImport (true,qidl)
- | IDENT "Include"; e = module_type_inl; l = LIST0 ext_module_expr ->
- VernacInclude(e::l)
- | IDENT "Include"; "Type"; e = module_type_inl; l = LIST0 ext_module_type ->
- warn_deprecated_include_type ~loc:!@loc ();
- VernacInclude(e::l) ] ]
- ;
- export_token:
- [ [ IDENT "Import" -> Some false
- | IDENT "Export" -> Some true
- | -> None ] ]
- ;
- ext_module_type:
- [ [ "<+"; mty = module_type_inl -> mty ] ]
- ;
- ext_module_expr:
- [ [ "<+"; mexpr = module_expr_inl -> mexpr ] ]
- ;
- check_module_type:
- [ [ "<:"; mty = module_type_inl -> mty ] ]
- ;
- check_module_types:
- [ [ mtys = LIST0 check_module_type -> mtys ] ]
- ;
- of_module_type:
- [ [ ":"; mty = module_type_inl -> Enforce mty
- | mtys = check_module_types -> Check mtys ] ]
- ;
- is_module_type:
- [ [ ":="; mty = module_type_inl ; l = LIST0 ext_module_type -> (mty::l)
- | -> [] ] ]
- ;
- is_module_expr:
- [ [ ":="; mexpr = module_expr_inl; l = LIST0 ext_module_expr -> (mexpr::l)
- | -> [] ] ]
- ;
- functor_app_annot:
- [ [ "["; IDENT "inline"; "at"; IDENT "level"; i = INT; "]" ->
- InlineAt (int_of_string i)
- | "["; IDENT "no"; IDENT "inline"; "]" -> NoInline
- | -> DefaultInline
- ] ]
- ;
- module_expr_inl:
- [ [ "!"; me = module_expr -> (me,NoInline)
- | me = module_expr; a = functor_app_annot -> (me,a) ] ]
- ;
- module_type_inl:
- [ [ "!"; me = module_type -> (me,NoInline)
- | me = module_type; a = functor_app_annot -> (me,a) ] ]
- ;
- (* Module binder *)
- module_binder:
- [ [ "("; export = export_token; idl = LIST1 identref; ":";
- mty = module_type_inl; ")" -> (export,idl,mty) ] ]
- ;
- (* Module expressions *)
- module_expr:
- [ [ me = module_expr_atom -> me
- | me1 = module_expr; me2 = module_expr_atom -> CAst.make ~loc:!@loc @@ CMapply (me1,me2)
- ] ]
- ;
- module_expr_atom:
- [ [ qid = qualid -> CAst.make ~loc:!@loc @@ CMident (qid.CAst.v) | "("; me = module_expr; ")" -> me ] ]
- ;
- with_declaration:
- [ [ "Definition"; fqid = fullyqualid; udecl = OPT univ_decl; ":="; c = Constr.lconstr ->
- CWith_Definition (fqid,udecl,c)
- | IDENT "Module"; fqid = fullyqualid; ":="; qid = qualid ->
- CWith_Module (fqid,qid)
- ] ]
- ;
- module_type:
- [ [ qid = qualid -> CAst.make ~loc:!@loc @@ CMident (qid.CAst.v)
- | "("; mt = module_type; ")" -> mt
- | mty = module_type; me = module_expr_atom ->
- CAst.make ~loc:!@loc @@ CMapply (mty,me)
- | mty = module_type; "with"; decl = with_declaration ->
- CAst.make ~loc:!@loc @@ CMwith (mty,decl)
- ] ]
- ;
- (* Proof using *)
- section_subset_expr:
- [ [ only_starredidentrefs; l = LIST0 starredidentref ->
- starredidentreflist_to_expr l
- | e = ssexpr -> e ]]
- ;
- starredidentref:
- [ [ i = identref -> SsSingl i
- | i = identref; "*" -> SsFwdClose(SsSingl i)
- | "Type" -> SsType
- | "Type"; "*" -> SsFwdClose SsType ]]
- ;
- ssexpr:
- [ "35"
- [ "-"; e = ssexpr -> SsCompl e ]
- | "50"
- [ e1 = ssexpr; "-"; e2 = ssexpr->SsSubstr(e1,e2)
- | e1 = ssexpr; "+"; e2 = ssexpr->SsUnion(e1,e2)]
- | "0"
- [ i = starredidentref -> i
- | "("; only_starredidentrefs; l = LIST0 starredidentref; ")"->
- starredidentreflist_to_expr l
- | "("; only_starredidentrefs; l = LIST0 starredidentref; ")"; "*" ->
- SsFwdClose(starredidentreflist_to_expr l)
- | "("; e = ssexpr; ")"-> e
- | "("; e = ssexpr; ")"; "*" -> SsFwdClose e ] ]
- ;
-END
-
-let warn_deprecated_arguments_scope =
- CWarnings.create ~name:"deprecated-arguments-scope" ~category:"deprecated"
- (fun () -> strbrk "Arguments Scope is deprecated; use Arguments instead")
-
-let warn_deprecated_implicit_arguments =
- CWarnings.create ~name:"deprecated-implicit-arguments" ~category:"deprecated"
- (fun () -> strbrk "Implicit Arguments is deprecated; use Arguments instead")
-
-(* Extensions: implicits, coercions, etc. *)
-GEXTEND Gram
- GLOBAL: gallina_ext instance_name hint_info;
-
- gallina_ext:
- [ [ (* Transparent and Opaque *)
- IDENT "Transparent"; l = LIST1 smart_global ->
- VernacSetOpacity (Conv_oracle.transparent, l)
- | IDENT "Opaque"; l = LIST1 smart_global ->
- VernacSetOpacity (Conv_oracle.Opaque, l)
- | IDENT "Strategy"; l =
- LIST1 [ v=strategy_level; "["; q=LIST1 smart_global; "]" -> (v,q)] ->
- VernacSetStrategy l
- (* Canonical structure *)
- | IDENT "Canonical"; IDENT "Structure"; qid = global ->
- VernacCanonical CAst.(make ~loc:!@loc @@ AN qid)
- | IDENT "Canonical"; IDENT "Structure"; ntn = by_notation ->
- VernacCanonical CAst.(make ~loc:!@loc @@ ByNotation ntn)
- | IDENT "Canonical"; IDENT "Structure"; qid = global; d = def_body ->
- let s = coerce_reference_to_id qid in
- VernacDefinition ((NoDischarge,CanonicalStructure),((CAst.make (Name s)),None),d)
-
- (* Coercions *)
- | IDENT "Coercion"; qid = global; d = def_body ->
- let s = coerce_reference_to_id qid in
- VernacDefinition ((NoDischarge,Coercion),((CAst.make (Name s)),None),d)
- | IDENT "Identity"; IDENT "Coercion"; f = identref; ":";
- s = class_rawexpr; ">->"; t = class_rawexpr ->
- VernacIdentityCoercion (f, s, t)
- | IDENT "Coercion"; qid = global; ":"; s = class_rawexpr; ">->";
- t = class_rawexpr ->
- VernacCoercion (CAst.make ~loc:!@loc @@ AN qid, s, t)
- | IDENT "Coercion"; ntn = by_notation; ":"; s = class_rawexpr; ">->";
- t = class_rawexpr ->
- VernacCoercion (CAst.make ~loc:!@loc @@ ByNotation ntn, s, t)
-
- | IDENT "Context"; c = LIST1 binder ->
- VernacContext (List.flatten c)
-
- | IDENT "Instance"; namesup = instance_name; ":";
- expl = [ "!" -> Decl_kinds.Implicit | -> Decl_kinds.Explicit ] ; t = operconstr LEVEL "200";
- info = hint_info ;
- props = [ ":="; "{"; r = record_declaration; "}" -> Some (true,r) |
- ":="; c = lconstr -> Some (false,c) | -> None ] ->
- VernacInstance (false,snd namesup,(fst namesup,expl,t),props,info)
-
- | IDENT "Existing"; IDENT "Instance"; id = global;
- info = hint_info ->
- VernacDeclareInstances [id, info]
-
- | IDENT "Existing"; IDENT "Instances"; ids = LIST1 global;
- pri = OPT [ "|"; i = natural -> i ] ->
- let info = { hint_priority = pri; hint_pattern = None } in
- let insts = List.map (fun i -> (i, info)) ids in
- VernacDeclareInstances insts
-
- | IDENT "Existing"; IDENT "Class"; is = global -> VernacDeclareClass is
-
- (* Arguments *)
- | IDENT "Arguments"; qid = smart_global;
- args = LIST0 argument_spec_block;
- more_implicits = OPT
- [ ","; impl = LIST1
- [ impl = LIST0 more_implicits_block -> List.flatten impl]
- SEP "," -> impl
- ];
- mods = OPT [ ":"; l = LIST1 arguments_modifier SEP "," -> l ] ->
- let mods = match mods with None -> [] | Some l -> List.flatten l in
- let slash_position = ref None in
- let rec parse_args i = function
- | [] -> []
- | `Id x :: args -> x :: parse_args (i+1) args
- | `Slash :: args ->
- if Option.is_empty !slash_position then
- (slash_position := Some i; parse_args i args)
- else
- user_err Pp.(str "The \"/\" modifier can occur only once")
- in
- let args = parse_args 0 (List.flatten args) in
- let more_implicits = Option.default [] more_implicits in
- VernacArguments (qid, args, more_implicits, !slash_position, mods)
-
-
- (* moved there so that camlp5 factors it with the previous rule *)
- | IDENT "Arguments"; IDENT "Scope"; qid = smart_global;
- "["; scl = LIST0 [ "_" -> None | sc = IDENT -> Some sc ]; "]" ->
- warn_deprecated_arguments_scope ~loc:!@loc ();
- VernacArgumentsScope (qid,scl)
-
- (* Implicit *)
- | IDENT "Implicit"; IDENT "Arguments"; qid = smart_global;
- pos = LIST0 [ "["; l = LIST0 implicit_name; "]" ->
- List.map (fun (id,b,f) -> (ExplByName id,b,f)) l ] ->
- warn_deprecated_implicit_arguments ~loc:!@loc ();
- VernacDeclareImplicits (qid,pos)
-
- | IDENT "Implicit"; "Type"; bl = reserv_list ->
- VernacReserve bl
-
- | IDENT "Implicit"; IDENT "Types"; bl = reserv_list ->
- test_plural_form_types loc "Implicit Types" bl;
- VernacReserve bl
-
- | IDENT "Generalizable";
- gen = [IDENT "All"; IDENT "Variables" -> Some []
- | IDENT "No"; IDENT "Variables" -> None
- | ["Variable" | IDENT "Variables"];
- idl = LIST1 identref -> Some idl ] ->
- VernacGeneralizable gen ] ]
- ;
- arguments_modifier:
- [ [ IDENT "simpl"; IDENT "nomatch" -> [`ReductionDontExposeCase]
- | IDENT "simpl"; IDENT "never" -> [`ReductionNeverUnfold]
- | IDENT "default"; IDENT "implicits" -> [`DefaultImplicits]
- | IDENT "clear"; IDENT "implicits" -> [`ClearImplicits]
- | IDENT "clear"; IDENT "scopes" -> [`ClearScopes]
- | IDENT "rename" -> [`Rename]
- | IDENT "assert" -> [`Assert]
- | IDENT "extra"; IDENT "scopes" -> [`ExtraScopes]
- | IDENT "clear"; IDENT "scopes"; IDENT "and"; IDENT "implicits" ->
- [`ClearImplicits; `ClearScopes]
- | IDENT "clear"; IDENT "implicits"; IDENT "and"; IDENT "scopes" ->
- [`ClearImplicits; `ClearScopes]
- ] ]
- ;
- implicit_name:
- [ [ "!"; id = ident -> (id, false, true)
- | id = ident -> (id,false,false)
- | "["; "!"; id = ident; "]" -> (id,true,true)
- | "["; id = ident; "]" -> (id,true, false) ] ]
- ;
- scope:
- [ [ "%"; key = IDENT -> key ] ]
- ;
- argument_spec: [
- [ b = OPT "!"; id = name ; s = OPT scope ->
- id.CAst.v, not (Option.is_empty b), Option.map (fun x -> CAst.make ~loc:!@loc x) s
- ]
- ];
- (* List of arguments implicit status, scope, modifiers *)
- argument_spec_block: [
- [ item = argument_spec ->
- let name, recarg_like, notation_scope = item in
- [`Id { name=name; recarg_like=recarg_like;
- notation_scope=notation_scope;
- implicit_status = NotImplicit}]
- | "/" -> [`Slash]
- | "("; items = LIST1 argument_spec; ")"; sc = OPT scope ->
- let f x = match sc, x with
- | None, x -> x | x, None -> Option.map (fun y -> CAst.make ~loc:!@loc y) x
- | Some _, Some _ -> user_err Pp.(str "scope declared twice") in
- List.map (fun (name,recarg_like,notation_scope) ->
- `Id { name=name; recarg_like=recarg_like;
- notation_scope=f notation_scope;
- implicit_status = NotImplicit}) items
- | "["; items = LIST1 argument_spec; "]"; sc = OPT scope ->
- let f x = match sc, x with
- | None, x -> x | x, None -> Option.map (fun y -> CAst.make ~loc:!@loc y) x
- | Some _, Some _ -> user_err Pp.(str "scope declared twice") in
- List.map (fun (name,recarg_like,notation_scope) ->
- `Id { name=name; recarg_like=recarg_like;
- notation_scope=f notation_scope;
- implicit_status = Implicit}) items
- | "{"; items = LIST1 argument_spec; "}"; sc = OPT scope ->
- let f x = match sc, x with
- | None, x -> x | x, None -> Option.map (fun y -> CAst.make ~loc:!@loc y) x
- | Some _, Some _ -> user_err Pp.(str "scope declared twice") in
- List.map (fun (name,recarg_like,notation_scope) ->
- `Id { name=name; recarg_like=recarg_like;
- notation_scope=f notation_scope;
- implicit_status = MaximallyImplicit}) items
- ]
- ];
- (* Same as [argument_spec_block], but with only implicit status and names *)
- more_implicits_block: [
- [ name = name -> [(name.CAst.v, Vernacexpr.NotImplicit)]
- | "["; items = LIST1 name; "]" ->
- List.map (fun name -> (name.CAst.v, Vernacexpr.Implicit)) items
- | "{"; items = LIST1 name; "}" ->
- List.map (fun name -> (name.CAst.v, Vernacexpr.MaximallyImplicit)) items
- ]
- ];
- strategy_level:
- [ [ IDENT "expand" -> Conv_oracle.Expand
- | IDENT "opaque" -> Conv_oracle.Opaque
- | n=INT -> Conv_oracle.Level (int_of_string n)
- | "-"; n=INT -> Conv_oracle.Level (- int_of_string n)
- | IDENT "transparent" -> Conv_oracle.transparent ] ]
- ;
- instance_name:
- [ [ name = ident_decl; sup = OPT binders ->
- (CAst.map (fun id -> Name id) (fst name), snd name),
- (Option.default [] sup)
- | -> ((CAst.make ~loc:!@loc Anonymous), None), [] ] ]
- ;
- hint_info:
- [ [ "|"; i = OPT natural; pat = OPT constr_pattern ->
- { hint_priority = i; hint_pattern = pat }
- | -> { hint_priority = None; hint_pattern = None } ] ]
- ;
- reserv_list:
- [ [ bl = LIST1 reserv_tuple -> bl | b = simple_reserv -> [b] ] ]
- ;
- reserv_tuple:
- [ [ "("; a = simple_reserv; ")" -> a ] ]
- ;
- simple_reserv:
- [ [ idl = LIST1 identref; ":"; c = lconstr -> (idl,c) ] ]
- ;
-
-END
-
-GEXTEND Gram
- GLOBAL: command query_command class_rawexpr gallina_ext;
-
- gallina_ext:
- [ [ IDENT "Export"; "Set"; table = option_table; v = option_value ->
- VernacSetOption (true, table, v)
- | IDENT "Export"; IDENT "Unset"; table = option_table ->
- VernacUnsetOption (true, table)
- ] ];
-
- command:
- [ [ IDENT "Comments"; l = LIST0 comment -> VernacComments l
-
- (* Hack! Should be in grammar_ext, but camlp5 factorizes badly *)
- | IDENT "Declare"; IDENT "Instance"; namesup = instance_name; ":";
- expl = [ "!" -> Decl_kinds.Implicit | -> Decl_kinds.Explicit ] ; t = operconstr LEVEL "200";
- info = hint_info ->
- VernacInstance (true, snd namesup, (fst namesup, expl, t), None, info)
-
- (* System directory *)
- | IDENT "Pwd" -> VernacChdir None
- | IDENT "Cd" -> VernacChdir None
- | IDENT "Cd"; dir = ne_string -> VernacChdir (Some dir)
-
- (* Toplevel control *)
- | IDENT "Drop" -> VernacToplevelControl Drop
- | IDENT "Quit" -> VernacToplevelControl Quit
-
- | IDENT "Load"; verbosely = [ IDENT "Verbose" -> true | -> false ];
- s = [ s = ne_string -> s | s = IDENT -> s ] ->
- VernacLoad (verbosely, s)
- | IDENT "Declare"; IDENT "ML"; IDENT "Module"; l = LIST1 ne_string ->
- VernacDeclareMLModule l
-
- | IDENT "Locate"; l = locatable -> VernacLocate l
-
- (* Managing load paths *)
- | IDENT "Add"; IDENT "LoadPath"; dir = ne_string; alias = as_dirpath ->
- VernacAddLoadPath (false, dir, alias)
- | IDENT "Add"; IDENT "Rec"; IDENT "LoadPath"; dir = ne_string;
- alias = as_dirpath -> VernacAddLoadPath (true, dir, alias)
- | IDENT "Remove"; IDENT "LoadPath"; dir = ne_string ->
- VernacRemoveLoadPath dir
-
- (* For compatibility *)
- | IDENT "AddPath"; dir = ne_string; "as"; alias = as_dirpath ->
- VernacAddLoadPath (false, dir, alias)
- | IDENT "AddRecPath"; dir = ne_string; "as"; alias = as_dirpath ->
- VernacAddLoadPath (true, dir, alias)
- | IDENT "DelPath"; dir = ne_string ->
- VernacRemoveLoadPath dir
-
- (* Type-Checking (pas dans le refman) *)
- | "Type"; c = lconstr -> VernacGlobalCheck c
-
- (* Printing (careful factorization of entries) *)
- | IDENT "Print"; p = printable -> VernacPrint p
- | IDENT "Print"; qid = smart_global; l = OPT univ_name_list -> VernacPrint (PrintName (qid,l))
- | IDENT "Print"; IDENT "Module"; "Type"; qid = global ->
- VernacPrint (PrintModuleType qid)
- | IDENT "Print"; IDENT "Module"; qid = global ->
- VernacPrint (PrintModule qid)
- | IDENT "Print"; IDENT "Namespace" ; ns = dirpath ->
- VernacPrint (PrintNamespace ns)
- | IDENT "Inspect"; n = natural -> VernacPrint (PrintInspect n)
-
- | IDENT "Add"; IDENT "ML"; IDENT "Path"; dir = ne_string ->
- VernacAddMLPath (false, dir)
- | IDENT "Add"; IDENT "Rec"; IDENT "ML"; IDENT "Path"; dir = ne_string ->
- VernacAddMLPath (true, dir)
-
- (* For acting on parameter tables *)
- | "Set"; table = option_table; v = option_value ->
- VernacSetOption (false, table, v)
- | IDENT "Unset"; table = option_table ->
- VernacUnsetOption (false, table)
-
- | IDENT "Print"; IDENT "Table"; table = option_table ->
- VernacPrintOption table
-
- | IDENT "Add"; table = IDENT; field = IDENT; v = LIST1 option_ref_value
- -> VernacAddOption ([table;field], v)
- (* A global value below will be hidden by a field above! *)
- (* In fact, we give priority to secondary tables *)
- (* No syntax for tertiary tables due to conflict *)
- (* (but they are unused anyway) *)
- | IDENT "Add"; table = IDENT; v = LIST1 option_ref_value ->
- VernacAddOption ([table], v)
-
- | IDENT "Test"; table = option_table; "for"; v = LIST1 option_ref_value
- -> VernacMemOption (table, v)
- | IDENT "Test"; table = option_table ->
- VernacPrintOption table
-
- | IDENT "Remove"; table = IDENT; field = IDENT; v= LIST1 option_ref_value
- -> VernacRemoveOption ([table;field], v)
- | IDENT "Remove"; table = IDENT; v = LIST1 option_ref_value ->
- VernacRemoveOption ([table], v) ]]
- ;
- query_command: (* TODO: rapprocher Eval et Check *)
- [ [ IDENT "Eval"; r = red_expr; "in"; c = lconstr; "." ->
- fun g -> VernacCheckMayEval (Some r, g, c)
- | IDENT "Compute"; c = lconstr; "." ->
- fun g -> VernacCheckMayEval (Some (Genredexpr.CbvVm None), g, c)
- | IDENT "Check"; c = lconstr; "." ->
- fun g -> VernacCheckMayEval (None, g, c)
- (* Searching the environment *)
- | IDENT "About"; qid = smart_global; l = OPT univ_name_list; "." ->
- fun g -> VernacPrint (PrintAbout (qid,l,g))
- | IDENT "SearchHead"; c = constr_pattern; l = in_or_out_modules; "." ->
- fun g -> VernacSearch (SearchHead c,g, l)
- | IDENT "SearchPattern"; c = constr_pattern; l = in_or_out_modules; "." ->
- fun g -> VernacSearch (SearchPattern c,g, l)
- | IDENT "SearchRewrite"; c = constr_pattern; l = in_or_out_modules; "." ->
- fun g -> VernacSearch (SearchRewrite c,g, l)
- | IDENT "Search"; s = searchabout_query; l = searchabout_queries; "." ->
- let (sl,m) = l in fun g -> VernacSearch (SearchAbout (s::sl),g, m)
- (* compatibility: SearchAbout *)
- | IDENT "SearchAbout"; s = searchabout_query; l = searchabout_queries; "." ->
- fun g -> let (sl,m) = l in VernacSearch (SearchAbout (s::sl),g, m)
- (* compatibility: SearchAbout with "[ ... ]" *)
- | IDENT "SearchAbout"; "["; sl = LIST1 searchabout_query; "]";
- l = in_or_out_modules; "." ->
- fun g -> VernacSearch (SearchAbout sl,g, l)
- ] ]
- ;
- printable:
- [ [ IDENT "Term"; qid = smart_global; l = OPT univ_name_list -> PrintName (qid,l)
- | IDENT "All" -> PrintFullContext
- | IDENT "Section"; s = global -> PrintSectionContext s
- | IDENT "Grammar"; ent = IDENT ->
- (* This should be in "syntax" section but is here for factorization*)
- PrintGrammar ent
- | IDENT "LoadPath"; dir = OPT dirpath -> PrintLoadPath dir
- | IDENT "Modules" ->
- user_err Pp.(str "Print Modules is obsolete; use Print Libraries instead")
- | IDENT "Libraries" -> PrintModules
-
- | IDENT "ML"; IDENT "Path" -> PrintMLLoadPath
- | IDENT "ML"; IDENT "Modules" -> PrintMLModules
- | IDENT "Debug"; IDENT "GC" -> PrintDebugGC
- | IDENT "Graph" -> PrintGraph
- | IDENT "Classes" -> PrintClasses
- | IDENT "TypeClasses" -> PrintTypeClasses
- | IDENT "Instances"; qid = smart_global -> PrintInstances qid
- | IDENT "Coercions" -> PrintCoercions
- | IDENT "Coercion"; IDENT "Paths"; s = class_rawexpr; t = class_rawexpr
- -> PrintCoercionPaths (s,t)
- | IDENT "Canonical"; IDENT "Projections" -> PrintCanonicalConversions
- | IDENT "Tables" -> PrintTables
- | IDENT "Options" -> PrintTables (* A Synonymous to Tables *)
- | IDENT "Hint" -> PrintHintGoal
- | IDENT "Hint"; qid = smart_global -> PrintHint qid
- | IDENT "Hint"; "*" -> PrintHintDb
- | IDENT "HintDb"; s = IDENT -> PrintHintDbName s
- | IDENT "Scopes" -> PrintScopes
- | IDENT "Scope"; s = IDENT -> PrintScope s
- | IDENT "Visibility"; s = OPT [x = IDENT -> x ] -> PrintVisibility s
- | IDENT "Implicit"; qid = smart_global -> PrintImplicit qid
- | IDENT "Universes"; fopt = OPT ne_string -> PrintUniverses (false, fopt)
- | IDENT "Sorted"; IDENT "Universes"; fopt = OPT ne_string -> PrintUniverses (true, fopt)
- | IDENT "Assumptions"; qid = smart_global -> PrintAssumptions (false, false, qid)
- | IDENT "Opaque"; IDENT "Dependencies"; qid = smart_global -> PrintAssumptions (true, false, qid)
- | IDENT "Transparent"; IDENT "Dependencies"; qid = smart_global -> PrintAssumptions (false, true, qid)
- | IDENT "All"; IDENT "Dependencies"; qid = smart_global -> PrintAssumptions (true, true, qid)
- | IDENT "Strategy"; qid = smart_global -> PrintStrategy (Some qid)
- | IDENT "Strategies" -> PrintStrategy None ] ]
- ;
- class_rawexpr:
- [ [ IDENT "Funclass" -> FunClass
- | IDENT "Sortclass" -> SortClass
- | qid = smart_global -> RefClass qid ] ]
- ;
- locatable:
- [ [ qid = smart_global -> LocateAny qid
- | IDENT "Term"; qid = smart_global -> LocateTerm qid
- | IDENT "File"; f = ne_string -> LocateFile f
- | IDENT "Library"; qid = global -> LocateLibrary qid
- | IDENT "Module"; qid = global -> LocateModule qid ] ]
- ;
- option_value:
- [ [ -> BoolValue true
- | n = integer -> IntValue (Some n)
- | s = STRING -> StringValue s ] ]
- ;
- option_ref_value:
- [ [ id = global -> QualidRefValue id
- | s = STRING -> StringRefValue s ] ]
- ;
- option_table:
- [ [ fl = LIST1 [ x = IDENT -> x ] -> fl ]]
- ;
- as_dirpath:
- [ [ d = OPT [ "as"; d = dirpath -> d ] -> d ] ]
- ;
- ne_in_or_out_modules:
- [ [ IDENT "inside"; l = LIST1 global -> SearchInside l
- | IDENT "outside"; l = LIST1 global -> SearchOutside l ] ]
- ;
- in_or_out_modules:
- [ [ m = ne_in_or_out_modules -> m
- | -> SearchOutside [] ] ]
- ;
- comment:
- [ [ c = constr -> CommentConstr c
- | s = STRING -> CommentString s
- | n = natural -> CommentInt n ] ]
- ;
- positive_search_mark:
- [ [ "-" -> false | -> true ] ]
- ;
- scope:
- [ [ "%"; key = IDENT -> key ] ]
- ;
- searchabout_query:
- [ [ b = positive_search_mark; s = ne_string; sc = OPT scope ->
- (b, SearchString (s,sc))
- | b = positive_search_mark; p = constr_pattern ->
- (b, SearchSubPattern p)
- ] ]
- ;
- searchabout_queries:
- [ [ m = ne_in_or_out_modules -> ([],m)
- | s = searchabout_query; l = searchabout_queries ->
- let (sl,m) = l in (s::sl,m)
- | -> ([],SearchOutside [])
- ] ]
- ;
- univ_name_list:
- [ [ "@{" ; l = LIST0 name; "}" -> l ] ]
- ;
-END;
-
-GEXTEND Gram
- command:
- [ [
-(* State management *)
- IDENT "Write"; IDENT "State"; s = IDENT -> VernacWriteState s
- | IDENT "Write"; IDENT "State"; s = ne_string -> VernacWriteState s
- | IDENT "Restore"; IDENT "State"; s = IDENT -> VernacRestoreState s
- | IDENT "Restore"; IDENT "State"; s = ne_string -> VernacRestoreState s
-
-(* Resetting *)
- | IDENT "Reset"; IDENT "Initial" -> VernacResetInitial
- | IDENT "Reset"; id = identref -> VernacResetName id
- | IDENT "Back" -> VernacBack 1
- | IDENT "Back"; n = natural -> VernacBack n
- | IDENT "BackTo"; n = natural -> VernacBackTo n
- | IDENT "Backtrack"; n = natural ; m = natural ; p = natural ->
- VernacBacktrack (n,m,p)
-
-(* Tactic Debugger *)
- | IDENT "Debug"; IDENT "On" ->
- VernacSetOption (false, ["Ltac";"Debug"], BoolValue true)
-
- | IDENT "Debug"; IDENT "Off" ->
- VernacSetOption (false, ["Ltac";"Debug"], BoolValue false)
-
-(* registration of a custom reduction *)
-
- | IDENT "Declare"; IDENT "Reduction"; s = IDENT; ":=";
- r = red_expr ->
- VernacDeclareReduction (s,r)
-
- ] ];
- END
-;;
-
-(* Grammar extensions *)
-
-GEXTEND Gram
- GLOBAL: syntax;
-
- syntax:
- [ [ IDENT "Open"; IDENT "Scope"; sc = IDENT ->
- VernacOpenCloseScope (true,sc)
-
- | IDENT "Close"; IDENT "Scope"; sc = IDENT ->
- VernacOpenCloseScope (false,sc)
-
- | IDENT "Delimit"; IDENT "Scope"; sc = IDENT; "with"; key = IDENT ->
- VernacDelimiters (sc, Some key)
- | IDENT "Undelimit"; IDENT "Scope"; sc = IDENT ->
- VernacDelimiters (sc, None)
-
- | IDENT "Bind"; IDENT "Scope"; sc = IDENT; "with";
- refl = LIST1 class_rawexpr -> VernacBindScope (sc,refl)
-
- | IDENT "Infix"; op = ne_lstring; ":="; p = constr;
- modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ];
- sc = OPT [ ":"; sc = IDENT -> sc ] ->
- VernacInfix ((op,modl),p,sc)
- | IDENT "Notation"; id = identref;
- idl = LIST0 ident; ":="; c = constr; b = only_parsing ->
- VernacSyntacticDefinition
- (id,(idl,c),b)
- | IDENT "Notation"; s = lstring; ":=";
- c = constr;
- modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ];
- sc = OPT [ ":"; sc = IDENT -> sc ] ->
- VernacNotation (c,(s,modl),sc)
- | IDENT "Format"; IDENT "Notation"; n = STRING; s = STRING; fmt = STRING ->
- VernacNotationAddFormat (n,s,fmt)
-
- | IDENT "Reserved"; IDENT "Infix"; s = ne_lstring;
- l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ] ->
- let s = CAst.map (fun s -> "x '"^s^"' y") s in
- VernacSyntaxExtension (true,(s,l))
-
- | IDENT "Reserved"; IDENT "Notation";
- s = ne_lstring;
- l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ]
- -> VernacSyntaxExtension (false, (s,l))
-
- (* "Print" "Grammar" should be here but is in "command" entry in order
- to factorize with other "Print"-based vernac entries *)
- ] ]
- ;
- only_parsing:
- [ [ "("; IDENT "only"; IDENT "parsing"; ")" ->
- Some Flags.Current
- | "("; IDENT "compat"; s = STRING; ")" ->
- Some (parse_compat_version s)
- | -> None ] ]
- ;
- level:
- [ [ IDENT "level"; n = natural -> NumLevel n
- | IDENT "next"; IDENT "level" -> NextLevel ] ]
- ;
- syntax_modifier:
- [ [ "at"; IDENT "level"; n = natural -> SetLevel n
- | IDENT "left"; IDENT "associativity" -> SetAssoc LeftA
- | IDENT "right"; IDENT "associativity" -> SetAssoc RightA
- | IDENT "no"; IDENT "associativity" -> SetAssoc NonA
- | IDENT "only"; IDENT "printing" -> SetOnlyPrinting
- | IDENT "only"; IDENT "parsing" -> SetOnlyParsing
- | IDENT "compat"; s = STRING ->
- SetCompatVersion (parse_compat_version s)
- | IDENT "format"; s1 = [s = STRING -> CAst.make ~loc:!@loc s];
- s2 = OPT [s = STRING -> CAst.make ~loc:!@loc s] ->
- begin match s1, s2 with
- | { CAst.v = k }, Some s -> SetFormat(k,s)
- | s, None -> SetFormat ("text",s) end
- | x = IDENT; ","; l = LIST1 [id = IDENT -> id ] SEP ","; "at";
- lev = level -> SetItemLevel (x::l,lev)
- | x = IDENT; "at"; lev = level -> SetItemLevel ([x],lev)
- | x = IDENT; "at"; lev = level; b = constr_as_binder_kind -> SetItemLevelAsBinder ([x],b,Some lev)
- | x = IDENT; b = constr_as_binder_kind -> SetItemLevelAsBinder ([x],b,None)
- | x = IDENT; typ = syntax_extension_type -> SetEntryType (x,typ)
- ] ]
- ;
- syntax_extension_type:
- [ [ IDENT "ident" -> ETName | IDENT "global" -> ETReference
- | IDENT "bigint" -> ETBigint
- | IDENT "binder" -> ETBinder true
- | IDENT "constr"; n = OPT at_level; b = constr_as_binder_kind -> ETConstrAsBinder (b,n)
- | IDENT "pattern" -> ETPattern (false,None)
- | IDENT "pattern"; "at"; IDENT "level"; n = natural -> ETPattern (false,Some n)
- | IDENT "strict"; IDENT "pattern" -> ETPattern (true,None)
- | IDENT "strict"; IDENT "pattern"; "at"; IDENT "level"; n = natural -> ETPattern (true,Some n)
- | IDENT "closed"; IDENT "binder" -> ETBinder false
- ] ]
- ;
- at_level:
- [ [ "at"; n = level -> n ] ]
- ;
- constr_as_binder_kind:
- [ [ "as"; IDENT "ident" -> AsIdent
- | "as"; IDENT "pattern" -> AsIdentOrPattern
- | "as"; IDENT "strict"; IDENT "pattern" -> AsStrictPattern ] ]
- ;
-END
diff --git a/parsing/notation_gram.ml b/parsing/notation_gram.ml
new file mode 100644
index 00000000..d8c08803
--- /dev/null
+++ b/parsing/notation_gram.ml
@@ -0,0 +1,43 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Names
+open Extend
+
+(** Dealing with precedences *)
+
+type precedence = int
+type parenRelation = L | E | Any | Prec of precedence
+type tolerability = precedence * parenRelation
+
+type level = Constrexpr.notation_entry * precedence * tolerability list * constr_entry_key list
+ (* first argument is InCustomEntry s for custom entries *)
+
+type grammar_constr_prod_item =
+ | GramConstrTerminal of Tok.t
+ | GramConstrNonTerminal of Extend.constr_prod_entry_key * Id.t option
+ | GramConstrListMark of int * bool * int
+ (* tells action rule to make a list of the n previous parsed items;
+ concat with last parsed list when true; additionally release
+ the p last items as if they were parsed autonomously *)
+
+(** Grammar rules for a notation *)
+
+type one_notation_grammar = {
+ notgram_level : level;
+ notgram_assoc : Extend.gram_assoc option;
+ notgram_notation : Constrexpr.notation;
+ notgram_prods : grammar_constr_prod_item list list;
+}
+
+type notation_grammar = {
+ notgram_onlyprinting : bool;
+ notgram_rules : one_notation_grammar list
+}
diff --git a/parsing/notgram_ops.ml b/parsing/notgram_ops.ml
new file mode 100644
index 00000000..5cc1292c
--- /dev/null
+++ b/parsing/notgram_ops.ml
@@ -0,0 +1,71 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Pp
+open CErrors
+open Util
+open Notation
+open Notation_gram
+
+(* Uninterpreted notation levels *)
+
+let notation_level_map = Summary.ref ~name:"notation_level_map" NotationMap.empty
+
+let declare_notation_level ?(onlyprint=false) ntn level =
+ try
+ let (level,onlyprint) = NotationMap.find ntn !notation_level_map in
+ if not onlyprint then anomaly (str "Notation " ++ pr_notation ntn ++ str " is already assigned a level.")
+ with Not_found ->
+ notation_level_map := NotationMap.add ntn (level,onlyprint) !notation_level_map
+
+let level_of_notation ?(onlyprint=false) ntn =
+ let (level,onlyprint') = NotationMap.find ntn !notation_level_map in
+ if onlyprint' && not onlyprint then raise Not_found;
+ level
+
+(**********************************************************************)
+(* Equality *)
+
+open Extend
+
+let parenRelation_eq t1 t2 = match t1, t2 with
+| L, L | E, E | Any, Any -> true
+| Prec l1, Prec l2 -> Int.equal l1 l2
+| _ -> false
+
+let production_position_eq pp1 pp2 = match (pp1,pp2) with
+| BorderProd (side1,assoc1), BorderProd (side2,assoc2) -> side1 = side2 && assoc1 = assoc2
+| InternalProd, InternalProd -> true
+| (BorderProd _ | InternalProd), _ -> false
+
+let production_level_eq l1 l2 = match (l1,l2) with
+| NextLevel, NextLevel -> true
+| NumLevel n1, NumLevel n2 -> Int.equal n1 n2
+| (NextLevel | NumLevel _), _ -> false
+
+let constr_entry_key_eq eq v1 v2 = match v1, v2 with
+| ETIdent, ETIdent -> true
+| ETGlobal, ETGlobal -> true
+| ETBigint, ETBigint -> true
+| ETBinder b1, ETBinder b2 -> b1 == b2
+| ETConstr (s1,bko1,lev1), ETConstr (s2,bko2,lev2) ->
+ notation_entry_eq s1 s2 && eq lev1 lev2 && Option.equal (=) bko1 bko2
+| ETPattern (b1,n1), ETPattern (b2,n2) -> b1 = b2 && Option.equal Int.equal n1 n2
+| (ETIdent | ETGlobal | ETBigint | ETBinder _ | ETConstr _ | ETPattern _), _ -> false
+
+let level_eq_gen strict (s1, l1, t1, u1) (s2, l2, t2, u2) =
+ let tolerability_eq (i1, r1) (i2, r2) = Int.equal i1 i2 && parenRelation_eq r1 r2 in
+ let prod_eq (l1,pp1) (l2,pp2) =
+ not strict ||
+ (production_level_eq l1 l2 && production_position_eq pp1 pp2) in
+ notation_entry_eq s1 s2 && Int.equal l1 l2 && List.equal tolerability_eq t1 t2
+ && List.equal (constr_entry_key_eq prod_eq) u1 u2
+
+let level_eq = level_eq_gen false
diff --git a/parsing/notgram_ops.mli b/parsing/notgram_ops.mli
new file mode 100644
index 00000000..f427a607
--- /dev/null
+++ b/parsing/notgram_ops.mli
@@ -0,0 +1,20 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* Merge with metasyntax? *)
+open Constrexpr
+open Notation_gram
+
+val level_eq : level -> level -> bool
+
+(** {6 Declare and test the level of a (possibly uninterpreted) notation } *)
+
+val declare_notation_level : ?onlyprint:bool -> notation -> level -> unit
+val level_of_notation : ?onlyprint:bool -> notation -> level (** raise [Not_found] if no level or not respecting onlyprint *)
diff --git a/parsing/parsing.mllib b/parsing/parsing.mllib
index 1f29636b..2154f2f8 100644
--- a/parsing/parsing.mllib
+++ b/parsing/parsing.mllib
@@ -1,9 +1,9 @@
Tok
CLexer
+Extend
+Notation_gram
+Ppextend
+Notgram_ops
Pcoq
-Egramml
-Egramcoq
G_constr
-G_vernac
G_prim
-G_proofs
diff --git a/parsing/pcoq.ml b/parsing/pcoq.ml
index 258c4bb1..eb3e6338 100644
--- a/parsing/pcoq.ml
+++ b/parsing/pcoq.ml
@@ -17,9 +17,17 @@ let curry f x y = f (x, y)
let uncurry f (x,y) = f x y
(** Location Utils *)
+let ploc_file_of_coq_file = function
+| Loc.ToplevelInput -> ""
+| Loc.InFile f -> f
+
let coq_file_of_ploc_file s =
if s = "" then Loc.ToplevelInput else Loc.InFile s
+let of_coqloc loc =
+ let open Loc in
+ Ploc.make_loc (ploc_file_of_coq_file loc.fname) loc.line_nb loc.bol_pos (loc.bp, loc.ep) ""
+
let to_coqloc loc =
{ Loc.fname = coq_file_of_ploc_file (Ploc.file_name loc);
Loc.line_nb = Ploc.line_nb loc;
@@ -78,24 +86,15 @@ module type S =
type internal_entry = Tok.t Gramext.g_entry
type symbol = Tok.t Gramext.g_symbol
type action = Gramext.g_action
- type production_rule = symbol list * action
- type single_extend_statment =
- string option * Gramext.g_assoc option * production_rule list
- type extend_statment =
- Gramext.position option * single_extend_statment list
type coq_parsable
- val parsable : ?file:Loc.source -> char Stream.t -> coq_parsable
+ val coq_parsable : ?file:Loc.source -> char Stream.t -> coq_parsable
val action : 'a -> action
val entry_create : string -> 'a entry
val entry_parse : 'a entry -> coq_parsable -> 'a
- val entry_print : Format.formatter -> 'a entry -> unit
val comment_state : coq_parsable -> ((int * int) * string) list
- val srules' : production_rule list -> symbol
- val parse_tokens_after_filter : 'a entry -> Tok.t Stream.t -> 'a
-
end with type 'a Entry.e = 'a Grammar.GMake(CLexer).Entry.e = struct
include Grammar.GMake(CLexer)
@@ -104,15 +103,10 @@ end with type 'a Entry.e = 'a Grammar.GMake(CLexer).Entry.e = struct
type internal_entry = Tok.t Gramext.g_entry
type symbol = Tok.t Gramext.g_symbol
type action = Gramext.g_action
- type production_rule = symbol list * action
- type single_extend_statment =
- string option * Gramext.g_assoc option * production_rule list
- type extend_statment =
- Gramext.position option * single_extend_statment list
type coq_parsable = parsable * CLexer.lexer_state ref
- let parsable ?(file=Loc.ToplevelInput) c =
+ let coq_parsable ?(file=Loc.ToplevelInput) c =
let state = ref (CLexer.init_lexer_state file) in
CLexer.set_lexer_state !state;
let a = parsable c in
@@ -137,14 +131,25 @@ end with type 'a Entry.e = 'a Grammar.GMake(CLexer).Entry.e = struct
let comment_state (p,state) =
CLexer.get_comment_state !state
- let entry_print ft x = Entry.print ft x
-
- (* Not used *)
- let srules' = Gramext.srules
- let parse_tokens_after_filter = Entry.parse_token
+end
+module Parsable =
+struct
+ type t = G.coq_parsable
+ let make = G.coq_parsable
+ let comment_state = G.comment_state
end
+module Entry =
+struct
+
+ type 'a t = 'a Grammar.GMake(CLexer).Entry.e
+
+ let create = G.Entry.create
+ let parse = G.entry_parse
+ let print = G.Entry.print
+
+end
let warning_verbose = Gramext.warning_verbose
@@ -208,9 +213,9 @@ let camlp5_verbosity silent f x =
(** Grammar extensions *)
-(** NB: [extend_statment =
- gram_position option * single_extend_statment list]
- and [single_extend_statment =
+(** NB: [extend_statement =
+ gram_position option * single_extend_statement list]
+ and [single_extend_statement =
string option * gram_assoc option * production_rule list]
and [production_rule = symbol list * action]
@@ -237,9 +242,9 @@ let rec symbol_of_prod_entry_key : type s a. (s, a) symbol -> _ = function
| Aentry e ->
Symbols.snterm (G.Entry.obj e)
| Aentryl (e, n) ->
- Symbols.snterml (G.Entry.obj e, string_of_int n)
+ Symbols.snterml (G.Entry.obj e, n)
| Arules rs ->
- G.srules' (List.map symbol_of_rules rs)
+ Gramext.srules (List.map symbol_of_rules rs)
and symbol_of_rule : type s a r. (s, a, r) Extend.rule -> _ = function
| Stop -> fun accu -> accu
@@ -264,16 +269,23 @@ let of_coq_extend_statement (pos, st) =
type gram_reinit = gram_assoc * gram_position
type extend_rule =
-| ExtendRule : 'a G.entry * gram_reinit option * 'a extend_statment -> extend_rule
+| ExtendRule : 'a G.entry * gram_reinit option * 'a extend_statement -> extend_rule
+
+module EntryCommand = Dyn.Make ()
+module EntryData = struct type _ t = Ex : 'b G.entry String.Map.t -> ('a * 'b) t end
+module EntryDataMap = EntryCommand.Map(EntryData)
type ext_kind =
| ByGrammar of extend_rule
| ByEXTEND of (unit -> unit) * (unit -> unit)
+ | ByEntry : ('a * 'b) EntryCommand.tag * string * 'b G.entry -> ext_kind
(** The list of extensions *)
let camlp5_state = ref []
+let camlp5_entries = ref EntryDataMap.empty
+
(** Deletion *)
let grammar_delete e reinit (pos,rls) =
@@ -329,6 +341,7 @@ module Gram =
I'm not entirely sure it makes sense, but at least it would be more correct.
*)
G.delete_rule e pil
+ let gram_extend e ext = grammar_extend e None ext
end
(** Remove extensions
@@ -338,7 +351,7 @@ module Gram =
let rec remove_grammars n =
if n>0 then
- (match !camlp5_state with
+ match !camlp5_state with
| [] -> anomaly ~label:"Pcoq.remove_grammars" (Pp.str "too many rules to remove.")
| ByGrammar (ExtendRule (g, reinit, ext)) :: t ->
grammar_delete g reinit (of_coq_extend_statement ext);
@@ -349,21 +362,31 @@ let rec remove_grammars n =
camlp5_state := t;
remove_grammars n;
redo();
- camlp5_state := ByEXTEND (undo,redo) :: !camlp5_state)
+ camlp5_state := ByEXTEND (undo,redo) :: !camlp5_state
+ | ByEntry (tag, name, e) :: t ->
+ G.Unsafe.clear_entry e;
+ camlp5_state := t;
+ let EntryData.Ex entries =
+ try EntryDataMap.find tag !camlp5_entries
+ with Not_found -> EntryData.Ex String.Map.empty
+ in
+ let entries = String.Map.remove name entries in
+ camlp5_entries := EntryDataMap.add tag (EntryData.Ex entries) !camlp5_entries;
+ remove_grammars (n - 1)
let make_rule r = [None, None, r]
(** An entry that checks we reached the end of the input. *)
let eoi_entry en =
- let e = Gram.entry_create ((Gram.Entry.name en) ^ "_eoi") in
+ let e = Entry.create ((Gram.Entry.name en) ^ "_eoi") in
let symbs = [Symbols.snterm (Gram.Entry.obj en); Symbols.stoken Tok.EOI] in
let act = Gram.action (fun _ x loc -> x) in
uncurry (Gram.extend e) (None, make_rule [symbs, act]);
e
let map_entry f en =
- let e = Gram.entry_create ((Gram.Entry.name en) ^ "_map") in
+ let e = Entry.create ((Gram.Entry.name en) ^ "_map") in
let symbs = [Symbols.snterm (Gram.Entry.obj en)] in
let act = Gram.action (fun x loc -> f x) in
uncurry (Gram.extend e) (None, make_rule [symbs, act]);
@@ -373,7 +396,7 @@ let map_entry f en =
(use eoi_entry) *)
let parse_string f x =
- let strm = Stream.of_string x in Gram.entry_parse f (Gram.parsable strm)
+ let strm = Stream.of_string x in Gram.entry_parse f (Gram.coq_parsable strm)
type gram_universe = string
@@ -387,7 +410,6 @@ let create_universe u =
let uprim = create_universe "prim"
let uconstr = create_universe "constr"
let utactic = create_universe "tactic"
-let uvernac = create_universe "vernac"
let get_univ u =
if Hashtbl.mem utables u then u
@@ -395,14 +417,14 @@ let get_univ u =
let new_entry u s =
let ename = u ^ ":" ^ s in
- let e = Gram.entry_create ename in
+ let e = Entry.create ename in
e
let make_gen_entry u s = new_entry u s
module GrammarObj =
struct
- type ('r, _, _) obj = 'r Gram.entry
+ type ('r, _, _) obj = 'r Entry.t
let name = "grammar"
let default _ = None
end
@@ -412,7 +434,7 @@ module Grammar = Register(GrammarObj)
let register_grammar = Grammar.register0
let genarg_grammar = Grammar.obj
-let create_generic_entry (type a) u s (etyp : a raw_abstract_argument_type) : a Gram.entry =
+let create_generic_entry (type a) u s (etyp : a raw_abstract_argument_type) : a Entry.t =
let e = new_entry u s in
let Rawwit t = etyp in
let () = Grammar.register0 t e in
@@ -424,38 +446,38 @@ module Prim =
struct
let gec_gen n = make_gen_entry uprim n
- (* Entries that can be referred via the string -> Gram.entry table *)
+ (* Entries that can be referred via the string -> Entry.t table *)
(* Typically for tactic or vernac extensions *)
let preident = gec_gen "preident"
let ident = gec_gen "ident"
let natural = gec_gen "natural"
let integer = gec_gen "integer"
- let bigint = Gram.entry_create "Prim.bigint"
+ let bigint = Entry.create "Prim.bigint"
let string = gec_gen "string"
- let lstring = Gram.entry_create "Prim.lstring"
+ let lstring = Entry.create "Prim.lstring"
let reference = make_gen_entry uprim "reference"
- let by_notation = Gram.entry_create "by_notation"
- let smart_global = Gram.entry_create "smart_global"
+ let by_notation = Entry.create "by_notation"
+ let smart_global = Entry.create "smart_global"
(* parsed like ident but interpreted as a term *)
let var = gec_gen "var"
- let name = Gram.entry_create "Prim.name"
- let identref = Gram.entry_create "Prim.identref"
- let univ_decl = Gram.entry_create "Prim.univ_decl"
- let ident_decl = Gram.entry_create "Prim.ident_decl"
- let pattern_ident = Gram.entry_create "pattern_ident"
- let pattern_identref = Gram.entry_create "pattern_identref"
+ let name = Entry.create "Prim.name"
+ let identref = Entry.create "Prim.identref"
+ let univ_decl = Entry.create "Prim.univ_decl"
+ let ident_decl = Entry.create "Prim.ident_decl"
+ let pattern_ident = Entry.create "pattern_ident"
+ let pattern_identref = Entry.create "pattern_identref"
(* A synonym of ident - maybe ident will be located one day *)
- let base_ident = Gram.entry_create "Prim.base_ident"
+ let base_ident = Entry.create "Prim.base_ident"
- let qualid = Gram.entry_create "Prim.qualid"
- let fullyqualid = Gram.entry_create "Prim.fullyqualid"
- let dirpath = Gram.entry_create "Prim.dirpath"
+ let qualid = Entry.create "Prim.qualid"
+ let fullyqualid = Entry.create "Prim.fullyqualid"
+ let dirpath = Entry.create "Prim.dirpath"
- let ne_string = Gram.entry_create "Prim.ne_string"
- let ne_lstring = Gram.entry_create "Prim.ne_lstring"
+ let ne_string = Entry.create "Prim.ne_string"
+ let ne_lstring = Entry.create "Prim.ne_lstring"
end
@@ -463,7 +485,7 @@ module Constr =
struct
let gec_constr = make_gen_entry uconstr
- (* Entries that can be referred via the string -> Gram.entry table *)
+ (* Entries that can be referred via the string -> Entry.t table *)
let constr = gec_constr "constr"
let operconstr = gec_constr "operconstr"
let constr_eoi = eoi_entry constr
@@ -474,67 +496,29 @@ module Constr =
let universe_level = make_gen_entry uconstr "universe_level"
let sort = make_gen_entry uconstr "sort"
let sort_family = make_gen_entry uconstr "sort_family"
- let pattern = Gram.entry_create "constr:pattern"
+ let pattern = Entry.create "constr:pattern"
let constr_pattern = gec_constr "constr_pattern"
let lconstr_pattern = gec_constr "lconstr_pattern"
- let closed_binder = Gram.entry_create "constr:closed_binder"
- let binder = Gram.entry_create "constr:binder"
- let binders = Gram.entry_create "constr:binders"
- let open_binders = Gram.entry_create "constr:open_binders"
- let binders_fixannot = Gram.entry_create "constr:binders_fixannot"
- let typeclass_constraint = Gram.entry_create "constr:typeclass_constraint"
- let record_declaration = Gram.entry_create "constr:record_declaration"
- let appl_arg = Gram.entry_create "constr:appl_arg"
+ let closed_binder = Entry.create "constr:closed_binder"
+ let binder = Entry.create "constr:binder"
+ let binders = Entry.create "constr:binders"
+ let open_binders = Entry.create "constr:open_binders"
+ let binders_fixannot = Entry.create "constr:binders_fixannot"
+ let typeclass_constraint = Entry.create "constr:typeclass_constraint"
+ let record_declaration = Entry.create "constr:record_declaration"
+ let appl_arg = Entry.create "constr:appl_arg"
end
module Module =
struct
- let module_expr = Gram.entry_create "module_expr"
- let module_type = Gram.entry_create "module_type"
+ let module_expr = Entry.create "module_expr"
+ let module_type = Entry.create "module_type"
end
-module Vernac_ =
- struct
- let gec_vernac s = Gram.entry_create ("vernac:" ^ s)
-
- (* The different kinds of vernacular commands *)
- let gallina = gec_vernac "gallina"
- let gallina_ext = gec_vernac "gallina_ext"
- let command = gec_vernac "command"
- let syntax = gec_vernac "syntax_command"
- let vernac_control = gec_vernac "Vernac.vernac_control"
- let rec_definition = gec_vernac "Vernac.rec_definition"
- let red_expr = make_gen_entry utactic "red_expr"
- let hint_info = gec_vernac "hint_info"
- (* Main vernac entry *)
- let main_entry = Gram.entry_create "vernac"
- let noedit_mode = gec_vernac "noedit_command"
-
- let () =
- let act_vernac = Gram.action (fun v loc -> Some (to_coqloc loc, v)) in
- let act_eoi = Gram.action (fun _ loc -> None) in
- let rule = [
- ([ Symbols.stoken Tok.EOI ], act_eoi);
- ([ Symbols.snterm (Gram.Entry.obj vernac_control) ], act_vernac );
- ] in
- uncurry (Gram.extend main_entry) (None, make_rule rule)
-
- let command_entry_ref = ref noedit_mode
- let command_entry =
- Gram.Entry.of_parser "command_entry"
- (fun strm -> Gram.parse_tokens_after_filter !command_entry_ref strm)
-
- end
-
-let main_entry = Vernac_.main_entry
-
-let set_command_entry e = Vernac_.command_entry_ref := e
-let get_command_entry () = !Vernac_.command_entry_ref
-
let epsilon_value f e =
let r = Rule (Next (Stop, e), fun x _ -> f x) in
let ext = of_coq_extend_statement (None, [None, None, [r]]) in
- let entry = G.entry_create "epsilon" in
+ let entry = Gram.entry_create "epsilon" in
let () = uncurry (G.extend entry) ext in
try Some (parse_string entry "") with _ -> None
@@ -550,59 +534,119 @@ module GrammarInterpMap = GrammarCommand.Map(GrammarInterp)
let grammar_interp = ref GrammarInterpMap.empty
-let (grammar_stack : (int * GrammarCommand.t * GramState.t) list ref) = ref []
+type ('a, 'b) entry_extension = 'a -> GramState.t -> string list * GramState.t
+
+module EntryInterp = struct type _ t = Ex : ('a, 'b) entry_extension -> ('a * 'b) t end
+module EntryInterpMap = EntryCommand.Map(EntryInterp)
+
+let entry_interp = ref EntryInterpMap.empty
+
+type grammar_entry =
+| GramExt of int * GrammarCommand.t
+| EntryExt : int * ('a * 'b) EntryCommand.tag * 'a -> grammar_entry
+
+let (grammar_stack : (grammar_entry * GramState.t) list ref) = ref []
type 'a grammar_command = 'a GrammarCommand.tag
+type ('a, 'b) entry_command = ('a * 'b) EntryCommand.tag
let create_grammar_command name interp : _ grammar_command =
let obj = GrammarCommand.create name in
let () = grammar_interp := GrammarInterpMap.add obj interp !grammar_interp in
obj
+let create_entry_command name (interp : ('a, 'b) entry_extension) : ('a, 'b) entry_command =
+ let obj = EntryCommand.create name in
+ let () = entry_interp := EntryInterpMap.add obj (EntryInterp.Ex interp) !entry_interp in
+ obj
+
let extend_grammar_command tag g =
let modify = GrammarInterpMap.find tag !grammar_interp in
let grammar_state = match !grammar_stack with
| [] -> GramState.empty
- | (_, _, st) :: _ -> st
+ | (_, st) :: _ -> st
in
let (rules, st) = modify g grammar_state in
let iter (ExtendRule (e, reinit, ext)) = grammar_extend_sync e reinit ext in
let () = List.iter iter rules in
let nb = List.length rules in
- grammar_stack := (nb, GrammarCommand.Dyn (tag, g), st) :: !grammar_stack
+ grammar_stack := (GramExt (nb, GrammarCommand.Dyn (tag, g)), st) :: !grammar_stack
-let recover_grammar_command (type a) (tag : a grammar_command) : a list =
- let filter : _ -> a option = fun (_, GrammarCommand.Dyn (tag', v), _) ->
- match GrammarCommand.eq tag tag' with
- | None -> None
- | Some Refl -> Some v
+let extend_entry_command (type a) (type b) (tag : (a, b) entry_command) (g : a) : b Gram.entry list =
+ let EntryInterp.Ex modify = EntryInterpMap.find tag !entry_interp in
+ let grammar_state = match !grammar_stack with
+ | [] -> GramState.empty
+ | (_, st) :: _ -> st
+ in
+ let (names, st) = modify g grammar_state in
+ let entries = List.map (fun name -> Gram.entry_create name) names in
+ let iter name e =
+ camlp5_state := ByEntry (tag, name, e) :: !camlp5_state;
+ let EntryData.Ex old =
+ try EntryDataMap.find tag !camlp5_entries
+ with Not_found -> EntryData.Ex String.Map.empty
+ in
+ let entries = String.Map.add name e old in
+ camlp5_entries := EntryDataMap.add tag (EntryData.Ex entries) !camlp5_entries
in
- List.map_filter filter !grammar_stack
+ let () = List.iter2 iter names entries in
+ let nb = List.length entries in
+ let () = grammar_stack := (EntryExt (nb, tag, g), st) :: !grammar_stack in
+ entries
+
+let find_custom_entry tag name =
+ let EntryData.Ex map = EntryDataMap.find tag !camlp5_entries in
+ String.Map.find name map
+
+let extend_dyn_grammar (e, _) = match e with
+| GramExt (_, (GrammarCommand.Dyn (tag, g))) -> extend_grammar_command tag g
+| EntryExt (_, tag, g) -> ignore (extend_entry_command tag g)
+
+(** Registering extra grammar *)
-let extend_dyn_grammar (GrammarCommand.Dyn (tag, g)) = extend_grammar_command tag g
+type any_entry = AnyEntry : 'a Gram.entry -> any_entry
+
+let grammar_names : any_entry list String.Map.t ref = ref String.Map.empty
-(* Summary functions: the state of the lexer is included in that of the parser.
+let register_grammars_by_name name grams =
+ grammar_names := String.Map.add name grams !grammar_names
+
+let find_grammars_by_name name =
+ try String.Map.find name !grammar_names
+ with Not_found ->
+ let fold (EntryDataMap.Any (tag, EntryData.Ex map)) accu =
+ try AnyEntry (String.Map.find name map) :: accu
+ with Not_found -> accu
+ in
+ EntryDataMap.fold fold !camlp5_entries []
+
+(** Summary functions: the state of the lexer is included in that of the parser.
Because the grammar affects the set of keywords when adding or removing
grammar rules. *)
-type frozen_t = (int * GrammarCommand.t * GramState.t) list * CLexer.keyword_state
+type frozen_t =
+ (grammar_entry * GramState.t) list *
+ CLexer.keyword_state
-let freeze _ : frozen_t = (!grammar_stack, CLexer.get_keyword_state ())
+let freeze _ : frozen_t =
+ (!grammar_stack, CLexer.get_keyword_state ())
(* We compare the current state of the grammar and the state to unfreeze,
by computing the longest common suffixes *)
let factorize_grams l1 l2 =
if l1 == l2 then ([], [], l1) else List.share_tails l1 l2
-let number_of_entries gcl =
- List.fold_left (fun n (p,_,_) -> n + p) 0 gcl
+let rec number_of_entries accu = function
+| [] -> accu
+| ((GramExt (p, _) | EntryExt (p, _, _)), _) :: rem ->
+ number_of_entries (p + accu) rem
let unfreeze (grams, lex) =
let (undo, redo, common) = factorize_grams !grammar_stack grams in
- let n = number_of_entries undo in
+ let n = number_of_entries 0 undo in
remove_grammars n;
grammar_stack := common;
CLexer.set_keyword_state lex;
- List.iter extend_dyn_grammar (List.rev_map pi2 redo)
+ List.iter extend_dyn_grammar (List.rev redo)
(** No need to provide an init function : the grammar state is
statically available, and already empty initially, while
@@ -635,17 +679,4 @@ let () =
Grammar.register0 wit_ref (Prim.reference);
Grammar.register0 wit_sort_family (Constr.sort_family);
Grammar.register0 wit_constr (Constr.constr);
- Grammar.register0 wit_red_expr (Vernac_.red_expr);
()
-
-(** Registering extra grammar *)
-
-type any_entry = AnyEntry : 'a Gram.entry -> any_entry
-
-let grammar_names : any_entry list String.Map.t ref = ref String.Map.empty
-
-let register_grammars_by_name name grams =
- grammar_names := String.Map.add name grams !grammar_names
-
-let find_grammars_by_name name =
- String.Map.find name !grammar_names
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index 9f186224..e12ccaa6 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -10,85 +10,48 @@
open Names
open Extend
-open Vernacexpr
open Genarg
open Constrexpr
open Libnames
-open Misctypes
-open Genredexpr
(** The parser of Coq *)
+(** DO NOT USE EXTENSION FUNCTIONS IN THIS MODULE.
+ We only have it here to work with Camlp5. Handwritten grammar extensions
+ should use the safe [Pcoq.grammar_extend] function below. *)
module Gram : sig
include Grammar.S with type te = Tok.t
-(* Where Grammar.S is
+ type 'a entry = 'a Entry.e
+ [@@ocaml.deprecated "Use [Pcoq.Entry.t]"]
-module type S =
- sig
- type te = 'x;
- type parsable = 'x;
- value parsable : Stream.t char -> parsable;
- value tokens : string -> list (string * int);
- value glexer : Plexing.lexer te;
- value set_algorithm : parse_algorithm -> unit;
- module Entry :
- sig
- type e 'a = 'y;
- value create : string -> e 'a;
- value parse : e 'a -> parsable -> 'a;
- value parse_token : e 'a -> Stream.t te -> 'a;
- value name : e 'a -> string;
- value of_parser : string -> (Stream.t te -> 'a) -> e 'a;
- value print : Format.formatter -> e 'a -> unit;
- external obj : e 'a -> Gramext.g_entry te = "%identity";
- end
- ;
- module Unsafe :
- sig
- value gram_reinit : Plexing.lexer te -> unit;
- value clear_entry : Entry.e 'a -> unit;
- end
- ;
- value extend :
- Entry.e 'a -> option Gramext.position ->
- list
- (option string * option Gramext.g_assoc *
- list (list (Gramext.g_symbol te) * Gramext.g_action)) ->
- unit;
- value delete_rule : Entry.e 'a -> list (Gramext.g_symbol te) -> unit;
- end
+ [@@@ocaml.warning "-3"]
-*)
-
- type 'a entry = 'a Entry.e
- type internal_entry = Tok.t Gramext.g_entry
- type symbol = Tok.t Gramext.g_symbol
- type action = Gramext.g_action
- type production_rule = symbol list * action
- type single_extend_statment =
- string option * Gramext.g_assoc option * production_rule list
- type extend_statment =
- Gramext.position option * single_extend_statment list
-
- type coq_parsable
-
- val parsable : ?file:Loc.source -> char Stream.t -> coq_parsable
- val action : 'a -> action
val entry_create : string -> 'a entry
- val entry_parse : 'a entry -> coq_parsable -> 'a
- val entry_print : Format.formatter -> 'a entry -> unit
+ [@@ocaml.deprecated "Use [Pcoq.Entry.create]"]
- (* Get comment parsing information from the Lexer *)
- val comment_state : coq_parsable -> ((int * int) * string) list
+ val gram_extend : 'a entry -> 'a Extend.extend_statement -> unit
- (* Apparently not used *)
- val srules' : production_rule list -> symbol
- val parse_tokens_after_filter : 'a entry -> Tok.t Stream.t -> 'a
+ [@@@ocaml.warning "+3"]
end with type 'a Entry.e = 'a Grammar.GMake(CLexer).Entry.e
+module Parsable :
+sig
+ type t
+ val make : ?file:Loc.source -> char Stream.t -> t
+ (* Get comment parsing information from the Lexer *)
+ val comment_state : t -> ((int * int) * string) list
+end
+
+module Entry : sig
+ type 'a t = 'a Grammar.GMake(CLexer).Entry.e
+ val create : string -> 'a t
+ val parse : 'a t -> Parsable.t -> 'a
+ val print : Format.formatter -> 'a t -> unit
+end
+
(** The parser of Coq is built from three kinds of rule declarations:
- dynamic rules declared at the evaluation of Coq files (using
@@ -170,106 +133,88 @@ val camlp5_verbosity : bool -> ('a -> unit) -> 'a -> unit
(** Parse a string *)
-val parse_string : 'a Gram.entry -> string -> 'a
-val eoi_entry : 'a Gram.entry -> 'a Gram.entry
-val map_entry : ('a -> 'b) -> 'a Gram.entry -> 'b Gram.entry
+val parse_string : 'a Entry.t -> string -> 'a
+val eoi_entry : 'a Entry.t -> 'a Entry.t
+val map_entry : ('a -> 'b) -> 'a Entry.t -> 'b Entry.t
type gram_universe
val get_univ : string -> gram_universe
+val create_universe : string -> gram_universe
+
+val new_entry : gram_universe -> string -> 'a Entry.t
val uprim : gram_universe
val uconstr : gram_universe
val utactic : gram_universe
-val uvernac : gram_universe
-val register_grammar : ('raw, 'glb, 'top) genarg_type -> 'raw Gram.entry -> unit
-val genarg_grammar : ('raw, 'glb, 'top) genarg_type -> 'raw Gram.entry
+
+val register_grammar : ('raw, 'glb, 'top) genarg_type -> 'raw Entry.t -> unit
+val genarg_grammar : ('raw, 'glb, 'top) genarg_type -> 'raw Entry.t
val create_generic_entry : gram_universe -> string ->
- ('a, rlevel) abstract_argument_type -> 'a Gram.entry
+ ('a, rlevel) abstract_argument_type -> 'a Entry.t
module Prim :
sig
open Names
open Libnames
- val preident : string Gram.entry
- val ident : Id.t Gram.entry
- val name : lname Gram.entry
- val identref : lident Gram.entry
- val univ_decl : universe_decl_expr Gram.entry
- val ident_decl : ident_decl Gram.entry
- val pattern_ident : Id.t Gram.entry
- val pattern_identref : lident Gram.entry
- val base_ident : Id.t Gram.entry
- val natural : int Gram.entry
- val bigint : Constrexpr.raw_natural_number Gram.entry
- val integer : int Gram.entry
- val string : string Gram.entry
- val lstring : lstring Gram.entry
- val qualid : qualid CAst.t Gram.entry
- val fullyqualid : Id.t list CAst.t Gram.entry
- val reference : reference Gram.entry
- val by_notation : (string * string option) Gram.entry
- val smart_global : reference or_by_notation Gram.entry
- val dirpath : DirPath.t Gram.entry
- val ne_string : string Gram.entry
- val ne_lstring : lstring Gram.entry
- val var : lident Gram.entry
+ val preident : string Entry.t
+ val ident : Id.t Entry.t
+ val name : lname Entry.t
+ val identref : lident Entry.t
+ val univ_decl : universe_decl_expr Entry.t
+ val ident_decl : ident_decl Entry.t
+ val pattern_ident : Id.t Entry.t
+ val pattern_identref : lident Entry.t
+ val base_ident : Id.t Entry.t
+ val natural : int Entry.t
+ val bigint : Constrexpr.raw_natural_number Entry.t
+ val integer : int Entry.t
+ val string : string Entry.t
+ val lstring : lstring Entry.t
+ val reference : qualid Entry.t
+ val qualid : qualid Entry.t
+ val fullyqualid : Id.t list CAst.t Entry.t
+ val by_notation : (string * string option) Entry.t
+ val smart_global : qualid or_by_notation Entry.t
+ val dirpath : DirPath.t Entry.t
+ val ne_string : string Entry.t
+ val ne_lstring : lstring Entry.t
+ val var : lident Entry.t
end
module Constr :
sig
- val constr : constr_expr Gram.entry
- val constr_eoi : constr_expr Gram.entry
- val lconstr : constr_expr Gram.entry
- val binder_constr : constr_expr Gram.entry
- val operconstr : constr_expr Gram.entry
- val ident : Id.t Gram.entry
- val global : reference Gram.entry
- val universe_level : glob_level Gram.entry
- val sort : glob_sort Gram.entry
- val sort_family : Sorts.family Gram.entry
- val pattern : cases_pattern_expr Gram.entry
- val constr_pattern : constr_expr Gram.entry
- val lconstr_pattern : constr_expr Gram.entry
- val closed_binder : local_binder_expr list Gram.entry
- val binder : local_binder_expr list Gram.entry (* closed_binder or variable *)
- val binders : local_binder_expr list Gram.entry (* list of binder *)
- val open_binders : local_binder_expr list Gram.entry
- val binders_fixannot : (local_binder_expr list * (lident option * recursion_order_expr)) Gram.entry
- val typeclass_constraint : (lname * bool * constr_expr) Gram.entry
- val record_declaration : constr_expr Gram.entry
- val appl_arg : (constr_expr * explicitation CAst.t option) Gram.entry
+ val constr : constr_expr Entry.t
+ val constr_eoi : constr_expr Entry.t
+ val lconstr : constr_expr Entry.t
+ val binder_constr : constr_expr Entry.t
+ val operconstr : constr_expr Entry.t
+ val ident : Id.t Entry.t
+ val global : qualid Entry.t
+ val universe_level : Glob_term.glob_level Entry.t
+ val sort : Glob_term.glob_sort Entry.t
+ val sort_family : Sorts.family Entry.t
+ val pattern : cases_pattern_expr Entry.t
+ val constr_pattern : constr_expr Entry.t
+ val lconstr_pattern : constr_expr Entry.t
+ val closed_binder : local_binder_expr list Entry.t
+ val binder : local_binder_expr list Entry.t (* closed_binder or variable *)
+ val binders : local_binder_expr list Entry.t (* list of binder *)
+ val open_binders : local_binder_expr list Entry.t
+ val binders_fixannot : (local_binder_expr list * (lident option * recursion_order_expr)) Entry.t
+ val typeclass_constraint : (lname * bool * constr_expr) Entry.t
+ val record_declaration : constr_expr Entry.t
+ val appl_arg : (constr_expr * explicitation CAst.t option) Entry.t
end
module Module :
sig
- val module_expr : module_ast Gram.entry
- val module_type : module_ast Gram.entry
- end
-
-module Vernac_ :
- sig
- val gallina : vernac_expr Gram.entry
- val gallina_ext : vernac_expr Gram.entry
- val command : vernac_expr Gram.entry
- val syntax : vernac_expr Gram.entry
- val vernac_control : vernac_control Gram.entry
- val rec_definition : (fixpoint_expr * decl_notation list) Gram.entry
- val noedit_mode : vernac_expr Gram.entry
- val command_entry : vernac_expr Gram.entry
- val red_expr : raw_red_expr Gram.entry
- val hint_info : Vernacexpr.hint_info_expr Gram.entry
+ val module_expr : module_ast Entry.t
+ val module_type : module_ast Entry.t
end
-(** The main entry: reads an optional vernac command *)
-val main_entry : (Loc.t * vernac_control) option Gram.entry
-
-(** Handling of the proof mode entry *)
-val get_command_entry : unit -> vernac_expr Gram.entry
-val set_command_entry : vernac_expr Gram.entry -> unit
-
val epsilon_value : ('a -> 'self) -> ('self, 'a) Extend.symbol -> 'self option
(** {5 Extending the parser without synchronization} *)
@@ -277,8 +222,8 @@ val epsilon_value : ('a -> 'self) -> ('self, 'a) Extend.symbol -> 'self option
type gram_reinit = gram_assoc * gram_position
(** Type of reinitialization data *)
-val grammar_extend : 'a Gram.entry -> gram_reinit option ->
- 'a Extend.extend_statment -> unit
+val grammar_extend : 'a Entry.t -> gram_reinit option ->
+ 'a Extend.extend_statement -> unit
(** Extend the grammar of Coq, without synchronizing it with the backtracking
mechanism. This means that grammar extensions defined this way will survive
an undo. *)
@@ -288,12 +233,14 @@ val grammar_extend : 'a Gram.entry -> gram_reinit option ->
module GramState : Store.S
(** Auxiliary state of the grammar. Any added data must be marshallable. *)
+(** {6 Extension with parsing rules} *)
+
type 'a grammar_command
(** Type of synchronized parsing extensions. The ['a] type should be
marshallable. *)
type extend_rule =
-| ExtendRule : 'a Gram.entry * gram_reinit option * 'a extend_statment -> extend_rule
+| ExtendRule : 'a Entry.t * gram_reinit option * 'a extend_statement -> extend_rule
type 'a grammar_extension = 'a -> GramState.t -> extend_rule list * GramState.t
(** Grammar extension entry point. Given some ['a] and a current grammar state,
@@ -308,12 +255,35 @@ val create_grammar_command : string -> 'a grammar_extension -> 'a grammar_comman
val extend_grammar_command : 'a grammar_command -> 'a -> unit
(** Extend the grammar of Coq with the given data. *)
-val recover_grammar_command : 'a grammar_command -> 'a list
-(** Recover the current stack of grammar extensions. *)
+(** {6 Extension with parsing entries} *)
+
+type ('a, 'b) entry_command
+(** Type of synchronized entry creation. The ['a] type should be
+ marshallable. *)
+
+type ('a, 'b) entry_extension = 'a -> GramState.t -> string list * GramState.t
+(** Entry extension entry point. Given some ['a] and a current grammar state,
+ such a function must produce the list of entry extensions that will be
+ created and kept synchronized w.r.t. the summary, together
+ with a new state. It should be pure. *)
+
+val create_entry_command : string -> ('a, 'b) entry_extension -> ('a, 'b) entry_command
+(** Create a new entry-creating command with the given name. The extension
+ function is called to generate the new entries for a given data. *)
+
+val extend_entry_command : ('a, 'b) entry_command -> 'a -> 'b Entry.t list
+(** Create new synchronized entries using the provided data. *)
+
+val find_custom_entry : ('a, 'b) entry_command -> string -> 'b Entry.t
+(** Find an entry generated by the synchronized system in the current state.
+ @raise Not_found if non-existent. *)
+
+(** {6 Protection w.r.t. backtrack} *)
val with_grammar_rule_protection : ('a -> 'b) -> 'a -> 'b
(** Location Utils *)
+val of_coqloc : Loc.t -> Ploc.t
val to_coqloc : Ploc.t -> Loc.t
val (!@) : Ploc.t -> Loc.t
@@ -322,7 +292,7 @@ val parser_summary_tag : frozen_t Summary.Dyn.tag
(** Registering grammars by name *)
-type any_entry = AnyEntry : 'a Gram.entry -> any_entry
+type any_entry = AnyEntry : 'a Entry.t -> any_entry
val register_grammars_by_name : string -> any_entry list -> unit
val find_grammars_by_name : string -> any_entry list
diff --git a/parsing/ppextend.ml b/parsing/ppextend.ml
new file mode 100644
index 00000000..e1f5e201
--- /dev/null
+++ b/parsing/ppextend.ml
@@ -0,0 +1,77 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Util
+open Pp
+open CErrors
+open Notation
+open Notation_gram
+
+(*s Pretty-print. *)
+
+type ppbox =
+ | PpHB of int
+ | PpHOVB of int
+ | PpHVB of int
+ | PpVB of int
+
+type ppcut =
+ | PpBrk of int * int
+ | PpFnl
+
+let ppcmd_of_box = function
+ | PpHB n -> h n
+ | PpHOVB n -> hov n
+ | PpHVB n -> hv n
+ | PpVB n -> v n
+
+let ppcmd_of_cut = function
+ | PpFnl -> fnl ()
+ | PpBrk(n1,n2) -> brk(n1,n2)
+
+type unparsing =
+ | UnpMetaVar of int * parenRelation
+ | UnpBinderMetaVar of int * parenRelation
+ | UnpListMetaVar of int * parenRelation * unparsing list
+ | UnpBinderListMetaVar of int * bool * unparsing list
+ | UnpTerminal of string
+ | UnpBox of ppbox * unparsing Loc.located list
+ | UnpCut of ppcut
+
+type unparsing_rule = unparsing list * precedence
+type extra_unparsing_rules = (string * string) list
+(* Concrete syntax for symbolic-extension table *)
+let notation_rules =
+ Summary.ref ~name:"notation-rules" (NotationMap.empty : (unparsing_rule * extra_unparsing_rules * notation_grammar) NotationMap.t)
+
+let declare_notation_rule ntn ~extra unpl gram =
+ notation_rules := NotationMap.add ntn (unpl,extra,gram) !notation_rules
+
+let find_notation_printing_rule ntn =
+ try pi1 (NotationMap.find ntn !notation_rules)
+ with Not_found -> anomaly (str "No printing rule found for " ++ pr_notation ntn ++ str ".")
+let find_notation_extra_printing_rules ntn =
+ try pi2 (NotationMap.find ntn !notation_rules)
+ with Not_found -> []
+let find_notation_parsing_rules ntn =
+ try pi3 (NotationMap.find ntn !notation_rules)
+ with Not_found -> anomaly (str "No parsing rule found for " ++ pr_notation ntn ++ str ".")
+
+let get_defined_notations () =
+ NotationSet.elements @@ NotationMap.domain !notation_rules
+
+let add_notation_extra_printing_rule ntn k v =
+ try
+ notation_rules :=
+ let p, pp, gr = NotationMap.find ntn !notation_rules in
+ NotationMap.add ntn (p, (k,v) :: pp, gr) !notation_rules
+ with Not_found ->
+ user_err ~hdr:"add_notation_extra_printing_rule"
+ (str "No such Notation.")
diff --git a/interp/ppextend.mli b/parsing/ppextend.mli
index c81058e7..7eb5967a 100644
--- a/interp/ppextend.mli
+++ b/parsing/ppextend.mli
@@ -8,7 +8,8 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Notation_term
+open Constrexpr
+open Notation_gram
(** {6 Pretty-print. } *)
@@ -26,6 +27,9 @@ val ppcmd_of_box : ppbox -> Pp.t -> Pp.t
val ppcmd_of_cut : ppcut -> Pp.t
+(** {6 Printing rules for notations} *)
+
+(** Declare and look for the printing rule for symbolic notations *)
type unparsing =
| UnpMetaVar of int * parenRelation
| UnpBinderMetaVar of int * parenRelation
@@ -34,3 +38,14 @@ type unparsing =
| UnpTerminal of string
| UnpBox of ppbox * unparsing Loc.located list
| UnpCut of ppcut
+
+type unparsing_rule = unparsing list * precedence
+type extra_unparsing_rules = (string * string) list
+val declare_notation_rule : notation -> extra:extra_unparsing_rules -> unparsing_rule -> notation_grammar -> unit
+val find_notation_printing_rule : notation -> unparsing_rule
+val find_notation_extra_printing_rules : notation -> extra_unparsing_rules
+val find_notation_parsing_rules : notation -> notation_grammar
+val add_notation_extra_printing_rule : notation -> string -> string -> unit
+
+(** Returns notations with defined parsing/printing rules *)
+val get_defined_notations : unit -> notation list
diff --git a/plugins/.merlin b/plugins/.merlin.in
index 2ba61696..2ba61696 100644
--- a/plugins/.merlin
+++ b/plugins/.merlin.in
diff --git a/plugins/btauto/Algebra.v b/plugins/btauto/Algebra.v
index ee7341a4..f1095fc9 100644
--- a/plugins/btauto/Algebra.v
+++ b/plugins/btauto/Algebra.v
@@ -1,4 +1,4 @@
-Require Import Bool PArith DecidableClass Omega ROmega.
+Require Import Bool PArith DecidableClass Omega Lia.
Ltac bool :=
repeat match goal with
@@ -84,9 +84,9 @@ Ltac case_decide := match goal with
let H := fresh "H" in
define (@decide P D) b H; destruct b; try_decide
| [ |- context [Pos.compare ?x ?y] ] =>
- destruct (Pos.compare_spec x y); try (exfalso; zify; romega)
+ destruct (Pos.compare_spec x y); try lia
| [ X : context [Pos.compare ?x ?y] |- _ ] =>
- destruct (Pos.compare_spec x y); try (exfalso; zify; romega)
+ destruct (Pos.compare_spec x y); try lia
end.
Section Definitions.
@@ -325,13 +325,13 @@ Qed.
Lemma linear_le_compat : forall k l p, linear k p -> (k <= l)%positive -> linear l p.
Proof.
-intros k l p H; revert l; induction H; constructor; eauto; zify; romega.
+intros k l p H; revert l; induction H; constructor; eauto; lia.
Qed.
Lemma linear_valid_incl : forall k p, linear k p -> valid k p.
Proof.
intros k p H; induction H; constructor; auto.
-eapply valid_le_compat; eauto; zify; romega.
+eapply valid_le_compat; eauto; lia.
Qed.
End Validity.
@@ -417,13 +417,13 @@ Qed.
Hint Extern 5 =>
match goal with
| [ |- (Pos.max ?x ?y <= ?z)%positive ] =>
- apply Pos.max_case_strong; intros; zify; romega
+ apply Pos.max_case_strong; intros; lia
| [ |- (?z <= Pos.max ?x ?y)%positive ] =>
- apply Pos.max_case_strong; intros; zify; romega
+ apply Pos.max_case_strong; intros; lia
| [ |- (Pos.max ?x ?y < ?z)%positive ] =>
- apply Pos.max_case_strong; intros; zify; romega
+ apply Pos.max_case_strong; intros; lia
| [ |- (?z < Pos.max ?x ?y)%positive ] =>
- apply Pos.max_case_strong; intros; zify; romega
+ apply Pos.max_case_strong; intros; lia
| _ => zify; omega
end.
Hint Resolve Pos.le_max_r Pos.le_max_l.
@@ -445,8 +445,8 @@ intros kl kr pl pr Hl Hr; revert kr pr Hr; induction Hl; intros kr pr Hr; simpl.
now rewrite <- (Pos.max_id i); intuition.
destruct (Pos.compare_spec i i0); subst; try case_decide; repeat (constructor; intuition).
+ apply (valid_le_compat (Pos.max i0 i0)); [now auto|]; rewrite Pos.max_id; auto.
- + apply (valid_le_compat (Pos.max i0 i0)); [now auto|]; rewrite Pos.max_id; zify; romega.
- + apply (valid_le_compat (Pos.max (Pos.succ i0) (Pos.succ i0))); [now auto|]; rewrite Pos.max_id; zify; romega.
+ + apply (valid_le_compat (Pos.max i0 i0)); [now auto|]; rewrite Pos.max_id; lia.
+ + apply (valid_le_compat (Pos.max (Pos.succ i0) (Pos.succ i0))); [now auto|]; rewrite Pos.max_id; lia.
+ apply (valid_le_compat (Pos.max (Pos.succ i) i0)); intuition.
+ apply (valid_le_compat (Pos.max i (Pos.succ i0))); intuition.
}
@@ -456,7 +456,7 @@ Lemma poly_mul_cst_valid_compat : forall k v p, valid k p -> valid k (poly_mul_c
Proof.
intros k v p H; induction H; simpl; [now auto|].
case_decide; [|now auto].
-eapply (valid_le_compat i); [now auto|zify; romega].
+eapply (valid_le_compat i); [now auto|lia].
Qed.
Lemma poly_mul_mon_null_compat : forall i p, null (poly_mul_mon i p) -> null p.
diff --git a/plugins/btauto/g_btauto.ml4 b/plugins/btauto/g_btauto.mlg
index 3ae0f45c..312ef1e5 100644
--- a/plugins/btauto/g_btauto.ml4
+++ b/plugins/btauto/g_btauto.mlg
@@ -8,11 +8,15 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Ltac_plugin
+}
+
DECLARE PLUGIN "btauto_plugin"
TACTIC EXTEND btauto
-| [ "btauto" ] -> [ Refl_btauto.Btauto.tac ]
+| [ "btauto" ] -> { Refl_btauto.Btauto.tac }
END
diff --git a/plugins/btauto/refl_btauto.ml b/plugins/btauto/refl_btauto.ml
index a09abfa1..c2bc8c07 100644
--- a/plugins/btauto/refl_btauto.ml
+++ b/plugins/btauto/refl_btauto.ml
@@ -1,12 +1,24 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Constr
+
let contrib_name = "btauto"
let init_constant dir s =
let find_constant contrib dir s =
- Universes.constr_of_global (Coqlib.find_reference contrib dir s)
+ UnivGen.constr_of_global (Coqlib.find_reference contrib dir s)
in
find_constant contrib_name dir s
-let get_constant dir s = lazy (Universes.constr_of_global @@ Coqlib.coq_reference contrib_name dir s)
+let get_constant dir s = lazy (UnivGen.constr_of_global @@ Coqlib.coq_reference contrib_name dir s)
let get_inductive dir s =
let glob_ref () = Coqlib.find_reference contrib_name ("Coq" :: dir) s in
@@ -106,7 +118,7 @@ module Bool = struct
let negb = Lazy.force negb in
let rec aux c = match decomp_term sigma c with
- | Term.App (head, args) ->
+ | App (head, args) ->
if head === andb && Array.length args = 2 then
Andb (aux args.(0), aux args.(1))
else if head === orb && Array.length args = 2 then
@@ -116,9 +128,9 @@ module Bool = struct
else if head === negb && Array.length args = 1 then
Negb (aux args.(0))
else Var (Env.add env c)
- | Term.Case (info, r, arg, pats) ->
+ | Case (info, r, arg, pats) ->
let is_bool =
- let i = info.Term.ci_ind in
+ let i = info.ci_ind in
Names.eq_ind i (Lazy.force ind)
in
if is_bool then
@@ -176,9 +188,9 @@ module Btauto = struct
let _, var = Tacmach.pf_reduction_of_red_expr gl (Genredexpr.CbvVm None) var in
let var = EConstr.Unsafe.to_constr var in
let rec to_list l = match decomp_term (Tacmach.project gl) l with
- | Term.App (c, _)
+ | App (c, _)
when c === (Lazy.force CoqList._nil) -> []
- | Term.App (c, [|_; h; t|])
+ | App (c, [|_; h; t|])
when c === (Lazy.force CoqList._cons) ->
if h === (Lazy.force Bool.trueb) then (true :: to_list t)
else if h === (Lazy.force Bool.falseb) then (false :: to_list t)
@@ -218,7 +230,7 @@ module Btauto = struct
let concl = EConstr.Unsafe.to_constr concl in
let t = decomp_term (Tacmach.New.project gl) concl in
match t with
- | Term.App (c, [|typ; p; _|]) when c === eq ->
+ | App (c, [|typ; p; _|]) when c === eq ->
(* should be an equality [@eq poly ?p (Cst false)] *)
let tac = Tacticals.New.tclORELSE0 Tactics.reflexivity (Proofview.V82.tactic (print_counterexample p env)) in
tac
@@ -236,7 +248,7 @@ module Btauto = struct
let bool = Lazy.force Bool.typ in
let t = decomp_term sigma concl in
match t with
- | Term.App (c, [|typ; tl; tr|])
+ | App (c, [|typ; tl; tr|])
when typ === bool && c === eq ->
let env = Env.empty () in
let fl = Bool.quote env sigma tl in
diff --git a/plugins/cc/ccalgo.ml b/plugins/cc/ccalgo.ml
index 8e53a044..f26ec0f4 100644
--- a/plugins/cc/ccalgo.ml
+++ b/plugins/cc/ccalgo.ml
@@ -26,6 +26,10 @@ let init_size=5
let cc_verbose=ref false
+let print_constr t =
+ let sigma, env = Pfedit.get_current_context () in
+ Printer.pr_econstr_env env sigma t
+
let debug x =
if !cc_verbose then Feedback.msg_debug (x ())
@@ -130,8 +134,8 @@ type cinfo=
ci_nhyps: int} (* # projectable args *)
let family_eq f1 f2 = match f1, f2 with
- | Prop Pos, Prop Pos
- | Prop Null, Prop Null
+ | Set, Set
+ | Prop, Prop
| Type _, Type _ -> true
| _ -> false
@@ -457,10 +461,10 @@ let rec canonize_name sigma c =
| LetIn (na,b,t,ct) ->
mkLetIn (na, func b,func t,func ct)
| App (ct,l) ->
- mkApp (func ct,Array.smartmap func l)
+ mkApp (func ct,Array.Smart.map func l)
| Proj(p,c) ->
let p' = Projection.map (fun kn ->
- Constant.make1 (Constant.canonical kn)) p in
+ MutInd.make1 (MutInd.canonical kn)) p in
(mkProj (p', func c))
| _ -> c
@@ -483,10 +487,10 @@ let rec inst_pattern subst = function
args t
let pr_idx_term uf i = str "[" ++ int i ++ str ":=" ++
- Termops.print_constr (EConstr.of_constr (constr_of_term (term uf i))) ++ str "]"
+ print_constr (EConstr.of_constr (constr_of_term (term uf i))) ++ str "]"
let pr_term t = str "[" ++
- Termops.print_constr (EConstr.of_constr (constr_of_term t)) ++ str "]"
+ print_constr (EConstr.of_constr (constr_of_term t)) ++ str "]"
let rec add_term state t=
let uf=state.uf in
@@ -601,7 +605,7 @@ let add_inst state (inst,int_subst) =
begin
debug (fun () ->
(str "Adding new equality, depth="++ int state.rew_depth) ++ fnl () ++
- (str " [" ++ Termops.print_constr (EConstr.of_constr prf) ++ str " : " ++
+ (str " [" ++ print_constr (EConstr.of_constr prf) ++ str " : " ++
pr_term s ++ str " == " ++ pr_term t ++ str "]"));
add_equality state prf s t
end
@@ -609,7 +613,7 @@ let add_inst state (inst,int_subst) =
begin
debug (fun () ->
(str "Adding new disequality, depth="++ int state.rew_depth) ++ fnl () ++
- (str " [" ++ Termops.print_constr (EConstr.of_constr prf) ++ str " : " ++
+ (str " [" ++ print_constr (EConstr.of_constr prf) ++ str " : " ++
pr_term s ++ str " <> " ++ pr_term t ++ str "]"));
add_disequality state (Hyp prf) s t
end
diff --git a/plugins/cc/cctac.ml b/plugins/cc/cctac.ml
index d19817e7..2eaa6146 100644
--- a/plugins/cc/cctac.ml
+++ b/plugins/cc/cctac.ml
@@ -49,7 +49,7 @@ let whd_delta env sigma t =
(* decompose member of equality in an applicative format *)
(** FIXME: evar leak *)
-let sf_of env sigma c = e_sort_of env (ref sigma) c
+let sf_of env sigma c = snd (sort_of env sigma c)
let rec decompose_term env sigma t=
match EConstr.kind sigma (whd env sigma t) with
@@ -84,13 +84,13 @@ let rec decompose_term env sigma t=
let canon_const = Constant.make1 (Constant.canonical c) in
(Symb (Constr.mkConstU (canon_const,u)))
| Proj (p, c) ->
- let canon_const kn = Constant.make1 (Constant.canonical kn) in
- let p' = Projection.map canon_const p in
+ let canon_mind kn = MutInd.make1 (MutInd.canonical kn) in
+ let p' = Projection.map canon_mind p in
let c = Retyping.expand_projection env sigma p' c [] in
decompose_term env sigma c
| _ ->
let t = Termops.strip_outer_cast sigma t in
- if closed0 sigma t then Symb (EConstr.to_constr sigma t) else raise Not_found
+ if closed0 sigma t then Symb (EConstr.to_constr ~abort_on_undefined_evars:false sigma t) else raise Not_found
(* decompose equality in members and type *)
open Termops
@@ -264,9 +264,8 @@ let app_global_with_holes f args n =
let ans = mkApp (fc, args) in
let (sigma, holes) = gen_holes env sigma t n [] in
let ans = applist (ans, holes) in
- let evdref = ref sigma in
- let () = Typing.e_check env evdref ans concl in
- (!evdref, ans)
+ let sigma = Typing.check env sigma ans concl in
+ (sigma, ans)
end
end
@@ -444,7 +443,7 @@ let cc_tactic depth additionnal_terms =
let open Glob_term in
let env = Proofview.Goal.env gl in
let terms_to_complete = List.map (build_term_to_complete uf) (epsilons uf) in
- let hole = DAst.make @@ GHole (Evar_kinds.InternalHole, Misctypes.IntroAnonymous, None) in
+ let hole = DAst.make @@ GHole (Evar_kinds.InternalHole, Namegen.IntroAnonymous, None) in
let pr_missing (c, missing) =
let c = Detyping.detype Detyping.Now ~lax:true false Id.Set.empty env sigma c in
let holes = List.init missing (fun _ -> hole) in
diff --git a/plugins/cc/g_congruence.ml4 b/plugins/cc/g_congruence.mlg
index fb013ac1..68505929 100644
--- a/plugins/cc/g_congruence.ml4
+++ b/plugins/cc/g_congruence.mlg
@@ -8,22 +8,26 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Ltac_plugin
open Cctac
open Stdarg
+}
+
DECLARE PLUGIN "cc_plugin"
(* Tactic registration *)
TACTIC EXTEND cc
- [ "congruence" ] -> [ congruence_tac 1000 [] ]
- |[ "congruence" integer(n) ] -> [ congruence_tac n [] ]
- |[ "congruence" "with" ne_constr_list(l) ] -> [ congruence_tac 1000 l ]
+| [ "congruence" ] -> { congruence_tac 1000 [] }
+| [ "congruence" integer(n) ] -> { congruence_tac n [] }
+| [ "congruence" "with" ne_constr_list(l) ] -> { congruence_tac 1000 l }
|[ "congruence" integer(n) "with" ne_constr_list(l) ] ->
- [ congruence_tac n l ]
+ { congruence_tac n l }
END
TACTIC EXTEND f_equal
- [ "f_equal" ] -> [ f_equal ]
+| [ "f_equal" ] -> { f_equal }
END
diff --git a/plugins/derive/derive.ml b/plugins/derive/derive.ml
index 8a55538b..480819eb 100644
--- a/plugins/derive/derive.ml
+++ b/plugins/derive/derive.ml
@@ -61,7 +61,7 @@ let start_deriving f suchthat lemma =
| Proved (opaque, None, obj) ->
match Proof_global.(obj.entries) with
| [_;f_def;lemma_def] ->
- opaque <> Vernacexpr.Transparent , f_def , lemma_def
+ opaque <> Proof_global.Transparent , f_def , lemma_def
| _ -> assert false
in
(** The opacity of [f_def] is adjusted to be [false], as it
diff --git a/plugins/extraction/ExtrHaskellString.v b/plugins/extraction/ExtrHaskellString.v
index ac1f6f91..a4a40d3c 100644
--- a/plugins/extraction/ExtrHaskellString.v
+++ b/plugins/extraction/ExtrHaskellString.v
@@ -35,6 +35,8 @@ Extract Inductive ascii => "Prelude.Char"
(Data.Bits.testBit (Data.Char.ord a) 6)
(Data.Bits.testBit (Data.Char.ord a) 7))".
Extract Inlined Constant Ascii.ascii_dec => "(Prelude.==)".
+Extract Inlined Constant Ascii.eqb => "(Prelude.==)".
Extract Inductive string => "Prelude.String" [ "([])" "(:)" ].
Extract Inlined Constant String.string_dec => "(Prelude.==)".
+Extract Inlined Constant String.eqb => "(Prelude.==)".
diff --git a/plugins/extraction/ExtrOcamlString.v b/plugins/extraction/ExtrOcamlString.v
index 030b486b..a2a6a8fe 100644
--- a/plugins/extraction/ExtrOcamlString.v
+++ b/plugins/extraction/ExtrOcamlString.v
@@ -33,6 +33,7 @@ Extract Constant shift =>
"fun b c -> Char.chr (((Char.code c) lsl 1) land 255 + if b then 1 else 0)".
Extract Inlined Constant ascii_dec => "(=)".
+Extract Inlined Constant Ascii.eqb => "(=)".
Extract Inductive string => "char list" [ "[]" "(::)" ].
diff --git a/plugins/extraction/common.mli b/plugins/extraction/common.mli
index 78545c8b..07237d75 100644
--- a/plugins/extraction/common.mli
+++ b/plugins/extraction/common.mli
@@ -9,7 +9,6 @@
(************************************************************************)
open Names
-open Globnames
open Miniml
(** By default, in module Format, you can do horizontal placing of blocks
@@ -54,7 +53,7 @@ val opened_libraries : unit -> ModPath.t list
type kind = Term | Type | Cons | Mod
-val pp_global : kind -> global_reference -> string
+val pp_global : kind -> GlobRef.t -> string
val pp_module : ModPath.t -> string
val top_visible_mp : unit -> ModPath.t
diff --git a/plugins/extraction/extract_env.ml b/plugins/extraction/extract_env.ml
index 397cb292..4ede11b5 100644
--- a/plugins/extraction/extract_env.ml
+++ b/plugins/extraction/extract_env.ml
@@ -79,7 +79,7 @@ module type VISIT = sig
(* Add reference / ... in the visit lists.
These functions silently add the mp of their arg in the mp list *)
- val add_ref : global_reference -> unit
+ val add_ref : GlobRef.t -> unit
val add_kn : KerName.t -> unit
val add_decl_deps : ml_decl -> unit
val add_spec_deps : ml_spec -> unit
@@ -596,19 +596,18 @@ let warns () =
let rec locate_ref = function
| [] -> [],[]
- | r::l ->
- let q = qualid_of_reference r in
- let mpo = try Some (Nametab.locate_module q.CAst.v) with Not_found -> None
+ | qid::l ->
+ let mpo = try Some (Nametab.locate_module qid) with Not_found -> None
and ro =
- try Some (Smartlocate.global_with_alias r)
+ try Some (Smartlocate.global_with_alias qid)
with Nametab.GlobalizationError _ | UserError _ -> None
in
match mpo, ro with
- | None, None -> Nametab.error_global_not_found q
+ | None, None -> Nametab.error_global_not_found qid
| None, Some r -> let refs,mps = locate_ref l in r::refs,mps
| Some mp, None -> let refs,mps = locate_ref l in refs,mp::mps
| Some mp, Some r ->
- warning_ambiguous_name (q.CAst.v,mp,r);
+ warning_ambiguous_name (qid,mp,r);
let refs,mps = locate_ref l in refs,mp::mps
(*s Recursive extraction in the Coq toplevel. The vernacular command is
@@ -646,7 +645,7 @@ let separate_extraction lr =
is \verb!Extraction! [qualid]. *)
let simple_extraction r =
- Vernacentries.dump_global CAst.(make (Misctypes.AN r));
+ Vernacentries.dump_global CAst.(make (Constrexpr.AN r));
match locate_ref [r] with
| ([], [mp]) as p -> full_extr None p
| [r],[] ->
diff --git a/plugins/extraction/extract_env.mli b/plugins/extraction/extract_env.mli
index 591d3bb8..54fde2ca 100644
--- a/plugins/extraction/extract_env.mli
+++ b/plugins/extraction/extract_env.mli
@@ -12,21 +12,20 @@
open Names
open Libnames
-open Globnames
-val simple_extraction : reference -> unit
-val full_extraction : string option -> reference list -> unit
-val separate_extraction : reference list -> unit
+val simple_extraction : qualid -> unit
+val full_extraction : string option -> qualid list -> unit
+val separate_extraction : qualid list -> unit
val extraction_library : bool -> Id.t -> unit
(* For the test-suite : extraction to a temporary file + ocamlc on it *)
-val extract_and_compile : reference list -> unit
+val extract_and_compile : qualid list -> unit
(* For debug / external output via coqtop.byte + Drop : *)
val mono_environment :
- global_reference list -> ModPath.t list -> Miniml.ml_structure
+ GlobRef.t list -> ModPath.t list -> Miniml.ml_structure
(* Used by the Relation Extraction plugin *)
diff --git a/plugins/extraction/extraction.ml b/plugins/extraction/extraction.ml
index f25f6362..67c605ea 100644
--- a/plugins/extraction/extraction.ml
+++ b/plugins/extraction/extraction.ml
@@ -431,7 +431,7 @@ and extract_really_ind env kn mib =
let packets =
Array.mapi
(fun i mip ->
- let (_,u),_ = Universes.fresh_inductive_instance env (kn,i) in
+ let (_,u),_ = UnivGen.fresh_inductive_instance env (kn,i) in
let ar = Inductive.type_of_inductive env ((mib,mip),u) in
let ar = EConstr.of_constr ar in
let info = (fst (flag_of_type env sg ar) = Info) in
@@ -488,7 +488,7 @@ and extract_really_ind env kn mib =
Int.equal (List.length l) 1 && not (type_mem_kn kn (List.hd l))
then raise (I Singleton);
if List.is_empty l then raise (I Standard);
- if Option.is_empty mib.mind_record then raise (I Standard);
+ if mib.mind_record == Declarations.NotRecord then raise (I Standard);
(* Now we're sure it's a record. *)
(* First, we find its field names. *)
let rec names_prod t = match Constr.kind t with
@@ -1065,9 +1065,14 @@ let extract_constant env kn cb =
(match cb.const_body with
| Undef _ -> warn_info (); mk_typ_ax ()
| Def c ->
- (match cb.const_proj with
+ (match Recordops.find_primitive_projection kn with
| None -> mk_typ (get_body c)
- | Some pb -> mk_typ (EConstr.of_constr pb.proj_body))
+ | Some p ->
+ let p = Projection.make p false in
+ let ind = Projection.inductive p in
+ let bodies = Inductiveops.legacy_match_projection env ind in
+ let body = bodies.(Projection.arg p) in
+ mk_typ (EConstr.of_constr body))
| OpaqueDef c ->
add_opaque r;
if access_opaque () then mk_typ (get_opaque env c)
@@ -1076,9 +1081,14 @@ let extract_constant env kn cb =
(match cb.const_body with
| Undef _ -> warn_info (); mk_ax ()
| Def c ->
- (match cb.const_proj with
+ (match Recordops.find_primitive_projection kn with
| None -> mk_def (get_body c)
- | Some pb -> mk_def (EConstr.of_constr pb.proj_body))
+ | Some p ->
+ let p = Projection.make p false in
+ let ind = Projection.inductive p in
+ let bodies = Inductiveops.legacy_match_projection env ind in
+ let body = bodies.(Projection.arg p) in
+ mk_def (EConstr.of_constr body))
| OpaqueDef c ->
add_opaque r;
if access_opaque () then mk_def (get_opaque env c)
diff --git a/plugins/extraction/miniml.ml b/plugins/extraction/miniml.ml
index e1e49d92..ce920ad6 100644
--- a/plugins/extraction/miniml.ml
+++ b/plugins/extraction/miniml.ml
@@ -11,7 +11,6 @@
(*s Target language for extraction: a core ML called MiniML. *)
open Names
-open Globnames
(* The [signature] type is used to know how many arguments a CIC
object expects, and what these arguments will become in the ML
@@ -26,7 +25,7 @@ open Globnames
type kill_reason =
| Ktype
| Kprop
- | Kimplicit of global_reference * int (* n-th arg of a cst or construct *)
+ | Kimplicit of GlobRef.t * int (* n-th arg of a cst or construct *)
type sign = Keep | Kill of kill_reason
@@ -39,7 +38,7 @@ type signature = sign list
type ml_type =
| Tarr of ml_type * ml_type
- | Tglob of global_reference * ml_type list
+ | Tglob of GlobRef.t * ml_type list
| Tvar of int
| Tvar' of int (* same as Tvar, used to avoid clash *)
| Tmeta of ml_meta (* used during ML type reconstruction *)
@@ -60,7 +59,7 @@ type inductive_kind =
| Singleton
| Coinductive
| Standard
- | Record of global_reference option list (* None for anonymous field *)
+ | Record of GlobRef.t option list (* None for anonymous field *)
(* A [ml_ind_packet] is the miniml counterpart of a [one_inductive_body].
If the inductive is logical ([ip_logical = false]), then all other fields
@@ -118,8 +117,8 @@ and ml_ast =
| MLapp of ml_ast * ml_ast list
| MLlam of ml_ident * ml_ast
| MLletin of ml_ident * ml_ast * ml_ast
- | MLglob of global_reference
- | MLcons of ml_type * global_reference * ml_ast list
+ | MLglob of GlobRef.t
+ | MLcons of ml_type * GlobRef.t * ml_ast list
| MLtuple of ml_ast list
| MLcase of ml_type * ml_ast * ml_branch array
| MLfix of int * Id.t array * ml_ast array
@@ -129,24 +128,24 @@ and ml_ast =
| MLmagic of ml_ast
and ml_pattern =
- | Pcons of global_reference * ml_pattern list
+ | Pcons of GlobRef.t * ml_pattern list
| Ptuple of ml_pattern list
| Prel of int (** Cf. the idents in the branch. [Prel 1] is the last one. *)
| Pwild
- | Pusual of global_reference (** Shortcut for Pcons (r,[Prel n;...;Prel 1]) **)
+ | Pusual of GlobRef.t (** Shortcut for Pcons (r,[Prel n;...;Prel 1]) **)
(*s ML declarations. *)
type ml_decl =
| Dind of MutInd.t * ml_ind
- | Dtype of global_reference * Id.t list * ml_type
- | Dterm of global_reference * ml_ast * ml_type
- | Dfix of global_reference array * ml_ast array * ml_type array
+ | Dtype of GlobRef.t * Id.t list * ml_type
+ | Dterm of GlobRef.t * ml_ast * ml_type
+ | Dfix of GlobRef.t array * ml_ast array * ml_type array
type ml_spec =
| Sind of MutInd.t * ml_ind
- | Stype of global_reference * Id.t list * ml_type option
- | Sval of global_reference * ml_type
+ | Stype of GlobRef.t * Id.t list * ml_type option
+ | Sval of GlobRef.t * ml_type
type ml_specif =
| Spec of ml_spec
diff --git a/plugins/extraction/miniml.mli b/plugins/extraction/miniml.mli
index e1e49d92..ce920ad6 100644
--- a/plugins/extraction/miniml.mli
+++ b/plugins/extraction/miniml.mli
@@ -11,7 +11,6 @@
(*s Target language for extraction: a core ML called MiniML. *)
open Names
-open Globnames
(* The [signature] type is used to know how many arguments a CIC
object expects, and what these arguments will become in the ML
@@ -26,7 +25,7 @@ open Globnames
type kill_reason =
| Ktype
| Kprop
- | Kimplicit of global_reference * int (* n-th arg of a cst or construct *)
+ | Kimplicit of GlobRef.t * int (* n-th arg of a cst or construct *)
type sign = Keep | Kill of kill_reason
@@ -39,7 +38,7 @@ type signature = sign list
type ml_type =
| Tarr of ml_type * ml_type
- | Tglob of global_reference * ml_type list
+ | Tglob of GlobRef.t * ml_type list
| Tvar of int
| Tvar' of int (* same as Tvar, used to avoid clash *)
| Tmeta of ml_meta (* used during ML type reconstruction *)
@@ -60,7 +59,7 @@ type inductive_kind =
| Singleton
| Coinductive
| Standard
- | Record of global_reference option list (* None for anonymous field *)
+ | Record of GlobRef.t option list (* None for anonymous field *)
(* A [ml_ind_packet] is the miniml counterpart of a [one_inductive_body].
If the inductive is logical ([ip_logical = false]), then all other fields
@@ -118,8 +117,8 @@ and ml_ast =
| MLapp of ml_ast * ml_ast list
| MLlam of ml_ident * ml_ast
| MLletin of ml_ident * ml_ast * ml_ast
- | MLglob of global_reference
- | MLcons of ml_type * global_reference * ml_ast list
+ | MLglob of GlobRef.t
+ | MLcons of ml_type * GlobRef.t * ml_ast list
| MLtuple of ml_ast list
| MLcase of ml_type * ml_ast * ml_branch array
| MLfix of int * Id.t array * ml_ast array
@@ -129,24 +128,24 @@ and ml_ast =
| MLmagic of ml_ast
and ml_pattern =
- | Pcons of global_reference * ml_pattern list
+ | Pcons of GlobRef.t * ml_pattern list
| Ptuple of ml_pattern list
| Prel of int (** Cf. the idents in the branch. [Prel 1] is the last one. *)
| Pwild
- | Pusual of global_reference (** Shortcut for Pcons (r,[Prel n;...;Prel 1]) **)
+ | Pusual of GlobRef.t (** Shortcut for Pcons (r,[Prel n;...;Prel 1]) **)
(*s ML declarations. *)
type ml_decl =
| Dind of MutInd.t * ml_ind
- | Dtype of global_reference * Id.t list * ml_type
- | Dterm of global_reference * ml_ast * ml_type
- | Dfix of global_reference array * ml_ast array * ml_type array
+ | Dtype of GlobRef.t * Id.t list * ml_type
+ | Dterm of GlobRef.t * ml_ast * ml_type
+ | Dfix of GlobRef.t array * ml_ast array * ml_type array
type ml_spec =
| Sind of MutInd.t * ml_ind
- | Stype of global_reference * Id.t list * ml_type option
- | Sval of global_reference * ml_type
+ | Stype of GlobRef.t * Id.t list * ml_type option
+ | Sval of GlobRef.t * ml_type
type ml_specif =
| Spec of ml_spec
diff --git a/plugins/extraction/mlutil.ml b/plugins/extraction/mlutil.ml
index 0656d487..9f5c1f1a 100644
--- a/plugins/extraction/mlutil.ml
+++ b/plugins/extraction/mlutil.ml
@@ -59,7 +59,7 @@ let rec eq_ml_type t1 t2 = match t1, t2 with
| Tarr (tl1, tr1), Tarr (tl2, tr2) ->
eq_ml_type tl1 tl2 && eq_ml_type tr1 tr2
| Tglob (gr1, t1), Tglob (gr2, t2) ->
- eq_gr gr1 gr2 && List.equal eq_ml_type t1 t2
+ GlobRef.equal gr1 gr2 && List.equal eq_ml_type t1 t2
| Tvar i1, Tvar i2 -> Int.equal i1 i2
| Tvar' i1, Tvar' i2 -> Int.equal i1 i2
| Tmeta m1, Tmeta m2 -> eq_ml_meta m1 m2
@@ -120,7 +120,7 @@ let rec mgu = function
| None -> m.contents <- Some t)
| Tarr(a, b), Tarr(a', b') ->
mgu (a, a'); mgu (b, b')
- | Tglob (r,l), Tglob (r',l') when Globnames.eq_gr r r' ->
+ | Tglob (r,l), Tglob (r',l') when GlobRef.equal r r' ->
List.iter mgu (List.combine l l')
| Tdummy _, Tdummy _ -> ()
| Tvar i, Tvar j when Int.equal i j -> ()
@@ -270,7 +270,7 @@ let rec var2var' = function
| Tglob (r,l) -> Tglob (r, List.map var2var' l)
| a -> a
-type abbrev_map = global_reference -> ml_type option
+type abbrev_map = GlobRef.t -> ml_type option
(*s Delta-reduction of type constants everywhere in a ML type [t].
[env] is a function of type [ml_type_env]. *)
@@ -381,9 +381,9 @@ let rec eq_ml_ast t1 t2 = match t1, t2 with
eq_ml_ident na1 na2 && eq_ml_ast t1 t2
| MLletin (na1, c1, t1), MLletin (na2, c2, t2) ->
eq_ml_ident na1 na2 && eq_ml_ast c1 c2 && eq_ml_ast t1 t2
-| MLglob gr1, MLglob gr2 -> eq_gr gr1 gr2
+| MLglob gr1, MLglob gr2 -> GlobRef.equal gr1 gr2
| MLcons (t1, gr1, c1), MLcons (t2, gr2, c2) ->
- eq_ml_type t1 t2 && eq_gr gr1 gr2 && List.equal eq_ml_ast c1 c2
+ eq_ml_type t1 t2 && GlobRef.equal gr1 gr2 && List.equal eq_ml_ast c1 c2
| MLtuple t1, MLtuple t2 ->
List.equal eq_ml_ast t1 t2
| MLcase (t1, c1, p1), MLcase (t2, c2, p2) ->
@@ -398,13 +398,13 @@ let rec eq_ml_ast t1 t2 = match t1, t2 with
and eq_ml_pattern p1 p2 = match p1, p2 with
| Pcons (gr1, p1), Pcons (gr2, p2) ->
- eq_gr gr1 gr2 && List.equal eq_ml_pattern p1 p2
+ GlobRef.equal gr1 gr2 && List.equal eq_ml_pattern p1 p2
| Ptuple p1, Ptuple p2 ->
List.equal eq_ml_pattern p1 p2
| Prel i1, Prel i2 ->
Int.equal i1 i2
| Pwild, Pwild -> true
-| Pusual gr1, Pusual gr2 -> eq_gr gr1 gr2
+| Pusual gr1, Pusual gr2 -> GlobRef.equal gr1 gr2
| _ -> false
and eq_ml_branch (id1, p1, t1) (id2, p2, t2) =
@@ -541,24 +541,24 @@ let dump_unused_vars a =
| MLcase (t,e,br) ->
let e' = ren env e in
- let br' = Array.smartmap (ren_branch env) br in
+ let br' = Array.Smart.map (ren_branch env) br in
if e' == e && br' == br then a else MLcase (t,e',br')
| MLfix (i,ids,v) ->
let env' = List.init (Array.length ids) (fun _ -> ref false) @ env in
- let v' = Array.smartmap (ren env') v in
+ let v' = Array.Smart.map (ren env') v in
if v' == v then a else MLfix (i,ids,v')
| MLapp (b,l) ->
- let b' = ren env b and l' = List.smartmap (ren env) l in
+ let b' = ren env b and l' = List.Smart.map (ren env) l in
if b' == b && l' == l then a else MLapp (b',l')
| MLcons(t,r,l) ->
- let l' = List.smartmap (ren env) l in
+ let l' = List.Smart.map (ren env) l in
if l' == l then a else MLcons (t,r,l')
| MLtuple l ->
- let l' = List.smartmap (ren env) l in
+ let l' = List.Smart.map (ren env) l in
if l' == l then a else MLtuple l'
| MLmagic b ->
@@ -984,7 +984,7 @@ let rec iota_red i lift br ((typ,r,a) as cons) =
if i >= Array.length br then raise Impossible;
let (ids,p,c) = br.(i) in
match p with
- | Pusual r' | Pcons (r',_) when not (Globnames.eq_gr r' r) -> iota_red (i+1) lift br cons
+ | Pusual r' | Pcons (r',_) when not (GlobRef.equal r' r) -> iota_red (i+1) lift br cons
| Pusual r' ->
let c = named_lams (List.rev ids) c in
let c = ast_lift lift c
diff --git a/plugins/extraction/mlutil.mli b/plugins/extraction/mlutil.mli
index 55a1ee89..d23fdb3d 100644
--- a/plugins/extraction/mlutil.mli
+++ b/plugins/extraction/mlutil.mli
@@ -9,7 +9,6 @@
(************************************************************************)
open Names
-open Globnames
open Miniml
open Table
@@ -59,7 +58,7 @@ val type_recomp : ml_type list * ml_type -> ml_type
val var2var' : ml_type -> ml_type
-type abbrev_map = global_reference -> ml_type option
+type abbrev_map = GlobRef.t -> ml_type option
val type_expand : abbrev_map -> ml_type -> ml_type
val type_simpl : ml_type -> ml_type
@@ -117,7 +116,7 @@ val dump_unused_vars : ml_ast -> ml_ast
val normalize : ml_ast -> ml_ast
val optimize_fix : ml_ast -> ml_ast
-val inline : global_reference -> ml_ast -> bool
+val inline : GlobRef.t -> ml_ast -> bool
val is_basic_pattern : ml_pattern -> bool
val has_deep_pattern : ml_branch array -> bool
diff --git a/plugins/extraction/modutil.ml b/plugins/extraction/modutil.ml
index f33a59ed..b398bc07 100644
--- a/plugins/extraction/modutil.ml
+++ b/plugins/extraction/modutil.ml
@@ -76,7 +76,7 @@ let struct_iter do_decl do_spec do_mp s =
(*s Apply some fonctions upon all references in [ml_type], [ml_ast],
[ml_decl], [ml_spec] and [ml_structure]. *)
-type do_ref = global_reference -> unit
+type do_ref = GlobRef.t -> unit
let record_iter_references do_term = function
| Record l -> List.iter (Option.iter do_term) l
diff --git a/plugins/extraction/modutil.mli b/plugins/extraction/modutil.mli
index 6a81f270..f45773f0 100644
--- a/plugins/extraction/modutil.mli
+++ b/plugins/extraction/modutil.mli
@@ -9,7 +9,6 @@
(************************************************************************)
open Names
-open Globnames
open Miniml
(*s Functions upon ML modules. *)
@@ -17,7 +16,7 @@ open Miniml
val struct_ast_search : (ml_ast -> bool) -> ml_structure -> bool
val struct_type_search : (ml_type -> bool) -> ml_structure -> bool
-type do_ref = global_reference -> unit
+type do_ref = GlobRef.t -> unit
val type_iter_references : do_ref -> ml_type -> unit
val ast_iter_references : do_ref -> do_ref -> do_ref -> ml_ast -> unit
@@ -30,7 +29,7 @@ val mtyp_of_mexpr : ml_module_expr -> ml_module_type
val msid_of_mt : ml_module_type -> ModPath.t
-val get_decl_in_structure : global_reference -> ml_structure -> ml_decl
+val get_decl_in_structure : GlobRef.t -> ml_structure -> ml_decl
(* Some transformations of ML terms. [optimize_struct] simplify
all beta redexes (when the argument does not occur, it is just
@@ -39,5 +38,5 @@ val get_decl_in_structure : global_reference -> ml_structure -> ml_decl
optimizations. The first argument is the list of objects we want to appear.
*)
-val optimize_struct : global_reference list * ModPath.t list ->
+val optimize_struct : GlobRef.t list * ModPath.t list ->
ml_structure -> ml_structure
diff --git a/plugins/extraction/table.ml b/plugins/extraction/table.ml
index 54c6d9d7..c3f4cfe6 100644
--- a/plugins/extraction/table.ml
+++ b/plugins/extraction/table.ml
@@ -652,7 +652,7 @@ let add_inline_entries b l =
(* Registration of operations for rollback. *)
-let inline_extraction : bool * global_reference list -> obj =
+let inline_extraction : bool * GlobRef.t list -> obj =
declare_object
{(default_object "Extraction Inline") with
cache_function = (fun (_,(b,l)) -> add_inline_entries b l);
@@ -736,7 +736,7 @@ let add_implicits r l =
(* Registration of operations for rollback. *)
-let implicit_extraction : global_reference * int_or_id list -> obj =
+let implicit_extraction : GlobRef.t * int_or_id list -> obj =
declare_object
{(default_object "Extraction Implicit") with
cache_function = (fun (_,(r,l)) -> add_implicits r l);
@@ -857,7 +857,7 @@ let find_custom_match pv =
(* Registration of operations for rollback. *)
-let in_customs : global_reference * string list * string -> obj =
+let in_customs : GlobRef.t * string list * string -> obj =
declare_object
{(default_object "ML extractions") with
cache_function = (fun (_,(r,ids,s)) -> add_custom r ids s);
@@ -867,7 +867,7 @@ let in_customs : global_reference * string list * string -> obj =
(fun (s,(r,ids,str)) -> (fst (subst_global s r), ids, str))
}
-let in_custom_matchs : global_reference * string -> obj =
+let in_custom_matchs : GlobRef.t * string -> obj =
declare_object
{(default_object "ML extractions custom matchs") with
cache_function = (fun (_,(r,s)) -> add_custom_match r s);
diff --git a/plugins/extraction/table.mli b/plugins/extraction/table.mli
index 906dfd96..a8baeaf1 100644
--- a/plugins/extraction/table.mli
+++ b/plugins/extraction/table.mli
@@ -10,31 +10,30 @@
open Names
open Libnames
-open Globnames
open Miniml
open Declarations
-module Refset' : CSig.SetS with type elt = global_reference
-module Refmap' : CSig.MapS with type key = global_reference
+module Refset' : CSig.SetS with type elt = GlobRef.t
+module Refmap' : CSig.MapS with type key = GlobRef.t
-val safe_basename_of_global : global_reference -> Id.t
+val safe_basename_of_global : GlobRef.t -> Id.t
(*s Warning and Error messages. *)
val warning_axioms : unit -> unit
val warning_opaques : bool -> unit
-val warning_ambiguous_name : ?loc:Loc.t -> qualid * ModPath.t * global_reference -> unit
+val warning_ambiguous_name : ?loc:Loc.t -> qualid * ModPath.t * GlobRef.t -> unit
val warning_id : string -> unit
-val error_axiom_scheme : global_reference -> int -> 'a
-val error_constant : global_reference -> 'a
-val error_inductive : global_reference -> 'a
+val error_axiom_scheme : GlobRef.t -> int -> 'a
+val error_constant : GlobRef.t -> 'a
+val error_inductive : GlobRef.t -> 'a
val error_nb_cons : unit -> 'a
val error_module_clash : ModPath.t -> ModPath.t -> 'a
val error_no_module_expr : ModPath.t -> 'a
-val error_singleton_become_prop : Id.t -> global_reference option -> 'a
+val error_singleton_become_prop : Id.t -> GlobRef.t option -> 'a
val error_unknown_module : qualid -> 'a
val error_scheme : unit -> 'a
-val error_not_visible : global_reference -> 'a
+val error_not_visible : GlobRef.t -> 'a
val error_MPfile_as_mod : ModPath.t -> bool -> 'a
val check_inside_module : unit -> unit
val check_inside_section : unit -> unit
@@ -44,12 +43,12 @@ val err_or_warn_remaining_implicit : kill_reason -> unit
val info_file : string -> unit
-(*s utilities about [module_path] and [kernel_names] and [global_reference] *)
+(*s utilities about [module_path] and [kernel_names] and [GlobRef.t] *)
-val occur_kn_in_ref : MutInd.t -> global_reference -> bool
-val repr_of_r : global_reference -> ModPath.t * DirPath.t * Label.t
-val modpath_of_r : global_reference -> ModPath.t
-val label_of_r : global_reference -> Label.t
+val occur_kn_in_ref : MutInd.t -> GlobRef.t -> bool
+val repr_of_r : GlobRef.t -> ModPath.t * DirPath.t * Label.t
+val modpath_of_r : GlobRef.t -> ModPath.t
+val label_of_r : GlobRef.t -> Label.t
val base_mp : ModPath.t -> ModPath.t
val is_modfile : ModPath.t -> bool
val string_of_modfile : ModPath.t -> string
@@ -61,7 +60,7 @@ val prefixes_mp : ModPath.t -> MPset.t
val common_prefix_from_list :
ModPath.t -> ModPath.t list -> ModPath.t option
val get_nth_label_mp : int -> ModPath.t -> Label.t
-val labels_of_ref : global_reference -> ModPath.t * Label.t list
+val labels_of_ref : GlobRef.t -> ModPath.t * Label.t list
(*s Some table-related operations *)
@@ -83,27 +82,27 @@ val add_ind : MutInd.t -> mutual_inductive_body -> ml_ind -> unit
val lookup_ind : MutInd.t -> mutual_inductive_body -> ml_ind option
val add_inductive_kind : MutInd.t -> inductive_kind -> unit
-val is_coinductive : global_reference -> bool
+val is_coinductive : GlobRef.t -> bool
val is_coinductive_type : ml_type -> bool
(* What are the fields of a record (empty for a non-record) *)
val get_record_fields :
- global_reference -> global_reference option list
-val record_fields_of_type : ml_type -> global_reference option list
+ GlobRef.t -> GlobRef.t option list
+val record_fields_of_type : ml_type -> GlobRef.t option list
val add_recursors : Environ.env -> MutInd.t -> unit
-val is_recursor : global_reference -> bool
+val is_recursor : GlobRef.t -> bool
val add_projection : int -> Constant.t -> inductive -> unit
-val is_projection : global_reference -> bool
-val projection_arity : global_reference -> int
-val projection_info : global_reference -> inductive * int (* arity *)
+val is_projection : GlobRef.t -> bool
+val projection_arity : GlobRef.t -> int
+val projection_info : GlobRef.t -> inductive * int (* arity *)
-val add_info_axiom : global_reference -> unit
-val remove_info_axiom : global_reference -> unit
-val add_log_axiom : global_reference -> unit
+val add_info_axiom : GlobRef.t -> unit
+val remove_info_axiom : GlobRef.t -> unit
+val add_log_axiom : GlobRef.t -> unit
-val add_opaque : global_reference -> unit
-val remove_opaque : global_reference -> unit
+val add_opaque : GlobRef.t -> unit
+val remove_opaque : GlobRef.t -> unit
val reset_tables : unit -> unit
@@ -172,22 +171,22 @@ val is_extrcompute : unit -> bool
(*s Table for custom inlining *)
-val to_inline : global_reference -> bool
-val to_keep : global_reference -> bool
+val to_inline : GlobRef.t -> bool
+val to_keep : GlobRef.t -> bool
(*s Table for implicits arguments *)
-val implicits_of_global : global_reference -> Int.Set.t
+val implicits_of_global : GlobRef.t -> Int.Set.t
(*s Table for user-given custom ML extractions. *)
(* UGLY HACK: registration of a function defined in [extraction.ml] *)
val type_scheme_nb_args_hook : (Environ.env -> Constr.t -> int) Hook.t
-val is_custom : global_reference -> bool
-val is_inline_custom : global_reference -> bool
-val find_custom : global_reference -> string
-val find_type_custom : global_reference -> string list * string
+val is_custom : GlobRef.t -> bool
+val is_inline_custom : GlobRef.t -> bool
+val find_custom : GlobRef.t -> string
+val find_type_custom : GlobRef.t -> string list * string
val is_custom_match : ml_branch array -> bool
val find_custom_match : ml_branch array -> string
@@ -195,17 +194,17 @@ val find_custom_match : ml_branch array -> string
(*s Extraction commands. *)
val extraction_language : lang -> unit
-val extraction_inline : bool -> reference list -> unit
+val extraction_inline : bool -> qualid list -> unit
val print_extraction_inline : unit -> Pp.t
val reset_extraction_inline : unit -> unit
val extract_constant_inline :
- bool -> reference -> string list -> string -> unit
+ bool -> qualid -> string list -> string -> unit
val extract_inductive :
- reference -> string -> string list -> string option -> unit
+ qualid -> string -> string list -> string option -> unit
type int_or_id = ArgInt of int | ArgId of Id.t
-val extraction_implicit : reference -> int_or_id list -> unit
+val extraction_implicit : qualid -> int_or_id list -> unit
(*s Table of blacklisted filenames *)
diff --git a/plugins/firstorder/formula.ml b/plugins/firstorder/formula.ml
index 047fc9fb..a60a966c 100644
--- a/plugins/firstorder/formula.ml
+++ b/plugins/firstorder/formula.ml
@@ -211,7 +211,7 @@ type left_pattern=
| Lexists of pinductive
| LA of constr*left_arrow_pattern
-type t={id:global_reference;
+type t={id:GlobRef.t;
constr:constr;
pat:(left_pattern,right_pattern) sum;
atoms:atoms}
diff --git a/plugins/firstorder/formula.mli b/plugins/firstorder/formula.mli
index 2962d923..e2c6f1c4 100644
--- a/plugins/firstorder/formula.mli
+++ b/plugins/firstorder/formula.mli
@@ -8,9 +8,9 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+open Names
open Constr
open EConstr
-open Globnames
val qflag : bool ref
@@ -35,7 +35,7 @@ type atoms = {positive:constr list;negative:constr list}
type side = Hyp | Concl | Hint
-val dummy_id: global_reference
+val dummy_id: GlobRef.t
val build_atoms : Environ.env -> Evd.evar_map -> counter ->
side -> constr -> bool * atoms
@@ -65,13 +65,13 @@ type left_pattern=
| Lexists of pinductive
| LA of constr*left_arrow_pattern
-type t={id: global_reference;
+type t={id: GlobRef.t;
constr: constr;
pat: (left_pattern,right_pattern) sum;
atoms: atoms}
(*exception Is_atom of constr*)
-val build_formula : Environ.env -> Evd.evar_map -> side -> global_reference -> types ->
+val build_formula : Environ.env -> Evd.evar_map -> side -> GlobRef.t -> types ->
counter -> (t,types) sum
diff --git a/plugins/firstorder/g_ground.ml4 b/plugins/firstorder/g_ground.ml4
index 30deb6f4..7e54bc8a 100644
--- a/plugins/firstorder/g_ground.ml4
+++ b/plugins/firstorder/g_ground.ml4
@@ -17,7 +17,6 @@ open Goptions
open Tacmach.New
open Tacticals.New
open Tacinterp
-open Libnames
open Stdarg
open Tacarg
open Pcoq.Prim
@@ -127,7 +126,7 @@ let normalize_evaluables=
open Genarg
open Ppconstr
open Printer
-let pr_firstorder_using_raw _ _ _ = Pptactic.pr_auto_using pr_reference
+let pr_firstorder_using_raw _ _ _ = Pptactic.pr_auto_using pr_qualid
let pr_firstorder_using_glob _ _ _ = Pptactic.pr_auto_using (pr_or_var (fun x -> pr_global (snd x)))
let pr_firstorder_using_typed _ _ _ = Pptactic.pr_auto_using pr_global
diff --git a/plugins/firstorder/ground.ml b/plugins/firstorder/ground.ml
index 4e3ba573..516b04ea 100644
--- a/plugins/firstorder/ground.ml
+++ b/plugins/firstorder/ground.ml
@@ -13,23 +13,21 @@ open Formula
open Sequent
open Rules
open Instances
-open Constr
open Tacmach.New
open Tacticals.New
+open Globnames
let update_flags ()=
- let predref=ref Names.Cpred.empty in
- let f coe=
- try
- let kn= fst (destConst (Classops.get_coercion_value coe)) in
- predref:=Names.Cpred.add kn !predref
- with DestKO -> ()
+ let f acc coe =
+ match coe.Classops.coe_value with
+ | ConstRef c -> Names.Cpred.add c acc
+ | _ -> acc
in
- List.iter f (Classops.coercions ());
+ let pred = List.fold_left f Names.Cpred.empty (Classops.coercions ()) in
red_flags:=
CClosure.RedFlags.red_add_transparent
CClosure.betaiotazeta
- (Names.Id.Pred.full,Names.Cpred.complement !predref)
+ (Names.Id.Pred.full,Names.Cpred.complement pred)
let ground_tac solver startseq =
Proofview.Goal.enter begin fun gl ->
diff --git a/plugins/firstorder/instances.ml b/plugins/firstorder/instances.ml
index e8c0b927..85f49395 100644
--- a/plugins/firstorder/instances.ml
+++ b/plugins/firstorder/instances.ml
@@ -22,7 +22,6 @@ open Reductionops
open Formula
open Sequent
open Names
-open Misctypes
open Context.Rel.Declaration
let compare_instance inst1 inst2=
@@ -43,7 +42,7 @@ let compare_gr id1 id2 =
module OrderedInstance=
struct
- type t=instance * Globnames.global_reference
+ type t=instance * GlobRef.t
let compare (inst1,id1) (inst2,id2)=
(compare_instance =? compare_gr) inst2 inst1 id2 id1
(* we want a __decreasing__ total order *)
@@ -184,12 +183,12 @@ let right_instance_tac inst continue seq=
[introf;
Proofview.Goal.enter begin fun gl ->
let id0 = List.nth (pf_ids_of_hyps gl) 0 in
- split (ImplicitBindings [mkVar id0])
+ split (Tactypes.ImplicitBindings [mkVar id0])
end;
tclSOLVE [wrap 0 true continue (deepen seq)]];
tclTRY assumption]
| Real ((0,t),_) ->
- (tclTHEN (split (ImplicitBindings [t]))
+ (tclTHEN (split (Tactypes.ImplicitBindings [t]))
(tclSOLVE [wrap 0 true continue (deepen seq)]))
| Real ((m,t),_) ->
tclFAIL 0 (Pp.str "not implemented ... yet")
diff --git a/plugins/firstorder/instances.mli b/plugins/firstorder/instances.mli
index 61786ffd..9f9ade3a 100644
--- a/plugins/firstorder/instances.mli
+++ b/plugins/firstorder/instances.mli
@@ -8,13 +8,13 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Globnames
+open Names
open Rules
val collect_quantified : Evd.evar_map -> Sequent.t -> Formula.t list * Sequent.t
val give_instances : Evd.evar_map -> Formula.t list -> Sequent.t ->
- (Unify.instance * global_reference) list
+ (Unify.instance * GlobRef.t) list
val quantified_tac : Formula.t list -> seqtac with_backtracking
diff --git a/plugins/firstorder/rules.ml b/plugins/firstorder/rules.ml
index cfcd6561..b13580bc 100644
--- a/plugins/firstorder/rules.ml
+++ b/plugins/firstorder/rules.ml
@@ -29,7 +29,7 @@ type tactic = unit Proofview.tactic
type seqtac= (Sequent.t -> tactic) -> Sequent.t -> tactic
-type lseqtac= global_reference -> seqtac
+type lseqtac= GlobRef.t -> seqtac
type 'a with_backtracking = tactic -> 'a
@@ -233,7 +233,7 @@ let ll_forall_tac prod backtrack id continue seq=
(* special for compatibility with old Intuition *)
-let constant str = Universes.constr_of_global
+let constant str = UnivGen.constr_of_global
@@ Coqlib.coq_reference "User" ["Init";"Logic"] str
let defined_connectives=lazy
diff --git a/plugins/firstorder/rules.mli b/plugins/firstorder/rules.mli
index 859388b3..924c2679 100644
--- a/plugins/firstorder/rules.mli
+++ b/plugins/firstorder/rules.mli
@@ -11,21 +11,20 @@
open Names
open Constr
open EConstr
-open Globnames
type tactic = unit Proofview.tactic
type seqtac= (Sequent.t -> tactic) -> Sequent.t -> tactic
-type lseqtac= global_reference -> seqtac
+type lseqtac= GlobRef.t -> seqtac
type 'a with_backtracking = tactic -> 'a
val wrap : int -> bool -> seqtac
-val basename_of_global: global_reference -> Id.t
+val basename_of_global: GlobRef.t -> Id.t
-val clear_global: global_reference -> tactic
+val clear_global: GlobRef.t -> tactic
val axiom_tac : constr -> Sequent.t -> tactic
@@ -41,7 +40,7 @@ val left_and_tac : pinductive -> lseqtac with_backtracking
val left_or_tac : pinductive -> lseqtac with_backtracking
-val left_false_tac : global_reference -> tactic
+val left_false_tac : GlobRef.t -> tactic
val ll_ind_tac : pinductive -> constr list -> lseqtac with_backtracking
diff --git a/plugins/firstorder/sequent.ml b/plugins/firstorder/sequent.ml
index 28599179..2a527da9 100644
--- a/plugins/firstorder/sequent.ml
+++ b/plugins/firstorder/sequent.ml
@@ -8,13 +8,13 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open EConstr
-open CErrors
open Util
+open Pp
+open CErrors
+open Names
+open EConstr
open Formula
open Unify
-open Globnames
-open Pp
let newcnt ()=
let cnt=ref (-1) in
@@ -56,7 +56,7 @@ struct
(priority e1.pat) - (priority e2.pat)
end
-type h_item = global_reference * (int*Constr.t) option
+type h_item = GlobRef.t * (int*Constr.t) option
module Hitem=
struct
@@ -77,17 +77,17 @@ module CM=Map.Make(Constr)
module History=Set.Make(Hitem)
let cm_add sigma typ nam cm=
- let typ = EConstr.to_constr sigma typ in
+ let typ = EConstr.to_constr ~abort_on_undefined_evars:false sigma typ in
try
let l=CM.find typ cm in CM.add typ (nam::l) cm
with
Not_found->CM.add typ [nam] cm
let cm_remove sigma typ nam cm=
- let typ = EConstr.to_constr sigma typ in
+ let typ = EConstr.to_constr ~abort_on_undefined_evars:false sigma typ in
try
let l=CM.find typ cm in
- let l0=List.filter (fun id-> not (Globnames.eq_gr id nam)) l in
+ let l0=List.filter (fun id-> not (GlobRef.equal id nam)) l in
match l0 with
[]->CM.remove typ cm
| _ ->CM.add typ l0 cm
@@ -97,7 +97,7 @@ module HP=Heap.Functional(OrderedFormula)
type t=
{redexes:HP.t;
- context:(global_reference list) CM.t;
+ context:(GlobRef.t list) CM.t;
latoms:constr list;
gl:types;
glatom:constr option;
@@ -117,7 +117,7 @@ let lookup sigma item seq=
let p (id2,o)=
match o with
None -> false
- | Some (m2, t2)-> Globnames.eq_gr id id2 && m2>m && more_general sigma (m2, EConstr.of_constr t2) (m, EConstr.of_constr t) in
+ | Some (m2, t2)-> GlobRef.equal id id2 && m2>m && more_general sigma (m2, EConstr.of_constr t2) (m, EConstr.of_constr t) in
History.exists p seq.history
let add_formula env sigma side nam t seq =
@@ -152,7 +152,7 @@ let re_add_formula_list sigma lf seq=
redexes=List.fold_right HP.add lf seq.redexes;
context=List.fold_right do_one lf seq.context}
-let find_left sigma t seq=List.hd (CM.find (EConstr.to_constr sigma t) seq.context)
+let find_left sigma t seq=List.hd (CM.find (EConstr.to_constr ~abort_on_undefined_evars:false sigma t) seq.context)
(*let rev_left seq=
try
@@ -187,9 +187,9 @@ let empty_seq depth=
let expand_constructor_hints =
List.map_append (function
- | IndRef ind ->
+ | GlobRef.IndRef ind ->
List.init (Inductiveops.nconstructors ind)
- (fun i -> ConstructRef (ind,i+1))
+ (fun i -> GlobRef.ConstructRef (ind,i+1))
| gr ->
[gr])
@@ -197,7 +197,7 @@ let extend_with_ref_list env sigma l seq =
let l = expand_constructor_hints l in
let f gr (seq, sigma) =
let sigma, c = Evd.fresh_global env sigma gr in
- let sigma, typ= Typing.type_of env sigma (EConstr.of_constr c) in
+ let sigma, typ= Typing.type_of env sigma c in
(add_formula env sigma Hyp gr typ seq, sigma) in
List.fold_right f l (seq, sigma)
@@ -229,7 +229,9 @@ let extend_with_auto_hints env sigma l seq =
let print_cmap map=
let print_entry c l s=
- let xc=Constrextern.extern_constr false (Global.env ()) Evd.empty (EConstr.of_constr c) in
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ let xc=Constrextern.extern_constr false env sigma (EConstr.of_constr c) in
str "| " ++
prlist Printer.pr_global l ++
str " : " ++
diff --git a/plugins/firstorder/sequent.mli b/plugins/firstorder/sequent.mli
index c4ed3e21..709b278e 100644
--- a/plugins/firstorder/sequent.mli
+++ b/plugins/firstorder/sequent.mli
@@ -8,26 +8,26 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+open Names
open EConstr
open Formula
-open Globnames
module CM: CSig.MapS with type key=Constr.t
-type h_item = global_reference * (int*Constr.t) option
+type h_item = GlobRef.t * (int*Constr.t) option
module History: Set.S with type elt = h_item
-val cm_add : Evd.evar_map -> constr -> global_reference -> global_reference list CM.t ->
- global_reference list CM.t
+val cm_add : Evd.evar_map -> constr -> GlobRef.t -> GlobRef.t list CM.t ->
+ GlobRef.t list CM.t
-val cm_remove : Evd.evar_map -> constr -> global_reference -> global_reference list CM.t ->
- global_reference list CM.t
+val cm_remove : Evd.evar_map -> constr -> GlobRef.t -> GlobRef.t list CM.t ->
+ GlobRef.t list CM.t
module HP: Heap.S with type elt=Formula.t
type t = {redexes:HP.t;
- context: global_reference list CM.t;
+ context: GlobRef.t list CM.t;
latoms:constr list;
gl:types;
glatom:constr option;
@@ -41,20 +41,20 @@ val record: h_item -> t -> t
val lookup: Evd.evar_map -> h_item -> t -> bool
-val add_formula : Environ.env -> Evd.evar_map -> side -> global_reference -> constr -> t -> t
+val add_formula : Environ.env -> Evd.evar_map -> side -> GlobRef.t -> constr -> t -> t
val re_add_formula_list : Evd.evar_map -> Formula.t list -> t -> t
-val find_left : Evd.evar_map -> constr -> t -> global_reference
+val find_left : Evd.evar_map -> constr -> t -> GlobRef.t
val take_formula : Evd.evar_map -> t -> Formula.t * t
val empty_seq : int -> t
-val extend_with_ref_list : Environ.env -> Evd.evar_map -> global_reference list ->
+val extend_with_ref_list : Environ.env -> Evd.evar_map -> GlobRef.t list ->
t -> t * Evd.evar_map
val extend_with_auto_hints : Environ.env -> Evd.evar_map -> Hints.hint_db_name list ->
t -> t * Evd.evar_map
-val print_cmap: global_reference list CM.t -> Pp.t
+val print_cmap: GlobRef.t list CM.t -> Pp.t
diff --git a/plugins/firstorder/unify.ml b/plugins/firstorder/unify.ml
index b869c04a..d63fe9d7 100644
--- a/plugins/firstorder/unify.ml
+++ b/plugins/firstorder/unify.ml
@@ -9,7 +9,7 @@
(************************************************************************)
open Util
-open Term
+open Constr
open EConstr
open Vars
open Termops
@@ -56,12 +56,12 @@ let unif evd t1 t2=
| Meta i,_ ->
let t=subst_meta !sigma nt2 in
if Int.Set.is_empty (free_rels evd t) &&
- not (dependent evd (EConstr.mkMeta i) t) then
+ not (occur_metavariable evd i t) then
bind i t else raise (UFAIL(nt1,nt2))
| _,Meta i ->
let t=subst_meta !sigma nt1 in
if Int.Set.is_empty (free_rels evd t) &&
- not (dependent evd (EConstr.mkMeta i) t) then
+ not (occur_metavariable evd i t) then
bind i t else raise (UFAIL(nt1,nt2))
| Cast(_,_,_),_->Queue.add (strip_outer_cast evd nt1,nt2) bige
| _,Cast(_,_,_)->Queue.add (nt1,strip_outer_cast evd nt2) bige
diff --git a/plugins/fourier/Fourier_util.v b/plugins/fourier/Fourier_util.v
deleted file mode 100644
index d3159698..00000000
--- a/plugins/fourier/Fourier_util.v
+++ /dev/null
@@ -1,222 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-Require Export Rbase.
-Comments "Lemmas used by the tactic Fourier".
-
-Open Scope R_scope.
-
-Lemma Rfourier_lt : forall x1 y1 a:R, x1 < y1 -> 0 < a -> a * x1 < a * y1.
-intros; apply Rmult_lt_compat_l; assumption.
-Qed.
-
-Lemma Rfourier_le : forall x1 y1 a:R, x1 <= y1 -> 0 < a -> a * x1 <= a * y1.
-red.
-intros.
-case H; auto with real.
-Qed.
-
-Lemma Rfourier_lt_lt :
- forall x1 y1 x2 y2 a:R,
- x1 < y1 -> x2 < y2 -> 0 < a -> x1 + a * x2 < y1 + a * y2.
-intros x1 y1 x2 y2 a H H0 H1; try assumption.
-apply Rplus_lt_compat.
-try exact H.
-apply Rfourier_lt.
-try exact H0.
-try exact H1.
-Qed.
-
-Lemma Rfourier_lt_le :
- forall x1 y1 x2 y2 a:R,
- x1 < y1 -> x2 <= y2 -> 0 < a -> x1 + a * x2 < y1 + a * y2.
-intros x1 y1 x2 y2 a H H0 H1; try assumption.
-case H0; intros.
-apply Rplus_lt_compat.
-try exact H.
-apply Rfourier_lt; auto with real.
-rewrite H2.
-rewrite (Rplus_comm y1 (a * y2)).
-rewrite (Rplus_comm x1 (a * y2)).
-apply Rplus_lt_compat_l.
-try exact H.
-Qed.
-
-Lemma Rfourier_le_lt :
- forall x1 y1 x2 y2 a:R,
- x1 <= y1 -> x2 < y2 -> 0 < a -> x1 + a * x2 < y1 + a * y2.
-intros x1 y1 x2 y2 a H H0 H1; try assumption.
-case H; intros.
-apply Rfourier_lt_le; auto with real.
-rewrite H2.
-apply Rplus_lt_compat_l.
-apply Rfourier_lt; auto with real.
-Qed.
-
-Lemma Rfourier_le_le :
- forall x1 y1 x2 y2 a:R,
- x1 <= y1 -> x2 <= y2 -> 0 < a -> x1 + a * x2 <= y1 + a * y2.
-intros x1 y1 x2 y2 a H H0 H1; try assumption.
-case H0; intros.
-red.
-left; try assumption.
-apply Rfourier_le_lt; auto with real.
-rewrite H2.
-case H; intros.
-red.
-left; try assumption.
-rewrite (Rplus_comm x1 (a * y2)).
-rewrite (Rplus_comm y1 (a * y2)).
-apply Rplus_lt_compat_l.
-try exact H3.
-rewrite H3.
-red.
-right; try assumption.
-auto with real.
-Qed.
-
-Lemma Rlt_zero_pos_plus1 : forall x:R, 0 < x -> 0 < 1 + x.
-intros x H; try assumption.
-rewrite Rplus_comm.
-apply Rle_lt_0_plus_1.
-red; auto with real.
-Qed.
-
-Lemma Rlt_mult_inv_pos : forall x y:R, 0 < x -> 0 < y -> 0 < x * / y.
-intros x y H H0; try assumption.
-replace 0 with (x * 0).
-apply Rmult_lt_compat_l; auto with real.
-ring.
-Qed.
-
-Lemma Rlt_zero_1 : 0 < 1.
-exact Rlt_0_1.
-Qed.
-
-Lemma Rle_zero_pos_plus1 : forall x:R, 0 <= x -> 0 <= 1 + x.
-intros x H; try assumption.
-case H; intros.
-red.
-left; try assumption.
-apply Rlt_zero_pos_plus1; auto with real.
-rewrite <- H0.
-replace (1 + 0) with 1.
-red; left.
-exact Rlt_zero_1.
-ring.
-Qed.
-
-Lemma Rle_mult_inv_pos : forall x y:R, 0 <= x -> 0 < y -> 0 <= x * / y.
-intros x y H H0; try assumption.
-case H; intros.
-red; left.
-apply Rlt_mult_inv_pos; auto with real.
-rewrite <- H1.
-red; right; ring.
-Qed.
-
-Lemma Rle_zero_1 : 0 <= 1.
-red; left.
-exact Rlt_zero_1.
-Qed.
-
-Lemma Rle_not_lt : forall n d:R, 0 <= n * / d -> ~ 0 < - n * / d.
-intros n d H; red; intros H0; try exact H0.
-generalize (Rgt_not_le 0 (n * / d)).
-intros H1; elim H1; try assumption.
-replace (n * / d) with (- - (n * / d)).
-replace 0 with (- -0).
-replace (- (n * / d)) with (- n * / d).
-replace (-0) with 0.
-red.
-apply Ropp_gt_lt_contravar.
-red.
-exact H0.
-ring.
-ring.
-ring.
-ring.
-Qed.
-
-Lemma Rnot_lt0 : forall x:R, ~ 0 < 0 * x.
-intros x; try assumption.
-replace (0 * x) with 0.
-apply Rlt_irrefl.
-ring.
-Qed.
-
-Lemma Rlt_not_le_frac_opp : forall n d:R, 0 < n * / d -> ~ 0 <= - n * / d.
-intros n d H; try assumption.
-apply Rgt_not_le.
-replace 0 with (-0).
-replace (- n * / d) with (- (n * / d)).
-apply Ropp_lt_gt_contravar.
-try exact H.
-ring.
-ring.
-Qed.
-
-Lemma Rnot_lt_lt : forall x y:R, ~ 0 < y - x -> ~ x < y.
-unfold not; intros.
-apply H.
-apply Rplus_lt_reg_l with x.
-replace (x + 0) with x.
-replace (x + (y - x)) with y.
-try exact H0.
-ring.
-ring.
-Qed.
-
-Lemma Rnot_le_le : forall x y:R, ~ 0 <= y - x -> ~ x <= y.
-unfold not; intros.
-apply H.
-case H0; intros.
-left.
-apply Rplus_lt_reg_l with x.
-replace (x + 0) with x.
-replace (x + (y - x)) with y.
-try exact H1.
-ring.
-ring.
-right.
-rewrite H1; ring.
-Qed.
-
-Lemma Rfourier_gt_to_lt : forall x y:R, y > x -> x < y.
-unfold Rgt; intros; assumption.
-Qed.
-
-Lemma Rfourier_ge_to_le : forall x y:R, y >= x -> x <= y.
-intros x y; exact (Rge_le y x).
-Qed.
-
-Lemma Rfourier_eqLR_to_le : forall x y:R, x = y -> x <= y.
-exact Req_le.
-Qed.
-
-Lemma Rfourier_eqRL_to_le : forall x y:R, y = x -> x <= y.
-exact Req_le_sym.
-Qed.
-
-Lemma Rfourier_not_ge_lt : forall x y:R, (x >= y -> False) -> x < y.
-exact Rnot_ge_lt.
-Qed.
-
-Lemma Rfourier_not_gt_le : forall x y:R, (x > y -> False) -> x <= y.
-exact Rnot_gt_le.
-Qed.
-
-Lemma Rfourier_not_le_gt : forall x y:R, (x <= y -> False) -> x > y.
-exact Rnot_le_lt.
-Qed.
-
-Lemma Rfourier_not_lt_ge : forall x y:R, (x < y -> False) -> x >= y.
-exact Rnot_lt_ge.
-Qed.
diff --git a/plugins/fourier/fourier.ml b/plugins/fourier/fourier.ml
deleted file mode 100644
index bee2b3b5..00000000
--- a/plugins/fourier/fourier.ml
+++ /dev/null
@@ -1,204 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-(* Méthode d'élimination de Fourier *)
-(* Référence:
-Auteur(s) : Fourier, Jean-Baptiste-Joseph
-
-Titre(s) : Oeuvres de Fourier [Document électronique]. Tome second. Mémoires publiés dans divers recueils / publ. par les soins de M. Gaston Darboux,...
-
-Publication : Numérisation BnF de l'édition de Paris : Gauthier-Villars, 1890
-
-Pages: 326-327
-
-http://gallica.bnf.fr/
-*)
-
-(* Un peu de calcul sur les rationnels...
-Les opérations rendent des rationnels normalisés,
-i.e. le numérateur et le dénominateur sont premiers entre eux.
-*)
-type rational = {num:int;
- den:int}
-;;
-let print_rational x =
- print_int x.num;
- print_string "/";
- print_int x.den
-;;
-
-let rec pgcd x y = if y = 0 then x else pgcd y (x mod y);;
-
-
-let r0 = {num=0;den=1};;
-let r1 = {num=1;den=1};;
-
-let rnorm x = let x = (if x.den<0 then {num=(-x.num);den=(-x.den)} else x) in
- if x.num=0 then r0
- else (let d=pgcd x.num x.den in
- let d= (if d<0 then -d else d) in
- {num=(x.num)/d;den=(x.den)/d});;
-
-let rop x = rnorm {num=(-x.num);den=x.den};;
-
-let rplus x y = rnorm {num=x.num*y.den + y.num*x.den;den=x.den*y.den};;
-
-let rminus x y = rnorm {num=x.num*y.den - y.num*x.den;den=x.den*y.den};;
-
-let rmult x y = rnorm {num=x.num*y.num;den=x.den*y.den};;
-
-let rinv x = rnorm {num=x.den;den=x.num};;
-
-let rdiv x y = rnorm {num=x.num*y.den;den=x.den*y.num};;
-
-let rinf x y = x.num*y.den < y.num*x.den;;
-let rinfeq x y = x.num*y.den <= y.num*x.den;;
-
-(* {coef;hist;strict}, où coef=[c1; ...; cn; d], représente l'inéquation
-c1x1+...+cnxn < d si strict=true, <= sinon,
-hist donnant les coefficients (positifs) d'une combinaison linéaire qui permet d'obtenir l'inéquation à partir de celles du départ.
-*)
-
-type ineq = {coef:rational list;
- hist:rational list;
- strict:bool};;
-
-let pop x l = l:=x::(!l);;
-
-(* sépare la liste d'inéquations s selon que leur premier coefficient est
-négatif, nul ou positif. *)
-let partitionne s =
- let lpos=ref [] in
- let lneg=ref [] in
- let lnul=ref [] in
- List.iter (fun ie -> match ie.coef with
- [] -> raise (Failure "empty ineq")
- |(c::r) -> if rinf c r0
- then pop ie lneg
- else if rinf r0 c then pop ie lpos
- else pop ie lnul)
- s;
- [!lneg;!lnul;!lpos]
-;;
-(* initialise les histoires d'une liste d'inéquations données par leurs listes de coefficients et leurs strictitudes (!):
-(add_hist [(equation 1, s1);...;(équation n, sn)])
-=
-[{équation 1, [1;0;...;0], s1};
- {équation 2, [0;1;...;0], s2};
- ...
- {équation n, [0;0;...;1], sn}]
-*)
-let add_hist le =
- let n = List.length le in
- let i = ref 0 in
- List.map (fun (ie,s) ->
- let h = ref [] in
- for _k = 1 to (n - (!i) - 1) do pop r0 h; done;
- pop r1 h;
- for _k = 1 to !i do pop r0 h; done;
- i:=!i+1;
- {coef=ie;hist=(!h);strict=s})
- le
-;;
-(* additionne deux inéquations *)
-let ie_add ie1 ie2 = {coef=List.map2 rplus ie1.coef ie2.coef;
- hist=List.map2 rplus ie1.hist ie2.hist;
- strict=ie1.strict || ie2.strict}
-;;
-(* multiplication d'une inéquation par un rationnel (positif) *)
-let ie_emult a ie = {coef=List.map (fun x -> rmult a x) ie.coef;
- hist=List.map (fun x -> rmult a x) ie.hist;
- strict= ie.strict}
-;;
-(* on enlève le premier coefficient *)
-let ie_tl ie = {coef=List.tl ie.coef;hist=ie.hist;strict=ie.strict}
-;;
-(* le premier coefficient: "tête" de l'inéquation *)
-let hd_coef ie = List.hd ie.coef
-;;
-
-(* calcule toutes les combinaisons entre inéquations de tête négative et inéquations de tête positive qui annulent le premier coefficient.
-*)
-let deduce_add lneg lpos =
- let res=ref [] in
- List.iter (fun i1 ->
- List.iter (fun i2 ->
- let a = rop (hd_coef i1) in
- let b = hd_coef i2 in
- pop (ie_tl (ie_add (ie_emult b i1)
- (ie_emult a i2))) res)
- lpos)
- lneg;
- !res
-;;
-(* élimination de la première variable à partir d'une liste d'inéquations:
-opération qu'on itère dans l'algorithme de Fourier.
-*)
-let deduce1 s =
- match (partitionne s) with
- [lneg;lnul;lpos] ->
- let lnew = deduce_add lneg lpos in
- (List.map ie_tl lnul)@lnew
- |_->assert false
-;;
-(* algorithme de Fourier: on élimine successivement toutes les variables.
-*)
-let deduce lie =
- let n = List.length (fst (List.hd lie)) in
- let lie=ref (add_hist lie) in
- for _i = 1 to n - 1 do
- lie:= deduce1 !lie;
- done;
- !lie
-;;
-
-(* donne [] si le système a des solutions,
-sinon donne [c,s,lc]
-où lc est la combinaison linéaire des inéquations de départ
-qui donne 0 < c si s=true
- ou 0 <= c sinon
-cette inéquation étant absurde.
-*)
-
-exception Contradiction of (rational * bool * rational list) list
-
-let unsolvable lie =
- let lr = deduce lie in
- let check = function
- | {coef=[c];hist=lc;strict=s} ->
- if (rinf c r0 && (not s)) || (rinfeq c r0 && s)
- then raise (Contradiction [c,s,lc])
- |_->assert false
- in
- try List.iter check lr; []
- with Contradiction l -> l
-
-(* Exemples:
-
-let test1=[[r1;r1;r0],true;[rop r1;r1;r1],false;[r0;rop r1;rop r1],false];;
-deduce test1;;
-unsolvable test1;;
-
-let test2=[
-[r1;r1;r0;r0;r0],false;
-[r0;r1;r1;r0;r0],false;
-[r0;r0;r1;r1;r0],false;
-[r0;r0;r0;r1;r1],false;
-[r1;r0;r0;r0;r1],false;
-[rop r1;rop r1;r0;r0;r0],false;
-[r0;rop r1;rop r1;r0;r0],false;
-[r0;r0;rop r1;rop r1;r0],false;
-[r0;r0;r0;rop r1;rop r1],false;
-[rop r1;r0;r0;r0;rop r1],false
-];;
-deduce test2;;
-unsolvable test2;;
-
-*)
diff --git a/plugins/fourier/fourierR.ml b/plugins/fourier/fourierR.ml
deleted file mode 100644
index b1c003de..00000000
--- a/plugins/fourier/fourierR.ml
+++ /dev/null
@@ -1,644 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-
-
-(* La tactique Fourier ne fonctionne de manière sûre que si les coefficients
-des inéquations et équations sont entiers. En attendant la tactique Field.
-*)
-
-open Constr
-open Tactics
-open Names
-open Globnames
-open Fourier
-open Contradiction
-open Proofview.Notations
-
-(******************************************************************************
-Opérations sur les combinaisons linéaires affines.
-La partie homogène d'une combinaison linéaire est en fait une table de hash
-qui donne le coefficient d'un terme du calcul des constructions,
-qui est zéro si le terme n'y est pas.
-*)
-
-module Constrhash = Hashtbl.Make(Constr)
-
-type flin = {fhom: rational Constrhash.t;
- fcste:rational};;
-
-let flin_zero () = {fhom=Constrhash.create 50;fcste=r0};;
-
-let flin_coef f x = try Constrhash.find f.fhom x with Not_found -> r0;;
-
-let flin_add f x c =
- let cx = flin_coef f x in
- Constrhash.replace f.fhom x (rplus cx c);
- f
-;;
-let flin_add_cste f c =
- {fhom=f.fhom;
- fcste=rplus f.fcste c}
-;;
-
-let flin_one () = flin_add_cste (flin_zero()) r1;;
-
-let flin_plus f1 f2 =
- let f3 = flin_zero() in
- Constrhash.iter (fun x c -> let _=flin_add f3 x c in ()) f1.fhom;
- Constrhash.iter (fun x c -> let _=flin_add f3 x c in ()) f2.fhom;
- flin_add_cste (flin_add_cste f3 f1.fcste) f2.fcste;
-;;
-
-let flin_minus f1 f2 =
- let f3 = flin_zero() in
- Constrhash.iter (fun x c -> let _=flin_add f3 x c in ()) f1.fhom;
- Constrhash.iter (fun x c -> let _=flin_add f3 x (rop c) in ()) f2.fhom;
- flin_add_cste (flin_add_cste f3 f1.fcste) (rop f2.fcste);
-;;
-let flin_emult a f =
- let f2 = flin_zero() in
- Constrhash.iter (fun x c -> let _=flin_add f2 x (rmult a c) in ()) f.fhom;
- flin_add_cste f2 (rmult a f.fcste);
-;;
-
-(*****************************************************************************)
-
-type ineq = Rlt | Rle | Rgt | Rge
-
-let string_of_R_constant kn =
- match Constant.repr3 kn with
- | ModPath.MPfile dir, sec_dir, id when
- sec_dir = DirPath.empty &&
- DirPath.to_string dir = "Coq.Reals.Rdefinitions"
- -> Label.to_string id
- | _ -> "constant_not_of_R"
-
-let rec string_of_R_constr c =
- match Constr.kind c with
- Cast (c,_,_) -> string_of_R_constr c
- |Const (c,_) -> string_of_R_constant c
- | _ -> "not_of_constant"
-
-exception NoRational
-
-let rec rational_of_constr c =
- match Constr.kind c with
- | Cast (c,_,_) -> (rational_of_constr c)
- | App (c,args) ->
- (match (string_of_R_constr c) with
- | "Ropp" ->
- rop (rational_of_constr args.(0))
- | "Rinv" ->
- rinv (rational_of_constr args.(0))
- | "Rmult" ->
- rmult (rational_of_constr args.(0))
- (rational_of_constr args.(1))
- | "Rdiv" ->
- rdiv (rational_of_constr args.(0))
- (rational_of_constr args.(1))
- | "Rplus" ->
- rplus (rational_of_constr args.(0))
- (rational_of_constr args.(1))
- | "Rminus" ->
- rminus (rational_of_constr args.(0))
- (rational_of_constr args.(1))
- | _ -> raise NoRational)
- | Const (kn,_) ->
- (match (string_of_R_constant kn) with
- "R1" -> r1
- |"R0" -> r0
- | _ -> raise NoRational)
- | _ -> raise NoRational
-;;
-
-exception NoLinear
-
-let rec flin_of_constr c =
- try(
- match Constr.kind c with
- | Cast (c,_,_) -> (flin_of_constr c)
- | App (c,args) ->
- (match (string_of_R_constr c) with
- "Ropp" ->
- flin_emult (rop r1) (flin_of_constr args.(0))
- | "Rplus"->
- flin_plus (flin_of_constr args.(0))
- (flin_of_constr args.(1))
- | "Rminus"->
- flin_minus (flin_of_constr args.(0))
- (flin_of_constr args.(1))
- | "Rmult"->
- (try
- let a = rational_of_constr args.(0) in
- try
- let b = rational_of_constr args.(1) in
- flin_add_cste (flin_zero()) (rmult a b)
- with NoRational ->
- flin_add (flin_zero()) args.(1) a
- with NoRational ->
- flin_add (flin_zero()) args.(0)
- (rational_of_constr args.(1)))
- | "Rinv"->
- let a = rational_of_constr args.(0) in
- flin_add_cste (flin_zero()) (rinv a)
- | "Rdiv"->
- (let b = rational_of_constr args.(1) in
- try
- let a = rational_of_constr args.(0) in
- flin_add_cste (flin_zero()) (rdiv a b)
- with NoRational ->
- flin_add (flin_zero()) args.(0) (rinv b))
- |_-> raise NoLinear)
- | Const (c,_) ->
- (match (string_of_R_constant c) with
- "R1" -> flin_one ()
- |"R0" -> flin_zero ()
- |_-> raise NoLinear)
- |_-> raise NoLinear)
- with NoRational | NoLinear -> flin_add (flin_zero()) c r1
-;;
-
-let flin_to_alist f =
- let res=ref [] in
- Constrhash.iter (fun x c -> res:=(c,x)::(!res)) f;
- !res
-;;
-
-(* Représentation des hypothèses qui sont des inéquations ou des équations.
-*)
-type hineq={hname:constr; (* le nom de l'hypothèse *)
- htype:string; (* Rlt, Rgt, Rle, Rge, eqTLR ou eqTRL *)
- hleft:constr;
- hright:constr;
- hflin:flin;
- hstrict:bool}
-;;
-
-(* Transforme une hypothese h:t en inéquation flin<0 ou flin<=0
-*)
-
-exception NoIneq
-
-let ineq1_of_constr (h,t) =
- let h = EConstr.Unsafe.to_constr h in
- let t = EConstr.Unsafe.to_constr t in
- match (Constr.kind t) with
- | App (f,args) ->
- (match Constr.kind f with
- | Const (c,_) when Array.length args = 2 ->
- let t1= args.(0) in
- let t2= args.(1) in
- (match (string_of_R_constant c) with
- |"Rlt" -> [{hname=h;
- htype="Rlt";
- hleft=t1;
- hright=t2;
- hflin= flin_minus (flin_of_constr t1)
- (flin_of_constr t2);
- hstrict=true}]
- |"Rgt" -> [{hname=h;
- htype="Rgt";
- hleft=t2;
- hright=t1;
- hflin= flin_minus (flin_of_constr t2)
- (flin_of_constr t1);
- hstrict=true}]
- |"Rle" -> [{hname=h;
- htype="Rle";
- hleft=t1;
- hright=t2;
- hflin= flin_minus (flin_of_constr t1)
- (flin_of_constr t2);
- hstrict=false}]
- |"Rge" -> [{hname=h;
- htype="Rge";
- hleft=t2;
- hright=t1;
- hflin= flin_minus (flin_of_constr t2)
- (flin_of_constr t1);
- hstrict=false}]
- |_-> raise NoIneq)
- | Ind ((kn,i),_) ->
- if not (eq_gr (IndRef(kn,i)) Coqlib.glob_eq) then raise NoIneq;
- let t0= args.(0) in
- let t1= args.(1) in
- let t2= args.(2) in
- (match (Constr.kind t0) with
- | Const (c,_) ->
- (match (string_of_R_constant c) with
- | "R"->
- [{hname=h;
- htype="eqTLR";
- hleft=t1;
- hright=t2;
- hflin= flin_minus (flin_of_constr t1)
- (flin_of_constr t2);
- hstrict=false};
- {hname=h;
- htype="eqTRL";
- hleft=t2;
- hright=t1;
- hflin= flin_minus (flin_of_constr t2)
- (flin_of_constr t1);
- hstrict=false}]
- |_-> raise NoIneq)
- |_-> raise NoIneq)
- |_-> raise NoIneq)
- |_-> raise NoIneq
-;;
-
-(* Applique la méthode de Fourier à une liste d'hypothèses (type hineq)
-*)
-
-let fourier_lineq lineq1 =
- let nvar=ref (-1) in
- let hvar=Constrhash.create 50 in (* la table des variables des inéquations *)
- List.iter (fun f ->
- Constrhash.iter (fun x _ -> if not (Constrhash.mem hvar x) then begin
- nvar:=(!nvar)+1;
- Constrhash.add hvar x (!nvar)
- end)
- f.hflin.fhom)
- lineq1;
- let sys= List.map (fun h->
- let v=Array.make ((!nvar)+1) r0 in
- Constrhash.iter (fun x c -> v.(Constrhash.find hvar x)<-c)
- h.hflin.fhom;
- ((Array.to_list v)@[rop h.hflin.fcste],h.hstrict))
- lineq1 in
- unsolvable sys
-;;
-
-(*********************************************************************)
-(* Defined constants *)
-
-let get = Lazy.force
-let cget = get
-let eget c = EConstr.of_constr (Lazy.force c)
-let constant path s = Universes.constr_of_global @@
- Coqlib.coq_reference "Fourier" path s
-
-(* Standard library *)
-open Coqlib
-let coq_sym_eqT = lazy (build_coq_eq_sym ())
-let coq_False = lazy (Universes.constr_of_global @@ build_coq_False ())
-let coq_not = lazy (Universes.constr_of_global @@ build_coq_not ())
-let coq_eq = lazy (Universes.constr_of_global @@ build_coq_eq ())
-
-(* Rdefinitions *)
-let constant_real = constant ["Reals";"Rdefinitions"]
-
-let coq_Rlt = lazy (constant_real "Rlt")
-let coq_Rgt = lazy (constant_real "Rgt")
-let coq_Rle = lazy (constant_real "Rle")
-let coq_Rge = lazy (constant_real "Rge")
-let coq_R = lazy (constant_real "R")
-let coq_Rminus = lazy (constant_real "Rminus")
-let coq_Rmult = lazy (constant_real "Rmult")
-let coq_Rplus = lazy (constant_real "Rplus")
-let coq_Ropp = lazy (constant_real "Ropp")
-let coq_Rinv = lazy (constant_real "Rinv")
-let coq_R0 = lazy (constant_real "R0")
-let coq_R1 = lazy (constant_real "R1")
-
-(* RIneq *)
-let coq_Rinv_1 = lazy (constant ["Reals";"RIneq"] "Rinv_1")
-
-(* Fourier_util *)
-let constant_fourier = constant ["fourier";"Fourier_util"]
-
-let coq_Rlt_zero_1 = lazy (constant_fourier "Rlt_zero_1")
-let coq_Rlt_zero_pos_plus1 = lazy (constant_fourier "Rlt_zero_pos_plus1")
-let coq_Rle_zero_pos_plus1 = lazy (constant_fourier "Rle_zero_pos_plus1")
-let coq_Rlt_mult_inv_pos = lazy (constant_fourier "Rlt_mult_inv_pos")
-let coq_Rle_zero_zero = lazy (constant_fourier "Rle_zero_zero")
-let coq_Rle_zero_1 = lazy (constant_fourier "Rle_zero_1")
-let coq_Rle_mult_inv_pos = lazy (constant_fourier "Rle_mult_inv_pos")
-let coq_Rnot_lt0 = lazy (constant_fourier "Rnot_lt0")
-let coq_Rle_not_lt = lazy (constant_fourier "Rle_not_lt")
-let coq_Rfourier_gt_to_lt = lazy (constant_fourier "Rfourier_gt_to_lt")
-let coq_Rfourier_ge_to_le = lazy (constant_fourier "Rfourier_ge_to_le")
-let coq_Rfourier_eqLR_to_le = lazy (constant_fourier "Rfourier_eqLR_to_le")
-let coq_Rfourier_eqRL_to_le = lazy (constant_fourier "Rfourier_eqRL_to_le")
-
-let coq_Rfourier_not_ge_lt = lazy (constant_fourier "Rfourier_not_ge_lt")
-let coq_Rfourier_not_gt_le = lazy (constant_fourier "Rfourier_not_gt_le")
-let coq_Rfourier_not_le_gt = lazy (constant_fourier "Rfourier_not_le_gt")
-let coq_Rfourier_not_lt_ge = lazy (constant_fourier "Rfourier_not_lt_ge")
-let coq_Rfourier_lt = lazy (constant_fourier "Rfourier_lt")
-let coq_Rfourier_le = lazy (constant_fourier "Rfourier_le")
-let coq_Rfourier_lt_lt = lazy (constant_fourier "Rfourier_lt_lt")
-let coq_Rfourier_lt_le = lazy (constant_fourier "Rfourier_lt_le")
-let coq_Rfourier_le_lt = lazy (constant_fourier "Rfourier_le_lt")
-let coq_Rfourier_le_le = lazy (constant_fourier "Rfourier_le_le")
-let coq_Rnot_lt_lt = lazy (constant_fourier "Rnot_lt_lt")
-let coq_Rnot_le_le = lazy (constant_fourier "Rnot_le_le")
-let coq_Rlt_not_le_frac_opp = lazy (constant_fourier "Rlt_not_le_frac_opp")
-
-(******************************************************************************
-Construction de la preuve en cas de succès de la méthode de Fourier,
-i.e. on obtient une contradiction.
-*)
-let is_int x = (x.den)=1
-;;
-
-(* fraction = couple (num,den) *)
-let rational_to_fraction x= (x.num,x.den)
-;;
-
-(* traduction -3 -> (Ropp (Rplus R1 (Rplus R1 R1)))
-*)
-let int_to_real n =
- let nn=abs n in
- if nn=0
- then get coq_R0
- else
- (let s=ref (get coq_R1) in
- for _i = 1 to (nn-1) do s:=mkApp (get coq_Rplus,[|get coq_R1;!s|]) done;
- if n<0 then mkApp (get coq_Ropp, [|!s|]) else !s)
-;;
-(* -1/2 -> (Rmult (Ropp R1) (Rinv (Rplus R1 R1)))
-*)
-let rational_to_real x =
- let (n,d)=rational_to_fraction x in
- mkApp (get coq_Rmult,
- [|int_to_real n;mkApp(get coq_Rinv,[|int_to_real d|])|])
-;;
-
-(* preuve que 0<n*1/d
-*)
-let tac_zero_inf_pos gl (n,d) =
- let get = eget in
- let tacn=ref (apply (get coq_Rlt_zero_1)) in
- let tacd=ref (apply (get coq_Rlt_zero_1)) in
- for _i = 1 to n - 1 do
- tacn:=(Tacticals.New.tclTHEN (apply (get coq_Rlt_zero_pos_plus1)) !tacn); done;
- for _i = 1 to d - 1 do
- tacd:=(Tacticals.New.tclTHEN (apply (get coq_Rlt_zero_pos_plus1)) !tacd); done;
- (Tacticals.New.tclTHENS (apply (get coq_Rlt_mult_inv_pos)) [!tacn;!tacd])
-;;
-
-(* preuve que 0<=n*1/d
-*)
-let tac_zero_infeq_pos gl (n,d)=
- let get = eget in
- let tacn=ref (if n=0
- then (apply (get coq_Rle_zero_zero))
- else (apply (get coq_Rle_zero_1))) in
- let tacd=ref (apply (get coq_Rlt_zero_1)) in
- for _i = 1 to n - 1 do
- tacn:=(Tacticals.New.tclTHEN (apply (get coq_Rle_zero_pos_plus1)) !tacn); done;
- for _i = 1 to d - 1 do
- tacd:=(Tacticals.New.tclTHEN (apply (get coq_Rlt_zero_pos_plus1)) !tacd); done;
- (Tacticals.New.tclTHENS (apply (get coq_Rle_mult_inv_pos)) [!tacn;!tacd])
-;;
-
-(* preuve que 0<(-n)*(1/d) => False
-*)
-let tac_zero_inf_false gl (n,d) =
- let get = eget in
-if n=0 then (apply (get coq_Rnot_lt0))
- else
- (Tacticals.New.tclTHEN (apply (get coq_Rle_not_lt))
- (tac_zero_infeq_pos gl (-n,d)))
-;;
-
-(* preuve que 0<=(-n)*(1/d) => False
-*)
-let tac_zero_infeq_false gl (n,d) =
- let get = eget in
- (Tacticals.New.tclTHEN (apply (get coq_Rlt_not_le_frac_opp))
- (tac_zero_inf_pos gl (-n,d)))
-;;
-
-let exact = exact_check;;
-
-let tac_use h =
- let get = eget in
- let tac = exact (EConstr.of_constr h.hname) in
- match h.htype with
- "Rlt" -> tac
- |"Rle" -> tac
- |"Rgt" -> (Tacticals.New.tclTHEN (apply (get coq_Rfourier_gt_to_lt)) tac)
- |"Rge" -> (Tacticals.New.tclTHEN (apply (get coq_Rfourier_ge_to_le)) tac)
- |"eqTLR" -> (Tacticals.New.tclTHEN (apply (get coq_Rfourier_eqLR_to_le)) tac)
- |"eqTRL" -> (Tacticals.New.tclTHEN (apply (get coq_Rfourier_eqRL_to_le)) tac)
- |_->assert false
-;;
-
-(*
-let is_ineq (h,t) =
- match (Constr.kind t) with
- App (f,args) ->
- (match (string_of_R_constr f) with
- "Rlt" -> true
- | "Rgt" -> true
- | "Rle" -> true
- | "Rge" -> true
-(* Wrong:not in Rdefinitions: *) | "eqT" ->
- (match (string_of_R_constr args.(0)) with
- "R" -> true
- | _ -> false)
- | _ ->false)
- |_->false
-;;
-*)
-
-let list_of_sign s =
- let open Context.Named.Declaration in
- List.map (function LocalAssum (name, typ) -> name, typ
- | LocalDef (name, _, typ) -> name, typ)
- s;;
-
-let mkAppL a =
- let l = Array.to_list a in
- mkApp(List.hd l, Array.of_list (List.tl l))
-;;
-
-exception GoalDone
-
-(* Résolution d'inéquations linéaires dans R *)
-let rec fourier () =
- Proofview.Goal.nf_enter begin fun gl ->
- let concl = Proofview.Goal.concl gl in
- let sigma = Tacmach.New.project gl in
- Coqlib.check_required_library ["Coq";"fourier";"Fourier"];
- let goal = Termops.strip_outer_cast sigma concl in
- let goal = EConstr.Unsafe.to_constr goal in
- let fhyp=Id.of_string "new_hyp_for_fourier" in
- (* si le but est une inéquation, on introduit son contraire,
- et le but à prouver devient False *)
- try
- match (Constr.kind goal) with
- App (f,args) ->
- let get = eget in
- (match (string_of_R_constr f) with
- "Rlt" ->
- (Tacticals.New.tclTHEN
- (Tacticals.New.tclTHEN (apply (get coq_Rfourier_not_ge_lt))
- (intro_using fhyp))
- (fourier ()))
- |"Rle" ->
- (Tacticals.New.tclTHEN
- (Tacticals.New.tclTHEN (apply (get coq_Rfourier_not_gt_le))
- (intro_using fhyp))
- (fourier ()))
- |"Rgt" ->
- (Tacticals.New.tclTHEN
- (Tacticals.New.tclTHEN (apply (get coq_Rfourier_not_le_gt))
- (intro_using fhyp))
- (fourier ()))
- |"Rge" ->
- (Tacticals.New.tclTHEN
- (Tacticals.New.tclTHEN (apply (get coq_Rfourier_not_lt_ge))
- (intro_using fhyp))
- (fourier ()))
- |_-> raise GoalDone)
- |_-> raise GoalDone
- with GoalDone ->
- (* les hypothèses *)
- let hyps = List.map (fun (h,t)-> (EConstr.mkVar h,t))
- (list_of_sign (Proofview.Goal.hyps gl)) in
- let lineq =ref [] in
- List.iter (fun h -> try (lineq:=(ineq1_of_constr h)@(!lineq))
- with NoIneq -> ())
- hyps;
- (* lineq = les inéquations découlant des hypothèses *)
- if !lineq=[] then CErrors.user_err Pp.(str "No inequalities");
- let res=fourier_lineq (!lineq) in
- let tac=ref (Proofview.tclUNIT ()) in
- if res=[]
- then CErrors.user_err Pp.(str "fourier failed")
- (* l'algorithme de Fourier a réussi: on va en tirer une preuve Coq *)
- else (match res with
- [(cres,sres,lc)]->
- (* lc=coefficients multiplicateurs des inéquations
- qui donnent 0<cres ou 0<=cres selon sres *)
- (*print_string "Fourier's method can prove the goal...";flush stdout;*)
- let lutil=ref [] in
- List.iter
- (fun (h,c) ->
- if c<>r0
- then (lutil:=(h,c)::(!lutil)(*;
- print_rational(c);print_string " "*)))
- (List.combine (!lineq) lc);
- (* on construit la combinaison linéaire des inéquation *)
- (match (!lutil) with
- (h1,c1)::lutil ->
- let s=ref (h1.hstrict) in
- let t1=ref (mkAppL [|get coq_Rmult;
- rational_to_real c1;
- h1.hleft|]) in
- let t2=ref (mkAppL [|get coq_Rmult;
- rational_to_real c1;
- h1.hright|]) in
- List.iter (fun (h,c) ->
- s:=(!s)||(h.hstrict);
- t1:=(mkAppL [|get coq_Rplus;
- !t1;
- mkAppL [|get coq_Rmult;
- rational_to_real c;
- h.hleft|] |]);
- t2:=(mkAppL [|get coq_Rplus;
- !t2;
- mkAppL [|get coq_Rmult;
- rational_to_real c;
- h.hright|] |]))
- lutil;
- let ineq=mkAppL [|if (!s) then get coq_Rlt else get coq_Rle;
- !t1;
- !t2 |] in
- let tc=rational_to_real cres in
- (* puis sa preuve *)
- let get = eget in
- let tac1=ref (if h1.hstrict
- then (Tacticals.New.tclTHENS (apply (get coq_Rfourier_lt))
- [tac_use h1;
- tac_zero_inf_pos gl
- (rational_to_fraction c1)])
- else (Tacticals.New.tclTHENS (apply (get coq_Rfourier_le))
- [tac_use h1;
- tac_zero_inf_pos gl
- (rational_to_fraction c1)])) in
- s:=h1.hstrict;
- List.iter (fun (h,c)->
- (if (!s)
- then (if h.hstrict
- then tac1:=(Tacticals.New.tclTHENS (apply (get coq_Rfourier_lt_lt))
- [!tac1;tac_use h;
- tac_zero_inf_pos gl
- (rational_to_fraction c)])
- else tac1:=(Tacticals.New.tclTHENS (apply (get coq_Rfourier_lt_le))
- [!tac1;tac_use h;
- tac_zero_inf_pos gl
- (rational_to_fraction c)]))
- else (if h.hstrict
- then tac1:=(Tacticals.New.tclTHENS (apply (get coq_Rfourier_le_lt))
- [!tac1;tac_use h;
- tac_zero_inf_pos gl
- (rational_to_fraction c)])
- else tac1:=(Tacticals.New.tclTHENS (apply (get coq_Rfourier_le_le))
- [!tac1;tac_use h;
- tac_zero_inf_pos gl
- (rational_to_fraction c)])));
- s:=(!s)||(h.hstrict))
- lutil;
- let tac2= if sres
- then tac_zero_inf_false gl (rational_to_fraction cres)
- else tac_zero_infeq_false gl (rational_to_fraction cres)
- in
- tac:=(Tacticals.New.tclTHENS (cut (EConstr.of_constr ineq))
- [Tacticals.New.tclTHEN (change_concl
- (EConstr.of_constr (mkAppL [| cget coq_not; ineq|]
- )))
- (Tacticals.New.tclTHEN (apply (if sres then get coq_Rnot_lt_lt
- else get coq_Rnot_le_le))
- (Tacticals.New.tclTHENS (Equality.replace
- (EConstr.of_constr (mkAppL [|cget coq_Rminus;!t2;!t1|]
- ))
- (EConstr.of_constr tc))
- [tac2;
- (Tacticals.New.tclTHENS
- (Equality.replace
- (EConstr.of_constr (mkApp (cget coq_Rinv,
- [|cget coq_R1|])))
- (get coq_R1))
-(* en attendant Field, ça peut aider Ring de remplacer 1/1 par 1 ... *)
-
- [Tacticals.New.tclORELSE
- (* TODO : Ring.polynom []*) (Proofview.tclUNIT ())
- (Proofview.tclUNIT ());
- Tacticals.New.pf_constr_of_global (cget coq_sym_eqT) >>= fun symeq ->
- (Tacticals.New.tclTHEN (apply symeq)
- (apply (get coq_Rinv_1)))]
-
- )
- ]));
- !tac1]);
- tac:=(Tacticals.New.tclTHENS (cut (get coq_False))
- [Tacticals.New.tclTHEN intro (contradiction None);
- !tac])
- |_-> assert false) |_-> assert false
- );
-(* ((tclTHEN !tac (tclFAIL 1 (* 1 au hasard... *))) gl) *)
- !tac
-(* ((tclABSTRACT None !tac) gl) *)
- end
-;;
-
-(*
-let fourier_tac x gl =
- fourier gl
-;;
-
-let v_fourier = add_tactic "Fourier" fourier_tac
-*)
-
diff --git a/plugins/fourier/fourier_plugin.mlpack b/plugins/fourier/fourier_plugin.mlpack
deleted file mode 100644
index b6262f8a..00000000
--- a/plugins/fourier/fourier_plugin.mlpack
+++ /dev/null
@@ -1,3 +0,0 @@
-Fourier
-FourierR
-G_fourier
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index d04887a4..268a012b 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -230,7 +230,7 @@ let isAppConstruct ?(env=Global.env ()) sigma t =
with Not_found -> false
let nf_betaiotazeta = (* Reductionops.local_strong Reductionops.whd_betaiotazeta *)
- Reductionops.clos_norm_flags CClosure.betaiotazeta Environ.empty_env Evd.empty
+ Reductionops.clos_norm_flags CClosure.betaiotazeta Environ.empty_env @@ Evd.from_env Environ.empty_env
exception NoChange
@@ -243,7 +243,7 @@ let change_eq env sigma hyp_id (context:rel_context) x t end_of_type =
raise NoChange;
end
in
- let eq_constr c1 c2 = Evarconv.e_conv env (ref sigma) c1 c2 in
+ let eq_constr c1 c2 = Option.has_some (Evarconv.conv env sigma c1 c2) in
if not (noccurn sigma 1 end_of_type)
then nochange "dependent"; (* if end_of_type depends on this term we don't touch it *)
if not (isApp sigma t) then nochange "not an equality";
@@ -414,9 +414,9 @@ let rewrite_until_var arg_num eq_ids : tactic =
let rec_pte_id = Id.of_string "Hrec"
let clean_hyp_with_heq ptes_infos eq_hyps hyp_id env sigma =
- let coq_False = EConstr.of_constr (Universes.constr_of_global @@ Coqlib.build_coq_False ()) in
- let coq_True = EConstr.of_constr (Universes.constr_of_global @@ Coqlib.build_coq_True ()) in
- let coq_I = EConstr.of_constr (Universes.constr_of_global @@ Coqlib.build_coq_I ()) in
+ let coq_False = EConstr.of_constr (UnivGen.constr_of_global @@ Coqlib.build_coq_False ()) in
+ let coq_True = EConstr.of_constr (UnivGen.constr_of_global @@ Coqlib.build_coq_True ()) in
+ let coq_I = EConstr.of_constr (UnivGen.constr_of_global @@ Coqlib.build_coq_I ()) in
let rec scan_type context type_of_hyp : tactic =
if isLetIn sigma type_of_hyp then
let real_type_of_hyp = it_mkProd_or_LetIn type_of_hyp context in
@@ -598,7 +598,7 @@ let treat_new_case ptes_infos nb_prod continue_tac term dyn_infos =
Proofview.V82.of_tactic (intro_using heq_id);
onLastHypId (fun heq_id -> tclTHENLIST [
(* Then the new hypothesis *)
- tclMAP (fun id -> Proofview.V82.of_tactic (introduction ~check:false id)) dyn_infos.rec_hyps;
+ tclMAP (fun id -> Proofview.V82.of_tactic (introduction id)) dyn_infos.rec_hyps;
observe_tac "after_introduction" (fun g' ->
(* We get infos on the equations introduced*)
let new_term_value_eq = pf_unsafe_type_of g' (mkVar heq_id) in
@@ -638,11 +638,11 @@ let my_orelse tac1 tac2 g =
(* observe (str "using snd tac since : " ++ CErrors.print e); *)
tac2 g
-let instanciate_hyps_with_args (do_prove:Id.t list -> tactic) hyps args_id =
+let instantiate_hyps_with_args (do_prove:Id.t list -> tactic) hyps args_id =
let args = Array.of_list (List.map mkVar args_id) in
- let instanciate_one_hyp hid =
+ let instantiate_one_hyp hid =
my_orelse
- ( (* we instanciate the hyp if possible *)
+ ( (* we instantiate the hyp if possible *)
fun g ->
let prov_hid = pf_get_new_id hid g in
let c = mkApp(mkVar hid,args) in
@@ -678,7 +678,7 @@ let instanciate_hyps_with_args (do_prove:Id.t list -> tactic) hyps args_id =
tclTHENLIST
[
tclMAP (fun hyp_id -> h_reduce_with_zeta (Locusops.onHyp hyp_id)) hyps;
- tclMAP instanciate_one_hyp hyps;
+ tclMAP instantiate_one_hyp hyps;
(fun g ->
let all_g_hyps_id =
List.fold_right Id.Set.add (pf_ids_of_hyps g) Id.Set.empty
@@ -722,11 +722,11 @@ let build_proof
tclTHENLIST [Proofview.V82.of_tactic (Simple.case t);
(fun g' ->
let g'_nb_prod = nb_prod (project g') (pf_concl g') in
- let nb_instanciate_partial = g'_nb_prod - g_nb_prod in
+ let nb_instantiate_partial = g'_nb_prod - g_nb_prod in
observe_tac "treat_new_case"
(treat_new_case
ptes_infos
- nb_instanciate_partial
+ nb_instantiate_partial
(build_proof do_finalize)
t
dyn_infos)
@@ -760,7 +760,7 @@ let build_proof
nb_rec_hyps = List.length new_hyps
}
in
-(* observe_tac "Lambda" *) (instanciate_hyps_with_args do_prove new_infos.rec_hyps [id]) g'
+(* observe_tac "Lambda" *) (instantiate_hyps_with_args do_prove new_infos.rec_hyps [id]) g'
(* build_proof do_finalize new_infos g' *)
) g
| _ ->
@@ -1013,7 +1013,7 @@ let generate_equation_lemma evd fnames f fun_num nb_params nb_args rec_args_num
lemma_type
(Lemmas.mk_hook (fun _ _ -> ()));
ignore (Pfedit.by (Proofview.V82.tactic prove_replacement));
- Lemmas.save_proof (Vernacexpr.(Proved(Transparent,None)));
+ Lemmas.save_proof (Vernacexpr.(Proved(Proof_global.Transparent,None)));
evd
@@ -1050,9 +1050,9 @@ let do_replace (evd:Evd.evar_map ref) params rec_arg_num rev_args_id f fun_num a
(Global.env ()) !evd
(Constrintern.locate_reference (qualid_of_ident equation_lemma_id))
in
- let res = EConstr.of_constr res in
- evd:=evd';
- let _ = Typing.e_type_of ~refresh:true (Global.env ()) evd res in
+ evd:=evd';
+ let sigma, _ = Typing.type_of ~refresh:true (Global.env ()) !evd res in
+ evd := sigma;
res
in
let nb_intro_to_do = nb_prod (project g) (pf_concl g) in
@@ -1099,10 +1099,12 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
let get_body const =
match Global.body_of_constant const with
| Some (body, _) ->
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
Tacred.cbv_norm_flags
(CClosure.RedFlags.mkflags [CClosure.RedFlags.fZETA])
- (Global.env ())
- (Evd.empty)
+ env
+ sigma
(EConstr.of_constr body)
| None -> user_err Pp.(str "Cannot define a principle over an axiom ")
in
@@ -1118,7 +1120,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
in
(full_params, (* real params *)
princ_params, (* the params of the principle which are not params of the function *)
- substl (* function instanciated with real params *)
+ substl (* function instantiated with real params *)
(List.map var_of_decl full_params)
f_body
)
@@ -1128,7 +1130,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
let f_body = compose_lam f_ctxt_other f_body in
(princ_info.params, (* real params *)
[],(* all params are full params *)
- substl (* function instanciated with real params *)
+ substl (* function instantiated with real params *)
(List.map var_of_decl princ_info.params)
f_body
)
@@ -1242,7 +1244,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
if this_fix_info.idx + 1 = 0
then tclIDTAC (* Someone tries to defined a principle on a fully parametric definition declared as a fixpoint (strange but ....) *)
else
- observe_tac_stream (str "h_fix " ++ int (this_fix_info.idx +1) ) (Proofview.V82.of_tactic (fix (Some this_fix_info.name) (this_fix_info.idx +1)))
+ observe_tac_stream (str "h_fix " ++ int (this_fix_info.idx +1) ) (Proofview.V82.of_tactic (fix this_fix_info.name (this_fix_info.idx +1)))
else
Proofview.V82.of_tactic (Tactics.mutual_fix this_fix_info.name (this_fix_info.idx + 1)
other_fix_infos 0)
@@ -1319,7 +1321,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
(* str "args := " ++ prlist_with_sep spc Ppconstr.pr_id args_id *)
(* ); *)
- (* observe_tac "instancing" *) (instanciate_hyps_with_args prove_tac
+ (* observe_tac "instancing" *) (instantiate_hyps_with_args prove_tac
(List.rev_map id_of_decl princ_info.branches)
(List.rev args_id))
]
@@ -1340,7 +1342,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
nb_rec_hyps = -100;
rec_hyps = [];
info =
- Reductionops.nf_betaiota (pf_env g) Evd.empty
+ Reductionops.nf_betaiota (pf_env g) (project g)
(applist(fbody_with_full_params,
(List.rev_map var_of_decl princ_params)@
(List.rev_map mkVar args_id)
@@ -1369,7 +1371,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
do_prove
dyn_infos
in
- instanciate_hyps_with_args prove_tac
+ instantiate_hyps_with_args prove_tac
(List.rev_map id_of_decl princ_info.branches)
(List.rev args_id)
]
@@ -1603,7 +1605,7 @@ let prove_principle_for_gen
match !tcc_lemma_ref with
| Undefined -> user_err Pp.(str "No tcc proof !!")
| Value lemma -> EConstr.of_constr lemma
- | Not_needed -> EConstr.of_constr (Universes.constr_of_global @@ Coqlib.build_coq_I ())
+ | Not_needed -> EConstr.of_constr (UnivGen.constr_of_global @@ Coqlib.build_coq_I ())
in
(* let rec list_diff del_list check_list = *)
(* match del_list with *)
@@ -1657,7 +1659,7 @@ let prove_principle_for_gen
(* observe_tac "reverting" *) (revert (List.rev (acc_rec_arg_id::args_ids)));
(* (fun g -> observe (Printer.pr_goal (sig_it g) ++ fnl () ++ *)
(* str "fix arg num" ++ int (List.length args_ids + 1) ); tclIDTAC g); *)
- (* observe_tac "h_fix " *) (Proofview.V82.of_tactic (fix (Some fix_id) (List.length args_ids + 1)));
+ (* observe_tac "h_fix " *) (Proofview.V82.of_tactic (fix fix_id (List.length args_ids + 1)));
(* (fun g -> observe (Printer.pr_goal (sig_it g) ++ fnl() ++ pr_lconstr_env (pf_env g ) (pf_unsafe_type_of g (mkVar fix_id) )); tclIDTAC g); *)
h_intros (List.rev (acc_rec_arg_id::args_ids));
Proofview.V82.of_tactic (Equality.rewriteLR (mkConst eq_ref));
@@ -1726,8 +1728,8 @@ let prove_principle_for_gen
ptes_info
(body_info rec_hyps)
in
- (* observe_tac "instanciate_hyps_with_args" *)
- (instanciate_hyps_with_args
+ (* observe_tac "instantiate_hyps_with_args" *)
+ (instantiate_hyps_with_args
make_proof
(List.map (get_name %> Nameops.Name.get_id) princ_info.branches)
(List.rev args_ids)
diff --git a/plugins/funind/functional_principles_types.ml b/plugins/funind/functional_principles_types.ml
index 804548ce..b2a528a1 100644
--- a/plugins/funind/functional_principles_types.ml
+++ b/plugins/funind/functional_principles_types.ml
@@ -266,7 +266,7 @@ let change_property_sort evd toSort princ princName =
(Global.env ()) evd (Constrintern.locate_reference (Libnames.qualid_of_ident princName)) in
let init =
let nargs = (princ_info.nparams + (List.length princ_info.predicates)) in
- mkApp(princName_as_constr,
+ mkApp(EConstr.Unsafe.to_constr princName_as_constr,
Array.init nargs
(fun i -> mkRel (nargs - i )))
in
@@ -291,7 +291,8 @@ let build_functional_principle (evd:Evd.evar_map ref) interactive_proof old_prin
let new_princ_name =
next_ident_away_in_goal (Id.of_string "___________princ_________") Id.Set.empty
in
- let _ = Typing.e_type_of ~refresh:true (Global.env ()) evd (EConstr.of_constr new_principle_type) in
+ let sigma, _ = Typing.type_of ~refresh:true (Global.env ()) !evd (EConstr.of_constr new_principle_type) in
+ evd := sigma;
let hook = Lemmas.mk_hook (hook new_principle_type) in
begin
Lemmas.start_proof
@@ -321,8 +322,7 @@ let generate_functional_principle (evd: Evd.evar_map ref)
try
let f = funs.(i) in
- let env = Global.env () in
- let type_sort = Evarutil.evd_comb1 (Evd.fresh_sort_in_family env) evd InType in
+ let type_sort = Evarutil.evd_comb1 Evd.fresh_sort_in_family evd InType in
let new_sorts =
match sorts with
| None -> Array.make (Array.length funs) (type_sort)
@@ -343,7 +343,7 @@ let generate_functional_principle (evd: Evd.evar_map ref)
(* let id_of_f = Label.to_id (con_label f) in *)
let register_with_sort fam_sort =
let evd' = Evd.from_env (Global.env ()) in
- let evd',s = Evd.fresh_sort_in_family env evd' fam_sort in
+ let evd',s = Evd.fresh_sort_in_family evd' fam_sort in
let name = Indrec.make_elimination_ident base_new_princ_name fam_sort in
let evd',value = change_property_sort evd' s new_principle_type new_princ_name in
let evd' = fst (Typing.type_of ~refresh:true (Global.env ()) evd' (EConstr.of_constr value)) in
@@ -353,7 +353,7 @@ let generate_functional_principle (evd: Evd.evar_map ref)
Evd.const_univ_entry ~poly evd'
in
let ce = Declare.definition_entry ~univs value in
- ignore(
+ ignore(
Declare.declare_constant
name
(DefinitionEntry ce,
@@ -507,8 +507,8 @@ let make_scheme evd (fas : (pconstant*Sorts.family) list) : Safe_typing.private_
let i = ref (-1) in
let sorts =
List.rev_map (fun (_,x) ->
- Evarutil.evd_comb1 (Evd.fresh_sort_in_family env) evd x
- )
+ Evarutil.evd_comb1 Evd.fresh_sort_in_family evd x
+ )
fas
in
(* We create the first priciple by tactic *)
@@ -626,15 +626,19 @@ let build_scheme fas =
Smartlocate.global_with_alias f
with Not_found ->
user_err ~hdr:"FunInd.build_scheme"
- (str "Cannot find " ++ Libnames.pr_reference f)
+ (str "Cannot find " ++ Libnames.pr_qualid f)
in
let evd',f = Evd.fresh_global (Global.env ()) !evd f_as_constant in
let _ = evd := evd' in
- let _ = Typing.e_type_of ~refresh:true (Global.env ()) evd (EConstr.of_constr f) in
- if isConst f
- then (destConst f,sort)
- else user_err Pp.(pr_constr_env (Global.env ()) !evd f ++spc () ++ str "should be the named of a globally defined function")
- )
+ let sigma, _ = Typing.type_of ~refresh:true (Global.env ()) !evd f in
+ evd := sigma;
+ let c, u =
+ try EConstr.destConst !evd f
+ with DestKO ->
+ user_err Pp.(pr_econstr_env (Global.env ()) !evd f ++spc () ++ str "should be the named of a globally defined function")
+ in
+ (c, EConstr.EInstance.kind !evd u), sort
+ )
fas
) in
let bodies_types =
@@ -663,7 +667,7 @@ let build_case_scheme fa =
try fst (Global.constr_of_global_in_context (Global.env ()) (Smartlocate.global_with_alias f))
with Not_found ->
user_err ~hdr:"FunInd.build_case_scheme"
- (str "Cannot find " ++ Libnames.pr_reference f) in
+ (str "Cannot find " ++ Libnames.pr_qualid f) in
let first_fun,u = destConst funs in
let funs_mp,funs_dp,_ = Constant.repr3 first_fun in
let first_fun_kn = try fst (find_Function_infos first_fun).graph_ind with Not_found -> raise No_graph_found in
@@ -684,7 +688,7 @@ let build_case_scheme fa =
let scheme_type = EConstr.Unsafe.to_constr ((Typing.unsafe_type_of env sigma) (EConstr.of_constr scheme)) in
let sorts =
(fun (_,_,x) ->
- Universes.new_sort_in_family x
+ UnivGen.new_sort_in_family x
)
fa
in
diff --git a/plugins/funind/functional_principles_types.mli b/plugins/funind/functional_principles_types.mli
index 33aeafef..97f9acdb 100644
--- a/plugins/funind/functional_principles_types.mli
+++ b/plugins/funind/functional_principles_types.mli
@@ -36,5 +36,5 @@ exception No_graph_found
val make_scheme : Evd.evar_map ref ->
(pconstant*Sorts.family) list -> Safe_typing.private_constants Entries.definition_entry list
-val build_scheme : (Id.t*Libnames.reference*Sorts.family) list -> unit
-val build_case_scheme : (Id.t*Libnames.reference*Sorts.family) -> unit
+val build_scheme : (Id.t*Libnames.qualid*Sorts.family) list -> unit
+val build_case_scheme : (Id.t*Libnames.qualid*Sorts.family) -> unit
diff --git a/plugins/funind/g_indfun.ml4 b/plugins/funind/g_indfun.ml4
index 90af20b4..a2d31780 100644
--- a/plugins/funind/g_indfun.ml4
+++ b/plugins/funind/g_indfun.ml4
@@ -15,7 +15,8 @@ open Indfun_common
open Indfun
open Genarg
open Stdarg
-open Misctypes
+open Tacarg
+open Tactypes
open Pcoq
open Pcoq.Prim
open Pcoq.Constr
@@ -38,7 +39,9 @@ let pr_fun_ind_using_typed prc prlc _ opt_c =
match opt_c with
| None -> mt ()
| Some b ->
- let (_, b) = b (Global.env ()) Evd.empty in
+ let env = Global.env () in
+ let evd = Evd.from_env env in
+ let (_, b) = b env evd in
spc () ++ hov 2 (str "using" ++ spc () ++ Miscprint.pr_with_bindings prc prlc b)
@@ -123,7 +126,7 @@ ARGUMENT EXTEND auto_using'
END
module Gram = Pcoq.Gram
-module Vernac = Pcoq.Vernac_
+module Vernac = Pvernac.Vernac_
module Tactic = Pltac
type function_rec_definition_loc_argtype = (Vernacexpr.fixpoint_expr * Vernacexpr.decl_notation list) Loc.located
@@ -165,7 +168,7 @@ END
let pr_fun_scheme_arg (princ_name,fun_name,s) =
Names.Id.print princ_name ++ str " :=" ++ spc() ++ str "Induction for " ++
- Libnames.pr_reference fun_name ++ spc() ++ str "Sort " ++
+ Libnames.pr_qualid fun_name ++ spc() ++ str "Sort " ++
Termops.pr_sort_family s
VERNAC ARGUMENT EXTEND fun_scheme_arg
@@ -178,11 +181,11 @@ let warning_error names e =
let (e, _) = ExplainErr.process_vernac_interp_error (e, Exninfo.null) in
match e with
| Building_graph e ->
- let names = pr_enum Libnames.pr_reference names in
+ let names = pr_enum Libnames.pr_qualid names in
let error = if do_observe () then (spc () ++ CErrors.print e) else mt () in
warn_cannot_define_graph (names,error)
| Defining_principle e ->
- let names = pr_enum Libnames.pr_reference names in
+ let names = pr_enum Libnames.pr_qualid names in
let error = if do_observe () then CErrors.print e else mt () in
warn_cannot_define_principle (names,error)
| _ -> raise e
diff --git a/plugins/funind/glob_term_to_relation.ml b/plugins/funind/glob_term_to_relation.ml
index 04006453..926a2056 100644
--- a/plugins/funind/glob_term_to_relation.ml
+++ b/plugins/funind/glob_term_to_relation.ml
@@ -10,7 +10,6 @@ open Indfun_common
open CErrors
open Util
open Glob_termops
-open Misctypes
module RelDecl = Context.Rel.Declaration
module NamedDecl = Context.Named.Declaration
@@ -883,7 +882,7 @@ let is_res r = match DAst.get r with
| _ -> false
let is_gr c gr = match DAst.get c with
-| GRef (r, _) -> Globnames.eq_gr r gr
+| GRef (r, _) -> GlobRef.equal r gr
| _ -> false
let is_gvar c = match DAst.get c with
@@ -892,7 +891,7 @@ let is_gvar c = match DAst.get c with
let same_raw_term rt1 rt2 =
match DAst.get rt1, DAst.get rt2 with
- | GRef(r1,_), GRef (r2,_) -> Globnames.eq_gr r1 r2
+ | GRef(r1,_), GRef (r2,_) -> GlobRef.equal r1 r2
| GHole _, GHole _ -> true
| _ -> false
let decompose_raw_eq lhs rhs =
@@ -1498,7 +1497,7 @@ let do_build_inductive
let _time2 = System.get_time () in
try
with_full_print
- (Flags.silently (ComInductive.do_mutual_inductive rel_inds (Flags.is_universe_polymorphism ()) false false))
+ (Flags.silently (ComInductive.do_mutual_inductive rel_inds (Flags.is_universe_polymorphism ()) false false ~uniform:ComInductive.NonUniformParameters))
Declarations.Finite
with
| UserError(s,msg) as e ->
@@ -1510,7 +1509,7 @@ let do_build_inductive
in
let msg =
str "while trying to define"++ spc () ++
- Ppvernac.pr_vernac Vernacexpr.(VernacExpr([], VernacInductive(GlobalNonCumulativity,false,Declarations.Finite,repacked_rel_inds)))
+ Ppvernac.pr_vernac Vernacexpr.(VernacExpr([], VernacInductive(None,false,Declarations.Finite,repacked_rel_inds)))
++ fnl () ++
msg
in
@@ -1525,7 +1524,7 @@ let do_build_inductive
in
let msg =
str "while trying to define"++ spc () ++
- Ppvernac.pr_vernac Vernacexpr.(VernacExpr([], VernacInductive(GlobalNonCumulativity,false,Declarations.Finite,repacked_rel_inds)))
+ Ppvernac.pr_vernac Vernacexpr.(VernacExpr([], VernacInductive(None,false,Declarations.Finite,repacked_rel_inds)))
++ fnl () ++
CErrors.print reraise
in
diff --git a/plugins/funind/glob_termops.ml b/plugins/funind/glob_termops.ml
index 769fcc1c..f81de82d 100644
--- a/plugins/funind/glob_termops.ml
+++ b/plugins/funind/glob_termops.ml
@@ -1,10 +1,10 @@
open Pp
+open Constr
open Glob_term
open CErrors
open Util
open Names
open Decl_kinds
-open Misctypes
(*
Some basic functions to rebuild glob_constr
@@ -16,8 +16,8 @@ let mkGApp(rt,rtl) = DAst.make @@ GApp(rt,rtl)
let mkGLambda(n,t,b) = DAst.make @@ GLambda(n,Explicit,t,b)
let mkGProd(n,t,b) = DAst.make @@ GProd(n,Explicit,t,b)
let mkGLetIn(n,b,t,c) = DAst.make @@ GLetIn(n,b,t,c)
-let mkGCases(rto,l,brl) = DAst.make @@ GCases(Term.RegularStyle,rto,l,brl)
-let mkGHole () = DAst.make @@ GHole(Evar_kinds.BinderType Anonymous,Misctypes.IntroAnonymous,None)
+let mkGCases(rto,l,brl) = DAst.make @@ GCases(RegularStyle,rto,l,brl)
+let mkGHole () = DAst.make @@ GHole(Evar_kinds.BinderType Anonymous,Namegen.IntroAnonymous,None)
(*
Some basic functions to decompose glob_constrs
@@ -108,7 +108,7 @@ let change_vars =
| GHole _ as x -> x
| GCast(b,c) ->
GCast(change_vars mapping b,
- Miscops.map_cast_type (change_vars mapping) c)
+ Glob_ops.map_cast_type (change_vars mapping) c)
) rt
and change_vars_br mapping ({CAst.loc;v=(idl,patl,res)} as br) =
let new_mapping = List.fold_right Id.Map.remove idl mapping in
@@ -288,7 +288,7 @@ let rec alpha_rt excluded rt =
| GHole _ as rt -> rt
| GCast (b,c) ->
GCast(alpha_rt excluded b,
- Miscops.map_cast_type (alpha_rt excluded) c)
+ Glob_ops.map_cast_type (alpha_rt excluded) c)
| GApp(f,args) ->
GApp(alpha_rt excluded f,
List.map (alpha_rt excluded) args
@@ -436,7 +436,7 @@ let replace_var_by_term x_id term =
| GHole _ as rt -> rt
| GCast(b,c) ->
GCast(replace_var_by_pattern b,
- Miscops.map_cast_type replace_var_by_pattern c)
+ Glob_ops.map_cast_type replace_var_by_pattern c)
) x
and replace_var_by_pattern_br ({CAst.loc;v=(idl,patl,res)} as br) =
if List.exists (fun id -> Id.compare id x_id == 0) idl
@@ -536,7 +536,7 @@ let expand_as =
| GRec _ -> user_err Pp.(str "Not handled GRec")
| GCast(b,c) ->
GCast(expand_as map b,
- Miscops.map_cast_type (expand_as map) c)
+ Glob_ops.map_cast_type (expand_as map) c)
| GCases(sty,po,el,brl) ->
GCases(sty, Option.map (expand_as map) po, List.map (fun (rt,t) -> expand_as map rt,t) el,
List.map (expand_as_br map) brl)
@@ -557,7 +557,8 @@ let resolve_and_replace_implicits ?(flags=Pretyping.all_and_fail_flags) ?(expect
(* FIXME : JF (30/03/2017) I'm not completely sure to have split understand as needed.
If someone knows how to prevent solved existantial removal in understand, please do not hesitate to change the computation of [ctx] here *)
let ctx,_,_ = Pretyping.ise_pretype_gen flags env sigma Glob_ops.empty_lvar expected_type rt in
- let ctx, f = Evarutil.nf_evars_and_universes ctx in
+ let ctx = Evd.minimize_universes ctx in
+ let f c = EConstr.of_constr (Evarutil.nf_evars_universes ctx (EConstr.Unsafe.to_constr c)) in
(* then we map [rt] to replace the implicit holes by their values *)
let rec change rt =
@@ -569,7 +570,7 @@ If someone knows how to prevent solved existantial removal in understand, pleas
(fun _ evi _ ->
match evi.evar_source with
| (loc_evi,ImplicitArg(gr_evi,p_evi,b_evi)) ->
- if Globnames.eq_gr grk gr_evi && pk=p_evi && bk=b_evi && rt.CAst.loc = loc_evi
+ if GlobRef.equal grk gr_evi && pk=p_evi && bk=b_evi && rt.CAst.loc = loc_evi
then raise (Found evi)
| _ -> ()
)
@@ -580,8 +581,8 @@ If someone knows how to prevent solved existantial removal in understand, pleas
with Found evi -> (* we found the evar corresponding to this hole *)
match evi.evar_body with
| Evar_defined c ->
- (* we just have to lift the solution in glob_term *)
- Detyping.detype Detyping.Now false Id.Set.empty env ctx (EConstr.of_constr (f c))
+ (* we just have to lift the solution in glob_term *)
+ Detyping.detype Detyping.Now false Id.Set.empty env ctx (f c)
| Evar_empty -> rt (* the hole was not solved : we do nothing *)
)
| (GHole(BinderType na,_,_)) -> (* we only want to deal with implicit arguments *)
@@ -603,7 +604,7 @@ If someone knows how to prevent solved existantial removal in understand, pleas
match evi.evar_body with
| Evar_defined c ->
(* we just have to lift the solution in glob_term *)
- Detyping.detype Detyping.Now false Id.Set.empty env ctx (EConstr.of_constr (f c))
+ Detyping.detype Detyping.Now false Id.Set.empty env ctx (f c)
| Evar_empty -> rt (* the hole was not solved : we d when falseo nothing *)
in
res
diff --git a/plugins/funind/glob_termops.mli b/plugins/funind/glob_termops.mli
index 7088ae59..481a8be3 100644
--- a/plugins/funind/glob_termops.mli
+++ b/plugins/funind/glob_termops.mli
@@ -13,7 +13,7 @@ val pattern_to_term : cases_pattern -> glob_constr
Some basic functions to rebuild glob_constr
In each of them the location is Util.Loc.ghost
*)
-val mkGRef : Globnames.global_reference -> glob_constr
+val mkGRef : GlobRef.t -> glob_constr
val mkGVar : Id.t -> glob_constr
val mkGApp : glob_constr*(glob_constr list) -> glob_constr
val mkGLambda : Name.t * glob_constr * glob_constr -> glob_constr
diff --git a/plugins/funind/indfun.ml b/plugins/funind/indfun.ml
index 57863ee6..9eda19a8 100644
--- a/plugins/funind/indfun.ml
+++ b/plugins/funind/indfun.ml
@@ -10,7 +10,7 @@ open Libnames
open Globnames
open Glob_term
open Declarations
-open Misctypes
+open Tactypes
open Decl_kinds
module RelDecl = Context.Rel.Declaration
@@ -77,8 +77,7 @@ let functional_induction with_clean c princl pat =
user_err (str "Cannot find induction principle for "
++ Printer.pr_leconstr_env (Tacmach.pf_env g) sigma (mkConst c') )
in
- let princ = EConstr.of_constr princ in
- (princ,NoBindings,Tacmach.pf_unsafe_type_of g' princ,g')
+ (princ,NoBindings,Tacmach.pf_unsafe_type_of g' princ,g')
| _ -> raise (UserError(None,str "functional induction must be used with a function" ))
end
| Some ((princ,binding)) ->
@@ -99,7 +98,7 @@ let functional_induction with_clean c princl pat =
List.map2
(fun c pat ->
((None,
- Ltac_plugin.Tacexpr.ElimOnConstr (fun env sigma -> (sigma,(c,NoBindings)))),
+ Tactics.ElimOnConstr (fun env sigma -> (sigma,(c,NoBindings)))),
(None,pat),
None))
(args@c_list)
@@ -260,7 +259,6 @@ let derive_inversion fix_names =
let evd,c =
Evd.fresh_global
(Global.env ()) evd (Constrintern.locate_reference (Libnames.qualid_of_ident id)) in
- let c = EConstr.of_constr c in
let (cst, u) = destConst evd c in
evd, (cst, EInstance.kind evd u) :: l
)
@@ -282,8 +280,7 @@ let derive_inversion fix_names =
(Global.env ()) evd
(Constrintern.locate_reference (Libnames.qualid_of_ident (mk_rel_id id)))
in
- let id = EConstr.of_constr id in
- evd,(fst (destInd evd id))::l
+ evd,(fst (destInd evd id))::l
)
fix_names
(evd',[])
@@ -364,17 +361,17 @@ let generate_principle (evd:Evd.evar_map ref) pconstants on_error
(*i The next call to mk_rel_id is valid since we have just construct the graph
Ensures by : do_built
i*)
- let f_R_mut = CAst.make @@ Ident (mk_rel_id (List.nth names 0)) in
+ let f_R_mut = qualid_of_ident @@ mk_rel_id (List.nth names 0) in
let ind_kn =
fst (locate_with_msg
- (pr_reference f_R_mut++str ": Not an inductive type!")
+ (pr_qualid f_R_mut++str ": Not an inductive type!")
locate_ind
f_R_mut)
in
let fname_kn (((fname,_),_,_,_,_),_) =
- let f_ref = CAst.map (fun n -> Ident n) fname in
- locate_with_msg
- (pr_reference f_ref++str ": Not an inductive type!")
+ let f_ref = qualid_of_ident ?loc:fname.CAst.loc fname.CAst.v in
+ locate_with_msg
+ (pr_qualid f_ref++str ": Not an inductive type!")
locate_constant
f_ref
in
@@ -387,7 +384,8 @@ let generate_principle (evd:Evd.evar_map ref) pconstants on_error
let evd = ref (Evd.from_env env) in
let evd',uprinc = Evd.fresh_global env !evd princ in
let _ = evd := evd' in
- let princ_type = Typing.e_type_of ~refresh:true env evd (EConstr.of_constr uprinc) in
+ let sigma, princ_type = Typing.type_of ~refresh:true env !evd uprinc in
+ evd := sigma;
let princ_type = EConstr.Unsafe.to_constr princ_type in
Functional_principles_types.generate_functional_principle
evd
@@ -424,7 +422,6 @@ let register_struct is_rec (fixpoint_exprl:(Vernacexpr.fixpoint_expr * Vernacexp
let evd,c =
Evd.fresh_global
(Global.env ()) evd (Constrintern.locate_reference (Libnames.qualid_of_ident fname)) in
- let c = EConstr.of_constr c in
let (cst, u) = destConst evd c in
let u = EInstance.kind evd u in
evd,((cst, u) :: l)
@@ -441,7 +438,6 @@ let register_struct is_rec (fixpoint_exprl:(Vernacexpr.fixpoint_expr * Vernacexp
let evd,c =
Evd.fresh_global
(Global.env ()) evd (Constrintern.locate_reference (Libnames.qualid_of_ident fname)) in
- let c = EConstr.of_constr c in
let (cst, u) = destConst evd c in
let u = EInstance.kind evd u in
evd,((cst, u) :: l)
@@ -480,7 +476,7 @@ let register_wf ?(is_mes=false) fname rec_impls wf_rel_expr wf_arg using_lemmas
let unbounded_eq =
let f_app_args =
CAst.make @@ Constrexpr.CAppExpl(
- (None,CAst.make @@ Ident fname,None) ,
+ (None,qualid_of_ident fname,None) ,
(List.map
(function
| {CAst.v=Anonymous} -> assert false
@@ -490,7 +486,7 @@ let register_wf ?(is_mes=false) fname rec_impls wf_rel_expr wf_arg using_lemmas
)
)
in
- CAst.make @@ Constrexpr.CApp ((None,Constrexpr_ops.mkRefC (CAst.make @@ Qualid (qualid_of_string "Logic.eq"))),
+ CAst.make @@ Constrexpr.CApp ((None,Constrexpr_ops.mkRefC (qualid_of_string "Logic.eq")),
[(f_app_args,None);(body,None)])
in
let eq = Constrexpr_ops.mkCProdN args unbounded_eq in
@@ -547,9 +543,9 @@ let register_mes fname rec_impls wf_mes_expr wf_rel_expr_opt wf_arg using_lemmas
| None ->
let ltof =
let make_dir l = DirPath.make (List.rev_map Id.of_string l) in
- CAst.make @@ Libnames.Qualid (Libnames.qualid_of_path
- (Libnames.make_path (make_dir ["Arith";"Wf_nat"]) (Id.of_string "ltof")))
- in
+ Libnames.qualid_of_path
+ (Libnames.make_path (make_dir ["Arith";"Wf_nat"]) (Id.of_string "ltof"))
+ in
let fun_from_mes =
let applied_mes =
Constrexpr_ops.mkAppC(wf_mes_expr,[Constrexpr_ops.mkIdentC wf_arg]) in
@@ -730,12 +726,10 @@ let do_generate_principle pconstants on_error register_built interactive_proof
()
let rec add_args id new_args = CAst.map (function
- | CRef (r,_) as b ->
- begin match r with
- | {CAst.v=Libnames.Ident fname} when Id.equal fname id ->
- CAppExpl((None,r,None),new_args)
- | _ -> b
- end
+ | CRef (qid,_) as b ->
+ if qualid_is_ident qid && Id.equal (qualid_basename qid) id then
+ CAppExpl((None,qid,None),new_args)
+ else b
| CFix _ | CCoFix _ -> anomaly ~label:"add_args " (Pp.str "todo.")
| CProdN(nal,b1) ->
CProdN(List.map (function CLocalAssum (nal,k,b2) -> CLocalAssum (nal,k,add_args id new_args b2)
@@ -749,13 +743,10 @@ let rec add_args id new_args = CAst.map (function
add_args id new_args b1)
| CLetIn(na,b1,t,b2) ->
CLetIn(na,add_args id new_args b1,Option.map (add_args id new_args) t,add_args id new_args b2)
- | CAppExpl((pf,r,us),exprl) ->
- begin
- match r with
- | {CAst.v=Libnames.Ident fname} when Id.equal fname id ->
- CAppExpl((pf,r,us),new_args@(List.map (add_args id new_args) exprl))
- | _ -> CAppExpl((pf,r,us),List.map (add_args id new_args) exprl)
- end
+ | CAppExpl((pf,qid,us),exprl) ->
+ if qualid_is_ident qid && Id.equal (qualid_basename qid) id then
+ CAppExpl((pf,qid,us),new_args@(List.map (add_args id new_args) exprl))
+ else CAppExpl((pf,qid,us),List.map (add_args id new_args) exprl)
| CApp((pf,b),bl) ->
CApp((pf,add_args id new_args b),
List.map (fun (e,o) -> add_args id new_args e,o) bl)
@@ -785,7 +776,7 @@ let rec add_args id new_args = CAst.map (function
| CSort _ as b -> b
| CCast(b1,b2) ->
CCast(add_args id new_args b1,
- Miscops.map_cast_type (add_args id new_args) b2)
+ Glob_ops.map_cast_type (add_args id new_args) b2)
| CRecord pars ->
CRecord (List.map (fun (e,o) -> e, add_args id new_args o) pars)
| CNotation _ -> anomaly ~label:"add_args " (Pp.str "CNotation.")
@@ -849,7 +840,7 @@ let rec get_args b t : Constrexpr.local_binder_expr list *
| _ -> [],b,t
-let make_graph (f_ref:global_reference) =
+let make_graph (f_ref : GlobRef.t) =
let c,c_body =
match f_ref with
| ConstRef c ->
@@ -890,7 +881,7 @@ let make_graph (f_ref:global_reference) =
| Constrexpr.CLocalAssum (nal,_,_) ->
List.map
(fun {CAst.loc;v=n} -> CAst.make ?loc @@
- CRef(CAst.make ?loc @@ Libnames.Ident(Nameops.Name.get_id n),None))
+ CRef(Libnames.qualid_of_ident ?loc @@ Nameops.Name.get_id n,None))
nal
| Constrexpr.CLocalPattern _ -> assert false
)
diff --git a/plugins/funind/indfun.mli b/plugins/funind/indfun.mli
index dcc1c2ea..f209fb19 100644
--- a/plugins/funind/indfun.mli
+++ b/plugins/funind/indfun.mli
@@ -1,4 +1,5 @@
-open Misctypes
+open Names
+open Tactypes
val warn_cannot_define_graph : ?loc:Loc.t -> Pp.t * Pp.t -> unit
@@ -18,4 +19,4 @@ val functional_induction :
Goal.goal Evd.sigma -> Goal.goal list Evd.sigma
-val make_graph : Globnames.global_reference -> unit
+val make_graph : GlobRef.t -> unit
diff --git a/plugins/funind/indfun_common.ml b/plugins/funind/indfun_common.ml
index a0b9217c..4eee2c7a 100644
--- a/plugins/funind/indfun_common.ml
+++ b/plugins/funind/indfun_common.ml
@@ -31,9 +31,7 @@ let id_of_name = function
Name id -> id
| _ -> raise Not_found
-let locate ref =
- let {CAst.v=qid} = qualid_of_reference ref in
- Nametab.locate qid
+let locate qid = Nametab.locate qid
let locate_ind ref =
match locate ref with
@@ -109,7 +107,7 @@ let const_of_id id =
let def_of_const t =
match Constr.kind t with
- Term.Const sp ->
+ Const sp ->
(try (match Environ.constant_opt_value_in (Global.env()) sp with
| Some c -> c
| _ -> assert false)
@@ -117,7 +115,7 @@ let def_of_const t =
|_ -> assert false
let coq_constant s =
- Universes.constr_of_global @@
+ UnivGen.constr_of_global @@
Coqlib.gen_reference_in_modules "RecursiveDefinition"
Coqlib.init_modules s;;
@@ -269,12 +267,12 @@ let subst_Function (subst,finfos) =
in
let function_constant' = do_subst_con finfos.function_constant in
let graph_ind' = do_subst_ind finfos.graph_ind in
- let equation_lemma' = Option.smartmap do_subst_con finfos.equation_lemma in
- let correctness_lemma' = Option.smartmap do_subst_con finfos.correctness_lemma in
- let completeness_lemma' = Option.smartmap do_subst_con finfos.completeness_lemma in
- let rect_lemma' = Option.smartmap do_subst_con finfos.rect_lemma in
- let rec_lemma' = Option.smartmap do_subst_con finfos.rec_lemma in
- let prop_lemma' = Option.smartmap do_subst_con finfos.prop_lemma in
+ let equation_lemma' = Option.Smart.map do_subst_con finfos.equation_lemma in
+ let correctness_lemma' = Option.Smart.map do_subst_con finfos.correctness_lemma in
+ let completeness_lemma' = Option.Smart.map do_subst_con finfos.completeness_lemma in
+ let rect_lemma' = Option.Smart.map do_subst_con finfos.rect_lemma in
+ let rec_lemma' = Option.Smart.map do_subst_con finfos.rec_lemma in
+ let prop_lemma' = Option.Smart.map do_subst_con finfos.prop_lemma in
if function_constant' == finfos.function_constant &&
graph_ind' == finfos.graph_ind &&
equation_lemma' == finfos.equation_lemma &&
@@ -302,12 +300,12 @@ let classify_Function infos = Libobject.Substitute infos
let discharge_Function (_,finfos) =
let function_constant' = Lib.discharge_con finfos.function_constant
and graph_ind' = Lib.discharge_inductive finfos.graph_ind
- and equation_lemma' = Option.smartmap Lib.discharge_con finfos.equation_lemma
- and correctness_lemma' = Option.smartmap Lib.discharge_con finfos.correctness_lemma
- and completeness_lemma' = Option.smartmap Lib.discharge_con finfos.completeness_lemma
- and rect_lemma' = Option.smartmap Lib.discharge_con finfos.rect_lemma
- and rec_lemma' = Option.smartmap Lib.discharge_con finfos.rec_lemma
- and prop_lemma' = Option.smartmap Lib.discharge_con finfos.prop_lemma
+ and equation_lemma' = Option.Smart.map Lib.discharge_con finfos.equation_lemma
+ and correctness_lemma' = Option.Smart.map Lib.discharge_con finfos.correctness_lemma
+ and completeness_lemma' = Option.Smart.map Lib.discharge_con finfos.completeness_lemma
+ and rect_lemma' = Option.Smart.map Lib.discharge_con finfos.rect_lemma
+ and rec_lemma' = Option.Smart.map Lib.discharge_con finfos.rec_lemma
+ and prop_lemma' = Option.Smart.map Lib.discharge_con finfos.prop_lemma
in
if function_constant' == finfos.function_constant &&
graph_ind' == finfos.graph_ind &&
@@ -471,7 +469,7 @@ let jmeq () =
try
Coqlib.check_required_library Coqlib.jmeq_module_name;
EConstr.of_constr @@
- Universes.constr_of_global @@
+ UnivGen.constr_of_global @@
Coqlib.coq_reference "Function" ["Logic";"JMeq"] "JMeq"
with e when CErrors.noncritical e -> raise (ToShow e)
@@ -479,7 +477,7 @@ let jmeq_refl () =
try
Coqlib.check_required_library Coqlib.jmeq_module_name;
EConstr.of_constr @@
- Universes.constr_of_global @@
+ UnivGen.constr_of_global @@
Coqlib.coq_reference "Function" ["Logic";"JMeq"] "JMeq_refl"
with e when CErrors.noncritical e -> raise (ToShow e)
@@ -492,7 +490,7 @@ let well_founded = function () -> EConstr.of_constr (coq_constant "well_founded"
let acc_rel = function () -> EConstr.of_constr (coq_constant "Acc")
let acc_inv_id = function () -> EConstr.of_constr (coq_constant "Acc_inv")
-let well_founded_ltof () = EConstr.of_constr @@ Universes.constr_of_global @@
+let well_founded_ltof () = EConstr.of_constr @@ UnivGen.constr_of_global @@
Coqlib.coq_reference "" ["Arith";"Wf_nat"] "well_founded_ltof"
let ltof_ref = function () -> (find_reference ["Coq";"Arith";"Wf_nat"] "ltof")
diff --git a/plugins/funind/indfun_common.mli b/plugins/funind/indfun_common.mli
index 5cc7163a..7e52ee22 100644
--- a/plugins/funind/indfun_common.mli
+++ b/plugins/funind/indfun_common.mli
@@ -20,11 +20,11 @@ val array_get_start : 'a array -> 'a array
val id_of_name : Name.t -> Id.t
-val locate_ind : Libnames.reference -> inductive
-val locate_constant : Libnames.reference -> Constant.t
+val locate_ind : Libnames.qualid -> inductive
+val locate_constant : Libnames.qualid -> Constant.t
val locate_with_msg :
- Pp.t -> (Libnames.reference -> 'a) ->
- Libnames.reference -> 'a
+ Pp.t -> (Libnames.qualid -> 'a) ->
+ Libnames.qualid -> 'a
val filter_map : ('a -> bool) -> ('a -> 'b) -> 'a list -> 'b list
val list_union_eq :
@@ -41,7 +41,7 @@ val chop_rprod_n : int -> Glob_term.glob_constr ->
val def_of_const : Constr.t -> Constr.t
val eq : EConstr.constr Lazy.t
val refl_equal : EConstr.constr Lazy.t
-val const_of_id: Id.t -> Globnames.global_reference(* constantyes *)
+val const_of_id: Id.t -> GlobRef.t(* constantyes *)
val jmeq : unit -> EConstr.constr
val jmeq_refl : unit -> EConstr.constr
@@ -107,11 +107,11 @@ val h_intros: Names.Id.t list -> Tacmach.tactic
val h_id : Names.Id.t
val hrec_id : Names.Id.t
val acc_inv_id : EConstr.constr Util.delayed
-val ltof_ref : Globnames.global_reference Util.delayed
+val ltof_ref : GlobRef.t Util.delayed
val well_founded_ltof : EConstr.constr Util.delayed
val acc_rel : EConstr.constr Util.delayed
val well_founded : EConstr.constr Util.delayed
-val evaluable_of_global_reference : Globnames.global_reference -> Names.evaluable_global_reference
+val evaluable_of_global_reference : GlobRef.t -> Names.evaluable_global_reference
val list_rewrite : bool -> (EConstr.constr*bool) list -> Tacmach.tactic
val decompose_lam_n : Evd.evar_map -> int -> EConstr.t ->
diff --git a/plugins/funind/invfun.ml b/plugins/funind/invfun.ml
index bed95740..ad11f853 100644
--- a/plugins/funind/invfun.ml
+++ b/plugins/funind/invfun.ml
@@ -23,7 +23,7 @@ open Tacticals
open Tactics
open Indfun_common
open Tacmach
-open Misctypes
+open Tactypes
open Termops
open Context.Rel.Declaration
@@ -67,7 +67,7 @@ let observe_tac s tac g =
let nf_zeta =
Reductionops.clos_norm_flags (CClosure.RedFlags.mkflags [CClosure.RedFlags.fZETA])
Environ.empty_env
- Evd.empty
+ (Evd.from_env Environ.empty_env)
let thin ids gl = Proofview.V82.of_tactic (Tactics.clear ids) gl
@@ -81,7 +81,7 @@ let thin ids gl = Proofview.V82.of_tactic (Tactics.clear ids) gl
let make_eq () =
try
- EConstr.of_constr (Universes.constr_of_global (Coqlib.build_coq_eq ()))
+ EConstr.of_constr (UnivGen.constr_of_global (Coqlib.build_coq_eq ()))
with _ -> assert false
@@ -102,9 +102,9 @@ let generate_type evd g_to_f f graph i =
let evd',graph =
Evd.fresh_global (Global.env ()) !evd (Globnames.IndRef (fst (destInd !evd graph)))
in
- let graph = EConstr.of_constr graph in
evd:=evd';
- let graph_arity = Typing.e_type_of (Global.env ()) evd graph in
+ let sigma, graph_arity = Typing.type_of (Global.env ()) !evd graph in
+ evd := sigma;
let ctxt,_ = decompose_prod_assum !evd graph_arity in
let fun_ctxt,res_type =
match ctxt with
@@ -172,7 +172,6 @@ let find_induction_principle evd f =
| None -> raise Not_found
| Some rect_lemma ->
let evd',rect_lemma = Evd.fresh_global (Global.env ()) !evd (Globnames.ConstRef rect_lemma) in
- let rect_lemma = EConstr.of_constr rect_lemma in
let evd',typ = Typing.type_of ~refresh:true (Global.env ()) evd' rect_lemma in
evd:=evd';
rect_lemma,typ
@@ -240,7 +239,7 @@ let prove_fun_correct evd funs_constr graphs_constr schemes lemmas_types_infos i
List.map
(fun decl ->
List.map
- (fun id -> CAst.make @@ IntroNaming (IntroIdentifier id))
+ (fun id -> CAst.make @@ IntroNaming (Namegen.IntroIdentifier id))
(generate_fresh_id (Id.of_string "y") ids (List.length (fst (decompose_prod_assum evd (RelDecl.get_type decl)))))
)
branches
@@ -258,7 +257,7 @@ let prove_fun_correct evd funs_constr graphs_constr schemes lemmas_types_infos i
List.fold_right
(fun {CAst.v=pat} acc ->
match pat with
- | IntroNaming (IntroIdentifier id) -> id::acc
+ | IntroNaming (Namegen.IntroIdentifier id) -> id::acc
| _ -> anomaly (Pp.str "Not an identifier.")
)
(List.nth intro_pats (pred i))
@@ -513,7 +512,7 @@ and intros_with_rewrite_aux : Tacmach.tactic =
intros_with_rewrite
] g
end
- | Ind _ when EConstr.eq_constr sigma t (EConstr.of_constr (Universes.constr_of_global @@ Coqlib.build_coq_False ())) ->
+ | Ind _ when EConstr.eq_constr sigma t (EConstr.of_constr (UnivGen.constr_of_global @@ Coqlib.build_coq_False ())) ->
Proofview.V82.of_tactic tauto g
| Case(_,_,v,_) ->
tclTHENLIST[
@@ -771,7 +770,8 @@ let derive_correctness make_scheme (funs: pconstant list) (graphs:inductive list
let type_info = (type_of_lemma_ctxt,type_of_lemma_concl) in
graphs_constr.(i) <- graph;
let type_of_lemma = EConstr.it_mkProd_or_LetIn type_of_lemma_concl type_of_lemma_ctxt in
- let _ = Typing.e_type_of (Global.env ()) evd type_of_lemma in
+ let sigma, _ = Typing.type_of (Global.env ()) !evd type_of_lemma in
+ evd := sigma;
let type_of_lemma = nf_zeta type_of_lemma in
observe (str "type_of_lemma := " ++ Printer.pr_leconstr_env (Global.env ()) !evd type_of_lemma);
type_of_lemma,type_info
@@ -818,13 +818,12 @@ let derive_correctness make_scheme (funs: pconstant list) (graphs:inductive list
ignore (Pfedit.by
(Proofview.V82.tactic (observe_tac ("prove correctness ("^(Id.to_string f_id)^")")
(proving_tac i))));
- (Lemmas.save_proof (Vernacexpr.(Proved(Transparent,None))));
+ (Lemmas.save_proof (Vernacexpr.(Proved(Proof_global.Transparent,None))));
let finfo = find_Function_infos (fst f_as_constant) in
(* let lem_cst = fst (destConst (Constrintern.global_reference lem_id)) in *)
let _,lem_cst_constr = Evd.fresh_global
(Global.env ()) !evd (Constrintern.locate_reference (Libnames.qualid_of_ident lem_id)) in
- let lem_cst_constr = EConstr.of_constr lem_cst_constr in
- let (lem_cst,_) = destConst !evd lem_cst_constr in
+ let (lem_cst,_) = destConst !evd lem_cst_constr in
update_Function {finfo with correctness_lemma = Some lem_cst};
)
@@ -880,12 +879,11 @@ let derive_correctness make_scheme (funs: pconstant list) (graphs:inductive list
ignore (Pfedit.by
(Proofview.V82.tactic (observe_tac ("prove completeness ("^(Id.to_string f_id)^")")
(proving_tac i)))) ;
- (Lemmas.save_proof (Vernacexpr.(Proved(Transparent,None))));
+ (Lemmas.save_proof (Vernacexpr.(Proved(Proof_global.Transparent,None))));
let finfo = find_Function_infos (fst f_as_constant) in
let _,lem_cst_constr = Evd.fresh_global
(Global.env ()) !evd (Constrintern.locate_reference (Libnames.qualid_of_ident lem_id)) in
- let lem_cst_constr = EConstr.of_constr lem_cst_constr in
- let (lem_cst,_) = destConst !evd lem_cst_constr in
+ let (lem_cst,_) = destConst !evd lem_cst_constr in
update_Function {finfo with completeness_lemma = Some lem_cst}
)
funs)
@@ -969,7 +967,7 @@ let functional_inversion kn hid fconst f_correct : Tacmach.tactic =
Proofview.V82.of_tactic (generalize [applist(f_correct,(Array.to_list f_args)@[res;mkVar hid])]);
thin [hid];
Proofview.V82.of_tactic (Simple.intro hid);
- Proofview.V82.of_tactic (Inv.inv FullInversion None (NamedHyp hid));
+ Proofview.V82.of_tactic (Inv.inv Inv.FullInversion None (NamedHyp hid));
(fun g ->
let new_ids = List.filter (fun id -> not (Id.Set.mem id old_ids)) (pf_ids_of_hyps g) in
tclMAP (revert_graph kn pre_tac) (hid::new_ids) g
diff --git a/plugins/funind/invfun.mli b/plugins/funind/invfun.mli
index ad306ab2..3ddc6092 100644
--- a/plugins/funind/invfun.mli
+++ b/plugins/funind/invfun.mli
@@ -9,8 +9,8 @@
(************************************************************************)
val invfun :
- Misctypes.quantified_hypothesis ->
- Globnames.global_reference option ->
+ Tactypes.quantified_hypothesis ->
+ Names.GlobRef.t option ->
Evar.t Evd.sigma -> Evar.t list Evd.sigma
val derive_correctness :
(Evd.evar_map ref ->
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index fb9ae64b..e9e8fcb6 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -37,7 +37,7 @@ open Glob_term
open Pretyping
open Termops
open Constrintern
-open Misctypes
+open Tactypes
open Genredexpr
open Equality
@@ -49,7 +49,7 @@ open Context.Rel.Declaration
(* Ugly things which should not be here *)
-let coq_constant m s = EConstr.of_constr @@ Universes.constr_of_global @@
+let coq_constant m s = EConstr.of_constr @@ UnivGen.constr_of_global @@
Coqlib.coq_reference "RecursiveDefinition" m s
let arith_Nat = ["Arith";"PeanoNat";"Nat"]
@@ -61,7 +61,7 @@ let pr_leconstr_rd =
let coq_init_constant s =
EConstr.of_constr (
- Universes.constr_of_global @@
+ UnivGen.constr_of_global @@
Coqlib.gen_reference_in_modules "RecursiveDefinition" Coqlib.init_modules s)
let find_reference sl s =
@@ -72,7 +72,7 @@ let declare_fun f_id kind ?univs value =
let ce = definition_entry ?univs value (*FIXME *) in
ConstRef(declare_constant f_id (DefinitionEntry ce, kind));;
-let defined () = Lemmas.save_proof (Vernacexpr.(Proved (Transparent,None)))
+let defined () = Lemmas.save_proof (Vernacexpr.(Proved (Proof_global.Transparent,None)))
let def_of_const t =
match (Constr.kind t) with
@@ -106,12 +106,12 @@ let const_of_ref = function
let nf_zeta env =
Reductionops.clos_norm_flags (CClosure.RedFlags.mkflags [CClosure.RedFlags.fZETA])
- env
- Evd.empty
+ env (Evd.from_env env)
let nf_betaiotazeta = (* Reductionops.local_strong Reductionops.whd_betaiotazeta *)
- Reductionops.clos_norm_flags CClosure.betaiotazeta Environ.empty_env Evd.empty
+ Reductionops.clos_norm_flags CClosure.betaiotazeta Environ.empty_env
+ (Evd.from_env Environ.empty_env)
@@ -181,7 +181,7 @@ let simpl_iter clause =
clause
(* Others ugly things ... *)
-let (value_f: Constr.t list -> global_reference -> Constr.t) =
+let (value_f: Constr.t list -> GlobRef.t -> Constr.t) =
let open Term in
let open Constr in
fun al fterm ->
@@ -215,7 +215,7 @@ let (value_f: Constr.t list -> global_reference -> Constr.t) =
let body = EConstr.Unsafe.to_constr body in
it_mkLambda_or_LetIn body context
-let (declare_f : Id.t -> logical_kind -> Constr.t list -> global_reference -> global_reference) =
+let (declare_f : Id.t -> logical_kind -> Constr.t list -> GlobRef.t -> GlobRef.t) =
fun f_id kind input_type fterm_ref ->
declare_fun f_id kind (value_f input_type fterm_ref);;
@@ -356,7 +356,7 @@ type 'a infos =
f_id : Id.t; (* function name *)
f_constr : constr; (* function term *)
f_terminate : constr; (* termination proof term *)
- func : global_reference; (* functional reference *)
+ func : GlobRef.t; (* functional reference *)
info : 'a;
is_main_branch : bool; (* on the main branch or on a matched expression *)
is_final : bool; (* final first order term or not *)
@@ -713,7 +713,7 @@ let mkDestructEq :
observe_tclTHENLIST (str "mkDestructEq")
[Proofview.V82.of_tactic (generalize new_hyps);
(fun g2 ->
- let changefun patvars sigma =
+ let changefun patvars env sigma =
pattern_occs [Locus.AllOccurrencesBut [1], expr] (pf_env g2) sigma (pf_concl g2)
in
Proofview.V82.of_tactic (change_in_concl None changefun) g2);
@@ -1152,7 +1152,7 @@ let termination_proof_header is_mes input_type ids args_id relation
tclTHEN (Proofview.V82.of_tactic (Tactics.generalize [mkVar id])) (Proofview.V82.of_tactic (clear [id])))
))
;
- observe_tac (str "fix") (Proofview.V82.of_tactic (fix (Some hrec) (nargs+1)));
+ observe_tac (str "fix") (Proofview.V82.of_tactic (fix hrec (nargs+1)));
h_intros args_id;
Proofview.V82.of_tactic (Simple.intro wf_rec_arg);
observe_tac (str "tac") (tac wf_rec_arg hrec wf_rec_arg acc_inv)
@@ -1241,7 +1241,7 @@ let get_current_subgoals_types () =
exception EmptySubgoals
let build_and_l sigma l =
- let and_constr = Universes.constr_of_global @@ Coqlib.build_coq_and () in
+ let and_constr = UnivGen.constr_of_global @@ Coqlib.build_coq_and () in
let conj_constr = coq_conj () in
let mk_and p1 p2 =
mkApp(EConstr.of_constr and_constr,[|p1;p2|]) in
@@ -1306,9 +1306,9 @@ let build_new_goal_type () =
let is_opaque_constant c =
let cb = Global.lookup_constant c in
match cb.Declarations.const_body with
- | Declarations.OpaqueDef _ -> Vernacexpr.Opaque
- | Declarations.Undef _ -> Vernacexpr.Opaque
- | Declarations.Def _ -> Vernacexpr.Transparent
+ | Declarations.OpaqueDef _ -> Proof_global.Opaque
+ | Declarations.Undef _ -> Proof_global.Opaque
+ | Declarations.Def _ -> Proof_global.Transparent
let open_new_goal build_proof sigma using_lemmas ref_ goal_name (gls_type,decompose_and_tac,nb_goal) =
(* Pp.msgnl (str "gls_type := " ++ Printer.pr_lconstr gls_type); *)
@@ -1318,14 +1318,14 @@ let open_new_goal build_proof sigma using_lemmas ref_ goal_name (gls_type,decomp
| None ->
try add_suffix current_proof_name "_subproof"
with e when CErrors.noncritical e ->
- anomaly (Pp.str "open_new_goal with an unamed theorem.")
+ anomaly (Pp.str "open_new_goal with an unnamed theorem.")
in
let na = next_global_ident_away name Id.Set.empty in
if Termops.occur_existential sigma gls_type then
CErrors.user_err Pp.(str "\"abstract\" cannot handle existentials");
let hook _ _ =
let opacity =
- let na_ref = CAst.make @@ Libnames.Ident na in
+ let na_ref = qualid_of_ident na in
let na_global = Smartlocate.global_with_alias na_ref in
match na_global with
ConstRef c -> is_opaque_constant c
@@ -1456,7 +1456,7 @@ let com_terminate
-let start_equation (f:global_reference) (term_f:global_reference)
+let start_equation (f:GlobRef.t) (term_f:GlobRef.t)
(cont_tactic:Id.t list -> tactic) g =
let sigma = project g in
let ids = pf_ids_of_hyps g in
@@ -1473,7 +1473,7 @@ let start_equation (f:global_reference) (term_f:global_reference)
observe_tac (str "prove_eq") (cont_tactic x)]) g;;
let (com_eqn : int -> Id.t ->
- global_reference -> global_reference -> global_reference
+ GlobRef.t -> GlobRef.t -> GlobRef.t
-> Constr.t -> unit) =
fun nb_arg eq_name functional_ref f_ref terminate_ref equation_lemma_type ->
let open CVars in
@@ -1533,14 +1533,12 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
let env = Global.env() in
let evd = Evd.from_env env in
let evd, function_type = interp_type_evars env evd type_of_f in
- let function_type = EConstr.Unsafe.to_constr function_type in
- let env = push_named (Context.Named.Declaration.LocalAssum (function_name,function_type)) env in
+ let env = EConstr.push_named (Context.Named.Declaration.LocalAssum (function_name,function_type)) env in
(* Pp.msgnl (str "function type := " ++ Printer.pr_lconstr function_type); *)
let evd, ty = interp_type_evars env evd ~impls:rec_impls eq in
- let ty = EConstr.Unsafe.to_constr ty in
- let evd, nf = Evarutil.nf_evars_and_universes evd in
- let equation_lemma_type = nf_betaiotazeta (EConstr.of_constr (nf ty)) in
- let function_type = nf function_type in
+ let evd = Evd.minimize_universes evd in
+ let equation_lemma_type = nf_betaiotazeta (Evarutil.nf_evar evd ty) in
+ let function_type = EConstr.to_constr ~abort_on_undefined_evars:false evd function_type in
let equation_lemma_type = EConstr.Unsafe.to_constr equation_lemma_type in
(* Pp.msgnl (str "lemma type := " ++ Printer.pr_lconstr equation_lemma_type ++ fnl ()); *)
let res_vars,eq' = decompose_prod equation_lemma_type in
@@ -1579,7 +1577,7 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
let hook _ _ =
let term_ref = Nametab.locate (qualid_of_ident term_id) in
let f_ref = declare_f function_name (IsProof Lemma) arg_types term_ref in
- let _ = Extraction_plugin.Table.extraction_inline true [CAst.make @@ Ident term_id] in
+ let _ = Extraction_plugin.Table.extraction_inline true [qualid_of_ident term_id] in
(* message "start second proof"; *)
let stop =
try com_eqn (List.length res_vars) equation_id functional_ref f_ref term_ref (subst_var function_name equation_lemma_type);
diff --git a/plugins/funind/recdef.mli b/plugins/funind/recdef.mli
index b95d64ce..549f1fc0 100644
--- a/plugins/funind/recdef.mli
+++ b/plugins/funind/recdef.mli
@@ -14,6 +14,6 @@ bool ->
int -> Constrexpr.constr_expr -> (pconstant ->
Indfun_common.tcc_lemma_value ref ->
pconstant ->
- pconstant -> int -> EConstr.types -> int -> EConstr.constr -> 'a) -> Constrexpr.constr_expr list -> unit
+ pconstant -> int -> EConstr.types -> int -> EConstr.constr -> unit) -> Constrexpr.constr_expr list -> unit
diff --git a/plugins/ltac/coretactics.ml4 b/plugins/ltac/coretactics.mlg
index 931633e1..6388906f 100644
--- a/plugins/ltac/coretactics.ml4
+++ b/plugins/ltac/coretactics.mlg
@@ -8,155 +8,165 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Util
open Locus
-open Misctypes
+open Tactypes
open Genredexpr
open Stdarg
open Extraargs
+open Tacarg
open Names
+open Logic
+
+let wit_hyp = wit_var
+
+}
DECLARE PLUGIN "ltac_plugin"
(** Basic tactics *)
TACTIC EXTEND reflexivity
- [ "reflexivity" ] -> [ Tactics.intros_reflexivity ]
+| [ "reflexivity" ] -> { Tactics.intros_reflexivity }
END
TACTIC EXTEND exact
- [ "exact" casted_constr(c) ] -> [ Tactics.exact_no_check c ]
+| [ "exact" casted_constr(c) ] -> { Tactics.exact_no_check c }
END
TACTIC EXTEND assumption
- [ "assumption" ] -> [ Tactics.assumption ]
+| [ "assumption" ] -> { Tactics.assumption }
END
TACTIC EXTEND etransitivity
- [ "etransitivity" ] -> [ Tactics.intros_transitivity None ]
+| [ "etransitivity" ] -> { Tactics.intros_transitivity None }
END
TACTIC EXTEND cut
- [ "cut" constr(c) ] -> [ Tactics.cut c ]
+| [ "cut" constr(c) ] -> { Tactics.cut c }
END
TACTIC EXTEND exact_no_check
- [ "exact_no_check" constr(c) ] -> [ Tactics.exact_no_check c ]
+| [ "exact_no_check" constr(c) ] -> { Tactics.exact_no_check c }
END
TACTIC EXTEND vm_cast_no_check
- [ "vm_cast_no_check" constr(c) ] -> [ Tactics.vm_cast_no_check c ]
+| [ "vm_cast_no_check" constr(c) ] -> { Tactics.vm_cast_no_check c }
END
TACTIC EXTEND native_cast_no_check
- [ "native_cast_no_check" constr(c) ] -> [ Tactics.native_cast_no_check c ]
+| [ "native_cast_no_check" constr(c) ] -> { Tactics.native_cast_no_check c }
END
TACTIC EXTEND casetype
- [ "casetype" constr(c) ] -> [ Tactics.case_type c ]
+| [ "casetype" constr(c) ] -> { Tactics.case_type c }
END
TACTIC EXTEND elimtype
- [ "elimtype" constr(c) ] -> [ Tactics.elim_type c ]
+| [ "elimtype" constr(c) ] -> { Tactics.elim_type c }
END
TACTIC EXTEND lapply
- [ "lapply" constr(c) ] -> [ Tactics.cut_and_apply c ]
+| [ "lapply" constr(c) ] -> { Tactics.cut_and_apply c }
END
TACTIC EXTEND transitivity
- [ "transitivity" constr(c) ] -> [ Tactics.intros_transitivity (Some c) ]
+| [ "transitivity" constr(c) ] -> { Tactics.intros_transitivity (Some c) }
END
(** Left *)
TACTIC EXTEND left
- [ "left" ] -> [ Tactics.left_with_bindings false NoBindings ]
+| [ "left" ] -> { Tactics.left_with_bindings false NoBindings }
END
TACTIC EXTEND eleft
- [ "eleft" ] -> [ Tactics.left_with_bindings true NoBindings ]
+| [ "eleft" ] -> { Tactics.left_with_bindings true NoBindings }
END
TACTIC EXTEND left_with
- [ "left" "with" bindings(bl) ] -> [
+| [ "left" "with" bindings(bl) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES false bl (fun bl -> Tactics.left_with_bindings false bl)
- ]
+ }
END
TACTIC EXTEND eleft_with
- [ "eleft" "with" bindings(bl) ] -> [
+| [ "eleft" "with" bindings(bl) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES true bl (fun bl -> Tactics.left_with_bindings true bl)
- ]
+ }
END
(** Right *)
TACTIC EXTEND right
- [ "right" ] -> [ Tactics.right_with_bindings false NoBindings ]
+| [ "right" ] -> { Tactics.right_with_bindings false NoBindings }
END
TACTIC EXTEND eright
- [ "eright" ] -> [ Tactics.right_with_bindings true NoBindings ]
+| [ "eright" ] -> { Tactics.right_with_bindings true NoBindings }
END
TACTIC EXTEND right_with
- [ "right" "with" bindings(bl) ] -> [
+| [ "right" "with" bindings(bl) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES false bl (fun bl -> Tactics.right_with_bindings false bl)
- ]
+ }
END
TACTIC EXTEND eright_with
- [ "eright" "with" bindings(bl) ] -> [
+| [ "eright" "with" bindings(bl) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES true bl (fun bl -> Tactics.right_with_bindings true bl)
- ]
+ }
END
(** Constructor *)
TACTIC EXTEND constructor
- [ "constructor" ] -> [ Tactics.any_constructor false None ]
-| [ "constructor" int_or_var(i) ] -> [
+| [ "constructor" ] -> { Tactics.any_constructor false None }
+| [ "constructor" int_or_var(i) ] -> {
Tactics.constructor_tac false None i NoBindings
- ]
-| [ "constructor" int_or_var(i) "with" bindings(bl) ] -> [
+ }
+| [ "constructor" int_or_var(i) "with" bindings(bl) ] -> {
let tac bl = Tactics.constructor_tac false None i bl in
Tacticals.New.tclDELAYEDWITHHOLES false bl tac
- ]
+ }
END
TACTIC EXTEND econstructor
- [ "econstructor" ] -> [ Tactics.any_constructor true None ]
-| [ "econstructor" int_or_var(i) ] -> [
+| [ "econstructor" ] -> { Tactics.any_constructor true None }
+| [ "econstructor" int_or_var(i) ] -> {
Tactics.constructor_tac true None i NoBindings
- ]
-| [ "econstructor" int_or_var(i) "with" bindings(bl) ] -> [
+ }
+| [ "econstructor" int_or_var(i) "with" bindings(bl) ] -> {
let tac bl = Tactics.constructor_tac true None i bl in
Tacticals.New.tclDELAYEDWITHHOLES true bl tac
- ]
+ }
END
(** Specialize *)
TACTIC EXTEND specialize
- [ "specialize" constr_with_bindings(c) ] -> [
+| [ "specialize" constr_with_bindings(c) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES false c (fun c -> Tactics.specialize c None)
- ]
-| [ "specialize" constr_with_bindings(c) "as" intropattern(ipat) ] -> [
+ }
+| [ "specialize" constr_with_bindings(c) "as" intropattern(ipat) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES false c (fun c -> Tactics.specialize c (Some ipat))
- ]
+ }
END
TACTIC EXTEND symmetry
- [ "symmetry" ] -> [ Tactics.intros_symmetry {onhyps=Some[];concl_occs=AllOccurrences} ]
+| [ "symmetry" ] -> { Tactics.intros_symmetry {onhyps=Some[];concl_occs=AllOccurrences} }
END
TACTIC EXTEND symmetry_in
-| [ "symmetry" "in" in_clause(cl) ] -> [ Tactics.intros_symmetry cl ]
+| [ "symmetry" "in" in_clause(cl) ] -> { Tactics.intros_symmetry cl }
END
(** Split *)
+{
+
let rec delayed_list = function
| [] -> fun _ sigma -> (sigma, [])
| x :: l ->
@@ -165,149 +175,159 @@ let rec delayed_list = function
let (sigma, l) = delayed_list l env sigma in
(sigma, x :: l)
+}
+
TACTIC EXTEND split
- [ "split" ] -> [ Tactics.split_with_bindings false [NoBindings] ]
+| [ "split" ] -> { Tactics.split_with_bindings false [NoBindings] }
END
TACTIC EXTEND esplit
- [ "esplit" ] -> [ Tactics.split_with_bindings true [NoBindings] ]
+| [ "esplit" ] -> { Tactics.split_with_bindings true [NoBindings] }
END
TACTIC EXTEND split_with
- [ "split" "with" bindings(bl) ] -> [
+| [ "split" "with" bindings(bl) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES false bl (fun bl -> Tactics.split_with_bindings false [bl])
- ]
+ }
END
TACTIC EXTEND esplit_with
- [ "esplit" "with" bindings(bl) ] -> [
+| [ "esplit" "with" bindings(bl) ] -> {
Tacticals.New.tclDELAYEDWITHHOLES true bl (fun bl -> Tactics.split_with_bindings true [bl])
- ]
+ }
END
TACTIC EXTEND exists
- [ "exists" ] -> [ Tactics.split_with_bindings false [NoBindings] ]
-| [ "exists" ne_bindings_list_sep(bll, ",") ] -> [
+| [ "exists" ] -> { Tactics.split_with_bindings false [NoBindings] }
+| [ "exists" ne_bindings_list_sep(bll, ",") ] -> {
Tacticals.New.tclDELAYEDWITHHOLES false (delayed_list bll) (fun bll -> Tactics.split_with_bindings false bll)
- ]
+ }
END
TACTIC EXTEND eexists
- [ "eexists" ] -> [ Tactics.split_with_bindings true [NoBindings] ]
-| [ "eexists" ne_bindings_list_sep(bll, ",") ] -> [
+| [ "eexists" ] -> { Tactics.split_with_bindings true [NoBindings] }
+| [ "eexists" ne_bindings_list_sep(bll, ",") ] -> {
Tacticals.New.tclDELAYEDWITHHOLES true (delayed_list bll) (fun bll -> Tactics.split_with_bindings true bll)
- ]
+ }
END
(** Intro *)
TACTIC EXTEND intros_until
- [ "intros" "until" quantified_hypothesis(h) ] -> [ Tactics.intros_until h ]
+| [ "intros" "until" quantified_hypothesis(h) ] -> { Tactics.intros_until h }
END
TACTIC EXTEND intro
-| [ "intro" ] -> [ Tactics.intro_move None MoveLast ]
-| [ "intro" ident(id) ] -> [ Tactics.intro_move (Some id) MoveLast ]
-| [ "intro" ident(id) "at" "top" ] -> [ Tactics.intro_move (Some id) MoveFirst ]
-| [ "intro" ident(id) "at" "bottom" ] -> [ Tactics.intro_move (Some id) MoveLast ]
-| [ "intro" ident(id) "after" hyp(h) ] -> [ Tactics.intro_move (Some id) (MoveAfter h) ]
-| [ "intro" ident(id) "before" hyp(h) ] -> [ Tactics.intro_move (Some id) (MoveBefore h) ]
-| [ "intro" "at" "top" ] -> [ Tactics.intro_move None MoveFirst ]
-| [ "intro" "at" "bottom" ] -> [ Tactics.intro_move None MoveLast ]
-| [ "intro" "after" hyp(h) ] -> [ Tactics.intro_move None (MoveAfter h) ]
-| [ "intro" "before" hyp(h) ] -> [ Tactics.intro_move None (MoveBefore h) ]
+| [ "intro" ] -> { Tactics.intro_move None MoveLast }
+| [ "intro" ident(id) ] -> { Tactics.intro_move (Some id) MoveLast }
+| [ "intro" ident(id) "at" "top" ] -> { Tactics.intro_move (Some id) MoveFirst }
+| [ "intro" ident(id) "at" "bottom" ] -> { Tactics.intro_move (Some id) MoveLast }
+| [ "intro" ident(id) "after" hyp(h) ] -> { Tactics.intro_move (Some id) (MoveAfter h) }
+| [ "intro" ident(id) "before" hyp(h) ] -> { Tactics.intro_move (Some id) (MoveBefore h) }
+| [ "intro" "at" "top" ] -> { Tactics.intro_move None MoveFirst }
+| [ "intro" "at" "bottom" ] -> { Tactics.intro_move None MoveLast }
+| [ "intro" "after" hyp(h) ] -> { Tactics.intro_move None (MoveAfter h) }
+| [ "intro" "before" hyp(h) ] -> { Tactics.intro_move None (MoveBefore h) }
END
(** Move *)
TACTIC EXTEND move
- [ "move" hyp(id) "at" "top" ] -> [ Tactics.move_hyp id MoveFirst ]
-| [ "move" hyp(id) "at" "bottom" ] -> [ Tactics.move_hyp id MoveLast ]
-| [ "move" hyp(id) "after" hyp(h) ] -> [ Tactics.move_hyp id (MoveAfter h) ]
-| [ "move" hyp(id) "before" hyp(h) ] -> [ Tactics.move_hyp id (MoveBefore h) ]
+| [ "move" hyp(id) "at" "top" ] -> { Tactics.move_hyp id MoveFirst }
+| [ "move" hyp(id) "at" "bottom" ] -> { Tactics.move_hyp id MoveLast }
+| [ "move" hyp(id) "after" hyp(h) ] -> { Tactics.move_hyp id (MoveAfter h) }
+| [ "move" hyp(id) "before" hyp(h) ] -> { Tactics.move_hyp id (MoveBefore h) }
END
(** Rename *)
TACTIC EXTEND rename
-| [ "rename" ne_rename_list_sep(ids, ",") ] -> [ Tactics.rename_hyp ids ]
+| [ "rename" ne_rename_list_sep(ids, ",") ] -> { Tactics.rename_hyp ids }
END
(** Revert *)
TACTIC EXTEND revert
- [ "revert" ne_hyp_list(hl) ] -> [ Tactics.revert hl ]
+| [ "revert" ne_hyp_list(hl) ] -> { Tactics.revert hl }
END
(** Simple induction / destruct *)
+{
+
let simple_induct h =
Tacticals.New.tclTHEN (Tactics.intros_until h)
(Tacticals.New.onLastHyp Tactics.simplest_elim)
+}
+
TACTIC EXTEND simple_induction
- [ "simple" "induction" quantified_hypothesis(h) ] -> [ simple_induct h ]
+| [ "simple" "induction" quantified_hypothesis(h) ] -> { simple_induct h }
END
+{
+
let simple_destruct h =
Tacticals.New.tclTHEN (Tactics.intros_until h)
(Tacticals.New.onLastHyp Tactics.simplest_case)
+}
+
TACTIC EXTEND simple_destruct
- [ "simple" "destruct" quantified_hypothesis(h) ] -> [ simple_destruct h ]
+| [ "simple" "destruct" quantified_hypothesis(h) ] -> { simple_destruct h }
END
(** Double induction *)
TACTIC EXTEND double_induction
- [ "double" "induction" quantified_hypothesis(h1) quantified_hypothesis(h2) ] ->
- [ Elim.h_double_induction h1 h2 ]
+| [ "double" "induction" quantified_hypothesis(h1) quantified_hypothesis(h2) ] ->
+ { Elim.h_double_induction h1 h2 }
END
(* Admit *)
TACTIC EXTEND admit
- [ "admit" ] -> [ Proofview.give_up ]
+|[ "admit" ] -> { Proofview.give_up }
END
(* Fix *)
TACTIC EXTEND fix
- [ "fix" natural(n) ] -> [ Tactics.fix None n ]
-| [ "fix" ident(id) natural(n) ] -> [ Tactics.fix (Some id) n ]
+| [ "fix" ident(id) natural(n) ] -> { Tactics.fix id n }
END
(* Cofix *)
TACTIC EXTEND cofix
- [ "cofix" ] -> [ Tactics.cofix None ]
-| [ "cofix" ident(id) ] -> [ Tactics.cofix (Some id) ]
+| [ "cofix" ident(id) ] -> { Tactics.cofix id }
END
(* Clear *)
TACTIC EXTEND clear
- [ "clear" hyp_list(ids) ] -> [
+| [ "clear" hyp_list(ids) ] -> {
if List.is_empty ids then Tactics.keep []
else Tactics.clear ids
- ]
-| [ "clear" "-" ne_hyp_list(ids) ] -> [ Tactics.keep ids ]
+ }
+| [ "clear" "-" ne_hyp_list(ids) ] -> { Tactics.keep ids }
END
(* Clearbody *)
TACTIC EXTEND clearbody
- [ "clearbody" ne_hyp_list(ids) ] -> [ Tactics.clear_body ids ]
+| [ "clearbody" ne_hyp_list(ids) ] -> { Tactics.clear_body ids }
END
(* Generalize dependent *)
TACTIC EXTEND generalize_dependent
- [ "generalize" "dependent" constr(c) ] -> [ Tactics.generalize_dep c ]
+| [ "generalize" "dependent" constr(c) ] -> { Tactics.generalize_dep c }
END
(* Table of "pervasives" macros tactics (e.g. auto, simpl, etc.) *)
+{
+
open Tacexpr
let initial_atomic () =
@@ -364,3 +384,5 @@ let initial_tacticals () =
]
let () = Mltop.declare_cache_obj initial_tacticals "ltac_plugin"
+
+}
diff --git a/plugins/ltac/evar_tactics.ml b/plugins/ltac/evar_tactics.ml
index 9382f567..84f13d21 100644
--- a/plugins/ltac/evar_tactics.ml
+++ b/plugins/ltac/evar_tactics.ml
@@ -10,7 +10,7 @@
open Util
open Names
-open Term
+open Constr
open CErrors
open Evar_refiner
open Tacmach
@@ -52,7 +52,7 @@ let instantiate_tac n c ido =
match ido with
ConclLocation () -> evar_list sigma (pf_concl gl)
| HypLocation (id,hloc) ->
- let decl = Environ.lookup_named_val id (Goal.V82.hyps sigma (sig_it gl)) in
+ let decl = Environ.lookup_named id (pf_env gl) in
match hloc with
InHyp ->
(match decl with
@@ -85,16 +85,14 @@ let let_evar name typ =
Proofview.Goal.enter begin fun gl ->
let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
- let sigma = ref sigma in
- let _ = Typing.e_sort_of env sigma typ in
- let sigma = !sigma in
+ let sigma, _ = Typing.sort_of env sigma typ in
let id = match name with
| Name.Anonymous ->
let id = Namegen.id_of_name_using_hdchar env sigma typ name in
Namegen.next_ident_away_in_goal id (Termops.vars_of_env env)
| Name.Name id -> id
in
- let (sigma, evar) = Evarutil.new_evar env sigma ~src ~naming:(Misctypes.IntroFresh id) typ in
+ let (sigma, evar) = Evarutil.new_evar env sigma ~src ~naming:(Namegen.IntroFresh id) typ in
Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS sigma)
(Tactics.letin_tac None (Name.Name id) evar None Locusops.nowhere)
end
diff --git a/plugins/ltac/extraargs.ml4 b/plugins/ltac/extraargs.ml4
index 702b8303..d7799511 100644
--- a/plugins/ltac/extraargs.ml4
+++ b/plugins/ltac/extraargs.ml4
@@ -19,7 +19,6 @@ open Tacmach
open Tacexpr
open Taccoerce
open Tacinterp
-open Misctypes
open Locus
(** Adding scopes for generic arguments not defined through ARGUMENT EXTEND *)
@@ -35,7 +34,7 @@ let () = create_generic_quotation "ident" Pcoq.Prim.ident Stdarg.wit_ident
let () = create_generic_quotation "reference" Pcoq.Prim.reference Stdarg.wit_ref
let () = create_generic_quotation "uconstr" Pcoq.Constr.lconstr Stdarg.wit_uconstr
let () = create_generic_quotation "constr" Pcoq.Constr.lconstr Stdarg.wit_constr
-let () = create_generic_quotation "ipattern" Pltac.simple_intropattern Stdarg.wit_intro_pattern
+let () = create_generic_quotation "ipattern" Pltac.simple_intropattern wit_intro_pattern
let () = create_generic_quotation "open_constr" Pcoq.Constr.lconstr Stdarg.wit_open_constr
let () =
let inject (loc, v) = Tacexpr.Tacexp v in
@@ -53,8 +52,11 @@ let () =
(* Rewriting orientation *)
-let _ = Metasyntax.add_token_obj "<-"
-let _ = Metasyntax.add_token_obj "->"
+let _ =
+ Mltop.declare_cache_obj
+ (fun () -> Metasyntax.add_token_obj "<-";
+ Metasyntax.add_token_obj "->")
+ "ltac_plugin"
let pr_orient _prc _prlc _prt = function
| true -> Pp.mt ()
@@ -251,7 +253,7 @@ END
let pr_by_arg_tac _prc _prlc prtac opt_c =
match opt_c with
| None -> mt ()
- | Some t -> hov 2 (str "by" ++ spc () ++ prtac (3,Notation_term.E) t)
+ | Some t -> hov 2 (str "by" ++ spc () ++ prtac (3,Notation_gram.E) t)
ARGUMENT EXTEND by_arg_tac
TYPED AS tactic_opt
@@ -298,25 +300,6 @@ END
(* spiwack: the print functions are incomplete, but I don't know what they are
used for *)
-let pr_r_nat_field natf =
- str "nat " ++
- match natf with
- | Retroknowledge.NatType -> str "type"
- | Retroknowledge.NatPlus -> str "plus"
- | Retroknowledge.NatTimes -> str "times"
-
-let pr_r_n_field nf =
- str "binary N " ++
- match nf with
- | Retroknowledge.NPositive -> str "positive"
- | Retroknowledge.NType -> str "type"
- | Retroknowledge.NTwice -> str "twice"
- | Retroknowledge.NTwicePlusOne -> str "twice plus one"
- | Retroknowledge.NPhi -> str "phi"
- | Retroknowledge.NPhiInv -> str "phi inv"
- | Retroknowledge.NPlus -> str "plus"
- | Retroknowledge.NTimes -> str "times"
-
let pr_r_int31_field i31f =
str "int31 " ++
match i31f with
@@ -354,26 +337,6 @@ let pr_retroknowledge_field f =
| Retroknowledge.KInt31 (group, i31f) -> (pr_r_int31_field i31f) ++
spc () ++ str "in " ++ qs group
-VERNAC ARGUMENT EXTEND retroknowledge_nat
-PRINTED BY pr_r_nat_field
-| [ "nat" "type" ] -> [ Retroknowledge.NatType ]
-| [ "nat" "plus" ] -> [ Retroknowledge.NatPlus ]
-| [ "nat" "times" ] -> [ Retroknowledge.NatTimes ]
-END
-
-
-VERNAC ARGUMENT EXTEND retroknowledge_binary_n
-PRINTED BY pr_r_n_field
-| [ "binary" "N" "positive" ] -> [ Retroknowledge.NPositive ]
-| [ "binary" "N" "type" ] -> [ Retroknowledge.NType ]
-| [ "binary" "N" "twice" ] -> [ Retroknowledge.NTwice ]
-| [ "binary" "N" "twice" "plus" "one" ] -> [ Retroknowledge.NTwicePlusOne ]
-| [ "binary" "N" "phi" ] -> [ Retroknowledge.NPhi ]
-| [ "binary" "N" "phi" "inv" ] -> [ Retroknowledge.NPhiInv ]
-| [ "binary" "N" "plus" ] -> [ Retroknowledge.NPlus ]
-| [ "binary" "N" "times" ] -> [ Retroknowledge.NTimes ]
-END
-
VERNAC ARGUMENT EXTEND retroknowledge_int31
PRINTED BY pr_r_int31_field
| [ "int31" "bits" ] -> [ Retroknowledge.Int31Bits ]
diff --git a/plugins/ltac/extraargs.mli b/plugins/ltac/extraargs.mli
index e5a4f090..e477b12c 100644
--- a/plugins/ltac/extraargs.mli
+++ b/plugins/ltac/extraargs.mli
@@ -12,17 +12,16 @@ open Tacexpr
open Names
open Constrexpr
open Glob_term
-open Misctypes
val wit_orient : bool Genarg.uniform_genarg_type
-val orient : bool Pcoq.Gram.entry
+val orient : bool Pcoq.Entry.t
val pr_orient : bool -> Pp.t
val wit_rename : (Id.t * Id.t) Genarg.uniform_genarg_type
-val occurrences : (int list or_var) Pcoq.Gram.entry
-val wit_occurrences : (int list or_var, int list or_var, int list) Genarg.genarg_type
-val pr_occurrences : int list or_var -> Pp.t
+val occurrences : (int list Locus.or_var) Pcoq.Entry.t
+val wit_occurrences : (int list Locus.or_var, int list Locus.or_var, int list) Genarg.genarg_type
+val pr_occurrences : int list Locus.or_var -> Pp.t
val occurrences_of : int list -> Locus.occurrences
val wit_natural : int Genarg.uniform_genarg_type
@@ -47,8 +46,8 @@ val wit_casted_constr :
Tacexpr.glob_constr_and_expr,
EConstr.t) Genarg.genarg_type
-val glob : constr_expr Pcoq.Gram.entry
-val lglob : constr_expr Pcoq.Gram.entry
+val glob : constr_expr Pcoq.Entry.t
+val lglob : constr_expr Pcoq.Entry.t
type 'id gen_place= ('id * Locus.hyp_location_flag,unit) location
@@ -56,26 +55,26 @@ type loc_place = lident gen_place
type place = Id.t gen_place
val wit_hloc : (loc_place, loc_place, place) Genarg.genarg_type
-val hloc : loc_place Pcoq.Gram.entry
+val hloc : loc_place Pcoq.Entry.t
val pr_hloc : loc_place -> Pp.t
-val by_arg_tac : Tacexpr.raw_tactic_expr option Pcoq.Gram.entry
+val by_arg_tac : Tacexpr.raw_tactic_expr option Pcoq.Entry.t
val wit_by_arg_tac :
(raw_tactic_expr option,
glob_tactic_expr option,
Geninterp.Val.t option) Genarg.genarg_type
val pr_by_arg_tac :
- (int * Notation_term.parenRelation -> raw_tactic_expr -> Pp.t) ->
+ (int * Notation_gram.parenRelation -> raw_tactic_expr -> Pp.t) ->
raw_tactic_expr option -> Pp.t
-val test_lpar_id_colon : unit Pcoq.Gram.entry
+val test_lpar_id_colon : unit Pcoq.Entry.t
val wit_test_lpar_id_colon : (unit, unit, unit) Genarg.genarg_type
(** Spiwack: Primitive for retroknowledge registration *)
-val retroknowledge_field : Retroknowledge.field Pcoq.Gram.entry
+val retroknowledge_field : Retroknowledge.field Pcoq.Entry.t
val wit_retroknowledge_field : (Retroknowledge.field, unit, unit) Genarg.genarg_type
val wit_in_clause :
diff --git a/plugins/ltac/extratactics.ml4 b/plugins/ltac/extratactics.ml4
index 2e90ce90..31695fc7 100644
--- a/plugins/ltac/extratactics.ml4
+++ b/plugins/ltac/extratactics.ml4
@@ -9,6 +9,7 @@
(************************************************************************)
open Pp
+open Constr
open Genarg
open Stdarg
open Tacarg
@@ -23,7 +24,9 @@ open CErrors
open Util
open Termops
open Equality
-open Misctypes
+open Namegen
+open Tactypes
+open Tactics
open Proofview.Notations
open Vernacinterp
@@ -284,80 +287,6 @@ VERNAC COMMAND FUNCTIONAL EXTEND HintRewrite CLASSIFIED BY classify_hint
END
(**********************************************************************)
-(* Hint Resolve *)
-
-open Term
-open EConstr
-open Vars
-open Coqlib
-
-let project_hint ~poly pri l2r r =
- let gr = Smartlocate.global_with_alias r in
- let env = Global.env() in
- let sigma = Evd.from_env env in
- let sigma, c = Evd.fresh_global env sigma gr in
- let c = EConstr.of_constr c in
- let t = Retyping.get_type_of env sigma c in
- let t =
- Tacred.reduce_to_quantified_ref env sigma (Lazy.force coq_iff_ref) t in
- let sign,ccl = decompose_prod_assum sigma t in
- let (a,b) = match snd (decompose_app sigma ccl) with
- | [a;b] -> (a,b)
- | _ -> assert false in
- let p =
- if l2r then build_coq_iff_left_proj () else build_coq_iff_right_proj () in
- let sigma, p = Evd.fresh_global env sigma p in
- let p = EConstr.of_constr p in
- let c = Reductionops.whd_beta sigma (mkApp (c, Context.Rel.to_extended_vect mkRel 0 sign)) in
- let c = it_mkLambda_or_LetIn
- (mkApp (p,[|mkArrow a (lift 1 b);mkArrow b (lift 1 a);c|])) sign in
- let id =
- Nameops.add_suffix (Nametab.basename_of_global gr) ("_proj_" ^ (if l2r then "l2r" else "r2l"))
- in
- let ctx = Evd.const_univ_entry ~poly sigma in
- let c = EConstr.to_constr sigma c in
- let c = Declare.declare_definition ~internal:Declare.InternalTacticRequest id (c,ctx) in
- let info = {Vernacexpr.hint_priority = pri; hint_pattern = None} in
- (info,false,true,Hints.PathAny, Hints.IsGlobRef (Globnames.ConstRef c))
-
-let add_hints_iff ~atts l2r lc n bl =
- let open Vernacinterp in
- Hints.add_hints (Locality.make_module_locality atts.locality) bl
- (Hints.HintsResolveEntry (List.map (project_hint ~poly:atts.polymorphic n l2r) lc))
-
-VERNAC COMMAND FUNCTIONAL EXTEND HintResolveIffLR CLASSIFIED AS SIDEFF
- [ "Hint" "Resolve" "->" ne_global_list(lc) natural_opt(n)
- ":" preident_list(bl) ] ->
- [ fun ~atts ~st -> begin
- add_hints_iff ~atts true lc n bl;
- st
- end
- ]
-| [ "Hint" "Resolve" "->" ne_global_list(lc) natural_opt(n) ] ->
- [ fun ~atts ~st -> begin
- add_hints_iff ~atts true lc n ["core"];
- st
- end
- ]
-END
-
-VERNAC COMMAND FUNCTIONAL EXTEND HintResolveIffRL CLASSIFIED AS SIDEFF
- [ "Hint" "Resolve" "<-" ne_global_list(lc) natural_opt(n)
- ":" preident_list(bl) ] ->
- [ fun ~atts ~st -> begin
- add_hints_iff ~atts false lc n bl;
- st
- end
- ]
-| [ "Hint" "Resolve" "<-" ne_global_list(lc) natural_opt(n) ] ->
- [ fun ~atts ~st -> begin
- add_hints_iff ~atts false lc n ["core"];
- st
- end
- ]
-END
-
-(**********************************************************************)
(* Refine *)
open EConstr
@@ -365,7 +294,7 @@ open Vars
let constr_flags () = {
Pretyping.use_typeclasses = true;
- Pretyping.solve_unification_constraints = true;
+ Pretyping.solve_unification_constraints = Pfedit.use_unification_heuristics ();
Pretyping.use_hook = Pfedit.solve_by_implicit_tactic ();
Pretyping.fail_evar = false;
Pretyping.expand_evars = true }
@@ -596,10 +525,16 @@ let inImplicitTactic : glob_tactic_expr option -> obj =
subst_function = subst_implicit_tactic;
classify_function = (fun o -> Dispose)}
+let warn_deprecated_implicit_tactic =
+ CWarnings.create ~name:"deprecated-implicit-tactic" ~category:"deprecated"
+ (fun () -> strbrk "Implicit tactics are deprecated")
+
let declare_implicit_tactic tac =
+ let () = warn_deprecated_implicit_tactic () in
Lib.add_anonymous_leaf (inImplicitTactic (Some (Tacintern.glob_tactic tac)))
let clear_implicit_tactic () =
+ let () = warn_deprecated_implicit_tactic () in
Lib.add_anonymous_leaf (inImplicitTactic None)
VERNAC COMMAND EXTEND ImplicitTactic CLASSIFIED AS SIDEFF
@@ -615,10 +550,12 @@ END
VERNAC COMMAND EXTEND RetroknowledgeRegister CLASSIFIED AS SIDEFF
| [ "Register" constr(c) "as" retroknowledge_field(f) "by" constr(b)] ->
- [ let tc,_ctx = Constrintern.interp_constr (Global.env ()) Evd.empty c in
- let tb,_ctx(*FIXME*) = Constrintern.interp_constr (Global.env ()) Evd.empty b in
- let tc = EConstr.to_constr Evd.empty tc in
- let tb = EConstr.to_constr Evd.empty tb in
+ [ let env = Global.env () in
+ let evd = Evd.from_env env in
+ let tc,_ctx = Constrintern.interp_constr env evd c in
+ let tb,_ctx(*FIXME*) = Constrintern.interp_constr env evd b in
+ let tc = EConstr.to_constr evd tc in
+ let tb = EConstr.to_constr evd tb in
Global.register f tc tb ]
END
@@ -668,8 +605,11 @@ let subst_var_with_hole occ tid t =
else
(incr locref;
DAst.make ~loc:(Loc.make_loc (!locref,0)) @@
- GHole (Evar_kinds.QuestionMark(Evar_kinds.Define true,Anonymous),
- Misctypes.IntroAnonymous, None)))
+ GHole (Evar_kinds.QuestionMark {
+ Evar_kinds.qm_obligation=Evar_kinds.Define true;
+ Evar_kinds.qm_name=Anonymous;
+ Evar_kinds.qm_record_field=None;
+ }, IntroAnonymous, None)))
else x
| _ -> map_glob_constr_left_to_right substrec x in
let t' = substrec t
@@ -680,13 +620,21 @@ let subst_hole_with_term occ tc t =
let locref = ref 0 in
let occref = ref occ in
let rec substrec c = match DAst.get c with
- | GHole (Evar_kinds.QuestionMark(Evar_kinds.Define true,Anonymous),Misctypes.IntroAnonymous,s) ->
+ | GHole (Evar_kinds.QuestionMark {
+ Evar_kinds.qm_obligation=Evar_kinds.Define true;
+ Evar_kinds.qm_name=Anonymous;
+ Evar_kinds.qm_record_field=None;
+ }, IntroAnonymous, s) ->
decr occref;
if Int.equal !occref 0 then tc
else
(incr locref;
DAst.make ~loc:(Loc.make_loc (!locref,0)) @@
- GHole (Evar_kinds.QuestionMark(Evar_kinds.Define true,Anonymous),Misctypes.IntroAnonymous,s))
+ GHole (Evar_kinds.QuestionMark {
+ Evar_kinds.qm_obligation=Evar_kinds.Define true;
+ Evar_kinds.qm_name=Anonymous;
+ Evar_kinds.qm_record_field=None;
+ },IntroAnonymous,s))
| _ -> map_glob_constr_left_to_right substrec c
in
substrec t
@@ -781,7 +729,7 @@ let mkCaseEq a : unit Proofview.tactic =
let concl = Proofview.Goal.concl gl in
let env = Proofview.Goal.env gl in
(** FIXME: this looks really wrong. Does anybody really use this tactic? *)
- let (_, c) = Tacred.pattern_occs [Locus.OnlyOccurrences [1], a] env Evd.empty concl in
+ let (_, c) = Tacred.pattern_occs [Locus.OnlyOccurrences [1], a] env (Evd.from_env env) concl in
change_concl c
end;
simplest_case a]
@@ -857,17 +805,12 @@ END
(* ********************************************************************* *)
-let eq_constr x y =
- Proofview.Goal.enter begin fun gl ->
- let env = Tacmach.New.pf_env gl in
- let evd = Tacmach.New.project gl in
- match EConstr.eq_constr_universes env evd x y with
- | Some _ -> Proofview.tclUNIT ()
- | None -> Tacticals.New.tclFAIL 0 (str "Not equal")
- end
-
TACTIC EXTEND constr_eq
-| [ "constr_eq" constr(x) constr(y) ] -> [ eq_constr x y ]
+| [ "constr_eq" constr(x) constr(y) ] -> [ Tactics.constr_eq ~strict:false x y ]
+END
+
+TACTIC EXTEND constr_eq_strict
+| [ "constr_eq_strict" constr(x) constr(y) ] -> [ Tactics.constr_eq ~strict:true x y ]
END
TACTIC EXTEND constr_eq_nounivs
@@ -1108,7 +1051,9 @@ END
VERNAC COMMAND EXTEND Declare_keys CLASSIFIED AS SIDEFF
| [ "Declare" "Equivalent" "Keys" constr(c) constr(c') ] -> [
let get_key c =
- let (evd, c) = Constrintern.interp_open_constr (Global.env ()) Evd.empty c in
+ let env = Global.env () in
+ let evd = Evd.from_env env in
+ let (evd, c) = Constrintern.interp_open_constr env evd c in
let kind c = EConstr.kind evd c in
Keys.constr_key kind c
in
diff --git a/plugins/ltac/g_auto.ml4 b/plugins/ltac/g_auto.ml4
index 643f7e99..35ed14fc 100644
--- a/plugins/ltac/g_auto.ml4
+++ b/plugins/ltac/g_auto.ml4
@@ -9,6 +9,7 @@
(************************************************************************)
open Pp
+open Constr
open Genarg
open Stdarg
open Pcoq.Prim
@@ -169,10 +170,10 @@ END
TACTIC EXTEND convert_concl_no_check
-| ["convert_concl_no_check" constr(x) ] -> [ Tactics.convert_concl_no_check x Term.DEFAULTcast ]
+| ["convert_concl_no_check" constr(x) ] -> [ Tactics.convert_concl_no_check x DEFAULTcast ]
END
-let pr_pre_hints_path_atom _ _ _ = Hints.pp_hints_path_atom Libnames.pr_reference
+let pr_pre_hints_path_atom _ _ _ = Hints.pp_hints_path_atom Libnames.pr_qualid
let pr_hints_path_atom _ _ _ = Hints.pp_hints_path_atom Printer.pr_global
let glob_hints_path_atom ist = Hints.glob_hints_path_atom
@@ -188,7 +189,7 @@ ARGUMENT EXTEND hints_path_atom
END
let pr_hints_path prc prx pry c = Hints.pp_hints_path c
-let pr_pre_hints_path prc prx pry c = Hints.pp_hints_path_gen Libnames.pr_reference c
+let pr_pre_hints_path prc prx pry c = Hints.pp_hints_path_gen Libnames.pr_qualid c
let glob_hints_path ist = Hints.glob_hints_path
ARGUMENT EXTEND hints_path
@@ -219,7 +220,7 @@ VERNAC COMMAND FUNCTIONAL EXTEND HintCut CLASSIFIED AS SIDEFF
fun ~atts ~st -> begin
let open Vernacinterp in
let entry = Hints.HintsCutEntry (Hints.glob_hints_path p) in
- Hints.add_hints (Locality.make_section_locality atts.locality)
+ Hints.add_hints ~local:(Locality.make_section_locality atts.locality)
(match dbnames with None -> ["core"] | Some l -> l) entry;
st
end
diff --git a/plugins/ltac/g_eqdecide.ml4 b/plugins/ltac/g_eqdecide.mlg
index 2251a662..e57afe3e 100644
--- a/plugins/ltac/g_eqdecide.ml4
+++ b/plugins/ltac/g_eqdecide.mlg
@@ -14,15 +14,19 @@
(* by Eduardo Gimenez *)
(************************************************************************)
+{
+
open Eqdecide
open Stdarg
+}
+
DECLARE PLUGIN "ltac_plugin"
TACTIC EXTEND decide_equality
-| [ "decide" "equality" ] -> [ decideEqualityGoal ]
+| [ "decide" "equality" ] -> { decideEqualityGoal }
END
TACTIC EXTEND compare
-| [ "compare" constr(c1) constr(c2) ] -> [ compare c1 c2 ]
+| [ "compare" constr(c1) constr(c2) ] -> { compare c1 c2 }
END
diff --git a/plugins/ltac/g_ltac.ml4 b/plugins/ltac/g_ltac.ml4
index 0c42a8bb..929390b1 100644
--- a/plugins/ltac/g_ltac.ml4
+++ b/plugins/ltac/g_ltac.ml4
@@ -12,21 +12,22 @@ DECLARE PLUGIN "ltac_plugin"
open Util
open Pp
+open Glob_term
open Constrexpr
open Tacexpr
-open Misctypes
+open Namegen
open Genarg
open Genredexpr
open Tok (* necessary for camlp5 *)
open Names
open Pcoq
-open Pcoq.Constr
-open Pcoq.Vernac_
open Pcoq.Prim
+open Pcoq.Constr
+open Pvernac.Vernac_
open Pltac
-let fail_default_value = ArgArg 0
+let fail_default_value = Locus.ArgArg 0
let arg_of_expr = function
TacArg (loc,a) -> a
@@ -34,20 +35,21 @@ let arg_of_expr = function
let genarg_of_unit () = in_gen (rawwit Stdarg.wit_unit) ()
let genarg_of_int n = in_gen (rawwit Stdarg.wit_int) n
-let genarg_of_ipattern pat = in_gen (rawwit Stdarg.wit_intro_pattern) pat
+let genarg_of_ipattern pat = in_gen (rawwit Tacarg.wit_intro_pattern) pat
let genarg_of_uconstr c = in_gen (rawwit Stdarg.wit_uconstr) c
let in_tac tac = in_gen (rawwit Tacarg.wit_ltac) tac
-let reference_to_id = CAst.map_with_loc (fun ?loc -> function
- | Libnames.Ident id -> id
- | Libnames.Qualid _ ->
- CErrors.user_err ?loc
- (str "This expression should be a simple identifier."))
+let reference_to_id qid =
+ if Libnames.qualid_is_ident qid then
+ CAst.make ?loc:qid.CAst.loc @@ Libnames.qualid_basename qid
+ else
+ CErrors.user_err ?loc:qid.CAst.loc
+ (str "This expression should be a simple identifier.")
-let tactic_mode = Gram.entry_create "vernac:tactic_command"
+let tactic_mode = Entry.create "vernac:tactic_command"
let new_entry name =
- let e = Gram.entry_create name in
+ let e = Entry.create name in
e
let toplevel_selector = new_entry "vernac:toplevel_selector"
@@ -58,8 +60,8 @@ let tacdef_body = new_entry "tactic:tacdef_body"
let _ =
let mode = {
Proof_global.name = "Classic";
- set = (fun () -> set_command_entry tactic_mode);
- reset = (fun () -> set_command_entry Pcoq.Vernac_.noedit_mode);
+ set = (fun () -> Pvernac.set_command_entry tactic_mode);
+ reset = (fun () -> Pvernac.(set_command_entry noedit_mode));
} in
Proof_global.register_proof_mode mode
@@ -197,9 +199,8 @@ GEXTEND Gram
non ambiguous name where dots are replaced by "_"? Probably too
verbose most of the time. *)
fresh_id:
- [ [ s = STRING -> ArgArg s (*| id = ident -> ArgVar (!@loc,id)*)
- | qid = qualid -> let (_pth,id) = Libnames.repr_qualid qid.CAst.v in
- ArgVar (CAst.make ~loc:!@loc id) ] ]
+ [ [ s = STRING -> Locus.ArgArg s (*| id = ident -> Locus.ArgVar (!@loc,id)*)
+ | qid = qualid -> Locus.ArgVar (CAst.make ~loc:!@loc @@ Libnames.qualid_basename qid) ] ]
;
constr_eval:
[ [ IDENT "eval"; rtc = red_expr; "in"; c = Constr.constr ->
@@ -286,12 +287,14 @@ GEXTEND Gram
(* Definitions for tactics *)
tacdef_body:
- [ [ name = Constr.global; it=LIST1 input_fun; redef = ltac_def_kind; body = tactic_expr ->
+ [ [ name = Constr.global; it=LIST1 input_fun;
+ redef = ltac_def_kind; body = tactic_expr ->
if redef then Tacexpr.TacticRedefinition (name, TacFun (it, body))
else
let id = reference_to_id name in
Tacexpr.TacticDefinition (id, TacFun (it, body))
- | name = Constr.global; redef = ltac_def_kind; body = tactic_expr ->
+ | name = Constr.global; redef = ltac_def_kind;
+ body = tactic_expr ->
if redef then Tacexpr.TacticRedefinition (name, body)
else
let id = reference_to_id name in
@@ -311,21 +314,23 @@ GEXTEND Gram
range_selector_or_nth:
[ [ n = natural ; "-" ; m = natural;
l = OPT [","; l = LIST1 range_selector SEP "," -> l] ->
- SelectList ((n, m) :: Option.default [] l)
+ Goal_select.SelectList ((n, m) :: Option.default [] l)
| n = natural;
l = OPT [","; l = LIST1 range_selector SEP "," -> l] ->
+ let open Goal_select in
Option.cata (fun l -> SelectList ((n, n) :: l)) (SelectNth n) l ] ]
;
selector_body:
[ [ l = range_selector_or_nth -> l
- | test_bracket_ident; "["; id = ident; "]" -> SelectId id ] ]
+ | test_bracket_ident; "["; id = ident; "]" -> Goal_select.SelectId id ] ]
;
selector:
[ [ IDENT "only"; sel = selector_body; ":" -> sel ] ]
;
toplevel_selector:
[ [ sel = selector_body; ":" -> sel
- | IDENT "all"; ":" -> SelectAll ] ]
+ | "!"; ":" -> Goal_select.SelectAlreadyFocused
+ | IDENT "all"; ":" -> Goal_select.SelectAll ] ]
;
tactic_mode:
[ [ g = OPT toplevel_selector; tac = G_vernac.query_command -> tac g
@@ -342,7 +347,7 @@ GEXTEND Gram
hint:
[ [ IDENT "Extern"; n = natural; c = OPT Constr.constr_pattern ; "=>";
tac = Pltac.tactic ->
- Vernacexpr.HintsExtern (n,c, in_tac tac) ] ]
+ Hints.HintsExtern (n,c, in_tac tac) ] ]
;
operconstr: LEVEL "0"
[ [ IDENT "ltac"; ":"; "("; tac = Pltac.tactic_expr; ")" ->
@@ -369,6 +374,7 @@ let _ = declare_int_option {
}
let vernac_solve n info tcom b =
+ let open Goal_select in
let status = Proof_global.with_current_proof (fun etac p ->
let with_end_tac = if b then Some etac else None in
let global = match n with SelectAll | SelectList _ -> true | _ -> false in
@@ -415,7 +421,7 @@ let is_explicit_terminator = function TacSolve _ -> true | _ -> false
VERNAC tactic_mode EXTEND VernacSolve
| [ - ltac_selector_opt(g) ltac_info_opt(n) tactic(t) ltac_use_default(def) ] =>
[ classify_as_proofstep ] -> [
- let g = Option.default (Proof_bullet.get_default_goal_selector ()) g in
+ let g = Option.default (Goal_select.get_default_goal_selector ()) g in
vernac_solve g n t def
]
| [ - "par" ":" ltac_info_opt(n) tactic(t) ltac_use_default(def) ] =>
@@ -428,7 +434,7 @@ VERNAC tactic_mode EXTEND VernacSolve
VtLater
] -> [
let t = rm_abstract t in
- vernac_solve SelectAll n t def
+ vernac_solve Goal_select.SelectAll n t def
]
END
@@ -466,14 +472,15 @@ VERNAC COMMAND FUNCTIONAL EXTEND VernacTacticNotation
[ VtSideff [], VtNow ] ->
[ fun ~atts ~st -> let open Vernacinterp in
let n = Option.default 0 n in
- Tacentries.add_tactic_notation (Locality.make_module_locality atts.locality) n r e;
+ let deprecation = atts.deprecated in
+ Tacentries.add_tactic_notation (Locality.make_module_locality atts.locality) n ?deprecation r e;
st
]
END
VERNAC COMMAND EXTEND VernacPrintLtac CLASSIFIED AS QUERY
| [ "Print" "Ltac" reference(r) ] ->
- [ Feedback.msg_notice (Tacintern.print_ltac (Libnames.qualid_of_reference r).CAst.v) ]
+ [ Feedback.msg_notice (Tacintern.print_ltac r) ]
END
VERNAC COMMAND EXTEND VernacLocateLtac CLASSIFIED AS QUERY
@@ -481,7 +488,7 @@ VERNAC COMMAND EXTEND VernacLocateLtac CLASSIFIED AS QUERY
[ Tacentries.print_located_tactic r ]
END
-let pr_ltac_ref = Libnames.pr_reference
+let pr_ltac_ref = Libnames.pr_qualid
let pr_tacdef_body tacdef_body =
let id, redef, body =
@@ -508,10 +515,10 @@ VERNAC COMMAND FUNCTIONAL EXTEND VernacDeclareTacticDefinition
| [ "Ltac" ne_ltac_tacdef_body_list_sep(l, "with") ] => [
VtSideff (List.map (function
| TacticDefinition ({CAst.v=r},_) -> r
- | TacticRedefinition ({CAst.v=Ident r},_) -> r
- | TacticRedefinition ({CAst.v=Qualid q},_) -> snd(repr_qualid q)) l), VtLater
+ | TacticRedefinition (qid,_) -> qualid_basename qid) l), VtLater
] -> [ fun ~atts ~st -> let open Vernacinterp in
- Tacentries.register_ltac (Locality.make_module_locality atts.locality) l;
+ let deprecation = atts.deprecated in
+ Tacentries.register_ltac (Locality.make_module_locality atts.locality) ?deprecation l;
st
]
END
diff --git a/plugins/ltac/g_obligations.ml4 b/plugins/ltac/g_obligations.ml4
index 352e92c2..1f56244c 100644
--- a/plugins/ltac/g_obligations.ml4
+++ b/plugins/ltac/g_obligations.ml4
@@ -12,7 +12,6 @@
Syntax for the subtac terms and types.
Elaborated from correctness/psyntax.ml4 by Jean-Christophe Filliâtre *)
-open Libnames
open Constrexpr
open Constrexpr_ops
open Stdarg
@@ -49,7 +48,7 @@ module Tactic = Pltac
open Pcoq
-let sigref = mkRefC (CAst.make @@ Qualid (Libnames.qualid_of_string "Coq.Init.Specif.sig"))
+let sigref loc = mkRefC (Libnames.qualid_of_string ~loc "Coq.Init.Specif.sig")
type 'a withtac_argtype = (Tacexpr.raw_tactic_expr option, 'a) Genarg.abstract_argument_type
@@ -68,7 +67,7 @@ GEXTEND Gram
Constr.closed_binder:
[[ "("; id=Prim.name; ":"; t=Constr.lconstr; "|"; c=Constr.lconstr; ")" ->
- let typ = mkAppC (sigref, [mkLambdaC ([id], default_binder_kind, t, c)]) in
+ let typ = mkAppC (sigref !@loc, [mkLambdaC ([id], default_binder_kind, t, c)]) in
[CLocalAssum ([id], default_binder_kind, typ)]
] ];
diff --git a/plugins/ltac/g_rewrite.ml4 b/plugins/ltac/g_rewrite.ml4
index fbaa2e58..f1634f15 100644
--- a/plugins/ltac/g_rewrite.ml4
+++ b/plugins/ltac/g_rewrite.ml4
@@ -11,7 +11,6 @@
(* Syntax for rewriting with strategies *)
open Names
-open Misctypes
open Locus
open Constrexpr
open Glob_term
@@ -20,9 +19,10 @@ open Extraargs
open Tacmach
open Rewrite
open Stdarg
-open Pcoq.Vernac_
+open Tactypes
open Pcoq.Prim
open Pcoq.Constr
+open Pvernac.Vernac_
open Pltac
DECLARE PLUGIN "ltac_plugin"
@@ -67,13 +67,13 @@ let subst_strategy s str = str
let pr_strategy _ _ _ (s : strategy) = Pp.str "<strategy>"
let pr_raw_strategy prc prlc _ (s : raw_strategy) =
- let prr = Pptactic.pr_red_expr (prc, prlc, Pputils.pr_or_by_notation Libnames.pr_reference, prc) in
+ let prr = Pptactic.pr_red_expr (prc, prlc, Pputils.pr_or_by_notation Libnames.pr_qualid, prc) in
Rewrite.pr_strategy prc prr s
let pr_glob_strategy prc prlc _ (s : glob_strategy) =
let prr = Pptactic.pr_red_expr
(Ppconstr.pr_constr_expr,
Ppconstr.pr_lconstr_expr,
- Pputils.pr_or_by_notation Libnames.pr_reference,
+ Pputils.pr_or_by_notation Libnames.pr_qualid,
Ppconstr.pr_constr_expr)
in
Rewrite.pr_strategy prc prr s
diff --git a/plugins/ltac/g_tactic.ml4 b/plugins/ltac/g_tactic.mlg
index 7534e279..571595be 100644
--- a/plugins/ltac/g_tactic.ml4
+++ b/plugins/ltac/g_tactic.mlg
@@ -8,15 +8,21 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Pp
open CErrors
open Util
+open Names
+open Namegen
open Tacexpr
open Genredexpr
open Constrexpr
open Libnames
open Tok
-open Misctypes
+open Tactypes
+open Tactics
+open Inv
open Locus
open Decl_kinds
@@ -154,7 +160,7 @@ let mkTacCase with_evar = function
(* Reinterpret ident as notations for variables in the context *)
(* because we don't know if they are quantified or not *)
| [(clear,ElimOnIdent id),(None,None),None],None ->
- TacCase (with_evar,(clear,(CAst.make @@ CRef (CAst.make ?loc:id.CAst.loc @@ Ident id.CAst.v,None),NoBindings)))
+ TacCase (with_evar,(clear,(CAst.make @@ CRef (qualid_of_ident ?loc:id.CAst.loc id.CAst.v,None),NoBindings)))
| ic ->
if List.exists (function ((_, ElimOnAnonHyp _),_,_) -> true | _ -> false) (fst ic)
then
@@ -211,488 +217,490 @@ let warn_deprecated_eqn_syntax =
(* Auxiliary grammar rules *)
-open Vernac_
+open Pvernac.Vernac_
+
+}
-GEXTEND Gram
+GRAMMAR EXTEND Gram
GLOBAL: simple_tactic constr_with_bindings quantified_hypothesis
bindings red_expr int_or_var open_constr uconstr
simple_intropattern in_clause clause_dft_concl hypident destruction_arg;
int_or_var:
- [ [ n = integer -> ArgArg n
- | id = identref -> ArgVar id ] ]
+ [ [ n = integer -> { ArgArg n }
+ | id = identref -> { ArgVar id } ] ]
;
nat_or_var:
- [ [ n = natural -> ArgArg n
- | id = identref -> ArgVar id ] ]
+ [ [ n = natural -> { ArgArg n }
+ | id = identref -> { ArgVar id } ] ]
;
(* An identifier or a quotation meta-variable *)
id_or_meta:
- [ [ id = identref -> id ] ]
+ [ [ id = identref -> { id } ] ]
;
open_constr:
- [ [ c = constr -> c ] ]
+ [ [ c = constr -> { c } ] ]
;
uconstr:
- [ [ c = constr -> c ] ]
+ [ [ c = constr -> { c } ] ]
;
destruction_arg:
- [ [ n = natural -> (None,ElimOnAnonHyp n)
+ [ [ n = natural -> { (None,ElimOnAnonHyp n) }
| test_lpar_id_rpar; c = constr_with_bindings ->
- (Some false,destruction_arg_of_constr c)
- | c = constr_with_bindings_arg -> on_snd destruction_arg_of_constr c
+ { (Some false,destruction_arg_of_constr c) }
+ | c = constr_with_bindings_arg -> { on_snd destruction_arg_of_constr c }
] ]
;
constr_with_bindings_arg:
- [ [ ">"; c = constr_with_bindings -> (Some true,c)
- | c = constr_with_bindings -> (None,c) ] ]
+ [ [ ">"; c = constr_with_bindings -> { (Some true,c) }
+ | c = constr_with_bindings -> { (None,c) } ] ]
;
quantified_hypothesis:
- [ [ id = ident -> NamedHyp id
- | n = natural -> AnonHyp n ] ]
+ [ [ id = ident -> { NamedHyp id }
+ | n = natural -> { AnonHyp n } ] ]
;
conversion:
- [ [ c = constr -> (None, c)
- | c1 = constr; "with"; c2 = constr -> (Some (AllOccurrences,c1),c2)
+ [ [ c = constr -> { (None, c) }
+ | c1 = constr; "with"; c2 = constr -> { (Some (AllOccurrences,c1),c2) }
| c1 = constr; "at"; occs = occs_nums; "with"; c2 = constr ->
- (Some (occs,c1), c2) ] ]
+ { (Some (occs,c1), c2) } ] ]
;
occs_nums:
- [ [ nl = LIST1 nat_or_var -> OnlyOccurrences nl
+ [ [ nl = LIST1 nat_or_var -> { OnlyOccurrences nl }
| "-"; n = nat_or_var; nl = LIST0 int_or_var ->
(* have used int_or_var instead of nat_or_var for compatibility *)
- AllOccurrencesBut (List.map (map_int_or_var abs) (n::nl)) ] ]
+ { AllOccurrencesBut (List.map (map_int_or_var abs) (n::nl)) } ] ]
;
occs:
- [ [ "at"; occs = occs_nums -> occs | -> AllOccurrences ] ]
+ [ [ "at"; occs = occs_nums -> { occs } | -> { AllOccurrences } ] ]
;
pattern_occ:
- [ [ c = constr; nl = occs -> (nl,c) ] ]
+ [ [ c = constr; nl = occs -> { (nl,c) } ] ]
;
ref_or_pattern_occ:
(* If a string, it is interpreted as a ref
(anyway a Coq string does not reduce) *)
- [ [ c = smart_global; nl = occs -> nl,Inl c
- | c = constr; nl = occs -> nl,Inr c ] ]
+ [ [ c = smart_global; nl = occs -> { nl,Inl c }
+ | c = constr; nl = occs -> { nl,Inr c } ] ]
;
unfold_occ:
- [ [ c = smart_global; nl = occs -> (nl,c) ] ]
+ [ [ c = smart_global; nl = occs -> { (nl,c) } ] ]
;
intropatterns:
- [ [ l = LIST0 nonsimple_intropattern -> l ]]
+ [ [ l = LIST0 nonsimple_intropattern -> { l } ] ]
;
ne_intropatterns:
- [ [ l = LIST1 nonsimple_intropattern -> l ]]
+ [ [ l = LIST1 nonsimple_intropattern -> { l } ] ]
;
or_and_intropattern:
- [ [ "["; tc = LIST1 intropatterns SEP "|"; "]" -> IntroOrPattern tc
- | "()" -> IntroAndPattern []
- | "("; si = simple_intropattern; ")" -> IntroAndPattern [si]
+ [ [ "["; tc = LIST1 intropatterns SEP "|"; "]" -> { IntroOrPattern tc }
+ | "()" -> { IntroAndPattern [] }
+ | "("; si = simple_intropattern; ")" -> { IntroAndPattern [si] }
| "("; si = simple_intropattern; ",";
tc = LIST1 simple_intropattern SEP "," ; ")" ->
- IntroAndPattern (si::tc)
+ { IntroAndPattern (si::tc) }
| "("; si = simple_intropattern; "&";
tc = LIST1 simple_intropattern SEP "&" ; ")" ->
(* (A & B & C) is translated into (A,(B,C)) *)
- let rec pairify = function
+ { let rec pairify = function
| ([]|[_]|[_;_]) as l -> l
| t::q -> [t; CAst.make ?loc:(loc_of_ne_list q) (IntroAction (IntroOrAndPattern (IntroAndPattern (pairify q))))]
- in IntroAndPattern (pairify (si::tc)) ] ]
+ in IntroAndPattern (pairify (si::tc)) } ] ]
;
equality_intropattern:
- [ [ "->" -> IntroRewrite true
- | "<-" -> IntroRewrite false
- | "[="; tc = intropatterns; "]" -> IntroInjection tc ] ]
+ [ [ "->" -> { IntroRewrite true }
+ | "<-" -> { IntroRewrite false }
+ | "[="; tc = intropatterns; "]" -> { IntroInjection tc } ] ]
;
naming_intropattern:
- [ [ prefix = pattern_ident -> IntroFresh prefix
- | "?" -> IntroAnonymous
- | id = ident -> IntroIdentifier id ] ]
+ [ [ prefix = pattern_ident -> { IntroFresh prefix }
+ | "?" -> { IntroAnonymous }
+ | id = ident -> { IntroIdentifier id } ] ]
;
nonsimple_intropattern:
- [ [ l = simple_intropattern -> l
- | "*" -> CAst.make ~loc:!@loc @@ IntroForthcoming true
- | "**" -> CAst.make ~loc:!@loc @@ IntroForthcoming false ]]
+ [ [ l = simple_intropattern -> { l }
+ | "*" -> { CAst.make ~loc @@ IntroForthcoming true }
+ | "**" -> { CAst.make ~loc @@ IntroForthcoming false } ] ]
;
simple_intropattern:
[ [ pat = simple_intropattern_closed;
- l = LIST0 ["%"; c = operconstr LEVEL "0" -> c] ->
- let {CAst.loc=loc0;v=pat} = pat in
+ l = LIST0 ["%"; c = operconstr LEVEL "0" -> { c } ] ->
+ { let {CAst.loc=loc0;v=pat} = pat in
let f c pat =
let loc1 = Constrexpr_ops.constr_loc c in
let loc = Loc.merge_opt loc0 loc1 in
IntroAction (IntroApplyOn (CAst.(make ?loc:loc1 c),CAst.(make ?loc pat))) in
- CAst.make ~loc:!@loc @@ List.fold_right f l pat ] ]
+ CAst.make ~loc @@ List.fold_right f l pat } ] ]
;
simple_intropattern_closed:
- [ [ pat = or_and_intropattern -> CAst.make ~loc:!@loc @@ IntroAction (IntroOrAndPattern pat)
- | pat = equality_intropattern -> CAst.make ~loc:!@loc @@ IntroAction pat
- | "_" -> CAst.make ~loc:!@loc @@ IntroAction IntroWildcard
- | pat = naming_intropattern -> CAst.make ~loc:!@loc @@ IntroNaming pat ] ]
+ [ [ pat = or_and_intropattern -> { CAst.make ~loc @@ IntroAction (IntroOrAndPattern pat) }
+ | pat = equality_intropattern -> { CAst.make ~loc @@ IntroAction pat }
+ | "_" -> { CAst.make ~loc @@ IntroAction IntroWildcard }
+ | pat = naming_intropattern -> { CAst.make ~loc @@ IntroNaming pat } ] ]
;
simple_binding:
- [ [ "("; id = ident; ":="; c = lconstr; ")" -> CAst.make ~loc:!@loc (NamedHyp id, c)
- | "("; n = natural; ":="; c = lconstr; ")" -> CAst.make ~loc:!@loc (AnonHyp n, c) ] ]
+ [ [ "("; id = ident; ":="; c = lconstr; ")" -> { CAst.make ~loc (NamedHyp id, c) }
+ | "("; n = natural; ":="; c = lconstr; ")" -> { CAst.make ~loc (AnonHyp n, c) } ] ]
;
bindings:
[ [ test_lpar_idnum_coloneq; bl = LIST1 simple_binding ->
- ExplicitBindings bl
- | bl = LIST1 constr -> ImplicitBindings bl ] ]
+ { ExplicitBindings bl }
+ | bl = LIST1 constr -> { ImplicitBindings bl } ] ]
;
constr_with_bindings:
- [ [ c = constr; l = with_bindings -> (c, l) ] ]
+ [ [ c = constr; l = with_bindings -> { (c, l) } ] ]
;
with_bindings:
- [ [ "with"; bl = bindings -> bl | -> NoBindings ] ]
+ [ [ "with"; bl = bindings -> { bl } | -> { NoBindings } ] ]
;
red_flags:
- [ [ IDENT "beta" -> [FBeta]
- | IDENT "iota" -> [FMatch;FFix;FCofix]
- | IDENT "match" -> [FMatch]
- | IDENT "fix" -> [FFix]
- | IDENT "cofix" -> [FCofix]
- | IDENT "zeta" -> [FZeta]
- | IDENT "delta"; d = delta_flag -> [d]
+ [ [ IDENT "beta" -> { [FBeta] }
+ | IDENT "iota" -> { [FMatch;FFix;FCofix] }
+ | IDENT "match" -> { [FMatch] }
+ | IDENT "fix" -> { [FFix] }
+ | IDENT "cofix" -> { [FCofix] }
+ | IDENT "zeta" -> { [FZeta] }
+ | IDENT "delta"; d = delta_flag -> { [d] }
] ]
;
delta_flag:
- [ [ "-"; "["; idl = LIST1 smart_global; "]" -> FDeltaBut idl
- | "["; idl = LIST1 smart_global; "]" -> FConst idl
- | -> FDeltaBut []
+ [ [ "-"; "["; idl = LIST1 smart_global; "]" -> { FDeltaBut idl }
+ | "["; idl = LIST1 smart_global; "]" -> { FConst idl }
+ | -> { FDeltaBut [] }
] ]
;
strategy_flag:
- [ [ s = LIST1 red_flags -> Redops.make_red_flag (List.flatten s)
- | d = delta_flag -> all_with d
+ [ [ s = LIST1 red_flags -> { Redops.make_red_flag (List.flatten s) }
+ | d = delta_flag -> { all_with d }
] ]
;
red_expr:
- [ [ IDENT "red" -> Red false
- | IDENT "hnf" -> Hnf
- | IDENT "simpl"; d = delta_flag; po = OPT ref_or_pattern_occ -> Simpl (all_with d,po)
- | IDENT "cbv"; s = strategy_flag -> Cbv s
- | IDENT "cbn"; s = strategy_flag -> Cbn s
- | IDENT "lazy"; s = strategy_flag -> Lazy s
- | IDENT "compute"; delta = delta_flag -> Cbv (all_with delta)
- | IDENT "vm_compute"; po = OPT ref_or_pattern_occ -> CbvVm po
- | IDENT "native_compute"; po = OPT ref_or_pattern_occ -> CbvNative po
- | IDENT "unfold"; ul = LIST1 unfold_occ SEP "," -> Unfold ul
- | IDENT "fold"; cl = LIST1 constr -> Fold cl
- | IDENT "pattern"; pl = LIST1 pattern_occ SEP"," -> Pattern pl
- | s = IDENT -> ExtraRedExpr s ] ]
+ [ [ IDENT "red" -> { Red false }
+ | IDENT "hnf" -> { Hnf }
+ | IDENT "simpl"; d = delta_flag; po = OPT ref_or_pattern_occ -> { Simpl (all_with d,po) }
+ | IDENT "cbv"; s = strategy_flag -> { Cbv s }
+ | IDENT "cbn"; s = strategy_flag -> { Cbn s }
+ | IDENT "lazy"; s = strategy_flag -> { Lazy s }
+ | IDENT "compute"; delta = delta_flag -> { Cbv (all_with delta) }
+ | IDENT "vm_compute"; po = OPT ref_or_pattern_occ -> { CbvVm po }
+ | IDENT "native_compute"; po = OPT ref_or_pattern_occ -> { CbvNative po }
+ | IDENT "unfold"; ul = LIST1 unfold_occ SEP "," -> { Unfold ul }
+ | IDENT "fold"; cl = LIST1 constr -> { Fold cl }
+ | IDENT "pattern"; pl = LIST1 pattern_occ SEP"," -> { Pattern pl }
+ | s = IDENT -> { ExtraRedExpr s } ] ]
;
hypident:
[ [ id = id_or_meta ->
- let id : Misctypes.lident = id in
- id,InHyp
+ { let id : lident = id in
+ id,InHyp }
| "("; IDENT "type"; IDENT "of"; id = id_or_meta; ")" ->
- let id : Misctypes.lident = id in
- id,InHypTypeOnly
+ { let id : lident = id in
+ id,InHypTypeOnly }
| "("; IDENT "value"; IDENT "of"; id = id_or_meta; ")" ->
- let id : Misctypes.lident = id in
- id,InHypValueOnly
+ { let id : lident = id in
+ id,InHypValueOnly }
] ]
;
hypident_occ:
- [ [ (id,l)=hypident; occs=occs ->
- let id : Misctypes.lident = id in
- ((occs,id),l) ] ]
+ [ [ h=hypident; occs=occs ->
+ { let (id,l) = h in
+ let id : lident = id in
+ ((occs,id),l) } ] ]
;
in_clause:
[ [ "*"; occs=occs ->
- {onhyps=None; concl_occs=occs}
+ { {onhyps=None; concl_occs=occs} }
| "*"; "|-"; occs=concl_occ ->
- {onhyps=None; concl_occs=occs}
+ { {onhyps=None; concl_occs=occs} }
| hl=LIST0 hypident_occ SEP","; "|-"; occs=concl_occ ->
- {onhyps=Some hl; concl_occs=occs}
+ { {onhyps=Some hl; concl_occs=occs} }
| hl=LIST0 hypident_occ SEP"," ->
- {onhyps=Some hl; concl_occs=NoOccurrences} ] ]
+ { {onhyps=Some hl; concl_occs=NoOccurrences} } ] ]
;
clause_dft_concl:
- [ [ "in"; cl = in_clause -> cl
- | occs=occs -> {onhyps=Some[]; concl_occs=occs}
- | -> all_concl_occs_clause ] ]
+ [ [ "in"; cl = in_clause -> { cl }
+ | occs=occs -> { {onhyps=Some[]; concl_occs=occs} }
+ | -> { all_concl_occs_clause } ] ]
;
clause_dft_all:
- [ [ "in"; cl = in_clause -> cl
- | -> {onhyps=None; concl_occs=AllOccurrences} ] ]
+ [ [ "in"; cl = in_clause -> { cl }
+ | -> { {onhyps=None; concl_occs=AllOccurrences} } ] ]
;
opt_clause:
- [ [ "in"; cl = in_clause -> Some cl
- | "at"; occs = occs_nums -> Some {onhyps=Some[]; concl_occs=occs}
- | -> None ] ]
+ [ [ "in"; cl = in_clause -> { Some cl }
+ | "at"; occs = occs_nums -> { Some {onhyps=Some[]; concl_occs=occs} }
+ | -> { None } ] ]
;
concl_occ:
- [ [ "*"; occs = occs -> occs
- | -> NoOccurrences ] ]
+ [ [ "*"; occs = occs -> { occs }
+ | -> { NoOccurrences } ] ]
;
in_hyp_list:
- [ [ "in"; idl = LIST1 id_or_meta -> idl
- | -> [] ] ]
+ [ [ "in"; idl = LIST1 id_or_meta -> { idl }
+ | -> { [] } ] ]
;
in_hyp_as:
- [ [ "in"; id = id_or_meta; ipat = as_ipat -> Some (id,ipat)
- | -> None ] ]
+ [ [ "in"; id = id_or_meta; ipat = as_ipat -> { Some (id,ipat) }
+ | -> { None } ] ]
;
orient:
- [ [ "->" -> true
- | "<-" -> false
- | -> true ]]
+ [ [ "->" -> { true }
+ | "<-" -> { false }
+ | -> { true } ] ]
;
simple_binder:
- [ [ na=name -> ([na],Default Explicit, CAst.make ~loc:!@loc @@
- CHole (Some (Evar_kinds.BinderType na.CAst.v), IntroAnonymous, None))
- | "("; nal=LIST1 name; ":"; c=lconstr; ")" -> (nal,Default Explicit,c)
+ [ [ na=name -> { ([na],Default Explicit, CAst.make ~loc @@
+ CHole (Some (Evar_kinds.BinderType na.CAst.v), IntroAnonymous, None)) }
+ | "("; nal=LIST1 name; ":"; c=lconstr; ")" -> { (nal,Default Explicit,c) }
] ]
;
fixdecl:
[ [ "("; id = ident; bl=LIST0 simple_binder; ann=fixannot;
- ":"; ty=lconstr; ")" -> (!@loc, id, bl, ann, ty) ] ]
+ ":"; ty=lconstr; ")" -> { (loc, id, bl, ann, ty) } ] ]
;
fixannot:
- [ [ "{"; IDENT "struct"; id=name; "}" -> Some id
- | -> None ] ]
+ [ [ "{"; IDENT "struct"; id=name; "}" -> { Some id }
+ | -> { None } ] ]
;
cofixdecl:
[ [ "("; id = ident; bl=LIST0 simple_binder; ":"; ty=lconstr; ")" ->
- (!@loc, id, bl, None, ty) ] ]
+ { (loc, id, bl, None, ty) } ] ]
;
bindings_with_parameters:
[ [ check_for_coloneq; "("; id = ident; bl = LIST0 simple_binder;
- ":="; c = lconstr; ")" -> (id, mkCLambdaN_simple bl c) ] ]
+ ":="; c = lconstr; ")" -> { (id, mkCLambdaN_simple bl c) } ] ]
;
eliminator:
- [ [ "using"; el = constr_with_bindings -> el ] ]
+ [ [ "using"; el = constr_with_bindings -> { el } ] ]
;
as_ipat:
- [ [ "as"; ipat = simple_intropattern -> Some ipat
- | -> None ] ]
+ [ [ "as"; ipat = simple_intropattern -> { Some ipat }
+ | -> { None } ] ]
;
or_and_intropattern_loc:
- [ [ ipat = or_and_intropattern -> ArgArg (CAst.make ~loc:!@loc ipat)
- | locid = identref -> ArgVar locid ] ]
+ [ [ ipat = or_and_intropattern -> { ArgArg (CAst.make ~loc ipat) }
+ | locid = identref -> { ArgVar locid } ] ]
;
as_or_and_ipat:
- [ [ "as"; ipat = or_and_intropattern_loc -> Some ipat
- | -> None ] ]
+ [ [ "as"; ipat = or_and_intropattern_loc -> { Some ipat }
+ | -> { None } ] ]
;
eqn_ipat:
- [ [ IDENT "eqn"; ":"; pat = naming_intropattern -> Some (CAst.make ~loc:!@loc pat)
+ [ [ IDENT "eqn"; ":"; pat = naming_intropattern -> { Some (CAst.make ~loc pat) }
| IDENT "_eqn"; ":"; pat = naming_intropattern ->
- let loc = !@loc in
- warn_deprecated_eqn_syntax ~loc "H"; Some (CAst.make ~loc pat)
+ { warn_deprecated_eqn_syntax ~loc "H"; Some (CAst.make ~loc pat) }
| IDENT "_eqn" ->
- let loc = !@loc in
- warn_deprecated_eqn_syntax ~loc "?"; Some (CAst.make ~loc IntroAnonymous)
- | -> None ] ]
+ { warn_deprecated_eqn_syntax ~loc "?"; Some (CAst.make ~loc IntroAnonymous) }
+ | -> { None } ] ]
;
as_name:
- [ [ "as"; id = ident ->Names.Name.Name id | -> Names.Name.Anonymous ] ]
+ [ [ "as"; id = ident -> { Names.Name.Name id } | -> { Names.Name.Anonymous } ] ]
;
by_tactic:
- [ [ "by"; tac = tactic_expr LEVEL "3" -> Some tac
- | -> None ] ]
+ [ [ "by"; tac = tactic_expr LEVEL "3" -> { Some tac }
+ | -> { None } ] ]
;
rewriter :
- [ [ "!"; c = constr_with_bindings_arg -> (RepeatPlus,c)
- | ["?"| LEFTQMARK]; c = constr_with_bindings_arg -> (RepeatStar,c)
- | n = natural; "!"; c = constr_with_bindings_arg -> (Precisely n,c)
- | n = natural; ["?" | LEFTQMARK]; c = constr_with_bindings_arg -> (UpTo n,c)
- | n = natural; c = constr_with_bindings_arg -> (Precisely n,c)
- | c = constr_with_bindings_arg -> (Precisely 1, c)
+ [ [ "!"; c = constr_with_bindings_arg -> { (Equality.RepeatPlus,c) }
+ | ["?" -> { () } | LEFTQMARK -> { () } ]; c = constr_with_bindings_arg -> { (Equality.RepeatStar,c) }
+ | n = natural; "!"; c = constr_with_bindings_arg -> { (Equality.Precisely n,c) }
+ | n = natural; ["?" -> { () } | LEFTQMARK -> { () } ]; c = constr_with_bindings_arg -> { (Equality.UpTo n,c) }
+ | n = natural; c = constr_with_bindings_arg -> { (Equality.Precisely n,c) }
+ | c = constr_with_bindings_arg -> { (Equality.Precisely 1, c) }
] ]
;
oriented_rewriter :
- [ [ b = orient; p = rewriter -> let (m,c) = p in (b,m,c) ] ]
+ [ [ b = orient; p = rewriter -> { let (m,c) = p in (b,m,c) } ] ]
;
induction_clause:
[ [ c = destruction_arg; pat = as_or_and_ipat; eq = eqn_ipat;
- cl = opt_clause -> (c,(eq,pat),cl) ] ]
+ cl = opt_clause -> { (c,(eq,pat),cl) } ] ]
;
induction_clause_list:
[ [ ic = LIST1 induction_clause SEP ","; el = OPT eliminator;
cl_tolerance = opt_clause ->
(* Condition for accepting "in" at the end by compatibility *)
- match ic,el,cl_tolerance with
+ { match ic,el,cl_tolerance with
| [c,pat,None],Some _,Some _ -> ([c,pat,cl_tolerance],el)
| _,_,Some _ -> err ()
- | _,_,None -> (ic,el) ]]
+ | _,_,None -> (ic,el) } ] ]
;
simple_tactic:
[ [
(* Basic tactics *)
IDENT "intros"; pl = ne_intropatterns ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacIntroPattern (false,pl))
+ { TacAtom (Loc.tag ~loc @@ TacIntroPattern (false,pl)) }
| IDENT "intros" ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacIntroPattern (false,[CAst.make ~loc:!@loc @@IntroForthcoming false]))
+ { TacAtom (Loc.tag ~loc @@ TacIntroPattern (false,[CAst.make ~loc @@IntroForthcoming false])) }
| IDENT "eintros"; pl = ne_intropatterns ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacIntroPattern (true,pl))
+ { TacAtom (Loc.tag ~loc @@ TacIntroPattern (true,pl)) }
| IDENT "apply"; cl = LIST1 constr_with_bindings_arg SEP ",";
- inhyp = in_hyp_as -> TacAtom (Loc.tag ~loc:!@loc @@ TacApply (true,false,cl,inhyp))
+ inhyp = in_hyp_as -> { TacAtom (Loc.tag ~loc @@ TacApply (true,false,cl,inhyp)) }
| IDENT "eapply"; cl = LIST1 constr_with_bindings_arg SEP ",";
- inhyp = in_hyp_as -> TacAtom (Loc.tag ~loc:!@loc @@ TacApply (true,true,cl,inhyp))
+ inhyp = in_hyp_as -> { TacAtom (Loc.tag ~loc @@ TacApply (true,true,cl,inhyp)) }
| IDENT "simple"; IDENT "apply";
cl = LIST1 constr_with_bindings_arg SEP ",";
- inhyp = in_hyp_as -> TacAtom (Loc.tag ~loc:!@loc @@ TacApply (false,false,cl,inhyp))
+ inhyp = in_hyp_as -> { TacAtom (Loc.tag ~loc @@ TacApply (false,false,cl,inhyp)) }
| IDENT "simple"; IDENT "eapply";
cl = LIST1 constr_with_bindings_arg SEP",";
- inhyp = in_hyp_as -> TacAtom (Loc.tag ~loc:!@loc @@ TacApply (false,true,cl,inhyp))
+ inhyp = in_hyp_as -> { TacAtom (Loc.tag ~loc @@ TacApply (false,true,cl,inhyp)) }
| IDENT "elim"; cl = constr_with_bindings_arg; el = OPT eliminator ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacElim (false,cl,el))
+ { TacAtom (Loc.tag ~loc @@ TacElim (false,cl,el)) }
| IDENT "eelim"; cl = constr_with_bindings_arg; el = OPT eliminator ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacElim (true,cl,el))
- | IDENT "case"; icl = induction_clause_list -> TacAtom (Loc.tag ~loc:!@loc @@ mkTacCase false icl)
- | IDENT "ecase"; icl = induction_clause_list -> TacAtom (Loc.tag ~loc:!@loc @@ mkTacCase true icl)
+ { TacAtom (Loc.tag ~loc @@ TacElim (true,cl,el)) }
+ | IDENT "case"; icl = induction_clause_list -> { TacAtom (Loc.tag ~loc @@ mkTacCase false icl) }
+ | IDENT "ecase"; icl = induction_clause_list -> { TacAtom (Loc.tag ~loc @@ mkTacCase true icl) }
| "fix"; id = ident; n = natural; "with"; fd = LIST1 fixdecl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacMutualFix (id,n,List.map mk_fix_tac fd))
+ { TacAtom (Loc.tag ~loc @@ TacMutualFix (id,n,List.map mk_fix_tac fd)) }
| "cofix"; id = ident; "with"; fd = LIST1 cofixdecl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacMutualCofix (id,List.map mk_cofix_tac fd))
+ { TacAtom (Loc.tag ~loc @@ TacMutualCofix (id,List.map mk_cofix_tac fd)) }
- | IDENT "pose"; (id,b) = bindings_with_parameters ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (false,Names.Name.Name id,b,Locusops.nowhere,true,None))
+ | IDENT "pose"; bl = bindings_with_parameters ->
+ { let (id,b) = bl in TacAtom (Loc.tag ~loc @@ TacLetTac (false,Names.Name.Name id,b,Locusops.nowhere,true,None)) }
| IDENT "pose"; b = constr; na = as_name ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (false,na,b,Locusops.nowhere,true,None))
- | IDENT "epose"; (id,b) = bindings_with_parameters ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (true,Names.Name id,b,Locusops.nowhere,true,None))
+ { TacAtom (Loc.tag ~loc @@ TacLetTac (false,na,b,Locusops.nowhere,true,None)) }
+ | IDENT "epose"; bl = bindings_with_parameters ->
+ { let (id,b) = bl in TacAtom (Loc.tag ~loc @@ TacLetTac (true,Names.Name id,b,Locusops.nowhere,true,None)) }
| IDENT "epose"; b = constr; na = as_name ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (true,na,b,Locusops.nowhere,true,None))
- | IDENT "set"; (id,c) = bindings_with_parameters; p = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (false,Names.Name.Name id,c,p,true,None))
+ { TacAtom (Loc.tag ~loc @@ TacLetTac (true,na,b,Locusops.nowhere,true,None)) }
+ | IDENT "set"; bl = bindings_with_parameters; p = clause_dft_concl ->
+ { let (id,c) = bl in TacAtom (Loc.tag ~loc @@ TacLetTac (false,Names.Name.Name id,c,p,true,None)) }
| IDENT "set"; c = constr; na = as_name; p = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (false,na,c,p,true,None))
- | IDENT "eset"; (id,c) = bindings_with_parameters; p = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (true,Names.Name id,c,p,true,None))
+ { TacAtom (Loc.tag ~loc @@ TacLetTac (false,na,c,p,true,None)) }
+ | IDENT "eset"; bl = bindings_with_parameters; p = clause_dft_concl ->
+ { let (id,c) = bl in TacAtom (Loc.tag ~loc @@ TacLetTac (true,Names.Name id,c,p,true,None)) }
| IDENT "eset"; c = constr; na = as_name; p = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (true,na,c,p,true,None))
+ { TacAtom (Loc.tag ~loc @@ TacLetTac (true,na,c,p,true,None)) }
| IDENT "remember"; c = constr; na = as_name; e = eqn_ipat;
p = clause_dft_all ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (false,na,c,p,false,e))
+ { TacAtom (Loc.tag ~loc @@ TacLetTac (false,na,c,p,false,e)) }
| IDENT "eremember"; c = constr; na = as_name; e = eqn_ipat;
p = clause_dft_all ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacLetTac (true,na,c,p,false,e))
+ { TacAtom (Loc.tag ~loc @@ TacLetTac (true,na,c,p,false,e)) }
(* Alternative syntax for "pose proof c as id" *)
| IDENT "assert"; test_lpar_id_coloneq; "("; lid = identref; ":=";
c = lconstr; ")" ->
- let { CAst.loc = loc; v = id } = lid in
- TacAtom (Loc.tag ?loc @@ TacAssert (false,true,None,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c))
+ { let { CAst.loc = loc; v = id } = lid in
+ TacAtom (Loc.tag ?loc @@ TacAssert (false,true,None,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c)) }
| IDENT "eassert"; test_lpar_id_coloneq; "("; lid = identref; ":=";
c = lconstr; ")" ->
- let { CAst.loc = loc; v = id } = lid in
- TacAtom (Loc.tag ?loc @@ TacAssert (true,true,None,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c))
+ { let { CAst.loc = loc; v = id } = lid in
+ TacAtom (Loc.tag ?loc @@ TacAssert (true,true,None,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c)) }
(* Alternative syntax for "assert c as id by tac" *)
| IDENT "assert"; test_lpar_id_colon; "("; lid = identref; ":";
c = lconstr; ")"; tac=by_tactic ->
- let { CAst.loc = loc; v = id } = lid in
- TacAtom (Loc.tag ?loc @@ TacAssert (false,true,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c))
+ { let { CAst.loc = loc; v = id } = lid in
+ TacAtom (Loc.tag ?loc @@ TacAssert (false,true,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c)) }
| IDENT "eassert"; test_lpar_id_colon; "("; lid = identref; ":";
c = lconstr; ")"; tac=by_tactic ->
- let { CAst.loc = loc; v = id } = lid in
- TacAtom (Loc.tag ?loc @@ TacAssert (true,true,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c))
+ { let { CAst.loc = loc; v = id } = lid in
+ TacAtom (Loc.tag ?loc @@ TacAssert (true,true,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c)) }
(* Alternative syntax for "enough c as id by tac" *)
| IDENT "enough"; test_lpar_id_colon; "("; lid = identref; ":";
c = lconstr; ")"; tac=by_tactic ->
- let { CAst.loc = loc; v = id } = lid in
- TacAtom (Loc.tag ?loc @@ TacAssert (false,false,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c))
+ { let { CAst.loc = loc; v = id } = lid in
+ TacAtom (Loc.tag ?loc @@ TacAssert (false,false,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c)) }
| IDENT "eenough"; test_lpar_id_colon; "("; lid = identref; ":";
c = lconstr; ")"; tac=by_tactic ->
- let { CAst.loc = loc; v = id } = lid in
- TacAtom (Loc.tag ?loc @@ TacAssert (true,false,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c))
+ { let { CAst.loc = loc; v = id } = lid in
+ TacAtom (Loc.tag ?loc @@ TacAssert (true,false,Some tac,Some (CAst.make ?loc @@ IntroNaming (IntroIdentifier id)),c)) }
| IDENT "assert"; c = constr; ipat = as_ipat; tac = by_tactic ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacAssert (false,true,Some tac,ipat,c))
+ { TacAtom (Loc.tag ~loc @@ TacAssert (false,true,Some tac,ipat,c)) }
| IDENT "eassert"; c = constr; ipat = as_ipat; tac = by_tactic ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacAssert (true,true,Some tac,ipat,c))
+ { TacAtom (Loc.tag ~loc @@ TacAssert (true,true,Some tac,ipat,c)) }
| IDENT "pose"; IDENT "proof"; c = lconstr; ipat = as_ipat ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacAssert (false,true,None,ipat,c))
+ { TacAtom (Loc.tag ~loc @@ TacAssert (false,true,None,ipat,c)) }
| IDENT "epose"; IDENT "proof"; c = lconstr; ipat = as_ipat ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacAssert (true,true,None,ipat,c))
+ { TacAtom (Loc.tag ~loc @@ TacAssert (true,true,None,ipat,c)) }
| IDENT "enough"; c = constr; ipat = as_ipat; tac = by_tactic ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacAssert (false,false,Some tac,ipat,c))
+ { TacAtom (Loc.tag ~loc @@ TacAssert (false,false,Some tac,ipat,c)) }
| IDENT "eenough"; c = constr; ipat = as_ipat; tac = by_tactic ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacAssert (true,false,Some tac,ipat,c))
+ { TacAtom (Loc.tag ~loc @@ TacAssert (true,false,Some tac,ipat,c)) }
| IDENT "generalize"; c = constr ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacGeneralize [((AllOccurrences,c),Names.Name.Anonymous)])
+ { TacAtom (Loc.tag ~loc @@ TacGeneralize [((AllOccurrences,c),Names.Name.Anonymous)]) }
| IDENT "generalize"; c = constr; l = LIST1 constr ->
- let gen_everywhere c = ((AllOccurrences,c),Names.Name.Anonymous) in
- TacAtom (Loc.tag ~loc:!@loc @@ TacGeneralize (List.map gen_everywhere (c::l)))
+ { let gen_everywhere c = ((AllOccurrences,c),Names.Name.Anonymous) in
+ TacAtom (Loc.tag ~loc @@ TacGeneralize (List.map gen_everywhere (c::l))) }
| IDENT "generalize"; c = constr; lookup_at_as_comma; nl = occs;
na = as_name;
- l = LIST0 [","; c = pattern_occ; na = as_name -> (c,na)] ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacGeneralize (((nl,c),na)::l))
+ l = LIST0 [","; c = pattern_occ; na = as_name -> { (c,na) } ] ->
+ { TacAtom (Loc.tag ~loc @@ TacGeneralize (((nl,c),na)::l)) }
(* Derived basic tactics *)
| IDENT "induction"; ic = induction_clause_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInductionDestruct (true,false,ic))
+ { TacAtom (Loc.tag ~loc @@ TacInductionDestruct (true,false,ic)) }
| IDENT "einduction"; ic = induction_clause_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInductionDestruct(true,true,ic))
+ { TacAtom (Loc.tag ~loc @@ TacInductionDestruct(true,true,ic)) }
| IDENT "destruct"; icl = induction_clause_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInductionDestruct(false,false,icl))
+ { TacAtom (Loc.tag ~loc @@ TacInductionDestruct(false,false,icl)) }
| IDENT "edestruct"; icl = induction_clause_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInductionDestruct(false,true,icl))
+ { TacAtom (Loc.tag ~loc @@ TacInductionDestruct(false,true,icl)) }
(* Equality and inversion *)
| IDENT "rewrite"; l = LIST1 oriented_rewriter SEP ",";
- cl = clause_dft_concl; t=by_tactic -> TacAtom (Loc.tag ~loc:!@loc @@ TacRewrite (false,l,cl,t))
+ cl = clause_dft_concl; t=by_tactic -> { TacAtom (Loc.tag ~loc @@ TacRewrite (false,l,cl,t)) }
| IDENT "erewrite"; l = LIST1 oriented_rewriter SEP ",";
- cl = clause_dft_concl; t=by_tactic -> TacAtom (Loc.tag ~loc:!@loc @@ TacRewrite (true,l,cl,t))
+ cl = clause_dft_concl; t=by_tactic -> { TacAtom (Loc.tag ~loc @@ TacRewrite (true,l,cl,t)) }
| IDENT "dependent"; k =
- [ IDENT "simple"; IDENT "inversion" -> SimpleInversion
- | IDENT "inversion" -> FullInversion
- | IDENT "inversion_clear" -> FullInversionClear ];
+ [ IDENT "simple"; IDENT "inversion" -> { SimpleInversion }
+ | IDENT "inversion" -> { FullInversion }
+ | IDENT "inversion_clear" -> { FullInversionClear } ];
hyp = quantified_hypothesis;
- ids = as_or_and_ipat; co = OPT ["with"; c = constr -> c] ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInversion (DepInversion (k,co,ids),hyp))
+ ids = as_or_and_ipat; co = OPT ["with"; c = constr -> { c } ] ->
+ { TacAtom (Loc.tag ~loc @@ TacInversion (DepInversion (k,co,ids),hyp)) }
| IDENT "simple"; IDENT "inversion";
hyp = quantified_hypothesis; ids = as_or_and_ipat;
cl = in_hyp_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInversion (NonDepInversion (SimpleInversion, cl, ids), hyp))
+ { TacAtom (Loc.tag ~loc @@ TacInversion (NonDepInversion (SimpleInversion, cl, ids), hyp)) }
| IDENT "inversion";
hyp = quantified_hypothesis; ids = as_or_and_ipat;
cl = in_hyp_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInversion (NonDepInversion (FullInversion, cl, ids), hyp))
+ { TacAtom (Loc.tag ~loc @@ TacInversion (NonDepInversion (FullInversion, cl, ids), hyp)) }
| IDENT "inversion_clear";
hyp = quantified_hypothesis; ids = as_or_and_ipat;
cl = in_hyp_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInversion (NonDepInversion (FullInversionClear, cl, ids), hyp))
+ { TacAtom (Loc.tag ~loc @@ TacInversion (NonDepInversion (FullInversionClear, cl, ids), hyp)) }
| IDENT "inversion"; hyp = quantified_hypothesis;
"using"; c = constr; cl = in_hyp_list ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacInversion (InversionUsing (c,cl), hyp))
+ { TacAtom (Loc.tag ~loc @@ TacInversion (InversionUsing (c,cl), hyp)) }
(* Conversion *)
| IDENT "red"; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Red false, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Red false, cl)) }
| IDENT "hnf"; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Hnf, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Hnf, cl)) }
| IDENT "simpl"; d = delta_flag; po = OPT ref_or_pattern_occ; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Simpl (all_with d, po), cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Simpl (all_with d, po), cl)) }
| IDENT "cbv"; s = strategy_flag; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Cbv s, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Cbv s, cl)) }
| IDENT "cbn"; s = strategy_flag; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Cbn s, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Cbn s, cl)) }
| IDENT "lazy"; s = strategy_flag; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Lazy s, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Lazy s, cl)) }
| IDENT "compute"; delta = delta_flag; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Cbv (all_with delta), cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Cbv (all_with delta), cl)) }
| IDENT "vm_compute"; po = OPT ref_or_pattern_occ; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (CbvVm po, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (CbvVm po, cl)) }
| IDENT "native_compute"; po = OPT ref_or_pattern_occ; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (CbvNative po, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (CbvNative po, cl)) }
| IDENT "unfold"; ul = LIST1 unfold_occ SEP ","; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Unfold ul, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Unfold ul, cl)) }
| IDENT "fold"; l = LIST1 constr; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Fold l, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Fold l, cl)) }
| IDENT "pattern"; pl = LIST1 pattern_occ SEP","; cl = clause_dft_concl ->
- TacAtom (Loc.tag ~loc:!@loc @@ TacReduce (Pattern pl, cl))
+ { TacAtom (Loc.tag ~loc @@ TacReduce (Pattern pl, cl)) }
(* Change ne doit pas s'appliquer dans un Definition t := Eval ... *)
- | IDENT "change"; (oc,c) = conversion; cl = clause_dft_concl ->
- let p,cl = merge_occurrences (!@loc) cl oc in
- TacAtom (Loc.tag ~loc:!@loc @@ TacChange (p,c,cl))
+ | IDENT "change"; c = conversion; cl = clause_dft_concl ->
+ { let (oc, c) = c in
+ let p,cl = merge_occurrences loc cl oc in
+ TacAtom (Loc.tag ~loc @@ TacChange (p,c,cl)) }
] ]
;
-END;;
+END
diff --git a/plugins/ltac/pltac.ml b/plugins/ltac/pltac.ml
index e9711268..759bb62f 100644
--- a/plugins/ltac/pltac.ml
+++ b/plugins/ltac/pltac.ml
@@ -11,11 +11,10 @@
open Pcoq
(* Main entry for extensions *)
-let simple_tactic = Gram.entry_create "tactic:simple_tactic"
+let simple_tactic = Entry.create "tactic:simple_tactic"
-let make_gen_entry _ name = Gram.entry_create ("tactic:" ^ name)
+let make_gen_entry _ name = Entry.create ("tactic:" ^ name)
-(* Entries that can be referred via the string -> Gram.entry table *)
(* Typically for tactic user extensions *)
let open_constr =
make_gen_entry utactic "open_constr"
@@ -23,7 +22,7 @@ let constr_with_bindings =
make_gen_entry utactic "constr_with_bindings"
let bindings =
make_gen_entry utactic "bindings"
-let hypident = Gram.entry_create "hypident"
+let hypident = Entry.create "hypident"
let constr_may_eval = make_gen_entry utactic "constr_may_eval"
let constr_eval = make_gen_entry utactic "constr_eval"
let uconstr =
@@ -40,7 +39,7 @@ let clause_dft_concl =
(* Main entries for ltac *)
-let tactic_arg = Gram.entry_create "tactic:tactic_arg"
+let tactic_arg = Entry.create "tactic:tactic_arg"
let tactic_expr = make_gen_entry utactic "tactic_expr"
let binder_tactic = make_gen_entry utactic "binder_tactic"
diff --git a/plugins/ltac/pltac.mli b/plugins/ltac/pltac.mli
index 6637de74..9bff98b6 100644
--- a/plugins/ltac/pltac.mli
+++ b/plugins/ltac/pltac.mli
@@ -15,24 +15,24 @@ open Libnames
open Constrexpr
open Tacexpr
open Genredexpr
-open Misctypes
+open Tactypes
-val open_constr : constr_expr Gram.entry
-val constr_with_bindings : constr_expr with_bindings Gram.entry
-val bindings : constr_expr bindings Gram.entry
-val hypident : (lident * Locus.hyp_location_flag) Gram.entry
-val constr_may_eval : (constr_expr,reference or_by_notation,constr_expr) may_eval Gram.entry
-val constr_eval : (constr_expr,reference or_by_notation,constr_expr) may_eval Gram.entry
-val uconstr : constr_expr Gram.entry
-val quantified_hypothesis : quantified_hypothesis Gram.entry
-val destruction_arg : constr_expr with_bindings destruction_arg Gram.entry
-val int_or_var : int or_var Gram.entry
-val simple_tactic : raw_tactic_expr Gram.entry
-val simple_intropattern : constr_expr intro_pattern_expr CAst.t Gram.entry
-val in_clause : lident Locus.clause_expr Gram.entry
-val clause_dft_concl : lident Locus.clause_expr Gram.entry
-val tactic_arg : raw_tactic_arg Gram.entry
-val tactic_expr : raw_tactic_expr Gram.entry
-val binder_tactic : raw_tactic_expr Gram.entry
-val tactic : raw_tactic_expr Gram.entry
-val tactic_eoi : raw_tactic_expr Gram.entry
+val open_constr : constr_expr Entry.t
+val constr_with_bindings : constr_expr with_bindings Entry.t
+val bindings : constr_expr bindings Entry.t
+val hypident : (Names.lident * Locus.hyp_location_flag) Entry.t
+val constr_may_eval : (constr_expr,qualid or_by_notation,constr_expr) may_eval Entry.t
+val constr_eval : (constr_expr,qualid or_by_notation,constr_expr) may_eval Entry.t
+val uconstr : constr_expr Entry.t
+val quantified_hypothesis : quantified_hypothesis Entry.t
+val destruction_arg : constr_expr with_bindings Tactics.destruction_arg Entry.t
+val int_or_var : int Locus.or_var Entry.t
+val simple_tactic : raw_tactic_expr Entry.t
+val simple_intropattern : constr_expr intro_pattern_expr CAst.t Entry.t
+val in_clause : Names.lident Locus.clause_expr Entry.t
+val clause_dft_concl : Names.lident Locus.clause_expr Entry.t
+val tactic_arg : raw_tactic_arg Entry.t
+val tactic_expr : raw_tactic_expr Entry.t
+val binder_tactic : raw_tactic_expr Entry.t
+val tactic : raw_tactic_expr Entry.t
+val tactic_eoi : raw_tactic_expr Entry.t
diff --git a/plugins/ltac/pptactic.ml b/plugins/ltac/pptactic.ml
index 11bb7a23..b219ee25 100644
--- a/plugins/ltac/pptactic.ml
+++ b/plugins/ltac/pptactic.ml
@@ -17,9 +17,8 @@ open Constrexpr
open Genarg
open Geninterp
open Stdarg
-open Libnames
-open Notation_term
-open Misctypes
+open Notation_gram
+open Tactypes
open Locus
open Decl_kinds
open Genredexpr
@@ -29,6 +28,7 @@ open Printer
open Tacexpr
open Tacarg
+open Tactics
module Tag =
struct
@@ -116,7 +116,7 @@ let string_of_genarg_arg (ArgumentType arg) =
let keyword x = tag_keyword (str x)
let primitive x = tag_primitive (str x)
- let has_type (Val.Dyn (tag, x)) t = match Val.eq tag t with
+ let has_type (Val.Dyn (tag, _)) t = match Val.eq tag t with
| None -> false
| Some _ -> true
@@ -149,9 +149,12 @@ let string_of_genarg_arg (ArgumentType arg) =
let open Genprint in
match generic_top_print (in_gen (Topwit wit) x) with
| TopPrinterBasic pr -> pr ()
- | TopPrinterNeedsContext pr -> pr (Global.env()) Evd.empty
+ | TopPrinterNeedsContext pr ->
+ let env = Global.env() in
+ pr env (Evd.from_env env)
| TopPrinterNeedsContextAndLevel { default_ensure_surrounded; printer } ->
- printer (Global.env()) Evd.empty default_ensure_surrounded
+ let env = Global.env() in
+ printer env (Evd.from_env env) default_ensure_surrounded
end
| _ -> default
@@ -186,7 +189,7 @@ let string_of_genarg_arg (ArgumentType arg) =
| AN v -> f v
| ByNotation (s,sc) -> qs s ++ pr_opt (fun sc -> str "%" ++ str sc) sc)
- let pr_located pr (loc,x) = pr x
+ let pr_located pr (_,x) = pr x
let pr_evaluable_reference = function
| EvalVarRef id -> pr_id id
@@ -238,7 +241,7 @@ let string_of_genarg_arg (ArgumentType arg) =
in
pr_sequence (fun x -> x) l
- let pr_extend_gen pr_gen lev { mltac_name = s; mltac_index = i } l =
+ let pr_extend_gen pr_gen _ { mltac_name = s; mltac_index = i } l =
let name =
str s.mltac_plugin ++ str "::" ++ str s.mltac_tactic ++
str "@" ++ int i
@@ -258,7 +261,7 @@ let string_of_genarg_arg (ArgumentType arg) =
| Extend.Uentry tag ->
let ArgT.Any tag = tag in
ArgT.repr tag
- | Extend.Uentryl (tkn, lvl) -> "tactic" ^ string_of_int lvl
+ | Extend.Uentryl (_, lvl) -> "tactic" ^ string_of_int lvl
let pr_alias_key key =
try
@@ -269,6 +272,8 @@ let string_of_genarg_arg (ArgumentType arg) =
in
pr_sequence pr prods
with Not_found ->
+ (* FIXME: This key, moreover printed with a low-level printer,
+ has no meaning user-side *)
KerName.print key
let pr_alias_gen pr_gen lev key l =
@@ -286,7 +291,7 @@ let string_of_genarg_arg (ArgumentType arg) =
let p = pr_tacarg_using_rule pr_gen prods in
if pp.pptac_level > lev then surround p else p
with Not_found ->
- let pr arg = str "_" in
+ let pr _ = str "_" in
KerName.print key ++ spc() ++ pr_sequence pr l ++ str" (* Generic printer *)"
let pr_farg prtac arg = prtac (1, Any) (TacArg (Loc.tag arg))
@@ -339,14 +344,14 @@ let string_of_genarg_arg (ArgumentType arg) =
pr_any_arg pr symb arg
| _ -> str "ltac:(" ++ prtac (1, Any) arg ++ str ")"
- let pr_raw_extend_rec prc prlc prtac prpat =
+ let pr_raw_extend_rec prtac =
pr_extend_gen (pr_farg prtac)
- let pr_glob_extend_rec prc prlc prtac prpat =
+ let pr_glob_extend_rec prtac =
pr_extend_gen (pr_farg prtac)
- let pr_raw_alias prc prlc prtac prpat lev key args =
+ let pr_raw_alias prtac lev key args =
pr_alias_gen (pr_targ (fun l a -> prtac l (TacArg (Loc.tag a)))) lev key args
- let pr_glob_alias prc prlc prtac prpat lev key args =
+ let pr_glob_alias prtac lev key args =
pr_alias_gen (pr_targ (fun l a -> prtac l (TacArg (Loc.tag a)))) lev key args
(**********************************************************************)
@@ -490,7 +495,7 @@ let string_of_genarg_arg (ArgumentType arg) =
let pr_orient b = if b then mt () else str "<- "
- let pr_multi = function
+ let pr_multi = let open Equality in function
| Precisely 1 -> mt ()
| Precisely n -> int n ++ str "!"
| UpTo n -> int n ++ str "?"
@@ -505,7 +510,7 @@ let string_of_genarg_arg (ArgumentType arg) =
let pr_destruction_arg prc prlc (clear_flag,h) =
pr_clear_flag clear_flag (pr_core_destruction_arg prc prlc) h
- let pr_inversion_kind = function
+ let pr_inversion_kind = let open Inv in function
| SimpleInversion -> primitive "simple inversion"
| FullInversion -> primitive "inversion"
| FullInversionClear -> primitive "inversion_clear"
@@ -514,7 +519,8 @@ let string_of_genarg_arg (ArgumentType arg) =
if Int.equal i j then int i
else int i ++ str "-" ++ int j
-let pr_goal_selector toplevel = function
+let pr_goal_selector toplevel = let open Goal_select in function
+ | SelectAlreadyFocused -> str "!:"
| SelectNth i -> int i ++ str ":"
| SelectList l -> prlist_with_sep (fun () -> str ", ") pr_range_selector l ++ str ":"
| SelectId id -> str "[" ++ Id.print id ++ str "]:"
@@ -740,12 +746,12 @@ let pr_goal_selector ~toplevel s =
(* Main tactic printer *)
and pr_atom1 a = tag_atom a (match a with
(* Basic tactics *)
- | TacIntroPattern (ev,[]) as t ->
+ | TacIntroPattern (_,[]) as t ->
pr_atom0 t
| TacIntroPattern (ev,(_::_ as p)) ->
hov 1 (primitive (if ev then "eintros" else "intros") ++
(match p with
- | [{CAst.v=Misctypes.IntroForthcoming false}] -> mt ()
+ | [{CAst.v=IntroForthcoming false}] -> mt ()
| _ -> spc () ++ prlist_with_sep spc (Miscprint.pr_intro_pattern pr.pr_dconstr) p))
| TacApply (a,ev,cb,inhyp) ->
hov 1 (
@@ -1051,7 +1057,7 @@ let pr_goal_selector ~toplevel s =
primitive "fresh" ++ pr_fresh_ids l, latom
| TacArg(_,TacGeneric arg) ->
pr.pr_generic arg, latom
- | TacArg(_,TacCall(loc,(f,[]))) ->
+ | TacArg(_,TacCall(_,(f,[]))) ->
pr.pr_reference f, latom
| TacArg(_,TacCall(loc,(f,l))) ->
pr_with_comments ?loc (hov 1 (
@@ -1105,12 +1111,12 @@ let pr_goal_selector ~toplevel s =
pr_lconstr = pr_lconstr_expr;
pr_pattern = pr_constr_pattern_expr;
pr_lpattern = pr_lconstr_pattern_expr;
- pr_constant = pr_or_by_notation pr_reference;
- pr_reference = pr_reference;
+ pr_constant = pr_or_by_notation pr_qualid;
+ pr_reference = pr_qualid;
pr_name = pr_lident;
pr_generic = (fun arg -> Pputils.pr_raw_generic (Global.env ()) arg);
- pr_extend = pr_raw_extend_rec pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr;
- pr_alias = pr_raw_alias pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr;
+ pr_extend = pr_raw_extend_rec pr_raw_tactic_level;
+ pr_alias = pr_raw_alias pr_raw_tactic_level;
} in
make_pr_tac
pr raw_printers
@@ -1139,12 +1145,8 @@ let pr_goal_selector ~toplevel s =
pr_reference = pr_ltac_or_var (pr_located pr_ltac_constant);
pr_name = pr_lident;
pr_generic = (fun arg -> Pputils.pr_glb_generic (Global.env ()) arg);
- pr_extend = pr_glob_extend_rec
- (pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
- prtac (pr_pat_and_constr_expr (pr_glob_constr_env env));
- pr_alias = pr_glob_alias
- (pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
- prtac (pr_pat_and_constr_expr (pr_glob_constr_env env));
+ pr_extend = pr_glob_extend_rec prtac;
+ pr_alias = pr_glob_alias prtac;
} in
make_pr_tac
pr glob_printers
@@ -1165,8 +1167,8 @@ let pr_goal_selector ~toplevel s =
| _ -> user_err Pp.(str "Cannot translate fix tactic: not enough products") in
strip_ty [] n ty
- let pr_atomic_tactic_level env sigma n t =
- let prtac n (t:atomic_tactic_expr) =
+ let pr_atomic_tactic_level env sigma t =
+ let prtac (t:atomic_tactic_expr) =
let pr = {
pr_tactic = (fun _ _ -> str "<tactic>");
pr_constr = (fun c -> pr_econstr_env env sigma c);
@@ -1185,18 +1187,15 @@ let pr_goal_selector ~toplevel s =
in
pr_atom pr strip_prod_binders_constr tag_atomic_tactic_expr t
in
- prtac n t
+ prtac t
let pr_raw_generic = Pputils.pr_raw_generic
let pr_glb_generic = Pputils.pr_glb_generic
- let pr_raw_extend env = pr_raw_extend_rec
- pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr
+ let pr_raw_extend _ = pr_raw_extend_rec pr_raw_tactic_level
- let pr_glob_extend env = pr_glob_extend_rec
- (pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
- (pr_glob_tactic_level env) (pr_pat_and_constr_expr (pr_glob_constr_env env))
+ let pr_glob_extend env = pr_glob_extend_rec (pr_glob_tactic_level env)
let pr_alias pr lev key args =
pr_alias_gen (fun _ arg -> pr arg) lev key args
@@ -1204,14 +1203,14 @@ let pr_goal_selector ~toplevel s =
let pr_extend pr lev ml args =
pr_extend_gen pr lev ml args
- let pr_atomic_tactic env sigma c = pr_atomic_tactic_level env sigma ltop c
+ let pr_atomic_tactic env sigma c = pr_atomic_tactic_level env sigma c
let declare_extra_genarg_pprule wit
(f : 'a raw_extra_genarg_printer)
(g : 'b glob_extra_genarg_printer)
(h : 'c extra_genarg_printer) =
begin match wit with
- | ExtraArg s -> ()
+ | ExtraArg _ -> ()
| _ -> user_err Pp.(str "Can declare a pretty-printing rule only for extra argument types.")
end;
let f x =
@@ -1319,7 +1318,7 @@ let () =
let open Genprint in
register_basic_print0 wit_int_or_var (pr_or_var int) (pr_or_var int) int;
register_basic_print0 wit_ref
- pr_reference (pr_or_var (pr_located pr_global)) pr_global;
+ pr_qualid (pr_or_var (pr_located pr_global)) pr_global;
register_basic_print0 wit_ident pr_id pr_id pr_id;
register_basic_print0 wit_var pr_lident pr_lident pr_id;
register_print0
@@ -1353,7 +1352,7 @@ let () =
;
Genprint.register_print0
wit_red_expr
- (lift (pr_red_expr (pr_constr_expr, pr_lconstr_expr, pr_or_by_notation pr_reference, pr_constr_pattern_expr)))
+ (lift (pr_red_expr (pr_constr_expr, pr_lconstr_expr, pr_or_by_notation pr_qualid, pr_constr_pattern_expr)))
(lift (pr_red_expr (pr_and_constr_expr pr_glob_constr_pptac, pr_and_constr_expr pr_lglob_constr_pptac, pr_or_var (pr_and_short_name pr_evaluable_reference), pr_pat_and_constr_expr pr_glob_constr_pptac)))
pr_red_expr_env
;
diff --git a/plugins/ltac/pptactic.mli b/plugins/ltac/pptactic.mli
index 5951f2b1..6c09e447 100644
--- a/plugins/ltac/pptactic.mli
+++ b/plugins/ltac/pptactic.mli
@@ -14,11 +14,11 @@
open Genarg
open Geninterp
open Names
-open Misctypes
open Environ
open Constrexpr
-open Notation_term
+open Notation_gram
open Tacexpr
+open Tactypes
type 'a grammar_tactic_prod_item_expr =
| TacTerm of string
@@ -84,7 +84,7 @@ type pp_tactic = {
pptac_prods : grammar_terminals;
}
-val pr_goal_selector : toplevel:bool -> goal_selector -> Pp.t
+val pr_goal_selector : toplevel:bool -> Goal_select.t -> Pp.t
val declare_notation_tactic_pprule : KerName.t -> pp_tactic -> unit
@@ -97,7 +97,7 @@ val pr_may_eval :
('a -> Pp.t) -> ('a -> Pp.t) -> ('b -> Pp.t) ->
('c -> Pp.t) -> ('a,'b,'c) Genredexpr.may_eval -> Pp.t
-val pr_and_short_name : ('a -> Pp.t) -> 'a and_short_name -> Pp.t
+val pr_and_short_name : ('a -> Pp.t) -> 'a Stdarg.and_short_name -> Pp.t
val pr_or_by_notation : ('a -> Pp.t) -> 'a or_by_notation -> Pp.t
val pr_evaluable_reference_env : env -> evaluable_global_reference -> Pp.t
@@ -153,5 +153,5 @@ val pr_value : tolerability -> Val.t -> Pp.t
val ltop : tolerability
-val make_constr_printer : (env -> Evd.evar_map -> Notation_term.tolerability -> 'a -> Pp.t) ->
+val make_constr_printer : (env -> Evd.evar_map -> tolerability -> 'a -> Pp.t) ->
'a Genprint.top_printer
diff --git a/plugins/ltac/rewrite.ml b/plugins/ltac/rewrite.ml
index d32a2fae..9f8cd2fc 100644
--- a/plugins/ltac/rewrite.ml
+++ b/plugins/ltac/rewrite.ml
@@ -26,7 +26,7 @@ open Classes
open Constrexpr
open Globnames
open Evd
-open Misctypes
+open Tactypes
open Locus
open Locusops
open Decl_kinds
@@ -104,9 +104,8 @@ let extends_undefined evars evars' =
let app_poly_check env evars f args =
let (evars, cstrs), fc = f evars in
- let evdref = ref evars in
- let t = Typing.e_solve_evars env evdref (mkApp (fc, args)) in
- (!evdref, cstrs), t
+ let evars, t = Typing.solve_evars env evars (mkApp (fc, args)) in
+ (evars, cstrs), t
let app_poly_nocheck env evars f args =
let evars, fc = f evars in
@@ -410,7 +409,7 @@ module TypeGlobal = struct
let inverse env (evd,cstrs) car rel =
- let (evd, sort) = Evarutil.new_Type ~rigid:Evd.univ_flexible env evd in
+ let (evd, sort) = Evarutil.new_Type ~rigid:Evd.univ_flexible evd in
app_poly_check env (evd,cstrs) coq_inverse [| car ; car; sort; rel |]
end
@@ -428,7 +427,8 @@ let split_head = function
| [] -> assert(false)
let eq_pb (ty, env, x, y as pb) (ty', env', x', y' as pb') =
- pb == pb' || (ty == ty' && Constr.equal x x' && Constr.equal y y')
+ let equal x y = Constr.equal (EConstr.Unsafe.to_constr x) (EConstr.Unsafe.to_constr y) in
+ pb == pb' || (ty == ty' && equal x x' && equal y y')
let problem_inclusion x y =
List.for_all (fun pb -> List.exists (fun pb' -> eq_pb pb pb') y) x
@@ -626,9 +626,9 @@ let solve_remaining_by env sigma holes by =
(** Evar should not be defined, but just in case *)
| Some evi ->
let env = Environ.reset_with_named_context evi.evar_hyps env in
- let ty = EConstr.of_constr evi.evar_concl in
+ let ty = evi.evar_concl in
let c, sigma = Pfedit.refine_by_tactic env sigma ty solve_tac in
- Evd.define evk c sigma
+ Evd.define evk (EConstr.of_constr c) sigma
in
List.fold_left solve sigma indep
@@ -1468,8 +1468,8 @@ exception RewriteFailure of Pp.t
type result = (evar_map * constr option * types) option option
let cl_rewrite_clause_aux ?(abs=None) strat env avoid sigma concl is_hyp : result =
+ let sigma, sort = Typing.sort_of env sigma concl in
let evdref = ref sigma in
- let sort = Typing.e_sort_of env evdref concl in
let evars = (!evdref, Evar.Set.empty) in
let evars, cstr =
let prop, (evars, arrow) =
@@ -1773,11 +1773,11 @@ let rec strategy_of_ast = function
(* By default the strategy for "rewrite_db" is top-down *)
-let mkappc s l = CAst.make @@ CAppExpl ((None,CAst.make @@ Libnames.Ident (Id.of_string s),None),l)
+let mkappc s l = CAst.make @@ CAppExpl ((None,qualid_of_ident (Id.of_string s),None),l)
let declare_an_instance n s args =
(((CAst.make @@ Name n),None), Explicit,
- CAst.make @@ CAppExpl ((None, CAst.make @@ Qualid (qualid_of_string s),None), args))
+ CAst.make @@ CAppExpl ((None, qualid_of_string s,None), args))
let declare_instance a aeq n s = declare_an_instance n s [a;aeq]
@@ -1791,17 +1791,17 @@ let anew_instance global binders instance fields =
let declare_instance_refl global binders a aeq n lemma =
let instance = declare_instance a aeq (add_suffix n "_Reflexive") "Coq.Classes.RelationClasses.Reflexive"
in anew_instance global binders instance
- [(CAst.make @@ Ident (Id.of_string "reflexivity"),lemma)]
+ [(qualid_of_ident (Id.of_string "reflexivity"),lemma)]
let declare_instance_sym global binders a aeq n lemma =
let instance = declare_instance a aeq (add_suffix n "_Symmetric") "Coq.Classes.RelationClasses.Symmetric"
in anew_instance global binders instance
- [(CAst.make @@ Ident (Id.of_string "symmetry"),lemma)]
+ [(qualid_of_ident (Id.of_string "symmetry"),lemma)]
let declare_instance_trans global binders a aeq n lemma =
let instance = declare_instance a aeq (add_suffix n "_Transitive") "Coq.Classes.RelationClasses.Transitive"
in anew_instance global binders instance
- [(CAst.make @@ Ident (Id.of_string "transitivity"),lemma)]
+ [(qualid_of_ident (Id.of_string "transitivity"),lemma)]
let declare_relation ?locality ?(binders=[]) a aeq n refl symm trans =
init_setoid ();
@@ -1825,16 +1825,16 @@ let declare_relation ?locality ?(binders=[]) a aeq n refl symm trans =
let instance = declare_instance a aeq n "Coq.Classes.RelationClasses.PreOrder"
in ignore(
anew_instance global binders instance
- [(CAst.make @@ Ident (Id.of_string "PreOrder_Reflexive"), lemma1);
- (CAst.make @@ Ident (Id.of_string "PreOrder_Transitive"),lemma3)])
+ [(qualid_of_ident (Id.of_string "PreOrder_Reflexive"), lemma1);
+ (qualid_of_ident (Id.of_string "PreOrder_Transitive"),lemma3)])
| (None, Some lemma2, Some lemma3) ->
let _lemma_sym = declare_instance_sym global binders a aeq n lemma2 in
let _lemma_trans = declare_instance_trans global binders a aeq n lemma3 in
let instance = declare_instance a aeq n "Coq.Classes.RelationClasses.PER"
in ignore(
anew_instance global binders instance
- [(CAst.make @@ Ident (Id.of_string "PER_Symmetric"), lemma2);
- (CAst.make @@ Ident (Id.of_string "PER_Transitive"),lemma3)])
+ [(qualid_of_ident (Id.of_string "PER_Symmetric"), lemma2);
+ (qualid_of_ident (Id.of_string "PER_Transitive"),lemma3)])
| (Some lemma1, Some lemma2, Some lemma3) ->
let _lemma_refl = declare_instance_refl global binders a aeq n lemma1 in
let _lemma_sym = declare_instance_sym global binders a aeq n lemma2 in
@@ -1842,11 +1842,11 @@ let declare_relation ?locality ?(binders=[]) a aeq n refl symm trans =
let instance = declare_instance a aeq n "Coq.Classes.RelationClasses.Equivalence"
in ignore(
anew_instance global binders instance
- [(CAst.make @@ Ident (Id.of_string "Equivalence_Reflexive"), lemma1);
- (CAst.make @@ Ident (Id.of_string "Equivalence_Symmetric"), lemma2);
- (CAst.make @@ Ident (Id.of_string "Equivalence_Transitive"), lemma3)])
+ [(qualid_of_ident (Id.of_string "Equivalence_Reflexive"), lemma1);
+ (qualid_of_ident (Id.of_string "Equivalence_Symmetric"), lemma2);
+ (qualid_of_ident (Id.of_string "Equivalence_Transitive"), lemma3)])
-let cHole = CAst.make @@ CHole (None, Misctypes.IntroAnonymous, None)
+let cHole = CAst.make @@ CHole (None, Namegen.IntroAnonymous, None)
let proper_projection sigma r ty =
let rel_vect n m = Array.init m (fun i -> mkRel(n+m-i)) in
@@ -1862,7 +1862,6 @@ let declare_projection n instance_id r =
let env = Global.env () in
let sigma = Evd.from_env env in
let sigma,c = Evd.fresh_global env sigma r in
- let c = EConstr.of_constr c in
let ty = Retyping.get_type_of env sigma c in
let term = proper_projection sigma c ty in
let sigma, typ = Typing.type_of env sigma term in
@@ -1923,7 +1922,7 @@ let build_morphism_signature env sigma m =
let evd = solve_constraints env !evd in
let evd = Evd.minimize_universes evd in
let m = Evarutil.nf_evars_universes evd (EConstr.Unsafe.to_constr morph) in
- Pretyping.check_evars env Evd.empty evd (EConstr.of_constr m);
+ Pretyping.check_evars env (Evd.from_env env) evd (EConstr.of_constr m);
Evd.evar_universe_context evd, m
let default_morphism sign m =
@@ -1950,16 +1949,15 @@ let add_setoid global binders a aeq t n =
let instance = declare_instance a aeq n "Coq.Classes.RelationClasses.Equivalence"
in ignore(
anew_instance global binders instance
- [(CAst.make @@ Ident (Id.of_string "Equivalence_Reflexive"), mkappc "Seq_refl" [a;aeq;t]);
- (CAst.make @@ Ident (Id.of_string "Equivalence_Symmetric"), mkappc "Seq_sym" [a;aeq;t]);
- (CAst.make @@ Ident (Id.of_string "Equivalence_Transitive"), mkappc "Seq_trans" [a;aeq;t])])
+ [(qualid_of_ident (Id.of_string "Equivalence_Reflexive"), mkappc "Seq_refl" [a;aeq;t]);
+ (qualid_of_ident (Id.of_string "Equivalence_Symmetric"), mkappc "Seq_sym" [a;aeq;t]);
+ (qualid_of_ident (Id.of_string "Equivalence_Transitive"), mkappc "Seq_trans" [a;aeq;t])])
let make_tactic name =
let open Tacexpr in
- let tacpath = Libnames.qualid_of_string name in
- let tacname = CAst.make @@ Qualid tacpath in
- TacArg (Loc.tag @@ (TacCall (Loc.tag (tacname, []))))
+ let tacqid = Libnames.qualid_of_string name in
+ TacArg (Loc.tag @@ (TacCall (Loc.tag (tacqid, []))))
let warn_add_morphism_deprecated =
CWarnings.create ~name:"add-morphism" ~category:"deprecated" (fun () ->
@@ -2009,7 +2007,7 @@ let add_morphism glob binders m s n =
let instance =
(((CAst.make @@ Name instance_id),None), Explicit,
CAst.make @@ CAppExpl (
- (None, CAst.make @@ Qualid (Libnames.qualid_of_string "Coq.Classes.Morphisms.Proper"),None),
+ (None, Libnames.qualid_of_string "Coq.Classes.Morphisms.Proper",None),
[cHole; s; m]))
in
let tac = Tacinterp.interp (make_tactic "add_morphism_tactic") in
diff --git a/plugins/ltac/rewrite.mli b/plugins/ltac/rewrite.mli
index 1e3d4733..0d014a0b 100644
--- a/plugins/ltac/rewrite.mli
+++ b/plugins/ltac/rewrite.mli
@@ -12,9 +12,9 @@ open Names
open Environ
open EConstr
open Constrexpr
-open Tacexpr
-open Misctypes
open Evd
+open Tactypes
+open Tacexpr
open Tacinterp
(** TODO: document and clean me! *)
diff --git a/plugins/ltac/tacarg.ml b/plugins/ltac/tacarg.ml
index 6eb482b1..8a25d485 100644
--- a/plugins/ltac/tacarg.ml
+++ b/plugins/ltac/tacarg.ml
@@ -19,6 +19,14 @@ let make0 ?dyn name =
let () = Geninterp.register_val0 wit dyn in
wit
+let wit_intro_pattern = make0 "intropattern"
+let wit_quant_hyp = make0 "quant_hyp"
+let wit_constr_with_bindings = make0 "constr_with_bindings"
+let wit_open_constr_with_bindings = make0 "open_constr_with_bindings"
+let wit_bindings = make0 "bindings"
+let wit_quantified_hypothesis = wit_quant_hyp
+let wit_intropattern = wit_intro_pattern
+
let wit_tactic : (raw_tactic_expr, glob_tactic_expr, Val.t) genarg_type =
make0 "tactic"
diff --git a/plugins/ltac/tacarg.mli b/plugins/ltac/tacarg.mli
index 5347eda7..bdb0be03 100644
--- a/plugins/ltac/tacarg.mli
+++ b/plugins/ltac/tacarg.mli
@@ -9,9 +9,33 @@
(************************************************************************)
open Genarg
-open Tacexpr
+open EConstr
open Constrexpr
-open Misctypes
+open Tactypes
+open Tacexpr
+
+(** Tactic related witnesses, could also live in tactics/ if other users *)
+val wit_intro_pattern : (constr_expr intro_pattern_expr CAst.t, glob_constr_and_expr intro_pattern_expr CAst.t, intro_pattern) genarg_type
+
+val wit_quant_hyp : quantified_hypothesis uniform_genarg_type
+
+val wit_constr_with_bindings :
+ (constr_expr with_bindings,
+ glob_constr_and_expr with_bindings,
+ constr with_bindings delayed_open) genarg_type
+
+val wit_open_constr_with_bindings :
+ (constr_expr with_bindings,
+ glob_constr_and_expr with_bindings,
+ constr with_bindings delayed_open) genarg_type
+
+val wit_bindings :
+ (constr_expr bindings,
+ glob_constr_and_expr bindings,
+ constr bindings delayed_open) genarg_type
+
+val wit_quantified_hypothesis : quantified_hypothesis uniform_genarg_type
+val wit_intropattern : (constr_expr intro_pattern_expr CAst.t, glob_constr_and_expr intro_pattern_expr CAst.t, intro_pattern) genarg_type
(** Generic arguments based on Ltac. *)
@@ -23,7 +47,7 @@ val wit_tactic : (raw_tactic_expr, glob_tactic_expr, Geninterp.Val.t) genarg_typ
val wit_ltac : (raw_tactic_expr, glob_tactic_expr, unit) genarg_type
val wit_destruction_arg :
- (constr_expr with_bindings Tacexpr.destruction_arg,
- glob_constr_and_expr with_bindings Tacexpr.destruction_arg,
- delayed_open_constr_with_bindings Tacexpr.destruction_arg) genarg_type
+ (constr_expr with_bindings Tactics.destruction_arg,
+ glob_constr_and_expr with_bindings Tactics.destruction_arg,
+ delayed_open_constr_with_bindings Tactics.destruction_arg) genarg_type
diff --git a/plugins/ltac/taccoerce.ml b/plugins/ltac/taccoerce.ml
index 3812a2ba..026c00b8 100644
--- a/plugins/ltac/taccoerce.ml
+++ b/plugins/ltac/taccoerce.ml
@@ -12,9 +12,11 @@ open Util
open Names
open Constr
open EConstr
-open Misctypes
+open Namegen
+open Tactypes
open Genarg
open Stdarg
+open Tacarg
open Geninterp
open Pp
@@ -163,8 +165,7 @@ let coerce_var_to_ident fresh env sigma v =
(* Interprets, if possible, a constr to an identifier which may not
be fresh but suitable to be given to the fresh tactic. Works for
vars, constants, inductive, constructors and sorts. *)
-let coerce_to_ident_not_fresh env sigma v =
-let g = sigma in
+let coerce_to_ident_not_fresh sigma v =
let id_of_name = function
| Name.Anonymous -> Id.of_string "x"
| Name.Name x -> x in
@@ -181,9 +182,9 @@ let id_of_name = function
| Some c ->
match EConstr.kind sigma c with
| Var id -> id
- | Meta m -> id_of_name (Evd.meta_name g m)
+ | Meta m -> id_of_name (Evd.meta_name sigma m)
| Evar (kn,_) ->
- begin match Evd.evar_ident kn g with
+ begin match Evd.evar_ident kn sigma with
| None -> fail ()
| Some id -> id
end
@@ -197,15 +198,16 @@ let id_of_name = function
let basename = Nametab.basename_of_global ref in
basename
| Sort s ->
- begin
+ begin
match ESorts.kind sigma s with
- | Sorts.Prop _ -> Label.to_id (Label.make "Prop")
- | Sorts.Type _ -> Label.to_id (Label.make "Type")
- end
+ | Sorts.Prop -> Label.to_id (Label.make "Prop")
+ | Sorts.Set -> Label.to_id (Label.make "Set")
+ | Sorts.Type _ -> Label.to_id (Label.make "Type")
+ end
| _ -> fail()
-let coerce_to_intro_pattern env sigma v =
+let coerce_to_intro_pattern sigma v =
if has_type v (topwit wit_intro_pattern) then
(out_gen (topwit wit_intro_pattern) v).CAst.v
else if has_type v (topwit wit_var) then
@@ -218,8 +220,8 @@ let coerce_to_intro_pattern env sigma v =
IntroNaming (IntroIdentifier (destVar sigma c))
| _ -> raise (CannotCoerceTo "an introduction pattern")
-let coerce_to_intro_pattern_naming env sigma v =
- match coerce_to_intro_pattern env sigma v with
+let coerce_to_intro_pattern_naming sigma v =
+ match coerce_to_intro_pattern sigma v with
| IntroNaming pat -> pat
| _ -> raise (CannotCoerceTo "a naming introduction pattern")
@@ -252,7 +254,7 @@ let coerce_to_constr env v =
(try [], constr_of_id env id with Not_found -> fail ())
else fail ()
-let coerce_to_uconstr env v =
+let coerce_to_uconstr v =
if has_type v (topwit wit_uconstr) then
out_gen (topwit wit_uconstr) v
else
@@ -296,11 +298,11 @@ let coerce_to_constr_list env v =
List.map map l
| None -> raise (CannotCoerceTo "a term list")
-let coerce_to_intro_pattern_list ?loc env sigma v =
+let coerce_to_intro_pattern_list ?loc sigma v =
match Value.to_list v with
| None -> raise (CannotCoerceTo "an intro pattern list")
| Some l ->
- let map v = CAst.make ?loc @@ coerce_to_intro_pattern env sigma v in
+ let map v = CAst.make ?loc @@ coerce_to_intro_pattern sigma v in
List.map map l
let coerce_to_hyp env sigma v =
@@ -325,7 +327,7 @@ let coerce_to_hyp_list env sigma v =
| None -> raise (CannotCoerceTo "a variable list")
(* Interprets a qualified name *)
-let coerce_to_reference env sigma v =
+let coerce_to_reference sigma v =
match Value.to_constr v with
| Some c ->
begin
@@ -353,7 +355,7 @@ let coerce_to_quantified_hypothesis sigma v =
(* Quantified named or numbered hypothesis or hypothesis in context *)
(* (as in Inversion) *)
-let coerce_to_decl_or_quant_hyp env sigma v =
+let coerce_to_decl_or_quant_hyp sigma v =
if has_type v (topwit wit_int) then
AnonHyp (out_gen (topwit wit_int) v)
else
@@ -365,7 +367,7 @@ let coerce_to_int_or_var_list v =
match Value.to_list v with
| None -> raise (CannotCoerceTo "an int list")
| Some l ->
- let map n = ArgArg (coerce_to_int n) in
+ let map n = Locus.ArgArg (coerce_to_int n) in
List.map map l
(** Abstract application, to print ltac functions *)
diff --git a/plugins/ltac/taccoerce.mli b/plugins/ltac/taccoerce.mli
index 1fa5e3c0..d2ae92f6 100644
--- a/plugins/ltac/taccoerce.mli
+++ b/plugins/ltac/taccoerce.mli
@@ -11,9 +11,9 @@
open Util
open Names
open EConstr
-open Misctypes
open Genarg
open Geninterp
+open Tactypes
(** Coercions from highest level generic arguments to actual data used by Ltac
interpretation. Those functions examinate dynamic types and try to return
@@ -51,12 +51,12 @@ val coerce_to_constr_context : Value.t -> constr
val coerce_var_to_ident : bool -> Environ.env -> Evd.evar_map -> Value.t -> Id.t
-val coerce_to_ident_not_fresh : Environ.env -> Evd.evar_map -> Value.t -> Id.t
+val coerce_to_ident_not_fresh : Evd.evar_map -> Value.t -> Id.t
-val coerce_to_intro_pattern : Environ.env -> Evd.evar_map -> Value.t -> Tacexpr.delayed_open_constr intro_pattern_expr
+val coerce_to_intro_pattern : Evd.evar_map -> Value.t -> Tacexpr.delayed_open_constr intro_pattern_expr
val coerce_to_intro_pattern_naming :
- Environ.env -> Evd.evar_map -> Value.t -> intro_pattern_naming_expr
+ Evd.evar_map -> Value.t -> Namegen.intro_pattern_naming_expr
val coerce_to_hint_base : Value.t -> string
@@ -64,7 +64,7 @@ val coerce_to_int : Value.t -> int
val coerce_to_constr : Environ.env -> Value.t -> Ltac_pretype.constr_under_binders
-val coerce_to_uconstr : Environ.env -> Value.t -> Ltac_pretype.closed_glob_constr
+val coerce_to_uconstr : Value.t -> Ltac_pretype.closed_glob_constr
val coerce_to_closed_constr : Environ.env -> Value.t -> constr
@@ -74,19 +74,19 @@ val coerce_to_evaluable_ref :
val coerce_to_constr_list : Environ.env -> Value.t -> constr list
val coerce_to_intro_pattern_list :
- ?loc:Loc.t -> Environ.env -> Evd.evar_map -> Value.t -> Tacexpr.intro_patterns
+ ?loc:Loc.t -> Evd.evar_map -> Value.t -> Tacexpr.intro_patterns
val coerce_to_hyp : Environ.env -> Evd.evar_map -> Value.t -> Id.t
val coerce_to_hyp_list : Environ.env -> Evd.evar_map -> Value.t -> Id.t list
-val coerce_to_reference : Environ.env -> Evd.evar_map -> Value.t -> Globnames.global_reference
+val coerce_to_reference : Evd.evar_map -> Value.t -> GlobRef.t
val coerce_to_quantified_hypothesis : Evd.evar_map -> Value.t -> quantified_hypothesis
-val coerce_to_decl_or_quant_hyp : Environ.env -> Evd.evar_map -> Value.t -> quantified_hypothesis
+val coerce_to_decl_or_quant_hyp : Evd.evar_map -> Value.t -> quantified_hypothesis
-val coerce_to_int_or_var_list : Value.t -> int or_var list
+val coerce_to_int_or_var_list : Value.t -> int Locus.or_var list
(** {5 Missing generic arguments} *)
diff --git a/plugins/ltac/tacentries.ml b/plugins/ltac/tacentries.ml
index e510b9f5..636cb8eb 100644
--- a/plugins/ltac/tacentries.ml
+++ b/plugins/ltac/tacentries.ml
@@ -45,7 +45,7 @@ let coincide s pat off =
let atactic n =
if n = 5 then Aentry Pltac.binder_tactic
- else Aentryl (Pltac.tactic_expr, n)
+ else Aentryl (Pltac.tactic_expr, string_of_int n)
type entry_name = EntryName :
'a raw_abstract_argument_type * (Tacexpr.raw_tactic_expr, 'a) Extend.symbol -> entry_name
@@ -252,7 +252,7 @@ type tactic_grammar_obj = {
tacobj_key : KerName.t;
tacobj_local : locality_flag;
tacobj_tacgram : tactic_grammar;
- tacobj_body : Id.t list * Tacexpr.glob_tactic_expr;
+ tacobj_body : Tacenv.alias_tactic;
tacobj_forml : bool;
}
@@ -288,10 +288,11 @@ let load_tactic_notation i (_, tobj) =
extend_tactic_grammar key tobj.tacobj_forml tobj.tacobj_tacgram
let subst_tactic_notation (subst, tobj) =
- let (ids, body) = tobj.tacobj_body in
+ let open Tacenv in
+ let alias = tobj.tacobj_body in
{ tobj with
tacobj_key = Mod_subst.subst_kn subst tobj.tacobj_key;
- tacobj_body = (ids, Tacsubst.subst_tactic subst body);
+ tacobj_body = { alias with alias_body = Tacsubst.subst_tactic subst alias.alias_body };
}
let classify_tactic_notation tacobj = Substitute tacobj
@@ -308,25 +309,26 @@ let cons_production_parameter = function
| TacTerm _ -> None
| TacNonTerm (_, (_, ido)) -> ido
-let add_glob_tactic_notation local ~level prods forml ids tac =
+let add_glob_tactic_notation local ~level ?deprecation prods forml ids tac =
let parule = {
tacgram_level = level;
tacgram_prods = prods;
} in
+ let open Tacenv in
let tacobj = {
tacobj_key = make_fresh_key prods;
tacobj_local = local;
tacobj_tacgram = parule;
- tacobj_body = (ids, tac);
+ tacobj_body = { alias_args = ids; alias_body = tac; alias_deprecation = deprecation };
tacobj_forml = forml;
} in
Lib.add_anonymous_leaf (inTacticGrammar tacobj)
-let add_tactic_notation local n prods e =
+let add_tactic_notation local n ?deprecation prods e =
let ids = List.map_filter cons_production_parameter prods in
let prods = List.map interp_prod_item prods in
let tac = Tacintern.glob_tactic_env ids (Global.env()) e in
- add_glob_tactic_notation local ~level:n prods false ids tac
+ add_glob_tactic_notation local ~level:n ?deprecation prods false ids tac
(**********************************************************************)
(* ML Tactic entries *)
@@ -366,7 +368,7 @@ let extend_atomic_tactic name entries =
in
List.iteri add_atomic entries
-let add_ml_tactic_notation name ~level prods =
+let add_ml_tactic_notation name ~level ?deprecation prods =
let len = List.length prods in
let iter i prods =
let open Tacexpr in
@@ -376,9 +378,9 @@ let add_ml_tactic_notation name ~level prods =
in
let ids = List.map_filter get_id prods in
let entry = { mltac_name = name; mltac_index = len - i - 1 } in
- let map id = Reference (Misctypes.ArgVar (CAst.make id)) in
+ let map id = Reference (Locus.ArgVar (CAst.make id)) in
let tac = TacML (Loc.tag (entry, List.map map ids)) in
- add_glob_tactic_notation false ~level prods true ids tac
+ add_glob_tactic_notation false ~level ?deprecation prods true ids tac
in
List.iteri iter (List.rev prods);
(** We call [extend_atomic_tactic] only for "basic tactics" (the ones at
@@ -398,7 +400,7 @@ let create_ltac_quotation name cast (e, l) =
let () = ltac_quotations := String.Set.add name !ltac_quotations in
let entry = match l with
| None -> Aentry e
- | Some l -> Aentryl (e, l)
+ | Some l -> Aentryl (e, string_of_int l)
in
(* let level = Some "1" in *)
let level = None in
@@ -430,7 +432,7 @@ let warn_unusable_identifier =
(fun id -> strbrk "The Ltac name" ++ spc () ++ Id.print id ++ spc () ++
strbrk "may be unusable because of a conflict with a notation.")
-let register_ltac local tacl =
+let register_ltac local ?deprecation tacl =
let map tactic_body =
match tactic_body with
| Tacexpr.TacticDefinition ({CAst.loc;v=id}, body) ->
@@ -449,12 +451,12 @@ let register_ltac local tacl =
in
let () = if is_shadowed then warn_unusable_identifier id in
NewTac id, body
- | Tacexpr.TacticRedefinition (ident, body) ->
+ | Tacexpr.TacticRedefinition (qid, body) ->
let kn =
- try Tacenv.locate_tactic (qualid_of_reference ident).CAst.v
+ try Tacenv.locate_tactic qid
with Not_found ->
- CErrors.user_err ?loc:ident.CAst.loc
- (str "There is no Ltac named " ++ pr_reference ident ++ str ".")
+ CErrors.user_err ?loc:qid.CAst.loc
+ (str "There is no Ltac named " ++ pr_qualid qid ++ str ".")
in
UpdateTac kn, body
in
@@ -483,10 +485,10 @@ let register_ltac local tacl =
let defs = States.with_state_protection defs () in
let iter (def, tac) = match def with
| NewTac id ->
- Tacenv.register_ltac false local id tac;
+ Tacenv.register_ltac false local id tac ?deprecation;
Flags.if_verbose Feedback.msg_info (Id.print id ++ str " is defined")
| UpdateTac kn ->
- Tacenv.redefine_ltac local kn tac;
+ Tacenv.redefine_ltac local kn tac ?deprecation;
let name = Tacenv.shortest_qualid_of_tactic kn in
Flags.if_verbose Feedback.msg_info (Libnames.pr_qualid name ++ str " is redefined")
in
@@ -554,13 +556,18 @@ let () =
] in
register_grammars_by_name "tactic" entries
+let get_identifier id =
+ (** Workaround for badly-designed generic arguments lacking a closure *)
+ Names.Id.of_string_soft ("$" ^ id)
+
+
type _ ty_sig =
| TyNil : (Geninterp.interp_sign -> unit Proofview.tactic) ty_sig
| TyIdent : string * 'r ty_sig -> 'r ty_sig
| TyArg :
- (('a, 'b, 'c) Extend.ty_user_symbol * Id.t) Loc.located * 'r ty_sig -> ('c -> 'r) ty_sig
+ ('a, 'b, 'c) Extend.ty_user_symbol * string * 'r ty_sig -> ('c -> 'r) ty_sig
| TyAnonArg :
- ('a, 'b, 'c) Extend.ty_user_symbol Loc.located * 'r ty_sig -> 'r ty_sig
+ ('a, 'b, 'c) Extend.ty_user_symbol * 'r ty_sig -> 'r ty_sig
type ty_ml = TyML : 'r ty_sig * 'r -> ty_ml
@@ -578,23 +585,15 @@ let rec clause_of_sign : type a. a ty_sig -> Genarg.ArgT.any Extend.user_symbol
fun sign -> match sign with
| TyNil -> []
| TyIdent (s, sig') -> TacTerm s :: clause_of_sign sig'
- | TyArg ((loc,(a,id)),sig') ->
- TacNonTerm (loc,(untype_user_symbol a,Some id)) :: clause_of_sign sig'
- | TyAnonArg ((loc,a),sig') ->
- TacNonTerm (loc,(untype_user_symbol a,None)) :: clause_of_sign sig'
+ | TyArg (a, id, sig') ->
+ let id = get_identifier id in
+ TacNonTerm (None,(untype_user_symbol a,Some id)) :: clause_of_sign sig'
+ | TyAnonArg (a, sig') ->
+ TacNonTerm (None,(untype_user_symbol a,None)) :: clause_of_sign sig'
let clause_of_ty_ml = function
| TyML (t,_) -> clause_of_sign t
-let rec prj : type a b c. (a,b,c) Extend.ty_user_symbol -> (a,b,c) genarg_type = function
- | TUentry a -> ExtraArg a
- | TUentryl (a,l) -> ExtraArg a
- | TUopt(o) -> OptArg (prj o)
- | TUlist1 l -> ListArg (prj l)
- | TUlist1sep (l,_) -> ListArg (prj l)
- | TUlist0 l -> ListArg (prj l)
- | TUlist0sep (l,_) -> ListArg (prj l)
-
let rec eval_sign : type a. a ty_sig -> a -> Geninterp.Val.t list -> Geninterp.interp_sign -> unit Proofview.tactic =
fun sign tac ->
match sign with
@@ -604,15 +603,15 @@ let rec eval_sign : type a. a ty_sig -> a -> Geninterp.Val.t list -> Geninterp.i
| _ :: _ -> assert false
end
| TyIdent (s, sig') -> eval_sign sig' tac
- | TyArg ((_loc,(a,id)), sig') ->
+ | TyArg (a, _, sig') ->
let f = eval_sign sig' in
begin fun tac vals ist -> match vals with
| [] -> assert false
| v :: vals ->
- let v' = Taccoerce.Value.cast (topwit (prj a)) v in
+ let v' = Taccoerce.Value.cast (topwit (Egramml.proj_symbol a)) v in
f (tac v') vals ist
end tac
- | TyAnonArg ((_loc,a), sig') -> eval_sign sig' tac
+ | TyAnonArg (a, sig') -> eval_sign sig' tac
let eval : ty_ml -> Geninterp.Val.t list -> Geninterp.interp_sign -> unit Proofview.tactic = function
| TyML (t,tac) -> eval_sign t tac
@@ -624,14 +623,14 @@ let is_constr_entry = function
let rec only_constr : type a. a ty_sig -> bool = function
| TyNil -> true
| TyIdent(_,_) -> false
-| TyArg((_,(u,_)),s) -> if is_constr_entry u then only_constr s else false
-| TyAnonArg((_,u),s) -> if is_constr_entry u then only_constr s else false
+| TyArg (u, _, s) -> if is_constr_entry u then only_constr s else false
+| TyAnonArg (u, s) -> if is_constr_entry u then only_constr s else false
let rec mk_sign_vars : type a. a ty_sig -> Name.t list = function
| TyNil -> []
| TyIdent (_,s) -> mk_sign_vars s
-| TyArg((_,(_,name)),s) -> Name name :: mk_sign_vars s
-| TyAnonArg((_,_),s) -> Anonymous :: mk_sign_vars s
+| TyArg (_, name, s) -> Name (get_identifier name) :: mk_sign_vars s
+| TyAnonArg (_, s) -> Anonymous :: mk_sign_vars s
let dummy_id = Id.of_string "_"
@@ -652,7 +651,7 @@ let lift_constr_tac_to_ml_tac vars tac =
end in
tac
-let tactic_extend plugin_name tacname ~level sign =
+let tactic_extend plugin_name tacname ~level ?deprecation sign =
let open Tacexpr in
let ml_tactic_name =
{ mltac_tactic = tacname;
@@ -681,10 +680,10 @@ let tactic_extend plugin_name tacname ~level sign =
This is the rôle of the [lift_constr_tac_to_ml_tac] function. *)
let body = Tacexpr.TacFun (vars, Tacexpr.TacML (Loc.tag (ml, [])))in
let id = Names.Id.of_string name in
- let obj () = Tacenv.register_ltac true false id body in
+ let obj () = Tacenv.register_ltac true false id body ?deprecation in
let () = Tacenv.register_ml_tactic ml_tactic_name [|tac|] in
Mltop.declare_cache_obj obj plugin_name
| _ ->
- let obj () = add_ml_tactic_notation ml_tactic_name ~level (List.map clause_of_ty_ml sign) in
+ let obj () = add_ml_tactic_notation ml_tactic_name ~level ?deprecation (List.map clause_of_ty_ml sign) in
Tacenv.register_ml_tactic ml_tactic_name @@ Array.of_list (List.map eval sign);
Mltop.declare_cache_obj obj plugin_name
diff --git a/plugins/ltac/tacentries.mli b/plugins/ltac/tacentries.mli
index 3f804ee8..138a584e 100644
--- a/plugins/ltac/tacentries.mli
+++ b/plugins/ltac/tacentries.mli
@@ -12,10 +12,12 @@
open Vernacexpr
open Tacexpr
+open Vernacinterp
(** {5 Tactic Definitions} *)
-val register_ltac : locality_flag -> Tacexpr.tacdef_body list -> unit
+val register_ltac : locality_flag -> ?deprecation:deprecation ->
+ Tacexpr.tacdef_body list -> unit
(** Adds new Ltac definitions to the environment. *)
(** {5 Tactic Notations} *)
@@ -34,8 +36,8 @@ type argument = Genarg.ArgT.any Extend.user_symbol
leaves. *)
val add_tactic_notation :
- locality_flag -> int -> raw_argument grammar_tactic_prod_item_expr list ->
- raw_tactic_expr -> unit
+ locality_flag -> int -> ?deprecation:deprecation -> raw_argument
+ grammar_tactic_prod_item_expr list -> raw_tactic_expr -> unit
(** [add_tactic_notation local level prods expr] adds a tactic notation in the
environment at level [level] with locality [local] made of the grammar
productions [prods] and returning the body [expr] *)
@@ -47,7 +49,7 @@ val register_tactic_notation_entry : string -> ('a, 'b, 'c) Genarg.genarg_type -
to finding an argument by name (as in {!Genarg}) if there is none
matching. *)
-val add_ml_tactic_notation : ml_tactic_name -> level:int ->
+val add_ml_tactic_notation : ml_tactic_name -> level:int -> ?deprecation:deprecation ->
argument grammar_tactic_prod_item_expr list list -> unit
(** A low-level variant of {!add_tactic_notation} used by the TACTIC EXTEND
ML-side macro. *)
@@ -55,7 +57,7 @@ val add_ml_tactic_notation : ml_tactic_name -> level:int ->
(** {5 Tactic Quotations} *)
val create_ltac_quotation : string ->
- ('grm Loc.located -> raw_tactic_arg) -> ('grm Pcoq.Gram.entry * int option) -> unit
+ ('grm Loc.located -> raw_tactic_arg) -> ('grm Pcoq.Entry.t * int option) -> unit
(** [create_ltac_quotation name f e] adds a quotation rule to Ltac, that is,
Ltac grammar now accepts arguments of the form ["name" ":" "(" <e> ")"], and
generates an argument using [f] on the entry parsed by [e]. *)
@@ -65,17 +67,18 @@ val create_ltac_quotation : string ->
val print_ltacs : unit -> unit
(** Display the list of ltac definitions currently available. *)
-val print_located_tactic : Libnames.reference -> unit
+val print_located_tactic : Libnames.qualid -> unit
(** Display the absolute name of a tactic. *)
type _ ty_sig =
| TyNil : (Geninterp.interp_sign -> unit Proofview.tactic) ty_sig
| TyIdent : string * 'r ty_sig -> 'r ty_sig
| TyArg :
- (('a, 'b, 'c) Extend.ty_user_symbol * Names.Id.t) Loc.located * 'r ty_sig -> ('c -> 'r) ty_sig
+ ('a, 'b, 'c) Extend.ty_user_symbol * string * 'r ty_sig -> ('c -> 'r) ty_sig
| TyAnonArg :
- ('a, 'b, 'c) Extend.ty_user_symbol Loc.located * 'r ty_sig -> 'r ty_sig
+ ('a, 'b, 'c) Extend.ty_user_symbol * 'r ty_sig -> 'r ty_sig
type ty_ml = TyML : 'r ty_sig * 'r -> ty_ml
-val tactic_extend : string -> string -> level:Int.t -> ty_ml list -> unit
+val tactic_extend : string -> string -> level:Int.t ->
+ ?deprecation:deprecation -> ty_ml list -> unit
diff --git a/plugins/ltac/tacenv.ml b/plugins/ltac/tacenv.ml
index d5ab2d69..1f2c722b 100644
--- a/plugins/ltac/tacenv.ml
+++ b/plugins/ltac/tacenv.ml
@@ -52,7 +52,11 @@ let shortest_qualid_of_tactic kn =
(** Tactic notations (TacAlias) *)
type alias = KerName.t
-type alias_tactic = Id.t list * glob_tactic_expr
+type alias_tactic =
+ { alias_args: Id.t list;
+ alias_body: glob_tactic_expr;
+ alias_deprecation: Vernacinterp.deprecation option;
+ }
let alias_map = Summary.ref ~name:"tactic-alias"
(KNmap.empty : alias_tactic KNmap.t)
@@ -118,6 +122,7 @@ type ltac_entry = {
tac_for_ml : bool;
tac_body : glob_tactic_expr;
tac_redef : ModPath.t list;
+ tac_deprecation : Vernacinterp.deprecation option
}
let mactab =
@@ -130,43 +135,51 @@ let interp_ltac r = (KNmap.find r !mactab).tac_body
let is_ltac_for_ml_tactic r = (KNmap.find r !mactab).tac_for_ml
-let add kn b t =
- let entry = { tac_for_ml = b; tac_body = t; tac_redef = [] } in
+let add ~deprecation kn b t =
+ let entry = { tac_for_ml = b;
+ tac_body = t;
+ tac_redef = [];
+ tac_deprecation = deprecation;
+ } in
mactab := KNmap.add kn entry !mactab
let replace kn path t =
- let (path, _, _) = KerName.repr path in
+ let path = KerName.modpath path in
let entry _ e = { e with tac_body = t; tac_redef = path :: e.tac_redef } in
mactab := KNmap.modify kn entry !mactab
-let load_md i ((sp, kn), (local, id, b, t)) = match id with
+let tac_deprecation kn =
+ try (KNmap.find kn !mactab).tac_deprecation with Not_found -> None
+
+let load_md i ((sp, kn), (local, id, b, t, deprecation)) = match id with
| None ->
let () = if not local then push_tactic (Until i) sp kn in
- add kn b t
+ add ~deprecation kn b t
| Some kn0 -> replace kn0 kn t
-let open_md i ((sp, kn), (local, id, b, t)) = match id with
+let open_md i ((sp, kn), (local, id, b, t, deprecation)) = match id with
| None ->
let () = if not local then push_tactic (Exactly i) sp kn in
- add kn b t
+ add ~deprecation kn b t
| Some kn0 -> replace kn0 kn t
-let cache_md ((sp, kn), (local, id ,b, t)) = match id with
+let cache_md ((sp, kn), (local, id ,b, t, deprecation)) = match id with
| None ->
let () = push_tactic (Until 1) sp kn in
- add kn b t
+ add ~deprecation kn b t
| Some kn0 -> replace kn0 kn t
let subst_kind subst id = match id with
| None -> None
| Some kn -> Some (Mod_subst.subst_kn subst kn)
-let subst_md (subst, (local, id, b, t)) =
- (local, subst_kind subst id, b, Tacsubst.subst_tactic subst t)
+let subst_md (subst, (local, id, b, t, deprecation)) =
+ (local, subst_kind subst id, b, Tacsubst.subst_tactic subst t, deprecation)
-let classify_md (local, _, _, _ as o) = Substitute o
+let classify_md (local, _, _, _, _ as o) = Substitute o
-let inMD : bool * ltac_constant option * bool * glob_tactic_expr -> obj =
+let inMD : bool * ltac_constant option * bool * glob_tactic_expr *
+ Vernacinterp.deprecation option -> obj =
declare_object {(default_object "TAC-DEFINITION") with
cache_function = cache_md;
load_function = load_md;
@@ -174,8 +187,8 @@ let inMD : bool * ltac_constant option * bool * glob_tactic_expr -> obj =
subst_function = subst_md;
classify_function = classify_md}
-let register_ltac for_ml local id tac =
- ignore (Lib.add_leaf id (inMD (local, None, for_ml, tac)))
+let register_ltac for_ml local ?deprecation id tac =
+ ignore (Lib.add_leaf id (inMD (local, None, for_ml, tac, deprecation)))
-let redefine_ltac local kn tac =
- Lib.add_anonymous_leaf (inMD (local, Some kn, false, tac))
+let redefine_ltac local ?deprecation kn tac =
+ Lib.add_anonymous_leaf (inMD (local, Some kn, false, tac, deprecation))
diff --git a/plugins/ltac/tacenv.mli b/plugins/ltac/tacenv.mli
index e0bac67d..d5d36c97 100644
--- a/plugins/ltac/tacenv.mli
+++ b/plugins/ltac/tacenv.mli
@@ -12,6 +12,7 @@ open Names
open Libnames
open Tacexpr
open Geninterp
+open Vernacinterp
(** This module centralizes the various ways of registering tactics. *)
@@ -29,7 +30,11 @@ val shortest_qualid_of_tactic : ltac_constant -> qualid
type alias = KerName.t
(** Type of tactic alias, used in the [TacAlias] node. *)
-type alias_tactic = Id.t list * glob_tactic_expr
+type alias_tactic =
+ { alias_args: Id.t list;
+ alias_body: glob_tactic_expr;
+ alias_deprecation: Vernacinterp.deprecation option;
+ }
(** Contents of a tactic notation *)
val register_alias : alias -> alias_tactic -> unit
@@ -43,7 +48,8 @@ val check_alias : alias -> bool
(** {5 Coq tactic definitions} *)
-val register_ltac : bool -> bool -> Id.t -> glob_tactic_expr -> unit
+val register_ltac : bool -> bool -> ?deprecation:deprecation -> Id.t ->
+ glob_tactic_expr -> unit
(** Register a new Ltac with the given name and body.
The first boolean indicates whether this is done from ML side, rather than
@@ -51,7 +57,8 @@ val register_ltac : bool -> bool -> Id.t -> glob_tactic_expr -> unit
definition. It also puts the Ltac name in the nametab, so that it can be
used unqualified. *)
-val redefine_ltac : bool -> KerName.t -> glob_tactic_expr -> unit
+val redefine_ltac : bool -> ?deprecation:deprecation -> KerName.t ->
+ glob_tactic_expr -> unit
(** Replace a Ltac with the given name and body. If the boolean flag is set
to true, then this is a local redefinition. *)
@@ -61,6 +68,9 @@ val interp_ltac : KerName.t -> glob_tactic_expr
val is_ltac_for_ml_tactic : KerName.t -> bool
(** Whether the tactic is defined from ML-side *)
+val tac_deprecation : KerName.t -> deprecation option
+(** The tactic deprecation notice, if any *)
+
type ltac_entry = {
tac_for_ml : bool;
(** Whether the tactic is defined from ML-side *)
@@ -68,6 +78,8 @@ type ltac_entry = {
(** The current body of the tactic *)
tac_redef : ModPath.t list;
(** List of modules redefining the tactic in reverse chronological order *)
+ tac_deprecation : deprecation option;
+ (** Deprecation notice to be printed when the tactic is used *)
}
val ltac_entries : unit -> ltac_entry KNmap.t
diff --git a/plugins/ltac/tacexpr.ml b/plugins/ltac/tacexpr.ml
index 8b0c4404..11d13d3a 100644
--- a/plugins/ltac/tacexpr.ml
+++ b/plugins/ltac/tacexpr.ml
@@ -15,7 +15,7 @@ open Libnames
open Genredexpr
open Genarg
open Pattern
-open Misctypes
+open Tactypes
open Locus
type ltac_constant = KerName.t
@@ -35,30 +35,46 @@ type advanced_flag = bool (* true = advanced false = basic *)
type letin_flag = bool (* true = use local def false = use Leibniz *)
type clear_flag = bool option (* true = clear hyp, false = keep hyp, None = use default *)
-type goal_selector = Vernacexpr.goal_selector =
+type goal_selector = Goal_select.t =
+ | SelectAlreadyFocused
+ [@ocaml.deprecated "Use constructors in [Goal_select]"]
| SelectNth of int
+ [@ocaml.deprecated "Use constructors in [Goal_select]"]
| SelectList of (int * int) list
+ [@ocaml.deprecated "Use constructors in [Goal_select]"]
| SelectId of Id.t
+ [@ocaml.deprecated "Use constructors in [Goal_select]"]
| SelectAll
+ [@ocaml.deprecated "Use constructors in [Goal_select]"]
+[@@ocaml.deprecated "Use [Goal_select.t]"]
-type 'a core_destruction_arg = 'a Misctypes.core_destruction_arg =
+type 'a core_destruction_arg = 'a Tactics.core_destruction_arg =
| ElimOnConstr of 'a
+ [@ocaml.deprecated "Use constructors in [Tactics]"]
| ElimOnIdent of lident
+ [@ocaml.deprecated "Use constructors in [Tactics]"]
| ElimOnAnonHyp of int
+ [@ocaml.deprecated "Use constructors in [Tactics]"]
+[@@ocaml.deprecated "Use Tactics.core_destruction_arg"]
type 'a destruction_arg =
- clear_flag * 'a core_destruction_arg
+ clear_flag * 'a Tactics.core_destruction_arg
+[@@ocaml.deprecated "Use Tactics.destruction_arg"]
-type inversion_kind = Misctypes.inversion_kind =
+type inversion_kind = Inv.inversion_kind =
| SimpleInversion
+ [@ocaml.deprecated "Use constructors in [Inv]"]
| FullInversion
+ [@ocaml.deprecated "Use constructors in [Inv]"]
| FullInversionClear
+ [@ocaml.deprecated "Use constructors in [Inv]"]
+[@@ocaml.deprecated "Use Tactics.inversion_kind"]
type ('c,'d,'id) inversion_strength =
| NonDepInversion of
- inversion_kind * 'id list * 'd or_and_intro_pattern_expr CAst.t or_var option
+ Inv.inversion_kind * 'id list * 'd or_and_intro_pattern_expr CAst.t or_var option
| DepInversion of
- inversion_kind * 'c option * 'd or_and_intro_pattern_expr CAst.t or_var option
+ Inv.inversion_kind * 'c option * 'd or_and_intro_pattern_expr CAst.t or_var option
| InversionUsing of 'c * 'id list
type ('a,'b) location = HypLocation of 'a | ConclLocation of 'b
@@ -69,8 +85,8 @@ type 'id message_token =
| MsgIdent of 'id
type ('dconstr,'id) induction_clause =
- 'dconstr with_bindings destruction_arg *
- (intro_pattern_naming_expr CAst.t option (* eqn:... *)
+ 'dconstr with_bindings Tactics.destruction_arg *
+ (Namegen.intro_pattern_naming_expr CAst.t option (* eqn:... *)
* 'dconstr or_and_intro_pattern_expr CAst.t or_var option) (* as ... *)
* 'id clause_expr option (* in ... *)
@@ -112,7 +128,7 @@ type ml_tactic_entry = {
(** Composite types *)
-type glob_constr_and_expr = Tactypes.glob_constr_and_expr
+type glob_constr_and_expr = Genintern.glob_constr_and_expr
type open_constr_expr = unit * constr_expr
type open_glob_constr = unit * glob_constr_and_expr
@@ -129,7 +145,7 @@ type delayed_open_constr = EConstr.constr delayed_open
type intro_pattern = delayed_open_constr intro_pattern_expr CAst.t
type intro_patterns = delayed_open_constr intro_pattern_expr CAst.t list
type or_and_intro_pattern = delayed_open_constr or_and_intro_pattern_expr CAst.t
-type intro_pattern_naming = intro_pattern_naming_expr CAst.t
+type intro_pattern_naming = Namegen.intro_pattern_naming_expr CAst.t
(** Generic expressions for atomic tactics *)
@@ -147,7 +163,7 @@ type 'a gen_atomic_tactic_expr =
'dtrm intro_pattern_expr CAst.t option * 'trm
| TacGeneralize of ('trm with_occurrences * Name.t) list
| TacLetTac of evars_flag * Name.t * 'trm * 'nam clause_expr * letin_flag *
- intro_pattern_naming_expr CAst.t option
+ Namegen.intro_pattern_naming_expr CAst.t option
(* Derived basic tactics *)
| TacInductionDestruct of
@@ -159,7 +175,7 @@ type 'a gen_atomic_tactic_expr =
(* Equality and inversion *)
| TacRewrite of evars_flag *
- (bool * multi * 'dtrm with_bindings_arg) list * 'nam clause_expr *
+ (bool * Equality.multi * 'dtrm with_bindings_arg) list * 'nam clause_expr *
(* spiwack: using ['dtrm] here is a small hack, may not be
stable by a change in the representation of delayed
terms. Because, in fact, it is the whole "with_bindings"
@@ -265,7 +281,7 @@ and 'a gen_tactic_expr =
('p,'a gen_tactic_expr) match_rule list
| TacFun of 'a gen_tactic_fun_ast
| TacArg of 'a gen_tactic_arg located
- | TacSelect of goal_selector * 'a gen_tactic_expr
+ | TacSelect of Goal_select.t * 'a gen_tactic_expr
(* For ML extensions *)
| TacML of (ml_tactic_entry * 'a gen_tactic_arg list) Loc.located
(* For syntax extensions *)
@@ -300,7 +316,7 @@ constraint 'a = <
type g_trm = glob_constr_and_expr
type g_pat = glob_constr_pattern_and_expr
-type g_cst = evaluable_global_reference and_short_name or_var
+type g_cst = evaluable_global_reference Stdarg.and_short_name or_var
type g_ref = ltac_constant located or_var
type g_nam = lident
@@ -328,8 +344,8 @@ type glob_tactic_arg =
type r_trm = constr_expr
type r_pat = constr_pattern_expr
-type r_cst = reference or_by_notation
-type r_ref = reference
+type r_cst = qualid or_by_notation
+type r_ref = qualid
type r_nam = lident
type r_lev = rlevel
@@ -393,5 +409,5 @@ type ltac_call_kind =
type ltac_trace = ltac_call_kind Loc.located list
type tacdef_body =
- | TacticDefinition of lident * raw_tactic_expr (* indicates that user employed ':=' in Ltac body *)
- | TacticRedefinition of reference * raw_tactic_expr (* indicates that user employed '::=' in Ltac body *)
+ | TacticDefinition of lident * raw_tactic_expr (* indicates that user employed ':=' in Ltac body *)
+ | TacticRedefinition of qualid * raw_tactic_expr (* indicates that user employed '::=' in Ltac body *)
diff --git a/plugins/ltac/tacexpr.mli b/plugins/ltac/tacexpr.mli
index 8b0c4404..6b131eda 100644
--- a/plugins/ltac/tacexpr.mli
+++ b/plugins/ltac/tacexpr.mli
@@ -15,8 +15,8 @@ open Libnames
open Genredexpr
open Genarg
open Pattern
-open Misctypes
open Locus
+open Tactypes
type ltac_constant = KerName.t
@@ -35,30 +35,46 @@ type advanced_flag = bool (* true = advanced false = basic *)
type letin_flag = bool (* true = use local def false = use Leibniz *)
type clear_flag = bool option (* true = clear hyp, false = keep hyp, None = use default *)
-type goal_selector = Vernacexpr.goal_selector =
+type goal_selector = Goal_select.t =
+ | SelectAlreadyFocused
+ [@ocaml.deprecated "Use constructors in [Goal_select]"]
| SelectNth of int
+ [@ocaml.deprecated "Use constructors in [Goal_select]"]
| SelectList of (int * int) list
+ [@ocaml.deprecated "Use constructors in [Goal_select]"]
| SelectId of Id.t
+ [@ocaml.deprecated "Use constructors in [Goal_select]"]
| SelectAll
+ [@ocaml.deprecated "Use constructors in [Goal_select]"]
+[@@ocaml.deprecated "Use Vernacexpr.goal_selector"]
-type 'a core_destruction_arg = 'a Misctypes.core_destruction_arg =
+type 'a core_destruction_arg = 'a Tactics.core_destruction_arg =
| ElimOnConstr of 'a
+ [@ocaml.deprecated "Use constructors in [Tactics]"]
| ElimOnIdent of lident
+ [@ocaml.deprecated "Use constructors in [Tactics]"]
| ElimOnAnonHyp of int
+ [@ocaml.deprecated "Use constructors in [Tactics]"]
+[@@ocaml.deprecated "Use Tactics.core_destruction_arg"]
type 'a destruction_arg =
- clear_flag * 'a core_destruction_arg
+ clear_flag * 'a Tactics.core_destruction_arg
+[@@ocaml.deprecated "Use Tactics.destruction_arg"]
-type inversion_kind = Misctypes.inversion_kind =
+type inversion_kind = Inv.inversion_kind =
| SimpleInversion
+ [@ocaml.deprecated "Use constructors in [Inv]"]
| FullInversion
+ [@ocaml.deprecated "Use constructors in [Inv]"]
| FullInversionClear
+ [@ocaml.deprecated "Use constructors in [Inv]"]
+[@@ocaml.deprecated "Use Tactics.inversion_kind"]
type ('c,'d,'id) inversion_strength =
| NonDepInversion of
- inversion_kind * 'id list * 'd or_and_intro_pattern_expr CAst.t or_var option
+ Inv.inversion_kind * 'id list * 'd or_and_intro_pattern_expr CAst.t or_var option
| DepInversion of
- inversion_kind * 'c option * 'd or_and_intro_pattern_expr CAst.t or_var option
+ Inv.inversion_kind * 'c option * 'd or_and_intro_pattern_expr CAst.t or_var option
| InversionUsing of 'c * 'id list
type ('a,'b) location = HypLocation of 'a | ConclLocation of 'b
@@ -69,8 +85,8 @@ type 'id message_token =
| MsgIdent of 'id
type ('dconstr,'id) induction_clause =
- 'dconstr with_bindings destruction_arg *
- (intro_pattern_naming_expr CAst.t option (* eqn:... *)
+ 'dconstr with_bindings Tactics.destruction_arg *
+ (Namegen.intro_pattern_naming_expr CAst.t option (* eqn:... *)
* 'dconstr or_and_intro_pattern_expr CAst.t or_var option) (* as ... *)
* 'id clause_expr option (* in ... *)
@@ -112,7 +128,7 @@ type ml_tactic_entry = {
(** Composite types *)
-type glob_constr_and_expr = Tactypes.glob_constr_and_expr
+type glob_constr_and_expr = Genintern.glob_constr_and_expr
type open_constr_expr = unit * constr_expr
type open_glob_constr = unit * glob_constr_and_expr
@@ -129,7 +145,7 @@ type delayed_open_constr = EConstr.constr delayed_open
type intro_pattern = delayed_open_constr intro_pattern_expr CAst.t
type intro_patterns = delayed_open_constr intro_pattern_expr CAst.t list
type or_and_intro_pattern = delayed_open_constr or_and_intro_pattern_expr CAst.t
-type intro_pattern_naming = intro_pattern_naming_expr CAst.t
+type intro_pattern_naming = Namegen.intro_pattern_naming_expr CAst.t
(** Generic expressions for atomic tactics *)
@@ -147,7 +163,7 @@ type 'a gen_atomic_tactic_expr =
'dtrm intro_pattern_expr CAst.t option * 'trm
| TacGeneralize of ('trm with_occurrences * Name.t) list
| TacLetTac of evars_flag * Name.t * 'trm * 'nam clause_expr * letin_flag *
- intro_pattern_naming_expr CAst.t option
+ Namegen.intro_pattern_naming_expr CAst.t option
(* Derived basic tactics *)
| TacInductionDestruct of
@@ -159,7 +175,7 @@ type 'a gen_atomic_tactic_expr =
(* Equality and inversion *)
| TacRewrite of evars_flag *
- (bool * multi * 'dtrm with_bindings_arg) list * 'nam clause_expr *
+ (bool * Equality.multi * 'dtrm with_bindings_arg) list * 'nam clause_expr *
(* spiwack: using ['dtrm] here is a small hack, may not be
stable by a change in the representation of delayed
terms. Because, in fact, it is the whole "with_bindings"
@@ -265,7 +281,7 @@ and 'a gen_tactic_expr =
('p,'a gen_tactic_expr) match_rule list
| TacFun of 'a gen_tactic_fun_ast
| TacArg of 'a gen_tactic_arg located
- | TacSelect of goal_selector * 'a gen_tactic_expr
+ | TacSelect of Goal_select.t * 'a gen_tactic_expr
(* For ML extensions *)
| TacML of (ml_tactic_entry * 'a gen_tactic_arg list) Loc.located
(* For syntax extensions *)
@@ -300,7 +316,7 @@ constraint 'a = <
type g_trm = glob_constr_and_expr
type g_pat = glob_constr_pattern_and_expr
-type g_cst = evaluable_global_reference and_short_name or_var
+type g_cst = evaluable_global_reference Stdarg.and_short_name or_var
type g_ref = ltac_constant located or_var
type g_nam = lident
@@ -328,8 +344,8 @@ type glob_tactic_arg =
type r_trm = constr_expr
type r_pat = constr_pattern_expr
-type r_cst = reference or_by_notation
-type r_ref = reference
+type r_cst = qualid or_by_notation
+type r_ref = qualid
type r_nam = lident
type r_lev = rlevel
@@ -393,5 +409,5 @@ type ltac_call_kind =
type ltac_trace = ltac_call_kind Loc.located list
type tacdef_body =
- | TacticDefinition of lident * raw_tactic_expr (* indicates that user employed ':=' in Ltac body *)
- | TacticRedefinition of reference * raw_tactic_expr (* indicates that user employed '::=' in Ltac body *)
+ | TacticDefinition of lident * raw_tactic_expr (* indicates that user employed ':=' in Ltac body *)
+ | TacticRedefinition of qualid * raw_tactic_expr (* indicates that user employed '::=' in Ltac body *)
diff --git a/plugins/ltac/tacintern.ml b/plugins/ltac/tacintern.ml
index 9ad9e152..5501cf92 100644
--- a/plugins/ltac/tacintern.ml
+++ b/plugins/ltac/tacintern.ml
@@ -27,7 +27,9 @@ open Tacexpr
open Genarg
open Stdarg
open Tacarg
-open Misctypes
+open Namegen
+open Tactypes
+open Tactics
open Locus
(** Globalization of tactic expressions :
@@ -91,88 +93,104 @@ let intern_or_var f ist = function
let intern_int_or_var = intern_or_var (fun (n : int) -> n)
let intern_string_or_var = intern_or_var (fun (s : string) -> s)
-let intern_global_reference ist = function
- | {CAst.loc;v=Ident id} when find_var id ist ->
- ArgVar (make ?loc id)
- | r ->
- let {CAst.loc} as lqid = qualid_of_reference r in
- try ArgArg (loc,locate_global_with_alias lqid)
- with Not_found -> error_global_not_found lqid
-
-let intern_ltac_variable ist = function
- | {loc;v=Ident id} ->
- if find_var id ist then
- (* A local variable of any type *)
- ArgVar (make ?loc id)
- else raise Not_found
- | _ ->
- raise Not_found
-
-let intern_constr_reference strict ist = function
- | {v=Ident id} as r when not strict && find_hyp id ist ->
- (DAst.make @@ GVar id), Some (make @@ CRef (r,None))
- | {v=Ident id} as r when find_var id ist ->
- (DAst.make @@ GVar id), if strict then None else Some (make @@ CRef (r,None))
- | r ->
- let {loc} as lqid = qualid_of_reference r in
- DAst.make @@ GRef (locate_global_with_alias lqid,None),
- if strict then None else Some (make @@ CRef (r,None))
+let intern_global_reference ist qid =
+ if qualid_is_ident qid && find_var (qualid_basename qid) ist then
+ ArgVar (make ?loc:qid.CAst.loc @@ qualid_basename qid)
+ else
+ try ArgArg (qid.CAst.loc,locate_global_with_alias qid)
+ with Not_found -> error_global_not_found qid
+
+let intern_ltac_variable ist qid =
+ if qualid_is_ident qid && find_var (qualid_basename qid) ist then
+ (* A local variable of any type *)
+ ArgVar (make ?loc:qid.CAst.loc @@ qualid_basename qid)
+ else raise Not_found
+
+let intern_constr_reference strict ist qid =
+ let id = qualid_basename qid in
+ if qualid_is_ident qid && not strict && find_hyp (qualid_basename qid) ist then
+ (DAst.make @@ GVar id), Some (make @@ CRef (qid,None))
+ else if qualid_is_ident qid && find_var (qualid_basename qid) ist then
+ (DAst.make @@ GVar id), if strict then None else Some (make @@ CRef (qid,None))
+ else
+ DAst.make @@ GRef (locate_global_with_alias qid,None),
+ if strict then None else Some (make @@ CRef (qid,None))
(* Internalize an isolated reference in position of tactic *)
-let intern_isolated_global_tactic_reference r =
- let {loc;v=qid} = qualid_of_reference r in
- TacCall (Loc.tag ?loc (ArgArg (loc,Tacenv.locate_tactic qid),[]))
-
-let intern_isolated_tactic_reference strict ist r =
+let warn_deprecated_tactic =
+ CWarnings.create ~name:"deprecated-tactic" ~category:"deprecated"
+ (fun (qid,depr) -> str "Tactic " ++ pr_qualid qid ++
+ strbrk " is deprecated" ++
+ pr_opt (fun since -> str "since " ++ str since) depr.Vernacinterp.since ++
+ str "." ++ pr_opt (fun note -> str note) depr.Vernacinterp.note)
+
+let warn_deprecated_alias =
+ CWarnings.create ~name:"deprecated-tactic-notation" ~category:"deprecated"
+ (fun (kn,depr) -> str "Tactic Notation " ++ Pptactic.pr_alias_key kn ++
+ strbrk " is deprecated since" ++
+ pr_opt (fun since -> str "since " ++ str since) depr.Vernacinterp.since ++
+ str "." ++ pr_opt (fun note -> str note) depr.Vernacinterp.note)
+
+let intern_isolated_global_tactic_reference qid =
+ let loc = qid.CAst.loc in
+ let kn = Tacenv.locate_tactic qid in
+ Option.iter (fun depr -> warn_deprecated_tactic ?loc (qid,depr)) @@
+ Tacenv.tac_deprecation kn;
+ TacCall (Loc.tag ?loc (ArgArg (loc,kn),[]))
+
+let intern_isolated_tactic_reference strict ist qid =
(* An ltac reference *)
- try Reference (intern_ltac_variable ist r)
+ try Reference (intern_ltac_variable ist qid)
with Not_found ->
(* A global tactic *)
- try intern_isolated_global_tactic_reference r
+ try intern_isolated_global_tactic_reference qid
with Not_found ->
(* Tolerance for compatibility, allow not to use "constr:" *)
- try ConstrMayEval (ConstrTerm (intern_constr_reference strict ist r))
+ try ConstrMayEval (ConstrTerm (intern_constr_reference strict ist qid))
with Not_found ->
(* Reference not found *)
- error_global_not_found (qualid_of_reference r)
+ error_global_not_found qid
(* Internalize an applied tactic reference *)
-let intern_applied_global_tactic_reference r =
- let {loc;v=qid} = qualid_of_reference r in
- ArgArg (loc,Tacenv.locate_tactic qid)
+let intern_applied_global_tactic_reference qid =
+ let loc = qid.CAst.loc in
+ let kn = Tacenv.locate_tactic qid in
+ Option.iter (fun depr -> warn_deprecated_tactic ?loc (qid,depr)) @@
+ Tacenv.tac_deprecation kn;
+ ArgArg (loc,kn)
-let intern_applied_tactic_reference ist r =
+let intern_applied_tactic_reference ist qid =
(* An ltac reference *)
- try intern_ltac_variable ist r
+ try intern_ltac_variable ist qid
with Not_found ->
(* A global tactic *)
- try intern_applied_global_tactic_reference r
+ try intern_applied_global_tactic_reference qid
with Not_found ->
(* Reference not found *)
- error_global_not_found (qualid_of_reference r)
+ error_global_not_found qid
(* Intern a reference parsed in a non-tactic entry *)
-let intern_non_tactic_reference strict ist r =
+let intern_non_tactic_reference strict ist qid =
(* An ltac reference *)
- try Reference (intern_ltac_variable ist r)
+ try Reference (intern_ltac_variable ist qid)
with Not_found ->
(* A constr reference *)
- try ConstrMayEval (ConstrTerm (intern_constr_reference strict ist r))
+ try ConstrMayEval (ConstrTerm (intern_constr_reference strict ist qid))
with Not_found ->
(* Tolerance for compatibility, allow not to use "ltac:" *)
- try intern_isolated_global_tactic_reference r
+ try intern_isolated_global_tactic_reference qid
with Not_found ->
(* By convention, use IntroIdentifier for unbound ident, when not in a def *)
- match r with
- | {loc;v=Ident id} when not strict ->
- let ipat = in_gen (glbwit wit_intro_pattern) (make ?loc @@ IntroNaming (IntroIdentifier id)) in
+ if qualid_is_ident qid && not strict then
+ let id = qualid_basename qid in
+ let ipat = in_gen (glbwit wit_intro_pattern) (make ?loc:qid.CAst.loc @@ IntroNaming (IntroIdentifier id)) in
TacGeneric ipat
- | _ ->
- (* Reference not found *)
- error_global_not_found (qualid_of_reference r)
+ else
+ (* Reference not found *)
+ error_global_not_found qid
let intern_message_token ist = function
| (MsgString _ | MsgInt _ as x) -> x
@@ -268,7 +286,7 @@ let intern_destruction_arg ist = function
| clear,ElimOnIdent {loc;v=id} ->
if !strict_check then
(* If in a defined tactic, no intros-until *)
- let c, p = intern_constr ist (make @@ CRef (make @@ Ident id, None)) in
+ let c, p = intern_constr ist (make @@ CRef (qualid_of_ident id, None)) in
match DAst.get c with
| GVar id -> clear,ElimOnIdent (make ?loc:c.loc id)
| _ -> clear,ElimOnConstr ((c, p), NoBindings)
@@ -276,16 +294,15 @@ let intern_destruction_arg ist = function
clear,ElimOnIdent (make ?loc id)
let short_name = function
- | {v=AN {loc;v=Ident id}} when not !strict_check -> Some (make ?loc id)
+ | {v=AN qid} when qualid_is_ident qid && not !strict_check ->
+ Some (make ?loc:qid.CAst.loc @@ qualid_basename qid)
| _ -> None
-let intern_evaluable_global_reference ist r =
- let lqid = qualid_of_reference r in
- try evaluable_of_global_reference ist.genv (locate_global_with_alias ~head:true lqid)
+let intern_evaluable_global_reference ist qid =
+ try evaluable_of_global_reference ist.genv (locate_global_with_alias ~head:true qid)
with Not_found ->
- match r with
- | {loc;v=Ident id} when not !strict_check -> EvalVarRef id
- | _ -> error_global_not_found lqid
+ if qualid_is_ident qid && not !strict_check then EvalVarRef (qualid_basename qid)
+ else error_global_not_found qid
let intern_evaluable_reference_or_by_notation ist = function
| {v=AN r} -> intern_evaluable_global_reference ist r
@@ -295,14 +312,19 @@ let intern_evaluable_reference_or_by_notation ist = function
(function ConstRef _ | VarRef _ -> true | _ -> false) ntn sc)
(* Globalize a reduction expression *)
-let intern_evaluable ist = function
- | {loc;v=AN {v=Ident id}} when find_var id ist -> ArgVar (make ?loc id)
- | {loc;v=AN {v=Ident id}} when not !strict_check && find_hyp id ist ->
- ArgArg (EvalVarRef id, Some (make ?loc id))
- | r ->
- let e = intern_evaluable_reference_or_by_notation ist r in
- let na = short_name r in
- ArgArg (e,na)
+let intern_evaluable ist r =
+ let f ist r =
+ let e = intern_evaluable_reference_or_by_notation ist r in
+ let na = short_name r in
+ ArgArg (e,na)
+ in
+ match r with
+ | {v=AN qid} when qualid_is_ident qid && find_var (qualid_basename qid) ist ->
+ ArgVar (make ?loc:qid.CAst.loc @@ qualid_basename qid)
+ | {v=AN qid} when qualid_is_ident qid && not !strict_check && find_hyp (qualid_basename qid) ist ->
+ let id = qualid_basename qid in
+ ArgArg (EvalVarRef id, Some (make ?loc:qid.CAst.loc id))
+ | _ -> f ist r
let intern_unfold ist (l,qid) = (l,intern_evaluable ist qid)
@@ -355,7 +377,7 @@ let intern_typed_pattern_or_ref_with_occurrences ist (l,p) =
subterm matched when a pattern *)
let r = match r with
| {v=AN r} -> r
- | {loc} -> make ?loc @@ Qualid (qualid_of_path (path_of_global (smart_global r))) in
+ | {loc} -> (qualid_of_path ?loc (path_of_global (smart_global r))) in
let sign = {
Constrintern.ltac_vars = ist.ltacvars;
ltac_bound = Id.Set.empty;
@@ -643,6 +665,8 @@ and intern_tactic_seq onlytac ist = function
(* For extensions *)
| TacAlias (loc,(s,l)) ->
+ let alias = Tacenv.interp_alias s in
+ Option.iter (fun o -> warn_deprecated_alias ?loc (s,o)) @@ alias.Tacenv.alias_deprecation;
let l = List.map (intern_tacarg !strict_check false ist) l in
ist.ltacvars, TacAlias (Loc.tag ?loc (s,l))
| TacML (loc,(opn,l)) ->
diff --git a/plugins/ltac/tacintern.mli b/plugins/ltac/tacintern.mli
index fb32508c..9146fced 100644
--- a/plugins/ltac/tacintern.mli
+++ b/plugins/ltac/tacintern.mli
@@ -12,7 +12,7 @@ open Names
open Tacexpr
open Genarg
open Constrexpr
-open Misctypes
+open Tactypes
(** Globalization of tactic expressions :
Conversion from [raw_tactic_expr] to [glob_tactic_expr] *)
diff --git a/plugins/ltac/tacinterp.ml b/plugins/ltac/tacinterp.ml
index c6c4f469..b9e892e5 100644
--- a/plugins/ltac/tacinterp.ml
+++ b/plugins/ltac/tacinterp.ml
@@ -12,6 +12,7 @@ open Constrintern
open Patternops
open Pp
open CAst
+open Namegen
open Genredexpr
open Glob_term
open Glob_ops
@@ -35,7 +36,8 @@ open Stdarg
open Tacarg
open Printer
open Pretyping
-open Misctypes
+open Tactypes
+open Tactics
open Locus
open Tacintern
open Taccoerce
@@ -140,16 +142,6 @@ let extract_trace ist = match TacStore.get ist.extra f_trace with
| None -> []
| Some l -> l
-module Value = struct
-
- include Taccoerce.Value
-
- let of_closure ist tac =
- let closure = VFun (UnnamedAppl,extract_trace ist, ist.lfun, [], tac) in
- of_tacvalue closure
-
-end
-
let print_top_val env v = Pptactic.pr_value Pptactic.ltop v
let catching_error call_trace fail (e, info) =
@@ -291,6 +283,12 @@ let debugging_exception_step ist signal_anomaly e pp =
debugging_step ist (fun () ->
pp() ++ spc() ++ str "raised the exception" ++ fnl() ++ explain_exc e)
+let ensure_freshness env =
+ (* We anonymize declarations which we know will not be used *)
+ (* This assumes that the original context had no rels *)
+ process_rel_context
+ (fun d e -> EConstr.push_rel (Context.Rel.Declaration.set_name Anonymous d) e) env
+
(* Raise Not_found if not in interpretation sign *)
let try_interp_ltac_var coerce ist env {loc;v=id} =
let v = Id.Map.find id ist.lfun in
@@ -311,11 +309,11 @@ let interp_name ist env sigma = function
| Name id -> Name (interp_ident ist env sigma id)
let interp_intro_pattern_var loc ist env sigma id =
- try try_interp_ltac_var (coerce_to_intro_pattern env sigma) ist (Some (env,sigma)) (make ?loc id)
+ try try_interp_ltac_var (coerce_to_intro_pattern sigma) ist (Some (env,sigma)) (make ?loc id)
with Not_found -> IntroNaming (IntroIdentifier id)
let interp_intro_pattern_naming_var loc ist env sigma id =
- try try_interp_ltac_var (coerce_to_intro_pattern_naming env sigma) ist (Some (env,sigma)) (make ?loc id)
+ try try_interp_ltac_var (coerce_to_intro_pattern_naming sigma) ist (Some (env,sigma)) (make ?loc id)
with Not_found -> IntroIdentifier id
let interp_int ist ({loc;v=id} as locid) =
@@ -356,11 +354,11 @@ let interp_hyp_list ist env sigma l =
let interp_reference ist env sigma = function
| ArgArg (_,r) -> r
| ArgVar {loc;v=id} ->
- try try_interp_ltac_var (coerce_to_reference env sigma) ist (Some (env,sigma)) (make ?loc id)
+ try try_interp_ltac_var (coerce_to_reference sigma) ist (Some (env,sigma)) (make ?loc id)
with Not_found ->
try
VarRef (get_id (Environ.lookup_named id env))
- with Not_found -> error_global_not_found (make ?loc @@ qualid_of_ident id)
+ with Not_found -> error_global_not_found (qualid_of_ident ?loc id)
let try_interp_evaluable env (loc, id) =
let v = Environ.lookup_named id env in
@@ -376,14 +374,14 @@ let interp_evaluable ist env sigma = function
with Not_found ->
match r with
| EvalConstRef _ -> r
- | _ -> error_global_not_found (make ?loc @@ qualid_of_ident id)
+ | _ -> error_global_not_found (qualid_of_ident ?loc id)
end
| ArgArg (r,None) -> r
| ArgVar {loc;v=id} ->
try try_interp_ltac_var (coerce_to_evaluable_ref env sigma) ist (Some (env,sigma)) (make ?loc id)
with Not_found ->
try try_interp_evaluable env (loc, id)
- with Not_found -> error_global_not_found (make ?loc @@ qualid_of_ident id)
+ with Not_found -> error_global_not_found (qualid_of_ident ?loc id)
(* Interprets an hypothesis name *)
let interp_occurrences ist occs =
@@ -450,7 +448,7 @@ let default_fresh_id = Id.of_string "H"
let interp_fresh_id ist env sigma l =
let extract_ident ist env sigma id =
- try try_interp_ltac_var (coerce_to_ident_not_fresh env sigma)
+ try try_interp_ltac_var (coerce_to_ident_not_fresh sigma)
ist (Some (env,sigma)) (make id)
with Not_found -> id in
let ids = List.map_filter (function ArgVar {v=id} -> Some id | _ -> None) l in
@@ -473,7 +471,7 @@ let interp_fresh_id ist env sigma l =
(* Extract the uconstr list from lfun *)
let extract_ltac_constr_context ist env sigma =
let add_uconstr id v map =
- try Id.Map.add id (coerce_to_uconstr env v) map
+ try Id.Map.add id (coerce_to_uconstr v) map
with CannotCoerceTo _ -> map
in
let add_constr id v map =
@@ -642,7 +640,7 @@ let interp_closed_typed_pattern_with_occurrences ist env sigma (occs, a) =
Inr (pattern_of_constr env sigma (EConstr.to_constr sigma c)) in
(try try_interp_ltac_var coerce_eval_ref_or_constr ist (Some (env,sigma)) (make ?loc id)
with Not_found ->
- error_global_not_found (make ?loc @@ qualid_of_ident id))
+ error_global_not_found (qualid_of_ident ?loc id))
| Inl (ArgArg _ as b) -> Inl (interp_evaluable ist env sigma b)
| Inr c -> Inr (interp_typed_pattern ist env sigma c) in
interp_occurrences ist occs, p
@@ -689,13 +687,11 @@ let interp_may_eval f ist env sigma = function
| ConstrContext ({loc;v=s},c) ->
(try
let (sigma,ic) = f ist env sigma c in
- let ctxt = coerce_to_constr_context (Id.Map.find s ist.lfun) in
+ let ctxt = try_interp_ltac_var coerce_to_constr_context ist (Some (env, sigma)) (make ?loc s) in
let ctxt = EConstr.Unsafe.to_constr ctxt in
- let evdref = ref sigma in
- let ic = EConstr.Unsafe.to_constr ic in
+ let ic = EConstr.Unsafe.to_constr ic in
let c = subst_meta [Constr_matching.special_meta,ic] ctxt in
- let c = Typing.e_solve_evars env evdref (EConstr.of_constr c) in
- !evdref , c
+ Typing.solve_evars env sigma (EConstr.of_constr c)
with
| Not_found ->
user_err ?loc ~hdr:"interp_may_eval"
@@ -800,7 +796,7 @@ and interp_or_and_intro_pattern ist env sigma = function
and interp_intro_pattern_list_as_list ist env sigma = function
| [{loc;v=IntroNaming (IntroIdentifier id)}] as l ->
- (try sigma, coerce_to_intro_pattern_list ?loc env sigma (Id.Map.find id ist.lfun)
+ (try sigma, coerce_to_intro_pattern_list ?loc sigma (Id.Map.find id ist.lfun)
with Not_found | CannotCoerceTo _ ->
List.fold_left_map (interp_intro_pattern ist env) sigma l)
| l -> List.fold_left_map (interp_intro_pattern ist env) sigma l
@@ -843,7 +839,7 @@ let interp_declared_or_quantified_hypothesis ist env sigma = function
| AnonHyp n -> AnonHyp n
| NamedHyp id ->
try try_interp_ltac_var
- (coerce_to_decl_or_quant_hyp env sigma) ist (Some (env,sigma)) (make id)
+ (coerce_to_decl_or_quant_hyp sigma) ist (Some (env,sigma)) (make id)
with Not_found -> NamedHyp id
let interp_binding ist env sigma {loc;v=(b,c)} =
@@ -926,7 +922,7 @@ let interp_destruction_arg ist gl arg =
if Tactics.is_quantified_hypothesis id gl then
keep,ElimOnIdent (make ?loc id)
else
- let c = (DAst.make ?loc @@ GVar id,Some (make @@ CRef (make ?loc @@ Ident id,None))) in
+ let c = (DAst.make ?loc @@ GVar id,Some (make @@ CRef (qualid_of_ident ?loc id,None))) in
let f env sigma =
let (sigma,c) = interp_open_constr ist env sigma c in
(sigma, (c,NoBindings))
@@ -1126,17 +1122,17 @@ and eval_tactic ist tac : unit Proofview.tactic = match tac with
| TacSelect (sel, tac) -> Tacticals.New.tclSELECT sel (interp_tactic ist tac)
(* For extensions *)
| TacAlias (loc,(s,l)) ->
- let (ids, body) = Tacenv.interp_alias s in
+ let alias = Tacenv.interp_alias s in
let (>>=) = Ftactic.bind in
let interp_vars = Ftactic.List.map (fun v -> interp_tacarg ist v) l in
let tac l =
let addvar x v accu = Id.Map.add x v accu in
- let lfun = List.fold_right2 addvar ids l ist.lfun in
+ let lfun = List.fold_right2 addvar alias.Tacenv.alias_args l ist.lfun in
Ftactic.lift (push_trace (loc,LtacNotationCall s) ist) >>= fun trace ->
let ist = {
lfun = lfun;
extra = TacStore.set ist.extra f_trace trace; } in
- val_interp ist body >>= fun v ->
+ val_interp ist alias.Tacenv.alias_body >>= fun v ->
Ftactic.lift (tactic_of_value ist v)
in
let tac =
@@ -1148,7 +1144,7 @@ and eval_tactic ist tac : unit Proofview.tactic = match tac with
some more elaborate solution will have to be used. *)
in
let tac =
- let len1 = List.length ids in
+ let len1 = List.length alias.Tacenv.alias_args in
let len2 = List.length l in
if len1 = len2 then tac
else Tacticals.New.tclZEROMSG (str "Arguments length mismatch: \
@@ -1308,7 +1304,7 @@ and tactic_of_value ist vle =
match appl with
UnnamedAppl -> "An unnamed user-defined tactic"
| GlbAppl apps ->
- let nms = List.map (fun (kn,_) -> Names.KerName.to_string kn) apps in
+ let nms = List.map (fun (kn,_) -> string_of_qualid (Tacenv.shortest_qualid_of_tactic kn)) apps in
match nms with
[] -> assert false
| kn::_ -> "The user-defined tactic \"" ^ kn ^ "\"" (* TODO: when do we not have a singleton? *)
@@ -1748,15 +1744,15 @@ and interp_atomic ist tac : unit Proofview.tactic =
| AllOccurrences | NoOccurrences -> true
| _ -> false
in
- let c_interp patvars sigma =
+ let c_interp patvars env sigma =
let lfun' = Id.Map.fold (fun id c lfun ->
Id.Map.add id (Value.of_constr c) lfun)
patvars ist.lfun
in
let ist = { ist with lfun = lfun' } in
if is_onhyps && is_onconcl
- then interp_type ist (pf_env gl) sigma c
- else interp_constr ist (pf_env gl) sigma c
+ then interp_type ist env sigma c
+ else interp_constr ist env sigma c
in
Tactics.change None c_interp (interp_clause ist (pf_env gl) (project gl) cl)
end
@@ -1769,11 +1765,12 @@ and interp_atomic ist tac : unit Proofview.tactic =
let sigma = project gl in
let op = interp_typed_pattern ist env sigma op in
let to_catch = function Not_found -> true | e -> CErrors.is_anomaly e in
- let c_interp patvars sigma =
+ let c_interp patvars env sigma =
let lfun' = Id.Map.fold (fun id c lfun ->
Id.Map.add id (Value.of_constr c) lfun)
patvars ist.lfun
in
+ let env = ensure_freshness env in
let ist = { ist with lfun = lfun' } in
try
interp_constr ist env sigma c
@@ -1861,6 +1858,31 @@ let eval_tactic_ist ist t =
Proofview.tclLIFT db_initialize <*>
interp_tactic ist t
+(** FFI *)
+
+module Value = struct
+
+ include Taccoerce.Value
+
+ let of_closure ist tac =
+ let closure = VFun (UnnamedAppl,extract_trace ist, ist.lfun, [], tac) in
+ of_tacvalue closure
+
+ (** Apply toplevel tactic values *)
+ let apply (f : value) (args: value list) =
+ let fold arg (i, vars, lfun) =
+ let id = Id.of_string ("x" ^ string_of_int i) in
+ let x = Reference (ArgVar CAst.(make id)) in
+ (succ i, x :: vars, Id.Map.add id arg lfun)
+ in
+ let (_, args, lfun) = List.fold_right fold args (0, [], Id.Map.empty) in
+ let lfun = Id.Map.add (Id.of_string "F") f lfun in
+ let ist = { (default_ist ()) with lfun = lfun; } in
+ let tac = TacArg(Loc.tag @@ TacCall (Loc.tag (ArgVar CAst.(make @@ Id.of_string "F"),args))) in
+ eval_tactic_ist ist tac
+
+end
+
(* globalization + interpretation *)
@@ -2009,7 +2031,8 @@ let interp_redexp env sigma r =
let _ =
let eval lfun env sigma ty tac =
- let ist = { lfun = lfun; extra = TacStore.empty; } in
+ let extra = TacStore.set TacStore.empty f_debug (get_debug ()) in
+ let ist = { lfun = lfun; extra; } in
let tac = interp_tactic ist tac in
let (c, sigma) = Pfedit.refine_by_tactic env sigma ty tac in
(EConstr.of_constr c, sigma)
diff --git a/plugins/ltac/tacinterp.mli b/plugins/ltac/tacinterp.mli
index bd44bdbe..f9883e44 100644
--- a/plugins/ltac/tacinterp.mli
+++ b/plugins/ltac/tacinterp.mli
@@ -14,7 +14,7 @@ open EConstr
open Tacexpr
open Genarg
open Redexpr
-open Misctypes
+open Tactypes
val ltac_trace_info : ltac_trace Exninfo.t
@@ -28,6 +28,7 @@ sig
val to_list : t -> t list option
val of_closure : Geninterp.interp_sign -> glob_tactic_expr -> t
val cast : 'a typed_abstract_argument_type -> Geninterp.Val.t -> 'a
+ val apply : t -> t list -> unit Proofview.tactic
end
(** Values for interpretation *)
@@ -131,7 +132,7 @@ val interp_ltac_var : (value -> 'a) -> interp_sign ->
val interp_int : interp_sign -> lident -> int
-val interp_int_or_var : interp_sign -> int or_var -> int
+val interp_int_or_var : interp_sign -> int Locus.or_var -> int
val default_ist : unit -> Geninterp.interp_sign
(** Empty ist with debug set on the current value. *)
diff --git a/plugins/ltac/tacsubst.ml b/plugins/ltac/tacsubst.ml
index a1d8b087..4626378d 100644
--- a/plugins/ltac/tacsubst.ml
+++ b/plugins/ltac/tacsubst.ml
@@ -14,7 +14,8 @@ open Mod_subst
open Genarg
open Stdarg
open Tacarg
-open Misctypes
+open Tactypes
+open Tactics
open Globnames
open Genredexpr
open Patternops
@@ -75,7 +76,7 @@ let subst_and_short_name f (c,n) =
(* assert (n=None); *)(* since tacdef are strictly globalized *)
(f c,None)
-let subst_or_var f = function
+let subst_or_var f = let open Locus in function
| ArgVar _ as x -> x
| ArgArg x -> ArgArg (f x)
@@ -112,7 +113,7 @@ let subst_glob_constr_or_pattern subst (bvars,c,p) =
(bvars,subst_glob_constr subst c,subst_pattern subst p)
let subst_redexp subst =
- Miscops.map_red_expr_gen
+ Redops.map_red_expr_gen
(subst_glob_constr subst)
(subst_evaluable subst)
(subst_glob_constr_or_pattern subst)
diff --git a/plugins/ltac/tacsubst.mli b/plugins/ltac/tacsubst.mli
index 0a894791..d406686c 100644
--- a/plugins/ltac/tacsubst.mli
+++ b/plugins/ltac/tacsubst.mli
@@ -11,7 +11,7 @@
open Tacexpr
open Mod_subst
open Genarg
-open Misctypes
+open Tactypes
(** Substitution of tactics at module closing time *)
diff --git a/plugins/ltac/tactic_debug.ml b/plugins/ltac/tactic_debug.ml
index bb815dcb..b15a8d6a 100644
--- a/plugins/ltac/tactic_debug.ml
+++ b/plugins/ltac/tactic_debug.ml
@@ -12,7 +12,6 @@ open Util
open Names
open Pp
open Tacexpr
-open Termops
let (ltac_trace_info : ltac_trace Exninfo.t) = Exninfo.make ()
@@ -51,8 +50,8 @@ let msg_tac_notice s = Proofview.NonLogical.print_notice (s++fnl())
let db_pr_goal gl =
let env = Proofview.Goal.env gl in
let concl = Proofview.Goal.concl gl in
- let penv = print_named_context env in
- let pc = print_constr_env env (Tacmach.New.project gl) concl in
+ let penv = Termops.Internal.print_named_context env in
+ let pc = Printer.pr_econstr_env env (Tacmach.New.project gl) concl in
str" " ++ hv 0 (penv ++ fnl () ++
str "============================" ++ fnl () ++
str" " ++ pc) ++ fnl ()
@@ -243,7 +242,7 @@ let db_constr debug env sigma c =
let open Proofview.NonLogical in
is_debug debug >>= fun db ->
if db then
- msg_tac_debug (str "Evaluated term: " ++ print_constr_env env sigma c)
+ msg_tac_debug (str "Evaluated term: " ++ Printer.pr_econstr_env env sigma c)
else return ()
(* Prints the pattern rule *)
@@ -268,7 +267,7 @@ let db_matched_hyp debug env sigma (id,_,c) ido =
is_debug debug >>= fun db ->
if db then
msg_tac_debug (str "Hypothesis " ++ Id.print id ++ hyp_bound ido ++
- str " has been matched: " ++ print_constr_env env sigma c)
+ str " has been matched: " ++ Printer.pr_econstr_env env sigma c)
else return ()
(* Prints the matched conclusion *)
@@ -276,7 +275,7 @@ let db_matched_concl debug env sigma c =
let open Proofview.NonLogical in
is_debug debug >>= fun db ->
if db then
- msg_tac_debug (str "Conclusion has been matched: " ++ print_constr_env env sigma c)
+ msg_tac_debug (str "Conclusion has been matched: " ++ Printer.pr_econstr_env env sigma c)
else return ()
(* Prints a success message when the goal has been matched *)
@@ -391,13 +390,10 @@ let explain_ltac_call_trace last trace loc =
let skip_extensions trace =
let rec aux = function
- | (_,Tacexpr.LtacNameCall f as tac) :: _
- when Tacenv.is_ltac_for_ml_tactic f -> [tac]
- | (_,Tacexpr.LtacNotationCall _ as tac) :: (_,Tacexpr.LtacMLCall _) :: _ ->
+ | (_,Tacexpr.LtacNotationCall _ as tac) :: (_,Tacexpr.LtacMLCall _) :: tail ->
(* Case of an ML defined tactic with entry of the form <<"foo" args>> *)
(* see tacextend.mlp *)
- [tac]
- | (_,Tacexpr.LtacMLCall _ as tac) :: _ -> [tac]
+ tac :: aux tail
| t :: tail -> t :: aux tail
| [] -> [] in
List.rev (aux (List.rev trace))
diff --git a/plugins/ltac/tactic_debug.mli b/plugins/ltac/tactic_debug.mli
index 734e76b5..175341df 100644
--- a/plugins/ltac/tactic_debug.mli
+++ b/plugins/ltac/tactic_debug.mli
@@ -76,7 +76,7 @@ val db_logic_failure : debug_info -> exn -> unit Proofview.NonLogical.t
(** Prints a logic failure message for a rule *)
val db_breakpoint : debug_info ->
- Misctypes.lident message_token list -> unit Proofview.NonLogical.t
+ lident message_token list -> unit Proofview.NonLogical.t
val extract_ltac_trace :
?loc:Loc.t -> Tacexpr.ltac_trace -> Pp.t option Loc.located
diff --git a/plugins/ltac/tactic_matching.ml b/plugins/ltac/tactic_matching.ml
index b6462c81..c949589e 100644
--- a/plugins/ltac/tactic_matching.ml
+++ b/plugins/ltac/tactic_matching.ml
@@ -46,7 +46,7 @@ let adjust : Constr_matching.bound_ident_map * Ltac_pretype.patvar_map ->
(** Adds a binding to a {!Id.Map.t} if the identifier is [Some id] *)
let id_map_try_add id x m =
match id with
- | Some id -> Id.Map.add id x m
+ | Some id -> Id.Map.add id (Lazy.force x) m
| None -> m
(** Adds a binding to a {!Id.Map.t} if the name is [Name id] *)
diff --git a/plugins/ltac/tauto.ml b/plugins/ltac/tauto.ml
index a51c09ca..299bc7ea 100644
--- a/plugins/ltac/tauto.ml
+++ b/plugins/ltac/tauto.ml
@@ -8,12 +8,11 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Term
+open Constr
open EConstr
open Hipattern
open Names
open Geninterp
-open Misctypes
open Ltac_plugin
open Tacexpr
open Tacinterp
@@ -94,7 +93,7 @@ let clear id = Tactics.clear [id]
let assumption = Tactics.assumption
-let split = Tactics.split_with_bindings false [Misctypes.NoBindings]
+let split = Tactics.split_with_bindings false [Tactypes.NoBindings]
(** Test *)
@@ -175,7 +174,7 @@ let flatten_contravariant_disj _ ist =
| Some (_,args) ->
let map i arg =
let typ = mkArrow arg c in
- let ci = Tactics.constructor_tac false None (succ i) Misctypes.NoBindings in
+ let ci = Tactics.constructor_tac false None (succ i) Tactypes.NoBindings in
let by = tclTHENLIST [intro; apply hyp; ci; assumption] in
assert_ ~by typ
in
@@ -187,7 +186,7 @@ let flatten_contravariant_disj _ ist =
let make_unfold name =
let dir = DirPath.make (List.map Id.of_string ["Logic"; "Init"; "Coq"]) in
let const = Constant.make2 (ModPath.MPfile dir) (Label.make name) in
- (Locus.AllOccurrences, ArgArg (EvalConstRef const, None))
+ Locus.(AllOccurrences, ArgArg (EvalConstRef const, None))
let u_not = make_unfold "not"
@@ -245,7 +244,7 @@ let with_flags flags _ ist =
let x = CAst.make @@ Id.of_string "x" in
let arg = Val.Dyn (tag_tauto_flags, flags) in
let ist = { ist with lfun = Id.Map.add x.CAst.v arg ist.lfun } in
- eval_tactic_ist ist (TacArg (Loc.tag @@ TacCall (Loc.tag (ArgVar f, [Reference (ArgVar x)]))))
+ eval_tactic_ist ist (TacArg (Loc.tag @@ TacCall (Loc.tag (Locus.ArgVar f, [Reference (Locus.ArgVar x)]))))
let register_tauto_tactic tac name0 args =
let ids = List.map (fun id -> Id.of_string id) args in
diff --git a/plugins/micromega/Fourier.v b/plugins/micromega/Fourier.v
new file mode 100644
index 00000000..0153de1d
--- /dev/null
+++ b/plugins/micromega/Fourier.v
@@ -0,0 +1,5 @@
+Require Import Lra.
+Require Export Fourier_util.
+
+#[deprecated(since = "8.9.0", note = "Use lra instead.")]
+Ltac fourier := lra.
diff --git a/plugins/micromega/Fourier_util.v b/plugins/micromega/Fourier_util.v
new file mode 100644
index 00000000..b62153de
--- /dev/null
+++ b/plugins/micromega/Fourier_util.v
@@ -0,0 +1,31 @@
+Require Export Rbase.
+Require Import Lra.
+
+Open Scope R_scope.
+
+Lemma Rlt_mult_inv_pos : forall x y:R, 0 < x -> 0 < y -> 0 < x * / y.
+intros x y H H0; try assumption.
+replace 0 with (x * 0).
+apply Rmult_lt_compat_l; auto with real.
+ring.
+Qed.
+
+Lemma Rlt_zero_pos_plus1 : forall x:R, 0 < x -> 0 < 1 + x.
+intros x H; try assumption.
+rewrite Rplus_comm.
+apply Rle_lt_0_plus_1.
+red; auto with real.
+Qed.
+
+Lemma Rle_zero_pos_plus1 : forall x:R, 0 <= x -> 0 <= 1 + x.
+ intros; lra.
+Qed.
+
+Lemma Rle_mult_inv_pos : forall x y:R, 0 <= x -> 0 < y -> 0 <= x * / y.
+intros x y H H0; try assumption.
+case H; intros.
+red; left.
+apply Rlt_mult_inv_pos; auto with real.
+rewrite <- H1.
+red; right; ring.
+Qed.
diff --git a/plugins/micromega/Tauto.v b/plugins/micromega/Tauto.v
index 31f55ae9..458844e1 100644
--- a/plugins/micromega/Tauto.v
+++ b/plugins/micromega/Tauto.v
@@ -211,7 +211,7 @@ Set Implicit Arguments.
(* BC *)
simpl.
case_eq (deduce t t) ; auto.
- intros until 0.
+ intros *.
case_eq (unsat t0) ; auto.
unfold eval_clause.
rewrite make_conj_cons.
@@ -263,7 +263,7 @@ Set Implicit Arguments.
Proof.
induction cl.
simpl. tauto.
- intros until 0.
+ intros *.
simpl.
assert (HH := add_term_correct env a cl').
case_eq (add_term a cl').
diff --git a/plugins/micromega/certificate.ml b/plugins/micromega/certificate.ml
index 9f39191f..3a9709b6 100644
--- a/plugins/micromega/certificate.ml
+++ b/plugins/micromega/certificate.ml
@@ -17,10 +17,9 @@
(* We take as input a list of polynomials [p1...pn] and return an unfeasibility
certificate polynomial. *)
-type var = int
-
-
+let debug = false
+open Util
open Big_int
open Num
open Polynomial
@@ -59,9 +58,6 @@ let q_spec = {
eqb = Mc.qeq_bool
}
-let r_spec = z_spec
-
-
let dev_form n_spec p =
let rec dev_form p =
match p with
@@ -84,38 +80,6 @@ let dev_form n_spec p =
pow n in
dev_form p
-
-let monomial_to_polynomial mn =
- Monomial.fold
- (fun v i acc ->
- let v = Ml2C.positive v in
- let mn = if Int.equal i 1 then Mc.PEX v else Mc.PEpow (Mc.PEX v ,Ml2C.n i) in
- if Pervasives.(=) acc (Mc.PEc (Mc.Zpos Mc.XH)) (** FIXME *)
- then mn
- else Mc.PEmul(mn,acc))
- mn
- (Mc.PEc (Mc.Zpos Mc.XH))
-
-
-
-let list_to_polynomial vars l =
- assert (List.for_all (fun x -> ceiling_num x =/ x) l);
- let var x = monomial_to_polynomial (List.nth vars x) in
-
- let rec xtopoly p i = function
- | [] -> p
- | c::l -> if c =/ (Int 0) then xtopoly p (i+1) l
- else let c = Mc.PEc (Ml2C.bigint (numerator c)) in
- let mn =
- if Pervasives.(=) c (Mc.PEc (Mc.Zpos Mc.XH))
- then var i
- else Mc.PEmul (c,var i) in
- let p' = if Pervasives.(=) p (Mc.PEc Mc.Z0) then mn else
- Mc.PEadd (mn, p) in
- xtopoly p' (i+1) l in
-
- xtopoly (Mc.PEc Mc.Z0) 0 l
-
let rec fixpoint f x =
let y' = f x in
if Pervasives.(=) y' x then y'
@@ -135,15 +99,6 @@ let rec_simpl_cone n_spec e =
let simplify_cone n_spec c = fixpoint (rec_simpl_cone n_spec) c
-
-type cone_prod =
- Const of cone
-| Ideal of cone *cone
-| Mult of cone * cone
-| Other of cone
-and cone = Mc.zWitness
-
-
let factorise_linear_cone c =
@@ -224,14 +179,6 @@ let positivity l =
in
xpositivity 0 l
-
-let string_of_op = function
- | Mc.Strict -> "> 0"
- | Mc.NonStrict -> ">= 0"
- | Mc.Equal -> "= 0"
- | Mc.NonEqual -> "<> 0"
-
-
module MonSet = Set.Make(Monomial)
(* If the certificate includes at least one strict inequality,
@@ -261,9 +208,6 @@ let build_linear_system l =
op = Ge ;
cst = Big_int zero_big_int}::(strict::(positivity l)@s0)
-
-let big_int_to_z = Ml2C.bigint
-
(* For Q, this is a pity that the certificate has been scaled
-- at a lower layer, certificates are using nums... *)
let make_certificate n_spec (cert,li) =
@@ -296,8 +240,6 @@ let make_certificate n_spec (cert,li) =
(simplify_cone n_spec (scalar_product cert' li)))
-exception Found of Monomial.t
-
exception Strict
module MonMap = Map.Make(Monomial)
@@ -367,7 +309,7 @@ let simple_linear_prover l =
let linear_prover n_spec l =
let build_system n_spec l =
- let li = List.combine l (interval 0 (List.length l -1)) in
+ let li = List.combine l (CList.interval 0 (List.length l -1)) in
let (l1,l') = List.partition
(fun (x,_) -> if Pervasives.(=) (snd x) Mc.NonEqual then true else false) li in
List.map
@@ -397,7 +339,7 @@ let nlinear_prover prfdepth (sys: (Mc.q Mc.pExpr * Mc.op1) list) =
LinPoly.MonT.clear ();
max_nb_cstr := compute_max_nb_cstr sys prfdepth ;
(* Assign a proof to the initial hypotheses *)
- let sys = mapi (fun c i -> (c,Mc.PsatzIn (Ml2C.nat i))) sys in
+ let sys = List.mapi (fun i c -> (c,Mc.PsatzIn (Ml2C.nat i))) sys in
(* Add all the product of hypotheses *)
@@ -452,39 +394,6 @@ let nlinear_prover prfdepth (sys: (Mc.q Mc.pExpr * Mc.op1) list) =
| Mc.PsatzZ -> Mc.PsatzZ in
Some (map_psatz cert)
-
-
-let make_linear_system l =
- let l' = List.map fst l in
- let monomials = List.fold_left (fun acc p -> Poly.addition p acc)
- (Poly.constant (Int 0)) l' in
- let monomials = Poly.fold
- (fun mn _ l -> if Pervasives.(=) mn Monomial.const then l else mn::l) monomials [] in
- (List.map (fun (c,op) ->
- {coeffs = Vect.from_list (List.map (fun mn -> (Poly.get mn c)) monomials) ;
- op = op ;
- cst = minus_num ( (Poly.get Monomial.const c))}) l
- ,monomials)
-
-
-let pplus x y = Mc.PEadd(x,y)
-let pmult x y = Mc.PEmul(x,y)
-let pconst x = Mc.PEc x
-let popp x = Mc.PEopp x
-
-(* keep track of enumerated vectors *)
-let rec mem p x l =
- match l with [] -> false | e::l -> if p x e then true else mem p x l
-
-let rec remove_assoc p x l =
- match l with [] -> [] | e::l -> if p x (fst e) then
- remove_assoc p x l else e::(remove_assoc p x l)
-
-let eq x y = Int.equal (Vect.compare x y) 0
-
-let remove e l = List.fold_left (fun l x -> if eq x e then l else x::l) [] l
-
-
(* The prover is (probably) incomplete --
only searching for naive cutting planes *)
@@ -494,38 +403,6 @@ let develop_constraint z_spec (e,k) =
| Mc.Equal -> (dev_form z_spec e , Eq)
| _ -> assert false
-
-let op_of_op_compat = function
- | Ge -> Mc.NonStrict
- | Eq -> Mc.Equal
-
-
-let integer_vector coeffs =
- let vars , coeffs = List.split coeffs in
- List.combine vars (List.map (fun x -> Big_int x) (rats_to_ints coeffs))
-
-let integer_cstr {coeffs = coeffs ; op = op ; cst = cst } =
- let vars , coeffs = List.split coeffs in
- match rats_to_ints (cst::coeffs) with
- | cst :: coeffs ->
- {
- coeffs = List.combine vars (List.map (fun x -> Big_int x) coeffs) ;
- op = op ; cst = Big_int cst}
- | _ -> assert false
-
-
-let pexpr_of_cstr_compat var cstr =
- let {coeffs = coeffs ; op = op ; cst = cst } = integer_cstr cstr in
- try
- let expr = list_to_polynomial var (Vect.to_list coeffs) in
- let d = Ml2C.bigint (denominator cst) in
- let n = Ml2C.bigint (numerator cst) in
- (pplus (pmult (pconst d) expr) (popp (pconst n)), op_of_op_compat op)
- with Failure _ -> failwith "pexpr_of_cstr_compat"
-
-
-
-
open Sos_types
let rec scale_term t =
@@ -555,18 +432,6 @@ let scale_term t =
let (s,t') = scale_term t in
s,t'
-
-let get_index_of_ith_match f i l =
- let rec get j res l =
- match l with
- | [] -> failwith "bad index"
- | e::l -> if f e
- then
- (if Int.equal j i then res else get (j+1) (res+1) l )
- else get j (res+1) l in
- get 0 0 l
-
-
let rec scale_certificate pos = match pos with
| Axiom_eq i -> unit_big_int , Axiom_eq i
| Axiom_le i -> unit_big_int , Axiom_le i
@@ -681,8 +546,6 @@ open Polynomial
module Env =
struct
- type t = int list
-
let id_of_hyp hyp l =
let rec xid_of_hyp i l =
match l with
@@ -749,9 +612,6 @@ let xlinear_prover sys =
| Inl _ -> None
-let output_num o n = output_string o (string_of_num n)
-let output_bigint o n = output_string o (string_of_big_int n)
-
let proof_of_farkas prf cert =
(* Printf.printf "\nproof_of_farkas %a , %a \n" (pp_list output_prf_rule) prf (pp_list output_bigint) cert ; *)
let rec mk_farkas acc prf cert =
@@ -894,23 +754,6 @@ let rec ext_gcd a b =
let (s,t) = ext_gcd b r in
(t, sub_big_int s (mult_big_int q t))
-
-let pp_ext_gcd a b =
- let a' = big_int_of_int a in
- let b' = big_int_of_int b in
-
- let (x,y) = ext_gcd a' b' in
- Printf.fprintf stdout "%s * %s + %s * %s = %s\n"
- (string_of_big_int x) (string_of_big_int a')
- (string_of_big_int y) (string_of_big_int b')
- (string_of_big_int (add_big_int (mult_big_int x a') (mult_big_int y b')))
-
-exception Result of (int * (proof * cstr_compat))
-
-let split_equations psys =
- List.partition (fun (c,p) -> c.op == Eq)
-
-
let extract_coprime (c1,p1) (c2,p2) =
let rec exist2 vect1 vect2 =
match vect1 , vect2 with
@@ -1058,29 +901,6 @@ let reduce_var_change psys =
Some (apply_and_normalise pivot_eq sys)
-
-
-
-let reduce_pivot psys =
- let is_equation (cstr,prf) =
- if cstr.op == Eq
- then
- try
- Some (fst (List.hd cstr.coeffs))
- with Not_found -> None
- else None in
- let (oeq,sys) = extract is_equation psys in
- match oeq with
- | None -> None (* Nothing to do *)
- | Some(v,pc) ->
- if debug then
- Printf.printf "Bad news : loss of completeness %a=%s" Vect.pp_vect (fst pc).coeffs (string_of_num (fst pc).cst);
- Some(pivot_sys v pc sys)
-
-
-
-
-
let iterate_until_stable f x =
let rec iter x =
match f x with
@@ -1225,7 +1045,7 @@ let xlia (can_enum:bool) reduction_equations sys =
| None -> None
| Some prf ->
(*Printf.printf "direct proof %a\n" output_proof prf ; *)
- let env = mapi (fun _ i -> i) sys in
+ let env = List.mapi (fun i _ -> i) sys in
let prf = compile_proof env prf in
(*try
if Mc.zChecker sys' prf then Some prf else
@@ -1244,7 +1064,7 @@ let lia (can_enum:bool) (prfdepth:int) sys =
max_nb_cstr := compute_max_nb_cstr sys prfdepth ;
let sys = List.map (develop_constraint z_spec) sys in
let (sys:cstr_compat list) = List.map cstr_compat_of_poly sys in
- let sys = mapi (fun c i -> (c,Hyp i)) sys in
+ let sys = List.mapi (fun i c -> (c,Hyp i)) sys in
xlia can_enum reduction_equations sys
@@ -1252,7 +1072,7 @@ let nlia enum prfdepth sys =
LinPoly.MonT.clear ();
max_nb_cstr := compute_max_nb_cstr sys prfdepth;
let sys = List.map (develop_constraint z_spec) sys in
- let sys = mapi (fun c i -> (c,Hyp i)) sys in
+ let sys = List.mapi (fun i c -> (c,Hyp i)) sys in
let is_linear = List.for_all (fun ((p,_),_) -> Poly.is_linear p) sys in
diff --git a/plugins/micromega/certificate.mli b/plugins/micromega/certificate.mli
new file mode 100644
index 00000000..13d50d1e
--- /dev/null
+++ b/plugins/micromega/certificate.mli
@@ -0,0 +1,22 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module Mc = Micromega
+
+type 'a number_spec
+
+val q_cert_of_pos : Sos_types.positivstellensatz -> Mc.q Mc.psatz
+val z_cert_of_pos : Sos_types.positivstellensatz -> Mc.z Mc.psatz
+val lia : bool -> int -> (Mc.z Mc.pExpr * Mc.op1) list -> Mc.zArithProof option
+val nlia : bool -> int -> (Mc.z Mc.pExpr * Mc.op1) list -> Mc.zArithProof option
+val nlinear_prover : int -> (Mc.q Mc.pExpr * Mc.op1) list -> Mc.q Mc.psatz option
+val linear_prover_with_cert : int -> 'a number_spec ->
+ ('a Mc.pExpr * Mc.op1) list -> 'a Mc.psatz option
+val q_spec : Mc.q number_spec
diff --git a/plugins/micromega/coq_micromega.ml b/plugins/micromega/coq_micromega.ml
index 168105e8..f22147f8 100644
--- a/plugins/micromega/coq_micromega.ml
+++ b/plugins/micromega/coq_micromega.ml
@@ -19,10 +19,11 @@
(************************************************************************)
open Pp
-open Mutils
-open Goptions
open Names
+open Goptions
+open Mutils
open Constr
+open Tactypes
(**
* Debug flag
@@ -30,19 +31,6 @@ open Constr
let debug = false
-(**
- * Time function
- *)
-
-let time str f x =
- let t0 = (Unix.times()).Unix.tms_utime in
- let res = f x in
- let t1 = (Unix.times()).Unix.tms_utime in
- (*if debug then*) (Printf.printf "time %s %f\n" str (t1 -. t0) ;
- flush stdout);
- res
-
-
(* Limit the proof search *)
let max_depth = max_int
@@ -305,8 +293,7 @@ let rec add_term t0 = function
*)
module ISet = Set.Make(Int)
-module IMap = Map.Make(Int)
-
+
(**
* Given a set of integers s=\{i0,...,iN\} and a list m, return the list of
* elements of m that are at position i0,...,iN.
@@ -373,7 +360,7 @@ struct
* ZMicromega.v
*)
- let gen_constant_in_modules s m n = EConstr.of_constr (Universes.constr_of_global @@ Coqlib.gen_reference_in_modules s m n)
+ let gen_constant_in_modules s m n = EConstr.of_constr (UnivGen.constr_of_global @@ Coqlib.gen_reference_in_modules s m n)
let init_constant = gen_constant_in_modules "ZMicromega" Coqlib.init_modules
let constant = gen_constant_in_modules "ZMicromega" coq_modules
let bin_constant = gen_constant_in_modules "ZMicromega" bin_module
@@ -395,16 +382,10 @@ struct
let coq_O = lazy (init_constant "O")
let coq_S = lazy (init_constant "S")
- let coq_nat = lazy (init_constant "nat")
let coq_N0 = lazy (bin_constant "N0")
let coq_Npos = lazy (bin_constant "Npos")
- let coq_pair = lazy (init_constant "pair")
- let coq_None = lazy (init_constant "None")
- let coq_option = lazy (init_constant "option")
-
- let coq_positive = lazy (bin_constant "positive")
let coq_xH = lazy (bin_constant "xH")
let coq_xO = lazy (bin_constant "xO")
let coq_xI = lazy (bin_constant "xI")
@@ -417,8 +398,6 @@ struct
let coq_Q = lazy (constant "Q")
let coq_R = lazy (constant "R")
- let coq_Build_Witness = lazy (constant "Build_Witness")
-
let coq_Qmake = lazy (constant "Qmake")
let coq_Rcst = lazy (constant "Rcst")
@@ -455,8 +434,6 @@ struct
let coq_Zmult = lazy (z_constant "Z.mul")
let coq_Zpower = lazy (z_constant "Z.pow")
- let coq_Qgt = lazy (constant "Qgt")
- let coq_Qge = lazy (constant "Qge")
let coq_Qle = lazy (constant "Qle")
let coq_Qlt = lazy (constant "Qlt")
let coq_Qeq = lazy (constant "Qeq")
@@ -476,7 +453,6 @@ struct
let coq_Rminus = lazy (r_constant "Rminus")
let coq_Ropp = lazy (r_constant "Ropp")
let coq_Rmult = lazy (r_constant "Rmult")
- let coq_Rdiv = lazy (r_constant "Rdiv")
let coq_Rinv = lazy (r_constant "Rinv")
let coq_Rpower = lazy (r_constant "pow")
let coq_IZR = lazy (r_constant "IZR")
@@ -509,12 +485,6 @@ struct
let coq_PsatzAdd = lazy (constant "PsatzAdd")
let coq_PsatzC = lazy (constant "PsatzC")
let coq_PsatzZ = lazy (constant "PsatzZ")
- let coq_coneMember = lazy (constant "coneMember")
-
- let coq_make_impl = lazy
- (gen_constant_in_modules "Zmicromega" [["Refl"]] "make_impl")
- let coq_make_conj = lazy
- (gen_constant_in_modules "Zmicromega" [["Refl"]] "make_conj")
let coq_TT = lazy
(gen_constant_in_modules "ZMicromega"
@@ -552,13 +522,6 @@ struct
let coq_QWitness = lazy
(gen_constant_in_modules "QMicromega"
[["Coq"; "micromega"; "QMicromega"]] "QWitness")
- let coq_ZWitness = lazy
- (gen_constant_in_modules "QMicromega"
- [["Coq"; "micromega"; "ZMicromega"]] "ZWitness")
-
- let coq_N_of_Z = lazy
- (gen_constant_in_modules "ZArithRing"
- [["Coq";"setoid_ring";"ZArithRing"]] "N_of_Z")
let coq_Build = lazy
(gen_constant_in_modules "RingMicromega"
@@ -577,34 +540,16 @@ struct
* pp_* functions pretty-print Coq terms.
*)
- (* Error datastructures *)
-
- type parse_error =
- | Ukn
- | BadStr of string
- | BadNum of int
- | BadTerm of constr
- | Msg of string
- | Goal of (constr list ) * constr * parse_error
-
- let string_of_error = function
- | Ukn -> "ukn"
- | BadStr s -> s
- | BadNum i -> string_of_int i
- | BadTerm _ -> "BadTerm"
- | Msg s -> s
- | Goal _ -> "Goal"
-
exception ParseError
(* A simple but useful getter function *)
let get_left_construct sigma term =
match EConstr.kind sigma term with
- | Term.Construct((_,i),_) -> (i,[| |])
- | Term.App(l,rst) ->
+ | Construct((_,i),_) -> (i,[| |])
+ | App(l,rst) ->
(match EConstr.kind sigma l with
- | Term.Construct((_,i),_) -> (i,rst)
+ | Construct((_,i),_) -> (i,rst)
| _ -> raise ParseError
)
| _ -> raise ParseError
@@ -648,19 +593,6 @@ struct
| Mc.N0 -> Lazy.force coq_N0
| Mc.Npos p -> EConstr.mkApp(Lazy.force coq_Npos,[| dump_positive p|])
- let rec dump_index x =
- match x with
- | Mc.XH -> Lazy.force coq_xH
- | Mc.XO p -> EConstr.mkApp(Lazy.force coq_xO,[| dump_index p |])
- | Mc.XI p -> EConstr.mkApp(Lazy.force coq_xI,[| dump_index p |])
-
- let pp_index o x = Printf.fprintf o "%i" (CoqToCaml.index x)
-
- let pp_n o x = output_string o (string_of_int (CoqToCaml.n x))
-
- let dump_pair t1 t2 dump_t1 dump_t2 (x,y) =
- EConstr.mkApp(Lazy.force coq_pair,[| t1 ; t2 ; dump_t1 x ; dump_t2 y|])
-
let parse_z sigma term =
let (i,c) = get_left_construct sigma term in
match i with
@@ -677,18 +609,13 @@ struct
let pp_z o x = Printf.fprintf o "%s" (Big_int.string_of_big_int (CoqToCaml.z_big_int x))
- let dump_num bd1 =
- EConstr.mkApp(Lazy.force coq_Qmake,
- [|dump_z (CamlToCoq.bigint (numerator bd1)) ;
- dump_positive (CamlToCoq.positive_big_int (denominator bd1)) |])
-
let dump_q q =
EConstr.mkApp(Lazy.force coq_Qmake,
[| dump_z q.Micromega.qnum ; dump_positive q.Micromega.qden|])
let parse_q sigma term =
match EConstr.kind sigma term with
- | Term.App(c, args) -> if EConstr.eq_constr sigma c (Lazy.force coq_Qmake) then
+ | App(c, args) -> if EConstr.eq_constr sigma c (Lazy.force coq_Qmake) then
{Mc.qnum = parse_z sigma args.(0) ; Mc.qden = parse_positive sigma args.(1) }
else raise ParseError
| _ -> raise ParseError
@@ -719,29 +646,6 @@ struct
| Mc.CInv t -> EConstr.mkApp(Lazy.force coq_CInv, [| dump_Rcst t |])
| Mc.COpp t -> EConstr.mkApp(Lazy.force coq_COpp, [| dump_Rcst t |])
- let rec parse_Rcst sigma term =
- let (i,c) = get_left_construct sigma term in
- match i with
- | 1 -> Mc.C0
- | 2 -> Mc.C1
- | 3 -> Mc.CQ (parse_q sigma c.(0))
- | 4 -> Mc.CPlus(parse_Rcst sigma c.(0), parse_Rcst sigma c.(1))
- | 5 -> Mc.CMinus(parse_Rcst sigma c.(0), parse_Rcst sigma c.(1))
- | 6 -> Mc.CMult(parse_Rcst sigma c.(0), parse_Rcst sigma c.(1))
- | 7 -> Mc.CInv(parse_Rcst sigma c.(0))
- | 8 -> Mc.COpp(parse_Rcst sigma c.(0))
- | _ -> raise ParseError
-
-
-
-
- let rec parse_list sigma parse_elt term =
- let (i,c) = get_left_construct sigma term in
- match i with
- | 1 -> []
- | 2 -> parse_elt sigma c.(1) :: parse_list sigma parse_elt c.(2)
- | i -> raise ParseError
-
let rec dump_list typ dump_elt l =
match l with
| [] -> EConstr.mkApp(Lazy.force coq_nil,[| typ |])
@@ -756,22 +660,8 @@ struct
| e::l -> Printf.fprintf o "%a ,%a" elt e _pp l in
Printf.fprintf o "%s%a%s" op _pp l cl
- let pp_var = pp_positive
-
let dump_var = dump_positive
- let pp_expr pp_z o e =
- let rec pp_expr o e =
- match e with
- | Mc.PEX n -> Printf.fprintf o "V %a" pp_var n
- | Mc.PEc z -> pp_z o z
- | Mc.PEadd(e1,e2) -> Printf.fprintf o "(%a)+(%a)" pp_expr e1 pp_expr e2
- | Mc.PEmul(e1,e2) -> Printf.fprintf o "%a*(%a)" pp_expr e1 pp_expr e2
- | Mc.PEopp e -> Printf.fprintf o "-(%a)" pp_expr e
- | Mc.PEsub(e1,e2) -> Printf.fprintf o "(%a)-(%a)" pp_expr e1 pp_expr e2
- | Mc.PEpow(e,n) -> Printf.fprintf o "(%a)^(%a)" pp_expr e pp_n n in
- pp_expr o e
-
let dump_expr typ dump_z e =
let rec dump_expr e =
match e with
@@ -854,18 +744,6 @@ struct
| Mc.OpGt-> Lazy.force coq_OpGt
| Mc.OpLt-> Lazy.force coq_OpLt
- let pp_op o e=
- match e with
- | Mc.OpEq-> Printf.fprintf o "="
- | Mc.OpNEq-> Printf.fprintf o "<>"
- | Mc.OpLe -> Printf.fprintf o "=<"
- | Mc.OpGe -> Printf.fprintf o ">="
- | Mc.OpGt-> Printf.fprintf o ">"
- | Mc.OpLt-> Printf.fprintf o "<"
-
- let pp_cstr pp_z o {Mc.flhs = l ; Mc.fop = op ; Mc.frhs = r } =
- Printf.fprintf o"(%a %a %a)" (pp_expr pp_z) l pp_op op (pp_expr pp_z) r
-
let dump_cstr typ dump_constant {Mc.flhs = e1 ; Mc.fop = o ; Mc.frhs = e2} =
EConstr.mkApp(Lazy.force coq_Build,
[| typ; dump_expr typ dump_constant e1 ;
@@ -904,8 +782,8 @@ struct
let parse_zop gl (op,args) =
let sigma = gl.sigma in
match EConstr.kind sigma op with
- | Term.Const (x,_) -> (assoc_const sigma op zop_table, args.(0) , args.(1))
- | Term.Ind((n,0),_) ->
+ | Const (x,_) -> (assoc_const sigma op zop_table, args.(0) , args.(1))
+ | Ind((n,0),_) ->
if EConstr.eq_constr sigma op (Lazy.force coq_Eq) && is_convertible gl args.(0) (Lazy.force coq_Z)
then (Mc.OpEq, args.(1), args.(2))
else raise ParseError
@@ -914,8 +792,8 @@ struct
let parse_rop gl (op,args) =
let sigma = gl.sigma in
match EConstr.kind sigma op with
- | Term.Const (x,_) -> (assoc_const sigma op rop_table, args.(0) , args.(1))
- | Term.Ind((n,0),_) ->
+ | Const (x,_) -> (assoc_const sigma op rop_table, args.(0) , args.(1))
+ | Ind((n,0),_) ->
if EConstr.eq_constr sigma op (Lazy.force coq_Eq) && is_convertible gl args.(0) (Lazy.force coq_R)
then (Mc.OpEq, args.(1), args.(2))
else raise ParseError
@@ -924,11 +802,6 @@ struct
let parse_qop gl (op,args) =
(assoc_const gl.sigma op qop_table, args.(0) , args.(1))
- let is_constant sigma t = (* This is an approx *)
- match EConstr.kind sigma t with
- | Term.Construct(i,_) -> true
- | _ -> false
-
type 'a op =
| Binop of ('a Mc.pExpr -> 'a Mc.pExpr -> 'a Mc.pExpr)
| Opp
@@ -947,8 +820,6 @@ struct
module Env =
struct
- type t = EConstr.constr list
-
let compute_rank_add env sigma v =
let rec _add env n v =
match env with
@@ -1011,10 +882,10 @@ struct
try (Mc.PEc (parse_constant term) , env)
with ParseError ->
match EConstr.kind sigma term with
- | Term.App(t,args) ->
+ | App(t,args) ->
(
match EConstr.kind sigma t with
- | Term.Const c ->
+ | Const c ->
( match assoc_ops sigma t ops_spec with
| Binop f -> combine env f (args.(0),args.(1))
| Opp -> let (expr,env) = parse_expr env args.(0) in
@@ -1077,13 +948,13 @@ struct
let rec rconstant sigma term =
match EConstr.kind sigma term with
- | Term.Const x ->
+ | Const x ->
if EConstr.eq_constr sigma term (Lazy.force coq_R0)
then Mc.C0
else if EConstr.eq_constr sigma term (Lazy.force coq_R1)
then Mc.C1
else raise ParseError
- | Term.App(op,args) ->
+ | App(op,args) ->
begin
try
(* the evaluation order is important in the following *)
@@ -1153,7 +1024,7 @@ struct
if debug
then Feedback.msg_debug (Pp.str "parse_arith: " ++ Printer.pr_leconstr_env gl.env sigma cstr ++ fnl ());
match EConstr.kind sigma cstr with
- | Term.App(op,args) ->
+ | App(op,args) ->
let (op,lhs,rhs) = parse_op gl (op,args) in
let (e1,env) = parse_expr sigma env lhs in
let (e2,env) = parse_expr sigma env rhs in
@@ -1168,17 +1039,6 @@ struct
(* generic parsing of arithmetic expressions *)
- let rec f2f = function
- | TT -> Mc.TT
- | FF -> Mc.FF
- | X _ -> Mc.X
- | A (x,_,_) -> Mc.A x
- | C (a,b) -> Mc.Cj(f2f a,f2f b)
- | D (a,b) -> Mc.D(f2f a,f2f b)
- | N (a) -> Mc.N(f2f a)
- | I(a,_,b) -> Mc.I(f2f a,f2f b)
-
-
let mkC f1 f2 = C(f1,f2)
let mkD f1 f2 = D(f1,f2)
let mkIff f1 f2 = C(I(f1,None,f2),I(f2,None,f1))
@@ -1208,7 +1068,7 @@ struct
let rec xparse_formula env tg term =
match EConstr.kind sigma term with
- | Term.App(l,rst) ->
+ | App(l,rst) ->
(match rst with
| [|a;b|] when EConstr.eq_constr sigma l (Lazy.force coq_and) ->
let f,env,tg = xparse_formula env tg a in
@@ -1225,7 +1085,7 @@ struct
let g,env,tg = xparse_formula env tg b in
mkformula_binary mkIff term f g,env,tg
| _ -> parse_atom env tg term)
- | Term.Prod(typ,a,b) when EConstr.Vars.noccurn sigma 1 b ->
+ | Prod(typ,a,b) when EConstr.Vars.noccurn sigma 1 b ->
let f,env,tg = xparse_formula env tg a in
let g,env,tg = xparse_formula env tg b in
mkformula_binary mkI term f g,env,tg
@@ -1323,31 +1183,6 @@ let dump_qexpr = lazy
dump_op = List.map (fun (x,y) -> (y,Lazy.force x)) qop_table
}
- let dump_positive_as_R p =
- let mult = Lazy.force coq_Rmult in
- let add = Lazy.force coq_Rplus in
-
- let one = Lazy.force coq_R1 in
- let mk_add x y = EConstr.mkApp(add,[|x;y|]) in
- let mk_mult x y = EConstr.mkApp(mult,[|x;y|]) in
-
- let two = mk_add one one in
-
- let rec dump_positive p =
- match p with
- | Mc.XH -> one
- | Mc.XO p -> mk_mult two (dump_positive p)
- | Mc.XI p -> mk_add one (mk_mult two (dump_positive p)) in
-
- dump_positive p
-
-let dump_n_as_R n =
- let z = CoqToCaml.n n in
- if z = 0
- then Lazy.force coq_R0
- else dump_positive_as_R (CamlToCoq.positive z)
-
-
let rec dump_Rcst_as_R cst =
match cst with
| Mc.C0 -> Lazy.force coq_R0
@@ -1481,54 +1316,6 @@ end (**
open M
-let rec sig_of_cone = function
- | Mc.PsatzIn n -> [CoqToCaml.nat n]
- | Mc.PsatzMulE(w1,w2) -> (sig_of_cone w1)@(sig_of_cone w2)
- | Mc.PsatzMulC(w1,w2) -> (sig_of_cone w2)
- | Mc.PsatzAdd(w1,w2) -> (sig_of_cone w1)@(sig_of_cone w2)
- | _ -> []
-
-let same_proof sg cl1 cl2 =
- let rec xsame_proof sg =
- match sg with
- | [] -> true
- | n::sg ->
- (try Int.equal (List.nth cl1 n) (List.nth cl2 n) with Invalid_argument _ -> false)
- && (xsame_proof sg ) in
- xsame_proof sg
-
-let tags_of_clause tgs wit clause =
- let rec xtags tgs = function
- | Mc.PsatzIn n -> Names.Id.Set.union tgs
- (snd (List.nth clause (CoqToCaml.nat n) ))
- | Mc.PsatzMulC(e,w) -> xtags tgs w
- | Mc.PsatzMulE (w1,w2) | Mc.PsatzAdd(w1,w2) -> xtags (xtags tgs w1) w2
- | _ -> tgs in
- xtags tgs wit
-
-(*let tags_of_cnf wits cnf =
- List.fold_left2 (fun acc w cl -> tags_of_clause acc w cl)
- Names.Id.Set.empty wits cnf *)
-
-let find_witness prover polys1 = try_any prover polys1
-
-let rec witness prover l1 l2 =
- match l2 with
- | [] -> Some []
- | e :: l2 ->
- match find_witness prover (e::l1) with
- | None -> None
- | Some w ->
- (match witness prover l1 l2 with
- | None -> None
- | Some l -> Some (w::l)
- )
-
-let rec apply_ids t ids =
- match ids with
- | [] -> t
- | i::ids -> apply_ids (mkApp(t,[| mkVar i |])) ids
-
let coq_Node =
lazy (gen_constant_in_modules "VarMap"
[["Coq" ; "micromega" ; "VarMap"];["VarMap"]] "Node")
@@ -1559,15 +1346,6 @@ let vm_of_list env =
List.fold_left (fun vm (c,i) ->
Mc.vm_add d (CamlToCoq.positive i) c vm) Mc.Empty env
-
-let rec pp_varmap o vm =
- match vm with
- | Mc.Empty -> output_string o "[]"
- | Mc.Leaf z -> Printf.fprintf o "[%a]" pp_z z
- | Mc.Node(l,z,r) -> Printf.fprintf o "[%a, %a, %a]" pp_varmap l pp_z z pp_varmap r
-
-
-
let rec dump_proof_term = function
| Micromega.DoneProof -> Lazy.force coq_doneProof
| Micromega.RatProof(cone,rst) ->
@@ -1662,45 +1440,11 @@ let qq_domain_spec = lazy {
dump_proof = dump_psatz coq_Q dump_q
}
-let rcst_domain_spec = lazy {
- typ = Lazy.force coq_R;
- coeff = Lazy.force coq_Rcst;
- dump_coeff = dump_Rcst;
- proof_typ = Lazy.force coq_QWitness ;
- dump_proof = dump_psatz coq_Q dump_q
-}
-
(** Naive topological sort of constr according to the subterm-ordering *)
(* An element is minimal x is minimal w.r.t y if
x <= y or (x and y are incomparable) *)
-let is_min le x y =
- if le x y then true
- else if le y x then false else true
-
-let is_minimal le l c = List.for_all (is_min le c) l
-
-let find_rem p l =
- let rec xfind_rem acc l =
- match l with
- | [] -> (None, acc)
- | x :: l -> if p x then (Some x, acc @ l)
- else xfind_rem (x::acc) l in
- xfind_rem [] l
-
-let find_minimal le l = find_rem (is_minimal le l) l
-
-let rec mk_topo_order le l =
- match find_minimal le l with
- | (None , _) -> []
- | (Some v,l') -> v :: (mk_topo_order le l')
-
-
-let topo_sort_constr l =
- mk_topo_order (fun c t -> Termops.dependent Evd.empty (** FIXME *) (EConstr.of_constr c) (EConstr.of_constr t)) l
-
-
(**
* Instanciate the current Coq goal with a Micromega formula, a varmap, and a
* witness.
@@ -1778,13 +1522,6 @@ let witness_list prover l =
let witness_list_tags = witness_list
-(* *Deprecated* let is_singleton = function [] -> true | [e] -> true | _ -> false *)
-
-let pp_ml_list pp_elt o l =
- output_string o "[" ;
- List.iter (fun x -> Printf.fprintf o "%a ;" pp_elt x) l ;
- output_string o "]"
-
(**
* Prune the proof object, according to the 'diff' between two cnf formulas.
*)
@@ -1792,7 +1529,7 @@ let pp_ml_list pp_elt o l =
let compact_proofs (cnf_ff: 'cst cnf) res (cnf_ff': 'cst cnf) =
let compact_proof (old_cl:'cst clause) (prf,prover) (new_cl:'cst clause) =
- let new_cl = Mutils.mapi (fun (f,_) i -> (f,i)) new_cl in
+ let new_cl = List.mapi (fun i (f,_) -> (f,i)) new_cl in
let remap i =
let formula = try fst (List.nth old_cl i) with Failure _ -> failwith "bad old index" in
List.assoc formula new_cl in
@@ -1991,7 +1728,7 @@ let micromega_gen
let intro_vars = Tacticals.New.tclTHENLIST (List.map intro vars) in
let intro_props = Tacticals.New.tclTHENLIST (List.map intro props) in
- let ipat_of_name id = Some (CAst.make @@ Misctypes.IntroNaming (Misctypes.IntroIdentifier id)) in
+ let ipat_of_name id = Some (CAst.make @@ IntroNaming (Namegen.IntroIdentifier id)) in
let goal_name = fresh_id Id.Set.empty (Names.Id.of_string "__arith") gl in
let env' = List.map (fun (id,i) -> EConstr.mkVar id,i) vars in
@@ -2106,7 +1843,7 @@ let micromega_genr prover tac =
let intro_vars = Tacticals.New.tclTHENLIST (List.map intro vars) in
let intro_props = Tacticals.New.tclTHENLIST (List.map intro props) in
- let ipat_of_name id = Some (CAst.make @@ Misctypes.IntroNaming (Misctypes.IntroIdentifier id)) in
+ let ipat_of_name id = Some (CAst.make @@ IntroNaming (Namegen.IntroIdentifier id)) in
let goal_name = fresh_id Id.Set.empty (Names.Id.of_string "__arith") gl in
let env' = List.map (fun (id,i) -> EConstr.mkVar id,i) vars in
@@ -2158,7 +1895,11 @@ let lift_ratproof prover l =
| Some c -> Some (Mc.RatProof( c,Mc.DoneProof))
type micromega_polys = (Micromega.q Mc.pol * Mc.op1) list
+
+[@@@ocaml.warning "-37"]
type csdp_certificate = S of Sos_types.positivstellensatz option | F of string
+(* Used to read the result of the execution of csdpcert *)
+
type provername = string * int option
(**
@@ -2406,16 +2147,6 @@ let nlinear_Z = {
pp_f = fun o x -> pp_pol pp_z o (fst x)
}
-
-
-let tauto_lia ff =
- let prover = linear_Z in
- let cnf_ff,_ = cnf Mc.negate Mc.normalise Mc.zunsat Mc.zdeduce ff in
- match witness_list_tags [prover] cnf_ff with
- | None -> None
- | Some l -> Some (List.map fst l)
-
-
(**
* Functions instantiating micromega_gen with the appropriate theories and
* solvers
diff --git a/plugins/micromega/coq_micromega.mli b/plugins/micromega/coq_micromega.mli
new file mode 100644
index 00000000..b91feb39
--- /dev/null
+++ b/plugins/micromega/coq_micromega.mli
@@ -0,0 +1,22 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+val psatz_Z : int -> unit Proofview.tactic -> unit Proofview.tactic
+val psatz_Q : int -> unit Proofview.tactic -> unit Proofview.tactic
+val psatz_R : int -> unit Proofview.tactic -> unit Proofview.tactic
+val xlia : unit Proofview.tactic -> unit Proofview.tactic
+val xnlia : unit Proofview.tactic -> unit Proofview.tactic
+val nra : unit Proofview.tactic -> unit Proofview.tactic
+val nqa : unit Proofview.tactic -> unit Proofview.tactic
+val sos_Z : unit Proofview.tactic -> unit Proofview.tactic
+val sos_Q : unit Proofview.tactic -> unit Proofview.tactic
+val sos_R : unit Proofview.tactic -> unit Proofview.tactic
+val lra_Q : unit Proofview.tactic -> unit Proofview.tactic
+val lra_R : unit Proofview.tactic -> unit Proofview.tactic
diff --git a/plugins/micromega/csdpcert.ml b/plugins/micromega/csdpcert.ml
index a1245b7c..9c1b4810 100644
--- a/plugins/micromega/csdpcert.ml
+++ b/plugins/micromega/csdpcert.ml
@@ -20,7 +20,6 @@ open Sos_types
open Sos_lib
module Mc = Micromega
-module Ml2C = Mutils.CamlToCoq
module C2Ml = Mutils.CoqToCaml
type micromega_polys = (Micromega.q Mc.pol * Mc.op1) list
@@ -28,7 +27,6 @@ type csdp_certificate = S of Sos_types.positivstellensatz option | F of string
type provername = string * int option
-let debug = false
let flags = [Open_append;Open_binary;Open_creat]
let chan = open_out_gen flags 0o666 "trace"
@@ -55,27 +53,6 @@ struct
end
open M
-open Mutils
-
-
-
-
-let canonical_sum_to_string = function s -> failwith "not implemented"
-
-let print_canonical_sum m = Format.print_string (canonical_sum_to_string m)
-
-let print_list_term o l =
- output_string o "print_list_term\n";
- List.iter (fun (e,k) -> Printf.fprintf o "q: %s %s ;"
- (string_of_poly (poly_of_term (expr_to_term e)))
- (match k with
- Mc.Equal -> "= "
- | Mc.Strict -> "> "
- | Mc.NonStrict -> ">= "
- | _ -> failwith "not_implemented")) (List.map (fun (e, o) -> Mc.denorm e , o) l) ;
- output_string o "\n"
-
-
let partition_expr l =
let rec f i = function
| [] -> ([],[],[])
@@ -125,7 +102,7 @@ let real_nonlinear_prover d l =
(sets_of_list neq) in
let (cert_ideal, cert_cone,monoid) = deepen_until d (fun d ->
- list_try_find (fun m -> let (ci,cc) =
+ tryfind (fun m -> let (ci,cc) =
real_positivnullstellensatz_general false d peq pge (poly_neg (fst m) ) in
(ci,cc,snd m)) monoids) 0 in
@@ -144,7 +121,7 @@ let real_nonlinear_prover d l =
| l -> Monoid l in
List.fold_right (fun x y -> Product(x,y)) lt sq in
- let proof = list_fold_right_elements
+ let proof = end_itlist
(fun s t -> Sum(s,t)) (proof_ne :: proofs_ideal @ proofs_cone) in
S (Some proof)
with
@@ -158,7 +135,7 @@ let pure_sos l =
(* If there is no strict inequality,
I should nonetheless be able to try something - over Z > is equivalent to -1 >= *)
try
- let l = List.combine l (interval 0 (List.length l -1)) in
+ let l = List.combine l (CList.interval 0 (List.length l -1)) in
let (lt,i) = try (List.find (fun (x,_) -> Pervasives.(=) (snd x) Mc.Strict) l)
with Not_found -> List.hd l in
let plt = poly_neg (poly_of_term (expr_to_term (fst lt))) in
@@ -183,13 +160,6 @@ let run_prover prover pb =
| "pure_sos", None -> pure_sos pb
| prover, _ -> (Printf.printf "unknown prover: %s\n" prover; exit 1)
-
-let output_csdp_certificate o = function
- | S None -> output_string o "S None"
- | S (Some p) -> Printf.fprintf o "S (Some %a)" output_psatz p
- | F s -> Printf.fprintf o "F %s" s
-
-
let main () =
try
let (prover,poly) = (input_value stdin : provername * micromega_polys) in
diff --git a/plugins/micromega/csdpcert.mli b/plugins/micromega/csdpcert.mli
new file mode 100644
index 00000000..7c3ee600
--- /dev/null
+++ b/plugins/micromega/csdpcert.mli
@@ -0,0 +1,9 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
diff --git a/plugins/micromega/g_micromega.ml4 b/plugins/micromega/g_micromega.mlg
index 81140a46..21f0414e 100644
--- a/plugins/micromega/g_micromega.ml4
+++ b/plugins/micromega/g_micromega.mlg
@@ -16,70 +16,74 @@
(* *)
(************************************************************************)
+{
+
open Ltac_plugin
open Stdarg
open Tacarg
+}
+
DECLARE PLUGIN "micromega_plugin"
TACTIC EXTEND RED
-| [ "myred" ] -> [ Tactics.red_in_concl ]
+| [ "myred" ] -> { Tactics.red_in_concl }
END
TACTIC EXTEND PsatzZ
-| [ "psatz_Z" int_or_var(i) tactic(t) ] -> [ (Coq_micromega.psatz_Z i
+| [ "psatz_Z" int_or_var(i) tactic(t) ] -> { (Coq_micromega.psatz_Z i
(Tacinterp.tactic_of_value ist t))
- ]
-| [ "psatz_Z" tactic(t)] -> [ (Coq_micromega.psatz_Z (-1)) (Tacinterp.tactic_of_value ist t) ]
+ }
+| [ "psatz_Z" tactic(t)] -> { (Coq_micromega.psatz_Z (-1)) (Tacinterp.tactic_of_value ist t) }
END
TACTIC EXTEND Lia
-[ "xlia" tactic(t) ] -> [ (Coq_micromega.xlia (Tacinterp.tactic_of_value ist t)) ]
+| [ "xlia" tactic(t) ] -> { (Coq_micromega.xlia (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND Nia
-[ "xnlia" tactic(t) ] -> [ (Coq_micromega.xnlia (Tacinterp.tactic_of_value ist t)) ]
+| [ "xnlia" tactic(t) ] -> { (Coq_micromega.xnlia (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND NRA
-[ "xnra" tactic(t) ] -> [ (Coq_micromega.nra (Tacinterp.tactic_of_value ist t))]
+| [ "xnra" tactic(t) ] -> { (Coq_micromega.nra (Tacinterp.tactic_of_value ist t))}
END
TACTIC EXTEND NQA
-[ "xnqa" tactic(t) ] -> [ (Coq_micromega.nqa (Tacinterp.tactic_of_value ist t))]
+| [ "xnqa" tactic(t) ] -> { (Coq_micromega.nqa (Tacinterp.tactic_of_value ist t))}
END
TACTIC EXTEND Sos_Z
-| [ "sos_Z" tactic(t) ] -> [ (Coq_micromega.sos_Z (Tacinterp.tactic_of_value ist t)) ]
+| [ "sos_Z" tactic(t) ] -> { (Coq_micromega.sos_Z (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND Sos_Q
-| [ "sos_Q" tactic(t) ] -> [ (Coq_micromega.sos_Q (Tacinterp.tactic_of_value ist t)) ]
+| [ "sos_Q" tactic(t) ] -> { (Coq_micromega.sos_Q (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND Sos_R
-| [ "sos_R" tactic(t) ] -> [ (Coq_micromega.sos_R (Tacinterp.tactic_of_value ist t)) ]
+| [ "sos_R" tactic(t) ] -> { (Coq_micromega.sos_R (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND LRA_Q
-[ "lra_Q" tactic(t) ] -> [ (Coq_micromega.lra_Q (Tacinterp.tactic_of_value ist t)) ]
+| [ "lra_Q" tactic(t) ] -> { (Coq_micromega.lra_Q (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND LRA_R
-[ "lra_R" tactic(t) ] -> [ (Coq_micromega.lra_R (Tacinterp.tactic_of_value ist t)) ]
+| [ "lra_R" tactic(t) ] -> { (Coq_micromega.lra_R (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND PsatzR
-| [ "psatz_R" int_or_var(i) tactic(t) ] -> [ (Coq_micromega.psatz_R i (Tacinterp.tactic_of_value ist t)) ]
-| [ "psatz_R" tactic(t) ] -> [ (Coq_micromega.psatz_R (-1) (Tacinterp.tactic_of_value ist t)) ]
+| [ "psatz_R" int_or_var(i) tactic(t) ] -> { (Coq_micromega.psatz_R i (Tacinterp.tactic_of_value ist t)) }
+| [ "psatz_R" tactic(t) ] -> { (Coq_micromega.psatz_R (-1) (Tacinterp.tactic_of_value ist t)) }
END
TACTIC EXTEND PsatzQ
-| [ "psatz_Q" int_or_var(i) tactic(t) ] -> [ (Coq_micromega.psatz_Q i (Tacinterp.tactic_of_value ist t)) ]
-| [ "psatz_Q" tactic(t) ] -> [ (Coq_micromega.psatz_Q (-1) (Tacinterp.tactic_of_value ist t)) ]
+| [ "psatz_Q" int_or_var(i) tactic(t) ] -> { (Coq_micromega.psatz_Q i (Tacinterp.tactic_of_value ist t)) }
+| [ "psatz_Q" tactic(t) ] -> { (Coq_micromega.psatz_Q (-1) (Tacinterp.tactic_of_value ist t)) }
END
diff --git a/plugins/micromega/g_micromega.mli b/plugins/micromega/g_micromega.mli
new file mode 100644
index 00000000..7c3ee600
--- /dev/null
+++ b/plugins/micromega/g_micromega.mli
@@ -0,0 +1,9 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
diff --git a/plugins/micromega/mfourier.ml b/plugins/micromega/mfourier.ml
index 37799441..3328abda 100644
--- a/plugins/micromega/mfourier.ml
+++ b/plugins/micromega/mfourier.ml
@@ -1,13 +1,9 @@
+open Util
open Num
-module Utils = Mutils
open Polynomial
open Vect
-let map_option = Utils.map_option
-let from_option = Utils.from_option
-
let debug = false
-type ('a,'b) lr = Inl of 'a | Inr of 'b
let compare_float (p : float) q = Pervasives.compare p q
@@ -26,9 +22,6 @@ struct
Intervals needs to be explicitly normalised.
*)
- type who = Left | Right
-
-
(** if then interval [itv] is empty, [norm_itv itv] returns [None]
otherwise, it returns [Some itv] *)
@@ -37,14 +30,6 @@ struct
| Some a , Some b -> if a <=/ b then Some itv else None
| _ -> Some itv
- (** [opp_itv itv] computes the opposite interval *)
- let opp_itv itv =
- let (l,r) = itv in
- (map_option minus_num r, map_option minus_num l)
-
-
-
-
(** [inter i1 i2 = None] if the intersection of intervals is empty
[inter i1 i2 = Some i] if [i] is the intersection of the intervals [i1] and [i2] *)
let inter i1 i2 =
@@ -92,10 +77,6 @@ type vector = Vect.t
module ISet = Set.Make(Int)
-
-module PSet = ISet
-
-
module System = Hashtbl.Make(Vect)
type proof =
@@ -131,14 +112,6 @@ and cstr_info = {
(** To be thrown when a system has no solution *)
exception SystemContradiction of proof
-let hyps prf =
- let rec hyps prf acc =
- match prf with
- | Assum i -> ISet.add i acc
- | Elim(_,prf1,prf2)
- | And(prf1,prf2) -> hyps prf1 (hyps prf2 acc) in
- hyps prf ISet.empty
-
(** Pretty printing *)
let rec pp_proof o prf =
@@ -147,26 +120,6 @@ let hyps prf =
| Elim(v, prf1,prf2) -> Printf.fprintf o "E(%i,%a,%a)" v pp_proof prf1 pp_proof prf2
| And(prf1,prf2) -> Printf.fprintf o "A(%a,%a)" pp_proof prf1 pp_proof prf2
-let pp_bound o = function
- | None -> output_string o "oo"
- | Some a -> output_string o (string_of_num a)
-
-let pp_itv o (l,r) = Printf.fprintf o "(%a,%a)" pp_bound l pp_bound r
-
-
-let pp_iset o s =
- output_string o "{" ;
- ISet.fold (fun i _ -> Printf.fprintf o "%i " i) s ();
- output_string o "}"
-
-let pp_pset o s =
- output_string o "{" ;
- PSet.fold (fun i _ -> Printf.fprintf o "%i " i) s ();
- output_string o "}"
-
-
-let pp_info o i = pp_itv o i.bound
-
let pp_cstr o (vect,bnd) =
let (l,r) = bnd in
(match l with
@@ -183,11 +136,6 @@ let pp_system o sys=
System.iter (fun vect ibnd ->
pp_cstr o (vect,(!ibnd).bound)) sys
-
-
-let pp_split_cstr o (vl,v,c,_) =
- Printf.fprintf o "(val x = %s ,%a,%s)" (string_of_num vl) pp_vect v (string_of_num c)
-
(** [merge_cstr_info] takes:
- the intersection of bounds and
- the union of proofs
@@ -243,8 +191,8 @@ let normalise_cstr vect cinfo =
(if n <>/ Int 1 then List.map (fun (x,nx) -> (x,nx // n)) vect else vect),
let divn x = x // n in
if Int.equal (sign_num n) 1
- then{cinfo with bound = (map_option divn l , map_option divn r) }
- else {cinfo with pos = cinfo.neg ; neg = cinfo.pos ; bound = (map_option divn r , map_option divn l)})
+ then{cinfo with bound = (Option.map divn l , Option.map divn r) }
+ else {cinfo with pos = cinfo.neg ; neg = cinfo.pos ; bound = (Option.map divn r , Option.map divn l)})
(** For compatibility, there is an external representation of constraints *)
@@ -281,7 +229,7 @@ let load_system l =
let sys = System.create 1000 in
- let li = Mutils.mapi (fun e i -> (e,i)) l in
+ let li = List.mapi (fun i e -> (e,i)) l in
let vars = List.fold_left (fun vrs (cstr,i) ->
match norm_cstr cstr i with
@@ -335,9 +283,6 @@ let add (v1,c1) (v2,c2) =
(* Printf.printf "add(%a,%s,%a,%s) -> %a\n" pp_vect v1 (string_of_num c1) pp_vect v2 (string_of_num c2) pp_vect (fst res) ;*)
res
-type tlr = (num * vector * cstr_info) list
-type tm = (vector * cstr_info ) list
-
(** To perform Fourier elimination, constraints are categorised depending on the sign of the variable to eliminate. *)
(** [split x vect info (l,m,r)]
@@ -381,8 +326,8 @@ let project vr sys =
let {neg = n1 ; pos = p1 ; bound = bound1 ; prf = prf1} = info1
and {neg = n2 ; pos = p2 ; bound = bound2 ; prf = prf2} = info2 in
- let bnd1 = from_option (fst bound1)
- and bnd2 = from_option (fst bound2) in
+ let bnd1 = Option.get (fst bound1)
+ and bnd2 = Option.get (fst bound2) in
let bound = (bnd1 // v1) +/ (bnd2 // minus_num v2) in
let vres,(n,p) = add (vect1,v1) (vect2,minus_num v2) in
(vres,{neg = n ; pos = p ; bound = (Some bound, None); prf = Elim(vr,info1.prf,info2.prf)}) in
@@ -419,13 +364,13 @@ let project_using_eq vr c vect bound prf (vect',info') =
let bndres =
let f x = cst +/ x // c2 in
let (l,r) = info'.bound in
- (map_option f l , map_option f r) in
+ (Option.map f l , Option.map f r) in
(vres,{neg = n ; pos = p ; bound = bndres ; prf = Elim(vr,prf,info'.prf)})
| None -> (vect',info')
let elim_var_using_eq vr vect cst prf sys =
- let c = from_option (get vr vect) in
+ let c = Option.get (get vr vect) in
let elim_var = project_using_eq vr c vect cst prf in
@@ -444,9 +389,7 @@ let elim_var_using_eq vr vect cst prf sys =
(** [size sys] computes the number of entries in the system of constraints *)
let size sys = System.fold (fun v iref s -> s + (!iref).neg + (!iref).pos) sys 0
-module IMap = Map.Make(Int)
-
-let pp_map o map = IMap.fold (fun k elt () -> Printf.fprintf o "%i -> %s\n" k (string_of_num elt)) map ()
+module IMap = CMap.Make(Int)
(** [eval_vect map vect] evaluates vector [vect] using the values of [map].
If [map] binds all the variables of [vect], we get
@@ -475,8 +418,8 @@ let restrict_bound n sum (itv:interval) =
| 0 -> if in_bound itv sum
then (None,None) (* redundant *)
else failwith "SystemContradiction"
- | 1 -> map_option f l , map_option f r
- | _ -> map_option f r , map_option f l
+ | 1 -> Option.map f l , Option.map f r
+ | _ -> Option.map f r , Option.map f l
(** [bound_of_variable map v sys] computes the interval of [v] in
@@ -613,12 +556,6 @@ struct
|(Some a, Some b) -> a =/ b
| _ -> false
- let eq_bound bnd c =
- match bnd with
- |(Some a, Some b) -> a =/ b && c =/ b
- | _ -> false
-
-
let rec unroll_until v l =
match l with
| [] -> (false,[])
diff --git a/plugins/micromega/mfourier.mli b/plugins/micromega/mfourier.mli
new file mode 100644
index 00000000..f1d8edea
--- /dev/null
+++ b/plugins/micromega/mfourier.mli
@@ -0,0 +1,49 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module Itv : sig
+
+ type interval = Num.num option * Num.num option
+ val range : interval -> Num.num option
+ val smaller_itv : interval -> interval -> bool
+
+end
+
+module IMap : CSig.MapS with type key = int
+
+type proof
+
+module Fourier : sig
+
+ val find_point : Polynomial.cstr_compat list ->
+ ((IMap.key * Num.num) list, proof) Util.union
+
+ val optimise : Polynomial.Vect.t ->
+ Polynomial.cstr_compat list ->
+ Itv.interval option
+
+end
+
+val pp_proof : out_channel -> proof -> unit
+
+module Proof : sig
+
+ val mk_proof : Polynomial.cstr_compat list ->
+ proof -> (Polynomial.Vect.t * Polynomial.cstr_compat) list
+
+ val add_op : Polynomial.op -> Polynomial.op -> Polynomial.op
+
+end
+
+val max_nb_cstr : int ref
+
+val eval_op : Polynomial.op -> Num.num -> Num.num -> bool
+
+exception TimeOut
diff --git a/plugins/micromega/mutils.ml b/plugins/micromega/mutils.ml
index 82367c0b..9d03560b 100644
--- a/plugins/micromega/mutils.ml
+++ b/plugins/micromega/mutils.ml
@@ -19,8 +19,6 @@
(* *)
(************************************************************************)
-let debug = false
-
let rec pp_list f o l =
match l with
| [] -> ()
@@ -36,15 +34,6 @@ let finally f rst =
with any -> raise reraise
); raise reraise
-let map_option f x =
- match x with
- | None -> None
- | Some v -> Some (f v)
-
-let from_option = function
- | None -> failwith "from_option"
- | Some v -> v
-
let rec try_any l x =
match l with
| [] -> None
@@ -52,13 +41,6 @@ let rec try_any l x =
| None -> try_any l x
| x -> x
-let iteri f l =
- let rec xiter i l =
- match l with
- | [] -> ()
- | e::l -> f i e ; xiter (i+1) l in
- xiter 0 l
-
let all_sym_pairs f l =
let pair_with acc e l = List.fold_left (fun acc x -> (f e x) ::acc) acc l in
@@ -77,14 +59,6 @@ let all_pairs f l =
| e::lx -> xpairs (pair_with acc e l) lx in
xpairs [] l
-
-
-let rec map3 f l1 l2 l3 =
- match l1 , l2 ,l3 with
- | [] , [] , [] -> []
- | e1::l1 , e2::l2 , e3::l3 -> (f e1 e2 e3)::(map3 f l1 l2 l3)
- | _ -> invalid_arg "map3"
-
let rec is_sublist f l1 l2 =
match l1 ,l2 with
| [] ,_ -> true
@@ -93,26 +67,6 @@ let rec is_sublist f l1 l2 =
if f e e' then is_sublist f l1' l2'
else is_sublist f l1 l2'
-let list_try_find f =
- let rec try_find_f = function
- | [] -> failwith "try_find"
- | h::t -> try f h with Failure _ -> try_find_f t
- in
- try_find_f
-
-let list_fold_right_elements f l =
- let rec aux = function
- | [] -> invalid_arg "list_fold_right_elements"
- | [x] -> x
- | x::l -> f x (aux l) in
- aux 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 extract pred l =
List.fold_left (fun (fd,sys) e ->
match fd with
@@ -163,51 +117,7 @@ let rats_to_ints l =
List.map (fun x -> (div_big_int (mult_big_int (numerator x) c)
(denominator x))) l
-(* Nasty reordering of lists - useful to trim certificate down *)
-let mapi f l =
- let rec xmapi i l =
- match l with
- | [] -> []
- | e::l -> (f e i)::(xmapi (i+1) l) in
- xmapi 0 l
-
-let concatMapi f l = List.rev (mapi (fun e i -> (i,f e)) l)
-
(* assoc_pos j [a0...an] = [j,a0....an,j+n],j+n+1 *)
-let assoc_pos j l = (mapi (fun e i -> e,i+j) l, j + (List.length l))
-
-let assoc_pos_assoc l =
- let rec xpos i l =
- match l with
- | [] -> []
- | (x,l) ::rst -> let (l',j) = assoc_pos i l in
- (x,l')::(xpos j rst) in
- xpos 0 l
-
-let filter_pos f l =
- (* Could sort ... take care of duplicates... *)
- let rec xfilter l =
- match l with
- | [] -> []
- | (x,e)::l ->
- if List.exists (fun ee -> List.mem ee f) (List.map snd e)
- then (x,e)::(xfilter l)
- else xfilter l in
- xfilter l
-
-let select_pos lpos l =
- let rec xselect i lpos l =
- match lpos with
- | [] -> []
- | j::rpos ->
- match l with
- | [] -> failwith "select_pos"
- | e::l ->
- if Int.equal i j
- then e:: (xselect (i+1) rpos l)
- else xselect (i+1) lpos l in
- xselect 0 lpos l
-
(**
* MODULE: Coq to Caml data-structure mappings
*)
@@ -238,12 +148,6 @@ struct
| XI i -> 1+(2*(index i))
| XO i -> 2*(index i)
- let z x =
- match x with
- | Z0 -> 0
- | Zpos p -> (positive p)
- | Zneg p -> - (positive p)
-
open Big_int
let rec positive_big_int p =
@@ -258,8 +162,6 @@ struct
| Zpos p -> (positive_big_int p)
| Zneg p -> minus_big_int (positive_big_int p)
- let num x = Num.Big_int (z_big_int x)
-
let q_to_num {qnum = x ; qden = y} =
Big_int (z_big_int x) // (Big_int (z_big_int (Zpos y)))
@@ -352,17 +254,6 @@ struct
let c = cmp e1 e2 in
if Int.equal c 0 then compare_list cmp l1 l2 else c
-(**
- * hash_list takes a hash function and a list, and computes an integer which
- * is the hash value of the list.
- *)
- let hash_list hash l =
- let rec _hash_list l h =
- match l with
- | [] -> h lxor (Hashtbl.hash [])
- | e::l -> _hash_list l ((hash e) lxor h)
- in _hash_list l 0
-
end
(**
diff --git a/plugins/micromega/mutils.mli b/plugins/micromega/mutils.mli
new file mode 100644
index 00000000..094429ea
--- /dev/null
+++ b/plugins/micromega/mutils.mli
@@ -0,0 +1,70 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+val numerator : Num.num -> Big_int.big_int
+val denominator : Num.num -> Big_int.big_int
+
+module Cmp : sig
+
+ val compare_list : ('a -> 'b -> int) -> 'a list -> 'b list -> int
+ val compare_lexical : (unit -> int) list -> int
+
+end
+
+module Tag : sig
+
+ type t
+
+ val pp : out_channel -> t -> unit
+ val next : t -> t
+ val from : int -> t
+
+end
+
+module TagSet : CSig.SetS with type elt = Tag.t
+
+val pp_list : (out_channel -> 'a -> unit) -> out_channel -> 'a list -> unit
+
+module CamlToCoq : sig
+
+ val positive : int -> Micromega.positive
+ val bigint : Big_int.big_int -> Micromega.z
+ val n : int -> Micromega.n
+ val nat : int -> Micromega.nat
+ val q : Num.num -> Micromega.q
+ val index : int -> Micromega.positive
+ val z : int -> Micromega.z
+ val positive_big_int : Big_int.big_int -> Micromega.positive
+
+end
+
+module CoqToCaml : sig
+
+ val z_big_int : Micromega.z -> Big_int.big_int
+ val q_to_num : Micromega.q -> Num.num
+ val positive : Micromega.positive -> int
+ val n : Micromega.n -> int
+ val nat : Micromega.nat -> int
+ val index : Micromega.positive -> int
+
+end
+
+val rats_to_ints : Num.num list -> Big_int.big_int list
+
+val all_pairs : ('a -> 'a -> 'b) -> 'a list -> 'b list
+val all_sym_pairs : ('a -> 'a -> 'b) -> 'a list -> 'b list
+val try_any : (('a -> 'b option) * 'c) list -> 'a -> 'b option
+val is_sublist : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool
+
+val gcd_list : Num.num list -> Big_int.big_int
+
+val extract : ('a -> 'b option) -> 'a list -> ('b * 'a) option * 'a list
+
+val command : string -> string array -> 'a -> 'b
diff --git a/plugins/micromega/persistent_cache.mli b/plugins/micromega/persistent_cache.mli
new file mode 100644
index 00000000..240fa490
--- /dev/null
+++ b/plugins/micromega/persistent_cache.mli
@@ -0,0 +1,47 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Hashtbl
+
+module type PHashtable =
+ sig
+ type 'a t
+ type key
+
+ val create : int -> string -> 'a t
+ (** [create i f] creates an empty persistent table
+ with initial size i associated with file [f] *)
+
+
+ val open_in : string -> 'a t
+ (** [open_in f] rebuilds a table from the records stored in file [f].
+ As marshaling is not type-safe, it migth segault.
+ *)
+
+ val find : 'a t -> key -> 'a
+ (** find has the specification of Hashtable.find *)
+
+ val add : 'a t -> key -> 'a -> unit
+ (** [add tbl key elem] adds the binding [key] [elem] to the table [tbl].
+ (and writes the binding to the file associated with [tbl].)
+ If [key] is already bound, raises KeyAlreadyBound *)
+
+ val close : 'a t -> unit
+ (** [close tbl] is closing the table.
+ Once closed, a table cannot be used.
+ i.e, find,add will raise UnboundTable *)
+
+ val memo : string -> (key -> 'a) -> (key -> 'a)
+ (** [memo cache f] returns a memo function for [f] using file [cache] as persistent table.
+ Note that the cache will only be loaded when the function is used for the first time *)
+
+ end
+
+module PHashtable(Key:HashedType) : PHashtable with type key = Key.t
diff --git a/plugins/micromega/polynomial.ml b/plugins/micromega/polynomial.ml
index db8b73a2..1d18a26f 100644
--- a/plugins/micromega/polynomial.ml
+++ b/plugins/micromega/polynomial.ml
@@ -20,9 +20,9 @@ open Utils
type var = int
+let debug = false
let (<+>) = add_num
-let (<->) = minus_num
let (<*>) = mult_num
@@ -33,8 +33,6 @@ sig
val is_const : t -> bool
val var : var -> t
val is_var : t -> bool
- val find : var -> t -> int
- val mult : var -> t -> t
val prod : t -> t -> t
val exp : t -> int -> t
val div : t -> t -> t * int
@@ -99,9 +97,6 @@ struct
(* Get the degre of a variable in a monomial *)
let find x m = try find x m with Not_found -> 0
- (* Multiply a monomial by a variable *)
- let mult x m = add x ( (find x m) + 1) m
-
(* Product of monomials *)
let prod m1 m2 = Map.fold (fun k d m -> add k ((find k m) + d) m) m1 m2
@@ -145,14 +140,10 @@ sig
val variable : var -> t
val add : Monomial.t -> num -> t -> t
val constant : num -> t
- val mult : Monomial.t -> num -> t -> t
val product : t -> t -> t
val addition : t -> t -> t
val uminus : t -> t
val fold : (Monomial.t -> num -> 'a -> 'a) -> t -> 'a -> 'a
- val pp : out_channel -> t -> unit
- val compare : t -> t -> int
- val is_null : t -> bool
val is_linear : t -> bool
end =
struct
@@ -162,12 +153,6 @@ struct
type t = num P.t
- let pp o p = P.iter
- (fun k v ->
- if Monomial.compare Monomial.const k = 0
- then Printf.fprintf o "%s " (string_of_num v)
- else Printf.fprintf o "%s*%a " (string_of_num v) Monomial.pp k) p
-
(* Get the coefficient of monomial mn *)
let get : Monomial.t -> t -> num =
fun mn p -> try find mn p with Not_found -> (Int 0)
@@ -220,10 +205,6 @@ struct
let fold = P.fold
- let is_null p = fold (fun mn vl b -> b && sign_num vl = 0) p true
-
- let compare = compare compare_num
-
let is_linear p = P.fold (fun m _ acc -> acc && (Monomial.is_const m || Monomial.is_var m)) p true
(* let is_linear p =
@@ -277,7 +258,6 @@ module Vect =
xfrom_list 0 l
let zero_num = Int 0
- let unit_num = Int 1
let to_list m =
@@ -311,11 +291,6 @@ module Vect =
| 1 -> (k,v) :: (set i n l)
| _ -> failwith "compare_num"
- let gcd m =
- let res = List.fold_left (fun x (i,e) -> Big_int.gcd_big_int x (Utils.numerator e)) Big_int.zero_big_int m in
- if Big_int.compare_big_int res Big_int.zero_big_int = 0
- then Big_int.unit_big_int else res
-
let mul z t =
match z with
| Int 0 -> []
@@ -345,7 +320,7 @@ module Vect =
- let compare : t -> t -> int = Utils.Cmp.compare_list (fun x y -> Utils.Cmp.compare_lexical
+ let compare : t -> t -> int = Mutils.Cmp.compare_list (fun x y -> Mutils.Cmp.compare_lexical
[
(fun () -> Int.compare (fst x) (fst y));
(fun () -> compare_num (snd x) (snd y))])
@@ -395,18 +370,8 @@ let opMult o1 o2 =
| Eq , Ge | Ge , Eq -> Ge
| Ge , Ge -> Ge
-let opAdd o1 o2 =
- match o1 , o2 with
- | Eq , _ | _ , Eq -> Eq
- | Ge , Ge -> Ge
-
-
-
-
open Big_int
-type index = int
-
type prf_rule =
| Hyp of int
| Def of int
@@ -550,35 +515,6 @@ let mul_proof_ext (p,c) prf =
| _ -> MulC((p,c),prf)
-
-(*
- let rec scale_prf_rule = function
- | Hyp i -> (unit_big_int, Hyp i)
- | Def i -> (unit_big_int, Def i)
- | Cst c -> (unit_big_int, Cst i)
- | Zero -> (unit_big_int, Zero)
- | Square p -> (unit_big_int,Square p)
- | Div(c,pr) ->
- let (bi,pr') = scale_prf_rule pr in
- (mult_big_int c bi , pr')
- | MulC(p,pr) ->
- let bi,pr' = scale_prf_rule pr in
- (bi,MulC p,pr')
- | MulPrf(p1,p2) ->
- let b1,p1 = scale_prf_rule p1 in
- let b2,p2 = scale_prf_rule p2 in
-
-
- | AddPrf(p1,p2) ->
- let b1,p1 = scale_prf_rule p1 in
- let b2,p2 = scale_prf_rule p2 in
- let g = gcd_big_int
-*)
-
-
-
-
-
module LinPoly =
struct
type t = Vect.t * num
diff --git a/plugins/micromega/polynomial.mli b/plugins/micromega/polynomial.mli
new file mode 100644
index 00000000..4c095202
--- /dev/null
+++ b/plugins/micromega/polynomial.mli
@@ -0,0 +1,118 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+type var = int
+
+module Monomial : sig
+
+ type t
+ val fold : (var -> int -> 'a -> 'a) -> t -> 'a -> 'a
+ val const : t
+ val sqrt : t -> t option
+ val is_var : t -> bool
+ val div : t -> t -> t * int
+
+ val compare : t -> t -> int
+
+end
+
+module Poly : sig
+
+ type t
+
+ val constant : Num.num -> t
+ val variable : var -> t
+ val addition : t -> t -> t
+ val product : t -> t -> t
+ val uminus : t -> t
+ val get : Monomial.t -> t -> Num.num
+ val fold : (Monomial.t -> Num.num -> 'a -> 'a) -> t -> 'a -> 'a
+
+ val is_linear : t -> bool
+
+ val add : Monomial.t -> Num.num -> t -> t
+
+end
+
+module Vect : sig
+
+ type var = int
+ type t = (var * Num.num) list
+ val hash : t -> int
+ val equal : t -> t -> bool
+ val compare : t -> t -> int
+ val pp_vect : 'a -> t -> unit
+
+ val get : var -> t -> Num.num option
+ val set : var -> Num.num -> t -> t
+ val fresh : (int * 'a) list -> int
+ val update : Int.t -> (Num.num -> Num.num) ->
+ (Int.t * Num.num) list -> (Int.t * Num.num) list
+ val null : t
+
+ val from_list : Num.num list -> t
+ val to_list : t -> Num.num list
+
+ val add : t -> t -> t
+ val mul : Num.num -> t -> t
+
+end
+
+type cstr_compat = {coeffs : Vect.t ; op : op ; cst : Num.num}
+and op = Eq | Ge
+
+type prf_rule =
+ | Hyp of int
+ | Def of int
+ | Cst of Big_int.big_int
+ | Zero
+ | Square of (Vect.t * Num.num)
+ | MulC of (Vect.t * Num.num) * prf_rule
+ | Gcd of Big_int.big_int * prf_rule
+ | MulPrf of prf_rule * prf_rule
+ | AddPrf of prf_rule * prf_rule
+ | CutPrf of prf_rule
+
+type proof =
+ | Done
+ | Step of int * prf_rule * proof
+ | Enum of int * prf_rule * Vect.t * prf_rule * proof list
+
+val proof_max_id : proof -> int
+
+val normalise_proof : int -> proof -> int * proof
+
+val output_proof : out_channel -> proof -> unit
+
+val add_proof : prf_rule -> prf_rule -> prf_rule
+val mul_proof : Big_int.big_int -> prf_rule -> prf_rule
+
+module LinPoly : sig
+
+ type t = Vect.t * Num.num
+
+ module MonT : sig
+
+ val clear : unit -> unit
+ val retrieve : int -> Monomial.t
+
+ end
+
+ val pivot_eq : Vect.var ->
+ cstr_compat * prf_rule ->
+ cstr_compat * prf_rule -> (cstr_compat * prf_rule) option
+
+ val linpol_of_pol : Poly.t -> t
+
+end
+
+val output_cstr : out_channel -> cstr_compat -> unit
+
+val opMult : op -> op -> op
diff --git a/plugins/micromega/sos.ml b/plugins/micromega/sos.ml
index e1ceabe9..42a41e17 100644
--- a/plugins/micromega/sos.ml
+++ b/plugins/micromega/sos.ml
@@ -95,7 +95,7 @@ let dim (v:vector) = fst v;;
let vector_const c n =
if c =/ Int 0 then vector_0 n
- else (n,itlist (fun k -> k |-> c) (1--n) undefined :vector);;
+ else (n,List.fold_right (fun k -> k |-> c) (1--n) undefined :vector);;
let vector_cmul c (v:vector) =
let n = dim v in
@@ -104,7 +104,7 @@ let vector_cmul c (v:vector) =
let vector_of_list l =
let n = List.length l in
- (n,itlist2 (|->) (1--n) l undefined :vector);;
+ (n,List.fold_right2 (|->) (1--n) l undefined :vector);;
(* ------------------------------------------------------------------------- *)
(* Matrices; again rows and columns indexed from 1. *)
@@ -242,7 +242,7 @@ let string_of_monomial m =
if m = monomial_1 then "1" else
let vps = List.fold_right (fun (x,k) a -> string_of_varpow x k :: a)
(sort humanorder_varpow (graph m)) [] in
- end_itlist (fun s t -> s^"*"^t) vps;;
+ String.concat "*" vps;;
let string_of_cmonomial (c,m) =
if m = monomial_1 then string_of_num c
@@ -310,7 +310,7 @@ let rec poly_of_term t = match t with
let sdpa_of_vector (v:vector) =
let n = dim v in
let strs = List.map (o (decimalize 20) (element v)) (1--n) in
- end_itlist (fun x y -> x ^ " " ^ y) strs ^ "\n";;
+ String.concat " " strs ^ "\n";;
(* ------------------------------------------------------------------------- *)
(* String for a matrix numbered k, in SDPA sparse format. *)
@@ -321,7 +321,7 @@ let sdpa_of_matrix k (m:matrix) =
let ms = foldr (fun (i,j) c a -> if i > j then a else ((i,j),c)::a)
(snd m) [] in
let mss = sort (increasing fst) ms in
- itlist (fun ((i,j),c) a ->
+ List.fold_right (fun ((i,j),c) a ->
pfx ^ string_of_int i ^ " " ^ string_of_int j ^
" " ^ decimalize 20 c ^ "\n" ^ a) mss "";;
@@ -340,7 +340,7 @@ let sdpa_of_problem comment obj mats =
"1\n" ^
string_of_int n ^ "\n" ^
sdpa_of_vector obj ^
- itlist2 (fun k m a -> sdpa_of_matrix (k - 1) m ^ a)
+ List.fold_right2 (fun k m a -> sdpa_of_matrix (k - 1) m ^ a)
(1--List.length mats) mats "";;
(* ------------------------------------------------------------------------- *)
@@ -489,11 +489,11 @@ let scale_then =
and maximal_element amat acc =
foldl (fun maxa m c -> max_num maxa (abs_num c)) acc amat in
fun solver obj mats ->
- let cd1 = itlist common_denominator mats (Int 1)
+ let cd1 = List.fold_right common_denominator mats (Int 1)
and cd2 = common_denominator (snd obj) (Int 1) in
let mats' = List.map (mapf (fun x -> cd1 */ x)) mats
and obj' = vector_cmul cd2 obj in
- let max1 = itlist maximal_element mats' (Int 0)
+ let max1 = List.fold_right maximal_element mats' (Int 0)
and max2 = maximal_element (snd obj') (Int 0) in
let scal1 = pow2 (20-int_of_float(log(float_of_num max1) /. log 2.0))
and scal2 = pow2 (20-int_of_float(log(float_of_num max2) /. log 2.0)) in
@@ -551,7 +551,7 @@ let minimal_convex_hull =
| (m::ms) -> if in_convex_hull ms m then ms else ms@[m] in
let augment m ms = funpow 3 augment1 (m::ms) in
fun mons ->
- let mons' = itlist augment (List.tl mons) [List.hd mons] in
+ let mons' = List.fold_right augment (List.tl mons) [List.hd mons] in
funpow (List.length mons') augment1 mons';;
(* ------------------------------------------------------------------------- *)
@@ -612,11 +612,11 @@ let newton_polytope pol =
let vars = poly_variables pol in
let mons = List.map (fun m -> List.map (fun x -> monomial_degree x m) vars) (dom pol)
and ds = List.map (fun x -> (degree x pol + 1) / 2) vars in
- let all = itlist (fun n -> allpairs (fun h t -> h::t) (0--n)) ds [[]]
+ let all = List.fold_right (fun n -> allpairs (fun h t -> h::t) (0--n)) ds [[]]
and mons' = minimal_convex_hull mons in
let all' =
List.filter (fun m -> in_convex_hull mons' (List.map (fun x -> 2 * x) m)) all in
- List.map (fun m -> itlist2 (fun v i a -> if i = 0 then a else (v |-> i) a)
+ List.map (fun m -> List.fold_right2 (fun v i a -> if i = 0 then a else (v |-> i) a)
vars m monomial_1) (List.rev all');;
(* ------------------------------------------------------------------------- *)
@@ -657,8 +657,8 @@ let deration d =
foldl (fun a i c -> gcd_num a (numerator c)) (Int 0) (snd l) in
(c // (a */ a)),mapa (fun x -> a */ x) l in
let d' = List.map adj d in
- let a = itlist ((o) lcm_num ( (o) denominator fst)) d' (Int 1) //
- itlist ((o) gcd_num ( (o) numerator fst)) d' (Int 0) in
+ let a = List.fold_right ((o) lcm_num ( (o) denominator fst)) d' (Int 1) //
+ List.fold_right ((o) gcd_num ( (o) numerator fst)) d' (Int 0) in
(Int 1 // a),List.map (fun (c,l) -> (a */ c,l)) d';;
(* ------------------------------------------------------------------------- *)
@@ -719,7 +719,7 @@ let sdpa_of_blockdiagonal k m =
let ents =
foldl (fun a (b,i,j) c -> if i > j then a else ((b,i,j),c)::a) [] m in
let entss = sort (increasing fst) ents in
- itlist (fun ((b,i,j),c) a ->
+ List.fold_right (fun ((b,i,j),c) a ->
pfx ^ string_of_int b ^ " " ^ string_of_int i ^ " " ^ string_of_int j ^
" " ^ decimalize 20 c ^ "\n" ^ a) entss "";;
@@ -732,10 +732,10 @@ let sdpa_of_blockproblem comment nblocks blocksizes obj mats =
"\"" ^ comment ^ "\"\n" ^
string_of_int m ^ "\n" ^
string_of_int nblocks ^ "\n" ^
- (end_itlist (fun s t -> s^" "^t) (List.map string_of_int blocksizes)) ^
+ (String.concat " " (List.map string_of_int blocksizes)) ^
"\n" ^
sdpa_of_vector obj ^
- itlist2 (fun k m a -> sdpa_of_blockdiagonal (k - 1) m ^ a)
+ List.fold_right2 (fun k m a -> sdpa_of_blockdiagonal (k - 1) m ^ a)
(1--List.length mats) mats "";;
(* ------------------------------------------------------------------------- *)
@@ -791,14 +791,14 @@ let blocks blocksizes bm =
(fun a (b,i,j) c -> if b = b0 then ((i,j) |-> c) a else a)
undefined bm in
(((bs,bs),m):matrix))
- (zip blocksizes (1--List.length blocksizes));;
+ (List.combine blocksizes (1--List.length blocksizes));;
(* ------------------------------------------------------------------------- *)
(* Positiv- and Nullstellensatz. Flag "linf" forces a linear representation. *)
(* ------------------------------------------------------------------------- *)
let real_positivnullstellensatz_general linf d eqs leqs pol =
- let vars = itlist ((o) union poly_variables) (pol::eqs @ List.map fst leqs) [] in
+ let vars = List.fold_right ((o) union poly_variables) (pol::eqs @ List.map fst leqs) [] in
let monoid =
if linf then
(poly_const num_1,Rational_lt num_1)::
@@ -808,16 +808,16 @@ let real_positivnullstellensatz_general linf d eqs leqs pol =
let mk_idmultiplier k p =
let e = d - multidegree p in
let mons = enumerate_monomials e vars in
- let nons = zip mons (1--List.length mons) in
+ let nons = List.combine mons (1--List.length mons) in
mons,
- itlist (fun (m,n) -> (m |-> ((-k,-n,n) |=> Int 1))) nons undefined in
+ List.fold_right (fun (m,n) -> (m |-> ((-k,-n,n) |=> Int 1))) nons undefined in
let mk_sqmultiplier k (p,c) =
let e = (d - multidegree p) / 2 in
let mons = enumerate_monomials e vars in
- let nons = zip mons (1--List.length mons) in
+ let nons = List.combine mons (1--List.length mons) in
mons,
- itlist (fun (m1,n1) ->
- itlist (fun (m2,n2) a ->
+ List.fold_right (fun (m1,n1) ->
+ List.fold_right (fun (m2,n2) a ->
let m = monomial_mul m1 m2 in
if n1 > n2 then a else
let c = if n1 = n2 then Int 1 else Int 2 in
@@ -825,17 +825,17 @@ let real_positivnullstellensatz_general linf d eqs leqs pol =
(m |-> equation_add ((k,n1,n2) |=> c) e) a)
nons)
nons undefined in
- let sqmonlist,sqs = unzip(List.map2 mk_sqmultiplier (1--List.length monoid) monoid)
- and idmonlist,ids = unzip(List.map2 mk_idmultiplier (1--List.length eqs) eqs) in
+ let sqmonlist,sqs = List.split(List.map2 mk_sqmultiplier (1--List.length monoid) monoid)
+ and idmonlist,ids = List.split(List.map2 mk_idmultiplier (1--List.length eqs) eqs) in
let blocksizes = List.map List.length sqmonlist in
let bigsum =
- itlist2 (fun p q a -> epoly_pmul p q a) eqs ids
- (itlist2 (fun (p,c) s a -> epoly_pmul p s a) monoid sqs
+ List.fold_right2 (fun p q a -> epoly_pmul p q a) eqs ids
+ (List.fold_right2 (fun (p,c) s a -> epoly_pmul p s a) monoid sqs
(epoly_of_poly(poly_neg pol))) in
let eqns = foldl (fun a m e -> e::a) [] bigsum in
let pvs,assig = eliminate_all_equations (0,0,0) eqns in
let qvars = (0,0,0)::pvs in
- let allassig = itlist (fun v -> (v |-> (v |=> Int 1))) pvs assig in
+ let allassig = List.fold_right (fun v -> (v |-> (v |=> Int 1))) pvs assig in
let mk_matrix v =
foldl (fun m (b,i,j) ass -> if b < 0 then m else
let c = tryapplyd ass v (Int 0) in
@@ -858,8 +858,8 @@ let real_positivnullstellensatz_general linf d eqs leqs pol =
else ());
let vec = nice_vector d raw_vec in
let blockmat = iter (1,dim vec)
- (fun i a -> bmatrix_add (bmatrix_cmul (element vec i) (el i mats)) a)
- (bmatrix_neg (el 0 mats)) in
+ (fun i a -> bmatrix_add (bmatrix_cmul (element vec i) (List.nth mats i)) a)
+ (bmatrix_neg (List.nth mats 0)) in
let allmats = blocks blocksizes blockmat in
vec,List.map diag allmats in
let vec,ratdias =
@@ -867,7 +867,7 @@ let real_positivnullstellensatz_general linf d eqs leqs pol =
else tryfind find_rounding (List.map Num.num_of_int (1--31) @
List.map pow2 (5--66)) in
let newassigs =
- itlist (fun k -> el (k - 1) pvs |-> element vec k)
+ List.fold_right (fun k -> List.nth pvs (k - 1) |-> element vec k)
(1--dim vec) ((0,0,0) |=> Int(-1)) in
let finalassigs =
foldl (fun a v e -> (v |-> equation_eval newassigs e) a) newassigs
@@ -877,17 +877,17 @@ let real_positivnullstellensatz_general linf d eqs leqs pol =
undefined p in
let mk_sos mons =
let mk_sq (c,m) =
- c,itlist (fun k a -> (el (k - 1) mons |--> element m k) a)
+ c,List.fold_right (fun k a -> (List.nth mons (k - 1) |--> element m k) a)
(1--List.length mons) undefined in
List.map mk_sq in
let sqs = List.map2 mk_sos sqmonlist ratdias
and cfs = List.map poly_of_epoly ids in
let msq = List.filter (fun (a,b) -> b <> []) (List.map2 (fun a b -> a,b) monoid sqs) in
- let eval_sq sqs = itlist
+ let eval_sq sqs = List.fold_right
(fun (c,q) -> poly_add (poly_cmul c (poly_mul q q))) sqs poly_0 in
let sanity =
- itlist (fun ((p,c),s) -> poly_add (poly_mul p (eval_sq s))) msq
- (itlist2 (fun p q -> poly_add (poly_mul p q)) cfs eqs
+ List.fold_right (fun ((p,c),s) -> poly_add (poly_mul p (eval_sq s))) msq
+ (List.fold_right2 (fun p q -> poly_add (poly_mul p q)) cfs eqs
(poly_neg pol)) in
if not(is_undefined sanity) then raise Sanity else
cfs,List.map (fun (a,b) -> snd a,b) msq;;
@@ -913,8 +913,8 @@ let monomial_order =
fun m1 m2 ->
if m2 = monomial_1 then true else if m1 = monomial_1 then false else
let mon1 = dest_monomial m1 and mon2 = dest_monomial m2 in
- let deg1 = itlist ((o) (+) snd) mon1 0
- and deg2 = itlist ((o) (+) snd) mon2 0 in
+ let deg1 = List.fold_right ((o) (+) snd) mon1 0
+ and deg2 = List.fold_right ((o) (+) snd) mon2 0 in
if deg1 < deg2 then false else if deg1 > deg2 then true
else lexorder mon1 mon2;;
@@ -929,7 +929,7 @@ let term_of_varpow =
let term_of_monomial =
fun m -> if m = monomial_1 then Const num_1 else
let m' = dest_monomial m in
- let vps = itlist (fun (x,k) a -> term_of_varpow x k :: a) m' [] in
+ let vps = List.fold_right (fun (x,k) a -> term_of_varpow x k :: a) m' [] in
end_itlist (fun s t -> Mul (s,t)) vps;;
let term_of_cmonomial =
@@ -953,202 +953,12 @@ let term_of_sos (pr,sqs) =
else Product(pr,end_itlist (fun a b -> Sum(a,b)) (List.map term_of_sqterm sqs));;
(* ------------------------------------------------------------------------- *)
-(* Interface to HOL. *)
-(* ------------------------------------------------------------------------- *)
-(*
-let REAL_NONLINEAR_PROVER translator (eqs,les,lts) =
- let eq0 = map (poly_of_term o lhand o concl) eqs
- and le0 = map (poly_of_term o lhand o concl) les
- and lt0 = map (poly_of_term o lhand o concl) lts in
- let eqp0 = map (fun (t,i) -> t,Axiom_eq i) (zip eq0 (0--(length eq0 - 1)))
- and lep0 = map (fun (t,i) -> t,Axiom_le i) (zip le0 (0--(length le0 - 1)))
- and ltp0 = map (fun (t,i) -> t,Axiom_lt i) (zip lt0 (0--(length lt0 - 1))) in
- let keq,eq = partition (fun (p,_) -> multidegree p = 0) eqp0
- and klep,lep = partition (fun (p,_) -> multidegree p = 0) lep0
- and kltp,ltp = partition (fun (p,_) -> multidegree p = 0) ltp0 in
- let trivial_axiom (p,ax) =
- match ax with
- Axiom_eq n when eval undefined p <>/ num_0 -> el n eqs
- | Axiom_le n when eval undefined p </ num_0 -> el n les
- | Axiom_lt n when eval undefined p <=/ num_0 -> el n lts
- | _ -> failwith "not a trivial axiom" in
- try let th = tryfind trivial_axiom (keq @ klep @ kltp) in
- CONV_RULE (LAND_CONV REAL_POLY_CONV THENC REAL_RAT_RED_CONV) th
- with Failure _ ->
- let pol = itlist poly_mul (map fst ltp) (poly_const num_1) in
- let leq = lep @ ltp in
- let tryall d =
- let e = multidegree pol in
- let k = if e = 0 then 0 else d / e in
- let eq' = map fst eq in
- tryfind (fun i -> d,i,real_positivnullstellensatz_general false d eq' leq
- (poly_neg(poly_pow pol i)))
- (0--k) in
- let d,i,(cert_ideal,cert_cone) = deepen tryall 0 in
- let proofs_ideal =
- map2 (fun q (p,ax) -> Eqmul(term_of_poly q,ax)) cert_ideal eq
- and proofs_cone = map term_of_sos cert_cone
- and proof_ne =
- if ltp = [] then Rational_lt num_1 else
- let p = end_itlist (fun s t -> Product(s,t)) (map snd ltp) in
- funpow i (fun q -> Product(p,q)) (Rational_lt num_1) in
- let proof = end_itlist (fun s t -> Sum(s,t))
- (proof_ne :: proofs_ideal @ proofs_cone) in
- print_string("Translating proof certificate to HOL");
- print_newline();
- translator (eqs,les,lts) proof;;
-*)
-(* ------------------------------------------------------------------------- *)
-(* A wrapper that tries to substitute away variables first. *)
-(* ------------------------------------------------------------------------- *)
-(*
-let REAL_NONLINEAR_SUBST_PROVER =
- let zero = `&0:real`
- and mul_tm = `( * ):real->real->real`
- and shuffle1 =
- CONV_RULE(REWR_CONV(REAL_ARITH `a + x = (y:real) <=> x = y - a`))
- and shuffle2 =
- CONV_RULE(REWR_CONV(REAL_ARITH `x + a = (y:real) <=> x = y - a`)) in
- let rec substitutable_monomial fvs tm =
- match tm with
- Var(_,Tyapp("real",[])) when not (mem tm fvs) -> Int 1,tm
- | Comb(Comb(Const("real_mul",_),c),(Var(_,_) as t))
- when is_ratconst c && not (mem t fvs)
- -> rat_of_term c,t
- | Comb(Comb(Const("real_add",_),s),t) ->
- (try substitutable_monomial (union (frees t) fvs) s
- with Failure _ -> substitutable_monomial (union (frees s) fvs) t)
- | _ -> failwith "substitutable_monomial"
- and isolate_variable v th =
- match lhs(concl th) with
- x when x = v -> th
- | Comb(Comb(Const("real_add",_),(Var(_,Tyapp("real",[])) as x)),t)
- when x = v -> shuffle2 th
- | Comb(Comb(Const("real_add",_),s),t) ->
- isolate_variable v(shuffle1 th) in
- let make_substitution th =
- let (c,v) = substitutable_monomial [] (lhs(concl th)) in
- let th1 = AP_TERM (mk_comb(mul_tm,term_of_rat(Int 1 // c))) th in
- let th2 = CONV_RULE(BINOP_CONV REAL_POLY_MUL_CONV) th1 in
- CONV_RULE (RAND_CONV REAL_POLY_CONV) (isolate_variable v th2) in
- fun translator ->
- let rec substfirst(eqs,les,lts) =
- try let eth = tryfind make_substitution eqs in
- let modify =
- CONV_RULE(LAND_CONV(SUBS_CONV[eth] THENC REAL_POLY_CONV)) in
- substfirst(filter (fun t -> lhand(concl t) <> zero) (map modify eqs),
- map modify les,map modify lts)
- with Failure _ -> REAL_NONLINEAR_PROVER translator (eqs,les,lts) in
- substfirst;;
-*)
-(* ------------------------------------------------------------------------- *)
-(* Overall function. *)
-(* ------------------------------------------------------------------------- *)
-(*
-let REAL_SOS =
- let init = GEN_REWRITE_CONV ONCE_DEPTH_CONV [DECIMAL]
- and pure = GEN_REAL_ARITH REAL_NONLINEAR_SUBST_PROVER in
- fun tm -> let th = init tm in EQ_MP (SYM th) (pure(rand(concl th)));;
-*)
-(* ------------------------------------------------------------------------- *)
-(* Add hacks for division. *)
-(* ------------------------------------------------------------------------- *)
-(*
-let REAL_SOSFIELD =
- let inv_tm = `inv:real->real` in
- let prenex_conv =
- TOP_DEPTH_CONV BETA_CONV THENC
- PURE_REWRITE_CONV[FORALL_SIMP; EXISTS_SIMP; real_div;
- REAL_INV_INV; REAL_INV_MUL; GSYM REAL_POW_INV] THENC
- NNFC_CONV THENC DEPTH_BINOP_CONV `(/\)` CONDS_CELIM_CONV THENC
- PRENEX_CONV
- and setup_conv = NNF_CONV THENC WEAK_CNF_CONV THENC CONJ_CANON_CONV
- and core_rule t =
- try REAL_ARITH t
- with Failure _ -> try REAL_RING t
- with Failure _ -> REAL_SOS t
- and is_inv =
- let is_div = is_binop `(/):real->real->real` in
- fun tm -> (is_div tm or (is_comb tm && rator tm = inv_tm)) &&
- not(is_ratconst(rand tm)) in
- let BASIC_REAL_FIELD tm =
- let is_freeinv t = is_inv t && free_in t tm in
- let itms = setify(map rand (find_terms is_freeinv tm)) in
- let hyps = map (fun t -> SPEC t REAL_MUL_RINV) itms in
- let tm' = itlist (fun th t -> mk_imp(concl th,t)) hyps tm in
- let itms' = map (curry mk_comb inv_tm) itms in
- let gvs = map (genvar o type_of) itms' in
- let tm'' = subst (zip gvs itms') tm' in
- let th1 = setup_conv tm'' in
- let cjs = conjuncts(rand(concl th1)) in
- let ths = map core_rule cjs in
- let th2 = EQ_MP (SYM th1) (end_itlist CONJ ths) in
- rev_itlist (C MP) hyps (INST (zip itms' gvs) th2) in
- fun tm ->
- let th0 = prenex_conv tm in
- let tm0 = rand(concl th0) in
- let avs,bod = strip_forall tm0 in
- let th1 = setup_conv bod in
- let ths = map BASIC_REAL_FIELD (conjuncts(rand(concl th1))) in
- EQ_MP (SYM th0) (GENL avs (EQ_MP (SYM th1) (end_itlist CONJ ths)));;
-*)
-(* ------------------------------------------------------------------------- *)
-(* Integer version. *)
-(* ------------------------------------------------------------------------- *)
-(*
-let INT_SOS =
- let atom_CONV =
- let pth = prove
- (`(~(x <= y) <=> y + &1 <= x:int) /\
- (~(x < y) <=> y <= x) /\
- (~(x = y) <=> x + &1 <= y \/ y + &1 <= x) /\
- (x < y <=> x + &1 <= y)`,
- REWRITE_TAC[INT_NOT_LE; INT_NOT_LT; INT_NOT_EQ; INT_LT_DISCRETE]) in
- GEN_REWRITE_CONV I [pth]
- and bub_CONV = GEN_REWRITE_CONV TOP_SWEEP_CONV
- [int_eq; int_le; int_lt; int_ge; int_gt;
- int_of_num_th; int_neg_th; int_add_th; int_mul_th;
- int_sub_th; int_pow_th; int_abs_th; int_max_th; int_min_th] in
- let base_CONV = TRY_CONV atom_CONV THENC bub_CONV in
- let NNF_NORM_CONV = GEN_NNF_CONV false
- (base_CONV,fun t -> base_CONV t,base_CONV(mk_neg t)) in
- let init_CONV =
- GEN_REWRITE_CONV DEPTH_CONV [FORALL_SIMP; EXISTS_SIMP] THENC
- GEN_REWRITE_CONV DEPTH_CONV [INT_GT; INT_GE] THENC
- CONDS_ELIM_CONV THENC NNF_NORM_CONV in
- let p_tm = `p:bool`
- and not_tm = `(~)` in
- let pth = TAUT(mk_eq(mk_neg(mk_neg p_tm),p_tm)) in
- fun tm ->
- let th0 = INST [tm,p_tm] pth
- and th1 = NNF_NORM_CONV(mk_neg tm) in
- let th2 = REAL_SOS(mk_neg(rand(concl th1))) in
- EQ_MP th0 (EQ_MP (AP_TERM not_tm (SYM th1)) th2);;
-*)
-(* ------------------------------------------------------------------------- *)
-(* Natural number version. *)
-(* ------------------------------------------------------------------------- *)
-(*
-let SOS_RULE tm =
- let avs = frees tm in
- let tm' = list_mk_forall(avs,tm) in
- let th1 = NUM_TO_INT_CONV tm' in
- let th2 = INT_SOS (rand(concl th1)) in
- SPECL avs (EQ_MP (SYM th1) th2);;
-*)
-(* ------------------------------------------------------------------------- *)
-(* Now pure SOS stuff. *)
-(* ------------------------------------------------------------------------- *)
-
-(*prioritize_real();;*)
-
-(* ------------------------------------------------------------------------- *)
(* Some combinatorial helper functions. *)
(* ------------------------------------------------------------------------- *)
let rec allpermutations l =
if l = [] then [[]] else
- itlist (fun h acc -> List.map (fun t -> h::t)
+ List.fold_right (fun h acc -> List.map (fun t -> h::t)
(allpermutations (subtract l [h])) @ acc) l [];;
let changevariables_monomial zoln (m:monomial) =
@@ -1165,14 +975,14 @@ let changevariables zoln pol =
let sdpa_of_vector (v:vector) =
let n = dim v in
let strs = List.map (o (decimalize 20) (element v)) (1--n) in
- end_itlist (fun x y -> x ^ " " ^ y) strs ^ "\n";;
+ String.concat " " strs ^ "\n";;
let sdpa_of_matrix k (m:matrix) =
let pfx = string_of_int k ^ " 1 " in
let ms = foldr (fun (i,j) c a -> if i > j then a else ((i,j),c)::a)
(snd m) [] in
let mss = sort (increasing fst) ms in
- itlist (fun ((i,j),c) a ->
+ List.fold_right (fun ((i,j),c) a ->
pfx ^ string_of_int i ^ " " ^ string_of_int j ^
" " ^ decimalize 20 c ^ "\n" ^ a) mss "";;
@@ -1184,7 +994,7 @@ let sdpa_of_problem comment obj mats =
"1\n" ^
string_of_int n ^ "\n" ^
sdpa_of_vector obj ^
- itlist2 (fun k m a -> sdpa_of_matrix (k - 1) m ^ a)
+ List.fold_right2 (fun k m a -> sdpa_of_matrix (k - 1) m ^ a)
(1--List.length mats) mats "";;
let run_csdp dbg obj mats =
@@ -1224,9 +1034,9 @@ let sumofsquares_general_symmetry tool pol =
let sym_eqs =
let invariants = List.filter
(fun vars' ->
- is_undefined(poly_sub pol (changevariables (zip vars vars') pol)))
+ is_undefined(poly_sub pol (changevariables (List.combine vars vars') pol)))
(allpermutations vars) in
- let lpns = zip lpps (1--List.length lpps) in
+ let lpns = List.combine lpps (1--List.length lpps) in
let lppcs =
List.filter (fun (m,(n1,n2)) -> n1 <= n2)
(allpairs
@@ -1234,8 +1044,8 @@ let sumofsquares_general_symmetry tool pol =
let clppcs = end_itlist (@)
(List.map (fun ((m1,m2),(n1,n2)) ->
List.map (fun vars' ->
- (changevariables_monomial (zip vars vars') m1,
- changevariables_monomial (zip vars vars') m2),(n1,n2))
+ (changevariables_monomial (List.combine vars vars') m1,
+ changevariables_monomial (List.combine vars vars') m2),(n1,n2))
invariants)
lppcs) in
let clppcs_dom = setify(List.map fst clppcs) in
@@ -1247,7 +1057,7 @@ let sumofsquares_general_symmetry tool pol =
[] -> raise Sanity
| [h] -> acc
| h::t -> List.map (fun k -> (k |-> Int(-1)) (h |=> Int 1)) t @ acc in
- itlist mk_eq eqvcls [] in
+ List.fold_right mk_eq eqvcls [] in
let eqs = foldl (fun a x y -> y::a) []
(itern 1 lpps (fun m1 n1 ->
itern 1 lpps (fun m2 n2 f ->
@@ -1259,7 +1069,7 @@ let sumofsquares_general_symmetry tool pol =
undefined pol)) @
sym_eqs in
let pvs,assig = eliminate_all_equations (0,0) eqs in
- let allassig = itlist (fun v -> (v |-> (v |=> Int 1))) pvs assig in
+ let allassig = List.fold_right (fun v -> (v |-> (v |=> Int 1))) pvs assig in
let qvars = (0,0)::pvs in
let diagents =
end_itlist equation_add (List.map (fun i -> apply allassig (i,i)) (1--n)) in
@@ -1281,18 +1091,18 @@ let sumofsquares_general_symmetry tool pol =
else ());
let vec = nice_vector d raw_vec in
let mat = iter (1,dim vec)
- (fun i a -> matrix_add (matrix_cmul (element vec i) (el i mats)) a)
- (matrix_neg (el 0 mats)) in
+ (fun i a -> matrix_add (matrix_cmul (element vec i) (List.nth mats i)) a)
+ (matrix_neg (List.nth mats 0)) in
deration(diag mat) in
let rat,dia =
if pvs = [] then
- let mat = matrix_neg (el 0 mats) in
+ let mat = matrix_neg (List.nth mats 0) in
deration(diag mat)
else
tryfind find_rounding (List.map Num.num_of_int (1--31) @
List.map pow2 (5--66)) in
let poly_of_lin(d,v) =
- d,foldl(fun a i c -> (el (i - 1) lpps |-> c) a) undefined (snd v) in
+ d,foldl(fun a i c -> (List.nth lpps (i - 1) |-> c) a) undefined (snd v) in
let lins = List.map poly_of_lin dia in
let sqs = List.map (fun (d,l) -> poly_mul (poly_const d) (poly_pow l 2)) lins in
let sos = poly_cmul rat (end_itlist poly_add sqs) in
@@ -1300,325 +1110,3 @@ let sumofsquares_general_symmetry tool pol =
let sumofsquares = sumofsquares_general_symmetry csdp;;
-(* ------------------------------------------------------------------------- *)
-(* Pure HOL SOS conversion. *)
-(* ------------------------------------------------------------------------- *)
-(*
-let SOS_CONV =
- let mk_square =
- let pow_tm = `(pow)` and two_tm = `2` in
- fun tm -> mk_comb(mk_comb(pow_tm,tm),two_tm)
- and mk_prod = mk_binop `( * )`
- and mk_sum = mk_binop `(+)` in
- fun tm ->
- let k,sos = sumofsquares(poly_of_term tm) in
- let mk_sqtm(c,p) =
- mk_prod (term_of_rat(k */ c)) (mk_square(term_of_poly p)) in
- let tm' = end_itlist mk_sum (map mk_sqtm sos) in
- let th = REAL_POLY_CONV tm and th' = REAL_POLY_CONV tm' in
- TRANS th (SYM th');;
-*)
-(* ------------------------------------------------------------------------- *)
-(* Attempt to prove &0 <= x by direct SOS decomposition. *)
-(* ------------------------------------------------------------------------- *)
-(*
-let PURE_SOS_TAC =
- let tac =
- MATCH_ACCEPT_TAC(REWRITE_RULE[GSYM REAL_POW_2] REAL_LE_SQUARE) ORELSE
- MATCH_ACCEPT_TAC REAL_LE_SQUARE ORELSE
- (MATCH_MP_TAC REAL_LE_ADD THEN CONJ_TAC) ORELSE
- (MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC) ORELSE
- CONV_TAC(RAND_CONV REAL_RAT_REDUCE_CONV THENC REAL_RAT_LE_CONV) in
- REPEAT GEN_TAC THEN REWRITE_TAC[real_ge] THEN
- GEN_REWRITE_TAC I [GSYM REAL_SUB_LE] THEN
- CONV_TAC(RAND_CONV SOS_CONV) THEN
- REPEAT tac THEN NO_TAC;;
-
-let PURE_SOS tm = prove(tm,PURE_SOS_TAC);;
-*)
-(* ------------------------------------------------------------------------- *)
-(* Examples. *)
-(* ------------------------------------------------------------------------- *)
-
-(*****
-
-time REAL_SOS
- `a1 >= &0 /\ a2 >= &0 /\
- (a1 * a1 + a2 * a2 = b1 * b1 + b2 * b2 + &2) /\
- (a1 * b1 + a2 * b2 = &0)
- ==> a1 * a2 - b1 * b2 >= &0`;;
-
-time REAL_SOS `&3 * x + &7 * a < &4 /\ &3 < &2 * x ==> a < &0`;;
-
-time REAL_SOS
- `b pow 2 < &4 * a * c ==> ~(a * x pow 2 + b * x + c = &0)`;;
-
-time REAL_SOS
- `(a * x pow 2 + b * x + c = &0) ==> b pow 2 >= &4 * a * c`;;
-
-time REAL_SOS
- `&0 <= x /\ x <= &1 /\ &0 <= y /\ y <= &1
- ==> x pow 2 + y pow 2 < &1 \/
- (x - &1) pow 2 + y pow 2 < &1 \/
- x pow 2 + (y - &1) pow 2 < &1 \/
- (x - &1) pow 2 + (y - &1) pow 2 < &1`;;
-
-time REAL_SOS
- `&0 <= b /\ &0 <= c /\ &0 <= x /\ &0 <= y /\
- (x pow 2 = c) /\ (y pow 2 = a pow 2 * c + b)
- ==> a * c <= y * x`;;
-
-time REAL_SOS
- `&0 <= x /\ &0 <= y /\ &0 <= z /\ x + y + z <= &3
- ==> x * y + x * z + y * z >= &3 * x * y * z`;;
-
-time REAL_SOS
- `(x pow 2 + y pow 2 + z pow 2 = &1) ==> (x + y + z) pow 2 <= &3`;;
-
-time REAL_SOS
- `(w pow 2 + x pow 2 + y pow 2 + z pow 2 = &1)
- ==> (w + x + y + z) pow 2 <= &4`;;
-
-time REAL_SOS
- `x >= &1 /\ y >= &1 ==> x * y >= x + y - &1`;;
-
-time REAL_SOS
- `x > &1 /\ y > &1 ==> x * y > x + y - &1`;;
-
-time REAL_SOS
- `abs(x) <= &1
- ==> abs(&64 * x pow 7 - &112 * x pow 5 + &56 * x pow 3 - &7 * x) <= &1`;;
-
-time REAL_SOS
- `abs(x - z) <= e /\ abs(y - z) <= e /\ &0 <= u /\ &0 <= v /\ (u + v = &1)
- ==> abs((u * x + v * y) - z) <= e`;;
-
-(* ------------------------------------------------------------------------- *)
-(* One component of denominator in dodecahedral example. *)
-(* ------------------------------------------------------------------------- *)
-
-time REAL_SOS
- `&2 <= x /\ x <= &125841 / &50000 /\
- &2 <= y /\ y <= &125841 / &50000 /\
- &2 <= z /\ z <= &125841 / &50000
- ==> &2 * (x * z + x * y + y * z) - (x * x + y * y + z * z) >= &0`;;
-
-(* ------------------------------------------------------------------------- *)
-(* Over a larger but simpler interval. *)
-(* ------------------------------------------------------------------------- *)
-
-time REAL_SOS
- `&2 <= x /\ x <= &4 /\ &2 <= y /\ y <= &4 /\ &2 <= z /\ z <= &4
- ==> &0 <= &2 * (x * z + x * y + y * z) - (x * x + y * y + z * z)`;;
-
-(* ------------------------------------------------------------------------- *)
-(* We can do 12. I think 12 is a sharp bound; see PP's certificate. *)
-(* ------------------------------------------------------------------------- *)
-
-time REAL_SOS
- `&2 <= x /\ x <= &4 /\ &2 <= y /\ y <= &4 /\ &2 <= z /\ z <= &4
- ==> &12 <= &2 * (x * z + x * y + y * z) - (x * x + y * y + z * z)`;;
-
-(* ------------------------------------------------------------------------- *)
-(* Gloptipoly example. *)
-(* ------------------------------------------------------------------------- *)
-
-(*** This works but normalization takes minutes
-
-time REAL_SOS
- `(x - y - &2 * x pow 4 = &0) /\ &0 <= x /\ x <= &2 /\ &0 <= y /\ y <= &3
- ==> y pow 2 - &7 * y - &12 * x + &17 >= &0`;;
-
- ***)
-
-(* ------------------------------------------------------------------------- *)
-(* Inequality from sci.math (see "Leon-Sotelo, por favor"). *)
-(* ------------------------------------------------------------------------- *)
-
-time REAL_SOS
- `&0 <= x /\ &0 <= y /\ (x * y = &1)
- ==> x + y <= x pow 2 + y pow 2`;;
-
-time REAL_SOS
- `&0 <= x /\ &0 <= y /\ (x * y = &1)
- ==> x * y * (x + y) <= x pow 2 + y pow 2`;;
-
-time REAL_SOS
- `&0 <= x /\ &0 <= y ==> x * y * (x + y) pow 2 <= (x pow 2 + y pow 2) pow 2`;;
-
-(* ------------------------------------------------------------------------- *)
-(* Some examples over integers and natural numbers. *)
-(* ------------------------------------------------------------------------- *)
-
-time SOS_RULE `!m n. 2 * m + n = (n + m) + m`;;
-time SOS_RULE `!n. ~(n = 0) ==> (0 MOD n = 0)`;;
-time SOS_RULE `!m n. m < n ==> (m DIV n = 0)`;;
-time SOS_RULE `!n:num. n <= n * n`;;
-time SOS_RULE `!m n. n * (m DIV n) <= m`;;
-time SOS_RULE `!n. ~(n = 0) ==> (0 DIV n = 0)`;;
-time SOS_RULE `!m n p. ~(p = 0) /\ m <= n ==> m DIV p <= n DIV p`;;
-time SOS_RULE `!a b n. ~(a = 0) ==> (n <= b DIV a <=> a * n <= b)`;;
-
-(* ------------------------------------------------------------------------- *)
-(* This is particularly gratifying --- cf hideous manual proof in arith.ml *)
-(* ------------------------------------------------------------------------- *)
-
-(*** This doesn't now seem to work as well as it did; what changed?
-
-time SOS_RULE
- `!a b c d. ~(b = 0) /\ b * c < (a + 1) * d ==> c DIV d <= a DIV b`;;
-
- ***)
-
-(* ------------------------------------------------------------------------- *)
-(* Key lemma for injectivity of Cantor-type pairing functions. *)
-(* ------------------------------------------------------------------------- *)
-
-time SOS_RULE
- `!x1 y1 x2 y2. ((x1 + y1) EXP 2 + x1 + 1 = (x2 + y2) EXP 2 + x2 + 1)
- ==> (x1 + y1 = x2 + y2)`;;
-
-time SOS_RULE
- `!x1 y1 x2 y2. ((x1 + y1) EXP 2 + x1 + 1 = (x2 + y2) EXP 2 + x2 + 1) /\
- (x1 + y1 = x2 + y2)
- ==> (x1 = x2) /\ (y1 = y2)`;;
-
-time SOS_RULE
- `!x1 y1 x2 y2.
- (((x1 + y1) EXP 2 + 3 * x1 + y1) DIV 2 =
- ((x2 + y2) EXP 2 + 3 * x2 + y2) DIV 2)
- ==> (x1 + y1 = x2 + y2)`;;
-
-time SOS_RULE
- `!x1 y1 x2 y2.
- (((x1 + y1) EXP 2 + 3 * x1 + y1) DIV 2 =
- ((x2 + y2) EXP 2 + 3 * x2 + y2) DIV 2) /\
- (x1 + y1 = x2 + y2)
- ==> (x1 = x2) /\ (y1 = y2)`;;
-
-(* ------------------------------------------------------------------------- *)
-(* Reciprocal multiplication (actually just ARITH_RULE does these). *)
-(* ------------------------------------------------------------------------- *)
-
-time SOS_RULE `x <= 127 ==> ((86 * x) DIV 256 = x DIV 3)`;;
-
-time SOS_RULE `x < 2 EXP 16 ==> ((104858 * x) DIV (2 EXP 20) = x DIV 10)`;;
-
-(* ------------------------------------------------------------------------- *)
-(* This is more impressive since it's really nonlinear. See REMAINDER_DECODE *)
-(* ------------------------------------------------------------------------- *)
-
-time SOS_RULE `0 < m /\ m < n ==> ((m * ((n * x) DIV m + 1)) DIV n = x)`;;
-
-(* ------------------------------------------------------------------------- *)
-(* Some conversion examples. *)
-(* ------------------------------------------------------------------------- *)
-
-time SOS_CONV
- `&2 * x pow 4 + &2 * x pow 3 * y - x pow 2 * y pow 2 + &5 * y pow 4`;;
-
-time SOS_CONV
- `x pow 4 - (&2 * y * z + &1) * x pow 2 +
- (y pow 2 * z pow 2 + &2 * y * z + &2)`;;
-
-time SOS_CONV `&4 * x pow 4 +
- &4 * x pow 3 * y - &7 * x pow 2 * y pow 2 - &2 * x * y pow 3 +
- &10 * y pow 4`;;
-
-time SOS_CONV `&4 * x pow 4 * y pow 6 + x pow 2 - x * y pow 2 + y pow 2`;;
-
-time SOS_CONV
- `&4096 * (x pow 4 + x pow 2 + z pow 6 - &3 * x pow 2 * z pow 2) + &729`;;
-
-time SOS_CONV
- `&120 * x pow 2 - &63 * x pow 4 + &10 * x pow 6 +
- &30 * x * y - &120 * y pow 2 + &120 * y pow 4 + &31`;;
-
-time SOS_CONV
- `&9 * x pow 2 * y pow 4 + &9 * x pow 2 * z pow 4 + &36 * x pow 2 * y pow 3 +
- &36 * x pow 2 * y pow 2 - &48 * x * y * z pow 2 + &4 * y pow 4 +
- &4 * z pow 4 - &16 * y pow 3 + &16 * y pow 2`;;
-
-time SOS_CONV
- `(x pow 2 + y pow 2 + z pow 2) *
- (x pow 4 * y pow 2 + x pow 2 * y pow 4 +
- z pow 6 - &3 * x pow 2 * y pow 2 * z pow 2)`;;
-
-time SOS_CONV
- `x pow 4 + y pow 4 + z pow 4 - &4 * x * y * z + x + y + z + &3`;;
-
-(*** I think this will work, but normalization is slow
-
-time SOS_CONV
- `&100 * (x pow 4 + y pow 4 + z pow 4 - &4 * x * y * z + x + y + z) + &212`;;
-
- ***)
-
-time SOS_CONV
- `&100 * ((&2 * x - &2) pow 2 + (x pow 3 - &8 * x - &2) pow 2) - &588`;;
-
-time SOS_CONV
- `x pow 2 * (&120 - &63 * x pow 2 + &10 * x pow 4) + &30 * x * y +
- &30 * y pow 2 * (&4 * y pow 2 - &4) + &31`;;
-
-(* ------------------------------------------------------------------------- *)
-(* Example of basic rule. *)
-(* ------------------------------------------------------------------------- *)
-
-time PURE_SOS
- `!x. x pow 4 + y pow 4 + z pow 4 - &4 * x * y * z + x + y + z + &3
- >= &1 / &7`;;
-
-time PURE_SOS
- `&0 <= &98 * x pow 12 +
- -- &980 * x pow 10 +
- &3038 * x pow 8 +
- -- &2968 * x pow 6 +
- &1022 * x pow 4 +
- -- &84 * x pow 2 +
- &2`;;
-
-time PURE_SOS
- `!x. &0 <= &2 * x pow 14 +
- -- &84 * x pow 12 +
- &1022 * x pow 10 +
- -- &2968 * x pow 8 +
- &3038 * x pow 6 +
- -- &980 * x pow 4 +
- &98 * x pow 2`;;
-
-(* ------------------------------------------------------------------------- *)
-(* From Zeng et al, JSC vol 37 (2004), p83-99. *)
-(* All of them work nicely with pure SOS_CONV, except (maybe) the one noted. *)
-(* ------------------------------------------------------------------------- *)
-
-PURE_SOS
- `x pow 6 + y pow 6 + z pow 6 - &3 * x pow 2 * y pow 2 * z pow 2 >= &0`;;
-
-PURE_SOS `x pow 4 + y pow 4 + z pow 4 + &1 - &4*x*y*z >= &0`;;
-
-PURE_SOS `x pow 4 + &2*x pow 2*z + x pow 2 - &2*x*y*z + &2*y pow 2*z pow 2 +
-&2*y*z pow 2 + &2*z pow 2 - &2*x + &2* y*z + &1 >= &0`;;
-
-(**** This is harder. Interestingly, this fails the pure SOS test, it seems.
- Yet only on rounding(!?) Poor Newton polytope optimization or something?
- But REAL_SOS does finally converge on the second run at level 12!
-
-REAL_SOS
-`x pow 4*y pow 4 - &2*x pow 5*y pow 3*z pow 2 + x pow 6*y pow 2*z pow 4 + &2*x
-pow 2*y pow 3*z - &4* x pow 3*y pow 2*z pow 3 + &2*x pow 4*y*z pow 5 + z pow
-2*y pow 2 - &2*z pow 4*y*x + z pow 6*x pow 2 >= &0`;;
-
- ****)
-
-PURE_SOS
-`x pow 4 + &4*x pow 2*y pow 2 + &2*x*y*z pow 2 + &2*x*y*w pow 2 + y pow 4 + z
-pow 4 + w pow 4 + &2*z pow 2*w pow 2 + &2*x pow 2*w + &2*y pow 2*w + &2*x*y +
-&3*w pow 2 + &2*z pow 2 + &1 >= &0`;;
-
-PURE_SOS
-`w pow 6 + &2*z pow 2*w pow 3 + x pow 4 + y pow 4 + z pow 4 + &2*x pow 2*w +
-&2*x pow 2*z + &3*x pow 2 + w pow 2 + &2*z*w + z pow 2 + &2*z + &2*w + &1 >=
-&0`;;
-
-*****)
diff --git a/plugins/micromega/sos_lib.ml b/plugins/micromega/sos_lib.ml
index 6b8b820a..6aebc4ca 100644
--- a/plugins/micromega/sos_lib.ml
+++ b/plugins/micromega/sos_lib.ml
@@ -9,8 +9,6 @@
open Num
-let debugging = ref false;;
-
(* ------------------------------------------------------------------------- *)
(* Comparisons that are reflexive on NaN and also short-circuiting. *)
(* ------------------------------------------------------------------------- *)
@@ -21,7 +19,6 @@ let (=?) = fun x y -> cmp x y = 0;;
let (<?) = fun x y -> cmp x y < 0;;
let (<=?) = fun x y -> cmp x y <= 0;;
let (>?) = fun x y -> cmp x y > 0;;
-let (>=?) = fun x y -> cmp x y >= 0;;
(* ------------------------------------------------------------------------- *)
(* Combinators. *)
@@ -59,48 +56,29 @@ let lcm_num x y =
(* ------------------------------------------------------------------------- *)
-(* List basics. *)
-(* ------------------------------------------------------------------------- *)
-
-let rec el n l =
- if n = 0 then List.hd l else el (n - 1) (List.tl l);;
-
-
-(* ------------------------------------------------------------------------- *)
(* Various versions of list iteration. *)
(* ------------------------------------------------------------------------- *)
-let rec itlist f l b =
- match l with
- [] -> b
- | (h::t) -> f h (itlist f t b);;
-
let rec end_itlist f l =
match l with
[] -> failwith "end_itlist"
| [x] -> x
| (h::t) -> f h (end_itlist f t);;
-let rec itlist2 f l1 l2 b =
- match (l1,l2) with
- ([],[]) -> b
- | (h1::t1,h2::t2) -> f h1 h2 (itlist2 f t1 t2 b)
- | _ -> failwith "itlist2";;
-
(* ------------------------------------------------------------------------- *)
(* All pairs arising from applying a function over two lists. *)
(* ------------------------------------------------------------------------- *)
let rec allpairs f l1 l2 =
match l1 with
- h1::t1 -> itlist (fun x a -> f h1 x :: a) l2 (allpairs f t1 l2)
+ h1::t1 -> List.fold_right (fun x a -> f h1 x :: a) l2 (allpairs f t1 l2)
| [] -> [];;
(* ------------------------------------------------------------------------- *)
(* String operations (surely there is a better way...) *)
(* ------------------------------------------------------------------------- *)
-let implode l = itlist (^) l "";;
+let implode l = List.fold_right (^) l "";;
let explode s =
let rec exap n l =
@@ -110,13 +88,6 @@ let explode s =
(* ------------------------------------------------------------------------- *)
-(* Attempting function or predicate applications. *)
-(* ------------------------------------------------------------------------- *)
-
-let can f x = try (f x; true) with Failure _ -> false;;
-
-
-(* ------------------------------------------------------------------------- *)
(* Repetition of a function. *)
(* ------------------------------------------------------------------------- *)
@@ -126,36 +97,20 @@ let rec funpow n f x =
(* ------------------------------------------------------------------------- *)
-(* Replication and sequences. *)
+(* Sequences. *)
(* ------------------------------------------------------------------------- *)
-let rec replicate x n =
- if n < 1 then []
- else x::(replicate x (n - 1));;
-
let rec (--) = fun m n -> if m > n then [] else m::((m + 1) -- n);;
(* ------------------------------------------------------------------------- *)
(* Various useful list operations. *)
(* ------------------------------------------------------------------------- *)
-let rec forall p l =
- match l with
- [] -> true
- | h::t -> p(h) && forall p t;;
-
let rec tryfind f l =
match l with
[] -> failwith "tryfind"
| (h::t) -> try f h with Failure _ -> tryfind f t;;
-let index x =
- let rec ind n l =
- match l with
- [] -> failwith "index"
- | (h::t) -> if x =? h then n else ind (n + 1) t in
- ind 0;;
-
(* ------------------------------------------------------------------------- *)
(* "Set" operations on lists. *)
(* ------------------------------------------------------------------------- *)
@@ -168,46 +123,16 @@ let rec mem x lis =
let insert x l =
if mem x l then l else x::l;;
-let union l1 l2 = itlist insert l1 l2;;
+let union l1 l2 = List.fold_right insert l1 l2;;
let subtract l1 l2 = List.filter (fun x -> not (mem x l2)) l1;;
(* ------------------------------------------------------------------------- *)
-(* Merging and bottom-up mergesort. *)
-(* ------------------------------------------------------------------------- *)
-
-let rec merge ord l1 l2 =
- match l1 with
- [] -> l2
- | h1::t1 -> match l2 with
- [] -> l1
- | h2::t2 -> if ord h1 h2 then h1::(merge ord t1 l2)
- else h2::(merge ord l1 t2);;
-
-
-(* ------------------------------------------------------------------------- *)
(* Common measure predicates to use with "sort". *)
(* ------------------------------------------------------------------------- *)
let increasing f x y = f x <? f y;;
-let decreasing f x y = f x >? f y;;
-
-(* ------------------------------------------------------------------------- *)
-(* Zipping, unzipping etc. *)
-(* ------------------------------------------------------------------------- *)
-
-let rec zip l1 l2 =
- match (l1,l2) with
- ([],[]) -> []
- | (h1::t1,h2::t2) -> (h1,h2)::(zip t1 t2)
- | _ -> failwith "zip";;
-
-let rec unzip =
- function [] -> [],[]
- | ((a,b)::rest) -> let alist,blist = unzip rest in
- (a::alist,b::blist);;
-
(* ------------------------------------------------------------------------- *)
(* Iterating functions over lists. *)
(* ------------------------------------------------------------------------- *)
@@ -443,8 +368,6 @@ let apply f = applyd f (fun x -> failwith "apply");;
let tryapplyd f a d = applyd f (fun x -> d) a;;
-let defined f x = try apply f x; true with Failure _ -> false;;
-
(* ------------------------------------------------------------------------- *)
(* Undefinition. *)
(* ------------------------------------------------------------------------- *)
@@ -490,8 +413,6 @@ let graph f = setify (foldl (fun a x y -> (x,y)::a) [] f);;
let dom f = setify(foldl (fun a x y -> x::a) [] f);;
-let ran f = setify(foldl (fun a x y -> y::a) [] f);;
-
(* ------------------------------------------------------------------------- *)
(* More parser basics. *)
(* ------------------------------------------------------------------------- *)
@@ -499,7 +420,7 @@ let ran f = setify(foldl (fun a x y -> y::a) [] f);;
exception Noparse;;
-let isspace,issep,isbra,issymb,isalpha,isnum,isalnum =
+let isspace,isnum =
let charcode s = Char.code(String.get s 0) in
let spaces = " \t\n\r"
and separators = ",;"
@@ -508,7 +429,7 @@ let isspace,issep,isbra,issymb,isalpha,isnum,isalnum =
and alphas = "'abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ"
and nums = "0123456789" in
let allchars = spaces^separators^brackets^symbs^alphas^nums in
- let csetsize = itlist ((o) max charcode) (explode allchars) 256 in
+ let csetsize = List.fold_right ((o) max charcode) (explode allchars) 256 in
let ctable = Array.make csetsize 0 in
do_list (fun c -> Array.set ctable (charcode c) 1) (explode spaces);
do_list (fun c -> Array.set ctable (charcode c) 2) (explode separators);
@@ -517,13 +438,8 @@ let isspace,issep,isbra,issymb,isalpha,isnum,isalnum =
do_list (fun c -> Array.set ctable (charcode c) 16) (explode alphas);
do_list (fun c -> Array.set ctable (charcode c) 32) (explode nums);
let isspace c = Array.get ctable (charcode c) = 1
- and issep c = Array.get ctable (charcode c) = 2
- and isbra c = Array.get ctable (charcode c) = 4
- and issymb c = Array.get ctable (charcode c) = 8
- and isalpha c = Array.get ctable (charcode c) = 16
- and isnum c = Array.get ctable (charcode c) = 32
- and isalnum c = Array.get ctable (charcode c) >= 16 in
- isspace,issep,isbra,issymb,isalpha,isnum,isalnum;;
+ and isnum c = Array.get ctable (charcode c) = 32 in
+ isspace,isnum;;
let parser_or parser1 parser2 input =
try parser1 input
@@ -566,9 +482,6 @@ let rec atleast n prs i =
(if n <= 0 then many prs
else prs ++ atleast (n - 1) prs >> (fun (h,t) -> h::t)) i;;
-let finished input =
- if input = [] then 0,input else failwith "Unparsed input";;
-
(* ------------------------------------------------------------------------- *)
let temp_path = Filename.get_temp_dir_name ();;
@@ -589,7 +502,7 @@ let strings_of_file filename =
(Pervasives.close_in fd; data);;
let string_of_file filename =
- end_itlist (fun s t -> s^"\n"^t) (strings_of_file filename);;
+ String.concat "\n" (strings_of_file filename);;
let file_of_string filename s =
let fd = Pervasives.open_out filename in
diff --git a/plugins/micromega/sos_lib.mli b/plugins/micromega/sos_lib.mli
new file mode 100644
index 00000000..8b53b815
--- /dev/null
+++ b/plugins/micromega/sos_lib.mli
@@ -0,0 +1,79 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+val o : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b
+
+val num_1 : Num.num
+val pow10 : int -> Num.num
+val pow2 : int -> Num.num
+
+val implode : string list -> string
+val explode : string -> string list
+
+val funpow : int -> ('a -> 'a) -> 'a -> 'a
+val tryfind : ('a -> 'b) -> 'a list -> 'b
+
+type ('a,'b) func =
+ | Empty
+ | Leaf of int * ('a*'b) list
+ | Branch of int * int * ('a,'b) func * ('a,'b) func
+
+val undefined : ('a, 'b) func
+val is_undefined : ('a, 'b) func -> bool
+val (|->) : 'a -> 'b -> ('a, 'b) func -> ('a, 'b) func
+val (|=>) : 'a -> 'b -> ('a, 'b) func
+val choose : ('a, 'b) func -> 'a * 'b
+val combine : ('a -> 'a -> 'a) -> ('a -> bool) -> ('b, 'a) func -> ('b, 'a) func -> ('b, 'a) func
+val (--) : int -> int -> int list
+
+val tryapplyd : ('a, 'b) func -> 'a -> 'b -> 'b
+val apply : ('a, 'b) func -> 'a -> 'b
+
+val foldl : ('a -> 'b -> 'c -> 'a) -> 'a -> ('b, 'c) func -> 'a
+val foldr : ('a -> 'b -> 'c -> 'c) -> ('a, 'b) func -> 'c -> 'c
+val mapf : ('a -> 'b) -> ('c, 'a) func -> ('c, 'b) func
+
+val undefine : 'a -> ('a, 'b) func -> ('a, 'b) func
+
+val dom : ('a, 'b) func -> 'a list
+val graph : ('a, 'b) func -> ('a * 'b) list
+
+val union : 'a list -> 'a list -> 'a list
+val subtract : 'a list -> 'a list -> 'a list
+val sort : ('a -> 'a -> bool) -> 'a list -> 'a list
+val setify : 'a list -> 'a list
+val increasing : ('a -> 'b) -> 'a -> 'a -> bool
+val allpairs : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
+
+val gcd_num : Num.num -> Num.num -> Num.num
+val lcm_num : Num.num -> Num.num -> Num.num
+val numerator : Num.num -> Num.num
+val denominator : Num.num -> Num.num
+val end_itlist : ('a -> 'a -> 'a) -> 'a list -> 'a
+
+val (>>) : ('a -> 'b * 'c) -> ('b -> 'd) -> 'a -> 'd * 'c
+val (++) : ('a -> 'b * 'c) -> ('c -> 'd * 'e) -> 'a -> ('b * 'd) * 'e
+
+val a : 'a -> 'a list -> 'a * 'a list
+val many : ('a -> 'b * 'a) -> 'a -> 'b list * 'a
+val some : ('a -> bool) -> 'a list -> 'a * 'a list
+val possibly : ('a -> 'b * 'a) -> 'a -> 'b list * 'a
+val isspace : string -> bool
+val parser_or : ('a -> 'b) -> ('a -> 'b) -> 'a -> 'b
+val isnum : string -> bool
+val atleast : int -> ('a -> 'b * 'a) -> 'a -> 'b list * 'a
+val listof : ('a -> 'b * 'c) -> ('c -> 'd * 'a) -> string -> 'a -> 'b list * 'c
+
+val temp_path : string
+val string_of_file : string -> string
+val file_of_string : string -> string -> unit
+
+val deepen_until : int -> (int -> 'a) -> int -> 'a
+exception TooDeep
diff --git a/plugins/nsatz/g_nsatz.ml4 b/plugins/nsatz/g_nsatz.mlg
index 4ac49adb..16ff512e 100644
--- a/plugins/nsatz/g_nsatz.ml4
+++ b/plugins/nsatz/g_nsatz.mlg
@@ -8,11 +8,15 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Ltac_plugin
open Stdarg
+}
+
DECLARE PLUGIN "nsatz_plugin"
TACTIC EXTEND nsatz_compute
-| [ "nsatz_compute" constr(lt) ] -> [ Nsatz.nsatz_compute (EConstr.Unsafe.to_constr lt) ]
+| [ "nsatz_compute" constr(lt) ] -> { Nsatz.nsatz_compute (EConstr.Unsafe.to_constr lt) }
END
diff --git a/plugins/nsatz/nsatz.ml b/plugins/nsatz/nsatz.ml
index 81b44ffa..d2d4639d 100644
--- a/plugins/nsatz/nsatz.ml
+++ b/plugins/nsatz/nsatz.ml
@@ -136,7 +136,7 @@ let mul = function
| (Const n,q) when eq_num n num_1 -> q
| (p,q) -> Mul(p,q)
-let gen_constant msg path s = Universes.constr_of_global @@
+let gen_constant msg path s = UnivGen.constr_of_global @@
coq_reference msg path s
let tpexpr = lazy (gen_constant "CC" ["setoid_ring";"Ring_polynom"] "PExpr")
diff --git a/plugins/omega/PreOmega.v b/plugins/omega/PreOmega.v
index 59fd9b80..94a3d404 100644
--- a/plugins/omega/PreOmega.v
+++ b/plugins/omega/PreOmega.v
@@ -85,6 +85,7 @@ Ltac zify_binop t thm a b:=
Ltac zify_op_1 :=
match goal with
+ | x := ?t : Z |- _ => let h := fresh "heq_" x in pose proof (eq_refl : x = t) as h; clearbody x
| |- context [ Z.max ?a ?b ] => zify_binop Z.max Z.max_spec a b
| H : context [ Z.max ?a ?b ] |- _ => zify_binop Z.max Z.max_spec a b
| |- context [ Z.min ?a ?b ] => zify_binop Z.min Z.min_spec a b
@@ -114,6 +115,7 @@ Ltac hide_Z_of_nat t :=
Ltac zify_nat_rel :=
match goal with
(* I: equalities *)
+ | x := ?t : nat |- _ => let h := fresh "heq_" x in pose proof (eq_refl : x = t) as h; clearbody x
| |- (@eq nat ?a ?b) => apply (Nat2Z.inj a b) (* shortcut *)
| H : context [ @eq nat ?a ?b ] |- _ => rewrite <- (Nat2Z.inj_iff a b) in H
| |- context [ @eq nat ?a ?b ] => rewrite <- (Nat2Z.inj_iff a b)
@@ -181,7 +183,7 @@ Ltac zify_nat_op :=
let t := eval compute in (Z.of_nat (S a)) in
change (Z.of_nat (S a)) with t in H
| _ => rewrite (Nat2Z.inj_succ a) in H
- | _ => (* if the [rewrite] fails (most likely a dependent occurence of [Z.of_nat (S a)]),
+ | _ => (* if the [rewrite] fails (most likely a dependent occurrence of [Z.of_nat (S a)]),
hide [Z.of_nat (S a)] in this one hypothesis *)
change (Z.of_nat (S a)) with (Z_of_nat' (S a)) in H
end
@@ -192,7 +194,7 @@ Ltac zify_nat_op :=
let t := eval compute in (Z.of_nat (S a)) in
change (Z.of_nat (S a)) with t
| _ => rewrite (Nat2Z.inj_succ a)
- | _ => (* if the [rewrite] fails (most likely a dependent occurence of [Z.of_nat (S a)]),
+ | _ => (* if the [rewrite] fails (most likely a dependent occurrence of [Z.of_nat (S a)]),
hide [Z.of_nat (S a)] in the goal *)
change (Z.of_nat (S a)) with (Z_of_nat' (S a))
end
@@ -223,6 +225,7 @@ Ltac hide_Zpos t :=
Ltac zify_positive_rel :=
match goal with
(* I: equalities *)
+ | x := ?t : positive |- _ => let h := fresh "heq_" x in pose proof (eq_refl : x = t) as h; clearbody x
| |- (@eq positive ?a ?b) => apply Pos2Z.inj
| H : context [ @eq positive ?a ?b ] |- _ => rewrite <- (Pos2Z.inj_iff a b) in H
| |- context [ @eq positive ?a ?b ] => rewrite <- (Pos2Z.inj_iff a b)
@@ -348,6 +351,7 @@ Ltac hide_Z_of_N t :=
Ltac zify_N_rel :=
match goal with
(* I: equalities *)
+ | x := ?t : N |- _ => let h := fresh "heq_" x in pose proof (eq_refl : x = t) as h; clearbody x
| |- (@eq N ?a ?b) => apply (N2Z.inj a b) (* shortcut *)
| H : context [ @eq N ?a ?b ] |- _ => rewrite <- (N2Z.inj_iff a b) in H
| |- context [ @eq N ?a ?b ] => rewrite <- (N2Z.inj_iff a b)
diff --git a/plugins/omega/coq_omega.ml b/plugins/omega/coq_omega.ml
index 51cd665f..e14c4e2e 100644
--- a/plugins/omega/coq_omega.ml
+++ b/plugins/omega/coq_omega.ml
@@ -18,8 +18,8 @@
open CErrors
open Util
open Names
+open Constr
open Nameops
-open Term
open EConstr
open Tacticals.New
open Tacmach.New
@@ -29,7 +29,7 @@ open Libnames
open Globnames
open Nametab
open Contradiction
-open Misctypes
+open Tactypes
open Context.Named.Declaration
module NamedDecl = Context.Named.Declaration
@@ -38,15 +38,9 @@ open OmegaSolver
(* Added by JCF, 09/03/98 *)
-let elim_id id =
- Proofview.Goal.enter begin fun gl ->
- simplest_elim (mkVar id)
- end
-let resolve_id id = Proofview.Goal.enter begin fun gl ->
- apply (mkVar id)
-end
+let elim_id id = simplest_elim (mkVar id)
-let timing timer_name f arg = f arg
+let resolve_id id = apply (mkVar id)
let display_time_flag = ref false
let display_system_flag = ref false
@@ -206,7 +200,7 @@ let coq_modules =
init_modules @arith_modules @ [logic_dir] @ zarith_base_modules
@ [["Coq"; "omega"; "OmegaLemmas"]]
-let gen_constant_in_modules n m s = EConstr.of_constr (Universes.constr_of_global @@ gen_reference_in_modules n m s)
+let gen_constant_in_modules n m s = EConstr.of_constr (UnivGen.constr_of_global @@ gen_reference_in_modules n m s)
let init_constant = gen_constant_in_modules "Omega" init_modules
let constant = gen_constant_in_modules "Omega" coq_modules
@@ -369,8 +363,11 @@ let coq_True = lazy (init_constant "True")
(* uses build_coq_and, build_coq_not, build_coq_or, build_coq_ex *)
(* For unfold *)
-let evaluable_ref_of_constr s c = match EConstr.kind Evd.empty (Lazy.force c) with
- | Const (kn,u) when Tacred.is_evaluable (Global.env()) (EvalConstRef kn) ->
+let evaluable_ref_of_constr s c =
+ let env = Global.env () in
+ let evd = Evd.from_env env in
+ match EConstr.kind evd (Lazy.force c) with
+ | Const (kn,u) when Tacred.is_evaluable env (EvalConstRef kn) ->
EvalConstRef kn
| _ -> anomaly ~label:"Coq_omega" (Pp.str (s^" is not an evaluable constant."))
diff --git a/plugins/omega/g_omega.ml4 b/plugins/omega/g_omega.mlg
index 170b937c..c3d063cf 100644
--- a/plugins/omega/g_omega.ml4
+++ b/plugins/omega/g_omega.mlg
@@ -18,6 +18,8 @@
DECLARE PLUGIN "omega_plugin"
+{
+
open Ltac_plugin
open Names
open Coq_omega
@@ -43,14 +45,15 @@ let omega_tactic l =
(Tacticals.New.tclREPEAT (Tacticals.New.tclTHENLIST tacs))
(omega_solver)
+}
TACTIC EXTEND omega
-| [ "omega" ] -> [ omega_tactic [] ]
+| [ "omega" ] -> { omega_tactic [] }
END
TACTIC EXTEND omega'
| [ "omega" "with" ne_ident_list(l) ] ->
- [ omega_tactic (List.map Names.Id.to_string l) ]
-| [ "omega" "with" "*" ] -> [ omega_tactic ["nat";"positive";"N";"Z"] ]
+ { omega_tactic (List.map Names.Id.to_string l) }
+| [ "omega" "with" "*" ] -> { omega_tactic ["nat";"positive";"N";"Z"] }
END
diff --git a/plugins/omega/omega.ml b/plugins/omega/omega.ml
index 2510c169..7bca7c70 100644
--- a/plugins/omega/omega.ml
+++ b/plugins/omega/omega.ml
@@ -178,7 +178,7 @@ let rec display_action print_var = function
| DIVIDE_AND_APPROX (e1,e2,k,d) ->
Printf.printf
"Inequation E%d is divided by %s and the constant coefficient is \
- rounded by substracting %s.\n" e1.id (sbi k) (sbi d)
+ rounded by subtracting %s.\n" e1.id (sbi k) (sbi d)
| NOT_EXACT_DIVIDE (e,k) ->
Printf.printf
"Constant in equation E%d is not divisible by the pgcd \
diff --git a/plugins/quote/g_quote.ml4 b/plugins/quote/g_quote.mlg
index c35e0fe1..749903c3 100644
--- a/plugins/quote/g_quote.ml4
+++ b/plugins/quote/g_quote.mlg
@@ -8,32 +8,39 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
+
open Ltac_plugin
open Names
-open Misctypes
open Tacexpr
open Geninterp
open Quote
open Stdarg
open Tacarg
+}
+
DECLARE PLUGIN "quote_plugin"
+{
+
let cont = Id.of_string "cont"
let x = Id.of_string "x"
let make_cont (k : Val.t) (c : EConstr.t) =
let c = Tacinterp.Value.of_constr c in
- let tac = TacCall (Loc.tag (ArgVar CAst.(make cont), [Reference (ArgVar CAst.(make x))])) in
+ let tac = TacCall (Loc.tag (Locus.ArgVar CAst.(make cont), [Reference (Locus.ArgVar CAst.(make x))])) in
let ist = { lfun = Id.Map.add cont k (Id.Map.singleton x c); extra = TacStore.empty; } in
Tacinterp.eval_tactic_ist ist (TacArg (Loc.tag tac))
+}
+
TACTIC EXTEND quote
- [ "quote" ident(f) ] -> [ quote f [] ]
-| [ "quote" ident(f) "[" ne_ident_list(lc) "]"] -> [ quote f lc ]
+| [ "quote" ident(f) ] -> { quote f [] }
+| [ "quote" ident(f) "[" ne_ident_list(lc) "]"] -> { quote f lc }
| [ "quote" ident(f) "in" constr(c) "using" tactic(k) ] ->
- [ gen_quote (make_cont k) c f [] ]
+ { gen_quote (make_cont k) c f [] }
| [ "quote" ident(f) "[" ne_ident_list(lc) "]"
"in" constr(c) "using" tactic(k) ] ->
- [ gen_quote (make_cont k) c f lc ]
+ { gen_quote (make_cont k) c f lc }
END
diff --git a/plugins/quote/quote.ml b/plugins/quote/quote.ml
index 912429c3..7464b42d 100644
--- a/plugins/quote/quote.ml
+++ b/plugins/quote/quote.ml
@@ -120,7 +120,7 @@ open Proofview.Notations
the constants are loaded in the environment *)
let constant dir s =
- EConstr.of_constr @@ Universes.constr_of_global @@
+ EConstr.of_constr @@ UnivGen.constr_of_global @@
Coqlib.coq_reference "Quote" ("quote"::dir) s
let coq_Empty_vm = lazy (constant ["Quote"] "Empty_vm")
diff --git a/plugins/romega/const_omega.ml b/plugins/romega/const_omega.ml
index ad3afafd..949cba2d 100644
--- a/plugins/romega/const_omega.ml
+++ b/plugins/romega/const_omega.ml
@@ -69,19 +69,19 @@ let z_module = [["Coq";"ZArith";"BinInt"]]
let init_constant x =
EConstr.of_constr @@
- Universes.constr_of_global @@
+ UnivGen.constr_of_global @@
Coqlib.gen_reference_in_modules "Omega" Coqlib.init_modules x
let constant x =
EConstr.of_constr @@
- Universes.constr_of_global @@
+ UnivGen.constr_of_global @@
Coqlib.gen_reference_in_modules "Omega" coq_modules x
let z_constant x =
EConstr.of_constr @@
- Universes.constr_of_global @@
+ UnivGen.constr_of_global @@
Coqlib.gen_reference_in_modules "Omega" z_module x
let bin_constant x =
EConstr.of_constr @@
- Universes.constr_of_global @@
+ UnivGen.constr_of_global @@
Coqlib.gen_reference_in_modules "Omega" bin_module x
(* Logic *)
@@ -170,7 +170,7 @@ let mk_list univ typ l =
loop l
let mk_plist =
- let type1lev = Universes.new_univ_level () in
+ let type1lev = UnivGen.new_univ_level () in
fun l -> mk_list type1lev EConstr.mkProp l
let mk_list = mk_list Univ.Level.set
diff --git a/plugins/romega/g_romega.ml4 b/plugins/romega/g_romega.mlg
index 5b77d08d..ac4f30b1 100644
--- a/plugins/romega/g_romega.ml4
+++ b/plugins/romega/g_romega.mlg
@@ -9,6 +9,8 @@
DECLARE PLUGIN "romega_plugin"
+{
+
open Ltac_plugin
open Names
open Refl_omega
@@ -39,13 +41,23 @@ let romega_tactic unsafe l =
(Tactics.intros)
(total_reflexive_omega_tactic unsafe))
+let romega_depr =
+ Vernacinterp.mk_deprecation
+ ~since:(Some "8.9")
+ ~note:(Some "Use lia instead.")
+ ()
+
+}
+
TACTIC EXTEND romega
-| [ "romega" ] -> [ romega_tactic false [] ]
-| [ "unsafe_romega" ] -> [ romega_tactic true [] ]
+DEPRECATED { romega_depr }
+| [ "romega" ] -> { romega_tactic false [] }
+| [ "unsafe_romega" ] -> { romega_tactic true [] }
END
TACTIC EXTEND romega'
+DEPRECATED { romega_depr }
| [ "romega" "with" ne_ident_list(l) ] ->
- [ romega_tactic false (List.map Names.Id.to_string l) ]
-| [ "romega" "with" "*" ] -> [ romega_tactic false ["nat";"positive";"N";"Z"] ]
+ { romega_tactic false (List.map Names.Id.to_string l) }
+| [ "romega" "with" "*" ] -> { romega_tactic false ["nat";"positive";"N";"Z"] }
END
diff --git a/plugins/romega/refl_omega.ml b/plugins/romega/refl_omega.ml
index d1824978..e6034806 100644
--- a/plugins/romega/refl_omega.ml
+++ b/plugins/romega/refl_omega.ml
@@ -8,6 +8,7 @@
open Pp
open Util
+open Constr
open Const_omega
module OmegaSolver = Omega_plugin.Omega.MakeOmegaSolver (Bigint)
open OmegaSolver
@@ -1036,13 +1037,13 @@ let resolution unsafe sigma env (reified_concl,reified_hyps) systems_list =
let decompose_tactic = decompose_tree env context solution_tree in
Tactics.generalize (l_generalize_arg @ l_reified_hypnames) >>
- Tactics.convert_concl_no_check reified Term.DEFAULTcast >>
+ Tactics.convert_concl_no_check reified DEFAULTcast >>
Tactics.apply (app coq_do_omega [|decompose_tactic|]) >>
show_goal >>
(if unsafe then
(* Trust the produced term. Faster, but might fail later at Qed.
Also handy when debugging, e.g. via a Show Proof after romega. *)
- Tactics.convert_concl_no_check (Lazy.force coq_True) Term.VMcast
+ Tactics.convert_concl_no_check (Lazy.force coq_True) VMcast
else
Tactics.normalise_vm_in_concl) >>
Tactics.apply (Lazy.force coq_I)
diff --git a/plugins/rtauto/g_rtauto.ml4 b/plugins/rtauto/g_rtauto.mlg
index aa675763..9c9fdcfa 100644
--- a/plugins/rtauto/g_rtauto.ml4
+++ b/plugins/rtauto/g_rtauto.mlg
@@ -8,12 +8,15 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+{
open Ltac_plugin
+}
+
DECLARE PLUGIN "rtauto_plugin"
TACTIC EXTEND rtauto
- [ "rtauto" ] -> [ Proofview.V82.tactic (Refl_tauto.rtauto_tac) ]
+| [ "rtauto" ] -> { Proofview.V82.tactic (Refl_tauto.rtauto_tac) }
END
diff --git a/plugins/rtauto/refl_tauto.ml b/plugins/rtauto/refl_tauto.ml
index 946b6dff..8a0f48dc 100644
--- a/plugins/rtauto/refl_tauto.ml
+++ b/plugins/rtauto/refl_tauto.ml
@@ -26,27 +26,27 @@ let step_count = ref 0
let node_count = ref 0
-let logic_constant s = Universes.constr_of_global @@
+let logic_constant s = UnivGen.constr_of_global @@
Coqlib.coq_reference "refl_tauto" ["Init";"Logic"] s
let li_False = lazy (destInd (logic_constant "False"))
let li_and = lazy (destInd (logic_constant "and"))
let li_or = lazy (destInd (logic_constant "or"))
-let pos_constant s = Universes.constr_of_global @@
+let pos_constant s = UnivGen.constr_of_global @@
Coqlib.coq_reference "refl_tauto" ["Numbers";"BinNums"] s
let l_xI = lazy (pos_constant "xI")
let l_xO = lazy (pos_constant "xO")
let l_xH = lazy (pos_constant "xH")
-let store_constant s = Universes.constr_of_global @@
+let store_constant s = UnivGen.constr_of_global @@
Coqlib.coq_reference "refl_tauto" ["rtauto";"Bintree"] s
let l_empty = lazy (store_constant "empty")
let l_push = lazy (store_constant "push")
-let constant s = Universes.constr_of_global @@
+let constant s = UnivGen.constr_of_global @@
Coqlib.coq_reference "refl_tauto" ["rtauto";"Rtauto"] s
let l_Reflect = lazy (constant "Reflect")
diff --git a/plugins/setoid_ring/g_newring.ml4 b/plugins/setoid_ring/g_newring.ml4
index 5e4c9214..4ea0b30b 100644
--- a/plugins/setoid_ring/g_newring.ml4
+++ b/plugins/setoid_ring/g_newring.ml4
@@ -29,11 +29,6 @@ TACTIC EXTEND protect_fv
[ protect_tac map ]
END
-TACTIC EXTEND closed_term
- [ "closed_term" constr(t) "[" ne_reference_list(l) "]" ] ->
- [ closed_term t l ]
-END
-
open Pptactic
open Ppconstr
@@ -42,11 +37,11 @@ let pr_ring_mod = function
| Ring_kind Abstract -> str "abstract"
| Ring_kind (Morphism morph) -> str "morphism" ++ pr_arg pr_constr_expr morph
| Const_tac (CstTac cst_tac) -> str "constants" ++ spc () ++ str "[" ++ pr_raw_tactic cst_tac ++ str "]"
- | Const_tac (Closed l) -> str "closed" ++ spc () ++ str "[" ++ prlist_with_sep spc pr_reference l ++ str "]"
+ | Const_tac (Closed l) -> str "closed" ++ spc () ++ str "[" ++ prlist_with_sep spc pr_qualid l ++ str "]"
| Pre_tac t -> str "preprocess" ++ spc () ++ str "[" ++ pr_raw_tactic t ++ str "]"
| Post_tac t -> str "postprocess" ++ spc () ++ str "[" ++ pr_raw_tactic t ++ str "]"
| Setoid(sth,ext) -> str "setoid" ++ pr_arg pr_constr_expr sth ++ pr_arg pr_constr_expr ext
- | Pow_spec(Closed l,spec) -> str "power_tac" ++ pr_arg pr_constr_expr spec ++ spc () ++ str "[" ++ prlist_with_sep spc pr_reference l ++ str "]"
+ | Pow_spec(Closed l,spec) -> str "power_tac" ++ pr_arg pr_constr_expr spec ++ spc () ++ str "[" ++ prlist_with_sep spc pr_qualid l ++ str "]"
| Pow_spec(CstTac cst_tac,spec) -> str "power_tac" ++ pr_arg pr_constr_expr spec ++ spc () ++ str "[" ++ pr_raw_tactic cst_tac ++ str "]"
| Sign_spec t -> str "sign" ++ pr_arg pr_constr_expr t
| Div_spec t -> str "div" ++ pr_arg pr_constr_expr t
diff --git a/plugins/setoid_ring/newring.ml b/plugins/setoid_ring/newring.ml
index 99bb8440..a736eec5 100644
--- a/plugins/setoid_ring/newring.ml
+++ b/plugins/setoid_ring/newring.ml
@@ -20,6 +20,7 @@ open Environ
open Libnames
open Globnames
open Glob_term
+open Locus
open Tacexpr
open Coqlib
open Mod_subst
@@ -29,7 +30,6 @@ open Printer
open Declare
open Decl_kinds
open Entries
-open Misctypes
open Newring_ast
open Proofview.Notations
@@ -40,11 +40,7 @@ let error msg = CErrors.user_err Pp.(str msg)
type protect_flag = Eval|Prot|Rec
-let tag_arg tag_rec map subs i c =
- match map i with
- Eval -> mk_clos subs c
- | Prot -> mk_atom c
- | Rec -> if Int.equal i (-1) then mk_clos subs c else tag_rec c
+type protection = Evd.evar_map -> EConstr.t -> GlobRef.t -> (Int.t -> protect_flag) option
let global_head_of_constr sigma c =
let f, args = decompose_app sigma c in
@@ -55,32 +51,24 @@ let global_of_constr_nofail c =
try global_of_constr c
with Not_found -> VarRef (Id.of_string "dummy")
-let rec mk_clos_but f_map subs t =
- let open Term in
- match f_map (global_of_constr_nofail t) with
- | Some map -> tag_arg (mk_clos_but f_map subs) map subs (-1) t
- | None ->
- (match Constr.kind t with
- App(f,args) -> mk_clos_app_but f_map subs f args 0
- | Prod _ -> mk_clos_deep (mk_clos_but f_map) subs t
- | _ -> mk_atom t)
+let rec mk_clos_but f_map n t =
+ let (f, args) = Constr.decompose_appvect t in
+ match f_map (global_of_constr_nofail f) with
+ | Some tag ->
+ let map i t = tag_arg f_map n (tag i) t in
+ if Array.is_empty args then map (-1) f
+ else mk_red (FApp (map (-1) f, Array.mapi map args))
+ | None -> mk_atom t
-and mk_clos_app_but f_map subs f args n =
- let open Constr in
- if n >= Array.length args then mk_atom(mkApp(f, args))
- else
- let fargs, args' = Array.chop n args in
- let f' = mkApp(f,fargs) in
- match f_map (global_of_constr_nofail f') with
- | Some map ->
- let f i t = tag_arg (mk_clos_but f_map subs) map subs i t in
- mk_red (FApp (f (-1) f', Array.mapi f args'))
- | None -> mk_atom (mkApp (f, args))
+and tag_arg f_map n tag c = match tag with
+| Eval -> mk_clos (Esubst.subs_id n) c
+| Prot -> mk_atom c
+| Rec -> mk_clos_but f_map n c
let interp_map l t =
- try Some(List.assoc_f eq_gr t l) with Not_found -> None
+ try Some(List.assoc_f GlobRef.equal t l) with Not_found -> None
-let protect_maps = ref String.Map.empty
+let protect_maps : protection String.Map.t ref = ref String.Map.empty
let add_map s m = protect_maps := String.Map.add s m !protect_maps
let lookup_map map =
try String.Map.find map !protect_maps
@@ -90,8 +78,14 @@ let lookup_map map =
let protect_red map env sigma c0 =
let evars ev = Evarutil.safe_evar_value sigma ev in
let c = EConstr.Unsafe.to_constr c0 in
- EConstr.of_constr (kl (create_clos_infos ~evars all env) (create_tab ())
- (mk_clos_but (lookup_map map sigma c0) (Esubst.subs_id 0) c));;
+ let tab = create_tab () in
+ let infos = create_clos_infos ~evars all env in
+ let map = lookup_map map sigma c0 in
+ let rec eval n c = match Constr.kind c with
+ | Prod (na, t, u) -> Constr.mkProd (na, eval n t, eval (n + 1) u)
+ | _ -> kl infos tab (mk_clos_but map n c)
+ in
+ EConstr.of_constr (eval 0 c)
let protect_tac map =
Tactics.reduct_option (protect_red map,DEFAULTcast) None
@@ -102,34 +96,36 @@ let protect_tac_in map id =
(****************************************************************************)
-let closed_term t l =
- let open Quote_plugin in
+let rec closed_under sigma cset t =
+ try
+ let (gr, _) = Termops.global_of_constr sigma t in
+ Refset_env.mem gr cset
+ with Not_found ->
+ match EConstr.kind sigma t with
+ | Cast(c,_,_) -> closed_under sigma cset c
+ | App(f,l) -> closed_under sigma cset f && Array.for_all (closed_under sigma cset) l
+ | _ -> false
+
+let closed_term args _ = match args with
+| [t; l] ->
+ let t = Option.get (Value.to_constr t) in
+ let l = List.map (fun c -> Value.cast (Genarg.topwit Stdarg.wit_ref) c) (Option.get (Value.to_list l)) in
Proofview.tclEVARMAP >>= fun sigma ->
- let l = List.map Universes.constr_of_global l in
- let cs = List.fold_right Quote.ConstrSet.add l Quote.ConstrSet.empty in
- if Quote.closed_under sigma cs t then Proofview.tclUNIT () else Tacticals.New.tclFAIL 0 (mt())
-
-(* TACTIC EXTEND echo
-| [ "echo" constr(t) ] ->
- [ Pp.msg (Termops.print_constr t); Tacinterp.eval_tactic (TacId []) ]
-END;;*)
+ let cs = List.fold_right Refset_env.add l Refset_env.empty in
+ if closed_under sigma cs t then Proofview.tclUNIT () else Tacticals.New.tclFAIL 0 (mt())
+| _ -> assert false
-(*
-let closed_term_ast l =
- TacFun([Some(Id.of_string"t")],
- TacAtom(Loc.ghost,TacExtend(Loc.ghost,"closed_term",
- [Genarg.in_gen Constrarg.wit_constr (mkVar(Id.of_string"t"));
- Genarg.in_gen (Genarg.wit_list Constrarg.wit_ref) l])))
-*)
-let closed_term_ast l =
+let closed_term_ast =
let tacname = {
mltac_plugin = "newring_plugin";
mltac_tactic = "closed_term";
} in
+ let () = Tacenv.register_ml_tactic tacname [|closed_term|] in
let tacname = {
mltac_name = tacname;
mltac_index = 0;
} in
+ fun l ->
let l = List.map (fun gr -> ArgArg(Loc.tag gr)) l in
TacFun([Name(Id.of_string"t")],
TacML(Loc.tag (tacname,
@@ -154,8 +150,7 @@ let ic_unsafe c = (*FIXME remove *)
let decl_constant na univs c =
let open Constr in
- let env = Global.env () in
- let vars = Univops.universes_of_constr env c in
+ let vars = Univops.universes_of_constr c in
let univs = Univops.restrict_universe_context univs vars in
let univs = Monomorphic_const_entry univs in
mkConst(declare_constant (Id.of_string na)
@@ -166,28 +161,13 @@ let decl_constant na univs c =
let ltac_call tac (args:glob_tactic_arg list) =
TacArg(Loc.tag @@ TacCall (Loc.tag (ArgArg(Loc.tag @@ Lazy.force tac),args)))
-(* Calling a locally bound tactic *)
-let ltac_lcall tac args =
- TacArg(Loc.tag @@ TacCall (Loc.tag (ArgVar CAst.(make @@ Id.of_string tac),args)))
-
-let ltac_apply (f : Value.t) (args: Tacinterp.Value.t list) =
- let fold arg (i, vars, lfun) =
- let id = Id.of_string ("x" ^ string_of_int i) in
- let x = Reference (ArgVar CAst.(make id)) in
- (succ i, x :: vars, Id.Map.add id arg lfun)
- in
- let (_, args, lfun) = List.fold_right fold args (0, [], Id.Map.empty) in
- let lfun = Id.Map.add (Id.of_string "F") f lfun in
- let ist = { (Tacinterp.default_ist ()) with Tacinterp.lfun = lfun; } in
- Tacinterp.eval_tactic_ist ist (ltac_lcall "F" args)
-
let dummy_goal env sigma =
let (gl,_,sigma) =
Goal.V82.mk_goal sigma (named_context_val env) EConstr.mkProp Evd.Store.empty in
{Evd.it = gl; Evd.sigma = sigma}
-let constr_of v = match Value.to_constr v with
- | Some c -> EConstr.Unsafe.to_constr c
+let constr_of evd v = match Value.to_constr v with
+ | Some c -> EConstr.to_constr evd c
| None -> failwith "Ring.exec_tactic: anomaly"
let tactic_res = ref [||]
@@ -221,8 +201,8 @@ let exec_tactic env evd n f args =
(** Evaluate the whole result *)
let gl = dummy_goal env evd in
let gls = Proofview.V82.of_tactic (Tacinterp.eval_tactic_ist ist (ltac_call f (args@[getter]))) gl in
- let evd, nf = Evarutil.nf_evars_and_universes (Refiner.project gls) in
- let nf c = nf (constr_of c) in
+ let evd = Evd.minimize_universes (Refiner.project gls) in
+ let nf c = constr_of evd c in
Array.map nf !tactic_res, Evd.universe_context_set evd
let stdlib_modules =
@@ -233,7 +213,7 @@ let stdlib_modules =
]
let coq_constant c =
- lazy (EConstr.of_constr (Universes.constr_of_global @@ Coqlib.gen_reference_in_modules "Ring" stdlib_modules c))
+ lazy (EConstr.of_constr (UnivGen.constr_of_global @@ Coqlib.gen_reference_in_modules "Ring" stdlib_modules c))
let coq_reference c =
lazy (Coqlib.gen_reference_in_modules "Ring" stdlib_modules c)
@@ -247,9 +227,10 @@ let coq_nil = coq_reference "nil"
let lapp f args = mkApp(Lazy.force f,args)
-let plapp evd f args =
- let fc = Evarutil.e_new_global evd (Lazy.force f) in
- mkApp(fc,args)
+let plapp evdref f args =
+ let evd, fc = Evarutil.new_global !evdref (Lazy.force f) in
+ evdref := evd;
+ mkApp(fc,args)
let dest_rel0 sigma t =
match EConstr.kind sigma t with
@@ -278,7 +259,7 @@ let plugin_modules =
]
let my_constant c =
- lazy (EConstr.of_constr (Universes.constr_of_global @@ Coqlib.gen_reference_in_modules "Ring" plugin_modules c))
+ lazy (EConstr.of_constr (UnivGen.constr_of_global @@ Coqlib.gen_reference_in_modules "Ring" plugin_modules c))
let my_reference c =
lazy (Coqlib.gen_reference_in_modules "Ring" plugin_modules c)
@@ -504,10 +485,12 @@ let ring_equality env evd (r,add,mul,opp,req) =
let op_morph =
match opp with
Some opp -> plapp evd coq_eq_morph [|r;add;mul;opp|]
- | None -> plapp evd coq_eq_smorph [|r;add;mul|] in
- let setoid = Typing.e_solve_evars env evd setoid in
- let op_morph = Typing.e_solve_evars env evd op_morph in
- (setoid,op_morph)
+ | None -> plapp evd coq_eq_smorph [|r;add;mul|] in
+ let sigma = !evd in
+ let sigma, setoid = Typing.solve_evars env sigma setoid in
+ let sigma, op_morph = Typing.solve_evars env sigma op_morph in
+ evd := sigma;
+ (setoid,op_morph)
| _ ->
let setoid = setoid_of_relation (Global.env ()) evd r req in
let signature = [Some (r,Some req);Some (r,Some req)],Some(r,Some req) in
@@ -586,48 +569,53 @@ let make_hyp env evd c =
let t = Retyping.get_type_of env !evd c in
plapp evd coq_mkhypo [|t;c|]
-let make_hyp_list env evd lH =
- let carrier = Evarutil.e_new_global evd (Lazy.force coq_hypo) in
+let make_hyp_list env evdref lH =
+ let evd, carrier = Evarutil.new_global !evdref (Lazy.force coq_hypo) in
+ evdref := evd;
let l =
List.fold_right
- (fun c l -> plapp evd coq_cons [|carrier; (make_hyp env evd c); l|]) lH
- (plapp evd coq_nil [|carrier|])
+ (fun c l -> plapp evdref coq_cons [|carrier; (make_hyp env evdref c); l|]) lH
+ (plapp evdref coq_nil [|carrier|])
in
- let l' = Typing.e_solve_evars env evd l in
+ let sigma, l' = Typing.solve_evars env !evdref l in
+ evdref := sigma;
let l' = EConstr.Unsafe.to_constr l' in
- Evarutil.nf_evars_universes !evd l'
+ Evarutil.nf_evars_universes !evdref l'
-let interp_power env evd pow =
- let carrier = Evarutil.e_new_global evd (Lazy.force coq_hypo) in
+let interp_power env evdref pow =
+ let evd, carrier = Evarutil.new_global !evdref (Lazy.force coq_hypo) in
+ evdref := evd;
match pow with
| None ->
let t = ArgArg(Loc.tag (Lazy.force ltac_inv_morph_nothing)) in
- (TacArg(Loc.tag (TacCall(Loc.tag (t,[])))), plapp evd coq_None [|carrier|])
+ (TacArg(Loc.tag (TacCall(Loc.tag (t,[])))), plapp evdref coq_None [|carrier|])
| Some (tac, spec) ->
let tac =
match tac with
| CstTac t -> Tacintern.glob_tactic t
| Closed lc ->
closed_term_ast (List.map Smartlocate.global_with_alias lc) in
- let spec = make_hyp env evd (ic_unsafe spec) in
- (tac, plapp evd coq_Some [|carrier; spec|])
+ let spec = make_hyp env evdref (ic_unsafe spec) in
+ (tac, plapp evdref coq_Some [|carrier; spec|])
-let interp_sign env evd sign =
- let carrier = Evarutil.e_new_global evd (Lazy.force coq_hypo) in
+let interp_sign env evdref sign =
+ let evd, carrier = Evarutil.new_global !evdref (Lazy.force coq_hypo) in
+ evdref := evd;
match sign with
- | None -> plapp evd coq_None [|carrier|]
+ | None -> plapp evdref coq_None [|carrier|]
| Some spec ->
- let spec = make_hyp env evd (ic_unsafe spec) in
- plapp evd coq_Some [|carrier;spec|]
+ let spec = make_hyp env evdref (ic_unsafe spec) in
+ plapp evdref coq_Some [|carrier;spec|]
(* Same remark on ill-typed terms ... *)
-let interp_div env evd div =
- let carrier = Evarutil.e_new_global evd (Lazy.force coq_hypo) in
+let interp_div env evdref div =
+ let evd, carrier = Evarutil.new_global !evdref (Lazy.force coq_hypo) in
+ evdref := evd;
match div with
- | None -> plapp evd coq_None [|carrier|]
+ | None -> plapp evdref coq_None [|carrier|]
| Some spec ->
- let spec = make_hyp env evd (ic_unsafe spec) in
- plapp evd coq_Some [|carrier;spec|]
+ let spec = make_hyp env evdref (ic_unsafe spec) in
+ plapp evdref coq_Some [|carrier;spec|]
(* Same remark on ill-typed terms ... *)
let add_theory0 name (sigma, rth) eqth morphth cst_tac (pre,post) power sign div =
@@ -728,7 +716,9 @@ let make_term_list env evd carrier rl =
let l = List.fold_right
(fun x l -> plapp evd coq_cons [|carrier;x;l|]) rl
(plapp evd coq_nil [|carrier|])
- in Typing.e_solve_evars env evd l
+ in
+ let sigma, l = Typing.solve_evars env !evd l in
+ evd := sigma; l
let carg c = Tacinterp.Value.of_constr (EConstr.of_constr c)
let tacarg expr =
@@ -760,7 +750,7 @@ let ring_lookup (f : Value.t) lH rl t =
let rl = Value.of_constr (make_term_list env evdref (EConstr.of_constr e.ring_carrier) rl) in
let lH = carg (make_hyp_list env evdref lH) in
let ring = ltac_ring_structure e in
- Proofview.tclTHEN (Proofview.Unsafe.tclEVARS !evdref) (ltac_apply f (ring@[lH;rl]))
+ Proofview.tclTHEN (Proofview.Unsafe.tclEVARS !evdref) (Value.apply f (ring@[lH;rl]))
with e when Proofview.V82.catchable_exception e -> Proofview.tclZERO e
end
@@ -917,7 +907,7 @@ let ftheory_to_obj : field_info -> obj =
let field_equality evd r inv req =
match EConstr.kind !evd req with
| App (f, [| _ |]) when eq_constr_nounivs !evd f (Lazy.force coq_eq) ->
- let c = Universes.constr_of_global (Coqlib.build_coq_eq_data()).congr in
+ let c = UnivGen.constr_of_global (Coqlib.build_coq_eq_data()).congr in
let c = EConstr.of_constr c in
mkApp(c,[|r;r;inv|])
| _ ->
@@ -1046,6 +1036,6 @@ let field_lookup (f : Value.t) lH rl t =
let rl = Value.of_constr (make_term_list env evdref (EConstr.of_constr e.field_carrier) rl) in
let lH = carg (make_hyp_list env evdref lH) in
let field = ltac_field_structure e in
- Proofview.tclTHEN (Proofview.Unsafe.tclEVARS !evdref) (ltac_apply f (field@[lH;rl]))
+ Proofview.tclTHEN (Proofview.Unsafe.tclEVARS !evdref) (Value.apply f (field@[lH;rl]))
with e when Proofview.V82.catchable_exception e -> Proofview.tclZERO e
end
diff --git a/plugins/setoid_ring/newring.mli b/plugins/setoid_ring/newring.mli
index 1d1557b1..fcd04a2e 100644
--- a/plugins/setoid_ring/newring.mli
+++ b/plugins/setoid_ring/newring.mli
@@ -11,7 +11,6 @@
open Names
open EConstr
open Libnames
-open Globnames
open Constrexpr
open Newring_ast
@@ -19,8 +18,6 @@ val protect_tac_in : string -> Id.t -> unit Proofview.tactic
val protect_tac : string -> unit Proofview.tactic
-val closed_term : EConstr.constr -> global_reference list -> unit Proofview.tactic
-
val add_theory :
Id.t ->
constr_expr ->
diff --git a/plugins/setoid_ring/newring_ast.ml b/plugins/setoid_ring/newring_ast.ml
index 3eb68b51..a83c79d1 100644
--- a/plugins/setoid_ring/newring_ast.ml
+++ b/plugins/setoid_ring/newring_ast.ml
@@ -22,7 +22,7 @@ type 'constr coeff_spec =
type cst_tac_spec =
CstTac of raw_tactic_expr
- | Closed of reference list
+ | Closed of qualid list
type 'constr ring_mod =
Ring_kind of 'constr coeff_spec
diff --git a/plugins/setoid_ring/newring_ast.mli b/plugins/setoid_ring/newring_ast.mli
index 3eb68b51..a83c79d1 100644
--- a/plugins/setoid_ring/newring_ast.mli
+++ b/plugins/setoid_ring/newring_ast.mli
@@ -22,7 +22,7 @@ type 'constr coeff_spec =
type cst_tac_spec =
CstTac of raw_tactic_expr
- | Closed of reference list
+ | Closed of qualid list
type 'constr ring_mod =
Ring_kind of 'constr coeff_spec
diff --git a/plugins/ssr/ssrast.mli b/plugins/ssr/ssrast.mli
index 7f5f2f63..a786b995 100644
--- a/plugins/ssr/ssrast.mli
+++ b/plugins/ssr/ssrast.mli
@@ -37,7 +37,7 @@ type ssrmult = int * ssrmmod
type ssrocc = (bool * int list) option
(* index MAYBE REMOVE ONLY INTERNAL stuff between {} *)
-type ssrindex = int Misctypes.or_var
+type ssrindex = int Locus.or_var
(* clear switch {H G} *)
type ssrclear = ssrhyps
@@ -84,11 +84,11 @@ type ssripat =
| IPatId of (*TODO id_mod option * *) Id.t
| IPatAnon of anon_iter (* inaccessible name *)
(* TODO | IPatClearMark *)
- | IPatDispatch of ssripatss (* /[..|..] *)
+ | IPatDispatch of bool (* ssr exception: accept a dispatch on the empty list even when there are subgoals *) * ssripatss (* (..|..) *)
| IPatCase of (* ipats_mod option * *) ssripatss (* this is not equivalent to /case /[..|..] if there are already multiple goals *)
| IPatInj of ssripatss
| IPatRewrite of (*occurrence option * rewrite_pattern **) ssrocc * ssrdir
- | IPatView of ssrview (* /view *)
+ | IPatView of bool * ssrview (* {}/view (true if the clear is present) *)
| IPatClear of ssrclear (* {H1 H2} *)
| IPatSimpl of ssrsimpl
| IPatAbstractVars of Id.t list
diff --git a/plugins/ssr/ssrbool.v b/plugins/ssr/ssrbool.v
index 7d05b643..a618fc78 100644
--- a/plugins/ssr/ssrbool.v
+++ b/plugins/ssr/ssrbool.v
@@ -10,264 +10,266 @@
(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *)
+(** #<style> .doc { font-family: monospace; white-space: pre; } </style># **)
+
Require Bool.
Require Import ssreflect ssrfun.
-(******************************************************************************)
-(* A theory of boolean predicates and operators. A large part of this file is *)
-(* concerned with boolean reflection. *)
-(* Definitions and notations: *)
-(* is_true b == the coercion of b : bool to Prop (:= b = true). *)
-(* This is just input and displayed as `b''. *)
-(* reflect P b == the reflection inductive predicate, asserting *)
-(* that the logical proposition P : prop with the *)
-(* formula b : bool. Lemmas asserting reflect P b *)
-(* are often referred to as "views". *)
-(* iffP, appP, sameP, rwP :: lemmas for direct manipulation of reflection *)
-(* views: iffP is used to prove reflection from *)
-(* logical equivalence, appP to compose views, and *)
-(* sameP and rwP to perform boolean and setoid *)
-(* rewriting. *)
-(* elimT :: coercion reflect >-> Funclass, which allows the *)
-(* direct application of `reflect' views to *)
-(* boolean assertions. *)
-(* decidable P <-> P is effectively decidable (:= {P} + {~ P}. *)
-(* contra, contraL, ... :: contraposition lemmas. *)
-(* altP my_viewP :: natural alternative for reflection; given *)
-(* lemma myviewP: reflect my_Prop my_formula, *)
-(* have [myP | not_myP] := altP my_viewP. *)
-(* generates two subgoals, in which my_formula has *)
-(* been replaced by true and false, resp., with *)
-(* new assumptions myP : my_Prop and *)
-(* not_myP: ~~ my_formula. *)
-(* Caveat: my_formula must be an APPLICATION, not *)
-(* a variable, constant, let-in, etc. (due to the *)
-(* poor behaviour of dependent index matching). *)
-(* boolP my_formula :: boolean disjunction, equivalent to *)
-(* altP (idP my_formula) but circumventing the *)
-(* dependent index capture issue; destructing *)
-(* boolP my_formula generates two subgoals with *)
-(* assumtions my_formula and ~~ myformula. As *)
-(* with altP, my_formula must be an application. *)
-(* \unless C, P <-> we can assume property P when a something that *)
-(* holds under condition C (such as C itself). *)
-(* := forall G : Prop, (C -> G) -> (P -> G) -> G. *)
-(* This is just C \/ P or rather its impredicative *)
-(* encoding, whose usage better fits the above *)
-(* description: given a lemma UCP whose conclusion *)
-(* is \unless C, P we can assume P by writing: *)
-(* wlog hP: / P by apply/UCP; (prove C -> goal). *)
-(* or even apply: UCP id _ => hP if the goal is C. *)
-(* classically P <-> we can assume P when proving is_true b. *)
-(* := forall b : bool, (P -> b) -> b. *)
-(* This is equivalent to ~ (~ P) when P : Prop. *)
-(* implies P Q == wrapper coinductive type that coerces to P -> Q *)
-(* and can be used as a P -> Q view unambigously. *)
-(* Useful to avoid spurious insertion of <-> views *)
-(* when Q is a conjunction of foralls, as in Lemma *)
-(* all_and2 below; conversely, avoids confusion in *)
-(* apply views for impredicative properties, such *)
-(* as \unless C, P. Also supports contrapositives. *)
-(* a && b == the boolean conjunction of a and b. *)
-(* a || b == the boolean disjunction of a and b. *)
-(* a ==> b == the boolean implication of b by a. *)
-(* ~~ a == the boolean negation of a. *)
-(* a (+) b == the boolean exclusive or (or sum) of a and b. *)
-(* [ /\ P1 , P2 & P3 ] == multiway logical conjunction, up to 5 terms. *)
-(* [ \/ P1 , P2 | P3 ] == multiway logical disjunction, up to 4 terms. *)
-(* [&& a, b, c & d] == iterated, right associative boolean conjunction *)
-(* with arbitrary arity. *)
-(* [|| a, b, c | d] == iterated, right associative boolean disjunction *)
-(* with arbitrary arity. *)
-(* [==> a, b, c => d] == iterated, right associative boolean implication *)
-(* with arbitrary arity. *)
-(* and3P, ... == specific reflection lemmas for iterated *)
-(* connectives. *)
-(* andTb, orbAC, ... == systematic names for boolean connective *)
-(* properties (see suffix conventions below). *)
-(* prop_congr == a tactic to move a boolean equality from *)
-(* its coerced form in Prop to the equality *)
-(* in bool. *)
-(* bool_congr == resolution tactic for blindly weeding out *)
-(* like terms from boolean equalities (can fail). *)
-(* This file provides a theory of boolean predicates and relations: *)
-(* pred T == the type of bool predicates (:= T -> bool). *)
-(* simpl_pred T == the type of simplifying bool predicates, using *)
-(* the simpl_fun from ssrfun.v. *)
-(* rel T == the type of bool relations. *)
-(* := T -> pred T or T -> T -> bool. *)
-(* simpl_rel T == type of simplifying relations. *)
-(* predType == the generic predicate interface, supported for *)
-(* for lists and sets. *)
-(* pred_class == a coercion class for the predType projection to *)
-(* pred; declaring a coercion to pred_class is an *)
-(* alternative way of equipping a type with a *)
-(* predType structure, which interoperates better *)
-(* with coercion subtyping. This is used, e.g., *)
-(* for finite sets, so that finite groups inherit *)
-(* the membership operation by coercing to sets. *)
-(* If P is a predicate the proposition "x satisfies P" can be written *)
-(* applicatively as (P x), or using an explicit connective as (x \in P); in *)
-(* the latter case we say that P is a "collective" predicate. We use A, B *)
-(* rather than P, Q for collective predicates: *)
-(* x \in A == x satisfies the (collective) predicate A. *)
-(* x \notin A == x doesn't satisfy the (collective) predicate A. *)
-(* The pred T type can be used as a generic predicate type for either kind, *)
-(* but the two kinds of predicates should not be confused. When a "generic" *)
-(* pred T value of one type needs to be passed as the other the following *)
-(* conversions should be used explicitly: *)
-(* SimplPred P == a (simplifying) applicative equivalent of P. *)
-(* mem A == an applicative equivalent of A: *)
-(* mem A x simplifies to x \in A. *)
-(* Alternatively one can use the syntax for explicit simplifying predicates *)
-(* and relations (in the following x is bound in E): *)
-(* [pred x | E] == simplifying (see ssrfun) predicate x => E. *)
-(* [pred x : T | E] == predicate x => E, with a cast on the argument. *)
-(* [pred : T | P] == constant predicate P on type T. *)
-(* [pred x | E1 & E2] == [pred x | E1 && E2]; an x : T cast is allowed. *)
-(* [pred x in A] == [pred x | x in A]. *)
-(* [pred x in A | E] == [pred x | x in A & E]. *)
-(* [pred x in A | E1 & E2] == [pred x in A | E1 && E2]. *)
-(* [predU A & B] == union of two collective predicates A and B. *)
-(* [predI A & B] == intersection of collective predicates A and B. *)
-(* [predD A & B] == difference of collective predicates A and B. *)
-(* [predC A] == complement of the collective predicate A. *)
-(* [preim f of A] == preimage under f of the collective predicate A. *)
-(* predU P Q, ... == union, etc of applicative predicates. *)
-(* pred0 == the empty predicate. *)
-(* predT == the total (always true) predicate. *)
-(* if T : predArgType, then T coerces to predT. *)
-(* {: T} == T cast to predArgType (e.g., {: bool * nat}) *)
-(* In the following, x and y are bound in E: *)
-(* [rel x y | E] == simplifying relation x, y => E. *)
-(* [rel x y : T | E] == simplifying relation with arguments cast. *)
-(* [rel x y in A & B | E] == [rel x y | [&& x \in A, y \in B & E]]. *)
-(* [rel x y in A & B] == [rel x y | (x \in A) && (y \in B)]. *)
-(* [rel x y in A | E] == [rel x y in A & A | E]. *)
-(* [rel x y in A] == [rel x y in A & A]. *)
-(* relU R S == union of relations R and S. *)
-(* Explicit values of type pred T (i.e., lamdba terms) should always be used *)
-(* applicatively, while values of collection types implementing the predType *)
-(* interface, such as sequences or sets should always be used as collective *)
-(* predicates. Defined constants and functions of type pred T or simpl_pred T *)
-(* as well as the explicit simpl_pred T values described below, can generally *)
-(* be used either way. Note however that x \in A will not auto-simplify when *)
-(* A is an explicit simpl_pred T value; the generic simplification rule inE *)
-(* must be used (when A : pred T, the unfold_in rule can be used). Constants *)
-(* of type pred T with an explicit simpl_pred value do not auto-simplify when *)
-(* used applicatively, but can still be expanded with inE. This behavior can *)
-(* be controlled as follows: *)
-(* Let A : collective_pred T := [pred x | ... ]. *)
-(* The collective_pred T type is just an alias for pred T, but this cast *)
-(* stops rewrite inE from expanding the definition of A, thus treating A *)
-(* into an abstract collection (unfold_in or in_collective can be used to *)
-(* expand manually). *)
-(* Let A : applicative_pred T := [pred x | ...]. *)
-(* This cast causes inE to turn x \in A into the applicative A x form; *)
-(* A will then have to unfolded explicitly with the /A rule. This will *)
-(* also apply to any definition that reduces to A (e.g., Let B := A). *)
-(* Canonical A_app_pred := ApplicativePred A. *)
-(* This declaration, given after definition of A, similarly causes inE to *)
-(* turn x \in A into A x, but in addition allows the app_predE rule to *)
-(* turn A x back into x \in A; it can be used for any definition of type *)
-(* pred T, which makes it especially useful for ambivalent predicates *)
-(* as the relational transitive closure connect, that are used in both *)
-(* applicative and collective styles. *)
-(* Purely for aesthetics, we provide a subtype of collective predicates: *)
-(* qualifier q T == a pred T pretty-printing wrapper. An A : qualifier q T *)
-(* coerces to pred_class and thus behaves as a collective *)
-(* predicate, but x \in A and x \notin A are displayed as: *)
-(* x \is A and x \isn't A when q = 0, *)
-(* x \is a A and x \isn't a A when q = 1, *)
-(* x \is an A and x \isn't an A when q = 2, respectively. *)
-(* [qualify x | P] := Qualifier 0 (fun x => P), constructor for the above. *)
-(* [qualify x : T | P], [qualify a x | P], [qualify an X | P], etc. *)
-(* variants of the above with type constraints and different *)
-(* values of q. *)
-(* We provide an internal interface to support attaching properties (such as *)
-(* being multiplicative) to predicates: *)
-(* pred_key p == phantom type that will serve as a support for properties *)
-(* to be attached to p : pred_class; instances should be *)
-(* created with Fact/Qed so as to be opaque. *)
-(* KeyedPred k_p == an instance of the interface structure that attaches *)
-(* (k_p : pred_key P) to P; the structure projection is a *)
-(* coercion to pred_class. *)
-(* KeyedQualifier k_q == an instance of the interface structure that attaches *)
-(* (k_q : pred_key q) to (q : qualifier n T). *)
-(* DefaultPredKey p == a default value for pred_key p; the vernacular command *)
-(* Import DefaultKeying attaches this key to all predicates *)
-(* that are not explicitly keyed. *)
-(* Keys can be used to attach properties to predicates, qualifiers and *)
-(* generic nouns in a way that allows them to be used transparently. The key *)
-(* projection of a predicate property structure such as unsignedPred should *)
-(* be a pred_key, not a pred, and corresponding lemmas will have the form *)
-(* Lemma rpredN R S (oppS : @opprPred R S) (kS : keyed_pred oppS) : *)
-(* {mono -%R: x / x \in kS}. *)
-(* Because x \in kS will be displayed as x \in S (or x \is S, etc), the *)
-(* canonical instance of opprPred will not normally be exposed (it will also *)
-(* be erased by /= simplification). In addition each predicate structure *)
-(* should have a DefaultPredKey Canonical instance that simply issues the *)
-(* property as a proof obligation (which can be caught by the Prop-irrelevant *)
-(* feature of the ssreflect plugin). *)
-(* Some properties of predicates and relations: *)
-(* A =i B <-> A and B are extensionally equivalent. *)
-(* {subset A <= B} <-> A is a (collective) subpredicate of B. *)
-(* subpred P Q <-> P is an (applicative) subpredicate or Q. *)
-(* subrel R S <-> R is a subrelation of S. *)
-(* In the following R is in rel T: *)
-(* reflexive R <-> R is reflexive. *)
-(* irreflexive R <-> R is irreflexive. *)
-(* symmetric R <-> R (in rel T) is symmetric (equation). *)
-(* pre_symmetric R <-> R is symmetric (implication). *)
-(* antisymmetric R <-> R is antisymmetric. *)
-(* total R <-> R is total. *)
-(* transitive R <-> R is transitive. *)
-(* left_transitive R <-> R is a congruence on its left hand side. *)
-(* right_transitive R <-> R is a congruence on its right hand side. *)
-(* equivalence_rel R <-> R is an equivalence relation. *)
-(* Localization of (Prop) predicates; if P1 is convertible to forall x, Qx, *)
-(* P2 to forall x y, Qxy and P3 to forall x y z, Qxyz : *)
-(* {for y, P1} <-> Qx{y / x}. *)
-(* {in A, P1} <-> forall x, x \in A -> Qx. *)
-(* {in A1 & A2, P2} <-> forall x y, x \in A1 -> y \in A2 -> Qxy. *)
-(* {in A &, P2} <-> forall x y, x \in A -> y \in A -> Qxy. *)
-(* {in A1 & A2 & A3, Q3} <-> forall x y z, *)
-(* x \in A1 -> y \in A2 -> z \in A3 -> Qxyz. *)
-(* {in A1 & A2 &, Q3} == {in A1 & A2 & A2, Q3}. *)
-(* {in A1 && A3, Q3} == {in A1 & A1 & A3, Q3}. *)
-(* {in A &&, Q3} == {in A & A & A, Q3}. *)
-(* {in A, bijective f} == f has a right inverse in A. *)
-(* {on C, P1} == forall x, (f x) \in C -> Qx *)
-(* when P1 is also convertible to Pf f. *)
-(* {on C &, P2} == forall x y, f x \in C -> f y \in C -> Qxy *)
-(* when P2 is also convertible to Pf f. *)
-(* {on C, P1' & g} == forall x, (f x) \in cd -> Qx *)
-(* when P1' is convertible to Pf f *)
-(* and P1' g is convertible to forall x, Qx. *)
-(* {on C, bijective f} == f has a right inverse on C. *)
-(* This file extends the lemma name suffix conventions of ssrfun as follows: *)
-(* A -- associativity, as in andbA : associative andb. *)
-(* AC -- right commutativity. *)
-(* ACA -- self-interchange (inner commutativity), e.g., *)
-(* orbACA : (a || b) || (c || d) = (a || c) || (b || d). *)
-(* b -- a boolean argument, as in andbb : idempotent andb. *)
-(* C -- commutativity, as in andbC : commutative andb, *)
-(* or predicate complement, as in predC. *)
-(* CA -- left commutativity. *)
-(* D -- predicate difference, as in predD. *)
-(* E -- elimination, as in negbFE : ~~ b = false -> b. *)
-(* F or f -- boolean false, as in andbF : b && false = false. *)
-(* I -- left/right injectivity, as in addbI : right_injective addb, *)
-(* or predicate intersection, as in predI. *)
-(* l -- a left-hand operation, as andb_orl : left_distributive andb orb. *)
-(* N or n -- boolean negation, as in andbN : a && (~~ a) = false. *)
-(* P -- a characteristic property, often a reflection lemma, as in *)
-(* andP : reflect (a /\ b) (a && b). *)
-(* r -- a right-hand operation, as orb_andr : rightt_distributive orb andb. *)
-(* T or t -- boolean truth, as in andbT: right_id true andb. *)
-(* U -- predicate union, as in predU. *)
-(* W -- weakening, as in in1W : {in D, forall x, P} -> forall x, P. *)
-(******************************************************************************)
+(**
+ A theory of boolean predicates and operators. A large part of this file is
+ concerned with boolean reflection.
+ Definitions and notations:
+ is_true b == the coercion of b : bool to Prop (:= b = true).
+ This is just input and displayed as `b''.
+ reflect P b == the reflection inductive predicate, asserting
+ that the logical proposition P : prop with the
+ formula b : bool. Lemmas asserting reflect P b
+ are often referred to as "views".
+ iffP, appP, sameP, rwP :: lemmas for direct manipulation of reflection
+ views: iffP is used to prove reflection from
+ logical equivalence, appP to compose views, and
+ sameP and rwP to perform boolean and setoid
+ rewriting.
+ elimT :: coercion reflect >-> Funclass, which allows the
+ direct application of `reflect' views to
+ boolean assertions.
+ decidable P <-> P is effectively decidable (:= {P} + {~ P}.
+ contra, contraL, ... :: contraposition lemmas.
+ altP my_viewP :: natural alternative for reflection; given
+ lemma myviewP: reflect my_Prop my_formula,
+ have #[#myP | not_myP#]# := altP my_viewP.
+ generates two subgoals, in which my_formula has
+ been replaced by true and false, resp., with
+ new assumptions myP : my_Prop and
+ not_myP: ~~ my_formula.
+ Caveat: my_formula must be an APPLICATION, not
+ a variable, constant, let-in, etc. (due to the
+ poor behaviour of dependent index matching).
+ boolP my_formula :: boolean disjunction, equivalent to
+ altP (idP my_formula) but circumventing the
+ dependent index capture issue; destructing
+ boolP my_formula generates two subgoals with
+ assumtions my_formula and ~~ myformula. As
+ with altP, my_formula must be an application.
+ \unless C, P <-> we can assume property P when a something that
+ holds under condition C (such as C itself).
+ := forall G : Prop, (C -> G) -> (P -> G) -> G.
+ This is just C \/ P or rather its impredicative
+ encoding, whose usage better fits the above
+ description: given a lemma UCP whose conclusion
+ is \unless C, P we can assume P by writing:
+ wlog hP: / P by apply/UCP; (prove C -> goal).
+ or even apply: UCP id _ => hP if the goal is C.
+ classically P <-> we can assume P when proving is_true b.
+ := forall b : bool, (P -> b) -> b.
+ This is equivalent to ~ (~ P) when P : Prop.
+ implies P Q == wrapper variant type that coerces to P -> Q and
+ can be used as a P -> Q view unambigously.
+ Useful to avoid spurious insertion of <-> views
+ when Q is a conjunction of foralls, as in Lemma
+ all_and2 below; conversely, avoids confusion in
+ apply views for impredicative properties, such
+ as \unless C, P. Also supports contrapositives.
+ a && b == the boolean conjunction of a and b.
+ a || b == the boolean disjunction of a and b.
+ a ==> b == the boolean implication of b by a.
+ ~~ a == the boolean negation of a.
+ a (+) b == the boolean exclusive or (or sum) of a and b.
+ #[# /\ P1 , P2 & P3 #]# == multiway logical conjunction, up to 5 terms.
+ #[# \/ P1 , P2 | P3 #]# == multiway logical disjunction, up to 4 terms.
+ #[#&& a, b, c & d#]# == iterated, right associative boolean conjunction
+ with arbitrary arity.
+ #[#|| a, b, c | d#]# == iterated, right associative boolean disjunction
+ with arbitrary arity.
+ #[#==> a, b, c => d#]# == iterated, right associative boolean implication
+ with arbitrary arity.
+ and3P, ... == specific reflection lemmas for iterated
+ connectives.
+ andTb, orbAC, ... == systematic names for boolean connective
+ properties (see suffix conventions below).
+ prop_congr == a tactic to move a boolean equality from
+ its coerced form in Prop to the equality
+ in bool.
+ bool_congr == resolution tactic for blindly weeding out
+ like terms from boolean equalities (can fail).
+ This file provides a theory of boolean predicates and relations:
+ pred T == the type of bool predicates (:= T -> bool).
+ simpl_pred T == the type of simplifying bool predicates, using
+ the simpl_fun from ssrfun.v.
+ rel T == the type of bool relations.
+ := T -> pred T or T -> T -> bool.
+ simpl_rel T == type of simplifying relations.
+ predType == the generic predicate interface, supported for
+ for lists and sets.
+ pred_class == a coercion class for the predType projection to
+ pred; declaring a coercion to pred_class is an
+ alternative way of equipping a type with a
+ predType structure, which interoperates better
+ with coercion subtyping. This is used, e.g.,
+ for finite sets, so that finite groups inherit
+ the membership operation by coercing to sets.
+ If P is a predicate the proposition "x satisfies P" can be written
+ applicatively as (P x), or using an explicit connective as (x \in P); in
+ the latter case we say that P is a "collective" predicate. We use A, B
+ rather than P, Q for collective predicates:
+ x \in A == x satisfies the (collective) predicate A.
+ x \notin A == x doesn't satisfy the (collective) predicate A.
+ The pred T type can be used as a generic predicate type for either kind,
+ but the two kinds of predicates should not be confused. When a "generic"
+ pred T value of one type needs to be passed as the other the following
+ conversions should be used explicitly:
+ SimplPred P == a (simplifying) applicative equivalent of P.
+ mem A == an applicative equivalent of A:
+ mem A x simplifies to x \in A.
+ Alternatively one can use the syntax for explicit simplifying predicates
+ and relations (in the following x is bound in E):
+ #[#pred x | E#]# == simplifying (see ssrfun) predicate x => E.
+ #[#pred x : T | E#]# == predicate x => E, with a cast on the argument.
+ #[#pred : T | P#]# == constant predicate P on type T.
+ #[#pred x | E1 & E2#]# == #[#pred x | E1 && E2#]#; an x : T cast is allowed.
+ #[#pred x in A#]# == #[#pred x | x in A#]#.
+ #[#pred x in A | E#]# == #[#pred x | x in A & E#]#.
+ #[#pred x in A | E1 & E2#]# == #[#pred x in A | E1 && E2#]#.
+ #[#predU A & B#]# == union of two collective predicates A and B.
+ #[#predI A & B#]# == intersection of collective predicates A and B.
+ #[#predD A & B#]# == difference of collective predicates A and B.
+ #[#predC A#]# == complement of the collective predicate A.
+ #[#preim f of A#]# == preimage under f of the collective predicate A.
+ predU P Q, ... == union, etc of applicative predicates.
+ pred0 == the empty predicate.
+ predT == the total (always true) predicate.
+ if T : predArgType, then T coerces to predT.
+ {: T} == T cast to predArgType (e.g., {: bool * nat})
+ In the following, x and y are bound in E:
+ #[#rel x y | E#]# == simplifying relation x, y => E.
+ #[#rel x y : T | E#]# == simplifying relation with arguments cast.
+ #[#rel x y in A & B | E#]# == #[#rel x y | #[#&& x \in A, y \in B & E#]# #]#.
+ #[#rel x y in A & B#]# == #[#rel x y | (x \in A) && (y \in B) #]#.
+ #[#rel x y in A | E#]# == #[#rel x y in A & A | E#]#.
+ #[#rel x y in A#]# == #[#rel x y in A & A#]#.
+ relU R S == union of relations R and S.
+ Explicit values of type pred T (i.e., lamdba terms) should always be used
+ applicatively, while values of collection types implementing the predType
+ interface, such as sequences or sets should always be used as collective
+ predicates. Defined constants and functions of type pred T or simpl_pred T
+ as well as the explicit simpl_pred T values described below, can generally
+ be used either way. Note however that x \in A will not auto-simplify when
+ A is an explicit simpl_pred T value; the generic simplification rule inE
+ must be used (when A : pred T, the unfold_in rule can be used). Constants
+ of type pred T with an explicit simpl_pred value do not auto-simplify when
+ used applicatively, but can still be expanded with inE. This behavior can
+ be controlled as follows:
+ Let A : collective_pred T := #[#pred x | ... #]#.
+ The collective_pred T type is just an alias for pred T, but this cast
+ stops rewrite inE from expanding the definition of A, thus treating A
+ into an abstract collection (unfold_in or in_collective can be used to
+ expand manually).
+ Let A : applicative_pred T := #[#pred x | ... #]#.
+ This cast causes inE to turn x \in A into the applicative A x form;
+ A will then have to unfolded explicitly with the /A rule. This will
+ also apply to any definition that reduces to A (e.g., Let B := A).
+ Canonical A_app_pred := ApplicativePred A.
+ This declaration, given after definition of A, similarly causes inE to
+ turn x \in A into A x, but in addition allows the app_predE rule to
+ turn A x back into x \in A; it can be used for any definition of type
+ pred T, which makes it especially useful for ambivalent predicates
+ as the relational transitive closure connect, that are used in both
+ applicative and collective styles.
+ Purely for aesthetics, we provide a subtype of collective predicates:
+ qualifier q T == a pred T pretty-printing wrapper. An A : qualifier q T
+ coerces to pred_class and thus behaves as a collective
+ predicate, but x \in A and x \notin A are displayed as:
+ x \is A and x \isn't A when q = 0,
+ x \is a A and x \isn't a A when q = 1,
+ x \is an A and x \isn't an A when q = 2, respectively.
+ #[#qualify x | P#]# := Qualifier 0 (fun x => P), constructor for the above.
+ #[#qualify x : T | P#]#, #[#qualify a x | P#]#, #[#qualify an X | P#]#, etc.
+ variants of the above with type constraints and different
+ values of q.
+ We provide an internal interface to support attaching properties (such as
+ being multiplicative) to predicates:
+ pred_key p == phantom type that will serve as a support for properties
+ to be attached to p : pred_class; instances should be
+ created with Fact/Qed so as to be opaque.
+ KeyedPred k_p == an instance of the interface structure that attaches
+ (k_p : pred_key P) to P; the structure projection is a
+ coercion to pred_class.
+ KeyedQualifier k_q == an instance of the interface structure that attaches
+ (k_q : pred_key q) to (q : qualifier n T).
+ DefaultPredKey p == a default value for pred_key p; the vernacular command
+ Import DefaultKeying attaches this key to all predicates
+ that are not explicitly keyed.
+ Keys can be used to attach properties to predicates, qualifiers and
+ generic nouns in a way that allows them to be used transparently. The key
+ projection of a predicate property structure such as unsignedPred should
+ be a pred_key, not a pred, and corresponding lemmas will have the form
+ Lemma rpredN R S (oppS : @opprPred R S) (kS : keyed_pred oppS) :
+ {mono -%%R: x / x \in kS}.
+ Because x \in kS will be displayed as x \in S (or x \is S, etc), the
+ canonical instance of opprPred will not normally be exposed (it will also
+ be erased by /= simplification). In addition each predicate structure
+ should have a DefaultPredKey Canonical instance that simply issues the
+ property as a proof obligation (which can be caught by the Prop-irrelevant
+ feature of the ssreflect plugin).
+ Some properties of predicates and relations:
+ A =i B <-> A and B are extensionally equivalent.
+ {subset A <= B} <-> A is a (collective) subpredicate of B.
+ subpred P Q <-> P is an (applicative) subpredicate or Q.
+ subrel R S <-> R is a subrelation of S.
+ In the following R is in rel T:
+ reflexive R <-> R is reflexive.
+ irreflexive R <-> R is irreflexive.
+ symmetric R <-> R (in rel T) is symmetric (equation).
+ pre_symmetric R <-> R is symmetric (implication).
+ antisymmetric R <-> R is antisymmetric.
+ total R <-> R is total.
+ transitive R <-> R is transitive.
+ left_transitive R <-> R is a congruence on its left hand side.
+ right_transitive R <-> R is a congruence on its right hand side.
+ equivalence_rel R <-> R is an equivalence relation.
+ Localization of (Prop) predicates; if P1 is convertible to forall x, Qx,
+ P2 to forall x y, Qxy and P3 to forall x y z, Qxyz :
+ {for y, P1} <-> Qx{y / x}.
+ {in A, P1} <-> forall x, x \in A -> Qx.
+ {in A1 & A2, P2} <-> forall x y, x \in A1 -> y \in A2 -> Qxy.
+ {in A &, P2} <-> forall x y, x \in A -> y \in A -> Qxy.
+ {in A1 & A2 & A3, Q3} <-> forall x y z,
+ x \in A1 -> y \in A2 -> z \in A3 -> Qxyz.
+ {in A1 & A2 &, Q3} == {in A1 & A2 & A2, Q3}.
+ {in A1 && A3, Q3} == {in A1 & A1 & A3, Q3}.
+ {in A &&, Q3} == {in A & A & A, Q3}.
+ {in A, bijective f} == f has a right inverse in A.
+ {on C, P1} == forall x, (f x) \in C -> Qx
+ when P1 is also convertible to Pf f.
+ {on C &, P2} == forall x y, f x \in C -> f y \in C -> Qxy
+ when P2 is also convertible to Pf f.
+ {on C, P1' & g} == forall x, (f x) \in cd -> Qx
+ when P1' is convertible to Pf f
+ and P1' g is convertible to forall x, Qx.
+ {on C, bijective f} == f has a right inverse on C.
+ This file extends the lemma name suffix conventions of ssrfun as follows:
+ A -- associativity, as in andbA : associative andb.
+ AC -- right commutativity.
+ ACA -- self-interchange (inner commutativity), e.g.,
+ orbACA : (a || b) || (c || d) = (a || c) || (b || d).
+ b -- a boolean argument, as in andbb : idempotent andb.
+ C -- commutativity, as in andbC : commutative andb,
+ or predicate complement, as in predC.
+ CA -- left commutativity.
+ D -- predicate difference, as in predD.
+ E -- elimination, as in negbFE : ~~ b = false -> b.
+ F or f -- boolean false, as in andbF : b && false = false.
+ I -- left/right injectivity, as in addbI : right_injective addb,
+ or predicate intersection, as in predI.
+ l -- a left-hand operation, as andb_orl : left_distributive andb orb.
+ N or n -- boolean negation, as in andbN : a && (~~ a) = false.
+ P -- a characteristic property, often a reflection lemma, as in
+ andP : reflect (a /\ b) (a && b).
+ r -- a right-hand operation, as orb_andr : rightt_distributive orb andb.
+ T or t -- boolean truth, as in andbT: right_id true andb.
+ U -- predicate union, as in predU.
+ W -- weakening, as in in1W : {in D, forall x, P} -> forall x, P. **)
+
Set Implicit Arguments.
Unset Strict Implicit.
@@ -288,23 +290,24 @@ Reserved Notation "x \notin A"
Reserved Notation "p1 =i p2"
(at level 70, format "'[hv' p1 '/ ' =i p2 ']'", no associativity).
-(* We introduce a number of n-ary "list-style" notations that share a common *)
-(* format, namely *)
-(* [op arg1, arg2, ... last_separator last_arg] *)
-(* This usually denotes a right-associative applications of op, e.g., *)
-(* [&& a, b, c & d] denotes a && (b && (c && d)) *)
-(* The last_separator must be a non-operator token. Here we use &, | or =>; *)
-(* our default is &, but we try to match the intended meaning of op. The *)
-(* separator is a workaround for limitations of the parsing engine; the same *)
-(* limitations mean the separator cannot be omitted even when last_arg can. *)
-(* The Notation declarations are complicated by the separate treatment for *)
-(* some fixed arities (binary for bool operators, and all arities for Prop *)
-(* operators). *)
-(* We also use the square brackets in comprehension-style notations *)
-(* [type var separator expr] *)
-(* where "type" is the type of the comprehension (e.g., pred) and "separator" *)
-(* is | or => . It is important that in other notations a leading square *)
-(* bracket [ is always followed by an operator symbol or a fixed identifier. *)
+(**
+ We introduce a number of n-ary "list-style" notations that share a common
+ format, namely
+ #[#op arg1, arg2, ... last_separator last_arg#]#
+ This usually denotes a right-associative applications of op, e.g.,
+ #[#&& a, b, c & d#]# denotes a && (b && (c && d))
+ The last_separator must be a non-operator token. Here we use &, | or =>;
+ our default is &, but we try to match the intended meaning of op. The
+ separator is a workaround for limitations of the parsing engine; the same
+ limitations mean the separator cannot be omitted even when last_arg can.
+ The Notation declarations are complicated by the separate treatment for
+ some fixed arities (binary for bool operators, and all arities for Prop
+ operators).
+ We also use the square brackets in comprehension-style notations
+ #[#type var separator expr#]#
+ where "type" is the type of the comprehension (e.g., pred) and "separator"
+ is | or => . It is important that in other notations a leading square
+ bracket #[# is always followed by an operator symbol or a fixed identifier. **)
Reserved Notation "[ /\ P1 & P2 ]" (at level 0, only parsing).
Reserved Notation "[ /\ P1 , P2 & P3 ]" (at level 0, format
@@ -344,19 +347,19 @@ Reserved Notation "[ 'rel' x y => E ]" (at level 0, x, y at level 8, format
Reserved Notation "[ 'rel' x y : T => E ]" (at level 0, x, y at level 8, format
"'[hv' [ 'rel' x y : T => '/ ' E ] ']'").
-(* Shorter delimiter *)
+(** Shorter delimiter **)
Delimit Scope bool_scope with B.
Open Scope bool_scope.
-(* An alternative to xorb that behaves somewhat better wrt simplification. *)
+(** An alternative to xorb that behaves somewhat better wrt simplification. **)
Definition addb b := if b then negb else id.
-(* Notation for && and || is declared in Init.Datatypes. *)
+(** Notation for && and || is declared in Init.Datatypes. **)
Notation "~~ b" := (negb b) : bool_scope.
Notation "b ==> c" := (implb b c) : bool_scope.
Notation "b1 (+) b2" := (addb b1 b2) : bool_scope.
-(* Constant is_true b := b = true is defined in Init.Datatypes. *)
+(** Constant is_true b := b = true is defined in Init.Datatypes. **)
Coercion is_true : bool >-> Sortclass. (* Prop *)
Lemma prop_congr : forall b b' : bool, b = b' -> b = b' :> Prop.
@@ -364,21 +367,22 @@ Proof. by move=> b b' ->. Qed.
Ltac prop_congr := apply: prop_congr.
-(* Lemmas for trivial. *)
+(** Lemmas for trivial. **)
Lemma is_true_true : true. Proof. by []. Qed.
Lemma not_false_is_true : ~ false. Proof. by []. Qed.
Lemma is_true_locked_true : locked true. Proof. by unlock. Qed.
Hint Resolve is_true_true not_false_is_true is_true_locked_true.
-(* Shorter names. *)
+(** Shorter names. **)
Definition isT := is_true_true.
Definition notF := not_false_is_true.
-(* Negation lemmas. *)
+(** Negation lemmas. **)
-(* We generally take NEGATION as the standard form of a false condition: *)
-(* negative boolean hypotheses should be of the form ~~ b, rather than ~ b or *)
-(* b = false, as much as possible. *)
+(**
+ We generally take NEGATION as the standard form of a false condition:
+ negative boolean hypotheses should be of the form ~~ b, rather than ~ b or
+ b = false, as much as possible. **)
Lemma negbT b : b = false -> ~~ b. Proof. by case: b. Qed.
Lemma negbTE b : ~~ b -> b = false. Proof. by case: b. Qed.
@@ -426,8 +430,9 @@ Proof. by move/contra=> notb_notc /notb_notc/negbTE. Qed.
Lemma contraFF (c b : bool) : (c -> b) -> b = false -> c = false.
Proof. by move/contraFN=> bF_notc /bF_notc/negbTE. Qed.
-(* Coercion of sum-style datatypes into bool, which makes it possible *)
-(* to use ssr's boolean if rather than Coq's "generic" if. *)
+(**
+ Coercion of sum-style datatypes into bool, which makes it possible
+ to use ssr's boolean if rather than Coq's "generic" if. **)
Coercion isSome T (u : option T) := if u is Some _ then true else false.
@@ -441,22 +446,23 @@ Prenex Implicits isSome is_inl is_left is_inleft.
Definition decidable P := {P} + {~ P}.
-(* Lemmas for ifs with large conditions, which allow reasoning about the *)
-(* condition without repeating it inside the proof (the latter IS *)
-(* preferable when the condition is short). *)
-(* Usage : *)
-(* if the goal contains (if cond then ...) = ... *)
-(* case: ifP => Hcond. *)
-(* generates two subgoal, with the assumption Hcond : cond = true/false *)
-(* Rewrite if_same eliminates redundant ifs *)
-(* Rewrite (fun_if f) moves a function f inside an if *)
-(* Rewrite if_arg moves an argument inside a function-valued if *)
+(**
+ Lemmas for ifs with large conditions, which allow reasoning about the
+ condition without repeating it inside the proof (the latter IS
+ preferable when the condition is short).
+ Usage :
+ if the goal contains (if cond then ...) = ...
+ case: ifP => Hcond.
+ generates two subgoal, with the assumption Hcond : cond = true/false
+ Rewrite if_same eliminates redundant ifs
+ Rewrite (fun_if f) moves a function f inside an if
+ Rewrite if_arg moves an argument inside a function-valued if **)
Section BoolIf.
Variables (A B : Type) (x : A) (f : A -> B) (b : bool) (vT vF : A).
-CoInductive if_spec (not_b : Prop) : bool -> A -> Set :=
+Variant if_spec (not_b : Prop) : bool -> A -> Set :=
| IfSpecTrue of b : if_spec not_b true vT
| IfSpecFalse of not_b : if_spec not_b false vF.
@@ -483,13 +489,13 @@ Lemma if_arg (fT fF : A -> B) :
(if b then fT else fF) x = if b then fT x else fF x.
Proof. by case b. Qed.
-(* Turning a boolean "if" form into an application. *)
+(** Turning a boolean "if" form into an application. **)
Definition if_expr := if b then vT else vF.
Lemma ifE : (if b then vT else vF) = if_expr. Proof. by []. Qed.
End BoolIf.
-(* Core (internal) reflection lemmas, used for the three kinds of views. *)
+(** Core (internal) reflection lemmas, used for the three kinds of views. **)
Section ReflectCore.
@@ -517,7 +523,7 @@ Proof. by case Hb => [? _ H ? | ? H _]; case: H. Qed.
End ReflectCore.
-(* Internal negated reflection lemmas *)
+(** Internal negated reflection lemmas **)
Section ReflectNegCore.
Variables (P Q : Prop) (b c : bool).
@@ -537,7 +543,7 @@ Proof. by rewrite -if_neg; apply: xorPif. Qed.
End ReflectNegCore.
-(* User-oriented reflection lemmas *)
+(** User-oriented reflection lemmas **)
Section Reflect.
Variables (P Q : Prop) (b b' c : bool).
@@ -584,8 +590,8 @@ Lemma rwP : P <-> b. Proof. by split; [apply: introT | apply: elimT]. Qed.
Lemma rwP2 : reflect Q b -> (P <-> Q).
Proof. by move=> Qb; split=> ?; [apply: appP | apply: elimT; case: Qb]. Qed.
-(* Predicate family to reflect excluded middle in bool. *)
-CoInductive alt_spec : bool -> Type :=
+(** Predicate family to reflect excluded middle in bool. **)
+Variant alt_spec : bool -> Type :=
| AltTrue of P : alt_spec true
| AltFalse of ~~ b : alt_spec false.
@@ -600,10 +606,10 @@ Hint View for apply/ introTF|3 introNTF|3 introTFn|3 elimT|2 elimTn|2 elimN|2.
Hint View for apply// equivPif|3 xorPif|3 equivPifn|3 xorPifn|3.
-(* Allow the direct application of a reflection lemma to a boolean assertion. *)
+(** Allow the direct application of a reflection lemma to a boolean assertion. **)
Coercion elimT : reflect >-> Funclass.
-CoInductive implies P Q := Implies of P -> Q.
+Variant implies P Q := Implies of P -> Q.
Lemma impliesP P Q : implies P Q -> P -> Q. Proof. by case. Qed.
Lemma impliesPn (P Q : Prop) : implies P Q -> ~ Q -> ~ P.
Proof. by case=> iP ? /iP. Qed.
@@ -611,7 +617,7 @@ Coercion impliesP : implies >-> Funclass.
Hint View for move/ impliesPn|2 impliesP|2.
Hint View for apply/ impliesPn|2 impliesP|2.
-(* Impredicative or, which can emulate a classical not-implies. *)
+(** Impredicative or, which can emulate a classical not-implies. **)
Definition unless condition property : Prop :=
forall goal : Prop, (condition -> goal) -> (property -> goal) -> goal.
@@ -637,8 +643,9 @@ Proof. by split; apply=> [hC|hP]; [apply/unlessL/unlessL | apply/unlessR]. Qed.
Lemma unless_contra b C : implies (~~ b -> C) (\unless C, b).
Proof. by split; case: b => [_ | hC]; [apply/unlessR | apply/unlessL/hC]. Qed.
-(* Classical reasoning becomes directly accessible for any bool subgoal. *)
-(* Note that we cannot use "unless" here for lack of universe polymorphism. *)
+(**
+ Classical reasoning becomes directly accessible for any bool subgoal.
+ Note that we cannot use "unless" here for lack of universe polymorphism. **)
Definition classically P : Prop := forall b : bool, (P -> b) -> b.
Lemma classicP (P : Prop) : classically P <-> ~ ~ P.
@@ -669,11 +676,12 @@ move=> iPQ []// notPQ; apply/notPQ=> /iPQ-cQ.
by case: notF; apply: cQ => hQ; apply: notPQ.
Qed.
-(* List notations for wider connectives; the Prop connectives have a fixed *)
-(* width so as to avoid iterated destruction (we go up to width 5 for /\, and *)
-(* width 4 for or). The bool connectives have arbitrary widths, but denote *)
-(* expressions that associate to the RIGHT. This is consistent with the right *)
-(* associativity of list expressions and thus more convenient in most proofs. *)
+(**
+ List notations for wider connectives; the Prop connectives have a fixed
+ width so as to avoid iterated destruction (we go up to width 5 for /\, and
+ width 4 for or). The bool connectives have arbitrary widths, but denote
+ expressions that associate to the RIGHT. This is consistent with the right
+ associativity of list expressions and thus more convenient in most proofs. **)
Inductive and3 (P1 P2 P3 : Prop) : Prop := And3 of P1 & P2 & P3.
@@ -822,7 +830,7 @@ Arguments implyP [b1 b2].
Prenex Implicits idP idPn negP negPn negPf.
Prenex Implicits andP and3P and4P and5P orP or3P or4P nandP norP implyP.
-(* Shorter, more systematic names for the boolean connectives laws. *)
+(** Shorter, more systematic names for the boolean connectives laws. **)
Lemma andTb : left_id true andb. Proof. by []. Qed.
Lemma andFb : left_zero false andb. Proof. by []. Qed.
@@ -880,14 +888,14 @@ Proof. by case: a; case: b. Qed.
Lemma negb_or (a b : bool) : ~~ (a || b) = ~~ a && ~~ b.
Proof. by case: a; case: b. Qed.
-(* Pseudo-cancellation -- i.e, absorbtion *)
+(** Pseudo-cancellation -- i.e, absorbtion **)
Lemma andbK a b : a && b || a = a. Proof. by case: a; case: b. Qed.
Lemma andKb a b : a || b && a = a. Proof. by case: a; case: b. Qed.
Lemma orbK a b : (a || b) && a = a. Proof. by case: a; case: b. Qed.
Lemma orKb a b : a && (b || a) = a. Proof. by case: a; case: b. Qed.
-(* Imply *)
+(** Imply **)
Lemma implybT b : b ==> true. Proof. by case: b. Qed.
Lemma implybF b : (b ==> false) = ~~ b. Proof. by case: b. Qed.
@@ -917,7 +925,7 @@ Proof. by case: a; case: b => // ->. Qed.
Lemma implyb_id2l (a b c : bool) : (a -> b = c) -> (a ==> b) = (a ==> c).
Proof. by case: a; case: b; case: c => // ->. Qed.
-(* Addition (xor) *)
+(** Addition (xor) **)
Lemma addFb : left_id false addb. Proof. by []. Qed.
Lemma addbF : right_id false addb. Proof. by case. Qed.
@@ -946,9 +954,10 @@ Lemma addbP a b : reflect (~~ a = b) (a (+) b).
Proof. by case: a; case: b; constructor. Qed.
Arguments addbP [a b].
-(* Resolution tactic for blindly weeding out common terms from boolean *)
-(* equalities. When faced with a goal of the form (andb/orb/addb b1 b2) = b3 *)
-(* they will try to locate b1 in b3 and remove it. This can fail! *)
+(**
+ Resolution tactic for blindly weeding out common terms from boolean
+ equalities. When faced with a goal of the form (andb/orb/addb b1 b2) = b3
+ they will try to locate b1 in b3 and remove it. This can fail! **)
Ltac bool_congr :=
match goal with
@@ -963,100 +972,101 @@ Ltac bool_congr :=
| |- (~~ ?X1 = ?X2) => congr 1 negb
end.
-(******************************************************************************)
-(* Predicates, i.e., packaged functions to bool. *)
-(* - pred T, the basic type for predicates over a type T, is simply an alias *)
-(* for T -> bool. *)
-(* We actually distinguish two kinds of predicates, which we call applicative *)
-(* and collective, based on the syntax used to test them at some x in T: *)
-(* - For an applicative predicate P, one uses prefix syntax: *)
-(* P x *)
-(* Also, most operations on applicative predicates use prefix syntax as *)
-(* well (e.g., predI P Q). *)
-(* - For a collective predicate A, one uses infix syntax: *)
-(* x \in A *)
-(* and all operations on collective predicates use infix syntax as well *)
-(* (e.g., [predI A & B]). *)
-(* There are only two kinds of applicative predicates: *)
-(* - pred T, the alias for T -> bool mentioned above *)
-(* - simpl_pred T, an alias for simpl_fun T bool with a coercion to pred T *)
-(* that auto-simplifies on application (see ssrfun). *)
-(* On the other hand, the set of collective predicate types is open-ended via *)
-(* - predType T, a Structure that can be used to put Canonical collective *)
-(* predicate interpretation on other types, such as lists, tuples, *)
-(* finite sets, etc. *)
-(* Indeed, we define such interpretations for applicative predicate types, *)
-(* which can therefore also be used with the infix syntax, e.g., *)
-(* x \in predI P Q *)
-(* Moreover these infix forms are convertible to their prefix counterpart *)
-(* (e.g., predI P Q x which in turn simplifies to P x && Q x). The converse *)
-(* is not true, however; collective predicate types cannot, in general, be *)
-(* general, be used applicatively, because of the "uniform inheritance" *)
-(* restriction on implicit coercions. *)
-(* However, we do define an explicit generic coercion *)
-(* - mem : forall (pT : predType), pT -> mem_pred T *)
-(* where mem_pred T is a variant of simpl_pred T that preserves the infix *)
-(* syntax, i.e., mem A x auto-simplifies to x \in A. *)
-(* Indeed, the infix "collective" operators are notation for a prefix *)
-(* operator with arguments of type mem_pred T or pred T, applied to coerced *)
-(* collective predicates, e.g., *)
-(* Notation "x \in A" := (in_mem x (mem A)). *)
-(* This prevents the variability in the predicate type from interfering with *)
-(* the application of generic lemmas. Moreover this also makes it much easier *)
-(* to define generic lemmas, because the simplest type -- pred T -- can be *)
-(* used as the type of generic collective predicates, provided one takes care *)
-(* not to use it applicatively; this avoids the burden of having to declare a *)
-(* different predicate type for each predicate parameter of each section or *)
-(* lemma. *)
-(* This trick is made possible by the fact that the constructor of the *)
-(* mem_pred T type aligns the unification process, forcing a generic *)
-(* "collective" predicate A : pred T to unify with the actual collective B, *)
-(* which mem has coerced to pred T via an internal, hidden implicit coercion, *)
-(* supplied by the predType structure for B. Users should take care not to *)
-(* inadvertently "strip" (mem B) down to the coerced B, since this will *)
-(* expose the internal coercion: Coq will display a term B x that cannot be *)
-(* typed as such. The topredE lemma can be used to restore the x \in B *)
-(* syntax in this case. While -topredE can conversely be used to change *)
-(* x \in P into P x, it is safer to use the inE and memE lemmas instead, as *)
-(* they do not run the risk of exposing internal coercions. As a consequence *)
-(* it is better to explicitly cast a generic applicative pred T to simpl_pred *)
-(* using the SimplPred constructor, when it is used as a collective predicate *)
-(* (see, e.g., Lemma eq_big in bigop). *)
-(* We also sometimes "instantiate" the predType structure by defining a *)
-(* coercion to the sort of the predPredType structure. This works better for *)
-(* types such as {set T} that have subtypes that coerce to them, since the *)
-(* same coercion will be inserted by the application of mem. It also lets us *)
-(* turn any Type aT : predArgType into the total predicate over that type, *)
-(* i.e., fun _: aT => true. This allows us to write, e.g., #|'I_n| for the *)
-(* cardinal of the (finite) type of integers less than n. *)
-(* Collective predicates have a specific extensional equality, *)
-(* - A =i B, *)
-(* while applicative predicates use the extensional equality of functions, *)
-(* - P =1 Q *)
-(* The two forms are convertible, however. *)
-(* We lift boolean operations to predicates, defining: *)
-(* - predU (union), predI (intersection), predC (complement), *)
-(* predD (difference), and preim (preimage, i.e., composition) *)
-(* For each operation we define three forms, typically: *)
-(* - predU : pred T -> pred T -> simpl_pred T *)
-(* - [predU A & B], a Notation for predU (mem A) (mem B) *)
-(* - xpredU, a Notation for the lambda-expression inside predU, *)
-(* which is mostly useful as an argument of =1, since it exposes the head *)
-(* head constant of the expression to the ssreflect matching algorithm. *)
-(* The syntax for the preimage of a collective predicate A is *)
-(* - [preim f of A] *)
-(* Finally, the generic syntax for defining a simpl_pred T is *)
-(* - [pred x : T | P(x)], [pred x | P(x)], [pred x in A | P(x)], etc. *)
-(* We also support boolean relations, but only the applicative form, with *)
-(* types *)
-(* - rel T, an alias for T -> pred T *)
-(* - simpl_rel T, an auto-simplifying version, and syntax *)
-(* [rel x y | P(x,y)], [rel x y in A & B | P(x,y)], etc. *)
-(* The notation [rel of fA] can be used to coerce a function returning a *)
-(* collective predicate to one returning pred T. *)
-(* Finally, note that there is specific support for ambivalent predicates *)
-(* that can work in either style, as per this file's head descriptor. *)
-(******************************************************************************)
+
+(**
+ Predicates, i.e., packaged functions to bool.
+ - pred T, the basic type for predicates over a type T, is simply an alias
+ for T -> bool.
+ We actually distinguish two kinds of predicates, which we call applicative
+ and collective, based on the syntax used to test them at some x in T:
+ - For an applicative predicate P, one uses prefix syntax:
+ P x
+ Also, most operations on applicative predicates use prefix syntax as
+ well (e.g., predI P Q).
+ - For a collective predicate A, one uses infix syntax:
+ x \in A
+ and all operations on collective predicates use infix syntax as well
+ (e.g., #[#predI A & B#]#).
+ There are only two kinds of applicative predicates:
+ - pred T, the alias for T -> bool mentioned above
+ - simpl_pred T, an alias for simpl_fun T bool with a coercion to pred T
+ that auto-simplifies on application (see ssrfun).
+ On the other hand, the set of collective predicate types is open-ended via
+ - predType T, a Structure that can be used to put Canonical collective
+ predicate interpretation on other types, such as lists, tuples,
+ finite sets, etc.
+ Indeed, we define such interpretations for applicative predicate types,
+ which can therefore also be used with the infix syntax, e.g.,
+ x \in predI P Q
+ Moreover these infix forms are convertible to their prefix counterpart
+ (e.g., predI P Q x which in turn simplifies to P x && Q x). The converse
+ is not true, however; collective predicate types cannot, in general, be
+ general, be used applicatively, because of the "uniform inheritance"
+ restriction on implicit coercions.
+ However, we do define an explicit generic coercion
+ - mem : forall (pT : predType), pT -> mem_pred T
+ where mem_pred T is a variant of simpl_pred T that preserves the infix
+ syntax, i.e., mem A x auto-simplifies to x \in A.
+ Indeed, the infix "collective" operators are notation for a prefix
+ operator with arguments of type mem_pred T or pred T, applied to coerced
+ collective predicates, e.g.,
+ Notation "x \in A" := (in_mem x (mem A)).
+ This prevents the variability in the predicate type from interfering with
+ the application of generic lemmas. Moreover this also makes it much easier
+ to define generic lemmas, because the simplest type -- pred T -- can be
+ used as the type of generic collective predicates, provided one takes care
+ not to use it applicatively; this avoids the burden of having to declare a
+ different predicate type for each predicate parameter of each section or
+ lemma.
+ This trick is made possible by the fact that the constructor of the
+ mem_pred T type aligns the unification process, forcing a generic
+ "collective" predicate A : pred T to unify with the actual collective B,
+ which mem has coerced to pred T via an internal, hidden implicit coercion,
+ supplied by the predType structure for B. Users should take care not to
+ inadvertently "strip" (mem B) down to the coerced B, since this will
+ expose the internal coercion: Coq will display a term B x that cannot be
+ typed as such. The topredE lemma can be used to restore the x \in B
+ syntax in this case. While -topredE can conversely be used to change
+ x \in P into P x, it is safer to use the inE and memE lemmas instead, as
+ they do not run the risk of exposing internal coercions. As a consequence
+ it is better to explicitly cast a generic applicative pred T to simpl_pred
+ using the SimplPred constructor, when it is used as a collective predicate
+ (see, e.g., Lemma eq_big in bigop).
+ We also sometimes "instantiate" the predType structure by defining a
+ coercion to the sort of the predPredType structure. This works better for
+ types such as {set T} that have subtypes that coerce to them, since the
+ same coercion will be inserted by the application of mem. It also lets us
+ turn any Type aT : predArgType into the total predicate over that type,
+ i.e., fun _: aT => true. This allows us to write, e.g., ##|'I_n| for the
+ cardinal of the (finite) type of integers less than n.
+ Collective predicates have a specific extensional equality,
+ - A =i B,
+ while applicative predicates use the extensional equality of functions,
+ - P =1 Q
+ The two forms are convertible, however.
+ We lift boolean operations to predicates, defining:
+ - predU (union), predI (intersection), predC (complement),
+ predD (difference), and preim (preimage, i.e., composition)
+ For each operation we define three forms, typically:
+ - predU : pred T -> pred T -> simpl_pred T
+ - #[#predU A & B#]#, a Notation for predU (mem A) (mem B)
+ - xpredU, a Notation for the lambda-expression inside predU,
+ which is mostly useful as an argument of =1, since it exposes the head
+ head constant of the expression to the ssreflect matching algorithm.
+ The syntax for the preimage of a collective predicate A is
+ - #[#preim f of A#]#
+ Finally, the generic syntax for defining a simpl_pred T is
+ - #[#pred x : T | P(x) #]#, #[#pred x | P(x) #]#, #[#pred x in A | P(x) #]#, etc.
+ We also support boolean relations, but only the applicative form, with
+ types
+ - rel T, an alias for T -> pred T
+ - simpl_rel T, an auto-simplifying version, and syntax
+ #[#rel x y | P(x,y) #]#, #[#rel x y in A & B | P(x,y) #]#, etc.
+ The notation #[#rel of fA#]# can be used to coerce a function returning a
+ collective predicate to one returning pred T.
+ Finally, note that there is specific support for ambivalent predicates
+ that can work in either style, as per this file's head descriptor. **)
+
Definition pred T := T -> bool.
@@ -1094,8 +1104,9 @@ Coercion applicative_pred_of_simpl (p : simpl_pred) : applicative_pred :=
fun_of_simpl p.
Coercion collective_pred_of_simpl (p : simpl_pred) : collective_pred :=
fun x => (let: SimplFun f := p in fun _ => f x) x.
-(* Note: applicative_of_simpl is convertible to pred_of_simpl, while *)
-(* collective_of_simpl is not. *)
+(**
+ Note: applicative_of_simpl is convertible to pred_of_simpl, while
+ collective_of_simpl is not. **)
Definition pred0 := SimplPred xpred0.
Definition predT := SimplPred xpredT.
@@ -1119,7 +1130,7 @@ Proof. by move=> *; apply/orP; left. Qed.
Lemma subrelUr r1 r2 : subrel r2 (relU r1 r2).
Proof. by move=> *; apply/orP; right. Qed.
-CoInductive mem_pred := Mem of pred T.
+Variant mem_pred := Mem of pred T.
Definition isMem pT topred mem := mem = (fun p : pT => Mem [eta topred p]).
@@ -1166,19 +1177,21 @@ Notation "[ 'rel' x y : T | E ]" := (SimplRel (fun x y : T => E%B))
Notation "[ 'predType' 'of' T ]" := (@clone_pred _ T _ id _ _ id)
(at level 0, format "[ 'predType' 'of' T ]") : form_scope.
-(* This redundant coercion lets us "inherit" the simpl_predType canonical *)
-(* instance by declaring a coercion to simpl_pred. This hack is the only way *)
-(* to put a predType structure on a predArgType. We use simpl_pred rather *)
-(* than pred to ensure that /= removes the identity coercion. Note that the *)
-(* coercion will never be used directly for simpl_pred, since the canonical *)
-(* instance should always be resolved. *)
+(**
+ This redundant coercion lets us "inherit" the simpl_predType canonical
+ instance by declaring a coercion to simpl_pred. This hack is the only way
+ to put a predType structure on a predArgType. We use simpl_pred rather
+ than pred to ensure that /= removes the identity coercion. Note that the
+ coercion will never be used directly for simpl_pred, since the canonical
+ instance should always be resolved. **)
Notation pred_class := (pred_sort (predPredType _)).
Coercion sort_of_simpl_pred T (p : simpl_pred T) : pred_class := p : pred T.
-(* This lets us use some types as a synonym for their universal predicate. *)
-(* Unfortunately, this won't work for existing types like bool, unless we *)
-(* redefine bool, true, false and all bool ops. *)
+(**
+ This lets us use some types as a synonym for their universal predicate.
+ Unfortunately, this won't work for existing types like bool, unless we
+ redefine bool, true, false and all bool ops. **)
Definition predArgType := Type.
Bind Scope type_scope with predArgType.
Identity Coercion sort_of_predArgType : predArgType >-> Sortclass.
@@ -1187,8 +1200,9 @@ Coercion pred_of_argType (T : predArgType) : simpl_pred T := predT.
Notation "{ : T }" := (T%type : predArgType)
(at level 0, format "{ : T }") : type_scope.
-(* These must be defined outside a Section because "cooking" kills the *)
-(* nosimpl tag. *)
+(**
+ These must be defined outside a Section because "cooking" kills the
+ nosimpl tag. **)
Definition mem T (pT : predType T) : pT -> mem_pred T :=
nosimpl (let: @PredType _ _ _ (exist _ mem _) := pT return pT -> _ in mem).
@@ -1254,12 +1268,13 @@ Section simpl_mem.
Variables (T : Type) (pT : predType T).
Implicit Types (x : T) (p : pred T) (sp : simpl_pred T) (pp : pT).
-(* Bespoke structures that provide fine-grained control over matching the *)
-(* various forms of the \in predicate; note in particular the different forms *)
-(* of hoisting that are used. We had to work around several bugs in the *)
-(* implementation of unification, notably improper expansion of telescope *)
-(* projections and overwriting of a variable assignment by a later *)
-(* unification (probably due to conversion cache cross-talk). *)
+(**
+ Bespoke structures that provide fine-grained control over matching the
+ various forms of the \in predicate; note in particular the different forms
+ of hoisting that are used. We had to work around several bugs in the
+ implementation of unification, notably improper expansion of telescope
+ projections and overwriting of a variable assignment by a later
+ unification (probably due to conversion cache cross-talk). **)
Structure manifest_applicative_pred p := ManifestApplicativePred {
manifest_applicative_pred_value :> pred T;
_ : manifest_applicative_pred_value = p
@@ -1305,10 +1320,11 @@ Lemma in_simpl x p (msp : manifest_simpl_pred p) :
in_mem x (Mem [eta fun_of_simpl (msp : simpl_pred T)]) = p x.
Proof. by case: msp => _ /= ->. Qed.
-(* Because of the explicit eta expansion in the left-hand side, this lemma *)
-(* should only be used in a right-to-left direction. The 8.3 hack allowing *)
-(* partial right-to-left use does not work with the improved expansion *)
-(* heuristics in 8.4. *)
+(**
+ Because of the explicit eta expansion in the left-hand side, this lemma
+ should only be used in a right-to-left direction. The 8.3 hack allowing
+ partial right-to-left use does not work with the improved expansion
+ heuristics in 8.4. **)
Lemma unfold_in x p : (x \in ([eta p] : pred T)) = p x.
Proof. by []. Qed.
@@ -1327,9 +1343,9 @@ Proof. by rewrite -mem_topred. Qed.
End simpl_mem.
-(* Qualifiers and keyed predicates. *)
+(** Qualifiers and keyed predicates. **)
-CoInductive qualifier (q : nat) T := Qualifier of predPredType T.
+Variant qualifier (q : nat) T := Qualifier of predPredType T.
Coercion has_quality n T (q : qualifier n T) : pred_class :=
fun x => let: Qualifier _ p := q in p x.
@@ -1371,12 +1387,12 @@ Notation "[ 'qualify' 'an' x | P ]" := (Qualifier 2 (fun x => P%B))
Notation "[ 'qualify' 'an' x : T | P ]" := (Qualifier 2 (fun x : T => P%B))
(at level 0, x at level 99, only parsing) : form_scope.
-(* Keyed predicates: support for property-bearing predicate interfaces. *)
+(** Keyed predicates: support for property-bearing predicate interfaces. **)
Section KeyPred.
Variable T : Type.
-CoInductive pred_key (p : predPredType T) := DefaultPredKey.
+Variant pred_key (p : predPredType T) := DefaultPredKey.
Variable p : predPredType T.
Structure keyed_pred (k : pred_key p) :=
@@ -1388,13 +1404,14 @@ Definition KeyedPred := @PackKeyedPred k p (frefl _).
Variable k_p : keyed_pred k.
Lemma keyed_predE : k_p =i p. Proof. by case: k_p. Qed.
-(* Instances that strip the mem cast; the first one has "pred_of_mem" as its *)
-(* projection head value, while the second has "pred_of_simpl". The latter *)
-(* has the side benefit of preempting accidental misdeclarations. *)
-(* Note: pred_of_mem is the registered mem >-> pred_class coercion, while *)
-(* simpl_of_mem; pred_of_simpl is the mem >-> pred >=> Funclass coercion. We *)
-(* must write down the coercions explicitly as the Canonical head constant *)
-(* computation does not strip casts !! *)
+(**
+ Instances that strip the mem cast; the first one has "pred_of_mem" as its
+ projection head value, while the second has "pred_of_simpl". The latter
+ has the side benefit of preempting accidental misdeclarations.
+ Note: pred_of_mem is the registered mem >-> pred_class coercion, while
+ simpl_of_mem; pred_of_simpl is the mem >-> pred >=> Funclass coercion. We
+ must write down the coercions explicitly as the Canonical head constant
+ computation does not strip casts !! **)
Canonical keyed_mem :=
@PackKeyedPred k (pred_of_mem (mem k_p)) keyed_predE.
Canonical keyed_mem_simpl :=
@@ -1434,7 +1451,7 @@ Canonical default_keyed_qualifier T n (q : qualifier n T) :=
End DefaultKeying.
-(* Skolemizing with conditions. *)
+(** Skolemizing with conditions. **)
Lemma all_tag_cond_dep I T (C : pred I) U :
(forall x, T x) -> (forall x, C x -> {y : T x & U x y}) ->
@@ -1461,8 +1478,9 @@ Proof. by move=> y0; apply: all_sig_cond_dep. Qed.
Section RelationProperties.
-(* Caveat: reflexive should not be used to state lemmas, as auto and trivial *)
-(* will not expand the constant. *)
+(**
+ Caveat: reflexive should not be used to state lemmas, as auto and trivial
+ will not expand the constant. **)
Variable T : Type.
@@ -1496,8 +1514,9 @@ Proof. by move=> x y /sym_left_transitive Rxy z; rewrite !(symR z) Rxy. Qed.
End PER.
-(* We define the equivalence property with prenex quantification so that it *)
-(* can be localized using the {in ..., ..} form defined below. *)
+(**
+ We define the equivalence property with prenex quantification so that it
+ can be localized using the {in ..., ..} form defined below. **)
Definition equivalence_rel := forall x y z, R z z * (R x y -> R x z = R y z).
@@ -1512,7 +1531,7 @@ End RelationProperties.
Lemma rev_trans T (R : rel T) : transitive R -> transitive (fun x y => R y x).
Proof. by move=> trR x y z Ryx Rzy; apply: trR Rzy Ryx. Qed.
-(* Property localization *)
+(** Property localization **)
Local Notation "{ 'all1' P }" := (forall x, P x : Prop) (at level 0).
Local Notation "{ 'all2' P }" := (forall x y, P x y : Prop) (at level 0).
@@ -1626,11 +1645,12 @@ Notation "{ 'on' cd , 'bijective' f }" := (bijective_on (mem cd) f)
(at level 0, f at level 8,
format "{ 'on' cd , 'bijective' f }") : type_scope.
-(* Weakening and monotonicity lemmas for localized predicates. *)
-(* Note that using these lemmas in backward reasoning will force expansion of *)
-(* the predicate definition, as Coq needs to expose the quantifier to apply *)
-(* these lemmas. We define a few specialized variants to avoid this for some *)
-(* of the ssrfun predicates. *)
+(**
+ Weakening and monotonicity lemmas for localized predicates.
+ Note that using these lemmas in backward reasoning will force expansion of
+ the predicate definition, as Coq needs to expose the quantifier to apply
+ these lemmas. We define a few specialized variants to avoid this for some
+ of the ssrfun predicates. **)
Section LocalGlobal.
diff --git a/plugins/ssr/ssrcommon.ml b/plugins/ssr/ssrcommon.ml
index 82cae439..c94039a6 100644
--- a/plugins/ssr/ssrcommon.ml
+++ b/plugins/ssr/ssrcommon.ml
@@ -181,10 +181,9 @@ let option_assert_get o msg =
(** Constructors for rawconstr *)
open Glob_term
open Globnames
-open Misctypes
open Decl_kinds
-let mkRHole = DAst.make @@ GHole (Evar_kinds.InternalHole, IntroAnonymous, None)
+let mkRHole = DAst.make @@ GHole (Evar_kinds.InternalHole, Namegen.IntroAnonymous, None)
let rec mkRHoles n = if n > 0 then mkRHole :: mkRHoles (n - 1) else []
let rec isRHoles cl = match cl with
@@ -254,7 +253,7 @@ let interp_refine ist gl rc =
let interp_open_constr ist gl gc =
- let (sigma, (c, _)) = Tacinterp.interp_open_constr_with_bindings ist (pf_env gl) (project gl) (gc, Misctypes.NoBindings) in
+ let (sigma, (c, _)) = Tacinterp.interp_open_constr_with_bindings ist (pf_env gl) (project gl) (gc, Tactypes.NoBindings) in
(project gl, (sigma, c))
let interp_term ist gl (_, c) = snd (interp_open_constr ist gl c)
@@ -423,12 +422,12 @@ let mk_anon_id t gl_ids =
(set s i (Char.chr (Char.code (get s i) + 1)); s) in
Id.of_bytes (loop (n - 1))
-let convert_concl_no_check t = Tactics.convert_concl_no_check t Term.DEFAULTcast
-let convert_concl t = Tactics.convert_concl t Term.DEFAULTcast
+let convert_concl_no_check t = Tactics.convert_concl_no_check t DEFAULTcast
+let convert_concl t = Tactics.convert_concl t DEFAULTcast
let rename_hd_prod orig_name_ref gl =
match EConstr.kind (project gl) (pf_concl gl) with
- | Term.Prod(_,src,tgt) ->
+ | Prod(_,src,tgt) ->
Proofview.V82.of_tactic (convert_concl_no_check (EConstr.mkProd (!orig_name_ref,src,tgt))) gl
| _ -> CErrors.anomaly (str "gentac creates no product")
@@ -504,16 +503,17 @@ let nf_evar sigma t =
EConstr.Unsafe.to_constr (Evarutil.nf_evar sigma (EConstr.of_constr t))
let pf_abs_evars2 gl rigid (sigma, c0) =
- let c0 = EConstr.to_constr sigma c0 in
+ let c0 = EConstr.to_constr ~abort_on_undefined_evars:false sigma c0 in
let sigma0, ucst = project gl, Evd.evar_universe_context sigma in
let nenv = env_size (pf_env gl) in
let abs_evar n k =
let evi = Evd.find sigma k in
- let dc = CList.firstn n (evar_filtered_context evi) in
+ let concl = EConstr.Unsafe.to_constr evi.evar_concl in
+ let dc = EConstr.Unsafe.to_named_context (CList.firstn n (evar_filtered_context evi)) in
let abs_dc c = function
| NamedDecl.LocalDef (x,b,t) -> mkNamedLetIn x b t (mkArrow t c)
| NamedDecl.LocalAssum (x,t) -> mkNamedProd x t c in
- let t = Context.Named.fold_inside abs_dc ~init:evi.evar_concl dc in
+ let t = Context.Named.fold_inside abs_dc ~init:concl dc in
nf_evar sigma t in
let rec put evlist c = match Constr.kind c with
| Evar (k, a) ->
@@ -569,11 +569,12 @@ let pf_abs_evars_pirrel gl (sigma, c0) =
let nenv = env_size (pf_env gl) in
let abs_evar n k =
let evi = Evd.find sigma k in
- let dc = CList.firstn n (evar_filtered_context evi) in
+ let concl = EConstr.Unsafe.to_constr evi.evar_concl in
+ let dc = EConstr.Unsafe.to_named_context (CList.firstn n (evar_filtered_context evi)) in
let abs_dc c = function
| NamedDecl.LocalDef (x,b,t) -> mkNamedLetIn x b t (mkArrow t c)
| NamedDecl.LocalAssum (x,t) -> mkNamedProd x t c in
- let t = Context.Named.fold_inside abs_dc ~init:evi.evar_concl dc in
+ let t = Context.Named.fold_inside abs_dc ~init:concl dc in
nf_evar sigma0 (nf_evar sigma t) in
let rec put evlist c = match Constr.kind c with
| Evar (k, a) ->
@@ -581,7 +582,7 @@ let pf_abs_evars_pirrel gl (sigma, c0) =
let n = max 0 (Array.length a - nenv) in
let k_ty =
Retyping.get_sort_family_of
- (pf_env gl) sigma (EConstr.of_constr (Evd.evar_concl (Evd.find sigma k))) in
+ (pf_env gl) sigma (Evd.evar_concl (Evd.find sigma k)) in
let is_prop = k_ty = InProp in
let t = abs_evar n k in (k, (n, t, is_prop)) :: put evlist t
| _ -> Constr.fold put evlist c in
@@ -746,7 +747,7 @@ let pf_mkSsrConst name gl =
let pf_fresh_global name gl =
let sigma, env, it = project gl, pf_env gl, sig_it gl in
let sigma,t = Evd.fresh_global env sigma name in
- t, re_sig it sigma
+ EConstr.Unsafe.to_constr t, re_sig it sigma
let mkProt t c gl =
let prot, gl = pf_mkSsrConst "protect_term" gl in
@@ -802,7 +803,7 @@ let rec is_name_in_ipats name = function
| IPatId id :: tl -> id = name || is_name_in_ipats name tl
| IPatAbstractVars ids :: tl ->
CList.mem_f Id.equal name ids || is_name_in_ipats name tl
- | (IPatCase l | IPatDispatch l | IPatInj l) :: tl ->
+ | (IPatCase l | IPatDispatch (_,l) | IPatInj l) :: tl ->
List.exists (is_name_in_ipats name) l || is_name_in_ipats name tl
| (IPatView _ | IPatAnon _ | IPatSimpl _ | IPatRewrite _ | IPatTac _ | IPatNoop) :: tl -> is_name_in_ipats name tl
| [] -> false
@@ -857,10 +858,10 @@ open Util
(** Constructors for constr_expr *)
let mkCProp loc = CAst.make ?loc @@ CSort GProp
let mkCType loc = CAst.make ?loc @@ CSort (GType [])
-let mkCVar ?loc id = CAst.make ?loc @@ CRef (CAst.make ?loc @@ Ident id, None)
+let mkCVar ?loc id = CAst.make ?loc @@ CRef (qualid_of_ident ?loc id, None)
let rec mkCHoles ?loc n =
- if n <= 0 then [] else (CAst.make ?loc @@ CHole (None, IntroAnonymous, None)) :: mkCHoles ?loc (n - 1)
-let mkCHole loc = CAst.make ?loc @@ CHole (None, IntroAnonymous, None)
+ if n <= 0 then [] else (CAst.make ?loc @@ CHole (None, Namegen.IntroAnonymous, None)) :: mkCHoles ?loc (n - 1)
+let mkCHole loc = CAst.make ?loc @@ CHole (None, Namegen.IntroAnonymous, None)
let mkCLambda ?loc name ty t = CAst.make ?loc @@
CLambdaN ([CLocalAssum([CAst.make ?loc name], Default Explicit, ty)], t)
let mkCArrow ?loc ty t = CAst.make ?loc @@
@@ -983,7 +984,7 @@ let applyn ~with_evars ?beta ?(with_shelve=false) n t gl =
if not (EConstr.Vars.closed0 sigma ty) then
raise dependent_apply_error;
let m = Evarutil.new_meta () in
- loop (meta_declare m (EConstr.Unsafe.to_constr ty) sigma) bo ((EConstr.mkMeta m)::args) (n-1)
+ loop (meta_declare m ty sigma) bo ((EConstr.mkMeta m)::args) (n-1)
| _ -> assert false
in loop sigma t [] n in
pp(lazy(str"Refiner.refiner " ++ Printer.pr_econstr_env (pf_env gl) (project gl) t));
@@ -1219,7 +1220,7 @@ let genclrtac cl cs clr =
(fun type_err gl ->
tclTHEN
(tclTHEN (Proofview.V82.of_tactic (Tactics.elim_type (EConstr.of_constr
- (Universes.constr_of_global @@ Coqlib.build_coq_False ())))) (old_cleartac clr))
+ (UnivGen.constr_of_global @@ Coqlib.build_coq_False ())))) (old_cleartac clr))
(fun gl -> raise type_err)
gl))
(old_cleartac clr)
@@ -1444,7 +1445,7 @@ let tclINTRO_ANON = tclINTRO ~id:None ~conclusion:return
let tclRENAME_HD_PROD name = Goal.enter begin fun gl ->
let convert_concl_no_check t =
- Tactics.convert_concl_no_check t Term.DEFAULTcast in
+ Tactics.convert_concl_no_check t DEFAULTcast in
let concl = Goal.concl gl in
let sigma = Goal.sigma gl in
match EConstr.kind sigma concl with
@@ -1503,7 +1504,7 @@ let tclOPTION o d =
let tacIS_INJECTION_CASE ?ty t = begin
tclOPTION ty (tacTYPEOF t) >>= fun ty ->
tacREDUCE_TO_QUANTIFIED_IND ty >>= fun ((mind,_),_) ->
- tclUNIT (Globnames.eq_gr (Globnames.IndRef mind) (Coqlib.build_coq_eq ()))
+ tclUNIT (GlobRef.equal (GlobRef.IndRef mind) (Coqlib.build_coq_eq ()))
end
let tclWITHTOP tac = Goal.enter begin fun gl ->
diff --git a/plugins/ssr/ssrcommon.mli b/plugins/ssr/ssrcommon.mli
index 2b8f1d54..9ba23467 100644
--- a/plugins/ssr/ssrcommon.mli
+++ b/plugins/ssr/ssrcommon.mli
@@ -212,7 +212,7 @@ val pf_abs_prod :
EConstr.t -> Goal.goal Evd.sigma * EConstr.types
val mkSsrRRef : string -> Glob_term.glob_constr * 'a option
-val mkSsrRef : string -> Globnames.global_reference
+val mkSsrRef : string -> GlobRef.t
val mkSsrConst :
string ->
env -> evar_map -> evar_map * EConstr.t
@@ -224,7 +224,7 @@ val new_wild_id : tac_ctx -> Names.Id.t * tac_ctx
val pf_fresh_global :
- Globnames.global_reference ->
+ GlobRef.t ->
Goal.goal Evd.sigma ->
Constr.constr * Goal.goal Evd.sigma
diff --git a/plugins/ssr/ssreflect.v b/plugins/ssr/ssreflect.v
index b0a94413..bebbd4ad 100644
--- a/plugins/ssr/ssreflect.v
+++ b/plugins/ssr/ssreflect.v
@@ -10,50 +10,53 @@
(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *)
+(** #<style> .doc { font-family: monospace; white-space: pre; } </style># **)
+
Require Import Bool. (* For bool_scope delimiter 'bool'. *)
Require Import ssrmatching.
Declare ML Module "ssreflect_plugin".
-(******************************************************************************)
-(* This file is the Gallina part of the ssreflect plugin implementation. *)
-(* Files that use the ssreflect plugin should always Require ssreflect and *)
-(* either Import ssreflect or Import ssreflect.SsrSyntax. *)
-(* Part of the contents of this file is technical and will only interest *)
-(* advanced developers; in addition the following are defined: *)
-(* [the str of v by f] == the Canonical s : str such that f s = v. *)
-(* [the str of v] == the Canonical s : str that coerces to v. *)
-(* argumentType c == the T such that c : forall x : T, P x. *)
-(* returnType c == the R such that c : T -> R. *)
-(* {type of c for s} == P s where c : forall x : T, P x. *)
-(* phantom T v == singleton type with inhabitant Phantom T v. *)
-(* phant T == singleton type with inhabitant Phant v. *)
-(* =^~ r == the converse of rewriting rule r (e.g., in a *)
-(* rewrite multirule). *)
-(* unkeyed t == t, but treated as an unkeyed matching pattern by *)
-(* the ssreflect matching algorithm. *)
-(* nosimpl t == t, but on the right-hand side of Definition C := *)
-(* nosimpl disables expansion of C by /=. *)
-(* locked t == t, but locked t is not convertible to t. *)
-(* locked_with k t == t, but not convertible to t or locked_with k' t *)
-(* unless k = k' (with k : unit). Coq type-checking *)
-(* will be much more efficient if locked_with with a *)
-(* bespoke k is used for sealed definitions. *)
-(* unlockable v == interface for sealed constant definitions of v. *)
-(* Unlockable def == the unlockable that registers def : C = v. *)
-(* [unlockable of C] == a clone for C of the canonical unlockable for the *)
-(* definition of C (e.g., if it uses locked_with). *)
-(* [unlockable fun C] == [unlockable of C] with the expansion forced to be *)
-(* an explicit lambda expression. *)
-(* -> The usage pattern for ADT operations is: *)
-(* Definition foo_def x1 .. xn := big_foo_expression. *)
-(* Fact foo_key : unit. Proof. by []. Qed. *)
-(* Definition foo := locked_with foo_key foo_def. *)
-(* Canonical foo_unlockable := [unlockable fun foo]. *)
-(* This minimizes the comparison overhead for foo, while still allowing *)
-(* rewrite unlock to expose big_foo_expression. *)
-(* More information about these definitions and their use can be found in the *)
-(* ssreflect manual, and in specific comments below. *)
-(******************************************************************************)
+
+(**
+ This file is the Gallina part of the ssreflect plugin implementation.
+ Files that use the ssreflect plugin should always Require ssreflect and
+ either Import ssreflect or Import ssreflect.SsrSyntax.
+ Part of the contents of this file is technical and will only interest
+ advanced developers; in addition the following are defined:
+ #[#the str of v by f#]# == the Canonical s : str such that f s = v.
+ #[#the str of v#]# == the Canonical s : str that coerces to v.
+ argumentType c == the T such that c : forall x : T, P x.
+ returnType c == the R such that c : T -> R.
+ {type of c for s} == P s where c : forall x : T, P x.
+ phantom T v == singleton type with inhabitant Phantom T v.
+ phant T == singleton type with inhabitant Phant v.
+ =^~ r == the converse of rewriting rule r (e.g., in a
+ rewrite multirule).
+ unkeyed t == t, but treated as an unkeyed matching pattern by
+ the ssreflect matching algorithm.
+ nosimpl t == t, but on the right-hand side of Definition C :=
+ nosimpl disables expansion of C by /=.
+ locked t == t, but locked t is not convertible to t.
+ locked_with k t == t, but not convertible to t or locked_with k' t
+ unless k = k' (with k : unit). Coq type-checking
+ will be much more efficient if locked_with with a
+ bespoke k is used for sealed definitions.
+ unlockable v == interface for sealed constant definitions of v.
+ Unlockable def == the unlockable that registers def : C = v.
+ #[#unlockable of C#]# == a clone for C of the canonical unlockable for the
+ definition of C (e.g., if it uses locked_with).
+ #[#unlockable fun C#]# == #[#unlockable of C#]# with the expansion forced to be
+ an explicit lambda expression.
+ -> The usage pattern for ADT operations is:
+ Definition foo_def x1 .. xn := big_foo_expression.
+ Fact foo_key : unit. Proof. by #[# #]#. Qed.
+ Definition foo := locked_with foo_key foo_def.
+ Canonical foo_unlockable := #[#unlockable fun foo#]#.
+ This minimizes the comparison overhead for foo, while still allowing
+ rewrite unlock to expose big_foo_expression.
+ More information about these definitions and their use can be found in the
+ ssreflect manual, and in specific comments below. **)
+
Set Implicit Arguments.
@@ -62,15 +65,16 @@ Unset Printing Implicit Defensive.
Module SsrSyntax.
-(* Declare Ssr keywords: 'is' 'of' '//' '/=' and '//='. We also declare the *)
-(* parsing level 8, as a workaround for a notation grammar factoring problem. *)
-(* Arguments of application-style notations (at level 10) should be declared *)
-(* at level 8 rather than 9 or the camlp5 grammar will not factor properly. *)
+(**
+ Declare Ssr keywords: 'is' 'of' '//' '/=' and '//='. We also declare the
+ parsing level 8, as a workaround for a notation grammar factoring problem.
+ Arguments of application-style notations (at level 10) should be declared
+ at level 8 rather than 9 or the camlp5 grammar will not factor properly. **)
Reserved Notation "(* x 'is' y 'of' z 'isn't' // /= //= *)" (at level 8).
Reserved Notation "(* 69 *)" (at level 69).
-(* Non ambiguous keyword to check if the SsrSyntax module is imported *)
+(** Non ambiguous keyword to check if the SsrSyntax module is imported **)
Reserved Notation "(* Use to test if 'SsrSyntax_is_Imported' *)" (at level 8).
Reserved Notation "<hidden n >" (at level 200).
@@ -81,10 +85,11 @@ End SsrSyntax.
Export SsrMatchingSyntax.
Export SsrSyntax.
-(* Make the general "if" into a notation, so that we can override it below. *)
-(* The notations are "only parsing" because the Coq decompiler will not *)
-(* recognize the expansion of the boolean if; using the default printer *)
-(* avoids a spurrious trailing %GEN_IF. *)
+(**
+ Make the general "if" into a notation, so that we can override it below.
+ The notations are "only parsing" because the Coq decompiler will not
+ recognize the expansion of the boolean if; using the default printer
+ avoids a spurrious trailing %%GEN_IF. **)
Delimit Scope general_if_scope with GEN_IF.
@@ -101,7 +106,7 @@ Notation "'if' c 'as' x 'return' t 'then' v1 'else' v2" :=
(at level 200, c, t, v1, v2 at level 200, x ident, only parsing)
: general_if_scope.
-(* Force boolean interpretation of simple if expressions. *)
+(** Force boolean interpretation of simple if expressions. **)
Delimit Scope boolean_if_scope with BOOL_IF.
@@ -116,37 +121,40 @@ Notation "'if' c 'as' x 'return' t 'then' v1 'else' v2" :=
Open Scope boolean_if_scope.
-(* To allow a wider variety of notations without reserving a large number of *)
-(* of identifiers, the ssreflect library systematically uses "forms" to *)
-(* enclose complex mixfix syntax. A "form" is simply a mixfix expression *)
-(* enclosed in square brackets and introduced by a keyword: *)
-(* [keyword ... ] *)
-(* Because the keyword follows a bracket it does not need to be reserved. *)
-(* Non-ssreflect libraries that do not respect the form syntax (e.g., the Coq *)
-(* Lists library) should be loaded before ssreflect so that their notations *)
-(* do not mask all ssreflect forms. *)
+(**
+ To allow a wider variety of notations without reserving a large number of
+ of identifiers, the ssreflect library systematically uses "forms" to
+ enclose complex mixfix syntax. A "form" is simply a mixfix expression
+ enclosed in square brackets and introduced by a keyword:
+ #[#keyword ... #]#
+ Because the keyword follows a bracket it does not need to be reserved.
+ Non-ssreflect libraries that do not respect the form syntax (e.g., the Coq
+ Lists library) should be loaded before ssreflect so that their notations
+ do not mask all ssreflect forms. **)
Delimit Scope form_scope with FORM.
Open Scope form_scope.
-(* Allow overloading of the cast (x : T) syntax, put whitespace around the *)
-(* ":" symbol to avoid lexical clashes (and for consistency with the parsing *)
-(* precedence of the notation, which binds less tightly than application), *)
-(* and put printing boxes that print the type of a long definition on a *)
-(* separate line rather than force-fit it at the right margin. *)
+(**
+ Allow overloading of the cast (x : T) syntax, put whitespace around the
+ ":" symbol to avoid lexical clashes (and for consistency with the parsing
+ precedence of the notation, which binds less tightly than application),
+ and put printing boxes that print the type of a long definition on a
+ separate line rather than force-fit it at the right margin. **)
Notation "x : T" := (x : T)
(at level 100, right associativity,
format "'[hv' x '/ ' : T ']'") : core_scope.
-(* Allow the casual use of notations like nat * nat for explicit Type *)
-(* declarations. Note that (nat * nat : Type) is NOT equivalent to *)
-(* (nat * nat)%type, whose inferred type is legacy type "Set". *)
+(**
+ Allow the casual use of notations like nat * nat for explicit Type
+ declarations. Note that (nat * nat : Type) is NOT equivalent to
+ (nat * nat)%%type, whose inferred type is legacy type "Set". **)
Notation "T : 'Type'" := (T%type : Type)
(at level 100, only parsing) : core_scope.
-(* Allow similarly Prop annotation for, e.g., rewrite multirules. *)
+(** Allow similarly Prop annotation for, e.g., rewrite multirules. **)
Notation "P : 'Prop'" := (P%type : Prop)
(at level 100, only parsing) : core_scope.
-(* Constants for abstract: and [: name ] intro pattern *)
+(** Constants for abstract: and #[#: name #]# intro pattern **)
Definition abstract_lock := unit.
Definition abstract_key := tt.
@@ -156,35 +164,36 @@ Definition abstract (statement : Type) (id : nat) (lock : abstract_lock) :=
Notation "<hidden n >" := (abstract _ n _).
Notation "T (* n *)" := (abstract T n abstract_key).
-(* Constants for tactic-views *)
+(** Constants for tactic-views **)
Inductive external_view : Type := tactic_view of Type.
-(* Syntax for referring to canonical structures: *)
-(* [the struct_type of proj_val by proj_fun] *)
-(* This form denotes the Canonical instance s of the Structure type *)
-(* struct_type whose proj_fun projection is proj_val, i.e., such that *)
-(* proj_fun s = proj_val. *)
-(* Typically proj_fun will be A record field accessors of struct_type, but *)
-(* this need not be the case; it can be, for instance, a field of a record *)
-(* type to which struct_type coerces; proj_val will likewise be coerced to *)
-(* the return type of proj_fun. In all but the simplest cases, proj_fun *)
-(* should be eta-expanded to allow for the insertion of implicit arguments. *)
-(* In the common case where proj_fun itself is a coercion, the "by" part *)
-(* can be omitted entirely; in this case it is inferred by casting s to the *)
-(* inferred type of proj_val. Obviously the latter can be fixed by using an *)
-(* explicit cast on proj_val, and it is highly recommended to do so when the *)
-(* return type intended for proj_fun is "Type", as the type inferred for *)
-(* proj_val may vary because of sort polymorphism (it could be Set or Prop). *)
-(* Note when using the [the _ of _] form to generate a substructure from a *)
-(* telescopes-style canonical hierarchy (implementing inheritance with *)
-(* coercions), one should always project or coerce the value to the BASE *)
-(* structure, because Coq will only find a Canonical derived structure for *)
-(* the Canonical base structure -- not for a base structure that is specific *)
-(* to proj_value. *)
+(**
+ Syntax for referring to canonical structures:
+ #[#the struct_type of proj_val by proj_fun#]#
+ This form denotes the Canonical instance s of the Structure type
+ struct_type whose proj_fun projection is proj_val, i.e., such that
+ proj_fun s = proj_val.
+ Typically proj_fun will be A record field accessors of struct_type, but
+ this need not be the case; it can be, for instance, a field of a record
+ type to which struct_type coerces; proj_val will likewise be coerced to
+ the return type of proj_fun. In all but the simplest cases, proj_fun
+ should be eta-expanded to allow for the insertion of implicit arguments.
+ In the common case where proj_fun itself is a coercion, the "by" part
+ can be omitted entirely; in this case it is inferred by casting s to the
+ inferred type of proj_val. Obviously the latter can be fixed by using an
+ explicit cast on proj_val, and it is highly recommended to do so when the
+ return type intended for proj_fun is "Type", as the type inferred for
+ proj_val may vary because of sort polymorphism (it could be Set or Prop).
+ Note when using the #[#the _ of _ #]# form to generate a substructure from a
+ telescopes-style canonical hierarchy (implementing inheritance with
+ coercions), one should always project or coerce the value to the BASE
+ structure, because Coq will only find a Canonical derived structure for
+ the Canonical base structure -- not for a base structure that is specific
+ to proj_value. **)
Module TheCanonical.
-CoInductive put vT sT (v1 v2 : vT) (s : sT) := Put.
+Variant put vT sT (v1 v2 : vT) (s : sT) := Put.
Definition get vT sT v s (p : @put vT sT v v s) := let: Put _ _ _ := p in s.
@@ -203,11 +212,12 @@ Notation "[ 'the' sT 'of' v 'by' f ]" :=
Notation "[ 'the' sT 'of' v ]" := (get ((fun s : sT => Put v (*coerce*)s s) _))
(at level 0, only parsing) : form_scope.
-(* The following are "format only" versions of the above notations. Since Coq *)
-(* doesn't provide this facility, we fake it by splitting the "the" keyword. *)
-(* We need to do this to prevent the formatter from being be thrown off by *)
-(* application collapsing, coercion insertion and beta reduction in the right *)
-(* hand side of the notations above. *)
+(**
+ The following are "format only" versions of the above notations. Since Coq
+ doesn't provide this facility, we fake it by splitting the "the" keyword.
+ We need to do this to prevent the formatter from being be thrown off by
+ application collapsing, coercion insertion and beta reduction in the right
+ hand side of the notations above. **)
Notation "[ 'th' 'e' sT 'of' v 'by' f ]" := (@get_by _ sT f v _ _)
(at level 0, format "[ 'th' 'e' sT 'of' v 'by' f ]") : form_scope.
@@ -215,37 +225,39 @@ Notation "[ 'th' 'e' sT 'of' v 'by' f ]" := (@get_by _ sT f v _ _)
Notation "[ 'th' 'e' sT 'of' v ]" := (@get _ sT v _ _)
(at level 0, format "[ 'th' 'e' sT 'of' v ]") : form_scope.
-(* We would like to recognize
-Notation "[ 'th' 'e' sT 'of' v : 'Type' ]" := (@get Type sT v _ _)
- (at level 0, format "[ 'th' 'e' sT 'of' v : 'Type' ]") : form_scope.
-*)
-
-(* Helper notation for canonical structure inheritance support. *)
-(* This is a workaround for the poor interaction between delta reduction and *)
-(* canonical projections in Coq's unification algorithm, by which transparent *)
-(* definitions hide canonical instances, i.e., in *)
-(* Canonical a_type_struct := @Struct a_type ... *)
-(* Definition my_type := a_type. *)
-(* my_type doesn't effectively inherit the struct structure from a_type. Our *)
-(* solution is to redeclare the instance as follows *)
-(* Canonical my_type_struct := Eval hnf in [struct of my_type]. *)
-(* The special notation [str of _] must be defined for each Strucure "str" *)
-(* with constructor "Str", typically as follows *)
-(* Definition clone_str s := *)
-(* let: Str _ x y ... z := s return {type of Str for s} -> str in *)
-(* fun k => k _ x y ... z. *)
-(* Notation "[ 'str' 'of' T 'for' s ]" := (@clone_str s (@Str T)) *)
-(* (at level 0, format "[ 'str' 'of' T 'for' s ]") : form_scope. *)
-(* Notation "[ 'str' 'of' T ]" := (repack_str (fun x => @Str T x)) *)
-(* (at level 0, format "[ 'str' 'of' T ]") : form_scope. *)
-(* The notation for the match return predicate is defined below; the eta *)
-(* expansion in the second form serves both to distinguish it from the first *)
-(* and to avoid the delta reduction problem. *)
-(* There are several variations on the notation and the definition of the *)
-(* the "clone" function, for telescopes, mixin classes, and join (multiple *)
-(* inheritance) classes. We describe a different idiom for clones in ssrfun; *)
-(* it uses phantom types (see below) and static unification; see fintype and *)
-(* ssralg for examples. *)
+(**
+ We would like to recognize
+Notation " #[# 'th' 'e' sT 'of' v : 'Type' #]#" := (@get Type sT v _ _)
+ (at level 0, format " #[# 'th' 'e' sT 'of' v : 'Type' #]#") : form_scope.
+ **)
+
+(**
+ Helper notation for canonical structure inheritance support.
+ This is a workaround for the poor interaction between delta reduction and
+ canonical projections in Coq's unification algorithm, by which transparent
+ definitions hide canonical instances, i.e., in
+ Canonical a_type_struct := @Struct a_type ...
+ Definition my_type := a_type.
+ my_type doesn't effectively inherit the struct structure from a_type. Our
+ solution is to redeclare the instance as follows
+ Canonical my_type_struct := Eval hnf in #[#struct of my_type#]#.
+ The special notation #[#str of _ #]# must be defined for each Strucure "str"
+ with constructor "Str", typically as follows
+ Definition clone_str s :=
+ let: Str _ x y ... z := s return {type of Str for s} -> str in
+ fun k => k _ x y ... z.
+ Notation " #[# 'str' 'of' T 'for' s #]#" := (@clone_str s (@Str T))
+ (at level 0, format " #[# 'str' 'of' T 'for' s #]#") : form_scope.
+ Notation " #[# 'str' 'of' T #]#" := (repack_str (fun x => @Str T x))
+ (at level 0, format " #[# 'str' 'of' T #]#") : form_scope.
+ The notation for the match return predicate is defined below; the eta
+ expansion in the second form serves both to distinguish it from the first
+ and to avoid the delta reduction problem.
+ There are several variations on the notation and the definition of the
+ the "clone" function, for telescopes, mixin classes, and join (multiple
+ inheritance) classes. We describe a different idiom for clones in ssrfun;
+ it uses phantom types (see below) and static unification; see fintype and
+ ssralg for examples. **)
Definition argumentType T P & forall x : T, P x := T.
Definition dependentReturnType T P & forall x : T, P x := P.
@@ -254,79 +266,82 @@ Definition returnType aT rT & aT -> rT := rT.
Notation "{ 'type' 'of' c 'for' s }" := (dependentReturnType c s)
(at level 0, format "{ 'type' 'of' c 'for' s }") : type_scope.
-(* A generic "phantom" type (actually, a unit type with a phantom parameter). *)
-(* This type can be used for type definitions that require some Structure *)
-(* on one of their parameters, to allow Coq to infer said structure so it *)
-(* does not have to be supplied explicitly or via the "[the _ of _]" notation *)
-(* (the latter interacts poorly with other Notation). *)
-(* The definition of a (co)inductive type with a parameter p : p_type, that *)
-(* needs to use the operations of a structure *)
-(* Structure p_str : Type := p_Str {p_repr :> p_type; p_op : p_repr -> ...} *)
-(* should be given as *)
-(* Inductive indt_type (p : p_str) := Indt ... . *)
-(* Definition indt_of (p : p_str) & phantom p_type p := indt_type p. *)
-(* Notation "{ 'indt' p }" := (indt_of (Phantom p)). *)
-(* Definition indt p x y ... z : {indt p} := @Indt p x y ... z. *)
-(* Notation "[ 'indt' x y ... z ]" := (indt x y ... z). *)
-(* That is, the concrete type and its constructor should be shadowed by *)
-(* definitions that use a phantom argument to infer and display the true *)
-(* value of p (in practice, the "indt" constructor often performs additional *)
-(* functions, like "locking" the representation -- see below). *)
-(* We also define a simpler version ("phant" / "Phant") of phantom for the *)
-(* common case where p_type is Type. *)
-
-CoInductive phantom T (p : T) := Phantom.
+(**
+ A generic "phantom" type (actually, a unit type with a phantom parameter).
+ This type can be used for type definitions that require some Structure
+ on one of their parameters, to allow Coq to infer said structure so it
+ does not have to be supplied explicitly or via the " #[#the _ of _ #]#" notation
+ (the latter interacts poorly with other Notation).
+ The definition of a (co)inductive type with a parameter p : p_type, that
+ needs to use the operations of a structure
+ Structure p_str : Type := p_Str {p_repr :> p_type; p_op : p_repr -> ...}
+ should be given as
+ Inductive indt_type (p : p_str) := Indt ... .
+ Definition indt_of (p : p_str) & phantom p_type p := indt_type p.
+ Notation "{ 'indt' p }" := (indt_of (Phantom p)).
+ Definition indt p x y ... z : {indt p} := @Indt p x y ... z.
+ Notation " #[# 'indt' x y ... z #]#" := (indt x y ... z).
+ That is, the concrete type and its constructor should be shadowed by
+ definitions that use a phantom argument to infer and display the true
+ value of p (in practice, the "indt" constructor often performs additional
+ functions, like "locking" the representation -- see below).
+ We also define a simpler version ("phant" / "Phant") of phantom for the
+ common case where p_type is Type. **)
+
+Variant phantom T (p : T) := Phantom.
Arguments phantom : clear implicits.
Arguments Phantom : clear implicits.
-CoInductive phant (p : Type) := Phant.
+Variant phant (p : Type) := Phant.
-(* Internal tagging used by the implementation of the ssreflect elim. *)
+(** Internal tagging used by the implementation of the ssreflect elim. **)
Definition protect_term (A : Type) (x : A) : A := x.
-(* The ssreflect idiom for a non-keyed pattern: *)
-(* - unkeyed t wiil match any subterm that unifies with t, regardless of *)
-(* whether it displays the same head symbol as t. *)
-(* - unkeyed t a b will match any application of a term f unifying with t, *)
-(* to two arguments unifying with with a and b, repectively, regardless of *)
-(* apparent head symbols. *)
-(* - unkeyed x where x is a variable will match any subterm with the same *)
-(* type as x (when x would raise the 'indeterminate pattern' error). *)
+(**
+ The ssreflect idiom for a non-keyed pattern:
+ - unkeyed t wiil match any subterm that unifies with t, regardless of
+ whether it displays the same head symbol as t.
+ - unkeyed t a b will match any application of a term f unifying with t,
+ to two arguments unifying with with a and b, repectively, regardless of
+ apparent head symbols.
+ - unkeyed x where x is a variable will match any subterm with the same
+ type as x (when x would raise the 'indeterminate pattern' error). **)
Notation unkeyed x := (let flex := x in flex).
-(* Ssreflect converse rewrite rule rule idiom. *)
+(** Ssreflect converse rewrite rule rule idiom. **)
Definition ssr_converse R (r : R) := (Logic.I, r).
Notation "=^~ r" := (ssr_converse r) (at level 100) : form_scope.
-(* Term tagging (user-level). *)
-(* The ssreflect library uses four strengths of term tagging to restrict *)
-(* convertibility during type checking: *)
-(* nosimpl t simplifies to t EXCEPT in a definition; more precisely, given *)
-(* Definition foo := nosimpl bar, foo (or foo t') will NOT be expanded by *)
-(* the /= and //= switches unless it is in a forcing context (e.g., in *)
-(* match foo t' with ... end, foo t' will be reduced if this allows the *)
-(* match to be reduced). Note that nosimpl bar is simply notation for a *)
-(* a term that beta-iota reduces to bar; hence rewrite /foo will replace *)
-(* foo by bar, and rewrite -/foo will replace bar by foo. *)
-(* CAVEAT: nosimpl should not be used inside a Section, because the end of *)
-(* section "cooking" removes the iota redex. *)
-(* locked t is provably equal to t, but is not convertible to t; 'locked' *)
-(* provides support for selective rewriting, via the lock t : t = locked t *)
-(* Lemma, and the ssreflect unlock tactic. *)
-(* locked_with k t is equal but not convertible to t, much like locked t, *)
-(* but supports explicit tagging with a value k : unit. This is used to *)
-(* mitigate a flaw in the term comparison heuristic of the Coq kernel, *)
-(* which treats all terms of the form locked t as equal and conpares their *)
-(* arguments recursively, leading to an exponential blowup of comparison. *)
-(* For this reason locked_with should be used rather than locked when *)
-(* defining ADT operations. The unlock tactic does not support locked_with *)
-(* but the unlock rewrite rule does, via the unlockable interface. *)
-(* we also use Module Type ascription to create truly opaque constants, *)
-(* because simple expansion of constants to reveal an unreducible term *)
-(* doubles the time complexity of a negative comparison. Such opaque *)
-(* constants can be expanded generically with the unlock rewrite rule. *)
-(* See the definition of card and subset in fintype for examples of this. *)
+(**
+ Term tagging (user-level).
+ The ssreflect library uses four strengths of term tagging to restrict
+ convertibility during type checking:
+ nosimpl t simplifies to t EXCEPT in a definition; more precisely, given
+ Definition foo := nosimpl bar, foo (or foo t') will NOT be expanded by
+ the /= and //= switches unless it is in a forcing context (e.g., in
+ match foo t' with ... end, foo t' will be reduced if this allows the
+ match to be reduced). Note that nosimpl bar is simply notation for a
+ a term that beta-iota reduces to bar; hence rewrite /foo will replace
+ foo by bar, and rewrite -/foo will replace bar by foo.
+ CAVEAT: nosimpl should not be used inside a Section, because the end of
+ section "cooking" removes the iota redex.
+ locked t is provably equal to t, but is not convertible to t; 'locked'
+ provides support for selective rewriting, via the lock t : t = locked t
+ Lemma, and the ssreflect unlock tactic.
+ locked_with k t is equal but not convertible to t, much like locked t,
+ but supports explicit tagging with a value k : unit. This is used to
+ mitigate a flaw in the term comparison heuristic of the Coq kernel,
+ which treats all terms of the form locked t as equal and conpares their
+ arguments recursively, leading to an exponential blowup of comparison.
+ For this reason locked_with should be used rather than locked when
+ defining ADT operations. The unlock tactic does not support locked_with
+ but the unlock rewrite rule does, via the unlockable interface.
+ we also use Module Type ascription to create truly opaque constants,
+ because simple expansion of constants to reveal an unreducible term
+ doubles the time complexity of a negative comparison. Such opaque
+ constants can be expanded generically with the unlock rewrite rule.
+ See the definition of card and subset in fintype for examples of this. **)
Notation nosimpl t := (let: tt := tt in t).
@@ -335,11 +350,11 @@ Definition locked A := let: tt := master_key in fun x : A => x.
Lemma lock A x : x = locked x :> A. Proof. unlock; reflexivity. Qed.
-(* Needed for locked predicates, in particular for eqType's. *)
+(** Needed for locked predicates, in particular for eqType's. **)
Lemma not_locked_false_eq_true : locked false <> true.
Proof. unlock; discriminate. Qed.
-(* The basic closing tactic "done". *)
+(** The basic closing tactic "done". **)
Ltac done :=
trivial; hnf; intros; solve
[ do ![solve [trivial | apply: sym_equal; trivial]
@@ -347,7 +362,7 @@ Ltac done :=
| case not_locked_false_eq_true; assumption
| match goal with H : ~ _ |- _ => solve [case H; trivial] end ].
-(* Quicker done tactic not including split, syntax: /0/ *)
+(** Quicker done tactic not including split, syntax: /0/ **)
Ltac ssrdone0 :=
trivial; hnf; intros; solve
[ do ![solve [trivial | apply: sym_equal; trivial]
@@ -355,7 +370,7 @@ Ltac ssrdone0 :=
| case not_locked_false_eq_true; assumption
| match goal with H : ~ _ |- _ => solve [case H; trivial] end ].
-(* To unlock opaque constants. *)
+(** To unlock opaque constants. **)
Structure unlockable T v := Unlockable {unlocked : T; _ : unlocked = v}.
Lemma unlock T x C : @unlocked T x C = x. Proof. by case: C. Qed.
@@ -365,25 +380,26 @@ Notation "[ 'unlockable' 'of' C ]" := (@Unlockable _ _ C (unlock _))
Notation "[ 'unlockable' 'fun' C ]" := (@Unlockable _ (fun _ => _) C (unlock _))
(at level 0, format "[ 'unlockable' 'fun' C ]") : form_scope.
-(* Generic keyed constant locking. *)
+(** Generic keyed constant locking. **)
-(* The argument order ensures that k is always compared before T. *)
+(** The argument order ensures that k is always compared before T. **)
Definition locked_with k := let: tt := k in fun T x => x : T.
-(* This can be used as a cheap alternative to cloning the unlockable instance *)
-(* below, but with caution as unkeyed matching can be expensive. *)
+(**
+ This can be used as a cheap alternative to cloning the unlockable instance
+ below, but with caution as unkeyed matching can be expensive. **)
Lemma locked_withE T k x : unkeyed (locked_with k x) = x :> T.
Proof. by case: k. Qed.
-(* Intensionaly, this instance will not apply to locked u. *)
+(** Intensionaly, this instance will not apply to locked u. **)
Canonical locked_with_unlockable T k x :=
@Unlockable T x (locked_with k x) (locked_withE k x).
-(* More accurate variant of unlock, and safer alternative to locked_withE. *)
+(** More accurate variant of unlock, and safer alternative to locked_withE. **)
Lemma unlock_with T k x : unlocked (locked_with_unlockable k x) = x :> T.
Proof. exact: unlock. Qed.
-(* The internal lemmas for the have tactics. *)
+(** The internal lemmas for the have tactics. **)
Definition ssr_have Plemma Pgoal (step : Plemma) rest : Pgoal := rest step.
Arguments ssr_have Plemma [Pgoal].
@@ -398,7 +414,7 @@ Arguments ssr_suff Plemma [Pgoal].
Definition ssr_wlog := ssr_suff.
Arguments ssr_wlog Plemma [Pgoal].
-(* Internal N-ary congruence lemmas for the congr tactic. *)
+(** Internal N-ary congruence lemmas for the congr tactic. **)
Fixpoint nary_congruence_statement (n : nat)
: (forall B, (B -> B -> Prop) -> Prop) -> Prop :=
@@ -422,7 +438,7 @@ Lemma ssr_congr_arrow Plemma Pgoal : Plemma = Pgoal -> Plemma -> Pgoal.
Proof. by move->. Qed.
Arguments ssr_congr_arrow : clear implicits.
-(* View lemmas that don't use reflection. *)
+(** View lemmas that don't use reflection. **)
Section ApplyIff.
@@ -440,14 +456,15 @@ End ApplyIff.
Hint View for move/ iffLRn|2 iffRLn|2 iffLR|2 iffRL|2.
Hint View for apply/ iffRLn|2 iffLRn|2 iffRL|2 iffLR|2.
-(* To focus non-ssreflect tactics on a subterm, eg vm_compute. *)
-(* Usage: *)
-(* elim/abstract_context: (pattern) => G defG. *)
-(* vm_compute; rewrite {}defG {G}. *)
-(* Note that vm_cast are not stored in the proof term *)
-(* for reductions occuring in the context, hence *)
-(* set here := pattern; vm_compute in (value of here) *)
-(* blows up at Qed time. *)
+(**
+ To focus non-ssreflect tactics on a subterm, eg vm_compute.
+ Usage:
+ elim/abstract_context: (pattern) => G defG.
+ vm_compute; rewrite {}defG {G}.
+ Note that vm_cast are not stored in the proof term
+ for reductions occuring in the context, hence
+ set here := pattern; vm_compute in (value of here)
+ blows up at Qed time. **)
Lemma abstract_context T (P : T -> Type) x :
(forall Q, Q = P -> Q x) -> P x.
Proof. by move=> /(_ P); apply. Qed.
diff --git a/plugins/ssr/ssrelim.ml b/plugins/ssr/ssrelim.ml
index 40af5187..602fcfca 100644
--- a/plugins/ssr/ssrelim.ml
+++ b/plugins/ssr/ssrelim.ml
@@ -14,9 +14,10 @@ open Util
open Names
open Printer
open Term
+open Constr
open Termops
open Globnames
-open Misctypes
+open Tactypes
open Tacmach
open Ssrmatching_plugin
@@ -358,7 +359,7 @@ let ssrelim ?(ind=ref None) ?(is_case=false) deps what ?elim eqid elim_intro_tac
let ev = List.fold_left Evar.Set.union Evar.Set.empty patterns_ev in
let ty_ev = Evar.Set.fold (fun i e ->
let ex = i in
- let i_ty = EConstr.of_constr (Evd.evar_concl (Evd.find (project gl) ex)) in
+ let i_ty = Evd.evar_concl (Evd.find (project gl) ex) in
Evar.Set.union e (evars_of_term i_ty))
ev Evar.Set.empty in
let inter = Evar.Set.inter ev ty_ev in
@@ -420,7 +421,7 @@ let injectl2rtac sigma c = match EConstr.kind sigma c with
let is_injection_case c gl =
let gl, cty = pfe_type_of gl c in
let (mind,_), _ = pf_reduce_to_quantified_ind gl cty in
- eq_gr (IndRef mind) (Coqlib.build_coq_eq ())
+ GlobRef.equal (IndRef mind) (Coqlib.build_coq_eq ())
let perform_injection c gl =
let gl, cty = pfe_type_of gl c in
diff --git a/plugins/ssr/ssrequality.ml b/plugins/ssr/ssrequality.ml
index c29203de..f23433f2 100644
--- a/plugins/ssr/ssrequality.ml
+++ b/plugins/ssr/ssrequality.ml
@@ -277,7 +277,7 @@ let unfoldintac occ rdx t (kt,_) gl =
let foldtac occ rdx ft gl =
let sigma0, concl0, env0 = project gl, pf_concl gl, pf_env gl in
let sigma, t = ft in
- let t = EConstr.to_constr sigma t in
+ let t = EConstr.to_constr ~abort_on_undefined_evars:false sigma t in
let fold, conclude = match rdx with
| Some (_, (In_T _ | In_X_In_T _)) | None ->
let ise = Evd.create_evar_defs sigma in
@@ -288,7 +288,10 @@ let foldtac occ rdx ft gl =
(fun env c _ h -> try find_T env c h ~k:(fun env t _ _ -> t) with NoMatch ->c),
(fun () -> try end_T () with NoMatch -> fake_pmatcher_end ())
| _ ->
- (fun env c _ h -> try let sigma = unify_HO env sigma (EConstr.of_constr c) (EConstr.of_constr t) in EConstr.to_constr sigma (EConstr.of_constr t)
+ (fun env c _ h ->
+ try
+ let sigma = unify_HO env sigma (EConstr.of_constr c) (EConstr.of_constr t) in
+ EConstr.to_constr ~abort_on_undefined_evars:false sigma (EConstr.of_constr t)
with _ -> errorstrm Pp.(str "fold pattern " ++ pr_constr_pat t ++ spc ()
++ str "does not match redex " ++ pr_constr_pat c)),
fake_pmatcher_end in
@@ -360,7 +363,7 @@ let pirrel_rewrite pred rdx rdx_ty new_rdx dir (sigma, c) c_ty gl =
let evs = Evar.Set.elements (Evarutil.undefined_evars_of_term sigma t) in
let open_evs = List.filter (fun k ->
Sorts.InProp <> Retyping.get_sort_family_of
- env sigma (EConstr.of_constr (Evd.evar_concl (Evd.find sigma k))))
+ env sigma (Evd.evar_concl (Evd.find sigma k)))
evs in
if open_evs <> [] then Some name else None)
(List.combine (Array.to_list args) names)
@@ -370,8 +373,8 @@ let pirrel_rewrite pred rdx rdx_ty new_rdx dir (sigma, c) c_ty gl =
;;
let is_construct_ref sigma c r =
- EConstr.isConstruct sigma c && eq_gr (ConstructRef (fst(EConstr.destConstruct sigma c))) r
-let is_ind_ref sigma c r = EConstr.isInd sigma c && eq_gr (IndRef (fst(EConstr.destInd sigma c))) r
+ EConstr.isConstruct sigma c && GlobRef.equal (ConstructRef (fst(EConstr.destConstruct sigma c))) r
+let is_ind_ref sigma c r = EConstr.isInd sigma c && GlobRef.equal (IndRef (fst(EConstr.destInd sigma c))) r
let rwcltac cl rdx dir sr gl =
let n, r_n,_, ucst = pf_abs_evars gl sr in
@@ -415,8 +418,6 @@ let rwcltac cl rdx dir sr gl =
then errorstrm Pp.(str "Rewriting impacts evars")
else errorstrm Pp.(str "Dependent type error in rewrite of "
++ pr_constr_env (pf_env gl) (project gl) (Term.mkNamedLambda pattern_id (EConstr.Unsafe.to_constr rdxt) (EConstr.Unsafe.to_constr cl)))
- | CErrors.UserError _ as e -> raise e
- | e -> anomaly ("cvtac's exception: " ^ Printexc.to_string e);
in
tclTHEN cvtac' rwtac gl
@@ -436,7 +437,7 @@ let lz_setoid_relation =
| env', srel when env' == env -> srel
| _ ->
let srel =
- try Some (Universes.constr_of_global @@
+ try Some (UnivGen.constr_of_global @@
Coqlib.coq_reference "Class_setoid" sdir "RewriteRelation")
with _ -> None in
last_srel := (env, srel); srel
@@ -479,11 +480,11 @@ let rwprocess_rule dir rule gl =
| _ -> let ra = Array.append a [|r|] in
function 1 ->
let sigma, pi1 = Evd.fresh_global env sigma coq_prod.Coqlib.proj1 in
- EConstr.mkApp (EConstr.of_constr pi1, ra), sigma
+ EConstr.mkApp (pi1, ra), sigma
| _ ->
let sigma, pi2 = Evd.fresh_global env sigma coq_prod.Coqlib.proj2 in
- EConstr.mkApp (EConstr.of_constr pi2, ra), sigma in
- if EConstr.eq_constr sigma a.(0) (EConstr.of_constr (Universes.constr_of_global @@ Coqlib.build_coq_True ())) then
+ EConstr.mkApp (pi2, ra), sigma in
+ if EConstr.eq_constr sigma a.(0) (EConstr.of_constr (UnivGen.constr_of_global @@ Coqlib.build_coq_True ())) then
let s, sigma = sr sigma 2 in
loop (converse_dir d) sigma s a.(1) rs 0
else
@@ -558,7 +559,7 @@ let rwrxtac occ rdx_pat dir rule gl =
let rpat env sigma0 (sigma, pats) (d, r, lhs, rhs) =
let sigma, pat =
let rw_progress rhs t evd = rw_progress rhs (EConstr.of_constr t) evd in
- mk_tpattern env sigma0 (sigma,EConstr.to_constr sigma r) (rw_progress rhs) d (EConstr.to_constr sigma lhs) in
+ mk_tpattern env sigma0 (sigma, EConstr.to_constr ~abort_on_undefined_evars:false sigma r) (rw_progress rhs) d (EConstr.to_constr ~abort_on_undefined_evars:false sigma lhs) in
sigma, pats @ [pat] in
let rpats = List.fold_left (rpat env0 sigma0) (r_sigma,[]) rules in
let find_R, end_R = mk_tpattern_matcher sigma0 occ ~upats_origin rpats in
@@ -568,7 +569,7 @@ let rwrxtac occ rdx_pat dir rule gl =
let r = ref None in
(fun env c _ h -> do_once r (fun () -> find_rule (EConstr.of_constr c), c); mkRel h),
(fun concl -> closed0_check concl e gl;
- let (d,(ev,ctx,c)) , x = assert_done r in (d,(ev,ctx, EConstr.to_constr ev c)) , x) in
+ let (d,(ev,ctx,c)) , x = assert_done r in (d,(ev,ctx, EConstr.to_constr ~abort_on_undefined_evars:false ev c)) , x) in
let concl0 = EConstr.Unsafe.to_constr concl0 in
let concl = eval_pattern env0 sigma0 concl0 rdx_pat occ find_R in
let (d, r), rdx = conclude concl in
@@ -590,7 +591,10 @@ let ssrinstancesofrule ist dir arg gl =
let rpat env sigma0 (sigma, pats) (d, r, lhs, rhs) =
let sigma, pat =
let rw_progress rhs t evd = rw_progress rhs (EConstr.of_constr t) evd in
- mk_tpattern env sigma0 (sigma,EConstr.to_constr sigma r) (rw_progress rhs) d (EConstr.to_constr sigma lhs) in
+ mk_tpattern env sigma0
+ (sigma,EConstr.to_constr ~abort_on_undefined_evars:false sigma r)
+ (rw_progress rhs) d
+ (EConstr.to_constr ~abort_on_undefined_evars:false sigma lhs) in
sigma, pats @ [pat] in
let rpats = List.fold_left (rpat env0 sigma0) (r_sigma,[]) rules in
mk_tpattern_matcher ~all_instances:true ~raise_NoMatch:true sigma0 None ~upats_origin rpats in
diff --git a/plugins/ssr/ssrfun.v b/plugins/ssr/ssrfun.v
index ac2c7824..4810c6e1 100644
--- a/plugins/ssr/ssrfun.v
+++ b/plugins/ssr/ssrfun.v
@@ -10,207 +10,210 @@
(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *)
+(** #<style> .doc { font-family: monospace; white-space: pre; } </style># **)
+
Require Import ssreflect.
-(******************************************************************************)
-(* This file contains the basic definitions and notations for working with *)
-(* functions. The definitions provide for: *)
-(* *)
-(* - Pair projections: *)
-(* p.1 == first element of a pair *)
-(* p.2 == second element of a pair *)
-(* These notations also apply to p : P /\ Q, via an and >-> pair coercion. *)
-(* *)
-(* - Simplifying functions, beta-reduced by /= and simpl: *)
-(* [fun : T => E] == constant function from type T that returns E *)
-(* [fun x => E] == unary function *)
-(* [fun x : T => E] == unary function with explicit domain type *)
-(* [fun x y => E] == binary function *)
-(* [fun x y : T => E] == binary function with common domain type *)
-(* [fun (x : T) y => E] \ *)
-(* [fun (x : xT) (y : yT) => E] | == binary function with (some) explicit, *)
-(* [fun x (y : T) => E] / independent domain types for each argument *)
-(* *)
-(* - Partial functions using option type: *)
-(* oapp f d ox == if ox is Some x returns f x, d otherwise *)
-(* odflt d ox == if ox is Some x returns x, d otherwise *)
-(* obind f ox == if ox is Some x returns f x, None otherwise *)
-(* omap f ox == if ox is Some x returns Some (f x), None otherwise *)
-(* *)
-(* - Singleton types: *)
-(* all_equal_to x0 == x0 is the only value in its type, so any such value *)
-(* can be rewritten to x0. *)
-(* *)
-(* - A generic wrapper type: *)
-(* wrapped T == the inductive type with values Wrap x for x : T. *)
-(* unwrap w == the projection of w : wrapped T on T. *)
-(* wrap x == the canonical injection of x : T into wrapped T; it is *)
-(* equivalent to Wrap x, but is declared as a (default) *)
-(* Canonical Structure, which lets the Coq HO unification *)
-(* automatically expand x into unwrap (wrap x). The delta *)
-(* reduction of wrap x to Wrap can be exploited to *)
-(* introduce controlled nondeterminism in Canonical *)
-(* Structure inference, as in the implementation of *)
-(* the mxdirect predicate in matrix.v. *)
-(* *)
-(* - Sigma types: *)
-(* tag w == the i of w : {i : I & T i}. *)
-(* tagged w == the T i component of w : {i : I & T i}. *)
-(* Tagged T x == the {i : I & T i} with component x : T i. *)
-(* tag2 w == the i of w : {i : I & T i & U i}. *)
-(* tagged2 w == the T i component of w : {i : I & T i & U i}. *)
-(* tagged2' w == the U i component of w : {i : I & T i & U i}. *)
-(* Tagged2 T U x y == the {i : I & T i} with components x : T i and y : U i. *)
-(* sval u == the x of u : {x : T | P x}. *)
-(* s2val u == the x of u : {x : T | P x & Q x}. *)
-(* The properties of sval u, s2val u are given by lemmas svalP, s2valP, and *)
-(* s2valP'. We provide coercions sigT2 >-> sigT and sig2 >-> sig >-> sigT. *)
-(* A suite of lemmas (all_sig, ...) let us skolemize sig, sig2, sigT, sigT2 *)
-(* and pair, e.g., *)
-(* have /all_sig[f fP] (x : T): {y : U | P y} by ... *)
-(* yields an f : T -> U such that fP : forall x, P (f x). *)
-(* - Identity functions: *)
-(* id == NOTATION for the explicit identity function fun x => x. *)
-(* @id T == notation for the explicit identity at type T. *)
-(* idfun == an expression with a head constant, convertible to id; *)
-(* idfun x simplifies to x. *)
-(* @idfun T == the expression above, specialized to type T. *)
-(* phant_id x y == the function type phantom _ x -> phantom _ y. *)
-(* *** In addition to their casual use in functional programming, identity *)
-(* functions are often used to trigger static unification as part of the *)
-(* construction of dependent Records and Structures. For example, if we need *)
-(* a structure sT over a type T, we take as arguments T, sT, and a "dummy" *)
-(* function T -> sort sT: *)
-(* Definition foo T sT & T -> sort sT := ... *)
-(* We can avoid specifying sT directly by calling foo (@id T), or specify *)
-(* the call completely while still ensuring the consistency of T and sT, by *)
-(* calling @foo T sT idfun. The phant_id type allows us to extend this trick *)
-(* to non-Type canonical projections. It also allows us to sidestep *)
-(* dependent type constraints when building explicit records, e.g., given *)
-(* Record r := R {x; y : T(x)}. *)
-(* if we need to build an r from a given y0 while inferring some x0, such *)
-(* that y0 : T(x0), we pose *)
-(* Definition mk_r .. y .. (x := ...) y' & phant_id y y' := R x y'. *)
-(* Calling @mk_r .. y0 .. id will cause Coq to use y' := y0, while checking *)
-(* the dependent type constraint y0 : T(x0). *)
-(* *)
-(* - Extensional equality for functions and relations (i.e. functions of two *)
-(* arguments): *)
-(* f1 =1 f2 == f1 x is equal to f2 x for all x. *)
-(* f1 =1 f2 :> A == ... and f2 is explicitly typed. *)
-(* f1 =2 f2 == f1 x y is equal to f2 x y for all x y. *)
-(* f1 =2 f2 :> A == ... and f2 is explicitly typed. *)
-(* *)
-(* - Composition for total and partial functions: *)
-(* f^~ y == function f with second argument specialised to y, *)
-(* i.e., fun x => f x y *)
-(* CAVEAT: conditional (non-maximal) implicit arguments *)
-(* of f are NOT inserted in this context *)
-(* @^~ x == application at x, i.e., fun f => f x *)
-(* [eta f] == the explicit eta-expansion of f, i.e., fun x => f x *)
-(* CAVEAT: conditional (non-maximal) implicit arguments *)
-(* of f are NOT inserted in this context. *)
-(* fun=> v := the constant function fun _ => v. *)
-(* f1 \o f2 == composition of f1 and f2. *)
-(* Note: (f1 \o f2) x simplifies to f1 (f2 x). *)
-(* f1 \; f2 == categorical composition of f1 and f2. This expands to *)
-(* to f2 \o f1 and (f1 \; f2) x simplifies to f2 (f1 x). *)
-(* pcomp f1 f2 == composition of partial functions f1 and f2. *)
-(* *)
-(* *)
-(* - Properties of functions: *)
-(* injective f <-> f is injective. *)
-(* cancel f g <-> g is a left inverse of f / f is a right inverse of g. *)
-(* pcancel f g <-> g is a left inverse of f where g is partial. *)
-(* ocancel f g <-> g is a left inverse of f where f is partial. *)
-(* bijective f <-> f is bijective (has a left and right inverse). *)
-(* involutive f <-> f is involutive. *)
-(* *)
-(* - Properties for operations. *)
-(* left_id e op <-> e is a left identity for op (e op x = x). *)
-(* right_id e op <-> e is a right identity for op (x op e = x). *)
-(* left_inverse e inv op <-> inv is a left inverse for op wrt identity e, *)
-(* i.e., (inv x) op x = e. *)
-(* right_inverse e inv op <-> inv is a right inverse for op wrt identity e *)
-(* i.e., x op (i x) = e. *)
-(* self_inverse e op <-> each x is its own op-inverse (x op x = e). *)
-(* idempotent op <-> op is idempotent for op (x op x = x). *)
-(* associative op <-> op is associative, i.e., *)
-(* x op (y op z) = (x op y) op z. *)
-(* commutative op <-> op is commutative (x op y = y op x). *)
-(* left_commutative op <-> op is left commutative, i.e., *)
-(* x op (y op z) = y op (x op z). *)
-(* right_commutative op <-> op is right commutative, i.e., *)
-(* (x op y) op z = (x op z) op y. *)
-(* left_zero z op <-> z is a left zero for op (z op x = z). *)
-(* right_zero z op <-> z is a right zero for op (x op z = z). *)
-(* left_distributive op1 op2 <-> op1 distributes over op2 to the left: *)
-(* (x op2 y) op1 z = (x op1 z) op2 (y op1 z). *)
-(* right_distributive op1 op2 <-> op distributes over add to the right: *)
-(* x op1 (y op2 z) = (x op1 z) op2 (x op1 z). *)
-(* interchange op1 op2 <-> op1 and op2 satisfy an interchange law: *)
-(* (x op2 y) op1 (z op2 t) = (x op1 z) op2 (y op1 t). *)
-(* Note that interchange op op is a commutativity property. *)
-(* left_injective op <-> op is injective in its left argument: *)
-(* x op y = z op y -> x = z. *)
-(* right_injective op <-> op is injective in its right argument: *)
-(* x op y = x op z -> y = z. *)
-(* left_loop inv op <-> op, inv obey the inverse loop left axiom: *)
-(* (inv x) op (x op y) = y for all x, y, i.e., *)
-(* op (inv x) is always a left inverse of op x *)
-(* rev_left_loop inv op <-> op, inv obey the inverse loop reverse left *)
-(* axiom: x op ((inv x) op y) = y, for all x, y. *)
-(* right_loop inv op <-> op, inv obey the inverse loop right axiom: *)
-(* (x op y) op (inv y) = x for all x, y. *)
-(* rev_right_loop inv op <-> op, inv obey the inverse loop reverse right *)
-(* axiom: (x op y) op (inv y) = x for all x, y. *)
-(* Note that familiar "cancellation" identities like x + y - y = x or *)
-(* x - y + y = x are respectively instances of right_loop and rev_right_loop *)
-(* The corresponding lemmas will use the K and NK/VK suffixes, respectively. *)
-(* *)
-(* - Morphisms for functions and relations: *)
-(* {morph f : x / a >-> r} <-> f is a morphism with respect to functions *)
-(* (fun x => a) and (fun x => r); if r == R[x], *)
-(* this states that f a = R[f x] for all x. *)
-(* {morph f : x / a} <-> f is a morphism with respect to the *)
-(* function expression (fun x => a). This is *)
-(* shorthand for {morph f : x / a >-> a}; note *)
-(* that the two instances of a are often *)
-(* interpreted at different types. *)
-(* {morph f : x y / a >-> r} <-> f is a morphism with respect to functions *)
-(* (fun x y => a) and (fun x y => r). *)
-(* {morph f : x y / a} <-> f is a morphism with respect to the *)
-(* function expression (fun x y => a). *)
-(* {homo f : x / a >-> r} <-> f is a homomorphism with respect to the *)
-(* predicates (fun x => a) and (fun x => r); *)
-(* if r == R[x], this states that a -> R[f x] *)
-(* for all x. *)
-(* {homo f : x / a} <-> f is a homomorphism with respect to the *)
-(* predicate expression (fun x => a). *)
-(* {homo f : x y / a >-> r} <-> f is a homomorphism with respect to the *)
-(* relations (fun x y => a) and (fun x y => r). *)
-(* {homo f : x y / a} <-> f is a homomorphism with respect to the *)
-(* relation expression (fun x y => a). *)
-(* {mono f : x / a >-> r} <-> f is monotone with respect to projectors *)
-(* (fun x => a) and (fun x => r); if r == R[x], *)
-(* this states that R[f x] = a for all x. *)
-(* {mono f : x / a} <-> f is monotone with respect to the projector *)
-(* expression (fun x => a). *)
-(* {mono f : x y / a >-> r} <-> f is monotone with respect to relators *)
-(* (fun x y => a) and (fun x y => r). *)
-(* {mono f : x y / a} <-> f is monotone with respect to the relator *)
-(* expression (fun x y => a). *)
-(* *)
-(* The file also contains some basic lemmas for the above concepts. *)
-(* Lemmas relative to cancellation laws use some abbreviated suffixes: *)
-(* K - a cancellation rule like esymK : cancel (@esym T x y) (@esym T y x). *)
-(* LR - a lemma moving an operation from the left hand side of a relation to *)
-(* the right hand side, like canLR: cancel g f -> x = g y -> f x = y. *)
-(* RL - a lemma moving an operation from the right to the left, e.g., canRL. *)
-(* Beware that the LR and RL orientations refer to an "apply" (back chaining) *)
-(* usage; when using the same lemmas with "have" or "move" (forward chaining) *)
-(* the directions will be reversed!. *)
-(******************************************************************************)
+
+(**
+ This file contains the basic definitions and notations for working with
+ functions. The definitions provide for:
+
+ - Pair projections:
+ p.1 == first element of a pair
+ p.2 == second element of a pair
+ These notations also apply to p : P /\ Q, via an and >-> pair coercion.
+
+ - Simplifying functions, beta-reduced by /= and simpl:
+ #[#fun : T => E#]# == constant function from type T that returns E
+ #[#fun x => E#]# == unary function
+ #[#fun x : T => E#]# == unary function with explicit domain type
+ #[#fun x y => E#]# == binary function
+ #[#fun x y : T => E#]# == binary function with common domain type
+ #[#fun (x : T) y => E#]# \
+ #[#fun (x : xT) (y : yT) => E#]# | == binary function with (some) explicit,
+ #[#fun x (y : T) => E#]# / independent domain types for each argument
+
+ - Partial functions using option type:
+ oapp f d ox == if ox is Some x returns f x, d otherwise
+ odflt d ox == if ox is Some x returns x, d otherwise
+ obind f ox == if ox is Some x returns f x, None otherwise
+ omap f ox == if ox is Some x returns Some (f x), None otherwise
+
+ - Singleton types:
+ all_equal_to x0 == x0 is the only value in its type, so any such value
+ can be rewritten to x0.
+
+ - A generic wrapper type:
+ wrapped T == the inductive type with values Wrap x for x : T.
+ unwrap w == the projection of w : wrapped T on T.
+ wrap x == the canonical injection of x : T into wrapped T; it is
+ equivalent to Wrap x, but is declared as a (default)
+ Canonical Structure, which lets the Coq HO unification
+ automatically expand x into unwrap (wrap x). The delta
+ reduction of wrap x to Wrap can be exploited to
+ introduce controlled nondeterminism in Canonical
+ Structure inference, as in the implementation of
+ the mxdirect predicate in matrix.v.
+
+ - Sigma types:
+ tag w == the i of w : {i : I & T i}.
+ tagged w == the T i component of w : {i : I & T i}.
+ Tagged T x == the {i : I & T i} with component x : T i.
+ tag2 w == the i of w : {i : I & T i & U i}.
+ tagged2 w == the T i component of w : {i : I & T i & U i}.
+ tagged2' w == the U i component of w : {i : I & T i & U i}.
+ Tagged2 T U x y == the {i : I & T i} with components x : T i and y : U i.
+ sval u == the x of u : {x : T | P x}.
+ s2val u == the x of u : {x : T | P x & Q x}.
+ The properties of sval u, s2val u are given by lemmas svalP, s2valP, and
+ s2valP'. We provide coercions sigT2 >-> sigT and sig2 >-> sig >-> sigT.
+ A suite of lemmas (all_sig, ...) let us skolemize sig, sig2, sigT, sigT2
+ and pair, e.g.,
+ have /all_sig#[#f fP#]# (x : T): {y : U | P y} by ...
+ yields an f : T -> U such that fP : forall x, P (f x).
+ - Identity functions:
+ id == NOTATION for the explicit identity function fun x => x.
+ @id T == notation for the explicit identity at type T.
+ idfun == an expression with a head constant, convertible to id;
+ idfun x simplifies to x.
+ @idfun T == the expression above, specialized to type T.
+ phant_id x y == the function type phantom _ x -> phantom _ y.
+ *** In addition to their casual use in functional programming, identity
+ functions are often used to trigger static unification as part of the
+ construction of dependent Records and Structures. For example, if we need
+ a structure sT over a type T, we take as arguments T, sT, and a "dummy"
+ function T -> sort sT:
+ Definition foo T sT & T -> sort sT := ...
+ We can avoid specifying sT directly by calling foo (@id T), or specify
+ the call completely while still ensuring the consistency of T and sT, by
+ calling @foo T sT idfun. The phant_id type allows us to extend this trick
+ to non-Type canonical projections. It also allows us to sidestep
+ dependent type constraints when building explicit records, e.g., given
+ Record r := R {x; y : T(x)}.
+ if we need to build an r from a given y0 while inferring some x0, such
+ that y0 : T(x0), we pose
+ Definition mk_r .. y .. (x := ...) y' & phant_id y y' := R x y'.
+ Calling @mk_r .. y0 .. id will cause Coq to use y' := y0, while checking
+ the dependent type constraint y0 : T(x0).
+
+ - Extensional equality for functions and relations (i.e. functions of two
+ arguments):
+ f1 =1 f2 == f1 x is equal to f2 x for all x.
+ f1 =1 f2 :> A == ... and f2 is explicitly typed.
+ f1 =2 f2 == f1 x y is equal to f2 x y for all x y.
+ f1 =2 f2 :> A == ... and f2 is explicitly typed.
+
+ - Composition for total and partial functions:
+ f^~ y == function f with second argument specialised to y,
+ i.e., fun x => f x y
+ CAVEAT: conditional (non-maximal) implicit arguments
+ of f are NOT inserted in this context
+ @^~ x == application at x, i.e., fun f => f x
+ #[#eta f#]# == the explicit eta-expansion of f, i.e., fun x => f x
+ CAVEAT: conditional (non-maximal) implicit arguments
+ of f are NOT inserted in this context.
+ fun=> v := the constant function fun _ => v.
+ f1 \o f2 == composition of f1 and f2.
+ Note: (f1 \o f2) x simplifies to f1 (f2 x).
+ f1 \; f2 == categorical composition of f1 and f2. This expands to
+ to f2 \o f1 and (f1 \; f2) x simplifies to f2 (f1 x).
+ pcomp f1 f2 == composition of partial functions f1 and f2.
+
+
+ - Properties of functions:
+ injective f <-> f is injective.
+ cancel f g <-> g is a left inverse of f / f is a right inverse of g.
+ pcancel f g <-> g is a left inverse of f where g is partial.
+ ocancel f g <-> g is a left inverse of f where f is partial.
+ bijective f <-> f is bijective (has a left and right inverse).
+ involutive f <-> f is involutive.
+
+ - Properties for operations.
+ left_id e op <-> e is a left identity for op (e op x = x).
+ right_id e op <-> e is a right identity for op (x op e = x).
+ left_inverse e inv op <-> inv is a left inverse for op wrt identity e,
+ i.e., (inv x) op x = e.
+ right_inverse e inv op <-> inv is a right inverse for op wrt identity e
+ i.e., x op (i x) = e.
+ self_inverse e op <-> each x is its own op-inverse (x op x = e).
+ idempotent op <-> op is idempotent for op (x op x = x).
+ associative op <-> op is associative, i.e.,
+ x op (y op z) = (x op y) op z.
+ commutative op <-> op is commutative (x op y = y op x).
+ left_commutative op <-> op is left commutative, i.e.,
+ x op (y op z) = y op (x op z).
+ right_commutative op <-> op is right commutative, i.e.,
+ (x op y) op z = (x op z) op y.
+ left_zero z op <-> z is a left zero for op (z op x = z).
+ right_zero z op <-> z is a right zero for op (x op z = z).
+ left_distributive op1 op2 <-> op1 distributes over op2 to the left:
+ (x op2 y) op1 z = (x op1 z) op2 (y op1 z).
+ right_distributive op1 op2 <-> op distributes over add to the right:
+ x op1 (y op2 z) = (x op1 z) op2 (x op1 z).
+ interchange op1 op2 <-> op1 and op2 satisfy an interchange law:
+ (x op2 y) op1 (z op2 t) = (x op1 z) op2 (y op1 t).
+ Note that interchange op op is a commutativity property.
+ left_injective op <-> op is injective in its left argument:
+ x op y = z op y -> x = z.
+ right_injective op <-> op is injective in its right argument:
+ x op y = x op z -> y = z.
+ left_loop inv op <-> op, inv obey the inverse loop left axiom:
+ (inv x) op (x op y) = y for all x, y, i.e.,
+ op (inv x) is always a left inverse of op x
+ rev_left_loop inv op <-> op, inv obey the inverse loop reverse left
+ axiom: x op ((inv x) op y) = y, for all x, y.
+ right_loop inv op <-> op, inv obey the inverse loop right axiom:
+ (x op y) op (inv y) = x for all x, y.
+ rev_right_loop inv op <-> op, inv obey the inverse loop reverse right
+ axiom: (x op y) op (inv y) = x for all x, y.
+ Note that familiar "cancellation" identities like x + y - y = x or
+ x - y + y = x are respectively instances of right_loop and rev_right_loop
+ The corresponding lemmas will use the K and NK/VK suffixes, respectively.
+
+ - Morphisms for functions and relations:
+ {morph f : x / a >-> r} <-> f is a morphism with respect to functions
+ (fun x => a) and (fun x => r); if r == R#[#x#]#,
+ this states that f a = R#[#f x#]# for all x.
+ {morph f : x / a} <-> f is a morphism with respect to the
+ function expression (fun x => a). This is
+ shorthand for {morph f : x / a >-> a}; note
+ that the two instances of a are often
+ interpreted at different types.
+ {morph f : x y / a >-> r} <-> f is a morphism with respect to functions
+ (fun x y => a) and (fun x y => r).
+ {morph f : x y / a} <-> f is a morphism with respect to the
+ function expression (fun x y => a).
+ {homo f : x / a >-> r} <-> f is a homomorphism with respect to the
+ predicates (fun x => a) and (fun x => r);
+ if r == R#[#x#]#, this states that a -> R#[#f x#]#
+ for all x.
+ {homo f : x / a} <-> f is a homomorphism with respect to the
+ predicate expression (fun x => a).
+ {homo f : x y / a >-> r} <-> f is a homomorphism with respect to the
+ relations (fun x y => a) and (fun x y => r).
+ {homo f : x y / a} <-> f is a homomorphism with respect to the
+ relation expression (fun x y => a).
+ {mono f : x / a >-> r} <-> f is monotone with respect to projectors
+ (fun x => a) and (fun x => r); if r == R#[#x#]#,
+ this states that R#[#f x#]# = a for all x.
+ {mono f : x / a} <-> f is monotone with respect to the projector
+ expression (fun x => a).
+ {mono f : x y / a >-> r} <-> f is monotone with respect to relators
+ (fun x y => a) and (fun x y => r).
+ {mono f : x y / a} <-> f is monotone with respect to the relator
+ expression (fun x y => a).
+
+ The file also contains some basic lemmas for the above concepts.
+ Lemmas relative to cancellation laws use some abbreviated suffixes:
+ K - a cancellation rule like esymK : cancel (@esym T x y) (@esym T y x).
+ LR - a lemma moving an operation from the left hand side of a relation to
+ the right hand side, like canLR: cancel g f -> x = g y -> f x = y.
+ RL - a lemma moving an operation from the right to the left, e.g., canRL.
+ Beware that the LR and RL orientations refer to an "apply" (back chaining)
+ usage; when using the same lemmas with "have" or "move" (forward chaining)
+ the directions will be reversed!. **)
+
Set Implicit Arguments.
Unset Strict Implicit.
@@ -219,7 +222,7 @@ Unset Printing Implicit Defensive.
Delimit Scope fun_scope with FUN.
Open Scope fun_scope.
-(* Notations for argument transpose *)
+(** Notations for argument transpose **)
Notation "f ^~ y" := (fun x => f x y)
(at level 10, y at level 8, no associativity, format "f ^~ y") : fun_scope.
Notation "@^~ x" := (fun f => f x)
@@ -228,7 +231,7 @@ Notation "@^~ x" := (fun f => f x)
Delimit Scope pair_scope with PAIR.
Open Scope pair_scope.
-(* Notations for pair/conjunction projections *)
+(** Notations for pair/conjunction projections **)
Notation "p .1" := (fst p)
(at level 2, left associativity, format "p .1") : pair_scope.
Notation "p .2" := (snd p)
@@ -239,8 +242,9 @@ Coercion pair_of_and P Q (PandQ : P /\ Q) := (proj1 PandQ, proj2 PandQ).
Definition all_pair I T U (w : forall i : I, T i * U i) :=
(fun i => (w i).1, fun i => (w i).2).
-(* Complements on the option type constructor, used below to *)
-(* encode partial functions. *)
+(**
+ Complements on the option type constructor, used below to
+ encode partial functions. **)
Module Option.
@@ -260,7 +264,7 @@ Notation obind := Option.bind.
Notation omap := Option.map.
Notation some := (@Some _) (only parsing).
-(* Shorthand for some basic equality lemmas. *)
+(** Shorthand for some basic equality lemmas. **)
Notation erefl := refl_equal.
Notation ecast i T e x := (let: erefl in _ = i := e return T in x).
@@ -269,31 +273,32 @@ Definition nesym := sym_not_eq.
Definition etrans := trans_eq.
Definition congr1 := f_equal.
Definition congr2 := f_equal2.
-(* Force at least one implicit when used as a view. *)
+(** Force at least one implicit when used as a view. **)
Prenex Implicits esym nesym.
-(* A predicate for singleton types. *)
+(** A predicate for singleton types. **)
Definition all_equal_to T (x0 : T) := forall x, unkeyed x = x0.
Lemma unitE : all_equal_to tt. Proof. by case. Qed.
-(* A generic wrapper type *)
+(** A generic wrapper type **)
Structure wrapped T := Wrap {unwrap : T}.
Canonical wrap T x := @Wrap T x.
Prenex Implicits unwrap wrap Wrap.
-(* Syntax for defining auxiliary recursive function. *)
-(* Usage: *)
-(* Section FooDefinition. *)
-(* Variables (g1 : T1) (g2 : T2). (globals) *)
-(* Fixoint foo_auxiliary (a3 : T3) ... := *)
-(* body, using [rec e3, ...] for recursive calls *)
-(* where "[ 'rec' a3 , a4 , ... ]" := foo_auxiliary. *)
-(* Definition foo x y .. := [rec e1, ...]. *)
-(* + proofs about foo *)
-(* End FooDefinition. *)
+(**
+ Syntax for defining auxiliary recursive function.
+ Usage:
+ Section FooDefinition.
+ Variables (g1 : T1) (g2 : T2). (globals)
+ Fixoint foo_auxiliary (a3 : T3) ... :=
+ body, using #[#rec e3, ... #]# for recursive calls
+ where " #[# 'rec' a3 , a4 , ... #]#" := foo_auxiliary.
+ Definition foo x y .. := #[#rec e1, ... #]#.
+ + proofs about foo
+ End FooDefinition. **)
Reserved Notation "[ 'rec' a0 ]"
(at level 0, format "[ 'rec' a0 ]").
@@ -319,14 +324,15 @@ Reserved Notation "[ 'rec' a0 , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ]"
(at level 0,
format "[ 'rec' a0 , a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 ]").
-(* Definitions and notation for explicit functions with simplification, *)
-(* i.e., which simpl and /= beta expand (this is complementary to nosimpl). *)
+(**
+ Definitions and notation for explicit functions with simplification,
+ i.e., which simpl and /= beta expand (this is complementary to nosimpl). **)
Section SimplFun.
Variables aT rT : Type.
-CoInductive simpl_fun := SimplFun of aT -> rT.
+Variant simpl_fun := SimplFun of aT -> rT.
Definition fun_of_simpl f := fun x => let: SimplFun lam := f in lam x.
@@ -362,11 +368,12 @@ Notation "[ 'fun' ( x : xT ) ( y : yT ) => E ]" :=
(fun x : xT => [fun y : yT => E])
(at level 0, x ident, y ident, only parsing) : fun_scope.
-(* For delta functions in eqtype.v. *)
+(** For delta functions in eqtype.v. **)
Definition SimplFunDelta aT rT (f : aT -> aT -> rT) := [fun z => f z z].
-(* Extensional equality, for unary and binary functions, including syntactic *)
-(* sugar. *)
+(**
+ Extensional equality, for unary and binary functions, including syntactic
+ sugar. **)
Section ExtensionalEquality.
@@ -439,7 +446,7 @@ Notation "@ 'idfun' T " := (@id_head T explicit_id_key)
Definition phant_id T1 T2 v1 v2 := phantom T1 v1 -> phantom T2 v2.
-(* Strong sigma types. *)
+(** Strong sigma types. **)
Section Tag.
@@ -473,9 +480,9 @@ Lemma all_tag2 I T U V :
{f : forall i, T i & forall i, U i (f i) & forall i, V i (f i)}.
Proof. by case/all_tag=> f /all_pair[]; exists f. Qed.
-(* Refinement types. *)
+(** Refinement types. **)
-(* Prenex Implicits and renaming. *)
+(** Prenex Implicits and renaming. **)
Notation sval := (@proj1_sig _ _).
Notation "@ 'sval'" := (@proj1_sig) (at level 10, format "@ 'sval'").
@@ -514,16 +521,16 @@ Section Morphism.
Variables (aT rT sT : Type) (f : aT -> rT).
-(* Morphism property for unary and binary functions *)
+(** Morphism property for unary and binary functions **)
Definition morphism_1 aF rF := forall x, f (aF x) = rF (f x).
Definition morphism_2 aOp rOp := forall x y, f (aOp x y) = rOp (f x) (f y).
-(* Homomorphism property for unary and binary relations *)
+(** Homomorphism property for unary and binary relations **)
Definition homomorphism_1 (aP rP : _ -> Prop) := forall x, aP x -> rP (f x).
Definition homomorphism_2 (aR rR : _ -> _ -> Prop) :=
forall x y, aR x y -> rR (f x) (f y).
-(* Stability property for unary and binary relations *)
+(** Stability property for unary and binary relations **)
Definition monomorphism_1 (aP rP : _ -> sT) := forall x, rP (f x) = aP x.
Definition monomorphism_2 (aR rR : _ -> _ -> sT) :=
forall x y, rR (f x) (f y) = aR x y.
@@ -600,16 +607,18 @@ Notation "{ 'mono' f : x y /~ a }" :=
(at level 0, f at level 99, x ident, y ident,
format "{ 'mono' f : x y /~ a }") : type_scope.
-(* In an intuitionistic setting, we have two degrees of injectivity. The *)
-(* weaker one gives only simplification, and the strong one provides a left *)
-(* inverse (we show in `fintype' that they coincide for finite types). *)
-(* We also define an intermediate version where the left inverse is only a *)
-(* partial function. *)
+(**
+ In an intuitionistic setting, we have two degrees of injectivity. The
+ weaker one gives only simplification, and the strong one provides a left
+ inverse (we show in `fintype' that they coincide for finite types).
+ We also define an intermediate version where the left inverse is only a
+ partial function. **)
Section Injections.
-(* rT must come first so we can use @ to mitigate the Coq 1st order *)
-(* unification bug (e..g., Coq can't infer rT from a "cancel" lemma). *)
+(**
+ rT must come first so we can use @ to mitigate the Coq 1st order
+ unification bug (e..g., Coq can't infer rT from a "cancel" lemma). **)
Variables (rT aT : Type) (f : aT -> rT).
Definition injective := forall x1 x2, f x1 = f x2 -> x1 = x2.
@@ -639,10 +648,10 @@ End Injections.
Lemma Some_inj {T} : injective (@Some T). Proof. by move=> x y []. Qed.
-(* Force implicits to use as a view. *)
+(** Force implicits to use as a view. **)
Prenex Implicits Some_inj.
-(* cancellation lemmas for dependent type casts. *)
+(** cancellation lemmas for dependent type casts. **)
Lemma esymK T x y : cancel (@esym T x y) (@esym T y x).
Proof. by case: y /. Qed.
@@ -684,7 +693,7 @@ Section Bijections.
Variables (A B : Type) (f : B -> A).
-CoInductive bijective : Prop := Bijective g of cancel f g & cancel g f.
+Variant bijective : Prop := Bijective g of cancel f g & cancel g f.
Hypothesis bijf : bijective.
diff --git a/plugins/ssr/ssrfwd.ml b/plugins/ssr/ssrfwd.ml
index a5765feb..e367cd32 100644
--- a/plugins/ssr/ssrfwd.ml
+++ b/plugins/ssr/ssrfwd.ml
@@ -68,25 +68,18 @@ open Ssripats
let ssrhaveNOtcresolution = Summary.ref ~name:"SSR:havenotcresolution" false
-let inHaveTCResolution = Libobject.declare_object {
- (Libobject.default_object "SSRHAVETCRESOLUTION") with
- Libobject.cache_function = (fun (_,v) -> ssrhaveNOtcresolution := v);
- Libobject.load_function = (fun _ (_,v) -> ssrhaveNOtcresolution := v);
- Libobject.classify_function = (fun v -> Libobject.Keep v);
-}
let _ =
Goptions.declare_bool_option
{ Goptions.optname = "have type classes";
Goptions.optkey = ["SsrHave";"NoTCResolution"];
Goptions.optread = (fun _ -> !ssrhaveNOtcresolution);
Goptions.optdepr = false;
- Goptions.optwrite = (fun b ->
- Lib.add_anonymous_leaf (inHaveTCResolution b)) }
+ Goptions.optwrite = (fun b -> ssrhaveNOtcresolution := b);
+ }
open Constrexpr
open Glob_term
-open Misctypes
let combineCG t1 t2 f g = match t1, t2 with
| (x, (t1, None)), (_, (t2, None)) -> x, (g t1 t2, None)
@@ -184,9 +177,7 @@ let havetac ist
let gs =
List.map (fun (_,a) ->
Ssripats.Internal.pf_find_abstract_proof false gl (EConstr.Unsafe.to_constr a.(1))) skols_args in
- let tacopen_skols gl =
- let stuff, g = Refiner.unpackage gl in
- Refiner.repackage stuff (gs @ [g]) in
+ let tacopen_skols gl = re_sig (gs @ [gl.Evd.it]) gl.Evd.sigma in
let gl, ty = pf_e_type_of gl t in
gl, ty, Proofview.V82.of_tactic (Tactics.apply t), id,
Tacticals.tclTHEN (Tacticals.tclTHEN itac_c simpltac)
diff --git a/plugins/ssr/ssripats.ml b/plugins/ssr/ssripats.ml
index 35036b6c..37dd00a7 100644
--- a/plugins/ssr/ssripats.ml
+++ b/plugins/ssr/ssripats.ml
@@ -12,6 +12,7 @@ open Ssrmatching_plugin
open Util
open Names
+open Constr
open Proofview
open Proofview.Notations
@@ -90,11 +91,11 @@ open State
(** Warning: unlike [nb_deps_assums], it does not perform reduction *)
let rec nb_assums cur env sigma t =
match EConstr.kind sigma t with
- | Term.Prod(name,ty,body) ->
+ | Prod(name,ty,body) ->
nb_assums (cur+1) env sigma body
- | Term.LetIn(name,ty,t1,t2) ->
+ | LetIn(name,ty,t1,t2) ->
nb_assums (cur+1) env sigma t2
- | Term.Cast(t,_,_) ->
+ | Cast(t,_,_) ->
nb_assums cur env sigma t
| _ -> cur
let nb_assums = nb_assums 0
@@ -118,13 +119,10 @@ let intro_end =
Ssrcommon.tcl0G (isCLR_CONSUME)
(** [=> _] *****************************************************************)
-let intro_clear ids future_ipats =
+let intro_clear ids =
Goal.enter begin fun gl ->
let _, clear_ids, ren =
List.fold_left (fun (used_ids, clear_ids, ren) id ->
- if not(Ssrcommon.is_name_in_ipats id future_ipats) then begin
- used_ids, id :: clear_ids, ren
- end else
let new_id = Ssrcommon.mk_anon_id (Id.to_string id) used_ids in
(new_id :: used_ids, new_id :: clear_ids, (id, new_id) :: ren))
(Tacmach.New.pf_ids_of_hyps gl, [], []) ids
@@ -212,22 +210,25 @@ let tclLOG p t =
tclUNIT ()
end
-let rec ipat_tac1 future_ipats ipat : unit tactic =
+let rec ipat_tac1 ipat : unit tactic =
match ipat with
- | IPatView l ->
- Ssrview.tclIPAT_VIEWS ~views:l
- ~conclusion:(fun ~to_clear:clr -> intro_clear clr future_ipats)
- | IPatDispatch ipatss ->
- tclEXTEND (List.map (ipat_tac future_ipats) ipatss) (tclUNIT ()) []
+ | IPatView (clear_if_id,l) ->
+ Ssrview.tclIPAT_VIEWS ~views:l ~clear_if_id
+ ~conclusion:(fun ~to_clear:clr -> intro_clear clr)
+
+ | IPatDispatch(true,[[]]) ->
+ tclUNIT ()
+ | IPatDispatch(_,ipatss) ->
+ tclDISPATCH (List.map ipat_tac ipatss)
| IPatId id -> Ssrcommon.tclINTRO_ID id
| IPatCase ipatss ->
- tclIORPAT (Ssrcommon.tclWITHTOP tac_case) future_ipats ipatss
+ tclIORPAT (Ssrcommon.tclWITHTOP tac_case) ipatss
| IPatInj ipatss ->
tclIORPAT (Ssrcommon.tclWITHTOP
(fun t -> V82.tactic ~nf_evars:false (Ssrelim.perform_injection t)))
- future_ipats ipatss
+ ipatss
| IPatAnon Drop -> intro_drop
| IPatAnon One -> Ssrcommon.tclINTRO_ANON
@@ -238,7 +239,7 @@ let rec ipat_tac1 future_ipats ipat : unit tactic =
| IPatClear ids ->
tacCHECK_HYPS_EXIST ids <*>
- intro_clear (List.map Ssrcommon.hyp_id ids) future_ipats
+ intro_clear (List.map Ssrcommon.hyp_id ids)
| IPatSimpl (Simpl n) ->
V82.tactic ~nf_evars:false (Ssrequality.simpltac (Simpl n))
@@ -255,17 +256,17 @@ let rec ipat_tac1 future_ipats ipat : unit tactic =
| IPatTac t -> t
-and ipat_tac future_ipats pl : unit tactic =
+and ipat_tac pl : unit tactic =
match pl with
| [] -> tclUNIT ()
| pat :: pl ->
- Ssrcommon.tcl0G (tclLOG pat (ipat_tac1 (pl @ future_ipats))) <*>
+ Ssrcommon.tcl0G (tclLOG pat ipat_tac1) <*>
isTICK pat <*>
- ipat_tac future_ipats pl
+ ipat_tac pl
-and tclIORPAT tac future_ipats = function
+and tclIORPAT tac = function
| [[]] -> tac
- | p -> Tacticals.New.tclTHENS tac (List.map (ipat_tac future_ipats) p)
+ | p -> Tacticals.New.tclTHENS tac (List.map ipat_tac p)
let split_at_first_case ipats =
let rec loop acc = function
@@ -276,17 +277,32 @@ let split_at_first_case ipats =
loop [] ipats
let ssr_exception is_on = function
- | Some (IPatCase l) when is_on -> Some (IPatDispatch l)
+ | Some (IPatCase l) when is_on -> Some (IPatDispatch(true, l))
| x -> x
let option_to_list = function None -> [] | Some x -> [x]
+(* Simple pass doing {x}/v -> /v{x} *)
+let elaborate_ipats l =
+ let rec elab = function
+ | [] -> []
+ | (IPatClear _ as p1) :: (IPatView _ as p2) :: rest -> p2 :: p1 :: elab rest
+ | IPatDispatch(s,p) :: rest -> IPatDispatch (s,List.map elab p) :: elab rest
+ | IPatCase p :: rest -> IPatCase (List.map elab p) :: elab rest
+ | IPatInj p :: rest -> IPatInj (List.map elab p) :: elab rest
+ | (IPatTac _ | IPatId _ | IPatSimpl _ | IPatClear _ |
+ IPatAnon _ | IPatView _ | IPatNoop | IPatRewrite _ |
+ IPatAbstractVars _) as x :: rest -> x :: elab rest
+ in
+ elab l
+
let main ?eqtac ~first_case_is_dispatch ipats =
+ let ipats = elaborate_ipats ipats in
let ip_before, case, ip_after = split_at_first_case ipats in
let case = ssr_exception first_case_is_dispatch case in
let case = option_to_list case in
let eqtac = option_to_list (Option.map (fun x -> IPatTac x) eqtac) in
- Ssrcommon.tcl0G (ipat_tac [] (ip_before @ case @ eqtac @ ip_after) <*> intro_end)
+ Ssrcommon.tcl0G (ipat_tac (ip_before @ case @ eqtac @ ip_after) <*> intro_end)
end (* }}} *)
@@ -366,8 +382,9 @@ let elim_intro_tac ipats ?ist what eqid ssrelim is_rec clr =
let ctx, last = EConstr.decompose_prod_assum sigma concl in
let args = match EConstr.kind_of_type sigma last with
| Term.AtomicType (hd, args) ->
- assert(Ssrcommon.is_protect hd env sigma);
- args
+ if Ssrcommon.is_protect hd env sigma then args
+ else Ssrcommon.errorstrm
+ (Pp.str "Too many names in intro pattern")
| _ -> assert false in
let case = args.(Array.length args-1) in
if not(EConstr.Vars.closed0 sigma case)
@@ -419,7 +436,7 @@ let tclLAST_GEN ~to_ind ((oclr, occ), t) conclusion = tclINDEPENDENTL begin
Goal.enter_one begin fun g ->
let pat = Ssrmatching.interp_cpattern sigma0 t None in
let cl0, env, sigma, hyps = Goal.(concl g, env g, sigma g, hyps g) in
- let cl = EConstr.to_constr sigma cl0 in
+ let cl = EConstr.to_constr ~abort_on_undefined_evars:false sigma cl0 in
let (c, ucst), cl =
try Ssrmatching.fill_occ_pattern ~raise_NoMatch:true env sigma cl pat occ 1
with Ssrmatching.NoMatch -> Ssrmatching.redex_of_pattern env pat, cl in
@@ -556,7 +573,7 @@ let rec eqmoveipats eqpat = function
let ssrsmovetac = Goal.enter begin fun g ->
let sigma, concl = Goal.(sigma g, concl g) in
match EConstr.kind sigma concl with
- | Term.Prod _ | Term.LetIn _ -> tclUNIT ()
+ | Prod _ | LetIn _ -> tclUNIT ()
| _ -> Tactics.hnf_in_concl
end
@@ -575,7 +592,7 @@ let ssrmovetac = function
(tacVIEW_THEN_GRAB view ~conclusion) <*>
tclIPAT (IPatClear clr :: ipats)
| _::_ as view, (_, ({ gens = []; clr }, ipats)) ->
- tclIPAT (IPatView view :: IPatClear clr :: ipats)
+ tclIPAT (IPatView (false,view) :: IPatClear clr :: ipats)
| _, (Some pat, (dgens, ipats)) ->
let dgentac = with_dgens dgens eqmovetac in
dgentac <*> tclIPAT (eqmoveipats pat ipats)
@@ -594,8 +611,8 @@ let rec is_Evar_or_CastedMeta sigma x =
let occur_existential_or_casted_meta sigma c =
let rec occrec c = match EConstr.kind sigma c with
- | Term.Evar _ -> raise Not_found
- | Term.Cast (m,_,_) when EConstr.isMeta sigma m -> raise Not_found
+ | Evar _ -> raise Not_found
+ | Cast (m,_,_) when EConstr.isMeta sigma m -> raise Not_found
| _ -> EConstr.iter sigma occrec c
in
try occrec c; false
@@ -624,8 +641,8 @@ let tacFIND_ABSTRACT_PROOF check_lock abstract_n =
Goal.enter_one ~__LOC__ begin fun g ->
let sigma, env = Goal.(sigma g, env g) in
let l = Evd.fold_undefined (fun e ei l ->
- match EConstr.kind sigma (EConstr.of_constr ei.Evd.evar_concl) with
- | Term.App(hd, [|ty; n; lock|])
+ match EConstr.kind sigma ei.Evd.evar_concl with
+ | App(hd, [|ty; n; lock|])
when (not check_lock ||
(occur_existential_or_casted_meta sigma ty &&
is_Evar_or_CastedMeta sigma lock)) &&
@@ -654,8 +671,8 @@ let ssrabstract dgens =
let sigma, env, concl = Goal.(sigma g, env g, concl g) in
let t = args_id.(0) in
match EConstr.kind sigma t with
- | (Term.Evar _ | Term.Meta _) -> Ssrcommon.tacUNIFY concl t <*> tclUNIT id
- | Term.Cast(m,_,_)
+ | (Evar _ | Meta _) -> Ssrcommon.tacUNIFY concl t <*> tclUNIT id
+ | Cast(m,_,_)
when EConstr.isEvar sigma m || EConstr.isMeta sigma m ->
Ssrcommon.tacUNIFY concl t <*> tclUNIT id
| _ ->
diff --git a/plugins/ssr/ssrparser.ml4 b/plugins/ssr/ssrparser.ml4
index 5f396744..eb69dca9 100644
--- a/plugins/ssr/ssrparser.ml4
+++ b/plugins/ssr/ssrparser.ml4
@@ -10,6 +10,7 @@
(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *)
+let _vmcast = Constr.VMcast
open Names
open Pp
open Pcoq
@@ -17,18 +18,19 @@ open Ltac_plugin
open Genarg
open Stdarg
open Tacarg
-open Term
open Libnames
open Tactics
open Tacmach
open Util
+open Locus
open Tacexpr
open Tacinterp
open Pltac
open Extraargs
open Ppconstr
-open Misctypes
+open Namegen
+open Tactypes
open Decl_kinds
open Constrexpr
open Constrexpr_ops
@@ -64,7 +66,7 @@ DECLARE PLUGIN "ssreflect_plugin"
* we thus save the lexer to restore it at the end of the file *)
let frozen_lexer = CLexer.get_keyword_state () ;;
-let tacltop = (5,Notation_term.E)
+let tacltop = (5,Notation_gram.E)
let pr_ssrtacarg _ _ prt = prt tacltop
ARGUMENT EXTEND ssrtacarg TYPED AS tactic PRINTED BY pr_ssrtacarg
@@ -301,24 +303,24 @@ END
let pr_index = function
- | Misctypes.ArgVar {CAst.v=id} -> pr_id id
- | Misctypes.ArgArg n when n > 0 -> int n
+ | ArgVar {CAst.v=id} -> pr_id id
+ | ArgArg n when n > 0 -> int n
| _ -> mt ()
let pr_ssrindex _ _ _ = pr_index
-let noindex = Misctypes.ArgArg 0
+let noindex = ArgArg 0
let check_index ?loc i =
if i > 0 then i else CErrors.user_err ?loc (str"Index not positive")
let mk_index ?loc = function
- | Misctypes.ArgArg i -> Misctypes.ArgArg (check_index ?loc i)
+ | ArgArg i -> ArgArg (check_index ?loc i)
| iv -> iv
let interp_index ist gl idx =
Tacmach.project gl,
match idx with
- | Misctypes.ArgArg _ -> idx
- | Misctypes.ArgVar id ->
+ | ArgArg _ -> idx
+ | ArgVar id ->
let i =
try
let v = Id.Map.find id.CAst.v ist.Tacinterp.lfun in
@@ -336,7 +338,7 @@ let interp_index ist gl idx =
| None -> raise Not_found
end end
with _ -> CErrors.user_err ?loc:id.CAst.loc (str"Index not a number") in
- Misctypes.ArgArg (check_index ?loc:id.CAst.loc i)
+ ArgArg (check_index ?loc:id.CAst.loc i)
open Pltac
@@ -410,8 +412,8 @@ let pr_docc = function
let pr_ssrdocc _ _ _ = pr_docc
ARGUMENT EXTEND ssrdocc TYPED AS ssrclear option * ssrocc PRINTED BY pr_ssrdocc
-| [ "{" ne_ssrhyp_list(clr) "}" ] -> [ mkclr clr ]
| [ "{" ssrocc(occ) "}" ] -> [ mkocc occ ]
+| [ "{" ssrhyp_list(clr) "}" ] -> [ mkclr clr ]
END
(* Old kinds of terms *)
@@ -543,7 +545,7 @@ END
let remove_loc x = x.CAst.v
-let ipat_of_intro_pattern p = Misctypes.(
+let ipat_of_intro_pattern p = Tactypes.(
let rec ipat_of_intro_pattern = function
| IntroNaming (IntroIdentifier id) -> IPatId id
| IntroAction IntroWildcard -> IPatAnon Drop
@@ -574,9 +576,9 @@ let rec map_ipat map_id map_ssrhyp map_ast_closure_term = function
| IPatAbstractVars l -> IPatAbstractVars (List.map map_id l)
| IPatClear clr -> IPatClear (List.map map_ssrhyp clr)
| IPatCase iorpat -> IPatCase (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat)
- | IPatDispatch iorpat -> IPatDispatch (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat)
+ | IPatDispatch (s,iorpat) -> IPatDispatch (s,List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat)
| IPatInj iorpat -> IPatInj (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat)
- | IPatView v -> IPatView (List.map map_ast_closure_term v)
+ | IPatView (clr,v) -> IPatView (clr,List.map map_ast_closure_term v)
| IPatTac _ -> assert false (*internal usage only *)
let wit_ssripatrep = add_genarg "ssripatrep" pr_ipat
@@ -595,16 +597,15 @@ let intern_ipats ist = List.map (intern_ipat ist)
let interp_intro_pattern = interp_wit wit_intro_pattern
-let interp_introid ist gl id = Misctypes.(
+let interp_introid ist gl id =
try IntroNaming (IntroIdentifier (hyp_id (snd (interp_hyp ist gl (SsrHyp (Loc.tag id))))))
with _ -> (snd (interp_intro_pattern ist gl (CAst.make @@ IntroNaming (IntroIdentifier id)))).CAst.v
-)
let get_intro_id = function
| IntroNaming (IntroIdentifier id) -> id
| _ -> assert false
-let rec add_intro_pattern_hyps ipat hyps = Misctypes.(
+let rec add_intro_pattern_hyps ipat hyps =
let {CAst.loc=loc;v=ipat} = ipat in
match ipat with
| IntroNaming (IntroIdentifier id) ->
@@ -623,7 +624,6 @@ let rec add_intro_pattern_hyps ipat hyps = Misctypes.(
| IntroForthcoming _ ->
(* As in ipat_of_intro_pattern, was unable to determine which kind
of ipat interp_introid could return [HH] *) assert false
-)
(* We interp the ipat using the standard ltac machinery for ids, since
* we have no clue what a name could be bound to (maybe another ipat) *)
@@ -641,12 +641,12 @@ let interp_ipat ist gl =
check_hyps_uniq [] clr'; IPatClear clr'
| IPatCase(iorpat) ->
IPatCase(List.map (List.map interp) iorpat)
- | IPatDispatch(iorpat) ->
- IPatDispatch(List.map (List.map interp) iorpat)
+ | IPatDispatch(s,iorpat) ->
+ IPatDispatch(s,List.map (List.map interp) iorpat)
| IPatInj iorpat -> IPatInj (List.map (List.map interp) iorpat)
| IPatAbstractVars l ->
IPatAbstractVars (List.map get_intro_id (List.map (interp_introid ist gl) l))
- | IPatView l -> IPatView (List.map (fun x -> snd(interp_ast_closure_term ist
+ | IPatView (clr,l) -> IPatView (clr,List.map (fun x -> snd(interp_ast_closure_term ist
gl x)) l)
| (IPatSimpl _ | IPatAnon _ | IPatRewrite _ | IPatNoop) as x -> x
| IPatTac _ -> assert false (*internal usage only *)
@@ -683,11 +683,17 @@ ARGUMENT EXTEND ssripat TYPED AS ssripatrep list PRINTED BY pr_ssripats
(* TODO | [ "+" ] -> [ [IPatAnon Temporary] ] *)
| [ ssrsimpl_ne(sim) ] -> [ [IPatSimpl sim] ]
| [ ssrdocc(occ) "->" ] -> [ match occ with
+ | Some [], _ -> CErrors.user_err ~loc (str"occ_switch expected")
| None, occ -> [IPatRewrite (occ, L2R)]
| Some clr, _ -> [IPatClear clr; IPatRewrite (allocc, L2R)]]
| [ ssrdocc(occ) "<-" ] -> [ match occ with
+ | Some [], _ -> CErrors.user_err ~loc (str"occ_switch expected")
| None, occ -> [IPatRewrite (occ, R2L)]
| Some clr, _ -> [IPatClear clr; IPatRewrite (allocc, R2L)]]
+ | [ ssrdocc(occ) ssrfwdview(v) ] -> [ match occ with
+ | Some [], _ -> [IPatView (true,v)]
+ | Some cl, _ -> check_hyps_uniq [] cl; [IPatClear cl;IPatView (false,v)]
+ | _ -> CErrors.user_err ~loc (str"Only identifiers are allowed here") ]
| [ ssrdocc(occ) ] -> [ match occ with
| Some cl, _ -> check_hyps_uniq [] cl; [IPatClear cl]
| _ -> CErrors.user_err ~loc (str"Only identifiers are allowed here")]
@@ -705,7 +711,7 @@ ARGUMENT EXTEND ssripat TYPED AS ssripatrep list PRINTED BY pr_ssripats
| [ "-/" integer(n) "/=" ] -> [ [IPatNoop;IPatSimpl(SimplCut (n,~-1))] ]
| [ "-/" integer(n) "/" integer (m) "=" ] ->
[ [IPatNoop;IPatSimpl(SimplCut(n,m))] ]
- | [ ssrfwdview(v) ] -> [ [IPatView v] ]
+ | [ ssrfwdview(v) ] -> [ [IPatView (false,v)] ]
| [ "[" ":" ident_list(idl) "]" ] -> [ [IPatAbstractVars idl] ]
| [ "[:" ident_list(idl) "]" ] -> [ [IPatAbstractVars idl] ]
END
@@ -956,6 +962,7 @@ END
(* the default simpl and unfold tactics would erase blindly. *)
open Ssrmatching_plugin.Ssrmatching
+open Ssrmatching_plugin.G_ssrmatching
let pr_wgen = function
| (clr, Some((id,k),None)) -> spc() ++ pr_clear mt clr ++ str k ++ pr_hoi id
@@ -1064,7 +1071,7 @@ let rec format_constr_expr h0 c0 = let open CAst in match h0, c0 with
| BFdef :: h, { v = CLetIn({CAst.v=x}, v, oty, c) } ->
let bs, c' = format_constr_expr h c in
Bdef (x, oty, v) :: bs, c'
- | [BFcast], { v = CCast (c, CastConv t) } ->
+ | [BFcast], { v = CCast (c, Glob_term.CastConv t) } ->
[Bcast t], c
| BFrec (has_str, has_cast) :: h,
{ v = CFix ( _, [_, (Some locn, CStructRec), bl, t, c]) } ->
@@ -1093,7 +1100,7 @@ let wit_ssrfwdfmt = add_genarg "ssrfwdfmt" pr_fwdfmt
let mkFwdVal fk c = ((fk, []), c)
let mkssrFwdVal fk c = ((fk, []), (c,None))
-let dC t = CastConv t
+let dC t = Glob_term.CastConv t
let same_ist { interp_env = x } { interp_env = y } =
match x,y with
@@ -1154,7 +1161,8 @@ ARGUMENT EXTEND ssrbvar TYPED AS constr PRINTED BY pr_ssrbvar
END
let bvar_lname = let open CAst in function
- | { v = CRef ({loc;v=Ident id}, _) } -> CAst.make ?loc @@ Name id
+ | { v = CRef (qid, _) } when qualid_is_ident qid ->
+ CAst.make ?loc:qid.CAst.loc @@ Name (qualid_basename qid)
| { loc = loc } -> CAst.make ?loc Anonymous
let pr_ssrbinder prc _ _ (_, c) = prc c
@@ -1210,8 +1218,8 @@ let push_binders c2 bs =
| [] -> c
| _ -> anomaly "binder not a lambda nor a let in" in
match c2 with
- | { loc; v = CCast (ct, CastConv cty) } ->
- CAst.make ?loc @@ (CCast (loop false ct bs, CastConv (loop true cty bs)))
+ | { loc; v = CCast (ct, Glob_term.CastConv cty) } ->
+ CAst.make ?loc @@ (CCast (loop false ct bs, Glob_term.CastConv (loop true cty bs)))
| ct -> loop false ct bs
let rec fix_binders = let open CAst in function
@@ -1246,7 +1254,8 @@ END
let pr_ssrfixfwd _ _ _ (id, fwd) = str " fix " ++ pr_id id ++ pr_fwd fwd
let bvar_locid = function
- | { CAst.v = CRef ({CAst.loc=loc;v=Ident id}, _) } -> CAst.make ?loc id
+ | { CAst.v = CRef (qid, _) } when qualid_is_ident qid ->
+ CAst.make ?loc:qid.CAst.loc (qualid_basename qid)
| _ -> CErrors.user_err (Pp.str "Missing identifier after \"(co)fix\"")
@@ -1399,7 +1408,7 @@ let check_seqtacarg dir arg = match snd arg, dir with
CErrors.user_err ?loc (str "expected \"first\"")
| _, _ -> arg
-let ssrorelse = Gram.entry_create "ssrorelse"
+let ssrorelse = Entry.create "ssrorelse"
GEXTEND Gram
GLOBAL: ssrorelse ssrseqarg;
ssrseqidx: [
@@ -1676,7 +1685,10 @@ let pr_gen (docc, dt) = pr_docc docc ++ pr_cpattern dt
let pr_ssrgen _ _ _ = pr_gen
ARGUMENT EXTEND ssrgen TYPED AS ssrdocc * cpattern PRINTED BY pr_ssrgen
-| [ ssrdocc(docc) cpattern(dt) ] -> [ docc, dt ]
+| [ ssrdocc(docc) cpattern(dt) ] -> [
+ match docc with
+ | Some [], _ -> CErrors.user_err ~loc (str"Clear flag {} not allowed here")
+ | _ -> docc, dt ]
| [ cpattern(dt) ] -> [ nodocc, dt ]
END
@@ -1938,7 +1950,7 @@ END
let vmexacttac pf =
Goal.nf_enter begin fun gl ->
- exact_no_check (EConstr.mkCast (pf, VMcast, Tacmach.New.pf_concl gl))
+ exact_no_check (EConstr.mkCast (pf, _vmcast, Tacmach.New.pf_concl gl))
end
TACTIC EXTEND ssrexact
diff --git a/plugins/ssr/ssrparser.mli b/plugins/ssr/ssrparser.mli
index 2ac7c7e2..862a9376 100644
--- a/plugins/ssr/ssrparser.mli
+++ b/plugins/ssr/ssrparser.mli
@@ -12,13 +12,13 @@
open Ltac_plugin
-val ssrtacarg : Tacexpr.raw_tactic_expr Pcoq.Gram.entry
+val ssrtacarg : Tacexpr.raw_tactic_expr Pcoq.Entry.t
val wit_ssrtacarg : (Tacexpr.raw_tactic_expr, Tacexpr.glob_tactic_expr, Geninterp.Val.t) Genarg.genarg_type
-val pr_ssrtacarg : 'a -> 'b -> (Notation_term.tolerability -> 'c) -> 'c
+val pr_ssrtacarg : 'a -> 'b -> (Notation_gram.tolerability -> 'c) -> 'c
-val ssrtclarg : Tacexpr.raw_tactic_expr Pcoq.Gram.entry
+val ssrtclarg : Tacexpr.raw_tactic_expr Pcoq.Entry.t
val wit_ssrtclarg : (Tacexpr.raw_tactic_expr, Tacexpr.glob_tactic_expr, Geninterp.Val.t) Genarg.genarg_type
-val pr_ssrtclarg : 'a -> 'b -> (Notation_term.tolerability -> 'c -> 'd) -> 'c -> 'd
+val pr_ssrtclarg : 'a -> 'b -> (Notation_gram.tolerability -> 'c -> 'd) -> 'c -> 'd
val add_genarg : string -> ('a -> Pp.t) -> 'a Genarg.uniform_genarg_type
diff --git a/plugins/ssr/ssrprinters.ml b/plugins/ssr/ssrprinters.ml
index 11369228..824666ba 100644
--- a/plugins/ssr/ssrprinters.ml
+++ b/plugins/ssr/ssrprinters.ml
@@ -101,13 +101,14 @@ let rec pr_ipat p =
| IPatSimpl sim -> pr_simpl sim
| IPatClear clr -> pr_clear mt clr
| IPatCase iorpat -> hov 1 (str "[" ++ pr_iorpat iorpat ++ str "]")
- | IPatDispatch iorpat -> hov 1 (str "/[" ++ pr_iorpat iorpat ++ str "]")
+ | IPatDispatch(_,iorpat) -> hov 1 (str "/[" ++ pr_iorpat iorpat ++ str "]")
| IPatInj iorpat -> hov 1 (str "[=" ++ pr_iorpat iorpat ++ str "]")
| IPatRewrite (occ, dir) -> pr_occ occ ++ pr_dir dir
| IPatAnon All -> str "*"
| IPatAnon Drop -> str "_"
| IPatAnon One -> str "?"
- | IPatView v -> pr_view2 v
+ | IPatView (false,v) -> pr_view2 v
+ | IPatView (true,v) -> str"{}" ++ pr_view2 v
| IPatNoop -> str "-"
| IPatAbstractVars l -> str "[:" ++ pr_list spc Id.print l ++ str "]"
| IPatTac _ -> str "<tac>"
diff --git a/plugins/ssr/ssrtacticals.ml b/plugins/ssr/ssrtacticals.ml
index 9cc4f5ce..83581f34 100644
--- a/plugins/ssr/ssrtacticals.ml
+++ b/plugins/ssr/ssrtacticals.ml
@@ -11,9 +11,9 @@
(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *)
open Names
+open Constr
open Termops
open Tacmach
-open Misctypes
open Locusops
open Ssrast
@@ -24,7 +24,7 @@ module NamedDecl = Context.Named.Declaration
(** Tacticals (+, -, *, done, by, do, =>, first, and last). *)
-let get_index = function ArgArg i -> i | _ ->
+let get_index = function Locus.ArgArg i -> i | _ ->
anomaly "Uninterpreted index"
(* Toplevel constr must be globalized twice ! *)
@@ -32,9 +32,8 @@ let get_index = function ArgArg i -> i | _ ->
let tclPERM perm tac gls =
let subgls = tac gls in
- let sigma, subgll = Refiner.unpackage subgls in
- let subgll' = perm subgll in
- Refiner.repackage sigma subgll'
+ let subgll' = perm subgls.Evd.it in
+ re_sig subgll' subgls.Evd.sigma
let rot_hyps dir i hyps =
let n = List.length hyps in
@@ -104,10 +103,10 @@ let endclausestac id_map clseq gl_id cl0 gl =
| ids, dc' ->
forced && ids = [] && (not hide_goal || dc' = [] && c_hidden) in
let rec unmark c = match EConstr.kind (project gl) c with
- | Term.Var id when hidden_clseq clseq && id = gl_id -> cl0
- | Term.Prod (Name id, t, c') when List.mem_assoc id id_map ->
+ | Var id when hidden_clseq clseq && id = gl_id -> cl0
+ | Prod (Name id, t, c') when List.mem_assoc id id_map ->
EConstr.mkProd (Name (orig_id id), unmark t, unmark c')
- | Term.LetIn (Name id, v, t, c') when List.mem_assoc id id_map ->
+ | LetIn (Name id, v, t, c') when List.mem_assoc id id_map ->
EConstr.mkLetIn (Name (orig_id id), unmark v, unmark t, unmark c')
| _ -> EConstr.map (project gl) unmark c in
let utac hyp =
diff --git a/plugins/ssr/ssrtacticals.mli b/plugins/ssr/ssrtacticals.mli
index a5636ad0..684e0023 100644
--- a/plugins/ssr/ssrtacticals.mli
+++ b/plugins/ssr/ssrtacticals.mli
@@ -17,7 +17,7 @@ val tclSEQAT :
Tacinterp.interp_sign ->
Tacinterp.Value.t ->
Ssrast.ssrdir ->
- int Misctypes.or_var *
+ int Locus.or_var *
(('a * Tacinterp.Value.t option list) *
Tacinterp.Value.t option) ->
Tacmach.tactic
@@ -37,7 +37,7 @@ val hinttac :
val ssrdotac :
Tacinterp.interp_sign ->
- ((int Misctypes.or_var * Ssrast.ssrmmod) *
+ ((int Locus.or_var * Ssrast.ssrmmod) *
(bool * Tacinterp.Value.t option list)) *
((Ssrast.ssrhyps *
((Ssrast.ssrhyp_or_id * string) *
diff --git a/plugins/ssr/ssrvernac.ml4 b/plugins/ssr/ssrvernac.ml4
index 05dbf0a8..989a6c5b 100644
--- a/plugins/ssr/ssrvernac.ml4
+++ b/plugins/ssr/ssrvernac.ml4
@@ -19,17 +19,14 @@ open Constrexpr_ops
open Pcoq
open Pcoq.Prim
open Pcoq.Constr
-open Pcoq.Vernac_
+open Pvernac.Vernac_
open Ltac_plugin
open Notation_ops
open Notation_term
open Glob_term
-open Globnames
open Stdarg
open Genarg
-open Misctypes
open Decl_kinds
-open Libnames
open Pp
open Ppconstr
open Printer
@@ -144,21 +141,21 @@ END
let declare_one_prenex_implicit locality f =
let fref =
try Smartlocate.global_with_alias f
- with _ -> errorstrm (pr_reference f ++ str " is not declared") in
+ with _ -> errorstrm (pr_qualid f ++ str " is not declared") in
let rec loop = function
| a :: args' when Impargs.is_status_implicit a ->
(ExplByName (Impargs.name_of_implicit a), (true, true, true)) :: loop args'
| args' when List.exists Impargs.is_status_implicit args' ->
- errorstrm (str "Expected prenex implicits for " ++ pr_reference f)
+ errorstrm (str "Expected prenex implicits for " ++ pr_qualid f)
| _ -> [] in
let impls =
match Impargs.implicits_of_global fref with
| [cond,impls] -> impls
- | [] -> errorstrm (str "Expected some implicits for " ++ pr_reference f)
+ | [] -> errorstrm (str "Expected some implicits for " ++ pr_qualid f)
| _ -> errorstrm (str "Multiple implicits not supported") in
match loop impls with
| [] ->
- errorstrm (str "Expected some implicits for " ++ pr_reference f)
+ errorstrm (str "Expected some implicits for " ++ pr_qualid f)
| impls ->
Impargs.declare_manual_implicits locality fref ~enriching:false [impls]
@@ -220,8 +217,8 @@ let interp_search_notation ?loc tag okey =
(Bytes.set s' i' '_'; loop (j + 1) (i' + 2))
else (String.blit s i s' i' m; loop (j + 1) (i' + m + 1)) in
loop 0 1 in
- let trim_ntn (pntn, m) = Bytes.sub_string pntn 1 (max 0 m) in
- let pr_ntn ntn = str "(" ++ str ntn ++ str ")" in
+ let trim_ntn (pntn, m) = (InConstrEntrySomeLevel,Bytes.sub_string pntn 1 (max 0 m)) in
+ let pr_ntn ntn = str "(" ++ Notation.pr_notation ntn ++ str ")" in
let pr_and_list pr = function
| [x] -> pr x
| x :: lx -> pr_list pr_comma pr lx ++ pr_comma () ++ str "and " ++ pr x
@@ -296,7 +293,7 @@ let interp_search_notation ?loc tag okey =
let scs' = List.remove (=) sc !scs in
let w = pr_ntn ntn ++ str " is also defined " ++ pr_scs scs' in
Feedback.msg_warning (hov 4 w)
- else if String.string_contains ~where:ntn ~what:" .. " then
+ else if String.string_contains ~where:(snd ntn) ~what:" .. " then
err (pr_ntn ntn ++ str " is an n-ary notation");
let nvars = List.filter (fun (_,(_,typ)) -> typ = NtnTypeConstr) nvars in
let rec sub () = function
@@ -361,13 +358,12 @@ let coerce_search_pattern_to_sort hpat =
true, cp
with _ -> false, [] in
let coerce hp coe_index =
- let coe = Classops.get_coercion_value coe_index in
+ let coe_ref = coe_index.Classops.coe_value in
try
- let coe_ref = global_of_constr coe in
let n_imps = Option.get (Classops.hide_coercion coe_ref) in
mkPApp (Pattern.PRef coe_ref) n_imps [|hp|]
- with _ ->
- errorstrm (str "need explicit coercion " ++ pr_constr_env env sigma coe ++ spc ()
+ with Not_found | Option.IsNone ->
+ errorstrm (str "need explicit coercion " ++ pr_global coe_ref ++ spc ()
++ str "to interpret head search pattern as type") in
filter_head, List.fold_left coerce hpat' coe_path
@@ -377,7 +373,10 @@ let interp_head_pat hpat =
| Cast (c', _, _) -> loop c'
| Prod (_, _, c') -> loop c'
| LetIn (_, _, _, c') -> loop c'
- | _ -> Constr_matching.is_matching (Global.env()) Evd.empty p (EConstr.of_constr c) in
+ | _ ->
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ Constr_matching.is_matching env sigma p (EConstr.of_constr c) in
filter_head, loop
let all_true _ = true
@@ -413,7 +412,7 @@ let interp_search_arg arg =
(* Module path postfilter *)
-let pr_modloc (b, m) = if b then str "-" ++ pr_reference m else pr_reference m
+let pr_modloc (b, m) = if b then str "-" ++ pr_qualid m else pr_qualid m
let wit_ssrmodloc = add_genarg "ssrmodloc" pr_modloc
@@ -431,10 +430,9 @@ GEXTEND Gram
END
let interp_modloc mr =
- let interp_mod (_, mr) =
- let {CAst.loc=loc; v=qid} = qualid_of_reference mr in
+ let interp_mod (_, qid) =
try Nametab.full_name_module qid with Not_found ->
- CErrors.user_err ?loc (str "No Module " ++ pr_qualid qid) in
+ CErrors.user_err ?loc:qid.CAst.loc (str "No Module " ++ pr_qualid qid) in
let mr_out, mr_in = List.partition fst mr in
let interp_bmod b = function
| [] -> fun _ _ _ -> true
diff --git a/plugins/ssr/ssrview.ml b/plugins/ssr/ssrview.ml
index aa614fbc..3f974ea0 100644
--- a/plugins/ssr/ssrview.ml
+++ b/plugins/ssr/ssrview.ml
@@ -67,9 +67,9 @@ end
module State : sig
(* View storage API *)
- val vsINIT : EConstr.t -> unit tactic
- val vsPUSH : (EConstr.t -> EConstr.t tactic) -> unit tactic
- val vsCONSUME : (Id.t option -> EConstr.t -> unit tactic) -> unit tactic
+ val vsINIT : EConstr.t * Id.t list -> unit tactic
+ val vsPUSH : (EConstr.t -> (EConstr.t * Id.t list) tactic) -> unit tactic
+ val vsCONSUME : (name:Id.t option -> EConstr.t -> to_clear:Id.t list -> unit tactic) -> unit tactic
val vsASSERT_EMPTY : unit tactic
end = struct (* {{{ *)
@@ -78,6 +78,7 @@ type vstate = {
subject_name : Id.t option; (* top *)
(* None if views are being applied to a term *)
view : EConstr.t; (* v2 (v1 top) *)
+ to_clear : Id.t list;
}
include Ssrcommon.MakeState(struct
@@ -85,13 +86,14 @@ include Ssrcommon.MakeState(struct
let init = None
end)
-let vsINIT view = tclSET (Some { subject_name = None; view })
+let vsINIT (view, to_clear) =
+ tclSET (Some { subject_name = None; view; to_clear })
let vsPUSH k =
tacUPDATE (fun s -> match s with
- | Some { subject_name; view } ->
- k view >>= fun view ->
- tclUNIT (Some { subject_name; view })
+ | Some { subject_name; view; to_clear } ->
+ k view >>= fun (view, clr) ->
+ tclUNIT (Some { subject_name; view; to_clear = to_clear @ clr })
| None ->
Goal.enter_one ~__LOC__ begin fun gl ->
let concl = Goal.concl gl in
@@ -102,15 +104,15 @@ let vsPUSH k =
| _ -> mk_anon_id "view_subject" (Tacmach.New.pf_ids_of_hyps gl) in
let view = EConstr.mkVar id in
Ssrcommon.tclINTRO_ID id <*>
- k view >>= fun view ->
- tclUNIT (Some { subject_name = Some id; view })
+ k view >>= fun (view, to_clear) ->
+ tclUNIT (Some { subject_name = Some id; view; to_clear })
end)
let vsCONSUME k =
tclGET (fun s -> match s with
- | Some { subject_name; view } ->
+ | Some { subject_name; view; to_clear } ->
tclSET None <*>
- k subject_name view
+ k ~name:subject_name view ~to_clear
| None -> anomaly "vsCONSUME: empty storage")
let vsASSERT_EMPTY =
@@ -157,7 +159,7 @@ let tclINJ_CONSTR_IST ist p =
let mkGHole =
DAst.make
- (Glob_term.GHole(Evar_kinds.InternalHole, Misctypes.IntroAnonymous, None))
+ (Glob_term.GHole(Evar_kinds.InternalHole, Namegen.IntroAnonymous, None))
let rec mkGHoles n = if n > 0 then mkGHole :: mkGHoles (n - 1) else []
let mkGApp f args =
if args = [] then f
@@ -187,6 +189,16 @@ end
* modular, see the 2 functions below that would need to "uncommit" *)
let tclKeepOpenConstr (_env, sigma, t) = Unsafe.tclEVARS sigma <*> tclUNIT t
+let tclADD_CLEAR_IF_ID (env, ist, t) x =
+ Ssrprinters.ppdebug (lazy
+ Pp.(str"tclADD_CLEAR_IF_ID: " ++ Printer.pr_econstr_env env ist t));
+ let hd, _ = EConstr.decompose_app ist t in
+ match EConstr.kind ist hd with
+ | Constr.Var id when Ssrcommon.not_section_id id -> tclUNIT (x, [id])
+ | _ -> tclUNIT (x,[])
+
+let tclPAIR p x = tclUNIT (x, p)
+
(* The ssr heuristic : *)
(* Estimate a bound on the number of arguments of a raw constr. *)
(* This is not perfect, because the unifier may fail to *)
@@ -203,14 +215,15 @@ let guess_max_implicits ist glob =
(fun _ -> tclUNIT 5)
let pad_to_inductive ist glob = Goal.enter_one ~__LOC__ begin fun goal ->
- interp_glob ist glob >>= fun (env, sigma, term) ->
+ interp_glob ist glob >>= fun (env, sigma, term as ot) ->
let term_ty = Retyping.get_type_of env sigma term in
let ctx, i = Reductionops.splay_prod env sigma term_ty in
let rel_ctx =
List.map (fun (a,b) -> Context.Rel.Declaration.LocalAssum(a,b)) ctx in
- if Ssrcommon.isAppInd (EConstr.push_rel_context rel_ctx env) sigma i
- then tclUNIT (mkGApp glob (mkGHoles (List.length ctx)))
- else Tacticals.New.tclZEROMSG Pp.(str"not an inductive")
+ if not (Ssrcommon.isAppInd (EConstr.push_rel_context rel_ctx env) sigma i)
+ then Tacticals.New.tclZEROMSG Pp.(str"not an inductive")
+ else tclUNIT (mkGApp glob (mkGHoles (List.length ctx)))
+ >>= tclADD_CLEAR_IF_ID ot
end
(* There are two ways of "applying" a view to term: *)
@@ -221,7 +234,7 @@ end
(* They require guessing the view hints and the number of *)
(* implicits, respectively, which we do by brute force. *)
(* Builds v p *)
-let interp_view ist v p =
+let interp_view ~clear_if_id ist v p =
let is_specialize hd =
match DAst.get hd with Glob_term.GHole _ -> true | _ -> false in
(* We cast the pile of views p into a term p_id *)
@@ -230,42 +243,48 @@ let interp_view ist v p =
match DAst.get v with
| Glob_term.GApp (hd, rargs) when is_specialize hd ->
Ssrprinters.ppdebug (lazy Pp.(str "specialize"));
- interp_glob ist (mkGApp p_id rargs) >>= tclKeepOpenConstr
+ interp_glob ist (mkGApp p_id rargs)
+ >>= tclKeepOpenConstr >>= tclPAIR []
| _ ->
Ssrprinters.ppdebug (lazy Pp.(str "view"));
(* We find out how to build (v p) eventually using an adaptor *)
let adaptors = AdaptorDb.(get Forward) in
Proofview.tclORELSE
- (pad_to_inductive ist v >>= fun vpad ->
+ (pad_to_inductive ist v >>= fun (vpad,clr) ->
Ssrcommon.tclFIRSTa (List.map
- (fun a -> interp_glob ist (mkGApp a [vpad; p_id])) adaptors))
+ (fun a -> interp_glob ist (mkGApp a [vpad; p_id])) adaptors)
+ >>= tclPAIR clr)
(fun _ ->
guess_max_implicits ist v >>= fun n ->
Ssrcommon.tclFIRSTi (fun n ->
- interp_glob ist (mkGApp v (mkGHoles n @ [p_id]))) n)
- >>= tclKeepOpenConstr
+ interp_glob ist (mkGApp v (mkGHoles n @ [p_id]))) n
+ >>= fun x -> tclADD_CLEAR_IF_ID x x)
+ >>= fun (ot,clr) ->
+ if clear_if_id
+ then tclKeepOpenConstr ot >>= tclPAIR clr
+ else tclKeepOpenConstr ot >>= tclPAIR []
(* we store in the state (v top), then (v1 (v2 top))... *)
-let pile_up_view (ist, v) =
+let pile_up_view ~clear_if_id (ist, v) =
let ist = Ssrcommon.option_assert_get ist (Pp.str"not a term") in
- State.vsPUSH (fun p -> interp_view ist v p)
+ State.vsPUSH (fun p -> interp_view ~clear_if_id ist v p)
let finalize_view s0 ?(simple_types=true) p =
Goal.enter_one ~__LOC__ begin fun g ->
let env = Goal.env g in
let sigma = Goal.sigma g in
- let evars_of_p = Evd.evars_of_term (EConstr.to_constr sigma p) in
+ let evars_of_p = Evd.evars_of_term (EConstr.to_constr ~abort_on_undefined_evars:false sigma p) in
let filter x _ = Evar.Set.mem x evars_of_p in
let sigma = Typeclasses.resolve_typeclasses ~fail:false ~filter env sigma in
let p = Reductionops.nf_evar sigma p in
let get_body = function Evd.Evar_defined x -> x | _ -> assert false in
let evars_of_econstr sigma t =
- Evd.evars_of_term (EConstr.to_constr sigma (EConstr.of_constr t)) in
+ Evarutil.undefined_evars_of_term sigma (EConstr.of_constr t) in
let rigid_of s =
List.fold_left (fun l k ->
if Evd.is_defined sigma k then
let bo = get_body Evd.(evar_body (find sigma k)) in
- k :: l @ Evar.Set.elements (evars_of_econstr sigma bo)
+ k :: l @ Evar.Set.elements (evars_of_econstr sigma (EConstr.Unsafe.to_constr bo))
else l
) [] s in
let und0 = (* Unassigned evars in the initial goal *)
@@ -292,7 +311,7 @@ let pose_proof subject_name p =
<*>
Tactics.New.reduce_after_refine
-let rec apply_all_views ending vs s0 =
+let rec apply_all_views ~clear_if_id ending vs s0 =
match vs with
| [] -> ending s0
| v :: vs ->
@@ -301,31 +320,35 @@ let rec apply_all_views ending vs s0 =
| `Tac tac ->
Ssrprinters.ppdebug (lazy Pp.(str"..a tactic"));
ending s0 <*> Tacinterp.eval_tactic tac <*>
- Ssrcommon.tacSIGMA >>= apply_all_views ending vs
+ Ssrcommon.tacSIGMA >>= apply_all_views ~clear_if_id ending vs
| `Term v ->
Ssrprinters.ppdebug (lazy Pp.(str"..a term"));
- pile_up_view v <*> apply_all_views ending vs s0
+ pile_up_view ~clear_if_id v <*>
+ apply_all_views ~clear_if_id ending vs s0
(* Entry points *********************************************************)
-let tclIPAT_VIEWS ~views:vs ~conclusion:tac =
+let tclIPAT_VIEWS ~views:vs ?(clear_if_id=false) ~conclusion:tac =
let end_view_application s0 =
- State.vsCONSUME (fun name t ->
- finalize_view s0 t >>= pose_proof name <*>
- tac ~to_clear:(Option.cata (fun x -> [x]) [] name)) in
+ State.vsCONSUME (fun ~name t ~to_clear ->
+ let to_clear = Option.cata (fun x -> [x]) [] name @ to_clear in
+ finalize_view s0 t >>= pose_proof name <*> tac ~to_clear) in
tclINDEPENDENT begin
State.vsASSERT_EMPTY <*>
- Ssrcommon.tacSIGMA >>= apply_all_views end_view_application vs <*>
+ Ssrcommon.tacSIGMA >>=
+ apply_all_views ~clear_if_id end_view_application vs <*>
State.vsASSERT_EMPTY
end
let tclWITH_FWD_VIEWS ~simple_types ~subject ~views:vs ~conclusion:tac =
let ending_tac s0 =
- State.vsCONSUME (fun _ t -> finalize_view s0 ~simple_types t >>= tac) in
+ State.vsCONSUME (fun ~name:_ t ~to_clear:_ ->
+ finalize_view s0 ~simple_types t >>= tac) in
tclINDEPENDENT begin
State.vsASSERT_EMPTY <*>
- State.vsINIT subject <*>
- Ssrcommon.tacSIGMA >>= apply_all_views ending_tac vs <*>
+ State.vsINIT (subject,[]) <*>
+ Ssrcommon.tacSIGMA >>=
+ apply_all_views ~clear_if_id:false ending_tac vs <*>
State.vsASSERT_EMPTY
end
diff --git a/plugins/ssr/ssrview.mli b/plugins/ssr/ssrview.mli
index be51fe7f..b128a95d 100644
--- a/plugins/ssr/ssrview.mli
+++ b/plugins/ssr/ssrview.mli
@@ -20,9 +20,11 @@ module AdaptorDb : sig
end
-(* Apply views to the top of the stack (intro pattern) *)
+(* Apply views to the top of the stack (intro pattern). If clear_if_id is
+ * true (default false) then views that happen to be a variable are considered
+ * as to be cleared (see the to_clear argument to the continuation) *)
val tclIPAT_VIEWS :
- views:ast_closure_term list ->
+ views:ast_closure_term list -> ?clear_if_id:bool ->
conclusion:(to_clear:Names.Id.t list -> unit Proofview.tactic) ->
unit Proofview.tactic
diff --git a/plugins/ssrmatching/g_ssrmatching.ml4 b/plugins/ssrmatching/g_ssrmatching.ml4
new file mode 100644
index 00000000..746c368a
--- /dev/null
+++ b/plugins/ssrmatching/g_ssrmatching.ml4
@@ -0,0 +1,101 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Ltac_plugin
+open Genarg
+open Pcoq
+open Pcoq.Constr
+open Ssrmatching
+open Ssrmatching.Internal
+
+(* Defining grammar rules with "xx" in it automatically declares keywords too,
+ * we thus save the lexer to restore it at the end of the file *)
+let frozen_lexer = CLexer.get_keyword_state () ;;
+
+DECLARE PLUGIN "ssrmatching_plugin"
+
+let pr_rpattern _ _ _ = pr_rpattern
+
+ARGUMENT EXTEND rpattern
+ TYPED AS rpatternty
+ PRINTED BY pr_rpattern
+ INTERPRETED BY interp_rpattern
+ GLOBALIZED BY glob_rpattern
+ SUBSTITUTED BY subst_rpattern
+ | [ lconstr(c) ] -> [ mk_rpattern (T (mk_lterm c None)) ]
+ | [ "in" lconstr(c) ] -> [ mk_rpattern (In_T (mk_lterm c None)) ]
+ | [ lconstr(x) "in" lconstr(c) ] ->
+ [ mk_rpattern (X_In_T (mk_lterm x None, mk_lterm c None)) ]
+ | [ "in" lconstr(x) "in" lconstr(c) ] ->
+ [ mk_rpattern (In_X_In_T (mk_lterm x None, mk_lterm c None)) ]
+ | [ lconstr(e) "in" lconstr(x) "in" lconstr(c) ] ->
+ [ mk_rpattern (E_In_X_In_T (mk_lterm e None, mk_lterm x None, mk_lterm c None)) ]
+ | [ lconstr(e) "as" lconstr(x) "in" lconstr(c) ] ->
+ [ mk_rpattern (E_As_X_In_T (mk_lterm e None, mk_lterm x None, mk_lterm c None)) ]
+END
+
+let pr_ssrterm _ _ _ = pr_ssrterm
+
+ARGUMENT EXTEND cpattern
+ PRINTED BY pr_ssrterm
+ INTERPRETED BY interp_ssrterm
+ GLOBALIZED BY glob_cpattern SUBSTITUTED BY subst_ssrterm
+ RAW_PRINTED BY pr_ssrterm
+ GLOB_PRINTED BY pr_ssrterm
+| [ "Qed" constr(c) ] -> [ mk_lterm c None ]
+END
+
+let input_ssrtermkind strm = match Util.stream_nth 0 strm with
+ | Tok.KEYWORD "(" -> '('
+ | Tok.KEYWORD "@" -> '@'
+ | _ -> ' '
+let ssrtermkind = Pcoq.Gram.Entry.of_parser "ssrtermkind" input_ssrtermkind
+
+GEXTEND Gram
+ GLOBAL: cpattern;
+ cpattern: [[ k = ssrtermkind; c = constr ->
+ let pattern = mk_term k c None in
+ if loc_of_cpattern pattern <> Some !@loc && k = '('
+ then mk_term 'x' c None
+ else pattern ]];
+END
+
+ARGUMENT EXTEND lcpattern
+ TYPED AS cpattern
+ PRINTED BY pr_ssrterm
+ INTERPRETED BY interp_ssrterm
+ GLOBALIZED BY glob_cpattern SUBSTITUTED BY subst_ssrterm
+ RAW_PRINTED BY pr_ssrterm
+ GLOB_PRINTED BY pr_ssrterm
+| [ "Qed" lconstr(c) ] -> [ mk_lterm c None ]
+END
+
+GEXTEND Gram
+ GLOBAL: lcpattern;
+ lcpattern: [[ k = ssrtermkind; c = lconstr ->
+ let pattern = mk_term k c None in
+ if loc_of_cpattern pattern <> Some !@loc && k = '('
+ then mk_term 'x' c None
+ else pattern ]];
+END
+
+ARGUMENT EXTEND ssrpatternarg TYPED AS rpattern PRINTED BY pr_rpattern
+| [ rpattern(pat) ] -> [ pat ]
+END
+
+TACTIC EXTEND ssrinstoftpat
+| [ "ssrinstancesoftpat" cpattern(arg) ] -> [ Proofview.V82.tactic (ssrinstancesof arg) ]
+END
+
+(* We wipe out all the keywords generated by the grammar rules we defined. *)
+(* The user is supposed to Require Import ssreflect or Require ssreflect *)
+(* and Import ssreflect.SsrSyntax to obtain these keywords and as a *)
+(* consequence the extended ssreflect grammar. *)
+let () = CLexer.set_keyword_state frozen_lexer ;;
diff --git a/plugins/ssrmatching/ssrmatching.ml4 b/plugins/ssrmatching/ssrmatching.ml
index 307bc21a..4a63dd47 100644
--- a/plugins/ssrmatching/ssrmatching.ml4
+++ b/plugins/ssrmatching/ssrmatching.ml
@@ -10,10 +10,6 @@
(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *)
-(* Defining grammar rules with "xx" in it automatically declares keywords too,
- * we thus save the lexer to restore it at the end of the file *)
-let frozen_lexer = CLexer.get_keyword_state () ;;
-
open Ltac_plugin
open Names
open Pp
@@ -22,8 +18,6 @@ open Stdarg
open Term
module CoqConstr = Constr
open CoqConstr
-open Pcoq
-open Pcoq.Constr
open Vars
open Libnames
open Tactics
@@ -40,14 +34,12 @@ open Pretyping
open Ppconstr
open Printer
open Globnames
-open Misctypes
+open Namegen
open Decl_kinds
open Evar_kinds
open Constrexpr
open Constrexpr_ops
-DECLARE PLUGIN "ssrmatching_plugin"
-
let errorstrm = CErrors.user_err ~hdr:"ssrmatching"
let loc_error loc msg = CErrors.user_err ?loc ~hdr:msg (str msg)
let ppnl = Feedback.msg_info
@@ -131,9 +123,12 @@ let add_genarg tag pr =
(** Constructors for cast type *)
let dC t = CastConv t
(** Constructors for constr_expr *)
-let isCVar = function { CAst.v = CRef ({CAst.v=Ident _},_) } -> true | _ -> false
-let destCVar = function { CAst.v = CRef ({CAst.v=Ident id},_) } -> id | _ ->
- CErrors.anomaly (str"not a CRef.")
+let isCVar = function { CAst.v = CRef (qid,_) } -> qualid_is_ident qid | _ -> false
+let destCVar = function
+ | { CAst.v = CRef (qid,_) } when qualid_is_ident qid ->
+ qualid_basename qid
+ | _ ->
+ CErrors.anomaly (str"not a CRef.")
let isGLambda c = match DAst.get c with GLambda (Name _, _, _, _) -> true | _ -> false
let destGLambda c = match DAst.get c with GLambda (Name id, _, _, c) -> (id, c)
| _ -> CErrors.anomaly (str "not a GLambda")
@@ -283,7 +278,7 @@ exception NoProgress
(* comparison can be much faster than the HO one. *)
let unif_EQ env sigma p c =
- let evars = existential_opt_value sigma, Evd.universes sigma in
+ let evars = existential_opt_value0 sigma, Evd.universes sigma in
try let _ = Reduction.conv env p ~evars c in true with _ -> false
let unif_EQ_args env sigma pa a =
@@ -314,24 +309,27 @@ let unif_HO_args env ise0 pa i ca =
(* evars into metas, since 8.2 does not TC metas. This means some lossage *)
(* for HO evars, though hopefully Miller patterns can pick up some of *)
(* those cases, and HO matching will mop up the rest. *)
-let flags_FO =
+let flags_FO env =
+ let oracle = Environ.oracle env in
+ let ts = Conv_oracle.get_transp_state oracle in
let flags =
- { (Unification.default_no_delta_unify_flags ()).Unification.core_unify_flags
+ { (Unification.default_no_delta_unify_flags ts).Unification.core_unify_flags
with
Unification.modulo_conv_on_closed_terms = None;
Unification.modulo_eta = true;
Unification.modulo_betaiota = true;
- Unification.modulo_delta_types = full_transparent_state}
+ Unification.modulo_delta_types = ts }
in
{ Unification.core_unify_flags = flags;
Unification.merge_unify_flags = flags;
Unification.subterm_unify_flags = flags;
Unification.allow_K_in_toplevel_higher_order_unification = false;
Unification.resolve_evars =
- (Unification.default_no_delta_unify_flags ()).Unification.resolve_evars
+ (Unification.default_no_delta_unify_flags ts).Unification.resolve_evars
}
let unif_FO env ise p c =
- Unification.w_unify env ise Reduction.CONV ~flags:flags_FO (EConstr.of_constr p) (EConstr.of_constr c)
+ Unification.w_unify env ise Reduction.CONV ~flags:(flags_FO env)
+ (EConstr.of_constr p) (EConstr.of_constr c)
(* Perform evar substitution in main term and prune substitution. *)
let nf_open_term sigma0 ise c =
@@ -339,7 +337,7 @@ let nf_open_term sigma0 ise c =
let s = ise and s' = ref sigma0 in
let rec nf c' = match kind c' with
| Evar ex ->
- begin try nf (existential_value s ex) with _ ->
+ begin try nf (existential_value0 s ex) with _ ->
let k, a = ex in let a' = Array.map nf a in
if not (Evd.mem !s' k) then
s' := Evd.add !s' k (Evarutil.nf_evar_info s (Evd.find s k));
@@ -349,7 +347,9 @@ let nf_open_term sigma0 ise c =
let copy_def k evi () =
if evar_body evi != Evd.Evar_empty then () else
match Evd.evar_body (Evd.find s k) with
- | Evar_defined c' -> s' := Evd.define k (nf c') !s'
+ | Evar_defined c' ->
+ let c' = EConstr.of_constr (nf (EConstr.Unsafe.to_constr c')) in
+ s' := Evd.define k c' !s'
| _ -> () in
let c' = nf c in let _ = Evd.fold copy_def sigma0 () in
!s', Evd.evar_universe_context s, EConstr.of_constr c'
@@ -448,7 +448,7 @@ let evars_for_FO ~hack env sigma0 (ise0:evar_map) c0 =
let nenv = env_size env + if hack then 1 else 0 in
let rec put c = match kind c with
| Evar (k, a as ex) ->
- begin try put (existential_value !sigma ex)
+ begin try put (existential_value0 !sigma ex)
with NotInstantiatedEvar ->
if Evd.mem sigma0 k then map put c else
let evi = Evd.find !sigma k in
@@ -459,11 +459,13 @@ let evars_for_FO ~hack env sigma0 (ise0:evar_map) c0 =
| Context.Named.Declaration.LocalAssum (x, t) ->
mkVar x :: d, mkNamedProd x (put t) c in
let a, t =
- Context.Named.fold_inside abs_dc ~init:([], (put evi.evar_concl)) dc in
+ Context.Named.fold_inside abs_dc
+ ~init:([], (put @@ EConstr.Unsafe.to_constr evi.evar_concl))
+ (EConstr.Unsafe.to_named_context dc) in
let m = Evarutil.new_meta () in
- ise := meta_declare m t !ise;
- sigma := Evd.define k (applistc (mkMeta m) a) !sigma;
- put (existential_value !sigma ex)
+ ise := meta_declare m (EConstr.of_constr t) !ise;
+ sigma := Evd.define k (EConstr.of_constr (applistc (mkMeta m) a)) !sigma;
+ put (existential_value0 !sigma ex)
end
| _ -> map put c in
let c1 = put c0 in !ise, c1
@@ -543,7 +545,7 @@ let splay_app ise =
| App (f, a') -> loop f (Array.append a' a)
| Cast (c', _, _) -> loop c' a
| Evar ex ->
- (try loop (existential_value ise ex) a with _ -> c, a)
+ (try loop (existential_value0 ise ex) a with _ -> c, a)
| _ -> c, a in
fun c -> match kind c with
| App (f, a) -> loop f a
@@ -706,9 +708,9 @@ let match_upats_HO ~on_instance upats env sigma0 ise c =
;;
-let fixed_upat = function
+let fixed_upat evd = function
| {up_k = KpatFlex | KpatEvar _ | KpatProj _} -> false
-| {up_t = t} -> not (occur_existential Evd.empty (EConstr.of_constr t)) (** FIXME *)
+| {up_t = t} -> not (occur_existential evd (EConstr.of_constr t)) (** FIXME *)
let do_once r f = match !r with Some _ -> () | None -> r := Some (f ())
@@ -767,7 +769,7 @@ let mk_tpattern_matcher ?(all_instances=false)
let p2t p = mkApp(p.up_f,p.up_a) in
let source () = match upats_origin, upats with
| None, [p] ->
- (if fixed_upat p then str"term " else str"partial term ") ++
+ (if fixed_upat ise p then str"term " else str"partial term ") ++
pr_constr_pat (p2t p) ++ spc()
| Some (dir,rule), [p] -> str"The " ++ pr_dir_side dir ++ str" of " ++
pr_constr_pat rule ++ fnl() ++ ws 4 ++ pr_constr_pat (p2t p) ++ fnl()
@@ -854,7 +856,7 @@ let rec uniquize = function
let p' = mkApp (pf, pa) in
if max_occ <= !nocc then p', u.up_dir, (sigma, uc, u.up_t)
else errorstrm (str"Only " ++ int !nocc ++ str" < " ++ int max_occ ++
- str(String.plural !nocc " occurence") ++ match upats_origin with
+ str(String.plural !nocc " occurrence") ++ match upats_origin with
| None -> str" of" ++ spc() ++ pr_constr_pat p'
| Some (dir,rule) -> str" of the " ++ pr_dir_side dir ++ fnl() ++
ws 4 ++ pr_constr_pat p' ++ fnl () ++
@@ -900,7 +902,6 @@ let pr_pattern_aux pr_constr = function
let pp_pattern (sigma, p) =
pr_pattern_aux (fun t -> pr_constr_pat (EConstr.Unsafe.to_constr (pi3 (nf_open_term sigma sigma (EConstr.of_constr t))))) p
let pr_cpattern = pr_term
-let pr_rpattern _ _ _ = pr_pattern
let wit_rpatternty = add_genarg "rpatternty" pr_pattern
@@ -931,7 +932,7 @@ let glob_cpattern gs p =
| k, (v, Some t), _ as orig ->
if k = 'x' then glob_ssrterm gs ('(', (v, Some t), None) else
match t.CAst.v with
- | CNotation("( _ in _ )", ([t1; t2], [], [], [])) ->
+ | CNotation((InConstrEntrySomeLevel,"( _ in _ )"), ([t1; t2], [], [], [])) ->
(try match glob t1, glob t2 with
| (r1, None), (r2, None) -> encode k "In" [r1;r2]
| (r1, Some _), (r2, Some _) when isCVar t1 ->
@@ -939,11 +940,11 @@ let glob_cpattern gs p =
| (r1, Some _), (r2, Some _) -> encode k "In" [r1; r2]
| _ -> CErrors.anomaly (str"where are we?.")
with _ when isCVar t1 -> encode k "In" [bind_in t1 t2])
- | CNotation("( _ in _ in _ )", ([t1; t2; t3], [], [], [])) ->
+ | CNotation((InConstrEntrySomeLevel,"( _ in _ in _ )"), ([t1; t2; t3], [], [], [])) ->
check_var t2; encode k "In" [fst (glob t1); bind_in t2 t3]
- | CNotation("( _ as _ )", ([t1; t2], [], [], [])) ->
+ | CNotation((InConstrEntrySomeLevel,"( _ as _ )"), ([t1; t2], [], [], [])) ->
encode k "As" [fst (glob t1); fst (glob t2)]
- | CNotation("( _ as _ in _ )", ([t1; t2; t3], [], [], [])) ->
+ | CNotation((InConstrEntrySomeLevel,"( _ as _ in _ )"), ([t1; t2; t3], [], [], [])) ->
check_var t2; encode k "As" [fst (glob t1); bind_in t2 t3]
| _ -> glob_ssrterm gs orig
;;
@@ -980,27 +981,7 @@ let interp_rpattern s = function
| E_As_X_In_T(e,x,t) ->
E_As_X_In_T (interp_ssrterm s e,interp_ssrterm s x,interp_ssrterm s t)
-let interp_rpattern ist gl t = Tacmach.project gl, interp_rpattern ist t
-
-ARGUMENT EXTEND rpattern
- TYPED AS rpatternty
- PRINTED BY pr_rpattern
- INTERPRETED BY interp_rpattern
- GLOBALIZED BY glob_rpattern
- SUBSTITUTED BY subst_rpattern
- | [ lconstr(c) ] -> [ T (mk_lterm c None) ]
- | [ "in" lconstr(c) ] -> [ In_T (mk_lterm c None) ]
- | [ lconstr(x) "in" lconstr(c) ] ->
- [ X_In_T (mk_lterm x None, mk_lterm c None) ]
- | [ "in" lconstr(x) "in" lconstr(c) ] ->
- [ In_X_In_T (mk_lterm x None, mk_lterm c None) ]
- | [ lconstr(e) "in" lconstr(x) "in" lconstr(c) ] ->
- [ E_In_X_In_T (mk_lterm e None, mk_lterm x None, mk_lterm c None) ]
- | [ lconstr(e) "as" lconstr(x) "in" lconstr(c) ] ->
- [ E_As_X_In_T (mk_lterm e None, mk_lterm x None, mk_lterm c None) ]
-END
-
-
+let interp_rpattern0 ist gl t = Tacmach.project gl, interp_rpattern ist t
type cpattern = char * glob_constr_and_expr * Geninterp.interp_sign option
let tag_of_cpattern = pi1
@@ -1015,8 +996,10 @@ type pattern = Evd.evar_map * (constr, constr) ssrpattern
let id_of_cpattern (_, (c1, c2), _) =
let open CAst in
match DAst.get c1, c2 with
- | _, Some { v = CRef ({CAst.v=Ident x}, _) } -> Some x
- | _, Some { v = CAppExpl ((_, {CAst.v=Ident x}, _), []) } -> Some x
+ | _, Some { v = CRef (qid, _) } when qualid_is_ident qid ->
+ Some (qualid_basename qid)
+ | _, Some { v = CAppExpl ((_, qid, _), []) } when qualid_is_ident qid ->
+ Some (qualid_basename qid)
| GRef (VarRef x, _), None -> Some x
| _ -> None
let id_of_Cterm t = match id_of_cpattern t with
@@ -1042,52 +1025,9 @@ let interp_wit wit ist gl x =
let interp_open_constr ist gl gc =
interp_wit wit_open_constr ist gl gc
let pf_intern_term gl (_, c, ist) = glob_constr ist (pf_env gl) (project gl) c
-let pr_ssrterm _ _ _ = pr_term
-let input_ssrtermkind strm = match stream_nth 0 strm with
- | Tok.KEYWORD "(" -> '('
- | Tok.KEYWORD "@" -> '@'
- | _ -> ' '
-let ssrtermkind = Pcoq.Gram.Entry.of_parser "ssrtermkind" input_ssrtermkind
let interp_ssrterm ist gl t = Tacmach.project gl, interp_ssrterm ist t
-ARGUMENT EXTEND cpattern
- PRINTED BY pr_ssrterm
- INTERPRETED BY interp_ssrterm
- GLOBALIZED BY glob_cpattern SUBSTITUTED BY subst_ssrterm
- RAW_PRINTED BY pr_ssrterm
- GLOB_PRINTED BY pr_ssrterm
-| [ "Qed" constr(c) ] -> [ mk_lterm c None ]
-END
-
-GEXTEND Gram
- GLOBAL: cpattern;
- cpattern: [[ k = ssrtermkind; c = constr ->
- let pattern = mk_term k c None in
- if loc_ofCG pattern <> Some !@loc && k = '('
- then mk_term 'x' c None
- else pattern ]];
-END
-
-ARGUMENT EXTEND lcpattern
- TYPED AS cpattern
- PRINTED BY pr_ssrterm
- INTERPRETED BY interp_ssrterm
- GLOBALIZED BY glob_cpattern SUBSTITUTED BY subst_ssrterm
- RAW_PRINTED BY pr_ssrterm
- GLOB_PRINTED BY pr_ssrterm
-| [ "Qed" lconstr(c) ] -> [ mk_lterm c None ]
-END
-
-GEXTEND Gram
- GLOBAL: lcpattern;
- lcpattern: [[ k = ssrtermkind; c = lconstr ->
- let pattern = mk_term k c None in
- if loc_ofCG pattern <> Some !@loc && k = '('
- then mk_term 'x' c None
- else pattern ]];
-END
-
let interp_term gl = function
| (_, c, Some ist) ->
on_snd EConstr.Unsafe.to_constr (interp_open_constr ist gl c)
@@ -1097,15 +1037,14 @@ let thin id sigma goal =
let ids = Id.Set.singleton id in
let env = Goal.V82.env sigma goal in
let cl = Goal.V82.concl sigma goal in
- let evdref = ref (Evd.clear_metas sigma) in
+ let sigma = Evd.clear_metas sigma in
let ans =
- try Some (Evarutil.clear_hyps_in_evi env evdref (Environ.named_context_val env) cl ids)
+ try Some (Evarutil.clear_hyps_in_evi env sigma (Environ.named_context_val env) cl ids)
with Evarutil.ClearDependencyError _ -> None
in
match ans with
| None -> sigma
- | Some (hyps, concl) ->
- let sigma = !evdref in
+ | Some (sigma, hyps, concl) ->
let (gl,ev,sigma) = Goal.V82.mk_goal sigma hyps concl (Goal.V82.extra sigma goal) in
let sigma = Goal.V82.partial_solution_to sigma goal gl ev in
sigma
@@ -1257,7 +1196,7 @@ let eval_pattern ?raise_NoMatch env0 sigma0 concl0 pattern occ do_subst =
let fs sigma x = nf_evar sigma x in
let pop_evar sigma e p =
let { Evd.evar_body = e_body } as e_def = Evd.find sigma e in
- let e_body = match e_body with Evar_defined c -> c
+ let e_body = match e_body with Evar_defined c -> EConstr.Unsafe.to_constr c
| _ -> errorstrm (str "Matching the pattern " ++ pr_constr_env env0 sigma0 p ++
str " did not instantiate ?" ++ int (Evar.repr e) ++ spc () ++
str "Does the variable bound by the \"in\" construct occur "++
@@ -1408,10 +1347,6 @@ let is_wildcard ((_, (l, r), _) : cpattern) : bool = match DAst.get l, r with
(* "ssrpattern" *)
-ARGUMENT EXTEND ssrpatternarg TYPED AS rpattern PRINTED BY pr_rpattern
-| [ rpattern(pat) ] -> [ pat ]
-END
-
let pr_rpattern = pr_pattern
let pf_merge_uc uc gl =
@@ -1420,6 +1355,9 @@ let pf_merge_uc uc gl =
let pf_unsafe_merge_uc uc gl =
re_sig (sig_it gl) (Evd.set_universe_context (project gl) uc)
+(** All the pattern types reuse the same dynamic toplevel tag *)
+let wit_ssrpatternarg = wit_rpatternty
+
let interp_rpattern = interp_rpattern ~wit_ssrpatternarg
let ssrpatterntac _ist arg gl =
@@ -1428,7 +1366,7 @@ let ssrpatterntac _ist arg gl =
let concl0 = pf_concl gl in
let concl0 = EConstr.Unsafe.to_constr concl0 in
let (t, uc), concl_x =
- fill_occ_pattern (Global.env()) sigma0 concl0 pat noindex 1 in
+ fill_occ_pattern (pf_env gl) sigma0 concl0 pat noindex 1 in
let t = EConstr.of_constr t in
let concl_x = EConstr.of_constr concl_x in
let gl, tty = pf_type_of gl t in
@@ -1471,14 +1409,20 @@ let ssrinstancesof arg gl =
done; raise NoMatch
with NoMatch -> ppnl (str"END INSTANCES"); tclIDTAC gl
-TACTIC EXTEND ssrinstoftpat
-| [ "ssrinstancesoftpat" cpattern(arg) ] -> [ Proofview.V82.tactic (ssrinstancesof arg) ]
-END
-
-(* We wipe out all the keywords generated by the grammar rules we defined. *)
-(* The user is supposed to Require Import ssreflect or Require ssreflect *)
-(* and Import ssreflect.SsrSyntax to obtain these keywords and as a *)
-(* consequence the extended ssreflect grammar. *)
-let () = CLexer.set_keyword_state frozen_lexer ;;
+module Internal =
+struct
+ let wit_rpatternty = wit_rpatternty
+ let glob_rpattern = glob_rpattern
+ let subst_rpattern = subst_rpattern
+ let interp_rpattern = interp_rpattern0
+ let pr_rpattern = pr_rpattern
+ let mk_rpattern x = x
+ let mk_lterm = mk_lterm
+ let mk_term = mk_term
+ let glob_cpattern = glob_cpattern
+ let subst_ssrterm = subst_ssrterm
+ let interp_ssrterm = interp_ssrterm
+ let pr_ssrterm = pr_term
+end
(* vim: set filetype=ocaml foldmethod=marker: *)
diff --git a/plugins/ssrmatching/ssrmatching.mli b/plugins/ssrmatching/ssrmatching.mli
new file mode 100644
index 00000000..9c79879d
--- /dev/null
+++ b/plugins/ssrmatching/ssrmatching.mli
@@ -0,0 +1,258 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2015 Microsoft Corporation and Inria. *)
+
+open Goal
+open Environ
+open Evd
+open Constr
+
+open Ltac_plugin
+open Tacexpr
+
+(** ******** Small Scale Reflection pattern matching facilities ************* *)
+
+(** Pattern parsing *)
+
+(** The type of context patterns, the patterns of the [set] tactic and
+ [:] tactical. These are patterns that identify a precise subterm. *)
+type cpattern
+val pr_cpattern : cpattern -> Pp.t
+
+(** The type of rewrite patterns, the patterns of the [rewrite] tactic.
+ These patterns also include patterns that identify all the subterms
+ of a context (i.e. "in" prefix) *)
+type rpattern
+val pr_rpattern : rpattern -> Pp.t
+
+(** Pattern interpretation and matching *)
+
+exception NoMatch
+exception NoProgress
+
+(** AST for [rpattern] (and consequently [cpattern]) *)
+type ('ident, 'term) ssrpattern =
+ | T of 'term
+ | In_T of 'term
+ | X_In_T of 'ident * 'term
+ | In_X_In_T of 'ident * 'term
+ | E_In_X_In_T of 'term * 'ident * 'term
+ | E_As_X_In_T of 'term * 'ident * 'term
+
+type pattern = evar_map * (constr, constr) ssrpattern
+val pp_pattern : pattern -> Pp.t
+
+(** Extracts the redex and applies to it the substitution part of the pattern.
+ @raise Anomaly if called on [In_T] or [In_X_In_T] *)
+val redex_of_pattern :
+ ?resolve_typeclasses:bool -> env -> pattern ->
+ constr Evd.in_evar_universe_context
+
+(** [interp_rpattern ise gl rpat] "internalizes" and "interprets" [rpat]
+ in the current [Ltac] interpretation signature [ise] and tactic input [gl]*)
+val interp_rpattern :
+ goal sigma ->
+ rpattern ->
+ pattern
+
+(** [interp_cpattern ise gl cpat ty] "internalizes" and "interprets" [cpat]
+ in the current [Ltac] interpretation signature [ise] and tactic input [gl].
+ [ty] is an optional type for the redex of [cpat] *)
+val interp_cpattern :
+ goal sigma ->
+ cpattern -> (glob_constr_and_expr * Geninterp.interp_sign) option ->
+ pattern
+
+(** The set of occurrences to be matched. The boolean is set to true
+ * to signal the complement of this set (i.e. \{-1 3\}) *)
+type occ = (bool * int list) option
+
+(** [subst e p t i]. [i] is the number of binders
+ traversed so far, [p] the term from the pattern, [t] the matched one *)
+type subst = env -> constr -> constr -> int -> constr
+
+(** [eval_pattern b env sigma t pat occ subst] maps [t] calling [subst] on every
+ [occ] occurrence of [pat]. The [int] argument is the number of
+ binders traversed. If [pat] is [None] then then subst is called on [t].
+ [t] must live in [env] and [sigma], [pat] must have been interpreted in
+ (an extension of) [sigma].
+ @raise NoMatch if [pat] has no occurrence and [b] is [true] (default [false])
+ @return [t] where all [occ] occurrences of [pat] have been mapped using
+ [subst] *)
+val eval_pattern :
+ ?raise_NoMatch:bool ->
+ env -> evar_map -> constr ->
+ pattern option -> occ -> subst ->
+ constr
+
+(** [fill_occ_pattern b env sigma t pat occ h] is a simplified version of
+ [eval_pattern].
+ It replaces all [occ] occurrences of [pat] in [t] with Rel [h].
+ [t] must live in [env] and [sigma], [pat] must have been interpreted in
+ (an extension of) [sigma].
+ @raise NoMatch if [pat] has no occurrence and [b] is [true] (default [false])
+ @return the instance of the redex of [pat] that was matched and [t]
+ transformed as described above. *)
+val fill_occ_pattern :
+ ?raise_NoMatch:bool ->
+ env -> evar_map -> constr ->
+ pattern -> occ -> int ->
+ constr Evd.in_evar_universe_context * constr
+
+(** *************************** Low level APIs ****************************** *)
+
+(* The primitive matching facility. It matches of a term with holes, like
+ the T pattern above, and calls a continuation on its occurrences. *)
+
+type ssrdir = L2R | R2L
+val pr_dir_side : ssrdir -> Pp.t
+
+(** a pattern for a term with wildcards *)
+type tpattern
+
+(** [mk_tpattern env sigma0 sigma_p ok p_origin dir t] compiles a term [t]
+ living in [env] [sigma] (an extension of [sigma0]) intro a [tpattern].
+ The [tpattern] can hold a (proof) term [p] and a diction [dir]. The [ok]
+ callback is used to filter occurrences.
+ @return the compiled [tpattern] and its [evar_map]
+ @raise UserEerror is the pattern is a wildcard *)
+val mk_tpattern :
+ ?p_origin:ssrdir * constr ->
+ env -> evar_map ->
+ evar_map * constr ->
+ (constr -> evar_map -> bool) ->
+ ssrdir -> constr ->
+ evar_map * tpattern
+
+(** [findP env t i k] is a stateful function that finds the next occurrence
+ of a tpattern and calls the callback [k] to map the subterm matched.
+ The [int] argument passed to [k] is the number of binders traversed so far
+ plus the initial value [i].
+ @return [t] where the subterms identified by the selected occurrences of
+ the patter have been mapped using [k]
+ @raise NoMatch if the raise_NoMatch flag given to [mk_tpattern_matcher] is
+ [true] and if the pattern did not match
+ @raise UserEerror if the raise_NoMatch flag given to [mk_tpattern_matcher] is
+ [false] and if the pattern did not match *)
+type find_P =
+ env -> constr -> int -> k:subst -> constr
+
+(** [conclude ()] asserts that all mentioned ocurrences have been visited.
+ @return the instance of the pattern, the evarmap after the pattern
+ instantiation, the proof term and the ssrdit stored in the tpattern
+ @raise UserEerror if too many occurrences were specified *)
+type conclude =
+ unit -> constr * ssrdir * (evar_map * UState.t * constr)
+
+(** [mk_tpattern_matcher b o sigma0 occ sigma_tplist] creates a pair
+ a function [find_P] and [conclude] with the behaviour explained above.
+ The flag [b] (default [false]) changes the error reporting behaviour
+ of [find_P] if none of the [tpattern] matches. The argument [o] can
+ be passed to tune the [UserError] eventually raised (useful if the
+ pattern is coming from the LHS/RHS of an equation) *)
+val mk_tpattern_matcher :
+ ?all_instances:bool ->
+ ?raise_NoMatch:bool ->
+ ?upats_origin:ssrdir * constr ->
+ evar_map -> occ -> evar_map * tpattern list ->
+ find_P * conclude
+
+(** Example of [mk_tpattern_matcher] to implement
+ [rewrite \{occ\}\[in t\]rules].
+ It first matches "in t" (called [pat]), then in all matched subterms
+ it matches the LHS of the rules using [find_R].
+ [concl0] is the initial goal, [concl] will be the goal where some terms
+ are replaced by a De Bruijn index. The [rw_progress] extra check
+ selects only occurrences that are not rewritten to themselves (e.g.
+ an occurrence "x + x" rewritten with the commutativity law of addition
+ is skipped) {[
+ let find_R, conclude = match pat with
+ | Some (_, In_T _) ->
+ let aux (sigma, pats) (d, r, lhs, rhs) =
+ let sigma, pat =
+ mk_tpattern env0 sigma0 (sigma, r) (rw_progress rhs) d lhs in
+ sigma, pats @ [pat] in
+ let rpats = List.fold_left aux (r_sigma, []) rules in
+ let find_R, end_R = mk_tpattern_matcher sigma0 occ rpats in
+ find_R ~k:(fun _ _ h -> mkRel h),
+ fun cl -> let rdx, d, r = end_R () in (d,r),rdx
+ | _ -> ... in
+ let concl = eval_pattern env0 sigma0 concl0 pat occ find_R in
+ let (d, r), rdx = conclude concl in ]} *)
+
+(* convenience shortcut: [pf_fill_occ_term gl occ (sigma,t)] returns
+ * the conclusion of [gl] where [occ] occurrences of [t] have been replaced
+ * by [Rel 1] and the instance of [t] *)
+val pf_fill_occ_term : goal sigma -> occ -> evar_map * EConstr.t -> EConstr.t * EConstr.t
+
+(* It may be handy to inject a simple term into the first form of cpattern *)
+val cpattern_of_term : char * glob_constr_and_expr -> Geninterp.interp_sign -> cpattern
+
+(** Helpers to make stateful closures. Example: a [find_P] function may be
+ called many times, but the pattern instantiation phase is performed only the
+ first time. The corresponding [conclude] has to return the instantiated
+ pattern redex. Since it is up to [find_P] to raise [NoMatch] if the pattern
+ has no instance, [conclude] considers it an anomaly if the pattern did
+ not match *)
+
+(** [do_once r f] calls [f] and updates the ref only once *)
+val do_once : 'a option ref -> (unit -> 'a) -> unit
+(** [assert_done r] return the content of r. @raise Anomaly is r is [None] *)
+val assert_done : 'a option ref -> 'a
+
+(** Very low level APIs.
+ these are calls to evarconv's [the_conv_x] followed by
+ [solve_unif_constraints_with_heuristics] and [resolve_typeclasses].
+ In case of failure they raise [NoMatch] *)
+
+val unify_HO : env -> evar_map -> EConstr.constr -> EConstr.constr -> evar_map
+val pf_unify_HO : goal sigma -> EConstr.constr -> EConstr.constr -> goal sigma
+
+(** Some more low level functions needed to implement the full SSR language
+ on top of the former APIs *)
+val tag_of_cpattern : cpattern -> char
+val loc_of_cpattern : cpattern -> Loc.t option
+val id_of_pattern : pattern -> Names.Id.t option
+val is_wildcard : cpattern -> bool
+val cpattern_of_id : Names.Id.t -> cpattern
+val pr_constr_pat : constr -> Pp.t
+val pf_merge_uc : UState.t -> goal Evd.sigma -> goal Evd.sigma
+val pf_unsafe_merge_uc : UState.t -> goal Evd.sigma -> goal Evd.sigma
+
+(* One can also "Set SsrMatchingDebug" from a .v *)
+val debug : bool -> unit
+
+(* One should delimit a snippet with "Set SsrMatchingProfiling" and
+ * "Unset SsrMatchingProfiling" to get timings *)
+val profile : bool -> unit
+
+val ssrinstancesof : cpattern -> Tacmach.tactic
+
+(** Functions used for grammar extensions. Do not use. *)
+
+module Internal :
+sig
+ val wit_rpatternty : (rpattern, rpattern, rpattern) Genarg.genarg_type
+ val glob_rpattern : Genintern.glob_sign -> rpattern -> rpattern
+ val subst_rpattern : Mod_subst.substitution -> rpattern -> rpattern
+ val interp_rpattern : Geninterp.interp_sign -> Proof_type.goal Evd.sigma -> rpattern -> Evd.evar_map * rpattern
+ val pr_rpattern : rpattern -> Pp.t
+ val mk_rpattern : (cpattern, cpattern) ssrpattern -> rpattern
+ val mk_lterm : Constrexpr.constr_expr -> Geninterp.interp_sign option -> cpattern
+ val mk_term : char -> Constrexpr.constr_expr -> Geninterp.interp_sign option -> cpattern
+
+ val glob_cpattern : Genintern.glob_sign -> cpattern -> cpattern
+ val subst_ssrterm : Mod_subst.substitution -> cpattern -> cpattern
+ val interp_ssrterm : Geninterp.interp_sign -> Proof_type.goal Evd.sigma -> cpattern -> Evd.evar_map * cpattern
+ val pr_ssrterm : cpattern -> Pp.t
+end
+
+(* eof *)
diff --git a/plugins/ssrmatching/ssrmatching.v b/plugins/ssrmatching/ssrmatching.v
new file mode 100644
index 00000000..fee09cc9
--- /dev/null
+++ b/plugins/ssrmatching/ssrmatching.v
@@ -0,0 +1,36 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2015 Microsoft Corporation and Inria. *)
+
+Declare ML Module "ssrmatching_plugin".
+
+Module SsrMatchingSyntax.
+
+(* Reserve the notation for rewrite patterns so that the user is not allowed *)
+(* to declare it at a different level. *)
+Reserved Notation "( a 'in' b )" (at level 0).
+Reserved Notation "( a 'as' b )" (at level 0).
+Reserved Notation "( a 'in' b 'in' c )" (at level 0).
+Reserved Notation "( a 'as' b 'in' c )" (at level 0).
+
+(* Notation to define shortcuts for the "X in t" part of a pattern. *)
+Notation "( X 'in' t )" := (_ : fun X => t) : ssrpatternscope.
+Delimit Scope ssrpatternscope with pattern.
+
+(* Some shortcuts for recurrent "X in t" parts. *)
+Notation RHS := (X in _ = X)%pattern.
+Notation LHS := (X in X = _)%pattern.
+
+End SsrMatchingSyntax.
+
+Export SsrMatchingSyntax.
+
+Tactic Notation "ssrpattern" ssrpatternarg(p) := ssrpattern p .
diff --git a/plugins/ssrmatching/ssrmatching_plugin.mlpack b/plugins/ssrmatching/ssrmatching_plugin.mlpack
index 5fb1f156..02c75f14 100644
--- a/plugins/ssrmatching/ssrmatching_plugin.mlpack
+++ b/plugins/ssrmatching/ssrmatching_plugin.mlpack
@@ -1 +1,2 @@
Ssrmatching
+G_ssrmatching
diff --git a/plugins/syntax/ascii_syntax.ml b/plugins/syntax/ascii_syntax.ml
index acb297dd..53153198 100644
--- a/plugins/syntax/ascii_syntax.ml
+++ b/plugins/syntax/ascii_syntax.ml
@@ -28,7 +28,7 @@ let make_kn dir id = Globnames.encode_mind (make_dir dir) (Id.of_string id)
let make_path dir id = Libnames.make_path (make_dir dir) (Id.of_string id)
let is_gr c gr = match DAst.get c with
-| GRef (r, _) -> Globnames.eq_gr r gr
+| GRef (r, _) -> GlobRef.equal r gr
| _ -> false
let ascii_module = ["Coq";"Strings";"Ascii"]
@@ -83,8 +83,18 @@ let make_ascii_string n =
let uninterp_ascii_string (AnyGlobConstr r) = Option.map make_ascii_string (uninterp_ascii r)
+open Notation
+
+let at_declare_ml_module f x =
+ Mltop.declare_cache_obj (fun () -> f x) __coq_plugin_name
+
let _ =
- Notation.declare_string_interpreter "char_scope"
- (ascii_path,ascii_module)
- interp_ascii_string
- ([DAst.make @@ GRef (static_glob_Ascii,None)], uninterp_ascii_string, true)
+ let sc = "char_scope" in
+ register_string_interpretation sc (interp_ascii_string,uninterp_ascii_string);
+ at_declare_ml_module enable_prim_token_interpretation
+ { pt_local = false;
+ pt_scope = sc;
+ pt_interp_info = Uid sc;
+ pt_required = (ascii_path,ascii_module);
+ pt_refs = [static_glob_Ascii];
+ pt_in_match = true }
diff --git a/plugins/syntax/g_numeral.ml4 b/plugins/syntax/g_numeral.ml4
new file mode 100644
index 00000000..55f61a58
--- /dev/null
+++ b/plugins/syntax/g_numeral.ml4
@@ -0,0 +1,38 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+DECLARE PLUGIN "numeral_notation_plugin"
+
+open Notation
+open Numeral
+open Pp
+open Names
+open Vernacinterp
+open Ltac_plugin
+open Stdarg
+open Pcoq.Prim
+
+let pr_numnot_option _ _ _ = function
+ | Nop -> mt ()
+ | Warning n -> str "(warning after " ++ str n ++ str ")"
+ | Abstract n -> str "(abstract after " ++ str n ++ str ")"
+
+ARGUMENT EXTEND numnotoption
+ PRINTED BY pr_numnot_option
+| [ ] -> [ Nop ]
+| [ "(" "warning" "after" bigint(waft) ")" ] -> [ Warning waft ]
+| [ "(" "abstract" "after" bigint(n) ")" ] -> [ Abstract n ]
+END
+
+VERNAC COMMAND EXTEND NumeralNotation CLASSIFIED AS SIDEFF
+ | [ "Numeral" "Notation" reference(ty) reference(f) reference(g) ":"
+ ident(sc) numnotoption(o) ] ->
+ [ vernac_numeral_notation (Locality.make_module_locality atts.locality) ty f g (Id.to_string sc) o ]
+END
diff --git a/plugins/syntax/int31_syntax.ml b/plugins/syntax/int31_syntax.ml
index 5529ea70..e34a401c 100644
--- a/plugins/syntax/int31_syntax.ml
+++ b/plugins/syntax/int31_syntax.ml
@@ -26,7 +26,7 @@ let make_dir l = DirPath.make (List.rev_map Id.of_string l)
let make_path dir id = Libnames.make_path (make_dir dir) (Id.of_string id)
let is_gr c gr = match DAst.get c with
-| GRef (r, _) -> Globnames.eq_gr r gr
+| GRef (r, _) -> GlobRef.equal r gr
| _ -> false
let make_mind mp id = Names.MutInd.make2 mp (Label.make id)
@@ -96,10 +96,19 @@ let uninterp_int31 (AnyGlobConstr i) =
with Non_closed ->
None
+open Notation
+
+let at_declare_ml_module f x =
+ Mltop.declare_cache_obj (fun () -> f x) __coq_plugin_name
+
(* Actually declares the interpreter for int31 *)
-let _ = Notation.declare_numeral_interpreter int31_scope
- (int31_path, int31_module)
- interp_int31
- ([DAst.make (GRef (int31_construct, None))],
- uninterp_int31,
- true)
+
+let _ =
+ register_bignumeral_interpretation int31_scope (interp_int31,uninterp_int31);
+ at_declare_ml_module enable_prim_token_interpretation
+ { pt_local = false;
+ pt_scope = int31_scope;
+ pt_interp_info = Uid int31_scope;
+ pt_required = (int31_path,int31_module);
+ pt_refs = [int31_construct];
+ pt_in_match = true }
diff --git a/plugins/syntax/nat_syntax.ml b/plugins/syntax/nat_syntax.ml
deleted file mode 100644
index ad8b54d4..00000000
--- a/plugins/syntax/nat_syntax.ml
+++ /dev/null
@@ -1,84 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-
-(* Poor's man DECLARE PLUGIN *)
-let __coq_plugin_name = "nat_syntax_plugin"
-let () = Mltop.add_known_module __coq_plugin_name
-
-(* This file defines the printer for natural numbers in [nat] *)
-
-(*i*)
-open Glob_term
-open Bigint
-open Coqlib
-open Pp
-open CErrors
-(*i*)
-
-(**********************************************************************)
-(* Parsing via scopes *)
-(* For example, (nat_of_string "3") is <<(S (S (S O)))>> *)
-
-let threshold = of_int 5000
-
-let warn_large_nat =
- CWarnings.create ~name:"large-nat" ~category:"numbers"
- (fun () -> strbrk "Stack overflow or segmentation fault happens when " ++
- strbrk "working with large numbers in nat (observed threshold " ++
- strbrk "may vary from 5000 to 70000 depending on your system " ++
- strbrk "limits and on the command executed).")
-
-let nat_of_int ?loc n =
- if is_pos_or_zero n then begin
- if less_than threshold n then warn_large_nat ();
- let ref_O = DAst.make ?loc @@ GRef (glob_O, None) in
- let ref_S = DAst.make ?loc @@ GRef (glob_S, None) in
- let rec mk_nat acc n =
- if n <> zero then
- mk_nat (DAst.make ?loc @@ GApp (ref_S, [acc])) (sub_1 n)
- else
- acc
- in
- mk_nat ref_O n
- end
- else
- user_err ?loc ~hdr:"nat_of_int"
- (str "Cannot interpret a negative number as a number of type nat")
-
-(************************************************************************)
-(* Printing via scopes *)
-
-exception Non_closed_number
-
-let rec int_of_nat x = DAst.with_val (function
- | GApp (r, [a]) ->
- begin match DAst.get r with
- | GRef (s,_) when Globnames.eq_gr s glob_S -> add_1 (int_of_nat a)
- | _ -> raise Non_closed_number
- end
- | GRef (z,_) when Globnames.eq_gr z glob_O -> zero
- | _ -> raise Non_closed_number
- ) x
-
-let uninterp_nat (AnyGlobConstr p) =
- try
- Some (int_of_nat p)
- with
- Non_closed_number -> None
-
-(************************************************************************)
-(* Declare the primitive parsers and printers *)
-
-let _ =
- Notation.declare_numeral_interpreter "nat_scope"
- (nat_path,datatypes_module_name)
- nat_of_int
- ([DAst.make @@ GRef (glob_S,None); DAst.make @@ GRef (glob_O,None)], uninterp_nat, true)
diff --git a/plugins/syntax/nat_syntax_plugin.mlpack b/plugins/syntax/nat_syntax_plugin.mlpack
deleted file mode 100644
index 39bdd62f..00000000
--- a/plugins/syntax/nat_syntax_plugin.mlpack
+++ /dev/null
@@ -1 +0,0 @@
-Nat_syntax
diff --git a/plugins/syntax/numeral.ml b/plugins/syntax/numeral.ml
new file mode 100644
index 00000000..10a0af0b
--- /dev/null
+++ b/plugins/syntax/numeral.ml
@@ -0,0 +1,142 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Pp
+open Util
+open Names
+open Libnames
+open Globnames
+open Constrexpr
+open Constrexpr_ops
+open Notation
+
+(** * Numeral notation *)
+
+let warn_abstract_large_num_no_op =
+ CWarnings.create ~name:"abstract-large-number-no-op" ~category:"numbers"
+ (fun f ->
+ strbrk "The 'abstract after' directive has no effect when " ++
+ strbrk "the parsing function (" ++
+ Nametab.pr_global_env (Termops.vars_of_env (Global.env ())) f ++ strbrk ") targets an " ++
+ strbrk "option type.")
+
+let get_constructors ind =
+ let mib,oib = Global.lookup_inductive ind in
+ let mc = oib.Declarations.mind_consnames in
+ Array.to_list
+ (Array.mapi (fun j c -> ConstructRef (ind, j + 1)) mc)
+
+let q_z = qualid_of_string "Coq.Numbers.BinNums.Z"
+let q_positive = qualid_of_string "Coq.Numbers.BinNums.positive"
+let q_int = qualid_of_string "Coq.Init.Decimal.int"
+let q_uint = qualid_of_string "Coq.Init.Decimal.uint"
+let q_option = qualid_of_string "Coq.Init.Datatypes.option"
+
+let unsafe_locate_ind q =
+ match Nametab.locate q with
+ | IndRef i -> i
+ | _ -> raise Not_found
+
+let locate_ind q =
+ try unsafe_locate_ind q
+ with Not_found -> Nametab.error_global_not_found q
+
+let locate_z () =
+ try
+ Some { z_ty = unsafe_locate_ind q_z;
+ pos_ty = unsafe_locate_ind q_positive }
+ with Not_found -> None
+
+let locate_int () =
+ { uint = locate_ind q_uint;
+ int = locate_ind q_int }
+
+let has_type f ty =
+ let (sigma, env) = Pfedit.get_current_context () in
+ let c = mkCastC (mkRefC f, Glob_term.CastConv ty) in
+ try let _ = Constrintern.interp_constr env sigma c in true
+ with Pretype_errors.PretypeError _ -> false
+
+let type_error_to f ty loadZ =
+ CErrors.user_err
+ (pr_qualid f ++ str " should go from Decimal.int to " ++
+ pr_qualid ty ++ str " or (option " ++ pr_qualid ty ++ str ")." ++
+ fnl () ++ str "Instead of Decimal.int, the types Decimal.uint or Z could be used" ++
+ (if loadZ then str " (require BinNums first)." else str "."))
+
+let type_error_of g ty loadZ =
+ CErrors.user_err
+ (pr_qualid g ++ str " should go from " ++ pr_qualid ty ++
+ str " to Decimal.int or (option Decimal.int)." ++ fnl () ++
+ str "Instead of Decimal.int, the types Decimal.uint or Z could be used" ++
+ (if loadZ then str " (require BinNums first)." else str "."))
+
+let vernac_numeral_notation local ty f g scope opts =
+ let int_ty = locate_int () in
+ let z_pos_ty = locate_z () in
+ let tyc = Smartlocate.global_inductive_with_alias ty in
+ let to_ty = Smartlocate.global_with_alias f in
+ let of_ty = Smartlocate.global_with_alias g in
+ let cty = mkRefC ty in
+ let app x y = mkAppC (x,[y]) in
+ let cref q = mkRefC q in
+ let arrow x y =
+ mkProdC ([CAst.make Anonymous],Default Decl_kinds.Explicit, x, y)
+ in
+ let cZ = cref q_z in
+ let cint = cref q_int in
+ let cuint = cref q_uint in
+ let coption = cref q_option in
+ let opt r = app coption r in
+ let constructors = get_constructors tyc in
+ (* Check the type of f *)
+ let to_kind =
+ if has_type f (arrow cint cty) then Int int_ty, Direct
+ else if has_type f (arrow cint (opt cty)) then Int int_ty, Option
+ else if has_type f (arrow cuint cty) then UInt int_ty.uint, Direct
+ else if has_type f (arrow cuint (opt cty)) then UInt int_ty.uint, Option
+ else
+ match z_pos_ty with
+ | Some z_pos_ty ->
+ if has_type f (arrow cZ cty) then Z z_pos_ty, Direct
+ else if has_type f (arrow cZ (opt cty)) then Z z_pos_ty, Option
+ else type_error_to f ty false
+ | None -> type_error_to f ty true
+ in
+ (* Check the type of g *)
+ let of_kind =
+ if has_type g (arrow cty cint) then Int int_ty, Direct
+ else if has_type g (arrow cty (opt cint)) then Int int_ty, Option
+ else if has_type g (arrow cty cuint) then UInt int_ty.uint, Direct
+ else if has_type g (arrow cty (opt cuint)) then UInt int_ty.uint, Option
+ else
+ match z_pos_ty with
+ | Some z_pos_ty ->
+ if has_type g (arrow cty cZ) then Z z_pos_ty, Direct
+ else if has_type g (arrow cty (opt cZ)) then Z z_pos_ty, Option
+ else type_error_of g ty false
+ | None -> type_error_of g ty true
+ in
+ let o = { to_kind; to_ty; of_kind; of_ty;
+ num_ty = ty;
+ warning = opts }
+ in
+ (match opts, to_kind with
+ | Abstract _, (_, Option) -> warn_abstract_large_num_no_op o.to_ty
+ | _ -> ());
+ let i =
+ { pt_local = local;
+ pt_scope = scope;
+ pt_interp_info = NumeralNotation o;
+ pt_required = Nametab.path_of_global (IndRef tyc),[];
+ pt_refs = constructors;
+ pt_in_match = true }
+ in
+ enable_prim_token_interpretation i
diff --git a/plugins/syntax/numeral.mli b/plugins/syntax/numeral.mli
new file mode 100644
index 00000000..f96b8321
--- /dev/null
+++ b/plugins/syntax/numeral.mli
@@ -0,0 +1,17 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Libnames
+open Vernacexpr
+open Notation
+
+(** * Numeral notation *)
+
+val vernac_numeral_notation : locality_flag -> qualid -> qualid -> qualid -> Notation_term.scope_name -> numnot_option -> unit
diff --git a/plugins/syntax/numeral_notation_plugin.mlpack b/plugins/syntax/numeral_notation_plugin.mlpack
new file mode 100644
index 00000000..f4d9cae3
--- /dev/null
+++ b/plugins/syntax/numeral_notation_plugin.mlpack
@@ -0,0 +1,2 @@
+Numeral
+G_numeral
diff --git a/plugins/syntax/r_syntax.ml b/plugins/syntax/r_syntax.ml
index 372e8ff3..49497aef 100644
--- a/plugins/syntax/r_syntax.ml
+++ b/plugins/syntax/r_syntax.ml
@@ -30,7 +30,7 @@ let make_dir l = DirPath.make (List.rev_map Id.of_string l)
let make_path dir id = Libnames.make_path (make_dir dir) (Id.of_string id)
let is_gr c gr = match DAst.get c with
-| GRef (r, _) -> Globnames.eq_gr r gr
+| GRef (r, _) -> GlobRef.equal r gr
| _ -> false
let positive_path = make_path binnums "positive"
@@ -66,7 +66,7 @@ let pos_of_bignat ?loc x =
let rec bignat_of_pos c = match DAst.get c with
| GApp (r, [a]) when is_gr r glob_xO -> mult_2(bignat_of_pos a)
| GApp (r, [a]) when is_gr r glob_xI -> add_1(mult_2(bignat_of_pos a))
- | GRef (a, _) when Globnames.eq_gr a glob_xH -> Bigint.one
+ | GRef (a, _) when GlobRef.equal a glob_xH -> Bigint.one
| _ -> raise Non_closed_number
(**********************************************************************)
@@ -98,7 +98,7 @@ let z_of_int ?loc n =
let bigint_of_z c = match DAst.get c with
| GApp (r,[a]) when is_gr r glob_POS -> bignat_of_pos a
| GApp (r,[a]) when is_gr r glob_NEG -> Bigint.neg (bignat_of_pos a)
- | GRef (a, _) when Globnames.eq_gr a glob_ZERO -> Bigint.zero
+ | GRef (a, _) when GlobRef.equal a glob_ZERO -> Bigint.zero
| _ -> raise Non_closed_number
(**********************************************************************)
@@ -131,9 +131,19 @@ let uninterp_r (AnyGlobConstr p) =
with Non_closed_number ->
None
-let _ = Notation.declare_numeral_interpreter "R_scope"
- (r_path,["Coq";"Reals";"Rdefinitions"])
- r_of_int
- ([DAst.make @@ GRef (glob_IZR, None)],
- uninterp_r,
- false)
+open Notation
+
+let at_declare_ml_module f x =
+ Mltop.declare_cache_obj (fun () -> f x) __coq_plugin_name
+
+let r_scope = "R_scope"
+
+let _ =
+ register_bignumeral_interpretation r_scope (r_of_int,uninterp_r);
+ at_declare_ml_module enable_prim_token_interpretation
+ { pt_local = false;
+ pt_scope = r_scope;
+ pt_interp_info = Uid r_scope;
+ pt_required = (r_path,["Coq";"Reals";"Rdefinitions"]);
+ pt_refs = [glob_IZR];
+ pt_in_match = false }
diff --git a/plugins/syntax/string_syntax.ml b/plugins/syntax/string_syntax.ml
index 2421cc12..7478c1e9 100644
--- a/plugins/syntax/string_syntax.ml
+++ b/plugins/syntax/string_syntax.ml
@@ -8,6 +8,7 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+open Names
open Globnames
open Ascii_syntax_plugin.Ascii_syntax
open Glob_term
@@ -34,7 +35,7 @@ let glob_String = lazy (make_reference "String")
let glob_EmptyString = lazy (make_reference "EmptyString")
let is_gr c gr = match DAst.get c with
-| GRef (r, _) -> Globnames.eq_gr r gr
+| GRef (r, _) -> GlobRef.equal r gr
| _ -> false
open Lazy
@@ -55,7 +56,7 @@ let uninterp_string (AnyGlobConstr r) =
(match uninterp_ascii a with
| Some c -> Buffer.add_char b (Char.chr c); aux s
| _ -> raise Non_closed_string)
- | GRef (z,_) when eq_gr z (force glob_EmptyString) ->
+ | GRef (z,_) when GlobRef.equal z (force glob_EmptyString) ->
Some (Buffer.contents b)
| _ ->
raise Non_closed_string
@@ -63,10 +64,18 @@ let uninterp_string (AnyGlobConstr r) =
with
Non_closed_string -> None
+open Notation
+
+let at_declare_ml_module f x =
+ Mltop.declare_cache_obj (fun () -> f x) __coq_plugin_name
+
let _ =
- Notation.declare_string_interpreter "string_scope"
- (string_path,["Coq";"Strings";"String"])
- interp_string
- ([DAst.make @@ GRef (static_glob_String,None);
- DAst.make @@ GRef (static_glob_EmptyString,None)],
- uninterp_string, true)
+ let sc = "string_scope" in
+ register_string_interpretation sc (interp_string,uninterp_string);
+ at_declare_ml_module enable_prim_token_interpretation
+ { pt_local = false;
+ pt_scope = sc;
+ pt_interp_info = Uid sc;
+ pt_required = (string_path,["Coq";"Strings";"String"]);
+ pt_refs = [static_glob_String; static_glob_EmptyString];
+ pt_in_match = true }
diff --git a/plugins/syntax/z_syntax.ml b/plugins/syntax/z_syntax.ml
deleted file mode 100644
index d5300e47..00000000
--- a/plugins/syntax/z_syntax.ml
+++ /dev/null
@@ -1,202 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Pp
-open CErrors
-open Util
-open Names
-open Bigint
-
-(* Poor's man DECLARE PLUGIN *)
-let __coq_plugin_name = "z_syntax_plugin"
-let () = Mltop.add_known_module __coq_plugin_name
-
-exception Non_closed_number
-
-(**********************************************************************)
-(* Parsing positive via scopes *)
-(**********************************************************************)
-
-open Globnames
-open Glob_term
-
-let binnums = ["Coq";"Numbers";"BinNums"]
-
-let make_dir l = DirPath.make (List.rev_map Id.of_string l)
-let make_path dir id = Libnames.make_path (make_dir dir) (Id.of_string id)
-
-let positive_path = make_path binnums "positive"
-
-(* TODO: temporary hack *)
-let make_kn dir id = Globnames.encode_mind dir id
-
-let positive_kn = make_kn (make_dir binnums) (Id.of_string "positive")
-let glob_positive = IndRef (positive_kn,0)
-let path_of_xI = ((positive_kn,0),1)
-let path_of_xO = ((positive_kn,0),2)
-let path_of_xH = ((positive_kn,0),3)
-let glob_xI = ConstructRef path_of_xI
-let glob_xO = ConstructRef path_of_xO
-let glob_xH = ConstructRef path_of_xH
-
-let pos_of_bignat ?loc x =
- let ref_xI = DAst.make ?loc @@ GRef (glob_xI, None) in
- let ref_xH = DAst.make ?loc @@ GRef (glob_xH, None) in
- let ref_xO = DAst.make ?loc @@ GRef (glob_xO, None) in
- let rec pos_of x =
- match div2_with_rest x with
- | (q,false) -> DAst.make ?loc @@ GApp (ref_xO,[pos_of q])
- | (q,true) when not (Bigint.equal q zero) -> DAst.make ?loc @@ GApp (ref_xI,[pos_of q])
- | (q,true) -> ref_xH
- in
- pos_of x
-
-let error_non_positive ?loc =
- user_err ?loc ~hdr:"interp_positive"
- (str "Only strictly positive numbers in type \"positive\".")
-
-let interp_positive ?loc n =
- if is_strictly_pos n then pos_of_bignat ?loc n
- else error_non_positive ?loc
-
-(**********************************************************************)
-(* Printing positive via scopes *)
-(**********************************************************************)
-
-let is_gr c gr = match DAst.get c with
-| GRef (r, _) -> Globnames.eq_gr r gr
-| _ -> false
-
-let rec bignat_of_pos x = DAst.with_val (function
- | GApp (r ,[a]) when is_gr r glob_xO -> mult_2(bignat_of_pos a)
- | GApp (r ,[a]) when is_gr r glob_xI -> add_1(mult_2(bignat_of_pos a))
- | GRef (a, _) when Globnames.eq_gr a glob_xH -> Bigint.one
- | _ -> raise Non_closed_number
- ) x
-
-let uninterp_positive (AnyGlobConstr p) =
- try
- Some (bignat_of_pos p)
- with Non_closed_number ->
- None
-
-(************************************************************************)
-(* Declaring interpreters and uninterpreters for positive *)
-(************************************************************************)
-
-let _ = Notation.declare_numeral_interpreter "positive_scope"
- (positive_path,binnums)
- interp_positive
- ([DAst.make @@ GRef (glob_xI, None);
- DAst.make @@ GRef (glob_xO, None);
- DAst.make @@ GRef (glob_xH, None)],
- uninterp_positive,
- true)
-
-(**********************************************************************)
-(* Parsing N via scopes *)
-(**********************************************************************)
-
-let n_kn = make_kn (make_dir binnums) (Id.of_string "N")
-let glob_n = IndRef (n_kn,0)
-let path_of_N0 = ((n_kn,0),1)
-let path_of_Npos = ((n_kn,0),2)
-let glob_N0 = ConstructRef path_of_N0
-let glob_Npos = ConstructRef path_of_Npos
-
-let n_path = make_path binnums "N"
-
-let n_of_binnat ?loc pos_or_neg n = DAst.make ?loc @@
- if not (Bigint.equal n zero) then
- GApp(DAst.make @@ GRef (glob_Npos,None), [pos_of_bignat ?loc n])
- else
- GRef(glob_N0, None)
-
-let error_negative ?loc =
- user_err ?loc ~hdr:"interp_N" (str "No negative numbers in type \"N\".")
-
-let n_of_int ?loc n =
- if is_pos_or_zero n then n_of_binnat ?loc true n
- else error_negative ?loc
-
-(**********************************************************************)
-(* Printing N via scopes *)
-(**********************************************************************)
-
-let bignat_of_n n = DAst.with_val (function
- | GApp (r, [a]) when is_gr r glob_Npos -> bignat_of_pos a
- | GRef (a,_) when Globnames.eq_gr a glob_N0 -> Bigint.zero
- | _ -> raise Non_closed_number
- ) n
-
-let uninterp_n (AnyGlobConstr p) =
- try Some (bignat_of_n p)
- with Non_closed_number -> None
-
-(************************************************************************)
-(* Declaring interpreters and uninterpreters for N *)
-
-let _ = Notation.declare_numeral_interpreter "N_scope"
- (n_path,binnums)
- n_of_int
- ([DAst.make @@ GRef (glob_N0, None);
- DAst.make @@ GRef (glob_Npos, None)],
- uninterp_n,
- true)
-
-(**********************************************************************)
-(* Parsing Z via scopes *)
-(**********************************************************************)
-
-let z_path = make_path binnums "Z"
-let z_kn = make_kn (make_dir binnums) (Id.of_string "Z")
-let glob_z = IndRef (z_kn,0)
-let path_of_ZERO = ((z_kn,0),1)
-let path_of_POS = ((z_kn,0),2)
-let path_of_NEG = ((z_kn,0),3)
-let glob_ZERO = ConstructRef path_of_ZERO
-let glob_POS = ConstructRef path_of_POS
-let glob_NEG = ConstructRef path_of_NEG
-
-let z_of_int ?loc n =
- if not (Bigint.equal n zero) then
- let sgn, n =
- if is_pos_or_zero n then glob_POS, n else glob_NEG, Bigint.neg n in
- DAst.make ?loc @@ GApp(DAst.make ?loc @@ GRef(sgn,None), [pos_of_bignat ?loc n])
- else
- DAst.make ?loc @@ GRef(glob_ZERO, None)
-
-(**********************************************************************)
-(* Printing Z via scopes *)
-(**********************************************************************)
-
-let bigint_of_z z = DAst.with_val (function
- | GApp (r, [a]) when is_gr r glob_POS -> bignat_of_pos a
- | GApp (r, [a]) when is_gr r glob_NEG -> Bigint.neg (bignat_of_pos a)
- | GRef (a, _) when Globnames.eq_gr a glob_ZERO -> Bigint.zero
- | _ -> raise Non_closed_number
- ) z
-
-let uninterp_z (AnyGlobConstr p) =
- try
- Some (bigint_of_z p)
- with Non_closed_number -> None
-
-(************************************************************************)
-(* Declaring interpreters and uninterpreters for Z *)
-
-let _ = Notation.declare_numeral_interpreter "Z_scope"
- (z_path,binnums)
- z_of_int
- ([DAst.make @@ GRef (glob_ZERO, None);
- DAst.make @@ GRef (glob_POS, None);
- DAst.make @@ GRef (glob_NEG, None)],
- uninterp_z,
- true)
diff --git a/plugins/syntax/z_syntax_plugin.mlpack b/plugins/syntax/z_syntax_plugin.mlpack
deleted file mode 100644
index 411260c0..00000000
--- a/plugins/syntax/z_syntax_plugin.mlpack
+++ /dev/null
@@ -1 +0,0 @@
-Z_syntax
diff --git a/pretyping/arguments_renaming.ml b/pretyping/arguments_renaming.ml
index 84295959..9d4badc6 100644
--- a/pretyping/arguments_renaming.ml
+++ b/pretyping/arguments_renaming.ml
@@ -26,7 +26,7 @@ let name_table =
type req =
| ReqLocal
- | ReqGlobal of global_reference * Name.t list
+ | ReqGlobal of GlobRef.t * Name.t list
let load_rename_args _ (_, (_, (r, names))) =
name_table := Refmap.add r names !name_table
diff --git a/pretyping/arguments_renaming.mli b/pretyping/arguments_renaming.mli
index 65e3c3be..6a776dc9 100644
--- a/pretyping/arguments_renaming.mli
+++ b/pretyping/arguments_renaming.mli
@@ -9,14 +9,13 @@
(************************************************************************)
open Names
-open Globnames
open Environ
open Constr
-val rename_arguments : bool -> global_reference -> Name.t list -> unit
+val rename_arguments : bool -> GlobRef.t -> Name.t list -> unit
(** [Not_found] is raised if no names are defined for [r] *)
-val arguments_names : global_reference -> Name.t list
+val arguments_names : GlobRef.t -> Name.t list
val rename_type_of_constant : env -> pconstant -> types
val rename_type_of_inductive : env -> pinductive -> types
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index fe0f20f8..ac00015e 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -295,8 +295,11 @@ let inductive_template evdref env tmloc ind =
| LocalAssum (na,ty) ->
let ty = EConstr.of_constr ty in
let ty' = substl subst ty in
- let e = e_new_evar env evdref ~src:(hole_source n) ty' in
- (e::subst,e::evarl,n+1)
+ let e = evd_comb1
+ (Evarutil.new_evar env ~src:(hole_source n))
+ evdref ty'
+ in
+ (e::subst,e::evarl,n+1)
| LocalDef (na,b,ty) ->
let b = EConstr.of_constr b in
(substl subst b::subst,evarl,n+1))
@@ -314,13 +317,15 @@ let try_find_ind env sigma typ realnames =
IsInd (typ,ind,names)
let inh_coerce_to_ind evdref env loc ty tyi =
- let sigma = !evdref in
+ let orig = !evdref in
let expected_typ = inductive_template evdref env loc tyi in
(* Try to refine the type with inductive information coming from the
constructor and renounce if not able to give more information *)
(* devrait être indifférent d'exiger leq ou pas puisque pour
un inductif cela doit être égal *)
- if not (e_cumul env evdref expected_typ ty) then evdref := sigma
+ match cumul env !evdref expected_typ ty with
+ | Some sigma -> evdref := sigma
+ | None -> evdref := orig
let binding_vars_of_inductive sigma = function
| NotInd _ -> []
@@ -368,15 +373,20 @@ let ltac_interp_realnames lvar = function
| t, IsInd (ty,ind,realnal) -> t, IsInd (ty,ind,List.map (ltac_interp_name lvar) realnal)
| _ as x -> x
+let is_patvar pat =
+ match DAst.get pat with
+ | PatVar _ -> true
+ | _ -> false
+
let coerce_row typing_fun evdref env lvar pats (tomatch,(na,indopt)) =
let loc = loc_of_glob_constr tomatch in
let tycon,realnames = find_tomatch_tycon evdref env loc indopt in
let j = typing_fun tycon env evdref !lvar tomatch in
- let evd, j = Coercion.inh_coerce_to_base ?loc:(loc_of_glob_constr tomatch) env !evdref j in
- evdref := evd;
+ let j = evd_comb1 (Coercion.inh_coerce_to_base ?loc:(loc_of_glob_constr tomatch) env) evdref j in
let typ = nf_evar !evdref j.uj_type in
lvar := make_return_predicate_ltac_lvar !evdref na tomatch j.uj_val !lvar;
let t =
+ if realnames = None && pats <> [] && List.for_all is_patvar pats then NotInd (None,typ) else
try try_find_ind env !evdref typ realnames
with Not_found ->
unify_tomatch_with_patterns evdref env loc typ pats realnames in
@@ -396,12 +406,8 @@ let coerce_to_indtype typing_fun evdref env lvar matx tomatchl =
(* Utils *)
let mkExistential env ?(src=(Loc.tag Evar_kinds.InternalHole)) evdref =
- let e, u = e_new_type_evar env evdref univ_flexible_alg ~src:src in e
-
-let evd_comb2 f evdref x y =
- let (evd',y) = f !evdref x y in
- evdref := evd';
- y
+ let (e, u) = evd_comb1 (new_type_evar env ~src:src) evdref univ_flexible_alg in
+ e
let adjust_tomatch_to_pattern pb ((current,typ),deps,dep) =
(* Ideally, we could find a common inductive type to which both the
@@ -424,7 +430,7 @@ let adjust_tomatch_to_pattern pb ((current,typ),deps,dep) =
let current =
if List.is_empty deps && isEvar !(pb.evdref) typ then
(* Don't insert coercions if dependent; only solve evars *)
- let _ = e_cumul pb.env pb.evdref indt typ in
+ let () = Option.iter ((:=) pb.evdref) (cumul pb.env !(pb.evdref) indt typ) in
current
else
(evd_comb2 (Coercion.inh_conv_coerce_to true pb.env)
@@ -574,7 +580,7 @@ let dependent_decl sigma a =
let rec dep_in_tomatch sigma n = function
| (Pushed _ | Alias _ | NonDepAlias) :: l -> dep_in_tomatch sigma n l
- | Abstract (_,d) :: l -> dependent_decl sigma (mkRel n) d || dep_in_tomatch sigma (n+1) l
+ | Abstract (_,d) :: l -> RelDecl.exists (fun c -> not (noccurn sigma n c)) d || dep_in_tomatch sigma (n+1) l
| [] -> false
let dependencies_in_rhs sigma nargs current tms eqns =
@@ -1014,8 +1020,8 @@ let adjust_impossible_cases pb pred tomatch submat =
begin match Constr.kind pred with
| Evar (evk,_) when snd (evar_source evk !(pb.evdref)) == Evar_kinds.ImpossibleCase ->
if not (Evd.is_defined !(pb.evdref) evk) then begin
- let evd, default = use_unit_judge !(pb.evdref) in
- pb.evdref := Evd.define evk (EConstr.Unsafe.to_constr default.uj_type) evd
+ let default = evd_comb0 use_unit_judge pb.evdref in
+ pb.evdref := Evd.define evk default.uj_type !(pb.evdref)
end;
add_assert_false_case pb tomatch
| _ ->
@@ -1425,8 +1431,9 @@ and match_current pb (initial,tomatch) =
let ci = make_case_info pb.env (fst mind) pb.casestyle in
let pred = nf_betaiota pb.env !(pb.evdref) pred in
let case =
- make_case_or_project pb.env !(pb.evdref) indf ci pred current brvals
+ make_case_or_project pb.env !(pb.evdref) indf ci pred current brvals
in
+ let _ = Evarutil.evd_comb1 (Typing.type_of pb.env) pb.evdref pred in
Typing.check_allowed_sort pb.env !(pb.evdref) mind current pred;
{ uj_val = applist (case, inst);
uj_type = prod_applist !(pb.evdref) typ inst }
@@ -1662,7 +1669,7 @@ let rec list_assoc_in_triple x = function
let abstract_tycon ?loc env evdref subst tycon extenv t =
let t = nf_betaiota env !evdref t in (* it helps in some cases to remove K-redex*)
let src = match EConstr.kind !evdref t with
- | Evar (evk,_) -> (Loc.tag ?loc @@ Evar_kinds.SubEvar evk)
+ | Evar (evk,_) -> (Loc.tag ?loc @@ Evar_kinds.SubEvar (None,evk))
| _ -> (Loc.tag ?loc @@ Evar_kinds.CasesType true) in
let subst0,t0 = adjust_to_extended_env_and_remove_deps env extenv !evdref subst t in
(* We traverse the type T of the original problem Xi looking for subterms
@@ -1681,7 +1688,7 @@ let abstract_tycon ?loc env evdref subst tycon extenv t =
(fun i _ ->
try list_assoc_in_triple i subst0 with Not_found -> mkRel i)
1 (rel_context env) in
- let ev' = e_new_evar env evdref ~src ty in
+ let ev' = evd_comb1 (Evarutil.new_evar env ~src) evdref ty in
begin match solve_simple_eqn (evar_conv_x full_transparent_state) env !evdref (None,ev,substl inst ev') with
| Success evd -> evdref := evd
| UnifFailure _ -> assert false
@@ -1698,21 +1705,24 @@ let abstract_tycon ?loc env evdref subst tycon extenv t =
let ty = get_type_of env !evdref t in
Evarutil.evd_comb1 (refresh_universes (Some false) env) evdref ty
in
- let ty = lift (-k) (aux x ty) in
+ let dummy_subst = List.init k (fun _ -> mkProp) in
+ let ty = substl dummy_subst (aux x ty) in
let depvl = free_rels !evdref ty in
let inst =
List.map_i
(fun i _ -> if Int.List.mem i vl then u else mkRel i) 1
(rel_context extenv) in
- let rel_filter =
- List.map (fun a -> not (isRel !evdref a) || dependent !evdref a u
- || Int.Set.mem (destRel !evdref a) depvl) inst in
+ let map a = match EConstr.kind !evdref a with
+ | Rel n -> not (noccurn !evdref n u) || Int.Set.mem n depvl
+ | _ -> true
+ in
+ let rel_filter = List.map map inst in
let named_filter =
List.map (fun d -> local_occur_var !evdref (NamedDecl.get_id d) u)
(named_context extenv) in
let filter = Filter.make (rel_filter @ named_filter) in
- let candidates = u :: List.map mkRel vl in
- let ev = e_new_evar extenv evdref ~src ~filter ~candidates ty in
+ let candidates = List.rev (u :: List.map mkRel vl) in
+ let ev = evd_comb1 (Evarutil.new_evar extenv ~src ~filter ~candidates) evdref ty in
lift k ev
in
aux (0,extenv,subst0) t0
@@ -1724,17 +1734,20 @@ let build_tycon ?loc env tycon_env s subst tycon extenv evdref t =
we are in an impossible branch *)
let n = Context.Rel.length (rel_context env) in
let n' = Context.Rel.length (rel_context tycon_env) in
- let impossible_case_type, u =
- e_new_type_evar (reset_context env) evdref univ_flexible_alg ~src:(Loc.tag ?loc Evar_kinds.ImpossibleCase) in
- (lift (n'-n) impossible_case_type, mkSort u)
+ let impossible_case_type, u =
+ evd_comb1
+ (new_type_evar (reset_context env) ~src:(Loc.tag ?loc Evar_kinds.ImpossibleCase))
+ evdref univ_flexible_alg
+ in
+ (lift (n'-n) impossible_case_type, mkSort u)
| Some t ->
let t = abstract_tycon ?loc tycon_env evdref subst tycon extenv t in
- let evd,tt = Typing.type_of extenv !evdref t in
- evdref := evd;
+ let tt = evd_comb1 (Typing.type_of extenv) evdref t in
(t,tt) in
- let b = e_cumul env evdref tt (mkSort s) (* side effect *) in
- if not b then anomaly (Pp.str "Build_tycon: should be a type.");
- { uj_val = t; uj_type = tt }
+ match cumul env !evdref tt (mkSort s) with
+ | None -> anomaly (Pp.str "Build_tycon: should be a type.");
+ | Some sigma -> evdref := sigma;
+ { uj_val = t; uj_type = tt }
(* For a multiple pattern-matching problem Xi on t1..tn with return
* type T, [build_inversion_problem Gamma Sigma (t1..tn) T] builds a return
@@ -1923,9 +1936,7 @@ let extract_arity_signature ?(dolift=true) env0 lvar tomatchl tmsign =
let inh_conv_coerce_to_tycon ?loc env evdref j tycon =
match tycon with
| Some p ->
- let (evd',j) = Coercion.inh_conv_coerce_to ?loc true env !evdref j p in
- evdref := evd';
- j
+ evd_comb2 (Coercion.inh_conv_coerce_to ?loc true env) evdref j p
| None -> j
(* We put the tycon inside the arity signature, possibly discovering dependencies. *)
@@ -1936,8 +1947,8 @@ let prepare_predicate_from_arsign_tycon env sigma loc tomatchs arsign c =
List.fold_right2 (fun (tm, tmtype) sign (subst, len) ->
let signlen = List.length sign in
match EConstr.kind sigma tm with
- | Rel n when dependent sigma tm c
- && Int.equal signlen 1 (* The term to match is not of a dependent type itself *) ->
+ | Rel n when Int.equal signlen 1 && not (noccurn sigma n c)
+ (* The term to match is not of a dependent type itself *) ->
((n, len) :: subst, len - signlen)
| Rel n when signlen > 1 (* The term is of a dependent type,
maybe some variable in its type appears in the tycon. *) ->
@@ -1948,13 +1959,13 @@ let prepare_predicate_from_arsign_tycon env sigma loc tomatchs arsign c =
List.fold_left
(fun (subst, len) arg ->
match EConstr.kind sigma arg with
- | Rel n when dependent sigma arg c ->
+ | Rel n when not (noccurn sigma n c) ->
((n, len) :: subst, pred len)
| _ -> (subst, pred len))
(subst, len) realargs
in
let subst =
- if dependent sigma tm c && List.for_all (isRel sigma) realargs
+ if not (noccurn sigma n c) && List.for_all (isRel sigma) realargs
then (n, len) :: subst else subst
in (subst, pred len))
| _ -> (subst, len - signlen))
@@ -2099,8 +2110,11 @@ let mk_JMeq_refl evdref typ x =
papp evdref coq_JMeq_refl [| typ; x |]
let hole na = DAst.make @@
- GHole (Evar_kinds.QuestionMark (Evar_kinds.Define false,na),
- Misctypes.IntroAnonymous, None)
+ GHole (Evar_kinds.QuestionMark {
+ Evar_kinds.qm_obligation= Evar_kinds.Define false;
+ Evar_kinds.qm_name=na;
+ Evar_kinds.qm_record_field=None},
+ IntroAnonymous, None)
let constr_of_pat env evdref arsign pat avoid =
let rec typ env (ty, realargs) pat avoid =
@@ -2581,7 +2595,8 @@ let compile_program_cases ?loc style (typing_function, evdref) tycon env lvar
let body = it_mkLambda_or_LetIn (applist (j.uj_val, args)) lets in
let j =
{ uj_val = it_mkLambda_or_LetIn body tomatchs_lets;
- uj_type = EConstr.of_constr (EConstr.to_constr !evdref tycon); }
+ (* XXX: is this normalization needed? *)
+ uj_type = Evarutil.nf_evar !evdref tycon; }
in j
(**************************************************************************)
diff --git a/pretyping/cbv.ml b/pretyping/cbv.ml
index cb0fc325..26590998 100644
--- a/pretyping/cbv.ml
+++ b/pretyping/cbv.ml
@@ -71,7 +71,7 @@ and cbv_stack =
| TOP
| APP of cbv_value array * cbv_stack
| CASE of constr * constr array * case_info * cbv_value subs * cbv_stack
- | PROJ of Projection.t * Declarations.projection_body * cbv_stack
+ | PROJ of Projection.t * cbv_stack
(* les vars pourraient etre des constr,
cela permet de retarder les lift: utile ?? *)
@@ -126,7 +126,7 @@ let rec stack_concat stk1 stk2 =
TOP -> stk2
| APP(v,stk1') -> APP(v,stack_concat stk1' stk2)
| CASE(c,b,i,s,stk1') -> CASE(c,b,i,s,stack_concat stk1' stk2)
- | PROJ (p,pinfo,stk1') -> PROJ (p,pinfo,stack_concat stk1' stk2)
+ | PROJ (p,stk1') -> PROJ (p,stack_concat stk1' stk2)
(* merge stacks when there is no shifts in between *)
let mkSTACK = function
@@ -187,7 +187,7 @@ let _ = Goptions.declare_bool_option {
Goptions.optwrite = (fun a -> debug_cbv:=a);
}
-let pr_key = function
+let debug_pr_key = function
| ConstKey (sp,_) -> Names.Constant.print sp
| VarKey id -> Names.Id.print id
| RelKey n -> Pp.(str "REL_" ++ int n)
@@ -200,7 +200,7 @@ let rec reify_stack t = function
reify_stack
(mkCase (ci, ty, t,br))
st
- | PROJ (p, pinfo, st) ->
+ | PROJ (p, st) ->
reify_stack (mkProj (p, t)) st
and reify_value = function (* reduction under binders *)
@@ -265,8 +265,7 @@ let rec norm_head info env t stack =
then Projection.unfold p
else p
in
- let pinfo = Environ.lookup_projection p (info_env info.infos) in
- norm_head info env c (PROJ (p', pinfo, stack))
+ norm_head info env c (PROJ (p', stack))
(* constants, axioms
* the first pattern is CRUCIAL, n=0 happens very often:
@@ -281,8 +280,9 @@ let rec norm_head info env t stack =
| Var id -> norm_head_ref 0 info env stack (VarKey id)
| Const sp ->
- Reductionops.reduction_effect_hook (env_of_infos info.infos) info.sigma t (lazy (reify_stack t stack));
- norm_head_ref 0 info env stack (ConstKey sp)
+ Reductionops.reduction_effect_hook (env_of_infos info.infos) info.sigma
+ (fst sp) (lazy (reify_stack t stack));
+ norm_head_ref 0 info env stack (ConstKey sp)
| LetIn (_, b, _, c) ->
(* zeta means letin are contracted; delta without zeta means we *)
@@ -320,14 +320,14 @@ and norm_head_ref k info env stack normt =
if red_set_ref (info_flags info.infos) normt then
match ref_value_cache info.infos info.tab normt with
| Some body ->
- if !debug_cbv then Feedback.msg_debug Pp.(str "Unfolding " ++ pr_key normt);
+ if !debug_cbv then Feedback.msg_debug Pp.(str "Unfolding " ++ debug_pr_key normt);
strip_appl (shift_value k body) stack
| None ->
- if !debug_cbv then Feedback.msg_debug Pp.(str "Not unfolding " ++ pr_key normt);
+ if !debug_cbv then Feedback.msg_debug Pp.(str "Not unfolding " ++ debug_pr_key normt);
(VAL(0,make_constr_ref k normt),stack)
else
begin
- if !debug_cbv then Feedback.msg_debug Pp.(str "Not unfolding " ++ pr_key normt);
+ if !debug_cbv then Feedback.msg_debug Pp.(str "Not unfolding " ++ debug_pr_key normt);
(VAL(0,make_constr_ref k normt),stack)
end
@@ -380,9 +380,9 @@ and cbv_stack_value info env = function
cbv_stack_term info stk env br.(n-1)
(* constructor in a Projection -> IOTA *)
- | (CONSTR(((sp,n),u),[||]), APP(args,PROJ(p,pi,stk)))
+ | (CONSTR(((sp,n),u),[||]), APP(args,PROJ(p,stk)))
when red_set (info_flags info.infos) fMATCH && Projection.unfolded p ->
- let arg = args.(pi.Declarations.proj_npars + pi.Declarations.proj_arg) in
+ let arg = args.(Projection.npars p + Projection.arg p) in
cbv_stack_value info env (strip_appl arg stk)
(* may be reduced later by application *)
@@ -407,7 +407,7 @@ let rec apply_stack info t = function
(mkCase (ci, cbv_norm_term info env ty, t,
Array.map (cbv_norm_term info env) br))
st
- | PROJ (p, pinfo, st) ->
+ | PROJ (p, st) ->
apply_stack info (mkProj (p, t)) st
(* performs the reduction on a constr, and returns a constr *)
@@ -455,7 +455,8 @@ let cbv_norm infos constr =
(* constant bodies are normalized at the first expansion *)
let create_cbv_infos flgs env sigma =
let infos = create
- (fun old_info tab c -> cbv_stack_term { tab; infos = old_info; sigma } TOP (subs_id 0) c)
+ ~share:true (** Not used by cbv *)
+ ~repr:(fun old_info tab c -> cbv_stack_term { tab; infos = old_info; sigma } TOP (subs_id 0) c)
flgs
env
(Reductionops.safe_evar_value sigma) in
diff --git a/pretyping/cbv.mli b/pretyping/cbv.mli
index cdaa39c5..83844c95 100644
--- a/pretyping/cbv.mli
+++ b/pretyping/cbv.mli
@@ -41,7 +41,7 @@ and cbv_stack =
| TOP
| APP of cbv_value array * cbv_stack
| CASE of constr * constr array * case_info * cbv_value subs * cbv_stack
- | PROJ of Projection.t * Declarations.projection_body * cbv_stack
+ | PROJ of Projection.t * cbv_stack
val shift_value : int -> cbv_value -> cbv_value
diff --git a/pretyping/classops.ml b/pretyping/classops.ml
index a0804b72..52e02c87 100644
--- a/pretyping/classops.ml
+++ b/pretyping/classops.ml
@@ -31,29 +31,26 @@ type cl_typ =
| CL_SECVAR of variable
| CL_CONST of Constant.t
| CL_IND of inductive
- | CL_PROJ of Constant.t
+ | CL_PROJ of Projection.Repr.t
type cl_info_typ = {
cl_param : int
}
-type coe_typ = global_reference
+type coe_typ = GlobRef.t
module CoeTypMap = Refmap_env
type coe_info_typ = {
- coe_value : constr;
- coe_type : types;
+ coe_value : GlobRef.t;
coe_local : bool;
- coe_context : Univ.ContextSet.t;
coe_is_identity : bool;
- coe_is_projection : bool;
- coe_param : int }
+ coe_is_projection : Projection.Repr.t option;
+ coe_param : int;
+}
let coe_info_typ_equal c1 c2 =
- let eq_constr c1 c2 = Termops.eq_constr Evd.empty (EConstr.of_constr c1) (EConstr.of_constr c2) in
- eq_constr c1.coe_value c2.coe_value &&
- eq_constr c1.coe_type c2.coe_type &&
+ GlobRef.equal c1.coe_value c2.coe_value &&
c1.coe_local == c2.coe_local &&
c1.coe_is_identity == c2.coe_is_identity &&
c1.coe_is_projection == c2.coe_is_projection &&
@@ -62,7 +59,7 @@ let coe_info_typ_equal c1 c2 =
let cl_typ_ord t1 t2 = match t1, t2 with
| CL_SECVAR v1, CL_SECVAR v2 -> Id.compare v1 v2
| CL_CONST c1, CL_CONST c2 -> Constant.CanOrd.compare c1 c2
- | CL_PROJ c1, CL_PROJ c2 -> Constant.CanOrd.compare c1 c2
+ | CL_PROJ c1, CL_PROJ c2 -> Projection.Repr.CanOrd.compare c1 c2
| CL_IND i1, CL_IND i2 -> ind_ord i1 i2
| _ -> Pervasives.compare t1 t2 (** OK *)
@@ -77,9 +74,7 @@ module IntMap = Map.Make(Int)
let cl_typ_eq t1 t2 = Int.equal (cl_typ_ord t1 t2) 0
-type coe_index = coe_info_typ
-
-type inheritance_path = coe_index list
+type inheritance_path = coe_info_typ list
(* table des classes, des coercions et graphe d'heritage *)
@@ -123,6 +118,9 @@ let class_tab =
let coercion_tab =
ref (CoeTypMap.empty : coe_info_typ CoeTypMap.t)
+let coercions_in_scope =
+ ref Refset_env.empty
+
module ClPairOrd =
struct
type t = cl_index * cl_index
@@ -136,12 +134,13 @@ module ClPairMap = Map.Make(ClPairOrd)
let inheritance_graph =
ref (ClPairMap.empty : inheritance_path ClPairMap.t)
-let freeze _ = (!class_tab, !coercion_tab, !inheritance_graph)
+let freeze _ = (!class_tab, !coercion_tab, !inheritance_graph, !coercions_in_scope)
-let unfreeze (fcl,fco,fig) =
+let unfreeze (fcl,fco,fig,in_scope) =
class_tab:=fcl;
coercion_tab:=fco;
- inheritance_graph:=fig
+ inheritance_graph:=fig;
+ coercions_in_scope:=in_scope
(* ajout de nouveaux "objets" *)
@@ -199,7 +198,7 @@ let find_class_type sigma t =
| Var id -> CL_SECVAR id, EInstance.empty, args
| Const (sp,u) -> CL_CONST sp, u, args
| Proj (p, c) when not (Projection.unfolded p) ->
- CL_PROJ (Projection.constant p), EInstance.empty, (c :: args)
+ CL_PROJ (Projection.repr p), EInstance.empty, (c :: args)
| Ind (ind_sp,u) -> CL_IND ind_sp, u, args
| Prod (_,_,_) -> CL_FUN, EInstance.empty, []
| Sort _ -> CL_SORT, EInstance.empty, []
@@ -211,7 +210,7 @@ let subst_cl_typ subst ct = match ct with
| CL_FUN
| CL_SECVAR _ -> ct
| CL_PROJ c ->
- let c',t = subst_con_kn subst c in
+ let c' = subst_proj_repr subst c in
if c' == c then ct else CL_PROJ c'
| CL_CONST c ->
let c',t = subst_con_kn subst c in
@@ -248,8 +247,11 @@ let class_args_of env sigma c = pi3 (find_class_type sigma c)
let string_of_class = function
| CL_FUN -> "Funclass"
| CL_SORT -> "Sortclass"
- | CL_CONST sp | CL_PROJ sp ->
- string_of_qualid (shortest_qualid_of_global Id.Set.empty (ConstRef sp))
+ | CL_CONST sp ->
+ string_of_qualid (shortest_qualid_of_global Id.Set.empty (ConstRef sp))
+ | CL_PROJ sp ->
+ let sp = Projection.Repr.constant sp in
+ string_of_qualid (shortest_qualid_of_global Id.Set.empty (ConstRef sp))
| CL_IND sp ->
string_of_qualid (shortest_qualid_of_global Id.Set.empty (IndRef sp))
| CL_SECVAR sp ->
@@ -297,31 +299,25 @@ let lookup_path_to_fun_from env sigma s =
let lookup_path_to_sort_from env sigma s =
apply_on_class_of env sigma s lookup_path_to_sort_from_class
+let mkNamed = function
+ | GlobRef.ConstRef c -> EConstr.mkConst c
+ | VarRef v -> EConstr.mkVar v
+ | ConstructRef c -> EConstr.mkConstruct c
+ | IndRef i -> EConstr.mkInd i
+
let get_coercion_constructor env coe =
- let c, _ =
- Reductionops.whd_all_stack env Evd.empty (EConstr.of_constr coe.coe_value)
- in
- match EConstr.kind Evd.empty (** FIXME *) c with
- | Construct (cstr,u) ->
- (cstr, Inductiveops.constructor_nrealargs cstr -1)
- | _ ->
- raise Not_found
+ let evd = Evd.from_env env in
+ let red x = fst (Reductionops.whd_all_stack env evd x) in
+ match EConstr.kind evd (red (mkNamed coe.coe_value)) with
+ | Constr.Construct (c, _) ->
+ c, Inductiveops.constructor_nrealargs c -1
+ | _ -> raise Not_found
let lookup_pattern_path_between env (s,t) =
let i = inductive_class_of s in
let j = inductive_class_of t in
List.map (get_coercion_constructor env) (ClPairMap.find (i,j) !inheritance_graph)
-(* coercion_value : coe_index -> unsafe_judgment * bool *)
-
-let coercion_value { coe_value = c; coe_type = t; coe_context = ctx;
- coe_is_identity = b; coe_is_projection = b' } =
- let subst, ctx = Universes.fresh_universe_context_set_instance ctx in
- let c' = Vars.subst_univs_level_constr subst c
- and t' = Vars.subst_univs_level_constr subst t in
- (make_judge (EConstr.of_constr c') (EConstr.of_constr t'), b, b'), ctx
-
-(* pretty-print functions are now in Pretty *)
(* rajouter une coercion dans le graphe *)
let path_printer : (env -> Evd.evar_map -> (Bijint.Index.t * Bijint.Index.t) * inheritance_path -> Pp.t) ref =
@@ -395,7 +391,7 @@ type coercion = {
coercion_type : coe_typ;
coercion_local : bool;
coercion_is_id : bool;
- coercion_is_proj : bool;
+ coercion_is_proj : Projection.Repr.t option;
coercion_source : cl_typ;
coercion_target : cl_typ;
coercion_params : int;
@@ -408,9 +404,8 @@ let reference_arity_length ref =
List.length (fst (Reductionops.splay_arity (Global.env()) Evd.empty (EConstr.of_constr t))) (** FIXME *)
let projection_arity_length p =
- let len = reference_arity_length (ConstRef p) in
- let pb = Environ.lookup_projection (Projection.make p false) (Global.env ()) in
- len - pb.Declarations.proj_npars
+ let len = reference_arity_length (ConstRef (Projection.Repr.constant p)) in
+ len - Projection.Repr.npars p
let class_params = function
| CL_FUN | CL_SORT -> 0
@@ -440,17 +435,13 @@ let cache_coercion env sigma (_, c) =
let () = add_class c.coercion_target in
let is, _ = class_info c.coercion_source in
let it, _ = class_info c.coercion_target in
- let value, ctx = Universes.fresh_global_instance env c.coercion_type in
- let typ = Retyping.get_type_of env sigma (EConstr.of_constr value) in
- let typ = EConstr.Unsafe.to_constr typ in
let xf =
- { coe_value = value;
- coe_type = typ;
- coe_context = ctx;
+ { coe_value = c.coercion_type;
coe_local = c.coercion_local;
coe_is_identity = c.coercion_is_id;
coe_is_projection = c.coercion_is_proj;
- coe_param = c.coercion_params } in
+ coe_param = c.coercion_params;
+ } in
let () = add_new_coercion c.coercion_type xf in
add_coercion_in_graph env sigma (xf,is,it)
@@ -458,21 +449,32 @@ let load_coercion _ o =
if !automatically_import_coercions then
cache_coercion (Global.env ()) Evd.empty o
+let set_coercion_in_scope (_, c) =
+ let r = c.coercion_type in
+ coercions_in_scope := Refset_env.add r !coercions_in_scope
+
let open_coercion i o =
- if Int.equal i 1 && not !automatically_import_coercions then
- cache_coercion (Global.env ()) Evd.empty o
+ if Int.equal i 1 then begin
+ set_coercion_in_scope o;
+ if not !automatically_import_coercions then
+ cache_coercion (Global.env ()) Evd.empty o
+ end
let subst_coercion (subst, c) =
let coe = subst_coe_typ subst c.coercion_type in
let cls = subst_cl_typ subst c.coercion_source in
let clt = subst_cl_typ subst c.coercion_target in
- if c.coercion_type == coe && c.coercion_source == cls && c.coercion_target == clt then c
- else { c with coercion_type = coe; coercion_source = cls; coercion_target = clt }
+ let clp = Option.Smart.map (subst_proj_repr subst) c.coercion_is_proj in
+ if c.coercion_type == coe && c.coercion_source == cls &&
+ c.coercion_target == clt && c.coercion_is_proj == clp
+ then c
+ else { c with coercion_type = coe; coercion_source = cls;
+ coercion_target = clt; coercion_is_proj = clp; }
let discharge_cl = function
| CL_CONST kn -> CL_CONST (Lib.discharge_con kn)
| CL_IND ind -> CL_IND (Lib.discharge_inductive ind)
- | CL_PROJ p -> CL_PROJ (Lib.discharge_con p)
+ | CL_PROJ p -> CL_PROJ (Lib.discharge_proj_repr p)
| cl -> cl
let discharge_coercion (_, c) =
@@ -489,6 +491,7 @@ let discharge_coercion (_, c) =
coercion_source = discharge_cl c.coercion_source;
coercion_target = discharge_cl c.coercion_target;
coercion_params = n + c.coercion_params;
+ coercion_is_proj = Option.map Lib.discharge_proj_repr c.coercion_is_proj;
} in
Some nc
@@ -500,7 +503,9 @@ let inCoercion : coercion -> obj =
open_function = open_coercion;
load_function = load_coercion;
cache_function = (fun objn ->
- let env = Global.env () in cache_coercion env Evd.empty objn
+ let env = Global.env () in
+ set_coercion_in_scope objn;
+ cache_coercion env Evd.empty objn
);
subst_function = subst_coercion;
classify_function = classify_coercion;
@@ -509,8 +514,8 @@ let inCoercion : coercion -> obj =
let declare_coercion coef ?(local = false) ~isid ~src:cls ~target:clt ~params:ps =
let isproj =
match coef with
- | ConstRef c -> Environ.is_projection c (Global.env ())
- | _ -> false
+ | ConstRef c -> Recordops.find_primitive_projection c
+ | _ -> None
in
let c = {
coercion_type = coef;
@@ -524,8 +529,6 @@ let declare_coercion coef ?(local = false) ~isid ~src:cls ~target:clt ~params:ps
Lib.add_anonymous_leaf (inCoercion c)
(* For printing purpose *)
-let get_coercion_value v = v.coe_value
-
let pr_cl_index = Bijint.Index.print
let classes () = Bijint.dom !class_tab
@@ -563,3 +566,6 @@ let hide_coercion coe =
let coe_info = coercion_info coe in
Some coe_info.coe_param
else None
+
+let is_coercion_in_scope r =
+ Refset_env.mem r !coercions_in_scope
diff --git a/pretyping/classops.mli b/pretyping/classops.mli
index f8600bbe..dc193c4e 100644
--- a/pretyping/classops.mli
+++ b/pretyping/classops.mli
@@ -21,7 +21,7 @@ type cl_typ =
| CL_SECVAR of variable
| CL_CONST of Constant.t
| CL_IND of inductive
- | CL_PROJ of Constant.t
+ | CL_PROJ of Projection.Repr.t
(** Equality over [cl_typ] *)
val cl_typ_eq : cl_typ -> cl_typ -> bool
@@ -36,19 +36,22 @@ type cl_info_typ = {
cl_param : int }
(** This is the type of coercion kinds *)
-type coe_typ = Globnames.global_reference
+type coe_typ = GlobRef.t
(** This is the type of infos for declared coercions *)
-type coe_info_typ
+type coe_info_typ = {
+ coe_value : GlobRef.t;
+ coe_local : bool;
+ coe_is_identity : bool;
+ coe_is_projection : Projection.Repr.t option;
+ coe_param : int;
+}
(** [cl_index] is the type of class keys *)
type cl_index
-(** [coe_index] is the type of coercion keys *)
-type coe_index
-
(** This is the type of paths from a class to another *)
-type inheritance_path = coe_index list
+type inheritance_path = coe_info_typ list
(** {6 Access to classes infos } *)
@@ -79,8 +82,6 @@ val declare_coercion :
(** {6 Access to coercions infos } *)
val coercion_exists : coe_typ -> bool
-val coercion_value : coe_index -> (unsafe_judgment * bool * bool) Univ.in_universe_context_set
-
(** {6 Lookup functions for coercion paths } *)
(** @raise Not_found in the following functions when no path exists *)
@@ -105,11 +106,12 @@ val install_path_printer :
val string_of_class : cl_typ -> string
val pr_class : cl_typ -> Pp.t
val pr_cl_index : cl_index -> Pp.t
-val get_coercion_value : coe_index -> Constr.t
val inheritance_graph : unit -> ((cl_index * cl_index) * inheritance_path) list
val classes : unit -> cl_typ list
-val coercions : unit -> coe_index list
+val coercions : unit -> coe_info_typ list
(** [hide_coercion] returns the number of params to skip if the coercion must
be hidden, [None] otherwise; it raises [Not_found] if not a coercion *)
val hide_coercion : coe_typ -> int option
+
+val is_coercion_in_scope : GlobRef.t -> bool
diff --git a/pretyping/coercion.ml b/pretyping/coercion.ml
index 04cb6a59..e15c00f7 100644
--- a/pretyping/coercion.ml
+++ b/pretyping/coercion.ml
@@ -20,6 +20,7 @@ open CErrors
open Util
open Names
open Term
+open Constr
open Environ
open EConstr
open Vars
@@ -48,31 +49,35 @@ exception NoCoercion
exception NoCoercionNoUnifier of evar_map * unification_error
(* Here, funj is a coercion therefore already typed in global context *)
-let apply_coercion_args env evd check isproj argl funj =
- let evdref = ref evd in
- let rec apply_rec acc typ = function
+let apply_coercion_args env sigma check isproj argl funj =
+ let rec apply_rec sigma acc typ = function
| [] ->
- if isproj then
- let cst = fst (destConst !evdref (j_val funj)) in
- let p = Projection.make cst false in
- let pb = lookup_projection p env in
- let args = List.skipn pb.Declarations.proj_npars argl in
- let hd, tl = match args with hd :: tl -> hd, tl | [] -> assert false in
- { uj_val = applist (mkProj (p, hd), tl);
- uj_type = typ }
- else
- { uj_val = applist (j_val funj,argl);
- uj_type = typ }
+ (match isproj with
+ | Some p ->
+ let npars = Projection.Repr.npars p in
+ let p = Projection.make p false in
+ let args = List.skipn npars argl in
+ let hd, tl = match args with hd :: tl -> hd, tl | [] -> assert false in
+ sigma, { uj_val = applist (mkProj (p, hd), tl);
+ uj_type = typ }
+ | None ->
+ sigma, { uj_val = applist (j_val funj,argl);
+ uj_type = typ })
| h::restl -> (* On devrait pouvoir s'arranger pour qu'on n'ait pas a faire hnf_constr *)
- match EConstr.kind !evdref (whd_all env !evdref typ) with
+ match EConstr.kind sigma (whd_all env sigma typ) with
| Prod (_,c1,c2) ->
- if check && not (e_cumul env evdref (Retyping.get_type_of env !evdref h) c1) then
- raise NoCoercion;
- apply_rec (h::acc) (subst1 h c2) restl
+ let sigma =
+ if check then
+ begin match cumul env sigma (Retyping.get_type_of env sigma h) c1 with
+ | None -> raise NoCoercion
+ | Some sigma -> sigma
+ end
+ else sigma
+ in
+ apply_rec sigma (h::acc) (subst1 h c2) restl
| _ -> anomaly (Pp.str "apply_coercion_args.")
in
- let res = apply_rec [] funj.uj_type argl in
- !evdref, res
+ apply_rec sigma [] funj.uj_type argl
(* appliquer le chemin de coercions de patterns p *)
let apply_pattern_coercion ?loc pat p =
@@ -93,8 +98,14 @@ let inh_pattern_coerce_to ?loc env pat ind1 ind2 =
open Program
let make_existential ?loc ?(opaque = not (get_proofs_transparency ())) na env evdref c =
- let src = Loc.tag ?loc (Evar_kinds.QuestionMark (Evar_kinds.Define opaque,na)) in
- Evarutil.e_new_evar env evdref ~src c
+ let src = Loc.tag ?loc (Evar_kinds.QuestionMark {
+ Evar_kinds.default_question_mark with
+ Evar_kinds.qm_obligation=Evar_kinds.Define opaque;
+ Evar_kinds.qm_name=na;
+ }) in
+ let evd, v = Evarutil.new_evar env !evdref ~src c in
+ evdref := evd;
+ v
let app_opt env evdref f t =
whd_betaiota !evdref (app_opt f t)
@@ -191,7 +202,8 @@ and coerce ?loc env evdref (x : EConstr.constr) (y : EConstr.constr)
(subst1 hdy restT') (succ i) (fun x -> eq_app (co x))
else Some (fun x ->
let term = co x in
- Typing.e_solve_evars env evdref term)
+ let sigma, term = Typing.solve_evars env !evdref term in
+ evdref := sigma; term)
in
if isEvar !evdref c || isEvar !evdref c' || not (Program.is_program_generalized_coercion ()) then
(* Second-order unification needed. *)
@@ -201,8 +213,8 @@ and coerce ?loc env evdref (x : EConstr.constr) (y : EConstr.constr)
match (EConstr.kind !evdref x, EConstr.kind !evdref y) with
| Sort s, Sort s' ->
(match ESorts.kind !evdref s, ESorts.kind !evdref s' with
- | Prop x, Prop y when x == y -> None
- | Prop _, Type _ -> None
+ | Prop, Prop | Set, Set -> None
+ | (Prop | Set), Type _ -> None
| Type x, Type y when Univ.Universe.equal x y -> None (* false *)
| _ -> subco ())
| Prod (name, a, b), Prod (name', a', b') ->
@@ -251,7 +263,7 @@ and coerce ?loc env evdref (x : EConstr.constr) (y : EConstr.constr)
let (n, dom, rng) = destLambda !evdref t in
if isEvar !evdref dom then
let (domk, args) = destEvar !evdref dom in
- evdref := define domk (EConstr.Unsafe.to_constr a) !evdref;
+ evdref := define domk a !evdref;
else ();
t, rng
| _ -> raise NoSubtacCoercion
@@ -337,8 +349,9 @@ let app_coercion env evdref coercion v =
match coercion with
| None -> v
| Some f ->
- let v' = Typing.e_solve_evars env evdref (f v) in
- whd_betaiota !evdref v'
+ let sigma, v' = Typing.solve_evars env !evdref (f v) in
+ evdref := sigma;
+ whd_betaiota !evdref v'
let coerce_itf ?loc env evd v t c1 =
let evdref = ref evd in
@@ -350,14 +363,25 @@ let saturate_evd env evd =
Typeclasses.resolve_typeclasses
~filter:Typeclasses.no_goals ~split:true ~fail:false env evd
+let warn_coercion_not_in_scope =
+ CWarnings.create ~name:"coercion-not-in-scope" ~category:"deprecated"
+ Pp.(fun r -> str "Coercion used but not in scope: " ++
+ Nametab.pr_global_env Id.Set.empty r ++ str ". If you want to use "
+ ++ str "this coercion, please Import the module that contains it.")
+
(* Apply coercion path from p to hj; raise NoCoercion if not applicable *)
let apply_coercion env sigma p hj typ_cl =
try
let j,t,evd =
List.fold_left
(fun (ja,typ_cl,sigma) i ->
- let ((fv,isid,isproj),ctx) = coercion_value i in
- let sigma = Evd.merge_context_set Evd.univ_flexible sigma ctx in
+ if not (is_coercion_in_scope i.coe_value) then
+ warn_coercion_not_in_scope i.coe_value;
+ let isid = i.coe_is_identity in
+ let isproj = i.coe_is_projection in
+ let sigma, c = new_global sigma i.coe_value in
+ let typ = Retyping.get_type_of env sigma c in
+ let fv = make_judge c typ in
let argl = (class_args_of env sigma typ_cl)@[ja.uj_val] in
let sigma, jres =
apply_coercion_args env sigma true isproj argl fv
@@ -370,7 +394,6 @@ let apply_coercion env sigma p hj typ_cl =
(hj,typ_cl,sigma) p
in evd, j
with NoCoercion as e -> raise e
- | e when CErrors.noncritical e -> anomaly (Pp.str "apply_coercion.")
(* Try to coerce to a funclass; raise NoCoercion if not possible *)
let inh_app_fun_core env evd j =
diff --git a/pretyping/constr_matching.ml b/pretyping/constr_matching.ml
index 0413c6b6..d7118efd 100644
--- a/pretyping/constr_matching.ml
+++ b/pretyping/constr_matching.ml
@@ -13,6 +13,7 @@ open Pp
open CErrors
open Util
open Names
+open Constr
open Globnames
open Termops
open Term
@@ -20,7 +21,6 @@ open EConstr
open Vars
open Pattern
open Patternops
-open Misctypes
open Context.Rel.Declaration
open Ltac_pretype
(*i*)
@@ -185,9 +185,36 @@ let push_binder na1 na2 t ctx =
Namegen.next_ident_away Namegen.default_non_dependent_ident avoid in
(na1, id2, t) :: ctx
-let to_fix (idx, (nas, cs, ts)) =
- let inj = EConstr.of_constr in
- (idx, (nas, Array.map inj cs, Array.map inj ts))
+(* This is an optimization of the main pattern-matching which shares
+ the longest common prefix of the body and type of a fixpoint. The
+ only practical effect at the time of writing is in binding variable
+ names: these variable names must be bound only once since the user
+ view at a fix displays only a (maximal) shared common prefix *)
+
+let rec match_under_common_fix_binders sorec sigma binding_vars ctx ctx' env env' subst t1 t2 b1 b2 =
+ match t1, EConstr.kind sigma t2, b1, EConstr.kind sigma b2 with
+ | PProd(na1,c1,t1'), Prod(na2,c2,t2'), PLambda (_,c1',b1'), Lambda (na2',c2',b2') ->
+ let ctx = push_binder na1 na2 c2 ctx in
+ let ctx' = push_binder na1 na2' c2' ctx' in
+ let env = EConstr.push_rel (LocalAssum (na2,c2)) env in
+ let subst = sorec ctx env subst c1 c2 in
+ let subst = sorec ctx env subst c1' c2' in
+ let subst = add_binders na1 na2 binding_vars subst in
+ match_under_common_fix_binders sorec sigma binding_vars
+ ctx ctx' env env' subst t1' t2' b1' b2'
+ | PLetIn(na1,c1,u1,t1), LetIn(na2,c2,u2,t2), PLetIn(_,c1',u1',b1), LetIn(na2',c2',u2',b2) ->
+ let ctx = push_binder na1 na2 u2 ctx in
+ let ctx' = push_binder na1 na2' u2' ctx' in
+ let env = EConstr.push_rel (LocalDef (na2,c2,t2)) env in
+ let subst = sorec ctx env subst c1 c2 in
+ let subst = sorec ctx env subst c1' c2' in
+ let subst = Option.fold_left (fun subst u1 -> sorec ctx env subst u1 u2) subst u1 in
+ let subst = Option.fold_left (fun subst u1' -> sorec ctx env subst u1' u2') subst u1' in
+ let subst = add_binders na1 na2 binding_vars subst in
+ match_under_common_fix_binders sorec sigma binding_vars
+ ctx ctx' env env' subst t1 t2 b1 b2
+ | _ ->
+ sorec ctx' env' (sorec ctx env subst t1 t2) b1 b2
let merge_binding sigma allow_bound_rels ctx n cT subst =
let c = match ctx with
@@ -252,9 +279,10 @@ let matches_core env sigma allow_bound_rels
| PSort ps, Sort s ->
+ let open Glob_term in
begin match ps, ESorts.kind sigma s with
- | GProp, Prop Null -> subst
- | GSet, Prop Pos -> subst
+ | GProp, Prop -> subst
+ | GSet, Set -> subst
| GType _, Type _ -> subst
| _ -> raise PatternMatchingFailure
end
@@ -366,8 +394,20 @@ let matches_core env sigma allow_bound_rels
let chk_head = sorec ctx env (sorec ctx env subst a1 a2) p1 p2 in
List.fold_left chk_branch chk_head br1
- | PFix c1, Fix _ when eq_constr sigma (mkFix (to_fix c1)) cT -> subst
- | PCoFix c1, CoFix _ when eq_constr sigma (mkCoFix (to_fix c1)) cT -> subst
+ | PFix ((ln1,i1),(lna1,tl1,bl1)), Fix ((ln2,i2),(lna2,tl2,bl2))
+ when Array.equal Int.equal ln1 ln2 && i1 = i2 ->
+ let ctx' = Array.fold_left3 (fun ctx na1 na2 t2 -> push_binder na1 na2 t2 ctx) ctx lna1 lna2 tl2 in
+ let env' = Array.fold_left2 (fun env na2 c2 -> EConstr.push_rel (LocalAssum (na2,c2)) env) env lna2 tl2 in
+ let subst = Array.fold_left4 (match_under_common_fix_binders sorec sigma binding_vars ctx ctx' env env') subst tl1 tl2 bl1 bl2 in
+ Array.fold_left2 (fun subst na1 na2 -> add_binders na1 na2 binding_vars subst) subst lna1 lna2
+
+ | PCoFix (i1,(lna1,tl1,bl1)), CoFix (i2,(lna2,tl2,bl2))
+ when i1 = i2 ->
+ let ctx' = Array.fold_left3 (fun ctx na1 na2 t2 -> push_binder na1 na2 t2 ctx) ctx lna1 lna2 tl2 in
+ let env' = Array.fold_left2 (fun env na2 c2 -> EConstr.push_rel (LocalAssum (na2,c2)) env) env lna2 tl2 in
+ let subst = Array.fold_left4 (match_under_common_fix_binders sorec sigma binding_vars ctx ctx' env env') subst tl1 tl2 bl1 bl2 in
+ Array.fold_left2 (fun subst na1 na2 -> add_binders na1 na2 binding_vars subst) subst lna1 lna2
+
| PEvar (c1,args1), Evar (c2,args2) when Evar.equal c1 c2 ->
Array.fold_left2 (sorec ctx env) subst args1 args2
| (PRef _ | PVar _ | PRel _ | PApp _ | PProj _ | PLambda _
@@ -392,7 +432,7 @@ let special_meta = (-1)
type matching_result =
{ m_sub : bound_ident_map * patvar_map;
- m_ctx : constr; }
+ m_ctx : constr Lazy.t; }
let mkresult s c n = IStream.Cons ( { m_sub=s; m_ctx=c; } , (IStream.thunk n) )
@@ -416,7 +456,7 @@ let authorized_occ env sigma closed pat c mk_ctx =
let subst = matches_core_closed env sigma pat c in
if closed && Id.Map.exists (fun _ c -> not (closed0 sigma c)) (snd subst)
then (fun next -> next ())
- else (fun next -> mkresult subst (mk_ctx (mkMeta special_meta)) next)
+ else (fun next -> mkresult subst (lazy (mk_ctx (mkMeta special_meta))) next)
with PatternMatchingFailure -> (fun next -> next ())
let subargs env v = Array.map_to_list (fun c -> (env, c)) v
diff --git a/pretyping/constr_matching.mli b/pretyping/constr_matching.mli
index 3c2c7391..d19789ef 100644
--- a/pretyping/constr_matching.mli
+++ b/pretyping/constr_matching.mli
@@ -61,7 +61,7 @@ val is_matching_head : env -> Evd.evar_map -> constr_pattern -> constr -> bool
(whose hole is denoted here with [special_meta]) *)
type matching_result =
{ m_sub : bound_ident_map * patvar_map;
- m_ctx : EConstr.t }
+ m_ctx : EConstr.t Lazy.t }
(** [match_subterm pat c] returns the substitution and the context
corresponding to each **closed** subterm of [c] matching [pat],
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index 9ba5949a..0dc5a9ba 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -14,6 +14,7 @@ open Pp
open CErrors
open Util
open Names
+open Constr
open Term
open EConstr
open Vars
@@ -26,7 +27,6 @@ open Libnames
open Globnames
open Nametab
open Mod_subst
-open Misctypes
open Decl_kinds
open Context.Named.Declaration
open Ltac_pretype
@@ -36,7 +36,7 @@ type _ delay =
| Later : [ `thunk ] delay
(** Should we keep details of universes during detyping ? *)
-let print_universes = Flags.univ_print
+let print_universes = ref false
(** If true, prints local context of evars, whatever print_arguments *)
let print_evar_arguments = ref false
@@ -87,7 +87,7 @@ let encode_tuple ({CAst.loc} as r) =
module PrintingInductiveMake =
functor (Test : sig
- val encode : reference -> inductive
+ val encode : qualid -> inductive
val member_message : Pp.t -> bool -> Pp.t
val field : string
val title : string
@@ -501,13 +501,104 @@ let detype_case computable detype detype_eqns testdep avoid data p c bl =
let eqnl = detype_eqns constructs constagsl bl in
GCases (tag,pred,[tomatch,(alias,aliastyp)],eqnl)
+let rec share_names detype n l avoid env sigma c t =
+ match EConstr.kind sigma c, EConstr.kind sigma t with
+ (* factorize even when not necessary to have better presentation *)
+ | Lambda (na,t,c), Prod (na',t',c') ->
+ let na = match (na,na') with
+ Name _, _ -> na
+ | _, Name _ -> na'
+ | _ -> na in
+ let t' = detype avoid env sigma t in
+ let id = next_name_away na avoid in
+ let avoid = Id.Set.add id avoid and env = add_name (Name id) None t env in
+ share_names detype (n-1) ((Name id,Explicit,None,t')::l) avoid env sigma c c'
+ (* May occur for fix built interactively *)
+ | LetIn (na,b,t',c), _ when n > 0 ->
+ let t'' = detype avoid env sigma t' in
+ let b' = detype avoid env sigma b in
+ let id = next_name_away na avoid in
+ let avoid = Id.Set. add id avoid and env = add_name (Name id) (Some b) t' env in
+ share_names detype n ((Name id,Explicit,Some b',t'')::l) avoid env sigma c (lift 1 t)
+ (* Only if built with the f/n notation or w/o let-expansion in types *)
+ | _, LetIn (_,b,_,t) when n > 0 ->
+ share_names detype n l avoid env sigma c (subst1 b t)
+ (* If it is an open proof: we cheat and eta-expand *)
+ | _, Prod (na',t',c') when n > 0 ->
+ let t'' = detype avoid env sigma t' in
+ let id = next_name_away na' avoid in
+ let avoid = Id.Set.add id avoid and env = add_name (Name id) None t' env in
+ let appc = mkApp (lift 1 c,[|mkRel 1|]) in
+ share_names detype (n-1) ((Name id,Explicit,None,t'')::l) avoid env sigma appc c'
+ (* If built with the f/n notation: we renounce to share names *)
+ | _ ->
+ if n>0 then Feedback.msg_debug (strbrk "Detyping.detype: cannot factorize fix enough");
+ let c = detype avoid env sigma c in
+ let t = detype avoid env sigma t in
+ (List.rev l,c,t)
+
+let rec share_pattern_names detype n l avoid env sigma c t =
+ let open Pattern in
+ if n = 0 then
+ let c = detype avoid env sigma c in
+ let t = detype avoid env sigma t in
+ (List.rev l,c,t)
+ else match c, t with
+ | PLambda (na,t,c), PProd (na',t',c') ->
+ let na = match (na,na') with
+ Name _, _ -> na
+ | _, Name _ -> na'
+ | _ -> na in
+ let t' = detype avoid env sigma t in
+ let id = next_name_away na avoid in
+ let avoid = Id.Set.add id avoid in
+ let env = Name id :: env in
+ share_pattern_names detype (n-1) ((Name id,Explicit,None,t')::l) avoid env sigma c c'
+ | _ ->
+ if n>0 then Feedback.msg_debug (strbrk "Detyping.detype: cannot factorize fix enough");
+ let c = detype avoid env sigma c in
+ let t = detype avoid env sigma t in
+ (List.rev l,c,t)
+
+let detype_fix detype avoid env sigma (vn,_ as nvn) (names,tys,bodies) =
+ let def_avoid, def_env, lfi =
+ Array.fold_left2
+ (fun (avoid, env, l) na ty ->
+ let id = next_name_away na avoid in
+ (Id.Set.add id avoid, add_name (Name id) None ty env, id::l))
+ (avoid, env, []) names tys in
+ let n = Array.length tys in
+ let v = Array.map3
+ (fun c t i -> share_names detype (i+1) [] def_avoid def_env sigma c (lift n t))
+ bodies tys vn in
+ GRec(GFix (Array.map (fun i -> Some i, GStructRec) (fst nvn), snd nvn),Array.of_list (List.rev lfi),
+ Array.map (fun (bl,_,_) -> bl) v,
+ Array.map (fun (_,_,ty) -> ty) v,
+ Array.map (fun (_,bd,_) -> bd) v)
+
+let detype_cofix detype avoid env sigma n (names,tys,bodies) =
+ let def_avoid, def_env, lfi =
+ Array.fold_left2
+ (fun (avoid, env, l) na ty ->
+ let id = next_name_away na avoid in
+ (Id.Set.add id avoid, add_name (Name id) None ty env, id::l))
+ (avoid, env, []) names tys in
+ let ntys = Array.length tys in
+ let v = Array.map2
+ (fun c t -> share_names detype 0 [] def_avoid def_env sigma c (lift ntys t))
+ bodies tys in
+ GRec(GCoFix n,Array.of_list (List.rev lfi),
+ Array.map (fun (bl,_,_) -> bl) v,
+ Array.map (fun (_,_,ty) -> ty) v,
+ Array.map (fun (_,bd,_) -> bd) v)
+
let detype_universe sigma u =
let fn (l, n) = Some (Termops.reference_of_level sigma l, n) in
Univ.Universe.map fn u
let detype_sort sigma = function
- | Prop Null -> GProp
- | Prop Pos -> GSet
+ | Prop -> GProp
+ | Set -> GSet
| Type u ->
GType
(if !print_universes
@@ -584,13 +675,12 @@ and detype_r d flags avoid env sigma t =
(Array.map_to_list (detype d flags avoid env sigma) args)
| Const (sp,u) -> GRef (ConstRef sp, detype_instance sigma u)
| Proj (p,c) ->
- let noparams () =
- let pb = Environ.lookup_projection p (snd env) in
- let pars = pb.Declarations.proj_npars in
- let hole = DAst.make @@ GHole(Evar_kinds.InternalHole,Misctypes.IntroAnonymous,None) in
- let args = List.make pars hole in
- GApp (DAst.make @@ GRef (ConstRef (Projection.constant p), None),
- (args @ [detype d flags avoid env sigma c]))
+ let noparams () =
+ let pars = Projection.npars p in
+ let hole = DAst.make @@ GHole(Evar_kinds.InternalHole,Namegen.IntroAnonymous,None) in
+ let args = List.make pars hole in
+ GApp (DAst.make @@ GRef (ConstRef (Projection.constant p), None),
+ (args @ [detype d flags avoid env sigma c]))
in
if fst flags || !Flags.in_debugger || !Flags.in_toplevel then
try noparams ()
@@ -603,8 +693,9 @@ and detype_r d flags avoid env sigma t =
(** Print the compatibility match version *)
let c' =
try
- let pb = Environ.lookup_projection p (snd env) in
- let body = pb.Declarations.proj_body in
+ let ind = Projection.inductive p in
+ let bodies = Inductiveops.legacy_match_projection (snd env) ind in
+ let body = bodies.(Projection.arg p) in
let ty = Retyping.get_type_of (snd env) sigma c in
let ((ind,u), args) = Inductiveops.find_mrectype (snd env) sigma ty in
let body' = strip_lam_assum body in
@@ -660,76 +751,8 @@ and detype_r d flags avoid env sigma t =
(ci.ci_ind,ci.ci_pp_info.style,
ci.ci_pp_info.cstr_tags,ci.ci_pp_info.ind_tags)
p c bl
- | Fix (nvn,recdef) -> detype_fix d flags avoid env sigma nvn recdef
- | CoFix (n,recdef) -> detype_cofix d flags avoid env sigma n recdef
-
-and detype_fix d flags avoid env sigma (vn,_ as nvn) (names,tys,bodies) =
- let def_avoid, def_env, lfi =
- Array.fold_left2
- (fun (avoid, env, l) na ty ->
- let id = next_name_away na avoid in
- (Id.Set.add id avoid, add_name (Name id) None ty env, id::l))
- (avoid, env, []) names tys in
- let n = Array.length tys in
- let v = Array.map3
- (fun c t i -> share_names d flags (i+1) [] def_avoid def_env sigma c (lift n t))
- bodies tys vn in
- GRec(GFix (Array.map (fun i -> Some i, GStructRec) (fst nvn), snd nvn),Array.of_list (List.rev lfi),
- Array.map (fun (bl,_,_) -> bl) v,
- Array.map (fun (_,_,ty) -> ty) v,
- Array.map (fun (_,bd,_) -> bd) v)
-
-and detype_cofix d flags avoid env sigma n (names,tys,bodies) =
- let def_avoid, def_env, lfi =
- Array.fold_left2
- (fun (avoid, env, l) na ty ->
- let id = next_name_away na avoid in
- (Id.Set.add id avoid, add_name (Name id) None ty env, id::l))
- (avoid, env, []) names tys in
- let ntys = Array.length tys in
- let v = Array.map2
- (fun c t -> share_names d flags 0 [] def_avoid def_env sigma c (lift ntys t))
- bodies tys in
- GRec(GCoFix n,Array.of_list (List.rev lfi),
- Array.map (fun (bl,_,_) -> bl) v,
- Array.map (fun (_,_,ty) -> ty) v,
- Array.map (fun (_,bd,_) -> bd) v)
-
-and share_names d flags n l avoid env sigma c t =
- match EConstr.kind sigma c, EConstr.kind sigma t with
- (* factorize even when not necessary to have better presentation *)
- | Lambda (na,t,c), Prod (na',t',c') ->
- let na = match (na,na') with
- Name _, _ -> na
- | _, Name _ -> na'
- | _ -> na in
- let t' = detype d flags avoid env sigma t in
- let id = next_name_away na avoid in
- let avoid = Id.Set.add id avoid and env = add_name (Name id) None t env in
- share_names d flags (n-1) ((Name id,Explicit,None,t')::l) avoid env sigma c c'
- (* May occur for fix built interactively *)
- | LetIn (na,b,t',c), _ when n > 0 ->
- let t'' = detype d flags avoid env sigma t' in
- let b' = detype d flags avoid env sigma b in
- let id = next_name_away na avoid in
- let avoid = Id.Set. add id avoid and env = add_name (Name id) (Some b) t' env in
- share_names d flags n ((Name id,Explicit,Some b',t'')::l) avoid env sigma c (lift 1 t)
- (* Only if built with the f/n notation or w/o let-expansion in types *)
- | _, LetIn (_,b,_,t) when n > 0 ->
- share_names d flags n l avoid env sigma c (subst1 b t)
- (* If it is an open proof: we cheat and eta-expand *)
- | _, Prod (na',t',c') when n > 0 ->
- let t'' = detype d flags avoid env sigma t' in
- let id = next_name_away na' avoid in
- let avoid = Id.Set.add id avoid and env = add_name (Name id) None t' env in
- let appc = mkApp (lift 1 c,[|mkRel 1|]) in
- share_names d flags (n-1) ((Name id,Explicit,None,t'')::l) avoid env sigma appc c'
- (* If built with the f/n notation: we renounce to share names *)
- | _ ->
- if n>0 then Feedback.msg_debug (strbrk "Detyping.detype: cannot factorize fix enough");
- let c = detype d flags avoid env sigma c in
- let t = detype d flags avoid env sigma t in
- (List.rev l,c,t)
+ | Fix (nvn,recdef) -> detype_fix (detype d flags) avoid env sigma nvn recdef
+ | CoFix (n,recdef) -> detype_cofix (detype d flags) avoid env sigma n recdef
and detype_eqns d flags avoid env sigma ci computable constructs consnargsl bl =
try
@@ -902,7 +925,7 @@ let rec subst_cases_pattern subst = DAst.map (function
| PatVar _ as pat -> pat
| PatCstr (((kn,i),j),cpl,n) as pat ->
let kn' = subst_mind subst kn
- and cpl' = List.smartmap (subst_cases_pattern subst) cpl in
+ and cpl' = List.Smart.map (subst_cases_pattern subst) cpl in
if kn' == kn && cpl' == cpl then pat else
PatCstr (((kn',i),j),cpl',n)
)
@@ -911,9 +934,11 @@ let (f_subst_genarg, subst_genarg_hook) = Hook.make ()
let rec subst_glob_constr subst = DAst.map (function
| GRef (ref,u) as raw ->
- let ref',t = subst_global subst ref in
- if ref' == ref then raw else
- DAst.get (detype Now false Id.Set.empty (Global.env()) Evd.empty (EConstr.of_constr t))
+ let ref',t = subst_global subst ref in
+ if ref' == ref then raw else
+ let env = Global.env () in
+ let evd = Evd.from_env env in
+ DAst.get (detype Now false Id.Set.empty env evd (EConstr.of_constr t))
| GSort _
| GVar _
@@ -922,7 +947,7 @@ let rec subst_glob_constr subst = DAst.map (function
| GApp (r,rl) as raw ->
let r' = subst_glob_constr subst r
- and rl' = List.smartmap (subst_glob_constr subst) rl in
+ and rl' = List.Smart.map (subst_glob_constr subst) rl in
if r' == r && rl' == rl then raw else
GApp(r',rl')
@@ -939,25 +964,25 @@ let rec subst_glob_constr subst = DAst.map (function
| GLetIn (n,r1,t,r2) as raw ->
let r1' = subst_glob_constr subst r1 in
let r2' = subst_glob_constr subst r2 in
- let t' = Option.smartmap (subst_glob_constr subst) t in
+ let t' = Option.Smart.map (subst_glob_constr subst) t in
if r1' == r1 && t == t' && r2' == r2 then raw else
GLetIn (n,r1',t',r2')
| GCases (sty,rtno,rl,branches) as raw ->
let open CAst in
- let rtno' = Option.smartmap (subst_glob_constr subst) rtno
- and rl' = List.smartmap (fun (a,x as y) ->
+ let rtno' = Option.Smart.map (subst_glob_constr subst) rtno
+ and rl' = List.Smart.map (fun (a,x as y) ->
let a' = subst_glob_constr subst a in
let (n,topt) = x in
- let topt' = Option.smartmap
+ let topt' = Option.Smart.map
(fun ({loc;v=((sp,i),y)} as t) ->
let sp' = subst_mind subst sp in
if sp == sp' then t else CAst.(make ?loc ((sp',i),y))) topt in
if a == a' && topt == topt' then y else (a',(n,topt'))) rl
- and branches' = List.smartmap
+ and branches' = List.Smart.map
(fun ({loc;v=(idl,cpl,r)} as branch) ->
let cpl' =
- List.smartmap (subst_cases_pattern subst) cpl
+ List.Smart.map (subst_cases_pattern subst) cpl
and r' = subst_glob_constr subst r in
if cpl' == cpl && r' == r then branch else
CAst.(make ?loc (idl,cpl',r')))
@@ -967,14 +992,14 @@ let rec subst_glob_constr subst = DAst.map (function
GCases (sty,rtno',rl',branches')
| GLetTuple (nal,(na,po),b,c) as raw ->
- let po' = Option.smartmap (subst_glob_constr subst) po
+ let po' = Option.Smart.map (subst_glob_constr subst) po
and b' = subst_glob_constr subst b
and c' = subst_glob_constr subst c in
if po' == po && b' == b && c' == c then raw else
GLetTuple (nal,(na,po'),b',c')
| GIf (c,(na,po),b1,b2) as raw ->
- let po' = Option.smartmap (subst_glob_constr subst) po
+ let po' = Option.Smart.map (subst_glob_constr subst) po
and b1' = subst_glob_constr subst b1
and b2' = subst_glob_constr subst b2
and c' = subst_glob_constr subst c in
@@ -982,12 +1007,12 @@ let rec subst_glob_constr subst = DAst.map (function
GIf (c',(na,po'),b1',b2')
| GRec (fix,ida,bl,ra1,ra2) as raw ->
- let ra1' = Array.smartmap (subst_glob_constr subst) ra1
- and ra2' = Array.smartmap (subst_glob_constr subst) ra2 in
- let bl' = Array.smartmap
- (List.smartmap (fun (na,k,obd,ty as dcl) ->
+ let ra1' = Array.Smart.map (subst_glob_constr subst) ra1
+ and ra2' = Array.Smart.map (subst_glob_constr subst) ra2 in
+ let bl' = Array.Smart.map
+ (List.Smart.map (fun (na,k,obd,ty as dcl) ->
let ty' = subst_glob_constr subst ty in
- let obd' = Option.smartmap (subst_glob_constr subst) obd in
+ let obd' = Option.Smart.map (subst_glob_constr subst) obd in
if ty'==ty && obd'==obd then dcl else (na,k,obd',ty')))
bl in
if ra1' == ra1 && ra2' == ra2 && bl'==bl then raw else
@@ -1000,14 +1025,15 @@ let rec subst_glob_constr subst = DAst.map (function
if nref == ref then knd else Evar_kinds.ImplicitArg (nref, i, b)
| _ -> knd
in
- let nsolve = Option.smartmap (Hook.get f_subst_genarg subst) solve in
+ let nsolve = Option.Smart.map (Hook.get f_subst_genarg subst) solve in
if nsolve == solve && nknd == knd then raw
else GHole (nknd, naming, nsolve)
| GCast (r1,k) as raw ->
let r1' = subst_glob_constr subst r1 in
- let k' = Miscops.smartmap_cast_type (subst_glob_constr subst) k in
+ let k' = smartmap_cast_type (subst_glob_constr subst) k in
if r1' == r1 && k' == k then raw else GCast (r1',k')
+
)
(* Utilities to transform kernel cases to simple pattern-matching problem *)
diff --git a/pretyping/detyping.mli b/pretyping/detyping.mli
index 32b94e1b..8695d52b 100644
--- a/pretyping/detyping.mli
+++ b/pretyping/detyping.mli
@@ -14,7 +14,6 @@ open EConstr
open Glob_term
open Termops
open Mod_subst
-open Misctypes
open Evd
open Ltac_pretype
@@ -56,6 +55,13 @@ val detype_sort : evar_map -> Sorts.t -> glob_sort
val detype_rel_context : 'a delay -> ?lax:bool -> constr option -> Id.Set.t -> (names_context * env) ->
evar_map -> rel_context -> 'a glob_decl_g list
+val share_pattern_names :
+ (Id.Set.t -> names_context -> 'c -> Pattern.constr_pattern -> 'a) -> int ->
+ (Name.t * Decl_kinds.binding_kind * 'b option * 'a) list ->
+ Id.Set.t -> names_context -> 'c -> Pattern.constr_pattern ->
+ Pattern.constr_pattern ->
+ (Name.t * Decl_kinds.binding_kind * 'b option * 'a) list * 'a * 'a
+
val detype_closed_glob : ?lax:bool -> bool -> Id.Set.t -> env -> evar_map -> closed_glob_constr -> glob_constr
(** look for the index of a named var or a nondep var as it is renamed *)
@@ -81,7 +87,7 @@ val subst_genarg_hook :
module PrintingInductiveMake :
functor (Test : sig
- val encode : Libnames.reference -> Names.inductive
+ val encode : Libnames.qualid -> Names.inductive
val member_message : Pp.t -> bool -> Pp.t
val field : string
val title : string
@@ -89,7 +95,7 @@ module PrintingInductiveMake :
sig
type t = Names.inductive
val compare : t -> t -> int
- val encode : Libnames.reference -> Names.inductive
+ val encode : Libnames.qualid -> Names.inductive
val subst : substitution -> t -> t
val printer : t -> Pp.t
val key : Goptions.option_name
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index d37090a6..7d480b8d 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -49,7 +49,7 @@ let _ = Goptions.declare_bool_option {
(* XXX: we would like to search for this with late binding
"data.id.type" etc... *)
let impossible_default_case () =
- let c, ctx = Universes.fresh_global_instance (Global.env()) (Globnames.ConstRef Coqlib.id) in
+ let c, ctx = UnivGen.fresh_global_instance (Global.env()) (Globnames.ConstRef Coqlib.id) in
let (_, u) = Constr.destConst c in
Some (c, Constr.mkConstU (Coqlib.type_of_id, u), ctx)
@@ -71,7 +71,7 @@ let coq_unit_judge =
let unfold_projection env evd ts p c =
let cst = Projection.constant p in
if is_transparent_constant ts cst then
- Some (mkProj (Projection.make cst true, c))
+ Some (mkProj (Projection.unfold p, c))
else None
let eval_flexible_term ts env evd c =
@@ -114,9 +114,6 @@ let flex_kind_of_term ts env evd c sk =
| Fix _ -> Rigid (* happens when the fixpoint is partially applied *)
| Cast _ | App _ | Case _ -> assert false
-let add_conv_pb (pb, env, x, y) sigma =
- Evd.add_conv_pb (pb, env, EConstr.Unsafe.to_constr x, EConstr.Unsafe.to_constr y) sigma
-
let apprec_nohdbeta ts env evd c =
let (t,sk as appr) = Reductionops.whd_nored_state evd (c, []) in
if Stack.not_purely_applicative sk
@@ -213,7 +210,7 @@ let check_conv_record env sigma (t1,sk1) (t2,sk2) =
else match (Stack.strip_n_app (l_us-1) sk2_effective) with
| None -> raise Not_found
| Some (l',el,s') -> (l'@Stack.append_app [|el|] Stack.empty,s') in
- let u, ctx' = Universes.fresh_instance_from ctx None in
+ let u, ctx' = UnivGen.fresh_instance_from ctx None in
let subst = Univ.make_inverse_instance_subst u in
let c = EConstr.of_constr c in
let c' = subst_univs_level_constr subst c in
@@ -295,8 +292,8 @@ let ise_stack2 no_app env evd f sk1 sk2 =
| Success i'' -> ise_stack2 true i'' q1 q2
| UnifFailure _ as x -> fail x)
| UnifFailure _ as x -> fail x)
- | Stack.Proj (n1,a1,p1,_)::q1, Stack.Proj (n2,a2,p2,_)::q2 ->
- if Constant.equal (Projection.constant p1) (Projection.constant p2)
+ | Stack.Proj (p1,_)::q1, Stack.Proj (p2,_)::q2 ->
+ if Projection.Repr.equal (Projection.repr p1) (Projection.repr p2)
then ise_stack2 true i q1 q2
else fail (UnifFailure (i, NotSameHead))
| Stack.Fix (((li1, i1),(_,tys1,bds1 as recdef1)),a1,_)::q1,
@@ -337,8 +334,8 @@ let exact_ise_stack2 env evd f sk1 sk2 =
(fun i -> ise_array2 i (fun ii -> f (push_rec_types recdef1 env) ii CONV) bds1 bds2);
(fun i -> ise_stack2 i a1 a2)]
else UnifFailure (i,NotSameHead)
- | Stack.Proj (n1,a1,p1,_)::q1, Stack.Proj (n2,a2,p2,_)::q2 ->
- if Constant.equal (Projection.constant p1) (Projection.constant p2)
+ | Stack.Proj (p1,_)::q1, Stack.Proj (p2,_)::q2 ->
+ if Projection.Repr.equal (Projection.repr p1) (Projection.repr p2)
then ise_stack2 i q1 q2
else (UnifFailure (i, NotSameHead))
| Stack.App _ :: _, Stack.App _ :: _ ->
@@ -369,13 +366,10 @@ let rec evar_conv_x ts env evd pbty term1 term2 =
let ground_test =
if is_ground_term evd term1 && is_ground_term evd term2 then (
let e =
- try
- let evd, b = infer_conv ~catch_incon:false ~pb:pbty ~ts:(fst ts)
- env evd term1 term2
- in
- if b then Success evd
- else UnifFailure (evd, ConversionFailed (env,term1,term2))
- with Univ.UniverseInconsistency e -> UnifFailure (evd, UnifUnivInconsistency e)
+ match infer_conv ~catch_incon:false ~pb:pbty ~ts:(fst ts) env evd term1 term2 with
+ | Some evd -> Success evd
+ | None -> UnifFailure (evd, ConversionFailed (env,term1,term2))
+ | exception Univ.UniverseInconsistency e -> UnifFailure (evd, UnifUnivInconsistency e)
in
match e with
| UnifFailure (evd, e) when not (is_ground_env evd env) -> None
@@ -516,7 +510,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
let tM = Stack.zip evd apprM in
miller_pfenning on_left
(fun () -> if not_only_app then (* Postpone the use of an heuristic *)
- switch (fun x y -> Success (add_conv_pb (pbty,env,x,y) i)) (Stack.zip evd apprF) tM
+ switch (fun x y -> Success (Evarutil.add_unification_pb (pbty,env,x,y) i)) (Stack.zip evd apprF) tM
else quick_fail i)
ev lF tM i
and consume (termF,skF as apprF) (termM,skM as apprM) i =
@@ -584,7 +578,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
i,mkEvar ev
else
i,Stack.zip evd apprF in
- switch (fun x y -> Success (add_conv_pb (pbty,env,x,y) i))
+ switch (fun x y -> Success (Evarutil.add_unification_pb (pbty,env,x,y) i))
tF tR
else
UnifFailure (evd,OccurCheck (fst ev,tR)))])
@@ -594,7 +588,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
(* Evar must be undefined since we have flushed evars *)
let () = if !debug_unification then
let open Pp in
- Feedback.msg_notice (v 0 (pr_state appr1 ++ cut () ++ pr_state appr2 ++ cut ())) in
+ Feedback.msg_notice (v 0 (pr_state env evd appr1 ++ cut () ++ pr_state env evd appr2 ++ cut ())) in
match (flex_kind_of_term (fst ts) env evd term1 sk1,
flex_kind_of_term (fst ts) env evd term2 sk2) with
| Flexible (sp1,al1 as ev1), Flexible (sp2,al2 as ev2) ->
@@ -990,10 +984,11 @@ and conv_record trs env evd (ctx,(h,h2),c,bs,(params,params1),(us,us2),(sk1,sk2)
else UnifFailure(evd,(*dummy*)NotSameHead)
and eta_constructor ts env evd sk1 ((ind, i), u) sk2 term2 =
+ let open Declarations in
let mib = lookup_mind (fst ind) env in
- match mib.Declarations.mind_record with
- | Some (Some (id, projs, pbs)) when mib.Declarations.mind_finite == Declarations.BiFinite ->
- let pars = mib.Declarations.mind_nparams in
+ match get_projections env ind with
+ | Some projs when mib.mind_finite == BiFinite ->
+ let pars = mib.mind_nparams in
(try
let l1' = Stack.tail pars sk1 in
let l2' =
@@ -1045,7 +1040,7 @@ let choose_less_dependent_instance evk evd term args =
let subst' = List.filter (fun (id,c) -> EConstr.eq_constr evd c term) subst in
match subst' with
| [] -> None
- | (id, _) :: _ -> Some (Evd.define evk (Constr.mkVar id) evd)
+ | (id, _) :: _ -> Some (Evd.define evk (mkVar id) evd)
let apply_on_subterm env evdref f c t =
let rec applyrec (env,(k,c) as acc) t =
@@ -1085,7 +1080,7 @@ let filter_possible_projections evd c ty ctxt args =
let a = Array.unsafe_get args i in
(match decl with
| NamedDecl.LocalAssum _ -> false
- | NamedDecl.LocalDef (_,c,_) -> not (isRel evd (EConstr.of_constr c) || isVar evd (EConstr.of_constr c))) ||
+ | NamedDecl.LocalDef (_,c,_) -> not (isRel evd c || isVar evd c)) ||
a == c ||
(* Here we make an approximation, for instance, we could also be *)
(* interested in finding a term u convertible to c such that a occurs *)
@@ -1135,7 +1130,7 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
end
| decl'::ctxt', c::l, occs::occsl ->
let id = NamedDecl.get_id decl' in
- let t = EConstr.of_constr (NamedDecl.get_type decl') in
+ let t = NamedDecl.get_type decl' in
let evs = ref [] in
let ty = Retyping.get_type_of env_rhs evd c in
let filter' = filter_possible_projections evd c ty ctxt args in
@@ -1162,17 +1157,18 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
let subst = make_subst (ctxt,Array.to_list args,argoccs) in
- let evdref = ref evd in
- let rhs = set_holes evdref rhs subst in
- let evd = !evdref in
+ let evd, rhs =
+ let evdref = ref evd in
+ let rhs = set_holes evdref rhs subst in
+ !evdref, rhs
+ in
(* We instantiate the evars of which the value is forced by typing *)
let evd,rhs =
- let evdref = ref evd in
- try let c = !solve_evars env_evar evdref rhs in !evdref,c
+ try !solve_evars env_evar evd rhs
with e when Pretype_errors.precatchable_exception e ->
(* Could not revert all subterms *)
- raise (TypingFailed !evdref) in
+ raise (TypingFailed evd) in
let rec abstract_free_holes evd = function
| (id,idty,c,_,evsref,_,_)::l ->
@@ -1183,7 +1179,7 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
(* We force abstraction over this unconstrained occurrence *)
(* and we use typing to propagate this instantiation *)
(* This is an arbitrary choice *)
- let evd = Evd.define evk (Constr.mkVar id) evd in
+ let evd = Evd.define evk (mkVar id) evd in
match evar_conv_x ts env_evar evd CUMUL idty evty with
| UnifFailure _ -> user_err Pp.(str "Cannot find an instance")
| Success evd ->
@@ -1205,14 +1201,11 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
(evar_conv_x full_transparent_state)
with IllTypedInstance _ -> raise (TypingFailed evd)
in
- Evd.define evk (EConstr.Unsafe.to_constr rhs) evd
+ Evd.define evk rhs evd
in
abstract_free_holes evd subst, true
with TypingFailed evd -> evd, false
-let to_pb (pb, env, t1, t2) =
- (pb, env, EConstr.Unsafe.to_constr t1, EConstr.Unsafe.to_constr t2)
-
let second_order_matching_with_args ts env evd pbty ev l t =
(*
let evd,ev = evar_absorb_arguments env evd ev l in
@@ -1222,7 +1215,7 @@ let second_order_matching_with_args ts env evd pbty ev l t =
else UnifFailure (evd, ConversionFailed (env,mkApp(mkEvar ev,l),t))
if b then Success evd else
*)
- let pb = to_pb (pbty,env,mkApp(mkEvar ev,l),t) in
+ let pb = (pbty,env,mkApp(mkEvar ev,l),t) in
UnifFailure (evd, CannotSolveConstraint (pb,ProblemBeyondCapabilities))
let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
@@ -1232,8 +1225,9 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
let (term2,l2 as appr2) = try destApp evd t2 with DestKO -> (t2, [||]) in
let () = if !debug_unification then
let open Pp in
- Feedback.msg_notice (v 0 (str "Heuristic:" ++ spc () ++ print_constr t1
- ++ cut () ++ print_constr t2 ++ cut ())) in
+ Feedback.msg_notice (v 0 (str "Heuristic:" ++ spc () ++
+ Termops.Internal.print_constr_env env evd t1 ++ cut () ++
+ Termops.Internal.print_constr_env env evd t2 ++ cut ())) in
let app_empty = Array.is_empty l1 && Array.is_empty l2 in
match EConstr.kind evd term1, EConstr.kind evd term2 with
| Evar (evk1,args1), (Rel _|Var _) when app_empty
@@ -1245,7 +1239,7 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
| Some evd -> Success evd
| None ->
let reason = ProblemBeyondCapabilities in
- UnifFailure (evd, CannotSolveConstraint (to_pb (pbty,env,t1,t2),reason)))
+ UnifFailure (evd, CannotSolveConstraint ((pbty,env,t1,t2),reason)))
| (Rel _|Var _), Evar (evk2,args2) when app_empty
&& List.for_all (fun a -> EConstr.eq_constr evd a term1 || isEvar evd a)
(remove_instance_local_defs evd evk2 args2) ->
@@ -1255,7 +1249,7 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
| Some evd -> Success evd
| None ->
let reason = ProblemBeyondCapabilities in
- UnifFailure (evd, CannotSolveConstraint (to_pb (pbty,env,t1,t2),reason)))
+ UnifFailure (evd, CannotSolveConstraint ((pbty,env,t1,t2),reason)))
| Evar (evk1,args1), Evar (evk2,args2) when Evar.equal evk1 evk2 ->
let f env evd pbty x y = is_fconv ~reds:ts pbty env evd x y in
Success (solve_refl ~can_drop:true f env evd
@@ -1295,10 +1289,10 @@ let error_cannot_unify env evd pb ?reason t1 t2 =
let check_problems_are_solved env evd =
match snd (extract_all_conv_pbs evd) with
- | (pbty,env,t1,t2) as pb::_ -> error_cannot_unify env evd pb (EConstr.of_constr t1) (EConstr.of_constr t2)
+ | (pbty,env,t1,t2) as pb::_ -> error_cannot_unify env evd pb t1 t2
| _ -> ()
-exception MaxUndefined of (Evar.t * evar_info * Constr.t list)
+exception MaxUndefined of (Evar.t * evar_info * EConstr.t list)
let max_undefined_with_candidates evd =
let fold evk evi () = match evi.evar_candidates with
@@ -1324,9 +1318,10 @@ let rec solve_unconstrained_evars_with_candidates ts evd =
let rec aux = function
| [] -> user_err Pp.(str "Unsolvable existential variables.")
| a::l ->
+ (* In case of variables, most recent ones come first *)
try
let conv_algo = evar_conv_x ts in
- let evd = check_evar_instance evd evk (EConstr.of_constr a) conv_algo in
+ let evd = check_evar_instance evd evk a conv_algo in
let evd = Evd.define evk a evd in
match reconsider_unif_constraints conv_algo evd with
| Success evd -> solve_unconstrained_evars_with_candidates ts evd
@@ -1334,9 +1329,9 @@ let rec solve_unconstrained_evars_with_candidates ts evd =
with
| IllTypedInstance _ -> aux l
| e when Pretype_errors.precatchable_exception e -> aux l in
- (* List.rev is there to favor most dependent solutions *)
- (* and favor progress when used with the refine tactics *)
- let evd = aux (List.rev l) in
+ (* Expected invariant: most dependent solutions come first *)
+ (* so as to favor progress when used with the refine tactics *)
+ let evd = aux l in
solve_unconstrained_evars_with_candidates ts evd
let solve_unconstrained_impossible_cases env evd =
@@ -1348,7 +1343,7 @@ let solve_unconstrained_impossible_cases env evd =
let ty = j_type j in
let conv_algo = evar_conv_x full_transparent_state in
let evd' = check_evar_instance evd' evk ty conv_algo in
- Evd.define evk (EConstr.Unsafe.to_constr ty) evd'
+ Evd.define evk ty evd'
| _ -> evd') evd evd
let solve_unif_constraints_with_heuristics env
@@ -1357,8 +1352,6 @@ let solve_unif_constraints_with_heuristics env
let rec aux evd pbs progress stuck =
match pbs with
| (pbty,env,t1,t2 as pb) :: pbs ->
- let t1 = EConstr.of_constr t1 in
- let t2 = EConstr.of_constr t2 in
(match apply_conversion_problem_heuristic ts env evd pbty t1 t2 with
| Success evd' ->
let (evd', rest) = extract_all_conv_pbs evd' in
@@ -1375,9 +1368,7 @@ let solve_unif_constraints_with_heuristics env
match stuck with
| [] -> (* We're finished *) evd
| (pbty,env,t1,t2 as pb) :: _ ->
- let t1 = EConstr.of_constr t1 in
- let t2 = EConstr.of_constr t2 in
- (* There remains stuck problems *)
+ (* There remains stuck problems *)
error_cannot_unify env evd pb t1 t2
in
let (evd,pbs) = extract_all_conv_pbs evd in
@@ -1404,6 +1395,16 @@ let the_conv_x_leq env ?(ts=default_transparent_state env) t1 t2 evd =
| Success evd' -> evd'
| UnifFailure (evd',e) -> raise (UnableToUnify (evd',e))
+let make_opt = function
+ | Success evd -> Some evd
+ | UnifFailure _ -> None
+
+let conv env ?(ts=default_transparent_state env) evd t1 t2 =
+ make_opt(evar_conv_x ts env evd CONV t1 t2)
+
+let cumul env ?(ts=default_transparent_state env) evd t1 t2 =
+ make_opt(evar_conv_x ts env evd CUMUL t1 t2)
+
let e_conv env ?(ts=default_transparent_state env) evdref t1 t2 =
match evar_conv_x ts env !evdref CONV t1 t2 with
| Success evd' -> evdref := evd'; true
diff --git a/pretyping/evarconv.mli b/pretyping/evarconv.mli
index 9270d6e3..cdf5dd0e 100644
--- a/pretyping/evarconv.mli
+++ b/pretyping/evarconv.mli
@@ -28,7 +28,13 @@ val the_conv_x_leq : env -> ?ts:transparent_state -> constr -> constr -> evar_ma
(** The same function resolving evars by side-effect and
catching the exception *)
val e_conv : env -> ?ts:transparent_state -> evar_map ref -> constr -> constr -> bool
+[@@ocaml.deprecated "Use [Evarconv.conv]"]
+
val e_cumul : env -> ?ts:transparent_state -> evar_map ref -> constr -> constr -> bool
+[@@ocaml.deprecated "Use [Evarconv.cumul]"]
+
+val conv : env -> ?ts:transparent_state -> evar_map -> constr -> constr -> evar_map option
+val cumul : env -> ?ts:transparent_state -> evar_map -> constr -> constr -> evar_map option
(** {6 Unification heuristics. } *)
@@ -63,7 +69,7 @@ val second_order_matching : transparent_state -> env -> evar_map ->
(** Declare function to enforce evars resolution by using typing constraints *)
-val set_solve_evars : (env -> evar_map ref -> constr -> constr) -> unit
+val set_solve_evars : (env -> evar_map -> constr -> evar_map * constr) -> unit
type unify_fun = transparent_state ->
env -> evar_map -> conv_pb -> constr -> constr -> Evarsolve.unification_result
diff --git a/pretyping/evardefine.ml b/pretyping/evardefine.ml
index 03f40ad9..571be746 100644
--- a/pretyping/evardefine.ml
+++ b/pretyping/evardefine.ml
@@ -19,6 +19,7 @@ open Vars
open Namegen
open Evd
open Evarutil
+open Evar_kinds
open Pretype_errors
module RelDecl = Context.Rel.Declaration
@@ -76,14 +77,16 @@ let define_pure_evar_as_product evd evk =
let evi = Evd.find_undefined evd evk in
let evenv = evar_env evi in
let id = next_ident_away idx (Environ.ids_of_named_context_val evi.evar_hyps) in
- let concl = Reductionops.whd_all evenv evd (EConstr.of_constr evi.evar_concl) in
+ let concl = Reductionops.whd_all evenv evd evi.evar_concl in
let s = destSort evd concl in
+ let evksrc = evar_source evk evd in
+ let src = subterm_source evk ~where:Domain evksrc in
let evd1,(dom,u1) =
- new_type_evar evenv evd univ_flexible_alg ~filter:(evar_filter evi)
+ new_type_evar evenv evd univ_flexible_alg ~src ~filter:(evar_filter evi)
in
let evd2,rng =
let newenv = push_named (LocalAssum (id, dom)) evenv in
- let src = evar_source evk evd1 in
+ let src = subterm_source evk ~where:Codomain evksrc in
let filter = Filter.extend 1 (evar_filter evi) in
if Sorts.is_prop (ESorts.kind evd1 s) then
(* Impredicative product, conclusion must fall in [Prop]. *)
@@ -98,7 +101,7 @@ let define_pure_evar_as_product evd evk =
evd3, rng
in
let prod = mkProd (Name id, dom, subst_var id rng) in
- let evd3 = Evd.define evk (EConstr.Unsafe.to_constr prod) evd2 in
+ let evd3 = Evd.define evk prod evd2 in
evd3,prod
(* Refine an applied evar to a product and returns its instantiation *)
@@ -125,7 +128,7 @@ let define_pure_evar_as_lambda env evd evk =
let open Context.Named.Declaration in
let evi = Evd.find_undefined evd evk in
let evenv = evar_env evi in
- let typ = Reductionops.whd_all evenv evd (EConstr.of_constr (evar_concl evi)) in
+ let typ = Reductionops.whd_all evenv evd (evar_concl evi) in
let evd1,(na,dom,rng) = match EConstr.kind evd typ with
| Prod (na,dom,rng) -> (evd,(na,dom,rng))
| Evar ev' -> let evd,typ = define_evar_as_product evd ev' in evd,destProd evd typ
@@ -135,10 +138,10 @@ let define_pure_evar_as_lambda env evd evk =
next_name_away_with_default_using_types "x" na avoid (Reductionops.whd_evar evd dom) in
let newenv = push_named (LocalAssum (id, dom)) evenv in
let filter = Filter.extend 1 (evar_filter evi) in
- let src = evar_source evk evd1 in
+ let src = subterm_source evk ~where:Body (evar_source evk evd1) in
let evd2,body = new_evar newenv evd1 ~src (subst1 (mkVar id) rng) ~filter in
let lam = mkLambda (Name id, dom, subst_var id body) in
- Evd.define evk (EConstr.Unsafe.to_constr lam) evd2, lam
+ Evd.define evk lam evd2, lam
let define_evar_as_lambda env evd (evk,args) =
let evd,lam = define_pure_evar_as_lambda env evd evk in
@@ -163,9 +166,9 @@ let define_evar_as_sort env evd (ev,args) =
let evd, u = new_univ_variable univ_rigid evd in
let evi = Evd.find_undefined evd ev in
let s = Type u in
- let concl = Reductionops.whd_all (evar_env evi) evd (EConstr.of_constr evi.evar_concl) in
+ let concl = Reductionops.whd_all (evar_env evi) evd evi.evar_concl in
let sort = destSort evd concl in
- let evd' = Evd.define ev (Constr.mkSort s) evd in
+ let evd' = Evd.define ev (mkSort s) evd in
Evd.set_leq_sort env evd' (Type (Univ.super u)) (ESorts.kind evd' sort), s
(* Propagation of constraints through application and abstraction:
@@ -198,4 +201,4 @@ let lift_tycon n = Option.map (lift n)
let pr_tycon env sigma = function
None -> str "None"
- | Some t -> Termops.print_constr_env env sigma t
+ | Some t -> Termops.Internal.print_constr_env env sigma t
diff --git a/pretyping/evarsolve.ml b/pretyping/evarsolve.ml
index d0721439..2dd37219 100644
--- a/pretyping/evarsolve.ml
+++ b/pretyping/evarsolve.ml
@@ -69,7 +69,7 @@ let refresh_universes ?(status=univ_rigid) ?(onlyalg=false) ?(refreshset=false)
if onlyalg && alg then
(evdref := Evd.make_flexible_variable !evdref ~algebraic:false l; t)
else t))
- | Prop Pos when refreshset && not direction ->
+ | Set when refreshset && not direction ->
(* Cannot make a universe "lower" than "Set",
only refreshing when we want higher universes. *)
refresh_sort status ~direction s
@@ -89,9 +89,9 @@ let refresh_universes ?(status=univ_rigid) ?(onlyalg=false) ?(refreshset=false)
Array.iter (refresh_term_evars onevars false) args
| Evar (ev, a) when onevars ->
let evi = Evd.find !evdref ev in
- let ty' = refresh ~onlyalg univ_flexible ~direction:true (EConstr.of_constr evi.evar_concl) in
+ let ty' = refresh ~onlyalg univ_flexible ~direction:true evi.evar_concl in
if !modified then
- evdref := Evd.add !evdref ev {evi with evar_concl = EConstr.Unsafe.to_constr ty'}
+ evdref := Evd.add !evdref ev {evi with evar_concl = ty'}
else ()
| _ -> EConstr.iter !evdref (refresh_term_evars onevars false) t
and refresh_polymorphic_positions args pos =
@@ -137,8 +137,6 @@ let test_success conv_algo env evd c c' rhs =
is_success (conv_algo env evd c c' rhs)
let add_conv_oriented_pb ?(tail=true) (pbty,env,t1,t2) evd =
- let t1 = EConstr.Unsafe.to_constr t1 in
- let t2 = EConstr.Unsafe.to_constr t2 in
match pbty with
| Some true -> add_conv_pb ~tail (Reduction.CUMUL,env,t1,t2) evd
| Some false -> add_conv_pb ~tail (Reduction.CUMUL,env,t2,t1) evd
@@ -197,7 +195,7 @@ let restrict_evar_key evd evk filter candidates =
| None -> evar_filter evi
| Some filter -> filter in
let candidates = match candidates with
- | NoUpdate -> Option.map (fun l -> List.map EConstr.of_constr l) evi.evar_candidates
+ | NoUpdate -> evi.evar_candidates
| UpdateWith c -> Some c in
restrict_evar evd evk filter candidates
end
@@ -527,7 +525,7 @@ let is_unification_pattern_meta env evd nb m l t =
match Option.List.map map l with
| Some l ->
begin match find_unification_pattern_args env evd l t with
- | Some _ as x when not (dependent evd (mkMeta m) t) -> x
+ | Some _ as x when not (occur_metavariable evd m t) -> x
| _ -> None
end
| None ->
@@ -600,13 +598,13 @@ let solve_pattern_eqn env sigma l c =
let make_projectable_subst aliases sigma evi args =
let sign = evar_filtered_context evi in
- let sign = List.map (fun d -> map_named_decl EConstr.of_constr d) sign in
let evar_aliases = compute_var_aliases sign sigma in
- let (_,full_subst,cstr_subst) =
- List.fold_right
- (fun decl (args,all,cstrs) ->
+ let (_,full_subst,cstr_subst,_) =
+ List.fold_right_i
+ (fun i decl (args,all,cstrs,revmap) ->
match decl,args with
| LocalAssum (id,c), a::rest ->
+ let revmap = Id.Map.add id i revmap in
let cstrs =
let a',args = decompose_app_vect sigma a in
match EConstr.kind sigma a' with
@@ -614,22 +612,26 @@ let make_projectable_subst aliases sigma evi args =
let l = try Constrmap.find (fst cstr) cstrs with Not_found -> [] in
Constrmap.add (fst cstr) ((args,id)::l) cstrs
| _ -> cstrs in
- (rest,Id.Map.add id [a,normalize_alias_opt sigma aliases a,id] all,cstrs)
+ let all = Int.Map.add i [a,normalize_alias_opt sigma aliases a,id] all in
+ (rest,all,cstrs,revmap)
| LocalDef (id,c,_), a::rest ->
+ let revmap = Id.Map.add id i revmap in
(match EConstr.kind sigma c with
| Var id' ->
let idc = normalize_alias_var sigma evar_aliases id' in
- let sub = try Id.Map.find idc all with Not_found -> [] in
+ let ic, sub =
+ try let ic = Id.Map.find idc revmap in ic, Int.Map.find ic all
+ with Not_found -> i, [] (* e.g. [idc] is a filtered variable: treat [id] as an assumption *) in
if List.exists (fun (c,_,_) -> EConstr.eq_constr sigma a c) sub then
- (rest,all,cstrs)
+ (rest,all,cstrs,revmap)
else
- (rest,
- Id.Map.add idc ((a,normalize_alias_opt sigma aliases a,id)::sub) all,
- cstrs)
+ let all = Int.Map.add ic ((a,normalize_alias_opt sigma aliases a,id)::sub) all in
+ (rest,all,cstrs,revmap)
| _ ->
- (rest,Id.Map.add id [a,normalize_alias_opt sigma aliases a,id] all,cstrs))
- | _ -> anomaly (Pp.str "Instance does not match its signature."))
- sign (Array.rev_to_list args,Id.Map.empty,Constrmap.empty) in
+ let all = Int.Map.add i [a,normalize_alias_opt sigma aliases a,id] all in
+ (rest,all,cstrs,revmap))
+ | _ -> anomaly (Pp.str "Instance does not match its signature.")) 0
+ sign (Array.rev_to_list args,Int.Map.empty,Constrmap.empty,Id.Map.empty) in
(full_subst,cstr_subst)
(*------------------------------------*
@@ -796,11 +798,11 @@ let rec assoc_up_to_alias sigma aliases y yc = function
let rec find_projectable_vars with_evars aliases sigma y subst =
let yc = normalize_alias sigma aliases y in
- let is_projectable idc idcl subst' =
+ let is_projectable idc idcl (subst1,subst2 as subst') =
(* First test if some [id] aliased to [idc] is bound to [y] in [subst] *)
try
let id = assoc_up_to_alias sigma aliases y yc idcl in
- (id,ProjectVar)::subst'
+ (id,ProjectVar)::subst1,subst2
with Not_found ->
(* Then test if [idc] is (indirectly) bound in [subst] to some evar *)
(* projectable on [y] *)
@@ -815,14 +817,18 @@ let rec find_projectable_vars with_evars aliases sigma y subst =
let subst,_ = make_projectable_subst aliases sigma evi argsv in
let l = find_projectable_vars with_evars aliases sigma y subst in
match l with
- | [id',p] -> (id,ProjectEvar (t,evi,id',p))::subst'
+ | [id',p] -> (subst1,(id,ProjectEvar (t,evi,id',p))::subst2)
| _ -> subst'
end
| [] -> subst'
| _ -> anomaly (Pp.str "More than one non var in aliases class of evar instance.")
else
subst' in
- Id.Map.fold is_projectable subst []
+ let subst1,subst2 = Int.Map.fold is_projectable subst ([],[]) in
+ (* We return the substitution with ProjectVar first (from most
+ recent to oldest var), followed by ProjectEvar (from most recent
+ to oldest var too) *)
+ subst1 @ subst2
(* [filter_solution] checks if one and only one possible projection exists
* among a set of solutions to a projection problem *)
@@ -845,25 +851,6 @@ let rec find_solution_type evarenv = function
| (id,ProjectEvar _)::l -> find_solution_type evarenv l
| [] -> assert false
-let is_preferred_projection_over sign (id,p) (id',p') =
- (* We give priority to projection of variables over instantiation of
- an evar considering that the latter is a stronger decision which
- may even procude an incorrect (ill-typed) solution *)
- match p, p' with
- | ProjectEvar _, ProjectVar -> false
- | ProjectVar, ProjectEvar _ -> true
- | _, _ ->
- List.index Id.equal id sign < List.index Id.equal id' sign
-
-let choose_projection evi sols =
- let sign = List.map get_id (evar_filtered_context evi) in
- match sols with
- | y::l ->
- List.fold_right (fun (id,p as x) (id',_ as y) ->
- if is_preferred_projection_over sign x y then x else y)
- l y
- | _ -> assert false
-
(* In case the solution to a projection problem requires the instantiation of
* subsidiary evars, [do_projection_effects] performs them; it
* also try to instantiate the type of those subsidiary evars if their
@@ -877,7 +864,7 @@ let choose_projection evi sols =
let rec do_projection_effects define_fun env ty evd = function
| ProjectVar -> evd
| ProjectEvar ((evk,argsv),evi,id,p) ->
- let evd = Evd.define evk (Constr.mkVar id) evd in
+ let evd = Evd.define evk (mkVar id) evd in
(* TODO: simplify constraints involving evk *)
let evd = do_projection_effects define_fun env ty evd p in
let ty = whd_all env evd (Lazy.force ty) in
@@ -887,7 +874,7 @@ let rec do_projection_effects define_fun env ty evd = function
one (however, regarding coercions, because t is obtained by
unif, we know that no coercion can be inserted) *)
let subst = make_pure_subst evi argsv in
- let ty' = replace_vars subst (EConstr.of_constr evi.evar_concl) in
+ let ty' = replace_vars subst evi.evar_concl in
if isEvar evd ty' then define_fun env evd (Some false) (destEvar evd ty') ty else evd
else
evd
@@ -1004,7 +991,7 @@ let filter_effective_candidates evd evi filter candidates =
let filter_candidates evd evk filter candidates_update =
let evi = Evd.find_undefined evd evk in
let candidates = match candidates_update with
- | NoUpdate -> Option.map (fun l -> List.map EConstr.of_constr l) evi.evar_candidates
+ | NoUpdate -> evi.evar_candidates
| UpdateWith c -> Some c
in
match candidates with
@@ -1023,13 +1010,12 @@ let closure_of_filter evd evk = function
| None -> None
| Some filter ->
let evi = Evd.find_undefined evd evk in
- let vars = collect_vars evd (EConstr.of_constr (evar_concl evi)) in
+ let vars = collect_vars evd (evar_concl evi) in
let test b decl = b || Id.Set.mem (get_id decl) vars ||
match decl with
| LocalAssum _ ->
false
| LocalDef (_,c,_) ->
- let c = EConstr.of_constr c in
not (isRel evd c || isVar evd c)
in
let newfilter = Filter.map_along test filter (evar_context evi) in
@@ -1062,7 +1048,7 @@ let do_restrict_hyps evd (evk,args as ev) filter candidates =
match candidates,filter with
| UpdateWith [], _ -> user_err Pp.(str "Not solvable.")
| UpdateWith [nc],_ ->
- let evd = Evd.define evk (EConstr.Unsafe.to_constr nc) evd in
+ let evd = Evd.define evk nc evd in
raise (EvarSolvedWhileRestricting (evd,mkEvar ev))
| NoUpdate, None -> evd,ev
| _ -> restrict_applied_evar evd ev filter candidates
@@ -1072,8 +1058,14 @@ let do_restrict_hyps evd (evk,args as ev) filter candidates =
let postpone_non_unique_projection env evd pbty (evk,argsv as ev) sols rhs =
let rhs = expand_vars_in_term env evd rhs in
- let filter =
- restrict_upon_filter evd evk
+ let filter a = match EConstr.kind evd a with
+ | Rel n -> not (noccurn evd n rhs)
+ | Var id ->
+ local_occur_var evd id rhs
+ || List.exists (fun (id', _) -> Id.equal id id') sols
+ | _ -> true
+ in
+ let filter = restrict_upon_filter evd evk filter argsv in
(* Keep only variables that occur in rhs *)
(* This is not safe: is the variable is a local def, its body *)
(* may contain references to variables that are removed, leading to *)
@@ -1081,9 +1073,6 @@ let postpone_non_unique_projection env evd pbty (evk,argsv as ev) sols rhs =
(* that says that the body is hidden. Note that expand_vars_in_term *)
(* expands only rels and vars aliases, not rels or vars bound to an *)
(* arbitrary complex term *)
- (fun a -> not (isRel evd a || isVar evd a)
- || dependent evd a rhs || List.exists (fun (id,_) -> isVarId evd id a) sols)
- argsv in
let filter = closure_of_filter evd evk filter in
let candidates = extract_candidates sols in
match candidates with
@@ -1113,9 +1102,6 @@ let postpone_non_unique_projection env evd pbty (evk,argsv as ev) sols rhs =
* Note: argument f is the function used to instantiate evars.
*)
-let instantiate_evar_array evi c args =
- EConstr.of_constr (instantiate_evar_array evi (EConstr.Unsafe.to_constr c) (Array.map EConstr.Unsafe.to_constr args))
-
let filter_compatible_candidates conv_algo env evd evi args rhs c =
let c' = instantiate_evar_array evi c args in
match conv_algo env evd Reduction.CONV rhs c' with
@@ -1135,8 +1121,6 @@ let restrict_candidates conv_algo env evd filter1 (evk1,argsv1) (evk2,argsv2) =
| _, None -> filter_candidates evd evk1 filter1 NoUpdate
| None, Some _ -> raise DoesNotPreserveCandidateRestriction
| Some l1, Some l2 ->
- let l1 = List.map EConstr.of_constr l1 in
- let l2 = List.map EConstr.of_constr l2 in
let l1 = filter_effective_candidates evd evi1 filter1 l1 in
let l1' = List.filter (fun c1 ->
let c1' = instantiate_evar_array evi1 c1 argsv1 in
@@ -1242,9 +1226,9 @@ let check_evar_instance evd evk1 body conv_algo =
try Retyping.get_type_of ~lax:true evenv evd body
with Retyping.RetypeError _ -> user_err Pp.(str "Ill-typed evar instance")
in
- match conv_algo evenv evd Reduction.CUMUL ty (EConstr.of_constr evi.evar_concl) with
+ match conv_algo evenv evd Reduction.CUMUL ty evi.evar_concl with
| Success evd -> evd
- | UnifFailure _ -> raise (IllTypedInstance (evenv,ty,EConstr.of_constr evi.evar_concl))
+ | UnifFailure _ -> raise (IllTypedInstance (evenv,ty, evi.evar_concl))
let update_evar_source ev1 ev2 evd =
let loc, evs2 = evar_source ev2 evd in
@@ -1257,7 +1241,7 @@ let update_evar_source ev1 ev2 evd =
let solve_evar_evar_l2r force f g env evd aliases pbty ev1 (evk2,_ as ev2) =
try
let evd,body = project_evar_on_evar force g env evd aliases 0 pbty ev1 ev2 in
- let evd' = Evd.define evk2 (EConstr.Unsafe.to_constr body) evd in
+ let evd' = Evd.define evk2 body evd in
let evd' = update_evar_source (fst (destEvar evd body)) evk2 evd' in
check_evar_instance evd' evk2 body g
with EvarSolvedOnTheFly (evd,c) ->
@@ -1292,17 +1276,19 @@ let solve_evar_evar_aux force f g env evd pbty (evk1,args1 as ev1) (evk2,args2 a
let solve_evar_evar ?(force=false) f g env evd pbty (evk1,args1 as ev1) (evk2,args2 as ev2) =
let pbty = if force then None else pbty in
let evi = Evd.find evd evk1 in
- let downcast evk t evd = downcast evk (EConstr.Unsafe.to_constr t) evd in
+ let downcast evk t evd = downcast evk t evd in
let evd =
try
(* ?X : Π Δ. Type i = ?Y : Π Δ'. Type j.
The body of ?X and ?Y just has to be of type Π Δ. Type k for some k <= i, j. *)
let evienv = Evd.evar_env evi in
- let ctx1, i = Reduction.dest_arity evienv evi.evar_concl in
+ let concl1 = EConstr.Unsafe.to_constr evi.evar_concl in
+ let ctx1, i = Reduction.dest_arity evienv concl1 in
let ctx1 = List.map (fun c -> map_rel_decl EConstr.of_constr c) ctx1 in
let evi2 = Evd.find evd evk2 in
let evi2env = Evd.evar_env evi2 in
- let ctx2, j = Reduction.dest_arity evi2env evi2.evar_concl in
+ let concl2 = EConstr.Unsafe.to_constr evi2.evar_concl in
+ let ctx2, j = Reduction.dest_arity evi2env concl2 in
let ctx2 = List.map (fun c -> map_rel_decl EConstr.of_constr c) ctx2 in
let ui, uj = univ_of_sort i, univ_of_sort j in
if i == j || Evd.check_eq evd ui uj
@@ -1375,14 +1361,14 @@ let solve_candidates conv_algo env evd (evk,argsv) rhs =
| Some l ->
let l' =
List.map_filter
- (fun c -> filter_compatible_candidates conv_algo env evd evi argsv rhs (EConstr.of_constr c)) l in
+ (fun c -> filter_compatible_candidates conv_algo env evd evi argsv rhs c) l in
match l' with
| [] -> raise IncompatibleCandidates
| [c,evd] ->
(* solve_candidates might have been called recursively in the mean *)
(* time and the evar been solved by the filtering process *)
if Evd.is_undefined evd evk then
- let evd' = Evd.define evk (EConstr.Unsafe.to_constr c) evd in
+ let evd' = Evd.define evk c evd in
check_evar_instance evd' evk c conv_algo
else evd
| l when List.length l < List.length l' ->
@@ -1401,8 +1387,8 @@ let occur_evar_upto_types sigma n c =
Array.iter occur_rec args
else (
seen := Evar.Set.add sp !seen;
- Option.iter occur_rec (existential_opt_value sigma e);
- occur_rec (Evd.existential_type sigma e))
+ Option.iter occur_rec (existential_opt_value0 sigma e);
+ occur_rec (Evd.existential_type0 sigma e))
| _ -> Constr.iter occur_rec c
in
try occur_rec c; false with Occur -> true
@@ -1451,12 +1437,8 @@ let rec invert_definition conv_algo choose env evd pbty (evk,argsv as ev) rhs =
let c, p = match sols with
| [] -> raise Not_found
| [id,p] -> (mkVar id, p)
- | _ ->
- if choose then
- let (id,p) = choose_projection evi sols in
- (mkVar id, p)
- else
- raise (NotUniqueInType sols)
+ | (id,p)::_ ->
+ if choose then (mkVar id, p) else raise (NotUniqueInType sols)
in
let ty = lazy (Retyping.get_type_of env !evdref (of_alias t)) in
let evd = do_projection_effects (evar_define conv_algo ~choose) env ty !evdref p in
@@ -1529,7 +1511,7 @@ let rec invert_definition conv_algo choose env evd pbty (evk,argsv as ev) rhs =
(* Try to project (a restriction of) the left evar ... *)
try
let evd,body = project_evar_on_evar false conv_algo env' evd aliases 0 None ev'' ev' in
- let evd = Evd.define evk' (EConstr.Unsafe.to_constr body) evd in
+ let evd = Evd.define evk' body evd in
check_evar_instance evd evk' body conv_algo
with
| EvarSolvedOnTheFly _ -> assert false (* ev has no candidates *)
@@ -1560,7 +1542,8 @@ let rec invert_definition conv_algo choose env evd pbty (evk,argsv as ev) rhs =
let t =
map_constr_with_full_binders !evdref (fun d (env,k) -> push_rel d env, k+1)
imitate envk t in
- t::l
+ (* Less dependent solutions come last *)
+ l@[t]
with e when CErrors.noncritical e -> l in
(match candidates with
| [x] -> x
@@ -1592,14 +1575,14 @@ let rec invert_definition conv_algo choose env evd pbty (evk,argsv as ev) rhs =
Id.Set.subset (collect_vars evd rhs) !names
in
let body =
- if fast rhs then EConstr.of_constr (EConstr.to_constr evd rhs) (** FIXME? *)
+ if fast rhs then nf_evar evd rhs (** FIXME? *)
else
let t' = imitate (env,0) rhs in
if !progress then
(recheck_applications conv_algo (evar_env evi) evdref t'; t')
else t'
in (!evdref,body)
-
+
(* [define] tries to solve the problem "?ev[args] = rhs" when "?ev" is
* an (uninstantiated) evar such that "hyps |- ?ev : typ". Otherwise said,
* [define] tries to find an instance lhs such that
@@ -1644,7 +1627,7 @@ and evar_define conv_algo ?(choose=false) env evd pbty (evk,argsv as ev) rhs =
print_constr body);
raise e in*)
let evd' = check_evar_instance evd' evk body conv_algo in
- Evd.define evk (EConstr.Unsafe.to_constr body) evd'
+ Evd.define evk body evd'
with
| NotEnoughInformationToProgress sols ->
postpone_non_unique_projection env evd pbty ev sols rhs
@@ -1691,8 +1674,6 @@ and evar_define conv_algo ?(choose=false) env evd pbty (evk,argsv as ev) rhs =
*)
let status_changed evd lev (pbty,_,t1,t2) =
- let t1 = EConstr.of_constr t1 in
- let t2 = EConstr.of_constr t2 in
(try Evar.Set.mem (head_evar evd t1) lev with NoHeadEvar -> false) ||
(try Evar.Set.mem (head_evar evd t2) lev with NoHeadEvar -> false)
@@ -1702,7 +1683,7 @@ let reconsider_unif_constraints conv_algo evd =
(fun p (pbty,env,t1,t2 as x) ->
match p with
| Success evd ->
- (match conv_algo env evd pbty (EConstr.of_constr t1) (EConstr.of_constr t2) with
+ (match conv_algo env evd pbty t1 t2 with
| Success _ as x -> x
| UnifFailure (i,e) -> UnifFailure (i,CannotSolveConstraint (x,e)))
| UnifFailure _ as x -> x)
diff --git a/pretyping/geninterp.mli b/pretyping/geninterp.mli
index fa522e9c..606a6ebe 100644
--- a/pretyping/geninterp.mli
+++ b/pretyping/geninterp.mli
@@ -42,8 +42,8 @@ sig
end
-module ValTMap (M : Dyn.TParam) :
- Dyn.MapS with type 'a obj = 'a M.t with type 'a key = 'a Val.typ
+module ValTMap (Value : Dyn.ValueS) :
+ Dyn.MapS with type 'a key = 'a Val.typ and type 'a value = 'a Value.t
(** Dynamic types for toplevel values. While the generic types permit to relate
objects at various levels of interpretation, toplevel values are wearing
diff --git a/pretyping/glob_ops.ml b/pretyping/glob_ops.ml
index eda45f3d..ebb30127 100644
--- a/pretyping/glob_ops.ml
+++ b/pretyping/glob_ops.ml
@@ -13,7 +13,6 @@ open CAst
open Names
open Nameops
open Globnames
-open Misctypes
open Glob_term
open Evar_kinds
open Ltac_pretype
@@ -47,12 +46,20 @@ let map_glob_decl_left_to_right f (na,k,obd,ty) =
let comp2 = f ty in
(na,k,comp1,comp2)
+
+let glob_sort_eq g1 g2 = let open Glob_term in match g1, g2 with
+| GProp, GProp -> true
+| GSet, GSet -> true
+| GType l1, GType l2 ->
+ List.equal (Option.equal (fun (x,m) (y,n) -> Libnames.qualid_eq x y && Int.equal m n)) l1 l2
+| _ -> false
+
let binding_kind_eq bk1 bk2 = match bk1, bk2 with
| Decl_kinds.Explicit, Decl_kinds.Explicit -> true
| Decl_kinds.Implicit, Decl_kinds.Implicit -> true
| (Decl_kinds.Explicit | Decl_kinds.Implicit), _ -> false
-let case_style_eq s1 s2 = match s1, s2 with
+let case_style_eq s1 s2 = let open Constr in match s1, s2 with
| LetStyle, LetStyle -> true
| IfStyle, IfStyle -> true
| LetPatternStyle, LetPatternStyle -> true
@@ -105,7 +112,7 @@ let fix_kind_eq f k1 k2 = match k1, k2 with
let eq (i1, o1) (i2, o2) =
Option.equal Int.equal i1 i2 && fix_recursion_order_eq f o1 o2
in
- Int.equal i1 i2 && Array.equal eq a1 a1
+ Int.equal i1 i2 && Array.equal eq a1 a2
| GCoFix i1, GCoFix i2 -> Int.equal i1 i2
| (GFix _ | GCoFix _), _ -> false
@@ -113,7 +120,7 @@ let instance_eq f (x1,c1) (x2,c2) =
Id.equal x1 x2 && f c1 c2
let mk_glob_constr_eq f c1 c2 = match DAst.get c1, DAst.get c2 with
- | GRef (gr1, _), GRef (gr2, _) -> eq_gr gr1 gr2
+ | GRef (gr1, _), GRef (gr2, _) -> GlobRef.equal gr1 gr2
| GVar id1, GVar id2 -> Id.equal id1 id2
| GEvar (id1, arg1), GEvar (id2, arg2) ->
Id.equal id1 id2 && List.equal (instance_eq f) arg1 arg2
@@ -136,21 +143,36 @@ let mk_glob_constr_eq f c1 c2 = match DAst.get c1, DAst.get c2 with
| GIf (m1, (pat1, p1), c1, t1), GIf (m2, (pat2, p2), c2, t2) ->
f m1 m2 && Name.equal pat1 pat2 &&
Option.equal f p1 p2 && f c1 c2 && f t1 t2
- | GRec (kn1, id1, decl1, c1, t1), GRec (kn2, id2, decl2, c2, t2) ->
+ | GRec (kn1, id1, decl1, t1, c1), GRec (kn2, id2, decl2, t2, c2) ->
fix_kind_eq f kn1 kn2 && Array.equal Id.equal id1 id2 &&
Array.equal (fun l1 l2 -> List.equal (glob_decl_eq f) l1 l2) decl1 decl2 &&
Array.equal f c1 c2 && Array.equal f t1 t2
- | GSort s1, GSort s2 -> Miscops.glob_sort_eq s1 s2
+ | GSort s1, GSort s2 -> glob_sort_eq s1 s2
| GHole (kn1, nam1, gn1), GHole (kn2, nam2, gn2) ->
Option.equal (==) gn1 gn2 (** Only thing sensible *) &&
- Miscops.intro_pattern_naming_eq nam1 nam2
+ Namegen.intro_pattern_naming_eq nam1 nam2
| GCast (c1, t1), GCast (c2, t2) ->
f c1 c2 && cast_type_eq f t1 t2
| (GRef _ | GVar _ | GEvar _ | GPatVar _ | GApp _ | GLambda _ | GProd _ | GLetIn _ |
- GCases _ | GLetTuple _ | GIf _ | GRec _ | GSort _ | GHole _ | GCast _), _ -> false
+ GCases _ | GLetTuple _ | GIf _ | GRec _ | GSort _ | GHole _ | GCast _ ), _ -> false
let rec glob_constr_eq c = mk_glob_constr_eq glob_constr_eq c
+(** Mapping [cast_type] *)
+
+let map_cast_type f = function
+ | CastConv a -> CastConv (f a)
+ | CastVM a -> CastVM (f a)
+ | CastCoerce -> CastCoerce
+ | CastNative a -> CastNative (f a)
+
+let smartmap_cast_type f c =
+ match c with
+ | CastConv a -> let a' = f a in if a' == a then c else CastConv a'
+ | CastVM a -> let a' = f a in if a' == a then c else CastVM a'
+ | CastCoerce -> CastCoerce
+ | CastNative a -> let a' = f a in if a' == a then c else CastNative a'
+
let map_glob_constr_left_to_right f = DAst.map (function
| GApp (g,args) ->
let comp1 = f g in
@@ -191,7 +213,7 @@ let map_glob_constr_left_to_right f = DAst.map (function
GRec (fk,idl,comp1,comp2,comp3)
| GCast (c,k) ->
let comp1 = f c in
- let comp2 = Miscops.map_cast_type f k in
+ let comp2 = map_cast_type f k in
GCast (comp1,comp2)
| (GVar _ | GSort _ | GHole _ | GRef _ | GEvar _ | GPatVar _) as x -> x
)
@@ -325,19 +347,19 @@ let bound_glob_vars =
(** Mapping of names in binders *)
-(* spiwack: I used a smartmap-style kind of mapping here, because the
+(* spiwack: I used a smart-style kind of mapping here, because the
operation will be the identity almost all of the time (with any
term outside of Ltac to begin with). But to be honest, there would
probably be no significant penalty in doing reallocation as
pattern-matching expressions are usually rather small. *)
let map_inpattern_binders f ({loc;v=(id,nal)} as x) =
- let r = CList.smartmap f nal in
+ let r = CList.Smart.map f nal in
if r == nal then x
else CAst.make ?loc (id,r)
let map_tomatch_binders f ((c,(na,inp)) as x) : tomatch_tuple =
- let r = Option.smartmap (fun p -> map_inpattern_binders f p) inp in
+ let r = Option.Smart.map (fun p -> map_inpattern_binders f p) inp in
if r == inp then x
else c,(f na, r)
@@ -349,7 +371,7 @@ let rec map_case_pattern_binders f = DAst.map (function
| PatCstr (c,ps,na) as x ->
let rna = f na in
let rps =
- CList.smartmap (fun p -> map_case_pattern_binders f p) ps
+ CList.Smart.map (fun p -> map_case_pattern_binders f p) ps
in
if rna == na && rps == ps then x
else PatCstr(c,rps,rna)
@@ -360,13 +382,13 @@ let map_cases_branch_binders f ({CAst.loc;v=(il,cll,rhs)} as x) : cases_clause =
It is intended to be a superset of the free variable of the
right-hand side, if I understand correctly. But I'm not sure when
or how they are used. *)
- let r = List.smartmap (fun cl -> map_case_pattern_binders f cl) cll in
+ let r = List.Smart.map (fun cl -> map_case_pattern_binders f cl) cll in
if r == cll then x
else CAst.make ?loc (il,r,rhs)
let map_pattern_binders f tomatch branches =
- CList.smartmap (fun tm -> map_tomatch_binders f tm) tomatch,
- CList.smartmap (fun br -> map_cases_branch_binders f br) branches
+ CList.Smart.map (fun tm -> map_tomatch_binders f tm) tomatch,
+ CList.Smart.map (fun br -> map_cases_branch_binders f br) branches
(** /mapping of names in binders *)
@@ -422,7 +444,7 @@ let rec rename_glob_vars l c = force @@ DAst.map_with_loc (fun ?loc -> function
else r
| GProd (na,bk,t,c) ->
let na',l' = update_subst na l in
- GProd (na,bk,rename_glob_vars l t,rename_glob_vars l' c)
+ GProd (na',bk,rename_glob_vars l t,rename_glob_vars l' c)
| GLambda (na,bk,t,c) ->
let na',l' = update_subst na l in
GLambda (na',bk,rename_glob_vars l t,rename_glob_vars l' c)
@@ -532,7 +554,9 @@ let rec glob_constr_of_cases_pattern_aux isclosed x = DAst.map_with_loc (fun ?lo
| PatVar (Name id) when not isclosed ->
GVar id
| PatVar Anonymous when not isclosed ->
- GHole (Evar_kinds.QuestionMark (Define false,Anonymous),Misctypes.IntroAnonymous,None)
+ GHole (Evar_kinds.QuestionMark {
+ Evar_kinds.default_question_mark with Evar_kinds.qm_obligation=Define false;
+ },Namegen.IntroAnonymous,None)
| _ -> raise Not_found
) x
diff --git a/pretyping/glob_ops.mli b/pretyping/glob_ops.mli
index 124440f5..c967f4e8 100644
--- a/pretyping/glob_ops.mli
+++ b/pretyping/glob_ops.mli
@@ -13,6 +13,8 @@ open Glob_term
(** Equalities *)
+val glob_sort_eq : Glob_term.glob_sort -> Glob_term.glob_sort -> bool
+
val cases_pattern_eq : 'a cases_pattern_g -> 'a cases_pattern_g -> bool
val alias_of_pat : 'a cases_pattern_g -> Name.t
@@ -20,10 +22,15 @@ val alias_of_pat : 'a cases_pattern_g -> Name.t
val set_pat_alias : Id.t -> 'a cases_pattern_g -> 'a cases_pattern_g
val cast_type_eq : ('a -> 'a -> bool) ->
- 'a Misctypes.cast_type -> 'a Misctypes.cast_type -> bool
+ 'a cast_type -> 'a cast_type -> bool
val glob_constr_eq : 'a glob_constr_g -> 'a glob_constr_g -> bool
+(** Mapping [cast_type] *)
+
+val map_cast_type : ('a -> 'b) -> 'a cast_type -> 'b cast_type
+val smartmap_cast_type : ('a -> 'a) -> 'a cast_type -> 'a cast_type
+
(** Operations on [glob_constr] *)
val cases_pattern_loc : 'a cases_pattern_g -> Loc.t option
diff --git a/intf/glob_term.ml b/pretyping/glob_term.ml
index 655dd20c..c6fdb0ec 100644
--- a/intf/glob_term.ml
+++ b/pretyping/glob_term.ml
@@ -17,12 +17,37 @@
arguments and pattern-matching compilation are not. *)
open Names
-open Globnames
open Decl_kinds
-open Misctypes
type existential_name = Id.t
+(** Sorts *)
+
+type 'a glob_sort_gen =
+ | GProp (** representation of [Prop] literal *)
+ | GSet (** representation of [Set] literal *)
+ | GType of 'a (** representation of [Type] literal *)
+
+type 'a universe_kind =
+ | UAnonymous
+ | UUnknown
+ | UNamed of 'a
+
+type level_info = Libnames.qualid universe_kind
+type glob_level = level_info glob_sort_gen
+type glob_constraint = glob_level * Univ.constraint_type * glob_level
+
+type sort_info = (Libnames.qualid * int) option list
+type glob_sort = sort_info glob_sort_gen
+
+(** Casts *)
+
+type 'a cast_type =
+ | CastConv of 'a
+ | CastVM of 'a
+ | CastCoerce (** Cast to a base type (eg, an underlying inductive type) *)
+ | CastNative of 'a
+
(** The kind of patterns that occurs in "match ... with ... end"
locs here refers to the ident's location, not whole pat *)
@@ -36,7 +61,7 @@ type cases_pattern = [ `any ] cases_pattern_g
(** Representation of an internalized (or in other words globalized) term. *)
type 'a glob_constr_r =
- | GRef of global_reference * glob_level list option
+ | GRef of GlobRef.t * glob_level list option
(** An identifier that represents a reference to an object defined
either in the (global) environment or in the (local) context. *)
| GVar of Id.t
@@ -55,7 +80,7 @@ type 'a glob_constr_r =
| GRec of 'a fix_kind_g * Id.t array * 'a glob_decl_g list array *
'a glob_constr_g array * 'a glob_constr_g array
| GSort of glob_sort
- | GHole of Evar_kinds.t * intro_pattern_naming_expr * Genarg.glob_generic_argument option
+ | GHole of Evar_kinds.t * Namegen.intro_pattern_naming_expr * Genarg.glob_generic_argument option
| GCast of 'a glob_constr_g * 'a glob_constr_g cast_type
and 'a glob_constr_g = ('a glob_constr_r, 'a) DAst.t
diff --git a/library/heads.ml b/pretyping/heads.ml
index 198672a0..7d9debce 100644
--- a/library/heads.ml
+++ b/pretyping/heads.ml
@@ -128,8 +128,8 @@ let compute_head = function
let env = Global.env() in
let cb = Environ.lookup_constant cst env in
let is_Def = function Declarations.Def _ -> true | _ -> false in
- let body =
- if cb.Declarations.const_proj = None && is_Def cb.Declarations.const_body
+ let body =
+ if not (Recordops.is_primitive_projection cst) && is_Def cb.Declarations.const_body
then Global.body_of_constant cst else None
in
(match body with
diff --git a/library/heads.mli b/pretyping/heads.mli
index 42124299..42124299 100644
--- a/library/heads.mli
+++ b/pretyping/heads.mli
diff --git a/pretyping/indrec.ml b/pretyping/indrec.ml
index 3143f8a5..dc900ab8 100644
--- a/pretyping/indrec.ml
+++ b/pretyping/indrec.ml
@@ -42,7 +42,7 @@ type recursion_scheme_error =
exception RecursionSchemeError of recursion_scheme_error
-let named_hd env t na = named_hd env Evd.empty (EConstr.of_constr t) na
+let named_hd env t na = named_hd env (Evd.from_env env) (EConstr.of_constr t) na
let name_assumption env = function
| LocalAssum (na,t) -> LocalAssum (named_hd env t na, t)
| LocalDef (na,c,t) -> LocalDef (named_hd env c na, c, t)
@@ -79,14 +79,14 @@ let mis_make_case_com dep env sigma (ind, u as pind) (mib,mip as specif) kind =
let lnamespar = Vars.subst_instance_context u mib.mind_params_ctxt in
let indf = make_ind_family(pind, Context.Rel.to_extended_list mkRel 0 lnamespar) in
let constrs = get_constructors env indf in
- let projs = get_projections env indf in
+ let projs = get_projections env ind in
let () = if Option.is_empty projs then check_privacy_block mib in
let () =
if not (Sorts.List.mem kind (elim_sorts specif)) then
raise
(RecursionSchemeError
- (NotAllowedCaseAnalysis (false, fst (Universes.fresh_sort_in_family env kind), pind)))
+ (NotAllowedCaseAnalysis (false, fst (UnivGen.fresh_sort_in_family kind), pind)))
in
let ndepar = mip.mind_nrealdecls + 1 in
@@ -136,7 +136,7 @@ let mis_make_case_com dep env sigma (ind, u as pind) (mib,mip as specif) kind =
mkLambda_string "f" t
(add_branch (push_rel (LocalAssum (Anonymous, t)) env) (k+1))
in
- let (sigma, s) = Evd.fresh_sort_in_family ~rigid:Evd.univ_flexible_alg env sigma kind in
+ let (sigma, s) = Evd.fresh_sort_in_family ~rigid:Evd.univ_flexible_alg sigma kind in
let typP = make_arity env' sigma dep indf s in
let typP = EConstr.Unsafe.to_constr typP in
let c =
@@ -455,7 +455,7 @@ let mis_make_indrec env sigma ?(force_mutual=false) listdepkind mib u =
| ((indi,u),_,_,dep,kinds)::rest ->
let indf = make_ind_family ((indi,u), Context.Rel.to_extended_list mkRel i lnamesparrec) in
let s =
- Evarutil.evd_comb1 (Evd.fresh_sort_in_family ~rigid:Evd.univ_flexible_alg env)
+ Evarutil.evd_comb1 (Evd.fresh_sort_in_family ~rigid:Evd.univ_flexible_alg)
evdref kinds
in
let typP = make_arity env !evdref dep indf s in
@@ -550,8 +550,7 @@ let check_arities env listdepkind =
let kelim = elim_sorts (mibi,mipi) in
if not (Sorts.List.mem kind kelim) then raise
(RecursionSchemeError
- (NotAllowedCaseAnalysis (true, fst (Universes.fresh_sort_in_family env
- kind),(mind,u))))
+ (NotAllowedCaseAnalysis (true, fst (UnivGen.fresh_sort_in_family kind),(mind,u))))
else if Int.List.mem ni ln then raise
(RecursionSchemeError (NotMutualInScheme (mind,mind)))
else ni::ln)
diff --git a/pretyping/indrec.mli b/pretyping/indrec.mli
index 7a68443b..de9d3a0a 100644
--- a/pretyping/indrec.mli
+++ b/pretyping/indrec.mli
@@ -62,7 +62,7 @@ val weaken_sort_scheme : env -> evar_map -> bool -> Sorts.t -> int -> constr ->
(** Recursor names utilities *)
-val lookup_eliminator : inductive -> Sorts.family -> Globnames.global_reference
+val lookup_eliminator : inductive -> Sorts.family -> GlobRef.t
val elimination_suffix : Sorts.family -> string
val make_elimination_ident : Id.t -> Sorts.family -> Id.t
diff --git a/pretyping/inductiveops.ml b/pretyping/inductiveops.ml
index 97aa82e4..0fa573b9 100644
--- a/pretyping/inductiveops.ml
+++ b/pretyping/inductiveops.ml
@@ -51,7 +51,7 @@ let arities_of_constructors env (ind,u as indu) =
type inductive_family = pinductive * constr list
let make_ind_family (mis, params) = (mis,params)
-let dest_ind_family (mis,params) = (mis,params)
+let dest_ind_family (mis,params) : inductive_family = (mis,params)
let map_ind_family f (mis,params) = (mis, List.map f params)
@@ -269,16 +269,14 @@ let allowed_sorts env (kn,i as ind) =
let (mib,mip) = Inductive.lookup_mind_specif env ind in
mip.mind_kelim
-let projection_nparams_env env p =
- let pb = lookup_projection p env in
- pb.proj_npars
+let projection_nparams_env _ p = Projection.npars p
-let projection_nparams p = projection_nparams_env (Global.env ()) p
+let projection_nparams p = Projection.npars p
let has_dependent_elim mib =
match mib.mind_record with
- | Some (Some _) -> mib.mind_finite == BiFinite
- | _ -> true
+ | PrimRecord _ -> mib.mind_finite == BiFinite
+ | NotRecord | FakeRecord -> true
(* Annotation for cases *)
let make_case_info env ind style =
@@ -303,7 +301,7 @@ type constructor_summary = {
cs_cstr : pconstructor;
cs_params : constr list;
cs_nargs : int;
- cs_args : Context.Rel.t;
+ cs_args : Constr.rel_context;
cs_concl_realargs : constr array
}
@@ -343,41 +341,39 @@ let get_constructors env (ind,params) =
Array.init (Array.length mip.mind_consnames)
(fun j -> get_constructor (ind,mib,mip,params) (j+1))
-let get_projections env (ind,params) =
- let (mib,mip) = Inductive.lookup_mind_specif env (fst ind) in
- match mib.mind_record with
- | Some (Some (id, projs, pbs)) -> Some projs
- | _ -> None
+let get_projections = Environ.get_projections
let make_case_or_project env sigma indf ci pred c branches =
let open EConstr in
- let projs = get_projections env indf in
+ let projs = get_projections env (fst (fst indf)) in
match projs with
| None -> (mkCase (ci, pred, c, branches))
| Some ps ->
assert(Array.length branches == 1);
+ let na, ty, t = destLambda sigma pred in
let () =
- let _, _, t = destLambda sigma pred in
let (ind, _), _ = dest_ind_family indf in
let mib, _ = Inductive.lookup_mind_specif env ind in
if (* dependent *) not (Vars.noccurn sigma 1 t) &&
not (has_dependent_elim mib) then
user_err ~hdr:"make_case_or_project"
Pp.(str"Dependent case analysis not allowed" ++
- str" on inductive type " ++ Names.MutInd.print (fst ind))
+ str" on inductive type " ++ Termops.Internal.print_constr_env env sigma (mkInd ind))
in
let branch = branches.(0) in
let ctx, br = decompose_lam_n_assum sigma (Array.length ps) branch in
- let n, subst =
+ let n, len, ctx =
List.fold_right
- (fun decl (i, subst) ->
+ (fun decl (i, j, ctx) ->
match decl with
- | LocalAssum (na, t) ->
- let t = mkProj (Projection.make ps.(i) true, c) in
- (i + 1, t :: subst)
- | LocalDef (na, b, t) -> (i, Vars.substl subst b :: subst))
- ctx (0, [])
- in Vars.substl subst br
+ | LocalAssum (na, ty) ->
+ let t = mkProj (Projection.make ps.(i) true, mkRel j) in
+ (i + 1, j + 1, LocalDef (na, t, Vars.liftn 1 j ty) :: ctx)
+ | LocalDef (na, b, ty) ->
+ (i, j + 1, LocalDef (na, Vars.liftn 1 j b, Vars.liftn 1 j ty) :: ctx))
+ ctx (0, 1, [])
+ in
+ mkLetIn (na, c, ty, it_mkLambda_or_LetIn (Vars.liftn 1 (Array.length ps + 1) br) ctx)
(* substitution in a signature *)
@@ -454,6 +450,110 @@ let build_branch_type env sigma dep p cs =
(**************************************************)
+(** From a rel context describing the constructor arguments,
+ build an expansion function.
+ The term built is expecting to be substituted first by
+ a substitution of the form [params, x : ind params] *)
+let compute_projections env (kn, i as ind) =
+ let open Term in
+ let mib = Environ.lookup_mind kn env in
+ let u = match mib.mind_universes with
+ | Monomorphic_ind _ -> Instance.empty
+ | Polymorphic_ind auctx -> make_abstract_instance auctx
+ | Cumulative_ind acumi ->
+ make_abstract_instance (ACumulativityInfo.univ_context acumi)
+ in
+ let x = match mib.mind_record with
+ | NotRecord | FakeRecord ->
+ anomaly Pp.(str "Trying to build primitive projections for a non-primitive record")
+ | PrimRecord info-> Name (pi1 (info.(i)))
+ in
+ let pkt = mib.mind_packets.(i) in
+ let { mind_nparams = nparamargs; mind_params_ctxt = params } = mib in
+ let subst = List.init mib.mind_ntypes (fun i -> mkIndU ((kn, mib.mind_ntypes - i - 1), u)) in
+ let rctx, _ = decompose_prod_assum (substl subst pkt.mind_nf_lc.(0)) in
+ let ctx, paramslet = List.chop pkt.mind_consnrealdecls.(0) rctx in
+ (** We build a substitution smashing the lets in the record parameters so
+ that typechecking projections requires just a substitution and not
+ matching with a parameter context. *)
+ let indty =
+ (* [ty] = [Ind inst] is typed in context [params] *)
+ let inst = Context.Rel.to_extended_vect mkRel 0 paramslet in
+ let indu = mkIndU (ind, u) in
+ let ty = mkApp (indu, inst) in
+ (* [Ind inst] is typed in context [params-wo-let] *)
+ ty
+ in
+ let ci =
+ let print_info =
+ { ind_tags = []; cstr_tags = [|Context.Rel.to_tags ctx|]; style = LetStyle } in
+ { ci_ind = ind;
+ ci_npar = nparamargs;
+ ci_cstr_ndecls = pkt.mind_consnrealdecls;
+ ci_cstr_nargs = pkt.mind_consnrealargs;
+ ci_pp_info = print_info }
+ in
+ let len = List.length ctx in
+ let compat_body ccl i =
+ (* [ccl] is defined in context [params;x:indty] *)
+ (* [ccl'] is defined in context [params;x:indty;x:indty] *)
+ let ccl' = liftn 1 2 ccl in
+ let p = mkLambda (x, lift 1 indty, ccl') in
+ let branch = it_mkLambda_or_LetIn (mkRel (len - i)) ctx in
+ let body = mkCase (ci, p, mkRel 1, [|lift 1 branch|]) in
+ it_mkLambda_or_LetIn (mkLambda (x,indty,body)) params
+ in
+ let projections decl (proj_arg, j, pbs, subst) =
+ match decl with
+ | LocalDef (na,c,t) ->
+ (* From [params, field1,..,fieldj |- c(params,field1,..,fieldj)]
+ to [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)] *)
+ let c = liftn 1 j c in
+ (* From [params, x:I, field1,..,fieldj |- c(params,field1,..,fieldj)]
+ to [params, x:I |- c(params,proj1 x,..,projj x)] *)
+ let c1 = substl subst c in
+ (* From [params, x:I |- subst:field1,..,fieldj]
+ to [params, x:I |- subst:field1,..,fieldj+1] where [subst]
+ is represented with instance of field1 last *)
+ let subst = c1 :: subst in
+ (proj_arg, j+1, pbs, subst)
+ | LocalAssum (na,t) ->
+ match na with
+ | Name id ->
+ let lab = Label.of_id id in
+ let kn = Projection.Repr.make ind ~proj_npars:mib.mind_nparams ~proj_arg lab in
+ (* from [params, field1,..,fieldj |- t(params,field1,..,fieldj)]
+ to [params, x:I, field1,..,fieldj |- t(params,field1,..,fieldj] *)
+ let t = liftn 1 j t in
+ (* from [params, x:I, field1,..,fieldj |- t(params,field1,..,fieldj)]
+ to [params-wo-let, x:I |- t(params,proj1 x,..,projj x)] *)
+ (* from [params, x:I, field1,..,fieldj |- t(field1,..,fieldj)]
+ to [params, x:I |- t(proj1 x,..,projj x)] *)
+ let ty = substl subst t in
+ let term = mkProj (Projection.make kn true, mkRel 1) in
+ let fterm = mkProj (Projection.make kn false, mkRel 1) in
+ let compat = compat_body ty (j - 1) in
+ let etab = it_mkLambda_or_LetIn (mkLambda (x, indty, term)) params in
+ let etat = it_mkProd_or_LetIn (mkProd (x, indty, ty)) params in
+ let body = (etab, etat, compat) in
+ (proj_arg + 1, j + 1, body :: pbs, fterm :: subst)
+ | Anonymous ->
+ anomaly Pp.(str "Trying to build primitive projections for a non-primitive record")
+ in
+ let (_, _, pbs, subst) =
+ List.fold_right projections ctx (0, 1, [], [])
+ in
+ Array.rev_of_list pbs
+
+let legacy_match_projection env ind =
+ Array.map pi3 (compute_projections env ind)
+
+let compute_projections ind mib =
+ let ans = compute_projections ind mib in
+ Array.map (fun (prj, ty, _) -> (prj, ty)) ans
+
+(**************************************************)
+
let extract_mrectype sigma t =
let open EConstr in
let (t, l) = decompose_app sigma t in
@@ -629,6 +729,10 @@ let type_of_inductive_knowing_conclusion env sigma ((mib,mip),u) conclty =
env evdref scl ar.template_level (ctx,ar.template_param_levels) in
!evdref, EConstr.of_constr (mkArity (List.rev ctx,scl))
+let type_of_projection_constant env (p,u) =
+ let pty = lookup_projection p env in
+ Vars.subst_instance_constr u pty
+
let type_of_projection_knowing_arg env sigma p c ty =
let c = EConstr.Unsafe.to_constr c in
let IndType(pars,realargs) =
@@ -637,7 +741,7 @@ let type_of_projection_knowing_arg env sigma p c ty =
raise (Invalid_argument "type_of_projection_knowing_arg_type: not an inductive type")
in
let (_,u), pars = dest_ind_family pars in
- substl (c :: List.rev pars) (Typeops.type_of_projection_constant env (p,u))
+ substl (c :: List.rev pars) (type_of_projection_constant env (p,u))
(***********************************************)
(* Guard condition *)
diff --git a/pretyping/inductiveops.mli b/pretyping/inductiveops.mli
index b0d714b0..ea34707b 100644
--- a/pretyping/inductiveops.mli
+++ b/pretyping/inductiveops.mli
@@ -93,12 +93,12 @@ val inductive_nparamdecls : inductive -> int
val inductive_nparamdecls_env : env -> inductive -> int
(** @return params context *)
-val inductive_paramdecls : pinductive -> Context.Rel.t
-val inductive_paramdecls_env : env -> pinductive -> Context.Rel.t
+val inductive_paramdecls : pinductive -> Constr.rel_context
+val inductive_paramdecls_env : env -> pinductive -> Constr.rel_context
(** @return full arity context, hence with letin *)
-val inductive_alldecls : pinductive -> Context.Rel.t
-val inductive_alldecls_env : env -> pinductive -> Context.Rel.t
+val inductive_alldecls : pinductive -> Constr.rel_context
+val inductive_alldecls_env : env -> pinductive -> Constr.rel_context
(** {7 Extract information from a constructor name} *)
@@ -130,7 +130,10 @@ val has_dependent_elim : mutual_inductive_body -> bool
(** Primitive projections *)
val projection_nparams : Projection.t -> int
+[@@ocaml.deprecated "Use [Projection.npars]"]
val projection_nparams_env : env -> Projection.t -> int
+[@@ocaml.deprecated "Use [Projection.npars]"]
+
val type_of_projection_knowing_arg : env -> evar_map -> Projection.t ->
EConstr.t -> EConstr.types -> types
@@ -141,7 +144,7 @@ type constructor_summary = {
cs_cstr : pconstructor; (* internal name of the constructor plus universes *)
cs_params : constr list; (* parameters of the constructor in current ctx *)
cs_nargs : int; (* length of arguments signature (letin included) *)
- cs_args : Context.Rel.t; (* signature of the arguments (letin included) *)
+ cs_args : Constr.rel_context; (* signature of the arguments (letin included) *)
cs_concl_realargs : constr array; (* actual realargs in the concl of cstr *)
}
val lift_constructor : int -> constructor_summary -> constructor_summary
@@ -149,12 +152,13 @@ val get_constructor :
pinductive * mutual_inductive_body * one_inductive_body * constr list ->
int -> constructor_summary
val get_constructors : env -> inductive_family -> constructor_summary array
-val get_projections : env -> inductive_family -> Constant.t array option
+val get_projections : env -> inductive -> Projection.Repr.t array option
+[@@ocaml.deprecated "Use [Environ.get_projections]"]
(** [get_arity] returns the arity of the inductive family instantiated
with the parameters; if recursively non-uniform parameters are not
part of the inductive family, they appears in the arity *)
-val get_arity : env -> inductive_family -> Context.Rel.t * Sorts.family
+val get_arity : env -> inductive_family -> Constr.rel_context * Sorts.family
val build_dependent_constructor : constructor_summary -> constr
val build_dependent_inductive : env -> inductive_family -> constr
@@ -194,6 +198,18 @@ val make_case_or_project :
val make_default_case_info : env -> case_style -> inductive -> case_info
i*)
+val compute_projections : Environ.env -> inductive -> (constr * types) array
+(** Given a primitive record type, for every field computes the eta-expanded
+ projection and its type. *)
+
+val legacy_match_projection : Environ.env -> inductive -> constr array
+(** Given a record type, computes the legacy match-based projection of the
+ projections.
+
+ BEWARE: such terms are ill-typed, and should thus only be used in upper
+ layers. The kernel will probably badly fail if presented with one of
+ those. *)
+
(********************)
val type_of_inductive_knowing_conclusion :
diff --git a/intf/locus.ml b/pretyping/locus.ml
index 95a2e495..37dd120c 100644
--- a/intf/locus.ml
+++ b/pretyping/locus.ml
@@ -9,10 +9,13 @@
(************************************************************************)
open Names
-open Misctypes
(** Locus : positions in hypotheses and goals *)
+type 'a or_var =
+ | ArgArg of 'a
+ | ArgVar of lident
+
(** {6 Occurrences} *)
type 'a occurrences_gen =
diff --git a/pretyping/locusops.ml b/pretyping/locusops.ml
index 1664e68f..6b6a3f8a 100644
--- a/pretyping/locusops.ml
+++ b/pretyping/locusops.ml
@@ -86,8 +86,8 @@ let concrete_clause_of enum_hyps cl =
(** Miscellaneous functions *)
let out_arg = function
- | Misctypes.ArgVar _ -> CErrors.anomaly (Pp.str "Unevaluated or_var variable.")
- | Misctypes.ArgArg x -> x
+ | ArgVar _ -> CErrors.anomaly (Pp.str "Unevaluated or_var variable.")
+ | ArgArg x -> x
let occurrences_of_hyp id cls =
let rec hyp_occ = function
diff --git a/pretyping/miscops.ml b/pretyping/miscops.ml
deleted file mode 100644
index 0f0af540..00000000
--- a/pretyping/miscops.ml
+++ /dev/null
@@ -1,76 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Util
-open Misctypes
-open Genredexpr
-
-(** Mapping [cast_type] *)
-
-let map_cast_type f = function
- | CastConv a -> CastConv (f a)
- | CastVM a -> CastVM (f a)
- | CastCoerce -> CastCoerce
- | CastNative a -> CastNative (f a)
-
-let smartmap_cast_type f c =
- match c with
- | CastConv a -> let a' = f a in if a' == a then c else CastConv a'
- | CastVM a -> let a' = f a in if a' == a then c else CastVM a'
- | CastCoerce -> CastCoerce
- | CastNative a -> let a' = f a in if a' == a then c else CastNative a'
-
-(** Equalities on [glob_sort] *)
-
-let glob_sort_eq g1 g2 = match g1, g2 with
-| GProp, GProp -> true
-| GSet, GSet -> true
-| GType l1, GType l2 ->
- List.equal (Option.equal (fun (x,m) (y,n) -> Libnames.eq_reference x y && Int.equal m n)) l1 l2
-| _ -> false
-
-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
-
-(** Mapping [red_expr_gen] *)
-
-let map_flags f flags =
- { flags with rConst = List.map f flags.rConst }
-
-let map_occs f (occ,e) = (occ,f e)
-
-let map_red_expr_gen f g h = function
- | Fold l -> Fold (List.map f l)
- | Pattern occs_l -> Pattern (List.map (map_occs f) occs_l)
- | Simpl (flags,occs_o) ->
- Simpl (map_flags g flags, Option.map (map_occs (map_union g h)) occs_o)
- | Unfold occs_l -> Unfold (List.map (map_occs g) occs_l)
- | Cbv flags -> Cbv (map_flags g flags)
- | Lazy flags -> Lazy (map_flags g flags)
- | CbvVm occs_o -> CbvVm (Option.map (map_occs (map_union g h)) occs_o)
- | CbvNative occs_o -> CbvNative (Option.map (map_occs (map_union g h)) occs_o)
- | Cbn flags -> Cbn (map_flags g flags)
- | ExtraRedExpr _ | Red _ | Hnf as x -> x
-
-(** Mapping bindings *)
-
-let map_explicit_bindings f l =
- let map = CAst.map (fun (hyp, x) -> (hyp, f x)) in
- List.map map l
-
-let map_bindings f = function
-| ImplicitBindings l -> ImplicitBindings (List.map f l)
-| ExplicitBindings expl -> ExplicitBindings (map_explicit_bindings f expl)
-| NoBindings -> NoBindings
-
-let map_with_bindings f (x, bl) = (f x, map_bindings f bl)
diff --git a/pretyping/miscops.mli b/pretyping/miscops.mli
deleted file mode 100644
index abe817fe..00000000
--- a/pretyping/miscops.mli
+++ /dev/null
@@ -1,36 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Misctypes
-open Genredexpr
-
-(** Mapping [cast_type] *)
-
-val map_cast_type : ('a -> 'b) -> 'a cast_type -> 'b cast_type
-val smartmap_cast_type : ('a -> 'a) -> 'a cast_type -> 'a cast_type
-
-(** Equalities on [glob_sort] *)
-
-val glob_sort_eq : glob_sort -> glob_sort -> bool
-
-(** Equalities on [intro_pattern_naming] *)
-
-val intro_pattern_naming_eq :
- intro_pattern_naming_expr -> intro_pattern_naming_expr -> bool
-
-(** Mapping [red_expr_gen] *)
-
-val map_red_expr_gen : ('a -> 'd) -> ('b -> 'e) -> ('c -> 'f) ->
- ('a,'b,'c) red_expr_gen -> ('d,'e,'f) red_expr_gen
-
-(** Mapping bindings *)
-
-val map_bindings : ('a -> 'b) -> 'a bindings -> 'b bindings
-val map_with_bindings : ('a -> 'b) -> 'a with_bindings -> 'b with_bindings
diff --git a/pretyping/nativenorm.ml b/pretyping/nativenorm.ml
index 1ed4d21b..4e95ecfe 100644
--- a/pretyping/nativenorm.ml
+++ b/pretyping/nativenorm.ml
@@ -21,8 +21,6 @@ open Nativecode
open Nativevalues
open Context.Rel.Declaration
-module NamedDecl = Context.Named.Declaration
-
(** This module implements normalization by evaluation to OCaml code *)
exception Find_at of int
@@ -125,7 +123,7 @@ let construct_of_constr_notnative const env tag (mind, _ as ind) u allargs =
try
if const then
let ctyp = type_constructor mind mib u (mip.mind_nf_lc.(0)) params in
- retroknowledge Retroknowledge.get_vm_decompile_constant_info env (mkInd ind) tag, ctyp
+ Retroknowledge.get_vm_decompile_constant_info env.retroknowledge (mkInd ind) tag, ctyp
else
raise Not_found
with Not_found ->
@@ -134,19 +132,19 @@ let construct_of_constr_notnative const env tag (mind, _ as ind) u allargs =
(mkApp(mkConstructU((ind,i),u), params), ctyp)
-let construct_of_constr const env tag typ =
+let construct_of_constr const env sigma tag typ =
let t, l = app_type env typ in
- match kind t with
+ match EConstr.kind_upto sigma t with
| Ind (ind,u) ->
construct_of_constr_notnative const env tag ind u l
| _ -> assert false
-let construct_of_constr_const env tag typ =
- fst (construct_of_constr true env tag typ)
+let construct_of_constr_const env sigma tag typ =
+ fst (construct_of_constr true env sigma tag typ)
let construct_of_constr_block = construct_of_constr false
-let build_branches_type env sigma (mind,_ as _ind) mib mip u params dep p =
+let build_branches_type env sigma (mind,_ as _ind) mib mip u params p =
let rtbl = mip.mind_reloc_tbl in
(* [build_one_branch i cty] construit le type de la ieme branche (commence
a 0) et les lambda correspondant aux realargs *)
@@ -163,20 +161,17 @@ let build_branches_type env sigma (mind,_ as _ind) mib mip u params dep p =
let codom =
let ndecl = List.length decl in
let papp = mkApp(lift ndecl p,crealargs) in
- if dep then
- let cstr = ith_constructor_of_inductive (fst ind) (i+1) in
- let relargs = Array.init carity (fun i -> mkRel (carity-i)) in
- let params = Array.map (lift ndecl) params in
- let dep_cstr = mkApp(mkApp(mkConstructU (cstr,snd ind),params),relargs) in
- mkApp(papp,[|dep_cstr|])
- else papp
+ let cstr = ith_constructor_of_inductive (fst ind) (i+1) in
+ let relargs = Array.init carity (fun i -> mkRel (carity-i)) in
+ let params = Array.map (lift ndecl) params in
+ let dep_cstr = mkApp(mkApp(mkConstructU (cstr,snd ind),params),relargs) in
+ mkApp(papp,[|dep_cstr|])
in
decl, decl_with_letin, codom
in Array.mapi build_one_branch mip.mind_nf_lc
-let build_case_type dep p realargs c =
- if dep then mkApp(mkApp(p, realargs), [|c|])
- else mkApp(p, realargs)
+let build_case_type p realargs c =
+ mkApp(mkApp(p, realargs), [|c|])
(* normalisation of values *)
@@ -190,6 +185,14 @@ let branch_of_switch lvl ans bs =
bs ci in
Array.init (Array.length tbl) branch
+let get_proj env (ind, proj_arg) =
+ let mib = Environ.lookup_mind (fst ind) env in
+ match Declareops.inductive_make_projection ind mib ~proj_arg with
+ | None ->
+ CErrors.anomaly (Pp.strbrk "Return type is not a primitive record")
+ | Some p ->
+ Projection.make p true
+
let rec nf_val env sigma v typ =
match kind_of_value v with
| Vaccu accu -> nf_accu env sigma accu
@@ -204,9 +207,9 @@ let rec nf_val env sigma v typ =
let env = push_rel (LocalAssum (name,dom)) env in
let body = nf_val env sigma (f (mk_rel_accu lvl)) codom in
mkLambda(name,dom,body)
- | Vconst n -> construct_of_constr_const env n typ
+ | Vconst n -> construct_of_constr_const env sigma n typ
| Vblock b ->
- let capp,ctyp = construct_of_constr_block env (block_tag b) typ in
+ let capp,ctyp = construct_of_constr_block env sigma (block_tag b) typ in
let args = nf_bargs env sigma b ctyp in
mkApp(capp,args)
@@ -281,9 +284,10 @@ and nf_atom env sigma atom =
let codom = nf_type env sigma (codom vn) in
mkProd(n,dom,codom)
| Ameta (mv,_) -> mkMeta mv
- | Aproj(p,c) ->
+ | Aproj (p, c) ->
let c = nf_accu env sigma c in
- mkProj(Projection.make p true,c)
+ let p = get_proj env p in
+ mkProj(p, c)
| _ -> fst (nf_atom_type env sigma atom)
and nf_atom_type env sigma atom =
@@ -305,13 +309,13 @@ and nf_atom_type env sigma atom =
let (mib,mip) = Inductive.lookup_mind_specif env (fst ind) in
let nparams = mib.mind_nparams in
let params,realargs = Array.chop nparams allargs in
+ let nparamdecls = Context.Rel.length (Inductive.inductive_paramdecls (mib,u)) in
let pT =
- hnf_prod_applist env
+ hnf_prod_applist_assum env nparamdecls
(Inductiveops.type_of_inductive env ind) (Array.to_list params) in
- let pT = whd_all env pT in
- let dep, p = nf_predicate env sigma ind mip params p pT in
+ let p = nf_predicate env sigma ind mip params p pT in
(* Calcul du type des branches *)
- let btypes = build_branches_type env sigma (fst ind) mib mip u params dep p in
+ let btypes = build_branches_type env sigma (fst ind) mib mip u params p in
(* calcul des branches *)
let bsw = branch_of_switch (nb_rel env) ans bs in
let mkbranch i v =
@@ -320,7 +324,7 @@ and nf_atom_type env sigma atom =
Termops.it_mkLambda_or_LetIn_from_no_LetIn b decl_with_letin
in
let branchs = Array.mapi mkbranch bsw in
- let tcase = build_case_type dep p realargs a in
+ let tcase = build_case_type p realargs a in
let ci = ans.asw_ci in
mkCase(ci, p, a, branchs), tcase
| Afix(tt,ft,rp,s) ->
@@ -350,7 +354,7 @@ and nf_atom_type env sigma atom =
let env = push_rel (LocalAssum (n,dom)) env in
let codom,s2 = nf_type_sort env sigma (codom vn) in
mkProd(n,dom,codom), Typeops.type_of_product env n s1 s2
- | Aevar(evk, _, args) ->
+ | Aevar(evk,args) ->
nf_evar env sigma evk args
| Ameta(mv,ty) ->
let ty = nf_type env sigma ty in
@@ -358,25 +362,30 @@ and nf_atom_type env sigma atom =
| Aproj(p,c) ->
let c,tc = nf_accu_type env sigma c in
let cj = make_judge c tc in
- let uj = Typeops.judge_of_projection env (Projection.make p true) cj in
+ let p = get_proj env p in
+ let uj = Typeops.judge_of_projection env p cj in
uj.uj_val, uj.uj_type
and nf_predicate env sigma ind mip params v pT =
- match kind_of_value v, kind pT with
- | Vfun f, Prod _ ->
+ match kind (whd_allnolet env pT) with
+ | LetIn (name,b,t,pT) ->
+ let body =
+ nf_predicate (push_rel (LocalDef (name,b,t)) env) sigma ind mip params v pT in
+ mkLetIn (name,b,t,body)
+ | Prod (name,dom,codom) -> begin
+ match kind_of_value v with
+ | Vfun f ->
let k = nb_rel env in
let vb = f (mk_rel_accu k) in
- let name,dom,codom =
- try decompose_prod env pT with
- DestKO ->
- CErrors.anomaly
- (Pp.strbrk "Returned a functional value in a type not recognized as a product type.")
- in
- let dep,body =
+ let body =
nf_predicate (push_rel (LocalAssum (name,dom)) env) sigma ind mip params vb codom in
- dep, mkLambda(name,dom,body)
- | Vfun f, _ ->
+ mkLambda(name,dom,body)
+ | _ -> nf_type env sigma v
+ end
+ | _ ->
+ match kind_of_value v with
+ | Vfun f ->
let k = nb_rel env in
let vb = f (mk_rel_accu k) in
let name = Name (Id.of_string "c") in
@@ -385,13 +394,13 @@ and nf_predicate env sigma ind mip params v pT =
let params = if Int.equal n 0 then params else Array.map (lift n) params in
let dom = mkApp(mkIndU ind,Array.append params rargs) in
let body = nf_type (push_rel (LocalAssum (name,dom)) env) sigma vb in
- true, mkLambda(name,dom,body)
- | _, _ -> false, nf_type env sigma v
+ mkLambda(name,dom,body)
+ | _ -> nf_type env sigma v
and nf_evar env sigma evk args =
let evi = try Evd.find sigma evk with Not_found -> assert false in
let hyps = Environ.named_context_of_val (Evd.evar_filtered_hyps evi) in
- let ty = Evd.evar_concl evi in
+ let ty = EConstr.Unsafe.to_constr @@ Evd.evar_concl evi in
if List.is_empty hyps then begin
assert (Int.equal (Array.length args) 0);
mkEvar (evk, [||]), ty
@@ -399,11 +408,7 @@ and nf_evar env sigma evk args =
else
(** Let-bound arguments are present in the evar arguments but not in the
type, so we turn the let into a product. *)
- let drop_body = function
- | NamedDecl.LocalAssum _ as d -> d
- | NamedDecl.LocalDef (na, _, t) -> NamedDecl.LocalAssum (na, t)
- in
- let hyps = List.map drop_body hyps in
+ let hyps = Context.Named.drop_bodies hyps in
let fold accu d = Term.mkNamedProd_or_LetIn d accu in
let t = List.fold_left fold ty hyps in
let ty, args = nf_args env sigma args t in
@@ -412,9 +417,8 @@ and nf_evar env sigma evk args =
mkEvar (evk, Array.rev_of_list args), ty
let evars_of_evar_map sigma =
- { Nativelambda.evars_val = Evd.existential_opt_value sigma;
- Nativelambda.evars_typ = Evd.existential_type sigma;
- Nativelambda.evars_metas = Evd.meta_type sigma }
+ { Nativelambda.evars_val = Evd.existential_opt_value0 sigma;
+ Nativelambda.evars_metas = Evd.meta_type0 sigma }
(* fork perf process, return profiler's process id *)
let start_profiler_linux profile_fn =
@@ -468,13 +472,12 @@ let native_norm env sigma c ty =
if not Coq_config.native_compiler then
user_err Pp.(str "Native_compute reduction has been disabled at configure time.")
else
- let penv = Environ.pre_env env in
(*
Format.eprintf "Numbers of free variables (named): %i\n" (List.length vl1);
Format.eprintf "Numbers of free variables (rel): %i\n" (List.length vl2);
*)
let ml_filename, prefix = Nativelib.get_ml_filename () in
- let code, upd = mk_norm_code penv (evars_of_evar_map sigma) prefix c in
+ let code, upd = mk_norm_code env (evars_of_evar_map sigma) prefix c in
let profile = get_profiling_enabled () in
match Nativelib.compile ml_filename code ~profile:profile with
| true, fn ->
diff --git a/pretyping/nativenorm.mli b/pretyping/nativenorm.mli
index 67b7a2a4..4997d0bf 100644
--- a/pretyping/nativenorm.mli
+++ b/pretyping/nativenorm.mli
@@ -25,4 +25,4 @@ val native_norm : env -> evar_map -> constr -> types -> constr
(** Conversion with inference of universe constraints *)
val native_infer_conv : ?pb:conv_pb -> env -> evar_map -> constr -> constr ->
- evar_map * bool
+ evar_map option
diff --git a/intf/pattern.ml b/pretyping/pattern.ml
index af234767..be7ebe49 100644
--- a/intf/pattern.ml
+++ b/pretyping/pattern.ml
@@ -9,12 +9,12 @@
(************************************************************************)
open Names
-open Globnames
-open Constr
-open Misctypes
(** {5 Patterns} *)
+(** Cases pattern variables *)
+type patvar = Id.t
+
type case_info_pattern =
{ cip_style : Constr.case_style;
cip_ind : inductive option;
@@ -22,9 +22,9 @@ type case_info_pattern =
cip_extensible : bool (** does this match end with _ => _ ? *) }
type constr_pattern =
- | PRef of global_reference
+ | PRef of GlobRef.t
| PVar of Id.t
- | PEvar of existential_key * constr_pattern array
+ | PEvar of Evar.t * constr_pattern array
| PRel of int
| PApp of constr_pattern * constr_pattern array
| PSoApp of patvar * constr_pattern list
@@ -32,13 +32,13 @@ type constr_pattern =
| PLambda of Name.t * constr_pattern * constr_pattern
| PProd of Name.t * constr_pattern * constr_pattern
| PLetIn of Name.t * constr_pattern * constr_pattern option * constr_pattern
- | PSort of glob_sort
+ | PSort of Glob_term.glob_sort
| PMeta of patvar option
| PIf of constr_pattern * constr_pattern * constr_pattern
| PCase of case_info_pattern * constr_pattern * constr_pattern *
(int * bool list * constr_pattern) list (** index of constructor, nb of args *)
- | PFix of fixpoint
- | PCoFix of cofixpoint
+ | PFix of (int array * int) * (Name.t array * constr_pattern array * constr_pattern array)
+ | PCoFix of int * (Name.t array * constr_pattern array * constr_pattern array)
(** Nota : in a [PCase], the array of branches might be shorter than
expected, denoting the use of a final "_ => _" branch *)
diff --git a/pretyping/patternops.ml b/pretyping/patternops.ml
index c9925087..3c1c4700 100644
--- a/pretyping/patternops.ml
+++ b/pretyping/patternops.ml
@@ -15,11 +15,9 @@ open Globnames
open Nameops
open Term
open Constr
-open Vars
open Glob_term
open Pp
open Mod_subst
-open Misctypes
open Decl_kinds
open Pattern
open Environ
@@ -31,7 +29,7 @@ let case_info_pattern_eq i1 i2 =
i1.cip_extensible == i2.cip_extensible
let rec constr_pattern_eq p1 p2 = match p1, p2 with
-| PRef r1, PRef r2 -> eq_gr r1 r2
+| PRef r1, PRef r2 -> GlobRef.equal r1 r2
| PVar v1, PVar v2 -> Id.equal v1 v2
| PEvar (ev1, ctx1), PEvar (ev2, ctx2) ->
Evar.equal ev1 ev2 && Array.equal constr_pattern_eq ctx1 ctx2
@@ -48,7 +46,7 @@ let rec constr_pattern_eq p1 p2 = match p1, p2 with
| PLetIn (v1, b1, t1, c1), PLetIn (v2, b2, t2, c2) ->
Name.equal v1 v2 && constr_pattern_eq b1 b2 &&
Option.equal constr_pattern_eq t1 t2 && constr_pattern_eq c1 c2
-| PSort s1, PSort s2 -> Miscops.glob_sort_eq s1 s2
+| PSort s1, PSort s2 -> Glob_ops.glob_sort_eq s1 s2
| PMeta m1, PMeta m2 -> Option.equal Id.equal m1 m2
| PIf (t1, l1, r1), PIf (t2, l2, r2) ->
constr_pattern_eq t1 t2 && constr_pattern_eq l1 l2 && constr_pattern_eq r1 r2
@@ -57,10 +55,10 @@ let rec constr_pattern_eq p1 p2 = match p1, p2 with
constr_pattern_eq p1 p2 &&
constr_pattern_eq r1 r2 &&
List.equal pattern_eq l1 l2
-| PFix f1, PFix f2 ->
- fixpoint_eq f1 f2
-| PCoFix f1, PCoFix f2 ->
- cofixpoint_eq f1 f2
+| PFix ((ln1,i1),f1), PFix ((ln2,i2),f2) ->
+ Array.equal Int.equal ln1 ln2 && Int.equal i1 i2 && rec_declaration_eq f1 f2
+| PCoFix (i1,f1), PCoFix (i2,f2) ->
+ Int.equal i1 i2 && rec_declaration_eq f1 f2
| PProj (p1, t1), PProj (p2, t2) ->
Projection.equal p1 p2 && constr_pattern_eq t1 t2
| (PRef _ | PVar _ | PEvar _ | PRel _ | PApp _ | PSoApp _
@@ -71,19 +69,10 @@ let rec constr_pattern_eq p1 p2 = match p1, p2 with
and pattern_eq (i1, j1, p1) (i2, j2, p2) =
Int.equal i1 i2 && List.equal (==) j1 j2 && constr_pattern_eq p1 p2
-and fixpoint_eq ((arg1, i1), r1) ((arg2, i2), r2) =
- Int.equal i1 i2 &&
- Array.equal Int.equal arg1 arg2 &&
- rec_declaration_eq r1 r2
-
-and cofixpoint_eq (i1, r1) (i2, r2) =
- Int.equal i1 i2 &&
- rec_declaration_eq r1 r2
-
and rec_declaration_eq (n1, c1, r1) (n2, c2, r2) =
Array.equal Name.equal n1 n2 &&
- Array.equal Constr.equal c1 c2 &&
- Array.equal Constr.equal r1 r2
+ Array.equal constr_pattern_eq c1 c2 &&
+ Array.equal constr_pattern_eq r1 r2
let rec occur_meta_pattern = function
| PApp (f,args) ->
@@ -123,8 +112,10 @@ let rec occurn_pattern n = function
| PMeta _ | PSoApp _ -> true
| PEvar (_,args) -> Array.exists (occurn_pattern n) args
| PVar _ | PRef _ | PSort _ -> false
- | PFix fix -> not (noccurn n (mkFix fix))
- | PCoFix cofix -> not (noccurn n (mkCoFix cofix))
+ | PFix (_,(_,tl,bl)) ->
+ Array.exists (occurn_pattern n) tl || Array.exists (occurn_pattern (n+Array.length tl)) bl
+ | PCoFix (_,(_,tl,bl)) ->
+ Array.exists (occurn_pattern n) tl || Array.exists (occurn_pattern (n+Array.length tl)) bl
let noccurn_pattern n c = not (occurn_pattern n c)
@@ -139,8 +130,7 @@ let rec head_pattern_bound t =
| PCase (_,p,c,br) -> head_pattern_bound c
| PRef r -> r
| PVar id -> VarRef id
- | PProj (p,c) -> ConstRef (Projection.constant p)
- | PEvar _ | PRel _ | PMeta _ | PSoApp _ | PSort _ | PFix _
+ | PEvar _ | PRel _ | PMeta _ | PSoApp _ | PSort _ | PFix _ | PProj _
-> raise BoundPattern
(* Perhaps they were arguments, but we don't beta-reduce *)
| PLambda _ -> raise BoundPattern
@@ -160,8 +150,8 @@ let pattern_of_constr env sigma t =
| Rel n -> PRel n
| Meta n -> PMeta (Some (Id.of_string ("META" ^ string_of_int n)))
| Var id -> PVar id
- | Sort (Prop Null) -> PSort GProp
- | Sort (Prop Pos) -> PSort GSet
+ | Sort Prop -> PSort GProp
+ | Sort Set -> PSort GSet
| Sort (Type _) -> PSort (GType [])
| Cast (c,_,_) -> pattern_of_constr env c
| LetIn (na,c,t,b) -> PLetIn (na,pattern_of_constr env c,Some (pattern_of_constr env t),
@@ -193,7 +183,7 @@ let pattern_of_constr env sigma t =
| Evar_kinds.GoalEvar | Evar_kinds.VarInstance _ ->
(* These are the two evar kinds used for existing goals *)
(* see Proofview.mark_in_evm *)
- if Evd.is_defined sigma evk then pattern_of_constr env (Evd.existential_value sigma ev)
+ if Evd.is_defined sigma evk then pattern_of_constr env (Evd.existential_value0 sigma ev)
else PEvar (evk,Array.map (pattern_of_constr env) ctxt)
| Evar_kinds.MatchingVar (Evar_kinds.SecondOrderPatVar ido) -> assert false
| _ ->
@@ -210,8 +200,16 @@ let pattern_of_constr env sigma t =
in
PCase (cip, pattern_of_constr env p, pattern_of_constr env a,
Array.to_list (Array.mapi branch_of_constr br))
- | Fix f -> PFix f
- | CoFix f -> PCoFix f in
+ | Fix (lni,(lna,tl,bl)) ->
+ let push env na2 c2 = push_rel (LocalAssum (na2,c2)) env in
+ let env' = Array.fold_left2 push env lna tl in
+ PFix (lni,(lna,Array.map (pattern_of_constr env) tl,
+ Array.map (pattern_of_constr env') bl))
+ | CoFix (ln,(lna,tl,bl)) ->
+ let push env na2 c2 = push_rel (LocalAssum (na2,c2)) env in
+ let env' = Array.fold_left2 push env lna tl in
+ PCoFix (ln,(lna,Array.map (pattern_of_constr env) tl,
+ Array.map (pattern_of_constr env') bl)) in
pattern_of_constr env t
(* To process patterns, we need a translation without typing at all. *)
@@ -226,10 +224,14 @@ let map_pattern_with_binders g f l = function
| PCase (ci,po,p,pl) ->
PCase (ci,f l po,f l p, List.map (fun (i,n,c) -> (i,n,f l c)) pl)
| PProj (p,pc) -> PProj (p, f l pc)
+ | PFix (lni,(lna,tl,bl)) ->
+ let l' = Array.fold_left (fun l na -> g na l) l lna in
+ PFix (lni,(lna,Array.map (f l) tl,Array.map (f l') bl))
+ | PCoFix (ln,(lna,tl,bl)) ->
+ let l' = Array.fold_left (fun l na -> g na l) l lna in
+ PCoFix (ln,(lna,Array.map (f l) tl,Array.map (f l') bl))
(* Non recursive *)
- | (PVar _ | PEvar _ | PRel _ | PRef _ | PSort _ | PMeta _
- (* Bound to terms *)
- | PFix _ | PCoFix _ as x) -> x
+ | (PVar _ | PEvar _ | PRel _ | PRef _ | PSort _ | PMeta _ as x) -> x
let error_instantiate_pattern id l =
let is = match l with
@@ -263,15 +265,12 @@ let instantiate_pattern env sigma lvar c =
error_instantiate_pattern id (List.subtract Id.equal ctx vars)
with Not_found (* Map.find failed *) ->
x)
- | (PFix _ | PCoFix _) -> user_err Pp.(str "Non instantiable pattern.")
| c ->
map_pattern_with_binders (fun id vars -> id::vars) aux vars c in
aux [] c
let rec liftn_pattern k n = function
| PRel i as x -> if i >= n then PRel (i+k) else x
- | PFix x -> PFix (destFix (liftn k n (mkFix x)))
- | PCoFix x -> PCoFix (destCoFix (liftn k n (mkCoFix x)))
| c -> map_pattern_with_binders (fun _ -> succ) (liftn_pattern k) n c
let lift_pattern k = liftn_pattern k 1
@@ -279,25 +278,26 @@ let lift_pattern k = liftn_pattern k 1
let rec subst_pattern subst pat =
match pat with
| PRef ref ->
- let ref',t = subst_global subst ref in
- if ref' == ref then pat else
- pattern_of_constr (Global.env()) Evd.empty t
+ let ref',t = subst_global subst ref in
+ if ref' == ref then pat else
+ let env = Global.env () in
+ let evd = Evd.from_env env in
+ pattern_of_constr env evd t
| PVar _
| PEvar _
| PRel _ -> pat
| PProj (p,c) ->
- let p' = Projection.map (fun p ->
- destConstRef (fst (subst_global subst (ConstRef p)))) p in
+ let p' = Projection.map (subst_mind subst) p in
let c' = subst_pattern subst c in
if p' == p && c' == c then pat else
PProj(p',c')
| PApp (f,args) ->
let f' = subst_pattern subst f in
- let args' = Array.smartmap (subst_pattern subst) args in
+ let args' = Array.Smart.map (subst_pattern subst) args in
if f' == f && args' == args then pat else
PApp (f',args')
| PSoApp (i,args) ->
- let args' = List.smartmap (subst_pattern subst) args in
+ let args' = List.Smart.map (subst_pattern subst) args in
if args' == args then pat else
PSoApp (i,args')
| PLambda (name,c1,c2) ->
@@ -312,7 +312,7 @@ let rec subst_pattern subst pat =
PProd (name,c1',c2')
| PLetIn (name,c1,t,c2) ->
let c1' = subst_pattern subst c1 in
- let t' = Option.smartmap (subst_pattern subst) t in
+ let t' = Option.Smart.map (subst_pattern subst) t in
let c2' = subst_pattern subst c2 in
if c1' == c1 && t' == t && c2' == c2 then pat else
PLetIn (name,c1',t',c2')
@@ -326,7 +326,7 @@ let rec subst_pattern subst pat =
PIf (c',c1',c2')
| PCase (cip,typ,c,branches) ->
let ind = cip.cip_ind in
- let ind' = Option.smartmap (subst_ind subst) ind in
+ let ind' = Option.Smart.map (subst_ind subst) ind in
let cip' = if ind' == ind then cip else { cip with cip_ind = ind' } in
let typ' = subst_pattern subst typ in
let c' = subst_pattern subst c in
@@ -334,23 +334,39 @@ let rec subst_pattern subst pat =
let c' = subst_pattern subst c in
if c' == c then br else (i,n,c')
in
- let branches' = List.smartmap subst_branch branches in
+ let branches' = List.Smart.map subst_branch branches in
if cip' == cip && typ' == typ && c' == c && branches' == branches
then pat
else PCase(cip', typ', c', branches')
- | PFix fixpoint ->
- let cstr = mkFix fixpoint in
- let fixpoint' = destFix (subst_mps subst cstr) in
- if fixpoint' == fixpoint then pat else
- PFix fixpoint'
- | PCoFix cofixpoint ->
- let cstr = mkCoFix cofixpoint in
- let cofixpoint' = destCoFix (subst_mps subst cstr) in
- if cofixpoint' == cofixpoint then pat else
- PCoFix cofixpoint'
-
-let mkPLambda na b = PLambda(na,PMeta None,b)
-let rev_it_mkPLambda = List.fold_right mkPLambda
+ | PFix (lni,(lna,tl,bl)) ->
+ let tl' = Array.Smart.map (subst_pattern subst) tl in
+ let bl' = Array.Smart.map (subst_pattern subst) bl in
+ if bl' == bl && tl' == tl then pat
+ else PFix (lni,(lna,tl',bl'))
+ | PCoFix (ln,(lna,tl,bl)) ->
+ let tl' = Array.Smart.map (subst_pattern subst) tl in
+ let bl' = Array.Smart.map (subst_pattern subst) bl in
+ if bl' == bl && tl' == tl then pat
+ else PCoFix (ln,(lna,tl',bl'))
+
+let mkPLetIn na b t c = PLetIn(na,b,t,c)
+let mkPProd na t u = PProd(na,t,u)
+let mkPLambda na t b = PLambda(na,t,b)
+let mkPLambdaUntyped na b = PLambda(na,PMeta None,b)
+let rev_it_mkPLambdaUntyped = List.fold_right mkPLambdaUntyped
+
+let mkPProd_or_LetIn (na,_,bo,t) c =
+ match bo with
+ | None -> mkPProd na t c
+ | Some b -> mkPLetIn na b (Some t) c
+
+let mkPLambda_or_LetIn (na,_,bo,t) c =
+ match bo with
+ | None -> mkPLambda na t c
+ | Some b -> mkPLetIn na b (Some t) c
+
+let it_mkPProd_or_LetIn = List.fold_left (fun c d -> mkPProd_or_LetIn d c)
+let it_mkPLambda_or_LetIn = List.fold_left (fun c d -> mkPLambda_or_LetIn d c)
let err ?loc pp = user_err ?loc ~hdr:"pattern_of_glob_constr" pp
@@ -400,7 +416,7 @@ let rec pat_of_raw metas vars = DAst.with_loc_val (fun ?loc -> function
pat_of_raw metas vars b1,pat_of_raw metas vars b2)
| GLetTuple (nal,(_,None),b,c) ->
let mkGLambda na c = DAst.make ?loc @@
- GLambda (na,Explicit, DAst.make @@ GHole (Evar_kinds.InternalHole, IntroAnonymous, None),c) in
+ GLambda (na,Explicit, DAst.make @@ GHole (Evar_kinds.InternalHole, Namegen.IntroAnonymous, None),c) in
let c = List.fold_right mkGLambda nal c in
let cip =
{ cip_style = LetStyle;
@@ -429,7 +445,7 @@ let rec pat_of_raw metas vars = DAst.with_loc_val (fun ?loc -> function
let pred = match p,indnames with
| Some p, Some {CAst.v=(_,nal)} ->
let nvars = na :: List.rev nal @ vars in
- rev_it_mkPLambda nal (mkPLambda na (pat_of_raw metas nvars p))
+ rev_it_mkPLambdaUntyped nal (mkPLambdaUntyped na (pat_of_raw metas nvars p))
| None, _ -> PMeta None
| Some p, None ->
match DAst.get p with
@@ -448,9 +464,40 @@ let rec pat_of_raw metas vars = DAst.with_loc_val (fun ?loc -> function
one non-trivial branch. These facts are used in [Constrextern]. *)
PCase (info, pred, pat_of_raw metas vars c, brs)
- | GPatVar _ | GIf _ | GLetTuple _ | GCases _ | GEvar _ | GRec _ ->
+ | GRec (GFix (ln,n), ids, decls, tl, cl) ->
+ if Array.exists (function (Some n, GStructRec) -> false | _ -> true) ln then
+ err ?loc (Pp.str "\"struct\" annotation is expected.")
+ else
+ let ln = Array.map (fst %> Option.get) ln in
+ let ctxtl = Array.map2 (pat_of_glob_in_context metas vars) decls tl in
+ let tl = Array.map (fun (ctx,tl) -> it_mkPProd_or_LetIn tl ctx) ctxtl in
+ let vars = Array.fold_left (fun vars na -> Name na::vars) vars ids in
+ let ctxtl = Array.map2 (pat_of_glob_in_context metas vars) decls cl in
+ let cl = Array.map (fun (ctx,cl) -> it_mkPLambda_or_LetIn cl ctx) ctxtl in
+ let names = Array.map (fun id -> Name id) ids in
+ PFix ((ln,n), (names, tl, cl))
+
+ | GRec (GCoFix n, ids, decls, tl, cl) ->
+ let ctxtl = Array.map2 (pat_of_glob_in_context metas vars) decls tl in
+ let tl = Array.map (fun (ctx,tl) -> it_mkPProd_or_LetIn tl ctx) ctxtl in
+ let vars = Array.fold_left (fun vars na -> Name na::vars) vars ids in
+ let ctxtl = Array.map2 (pat_of_glob_in_context metas vars) decls cl in
+ let cl = Array.map (fun (ctx,cl) -> it_mkPLambda_or_LetIn cl ctx) ctxtl in
+ let names = Array.map (fun id -> Name id) ids in
+ PCoFix (n, (names, tl, cl))
+
+ | GPatVar _ | GIf _ | GLetTuple _ | GCases _ | GEvar _ ->
err ?loc (Pp.str "Non supported pattern."))
+and pat_of_glob_in_context metas vars decls c =
+ let rec aux acc vars = function
+ | (na,bk,b,t) :: decls ->
+ let decl = (na,bk,Option.map (pat_of_raw metas vars) b,pat_of_raw metas vars t) in
+ aux (decl::acc) (na::vars) decls
+ | [] ->
+ acc, pat_of_raw metas vars c
+ in aux [] vars decls
+
and pats_of_glob_branches loc metas vars ind brs =
let get_arg p = match DAst.get p with
| PatVar na ->
@@ -475,7 +522,7 @@ and pats_of_glob_branches loc metas vars ind brs =
(str "No unique branch for " ++ int j ++ str"-th constructor.");
let lna = List.map get_arg lv in
let vars' = List.rev lna @ vars in
- let pat = rev_it_mkPLambda lna (pat_of_raw metas vars' br) in
+ let pat = rev_it_mkPLambdaUntyped lna (pat_of_raw metas vars' br) in
let ext,pats = get_pat (Int.Set.add (j-1) indexes) brs in
let tags = List.map (fun _ -> false) lv (* approximation, w/o let-in *) in
ext, ((j-1, tags, pat) :: pats)
diff --git a/pretyping/patternops.mli b/pretyping/patternops.mli
index 9f087857..36317b3a 100644
--- a/pretyping/patternops.mli
+++ b/pretyping/patternops.mli
@@ -8,12 +8,11 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open EConstr
-open Globnames
-open Glob_term
+open Names
open Mod_subst
-open Misctypes
+open Glob_term
open Pattern
+open EConstr
open Ltac_pretype
(** {5 Functions on patterns} *)
@@ -32,12 +31,12 @@ exception BoundPattern
type [t] or raises [BoundPattern] (even if a sort); it raises an anomaly
if [t] is an abstraction *)
-val head_pattern_bound : constr_pattern -> global_reference
+val head_pattern_bound : constr_pattern -> GlobRef.t
(** [head_of_constr_reference c] assumes [r] denotes a reference and
returns its label; raises an anomaly otherwise *)
-val head_of_constr_reference : Evd.evar_map -> constr -> global_reference
+val head_of_constr_reference : Evd.evar_map -> constr -> GlobRef.t
(** [pattern_of_constr c] translates a term [c] with metavariables into
a pattern; currently, no destructor (Cases, Fix, Cofix) and no
diff --git a/pretyping/pretype_errors.ml b/pretyping/pretype_errors.ml
index 278a4761..856894d9 100644
--- a/pretyping/pretype_errors.ml
+++ b/pretyping/pretype_errors.ml
@@ -165,7 +165,7 @@ let error_not_product ?loc env sigma c =
(*s Error in conversion from AST to glob_constr *)
let error_var_not_found ?loc s =
- raise_pretype_error ?loc (empty_env, Evd.empty, VarNotFound s)
+ raise_pretype_error ?loc (empty_env, Evd.from_env empty_env, VarNotFound s)
(*s Typeclass errors *)
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index c7db802f..ab6c1393 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -28,6 +28,7 @@ open CErrors
open Util
open Names
open Evd
+open Constr
open Term
open Termops
open Environ
@@ -44,7 +45,6 @@ open Pretype_errors
open Glob_term
open Glob_ops
open Evarconv
-open Misctypes
open Ltac_pretype
module NamedDecl = Context.Named.Declaration
@@ -117,7 +117,7 @@ open ExtraEnv
exception Found of int array
let nf_fix sigma (nas, cs, ts) =
- let inj c = EConstr.to_constr sigma c in
+ let inj c = EConstr.to_constr ~abort_on_undefined_evars:false sigma c in
(nas, Array.map inj cs, Array.map inj ts)
let search_guard ?loc env possible_indexes fixdefs =
@@ -169,48 +169,39 @@ let _ =
optread = is_strict_universe_declarations;
optwrite = (:=) strict_universe_declarations })
-let _ =
- Goptions.(declare_bool_option
- { optdepr = false;
- optname = "minimization to Set";
- optkey = ["Universe";"Minimization";"ToSet"];
- optread = Universes.is_set_minimization;
- optwrite = (:=) Universes.set_minimization })
-
(** Miscellaneous interpretation functions *)
-let interp_known_universe_level evd r =
- let qid = Libnames.qualid_of_reference r in
+let interp_known_universe_level evd qid =
try
- match r.CAst.v with
- | Libnames.Ident id -> Evd.universe_of_name evd id
- | Libnames.Qualid _ -> raise Not_found
+ let open Libnames in
+ if qualid_is_ident qid then Evd.universe_of_name evd @@ qualid_basename qid
+ else raise Not_found
with Not_found ->
- let univ, k = Nametab.locate_universe qid.CAst.v in
+ let univ, k = Nametab.locate_universe qid in
Univ.Level.make univ k
-let interp_universe_level_name ~anon_rigidity evd r =
- try evd, interp_known_universe_level evd r
+let interp_universe_level_name ~anon_rigidity evd qid =
+ try evd, interp_known_universe_level evd qid
with Not_found ->
- match r with (* Qualified generated name *)
- | {CAst.loc; v=Libnames.Qualid qid} ->
- let dp, i = Libnames.repr_qualid qid in
- let num =
- try int_of_string (Id.to_string i)
- with Failure _ ->
- user_err ?loc ~hdr:"interp_universe_level_name"
- (Pp.(str "Undeclared global universe: " ++ Libnames.pr_reference r))
- in
- let level = Univ.Level.make dp num in
- let evd =
- try Evd.add_global_univ evd level
- with UGraph.AlreadyDeclared -> evd
- in evd, level
- | {CAst.loc; v=Libnames.Ident id} -> (* Undeclared *)
- if not (is_strict_universe_declarations ()) then
- new_univ_level_variable ?loc ~name:id univ_rigid evd
- else user_err ?loc ~hdr:"interp_universe_level_name"
- (Pp.(str "Undeclared universe: " ++ Id.print id))
+ if Libnames.qualid_is_ident qid then (* Undeclared *)
+ let id = Libnames.qualid_basename qid in
+ if not (is_strict_universe_declarations ()) then
+ new_univ_level_variable ?loc:qid.CAst.loc ~name:id univ_rigid evd
+ else user_err ?loc:qid.CAst.loc ~hdr:"interp_universe_level_name"
+ (Pp.(str "Undeclared universe: " ++ Id.print id))
+ else
+ let dp, i = Libnames.repr_qualid qid in
+ let num =
+ try int_of_string (Id.to_string i)
+ with Failure _ ->
+ user_err ?loc:qid.CAst.loc ~hdr:"interp_universe_level_name"
+ (Pp.(str "Undeclared global universe: " ++ Libnames.pr_qualid qid))
+ in
+ let level = Univ.Level.make dp num in
+ let evd =
+ try Evd.add_global_univ evd level
+ with UGraph.AlreadyDeclared -> evd
+ in evd, level
let interp_universe ?loc evd = function
| [] -> let evd, l = new_univ_level_variable ?loc univ_rigid evd in
@@ -240,12 +231,12 @@ let interp_known_level_info ?loc evd = function
| UUnknown | UAnonymous ->
user_err ?loc ~hdr:"interp_known_level_info"
(str "Anonymous universes not allowed here.")
- | UNamed ref ->
- try interp_known_universe_level evd ref
+ | UNamed qid ->
+ try interp_known_universe_level evd qid
with Not_found ->
- user_err ?loc ~hdr:"interp_known_level_info" (str "Undeclared universe " ++ Libnames.pr_reference ref)
+ user_err ?loc ~hdr:"interp_known_level_info" (str "Undeclared universe " ++ Libnames.pr_qualid qid)
-let interp_level_info ?loc evd : Misctypes.level_info -> _ = function
+let interp_level_info ?loc evd : level_info -> _ = function
| UUnknown -> new_univ_level_variable ?loc univ_rigid evd
| UAnonymous -> new_univ_level_variable ?loc univ_flexible evd
| UNamed s -> interp_universe_level_name ~anon_rigidity:univ_flexible evd s
@@ -315,7 +306,7 @@ let apply_inference_hook hook evdref frozen = match frozen with
then
try
let sigma, c = hook sigma evk in
- Evd.define evk (EConstr.Unsafe.to_constr c) sigma
+ Evd.define evk c sigma
with Exit ->
sigma
else
@@ -390,8 +381,16 @@ let adjust_evar_source evdref na c =
| Name id, Evar (evk,args) ->
let evi = Evd.find !evdref evk in
begin match evi.evar_source with
- | loc, Evar_kinds.QuestionMark (b,Anonymous) ->
- let src = (loc,Evar_kinds.QuestionMark (b,na)) in
+ | loc, Evar_kinds.QuestionMark {
+ Evar_kinds.qm_obligation=b;
+ Evar_kinds.qm_name=Anonymous;
+ Evar_kinds.qm_record_field=recfieldname;
+ } ->
+ let src = (loc,Evar_kinds.QuestionMark {
+ Evar_kinds.qm_obligation=b;
+ Evar_kinds.qm_name=na;
+ Evar_kinds.qm_record_field=recfieldname;
+ }) in
let (evd, evk') = restrict_evar !evdref evk (evar_filter evi) ~src None in
evdref := evd;
mkEvar (evk',args)
@@ -429,7 +428,7 @@ let ltac_interp_name_env k0 lvar env sigma =
let n = Context.Rel.length (rel_context env) - k0 in
let ctxt,_ = List.chop n (rel_context env) in
let open Context.Rel.Declaration in
- let ctxt' = List.smartmap (map_name (ltac_interp_name lvar)) ctxt in
+ let ctxt' = List.Smart.map (map_name (ltac_interp_name lvar)) ctxt in
if List.equal (fun d1 d2 -> Name.equal (get_name d1) (get_name d2)) ctxt ctxt' then env
else push_rel_context sigma ctxt' (pop_rel_context n env sigma)
@@ -445,7 +444,7 @@ let protected_get_type_of env sigma c =
try Retyping.get_type_of ~lax:true env.ExtraEnv.env sigma c
with Retyping.RetypeError _ ->
user_err
- (str "Cannot reinterpret " ++ quote (print_constr c) ++
+ (str "Cannot reinterpret " ++ quote (Termops.Internal.print_constr_env env.ExtraEnv.env sigma c) ++
str " in the current environment.")
let pretype_id pretype k0 loc env evdref lvar id =
@@ -499,7 +498,7 @@ let interp_known_glob_level ?loc evd = function
| GSet -> Univ.Level.set
| GType s -> interp_known_level_info ?loc evd s
-let interp_glob_level ?loc evd : Misctypes.glob_level -> _ = function
+let interp_glob_level ?loc evd : glob_level -> _ = function
| GProp -> evd, Univ.Level.prop
| GSet -> evd, Univ.Level.set
| GType s -> interp_level_info ?loc evd s
@@ -532,7 +531,7 @@ let pretype_global ?loc rigid env evd gr us =
interp_instance ?loc evd ~len l
in
let (sigma, c) = Evd.fresh_global ?loc ~rigid ?names:instance env.ExtraEnv.env evd gr in
- (sigma, EConstr.of_constr c)
+ (sigma, c)
let pretype_ref ?loc evdref env ref us =
match ref with
@@ -674,14 +673,18 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
let ftys = Array.map2 (fun e a -> it_mkProd_or_LetIn a e) ctxtv lara in
let nbfix = Array.length lar in
let names = Array.map (fun id -> Name id) names in
- let _ =
+ let () =
match tycon with
| Some t ->
let fixi = match fixkind with
| GFix (vn,i) -> i
| GCoFix i -> i
- in e_conv env.ExtraEnv.env evdref ftys.(fixi) t
- | None -> true
+ in
+ begin match conv env.ExtraEnv.env !evdref ftys.(fixi) t with
+ | None -> ()
+ | Some sigma -> evdref := sigma
+ end
+ | None -> ()
in
(* Note: bodies are not used by push_rec_types, so [||] is safe *)
let newenv = push_rec_types !evdref (names,ftys,[||]) env in
@@ -698,7 +701,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
{ uj_val = it_mkLambda_or_LetIn j.uj_val ctxt;
uj_type = it_mkProd_or_LetIn j.uj_type ctxt })
ctxtv vdef in
- Typing.check_type_fixpoint ?loc env.ExtraEnv.env evdref names ftys vdefj;
+ evdref := Typing.check_type_fixpoint ?loc env.ExtraEnv.env !evdref names ftys vdefj;
let nf c = nf_evar !evdref c in
let ftys = Array.map nf ftys in (** FIXME *)
let fdefs = Array.map (fun x -> nf (j_val x)) vdefj in
@@ -765,11 +768,11 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
in
let app_f =
match EConstr.kind !evdref fj.uj_val with
- | Const (p, u) when Environ.is_projection p env.ExtraEnv.env ->
+ | Const (p, u) when Recordops.is_primitive_projection p ->
+ let p = Option.get @@ Recordops.find_primitive_projection p in
let p = Projection.make p false in
- let pb = Environ.lookup_projection p env.ExtraEnv.env in
- let npars = pb.Declarations.proj_npars in
- fun n ->
+ let npars = Projection.npars p in
+ fun n ->
if n == npars + 1 then fun _ v -> mkProj (p, v)
else fun f v -> applist (f, [v])
| _ -> fun _ f v -> applist (f, [v])
@@ -788,9 +791,12 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
match candargs with
| [] -> [], j_val hj
| arg :: args ->
- if e_conv env.ExtraEnv.env evdref (j_val hj) arg then
- args, nf_evar !evdref (j_val hj)
- else [], j_val hj
+ begin match conv env.ExtraEnv.env !evdref (j_val hj) arg with
+ | Some sigma -> evdref := sigma;
+ args, nf_evar !evdref (j_val hj)
+ | None ->
+ [], j_val hj
+ end
in
let ujval = adjust_evar_source evdref na ujval in
let value, typ = app_f n (j_val resj) ujval, subst1 ujval c2 in
@@ -894,6 +900,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
let cloc = loc_of_glob_constr c in
error_case_not_inductive ?loc:cloc env.ExtraEnv.env !evdref cj
in
+ let ind = fst (fst (dest_ind_family indf)) in
let cstrs = get_constructors env.ExtraEnv.env indf in
if not (Int.equal (Array.length cstrs) 1) then
user_err ?loc (str "Destructing let is only for inductive types" ++
@@ -904,7 +911,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
int cs.cs_nargs ++ str " variables.");
let fsign, record =
let set_name na d = set_name na (map_rel_decl EConstr.of_constr d) in
- match get_projections env.ExtraEnv.env indf with
+ match Environ.get_projections env.ExtraEnv.env ind with
| None ->
List.map2 set_name (List.rev nal) cs.cs_args, false
| Some ps ->
@@ -920,9 +927,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
| [], [] -> []
| _ -> assert false
in aux 1 1 (List.rev nal) cs.cs_args, true in
- let fsign = if Flags.version_strictly_greater Flags.V8_6
- then Context.Rel.map (whd_betaiota !evdref) fsign
- else fsign (* beta-iota-normalization regression in 8.5 and 8.6 *) in
+ let fsign = Context.Rel.map (whd_betaiota !evdref) fsign in
let obj ind p v f =
if not record then
let nal = List.map (fun na -> ltac_interp_name lvar na) nal in
@@ -1032,10 +1037,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
let pi = lift n pred in (* liftn n 2 pred ? *)
let pi = beta_applist !evdref (pi, [EConstr.of_constr (build_dependent_constructor cs)]) in
let cs_args = List.map (fun d -> map_rel_decl EConstr.of_constr d) cs.cs_args in
- let cs_args =
- if Flags.version_strictly_greater Flags.V8_6
- then Context.Rel.map (whd_betaiota !evdref) cs_args
- else cs_args (* beta-iota-normalization regression in 8.5 and 8.6 *) in
+ let cs_args = Context.Rel.map (whd_betaiota !evdref) cs_args in
let csgn =
List.map (set_name Anonymous) cs_args
in
@@ -1077,9 +1079,9 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
let cj = pretype empty_tycon env evdref lvar c in
let cty = nf_evar !evdref cj.uj_type and tval = nf_evar !evdref tval in
if not (occur_existential !evdref cty || occur_existential !evdref tval) then
- let (evd,b) = Reductionops.vm_infer_conv env.ExtraEnv.env !evdref cty tval in
- if b then (evdref := evd; cj, tval)
- else
+ match Reductionops.vm_infer_conv env.ExtraEnv.env !evdref cty tval with
+ | Some evd -> (evdref := evd; cj, tval)
+ | None ->
error_actual_type ?loc env.ExtraEnv.env !evdref cj tval
(ConversionFailed (env.ExtraEnv.env,cty,tval))
else user_err ?loc (str "Cannot check cast with vm: " ++
@@ -1088,9 +1090,9 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
let cj = pretype empty_tycon env evdref lvar c in
let cty = nf_evar !evdref cj.uj_type and tval = nf_evar !evdref tval in
begin
- let (evd,b) = Nativenorm.native_infer_conv env.ExtraEnv.env !evdref cty tval in
- if b then (evdref := evd; cj, tval)
- else
+ match Nativenorm.native_infer_conv env.ExtraEnv.env !evdref cty tval with
+ | Some evd -> (evdref := evd; cj, tval)
+ | None ->
error_actual_type ?loc env.ExtraEnv.env !evdref cj tval
(ConversionFailed (env.ExtraEnv.env,cty,tval))
end
@@ -1104,7 +1106,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
and pretype_instance k0 resolve_tc env evdref lvar loc hyps evk update =
let f decl (subst,update) =
let id = NamedDecl.get_id decl in
- let t = replace_vars subst (EConstr.of_constr (NamedDecl.get_type decl)) in
+ let t = replace_vars subst (NamedDecl.get_type decl) in
let c, update =
try
let c = List.assoc id update in
@@ -1145,7 +1147,7 @@ and pretype_type k0 resolve_tc valcon (env : ExtraEnv.t) evdref lvar c = match D
(* Correction of bug #5315 : we need to define an evar for *all* holes *)
let evkt = e_new_evar env evdref ~src:(loc, knd) ~naming (mkSort s) in
let ev,_ = destEvar !evdref evkt in
- evdref := Evd.define ev (to_constr !evdref v) !evdref;
+ evdref := Evd.define ev (nf_evar !evdref v) !evdref;
(* End of correction of bug #5315 *)
{ utj_val = v;
utj_type = s }
@@ -1161,10 +1163,12 @@ and pretype_type k0 resolve_tc valcon (env : ExtraEnv.t) evdref lvar c = match D
match valcon with
| None -> tj
| Some v ->
- if e_cumul env.ExtraEnv.env evdref v tj.utj_val then tj
- else
+ begin match cumul env.ExtraEnv.env !evdref v tj.utj_val with
+ | Some sigma -> evdref := sigma; tj
+ | None ->
error_unexpected_type
?loc:(loc_of_glob_constr c) env.ExtraEnv.env !evdref tj.utj_val v
+ end
let ise_pretype_gen flags env sigma lvar kind c =
let env = make_env env sigma in
diff --git a/pretyping/pretyping.mli b/pretyping/pretyping.mli
index 415c4e17..73f5b77e 100644
--- a/pretyping/pretyping.mli
+++ b/pretyping/pretyping.mli
@@ -22,7 +22,7 @@ open Ltac_pretype
open Evardefine
val interp_known_glob_level : ?loc:Loc.t -> Evd.evar_map ->
- Misctypes.glob_level -> Univ.Level.t
+ glob_level -> Univ.Level.t
(** An auxiliary function for searching for fixpoint guard indexes *)
diff --git a/pretyping/pretyping.mllib b/pretyping/pretyping.mllib
index ae4ad0be..5da5aff4 100644
--- a/pretyping/pretyping.mllib
+++ b/pretyping/pretyping.mllib
@@ -1,5 +1,5 @@
Geninterp
-Ltac_pretype
+Locus
Locusops
Pretype_errors
Reductionops
@@ -14,11 +14,14 @@ Find_subterm
Evardefine
Evarsolve
Recordops
+Heads
Evarconv
Typing
Miscops
+Glob_term
+Ltac_pretype
Glob_ops
-Redops
+Pattern
Patternops
Constr_matching
Tacred
@@ -32,4 +35,3 @@ Indrec
Cases
Pretyping
Unification
-Univdecls
diff --git a/pretyping/program.ml b/pretyping/program.ml
index 52d940d8..8cfb7966 100644
--- a/pretyping/program.ml
+++ b/pretyping/program.ml
@@ -16,7 +16,9 @@ let init_reference dir s () = Coqlib.coq_reference "Program" dir s
let papp evdref r args =
let open EConstr in
let gr = delayed_force r in
- mkApp (Evarutil.e_new_global evdref gr, args)
+ let evd, hd = Evarutil.new_global !evdref gr in
+ evdref := evd;
+ mkApp (hd, args)
let sig_typ = init_reference ["Init"; "Specif"] "sig"
let sig_intro = init_reference ["Init"; "Specif"] "exist"
diff --git a/pretyping/program.mli b/pretyping/program.mli
index df0848ba..a8f51157 100644
--- a/pretyping/program.mli
+++ b/pretyping/program.mli
@@ -8,37 +8,37 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+open Names
open EConstr
-open Globnames
(** A bunch of Coq constants used by Progam *)
-val sig_typ : unit -> global_reference
-val sig_intro : unit -> global_reference
-val sig_proj1 : unit -> global_reference
-val sigT_typ : unit -> global_reference
-val sigT_intro : unit -> global_reference
-val sigT_proj1 : unit -> global_reference
-val sigT_proj2 : unit -> global_reference
+val sig_typ : unit -> GlobRef.t
+val sig_intro : unit -> GlobRef.t
+val sig_proj1 : unit -> GlobRef.t
+val sigT_typ : unit -> GlobRef.t
+val sigT_intro : unit -> GlobRef.t
+val sigT_proj1 : unit -> GlobRef.t
+val sigT_proj2 : unit -> GlobRef.t
-val prod_typ : unit -> global_reference
-val prod_intro : unit -> global_reference
-val prod_proj1 : unit -> global_reference
-val prod_proj2 : unit -> global_reference
+val prod_typ : unit -> GlobRef.t
+val prod_intro : unit -> GlobRef.t
+val prod_proj1 : unit -> GlobRef.t
+val prod_proj2 : unit -> GlobRef.t
-val coq_eq_ind : unit -> global_reference
-val coq_eq_refl : unit -> global_reference
-val coq_eq_refl_ref : unit -> global_reference
-val coq_eq_rect : unit -> global_reference
+val coq_eq_ind : unit -> GlobRef.t
+val coq_eq_refl : unit -> GlobRef.t
+val coq_eq_refl_ref : unit -> GlobRef.t
+val coq_eq_rect : unit -> GlobRef.t
-val coq_JMeq_ind : unit -> global_reference
-val coq_JMeq_refl : unit -> global_reference
+val coq_JMeq_ind : unit -> GlobRef.t
+val coq_JMeq_refl : unit -> GlobRef.t
val mk_coq_and : Evd.evar_map -> constr list -> Evd.evar_map * constr
val mk_coq_not : Evd.evar_map -> constr -> Evd.evar_map * constr
(** Polymorphic application of delayed references *)
-val papp : Evd.evar_map ref -> (unit -> global_reference) -> constr array -> constr
+val papp : Evd.evar_map ref -> (unit -> GlobRef.t) -> constr array -> constr
val get_proofs_transparency : unit -> bool
val is_program_cases : unit -> bool
diff --git a/pretyping/recordops.ml b/pretyping/recordops.ml
index d070edea..aedef40e 100644
--- a/pretyping/recordops.ml
+++ b/pretyping/recordops.ml
@@ -44,7 +44,7 @@ type struc_typ = {
let structure_table =
Summary.ref (Indmap.empty : struc_typ Indmap.t) ~name:"record-structs"
let projection_table =
- Summary.ref Cmap.empty ~name:"record-projs"
+ Summary.ref (Cmap.empty : struc_typ Cmap.t) ~name:"record-projs"
(* TODO: could be unify struc_typ and struc_tuple ? in particular,
is the inductive always (fst constructor) ? It seems so... *)
@@ -53,7 +53,9 @@ type struc_tuple =
inductive * constructor * (Name.t * bool) list * Constant.t option list
let load_structure i (_,(ind,id,kl,projs)) =
- let n = (fst (Global.lookup_inductive ind)).Declarations.mind_nparams in
+ let open Declarations in
+ let mib, mip = Global.lookup_inductive ind in
+ let n = mib.mind_nparams in
let struc =
{ s_CONST = id; s_EXPECTEDPARAM = n; s_PROJ = projs; s_PROJKIND = kl } in
structure_table := Indmap.add ind struc !structure_table;
@@ -69,8 +71,8 @@ let subst_structure (subst,((kn,i),id,kl,projs as obj)) =
let projs' =
(* invariant: struc.s_PROJ is an evaluable reference. Thus we can take *)
(* the first component of subst_con. *)
- List.smartmap
- (Option.smartmap (fun kn -> fst (subst_con_kn subst kn)))
+ List.Smart.map
+ (Option.Smart.map (fun kn -> fst (subst_con_kn subst kn)))
projs
in
let id' = fst (subst_constructor subst id) in
@@ -107,6 +109,34 @@ let find_projection = function
| ConstRef cst -> Cmap.find cst !projection_table
| _ -> raise Not_found
+let prim_table =
+ Summary.ref (Cmap_env.empty : Projection.Repr.t Cmap_env.t) ~name:"record-prim-projs"
+
+let load_prim i (_,p) =
+ prim_table := Cmap_env.add (Projection.Repr.constant p) p !prim_table
+
+let cache_prim p = load_prim 1 p
+
+let subst_prim (subst,p) = subst_proj_repr subst p
+
+let discharge_prim (_,p) = Some (Lib.discharge_proj_repr p)
+
+let inPrim : Projection.Repr.t -> obj =
+ declare_object {
+ (default_object "PRIMPROJS") with
+ cache_function = cache_prim ;
+ load_function = load_prim;
+ subst_function = subst_prim;
+ classify_function = (fun x -> Substitute x);
+ discharge_function = discharge_prim }
+
+let declare_primitive_projection p = Lib.add_anonymous_leaf (inPrim p)
+
+let is_primitive_projection c = Cmap_env.mem c !prim_table
+
+let find_primitive_projection c =
+ try Some (Cmap_env.find c !prim_table) with Not_found -> None
+
(************************************************************************)
(*s A canonical structure declares "canonical" conversion hints between *)
(* the effective components of a structure and the projections of the *)
@@ -144,13 +174,13 @@ type obj_typ = {
o_TCOMPS : constr list } (* ordered *)
type cs_pattern =
- Const_cs of global_reference
+ Const_cs of GlobRef.t
| Prod_cs
| Sort_cs of Sorts.family
| Default_cs
let eq_cs_pattern p1 p2 = match p1, p2 with
-| Const_cs gr1, Const_cs gr2 -> eq_gr gr1 gr2
+| Const_cs gr1, Const_cs gr2 -> GlobRef.equal gr1 gr2
| Prod_cs, Prod_cs -> true
| Sort_cs s1, Sort_cs s2 -> Sorts.family_equal s1 s2
| Default_cs, Default_cs -> true
@@ -199,7 +229,7 @@ let warn_projection_no_head_constant =
let env = Termops.push_rels_assum sign env in
let con_pp = Nametab.pr_global_env Id.Set.empty (ConstRef con) in
let proji_sp_pp = Nametab.pr_global_env Id.Set.empty (ConstRef proji_sp) in
- let term_pp = Termops.print_constr_env env Evd.empty (EConstr.of_constr t) in
+ let term_pp = Termops.Internal.print_constr_env env (Evd.from_env env) (EConstr.of_constr t) in
strbrk "Projection value has no head constant: "
++ term_pp ++ strbrk " in canonical instance "
++ con_pp ++ str " of " ++ proji_sp_pp ++ strbrk ", ignoring it.")
@@ -211,7 +241,7 @@ let compute_canonical_projections warn (con,ind) =
let u = Univ.make_abstract_instance ctx in
let v = (mkConstU (con,u)) in
let c = Environ.constant_value_in env (con,u) in
- let sign,t = Reductionops.splay_lam env Evd.empty (EConstr.of_constr c) in
+ let sign,t = Reductionops.splay_lam env (Evd.from_env env) (EConstr.of_constr c) in
let sign = List.map (on_snd EConstr.Unsafe.to_constr) sign in
let t = EConstr.Unsafe.to_constr t in
let lt = List.rev_map snd sign in
@@ -265,8 +295,12 @@ let add_canonical_structure warn o =
in match ocs with
| None -> object_table := Refmap.add proj ((pat,s)::l) !object_table;
| Some (c, cs) ->
- let old_can_s = (Termops.print_constr (EConstr.of_constr cs.o_DEF))
- and new_can_s = (Termops.print_constr (EConstr.of_constr s.o_DEF)) in
+ (* XXX: Undesired global access to env *)
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ let old_can_s = (Termops.Internal.print_constr_env env sigma (EConstr.of_constr cs.o_DEF))
+ and new_can_s = (Termops.Internal.print_constr_env env sigma (EConstr.of_constr s.o_DEF))
+ in
let prj = (Nametab.pr_global_env Id.Set.empty proj)
and hd_val = (pr_cs_pattern cs_pat) in
if warn then warn_redundant_canonical_projection (hd_val,prj,new_can_s,old_can_s))
@@ -304,36 +338,38 @@ let error_not_structure ref description =
user_err ~hdr:"object_declare"
(str"Could not declare a canonical structure " ++
(Id.print (basename_of_global ref) ++ str"." ++ spc() ++
- str(description)))
+ description))
let check_and_decompose_canonical_structure ref =
let sp =
match ref with
ConstRef sp -> sp
- | _ -> error_not_structure ref "Expected an instance of a record or structure."
+ | _ -> error_not_structure ref (str "Expected an instance of a record or structure.")
in
let env = Global.env () in
let u = Univ.make_abstract_instance (Environ.constant_context env sp) in
let vc = match Environ.constant_opt_value_in env (sp, u) with
| Some vc -> vc
- | None -> error_not_structure ref "Could not find its value in the global environment." in
- let body = snd (splay_lam (Global.env()) Evd.empty (EConstr.of_constr vc)) (** FIXME *) in
+ | None -> error_not_structure ref (str "Could not find its value in the global environment.") in
+ let env = Global.env () in
+ let evd = Evd.from_env env in
+ let body = snd (splay_lam (Global.env()) evd (EConstr.of_constr vc)) in
let body = EConstr.Unsafe.to_constr body in
let f,args = match kind body with
| App (f,args) -> f,args
| _ ->
- error_not_structure ref "Expected a record or structure constructor applied to arguments." in
+ error_not_structure ref (str "Expected a record or structure constructor applied to arguments.") in
let indsp = match kind f with
| Construct ((indsp,1),u) -> indsp
- | _ -> error_not_structure ref "Expected an instance of a record or structure." in
+ | _ -> error_not_structure ref (str "Expected an instance of a record or structure.") in
let s =
try lookup_structure indsp
with Not_found ->
error_not_structure ref
- ("Could not find the record or structure " ^ (MutInd.to_string (fst indsp))) in
+ (str "Could not find the record or structure " ++ Termops.Internal.print_constr_env env evd (EConstr.mkInd indsp)) in
let ntrue_projs = List.count snd s.s_PROJKIND in
if s.s_EXPECTEDPARAM + ntrue_projs > Array.length args then
- error_not_structure ref "Got too few arguments to the record or structure constructor.";
+ error_not_structure ref (str "Got too few arguments to the record or structure constructor.");
(sp,indsp)
let declare_canonical_structure ref =
diff --git a/pretyping/recordops.mli b/pretyping/recordops.mli
index 1f7b23c0..415b9641 100644
--- a/pretyping/recordops.mli
+++ b/pretyping/recordops.mli
@@ -10,7 +10,6 @@
open Names
open Constr
-open Globnames
(** Operations concerning records and canonical structures *)
@@ -40,10 +39,17 @@ val lookup_structure : inductive -> struc_typ
val lookup_projections : inductive -> Constant.t option list
(** raise [Not_found] if not a projection *)
-val find_projection_nparams : global_reference -> int
+val find_projection_nparams : GlobRef.t -> int
(** raise [Not_found] if not a projection *)
-val find_projection : global_reference -> struc_typ
+val find_projection : GlobRef.t -> struc_typ
+
+(** Sets up the mapping from constants to primitive projections *)
+val declare_primitive_projection : Projection.Repr.t -> unit
+
+val is_primitive_projection : Constant.t -> bool
+
+val find_primitive_projection : Constant.t -> Projection.Repr.t option
(** {6 Canonical structures } *)
(** A canonical structure declares "canonical" conversion hints between
@@ -52,7 +58,7 @@ val find_projection : global_reference -> struc_typ
(** A cs_pattern characterizes the form of a component of canonical structure *)
type cs_pattern =
- Const_cs of global_reference
+ Const_cs of GlobRef.t
| Prod_cs
| Sort_cs of Sorts.family
| Default_cs
@@ -71,9 +77,9 @@ val cs_pattern_of_constr : Environ.env -> constr -> cs_pattern * int option * co
val pr_cs_pattern : cs_pattern -> Pp.t
-val lookup_canonical_conversion : (global_reference * cs_pattern) -> constr * obj_typ
-val declare_canonical_structure : global_reference -> unit
+val lookup_canonical_conversion : (GlobRef.t * cs_pattern) -> constr * obj_typ
+val declare_canonical_structure : GlobRef.t -> unit
val is_open_canonical_projection :
Environ.env -> Evd.evar_map -> Reductionops.state -> bool
val canonical_projections : unit ->
- ((global_reference * cs_pattern) * obj_typ) list
+ ((GlobRef.t * cs_pattern) * obj_typ) list
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml
index 360c6e86..fb2be89e 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -47,29 +47,28 @@ open Libobject
type effect_name = string
(** create a persistent set to store effect functions *)
-module ConstrMap = Map.Make (Constr)
(* Table bindings a constant to an effect *)
-let constant_effect_table = Summary.ref ~name:"reduction-side-effect" ConstrMap.empty
+let constant_effect_table = Summary.ref ~name:"reduction-side-effect" Cmap.empty
(* Table bindings function key to effective functions *)
let effect_table = Summary.ref ~name:"reduction-function-effect" String.Map.empty
(** a test to know whether a constant is actually the effect function *)
-let reduction_effect_hook env sigma termkey c =
+let reduction_effect_hook env sigma con c =
try
- let funkey = ConstrMap.find termkey !constant_effect_table in
+ let funkey = Cmap.find con !constant_effect_table in
let effect = String.Map.find funkey !effect_table in
effect env sigma (Lazy.force c)
with Not_found -> ()
-let cache_reduction_effect (_,(termkey,funkey)) =
- constant_effect_table := ConstrMap.add termkey funkey !constant_effect_table
+let cache_reduction_effect (_,(con,funkey)) =
+ constant_effect_table := Cmap.add con funkey !constant_effect_table
-let subst_reduction_effect (subst,(termkey,funkey)) =
- (subst_mps subst termkey,funkey)
+let subst_reduction_effect (subst,(con,funkey)) =
+ (subst_constant subst con,funkey)
-let inReductionEffect : Constr.constr * string -> obj =
+let inReductionEffect : Constant.t * string -> obj =
declare_object {(default_object "REDUCTION-EFFECT") with
cache_function = cache_reduction_effect;
open_function = (fun i o -> if Int.equal i 1 then cache_reduction_effect o);
@@ -83,8 +82,7 @@ let declare_reduction_effect funkey f =
(** A function to set the value of the print function *)
let set_reduction_effect x funkey =
- let termkey = Universes.constr_of_global x in
- Lib.add_anonymous_leaf (inReductionEffect (termkey,funkey))
+ Lib.add_anonymous_leaf (inReductionEffect (x,funkey))
(** Machinery to custom the behavior of the reduction *)
@@ -104,7 +102,7 @@ module ReductionBehaviour = struct
type flag = [ `ReductionDontExposeCase | `ReductionNeverUnfold ]
type req =
| ReqLocal
- | ReqGlobal of global_reference * (int list * int * flag list)
+ | ReqGlobal of GlobRef.t * (int list * int * flag list)
let load _ (_,(_,(r, b))) =
table := Refmap.add r b !table
@@ -255,9 +253,9 @@ module Cst_stack = struct
(applist (cst, List.rev params))
t) cst_l c
- let pr l =
+ let pr env sigma l =
let open Pp in
- let p_c c = Termops.print_constr c in
+ let p_c c = Termops.Internal.print_constr_env env sigma c in
prlist_with_sep pr_semicolon
(fun (c,params,args) ->
hov 1 (str"(" ++ p_c c ++ str ")" ++ spc () ++ pr_sequence p_c params ++ spc () ++ str "(args:" ++
@@ -280,7 +278,7 @@ sig
type 'a member =
| App of 'a app_node
| Case of case_info * 'a * 'a array * Cst_stack.t
- | Proj of int * int * Projection.t * Cst_stack.t
+ | Proj of Projection.t * Cst_stack.t
| Fix of ('a, 'a) pfixpoint * 'a t * Cst_stack.t
| Cst of cst_member * int * int list * 'a t * Cst_stack.t
and 'a t = 'a member list
@@ -337,11 +335,12 @@ struct
type 'a member =
| App of 'a app_node
| Case of case_info * 'a * 'a array * Cst_stack.t
- | Proj of int * int * Projection.t * Cst_stack.t
+ | Proj of Projection.t * Cst_stack.t
| Fix of ('a, 'a) pfixpoint * 'a t * Cst_stack.t
| Cst of cst_member * int * int list * 'a t * Cst_stack.t
and 'a t = 'a member list
+ (* Debugging printer *)
let rec pr_member pr_c member =
let open Pp in
let pr_c x = hov 1 (pr_c x) in
@@ -351,9 +350,8 @@ struct
str "ZCase(" ++
prvect_with_sep (pr_bar) pr_c br
++ str ")"
- | Proj (n,m,p,cst) ->
- str "ZProj(" ++ int n ++ pr_comma () ++ int m ++
- pr_comma () ++ Constant.print (Projection.constant p) ++ str ")"
+ | Proj (p,cst) ->
+ str "ZProj(" ++ Constant.debug_print (Projection.constant p) ++ str ")"
| Fix (f,args,cst) ->
str "ZFix(" ++ Termops.pr_fix pr_c f
++ pr_comma () ++ pr pr_c args ++ str ")"
@@ -370,11 +368,11 @@ struct
let open Pp in
match c with
| Cst_const (c, u) ->
- if Univ.Instance.is_empty u then Constant.print c
- else str"(" ++ Constant.print c ++ str ", " ++
+ if Univ.Instance.is_empty u then Constant.debug_print c
+ else str"(" ++ Constant.debug_print c ++ str ", " ++
Univ.Instance.pr Univ.Level.pr u ++ str")"
| Cst_proj p ->
- str".(" ++ Constant.print (Projection.constant p) ++ str")"
+ str".(" ++ Constant.debug_print (Projection.constant p) ++ str")"
let empty = []
let is_empty = CList.is_empty
@@ -413,10 +411,9 @@ struct
(f t1 t2) && (equal_rec s1' s2')
| Case (_,t1,a1,_) :: s1, Case (_,t2,a2,_) :: s2 ->
f t1 t2 && CArray.equal (fun x y -> f x y) a1 a2 && equal_rec s1 s2
- | (Proj (n1,m1,p,_)::s1, Proj(n2,m2,p2,_)::s2) ->
- Int.equal n1 n2 && Int.equal m1 m2
- && Constant.equal (Projection.constant p) (Projection.constant p2)
- && equal_rec s1 s2
+ | (Proj (p,_)::s1, Proj(p2,_)::s2) ->
+ Projection.Repr.equal (Projection.repr p) (Projection.repr p2)
+ && equal_rec s1 s2
| Fix (f1,s1,_) :: s1', Fix (f2,s2,_) :: s2' ->
f_fix f1 f2
&& equal_rec (List.rev s1) (List.rev s2)
@@ -436,7 +433,7 @@ struct
| (_, App (i,_,j)::s2) -> compare_rec (bal - j - 1 + i) stk1 s2
| (Case(c1,_,_,_)::s1, Case(c2,_,_,_)::s2) ->
Int.equal bal 0 (* && c1.ci_ind = c2.ci_ind *) && compare_rec 0 s1 s2
- | (Proj (n1,m1,p,_)::s1, Proj(n2,m2,p2,_)::s2) ->
+ | (Proj (p,_)::s1, Proj(p2,_)::s2) ->
Int.equal bal 0 && compare_rec 0 s1 s2
| (Fix(_,a1,_)::s1, Fix(_,a2,_)::s2) ->
Int.equal bal 0 && compare_rec 0 a1 a2 && compare_rec 0 s1 s2
@@ -456,7 +453,7 @@ struct
aux (f o t1 t2) l1 l2
| Case (_,t1,a1,_) :: q1, Case (_,t2,a2,_) :: q2 ->
aux (Array.fold_left2 f (f o t1 t2) a1 a2) q1 q2
- | Proj (n1,m1,p1,_) :: q1, Proj (n2,m2,p2,_) :: q2 ->
+ | Proj (p1,_) :: q1, Proj (p2,_) :: q2 ->
aux o q1 q2
| Fix ((_,(_,a1,b1)),s1,_) :: q1, Fix ((_,(_,a2,b2)),s2,_) :: q2 ->
let o' = aux (Array.fold_left2 f (Array.fold_left2 f o b1 b2) a1 a2) (List.rev s1) (List.rev s2) in
@@ -469,7 +466,7 @@ struct
in aux o (List.rev sk1) (List.rev sk2)
let rec map f x = List.map (function
- | (Proj (_,_,_,_)) as e -> e
+ | (Proj (_,_)) as e -> e
| App (i,a,j) ->
let le = j - i + 1 in
App (0,Array.map f (Array.sub a i le), le-1)
@@ -513,7 +510,7 @@ struct
let will_expose_iota args =
List.exists
(function (Fix (_,_,l) | Case (_,_,_,l) |
- Proj (_,_,_,l) | Cst (_,_,_,_,l)) when Cst_stack.is_empty l -> true | _ -> false)
+ Proj (_,l) | Cst (_,_,_,_,l)) when Cst_stack.is_empty l -> true | _ -> false)
args
let list_of_app_stack s =
@@ -590,9 +587,9 @@ struct
zip (best_state sigma (constr_of_cst_member cst (params @ (append_app [|f|] s))) cst_l)
| f, (Cst (cst,_,_,params,_)::s) ->
zip (constr_of_cst_member cst (params @ (append_app [|f|] s)))
- | f, (Proj (n,m,p,cst_l)::s) when refold ->
+ | f, (Proj (p,cst_l)::s) when refold ->
zip (best_state sigma (mkProj (p,f),s) cst_l)
- | f, (Proj (n,m,p,_)::s) -> zip (mkProj (p,f),s)
+ | f, (Proj (p,_)::s) -> zip (mkProj (p,f),s)
in
zip s
@@ -617,9 +614,9 @@ type contextual_state_reduction_function =
type state_reduction_function = contextual_state_reduction_function
type local_state_reduction_function = evar_map -> state -> state
-let pr_state (tm,sk) =
+let pr_state env sigma (tm,sk) =
let open Pp in
- let pr c = Termops.print_constr c in
+ let pr c = Termops.Internal.print_constr_env env sigma c in
h 0 (pr tm ++ str "|" ++ cut () ++ Stack.pr pr sk)
(*************************************)
@@ -632,6 +629,18 @@ let safe_meta_value sigma ev =
try Some (Evd.meta_value sigma ev)
with Not_found -> None
+let strong_with_flags whdfun flags env sigma t =
+ let push_rel_check_zeta d env =
+ let open CClosure.RedFlags in
+ let d = match d with
+ | LocalDef (na,c,t) when not (red_set flags fZETA) -> LocalAssum (na,t)
+ | d -> d in
+ push_rel d env in
+ let rec strongrec env t =
+ map_constr_with_full_binders sigma
+ push_rel_check_zeta strongrec env (whdfun flags env sigma t) in
+ strongrec env t
+
let strong whdfun env sigma t =
let rec strongrec env t =
map_constr_with_full_binders sigma push_rel strongrec env (whdfun env sigma t) in
@@ -701,18 +710,18 @@ let reducible_mind_case sigma c = match EConstr.kind sigma c with
let magicaly_constant_of_fixbody env sigma reference bd = function
| Name.Anonymous -> bd
| Name.Name id ->
- let open Universes in
+ let open UnivProblem in
try
let (cst_mod,cst_sect,_) = Constant.repr3 reference in
let cst = Constant.make3 cst_mod cst_sect (Label.of_id id) in
- let (cst, u), ctx = fresh_constant_instance env cst in
+ let (cst, u), ctx = UnivGen.fresh_constant_instance env cst in
match constant_opt_value_in env (cst,u) with
| None -> bd
| Some t ->
let csts = EConstr.eq_constr_universes env sigma (EConstr.of_constr t) bd in
begin match csts with
| Some csts ->
- let subst = Constraints.fold (fun cst acc ->
+ let subst = Set.fold (fun cst acc ->
let l, r = match cst with
| ULub (u, v) | UWeak (u, v) -> u, v
| UEq (u, v) | ULe (u, v) ->
@@ -845,10 +854,10 @@ let rec whd_state_gen ?csts ~refold ~tactic_mode flags env sigma =
let rec whrec cst_l (x, stack) =
let () = if !debug_RAKAM then
let open Pp in
- let pr c = Termops.print_constr c in
+ let pr c = Termops.Internal.print_constr_env env sigma c in
Feedback.msg_notice
(h 0 (str "<<" ++ pr x ++
- str "|" ++ cut () ++ Cst_stack.pr cst_l ++
+ str "|" ++ cut () ++ Cst_stack.pr env sigma cst_l ++
str "|" ++ cut () ++ Stack.pr pr stack ++
str ">>"))
in
@@ -871,10 +880,10 @@ let rec whd_state_gen ?csts ~refold ~tactic_mode flags env sigma =
| Evar ev -> fold ()
| Meta ev ->
(match safe_meta_value sigma ev with
- | Some body -> whrec cst_l (EConstr.of_constr body, stack)
+ | Some body -> whrec cst_l (body, stack)
| None -> fold ())
| Const (c,u as const) ->
- reduction_effect_hook env sigma (EConstr.to_constr sigma x)
+ reduction_effect_hook env sigma c
(lazy (EConstr.to_constr sigma (Stack.zip sigma (x,stack))));
if CClosure.RedFlags.red_set flags (CClosure.RedFlags.fCONST c) then
let u' = EInstance.kind sigma u in
@@ -920,16 +929,13 @@ let rec whd_state_gen ?csts ~refold ~tactic_mode flags env sigma =
(arg,Stack.Cst(Stack.Cst_const (fst const, u'),curr,remains,bef,cst_l)::s')
) else fold ()
| Proj (p, c) when CClosure.RedFlags.red_projection flags p ->
- (let pb = lookup_projection p env in
- let kn = Projection.constant p in
- let npars = pb.Declarations.proj_npars
- and arg = pb.Declarations.proj_arg in
- if not tactic_mode then
- let stack' = (c, Stack.Proj (npars, arg, p, Cst_stack.empty (*cst_l*)) :: stack) in
+ (let npars = Projection.npars p in
+ if not tactic_mode then
+ let stack' = (c, Stack.Proj (p, Cst_stack.empty (*cst_l*)) :: stack) in
whrec Cst_stack.empty stack'
- else match ReductionBehaviour.get (Globnames.ConstRef kn) with
+ else match ReductionBehaviour.get (Globnames.ConstRef (Projection.constant p)) with
| None ->
- let stack' = (c, Stack.Proj (npars, arg, p, cst_l) :: stack) in
+ let stack' = (c, Stack.Proj (p, cst_l) :: stack) in
let stack'', csts = whrec Cst_stack.empty stack' in
if equal_stacks sigma stack' stack'' then fold ()
else stack'', csts
@@ -946,7 +952,7 @@ let rec whd_state_gen ?csts ~refold ~tactic_mode flags env sigma =
|[] -> (* if nargs has been specified *)
(* CAUTION : the constant is NEVER refold
(even when it hides a (co)fix) *)
- let stack' = (c, Stack.Proj (npars, arg, p, cst_l) :: stack) in
+ let stack' = (c, Stack.Proj (p, cst_l) :: stack) in
whrec Cst_stack.empty(* cst_l *) stack'
| curr::remains ->
if curr == 0 then (* Try to reduce the record argument *)
@@ -1005,8 +1011,8 @@ let rec whd_state_gen ?csts ~refold ~tactic_mode flags env sigma =
match Stack.strip_app stack with
|args, (Stack.Case(ci, _, lf,_)::s') when use_match ->
whrec Cst_stack.empty (lf.(c-1), (Stack.tail ci.ci_npar args) @ s')
- |args, (Stack.Proj (n,m,p,_)::s') when use_match ->
- whrec Cst_stack.empty (Stack.nth args (n+m), s')
+ |args, (Stack.Proj (p,_)::s') when use_match ->
+ whrec Cst_stack.empty (Stack.nth args (Projection.npars p + Projection.arg p), s')
|args, (Stack.Fix (f,s',cst_l)::s'') when use_fix ->
let x' = Stack.zip sigma (x, args) in
let out_sk = s' @ (Stack.append_app [|x'|] s'') in
@@ -1025,14 +1031,11 @@ let rec whd_state_gen ?csts ~refold ~tactic_mode flags env sigma =
whrec (if refold then Cst_stack.add_cst (mkConstU const) cst_l else cst_l)
(body, s' @ (Stack.append_app [|x'|] s'')))
| Stack.Cst_proj p ->
- let pb = lookup_projection p env in
- let npars = pb.Declarations.proj_npars in
- let narg = pb.Declarations.proj_arg in
- let stack = s' @ (Stack.append_app [|x'|] s'') in
+ let stack = s' @ (Stack.append_app [|x'|] s'') in
match Stack.strip_n_app 0 stack with
| None -> assert false
| Some (_,arg,s'') ->
- whrec Cst_stack.empty (arg, Stack.Proj (npars,narg,p,cst_l) :: s''))
+ whrec Cst_stack.empty (arg, Stack.Proj (p,cst_l) :: s''))
| next :: remains' -> match Stack.strip_n_app (next-curr-1) s'' with
| None -> fold ()
| Some (bef,arg,s''') ->
@@ -1090,10 +1093,7 @@ let local_whd_state_gen flags sigma =
| _ -> s)
| Proj (p,c) when CClosure.RedFlags.red_projection flags p ->
- (let pb = lookup_projection p (Global.env ()) in
- whrec (c, Stack.Proj (pb.Declarations.proj_npars, pb.Declarations.proj_arg,
- p, Cst_stack.empty)
- :: stack))
+ (whrec (c, Stack.Proj (p, Cst_stack.empty) :: stack))
| Case (ci,p,d,lf) ->
whrec (d, Stack.Case (ci,p,lf,Cst_stack.empty) :: stack)
@@ -1106,7 +1106,7 @@ let local_whd_state_gen flags sigma =
| Evar ev -> s
| Meta ev ->
(match safe_meta_value sigma ev with
- Some c -> whrec (EConstr.of_constr c,stack)
+ Some c -> whrec (c,stack)
| None -> s)
| Construct ((ind,c),u) ->
@@ -1116,8 +1116,8 @@ let local_whd_state_gen flags sigma =
match Stack.strip_app stack with
|args, (Stack.Case(ci, _, lf,_)::s') when use_match ->
whrec (lf.(c-1), (Stack.tail ci.ci_npar args) @ s')
- |args, (Stack.Proj (n,m,p,_) :: s') when use_match ->
- whrec (Stack.nth args (n+m), s')
+ |args, (Stack.Proj (p,_) :: s') when use_match ->
+ whrec (Stack.nth args (Projection.npars p + Projection.arg p), s')
|args, (Stack.Fix (f,s',cst)::s'') when use_fix ->
let x' = Stack.zip sigma (x,args) in
whrec (contract_fix sigma f, s' @ (Stack.append_app [|x'|] s''))
@@ -1348,11 +1348,10 @@ let infer_conv_gen conv_fun ?(catch_incon=true) ?(pb=Reduction.CUMUL)
?(ts=full_transparent_state) env sigma x y =
(** FIXME *)
try
- let b, sigma =
- let ans =
- if pb == Reduction.CUMUL then
+ let ans = match pb with
+ | Reduction.CUMUL ->
EConstr.leq_constr_universes env sigma x y
- else
+ | Reduction.CONV ->
EConstr.eq_constr_universes env sigma x y
in
let ans = match ans with
@@ -1362,20 +1361,17 @@ let infer_conv_gen conv_fun ?(catch_incon=true) ?(pb=Reduction.CUMUL)
with Univ.UniverseInconsistency _ | Evd.UniversesDiffer -> None
in
match ans with
- | None -> false, sigma
- | Some sigma -> true, sigma
- in
- if b then sigma, true
- else
+ | Some sigma -> ans
+ | None ->
let x = EConstr.Unsafe.to_constr x in
let y = EConstr.Unsafe.to_constr y in
let sigma' =
conv_fun pb ~l2r:false sigma ts
env (sigma, sigma_univ_state) x y in
- sigma', true
+ Some sigma'
with
- | Reduction.NotConvertible -> sigma, false
- | Univ.UniverseInconsistency _ when catch_incon -> sigma, false
+ | Reduction.NotConvertible -> None
+ | Univ.UniverseInconsistency _ when catch_incon -> None
| e when is_anomaly e -> report_anomaly e
let infer_conv = infer_conv_gen (fun pb ~l2r sigma ->
@@ -1392,7 +1388,7 @@ let vm_infer_conv ?(pb=Reduction.CUMUL) env t1 t2 =
(********************************************************************)
let whd_meta sigma c = match EConstr.kind sigma c with
- | Meta p -> (try EConstr.of_constr (meta_value sigma p) with Not_found -> c)
+ | Meta p -> (try meta_value sigma p with Not_found -> c)
| _ -> c
let default_plain_instance_ident = Id.of_string "H"
@@ -1404,7 +1400,7 @@ let plain_instance sigma s c =
| Meta p -> (try lift n (Metamap.find p s) with Not_found -> u)
| App (f,l) when isCast sigma f ->
let (f,_,t) = destCast sigma f in
- let l' = CArray.Fun1.smartmap irec n l in
+ let l' = Array.Fun1.Smart.map irec n l in
(match EConstr.kind sigma f with
| Meta p ->
(* Don't flatten application nodes: this is used to extract a
@@ -1413,7 +1409,7 @@ let plain_instance sigma s c =
(try let g = Metamap.find p s in
match EConstr.kind sigma g with
| App _ ->
- let l' = CArray.Fun1.smartmap lift 1 l' in
+ let l' = Array.Fun1.Smart.map lift 1 l' in
mkLetIn (Name default_plain_instance_ident,g,t,mkApp(mkRel 1, l'))
| _ -> mkApp (g,l')
with Not_found -> mkApp (f,l'))
@@ -1580,11 +1576,11 @@ let whd_betaiota_deltazeta_for_iota_state ts env sigma csts s =
let (t_o,stack_o),csts_o = whd_state_gen ~csts:csts' ~refold ~tactic_mode
(CClosure.RedFlags.red_add_transparent CClosure.all ts) env sigma (t,args) in
if isConstruct sigma t_o then whrec csts_o (t_o, stack_o@stack') else s,csts'
- |args, (Stack.Proj (n,m,p,_) :: stack'') ->
+ |args, (Stack.Proj (p,_) :: stack'') ->
let (t_o,stack_o),csts_o = whd_state_gen ~csts:csts' ~refold ~tactic_mode
(CClosure.RedFlags.red_add_transparent CClosure.all ts) env sigma (t,args) in
if isConstruct sigma t_o then
- whrec Cst_stack.empty (Stack.nth stack_o (n+m), stack'')
+ whrec Cst_stack.empty (Stack.nth stack_o (Projection.npars p + Projection.arg p), stack'')
else s,csts'
|_, ((Stack.App _|Stack.Cst _) :: _|[]) -> s,csts'
in whrec csts s
@@ -1612,7 +1608,7 @@ let meta_value evd mv =
match meta_opt_fvalue evd mv with
| Some (b,_) ->
let metas = Metamap.bind valrec b.freemetas in
- instance evd metas (EConstr.of_constr b.rebus)
+ instance evd metas b.rebus
| None -> mkMeta mv
in
valrec mv
@@ -1625,9 +1621,8 @@ let meta_instance sigma b =
instance sigma c_sigma b.rebus
let nf_meta sigma c =
- let c = EConstr.Unsafe.to_constr c in
let cl = mk_freelisted c in
- meta_instance sigma { cl with rebus = EConstr.of_constr cl.rebus }
+ meta_instance sigma { cl with rebus = cl.rebus }
(* Instantiate metas that create beta/iota redexes *)
@@ -1648,7 +1643,6 @@ let meta_reducible_instance evd b =
(match
try
let g, s = Metamap.find m metas in
- let g = EConstr.of_constr g in
let is_coerce = match s with CoerceToType -> true | _ -> false in
if isConstruct evd g || not is_coerce then Some g else None
with Not_found -> None
@@ -1660,7 +1654,6 @@ let meta_reducible_instance evd b =
(match
try
let g, s = Metamap.find m metas in
- let g = EConstr.of_constr g in
let is_coerce = match s with CoerceToType -> true | _ -> false in
if isLambda evd g || not is_coerce then Some g else None
with Not_found -> None
@@ -1669,7 +1662,6 @@ let meta_reducible_instance evd b =
| None -> mkApp (f,Array.map irec l))
| Meta m ->
(try let g, s = Metamap.find m metas in
- let g = EConstr.of_constr g in
let is_coerce = match s with CoerceToType -> true | _ -> false in
if not is_coerce then irec g else u
with Not_found -> u)
@@ -1678,7 +1670,6 @@ let meta_reducible_instance evd b =
(match
try
let g, s = Metamap.find m metas in
- let g = EConstr.of_constr g in
let is_coerce = match s with CoerceToType -> true | _ -> false in
if isConstruct evd g || not is_coerce then Some g else None
with Not_found -> None
diff --git a/pretyping/reductionops.mli b/pretyping/reductionops.mli
index b8ac085a..c0ff6723 100644
--- a/pretyping/reductionops.mli
+++ b/pretyping/reductionops.mli
@@ -25,10 +25,10 @@ module ReductionBehaviour : sig
(** [set is_local ref (recargs, nargs, flags)] *)
val set :
- bool -> Globnames.global_reference -> (int list * int * flag list) -> unit
+ bool -> GlobRef.t -> (int list * int * flag list) -> unit
val get :
- Globnames.global_reference -> (int list * int * flag list) option
- val print : Globnames.global_reference -> Pp.t
+ GlobRef.t -> (int list * int * flag list) option
+ val print : GlobRef.t -> Pp.t
end
(** {6 Support for reduction effects } *)
@@ -41,10 +41,10 @@ val declare_reduction_effect : effect_name ->
(Environ.env -> Evd.evar_map -> Constr.constr -> unit) -> unit
(* [set_reduction_effect cst name] declares effect [name] to be called when [cst] is found *)
-val set_reduction_effect : Globnames.global_reference -> effect_name -> unit
+val set_reduction_effect : Constant.t -> effect_name -> unit
(* [effect_hook env sigma key term] apply effect associated to [key] on [term] *)
-val reduction_effect_hook : Environ.env -> Evd.evar_map -> Constr.constr ->
+val reduction_effect_hook : Environ.env -> Evd.evar_map -> Constant.t ->
Constr.constr Lazy.t -> unit
(** {6 Machinery about a stack of unfolded constant }
@@ -60,7 +60,7 @@ module Cst_stack : sig
val best_cst : t -> (constr * constr list) option
val best_replace : Evd.evar_map -> constr -> t -> constr -> constr
val reference : Evd.evar_map -> t -> Constant.t option
- val pr : t -> Pp.t
+ val pr : env -> Evd.evar_map -> t -> Pp.t
end
module Stack : sig
@@ -75,7 +75,7 @@ module Stack : sig
type 'a member =
| App of 'a app_node
| Case of case_info * 'a * 'a array * Cst_stack.t
- | Proj of int * int * Projection.t * Cst_stack.t
+ | Proj of Projection.t * Cst_stack.t
| Fix of ('a, 'a) pfixpoint * 'a t * Cst_stack.t
| Cst of cst_member * int (** current foccussed arg *) * int list (** remaining args *)
* 'a t * Cst_stack.t
@@ -140,10 +140,13 @@ type contextual_state_reduction_function =
type state_reduction_function = contextual_state_reduction_function
type local_state_reduction_function = evar_map -> state -> state
-val pr_state : state -> Pp.t
+val pr_state : env -> evar_map -> state -> Pp.t
(** {6 Reduction Function Operators } *)
+val strong_with_flags :
+ (CClosure.RedFlags.reds -> reduction_function) ->
+ (CClosure.RedFlags.reds -> reduction_function)
val strong : reduction_function -> reduction_function
val local_strong : local_reduction_function -> local_reduction_function
val strong_prodspine : local_reduction_function -> local_reduction_function
@@ -277,13 +280,13 @@ val check_conv : ?pb:conv_pb -> ?ts:transparent_state -> env -> evar_map -> con
otherwise returns false in that case.
*)
val infer_conv : ?catch_incon:bool -> ?pb:conv_pb -> ?ts:transparent_state ->
- env -> evar_map -> constr -> constr -> evar_map * bool
+ env -> evar_map -> constr -> constr -> evar_map option
(** Conversion with inference of universe constraints *)
val set_vm_infer_conv : (?pb:conv_pb -> env -> evar_map -> constr -> constr ->
- evar_map * bool) -> unit
+ evar_map option) -> unit
val vm_infer_conv : ?pb:conv_pb -> env -> evar_map -> constr -> constr ->
- evar_map * bool
+ evar_map option
(** [infer_conv_gen] behaves like [infer_conv] but is parametrized by a
@@ -291,7 +294,7 @@ conversion function. Used to pretype vm and native casts. *)
val infer_conv_gen : (conv_pb -> l2r:bool -> evar_map -> transparent_state ->
(Constr.constr, evar_map) Reduction.generic_conversion_function) ->
?catch_incon:bool -> ?pb:conv_pb -> ?ts:transparent_state -> env ->
- evar_map -> constr -> constr -> evar_map * bool
+ evar_map -> constr -> constr -> evar_map option
(** {6 Special-Purpose Reduction Functions } *)
diff --git a/pretyping/retyping.ml b/pretyping/retyping.ml
index 3582b644..7e43c5e4 100644
--- a/pretyping/retyping.ml
+++ b/pretyping/retyping.ml
@@ -57,8 +57,8 @@ let get_type_from_constraints env sigma t =
if isEvar sigma (fst (decompose_app_vect sigma t)) then
match
List.map_filter (fun (pbty,env,t1,t2) ->
- if is_fconv Reduction.CONV env sigma t (EConstr.of_constr t1) then Some t2
- else if is_fconv Reduction.CONV env sigma t (EConstr.of_constr t2) then Some t1
+ if is_fconv Reduction.CONV env sigma t t1 then Some t2
+ else if is_fconv Reduction.CONV env sigma t t2 then Some t1
else None)
(snd (Evd.extract_all_conv_pbs sigma))
with
@@ -99,7 +99,7 @@ let retype ?(polyprop=true) sigma =
let rec type_of env cstr =
match EConstr.kind sigma cstr with
| Meta n ->
- (try strip_outer_cast sigma (EConstr.of_constr (Evd.meta_ftype sigma n).Evd.rebus)
+ (try strip_outer_cast sigma (Evd.meta_ftype sigma n).Evd.rebus
with Not_found -> retype_error (BadMeta n))
| Rel n ->
let ty = RelDecl.get_type (lookup_rel n env) in
@@ -115,7 +115,7 @@ let retype ?(polyprop=true) sigma =
try Inductiveops.find_rectype env sigma t
with Not_found ->
try
- let t = EConstr.of_constr (get_type_from_constraints env sigma t) in
+ let t = get_type_from_constraints env sigma t in
Inductiveops.find_rectype env sigma t
with Not_found -> retype_error BadRecursiveType
in
@@ -149,18 +149,13 @@ let retype ?(polyprop=true) sigma =
| Cast (c,_, s) when isSort sigma s -> destSort sigma s
| Sort s ->
begin match ESorts.kind sigma s with
- | Prop _ -> Sorts.type1
+ | Prop | Set -> Sorts.type1
| Type u -> Type (Univ.super u)
end
| Prod (name,t,c2) ->
- (match (sort_of env t, sort_of (push_rel (LocalAssum (name,t)) env) c2) with
- | _, (Prop Null as s) -> s
- | Prop _, (Prop Pos as s) -> s
- | Type _, (Prop Pos as s) when is_impredicative_set env -> s
- | Type u1, Prop Pos -> Type (Univ.sup u1 Univ.type0_univ)
- | Prop Pos, (Type u2) -> Type (Univ.sup Univ.type0_univ u2)
- | Prop Null, (Type _ as s) -> s
- | Type u1, Type u2 -> Type (Univ.sup u1 u2))
+ let dom = sort_of env t in
+ let rang = sort_of (push_rel (LocalAssum (name,t)) env) c2 in
+ Typeops.sort_of_product env dom rang
| App(f,args) when is_template_polymorphic env sigma f ->
let t = type_of_global_reference_knowing_parameters env f args in
sort_of_atomic_type env sigma t args
@@ -170,7 +165,7 @@ let retype ?(polyprop=true) sigma =
and type_of_global_reference_knowing_parameters env c args =
let argtyps =
- Array.map (fun c -> lazy (EConstr.to_constr sigma (type_of env c))) args in
+ Array.map (fun c -> lazy (EConstr.to_constr ~abort_on_undefined_evars:false sigma (type_of env c))) args in
match EConstr.kind sigma c with
| Ind (ind, u) ->
let u = EInstance.kind sigma u in
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index 518d2f60..8911a2f3 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -12,7 +12,7 @@ open Pp
open CErrors
open Util
open Names
-open Term
+open Constr
open Libnames
open Globnames
open Termops
@@ -49,7 +49,7 @@ let error_not_evaluable r =
let is_evaluable_const env cst =
is_transparent env (ConstKey cst) &&
- (evaluable_constant cst env || is_projection cst env)
+ evaluable_constant cst env
let is_evaluable_var env id =
is_transparent env (VarKey id) && evaluable_named id env
@@ -416,7 +416,7 @@ exception Partial
reduction is solved by the expanded fix term. *)
let solve_arity_problem env sigma fxminargs c =
let evm = ref sigma in
- let set_fix i = evm := Evd.define i (Constr.mkVar vfx) !evm in
+ let set_fix i = evm := Evd.define i (mkVar vfx) !evm in
let rec check strict c =
let c' = whd_betaiotazeta sigma c in
let (h,rcargs) = decompose_app_vect sigma c' in
@@ -539,7 +539,7 @@ let reduce_mind_case_use_function func env sigma mia =
let match_eval_ref env sigma constr stack =
match EConstr.kind sigma constr with
| Const (sp, u) ->
- reduction_effect_hook env sigma (EConstr.to_constr sigma constr)
+ reduction_effect_hook env sigma sp
(lazy (EConstr.to_constr sigma (applist (constr,stack))));
if is_evaluable env (EvalConstRef sp) then Some (EvalConst sp, u) else None
| Var id when is_evaluable env (EvalVarRef id) -> Some (EvalVar id, EInstance.empty)
@@ -550,7 +550,7 @@ let match_eval_ref env sigma constr stack =
let match_eval_ref_value env sigma constr stack =
match EConstr.kind sigma constr with
| Const (sp, u) ->
- reduction_effect_hook env sigma (EConstr.to_constr sigma constr)
+ reduction_effect_hook env sigma sp
(lazy (EConstr.to_constr sigma (applist (constr,stack))));
if is_evaluable env (EvalConstRef sp) then
let u = EInstance.kind sigma u in
@@ -558,8 +558,6 @@ let match_eval_ref_value env sigma constr stack =
else
None
| Proj (p, c) when not (Projection.unfolded p) ->
- reduction_effect_hook env sigma (EConstr.to_constr sigma constr)
- (lazy (EConstr.to_constr sigma (applist (constr,stack))));
if is_evaluable env (EvalConstRef (Projection.constant p)) then
Some (mkProj (Projection.unfold p, c))
else None
@@ -597,12 +595,11 @@ let recargs = function
| EvalVar _ | EvalRel _ | EvalEvar _ -> None
| EvalConst c -> ReductionBehaviour.get (ConstRef c)
-let reduce_projection env sigma pb (recarg'hd,stack') stack =
+let reduce_projection env sigma p ~npars (recarg'hd,stack') stack =
(match EConstr.kind sigma recarg'hd with
| Construct _ ->
- let proj_narg =
- pb.Declarations.proj_npars + pb.Declarations.proj_arg
- in Reduced (List.nth stack' proj_narg, stack)
+ let proj_narg = npars + Projection.arg p in
+ Reduced (List.nth stack' proj_narg, stack)
| _ -> NotReducible)
let reduce_proj env sigma whfun whfun' c =
@@ -613,10 +610,8 @@ let reduce_proj env sigma whfun whfun' c =
let constr, cargs = whfun c' in
(match EConstr.kind sigma constr with
| Construct _ ->
- let proj_narg =
- let pb = lookup_projection proj env in
- pb.Declarations.proj_npars + pb.Declarations.proj_arg
- in List.nth cargs proj_narg
+ let proj_narg = Projection.npars proj + Projection.arg proj in
+ List.nth cargs proj_narg
| _ -> raise Redelimination)
| Case (n,p,c,brs) ->
let c' = redrec c in
@@ -641,7 +636,7 @@ let whd_nothing_for_iota env sigma s =
| _ -> s)
| Evar ev -> s
| Meta ev ->
- (try whrec (EConstr.of_constr (Evd.meta_value sigma ev), stack)
+ (try whrec (Evd.meta_value sigma ev, stack)
with Not_found -> s)
| Const (const, u) when is_transparent_constant full_transparent_state const ->
let u = EInstance.kind sigma u in
@@ -765,22 +760,22 @@ and whd_simpl_stack env sigma =
(try
let unf = Projection.unfolded p in
if unf || is_evaluable env (EvalConstRef (Projection.constant p)) then
- let pb = lookup_projection p env in
+ let npars = Projection.npars p in
(match unf, ReductionBehaviour.get (ConstRef (Projection.constant p)) with
| false, Some (l, n, f) when List.mem `ReductionNeverUnfold f ->
(* simpl never *) s'
| false, Some (l, n, f) when not (List.is_empty l) ->
let l' = List.map_filter (fun i ->
- let idx = (i - (pb.Declarations.proj_npars + 1)) in
+ let idx = (i - (npars + 1)) in
if idx < 0 then None else Some idx) l in
let stack = reduce_params env sigma stack l' in
- (match reduce_projection env sigma pb
+ (match reduce_projection env sigma p ~npars
(whd_construct_stack env sigma c) stack
with
| Reduced s' -> redrec (applist s')
| NotReducible -> s')
| _ ->
- match reduce_projection env sigma pb (whd_construct_stack env sigma c) stack with
+ match reduce_projection env sigma p ~npars (whd_construct_stack env sigma c) stack with
| Reduced s' -> redrec (applist s')
| NotReducible -> s')
else s'
@@ -852,8 +847,8 @@ let try_red_product env sigma c =
| Construct _ -> c
| _ -> redrec env c
in
- let pb = lookup_projection p env in
- (match reduce_projection env sigma pb (whd_betaiotazeta_stack sigma c') [] with
+ let npars = Projection.npars p in
+ (match reduce_projection env sigma p ~npars (whd_betaiotazeta_stack sigma c') [] with
| Reduced s -> simpfun (applist s)
| NotReducible -> raise Redelimination)
| _ ->
@@ -946,8 +941,8 @@ let whd_simpl_orelse_delta_but_fix env sigma c =
(match EConstr.kind sigma constr with
| Const (c', _) -> Constant.equal (Projection.constant p) c'
| _ -> false) ->
- let pb = Environ.lookup_projection p env in
- if List.length stack <= pb.Declarations.proj_npars then
+ let npars = Projection.npars p in
+ if List.length stack <= npars then
(** Do not show the eta-expanded form *)
s'
else redrec (applist (c, stack))
@@ -1279,7 +1274,7 @@ let reduce_to_ref_gen allow_product env sigma ref t =
error_cannot_recognize ref
| _ ->
try
- if eq_gr (fst (global_of_constr sigma c)) ref
+ if GlobRef.equal (fst (global_of_constr sigma c)) ref
then it_mkProd_or_LetIn t l
else raise Not_found
with Not_found ->
diff --git a/pretyping/tacred.mli b/pretyping/tacred.mli
index aa7604f5..e6065dda 100644
--- a/pretyping/tacred.mli
+++ b/pretyping/tacred.mli
@@ -14,7 +14,6 @@ open Evd
open EConstr
open Reductionops
open Pattern
-open Globnames
open Locus
open Univ
open Ltac_pretype
@@ -30,13 +29,13 @@ exception ReductionTacticError of reduction_tactic_error
val is_evaluable : Environ.env -> evaluable_global_reference -> bool
-val error_not_evaluable : Globnames.global_reference -> 'a
+val error_not_evaluable : GlobRef.t -> 'a
val evaluable_of_global_reference :
- Environ.env -> Globnames.global_reference -> evaluable_global_reference
+ Environ.env -> GlobRef.t -> evaluable_global_reference
val global_of_evaluable_reference :
- evaluable_global_reference -> Globnames.global_reference
+ evaluable_global_reference -> GlobRef.t
exception Redelimination
@@ -88,10 +87,10 @@ val reduce_to_quantified_ind : env -> evar_map -> types -> (inductive * EInstan
(** [reduce_to_quantified_ref env sigma ref t] try to put [t] in the form
[t'=(x1:A1)..(xn:An)(ref args)] and fails with user error if not possible *)
val reduce_to_quantified_ref :
- env -> evar_map -> global_reference -> types -> types
+ env -> evar_map -> GlobRef.t -> types -> types
val reduce_to_atomic_ref :
- env -> evar_map -> global_reference -> types -> types
+ env -> evar_map -> GlobRef.t -> types -> types
val find_hnf_rectype :
env -> evar_map -> types -> (inductive * EInstance.t) * constr list
diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml
index 08051fd3..efb3c339 100644
--- a/pretyping/typeclasses.ml
+++ b/pretyping/typeclasses.ml
@@ -25,6 +25,13 @@ module RelDecl = Context.Rel.Declaration
module NamedDecl = Context.Named.Declaration
(*i*)
+(* Core typeclasses hints *)
+type 'a hint_info_gen =
+ { hint_priority : int option;
+ hint_pattern : 'a option }
+
+type hint_info = (Pattern.patvar list * Pattern.constr_pattern) hint_info_gen
+
let typeclasses_unique_solutions = ref false
let set_typeclasses_unique_solutions d = (:=) typeclasses_unique_solutions d
let get_typeclasses_unique_solutions () = !typeclasses_unique_solutions
@@ -64,16 +71,16 @@ type typeclass = {
cl_univs : Univ.AUContext.t;
(* The class implementation *)
- cl_impl : global_reference;
+ cl_impl : GlobRef.t;
(* Context in which the definitions are typed. Includes both typeclass parameters and superclasses. *)
- cl_context : global_reference option list * Context.Rel.t;
+ cl_context : GlobRef.t option list * Constr.rel_context;
(* Context of definitions and properties on defs, will not be shared *)
- cl_props : Context.Rel.t;
+ cl_props : Constr.rel_context;
(* The method implementaions as projections. *)
- cl_projs : (Name.t * (direction * Vernacexpr.hint_info_expr) option
+ cl_projs : (Name.t * (direction * hint_info) option
* Constant.t option) list;
cl_strict : bool;
@@ -84,19 +91,19 @@ type typeclass = {
type typeclasses = typeclass Refmap.t
type instance = {
- is_class: global_reference;
- is_info: Vernacexpr.hint_info_expr;
+ is_class: GlobRef.t;
+ is_info: hint_info;
(* Sections where the instance should be redeclared,
None for discard, Some 0 for none. *)
is_global: int option;
- is_impl: global_reference;
+ is_impl: GlobRef.t;
}
type instances = (instance Refmap.t) Refmap.t
let instance_impl is = is.is_impl
-let hint_priority is = is.is_info.Vernacexpr.hint_priority
+let hint_priority is = is.is_info.hint_priority
let new_instance cl info glob impl =
let global =
@@ -158,7 +165,7 @@ let rec is_class_type evd c =
| _ -> is_class_constr evd c
let is_class_evar evd evi =
- is_class_type evd (EConstr.of_constr evi.Evd.evar_concl)
+ is_class_type evd evi.Evd.evar_concl
(*
* classes persistent object
@@ -173,12 +180,12 @@ let subst_class (subst,cl) =
let do_subst_con c = Mod_subst.subst_constant subst c
and do_subst c = Mod_subst.subst_mps subst c
and do_subst_gr gr = fst (subst_global subst gr) in
- let do_subst_ctx = List.smartmap (RelDecl.map_constr do_subst) in
+ let do_subst_ctx = List.Smart.map (RelDecl.map_constr do_subst) in
let do_subst_context (grs,ctx) =
- List.smartmap (Option.smartmap do_subst_gr) grs,
+ List.Smart.map (Option.Smart.map do_subst_gr) grs,
do_subst_ctx ctx in
- let do_subst_projs projs = List.smartmap (fun (x, y, z) ->
- (x, y, Option.smartmap do_subst_con z)) projs in
+ let do_subst_projs projs = List.Smart.map (fun (x, y, z) ->
+ (x, y, Option.Smart.map do_subst_con z)) projs in
{ cl_univs = cl.cl_univs;
cl_impl = do_subst_gr cl.cl_impl;
cl_context = do_subst_context cl.cl_context;
@@ -216,7 +223,7 @@ let discharge_class (_,cl) =
| Some (_, ((tc,_), _)) -> Some tc.cl_impl)
ctx'
in
- List.smartmap (Option.smartmap Lib.discharge_global) grs
+ List.Smart.map (Option.Smart.map Lib.discharge_global) grs
@ newgrs
in grs', discharge_rel_context subst 1 ctx @ ctx' in
let cl_impl' = Lib.discharge_global cl.cl_impl in
@@ -227,12 +234,12 @@ let discharge_class (_,cl) =
let usubst, cl_univs' = Lib.discharge_abstract_universe_context info cl.cl_univs in
let context = discharge_context ctx (subst, usubst) cl.cl_context in
let props = discharge_rel_context (subst, usubst) (succ (List.length (fst cl.cl_context))) cl.cl_props in
- let discharge_proj (x, y, z) = x, y, Option.smartmap Lib.discharge_con z in
+ let discharge_proj (x, y, z) = x, y, Option.Smart.map Lib.discharge_con z in
{ cl_univs = cl_univs';
cl_impl = cl_impl';
cl_context = context;
cl_props = props;
- cl_projs = List.smartmap discharge_proj cl.cl_projs;
+ cl_projs = List.Smart.map discharge_proj cl.cl_projs;
cl_strict = cl.cl_strict;
cl_unique = cl.cl_unique
}
@@ -266,8 +273,6 @@ let check_instance env sigma c =
not (Evd.has_undefined evd)
with e when CErrors.noncritical e -> false
-open Vernacexpr
-
let build_subclasses ~check env sigma glob { hint_priority = pri } =
let _id = Nametab.basename_of_global glob in
let _next_id =
@@ -276,7 +281,7 @@ let build_subclasses ~check env sigma glob { hint_priority = pri } =
Nameops.add_suffix _id ("_subinstance_" ^ string_of_int !i))
in
let ty, ctx = Global.type_of_global_in_context env glob in
- let inst, ctx = Universes.fresh_instance_from ctx None in
+ let inst, ctx = UnivGen.fresh_instance_from ctx None in
let ty = Vars.subst_instance_constr inst ty in
let ty = EConstr.of_constr ty in
let sigma = Evd.merge_context_set Evd.univ_rigid sigma ctx in
@@ -316,7 +321,7 @@ let build_subclasses ~check env sigma glob { hint_priority = pri } =
hints @ (path', info, body) :: rest
in List.fold_left declare_proj [] projs
in
- let term = Universes.constr_of_global_univ (glob, inst) in
+ let term = UnivGen.constr_of_global_univ (glob, inst) in
(*FIXME subclasses should now get substituted for each particular instance of
the polymorphic superclass *)
aux pri term ty [glob]
@@ -475,7 +480,7 @@ let instances r =
let cl = class_info r in instances_of cl
let is_class gr =
- Refmap.exists (fun _ v -> eq_gr v.cl_impl gr) !classes
+ Refmap.exists (fun _ v -> GlobRef.equal v.cl_impl gr) !classes
let is_instance = function
| ConstRef c ->
diff --git a/pretyping/typeclasses.mli b/pretyping/typeclasses.mli
index b80c2871..80c6d823 100644
--- a/pretyping/typeclasses.mli
+++ b/pretyping/typeclasses.mli
@@ -16,6 +16,13 @@ open Environ
type direction = Forward | Backward
+(* Core typeclasses hints *)
+type 'a hint_info_gen =
+ { hint_priority : int option;
+ hint_pattern : 'a option }
+
+type hint_info = (Pattern.patvar list * Pattern.constr_pattern) hint_info_gen
+
(** This module defines type-classes *)
type typeclass = {
(** The toplevel universe quantification in which the typeclass lives. In
@@ -24,20 +31,20 @@ type typeclass = {
(** The class implementation: a record parameterized by the context with defs in it or a definition if
the class is a singleton. This acts as the class' global identifier. *)
- cl_impl : global_reference;
+ cl_impl : GlobRef.t;
(** Context in which the definitions are typed. Includes both typeclass parameters and superclasses.
The global reference gives a direct link to the class itself. *)
- cl_context : global_reference option list * Context.Rel.t;
+ cl_context : GlobRef.t option list * Constr.rel_context;
(** Context of definitions and properties on defs, will not be shared *)
- cl_props : Context.Rel.t;
+ cl_props : Constr.rel_context;
(** The methods implementations of the typeclass as projections.
Some may be undefinable due to sorting restrictions or simply undefined if
no name is provided. The [int option option] indicates subclasses whose hint has
the given priority. *)
- cl_projs : (Name.t * (direction * Vernacexpr.hint_info_expr) option * Constant.t option) list;
+ cl_projs : (Name.t * (direction * hint_info) option * Constant.t option) list;
(** Whether we use matching or full unification during resolution *)
cl_strict : bool;
@@ -49,18 +56,17 @@ type typeclass = {
type instance
-val instances : global_reference -> instance list
+val instances : GlobRef.t -> instance list
val typeclasses : unit -> typeclass list
val all_instances : unit -> instance list
val add_class : typeclass -> unit
-val new_instance : typeclass -> Vernacexpr.hint_info_expr -> bool ->
- global_reference -> instance
+val new_instance : typeclass -> hint_info -> bool -> GlobRef.t -> instance
val add_instance : instance -> unit
val remove_instance : instance -> unit
-val class_info : global_reference -> typeclass (** raises a UserError if not a class *)
+val class_info : GlobRef.t -> typeclass (** raises a UserError if not a class *)
(** These raise a UserError if not a class.
@@ -74,12 +80,12 @@ val typeclass_univ_instance : typeclass Univ.puniverses -> typeclass
(** Just return None if not a class *)
val class_of_constr : evar_map -> EConstr.constr -> (EConstr.rel_context * ((typeclass * EConstr.EInstance.t) * constr list)) option
-val instance_impl : instance -> global_reference
+val instance_impl : instance -> GlobRef.t
val hint_priority : instance -> int option
-val is_class : global_reference -> bool
-val is_instance : global_reference -> bool
+val is_class : GlobRef.t -> bool
+val is_instance : GlobRef.t -> bool
(** Returns the term and type for the given instance of the parameters and fields
of the type class. *)
@@ -121,24 +127,24 @@ val set_typeclass_transparency : evaluable_global_reference -> bool -> bool -> u
val classes_transparent_state_hook : (unit -> transparent_state) Hook.t
val classes_transparent_state : unit -> transparent_state
-val add_instance_hint_hook :
- (global_reference_or_constr -> global_reference list ->
- bool (* local? *) -> Vernacexpr.hint_info_expr -> Decl_kinds.polymorphic -> unit) Hook.t
-val remove_instance_hint_hook : (global_reference -> unit) Hook.t
-val add_instance_hint : global_reference_or_constr -> global_reference list ->
- bool -> Vernacexpr.hint_info_expr -> Decl_kinds.polymorphic -> unit
-val remove_instance_hint : global_reference -> unit
+val add_instance_hint_hook :
+ (global_reference_or_constr -> GlobRef.t list ->
+ bool (* local? *) -> hint_info -> Decl_kinds.polymorphic -> unit) Hook.t
+val remove_instance_hint_hook : (GlobRef.t -> unit) Hook.t
+val add_instance_hint : global_reference_or_constr -> GlobRef.t list ->
+ bool -> hint_info -> Decl_kinds.polymorphic -> unit
+val remove_instance_hint : GlobRef.t -> unit
val solve_all_instances_hook : (env -> evar_map -> evar_filter -> bool -> bool -> bool -> evar_map) Hook.t
val solve_one_instance_hook : (env -> evar_map -> EConstr.types -> bool -> evar_map * EConstr.constr) Hook.t
-val declare_instance : Vernacexpr.hint_info_expr option -> bool -> global_reference -> unit
+val declare_instance : hint_info option -> bool -> GlobRef.t -> unit
(** Build the subinstances hints for a given typeclass object.
check tells if we should check for existence of the
subinstances and add only the missing ones. *)
-val build_subclasses : check:bool -> env -> evar_map -> global_reference ->
- Vernacexpr.hint_info_expr ->
- (global_reference list * Vernacexpr.hint_info_expr * constr) list
+val build_subclasses : check:bool -> env -> evar_map -> GlobRef.t ->
+ hint_info ->
+ (GlobRef.t list * hint_info * constr) list
diff --git a/pretyping/typeclasses_errors.ml b/pretyping/typeclasses_errors.ml
index e10c81c2..2720a3e4 100644
--- a/pretyping/typeclasses_errors.ml
+++ b/pretyping/typeclasses_errors.ml
@@ -9,18 +9,16 @@
(************************************************************************)
(*i*)
+open Names
open EConstr
open Environ
-open Constrexpr
-open Globnames
(*i*)
type contexts = Parameters | Properties
type typeclass_error =
| NotAClass of constr
- | UnboundMethod of global_reference * Misctypes.lident (* Class name, method *)
- | MismatchedContextInstance of contexts * constr_expr list * Context.Rel.t (* found, expected *)
+ | UnboundMethod of GlobRef.t * lident (* Class name, method *)
exception TypeClassError of env * typeclass_error
@@ -29,5 +27,3 @@ let typeclass_error env err = raise (TypeClassError (env, err))
let not_a_class env c = typeclass_error env (NotAClass c)
let unbound_method env cid id = typeclass_error env (UnboundMethod (cid, id))
-
-let mismatched_ctx_inst env c n m = typeclass_error env (MismatchedContextInstance (c, n, m))
diff --git a/pretyping/typeclasses_errors.mli b/pretyping/typeclasses_errors.mli
index d9829565..9831627a 100644
--- a/pretyping/typeclasses_errors.mli
+++ b/pretyping/typeclasses_errors.mli
@@ -8,23 +8,19 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+open Names
open EConstr
open Environ
-open Constrexpr
-open Globnames
type contexts = Parameters | Properties
type typeclass_error =
| NotAClass of constr
- | UnboundMethod of global_reference * Misctypes.lident (** Class name, method *)
- | MismatchedContextInstance of contexts * constr_expr list * Context.Rel.t (** found, expected *)
+ | UnboundMethod of GlobRef.t * lident (** Class name, method *)
exception TypeClassError of env * typeclass_error
val not_a_class : env -> constr -> 'a
-val unbound_method : env -> global_reference -> Misctypes.lident -> 'a
-
-val mismatched_ctx_inst : env -> contexts -> constr_expr list -> Context.Rel.t -> 'a
+val unbound_method : env -> GlobRef.t -> lident -> 'a
diff --git a/pretyping/typing.ml b/pretyping/typing.ml
index 4c834f2f..4ba715f0 100644
--- a/pretyping/typing.ml
+++ b/pretyping/typing.ml
@@ -14,6 +14,7 @@ open Pp
open CErrors
open Util
open Term
+open Constr
open Environ
open EConstr
open Vars
@@ -29,113 +30,123 @@ let meta_type evd mv =
let ty =
try Evd.meta_ftype evd mv
with Not_found -> anomaly (str "unknown meta ?" ++ str (Nameops.string_of_meta mv) ++ str ".") in
- let ty = Evd.map_fl EConstr.of_constr ty in
meta_instance evd ty
let inductive_type_knowing_parameters env sigma (ind,u) jl =
let u = Unsafe.to_instance u in
let mspec = lookup_mind_specif env ind in
- let paramstyp = Array.map (fun j -> lazy (EConstr.to_constr sigma j.uj_type)) jl in
+ let paramstyp = Array.map (fun j -> lazy (EConstr.to_constr ~abort_on_undefined_evars:false sigma j.uj_type)) jl in
Inductive.type_of_inductive_knowing_parameters env (mspec,u) paramstyp
-let e_type_judgment env evdref j =
- match EConstr.kind !evdref (whd_all env !evdref j.uj_type) with
- | Sort s -> {utj_val = j.uj_val; utj_type = ESorts.kind !evdref s }
+let type_judgment env sigma j =
+ match EConstr.kind sigma (whd_all env sigma j.uj_type) with
+ | Sort s -> sigma, {utj_val = j.uj_val; utj_type = ESorts.kind sigma s }
| Evar ev ->
- let (evd,s) = Evardefine.define_evar_as_sort env !evdref ev in
- evdref := evd; { utj_val = j.uj_val; utj_type = s }
- | _ -> error_not_a_type env !evdref j
-
-let e_assumption_of_judgment env evdref j =
- try (e_type_judgment env evdref j).utj_val
+ let (sigma,s) = Evardefine.define_evar_as_sort env sigma ev in
+ sigma, { utj_val = j.uj_val; utj_type = s }
+ | _ -> error_not_a_type env sigma j
+
+let assumption_of_judgment env sigma j =
+ try
+ let sigma, j = type_judgment env sigma j in
+ sigma, j.utj_val
with Type_errors.TypeError _ | PretypeError _ ->
- error_assumption env !evdref j
+ error_assumption env sigma j
-let e_judge_of_applied_inductive_knowing_parameters env evdref funj ind argjv =
- let rec apply_rec n typ = function
+let judge_of_applied_inductive_knowing_parameters env sigma funj ind argjv =
+ let rec apply_rec sigma n typ = function
| [] ->
- { uj_val = mkApp (j_val funj, Array.map j_val argjv);
- uj_type =
- let ar = inductive_type_knowing_parameters env !evdref ind argjv in
- hnf_prod_appvect env !evdref (EConstr.of_constr ar) (Array.map j_val argjv) }
+ sigma, { uj_val = mkApp (j_val funj, Array.map j_val argjv);
+ uj_type =
+ let ar = inductive_type_knowing_parameters env sigma ind argjv in
+ hnf_prod_appvect env sigma (EConstr.of_constr ar) (Array.map j_val argjv) }
| hj::restjl ->
- let (c1,c2) =
- match EConstr.kind !evdref (whd_all env !evdref typ) with
- | Prod (_,c1,c2) -> (c1,c2)
+ let sigma, (c1,c2) =
+ match EConstr.kind sigma (whd_all env sigma typ) with
+ | Prod (_,c1,c2) -> sigma, (c1,c2)
| Evar ev ->
- let (evd',t) = Evardefine.define_evar_as_product !evdref ev in
- evdref := evd';
- let (_,c1,c2) = destProd evd' t in
- (c1,c2)
+ let (sigma,t) = Evardefine.define_evar_as_product sigma ev in
+ let (_,c1,c2) = destProd sigma t in
+ sigma, (c1,c2)
| _ ->
- error_cant_apply_not_functional env !evdref funj argjv
+ error_cant_apply_not_functional env sigma funj argjv
in
- if Evarconv.e_cumul env evdref hj.uj_type c1 then
- apply_rec (n+1) (subst1 hj.uj_val c2) restjl
- else
- error_cant_apply_bad_type env !evdref (n, c1, hj.uj_type) funj argjv
+ begin match Evarconv.cumul env sigma hj.uj_type c1 with
+ | Some sigma ->
+ apply_rec sigma (n+1) (subst1 hj.uj_val c2) restjl
+ | None ->
+ error_cant_apply_bad_type env sigma (n, c1, hj.uj_type) funj argjv
+ end
in
- apply_rec 1 funj.uj_type (Array.to_list argjv)
+ apply_rec sigma 1 funj.uj_type (Array.to_list argjv)
-let e_judge_of_apply env evdref funj argjv =
- let rec apply_rec n typ = function
+let judge_of_apply env sigma funj argjv =
+ let rec apply_rec sigma n typ = function
| [] ->
- { uj_val = mkApp (j_val funj, Array.map j_val argjv);
- uj_type = typ }
+ sigma, { uj_val = mkApp (j_val funj, Array.map j_val argjv);
+ uj_type = typ }
| hj::restjl ->
- let (c1,c2) =
- match EConstr.kind !evdref (whd_all env !evdref typ) with
- | Prod (_,c1,c2) -> (c1,c2)
+ let sigma, (c1,c2) =
+ match EConstr.kind sigma (whd_all env sigma typ) with
+ | Prod (_,c1,c2) -> sigma, (c1,c2)
| Evar ev ->
- let (evd',t) = Evardefine.define_evar_as_product !evdref ev in
- evdref := evd';
- let (_,c1,c2) = destProd evd' t in
- (c1,c2)
+ let (sigma,t) = Evardefine.define_evar_as_product sigma ev in
+ let (_,c1,c2) = destProd sigma t in
+ sigma, (c1,c2)
| _ ->
- error_cant_apply_not_functional env !evdref funj argjv
+ error_cant_apply_not_functional env sigma funj argjv
in
- if Evarconv.e_cumul env evdref hj.uj_type c1 then
- apply_rec (n+1) (subst1 hj.uj_val c2) restjl
- else
- error_cant_apply_bad_type env !evdref (n, c1, hj.uj_type) funj argjv
+ begin match Evarconv.cumul env sigma hj.uj_type c1 with
+ | Some sigma ->
+ apply_rec sigma (n+1) (subst1 hj.uj_val c2) restjl
+ | None ->
+ error_cant_apply_bad_type env sigma (n, c1, hj.uj_type) funj argjv
+ end
in
- apply_rec 1 funj.uj_type (Array.to_list argjv)
+ apply_rec sigma 1 funj.uj_type (Array.to_list argjv)
-let e_check_branch_types env evdref (ind,u) cj (lfj,explft) =
+let check_branch_types env sigma (ind,u) cj (lfj,explft) =
if not (Int.equal (Array.length lfj) (Array.length explft)) then
- error_number_branches env !evdref cj (Array.length explft);
- for i = 0 to Array.length explft - 1 do
- if not (Evarconv.e_cumul env evdref lfj.(i).uj_type explft.(i)) then
- error_ill_formed_branch env !evdref cj.uj_val ((ind,i+1),u) lfj.(i).uj_type explft.(i)
- done
+ error_number_branches env sigma cj (Array.length explft);
+ Array.fold_left2_i (fun i sigma lfj explft ->
+ match Evarconv.cumul env sigma lfj.uj_type explft with
+ | Some sigma -> sigma
+ | None ->
+ error_ill_formed_branch env sigma cj.uj_val ((ind,i+1),u) lfj.uj_type explft)
+ sigma lfj explft
let max_sort l =
if Sorts.List.mem InType l then InType else
if Sorts.List.mem InSet l then InSet else InProp
-let e_is_correct_arity env evdref c pj ind specif params =
- let arsign = make_arity_signature env !evdref true (make_ind_family (ind,params)) in
+let is_correct_arity env sigma c pj ind specif params =
+ let arsign = make_arity_signature env sigma true (make_ind_family (ind,params)) in
let allowed_sorts = elim_sorts specif in
- let error () = Pretype_errors.error_elim_arity env !evdref ind allowed_sorts c pj None in
- let rec srec env pt ar =
- let pt' = whd_all env !evdref pt in
- match EConstr.kind !evdref pt', ar with
+ let error () = Pretype_errors.error_elim_arity env sigma ind allowed_sorts c pj None in
+ let rec srec env sigma pt ar =
+ let pt' = whd_all env sigma pt in
+ match EConstr.kind sigma pt', ar with
| Prod (na1,a1,t), (LocalAssum (_,a1'))::ar' ->
- if not (Evarconv.e_cumul env evdref a1 a1') then error ();
- srec (push_rel (LocalAssum (na1,a1)) env) t ar'
+ begin match Evarconv.cumul env sigma a1 a1' with
+ | None -> error ()
+ | Some sigma ->
+ srec (push_rel (LocalAssum (na1,a1)) env) sigma t ar'
+ end
| Sort s, [] ->
- let s = ESorts.kind !evdref s in
+ let s = ESorts.kind sigma s in
if not (Sorts.List.mem (Sorts.family s) allowed_sorts)
then error ()
+ else sigma
| Evar (ev,_), [] ->
- let evd, s = Evd.fresh_sort_in_family env !evdref (max_sort allowed_sorts) in
- evdref := Evd.define ev (Constr.mkSort s) evd
+ let sigma, s = Evd.fresh_sort_in_family sigma (max_sort allowed_sorts) in
+ let sigma = Evd.define ev (mkSort s) sigma in
+ sigma
| _, (LocalDef _ as d)::ar' ->
- srec (push_rel d env) (lift 1 pt') ar'
+ srec (push_rel d env) sigma (lift 1 pt') ar'
| _ ->
error ()
in
- srec env pj.uj_type (List.rev arsign)
+ srec env sigma pj.uj_type (List.rev arsign)
let lambda_applist_assum sigma n c l =
let rec app n subst t l =
@@ -148,66 +159,70 @@ let lambda_applist_assum sigma n c l =
| _ -> anomaly (Pp.str "Not enough lambda/let's.") in
app n [] c l
-let e_type_case_branches env evdref (ind,largs) pj c =
+let type_case_branches env sigma (ind,largs) pj c =
let specif = lookup_mind_specif env (fst ind) in
let nparams = inductive_params specif in
let (params,realargs) = List.chop nparams largs in
let p = pj.uj_val in
let params = List.map EConstr.Unsafe.to_constr params in
- let () = e_is_correct_arity env evdref c pj ind specif params in
- let lc = build_branches_type ind specif params (EConstr.to_constr !evdref p) in
+ let sigma = is_correct_arity env sigma c pj ind specif params in
+ let lc = build_branches_type ind specif params (EConstr.to_constr ~abort_on_undefined_evars:false sigma p) in
let lc = Array.map EConstr.of_constr lc in
let n = (snd specif).Declarations.mind_nrealdecls in
- let ty = whd_betaiota !evdref (lambda_applist_assum !evdref (n+1) p (realargs@[c])) in
- (lc, ty)
+ let ty = whd_betaiota sigma (lambda_applist_assum sigma (n+1) p (realargs@[c])) in
+ sigma, (lc, ty)
-let e_judge_of_case env evdref ci pj cj lfj =
+let judge_of_case env sigma ci pj cj lfj =
let ((ind, u), spec) =
- try find_mrectype env !evdref cj.uj_type
- with Not_found -> error_case_not_inductive env !evdref cj in
- let indspec = ((ind, EInstance.kind !evdref u), spec) in
+ try find_mrectype env sigma cj.uj_type
+ with Not_found -> error_case_not_inductive env sigma cj in
+ let indspec = ((ind, EInstance.kind sigma u), spec) in
let _ = check_case_info env (fst indspec) ci in
- let (bty,rslty) = e_type_case_branches env evdref indspec pj cj.uj_val in
- e_check_branch_types env evdref (fst indspec) cj (lfj,bty);
- { uj_val = mkCase (ci, pj.uj_val, cj.uj_val, Array.map j_val lfj);
- uj_type = rslty }
+ let sigma, (bty,rslty) = type_case_branches env sigma indspec pj cj.uj_val in
+ let sigma = check_branch_types env sigma (fst indspec) cj (lfj,bty) in
+ sigma, { uj_val = mkCase (ci, pj.uj_val, cj.uj_val, Array.map j_val lfj);
+ uj_type = rslty }
-let check_type_fixpoint ?loc env evdref lna lar vdefj =
+let check_type_fixpoint ?loc env sigma lna lar vdefj =
let lt = Array.length vdefj in
- if Int.equal (Array.length lar) lt then
- for i = 0 to lt-1 do
- if not (Evarconv.e_cumul env evdref (vdefj.(i)).uj_type
- (lift lt lar.(i))) then
- error_ill_typed_rec_body ?loc env !evdref
- i lna vdefj lar
- done
+ assert (Int.equal (Array.length lar) lt);
+ Array.fold_left2_i (fun i sigma defj ar ->
+ match Evarconv.cumul env sigma defj.uj_type (lift lt ar) with
+ | Some sigma -> sigma
+ | None ->
+ error_ill_typed_rec_body ?loc env sigma
+ i lna vdefj lar)
+ sigma vdefj lar
+
(* FIXME: might depend on the level of actual parameters!*)
let check_allowed_sort env sigma ind c p =
- let pj = Retyping.get_judgment_of env sigma p in
- let ksort = Sorts.family (ESorts.kind sigma (sort_of_arity env sigma pj.uj_type)) in
let specif = Global.lookup_inductive (fst ind) in
let sorts = elim_sorts specif in
+ let pj = Retyping.get_judgment_of env sigma p in
+ let _, s = splay_prod env sigma pj.uj_type in
+ let ksort = match EConstr.kind sigma s with
+ | Sort s -> Sorts.family (ESorts.kind sigma s)
+ | _ -> error_elim_arity env sigma ind sorts c pj None in
if not (List.exists ((==) ksort) sorts) then
let s = inductive_sort_family (snd specif) in
error_elim_arity env sigma ind sorts c pj
(Some(ksort,s,Type_errors.error_elim_explain ksort s))
-let e_judge_of_cast env evdref cj k tj =
+let judge_of_cast env sigma cj k tj =
let expected_type = tj.utj_val in
- if not (Evarconv.e_cumul env evdref cj.uj_type expected_type) then
- error_actual_type_core env !evdref cj expected_type;
- { uj_val = mkCast (cj.uj_val, k, expected_type);
- uj_type = expected_type }
+ match Evarconv.cumul env sigma cj.uj_type expected_type with
+ | None ->
+ error_actual_type_core env sigma cj expected_type;
+ | Some sigma ->
+ sigma, { uj_val = mkCast (cj.uj_val, k, expected_type);
+ uj_type = expected_type }
-let enrich_env env evdref =
- let penv = Environ.pre_env env in
- let penv' = Pre_env.({ penv with env_stratification =
- { penv.env_stratification with env_universes = Evd.universes !evdref } }) in
- Environ.env_of_pre_env penv'
+let enrich_env env sigma =
+ set_universes env @@ Evd.universes sigma
let check_fix env sigma pfix =
- let inj c = EConstr.to_constr sigma c in
+ let inj c = EConstr.to_constr ~abort_on_undefined_evars:false sigma c in
let (idx, (ids, cs, ts)) = pfix in
check_fix env (idx, (ids, Array.map inj cs, Array.map inj ts))
@@ -226,10 +241,6 @@ let judge_of_set =
{ uj_val = EConstr.mkSet;
uj_type = EConstr.mkSort Sorts.type1 }
-let judge_of_prop_contents = function
- | Null -> judge_of_prop
- | Pos -> judge_of_set
-
let judge_of_type u =
let uu = Univ.Universe.super u in
{ uj_val = EConstr.mkType u;
@@ -242,16 +253,16 @@ let judge_of_variable env id =
Termops.on_judgment EConstr.of_constr (judge_of_variable env id)
let judge_of_projection env sigma p cj =
- let pb = lookup_projection p env in
+ let pty = lookup_projection p env in
let (ind,u), args =
try find_mrectype env sigma cj.uj_type
with Not_found -> error_case_not_inductive env sigma cj
in
let u = EInstance.kind sigma u in
- let ty = EConstr.of_constr (CVars.subst_instance_constr u pb.Declarations.proj_type) in
- let ty = substl (cj.uj_val :: List.rev args) ty in
- {uj_val = EConstr.mkProj (p,cj.uj_val);
- uj_type = ty}
+ let ty = EConstr.of_constr (CVars.subst_instance_constr u pty) in
+ let ty = substl (cj.uj_val :: List.rev args) ty in
+ {uj_val = EConstr.mkProj (p,cj.uj_val);
+ uj_type = ty}
let judge_of_abstraction env name var j =
{ uj_val = mkLambda (name, var.utj_val, j.uj_val);
@@ -268,165 +279,166 @@ let judge_of_letin env name defj typj j =
(* cstr must be in n.f. w.r.t. evars and execute returns a judgement
where both the term and type are in n.f. *)
-let rec execute env evdref cstr =
- let cstr = whd_evar !evdref cstr in
- match EConstr.kind !evdref cstr with
+let rec execute env sigma cstr =
+ let cstr = whd_evar sigma cstr in
+ match EConstr.kind sigma cstr with
| Meta n ->
- { uj_val = cstr; uj_type = meta_type !evdref n }
+ sigma, { uj_val = cstr; uj_type = meta_type sigma n }
| Evar ev ->
- let ty = EConstr.existential_type !evdref ev in
- let jty = execute env evdref ty in
- let jty = e_assumption_of_judgment env evdref jty in
- { uj_val = cstr; uj_type = jty }
+ let ty = EConstr.existential_type sigma ev in
+ let sigma, jty = execute env sigma ty in
+ let sigma, jty = assumption_of_judgment env sigma jty in
+ sigma, { uj_val = cstr; uj_type = jty }
| Rel n ->
- judge_of_relative env n
+ sigma, judge_of_relative env n
| Var id ->
- judge_of_variable env id
+ sigma, judge_of_variable env id
| Const (c, u) ->
- let u = EInstance.kind !evdref u in
- make_judge cstr (EConstr.of_constr (rename_type_of_constant env (c, u)))
+ let u = EInstance.kind sigma u in
+ sigma, make_judge cstr (EConstr.of_constr (rename_type_of_constant env (c, u)))
| Ind (ind, u) ->
- let u = EInstance.kind !evdref u in
- make_judge cstr (EConstr.of_constr (rename_type_of_inductive env (ind, u)))
+ let u = EInstance.kind sigma u in
+ sigma, make_judge cstr (EConstr.of_constr (rename_type_of_inductive env (ind, u)))
| Construct (cstruct, u) ->
- let u = EInstance.kind !evdref u in
- make_judge cstr (EConstr.of_constr (rename_type_of_constructor env (cstruct, u)))
+ let u = EInstance.kind sigma u in
+ sigma, make_judge cstr (EConstr.of_constr (rename_type_of_constructor env (cstruct, u)))
| Case (ci,p,c,lf) ->
- let cj = execute env evdref c in
- let pj = execute env evdref p in
- let lfj = execute_array env evdref lf in
- e_judge_of_case env evdref ci pj cj lfj
+ let sigma, cj = execute env sigma c in
+ let sigma, pj = execute env sigma p in
+ let sigma, lfj = execute_array env sigma lf in
+ judge_of_case env sigma ci pj cj lfj
| Fix ((vn,i as vni),recdef) ->
- let (_,tys,_ as recdef') = execute_recdef env evdref recdef in
+ let sigma, (_,tys,_ as recdef') = execute_recdef env sigma recdef in
let fix = (vni,recdef') in
- check_fix env !evdref fix;
- make_judge (mkFix fix) tys.(i)
+ check_fix env sigma fix;
+ sigma, make_judge (mkFix fix) tys.(i)
| CoFix (i,recdef) ->
- let (_,tys,_ as recdef') = execute_recdef env evdref recdef in
+ let sigma, (_,tys,_ as recdef') = execute_recdef env sigma recdef in
let cofix = (i,recdef') in
- check_cofix env !evdref cofix;
- make_judge (mkCoFix cofix) tys.(i)
+ check_cofix env sigma cofix;
+ sigma, make_judge (mkCoFix cofix) tys.(i)
| Sort s ->
- begin match ESorts.kind !evdref s with
- | Prop c ->
- judge_of_prop_contents c
- | Type u ->
- judge_of_type u
+ begin match ESorts.kind sigma s with
+ | Prop -> sigma, judge_of_prop
+ | Set -> sigma, judge_of_set
+ | Type u -> sigma, judge_of_type u
end
| Proj (p, c) ->
- let cj = execute env evdref c in
- judge_of_projection env !evdref p cj
+ let sigma, cj = execute env sigma c in
+ sigma, judge_of_projection env sigma p cj
| App (f,args) ->
- let jl = execute_array env evdref args in
- (match EConstr.kind !evdref f with
+ let sigma, jl = execute_array env sigma args in
+ (match EConstr.kind sigma f with
| Ind (ind, u) when EInstance.is_empty u && Environ.template_polymorphic_ind ind env ->
- let fj = execute env evdref f in
- e_judge_of_applied_inductive_knowing_parameters env evdref fj (ind, u) jl
+ let sigma, fj = execute env sigma f in
+ judge_of_applied_inductive_knowing_parameters env sigma fj (ind, u) jl
| _ ->
(* No template polymorphism *)
- let fj = execute env evdref f in
- e_judge_of_apply env evdref fj jl)
+ let sigma, fj = execute env sigma f in
+ judge_of_apply env sigma fj jl)
| Lambda (name,c1,c2) ->
- let j = execute env evdref c1 in
- let var = e_type_judgment env evdref j in
+ let sigma, j = execute env sigma c1 in
+ let sigma, var = type_judgment env sigma j in
let env1 = push_rel (LocalAssum (name, var.utj_val)) env in
- let j' = execute env1 evdref c2 in
- judge_of_abstraction env1 name var j'
+ let sigma, j' = execute env1 sigma c2 in
+ sigma, judge_of_abstraction env1 name var j'
| Prod (name,c1,c2) ->
- let j = execute env evdref c1 in
- let varj = e_type_judgment env evdref j in
+ let sigma, j = execute env sigma c1 in
+ let sigma, varj = type_judgment env sigma j in
let env1 = push_rel (LocalAssum (name, varj.utj_val)) env in
- let j' = execute env1 evdref c2 in
- let varj' = e_type_judgment env1 evdref j' in
- judge_of_product env name varj varj'
+ let sigma, j' = execute env1 sigma c2 in
+ let sigma, varj' = type_judgment env1 sigma j' in
+ sigma, judge_of_product env name varj varj'
| LetIn (name,c1,c2,c3) ->
- let j1 = execute env evdref c1 in
- let j2 = execute env evdref c2 in
- let j2 = e_type_judgment env evdref j2 in
- let _ = e_judge_of_cast env evdref j1 DEFAULTcast j2 in
+ let sigma, j1 = execute env sigma c1 in
+ let sigma, j2 = execute env sigma c2 in
+ let sigma, j2 = type_judgment env sigma j2 in
+ let sigma, _ = judge_of_cast env sigma j1 DEFAULTcast j2 in
let env1 = push_rel (LocalDef (name, j1.uj_val, j2.utj_val)) env in
- let j3 = execute env1 evdref c3 in
- judge_of_letin env name j1 j2 j3
+ let sigma, j3 = execute env1 sigma c3 in
+ sigma, judge_of_letin env name j1 j2 j3
| Cast (c,k,t) ->
- let cj = execute env evdref c in
- let tj = execute env evdref t in
- let tj = e_type_judgment env evdref tj in
- e_judge_of_cast env evdref cj k tj
-
-and execute_recdef env evdref (names,lar,vdef) =
- let larj = execute_array env evdref lar in
- let lara = Array.map (e_assumption_of_judgment env evdref) larj in
+ let sigma, cj = execute env sigma c in
+ let sigma, tj = execute env sigma t in
+ let sigma, tj = type_judgment env sigma tj in
+ judge_of_cast env sigma cj k tj
+
+and execute_recdef env sigma (names,lar,vdef) =
+ let sigma, larj = execute_array env sigma lar in
+ let sigma, lara = Array.fold_left_map (assumption_of_judgment env) sigma larj in
let env1 = push_rec_types (names,lara,vdef) env in
- let vdefj = execute_array env1 evdref vdef in
+ let sigma, vdefj = execute_array env1 sigma vdef in
let vdefv = Array.map j_val vdefj in
- let _ = check_type_fixpoint env1 evdref names lara vdefj in
- (names,lara,vdefv)
+ let sigma = check_type_fixpoint env1 sigma names lara vdefj in
+ sigma, (names,lara,vdefv)
+
+and execute_array env = Array.fold_left_map (execute env)
-and execute_array env evdref = Array.map (execute env evdref)
+let check env sigma c t =
+ let env = enrich_env env sigma in
+ let sigma, j = execute env sigma c in
+ match Evarconv.cumul env sigma j.uj_type t with
+ | None ->
+ error_actual_type_core env sigma j t
+ | Some sigma -> sigma
let e_check env evdref c t =
- let env = enrich_env env evdref in
- let j = execute env evdref c in
- if not (Evarconv.e_cumul env evdref j.uj_type t) then
- error_actual_type_core env !evdref j t
+ evdref := check env !evdref c t
(* Type of a constr *)
-let unsafe_type_of env evd c =
- let evdref = ref evd in
- let env = enrich_env env evdref in
- let j = execute env evdref c in
- j.uj_type
+let unsafe_type_of env sigma c =
+ let env = enrich_env env sigma in
+ let sigma, j = execute env sigma c in
+ j.uj_type
(* Sort of a type *)
+let sort_of env sigma c =
+ let env = enrich_env env sigma in
+ let sigma, j = execute env sigma c in
+ let sigma, a = type_judgment env sigma j in
+ sigma, a.utj_type
+
let e_sort_of env evdref c =
- let env = enrich_env env evdref in
- let j = execute env evdref c in
- let a = e_type_judgment env evdref j in
- a.utj_type
+ Evarutil.evd_comb1 (sort_of env) evdref c
(* Try to solve the existential variables by typing *)
-let type_of ?(refresh=false) env evd c =
- let evdref = ref evd in
- let env = enrich_env env evdref in
- let j = execute env evdref c in
+let type_of ?(refresh=false) env sigma c =
+ let env = enrich_env env sigma in
+ let sigma, j = execute env sigma c in
(* side-effect on evdref *)
if refresh then
- Evarsolve.refresh_universes ~onlyalg:true (Some false) env !evdref j.uj_type
- else !evdref, j.uj_type
+ Evarsolve.refresh_universes ~onlyalg:true (Some false) env sigma j.uj_type
+ else sigma, j.uj_type
-let e_type_of ?(refresh=false) env evdref c =
- let env = enrich_env env evdref in
- let j = execute env evdref c in
+let e_type_of ?refresh env evdref c =
+ Evarutil.evd_comb1 (type_of ?refresh env) evdref c
+
+let solve_evars env sigma c =
+ let env = enrich_env env sigma in
+ let sigma, j = execute env sigma c in
(* side-effect on evdref *)
- if refresh then
- let evd, c = Evarsolve.refresh_universes ~onlyalg:true (Some false) env !evdref j.uj_type in
- let () = evdref := evd in
- c
- else j.uj_type
+ sigma, nf_evar sigma j.uj_val
let e_solve_evars env evdref c =
- let env = enrich_env env evdref in
- let c = (execute env evdref c).uj_val in
- (* side-effect on evdref *)
- nf_evar !evdref c
+ Evarutil.evd_comb1 (solve_evars env) evdref c
-let _ = Evarconv.set_solve_evars (fun env evdref c -> e_solve_evars env evdref c)
+let _ = Evarconv.set_solve_evars (fun env sigma c -> solve_evars env sigma c)
diff --git a/pretyping/typing.mli b/pretyping/typing.mli
index 0ff724a1..3cf43ace 100644
--- a/pretyping/typing.mli
+++ b/pretyping/typing.mli
@@ -26,18 +26,25 @@ val type_of : ?refresh:bool -> env -> evar_map -> constr -> evar_map * types
(** Variant of [type_of] using references instead of state-passing. *)
val e_type_of : ?refresh:bool -> env -> evar_map ref -> constr -> types
+[@@ocaml.deprecated "Use [Typing.type_of]"]
(** Typecheck a type and return its sort *)
+val sort_of : env -> evar_map -> types -> evar_map * Sorts.t
val e_sort_of : env -> evar_map ref -> types -> Sorts.t
+[@@ocaml.deprecated "Use [Typing.sort_of]"]
(** Typecheck a term has a given type (assuming the type is OK) *)
+val check : env -> evar_map -> constr -> types -> evar_map
val e_check : env -> evar_map ref -> constr -> types -> unit
+[@@ocaml.deprecated "Use [Typing.check]"]
(** Returns the instantiated type of a metavariable *)
val meta_type : evar_map -> metavariable -> types
(** Solve existential variables using typing *)
+val solve_evars : env -> evar_map -> constr -> evar_map * constr
val e_solve_evars : env -> evar_map ref -> constr -> constr
+[@@ocaml.deprecated "Use [Typing.solve_evars]"]
(** Raise an error message if incorrect elimination for this inductive *)
(** (first constr is term to match, second is return predicate) *)
@@ -46,8 +53,8 @@ val check_allowed_sort : env -> evar_map -> pinductive -> constr -> constr ->
(** Raise an error message if bodies have types not unifiable with the
expected ones *)
-val check_type_fixpoint : ?loc:Loc.t -> env -> evar_map ref ->
- Names.Name.t array -> types array -> unsafe_judgment array -> unit
+val check_type_fixpoint : ?loc:Loc.t -> env -> evar_map ->
+ Names.Name.t array -> types array -> unsafe_judgment array -> evar_map
val judge_of_prop : unsafe_judgment
val judge_of_set : unsafe_judgment
@@ -55,3 +62,4 @@ val judge_of_abstraction : Environ.env -> Name.t ->
unsafe_type_judgment -> unsafe_judgment -> unsafe_judgment
val judge_of_product : Environ.env -> Name.t ->
unsafe_type_judgment -> unsafe_type_judgment -> unsafe_judgment
+val judge_of_projection : env -> evar_map -> Projection.t -> unsafe_judgment -> unsafe_judgment
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index 6f594186..4665486f 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -84,7 +84,7 @@ let occur_meta_or_undefined_evar evd c =
| Evar (ev,args) ->
(match evar_body (Evd.find evd ev) with
| Evar_defined c ->
- occrec c; Array.iter occrec args
+ occrec (EConstr.Unsafe.to_constr c); Array.iter occrec args
| Evar_empty -> raise Occur)
| _ -> Constr.iter occrec c
in try occrec c; false with Occur | Not_found -> true
@@ -189,18 +189,14 @@ let pose_all_metas_as_evars env evd t =
let rec aux t = match EConstr.kind !evdref t with
| Meta mv ->
(match Evd.meta_opt_fvalue !evdref mv with
- | Some ({rebus=c},_) -> EConstr.of_constr c
+ | Some ({rebus=c},_) -> c
| None ->
let {rebus=ty;freemetas=mvs} = Evd.meta_ftype evd mv in
- let ty = EConstr.of_constr ty in
let ty = if Evd.Metaset.is_empty mvs then ty else aux ty in
- let ty =
- if Flags.version_strictly_greater Flags.V8_6
- then nf_betaiota env evd ty (* How it was in Coq <= 8.4 (but done in logic.ml at this time) *)
- else ty (* some beta-iota-normalization "regression" in 8.5 and 8.6 *) in
+ let ty = nf_betaiota env evd ty in
let src = Evd.evar_source_of_meta mv !evdref in
- let ev = Evarutil.e_new_evar env evdref ~src ty in
- evdref := meta_assign mv (EConstr.Unsafe.to_constr ev,(Conv,TypeNotProcessed)) !evdref;
+ let evd, ev = Evarutil.new_evar env !evdref ~src ty in
+ evdref := meta_assign mv (ev,(Conv,TypeNotProcessed)) evd;
ev)
| _ ->
EConstr.map !evdref aux t in
@@ -399,8 +395,13 @@ let default_no_delta_core_unify_flags () = { (default_core_unify_flags ()) with
modulo_betaiota = false;
}
-let default_no_delta_unify_flags () =
- let flags = default_no_delta_core_unify_flags () in {
+let default_no_delta_unify_flags ts =
+ let flags = default_no_delta_core_unify_flags () in
+ let flags = { flags with
+ modulo_conv_on_closed_terms = Some ts;
+ modulo_delta_types = ts
+ } in
+ {
core_unify_flags = flags;
merge_unify_flags = flags;
subterm_unify_flags = flags;
@@ -474,12 +475,8 @@ let expand_table_key env = function
| RelKey _ -> None
let unfold_projection env p stk =
- (match try Some (lookup_projection p env) with Not_found -> None with
- | Some pb ->
- let s = Stack.Proj (pb.Declarations.proj_npars, pb.Declarations.proj_arg,
- p, Cst_stack.empty) in
- s :: stk
- | None -> assert false)
+ let s = Stack.Proj (p, Cst_stack.empty) in
+ s :: stk
let expand_key ts env sigma = function
| Some (IsKey k) -> Option.map EConstr.of_constr (expand_table_key env k)
@@ -508,7 +505,7 @@ let key_of env sigma b flags f =
match EConstr.kind sigma f with
| Const (cst, u) when is_transparent env (ConstKey cst) &&
(Cpred.mem cst (snd flags.modulo_delta)
- || Environ.is_projection cst env) ->
+ || Recordops.is_primitive_projection cst) ->
let u = EInstance.kind sigma u in
Some (IsKey (ConstKey (cst, u)))
| Var id when is_transparent env (VarKey id) &&
@@ -562,16 +559,16 @@ let is_rigid_head sigma flags t =
| Proj (_, _) -> false (* Why aren't Prod, Sort rigid heads ? *)
let force_eqs c =
- let open Universes in
- Constraints.fold
+ let open UnivProblem in
+ Set.fold
(fun c acc ->
let c' = match c with
(* Should we be forcing weak constraints? *)
| ULub (l, r) | UWeak (l, r) -> UEq (Univ.Universe.make l,Univ.Universe.make r)
| ULe _ | UEq _ -> c
in
- Constraints.add c' acc)
- c Constraints.empty
+ Set.add c' acc)
+ c Set.empty
let constr_cmp pb env sigma flags t u =
let cstrs =
@@ -580,16 +577,16 @@ let constr_cmp pb env sigma flags t u =
in
match cstrs with
| Some cstrs ->
- begin try Evd.add_universe_constraints sigma cstrs, true
- with Univ.UniverseInconsistency _ -> sigma, false
+ begin try Some (Evd.add_universe_constraints sigma cstrs)
+ with Univ.UniverseInconsistency _ -> None
| Evd.UniversesDiffer ->
if is_rigid_head sigma flags t then
- try Evd.add_universe_constraints sigma (force_eqs cstrs), true
- with Univ.UniverseInconsistency _ -> sigma, false
- else sigma, false
+ try Some (Evd.add_universe_constraints sigma (force_eqs cstrs))
+ with Univ.UniverseInconsistency _ -> None
+ else None
end
| None ->
- sigma, false
+ None
let do_reduce ts (env, nb) sigma c =
Stack.zip sigma (fst (whd_betaiota_deltazeta_for_iota_state
@@ -624,9 +621,9 @@ let check_compatibility env pbty flags (sigma,metasubst,evarsubst : subst0) tyM
| None -> sigma
| Some n ->
if is_ground_term sigma m && is_ground_term sigma n then
- let sigma, b = infer_conv ~pb:pbty ~ts:flags.modulo_delta_types env sigma m n in
- if b then sigma
- else error_cannot_unify env sigma (m,n)
+ match infer_conv ~pb:pbty ~ts:flags.modulo_delta_types env sigma m n with
+ | Some sigma -> sigma
+ | None -> error_cannot_unify env sigma (m,n)
else sigma
@@ -652,10 +649,12 @@ let rec is_neutral env sigma ts t =
let is_eta_constructor_app env sigma ts f l1 term =
match EConstr.kind sigma f with
- | Construct (((_, i as ind), j), u) when i == 0 && j == 1 ->
+ | Construct (((_, i as ind), j), u) when j == 1 ->
+ let open Declarations in
let mib = lookup_mind (fst ind) env in
(match mib.Declarations.mind_record with
- | Some (Some (_,exp,projs)) when mib.Declarations.mind_finite == Declarations.BiFinite &&
+ | PrimRecord info when mib.Declarations.mind_finite == Declarations.BiFinite &&
+ let (_, projs, _) = info.(i) in
Array.length projs == Array.length l1 - mib.Declarations.mind_nparams ->
(** Check that the other term is neutral *)
is_neutral env sigma ts term
@@ -666,12 +665,12 @@ let eta_constructor_app env sigma f l1 term =
match EConstr.kind sigma f with
| Construct (((_, i as ind), j), u) ->
let mib = lookup_mind (fst ind) env in
- (match mib.Declarations.mind_record with
- | Some (Some (_, projs, _)) ->
+ (match get_projections env ind with
+ | Some projs ->
let npars = mib.Declarations.mind_nparams in
let pars, l1' = Array.chop npars l1 in
let arg = Array.append pars [|term|] in
- let l2 = Array.map (fun p -> mkApp (mkConstU (p,u), arg)) projs in
+ let l2 = Array.map (fun p -> mkApp (mkConstU (Projection.Repr.constant p,u), arg)) projs in
l1', l2
| _ -> assert false)
| _ -> assert false
@@ -682,8 +681,10 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
and cN = Evarutil.whd_head_evar sigma curn in
let () =
if !debug_unification then
- Feedback.msg_debug (print_constr_env curenv sigma cM ++ str" ~= " ++ print_constr_env curenv sigma cN)
- in
+ Feedback.msg_debug (
+ Termops.Internal.print_constr_env curenv sigma cM ++ str" ~= " ++
+ Termops.Internal.print_constr_env curenv sigma cN)
+ in
match (EConstr.kind sigma cM, EConstr.kind sigma cN) with
| Meta k1, Meta k2 ->
if Int.equal k1 k2 then substn else
@@ -699,7 +700,7 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
if k2 < k1 then sigma,(k1,cN,stN)::metasubst,evarsubst
else sigma,(k2,cM,stM)::metasubst,evarsubst
| Meta k, _
- when not (dependent sigma cM cN) (* helps early trying alternatives *) ->
+ when not (occur_metavariable sigma k cN) (* helps early trying alternatives *) ->
let sigma =
if opt.with_types && flags.check_applied_meta_types then
(try
@@ -719,7 +720,7 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
evarsubst)
else error_cannot_unify_local curenv sigma (m,n,cN)
| _, Meta k
- when not (dependent sigma cN cM) (* helps early trying alternatives *) ->
+ when not (occur_metavariable sigma k cM) (* helps early trying alternatives *) ->
let sigma =
if opt.with_types && flags.check_applied_meta_types then
(try
@@ -741,11 +742,12 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
| Evar (evk,_ as ev), Evar (evk',_)
when not (Evar.Set.mem evk flags.frozen_evars)
&& Evar.equal evk evk' ->
- let sigma',b = constr_cmp cv_pb env sigma flags cM cN in
- if b then
- sigma',metasubst,evarsubst
- else
+ begin match constr_cmp cv_pb env sigma flags cM cN with
+ | Some sigma ->
+ sigma, metasubst, evarsubst
+ | None ->
sigma,metasubst,((curenv,ev,cN)::evarsubst)
+ end
| Evar (evk,_ as ev), _
when not (Evar.Set.mem evk flags.frozen_evars)
&& not (occur_evar sigma evk cN) ->
@@ -838,6 +840,26 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
with ex when precatchable_exception ex ->
reduce curenvnb pb opt substn cM cN)
+ | Fix ((ln1,i1),(lna1,tl1,bl1)), Fix ((ln2,i2),(_,tl2,bl2)) when
+ Int.equal i1 i2 && Array.equal Int.equal ln1 ln2 ->
+ (try
+ let opt' = {opt with at_top = true; with_types = false} in
+ let curenvnb' = Array.fold_right2 (fun na t -> push (na,t)) lna1 tl1 curenvnb in
+ Array.fold_left2 (unirec_rec curenvnb' CONV opt')
+ (Array.fold_left2 (unirec_rec curenvnb CONV opt') substn tl1 tl2) bl1 bl2
+ with ex when precatchable_exception ex ->
+ reduce curenvnb pb opt substn cM cN)
+
+ | CoFix (i1,(lna1,tl1,bl1)), CoFix (i2,(_,tl2,bl2)) when
+ Int.equal i1 i2 ->
+ (try
+ let opt' = {opt with at_top = true; with_types = false} in
+ let curenvnb' = Array.fold_right2 (fun na t -> push (na,t)) lna1 tl1 curenvnb in
+ Array.fold_left2 (unirec_rec curenvnb' CONV opt')
+ (Array.fold_left2 (unirec_rec curenvnb CONV opt') substn tl1 tl2) bl1 bl2
+ with ex when precatchable_exception ex ->
+ reduce curenvnb pb opt substn cM cN)
+
| App (f1,l1), _ when
(isMeta sigma f1 && use_metas_pattern_unification sigma flags nb l1
|| use_evars_pattern_unification flags && isAllowedEvar sigma flags f1) ->
@@ -923,9 +945,9 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
and unify_not_same_head curenvnb pb opt (sigma, metas, evars as substn : subst0) cM cN =
try canonical_projections curenvnb pb opt cM cN substn
with ex when precatchable_exception ex ->
- let sigma', b = constr_cmp cv_pb env sigma flags cM cN in
- if b then (sigma', metas, evars)
- else
+ match constr_cmp cv_pb env sigma flags cM cN with
+ | Some sigma -> (sigma, metas, evars)
+ | None ->
try reduce curenvnb pb opt substn cM cN
with ex when precatchable_exception ex ->
let (f1,l1) =
@@ -982,12 +1004,13 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
(* Renounce, maybe metas/evars prevents typing *) sigma
else sigma
in
- let sigma, b = infer_conv ~pb ~ts:convflags curenv sigma m1 n1 in
- if b then Some (sigma, metasubst, evarsubst)
- else
- if is_ground_term sigma m1 && is_ground_term sigma n1 then
- error_cannot_unify curenv sigma (cM,cN)
- else None
+ match infer_conv ~pb ~ts:convflags curenv sigma m1 n1 with
+ | Some sigma ->
+ Some (sigma, metasubst, evarsubst)
+ | None ->
+ if is_ground_term sigma m1 && is_ground_term sigma n1 then
+ error_cannot_unify curenv sigma (cM,cN)
+ else None
in
match res with
| Some substn -> substn
@@ -1060,7 +1083,7 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
(evd,t2::ks, m-1)
else
let mv = new_meta () in
- let evd' = meta_declare mv (EConstr.Unsafe.to_constr (substl ks b)) evd in
+ let evd' = meta_declare mv (substl ks b) evd in
(evd', mkMeta mv :: ks, m - 1))
(sigma,[],List.length bs) bs
in
@@ -1090,11 +1113,13 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
then
None
else
- let sigma, b = match flags.modulo_conv_on_closed_terms with
+ let ans = match flags.modulo_conv_on_closed_terms with
| Some convflags -> infer_conv ~pb:cv_pb ~ts:convflags env sigma m n
| _ -> constr_cmp cv_pb env sigma flags m n in
- if b then Some sigma
- else if (match flags.modulo_conv_on_closed_terms, flags.modulo_delta with
+ match ans with
+ | Some sigma -> ans
+ | None ->
+ if (match flags.modulo_conv_on_closed_terms, flags.modulo_delta with
| Some (cv_id, cv_k), (dl_id, dl_k) ->
Id.Pred.subset dl_id cv_id && Cpred.subset dl_k cv_k
| None,(dl_id, dl_k) ->
@@ -1247,7 +1272,7 @@ let try_to_coerce env evd c cty tycon =
let j = make_judge c cty in
let (evd',j') = inh_conv_coerce_rigid_to true env evd j tycon in
let evd' = Evarconv.solve_unif_constraints_with_heuristics env evd' in
- let evd' = Evd.map_metas_fvalue (fun c -> EConstr.Unsafe.to_constr (nf_evar evd' (EConstr.of_constr c))) evd' in
+ let evd' = Evd.map_metas_fvalue (fun c -> nf_evar evd' c) evd' in
(evd',j'.uj_val)
let w_coerce_to_type env evd c cty mvty =
@@ -1359,11 +1384,11 @@ let w_merge env with_types flags (evd,metas,evars : subst0) =
if meta_defined evd mv then
let {rebus=c'},(status',_) = meta_fvalue evd mv in
let (take_left,st,(evd,metas',evars')) =
- merge_instances env evd flags status' status (EConstr.of_constr c') c
+ merge_instances env evd flags status' status c' c
in
let evd' =
if take_left then evd
- else meta_reassign mv (EConstr.Unsafe.to_constr c,(st,TypeProcessed)) evd
+ else meta_reassign mv (c,(st,TypeProcessed)) evd
in
w_merge_rec evd' (metas'@metas@metas'') (evars'@evars'') eqns
else
@@ -1372,7 +1397,7 @@ let w_merge env with_types flags (evd,metas,evars : subst0) =
if isMetaOf evd mv (whd_all env evd c) then evd
else error_cannot_unify env evd (mkMeta mv,c)
else
- meta_assign mv (EConstr.Unsafe.to_constr c,(status,TypeProcessed)) evd in
+ meta_assign mv (c,(status,TypeProcessed)) evd in
w_merge_rec evd' (metas''@metas) evars'' eqns
| [] ->
(* Process type eqns *)
@@ -1396,17 +1421,17 @@ let w_merge env with_types flags (evd,metas,evars : subst0) =
let (evd', c) = applyHead sp_env evd nargs hdc in
let (evd'',mc,ec) =
unify_0 sp_env evd' CUMUL flags
- (get_type_of sp_env evd' c) (EConstr.of_constr ev.evar_concl) in
+ (get_type_of sp_env evd' c) ev.evar_concl in
let evd''' = w_merge_rec evd'' mc ec [] in
if evd' == evd'''
- then Evd.define sp (EConstr.Unsafe.to_constr c) evd'''
- else Evd.define sp (EConstr.Unsafe.to_constr (Evarutil.nf_evar evd''' c)) evd''' in
+ then Evd.define sp c evd'''
+ else Evd.define sp (Evarutil.nf_evar evd''' c) evd''' in
let check_types evd =
let metas = Evd.meta_list evd in
let eqns = List.fold_left (fun acc (mv, b) ->
match b with
- | Clval (n, (t, (c, TypeNotProcessed)), v) -> (mv, c, EConstr.of_constr t.rebus) :: acc
+ | Clval (n, (t, (c, TypeNotProcessed)), v) -> (mv, c, t.rebus) :: acc
| _ -> acc) [] metas
in w_merge_rec evd [] [] eqns
in
@@ -1417,11 +1442,6 @@ let w_merge env with_types flags (evd,metas,evars : subst0) =
in
if with_types then check_types res else res
-let retract_coercible_metas evd =
- let (metas, evd) = retract_coercible_metas evd in
- let map (mv, c, st) = (mv, EConstr.of_constr c, st) in
- (List.map map metas, evd)
-
let w_unify_meta_types env ?(flags=default_unify_flags ()) evd =
let metas,evd = retract_coercible_metas evd in
w_merge env true flags.merge_unify_flags (evd,metas,[])
@@ -1506,12 +1526,12 @@ let indirectly_dependent sigma c d decls =
it is needed otherwise, as e.g. when abstracting over "2" in
"forall H:0=2, H=H:>(0=1+1) -> 0=2." where there is now obvious
way to see that the second hypothesis depends indirectly over 2 *)
- List.exists (fun d' -> dependent_in_decl sigma (EConstr.mkVar (NamedDecl.get_id d')) d) decls
+ let open Context.Named.Declaration in
+ List.exists (fun d' -> exists (fun c -> Termops.local_occur_var sigma (NamedDecl.get_id d') c) d) decls
let finish_evar_resolution ?(flags=Pretyping.all_and_fail_flags) env current_sigma (pending,c) =
let sigma = Pretyping.solve_remaining_evars flags env current_sigma pending in
- let sigma, subst = nf_univ_variables sigma in
- (sigma, EConstr.of_constr (Universes.subst_univs_constr subst (EConstr.Unsafe.to_constr (nf_evar sigma c))))
+ (sigma, nf_evar sigma c)
let default_matching_core_flags sigma =
let ts = Names.full_transparent_state in {
@@ -1589,8 +1609,10 @@ let make_pattern_test from_prefix_of_ind is_correct_type env sigma (pending,c) =
let merge_fun c1 c2 =
match c1, c2 with
| Some (evd,c1,x), Some (_,c2,_) ->
- let (evd,b) = infer_conv ~pb:CONV env evd c1 c2 in
- if b then Some (evd, c1, x) else raise (NotUnifiable None)
+ begin match infer_conv ~pb:CONV env evd c1 c2 with
+ | Some evd -> Some (evd, c1, x)
+ | None -> raise (NotUnifiable None)
+ end
| Some _, None -> c1
| None, Some _ -> c2
| None, None -> None in
@@ -1599,9 +1621,8 @@ let make_pattern_test from_prefix_of_ind is_correct_type env sigma (pending,c) =
(fun test -> match test.testing_state with
| None -> None
| Some (sigma,_,l) ->
- let c = applist (nf_evar sigma (local_strong whd_meta sigma c), l) in
- let univs, subst = nf_univ_variables sigma in
- Some (sigma,EConstr.of_constr (Universes.subst_univs_constr subst (EConstr.Unsafe.to_constr c))))
+ let c = applist (local_strong whd_meta sigma c, l) in
+ Some (sigma, c))
let make_eq_test env evd c =
let out cstr =
@@ -1908,10 +1929,11 @@ let secondOrderAbstraction env evd flags typ (p, oplist) =
let (evd',cllist) = w_unify_to_subterm_list env evd flags p oplist typ in
let typp = Typing.meta_type evd' p in
let evd',(pred,predtyp) = abstract_list_all env evd' typp typ cllist in
- let evd', b = infer_conv ~pb:CUMUL env evd' predtyp typp in
- if not b then
+ match infer_conv ~pb:CUMUL env evd' predtyp typp with
+ | None ->
error_wrong_abstraction_type env evd'
(Evd.meta_name evd p) pred typp predtyp;
+ | Some evd' ->
w_merge env false flags.merge_unify_flags
(evd',[p,pred,(Conv,TypeProcessed)],[])
diff --git a/pretyping/unification.mli b/pretyping/unification.mli
index 16ce5c93..e2e261ae 100644
--- a/pretyping/unification.mli
+++ b/pretyping/unification.mli
@@ -8,6 +8,7 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+open Names
open Constr
open EConstr
open Environ
@@ -40,7 +41,7 @@ val default_core_unify_flags : unit -> core_unify_flags
val default_no_delta_core_unify_flags : unit -> core_unify_flags
val default_unify_flags : unit -> unify_flags
-val default_no_delta_unify_flags : unit -> unify_flags
+val default_no_delta_unify_flags : transparent_state -> unify_flags
val elim_flags : unit -> unify_flags
val elim_no_delta_flags : unit -> unify_flags
diff --git a/pretyping/univdecls.ml b/pretyping/univdecls.ml
deleted file mode 100644
index 8864be57..00000000
--- a/pretyping/univdecls.ml
+++ /dev/null
@@ -1,52 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open CErrors
-
-(** Local universes and constraints declarations *)
-type universe_decl =
- (Misctypes.lident list, Univ.Constraint.t) Misctypes.gen_universe_decl
-
-let default_univ_decl =
- let open Misctypes in
- { univdecl_instance = [];
- univdecl_extensible_instance = true;
- univdecl_constraints = Univ.Constraint.empty;
- univdecl_extensible_constraints = true }
-
-let interp_univ_constraints env evd cstrs =
- let interp (evd,cstrs) (u, d, u') =
- let ul = Pretyping.interp_known_glob_level evd u in
- let u'l = Pretyping.interp_known_glob_level evd u' in
- let cstr = (ul,d,u'l) in
- let cstrs' = Univ.Constraint.add cstr cstrs in
- try let evd = Evd.add_constraints evd (Univ.Constraint.singleton cstr) in
- evd, cstrs'
- with Univ.UniverseInconsistency e ->
- user_err ~hdr:"interp_constraint"
- (Univ.explain_universe_inconsistency (Termops.pr_evd_level evd) e)
- in
- List.fold_left interp (evd,Univ.Constraint.empty) cstrs
-
-let interp_univ_decl env decl =
- let open Misctypes in
- let pl : lident list = decl.univdecl_instance in
- let evd = Evd.from_ctx (UState.make_with_initial_binders (Environ.universes env) pl) in
- let evd, cstrs = interp_univ_constraints env evd decl.univdecl_constraints in
- let decl = { univdecl_instance = pl;
- univdecl_extensible_instance = decl.univdecl_extensible_instance;
- univdecl_constraints = cstrs;
- univdecl_extensible_constraints = decl.univdecl_extensible_constraints }
- in evd, decl
-
-let interp_univ_decl_opt env l =
- match l with
- | None -> Evd.from_env env, default_univ_decl
- | Some decl -> interp_univ_decl env decl
diff --git a/pretyping/univdecls.mli b/pretyping/univdecls.mli
deleted file mode 100644
index 305d045b..00000000
--- a/pretyping/univdecls.mli
+++ /dev/null
@@ -1,21 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-(** Local universe and constraint declarations. *)
-type universe_decl =
- (Misctypes.lident list, Univ.Constraint.t) Misctypes.gen_universe_decl
-
-val default_univ_decl : universe_decl
-
-val interp_univ_decl : Environ.env -> Constrexpr.universe_decl_expr ->
- Evd.evar_map * universe_decl
-
-val interp_univ_decl_opt : Environ.env -> Constrexpr.universe_decl_expr option ->
- Evd.evar_map * universe_decl
diff --git a/pretyping/vnorm.ml b/pretyping/vnorm.ml
index c53305e2..82c732c5 100644
--- a/pretyping/vnorm.ml
+++ b/pretyping/vnorm.ml
@@ -79,7 +79,7 @@ let construct_of_constr const env tag typ =
(* spiwack : here be a branch for specific decompilation handled by retroknowledge *)
try
if const then
- ((retroknowledge Retroknowledge.get_vm_decompile_constant_info env (mkIndU indu) tag),
+ ((Retroknowledge.get_vm_decompile_constant_info env.retroknowledge (mkIndU indu) tag),
typ) (*spiwack: this may need to be changed in case there are parameters in the
type which may cause a constant value to have an arity.
(type_constructor seems to be all about parameters actually)
@@ -103,7 +103,7 @@ let construct_of_constr_block = construct_of_constr false
let type_of_ind env (ind, u) =
type_of_inductive env (Inductive.lookup_mind_specif env ind, u)
-let build_branches_type env sigma (mind,_ as _ind) mib mip u params dep p =
+let build_branches_type env sigma (mind,_ as _ind) mib mip u params p =
let rtbl = mip.mind_reloc_tbl in
(* [build_one_branch i cty] construit le type de la ieme branche (commence
a 0) et les lambda correspondant aux realargs *)
@@ -120,20 +120,17 @@ let build_branches_type env sigma (mind,_ as _ind) mib mip u params dep p =
let codom =
let ndecl = List.length decl in
let papp = mkApp(lift ndecl p,crealargs) in
- if dep then
- let cstr = ith_constructor_of_inductive ind (i+1) in
- let relargs = Array.init carity (fun i -> mkRel (carity-i)) in
- let params = Array.map (lift ndecl) params in
- let dep_cstr = mkApp(mkApp(mkConstructU (cstr,u),params),relargs) in
- mkApp(papp,[|dep_cstr|])
- else papp
+ let cstr = ith_constructor_of_inductive ind (i+1) in
+ let relargs = Array.init carity (fun i -> mkRel (carity-i)) in
+ let params = Array.map (lift ndecl) params in
+ let dep_cstr = mkApp(mkApp(mkConstructU (cstr,u),params),relargs) in
+ mkApp(papp,[|dep_cstr|])
in
decl, decl_with_letin, codom
in Array.mapi build_one_branch mip.mind_nf_lc
-let build_case_type dep p realargs c =
- if dep then mkApp(mkApp(p, realargs), [|c|])
- else mkApp(p, realargs)
+let build_case_type p realargs c =
+ mkApp(mkApp(p, realargs), [|c|])
(* La fonction de normalisation *)
@@ -164,9 +161,9 @@ and nf_whd env sigma whd typ =
| Vconstr_block b ->
let tag = btag b in
let (tag,ofs) =
- if tag = Cbytecodes.last_variant_tag then
+ if tag = Obj.last_non_constant_constructor_tag then
match whd_val (bfield b 0) with
- | Vconstr_const tag -> (tag+Cbytecodes.last_variant_tag, 1)
+ | Vconstr_const tag -> (tag+Obj.last_non_constant_constructor_tag, 1)
| _ -> assert false
else (tag, 0) in
let capp,ctyp = construct_of_constr_block env tag typ in
@@ -205,7 +202,7 @@ and nf_univ_args ~nb_univs mk env sigma stk =
and nf_evar env sigma evk stk =
let evi = try Evd.find sigma evk with Not_found -> assert false in
let hyps = Environ.named_context_of_val (Evd.evar_filtered_hyps evi) in
- let concl = Evd.evar_concl evi in
+ let concl = EConstr.Unsafe.to_constr @@ Evd.evar_concl evi in
if List.is_empty hyps then
nf_stk env sigma (mkEvar (evk, [||])) concl stk
else match stk with
@@ -214,11 +211,7 @@ and nf_evar env sigma evk stk =
really an invariant? *)
(** Let-bound arguments are present in the evar arguments but not in the
type, so we turn the let into a product. *)
- let drop_body = function
- | NamedDecl.LocalAssum _ as d -> d
- | NamedDecl.LocalDef (na, _, t) -> NamedDecl.LocalAssum (na, t)
- in
- let hyps = List.map drop_body hyps in
+ let hyps = Context.Named.drop_bodies hyps in
let fold accu d = Term.mkNamedProd_or_LetIn d accu in
let t = List.fold_left fold concl hyps in
let t, args = nf_args env sigma args t in
@@ -273,10 +266,9 @@ and nf_stk ?from:(from=0) env sigma c t stk =
let nparamdecls = Context.Rel.length (Inductive.inductive_paramdecls (mib,u)) in
let pT =
hnf_prod_applist_assum env nparamdecls (type_of_ind env (ind,u)) (Array.to_list params) in
- let pT = whd_all env pT in
- let dep, p = nf_predicate env sigma (ind,u) mip params (type_of_switch sw) pT in
+ let p = nf_predicate env sigma (ind,u) mip params (type_of_switch sw) pT in
(* Calcul du type des branches *)
- let btypes = build_branches_type env sigma ind mib mip u params dep p in
+ let btypes = build_branches_type env sigma ind mib mip u params p in
(* calcul des branches *)
let bsw = branch_of_switch (nb_rel env) sw in
let mkbranch i (n,v) =
@@ -285,8 +277,8 @@ and nf_stk ?from:(from=0) env sigma c t stk =
Termops.it_mkLambda_or_LetIn_from_no_LetIn b decl_with_letin
in
let branchs = Array.mapi mkbranch bsw in
- let tcase = build_case_type dep p realargs c in
- let ci = sw.sw_annot.Cbytecodes.ci in
+ let tcase = build_case_type p realargs c in
+ let ci = sw.sw_annot.Vmvalues.ci in
nf_stk env sigma (mkCase(ci, p, c, branchs)) tcase stk
| Zproj p :: stk ->
assert (from = 0) ;
@@ -295,15 +287,24 @@ and nf_stk ?from:(from=0) env sigma c t stk =
nf_stk env sigma (mkProj(p',c)) ty stk
and nf_predicate env sigma ind mip params v pT =
- match whd_val v, kind pT with
- | Vfun f, Prod _ ->
+ match kind (whd_allnolet env pT) with
+ | LetIn (name,b,t,pT) ->
+ let body =
+ nf_predicate (push_rel (LocalDef (name,b,t)) env) sigma ind mip params v pT in
+ mkLetIn (name,b,t,body)
+ | Prod (name,dom,codom) -> begin
+ match whd_val v with
+ | Vfun f ->
let k = nb_rel env in
let vb = reduce_fun k f in
- let name,dom,codom = decompose_prod env pT in
- let dep,body =
+ let body =
nf_predicate (push_rel (LocalAssum (name,dom)) env) sigma ind mip params vb codom in
- dep, mkLambda(name,dom,body)
- | Vfun f, _ ->
+ mkLambda(name,dom,body)
+ | _ -> assert false
+ end
+ | _ ->
+ match whd_val v with
+ | Vfun f ->
let k = nb_rel env in
let vb = reduce_fun k f in
let name = Name (Id.of_string "c") in
@@ -312,8 +313,8 @@ and nf_predicate env sigma ind mip params v pT =
let params = if Int.equal n 0 then params else Array.map (lift n) params in
let dom = mkApp(mkIndU ind,Array.append params rargs) in
let body = nf_vtype (push_rel (LocalAssum (name,dom)) env) sigma vb in
- true, mkLambda(name,dom,body)
- | _, _ -> false, nf_val env sigma v crazy_type
+ mkLambda(name,dom,body)
+ | _ -> assert false
and nf_args env sigma vargs ?from:(f=0) t =
let t = ref t in
@@ -388,9 +389,9 @@ let cbv_vm env sigma c t =
if Termops.occur_meta sigma c then
CErrors.user_err Pp.(str "vm_compute does not support metas.");
(** This evar-normalizes terms beforehand *)
- let c = EConstr.to_constr sigma c in
- let t = EConstr.to_constr sigma t in
- let v = Vconv.val_of_constr env c in
+ let c = EConstr.to_constr ~abort_on_undefined_evars:false sigma c in
+ let t = EConstr.to_constr ~abort_on_undefined_evars:false sigma t in
+ let v = Csymtable.val_of_constr env c in
EConstr.of_constr (nf_val env sigma v t)
let vm_infer_conv ?(pb=Reduction.CUMUL) env sigma t1 t2 =
diff --git a/printing/genprint.ml b/printing/genprint.ml
index 1bb7838a..fa53a879 100644
--- a/printing/genprint.ml
+++ b/printing/genprint.ml
@@ -19,15 +19,15 @@ open Geninterp
(* Printing generic values *)
type 'a with_level =
- { default_already_surrounded : Notation_term.tolerability;
- default_ensure_surrounded : Notation_term.tolerability;
+ { default_already_surrounded : Notation_gram.tolerability;
+ default_ensure_surrounded : Notation_gram.tolerability;
printer : 'a }
type printer_result =
| PrinterBasic of (unit -> Pp.t)
-| PrinterNeedsLevel of (Notation_term.tolerability -> Pp.t) with_level
+| PrinterNeedsLevel of (Notation_gram.tolerability -> Pp.t) with_level
-type printer_fun_with_level = Environ.env -> Evd.evar_map -> Notation_term.tolerability -> Pp.t
+type printer_fun_with_level = Environ.env -> Evd.evar_map -> Notation_gram.tolerability -> Pp.t
type top_printer_result =
| TopPrinterBasic of (unit -> Pp.t)
diff --git a/printing/genprint.mli b/printing/genprint.mli
index fd5dd725..1a31025a 100644
--- a/printing/genprint.mli
+++ b/printing/genprint.mli
@@ -13,15 +13,15 @@
open Genarg
type 'a with_level =
- { default_already_surrounded : Notation_term.tolerability;
- default_ensure_surrounded : Notation_term.tolerability;
+ { default_already_surrounded : Notation_gram.tolerability;
+ default_ensure_surrounded : Notation_gram.tolerability;
printer : 'a }
type printer_result =
| PrinterBasic of (unit -> Pp.t)
-| PrinterNeedsLevel of (Notation_term.tolerability -> Pp.t) with_level
+| PrinterNeedsLevel of (Notation_gram.tolerability -> Pp.t) with_level
-type printer_fun_with_level = Environ.env -> Evd.evar_map -> Notation_term.tolerability -> Pp.t
+type printer_fun_with_level = Environ.env -> Evd.evar_map -> Notation_gram.tolerability -> Pp.t
type top_printer_result =
| TopPrinterBasic of (unit -> Pp.t)
diff --git a/printing/ppconstr.ml b/printing/ppconstr.ml
index 4c5d955c..90d2b7ab 100644
--- a/printing/ppconstr.ml
+++ b/printing/ppconstr.ml
@@ -18,11 +18,12 @@ open Nameops
open Libnames
open Pputils
open Ppextend
-open Notation_term
+open Glob_term
open Constrexpr
open Constrexpr_ops
+open Notation_gram
open Decl_kinds
-open Misctypes
+open Namegen
(*i*)
module Tag =
@@ -87,8 +88,6 @@ let tag_var = tag Tag.variable
| Numeral (_,b) -> if b then lposint else lnegint
| String _ -> latom
- open Notation
-
let print_hunks n pr pr_patt pr_binders (terms, termlists, binders, binderlists) unps =
let env = ref terms and envlist = ref termlists and bl = ref binders and bll = ref binderlists in
let pop r = let a = List.hd !r in r := List.tl !r; a in
@@ -160,7 +159,7 @@ let tag_var = tag Tag.variable
let pr_univ_expr = function
| Some (x,n) ->
- pr_reference x ++ (match n with 0 -> mt () | _ -> str"+" ++ int n)
+ pr_qualid x ++ (match n with 0 -> mt () | _ -> str"+" ++ int n)
| None -> str"_"
let pr_univ l =
@@ -170,18 +169,18 @@ let tag_var = tag Tag.variable
let pr_univ_annot pr x = str "@{" ++ pr x ++ str "}"
- let pr_glob_sort = function
+ let pr_glob_sort = let open Glob_term in function
| GProp -> tag_type (str "Prop")
| GSet -> tag_type (str "Set")
| GType [] -> tag_type (str "Type")
| GType u -> hov 0 (tag_type (str "Type") ++ pr_univ_annot pr_univ u)
- let pr_glob_level = function
+ let pr_glob_level = let open Glob_term in function
| GProp -> tag_type (str "Prop")
| GSet -> tag_type (str "Set")
| GType UUnknown -> tag_type (str "Type")
| GType UAnonymous -> tag_type (str "_")
- | GType (UNamed u) -> tag_type (pr_reference u)
+ | GType (UNamed u) -> tag_type (pr_qualid u)
let pr_qualid sp =
let (sl, id) = repr_qualid sp in
@@ -199,23 +198,23 @@ let tag_var = tag Tag.variable
let pr_qualid = pr_qualid
let pr_patvar = pr_id
- let pr_glob_sort_instance = function
+ let pr_glob_sort_instance = let open Glob_term in function
| GProp ->
tag_type (str "Prop")
| GSet ->
tag_type (str "Set")
| GType u ->
(match u with
- | UNamed u -> pr_reference u
+ | UNamed u -> pr_qualid u
| UAnonymous -> tag_type (str "Type")
| UUnknown -> tag_type (str "_"))
let pr_universe_instance l =
pr_opt_no_spc (pr_univ_annot (prlist_with_sep spc pr_glob_sort_instance)) l
- let pr_reference = CAst.with_val (function
- | Qualid qid -> pr_qualid qid
- | Ident id -> tag_var (pr_id id))
+ let pr_reference qid =
+ if qualid_is_ident qid then tag_var (pr_id @@ qualid_basename qid)
+ else pr_qualid qid
let pr_cref ref us =
pr_reference ref ++ pr_universe_instance us
@@ -229,7 +228,7 @@ let tag_var = tag Tag.variable
str "(" ++ pr_id id ++ str ":=" ++ pr ltop a ++ str ")"
let pr_opt_type_spc pr = function
- | { CAst.v = CHole (_,Misctypes.IntroAnonymous,_) } -> mt ()
+ | { CAst.v = CHole (_,IntroAnonymous,_) } -> mt ()
| t -> str " :" ++ pr_sep_com (fun()->brk(1,2)) (pr ltop) t
let pr_lident {loc; v=id} =
@@ -243,8 +242,8 @@ let tag_var = tag Tag.variable
| x -> pr_ast Name.print x
let pr_or_var pr = function
- | ArgArg x -> pr x
- | ArgVar id -> pr_lident id
+ | Locus.ArgArg x -> pr x
+ | Locus.ArgVar id -> pr_lident id
let pr_prim_token = function
| Numeral (n,s) -> str (if s then n else "-"^n)
@@ -296,7 +295,7 @@ let tag_var = tag Tag.variable
| CPatOr pl ->
hov 0 (prlist_with_sep pr_spcbar (pr_patt mt (lpator,L)) pl), lpator
- | CPatNotation ("( _ )",([p],[]),[]) ->
+ | CPatNotation ((_,"( _ )"),([p],[]),[]) ->
pr_patt (fun()->str"(") (max_int,E) p ++ str")", latom
| CPatNotation (s,(l,ll),args) ->
@@ -364,7 +363,7 @@ let tag_var = tag Tag.variable
end
| Default b ->
match t with
- | { CAst.v = CHole (_,Misctypes.IntroAnonymous,_) } ->
+ | { CAst.v = CHole (_,IntroAnonymous,_) } ->
let s = prlist_with_sep spc pr_lname nal in
hov 1 (surround_implicit b s)
| _ ->
@@ -458,7 +457,7 @@ let tag_var = tag Tag.variable
let pr_case_type pr po =
match po with
- | None | Some { CAst.v = CHole (_,Misctypes.IntroAnonymous,_) } -> mt()
+ | None | Some { CAst.v = CHole (_,IntroAnonymous,_) } -> mt()
| Some p ->
spc() ++ hov 2 (keyword "return" ++ pr_sep_com spc (pr lsimpleconstr) p)
@@ -565,9 +564,9 @@ let tag_var = tag Tag.variable
return (p ++ prlist (pr spc (lapp,L)) l2, lapp)
else
return (p, lproj)
- | CAppExpl ((None,{v=Ident var},us),[t])
- | CApp ((_, {v = CRef({v=Ident var},us)}),[t,None])
- when Id.equal var Notation_ops.ldots_var ->
+ | CAppExpl ((None,qid,us),[t])
+ | CApp ((_, {v = CRef(qid,us)}),[t,None])
+ when qualid_is_ident qid && Id.equal (qualid_basename qid) Notation_ops.ldots_var ->
return (
hov 0 (str ".." ++ pr spc (latom,E) t ++ spc () ++ str ".."),
larg
@@ -593,7 +592,7 @@ let tag_var = tag Tag.variable
hv 0 (str"{|" ++ pr_record_body_gen (pr spc) l ++ str" |}"),
latom
)
- | CCases (LetPatternStyle,rtntypopt,[c,as_clause,in_clause],[{v=([[p]],b)}]) ->
+ | CCases (Constr.LetPatternStyle,rtntypopt,[c,as_clause,in_clause],[{v=([[p]],b)}]) ->
return (
hv 0 (
keyword "let" ++ spc () ++ str"'" ++
@@ -644,9 +643,9 @@ let tag_var = tag Tag.variable
lif
)
- | CHole (_,Misctypes.IntroIdentifier id,_) ->
+ | CHole (_,IntroIdentifier id,_) ->
return (str "?[" ++ pr_id id ++ str "]", latom)
- | CHole (_,Misctypes.IntroFresh id,_) ->
+ | CHole (_,IntroFresh id,_) ->
return (str "?[?" ++ pr_id id ++ str "]", latom)
| CHole (_,_,_) ->
return (str "_", latom)
@@ -666,7 +665,7 @@ let tag_var = tag Tag.variable
| CastCoerce -> str ":>"),
lcast
)
- | CNotation ("( _ )",([t],[],[],[])) ->
+ | CNotation ((_,"( _ )"),([t],[],[],[])) ->
return (pr (fun()->str"(") (max_int,L) t ++ str")", latom)
| CNotation (s,env) ->
pr_notation (pr mt) pr_patt (pr_binders_gen (pr mt ltop)) s env
diff --git a/printing/ppconstr.mli b/printing/ppconstr.mli
index 1f1308b0..bca419c9 100644
--- a/printing/ppconstr.mli
+++ b/printing/ppconstr.mli
@@ -15,14 +15,13 @@
open Libnames
open Constrexpr
open Names
-open Misctypes
-open Notation_term
+open Notation_gram
val prec_less : precedence -> tolerability -> bool
val pr_tight_coma : unit -> Pp.t
-val pr_or_var : ('a -> Pp.t) -> 'a or_var -> Pp.t
+val pr_or_var : ('a -> Pp.t) -> 'a Locus.or_var -> Pp.t
val pr_lident : lident -> Pp.t
val pr_lname : lname -> Pp.t
@@ -39,16 +38,16 @@ val pr_name : Name.t -> Pp.t
[@@ocaml.deprecated "alias of Names.Name.print"]
val pr_qualid : qualid -> Pp.t
-val pr_patvar : patvar -> Pp.t
+val pr_patvar : Pattern.patvar -> Pp.t
-val pr_glob_level : glob_level -> Pp.t
-val pr_glob_sort : glob_sort -> Pp.t
+val pr_glob_level : Glob_term.glob_level -> Pp.t
+val pr_glob_sort : Glob_term.glob_sort -> Pp.t
val pr_guard_annot : (constr_expr -> Pp.t) ->
local_binder_expr list ->
lident option * recursion_order_expr ->
Pp.t
-val pr_record_body : (reference * constr_expr) list -> Pp.t
+val pr_record_body : (qualid * constr_expr) list -> Pp.t
val pr_binders : local_binder_expr list -> Pp.t
val pr_constr_pattern_expr : constr_pattern_expr -> Pp.t
val pr_lconstr_pattern_expr : constr_pattern_expr -> Pp.t
diff --git a/printing/pputils.ml b/printing/pputils.ml
index c14aa318..59e5f68f 100644
--- a/printing/pputils.ml
+++ b/printing/pputils.ml
@@ -11,7 +11,6 @@
open Util
open Pp
open Genarg
-open Misctypes
open Locus
open Genredexpr
@@ -69,7 +68,7 @@ let pr_short_red_flag pr r =
let pr_red_flag pr r =
try pr_short_red_flag pr r
- with complexRedFlags ->
+ with ComplexRedFlag ->
(if r.rBeta then pr_arg str "beta" else mt ()) ++
(if r.rMatch && r.rFix && r.rCofix then pr_arg str "iota" else
(if r.rMatch then pr_arg str "match" else mt ()) ++
@@ -122,7 +121,7 @@ let pr_red_expr (pr_constr,pr_lconstr,pr_ref,pr_pattern) keyword = function
let pr_red_expr_env env sigma (pr_constr,pr_lconstr,pr_ref,pr_pattern) =
pr_red_expr (pr_constr env sigma, pr_lconstr env sigma, pr_ref, pr_pattern env sigma)
-let pr_or_by_notation f = function
+let pr_or_by_notation f = let open Constrexpr in function
| {CAst.loc; v=AN v} -> f v
| {CAst.loc; v=ByNotation (s,sc)} -> qs s ++ pr_opt (fun sc -> str "%" ++ str sc) sc
diff --git a/printing/pputils.mli b/printing/pputils.mli
index 6039168f..5b1969e2 100644
--- a/printing/pputils.mli
+++ b/printing/pputils.mli
@@ -9,7 +9,6 @@
(************************************************************************)
open Genarg
-open Misctypes
open Locus
open Genredexpr
@@ -18,7 +17,7 @@ val pr_ast : ('a -> Pp.t) -> 'a CAst.t -> Pp.t
(** Prints an object surrounded by its commented location *)
val pr_or_var : ('a -> Pp.t) -> 'a or_var -> Pp.t
-val pr_or_by_notation : ('a -> Pp.t) -> 'a or_by_notation -> Pp.t
+val pr_or_by_notation : ('a -> Pp.t) -> 'a Constrexpr.or_by_notation -> Pp.t
val pr_with_occurrences :
('a -> Pp.t) -> (string -> Pp.t) -> 'a with_occurrences -> Pp.t
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index 1f17d844..1810cc65 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -26,7 +26,6 @@ open Libobject
open Libnames
open Globnames
open Recordops
-open Misctypes
open Printer
open Printmod
open Context.Rel.Declaration
@@ -35,13 +34,13 @@ open Context.Rel.Declaration
module NamedDecl = Context.Named.Declaration
type object_pr = {
- print_inductive : MutInd.t -> Universes.univ_name_list option -> Pp.t;
- print_constant_with_infos : Constant.t -> Universes.univ_name_list option -> Pp.t;
+ print_inductive : MutInd.t -> UnivNames.univ_name_list option -> Pp.t;
+ print_constant_with_infos : Constant.t -> UnivNames.univ_name_list option -> Pp.t;
print_section_variable : env -> Evd.evar_map -> variable -> Pp.t;
print_syntactic_def : env -> KerName.t -> Pp.t;
print_module : bool -> ModPath.t -> Pp.t;
print_modtype : ModPath.t -> Pp.t;
- print_named_decl : env -> Evd.evar_map -> Context.Named.Declaration.t -> Pp.t;
+ print_named_decl : env -> Evd.evar_map -> Constr.named_declaration -> Pp.t;
print_library_entry : env -> Evd.evar_map -> bool -> (object_name * Lib.node) -> Pp.t option;
print_context : env -> Evd.evar_map -> bool -> int option -> Lib.library_segment -> Pp.t;
print_typed_value_in_env : Environ.env -> Evd.evar_map -> EConstr.constr * EConstr.types -> Pp.t;
@@ -77,7 +76,9 @@ let print_ref reduce ref udecl =
let typ = EConstr.of_constr typ in
let typ =
if reduce then
- let ctx,ccl = Reductionops.splay_prod_assum (Global.env()) Evd.empty typ
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ let ctx,ccl = Reductionops.splay_prod_assum env sigma typ
in EConstr.it_mkProd_or_LetIn ccl ctx
else typ in
let univs = Global.universes_of_global ref in
@@ -93,11 +94,12 @@ let print_ref reduce ref udecl =
let inst = Univ.AUContext.instance univs in
let univs = Univ.UContext.make (inst, Univ.AUContext.instantiate inst univs) in
let env = Global.env () in
- let bl = Universes.universe_binders_with_opt_names ref
+ let bl = UnivNames.universe_binders_with_opt_names ref
(Array.to_list (Univ.Instance.to_array inst)) udecl in
let sigma = Evd.from_ctx (UState.of_binders bl) in
let inst =
- if Global.is_polymorphic ref then Printer.pr_universe_instance sigma univs
+ if Global.is_polymorphic ref
+ then Printer.pr_universe_instance sigma (Univ.UContext.instance univs)
else mt ()
in
hov 0 (pr_global ref ++ inst ++ str " :" ++ spc () ++ pr_letype_env env sigma typ ++
@@ -245,13 +247,13 @@ let print_type_in_type ref =
else []
let print_primitive_record recflag mipv = function
- | Some (Some (_, ps,_)) ->
+ | PrimRecord _ ->
let eta = match recflag with
| CoFinite | Finite -> str" without eta conversion"
| BiFinite -> str " with eta conversion"
in
[Id.print mipv.(0).mind_typename ++ str" has primitive projections" ++ eta ++ str"."]
- | _ -> []
+ | FakeRecord | NotRecord -> []
let print_primitive ref =
match ref with
@@ -328,7 +330,7 @@ type 'a locatable_info = {
type locatable = Locatable : 'a locatable_info -> locatable
type logical_name =
- | Term of global_reference
+ | Term of GlobRef.t
| Dir of global_dir_reference
| Syntactic of KerName.t
| ModuleType of ModPath.t
@@ -343,8 +345,7 @@ let register_locatable name f =
exception ObjFound of logical_name
-let locate_any_name ref =
- let {v=qid} = qualid_of_reference ref in
+let locate_any_name qid =
try Term (Nametab.locate qid)
with Not_found ->
try Syntactic (Nametab.locate_syndef qid)
@@ -376,7 +377,6 @@ let pr_located_qualid = function
| DirOpenModtype { obj_dir ; _ } -> "Open Module Type", obj_dir
| DirOpenSection { obj_dir ; _ } -> "Open Section", obj_dir
| DirModule { obj_dir ; _ } -> "Module", obj_dir
- | DirClosedSection dir -> "Closed Section", dir
in
str s ++ spc () ++ DirPath.print dir
| ModuleType mp ->
@@ -452,8 +452,7 @@ type locatable_kind =
| LocOther of string
| LocAny
-let print_located_qualid name flags ref =
- let {v=qid} = qualid_of_reference ref in
+let print_located_qualid name flags qid =
let located = match flags with
| LocTerm -> locate_term qid
| LocModule -> locate_modtype qid @ locate_module qid
@@ -554,8 +553,7 @@ let print_instance sigma cb =
if Declareops.constant_is_polymorphic cb then
let univs = Declareops.constant_polymorphic_context cb in
let inst = Univ.AUContext.instance univs in
- let univs = Univ.UContext.make (inst, Univ.AUContext.instantiate inst univs) in
- pr_universe_instance sigma univs
+ pr_universe_instance sigma inst
else mt()
let print_constant with_values sep sp udecl =
@@ -595,7 +593,7 @@ let print_constant with_values sep sp udecl =
in
let ctx =
UState.of_binders
- (Universes.universe_binders_with_opt_names (ConstRef sp) ulist udecl)
+ (UnivNames.universe_binders_with_opt_names (ConstRef sp) ulist udecl)
in
let env = Global.env () and sigma = Evd.from_ctx ctx in
let pr_ltype = pr_ltype_env env sigma in
@@ -659,14 +657,10 @@ let gallina_print_library_entry env sigma with_values ent =
gallina_print_leaf_entry env sigma with_values (oname,lobj)
| (oname,Lib.OpenedSection (dir,_)) ->
Some (str " >>>>>>> Section " ++ pr_name oname)
- | (oname,Lib.ClosedSection _) ->
- Some (str " >>>>>>> Closed Section " ++ pr_name oname)
| (_,Lib.CompilingLibrary { obj_dir; _ }) ->
Some (str " >>>>>>> Library " ++ DirPath.print obj_dir)
| (oname,Lib.OpenedModule _) ->
Some (str " >>>>>>> Module " ++ pr_name oname)
- | (oname,Lib.ClosedModule _) ->
- Some (str " >>>>>>> Closed Module " ++ pr_name oname)
let gallina_print_context env sigma with_values =
let rec prec n = function
@@ -718,7 +712,10 @@ let print_eval x = !object_pr.print_eval x
(**** Printing declarations and judgments *)
(**** Abstract layer *****)
-let print_typed_value x = print_typed_value_in_env (Global.env ()) Evd.empty x
+let print_typed_value x =
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ print_typed_value_in_env env sigma x
let print_judgment env sigma {uj_val=trm;uj_type=typ} =
print_typed_value_in_env env sigma (trm, typ)
@@ -784,18 +781,14 @@ let print_full_pure_context env sigma =
follows the definition of the inductive type *)
(* This is designed to print the contents of an opened section *)
-let read_sec_context r =
- let qid = qualid_of_reference r in
+let read_sec_context qid =
let dir =
- try Nametab.locate_section qid.v
+ try Nametab.locate_section qid
with Not_found ->
user_err ?loc:qid.loc ~hdr:"read_sec_context" (str "Unknown section.") in
let rec get_cxt in_cxt = function
| (_,Lib.OpenedSection ({obj_dir;_},_) as hd)::rest ->
if DirPath.equal dir obj_dir then (hd::in_cxt) else get_cxt (hd::in_cxt) rest
- | (_,Lib.ClosedSection _)::rest ->
- user_err Pp.(str "Cannot print the contents of a closed section.")
- (* LEM: Actually, we could if we wanted to. *)
| [] -> []
| hd::rest -> get_cxt (hd::in_cxt) rest
in
@@ -839,12 +832,12 @@ let print_any_name env sigma na udecl =
let print_name env sigma na udecl =
match na with
- | {loc; v=ByNotation (ntn,sc)} ->
+ | {loc; v=Constrexpr.ByNotation (ntn,sc)} ->
print_any_name env sigma
(Term (Notation.interp_notation_as_global_reference ?loc (fun _ -> true)
ntn sc))
udecl
- | {loc; v=AN ref} ->
+ | {loc; v=Constrexpr.AN ref} ->
print_any_name env sigma (locate_any_name ref) udecl
let print_opaque_name env sigma qid =
@@ -892,11 +885,11 @@ let print_about_any ?loc env sigma k udecl =
let print_about env sigma na udecl =
match na with
- | {loc;v=ByNotation (ntn,sc)} ->
+ | {loc;v=Constrexpr.ByNotation (ntn,sc)} ->
print_about_any ?loc env sigma
(Term (Notation.interp_notation_as_global_reference ?loc (fun _ -> true)
ntn sc)) udecl
- | {loc;v=AN ref} ->
+ | {loc;v=Constrexpr.AN ref} ->
print_about_any ?loc env sigma (locate_any_name ref) udecl
(* for debug *)
@@ -909,7 +902,7 @@ let inspect env sigma depth =
open Classops
-let print_coercion_value env sigma v = pr_lconstr_env env sigma (get_coercion_value v)
+let print_coercion_value env sigma v = Printer.pr_global v.coe_value
let print_class i =
let cl,_ = class_info_from_index i in
diff --git a/printing/prettyp.mli b/printing/prettyp.mli
index 213f0aee..1668bce2 100644
--- a/printing/prettyp.mli
+++ b/printing/prettyp.mli
@@ -12,8 +12,6 @@ open Names
open Environ
open Reductionops
open Libnames
-open Globnames
-open Misctypes
open Evd
(** A Pretty-Printer for the Calculus of Inductive Constructions. *)
@@ -26,20 +24,20 @@ val print_library_entry : env -> Evd.evar_map -> bool -> (object_name * Lib.node
val print_full_context : env -> Evd.evar_map -> Pp.t
val print_full_context_typ : env -> Evd.evar_map -> Pp.t
val print_full_pure_context : env -> Evd.evar_map -> Pp.t
-val print_sec_context : env -> Evd.evar_map -> reference -> Pp.t
-val print_sec_context_typ : env -> Evd.evar_map -> reference -> Pp.t
+val print_sec_context : env -> Evd.evar_map -> qualid -> Pp.t
+val print_sec_context_typ : env -> Evd.evar_map -> qualid -> Pp.t
val print_judgment : env -> Evd.evar_map -> EConstr.unsafe_judgment -> Pp.t
val print_safe_judgment : env -> Evd.evar_map -> Safe_typing.judgment -> Pp.t
val print_eval :
reduction_function -> env -> Evd.evar_map ->
Constrexpr.constr_expr -> EConstr.unsafe_judgment -> Pp.t
-val print_name : env -> Evd.evar_map -> reference or_by_notation ->
- Universes.univ_name_list option -> Pp.t
-val print_opaque_name : env -> Evd.evar_map -> reference -> Pp.t
-val print_about : env -> Evd.evar_map -> reference or_by_notation ->
- Universes.univ_name_list option -> Pp.t
-val print_impargs : reference or_by_notation -> Pp.t
+val print_name : env -> Evd.evar_map -> qualid Constrexpr.or_by_notation ->
+ UnivNames.univ_name_list option -> Pp.t
+val print_opaque_name : env -> Evd.evar_map -> qualid -> Pp.t
+val print_about : env -> Evd.evar_map -> qualid Constrexpr.or_by_notation ->
+ UnivNames.univ_name_list option -> Pp.t
+val print_impargs : qualid Constrexpr.or_by_notation -> Pp.t
(** Pretty-printing functions for classes and coercions *)
val print_graph : env -> evar_map -> Pp.t
@@ -50,7 +48,7 @@ val print_canonical_projections : env -> Evd.evar_map -> Pp.t
(** Pretty-printing functions for type classes and instances *)
val print_typeclasses : unit -> Pp.t
-val print_instances : global_reference -> Pp.t
+val print_instances : GlobRef.t -> Pp.t
val print_all_instances : unit -> Pp.t
val inspect : env -> Evd.evar_map -> int -> Pp.t
@@ -79,19 +77,19 @@ val register_locatable : string -> 'a locatable_info -> unit
name describing the kind of objects considered and that is added as a
grammar command prefix for vernacular commands Locate. *)
-val print_located_qualid : reference -> Pp.t
-val print_located_term : reference -> Pp.t
-val print_located_module : reference -> Pp.t
-val print_located_other : string -> reference -> Pp.t
+val print_located_qualid : qualid -> Pp.t
+val print_located_term : qualid -> Pp.t
+val print_located_module : qualid -> Pp.t
+val print_located_other : string -> qualid -> Pp.t
type object_pr = {
- print_inductive : MutInd.t -> Universes.univ_name_list option -> Pp.t;
- print_constant_with_infos : Constant.t -> Universes.univ_name_list option -> Pp.t;
+ print_inductive : MutInd.t -> UnivNames.univ_name_list option -> Pp.t;
+ print_constant_with_infos : Constant.t -> UnivNames.univ_name_list option -> Pp.t;
print_section_variable : env -> Evd.evar_map -> variable -> Pp.t;
print_syntactic_def : env -> KerName.t -> Pp.t;
print_module : bool -> ModPath.t -> Pp.t;
print_modtype : ModPath.t -> Pp.t;
- print_named_decl : env -> Evd.evar_map -> Context.Named.Declaration.t -> Pp.t;
+ print_named_decl : env -> Evd.evar_map -> Constr.named_declaration -> Pp.t;
print_library_entry : env -> Evd.evar_map -> bool -> (object_name * Lib.node) -> Pp.t option;
print_context : env -> Evd.evar_map -> bool -> int option -> Lib.library_segment -> Pp.t;
print_typed_value_in_env : Environ.env -> Evd.evar_map -> EConstr.constr * EConstr.types -> Pp.t;
diff --git a/printing/printer.ml b/printing/printer.ml
index 199aa79c..b4038e0f 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -82,24 +82,23 @@ let pr_econstr_n_core goal_concl_style env sigma n t =
pr_constr_expr_n n (extern_constr goal_concl_style env sigma t)
let pr_econstr_core goal_concl_style env sigma t =
pr_constr_expr (extern_constr goal_concl_style env sigma t)
-let pr_leconstr_core goal_concl_style env sigma t =
- pr_lconstr_expr (extern_constr goal_concl_style env sigma t)
+let pr_leconstr_core = Proof_diffs.pr_leconstr_core
let pr_constr_n_env env sigma n c = pr_econstr_n_core false env sigma n (EConstr.of_constr c)
-let pr_lconstr_env env sigma c = pr_leconstr_core false env sigma (EConstr.of_constr c)
+let pr_lconstr_env = Proof_diffs.pr_lconstr_env
let pr_constr_env env sigma c = pr_econstr_core false env sigma (EConstr.of_constr c)
let _ = Hook.set Refine.pr_constr pr_constr_env
let pr_lconstr_goal_style_env env sigma c = pr_leconstr_core true env sigma (EConstr.of_constr c)
let pr_constr_goal_style_env env sigma c = pr_econstr_core true env sigma (EConstr.of_constr c)
-let pr_open_lconstr_env env sigma (_,c) = pr_lconstr_env env sigma c
-let pr_open_constr_env env sigma (_,c) = pr_constr_env env sigma c
-
let pr_econstr_n_env env sigma c = pr_econstr_n_core false env sigma c
let pr_leconstr_env env sigma c = pr_leconstr_core false env sigma c
let pr_econstr_env env sigma c = pr_econstr_core false env sigma c
+let pr_open_lconstr_env env sigma (_,c) = pr_leconstr_env env sigma c
+let pr_open_constr_env env sigma (_,c) = pr_econstr_env env sigma c
+
(* NB do not remove the eta-redexes! Global.env() has side-effects... *)
let pr_lconstr t =
let (sigma, env) = Pfedit.get_current_context () in
@@ -108,12 +107,12 @@ let pr_constr t =
let (sigma, env) = Pfedit.get_current_context () in
pr_constr_env env sigma t
-let pr_open_lconstr (_,c) = pr_lconstr c
-let pr_open_constr (_,c) = pr_constr c
-
let pr_leconstr c = pr_lconstr (EConstr.Unsafe.to_constr c)
let pr_econstr c = pr_constr (EConstr.Unsafe.to_constr c)
+let pr_open_lconstr (_,c) = pr_leconstr c
+let pr_open_constr (_,c) = pr_econstr c
+
let pr_constr_under_binders_env_gen pr env sigma (ids,c) =
(* Warning: clashes can occur with variables of same name in env but *)
(* we also need to preserve the actual names of the patterns *)
@@ -133,8 +132,7 @@ let pr_lconstr_under_binders c =
let pr_etype_core goal_concl_style env sigma t =
pr_constr_expr (extern_type goal_concl_style env sigma t)
-let pr_letype_core goal_concl_style env sigma t =
- pr_lconstr_expr (extern_type goal_concl_style env sigma t)
+let pr_letype_core = Proof_diffs.pr_letype_core
let pr_ltype_env env sigma c = pr_letype_core false env sigma (EConstr.of_constr c)
let pr_type_env env sigma c = pr_etype_core false env sigma (EConstr.of_constr c)
@@ -194,7 +192,7 @@ let pr_constr_pattern t =
let pr_sort sigma s = pr_glob_sort (extern_sort sigma s)
-let _ = Termops.set_print_constr
+let _ = Termops.Internal.set_print_constr
(fun env sigma t -> pr_lconstr_expr (extern_constr ~lax:true false env sigma t))
let pr_in_comment pr x = str "(* " ++ pr x ++ str " *)"
@@ -229,15 +227,15 @@ let dirpath_of_global = function
dirpath_of_mp (MutInd.modpath kn)
| VarRef _ -> DirPath.empty
-let qualid_of_global env r =
- Libnames.make_qualid (dirpath_of_global r) (id_of_global env r)
+let qualid_of_global ?loc env r =
+ Libnames.make_qualid ?loc (dirpath_of_global r) (id_of_global env r)
let safe_gen f env sigma c =
let orig_extern_ref = Constrextern.get_extern_reference () in
let extern_ref ?loc vars r =
try orig_extern_ref vars r
with e when CErrors.noncritical e ->
- CAst.make ?loc @@ Libnames.Qualid (qualid_of_global env r)
+ qualid_of_global ?loc env r
in
Constrextern.set_extern_reference extern_ref;
try
@@ -290,17 +288,19 @@ let pr_cumulativity_info sigma cumi =
let pr_global_env = pr_global_env
let pr_global = pr_global_env Id.Set.empty
-let pr_puniverses f env (c,u) =
- f env c ++
- (if !Constrextern.print_universes then
- str"(*" ++ Univ.Instance.pr Universes.pr_with_global_universes u ++ str"*)"
- else mt ())
+let pr_universe_instance evd inst =
+ str"@{" ++ Univ.Instance.pr (Termops.pr_evd_level evd) inst ++ str"}"
+
+let pr_puniverses f env sigma (c,u) =
+ if !Constrextern.print_universes
+ then f env c ++ pr_universe_instance sigma u
+ else f env c
let pr_constant env cst = pr_global_env (Termops.vars_of_env env) (ConstRef cst)
let pr_existential_key = Termops.pr_existential_key
let pr_existential env sigma ev = pr_lconstr_env env sigma (mkEvar ev)
-let pr_inductive env ind = pr_lconstr_env env Evd.empty (mkInd ind)
-let pr_constructor env cstr = pr_lconstr_env env Evd.empty (mkConstruct cstr)
+let pr_inductive env ind = pr_lconstr_env env (Evd.from_env env) (mkInd ind)
+let pr_constructor env cstr = pr_lconstr_env env (Evd.from_env env) (mkConstruct cstr)
let pr_pconstant = pr_puniverses pr_constant
let pr_pinductive = pr_puniverses pr_inductive
@@ -493,16 +493,23 @@ let pr_transparent_state (ids, csts) =
hv 0 (str"VARIABLES: " ++ pr_idpred ids ++ fnl () ++
str"CONSTANTS: " ++ pr_cpred csts ++ fnl ())
-(* display complete goal *)
-let default_pr_goal gs =
- let g = sig_it gs in
- let sigma = project gs in
+(* display complete goal
+ og_s has goal+sigma on the previous proof step for diffs
+ g_s has goal+sigma on the current proof step
+ *)
+let pr_goal ?(diffs=false) ?og_s g_s =
+ let g = sig_it g_s in
+ let sigma = project g_s in
let env = Goal.V82.env sigma g in
let concl = Goal.V82.concl sigma g in
let goal =
- pr_context_of env sigma ++ cut () ++
- str "============================" ++ cut () ++
- pr_goal_concl_style_env env sigma concl in
+ if diffs then
+ Proof_diffs.diff_goal ?og_s g sigma
+ else
+ pr_context_of env sigma ++ cut () ++
+ str "============================" ++ cut () ++
+ pr_goal_concl_style_env env sigma concl
+ in
str " " ++ v 0 goal
(* display a goal tag *)
@@ -518,13 +525,18 @@ let pr_goal_name sigma g =
let pr_goal_header nme sigma g =
let (g,sigma) = Goal.V82.nf_evar sigma g in
str "subgoal " ++ nme ++ (if should_tag() then pr_goal_tag g else str"")
- ++ (if should_gname() then str " " ++ Pp.surround (pr_existential_key sigma g) else mt ())
+ ++ (if should_gname() then str " " ++ Pp.surround (pr_existential_key sigma g) else mt ())
(* display the conclusion of a goal *)
-let pr_concl n sigma g =
+let pr_concl n ?(diffs=false) ?og_s sigma g =
let (g,sigma) = Goal.V82.nf_evar sigma g in
let env = Goal.V82.env sigma g in
- let pc = pr_goal_concl_style_env env sigma (Goal.V82.concl sigma g) in
+ let pc =
+ if diffs then
+ Proof_diffs.diff_concl ?og_s sigma g
+ else
+ pr_goal_concl_style_env env sigma (Goal.V82.concl sigma g)
+ in
let header = pr_goal_header (int n) sigma g in
header ++ str " is:" ++ cut () ++ str" " ++ pc
@@ -541,12 +553,12 @@ let pr_evgl_sign sigma evi =
if List.is_empty ids then mt () else
(str " (" ++ prlist_with_sep pr_comma pr_id ids ++ str " cannot be used)")
in
- let pc = pr_lconstr_env env sigma evi.evar_concl in
+ let pc = pr_leconstr_env env sigma evi.evar_concl in
let candidates =
match evi.evar_body, evi.evar_candidates with
| Evar_empty, Some l ->
spc () ++ str "= {" ++
- prlist_with_sep (fun () -> str "|") (pr_lconstr_env env sigma) l ++ str "}"
+ prlist_with_sep (fun () -> str "|") (pr_leconstr_env env sigma) l ++ str "}"
| _ ->
mt ()
in
@@ -591,11 +603,11 @@ let pr_ne_evar_set hd tl sigma l =
mt ()
let pr_selected_subgoal name sigma g =
- let pg = default_pr_goal { sigma=sigma ; it=g; } in
+ let pg = pr_goal { sigma=sigma ; it=g; } in
let header = pr_goal_header name sigma g in
v 0 (header ++ str " is:" ++ cut () ++ pg)
-let default_pr_subgoal n sigma =
+let pr_subgoal n sigma =
let rec prrec p = function
| [] -> user_err Pp.(str "No such goal.")
| g::rest ->
@@ -622,8 +634,8 @@ let print_evar_constraints gl sigma =
end
in
let pr_evconstr (pbty,env,t1,t2) =
- let t1 = Evarutil.nf_evar sigma (EConstr.of_constr t1)
- and t2 = Evarutil.nf_evar sigma (EConstr.of_constr t2) in
+ let t1 = Evarutil.nf_evar sigma t1
+ and t2 = Evarutil.nf_evar sigma t2 in
let env =
(** We currently allow evar instances to refer to anonymous de Bruijn
indices, so we protect the error printing code in this case by giving
@@ -691,12 +703,25 @@ let print_dependent_evars gl sigma seeds =
in
constraints ++ evars ()
+module GoalMap = Evar.Map
+
(* Print open subgoals. Checks for uninstantiated existential variables *)
(* spiwack: [seeds] is for printing dependent evars in emacs mode. *)
(* spiwack: [pr_first] is true when the first goal must be singled out
and printed in its entirety. *)
-let default_pr_subgoals ?(pr_first=true)
+(* [os_map] is derived from the previous proof step, used for diffs *)
+let pr_subgoals ?(pr_first=true) ?(diffs=false) ?os_map
close_cmd sigma ~seeds ~shelf ~stack ~unfocused ~goals =
+ let diff_goal_map =
+ match os_map with
+ | Some (_, diff_goal_map) -> diff_goal_map
+ | None -> GoalMap.empty
+ in
+
+ let map_goal_for_diff ng = (* todo: move to proof_diffs.ml *)
+ try GoalMap.find ng diff_goal_map with Not_found -> ng
+ in
+
(** Printing functions for the extra informations. *)
let rec print_stack a = function
| [] -> Pp.int a
@@ -729,17 +754,24 @@ let default_pr_subgoals ?(pr_first=true)
if needed then str" focused "
else str" " (* non-breakable space *)
in
- (** Main function *)
+
+ let get_ogs g =
+ match os_map with
+ | Some (osigma, _) -> Some { it = map_goal_for_diff g; sigma = osigma }
+ | None -> None
+ in
let rec pr_rec n = function
| [] -> (mt ())
| g::rest ->
- let pc = pr_concl n sigma g in
+ let og_s = get_ogs g in
+ let pc = pr_concl n ~diffs ?og_s sigma g in
let prest = pr_rec (n+1) rest in
(cut () ++ pc ++ prest)
in
let print_multiple_goals g l =
if pr_first then
- default_pr_goal { it = g ; sigma = sigma; }
+ let og_s = get_ogs g in
+ pr_goal ~diffs ?og_s { it = g ; sigma = sigma }
++ (if l=[] then mt () else cut ())
++ pr_rec 2 l
else
@@ -751,6 +783,8 @@ let default_pr_subgoals ?(pr_first=true)
| Some cmd -> Feedback.msg_info cmd
| None -> ()
in
+
+ (** Main function *)
match goals with
| [] ->
begin
@@ -780,34 +814,7 @@ let default_pr_subgoals ?(pr_first=true)
++ print_dependent_evars (Some g1) sigma seeds
)
-(**********************************************************************)
-(* Abstraction layer *)
-
-
-type printer_pr = {
- pr_subgoals : ?pr_first:bool -> Pp.t option -> evar_map -> seeds:goal list -> shelf:goal list -> stack:int list -> unfocused:goal list -> goals:goal list -> Pp.t;
- pr_subgoal : int -> evar_map -> goal list -> Pp.t;
- pr_goal : goal sigma -> Pp.t;
-}
-
-let default_printer_pr = {
- pr_subgoals = default_pr_subgoals;
- pr_subgoal = default_pr_subgoal;
- pr_goal = default_pr_goal;
-}
-
-let printer_pr = ref default_printer_pr
-
-let set_printer_pr = (:=) printer_pr
-
-let pr_subgoals ?pr_first x = !printer_pr.pr_subgoals ?pr_first x
-let pr_subgoal x = !printer_pr.pr_subgoal x
-let pr_goal x = !printer_pr.pr_goal x
-
-(* End abstraction layer *)
-(**********************************************************************)
-
-let pr_open_subgoals ~proof =
+let pr_open_subgoals_diff ?(quiet=false) ?(diffs=false) ?oproof proof =
(* spiwack: it shouldn't be the job of the printer to look up stuff
in the [evar_map], I did stuff that way because it was more
straightforward, but seriously, [Proof.proof] should return
@@ -830,21 +837,33 @@ let pr_open_subgoals ~proof =
fnl ()
++ pr_subgoals ~pr_first:false None bsigma ~seeds ~shelf:[] ~stack:[] ~unfocused:[] ~goals:shelf
| _ , _, _ ->
- let end_cmd =
- str "This subproof is complete, but there are some unfocused goals." ++
- (let s = Proof_bullet.suggest p in
- if Pp.ismt s then s else fnl () ++ s) ++
- fnl ()
+ let cmd = if quiet then None else
+ Some
+ (str "This subproof is complete, but there are some unfocused goals." ++
+ (let s = Proof_bullet.suggest p in
+ if Pp.ismt s then s else fnl () ++ s) ++
+ fnl ())
in
- pr_subgoals ~pr_first:false (Some end_cmd) bsigma ~seeds ~shelf ~stack:[] ~unfocused:[] ~goals:bgoals
+ pr_subgoals ~pr_first:false cmd bsigma ~seeds ~shelf ~stack:[] ~unfocused:[] ~goals:bgoals
end
| _ ->
let { Evd.it = bgoals ; sigma = bsigma } = Proof.V82.background_subgoals p in
let bgoals_focused, bgoals_unfocused = List.partition (fun x -> List.mem x goals) bgoals in
let unfocused_if_needed = if should_unfoc() then bgoals_unfocused else [] in
- pr_subgoals ~pr_first:true None bsigma ~seeds ~shelf ~stack:[] ~unfocused:unfocused_if_needed ~goals:bgoals_focused
+ let os_map = match oproof with
+ | Some op when diffs ->
+ let (_,_,_,_, osigma) = Proof.proof op in
+ let diff_goal_map = Proof_diffs.make_goal_map oproof proof in
+ Some (osigma, diff_goal_map)
+ | _ -> None
+ in
+ pr_subgoals ~pr_first:true ~diffs ?os_map None bsigma ~seeds ~shelf ~stack:[]
+ ~unfocused:unfocused_if_needed ~goals:bgoals_focused
end
+let pr_open_subgoals ~proof =
+ pr_open_subgoals_diff proof
+
let pr_nth_open_subgoal ~proof n =
let gls,_,_,_,sigma = Proof.proof proof in
pr_subgoal n sigma gls
@@ -879,7 +898,7 @@ type axiom =
type context_object =
| Variable of Id.t (* A section variable or a Let definition *)
- | Axiom of axiom * (Label.t * Context.Rel.t * types) list
+ | Axiom of axiom * (Label.t * Constr.rel_context * types) list
| Opaque of Constant.t (* An opaque constant. *)
| Transparent of Constant.t
@@ -925,11 +944,18 @@ let pr_assumptionset env sigma s =
let safe_pr_constant env kn =
try pr_constant env kn
with Not_found ->
+ (* FIXME? *)
let mp,_,lab = Constant.repr3 kn in
str (ModPath.to_string mp) ++ str "." ++ Label.print lab
in
- let safe_pr_ltype typ =
- try str " : " ++ pr_ltype typ
+ let safe_pr_inductive env kn =
+ try pr_inductive env (kn,0)
+ with Not_found ->
+ (* FIXME? *)
+ MutInd.print kn
+ in
+ let safe_pr_ltype env sigma typ =
+ try str " : " ++ pr_ltype_env env sigma typ
with e when CErrors.noncritical e -> mt ()
in
let safe_pr_ltype_relctx (rctx, typ) =
@@ -940,9 +966,9 @@ let pr_assumptionset env sigma s =
let pr_axiom env ax typ =
match ax with
| Constant kn ->
- safe_pr_constant env kn ++ safe_pr_ltype typ
+ safe_pr_constant env kn ++ safe_pr_ltype env sigma typ
| Positive m ->
- hov 2 (MutInd.print m ++ spc () ++ strbrk"is positive.")
+ hov 2 (safe_pr_inductive env m ++ spc () ++ strbrk"is positive.")
| Guarded kn ->
hov 2 (safe_pr_constant env kn ++ spc () ++ strbrk"is positive.")
in
@@ -950,7 +976,7 @@ let pr_assumptionset env sigma s =
let (v, a, o, tr) = accu in
match t with
| Variable id ->
- let var = pr_id id ++ str " : " ++ pr_ltype typ in
+ let var = pr_id id ++ str " : " ++ pr_ltype_env env sigma typ in
(var :: v, a, o, tr)
| Axiom (axiom, []) ->
let ax = pr_axiom env axiom typ in
@@ -964,10 +990,10 @@ let pr_assumptionset env sigma s =
l in
(v, ax :: a, o, tr)
| Opaque kn ->
- let opq = safe_pr_constant env kn ++ safe_pr_ltype typ in
+ let opq = safe_pr_constant env kn ++ safe_pr_ltype env sigma typ in
(v, a, opq :: o, tr)
| Transparent kn ->
- let tran = safe_pr_constant env kn ++ safe_pr_ltype typ in
+ let tran = safe_pr_constant env kn ++ safe_pr_ltype env sigma typ in
(v, a, o, tran :: tr)
in
let (vars, axioms, opaque, trans) =
@@ -1014,6 +1040,21 @@ let pr_polymorphic b =
if b then str"Polymorphic " else str"Monomorphic "
else mt ()
-let pr_universe_instance evd ctx =
- let inst = Univ.UContext.instance ctx in
- str"@{" ++ Univ.Instance.pr (Termops.pr_evd_level evd) inst ++ str"}"
+(* print the proof step, possibly with diffs highlighted, *)
+let print_and_diff oldp newp =
+ match newp with
+ | None -> ()
+ | Some proof ->
+ let output =
+ if Proof_diffs.show_diffs () then
+ try pr_open_subgoals_diff ~diffs:true ?oproof:oldp proof
+ with Pp_diff.Diff_Failure msg -> begin
+ (* todo: print the unparsable string (if we know it) *)
+ Feedback.msg_warning Pp.(str ("Diff failure: " ^ msg) ++ cut()
+ ++ str "Showing results without diff highlighting" );
+ pr_open_subgoals ~proof
+ end
+ else
+ pr_open_subgoals ~proof
+ in
+ Feedback.msg_notice output;;
diff --git a/printing/printer.mli b/printing/printer.mli
index 41843680..518c5b93 100644
--- a/printing/printer.mli
+++ b/printing/printer.mli
@@ -9,7 +9,6 @@
(************************************************************************)
open Names
-open Globnames
open Constr
open Environ
open Pattern
@@ -37,7 +36,7 @@ val pr_constr : constr -> Pp.t
[@@ocaml.deprecated "The global printing API is deprecated, please use the _env functions"]
val pr_constr_goal_style_env : env -> evar_map -> constr -> Pp.t
-val pr_constr_n_env : env -> evar_map -> Notation_term.tolerability -> constr -> Pp.t
+val pr_constr_n_env : env -> evar_map -> Notation_gram.tolerability -> constr -> Pp.t
(** Same, but resilient to [Nametab] errors. Prints fully-qualified
names when [shortest_qualid_of_global] has failed. Prints "??"
@@ -58,7 +57,7 @@ val pr_leconstr_env : env -> evar_map -> EConstr.t -> Pp.t
val pr_leconstr : EConstr.t -> Pp.t
[@@ocaml.deprecated "The global printing API is deprecated, please use the _env functions"]
-val pr_econstr_n_env : env -> evar_map -> Notation_term.tolerability -> EConstr.t -> Pp.t
+val pr_econstr_n_env : env -> evar_map -> Notation_gram.tolerability -> EConstr.t -> Pp.t
val pr_etype_env : env -> evar_map -> EConstr.types -> Pp.t
val pr_letype_env : env -> evar_map -> EConstr.types -> Pp.t
@@ -88,7 +87,7 @@ val pr_type_env : env -> evar_map -> types -> Pp.t
val pr_type : types -> Pp.t
[@@ocaml.deprecated "The global printing API is deprecated, please use the _env functions"]
-val pr_closed_glob_n_env : env -> evar_map -> Notation_term.tolerability -> closed_glob_constr -> Pp.t
+val pr_closed_glob_n_env : env -> evar_map -> Notation_gram.tolerability -> closed_glob_constr -> Pp.t
val pr_closed_glob_env : env -> evar_map -> closed_glob_constr -> Pp.t
val pr_closed_glob : closed_glob_constr -> Pp.t
[@@ocaml.deprecated "The global printing API is deprecated, please use the _env functions"]
@@ -121,7 +120,7 @@ val pr_sort : evar_map -> Sorts.t -> Pp.t
val pr_polymorphic : bool -> Pp.t
val pr_cumulative : bool -> bool -> Pp.t
-val pr_universe_instance : evar_map -> Univ.UContext.t -> Pp.t
+val pr_universe_instance : evar_map -> Univ.Instance.t -> Pp.t
val pr_universe_ctx : evar_map -> ?variance:Univ.Variance.t array ->
Univ.UContext.t -> Pp.t
val pr_universe_ctx_set : evar_map -> Univ.ContextSet.t -> Pp.t
@@ -130,8 +129,8 @@ val pr_cumulativity_info : evar_map -> Univ.CumulativityInfo.t -> Pp.t
(** Printing global references using names as short as possible *)
-val pr_global_env : Id.Set.t -> global_reference -> Pp.t
-val pr_global : global_reference -> Pp.t
+val pr_global_env : Id.Set.t -> GlobRef.t -> Pp.t
+val pr_global : GlobRef.t -> Pp.t
val pr_constant : env -> Constant.t -> Pp.t
val pr_existential_key : evar_map -> Evar.t -> Pp.t
@@ -140,9 +139,9 @@ val pr_constructor : env -> constructor -> Pp.t
val pr_inductive : env -> inductive -> Pp.t
val pr_evaluable_reference : evaluable_global_reference -> Pp.t
-val pr_pconstant : env -> pconstant -> Pp.t
-val pr_pinductive : env -> pinductive -> Pp.t
-val pr_pconstructor : env -> pconstructor -> Pp.t
+val pr_pconstant : env -> evar_map -> pconstant -> Pp.t
+val pr_pinductive : env -> evar_map -> pinductive -> Pp.t
+val pr_pconstructor : env -> evar_map -> pconstructor -> Pp.t
(** Contexts *)
@@ -153,13 +152,13 @@ val get_compact_context : unit -> bool
val pr_context_unlimited : env -> evar_map -> Pp.t
val pr_ne_context_of : Pp.t -> env -> evar_map -> Pp.t
-val pr_named_decl : env -> evar_map -> Context.Named.Declaration.t -> Pp.t
-val pr_compacted_decl : env -> evar_map -> Context.Compacted.Declaration.t -> Pp.t
-val pr_rel_decl : env -> evar_map -> Context.Rel.Declaration.t -> Pp.t
+val pr_named_decl : env -> evar_map -> Constr.named_declaration -> Pp.t
+val pr_compacted_decl : env -> evar_map -> Constr.compacted_declaration -> Pp.t
+val pr_rel_decl : env -> evar_map -> Constr.rel_declaration -> Pp.t
-val pr_named_context : env -> evar_map -> Context.Named.t -> Pp.t
+val pr_named_context : env -> evar_map -> Constr.named_context -> Pp.t
val pr_named_context_of : env -> evar_map -> Pp.t
-val pr_rel_context : env -> evar_map -> Context.Rel.t -> Pp.t
+val pr_rel_context : env -> evar_map -> Constr.rel_context -> Pp.t
val pr_rel_context_of : env -> evar_map -> Pp.t
val pr_context_of : env -> evar_map -> Pp.t
@@ -172,22 +171,46 @@ val pr_transparent_state : transparent_state -> Pp.t
(** Proofs, these functions obey [Hyps Limit] and [Compact contexts]. *)
-val pr_goal : goal sigma -> Pp.t
-
-(** [pr_subgoals ~pr_first pp sigma seeds shelf focus_stack unfocused goals]
- prints the goals of the list [goals] followed by the goals in
- [unfocused], in a short way (typically only the conclusion) except
- for the first goal if [pr_first] is true. This function can be
- replaced by another one by calling [set_printer_pr] (see below),
- typically by plugin writers. The default printer prints only the
- focused goals unless the conrresponding option
- [enable_unfocused_goal_printing] is set. [seeds] is for printing
- dependent evars (mainly for emacs proof tree mode). *)
-val pr_subgoals : ?pr_first:bool -> Pp.t option -> evar_map -> seeds:goal list -> shelf:goal list -> stack:int list -> unfocused:goal list -> goals:goal list -> Pp.t
+(** [pr_goal ~diffs ~og_s g_s] prints the goal specified by [g_s]. If [diffs] is true,
+ highlight the differences between the old goal, [og_s], and [g_s]. [g_s] and [og_s] are
+ records containing the goal and sigma for, respectively, the new and old proof steps,
+ e.g. [{ it = g ; sigma = sigma }].
+*)
+val pr_goal : ?diffs:bool -> ?og_s:(goal sigma) -> goal sigma -> Pp.t
+
+(** [pr_subgoals ~pr_first ~diffs ~os_map close_cmd sigma ~seeds ~shelf ~stack ~unfocused ~goals]
+ prints the goals in [goals] followed by the goals in [unfocused] in a compact form
+ (typically only the conclusion). If [pr_first] is true, print the first goal in full.
+ [close_cmd] is printed afterwards verbatim.
+
+ If [diffs] is true, then highlight diffs relative to [os_map] in the output for first goal.
+ [os_map] contains sigma for the old proof step and the goal map created by
+ [Proof_diffs.make_goal_map].
+
+ This function prints only the focused goals unless the corresponding option [enable_unfocused_goal_printing] is set.
+ [seeds] is for printing dependent evars (mainly for emacs proof tree mode). [shelf] is from
+ Proof.proof and is used to identify shelved goals in a message if there are no more subgoals but
+ there are non-instantiated existential variables. [stack] is used to print summary info on unfocused
+ goals.
+*)
+val pr_subgoals : ?pr_first:bool -> ?diffs:bool -> ?os_map:(evar_map * Evar.t Evar.Map.t) -> Pp.t option -> evar_map
+ -> seeds:goal list -> shelf:goal list -> stack:int list
+ -> unfocused: goal list -> goals:goal list -> Pp.t
val pr_subgoal : int -> evar_map -> goal list -> Pp.t
-val pr_concl : int -> evar_map -> goal -> Pp.t
+(** [pr_concl n ~diffs ~og_s sigma g] prints the conclusion of the goal [g] using [sigma]. The output
+ is labelled "subgoal [n]". If [diffs] is true, highlight the differences between the old conclusion,
+ [og_s], and [g]+[sigma]. [og_s] is a record containing the old goal and sigma, e.g. [{ it = g ; sigma = sigma }].
+*)
+val pr_concl : int -> ?diffs:bool -> ?og_s:(goal sigma) -> evar_map -> goal -> Pp.t
+
+(** [pr_open_subgoals_diff ~quiet ~diffs ~oproof proof] shows the context for [proof] as used by, for example, coqtop.
+ The first active goal is printed with all its antecedents and the conclusion. The other active goals only show their
+ conclusions. If [diffs] is true, highlight the differences between the old proof, [oproof], and [proof]. [quiet]
+ disables printing messages as Feedback.
+*)
+val pr_open_subgoals_diff : ?quiet:bool -> ?diffs:bool -> ?oproof:Proof.t -> Proof.t -> Pp.t
val pr_open_subgoals : proof:Proof.t -> Pp.t
val pr_nth_open_subgoal : proof:Proof.t -> int -> Pp.t
val pr_evar : evar_map -> (Evar.t * evar_info) -> Pp.t
@@ -197,11 +220,14 @@ val pr_ne_evar_set : Pp.t -> Pp.t -> evar_map ->
Evar.Set.t -> Pp.t
val pr_prim_rule : prim_rule -> Pp.t
+[@@ocaml.deprecated "[pr_prim_rule] is scheduled to be removed along with the legacy proof engine"]
+
+val print_and_diff : Proof.t option -> Proof.t option -> unit
(** Backwards compatibility *)
val prterm : constr -> Pp.t (** = pr_lconstr *)
-
+[@@ocaml.deprecated "The global printing API is deprecated, please use the _env functions"]
(** Declarations for the "Print Assumption" command *)
type axiom =
@@ -211,7 +237,7 @@ type axiom =
type context_object =
| Variable of Id.t (* A section variable or a Let definition *)
- | Axiom of axiom * (Label.t * Context.Rel.t * types) list
+ | Axiom of axiom * (Label.t * Constr.rel_context * types) list
| Opaque of Constant.t (* An opaque constant. *)
| Transparent of Constant.t
@@ -223,14 +249,3 @@ val pr_assumptionset : env -> evar_map -> types ContextObjectMap.t -> Pp.t
val pr_goal_by_id : proof:Proof.t -> Id.t -> Pp.t
-type printer_pr = {
- pr_subgoals : ?pr_first:bool -> Pp.t option -> evar_map -> seeds:goal list -> shelf:goal list -> stack:int list -> unfocused:goal list -> goals:goal list -> Pp.t;
-
- pr_subgoal : int -> evar_map -> goal list -> Pp.t;
- pr_goal : goal sigma -> Pp.t;
-}
-
-val set_printer_pr : printer_pr -> unit
-
-val default_printer_pr : printer_pr
-
diff --git a/printing/printing.mllib b/printing/printing.mllib
index 86b68d8f..deb52ad2 100644
--- a/printing/printing.mllib
+++ b/printing/printing.mllib
@@ -1,7 +1,7 @@
Genprint
Pputils
Ppconstr
+Proof_diffs
Printer
Printmod
Prettyp
-Ppvernac
diff --git a/printing/printmod.ml b/printing/printmod.ml
index e076c10f..e2d9850b 100644
--- a/printing/printmod.ml
+++ b/printing/printmod.ml
@@ -103,9 +103,7 @@ let print_one_inductive env sigma mib ((_,i) as ind) =
let envpar = push_rel_context params env in
let inst =
if Declareops.inductive_is_polymorphic mib then
- let ctx = Declareops.inductive_polymorphic_context mib in
- let ctx = Univ.UContext.make (u, Univ.AUContext.instantiate u ctx) in
- Printer.pr_universe_instance sigma ctx
+ Printer.pr_universe_instance sigma u
else mt ()
in
hov 0 (
@@ -140,7 +138,7 @@ let print_mutual_inductive env mind mib udecl =
(AUContext.instance (Declareops.inductive_polymorphic_context mib)))
else []
in
- let bl = Universes.universe_binders_with_opt_names (IndRef (mind, 0)) univs udecl in
+ let bl = UnivNames.universe_binders_with_opt_names (IndRef (mind, 0)) univs udecl in
let sigma = Evd.from_ctx (UState.of_binders bl) in
hov 0 (Printer.pr_polymorphic (Declareops.inductive_is_polymorphic mib) ++
Printer.pr_cumulative
@@ -183,7 +181,7 @@ let print_record env mind mib udecl =
let cstrtype = hnf_prod_applist_assum env nparamdecls cstrtypes.(0) args in
let fields = get_fields cstrtype in
let envpar = push_rel_context params env in
- let bl = Universes.universe_binders_with_opt_names (IndRef (mind,0))
+ let bl = UnivNames.universe_binders_with_opt_names (IndRef (mind,0))
(Array.to_list (Univ.Instance.to_array u)) udecl in
let sigma = Evd.from_ctx (UState.of_binders bl) in
let keyword =
@@ -217,7 +215,7 @@ let print_record env mind mib udecl =
)
let pr_mutual_inductive_body env mind mib udecl =
- if mib.mind_record <> None && not !Flags.raw_print then
+ if mib.mind_record != NotRecord && not !Flags.raw_print then
print_record env mind mib udecl
else
print_mutual_inductive env mind mib udecl
@@ -323,7 +321,6 @@ let print_body is_impl env mp (l,body) =
else Univ.Instance.empty
in
let ctx = Univ.UContext.make (u, Univ.AUContext.instantiate u ctx) in
- let sigma = Evd.empty in
(match cb.const_body with
| Def _ -> def "Definition" ++ spc ()
| OpaqueDef _ when is_impl -> def "Theorem" ++ spc ()
@@ -332,17 +329,17 @@ let print_body is_impl env mp (l,body) =
| None -> mt ()
| Some env ->
str " :" ++ spc () ++
- hov 0 (Printer.pr_ltype_env env sigma
+ hov 0 (Printer.pr_ltype_env env (Evd.from_env env)
(Vars.subst_instance_constr u
cb.const_type)) ++
(match cb.const_body with
| Def l when is_impl ->
spc () ++
hov 2 (str ":= " ++
- Printer.pr_lconstr_env env sigma
+ Printer.pr_lconstr_env env (Evd.from_env env)
(Vars.subst_instance_constr u (Mod_subst.force_constr l)))
| _ -> mt ()) ++ str "." ++
- Printer.pr_universe_ctx sigma ctx)
+ Printer.pr_universe_ctx (Evd.from_env env) ctx)
| SFBmind mib ->
try
let env = Option.get env in
@@ -387,7 +384,7 @@ let rec print_typ_expr env mp locals mty =
let s = String.concat "." (List.map Id.to_string idl) in
(* XXX: What should env and sigma be here? *)
let env = Global.env () in
- let sigma = Evd.empty in
+ let sigma = Evd.from_env env in
hov 2 (print_typ_expr env' mp locals me ++ spc() ++ str "with" ++ spc()
++ def "Definition"++ spc() ++ str s ++ spc() ++ str ":="++ spc()
++ Printer.pr_lconstr_env env sigma c)
diff --git a/printing/printmod.mli b/printing/printmod.mli
index b0b0b0a3..48ba866c 100644
--- a/printing/printmod.mli
+++ b/printing/printmod.mli
@@ -15,6 +15,6 @@ val printable_body : DirPath.t -> bool
val pr_mutual_inductive_body : Environ.env ->
MutInd.t -> Declarations.mutual_inductive_body ->
- Universes.univ_name_list option -> Pp.t
+ UnivNames.univ_name_list option -> Pp.t
val print_module : bool -> ModPath.t -> Pp.t
val print_modtype : ModPath.t -> Pp.t
diff --git a/printing/proof_diffs.ml b/printing/proof_diffs.ml
new file mode 100644
index 00000000..0b630b39
--- /dev/null
+++ b/printing/proof_diffs.ml
@@ -0,0 +1,635 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(*
+Displays the differences between successive proof steps in coqtop and CoqIDE.
+Proof General requires minor changes to make the diffs visible, but this code
+shouldn't break the existing version of PG. See pp_diff.ml for details on how
+the diff works.
+
+Diffs are computed for the hypotheses and conclusion of each goal in the new
+proof with its matching goal in the old proof.
+
+Diffs can be enabled in coqtop with 'Set Diffs "on"|"off"|"removed"' or
+'-diffs on|off|removed' on the OS command line. In CoqIDE, they can be enabled
+from the View menu. The "on" option shows only the new item with added text,
+while "removed" shows each modified item twice--once with the old value showing
+removed text and once with the new value showing added text.
+
+In CoqIDE, colors and highlights can be set in the Edit/Preferences/Tags panel.
+For coqtop, these can be set through the COQ_COLORS environment variable.
+
+Limitations/Possible enhancements:
+
+- coqtop colors were chosen for white text on a black background. They're
+not the greatest. I didn't want to change the existing green highlight.
+Suggestions welcome.
+
+- coqtop underlines removed text because (per Wikipedia) the ANSI escape code
+for strikeout is not commonly supported (it didn't work on my system). CoqIDE
+uses strikeout on removed text.
+*)
+
+open Pp_diff
+
+let diff_option = ref `OFF
+
+let read_diffs_option () = match !diff_option with
+| `OFF -> "off"
+| `ON -> "on"
+| `REMOVED -> "removed"
+
+let write_diffs_option = function
+| "off" -> diff_option := `OFF
+| "on" -> diff_option := `ON
+| "removed" -> diff_option := `REMOVED
+| _ -> CErrors.user_err Pp.(str "Diffs option only accepts the following values: \"off\", \"on\", \"removed\".")
+
+let _ =
+ Goptions.(declare_string_option {
+ optdepr = false;
+ optname = "show diffs in proofs";
+ optkey = ["Diffs"];
+ optread = read_diffs_option;
+ optwrite = write_diffs_option
+ })
+
+let show_diffs () = !diff_option <> `OFF;;
+let show_removed () = !diff_option = `REMOVED;;
+
+
+(* DEBUG/UNIT TEST *)
+let cfprintf oc = Printf.(kfprintf (fun oc -> fprintf oc "") oc)
+let log_out_ch = ref stdout
+[@@@ocaml.warning "-32"]
+let cprintf s = cfprintf !log_out_ch s
+[@@@ocaml.warning "+32"]
+
+module StringMap = Map.Make(String);;
+
+let tokenize_string s =
+ (* todo: cLexer changes buff as it proceeds. Seems like that should be saved, too.
+ But I don't understand how it's used--it looks like things get appended to it but
+ it never gets cleared. *)
+ let rec stream_tok acc str =
+ let e = Stream.next str in
+ if Tok.(equal e EOI) then
+ List.rev acc
+ else
+ stream_tok ((Tok.extract_string e) :: acc) str
+ in
+ let st = CLexer.get_lexer_state () in
+ try
+ let istr = Stream.of_string s in
+ let lex = CLexer.lexer.Plexing.tok_func istr in
+ let toks = stream_tok [] (fst lex) in
+ CLexer.set_lexer_state st;
+ toks
+ with exn ->
+ CLexer.set_lexer_state st;
+ raise (Diff_Failure "Input string is not lexable");;
+
+
+type hyp_info = {
+ idents: string list;
+ rhs_pp: Pp.t;
+ mutable done_: bool;
+}
+
+(* Generate the diffs between the old and new hyps.
+ This works by matching lines with the hypothesis name and diffing the right-hand side.
+ Lines that have multiple names such as "n, m : nat" are handled specially to account
+ for, say, the addition of m to a pre-existing "n : nat".
+ *)
+let diff_hyps o_line_idents o_map n_line_idents n_map =
+ let rv : Pp.t list ref = ref [] in
+
+ let is_done ident map = (StringMap.find ident map).done_ in
+ let exists ident map =
+ try let _ = StringMap.find ident map in true
+ with Not_found -> false in
+ let contains l ident = try [List.find (fun x -> x = ident) l] with Not_found -> [] in
+
+ let output old_ids_uo new_ids =
+ (* use the order from the old line in case it's changed in the new *)
+ let old_ids = if old_ids_uo = [] then [] else
+ let orig = (StringMap.find (List.hd old_ids_uo) o_map).idents in
+ List.concat (List.map (contains orig) old_ids_uo)
+ in
+
+ let setup ids map = if ids = [] then ("", Pp.mt ()) else
+ let open Pp in
+ let rhs_pp = (StringMap.find (List.hd ids) map).rhs_pp in
+ let pp_ids = List.map (fun x -> str x) ids in
+ let hyp_pp = List.fold_left (fun l1 l2 -> l1 ++ str ", " ++ l2) (List.hd pp_ids) (List.tl pp_ids) ++ rhs_pp in
+ (string_of_ppcmds hyp_pp, hyp_pp)
+ in
+
+ let (o_line, o_pp) = setup old_ids o_map in
+ let (n_line, n_pp) = setup new_ids n_map in
+
+ let hyp_diffs = diff_str ~tokenize_string o_line n_line in
+ let (has_added, has_removed) = has_changes hyp_diffs in
+ if show_removed () && has_removed then begin
+ let o_entry = StringMap.find (List.hd old_ids) o_map in
+ o_entry.done_ <- true;
+ rv := (add_diff_tags `Removed o_pp hyp_diffs) :: !rv;
+ end;
+ if n_line <> "" then begin
+ let n_entry = StringMap.find (List.hd new_ids) n_map in
+ n_entry.done_ <- true;
+ rv := (add_diff_tags `Added n_pp hyp_diffs) :: !rv
+ end
+ in
+
+ (* process identifier level diff *)
+ let process_ident_diff diff =
+ let (dtype, ident) = get_dinfo diff in
+ match dtype with
+ | `Removed ->
+ if dtype = `Removed then begin
+ let o_idents = (StringMap.find ident o_map).idents in
+ (* only show lines that have all idents removed here; other removed idents appear later *)
+ if show_removed () &&
+ List.for_all (fun x -> not (exists x n_map)) o_idents then
+ output (List.rev o_idents) []
+ end
+ | _ -> begin (* Added or Common case *)
+ let n_idents = (StringMap.find ident n_map).idents in
+
+ (* Process a new hyp line, possibly splitting it. Duplicates some of
+ process_ident iteration, but easier to understand this way *)
+ let process_line ident2 =
+ if not (is_done ident2 n_map) then begin
+ let n_ids_list : string list ref = ref [] in
+ let o_ids_list : string list ref = ref [] in
+ let fst_omap_idents = ref None in
+ let add ids id map =
+ ids := id :: !ids;
+ (StringMap.find id map).done_ <- true in
+
+ (* get identifiers shared by one old and one new line, plus
+ other Added in new and other Removed in old *)
+ let process_split ident3 =
+ if not (is_done ident3 n_map) then begin
+ let this_omap_idents = try Some (StringMap.find ident3 o_map).idents
+ with Not_found -> None in
+ if !fst_omap_idents = None then
+ fst_omap_idents := this_omap_idents;
+ match (!fst_omap_idents, this_omap_idents) with
+ | (Some fst, Some this) when fst == this -> (* yes, == *)
+ add n_ids_list ident3 n_map;
+ (* include, in old order, all undone Removed idents in old *)
+ List.iter (fun x -> if x = ident3 || not (is_done x o_map) && not (exists x n_map) then
+ (add o_ids_list x o_map)) fst
+ | (_, None) ->
+ add n_ids_list ident3 n_map (* include all undone Added idents in new *)
+ | _ -> ()
+ end in
+ List.iter process_split n_idents;
+ output (List.rev !o_ids_list) (List.rev !n_ids_list)
+ end in
+ List.iter process_line n_idents (* O(n^2), so sue me *)
+ end in
+
+ let cvt s = Array.of_list (List.concat s) in
+ let ident_diffs = diff_strs (cvt o_line_idents) (cvt n_line_idents) in
+ List.iter process_ident_diff ident_diffs;
+ List.rev !rv;;
+
+
+type 'a hyp = (Names.Id.t list * 'a option * 'a)
+type 'a reified_goal = { name: string; ty: 'a; hyps: 'a hyp list; env : Environ.env; sigma: Evd.evar_map }
+
+(* XXX: Port to proofview, one day. *)
+(* open Proofview *)
+module CDC = Context.Compacted.Declaration
+
+let to_tuple : Constr.compacted_declaration -> (Names.Id.t list * 'pc option * 'pc) =
+ let open CDC in function
+ | LocalAssum(idl, tm) -> (idl, None, tm)
+ | LocalDef(idl,tdef,tm) -> (idl, Some tdef, tm);;
+
+(* XXX: Very unfortunately we cannot use the Proofview interface as
+ Proof is still using the "legacy" one. *)
+let process_goal_concl sigma g : Constr.t * Environ.env =
+ let env = Goal.V82.env sigma g in
+ let ty = Goal.V82.concl sigma g in
+ let ty = EConstr.to_constr sigma ty in
+ (ty, env)
+
+let process_goal sigma g : Constr.t reified_goal =
+ let env = Goal.V82.env sigma g in
+ let hyps = Goal.V82.hyps sigma g in
+ let ty = Goal.V82.concl sigma g in
+ let name = Goal.uid g in
+ (* There is a Constr/Econstr mess here... *)
+ let ty = EConstr.to_constr sigma ty in
+ (* compaction is usually desired [eg for better display] *)
+ let hyps = Termops.compact_named_context (Environ.named_context_of_val hyps) in
+ let hyps = List.map to_tuple hyps in
+ { name; ty; hyps; env; sigma };;
+
+let pr_letype_core goal_concl_style env sigma t =
+ Ppconstr.pr_lconstr_expr (Constrextern.extern_type goal_concl_style env sigma t)
+
+let pp_of_type env sigma ty =
+ pr_letype_core true env sigma EConstr.(of_constr ty)
+
+let pr_leconstr_core goal_concl_style env sigma t =
+ Ppconstr.pr_lconstr_expr (Constrextern.extern_constr goal_concl_style env sigma t)
+
+let pr_lconstr_env env sigma c = pr_leconstr_core false env sigma (EConstr.of_constr c)
+
+let diff_concl ?og_s nsigma ng =
+ let open Evd in
+ let o_concl_pp = match og_s with
+ | Some { it=og; sigma=osigma } ->
+ let (oty, oenv) = process_goal_concl osigma og in
+ pp_of_type oenv osigma oty
+ | None -> Pp.mt()
+ in
+ let (nty, nenv) = process_goal_concl nsigma ng in
+ let n_concl_pp = pp_of_type nenv nsigma nty in
+
+ let show_removed = Some (show_removed ()) in
+
+ diff_pp_combined ~tokenize_string ?show_removed o_concl_pp n_concl_pp
+
+(* fetch info from a goal, returning (idents, map, concl_pp) where
+idents is a list with one entry for each hypothesis, in which each entry
+is the list of idents on the lhs of the hypothesis. map is a map from
+ident to hyp_info reoords. For example: for the hypotheses:
+ b : bool
+ n, m : nat
+
+idents will be [ ["b"]; ["n"; "m"] ]
+
+map will contain:
+ "b" -> { ["b"], Pp.t for ": bool"; false }
+ "n" -> { ["n"; "m"], Pp.t for ": nat"; false }
+ "m" -> { ["n"; "m"], Pp.t for ": nat"; false }
+ where the last two entries share the idents list.
+
+concl_pp is the conclusion as a Pp.t
+*)
+let goal_info goal sigma =
+ let map = ref StringMap.empty in
+ let line_idents = ref [] in
+ let build_hyp_info env sigma hyp =
+ let (names, body, ty) = hyp in
+ let open Pp in
+ let idents = List.map (fun x -> Names.Id.to_string x) names in
+
+ line_idents := idents :: !line_idents;
+ let mid = match body with
+ | Some c ->
+ let pb = pr_lconstr_env env sigma c in
+ let pb = if Constr.isCast c then surround pb else pb in
+ str " := " ++ pb
+ | None -> mt() in
+ let ts = pp_of_type env sigma ty in
+ let rhs_pp = mid ++ str " : " ++ ts in
+
+ let make_entry () = { idents; rhs_pp; done_ = false } in
+ List.iter (fun ident -> map := (StringMap.add ident (make_entry ()) !map); ()) idents
+ in
+
+ try
+ let { ty=ty; hyps=hyps; env=env } = process_goal sigma goal in
+ List.iter (build_hyp_info env sigma) (List.rev hyps);
+ let concl_pp = pp_of_type env sigma ty in
+ ( List.rev !line_idents, !map, concl_pp )
+ with _ -> ([], !map, Pp.mt ());;
+
+let diff_goal_info o_info n_info =
+ let (o_line_idents, o_hyp_map, o_concl_pp) = o_info in
+ let (n_line_idents, n_hyp_map, n_concl_pp) = n_info in
+ let show_removed = Some (show_removed ()) in
+ let concl_pp = diff_pp_combined ~tokenize_string ?show_removed o_concl_pp n_concl_pp in
+
+ let hyp_diffs_list = diff_hyps o_line_idents o_hyp_map n_line_idents n_hyp_map in
+ (hyp_diffs_list, concl_pp)
+
+let hyp_list_to_pp hyps =
+ let open Pp in
+ match hyps with
+ | h :: tl -> List.fold_left (fun x y -> x ++ cut () ++ y) h tl
+ | [] -> mt ();;
+
+let unwrap g_s =
+ match g_s with
+ | Some g_s ->
+ let goal = Evd.sig_it g_s in
+ let sigma = Refiner.project g_s in
+ goal_info goal sigma
+ | None -> ([], StringMap.empty, Pp.mt ())
+
+let diff_goal_ide og_s ng nsigma =
+ diff_goal_info (unwrap og_s) (goal_info ng nsigma)
+
+let diff_goal ?og_s ng ns =
+ let (hyps_pp_list, concl_pp) = diff_goal_info (unwrap og_s) (goal_info ng ns) in
+ let open Pp in
+ v 0 (
+ (hyp_list_to_pp hyps_pp_list) ++ cut () ++
+ str "============================" ++ cut () ++
+ concl_pp);;
+
+
+(*** Code to determine which calls to compare between the old and new proofs ***)
+
+open Constrexpr
+open Glob_term
+open Names
+open CAst
+
+(* Compare the old and new proof trees to identify the correspondence between
+new and old goals. Returns a map from the new evar name to the old,
+e.g. "Goal2" -> "Goal1". Assumes that proof steps only rewrite CEvar nodes
+and that CEvar nodes cannot contain other CEvar nodes.
+
+The comparison works this way:
+1. Traverse the old and new trees together (ogname = "", ot != nt):
+- if the old and new trees both have CEvar nodes, add an entry to the map from
+ the new evar name to the old evar name. (Position of goals is preserved but
+ evar names may not be--see below.)
+- if the old tree has a CEvar node and the new tree has a different type of node,
+ we've found a changed goal. Set ogname to the evar name of the old goal and
+ go to step 2.
+- any other mismatch violates the assumptions, raise an exception
+2. Traverse the new tree from the point of the difference (ogname <> "", ot = nt).
+- if the node is a CEvar, generate a map entry from the new evar name to ogname.
+
+Goal ids for unchanged goals appear to be preserved across proof steps.
+However, the evar name associated with a goal id may change in a proof step
+even if that goal is not changed by the tactic. You can see this by enabling
+the call to db_goal_map and entering the following:
+
+ Parameter P : nat -> Prop.
+ Goal (P 1 /\ P 2 /\ P 3) /\ P 4.
+ split.
+ Show Proof.
+ split.
+ Show Proof.
+
+ Which gives you this summarized output:
+
+ > split.
+ New Goals: 3 -> Goal 4 -> Goal0 <--- goal 4 is "Goal0"
+ Old Goals: 1 -> Goal
+ Goal map: 3 -> 1 4 -> 1
+ > Show Proof.
+ (conj ?Goal ?Goal0) <--- goal 4 is the rightmost goal in the proof
+ > split.
+ New Goals: 6 -> Goal0 7 -> Goal1 4 -> Goal <--- goal 4 is now "Goal"
+ Old Goals: 3 -> Goal 4 -> Goal0
+ Goal map: 6 -> 3 7 -> 3
+ > Show Proof.
+ (conj (conj ?Goal0 ?Goal1) ?Goal) <--- goal 4 is still the rightmost goal in the proof
+ *)
+let match_goals ot nt =
+ let nevar_to_oevar = ref StringMap.empty in
+ (* ogname is "" when there is no difference on the current path.
+ It's set to the old goal's evar name once a rewitten goal is found,
+ at which point the code only searches for the replacing goals
+ (and ot is set to nt). *)
+ let rec match_goals_r ogname ot nt =
+ let constr_expr ogname exp exp2 =
+ match_goals_r ogname exp.v exp2.v
+ in
+ let constr_expr_opt ogname exp exp2 =
+ match exp, exp2 with
+ | Some expa, Some expb -> constr_expr ogname expa expb
+ | None, None -> ()
+ | _, _ -> raise (Diff_Failure "Unable to match goals betwen old and new proof states (1)")
+ in
+ let local_binder_expr ogname exp exp2 =
+ match exp, exp2 with
+ | CLocalAssum (nal,bk,ty), CLocalAssum(nal2,bk2,ty2) ->
+ constr_expr ogname ty ty2
+ | CLocalDef (n,c,t), CLocalDef (n2,c2,t2) ->
+ constr_expr ogname c c2;
+ constr_expr_opt ogname t t2
+ | CLocalPattern p, CLocalPattern p2 ->
+ let (p,ty), (p2,ty2) = p.v,p2.v in
+ constr_expr_opt ogname ty ty2
+ | _, _ -> raise (Diff_Failure "Unable to match goals betwen old and new proof states (2)")
+ in
+ let recursion_order_expr ogname exp exp2 =
+ match exp, exp2 with
+ | CStructRec, CStructRec -> ()
+ | CWfRec c, CWfRec c2 ->
+ constr_expr ogname c c2
+ | CMeasureRec (m,r), CMeasureRec (m2,r2) ->
+ constr_expr ogname m m2;
+ constr_expr_opt ogname r r2
+ | _, _ -> raise (Diff_Failure "Unable to match goals betwen old and new proof states (3)")
+ in
+ let fix_expr ogname exp exp2 =
+ let (l,(lo,ro),lb,ce1,ce2), (l2,(lo2,ro2),lb2,ce12,ce22) = exp,exp2 in
+ recursion_order_expr ogname ro ro2;
+ List.iter2 (local_binder_expr ogname) lb lb2;
+ constr_expr ogname ce1 ce12;
+ constr_expr ogname ce2 ce22
+ in
+ let cofix_expr ogname exp exp2 =
+ let (l,lb,ce1,ce2), (l2,lb2,ce12,ce22) = exp,exp2 in
+ List.iter2 (local_binder_expr ogname) lb lb2;
+ constr_expr ogname ce1 ce12;
+ constr_expr ogname ce2 ce22
+ in
+ let case_expr ogname exp exp2 =
+ let (ce,l,cp), (ce2,l2,cp2) = exp,exp2 in
+ constr_expr ogname ce ce2
+ in
+ let branch_expr ogname exp exp2 =
+ let (cpe,ce), (cpe2,ce2) = exp.v,exp2.v in
+ constr_expr ogname ce ce2
+ in
+ let constr_notation_substitution ogname exp exp2 =
+ let (ce, cel, cp, lb), (ce2, cel2, cp2, lb2) = exp, exp2 in
+ List.iter2 (constr_expr ogname) ce ce2;
+ List.iter2 (fun a a2 -> List.iter2 (constr_expr ogname) a a2) cel cel2;
+ List.iter2 (fun a a2 -> List.iter2 (local_binder_expr ogname) a a2) lb lb2
+ in
+ begin
+ match ot, nt with
+ | CRef (ref,us), CRef (ref2,us2) -> ()
+ | CFix (id,fl), CFix (id2,fl2) ->
+ List.iter2 (fix_expr ogname) fl fl2
+ | CCoFix (id,cfl), CCoFix (id2,cfl2) ->
+ List.iter2 (cofix_expr ogname) cfl cfl2
+ | CProdN (bl,c2), CProdN (bl2,c22)
+ | CLambdaN (bl,c2), CLambdaN (bl2,c22) ->
+ List.iter2 (local_binder_expr ogname) bl bl2;
+ constr_expr ogname c2 c22
+ | CLetIn (na,c1,t,c2), CLetIn (na2,c12,t2,c22) ->
+ constr_expr ogname c1 c12;
+ constr_expr_opt ogname t t2;
+ constr_expr ogname c2 c22
+ | CAppExpl ((isproj,ref,us),args), CAppExpl ((isproj2,ref2,us2),args2) ->
+ List.iter2 (constr_expr ogname) args args2
+ | CApp ((isproj,f),args), CApp ((isproj2,f2),args2) ->
+ constr_expr ogname f f2;
+ List.iter2 (fun a a2 -> let (c, _) = a and (c2, _) = a2 in
+ constr_expr ogname c c2) args args2
+ | CRecord fs, CRecord fs2 ->
+ List.iter2 (fun a a2 -> let (_, c) = a and (_, c2) = a2 in
+ constr_expr ogname c c2) fs fs2
+ | CCases (sty,rtnpo,tms,eqns), CCases (sty2,rtnpo2,tms2,eqns2) ->
+ constr_expr_opt ogname rtnpo rtnpo2;
+ List.iter2 (case_expr ogname) tms tms2;
+ List.iter2 (branch_expr ogname) eqns eqns2
+ | CLetTuple (nal,(na,po),b,c), CLetTuple (nal2,(na2,po2),b2,c2) ->
+ constr_expr_opt ogname po po2;
+ constr_expr ogname b b2;
+ constr_expr ogname c c2
+ | CIf (c,(na,po),b1,b2), CIf (c2,(na2,po2),b12,b22) ->
+ constr_expr ogname c c2;
+ constr_expr_opt ogname po po2;
+ constr_expr ogname b1 b12;
+ constr_expr ogname b2 b22
+ | CHole (k,naming,solve), CHole (k2,naming2,solve2) -> ()
+ | CPatVar _, CPatVar _ -> ()
+ | CEvar (n,l), CEvar (n2,l2) ->
+ let oevar = if ogname = "" then Id.to_string n else ogname in
+ nevar_to_oevar := StringMap.add (Id.to_string n2) oevar !nevar_to_oevar;
+ List.iter2 (fun x x2 -> let (_, g) = x and (_, g2) = x2 in constr_expr ogname g g2) l l2
+ | CEvar (n,l), nt' ->
+ (* pass down the old goal evar name *)
+ match_goals_r (Id.to_string n) nt' nt'
+ | CSort s, CSort s2 -> ()
+ | CCast (c,c'), CCast (c2,c'2) ->
+ constr_expr ogname c c2;
+ (match c', c'2 with
+ | CastConv a, CastConv a2
+ | CastVM a, CastVM a2
+ | CastNative a, CastNative a2 ->
+ constr_expr ogname a a2
+ | CastCoerce, CastCoerce -> ()
+ | _, _ -> raise (Diff_Failure "Unable to match goals betwen old and new proof states (4)"))
+ | CNotation (ntn,args), CNotation (ntn2,args2) ->
+ constr_notation_substitution ogname args args2
+ | CGeneralization (b,a,c), CGeneralization (b2,a2,c2) ->
+ constr_expr ogname c c2
+ | CPrim p, CPrim p2 -> ()
+ | CDelimiters (key,e), CDelimiters (key2,e2) ->
+ constr_expr ogname e e2
+ | _, _ -> raise (Diff_Failure "Unable to match goals betwen old and new proof states (5)")
+ end
+ in
+
+ (match ot with
+ | Some ot -> match_goals_r "" ot nt
+ | None -> ());
+ !nevar_to_oevar
+
+
+let to_constr p =
+ let open CAst in
+ let pprf = Proof.partial_proof p in
+ (* pprf generally has only one element, but it may have more in the derive plugin *)
+ let t = List.hd pprf in
+ let sigma, env = Pfedit.get_current_context ~p () in
+ let x = Constrextern.extern_constr false env sigma t in (* todo: right options?? *)
+ x.v
+
+
+module GoalMap = Evar.Map
+
+let goal_to_evar g sigma = Id.to_string (Termops.pr_evar_suggested_name g sigma)
+
+[@@@ocaml.warning "-32"]
+let db_goal_map op np ng_to_og =
+ Printf.printf "New Goals: ";
+ let (ngoals,_,_,_,nsigma) = Proof.proof np in
+ List.iter (fun ng -> Printf.printf "%d -> %s " (Evar.repr ng) (goal_to_evar ng nsigma)) ngoals;
+ (match op with
+ | Some op ->
+ let (ogoals,_,_,_,osigma) = Proof.proof op in
+ Printf.printf "\nOld Goals: ";
+ List.iter (fun og -> Printf.printf "%d -> %s " (Evar.repr og) (goal_to_evar og osigma)) ogoals
+ | None -> ());
+ Printf.printf "\nGoal map: ";
+ GoalMap.iter (fun og ng -> Printf.printf "%d -> %d " (Evar.repr og) (Evar.repr ng)) ng_to_og;
+ Printf.printf "\n"
+[@@@ocaml.warning "+32"]
+
+(* Create a map from new goals to old goals for proof diff. The map only
+ has entries for new goals that are not the same as the corresponding old
+ goal; there are no entries for unchanged goals.
+
+ It proceeds as follows:
+ 1. Find the goal ids that were removed from the old proof and that were
+ added in the new proof. If the same goal id is present in both proofs
+ then conclude the goal is unchanged (assumption).
+
+ 2. The code assumes that proof changes only take the form of replacing
+ one or more goal symbols (CEvars) with new terms. Therefore:
+ - if there are no removals, the proofs are the same.
+ - if there are removals but no additions, then there are no new goals
+ that aren't the same as their associated old goals. For the both of
+ these cases, the map is empty because there are no new goals that differ
+ from their old goals
+ - if there is only one removal, then any added goals should be mapped to
+ the removed goal.
+ - if there are more than 2 removals and more than one addition, call
+ match_goals to get a map between old and new evar names, then use this
+ to create the map from new goal ids to old goal ids for the differing goals.
+*)
+let make_goal_map_i op np =
+ let ng_to_og = ref GoalMap.empty in
+ match op with
+ | None -> !ng_to_og
+ | Some op ->
+ let open Goal.Set in
+ let ogs = Proof.all_goals op in
+ let ngs = Proof.all_goals np in
+ let rem_gs = diff ogs ngs in
+ let num_rems = cardinal rem_gs in
+ let add_gs = diff ngs ogs in
+ let num_adds = cardinal add_gs in
+
+ if num_rems = 0 then
+ !ng_to_og (* proofs are the same *)
+ else if num_adds = 0 then
+ !ng_to_og (* only removals *)
+ else if num_rems = 1 then begin
+ (* only 1 removal, some additions *)
+ let removed_g = List.hd (elements rem_gs) in
+ Goal.Set.iter (fun x -> ng_to_og := GoalMap.add x removed_g !ng_to_og) add_gs;
+ !ng_to_og
+ end else begin
+ (* >= 2 removals, >= 1 addition, need to match *)
+ let nevar_to_oevar = match_goals (Some (to_constr op)) (to_constr np) in
+
+ let oevar_to_og = ref StringMap.empty in
+ let (_,_,_,_,osigma) = Proof.proof op in
+ List.iter (fun og -> oevar_to_og := StringMap.add (goal_to_evar og osigma) og !oevar_to_og)
+ (Goal.Set.elements rem_gs);
+
+ try
+ let (_,_,_,_,nsigma) = Proof.proof np in
+ let get_og ng =
+ let nevar = goal_to_evar ng nsigma in
+ let oevar = StringMap.find nevar nevar_to_oevar in
+ let og = StringMap.find oevar !oevar_to_og in
+ og
+ in
+ Goal.Set.iter (fun ng -> ng_to_og := GoalMap.add ng (get_og ng) !ng_to_og) add_gs;
+ !ng_to_og
+ with Not_found -> raise (Diff_Failure "Unable to match goals betwen old and new proof states (6)")
+ end
+
+let make_goal_map op np =
+ let ng_to_og = make_goal_map_i op np in
+ (*db_goal_map op np ng_to_og;*)
+ ng_to_og
diff --git a/printing/proof_diffs.mli b/printing/proof_diffs.mli
new file mode 100644
index 00000000..832393e1
--- /dev/null
+++ b/printing/proof_diffs.mli
@@ -0,0 +1,84 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* diff options *)
+
+(** Controls whether to show diffs. Takes values "on", "off", "removed" *)
+val write_diffs_option : string -> unit
+(** Returns true if the diffs option is "on" or "removed" *)
+val show_diffs : unit -> bool
+
+open Evd
+open Proof_type
+open Environ
+open Constr
+
+(** Computes the diff between the goals of two Proofs and returns
+the highlighted lists of hypotheses and conclusions.
+
+If the strings used to display the goal are not lexable (this is believed
+unlikely), this routine will generate a Diff_Failure. This routine may also
+raise Diff_Failure under some "impossible" conditions.
+
+If you want to make your call especially bulletproof, catch these
+exceptions, print a user-visible message, then recall this routine with
+the first argument set to None, which will skip the diff.
+*)
+val diff_goal_ide : goal sigma option -> goal -> Evd.evar_map -> Pp.t list * Pp.t
+
+(** Computes the diff between two goals
+
+If the strings used to display the goal are not lexable (this is believed
+unlikely), this routine will generate a Diff_Failure. This routine may also
+raise Diff_Failure under some "impossible" conditions.
+
+If you want to make your call especially bulletproof, catch these
+exceptions, print a user-visible message, then recall this routine with
+the first argument set to None, which will skip the diff.
+*)
+val diff_goal : ?og_s:(goal sigma) -> goal -> Evd.evar_map -> Pp.t
+
+(** Convert a string to a list of token strings using the lexer *)
+val tokenize_string : string -> string list
+
+val pr_letype_core : bool -> Environ.env -> Evd.evar_map -> EConstr.types -> Pp.t
+val pr_leconstr_core : bool -> Environ.env -> Evd.evar_map -> EConstr.constr -> Pp.t
+val pr_lconstr_env : env -> evar_map -> constr -> Pp.t
+
+(** Computes diffs for a single conclusion *)
+val diff_concl : ?og_s:goal sigma -> Evd.evar_map -> Goal.goal -> Pp.t
+
+(** Generates a map from [np] to [op] that maps changed goals to their prior
+forms. The map doesn't include entries for unchanged goals; unchanged goals
+will have the same goal id in both versions.
+
+[op] and [np] must be from the same proof document and [op] must be for a state
+before [np]. *)
+val make_goal_map : Proof.t option -> Proof.t -> Evar.t Evar.Map.t
+
+(* Exposed for unit test, don't use these otherwise *)
+(* output channel for the test log file *)
+val log_out_ch : out_channel ref
+
+
+type hyp_info = {
+ idents: string list;
+ rhs_pp: Pp.t;
+ mutable done_: bool;
+}
+
+module StringMap :
+sig
+ type +'a t
+ val empty: hyp_info t
+ val add : string -> hyp_info -> hyp_info t -> hyp_info t
+end
+
+val diff_hyps : string list list -> hyp_info StringMap.t -> string list list -> hyp_info StringMap.t -> Pp.t list
diff --git a/proofs/clenv.ml b/proofs/clenv.ml
index 03ff580a..95e908c4 100644
--- a/proofs/clenv.ml
+++ b/proofs/clenv.ml
@@ -13,8 +13,8 @@ open CErrors
open Util
open Names
open Nameops
-open Term
open Termops
+open Constr
open Namegen
open Environ
open Evd
@@ -26,7 +26,7 @@ open Tacred
open Pretype_errors
open Evarutil
open Unification
-open Misctypes
+open Tactypes
(******************************************************************)
(* Clausal environments *)
@@ -62,9 +62,6 @@ let clenv_get_type_of ce c = Retyping.get_type_of (cl_env ce) (cl_sigma ce) c
exception NotExtensibleClause
-let mk_freelisted c =
- map_fl EConstr.of_constr (mk_freelisted (EConstr.Unsafe.to_constr c))
-
let clenv_push_prod cl =
let typ = whd_all (cl_env cl) (cl_sigma cl) (clenv_type cl) in
let rec clrec typ = match EConstr.kind cl.evd typ with
@@ -73,7 +70,7 @@ let clenv_push_prod cl =
let mv = new_meta () in
let dep = not (noccurn (cl_sigma cl) 1 u) in
let na' = if dep then na else Anonymous in
- let e' = meta_declare mv (EConstr.Unsafe.to_constr t) ~name:na' cl.evd in
+ let e' = meta_declare mv t ~name:na' cl.evd in
let concl = if dep then subst1 (mkMeta mv) u else u in
let def = applist (cl.templval.rebus,[mkMeta mv]) in
{ templval = mk_freelisted def;
@@ -107,8 +104,7 @@ let clenv_environments evd bound t =
let mv = new_meta () in
let dep = not (noccurn evd 1 t2) in
let na' = if dep then na else Anonymous in
- let t1 = EConstr.Unsafe.to_constr t1 in
- let e' = meta_declare mv t1 ~name:na' e in
+ let e' = meta_declare mv t1 ~name:na' e in
clrec (e', (mkMeta mv)::metas) (Option.map ((+) (-1)) n)
(if dep then (subst1 (mkMeta mv) t2) else t2)
| (n, LetIn (na,b,_,t)) -> clrec (e,metas) n (subst1 b t)
@@ -167,13 +163,13 @@ let clenv_assign mv rhs clenv =
user_err Pp.(str "clenv_assign: circularity in unification");
try
if meta_defined clenv.evd mv then
- if not (EConstr.eq_constr clenv.evd (EConstr.of_constr (fst (meta_fvalue clenv.evd mv)).rebus) rhs) then
+ if not (EConstr.eq_constr clenv.evd (fst (meta_fvalue clenv.evd mv)).rebus rhs) then
error_incompatible_inst clenv mv
else
clenv
else
let st = (Conv,TypeNotProcessed) in
- {clenv with evd = meta_assign mv (EConstr.Unsafe.to_constr rhs_fls.rebus,st) clenv.evd}
+ {clenv with evd = meta_assign mv (rhs_fls.rebus,st) clenv.evd}
with Not_found ->
user_err Pp.(str "clenv_assign: undefined meta")
@@ -218,7 +214,7 @@ let clenv_assign mv rhs clenv =
*)
let clenv_metas_in_type_of_meta evd mv =
- (mk_freelisted (meta_instance evd (map_fl EConstr.of_constr (meta_ftype evd mv)))).freemetas
+ (mk_freelisted (meta_instance evd (meta_ftype evd mv))).freemetas
let dependent_in_type_of_metas clenv mvs =
List.fold_right
@@ -288,11 +284,11 @@ let adjust_meta_source evd mv = function
in situations like "ex_intro (fun x => P) ?ev p" *)
let f = function (mv',(Cltyp (_,t) | Clval (_,_,t))) ->
if Metaset.mem mv t.freemetas then
- let f,l = decompose_app evd (EConstr.of_constr t.rebus) in
+ let f,l = decompose_app evd t.rebus in
match EConstr.kind evd f with
| Meta mv'' ->
(match meta_opt_fvalue evd mv'' with
- | Some (c,_) -> match_name (EConstr.of_constr c.rebus) l
+ | Some (c,_) -> match_name c.rebus l
| None -> None)
| _ -> None
else None in
@@ -502,7 +498,6 @@ let clenv_assign_binding clenv k c =
let k_typ = clenv_hnf_constr clenv (clenv_meta_type clenv k) in
let c_typ = nf_betaiota clenv.env clenv.evd (clenv_get_type_of clenv c) in
let status,clenv',c = clenv_unify_binding_type clenv c c_typ k_typ in
- let c = EConstr.Unsafe.to_constr c in
{ clenv' with evd = meta_assign k (c,(Conv,status)) clenv'.evd }
let clenv_match_args bl clenv =
@@ -515,7 +510,7 @@ let clenv_match_args bl clenv =
(fun clenv {CAst.loc;v=(b,c)} ->
let k = meta_of_binder clenv loc mvs b in
if meta_defined clenv.evd k then
- if EConstr.eq_constr clenv.evd (EConstr.of_constr (fst (meta_fvalue clenv.evd k)).rebus) c then clenv
+ if EConstr.eq_constr clenv.evd (fst (meta_fvalue clenv.evd k)).rebus c then clenv
else error_already_defined b
else
clenv_assign_binding clenv k c)
@@ -580,8 +575,8 @@ let make_clenv_binding env sigma = make_clenv_binding_gen false None env sigma
let pr_clenv clenv =
h 0
- (str"TEMPL: " ++ print_constr clenv.templval.rebus ++
- str" : " ++ print_constr clenv.templtyp.rebus ++ fnl () ++
+ (str"TEMPL: " ++ Termops.Internal.print_constr_env clenv.env clenv.evd clenv.templval.rebus ++
+ str" : " ++ Termops.Internal.print_constr_env clenv.env clenv.evd clenv.templtyp.rebus ++ fnl () ++
pr_evar_map (Some 2) clenv.evd)
(****************************************************************)
@@ -677,7 +672,7 @@ let define_with_type sigma env ev c =
let j = Environ.make_judge c ty in
let (sigma, j) = Coercion.inh_conv_coerce_to true env sigma j t in
let (ev, _) = destEvar sigma ev in
- let sigma = Evd.define ev (EConstr.Unsafe.to_constr j.Environ.uj_val) sigma in
+ let sigma = Evd.define ev j.Environ.uj_val sigma in
sigma
let solve_evar_clause env sigma hyp_only clause = function
diff --git a/proofs/clenv.mli b/proofs/clenv.mli
index b85c4fc5..f9506290 100644
--- a/proofs/clenv.mli
+++ b/proofs/clenv.mli
@@ -18,7 +18,7 @@ open Environ
open Evd
open EConstr
open Unification
-open Misctypes
+open Tactypes
(** {6 The Type of Constructions clausale environments.} *)
diff --git a/proofs/clenvtac.ml b/proofs/clenvtac.ml
index 209104ac..544175c6 100644
--- a/proofs/clenvtac.ml
+++ b/proofs/clenvtac.ml
@@ -10,7 +10,7 @@
open Util
open Names
-open Term
+open Constr
open Termops
open Evd
open EConstr
@@ -54,7 +54,7 @@ let clenv_cast_meta clenv =
let clenv_value_cast_meta clenv =
clenv_cast_meta clenv (clenv_value clenv)
-let clenv_pose_dependent_evars with_evars clenv =
+let clenv_pose_dependent_evars ?(with_evars=false) clenv =
let dep_mvs = clenv_dependent clenv in
let env, sigma = clenv.env, clenv.evd in
if not (List.is_empty dep_mvs) && not with_evars then
@@ -75,12 +75,12 @@ let check_tc evd =
let has_typeclass = Evar.Map.exists check (Evd.undefined_map evd) in
(has_typeclass, !has_resolvable)
-let clenv_refine with_evars ?(with_classes=true) clenv =
+let clenv_refine ?(with_evars=false) ?(with_classes=true) clenv =
(** ppedrot: a Goal.enter here breaks things, because the tactic below may
solve goals by side effects, while the compatibility layer keeps those
useless goals. That deserves a FIXME. *)
Proofview.V82.tactic begin fun gl ->
- let clenv = clenv_pose_dependent_evars with_evars clenv in
+ let clenv = clenv_pose_dependent_evars ~with_evars clenv in
let evd' =
if with_classes then
let (has_typeclass, has_resolvable) = check_tc clenv.evd in
@@ -105,10 +105,10 @@ open Unification
let dft = default_unify_flags
-let res_pf ?(with_evars=false) ?(with_classes=true) ?(flags=dft ()) clenv =
+let res_pf ?with_evars ?(with_classes=true) ?(flags=dft ()) clenv =
Proofview.Goal.enter begin fun gl ->
let clenv = clenv_unique_resolver ~flags clenv gl in
- clenv_refine with_evars ~with_classes clenv
+ clenv_refine ?with_evars ~with_classes clenv
end
(* [unifyTerms] et [unify] ne semble pas gérer les Meta, en
diff --git a/proofs/clenvtac.mli b/proofs/clenvtac.mli
index 7c1e300b..d1784784 100644
--- a/proofs/clenvtac.mli
+++ b/proofs/clenvtac.mli
@@ -13,12 +13,11 @@
open Clenv
open EConstr
open Unification
-open Misctypes
(** Tactics *)
val unify : ?flags:unify_flags -> constr -> unit Proofview.tactic
-val clenv_refine : evars_flag -> ?with_classes:bool -> clausenv -> unit Proofview.tactic
-val res_pf : ?with_evars:evars_flag -> ?with_classes:bool -> ?flags:unify_flags -> clausenv -> unit Proofview.tactic
+val clenv_refine : ?with_evars:bool -> ?with_classes:bool -> clausenv -> unit Proofview.tactic
+val res_pf : ?with_evars:bool -> ?with_classes:bool -> ?flags:unify_flags -> clausenv -> unit Proofview.tactic
-val clenv_pose_dependent_evars : evars_flag -> clausenv -> clausenv
+val clenv_pose_dependent_evars : ?with_evars:bool -> clausenv -> clausenv
val clenv_value_cast_meta : clausenv -> constr
diff --git a/proofs/evar_refiner.ml b/proofs/evar_refiner.ml
index 0d197c92..c80f370f 100644
--- a/proofs/evar_refiner.ml
+++ b/proofs/evar_refiner.ml
@@ -25,8 +25,6 @@ open Ltac_pretype
type glob_constr_ltac_closure = ltac_var_map * glob_constr
let depends_on_evar sigma evk _ (pbty,_,t1,t2) =
- let t1 = EConstr.of_constr t1 in
- let t2 = EConstr.of_constr t2 in
try Evar.equal (head_evar sigma t1) evk
with NoHeadEvar ->
try Evar.equal (head_evar sigma t2) evk
@@ -35,12 +33,12 @@ let depends_on_evar sigma evk _ (pbty,_,t1,t2) =
let define_and_solve_constraints evk c env evd =
if Termops.occur_evar evd evk c then
Pretype_errors.error_occur_check env evd evk c;
- let evd = define evk (EConstr.Unsafe.to_constr c) evd in
+ let evd = define evk c evd in
let (evd,pbs) = extract_changed_conv_pbs evd (depends_on_evar evd evk) in
match
List.fold_left
(fun p (pbty,env,t1,t2) -> match p with
- | Success evd -> Evarconv.evar_conv_x full_transparent_state env evd pbty (EConstr.of_constr t1) (EConstr.of_constr t2)
+ | Success evd -> Evarconv.evar_conv_x full_transparent_state env evd pbty t1 t2
| UnifFailure _ as x -> x) (Success evd)
pbs
with
@@ -59,7 +57,7 @@ let w_refine (evk,evi) (ltac_var,rawc) sigma =
Pretyping.fail_evar = false;
Pretyping.expand_evars = true } in
try Pretyping.understand_ltac flags
- env sigma ltac_var (Pretyping.OfType (EConstr.of_constr evi.evar_concl)) rawc
+ env sigma ltac_var (Pretyping.OfType evi.evar_concl) rawc
with e when CErrors.noncritical e ->
let loc = Glob_ops.loc_of_glob_constr rawc in
user_err ?loc
diff --git a/proofs/goal.ml b/proofs/goal.ml
index ba7e458f..c14c0a8a 100644
--- a/proofs/goal.ml
+++ b/proofs/goal.ml
@@ -48,7 +48,7 @@ module V82 = struct
(* Access to ".evar_concl" *)
let concl evars gl =
let evi = Evd.find evars gl in
- EConstr.of_constr evi.Evd.evar_concl
+ evi.Evd.evar_concl
(* Access to ".evar_extra" *)
let extra evars gl =
@@ -61,7 +61,6 @@ module V82 = struct
be shelved. It must not appear as a future_goal, so the future
goals are restored to their initial value after the evar is
created. *)
- let concl = EConstr.Unsafe.to_constr concl in
let prev_future_goals = Evd.save_future_goals evars in
let evi = { Evd.evar_hyps = hyps;
Evd.evar_concl = concl;
@@ -86,7 +85,7 @@ module V82 = struct
if not (Evarutil.occur_evar_upto sigma evk c) then ()
else Pretype_errors.error_occur_check Environ.empty_env sigma evk c
in
- Evd.define evk (EConstr.Unsafe.to_constr c) sigma
+ Evd.define evk c sigma
(* Instantiates a goal with an open term, using name of goal for evk' *)
let partial_solution_to sigma evk evk' c =
@@ -100,7 +99,9 @@ module V82 = struct
let same_goal evars1 gl1 evars2 gl2 =
let evi1 = Evd.find evars1 gl1 in
let evi2 = Evd.find evars2 gl2 in
- Constr.equal evi1.Evd.evar_concl evi2.Evd.evar_concl &&
+ let c1 = EConstr.Unsafe.to_constr evi1.Evd.evar_concl in
+ let c2 = EConstr.Unsafe.to_constr evi2.Evd.evar_concl in
+ Constr.equal c1 c2 &&
Environ.eq_named_context_val evi1.Evd.evar_hyps evi2.Evd.evar_hyps
let weak_progress glss gls =
@@ -117,20 +118,6 @@ module V82 = struct
with a good implementation of them.
*)
- (* Used for congruence closure *)
- let new_goal_with sigma gl extra_hyps =
- let evi = Evd.find sigma gl in
- let hyps = evi.Evd.evar_hyps in
- let new_hyps =
- List.fold_right Environ.push_named_context_val extra_hyps hyps in
- let filter = evi.Evd.evar_filter in
- let new_filter = Evd.Filter.extend (List.length extra_hyps) filter in
- let new_evi =
- { evi with Evd.evar_hyps = new_hyps; Evd.evar_filter = new_filter } in
- let new_evi = Typeclasses.mark_unresolvable new_evi in
- let (sigma, evk) = Evarutil.new_pure_evar_full Evd.empty new_evi in
- { Evd.it = evk ; sigma = sigma; }
-
(* Used by the compatibility layer and typeclasses *)
let nf_evar sigma gl =
let evi = Evd.find sigma gl in
@@ -156,3 +143,5 @@ module V82 = struct
) ~init:(concl sigma gl) env
end
+
+module Set = Set.Make(struct type t = goal let compare = Evar.compare end)
diff --git a/proofs/goal.mli b/proofs/goal.mli
index dc986315..a033d6da 100644
--- a/proofs/goal.mli
+++ b/proofs/goal.mli
@@ -64,9 +64,6 @@ module V82 : sig
(* Principal part of tclNOTSAMEGOAL *)
val same_goal : Evd.evar_map -> goal -> Evd.evar_map -> goal -> bool
- (* Used for congruence closure *)
- val new_goal_with : Evd.evar_map -> goal -> Context.Named.t -> goal Evd.sigma
-
(* Used by the compatibility layer and typeclasses *)
val nf_evar : Evd.evar_map -> goal -> goal * Evd.evar_map
@@ -74,3 +71,5 @@ module V82 : sig
val abstract_type : Evd.evar_map -> goal -> EConstr.types
end
+
+module Set : sig include Set.S with type elt = goal end
diff --git a/proofs/goal_select.ml b/proofs/goal_select.ml
new file mode 100644
index 00000000..65a94a2c
--- /dev/null
+++ b/proofs/goal_select.ml
@@ -0,0 +1,68 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Names
+
+(* spiwack: I'm choosing, for now, to have [goal_selector] be a
+ different type than [goal_reference] mostly because if it makes sense
+ to print a goal that is out of focus (or already solved) it doesn't
+ make sense to apply a tactic to it. Hence it the types may look very
+ similar, they do not seem to mean the same thing. *)
+type t =
+ | SelectAlreadyFocused
+ | SelectNth of int
+ | SelectList of (int * int) list
+ | SelectId of Id.t
+ | SelectAll
+
+(* Default goal selector: selector chosen when a tactic is applied
+ without an explicit selector. *)
+let default_goal_selector = ref (SelectNth 1)
+let get_default_goal_selector () = !default_goal_selector
+
+let pr_range_selector (i, j) =
+ if i = j then Pp.int i
+ else Pp.(int i ++ str "-" ++ int j)
+
+let pr_goal_selector = function
+ | SelectAlreadyFocused -> Pp.str "!"
+ | SelectAll -> Pp.str "all"
+ | SelectNth i -> Pp.int i
+ | SelectList l ->
+ Pp.(str "["
+ ++ prlist_with_sep pr_comma pr_range_selector l
+ ++ str "]")
+ | SelectId id -> Names.Id.print id
+
+let parse_goal_selector = function
+ | "!" -> SelectAlreadyFocused
+ | "all" -> SelectAll
+ | i ->
+ let err_msg = "The default selector must be \"all\" or a natural number." in
+ begin try
+ let i = int_of_string i in
+ if i < 0 then CErrors.user_err Pp.(str err_msg);
+ SelectNth i
+ with Failure _ -> CErrors.user_err Pp.(str err_msg)
+ end
+
+let _ = let open Goptions in
+ declare_string_option
+ { optdepr = false;
+ optname = "default goal selector" ;
+ optkey = ["Default";"Goal";"Selector"] ;
+ optread = begin fun () ->
+ Pp.string_of_ppcmds
+ (pr_goal_selector !default_goal_selector)
+ end;
+ optwrite = begin fun n ->
+ default_goal_selector := parse_goal_selector n
+ end
+ }
diff --git a/proofs/goal_select.mli b/proofs/goal_select.mli
new file mode 100644
index 00000000..b1c57238
--- /dev/null
+++ b/proofs/goal_select.mli
@@ -0,0 +1,26 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Names
+
+(* spiwack: I'm choosing, for now, to have [goal_selector] be a
+ different type than [goal_reference] mostly because if it makes sense
+ to print a goal that is out of focus (or already solved) it doesn't
+ make sense to apply a tactic to it. Hence it the types may look very
+ similar, they do not seem to mean the same thing. *)
+type t =
+ | SelectAlreadyFocused
+ | SelectNth of int
+ | SelectList of (int * int) list
+ | SelectId of Id.t
+ | SelectAll
+
+val pr_goal_selector : t -> Pp.t
+val get_default_goal_selector : unit -> t
diff --git a/proofs/logic.ml b/proofs/logic.ml
index e5294715..613581ad 100644
--- a/proofs/logic.ml
+++ b/proofs/logic.ml
@@ -23,7 +23,6 @@ open Typing
open Proof_type
open Type_errors
open Retyping
-open Misctypes
module NamedDecl = Context.Named.Declaration
@@ -63,6 +62,7 @@ let is_unification_error = function
let catchable_exception = function
| CErrors.UserError _ | TypeError _
+ | Notation.NumeralNotationError _
| RefinerError _ | Indrec.RecursionSchemeError _
| Nametab.GlobalizationError _
(* reduction errors *)
@@ -185,6 +185,22 @@ let check_decl_position env sigma sign d =
* on the right side [right] if [toleft=false].
* If [with_dep] then dependent hypotheses are moved accordingly. *)
+(** Move destination for hypothesis *)
+
+type 'id move_location =
+ | MoveAfter of 'id
+ | MoveBefore of 'id
+ | MoveFirst
+ | MoveLast (** can be seen as "no move" when doing intro *)
+
+(** Printing of [move_location] *)
+
+let pr_move_location pr_id = function
+ | MoveAfter id -> brk(1,1) ++ str "after " ++ pr_id id
+ | MoveBefore id -> brk(1,1) ++ str "before " ++ pr_id id
+ | MoveFirst -> str " at top"
+ | MoveLast -> str " at bottom"
+
let move_location_eq m1 m2 = match m1, m2 with
| MoveAfter id1, MoveAfter id2 -> Id.equal id1 id2
| MoveBefore id1, MoveBefore id2 -> Id.equal id1 id2
@@ -236,7 +252,7 @@ let move_hyp sigma toleft (left,declfrom,right) hto =
(first, d::middle)
else
user_err ~hdr:"move_hyp" (str "Cannot move " ++ Id.print (NamedDecl.get_id declfrom) ++
- Miscprint.pr_move_location Id.print hto ++
+ pr_move_location Id.print hto ++
str (if toleft then ": it occurs in the type of " else ": it depends on ")
++ Id.print hyp ++ str ".")
else
@@ -289,7 +305,15 @@ let collect_meta_variables c =
let rec collrec deep acc c = match kind c with
| Meta mv -> if deep then error_unsupported_deep_meta () else mv::acc
| Cast(c,_,_) -> collrec deep acc c
- | (App _| Case _) -> Constr.fold (collrec deep) acc c
+ | Case(ci,p,c,br) ->
+ (* Hack assuming only two situations: the legacy one that branches,
+ if with Metas, are Meta, and the new one with eta-let-expanded
+ branches *)
+ let br = Array.map2 (fun n b -> try snd (Term.decompose_lam_n_decls n b) with UserError _ -> b) ci.ci_cstr_ndecls br in
+ Array.fold_left (collrec deep)
+ (Constr.fold (collrec deep) (Constr.fold (collrec deep) acc p) c)
+ br
+ | App _ -> Constr.fold (collrec deep) acc c
| Proj (_, c) -> collrec deep acc c
| _ -> Constr.fold (collrec true) acc c
in
@@ -301,9 +325,10 @@ let check_meta_variables env sigma c =
let check_conv_leq_goal env sigma arg ty conclty =
if !check then
- let evm, b = Reductionops.infer_conv env sigma (EConstr.of_constr ty) (EConstr.of_constr conclty) in
- if b then evm
- else raise (RefinerError (env, sigma, BadType (arg,ty,conclty)))
+ let ans = Reductionops.infer_conv env sigma (EConstr.of_constr ty) (EConstr.of_constr conclty) in
+ match ans with
+ | Some evm -> evm
+ | None -> raise (RefinerError (env, sigma, BadType (arg,ty,conclty)))
else sigma
exception Stop of EConstr.t list
@@ -387,12 +412,7 @@ let rec mk_refgoals sigma goal goalacc conclty trm =
| Case (ci,p,c,lf) ->
let (acc',lbrty,conclty',sigma,p',c') = mk_casegoals sigma goal goalacc p c in
let sigma = check_conv_leq_goal env sigma trm conclty' conclty in
- let (acc'',sigma, rbranches) =
- Array.fold_left2
- (fun (lacc,sigma,bacc) ty fi ->
- let (r,_,s,b') = mk_refgoals sigma goal lacc ty fi in r,s,(b'::bacc))
- (acc',sigma,[]) lbrty lf
- in
+ let (acc'',sigma,rbranches) = treat_case sigma goal ci lbrty lf acc' in
let lf' = Array.rev_of_list rbranches in
let ans =
if p' == p && c' == c && Array.equal (==) lf' lf then trm
@@ -440,12 +460,7 @@ and mk_hdgoals sigma goal goalacc trm =
| Case (ci,p,c,lf) ->
let (acc',lbrty,conclty',sigma,p',c') = mk_casegoals sigma goal goalacc p c in
- let (acc'',sigma,rbranches) =
- Array.fold_left2
- (fun (lacc,sigma,bacc) ty fi ->
- let (r,_,s,b') = mk_refgoals sigma goal lacc ty fi in r,s,(b'::bacc))
- (acc',sigma,[]) lbrty lf
- in
+ let (acc'',sigma,rbranches) = treat_case sigma goal ci lbrty lf acc' in
let lf' = Array.rev_of_list rbranches in
let ans =
if p' == p && c' == c && Array.equal (==) lf' lf then trm
@@ -483,7 +498,7 @@ and mk_arggoals sigma goal goalacc funty allargs =
let env = Goal.V82.env sigma goal in
raise (RefinerError (env,sigma,CannotApply (t, harg)))
in
- Array.smartfoldmap foldmap (goalacc, funty, sigma) allargs
+ Array.Smart.fold_left_map foldmap (goalacc, funty, sigma) allargs
and mk_casegoals sigma goal goalacc p c =
let env = Goal.V82.env sigma goal in
@@ -497,6 +512,50 @@ and mk_casegoals sigma goal goalacc p c =
let (lbrty,conclty) = type_case_branches_with_names env sigma indspec p c in
(acc'',lbrty,conclty,sigma,p',c')
+and treat_case sigma goal ci lbrty lf acc' =
+ let rec strip_outer_cast c = match kind c with
+ | Cast (c,_,_) -> strip_outer_cast c
+ | _ -> c in
+ let decompose_app_vect c = match kind c with
+ | App (f,cl) -> (f, cl)
+ | _ -> (c,[||]) in
+ let env = Goal.V82.env sigma goal in
+ Array.fold_left3
+ (fun (lacc,sigma,bacc) ty fi l ->
+ if isMeta (strip_outer_cast fi) then
+ (* Support for non-eta-let-expanded Meta as found in *)
+ (* destruct/case with an non eta-let expanded elimination scheme *)
+ let (r,_,s,fi') = mk_refgoals sigma goal lacc ty fi in
+ r,s,(fi'::bacc)
+ else
+ (* Deal with a branch in expanded form of the form
+ Case(ci,p,c,[|eta-let-exp(Meta);...;eta-let-exp(Meta)|]) as
+ if it were not so, so as to preserve compatibility with when
+ destruct/case generated schemes of the form
+ Case(ci,p,c,[|Meta;...;Meta|];
+ CAUTION: it does not deal with the general case of eta-zeta
+ reduced branches having a form different from Meta, as it
+ would be theoretically the case with third-party code *)
+ let n = List.length l in
+ let ctx, body = Term.decompose_lam_n_decls n fi in
+ let head, args = decompose_app_vect body in
+ (* Strip cast because clenv_cast_meta adds a cast when the branch is
+ eta-expanded but when not when the branch has the single-meta
+ form [Meta] *)
+ let head = strip_outer_cast head in
+ if isMeta head then begin
+ assert (args = Context.Rel.to_extended_vect mkRel 0 ctx);
+ let head' = lift (-n) head in
+ let (r,_,s,head'') = mk_refgoals sigma goal lacc ty head' in
+ let fi' = it_mkLambda_or_LetIn (mkApp (head'',args)) ctx in
+ (r,s,fi'::bacc)
+ end
+ else
+ (* Supposed to be meta-free *)
+ let sigma, t'ty = goal_type_of env sigma fi in
+ let sigma = check_conv_leq_goal env sigma fi t'ty ty in
+ (lacc,sigma,fi::bacc))
+ (acc',sigma,[]) lbrty lf ci.ci_pp_info.cstr_tags
let convert_hyp check sign sigma d =
let id = NamedDecl.get_id d in
diff --git a/proofs/logic.mli b/proofs/logic.mli
index dc471bb5..9db54732 100644
--- a/proofs/logic.mli
+++ b/proofs/logic.mli
@@ -58,12 +58,23 @@ val error_no_such_hypothesis : Environ.env -> evar_map -> Id.t -> 'a
val catchable_exception : exn -> bool
+(** Move destination for hypothesis *)
+
+type 'id move_location =
+ | MoveAfter of 'id
+ | MoveBefore of 'id
+ | MoveFirst
+ | MoveLast (** can be seen as "no move" when doing intro *)
+
+val pr_move_location :
+ ('a -> Pp.t) -> 'a move_location -> Pp.t
+
val convert_hyp : bool -> Environ.named_context_val -> evar_map ->
EConstr.named_declaration -> Environ.named_context_val
-val move_hyp_in_named_context : Environ.env -> Evd.evar_map -> Id.t -> Id.t Misctypes.move_location ->
+val move_hyp_in_named_context : Environ.env -> Evd.evar_map -> Id.t -> Id.t move_location ->
Environ.named_context_val -> Environ.named_context_val
val insert_decl_in_named_context : Evd.evar_map ->
- EConstr.named_declaration -> Id.t Misctypes.move_location ->
+ EConstr.named_declaration -> Id.t move_location ->
Environ.named_context_val -> Environ.named_context_val
diff --git a/proofs/miscprint.ml b/proofs/miscprint.ml
index 1a63ff67..ec17b807 100644
--- a/proofs/miscprint.ml
+++ b/proofs/miscprint.ml
@@ -10,7 +10,7 @@
open Pp
open Names
-open Misctypes
+open Tactypes
(** Printing of [intro_pattern] *)
@@ -20,7 +20,7 @@ let rec pr_intro_pattern prc {CAst.v=pat} = match pat with
| IntroNaming p -> pr_intro_pattern_naming p
| IntroAction p -> pr_intro_pattern_action prc p
-and pr_intro_pattern_naming = function
+and pr_intro_pattern_naming = let open Namegen in function
| IntroIdentifier id -> Id.print id
| IntroFresh id -> str "?" ++ Id.print id
| IntroAnonymous -> str "?"
@@ -43,14 +43,6 @@ and pr_or_and_intro_pattern prc = function
hv 0 (prlist_with_sep pr_bar (prlist_with_sep spc (pr_intro_pattern prc)) pll)
++ str "]"
-(** Printing of [move_location] *)
-
-let pr_move_location pr_id = function
- | MoveAfter id -> brk(1,1) ++ str "after " ++ pr_id id
- | MoveBefore id -> brk(1,1) ++ str "before " ++ pr_id id
- | MoveFirst -> str " at top"
- | MoveLast -> str " at bottom"
-
(** Printing of bindings *)
let pr_binding prc = let open CAst in function
| {loc;v=(NamedHyp id, c)} -> hov 1 (Names.Id.print id ++ str " := " ++ cut () ++ prc c)
diff --git a/proofs/miscprint.mli b/proofs/miscprint.mli
index 79790a27..f4e2e683 100644
--- a/proofs/miscprint.mli
+++ b/proofs/miscprint.mli
@@ -8,7 +8,7 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Misctypes
+open Tactypes
(** Printing of [intro_pattern] *)
@@ -18,13 +18,10 @@ val pr_intro_pattern :
val pr_or_and_intro_pattern :
('a -> Pp.t) -> 'a or_and_intro_pattern_expr -> Pp.t
-val pr_intro_pattern_naming : intro_pattern_naming_expr -> Pp.t
+val pr_intro_pattern_naming : Namegen.intro_pattern_naming_expr -> Pp.t
(** Printing of [move_location] *)
-val pr_move_location :
- ('a -> Pp.t) -> 'a move_location -> Pp.t
-
val pr_bindings :
('a -> Pp.t) ->
('a -> Pp.t) -> 'a bindings -> Pp.t
diff --git a/proofs/pfedit.ml b/proofs/pfedit.ml
index 5d137988..e6507332 100644
--- a/proofs/pfedit.ml
+++ b/proofs/pfedit.ml
@@ -51,23 +51,22 @@ let _ = CErrors.register_handler begin function
| _ -> raise CErrors.Unhandled
end
-let get_nth_V82_goal i =
- let p = Proof_global.give_me_the_proof () in
+let get_nth_V82_goal p i =
let goals,_,_,_,sigma = Proof.proof p in
try { it = List.nth goals (i-1) ; sigma }
with Failure _ -> raise NoSuchGoal
-let get_goal_context_gen i =
- let { it=goal ; sigma=sigma; } = get_nth_V82_goal i in
+let get_goal_context_gen p i =
+ let { it=goal ; sigma=sigma; } = get_nth_V82_goal p i in
(sigma, Refiner.pf_env { it=goal ; sigma=sigma; })
let get_goal_context i =
- try get_goal_context_gen i
+ try get_goal_context_gen (Proof_global.give_me_the_proof ()) i
with Proof_global.NoCurrentProof -> CErrors.user_err Pp.(str "No focused proof.")
| NoSuchGoal -> CErrors.user_err Pp.(str "No such goal.")
let get_current_goal_context () =
- try get_goal_context_gen 1
+ try get_goal_context_gen (Proof_global.give_me_the_proof ()) 1
with Proof_global.NoCurrentProof -> CErrors.user_err Pp.(str "No focused proof.")
| NoSuchGoal ->
(* spiwack: returning empty evar_map, since if there is no goal, under focus,
@@ -75,14 +74,18 @@ let get_current_goal_context () =
let env = Global.env () in
(Evd.from_env env, env)
-let get_current_context () =
- try get_goal_context_gen 1
+let get_current_context ?p () =
+ let current_proof_by_default = function
+ | Some p -> p
+ | None -> Proof_global.give_me_the_proof ()
+ in
+ try get_goal_context_gen (current_proof_by_default p) 1
with Proof_global.NoCurrentProof ->
let env = Global.env () in
(Evd.from_env env, env)
| NoSuchGoal ->
(* No more focused goals ? *)
- let p = Proof_global.give_me_the_proof () in
+ let p = (current_proof_by_default p) in
let evd = Proof.in_proof p (fun x -> x) in
(evd, Global.env ())
@@ -100,11 +103,23 @@ let solve ?with_end_tac gi info_lvl tac pr =
| None -> tac
| Some _ -> Proofview.Trace.record_info_trace tac
in
- let tac = match gi with
- | Vernacexpr.SelectNth i -> Proofview.tclFOCUS i i tac
- | Vernacexpr.SelectList l -> Proofview.tclFOCUSLIST l tac
- | Vernacexpr.SelectId id -> Proofview.tclFOCUSID id tac
- | Vernacexpr.SelectAll -> tac
+ let tac = let open Goal_select in match gi with
+ | SelectAlreadyFocused ->
+ let open Proofview.Notations in
+ Proofview.numgoals >>= fun n ->
+ if n == 1 then tac
+ else
+ let e = CErrors.UserError
+ (None,
+ Pp.(str "Expected a single focused goal but " ++
+ int n ++ str " goals are focused."))
+ in
+ Proofview.tclZERO e
+
+ | SelectNth i -> Proofview.tclFOCUS i i tac
+ | SelectList l -> Proofview.tclFOCUSLIST l tac
+ | SelectId id -> Proofview.tclFOCUSID id tac
+ | SelectAll -> tac
in
let tac =
if use_unification_heuristics () then
@@ -121,7 +136,7 @@ let solve ?with_end_tac gi info_lvl tac pr =
with
Proof_global.NoCurrentProof -> CErrors.user_err Pp.(str "No focused proof")
-let by tac = Proof_global.with_current_proof (fun _ -> solve (Vernacexpr.SelectNth 1) None tac)
+let by tac = Proof_global.with_current_proof (fun _ -> solve (Goal_select.SelectNth 1) None tac)
let instantiate_nth_evar_com n com =
Proof_global.simple_with_current_proof (fun _ p -> Proof.V82.instantiate_evar n com p)
@@ -161,7 +176,7 @@ let build_by_tactic ?(side_eff=true) env sigma ?(poly=false) typ tac =
const_entry_body = Future.chain ce.const_entry_body
(fun (pt, _) -> pt, ()) } in
let (cb, ctx), () = Future.force ce.const_entry_body in
- let univs = UState.merge side_eff Evd.univ_rigid univs ctx in
+ let univs = UState.merge ~sideff:side_eff ~extend:true Evd.univ_rigid univs ctx in
cb, status, univs
let refine_by_tactic env sigma ty tac =
@@ -188,8 +203,7 @@ let refine_by_tactic env sigma ty tac =
| [c, _] -> c
| _ -> assert false
in
- let ans = Reductionops.nf_evar sigma ans in
- let ans = EConstr.Unsafe.to_constr ans in
+ let ans = EConstr.to_constr ~abort_on_undefined_evars:false sigma ans in
(** [neff] contains the freshly generated side-effects *)
let neff = Evd.eval_side_effects sigma in
(** Reset the old side-effects *)
@@ -233,7 +247,7 @@ let apply_implicit_tactic tac = (); fun env sigma evk ->
(Environ.named_context env) ->
let tac = Proofview.tclTHEN tac (Proofview.tclEXTEND [] (Proofview.tclZERO (CErrors.UserError (None,Pp.str"Proof is not complete."))) []) in
(try
- let c = Evarutil.nf_evars_universes sigma evi.evar_concl in
+ let c = Evarutil.nf_evars_universes sigma (EConstr.Unsafe.to_constr evi.evar_concl) in
let c = EConstr.of_constr c in
if Evarutil.has_undefined_evars sigma c then raise Exit;
let (ans, _, ctx) =
diff --git a/proofs/pfedit.mli b/proofs/pfedit.mli
index 65cde3a3..5feb5bd6 100644
--- a/proofs/pfedit.mli
+++ b/proofs/pfedit.mli
@@ -24,7 +24,7 @@ open Decl_kinds
proof of mutually dependent theorems) *)
val start_proof :
- Id.t -> ?pl:Univdecls.universe_decl -> goal_kind -> Evd.evar_map -> named_context_val -> EConstr.constr ->
+ Id.t -> ?pl:UState.universe_decl -> goal_kind -> Evd.evar_map -> named_context_val -> EConstr.constr ->
?init_tac:unit Proofview.tactic ->
Proof_global.proof_terminator -> unit
@@ -60,7 +60,7 @@ val get_current_goal_context : unit -> Evd.evar_map * env
If there is no pending proof then it returns the current global
environment and empty evar_map. *)
-val get_current_context : unit -> Evd.evar_map * env
+val get_current_context : ?p:Proof.t -> unit -> Evd.evar_map * env
(** [current_proof_statement] *)
@@ -75,7 +75,7 @@ val current_proof_statement :
tac] applies [tac] to all subgoals. *)
val solve : ?with_end_tac:unit Proofview.tactic ->
- Vernacexpr.goal_selector -> int option -> unit Proofview.tactic ->
+ Goal_select.t -> int option -> unit Proofview.tactic ->
Proof.t -> Proof.t * bool
(** [by tac] applies tactic [tac] to the 1st subgoal of the current
@@ -85,6 +85,9 @@ val solve : ?with_end_tac:unit Proofview.tactic ->
val by : unit Proofview.tactic -> bool
+(** Option telling if unification heuristics should be used. *)
+val use_unification_heuristics : unit -> bool
+
(** [instantiate_nth_evar_com n c] instantiate the [n]th undefined
existential variable of the current focused proof by [c] or raises a
UserError if no proof is focused or if there is no such [n]th
diff --git a/proofs/proof.ml b/proofs/proof.ml
index 51e0a1d6..8bbd82bb 100644
--- a/proofs/proof.ml
+++ b/proofs/proof.ml
@@ -63,6 +63,7 @@ exception CannotUnfocusThisWay
(* Cannot focus on non-existing subgoals *)
exception NoSuchGoals of int * int
+exception NoSuchGoal of Names.Id.t
exception FullyUnfocused
@@ -75,6 +76,10 @@ let _ = CErrors.register_handler begin function
CErrors.user_err ~hdr:"Focus" Pp.(
str"Not every goal in range ["++ int i ++ str","++int j++str"] exist."
)
+ | NoSuchGoal id ->
+ CErrors.user_err
+ ~hdr:"Focus"
+ Pp.(str "No such goal: " ++ str (Names.Id.to_string id) ++ str ".")
| FullyUnfocused -> CErrors.user_err Pp.(str "The proof is not focused")
| _ -> raise CErrors.Unhandled
end
@@ -230,6 +235,37 @@ let focus cond inf i pr =
try _focus cond (Obj.repr inf) i i pr
with CList.IndexOutOfRange -> raise (NoSuchGoals (i,i))
+(* Focus on the goal named id *)
+let focus_id cond inf id pr =
+ let (focused_goals, evar_map) = Proofview.proofview pr.proofview in
+ begin match try Some (Evd.evar_key id evar_map) with Not_found -> None with
+ | Some ev ->
+ begin match CList.safe_index Evar.equal ev focused_goals with
+ | Some i ->
+ (* goal is already under focus *)
+ _focus cond (Obj.repr inf) i i pr
+ | None ->
+ if CList.mem_f Evar.equal ev pr.shelf then
+ (* goal is on the shelf, put it in focus *)
+ let proofview = Proofview.unshelve [ev] pr.proofview in
+ let shelf =
+ CList.filter (fun ev' -> Evar.equal ev ev' |> not) pr.shelf
+ in
+ let pr = { pr with proofview; shelf } in
+ let (focused_goals, _) = Proofview.proofview pr.proofview in
+ let i =
+ (* Now we know that this will succeed *)
+ try CList.index Evar.equal ev focused_goals
+ with Not_found -> assert false
+ in
+ _focus cond (Obj.repr inf) i i pr
+ else
+ raise CannotUnfocusThisWay
+ end
+ | None ->
+ raise (NoSuchGoal id)
+ end
+
let rec unfocus kind pr () =
let cond = cond_of_focus pr in
match test_cond cond kind pr.proofview with
@@ -452,3 +488,12 @@ module V82 = struct
{ pr with proofview ; shelf }
end
+
+let all_goals p =
+ let add gs set =
+ List.fold_left (fun s g -> Goal.Set.add g s) set gs in
+ let (goals,stack,shelf,given_up,_) = proof p in
+ let set = add goals Goal.Set.empty in
+ let set = List.fold_left (fun s gs -> let (g1, g2) = gs in add g1 (add g2 set)) set stack in
+ let set = add shelf set in
+ add given_up set
diff --git a/proofs/proof.mli b/proofs/proof.mli
index c0e832fb..511dcc2e 100644
--- a/proofs/proof.mli
+++ b/proofs/proof.mli
@@ -137,6 +137,9 @@ val done_cond : ?loose_end:bool -> 'a focus_kind -> 'a focus_condition
a need for it? *)
val focus : 'a focus_condition -> 'a -> int -> t -> t
+(* focus on goal named id *)
+val focus_id : 'aa focus_condition -> 'a -> Names.Id.t -> t -> t
+
exception FullyUnfocused
exception CannotUnfocusThisWay
@@ -207,3 +210,6 @@ module V82 : sig
(* Implements the Existential command *)
val instantiate_evar : int -> Constrexpr.constr_expr -> t -> t
end
+
+(* returns the set of all goals in the proof *)
+val all_goals : t -> Goal.Set.t
diff --git a/proofs/proof_bullet.ml b/proofs/proof_bullet.ml
index e22d382f..cc3e79f8 100644
--- a/proofs/proof_bullet.ml
+++ b/proofs/proof_bullet.ml
@@ -10,19 +10,22 @@
open Proof
-type t = Vernacexpr.bullet
+type t =
+ | Dash of int
+ | Star of int
+ | Plus of int
let bullet_eq b1 b2 = match b1, b2 with
-| Vernacexpr.Dash n1, Vernacexpr.Dash n2 -> n1 = n2
-| Vernacexpr.Star n1, Vernacexpr.Star n2 -> n1 = n2
-| Vernacexpr.Plus n1, Vernacexpr.Plus n2 -> n1 = n2
+| Dash n1, Dash n2 -> n1 = n2
+| Star n1, Star n2 -> n1 = n2
+| Plus n1, Plus n2 -> n1 = n2
| _ -> false
let pr_bullet b =
match b with
- | Vernacexpr.Dash n -> Pp.(str (String.make n '-'))
- | Vernacexpr.Star n -> Pp.(str (String.make n '*'))
- | Vernacexpr.Plus n -> Pp.(str (String.make n '+'))
+ | Dash n -> Pp.(str (String.make n '-'))
+ | Star n -> Pp.(str (String.make n '*'))
+ | Plus n -> Pp.(str (String.make n '+'))
type behavior = {
@@ -195,52 +198,5 @@ let put p b =
let suggest p =
(!current_behavior).suggest p
-(**********************************************************)
-(* *)
-(* Default goal selector *)
-(* *)
-(**********************************************************)
-
-
-(* Default goal selector: selector chosen when a tactic is applied
- without an explicit selector. *)
-let default_goal_selector = ref (Vernacexpr.SelectNth 1)
-let get_default_goal_selector () = !default_goal_selector
-
-let pr_range_selector (i, j) =
- if i = j then Pp.int i
- else Pp.(int i ++ str "-" ++ int j)
-
-let pr_goal_selector = function
- | Vernacexpr.SelectAll -> Pp.str "all"
- | Vernacexpr.SelectNth i -> Pp.int i
- | Vernacexpr.SelectList l ->
- Pp.(str "["
- ++ prlist_with_sep pr_comma pr_range_selector l
- ++ str "]")
- | Vernacexpr.SelectId id -> Names.Id.print id
-
-let parse_goal_selector = function
- | "all" -> Vernacexpr.SelectAll
- | i ->
- let err_msg = "The default selector must be \"all\" or a natural number." in
- begin try
- let i = int_of_string i in
- if i < 0 then CErrors.user_err Pp.(str err_msg);
- Vernacexpr.SelectNth i
- with Failure _ -> CErrors.user_err Pp.(str err_msg)
- end
-
-let _ =
- Goptions.(declare_string_option{optdepr = false;
- optname = "default goal selector" ;
- optkey = ["Default";"Goal";"Selector"] ;
- optread = begin fun () ->
- Pp.string_of_ppcmds
- (pr_goal_selector !default_goal_selector)
- end;
- optwrite = begin fun n ->
- default_goal_selector := parse_goal_selector n
- end
- })
-
+let pr_goal_selector = Goal_select.pr_goal_selector
+let get_default_goal_selector = Goal_select.get_default_goal_selector
diff --git a/proofs/proof_bullet.mli b/proofs/proof_bullet.mli
index ffbaa0fa..a09a7ec1 100644
--- a/proofs/proof_bullet.mli
+++ b/proofs/proof_bullet.mli
@@ -14,7 +14,10 @@
(* *)
(**********************************************************)
-type t = Vernacexpr.bullet
+type t =
+ | Dash of int
+ | Star of int
+ | Plus of int
(** A [behavior] is the data of a put function which
is called when a bullet prefixes a tactic, a suggest function
@@ -42,12 +45,8 @@ val register_behavior : behavior -> unit
val put : Proof.t -> t -> Proof.t
val suggest : Proof.t -> Pp.t
-(**********************************************************)
-(* *)
-(* Default goal selector *)
-(* *)
-(**********************************************************)
-
-val pr_goal_selector : Vernacexpr.goal_selector -> Pp.t
-val get_default_goal_selector : unit -> Vernacexpr.goal_selector
-
+(** Deprecated *)
+val pr_goal_selector : Goal_select.t -> Pp.t
+[@@ocaml.deprecated "Please use [Goal_select.pr_goal_selector]"]
+val get_default_goal_selector : unit -> Goal_select.t
+[@@ocaml.deprecated "Please use [Goal_select.get_default_goal_selector]"]
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index d6c0e334..7e250faa 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -78,11 +78,14 @@ type proof_object = {
universes: UState.t;
}
+type opacity_flag = Opaque | Transparent
+
type proof_ending =
| Admitted of Names.Id.t * Decl_kinds.goal_kind * Entries.parameter_entry * UState.t
- | Proved of Vernacexpr.opacity_flag *
- Misctypes.lident option *
+ | Proved of opacity_flag *
+ lident option *
proof_object
+
type proof_terminator = proof_ending -> unit
type closed_proof = proof_object * proof_terminator
@@ -90,11 +93,11 @@ type pstate = {
pid : Id.t; (* the name of the theorem whose proof is being constructed *)
terminator : proof_terminator CEphemeron.key;
endline_tactic : Genarg.glob_generic_argument option;
- section_vars : Context.Named.t option;
+ section_vars : Constr.named_context option;
proof : Proof.t;
strength : Decl_kinds.goal_kind;
mode : proof_mode CEphemeron.key;
- universe_decl: Univdecls.universe_decl;
+ universe_decl: UState.universe_decl;
}
type t = pstate list
@@ -235,13 +238,6 @@ let activate_proof_mode mode =
let disactivate_current_proof_mode () =
CEphemeron.iter_opt !current_proof_mode (fun x -> x.reset ())
-let default_universe_decl =
- let open Misctypes in
- { univdecl_instance = [];
- univdecl_extensible_instance = true;
- univdecl_constraints = Univ.Constraint.empty;
- univdecl_extensible_constraints = true }
-
(** [start_proof sigma id pl str goals terminator] starts a proof of name
[id] with goals [goals] (a list of pairs of environment and
conclusion); [str] describes what kind of theorem/definition this
@@ -250,7 +246,7 @@ let default_universe_decl =
end of the proof to close the proof. The proof is started in the
evar map [sigma] (which can typically contain universe
constraints), and with universe bindings pl. *)
-let start_proof sigma id ?(pl=default_universe_decl) str goals terminator =
+let start_proof sigma id ?(pl=UState.default_univ_decl) str goals terminator =
let initial_state = {
pid = id;
terminator = CEphemeron.create terminator;
@@ -262,7 +258,7 @@ let start_proof sigma id ?(pl=default_universe_decl) str goals terminator =
universe_decl = pl } in
push initial_state pstates
-let start_dependent_proof id ?(pl=default_universe_decl) str goals terminator =
+let start_dependent_proof id ?(pl=UState.default_univ_decl) str goals terminator =
let initial_state = {
pid = id;
terminator = CEphemeron.create terminator;
@@ -340,8 +336,8 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now
have existential variables in the initial types of goals, we need to
normalise them for the kernel. *)
let subst_evar k =
- Proof.in_proof proof (fun m -> Evd.existential_opt_value m k) in
- let nf = Universes.nf_evars_and_universes_opt_subst subst_evar
+ Proof.in_proof proof (fun m -> Evd.existential_opt_value0 m k) in
+ let nf = UnivSubst.nf_evars_and_universes_opt_subst subst_evar
(UState.subst universes) in
let make_body =
if poly || now then
@@ -352,9 +348,8 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now
not (Safe_typing.empty_private_constants = eff))
in
let typ = if allow_deferred then t else nf t in
- let env = Global.env () in
- let used_univs_body = Univops.universes_of_constr env body in
- let used_univs_typ = Univops.universes_of_constr env typ in
+ let used_univs_body = Univops.universes_of_constr body in
+ let used_univs_typ = Univops.universes_of_constr typ in
if allow_deferred then
let initunivs = UState.const_univ_entry ~poly initial_euctx in
let ctx = constrain_variables universes in
@@ -441,8 +436,8 @@ let return_proof ?(allow_partial=false) () =
(** ppedrot: FIXME, this is surely wrong. There is no reason to duplicate
side-effects... This may explain why one need to uniquize side-effects
thereafter... *)
- let proofs =
- List.map (fun (c, _) -> (Evarutil.nf_evars_universes evd (EConstr.Unsafe.to_constr c), eff)) initial_goals in
+ let proofs =
+ List.map (fun (c, _) -> (EConstr.to_constr evd c, eff)) initial_goals in
proofs, Evd.evar_universe_context evd
let close_future_proof ~feedback_id proof =
diff --git a/proofs/proof_global.mli b/proofs/proof_global.mli
index bf35fd65..854ceaa4 100644
--- a/proofs/proof_global.mli
+++ b/proofs/proof_global.mli
@@ -22,7 +22,7 @@ val check_no_pending_proof : unit -> unit
val get_current_proof_name : unit -> Names.Id.t
val get_all_proof_names : unit -> Names.Id.t list
-val discard : Misctypes.lident -> unit
+val discard : Names.lident -> unit
val discard_current : unit -> unit
val discard_all : unit -> unit
@@ -48,11 +48,13 @@ type proof_object = {
universes: UState.t;
}
+type opacity_flag = Opaque | Transparent
+
type proof_ending =
| Admitted of Names.Id.t * Decl_kinds.goal_kind * Entries.parameter_entry *
UState.t
- | Proved of Vernacexpr.opacity_flag *
- Misctypes.lident option *
+ | Proved of opacity_flag *
+ Names.lident option *
proof_object
type proof_terminator
type closed_proof = proof_object * proof_terminator
@@ -69,14 +71,14 @@ val apply_terminator : proof_terminator -> proof_ending -> unit
evar map [sigma] (which can typically contain universe
constraints), and with universe bindings pl. *)
val start_proof :
- Evd.evar_map -> Names.Id.t -> ?pl:Univdecls.universe_decl ->
+ Evd.evar_map -> Names.Id.t -> ?pl:UState.universe_decl ->
Decl_kinds.goal_kind -> (Environ.env * EConstr.types) list ->
proof_terminator -> unit
(** Like [start_proof] except that there may be dependencies between
initial goals. *)
val start_dependent_proof :
- Names.Id.t -> ?pl:Univdecls.universe_decl -> Decl_kinds.goal_kind ->
+ Names.Id.t -> ?pl:UState.universe_decl -> Decl_kinds.goal_kind ->
Proofview.telescope -> proof_terminator -> unit
(** Update the proofs global environment after a side-effecting command
@@ -124,11 +126,11 @@ val set_endline_tactic : Genarg.glob_generic_argument -> unit
* (w.r.t. type dependencies and let-ins covered by it) + a list of
* ids to be cleared *)
val set_used_variables :
- Names.Id.t list -> Context.Named.t * Misctypes.lident list
-val get_used_variables : unit -> Context.Named.t option
+ Names.Id.t list -> Constr.named_context * Names.lident list
+val get_used_variables : unit -> Constr.named_context option
(** Get the universe declaration associated to the current proof. *)
-val get_universe_decl : unit -> Univdecls.universe_decl
+val get_universe_decl : unit -> UState.universe_decl
module V82 : sig
val get_current_initial_conclusions : unit -> Names.Id.t *(EConstr.types list *
diff --git a/proofs/proofs.mllib b/proofs/proofs.mllib
index 058e839b..197f71ca 100644
--- a/proofs/proofs.mllib
+++ b/proofs/proofs.mllib
@@ -5,6 +5,7 @@ Proof_type
Logic
Refine
Proof
+Goal_select
Proof_bullet
Proof_global
Redexpr
diff --git a/proofs/redexpr.ml b/proofs/redexpr.ml
index 6fb41193..44685d2b 100644
--- a/proofs/redexpr.ml
+++ b/proofs/redexpr.ml
@@ -12,7 +12,7 @@ open Pp
open CErrors
open Util
open Names
-open Term
+open Constr
open EConstr
open Declarations
open Globnames
@@ -23,7 +23,6 @@ open Tacred
open CClosure
open RedFlags
open Libobject
-open Misctypes
(* call by value normalisation function using the virtual machine *)
let cbv_vm env sigma c =
@@ -53,7 +52,7 @@ let whd_cbn flags env sigma t =
Reductionops.Stack.zip ~refold:true sigma state
let strong_cbn flags =
- strong (whd_cbn flags)
+ strong_with_flags whd_cbn flags
let simplIsCbn = ref (false)
let _ = Goptions.declare_bool_option {
@@ -92,9 +91,9 @@ let cache_strategy (_,str) =
let subst_strategy (subs,(local,obj)) =
local,
- List.smartmap
+ List.Smart.map
(fun (k,ql as entry) ->
- let ql' = List.smartmap (Mod_subst.subst_evaluable_reference subs) ql in
+ let ql' = List.Smart.map (Mod_subst.subst_evaluable_reference subs) ql in
if ql==ql' then entry else (k,ql'))
obj
@@ -200,8 +199,8 @@ let decl_red_expr s e =
end
let out_arg = function
- | ArgVar _ -> anomaly (Pp.str "Unevaluated or_var variable.")
- | ArgArg x -> x
+ | Locus.ArgVar _ -> anomaly (Pp.str "Unevaluated or_var variable.")
+ | Locus.ArgArg x -> x
let out_with_occurrences (occs,c) =
(Locusops.occurrences_map (List.map out_arg) occs, c)
@@ -263,7 +262,7 @@ let subst_mps subst c =
EConstr.of_constr (Mod_subst.subst_mps subst (EConstr.Unsafe.to_constr c))
let subst_red_expr subs =
- Miscops.map_red_expr_gen
+ Redops.map_red_expr_gen
(subst_mps subs)
(Mod_subst.subst_evaluable_reference subs)
(Patternops.subst_pattern subs)
diff --git a/proofs/refine.ml b/proofs/refine.ml
index 909556b1..198e057e 100644
--- a/proofs/refine.ml
+++ b/proofs/refine.ml
@@ -15,7 +15,7 @@ open Context.Named.Declaration
module NamedDecl = Context.Named.Declaration
let extract_prefix env info =
- let ctx1 = List.rev (Environ.named_context env) in
+ let ctx1 = List.rev (EConstr.named_context env) in
let ctx2 = List.rev (Evd.evar_context info) in
let rec share l1 l2 accu = match l1, l2 with
| d1 :: l1, d2 :: l2 ->
@@ -29,47 +29,34 @@ let typecheck_evar ev env sigma =
let info = Evd.find sigma ev in
(** Typecheck the hypotheses. *)
let type_hyp (sigma, env) decl =
- let t = EConstr.of_constr (NamedDecl.get_type decl) in
- let evdref = ref sigma in
- let _ = Typing.e_sort_of env evdref t in
- let () = match decl with
- | LocalAssum _ -> ()
- | LocalDef (_,body,_) -> Typing.e_check env evdref (EConstr.of_constr body) t
+ let t = NamedDecl.get_type decl in
+ let sigma, _ = Typing.sort_of env sigma t in
+ let sigma = match decl with
+ | LocalAssum _ -> sigma
+ | LocalDef (_,body,_) -> Typing.check env sigma body t
in
- (!evdref, Environ.push_named decl env)
+ (sigma, EConstr.push_named decl env)
in
let (common, changed) = extract_prefix env info in
- let env = Environ.reset_with_named_context (Environ.val_of_named_context common) env in
+ let env = Environ.reset_with_named_context (EConstr.val_of_named_context common) env in
let (sigma, env) = List.fold_left type_hyp (sigma, env) changed in
(** Typecheck the conclusion *)
- let evdref = ref sigma in
- let _ = Typing.e_sort_of env evdref (EConstr.of_constr (Evd.evar_concl info)) in
- !evdref
-
-let typecheck_proof c concl env sigma =
- let evdref = ref sigma in
- let () = Typing.e_check env evdref c concl in
- !evdref
+ let sigma, _ = Typing.sort_of env sigma (Evd.evar_concl info) in
+ sigma
let (pr_constrv,pr_constr) =
Hook.make ~default:(fun _env _sigma _c -> Pp.str"<constr>") ()
(* Get the side-effect's constant declarations to update the monad's
* environmnent *)
-let add_if_undefined kn cb env =
- try ignore(Environ.lookup_constant kn env); env
- with Not_found -> Environ.add_constant kn cb env
+let add_if_undefined env eff =
+ let open Entries in
+ try ignore(Environ.lookup_constant eff.seff_constant env); env
+ with Not_found -> Environ.add_constant eff.seff_constant eff.seff_body env
(* Add the side effects to the monad's environment, if not already done. *)
-let add_side_effect env = function
- | { Entries.eff = Entries.SEsubproof (kn, cb, eff_env) } ->
- add_if_undefined kn cb env
- | { Entries.eff = Entries.SEscheme (l,_) } ->
- List.fold_left (fun env (_,kn,cb,eff_env) ->
- add_if_undefined kn cb env) env l
-
-let add_side_effects env effects =
- List.fold_left (fun env eff -> add_side_effect env eff) env effects
+let add_side_effects env eff =
+ List.fold_left add_if_undefined env eff
let generic_refine ~typecheck f gl =
let sigma = Proofview.Goal.sigma gl in
@@ -93,7 +80,7 @@ let generic_refine ~typecheck f gl =
let fold accu ev = typecheck_evar ev env accu in
let sigma = if typecheck then Evd.fold_future_goals fold sigma evs else sigma in
(** Check that the refined term is typesafe *)
- let sigma = if typecheck then typecheck_proof c concl env sigma else sigma in
+ let sigma = if typecheck then Typing.check env sigma c concl else sigma in
(** Check that the goal itself does not appear in the refined term *)
let self = Proofview.Goal.goal gl in
let _ =
@@ -106,7 +93,6 @@ let generic_refine ~typecheck f gl =
let evs = Evd.map_filter_future_goals (Proofview.Unsafe.advance sigma) evs in
let comb,shelf,given_up,evkmain = Evd.dispatch_future_goals evs in
(** Proceed to the refinement *)
- let c = EConstr.Unsafe.to_constr c in
let sigma = match Proofview.Unsafe.advance sigma self with
| None ->
(** Nothing to do, the goal has been solved by side-effect *)
@@ -124,7 +110,8 @@ let generic_refine ~typecheck f gl =
(** Mark goals *)
let sigma = CList.fold_left Proofview.Unsafe.mark_as_goal sigma comb in
let comb = CList.map (fun x -> Proofview.goal_with_state x state) comb in
- let trace () = Pp.(hov 2 (str"simple refine"++spc()++ Hook.get pr_constrv env sigma c)) in
+ let trace () = Pp.(hov 2 (str"simple refine"++spc()++
+ Hook.get pr_constrv env sigma (EConstr.Unsafe.to_constr c))) in
Proofview.Trace.name_tactic trace (Proofview.tclUNIT v) >>= fun v ->
Proofview.Unsafe.tclSETENV (Environ.reset_context env) <*>
Proofview.Unsafe.tclEVARS sigma <*>
diff --git a/proofs/refiner.mli b/proofs/refiner.mli
index 5cd703a2..0f83e16e 100644
--- a/proofs/refiner.mli
+++ b/proofs/refiner.mli
@@ -23,9 +23,12 @@ val pf_env : goal sigma -> Environ.env
val pf_hyps : goal sigma -> named_context
val unpackage : 'a sigma -> evar_map ref * 'a
+[@@ocaml.deprecated "Do not use [evar_map ref]"]
val repackage : evar_map ref -> 'a -> 'a sigma
+[@@ocaml.deprecated "Do not use [evar_map ref]"]
val apply_sig_tac :
evar_map ref -> (goal sigma -> goal list sigma) -> goal -> goal list
+[@@ocaml.deprecated "Do not use [evar_map ref]"]
val refiner : rule -> tactic
diff --git a/proofs/tacmach.ml b/proofs/tacmach.ml
index 1889054f..182b38d3 100644
--- a/proofs/tacmach.ml
+++ b/proofs/tacmach.ml
@@ -33,9 +33,11 @@ let re_sig it gc = { it = it; sigma = gc; }
type 'a sigma = 'a Evd.sigma;;
type tactic = Proof_type.tactic;;
+[@@@ocaml.warning "-3"]
let unpackage = Refiner.unpackage
let repackage = Refiner.repackage
let apply_sig_tac = Refiner.apply_sig_tac
+[@@@ocaml.warning "+3"]
let sig_it = Refiner.sig_it
let project = Refiner.project
@@ -73,7 +75,7 @@ let pf_ids_set_of_hyps gls =
let pf_get_new_id id gls =
next_ident_away id (pf_ids_set_of_hyps gls)
-let pf_global gls id = EConstr.of_constr (Universes.constr_of_global (Constrintern.construct_reference (pf_hyps gls) id))
+let pf_global gls id = EConstr.of_constr (UnivGen.constr_of_global (Constrintern.construct_reference (pf_hyps gls) id))
let pf_reduction_of_red_expr gls re c =
let (redfun, _) = reduction_of_red_expr (pf_env gls) re in
@@ -125,8 +127,8 @@ open Pp
let db_pr_goal sigma g =
let env = Goal.V82.env sigma g in
- let penv = print_named_context env in
- let pc = print_constr_env env sigma (Goal.V82.concl sigma g) in
+ let penv = Termops.Internal.print_named_context env in
+ let pc = Termops.Internal.print_constr_env env sigma (Goal.V82.concl sigma g) in
str" " ++ hv 0 (penv ++ fnl () ++
str "============================" ++ fnl () ++
str" " ++ pc) ++ fnl ()
diff --git a/proofs/tacmach.mli b/proofs/tacmach.mli
index 770d0940..31496fb3 100644
--- a/proofs/tacmach.mli
+++ b/proofs/tacmach.mli
@@ -30,9 +30,12 @@ val project : goal sigma -> evar_map
val re_sig : 'a -> evar_map -> 'a sigma
val unpackage : 'a sigma -> evar_map ref * 'a
+[@@ocaml.deprecated "Do not use [evar_map ref]"]
val repackage : evar_map ref -> 'a -> 'a sigma
+[@@ocaml.deprecated "Do not use [evar_map ref]"]
val apply_sig_tac :
evar_map ref -> (goal sigma -> (goal list) sigma) -> goal -> (goal list)
+[@@ocaml.deprecated "Do not use [evar_map ref]"]
val pf_concl : goal sigma -> types
val pf_env : goal sigma -> env
@@ -95,7 +98,7 @@ val pr_glls : goal list sigma -> Pp.t
(* Variants of [Tacmach] functions built with the new proof engine *)
module New : sig
val pf_apply : (env -> evar_map -> 'a) -> Proofview.Goal.t -> 'a
- val pf_global : Id.t -> Proofview.Goal.t -> Globnames.global_reference
+ val pf_global : Id.t -> Proofview.Goal.t -> GlobRef.t
(** FIXME: encapsulate the level in an existential type. *)
val of_old : (Proof_type.goal Evd.sigma -> 'a) -> Proofview.Goal.t -> 'a
diff --git a/interp/tactypes.ml b/proofs/tactypes.ml
index 83e42be8..86a7e9c5 100644
--- a/interp/tactypes.ml
+++ b/proofs/tactypes.ml
@@ -13,15 +13,35 @@
meant to stay. *)
open Names
-open Constrexpr
-open Pattern
-open Misctypes
-(** In globalize tactics, we need to keep the initial [constr_expr] to recompute
- in the environment by the effective calls to Intro, Inversion, etc
- The [constr_expr] field is [None] in TacDef though *)
-type glob_constr_and_expr = Glob_term.glob_constr * constr_expr option
-type glob_constr_pattern_and_expr = Id.Set.t * glob_constr_and_expr * constr_pattern
+(** Introduction patterns *)
+
+type 'constr intro_pattern_expr =
+ | IntroForthcoming of bool
+ | IntroNaming of Namegen.intro_pattern_naming_expr
+ | IntroAction of 'constr intro_pattern_action_expr
+and 'constr intro_pattern_action_expr =
+ | IntroWildcard
+ | IntroOrAndPattern of 'constr or_and_intro_pattern_expr
+ | IntroInjection of ('constr intro_pattern_expr) CAst.t list
+ | IntroApplyOn of 'constr CAst.t * 'constr intro_pattern_expr CAst.t
+ | IntroRewrite of bool
+and 'constr or_and_intro_pattern_expr =
+ | IntroOrPattern of ('constr intro_pattern_expr) CAst.t list list
+ | IntroAndPattern of ('constr intro_pattern_expr) CAst.t list
+
+(** Bindings *)
+
+type quantified_hypothesis = AnonHyp of int | NamedHyp of Id.t
+
+type 'a explicit_bindings = (quantified_hypothesis * 'a) CAst.t list
+
+type 'a bindings =
+ | ImplicitBindings of 'a list
+ | ExplicitBindings of 'a explicit_bindings
+ | NoBindings
+
+type 'a with_bindings = 'a * 'a bindings
type 'a delayed_open = Environ.env -> Evd.evar_map -> Evd.evar_map * 'a
@@ -31,4 +51,4 @@ type delayed_open_constr_with_bindings = EConstr.constr with_bindings delayed_op
type intro_pattern = delayed_open_constr intro_pattern_expr CAst.t
type intro_patterns = delayed_open_constr intro_pattern_expr CAst.t list
type or_and_intro_pattern = delayed_open_constr or_and_intro_pattern_expr CAst.t
-type intro_pattern_naming = intro_pattern_naming_expr CAst.t
+type intro_pattern_naming = Namegen.intro_pattern_naming_expr CAst.t
diff --git a/stm/asyncTaskQueue.ml b/stm/asyncTaskQueue.ml
index b3e1500a..768d94d3 100644
--- a/stm/asyncTaskQueue.ml
+++ b/stm/asyncTaskQueue.ml
@@ -60,7 +60,7 @@ module Make(T : Task) () = struct
type request = Request of T.request
type more_data =
- | MoreDataUnivLevel of Universes.universe_id list
+ | MoreDataUnivLevel of UnivGen.universe_id list
let slave_respond (Request r) =
let res = T.perform r in
@@ -120,12 +120,11 @@ module Make(T : Task) () = struct
let proc, ic, oc =
let rec set_slave_opt = function
| [] -> !async_proofs_flags_for_workers @
- ["-toploop"; !T.name^"top";
- "-worker-id"; name;
+ ["-worker-id"; name;
"-async-proofs-worker-priority";
- CoqworkmgrApi.(string_of_priority !WorkerLoop.async_proofs_worker_priority)]
- | ("-ideslave"|"-emacs"|"-emacs-U"|"-batch")::tl -> set_slave_opt tl
- | ("-async-proofs" |"-toploop" |"-vio2vo"
+ CoqworkmgrApi.(string_of_priority !async_proofs_worker_priority)]
+ | ("-emacs"|"-emacs-U"|"-batch")::tl -> set_slave_opt tl
+ | ("-async-proofs" |"-vio2vo"
|"-load-vernac-source" |"-l" |"-load-vernac-source-verbose" |"-lv"
|"-compile" |"-compile-verbose"
|"-async-proofs-worker-priority" |"-worker-id") :: _ :: tl ->
@@ -134,7 +133,8 @@ module Make(T : Task) () = struct
let args =
Array.of_list (set_slave_opt (List.tl (Array.to_list Sys.argv))) in
let env = Array.append (T.extra_env ()) (Unix.environment ()) in
- Worker.spawn ~env Sys.argv.(0) args in
+ let worker_name = System.get_toplevel_path ("coq" ^ !T.name) in
+ Worker.spawn ~env worker_name args in
name, proc, CThread.prepare_in_channel_for_thread_friendly_io ic, oc
let manager cpanel (id, proc, ic, oc) =
@@ -171,7 +171,7 @@ module Make(T : Task) () = struct
| Unix.WSIGNALED sno -> Printf.sprintf "signalled(%d)" sno
| Unix.WSTOPPED sno -> Printf.sprintf "stopped(%d)" sno) in
let more_univs n =
- CList.init n (fun _ -> Universes.new_univ_id ()) in
+ CList.init n (fun _ -> UnivGen.new_univ_id ()) in
let rec kill_if () =
if not (Worker.is_alive proc) then ()
@@ -310,7 +310,7 @@ module Make(T : Task) () = struct
Marshal.to_channel oc (RespFeedback (debug_with_pid fb)) []; flush oc in
ignore (Feedback.add_feeder (fun x -> slave_feeder (Option.get !slave_oc) x));
(* We ask master to allocate universe identifiers *)
- Universes.set_remote_new_univ_id (bufferize (fun () ->
+ UnivGen.set_remote_new_univ_id (bufferize (fun () ->
marshal_response (Option.get !slave_oc) RespGetCounterNewUnivLevel;
match unmarshal_more_data (Option.get !slave_ic) with
| MoreDataUnivLevel l -> l));
diff --git a/stm/coqworkmgrApi.ml b/stm/coqworkmgrApi.ml
index 36b5d18a..841cc08c 100644
--- a/stm/coqworkmgrApi.ml
+++ b/stm/coqworkmgrApi.ml
@@ -11,6 +11,10 @@
let debug = false
type priority = Low | High
+
+(* Default priority *)
+let async_proofs_worker_priority = ref Low
+
let string_of_priority = function Low -> "low" | High -> "high"
let priority_of_string = function
| "low" -> Low
diff --git a/stm/coqworkmgrApi.mli b/stm/coqworkmgrApi.mli
index 2983b619..be5b2917 100644
--- a/stm/coqworkmgrApi.mli
+++ b/stm/coqworkmgrApi.mli
@@ -14,6 +14,9 @@ type priority = Low | High
val string_of_priority : priority -> string
val priority_of_string : string -> priority
+(* Default priority *)
+val async_proofs_worker_priority : priority ref
+
(* Connects to a work manager if any. If no worker manager, then
-async-proofs-j and -async-proofs-tac-j are used *)
val init : priority -> unit
diff --git a/stm/proofBlockDelimiter.ml b/stm/proofBlockDelimiter.ml
index 23f97612..b8af2bcd 100644
--- a/stm/proofBlockDelimiter.ml
+++ b/stm/proofBlockDelimiter.ml
@@ -23,8 +23,8 @@ val crawl :
static_block_declaration option
val unit_val : Stm.DynBlockData.t
-val of_bullet_val : Vernacexpr.bullet -> Stm.DynBlockData.t
-val to_bullet_val : Stm.DynBlockData.t -> Vernacexpr.bullet
+val of_bullet_val : Proof_bullet.t -> Stm.DynBlockData.t
+val to_bullet_val : Stm.DynBlockData.t -> Proof_bullet.t
val of_vernac_control_val : Vernacexpr.vernac_control -> Stm.DynBlockData.t
val to_vernac_control_val : Stm.DynBlockData.t -> Vernacexpr.vernac_control
@@ -41,7 +41,7 @@ let simple_goal sigma g gs =
let open Evd in
let open Evarutil in
let evi = Evd.find sigma g in
- Set.is_empty (evars_of_term evi.evar_concl) &&
+ Set.is_empty (evars_of_term (EConstr.Unsafe.to_constr evi.evar_concl)) &&
Set.is_empty (evars_of_filtered_evar_info (nf_evar_info sigma evi)) &&
not (List.exists (Proofview.depends_on sigma g) gs)
diff --git a/stm/proofBlockDelimiter.mli b/stm/proofBlockDelimiter.mli
index 9784de11..eacd3687 100644
--- a/stm/proofBlockDelimiter.mli
+++ b/stm/proofBlockDelimiter.mli
@@ -38,6 +38,6 @@ val crawl :
val unit_val : Stm.DynBlockData.t
(* Bullets *)
-val of_bullet_val : Vernacexpr.bullet -> Stm.DynBlockData.t
-val to_bullet_val : Stm.DynBlockData.t -> Vernacexpr.bullet
+val of_bullet_val : Proof_bullet.t -> Stm.DynBlockData.t
+val to_bullet_val : Stm.DynBlockData.t -> Proof_bullet.t
diff --git a/stm/proofworkertop.mllib b/stm/proofworkertop.mllib
deleted file mode 100644
index f9f6c22d..00000000
--- a/stm/proofworkertop.mllib
+++ /dev/null
@@ -1 +0,0 @@
-Proofworkertop
diff --git a/stm/queryworkertop.mllib b/stm/queryworkertop.mllib
deleted file mode 100644
index c2f73089..00000000
--- a/stm/queryworkertop.mllib
+++ /dev/null
@@ -1 +0,0 @@
-Queryworkertop
diff --git a/stm/spawned.ml b/stm/spawned.ml
index 3833c802..a5d6ea96 100644
--- a/stm/spawned.ml
+++ b/stm/spawned.ml
@@ -28,13 +28,11 @@ let controller h pr pw =
prerr_endline "starting controller thread";
let main () =
let ic, oc = open_bin_connection h pr pw in
- let rec loop () =
+ let loop () =
try
match CThread.thread_friendly_input_value ic with
| Hello _ -> prerr_endline "internal protocol error"; exit 1
| ReqDie -> prerr_endline "death sentence received"; exit 0
- | ReqStats ->
- output_value oc (RespStats (Gc.quick_stat ())); flush oc; loop ()
with
| e ->
prerr_endline ("control channel broken: " ^ Printexc.to_string e);
diff --git a/stm/stm.ml b/stm/stm.ml
index e1b90bd2..ada7e3e3 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -92,11 +92,11 @@ let execution_error ?loc state_id msg =
module Hooks = struct
let state_computed, state_computed_hook = Hook.make
- ~default:(fun state_id ~in_cache ->
+ ~default:(fun ~doc:_ state_id ~in_cache ->
feedback ~id:state_id Processed) ()
let state_ready, state_ready_hook = Hook.make
- ~default:(fun state_id -> ()) ()
+ ~default:(fun ~doc:_ state_id -> ()) ()
let forward_feedback, forward_feedback_hook =
let m = Mutex.create () in
@@ -106,7 +106,7 @@ let forward_feedback, forward_feedback_hook =
with e -> Mutex.unlock m; raise e) ()
let unreachable_state, unreachable_state_hook = Hook.make
- ~default:(fun _ _ -> ()) ()
+ ~default:(fun ~doc:_ _ _ -> ()) ()
include Hook
@@ -578,7 +578,7 @@ end = struct (* {{{ *)
| None -> raise Vcs_aux.Expired
let set_state id s =
(get_info id).state <- s;
- if async_proofs_is_master !cur_opt then Hooks.(call state_ready id)
+ if async_proofs_is_master !cur_opt then Hooks.(call state_ready ~doc:dummy_doc (* XXX should be taken in input *) id)
let get_state id = (get_info id).state
let reached id =
let info = get_info id in
@@ -770,6 +770,7 @@ module State : sig
Warning: an optimization in installed_cached requires that state
modifying functions are always executed using this wrapper. *)
val define :
+ doc:doc ->
?safe_id:Stateid.t ->
?redefine:bool -> ?cache:Summary.marshallable ->
?feedback_processed:bool -> (unit -> unit) -> Stateid.t -> unit
@@ -919,7 +920,7 @@ end = struct (* {{{ *)
let e2 = Summary.project_from_summary s2 Global.global_env_summary_tag in
e1 == e2
- let define ?safe_id ?(redefine=false) ?(cache=`No) ?(feedback_processed=true)
+ let define ~doc ?safe_id ?(redefine=false) ?(cache=`No) ?(feedback_processed=true)
f id
=
feedback ~id:id (ProcessingIn !Flags.async_proofs_worker_id);
@@ -938,7 +939,7 @@ end = struct (* {{{ *)
stm_prerr_endline (fun () -> "setting cur id to "^str_id);
cur_id := id;
if feedback_processed then
- Hooks.(call state_computed id ~in_cache:false);
+ Hooks.(call state_computed ~doc id ~in_cache:false);
VCS.reached id;
if Proof_global.there_are_pending_proofs () then
VCS.goals id (Proof_global.get_open_goals ())
@@ -954,7 +955,7 @@ end = struct (* {{{ *)
| Some _, None -> (e, info)
| Some (_,at), Some id -> (e, Stateid.add info ~valid:id at) in
if cache = `Yes || cache = `Shallow then freeze_invalid id ie;
- Hooks.(call unreachable_state id ie);
+ Hooks.(call unreachable_state ~doc id ie);
Exninfo.iraise ie
let init_state = ref None
@@ -1072,7 +1073,7 @@ let stm_vernac_interp ?proof ?route id st { verbose; loc; expr } : Vernacstate.t
let is_filtered_command = function
| VernacResetName _ | VernacResetInitial | VernacBack _
| VernacBackTo _ | VernacRestart | VernacUndo _ | VernacUndoTo _
- | VernacBacktrack _ | VernacAbortAll | VernacAbort _ -> true
+ | VernacAbortAll | VernacAbort _ -> true
| _ -> false
in
let aux_interp st expr =
@@ -1097,13 +1098,13 @@ let stm_vernac_interp ?proof ?route id st { verbose; loc; expr } : Vernacstate.t
module Backtrack : sig
val record : unit -> unit
- val backto : Stateid.t -> unit
(* we could navigate the dag, but this ways easy *)
val branches_of : Stateid.t -> backup
(* Returns the state that the command should backtract to *)
- val undo_vernac_classifier : vernac_control -> Stateid.t * vernac_when
+ val undo_vernac_classifier : vernac_control -> doc:doc -> Stateid.t * vernac_when
+ val get_prev_proof : doc:doc -> Stateid.t -> Proof.t option
end = struct (* {{{ *)
@@ -1122,14 +1123,6 @@ end = struct (* {{{ *)
info.vcs_backup <- backup, branches)
[VCS.current_branch (); VCS.Branch.master]
- let backto oid =
- let info = VCS.get_info oid in
- match info.vcs_backup with
- | None, _ ->
- anomaly Pp.(str"Backtrack.backto "++str(Stateid.to_string oid)++
- str": a state with no vcs_backup.")
- | Some vcs, _ -> VCS.restore vcs
-
let branches_of id =
let info = VCS.get_info id in
match info.vcs_backup with
@@ -1169,7 +1162,17 @@ end = struct (* {{{ *)
" If your use is intentional, you may want to disable this warning and pass" ^
" the \"-async-proofs-cache force\" option to Coq."))
- let undo_vernac_classifier v =
+ let back_tactic n (id,_,_,tactic,undo) =
+ let value = (if tactic then 1 else 0) - undo in
+ if Int.equal n 0 then `Stop id else `Cont (n-value)
+
+ let get_proof ~doc id =
+ let open Vernacstate in
+ match state_of_id ~doc id with
+ | `Valid (Some vstate) -> Some (Proof_global.proof_of_state vstate.proof)
+ | _ -> None
+
+ let undo_vernac_classifier v ~doc =
if VCS.is_interactive () = `No && !cur_opt.async_proofs_cache <> Some Force
then undo_costly_in_batch_mode v;
try
@@ -1193,9 +1196,7 @@ end = struct (* {{{ *)
oid, VtNow
| VernacUndo n ->
let id = VCS.get_branch_pos (VCS.current_branch ()) in
- let oid = fold_until (fun n (id,_,_,tactic,undo) ->
- let value = (if tactic then 1 else 0) - undo in
- if Int.equal n 0 then `Stop id else `Cont (n-value)) n id in
+ let oid = fold_until back_tactic n id in
oid, VtLater
| VernacUndoTo _
| VernacRestart as e ->
@@ -1220,7 +1221,6 @@ end = struct (* {{{ *)
match Vcs_.branches vcs with [_] -> `Stop id | _ -> `Cont ())
() id in
oid, VtLater
- | VernacBacktrack (id,_,_)
| VernacBackTo id ->
Stateid.of_int id, VtNow
| _ -> anomaly Pp.(str "incorrect VtMeta classification")
@@ -1229,8 +1229,29 @@ end = struct (* {{{ *)
CErrors.user_err ~hdr:"undo_vernac_classifier"
Pp.(str "Cannot undo")
+ let get_prev_proof ~doc id =
+ try
+ let np = get_proof ~doc id in
+ match np with
+ | None -> None
+ | Some cp ->
+ let did = ref id in
+ let rv = ref np in
+ let done_ = ref false in
+ while not !done_ do
+ did := fold_until back_tactic 1 !did;
+ rv := get_proof ~doc !did;
+ done_ := match !rv with
+ | Some rv -> not (Goal.Set.equal (Proof.all_goals rv) (Proof.all_goals cp))
+ | None -> true
+ done;
+ !rv
+ with Not_found | Proof_global.NoCurrentProof -> None
+
end (* }}} *)
+let get_prev_proof = Backtrack.get_prev_proof
+
let hints = ref Aux_file.empty_aux_file
let set_compilation_hints file =
hints := Aux_file.load_aux_file_for file
@@ -1343,7 +1364,7 @@ module rec ProofTask : sig
t_stop : Stateid.t;
t_drop : bool;
t_states : competence;
- t_assign : Proof_global.closed_proof_output Future.assignement -> unit;
+ t_assign : Proof_global.closed_proof_output Future.assignment -> unit;
t_loc : Loc.t option;
t_uuid : Future.UUID.t;
t_name : string }
@@ -1362,6 +1383,7 @@ module rec ProofTask : sig
and type request := request
val build_proof_here :
+ doc:doc ->
?loc:Loc.t ->
drop_pt:bool ->
Stateid.t * Stateid.t -> Stateid.t ->
@@ -1381,7 +1403,7 @@ end = struct (* {{{ *)
t_stop : Stateid.t;
t_drop : bool;
t_states : competence;
- t_assign : Proof_global.closed_proof_output Future.assignement -> unit;
+ t_assign : Proof_global.closed_proof_output Future.assignment -> unit;
t_loc : Loc.t option;
t_uuid : Future.UUID.t;
t_name : string }
@@ -1476,11 +1498,12 @@ end = struct (* {{{ *)
execution_error start (Pp.strbrk s);
feedback (InProgress ~-1)
- let build_proof_here ?loc ~drop_pt (id,valid) eop =
+ let build_proof_here ~doc ?loc ~drop_pt (id,valid) eop =
Future.create (State.exn_on id ~valid) (fun () ->
let wall_clock1 = Unix.gettimeofday () in
- if VCS.is_interactive () = `No then Reach.known_state ~cache:`No eop
- else Reach.known_state ~cache:`Shallow eop;
+ if VCS.is_interactive () = `No
+ then Reach.known_state ~doc ~cache:`No eop
+ else Reach.known_state ~doc ~cache:`Shallow eop;
let wall_clock2 = Unix.gettimeofday () in
Aux_file.record_in_aux_at ?loc "proof_build_time"
(Printf.sprintf "%.3f" (wall_clock2 -. wall_clock1));
@@ -1494,7 +1517,7 @@ end = struct (* {{{ *)
VCS.print ();
let proof, future_proof, time =
let wall_clock = Unix.gettimeofday () in
- let fp = build_proof_here ?loc ~drop_pt:drop exn_info stop in
+ let fp = build_proof_here ~doc:dummy_doc (* XXX should be document *) ?loc ~drop_pt:drop exn_info stop in
let proof = Future.force fp in
proof, fp, Unix.gettimeofday () -. wall_clock in
(* We typecheck the proof with the kernel (in the worker) to spot
@@ -1518,7 +1541,7 @@ end = struct (* {{{ *)
stm_vernac_interp stop
~proof:(pobject, terminator) st
{ verbose = false; loc; indentation = 0; strlen = 0;
- expr = VernacExpr ([], VernacEndProof (Proved (Opaque,None))) }) in
+ expr = VernacExpr ([], VernacEndProof (Proved (Proof_global.Opaque,None))) }) in
ignore(Future.join checked_proof);
end;
(* STATE: Restore the state XXX: handle exn *)
@@ -1587,7 +1610,7 @@ end = struct (* {{{ *)
msg_warning Pp.(strbrk("Marshalling error: "^s^". "^
"The system state could not be sent to the worker process. "^
"Falling back to local, lazy, evaluation."));
- t_assign(`Comp(build_proof_here ?loc:t_loc ~drop_pt t_exn_info t_stop));
+ t_assign(`Comp(build_proof_here ~doc:dummy_doc (* XXX should be stored in a closure, it is the same doc that was used to generate the task *) ?loc:t_loc ~drop_pt t_exn_info t_stop));
feedback (InProgress ~-1)
end (* }}} *)
@@ -1597,6 +1620,7 @@ and Slaves : sig
(* (eventually) remote calls *)
val build_proof :
+ doc:doc ->
?loc:Loc.t -> drop_pt:bool ->
exn_info:(Stateid.t * Stateid.t) -> block_start:Stateid.t -> block_stop:Stateid.t ->
name:string -> future_proof * AsyncTaskQueue.cancel_switch
@@ -1644,7 +1668,7 @@ end = struct (* {{{ *)
with VCS.Expired -> cur in
aux stop in
try
- Reach.known_state ~cache:`No stop;
+ Reach.known_state ~doc:dummy_doc (* XXX should be document *) ~cache:`No stop;
if drop then
let _proof = Proof_global.return_proof ~allow_partial:true () in
`OK_ADMITTED
@@ -1657,7 +1681,7 @@ end = struct (* {{{ *)
Proof_global.close_proof ~keep_body_ucst_separate:true (fun x -> x) in
(* We jump at the beginning since the kernel handles side effects by also
* looking at the ones that happen to be present in the current env *)
- Reach.known_state ~cache:`No start;
+ Reach.known_state ~doc:dummy_doc (* XXX should be document *) ~cache:`No start;
(* STATE SPEC:
* - start: First non-expired state! [This looks very fishy]
* - end : start + qed
@@ -1667,7 +1691,7 @@ end = struct (* {{{ *)
let st = Vernacstate.freeze_interp_state `No in
ignore(stm_vernac_interp stop ~proof st
{ verbose = false; loc; indentation = 0; strlen = 0;
- expr = VernacExpr ([], VernacEndProof (Proved (Opaque,None))) });
+ expr = VernacExpr ([], VernacEndProof (Proved (Proof_global.Opaque,None))) });
`OK proof
end
with e ->
@@ -1764,7 +1788,7 @@ end = struct (* {{{ *)
BuildProof { t_states = s2 } -> overlap_rel s1 s2
| _ -> 0)
- let build_proof ?loc ~drop_pt ~exn_info ~block_start ~block_stop ~name:pname =
+ let build_proof ~doc ?loc ~drop_pt ~exn_info ~block_start ~block_stop ~name:pname =
let id, valid as t_exn_info = exn_info in
let cancel_switch = ref false in
if TaskQueue.n_workers (Option.get !queue) = 0 then
@@ -1779,7 +1803,7 @@ end = struct (* {{{ *)
TaskQueue.enqueue_task (Option.get !queue) task ~cancel_switch;
f, cancel_switch
end else
- ProofTask.build_proof_here ?loc ~drop_pt t_exn_info block_stop, cancel_switch
+ ProofTask.build_proof_here ~doc ?loc ~drop_pt t_exn_info block_stop, cancel_switch
else
let f, t_assign = Future.create_delegate ~name:pname (State.exn_on id ~valid) in
let t_uuid = Future.uuid f in
@@ -1819,7 +1843,7 @@ and TacTask : sig
type task = {
t_state : Stateid.t;
t_state_fb : Stateid.t;
- t_assign : output Future.assignement -> unit;
+ t_assign : output Future.assignment -> unit;
t_ast : int * aast;
t_goal : Goal.goal;
t_kill : unit -> unit;
@@ -1836,7 +1860,7 @@ end = struct (* {{{ *)
type task = {
t_state : Stateid.t;
t_state_fb : Stateid.t;
- t_assign : output Future.assignement -> unit;
+ t_assign : output Future.assignment -> unit;
t_ast : int * aast;
t_goal : Goal.goal;
t_kill : unit -> unit;
@@ -1855,7 +1879,7 @@ end = struct (* {{{ *)
| RespError of Pp.t
| RespNoProgress
- let name = ref "tacworker"
+ let name = ref "tacticworker"
let extra_env () = [||]
type competence = unit
type worker_status = Fresh | Old of competence
@@ -1902,11 +1926,11 @@ end = struct (* {{{ *)
let perform { r_state = id; r_state_fb; r_document = vcs; r_ast; r_goal } =
Option.iter VCS.restore vcs;
try
- Reach.known_state ~cache:`No id;
+ Reach.known_state ~doc:dummy_doc (* XXX should be vcs *) ~cache:`No id;
stm_purify (fun () ->
let _,_,_,_,sigma0 = Proof.proof (Proof_global.give_me_the_proof ()) in
let g = Evd.find sigma0 r_goal in
- let is_ground c = Evarutil.is_ground_term sigma0 (EConstr.of_constr c) in
+ let is_ground c = Evarutil.is_ground_term sigma0 c in
if not (
is_ground Evd.(evar_concl g) &&
List.for_all (Context.Named.Declaration.for_all is_ground)
@@ -1929,7 +1953,6 @@ end = struct (* {{{ *)
match Evd.(evar_body (find sigma r_goal)) with
| Evd.Evar_empty -> RespNoProgress
| Evd.Evar_defined t ->
- let t = EConstr.of_constr t in
let t = Evarutil.nf_evar sigma t in
if Evarutil.is_ground_term sigma t then
let t = EConstr.Unsafe.to_constr t in
@@ -2058,7 +2081,7 @@ end = struct (* {{{ *)
let perform { r_where; r_doc; r_what; r_for } =
VCS.restore r_doc;
VCS.print ();
- Reach.known_state ~cache:`No r_where;
+ Reach.known_state ~doc:dummy_doc (* XXX should be r_doc *) ~cache:`No r_where;
(* STATE *)
let st = Vernacstate.freeze_interp_state `No in
try
@@ -2103,7 +2126,8 @@ end (* }}} *)
and Reach : sig
val known_state :
- ?redefine_qed:bool -> cache:Summary.marshallable -> Stateid.t -> unit
+ doc:doc -> ?redefine_qed:bool -> cache:Summary.marshallable ->
+ Stateid.t -> unit
end = struct (* {{{ *)
@@ -2119,12 +2143,6 @@ let delegate name =
|| VCS.is_vio_doc ()
|| !cur_opt.async_proofs_full
-let warn_deprecated_nested_proofs =
- CWarnings.create ~name:"deprecated-nested-proofs" ~category:"deprecated"
- (fun () ->
- strbrk ("Nested proofs are deprecated and will "^
- "stop working in a future Coq version"))
-
let collect_proof keep cur hd brkind id =
stm_prerr_endline (fun () -> "Collecting proof ending at "^Stateid.to_string id);
let no_name = "" in
@@ -2133,7 +2151,7 @@ let collect_proof keep cur hd brkind id =
| id :: _ -> Names.Id.to_string id in
let loc = (snd cur).loc in
let is_defined_expr = function
- | VernacEndProof (Proved (Transparent,_)) -> true
+ | VernacEndProof (Proved (Proof_global.Transparent,_)) -> true
| _ -> false in
let is_defined = function
| _, { expr = e } -> is_defined_expr (Vernacprop.under_control e)
@@ -2206,8 +2224,7 @@ let collect_proof keep cur hd brkind id =
assert (VCS.Branch.equal hd hd' || VCS.Branch.equal hd VCS.edit_branch);
let name = name ids in
`MaybeASync (parent last, accn, name, delegate name)
- | `Sideff _ ->
- warn_deprecated_nested_proofs ();
+ | `Sideff (CherryPickEnv,_) ->
`Sync (no_name,`NestedProof)
| _ -> `Sync (no_name,`Unknown) in
let make_sync why = function
@@ -2261,7 +2278,7 @@ let log_processing_sync id name reason = log_string Printf.(sprintf
let wall_clock_last_fork = ref 0.0
-let known_state ?(redefine_qed=false) ~cache id =
+let known_state ~doc ?(redefine_qed=false) ~cache id =
let error_absorbing_tactic id blockname exn =
(* We keep the static/dynamic part of block detection separate, since
@@ -2294,7 +2311,7 @@ let known_state ?(redefine_qed=false) ~cache id =
Proof_global.unfreeze proof;
Proof_global.with_current_proof (fun _ p ->
feedback ~id:id Feedback.AddedAxiom;
- fst (Pfedit.solve Vernacexpr.SelectAll None tac p), ());
+ fst (Pfedit.solve Goal_select.SelectAll None tac p), ());
(* STATE SPEC:
* - start: Modifies the input state adding a proof.
* - end : maybe after recovery command.
@@ -2356,7 +2373,7 @@ let known_state ?(redefine_qed=false) ~cache id =
and reach ?safe_id ?(redefine_qed=false) ?(cache=cache) id =
stm_prerr_endline (fun () -> "reaching: " ^ Stateid.to_string id);
if not redefine_qed && State.is_cached ~cache id then begin
- Hooks.(call state_computed id ~in_cache:true);
+ Hooks.(call state_computed ~doc id ~in_cache:true);
stm_prerr_endline (fun () -> "reached (cache)");
State.install_cached id
end else
@@ -2437,7 +2454,7 @@ let known_state ?(redefine_qed=false) ~cache id =
^" proof. Reprocess the command declaring "
^"the proof's statement to avoid that."));
let fp, cancel =
- Slaves.build_proof
+ Slaves.build_proof ~doc
?loc ~drop_pt ~exn_info ~block_start ~block_stop ~name in
Future.replace ofp fp;
qed.fproof <- Some (fp, cancel);
@@ -2449,10 +2466,10 @@ let known_state ?(redefine_qed=false) ~cache id =
reach ~cache:`Shallow block_start;
let fp, cancel =
if delegate then
- Slaves.build_proof
+ Slaves.build_proof ~doc
?loc ~drop_pt ~exn_info ~block_start ~block_stop ~name
else
- ProofTask.build_proof_here ?loc
+ ProofTask.build_proof_here ~doc ?loc
~drop_pt exn_info block_stop, ref false
in
qed.fproof <- Some (fp, cancel);
@@ -2522,7 +2539,7 @@ let known_state ?(redefine_qed=false) ~cache id =
let cache_step =
if !cur_opt.async_proofs_cache = Some Force then `Yes
else cache_step in
- State.define ?safe_id
+ State.define ~doc ?safe_id
~cache:cache_step ~redefine:redefine_qed ~feedback_processed step id;
stm_prerr_endline (fun () -> "reached: "^ Stateid.to_string id) in
reach ~redefine_qed id
@@ -2571,8 +2588,8 @@ let new_doc { doc_type ; iload_path; require_libs; stm_options } =
let load_objs libs =
let rq_file (dir, from, exp) =
- let mp = CAst.make @@ Libnames.(Qualid (qualid_of_string dir)) in
- let mfrom = Option.map (fun fr -> CAst.make @@ Libnames.(Qualid (qualid_of_string fr))) from in
+ let mp = Libnames.qualid_of_string dir in
+ let mfrom = Option.map Libnames.qualid_of_string from in
Flags.silently (Vernacentries.vernac_require mfrom exp) [mp] in
List.(iter rq_file (rev libs))
in
@@ -2611,7 +2628,7 @@ let new_doc { doc_type ; iload_path; require_libs; stm_options } =
load_objs require_libs;
(* We record the state at this point! *)
- State.define ~cache:`Yes ~redefine:true (fun () -> ()) Stateid.initial;
+ State.define ~doc ~cache:`Yes ~redefine:true (fun () -> ()) Stateid.initial;
Backtrack.record ();
Slaves.init ();
if async_proofs_is_master !cur_opt then begin
@@ -2632,7 +2649,7 @@ let new_doc { doc_type ; iload_path; require_libs; stm_options } =
let observe ~doc id =
let vcs = VCS.backup () in
try
- Reach.known_state ~cache:(VCS.is_interactive ()) id;
+ Reach.known_state ~doc ~cache:(VCS.is_interactive ()) id;
VCS.print ();
doc
with e ->
@@ -2725,7 +2742,7 @@ let merge_proof_branch ~valid ?id qast keep brname =
VCS.rewrite_merge qed_id ~ours:(Qed (qed ofp)) ~at:master_id brname;
VCS.delete_branch brname;
VCS.gc ();
- let _st = Reach.known_state ~redefine_qed:true ~cache:`No qed_id in
+ let _st : unit = Reach.known_state ~doc:dummy_doc (* XXX should be taken in input *) ~redefine_qed:true ~cache:`No qed_id in
VCS.checkout VCS.Branch.master;
`Unfocus qed_id
| { VCS.kind = `Master } ->
@@ -2734,7 +2751,6 @@ let merge_proof_branch ~valid ?id qast keep brname =
(* When tty is true, this code also does some of the job of the user interface:
jump back to a state that is valid *)
let handle_failure (e, info) vcs =
- if e = CErrors.Drop then Exninfo.iraise (e, info) else
match Stateid.get info with
| None ->
VCS.restore vcs;
@@ -2758,9 +2774,7 @@ let snapshot_vio ~doc ldir long_f_dot_vo =
let reset_task_queue = Slaves.reset_task_queue
(* Document building *)
-let process_back_meta_command ~part_of_script ~newtip ~head oid aast w =
- match part_of_script, w with
- | true, w ->
+let process_back_meta_command ~newtip ~head oid aast w =
let id = VCS.new_node ~id:newtip () in
let { mine; others } = Backtrack.branches_of oid in
let valid = VCS.get_branch_pos head in
@@ -2780,16 +2794,15 @@ let process_back_meta_command ~part_of_script ~newtip ~head oid aast w =
VCS.commit id (Alias (oid,aast));
Backtrack.record (); if w == VtNow then ignore(finish ~doc:dummy_doc); `Ok
- | false, VtNow ->
- stm_prerr_endline (fun () -> "undo to state " ^ Stateid.to_string oid);
- Backtrack.backto oid;
- VCS.checkout_shallowest_proof_branch ();
- Reach.known_state ~cache:(VCS.is_interactive ()) oid; `Ok
-
- | false, VtLater ->
- anomaly(str"undo classifier: VtMeta + VtLater must imply part_of_script.")
+let allow_nested_proofs = ref false
+let _ = Goptions.declare_bool_option
+ { Goptions.optdepr = false;
+ Goptions.optname = "Nested Proofs Allowed";
+ Goptions.optkey = Vernac_classifier.stm_allow_nested_proofs_option_name;
+ Goptions.optread = (fun () -> !allow_nested_proofs);
+ Goptions.optwrite = (fun b -> allow_nested_proofs := b) }
-let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
+let process_transaction ~doc ?(newtip=Stateid.fresh ())
({ verbose; loc; expr } as x) c =
stm_pperr_endline (fun () -> str "{{{ processing: " ++ pr_ast x);
let vcs = VCS.backup () in
@@ -2802,23 +2815,11 @@ let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
match c with
(* Meta *)
| VtMeta, _ ->
- let id, w = Backtrack.undo_vernac_classifier expr in
- (* Special case Backtrack, as it is never part of a script. See #6240 *)
- let part_of_script = begin match Vernacprop.under_control expr with
- | VernacBacktrack _ -> false
- | _ -> part_of_script
- end in
- process_back_meta_command ~part_of_script ~newtip ~head id x w
+ let id, w = Backtrack.undo_vernac_classifier expr ~doc in
+ process_back_meta_command ~newtip ~head id x w
+
(* Query *)
- | VtQuery (false,route), VtNow ->
- let query_sid = VCS.cur_tip () in
- (try
- let st = Vernacstate.freeze_interp_state `No in
- ignore(stm_vernac_interp ~route query_sid st x)
- with e ->
- let e = CErrors.push e in
- Exninfo.iraise (State.exn_on ~valid:Stateid.dummy query_sid e)); `Ok
- | VtQuery (true, route), w ->
+ | VtQuery, w ->
let id = VCS.new_node ~id:newtip () in
let queue =
if !cur_opt.async_proofs_full then `QueryQueue (ref false)
@@ -2830,11 +2831,17 @@ let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
VCS.commit id (mkTransCmd x [] false queue);
Backtrack.record (); if w == VtNow then ignore(finish ~doc:dummy_doc); `Ok
- | VtQuery (false,_), VtLater ->
- anomaly(str"classifier: VtQuery + VtLater must imply part_of_script.")
-
(* Proof *)
| VtStartProof (mode, guarantee, names), w ->
+
+ if not !allow_nested_proofs && VCS.proof_nesting () > 0 then
+ "Nested proofs are not allowed unless you turn option Nested Proofs Allowed on."
+ |> Pp.str
+ |> (fun s -> (UserError (None, s), Exninfo.null))
+ |> State.exn_on ~valid:Stateid.dummy Stateid.dummy
+ |> Exninfo.iraise
+ else
+
let id = VCS.new_node ~id:newtip () in
let bname = VCS.mk_branch_name x in
VCS.checkout VCS.Branch.master;
@@ -2885,12 +2892,7 @@ let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
Backtrack.record (); if w == VtNow then ignore(finish ~doc:dummy_doc);
rc
- (* Side effect in a (still open) proof is replayed on all branches *)
- | VtUnknown, _ when Vernacprop.under_control expr = VernacToplevelControl Drop ->
- let st = Vernacstate.freeze_interp_state `No in
- ignore(stm_vernac_interp (VCS.get_branch_pos head) st x);
- `Ok
-
+ (* Side effect in a (still open) proof is replayed on all branches*)
| VtSideff l, w ->
let id = VCS.new_node ~id:newtip () in
begin match (VCS.get_branch head).VCS.kind with
@@ -2914,11 +2916,11 @@ let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
let in_proof = not (VCS.Branch.equal head VCS.Branch.master) in
let id = VCS.new_node ~id:newtip () in
let head_id = VCS.get_branch_pos head in
- let _st = Reach.known_state ~cache:`Yes head_id in (* ensure it is ok *)
+ let _st : unit = Reach.known_state ~doc ~cache:`Yes head_id in (* ensure it is ok *)
let step () =
VCS.checkout VCS.Branch.master;
let mid = VCS.get_branch_pos VCS.Branch.master in
- let _st' = Reach.known_state ~cache:(VCS.is_interactive ()) mid in
+ let _st' : unit = Reach.known_state ~doc ~cache:(VCS.is_interactive ()) mid in
let st = Vernacstate.freeze_interp_state `No in
ignore(stm_vernac_interp id st x);
(* Vernac x may or may not start a proof *)
@@ -2944,7 +2946,7 @@ let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
end;
VCS.checkout_shallowest_proof_branch ();
end in
- State.define ~safe_id:head_id ~cache:`Yes step id;
+ State.define ~doc ~safe_id:head_id ~cache:`Yes step id;
Backtrack.record (); `Ok
| VtUnknown, VtLater ->
@@ -3004,7 +3006,7 @@ let parse_sentence ~doc sid pa =
str "All is good if not parsing changes occur between the two states, however if they do, a problem might occur.");
Flags.with_option Flags.we_are_parsing (fun () ->
try
- match Pcoq.Gram.entry_parse Pcoq.main_entry pa with
+ match Pcoq.Entry.parse Pvernac.main_entry pa with
| None -> raise End_of_input
| Some (loc, cmd) -> CAst.make ~loc cmd
with e when CErrors.noncritical e ->
@@ -3058,7 +3060,7 @@ let add ~doc ~ontop ?newtip verb { CAst.loc; v=ast } =
(* XXX: Classifiy vernac should be moved inside process transaction *)
let clas = Vernac_classifier.classify_vernac ast in
let aast = { verbose = verb; indentation; strlen; loc; expr = ast } in
- match process_transaction ?newtip aast clas with
+ match process_transaction ~doc ?newtip aast clas with
| `Ok -> doc, VCS.cur_tip (), `NewTip
| `Unfocus qed_id -> doc, qed_id, `Unfocus (VCS.cur_tip ())
@@ -3073,18 +3075,14 @@ type focus = {
let query ~doc ~at ~route s =
stm_purify (fun s ->
if Stateid.equal at Stateid.dummy then ignore(finish ~doc:dummy_doc)
- else Reach.known_state ~cache:`Yes at;
+ else Reach.known_state ~doc ~cache:`Yes at;
try
while true do
let { CAst.loc; v=ast } = parse_sentence ~doc at s in
let indentation, strlen = compute_indentation ?loc at in
- let clas = Vernac_classifier.classify_vernac ast in
+ let st = State.get_cached at in
let aast = { verbose = true; indentation; strlen; loc; expr = ast } in
- match clas with
- | VtMeta , _ -> (* TODO: can this still happen ? *)
- ignore(process_transaction ~part_of_script:false aast (VtMeta,VtNow))
- | _ ->
- ignore(process_transaction aast (VtQuery (false,route), VtNow))
+ ignore(stm_vernac_interp ~route at st aast)
done;
with
| End_of_input -> ()
@@ -3139,7 +3137,7 @@ let edit_at ~doc id =
VCS.edit_branch (`Edit (mode, qed_id, master_id, keep, old_branch));
VCS.delete_boxes_of id;
cancel_switch := true;
- Reach.known_state ~cache:(VCS.is_interactive ()) id;
+ Reach.known_state ~doc ~cache:(VCS.is_interactive ()) id;
VCS.checkout_shallowest_proof_branch ();
`Focus { stop = qed_id; start = master_id; tip } in
let no_edit = function
@@ -3162,7 +3160,7 @@ let edit_at ~doc id =
VCS.gc ();
VCS.print ();
if not !cur_opt.async_proofs_full then
- Reach.known_state ~cache:(VCS.is_interactive ()) id;
+ Reach.known_state ~doc ~cache:(VCS.is_interactive ()) id;
VCS.checkout_shallowest_proof_branch ();
`NewTip in
try
@@ -3191,7 +3189,7 @@ let edit_at ~doc id =
| true, None, _ ->
if on_cur_branch id then begin
VCS.reset_branch (VCS.current_branch ()) id;
- Reach.known_state ~cache:(VCS.is_interactive ()) id;
+ Reach.known_state ~doc ~cache:(VCS.is_interactive ()) id;
VCS.checkout_shallowest_proof_branch ();
`NewTip
end else if is_ancestor_of_cur_branch id then begin
diff --git a/stm/stm.mli b/stm/stm.mli
index 35ce77a3..1e5ceb7e 100644
--- a/stm/stm.mli
+++ b/stm/stm.mli
@@ -92,11 +92,11 @@ val new_doc : stm_init_options -> doc * Stateid.t
(** [parse_sentence sid pa] Reads a sentence from [pa] with parsing
state [sid] Returns [End_of_input] if the stream ends *)
-val parse_sentence : doc:doc -> Stateid.t -> Pcoq.Gram.coq_parsable ->
+val parse_sentence : doc:doc -> Stateid.t -> Pcoq.Parsable.t ->
Vernacexpr.vernac_control CAst.t
(* Reminder: A parsable [pa] is constructed using
- [Pcoq.Gram.coq_parsable stream], where [stream : char Stream.t]. *)
+ [Pcoq.Parsable.t stream], where [stream : char Stream.t]. *)
exception End_of_input
@@ -110,11 +110,16 @@ val add : doc:doc -> ontop:Stateid.t -> ?newtip:Stateid.t ->
bool -> Vernacexpr.vernac_control CAst.t ->
doc * Stateid.t * [ `NewTip | `Unfocus of Stateid.t ]
+(* Returns the proof state before the last tactic that was applied at or before
+the specified state AND that has differences in the underlying proof (i.e.,
+ignoring proofview-only changes). Used to compute proof diffs. *)
+val get_prev_proof : doc:doc -> Stateid.t -> Proof.t option
+
(* [query at ?report_with cmd] Executes [cmd] at a given state [at],
throwing away side effects except messages. Feedback will
be sent with [report_with], which defaults to the dummy state id *)
val query : doc:doc ->
- at:Stateid.t -> route:Feedback.route_id -> Pcoq.Gram.coq_parsable -> unit
+ at:Stateid.t -> route:Feedback.route_id -> Pcoq.Parsable.t -> unit
(* [edit_at id] is issued to change the editing zone. [`NewTip] is returned if
the requested id is the new document tip hence the document portion following
@@ -263,11 +268,12 @@ val register_proof_block_delimiter :
* the alternative toploop for the worker can be selected by changing
* the name of the Task(s) above) *)
-val state_computed_hook : (Stateid.t -> in_cache:bool -> unit) Hook.t
-val unreachable_state_hook : (Stateid.t -> Exninfo.iexn -> unit) Hook.t
+val state_computed_hook : (doc:doc -> Stateid.t -> in_cache:bool -> unit) Hook.t
+val unreachable_state_hook :
+ (doc:doc -> Stateid.t -> Exninfo.iexn -> unit) Hook.t
(* ready means that master has it at hand *)
-val state_ready_hook : (Stateid.t -> unit) Hook.t
+val state_ready_hook : (doc:doc -> Stateid.t -> unit) Hook.t
(* Messages from the workers to the master *)
val forward_feedback_hook : (Feedback.feedback -> unit) Hook.t
diff --git a/stm/stm.mllib b/stm/stm.mllib
index 72b53801..4b254e81 100644
--- a/stm/stm.mllib
+++ b/stm/stm.mllib
@@ -5,7 +5,6 @@ TQueue
WorkerPool
Vernac_classifier
CoqworkmgrApi
-WorkerLoop
AsyncTaskQueue
Stm
ProofBlockDelimiter
diff --git a/stm/tacworkertop.mllib b/stm/tacworkertop.mllib
deleted file mode 100644
index db38fde2..00000000
--- a/stm/tacworkertop.mllib
+++ /dev/null
@@ -1 +0,0 @@
-Tacworkertop
diff --git a/stm/vernac_classifier.ml b/stm/vernac_classifier.ml
index f68c8b32..21704779 100644
--- a/stm/vernac_classifier.ml
+++ b/stm/vernac_classifier.ml
@@ -16,8 +16,6 @@ open Vernacexpr
let default_proof_mode () = Proof_global.get_default_proof_mode_name () [@ocaml.warning "-3"]
-let string_of_in_script b = if b then " (inside script)" else ""
-
let string_of_parallel = function
| `Yes (solve,abs) ->
"par" ^ if solve then "solve" else "" ^ if abs then "abs" else ""
@@ -34,7 +32,7 @@ let string_of_vernac_type = function
"ProofStep " ^ string_of_parallel parallel ^
Option.default "" proof_block_detection
| VtProofMode s -> "ProofMode " ^ s
- | VtQuery (b, route) -> "Query " ^ string_of_in_script b ^ " route " ^ string_of_int route
+ | VtQuery -> "Query"
| VtMeta -> "Meta "
let string_of_vernac_when = function
@@ -44,25 +42,25 @@ let string_of_vernac_when = function
let string_of_vernac_classification (t,w) =
string_of_vernac_type t ^ " " ^ string_of_vernac_when w
-let classifiers = ref []
-let declare_vernac_classifier
- (s : Vernacexpr.extend_name)
- (f : Genarg.raw_generic_argument list -> unit -> vernac_classification)
-=
- classifiers := !classifiers @ [s,f]
-
let idents_of_name : Names.Name.t -> Names.Id.t list =
function
| Names.Anonymous -> []
| Names.Name n -> [n]
+let stm_allow_nested_proofs_option_name = ["Nested";"Proofs";"Allowed"]
+
+let options_affecting_stm_scheduling =
+ [ Vernacentries.universe_polymorphism_option_name;
+ stm_allow_nested_proofs_option_name ]
+
let classify_vernac e =
let static_classifier ~poly e = match e with
(* Univ poly compatibility: we run it now, so that we can just
* look at Flags in stm.ml. Would be nicer to have the stm
* look at the entire dag to detect this option. *)
| ( VernacSetOption (_, l,_) | VernacUnsetOption (_, l))
- when CList.equal String.equal l Vernacentries.universe_polymorphism_option_name ->
+ when CList.exists (CList.equal String.equal l)
+ options_affecting_stm_scheduling ->
VtSideff [], VtNow
(* Qed *)
| VernacAbort _ -> VtQed VtDrop, VtLater
@@ -70,7 +68,7 @@ let classify_vernac e =
| VernacEndProof _ | VernacExactProof _ -> VtQed VtKeep, VtLater
(* Query *)
| VernacShow _ | VernacPrint _ | VernacSearch _ | VernacLocate _
- | VernacCheckMayEval _ -> VtQuery (true,Feedback.default_route), VtLater
+ | VernacCheckMayEval _ -> VtQuery, VtLater
(* ProofStep *)
| VernacProof _
| VernacFocus _ | VernacUnfocus
@@ -145,7 +143,7 @@ let classify_vernac e =
| VernacAddLoadPath _ | VernacRemoveLoadPath _ | VernacAddMLPath _
| VernacChdir _
| VernacCreateHintDb _ | VernacRemoveHints _ | VernacHints _
- | VernacDeclareImplicits _ | VernacArguments _ | VernacArgumentsScope _
+ | VernacArguments _
| VernacReserve _
| VernacGeneralizable _
| VernacSetOpacity _ | VernacSetStrategy _
@@ -157,6 +155,7 @@ let classify_vernac e =
| VernacDeclareClass _ | VernacDeclareInstances _
| VernacRegister _
| VernacNameSectionHypSet _
+ | VernacDeclareCustomEntry _
| VernacComments _ -> VtSideff [], VtLater
(* Who knows *)
| VernacLoad _ -> VtSideff [], VtNow
@@ -183,30 +182,26 @@ let classify_vernac e =
| VernacBack _ | VernacAbortAll
| VernacUndoTo _ | VernacUndo _
| VernacResetName _ | VernacResetInitial
- | VernacBacktrack _ | VernacBackTo _ | VernacRestart -> VtMeta, VtNow
+ | VernacBackTo _ | VernacRestart -> VtMeta, VtNow
(* What are these? *)
- | VernacToplevelControl _
| VernacRestoreState _
| VernacWriteState _ -> VtSideff [], VtNow
(* Plugins should classify their commands *)
| VernacExtend (s,l) ->
- try List.assoc s !classifiers l ()
+ try Vernacentries.get_vernac_classifier s l
with Not_found -> anomaly(str"No classifier for"++spc()++str (fst s)++str".")
in
let rec static_control_classifier ~poly = function
| VernacExpr (f, e) ->
- let poly = List.fold_left (fun poly f ->
- match f with
- | VernacPolymorphic b -> b
- | (VernacProgram | VernacLocal _) -> poly
- ) poly f in
+ let _, atts = Vernacentries.attributes_of_flags f Vernacinterp.(mk_atts ~polymorphic:poly ()) in
+ let poly = atts.Vernacinterp.polymorphic in
static_classifier ~poly e
| VernacTimeout (_,e) -> static_control_classifier ~poly e
| VernacTime (_,{v=e}) | VernacRedirect (_, {v=e}) ->
static_control_classifier ~poly e
| VernacFail e -> (* Fail Qed or Fail Lemma must not join/fork the DAG *)
(match static_control_classifier ~poly e with
- | ( VtQuery _ | VtProofStep _ | VtSideff _
+ | ( VtQuery | VtProofStep _ | VtSideff _
| VtProofMode _ | VtMeta), _ as x -> x
| VtQed _, _ ->
VtProofStep { parallel = `No; proof_block_detection = None },
@@ -215,6 +210,6 @@ let classify_vernac e =
in
static_control_classifier ~poly:(Flags.is_universe_polymorphism ()) e
-let classify_as_query = VtQuery (true,Feedback.default_route), VtLater
+let classify_as_query = VtQuery, VtLater
let classify_as_sideeff = VtSideff [], VtLater
let classify_as_proofstep = VtProofStep { parallel = `No; proof_block_detection = None}, VtLater
diff --git a/stm/vernac_classifier.mli b/stm/vernac_classifier.mli
index abbc04e8..e82b1914 100644
--- a/stm/vernac_classifier.mli
+++ b/stm/vernac_classifier.mli
@@ -9,19 +9,15 @@
(************************************************************************)
open Vernacexpr
-open Genarg
val string_of_vernac_classification : vernac_classification -> string
(** What does a vernacular do *)
val classify_vernac : vernac_control -> vernac_classification
-(** Install a vernacular classifier for VernacExtend *)
-val declare_vernac_classifier :
- Vernacexpr.extend_name -> (raw_generic_argument list -> unit -> vernac_classification) -> unit
-
(** Standard constant classifiers *)
val classify_as_query : vernac_classification
val classify_as_sideeff : vernac_classification
val classify_as_proofstep : vernac_classification
+val stm_allow_nested_proofs_option_name : string list
diff --git a/tactics/auto.ml b/tactics/auto.ml
index 0c0d9bcf..d7de6c4f 100644
--- a/tactics/auto.ml
+++ b/tactics/auto.ml
@@ -8,8 +8,6 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-module CVars = Vars
-
open Pp
open Util
open Names
@@ -81,15 +79,14 @@ let connect_hint_clenv poly (c, _, ctx) clenv gl =
let clenv, c =
if poly then
(** Refresh the instance of the hint *)
- let (subst, ctx) = Universes.fresh_universe_context_set_instance ctx in
- let map c = CVars.subst_univs_level_constr subst c in
+ let (subst, ctx) = UnivGen.fresh_universe_context_set_instance ctx in
let emap c = Vars.subst_univs_level_constr subst c in
let evd = Evd.merge_context_set Evd.univ_flexible evd ctx in
(** Only metas are mentioning the old universes. *)
let clenv = {
templval = Evd.map_fl emap clenv.templval;
templtyp = Evd.map_fl emap clenv.templtyp;
- evd = Evd.map_metas map evd;
+ evd = Evd.map_metas emap evd;
env = Proofview.Goal.env gl;
} in
clenv, emap c
@@ -102,7 +99,7 @@ let unify_resolve poly flags ((c : raw_hint), clenv) =
Proofview.Goal.enter begin fun gl ->
let clenv, c = connect_hint_clenv poly c clenv gl in
let clenv = clenv_unique_resolver ~flags clenv gl in
- Clenvtac.clenv_refine false clenv
+ Clenvtac.clenv_refine clenv
end
let unify_resolve_nodelta poly h = unify_resolve poly auto_unif_flags h
diff --git a/tactics/autorewrite.ml b/tactics/autorewrite.ml
index c3857e6b..c8fd0b7a 100644
--- a/tactics/autorewrite.ml
+++ b/tactics/autorewrite.ml
@@ -30,7 +30,7 @@ let subst_hint subst hint =
let cst' = subst_mps subst hint.rew_lemma in
let typ' = subst_mps subst hint.rew_type in
let pat' = subst_mps subst hint.rew_pat in
- let t' = Option.smartmap (Genintern.generic_substitute subst) hint.rew_tac in
+ let t' = Option.Smart.map (Genintern.generic_substitute subst) hint.rew_tac in
if hint.rew_lemma == cst' && hint.rew_type == typ' && hint.rew_tac == t' then hint else
{ hint with
rew_lemma = cst'; rew_type = typ';
@@ -93,7 +93,7 @@ let one_base general_rewrite_maybe_in tac_main bas =
let try_rewrite dir ctx c tc =
Proofview.Goal.enter begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
- let subst, ctx' = Universes.fresh_universe_context_set_instance ctx in
+ let subst, ctx' = UnivGen.fresh_universe_context_set_instance ctx in
let c' = Vars.subst_univs_level_constr subst c in
let sigma = Evd.merge_context_set Evd.univ_flexible sigma ctx' in
Proofview.tclTHEN (Proofview.Unsafe.tclEVARS sigma)
@@ -228,7 +228,7 @@ let decompose_applied_relation metas env sigma c ctype left2right =
if metas then eqclause
else clenv_pose_metas_as_evars eqclause (Evd.undefined_metas eqclause.evd)
in
- let (equiv, args) = decompose_app (EConstr.Unsafe.to_constr (Clenv.clenv_type eqclause)) in
+ let (equiv, args) = EConstr.decompose_app sigma (Clenv.clenv_type eqclause) in
let rec split_last_two = function
| [c1;c2] -> [],(c1, c2)
| x::y::z ->
@@ -236,17 +236,19 @@ let decompose_applied_relation metas env sigma c ctype left2right =
| _ -> raise Not_found
in
try
- let others,(c1,c2) = split_last_two args in
- let ty1, ty2 =
- Typing.unsafe_type_of env eqclause.evd (EConstr.of_constr c1), Typing.unsafe_type_of env eqclause.evd (EConstr.of_constr c2)
- in
- let ty = EConstr.Unsafe.to_constr ty in
- let ty1 = EConstr.Unsafe.to_constr ty1 in
+ let others,(c1,c2) = split_last_two args in
+ let ty1, ty2 = Typing.unsafe_type_of env eqclause.evd c1, Typing.unsafe_type_of env eqclause.evd c2 in
+ (* XXX: It looks like mk_clenv_from_env should be fixed instead? *)
+ let open EConstr in
+ let hyp_ty = Unsafe.to_constr ty in
+ let hyp_car = Unsafe.to_constr ty1 in
+ let hyp_prf = Unsafe.to_constr @@ Clenv.clenv_value eqclause in
+ let hyp_rel = Unsafe.to_constr @@ mkApp (equiv, Array.of_list others) in
+ let hyp_left = Unsafe.to_constr @@ c1 in
+ let hyp_right = Unsafe.to_constr @@ c2 in
(* if not (evd_convertible env eqclause.evd ty1 ty2) then None *)
(* else *)
- Some { hyp_cl=eqclause; hyp_prf=EConstr.Unsafe.to_constr (Clenv.clenv_value eqclause); hyp_ty = ty;
- hyp_car=ty1; hyp_rel=mkApp (equiv, Array.of_list others);
- hyp_l2r=left2right; hyp_left=c1; hyp_right=c2; }
+ Some { hyp_cl=eqclause; hyp_prf; hyp_ty; hyp_car; hyp_rel; hyp_l2r=left2right; hyp_left; hyp_right; }
with Not_found -> None
in
match find_rel ctype with
diff --git a/tactics/btermdn.ml b/tactics/btermdn.ml
index 8e50c977..aca7f6c6 100644
--- a/tactics/btermdn.ml
+++ b/tactics/btermdn.ml
@@ -9,7 +9,7 @@
(************************************************************************)
open Util
-open Term
+open Constr
open EConstr
open Names
open Pattern
@@ -22,7 +22,7 @@ open Globnames
let dnet_depth = ref 8
type term_label =
-| GRLabel of global_reference
+| GRLabel of GlobRef.t
| ProdLabel
| LambdaLabel
| SortLabel
diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml
index 73b649e5..29797240 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -18,6 +18,7 @@ open CErrors
open Util
open Names
open Term
+open Constr
open Termops
open EConstr
open Tacmach
@@ -206,7 +207,7 @@ let clenv_unique_resolver_tac with_evars ~flags clenv' =
try Proofview.tclUNIT (clenv_unique_resolver ~flags clenv' gls)
with e -> Proofview.tclZERO e
in resolve >>= fun clenv' ->
- Clenvtac.clenv_refine with_evars ~with_classes:false clenv'
+ Clenvtac.clenv_refine ~with_evars ~with_classes:false clenv'
end
let unify_e_resolve poly flags = begin fun gls (c,_,clenv) ->
@@ -226,7 +227,7 @@ let unify_resolve_refine poly flags gls ((c, t, ctx),n,clenv) =
Refine.refine ~typecheck:false begin fun sigma ->
let sigma, term, ty =
if poly then
- let (subst, ctx) = Universes.fresh_universe_context_set_instance ctx in
+ let (subst, ctx) = UnivGen.fresh_universe_context_set_instance ctx in
let map c = Vars.subst_univs_level_constr subst c in
let sigma = Evd.merge_context_set Evd.univ_flexible sigma ctx in
sigma, map c, map t
@@ -476,7 +477,7 @@ let is_Prop env sigma concl =
match EConstr.kind sigma ty with
| Sort s ->
begin match ESorts.kind sigma s with
- | Prop Null -> true
+ | Prop -> true
| _ -> false
end
| _ -> false
@@ -546,12 +547,7 @@ let make_resolve_hyp env sigma st flags only_classes pri decl =
let hints = build_subclasses ~check:false env sigma (VarRef id) empty_hint_info in
(List.map_append
(fun (path,info,c) ->
- let info =
- { info with Vernacexpr.hint_pattern =
- Option.map (Constrintern.intern_constr_pattern env sigma)
- info.Vernacexpr.hint_pattern }
- in
- make_resolves env sigma ~name:(PathHints path)
+ make_resolves env sigma ~name:(PathHints path)
(true,false,not !Flags.quiet) info false
(IsConstr (EConstr.of_constr c,Univ.ContextSet.empty)))
hints)
@@ -653,17 +649,6 @@ module Search = struct
Evd.add sigma gl evi')
sigma goals
- let fail_if_nonclass info =
- Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
- if is_class_type sigma (Proofview.Goal.concl gl) then
- Proofview.tclUNIT ()
- else (if !typeclasses_debug > 1 then
- Feedback.msg_debug (pr_depth info.search_depth ++
- str": failure due to non-class subgoal " ++
- pr_ev sigma (Proofview.Goal.goal gl));
- Proofview.tclZERO NoApplicableEx) end
-
(** The general hint application tactic.
tac1 + tac2 .... The choice of OR or ORELSE is determined
depending on the dependencies of the goal and the unique/Prop
@@ -708,8 +693,9 @@ module Search = struct
let msg =
match fst ie with
| Pretype_errors.PretypeError (env, evd, Pretype_errors.CannotUnify (x,y,_)) ->
- str"Cannot unify " ++ print_constr_env env evd x ++ str" and " ++
- print_constr_env env evd y
+ str"Cannot unify " ++
+ Printer.pr_econstr_env env evd x ++ str" and " ++
+ Printer.pr_econstr_env env evd y
| ReachedLimitEx -> str "Proof-search reached its limit."
| NoApplicableEx -> str "Proof-search failed."
| e -> CErrors.iprint ie
@@ -802,13 +788,8 @@ module Search = struct
in
if path_matches derivs [] then aux e tl
else
- let filter =
- if false (* in 8.6, still allow non-class subgoals
- info.search_only_classes *) then fail_if_nonclass info
- else Proofview.tclUNIT ()
- in
ortac
- (with_shelf (tac <*> filter) >>= fun s ->
+ (with_shelf tac >>= fun s ->
let i = !idx in incr idx; result s i None)
(fun e' ->
if CErrors.noncritical (fst e') then
@@ -872,12 +853,9 @@ module Search = struct
let search_tac_gl ?st only_classes dep hints depth i sigma gls gl :
unit Proofview.tactic =
let open Proofview in
- if false (* In 8.6, still allow non-class goals only_classes && not (is_class_type sigma (Goal.concl gl)) *) then
- Tacticals.New.tclZEROMSG (str"Not a subgoal for a class")
- else
- let dep = dep || Proofview.unifiable sigma (Goal.goal gl) gls in
- let info = make_autogoal ?st only_classes dep (cut_of_hints hints) i gl in
- search_tac hints depth 1 info
+ let dep = dep || Proofview.unifiable sigma (Goal.goal gl) gls in
+ let info = make_autogoal ?st only_classes dep (cut_of_hints hints) i gl in
+ search_tac hints depth 1 info
let search_tac ?(st=full_transparent_state) only_classes dep hints depth =
let open Proofview in
@@ -1030,8 +1008,8 @@ module Intpart = Unionfind.Make(Evar.Set)(Evar.Map)
let deps_of_constraints cstrs evm p =
List.iter (fun (_, _, x, y) ->
- let evx = Evarutil.undefined_evars_of_term evm (EConstr.of_constr x) in
- let evy = Evarutil.undefined_evars_of_term evm (EConstr.of_constr y) in
+ let evx = Evarutil.undefined_evars_of_term evm x in
+ let evy = Evarutil.undefined_evars_of_term evm y in
Intpart.union_set (Evar.Set.union evx evy) p)
cstrs
@@ -1076,7 +1054,7 @@ let error_unresolvable env comp evd =
| Some s -> Evar.Set.mem ev s
in
let fold ev evi (found, accu) =
- let ev_class = class_of_constr evd (EConstr.of_constr evi.evar_concl) in
+ let ev_class = class_of_constr evd evi.evar_concl in
if not (Option.is_empty ev_class) && is_part ev then
(* focus on one instance if only one was searched for *)
if not found then (true, Some ev)
@@ -1174,7 +1152,7 @@ let solve_inst env evd filter unique split fail =
let _ =
Hook.set Typeclasses.solve_all_instances_hook solve_inst
-let resolve_one_typeclass env ?(sigma=Evd.empty) gl unique =
+let resolve_one_typeclass env ?(sigma=Evd.from_env env) gl unique =
let nc, gl, subst, _ = Evarutil.push_rel_context_to_named_context env sigma gl in
let (gl,t,sigma) =
Goal.V82.mk_goal sigma nc gl Store.empty in
diff --git a/tactics/contradiction.ml b/tactics/contradiction.ml
index c285f21e..e12063fd 100644
--- a/tactics/contradiction.ml
+++ b/tactics/contradiction.ml
@@ -8,13 +8,12 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Term
+open Constr
open EConstr
open Hipattern
open Tactics
open Coqlib
open Reductionops
-open Misctypes
open Proofview.Notations
module NamedDecl = Context.Named.Declaration
@@ -120,7 +119,7 @@ let contradiction_term (c,lbind as cl) =
else
Proofview.tclORELSE
begin
- if lbind = NoBindings then
+ if lbind = Tactypes.NoBindings then
filter_hyp (fun c -> is_negation_of env sigma typ c)
(fun id -> simplest_elim (mkApp (mkVar id,[|c|])))
else
diff --git a/tactics/contradiction.mli b/tactics/contradiction.mli
index 2b3a9475..4bb3263f 100644
--- a/tactics/contradiction.mli
+++ b/tactics/contradiction.mli
@@ -9,7 +9,7 @@
(************************************************************************)
open EConstr
-open Misctypes
+open Tactypes
val absurd : constr -> unit Proofview.tactic
val contradiction : constr with_bindings option -> unit Proofview.tactic
diff --git a/tactics/eauto.ml b/tactics/eauto.ml
index dc310c54..80d07c5c 100644
--- a/tactics/eauto.ml
+++ b/tactics/eauto.ml
@@ -12,7 +12,7 @@ open Pp
open CErrors
open Util
open Names
-open Term
+open Constr
open Termops
open EConstr
open Proof_type
@@ -70,11 +70,10 @@ let first_goal gls =
(* tactic -> tactic_list : Apply a tactic to the first goal in the list *)
let apply_tac_list tac glls =
- let (sigr,lg) = unpackage glls in
- match lg with
+ match glls.it with
| (g1::rest) ->
- let gl = apply_sig_tac sigr tac g1 in
- repackage sigr (gl@rest)
+ let pack = tac (re_sig g1 glls.sigma) in
+ re_sig (pack.it @ rest) pack.sigma
| _ -> user_err Pp.(str "apply_tac_list")
let one_step l gl =
@@ -90,7 +89,7 @@ let rec prolog l n gl =
let out_term env = function
| IsConstr (c, _) -> c
- | IsGlobRef gr -> EConstr.of_constr (fst (Universes.fresh_global_instance env gr))
+ | IsGlobRef gr -> EConstr.of_constr (fst (UnivGen.fresh_global_instance env gr))
let prolog_tac l n =
Proofview.V82.tactic begin fun gl ->
diff --git a/tactics/elim.mli b/tactics/elim.mli
index d6b67e5b..ddfac3f2 100644
--- a/tactics/elim.mli
+++ b/tactics/elim.mli
@@ -11,12 +11,11 @@
open Names
open EConstr
open Tacticals
-open Misctypes
open Tactypes
(** Eliminations tactics. *)
-val introCaseAssumsThen : evars_flag ->
+val introCaseAssumsThen : Tactics.evars_flag ->
(intro_patterns -> branch_assumptions -> unit Proofview.tactic) ->
branch_args -> unit Proofview.tactic
diff --git a/tactics/elimschemes.ml b/tactics/elimschemes.ml
index 6bd4866c..3b69d992 100644
--- a/tactics/elimschemes.ml
+++ b/tactics/elimschemes.ml
@@ -44,10 +44,10 @@ let optimize_non_type_induction_scheme kind dep sort _ ind =
mib.mind_nparams_rec
else
mib.mind_nparams in
- let sigma, sort = Evd.fresh_sort_in_family env sigma sort in
+ let sigma, sort = Evd.fresh_sort_in_family sigma sort in
let sigma, t', c' = weaken_sort_scheme env sigma false sort npars c t in
- let sigma, nf = Evarutil.nf_evars_and_universes sigma in
- (nf c', Evd.evar_universe_context sigma), eff
+ let sigma = Evd.minimize_universes sigma in
+ (Evarutil.nf_evars_universes sigma c', Evd.evar_universe_context sigma), eff
else
let sigma, pind = Evd.fresh_inductive_instance env sigma ind in
let sigma, c = build_induction_scheme env sigma pind dep sort in
diff --git a/tactics/eqdecide.ml b/tactics/eqdecide.ml
index b0deeed1..832014a6 100644
--- a/tactics/eqdecide.ml
+++ b/tactics/eqdecide.ml
@@ -17,18 +17,18 @@
open Util
open Names
open Namegen
-open Term
+open Constr
open EConstr
open Declarations
open Tactics
open Tacticals.New
open Auto
open Constr_matching
-open Misctypes
open Hipattern
open Proofview.Notations
open Tacmach.New
open Coqlib
+open Tactypes
(* This file containts the implementation of the tactics ``Decide
Equality'' and ``Compare''. They can be used to decide the
@@ -58,14 +58,14 @@ let clear_last =
let choose_eq eqonleft =
if eqonleft then
- left_with_bindings false Misctypes.NoBindings
+ left_with_bindings false NoBindings
else
- right_with_bindings false Misctypes.NoBindings
+ right_with_bindings false NoBindings
let choose_noteq eqonleft =
if eqonleft then
- right_with_bindings false Misctypes.NoBindings
+ right_with_bindings false NoBindings
else
- left_with_bindings false Misctypes.NoBindings
+ left_with_bindings false NoBindings
(* A surgical generalize which selects the right occurrences by hand *)
(* This prevents issues where c2 is also a subterm of c1 (see e.g. #5449) *)
diff --git a/tactics/eqschemes.ml b/tactics/eqschemes.ml
index 477de645..ea5ff4a6 100644
--- a/tactics/eqschemes.ml
+++ b/tactics/eqschemes.ml
@@ -78,7 +78,7 @@ let build_dependent_inductive ind (mib,mip) =
Context.Rel.to_extended_list mkRel mip.mind_nrealdecls mib.mind_params_ctxt
@ Context.Rel.to_extended_list mkRel 0 realargs)
-let named_hd env t na = named_hd env Evd.empty (EConstr.of_constr t) na
+let named_hd env t na = named_hd env (Evd.from_env env) (EConstr.of_constr t) na
let name_assumption env = function
| LocalAssum (na,t) -> LocalAssum (named_hd env t na, t)
| LocalDef (na,c,t) -> LocalDef (named_hd env c na, c, t)
@@ -102,15 +102,20 @@ let get_coq_eq ctx =
let eq = Globnames.destIndRef Coqlib.glob_eq in
(* Do not force the lazy if they are not defined *)
let eq, ctx = with_context_set ctx
- (Universes.fresh_inductive_instance (Global.env ()) eq) in
+ (UnivGen.fresh_inductive_instance (Global.env ()) eq) in
mkIndU eq, mkConstructUi (eq,1), ctx
with Not_found ->
user_err Pp.(str "eq not found.")
let univ_of_eq env eq =
- let eq = EConstr.of_constr eq in
- match Constr.kind (EConstr.Unsafe.to_constr (Retyping.get_type_of env Evd.empty eq)) with
- | Prod (_,t,_) -> (match Constr.kind t with Sort (Type u) -> u | _ -> assert false)
+ let open EConstr in
+ let eq = of_constr eq in
+ let sigma = Evd.from_env env in
+ match kind sigma (Retyping.get_type_of env sigma eq) with
+ | Prod (_,t,_) -> (match kind sigma t with
+ Sort k ->
+ (match ESorts.kind sigma k with Type u -> u | _ -> assert false)
+ | _ -> assert false)
| _ -> assert false
(**********************************************************************)
@@ -192,7 +197,7 @@ let get_non_sym_eq_data env (ind,u) =
(**********************************************************************)
let build_sym_scheme env ind =
- let (ind,u as indu), ctx = Universes.fresh_inductive_instance env ind in
+ let (ind,u as indu), ctx = UnivGen.fresh_inductive_instance env ind in
let (mib,mip as specif),nrealargs,realsign,paramsctxt,paramsctxt1 =
get_sym_eq_data env indu in
let cstr n =
@@ -241,11 +246,11 @@ let sym_scheme_kind =
let const_of_scheme kind env ind ctx =
let sym_scheme, eff = (find_scheme kind ind) in
let sym, ctx = with_context_set ctx
- (Universes.fresh_constant_instance (Global.env()) sym_scheme) in
+ (UnivGen.fresh_constant_instance (Global.env()) sym_scheme) in
mkConstU sym, ctx, eff
let build_sym_involutive_scheme env ind =
- let (ind,u as indu), ctx = Universes.fresh_inductive_instance env ind in
+ let (ind,u as indu), ctx = UnivGen.fresh_inductive_instance env ind in
let (mib,mip as specif),nrealargs,realsign,paramsctxt,paramsctxt1 =
get_sym_eq_data env indu in
let eq,eqrefl,ctx = get_coq_eq ctx in
@@ -353,7 +358,7 @@ let sym_involutive_scheme_kind =
(**********************************************************************)
let build_l2r_rew_scheme dep env ind kind =
- let (ind,u as indu), ctx = Universes.fresh_inductive_instance env ind in
+ let (ind,u as indu), ctx = UnivGen.fresh_inductive_instance env ind in
let (mib,mip as specif),nrealargs,realsign,paramsctxt,paramsctxt1 =
get_sym_eq_data env indu in
let sym, ctx, eff = const_of_scheme sym_scheme_kind env ind ctx in
@@ -392,7 +397,7 @@ let build_l2r_rew_scheme dep env ind kind =
rel_vect (nrealargs+4) nrealargs;
rel_vect 1 nrealargs;
[|mkRel 1|]]) in
- let s, ctx' = Universes.fresh_sort_in_family (Global.env ()) kind in
+ let s, ctx' = UnivGen.fresh_sort_in_family kind in
let ctx = Univ.ContextSet.union ctx ctx' in
let s = mkSort s in
let ci = make_case_info (Global.env()) ind RegularStyle in
@@ -469,7 +474,7 @@ let build_l2r_rew_scheme dep env ind kind =
(**********************************************************************)
let build_l2r_forward_rew_scheme dep env ind kind =
- let (ind,u as indu), ctx = Universes.fresh_inductive_instance env ind in
+ let (ind,u as indu), ctx = UnivGen.fresh_inductive_instance env ind in
let (mib,mip as specif),nrealargs,realsign,paramsctxt,paramsctxt1 =
get_sym_eq_data env indu in
let cstr n p =
@@ -495,7 +500,7 @@ let build_l2r_forward_rew_scheme dep env ind kind =
name_context env ((LocalAssum (Name varH,applied_ind))::realsign) in
let realsign_ind_P n aP =
name_context env ((LocalAssum (Name varH,aP))::realsign_P n) in
- let s, ctx' = Universes.fresh_sort_in_family (Global.env ()) kind in
+ let s, ctx' = UnivGen.fresh_sort_in_family kind in
let ctx = Univ.ContextSet.union ctx ctx' in
let s = mkSort s in
let ci = make_case_info (Global.env()) ind RegularStyle in
@@ -561,7 +566,7 @@ let build_l2r_forward_rew_scheme dep env ind kind =
(**********************************************************************)
let build_r2l_forward_rew_scheme dep env ind kind =
- let (ind,u as indu), ctx = Universes.fresh_inductive_instance env ind in
+ let (ind,u as indu), ctx = UnivGen.fresh_inductive_instance env ind in
let ((mib,mip as specif),constrargs,realsign,paramsctxt,nrealargs) =
get_non_sym_eq_data env indu in
let cstr n =
@@ -573,7 +578,7 @@ let build_r2l_forward_rew_scheme dep env ind kind =
let applied_ind = build_dependent_inductive indu specif in
let realsign_ind =
name_context env ((LocalAssum (Name varH,applied_ind))::realsign) in
- let s, ctx' = Universes.fresh_sort_in_family (Global.env ()) kind in
+ let s, ctx' = UnivGen.fresh_sort_in_family kind in
let ctx = Univ.ContextSet.union ctx ctx' in
let s = mkSort s in
let ci = make_case_info (Global.env()) ind RegularStyle in
@@ -620,7 +625,9 @@ let build_r2l_forward_rew_scheme dep env ind kind =
(**********************************************************************)
let fix_r2l_forward_rew_scheme (c, ctx') =
- let t = Retyping.get_type_of (Global.env()) Evd.empty (EConstr.of_constr c) in
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ let t = Retyping.get_type_of env sigma (EConstr.of_constr c) in
let t = EConstr.Unsafe.to_constr t in
let ctx,_ = decompose_prod_assum t in
match ctx with
@@ -630,7 +637,7 @@ let fix_r2l_forward_rew_scheme (c, ctx') =
(mkLambda_or_LetIn (RelDecl.map_constr (liftn (-1) 1) p)
(mkLambda_or_LetIn (RelDecl.map_constr (liftn (-1) 2) hp)
(mkLambda_or_LetIn (RelDecl.map_constr (lift 2) ind)
- (EConstr.Unsafe.to_constr (Reductionops.whd_beta Evd.empty
+ (EConstr.Unsafe.to_constr (Reductionops.whd_beta sigma
(EConstr.of_constr (applist (c,
Context.Rel.to_extended_list mkRel 3 indargs @ [mkRel 1;mkRel 3;mkRel 2]))))))))
in c', ctx'
@@ -755,7 +762,7 @@ let rew_r2l_scheme_kind =
let build_congr env (eq,refl,ctx) ind =
let (ind,u as indu), ctx = with_context_set ctx
- (Universes.fresh_inductive_instance env ind) in
+ (UnivGen.fresh_inductive_instance env ind) in
let (mib,mip) = lookup_mind_specif env ind in
if not (Int.equal (Array.length mib.mind_packets) 1) || not (Int.equal (Array.length mip.mind_nf_lc) 1) then
error "Not an inductive type with a single constructor.";
@@ -778,7 +785,7 @@ let build_congr env (eq,refl,ctx) ind =
let varH = fresh env (Id.of_string "H") in
let varf = fresh env (Id.of_string "f") in
let ci = make_case_info (Global.env()) ind RegularStyle in
- let uni, ctx = Universes.extend_context (Universes.new_global_univ ()) ctx in
+ let uni, ctx = UnivGen.extend_context (UnivGen.new_global_univ ()) ctx in
let ctx = (fst ctx, Univ.enforce_leq uni (univ_of_eq env eq) (snd ctx)) in
let c =
my_it_mkLambda_or_LetIn paramsctxt
diff --git a/tactics/equality.ml b/tactics/equality.ml
index 5821717d..0e392157 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -15,6 +15,7 @@ open Util
open Names
open Nameops
open Term
+open Constr
open Termops
open EConstr
open Vars
@@ -41,7 +42,7 @@ open Ind_tables
open Eqschemes
open Locus
open Locusops
-open Misctypes
+open Tactypes
open Proofview.Notations
open Unification
open Context.Named.Declaration
@@ -153,7 +154,7 @@ let instantiate_lemma_all frzevars gl c ty l l2r concl =
let c1 = args.(arglen - 2) in
let c2 = args.(arglen - 1) in
let try_occ (evd', c') =
- Clenvtac.clenv_pose_dependent_evars true {eqclause with evd = evd'}
+ Clenvtac.clenv_pose_dependent_evars ~with_evars:true {eqclause with evd = evd'}
in
let flags = make_flags frzevars (Tacmach.New.project gl) rewrite_unif_flags eqclause in
let occs =
@@ -545,6 +546,12 @@ let apply_special_clear_request clear_flag f =
e when catchable_exception e -> tclIDTAC
end
+type multi =
+ | Precisely of int
+ | UpTo of int
+ | RepeatStar
+ | RepeatPlus
+
let general_multi_rewrite with_evars l cl tac =
let do1 l2r f =
Proofview.Goal.enter begin fun gl ->
@@ -935,7 +942,7 @@ let rec build_discriminator env sigma true_0 false_0 dirn c = function
let (cnum_nlams,cnum_env,kont) = descend_then env sigma c cnum in
let newc = mkRel(cnum_nlams-argnum) in
let subval = build_discriminator cnum_env sigma true_0 false_0 dirn newc l in
- kont sigma subval (false_0,mkSort (Prop Null))
+ kont sigma subval (false_0,mkProp)
(* Note: discrimination could be more clever: if some elimination is
not allowed because of a large impredicative constructor in the
@@ -1036,7 +1043,7 @@ let onEquality with_evars tac (c,lbindc) =
let t = type_of c in
let t' = try snd (reduce_to_quantified_ind t) with UserError _ -> t in
let eq_clause = pf_apply make_clenv_binding gl (c,t') lbindc in
- let eq_clause' = Clenvtac.clenv_pose_dependent_evars with_evars eq_clause in
+ let eq_clause' = Clenvtac.clenv_pose_dependent_evars ~with_evars eq_clause in
let eqn = clenv_type eq_clause' in
let (eq,u,eq_args) = find_this_eq_data_decompose gl eqn in
tclTHEN
@@ -1108,8 +1115,6 @@ let make_tuple env sigma (rterm,rty) lind =
let p = mkLambda (na, a, rty) in
let sigma, exist_term = Evd.fresh_global env sigma sigdata.intro in
let sigma, sig_term = Evd.fresh_global env sigma sigdata.typ in
- let exist_term = EConstr.of_constr exist_term in
- let sig_term = EConstr.of_constr sig_term in
sigma,
(applist(exist_term,[a;p;(mkRel lind);rterm]),
applist(sig_term,[a;p]))
@@ -1178,35 +1183,35 @@ let minimal_free_rels_rec env sigma =
let sig_clausal_form env sigma sort_of_ty siglen ty dflt =
let sigdata = find_sigma_data env sort_of_ty in
- let evdref = ref (Evd.clear_metas sigma) in
- let rec sigrec_clausal_form siglen p_i =
+ let rec sigrec_clausal_form sigma siglen p_i =
if Int.equal siglen 0 then
(* is the default value typable with the expected type *)
let dflt_typ = unsafe_type_of env sigma dflt in
try
- let () = evdref := Evarconv.the_conv_x_leq env dflt_typ p_i !evdref in
- let () =
- evdref := Evarconv.solve_unif_constraints_with_heuristics env !evdref in
- dflt
+ let sigma = Evarconv.the_conv_x_leq env dflt_typ p_i sigma in
+ let sigma =
+ Evarconv.solve_unif_constraints_with_heuristics env sigma in
+ sigma, dflt
with Evarconv.UnableToUnify _ ->
user_err Pp.(str "Cannot solve a unification problem.")
else
- let (a,p_i_minus_1) = match whd_beta_stack !evdref p_i with
+ let (a,p_i_minus_1) = match whd_beta_stack sigma p_i with
| (_sigS,[a;p]) -> (a, p)
| _ -> anomaly ~label:"sig_clausal_form" (Pp.str "should be a sigma type.") in
- let ev = Evarutil.e_new_evar env evdref a in
+ let sigma, ev = Evarutil.new_evar env sigma a in
let rty = beta_applist sigma (p_i_minus_1,[ev]) in
- let tuple_tail = sigrec_clausal_form (siglen-1) rty in
- let evopt = match EConstr.kind !evdref ev with Evar _ -> None | _ -> Some ev in
+ let sigma, tuple_tail = sigrec_clausal_form sigma (siglen-1) rty in
+ let evopt = match EConstr.kind sigma ev with Evar _ -> None | _ -> Some ev in
match evopt with
| Some w ->
- let w_type = unsafe_type_of env !evdref w in
- if Evarconv.e_cumul env evdref w_type a then
- let exist_term = Evarutil.evd_comb1 (Evd.fresh_global env) evdref sigdata.intro in
- let exist_term = EConstr.of_constr exist_term in
- applist(exist_term,[a;p_i_minus_1;w;tuple_tail])
- else
+ let w_type = unsafe_type_of env sigma w in
+ begin match Evarconv.cumul env sigma w_type a with
+ | Some sigma ->
+ let sigma, exist_term = Evd.fresh_global env sigma sigdata.intro in
+ sigma, applist(exist_term,[a;p_i_minus_1;w;tuple_tail])
+ | None ->
user_err Pp.(str "Cannot solve a unification problem.")
+ end
| None ->
(* This at least happens if what has been detected as a
dependency is not one; use an evasive error message;
@@ -1216,8 +1221,9 @@ let sig_clausal_form env sigma sort_of_ty siglen ty dflt =
unsolved evars would mean not binding rel *)
user_err Pp.(str "Cannot solve a unification problem.")
in
- let scf = sigrec_clausal_form siglen ty in
- !evdref, Evarutil.nf_evar !evdref scf
+ let sigma = Evd.clear_metas sigma in
+ let sigma, scf = sigrec_clausal_form sigma siglen ty in
+ sigma, Evarutil.nf_evar sigma scf
(* The problem is to build a destructor (a generalization of the
predecessor) which, when applied to a term made of constructors
@@ -1372,7 +1378,6 @@ let inject_at_positions env sigma l2r (eq,_,(t,t1,t2)) eq_clause posns tac =
let sigma, (injbody,resty) = build_injector e_env !evdref t1' (mkVar e) cpath in
let injfun = mkNamedLambda e t injbody in
let sigma,congr = Evd.fresh_global env sigma eq.congr in
- let congr = EConstr.of_constr congr in
let pf = applist(congr,[t;resty;injfun;t1;t2]) in
let sigma, pf_typ = Typing.type_of env sigma pf in
let inj_clause = apply_on_clause (pf,pf_typ) eq_clause in
@@ -1783,7 +1788,7 @@ let subst_all ?(flags=default_subst_tactic_flags) () =
try
let lbeq,u,(_,x,y) = find_eq_data_decompose (NamedDecl.get_type decl) in
let u = EInstance.kind sigma u in
- let eq = Universes.constr_of_global_univ (lbeq.eq,u) in
+ let eq = UnivGen.constr_of_global_univ (lbeq.eq,u) in
if flags.only_leibniz then restrict_to_eq_and_identity eq;
match EConstr.kind sigma x, EConstr.kind sigma y with
| Var z, _ when not (is_evaluable env (EvalVarRef z)) ->
@@ -1809,9 +1814,9 @@ let subst_all ?(flags=default_subst_tactic_flags) () =
(* J.F.: added to prevent failure on goal containing x=x as an hyp *)
if EConstr.eq_constr sigma x y then Proofview.tclUNIT () else
match EConstr.kind sigma x, EConstr.kind sigma y with
- | Var x', _ when not (dependent sigma x y) && not (is_evaluable env (EvalVarRef x')) ->
+ | Var x', _ when not (Termops.local_occur_var sigma x' y) && not (is_evaluable env (EvalVarRef x')) ->
subst_one flags.rewrite_dependent_proof x' (hyp,y,true)
- | _, Var y' when not (dependent sigma y x) && not (is_evaluable env (EvalVarRef y')) ->
+ | _, Var y' when not (Termops.local_occur_var sigma y' x) && not (is_evaluable env (EvalVarRef y')) ->
subst_one flags.rewrite_dependent_proof y' (hyp,x,false)
| _ ->
Proofview.tclUNIT ()
@@ -1834,7 +1839,7 @@ let subst_all ?(flags=default_subst_tactic_flags) () =
try
let lbeq,u,(_,x,y) = find_eq_data_decompose c in
let u = EInstance.kind sigma u in
- let eq = Universes.constr_of_global_univ (lbeq.eq,u) in
+ let eq = UnivGen.constr_of_global_univ (lbeq.eq,u) in
if flags.only_leibniz then restrict_to_eq_and_identity eq;
(* J.F.: added to prevent failure on goal containing x=x as an hyp *)
if EConstr.eq_constr sigma x y then failwith "caught";
diff --git a/tactics/equality.mli b/tactics/equality.mli
index c0be917a..6f3e08ea 100644
--- a/tactics/equality.mli
+++ b/tactics/equality.mli
@@ -15,8 +15,8 @@ open EConstr
open Environ
open Ind_tables
open Locus
-open Misctypes
open Tactypes
+open Tactics
(*i*)
type dep_proof_flag = bool (* true = support rewriting dependent proofs *)
@@ -61,6 +61,12 @@ val general_rewrite_in :
val general_rewrite_clause :
orientation -> evars_flag -> ?tac:(unit Proofview.tactic * conditions) -> constr with_bindings -> clause -> unit Proofview.tactic
+type multi =
+ | Precisely of int
+ | UpTo of int
+ | RepeatStar
+ | RepeatPlus
+
val general_multi_rewrite :
evars_flag -> (bool * multi * clear_flag * delayed_open_constr_with_bindings) list ->
clause -> (unit Proofview.tactic * conditions) option -> unit Proofview.tactic
@@ -80,20 +86,20 @@ val discrConcl : unit Proofview.tactic
val discrHyp : Id.t -> unit Proofview.tactic
val discrEverywhere : evars_flag -> unit Proofview.tactic
val discr_tac : evars_flag ->
- constr with_bindings destruction_arg option -> unit Proofview.tactic
+ constr with_bindings Tactics.destruction_arg option -> unit Proofview.tactic
(* Below, if flag is [None], it takes the value from the dynamic value of the option *)
val inj : inj_flags option -> intro_patterns option -> evars_flag ->
clear_flag -> constr with_bindings -> unit Proofview.tactic
val injClause : inj_flags option -> intro_patterns option -> evars_flag ->
- constr with_bindings destruction_arg option -> unit Proofview.tactic
+ constr with_bindings Tactics.destruction_arg option -> unit Proofview.tactic
val injHyp : inj_flags option -> clear_flag -> Id.t -> unit Proofview.tactic
val injConcl : inj_flags option -> unit Proofview.tactic
val simpleInjClause : inj_flags option -> evars_flag ->
- constr with_bindings destruction_arg option -> unit Proofview.tactic
+ constr with_bindings Tactics.destruction_arg option -> unit Proofview.tactic
-val dEq : keep_proofs:(bool option) -> evars_flag -> constr with_bindings destruction_arg option -> unit Proofview.tactic
-val dEqThen : keep_proofs:(bool option) -> evars_flag -> (clear_flag -> constr -> int -> unit Proofview.tactic) -> constr with_bindings destruction_arg option -> unit Proofview.tactic
+val dEq : keep_proofs:(bool option) -> evars_flag -> constr with_bindings Tactics.destruction_arg option -> unit Proofview.tactic
+val dEqThen : keep_proofs:(bool option) -> evars_flag -> (clear_flag -> constr -> int -> unit Proofview.tactic) -> constr with_bindings Tactics.destruction_arg option -> unit Proofview.tactic
val make_iterated_tuple :
env -> evar_map -> constr -> (constr * types) -> evar_map * (constr * constr * constr)
diff --git a/tactics/hints.ml b/tactics/hints.ml
index 500abc5b..43a450ea 100644
--- a/tactics/hints.ml
+++ b/tactics/hints.ml
@@ -12,7 +12,7 @@ open Pp
open Util
open CErrors
open Names
-open Term
+open Constr
open Evd
open EConstr
open Vars
@@ -23,17 +23,16 @@ open Libobject
open Namegen
open Libnames
open Smartlocate
-open Misctypes
open Termops
open Inductiveops
open Typing
open Decl_kinds
+open Typeclasses
open Pattern
open Patternops
open Clenv
open Tacred
open Printer
-open Vernacexpr
module NamedDecl = Context.Named.Declaration
@@ -94,13 +93,14 @@ let secvars_of_hyps hyps =
else pred
let empty_hint_info =
- let open Vernacexpr in
{ hint_priority = None; hint_pattern = None }
(************************************************************************)
(* The Type of Constructions Autotactic Hints *)
(************************************************************************)
+type hint_info_expr = Constrexpr.constr_pattern_expr hint_info_gen
+
type 'a hint_ast =
| Res_pf of 'a (* Hint Apply *)
| ERes_pf of 'a (* Hint EApply *)
@@ -115,7 +115,7 @@ type 'a hints_path_atom_gen =
(* For forward hints, their names is the list of projections *)
| PathAny
-type hints_path_atom = global_reference hints_path_atom_gen
+type hints_path_atom = GlobRef.t hints_path_atom_gen
type 'a hints_path_gen =
| PathAtom of 'a hints_path_atom_gen
@@ -125,11 +125,11 @@ type 'a hints_path_gen =
| PathEmpty
| PathEpsilon
-type pre_hints_path = Libnames.reference hints_path_gen
-type hints_path = global_reference hints_path_gen
+type pre_hints_path = Libnames.qualid hints_path_gen
+type hints_path = GlobRef.t hints_path_gen
type hint_term =
- | IsGlobRef of global_reference
+ | IsGlobRef of GlobRef.t
| IsConstr of constr * Univ.ContextSet.t
type 'a with_uid = {
@@ -153,9 +153,33 @@ type 'a with_metadata = {
type full_hint = hint with_metadata
-type hint_entry = global_reference option *
+type hint_entry = GlobRef.t option *
raw_hint hint_ast with_uid with_metadata
+type reference_or_constr =
+ | HintsReference of qualid
+ | HintsConstr of Constrexpr.constr_expr
+
+type hint_mode =
+ | ModeInput (* No evars *)
+ | ModeNoHeadEvar (* No evar at the head *)
+ | ModeOutput (* Anything *)
+
+type 'a hints_transparency_target =
+ | HintsVariables
+ | HintsConstants
+ | HintsReferences of 'a list
+
+type hints_expr =
+ | HintsResolve of (hint_info_expr * bool * reference_or_constr) list
+ | HintsResolveIFF of bool * qualid list * int option
+ | HintsImmediate of reference_or_constr list
+ | HintsUnfold of qualid list
+ | HintsTransparency of qualid hints_transparency_target * bool
+ | HintsMode of qualid * hint_mode list
+ | HintsConstructors of qualid list
+ | HintsExtern of int * Constrexpr.constr_expr option * Genarg.raw_generic_argument
+
type import_level = [ `LAX | `WARN | `STRICT ]
let warn_hint : import_level ref = ref `LAX
@@ -275,16 +299,16 @@ let strip_params env sigma c =
match EConstr.kind sigma c with
| App (f, args) ->
(match EConstr.kind sigma f with
- | Const (p,_) ->
- let cb = lookup_constant p env in
- (match cb.Declarations.const_proj with
- | Some pb ->
- let n = pb.Declarations.proj_npars in
- if Array.length args > n then
- mkApp (mkProj (Projection.make p false, args.(n)),
- Array.sub args (n+1) (Array.length args - (n + 1)))
- else c
- | None -> c)
+ | Const (cst,_) ->
+ (match Recordops.find_primitive_projection cst with
+ | Some p ->
+ let p = Projection.make p false in
+ let npars = Projection.npars p in
+ if Array.length args > npars then
+ mkApp (mkProj (p, args.(npars)),
+ Array.sub args (npars+1) (Array.length args - (npars + 1)))
+ else c
+ | None -> c)
| _ -> c)
| _ -> c
@@ -308,7 +332,7 @@ let instantiate_hint env sigma p =
{ p with code = { p.code with obj = code } }
let hints_path_atom_eq h1 h2 = match h1, h2 with
-| PathHints l1, PathHints l2 -> List.equal eq_gr l1 l2
+| PathHints l1, PathHints l2 -> List.equal GlobRef.equal l1 l2
| PathAny, PathAny -> true
| _ -> false
@@ -365,7 +389,7 @@ let path_seq p p' =
let rec path_derivate hp hint =
let rec derivate_atoms hints hints' =
match hints, hints' with
- | gr :: grs, gr' :: grs' when eq_gr gr gr' -> derivate_atoms grs grs'
+ | gr :: grs, gr' :: grs' when GlobRef.equal gr gr' -> derivate_atoms grs grs'
| [], [] -> PathEpsilon
| [], hints -> PathEmpty
| grs, [] -> PathAtom (PathHints grs)
@@ -448,7 +472,7 @@ let subst_path_atom subst p =
| PathAny -> p
| PathHints grs ->
let gr' gr = fst (subst_global subst gr) in
- let grs' = List.smartmap gr' grs in
+ let grs' = List.Smart.map gr' grs in
if grs' == grs then p else PathHints grs'
let rec subst_hints_path subst hp =
@@ -474,28 +498,28 @@ module Hint_db :
sig
type t
val empty : ?name:hint_db_name -> transparent_state -> bool -> t
-val find : global_reference -> t -> search_entry
+val find : GlobRef.t -> t -> search_entry
val map_none : secvars:Id.Pred.t -> t -> full_hint list
-val map_all : secvars:Id.Pred.t -> global_reference -> t -> full_hint list
+val map_all : secvars:Id.Pred.t -> GlobRef.t -> t -> full_hint list
val map_existential : evar_map -> secvars:Id.Pred.t ->
- (global_reference * constr array) -> constr -> t -> full_hint list
+ (GlobRef.t * constr array) -> constr -> t -> full_hint list
val map_eauto : evar_map -> secvars:Id.Pred.t ->
- (global_reference * constr array) -> constr -> t -> full_hint list
+ (GlobRef.t * constr array) -> constr -> t -> full_hint list
val map_auto : evar_map -> secvars:Id.Pred.t ->
- (global_reference * constr array) -> constr -> t -> full_hint list
+ (GlobRef.t * constr array) -> constr -> t -> full_hint list
val add_one : env -> evar_map -> hint_entry -> t -> t
val add_list : env -> evar_map -> hint_entry list -> t -> t
-val remove_one : global_reference -> t -> t
-val remove_list : global_reference list -> t -> t
-val iter : (global_reference option -> hint_mode array list -> full_hint list -> unit) -> t -> unit
+val remove_one : GlobRef.t -> t -> t
+val remove_list : GlobRef.t list -> t -> t
+val iter : (GlobRef.t option -> hint_mode array list -> full_hint list -> unit) -> t -> unit
val use_dn : t -> bool
val transparent_state : t -> transparent_state
val set_transparent_state : t -> transparent_state -> t
val add_cut : hints_path -> t -> t
-val add_mode : global_reference -> hint_mode array -> t -> t
+val add_mode : GlobRef.t -> hint_mode array -> t -> t
val cut : t -> hints_path
val unfolds : t -> Id.Set.t * Cset.t
-val fold : (global_reference option -> hint_mode array list -> full_hint list -> 'a -> 'a) ->
+val fold : (GlobRef.t option -> hint_mode array list -> full_hint list -> 'a -> 'a) ->
t -> 'a -> 'a
end =
@@ -510,7 +534,7 @@ struct
hintdb_map : search_entry Constr_map.t;
(* A list of unindexed entries starting with an unfoldable constant
or with no associated pattern. *)
- hintdb_nopat : (global_reference option * stored_data) list;
+ hintdb_nopat : (GlobRef.t option * stored_data) list;
hintdb_name : string option;
}
@@ -654,7 +678,7 @@ struct
let add_list env sigma l db = List.fold_left (fun db k -> add_one env sigma k db) db l
- let remove_sdl p sdl = List.smartfilter p sdl
+ let remove_sdl p sdl = List.filter p sdl
let remove_he st p se =
let sl1' = remove_sdl p se.sentry_nopat in
@@ -664,9 +688,9 @@ struct
let remove_list grs db =
let filter (_, h) =
- match h.name with PathHints [gr] -> not (List.mem_f eq_gr gr grs) | _ -> true in
+ match h.name with PathHints [gr] -> not (List.mem_f GlobRef.equal gr grs) | _ -> true in
let hintmap = Constr_map.map (remove_he db.hintdb_state filter) db.hintdb_map in
- let hintnopat = List.smartfilter (fun (ge, sd) -> filter sd) db.hintdb_nopat in
+ let hintnopat = List.filter (fun (ge, sd) -> filter sd) db.hintdb_nopat in
{ db with hintdb_map = hintmap; hintdb_nopat = hintnopat }
let remove_one gr db = remove_list [gr] db
@@ -792,7 +816,7 @@ let make_exact_entry env sigma info poly ?(name=PathAny) (c, cty, ctx) =
match EConstr.kind sigma cty with
| Prod _ -> failwith "make_exact_entry"
| _ ->
- let pat = Patternops.pattern_of_constr env sigma (EConstr.to_constr sigma cty) in
+ let pat = Patternops.pattern_of_constr env sigma (EConstr.to_constr ~abort_on_undefined_evars:false sigma cty) in
let hd =
try head_pattern_bound pat
with BoundPattern -> failwith "make_exact_entry"
@@ -814,12 +838,12 @@ let make_apply_entry env sigma (eapply,hnf,verbose) info poly ?(name=PathAny) (c
let sigma' = Evd.merge_context_set univ_flexible sigma ctx in
let ce = mk_clenv_from_env env sigma' None (c,cty) in
let c' = clenv_type (* ~reduce:false *) ce in
- let pat = Patternops.pattern_of_constr env ce.evd (EConstr.to_constr sigma c') in
+ let pat = Patternops.pattern_of_constr env ce.evd (EConstr.to_constr ~abort_on_undefined_evars:false sigma c') in
let hd =
try head_pattern_bound pat
with BoundPattern -> failwith "make_apply_entry" in
let miss = clenv_missing ce in
- let nmiss = List.length (clenv_missing ce) in
+ let nmiss = List.length miss in
let secvars = secvars_of_constr env sigma c in
let pri = match info.hint_priority with None -> nb_hyp sigma' cty + nmiss | Some p -> p in
let pat = match info.hint_pattern with
@@ -862,20 +886,6 @@ let pr_hint_term env sigma ctx = function
let sigma = Evd.merge_context_set Evd.univ_flexible sigma ctx in
pr_econstr_env env sigma c
-(** We need an object to record the side-effect of registering
- global universes associated with a hint. *)
-let cache_context_set (_,c) =
- Global.push_context_set false c
-
-let input_context_set : Univ.ContextSet.t -> Libobject.obj =
- let open Libobject in
- declare_object
- { (default_object "Global universe context") with
- cache_function = cache_context_set;
- load_function = (fun _ -> cache_context_set);
- discharge_function = (fun (_,a) -> Some a);
- classify_function = (fun a -> Keep a) }
-
let warn_polymorphic_hint =
CWarnings.create ~name:"polymorphic-hint" ~category:"automation"
(fun hint -> strbrk"Using polymorphic hint " ++ hint ++
@@ -886,7 +896,7 @@ let fresh_global_or_constr env sigma poly cr =
let isgr, (c, ctx) =
match cr with
| IsGlobRef gr ->
- let (c, ctx) = Universes.fresh_global_instance env gr in
+ let (c, ctx) = UnivGen.fresh_global_instance env gr in
true, (EConstr.of_constr c, ctx)
| IsConstr (c, ctx) -> false, (c, ctx)
in
@@ -895,7 +905,7 @@ let fresh_global_or_constr env sigma poly cr =
else begin
if isgr then
warn_polymorphic_hint (pr_hint_term env sigma ctx cr);
- Lib.add_anonymous_leaf (input_context_set ctx);
+ Declare.declare_universe_context false ctx;
(c, Univ.ContextSet.empty)
end
@@ -1005,15 +1015,19 @@ let add_hint dbname hintlist =
let db' = Hint_db.add_list env sigma hintlist db in
searchtable_add (dbname,db')
-let add_transparency dbname grs b =
+let add_transparency dbname target b =
let db = get_db dbname in
- let st = Hint_db.transparent_state db in
+ let (ids, csts as st) = Hint_db.transparent_state db in
let st' =
- List.fold_left (fun (ids, csts) gr ->
- match gr with
- | EvalConstRef c -> (ids, (if b then Cpred.add else Cpred.remove) c csts)
- | EvalVarRef v -> (if b then Id.Pred.add else Id.Pred.remove) v ids, csts)
- st grs
+ match target with
+ | HintsVariables -> (if b then Id.Pred.full else Id.Pred.empty), csts
+ | HintsConstants -> ids, if b then Cpred.full else Cpred.empty
+ | HintsReferences grs ->
+ List.fold_left (fun (ids, csts) gr ->
+ match gr with
+ | EvalConstRef c -> (ids, (if b then Cpred.add else Cpred.remove) c csts)
+ | EvalVarRef v -> (if b then Id.Pred.add else Id.Pred.remove) v ids, csts)
+ st grs
in searchtable_add (dbname, Hint_db.set_transparent_state db st')
let remove_hint dbname grs =
@@ -1023,11 +1037,11 @@ let remove_hint dbname grs =
type hint_action =
| CreateDB of bool * transparent_state
- | AddTransparency of evaluable_global_reference list * bool
+ | AddTransparency of evaluable_global_reference hints_transparency_target * bool
| AddHints of hint_entry list
- | RemoveHints of global_reference list
+ | RemoveHints of GlobRef.t list
| AddCut of hints_path
- | AddMode of global_reference * hint_mode array
+ | AddMode of GlobRef.t * hint_mode array
let add_cut dbname path =
let db = get_db dbname in
@@ -1075,8 +1089,8 @@ let subst_autohint (subst, obj) =
in if gr' == gr then gr else gr'
in
let subst_hint (k,data as hint) =
- let k' = Option.smartmap subst_key k in
- let pat' = Option.smartmap (subst_pattern subst) data.pat in
+ let k' = Option.Smart.map subst_key k in
+ let pat' = Option.Smart.map (subst_pattern subst) data.pat in
let subst_mps subst c = EConstr.of_constr (subst_mps subst (EConstr.Unsafe.to_constr c)) in
let code' = match data.code.obj with
| Res_pf (c,t,ctx) ->
@@ -1113,14 +1127,22 @@ let subst_autohint (subst, obj) =
in
let action = match obj.hint_action with
| CreateDB _ -> obj.hint_action
- | AddTransparency (grs, b) ->
- let grs' = List.smartmap (subst_evaluable_reference subst) grs in
- if grs == grs' then obj.hint_action else AddTransparency (grs', b)
+ | AddTransparency (target, b) ->
+ let target' =
+ match target with
+ | HintsVariables -> target
+ | HintsConstants -> target
+ | HintsReferences grs ->
+ let grs' = List.Smart.map (subst_evaluable_reference subst) grs in
+ if grs == grs' then target
+ else HintsReferences grs'
+ in
+ if target' == target then obj.hint_action else AddTransparency (target', b)
| AddHints hintlist ->
- let hintlist' = List.smartmap subst_hint hintlist in
+ let hintlist' = List.Smart.map subst_hint hintlist in
if hintlist' == hintlist then obj.hint_action else AddHints hintlist'
| RemoveHints grs ->
- let grs' = List.smartmap (subst_global_reference subst) grs in
+ let grs' = List.Smart.map (subst_global_reference subst) grs in
if grs == grs' then obj.hint_action else RemoveHints grs'
| AddCut path ->
let path' = subst_hints_path subst path in
@@ -1228,15 +1250,15 @@ let add_trivials env sigma l local dbnames =
type hnf = bool
-type hint_info = (patvar list * constr_pattern) hint_info_gen
+type nonrec hint_info = hint_info
type hints_entry =
| HintsResolveEntry of (hint_info * polymorphic * hnf * hints_path_atom * hint_term) list
| HintsImmediateEntry of (hints_path_atom * polymorphic * hint_term) list
| HintsCutEntry of hints_path
| HintsUnfoldEntry of evaluable_global_reference list
- | HintsTransparencyEntry of evaluable_global_reference list * bool
- | HintsModeEntry of global_reference * hint_mode list
+ | HintsTransparencyEntry of evaluable_global_reference hints_transparency_target * bool
+ | HintsModeEntry of GlobRef.t * hint_mode list
| HintsExternEntry of hint_info * Genarg.glob_generic_argument
let default_prepare_hint_ident = Id.of_string "H"
@@ -1273,20 +1295,53 @@ let prepare_hint check (poly,local) env init (sigma,c) =
subst := (evar,mkVar id)::!subst;
mkNamedLambda id t (iter (replace_term sigma evar (mkVar id) c)) in
let c' = iter c in
- if check then Pretyping.check_evars (Global.env()) Evd.empty sigma c';
+ let env = Global.env () in
+ let empty_sigma = Evd.from_env env in
+ if check then Pretyping.check_evars env empty_sigma sigma c';
let diff = Univ.ContextSet.diff (Evd.universe_context_set sigma) (Evd.universe_context_set init) in
if poly then IsConstr (c', diff)
else if local then IsConstr (c', diff)
- else (Lib.add_anonymous_leaf (input_context_set diff);
+ else (Declare.declare_universe_context false diff;
IsConstr (c', Univ.ContextSet.empty))
+let project_hint ~poly pri l2r r =
+ let open EConstr in
+ let open Coqlib in
+ let gr = Smartlocate.global_with_alias r in
+ let env = Global.env() in
+ let sigma = Evd.from_env env in
+ let sigma, c = Evd.fresh_global env sigma gr in
+ let t = Retyping.get_type_of env sigma c in
+ let t =
+ Tacred.reduce_to_quantified_ref env sigma (Lazy.force coq_iff_ref) t in
+ let sign,ccl = decompose_prod_assum sigma t in
+ let (a,b) = match snd (decompose_app sigma ccl) with
+ | [a;b] -> (a,b)
+ | _ -> assert false in
+ let p =
+ if l2r then build_coq_iff_left_proj () else build_coq_iff_right_proj () in
+ let sigma, p = Evd.fresh_global env sigma p in
+ let c = Reductionops.whd_beta sigma (mkApp (c, Context.Rel.to_extended_vect mkRel 0 sign)) in
+ let c = it_mkLambda_or_LetIn
+ (mkApp (p,[|mkArrow a (lift 1 b);mkArrow b (lift 1 a);c|])) sign in
+ let id =
+ Nameops.add_suffix (Nametab.basename_of_global gr) ("_proj_" ^ (if l2r then "l2r" else "r2l"))
+ in
+ let ctx = Evd.const_univ_entry ~poly sigma in
+ let c = EConstr.to_constr sigma c in
+ let c = Declare.declare_definition ~internal:Declare.InternalTacticRequest id (c,ctx) in
+ let info = {Typeclasses.hint_priority = pri; hint_pattern = None} in
+ (info,false,true,PathAny, IsGlobRef (Globnames.ConstRef c))
+
let interp_hints poly =
fun h ->
let env = Global.env () in
let sigma = Evd.from_env env in
let f poly c =
let evd,c = Constrintern.interp_open_constr env sigma c in
- prepare_hint true (poly,false) (Global.env()) Evd.empty (evd,c) in
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ prepare_hint true (poly,false) env sigma (evd,c) in
let fref r =
let gr = global_with_alias r in
Dumpglob.add_glob ?loc:r.CAst.loc gr;
@@ -1305,18 +1360,25 @@ let interp_hints poly =
let info = { info with hint_pattern = Option.map fp info.hint_pattern } in
(info, poly, b, path, gr)
in
+ let ft = function
+ | HintsVariables -> HintsVariables
+ | HintsConstants -> HintsConstants
+ | HintsReferences lhints -> HintsReferences (List.map fr lhints)
+ in
+ let fp = Constrintern.intern_constr_pattern (Global.env()) in
match h with
| HintsResolve lhints -> HintsResolveEntry (List.map fres lhints)
+ | HintsResolveIFF (l2r, lc, n) ->
+ HintsResolveEntry (List.map (project_hint ~poly n l2r) lc)
| HintsImmediate lhints -> HintsImmediateEntry (List.map fi lhints)
| HintsUnfold lhints -> HintsUnfoldEntry (List.map fr lhints)
- | HintsTransparency (lhints, b) ->
- HintsTransparencyEntry (List.map fr lhints, b)
+ | HintsTransparency (t, b) -> HintsTransparencyEntry (ft t, b)
| HintsMode (r, l) -> HintsModeEntry (fref r, l)
| HintsConstructors lqid ->
let constr_hints_of_ind qid =
let ind = global_inductive_with_alias qid in
let mib,_ = Global.lookup_inductive ind in
- Dumpglob.dump_reference ?loc:qid.CAst.loc "<>" (string_of_reference qid) "ind";
+ Dumpglob.dump_reference ?loc:qid.CAst.loc "<>" (string_of_qualid qid) "ind";
List.init (nconstructors ind)
(fun i -> let c = (ind,i+1) in
let gr = ConstructRef c in
@@ -1325,14 +1387,14 @@ let interp_hints poly =
PathHints [gr], IsGlobRef gr)
in HintsResolveEntry (List.flatten (List.map constr_hints_of_ind lqid))
| HintsExtern (pri, patcom, tacexp) ->
- let pat = Option.map fp patcom in
+ let pat = Option.map (fp sigma) patcom in
let l = match pat with None -> [] | Some (l, _) -> l in
let ltacvars = List.fold_left (fun accu x -> Id.Set.add x accu) Id.Set.empty l in
let env = Genintern.({ (empty_glob_sign env) with ltacvars }) in
let _, tacexp = Genintern.generic_intern env tacexp in
HintsExternEntry ({ hint_priority = Some pri; hint_pattern = pat }, tacexp)
-let add_hints local dbnames0 h =
+let add_hints ~local dbnames0 h =
if String.List.mem "nocore" dbnames0 then
user_err Pp.(str "The hint database \"nocore\" is meant to stay empty.");
let dbnames = if List.is_empty dbnames0 then ["core"] else dbnames0 in
@@ -1367,12 +1429,10 @@ let expand_constructor_hints env sigma lems =
(* builds a hint database from a constr signature *)
(* typically used with (lid, ltyp) = pf_hyps_types <some goal> *)
-let add_hint_lemmas env sigma eapply lems hint_db =
+let constructor_hints env sigma eapply lems =
let lems = expand_constructor_hints env sigma lems in
- let hintlist' =
- List.map_append (fun (poly, lem) ->
- make_resolves env sigma (eapply,true,false) empty_hint_info poly lem) lems in
- Hint_db.add_list env sigma hintlist' hint_db
+ List.map_append (fun (poly, lem) ->
+ make_resolves env sigma (eapply,true,false) empty_hint_info poly lem) lems
let make_local_hint_db env sigma ts eapply lems =
let map c = c env sigma in
@@ -1383,8 +1443,9 @@ let make_local_hint_db env sigma ts eapply lems =
| Some ts -> ts
in
let hintlist = List.map_append (make_resolve_hyp env sigma) sign in
- add_hint_lemmas env sigma eapply lems
- (Hint_db.add_list env sigma hintlist (Hint_db.empty ts false))
+ Hint_db.empty ts false
+ |> Hint_db.add_list env sigma hintlist
+ |> Hint_db.add_list env sigma (constructor_hints env sigma eapply lems)
let make_local_hint_db env sigma ?ts eapply lems =
make_local_hint_db env sigma ts eapply lems
diff --git a/tactics/hints.mli b/tactics/hints.mli
index 1811150c..9bf6c175 100644
--- a/tactics/hints.mli
+++ b/tactics/hints.mli
@@ -12,29 +12,29 @@ open Util
open Names
open EConstr
open Environ
-open Globnames
open Decl_kinds
open Evd
-open Misctypes
open Tactypes
open Clenv
open Pattern
-open Vernacexpr
+open Typeclasses
(** {6 General functions. } *)
exception Bound
-val decompose_app_bound : evar_map -> constr -> global_reference * constr array
+val decompose_app_bound : evar_map -> constr -> GlobRef.t * constr array
type debug = Debug | Info | Off
val secvars_of_hyps : ('c, 't) Context.Named.pt -> Id.Pred.t
-val empty_hint_info : 'a hint_info_gen
+val empty_hint_info : 'a Typeclasses.hint_info_gen
(** Pre-created hint databases *)
+type hint_info_expr = Constrexpr.constr_pattern_expr hint_info_gen
+
type 'a hint_ast =
| Res_pf of 'a (* Hint Apply *)
| ERes_pf of 'a (* Hint EApply *)
@@ -51,7 +51,7 @@ type 'a hints_path_atom_gen =
(* For forward hints, their names is the list of projections *)
| PathAny
-type hints_path_atom = global_reference hints_path_atom_gen
+type hints_path_atom = GlobRef.t hints_path_atom_gen
type hint_db_name = string
type 'a with_metadata = private {
@@ -72,6 +72,30 @@ type search_entry
type hint_entry
+type reference_or_constr =
+ | HintsReference of Libnames.qualid
+ | HintsConstr of Constrexpr.constr_expr
+
+type hint_mode =
+ | ModeInput (* No evars *)
+ | ModeNoHeadEvar (* No evar at the head *)
+ | ModeOutput (* Anything *)
+
+type 'a hints_transparency_target =
+ | HintsVariables
+ | HintsConstants
+ | HintsReferences of 'a list
+
+type hints_expr =
+ | HintsResolve of (hint_info_expr * bool * reference_or_constr) list
+ | HintsResolveIFF of bool * Libnames.qualid list * int option
+ | HintsImmediate of reference_or_constr list
+ | HintsUnfold of Libnames.qualid list
+ | HintsTransparency of Libnames.qualid hints_transparency_target * bool
+ | HintsMode of Libnames.qualid * hint_mode list
+ | HintsConstructors of Libnames.qualid list
+ | HintsExtern of int * Constrexpr.constr_expr option * Genarg.raw_generic_argument
+
type 'a hints_path_gen =
| PathAtom of 'a hints_path_atom_gen
| PathStar of 'a hints_path_gen
@@ -80,8 +104,8 @@ type 'a hints_path_gen =
| PathEmpty
| PathEpsilon
-type pre_hints_path = Libnames.reference hints_path_gen
-type hints_path = global_reference hints_path_gen
+type pre_hints_path = Libnames.qualid hints_path_gen
+type hints_path = GlobRef.t hints_path_gen
val normalize_path : hints_path -> hints_path
val path_matches : hints_path -> hints_path_atom list -> bool
@@ -91,15 +115,15 @@ val pp_hints_path_atom : ('a -> Pp.t) -> 'a hints_path_atom_gen -> Pp.t
val pp_hints_path : hints_path -> Pp.t
val pp_hint_mode : hint_mode -> Pp.t
val glob_hints_path_atom :
- Libnames.reference hints_path_atom_gen -> Globnames.global_reference hints_path_atom_gen
+ Libnames.qualid hints_path_atom_gen -> GlobRef.t hints_path_atom_gen
val glob_hints_path :
- Libnames.reference hints_path_gen -> Globnames.global_reference hints_path_gen
+ Libnames.qualid hints_path_gen -> GlobRef.t hints_path_gen
module Hint_db :
sig
type t
val empty : ?name:hint_db_name -> transparent_state -> bool -> t
- val find : global_reference -> t -> search_entry
+ val find : GlobRef.t -> t -> search_entry
(** All hints which have no pattern.
* [secvars] represent the set of section variables that
@@ -107,27 +131,27 @@ module Hint_db :
val map_none : secvars:Id.Pred.t -> t -> full_hint list
(** All hints associated to the reference *)
- val map_all : secvars:Id.Pred.t -> global_reference -> t -> full_hint list
+ val map_all : secvars:Id.Pred.t -> GlobRef.t -> t -> full_hint list
(** All hints associated to the reference, respecting modes if evars appear in the
arguments, _not_ using the discrimination net. *)
val map_existential : evar_map -> secvars:Id.Pred.t ->
- (global_reference * constr array) -> constr -> t -> full_hint list
+ (GlobRef.t * constr array) -> constr -> t -> full_hint list
(** All hints associated to the reference, respecting modes if evars appear in the
arguments and using the discrimination net. *)
- val map_eauto : evar_map -> secvars:Id.Pred.t -> (global_reference * constr array) -> constr -> t -> full_hint list
+ val map_eauto : evar_map -> secvars:Id.Pred.t -> (GlobRef.t * constr array) -> constr -> t -> full_hint list
(** All hints associated to the reference, respecting modes if evars appear in the
arguments. *)
val map_auto : evar_map -> secvars:Id.Pred.t ->
- (global_reference * constr array) -> constr -> t -> full_hint list
+ (GlobRef.t * constr array) -> constr -> t -> full_hint list
val add_one : env -> evar_map -> hint_entry -> t -> t
val add_list : env -> evar_map -> hint_entry list -> t -> t
- val remove_one : global_reference -> t -> t
- val remove_list : global_reference list -> t -> t
- val iter : (global_reference option ->
+ val remove_one : GlobRef.t -> t -> t
+ val remove_list : GlobRef.t list -> t -> t
+ val iter : (GlobRef.t option ->
hint_mode array list -> full_hint list -> unit) -> t -> unit
val use_dn : t -> bool
@@ -144,10 +168,8 @@ type hint_db = Hint_db.t
type hnf = bool
-type hint_info = (patvar list * constr_pattern) hint_info_gen
-
type hint_term =
- | IsGlobRef of global_reference
+ | IsGlobRef of GlobRef.t
| IsConstr of constr * Univ.ContextSet.t
type hints_entry =
@@ -156,8 +178,8 @@ type hints_entry =
| HintsImmediateEntry of (hints_path_atom * polymorphic * hint_term) list
| HintsCutEntry of hints_path
| HintsUnfoldEntry of evaluable_global_reference list
- | HintsTransparencyEntry of evaluable_global_reference list * bool
- | HintsModeEntry of global_reference * hint_mode list
+ | HintsTransparencyEntry of evaluable_global_reference hints_transparency_target * bool
+ | HintsModeEntry of GlobRef.t * hint_mode list
| HintsExternEntry of hint_info * Genarg.glob_generic_argument
val searchtable_map : hint_db_name -> hint_db
@@ -171,7 +193,7 @@ val searchtable_add : (hint_db_name * hint_db) -> unit
val create_hint_db : bool -> hint_db_name -> transparent_state -> bool -> unit
-val remove_hints : bool -> hint_db_name list -> global_reference list -> unit
+val remove_hints : bool -> hint_db_name list -> GlobRef.t list -> unit
val current_db_names : unit -> String.Set.t
@@ -179,7 +201,7 @@ val current_pure_db : unit -> hint_db list
val interp_hints : polymorphic -> hints_expr -> hints_entry
-val add_hints : locality_flag -> hint_db_name list -> hints_entry -> unit
+val add_hints : local:bool -> hint_db_name list -> hints_entry -> unit
val prepare_hint : bool (* Check no remaining evars *) ->
(bool * bool) (* polymorphic or monomorphic, local or global *) ->
@@ -264,7 +286,7 @@ val rewrite_db : hint_db_name
val pr_searchtable : env -> evar_map -> Pp.t
val pr_applicable_hint : unit -> Pp.t
-val pr_hint_ref : env -> evar_map -> global_reference -> Pp.t
+val pr_hint_ref : env -> evar_map -> GlobRef.t -> Pp.t
val pr_hint_db_by_name : env -> evar_map -> hint_db_name -> Pp.t
val pr_hint_db_env : env -> evar_map -> Hint_db.t -> Pp.t
val pr_hint_db : Hint_db.t -> Pp.t
@@ -274,3 +296,5 @@ val pr_hint : env -> evar_map -> hint -> Pp.t
(** Hook for changing the initialization of auto *)
val add_hints_init : (unit -> unit) -> unit
+type nonrec hint_info = hint_info
+[@@ocaml.deprecated "Use [Typeclasses.hint_info]"]
diff --git a/tactics/hipattern.ml b/tactics/hipattern.ml
index b012a7ec..7da059ae 100644
--- a/tactics/hipattern.ml
+++ b/tactics/hipattern.ml
@@ -12,7 +12,7 @@ open Pp
open CErrors
open Util
open Names
-open Term
+open Constr
open Termops
open EConstr
open Inductiveops
@@ -263,7 +263,9 @@ open Evar_kinds
let mkPattern c = snd (Patternops.pattern_of_glob_constr c)
let mkGApp f args = DAst.make @@ GApp (f, args)
let mkGHole = DAst.make @@
- GHole (QuestionMark (Define false,Anonymous), Misctypes.IntroAnonymous, None)
+ GHole (QuestionMark {
+ Evar_kinds.default_question_mark with Evar_kinds.qm_obligation=Define false;
+ }, Namegen.IntroAnonymous, None)
let mkGProd id c1 c2 = DAst.make @@
GProd (Name (Id.of_string id), Explicit, c1, c2)
let mkGArrow c1 c2 = DAst.make @@
@@ -294,13 +296,13 @@ let match_with_equation env sigma t =
let (hdapp,args) = destApp sigma t in
match EConstr.kind sigma hdapp with
| Ind (ind,u) ->
- if eq_gr (IndRef ind) glob_eq then
+ if GlobRef.equal (IndRef ind) glob_eq then
Some (build_coq_eq_data()),hdapp,
PolymorphicLeibnizEq(args.(0),args.(1),args.(2))
- else if eq_gr (IndRef ind) glob_identity then
+ else if GlobRef.equal (IndRef ind) glob_identity then
Some (build_coq_identity_data()),hdapp,
PolymorphicLeibnizEq(args.(0),args.(1),args.(2))
- else if eq_gr (IndRef ind) glob_jmeq then
+ else if GlobRef.equal (IndRef ind) glob_jmeq then
Some (build_coq_jmeq_data()),hdapp,
HeterogenousEq(args.(0),args.(1),args.(2),args.(3))
else
diff --git a/tactics/hipattern.mli b/tactics/hipattern.mli
index 0697d0f1..f04cda12 100644
--- a/tactics/hipattern.mli
+++ b/tactics/hipattern.mli
@@ -144,7 +144,7 @@ val is_matching_sigma : Environ.env -> evar_map -> constr -> bool
(** Match a decidable equality judgement (e.g [{t=u:>T}+{~t=u}]), returns
[t,u,T] and a boolean telling if equality is on the left side *)
-val match_eqdec : Environ.env -> evar_map -> constr -> bool * Globnames.global_reference * constr * constr * constr
+val match_eqdec : Environ.env -> evar_map -> constr -> bool * GlobRef.t * constr * constr * constr
(** Match a negation *)
val is_matching_not : Environ.env -> evar_map -> constr -> bool
diff --git a/tactics/ind_tables.ml b/tactics/ind_tables.ml
index 62ead57f..e4013152 100644
--- a/tactics/ind_tables.ml
+++ b/tactics/ind_tables.ml
@@ -53,7 +53,7 @@ let subst_one_scheme subst (ind,const) =
(subst_ind subst ind,subst_constant subst const)
let subst_scheme (subst,(kind,l)) =
- (kind,Array.map (subst_one_scheme subst) l)
+ (kind,Array.Smart.map (subst_one_scheme subst) l)
let discharge_scheme (_,(kind,l)) =
Some (kind,Array.map (fun (ind,const) ->
@@ -123,7 +123,7 @@ let define internal id c p univs =
let fd = declare_constant ~internal in
let id = compute_name internal id in
let ctx = UState.minimize univs in
- let c = Universes.subst_opt_univs_constr (UState.subst ctx) c in
+ let c = UnivSubst.nf_evars_and_universes_opt_subst (fun _ -> None) (UState.subst ctx) c in
let univs =
if p then Polymorphic_const_entry (UState.context ctx)
else Monomorphic_const_entry (UState.context_set ctx)
@@ -154,7 +154,7 @@ let define_individual_scheme_base kind suff f mode idopt (mind,i as ind) =
| None -> add_suffix mib.mind_packets.(i).mind_typename suff in
let const = define mode id c (Declareops.inductive_is_polymorphic mib) ctx in
declare_scheme kind [|ind,const|];
- const, Safe_typing.add_private
+ const, Safe_typing.concat_private
(Safe_typing.private_con_of_scheme ~kind (Global.safe_env()) [ind,const]) eff
let define_individual_scheme kind mode names (mind,i as ind) =
@@ -174,7 +174,7 @@ let define_mutual_scheme_base kind suff f mode names mind =
let schemes = Array.mapi (fun i cst -> ((mind,i),cst)) consts in
declare_scheme kind schemes;
consts,
- Safe_typing.add_private
+ Safe_typing.concat_private
(Safe_typing.private_con_of_scheme
~kind (Global.safe_env()) (Array.to_list schemes))
eff
@@ -187,7 +187,7 @@ let define_mutual_scheme kind mode names mind =
let find_scheme_on_env_too kind ind =
let s = String.Map.find kind (Indmap.find ind !scheme_map) in
- s, Safe_typing.add_private
+ s, Safe_typing.concat_private
(Safe_typing.private_con_of_scheme
~kind (Global.safe_env()) [ind, s])
Safe_typing.empty_private_constants
diff --git a/tactics/inv.ml b/tactics/inv.ml
index 067fc894..43786c8e 100644
--- a/tactics/inv.ml
+++ b/tactics/inv.ml
@@ -14,6 +14,7 @@ open Util
open Names
open Term
open Termops
+open Constr
open EConstr
open Vars
open Namegen
@@ -25,7 +26,7 @@ open Tacticals.New
open Tactics
open Elim
open Equality
-open Misctypes
+open Tactypes
open Proofview.Notations
module NamedDecl = Context.Named.Declaration
@@ -64,6 +65,11 @@ let var_occurs_in_pf gl id =
type inversion_status = Dep of constr option | NoDep
+type inversion_kind =
+ | SimpleInversion
+ | FullInversion
+ | FullInversionClear
+
let compute_eqn env sigma n i ai =
(mkRel (n-i),get_type_of env sigma (mkRel (n-i)))
@@ -88,7 +94,7 @@ let make_inv_predicate env evd indf realargs id status concl =
| Some concl -> concl (*assumed it's some [x1..xn,H:I(x1..xn)]C*)
| None ->
let sort = get_sort_family_of env !evd concl in
- let sort = Evarutil.evd_comb1 (Evd.fresh_sort_in_family env) evd sort in
+ let sort = Evarutil.evd_comb1 Evd.fresh_sort_in_family evd sort in
let p = make_arity env !evd true indf sort in
let evd',(p,ptyp) = Unification.abstract_list_all env
!evd p concl (realargs@[mkVar id])
@@ -119,12 +125,10 @@ let make_inv_predicate env evd indf realargs id status concl =
in
let eq_term = eqdata.Coqlib.eq in
let eq = Evarutil.evd_comb1 (Evd.fresh_global env) evd eq_term in
- let eq = EConstr.of_constr eq in
let eqn = applist (eq,[eqnty;lhs;rhs]) in
let eqns = (Anonymous, lift n eqn) :: eqns in
let refl_term = eqdata.Coqlib.refl in
let refl_term = Evarutil.evd_comb1 (Evd.fresh_global env) evd refl_term in
- let refl_term = EConstr.of_constr refl_term in
let refl = mkApp (refl_term, [|eqnty; rhs|]) in
let _ = Evarutil.evd_comb1 (Typing.type_of env) evd refl in
let args = refl :: args in
@@ -289,7 +293,7 @@ let error_too_many_names pats =
str "Unexpected " ++
str (String.plural (List.length pats) "introduction pattern") ++
str ": " ++ pr_enum (Miscprint.pr_intro_pattern
- (fun c -> Printer.pr_constr_env env sigma (EConstr.Unsafe.to_constr (snd (c env Evd.empty))))) pats ++
+ (fun c -> Printer.pr_econstr_env env sigma (snd (c env (Evd.from_env env))))) pats ++
str ".")
let get_names (allow_conj,issimple) ({CAst.loc;v=pat} as x) = match pat with
@@ -328,7 +332,7 @@ let rec tclMAP_i allow_conj n tacfun = function
(tacfun (get_names allow_conj a))
(tclMAP_i allow_conj (n-1) tacfun l)
-let remember_first_eq id x = if !x == MoveLast then x := MoveAfter id
+let remember_first_eq id x = if !x == Logic.MoveLast then x := Logic.MoveAfter id
(* invariant: ProjectAndApply is responsible for erasing the clause
which it is given as input
@@ -371,7 +375,7 @@ let projectAndApply as_mode thin avoid id eqname names depids =
[if as_mode then clear [id] else tclIDTAC;
(tclMAP_i (false,false) neqns (function (idopt,_) ->
tclTRY (tclTHEN
- (intro_move_avoid idopt avoid MoveLast)
+ (intro_move_avoid idopt avoid Logic.MoveLast)
(* try again to substitute and if still not a variable after *)
(* decomposition, arbitrarily try to rewrite RL !? *)
(tclTRY (onLastHypId (substHypIfVariable (fun id -> subst_hyp false id))))))
@@ -400,7 +404,7 @@ let nLastDecls i tac =
let rewrite_equations as_mode othin neqns names ba =
Proofview.Goal.enter begin fun gl ->
let (depids,nodepids) = split_dep_and_nodep ba.Tacticals.assums gl in
- let first_eq = ref MoveLast in
+ let first_eq = ref Logic.MoveLast in
let avoid = if as_mode then Id.Set.of_list (List.map NamedDecl.get_id nodepids) else Id.Set.empty in
match othin with
| Some thin ->
@@ -412,20 +416,20 @@ let rewrite_equations as_mode othin neqns names ba =
(nLastDecls neqns (fun ctx -> clear (ids_of_named_context ctx)));
tclMAP_i (true,false) neqns (fun (idopt,names) ->
(tclTHEN
- (intro_move_avoid idopt avoid MoveLast)
+ (intro_move_avoid idopt avoid Logic.MoveLast)
(onLastHypId (fun id ->
tclTRY (projectAndApply as_mode thin avoid id first_eq names depids)))))
names;
tclMAP (fun d -> tclIDTAC >>= fun () -> (* delay for [first_eq]. *)
let idopt = if as_mode then Some (NamedDecl.get_id d) else None in
- intro_move idopt (if thin then MoveLast else !first_eq))
+ intro_move idopt (if thin then Logic.MoveLast else !first_eq))
nodepids;
(tclMAP (fun d -> tclTRY (clear [NamedDecl.get_id d])) depids)]
| None ->
(* simple inversion *)
if as_mode then
tclMAP_i (false,true) neqns (fun (idopt,_) ->
- intro_move idopt MoveLast) names
+ intro_move idopt Logic.MoveLast) names
else
(tclTHENLIST
[tclDO neqns intro;
@@ -465,7 +469,7 @@ let raw_inversion inv_kind id status names =
make_inv_predicate env evdref indf realargs id status concl in
let sigma = !evdref in
let (cut_concl,case_tac) =
- if status != NoDep && (dependent sigma c concl) then
+ if status != NoDep && (local_occur_var sigma id concl) then
Reductionops.beta_applist sigma (elim_predicate, realargs@[c]),
case_then_using
else
@@ -491,11 +495,12 @@ let raw_inversion inv_kind id status names =
(* Error messages of the inversion tactics *)
let wrap_inv_error id = function (e, info) -> match e with
| Indrec.RecursionSchemeError
- (Indrec.NotAllowedCaseAnalysis (_,(Type _ | Prop Pos as k),i)) ->
+ (Indrec.NotAllowedCaseAnalysis (_,(Type _ | Set as k),i)) ->
Proofview.tclENV >>= fun env ->
+ Proofview.tclEVARMAP >>= fun sigma ->
tclZEROMSG (
(strbrk "Inversion would require case analysis on sort " ++
- pr_sort Evd.empty k ++
+ pr_sort sigma k ++
strbrk " which is not allowed for inductive definition " ++
pr_inductive env (fst i) ++ str "."))
| e -> Proofview.tclZERO ~info e
diff --git a/tactics/inv.mli b/tactics/inv.mli
index c63d57af..bbd1f335 100644
--- a/tactics/inv.mli
+++ b/tactics/inv.mli
@@ -10,11 +10,15 @@
open Names
open EConstr
-open Misctypes
open Tactypes
type inversion_status = Dep of constr option | NoDep
+type inversion_kind =
+ | SimpleInversion
+ | FullInversion
+ | FullInversionClear
+
val inv_clause :
inversion_kind -> or_and_intro_pattern option -> Id.t list ->
quantified_hypothesis -> unit Proofview.tactic
diff --git a/tactics/leminv.ml b/tactics/leminv.ml
index a4cdc159..caf4c1ec 100644
--- a/tactics/leminv.ml
+++ b/tactics/leminv.ml
@@ -12,9 +12,9 @@ open Pp
open CErrors
open Util
open Names
-open Term
open Termops
open Environ
+open Constr
open EConstr
open Vars
open Namegen
@@ -232,9 +232,8 @@ let inversion_scheme env sigma t sort dep_option inv_op =
let c = fill_holes pfterm in
(* warning: side-effect on ownSign *)
let invProof = it_mkNamedLambda_or_LetIn c !ownSign in
- let invProof = EConstr.Unsafe.to_constr invProof in
- let p = Evarutil.nf_evars_universes sigma invProof in
- p, sigma
+ let p = EConstr.to_constr sigma invProof in
+ p, sigma
let add_inversion_lemma ~poly name env sigma t sort dep inv_op =
let invProof, sigma = inversion_scheme env sigma t sort dep inv_op in
@@ -252,7 +251,7 @@ let add_inversion_lemma_exn ~poly na com comsort bool tac =
let env = Global.env () in
let sigma = Evd.from_env env in
let sigma, c = Constrintern.interp_type_evars env sigma com in
- let sigma, sort = Evd.fresh_sort_in_family ~rigid:univ_rigid env sigma comsort in
+ let sigma, sort = Evd.fresh_sort_in_family ~rigid:univ_rigid sigma comsort in
try
add_inversion_lemma ~poly na env sigma c sort bool tac
with
diff --git a/tactics/leminv.mli b/tactics/leminv.mli
index 2337a790..f42e5a8b 100644
--- a/tactics/leminv.mli
+++ b/tactics/leminv.mli
@@ -11,7 +11,7 @@
open Names
open EConstr
open Constrexpr
-open Misctypes
+open Tactypes
val lemInv_clause :
quantified_hypothesis -> constr -> Id.t list -> unit Proofview.tactic
diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml
index 958a205a..596feeec 100644
--- a/tactics/tacticals.ml
+++ b/tactics/tacticals.ml
@@ -159,8 +159,6 @@ type branch_assumptions = {
ba : branch_args; (* the branch args *)
assums : named_context} (* the list of assumptions introduced *)
-open Misctypes
-
let fix_empty_or_and_pattern nv l =
(* 1- The syntax does not distinguish between "[ ]" for one clause with no
names and "[ ]" for no clause at all *)
@@ -194,7 +192,7 @@ let check_or_and_pattern_size ?loc check_and names branchsigns =
if not (Int.equal p p1 || Int.equal p p2) then err1 p1 p2;
if Int.equal p p1 then
IntroAndPattern
- (List.extend branchsigns.(0) (CAst.make @@ IntroNaming IntroAnonymous) l)
+ (List.extend branchsigns.(0) (CAst.make @@ IntroNaming Namegen.IntroAnonymous) l)
else
names
else
@@ -225,7 +223,7 @@ let compute_induction_names_gen check_and branchletsigns = function
let compute_induction_names = compute_induction_names_gen true
(* Compute the let-in signature of case analysis or standard induction scheme *)
-let compute_constructor_signatures isrec ((_,k as ity),u) =
+let compute_constructor_signatures ~rec_flag ((_,k as ity),u) =
let rec analrec c recargs =
match Constr.kind c, recargs with
| Prod (_,_,c), recarg::rest ->
@@ -233,7 +231,7 @@ let compute_constructor_signatures isrec ((_,k as ity),u) =
begin match Declareops.dest_recarg recarg with
| Norec | Imbr _ -> true :: rest
| Mrec (_,j) ->
- if isrec && Int.equal j k then true :: true :: rest
+ if rec_flag && Int.equal j k then true :: true :: rest
else true :: rest
end
| LetIn (_,_,_,c), rest -> false :: analrec c rest
@@ -263,7 +261,7 @@ let pf_with_evars glsev k gls =
tclTHEN (Refiner.tclEVARS evd) (k a) gls
let pf_constr_of_global gr k =
- pf_with_evars (fun gls -> on_snd EConstr.of_constr (pf_apply Evd.fresh_global gls gr)) k
+ pf_with_evars (fun gls -> pf_apply Evd.fresh_global gls gr) k
(** Tacticals of Ltac defined directly in term of Proofview *)
module New = struct
@@ -369,9 +367,36 @@ module New = struct
tclTHENSFIRSTn t1 l (tclUNIT())
let tclTHENFIRST t1 t2 =
tclTHENFIRSTn t1 [|t2|]
+
+ let tclBINDFIRST t1 t2 =
+ t1 >>= fun ans ->
+ Proofview.Unsafe.tclGETGOALS >>= fun gls ->
+ match gls with
+ | [] -> tclFAIL 0 (str "Expect at least one goal.")
+ | hd::tl ->
+ Proofview.Unsafe.tclSETGOALS [hd] <*> t2 ans >>= fun ans ->
+ Proofview.Unsafe.tclNEWGOALS tl <*>
+ Proofview.tclUNIT ans
+
let tclTHENLASTn t1 l =
tclTHENS3PARTS t1 [||] (tclUNIT()) l
let tclTHENLAST t1 t2 = tclTHENLASTn t1 [|t2|]
+
+ let option_of_failure f x = try Some (f x) with Failure _ -> None
+
+ let tclBINDLAST t1 t2 =
+ t1 >>= fun ans ->
+ Proofview.Unsafe.tclGETGOALS >>= fun gls ->
+ match option_of_failure List.sep_last gls with
+ | None -> tclFAIL 0 (str "Expect at least one goal.")
+ | Some (last,firstn) ->
+ Proofview.Unsafe.tclSETGOALS [last] <*> t2 ans >>= fun ans ->
+ Proofview.Unsafe.tclGETGOALS >>= fun newgls ->
+ tclEVARMAP >>= fun sigma ->
+ let firstn = Proofview.Unsafe.undefined sigma firstn in
+ Proofview.Unsafe.tclSETGOALS (firstn@newgls) <*>
+ Proofview.tclUNIT ans
+
let tclTHENS t l =
tclINDEPENDENT begin
t <*>Proofview.tclORELSE (* converts the [SizeMismatch] error into an ltac error *)
@@ -465,11 +490,13 @@ module New = struct
Proofview.tclINDEPENDENT (Proofview.tclPROGRESS t)
(* Select a subset of the goals *)
- let tclSELECT = function
- | Vernacexpr.SelectNth i -> Proofview.tclFOCUS i i
- | Vernacexpr.SelectList l -> Proofview.tclFOCUSLIST l
- | Vernacexpr.SelectId id -> Proofview.tclFOCUSID id
- | Vernacexpr.SelectAll -> fun tac -> tac
+ let tclSELECT = let open Goal_select in function
+ | SelectNth i -> Proofview.tclFOCUS i i
+ | SelectList l -> Proofview.tclFOCUSLIST l
+ | SelectId id -> Proofview.tclFOCUSID id
+ | SelectAll -> anomaly ~label:"tclSELECT" Pp.(str "SelectAll not allowed here")
+ | SelectAlreadyFocused ->
+ anomaly ~label:"tclSELECT" Pp.(str "SelectAlreadyFocused not allowed here")
(* Check that holes in arguments have been resolved *)
@@ -479,8 +506,8 @@ module New = struct
let evi = Evd.find sigma evk in
match Evd.evar_body evi with
| Evd.Evar_empty -> Some (evk,evi)
- | Evd.Evar_defined c -> match Constr.kind c with
- | Term.Evar (evk,l) -> is_undefined_up_to_restriction sigma evk
+ | Evd.Evar_defined c -> match Constr.kind (EConstr.Unsafe.to_constr c) with
+ | Evar (evk,l) -> is_undefined_up_to_restriction sigma evk
| _ ->
(* We make the assumption that there is no way to refine an
evar remaining after typing from the initial term given to
@@ -607,7 +634,7 @@ module New = struct
(* Find the right elimination suffix corresponding to the sort of the goal *)
(* c should be of type A1->.. An->B with B an inductive definition *)
let general_elim_then_using mk_elim
- isrec allnames tac predicate ind (c, t) =
+ rec_flag allnames tac predicate ind (c, t) =
Proofview.Goal.enter begin fun gl ->
let sigma, elim = mk_elim ind gl in
let ind = on_snd (fun u -> EInstance.kind sigma u) ind in
@@ -628,15 +655,14 @@ module New = struct
| _ ->
let name_elim =
match EConstr.kind sigma elim with
- | Const (kn, _) -> Constant.to_string kn
- | Var id -> Id.to_string id
- | _ -> "\b"
+ | Const _ | Var _ -> str " " ++ Printer.pr_econstr_env (pf_env gl) sigma elim
+ | _ -> mt ()
in
user_err ~hdr:"Tacticals.general_elim_then_using"
- (str "The elimination combinator " ++ str name_elim ++ str " is unknown.")
+ (str "The elimination combinator " ++ name_elim ++ str " is unknown.")
in
let elimclause' = clenv_fchain ~with_univs:false indmv elimclause indclause in
- let branchsigns = compute_constructor_signatures isrec ind in
+ let branchsigns = compute_constructor_signatures ~rec_flag ind in
let brnames = compute_induction_names_gen false branchsigns allnames in
let flags = Unification.elim_flags () in
let elimclause' =
@@ -659,7 +685,7 @@ module New = struct
in
let branchtacs = List.init (Array.length branchsigns) after_tac in
Proofview.tclTHEN
- (Clenvtac.clenv_refine false clenv')
+ (Clenvtac.clenv_refine clenv')
(Proofview.tclEXTEND [] tclIDTAC branchtacs)
end) end
@@ -682,7 +708,7 @@ module New = struct
let gl_make_elim ind = begin fun gl ->
let gr = Indrec.lookup_eliminator (fst ind) (elimination_sort_of_goal gl) in
let (sigma, c) = pf_apply Evd.fresh_global gl gr in
- (sigma, EConstr.of_constr c)
+ (sigma, c)
end
let gl_make_case_dep (ind, u) = begin fun gl ->
@@ -726,8 +752,8 @@ module New = struct
let (ind,t) = pf_reduce_to_quantified_ind gl (pf_unsafe_type_of gl c) in
let isrec,mkelim =
match (Global.lookup_mind (fst (fst ind))).mind_record with
- | None -> true,gl_make_elim
- | Some _ -> false,gl_make_case_dep
+ | NotRecord -> true,gl_make_elim
+ | FakeRecord | PrimRecord _ -> false,gl_make_case_dep
in
general_elim_then_using mkelim isrec None tac None ind (c, t)
end
@@ -742,7 +768,6 @@ module New = struct
Proofview.tclEVARMAP >>= fun sigma ->
Proofview.tclENV >>= fun env ->
let (sigma, c) = Evd.fresh_global env sigma ref in
- let c = EConstr.of_constr c in
Proofview.Unsafe.tclEVARS sigma <*> Proofview.tclUNIT c
end
diff --git a/tactics/tacticals.mli b/tactics/tacticals.mli
index f0ebac78..1e66c2b0 100644
--- a/tactics/tacticals.mli
+++ b/tactics/tacticals.mli
@@ -14,7 +14,6 @@ open EConstr
open Evd
open Proof_type
open Locus
-open Misctypes
open Tactypes
(** Tacticals i.e. functions from tactics to tactics. *)
@@ -124,7 +123,7 @@ val fix_empty_or_and_pattern : int ->
delayed_open_constr or_and_intro_pattern_expr ->
delayed_open_constr or_and_intro_pattern_expr
-val compute_constructor_signatures : rec_flag -> inductive * 'a -> bool list array
+val compute_constructor_signatures : rec_flag:bool -> inductive * 'a -> bool list array
(** Useful for [as intro_pattern] modifier *)
val compute_induction_names :
@@ -135,7 +134,7 @@ val elimination_sort_of_hyp : Id.t -> goal sigma -> Sorts.family
val elimination_sort_of_clause : Id.t option -> goal sigma -> Sorts.family
val pf_with_evars : (goal sigma -> Evd.evar_map * 'a) -> ('a -> tactic) -> tactic
-val pf_constr_of_global : Globnames.global_reference -> (constr -> tactic) -> tactic
+val pf_constr_of_global : GlobRef.t -> (constr -> tactic) -> tactic
(** Tacticals defined directly in term of Proofview *)
@@ -196,8 +195,10 @@ module New : sig
(** [tclTHENFIRST tac1 tac2 gls] applies the tactic [tac1] to [gls]
and [tac2] to the first resulting subgoal *)
val tclTHENFIRST : unit tactic -> unit tactic -> unit tactic
+ val tclBINDFIRST : 'a tactic -> ('a -> 'b tactic) -> 'b tactic
val tclTHENLASTn : unit tactic -> unit tactic array -> unit tactic
val tclTHENLAST : unit tactic -> unit tactic -> unit tactic
+ val tclBINDLAST : 'a tactic -> ('a -> 'b tactic) -> 'b tactic
(* [tclTHENS t l = t <*> tclDISPATCH l] *)
val tclTHENS : unit tactic -> unit tactic list -> unit tactic
(* [tclTHENLIST [t1;…;tn]] is [t1<*>…<*>tn] *)
@@ -221,7 +222,7 @@ module New : sig
val tclCOMPLETE : 'a tactic -> 'a tactic
val tclSOLVE : unit tactic list -> unit tactic
val tclPROGRESS : unit tactic -> unit tactic
- val tclSELECT : Vernacexpr.goal_selector -> 'a tactic -> 'a tactic
+ val tclSELECT : Goal_select.t -> 'a tactic -> 'a tactic
val tclWITHHOLES : bool -> 'a tactic -> Evd.evar_map -> 'a tactic
val tclDELAYEDWITHHOLES : bool -> 'a delayed_open -> ('a -> unit tactic) -> unit tactic
@@ -266,5 +267,5 @@ module New : sig
val elim_on_ba : (branch_assumptions -> unit Proofview.tactic) -> branch_args -> unit Proofview.tactic
val case_on_ba : (branch_assumptions -> unit Proofview.tactic) -> branch_args -> unit Proofview.tactic
- val pf_constr_of_global : Globnames.global_reference -> constr Proofview.tactic
+ val pf_constr_of_global : GlobRef.t -> constr Proofview.tactic
end
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index dfdd3237..f060e494 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -43,7 +43,7 @@ open Pretype_errors
open Unification
open Locus
open Locusops
-open Misctypes
+open Tactypes
open Proofview.Notations
open Context.Named.Declaration
@@ -128,14 +128,14 @@ let unsafe_intro env store decl b =
(sigma, mkNamedLambda_or_LetIn decl ev)
end
-let introduction ?(check=true) id =
+let introduction id =
Proofview.Goal.enter begin fun gl ->
let concl = Proofview.Goal.concl gl in
let sigma = Tacmach.New.project gl in
let hyps = named_context_val (Proofview.Goal.env gl) in
let store = Proofview.Goal.extra gl in
let env = Proofview.Goal.env gl in
- let () = if check && mem_named_context_val id hyps then
+ let () = if mem_named_context_val id hyps then
user_err ~hdr:"Tactics.introduction"
(str "Variable " ++ Id.print id ++ str " is already declared.")
in
@@ -158,9 +158,9 @@ let convert_concl ?(check=true) ty k =
let sigma =
if check then begin
ignore (Typing.unsafe_type_of env sigma ty);
- let sigma,b = Reductionops.infer_conv env sigma ty conclty in
- if not b then error "Not convertible.";
- sigma
+ match Reductionops.infer_conv env sigma ty conclty with
+ | None -> error "Not convertible."
+ | Some sigma -> sigma
end else sigma in
let (sigma, x) = Evarutil.new_evar env sigma ~principal:true ~store ty in
let ans = if k == DEFAULTcast then x else mkCast(x,k,conclty) in
@@ -186,11 +186,10 @@ let convert_hyp_no_check = convert_hyp ~check:false
let convert_gen pb x y =
Proofview.Goal.enter begin fun gl ->
- try
- let sigma, b = Tacmach.New.pf_apply (Reductionops.infer_conv ~pb) gl x y in
- if b then Proofview.Unsafe.tclEVARS sigma
- else Tacticals.New.tclFAIL 0 (str "Not convertible")
- with (* Reduction.NotConvertible *) _ ->
+ match Tacmach.New.pf_apply (Reductionops.infer_conv ~pb) gl x y with
+ | Some sigma -> Proofview.Unsafe.tclEVARS sigma
+ | None -> Tacticals.New.tclFAIL 0 (str "Not convertible")
+ | exception _ ->
(** FIXME: Sometimes an anomaly is raised from conversion *)
Tacticals.New.tclFAIL 0 (str "Not convertible")
end
@@ -198,32 +197,46 @@ end
let convert x y = convert_gen Reduction.CONV x y
let convert_leq x y = convert_gen Reduction.CUMUL x y
-let clear_dependency_msg env sigma id = function
+let clear_in_global_msg = function
+ | None -> mt ()
+ | Some ref -> str " implicitly in " ++ Printer.pr_global ref
+
+let clear_dependency_msg env sigma id err inglobal =
+ let pp = clear_in_global_msg inglobal in
+ match err with
| Evarutil.OccurHypInSimpleClause None ->
- Id.print id ++ str " is used in conclusion."
+ Id.print id ++ str " is used" ++ pp ++ str " in conclusion."
| Evarutil.OccurHypInSimpleClause (Some id') ->
- Id.print id ++ strbrk " is used in hypothesis " ++ Id.print id' ++ str"."
+ Id.print id ++ strbrk " is used" ++ pp ++ str " in hypothesis " ++ Id.print id' ++ str"."
| Evarutil.EvarTypingBreak ev ->
str "Cannot remove " ++ Id.print id ++
strbrk " without breaking the typing of " ++
Printer.pr_existential env sigma ev ++ str"."
+ | Evarutil.NoCandidatesLeft ev ->
+ str "Cannot remove " ++ Id.print id ++ str " as it would leave the existential " ++
+ Printer.pr_existential_key sigma ev ++ str" without candidates."
-let error_clear_dependency env sigma id err =
- user_err (clear_dependency_msg env sigma id err)
+let error_clear_dependency env sigma id err inglobal =
+ user_err (clear_dependency_msg env sigma id err inglobal)
-let replacing_dependency_msg env sigma id = function
+let replacing_dependency_msg env sigma id err inglobal =
+ let pp = clear_in_global_msg inglobal in
+ match err with
| Evarutil.OccurHypInSimpleClause None ->
- str "Cannot change " ++ Id.print id ++ str ", it is used in conclusion."
+ str "Cannot change " ++ Id.print id ++ str ", it is used" ++ pp ++ str " in conclusion."
| Evarutil.OccurHypInSimpleClause (Some id') ->
str "Cannot change " ++ Id.print id ++
- strbrk ", it is used in hypothesis " ++ Id.print id' ++ str"."
+ strbrk ", it is used" ++ pp ++ str " in hypothesis " ++ Id.print id' ++ str"."
| Evarutil.EvarTypingBreak ev ->
str "Cannot change " ++ Id.print id ++
strbrk " without breaking the typing of " ++
Printer.pr_existential env sigma ev ++ str"."
+ | Evarutil.NoCandidatesLeft ev ->
+ str "Cannot change " ++ Id.print id ++ str " as it would leave the existential " ++
+ Printer.pr_existential_key sigma ev ++ str" without candidates."
-let error_replacing_dependency env sigma id err =
- user_err (replacing_dependency_msg env sigma id err)
+let error_replacing_dependency env sigma id err inglobal =
+ user_err (replacing_dependency_msg env sigma id err inglobal)
(* This tactic enables the user to remove hypotheses from the signature.
* Some care is taken to prevent him from removing variables that are
@@ -239,13 +252,12 @@ let clear_gen fail = function
let env = Proofview.Goal.env gl in
let sigma = Tacmach.New.project gl in
let concl = Proofview.Goal.concl gl in
- let evdref = ref sigma in
- let (hyps, concl) =
- try clear_hyps_in_evi env evdref (named_context_val env) concl ids
- with Evarutil.ClearDependencyError (id,err) -> fail env sigma id err
+ let (sigma, hyps, concl) =
+ try clear_hyps_in_evi env sigma (named_context_val env) concl ids
+ with Evarutil.ClearDependencyError (id,err,inglobal) -> fail env sigma id err inglobal
in
let env = reset_with_named_context hyps env in
- Proofview.tclTHEN (Proofview.Unsafe.tclEVARS !evdref)
+ Proofview.tclTHEN (Proofview.Unsafe.tclEVARS sigma)
(Refine.refine ~typecheck:false begin fun sigma ->
Evarutil.new_evar env sigma ~principal:true concl
end)
@@ -423,11 +435,10 @@ let get_previous_hyp_position env sigma id =
let clear_hyps2 env sigma ids sign t cl =
try
- let evdref = ref (Evd.clear_metas sigma) in
- let (hyps,t,cl) = Evarutil.clear_hyps2_in_evi env evdref sign t cl ids in
- (hyps, t, cl, !evdref)
- with Evarutil.ClearDependencyError (id,err) ->
- error_replacing_dependency env sigma id err
+ let sigma = Evd.clear_metas sigma in
+ Evarutil.clear_hyps2_in_evi env sigma sign t cl ids
+ with Evarutil.ClearDependencyError (id,err,inglobal) ->
+ error_replacing_dependency env sigma id err inglobal
let internal_cut_gen ?(check=true) dir replace id t =
Proofview.Goal.enter begin fun gl ->
@@ -439,7 +450,7 @@ let internal_cut_gen ?(check=true) dir replace id t =
let sign',t,concl,sigma =
if replace then
let nexthyp = get_next_hyp_position env sigma id (named_context_of_val sign) in
- let sign',t,concl,sigma = clear_hyps2 env sigma (Id.Set.singleton id) sign t concl in
+ let sigma,sign',t,concl = clear_hyps2 env sigma (Id.Set.singleton id) sign t concl in
let sign' = insert_decl_in_named_context sigma (LocalAssum (id,t)) nexthyp sign' in
sign',t,concl,sigma
else
@@ -557,20 +568,7 @@ let mutual_fix f n rest j = Proofview.Goal.enter begin fun gl ->
end
end
-let warning_nameless_fix =
- CWarnings.create ~name:"nameless-fix" ~category:"deprecated" Pp.(fun () ->
- str "fix/cofix without a name are deprecated, please use the named version.")
-
-let fix ido n = match ido with
- | None ->
- warning_nameless_fix ();
- Proofview.Goal.enter begin fun gl ->
- let name = Proof_global.get_current_proof_name () in
- let id = new_fresh_id Id.Set.empty name gl in
- mutual_fix id n [] 0
- end
- | Some id ->
- mutual_fix id n [] 0
+let fix id n = mutual_fix id n [] 0
let rec check_is_mutcoind env sigma cl =
let b = whd_all env sigma cl in
@@ -613,16 +611,7 @@ let mutual_cofix f others j = Proofview.Goal.enter begin fun gl ->
end
end
-let cofix ido = match ido with
- | None ->
- warning_nameless_fix ();
- Proofview.Goal.enter begin fun gl ->
- let name = Proof_global.get_current_proof_name () in
- let id = new_fresh_id Id.Set.empty name gl in
- mutual_cofix id [] 0
- end
- | Some id ->
- mutual_cofix id [] 0
+let cofix id = mutual_cofix id [] 0
(**************************************************************)
(* Reduction and conversion tactics *)
@@ -802,9 +791,9 @@ let e_change_in_hyp redfun (id,where) =
(convert_hyp c)
end
-type change_arg = Ltac_pretype.patvar_map -> evar_map -> evar_map * EConstr.constr
+type change_arg = Ltac_pretype.patvar_map -> env -> evar_map -> evar_map * EConstr.constr
-let make_change_arg c pats sigma = (sigma, replace_vars (Id.Map.bindings pats) c)
+let make_change_arg c pats env sigma = (sigma, replace_vars (Id.Map.bindings pats) c)
let check_types env sigma mayneedglobalcheck deep newc origc =
let t1 = Retyping.get_type_of env sigma newc in
@@ -812,15 +801,15 @@ let check_types env sigma mayneedglobalcheck deep newc origc =
let t2 = Retyping.get_type_of env sigma origc in
let sigma, t2 = Evarsolve.refresh_universes
~onlyalg:true (Some false) env sigma t2 in
- let sigma, b = infer_conv ~pb:Reduction.CUMUL env sigma t1 t2 in
- if not b then
+ match infer_conv ~pb:Reduction.CUMUL env sigma t1 t2 with
+ | None ->
if
isSort sigma (whd_all env sigma t1) &&
isSort sigma (whd_all env sigma t2)
then (mayneedglobalcheck := true; sigma)
else
user_err ~hdr:"convert-check-hyp" (str "Types are incompatible.")
- else sigma
+ | Some sigma -> sigma
end
else
if not (isSort sigma (whd_all env sigma t1)) then
@@ -829,11 +818,11 @@ let check_types env sigma mayneedglobalcheck deep newc origc =
(* Now we introduce different instances of the previous tacticals *)
let change_and_check cv_pb mayneedglobalcheck deep t env sigma c =
- let (sigma, t') = t sigma in
+ let (sigma, t') = t env sigma in
let sigma = check_types env sigma mayneedglobalcheck deep t' c in
- let sigma, b = infer_conv ~pb:cv_pb env sigma t' c in
- if not b then user_err ~hdr:"convert-check-hyp" (str "Not convertible.");
- (sigma, t')
+ match infer_conv ~pb:cv_pb env sigma t' c with
+ | None -> user_err ~hdr:"convert-check-hyp" (str "Not convertible.");
+ | Some sigma -> (sigma, t')
(* Use cumulativity only if changing the conclusion not a subterm *)
let change_on_subterm cv_pb deep t where env sigma c =
@@ -971,6 +960,11 @@ let rec intro_then_gen name_flag move_flag force_flag dep_flag tac =
| LetIn (name,b,t,u) when not dep_flag || not (noccurn sigma 1 u) ->
let name = find_name false (LocalDef (name,b,t)) name_flag gl in
build_intro_tac name move_flag tac
+ | Evar ev when force_flag ->
+ let sigma, t = Evardefine.define_evar_as_product sigma ev in
+ Tacticals.New.tclTHEN
+ (Proofview.Unsafe.tclEVARS sigma)
+ (intro_then_gen name_flag move_flag force_flag dep_flag tac)
| _ ->
begin if not force_flag then Proofview.tclZERO (RefinerError (env, sigma, IntroNeedsProduct))
(* Note: red_in_concl includes betaiotazeta and this was like *)
@@ -1108,7 +1102,13 @@ let msg_quantified_hypothesis = function
pr_nth n ++
str " non dependent hypothesis"
+let warn_deprecated_intros_until_0 =
+ CWarnings.create ~name:"deprecated-intros-until-0" ~category:"tactics"
+ (fun () ->
+ strbrk"\"intros until 0\" is deprecated, use \"intros *\"; instead of \"induction 0\" and \"destruct 0\" use explicitly a name.\"")
+
let depth_of_quantified_hypothesis red h gl =
+ if h = AnonHyp 0 then warn_deprecated_intros_until_0 ();
match lookup_hypothesis_as_renamed_gen red h gl with
| Some depth -> depth
| None ->
@@ -1159,6 +1159,18 @@ let tactic_infer_flags with_evar = {
Pretyping.fail_evar = not with_evar;
Pretyping.expand_evars = true }
+type evars_flag = bool (* true = pose evars false = fail on evars *)
+type rec_flag = bool (* true = recursive false = not recursive *)
+type advanced_flag = bool (* true = advanced false = basic *)
+type clear_flag = bool option (* true = clear hyp, false = keep hyp, None = use default *)
+
+type 'a core_destruction_arg =
+ | ElimOnConstr of 'a
+ | ElimOnIdent of lident
+ | ElimOnAnonHyp of int
+
+type 'a destruction_arg =
+ clear_flag * 'a core_destruction_arg
let onOpenInductionArg env sigma tac = function
| clear_flag,ElimOnConstr f ->
@@ -1251,7 +1263,6 @@ let cut c =
end
let error_uninstantiated_metas t clenv =
- let t = EConstr.Unsafe.to_constr t in
let na = meta_name clenv.evd (List.hd (Metaset.elements (metavars_of t))) in
let id = match na with Name id -> id | _ -> anomaly (Pp.str "unnamed dependent meta.")
in user_err (str "Cannot find an instance for " ++ Id.print id ++ str".")
@@ -1261,7 +1272,7 @@ let check_unresolved_evars_of_metas sigma clenv =
(* Refiner.pose_all_metas_as_evars are resolved *)
List.iter (fun (mv,b) -> match b with
| Clval (_,(c,_),_) ->
- (match Constr.kind c.rebus with
+ (match Constr.kind (EConstr.Unsafe.to_constr c.rebus) with
| Evar (evk,_) when Evd.is_undefined clenv.evd evk
&& not (Evd.mem sigma evk) ->
error_uninstantiated_metas (mkMeta mv) clenv
@@ -1281,7 +1292,7 @@ let do_replace id = function
let clenv_refine_in ?(sidecond_first=false) with_evars ?(with_classes=true)
targetid id sigma0 clenv tac =
- let clenv = Clenvtac.clenv_pose_dependent_evars with_evars clenv in
+ let clenv = Clenvtac.clenv_pose_dependent_evars ~with_evars clenv in
let clenv =
if with_classes then
{ clenv with evd = Typeclasses.resolve_typeclasses
@@ -1438,9 +1449,7 @@ let is_nonrec mind = (Global.lookup_mind (fst mind)).mind_finite == Declarations
let find_ind_eliminator ind s gl =
let gr = lookup_eliminator ind s in
- let evd, c = Tacmach.New.pf_apply Evd.fresh_global gl gr in
- let c = EConstr.of_constr c in
- evd, c
+ Tacmach.New.pf_apply Evd.fresh_global gl gr
let find_eliminator c gl =
let ((ind,u),t) = Tacmach.New.pf_reduce_to_quantified_ind gl (Tacmach.New.pf_unsafe_type_of gl c) in
@@ -1572,9 +1581,10 @@ let make_projection env sigma params cstr sign elim i n c u =
| Some proj ->
let args = Context.Rel.to_extended_vect mkRel 0 sign in
let proj =
- if Environ.is_projection proj env then
+ match Recordops.find_primitive_projection proj with
+ | Some proj ->
mkProj (Projection.make proj false, mkApp (c, args))
- else
+ | None ->
mkApp (mkConstU (proj,u), Array.append (Array.of_list params)
[|mkApp (c, args)|])
in
@@ -1639,13 +1649,11 @@ let tclORELSEOPT t k =
Proofview.tclZERO ~info e
| Some tac -> tac)
-let general_apply with_delta with_destruct with_evars clear_flag
- {CAst.loc;v=(c,lbind : EConstr.constr with_bindings)} =
+let general_apply ?(respect_opaque=false) with_delta with_destruct with_evars
+ clear_flag {CAst.loc;v=(c,lbind : EConstr.constr with_bindings)} =
Proofview.Goal.enter begin fun gl ->
let concl = Proofview.Goal.concl gl in
let sigma = Tacmach.New.project gl in
- let flags =
- if with_delta then default_unify_flags () else default_no_delta_unify_flags () in
(* The actual type of the theorem. It will be matched against the
goal. If this fails, then the head constant will be unfolded step by
step. *)
@@ -1654,7 +1662,12 @@ let general_apply with_delta with_destruct with_evars clear_flag
Proofview.Goal.enter begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = Tacmach.New.project gl in
-
+ let ts =
+ if respect_opaque then Conv_oracle.get_transp_state (oracle env)
+ else full_transparent_state
+ in
+ let flags =
+ if with_delta then default_unify_flags () else default_no_delta_unify_flags ts in
let thm_ty0 = nf_betaiota env sigma (Retyping.get_type_of env sigma c) in
let try_apply thm_ty nprod =
try
@@ -1720,14 +1733,14 @@ let rec apply_with_bindings_gen b e = function
(general_apply b b e k cb)
(apply_with_bindings_gen b e cbl)
-let apply_with_delayed_bindings_gen b e l =
+let apply_with_delayed_bindings_gen b e l =
let one k {CAst.loc;v=f} =
Proofview.Goal.enter begin fun gl ->
let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
let (sigma, cb) = f env sigma in
Tacticals.New.tclWITHHOLES e
- (general_apply b b e k CAst.(make ?loc cb)) sigma
+ (general_apply ~respect_opaque:(not b) b b e k CAst.(make ?loc cb)) sigma
end
in
let rec aux = function
@@ -1802,14 +1815,12 @@ let apply_in_once_main flags innerclause env sigma (loc,d,lbind) =
in
aux (make_clenv_binding env sigma (d,thm) lbind)
-let apply_in_once sidecond_first with_delta with_destruct with_evars naming
- id (clear_flag,{ CAst.loc; v= d,lbind}) tac =
+let apply_in_once ?(respect_opaque = false) sidecond_first with_delta
+ with_destruct with_evars naming id (clear_flag,{ CAst.loc; v= d,lbind}) tac =
let open Context.Rel.Declaration in
Proofview.Goal.enter begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = Tacmach.New.project gl in
- let flags =
- if with_delta then default_unify_flags () else default_no_delta_unify_flags () in
let t' = Tacmach.New.pf_get_hyp_typ id gl in
let innerclause = mk_clenv_from_env env sigma (Some 0) (mkVar id,t') in
let targetid = find_name true (LocalAssum (Anonymous,t')) naming gl in
@@ -1817,6 +1828,12 @@ let apply_in_once sidecond_first with_delta with_destruct with_evars naming
Proofview.Goal.enter begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = Tacmach.New.project gl in
+ let ts =
+ if respect_opaque then Conv_oracle.get_transp_state (oracle env)
+ else full_transparent_state
+ in
+ let flags =
+ if with_delta then default_unify_flags () else default_no_delta_unify_flags ts in
try
let clause = apply_in_once_main flags innerclause env sigma (loc,c,lbind) in
clenv_refine_in ~sidecond_first with_evars targetid id sigma clause
@@ -1836,14 +1853,14 @@ let apply_in_once sidecond_first with_delta with_destruct with_evars naming
aux [] with_destruct d
end
-let apply_in_delayed_once sidecond_first with_delta with_destruct with_evars naming
- id (clear_flag,{CAst.loc;v=f}) tac =
+let apply_in_delayed_once ?(respect_opaque = false) sidecond_first with_delta
+ with_destruct with_evars naming id (clear_flag,{CAst.loc;v=f}) tac =
Proofview.Goal.enter begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = Tacmach.New.project gl in
let (sigma, c) = f env sigma in
Tacticals.New.tclWITHHOLES with_evars
- (apply_in_once sidecond_first with_delta with_destruct with_evars
+ (apply_in_once ~respect_opaque sidecond_first with_delta with_destruct with_evars
naming id (clear_flag,CAst.(make ?loc c)) tac)
sigma
end
@@ -1911,8 +1928,8 @@ let cast_no_check cast c =
exact_no_check (mkCast (c, cast, concl))
end
-let vm_cast_no_check c = cast_no_check Term.VMcast c
-let native_cast_no_check c = cast_no_check Term.NATIVEcast c
+let vm_cast_no_check c = cast_no_check VMcast c
+let native_cast_no_check c = cast_no_check NATIVEcast c
let exact_proof c =
let open Tacmach.New in
@@ -1935,16 +1952,19 @@ let assumption =
let t = NamedDecl.get_type decl in
let concl = Proofview.Goal.concl gl in
let sigma = Tacmach.New.project gl in
- let (sigma, is_same_type) =
- if only_eq then (sigma, EConstr.eq_constr sigma t concl)
+ let ans =
+ if only_eq then
+ if EConstr.eq_constr sigma t concl then Some sigma
+ else None
else
let env = Proofview.Goal.env gl in
infer_conv env sigma t concl
in
- if is_same_type then
+ match ans with
+ | Some sigma ->
(Proofview.Unsafe.tclEVARS sigma) <*>
exact_no_check (mkVar (NamedDecl.get_id decl))
- else arec gl only_eq rest
+ | None -> arec gl only_eq rest
in
let assumption_tac gl =
let hyps = Proofview.Goal.hyps gl in
@@ -1964,24 +1984,22 @@ let on_the_bodies = function
exception DependsOnBody of Id.t option
let check_is_type env sigma ty =
- let evdref = ref sigma in
try
- let _ = Typing.e_sort_of env evdref ty in
- !evdref
+ let sigma, _ = Typing.sort_of env sigma ty in
+ sigma
with e when CErrors.noncritical e ->
raise (DependsOnBody None)
let check_decl env sigma decl =
let open Context.Named.Declaration in
let ty = NamedDecl.get_type decl in
- let evdref = ref sigma in
try
- let _ = Typing.e_sort_of env evdref ty in
- let _ = match decl with
- | LocalAssum _ -> ()
- | LocalDef (_,c,_) -> Typing.e_check env evdref c ty
+ let sigma, _ = Typing.sort_of env sigma ty in
+ let sigma = match decl with
+ | LocalAssum _ -> sigma
+ | LocalDef (_,c,_) -> Typing.check env sigma c ty
in
- !evdref
+ sigma
with e when CErrors.noncritical e ->
let id = NamedDecl.get_id decl in
raise (DependsOnBody (Some id))
@@ -2252,7 +2270,7 @@ let intro_or_and_pattern ?loc with_evars bracketed ll thin tac id =
let c = mkVar id in
let t = Tacmach.New.pf_unsafe_type_of gl c in
let (ind,t) = Tacmach.New.pf_reduce_to_quantified_ind gl t in
- let branchsigns = compute_constructor_signatures false ind in
+ let branchsigns = compute_constructor_signatures ~rec_flag:false ind in
let nv_with_let = Array.map List.length branchsigns in
let ll = fix_empty_or_and_pattern (Array.length branchsigns) ll in
let ll = get_and_check_or_and_pattern ?loc ll branchsigns in
@@ -2532,11 +2550,11 @@ let assert_as first hd ipat t =
(* apply in as *)
-let general_apply_in sidecond_first with_delta with_destruct with_evars
- id lemmas ipat =
+let general_apply_in ?(respect_opaque=false) sidecond_first with_delta
+ with_destruct with_evars id lemmas ipat =
let tac (naming,lemma) tac id =
- apply_in_delayed_once sidecond_first with_delta with_destruct with_evars
- naming id lemma tac in
+ apply_in_delayed_once ~respect_opaque sidecond_first with_delta
+ with_destruct with_evars naming id lemma tac in
Proofview.Goal.enter begin fun gl ->
let destopt =
if with_evars then MoveLast (* evars would depend on the whole context *)
@@ -2567,7 +2585,7 @@ let apply_in simple with_evars id lemmas ipat =
general_apply_in false simple simple with_evars id lemmas ipat
let apply_delayed_in simple with_evars id lemmas ipat =
- general_apply_in false simple simple with_evars id lemmas ipat
+ general_apply_in ~respect_opaque:true false simple simple with_evars id lemmas ipat
(*****************************)
(* Tactics abstracting terms *)
@@ -2605,9 +2623,7 @@ let letin_tac_gen with_eq (id,depdecls,lastlhyp,ccl,c) ty =
let eqdata = build_coq_eq_data () in
let args = if lr then [t;mkVar id;c] else [t;c;mkVar id]in
let (sigma, eq) = Evd.fresh_global env sigma eqdata.eq in
- let eq = EConstr.of_constr eq in
let (sigma, refl) = Evd.fresh_global env sigma eqdata.refl in
- let refl = EConstr.of_constr refl in
let eq = applist (eq,args) in
let refl = applist (refl, [t;mkVar id]) in
let term = mkNamedLetIn id c t (mkLetIn (Name heq, refl, eq, ccl)) in
@@ -2663,9 +2679,7 @@ let mkletin_goal env sigma store with_eq dep (id,lastlhyp,ccl,c) ty =
let eqdata = build_coq_eq_data () in
let args = if lr then [t;mkVar id;c] else [t;c;mkVar id]in
let (sigma, eq) = Evd.fresh_global env sigma eqdata.eq in
- let eq = EConstr.of_constr eq in
let (sigma, refl) = Evd.fresh_global env sigma eqdata.refl in
- let refl = EConstr.of_constr refl in
let eq = applist (eq,args) in
let refl = applist (refl, [t;mkVar id]) in
let newenv = insert_before [LocalAssum (heq,eq); decl] lastlhyp env in
@@ -3003,8 +3017,24 @@ let unfold_body x =
end
end
+let warn_cannot_remove_as_expected =
+ CWarnings.create ~name:"cannot-remove-as-expected" ~category:"tactics"
+ (fun (id,inglobal) ->
+ let pp = match inglobal with
+ | None -> mt ()
+ | Some ref -> str ", it is used implicitly in " ++ Printer.pr_global ref in
+ str "Cannot remove " ++ Id.print id ++ pp ++ str ".")
+
+let clear_for_destruct ids =
+ Proofview.tclORELSE
+ (clear_gen (fun env sigma id err inglobal -> raise (ClearDependencyError (id,err,inglobal))) ids)
+ (function
+ | ClearDependencyError (id,err,inglobal),_ -> warn_cannot_remove_as_expected (id,inglobal); Proofview.tclUNIT ()
+ | e -> iraise e)
+
(* Either unfold and clear if defined or simply clear if not a definition *)
-let expand_hyp id = Tacticals.New.tclTRY (unfold_body id) <*> clear [id]
+let expand_hyp id =
+ Tacticals.New.tclTRY (unfold_body id) <*> clear_for_destruct [id]
(*****************************)
(* High-level induction *)
@@ -3420,7 +3450,7 @@ let cook_sign hyp0_opt inhyps indvars env sigma =
type elim_scheme = {
elimc: constr with_bindings option;
elimt: types;
- indref: global_reference option;
+ indref: GlobRef.t option;
params: rel_context; (* (prm1,tprm1);(prm2,tprm2)...(prmp,tprmp) *)
nparams: int; (* number of parameters *)
predicates: rel_context; (* (Qq, (Tq_1 -> Tq_2 ->...-> Tq_nq)), (Q1,...) *)
@@ -3782,7 +3812,10 @@ let specialize_eqs id =
let ty = Tacmach.New.pf_get_hyp_typ id gl in
let evars = ref (Proofview.Goal.sigma gl) in
let unif env evars c1 c2 =
- compare_upto_variables !evars c1 c2 && Evarconv.e_conv env evars c1 c2
+ compare_upto_variables !evars c1 c2 &&
+ (match Evarconv.conv env !evars c1 c2 with
+ | Some sigma -> evars := sigma; true
+ | None -> false)
in
let rec aux in_eqs ctx acc ty =
match EConstr.kind !evars ty with
@@ -3807,7 +3840,8 @@ let specialize_eqs id =
| _ ->
if in_eqs then acc, in_eqs, ctx, ty
else
- let e = e_new_evar (push_rel_context ctx env) evars t in
+ let sigma, e = Evarutil.new_evar (push_rel_context ctx env) !evars t in
+ evars := sigma;
aux false (LocalDef (na,e,t) :: ctx) (mkApp (lift 1 acc, [| mkRel 1 |])) b)
| t -> acc, in_eqs, ctx, ty
in
@@ -4176,7 +4210,7 @@ let induction_tac with_evars params indvars elim =
let elimclause' = recolle_clenv i params indvars elimclause gl in
(* one last resolution (useless?) *)
let resolved = clenv_unique_resolver ~flags:(elim_flags ()) elimclause' gl in
- Clenvtac.clenv_refine with_evars resolved
+ Clenvtac.clenv_refine ~with_evars resolved
end
(* Apply induction "in place" taking into account dependent
@@ -4334,7 +4368,7 @@ let check_expected_type env sigma (elimc,bl) elimt =
let sigma,cl = make_evar_clause env sigma ~len:(n - 1) elimt in
let sigma = solve_evar_clause env sigma true cl bl in
let (_,u,_) = destProd sigma cl.cl_concl in
- fun t -> Evarconv.e_cumul env (ref sigma) t u
+ fun t -> Option.has_some (Evarconv.cumul env sigma t u)
let check_enough_applied env sigma elim =
(* A heuristic to decide whether the induction arg is enough applied *)
@@ -4927,9 +4961,9 @@ let cache_term_by_tactic_then ~opaque ?(goal_type=None) id gk tac tacK =
let evd, ctx, concl =
(* FIXME: should be done only if the tactic succeeds *)
- let evd, nf = nf_evars_and_universes !evdref in
+ let evd = Evd.minimize_universes !evdref in
let ctx = Evd.universe_context_set evd in
- evd, ctx, nf concl
+ evd, ctx, Evarutil.nf_evars_universes evd concl
in
let concl = EConstr.of_constr concl in
let solve_tac = tclCOMPLETE (tclTHEN (tclDO (List.length sign) intro) tac) in
@@ -4973,7 +5007,7 @@ let cache_term_by_tactic_then ~opaque ?(goal_type=None) id gk tac tacK =
let evd = Evd.set_universe_context evd ectx in
let open Safe_typing in
let eff = private_con_of_con (Global.safe_env ()) cst in
- let effs = add_private eff
+ let effs = concat_private eff
Entries.(snd (Future.force const.const_entry_body)) in
let solve =
Proofview.tclEFFECTS effs <*>
@@ -5007,6 +5041,26 @@ let tclABSTRACT ?(opaque=true) name_op tac =
else name_op_to_name name_op (DefinitionBody Definition) "_subterm" in
abstract_subproof ~opaque s gk tac
+let constr_eq ~strict x y =
+ let fail = Tacticals.New.tclFAIL 0 (str "Not equal") in
+ let fail_universes = Tacticals.New.tclFAIL 0 (str "Not equal (due to universes)") in
+ Proofview.Goal.enter begin fun gl ->
+ let env = Tacmach.New.pf_env gl in
+ let evd = Tacmach.New.project gl in
+ match EConstr.eq_constr_universes env evd x y with
+ | Some csts ->
+ let csts = UnivProblem.to_constraints ~force_weak:false (Evd.universes evd) csts in
+ if strict then
+ if Evd.check_constraints evd csts then Proofview.tclUNIT ()
+ else fail_universes
+ else
+ (match Evd.add_constraints evd csts with
+ | evd -> Proofview.Unsafe.tclEVARS evd
+ | exception Univ.UniverseInconsistency _ ->
+ fail_universes)
+ | None -> fail
+ end
+
let unify ?(state=full_transparent_state) x y =
Proofview.Goal.enter begin fun gl ->
let env = Proofview.Goal.env gl in
diff --git a/tactics/tactics.mli b/tactics/tactics.mli
index 079baa3e..34b49f3b 100644
--- a/tactics/tactics.mli
+++ b/tactics/tactics.mli
@@ -16,10 +16,8 @@ open Proof_type
open Evd
open Clenv
open Redexpr
-open Globnames
open Pattern
open Unification
-open Misctypes
open Tactypes
open Locus
open Ltac_pretype
@@ -35,16 +33,16 @@ val is_quantified_hypothesis : Id.t -> Proofview.Goal.t -> bool
(** {6 Primitive tactics. } *)
-val introduction : ?check:bool -> Id.t -> unit Proofview.tactic
+val introduction : Id.t -> unit Proofview.tactic
val convert_concl : ?check:bool -> types -> cast_kind -> unit Proofview.tactic
val convert_hyp : ?check:bool -> named_declaration -> unit Proofview.tactic
val convert_concl_no_check : types -> cast_kind -> unit Proofview.tactic
val convert_hyp_no_check : named_declaration -> unit Proofview.tactic
val mutual_fix :
Id.t -> int -> (Id.t * int * constr) list -> int -> unit Proofview.tactic
-val fix : Id.t option -> int -> unit Proofview.tactic
+val fix : Id.t -> int -> unit Proofview.tactic
val mutual_cofix : Id.t -> (Id.t * constr) list -> int -> unit Proofview.tactic
-val cofix : Id.t option -> unit Proofview.tactic
+val cofix : Id.t -> unit Proofview.tactic
val convert : constr -> constr -> unit Proofview.tactic
val convert_leq : constr -> constr -> unit Proofview.tactic
@@ -57,8 +55,8 @@ val find_intro_names : rel_context -> goal sigma -> Id.t list
val intro : unit Proofview.tactic
val introf : unit Proofview.tactic
-val intro_move : Id.t option -> Id.t move_location -> unit Proofview.tactic
-val intro_move_avoid : Id.t option -> Id.Set.t -> Id.t move_location -> unit Proofview.tactic
+val intro_move : Id.t option -> Id.t Logic.move_location -> unit Proofview.tactic
+val intro_move_avoid : Id.t option -> Id.Set.t -> Id.t Logic.move_location -> unit Proofview.tactic
(** [intro_avoiding idl] acts as intro but prevents the new Id.t
to belong to [idl] *)
@@ -92,9 +90,22 @@ val intros_clearing : bool list -> unit Proofview.tactic
val try_intros_until :
(Id.t -> unit Proofview.tactic) -> quantified_hypothesis -> unit Proofview.tactic
+type evars_flag = bool (* true = pose evars false = fail on evars *)
+type rec_flag = bool (* true = recursive false = not recursive *)
+type advanced_flag = bool (* true = advanced false = basic *)
+type clear_flag = bool option (* true = clear hyp, false = keep hyp, None = use default *)
+
(** Apply a tactic on a quantified hypothesis, an hypothesis in context
or a term with bindings *)
+type 'a core_destruction_arg =
+ | ElimOnConstr of 'a
+ | ElimOnIdent of lident
+ | ElimOnAnonHyp of int
+
+type 'a destruction_arg =
+ clear_flag * 'a core_destruction_arg
+
val onInductionArg :
(clear_flag -> constr with_bindings -> unit Proofview.tactic) ->
constr with_bindings destruction_arg -> unit Proofview.tactic
@@ -110,11 +121,11 @@ val use_clear_hyp_by_default : unit -> bool
(** {6 Introduction tactics with eliminations. } *)
val intro_patterns : evars_flag -> intro_patterns -> unit Proofview.tactic
-val intro_patterns_to : evars_flag -> Id.t move_location -> intro_patterns ->
+val intro_patterns_to : evars_flag -> Id.t Logic.move_location -> intro_patterns ->
unit Proofview.tactic
-val intro_patterns_bound_to : evars_flag -> int -> Id.t move_location -> intro_patterns ->
+val intro_patterns_bound_to : evars_flag -> int -> Id.t Logic.move_location -> intro_patterns ->
unit Proofview.tactic
-val intro_pattern_to : evars_flag -> Id.t move_location -> delayed_open_constr intro_pattern_expr ->
+val intro_pattern_to : evars_flag -> Id.t Logic.move_location -> delayed_open_constr intro_pattern_expr ->
unit Proofview.tactic
(** Implements user-level "intros", with [] standing for "**" *)
@@ -134,7 +145,7 @@ val exact_proof : Constrexpr.constr_expr -> unit Proofview.tactic
type tactic_reduction = Reductionops.reduction_function
type e_tactic_reduction = Reductionops.e_reduction_function
-type change_arg = patvar_map -> evar_map -> evar_map * constr
+type change_arg = patvar_map -> env -> evar_map -> evar_map * constr
val make_change_arg : constr -> change_arg
val reduct_in_hyp : ?check:bool -> tactic_reduction -> hyp_location -> unit Proofview.tactic
@@ -169,7 +180,7 @@ val change :
val pattern_option :
(occurrences * constr) list -> goal_location -> unit Proofview.tactic
val reduce : red_expr -> clause -> unit Proofview.tactic
-val unfold_constr : global_reference -> unit Proofview.tactic
+val unfold_constr : GlobRef.t -> unit Proofview.tactic
(** {6 Modification of the local context. } *)
@@ -181,7 +192,7 @@ val apply_clear_request : clear_flag -> bool -> constr -> unit Proofview.tactic
val specialize : constr with_bindings -> intro_pattern option -> unit Proofview.tactic
-val move_hyp : Id.t -> Id.t move_location -> unit Proofview.tactic
+val move_hyp : Id.t -> Id.t Logic.move_location -> unit Proofview.tactic
val rename_hyp : (Id.t * Id.t) list -> unit Proofview.tactic
val revert : Id.t list -> unit Proofview.tactic
@@ -245,7 +256,7 @@ val apply_delayed_in :
type elim_scheme = {
elimc: constr with_bindings option;
elimt: types;
- indref: global_reference option;
+ indref: GlobRef.t option;
params: rel_context; (** (prm1,tprm1);(prm2,tprm2)...(prmp,tprmp) *)
nparams: int; (** number of parameters *)
predicates: rel_context; (** (Qq, (Tq_1 -> Tq_2 ->...-> Tq_nq)), (Q1,...) *)
@@ -398,6 +409,11 @@ val generalize_dep : ?with_let:bool (** Don't lose let bindings *) -> constr -
(** {6 Other tactics. } *)
+(** Syntactic equality up to universes. With [strict] the universe
+ constraints must be already true to succeed, without [strict] they
+ are added to the evar map. *)
+val constr_eq : strict:bool -> constr -> constr -> unit Proofview.tactic
+
val unify : ?state:Names.transparent_state -> constr -> constr -> unit Proofview.tactic
val cache_term_by_tactic_then : opaque:bool -> ?goal_type:(constr option) -> Id.t -> Decl_kinds.goal_kind -> unit Proofview.tactic -> (constr -> constr list -> unit Proofview.tactic) -> unit Proofview.tactic
diff --git a/tactics/term_dnet.ml b/tactics/term_dnet.ml
index 753c608a..8bdcc632 100644
--- a/tactics/term_dnet.ml
+++ b/tactics/term_dnet.ml
@@ -37,7 +37,7 @@ struct
type 't t =
| DRel
| DSort
- | DRef of global_reference
+ | DRef of GlobRef.t
| DCtx of 't * 't (* (binding list, subterm) = Prods and LetIns *)
| DLambda of 't * 't
| DApp of 't * 't (* binary app *)
@@ -290,7 +290,7 @@ struct
| Const (c,u) -> Term (DRef (ConstRef c))
| Ind (i,u) -> Term (DRef (IndRef i))
| Construct (c,u)-> Term (DRef (ConstructRef c))
- | Term.Meta _ -> assert false
+ | Meta _ -> assert false
| Evar (i,_) ->
let meta =
try Evar.Map.find i !metas
diff --git a/tactics/term_dnet.mli b/tactics/term_dnet.mli
index 2c748f9c..7bce5778 100644
--- a/tactics/term_dnet.mli
+++ b/tactics/term_dnet.mli
@@ -26,7 +26,7 @@ open Mod_subst
The results returned here are perfect, since post-filtering is done
inside here.
- See lib/dnet.mli for more details.
+ See tactics/dnet.mli for more details.
*)
(** Identifiers to store (right hand side of the association) *)
diff --git a/test-suite/Makefile b/test-suite/Makefile
index 85076418..598d6db2 100644
--- a/test-suite/Makefile
+++ b/test-suite/Makefile
@@ -8,9 +8,6 @@
## # (see LICENSE file for the text of the license) ##
##########################################################################
-# This is a standalone Makefile to run the test-suite. It can be used
-# outside of the Coq source tree (if BIN is overridden).
-
# There is one %.v.log target per %.v test file. The target will be
# filled with the output, timings and status of the test. There is
# also one target per directory containing %.v files, that runs all
@@ -23,6 +20,14 @@
# The "run" target runs all tests that have not been run yet. To force
# all tests to be run, use the "clean" target.
+
+###########################################################################
+# Includes
+###########################################################################
+
+-include ../config/Makefile
+include ../Makefile.common
+
#######################################################################
# Variables
#######################################################################
@@ -79,6 +84,8 @@ log_anomaly = "==========> FAILURE <=========="
log_failure = "==========> FAILURE <=========="
log_intro = "==========> TESTING $(1) <=========="
+FAIL = >&2 echo 'FAILED $@'
+
#######################################################################
# Testing subsystems
#######################################################################
@@ -92,10 +99,10 @@ INTERACTIVE := interactive
VSUBSYSTEMS := prerequisite success failure $(BUGS) output \
output-modulo-time $(INTERACTIVE) micromega $(COMPLEXITY) modules stm \
- coqdoc
+ coqdoc ssr
# All subsystems
-SUBSYSTEMS := $(VSUBSYSTEMS) misc bugs ide vio coqchk coqwc coq-makefile
+SUBSYSTEMS := $(VSUBSYSTEMS) misc bugs ide vio coqchk coqwc coq-makefile tools unit-tests
PREREQUISITELOG = prerequisite/admit.v.log \
prerequisite/make_local.v.log prerequisite/make_notation.v.log \
@@ -116,25 +123,27 @@ run: $(SUBSYSTEMS)
bugs: $(BUGS)
clean:
- rm -f trace .lia.cache
- $(SHOW) "RM <**/*.stamp> <**/*.vo> <**/*.vio> <**/*.log>"
+ rm -f trace .lia.cache output/MExtraction.out
+ $(SHOW) 'RM <**/*.stamp> <**/*.vo> <**/*.vio> <**/*.log> <**/*.glob>'
$(HIDE)find . \( \
- -name '*.stamp' -o -name '*.vo' -o -name '*.vio' -o -name '*.log' \
- \) -print0 | xargs -0 rm -f
-
+ -name '*.stamp' -o -name '*.vo' -o -name '*.vio' -o -name '*.log' -o -name '*.glob' \
+ \) -print0 | xargs -0 rm -f
+ $(SHOW) 'RM <**/*.cmx> <**/*.cmi> <**/*.o> <**/*.test>'
+ $(HIDE)find unit-tests \( \
+ -name '*.cmx' -o -name '*.cmi' -o -name '*.o' -o -name '*.test' \
+ \) -print0 | xargs -0 rm -f
distclean: clean
- $(HIDE)find . -name '*.log' -print0 | xargs -0 rm -f
+ $(SHOW) 'RM <**/*.aux>'
+ $(HIDE)find . -name '*.aux' -print0 | xargs -0 rm -f
#######################################################################
# Per-subsystem targets
#######################################################################
-define mkstamp
-$(1): $(1).stamp ; @true
-$(1).stamp: $(patsubst %.v,%.v.log,$(wildcard $(1)/*.v)) ; \
- $(HIDE)touch $$@
+define vdeps
+$(1): $(patsubst %.v,%.v.log,$(wildcard $(1)/*.v))
endef
-$(foreach S,$(VSUBSYSTEMS),$(eval $(call mkstamp,$(S))))
+$(foreach S,$(VSUBSYSTEMS),$(eval $(call vdeps,$(S))))
#######################################################################
# Summary
@@ -158,18 +167,21 @@ summary:
$(call summary_dir, "Complexity tests", complexity); \
$(call summary_dir, "Module tests", modules); \
$(call summary_dir, "STM tests", stm); \
+ $(call summary_dir, "SSR tests", ssr); \
$(call summary_dir, "IDE tests", ide); \
$(call summary_dir, "VI tests", vio); \
$(call summary_dir, "Coqchk tests", coqchk); \
$(call summary_dir, "Coqwc tests", coqwc); \
$(call summary_dir, "Coq makefile", coq-makefile); \
$(call summary_dir, "Coqdoc tests", coqdoc); \
+ $(call summary_dir, "tools/ tests", tools); \
+ $(call summary_dir, "Unit tests", unit-tests); \
nb_success=`find . -name '*.log' -exec tail -n2 '{}' \; | grep -e $(log_success) | wc -l`; \
nb_failure=`find . -name '*.log' -exec tail -n2 '{}' \; | grep -e $(log_failure) | wc -l`; \
nb_tests=`expr $$nb_success + $$nb_failure`; \
- pourcentage=`expr 100 \* $$nb_success / $$nb_tests`; \
+ percentage=`expr 100 \* $$nb_success / $$nb_tests`; \
echo; \
- echo "$$nb_success tests passed over $$nb_tests, i.e. $$pourcentage %"; \
+ echo "$$nb_success tests passed over $$nb_tests, i.e. $$percentage %"; \
}
summary.log:
@@ -185,10 +197,7 @@ PRINT_LOGS:=APPVEYOR
endif #APPVEYOR
report: summary.log
- $(HIDE)bash save-logs.sh
- $(HIDE)if [ -n "${TRAVIS}" ]; then find logs/ -name '*.log' -not -name 'summary.log' -exec 'bash' '-c' 'echo "travis_fold:start:coq.logs.$$(echo '{}' | sed s,/,.,g)"' ';' -exec cat '{}' ';' -exec 'bash' '-c' 'echo "travis_fold:end:coq.logs.$$(echo '{}' | sed s,/,.,g)"' ';'; fi
- $(HIDE)if [ -n "${PRINT_LOGS}" ]; then find logs/ -name '*.log' -not -name 'summary.log' -exec 'bash' '-c' 'echo {}' ';' -exec cat '{}' ';' -exec 'bash' '-c' 'echo' ';'; fi
- $(HIDE)if grep -q -F 'Error!' summary.log ; then echo FAILURES; grep -F 'Error!' summary.log; false; else echo NO FAILURES; fi
+ $(HIDE)bash report.sh
#######################################################################
# Regression (and progression) tests
@@ -218,6 +227,7 @@ $(addsuffix .log,$(wildcard bugs/opened/*.v)): %.v.log: %.v
else \
echo $(log_failure); \
echo " $<...Error! (bug seems to be closed, please check)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -233,10 +243,49 @@ $(addsuffix .log,$(wildcard bugs/closed/*.v)): %.v.log: %.v
else \
echo $(log_failure); \
echo " $<...Error! (bug seems to be opened, please check)"; \
+ $(FAIL); \
fi; \
} > "$@"
#######################################################################
+# Unit tests
+#######################################################################
+
+OCAMLOPT := $(OCAMLFIND) opt $(CAMLFLAGS)
+SYSMOD:=-package num,str,unix,dynlink,threads
+
+COQSRCDIRS:=$(addprefix -I $(LIB)/,$(CORESRCDIRS))
+COQCMXS:=$(addprefix $(LIB)/,$(LINKCMX))
+
+# ML files from unit-test framework, not containing tests
+UNIT_SRCFILES:=$(shell find ./unit-tests/src -name *.ml)
+UNIT_ALLMLFILES:=$(shell find ./unit-tests -name *.ml)
+UNIT_MLFILES:=$(filter-out $(UNIT_SRCFILES),$(UNIT_ALLMLFILES))
+UNIT_LOGFILES:=$(patsubst %.ml,%.ml.log,$(UNIT_MLFILES))
+
+UNIT_CMXS=utest.cmx
+
+unit-tests/src/utest.cmx: unit-tests/src/utest.ml unit-tests/src/utest.cmi
+ $(SHOW) 'OCAMLOPT $<'
+ $(HIDE)$(OCAMLOPT) -c -I unit-tests/src -package oUnit $<
+unit-tests/src/utest.cmi: unit-tests/src/utest.mli
+ $(SHOW) 'OCAMLOPT $<'
+ $(HIDE)$(OCAMLOPT) -package oUnit $<
+
+$(UNIT_LOGFILES): unit-tests/src/utest.cmx
+
+unit-tests: $(UNIT_LOGFILES)
+
+# Build executable, run it to generate log file
+unit-tests/%.ml.log: unit-tests/%.ml
+ $(SHOW) 'TEST $<'
+ $(HIDE)$(OCAMLOPT) -linkall -linkpkg -cclib -lcoqrun \
+ $(SYSMOD) -package camlp5.gramlib,oUnit \
+ -I unit-tests/src $(COQSRCDIRS) $(COQCMXS) \
+ $(UNIT_CMXS) $< -o $<.test;
+ $(HIDE)./$<.test
+
+#######################################################################
# Other generic tests
#######################################################################
@@ -248,13 +297,15 @@ $(addsuffix .log,$(wildcard prerequisite/*.v)): %.v.log: %.v
if [ $$R != 0 ]; then \
echo $(log_failure); \
echo " $<...could not be prepared" ; \
+ $(FAIL); \
else \
echo $(log_success); \
echo " $<...correctly prepared" ; \
fi; \
} > "$@"
-$(addsuffix .log,$(wildcard success/*.v micromega/*.v modules/*.v)): %.v.log: %.v $(PREREQUISITELOG)
+ssr: $(wildcard ssr/*.v:%.v=%.v.log)
+$(addsuffix .log,$(wildcard ssr/*.v success/*.v micromega/*.v modules/*.v)): %.v.log: %.v $(PREREQUISITELOG)
@echo "TEST $< $(call get_coq_prog_args_in_parens,"$<")"
$(HIDE){ \
opts="$(if $(findstring modules/,$<),-R modules Mods -impredicative-set)"; \
@@ -266,6 +317,7 @@ $(addsuffix .log,$(wildcard success/*.v micromega/*.v modules/*.v)): %.v.log: %.
else \
echo $(log_failure); \
echo " $<...Error! (should be accepted)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -282,6 +334,7 @@ $(addsuffix .log,$(wildcard stm/*.v)): %.v.log: %.v
else \
echo $(log_failure); \
echo " $<...Error! (should be accepted)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -296,6 +349,7 @@ $(addsuffix .log,$(wildcard failure/*.v)): %.v.log: %.v $(PREREQUISITELOG)
else \
echo $(log_failure); \
echo " $<...Error! (should be rejected)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -303,25 +357,33 @@ $(addsuffix .log,$(wildcard output/*.v)): %.v.log: %.v %.out $(PREREQUISITELOG)
@echo "TEST $< $(call get_coq_prog_args_in_parens,"$<")"
$(HIDE){ \
echo $(call log_intro,$<); \
- tmpoutput=`mktemp /tmp/coqcheck.XXXXXX`; \
+ output=$*.out.real; \
$(call get_command_based_on_flags,"$<") "$<" $(call get_coq_prog_args,"$<") 2>&1 \
| grep -v "Welcome to Coq" \
| grep -v "\[Loading ML file" \
| grep -v "Skipping rcfile loading" \
| grep -v "^<W>" \
| sed 's/File "[^"]*"/File "stdin"/' \
- > $$tmpoutput; \
- diff -u --strip-trailing-cr $*.out $$tmpoutput 2>&1; R=$$?; times; \
+ > $$output; \
+ diff -u --strip-trailing-cr $*.out $$output 2>&1; R=$$?; times; \
if [ $$R = 0 ]; then \
echo $(log_success); \
echo " $<...Ok"; \
+ rm $$output; \
else \
echo $(log_failure); \
echo " $<...Error! (unexpected output)"; \
+ $(FAIL); \
fi; \
- rm $$tmpoutput; \
} > "$@"
+.PHONY: approve-output
+approve-output: output
+ $(HIDE)for f in output/*.out.real; do \
+ mv "$$f" "$${f%.real}"; \
+ echo "Updated $${f%.real}!"; \
+ done
+
# the expected output for the MExtraction test is
# /plugins/micromega/micromega.ml except with additional newline
output/MExtraction.out: ../plugins/micromega/micromega.ml
@@ -360,6 +422,7 @@ $(addsuffix .log,$(wildcard output-modulo-time/*.v)): %.v.log: %.v %.out
else \
echo $(log_failure); \
echo " $<...Error! (unexpected output)"; \
+ $(FAIL); \
fi; \
rm $$tmpoutput; \
rm $$tmpexpected; \
@@ -376,6 +439,7 @@ $(addsuffix .log,$(wildcard interactive/*.v)): %.v.log: %.v $(PREREQUISITELOG)
else \
echo $(log_failure); \
echo " $<...Error! (should be accepted)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -408,6 +472,7 @@ $(addsuffix .log,$(wildcard complexity/*.v)): %.v.log: %.v $(PREREQUISITELOG)
else \
echo $(log_failure); \
echo " $<...Error! (should run faster)"; \
+ $(FAIL); \
fi; \
fi; \
} > "$@"
@@ -425,6 +490,7 @@ $(addsuffix .log,$(wildcard ideal-features/*.v)): %.v.log: %.v $(PREREQUISITELOG
else \
echo $(log_failure); \
echo " $<...Good news! (wish seems to be granted, please check)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -448,6 +514,7 @@ $(patsubst %.sh,%.log,$(wildcard misc/*.sh)): %.log: %.sh $(PREREQUISITELOG)
@echo "TEST $<"
$(HIDE){ \
echo $(call log_intro,$<); \
+ export BIN="$(BIN)"; \
export coqc="$(coqc)"; \
export coqtop="$(coqtop)"; \
export coqdep="$(coqdep)"; \
@@ -459,6 +526,7 @@ $(patsubst %.sh,%.log,$(wildcard misc/*.sh)): %.log: %.sh $(PREREQUISITELOG)
else \
echo $(log_failure); \
echo " $<...Error!"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -477,6 +545,7 @@ ide : $(patsubst %.fake,%.fake.log,$(wildcard ide/*.fake))
else \
echo $(log_failure); \
echo " $<...Error!"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -496,6 +565,7 @@ vio: $(patsubst %.v,%.vio.log,$(wildcard vio/*.v))
else \
echo $(log_failure); \
echo " $<...Error!"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -514,6 +584,7 @@ coqchk: $(patsubst %.v,%.chk.log,$(wildcard coqchk/*.v))
else \
echo $(log_failure); \
echo " $<...Error!"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -533,6 +604,7 @@ coqwc/%.v.log : coqwc/%.v
else \
echo $(log_failure); \
echo " $<...Error! (unexpected output)"; \
+ $(FAIL); \
fi; \
rm $$tmpoutput; \
} > "$@"
@@ -553,6 +625,7 @@ coq-makefile/%.log : coq-makefile/%/run.sh
else \
echo $(log_failure); \
echo " $<...Error!"; \
+ $(FAIL); \
fi; \
) > "$@"
@@ -577,5 +650,26 @@ $(addsuffix .log,$(wildcard coqdoc/*.v)): %.v.log: %.v %.html.out %.tex.out $(PR
else \
echo $(log_failure); \
echo " $<...Error! (unexpected output)"; \
+ $(FAIL); \
fi; \
} > "$@"
+
+# tools/
+
+tools: $(patsubst %/run.sh,%.log,$(wildcard tools/*/run.sh))
+
+tools/%.log : tools/%/run.sh
+ @echo "TEST tools/$*"
+ $(HIDE)(\
+ export COQBIN=$(BIN);\
+ cd tools/$* && \
+ bash run.sh 2>&1; \
+ if [ $$? = 0 ]; then \
+ echo $(log_success); \
+ echo " $<...Ok"; \
+ else \
+ echo $(log_failure); \
+ echo " $<...Error!"; \
+ $(FAIL); \
+ fi; \
+ ) > "$@"
diff --git a/test-suite/README.md b/test-suite/README.md
index 1d119564..e81da083 100644
--- a/test-suite/README.md
+++ b/test-suite/README.md
@@ -62,14 +62,37 @@ BUILDING SUMMARY FILE
NO FAILURES
```
-See [`test-suite/Makefile`](/test-suite/Makefile) for more information.
+See [`test-suite/Makefile`](Makefile) for more information.
## Adding a test
-Regression tests for closed bugs should be added to `test-suite/bugs/closed`, as `1234.v` where `1234` is the bug number.
+Regression tests for closed bugs should be added to
+[`bugs/closed`](bugs/closed), as `1234.v` where `1234` is the bug number.
Files in this directory are tested for successful compilation.
When you fix a bug, you should usually add a regression test here as well.
-The error "(bug seems to be opened, please check)" when running `make test-suite` means that a test in `bugs/closed` failed to compile.
+The error "(bug seems to be opened, please check)" when running
+`make test-suite` means that a test in [`bugs/closed`](bugs/closed) failed to
+compile.
-There are also output tests in `test-suite/output` which consist of a `.v` file and a `.out` file with the expected output.
+There are also output tests in [`output`](output) which consist of a `.v` file
+and a `.out` file with the expected output.
+
+There are unit tests of OCaml code in [`unit-tests`](unit-tests). These tests
+are contained in `.ml` files, and rely on the `OUnit` unit-test framework, as
+described at <http://ounit.forge.ocamlcore.org/>. Use `make unit-tests` in the
+[`unit-tests`](unit-tests) directory to run them.
+
+## Fixing output tests
+
+When an output test `output/foo.v` fails, the output is stored in
+`output/foo.out.real`. Move that file to the reference file
+`output/foo.out` to update the test, approving the new output. Target
+`approve-output` will do this for all failing output tests
+automatically.
+
+Don't forget to check the updated `.out` files into git!
+
+Note that `output/MExtraction.out` is special: it is copied from
+[`micromega/micromega.ml`](../plugins/micromega/micromega.ml) in the plugin
+source directory. Automatic approval will incorrectly update the copy.
diff --git a/test-suite/bugs/closed/1341.v b/test-suite/bugs/closed/1341.v
index 8c5a3885..79a0a14d 100644
--- a/test-suite/bugs/closed/1341.v
+++ b/test-suite/bugs/closed/1341.v
@@ -8,7 +8,7 @@ Hypothesis Xst : forall A, Equivalence (Xeq A).
Variable map : forall A B, (A -> B) -> X A -> X B.
-Implicit Arguments map [A B].
+Arguments map [A B].
Goal forall A B (a b:X (B -> A)) (c:X A) (f:A -> B -> A), Xeq _ a b -> Xeq _ b (map f c) -> Xeq _ a (map f c).
intros A B a b c f Hab Hbc.
diff --git a/test-suite/bugs/closed/1844.v b/test-suite/bugs/closed/1844.v
index 17eeb352..c41e4590 100644
--- a/test-suite/bugs/closed/1844.v
+++ b/test-suite/bugs/closed/1844.v
@@ -5,7 +5,7 @@ Definition zeq := Z.eq_dec.
Definition update (A: Set) (x: Z) (v: A) (s: Z -> A) : Z -> A :=
fun y => if zeq x y then v else s y.
-Implicit Arguments update [A].
+Arguments update [A].
Definition ident := Z.
Parameter operator: Set.
diff --git a/test-suite/bugs/closed/1891.v b/test-suite/bugs/closed/1891.v
index 68581117..5024a5bc 100644
--- a/test-suite/bugs/closed/1891.v
+++ b/test-suite/bugs/closed/1891.v
@@ -3,7 +3,7 @@
Definition f (A: Set) (l: T A): unit := tt.
- Implicit Arguments f [A].
+ Arguments f [A].
Lemma L (x: T unit): (unit -> T unit) -> unit.
Proof.
diff --git a/test-suite/bugs/closed/1951.v b/test-suite/bugs/closed/1951.v
index 7558b0b8..e950554c 100644
--- a/test-suite/bugs/closed/1951.v
+++ b/test-suite/bugs/closed/1951.v
@@ -42,7 +42,7 @@ match s as a return (S a) with
pair (ind2 a0) IHl) l)
end. (* some induction principle *)
-Implicit Arguments ind [S].
+Arguments ind [S].
Lemma k : a -> Type. (* some ininteresting lemma *)
intro;pattern H;apply ind;intros.
diff --git a/test-suite/bugs/closed/1981.v b/test-suite/bugs/closed/1981.v
index 99952682..a3d94293 100644
--- a/test-suite/bugs/closed/1981.v
+++ b/test-suite/bugs/closed/1981.v
@@ -1,4 +1,4 @@
-Implicit Arguments ex_intro [A].
+Arguments ex_intro [A].
Goal exists n : nat, True.
eapply ex_intro. exact 0. exact I.
diff --git a/test-suite/bugs/closed/2362.v b/test-suite/bugs/closed/2362.v
index febb9c7b..10e86cd1 100644
--- a/test-suite/bugs/closed/2362.v
+++ b/test-suite/bugs/closed/2362.v
@@ -8,7 +8,7 @@ Class Pointed (M:Type -> Type) :=
Unset Implicit Arguments.
Inductive FPair (A B:Type) (neutral: B) : Type:=
fpair : forall (a:A) (b:B), FPair A B neutral.
-Implicit Arguments fpair [[A] [B] [neutral]].
+Arguments fpair {A B neutral}.
Set Implicit Arguments.
diff --git a/test-suite/bugs/closed/2378.v b/test-suite/bugs/closed/2378.v
index 23a58501..b9dd6540 100644
--- a/test-suite/bugs/closed/2378.v
+++ b/test-suite/bugs/closed/2378.v
@@ -63,7 +63,7 @@ Fixpoint lpSat st f: Prop :=
end.
End PropLogic.
-Implicit Arguments lpSat.
+Arguments lpSat : default implicits.
Fixpoint LPTransfo Pred1 Pred2 p2lp (f: LP Pred1): LP Pred2 :=
match f with
@@ -71,9 +71,9 @@ Fixpoint LPTransfo Pred1 Pred2 p2lp (f: LP Pred1): LP Pred2 :=
| LPAnd _ f1 f2 => LPAnd _ (LPTransfo Pred1 Pred2 p2lp f1) (LPTransfo Pred1 Pred2 p2lp f2)
| LPNot _ f1 => LPNot _ (LPTransfo Pred1 Pred2 p2lp f1)
end.
-Implicit Arguments LPTransfo.
+Arguments LPTransfo : default implicits.
-Definition addIndex (Ind:Type) (Pred: Ind -> Type) (i: Ind) f :=
+Definition addIndex (Ind:Type) (Pred: Ind -> Type) (i: Ind) f :=
LPTransfo (fun p => LPPred _ (existT (fun i => Pred i) i p)) f.
Section TTS.
@@ -121,8 +121,8 @@ Record simu (Pred: Type) (a: TTS StateA) (c: TTS StateC) (tra: Pred -> LP (Predi
Delay _ a (mabs m ex1 st1) d (mabs m (mDelay m ex1 st1 d) st2);
simuNext: forall ex1 st1 st2, Next _ c st1 st2 -> inv ex1 st1 ->
Next _ a (mabs m ex1 st1) (mabs m (mNext m ex1 st1) st2);
- simuPred: forall ext st, inv ext st ->
- (forall p, lpSat (Satisfy _ c) st (trc p) <-> lpSat (Satisfy _ a) (mabs m ext st) (tra p))
+ simuPred: forall ext st, inv ext st ->
+ (forall p, lpSat (Satisfy _ c) st (trc p) <-> lpSat (Satisfy _ a) (mabs m ext st) (tra p))
}.
Theorem satProd: forall State Ind Pred (Sat: forall i, State -> Pred i -> Prop) (st:State) i (f: LP (Pred i)),
@@ -137,15 +137,15 @@ Qed.
Definition trProd (State: Type) Ind (Pred: Ind -> Type) (tts: Ind -> TTS State) (tr: forall i, (Pred i) -> LP (Predicate _ (tts i))):
{i:Ind & Pred i} -> LP (Predicate _ (TTSIndexedProduct _ Ind tts)) :=
- fun p => addIndex Ind _ (projS1 p) (tr (projS1 p) (projS2 p)).
+ fun p => addIndex Ind _ (projT1 p) (tr (projT1 p) (projT2 p)).
-Implicit Arguments trProd.
+Arguments trProd : default implicits.
Require Import Setoid.
Theorem satTrProd:
- forall State Ind Pred (tts: Ind -> TTS State)
+ forall State Ind Pred (tts: Ind -> TTS State)
(tr: forall i, (Pred i) -> LP (Predicate _ (tts i))) (st:State) (p: {i:Ind & (Pred i)}),
- lpSat (Satisfy _ (tts (projS1 p))) st (tr (projS1 p) (projS2 p))
+ lpSat (Satisfy _ (tts (projT1 p))) st (tr (projT1 p) (projT2 p))
<->
lpSat (Satisfy _ (TTSIndexedProduct _ _ tts)) st (trProd _ tts tr p).
Proof.
@@ -154,11 +154,11 @@ Proof.
(fun i => Satisfy _ (tts i))); tauto.
Qed.
-Theorem simuProd:
- forall Ind (Pred: Ind -> Type) (tta: Ind -> TTS StateA) (ttc: Ind -> TTS StateC)
+Theorem simuProd:
+ forall Ind (Pred: Ind -> Type) (tta: Ind -> TTS StateA) (ttc: Ind -> TTS StateC)
(tra: forall i, (Pred i) -> LP (Predicate _ (tta i)))
(trc: forall i, (Pred i) -> LP (Predicate _ (ttc i))),
- (forall i, simu _ (tta i) (ttc i) (tra i) (trc i)) ->
+ (forall i, simu _ (tta i) (ttc i) (tra i) (trc i)) ->
simu _ (TTSIndexedProduct _ Ind tta) (TTSIndexedProduct _ Ind ttc)
(trProd Pred tta tra) (trProd Pred ttc trc).
Proof.
@@ -171,11 +171,11 @@ Proof.
eapply simuDelay; eauto.
eapply simuNext; eauto.
split; simpl; intros.
- generalize (proj1 (simuPred _ _ _ _ _ (X (projS1 p)) ext st (H (projS1 p)) (projS2 p))); simpl; intro.
+ generalize (proj1 (simuPred _ _ _ _ _ (X (projT1 p)) ext st (H (projT1 p)) (projT2 p))); simpl; intro.
rewrite <- (satTrProd StateA Ind Pred tta tra); apply H1.
rewrite (satTrProd StateC Ind Pred ttc trc); apply H0.
- generalize (proj2 (simuPred _ _ _ _ _ (X (projS1 p)) ext st (H (projS1 p)) (projS2 p))); simpl; intro.
+ generalize (proj2 (simuPred _ _ _ _ _ (X (projT1 p)) ext st (H (projT1 p)) (projT2 p))); simpl; intro.
rewrite <- (satTrProd StateC Ind Pred ttc trc); apply H1.
rewrite (satTrProd StateA Ind Pred tta tra); apply H0.
Qed.
@@ -189,11 +189,11 @@ Record simu_equiv StateA StateC m1 m2 Pred (a: TTS StateA) (c: TTS StateC) (tra:
simuRL: simu StateC StateA m2 Pred c a trc tra
}.
-Theorem simu_equivProd:
- forall StateA StateC m1 m2 Ind (Pred: Ind -> Type) (tta: Ind -> TTS StateA) (ttc: Ind -> TTS StateC)
+Theorem simu_equivProd:
+ forall StateA StateC m1 m2 Ind (Pred: Ind -> Type) (tta: Ind -> TTS StateA) (ttc: Ind -> TTS StateC)
(tra: forall i, (Pred i) -> LP (Predicate _ (tta i)))
(trc: forall i, (Pred i) -> LP (Predicate _ (ttc i))),
- (forall i, simu_equiv StateA StateC m1 m2 _ (tta i) (ttc i) (tra i) (trc i)) ->
+ (forall i, simu_equiv StateA StateC m1 m2 _ (tta i) (ttc i) (tra i) (trc i)) ->
simu_equiv StateA StateC m1 m2 _ (TTSIndexedProduct _ Ind tta) (TTSIndexedProduct _ Ind ttc)
(trProd _ _ Pred tta tra) (trProd _ _ Pred ttc trc).
Proof.
@@ -237,7 +237,7 @@ Definition pPredicate (L: RTLanguage) (sys: PSyntax L) := { i : pIndex L sys & M
(* product with shared state *)
-Definition PLanguage (L: RTLanguage): RTLanguage :=
+Definition PLanguage (L: RTLanguage): RTLanguage :=
mkRTLanguage
(PSyntax L)
(pState L)
@@ -246,7 +246,7 @@ Definition PLanguage (L: RTLanguage): RTLanguage :=
eq_refl => Semantic L (pComponents L mdl i)
end))
(pPredicate L)
- (fun mdl => trProd _ _ _ _
+ (fun mdl => trProd _ _ _ _
(fun i pi => match pIsShared L mdl i as e in (_ = y) return
(LP (Predicate y
match e in (_ = y0) return (TTS y0) with
@@ -259,22 +259,22 @@ Definition PLanguage (L: RTLanguage): RTLanguage :=
Inductive Empty: Type :=.
Record isSharedTransfo l1 l2 tr: Prop := isSharedTransfoPrf {
-sameState: forall mdl i j,
+sameState: forall mdl i j,
DynamicState l2 (Tmodel l1 l2 tr (pComponents l1 mdl i)) =
DynamicState l2 (Tmodel l1 l2 tr (pComponents l1 mdl j));
-sameMState: forall mdl i j,
+sameMState: forall mdl i j,
mState _ _ (Tl1l2 _ _ tr (pComponents l1 mdl i)) =
mState _ _ (Tl1l2 _ _ tr (pComponents l1 mdl j));
-sameM12: forall mdl i j,
+sameM12: forall mdl i j,
Tl1l2 _ _ tr (pComponents l1 mdl i) =
match sym_eq (sameState mdl i j) in _=y return mapping _ y with
eq_refl => match sym_eq (pIsShared l1 mdl i) in _=x return mapping x _ with
eq_refl => match pIsShared l1 mdl j in _=x return mapping x _ with
eq_refl => Tl1l2 _ _ tr (pComponents l1 mdl j)
end
- end
+ end
end;
-sameM21: forall mdl i j,
+sameM21: forall mdl i j,
Tl2l1 l1 l2 tr (pComponents l1 mdl i) =
match
sym_eq (sameState mdl i j) in (_ = y)
@@ -301,7 +301,7 @@ end
Definition PTransfoSyntax l1 l2 tr (h: isSharedTransfo l1 l2 tr) mdl :=
mkPSyntax l2 (pIndex l1 mdl)
(pIsEmpty l1 mdl)
- (match pIsEmpty l1 mdl return Type with
+ (match pIsEmpty l1 mdl return Type with
inleft i => DynamicState l2 (Tmodel l1 l2 tr (pComponents l1 mdl i))
|inright h => pState l1 mdl
end)
@@ -314,7 +314,7 @@ Definition PTransfoSyntax l1 l2 tr (h: isSharedTransfo l1 l2 tr) mdl :=
| inright _ => pState l1 mdl
end)
with
- inleft j => sameState l1 l2 tr h mdl i j
+ inleft j => sameState l1 l2 tr h mdl i j
| inright h => match h i with end
end).
@@ -388,12 +388,12 @@ match pIsEmpty l1 mdl with
addIndex (pIndex l1 mdl) (fun i => MdlPredicate l2 (Tmodel l1 l2 tr (pComponents l1 mdl i))) x
(LPTransfo (Tpred l1 l2 tr (pComponents l1 mdl x))
(LPPred (MdlPredicate l1 (pComponents l1 mdl x)) p))
-| inright f => match f (projS1 pp) with end
+| inright f => match f (projT1 pp) with end
end.
-Lemma simu_eqA:
+Lemma simu_eqA:
forall A1 A2 C m P sa sc tta ttc (h: A2=A1),
- simu A1 C (match h in (_=y) return mapping _ C with eq_refl => m end)
+ simu A1 C (match h in (_=y) return mapping _ C with eq_refl => m end)
P (match h in (_=y) return TTS y with eq_refl => sa end)
sc (fun p => match h in (_=y) return LP (Predicate y _) with eq_refl => tta p end)
ttc ->
@@ -401,9 +401,9 @@ Lemma simu_eqA:
admit.
Qed.
-Lemma simu_eqC:
+Lemma simu_eqC:
forall A C1 C2 m P sa sc tta ttc (h: C2=C1),
- simu A C1 (match h in (_=y) return mapping A _ with eq_refl => m end)
+ simu A C1 (match h in (_=y) return mapping A _ with eq_refl => m end)
P sa (match h in (_=y) return TTS y with eq_refl => sc end)
tta (fun p => match h in (_=y) return LP (Predicate y _) with eq_refl => ttc p end)
->
@@ -411,10 +411,10 @@ Lemma simu_eqC:
admit.
Qed.
-Lemma simu_eqA1:
+Lemma simu_eqA1:
forall A1 A2 C m P sa sc tta ttc (h: A1=A2),
- simu A1 C m
- P
+ simu A1 C m
+ P
(match (sym_eq h) in (_=y) return TTS y with eq_refl => sa end) sc
(fun p => match (sym_eq h) as e in (_=y) return LP (Predicate y (match e in (_=z) return TTS z with eq_refl => sa end)) with eq_refl => tta p end) ttc
->
@@ -422,32 +422,32 @@ Lemma simu_eqA1:
admit.
Qed.
-Lemma simu_eqA2:
+Lemma simu_eqA2:
forall A1 A2 C m P sa sc tta ttc (h: A1=A2),
simu A1 C (match (sym_eq h) in (_=y) return mapping _ C with eq_refl => m end)
- P
+ P
sa sc tta ttc
->
simu A2 C m P
- (match h in (_=y) return TTS y with eq_refl => sa end) sc
+ (match h in (_=y) return TTS y with eq_refl => sa end) sc
(fun p => match h as e in (_=y) return LP (Predicate y match e in (_=y0) return TTS y0 with eq_refl => sa end) with eq_refl => tta p end)
ttc.
admit.
Qed.
-Lemma simu_eqC2:
+Lemma simu_eqC2:
forall A C1 C2 m P sa sc tta ttc (h: C1=C2),
simu A C1 (match (sym_eq h) in (_=y) return mapping A _ with eq_refl => m end)
- P
+ P
sa sc tta ttc
->
simu A C2 m P
- sa (match h in (_=y) return TTS y with eq_refl => sc end)
+ sa (match h in (_=y) return TTS y with eq_refl => sc end)
tta (fun p => match h as e in (_=y) return LP (Predicate y match e in (_=y0) return TTS y0 with eq_refl => sc end) with eq_refl => ttc p end).
admit.
Qed.
-Lemma simu_eqM:
+Lemma simu_eqM:
forall A C m1 m2 P sa sc tta ttc (h: m1=m2),
simu A C m1 P sa sc tta ttc
->
@@ -470,7 +470,7 @@ Lemma LPTransfo_addIndex:
addIndex Ind tr1 (projT1 p0) (tr2 (projT1 p0) (projT2 p0)))
(addIndex Ind Pred x p).
Proof.
- unfold addIndex; intros.
+ unfold addIndex; intros.
rewrite LPTransfo_trans.
rewrite LPTransfo_trans.
simpl.
@@ -491,7 +491,7 @@ Lemma LPTransfo_addIndex_tr:
addIndex Ind tr1 (projT1 p0) (tr3 (projT1 p0) (tr2 (projT1 p0) (projT2 p0))))
(addIndex Ind Pred x p).
Proof.
- unfold addIndex; simpl; intros.
+ unfold addIndex; simpl; intros.
rewrite LPTransfo_trans; simpl.
rewrite <- LPTransfo_trans.
f_equal.
@@ -505,19 +505,19 @@ Qed.
Require Export Coq.Logic.FunctionalExtensionality.
Print PLanguage.
-Program Definition PTransfo l1 l2 (tr: Transformation l1 l2) (h: isSharedTransfo l1 l2 tr):
+Program Definition PTransfo l1 l2 (tr: Transformation l1 l2) (h: isSharedTransfo l1 l2 tr):
Transformation (PLanguage l1) (PLanguage l2) :=
mkTransformation (PLanguage l1) (PLanguage l2)
(PTransfoSyntax l1 l2 tr h)
(Pmap12 l1 l2 tr h)
(Pmap21 l1 l2 tr h)
(PTpred l1 l2 tr h)
- (fun mdl => simu_equivProd
- (pState l1 mdl)
- (pState l2 (PTransfoSyntax l1 l2 tr h mdl))
+ (fun mdl => simu_equivProd
+ (pState l1 mdl)
+ (pState l2 (PTransfoSyntax l1 l2 tr h mdl))
(Pmap12 l1 l2 tr h mdl)
(Pmap21 l1 l2 tr h mdl)
- (pIndex l1 mdl)
+ (pIndex l1 mdl)
(fun i => MdlPredicate l1 (pComponents l1 mdl i))
(compSemantic l1 mdl)
(compSemantic l2 (PTransfoSyntax l1 l2 tr h mdl))
diff --git a/test-suite/bugs/closed/2404.v b/test-suite/bugs/closed/2404.v
index 8ac696e9..f6ec6760 100644
--- a/test-suite/bugs/closed/2404.v
+++ b/test-suite/bugs/closed/2404.v
@@ -22,13 +22,13 @@ Section Derived.
Definition bexportw := exportw base.
Definition bwweak := wweak base.
- Implicit Arguments bexportw [a b].
+ Arguments bexportw [a b].
Inductive RstarSetProof {I : Type} (T : I -> I -> Type) : I -> I -> Type :=
starReflS : forall a, RstarSetProof T a a
| starTransS : forall i j k, T i j -> (RstarSetProof T j k) -> RstarSetProof T i k.
-Implicit Arguments starTransS [I T i j k].
+Arguments starTransS [I T i j k].
Definition RstarInv {A : Set} (rel : relation A) : A -> A -> Type := (flip (RstarSetProof (flip rel))).
diff --git a/test-suite/bugs/closed/2456.v b/test-suite/bugs/closed/2456.v
index de28c7f4..e5a392c4 100644
--- a/test-suite/bugs/closed/2456.v
+++ b/test-suite/bugs/closed/2456.v
@@ -6,7 +6,7 @@ Parameter Patch : nat -> nat -> Set.
Inductive Catch (from to : nat) : Type
:= MkCatch : forall (p : Patch from to),
Catch from to.
-Implicit Arguments MkCatch [from to].
+Arguments MkCatch [from to].
Inductive CatchCommute5
: forall {from mid1 mid2 to : nat},
diff --git a/test-suite/bugs/closed/2584.v b/test-suite/bugs/closed/2584.v
index ef2e4e35..b5a723b4 100644
--- a/test-suite/bugs/closed/2584.v
+++ b/test-suite/bugs/closed/2584.v
@@ -8,7 +8,7 @@ Inductive res (A: Type) : Type :=
| OK: A -> res A
| Error: err -> res A.
-Implicit Arguments Error [A].
+Arguments Error [A].
Set Printing Universes.
diff --git a/test-suite/bugs/closed/2667.v b/test-suite/bugs/closed/2667.v
index 0631e535..0e6d0108 100644
--- a/test-suite/bugs/closed/2667.v
+++ b/test-suite/bugs/closed/2667.v
@@ -1,11 +1,11 @@
-(* Check that extra arguments to Arguments Scope do not disturb use of *)
+(* Check that extra arguments to Arguments do not disturb use of *)
(* scopes in constructors *)
Inductive stmt : Type := Sskip: stmt | Scall : nat -> stmt.
Bind Scope Cminor with stmt.
(* extra argument is ok because of possible coercion to funclass *)
-Arguments Scope Scall [_ Cminor ].
+Arguments Scall _ _%Cminor : extra scopes.
(* extra argument is ok because of possible coercion to funclass *)
Fixpoint f (c: stmt) : Prop := match c with Scall _ => False | _ => False end.
diff --git a/test-suite/bugs/closed/2670.v b/test-suite/bugs/closed/2670.v
index c401420e..791889b2 100644
--- a/test-suite/bugs/closed/2670.v
+++ b/test-suite/bugs/closed/2670.v
@@ -15,6 +15,14 @@ Proof.
refine (match e return _ with refl_equal => _ end).
reflexivity.
Undo 2.
+ (** Check insensitivity to alphabetic order *)
+ refine (match e as a in _ = b return _ with refl_equal => _ end).
+ reflexivity.
+ Undo 2.
+ (** Check insensitivity to alphabetic order *)
+ refine (match e as z in _ = y return _ with refl_equal => _ end).
+ reflexivity.
+ Undo 2.
(* Next line similarly has a dependent and a non dependent solution *)
refine (match e with refl_equal => _ end).
reflexivity.
diff --git a/test-suite/bugs/closed/2729.v b/test-suite/bugs/closed/2729.v
index 7929b881..c9d65c12 100644
--- a/test-suite/bugs/closed/2729.v
+++ b/test-suite/bugs/closed/2729.v
@@ -82,8 +82,8 @@ Inductive SequenceBase (pu : PatchUniverse)
(p : pu_type from mid)
(qs : SequenceBase pu mid to),
SequenceBase pu from to.
-Implicit Arguments Nil [pu cxt].
-Implicit Arguments Cons [pu from mid to].
+Arguments Nil [pu cxt].
+Arguments Cons [pu from mid to].
Program Fixpoint insertBase {pu : PatchUniverse}
{from mid to : NameSet}
diff --git a/test-suite/bugs/closed/2733.v b/test-suite/bugs/closed/2733.v
index 832de4f9..24dd30b3 100644
--- a/test-suite/bugs/closed/2733.v
+++ b/test-suite/bugs/closed/2733.v
@@ -16,6 +16,21 @@ match k,l with
|B,l' => Bcons true (Ncons 0 l')
end.
+(* At some time, the success of trullynul was dependent on the name of
+ the variables! *)
+
+Definition trullynul2 k {a} (l : alt_list k a) :=
+match k,l with
+ |N,l' => Ncons 0 (Bcons true l')
+ |B,l' => Bcons true (Ncons 0 l')
+end.
+
+Definition trullynul3 k {z} (l : alt_list k z) :=
+match k,l with
+ |N,l' => Ncons 0 (Bcons true l')
+ |B,l' => Bcons true (Ncons 0 l')
+end.
+
Fixpoint app (P : forall {k k'}, alt_list k k' -> alt_list k k') {t1 t2} (l : alt_list t1 t2) {struct l}: forall {t3}, alt_list t2 t3 ->
alt_list t1 t3 :=
match l with
diff --git a/test-suite/bugs/closed/2830.v b/test-suite/bugs/closed/2830.v
index bb607b78..07a5cf91 100644
--- a/test-suite/bugs/closed/2830.v
+++ b/test-suite/bugs/closed/2830.v
@@ -49,9 +49,9 @@ Record ageable_facts (A:Type) (level: A -> nat) (age1:A -> option A) :=
; af_level2 : forall x y, age1 x = Some y -> level x = S (level y)
}.
-Implicit Arguments af_unage [[A] [level] [age1]].
-Implicit Arguments af_level1 [[A] [level] [age1]].
-Implicit Arguments af_level2 [[A] [level] [age1]].
+Arguments af_unage {A level age1}.
+Arguments af_level1 {A level age1}.
+Arguments af_level2 {A level age1}.
Class ageable (A:Type) := mkAgeable
{ level : A -> nat
@@ -77,7 +77,7 @@ Coercion app_pred : pred >-> Funclass.
Global Opaque pred.
Definition derives {A} `{ageable A} (P Q:pred A) := forall a:A, P a -> Q a.
-Implicit Arguments derives.
+Arguments derives : default implicits.
Program Definition andp {A} `{ageable A} (P Q:pred A) : pred A :=
fun a:A => P a /\ Q a.
@@ -170,7 +170,7 @@ Class Functor `(C:Category) `(D:Category) (im : C -> D) := {
fmap g ∘ fmap f ≈ fmap (g ∘ f)
}.
Coercion functor_im : Functor >-> Funclass.
-Implicit Arguments fmap [Object Hom C Object0 Hom0 D im a b].
+Arguments fmap [Object Hom C Object0 Hom0 D im] _ [a b].
Add Parametric Morphism `(C:Category) `(D:Category)
(Im:C->D) (F:Functor C D Im) (a b:C) : (@fmap _ _ C _ _ D Im F a b)
diff --git a/test-suite/bugs/closed/2969.v b/test-suite/bugs/closed/2969.v
index a03adbd7..7b1a2617 100644
--- a/test-suite/bugs/closed/2969.v
+++ b/test-suite/bugs/closed/2969.v
@@ -12,6 +12,7 @@ eexists.
reflexivity.
Grab Existential Variables.
admit.
+Admitted.
(* Alternative variant which failed but without raising anomaly *)
@@ -24,3 +25,4 @@ clearbody n n0.
exact I.
Grab Existential Variables.
admit.
+Admitted.
diff --git a/test-suite/bugs/closed/3068.v b/test-suite/bugs/closed/3068.v
index 79671ce9..9811733d 100644
--- a/test-suite/bugs/closed/3068.v
+++ b/test-suite/bugs/closed/3068.v
@@ -33,7 +33,7 @@ Section Counted_list.
End Counted_list.
-Implicit Arguments counted_def_nth [A n].
+Arguments counted_def_nth [A n].
Section Finite_nat_set.
diff --git a/test-suite/bugs/closed/3377.v b/test-suite/bugs/closed/3377.v
index 8e9e3933..abfcf1d3 100644
--- a/test-suite/bugs/closed/3377.v
+++ b/test-suite/bugs/closed/3377.v
@@ -5,6 +5,7 @@ Record prod A B := pair { fst : A; snd : B}.
Goal fst (@pair Type Type Type Type).
Set Printing All.
match goal with |- ?f ?x => set (foo := f x) end.
+Abort.
Goal forall x : prod Set Set, x = @pair _ _ (fst x) (snd x).
Proof.
@@ -12,6 +13,6 @@ Proof.
lazymatch goal with
| [ |- ?x = @pair _ _ (?f ?x) (?g ?x) ] => pose f
end.
-
(* Toplevel input, characters 7-44:
Error: No matching clauses for match. *)
+Abort.
diff --git a/test-suite/bugs/closed/3513.v b/test-suite/bugs/closed/3513.v
index 1f0f3b0d..a1d0b910 100644
--- a/test-suite/bugs/closed/3513.v
+++ b/test-suite/bugs/closed/3513.v
@@ -21,7 +21,7 @@ Section ILogic_Fun.
Local Instance ILFun_Ops : ILogicOps (@ILFunFrm T _ Frm _) := admit.
Definition ILFun_ILogic : ILogic (@ILFunFrm T _ Frm _) := admit.
End ILogic_Fun.
-Implicit Arguments ILFunFrm [[ILOps] [e]].
+Arguments ILFunFrm _ {e} _ {ILOps}.
Instance ILogicOps_Prop : ILogicOps Prop | 2 := {| lentails P Q := (P : Prop) -> Q;
ltrue := True;
land P Q := P /\ Q;
diff --git a/test-suite/bugs/closed/3647.v b/test-suite/bugs/closed/3647.v
index f5a22bd5..e91c004c 100644
--- a/test-suite/bugs/closed/3647.v
+++ b/test-suite/bugs/closed/3647.v
@@ -26,7 +26,7 @@ Record morphism T T' `{e : type T} `{e' : type T'} :=
mkMorph {
morph :> T -> T';
morph_resp : setoid_resp morph}.
-Implicit Arguments mkMorph [T T' e e0 e' e1].
+Arguments mkMorph [T T' e0 e e1 e'].
Infix "-s>" := morphism (at level 45, right associativity).
Section Morphisms.
Context {S T U V} `{eS : type S} `{eT : type T} `{eU : type U} `{eV : type V}.
@@ -334,8 +334,8 @@ Section ILogic_Fun.
End ILogic_Fun.
-Implicit Arguments ILFunFrm [[ILOps] [e]].
-Implicit Arguments mkILFunFrm [T Frm ILOps].
+Arguments ILFunFrm _ {e} _ {ILOps}.
+Arguments mkILFunFrm [T] _ [Frm ILOps].
Program Definition ILFun_eq {T R} {ILOps: ILogicOps R} {ILogic: ILogic R} (P : T -> R) :
@ILFunFrm T _ R ILOps :=
diff --git a/test-suite/bugs/closed/3690.v b/test-suite/bugs/closed/3690.v
index fa30132a..9273a20e 100644
--- a/test-suite/bugs/closed/3690.v
+++ b/test-suite/bugs/closed/3690.v
@@ -41,8 +41,5 @@ Type@{Top.34} -> Type@{Top.37}
Top.36 < Top.34
Top.37 < Top.36
*) *)
-Fail Check @qux@{Set Set}.
-Check @qux@{Type Type Type Type}.
-(* [qux] should only need two universes *)
-Check @qux@{i j k l}. (* Error: The command has not failed!, but I think this is suboptimal *)
-Fail Check @qux@{i j}.
+Check @qux@{Type Type}.
+(* used to have 4 universes *)
diff --git a/test-suite/bugs/closed/3732.v b/test-suite/bugs/closed/3732.v
index 09f1149c..13d62b8f 100644
--- a/test-suite/bugs/closed/3732.v
+++ b/test-suite/bugs/closed/3732.v
@@ -16,7 +16,7 @@ Section machine.
| Inj : forall G, Prop -> propX G
| ExistsX : forall G A, propX (A :: G) -> propX G.
- Implicit Arguments Inj [G].
+ Arguments Inj [G].
Definition PropX := propX nil.
Fixpoint last (G : list Type) : Type.
diff --git a/test-suite/bugs/closed/3956.v b/test-suite/bugs/closed/3956.v
index 4957cc74..ac30fc73 100644
--- a/test-suite/bugs/closed/3956.v
+++ b/test-suite/bugs/closed/3956.v
@@ -129,13 +129,13 @@ Module Comodality_Theory (F : Comodality).
:= IdmapM FPM.
Module cip_FPM := FPM.coindpathsM FPM cmpinv_o_cmp_M idmap_FPM.
Module cip_FPHM <: HomotopyM FPM cmpM.PM cip_FPM.fhM cip_FPM.fkM.
- Definition m : forall x, cip_FPM.fhM.m@{i j} x = cip_FPM.fkM.m@{i j} x.
+ Definition m : forall x, cip_FPM.fhM.m x = cip_FPM.fkM.m x.
Proof.
intros x.
- refine (concat (cmpinvM.m_beta@{i j} (cmpM.m@{i j} x)) _).
+ refine (concat (cmpinvM.m_beta (cmpM.m x)) _).
apply path_prod@{i i i}; simpl.
- - exact (cmpM.FfstM.mM.m_beta@{i j} x).
- - exact (cmpM.FsndM.mM.m_beta@{i j} x).
+ - exact (cmpM.FfstM.mM.m_beta x).
+ - exact (cmpM.FsndM.mM.m_beta x).
Defined.
End cip_FPHM.
End isequiv_F_prod_cmp_M.
diff --git a/test-suite/bugs/closed/4069.v b/test-suite/bugs/closed/4069.v
index 606c6e08..668f6bb4 100644
--- a/test-suite/bugs/closed/4069.v
+++ b/test-suite/bugs/closed/4069.v
@@ -41,6 +41,8 @@ Proof. f_equal.
8.5: 2 goals, skipn n l = l -> k ++ skipn n l = skipn n l
and skipn n l = l
*)
+Abort.
+
Require Import List.
Fixpoint replicate {A} (n : nat) (x : A) : list A :=
match n with 0 => nil | S n => x :: replicate n x end.
diff --git a/test-suite/bugs/closed/4095.v b/test-suite/bugs/closed/4095.v
index 8d7dfbd4..bc9380f9 100644
--- a/test-suite/bugs/closed/4095.v
+++ b/test-suite/bugs/closed/4095.v
@@ -23,7 +23,7 @@ Section ILogic_Fun.
Local Instance ILFun_Ops : ILogicOps (@ILFunFrm T _ Frm _) := admit.
Definition ILFun_ILogic : ILogic (@ILFunFrm T _ Frm _) := admit.
End ILogic_Fun.
-Implicit Arguments ILFunFrm [[ILOps] [e]].
+Arguments ILFunFrm _ {e} _ {ILOps}.
Instance ILogicOps_Prop : ILogicOps Prop | 2 := {| lentails P Q := (P : Prop) -> Q;
ltrue := True;
land P Q := P /\ Q;
diff --git a/test-suite/bugs/closed/4132.v b/test-suite/bugs/closed/4132.v
index 806ffb77..67ecc308 100644
--- a/test-suite/bugs/closed/4132.v
+++ b/test-suite/bugs/closed/4132.v
@@ -26,6 +26,6 @@ Qed.
Lemma foo3 x y (b := 0) (H1 : x <= y) (H2 : y <= b) : x <= b.
omega. (* Pierre L: according to a comment of bug report #4132,
- this might have triggered "Failure(occurence 2)" in the past,
+ this might have triggered "Failure(occurrence 2)" in the past,
but I never managed to reproduce that. *)
Qed.
diff --git a/test-suite/bugs/closed/4198.v b/test-suite/bugs/closed/4198.v
index eb37141b..28800ac0 100644
--- a/test-suite/bugs/closed/4198.v
+++ b/test-suite/bugs/closed/4198.v
@@ -13,6 +13,7 @@ Goal forall A (x x' : A) (xs xs' : list A) (H : x::xs = x'::xs'),
match goal with
| [ |- context G[@hd] ] => idtac
end.
+Abort.
(* This second example comes from CFGV where inspecting subterms of a
match is expecting to inspect first the term to match (even though
@@ -35,3 +36,4 @@ Ltac mydestruct :=
Goal forall x, match x with 0 => 0 | _ => 0 end = 0.
intros.
mydestruct.
+Abort.
diff --git a/test-suite/bugs/closed/4306.v b/test-suite/bugs/closed/4306.v
index 28f028ad..80c348d2 100644
--- a/test-suite/bugs/closed/4306.v
+++ b/test-suite/bugs/closed/4306.v
@@ -1,13 +1,13 @@
Require Import List.
Require Import Arith.
-Require Import Recdef.
+Require Import Recdef.
Require Import Omega.
Function foo (xys : (list nat * list nat)) {measure (fun xys => length (fst xys) + length (snd xys))} : list nat :=
match xys with
| (nil, _) => snd xys
| (_, nil) => fst xys
- | (x :: xs', y :: ys') => match Compare_dec.nat_compare x y with
+ | (x :: xs', y :: ys') => match Nat.compare x y with
| Lt => x :: foo (xs', y :: ys')
| Eq => x :: foo (xs', ys')
| Gt => y :: foo (x :: xs', ys')
@@ -24,7 +24,7 @@ Function bar (xys : (list nat * list nat)) {measure (fun xys => length (fst xys)
match (xs, ys) with
| (nil, _) => ys
| (_, nil) => xs
- | (x :: xs', y :: ys') => match Compare_dec.nat_compare x y with
+ | (x :: xs', y :: ys') => match Nat.compare x y with
| Lt => x :: foo (xs', ys)
| Eq => x :: foo (xs', ys')
| Gt => y :: foo (xs, ys')
diff --git a/test-suite/bugs/closed/4527.v b/test-suite/bugs/closed/4527.v
index 117d6523..f8cedfff 100644
--- a/test-suite/bugs/closed/4527.v
+++ b/test-suite/bugs/closed/4527.v
@@ -23,7 +23,9 @@ Module Export Datatypes.
Set Implicit Arguments.
Notation nat := Coq.Init.Datatypes.nat.
+Notation O := Coq.Init.Datatypes.O.
Notation S := Coq.Init.Datatypes.S.
+Notation two := (S (S O)).
Record prod (A B : Type) := pair { fst : A ; snd : B }.
@@ -159,7 +161,7 @@ End Adjointify.
(n : nat) {A : Type@{i}} {B : Type@{j}}
(f : A -> B) (C : B -> Type@{k}) : Type@{l}
:= match n with
- | 0 => Unit@{l}
+ | O => Unit@{l}
| S n => (forall (g : forall a, C (f a)),
ExtensionAlong@{i j k l l} f C g) *
forall (h k : forall b, C b),
@@ -220,12 +222,12 @@ Section ORecursion.
Definition O_indpaths {P Q : Type} {Q_inO : In O Q}
(g h : O P -> Q) (p : g o to O P == h o to O P)
: g == h
- := (fst (snd (extendable_to_O O 2) g h) p).1.
+ := (fst (snd (extendable_to_O O two) g h) p).1.
Definition O_indpaths_beta {P Q : Type} {Q_inO : In O Q}
(g h : O P -> Q) (p : g o (to O P) == h o (to O P)) (x : P)
: O_indpaths g h p (to O P x) = p x
- := (fst (snd (extendable_to_O O 2) g h) p).2 x.
+ := (fst (snd (extendable_to_O O two) g h) p).2 x.
End ORecursion.
diff --git a/test-suite/bugs/closed/4533.v b/test-suite/bugs/closed/4533.v
index c3e0da11..fd2380a0 100644
--- a/test-suite/bugs/closed/4533.v
+++ b/test-suite/bugs/closed/4533.v
@@ -17,7 +17,10 @@ Notation "A -> B" := (forall (_ : A), B) : type_scope.
Module Export Datatypes.
Set Implicit Arguments.
Notation nat := Coq.Init.Datatypes.nat.
+ Notation O := Coq.Init.Datatypes.O.
Notation S := Coq.Init.Datatypes.S.
+ Notation one := (S O).
+ Notation two := (S one).
Record prod (A B : Type) := pair { fst : A ; snd : B }.
Notation "x * y" := (prod x y) : type_scope.
Delimit Scope nat_scope with nat.
@@ -109,7 +112,7 @@ Fixpoint ExtendableAlong@{i j k l}
(n : nat) {A : Type@{i}} {B : Type@{j}}
(f : A -> B) (C : B -> Type@{k}) : Type@{l}
:= match n with
- | 0 => Unit@{l}
+ | O => Unit@{l}
| S n => (forall (g : forall a, C (f a)),
ExtensionAlong@{i j k l l} f C g) *
forall (h k : forall b, C b),
@@ -160,17 +163,17 @@ Module ReflectiveSubuniverses_Theory (Os : ReflectiveSubuniverses).
Definition O_rec {P Q : Type} {Q_inO : In O Q}
(f : P -> Q)
: O P -> Q
- := (fst (extendable_to_O O 1%nat) f).1.
+ := (fst (extendable_to_O O one) f).1.
Definition O_rec_beta {P Q : Type} {Q_inO : In O Q}
(f : P -> Q) (x : P)
: O_rec f (to O P x) = f x
- := (fst (extendable_to_O O 1%nat) f).2 x.
+ := (fst (extendable_to_O O one) f).2 x.
Definition O_indpaths {P Q : Type} {Q_inO : In O Q}
(g h : O P -> Q) (p : g o to O P == h o to O P)
: g == h
- := (fst (snd (extendable_to_O O 2) g h) p).1.
+ := (fst (snd (extendable_to_O O two) g h) p).1.
End ORecursion.
diff --git a/test-suite/bugs/closed/4544.v b/test-suite/bugs/closed/4544.v
index 4ad53bc6..13c47edc 100644
--- a/test-suite/bugs/closed/4544.v
+++ b/test-suite/bugs/closed/4544.v
@@ -19,6 +19,7 @@ Inductive sum (A B : Type) : Type :=
| inl : A -> sum A B
| inr : B -> sum A B.
Notation nat := Coq.Init.Datatypes.nat.
+Notation O := Coq.Init.Datatypes.O.
Notation S := Coq.Init.Datatypes.S.
Notation "x + y" := (sum x y) : type_scope.
@@ -449,7 +450,7 @@ Section Extensions.
(n : nat) {A : Type@{i}} {B : Type@{j}}
(f : A -> B) (C : B -> Type@{k}) : Type@{l}
:= match n with
- | 0 => Unit@{l}
+ | O => Unit@{l}
| S n => (forall (g : forall a, C (f a)),
ExtensionAlong@{i j k l l} f C g) *
forall (h k : forall b, C b),
diff --git a/test-suite/bugs/closed/4782.v b/test-suite/bugs/closed/4782.v
index dbd71035..1e1a4cb9 100644
--- a/test-suite/bugs/closed/4782.v
+++ b/test-suite/bugs/closed/4782.v
@@ -6,6 +6,7 @@ Inductive p : Prop := consp : forall (e : r) (x : type e), cond e x -> p.
Goal p.
Fail apply consp with (fun _ : bool => mk_r unit (fun x => True)) nil.
+Abort.
(* A simplification of an example from coquelicot, which was failing
at some time after a fix #4782 was committed. *)
@@ -21,4 +22,5 @@ Set Typeclasses Debug.
Goal forall (A:T) (x:dom A), pairT A A = pairT A A.
intros.
apply (F _ _) with (x,x).
+Abort.
diff --git a/test-suite/bugs/closed/4798.v b/test-suite/bugs/closed/4798.v
index 6f2bcb96..41a1251c 100644
--- a/test-suite/bugs/closed/4798.v
+++ b/test-suite/bugs/closed/4798.v
@@ -1,3 +1,3 @@
Check match 2 with 0 => 0 | S n => n end.
-Notation "|" := 1 (compat "8.6").
+Notation "|" := 1 (compat "8.7").
Check match 2 with 0 => 0 | S n => n end. (* fails *)
diff --git a/test-suite/bugs/closed/4865.v b/test-suite/bugs/closed/4865.v
index c5bf3289..da4e53aa 100644
--- a/test-suite/bugs/closed/4865.v
+++ b/test-suite/bugs/closed/4865.v
@@ -48,5 +48,5 @@ Fail Check g 0 0 1. (* 2nd 0 in bool *)
Fixpoint arr n := match n with 0%nat => nat | S n => nat -> arr n end.
Fixpoint lam n : arr n := match n with 0%nat => 0%nat | S n => fun x => lam n end.
Notation "0" := true.
-Arguments Scope lam [nat_scope nat_scope].
+Arguments lam _%nat_scope _%nat_scope : extra scopes.
Check (lam 1 0).
diff --git a/test-suite/bugs/closed/4882.v b/test-suite/bugs/closed/4882.v
deleted file mode 100644
index 8c26af70..00000000
--- a/test-suite/bugs/closed/4882.v
+++ /dev/null
@@ -1,50 +0,0 @@
-
-Definition Foo {T}{a : T} : T := a.
-
-Module A.
-
- Declare Implicit Tactic eauto.
-
- Goal forall A (x : A), A.
- intros.
- apply Foo. (* Check defined evars are normalized *)
- (* Qed. *)
- Abort.
-
-End A.
-
-Module B.
-
- Definition Foo {T}{a : T} : T := a.
-
- Declare Implicit Tactic eassumption.
-
- Goal forall A (x : A), A.
- intros.
- apply Foo.
- (* Qed. *)
- Abort.
-
-End B.
-
-Module C.
-
- Declare Implicit Tactic first [exact True|assumption].
-
- Goal forall (x : True), True.
- intros.
- apply (@Foo _ _).
- Qed.
-
-End C.
-
-Module D.
-
- Declare Implicit Tactic assumption.
-
- Goal forall A (x : A), A.
- intros.
- exact _.
- Qed.
-
-End D.
diff --git a/test-suite/bugs/closed/5012.v b/test-suite/bugs/closed/5012.v
new file mode 100644
index 00000000..5326c0fb
--- /dev/null
+++ b/test-suite/bugs/closed/5012.v
@@ -0,0 +1,17 @@
+Class Foo := { foo : Set }.
+
+Axiom admit : forall {T}, T.
+
+Global Instance Foo0 : Foo
+ := {| foo := admit |}.
+
+Global Instance Foo1 : Foo
+ := { foo := admit }.
+
+Existing Class Foo.
+
+Global Instance Foo2 : Foo
+ := { foo := admit }. (* Error: Unbound method name foo of class Foo. *)
+
+Set Warnings "+already-existing-class".
+Fail Existing Class Foo.
diff --git a/test-suite/bugs/closed/5500.v b/test-suite/bugs/closed/5500.v
new file mode 100644
index 00000000..aa63e2ab
--- /dev/null
+++ b/test-suite/bugs/closed/5500.v
@@ -0,0 +1,35 @@
+(* Too weak check on the correctness of return clause was leading to an anomaly *)
+
+Inductive Vector A: nat -> Type :=
+ nil: Vector A O
+| cons: forall n, A -> Vector A n -> Vector A (S n).
+
+(* This could be made working with a better inference of inner return
+ predicates from the return predicate at the higher level of the
+ nested matching. Currently, we only check that it does not raise an
+ anomaly, but eventually, the "Fail" could be removed. *)
+
+Fail Definition hd_fst A x n (v: A * Vector A (S n)) :=
+ match v as v0 return match v0 with
+ (l, r) =>
+ match r in Vector _ n return match n with 0 => Type | S _ => Type end with
+ nil _ => A
+ | cons _ _ _ _ => A
+ end
+ end with
+ (_, nil _) => x
+ | (_, cons _ n hd tl) => hd
+ end.
+
+(* This is another example of failure but involving beta-reduction and
+ not iota-reduction. Thus, for this one, I don't see how it could be
+ solved by small inversion, whatever smart is small inversion. *)
+
+Inductive A : (Type->Type) -> Type := J : A (fun x => x).
+
+Fail Check fun x : nat * A (fun x => x) =>
+ match x return match x with
+ (y,z) => match z in A f return f Type with J => bool end
+ end with
+ (y,J) => true
+ end.
diff --git a/test-suite/bugs/closed/5547.v b/test-suite/bugs/closed/5547.v
new file mode 100644
index 00000000..79633f48
--- /dev/null
+++ b/test-suite/bugs/closed/5547.v
@@ -0,0 +1,16 @@
+(* Checking typability of intermediate return predicates in nested pattern-matching *)
+
+Inductive A : (Type->Type) -> Type := J : A (fun x => x).
+Definition ret (x : nat * A (fun x => x))
+ := match x return Type with
+ | (y,z) => match z in A f return f Type with
+ | J => bool
+ end
+ end.
+Definition foo : forall x, ret x.
+Proof.
+Fail refine (fun x
+ => match x return ret x with
+ | (y,J) => true
+ end
+ ).
diff --git a/test-suite/bugs/closed/5696.v b/test-suite/bugs/closed/5696.v
new file mode 100644
index 00000000..a20ad1b4
--- /dev/null
+++ b/test-suite/bugs/closed/5696.v
@@ -0,0 +1,5 @@
+(* Slightly improving interpretation of Ltac subterms in notations *)
+
+Notation "'var2' x .. y = z ; e" := (ltac:(exact z), (fun x => .. (fun y => e)
+..)) (at level 200, x binder, y binder, e at level 220).
+Check (var2 a = 1; a).
diff --git a/test-suite/bugs/closed/5719.v b/test-suite/bugs/closed/5719.v
new file mode 100644
index 00000000..0fad5f54
--- /dev/null
+++ b/test-suite/bugs/closed/5719.v
@@ -0,0 +1,9 @@
+Axiom cons_data_one :
+ forall (Aone : unit -> Set) (i : unit) (a : Aone i), nat.
+Axiom P : nat -> Prop.
+Axiom children_data_rect3 : forall {Aone : unit -> Set}
+ (cons_one_case : forall (i : unit) (b : Aone i),
+ nat -> nat -> P (cons_data_one Aone i b)),
+ P 0.
+Fail Definition decide_children_equality IH := children_data_rect3
+ (fun _ '(existT _ _ _) => match IH with tt => _ end).
diff --git a/test-suite/bugs/closed/7011.v b/test-suite/bugs/closed/7011.v
new file mode 100644
index 00000000..296e4e11
--- /dev/null
+++ b/test-suite/bugs/closed/7011.v
@@ -0,0 +1,16 @@
+(* Fix and Cofix were missing in tactic unification *)
+
+Goal exists e, (fix foo (n : nat) : nat := match n with O => e | S n' => foo n' end)
+ = (fix foo (n : nat) : nat := match n with O => O | S n' => foo n' end).
+Proof.
+ eexists.
+ reflexivity.
+Qed.
+
+CoInductive stream := cons : nat -> stream -> stream.
+
+Goal exists e, (cofix foo := cons e foo) = (cofix foo := cons 0 foo).
+Proof.
+ eexists.
+ reflexivity.
+Qed.
diff --git a/test-suite/bugs/closed/7068.v b/test-suite/bugs/closed/7068.v
new file mode 100644
index 00000000..9fadb195
--- /dev/null
+++ b/test-suite/bugs/closed/7068.v
@@ -0,0 +1,6 @@
+(* These tests are only about a subset of #7068 *)
+(* The original issue is still open *)
+
+Inductive foo : let T := Type in T := .
+Definition bob1 := Eval vm_compute in foo_rect.
+Definition bob2 := Eval native_compute in foo_rect.
diff --git a/test-suite/bugs/closed/7076.v b/test-suite/bugs/closed/7076.v
new file mode 100644
index 00000000..0abc88c2
--- /dev/null
+++ b/test-suite/bugs/closed/7076.v
@@ -0,0 +1,4 @@
+(* These calls were raising an anomaly at some time *)
+Inductive A : nat -> id (nat->Type) := .
+Eval vm_compute in fun x => match x in A y z return y = z with end.
+Eval native_compute in fun x => match x in A y z return y = z with end.
diff --git a/test-suite/bugs/closed/7092.v b/test-suite/bugs/closed/7092.v
new file mode 100644
index 00000000..d90de8b9
--- /dev/null
+++ b/test-suite/bugs/closed/7092.v
@@ -0,0 +1,70 @@
+(* Examples matching fix/cofix in Ltac pattern-matching *)
+
+Goal True.
+lazymatch (eval cbv delta [Nat.add] in Nat.add) with
+| (fix F (n : nat) (v : ?A) {struct n} : @?P n v
+ := match n with
+ | O => @?O_case v
+ | S n' => @?S_case n' v F
+ end)
+ =>
+ unify A nat;
+ unify P (fun _ _ : nat => nat);
+ unify O_case (fun v : nat => v);
+ unify S_case (fun (p : nat) (m : nat) (add : nat -> nat -> nat)
+ => S (add p m))
+ end.
+Abort.
+
+Fixpoint f l n := match n with 0 => 0 | S n => g n (cons n l) end
+with g n l := match n with 0 => 1 | S n => f (cons 0 l) n end.
+
+Goal True.
+
+lazymatch (eval cbv delta [f] in f) with
+| fix myf (l : ?L) (n : ?N) {struct n} : nat :=
+ match n as _ with
+ | 0 => ?Z
+ | S n0 => @?S myf myg n0 l
+ end
+ with myg (n' : ?N') (l' : ?L') {struct n'} : nat :=
+ match n' as _ with
+ | 0 => ?Z'
+ | S n0' => @?S' myf myg n0' l'
+ end
+ for myf =>
+ unify L (list nat);
+ unify L' (list nat);
+ unify N nat;
+ unify N' nat;
+ unify Z 0;
+ unify Z' 1;
+ unify S (fun (f : L -> N -> nat) (g : N -> L -> nat) n l => g n (cons n l));
+ unify S' (fun (f : L -> N -> nat) (g : N -> L -> nat) (n:N) l => f (cons 0 l) n)
+end.
+
+Abort.
+
+CoInductive S1 := C1 : nat -> S2 -> S1 with S2 := C2 : bool -> S1 -> S2.
+
+CoFixpoint f' n l := C1 n (g' (cons n l) n n)
+with g' l n p := C2 true (f' (S n) l).
+
+Goal True.
+
+lazymatch (eval cbv delta [f'] in f') with
+| cofix myf (n : ?N) (l : ?L) : ?T := @?X n g l
+ with g (l' : ?L') (n' : ?N') (p' : ?N'') : ?T' := @?X' n' myf l'
+ for myf =>
+ unify L (list nat);
+ unify L' (list nat);
+ unify N nat;
+ unify N' nat;
+ unify N'' nat;
+ unify T S1;
+ unify T' S2;
+ unify X (fun n g l => C1 n (g (cons n l) n n));
+ unify X' (fun n f (l : list nat) => C2 true (f (S n) l))
+end.
+
+Abort.
diff --git a/test-suite/bugs/closed/7421.v b/test-suite/bugs/closed/7421.v
new file mode 100644
index 00000000..afcdd35f
--- /dev/null
+++ b/test-suite/bugs/closed/7421.v
@@ -0,0 +1,39 @@
+
+
+Universe i j.
+
+Goal False.
+Proof.
+ Check Type@{i} : Type@{j}.
+ Fail constr_eq_strict Type@{i} Type@{j}.
+ assert_succeeds constr_eq Type@{i} Type@{j}. (* <- i=j is forgotten after assert_succeeds *)
+ Fail constr_eq_strict Type@{i} Type@{j}.
+
+ constr_eq Type@{i} Type@{j}. (* <- i=j is retained *)
+ constr_eq_strict Type@{i} Type@{j}.
+ Fail Check Type@{i} : Type@{j}.
+
+ Fail constr_eq Prop Set.
+ Fail constr_eq Prop Type.
+
+ Fail constr_eq_strict Type Type.
+ constr_eq Type Type.
+
+ constr_eq_strict Set Set.
+ constr_eq Set Set.
+ constr_eq Prop Prop.
+
+ let x := constr:(Type) in constr_eq_strict x x.
+ let x := constr:(Type) in constr_eq x x.
+
+ Fail lazymatch type of prod with
+ | ?A -> ?B -> _ => constr_eq_strict A B
+ end.
+ lazymatch type of prod with
+ | ?A -> ?B -> _ => constr_eq A B
+ end.
+ lazymatch type of prod with
+ | ?A -> ?B -> ?C => constr_eq A C
+ end.
+
+Abort.
diff --git a/test-suite/bugs/closed/7631.v b/test-suite/bugs/closed/7631.v
index 34eb8b86..93aeb83e 100644
--- a/test-suite/bugs/closed/7631.v
+++ b/test-suite/bugs/closed/7631.v
@@ -7,6 +7,7 @@ Section Foo.
Let bar := foo.
Eval native_compute in bar.
+Eval vm_compute in bar.
End Foo.
@@ -17,5 +18,6 @@ Module RelContext.
Definition foo := true.
Definition bar (x := foo) := Eval native_compute in x.
+Definition barvm (x := foo) := Eval vm_compute in x.
End RelContext.
diff --git a/test-suite/bugs/closed/7900.v b/test-suite/bugs/closed/7900.v
new file mode 100644
index 00000000..583ef0ef
--- /dev/null
+++ b/test-suite/bugs/closed/7900.v
@@ -0,0 +1,53 @@
+Require Import Coq.Program.Program.
+(* Set Universe Polymorphism. *)
+Set Printing Universes.
+
+Axiom ALL : forall {T:Prop}, T.
+
+Inductive Expr : Set := E (a : Expr).
+
+Parameter Value : Set.
+
+Fixpoint eval (e: Expr): Value :=
+ match e with
+ | E a => eval a
+ end.
+
+Class Quote (n: Value) : Set :=
+ { quote: Expr
+ ; eval_quote: eval quote = n }.
+
+Program Definition quote_mult n
+ `{!Quote n} : Quote n :=
+ {| quote := E (quote (n:=n)) |}.
+
+Set Printing Universes.
+Next Obligation.
+Proof.
+ Show Universes.
+ destruct Quote0 as [q eq].
+ Show Universes.
+ rewrite <- eq.
+ clear n eq.
+ Show Universes.
+ apply ALL.
+ Show Universes.
+Qed.
+Print quote_mult_obligation_1.
+(* quote_mult_obligation_1@{} =
+let Top_internal_eq_rew_dep :=
+ fun (A : Type@{Coq.Init.Logic.8}) (x : A) (P : forall a : A, x = a -> Type@{Top.5} (* <- XXX *))
+ (f : P x eq_refl) (y : A) (e : x = y) =>
+ match e as e0 in (_ = y0) return (P y0 e0) with
+ | eq_refl => f
+ end in
+fun (n : Value) (Quote0 : Quote n) =>
+match Quote0 as q return (eval quote = n) with
+| {| quote := q; eval_quote := eq0 |} =>
+ Top_internal_eq_rew_dep Value (eval q) (fun (n0 : Value) (eq1 : eval q = n0) => eval quote = n0)
+ ALL n eq0
+end
+ : forall (n : Value) (Quote0 : Quote n), eval (E quote) = n
+
+quote_mult_obligation_1 is universe polymorphic
+*)
diff --git a/test-suite/bugs/closed/7903.v b/test-suite/bugs/closed/7903.v
new file mode 100644
index 00000000..55c7ee99
--- /dev/null
+++ b/test-suite/bugs/closed/7903.v
@@ -0,0 +1,4 @@
+(* Slightly improving interpretation of Ltac subterms in notations *)
+
+Notation bar x f := (let z := ltac:(exact 1) in (fun x : nat => f)).
+Check bar x (x + x).
diff --git a/test-suite/bugs/closed/8081.v b/test-suite/bugs/closed/8081.v
new file mode 100644
index 00000000..0f2501aa
--- /dev/null
+++ b/test-suite/bugs/closed/8081.v
@@ -0,0 +1,4 @@
+Section foo.
+End foo.
+Section foo.
+End foo.
diff --git a/test-suite/bugs/closed/8106.v b/test-suite/bugs/closed/8106.v
new file mode 100644
index 00000000..a711c5ad
--- /dev/null
+++ b/test-suite/bugs/closed/8106.v
@@ -0,0 +1,4 @@
+(* Was raising an anomaly "already assigned a level" on the second line *)
+
+Notation "c1 ; c2" := (c1 + c2) (only printing, at level 76, right associativity, c1 at level 76, c2 at level 76).
+Notation "c1 ; c2" := (c1 + c2) (only parsing, at level 76, right associativity, c2 at level 76).
diff --git a/test-suite/bugs/closed/8126.v b/test-suite/bugs/closed/8126.v
new file mode 100644
index 00000000..f52dfc6b
--- /dev/null
+++ b/test-suite/bugs/closed/8126.v
@@ -0,0 +1,13 @@
+(* See also output test Notations4.v *)
+
+Inductive foo := tt.
+Bind Scope foo_scope with foo.
+Delimit Scope foo_scope with foo.
+Notation "'HI'" := tt : foo_scope.
+Definition myfoo (x : nat) (y : nat) (z : foo) := y.
+Notation myfoo0 := (@myfoo 0).
+Notation myfoo01 := (@myfoo0 1).
+Check myfoo 0 1 HI. (* prints [myfoo0 1 HI], but should print [myfoo01 HI] *)
+Check myfoo0 1 HI. (* prints [myfoo0 1 HI], but should print [myfoo01 HI] *)
+Check myfoo01 tt. (* prints [myfoo0 1 HI], but should print [myfoo01 HI] *)
+Check myfoo01 HI. (* was failing *)
diff --git a/test-suite/bugs/closed/8270.v b/test-suite/bugs/closed/8270.v
new file mode 100644
index 00000000..f36f757f
--- /dev/null
+++ b/test-suite/bugs/closed/8270.v
@@ -0,0 +1,15 @@
+(* Don't do zeta in cbn when not asked for *)
+
+Goal let x := 0 in
+ let y := x in
+ y = 0.
+ (* We use "cofix" as an example because there are obviously no
+ cofixpoints in sight. This problem arises with any set of
+ reduction flags (not including zeta where the lets are of course reduced away) *)
+ cbn cofix.
+ intro x.
+ unfold x at 1. (* Should succeed *)
+ Undo 2.
+ cbn zeta.
+ Fail unfold x at 1.
+Abort.
diff --git a/test-suite/bugs/closed/8553.v b/test-suite/bugs/closed/8553.v
new file mode 100644
index 00000000..4a1afabe
--- /dev/null
+++ b/test-suite/bugs/closed/8553.v
@@ -0,0 +1,7 @@
+(* Using tactic "change" under binders *)
+
+Definition add2 n := n +2.
+Goal (fun n => n) = (fun n => n+2).
+change (?n + 2) with (add2 n).
+match goal with |- _ = (fun n => add2 n) => idtac end. (* To test the presence of add2 *)
+Abort.
diff --git a/test-suite/bugs/closed/8672.v b/test-suite/bugs/closed/8672.v
new file mode 100644
index 00000000..66cd6dfa
--- /dev/null
+++ b/test-suite/bugs/closed/8672.v
@@ -0,0 +1,5 @@
+(* Was generating a dangling "pat" variable at some time *)
+
+Notation "'plet' x := e 'in' t" :=
+ ((fun H => let x := id H in t) e) (at level 0, x pattern).
+Definition bla := plet (pair x y) := pair 1 2 in x.
diff --git a/test-suite/bugs/closed/bug_8544.v b/test-suite/bugs/closed/bug_8544.v
new file mode 100644
index 00000000..674d1125
--- /dev/null
+++ b/test-suite/bugs/closed/bug_8544.v
@@ -0,0 +1,6 @@
+Require Import ssreflect.
+Goal True \/ True -> False.
+Proof.
+(* the following should fail: 2 subgoals, but only one intro pattern *)
+Fail case => [a].
+Abort.
diff --git a/test-suite/bugs/closed/bug_8755.v b/test-suite/bugs/closed/bug_8755.v
new file mode 100644
index 00000000..cd5aee4f
--- /dev/null
+++ b/test-suite/bugs/closed/bug_8755.v
@@ -0,0 +1,6 @@
+
+Lemma f : Type.
+Fail let i := ident:(i) in
+let t := context i [Type] in
+idtac.
+Abort.
diff --git a/test-suite/bugs/closed/bug_8794.v b/test-suite/bugs/closed/bug_8794.v
new file mode 100644
index 00000000..5ff0b302
--- /dev/null
+++ b/test-suite/bugs/closed/bug_8794.v
@@ -0,0 +1,11 @@
+(* This used to raise an anomaly in 8.8 *)
+
+Inductive T := Tau (t : T).
+
+Notation idT t := (match t with Tau t => Tau t end).
+
+Lemma match_itree : forall (t : T), t = idT t.
+Proof. destruct t; auto. Qed.
+
+Lemma what (k : unit -> T) : k tt = k tt.
+Proof. rewrite match_itree. Abort.
diff --git a/test-suite/bugs/closed/bug_8885.v b/test-suite/bugs/closed/bug_8885.v
new file mode 100644
index 00000000..9d86c08d
--- /dev/null
+++ b/test-suite/bugs/closed/bug_8885.v
@@ -0,0 +1,8 @@
+From Coq Require Import Cyclic31.
+
+Definition Nat `(int31) := nat.
+Definition Zero (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _: digits) := 0.
+
+Check (eq_refl (int31_rect Nat Zero 1) : 0 = 0).
+Check (eq_refl (int31_rect Nat Zero 1) <: 0 = 0).
+Check (eq_refl (int31_rect Nat Zero 1) <<: 0 = 0).
diff --git a/test-suite/bugs/opened/3295.v b/test-suite/bugs/opened/3295.v
index 2a156e33..c09649de 100644
--- a/test-suite/bugs/opened/3295.v
+++ b/test-suite/bugs/opened/3295.v
@@ -5,7 +5,7 @@ Class lops := lmk_ops {
weq: relation car
}.
-Implicit Arguments car [].
+Arguments car : clear implicits.
Coercion car: lops >-> Sortclass.
@@ -23,7 +23,7 @@ Class ops := mk_ops {
dot: forall n m p, mor n m -> mor m p -> mor n p
}.
Coercion mor: ops >-> Funclass.
-Implicit Arguments ob [].
+Arguments ob : clear implicits.
Instance dot_weq `{ops} n m p: Proper (weq ==> weq ==> weq) (dot n m p).
Proof.
diff --git a/test-suite/check b/test-suite/check
deleted file mode 100755
index 3d14f6bc..00000000
--- a/test-suite/check
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-MAKE="${MAKE:=make}"
-
-${MAKE} clean > /dev/null 2>&1
-${MAKE} all > /dev/null 2>&1
-cat summary.log
diff --git a/test-suite/complexity/injection.v b/test-suite/complexity/injection.v
index 08f489d7..a76fa19d 100644
--- a/test-suite/complexity/injection.v
+++ b/test-suite/complexity/injection.v
@@ -47,7 +47,7 @@ Parameter mkJoinmap : forall (key: Type) (t: Type) (j: joinable t),
joinmap key j.
Parameter ADMIT: forall p: Prop, p.
-Implicit Arguments ADMIT [p].
+Arguments ADMIT [p].
Module Share.
Parameter jb : joinable bool.
diff --git a/test-suite/coq-makefile/coqdoc1/run.sh b/test-suite/coq-makefile/coqdoc1/run.sh
index dc5a500d..88237815 100755
--- a/test-suite/coq-makefile/coqdoc1/run.sh
+++ b/test-suite/coq-makefile/coqdoc1/run.sh
@@ -9,7 +9,15 @@ make html mlihtml
make install DSTROOT="$PWD/tmp"
make install-doc DSTROOT="$PWD/tmp"
#make debug
-(for d in `find tmp -name user-contrib` ; do pushd $d >/dev/null && find . && popd >/dev/null; done) | sort -u > actual
+
+# to learn about <(cmd) see https://www.gnu.org/software/bash/manual/html_node/Process-Substitution.html
+(
+ while IFS= read -r -d '' d
+ do
+ pushd "$d" >/dev/null && find . && popd >/dev/null
+ done < <(find tmp -name user-contrib -print0)
+) | sort -u > actual
+
sort -u > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/coqdoc2/run.sh b/test-suite/coq-makefile/coqdoc2/run.sh
index dc5a500d..5811dd17 100755
--- a/test-suite/coq-makefile/coqdoc2/run.sh
+++ b/test-suite/coq-makefile/coqdoc2/run.sh
@@ -9,7 +9,13 @@ make html mlihtml
make install DSTROOT="$PWD/tmp"
make install-doc DSTROOT="$PWD/tmp"
#make debug
-(for d in `find tmp -name user-contrib` ; do pushd $d >/dev/null && find . && popd >/dev/null; done) | sort -u > actual
+(
+ while IFS= read -r -d '' d
+ do
+ pushd "$d" >/dev/null && find . && popd >/dev/null
+ done < <(find tmp -name user-contrib -print0)
+) | sort -u > actual
+
sort -u > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/findlib-package/run.sh b/test-suite/coq-makefile/findlib-package/run.sh
index 5b24df63..5cab400c 100755
--- a/test-suite/coq-makefile/findlib-package/run.sh
+++ b/test-suite/coq-makefile/findlib-package/run.sh
@@ -7,7 +7,8 @@ export OCAMLPATH=$OCAMLPATH:$PWD/findlib
if which cygpath 2>/dev/null; then
# the only way I found to pass OCAMLPATH on win is to have it contain
# only one entry
- export OCAMLPATH=`cygpath -w $PWD/findlib`
+ OCAMLPATH=$(cygpath -w "$PWD"/findlib)
+ export OCAMLPATH
fi
make -C findlib/foo clean
coq_makefile -f _CoqProject -o Makefile
diff --git a/test-suite/coq-makefile/mlpack1/run.sh b/test-suite/coq-makefile/mlpack1/run.sh
index 03df9cf0..bbd2fc46 100755
--- a/test-suite/coq-makefile/mlpack1/run.sh
+++ b/test-suite/coq-makefile/mlpack1/run.sh
@@ -8,7 +8,7 @@ make
make html mlihtml
make install DSTROOT="$PWD/tmp"
#make debug
-(cd `find tmp -name user-contrib` && find .) | sort > actual
+(cd "$(find tmp -name user-contrib)" && find .) | sort > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/mlpack2/run.sh b/test-suite/coq-makefile/mlpack2/run.sh
index 03df9cf0..bbd2fc46 100755
--- a/test-suite/coq-makefile/mlpack2/run.sh
+++ b/test-suite/coq-makefile/mlpack2/run.sh
@@ -8,7 +8,7 @@ make
make html mlihtml
make install DSTROOT="$PWD/tmp"
#make debug
-(cd `find tmp -name user-contrib` && find .) | sort > actual
+(cd "$(find tmp -name user-contrib)" && find .) | sort > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/multiroot/run.sh b/test-suite/coq-makefile/multiroot/run.sh
index d3bb5310..45bf1481 100755
--- a/test-suite/coq-makefile/multiroot/run.sh
+++ b/test-suite/coq-makefile/multiroot/run.sh
@@ -11,7 +11,12 @@ make html mlihtml
make install DSTROOT="$PWD/tmp"
make install-doc DSTROOT="$PWD/tmp"
#make debug
-(for d in `find tmp -name user-contrib` ; do pushd $d >/dev/null && find . && popd >/dev/null; done) | sort -u > actual
+(
+ while IFS= read -r -d '' d
+ do
+ pushd "$d" >/dev/null && find . && popd >/dev/null
+ done < <(find tmp -name user-contrib -print0)
+) | sort -u > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/native1/run.sh b/test-suite/coq-makefile/native1/run.sh
index 89bafe9a..8f9ab9a7 100755
--- a/test-suite/coq-makefile/native1/run.sh
+++ b/test-suite/coq-makefile/native1/run.sh
@@ -1,17 +1,17 @@
#!/usr/bin/env bash
-NATIVECOMP=`grep "let no_native_compiler = false" ../../../config/coq_config.ml`||true
-if [[ `which ocamlopt` && $NATIVECOMP ]]; then
+NATIVECOMP=$(grep "let no_native_compiler = false" ../../../config/coq_config.ml)||true
+if [[ $(which ocamlopt) && $NATIVECOMP ]]; then
. ../template/init.sh
-
+
coq_makefile -f _CoqProject -o Makefile
cat Makefile.conf
make
make html mlihtml
make install DSTROOT="$PWD/tmp"
#make debug
-(cd `find tmp -name user-contrib` && find .) | sort > actual
+(cd "$(find tmp -name user-contrib)" && find .) | sort > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/plugin1/run.sh b/test-suite/coq-makefile/plugin1/run.sh
index 5433d9e9..1e2bd979 100755
--- a/test-suite/coq-makefile/plugin1/run.sh
+++ b/test-suite/coq-makefile/plugin1/run.sh
@@ -9,7 +9,7 @@ make
make html mlihtml
make install DSTROOT="$PWD/tmp"
#make debug
-(cd `find tmp -name user-contrib` && find .) | sort > actual
+(cd "$(find tmp -name user-contrib)" && find .) | sort > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/plugin2/run.sh b/test-suite/coq-makefile/plugin2/run.sh
index 5433d9e9..1e2bd979 100755
--- a/test-suite/coq-makefile/plugin2/run.sh
+++ b/test-suite/coq-makefile/plugin2/run.sh
@@ -9,7 +9,7 @@ make
make html mlihtml
make install DSTROOT="$PWD/tmp"
#make debug
-(cd `find tmp -name user-contrib` && find .) | sort > actual
+(cd "$(find tmp -name user-contrib)" && find .) | sort > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/plugin3/run.sh b/test-suite/coq-makefile/plugin3/run.sh
index 5433d9e9..1e2bd979 100755
--- a/test-suite/coq-makefile/plugin3/run.sh
+++ b/test-suite/coq-makefile/plugin3/run.sh
@@ -9,7 +9,7 @@ make
make html mlihtml
make install DSTROOT="$PWD/tmp"
#make debug
-(cd `find tmp -name user-contrib` && find .) | sort > actual
+(cd "$(find tmp -name user-contrib)" && find .) | sort > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/quick2vo/run.sh b/test-suite/coq-makefile/quick2vo/run.sh
index 9e681223..dda51dd2 100755
--- a/test-suite/coq-makefile/quick2vo/run.sh
+++ b/test-suite/coq-makefile/quick2vo/run.sh
@@ -1,11 +1,11 @@
#!/usr/bin/env bash
-a=`uname`
+a=$(uname)
. ../template/init.sh
coq_makefile -f _CoqProject -o Makefile
# vio2vo is broken on Windows (#6720)
-if [ "$a" = "Darwin" -o "$a" = "Linux" ]; then
+if [ "$a" = "Darwin" ] || [ "$a" = "Linux" ]; then
make quick2vo J=2
test -f theories/test.vo
make validate
diff --git a/test-suite/coq-makefile/template/init.sh b/test-suite/coq-makefile/template/init.sh
index e19d168c..2e066d30 100755
--- a/test-suite/coq-makefile/template/init.sh
+++ b/test-suite/coq-makefile/template/init.sh
@@ -1,10 +1,11 @@
+#!/bin/sh
. ../template/path-init.sh
rm -rf _test
mkdir _test
find . -maxdepth 1 -not -name . -not -name _test -exec cp -r '{}' -t _test ';'
-cd _test
+cd _test || exit 1
mkdir -p src
mkdir -p theories/sub
diff --git a/test-suite/coq-makefile/template/path-init.sh b/test-suite/coq-makefile/template/path-init.sh
index dd19ab2b..c79b5665 100755
--- a/test-suite/coq-makefile/template/path-init.sh
+++ b/test-suite/coq-makefile/template/path-init.sh
@@ -1,3 +1,4 @@
+#!/bin/sh
set -e
set -o pipefail
diff --git a/test-suite/coq-makefile/timing/precomputed-time-tests/run.sh b/test-suite/coq-makefile/timing/precomputed-time-tests/run.sh
index a918cceb..9f3b648a 100755
--- a/test-suite/coq-makefile/timing/precomputed-time-tests/run.sh
+++ b/test-suite/coq-makefile/timing/precomputed-time-tests/run.sh
@@ -4,7 +4,8 @@ set -x
set -e
cd "$(dirname "${BASH_SOURCE[0]}")"
-export COQLIB="$(cd ../../../.. && pwd)"
+COQLIB="$(cd ../../../.. && pwd)"
+export COQLIB
-./001-correct-diff-sorting-order/run.sh || exit $?
-./002-single-file-sorting/run.sh || exit $?
+./001-correct-diff-sorting-order/run.sh
+./002-single-file-sorting/run.sh
diff --git a/test-suite/coq-makefile/timing/run.sh b/test-suite/coq-makefile/timing/run.sh
index f0e036ee..78a3f7c6 100755
--- a/test-suite/coq-makefile/timing/run.sh
+++ b/test-suite/coq-makefile/timing/run.sh
@@ -62,16 +62,14 @@ TO_SED_IN_PER_LINE=(
-e s'/ */ /g' # Sometimes 0 will show up as 0m00.s, sometimes it'll end up being more like 0m00.001s; we must strip out the spaces that result from left-aligning numbers of different widths based on how many digits Coq's [-time] gives
)
-for ext in "" .desired; do
- for file in time-of-build-before.log time-of-build-after.log time-of-build-both.log; do
- cat ${file}${ext} | grep -v 'warning: undefined variable' | sed "${TO_SED_IN_BOTH[@]}" "${TO_SED_IN_PER_FILE[@]}" > ${file}${ext}.processed
- done
-done
for file in time-of-build-before.log time-of-build-after.log time-of-build-both.log; do
- echo "cat $file"
- cat "$file"
- echo
- diff -u $file.desired.processed $file.processed || exit $?
+ for ext in "" .desired; do
+ grep -v 'warning: undefined variable' < ${file}${ext} | sed "${TO_SED_IN_BOTH[@]}" "${TO_SED_IN_PER_FILE[@]}" > ${file}${ext}.processed
+ done
+ echo "cat $file"
+ cat "$file"
+ echo
+ diff -u $file.desired.processed $file.processed || exit $?
done
cd ../per-file-before
@@ -96,13 +94,12 @@ echo "cat A.v.timing.diff"
cat A.v.timing.diff
echo
+file=A.v.timing.diff
+
for ext in "" .desired; do
- for file in A.v.timing.diff; do
- cat ${file}${ext} | sed "${TO_SED_IN_BOTH[@]}" "${TO_SED_IN_PER_LINE[@]}" | sort > ${file}${ext}.processed
- done
-done
-for file in A.v.timing.diff; do
- diff -u $file.desired.processed $file.processed || exit $?
+ sed "${TO_SED_IN_BOTH[@]}" "${TO_SED_IN_PER_LINE[@]}" < "${file}${ext}" | sort > "${file}${ext}.processed"
done
+diff -u "$file.desired.processed" "$file.processed" || exit $?
+
exit 0
diff --git a/test-suite/coq-makefile/uninstall1/run.sh b/test-suite/coq-makefile/uninstall1/run.sh
index 5354f794..fc95d84b 100755
--- a/test-suite/coq-makefile/uninstall1/run.sh
+++ b/test-suite/coq-makefile/uninstall1/run.sh
@@ -11,7 +11,12 @@ make install-doc DSTROOT="$PWD/tmp"
make uninstall DSTROOT="$PWD/tmp"
make uninstall-doc DSTROOT="$PWD/tmp"
#make debug
-(for d in `find tmp -name user-contrib` ; do pushd $d >/dev/null && find . && popd >/dev/null; done) | sort -u > actual
+(
+ while IFS= read -r -d '' d
+ do
+ pushd "$d" >/dev/null && find . && popd >/dev/null
+ done < <(find tmp -name user-contrib -print0)
+) | sort -u > actual
sort -u > desired <<EOT
.
EOT
diff --git a/test-suite/coq-makefile/uninstall2/run.sh b/test-suite/coq-makefile/uninstall2/run.sh
index 5354f794..fc95d84b 100755
--- a/test-suite/coq-makefile/uninstall2/run.sh
+++ b/test-suite/coq-makefile/uninstall2/run.sh
@@ -11,7 +11,12 @@ make install-doc DSTROOT="$PWD/tmp"
make uninstall DSTROOT="$PWD/tmp"
make uninstall-doc DSTROOT="$PWD/tmp"
#make debug
-(for d in `find tmp -name user-contrib` ; do pushd $d >/dev/null && find . && popd >/dev/null; done) | sort -u > actual
+(
+ while IFS= read -r -d '' d
+ do
+ pushd "$d" >/dev/null && find . && popd >/dev/null
+ done < <(find tmp -name user-contrib -print0)
+) | sort -u > actual
sort -u > desired <<EOT
.
EOT
diff --git a/test-suite/coq-makefile/vio2vo/run.sh b/test-suite/coq-makefile/vio2vo/run.sh
index 85656da4..e555d62f 100755
--- a/test-suite/coq-makefile/vio2vo/run.sh
+++ b/test-suite/coq-makefile/vio2vo/run.sh
@@ -1,12 +1,12 @@
#!/usr/bin/env bash
-a=`uname`
+a=$(uname)
. ../template/init.sh
coq_makefile -f _CoqProject -o Makefile
make quick
# vio2vo is broken on Windows (#6720)
-if [ "$a" = "Darwin" -o "$a" = "Linux" ]; then
+if [ "$a" = "Darwin" ] || [ "$a" = "Linux" ]; then
make vio2vo J=2
test -f theories/test.vo
make validate
diff --git a/test-suite/coqchk/bug_8655.v b/test-suite/coqchk/bug_8655.v
new file mode 100644
index 00000000..06d08b20
--- /dev/null
+++ b/test-suite/coqchk/bug_8655.v
@@ -0,0 +1 @@
+Inductive IND2 (A:Type) (T:=fun _ : Type->Type => A) := CONS2 : IND2 A -> IND2 (T IND2).
diff --git a/test-suite/coqchk/bug_8876.v b/test-suite/coqchk/bug_8876.v
new file mode 100644
index 00000000..2d20511a
--- /dev/null
+++ b/test-suite/coqchk/bug_8876.v
@@ -0,0 +1,19 @@
+(* -*- coq-prog-args: ("-noinit"); -*- *)
+Require Import Coq.Init.Notations.
+
+Notation "x -> y" := (forall _ : x, y).
+
+Inductive eq {A:Type} (a:A) : A -> Prop := eq_refl : eq a a.
+
+Set Universe Polymorphism.
+Set Polymorphic Inductive Cumulativity.
+Set Printing Universes.
+
+(* Constructors for an inductive with indices *)
+Module WithIndex.
+ Inductive foo@{i} : (Prop -> Prop) -> Prop := mkfoo: foo (fun x => x).
+
+ Monomorphic Universes i j.
+ Monomorphic Constraint i < j.
+ Definition bar : eq mkfoo@{i} mkfoo@{j} := eq_refl _.
+End WithIndex.
diff --git a/test-suite/coqchk/bug_8881.v b/test-suite/coqchk/bug_8881.v
new file mode 100644
index 00000000..dfc209b3
--- /dev/null
+++ b/test-suite/coqchk/bug_8881.v
@@ -0,0 +1,23 @@
+
+(* Check use of equivalence on inductive types (bug #1242) *)
+
+Module Type ASIG.
+ Inductive t : Set := a | b : t.
+ Definition f := fun x => match x with a => true | b => false end.
+End ASIG.
+
+Module Type BSIG.
+ Declare Module A : ASIG.
+ Definition f := fun x => match x with A.a => true | A.b => false end.
+End BSIG.
+
+Module C (A : ASIG) (B : BSIG with Module A:=A).
+
+ (* Check equivalence is considered in "case_info" *)
+ Lemma test : forall x, A.f x = B.f x.
+ Proof.
+ intro x. unfold B.f, A.f.
+ destruct x; reflexivity.
+ Qed.
+
+End C.
diff --git a/test-suite/coqchk/include_primproj.v b/test-suite/coqchk/include_primproj.v
new file mode 100644
index 00000000..804ba1d3
--- /dev/null
+++ b/test-suite/coqchk/include_primproj.v
@@ -0,0 +1,13 @@
+(* #7329 *)
+Set Primitive Projections.
+
+Module M.
+ Module Bar.
+ Record Box := box { unbox : Type }.
+
+ Axiom foo : Box.
+ Axiom baz : forall _ : unbox foo, unbox foo.
+ End Bar.
+End M.
+
+Include M.
diff --git a/test-suite/coqdoc/links.html.out b/test-suite/coqdoc/links.html.out
index 5e4b676c..d2d4d5d7 100644
--- a/test-suite/coqdoc/links.html.out
+++ b/test-suite/coqdoc/links.html.out
@@ -60,32 +60,32 @@ Various checks for coqdoc
<span class="id" title="keyword">Definition</span> <a name="f"><span class="id" title="definition">f</span></a> := <span class="id" title="keyword">∀</span> <span class="id" title="var">C</span>:<span class="id" title="keyword">Prop</span>, <a class="idref" href="Coqdoc.links.html#C"><span class="id" title="variable">C</span></a>.<br/>
<br/>
-<span class="id" title="keyword">Notation</span> <a name="1a1c7f13320341c3638e9edcc3e6389d"><span class="id" title="notation">&quot;</span></a>n ++ m" := (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#plus"><span class="id" title="abbreviation">plus</span></a> <span class="id" title="var">n</span> <span class="id" title="var">m</span>).<br/>
+<span class="id" title="keyword">Notation</span> <a name="f03f7a04ef75ff3ac66ca5c23554e52e"><span class="id" title="notation">&quot;</span></a>n ++ m" := (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#plus"><span class="id" title="abbreviation">plus</span></a> <span class="id" title="var">n</span> <span class="id" title="var">m</span>).<br/>
<br/>
-<span class="id" title="keyword">Notation</span> <a name="1a1c7f13320341c3638e9edcc3e6389d"><span class="id" title="notation">&quot;</span></a>n ++ m" := (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#mult"><span class="id" title="abbreviation">mult</span></a> <span class="id" title="var">n</span> <span class="id" title="var">m</span>).
+<span class="id" title="keyword">Notation</span> <a name="f03f7a04ef75ff3ac66ca5c23554e52e"><span class="id" title="notation">&quot;</span></a>n ++ m" := (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#mult"><span class="id" title="abbreviation">mult</span></a> <span class="id" title="var">n</span> <span class="id" title="var">m</span>).
<br/>
-<span class="id" title="keyword">Notation</span> <a name="6b97e27793a3d22f5c0d1dd63170fd68"><span class="id" title="notation">&quot;</span></a>n ** m" := (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#plus"><span class="id" title="abbreviation">plus</span></a> <span class="id" title="var">n</span> <span class="id" title="var">m</span>) (<span class="id" title="tactic">at</span> <span class="id" title="keyword">level</span> 60).<br/>
+<span class="id" title="keyword">Notation</span> <a name="f07b3676d96b68749d342542fd80e2b0"><span class="id" title="notation">&quot;</span></a>n ** m" := (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#plus"><span class="id" title="abbreviation">plus</span></a> <span class="id" title="var">n</span> <span class="id" title="var">m</span>) (<span class="id" title="tactic">at</span> <span class="id" title="keyword">level</span> 60).<br/>
<br/>
-<span class="id" title="keyword">Notation</span> <a name="3e01fbae4590c7b7699ff99ce61580e1"><span class="id" title="notation">&quot;</span></a>n ▵ m" := (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#plus"><span class="id" title="abbreviation">plus</span></a> <span class="id" title="var">n</span> <span class="id" title="var">m</span>) (<span class="id" title="tactic">at</span> <span class="id" title="keyword">level</span> 60).<br/>
+<span class="id" title="keyword">Notation</span> <a name="a647c51c9816a1b44fcfa5312db8344a"><span class="id" title="notation">&quot;</span></a>n ▵ m" := (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#plus"><span class="id" title="abbreviation">plus</span></a> <span class="id" title="var">n</span> <span class="id" title="var">m</span>) (<span class="id" title="tactic">at</span> <span class="id" title="keyword">level</span> 60).<br/>
<br/>
-<span class="id" title="keyword">Notation</span> <a name="347f39a83bf7d45676cff54fd7e8966f"><span class="id" title="notation">&quot;</span></a>n '_' ++ 'x' m" := (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#plus"><span class="id" title="abbreviation">plus</span></a> <span class="id" title="var">n</span> <span class="id" title="var">m</span>) (<span class="id" title="tactic">at</span> <span class="id" title="keyword">level</span> 3).<br/>
+<span class="id" title="keyword">Notation</span> <a name="3dd9eae9daa65efe5444f5fc3529a2e7"><span class="id" title="notation">&quot;</span></a>n '_' ++ 'x' m" := (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#plus"><span class="id" title="abbreviation">plus</span></a> <span class="id" title="var">n</span> <span class="id" title="var">m</span>) (<span class="id" title="tactic">at</span> <span class="id" title="keyword">level</span> 3).<br/>
<br/>
-<span class="id" title="keyword">Inductive</span> <a name="eq"><span class="id" title="inductive">eq</span></a> (<span class="id" title="var">A</span>:<span class="id" title="keyword">Type</span>) (<span class="id" title="var">x</span>:<a class="idref" href="Coqdoc.links.html#A"><span class="id" title="variable">A</span></a>) : <span class="id" title="var">A</span> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Logic.html#d43e996736952df71ebeeae74d10a287"><span class="id" title="notation">→</span></a> <span class="id" title="keyword">Prop</span> := <a name="eq_refl"><span class="id" title="constructor">eq_refl</span></a> : <a class="idref" href="Coqdoc.links.html#x"><span class="id" title="variable">x</span></a> <a class="idref" href="Coqdoc.links.html#8f9364556521ebb498093f28eea2240f"><span class="id" title="notation">=</span></a> <a class="idref" href="Coqdoc.links.html#x"><span class="id" title="variable">x</span></a> <a class="idref" href="Coqdoc.links.html#8f9364556521ebb498093f28eea2240f"><span class="id" title="notation">:&gt;</span></a><a class="idref" href="Coqdoc.links.html#A"><span class="id" title="variable">A</span></a><br/>
+<span class="id" title="keyword">Inductive</span> <a name="eq"><span class="id" title="inductive">eq</span></a> (<span class="id" title="var">A</span>:<span class="id" title="keyword">Type</span>) (<span class="id" title="var">x</span>:<a class="idref" href="Coqdoc.links.html#A"><span class="id" title="variable">A</span></a>) : <span class="id" title="var">A</span> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Logic.html#1c93e43e07fbeaeb6a625cb6614beb5d"><span class="id" title="notation">→</span></a> <span class="id" title="keyword">Prop</span> := <a name="eq_refl"><span class="id" title="constructor">eq_refl</span></a> : <a class="idref" href="Coqdoc.links.html#x"><span class="id" title="variable">x</span></a> <a class="idref" href="Coqdoc.links.html#b8b2ebc8e1a8b9aa935c0702efb5dccf"><span class="id" title="notation">=</span></a> <a class="idref" href="Coqdoc.links.html#x"><span class="id" title="variable">x</span></a> <a class="idref" href="Coqdoc.links.html#b8b2ebc8e1a8b9aa935c0702efb5dccf"><span class="id" title="notation">:&gt;</span></a><a class="idref" href="Coqdoc.links.html#A"><span class="id" title="variable">A</span></a><br/>
<br/>
-<span class="id" title="keyword">where</span> <a name="8f9364556521ebb498093f28eea2240f"><span class="id" title="notation">&quot;</span></a>x = y :&gt; A" := (@<a class="idref" href="Coqdoc.links.html#eq"><span class="id" title="inductive">eq</span></a> <span class="id" title="var">A</span> <span class="id" title="var">x</span> <span class="id" title="var">y</span>) : <span class="id" title="var">type_scope</span>.<br/>
+<span class="id" title="keyword">where</span> <a name="b8b2ebc8e1a8b9aa935c0702efb5dccf"><span class="id" title="notation">&quot;</span></a>x = y :&gt; A" := (@<a class="idref" href="Coqdoc.links.html#eq"><span class="id" title="inductive">eq</span></a> <span class="id" title="var">A</span> <span class="id" title="var">x</span> <span class="id" title="var">y</span>) : <span class="id" title="var">type_scope</span>.<br/>
<br/>
-<span class="id" title="keyword">Definition</span> <a name="eq0"><span class="id" title="definition">eq0</span></a> := 0 <a class="idref" href="Coqdoc.links.html#8f9364556521ebb498093f28eea2240f"><span class="id" title="notation">=</span></a> 0 <a class="idref" href="Coqdoc.links.html#8f9364556521ebb498093f28eea2240f"><span class="id" title="notation">:&gt;</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#nat"><span class="id" title="inductive">nat</span></a>.<br/>
+<span class="id" title="keyword">Definition</span> <a name="eq0"><span class="id" title="definition">eq0</span></a> := 0 <a class="idref" href="Coqdoc.links.html#b8b2ebc8e1a8b9aa935c0702efb5dccf"><span class="id" title="notation">=</span></a> 0 <a class="idref" href="Coqdoc.links.html#b8b2ebc8e1a8b9aa935c0702efb5dccf"><span class="id" title="notation">:&gt;</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#nat"><span class="id" title="inductive">nat</span></a>.<br/>
<br/>
-<span class="id" title="keyword">Notation</span> <a name="548d1059c499c9b2a9b95b07e68c2090"><span class="id" title="notation">&quot;</span></a>( x # y ; .. ; z )" := (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#pair"><span class="id" title="constructor">pair</span></a> .. (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#pair"><span class="id" title="constructor">pair</span></a> <span class="id" title="var">x</span> <span class="id" title="var">y</span>) .. <span class="id" title="var">z</span>).<br/>
+<span class="id" title="keyword">Notation</span> <a name="2c0c193cd2aedf7ecdb713db64dbfce6"><span class="id" title="notation">&quot;</span></a>( x # y ; .. ; z )" := (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#pair"><span class="id" title="constructor">pair</span></a> .. (<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#pair"><span class="id" title="constructor">pair</span></a> <span class="id" title="var">x</span> <span class="id" title="var">y</span>) .. <span class="id" title="var">z</span>).<br/>
<br/>
-<span class="id" title="keyword">Definition</span> <a name="9f5a1d89cbd4d38f5e289576db7123d1"><span class="id" title="definition">b_α</span></a> := <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#44400027531d4bc3f586a1997dc874c0"><span class="id" title="notation">(</span></a><a class="idref" href="Coqdoc.links.html#548d1059c499c9b2a9b95b07e68c2090"><span class="id" title="notation">(</span></a>0<a class="idref" href="Coqdoc.links.html#548d1059c499c9b2a9b95b07e68c2090"><span class="id" title="notation">#</span></a>0<a class="idref" href="Coqdoc.links.html#548d1059c499c9b2a9b95b07e68c2090"><span class="id" title="notation">;</span></a>0<a class="idref" href="Coqdoc.links.html#548d1059c499c9b2a9b95b07e68c2090"><span class="id" title="notation">)</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#44400027531d4bc3f586a1997dc874c0"><span class="id" title="notation">,</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#44400027531d4bc3f586a1997dc874c0"><span class="id" title="notation">(</span></a>0 <a class="idref" href="Coqdoc.links.html#6b97e27793a3d22f5c0d1dd63170fd68"><span class="id" title="notation">**</span></a> 0<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#44400027531d4bc3f586a1997dc874c0"><span class="id" title="notation">))</span></a>.<br/>
+<span class="id" title="keyword">Definition</span> <a name="9f5a1d89cbd4d38f5e289576db7123d1"><span class="id" title="definition">b_α</span></a> := <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#e6756e10c36f149b18b4a8741ed83079"><span class="id" title="notation">(</span></a><a class="idref" href="Coqdoc.links.html#2c0c193cd2aedf7ecdb713db64dbfce6"><span class="id" title="notation">(</span></a>0<a class="idref" href="Coqdoc.links.html#2c0c193cd2aedf7ecdb713db64dbfce6"><span class="id" title="notation">#</span></a>0<a class="idref" href="Coqdoc.links.html#2c0c193cd2aedf7ecdb713db64dbfce6"><span class="id" title="notation">;</span></a>0<a class="idref" href="Coqdoc.links.html#2c0c193cd2aedf7ecdb713db64dbfce6"><span class="id" title="notation">)</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#e6756e10c36f149b18b4a8741ed83079"><span class="id" title="notation">,</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#e6756e10c36f149b18b4a8741ed83079"><span class="id" title="notation">(</span></a>0 <a class="idref" href="Coqdoc.links.html#f07b3676d96b68749d342542fd80e2b0"><span class="id" title="notation">**</span></a> 0<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#e6756e10c36f149b18b4a8741ed83079"><span class="id" title="notation">))</span></a>.<br/>
<br/>
<span class="id" title="keyword">Notation</span> <a name="h"><span class="id" title="abbreviation">h</span></a> := <a class="idref" href="Coqdoc.links.html#a"><span class="id" title="definition">a</span></a>.<br/>
@@ -97,7 +97,7 @@ Various checks for coqdoc
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Variables</span> <a name="test.b'"><span class="id" title="variable">b'</span></a> <a name="test.b2"><span class="id" title="variable">b2</span></a>: <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#nat"><span class="id" title="inductive">nat</span></a>.<br/>
<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Notation</span> <a name="4ab0449b36c75cf94e08c5822ea83e3d"><span class="id" title="notation">&quot;</span></a>n + m" := (<span class="id" title="var">n</span> <a class="idref" href="Coqdoc.links.html#3e01fbae4590c7b7699ff99ce61580e1"><span class="id" title="notation">▵</span></a> <span class="id" title="var">m</span>) : <span class="id" title="var">my_scope</span>.<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Notation</span> <a name="2158f15740ce05a939b657be222c26d6"><span class="id" title="notation">&quot;</span></a>n + m" := (<span class="id" title="var">n</span> <a class="idref" href="Coqdoc.links.html#a647c51c9816a1b44fcfa5312db8344a"><span class="id" title="notation">▵</span></a> <span class="id" title="var">m</span>) : <span class="id" title="var">my_scope</span>.<br/>
<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Delimit</span> <span class="id" title="keyword">Scope</span> <span class="id" title="var">my_scope</span> <span class="id" title="keyword">with</span> <span class="id" title="var">my</span>.<br/>
@@ -106,19 +106,19 @@ Various checks for coqdoc
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Notation</span> <a name="l"><span class="id" title="abbreviation">l</span></a> := 0.<br/>
<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Definition</span> <a name="ab410a966ac148e9b78c65c6cdf301fd"><span class="id" title="definition">α</span></a> := (0 <a class="idref" href="Coqdoc.links.html#4ab0449b36c75cf94e08c5822ea83e3d"><span class="id" title="notation">+</span></a> <a class="idref" href="Coqdoc.links.html#l"><span class="id" title="abbreviation">l</span></a>)%<span class="id" title="var">my</span>.<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Definition</span> <a name="ab410a966ac148e9b78c65c6cdf301fd"><span class="id" title="definition">α</span></a> := (0 <a class="idref" href="Coqdoc.links.html#2158f15740ce05a939b657be222c26d6"><span class="id" title="notation">+</span></a> <a class="idref" href="Coqdoc.links.html#l"><span class="id" title="abbreviation">l</span></a>)%<span class="id" title="var">my</span>.<br/>
<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Definition</span> <a name="a'"><span class="id" title="definition">a'</span></a> <span class="id" title="var">b</span> := <a class="idref" href="Coqdoc.links.html#test.b'"><span class="id" title="variable">b'</span></a><a class="idref" href="Coqdoc.links.html#1a1c7f13320341c3638e9edcc3e6389d"><span class="id" title="notation">++</span></a>0<a class="idref" href="Coqdoc.links.html#1a1c7f13320341c3638e9edcc3e6389d"><span class="id" title="notation">++</span></a><a class="idref" href="Coqdoc.links.html#test.b2"><span class="id" title="variable">b2</span></a> <a class="idref" href="Coqdoc.links.html#347f39a83bf7d45676cff54fd7e8966f"><span class="id" title="notation">_</span></a> <a class="idref" href="Coqdoc.links.html#347f39a83bf7d45676cff54fd7e8966f"><span class="id" title="notation">++</span></a><a class="idref" href="Coqdoc.links.html#347f39a83bf7d45676cff54fd7e8966f"><span class="id" title="notation">x</span></a> <a class="idref" href="Coqdoc.links.html#b"><span class="id" title="variable">b</span></a>.<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Definition</span> <a name="a'"><span class="id" title="definition">a'</span></a> <span class="id" title="var">b</span> := <a class="idref" href="Coqdoc.links.html#test.b'"><span class="id" title="variable">b'</span></a><a class="idref" href="Coqdoc.links.html#f03f7a04ef75ff3ac66ca5c23554e52e"><span class="id" title="notation">++</span></a>0<a class="idref" href="Coqdoc.links.html#f03f7a04ef75ff3ac66ca5c23554e52e"><span class="id" title="notation">++</span></a><a class="idref" href="Coqdoc.links.html#test.b2"><span class="id" title="variable">b2</span></a> <a class="idref" href="Coqdoc.links.html#3dd9eae9daa65efe5444f5fc3529a2e7"><span class="id" title="notation">_</span></a> <a class="idref" href="Coqdoc.links.html#3dd9eae9daa65efe5444f5fc3529a2e7"><span class="id" title="notation">++</span></a><a class="idref" href="Coqdoc.links.html#3dd9eae9daa65efe5444f5fc3529a2e7"><span class="id" title="notation">x</span></a> <a class="idref" href="Coqdoc.links.html#b"><span class="id" title="variable">b</span></a>.<br/>
<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Definition</span> <a name="c"><span class="id" title="definition">c</span></a> := <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Specif.html#5bf2050e90b21ebc82dc5463d1ba338e"><span class="id" title="notation">{</span></a><a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Logic.html#True"><span class="id" title="inductive">True</span></a><a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Specif.html#5bf2050e90b21ebc82dc5463d1ba338e"><span class="id" title="notation">}+{</span></a><a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Logic.html#True"><span class="id" title="inductive">True</span></a><a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Specif.html#5bf2050e90b21ebc82dc5463d1ba338e"><span class="id" title="notation">}</span></a>.<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Definition</span> <a name="c"><span class="id" title="definition">c</span></a> := <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Specif.html#87727981cdc1579fef00b9d9c1d3b9da"><span class="id" title="notation">{</span></a><a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Logic.html#True"><span class="id" title="inductive">True</span></a><a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Specif.html#87727981cdc1579fef00b9d9c1d3b9da"><span class="id" title="notation">}+{</span></a><a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Logic.html#True"><span class="id" title="inductive">True</span></a><a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Specif.html#87727981cdc1579fef00b9d9c1d3b9da"><span class="id" title="notation">}</span></a>.<br/>
<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Definition</span> <a name="d"><span class="id" title="definition">d</span></a> := (1<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#b3eea360671e1b32b18a26e15b3aace3"><span class="id" title="notation">+</span></a>2)%<span class="id" title="var">nat</span>.<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Definition</span> <a name="d"><span class="id" title="definition">d</span></a> := (1<a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#0dacc1786c5ba797d47dd85006231633"><span class="id" title="notation">+</span></a>2)%<span class="id" title="var">nat</span>.<br/>
<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Lemma</span> <a name="e"><span class="id" title="lemma">e</span></a> : <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#nat"><span class="id" title="inductive">nat</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#3dcaec3b772747610227247939f96b01"><span class="id" title="notation">+</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#nat"><span class="id" title="inductive">nat</span></a>.<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Lemma</span> <a name="e"><span class="id" title="lemma">e</span></a> : <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#nat"><span class="id" title="inductive">nat</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#e03f39daf98516fa530d3f6f5a1b4d92"><span class="id" title="notation">+</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#nat"><span class="id" title="inductive">nat</span></a>.<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="var">Admitted</span>.<br/>
<br/>
@@ -137,7 +137,7 @@ Various checks for coqdoc
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Variables</span> <a name="test2.test.b2"><span class="id" title="variable">b2</span></a>: <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#nat"><span class="id" title="inductive">nat</span></a>.<br/>
<br/>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Definition</span> <a name="a''"><span class="id" title="definition">a''</span></a> <span class="id" title="var">b</span> := <a class="idref" href="Coqdoc.links.html#test2.b'"><span class="id" title="variable">b'</span></a> <a class="idref" href="Coqdoc.links.html#1a1c7f13320341c3638e9edcc3e6389d"><span class="id" title="notation">++</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#O"><span class="id" title="constructor">O</span></a> <a class="idref" href="Coqdoc.links.html#1a1c7f13320341c3638e9edcc3e6389d"><span class="id" title="notation">++</span></a> <a class="idref" href="Coqdoc.links.html#test2.test.b2"><span class="id" title="variable">b2</span></a> <a class="idref" href="Coqdoc.links.html#347f39a83bf7d45676cff54fd7e8966f"><span class="id" title="notation">_</span></a> <a class="idref" href="Coqdoc.links.html#347f39a83bf7d45676cff54fd7e8966f"><span class="id" title="notation">++</span></a> <a class="idref" href="Coqdoc.links.html#347f39a83bf7d45676cff54fd7e8966f"><span class="id" title="notation">x</span></a> <a class="idref" href="Coqdoc.links.html#b"><span class="id" title="variable">b</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#b3eea360671e1b32b18a26e15b3aace3"><span class="id" title="notation">+</span></a> <a class="idref" href="Coqdoc.links.html#h"><span class="id" title="abbreviation">h</span></a> 0.<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">Definition</span> <a name="a''"><span class="id" title="definition">a''</span></a> <span class="id" title="var">b</span> := <a class="idref" href="Coqdoc.links.html#test2.b'"><span class="id" title="variable">b'</span></a> <a class="idref" href="Coqdoc.links.html#f03f7a04ef75ff3ac66ca5c23554e52e"><span class="id" title="notation">++</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html#O"><span class="id" title="constructor">O</span></a> <a class="idref" href="Coqdoc.links.html#f03f7a04ef75ff3ac66ca5c23554e52e"><span class="id" title="notation">++</span></a> <a class="idref" href="Coqdoc.links.html#test2.test.b2"><span class="id" title="variable">b2</span></a> <a class="idref" href="Coqdoc.links.html#3dd9eae9daa65efe5444f5fc3529a2e7"><span class="id" title="notation">_</span></a> <a class="idref" href="Coqdoc.links.html#3dd9eae9daa65efe5444f5fc3529a2e7"><span class="id" title="notation">++</span></a> <a class="idref" href="Coqdoc.links.html#3dd9eae9daa65efe5444f5fc3529a2e7"><span class="id" title="notation">x</span></a> <a class="idref" href="Coqdoc.links.html#b"><span class="id" title="variable">b</span></a> <a class="idref" href="http://coq.inria.fr/stdlib/Coq.Init.Peano.html#0dacc1786c5ba797d47dd85006231633"><span class="id" title="notation">+</span></a> <a class="idref" href="Coqdoc.links.html#h"><span class="id" title="abbreviation">h</span></a> 0.<br/>
<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" title="keyword">End</span> <a class="idref" href="Coqdoc.links.html#test2.test"><span class="id" title="section">test</span></a>.<br/>
diff --git a/test-suite/coqdoc/links.tex.out b/test-suite/coqdoc/links.tex.out
index f42db99d..24f96ff1 100644
--- a/test-suite/coqdoc/links.tex.out
+++ b/test-suite/coqdoc/links.tex.out
@@ -51,34 +51,34 @@ Various checks for coqdoc
\coqdockw{Definition} \coqdef{Coqdoc.links.f}{f}{\coqdocdefinition{f}} := \coqdockw{\ensuremath{\forall}} \coqdocvar{C}:\coqdockw{Prop}, \coqdocvariable{C}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
-\coqdockw{Notation} \coqdef{Coqdoc.links.::x '++' x}{"}{"}n ++ m" := (\coqexternalref{plus}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocabbreviation{plus}} \coqdocvar{n} \coqdocvar{m}).\coqdoceol
+\coqdockw{Notation} \coqdef{Coqdoc.links.:::x '++' x}{"}{"}n ++ m" := (\coqexternalref{plus}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocabbreviation{plus}} \coqdocvar{n} \coqdocvar{m}).\coqdoceol
\coqdocemptyline
\coqdocnoindent
-\coqdockw{Notation} \coqdef{Coqdoc.links.::x '++' x}{"}{"}n ++ m" := (\coqexternalref{mult}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocabbreviation{mult}} \coqdocvar{n} \coqdocvar{m}). \coqdocemptyline
+\coqdockw{Notation} \coqdef{Coqdoc.links.:::x '++' x}{"}{"}n ++ m" := (\coqexternalref{mult}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocabbreviation{mult}} \coqdocvar{n} \coqdocvar{m}). \coqdocemptyline
\coqdocnoindent
-\coqdockw{Notation} \coqdef{Coqdoc.links.::x '**' x}{"}{"}n ** m" := (\coqexternalref{plus}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocabbreviation{plus}} \coqdocvar{n} \coqdocvar{m}) (\coqdoctac{at} \coqdockw{level} 60).\coqdoceol
+\coqdockw{Notation} \coqdef{Coqdoc.links.:::x '**' x}{"}{"}n ** m" := (\coqexternalref{plus}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocabbreviation{plus}} \coqdocvar{n} \coqdocvar{m}) (\coqdoctac{at} \coqdockw{level} 60).\coqdoceol
\coqdocemptyline
\coqdocnoindent
-\coqdockw{Notation} \coqdef{Coqdoc.links.::x 'xE2x96xB5' x}{"}{"}n ▵ m" := (\coqexternalref{plus}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocabbreviation{plus}} \coqdocvar{n} \coqdocvar{m}) (\coqdoctac{at} \coqdockw{level} 60).\coqdoceol
+\coqdockw{Notation} \coqdef{Coqdoc.links.:::x 'xE2x96xB5' x}{"}{"}n ▵ m" := (\coqexternalref{plus}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocabbreviation{plus}} \coqdocvar{n} \coqdocvar{m}) (\coqdoctac{at} \coqdockw{level} 60).\coqdoceol
\coqdocemptyline
\coqdocnoindent
-\coqdockw{Notation} \coqdef{Coqdoc.links.::x ''' ''' '++' 'x' x}{"}{"}n '\_' ++ 'x' m" := (\coqexternalref{plus}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocabbreviation{plus}} \coqdocvar{n} \coqdocvar{m}) (\coqdoctac{at} \coqdockw{level} 3).\coqdoceol
+\coqdockw{Notation} \coqdef{Coqdoc.links.:::x ''' ''' '++' 'x' x}{"}{"}n '\_' ++ 'x' m" := (\coqexternalref{plus}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocabbreviation{plus}} \coqdocvar{n} \coqdocvar{m}) (\coqdoctac{at} \coqdockw{level} 3).\coqdoceol
\coqdocemptyline
\coqdocnoindent
-\coqdockw{Inductive} \coqdef{Coqdoc.links.eq}{eq}{\coqdocinductive{eq}} (\coqdocvar{A}:\coqdockw{Type}) (\coqdocvar{x}:\coqdocvariable{A}) : \coqdocvar{A} \coqexternalref{:type scope:x '->' x}{http://coq.inria.fr/stdlib/Coq.Init.Logic}{\coqdocnotation{\ensuremath{\rightarrow}}} \coqdockw{Prop} := \coqdef{Coqdoc.links.eq refl}{eq\_refl}{\coqdocconstructor{eq\_refl}} : \coqdocvariable{x} \coqref{Coqdoc.links.:type scope:x '=' x ':>' x}{\coqdocnotation{=}} \coqdocvariable{x} \coqref{Coqdoc.links.:type scope:x '=' x ':>' x}{\coqdocnotation{:>}}\coqdocvariable{A}\coqdoceol
+\coqdockw{Inductive} \coqdef{Coqdoc.links.eq}{eq}{\coqdocinductive{eq}} (\coqdocvar{A}:\coqdockw{Type}) (\coqdocvar{x}:\coqdocvariable{A}) : \coqdocvar{A} \coqexternalref{::type scope:x '->' x}{http://coq.inria.fr/stdlib/Coq.Init.Logic}{\coqdocnotation{\ensuremath{\rightarrow}}} \coqdockw{Prop} := \coqdef{Coqdoc.links.eq refl}{eq\_refl}{\coqdocconstructor{eq\_refl}} : \coqdocvariable{x} \coqref{Coqdoc.links.::type scope:x '=' x ':>' x}{\coqdocnotation{=}} \coqdocvariable{x} \coqref{Coqdoc.links.::type scope:x '=' x ':>' x}{\coqdocnotation{:>}}\coqdocvariable{A}\coqdoceol
\coqdocnoindent
\coqdoceol
\coqdocnoindent
-\coqdockw{where} \coqdef{Coqdoc.links.:type scope:x '=' x ':>' x}{"}{"}x = y :> A" := (@\coqref{Coqdoc.links.eq}{\coqdocinductive{eq}} \coqdocvar{A} \coqdocvar{x} \coqdocvar{y}) : \coqdocvar{type\_scope}.\coqdoceol
+\coqdockw{where} \coqdef{Coqdoc.links.::type scope:x '=' x ':>' x}{"}{"}x = y :> A" := (@\coqref{Coqdoc.links.eq}{\coqdocinductive{eq}} \coqdocvar{A} \coqdocvar{x} \coqdocvar{y}) : \coqdocvar{type\_scope}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
-\coqdockw{Definition} \coqdef{Coqdoc.links.eq0}{eq0}{\coqdocdefinition{eq0}} := 0 \coqref{Coqdoc.links.:type scope:x '=' x ':>' x}{\coqdocnotation{=}} 0 \coqref{Coqdoc.links.:type scope:x '=' x ':>' x}{\coqdocnotation{:>}} \coqexternalref{nat}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocinductive{nat}}.\coqdoceol
+\coqdockw{Definition} \coqdef{Coqdoc.links.eq0}{eq0}{\coqdocdefinition{eq0}} := 0 \coqref{Coqdoc.links.::type scope:x '=' x ':>' x}{\coqdocnotation{=}} 0 \coqref{Coqdoc.links.::type scope:x '=' x ':>' x}{\coqdocnotation{:>}} \coqexternalref{nat}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocinductive{nat}}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
-\coqdockw{Notation} \coqdef{Coqdoc.links.::'(' x 'x23' x ';' '..' ';' x ')'}{"}{"}( x \# y ; .. ; z )" := (\coqexternalref{pair}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocconstructor{pair}} .. (\coqexternalref{pair}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocconstructor{pair}} \coqdocvar{x} \coqdocvar{y}) .. \coqdocvar{z}).\coqdoceol
+\coqdockw{Notation} \coqdef{Coqdoc.links.:::'(' x 'x23' x ';' '..' ';' x ')'}{"}{"}( x \# y ; .. ; z )" := (\coqexternalref{pair}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocconstructor{pair}} .. (\coqexternalref{pair}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocconstructor{pair}} \coqdocvar{x} \coqdocvar{y}) .. \coqdocvar{z}).\coqdoceol
\coqdocemptyline
\coqdocnoindent
-\coqdockw{Definition} \coqdef{Coqdoc.links.b xCExB1}{b\_α}{\coqdocdefinition{b\_α}} := \coqexternalref{:core scope:'(' x ',' x ',' '..' ',' x ')'}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocnotation{(}}\coqref{Coqdoc.links.::'(' x 'x23' x ';' '..' ';' x ')'}{\coqdocnotation{(}}0\coqref{Coqdoc.links.::'(' x 'x23' x ';' '..' ';' x ')'}{\coqdocnotation{\#}}0\coqref{Coqdoc.links.::'(' x 'x23' x ';' '..' ';' x ')'}{\coqdocnotation{;}}0\coqref{Coqdoc.links.::'(' x 'x23' x ';' '..' ';' x ')'}{\coqdocnotation{)}} \coqexternalref{:core scope:'(' x ',' x ',' '..' ',' x ')'}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocnotation{,}} \coqexternalref{:core scope:'(' x ',' x ',' '..' ',' x ')'}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocnotation{(}}0 \coqref{Coqdoc.links.::x '**' x}{\coqdocnotation{**}} 0\coqexternalref{:core scope:'(' x ',' x ',' '..' ',' x ')'}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocnotation{))}}.\coqdoceol
+\coqdockw{Definition} \coqdef{Coqdoc.links.b xCExB1}{b\_α}{\coqdocdefinition{b\_α}} := \coqexternalref{::core scope:'(' x ',' x ',' '..' ',' x ')'}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocnotation{(}}\coqref{Coqdoc.links.:::'(' x 'x23' x ';' '..' ';' x ')'}{\coqdocnotation{(}}0\coqref{Coqdoc.links.:::'(' x 'x23' x ';' '..' ';' x ')'}{\coqdocnotation{\#}}0\coqref{Coqdoc.links.:::'(' x 'x23' x ';' '..' ';' x ')'}{\coqdocnotation{;}}0\coqref{Coqdoc.links.:::'(' x 'x23' x ';' '..' ';' x ')'}{\coqdocnotation{)}} \coqexternalref{::core scope:'(' x ',' x ',' '..' ',' x ')'}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocnotation{,}} \coqexternalref{::core scope:'(' x ',' x ',' '..' ',' x ')'}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocnotation{(}}0 \coqref{Coqdoc.links.:::x '**' x}{\coqdocnotation{**}} 0\coqexternalref{::core scope:'(' x ',' x ',' '..' ',' x ')'}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocnotation{))}}.\coqdoceol
\coqdocemptyline
\coqdocnoindent
\coqdockw{Notation} \coqdef{Coqdoc.links.h}{h}{\coqdocabbreviation{h}} := \coqref{Coqdoc.links.a}{\coqdocdefinition{a}}.\coqdoceol
@@ -90,7 +90,7 @@ Various checks for coqdoc
\coqdockw{Variables} \coqdef{Coqdoc.links.test.b'}{b'}{\coqdocvariable{b'}} \coqdef{Coqdoc.links.test.b2}{b2}{\coqdocvariable{b2}}: \coqexternalref{nat}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocinductive{nat}}.\coqdoceol
\coqdocemptyline
\coqdocindent{2.00em}
-\coqdockw{Notation} \coqdef{Coqdoc.links.test.:my scope:x '+' x}{"}{"}n + m" := (\coqdocvar{n} \coqref{Coqdoc.links.::x 'xE2x96xB5' x}{\coqdocnotation{▵}} \coqdocvar{m}) : \coqdocvar{my\_scope}.\coqdoceol
+\coqdockw{Notation} \coqdef{Coqdoc.links.test.::my scope:x '+' x}{"}{"}n + m" := (\coqdocvar{n} \coqref{Coqdoc.links.:::x 'xE2x96xB5' x}{\coqdocnotation{▵}} \coqdocvar{m}) : \coqdocvar{my\_scope}.\coqdoceol
\coqdocemptyline
\coqdocindent{2.00em}
\coqdockw{Delimit} \coqdockw{Scope} \coqdocvar{my\_scope} \coqdockw{with} \coqdocvar{my}.\coqdoceol
@@ -99,19 +99,19 @@ Various checks for coqdoc
\coqdockw{Notation} \coqdef{Coqdoc.links.l}{l}{\coqdocabbreviation{l}} := 0.\coqdoceol
\coqdocemptyline
\coqdocindent{2.00em}
-\coqdockw{Definition} \coqdef{Coqdoc.links.xCExB1}{α}{\coqdocdefinition{α}} := (0 \coqref{Coqdoc.links.test.:my scope:x '+' x}{\coqdocnotation{+}} \coqref{Coqdoc.links.l}{\coqdocabbreviation{l}})\%\coqdocvar{my}.\coqdoceol
+\coqdockw{Definition} \coqdef{Coqdoc.links.xCExB1}{α}{\coqdocdefinition{α}} := (0 \coqref{Coqdoc.links.test.::my scope:x '+' x}{\coqdocnotation{+}} \coqref{Coqdoc.links.l}{\coqdocabbreviation{l}})\%\coqdocvar{my}.\coqdoceol
\coqdocemptyline
\coqdocindent{2.00em}
-\coqdockw{Definition} \coqdef{Coqdoc.links.a'}{a'}{\coqdocdefinition{a'}} \coqdocvar{b} := \coqdocvariable{b'}\coqref{Coqdoc.links.::x '++' x}{\coqdocnotation{++}}0\coqref{Coqdoc.links.::x '++' x}{\coqdocnotation{++}}\coqdocvariable{b2} \coqref{Coqdoc.links.::x ''' ''' '++' 'x' x}{\coqdocnotation{\_}} \coqref{Coqdoc.links.::x ''' ''' '++' 'x' x}{\coqdocnotation{++}}\coqref{Coqdoc.links.::x ''' ''' '++' 'x' x}{\coqdocnotation{x}} \coqdocvariable{b}.\coqdoceol
+\coqdockw{Definition} \coqdef{Coqdoc.links.a'}{a'}{\coqdocdefinition{a'}} \coqdocvar{b} := \coqdocvariable{b'}\coqref{Coqdoc.links.:::x '++' x}{\coqdocnotation{++}}0\coqref{Coqdoc.links.:::x '++' x}{\coqdocnotation{++}}\coqdocvariable{b2} \coqref{Coqdoc.links.:::x ''' ''' '++' 'x' x}{\coqdocnotation{\_}} \coqref{Coqdoc.links.:::x ''' ''' '++' 'x' x}{\coqdocnotation{++}}\coqref{Coqdoc.links.:::x ''' ''' '++' 'x' x}{\coqdocnotation{x}} \coqdocvariable{b}.\coqdoceol
\coqdocemptyline
\coqdocindent{2.00em}
-\coqdockw{Definition} \coqdef{Coqdoc.links.c}{c}{\coqdocdefinition{c}} := \coqexternalref{:type scope:'x7B' x 'x7D' '+' 'x7B' x 'x7D'}{http://coq.inria.fr/stdlib/Coq.Init.Specif}{\coqdocnotation{\{}}\coqexternalref{True}{http://coq.inria.fr/stdlib/Coq.Init.Logic}{\coqdocinductive{True}}\coqexternalref{:type scope:'x7B' x 'x7D' '+' 'x7B' x 'x7D'}{http://coq.inria.fr/stdlib/Coq.Init.Specif}{\coqdocnotation{\}+\{}}\coqexternalref{True}{http://coq.inria.fr/stdlib/Coq.Init.Logic}{\coqdocinductive{True}}\coqexternalref{:type scope:'x7B' x 'x7D' '+' 'x7B' x 'x7D'}{http://coq.inria.fr/stdlib/Coq.Init.Specif}{\coqdocnotation{\}}}.\coqdoceol
+\coqdockw{Definition} \coqdef{Coqdoc.links.c}{c}{\coqdocdefinition{c}} := \coqexternalref{::type scope:'x7B' x 'x7D' '+' 'x7B' x 'x7D'}{http://coq.inria.fr/stdlib/Coq.Init.Specif}{\coqdocnotation{\{}}\coqexternalref{True}{http://coq.inria.fr/stdlib/Coq.Init.Logic}{\coqdocinductive{True}}\coqexternalref{::type scope:'x7B' x 'x7D' '+' 'x7B' x 'x7D'}{http://coq.inria.fr/stdlib/Coq.Init.Specif}{\coqdocnotation{\}+\{}}\coqexternalref{True}{http://coq.inria.fr/stdlib/Coq.Init.Logic}{\coqdocinductive{True}}\coqexternalref{::type scope:'x7B' x 'x7D' '+' 'x7B' x 'x7D'}{http://coq.inria.fr/stdlib/Coq.Init.Specif}{\coqdocnotation{\}}}.\coqdoceol
\coqdocemptyline
\coqdocindent{2.00em}
-\coqdockw{Definition} \coqdef{Coqdoc.links.d}{d}{\coqdocdefinition{d}} := (1\coqexternalref{:nat scope:x '+' x}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocnotation{+}}2)\%\coqdocvar{nat}.\coqdoceol
+\coqdockw{Definition} \coqdef{Coqdoc.links.d}{d}{\coqdocdefinition{d}} := (1\coqexternalref{::nat scope:x '+' x}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocnotation{+}}2)\%\coqdocvar{nat}.\coqdoceol
\coqdocemptyline
\coqdocindent{2.00em}
-\coqdockw{Lemma} \coqdef{Coqdoc.links.e}{e}{\coqdoclemma{e}} : \coqexternalref{nat}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocinductive{nat}} \coqexternalref{:type scope:x '+' x}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocnotation{+}} \coqexternalref{nat}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocinductive{nat}}.\coqdoceol
+\coqdockw{Lemma} \coqdef{Coqdoc.links.e}{e}{\coqdoclemma{e}} : \coqexternalref{nat}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocinductive{nat}} \coqexternalref{::type scope:x '+' x}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocnotation{+}} \coqexternalref{nat}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocinductive{nat}}.\coqdoceol
\coqdocindent{2.00em}
\coqdocvar{Admitted}.\coqdoceol
\coqdocemptyline
@@ -131,7 +131,7 @@ Various checks for coqdoc
\coqdockw{Variables} \coqdef{Coqdoc.links.test2.test.b2}{b2}{\coqdocvariable{b2}}: \coqexternalref{nat}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocinductive{nat}}.\coqdoceol
\coqdocemptyline
\coqdocindent{3.00em}
-\coqdockw{Definition} \coqdef{Coqdoc.links.a''}{a'{}'}{\coqdocdefinition{a'{}'}} \coqdocvar{b} := \coqdocvariable{b'} \coqref{Coqdoc.links.::x '++' x}{\coqdocnotation{++}} \coqexternalref{O}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocconstructor{O}} \coqref{Coqdoc.links.::x '++' x}{\coqdocnotation{++}} \coqdocvariable{b2} \coqref{Coqdoc.links.::x ''' ''' '++' 'x' x}{\coqdocnotation{\_}} \coqref{Coqdoc.links.::x ''' ''' '++' 'x' x}{\coqdocnotation{++}} \coqref{Coqdoc.links.::x ''' ''' '++' 'x' x}{\coqdocnotation{x}} \coqdocvariable{b} \coqexternalref{:nat scope:x '+' x}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocnotation{+}} \coqref{Coqdoc.links.h}{\coqdocabbreviation{h}} 0.\coqdoceol
+\coqdockw{Definition} \coqdef{Coqdoc.links.a''}{a'{}'}{\coqdocdefinition{a'{}'}} \coqdocvar{b} := \coqdocvariable{b'} \coqref{Coqdoc.links.:::x '++' x}{\coqdocnotation{++}} \coqexternalref{O}{http://coq.inria.fr/stdlib/Coq.Init.Datatypes}{\coqdocconstructor{O}} \coqref{Coqdoc.links.:::x '++' x}{\coqdocnotation{++}} \coqdocvariable{b2} \coqref{Coqdoc.links.:::x ''' ''' '++' 'x' x}{\coqdocnotation{\_}} \coqref{Coqdoc.links.:::x ''' ''' '++' 'x' x}{\coqdocnotation{++}} \coqref{Coqdoc.links.:::x ''' ''' '++' 'x' x}{\coqdocnotation{x}} \coqdocvariable{b} \coqexternalref{::nat scope:x '+' x}{http://coq.inria.fr/stdlib/Coq.Init.Peano}{\coqdocnotation{+}} \coqref{Coqdoc.links.h}{\coqdocabbreviation{h}} 0.\coqdoceol
\coqdocemptyline
\coqdocindent{2.00em}
\coqdockw{End} \coqref{Coqdoc.links.test2.test}{\coqdocsection{test}}.\coqdoceol
diff --git a/test-suite/failure/check.v b/test-suite/failure/check.v
index a148ebe8..0ef4b417 100644
--- a/test-suite/failure/check.v
+++ b/test-suite/failure/check.v
@@ -1,3 +1,3 @@
-Implicit Arguments eq [A].
+Arguments eq [A].
Fail Check (bool = true).
diff --git a/test-suite/ide/undo012.fake b/test-suite/ide/undo012.fake
index b3d1c6d5..c95df1b1 100644
--- a/test-suite/ide/undo012.fake
+++ b/test-suite/ide/undo012.fake
@@ -3,6 +3,7 @@
#
# Test backtracking in presence of nested proofs
#
+ADD { Set Nested Proofs Allowed. }
ADD { Lemma aa : True -> True /\ True. }
ADD { intro H. }
ADD { split. }
diff --git a/test-suite/ide/undo013.fake b/test-suite/ide/undo013.fake
index 921a9d0f..a3ccefd2 100644
--- a/test-suite/ide/undo013.fake
+++ b/test-suite/ide/undo013.fake
@@ -4,6 +4,7 @@
# Test backtracking in presence of nested proofs
# Second, trigger the undo of an inner proof
#
+ADD { Set Nested Proofs Allowed. }
ADD { Lemma aa : True -> True /\ True. }
ADD { intro H. }
ADD { split. }
diff --git a/test-suite/ide/undo014.fake b/test-suite/ide/undo014.fake
index f5fe7747..13e71822 100644
--- a/test-suite/ide/undo014.fake
+++ b/test-suite/ide/undo014.fake
@@ -4,6 +4,7 @@
# Test backtracking in presence of nested proofs
# Third, undo inside an inner proof
#
+ADD { Set Nested Proofs Allowed. }
ADD { Lemma aa : True -> True /\ True. }
ADD { intro H. }
ADD { split. }
diff --git a/test-suite/ide/undo015.fake b/test-suite/ide/undo015.fake
index a1e5c947..9cbd6446 100644
--- a/test-suite/ide/undo015.fake
+++ b/test-suite/ide/undo015.fake
@@ -4,6 +4,7 @@
# Test backtracking in presence of nested proofs
# Fourth, undo from an inner proof to a above proof
#
+ADD { Set Nested Proofs Allowed. }
ADD { Lemma aa : True -> True /\ True. }
ADD { intro H. }
ADD { split. }
diff --git a/test-suite/ide/undo016.fake b/test-suite/ide/undo016.fake
index f9414c1e..15bd3cc9 100644
--- a/test-suite/ide/undo016.fake
+++ b/test-suite/ide/undo016.fake
@@ -4,6 +4,7 @@
# Test backtracking in presence of nested proofs
# Fifth, undo from an inner proof to a previous inner proof
#
+ADD { Set Nested Proofs Allowed. }
ADD { Lemma aa : True -> True /\ True. }
ADD { intro H. }
ADD { split. }
diff --git a/test-suite/interactive/PrimNotation.v b/test-suite/interactive/PrimNotation.v
new file mode 100644
index 00000000..07986b0d
--- /dev/null
+++ b/test-suite/interactive/PrimNotation.v
@@ -0,0 +1,64 @@
+(* Until recently, the Notation.declare_numeral_notation wasn't synchronized
+ w.r.t. backtracking. This should be ok now.
+ This test is pretty artificial (we must declare Z_scope for this to work).
+*)
+
+Delimit Scope Z_scope with Z.
+Open Scope Z_scope.
+Check let v := 0 in v : nat.
+(* let v := 0 in v : nat : nat *)
+Require BinInt.
+Check let v := 0 in v : BinNums.Z.
+(* let v := 0 in v : BinNums.Z : BinNums.Z *)
+Back 2.
+Check let v := 0 in v : nat.
+(* Expected answer: let v := 0 in v : nat : nat *)
+(* Used to fail with:
+Error: Cannot interpret in Z_scope without requiring first module BinNums.
+*)
+
+Local Set Universe Polymorphism.
+Delimit Scope punit_scope with punit.
+Delimit Scope pcunit_scope with pcunit.
+Delimit Scope int_scope with int.
+Numeral Notation Decimal.int Decimal.int_of_int Decimal.int_of_int : int_scope.
+Module A.
+ NonCumulative Inductive punit@{u} : Type@{u} := ptt.
+ Cumulative Inductive pcunit@{u} : Type@{u} := pctt.
+ Definition to_punit : Decimal.int -> option punit
+ := fun v => match v with 0%int => Some ptt | _ => None end.
+ Definition to_pcunit : Decimal.int -> option pcunit
+ := fun v => match v with 0%int => Some pctt | _ => None end.
+ Definition of_punit : punit -> Decimal.uint := fun _ => Nat.to_uint 0.
+ Definition of_pcunit : pcunit -> Decimal.uint := fun _ => Nat.to_uint 0.
+ Numeral Notation punit to_punit of_punit : punit_scope.
+ Check let v := 0%punit in v : punit.
+ Back 2.
+ Numeral Notation pcunit to_pcunit of_pcunit : punit_scope.
+ Check let v := 0%punit in v : pcunit.
+End A.
+Reset A.
+Local Unset Universe Polymorphism.
+Module A.
+ Inductive punit : Set := ptt.
+ Definition to_punit : Decimal.int -> option punit
+ := fun v => match v with 0%int => Some ptt | _ => None end.
+ Definition of_punit : punit -> Decimal.uint := fun _ => Nat.to_uint 0.
+ Numeral Notation punit to_punit of_punit : punit_scope.
+ Check let v := 0%punit in v : punit.
+End A.
+Local Set Universe Polymorphism.
+Inductive punit@{u} : Type@{u} := ptt.
+Definition to_punit : Decimal.int -> option punit
+ := fun v => match v with 0%int => Some ptt | _ => None end.
+Definition of_punit : punit -> Decimal.uint := fun _ => Nat.to_uint 0.
+Numeral Notation punit to_punit of_punit : punit_scope.
+Check let v := 0%punit in v : punit.
+Back 6. (* check backtracking of registering universe polymorphic constants *)
+Local Unset Universe Polymorphism.
+Inductive punit : Set := ptt.
+Definition to_punit : Decimal.int -> option punit
+ := fun v => match v with 0%int => Some ptt | _ => None end.
+Definition of_punit : punit -> Decimal.uint := fun _ => Nat.to_uint 0.
+Numeral Notation punit to_punit of_punit : punit_scope.
+Check let v := 0%punit in v : punit.
diff --git a/test-suite/misc/7595.sh b/test-suite/misc/7595.sh
new file mode 100755
index 00000000..836e354e
--- /dev/null
+++ b/test-suite/misc/7595.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+set -e
+
+$coqc -R misc/7595 Test misc/7595/base.v
+$coqc -R misc/7595 Test misc/7595/FOO.v
diff --git a/test-suite/misc/7595/FOO.v b/test-suite/misc/7595/FOO.v
new file mode 100644
index 00000000..30c957d3
--- /dev/null
+++ b/test-suite/misc/7595/FOO.v
@@ -0,0 +1,39 @@
+Require Import Test.base.
+
+Lemma dec_stable `{Decision P} : ¬¬P → P.
+Proof. firstorder. Qed.
+
+(** The tactic [destruct_decide] destructs a sumbool [dec]. If one of the
+components is double negated, it will try to remove the double negation. *)
+Tactic Notation "destruct_decide" constr(dec) "as" ident(H) :=
+ destruct dec as [H|H];
+ try match type of H with
+ | ¬¬_ => apply dec_stable in H
+ end.
+Tactic Notation "destruct_decide" constr(dec) :=
+ let H := fresh in destruct_decide dec as H.
+
+
+(** * Monadic operations *)
+Instance option_guard: MGuard option := λ P dec A f,
+ match dec with left H => f H | _ => None end.
+
+(** * Tactics *)
+Tactic Notation "case_option_guard" "as" ident(Hx) :=
+ match goal with
+ | H : context C [@mguard option _ ?P ?dec] |- _ =>
+ change (@mguard option _ P dec) with (λ A (f : P → option A),
+ match @decide P dec with left H' => f H' | _ => None end) in *;
+ destruct_decide (@decide P dec) as Hx
+ | |- context C [@mguard option _ ?P ?dec] =>
+ change (@mguard option _ P dec) with (λ A (f : P → option A),
+ match @decide P dec with left H' => f H' | _ => None end) in *;
+ destruct_decide (@decide P dec) as Hx
+ end.
+Tactic Notation "case_option_guard" :=
+ let H := fresh in case_option_guard as H.
+
+(* This proof failed depending on the name of the module. *)
+Lemma option_guard_True {A} P `{Decision P} (mx : option A) :
+ P → (guard P; mx) = mx.
+Proof. intros. case_option_guard. reflexivity. contradiction. Qed.
diff --git a/test-suite/misc/7595/base.v b/test-suite/misc/7595/base.v
new file mode 100644
index 00000000..6a6b7b79
--- /dev/null
+++ b/test-suite/misc/7595/base.v
@@ -0,0 +1,28 @@
+From Coq Require Export Morphisms RelationClasses List Bool Utf8 Setoid.
+Set Default Proof Using "Type".
+Export ListNotations.
+From Coq.Program Require Export Basics Syntax.
+Global Generalizable All Variables.
+
+(** * Type classes *)
+(** ** Decidable propositions *)
+(** This type class by (Spitters/van der Weegen, 2011) collects decidable
+propositions. *)
+Class Decision (P : Prop) := decide : {P} + {¬P}.
+Hint Mode Decision ! : typeclass_instances.
+Arguments decide _ {_} : simpl never, assert.
+
+(** ** Proof irrelevant types *)
+(** This type class collects types that are proof irrelevant. That means, all
+elements of the type are equal. We use this notion only used for propositions,
+but by universe polymorphism we can generalize it. *)
+Class ProofIrrel (A : Type) : Prop := proof_irrel (x y : A) : x = y.
+Hint Mode ProofIrrel ! : typeclass_instances.
+
+Class MGuard (M : Type → Type) :=
+ mguard: ∀ P {dec : Decision P} {A}, (P → M A) → M A.
+Arguments mguard _ _ _ !_ _ _ / : assert.
+Notation "'guard' P ; z" := (mguard P (λ _, z))
+ (at level 20, z at level 200, only parsing, right associativity) .
+Notation "'guard' P 'as' H ; z" := (mguard P (λ H, z))
+ (at level 20, z at level 200, only parsing, right associativity) .
diff --git a/test-suite/misc/7704.sh b/test-suite/misc/7704.sh
new file mode 100755
index 00000000..0ca2c97d
--- /dev/null
+++ b/test-suite/misc/7704.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+
+set -e
+
+export PATH=$BIN:$PATH
+
+${coqtop#"$BIN"} -compile misc/aux7704.v
diff --git a/test-suite/misc/aux7704.v b/test-suite/misc/aux7704.v
new file mode 100644
index 00000000..6fdcf676
--- /dev/null
+++ b/test-suite/misc/aux7704.v
@@ -0,0 +1,6 @@
+
+Goal True /\ True.
+Proof.
+ split.
+ par:exact I.
+Qed.
diff --git a/test-suite/misc/deps-checksum.sh b/test-suite/misc/deps-checksum.sh
index e07612b8..a15a8fbe 100755
--- a/test-suite/misc/deps-checksum.sh
+++ b/test-suite/misc/deps-checksum.sh
@@ -1,3 +1,4 @@
+#!/bin/sh
rm -f misc/deps/A/*.vo misc/deps/B/*.vo
$coqc -R misc/deps/A A misc/deps/A/A.v
$coqc -R misc/deps/B A misc/deps/B/A.v
diff --git a/test-suite/misc/deps-order.sh b/test-suite/misc/deps-order.sh
index 299f4946..6bb2ba2d 100755
--- a/test-suite/misc/deps-order.sh
+++ b/test-suite/misc/deps-order.sh
@@ -1,17 +1,18 @@
+#!/bin/sh
# Check that both coqdep and coqtop/coqc supports -R
# Check that both coqdep and coqtop/coqc takes the later -R
# See bugs 2242, 2337, 2339
rm -f misc/deps/lib/*.vo misc/deps/client/*.vo
-tmpoutput=`mktemp /tmp/coqcheck.XXXXXX`
-$coqdep -R misc/deps/lib lib -R misc/deps/client client misc/deps/client/bar.v 2>&1 | head -n 1 > $tmpoutput
-diff -u --strip-trailing-cr misc/deps/deps.out $tmpoutput 2>&1
+tmpoutput=$(mktemp /tmp/coqcheck.XXXXXX)
+$coqdep -R misc/deps/lib lib -R misc/deps/client client misc/deps/client/bar.v 2>&1 | head -n 1 > "$tmpoutput"
+diff -u --strip-trailing-cr misc/deps/deps.out "$tmpoutput" 2>&1
R=$?
times
$coqc -R misc/deps/lib lib misc/deps/lib/foo.v 2>&1
$coqc -R misc/deps/lib lib -R misc/deps/client client misc/deps/client/foo.v 2>&1
$coqtop -R misc/deps/lib lib -R misc/deps/client client -load-vernac-source misc/deps/client/bar.v 2>&1
S=$?
-if [ $R = 0 -a $S = 0 ]; then
+if [ $R = 0 ] && [ $S = 0 ]; then
printf "coqdep and coqtop agree\n"
exit 0
else
diff --git a/test-suite/misc/deps-utf8.sh b/test-suite/misc/deps-utf8.sh
index 13e264c0..acb45b22 100755
--- a/test-suite/misc/deps-utf8.sh
+++ b/test-suite/misc/deps-utf8.sh
@@ -1,15 +1,16 @@
+#!/bin/sh
# Check reading directories matching non pure ascii idents
# See bug #5715 (utf-8 working on macos X and linux)
# Windows is still not compliant
-a=`uname`
-if [ "$a" = "Darwin" -o "$a" = "Linux" ]; then
+a=$(uname)
+if [ "$a" = "Darwin" ] || [ "$a" = "Linux" ]; then
rm -f misc/deps/théorèmes/*.v
-tmpoutput=`mktemp /tmp/coqcheck.XXXXXX`
+tmpoutput=$(mktemp /tmp/coqcheck.XXXXXX)
$coqc -R misc/deps AlphaBêta misc/deps/αβ/γδ.v
R=$?
$coqtop -R misc/deps AlphaBêta -load-vernac-source misc/deps/αβ/εζ.v
S=$?
-if [ $R = 0 -a $S = 0 ]; then
+if [ $R = 0 ] && [ $S = 0 ]; then
exit 0
else
exit 1
diff --git a/test-suite/misc/exitstatus.sh b/test-suite/misc/exitstatus.sh
index cea1de86..a327f424 100755
--- a/test-suite/misc/exitstatus.sh
+++ b/test-suite/misc/exitstatus.sh
@@ -1,7 +1,8 @@
+#!/bin/sh
$coqtop -load-vernac-source misc/exitstatus/illtyped.v
N=$?
$coqc misc/exitstatus/illtyped.v
P=$?
-printf "On ill-typed input, coqtop returned $N.\n"
-printf "On ill-typed input, coqc returned $P.\n"
-if [ $N = 1 -a $P = 1 ]; then exit 0; else exit 1; fi
+printf "On ill-typed input, coqtop returned %s.\n" "$N"
+printf "On ill-typed input, coqc returned %s.\n" "$P"
+if [ $N = 1 ] && [ $P = 1 ]; then exit 0; else exit 1; fi
diff --git a/test-suite/misc/poly-capture-global-univs.sh b/test-suite/misc/poly-capture-global-univs.sh
new file mode 100755
index 00000000..e066ac03
--- /dev/null
+++ b/test-suite/misc/poly-capture-global-univs.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+set -e
+
+export COQBIN=$BIN
+export PATH=$COQBIN:$PATH
+
+cd misc/poly-capture-global-univs/
+
+coq_makefile -f _CoqProject -o Makefile
+
+make clean
+
+make src/evil_plugin.cmxs
+
+if make; then
+ >&2 echo 'Should have failed!'
+ exit 1
+fi
diff --git a/test-suite/misc/poly-capture-global-univs/_CoqProject b/test-suite/misc/poly-capture-global-univs/_CoqProject
new file mode 100644
index 00000000..70ec2460
--- /dev/null
+++ b/test-suite/misc/poly-capture-global-univs/_CoqProject
@@ -0,0 +1,9 @@
+-Q theories Evil
+-I src
+
+src/evil.ml4
+src/evilImpl.ml
+src/evilImpl.mli
+src/evil_plugin.mlpack
+theories/evil.v
+
diff --git a/test-suite/misc/poly-capture-global-univs/src/evil.ml4 b/test-suite/misc/poly-capture-global-univs/src/evil.ml4
new file mode 100644
index 00000000..565e979a
--- /dev/null
+++ b/test-suite/misc/poly-capture-global-univs/src/evil.ml4
@@ -0,0 +1,9 @@
+
+open Stdarg
+open EvilImpl
+
+DECLARE PLUGIN "evil_plugin"
+
+VERNAC COMMAND FUNCTIONAL EXTEND VernacEvil CLASSIFIED AS SIDEFF
+| [ "Evil" ident(x) ident(y) ] -> [ fun ~atts ~st -> evil x y; st ]
+END
diff --git a/test-suite/misc/poly-capture-global-univs/src/evilImpl.ml b/test-suite/misc/poly-capture-global-univs/src/evilImpl.ml
new file mode 100644
index 00000000..6d8ce7c5
--- /dev/null
+++ b/test-suite/misc/poly-capture-global-univs/src/evilImpl.ml
@@ -0,0 +1,22 @@
+open Names
+
+let evil t f =
+ let open Univ in
+ let open Entries in
+ let open Decl_kinds in
+ let open Constr in
+ let k = IsDefinition Definition in
+ let u = Level.var 0 in
+ let tu = mkType (Universe.make u) in
+ let te = Declare.definition_entry
+ ~univs:(Monomorphic_const_entry (ContextSet.singleton u)) tu
+ in
+ let tc = Declare.declare_constant t (DefinitionEntry te, k) in
+ let tc = mkConst tc in
+
+ let fe = Declare.definition_entry
+ ~univs:(Polymorphic_const_entry (UContext.make (Instance.of_array [|u|],Constraint.empty)))
+ ~types:(Term.mkArrow tc tu)
+ (mkLambda (Name.Name (Id.of_string "x"), tc, mkRel 1))
+ in
+ ignore (Declare.declare_constant f (DefinitionEntry fe, k))
diff --git a/test-suite/misc/poly-capture-global-univs/src/evilImpl.mli b/test-suite/misc/poly-capture-global-univs/src/evilImpl.mli
new file mode 100644
index 00000000..97c7e3da
--- /dev/null
+++ b/test-suite/misc/poly-capture-global-univs/src/evilImpl.mli
@@ -0,0 +1,2 @@
+
+val evil : Names.Id.t -> Names.Id.t -> unit
diff --git a/test-suite/misc/poly-capture-global-univs/src/evil_plugin.mlpack b/test-suite/misc/poly-capture-global-univs/src/evil_plugin.mlpack
new file mode 100644
index 00000000..0093328a
--- /dev/null
+++ b/test-suite/misc/poly-capture-global-univs/src/evil_plugin.mlpack
@@ -0,0 +1,2 @@
+EvilImpl
+Evil
diff --git a/test-suite/misc/poly-capture-global-univs/theories/evil.v b/test-suite/misc/poly-capture-global-univs/theories/evil.v
new file mode 100644
index 00000000..7fd98c27
--- /dev/null
+++ b/test-suite/misc/poly-capture-global-univs/theories/evil.v
@@ -0,0 +1,13 @@
+
+Declare ML Module "evil_plugin".
+
+Evil T f. (* <- if this doesn't fail then the rest goes through *)
+
+Definition g : Type -> Set := f.
+
+Require Import Hurkens.
+
+Lemma absurd : False.
+Proof.
+ exact (TypeNeqSmallType.paradox (g Type) eq_refl).
+Qed.
diff --git a/test-suite/misc/printers.sh b/test-suite/misc/printers.sh
index 28e7dc36..ef3f056d 100755
--- a/test-suite/misc/printers.sh
+++ b/test-suite/misc/printers.sh
@@ -1,3 +1,2 @@
-printf "Drop. #use\"include\";; #quit;;\n" | $coqtopbyte 2>&1 | egrep "Error|Unbound"
-if [ $? = 0 ]; then exit 1; else exit 0; fi
-
+#!/bin/sh
+if printf "Drop. #use\"include\";; #quit;;\n" | $coqtopbyte 2>&1 | grep -E "Error|Unbound" ; then exit 1; else exit 0; fi
diff --git a/test-suite/misc/universes.sh b/test-suite/misc/universes.sh
index d87a8603..ef61ca62 100755
--- a/test-suite/misc/universes.sh
+++ b/test-suite/misc/universes.sh
@@ -1,8 +1,9 @@
+#!/bin/sh
# Sort universes for the whole standard library
EXPECTED_UNIVERSES=4 # Prop is not counted
$coqc -R misc/universes Universes misc/universes/all_stdlib 2>&1
$coqc -R misc/universes Universes misc/universes/universes 2>&1
mv universes.txt misc/universes
-N=`awk '{print $3}' misc/universes/universes.txt | sort -u | wc -l`
-printf "Found %s/%s universes\n" $N $EXPECTED_UNIVERSES
+N=$(awk '{print $3}' misc/universes/universes.txt | sort -u | wc -l)
+printf "Found %s/%s universes\n" "$N" "$EXPECTED_UNIVERSES"
if [ "$N" -eq $EXPECTED_UNIVERSES ]; then exit 0; else exit 1; fi
diff --git a/test-suite/modules/PO.v b/test-suite/modules/PO.v
index 8ba8525c..be331049 100644
--- a/test-suite/modules/PO.v
+++ b/test-suite/modules/PO.v
@@ -1,8 +1,8 @@
Set Implicit Arguments.
Unset Strict Implicit.
-Implicit Arguments fst.
-Implicit Arguments snd.
+Arguments fst : default implicits.
+Arguments snd : default implicits.
Module Type PO.
Parameter T : Set.
diff --git a/test-suite/modules/Przyklad.v b/test-suite/modules/Przyklad.v
index 7214287a..ece1b47b 100644
--- a/test-suite/modules/Przyklad.v
+++ b/test-suite/modules/Przyklad.v
@@ -1,7 +1,7 @@
Definition ifte (T : Set) (A B : Prop) (s : {A} + {B})
(th el : T) := if s then th else el.
-Implicit Arguments ifte.
+Arguments ifte : default implicits.
Lemma Reflexivity_provable :
forall (A : Set) (a : A) (s : {a = a} + {a <> a}),
diff --git a/test-suite/output/Arguments_renaming.out b/test-suite/output/Arguments_renaming.out
index e73312c6..c0b04eb5 100644
--- a/test-suite/output/Arguments_renaming.out
+++ b/test-suite/output/Arguments_renaming.out
@@ -1,6 +1,5 @@
The command has indeed failed with message:
-To rename arguments the "rename" flag must be specified.
-Argument A renamed to B.
+Flag "rename" expected to rename A into B.
File "stdin", line 2, characters 0-25:
Warning: This command is just asserting the names of arguments of identity.
If this is what you want add ': assert' to silence the warning. If you want
@@ -113,5 +112,4 @@ Argument z cannot be declared implicit.
The command has indeed failed with message:
Extra arguments: y.
The command has indeed failed with message:
-To rename arguments the "rename" flag must be specified.
-Argument A renamed to R.
+Flag "rename" expected to rename A into R.
diff --git a/test-suite/output/BadOptionValueType.out b/test-suite/output/BadOptionValueType.out
new file mode 100644
index 00000000..34d8518a
--- /dev/null
+++ b/test-suite/output/BadOptionValueType.out
@@ -0,0 +1,8 @@
+The command has indeed failed with message:
+Bad type of value for this option: expected int, got string.
+The command has indeed failed with message:
+Bad type of value for this option: expected bool, got string.
+The command has indeed failed with message:
+Bad type of value for this option: expected bool, got int.
+The command has indeed failed with message:
+Bad type of value for this option: expected bool, got int.
diff --git a/test-suite/output/BadOptionValueType.v b/test-suite/output/BadOptionValueType.v
new file mode 100644
index 00000000..b61c3757
--- /dev/null
+++ b/test-suite/output/BadOptionValueType.v
@@ -0,0 +1,4 @@
+Fail Set Default Timeout "2".
+Fail Set Debug Eauto "yes".
+Fail Set Debug Eauto 1.
+Fail Set Implicit Arguments 1.
diff --git a/test-suite/output/Cases.out b/test-suite/output/Cases.out
index 419dcadb..dfab400b 100644
--- a/test-suite/output/Cases.out
+++ b/test-suite/output/Cases.out
@@ -169,3 +169,5 @@ fun x : K => match x with
| _ => 2
end
: K -> nat
+The command has indeed failed with message:
+Pattern "S _, _" is redundant in this clause.
diff --git a/test-suite/output/Cases.v b/test-suite/output/Cases.v
index caf3b287..e4fa7044 100644
--- a/test-suite/output/Cases.v
+++ b/test-suite/output/Cases.v
@@ -163,6 +163,7 @@ match goal with |- ?y + _ = _ => pose (match y as y with 0 => 0 | S n => 0 end)
match goal with |- ?y + _ = _ => pose (match y as y return y=y with 0 => eq_refl | S n => eq_refl end) end.
match goal with |- ?y + _ = _ => pose (match y return y=y with 0 => eq_refl | S n => eq_refl end) end.
Show.
+Abort.
Lemma lem5 (p:nat) : eq_refl p = eq_refl p.
let y := fresh "n" in (* Checking that y is hidden *)
@@ -216,3 +217,6 @@ Check fun x => match x with a3 | a4 => 3 | _ => 2 end.
Check fun x => match x with a3 => 3 | a2 | a1 => 4 | _ => 2 end.
Check fun x => match x with a4 => 3 | a2 | a1 => 4 | _ => 2 end.
Check fun x => match x with a3 | a4 | a1 => 3 | _ => 2 end.
+
+(* Test redundant clause within a disjunctive pattern *)
+Fail Check fun n m => match n, m with 0, 0 | _, S _ | S 0, _ | S (S _ | _), _ => false end.
diff --git a/test-suite/output/Deprecation.out b/test-suite/output/Deprecation.out
new file mode 100644
index 00000000..7e290847
--- /dev/null
+++ b/test-suite/output/Deprecation.out
@@ -0,0 +1,3 @@
+File "stdin", line 5, characters 0-3:
+Warning: Tactic foo is deprecated since X.Y. Use idtac instead.
+[deprecated-tactic,deprecated]
diff --git a/test-suite/output/Deprecation.v b/test-suite/output/Deprecation.v
new file mode 100644
index 00000000..04d5eb3d
--- /dev/null
+++ b/test-suite/output/Deprecation.v
@@ -0,0 +1,6 @@
+#[deprecated(since = "X.Y", note = "Use idtac instead.")]
+ Ltac foo := idtac.
+
+Goal True.
+foo.
+Abort.
diff --git a/test-suite/output/Errors.out b/test-suite/output/Errors.out
index 38d055b2..24180c45 100644
--- a/test-suite/output/Errors.out
+++ b/test-suite/output/Errors.out
@@ -8,3 +8,11 @@ Unable to unify "nat" with "True".
The command has indeed failed with message:
Ltac call to "instantiate ( (ident) := (lglob) )" failed.
Instance is not well-typed in the environment of ?x.
+The command has indeed failed with message:
+Cannot infer the domain of the type of f.
+The command has indeed failed with message:
+Cannot infer the domain of the implicit parameter A of id whose type is
+"Type".
+The command has indeed failed with message:
+Cannot infer the codomain of the type of f in environment:
+x : nat
diff --git a/test-suite/output/Errors.v b/test-suite/output/Errors.v
index 424d2480..c9b50913 100644
--- a/test-suite/output/Errors.v
+++ b/test-suite/output/Errors.v
@@ -25,3 +25,9 @@ eexists ?[x].
destruct H1 as [x1 H1].
Fail instantiate (x:=projT1 x1).
Abort.
+
+(* Test some messages for non solvable evars *)
+
+Fail Goal forall a f, f a = 0.
+Fail Goal forall f x, id f x = 0.
+Fail Goal forall f P, P (f 0).
diff --git a/test-suite/output/Notations.out b/test-suite/output/Notations.out
index b60b1ee8..94b86fc2 100644
--- a/test-suite/output/Notations.out
+++ b/test-suite/output/Notations.out
@@ -125,13 +125,15 @@ s
: nat
fun _ : nat => 9
: nat -> nat
-fun (x : nat) (p : x = x) => match p with
- | ONE => ONE
- end = p
+fun (x : nat) (p : x = x) =>
+match p in (_ = n) return (n = n) with
+| ONE => ONE
+end = p
: forall x : nat, x = x -> Prop
-fun (x : nat) (p : x = x) => match p with
- | 1 => 1
- end = p
+fun (x : nat) (p : x = x) =>
+match p in (_ = n) return (n = n) with
+| 1 => 1
+end = p
: forall x : nat, x = x -> Prop
bar 0
: nat
diff --git a/test-suite/output/Notations3.out b/test-suite/output/Notations3.out
index 5ab61616..d32cf67e 100644
--- a/test-suite/output/Notations3.out
+++ b/test-suite/output/Notations3.out
@@ -246,3 +246,9 @@ Notation
============================
##@%
^^^
+myfoo01 tt
+ : nat
+myfoo01 tt
+ : nat
+myfoo01 tt
+ : nat
diff --git a/test-suite/output/Notations3.v b/test-suite/output/Notations3.v
index 876aaa39..180e8d33 100644
--- a/test-suite/output/Notations3.v
+++ b/test-suite/output/Notations3.v
@@ -399,3 +399,14 @@ Show.
Abort.
End Issue7731.
+
+Module Issue8126.
+
+Definition myfoo (x : nat) (y : nat) (z : unit) := y.
+Notation myfoo0 := (@myfoo 0).
+Notation myfoo01 := (@myfoo0 1).
+Check myfoo 0 1 tt. (* was printing [myfoo0 1 HI], but should print [myfoo01 HI] *)
+Check myfoo0 1 tt. (* was printing [myfoo0 1 HI], but should print [myfoo01 HI] *)
+Check myfoo01 tt. (* was printing [myfoo0 1 HI], but should print [myfoo01 HI] *)
+
+End Issue8126.
diff --git a/test-suite/output/Notations4.out b/test-suite/output/Notations4.out
new file mode 100644
index 00000000..46784d18
--- /dev/null
+++ b/test-suite/output/Notations4.out
@@ -0,0 +1,19 @@
+[< 0 > + < 1 > * < 2 >]
+ : nat
+[< b > + < b > * < 2 >]
+ : nat
+[<< # 0 >>]
+ : option nat
+[1 {f 1}]
+ : Expr
+fun (x : nat) (y z : Expr) => [1 + y z + {f x}]
+ : nat -> Expr -> Expr -> Expr
+fun e : Expr =>
+match e with
+| [x y + z] => [x + y z]
+| [1 + 1] => [1]
+| _ => [e + e]
+end
+ : Expr -> Expr
+[(1 + 1)]
+ : Expr
diff --git a/test-suite/output/Notations4.v b/test-suite/output/Notations4.v
new file mode 100644
index 00000000..6bdbf1be
--- /dev/null
+++ b/test-suite/output/Notations4.v
@@ -0,0 +1,72 @@
+(* An example with constr subentries *)
+
+Module A.
+
+Declare Custom Entry myconstr.
+
+Notation "[ x ]" := x (x custom myconstr at level 6).
+Notation "x + y" := (Nat.add x y) (in custom myconstr at level 5).
+Notation "x * y" := (Nat.mul x y) (in custom myconstr at level 4).
+Notation "< x >" := x (in custom myconstr at level 3, x constr at level 10).
+Check [ < 0 > + < 1 > * < 2 >].
+
+Axiom a : nat.
+Notation b := a.
+Check [ < b > + < a > * < 2 >].
+
+Declare Custom Entry anotherconstr.
+
+Notation "[ x ]" := x (x custom myconstr at level 6).
+Notation "<< x >>" := x (in custom myconstr at level 3, x custom anotherconstr at level 10).
+Notation "# x" := (Some x) (in custom anotherconstr at level 8, x constr at level 9).
+Check [ << # 0 >> ].
+
+End A.
+
+Module B.
+
+Inductive Expr :=
+ | Mul : Expr -> Expr -> Expr
+ | Add : Expr -> Expr -> Expr
+ | One : Expr.
+
+Declare Custom Entry expr.
+Notation "[ expr ]" := expr (expr custom expr at level 2).
+Notation "1" := One (in custom expr at level 0).
+Notation "x y" := (Mul x y) (in custom expr at level 1, left associativity).
+Notation "x + y" := (Add x y) (in custom expr at level 2, left associativity).
+Notation "( x )" := x (in custom expr at level 0, x at level 2).
+Notation "{ x }" := x (in custom expr at level 0, x constr).
+Notation "x" := x (in custom expr at level 0, x ident).
+
+Axiom f : nat -> Expr.
+Check [1 {f 1}].
+Check fun x y z => [1 + y z + {f x}].
+Check fun e => match e with
+| [x y + z] => [x + y z]
+| [1 + 1] => [1]
+| y => [y + e]
+end.
+
+End B.
+
+Module C.
+
+Inductive Expr :=
+ | Add : Expr -> Expr -> Expr
+ | One : Expr.
+
+Declare Custom Entry expr.
+Notation "[ expr ]" := expr (expr custom expr at level 1).
+Notation "1" := One (in custom expr at level 0).
+Notation "x + y" := (Add x y) (in custom expr at level 2, left associativity).
+Notation "( x )" := x (in custom expr at level 0, x at level 2).
+
+(* Check the use of a two-steps coercion from constr to expr 1 then
+ from expr 0 to expr 2 (note that camlp5 parsing is more tolerant
+ and does not require parentheses to parse from level 2 while at
+ level 1) *)
+
+Check [1 + 1].
+
+End C.
diff --git a/test-suite/output/PrintInfos.out b/test-suite/output/PrintInfos.out
index 1307a8f2..975b2ef7 100644
--- a/test-suite/output/PrintInfos.out
+++ b/test-suite/output/PrintInfos.out
@@ -85,8 +85,8 @@ bar : forall x : nat, x = 0
Argument x is implicit and maximally inserted
Module Coq.Init.Peano
-Notation existS2 := existT2
-Expands to: Notation Coq.Init.Specif.existS2
+Notation sym_eq := eq_sym
+Expands to: Notation Coq.Init.Logic.sym_eq
Inductive eq (A : Type) (x : A) : A -> Prop := eq_refl : x = x
For eq: Argument A is implicit and maximally inserted
diff --git a/test-suite/output/PrintInfos.v b/test-suite/output/PrintInfos.v
index a498db3e..62aa80f8 100644
--- a/test-suite/output/PrintInfos.v
+++ b/test-suite/output/PrintInfos.v
@@ -26,8 +26,7 @@ About bar.
Print bar.
About Peano. (* Module *)
-Set Warnings "-deprecated".
-About existS2. (* Notation *)
+About sym_eq. (* Notation *)
Arguments eq_refl {A} {x}, {A} x.
Print eq_refl.
@@ -46,4 +45,3 @@ Goal forall n:nat, let g := newdef in n <> newdef n -> newdef n <> n -> False.
About g. (* search hypothesis *)
About h. (* search hypothesis *)
Abort.
-
diff --git a/test-suite/output/RecordMissingField.out b/test-suite/output/RecordMissingField.out
new file mode 100644
index 00000000..7c80a606
--- /dev/null
+++ b/test-suite/output/RecordMissingField.out
@@ -0,0 +1,4 @@
+File "stdin", line 8, characters 5-22:
+Error: Cannot infer field y2p of record point2d in environment:
+p : point2d
+
diff --git a/test-suite/output/RecordMissingField.v b/test-suite/output/RecordMissingField.v
new file mode 100644
index 00000000..84f1748f
--- /dev/null
+++ b/test-suite/output/RecordMissingField.v
@@ -0,0 +1,8 @@
+(** Check for error message when missing a record field. Error message
+should contain missing field, and the inferred type of the record **)
+
+Record point2d := mkPoint { x2p: nat; y2p: nat }.
+
+
+Definition increment_x (p: point2d) : point2d :=
+ {| x2p := x2p p + 1; |}.
diff --git a/test-suite/output/UnclosedBlocks.out b/test-suite/output/UnclosedBlocks.out
index b83e94ad..31481e84 100644
--- a/test-suite/output/UnclosedBlocks.out
+++ b/test-suite/output/UnclosedBlocks.out
@@ -1,3 +1,2 @@
-
Error: The section Baz, module type Bar and module Foo need to be closed.
diff --git a/test-suite/output/Unicode.out b/test-suite/output/Unicode.out
new file mode 100644
index 00000000..a57b3bba
--- /dev/null
+++ b/test-suite/output/Unicode.out
@@ -0,0 +1,41 @@
+1 subgoal
+
+ very_very_long_type_name1 : Type
+ very_very_long_type_name2 : Type
+ f : very_very_long_type_name1 → very_very_long_type_name2 → Prop
+ ============================
+ True
+ → True
+ → ∀ (x : very_very_long_type_name1) (y : very_very_long_type_name2),
+ f x y ∧ f x y ∧ f x y ∧ f x y ∧ f x y ∧ f x y
+1 subgoal
+
+ very_very_long_type_name1 : Type
+ very_very_long_type_name2 : Type
+ f : very_very_long_type_name1 → very_very_long_type_name2 → Prop
+ ============================
+ True
+ → True
+ → ∀ (x : very_very_long_type_name2) (y : very_very_long_type_name1)
+ (z : very_very_long_type_name2), f y x ∧ f y z
+1 subgoal
+
+ very_very_long_type_name1 : Type
+ very_very_long_type_name2 : Type
+ f : very_very_long_type_name1 → very_very_long_type_name2 → Prop
+ ============================
+ True
+ → True
+ → ∀ (x : very_very_long_type_name2) (y : very_very_long_type_name1)
+ (z : very_very_long_type_name2),
+ f y x ∧ f y z ∧ f y x ∧ f y z ∧ f y x ∧ f y z
+1 subgoal
+
+ very_very_long_type_name1 : Type
+ very_very_long_type_name2 : Type
+ f : very_very_long_type_name1 → very_very_long_type_name2 → Prop
+ ============================
+ True
+ → True
+ → ∃ (x : very_very_long_type_name1) (y : very_very_long_type_name2),
+ f x y ∧ f x y ∧ f x y ∧ f x y ∧ f x y ∧ f x y
diff --git a/test-suite/output/Unicode.v b/test-suite/output/Unicode.v
new file mode 100644
index 00000000..42b07e5a
--- /dev/null
+++ b/test-suite/output/Unicode.v
@@ -0,0 +1,28 @@
+Require Import Coq.Unicode.Utf8.
+
+Section test.
+Context (very_very_long_type_name1 : Type) (very_very_long_type_name2 : Type).
+Context (f : very_very_long_type_name1 -> very_very_long_type_name2 -> Prop).
+
+Lemma test : True -> True ->
+ forall (x : very_very_long_type_name1) (y : very_very_long_type_name2),
+ f x y /\ f x y /\ f x y /\ f x y /\ f x y /\ f x y.
+Proof. Show. Abort.
+
+Lemma test : True -> True ->
+ forall (x : very_very_long_type_name2) (y : very_very_long_type_name1)
+ (z : very_very_long_type_name2),
+ f y x /\ f y z.
+Proof. Show. Abort.
+
+Lemma test : True -> True ->
+ forall (x : very_very_long_type_name2) (y : very_very_long_type_name1)
+ (z : very_very_long_type_name2),
+ f y x /\ f y z /\ f y x /\ f y z /\ f y x /\ f y z.
+Proof. Show. Abort.
+
+Lemma test : True -> True ->
+ exists (x : very_very_long_type_name1) (y : very_very_long_type_name2),
+ f x y /\ f x y /\ f x y /\ f x y /\ f x y /\ f x y.
+Proof. Show. Abort.
+End test.
diff --git a/test-suite/output/bug5778.out b/test-suite/output/bug5778.out
index 91ceb1b5..d6056c50 100644
--- a/test-suite/output/bug5778.out
+++ b/test-suite/output/bug5778.out
@@ -1,4 +1,4 @@
The command has indeed failed with message:
-In nested Ltac calls to "c", "abs" and "abstract b ltac:(())", last call
-failed.
+In nested Ltac calls to "c", "abs", "abstract b ltac:(())",
+"b", "a", "pose (I : I)" and "(I : I)", last term evaluation failed.
The term "I" has type "True" which should be Set, Prop or Type.
diff --git a/test-suite/output/bug6404.out b/test-suite/output/bug6404.out
new file mode 100644
index 00000000..05464755
--- /dev/null
+++ b/test-suite/output/bug6404.out
@@ -0,0 +1,4 @@
+The command has indeed failed with message:
+In nested Ltac calls to "c", "abs", "transparent_abstract (tactic3)",
+"b", "a", "pose (I : I)" and "(I : I)", last term evaluation failed.
+The term "I" has type "True" which should be Set, Prop or Type.
diff --git a/test-suite/output/bug6404.v b/test-suite/output/bug6404.v
new file mode 100644
index 00000000..bbe6b1a0
--- /dev/null
+++ b/test-suite/output/bug6404.v
@@ -0,0 +1,7 @@
+Ltac a _ := pose (I : I).
+Ltac b _ := a ().
+Ltac abs _ := transparent_abstract b ().
+Ltac c _ := abs ().
+Goal True.
+ Fail c ().
+Abort.
diff --git a/test-suite/output/ltac.v b/test-suite/output/ltac.v
index 6adbe95d..901b1e3a 100644
--- a/test-suite/output/ltac.v
+++ b/test-suite/output/ltac.v
@@ -37,17 +37,20 @@ Fail g1 I.
Fail f1 I.
Fail g2 I.
Fail f2 I.
+Abort.
Ltac h x := injection x.
Goal True -> False.
Fail h I.
intro H.
Fail h H.
+Abort.
(* Check printing of the "var" argument "Hx" *)
Ltac m H := idtac H; exact H.
Goal True.
let a:=constr:(let Hx := 0 in ltac:(m Hx)) in idtac.
+Abort.
(* Check consistency of interpretation scopes (#4398) *)
diff --git a/test-suite/output/ltac_missing_args.out b/test-suite/output/ltac_missing_args.out
index 7326f137..8a00cd3f 100644
--- a/test-suite/output/ltac_missing_args.out
+++ b/test-suite/output/ltac_missing_args.out
@@ -1,25 +1,25 @@
The command has indeed failed with message:
-The user-defined tactic "Top.foo" was not fully applied:
+The user-defined tactic "foo" was not fully applied:
There is a missing argument for variable x,
no arguments at all were provided.
The command has indeed failed with message:
-The user-defined tactic "Top.bar" was not fully applied:
+The user-defined tactic "bar" was not fully applied:
There is a missing argument for variable x,
no arguments at all were provided.
The command has indeed failed with message:
-The user-defined tactic "Top.bar" was not fully applied:
+The user-defined tactic "bar" was not fully applied:
There are missing arguments for variables y and _,
an argument was provided for variable x.
The command has indeed failed with message:
-The user-defined tactic "Top.baz" was not fully applied:
+The user-defined tactic "baz" was not fully applied:
There is a missing argument for variable x,
no arguments at all were provided.
The command has indeed failed with message:
-The user-defined tactic "Top.qux" was not fully applied:
+The user-defined tactic "qux" was not fully applied:
There is a missing argument for variable x,
no arguments at all were provided.
The command has indeed failed with message:
-The user-defined tactic "Top.mydo" was not fully applied:
+The user-defined tactic "mydo" was not fully applied:
There is a missing argument for variable _,
no arguments at all were provided.
The command has indeed failed with message:
@@ -31,7 +31,7 @@ An unnamed user-defined tactic was not fully applied:
There is a missing argument for variable _,
no arguments at all were provided.
The command has indeed failed with message:
-The user-defined tactic "Top.rec" was not fully applied:
+The user-defined tactic "rec" was not fully applied:
There is a missing argument for variable x,
no arguments at all were provided.
The command has indeed failed with message:
diff --git a/test-suite/output/ssr_explain_match.out b/test-suite/output/ssr_explain_match.out
new file mode 100644
index 00000000..32cfb354
--- /dev/null
+++ b/test-suite/output/ssr_explain_match.out
@@ -0,0 +1,55 @@
+File "stdin", line 12, characters 0-61:
+Warning: Notation "_ - _" was already used in scope nat_scope.
+[notation-overridden,parsing]
+File "stdin", line 12, characters 0-61:
+Warning: Notation "_ <= _" was already used in scope nat_scope.
+[notation-overridden,parsing]
+File "stdin", line 12, characters 0-61:
+Warning: Notation "_ < _" was already used in scope nat_scope.
+[notation-overridden,parsing]
+File "stdin", line 12, characters 0-61:
+Warning: Notation "_ >= _" was already used in scope nat_scope.
+[notation-overridden,parsing]
+File "stdin", line 12, characters 0-61:
+Warning: Notation "_ > _" was already used in scope nat_scope.
+[notation-overridden,parsing]
+File "stdin", line 12, characters 0-61:
+Warning: Notation "_ <= _ <= _" was already used in scope nat_scope.
+[notation-overridden,parsing]
+File "stdin", line 12, characters 0-61:
+Warning: Notation "_ < _ <= _" was already used in scope nat_scope.
+[notation-overridden,parsing]
+File "stdin", line 12, characters 0-61:
+Warning: Notation "_ <= _ < _" was already used in scope nat_scope.
+[notation-overridden,parsing]
+File "stdin", line 12, characters 0-61:
+Warning: Notation "_ < _ < _" was already used in scope nat_scope.
+[notation-overridden,parsing]
+File "stdin", line 12, characters 0-61:
+Warning: Notation "_ + _" was already used in scope nat_scope.
+[notation-overridden,parsing]
+File "stdin", line 12, characters 0-61:
+Warning: Notation "_ * _" was already used in scope nat_scope.
+[notation-overridden,parsing]
+BEGIN INSTANCES
+instance: (x + y + z) matches: (x + y + z)
+instance: (x + y) matches: (x + y)
+instance: (x + y) matches: (x + y)
+END INSTANCES
+BEGIN INSTANCES
+instance: (addnC (x + y) z) matches: (x + y + z)
+instance: (addnC x y) matches: (x + y)
+instance: (addnC x y) matches: (x + y)
+END INSTANCES
+BEGIN INSTANCES
+instance: (addnA x y z) matches: (x + y + z)
+END INSTANCES
+BEGIN INSTANCES
+instance: (addnA x y z) matches: (x + y + z)
+instance: (addnC z (x + y)) matches: (x + y + z)
+instance: (addnC y x) matches: (x + y)
+instance: (addnC y x) matches: (x + y)
+END INSTANCES
+The command has indeed failed with message:
+Ltac call to "ssrinstancesoftpat (cpattern)" failed.
+Not supported
diff --git a/test-suite/output/ssr_explain_match.v b/test-suite/output/ssr_explain_match.v
new file mode 100644
index 00000000..56ca24b6
--- /dev/null
+++ b/test-suite/output/ssr_explain_match.v
@@ -0,0 +1,23 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+Require Import ssrmatching.
+Require Import ssreflect ssrbool TestSuite.ssr_mini_mathcomp.
+
+Definition addnAC := (addnA, addnC).
+
+Lemma test x y z : x + y + z = x + y.
+
+ssrinstancesoftpat (_ + _).
+ssrinstancesofruleL2R addnC.
+ssrinstancesofruleR2L addnA.
+ssrinstancesofruleR2L addnAC.
+Fail ssrinstancesoftpat (_ + _ in RHS). (* Not implemented *)
+Admitted.
diff --git a/test-suite/prerequisite/make_local.v b/test-suite/prerequisite/make_local.v
index 8700a6c4..6d9117c0 100644
--- a/test-suite/prerequisite/make_local.v
+++ b/test-suite/prerequisite/make_local.v
@@ -2,8 +2,7 @@
Definition f (A:Type) (a:A) := a.
-Local Arguments Scope f [type_scope type_scope].
-Local Implicit Arguments f [A].
+Local Arguments f [A]%type_scope _%type_scope.
(* Used in ImportedCoercion.v to test the locality flag *)
diff --git a/test-suite/prerequisite/ssr_mini_mathcomp.v b/test-suite/prerequisite/ssr_mini_mathcomp.v
new file mode 100644
index 00000000..cb2c5673
--- /dev/null
+++ b/test-suite/prerequisite/ssr_mini_mathcomp.v
@@ -0,0 +1,1472 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* Some code from mathcomp needed in order to run ssr_* tests *)
+
+Require Import ssreflect ssrfun ssrbool.
+
+Global Set SsrOldRewriteGoalsOrder.
+Global Set Asymmetric Patterns.
+Global Set Bullet Behavior "None".
+
+Set Implicit Arguments.
+Unset Strict Implicit.
+Unset Printing Implicit Defensive.
+
+(* eqtype ---------------------------------------------------------- *)
+
+Module Equality.
+
+Definition axiom T (e : rel T) := forall x y, reflect (x = y) (e x y).
+
+Structure mixin_of T := Mixin {op : rel T; _ : axiom op}.
+Notation class_of := mixin_of (only parsing).
+
+Section ClassDef.
+
+Structure type := Pack {sort; _ : class_of sort; _ : Type}.
+Local Coercion sort : type >-> Sortclass.
+Variables (T : Type) (cT : type).
+
+Definition class := let: Pack _ c _ := cT return class_of cT in c.
+
+Definition pack c := @Pack T c T.
+Definition clone := fun c & cT -> T & phant_id (pack c) cT => pack c.
+
+End ClassDef.
+
+Module Exports.
+Coercion sort : type >-> Sortclass.
+Notation eqType := type.
+Notation EqMixin := Mixin.
+Notation EqType T m := (@pack T m).
+Notation "[ 'eqMixin' 'of' T ]" := (class _ : mixin_of T)
+ (at level 0, format "[ 'eqMixin' 'of' T ]") : form_scope.
+Notation "[ 'eqType' 'of' T 'for' C ]" := (@clone T C _ idfun id)
+ (at level 0, format "[ 'eqType' 'of' T 'for' C ]") : form_scope.
+Notation "[ 'eqType' 'of' T ]" := (@clone T _ _ id id)
+ (at level 0, format "[ 'eqType' 'of' T ]") : form_scope.
+End Exports.
+
+End Equality.
+Export Equality.Exports.
+
+Definition eq_op T := Equality.op (Equality.class T).
+
+Lemma eqE T x : eq_op x = Equality.op (Equality.class T) x.
+Proof. by []. Qed.
+
+Lemma eqP T : Equality.axiom (@eq_op T).
+Proof. by case: T => ? []. Qed.
+Arguments eqP [T x y].
+
+Delimit Scope eq_scope with EQ.
+Open Scope eq_scope.
+
+Notation "x == y" := (eq_op x y)
+ (at level 70, no associativity) : bool_scope.
+Notation "x == y :> T" := ((x : T) == (y : T))
+ (at level 70, y at next level) : bool_scope.
+Notation "x != y" := (~~ (x == y))
+ (at level 70, no associativity) : bool_scope.
+Notation "x != y :> T" := (~~ (x == y :> T))
+ (at level 70, y at next level) : bool_scope.
+Notation "x =P y" := (eqP : reflect (x = y) (x == y))
+ (at level 70, no associativity) : eq_scope.
+Notation "x =P y :> T" := (eqP : reflect (x = y :> T) (x == y :> T))
+ (at level 70, y at next level, no associativity) : eq_scope.
+
+Prenex Implicits eq_op eqP.
+
+Lemma eq_refl (T : eqType) (x : T) : x == x. Proof. exact/eqP. Qed.
+Notation eqxx := eq_refl.
+
+Lemma eq_sym (T : eqType) (x y : T) : (x == y) = (y == x).
+Proof. exact/eqP/eqP. Qed.
+
+Hint Resolve eq_refl eq_sym.
+
+
+Definition eqb b := addb (~~ b).
+
+Lemma eqbP : Equality.axiom eqb.
+Proof. by do 2!case; constructor. Qed.
+
+Canonical bool_eqMixin := EqMixin eqbP.
+Canonical bool_eqType := Eval hnf in EqType bool bool_eqMixin.
+
+Section ProdEqType.
+
+Variable T1 T2 : eqType.
+
+Definition pair_eq := [rel u v : T1 * T2 | (u.1 == v.1) && (u.2 == v.2)].
+
+Lemma pair_eqP : Equality.axiom pair_eq.
+Proof.
+move=> [x1 x2] [y1 y2] /=; apply: (iffP andP) => [[]|[<- <-]] //=.
+by do 2!move/eqP->.
+Qed.
+
+Definition prod_eqMixin := EqMixin pair_eqP.
+Canonical prod_eqType := Eval hnf in EqType (T1 * T2) prod_eqMixin.
+
+End ProdEqType.
+
+Section OptionEqType.
+
+Variable T : eqType.
+
+Definition opt_eq (u v : option T) : bool :=
+ oapp (fun x => oapp (eq_op x) false v) (~~ v) u.
+
+Lemma opt_eqP : Equality.axiom opt_eq.
+Proof.
+case=> [x|] [y|] /=; by [constructor | apply: (iffP eqP) => [|[]] ->].
+Qed.
+
+Canonical option_eqMixin := EqMixin opt_eqP.
+Canonical option_eqType := Eval hnf in EqType (option T) option_eqMixin.
+
+End OptionEqType.
+
+Notation xpred1 := (fun a1 x => x == a1).
+Notation xpredU1 := (fun a1 (p : pred _) x => (x == a1) || p x).
+
+Section EqPred.
+
+Variable T : eqType.
+
+Definition pred1 (a1 : T) := SimplPred (xpred1 a1).
+Definition predU1 (a1 : T) p := SimplPred (xpredU1 a1 p).
+
+End EqPred.
+
+Section TransferEqType.
+
+Variables (T : Type) (eT : eqType) (f : T -> eT).
+
+Lemma inj_eqAxiom : injective f -> Equality.axiom (fun x y => f x == f y).
+Proof. by move=> f_inj x y; apply: (iffP eqP) => [|-> //]; apply: f_inj. Qed.
+
+Definition InjEqMixin f_inj := EqMixin (inj_eqAxiom f_inj).
+
+Definition PcanEqMixin g (fK : pcancel f g) := InjEqMixin (pcan_inj fK).
+
+Definition CanEqMixin g (fK : cancel f g) := InjEqMixin (can_inj fK).
+
+End TransferEqType.
+
+(* We use the module system to circumvent a silly limitation that *)
+(* forbids using the same constant to coerce to different targets. *)
+Module Type EqTypePredSig.
+Parameter sort : eqType -> predArgType.
+End EqTypePredSig.
+Module MakeEqTypePred (eqmod : EqTypePredSig).
+Coercion eqmod.sort : eqType >-> predArgType.
+End MakeEqTypePred.
+Module Export EqTypePred := MakeEqTypePred Equality.
+
+
+Section SubType.
+
+Variables (T : Type) (P : pred T).
+
+Structure subType : Type := SubType {
+ sub_sort :> Type;
+ val : sub_sort -> T;
+ Sub : forall x, P x -> sub_sort;
+ _ : forall K (_ : forall x Px, K (@Sub x Px)) u, K u;
+ _ : forall x Px, val (@Sub x Px) = x
+}.
+
+Arguments Sub [s].
+Lemma vrefl : forall x, P x -> x = x. Proof. by []. Qed.
+Definition vrefl_rect := vrefl.
+
+Definition clone_subType U v :=
+ fun sT & sub_sort sT -> U =>
+ fun c Urec cK (sT' := @SubType U v c Urec cK) & phant_id sT' sT => sT'.
+
+Variable sT : subType.
+
+CoInductive Sub_spec : sT -> Type := SubSpec x Px : Sub_spec (Sub x Px).
+
+Lemma SubP u : Sub_spec u.
+Proof. by case: sT Sub_spec SubSpec u => T' _ C rec /= _. Qed.
+
+Lemma SubK x Px : @val sT (Sub x Px) = x.
+Proof. by case: sT. Qed.
+
+Definition insub x :=
+ if @idP (P x) is ReflectT Px then @Some sT (Sub x Px) else None.
+
+Definition insubd u0 x := odflt u0 (insub x).
+
+CoInductive insub_spec x : option sT -> Type :=
+ | InsubSome u of P x & val u = x : insub_spec x (Some u)
+ | InsubNone of ~~ P x : insub_spec x None.
+
+Lemma insubP x : insub_spec x (insub x).
+Proof.
+by rewrite /insub; case: {-}_ / idP; [left; rewrite ?SubK | right; apply/negP].
+Qed.
+
+Lemma insubT x Px : insub x = Some (Sub x Px).
+Admitted.
+
+Lemma insubF x : P x = false -> insub x = None.
+Proof. by move/idP; case: insubP. Qed.
+
+Lemma insubN x : ~~ P x -> insub x = None.
+Proof. by move/negPf/insubF. Qed.
+
+Lemma isSome_insub : ([eta insub] : pred T) =1 P.
+Proof. by apply: fsym => x; case: insubP => // /negPf. Qed.
+
+Lemma insubK : ocancel insub (@val _).
+Proof. by move=> x; case: insubP. Qed.
+
+Lemma valP (u : sT) : P (val u).
+Proof. by case/SubP: u => x Px; rewrite SubK. Qed.
+
+Lemma valK : pcancel (@val _) insub.
+Proof. by case/SubP=> x Px; rewrite SubK; apply: insubT. Qed.
+
+Lemma val_inj : injective (@val sT).
+Proof. exact: pcan_inj valK. Qed.
+
+Lemma valKd u0 : cancel (@val _) (insubd u0).
+Proof. by move=> u; rewrite /insubd valK. Qed.
+
+Lemma val_insubd u0 x : val (insubd u0 x) = if P x then x else val u0.
+Proof. by rewrite /insubd; case: insubP => [u -> | /negPf->]. Qed.
+
+Lemma insubdK u0 : {in P, cancel (insubd u0) (@val _)}.
+Proof. by move=> x Px; rewrite /= val_insubd [P x]Px. Qed.
+
+Definition insub_eq x :=
+ let Some_sub Px := Some (Sub x Px : sT) in
+ let None_sub _ := None in
+ (if P x as Px return P x = Px -> _ then Some_sub else None_sub) (erefl _).
+
+Lemma insub_eqE : insub_eq =1 insub.
+Proof.
+rewrite /insub_eq /insub => x; case: {2 3}_ / idP (erefl _) => // Px Px'.
+by congr (Some _); apply: val_inj; rewrite !SubK.
+Qed.
+
+End SubType.
+
+Arguments SubType [T P].
+Arguments Sub [T P s].
+Arguments vrefl [T P].
+Arguments vrefl_rect [T P].
+Arguments clone_subType [T P] U v [sT] _ [c Urec cK].
+Arguments insub [T P sT].
+Arguments insubT [T] P [sT x].
+Arguments val_inj [T P sT].
+Prenex Implicits val Sub vrefl vrefl_rect insub insubd val_inj.
+
+Local Notation inlined_sub_rect :=
+ (fun K K_S u => let (x, Px) as u return K u := u in K_S x Px).
+
+Local Notation inlined_new_rect :=
+ (fun K K_S u => let (x) as u return K u := u in K_S x).
+
+Notation "[ 'subType' 'for' v ]" := (SubType _ v _ inlined_sub_rect vrefl_rect)
+ (at level 0, only parsing) : form_scope.
+
+Notation "[ 'sub' 'Type' 'for' v ]" := (SubType _ v _ _ vrefl_rect)
+ (at level 0, format "[ 'sub' 'Type' 'for' v ]") : form_scope.
+
+Notation "[ 'subType' 'for' v 'by' rec ]" := (SubType _ v _ rec vrefl)
+ (at level 0, format "[ 'subType' 'for' v 'by' rec ]") : form_scope.
+
+Notation "[ 'subType' 'of' U 'for' v ]" := (clone_subType U v id idfun)
+ (at level 0, format "[ 'subType' 'of' U 'for' v ]") : form_scope.
+
+(*
+Notation "[ 'subType' 'for' v ]" := (clone_subType _ v id idfun)
+ (at level 0, format "[ 'subType' 'for' v ]") : form_scope.
+*)
+Notation "[ 'subType' 'of' U ]" := (clone_subType U _ id id)
+ (at level 0, format "[ 'subType' 'of' U ]") : form_scope.
+
+Definition NewType T U v c Urec :=
+ let Urec' P IH := Urec P (fun x : T => IH x isT : P _) in
+ SubType U v (fun x _ => c x) Urec'.
+Arguments NewType [T U].
+
+Notation "[ 'newType' 'for' v ]" := (NewType v _ inlined_new_rect vrefl_rect)
+ (at level 0, only parsing) : form_scope.
+
+Notation "[ 'new' 'Type' 'for' v ]" := (NewType v _ _ vrefl_rect)
+ (at level 0, format "[ 'new' 'Type' 'for' v ]") : form_scope.
+
+Notation "[ 'newType' 'for' v 'by' rec ]" := (NewType v _ rec vrefl)
+ (at level 0, format "[ 'newType' 'for' v 'by' rec ]") : form_scope.
+
+Definition innew T nT x := @Sub T predT nT x (erefl true).
+Arguments innew [T nT].
+Prenex Implicits innew.
+
+Lemma innew_val T nT : cancel val (@innew T nT).
+Proof. by move=> u; apply: val_inj; apply: SubK. Qed.
+
+(* Prenex Implicits and renaming. *)
+Notation sval := (@proj1_sig _ _).
+Notation "@ 'sval'" := (@proj1_sig) (at level 10, format "@ 'sval'").
+
+Section SubEqType.
+
+Variables (T : eqType) (P : pred T) (sT : subType P).
+
+Local Notation ev_ax := (fun T v => @Equality.axiom T (fun x y => v x == v y)).
+Lemma val_eqP : ev_ax sT val. Proof. exact: inj_eqAxiom val_inj. Qed.
+
+Definition sub_eqMixin := EqMixin val_eqP.
+Canonical sub_eqType := Eval hnf in EqType sT sub_eqMixin.
+
+Definition SubEqMixin :=
+ (let: SubType _ v _ _ _ as sT' := sT
+ return ev_ax sT' val -> Equality.class_of sT' in
+ fun vP : ev_ax _ v => EqMixin vP
+ ) val_eqP.
+
+Lemma val_eqE (u v : sT) : (val u == val v) = (u == v).
+Proof. by []. Qed.
+
+End SubEqType.
+
+Arguments val_eqP [T P sT x y].
+Prenex Implicits val_eqP.
+
+Notation "[ 'eqMixin' 'of' T 'by' <: ]" := (SubEqMixin _ : Equality.class_of T)
+ (at level 0, format "[ 'eqMixin' 'of' T 'by' <: ]") : form_scope.
+
+(* ssrnat ---------------------------------------------------------- *)
+
+Notation succn := Datatypes.S.
+Notation predn := Peano.pred.
+
+Notation "n .+1" := (succn n) (at level 2, left associativity,
+ format "n .+1") : nat_scope.
+Notation "n .+2" := n.+1.+1 (at level 2, left associativity,
+ format "n .+2") : nat_scope.
+Notation "n .+3" := n.+2.+1 (at level 2, left associativity,
+ format "n .+3") : nat_scope.
+Notation "n .+4" := n.+2.+2 (at level 2, left associativity,
+ format "n .+4") : nat_scope.
+
+Notation "n .-1" := (predn n) (at level 2, left associativity,
+ format "n .-1") : nat_scope.
+Notation "n .-2" := n.-1.-1 (at level 2, left associativity,
+ format "n .-2") : nat_scope.
+
+Fixpoint eqn m n {struct m} :=
+ match m, n with
+ | 0, 0 => true
+ | m'.+1, n'.+1 => eqn m' n'
+ | _, _ => false
+ end.
+
+Lemma eqnP : Equality.axiom eqn.
+Proof.
+move=> n m; apply: (iffP idP) => [|<-]; last by elim n.
+by elim: n m => [|n IHn] [|m] //= /IHn->.
+Qed.
+
+Canonical nat_eqMixin := EqMixin eqnP.
+Canonical nat_eqType := Eval hnf in EqType nat nat_eqMixin.
+
+Arguments eqnP [x y].
+Prenex Implicits eqnP.
+
+Coercion nat_of_bool (b : bool) := if b then 1 else 0.
+
+Fixpoint odd n := if n is n'.+1 then ~~ odd n' else false.
+
+Lemma oddb (b : bool) : odd b = b. Proof. by case: b. Qed.
+
+Definition subn_rec := minus.
+Notation "m - n" := (subn_rec m n) : nat_rec_scope.
+
+Definition subn := nosimpl subn_rec.
+Notation "m - n" := (subn m n) : nat_scope.
+
+Definition leq m n := m - n == 0.
+
+Notation "m <= n" := (leq m n) : nat_scope.
+Notation "m < n" := (m.+1 <= n) : nat_scope.
+Notation "m >= n" := (n <= m) (only parsing) : nat_scope.
+Notation "m > n" := (n < m) (only parsing) : nat_scope.
+
+
+Notation "m <= n <= p" := ((m <= n) && (n <= p)) : nat_scope.
+Notation "m < n <= p" := ((m < n) && (n <= p)) : nat_scope.
+Notation "m <= n < p" := ((m <= n) && (n < p)) : nat_scope.
+Notation "m < n < p" := ((m < n) && (n < p)) : nat_scope.
+
+Open Scope nat_scope.
+
+
+Lemma ltnS m n : (m < n.+1) = (m <= n). Proof. by []. Qed.
+Lemma leq0n n : 0 <= n. Proof. by []. Qed.
+Lemma ltn0Sn n : 0 < n.+1. Proof. by []. Qed.
+Lemma ltn0 n : n < 0 = false. Proof. by []. Qed.
+Lemma leqnn n : n <= n. Proof. by elim: n. Qed.
+Hint Resolve leqnn.
+Lemma leqnSn n : n <= n.+1. Proof. by elim: n. Qed.
+
+Lemma leq_trans n m p : m <= n -> n <= p -> m <= p.
+Admitted.
+Lemma leqW m n : m <= n -> m <= n.+1.
+Admitted.
+Hint Resolve leqnSn.
+Lemma ltnW m n : m < n -> m <= n.
+Proof. exact: leq_trans. Qed.
+Hint Resolve ltnW.
+
+Definition addn_rec := plus.
+Notation "m + n" := (addn_rec m n) : nat_rec_scope.
+
+Definition addn := nosimpl addn_rec.
+Notation "m + n" := (addn m n) : nat_scope.
+
+Lemma addn0 : right_id 0 addn. Proof. by move=> n; apply/eqP; elim: n. Qed.
+Lemma add0n : left_id 0 addn. Proof. by []. Qed.
+Lemma addSn m n : m.+1 + n = (m + n).+1. Proof. by []. Qed.
+Lemma addnS m n : m + n.+1 = (m + n).+1. Proof. by elim: m. Qed.
+
+Lemma addnCA : left_commutative addn.
+Proof. by move=> m n p; elim: m => //= m; rewrite addnS => <-. Qed.
+
+Lemma addnC : commutative addn.
+Proof. by move=> m n; rewrite -{1}[n]addn0 addnCA addn0. Qed.
+
+Lemma addnA : associative addn.
+Proof. by move=> m n p; rewrite (addnC n) addnCA addnC. Qed.
+
+Lemma subnK m n : m <= n -> (n - m) + m = n.
+Admitted.
+
+
+Definition muln_rec := mult.
+Notation "m * n" := (muln_rec m n) : nat_rec_scope.
+
+Definition muln := nosimpl muln_rec.
+Notation "m * n" := (muln m n) : nat_scope.
+
+Lemma mul0n : left_zero 0 muln. Proof. by []. Qed.
+Lemma muln0 : right_zero 0 muln. Proof. by elim. Qed.
+Lemma mul1n : left_id 1 muln. Proof. exact: addn0. Qed.
+
+Lemma mulSn m n : m.+1 * n = n + m * n. Proof. by []. Qed.
+Lemma mulSnr m n : m.+1 * n = m * n + n. Proof. exact: addnC. Qed.
+
+Lemma mulnS m n : m * n.+1 = m + m * n.
+Proof. by elim: m => // m; rewrite !mulSn !addSn addnCA => ->. Qed.
+
+Lemma mulnSr m n : m * n.+1 = m * n + m.
+Proof. by rewrite addnC mulnS. Qed.
+
+Lemma muln1 : right_id 1 muln.
+Proof. by move=> n; rewrite mulnSr muln0. Qed.
+
+Lemma mulnC : commutative muln.
+Proof.
+by move=> m n; elim: m => [|m]; rewrite (muln0, mulnS) // mulSn => ->.
+Qed.
+
+Lemma mulnDl : left_distributive muln addn.
+Proof. by move=> m1 m2 n; elim: m1 => //= m1 IHm; rewrite -addnA -IHm. Qed.
+
+Lemma mulnDr : right_distributive muln addn.
+Proof. by move=> m n1 n2; rewrite !(mulnC m) mulnDl. Qed.
+
+Lemma mulnA : associative muln.
+Proof. by move=> m n p; elim: m => //= m; rewrite mulSn mulnDl => ->. Qed.
+
+Lemma mulnCA : left_commutative muln.
+Proof. by move=> m n1 n2; rewrite !mulnA (mulnC m). Qed.
+
+Lemma mulnAC : right_commutative muln.
+Proof. by move=> m n p; rewrite -!mulnA (mulnC n). Qed.
+
+Lemma mulnACA : interchange muln muln.
+Proof. by move=> m n p q; rewrite -!mulnA (mulnCA n). Qed.
+
+(* seq ------------------------------------------------------------- *)
+
+Delimit Scope seq_scope with SEQ.
+Open Scope seq_scope.
+
+(* Inductive seq (T : Type) : Type := Nil | Cons of T & seq T. *)
+Notation seq := list.
+Prenex Implicits cons.
+Notation Cons T := (@cons T) (only parsing).
+Notation Nil T := (@nil T) (only parsing).
+
+Bind Scope seq_scope with list.
+Arguments cons _%type _ _%SEQ.
+
+(* As :: and ++ are (improperly) declared in Init.datatypes, we only rebind *)
+(* them here. *)
+Infix "::" := cons : seq_scope.
+
+(* GG - this triggers a camlp4 warning, as if this Notation had been Reserved *)
+Notation "[ :: ]" := nil (at level 0, format "[ :: ]") : seq_scope.
+
+Notation "[ :: x1 ]" := (x1 :: [::])
+ (at level 0, format "[ :: x1 ]") : seq_scope.
+
+Notation "[ :: x & s ]" := (x :: s) (at level 0, only parsing) : seq_scope.
+
+Notation "[ :: x1 , x2 , .. , xn & s ]" := (x1 :: x2 :: .. (xn :: s) ..)
+ (at level 0, format
+ "'[hv' [ :: '[' x1 , '/' x2 , '/' .. , '/' xn ']' '/ ' & s ] ']'"
+ ) : seq_scope.
+
+Notation "[ :: x1 ; x2 ; .. ; xn ]" := (x1 :: x2 :: .. [:: xn] ..)
+ (at level 0, format "[ :: '[' x1 ; '/' x2 ; '/' .. ; '/' xn ']' ]"
+ ) : seq_scope.
+
+Section Sequences.
+
+Variable n0 : nat. (* numerical parameter for take, drop et al *)
+Variable T : Type. (* must come before the implicit Type *)
+Variable x0 : T. (* default for head/nth *)
+
+Implicit Types x y z : T.
+Implicit Types m n : nat.
+Implicit Type s : seq T.
+
+Fixpoint size s := if s is _ :: s' then (size s').+1 else 0.
+
+Fixpoint cat s1 s2 := if s1 is x :: s1' then x :: s1' ++ s2 else s2
+where "s1 ++ s2" := (cat s1 s2) : seq_scope.
+
+Lemma cat0s s : [::] ++ s = s. Proof. by []. Qed.
+
+Lemma cats0 s : s ++ [::] = s.
+Proof. by elim: s => //= x s ->. Qed.
+
+Lemma catA s1 s2 s3 : s1 ++ s2 ++ s3 = (s1 ++ s2) ++ s3.
+Proof. by elim: s1 => //= x s1 ->. Qed.
+
+Fixpoint nth s n {struct n} :=
+ if s is x :: s' then if n is n'.+1 then @nth s' n' else x else x0.
+
+Fixpoint rcons s z := if s is x :: s' then x :: rcons s' z else [:: z].
+
+CoInductive last_spec : seq T -> Type :=
+ | LastNil : last_spec [::]
+ | LastRcons s x : last_spec (rcons s x).
+
+Lemma lastP s : last_spec s.
+Proof using. Admitted.
+
+Lemma last_ind P :
+ P [::] -> (forall s x, P s -> P (rcons s x)) -> forall s, P s.
+Proof using. Admitted.
+
+
+Section Map.
+
+Variables (T2 : Type) (f : T -> T2).
+
+Fixpoint map s := if s is x :: s' then f x :: map s' else [::].
+
+End Map.
+
+Section SeqFind.
+
+Variable a : pred T.
+
+Fixpoint count s := if s is x :: s' then a x + count s' else 0.
+
+Fixpoint filter s :=
+ if s is x :: s' then if a x then x :: filter s' else filter s' else [::].
+
+End SeqFind.
+
+End Sequences.
+
+Infix "++" := cat : seq_scope.
+
+Notation count_mem x := (count (pred_of_simpl (pred1 x))).
+
+Section EqSeq.
+
+Variables (n0 : nat) (T : eqType) (x0 : T).
+Local Notation nth := (nth x0).
+Implicit Type s : seq T.
+Implicit Types x y z : T.
+
+Fixpoint eqseq s1 s2 {struct s2} :=
+ match s1, s2 with
+ | [::], [::] => true
+ | x1 :: s1', x2 :: s2' => (x1 == x2) && eqseq s1' s2'
+ | _, _ => false
+ end.
+
+Lemma eqseqP : Equality.axiom eqseq.
+Proof.
+move; elim=> [|x1 s1 IHs] [|x2 s2]; do [by constructor | simpl].
+case: (x1 =P x2) => [<-|neqx]; last by right; case.
+by apply: (iffP (IHs s2)) => [<-|[]].
+Qed.
+
+Canonical seq_eqMixin := EqMixin eqseqP.
+Canonical seq_eqType := Eval hnf in EqType (seq T) seq_eqMixin.
+
+Fixpoint mem_seq (s : seq T) :=
+ if s is y :: s' then xpredU1 y (mem_seq s') else xpred0.
+
+Definition eqseq_class := seq T.
+Identity Coercion seq_of_eqseq : eqseq_class >-> seq.
+Coercion pred_of_eq_seq (s : eqseq_class) : pred_class := [eta mem_seq s].
+
+Canonical seq_predType := @mkPredType T (seq T) pred_of_eq_seq.
+
+Fixpoint uniq s := if s is x :: s' then (x \notin s') && uniq s' else true.
+
+End EqSeq.
+
+Definition bitseq := seq bool.
+Canonical bitseq_eqType := Eval hnf in [eqType of bitseq].
+Canonical bitseq_predType := Eval hnf in [predType of bitseq].
+
+Section Pmap.
+
+Variables (aT rT : Type) (f : aT -> option rT) (g : rT -> aT).
+
+Fixpoint pmap s :=
+ if s is x :: s' then let r := pmap s' in oapp (cons^~ r) r (f x) else [::].
+
+End Pmap.
+
+Fixpoint iota m n := if n is n'.+1 then m :: iota m.+1 n' else [::].
+
+Section FoldRight.
+
+Variables (T : Type) (R : Type) (f : T -> R -> R) (z0 : R).
+
+Fixpoint foldr s := if s is x :: s' then f x (foldr s') else z0.
+
+End FoldRight.
+
+Lemma mem_iota m n i : (i \in iota m n) = (m <= i) && (i < m + n).
+Admitted.
+
+
+(* choice ------------------------------------------------------------- *)
+
+Module Choice.
+
+Section ClassDef.
+
+Record mixin_of T := Mixin {
+ find : pred T -> nat -> option T;
+ _ : forall P n x, find P n = Some x -> P x;
+ _ : forall P : pred T, (exists x, P x) -> exists n, find P n;
+ _ : forall P Q : pred T, P =1 Q -> find P =1 find Q
+}.
+
+Record class_of T := Class {base : Equality.class_of T; mixin : mixin_of T}.
+Local Coercion base : class_of >-> Equality.class_of.
+
+Structure type := Pack {sort; _ : class_of sort; _ : Type}.
+Local Coercion sort : type >-> Sortclass.
+Variables (T : Type) (cT : type).
+Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
+Definition clone c of phant_id class c := @Pack T c T.
+Let xT := let: Pack T _ _ := cT in T.
+Notation xclass := (class : class_of xT).
+
+Definition pack m :=
+ fun b bT & phant_id (Equality.class bT) b => Pack (@Class T b m) T.
+
+(* Inheritance *)
+Definition eqType := @Equality.Pack cT xclass xT.
+
+End ClassDef.
+
+Module Import Exports.
+Coercion base : class_of >-> Equality.class_of.
+Coercion sort : type >-> Sortclass.
+Coercion eqType : type >-> Equality.type.
+Canonical eqType.
+Notation choiceType := type.
+Notation choiceMixin := mixin_of.
+Notation ChoiceType T m := (@pack T m _ _ id).
+Notation "[ 'choiceType' 'of' T 'for' cT ]" := (@clone T cT _ idfun)
+ (at level 0, format "[ 'choiceType' 'of' T 'for' cT ]") : form_scope.
+Notation "[ 'choiceType' 'of' T ]" := (@clone T _ _ id)
+ (at level 0, format "[ 'choiceType' 'of' T ]") : form_scope.
+
+End Exports.
+
+End Choice.
+Export Choice.Exports.
+
+Section ChoiceTheory.
+
+Variable T : choiceType.
+
+Section CanChoice.
+
+Variables (sT : Type) (f : sT -> T).
+
+Lemma PcanChoiceMixin f' : pcancel f f' -> choiceMixin sT.
+Admitted.
+
+Definition CanChoiceMixin f' (fK : cancel f f') :=
+ PcanChoiceMixin (can_pcan fK).
+
+End CanChoice.
+
+Section SubChoice.
+
+Variables (P : pred T) (sT : subType P).
+
+Definition sub_choiceMixin := PcanChoiceMixin (@valK T P sT).
+Definition sub_choiceClass := @Choice.Class sT (sub_eqMixin sT) sub_choiceMixin.
+Canonical sub_choiceType := Choice.Pack sub_choiceClass sT.
+
+End SubChoice.
+
+
+Fact seq_choiceMixin : choiceMixin (seq T).
+Admitted.
+Canonical seq_choiceType := Eval hnf in ChoiceType (seq T) seq_choiceMixin.
+End ChoiceTheory.
+
+Fact nat_choiceMixin : choiceMixin nat.
+Proof.
+pose f := [fun (P : pred nat) n => if P n then Some n else None].
+exists f => [P n m | P [n Pn] | P Q eqPQ n] /=; last by rewrite eqPQ.
+ by case: ifP => // Pn [<-].
+by exists n; rewrite Pn.
+Qed.
+Canonical nat_choiceType := Eval hnf in ChoiceType nat nat_choiceMixin.
+
+Definition bool_choiceMixin := CanChoiceMixin oddb.
+Canonical bool_choiceType := Eval hnf in ChoiceType bool bool_choiceMixin.
+Canonical bitseq_choiceType := Eval hnf in [choiceType of bitseq].
+
+
+Notation "[ 'choiceMixin' 'of' T 'by' <: ]" :=
+ (sub_choiceMixin _ : choiceMixin T)
+ (at level 0, format "[ 'choiceMixin' 'of' T 'by' <: ]") : form_scope.
+
+
+
+
+Module Countable.
+
+Record mixin_of (T : Type) : Type := Mixin {
+ pickle : T -> nat;
+ unpickle : nat -> option T;
+ pickleK : pcancel pickle unpickle
+}.
+
+Definition EqMixin T m := PcanEqMixin (@pickleK T m).
+Definition ChoiceMixin T m := PcanChoiceMixin (@pickleK T m).
+
+Section ClassDef.
+
+Record class_of T := Class { base : Choice.class_of T; mixin : mixin_of T }.
+Local Coercion base : class_of >-> Choice.class_of.
+
+Structure type : Type := Pack {sort : Type; _ : class_of sort; _ : Type}.
+Local Coercion sort : type >-> Sortclass.
+Variables (T : Type) (cT : type).
+Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
+Definition clone c of phant_id class c := @Pack T c T.
+Let xT := let: Pack T _ _ := cT in T.
+Notation xclass := (class : class_of xT).
+
+Definition pack m :=
+ fun bT b & phant_id (Choice.class bT) b => Pack (@Class T b m) T.
+
+Definition eqType := @Equality.Pack cT xclass xT.
+Definition choiceType := @Choice.Pack cT xclass xT.
+
+End ClassDef.
+
+Module Exports.
+Coercion base : class_of >-> Choice.class_of.
+Coercion mixin : class_of >-> mixin_of.
+Coercion sort : type >-> Sortclass.
+Coercion eqType : type >-> Equality.type.
+Canonical eqType.
+Coercion choiceType : type >-> Choice.type.
+Canonical choiceType.
+Notation countType := type.
+Notation CountType T m := (@pack T m _ _ id).
+Notation CountMixin := Mixin.
+Notation CountChoiceMixin := ChoiceMixin.
+Notation "[ 'countType' 'of' T 'for' cT ]" := (@clone T cT _ idfun)
+ (at level 0, format "[ 'countType' 'of' T 'for' cT ]") : form_scope.
+Notation "[ 'countType' 'of' T ]" := (@clone T _ _ id)
+ (at level 0, format "[ 'countType' 'of' T ]") : form_scope.
+
+End Exports.
+
+End Countable.
+Export Countable.Exports.
+
+Definition unpickle T := Countable.unpickle (Countable.class T).
+Definition pickle T := Countable.pickle (Countable.class T).
+Arguments unpickle [T].
+Prenex Implicits pickle unpickle.
+
+Section CountableTheory.
+
+Variable T : countType.
+
+Lemma pickleK : @pcancel nat T pickle unpickle.
+Proof. exact: Countable.pickleK. Qed.
+
+Definition pickle_inv n :=
+ obind (fun x : T => if pickle x == n then Some x else None) (unpickle n).
+
+Lemma pickle_invK : ocancel pickle_inv pickle.
+Proof.
+by rewrite /pickle_inv => n; case def_x: (unpickle n) => //= [x]; case: eqP.
+Qed.
+
+Lemma pickleK_inv : pcancel pickle pickle_inv.
+Proof. by rewrite /pickle_inv => x; rewrite pickleK /= eqxx. Qed.
+
+Lemma pcan_pickleK sT f f' :
+ @pcancel T sT f f' -> pcancel (pickle \o f) (pcomp f' unpickle).
+Proof. by move=> fK x; rewrite /pcomp pickleK /= fK. Qed.
+
+Definition PcanCountMixin sT f f' (fK : pcancel f f') :=
+ @CountMixin sT _ _ (pcan_pickleK fK).
+
+Definition CanCountMixin sT f f' (fK : cancel f f') :=
+ @PcanCountMixin sT _ _ (can_pcan fK).
+
+Definition sub_countMixin P sT := PcanCountMixin (@valK T P sT).
+
+End CountableTheory.
+Notation "[ 'countMixin' 'of' T 'by' <: ]" :=
+ (sub_countMixin _ : Countable.mixin_of T)
+ (at level 0, format "[ 'countMixin' 'of' T 'by' <: ]") : form_scope.
+
+Section SubCountType.
+
+Variables (T : choiceType) (P : pred T).
+Import Countable.
+
+Structure subCountType : Type :=
+ SubCountType {subCount_sort :> subType P; _ : mixin_of subCount_sort}.
+
+Coercion sub_countType (sT : subCountType) :=
+ Eval hnf in pack (let: SubCountType _ m := sT return mixin_of sT in m) id.
+Canonical sub_countType.
+
+Definition pack_subCountType U :=
+ fun sT cT & sub_sort sT * sort cT -> U * U =>
+ fun b m & phant_id (Class b m) (class cT) => @SubCountType sT m.
+
+End SubCountType.
+
+(* This assumes that T has both countType and subType structures. *)
+Notation "[ 'subCountType' 'of' T ]" :=
+ (@pack_subCountType _ _ T _ _ id _ _ id)
+ (at level 0, format "[ 'subCountType' 'of' T ]") : form_scope.
+
+Lemma nat_pickleK : pcancel id (@Some nat). Proof. by []. Qed.
+Definition nat_countMixin := CountMixin nat_pickleK.
+Canonical nat_countType := Eval hnf in CountType nat nat_countMixin.
+
+(* fintype --------------------------------------------------------- *)
+
+Module Finite.
+
+Section RawMixin.
+
+Variable T : eqType.
+
+Definition axiom e := forall x : T, count_mem x e = 1.
+
+Lemma uniq_enumP e : uniq e -> e =i T -> axiom e.
+Admitted.
+
+Record mixin_of := Mixin {
+ mixin_base : Countable.mixin_of T;
+ mixin_enum : seq T;
+ _ : axiom mixin_enum
+}.
+
+End RawMixin.
+
+Section Mixins.
+
+Variable T : countType.
+
+Definition EnumMixin :=
+ let: Countable.Pack _ (Countable.Class _ m) _ as cT := T
+ return forall e : seq cT, axiom e -> mixin_of cT in
+ @Mixin (EqType _ _) m.
+
+Definition UniqMixin e Ue eT := @EnumMixin e (uniq_enumP Ue eT).
+
+Variable n : nat.
+
+End Mixins.
+
+Section ClassDef.
+
+Record class_of T := Class {
+ base : Choice.class_of T;
+ mixin : mixin_of (Equality.Pack base T)
+}.
+Definition base2 T c := Countable.Class (@base T c) (mixin_base (mixin c)).
+Local Coercion base : class_of >-> Choice.class_of.
+
+Structure type : Type := Pack {sort; _ : class_of sort; _ : Type}.
+Local Coercion sort : type >-> Sortclass.
+Variables (T : Type) (cT : type).
+Definition class := let: Pack _ c _ as cT' := cT return class_of cT' in c.
+Definition clone c of phant_id class c := @Pack T c T.
+Let xT := let: Pack T _ _ := cT in T.
+Notation xclass := (class : class_of xT).
+
+Definition pack b0 (m0 : mixin_of (EqType T b0)) :=
+ fun bT b & phant_id (Choice.class bT) b =>
+ fun m & phant_id m0 m => Pack (@Class T b m) T.
+
+Definition eqType := @Equality.Pack cT xclass xT.
+Definition choiceType := @Choice.Pack cT xclass xT.
+Definition countType := @Countable.Pack cT (base2 xclass) xT.
+
+End ClassDef.
+
+Module Import Exports.
+Coercion mixin_base : mixin_of >-> Countable.mixin_of.
+Coercion base : class_of >-> Choice.class_of.
+Coercion mixin : class_of >-> mixin_of.
+Coercion base2 : class_of >-> Countable.class_of.
+Coercion sort : type >-> Sortclass.
+Coercion eqType : type >-> Equality.type.
+Canonical eqType.
+Coercion choiceType : type >-> Choice.type.
+Canonical choiceType.
+Coercion countType : type >-> Countable.type.
+Canonical countType.
+Notation finType := type.
+Notation FinType T m := (@pack T _ m _ _ id _ id).
+Notation FinMixin := EnumMixin.
+Notation UniqFinMixin := UniqMixin.
+Notation "[ 'finType' 'of' T 'for' cT ]" := (@clone T cT _ idfun)
+ (at level 0, format "[ 'finType' 'of' T 'for' cT ]") : form_scope.
+Notation "[ 'finType' 'of' T ]" := (@clone T _ _ id)
+ (at level 0, format "[ 'finType' 'of' T ]") : form_scope.
+End Exports.
+
+Module Type EnumSig.
+Parameter enum : forall cT : type, seq cT.
+Axiom enumDef : enum = fun cT => mixin_enum (class cT).
+End EnumSig.
+
+Module EnumDef : EnumSig.
+Definition enum cT := mixin_enum (class cT).
+Definition enumDef := erefl enum.
+End EnumDef.
+
+Notation enum := EnumDef.enum.
+
+End Finite.
+Export Finite.Exports.
+
+Section SubFinType.
+
+Variables (T : choiceType) (P : pred T).
+Import Finite.
+
+Structure subFinType := SubFinType {
+ subFin_sort :> subType P;
+ _ : mixin_of (sub_eqType subFin_sort)
+}.
+
+Definition pack_subFinType U :=
+ fun cT b m & phant_id (class cT) (@Class U b m) =>
+ fun sT m' & phant_id m' m => @SubFinType sT m'.
+
+Implicit Type sT : subFinType.
+
+Definition subFin_mixin sT :=
+ let: SubFinType _ m := sT return mixin_of (sub_eqType sT) in m.
+
+Coercion subFinType_subCountType sT := @SubCountType _ _ sT (subFin_mixin sT).
+Canonical subFinType_subCountType.
+
+Coercion subFinType_finType sT :=
+ Pack (@Class sT (sub_choiceClass sT) (subFin_mixin sT)) sT.
+Canonical subFinType_finType.
+
+Definition enum_mem T (mA : mem_pred _) := filter mA (Finite.enum T).
+Definition image_mem T T' f mA : seq T' := map f (@enum_mem T mA).
+Definition codom T T' f := @image_mem T T' f (mem T).
+
+Lemma codom_val sT x : (x \in codom (val : sT -> T)) = P x.
+Admitted.
+
+End SubFinType.
+
+
+(* This assumes that T has both finType and subCountType structures. *)
+Notation "[ 'subFinType' 'of' T ]" := (@pack_subFinType _ _ T _ _ _ id _ _ id)
+ (at level 0, format "[ 'subFinType' 'of' T ]") : form_scope.
+
+
+
+Section OrdinalSub.
+
+Variable n : nat.
+
+Inductive ordinal : predArgType := Ordinal m of m < n.
+
+Coercion nat_of_ord i := let: Ordinal m _ := i in m.
+
+Canonical ordinal_subType := [subType for nat_of_ord].
+Definition ordinal_eqMixin := Eval hnf in [eqMixin of ordinal by <:].
+Canonical ordinal_eqType := Eval hnf in EqType ordinal ordinal_eqMixin.
+Definition ordinal_choiceMixin := [choiceMixin of ordinal by <:].
+Canonical ordinal_choiceType :=
+ Eval hnf in ChoiceType ordinal ordinal_choiceMixin.
+Definition ordinal_countMixin := [countMixin of ordinal by <:].
+Canonical ordinal_countType := Eval hnf in CountType ordinal ordinal_countMixin.
+Canonical ordinal_subCountType := [subCountType of ordinal].
+
+Lemma ltn_ord (i : ordinal) : i < n. Proof. exact: valP i. Qed.
+
+Lemma ord_inj : injective nat_of_ord. Proof. exact: val_inj. Qed.
+
+Definition ord_enum : seq ordinal := pmap insub (iota 0 n).
+
+Lemma val_ord_enum : map val ord_enum = iota 0 n.
+Admitted.
+
+Lemma ord_enum_uniq : uniq ord_enum.
+Admitted.
+
+Lemma mem_ord_enum i : i \in ord_enum.
+Admitted.
+
+Definition ordinal_finMixin :=
+ Eval hnf in UniqFinMixin ord_enum_uniq mem_ord_enum.
+Canonical ordinal_finType := Eval hnf in FinType ordinal ordinal_finMixin.
+Canonical ordinal_subFinType := Eval hnf in [subFinType of ordinal].
+
+End OrdinalSub.
+
+Notation "''I_' n" := (ordinal n)
+ (at level 8, n at level 2, format "''I_' n").
+
+(* bigop ----------------------------------------------------------------- *)
+
+Reserved Notation "\big [ op / idx ]_ i F"
+ (at level 36, F at level 36, op, idx at level 10, i at level 0,
+ right associativity,
+ format "'[' \big [ op / idx ]_ i '/ ' F ']'").
+Reserved Notation "\big [ op / idx ]_ ( i <- r | P ) F"
+ (at level 36, F at level 36, op, idx at level 10, i, r at level 50,
+ format "'[' \big [ op / idx ]_ ( i <- r | P ) '/ ' F ']'").
+Reserved Notation "\big [ op / idx ]_ ( i <- r ) F"
+ (at level 36, F at level 36, op, idx at level 10, i, r at level 50,
+ format "'[' \big [ op / idx ]_ ( i <- r ) '/ ' F ']'").
+Reserved Notation "\big [ op / idx ]_ ( m <= i < n | P ) F"
+ (at level 36, F at level 36, op, idx at level 10, m, i, n at level 50,
+ format "'[' \big [ op / idx ]_ ( m <= i < n | P ) F ']'").
+Reserved Notation "\big [ op / idx ]_ ( m <= i < n ) F"
+ (at level 36, F at level 36, op, idx at level 10, i, m, n at level 50,
+ format "'[' \big [ op / idx ]_ ( m <= i < n ) '/ ' F ']'").
+Reserved Notation "\big [ op / idx ]_ ( i | P ) F"
+ (at level 36, F at level 36, op, idx at level 10, i at level 50,
+ format "'[' \big [ op / idx ]_ ( i | P ) '/ ' F ']'").
+Reserved Notation "\big [ op / idx ]_ ( i : t | P ) F"
+ (at level 36, F at level 36, op, idx at level 10, i at level 50,
+ format "'[' \big [ op / idx ]_ ( i : t | P ) '/ ' F ']'").
+Reserved Notation "\big [ op / idx ]_ ( i : t ) F"
+ (at level 36, F at level 36, op, idx at level 10, i at level 50,
+ format "'[' \big [ op / idx ]_ ( i : t ) '/ ' F ']'").
+Reserved Notation "\big [ op / idx ]_ ( i < n | P ) F"
+ (at level 36, F at level 36, op, idx at level 10, i, n at level 50,
+ format "'[' \big [ op / idx ]_ ( i < n | P ) '/ ' F ']'").
+Reserved Notation "\big [ op / idx ]_ ( i < n ) F"
+ (at level 36, F at level 36, op, idx at level 10, i, n at level 50,
+ format "'[' \big [ op / idx ]_ ( i < n ) F ']'").
+Reserved Notation "\big [ op / idx ]_ ( i 'in' A | P ) F"
+ (at level 36, F at level 36, op, idx at level 10, i, A at level 50,
+ format "'[' \big [ op / idx ]_ ( i 'in' A | P ) '/ ' F ']'").
+Reserved Notation "\big [ op / idx ]_ ( i 'in' A ) F"
+ (at level 36, F at level 36, op, idx at level 10, i, A at level 50,
+ format "'[' \big [ op / idx ]_ ( i 'in' A ) '/ ' F ']'").
+
+Module Monoid.
+
+Section Definitions.
+Variables (T : Type) (idm : T).
+
+Structure law := Law {
+ operator : T -> T -> T;
+ _ : associative operator;
+ _ : left_id idm operator;
+ _ : right_id idm operator
+}.
+Local Coercion operator : law >-> Funclass.
+
+Structure com_law := ComLaw {
+ com_operator : law;
+ _ : commutative com_operator
+}.
+Local Coercion com_operator : com_law >-> law.
+
+Structure mul_law := MulLaw {
+ mul_operator : T -> T -> T;
+ _ : left_zero idm mul_operator;
+ _ : right_zero idm mul_operator
+}.
+Local Coercion mul_operator : mul_law >-> Funclass.
+
+Structure add_law (mul : T -> T -> T) := AddLaw {
+ add_operator : com_law;
+ _ : left_distributive mul add_operator;
+ _ : right_distributive mul add_operator
+}.
+Local Coercion add_operator : add_law >-> com_law.
+
+Let op_id (op1 op2 : T -> T -> T) := phant_id op1 op2.
+
+Definition clone_law op :=
+ fun (opL : law) & op_id opL op =>
+ fun opmA op1m opm1 (opL' := @Law op opmA op1m opm1)
+ & phant_id opL' opL => opL'.
+
+Definition clone_com_law op :=
+ fun (opL : law) (opC : com_law) & op_id opL op & op_id opC op =>
+ fun opmC (opC' := @ComLaw opL opmC) & phant_id opC' opC => opC'.
+
+Definition clone_mul_law op :=
+ fun (opM : mul_law) & op_id opM op =>
+ fun op0m opm0 (opM' := @MulLaw op op0m opm0) & phant_id opM' opM => opM'.
+
+Definition clone_add_law mop aop :=
+ fun (opC : com_law) (opA : add_law mop) & op_id opC aop & op_id opA aop =>
+ fun mopDm mopmD (opA' := @AddLaw mop opC mopDm mopmD)
+ & phant_id opA' opA => opA'.
+
+End Definitions.
+
+Module Import Exports.
+Coercion operator : law >-> Funclass.
+Coercion com_operator : com_law >-> law.
+Coercion mul_operator : mul_law >-> Funclass.
+Coercion add_operator : add_law >-> com_law.
+Notation "[ 'law' 'of' f ]" := (@clone_law _ _ f _ id _ _ _ id)
+ (at level 0, format"[ 'law' 'of' f ]") : form_scope.
+Notation "[ 'com_law' 'of' f ]" := (@clone_com_law _ _ f _ _ id id _ id)
+ (at level 0, format "[ 'com_law' 'of' f ]") : form_scope.
+Notation "[ 'mul_law' 'of' f ]" := (@clone_mul_law _ _ f _ id _ _ id)
+ (at level 0, format"[ 'mul_law' 'of' f ]") : form_scope.
+Notation "[ 'add_law' m 'of' a ]" := (@clone_add_law _ _ m a _ _ id id _ _ id)
+ (at level 0, format "[ 'add_law' m 'of' a ]") : form_scope.
+End Exports.
+
+Section CommutativeAxioms.
+
+Variable (T : Type) (zero one : T) (mul add : T -> T -> T) (inv : T -> T).
+Hypothesis mulC : commutative mul.
+
+Lemma mulC_id : left_id one mul -> right_id one mul.
+Proof. by move=> mul1x x; rewrite mulC. Qed.
+
+Lemma mulC_zero : left_zero zero mul -> right_zero zero mul.
+Proof. by move=> mul0x x; rewrite mulC. Qed.
+
+Lemma mulC_dist : left_distributive mul add -> right_distributive mul add.
+Proof. by move=> mul_addl x y z; rewrite !(mulC x). Qed.
+
+End CommutativeAxioms.
+Module Theory.
+
+Section Theory.
+Variables (T : Type) (idm : T).
+
+Section Plain.
+Variable mul : law idm.
+Lemma mul1m : left_id idm mul. Proof. by case mul. Qed.
+Lemma mulm1 : right_id idm mul. Proof. by case mul. Qed.
+Lemma mulmA : associative mul. Proof. by case mul. Qed.
+(*Lemma iteropE n x : iterop n mul x idm = iter n (mul x) idm.*)
+
+End Plain.
+
+Section Commutative.
+Variable mul : com_law idm.
+Lemma mulmC : commutative mul. Proof. by case mul. Qed.
+Lemma mulmCA : left_commutative mul.
+Proof. by move=> x y z; rewrite !mulmA (mulmC x). Qed.
+Lemma mulmAC : right_commutative mul.
+Proof. by move=> x y z; rewrite -!mulmA (mulmC y). Qed.
+Lemma mulmACA : interchange mul mul.
+Proof. by move=> x y z t; rewrite -!mulmA (mulmCA y). Qed.
+End Commutative.
+
+Section Mul.
+Variable mul : mul_law idm.
+Lemma mul0m : left_zero idm mul. Proof. by case mul. Qed.
+Lemma mulm0 : right_zero idm mul. Proof. by case mul. Qed.
+End Mul.
+
+Section Add.
+Variables (mul : T -> T -> T) (add : add_law idm mul).
+Lemma addmA : associative add. Proof. exact: mulmA. Qed.
+Lemma addmC : commutative add. Proof. exact: mulmC. Qed.
+Lemma addmCA : left_commutative add. Proof. exact: mulmCA. Qed.
+Lemma addmAC : right_commutative add. Proof. exact: mulmAC. Qed.
+Lemma add0m : left_id idm add. Proof. exact: mul1m. Qed.
+Lemma addm0 : right_id idm add. Proof. exact: mulm1. Qed.
+Lemma mulm_addl : left_distributive mul add. Proof. by case add. Qed.
+Lemma mulm_addr : right_distributive mul add. Proof. by case add. Qed.
+End Add.
+
+Definition simpm := (mulm1, mulm0, mul1m, mul0m, mulmA).
+
+End Theory.
+
+End Theory.
+Include Theory.
+
+End Monoid.
+Export Monoid.Exports.
+
+Section PervasiveMonoids.
+
+Import Monoid.
+
+Canonical andb_monoid := Law andbA andTb andbT.
+Canonical andb_comoid := ComLaw andbC.
+
+Canonical andb_muloid := MulLaw andFb andbF.
+Canonical orb_monoid := Law orbA orFb orbF.
+Canonical orb_comoid := ComLaw orbC.
+Canonical orb_muloid := MulLaw orTb orbT.
+Canonical addb_monoid := Law addbA addFb addbF.
+Canonical addb_comoid := ComLaw addbC.
+Canonical orb_addoid := AddLaw andb_orl andb_orr.
+Canonical andb_addoid := AddLaw orb_andl orb_andr.
+Canonical addb_addoid := AddLaw andb_addl andb_addr.
+
+Canonical addn_monoid := Law addnA add0n addn0.
+Canonical addn_comoid := ComLaw addnC.
+Canonical muln_monoid := Law mulnA mul1n muln1.
+Canonical muln_comoid := ComLaw mulnC.
+Canonical muln_muloid := MulLaw mul0n muln0.
+Canonical addn_addoid := AddLaw mulnDl mulnDr.
+
+Canonical cat_monoid T := Law (@catA T) (@cat0s T) (@cats0 T).
+
+End PervasiveMonoids.
+Delimit Scope big_scope with BIG.
+Open Scope big_scope.
+
+(* The bigbody wrapper is a workaround for a quirk of the Coq pretty-printer, *)
+(* which would fail to redisplay the \big notation when the <general_term> or *)
+(* <condition> do not depend on the bound index. The BigBody constructor *)
+(* packages both in in a term in which i occurs; it also depends on the *)
+(* iterated <op>, as this can give more information on the expected type of *)
+(* the <general_term>, thus allowing for the insertion of coercions. *)
+CoInductive bigbody R I := BigBody of I & (R -> R -> R) & bool & R.
+
+Definition applybig {R I} (body : bigbody R I) x :=
+ let: BigBody _ op b v := body in if b then op v x else x.
+
+Definition reducebig R I idx r (body : I -> bigbody R I) :=
+ foldr (applybig \o body) idx r.
+
+Module Type BigOpSig.
+Parameter bigop : forall R I, R -> seq I -> (I -> bigbody R I) -> R.
+Axiom bigopE : bigop = reducebig.
+End BigOpSig.
+
+Module BigOp : BigOpSig.
+Definition bigop := reducebig.
+Lemma bigopE : bigop = reducebig. Proof. by []. Qed.
+End BigOp.
+
+Notation bigop := BigOp.bigop (only parsing).
+Canonical bigop_unlock := Unlockable BigOp.bigopE.
+
+Definition index_iota m n := iota m (n - m).
+
+Definition index_enum (T : finType) := Finite.enum T.
+
+Lemma mem_index_iota m n i : i \in index_iota m n = (m <= i < n).
+Admitted.
+
+Lemma mem_index_enum T i : i \in index_enum T.
+Admitted.
+
+Hint Resolve mem_index_enum.
+
+(*
+Lemma filter_index_enum T P : filter P (index_enum T) = enum P.
+Proof. by []. Qed.
+*)
+
+Notation "\big [ op / idx ]_ ( i <- r | P ) F" :=
+ (bigop idx r (fun i => BigBody i op P%B F)) : big_scope.
+Notation "\big [ op / idx ]_ ( i <- r ) F" :=
+ (bigop idx r (fun i => BigBody i op true F)) : big_scope.
+Notation "\big [ op / idx ]_ ( m <= i < n | P ) F" :=
+ (bigop idx (index_iota m n) (fun i : nat => BigBody i op P%B F))
+ : big_scope.
+Notation "\big [ op / idx ]_ ( m <= i < n ) F" :=
+ (bigop idx (index_iota m n) (fun i : nat => BigBody i op true F))
+ : big_scope.
+Notation "\big [ op / idx ]_ ( i | P ) F" :=
+ (bigop idx (index_enum _) (fun i => BigBody i op P%B F)) : big_scope.
+Notation "\big [ op / idx ]_ i F" :=
+ (bigop idx (index_enum _) (fun i => BigBody i op true F)) : big_scope.
+Notation "\big [ op / idx ]_ ( i : t | P ) F" :=
+ (bigop idx (index_enum _) (fun i : t => BigBody i op P%B F))
+ (only parsing) : big_scope.
+Notation "\big [ op / idx ]_ ( i : t ) F" :=
+ (bigop idx (index_enum _) (fun i : t => BigBody i op true F))
+ (only parsing) : big_scope.
+Notation "\big [ op / idx ]_ ( i < n | P ) F" :=
+ (\big[op/idx]_(i : ordinal n | P%B) F) : big_scope.
+Notation "\big [ op / idx ]_ ( i < n ) F" :=
+ (\big[op/idx]_(i : ordinal n) F) : big_scope.
+Notation "\big [ op / idx ]_ ( i 'in' A | P ) F" :=
+ (\big[op/idx]_(i | (i \in A) && P) F) : big_scope.
+Notation "\big [ op / idx ]_ ( i 'in' A ) F" :=
+ (\big[op/idx]_(i | i \in A) F) : big_scope.
+
+Notation BIG_F := (F in \big[_/_]_(i <- _ | _) F i)%pattern.
+Notation BIG_P := (P in \big[_/_]_(i <- _ | P i) _)%pattern.
+
+(* Induction loading *)
+Lemma big_load R (K K' : R -> Type) idx op I r (P : pred I) F :
+ K (\big[op/idx]_(i <- r | P i) F i) * K' (\big[op/idx]_(i <- r | P i) F i)
+ -> K' (\big[op/idx]_(i <- r | P i) F i).
+Proof. by case. Qed.
+
+Arguments big_load [R] K [K'] idx op [I].
+
+Section Elim3.
+
+Variables (R1 R2 R3 : Type) (K : R1 -> R2 -> R3 -> Type).
+Variables (id1 : R1) (op1 : R1 -> R1 -> R1).
+Variables (id2 : R2) (op2 : R2 -> R2 -> R2).
+Variables (id3 : R3) (op3 : R3 -> R3 -> R3).
+
+Hypothesis Kid : K id1 id2 id3.
+
+Lemma big_rec3 I r (P : pred I) F1 F2 F3
+ (K_F : forall i y1 y2 y3, P i -> K y1 y2 y3 ->
+ K (op1 (F1 i) y1) (op2 (F2 i) y2) (op3 (F3 i) y3)) :
+ K (\big[op1/id1]_(i <- r | P i) F1 i)
+ (\big[op2/id2]_(i <- r | P i) F2 i)
+ (\big[op3/id3]_(i <- r | P i) F3 i).
+Proof. by rewrite unlock; elim: r => //= i r; case: ifP => //; apply: K_F. Qed.
+
+Hypothesis Kop : forall x1 x2 x3 y1 y2 y3,
+ K x1 x2 x3 -> K y1 y2 y3-> K (op1 x1 y1) (op2 x2 y2) (op3 x3 y3).
+Lemma big_ind3 I r (P : pred I) F1 F2 F3
+ (K_F : forall i, P i -> K (F1 i) (F2 i) (F3 i)) :
+ K (\big[op1/id1]_(i <- r | P i) F1 i)
+ (\big[op2/id2]_(i <- r | P i) F2 i)
+ (\big[op3/id3]_(i <- r | P i) F3 i).
+Proof. by apply: big_rec3 => i x1 x2 x3 /K_F; apply: Kop. Qed.
+
+End Elim3.
+
+Arguments big_rec3 [R1 R2 R3] K [id1 op1 id2 op2 id3 op3] _ [I r P F1 F2 F3].
+Arguments big_ind3 [R1 R2 R3] K [id1 op1 id2 op2 id3 op3] _ _ [I r P F1 F2 F3].
+
+Section Elim2.
+
+Variables (R1 R2 : Type) (K : R1 -> R2 -> Type) (f : R2 -> R1).
+Variables (id1 : R1) (op1 : R1 -> R1 -> R1).
+Variables (id2 : R2) (op2 : R2 -> R2 -> R2).
+
+Hypothesis Kid : K id1 id2.
+
+Lemma big_rec2 I r (P : pred I) F1 F2
+ (K_F : forall i y1 y2, P i -> K y1 y2 ->
+ K (op1 (F1 i) y1) (op2 (F2 i) y2)) :
+ K (\big[op1/id1]_(i <- r | P i) F1 i) (\big[op2/id2]_(i <- r | P i) F2 i).
+Proof. by rewrite unlock; elim: r => //= i r; case: ifP => //; apply: K_F. Qed.
+
+Hypothesis Kop : forall x1 x2 y1 y2,
+ K x1 x2 -> K y1 y2 -> K (op1 x1 y1) (op2 x2 y2).
+Lemma big_ind2 I r (P : pred I) F1 F2 (K_F : forall i, P i -> K (F1 i) (F2 i)) :
+ K (\big[op1/id1]_(i <- r | P i) F1 i) (\big[op2/id2]_(i <- r | P i) F2 i).
+Proof. by apply: big_rec2 => i x1 x2 /K_F; apply: Kop. Qed.
+
+Hypotheses (f_op : {morph f : x y / op2 x y >-> op1 x y}) (f_id : f id2 = id1).
+Lemma big_morph I r (P : pred I) F :
+ f (\big[op2/id2]_(i <- r | P i) F i) = \big[op1/id1]_(i <- r | P i) f (F i).
+Proof. by rewrite unlock; elim: r => //= i r <-; rewrite -f_op -fun_if. Qed.
+
+End Elim2.
+
+Arguments big_rec2 [R1 R2] K [id1 op1 id2 op2] _ [I r P F1 F2].
+Arguments big_ind2 [R1 R2] K [id1 op1 id2 op2] _ _ [I r P F1 F2].
+Arguments big_morph [R1 R2] f [id1 op1 id2 op2] _ _ [I].
+
+Section Elim1.
+
+Variables (R : Type) (K : R -> Type) (f : R -> R).
+Variables (idx : R) (op op' : R -> R -> R).
+
+Hypothesis Kid : K idx.
+
+Lemma big_rec I r (P : pred I) F
+ (Kop : forall i x, P i -> K x -> K (op (F i) x)) :
+ K (\big[op/idx]_(i <- r | P i) F i).
+Proof. by rewrite unlock; elim: r => //= i r; case: ifP => //; apply: Kop. Qed.
+
+Hypothesis Kop : forall x y, K x -> K y -> K (op x y).
+Lemma big_ind I r (P : pred I) F (K_F : forall i, P i -> K (F i)) :
+ K (\big[op/idx]_(i <- r | P i) F i).
+Proof. by apply: big_rec => // i x /K_F /Kop; apply. Qed.
+
+Hypothesis Kop' : forall x y, K x -> K y -> op x y = op' x y.
+Lemma eq_big_op I r (P : pred I) F (K_F : forall i, P i -> K (F i)) :
+ \big[op/idx]_(i <- r | P i) F i = \big[op'/idx]_(i <- r | P i) F i.
+Proof.
+by elim/(big_load K): _; elim/big_rec2: _ => // i _ y Pi [Ky <-]; auto.
+Qed.
+
+Hypotheses (fM : {morph f : x y / op x y}) (f_id : f idx = idx).
+Lemma big_endo I r (P : pred I) F :
+ f (\big[op/idx]_(i <- r | P i) F i) = \big[op/idx]_(i <- r | P i) f (F i).
+Proof. exact: big_morph. Qed.
+
+End Elim1.
+
+Arguments big_rec [R] K [idx op] _ [I r P F].
+Arguments big_ind [R] K [idx op] _ _ [I r P F].
+Arguments eq_big_op [R] K [idx op] op' _ _ _ [I].
+Arguments big_endo [R] f [idx op] _ _ [I].
+
+(* zmodp -------------------------------------------------------------------- *)
+
+Lemma ord1 : all_equal_to (@Ordinal 1 0 is_true_true : 'I_1).
+Admitted.
diff --git a/clib/canary.mli b/test-suite/prerequisite/ssr_ssrsyntax1.v
index d993eabc..2b404e2d 100644
--- a/clib/canary.mli
+++ b/test-suite/prerequisite/ssr_ssrsyntax1.v
@@ -8,20 +8,29 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-type t
-(** Type of canaries. Canaries are used to ensure that an object does not use
- generic operations. *)
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-val obj : t
-(** Canary. In the current implementation, this object is marshallable,
- forbids generic comparison but still allows generic hashes. *)
+Require ssreflect.
+Require Import Arith.
-module type Obj = sig type t end
+Goal (forall a b, a + b = b + a).
+intros.
+rewrite plus_comm, plus_comm.
+split.
+Abort.
-module Make(M : Obj) :
-sig
- type t
- val prj : t -> M.t
- val inj : M.t -> t
-end
-(** Adds a canary to any type. *)
+Module Foo.
+Import ssreflect.
+
+Goal (forall a b, a + b = b + a).
+intros.
+rewrite 2![_ + _]plus_comm.
+split.
+Abort.
+End Foo.
+
+Goal (forall a b, a + b = b + a).
+intros.
+rewrite plus_comm, plus_comm.
+split.
+Abort.
diff --git a/test-suite/report.sh b/test-suite/report.sh
new file mode 100755
index 00000000..05f39b4b
--- /dev/null
+++ b/test-suite/report.sh
@@ -0,0 +1,55 @@
+#!/usr/bin/env bash
+
+# save failed logs to logs/, then print failure information
+# returns failure code if any failed logs exist
+
+# save step
+
+SAVEDIR="logs"
+
+# reset for local builds
+rm -rf "$SAVEDIR"
+mkdir "$SAVEDIR"
+
+# keep this synced with test-suite/Makefile
+FAILMARK="==========> FAILURE <=========="
+
+FAILED=$(mktemp /tmp/coq-check-XXXXXX)
+find . '(' -path ./bugs/opened -prune ')' -o '(' -name '*.log' -exec grep "$FAILMARK" -q '{}' ';' -print0 ')' > "$FAILED"
+
+rsync -a --from0 --files-from="$FAILED" . "$SAVEDIR"
+cp summary.log "$SAVEDIR"/
+
+# cleanup
+rm "$FAILED"
+
+# print info
+if [ -n "$TRAVIS" ] || [ -n "$PRINT_LOGS" ]; then
+ find logs/ -name '*.log' -not -name 'summary.log' -print0 | while IFS= read -r -d '' file; do
+ if [ -n "$TRAVIS" ]; then
+ # ${foo////.} replaces every / by . in $foo
+ printf 'travis_fold:start:coq.logs.%s\n' "${file////.}";
+ else printf '%s\n' "$file"
+ fi
+
+ cat "$file"
+
+ if [ -n "$TRAVIS" ]; then
+ # ${foo////.} replaces every / by . in $foo
+ printf 'travis_fold:end:coq.logs.%s\n' "${file////.}";
+ else printf '\n'
+ fi
+ done
+fi
+
+if grep -q -F 'Error!' summary.log ; then
+ echo FAILURES;
+ grep -F 'Error!' summary.log;
+ if [ -z "$TRAVIS" ] && [ -z "$PRINT_LOGS" ]; then
+ echo 'To print details of failed tests, rerun with environment variable PRINT_LOGS=1'
+ echo 'eg "make report PRINT_LOGS=1" from the test suite directory"'
+ echo 'See README.md in the test suite directory for more information.'
+ fi
+ false
+else echo NO FAILURES;
+fi
diff --git a/test-suite/save-logs.sh b/test-suite/save-logs.sh
deleted file mode 100755
index 9b8fff09..00000000
--- a/test-suite/save-logs.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env bash
-
-SAVEDIR="logs"
-
-# reset for local builds
-rm -rf "$SAVEDIR"
-mkdir "$SAVEDIR"
-
-# keep this synced with test-suite/Makefile
-FAILMARK="==========> FAILURE <=========="
-
-FAILED=$(mktemp /tmp/coq-check-XXXXXX)
-find . '(' -path ./bugs/opened -prune ')' -o '(' -name '*.log' -exec grep "$FAILMARK" -q '{}' ';' -print0 ')' > "$FAILED"
-
-rsync -a --from0 --files-from="$FAILED" . "$SAVEDIR"
-cp summary.log "$SAVEDIR"/
-
-# cleanup
-rm "$FAILED"
diff --git a/test-suite/ssr/absevarprop.v b/test-suite/ssr/absevarprop.v
new file mode 100644
index 00000000..fa1de009
--- /dev/null
+++ b/test-suite/ssr/absevarprop.v
@@ -0,0 +1,96 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect ssrbool ssrfun.
+Require Import TestSuite.ssr_mini_mathcomp.
+
+Lemma test15: forall (y : nat) (x : 'I_2), y < 1 -> val x = y -> Some x = insub y.
+move=> y x le_1 defx; rewrite insubT ?(leq_trans le_1) // => ?.
+by congr (Some _); apply: val_inj=> /=; exact: defx.
+Qed.
+
+Axiom P : nat -> Prop.
+Axiom Q : forall n, P n -> Prop.
+Definition R := fun (x : nat) (p : P x) m (q : P (x+1)) => m > 0.
+
+Inductive myEx : Type := ExI : forall n (pn : P n) pn', Q n pn -> R n pn n pn' -> myEx.
+
+Variable P1 : P 1.
+Variable P11 : P (1 + 1).
+Variable Q1 : forall P1, Q 1 P1.
+
+Lemma testmE1 : myEx.
+Proof.
+apply: ExI 1 _ _ _ _.
+ match goal with |- P 1 => exact: P1 | _ => fail end.
+ match goal with |- P (1+1) => exact: P11 | _ => fail end.
+ match goal with |- forall p : P 1, Q 1 p => move=> *; exact: Q1 | _ => fail end.
+match goal with |- forall (p : P 1) (q : P (1+1)), is_true (R 1 p 1 q) => done | _ => fail end.
+Qed.
+
+Lemma testE2 : exists y : { x | P x }, sval y = 1.
+Proof.
+apply: ex_intro (exist _ 1 _) _.
+ match goal with |- P 1 => exact: P1 | _ => fail end.
+match goal with |- forall p : P 1, @sval _ _ (@exist _ _ 1 p) = 1 => done | _ => fail end.
+Qed.
+
+Lemma testE3 : exists y : { x | P x }, sval y = 1.
+Proof.
+have := (ex_intro _ (exist _ 1 _) _); apply.
+ match goal with |- P 1 => exact: P1 | _ => fail end.
+match goal with |- forall p : P 1, @sval _ _ (@exist _ _ 1 p) = 1 => done | _ => fail end.
+Qed.
+
+Lemma testE4 : P 2 -> exists y : { x | P x }, sval y = 2.
+Proof.
+move=> P2; apply: ex_intro (exist _ 2 _) _.
+match goal with |- @sval _ _ (@exist _ _ 2 P2) = 2 => done | _ => fail end.
+Qed.
+
+Hint Resolve P1.
+
+Lemma testmE12 : myEx.
+Proof.
+apply: ExI 1 _ _ _ _.
+ match goal with |- P (1+1) => exact: P11 | _ => fail end.
+ match goal with |- Q 1 P1 => exact: Q1 | _ => fail end.
+match goal with |- forall (q : P (1+1)), is_true (R 1 P1 1 q) => done | _ => fail end.
+Qed.
+
+Create HintDb SSR.
+
+Hint Resolve P11 : SSR.
+
+Ltac ssrautoprop := trivial with SSR.
+
+Lemma testmE13 : myEx.
+Proof.
+apply: ExI 1 _ _ _ _.
+ match goal with |- Q 1 P1 => exact: Q1 | _ => fail end.
+match goal with |- is_true (R 1 P1 1 P11) => done | _ => fail end.
+Qed.
+
+Definition R1 := fun (x : nat) (p : P x) m (q : P (x+1)) (r : Q x p) => m > 0.
+
+Inductive myEx1 : Type :=
+ ExI1 : forall n (pn : P n) pn' (q : Q n pn), R1 n pn n pn' q -> myEx1.
+
+Hint Resolve (Q1 P1) : SSR.
+
+(* tests that goals in prop are solved in the right order, propagating instantiations,
+ thus the goal Q 1 ?p1 is faced by trivial after ?p1, and is thus evar free *)
+Lemma testmE14 : myEx1.
+Proof.
+apply: ExI1 1 _ _ _ _.
+match goal with |- is_true (R1 1 P1 1 P11 (Q1 P1)) => done | _ => fail end.
+Qed.
diff --git a/test-suite/ssr/abstract_var2.v b/test-suite/ssr/abstract_var2.v
new file mode 100644
index 00000000..7c57d202
--- /dev/null
+++ b/test-suite/ssr/abstract_var2.v
@@ -0,0 +1,25 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+Require Import ssreflect.
+
+Set Implicit Arguments.
+
+Axiom P : nat -> nat -> Prop.
+
+Axiom tr :
+ forall x y z, P x y -> P y z -> P x z.
+
+Lemma test a b c : P a c -> P a b.
+Proof.
+intro H.
+Fail have [: s1 s2] H1 : P a b := @tr _ _ _ s1 s2.
+have [: w s1 s2] H1 : P a b := @tr _ w _ s1 s2.
+Abort.
diff --git a/test-suite/ssr/binders.v b/test-suite/ssr/binders.v
new file mode 100644
index 00000000..97b7d830
--- /dev/null
+++ b/test-suite/ssr/binders.v
@@ -0,0 +1,55 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool TestSuite.ssr_mini_mathcomp.
+
+Lemma test (x : bool) : True.
+have H1 x := x.
+have (x) := x => H2.
+have H3 T (x : T) := x.
+have ? : bool := H1 _ x.
+have ? : bool := H2 _ x.
+have ? : bool := H3 _ x.
+have ? (z : bool) : forall y : bool, z = z := fun y => refl_equal _.
+have ? w : w = w := @refl_equal nat w.
+have ? y : true by [].
+have ? (z : bool) : z = z.
+ exact: (@refl_equal _ z).
+have ? (z w : bool) : z = z by exact: (@refl_equal _ z).
+have H w (a := 3) (_ := 4) : w && true = w.
+ by rewrite andbT.
+exact I.
+Qed.
+
+Lemma test1 : True.
+suff (x : bool): x = x /\ True.
+ by move/(_ true); case=> _.
+split; first by exact: (@refl_equal _ x).
+suff H y : y && true = y /\ True.
+ by case: (H true).
+suff H1 /= : true && true /\ True.
+ by rewrite andbT; split; [exact: (@refl_equal _ y) | exact: I].
+match goal with |- is_true true /\ True => idtac end.
+by split.
+Qed.
+
+Lemma foo n : n >= 0.
+have f i (j := i + n) : j < n.
+ match goal with j := i + n |- _ => idtac end.
+Undo 2.
+suff f i (j := i + n) : j < n.
+ done.
+match goal with j := i + n |- _ => idtac end.
+Undo 3.
+done.
+Qed.
diff --git a/test-suite/ssr/binders_of.v b/test-suite/ssr/binders_of.v
new file mode 100644
index 00000000..69b52eac
--- /dev/null
+++ b/test-suite/ssr/binders_of.v
@@ -0,0 +1,23 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+
+Require Import ssreflect.
+Require Import TestSuite.ssr_mini_mathcomp.
+
+Lemma test1 : True.
+have f of seq nat & nat : nat.
+ exact 3.
+have g of nat := 3.
+have h of nat : nat := 3.
+have _ : f [::] 3 = g 3 + h 4.
+Admitted.
diff --git a/test-suite/ssr/caseview.v b/test-suite/ssr/caseview.v
new file mode 100644
index 00000000..94b064b0
--- /dev/null
+++ b/test-suite/ssr/caseview.v
@@ -0,0 +1,17 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+
+
+Lemma test (A B : Prop) : A /\ B -> True.
+Proof. by case=> _ /id _. Qed.
diff --git a/test-suite/ssr/congr.v b/test-suite/ssr/congr.v
new file mode 100644
index 00000000..7e60b04a
--- /dev/null
+++ b/test-suite/ssr/congr.v
@@ -0,0 +1,34 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool TestSuite.ssr_mini_mathcomp.
+
+Lemma test1 : forall a b : nat, a == b -> a == 0 -> b == 0.
+Proof. move=> a b Eab Eac; congr (_ == 0) : Eac; exact: eqP Eab. Qed.
+
+Definition arrow A B := A -> B.
+
+Lemma test2 : forall a b : nat, a == b -> arrow (a == 0) (b == 0).
+Proof. move=> a b Eab; congr (_ == 0); exact: eqP Eab. Qed.
+
+Definition equals T (A B : T) := A = B.
+
+Lemma test3 : forall a b : nat, a = b -> equals nat (a + b) (b + b).
+Proof. move=> a b E; congr (_ + _); exact E. Qed.
+
+Variable S : eqType.
+Variable f : nat -> S.
+Coercion f : nat >-> Equality.sort.
+
+Lemma test4 : forall a b : nat, b = a -> @eq S (b + b) (a + a).
+Proof. move=> a b Eba; congr (_ + _); exact: Eba. Qed.
diff --git a/test-suite/ssr/deferclear.v b/test-suite/ssr/deferclear.v
new file mode 100644
index 00000000..85353dad
--- /dev/null
+++ b/test-suite/ssr/deferclear.v
@@ -0,0 +1,37 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+
+Require Import ssrbool TestSuite.ssr_mini_mathcomp.
+
+Variable T : Type.
+
+Lemma test0 : forall a b c d : T, True.
+Proof. by move=> a b {a} a c; exact I. Qed.
+
+Variable P : T -> Prop.
+
+Lemma test1 : forall a b c : T, P a -> forall d : T, True.
+Proof. move=> a b {a} a _ d; exact I. Qed.
+
+Definition Q := forall x y : nat, x = y.
+Axiom L : 0 = 0 -> Q.
+Axiom L' : 0 = 0 -> forall x y : nat, x = y.
+Lemma test3 : Q.
+by apply/L.
+Undo.
+rewrite /Q.
+by apply/L.
+Undo 2.
+by apply/L'.
+Qed.
diff --git a/test-suite/success/ssr_delayed_clear_rename.v b/test-suite/ssr/delayed_clear_rename.v
index 951e5aff..951e5aff 100644
--- a/test-suite/success/ssr_delayed_clear_rename.v
+++ b/test-suite/ssr/delayed_clear_rename.v
diff --git a/test-suite/ssr/dependent_type_err.v b/test-suite/ssr/dependent_type_err.v
new file mode 100644
index 00000000..a5789d8d
--- /dev/null
+++ b/test-suite/ssr/dependent_type_err.v
@@ -0,0 +1,20 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrfun ssrbool TestSuite.ssr_mini_mathcomp.
+
+Lemma ltn_leq_trans : forall n m p : nat, m < n -> n <= p -> m < p.
+move=> n m p Hmn Hnp; rewrite -ltnS.
+Fail rewrite (_ : forall n0 m0 p0 : nat, m0 <= n0 -> n0 < p0 -> m0 < p0).
+Fail rewrite leq_ltn_trans.
+Admitted.
diff --git a/test-suite/ssr/derive_inversion.v b/test-suite/ssr/derive_inversion.v
new file mode 100644
index 00000000..abf63a20
--- /dev/null
+++ b/test-suite/ssr/derive_inversion.v
@@ -0,0 +1,29 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+Require Import ssreflect ssrbool.
+
+Set Implicit Arguments.
+
+ Inductive wf T : bool -> option T -> Type :=
+ | wf_f : wf false None
+ | wf_t : forall x, wf true (Some x).
+
+ Derive Inversion wf_inv with (forall T b (o : option T), wf b o) Sort Prop.
+
+ Lemma Problem T b (o : option T) :
+ wf b o ->
+ match b with
+ | true => exists x, o = Some x
+ | false => o = None
+ end.
+ Proof.
+ by case: b; elim/wf_inv=> //; case: o=> // a *; exists a.
+ Qed.
diff --git a/test-suite/ssr/elim.v b/test-suite/ssr/elim.v
new file mode 100644
index 00000000..908249a3
--- /dev/null
+++ b/test-suite/ssr/elim.v
@@ -0,0 +1,279 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool ssrfun TestSuite.ssr_mini_mathcomp.
+Axiom daemon : False. Ltac myadmit := case: daemon.
+
+(* Ltac debugging feature: recursive elim + eq generation *)
+Lemma testL1 : forall A (s : seq A), s = s.
+Proof.
+move=> A s; elim branch: s => [|x xs _].
+match goal with _ : _ = [::] |- [::] = [::] => move: branch => // | _ => fail end.
+match goal with _ : _ = _ :: _ |- _ :: _ = _ :: _ => move: branch => // | _ => fail end.
+Qed.
+
+(* The same but with explicit eliminator and a conflict in the intro pattern *)
+Lemma testL2 : forall A (s : seq A), s = s.
+Proof.
+move=> A s; elim/last_ind branch: s => [|x s _].
+match goal with _ : _ = [::] |- [::] = [::] => move: branch => // | _ => fail end.
+match goal with _ : _ = rcons _ _ |- rcons _ _ = rcons _ _ => move: branch => // | _ => fail end.
+Qed.
+
+(* The same but without names for variables involved in the generated eq *)
+Lemma testL3 : forall A (s : seq A), s = s.
+Proof.
+move=> A s; elim branch: s; move: (s) => _.
+match goal with _ : _ = [::] |- [::] = [::] => move: branch => // | _ => fail end.
+move=> _; match goal with _ : _ = _ :: _ |- _ :: _ = _ :: _ => move: branch => // | _ => fail end.
+Qed.
+
+Inductive foo : Type := K1 : foo | K2 : foo -> foo -> foo | K3 : (nat -> foo) -> foo.
+
+(* The same but with more intros to be done *)
+Lemma testL4 : forall (o : foo), o = o.
+Proof.
+move=> o; elim branch: o.
+match goal with _ : _ = K1 |- K1 = K1 => move: branch => // | _ => fail end.
+move=> _; match goal with _ : _ = K2 _ _ |- K2 _ _ = K2 _ _ => move: branch => // | _ => fail end.
+move=> _; match goal with _ : _ = K3 _ |- K3 _ = K3 _ => move: branch => // | _ => fail end.
+Qed.
+
+(* Occurrence counting *)
+Lemma testO1: forall (b : bool), b = b.
+Proof.
+move=> b; case: (b) / idP.
+match goal with |- is_true b -> true = true => done | _ => fail end.
+match goal with |- ~ is_true b -> false = false => done | _ => fail end.
+Qed.
+
+(* The same but only the second occ *)
+Lemma testO2: forall (b : bool), b = b.
+Proof.
+move=> b; case: {2}(b) / idP.
+match goal with |- is_true b -> b = true => done | _ => fail end.
+match goal with |- ~ is_true b -> b = false => move/(introF idP) => // | _ => fail end.
+Qed.
+
+(* The same but with eq generation *)
+Lemma testO3: forall (b : bool), b = b.
+Proof.
+move=> b; case E: {2}(b) / idP.
+match goal with _ : is_true b, _ : b = true |- b = true => move: E => _; done | _ => fail end.
+match goal with H : ~ is_true b, _ : b = false |- b = false => move: E => _; move/(introF idP): H => // | _ => fail end.
+Qed.
+
+(* Views *)
+Lemma testV1 : forall A (s : seq A), s = s.
+Proof.
+move=> A s; case/lastP E: {1}s => [| x xs].
+match goal with _ : s = [::] |- [::] = s => symmetry; exact E | _ => fail end.
+match goal with _ : s = rcons x xs |- rcons _ _ = s => symmetry; exact E | _ => fail end.
+Qed.
+
+Lemma testV2 : forall A (s : seq A), s = s.
+Proof.
+move=> A s; case/lastP E: s => [| x xs].
+match goal with _ : s = [::] |- [::] = [::] => done | _ => fail end.
+match goal with _ : s = rcons x xs |- rcons _ _ = rcons _ _ => done | _ => fail end.
+Qed.
+
+Lemma testV3 : forall A (s : seq A), s = s.
+Proof.
+move=> A s; case/lastP: s => [| x xs].
+match goal with |- [::] = [::] => done | _ => fail end.
+match goal with |- rcons _ _ = rcons _ _ => done | _ => fail end.
+Qed.
+
+(* Patterns *)
+Lemma testP1: forall (x y : nat), (y == x) && (y == x) -> y == x.
+move=> x y; elim: {2}(_ == _) / eqP.
+match goal with |- (y = x -> is_true ((y == x) && true) -> is_true (y == x)) => move=> -> // | _ => fail end.
+match goal with |- (y <> x -> is_true ((y == x) && false) -> is_true (y == x)) => move=> _; rewrite andbC // | _ => fail end.
+Qed.
+
+(* The same but with an implicit pattern *)
+Lemma testP2 : forall (x y : nat), (y == x) && (y == x) -> y == x.
+move=> x y; elim: {2}_ / eqP.
+match goal with |- (y = x -> is_true ((y == x) && true) -> is_true (y == x)) => move=> -> // | _ => fail end.
+match goal with |- (y <> x -> is_true ((y == x) && false) -> is_true (y == x)) => move=> _; rewrite andbC // | _ => fail end.
+Qed.
+
+(* The same but with an eq generation switch *)
+Lemma testP3 : forall (x y : nat), (y == x) && (y == x) -> y == x.
+move=> x y; elim E: {2}_ / eqP.
+match goal with _ : y = x |- (is_true ((y == x) && true) -> is_true (y == x)) => rewrite E; reflexivity | _ => fail end.
+match goal with _ : y <> x |- (is_true ((y == x) && false) -> is_true (y == x)) => rewrite E => /= H; exact H | _ => fail end.
+Qed.
+
+Inductive spec : nat -> nat -> nat -> Prop :=
+| specK : forall a b c, a = 0 -> b = 2 -> c = 4 -> spec a b c.
+Lemma specP : spec 0 2 4. Proof. by constructor. Qed.
+
+Lemma testP4 : (1+1) * 4 = 2 + (1+1) + (2 + 2).
+Proof.
+case: specP => a b c defa defb defc.
+match goal with |- (a.+1 + a.+1) * c = b + (a.+1 + a.+1) + (b + b) => subst; done | _ => fail end.
+Qed.
+
+Lemma testP5 : (1+1) * 4 = 2 + (1+1) + (2 + 2).
+Proof.
+case: (1 + 1) _ / specP => a b c defa defb defc.
+match goal with |- b * c = a.+2 + b + (a.+2 + a.+2) => subst; done | _ => fail end.
+Qed.
+
+Lemma testP6 : (1+1) * 4 = 2 + (1+1) + (2 + 2).
+Proof.
+case: {2}(1 + 1) _ / specP => a b c defa defb defc.
+match goal with |- (a.+1 + a.+1) * c = a.+2 + b + (a.+2 + a.+2) => subst; done | _ => fail end.
+Qed.
+
+Lemma testP7 : (1+1) * 4 = 2 + (1+1) + (2 + 2).
+Proof.
+case: _ (1 + 1) (2 + _) / specP => a b c defa defb defc.
+match goal with |- b * a.+4 = c + c => subst; done | _ => fail end.
+Qed.
+
+Lemma testP8 : (1+1) * 4 = 2 + (1+1) + (2 + 2).
+Proof.
+case E: (1 + 1) (2 + _) / specP=> [a b c defa defb defc].
+match goal with |- b * a.+4 = c + c => subst; done | _ => fail end.
+Qed.
+
+Variables (T : Type) (tr : T -> T).
+
+Inductive exec (cf0 cf1 : T) : seq T -> Prop :=
+| exec_step : tr cf0 = cf1 -> exec cf0 cf1 [::]
+| exec_star : forall cf2 t, tr cf0 = cf2 ->
+ exec cf2 cf1 t -> exec cf0 cf1 (cf2 :: t).
+
+Inductive execr (cf0 cf1 : T) : seq T -> Prop :=
+| execr_step : tr cf0 = cf1 -> execr cf0 cf1 [::]
+| execr_star : forall cf2 t, execr cf0 cf2 t ->
+ tr cf2 = cf1 -> execr cf0 cf1 (t ++ [:: cf2]).
+
+Lemma execP : forall cf0 cf1 t, exec cf0 cf1 t <-> execr cf0 cf1 t.
+Proof.
+move=> cf0 cf1 t; split => [] Ecf.
+ elim: Ecf.
+ match goal with |- forall cf2 cf3 : T, tr cf2 = cf3 ->
+ execr cf2 cf3 [::] => myadmit | _ => fail end.
+ match goal with |- forall (cf2 cf3 cf4 : T) (t0 : seq T),
+ tr cf2 = cf4 -> exec cf4 cf3 t0 -> execr cf4 cf3 t0 ->
+ execr cf2 cf3 (cf4 :: t0) => myadmit | _ => fail end.
+elim: Ecf.
+ match goal with |- forall cf2 : T,
+ tr cf0 = cf2 -> exec cf0 cf2 [::] => myadmit | _ => fail end.
+match goal with |- forall (cf2 cf3 : T) (t0 : seq T),
+ execr cf0 cf3 t0 -> exec cf0 cf3 t0 -> tr cf3 = cf2 ->
+ exec cf0 cf2 (t0 ++ [:: cf3]) => myadmit | _ => fail end.
+Qed.
+
+Fixpoint plus (m n : nat) {struct n} : nat :=
+ match n with
+ | 0 => m
+ | S p => S (plus m p)
+ end.
+
+Definition plus_equation :
+forall m n : nat,
+ plus m n =
+ match n with
+ | 0 => m
+ | p.+1 => (plus m p).+1
+ end
+:=
+fun m n : nat =>
+match
+ n as n0
+ return
+ (forall m0 : nat,
+ plus m0 n0 =
+ match n0 with
+ | 0 => m0
+ | p.+1 => (plus m0 p).+1
+ end)
+with
+| 0 => @erefl nat
+| n0.+1 => fun m0 : nat => erefl (plus m0 n0).+1
+end m.
+
+Definition plus_rect :
+forall (m : nat) (P : nat -> nat -> Type),
+ (forall n : nat, n = 0 -> P 0 m) ->
+ (forall n p : nat,
+ n = p.+1 -> P p (plus m p) -> P p.+1 (plus m p).+1) ->
+ forall n : nat, P n (plus m n)
+:=
+fun (m : nat) (P : nat -> nat -> Type)
+ (f0 : forall n : nat, n = 0 -> P 0 m)
+ (f : forall n p : nat,
+ n = p.+1 -> P p (plus m p) -> P p.+1 (plus m p).+1) =>
+fix plus0 (n : nat) : P n (plus m n) :=
+ eq_rect_r [eta P n]
+ (let f1 := f0 n in
+ let f2 := f n in
+ match
+ n as n0
+ return
+ (n = n0 ->
+ (forall p : nat,
+ n0 = p.+1 -> P p (plus m p) -> P p.+1 (plus m p).+1) ->
+ (n0 = 0 -> P 0 m) ->
+ P n0 match n0 with
+ | 0 => m
+ | p.+1 => (plus m p).+1
+ end)
+ with
+ | 0 =>
+ fun (_ : n = 0)
+ (_ : forall p : nat,
+ 0 = p.+1 ->
+ P p (plus m p) -> P p.+1 (plus m p).+1)
+ (f4 : 0 = 0 -> P 0 m) => unkeyed (f4 (erefl 0))
+ | n0.+1 =>
+ fun (_ : n = n0.+1)
+ (f3 : forall p : nat,
+ n0.+1 = p.+1 ->
+ P p (plus m p) -> P p.+1 (plus m p).+1)
+ (_ : n0.+1 = 0 -> P 0 m) =>
+ let f5 :=
+ let p := n0 in
+ let H := erefl n0.+1 : n0.+1 = p.+1 in f3 p H in
+ unkeyed (let Hrec := plus0 n0 in f5 Hrec)
+ end (erefl n) f2 f1) (plus_equation m n).
+
+Definition plus_ind := plus_rect.
+
+Lemma exF x y z: plus (plus x y) z = plus x (plus y z).
+elim/plus_ind: z / (plus _ z).
+match goal with |- forall n : nat, n = 0 -> plus x y = plus x (plus y 0) => idtac end.
+Undo 2.
+elim/plus_ind: (plus _ z).
+match goal with |- forall n : nat, n = 0 -> plus x y = plus x (plus y 0) => idtac end.
+Undo 2.
+elim/plus_ind: {z}(plus _ z).
+match goal with |- forall n : nat, n = 0 -> plus x y = plus x (plus y 0) => idtac end.
+Undo 2.
+elim/plus_ind: {z}_.
+match goal with |- forall n : nat, n = 0 -> plus x y = plus x (plus y 0) => idtac end.
+Undo 2.
+elim/plus_ind: z / _.
+match goal with |- forall n : nat, n = 0 -> plus x y = plus x (plus y 0) => idtac end.
+ done.
+by move=> _ p _ ->.
+Qed.
+
+(* BUG elim-False *)
+Lemma testeF : False -> 1 = 0.
+Proof. by elim. Qed.
diff --git a/test-suite/ssr/elim2.v b/test-suite/ssr/elim2.v
new file mode 100644
index 00000000..c7c20d8f
--- /dev/null
+++ b/test-suite/ssr/elim2.v
@@ -0,0 +1,74 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool TestSuite.ssr_mini_mathcomp.
+(* div fintype finfun path bigop. *)
+
+Axiom daemon : False. Ltac myadmit := case: daemon.
+
+Lemma big_load R (K K' : R -> Type) idx op I r (P : pred I) F :
+ let s := \big[op/idx]_(i <- r | P i) F i in
+ K s * K' s -> K' s.
+Proof. by move=> /= [_]. Qed.
+Arguments big_load [R] K [K' idx op I r P F].
+
+Section Elim1.
+
+Variables (R : Type) (K : R -> Type) (f : R -> R).
+Variables (idx : R) (op op' : R -> R -> R).
+
+Hypothesis Kid : K idx.
+
+Ltac ASSERT1 := match goal with |- (K idx) => myadmit end.
+Ltac ASSERT2 K := match goal with |- (forall x1 : R, R ->
+ forall y1 : R, R -> K x1 -> K y1 -> K (op x1 y1)) => myadmit end.
+
+
+Lemma big_rec I r (P : pred I) F
+ (Kop : forall i x, P i -> K x -> K (op (F i) x)) :
+ K (\big[op/idx]_(i <- r | P i) F i).
+Proof.
+elim/big_ind2: {-}_.
+ ASSERT1. ASSERT2 K. match goal with |- (forall i : I, is_true (P i) -> K (F i)) => myadmit end. Undo 4.
+elim/big_ind2: _ / {-}_.
+ ASSERT1. ASSERT2 K. match goal with |- (forall i : I, is_true (P i) -> K (F i)) => myadmit end. Undo 4.
+
+elim/big_rec2: (\big[op/idx]_(i <- r | P i) op idx (F i))
+ / (\big[op/idx]_(i <- r | P i) F i).
+ ASSERT1. match goal with |- (forall i : I, R -> forall y2 : R, is_true (P i) -> K y2 -> K (op (F i) y2)) => myadmit end. Undo 3.
+
+elim/(big_load (phantom R)): _.
+ Undo.
+
+Fail elim/big_rec2: {2}_.
+
+elim/big_rec2: (\big[op/idx]_(i <- r | P i) F i)
+ / {1}(\big[op/idx]_(i <- r | P i) F i).
+ Undo.
+
+elim/(big_load (phantom R)): _.
+Undo.
+
+Fail elim/big_rec2: _ / {2}(\big[op/idx]_(i <- r | P i) F i).
+Admitted.
+
+Definition morecomplexthannecessary A (P : A -> A -> Prop) x y := P x y.
+
+Lemma grab A (P : A -> A -> Prop) n m : (n = m) -> (P n n) -> morecomplexthannecessary A P n m.
+by move->.
+Qed.
+
+Goal forall n m, m + (n + m) = m + (n * 1 + m).
+Proof. move=> n m; elim/grab : (_ * _) / {1}n => //; exact: muln1. Qed.
+
+End Elim1.
diff --git a/test-suite/ssr/elim_pattern.v b/test-suite/ssr/elim_pattern.v
new file mode 100644
index 00000000..ef465828
--- /dev/null
+++ b/test-suite/ssr/elim_pattern.v
@@ -0,0 +1,27 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool TestSuite.ssr_mini_mathcomp.
+Axiom daemon : False. Ltac myadmit := case: daemon.
+
+Lemma test x : (x == x) = (x + x.+1 == 2 * x + 1).
+case: (X in _ = X) / eqP => _.
+match goal with |- (x == x) = true => myadmit end.
+match goal with |- (x == x) = false => myadmit end.
+Qed.
+
+Lemma test1 x : (x == x) = (x + x.+1 == 2 * x + 1).
+elim: (x in RHS).
+match goal with |- (x == x) = _ => myadmit end.
+match goal with |- forall n, (x == x) = _ -> (x == x) = _ => myadmit end.
+Qed.
diff --git a/test-suite/ssr/first_n.v b/test-suite/ssr/first_n.v
new file mode 100644
index 00000000..4971add9
--- /dev/null
+++ b/test-suite/ssr/first_n.v
@@ -0,0 +1,21 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool.
+
+Lemma test : False -> (bool -> False -> True -> True) -> True.
+move=> F; let w := constr:(2) in apply; last w first.
+- by apply: F.
+- by apply: I.
+- by apply: true.
+Qed.
diff --git a/test-suite/ssr/gen_have.v b/test-suite/ssr/gen_have.v
new file mode 100644
index 00000000..249e006f
--- /dev/null
+++ b/test-suite/ssr/gen_have.v
@@ -0,0 +1,174 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrfun ssrbool TestSuite.ssr_mini_mathcomp.
+Axiom daemon : False. Ltac myadmit := case: daemon.
+
+Axiom P : nat -> Prop.
+Lemma clear_test (b1 b2 : bool) : b2 = b2.
+Proof.
+(* wlog gH : (b3 := b2) / b2 = b3. myadmit. *)
+gen have {b1} H, gH : (b3 := b2) (w := erefl 3) / b2 = b3.
+ myadmit.
+Fail exact (H b1).
+exact (H b2 (erefl _)).
+Qed.
+
+
+Lemma test1 n (ngt0 : 0 < n) : P n.
+gen have lt2le, /andP[H1 H2] : n ngt0 / (0 <= n) && (n != 0).
+ match goal with |- is_true((0 <= n) && (n != 0)) => myadmit end.
+Check (lt2le : forall n : nat, 0 < n -> (0 <= n) && (n != 0)).
+Check (H1 : 0 <= n).
+Check (H2 : n != 0).
+myadmit.
+Qed.
+
+Lemma test2 n (ngt0 : 0 < n) : P n.
+gen have _, /andP[H1 H2] : n ngt0 / (0 <= n) && (n != 0).
+ match goal with |- is_true((0 <= n) && (n != 0)) => myadmit end.
+lazymatch goal with
+ | lt2le : forall n : nat, is_true(0 < n) -> is_true((0 <= n) && (n != 0))
+ |- _ => fail "not cleared"
+ | _ => idtac end.
+Check (H1 : 0 <= n).
+Check (H2 : n != 0).
+myadmit.
+Qed.
+
+Lemma test3 n (ngt0 : 0 < n) : P n.
+gen have H : n ngt0 / (0 <= n) && (n != 0).
+ match goal with |- is_true((0 <= n) && (n != 0)) => myadmit end.
+Check (H : forall n : nat, 0 < n -> (0 <= n) && (n != 0)).
+myadmit.
+Qed.
+
+Lemma test4 n (ngt0 : 0 < n) : P n.
+gen have : n ngt0 / (0 <= n) && (n != 0).
+ match goal with |- is_true((0 <= n) && (n != 0)) => myadmit end.
+move=> H.
+Check(H : forall n : nat, 0 < n -> (0 <= n) && (n != 0)).
+myadmit.
+Qed.
+
+Lemma test4bis n (ngt0 : 0 < n) : P n.
+wlog suff : n ngt0 / (0 <= n) && (n != 0); last first.
+ match goal with |- is_true((0 <= n) && (n != 0)) => myadmit end.
+move=> H.
+Check(H : forall n : nat, 0 < n -> (0 <= n) && (n != 0)).
+myadmit.
+Qed.
+
+Lemma test5 n (ngt0 : 0 < n) : P n.
+Fail gen have : / (0 <= n) && (n != 0).
+Abort.
+
+Lemma test6 n (ngt0 : 0 < n) : P n.
+gen have : n ngt0 / (0 <= n) && (n != 0) by myadmit.
+Abort.
+
+Lemma test7 n (ngt0 : 0 < n) : P n.
+Fail gen have : n / (0 <= n) && (n != 0).
+Abort.
+
+Lemma test3wlog2 n (ngt0 : 0 < n) : P n.
+gen have H : (m := n) ngt0 / (0 <= m) && (m != 0).
+ match goal with
+ ngt0 : is_true(0 < m) |- is_true((0 <= m) && (m != 0)) => myadmit end.
+Check (H : forall n : nat, 0 < n -> (0 <= n) && (n != 0)).
+myadmit.
+Qed.
+
+Lemma test3wlog3 n (ngt0 : 0 < n) : P n.
+gen have H : {n} (m := n) (n := 0) ngt0 / (0 <= m) && (m != n).
+ match goal with
+ ngt0 : is_true(n < m) |- is_true((0 <= m) && (m != n)) => myadmit end.
+Check (H : forall m n : nat, n < m -> (0 <= m) && (m != n)).
+myadmit.
+Qed.
+
+Lemma testw1 n (ngt0 : 0 < n) : n <= 0.
+wlog H : (z := 0) (m := n) ngt0 / m != 0.
+ match goal with
+ |- (forall z m,
+ is_true(z < m) -> is_true(m != 0) -> is_true(m <= z)) ->
+ is_true(n <= 0) => myadmit end.
+Check(n : nat).
+Check(m : nat).
+Check(z : nat).
+Check(ngt0 : z < m).
+Check(H : m != 0).
+myadmit.
+Qed.
+
+Lemma testw2 n (ngt0 : 0 < n) : n <= 0.
+wlog H : (m := n) (z := (X in n <= X)) ngt0 / m != z.
+ match goal with
+ |- (forall m z : nat,
+ is_true(0 < m) -> is_true(m != z) -> is_true(m <= z)) ->
+ is_true(n <= 0) => idtac end.
+Restart.
+wlog H : (m := n) (one := (X in X <= _)) ngt0 / m != one.
+ match goal with
+ |- (forall m one : nat,
+ is_true(one <= m) -> is_true(m != one) -> is_true(m <= 0)) ->
+ is_true(n <= 0) => idtac end.
+Restart.
+wlog H : {n} (m := n) (z := (X in _ <= X)) ngt0 / m != z.
+ match goal with
+ |- (forall m z : nat,
+ is_true(0 < z) -> is_true(m != z) -> is_true(m <= 0)) ->
+ is_true(n <= 0) => idtac end.
+ myadmit.
+Fail Check n.
+myadmit.
+Qed.
+
+Section Test.
+Variable x : nat.
+Definition addx y := y + x.
+
+Lemma testw3 (m n : nat) (ngt0 : 0 < n) : n <= addx x.
+wlog H : (n0 := n) (y := x) (@twoy := (id _ as X in _ <= X)) / twoy = 2 * y.
+ myadmit.
+myadmit.
+Qed.
+
+
+Definition twox := x + x.
+Definition bis := twox.
+
+Lemma testw3x n (ngt0 : 0 < n) : n + x <= twox.
+wlog H : (y := x) (@twoy := (X in _ <= X)) / twoy = 2 * y.
+ match goal with
+ |- (forall y : nat,
+ let twoy := y + y in
+ twoy = 2 * y -> is_true(n + y <= twoy)) ->
+ is_true(n + x <= twox) => myadmit end.
+Restart.
+wlog H : (y := x) (@twoy := (id _ as X in _ <= X)) / twoy = 2 * y.
+ match goal with
+ |- (forall y : nat,
+ let twoy := twox in
+ twoy = 2 * y -> is_true(n + y <= twoy)) ->
+ is_true(n + x <= twox) => myadmit end.
+myadmit.
+Qed.
+
+End Test.
+
+Lemma test_in n k (def_k : k = 0) (ngtk : k < n) : P n.
+rewrite -(add0n n) in {def_k k ngtk} (m := k) (def_m := def_k) (ngtm := ngtk).
+rewrite def_m add0n in {ngtm} (e := erefl 0 ) (ngt0 := ngtm) => {def_m}.
+myadmit.
+Qed.
diff --git a/test-suite/ssr/gen_pattern.v b/test-suite/ssr/gen_pattern.v
new file mode 100644
index 00000000..c0592e88
--- /dev/null
+++ b/test-suite/ssr/gen_pattern.v
@@ -0,0 +1,33 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool TestSuite.ssr_mini_mathcomp.
+
+Notation "( a 'in' c )" := (a + c) (only parsing) : myscope.
+Delimit Scope myscope with myscope.
+
+Notation "( a 'in' c )" := (a + c) (only parsing).
+
+Lemma foo x y : x + x.+1 = x.+1 + y.
+move: {x} (x.+1) {1}x y (x.+1 in RHS).
+ match goal with |- forall a b c d, b + a = d + c => idtac end.
+Admitted.
+
+Lemma bar x y : x + x.+1 = x.+1 + y.
+move E: ((x.+1 in y)) => w.
+ match goal with |- x + x.+1 = w => rewrite -{w}E end.
+move E: (x.+1 in y)%myscope => w.
+ match goal with |- x + x.+1 = w => rewrite -{w}E end.
+move E: ((x + y).+1 as RHS) => w.
+ match goal with |- x + x.+1 = w => rewrite -{}E -addSn end.
+Admitted.
diff --git a/test-suite/ssr/have_TC.v b/test-suite/ssr/have_TC.v
new file mode 100644
index 00000000..b3a26ed2
--- /dev/null
+++ b/test-suite/ssr/have_TC.v
@@ -0,0 +1,50 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+
+Axiom daemon : False. Ltac myadmit := case: daemon.
+
+Class foo (T : Type) := { n : nat }.
+Instance five : foo nat := {| n := 5 |}.
+
+Definition bar T {f : foo T} m : Prop :=
+ @n _ f = m.
+
+Eval compute in (bar nat 7).
+
+Lemma a : True.
+set toto := bar _ 8.
+have titi : bar _ 5.
+ reflexivity.
+have titi2 : bar _ 5 := .
+ Fail reflexivity.
+ by myadmit.
+have totoc (H : bar _ 5) : 3 = 3 := eq_refl.
+move/totoc: nat => _.
+exact I.
+Qed.
+
+Set SsrHave NoTCResolution.
+
+Lemma a' : True.
+set toto := bar _ 8.
+have titi : bar _ 5.
+ Fail reflexivity.
+ by myadmit.
+have titi2 : bar _ 5 := .
+ Fail reflexivity.
+ by myadmit.
+have totoc (H : bar _ 5) : 3 = 3 := eq_refl.
+move/totoc: nat => _.
+exact I.
+Qed.
diff --git a/test-suite/ssr/have_transp.v b/test-suite/ssr/have_transp.v
new file mode 100644
index 00000000..1c998da7
--- /dev/null
+++ b/test-suite/ssr/have_transp.v
@@ -0,0 +1,48 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrfun ssrbool TestSuite.ssr_mini_mathcomp.
+
+
+Lemma test1 n : n >= 0.
+Proof.
+have [:s1] @h m : 'I_(n+m).+1.
+ apply: Sub 0 _.
+ abstract: s1 m.
+ by auto.
+cut (forall m, 0 < (n+m).+1); last assumption.
+rewrite [_ 1 _]/= in s1 h *.
+by [].
+Qed.
+
+Lemma test2 n : n >= 0.
+Proof.
+have [:s1] @h m : 'I_(n+m).+1 := Sub 0 (s1 m).
+ move=> m; reflexivity.
+cut (forall m, 0 < (n+m).+1); last assumption.
+by [].
+Qed.
+
+Lemma test3 n : n >= 0.
+Proof.
+Fail have [:s1] @h m : 'I_(n+m).+1 by apply: (Sub 0 (s1 m)); auto.
+have [:s1] @h m : 'I_(n+m).+1 by apply: (Sub 0); abstract: s1 m; auto.
+cut (forall m, 0 < (n+m).+1); last assumption.
+by [].
+Qed.
+
+Lemma test4 n : n >= 0.
+Proof.
+have @h m : 'I_(n+m).+1 by apply: (Sub 0); abstract auto.
+by [].
+Qed.
diff --git a/test-suite/ssr/have_view_idiom.v b/test-suite/ssr/have_view_idiom.v
new file mode 100644
index 00000000..3d6c9d98
--- /dev/null
+++ b/test-suite/ssr/have_view_idiom.v
@@ -0,0 +1,18 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool.
+
+Lemma test (a b : bool) (pab : a && b) : b.
+have {pab} /= /andP [pa -> //] /= : true && (a && b) := pab.
+Qed.
diff --git a/test-suite/ssr/havesuff.v b/test-suite/ssr/havesuff.v
new file mode 100644
index 00000000..aa1f7187
--- /dev/null
+++ b/test-suite/ssr/havesuff.v
@@ -0,0 +1,85 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+
+
+Variables P G : Prop.
+
+Lemma test1 : (P -> G) -> P -> G.
+Proof.
+move=> pg p.
+have suff {pg} H : P.
+ match goal with |- P -> G => move=> _; exact: pg p | _ => fail end.
+match goal with H : P -> G |- G => exact: H p | _ => fail end.
+Qed.
+
+Lemma test2 : (P -> G) -> P -> G.
+Proof.
+move=> pg p.
+have suffices {pg} H : P.
+ match goal with |- P -> G => move=> _; exact: pg p | _ => fail end.
+match goal with H : P -> G |- G => exact: H p | _ => fail end.
+Qed.
+
+Lemma test3 : (P -> G) -> P -> G.
+Proof.
+move=> pg p.
+suff have {pg} H : P.
+ match goal with H : P |- G => exact: pg H | _ => fail end.
+match goal with |- (P -> G) -> G => move=> H; exact: H p | _ => fail end.
+Qed.
+
+Lemma test4 : (P -> G) -> P -> G.
+Proof.
+move=> pg p.
+suffices have {pg} H: P.
+ match goal with H : P |- G => exact: pg H | _ => fail end.
+match goal with |- (P -> G) -> G => move=> H; exact: H p | _ => fail end.
+Qed.
+
+(*
+Lemma test5 : (P -> G) -> P -> G.
+Proof.
+move=> pg p.
+suff have {pg} H : P := pg H.
+match goal with |- (P -> G) -> G => move=> H; exact: H p | _ => fail end.
+Qed.
+*)
+
+(*
+Lemma test6 : (P -> G) -> P -> G.
+Proof.
+move=> pg p.
+suff have {pg} H := pg H.
+match goal with |- (P -> G) -> G => move=> H; exact: H p | _ => fail end.
+Qed.
+*)
+
+Lemma test7 : (P -> G) -> P -> G.
+Proof.
+move=> pg p.
+have suff {pg} H : P := pg.
+match goal with H : P -> G |- G => exact: H p | _ => fail end.
+Qed.
+
+Lemma test8 : (P -> G) -> P -> G.
+Proof.
+move=> pg p.
+have suff {pg} H := pg.
+match goal with H : P -> G |- G => exact: H p | _ => fail end.
+Qed.
+
+Goal forall x y : bool, x = y -> x = y.
+move=> x y E.
+by have {x E} -> : x = y by [].
+Qed.
diff --git a/plugins/fourier/Fourier.v b/test-suite/ssr/if_isnt.v
index 07f32be8..b8f6b773 100644
--- a/plugins/fourier/Fourier.v
+++ b/test-suite/ssr/if_isnt.v
@@ -8,13 +8,15 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-(* "Fourier's method to solve linear inequations/equations systems.".*)
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-Require Export Field.
-Require Export DiscrR.
-Require Export Fourier_util.
-Declare ML Module "fourier_plugin".
+Require Import ssreflect.
-Ltac fourier := abstract (compute [IZR IPR IPR_2] in *; fourierz; field; discrR).
-Ltac fourier_eq := apply Rge_antisym; fourier.
+Definition unopt (x : option bool) :=
+ if x isn't Some x then false else x.
+
+Lemma test1 : unopt None = false /\
+ unopt (Some false) = false /\
+ unopt (Some true) = true.
+Proof. by auto. Qed.
diff --git a/test-suite/ssr/intro_beta.v b/test-suite/ssr/intro_beta.v
new file mode 100644
index 00000000..8a164bd8
--- /dev/null
+++ b/test-suite/ssr/intro_beta.v
@@ -0,0 +1,25 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+
+
+Axiom T : Type.
+
+Definition C (P : T -> Prop) := forall x, P x.
+
+Axiom P : T -> T -> Prop.
+
+Lemma foo : C (fun x => forall y, let z := x in P y x).
+move=> a b.
+match goal with |- (let y := _ in _) => idtac end.
+Admitted.
diff --git a/test-suite/ssr/intro_noop.v b/test-suite/ssr/intro_noop.v
new file mode 100644
index 00000000..fdc85173
--- /dev/null
+++ b/test-suite/ssr/intro_noop.v
@@ -0,0 +1,37 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool.
+Axiom daemon : False. Ltac myadmit := case: daemon.
+
+Lemma v : True -> bool -> bool. Proof. by []. Qed.
+
+Reserved Notation " a -/ b " (at level 0).
+Reserved Notation " a -// b " (at level 0).
+Reserved Notation " a -/= b " (at level 0).
+Reserved Notation " a -//= b " (at level 0).
+
+Lemma test : forall a b c, a || b || c.
+Proof.
+move=> ---a--- - -/=- -//- -/=- -//=- b [|-].
+move: {-}a => /v/v-H; have _ := H I I.
+Fail move: {-}a {H} => /v-/v-H.
+have - -> : a = (id a) by [].
+have --> : a = (id a) by [].
+have - - _ : a = (id a) by [].
+have -{1}-> : a = (id a) by [].
+ by myadmit.
+move: a.
+case: b => -[] //.
+by myadmit.
+Qed.
diff --git a/test-suite/ssr/ipat_clear_if_id.v b/test-suite/ssr/ipat_clear_if_id.v
new file mode 100644
index 00000000..7a44db2e
--- /dev/null
+++ b/test-suite/ssr/ipat_clear_if_id.v
@@ -0,0 +1,23 @@
+Require Import ssreflect.
+
+Axiom v1 : nat -> bool.
+
+Section Foo.
+
+Variable v2 : nat -> bool.
+
+Lemma test (v3 : nat -> bool) (v4 : bool -> bool) (v5 : bool -> bool) : nat -> nat -> nat -> nat -> True.
+Proof.
+move=> {}/v1 b1 {}/v2 b2 {}/v3 b3 {}/v2/v4/v5 b4.
+Check b1 : bool.
+Check b2 : bool.
+Check b3 : bool.
+Check b4 : bool.
+Fail Check v3.
+Fail Check v4.
+Fail Check v5.
+Check v2 : nat -> bool.
+by [].
+Qed.
+
+End Foo.
diff --git a/test-suite/ssr/ipatalternation.v b/test-suite/ssr/ipatalternation.v
new file mode 100644
index 00000000..6aa9a954
--- /dev/null
+++ b/test-suite/ssr/ipatalternation.v
@@ -0,0 +1,18 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+
+
+Lemma test1 : Prop -> Prop -> Prop -> Prop -> Prop -> True = False -> Prop -> True \/ True.
+by move=> A /= /= /= B C {A} {B} ? _ {C} {1}-> *; right.
+Qed.
diff --git a/test-suite/ssr/ltac_have.v b/test-suite/ssr/ltac_have.v
new file mode 100644
index 00000000..380e52af
--- /dev/null
+++ b/test-suite/ssr/ltac_have.v
@@ -0,0 +1,39 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool TestSuite.ssr_mini_mathcomp.
+
+Ltac SUFF1 h t := suff h x (p := x < 0) : t.
+Ltac SUFF2 h t := suff h x (p := x < 0) : t by apply h.
+Ltac HAVE1 h t u := have h x (p := x < 0) : t := u.
+Ltac HAVE2 h t := have h x (p := x < 0) : t by [].
+Ltac HAVE3 h t := have h x (p := x < 0) : t.
+Ltac HAVES h t := have suff h : t.
+Ltac SUFFH h t := suff have h : t.
+
+Lemma foo z : z < 0.
+SUFF1 h1 (z+1 < 0).
+Undo.
+SUFF2 h2 (z < 0).
+Undo.
+HAVE1 h3 (z = z) (refl_equal z).
+Undo.
+HAVE2 h4 (z = z).
+Undo.
+HAVE3 h5 (z < 0).
+Undo.
+HAVES h6 (z < 1).
+Undo.
+SUFFH h7 (z < 1).
+Undo.
+Admitted.
diff --git a/test-suite/ssr/ltac_in.v b/test-suite/ssr/ltac_in.v
new file mode 100644
index 00000000..bcdf96dd
--- /dev/null
+++ b/test-suite/ssr/ltac_in.v
@@ -0,0 +1,26 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool TestSuite.ssr_mini_mathcomp.
+
+Set Implicit Arguments.
+Unset Strict Implicit.
+Import Prenex Implicits.
+
+(* error 1 *)
+
+Ltac subst1 H := move: H; rewrite {1} addnC; move => H.
+Ltac subst2 H := rewrite addnC in H.
+
+Goal ( forall a b: nat, b+a = 0 -> b+a=0).
+Proof. move=> a b hyp. subst1 hyp. subst2 hyp. done. Qed.
diff --git a/theories/Compat/Coq86.v b/test-suite/ssr/move_after.v
index 666be207..a7a9afea 100644
--- a/theories/Compat/Coq86.v
+++ b/test-suite/ssr/move_after.v
@@ -8,8 +8,12 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-(** Compatibility file for making Coq act similar to Coq v8.6 *)
-Require Export Coq.Compat.Coq87.
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-Require Export Coq.extraction.Extraction.
-Require Export Coq.funind.FunInd.
+Require Import ssreflect.
+
+
+Goal True -> True -> True.
+move=> H1 H2.
+move H1 after H2.
+Admitted.
diff --git a/test-suite/ssr/multiview.v b/test-suite/ssr/multiview.v
new file mode 100644
index 00000000..f4e717b3
--- /dev/null
+++ b/test-suite/ssr/multiview.v
@@ -0,0 +1,58 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool TestSuite.ssr_mini_mathcomp.
+
+Goal forall m n p, n <= p -> m <= n -> m <= p.
+by move=> m n p le_n_p /leq_trans; apply.
+Undo 1.
+by move=> m n p le_n_p /leq_trans /(_ le_n_p) le_m_p; exact: le_m_p.
+Undo 1.
+by move=> m n p le_n_p /leq_trans ->.
+Qed.
+
+Goal forall P Q X : Prop, Q -> (True -> X -> Q = P) -> X -> P.
+by move=> P Q X q V /V <-.
+Qed.
+
+Lemma test0: forall a b, a && a && b -> b.
+by move=> a b; repeat move=> /andP []; move=> *.
+Qed.
+
+Lemma test1 : forall a b, a && b -> b.
+by move=> a b /andP /andP /andP [] //.
+Qed.
+
+Lemma test2 : forall a b, a && b -> b.
+by move=> a b /andP /andP /(@andP a) [] //.
+Qed.
+
+Lemma test3 : forall a b, a && (b && b) -> b.
+by move=> a b /andP [_ /andP [_ //]].
+Qed.
+
+Lemma test4: forall a b, a && b = b && a.
+by move=> a b; apply/andP/andP=> ?; apply/andP/andP/andP; rewrite andbC; apply/andP.
+Qed.
+
+Lemma test5: forall C I A O, (True -> O) -> (O -> A) -> (True -> A -> I) -> (I -> C) -> C.
+by move=> c i a o O A I C; apply/C/I/A/O.
+Qed.
+
+Lemma test6: forall A B, (A -> B) -> A -> B.
+move=> A B A_to_B a; move/A_to_B in a; exact: a.
+Qed.
+
+Lemma test7: forall A B, (A -> B) -> A -> B.
+move=> A B A_to_B a; apply A_to_B in a; exact: a.
+Qed.
diff --git a/clib/canary.ml b/test-suite/ssr/occarrow.v
index b8b79ed7..49af7ae0 100644
--- a/clib/canary.ml
+++ b/test-suite/ssr/occarrow.v
@@ -8,21 +8,16 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-type t = Obj.t
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
-let obj = Obj.new_block Obj.closure_tag 0
- (** This is an empty closure block. In the current implementation, it is
- sufficient to allow marshalling but forbid equality. Sadly still allows
- hash. *)
- (** FIXME : use custom blocks somehow. *)
+Require Import ssreflect.
+Require Import TestSuite.ssr_mini_mathcomp.
-module type Obj = sig type t end
+Lemma test1 : forall n m : nat, n = m -> m * m + n * n = n * n + n * n.
+move=> n m E; have [{2}-> _] : n * n = m * n /\ True by move: E => {1}<-.
+by move: E => {3}->.
+Qed.
-module Make(M : Obj) =
-struct
- type canary = t
- type t = (canary * M.t)
-
- let prj (_, x) = x
- let inj x = (obj, x)
-end
+Lemma test2 : forall n m : nat, True /\ (n = m -> n * n = n * m).
+by move=> n m; constructor=> [|{2}->].
+Qed.
diff --git a/test-suite/ssr/patnoX.v b/test-suite/ssr/patnoX.v
new file mode 100644
index 00000000..d69f03ac
--- /dev/null
+++ b/test-suite/ssr/patnoX.v
@@ -0,0 +1,18 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool.
+Goal forall x, x && true = x.
+move=> x.
+Fail (rewrite [X in _ && _]andbT).
+Abort.
diff --git a/test-suite/ssr/pattern.v b/test-suite/ssr/pattern.v
new file mode 100644
index 00000000..396f4f03
--- /dev/null
+++ b/test-suite/ssr/pattern.v
@@ -0,0 +1,32 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+Require Import ssrmatching.
+
+(*Set Debug SsrMatching.*)
+
+Tactic Notation "at" "[" ssrpatternarg(pat) "]" tactic(t) :=
+ let name := fresh in
+ let def_name := fresh in
+ ssrpattern pat;
+ intro name;
+ pose proof (refl_equal name) as def_name;
+ unfold name at 1 in def_name;
+ t def_name;
+ [ rewrite <- def_name | idtac.. ];
+ clear name def_name.
+
+Lemma test (H : True -> True -> 3 = 7) : 28 = 3 * 4.
+Proof.
+at [ X in X * 4 ] ltac:(fun place => rewrite -> H in place).
+- reflexivity.
+- trivial.
+- trivial.
+Qed.
diff --git a/test-suite/ssr/primproj.v b/test-suite/ssr/primproj.v
new file mode 100644
index 00000000..cf61eb43
--- /dev/null
+++ b/test-suite/ssr/primproj.v
@@ -0,0 +1,164 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+
+
+Require Import Setoid.
+Set Primitive Projections.
+
+
+Module CoqBug.
+Record foo A := Foo { foo_car : A }.
+
+Definition bar : foo _ := Foo nat 10.
+
+Variable alias : forall A, foo A -> A.
+
+Parameter e : @foo_car = alias.
+
+Goal foo_car _ bar = alias _ bar.
+Proof.
+(* Coq equally fails *)
+Fail rewrite -> e.
+Fail rewrite e at 1.
+Fail setoid_rewrite e.
+Fail setoid_rewrite e at 1.
+Set Keyed Unification.
+Fail rewrite -> e.
+Fail rewrite e at 1.
+Fail setoid_rewrite e.
+Fail setoid_rewrite e at 1.
+Admitted.
+
+End CoqBug.
+
+(* ----------------------------------------------- *)
+Require Import ssreflect.
+
+Set Primitive Projections.
+
+Module T1.
+
+Record foo A := Foo { foo_car : A }.
+
+Definition bar : foo _ := Foo nat 10.
+
+Goal foo_car _ bar = 10.
+Proof.
+match goal with
+| |- foo_car _ bar = 10 => idtac
+end.
+rewrite /foo_car.
+(*
+Fail match goal with
+| |- foo_car _ bar = 10 => idtac
+end.
+*)
+Admitted.
+
+End T1.
+
+
+Module T2.
+
+Record foo {A} := Foo { foo_car : A }.
+
+Definition bar : foo := Foo nat 10.
+
+Goal foo_car bar = 10.
+match goal with
+| |- foo_car bar = 10 => idtac
+end.
+rewrite /foo_car.
+(*
+Fail match goal with
+| |- foo_car bar = 10 => idtac
+end.
+*)
+Admitted.
+
+End T2.
+
+
+Module T3.
+
+Record foo {A} := Foo { foo_car : A }.
+
+Definition bar : foo := Foo nat 10.
+
+Goal foo_car bar = 10.
+Proof.
+rewrite -[foo_car _]/(id _).
+match goal with |- id _ = 10 => idtac end.
+Admitted.
+
+Goal foo_car bar = 10.
+Proof.
+set x := foo_car _.
+match goal with |- x = 10 => idtac end.
+Admitted.
+
+End T3.
+
+Module T4.
+
+Inductive seal {A} (f : A) := { unseal : A; seal_eq : unseal = f }.
+Arguments unseal {_ _} _.
+Arguments seal_eq {_ _} _.
+
+Record uPred : Type := IProp { uPred_holds :> Prop }.
+
+Definition uPred_or_def (P Q : uPred) : uPred :=
+ {| uPred_holds := P \/ Q |}.
+Definition uPred_or_aux : seal (@uPred_or_def). by eexists. Qed.
+Definition uPred_or := unseal uPred_or_aux.
+Definition uPred_or_eq: @uPred_or = @uPred_or_def := seal_eq uPred_or_aux.
+
+Lemma foobar (P1 P2 Q : uPred) :
+ (P1 <-> P2) -> (uPred_or P1 Q) <-> (uPred_or P2 Q).
+Proof.
+ rewrite uPred_or_eq. (* This fails. *)
+Admitted.
+
+End T4.
+
+
+Module DesignFlaw.
+
+Record foo A := Foo { foo_car : A }.
+Definition bar : foo _ := Foo nat 10.
+
+Definition app (f : foo nat -> nat) x := f x.
+
+Goal app (foo_car _) bar = 10.
+Proof.
+unfold app. (* mkApp should produce a Proj *)
+Fail set x := (foo_car _ _).
+Admitted.
+
+End DesignFlaw.
+
+
+Module Bug.
+
+Record foo A := Foo { foo_car : A }.
+
+Definition bar : foo _ := Foo nat 10.
+
+Variable alias : forall A, foo A -> A.
+
+Parameter e : @foo_car = alias.
+
+Goal foo_car _ bar = alias _ bar.
+Proof.
+Fail rewrite e. (* Issue: #86 *)
+Admitted.
+
+End Bug.
diff --git a/test-suite/ssr/rewpatterns.v b/test-suite/ssr/rewpatterns.v
new file mode 100644
index 00000000..f7993f40
--- /dev/null
+++ b/test-suite/ssr/rewpatterns.v
@@ -0,0 +1,146 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+
+Require Import ssreflect.
+Require Import ssrbool ssrfun TestSuite.ssr_mini_mathcomp.
+
+Lemma test1 : forall x y (f : nat -> nat), f (x + y).+1 = f (y + x.+1).
+by move=> x y f; rewrite [_.+1](addnC x.+1).
+Qed.
+
+Lemma test2 : forall x y f, x + y + f (y + x) + f (y + x) = x + y + f (y + x) + f (x + y).
+by move=> x y f; rewrite {2}[in f _]addnC.
+Qed.
+
+Lemma test2' : forall x y f, true && f (x * (y + x)) = true && f(x * (x + y)).
+by move=> x y f; rewrite [in f _](addnC y).
+Qed.
+
+Lemma test2'' : forall x y f, f (y + x) + f(y + x) + f(y + x) = f(x + y) + f(y + x) + f(x + y).
+by move=> x y f; rewrite {1 3}[in f _](addnC y).
+Qed.
+
+(* patterns catching bound vars not supported *)
+Lemma test2_1 : forall x y f, true && (let z := x in f (z * (y + x))) = true && f(x * (x + y)).
+by move=> x y f; rewrite [in f _](addnC x). (* put y when bound var will be OK *)
+Qed.
+
+Lemma test3 : forall x y f, x + f (x + y) (f (y + x) x) = x + f (x + y) (f (x + y) x).
+by move=> x y f; rewrite [in X in (f _ X)](addnC y).
+Qed.
+
+Lemma test3' : forall x y f, x = y -> x + f (x + x) x + f (x + x) x =
+ x + f (x + y) x + f (y + x) x.
+by move=> x y f E; rewrite {2 3}[in X in (f X _)]E.
+Qed.
+
+Lemma test3'' : forall x y f, x = y -> x + f (x + y) x + f (x + y) x =
+ x + f (x + y) x + f (y + y) x.
+by move=> x y f E; rewrite {2}[in X in (f X _)]E.
+Qed.
+
+Lemma test4 : forall x y f, x = y -> x + f (fun _ : nat => x + x) x + f (fun _ => x + x) x =
+ x + f (fun _ => x + y) x + f (fun _ => y + x) x.
+by move=> x y f E; rewrite {2 3}[in X in (f X _)]E.
+Qed.
+
+Lemma test4' : forall x y f, x = y -> x + f (fun _ _ _ : nat => x + x) x =
+ x + f (fun _ _ _ => x + y) x.
+by move=> x y f E; rewrite {2}[in X in (f X _)]E.
+Qed.
+
+Lemma test5 : forall x y f, x = y -> x + f (y + x) x + f (y + x) x =
+ x + f (x + y) x + f (y + x) x.
+by move=> x y f E; rewrite {1}[X in (f X _)]addnC.
+Qed.
+
+Lemma test3''' : forall x y f, x = y -> x + f (x + y) x + f (x + y) (x + y) =
+ x + f (x + y) x + f (y + y) (x + y).
+by move=> x y f E; rewrite {1}[in X in (f X X)]E.
+Qed.
+
+Lemma test3'''' : forall x y f, x = y -> x + f (x + y) x + f (x + y) (x + y) =
+ x + f (x + y) x + f (y + y) (y + y).
+by move=> x y f E; rewrite [in X in (f X X)]E.
+Qed.
+
+Lemma test3x : forall x y f, y+y = x+y -> x + f (x + y) x + f (x + y) (x + y) =
+ x + f (x + y) x + f (y + y) (y + y).
+by move=> x y f E; rewrite -[X in (f X X)]E.
+Qed.
+
+Lemma test6 : forall x y (f : nat -> nat), f (x + y).+1 = f (y.+1 + x).
+by move=> x y f; rewrite [(x + y) in X in (f X)]addnC.
+Qed.
+
+Lemma test7 : forall x y (f : nat -> nat), f (x + y).+1 = f (y + x.+1).
+by move=> x y f; rewrite [(x.+1 + y) as X in (f X)]addnC.
+Qed.
+
+Lemma manual x y z (f : nat -> nat -> nat) : (x + y).+1 + f (x.+1 + y) (z + (x + y).+1) = 0.
+Proof.
+rewrite [in f _]addSn.
+match goal with |- (x + y).+1 + f (x + y).+1 (z + (x + y).+1) = 0 => idtac end.
+rewrite -[X in _ = X]addn0.
+match goal with |- (x + y).+1 + f (x + y).+1 (z + (x + y).+1) = 0 + 0 => idtac end.
+rewrite -{2}[in X in _ = X](addn0 0).
+match goal with |- (x + y).+1 + f (x + y).+1 (z + (x + y).+1) = 0 + (0 + 0) => idtac end.
+rewrite [_.+1 in X in f _ X](addnC x.+1).
+match goal with |- (x + y).+1 + f (x + y).+1 (z + (y + x.+1)) = 0 + (0 + 0) => idtac end.
+rewrite [x.+1 + y as X in f X _]addnC.
+match goal with |- (x + y).+1 + f (y + x.+1) (z + (y + x.+1)) = 0 + (0 + 0) => idtac end.
+Admitted.
+
+Goal (exists x : 'I_3, x > 0).
+apply: (ex_intro _ (@Ordinal _ 2 _)).
+Admitted.
+
+Goal (forall y, 1 < y < 2 -> exists x : 'I_3, x > 0).
+move=> y; case/andP=> y_gt1 y_lt2; apply: (ex_intro _ (@Ordinal _ y _)).
+ by apply: leq_trans y_lt2 _.
+by move=> y_lt3; apply: leq_trans _ y_gt1.
+Qed.
+
+Goal (forall x y : nat, forall P : nat -> Prop, x = y -> True).
+move=> x y P E.
+have: P x -> P y by suff: x = y by move=> ?; congr (P _).
+Admitted.
+
+Goal forall a : bool, a -> true && a || false && a.
+by move=> a ?; rewrite [true && _]/= [_ && a]/= orbC [_ || _]//=.
+Qed.
+
+Goal forall a : bool, a -> true && a || false && a.
+by move=> a ?; rewrite [X in X || _]/= [X in _ || X]/= orbC [false && a as X in X || _]//=.
+Qed.
+
+Variable a : bool.
+Definition f x := x || a.
+Definition g x := f x.
+
+Goal a -> g false.
+by move=> Ha; rewrite [g _]/f orbC Ha.
+Qed.
+
+Goal a -> g false || g false.
+move=> Ha; rewrite {2}[g _]/f orbC Ha.
+match goal with |- (is_true (false || true || g false)) => done end.
+Qed.
+
+Goal a -> (a && a || true && a) && true.
+by move=> Ha; rewrite -[_ || _]/(g _) andbC /= Ha [g _]/f.
+Qed.
+
+Goal a -> (a || a) && true.
+by move=> Ha; rewrite -[in _ || _]/(f _) Ha andbC /f.
+Qed.
diff --git a/test-suite/ssr/rewrite_illtyped.v b/test-suite/ssr/rewrite_illtyped.v
new file mode 100644
index 00000000..7358068c
--- /dev/null
+++ b/test-suite/ssr/rewrite_illtyped.v
@@ -0,0 +1,9 @@
+From Coq Require Import ssreflect Setoid.
+
+Structure SEProp := {prop_of : Prop; _ : prop_of <-> True}.
+
+Fact anomaly: forall P : SEProp, prop_of P.
+Proof.
+move=> [P E].
+Fail rewrite E.
+Abort.
diff --git a/test-suite/ssr/set_lamda.v b/test-suite/ssr/set_lamda.v
new file mode 100644
index 00000000..a012ec68
--- /dev/null
+++ b/test-suite/ssr/set_lamda.v
@@ -0,0 +1,27 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool ssrfun.
+Require Import TestSuite.ssr_mini_mathcomp.
+
+Set Implicit Arguments.
+Unset Strict Implicit.
+Import Prenex Implicits.
+
+(* error 2 *)
+
+Goal (exists f: Set -> nat, f nat = 0).
+Proof. set (f:= fun _:Set =>0). by exists f. Qed.
+
+Goal (exists f: Set -> nat, f nat = 0).
+Proof. set f := (fun _:Set =>0). by exists f. Qed.
diff --git a/test-suite/ssr/set_pattern.v b/test-suite/ssr/set_pattern.v
new file mode 100644
index 00000000..3ce75e87
--- /dev/null
+++ b/test-suite/ssr/set_pattern.v
@@ -0,0 +1,64 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+
+Axiom daemon : False. Ltac myadmit := case: daemon.
+
+Ltac T1 x := match goal with |- _ => set t := (x in X in _ = X) end.
+Ltac T2 x := first [set t := (x in RHS)].
+Ltac T3 x := first [set t := (x in Y in _ = Y)|idtac].
+Ltac T4 x := set t := (x in RHS); idtac.
+Ltac T5 x := match goal with |- _ => set t := (x in RHS) | |- _ => idtac end.
+
+Require Import ssrbool TestSuite.ssr_mini_mathcomp.
+
+Open Scope nat_scope.
+
+Lemma foo x y : x.+1 = y + x.+1.
+set t := (_.+1 in RHS). match goal with |- x.+1 = y + t => rewrite /t {t} end.
+set t := (x in RHS). match goal with |- x.+1 = y + t.+1 => rewrite /t {t} end.
+set t := (x in _ = x). match goal with |- x.+1 = t => rewrite /t {t} end.
+set t := (x in X in _ = X).
+ match goal with |- x.+1 = y + t.+1 => rewrite /t {t} end.
+set t := (x in RHS). match goal with |- x.+1 = y + t.+1 => rewrite /t {t} end.
+set t := (y + (1 + x) as X in _ = X).
+ match goal with |- x.+1 = t => rewrite /t addSn add0n {t} end.
+set t := x.+1. match goal with |- t = y + t => rewrite /t {t} end.
+set t := (x).+1. match goal with |- t = y + t => rewrite /t {t} end.
+set t := ((x).+1 in X in _ = X).
+ match goal with |- x.+1 = y + t => rewrite /t {t} end.
+set t := (x.+1 in RHS). match goal with |- x.+1 = y + t => rewrite /t {t} end.
+T1 (x.+1). match goal with |- x.+1 = y + t => rewrite /t {t} end.
+T2 (x.+1). match goal with |- x.+1 = y + t => rewrite /t {t} end.
+T3 (x.+1). match goal with |- x.+1 = y + t => rewrite /t {t} end.
+T4 (x.+1). match goal with |- x.+1 = y + t => rewrite /t {t} end.
+T5 (x.+1). match goal with |- x.+1 = y + t => rewrite /t {t} end.
+rewrite [RHS]addnC.
+ match goal with |- x.+1 = x.+1 + y => rewrite -[RHS]addnC end.
+rewrite -[in RHS](@subnK 1 x.+1) //.
+ match goal with |- x.+1 = y + (x.+1 - 1 + 1) => rewrite subnK // end.
+have H : x.+1 = y by myadmit.
+set t := _.+1 in H |- *.
+ match goal with H : t = y |- t = y + t => rewrite /t {t} in H * end.
+set t := (_.+1 in X in _ + X) in H |- *.
+ match goal with H : x.+1 = y |- x.+1 = y + t => rewrite /t {t} in H * end.
+set t := 0. match goal with t := 0 |- x.+1 = y + x.+1 => clear t end.
+set t := y + _. match goal with |- x.+1 = t => rewrite /t {t} end.
+set t : nat := 0. clear t.
+set t : nat := (x in RHS).
+ match goal with |- x.+1 = y + t.+1 => rewrite /t {t} end.
+set t : nat := RHS. match goal with |- x.+1 = t => rewrite /t {t} end.
+(* set t := 0 + _. *)
+(* set t := (x).+1 in X in _ + X in H |-. *)
+(* set t := (x).+1 in X in _ = X.*)
+Admitted.
diff --git a/test-suite/ssr/ssrpattern.v b/test-suite/ssr/ssrpattern.v
new file mode 100644
index 00000000..422bb95f
--- /dev/null
+++ b/test-suite/ssr/ssrpattern.v
@@ -0,0 +1,7 @@
+Require Import ssrmatching.
+
+Goal forall n, match n with 0 => 0 | _ => 0 end = 0.
+Proof.
+ intro n.
+ ssrpattern (match _ with 0 => _ | S n' => _ end).
+Abort.
diff --git a/test-suite/ssr/ssrsyntax2.v b/test-suite/ssr/ssrsyntax2.v
new file mode 100644
index 00000000..af839fab
--- /dev/null
+++ b/test-suite/ssr/ssrsyntax2.v
@@ -0,0 +1,20 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import TestSuite.ssr_ssrsyntax1.
+Require Import Arith.
+
+Goal (forall a b, a + b = b + a).
+intros.
+rewrite plus_comm, plus_comm.
+split.
+Qed.
diff --git a/test-suite/ssr/tc.v b/test-suite/ssr/tc.v
new file mode 100644
index 00000000..ae4589ef
--- /dev/null
+++ b/test-suite/ssr/tc.v
@@ -0,0 +1,39 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+
+
+Class foo (A : Type) : Type := mkFoo { val : A }.
+Instance foo_pair {A B} {f1 : foo A} {f2 : foo B} : foo (A * B) | 2 :=
+ {| val := (@val _ f1, @val _ f2) |}.
+Instance foo_nat : foo nat | 3 := {| val := 0 |}.
+
+Definition id {A} (x : A) := x.
+Axiom E : forall A {f : foo A} (a : A), id a = (@val _ f).
+
+Lemma test (x : nat) : id true = true -> id x = 0.
+Proof.
+Fail move=> _; reflexivity.
+Timeout 2 rewrite E => _; reflexivity.
+Qed.
+
+Definition P {A} (x : A) : Prop := x = x.
+Axiom V : forall A {f : foo A} (x:A), P x -> P (id x).
+
+Lemma test1 (x : nat) : P x -> P (id x).
+Proof.
+move=> px.
+Timeout 2 Fail move/V: px.
+Timeout 2 move/V : (px) => _.
+move/(V nat) : px => H; exact H.
+Qed.
diff --git a/test-suite/ssr/typeof.v b/test-suite/ssr/typeof.v
new file mode 100644
index 00000000..ca121fdb
--- /dev/null
+++ b/test-suite/ssr/typeof.v
@@ -0,0 +1,22 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+
+Ltac mycut x :=
+ let tx := type of x in
+ cut tx.
+
+Lemma test : True.
+Proof.
+by mycut I=> [ x | ]; [ exact x | exact I ].
+Qed.
diff --git a/plugins/fourier/g_fourier.ml4 b/test-suite/ssr/unfold_Opaque.v
index 44560ac1..7c2b51de 100644
--- a/plugins/fourier/g_fourier.ml4
+++ b/test-suite/ssr/unfold_Opaque.v
@@ -8,11 +8,11 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Ltac_plugin
-open FourierR
+Require Import ssreflect.
-DECLARE PLUGIN "fourier_plugin"
+Definition x := 3.
+Opaque x.
-TACTIC EXTEND fourier
- [ "fourierz" ] -> [ fourier () ]
-END
+Goal x = 3.
+Fail rewrite /x.
+Admitted.
diff --git a/test-suite/ssr/unkeyed.v b/test-suite/ssr/unkeyed.v
new file mode 100644
index 00000000..710941c3
--- /dev/null
+++ b/test-suite/ssr/unkeyed.v
@@ -0,0 +1,31 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrfun ssrbool TestSuite.ssr_mini_mathcomp.
+
+Set Implicit Arguments.
+Unset Strict Implicit.
+Import Prenex Implicits.
+
+Lemma test0 (a b : unit) f : a = f b.
+Proof. by rewrite !unitE. Qed.
+
+Lemma phE T : all_equal_to (Phant T). Proof. by case. Qed.
+
+Lemma test1 (a b : phant nat) f : a = f b.
+Proof. by rewrite !phE. Qed.
+
+Lemma eq_phE (T : eqType) : all_equal_to (Phant T). Proof. by case. Qed.
+
+Lemma test2 (a b : phant bool) f : a = locked (f b).
+Proof. by rewrite !eq_phE. Qed.
diff --git a/test-suite/ssr/view_case.v b/test-suite/ssr/view_case.v
new file mode 100644
index 00000000..2721470c
--- /dev/null
+++ b/test-suite/ssr/view_case.v
@@ -0,0 +1,31 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool TestSuite.ssr_mini_mathcomp.
+
+Axiom P : forall T, seq T -> Prop.
+
+Goal (forall T (s : seq T), P _ s).
+move=> T s.
+elim: s => [| x /lastP [| s] IH].
+Admitted.
+
+Goal forall x : 'I_1, x = 0 :> nat.
+move=> /ord1 -> /=; exact: refl_equal.
+Qed.
+
+Goal forall x : 'I_1, x = 0 :> nat.
+move=> x.
+move=> /ord1 -> in x |- *.
+exact: refl_equal.
+Qed.
diff --git a/test-suite/ssr/wlog_suff.v b/test-suite/ssr/wlog_suff.v
new file mode 100644
index 00000000..43a8f3b8
--- /dev/null
+++ b/test-suite/ssr/wlog_suff.v
@@ -0,0 +1,28 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool.
+
+Lemma test b : b || ~~b.
+wlog _ : b / b = true.
+ case: b; [ by apply | by rewrite orbC ].
+wlog suff: b / b || ~~b.
+ by case: b.
+by case: b.
+Qed.
+
+Lemma test2 b c (H : c = b) : b || ~~b.
+wlog _ : b {c H} / b = true.
+ by case: b H.
+by case: b.
+Qed.
diff --git a/test-suite/ssr/wlogletin.v b/test-suite/ssr/wlogletin.v
new file mode 100644
index 00000000..64e1ea84
--- /dev/null
+++ b/test-suite/ssr/wlogletin.v
@@ -0,0 +1,50 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool.
+Require Import TestSuite.ssr_mini_mathcomp.
+
+Variable T : Type.
+Variables P : T -> Prop.
+
+Definition f := fun x y : T => x.
+
+Lemma test1 : forall x y : T, P (f x y) -> P x.
+Proof.
+move=> x y; set fxy := f x y; move=> Pfxy.
+wlog H : @fxy Pfxy / P x.
+ match goal with |- (let fxy0 := f x y in P fxy0 -> P x -> P x) -> P x => by auto | _ => fail end.
+exact: H.
+Qed.
+
+Lemma test2 : forall x y : T, P (f x y) -> P x.
+Proof.
+move=> x y; set fxy := f x y; move=> Pfxy.
+wlog H : fxy Pfxy / P x.
+ match goal with |- (forall fxy, P fxy -> P x -> P x) -> P x => by auto | _ => fail end.
+exact: H.
+Qed.
+
+Lemma test3 : forall x y : T, P (f x y) -> P x.
+Proof.
+move=> x y; set fxy := f x y; move=> Pfxy.
+move: {1}@fxy (Pfxy) (Pfxy).
+match goal with |- (let fxy0 := f x y in P fxy0 -> P fxy -> P x) => by auto | _ => fail end.
+Qed.
+
+Lemma test4 : forall n m z: bool, n = z -> let x := n in x = m && n -> x = m && n.
+move=> n m z E x H.
+case: true.
+ by rewrite {1 2}E in (x) H |- *.
+by rewrite {1}E in x H |- *.
+Qed.
diff --git a/test-suite/ssr/wlong_intro.v b/test-suite/ssr/wlong_intro.v
new file mode 100644
index 00000000..dd80f043
--- /dev/null
+++ b/test-suite/ssr/wlong_intro.v
@@ -0,0 +1,20 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* (c) Copyright 2006-2016 Microsoft Corporation and Inria. *)
+
+Require Import ssreflect.
+Require Import ssrbool.
+Require Import TestSuite.ssr_mini_mathcomp.
+
+Goal (forall x y : nat, True).
+move=> x y.
+wlog suff: x y / x <= y.
+Admitted.
diff --git a/test-suite/stm/Nijmegen_QArithSternBrocot_Zaux.v b/test-suite/stm/Nijmegen_QArithSternBrocot_Zaux.v
index 06357cfc..3c427237 100644
--- a/test-suite/stm/Nijmegen_QArithSternBrocot_Zaux.v
+++ b/test-suite/stm/Nijmegen_QArithSternBrocot_Zaux.v
@@ -23,7 +23,7 @@ Require Export ZArithRing.
Tactic Notation "ElimCompare" constr(c) constr(d) := elim_compare c d.
Ltac Flip :=
- apply Zgt_lt || apply Zlt_gt || apply Zle_ge || apply Zge_le; assumption.
+ apply Z.gt_lt || apply Z.lt_gt || apply Z.le_ge || apply Z.ge_le; assumption.
Ltac Falsum :=
try intro; apply False_ind;
@@ -37,12 +37,12 @@ Ltac Falsum :=
Ltac Step_l a :=
match goal with
| |- (?X1 < ?X2)%Z => replace X1 with a; [ idtac | try ring ]
- end.
+ end.
Ltac Step_r a :=
match goal with
| |- (?X1 < ?X2)%Z => replace X2 with a; [ idtac | try ring ]
- end.
+ end.
Ltac CaseEq formula :=
generalize (refl_equal formula); pattern formula at -1 in |- *;
@@ -53,7 +53,7 @@ Lemma pair_1 : forall (A B : Set) (H : A * B), H = pair (fst H) (snd H).
Proof.
intros.
case H.
- intros.
+ intros.
simpl in |- *.
reflexivity.
Qed.
@@ -73,10 +73,10 @@ Proof.
Qed.
-Section projection.
+Section projection.
Variable A : Set.
Variable P : A -> Prop.
-
+
Definition projP1 (H : sig P) := let (x, h) := H in x.
Definition projP2 (H : sig P) :=
let (x, h) as H return (P (projP1 H)) := H in h.
@@ -131,11 +131,11 @@ Declare Right Step neq_stepr.
Lemma not_O_S : forall n : nat, n <> 0 -> {p : nat | n = S p}.
-Proof.
+Proof.
intros [| np] Hn; [ exists 0; apply False_ind; apply Hn | exists np ];
- reflexivity.
+ reflexivity.
Qed.
-
+
Lemma lt_minus_neq : forall m n : nat, m < n -> n - m <> 0.
Proof.
@@ -156,12 +156,12 @@ Proof.
Qed.
Lemma le_plus_O_l : forall p q : nat, p + q <= 0 -> p = 0.
-Proof.
+Proof.
intros; omega.
Qed.
Lemma le_plus_O_r : forall p q : nat, p + q <= 0 -> q = 0.
-Proof.
+Proof.
intros; omega.
Qed.
@@ -228,8 +228,8 @@ Proof.
assumption.
intro.
right.
- apply Zle_lt_trans with (m := x).
- apply Zge_le.
+ apply Z.le_lt_trans with (m := x).
+ apply Z.ge_le.
assumption.
assumption.
Qed.
@@ -268,7 +268,7 @@ Proof.
left.
assumption.
intro H0.
- generalize (Zge_le _ _ H0).
+ generalize (Z.ge_le _ _ H0).
intro.
case (Z_le_lt_eq_dec _ _ H1).
intro.
@@ -290,25 +290,25 @@ Proof.
left.
assumption.
intro H.
- generalize (Zge_le _ _ H).
+ generalize (Z.ge_le _ _ H).
intro H0.
case (Z_le_lt_eq_dec y x H0).
intro H1.
left.
right.
- apply Zlt_gt.
+ apply Z.lt_gt.
assumption.
intro.
right.
symmetry in |- *.
assumption.
Qed.
-
+
Lemma Z_dec' : forall x y : Z, {(x < y)%Z} + {(y < x)%Z} + {x = y}.
Proof.
intros x y.
- case (Z_eq_dec x y); intro H;
+ case (Z.eq_dec x y); intro H;
[ right; assumption | left; apply (not_Zeq_inf _ _ H) ].
Qed.
@@ -321,7 +321,7 @@ Proof.
assumption.
intro.
right.
- apply Zge_le.
+ apply Z.ge_le.
assumption.
Qed.
@@ -335,7 +335,7 @@ Lemma Z_lt_lt_S_eq_dec :
Proof.
intros.
generalize (Zlt_le_succ _ _ H).
- unfold Zsucc in |- *.
+ unfold Z.succ in |- *.
apply Z_le_lt_eq_dec.
Qed.
@@ -347,7 +347,7 @@ Proof.
case (Z_lt_le_dec a c).
intro z.
right.
- intro.
+ intro.
elim H.
intros.
generalize z.
@@ -356,8 +356,8 @@ Proof.
intro.
case (Z_lt_le_dec b d).
intro z0.
- right.
- intro.
+ right.
+ intro.
elim H.
intros.
generalize z0.
@@ -367,7 +367,7 @@ Proof.
left.
split.
assumption.
- assumption.
+ assumption.
Qed.
(*###########################################################################*)
@@ -386,30 +386,30 @@ Qed.
Lemma Zlt_minus : forall a b : Z, (b < a)%Z -> (0 < a - b)%Z.
Proof.
- intros a b.
+ intros a b.
intros.
apply Zplus_lt_reg_l with b.
- unfold Zminus in |- *.
+ unfold Zminus in |- *.
rewrite (Zplus_comm a).
- rewrite (Zplus_assoc b (- b)).
+ rewrite (Zplus_assoc b (- b)).
rewrite Zplus_opp_r.
- simpl in |- *.
- rewrite <- Zplus_0_r_reverse.
+ simpl in |- *.
+ rewrite <- Zplus_0_r_reverse.
assumption.
Qed.
Lemma Zle_minus : forall a b : Z, (b <= a)%Z -> (0 <= a - b)%Z.
Proof.
- intros a b.
+ intros a b.
intros.
apply Zplus_le_reg_l with b.
- unfold Zminus in |- *.
+ unfold Zminus in |- *.
rewrite (Zplus_comm a).
- rewrite (Zplus_assoc b (- b)).
+ rewrite (Zplus_assoc b (- b)).
rewrite Zplus_opp_r.
- simpl in |- *.
- rewrite <- Zplus_0_r_reverse.
+ simpl in |- *.
+ rewrite <- Zplus_0_r_reverse.
assumption.
Qed.
@@ -417,7 +417,7 @@ Lemma Zlt_plus_plus :
forall m n p q : Z, (m < n)%Z -> (p < q)%Z -> (m + p < n + q)%Z.
Proof.
intros.
- apply Zlt_trans with (m := (n + p)%Z).
+ apply Z.lt_trans with (m := (n + p)%Z).
rewrite Zplus_comm.
rewrite Zplus_comm with (n := n).
apply Zplus_lt_compat_l.
@@ -459,11 +459,11 @@ Lemma Zge_gt_plus_plus :
Proof.
intros.
case (Zle_lt_or_eq n m).
- apply Zge_le.
+ apply Z.ge_le.
assumption.
intro.
apply Zgt_plus_plus.
- apply Zlt_gt.
+ apply Z.lt_gt.
assumption.
assumption.
intro.
@@ -521,7 +521,7 @@ Qed.
Lemma Zle_neg_opp : forall x : Z, (x <= 0)%Z -> (0 <= - x)%Z.
-Proof.
+Proof.
intros.
apply Zplus_le_reg_l with x.
rewrite Zplus_opp_r.
@@ -530,7 +530,7 @@ Proof.
Qed.
Lemma Zle_pos_opp : forall x : Z, (0 <= x)%Z -> (- x <= 0)%Z.
-Proof.
+Proof.
intros.
apply Zplus_le_reg_l with x.
rewrite Zplus_opp_r.
@@ -542,7 +542,7 @@ Qed.
Lemma Zge_opp : forall x y : Z, (x <= y)%Z -> (- x >= - y)%Z.
Proof.
intros.
- apply Zle_ge.
+ apply Z.le_ge.
apply Zplus_le_reg_l with (p := (x + y)%Z).
ring_simplify (x + y + - y)%Z (x + y + - x)%Z.
assumption.
@@ -584,8 +584,8 @@ Proof.
ring_simplify (- a * x + a * x)%Z.
replace (- a * x + a * y)%Z with ((y - x) * a)%Z.
apply Zmult_gt_0_le_0_compat.
- apply Zlt_gt.
- assumption.
+ apply Z.lt_gt.
+ assumption.
unfold Zminus in |- *.
apply Zle_left.
assumption.
@@ -621,7 +621,7 @@ Proof.
rewrite H0.
reflexivity.
Qed.
-
+
Lemma Zsimpl_mult_l :
forall n m p : Z, n <> 0%Z -> (n * m)%Z = (n * p)%Z -> m = p.
Proof.
@@ -642,14 +642,14 @@ Lemma Zlt_reg_mult_l :
Proof.
intros.
case (Zcompare_Gt_spec x 0).
- unfold Zgt in H.
+ unfold Z.gt in H.
assumption.
intros.
- cut (x = Zpos x0).
+ cut (x = Zpos x0).
intro.
rewrite H2.
- unfold Zlt in H0.
- unfold Zlt in |- *.
+ unfold Z.lt in H0.
+ unfold Z.lt in |- *.
cut ((Zpos x0 * y ?= Zpos x0 * z)%Z = (y ?= z)%Z).
intro.
exact (trans_eq H3 H0).
@@ -672,10 +672,10 @@ Proof.
intro.
cut ((y ?= x)%Z = (- x ?= - y)%Z).
intro.
- exact (trans_eq H0 H1).
+ exact (trans_eq H0 H1).
exact (Zcompare_opp y x).
apply sym_eq.
- exact (Zlt_gt x y H).
+ exact (Z.lt_gt x y H).
Qed.
@@ -698,22 +698,22 @@ Proof.
intro.
rewrite H6 in H4.
assumption.
- exact (Zopp_involutive (x * z)).
- exact (Zopp_involutive (x * y)).
+ exact (Z.opp_involutive (x * z)).
+ exact (Z.opp_involutive (x * y)).
cut ((- (- x * y))%Z = (- - (x * y))%Z).
intro.
rewrite H4 in H3.
- cut ((- (- x * z))%Z = (- - (x * z))%Z).
+ cut ((- (- x * z))%Z = (- - (x * z))%Z).
intro.
rewrite H5 in H3.
assumption.
cut ((- x * z)%Z = (- (x * z))%Z).
intro.
- exact (f_equal Zopp H5).
+ exact (f_equal Z.opp H5).
exact (Zopp_mult_distr_l_reverse x z).
cut ((- x * y)%Z = (- (x * y))%Z).
intro.
- exact (f_equal Zopp H4).
+ exact (f_equal Z.opp H4).
exact (Zopp_mult_distr_l_reverse x y).
exact (Zlt_opp (- x * y) (- x * z) H2).
exact (Zlt_reg_mult_l (- x) y z H1 H0).
@@ -735,14 +735,14 @@ Proof.
assumption.
exact (sym_eq H2).
exact (Zorder.Zlt_not_eq y x H0).
- exact (Zgt_lt x y H).
+ exact (Z.gt_lt x y H).
Qed.
Lemma Zmult_resp_nonzero :
forall x y : Z, x <> 0%Z -> y <> 0%Z -> (x * y)%Z <> 0%Z.
Proof.
intros x y Hx Hy Hxy.
- apply Hx.
+ apply Hx.
apply Zmult_integral_l with y; assumption.
Qed.
@@ -769,12 +769,12 @@ Qed.
Lemma not_Zle_lt : forall x y : Z, ~ (y <= x)%Z -> (x < y)%Z.
Proof.
- intros; apply Zgt_lt; apply Znot_le_gt; assumption.
+ intros; apply Z.gt_lt; apply Znot_le_gt; assumption.
Qed.
Lemma not_Zlt : forall x y : Z, ~ (y < x)%Z -> (x <= y)%Z.
Proof.
- intros x y H1 H2; apply H1; apply Zgt_lt; assumption.
+ intros x y H1 H2; apply H1; apply Z.gt_lt; assumption.
Qed.
@@ -813,7 +813,7 @@ Proof.
cut (x > 0)%Z.
intro.
exact (Zlt_reg_mult_l x y z H4 H2).
- exact (Zlt_gt 0 x H3).
+ exact (Z.lt_gt 0 x H3).
intro.
apply False_ind.
cut (x * z < x * y)%Z.
@@ -849,7 +849,7 @@ Proof.
cut (x > 0)%Z.
intro.
exact (Zlt_reg_mult_l x z y H4 H2).
- exact (Zlt_gt 0 x H3).
+ exact (Z.lt_gt 0 x H3).
Qed.
Lemma Zlt_mult_mult :
@@ -857,9 +857,9 @@ Lemma Zlt_mult_mult :
(0 < a)%Z -> (0 < d)%Z -> (a < b)%Z -> (c < d)%Z -> (a * c < b * d)%Z.
Proof.
intros.
- apply Zlt_trans with (a * d)%Z.
+ apply Z.lt_trans with (a * d)%Z.
apply Zlt_reg_mult_l.
- Flip.
+ Flip.
assumption.
rewrite Zmult_comm.
rewrite Zmult_comm with b d.
@@ -881,11 +881,11 @@ Proof.
apply Zgt_not_eq.
assumption.
trivial.
-
+
intro.
case (not_Zeq x y H1).
trivial.
-
+
intro.
apply False_ind.
cut (a * y > a * x)%Z.
@@ -913,14 +913,14 @@ Proof.
rewrite Zmult_opp_opp.
rewrite Zmult_opp_opp.
assumption.
- apply Zopp_involutive.
- apply Zopp_involutive.
- apply Zgt_lt.
+ apply Z.opp_involutive.
+ apply Z.opp_involutive.
+ apply Z.gt_lt.
apply Zlt_opp.
- apply Zgt_lt.
+ apply Z.gt_lt.
assumption.
simpl in |- *.
- rewrite Zopp_involutive.
+ rewrite Z.opp_involutive.
assumption.
Qed.
@@ -944,7 +944,7 @@ Proof.
constructor.
replace (-1 * y)%Z with (- y)%Z.
replace (-1 * x)%Z with (- x)%Z.
- apply Zlt_gt.
+ apply Z.lt_gt.
assumption.
ring.
ring.
@@ -959,13 +959,13 @@ Proof.
trivial.
intro.
apply False_ind.
- apply (Zlt_irrefl (a * x)).
- apply Zle_lt_trans with (m := (a * y)%Z).
+ apply (Z.lt_irrefl (a * x)).
+ apply Z.le_lt_trans with (m := (a * y)%Z).
assumption.
- apply Zgt_lt.
+ apply Z.gt_lt.
apply Zlt_conv_mult_l.
assumption.
- apply Zgt_lt.
+ apply Z.gt_lt.
assumption.
Qed.
@@ -973,17 +973,17 @@ Lemma Zlt_mult_cancel_l :
forall x y z : Z, (0 < x)%Z -> (x * y < x * z)%Z -> (y < z)%Z.
Proof.
intros.
- apply Zgt_lt.
+ apply Z.gt_lt.
apply Zgt_mult_reg_absorb_l with x.
- apply Zlt_gt.
- assumption.
- apply Zlt_gt.
+ apply Z.lt_gt.
+ assumption.
+ apply Z.lt_gt.
assumption.
Qed.
-
+
Lemma Zmin_cancel_Zle : forall x y : Z, (- x <= - y)%Z -> (y <= x)%Z.
-Proof.
+Proof.
intros.
apply Zmult_cancel_Zle with (a := (-1)%Z).
constructor.
@@ -1004,18 +1004,18 @@ Proof.
trivial.
intro.
apply False_ind.
- apply (Zlt_irrefl (a * y)).
- apply Zle_lt_trans with (m := (a * x)%Z).
+ apply (Z.lt_irrefl (a * y)).
+ apply Z.le_lt_trans with (m := (a * x)%Z).
assumption.
apply Zlt_reg_mult_l.
- apply Zlt_gt.
+ apply Z.lt_gt.
assumption.
- apply Zgt_lt.
+ apply Z.gt_lt.
assumption.
Qed.
Lemma Zopp_Zle : forall x y : Z, (y <= x)%Z -> (- x <= - y)%Z.
-Proof.
+Proof.
intros.
apply Zmult_cancel_Zle with (a := (-1)%Z).
constructor.
@@ -1026,7 +1026,7 @@ Proof.
clear x H; ring.
Qed.
-
+
Lemma Zle_lt_eq_S : forall x y : Z, (x <= y)%Z -> (y < x + 1)%Z -> y = x.
Proof.
intros.
@@ -1035,8 +1035,8 @@ Proof.
apply False_ind.
generalize (Zlt_le_succ x y H1).
intro.
- apply (Zlt_not_le y (x + 1) H0).
- replace (x + 1)%Z with (Zsucc x).
+ apply (Zlt_not_le y (x + 1) H0).
+ replace (x + 1)%Z with (Z.succ x).
assumption.
reflexivity.
intro H1.
@@ -1053,8 +1053,8 @@ Proof.
apply False_ind.
generalize (Zlt_le_succ x y H).
intro.
- apply (Zlt_not_le y (x + 1) H1).
- replace (x + 1)%Z with (Zsucc x).
+ apply (Zlt_not_le y (x + 1) H1).
+ replace (x + 1)%Z with (Z.succ x).
assumption.
reflexivity.
trivial.
@@ -1067,9 +1067,9 @@ Proof.
intros.
case (Z_zerop c).
intro.
- rewrite e.
+ rewrite e.
left.
- apply sym_not_eq.
+ apply sym_not_eq.
intro.
apply H; repeat split; assumption.
intro; right; assumption.
@@ -1085,21 +1085,21 @@ Proof.
[ apply False_ind; apply H; repeat split | right; right ]
| right; left ]
| left ]; assumption.
-Qed.
+Qed.
Lemma mediant_1 :
forall m n m' n' : Z, (m' * n < m * n')%Z -> ((m + m') * n < m * (n + n'))%Z.
Proof.
- intros.
- rewrite Zmult_plus_distr_r.
+ intros.
+ rewrite Zmult_plus_distr_r.
rewrite Zmult_plus_distr_l.
apply Zplus_lt_compat_l.
assumption.
Qed.
-
+
Lemma mediant_2 :
forall m n m' n' : Z,
- (m' * n < m * n')%Z -> (m' * (n + n') < (m + m') * n')%Z.
+ (m' * n < m * n')%Z -> (m' * (n + n') < (m + m') * n')%Z.
Proof.
intros.
rewrite Zmult_plus_distr_l.
@@ -1121,7 +1121,7 @@ Proof.
assumption.
assumption.
ring.
-Qed.
+Qed.
Lemma fraction_lt_trans :
forall a b c d e f : Z,
@@ -1130,21 +1130,21 @@ Lemma fraction_lt_trans :
(0 < f)%Z -> (a * d < c * b)%Z -> (c * f < e * d)%Z -> (a * f < e * b)%Z.
Proof.
intros.
- apply Zgt_lt.
+ apply Z.gt_lt.
apply Zgt_mult_reg_absorb_l with d.
Flip.
apply Zgt_trans with (c * b * f)%Z.
replace (d * (e * b))%Z with (b * (e * d))%Z.
replace (c * b * f)%Z with (b * (c * f))%Z.
- apply Zlt_gt.
+ apply Z.lt_gt.
apply Zlt_reg_mult_l.
Flip.
assumption.
ring.
ring.
- replace (c * b * f)%Z with (f * (c * b))%Z.
+ replace (c * b * f)%Z with (f * (c * b))%Z.
replace (d * (a * f))%Z with (f * (a * d))%Z.
- apply Zlt_gt.
+ apply Z.lt_gt.
apply Zlt_reg_mult_l.
Flip.
assumption.
@@ -1157,7 +1157,7 @@ Lemma square_pos : forall a : Z, a <> 0%Z -> (0 < a * a)%Z.
Proof.
intros [| p| p]; intros; [ Falsum | constructor | constructor ].
Qed.
-
+
Hint Resolve square_pos: zarith.
(*###########################################################################*)
@@ -1182,19 +1182,19 @@ Proof.
intros.
unfold Z_of_nat in |- *.
rewrite H0.
-
+
apply f_equal with (A := positive) (B := Z) (f := Zpos).
cut (P_of_succ_nat (nat_of_P p) = P_of_succ_nat (S x)).
intro.
rewrite P_of_succ_nat_o_nat_of_P_eq_succ in H1.
- cut (Ppred (Psucc p) = Ppred (P_of_succ_nat (S x))).
+ cut (Pos.pred (Pos.succ p) = Pos.pred (P_of_succ_nat (S x))).
intro.
- rewrite Ppred_succ in H2.
+ rewrite Pos.pred_succ in H2.
simpl in H2.
- rewrite Ppred_succ in H2.
+ rewrite Pos.pred_succ in H2.
apply sym_eq.
assumption.
- apply f_equal with (A := positive) (B := positive) (f := Ppred).
+ apply f_equal with (A := positive) (B := positive) (f := Pos.pred).
assumption.
apply f_equal with (f := P_of_succ_nat).
assumption.
@@ -1222,7 +1222,7 @@ Lemma NEG_neq_ZERO : forall p : positive, Zneg p <> 0%Z.
Proof.
intros.
apply Zorder.Zlt_not_eq.
- unfold Zlt in |- *.
+ unfold Z.lt in |- *.
constructor.
Qed.
@@ -1237,7 +1237,7 @@ Qed.
Lemma nat_nat_pos : forall m n : nat, ((m + 1) * (n + 1) > 0)%Z. (*QF*)
Proof.
intros.
- apply Zlt_gt.
+ apply Z.lt_gt.
cut (Z_of_nat m + 1 > 0)%Z.
intro.
cut (0 < Z_of_nat n + 1)%Z.
@@ -1246,24 +1246,24 @@ Proof.
rewrite Zmult_0_r.
intro.
assumption.
-
+
apply Zlt_reg_mult_l.
assumption.
assumption.
- change (0 < Zsucc (Z_of_nat n))%Z in |- *.
+ change (0 < Z.succ (Z_of_nat n))%Z in |- *.
apply Zle_lt_succ.
change (Z_of_nat 0 <= Z_of_nat n)%Z in |- *.
apply Znat.inj_le.
apply le_O_n.
- apply Zlt_gt.
- change (0 < Zsucc (Z_of_nat m))%Z in |- *.
+ apply Z.lt_gt.
+ change (0 < Z.succ (Z_of_nat m))%Z in |- *.
apply Zle_lt_succ.
change (Z_of_nat 0 <= Z_of_nat m)%Z in |- *.
apply Znat.inj_le.
apply le_O_n.
Qed.
-
-
+
+
Theorem S_predn : forall m : nat, m <> 0 -> S (pred m) = m. (*QF*)
Proof.
intros.
@@ -1271,8 +1271,8 @@ Proof.
intro.
case s.
intros.
- rewrite <- e.
- rewrite <- pred_Sn with (n := x).
+ rewrite <- e.
+ rewrite <- pred_Sn with (n := x).
trivial.
intro.
apply False_ind.
@@ -1281,7 +1281,7 @@ Proof.
assumption.
Qed.
-Lemma absolu_1 : forall x : Z, Zabs_nat x = 0 -> x = 0%Z. (*QF*)
+Lemma absolu_1 : forall x : Z, Z.abs_nat x = 0 -> x = 0%Z. (*QF*)
Proof.
intros.
case (dec_eq x 0).
@@ -1302,15 +1302,15 @@ Proof.
apply proj1 with (B := x = 0%Z -> (x ?= 0)%Z = Datatypes.Eq).
change ((x ?= 0)%Z = Datatypes.Eq <-> x = 0%Z) in |- *.
apply Zcompare_Eq_iff_eq.
-
+
(***)
intro.
- cut (exists h : nat, Zabs_nat x = S h).
+ cut (exists h : nat, Z.abs_nat x = S h).
intro.
case H3.
rewrite H.
exact O_S.
-
+
change (x < 0)%Z in H2.
cut (0 > x)%Z.
intro.
@@ -1324,7 +1324,7 @@ Proof.
case H6.
intros.
rewrite H7.
- unfold Zabs_nat in |- *.
+ unfold Z.abs_nat in |- *.
generalize x1.
exact ZL4.
cut (x = (- Zpos x0)%Z).
@@ -1335,21 +1335,21 @@ Proof.
cut ((- - x)%Z = x).
intro.
rewrite <- H6.
- exact (f_equal Zopp H5).
- apply Zopp_involutive.
+ exact (f_equal Z.opp H5).
+ apply Z.opp_involutive.
apply Zcompare_Gt_spec.
assumption.
- apply Zlt_gt.
+ apply Z.lt_gt.
assumption.
-
+
(***)
intro.
- cut (exists h : nat, Zabs_nat x = S h).
+ cut (exists h : nat, Z.abs_nat x = S h).
intro.
case H3.
rewrite H.
exact O_S.
-
+
cut (exists p : positive, (x + - (0))%Z = Zpos p).
simpl in |- *.
rewrite Zplus_0_r.
@@ -1357,12 +1357,12 @@ Proof.
case H3.
intros.
rewrite H4.
- unfold Zabs_nat in |- *.
+ unfold Z.abs_nat in |- *.
generalize x0.
exact ZL4.
apply Zcompare_Gt_spec.
assumption.
-
+
(***)
cut ((x < 0)%Z \/ (0 < x)%Z).
intro.
@@ -1373,14 +1373,14 @@ Proof.
assumption.
intro.
right.
- apply Zlt_gt.
+ apply Z.lt_gt.
assumption.
assumption.
apply not_Zeq.
assumption.
Qed.
-Lemma absolu_2 : forall x : Z, x <> 0%Z -> Zabs_nat x <> 0. (*QF*)
+Lemma absolu_2 : forall x : Z, x <> 0%Z -> Z.abs_nat x <> 0. (*QF*)
Proof.
intros.
intro.
@@ -1392,7 +1392,7 @@ Qed.
-Lemma absolu_inject_nat : forall n : nat, Zabs_nat (Z_of_nat n) = n.
+Lemma absolu_inject_nat : forall n : nat, Z.abs_nat (Z_of_nat n) = n.
Proof.
simple induction n; simpl in |- *.
reflexivity.
@@ -1404,7 +1404,7 @@ Qed.
Lemma eq_inj : forall m n : nat, m = n :>Z -> m = n.
Proof.
intros.
- generalize (f_equal Zabs_nat H).
+ generalize (f_equal Z.abs_nat H).
intro.
rewrite (absolu_inject_nat m) in H0.
rewrite (absolu_inject_nat n) in H0.
@@ -1438,7 +1438,7 @@ Qed.
Lemma le_absolu :
forall x y : Z,
- (0 <= x)%Z -> (0 <= y)%Z -> (x <= y)%Z -> Zabs_nat x <= Zabs_nat y.
+ (0 <= x)%Z -> (0 <= y)%Z -> (x <= y)%Z -> Z.abs_nat x <= Z.abs_nat y.
Proof.
intros [| x| x] [| y| y] Hx Hy Hxy;
apply le_O_n ||
@@ -1451,7 +1451,7 @@ Proof.
| id1:(Zpos _ <= Zneg _)%Z |- _ =>
apply False_ind; apply id1; constructor
end).
- simpl in |- *.
+ simpl in |- *.
apply le_inj.
do 2 rewrite ZL9.
assumption.
@@ -1459,7 +1459,7 @@ Qed.
Lemma lt_absolu :
forall x y : Z,
- (0 <= x)%Z -> (0 <= y)%Z -> (x < y)%Z -> Zabs_nat x < Zabs_nat y.
+ (0 <= x)%Z -> (0 <= y)%Z -> (x < y)%Z -> Z.abs_nat x < Z.abs_nat y.
Proof.
intros [| x| x] [| y| y] Hx Hy Hxy; inversion Hxy;
try
@@ -1470,13 +1470,13 @@ Proof.
apply False_ind; apply id1; constructor
| id1:(Zpos _ <= Zneg _)%Z |- _ =>
apply False_ind; apply id1; constructor
- end; simpl in |- *; apply lt_inj; repeat rewrite ZL9;
+ end; simpl in |- *; apply lt_inj; repeat rewrite ZL9;
assumption.
Qed.
Lemma absolu_plus :
forall x y : Z,
- (0 <= x)%Z -> (0 <= y)%Z -> Zabs_nat (x + y) = Zabs_nat x + Zabs_nat y.
+ (0 <= x)%Z -> (0 <= y)%Z -> Z.abs_nat (x + y) = Z.abs_nat x + Z.abs_nat y.
Proof.
intros [| x| x] [| y| y] Hx Hy; trivial;
try
@@ -1489,23 +1489,23 @@ Proof.
apply False_ind; apply id1; constructor
end.
rewrite <- BinInt.Zpos_plus_distr.
- unfold Zabs_nat in |- *.
+ unfold Z.abs_nat in |- *.
apply nat_of_P_plus_morphism.
Qed.
Lemma pred_absolu :
- forall x : Z, (0 < x)%Z -> pred (Zabs_nat x) = Zabs_nat (x - 1).
+ forall x : Z, (0 < x)%Z -> pred (Z.abs_nat x) = Z.abs_nat (x - 1).
Proof.
intros x Hx.
generalize (Z_lt_lt_S_eq_dec 0 x Hx); simpl in |- *; intros [H1| H1];
- [ replace (Zabs_nat x) with (Zabs_nat (x - 1 + 1));
+ [ replace (Z.abs_nat x) with (Z.abs_nat (x - 1 + 1));
[ idtac | apply f_equal with Z; auto with zarith ];
rewrite absolu_plus;
- [ unfold Zabs_nat at 2, nat_of_P, Piter_op in |- *; omega
+ [ unfold Z.abs_nat at 2, nat_of_P, Pos.iter_op in |- *; omega
| auto with zarith
| intro; discriminate ]
| rewrite <- H1; reflexivity ].
-Qed.
+Qed.
Definition pred_nat : forall (x : Z) (Hx : (0 < x)%Z), nat.
intros [| px| px] Hx; try abstract (discriminate Hx).
@@ -1535,7 +1535,7 @@ Proof.
Qed.
Lemma absolu_pred_nat :
- forall (m : Z) (Hm : (0 < m)%Z), S (pred_nat m Hm) = Zabs_nat m.
+ forall (m : Z) (Hm : (0 < m)%Z), S (pred_nat m Hm) = Z.abs_nat m.
Proof.
intros [| px| px] Hx; try discriminate Hx.
unfold pred_nat in |- *.
@@ -1545,7 +1545,7 @@ Proof.
Qed.
Lemma pred_nat_absolu :
- forall (m : Z) (Hm : (0 < m)%Z), pred_nat m Hm = Zabs_nat (m - 1).
+ forall (m : Z) (Hm : (0 < m)%Z), pred_nat m Hm = Z.abs_nat (m - 1).
Proof.
intros [| px| px] Hx; try discriminate Hx.
unfold pred_nat in |- *.
@@ -1557,15 +1557,15 @@ Lemma minus_pred_nat :
S (pred_nat n Hn) - S (pred_nat m Hm) = S (pred_nat (n - m) Hnm).
Proof.
intros.
- simpl in |- *.
+ simpl in |- *.
destruct n; try discriminate Hn.
destruct m; try discriminate Hm.
unfold pred_nat at 1 2 in |- *.
rewrite minus_pred; try apply lt_O_nat_of_P.
apply eq_inj.
- rewrite <- pred_nat_unfolded.
+ rewrite <- pred_nat_unfolded.
rewrite Znat.inj_minus1.
- repeat rewrite ZL9.
+ repeat rewrite ZL9.
reflexivity.
apply le_inj.
apply Zlt_le_weak.
@@ -1581,13 +1581,13 @@ Qed.
Lemma Zsgn_1 :
- forall x : Z, {Zsgn x = 0%Z} + {Zsgn x = 1%Z} + {Zsgn x = (-1)%Z}. (*QF*)
+ forall x : Z, {Z.sgn x = 0%Z} + {Z.sgn x = 1%Z} + {Z.sgn x = (-1)%Z}. (*QF*)
Proof.
intros.
case x.
left.
left.
- unfold Zsgn in |- *.
+ unfold Z.sgn in |- *.
reflexivity.
intro.
simpl in |- *.
@@ -1601,13 +1601,13 @@ Proof.
Qed.
-Lemma Zsgn_2 : forall x : Z, Zsgn x = 0%Z -> x = 0%Z. (*QF*)
+Lemma Zsgn_2 : forall x : Z, Z.sgn x = 0%Z -> x = 0%Z. (*QF*)
Proof.
intros [| p1| p1]; simpl in |- *; intro H; constructor || discriminate H.
Qed.
-Lemma Zsgn_3 : forall x : Z, x <> 0%Z -> Zsgn x <> 0%Z. (*QF*)
+Lemma Zsgn_3 : forall x : Z, x <> 0%Z -> Z.sgn x <> 0%Z. (*QF*)
Proof.
intro.
case x.
@@ -1626,21 +1626,21 @@ Qed.
-Theorem Zsgn_4 : forall a : Z, a = (Zsgn a * Zabs_nat a)%Z. (*QF*)
+Theorem Zsgn_4 : forall a : Z, a = (Z.sgn a * Z.abs_nat a)%Z. (*QF*)
Proof.
intro.
case a.
simpl in |- *.
reflexivity.
intro.
- unfold Zsgn in |- *.
- unfold Zabs_nat in |- *.
+ unfold Z.sgn in |- *.
+ unfold Z.abs_nat in |- *.
rewrite Zmult_1_l.
symmetry in |- *.
apply ZL9.
intros.
- unfold Zsgn in |- *.
- unfold Zabs_nat in |- *.
+ unfold Z.sgn in |- *.
+ unfold Z.abs_nat in |- *.
rewrite ZL9.
constructor.
Qed.
@@ -1650,7 +1650,7 @@ Theorem Zsgn_5 :
forall a b x y : Z,
x <> 0%Z ->
y <> 0%Z ->
- (Zsgn a * x)%Z = (Zsgn b * y)%Z -> (Zsgn a * y)%Z = (Zsgn b * x)%Z. (*QF*)
+ (Z.sgn a * x)%Z = (Z.sgn b * y)%Z -> (Z.sgn a * y)%Z = (Z.sgn b * x)%Z. (*QF*)
Proof.
intros a b x y H H0.
case a.
@@ -1660,7 +1660,7 @@ Proof.
trivial.
intro.
- unfold Zsgn in |- *.
+ unfold Z.sgn in |- *.
intro.
rewrite Zmult_1_l in H1.
simpl in H1.
@@ -1669,11 +1669,11 @@ Proof.
symmetry in |- *.
assumption.
intro.
- unfold Zsgn in |- *.
+ unfold Z.sgn in |- *.
intro.
apply False_ind.
apply H0.
- apply Zopp_inj.
+ apply Z.opp_inj.
simpl in |- *.
transitivity (-1 * y)%Z.
constructor.
@@ -1683,13 +1683,13 @@ Proof.
simpl in |- *.
reflexivity.
intro.
- unfold Zsgn at 1 in |- *.
- unfold Zsgn at 2 in |- *.
+ unfold Z.sgn at 1 in |- *.
+ unfold Z.sgn at 2 in |- *.
intro.
transitivity y.
rewrite Zmult_1_l.
reflexivity.
- transitivity (Zsgn b * (Zsgn b * y))%Z.
+ transitivity (Z.sgn b * (Z.sgn b * y))%Z.
case (Zsgn_1 b).
intro.
case s.
@@ -1712,20 +1712,20 @@ Proof.
rewrite H1.
reflexivity.
intro.
- unfold Zsgn at 1 in |- *.
- unfold Zsgn at 2 in |- *.
+ unfold Z.sgn at 1 in |- *.
+ unfold Z.sgn at 2 in |- *.
intro.
- transitivity (Zsgn b * (-1 * (Zsgn b * y)))%Z.
+ transitivity (Z.sgn b * (-1 * (Z.sgn b * y)))%Z.
case (Zsgn_1 b).
intros.
case s.
intro.
apply False_ind.
apply H.
- apply Zopp_inj.
+ apply Z.opp_inj.
transitivity (-1 * x)%Z.
ring.
- unfold Zopp in |- *.
+ unfold Z.opp in |- *.
rewrite e in H1.
transitivity (0 * y)%Z.
assumption.
@@ -1741,7 +1741,7 @@ Proof.
ring.
Qed.
-Lemma Zsgn_6 : forall x : Z, x = 0%Z -> Zsgn x = 0%Z.
+Lemma Zsgn_6 : forall x : Z, x = 0%Z -> Z.sgn x = 0%Z.
Proof.
intros.
rewrite H.
@@ -1750,44 +1750,44 @@ Proof.
Qed.
-Lemma Zsgn_7 : forall x : Z, (x > 0)%Z -> Zsgn x = 1%Z.
+Lemma Zsgn_7 : forall x : Z, (x > 0)%Z -> Z.sgn x = 1%Z.
Proof.
intro.
case x.
intro.
apply False_ind.
- apply (Zlt_irrefl 0).
+ apply (Z.lt_irrefl 0).
Flip.
intros.
simpl in |- *.
reflexivity.
intros.
apply False_ind.
- apply (Zlt_irrefl (Zneg p)).
- apply Zlt_trans with 0%Z.
+ apply (Z.lt_irrefl (Zneg p)).
+ apply Z.lt_trans with 0%Z.
constructor.
Flip.
Qed.
-Lemma Zsgn_7' : forall x : Z, (0 < x)%Z -> Zsgn x = 1%Z.
+Lemma Zsgn_7' : forall x : Z, (0 < x)%Z -> Z.sgn x = 1%Z.
Proof.
intros; apply Zsgn_7; Flip.
Qed.
-Lemma Zsgn_8 : forall x : Z, (x < 0)%Z -> Zsgn x = (-1)%Z.
+Lemma Zsgn_8 : forall x : Z, (x < 0)%Z -> Z.sgn x = (-1)%Z.
Proof.
intro.
case x.
intro.
apply False_ind.
- apply (Zlt_irrefl 0).
+ apply (Z.lt_irrefl 0).
assumption.
intros.
apply False_ind.
- apply (Zlt_irrefl 0).
- apply Zlt_trans with (Zpos p).
+ apply (Z.lt_irrefl 0).
+ apply Z.lt_trans with (Zpos p).
constructor.
assumption.
intros.
@@ -1795,7 +1795,7 @@ Proof.
reflexivity.
Qed.
-Lemma Zsgn_9 : forall x : Z, Zsgn x = 1%Z -> (0 < x)%Z.
+Lemma Zsgn_9 : forall x : Z, Z.sgn x = 1%Z -> (0 < x)%Z.
Proof.
intro.
case x.
@@ -1809,8 +1809,8 @@ Proof.
apply False_ind.
discriminate.
Qed.
-
-Lemma Zsgn_10 : forall x : Z, Zsgn x = (-1)%Z -> (x < 0)%Z.
+
+Lemma Zsgn_10 : forall x : Z, Z.sgn x = (-1)%Z -> (x < 0)%Z.
Proof.
intro.
case x.
@@ -1822,9 +1822,9 @@ Proof.
discriminate.
intros.
constructor.
-Qed.
+Qed.
-Lemma Zsgn_11 : forall x : Z, (Zsgn x < 0)%Z -> (x < 0)%Z.
+Lemma Zsgn_11 : forall x : Z, (Z.sgn x < 0)%Z -> (x < 0)%Z.
Proof.
intros.
apply Zsgn_10.
@@ -1833,7 +1833,7 @@ Proof.
apply False_ind.
case s.
intro.
- generalize (Zorder.Zlt_not_eq _ _ H).
+ generalize (Zorder.Zlt_not_eq _ _ H).
intro.
apply (H0 e).
intro.
@@ -1842,9 +1842,9 @@ Proof.
intro.
discriminate.
trivial.
-Qed.
+Qed.
-Lemma Zsgn_12 : forall x : Z, (0 < Zsgn x)%Z -> (0 < x)%Z.
+Lemma Zsgn_12 : forall x : Z, (0 < Z.sgn x)%Z -> (0 < x)%Z.
Proof.
intros.
apply Zsgn_9.
@@ -1852,7 +1852,7 @@ Proof.
intro.
case s.
intro.
- generalize (Zorder.Zlt_not_eq _ _ H).
+ generalize (Zorder.Zlt_not_eq _ _ H).
intro.
generalize (sym_eq e).
intro.
@@ -1865,78 +1865,78 @@ Proof.
intro.
apply False_ind.
discriminate.
-Qed.
+Qed.
-Lemma Zsgn_13 : forall x : Z, (0 <= Zsgn x)%Z -> (0 <= x)%Z.
+Lemma Zsgn_13 : forall x : Z, (0 <= Z.sgn x)%Z -> (0 <= x)%Z.
Proof.
- intros.
- case (Z_le_lt_eq_dec 0 (Zsgn x) H).
+ intros.
+ case (Z_le_lt_eq_dec 0 (Z.sgn x) H).
intro.
apply Zlt_le_weak.
apply Zsgn_12.
- assumption.
+ assumption.
intro.
- assert (x = 0%Z).
+ assert (x = 0%Z).
apply Zsgn_2.
symmetry in |- *.
assumption.
rewrite H0.
- apply Zle_refl.
+ apply Z.le_refl.
Qed.
-Lemma Zsgn_14 : forall x : Z, (Zsgn x <= 0)%Z -> (x <= 0)%Z.
+Lemma Zsgn_14 : forall x : Z, (Z.sgn x <= 0)%Z -> (x <= 0)%Z.
Proof.
- intros.
- case (Z_le_lt_eq_dec (Zsgn x) 0 H).
+ intros.
+ case (Z_le_lt_eq_dec (Z.sgn x) 0 H).
intro.
apply Zlt_le_weak.
apply Zsgn_11.
- assumption.
+ assumption.
intro.
- assert (x = 0%Z).
+ assert (x = 0%Z).
apply Zsgn_2.
assumption.
rewrite H0.
- apply Zle_refl.
+ apply Z.le_refl.
Qed.
-Lemma Zsgn_15 : forall x y : Z, Zsgn (x * y) = (Zsgn x * Zsgn y)%Z.
+Lemma Zsgn_15 : forall x y : Z, Z.sgn (x * y) = (Z.sgn x * Z.sgn y)%Z.
Proof.
intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; constructor.
Qed.
Lemma Zsgn_16 :
forall x y : Z,
- Zsgn (x * y) = 1%Z -> {(0 < x)%Z /\ (0 < y)%Z} + {(x < 0)%Z /\ (y < 0)%Z}.
+ Z.sgn (x * y) = 1%Z -> {(0 < x)%Z /\ (0 < y)%Z} + {(x < 0)%Z /\ (y < 0)%Z}.
Proof.
intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intro H;
try discriminate H; [ left | right ]; repeat split.
-Qed.
+Qed.
Lemma Zsgn_17 :
forall x y : Z,
- Zsgn (x * y) = (-1)%Z -> {(0 < x)%Z /\ (y < 0)%Z} + {(x < 0)%Z /\ (0 < y)%Z}.
+ Z.sgn (x * y) = (-1)%Z -> {(0 < x)%Z /\ (y < 0)%Z} + {(x < 0)%Z /\ (0 < y)%Z}.
Proof.
intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intro H;
try discriminate H; [ left | right ]; repeat split.
-Qed.
+Qed.
-Lemma Zsgn_18 : forall x y : Z, Zsgn (x * y) = 0%Z -> {x = 0%Z} + {y = 0%Z}.
+Lemma Zsgn_18 : forall x y : Z, Z.sgn (x * y) = 0%Z -> {x = 0%Z} + {y = 0%Z}.
Proof.
intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intro H;
try discriminate H; [ left | right | right ]; constructor.
-Qed.
+Qed.
-Lemma Zsgn_19 : forall x y : Z, (0 < Zsgn x + Zsgn y)%Z -> (0 < x + y)%Z.
+Lemma Zsgn_19 : forall x y : Z, (0 < Z.sgn x + Z.sgn y)%Z -> (0 < x + y)%Z.
Proof.
Proof.
intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intro H;
discriminate H || (constructor || apply Zsgn_12; assumption).
Qed.
-Lemma Zsgn_20 : forall x y : Z, (Zsgn x + Zsgn y < 0)%Z -> (x + y < 0)%Z.
+Lemma Zsgn_20 : forall x y : Z, (Z.sgn x + Z.sgn y < 0)%Z -> (x + y < 0)%Z.
Proof.
Proof.
intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intro H;
@@ -1944,43 +1944,43 @@ Proof.
Qed.
-Lemma Zsgn_21 : forall x y : Z, (0 < Zsgn x + Zsgn y)%Z -> (0 <= x)%Z.
+Lemma Zsgn_21 : forall x y : Z, (0 < Z.sgn x + Z.sgn y)%Z -> (0 <= x)%Z.
Proof.
intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intros H H0;
discriminate H || discriminate H0.
Qed.
-Lemma Zsgn_22 : forall x y : Z, (Zsgn x + Zsgn y < 0)%Z -> (x <= 0)%Z.
+Lemma Zsgn_22 : forall x y : Z, (Z.sgn x + Z.sgn y < 0)%Z -> (x <= 0)%Z.
Proof.
Proof.
intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intros H H0;
discriminate H || discriminate H0.
Qed.
-Lemma Zsgn_23 : forall x y : Z, (0 < Zsgn x + Zsgn y)%Z -> (0 <= y)%Z.
+Lemma Zsgn_23 : forall x y : Z, (0 < Z.sgn x + Z.sgn y)%Z -> (0 <= y)%Z.
Proof.
intros [|p1|p1] [|p2|p2]; simpl in |- *;
intros H H0; discriminate H || discriminate H0.
Qed.
-Lemma Zsgn_24 : forall x y : Z, (Zsgn x + Zsgn y < 0)%Z -> (y <= 0)%Z.
+Lemma Zsgn_24 : forall x y : Z, (Z.sgn x + Z.sgn y < 0)%Z -> (y <= 0)%Z.
Proof.
intros [|p1|p1] [|p2|p2]; simpl in |- *;
intros H H0; discriminate H || discriminate H0.
Qed.
-Lemma Zsgn_25 : forall x : Z, Zsgn (- x) = (- Zsgn x)%Z.
+Lemma Zsgn_25 : forall x : Z, Z.sgn (- x) = (- Z.sgn x)%Z.
Proof.
intros [| p1| p1]; simpl in |- *; reflexivity.
Qed.
-Lemma Zsgn_26 : forall x : Z, (0 < x)%Z -> (0 < Zsgn x)%Z.
+Lemma Zsgn_26 : forall x : Z, (0 < x)%Z -> (0 < Z.sgn x)%Z.
Proof.
intros [| p| p] Hp; trivial.
Qed.
-Lemma Zsgn_27 : forall x : Z, (x < 0)%Z -> (Zsgn x < 0)%Z.
+Lemma Zsgn_27 : forall x : Z, (x < 0)%Z -> (Z.sgn x < 0)%Z.
Proof.
intros [| p| p] Hp; trivial.
Qed.
@@ -1994,7 +1994,7 @@ Hint Resolve Zsgn_1 Zsgn_2 Zsgn_3 Zsgn_4 Zsgn_5 Zsgn_6 Zsgn_7 Zsgn_7' Zsgn_8
(** Properties of Zabs *)
(*###########################################################################*)
-Lemma Zabs_1 : forall z p : Z, (Zabs z < p)%Z -> (z < p)%Z /\ (- p < z)%Z.
+Lemma Zabs_1 : forall z p : Z, (Z.abs z < p)%Z -> (z < p)%Z /\ (- p < z)%Z.
Proof.
intros z p.
case z.
@@ -2003,25 +2003,25 @@ Proof.
split.
assumption.
apply Zgt_mult_conv_absorb_l with (a := (-1)%Z).
- replace (-1)%Z with (Zpred 0).
+ replace (-1)%Z with (Z.pred 0).
apply Zlt_pred.
simpl; trivial.
ring_simplify (-1 * - p)%Z (-1 * 0)%Z.
- apply Zlt_gt.
+ apply Z.lt_gt.
assumption.
intros.
simpl in H.
split.
assumption.
- apply Zlt_trans with (m := 0%Z).
+ apply Z.lt_trans with (m := 0%Z).
apply Zgt_mult_conv_absorb_l with (a := (-1)%Z).
- replace (-1)%Z with (Zpred 0).
+ replace (-1)%Z with (Z.pred 0).
apply Zlt_pred.
simpl; trivial.
ring_simplify (-1 * - p)%Z (-1 * 0)%Z.
- apply Zlt_gt.
- apply Zlt_trans with (m := Zpos p0).
+ apply Z.lt_gt.
+ apply Z.lt_trans with (m := Zpos p0).
constructor.
assumption.
constructor.
@@ -2029,28 +2029,28 @@ Proof.
intros.
simpl in H.
split.
- apply Zlt_trans with (m := Zpos p0).
+ apply Z.lt_trans with (m := Zpos p0).
constructor.
assumption.
-
+
apply Zgt_mult_conv_absorb_l with (a := (-1)%Z).
- replace (-1)%Z with (Zpred 0).
+ replace (-1)%Z with (Z.pred 0).
apply Zlt_pred.
simpl;trivial.
ring_simplify (-1 * - p)%Z.
replace (-1 * Zneg p0)%Z with (- Zneg p0)%Z.
- replace (- Zneg p0)%Z with (Zpos p0).
- apply Zlt_gt.
+ replace (- Zneg p0)%Z with (Zpos p0).
+ apply Z.lt_gt.
assumption.
symmetry in |- *.
apply Zopp_neg.
- rewrite Zopp_mult_distr_l_reverse with (n := 1%Z).
+ rewrite Zopp_mult_distr_l_reverse with (n := 1%Z).
simpl in |- *.
constructor.
Qed.
-Lemma Zabs_2 : forall z p : Z, (Zabs z > p)%Z -> (z > p)%Z \/ (- p > z)%Z.
+Lemma Zabs_2 : forall z p : Z, (Z.abs z > p)%Z -> (z > p)%Z \/ (- p > z)%Z.
Proof.
intros z p.
case z.
@@ -2067,7 +2067,7 @@ Proof.
intros.
simpl in H.
right.
- apply Zlt_gt.
+ apply Z.lt_gt.
apply Zgt_mult_conv_absorb_l with (a := (-1)%Z).
constructor.
ring_simplify (-1 * - p)%Z.
@@ -2076,22 +2076,22 @@ Proof.
reflexivity.
Qed.
-Lemma Zabs_3 : forall z p : Z, (z < p)%Z /\ (- p < z)%Z -> (Zabs z < p)%Z.
+Lemma Zabs_3 : forall z p : Z, (z < p)%Z /\ (- p < z)%Z -> (Z.abs z < p)%Z.
Proof.
intros z p.
case z.
- intro.
+ intro.
simpl in |- *.
elim H.
intros.
assumption.
-
+
intros.
elim H.
intros.
simpl in |- *.
assumption.
-
+
intros.
elim H.
intros.
@@ -2100,14 +2100,14 @@ Proof.
constructor.
replace (-1 * Zpos p0)%Z with (Zneg p0).
replace (-1 * p)%Z with (- p)%Z.
- apply Zlt_gt.
+ apply Z.lt_gt.
assumption.
- ring.
+ ring.
simpl in |- *.
reflexivity.
Qed.
-Lemma Zabs_4 : forall z p : Z, (Zabs z < p)%Z -> (- p < z < p)%Z.
+Lemma Zabs_4 : forall z p : Z, (Z.abs z < p)%Z -> (- p < z < p)%Z.
Proof.
intros.
split.
@@ -2118,28 +2118,28 @@ Proof.
apply Zabs_1.
assumption.
Qed.
-
-Lemma Zabs_5 : forall z p : Z, (Zabs z <= p)%Z -> (- p <= z <= p)%Z.
+
+Lemma Zabs_5 : forall z p : Z, (Z.abs z <= p)%Z -> (- p <= z <= p)%Z.
Proof.
intros.
split.
- replace (- p)%Z with (Zsucc (- Zsucc p)).
+ replace (- p)%Z with (Z.succ (- Z.succ p)).
apply Zlt_le_succ.
- apply proj2 with (A := (z < Zsucc p)%Z).
+ apply proj2 with (A := (z < Z.succ p)%Z).
apply Zabs_1.
apply Zle_lt_succ.
assumption.
- unfold Zsucc in |- *.
+ unfold Z.succ in |- *.
ring.
apply Zlt_succ_le.
- apply proj1 with (B := (- Zsucc p < z)%Z).
+ apply proj1 with (B := (- Z.succ p < z)%Z).
apply Zabs_1.
apply Zle_lt_succ.
assumption.
Qed.
-Lemma Zabs_6 : forall z p : Z, (Zabs z <= p)%Z -> (z <= p)%Z.
+Lemma Zabs_6 : forall z p : Z, (Z.abs z <= p)%Z -> (z <= p)%Z.
Proof.
intros.
apply proj2 with (A := (- p <= z)%Z).
@@ -2147,7 +2147,7 @@ Proof.
assumption.
Qed.
-Lemma Zabs_7 : forall z p : Z, (Zabs z <= p)%Z -> (- p <= z)%Z.
+Lemma Zabs_7 : forall z p : Z, (Z.abs z <= p)%Z -> (- p <= z)%Z.
Proof.
intros.
apply proj1 with (B := (z <= p)%Z).
@@ -2155,7 +2155,7 @@ Proof.
assumption.
Qed.
-Lemma Zabs_8 : forall z p : Z, (- p <= z <= p)%Z -> (Zabs z <= p)%Z.
+Lemma Zabs_8 : forall z p : Z, (- p <= z <= p)%Z -> (Z.abs z <= p)%Z.
Proof.
intros.
apply Zlt_succ_le.
@@ -2165,14 +2165,14 @@ Proof.
split.
apply Zle_lt_succ.
assumption.
- apply Zlt_le_trans with (m := (- p)%Z).
- apply Zgt_lt.
+ apply Z.lt_le_trans with (m := (- p)%Z).
+ apply Z.gt_lt.
apply Zlt_opp.
apply Zlt_succ.
assumption.
Qed.
-Lemma Zabs_min : forall z : Z, Zabs z = Zabs (- z).
+Lemma Zabs_min : forall z : Z, Z.abs z = Z.abs (- z).
Proof.
intro.
case z.
@@ -2187,67 +2187,67 @@ Proof.
Qed.
Lemma Zabs_9 :
- forall z p : Z, (0 <= p)%Z -> (p < z)%Z \/ (z < - p)%Z -> (p < Zabs z)%Z.
+ forall z p : Z, (0 <= p)%Z -> (p < z)%Z \/ (z < - p)%Z -> (p < Z.abs z)%Z.
Proof.
intros.
case H0.
intro.
- replace (Zabs z) with z.
+ replace (Z.abs z) with z.
assumption.
symmetry in |- *.
- apply Zabs_eq.
+ apply Z.abs_eq.
apply Zlt_le_weak.
- apply Zle_lt_trans with (m := p).
+ apply Z.le_lt_trans with (m := p).
assumption.
assumption.
intro.
- cut (Zabs z = (- z)%Z).
+ cut (Z.abs z = (- z)%Z).
intro.
rewrite H2.
apply Zmin_cancel_Zlt.
ring_simplify (- - z)%Z.
assumption.
rewrite Zabs_min.
- apply Zabs_eq.
+ apply Z.abs_eq.
apply Zlt_le_weak.
- apply Zle_lt_trans with (m := p).
+ apply Z.le_lt_trans with (m := p).
assumption.
apply Zmin_cancel_Zlt.
ring_simplify (- - z)%Z.
assumption.
Qed.
-Lemma Zabs_10 : forall z : Z, (0 <= Zabs z)%Z.
+Lemma Zabs_10 : forall z : Z, (0 <= Z.abs z)%Z.
Proof.
intro.
case (Z_zerop z).
intro.
rewrite e.
simpl in |- *.
- apply Zle_refl.
+ apply Z.le_refl.
intro.
case (not_Zeq z 0 n).
intro.
apply Zlt_le_weak.
apply Zabs_9.
- apply Zle_refl.
+ apply Z.le_refl.
simpl in |- *.
right.
assumption.
intro.
apply Zlt_le_weak.
apply Zabs_9.
- apply Zle_refl.
+ apply Z.le_refl.
simpl in |- *.
left.
assumption.
Qed.
-Lemma Zabs_11 : forall z : Z, z <> 0%Z -> (0 < Zabs z)%Z.
+Lemma Zabs_11 : forall z : Z, z <> 0%Z -> (0 < Z.abs z)%Z.
Proof.
intros.
apply Zabs_9.
- apply Zle_refl.
+ apply Z.le_refl.
simpl in |- *.
apply not_Zeq.
intro.
@@ -2256,14 +2256,14 @@ Proof.
assumption.
Qed.
-Lemma Zabs_12 : forall z m : Z, (m < Zabs z)%Z -> {(m < z)%Z} + {(z < - m)%Z}.
+Lemma Zabs_12 : forall z m : Z, (m < Z.abs z)%Z -> {(m < z)%Z} + {(z < - m)%Z}.
Proof.
intros [| p| p] m; simpl in |- *; intros H;
- [ left | left | right; apply Zmin_cancel_Zlt; rewrite Zopp_involutive ];
+ [ left | left | right; apply Zmin_cancel_Zlt; rewrite Z.opp_involutive ];
assumption.
Qed.
-Lemma Zabs_mult : forall z p : Z, Zabs (z * p) = (Zabs z * Zabs p)%Z.
+Lemma Zabs_mult : forall z p : Z, Z.abs (z * p) = (Z.abs z * Z.abs p)%Z.
Proof.
intros.
case z.
@@ -2290,22 +2290,22 @@ Proof.
reflexivity.
Qed.
-Lemma Zabs_plus : forall z p : Z, (Zabs (z + p) <= Zabs z + Zabs p)%Z.
+Lemma Zabs_plus : forall z p : Z, (Z.abs (z + p) <= Z.abs z + Z.abs p)%Z.
Proof.
intros.
case z.
simpl in |- *.
- apply Zle_refl.
+ apply Z.le_refl.
case p.
intro.
simpl in |- *.
- apply Zle_refl.
+ apply Z.le_refl.
intros.
simpl in |- *.
- apply Zle_refl.
+ apply Z.le_refl.
intros.
- unfold Zabs at 2 in |- *.
- unfold Zabs at 2 in |- *.
+ unfold Z.abs at 2 in |- *.
+ unfold Z.abs at 2 in |- *.
apply Zabs_8.
split.
apply Zplus_le_reg_l with (Zpos p1 - Zneg p0)%Z.
@@ -2322,17 +2322,17 @@ Proof.
ring.
ring.
apply Zplus_le_compat.
- apply Zle_refl.
+ apply Z.le_refl.
apply Zlt_le_weak.
constructor.
-
+
case p.
simpl in |- *.
intro.
- apply Zle_refl.
+ apply Z.le_refl.
intros.
- unfold Zabs at 2 in |- *.
- unfold Zabs at 2 in |- *.
+ unfold Z.abs at 2 in |- *.
+ unfold Z.abs at 2 in |- *.
apply Zabs_8.
split.
apply Zplus_le_reg_l with (Zpos p1 + Zneg p0)%Z.
@@ -2360,13 +2360,13 @@ Proof.
apply Zplus_le_compat.
apply Zlt_le_weak.
constructor.
- apply Zle_refl.
+ apply Z.le_refl.
intros.
simpl in |- *.
- apply Zle_refl.
+ apply Z.le_refl.
Qed.
-Lemma Zabs_neg : forall z : Z, (z <= 0)%Z -> Zabs z = (- z)%Z.
+Lemma Zabs_neg : forall z : Z, (z <= 0)%Z -> Z.abs z = (- z)%Z.
Proof.
intro.
case z.
@@ -2383,11 +2383,11 @@ Proof.
reflexivity.
Qed.
-Lemma Zle_Zabs: forall z, (z <= Zabs z)%Z.
+Lemma Zle_Zabs: forall z, (z <= Z.abs z)%Z.
Proof.
- intros [|z|z]; simpl; auto with zarith; apply Zle_neg_pos.
+ intros [|z|z]; simpl; auto with zarith; apply Zle_neg_pos.
Qed.
-
+
Hint Resolve Zabs_1 Zabs_2 Zabs_3 Zabs_4 Zabs_5 Zabs_6 Zabs_7 Zabs_8 Zabs_9
Zabs_10 Zabs_11 Zabs_12 Zabs_min Zabs_neg Zabs_mult Zabs_plus Zle_Zabs: zarith.
@@ -2400,7 +2400,7 @@ Lemma Zind :
forall (P : Z -> Prop) (p : Z),
P p ->
(forall q : Z, (p <= q)%Z -> P q -> P (q + 1)%Z) ->
- forall q : Z, (p <= q)%Z -> P q.
+ forall q : Z, (p <= q)%Z -> P q.
Proof.
intros P p.
intro.
@@ -2426,14 +2426,14 @@ Proof.
replace (p + Z_of_nat (S k))%Z with (p + k + 1)%Z.
apply H0.
apply Zplus_le_reg_l with (p := (- p)%Z).
- replace (- p + p)%Z with (Z_of_nat 0).
+ replace (- p + p)%Z with (Z_of_nat 0).
ring_simplify (- p + (p + Z_of_nat k))%Z.
apply Znat.inj_le.
apply le_O_n.
- ring_simplify; auto with arith.
+ ring_simplify; auto with arith.
assumption.
rewrite (Znat.inj_S k).
- unfold Zsucc in |- *.
+ unfold Z.succ in |- *.
ring.
intros.
cut (exists k : nat, (q - p)%Z = Z_of_nat k).
@@ -2457,7 +2457,7 @@ Lemma Zrec :
forall (P : Z -> Set) (p : Z),
P p ->
(forall q : Z, (p <= q)%Z -> P q -> P (q + 1)%Z) ->
- forall q : Z, (p <= q)%Z -> P q.
+ forall q : Z, (p <= q)%Z -> P q.
Proof.
intros F p.
intro.
@@ -2483,7 +2483,7 @@ Proof.
replace (p + Z_of_nat (S k))%Z with (p + k + 1)%Z.
apply H0.
apply Zplus_le_reg_l with (p := (- p)%Z).
- replace (- p + p)%Z with (Z_of_nat 0).
+ replace (- p + p)%Z with (Z_of_nat 0).
replace (- p + (p + Z_of_nat k))%Z with (Z_of_nat k).
apply Znat.inj_le.
apply le_O_n.
@@ -2491,7 +2491,7 @@ Proof.
rewrite Zplus_opp_l; reflexivity.
assumption.
rewrite (Znat.inj_S k).
- unfold Zsucc in |- *.
+ unfold Z.succ in |- *.
apply Zplus_assoc_reverse.
intros.
cut {k : nat | (q - p)%Z = Z_of_nat k}.
@@ -2540,14 +2540,14 @@ Proof.
replace (p - 0)%Z with p.
assumption.
unfold Zminus in |- *.
- unfold Zopp in |- *.
+ unfold Z.opp in |- *.
rewrite Zplus_0_r; reflexivity.
replace (p - Z_of_nat (S k))%Z with (p - k - 1)%Z.
apply H0.
apply Zplus_le_reg_l with (p := (- p)%Z).
- replace (- p + p)%Z with (- Z_of_nat 0)%Z.
+ replace (- p + p)%Z with (- Z_of_nat 0)%Z.
replace (- p + (p - Z_of_nat k))%Z with (- Z_of_nat k)%Z.
- apply Zge_le.
+ apply Z.ge_le.
apply Zge_opp.
apply Znat.inj_le.
apply le_O_n.
@@ -2555,7 +2555,7 @@ Proof.
rewrite Zplus_opp_l; reflexivity.
assumption.
rewrite (Znat.inj_S k).
- unfold Zsucc in |- *.
+ unfold Z.succ in |- *.
unfold Zminus at 1 2 in |- *.
rewrite Zplus_assoc_reverse.
rewrite <- Zopp_plus_distr.
@@ -2567,16 +2567,16 @@ Proof.
intro k.
intros.
exists k.
- apply Zopp_inj.
+ apply Z.opp_inj.
apply Zplus_reg_l with (n := p).
- replace (p + - (p - Z_of_nat k))%Z with (Z_of_nat k).
+ replace (p + - (p - Z_of_nat k))%Z with (Z_of_nat k).
rewrite <- e.
reflexivity.
unfold Zminus in |- *.
rewrite Zopp_plus_distr.
rewrite Zplus_assoc.
rewrite Zplus_opp_r.
- rewrite Zopp_involutive.
+ rewrite Z.opp_involutive.
reflexivity.
apply Z_of_nat_complete_inf.
unfold Zminus in |- *.
@@ -2615,17 +2615,17 @@ Proof.
replace (p - Z_of_nat (S k))%Z with (p - k - 1)%Z.
apply H0.
apply Zplus_le_reg_l with (p := (- p)%Z).
- replace (- p + p)%Z with (- Z_of_nat 0)%Z.
+ replace (- p + p)%Z with (- Z_of_nat 0)%Z.
replace (- p + (p - Z_of_nat k))%Z with (- Z_of_nat k)%Z.
- apply Zge_le.
+ apply Z.ge_le.
apply Zge_opp.
apply Znat.inj_le.
apply le_O_n.
- ring.
+ ring.
ring_simplify; auto with arith.
assumption.
rewrite (Znat.inj_S k).
- unfold Zsucc in |- *.
+ unfold Z.succ in |- *.
ring.
intros.
cut (exists k : nat, (p - q)%Z = Z_of_nat k).
@@ -2634,9 +2634,9 @@ Proof.
intro k.
intros.
exists k.
- apply Zopp_inj.
+ apply Z.opp_inj.
apply Zplus_reg_l with (n := p).
- replace (p + - (p - Z_of_nat k))%Z with (Z_of_nat k).
+ replace (p + - (p - Z_of_nat k))%Z with (Z_of_nat k).
rewrite <- H3.
ring.
ring.
@@ -2654,44 +2654,44 @@ Proof.
intros P p WF_ind_step q Hq.
cut (forall x : Z, (p <= x)%Z -> forall y : Z, (p <= y < x)%Z -> P y).
intro.
- apply (H (Zsucc q)).
+ apply (H (Z.succ q)).
apply Zle_le_succ.
assumption.
-
+
split; [ assumption | exact (Zlt_succ q) ].
- intros x0 Hx0; generalize Hx0; pattern x0 in |- *.
+ intros x0 Hx0; generalize Hx0; pattern x0 in |- *.
apply Zrec with (p := p).
intros.
absurd (p <= p)%Z.
apply Zgt_not_le.
apply Zgt_le_trans with (m := y).
- apply Zlt_gt.
+ apply Z.lt_gt.
elim H.
intros.
assumption.
elim H.
intros.
assumption.
- apply Zle_refl.
+ apply Z.le_refl.
- intros.
- apply WF_ind_step.
+ intros.
+ apply WF_ind_step.
intros.
apply (H0 H).
- split.
+ split.
elim H2.
intros.
assumption.
- apply Zlt_le_trans with y.
+ apply Z.lt_le_trans with y.
elim H2.
intros.
assumption.
- apply Zgt_succ_le.
- apply Zlt_gt.
+ apply Zgt_succ_le.
+ apply Z.lt_gt.
elim H1.
intros.
- unfold Zsucc in |- *.
+ unfold Z.succ in |- *.
assumption.
assumption.
Qed.
@@ -2744,44 +2744,44 @@ Proof.
intros P p WF_ind_step q Hq.
cut (forall x : Z, (p <= x)%Z -> forall y : Z, (p <= y < x)%Z -> P y).
intro.
- apply (H (Zsucc q)).
+ apply (H (Z.succ q)).
apply Zle_le_succ.
assumption.
-
+
split; [ assumption | exact (Zlt_succ q) ].
- intros x0 Hx0; generalize Hx0; pattern x0 in |- *.
+ intros x0 Hx0; generalize Hx0; pattern x0 in |- *.
apply Zind with (p := p).
intros.
absurd (p <= p)%Z.
apply Zgt_not_le.
apply Zgt_le_trans with (m := y).
- apply Zlt_gt.
+ apply Z.lt_gt.
elim H.
intros.
assumption.
elim H.
intros.
assumption.
- apply Zle_refl.
+ apply Z.le_refl.
- intros.
- apply WF_ind_step.
+ intros.
+ apply WF_ind_step.
intros.
apply (H0 H).
- split.
+ split.
elim H2.
intros.
assumption.
- apply Zlt_le_trans with y.
+ apply Z.lt_le_trans with y.
elim H2.
intros.
assumption.
- apply Zgt_succ_le.
- apply Zlt_gt.
+ apply Zgt_succ_le.
+ apply Z.lt_gt.
elim H1.
intros.
- unfold Zsucc in |- *.
+ unfold Z.succ in |- *.
assumption.
assumption.
Qed.
@@ -2830,16 +2830,16 @@ Qed.
(** Properties of Zmax *)
(*###########################################################################*)
-Definition Zmax (n m : Z) := (n + m - Zmin n m)%Z.
+Definition Zmax (n m : Z) := (n + m - Z.min n m)%Z.
Lemma ZmaxSS : forall n m : Z, (Zmax n m + 1)%Z = Zmax (n + 1) (m + 1).
Proof.
intros.
unfold Zmax in |- *.
- replace (Zmin (n + 1) (m + 1)) with (Zmin n m + 1)%Z.
+ replace (Z.min (n + 1) (m + 1)) with (Z.min n m + 1)%Z.
ring.
symmetry in |- *.
- change (Zmin (Zsucc n) (Zsucc m) = Zsucc (Zmin n m)) in |- *.
+ change (Z.min (Z.succ n) (Z.succ m) = Z.succ (Z.min n m)) in |- *.
symmetry in |- *.
apply Zmin_SS.
Qed.
@@ -2848,29 +2848,29 @@ Lemma Zle_max_l : forall n m : Z, (n <= Zmax n m)%Z.
Proof.
intros.
unfold Zmax in |- *.
- apply Zplus_le_reg_l with (p := (- n + Zmin n m)%Z).
- ring_simplify (- n + Zmin n m + n)%Z.
- ring_simplify (- n + Zmin n m + (n + m - Zmin n m))%Z.
- apply Zle_min_r.
+ apply Zplus_le_reg_l with (p := (- n + Z.min n m)%Z).
+ ring_simplify (- n + Z.min n m + n)%Z.
+ ring_simplify (- n + Z.min n m + (n + m - Z.min n m))%Z.
+ apply Z.le_min_r.
Qed.
Lemma Zle_max_r : forall n m : Z, (m <= Zmax n m)%Z.
Proof.
intros.
unfold Zmax in |- *.
- apply Zplus_le_reg_l with (p := (- m + Zmin n m)%Z).
- ring_simplify (- m + Zmin n m + m)%Z.
- ring_simplify (- m + Zmin n m + (n + m - Zmin n m))%Z.
- apply Zle_min_l.
+ apply Zplus_le_reg_l with (p := (- m + Z.min n m)%Z).
+ ring_simplify (- m + Z.min n m + m)%Z.
+ ring_simplify (- m + Z.min n m + (n + m - Z.min n m))%Z.
+ apply Z.le_min_l.
Qed.
-Lemma Zmin_or_informative : forall n m : Z, {Zmin n m = n} + {Zmin n m = m}.
+Lemma Zmin_or_informative : forall n m : Z, {Z.min n m = n} + {Z.min n m = m}.
Proof.
intros.
case (Z_lt_ge_dec n m).
- unfold Zmin in |- *.
- unfold Zlt in |- *.
+ unfold Z.min in |- *.
+ unfold Z.lt in |- *.
intro z.
rewrite z.
left.
@@ -2880,8 +2880,8 @@ Proof.
intro.
case H.
intros z0.
- unfold Zmin in |- *.
- unfold Zgt in z0.
+ unfold Z.min in |- *.
+ unfold Z.gt in z0.
rewrite z0.
right.
reflexivity.
@@ -2894,14 +2894,14 @@ Proof.
elim H.
intro.
left.
- apply Zlt_gt.
+ apply Z.lt_gt.
assumption.
intro.
right.
symmetry in |- *.
assumption.
- apply Z_le_lt_eq_dec.
- apply Zge_le.
+ apply Z_le_lt_eq_dec.
+ apply Z.ge_le.
assumption.
Qed.
@@ -2925,8 +2925,8 @@ Proof.
assumption.
ring.
Qed.
-
-Lemma Zmax_or_informative : forall n m : Z, {Zmax n m = n} + {Zmax n m = m}.
+
+Lemma Zmax_or_informative : forall n m : Z, {Zmax n m = n} + {Zmax n m = m}.
Proof.
intros.
unfold Zmax in |- *.
@@ -2960,12 +2960,12 @@ Proof.
exact Zeven.Zeven_Sn.
Qed.
-Lemma Zeven_pred : forall x : Z, Zeven.Zodd x -> Zeven.Zeven (x - 1).
+Lemma Zeven_pred : forall x : Z, Zeven.Zodd x -> Zeven.Zeven (x - 1).
Proof.
exact Zeven.Zeven_pred.
Qed.
-(* This lemma used to be useful since it was mentioned with an unnecessary premise
+(* This lemma used to be useful since it was mentioned with an unnecessary premise
`x>=0` as Z_modulo_2 in ZArith, but the ZArith version has been fixed. *)
Definition Z_modulo_2_always :
@@ -2987,10 +2987,10 @@ Proof.
Qed.
Lemma Z_div_le :
- forall a b c : Z, (0 < c)%Z -> (b <= a)%Z -> (b / c <= a / c)%Z.
+ forall a b c : Z, (0 < c)%Z -> (b <= a)%Z -> (b / c <= a / c)%Z.
Proof.
intros.
- apply Zge_le.
+ apply Z.ge_le.
apply Z_div_ge; Flip; assumption.
Qed.
@@ -2998,7 +2998,7 @@ Lemma Z_div_nonneg :
forall a b : Z, (0 < b)%Z -> (0 <= a)%Z -> (0 <= a / b)%Z.
Proof.
intros.
- apply Zge_le.
+ apply Z.ge_le.
apply Z_div_ge0; Flip; assumption.
Qed.
@@ -3012,7 +3012,7 @@ Proof.
intro.
apply (Zlt_not_le (b * (a / b) + a mod b) 0 H0).
apply Zplus_le_0_compat.
- apply Zmult_le_0_compat.
+ apply Zmult_le_0_compat.
apply Zlt_le_weak; assumption.
Flip.
assumption.
diff --git a/test-suite/success/AdvancedTypeClasses.v b/test-suite/success/AdvancedTypeClasses.v
index b4efa7ed..d0aa5c85 100644
--- a/test-suite/success/AdvancedTypeClasses.v
+++ b/test-suite/success/AdvancedTypeClasses.v
@@ -28,8 +28,8 @@ Class interp_pair (abs : Type) :=
{ repr : term;
link: abs = interp repr }.
-Implicit Arguments repr [[interp_pair]].
-Implicit Arguments link [[interp_pair]].
+Arguments repr _ {interp_pair}.
+Arguments link _ {interp_pair}.
Lemma prod_interp `{interp_pair a, interp_pair b} : a * b = interp (Prod (repr a) (repr b)).
simpl. intros. rewrite <- link. rewrite <- (link b). reflexivity.
diff --git a/test-suite/success/BracketsWithGoalSelector.v b/test-suite/success/BracketsWithGoalSelector.v
index ed035f52..2f7425bc 100644
--- a/test-suite/success/BracketsWithGoalSelector.v
+++ b/test-suite/success/BracketsWithGoalSelector.v
@@ -14,3 +14,12 @@ Proof.
Fail Qed.
}
Qed.
+
+Lemma foo (n: nat) (P : nat -> Prop):
+ P n.
+Proof.
+ intros.
+ refine (nat_ind _ ?[Base] ?[Step] _).
+ [Base]: { admit. }
+ [Step]: { admit. }
+Abort.
diff --git a/test-suite/success/Case11.v b/test-suite/success/Case11.v
index 445ffac8..fbe909ec 100644
--- a/test-suite/success/Case11.v
+++ b/test-suite/success/Case11.v
@@ -5,9 +5,9 @@ Section A.
Variables (Alpha : Set) (Beta : Set).
-Definition nodep_prod_of_dep (c : sigS (fun a : Alpha => Beta)) :
+Definition nodep_prod_of_dep (c : sigT (fun a : Alpha => Beta)) :
Alpha * Beta := match c with
- | existS _ a b => (a, b)
+ | existT _ a b => (a, b)
end.
End A.
diff --git a/test-suite/success/Case17.v b/test-suite/success/Case17.v
index 861d0466..a4efcca9 100644
--- a/test-suite/success/Case17.v
+++ b/test-suite/success/Case17.v
@@ -1,5 +1,5 @@
(* Check the synthesis of predicate from a cast in case of matching of
- the first component (here [list bool]) of a dependent type (here [sigS])
+ the first component (here [list bool]) of a dependent type (here [sigT])
(Simplification of an example from file parsing2.v of the Coq'Art
exercises) *)
@@ -19,10 +19,10 @@ Axiom HHH : forall A : Prop, A.
Check
(match rec l0 (HHH _) with
- | inleft (existS _ (false :: l1) _) => inright _ (HHH _)
- | inleft (existS _ (true :: l1) (exist _ t1 (conj Hp Hl))) =>
+ | inleft (existT _ (false :: l1) _) => inright _ (HHH _)
+ | inleft (existT _ (true :: l1) (exist _ t1 (conj Hp Hl))) =>
inright _ (HHH _)
- | inleft (existS _ _ _) => inright _ (HHH _)
+ | inleft (existT _ _ _) => inright _ (HHH _)
| inright Hnp => inright _ (HHH _)
end
:{l'' : list bool &
@@ -39,10 +39,10 @@ Check
{t : nat | parse_rel l' l'' t /\ length l'' <= length l'}} +
{(forall (l'' : list bool) (t : nat), ~ parse_rel l' l'' t)}) =>
match rec l0 (HHH _) with
- | inleft (existS _ (false :: l1) _) => inright _ (HHH _)
- | inleft (existS _ (true :: l1) (exist _ t1 (conj Hp Hl))) =>
+ | inleft (existT _ (false :: l1) _) => inright _ (HHH _)
+ | inleft (existT _ (true :: l1) (exist _ t1 (conj Hp Hl))) =>
inright _ (HHH _)
- | inleft (existS _ _ _) => inright _ (HHH _)
+ | inleft (existT _ _ _) => inright _ (HHH _)
| inright Hnp => inright _ (HHH _)
end
:{l'' : list bool &
diff --git a/test-suite/success/Compat88.v b/test-suite/success/Compat88.v
new file mode 100644
index 00000000..e2045900
--- /dev/null
+++ b/test-suite/success/Compat88.v
@@ -0,0 +1,18 @@
+(* -*- coq-prog-args: ("-compat" "8.8") -*- *)
+(** Check that various syntax usage is available without importing
+ relevant files. *)
+Require Coq.Strings.Ascii Coq.Strings.String.
+Require Coq.ZArith.BinIntDef Coq.PArith.BinPosDef Coq.NArith.BinNatDef.
+Require Coq.Reals.Rdefinitions.
+Require Coq.Numbers.Cyclic.Int31.Cyclic31.
+
+Require Import Coq.Compat.Coq88. (* XXX FIXME Should not need [Require], see https://github.com/coq/coq/issues/8311 *)
+
+Check String.String "a" String.EmptyString.
+Check String.eqb "a" "a".
+Check Nat.eqb 1 1.
+Check BinNat.N.eqb 1 1.
+Check BinInt.Z.eqb 1 1.
+Check BinPos.Pos.eqb 1 1.
+Check Rdefinitions.Rplus 1 1.
+Check Int31.iszero 1.
diff --git a/test-suite/success/CompatCurrentFlag.v b/test-suite/success/CompatCurrentFlag.v
index 288c9d1d..5650dba2 100644
--- a/test-suite/success/CompatCurrentFlag.v
+++ b/test-suite/success/CompatCurrentFlag.v
@@ -1,3 +1,3 @@
-(* -*- coq-prog-args: ("-compat" "8.8") -*- *)
+(* -*- coq-prog-args: ("-compat" "8.9") -*- *)
(** Check that the current compatibility flag actually requires the relevant modules. *)
-Import Coq.Compat.Coq88.
+Import Coq.Compat.Coq89.
diff --git a/test-suite/success/CompatOldFlag.v b/test-suite/success/CompatOldFlag.v
index b7bbc505..37d50ee6 100644
--- a/test-suite/success/CompatOldFlag.v
+++ b/test-suite/success/CompatOldFlag.v
@@ -1,5 +1,5 @@
-(* -*- coq-prog-args: ("-compat" "8.6") -*- *)
+(* -*- coq-prog-args: ("-compat" "8.7") -*- *)
(** Check that the current-minus-two compatibility flag actually requires the relevant modules. *)
+Import Coq.Compat.Coq89.
Import Coq.Compat.Coq88.
Import Coq.Compat.Coq87.
-Import Coq.Compat.Coq86.
diff --git a/test-suite/success/CompatPreviousFlag.v b/test-suite/success/CompatPreviousFlag.v
index 9cfe6039..99813883 100644
--- a/test-suite/success/CompatPreviousFlag.v
+++ b/test-suite/success/CompatPreviousFlag.v
@@ -1,4 +1,4 @@
-(* -*- coq-prog-args: ("-compat" "8.7") -*- *)
+(* -*- coq-prog-args: ("-compat" "8.8") -*- *)
(** Check that the current-minus-one compatibility flag actually requires the relevant modules. *)
+Import Coq.Compat.Coq89.
Import Coq.Compat.Coq88.
-Import Coq.Compat.Coq87.
diff --git a/test-suite/success/FunindExtraction_compat86.v b/test-suite/success/FunindExtraction_compat86.v
deleted file mode 100644
index 8912197d..00000000
--- a/test-suite/success/FunindExtraction_compat86.v
+++ /dev/null
@@ -1,506 +0,0 @@
-(* -*- coq-prog-args: ("-compat" "8.6") -*- *)
-
-Definition iszero (n : nat) : bool :=
- match n with
- | O => true
- | _ => false
- end.
-
-Functional Scheme iszero_ind := Induction for iszero Sort Prop.
-
-Lemma toto : forall n : nat, n = 0 -> iszero n = true.
-intros x eg.
- functional induction iszero x; simpl.
-trivial.
-inversion eg.
-Qed.
-
-
-Function ftest (n m : nat) : nat :=
- match n with
- | O => match m with
- | O => 0
- | _ => 1
- end
- | S p => 0
- end.
-(* MS: FIXME: apparently can't define R_ftest_complete. Rest of the file goes through. *)
-
-Lemma test1 : forall n m : nat, ftest n m <= 2.
-intros n m.
- functional induction ftest n m; auto.
-Qed.
-
-Lemma test2 : forall m n, ~ 2 = ftest n m.
-Proof.
-intros n m;intro H.
-functional inversion H ftest.
-Qed.
-
-Lemma test3 : forall n m, ftest n m = 0 -> (n = 0 /\ m = 0) \/ n <> 0.
-Proof.
-functional inversion 1 ftest;auto.
-Qed.
-
-
-Require Import Arith.
-Lemma test11 : forall m : nat, ftest 0 m <= 2.
-intros m.
- functional induction ftest 0 m.
-auto.
-auto.
-auto with *.
-Qed.
-
-Function lamfix (m n : nat) {struct n } : nat :=
- match n with
- | O => m
- | S p => lamfix m p
- end.
-
-(* Parameter v1 v2 : nat. *)
-
-Lemma lamfix_lem : forall v1 v2 : nat, lamfix v1 v2 = v1.
-intros v1 v2.
- functional induction lamfix v1 v2.
-trivial.
-assumption.
-Defined.
-
-
-
-(* polymorphic function *)
-Require Import List.
-
-Functional Scheme app_ind := Induction for app Sort Prop.
-
-Lemma appnil : forall (A : Set) (l l' : list A), l' = nil -> l = l ++ l'.
-intros A l l'.
- functional induction app A l l'; intuition.
- rewrite <- H0; trivial.
-Qed.
-
-
-
-
-
-Require Export Arith.
-
-
-Function trivfun (n : nat) : nat :=
- match n with
- | O => 0
- | S m => trivfun m
- end.
-
-
-(* essaie de parametre variables non locaux:*)
-
-Parameter varessai : nat.
-
-Lemma first_try : trivfun varessai = 0.
- functional induction trivfun varessai.
-trivial.
-assumption.
-Defined.
-
-
- Functional Scheme triv_ind := Induction for trivfun Sort Prop.
-
-Lemma bisrepetita : forall n' : nat, trivfun n' = 0.
-intros n'.
- functional induction trivfun n'.
-trivial.
-assumption.
-Qed.
-
-
-
-
-
-
-
-Function iseven (n : nat) : bool :=
- match n with
- | O => true
- | S (S m) => iseven m
- | _ => false
- end.
-
-
-Function funex (n : nat) : nat :=
- match iseven n with
- | true => n
- | false => match n with
- | O => 0
- | S r => funex r
- end
- end.
-
-
-Function nat_equal_bool (n m : nat) {struct n} : bool :=
- match n with
- | O => match m with
- | O => true
- | _ => false
- end
- | S p => match m with
- | O => false
- | S q => nat_equal_bool p q
- end
- end.
-
-
-Require Export Div2.
-Require Import Nat.
-Functional Scheme div2_ind := Induction for div2 Sort Prop.
-Lemma div2_inf : forall n : nat, div2 n <= n.
-intros n.
- functional induction div2 n.
-auto.
-auto.
-
-apply le_S.
-apply le_n_S.
-exact IHn0.
-Qed.
-
-(* reuse this lemma as a scheme:*)
-
-Function nested_lam (n : nat) : nat -> nat :=
- match n with
- | O => fun m : nat => 0
- | S n' => fun m : nat => m + nested_lam n' m
- end.
-
-
-Lemma nest : forall n m : nat, nested_lam n m = n * m.
-intros n m.
- functional induction nested_lam n m; simpl;auto.
-Qed.
-
-
-Function essai (x : nat) (p : nat * nat) {struct x} : nat :=
- let (n, m) := (p: nat*nat) in
- match n with
- | O => 0
- | S q => match x with
- | O => 1
- | S r => S (essai r (q, m))
- end
- end.
-
-Lemma essai_essai :
- forall (x : nat) (p : nat * nat), let (n, m) := p in 0 < n -> 0 < essai x p.
-intros x p.
- functional induction essai x p; intros.
-inversion H.
-auto with arith.
- auto with arith.
-Qed.
-
-Function plus_x_not_five'' (n m : nat) {struct n} : nat :=
- let x := nat_equal_bool m 5 in
- let y := 0 in
- match n with
- | O => y
- | S q =>
- let recapp := plus_x_not_five'' q m in
- match x with
- | true => S recapp
- | false => S recapp
- end
- end.
-
-Lemma notplusfive'' : forall x y : nat, y = 5 -> plus_x_not_five'' x y = x.
-intros a b.
- functional induction plus_x_not_five'' a b; intros hyp; simpl; auto.
-Qed.
-
-Lemma iseq_eq : forall n m : nat, n = m -> nat_equal_bool n m = true.
-intros n m.
- functional induction nat_equal_bool n m; simpl; intros hyp; auto.
-rewrite <- hyp in y; simpl in y;tauto.
-inversion hyp.
-Qed.
-
-Lemma iseq_eq' : forall n m : nat, nat_equal_bool n m = true -> n = m.
-intros n m.
- functional induction nat_equal_bool n m; simpl; intros eg; auto.
-inversion eg.
-inversion eg.
-Qed.
-
-
-Inductive istrue : bool -> Prop :=
- istrue0 : istrue true.
-
-Functional Scheme add_ind := Induction for add Sort Prop.
-
-Lemma inf_x_plusxy' : forall x y : nat, x <= x + y.
-intros n m.
- functional induction add n m; intros.
-auto with arith.
-auto with arith.
-Qed.
-
-
-Lemma inf_x_plusxy'' : forall x : nat, x <= x + 0.
-intros n.
-unfold plus.
- functional induction plus n 0; intros.
-auto with arith.
-apply le_n_S.
-assumption.
-Qed.
-
-Lemma inf_x_plusxy''' : forall x : nat, x <= 0 + x.
-intros n.
- functional induction plus 0 n; intros; auto with arith.
-Qed.
-
-Function mod2 (n : nat) : nat :=
- match n with
- | O => 0
- | S (S m) => S (mod2 m)
- | _ => 0
- end.
-
-Lemma princ_mod2 : forall n : nat, mod2 n <= n.
-intros n.
- functional induction mod2 n; simpl; auto with arith.
-Qed.
-
-Function isfour (n : nat) : bool :=
- match n with
- | S (S (S (S O))) => true
- | _ => false
- end.
-
-Function isononeorfour (n : nat) : bool :=
- match n with
- | S O => true
- | S (S (S (S O))) => true
- | _ => false
- end.
-
-Lemma toto'' : forall n : nat, istrue (isfour n) -> istrue (isononeorfour n).
-intros n.
- functional induction isononeorfour n; intros istr; simpl;
- inversion istr.
-apply istrue0.
-destruct n. inversion istr.
-destruct n. tauto.
-destruct n. inversion istr.
-destruct n. inversion istr.
-destruct n. tauto.
-simpl in *. inversion H0.
-Qed.
-
-Lemma toto' : forall n m : nat, n = 4 -> istrue (isononeorfour n).
-intros n.
- functional induction isononeorfour n; intros m istr; inversion istr.
-apply istrue0.
-rewrite H in y; simpl in y;tauto.
-Qed.
-
-Function ftest4 (n m : nat) : nat :=
- match n with
- | O => match m with
- | O => 0
- | S q => 1
- end
- | S p => match m with
- | O => 0
- | S r => 1
- end
- end.
-
-Lemma test4 : forall n m : nat, ftest n m <= 2.
-intros n m.
- functional induction ftest n m; auto with arith.
-Qed.
-
-Lemma test4' : forall n m : nat, ftest4 (S n) m <= 2.
-intros n m.
-assert ({n0 | n0 = S n}).
-exists (S n);reflexivity.
-destruct H as [n0 H1].
-rewrite <- H1;revert H1.
- functional induction ftest4 n0 m.
-inversion 1.
-inversion 1.
-
-auto with arith.
-auto with arith.
-Qed.
-
-Function ftest44 (x : nat * nat) (n m : nat) : nat :=
- let (p, q) := (x: nat*nat) in
- match n with
- | O => match m with
- | O => 0
- | S q => 1
- end
- | S p => match m with
- | O => 0
- | S r => 1
- end
- end.
-
-Lemma test44 :
- forall (pq : nat * nat) (n m o r s : nat), ftest44 pq n (S m) <= 2.
-intros pq n m o r s.
- functional induction ftest44 pq n (S m).
-auto with arith.
-auto with arith.
-auto with arith.
-auto with arith.
-Qed.
-
-Function ftest2 (n m : nat) {struct n} : nat :=
- match n with
- | O => match m with
- | O => 0
- | S q => 0
- end
- | S p => ftest2 p m
- end.
-
-Lemma test2' : forall n m : nat, ftest2 n m <= 2.
-intros n m.
- functional induction ftest2 n m; simpl; intros; auto.
-Qed.
-
-Function ftest3 (n m : nat) {struct n} : nat :=
- match n with
- | O => 0
- | S p => match m with
- | O => ftest3 p 0
- | S r => 0
- end
- end.
-
-Lemma test3' : forall n m : nat, ftest3 n m <= 2.
-intros n m.
- functional induction ftest3 n m.
-intros.
-auto.
-intros.
-auto.
-intros.
-simpl.
-auto.
-Qed.
-
-Function ftest5 (n m : nat) {struct n} : nat :=
- match n with
- | O => 0
- | S p => match m with
- | O => ftest5 p 0
- | S r => ftest5 p r
- end
- end.
-
-Lemma test5 : forall n m : nat, ftest5 n m <= 2.
-intros n m.
- functional induction ftest5 n m.
-intros.
-auto.
-intros.
-auto.
-intros.
-simpl.
-auto.
-Qed.
-
-Function ftest7 (n : nat) : nat :=
- match ftest5 n 0 with
- | O => 0
- | S r => 0
- end.
-
-Lemma essai7 :
- forall (Hrec : forall n : nat, ftest5 n 0 = 0 -> ftest7 n <= 2)
- (Hrec0 : forall n r : nat, ftest5 n 0 = S r -> ftest7 n <= 2)
- (n : nat), ftest7 n <= 2.
-intros hyp1 hyp2 n.
- functional induction ftest7 n; auto.
-Qed.
-
-Function ftest6 (n m : nat) {struct n} : nat :=
- match n with
- | O => 0
- | S p => match ftest5 p 0 with
- | O => ftest6 p 0
- | S r => ftest6 p r
- end
- end.
-
-
-Lemma princ6 :
- (forall n m : nat, n = 0 -> ftest6 0 m <= 2) ->
- (forall n m p : nat,
- ftest6 p 0 <= 2 -> ftest5 p 0 = 0 -> n = S p -> ftest6 (S p) m <= 2) ->
- (forall n m p r : nat,
- ftest6 p r <= 2 -> ftest5 p 0 = S r -> n = S p -> ftest6 (S p) m <= 2) ->
- forall x y : nat, ftest6 x y <= 2.
-intros hyp1 hyp2 hyp3 n m.
-generalize hyp1 hyp2 hyp3.
-clear hyp1 hyp2 hyp3.
- functional induction ftest6 n m; auto.
-Qed.
-
-Lemma essai6 : forall n m : nat, ftest6 n m <= 2.
-intros n m.
- functional induction ftest6 n m; simpl; auto.
-Qed.
-
-(* Some tests with modules *)
-Module M.
-Function test_m (n:nat) : nat :=
- match n with
- | 0 => 0
- | S n => S (S (test_m n))
- end.
-
-Lemma test_m_is_double : forall n, div2 (test_m n) = n.
-Proof.
-intros n.
-functional induction (test_m n).
-reflexivity.
-simpl;rewrite IHn0;reflexivity.
-Qed.
-End M.
-(* We redefine a new Function with the same name *)
-Function test_m (n:nat) : nat :=
- pred n.
-
-Lemma test_m_is_pred : forall n, test_m n = pred n.
-Proof.
-intro n.
-functional induction (test_m n). (* the test_m_ind to use is the last defined saying that test_m = pred*)
-reflexivity.
-Qed.
-
-(* Checks if the dot notation are correctly treated in infos *)
-Lemma M_test_m_is_double : forall n, div2 (M.test_m n) = n.
-intro n.
-(* here we should apply M.test_m_ind *)
-functional induction (M.test_m n).
-reflexivity.
-simpl;rewrite IHn0;reflexivity.
-Qed.
-
-Import M.
-(* Now test_m is the one which defines double *)
-
-Lemma test_m_is_double : forall n, div2 (M.test_m n) = n.
-intro n.
-(* here we should apply M.test_m_ind *)
-functional induction (test_m n).
-reflexivity.
-simpl;rewrite IHn0;reflexivity.
-Qed.
-
-Extraction iszero.
diff --git a/test-suite/success/Hints.v b/test-suite/success/Hints.v
index 8d08f597..2f13b7c2 100644
--- a/test-suite/success/Hints.v
+++ b/test-suite/success/Hints.v
@@ -183,3 +183,33 @@ End HintCut.
Goal forall (m : nat), exists n, m = n /\ m = n.
intros m; eexists; split; [trivial | reflexivity].
Qed.
+
+Section HintTransparent.
+
+ Definition fn (x : nat) := S x.
+
+ Create HintDb trans.
+
+ Hint Resolve eq_refl | (_ = _) : trans.
+
+ (* No reduction *)
+ Hint Variables Opaque : trans. Hint Constants Opaque : trans.
+
+ Goal forall x : nat, fn x = S x.
+ Proof.
+ intros.
+ Fail typeclasses eauto with trans.
+ unfold fn.
+ typeclasses eauto with trans.
+ Qed.
+
+ (** Now allow unfolding fn *)
+ Hint Constants Transparent : trans.
+
+ Goal forall x : nat, fn x = S x.
+ Proof.
+ intros.
+ typeclasses eauto with trans.
+ Qed.
+
+End HintTransparent.
diff --git a/test-suite/success/ImplicitArguments.v b/test-suite/success/ImplicitArguments.v
index 921433ca..9a19b595 100644
--- a/test-suite/success/ImplicitArguments.v
+++ b/test-suite/success/ImplicitArguments.v
@@ -2,7 +2,7 @@ Inductive vector {A : Type} : nat -> Type :=
| vnil : vector 0
| vcons : A -> forall {n'}, vector n' -> vector (S n').
-Implicit Arguments vector [].
+Arguments vector A : clear implicits.
Require Import Coq.Program.Program.
diff --git a/test-suite/success/ImplicitTactic.v b/test-suite/success/ImplicitTactic.v
deleted file mode 100644
index d8fa3043..00000000
--- a/test-suite/success/ImplicitTactic.v
+++ /dev/null
@@ -1,16 +0,0 @@
-(* A Wiedijk-Cruz-Filipe style tactic for solving implicit arguments *)
-
-(* Declare a term expression with a hole *)
-Parameter quo : nat -> forall n:nat, n<>0 -> nat.
-Notation "x / y" := (quo x y _) : nat_scope.
-
-(* Declare the tactic for resolving implicit arguments still
- unresolved after type-checking; it must complete the subgoal to
- succeed *)
-Declare Implicit Tactic assumption.
-
-Goal forall n d, d<>0 -> { q:nat & { r:nat | d * q + r = n }}.
-intros.
-(* Here, assumption is used to solve the implicit argument of quo *)
-exists (n / d).
-
diff --git a/test-suite/success/Inductive.v b/test-suite/success/Inductive.v
index 5b1482fd..c2130995 100644
--- a/test-suite/success/Inductive.v
+++ b/test-suite/success/Inductive.v
@@ -1,7 +1,5 @@
(* Test des definitions inductives imbriquees *)
-Require Import List.
-
Inductive X : Set :=
cons1 : list X -> X.
@@ -73,7 +71,7 @@ CoInductive LList (A : Set) : Set :=
| LNil : LList A
| LCons : A -> LList A -> LList A.
-Implicit Arguments LNil [A].
+Arguments LNil [A].
Inductive Finite (A : Set) : LList A -> Prop :=
| Finite_LNil : Finite LNil
diff --git a/test-suite/success/Injection.v b/test-suite/success/Injection.v
index 78652fb6..7ee471ba 100644
--- a/test-suite/success/Injection.v
+++ b/test-suite/success/Injection.v
@@ -19,8 +19,8 @@ Qed.
(* Check that no tuple needs to be built *)
Lemma l3 :
forall x y : nat,
- existS (fun n : nat => {n = n} + {n = n}) x (left _ (refl_equal x)) =
- existS (fun n : nat => {n = n} + {n = n}) y (left _ (refl_equal y)) ->
+ existT (fun n : nat => {n = n} + {n = n}) x (left _ (refl_equal x)) =
+ existT (fun n : nat => {n = n} + {n = n}) y (left _ (refl_equal y)) ->
x = y.
intros x y H.
injection H.
@@ -30,10 +30,10 @@ Qed.
(* Check that a tuple is built (actually the same as the initial one) *)
Lemma l4 :
forall p1 p2 : {0 = 0} + {0 = 0},
- existS (fun n : nat => {n = n} + {n = n}) 0 p1 =
- existS (fun n : nat => {n = n} + {n = n}) 0 p2 ->
- existS (fun n : nat => {n = n} + {n = n}) 0 p1 =
- existS (fun n : nat => {n = n} + {n = n}) 0 p2.
+ existT (fun n : nat => {n = n} + {n = n}) 0 p1 =
+ existT (fun n : nat => {n = n} + {n = n}) 0 p2 ->
+ existT (fun n : nat => {n = n} + {n = n}) 0 p1 =
+ existT (fun n : nat => {n = n} + {n = n}) 0 p2.
intros.
injection H.
exact (fun H => H).
diff --git a/test-suite/success/Inversion.v b/test-suite/success/Inversion.v
index 45c71615..ee540d71 100644
--- a/test-suite/success/Inversion.v
+++ b/test-suite/success/Inversion.v
@@ -31,7 +31,7 @@ Inductive in_extension (I : Set) (r : rule I) : extension I -> Type :=
| in_first : forall e, in_extension r (add_rule r e)
| in_rest : forall e r', in_extension r e -> in_extension r (add_rule r' e).
-Implicit Arguments NL [I].
+Arguments NL [I].
Inductive super_extension (I : Set) (e : extension I) :
extension I -> Type :=
@@ -107,6 +107,7 @@ Goal forall o, foo2 o -> 0 = 1.
intros.
eapply trans_eq.
inversion H.
+Abort.
(* Check that the part of "injection" that is called by "inversion"
does the same number of intros as the number of equations
@@ -136,6 +137,7 @@ Goal True -> True.
intro.
Fail inversion H using False.
Fail inversion foo using True_ind.
+Abort.
(* Was failing at some time between 7 and 10 September 2014 *)
(* even though, it is not clear that the resulting context is interesting *)
diff --git a/test-suite/success/Fourier.v b/test-suite/success/LraTest.v
index b63bead4..bf3a87da 100644
--- a/test-suite/success/Fourier.v
+++ b/test-suite/success/LraTest.v
@@ -1,12 +1,14 @@
-Require Import Rfunctions.
-Require Import Fourier.
+Require Import Reals.
+Require Import Lra.
+
+Open Scope R_scope.
Lemma l1 : forall x y z : R, Rabs (x - z) <= Rabs (x - y) + Rabs (y - z).
-intros; split_Rabs; fourier.
+intros; split_Rabs; lra.
Qed.
Lemma l2 :
forall x y : R, x < Rabs y -> y < 1 -> x >= 0 -> - y <= 1 -> Rabs x <= 1.
intros.
-split_Rabs; fourier.
+split_Rabs; lra.
Qed.
diff --git a/test-suite/success/LtacDeprecation.v b/test-suite/success/LtacDeprecation.v
new file mode 100644
index 00000000..633a5e47
--- /dev/null
+++ b/test-suite/success/LtacDeprecation.v
@@ -0,0 +1,32 @@
+Set Warnings "+deprecated".
+
+#[deprecated(since = "8.8", note = "Use idtac instead")]
+Ltac foo x := idtac.
+
+Goal True.
+Fail (foo true).
+Abort.
+
+Fail Ltac bar := foo.
+Fail Tactic Notation "bar" := foo.
+
+#[deprecated(since = "8.8", note = "Use idtac instead")]
+Tactic Notation "bar" := idtac.
+
+Goal True.
+Fail bar.
+Abort.
+
+Fail Ltac zar := bar.
+
+Set Warnings "-deprecated".
+
+Ltac zar := foo.
+Ltac zarzar := bar.
+
+Set Warnings "+deprecated".
+
+Goal True.
+zar x.
+zarzar.
+Abort.
diff --git a/test-suite/success/Notations2.v b/test-suite/success/Notations2.v
index 7c2cf3ee..1b33863e 100644
--- a/test-suite/success/Notations2.v
+++ b/test-suite/success/Notations2.v
@@ -126,3 +126,31 @@ Notation "'myexists' x , p" := (ex (fun x => p))
(at level 200, x ident, p at level 200, right associativity) : type_scope.
Check myexists I, I = 0. (* Should not be seen as a constructor *)
End M14.
+
+(* 15. Testing different ways to give the same levels without failing *)
+
+Module M15.
+ Local Notation "###### x" := (S x) (right associativity, at level 79, x at next level).
+ Fail Local Notation "###### x" := (S x) (right associativity, at level 79).
+ Local Notation "###### x" := (S x) (at level 79).
+End M15.
+
+(* 16. Some test about custom entries *)
+Module M16.
+ (* Test locality *)
+ Local Declare Custom Entry foo.
+ Fail Notation "#" := 0 (in custom foo). (* Should be local *)
+ Local Notation "#" := 0 (in custom foo).
+
+ (* Test import *)
+ Module A.
+ Declare Custom Entry foo2.
+ End A.
+ Fail Notation "##" := 0 (in custom foo2).
+ Import A.
+ Local Notation "##" := 0 (in custom foo2).
+
+ (* Test Print Grammar *)
+ Print Grammar foo.
+ Print Grammar foo2.
+End M16.
diff --git a/test-suite/success/NumeralNotations.v b/test-suite/success/NumeralNotations.v
new file mode 100644
index 00000000..47ef3812
--- /dev/null
+++ b/test-suite/success/NumeralNotations.v
@@ -0,0 +1,302 @@
+(* Test that we fail, rather than raising anomalies, on opaque terms during interpretation *)
+
+(* https://github.com/coq/coq/pull/8064#discussion_r202497516 *)
+Module Test1.
+ Axiom hold : forall {A B C}, A -> B -> C.
+ Definition opaque3 (x : Decimal.int) : Decimal.int := hold x (fix f (x : nat) : nat := match x with O => O | S n => S (f n) end).
+ Numeral Notation Decimal.int opaque3 opaque3 : opaque_scope.
+ Delimit Scope opaque_scope with opaque.
+ Fail Check 1%opaque.
+End Test1.
+
+(* https://github.com/coq/coq/pull/8064#discussion_r202497990 *)
+Module Test2.
+ Axiom opaque4 : option Decimal.int.
+ Definition opaque6 (x : Decimal.int) : option Decimal.int := opaque4.
+ Numeral Notation Decimal.int opaque6 opaque6 : opaque_scope.
+ Delimit Scope opaque_scope with opaque.
+ Open Scope opaque_scope.
+ Fail Check 1%opaque.
+End Test2.
+
+Module Test3.
+ Inductive silly := SILLY (v : Decimal.uint) (f : forall A, A -> A).
+ Definition to_silly (v : Decimal.uint) := SILLY v (fun _ x => x).
+ Definition of_silly (v : silly) := match v with SILLY v _ => v end.
+ Numeral Notation silly to_silly of_silly : silly_scope.
+ Delimit Scope silly_scope with silly.
+ Fail Check 1%silly.
+End Test3.
+
+
+Module Test4.
+ Polymorphic NonCumulative Inductive punit := ptt.
+ Polymorphic Definition pto_punit (v : Decimal.uint) : option punit := match Nat.of_uint v with O => Some ptt | _ => None end.
+ Polymorphic Definition pto_punit_all (v : Decimal.uint) : punit := ptt.
+ Polymorphic Definition pof_punit (v : punit) : Decimal.uint := Nat.to_uint 0.
+ Definition to_punit (v : Decimal.uint) : option punit := match Nat.of_uint v with O => Some ptt | _ => None end.
+ Definition of_punit (v : punit) : Decimal.uint := Nat.to_uint 0.
+ Polymorphic Definition pto_unit (v : Decimal.uint) : option unit := match Nat.of_uint v with O => Some tt | _ => None end.
+ Polymorphic Definition pof_unit (v : unit) : Decimal.uint := Nat.to_uint 0.
+ Definition to_unit (v : Decimal.uint) : option unit := match Nat.of_uint v with O => Some tt | _ => None end.
+ Definition of_unit (v : unit) : Decimal.uint := Nat.to_uint 0.
+ Numeral Notation punit to_punit of_punit : pto.
+ Numeral Notation punit pto_punit of_punit : ppo.
+ Numeral Notation punit to_punit pof_punit : ptp.
+ Numeral Notation punit pto_punit pof_punit : ppp.
+ Numeral Notation unit to_unit of_unit : uto.
+ Delimit Scope pto with pto.
+ Delimit Scope ppo with ppo.
+ Delimit Scope ptp with ptp.
+ Delimit Scope ppp with ppp.
+ Delimit Scope uto with uto.
+ Check let v := 0%pto in v : punit.
+ Check let v := 0%ppo in v : punit.
+ Check let v := 0%ptp in v : punit.
+ Check let v := 0%ppp in v : punit.
+ Check let v := 0%uto in v : unit.
+ Fail Check 1%uto.
+ Fail Check (-1)%uto.
+ Numeral Notation unit pto_unit of_unit : upo.
+ Numeral Notation unit to_unit pof_unit : utp.
+ Numeral Notation unit pto_unit pof_unit : upp.
+ Delimit Scope upo with upo.
+ Delimit Scope utp with utp.
+ Delimit Scope upp with upp.
+ Check let v := 0%upo in v : unit.
+ Check let v := 0%utp in v : unit.
+ Check let v := 0%upp in v : unit.
+
+ Polymorphic Definition pto_punits := pto_punit_all@{Set}.
+ Polymorphic Definition pof_punits := pof_punit@{Set}.
+ Numeral Notation punit pto_punits pof_punits : ppps (abstract after 1).
+ Delimit Scope ppps with ppps.
+ Universe u.
+ Constraint Set < u.
+ Check let v := 0%ppps in v : punit@{u}. (* Check that universes are refreshed *)
+ Fail Check let v := 1%ppps in v : punit@{u}. (* Note that universes are not refreshed here *)
+End Test4.
+
+Module Test5.
+ Check S. (* At one point gave Error: Anomaly "Uncaught exception Pretype_errors.PretypeError(_, _, _)." Please report at http://coq.inria.fr/bugs/. *)
+End Test5.
+
+Module Test6.
+ (* Check that numeral notations on enormous terms don't take forever to print/parse *)
+ (* Ackerman definition from https://stackoverflow.com/a/10303475/377022 *)
+ Fixpoint ack (n m : nat) : nat :=
+ match n with
+ | O => S m
+ | S p => let fix ackn (m : nat) :=
+ match m with
+ | O => ack p 1
+ | S q => ack p (ackn q)
+ end
+ in ackn m
+ end.
+
+ Timeout 1 Check (S (ack 4 4)). (* should be instantaneous *)
+
+ Local Set Primitive Projections.
+ Record > wnat := wrap { unwrap :> nat }.
+ Definition to_uint (x : wnat) : Decimal.uint := Nat.to_uint x.
+ Definition of_uint (x : Decimal.uint) : wnat := Nat.of_uint x.
+ Module Export Scopes.
+ Delimit Scope wnat_scope with wnat.
+ End Scopes.
+ Module Export Notations.
+ Export Scopes.
+ Numeral Notation wnat of_uint to_uint : wnat_scope (abstract after 5000).
+ End Notations.
+ Check let v := 0%wnat in v : wnat.
+ Check wrap O.
+ Timeout 1 Check wrap (ack 4 4). (* should be instantaneous *)
+End Test6.
+
+Module Test6_2.
+ Import Test6.Scopes.
+ Check Test6.wrap 0.
+ Import Test6.Notations.
+ Check let v := 0%wnat in v : Test6.wnat.
+End Test6_2.
+
+Module Test7.
+ Local Set Primitive Projections.
+ Record wuint := wrap { unwrap : Decimal.uint }.
+ Delimit Scope wuint_scope with wuint.
+ Numeral Notation wuint wrap unwrap : wuint_scope.
+ Check let v := 0%wuint in v : wuint.
+ Check let v := 1%wuint in v : wuint.
+End Test7.
+
+Module Test8.
+ Local Set Primitive Projections.
+ Record wuint := wrap { unwrap : Decimal.uint }.
+ Delimit Scope wuint8_scope with wuint8.
+ Delimit Scope wuint8'_scope with wuint8'.
+ Section with_var.
+ Context (dummy : unit).
+ Definition wrap' := let __ := dummy in wrap.
+ Definition unwrap' := let __ := dummy in unwrap.
+ Numeral Notation wuint wrap' unwrap' : wuint8_scope.
+ Check let v := 0%wuint8 in v : wuint.
+ End with_var.
+ Check let v := 0%wuint8 in v : nat.
+ Fail Check let v := 0%wuint8 in v : wuint.
+ Compute wrap (Nat.to_uint 0).
+
+ Notation wrap'' := wrap.
+ Notation unwrap'' := unwrap.
+ Numeral Notation wuint wrap'' unwrap'' : wuint8'_scope.
+ Check let v := 0%wuint8' in v : wuint.
+End Test8.
+
+Module Test9.
+ Delimit Scope wuint9_scope with wuint9.
+ Delimit Scope wuint9'_scope with wuint9'.
+ Section with_let.
+ Local Set Primitive Projections.
+ Record wuint := wrap { unwrap : Decimal.uint }.
+ Let wrap' := wrap.
+ Let unwrap' := unwrap.
+ Local Notation wrap'' := wrap.
+ Local Notation unwrap'' := unwrap.
+ Numeral Notation wuint wrap' unwrap' : wuint9_scope.
+ Check let v := 0%wuint9 in v : wuint.
+ Numeral Notation wuint wrap'' unwrap'' : wuint9'_scope.
+ Check let v := 0%wuint9' in v : wuint.
+ End with_let.
+ Check let v := 0%wuint9 in v : nat.
+ Fail Check let v := 0%wuint9 in v : wuint.
+End Test9.
+
+Module Test10.
+ (* Test that it is only a warning to add abstract after to an optional parsing function *)
+ Definition to_uint (v : unit) := Nat.to_uint 0.
+ Definition of_uint (v : Decimal.uint) := match Nat.of_uint v with O => Some tt | _ => None end.
+ Definition of_any_uint (v : Decimal.uint) := tt.
+ Delimit Scope unit_scope with unit.
+ Delimit Scope unit2_scope with unit2.
+ Numeral Notation unit of_uint to_uint : unit_scope (abstract after 1).
+ Local Set Warnings Append "+abstract-large-number-no-op".
+ (* Check that there is actually a warning here *)
+ Fail Numeral Notation unit of_uint to_uint : unit2_scope (abstract after 1).
+ (* Check that there is no warning here *)
+ Numeral Notation unit of_any_uint to_uint : unit2_scope (abstract after 1).
+End Test10.
+
+Module Test11.
+ (* Test that numeral notations don't work on proof-local variables, especially not ones containing evars *)
+ Inductive unit11 := tt11.
+ Delimit Scope unit11_scope with unit11.
+ Goal True.
+ evar (to_uint : unit11 -> Decimal.uint).
+ evar (of_uint : Decimal.uint -> unit11).
+ Fail Numeral Notation unit11 of_uint to_uint : uint11_scope.
+ exact I.
+ Unshelve.
+ all: solve [ constructor ].
+ Qed.
+End Test11.
+
+Module Test12.
+ (* Test for numeral notations on context variables *)
+ Delimit Scope test12_scope with test12.
+ Section test12.
+ Context (to_uint : unit -> Decimal.uint) (of_uint : Decimal.uint -> unit).
+
+ Numeral Notation unit of_uint to_uint : test12_scope.
+ Check let v := 1%test12 in v : unit.
+ End test12.
+End Test12.
+
+Module Test13.
+ (* Test for numeral notations on notations which do not denote references *)
+ Delimit Scope test13_scope with test13.
+ Delimit Scope test13'_scope with test13'.
+ Delimit Scope test13''_scope with test13''.
+ Definition to_uint (x y : unit) : Decimal.uint := Nat.to_uint O.
+ Definition of_uint (x : Decimal.uint) : unit := tt.
+ Definition to_uint_good := to_uint tt.
+ Notation to_uint' := (to_uint tt).
+ Notation to_uint'' := (to_uint _).
+ Numeral Notation unit of_uint to_uint_good : test13_scope.
+ Check let v := 0%test13 in v : unit.
+ Fail Numeral Notation unit of_uint to_uint' : test13'_scope.
+ Fail Check let v := 0%test13' in v : unit.
+ Fail Numeral Notation unit of_uint to_uint'' : test13''_scope.
+ Fail Check let v := 0%test13'' in v : unit.
+End Test13.
+
+Module Test14.
+ (* Test that numeral notations follow [Import], not [Require], and
+ also test that [Local Numeral Notation]s do not escape modules
+ nor sections. *)
+ Delimit Scope test14_scope with test14.
+ Delimit Scope test14'_scope with test14'.
+ Delimit Scope test14''_scope with test14''.
+ Delimit Scope test14'''_scope with test14'''.
+ Module Inner.
+ Definition to_uint (x : unit) : Decimal.uint := Nat.to_uint O.
+ Definition of_uint (x : Decimal.uint) : unit := tt.
+ Local Numeral Notation unit of_uint to_uint : test14_scope.
+ Global Numeral Notation unit of_uint to_uint : test14'_scope.
+ Check let v := 0%test14 in v : unit.
+ Check let v := 0%test14' in v : unit.
+ End Inner.
+ Fail Check let v := 0%test14 in v : unit.
+ Fail Check let v := 0%test14' in v : unit.
+ Import Inner.
+ Fail Check let v := 0%test14 in v : unit.
+ Check let v := 0%test14' in v : unit.
+ Section InnerSection.
+ Definition to_uint (x : unit) : Decimal.uint := Nat.to_uint O.
+ Definition of_uint (x : Decimal.uint) : unit := tt.
+ Local Numeral Notation unit of_uint to_uint : test14''_scope.
+ Fail Global Numeral Notation unit of_uint to_uint : test14'''_scope.
+ Check let v := 0%test14'' in v : unit.
+ Fail Check let v := 0%test14''' in v : unit.
+ End InnerSection.
+ Fail Check let v := 0%test14'' in v : unit.
+ Fail Check let v := 0%test14''' in v : unit.
+End Test14.
+
+Module Test15.
+ (** Test module include *)
+ Delimit Scope test15_scope with test15.
+ Module Inner.
+ Definition to_uint (x : unit) : Decimal.uint := Nat.to_uint O.
+ Definition of_uint (x : Decimal.uint) : unit := tt.
+ Numeral Notation unit of_uint to_uint : test15_scope.
+ Check let v := 0%test15 in v : unit.
+ End Inner.
+ Module Inner2.
+ Include Inner.
+ Check let v := 0%test15 in v : unit.
+ End Inner2.
+ Import Inner Inner2.
+ Check let v := 0%test15 in v : unit.
+End Test15.
+
+Module Test16.
+ (** Test functors *)
+ Delimit Scope test16_scope with test16.
+ Module Type A.
+ Axiom T : Set.
+ Axiom t : T.
+ End A.
+ Module F (a : A).
+ Inductive Foo := foo (_ : a.T).
+ Definition to_uint (x : Foo) : Decimal.uint := Nat.to_uint O.
+ Definition of_uint (x : Decimal.uint) : Foo := foo a.t.
+ Global Numeral Notation Foo of_uint to_uint : test16_scope.
+ Check let v := 0%test16 in v : Foo.
+ End F.
+ Module a <: A.
+ Definition T : Set := unit.
+ Definition t : T := tt.
+ End a.
+ Module Import f := F a.
+ (** Ideally this should work, but it should definitely not anomaly *)
+ Fail Check let v := 0%test16 in v : Foo.
+End Test16.
diff --git a/test-suite/success/ROmega4.v b/test-suite/success/ROmega4.v
index 58ae5b8f..a7245927 100644
--- a/test-suite/success/ROmega4.v
+++ b/test-suite/success/ROmega4.v
@@ -3,12 +3,12 @@
See also #148 for the corresponding improvement in Omega.
*)
-Require Import ZArith ROmega.
+Require Import ZArith Lia.
Open Scope Z.
Goal let x := 3 in x = 3.
intros.
-romega.
+lia.
Qed.
(** Example seen in #4132
@@ -22,5 +22,5 @@ Lemma foo
(H : - zxy' <= zxy)
(H' : zxy' <= x') : - b <= zxy.
Proof.
-romega.
+lia.
Qed.
diff --git a/test-suite/success/RecTutorial.v b/test-suite/success/RecTutorial.v
index 84194049..6370cab6 100644
--- a/test-suite/success/RecTutorial.v
+++ b/test-suite/success/RecTutorial.v
@@ -589,6 +589,8 @@ Close Scope Z_scope.
Theorem S_is_not_O : forall n, S n <> 0.
+Set Nested Proofs Allowed.
+
Definition Is_zero (x:nat):= match x with
| 0 => True
| _ => False
@@ -991,10 +993,10 @@ Proof.
Qed.
-Implicit Arguments Vector.cons [A n].
-Implicit Arguments Vector.nil [A].
-Implicit Arguments Vector.hd [A n].
-Implicit Arguments Vector.tl [A n].
+Arguments Vector.cons [A] _ [n].
+Arguments Vector.nil [A].
+Arguments Vector.hd [A n].
+Arguments Vector.tl [A n].
Definition Vid : forall (A : Type)(n:nat), Vector.t A n -> Vector.t A n.
Proof.
@@ -1064,7 +1066,7 @@ Fixpoint vector_nth (A:Set)(n:nat)(p:nat)(v:Vector.t A p){struct v}
| S n', Vector.cons _ v' => vector_nth A n' _ v'
end.
-Implicit Arguments vector_nth [A p].
+Arguments vector_nth [A] _ [p].
Lemma nth_bitwise : forall (n:nat) (v1 v2: Vector.t bool n) i a b,
@@ -1159,7 +1161,7 @@ infiniteproof map_iterate'.
Qed.
-Implicit Arguments LNil [A].
+Arguments LNil [A].
Lemma Lnil_not_Lcons : forall (A:Set)(a:A)(l:LList A),
LNil <> (LCons a l).
diff --git a/test-suite/success/Record.v b/test-suite/success/Record.v
index 6f27c1d3..18ebcd63 100644
--- a/test-suite/success/Record.v
+++ b/test-suite/success/Record.v
@@ -5,7 +5,7 @@ Require Import Program.
Require Import List.
Record vector {A : Type} {n : nat} := { vec_list : list A ; vec_len : length vec_list = n }.
-Implicit Arguments vector [].
+Arguments vector : clear implicits.
Coercion vec_list : vector >-> list.
diff --git a/test-suite/success/Scopes.v b/test-suite/success/Scopes.v
index ca374671..2da63063 100644
--- a/test-suite/success/Scopes.v
+++ b/test-suite/success/Scopes.v
@@ -11,7 +11,7 @@ Check (A.opp 3).
Record B := { f :> Z -> Z }.
Variable a:B.
-Arguments Scope a [Z_scope].
+Arguments a _%Z_scope : extra scopes.
Check a 0.
(* Check that casts activate scopes if ever possible *)
diff --git a/test-suite/success/Typeclasses.v b/test-suite/success/Typeclasses.v
index cd6eac35..400479ae 100644
--- a/test-suite/success/Typeclasses.v
+++ b/test-suite/success/Typeclasses.v
@@ -128,8 +128,8 @@ Record Monad {m : Type -> Type} := {
Print Visibility.
Print unit.
-Implicit Arguments unit [[m] [m0] [α]].
-Implicit Arguments Monad [].
+Arguments unit {m m0 α}.
+Arguments Monad : clear implicits.
Notation "'return' t" := (unit t).
(* Test correct handling of existentials and defined fields. *)
diff --git a/test-suite/success/apply.v b/test-suite/success/apply.v
index 02e043bc..e1df9ba8 100644
--- a/test-suite/success/apply.v
+++ b/test-suite/success/apply.v
@@ -39,7 +39,7 @@ Qed.
(* Check apply/eapply distinction in presence of open terms *)
Parameter h : forall x y z : nat, x = z -> x = y.
-Implicit Arguments h [[x] [y]].
+Arguments h {x y}.
Goal 1 = 0 -> True.
intro H.
apply h in H || exact I.
@@ -559,3 +559,26 @@ split.
- (* clear b:True *) match goal with H:_ |- _ => clear H end.
(* use a:0=0 *) match goal with H:_ |- _ => exact H end.
Qed.
+
+(* Test choice of most dependent solution *)
+Goal forall n, n = 0 -> exists p, p = n /\ p = 0.
+intros. eexists ?[p]. split. rewrite H.
+reflexivity. (* Compatibility tells [?p:=n] rather than [?p:=0] *)
+exact H. (* this checks that the goal is [n=0], not [0=0] *)
+Qed.
+
+(* Check insensitivity to alphabetic order of names*)
+(* In both cases, the last name is conventionally chosen *)
+(* Before 8.9, the name coming first in alphabetic order *)
+(* was chosen. *)
+Goal forall m n, m = n -> n = 0 -> exists p, p = n /\ p = 0.
+intros. eexists ?[p]. split. rewrite H.
+reflexivity.
+exact H0.
+Qed.
+
+Goal forall n m, n = m -> m = 0 -> exists p, p = m /\ p = 0.
+intros. eexists ?[p]. split. rewrite H.
+reflexivity.
+exact H0.
+Qed.
diff --git a/test-suite/success/attribute-syntax.v b/test-suite/success/attribute-syntax.v
new file mode 100644
index 00000000..83fb3d0c
--- /dev/null
+++ b/test-suite/success/attribute-syntax.v
@@ -0,0 +1,23 @@
+From Coq Require Program.
+
+Section Scope.
+
+#[local] Coercion nat_of_bool (b: bool) : nat :=
+ if b then 0 else 1.
+
+Check (refl_equal : true = 0 :> nat).
+
+End Scope.
+
+Fail Check 0 = true :> nat.
+
+#[polymorphic]
+Definition ι T (x: T) := x.
+
+Check ι _ ι.
+
+#[program]
+Fixpoint f (n: nat) {wf lt n} : nat := _.
+
+#[deprecated(since="8.9.0")]
+Ltac foo := foo.
diff --git a/test-suite/success/dependentind.v b/test-suite/success/dependentind.v
index f5bb884d..55ae54ca 100644
--- a/test-suite/success/dependentind.v
+++ b/test-suite/success/dependentind.v
@@ -42,7 +42,7 @@ Inductive ctx : Type :=
Bind Scope context_scope with ctx.
Delimit Scope context_scope with ctx.
-Arguments Scope snoc [context_scope].
+Arguments snoc _%context_scope.
Notation " Γ , τ " := (snoc Γ τ) (at level 25, τ at next level, left associativity) : context_scope.
diff --git a/test-suite/success/destruct.v b/test-suite/success/destruct.v
index 6fbe61a9..d1d38465 100644
--- a/test-suite/success/destruct.v
+++ b/test-suite/success/destruct.v
@@ -422,6 +422,7 @@ Abort.
Goal forall b:bool, b = b.
intros.
destruct b eqn:H.
+Abort.
(* Check natural instantiation behavior when the goal has already an evar *)
diff --git a/test-suite/success/evars.v b/test-suite/success/evars.v
index 0f9fb745..253b48e4 100644
--- a/test-suite/success/evars.v
+++ b/test-suite/success/evars.v
@@ -386,7 +386,7 @@ Record iffT (X Y:Type) : Type := mkIff { iffLR : X->Y; iffRL : Y->X }.
Record tri (R:Type->Type->Type) (S:Type->Type->Type) (T:Type->Type->Type) := mkTri {
tri0 : forall a b c, R a b -> S a c -> T b c
}.
-Implicit Arguments mkTri [R S T].
+Arguments mkTri [R S T].
Definition tri_iffT : tri iffT iffT iffT :=
(mkTri
(fun X0 X1 X2 E01 E02 =>
diff --git a/test-suite/success/goal_selector.v b/test-suite/success/goal_selector.v
index 86814051..0951c5c8 100644
--- a/test-suite/success/goal_selector.v
+++ b/test-suite/success/goal_selector.v
@@ -53,3 +53,17 @@ Goal True -> exists (x : Prop), x.
Proof.
intro H; eexists ?[x]; only [x]: exact True. 1: assumption.
Qed.
+
+(* Strict focusing! *)
+Set Default Goal Selector "!".
+
+Goal True -> True /\ True /\ True.
+Proof.
+ intro.
+ split;only 2:split.
+ Fail exact I.
+ Fail !:exact I.
+ 1:exact I.
+ - !:exact H.
+ - exact I.
+Qed.
diff --git a/test-suite/success/implicit.v b/test-suite/success/implicit.v
index a0981311..23853890 100644
--- a/test-suite/success/implicit.v
+++ b/test-suite/success/implicit.v
@@ -33,11 +33,11 @@ Definition eq1 := fun (A:Type) (x y:A) => x=y.
Definition eq2 := fun (A:Type) (x y:A) => x=y.
Definition eq3 := fun (A:Type) (x y:A) => x=y.
-Implicit Arguments op' [].
-Global Implicit Arguments op'' [].
+Arguments op' : clear implicits.
+Global Arguments op'' : clear implicits.
-Implicit Arguments eq2 [].
-Global Implicit Arguments eq3 [].
+Arguments eq2 : clear implicits.
+Global Arguments eq3 : clear implicits.
Check (op 0 0).
Check (op' nat 0 0).
@@ -89,14 +89,14 @@ Fixpoint plus n m {struct n} :=
(* Check multiple implicit arguments signatures *)
-Implicit Arguments eq_refl [[A] [x]] [[A]].
+Arguments eq_refl {A x}, {A}.
Check eq_refl : 0 = 0.
(* Check that notations preserve implicit (since 8.3) *)
Parameter p : forall A, A -> forall n, n = 0 -> True.
-Implicit Arguments p [A n].
+Arguments p [A] _ [n].
Notation Q := (p 0).
Check Q eq_refl.
diff --git a/test-suite/success/intros.v b/test-suite/success/intros.v
index a329894a..d37ad9f5 100644
--- a/test-suite/success/intros.v
+++ b/test-suite/success/intros.v
@@ -127,4 +127,28 @@ induction 1 as (n,H,IH).
exact Logic.I.
Qed.
+(* Make "intro"/"intros" progress on existential variables *)
+Module Evar.
+
+Goal exists (A:Prop), A.
+eexists.
+unshelve (intro x).
+- exact nat.
+- exact (x=x).
+- auto.
+Qed.
+
+Goal exists (A:Prop), A.
+eexists.
+unshelve (intros x).
+- exact nat.
+- exact (x=x).
+- auto.
+Qed.
+
+Definition d := ltac:(intro x; exact (x*x)).
+
+Definition d' : nat -> _ := ltac:(intros;exact 0).
+
+End Evar.
diff --git a/test-suite/success/letproj.v b/test-suite/success/letproj.v
index de2857b4..2f0d8bf8 100644
--- a/test-suite/success/letproj.v
+++ b/test-suite/success/letproj.v
@@ -7,3 +7,5 @@ Definition test (A : Type) (f : Foo A) :=
Scheme foo_case := Case for Foo Sort Type.
+Definition test' (A : Type) (f : Foo A) :=
+ let 'Build_Foo _ x y := f in x.
diff --git a/test-suite/success/mutual_record.v b/test-suite/success/mutual_record.v
new file mode 100644
index 00000000..77529733
--- /dev/null
+++ b/test-suite/success/mutual_record.v
@@ -0,0 +1,57 @@
+Module M0.
+
+Inductive foo (A : Type) := Foo {
+ foo0 : option (bar A);
+ foo1 : nat;
+ foo2 := foo1 = 0;
+ foo3 : foo2;
+}
+
+with bar (A : Type) := Bar {
+ bar0 : A;
+ bar1 := 0;
+ bar2 : bar1 = 0;
+ bar3 : nat -> foo A;
+}.
+
+End M0.
+
+Module M1.
+
+Set Primitive Projections.
+
+Inductive foo (A : Type) := Foo {
+ foo0 : option (bar A);
+ foo1 : nat;
+ foo2 := foo1 = 0;
+ foo3 : foo2;
+}
+
+with bar (A : Type) := Bar {
+ bar0 : A;
+ bar1 := 0;
+ bar2 : bar1 = 0;
+ bar3 : nat -> foo A;
+}.
+
+End M1.
+
+Module M2.
+
+Set Primitive Projections.
+
+CoInductive foo (A : Type) := Foo {
+ foo0 : option (bar A);
+ foo1 : nat;
+ foo2 := foo1 = 0;
+ foo3 : foo2;
+}
+
+with bar (A : Type) := Bar {
+ bar0 : A;
+ bar1 := 0;
+ bar2 : bar1 = 0;
+ bar3 : nat -> foo A;
+}.
+
+End M2.
diff --git a/test-suite/success/primitiveproj.v b/test-suite/success/primitiveproj.v
index 31a1608c..299b08bd 100644
--- a/test-suite/success/primitiveproj.v
+++ b/test-suite/success/primitiveproj.v
@@ -193,9 +193,37 @@ Set Primitive Projections.
Record s (x:nat) (y:=S x) := {c:=x; d:x=c}.
Lemma f : 0=1.
Proof.
-Fail apply d.
+ Fail apply d.
(*
split.
reflexivity.
Qed.
*)
+Abort.
+
+(* Primitive projection match compilation *)
+Require Import List.
+Set Primitive Projections.
+
+Record prod (A B : Type) := pair { fst : A ; snd : B }.
+Arguments pair {_ _} _ _.
+
+Fixpoint split_at {A} (l : list A) (n : nat) : prod (list A) (list A) :=
+ match n with
+ | 0 => pair nil l
+ | S n =>
+ match l with
+ | nil => pair nil nil
+ | x :: l => let 'pair l1 l2 := split_at l n in pair (x :: l1) l2
+ end
+ end.
+
+Time Eval vm_compute in split_at (repeat 0 20) 10. (* Takes 0s *)
+Time Eval vm_compute in split_at (repeat 0 40) 20. (* Takes 0.001s *)
+Timeout 1 Time Eval vm_compute in split_at (repeat 0 60) 30. (* Used to take 60s, now takes 0.001s *)
+
+Check (@eq_refl _ 0 <: 0 = fst (pair 0 1)).
+Fail Check (@eq_refl _ 0 <: 0 = snd (pair 0 1)).
+
+Check (@eq_refl _ 0 <<: 0 = fst (pair 0 1)).
+Fail Check (@eq_refl _ 0 <<: 0 = snd (pair 0 1)).
diff --git a/test-suite/success/refine.v b/test-suite/success/refine.v
index 22fb4d75..40986e57 100644
--- a/test-suite/success/refine.v
+++ b/test-suite/success/refine.v
@@ -121,14 +121,16 @@ Abort.
(* Wish 1988: that fun forces unfold in refine *)
Goal (forall A : Prop, A -> ~~A).
-Proof. refine(fun A a f => _).
+Proof. refine(fun A a f => _). Abort.
(* Checking beta-iota normalization of hypotheses in created evars *)
Goal {x|x=0} -> True.
refine (fun y => let (x,a) := y in _).
match goal with a:_=0 |- _ => idtac end.
+Abort.
Goal (forall P, {P 0}+{P 1}) -> True.
refine (fun H => if H (fun x => x=x) then _ else _).
match goal with _:0=0 |- _ => idtac end.
+Abort.
diff --git a/test-suite/success/rewrite.v b/test-suite/success/rewrite.v
index 448d0082..baf08979 100644
--- a/test-suite/success/rewrite.v
+++ b/test-suite/success/rewrite.v
@@ -7,7 +7,7 @@ Inductive listn : nat -> Set :=
Axiom
ax :
forall (n n' : nat) (l : listn (n + n')) (l' : listn (n' + n)),
- existS _ (n + n') l = existS _ (n' + n) l'.
+ existT _ (n + n') l = existT _ (n' + n) l'.
Lemma lem :
forall (n n' : nat) (l : listn (n + n')) (l' : listn (n' + n)),
@@ -72,7 +72,7 @@ Qed.
Require Import JMeq.
-Goal forall A B (a:A) (b:B), JMeq a b -> JMeq b a -> True.
+Goal forall A B (a:A) (b:B), JMeq a b -> JMeq b a -> True.
inversion 1; (* Goal is now [JMeq a a -> True] *) dependent rewrite H3.
Undo.
intros; inversion H; dependent rewrite H4 in H0.
@@ -135,7 +135,7 @@ Abort.
Goal forall x y, x=y+0 -> let z := x+1 in x+1=y -> z=z -> z=x.
intros.
subst x. (* was failing *)
-subst z.
+subst z.
rewrite H0.
auto with arith.
Qed.
diff --git a/test-suite/success/sideff.v b/test-suite/success/sideff.v
index 3c0b8156..b9a1273b 100644
--- a/test-suite/success/sideff.v
+++ b/test-suite/success/sideff.v
@@ -5,6 +5,8 @@ Proof.
apply (const tt tt).
Qed.
+Set Nested Proofs Allowed.
+
Lemma foobar' : unit.
Lemma aux : forall A : Type, A -> unit.
Proof. intros. pose (foo := idw A). exact tt. Show Universes. Qed.
diff --git a/test-suite/success/uniform_inductive_parameters.v b/test-suite/success/uniform_inductive_parameters.v
new file mode 100644
index 00000000..42236a53
--- /dev/null
+++ b/test-suite/success/uniform_inductive_parameters.v
@@ -0,0 +1,13 @@
+Set Uniform Inductive Parameters.
+
+Inductive list (A : Type) :=
+ | nil : list
+ | cons : A -> list -> list.
+Check (list : Type -> Type).
+Check (cons : forall A, A -> list A -> list A).
+
+Inductive list2 (A : Type) (A' := prod A A) :=
+ | nil2 : list2
+ | cons2 : A' -> list2 -> list2.
+Check (list2 : Type -> Type).
+Check (cons2 : forall A (A' := prod A A), A' -> list2 A -> list2 A).
diff --git a/test-suite/success/univers.v b/test-suite/success/univers.v
index 28634045..28426b57 100644
--- a/test-suite/success/univers.v
+++ b/test-suite/success/univers.v
@@ -60,7 +60,7 @@ Qed.
Record U : Type := { A:=Type; a:A }.
-(** Check assignement of sorts to inductives and records. *)
+(** Check assignment of sorts to inductives and records. *)
Variable sh : list nat.
diff --git a/test-suite/success/vm_records.v b/test-suite/success/vm_records.v
new file mode 100644
index 00000000..8a1544c8
--- /dev/null
+++ b/test-suite/success/vm_records.v
@@ -0,0 +1,40 @@
+Set Primitive Projections.
+
+Module M.
+
+CoInductive foo := Foo {
+ foo0 : foo;
+ foo1 : bar;
+}
+with bar := Bar {
+ bar0 : foo;
+ bar1 : bar;
+}.
+
+CoFixpoint f : foo := Foo f g
+with g : bar := Bar f g.
+
+Check (@eq_refl _ g.(bar0) <: f.(foo0).(foo0) = g.(bar0)).
+Check (@eq_refl _ g <: g.(bar1).(bar0).(foo1) = g).
+
+End M.
+
+Module N.
+
+Inductive foo := Foo {
+ foo0 : option foo;
+ foo1 : list bar;
+}
+with bar := Bar {
+ bar0 : option bar;
+ bar1 : list foo;
+}.
+
+Definition f_0 := Foo None nil.
+Definition g_0 := Bar None nil.
+
+Definition f := Foo (Some f_0) (cons g_0 nil).
+
+Check (@eq_refl _ f.(foo1) <: f.(foo1) = cons g_0 nil).
+
+End N.
diff --git a/test-suite/tools/update-compat/run.sh b/test-suite/tools/update-compat/run.sh
new file mode 100755
index 00000000..02a23484
--- /dev/null
+++ b/test-suite/tools/update-compat/run.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+# allow running this script from any directory by basing things on where the script lives
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
+
+# we assume that the script lives in test-suite/tools/update-compat/,
+# and that update-compat.py lives in dev/tools/
+cd "${SCRIPT_DIR}/../../.."
+dev/tools/update-compat.py --assert-unchanged --cur-version=8.9 || exit $?
diff --git a/test-suite/unit-tests/.merlin.in b/test-suite/unit-tests/.merlin.in
new file mode 100644
index 00000000..b2279de7
--- /dev/null
+++ b/test-suite/unit-tests/.merlin.in
@@ -0,0 +1,6 @@
+REC
+
+S **
+B **
+
+PKG oUnit
diff --git a/test-suite/unit-tests/clib/inteq.ml b/test-suite/unit-tests/clib/inteq.ml
new file mode 100644
index 00000000..89717c79
--- /dev/null
+++ b/test-suite/unit-tests/clib/inteq.ml
@@ -0,0 +1,15 @@
+open Utest
+
+let log_out_ch = open_log_out_ch __FILE__
+
+let eq0 = mk_bool_test "clib-inteq0"
+ "Int.equal on 0"
+ (Int.equal 0 0)
+
+let eq42 = mk_bool_test "clib-inteq42"
+ "Int.equal on 42"
+ (Int.equal 42 42)
+
+let tests = [ eq0; eq42 ]
+
+let _ = run_tests __FILE__ log_out_ch tests
diff --git a/test-suite/unit-tests/clib/unicode_tests.ml b/test-suite/unit-tests/clib/unicode_tests.ml
new file mode 100644
index 00000000..95316ad3
--- /dev/null
+++ b/test-suite/unit-tests/clib/unicode_tests.ml
@@ -0,0 +1,17 @@
+open Utest
+
+let log_out_ch = open_log_out_ch __FILE__
+
+let unicode0 = mk_eq_test "clib-unicode0"
+ "split_at_first_letter, first letter is character"
+ None
+ (Unicode.split_at_first_letter "ident")
+
+let unicode1 = mk_eq_test "clib-unicode1"
+ "split_at_first_letter, first letter not character"
+ (Some ("__","ident"))
+ (Unicode.split_at_first_letter "__ident")
+
+let tests = [ unicode0; unicode1 ]
+
+let _ = run_tests __FILE__ log_out_ch tests
diff --git a/test-suite/unit-tests/printing/proof_diffs_test.ml b/test-suite/unit-tests/printing/proof_diffs_test.ml
new file mode 100644
index 00000000..526cefec
--- /dev/null
+++ b/test-suite/unit-tests/printing/proof_diffs_test.ml
@@ -0,0 +1,333 @@
+open OUnit
+open Utest
+open Pp_diff
+open Proof_diffs
+
+let tokenize_string = Proof_diffs.tokenize_string
+let diff_pp = diff_pp ~tokenize_string
+let diff_str = diff_str ~tokenize_string
+
+let tests = ref []
+let add_test name test = tests := (mk_test name (TestCase test)) :: !tests
+
+let log_out_ch = open_log_out_ch __FILE__
+let cfprintf oc = Printf.(kfprintf (fun oc -> fprintf oc "") oc)
+let cprintf s = cfprintf log_out_ch s
+let _ = Proof_diffs.log_out_ch := log_out_ch
+
+let string_of_string s : string = "\"" ^ s ^ "\""
+
+(* todo: OCaml: why can't the body of the test function be given in the add_test line? *)
+
+let t () =
+ let expected : diff_list = [] in
+ let diffs = diff_str "" " " in
+
+ assert_equal ~msg:"empty" ~printer:string_of_diffs expected diffs;
+ let (has_added, has_removed) = has_changes diffs in
+ assert_equal ~msg:"has `Added" ~printer:string_of_bool false has_added;
+ assert_equal ~msg:"has `Removed" ~printer:string_of_bool false has_removed
+let _ = add_test "diff_str empty" t
+
+
+let t () =
+ let expected : diff_list =
+ [ `Common (0, 0, "a"); `Common (1, 1, "b"); `Common (2, 2, "c")] in
+ let diffs = diff_str "a b c" " a b\t c\n" in
+
+ assert_equal ~msg:"white space" ~printer:string_of_diffs expected diffs;
+ let (has_added, has_removed) = has_changes diffs in
+ assert_equal ~msg:"no `Added" ~printer:string_of_bool false has_added;
+ assert_equal ~msg:"no `Removed" ~printer:string_of_bool false has_removed
+let _ = add_test "diff_str white space" t
+
+let t () =
+ let expected : diff_list = [ `Removed (0, "a"); `Added (0, "b")] in
+ let diffs = diff_str "a" "b" in
+
+ assert_equal ~msg:"add/remove" ~printer:string_of_diffs expected diffs;
+ let (has_added, has_removed) = has_changes diffs in
+ assert_equal ~msg:"has `Added" ~printer:string_of_bool true has_added;
+ assert_equal ~msg:"has `Removed" ~printer:string_of_bool true has_removed
+let _ = add_test "diff_str add/remove" t
+
+(* example of a limitation, not really a test *)
+let t () =
+ try
+ let _ = diff_str "a" "&gt;" in
+ assert_failure "unlexable string gives an exception"
+ with _ -> ()
+let _ = add_test "diff_str unlexable" t
+
+(* problematic examples for tokenize_string:
+ comments omitted
+ quoted string loses quote marks (are escapes supported/handled?)
+ char constant split into 2
+ *)
+let t () =
+ List.iter (fun x -> cprintf "'%s' " x) (tokenize_string "(* comment *) \"string\" 'c' xx");
+ cprintf "\n"
+let _ = add_test "tokenize_string examples" t
+
+open Pp
+
+(* note pp_to_string concatenates adjacent strings, could become one token,
+e.g. str " a" ++ str "b " will give a token "ab" *)
+(* checks background is present and correct *)
+let t () =
+ let o_pp = str "a" ++ str "!" ++ str "c" in
+ let n_pp = str "a" ++ str "?" ++ str "c" in
+ let (o_exp, n_exp) = (wrap_in_bg "diff.removed" (str "a" ++ (tag "diff.removed" (str "!")) ++ str "c"),
+ wrap_in_bg "diff.added" (str "a" ++ (tag "diff.added" (str "?")) ++ str "c")) in
+ let (o_diff, n_diff) = diff_pp o_pp n_pp in
+
+ assert_equal ~msg:"removed" ~printer:db_string_of_pp o_exp o_diff;
+ assert_equal ~msg:"added" ~printer:db_string_of_pp n_exp n_diff
+let _ = add_test "diff_pp/add_diff_tags add/remove" t
+
+let t () =
+ (*Printf.printf "%s\n" (string_of_diffs (diff_str "a d" "a b c d"));*)
+ let o_pp = str "a" ++ str " d" in
+ let n_pp = str "a" ++ str " b " ++ str " c " ++ str "d" ++ str " e " in
+ let n_exp = flatten (wrap_in_bg "diff.added" (seq [
+ str "a";
+ str " "; (tag "start.diff.added" (str "b "));
+ (tag "end.diff.added" (str " c")); str " ";
+ (str "d");
+ str " "; (tag "diff.added" (str "e")); str " "
+ ])) in
+ let (_, n_diff) = diff_pp o_pp n_pp in
+
+ assert_equal ~msg:"added" ~printer:db_string_of_pp n_exp (flatten n_diff);;
+let _ = add_test "diff_pp/add_diff_tags a span with spaces" t
+
+
+let t () =
+ let o_pp = str " " in
+ let n_pp = tag "sometag" (str "a") in
+ let n_exp = flatten (wrap_in_bg "diff.added" (tag "diff.added" (tag "sometag" (str "a")))) in
+ let (_, n_diff) = diff_pp o_pp n_pp in
+
+ assert_equal ~msg:"added" ~printer:db_string_of_pp n_exp (flatten n_diff)
+let _ = add_test "diff_pp/add_diff_tags diff tags outside existing tags" t
+
+let t () =
+ let o_pp = str " " in
+ let n_pp = seq [(tag "sometag" (str " a ")); str "b"] in
+ let n_exp = flatten (wrap_in_bg "diff.added"
+ (seq [tag "sometag" (str " "); (tag "start.diff.added" (tag "sometag" (str "a ")));
+ (tag "end.diff.added" (str "b"))]) ) in
+ let (_, n_diff) = diff_pp o_pp n_pp in
+
+ assert_equal ~msg:"added" ~printer:db_string_of_pp n_exp (flatten n_diff)
+let _ = add_test "diff_pp/add_diff_tags existing tagged values with spaces" t
+
+let t () =
+ let o_pp = str " " in
+ let n_pp = str " a b " in
+ let n_exp = flatten (wrap_in_bg "diff.added"
+ (seq [str " "; tag "diff.added" (str "a b"); str " "])) in
+ let (_, n_diff) = diff_pp o_pp n_pp in
+
+ assert_equal ~msg:"added" ~printer:db_string_of_pp n_exp (flatten n_diff)
+let _ = add_test "diff_pp/add_diff_tags multiple tokens in pp" t
+
+let t () =
+ let o_pp = str "a d" in
+ let n_pp = seq [str "a b"; str "c d"] in
+ let n_exp = flatten (wrap_in_bg "diff.added"
+ (seq [str "a "; tag "start.diff.added" (str "b");
+ tag "end.diff.added" (str "c"); str " d"])) in
+ let (_, n_diff) = diff_pp o_pp n_pp in
+
+ assert_equal ~msg:"added" ~printer:db_string_of_pp n_exp (flatten n_diff)
+let _ = add_test "diff_pp/add_diff_tags token spanning multiple Ppcmd_strs" t
+
+let t () =
+ let o_pp = seq [str ""; str "a"] in
+ let n_pp = seq [str ""; str "a b"] in
+ let n_exp = flatten (wrap_in_bg "diff.added"
+ (seq [str ""; str "a "; tag "diff.added" (str "b")])) in
+ let (_, n_diff) = diff_pp o_pp n_pp in
+
+ assert_equal ~msg:"added" ~printer:db_string_of_pp n_exp (flatten n_diff)
+let _ = add_test "diff_pp/add_diff_tags empty string preserved" t
+
+(* todo: awaiting a change in the lexer to return the quotes of the string token *)
+let t () =
+ let s = "\"a b\"" in
+ let o_pp = seq [str s] in
+ let n_pp = seq [str "\"a b\" "] in
+ cprintf "ppcmds: %s\n" (string_of_ppcmds n_pp);
+ let n_exp = flatten (wrap_in_bg "diff.added"
+ (seq [str ""; str "a "; tag "diff.added" (str "b")])) in
+ let (_, n_diff) = diff_pp o_pp n_pp in
+
+ assert_equal ~msg:"string" ~printer:string_of_string "a b" (List.hd (tokenize_string s));
+ assert_equal ~msg:"added" ~printer:db_string_of_pp n_exp (flatten n_diff)
+let _ = if false then add_test "diff_pp/add_diff_tags token containing white space" t
+
+let add_entries map idents rhs_pp =
+ let make_entry() = { idents; rhs_pp; done_ = false } in
+ List.iter (fun ident -> map := (StringMap.add ident (make_entry ()) !map); ()) idents;;
+
+let print_list hyps = List.iter (fun x -> cprintf "%s\n" (string_of_ppcmds (flatten x))) hyps
+let db_print_list hyps = List.iter (fun x -> cprintf "%s\n" (db_string_of_pp (flatten x))) hyps
+
+
+(* a : foo
+ b : bar car ->
+ b : car
+ a : foo bar *)
+let t () =
+ write_diffs_option "removed"; (* turn on "removed" option *)
+ let o_line_idents = [ ["a"]; ["b"]] in
+ let o_hyp_map = ref StringMap.empty in
+ add_entries o_hyp_map ["a"] (str " : foo");
+ add_entries o_hyp_map ["b"] (str " : bar car");
+ let n_line_idents = [ ["b"]; ["a"]] in
+ let n_hyp_map = ref StringMap.empty in
+ add_entries n_hyp_map ["b"] (str " : car");
+ add_entries n_hyp_map ["a"] (str " : foo bar");
+ let expected = [flatten (wrap_in_bg "diff.removed" (seq [str "b"; str " : "; (tag "diff.removed" (str "bar")); str " car" ]));
+ flatten (wrap_in_bg "diff.added" (seq [str "b"; str " : car" ]));
+ flatten (wrap_in_bg "diff.added" (seq [str "a"; str " : foo "; (tag "diff.added" (str "bar")) ]))
+ ] in
+
+ let hyps_diff_list = diff_hyps o_line_idents !o_hyp_map n_line_idents !n_hyp_map in
+
+ (*print_list hyps_diff_list;*)
+ (*db_print_list hyps_diff_list;*)
+
+ List.iter2 (fun exp act ->
+ assert_equal ~msg:"added" ~printer:db_string_of_pp exp (flatten act))
+ expected hyps_diff_list
+let _ = add_test "diff_hyps simple diffs" t
+
+(* a : nat
+ c, d : int ->
+ a, b : nat
+ d : int
+ and keeps old order *)
+let t () =
+ write_diffs_option "removed"; (* turn on "removed" option *)
+ let o_line_idents = [ ["a"]; ["c"; "d"]] in
+ let o_hyp_map = ref StringMap.empty in
+ add_entries o_hyp_map ["a"] (str " : nat");
+ add_entries o_hyp_map ["c"; "d"] (str " : int");
+ let n_line_idents = [ ["a"; "b"]; ["d"]] in
+ let n_hyp_map = ref StringMap.empty in
+ add_entries n_hyp_map ["a"; "b"] (str " : nat");
+ add_entries n_hyp_map ["d"] (str " : int");
+ let expected = [flatten (wrap_in_bg "diff.added" (seq [str "a"; (tag "start.diff.added" (str ", ")); (tag "end.diff.added" (str "b")); str " : nat" ]));
+ flatten (wrap_in_bg "diff.removed" (seq [(tag "start.diff.removed" (str "c")); (tag "end.diff.removed" (str ",")); str " "; str "d"; str " : int" ]));
+ flatten (wrap_in_bg "diff.added" (seq [str "d"; str " : int" ]))
+ ] in
+
+ let hyps_diff_list = diff_hyps o_line_idents !o_hyp_map n_line_idents !n_hyp_map in
+
+ (*print_list hyps_diff_list;*)
+ (*print_list expected;*)
+
+ (*db_print_list hyps_diff_list;*)
+ (*db_print_list expected;*)
+
+ List.iter2 (fun exp act ->
+ assert_equal ~msg:"added" ~printer:db_string_of_pp exp (flatten act))
+ expected hyps_diff_list
+let _ = add_test "diff_hyps compacted" t
+
+(* a : foo
+ b : bar
+ c : nat ->
+ b, a, c : nat
+DIFFS
+ b : bar (remove bar)
+ b : nat (add nat)
+ a : foo (remove foo)
+ a : nat (add nat)
+ c : nat
+ is this a realistic use case?
+*)
+let t () =
+ write_diffs_option "removed"; (* turn on "removed" option *)
+ let o_line_idents = [ ["a"]; ["b"]; ["c"]] in
+ let o_hyp_map = ref StringMap.empty in
+ add_entries o_hyp_map ["a"] (str " : foo");
+ add_entries o_hyp_map ["b"] (str " : bar");
+ add_entries o_hyp_map ["c"] (str " : nat");
+ let n_line_idents = [ ["b"; "a"; "c"] ] in
+ let n_hyp_map = ref StringMap.empty in
+ add_entries n_hyp_map ["b"; "a"; "c"] (str " : nat");
+ let expected = [flatten (wrap_in_bg "diff.removed" (seq [str "b"; str " : "; (tag "diff.removed" (str "bar"))]));
+ flatten (wrap_in_bg "diff.added" (seq [str "b"; str " : "; (tag "diff.added" (str "nat"))]));
+ flatten (wrap_in_bg "diff.removed" (seq [str "a"; str " : "; (tag "diff.removed" (str "foo"))]));
+ flatten (wrap_in_bg "diff.added" (seq [str "a"; str " : "; (tag "diff.added" (str "nat"))]));
+ flatten (seq [str "c"; str " : nat"])
+ ] in
+
+ let hyps_diff_list = diff_hyps o_line_idents !o_hyp_map n_line_idents !n_hyp_map in
+
+ (*print_list hyps_diff_list;*)
+ (*db_print_list hyps_diff_list;*)
+
+ List.iter2 (fun exp act ->
+ assert_equal ~msg:"added" ~printer:db_string_of_pp exp (flatten act))
+ expected hyps_diff_list
+let _ = add_test "diff_hyps compacted with join" t
+
+(* b, a, c : nat ->
+ a : foo
+ b : bar
+ c : nat
+DIFFS
+ a : nat (remove nat)
+ a : foo (add foo)
+ b : nat (remove nat)
+ b : bar (add bar)
+ c : nat
+ is this a realistic use case? *)
+let t () =
+ write_diffs_option "removed"; (* turn on "removed" option *)
+ let o_line_idents = [ ["b"; "a"; "c"] ] in
+ let o_hyp_map = ref StringMap.empty in
+ add_entries o_hyp_map ["b"; "a"; "c"] (str " : nat");
+ let n_line_idents = [ ["a"]; ["b"]; ["c"]] in
+ let n_hyp_map = ref StringMap.empty in
+ add_entries n_hyp_map ["a"] (str " : foo");
+ add_entries n_hyp_map ["b"] (str " : bar");
+ add_entries n_hyp_map ["c"] (str " : nat");
+ let expected = [flatten (wrap_in_bg "diff.removed" (seq [str "a"; str " : "; (tag "diff.removed" (str "nat"))]));
+ flatten (wrap_in_bg "diff.added" (seq [str "a"; str " : "; (tag "diff.added" (str "foo"))]));
+ flatten (wrap_in_bg "diff.removed" (seq [str "b"; str " : "; (tag "diff.removed" (str "nat"))]));
+ flatten (wrap_in_bg "diff.added" (seq [str "b"; str " : "; (tag "diff.added" (str "bar"))]));
+ flatten (seq [str "c"; str " : nat"])
+ ] in
+
+ let hyps_diff_list = diff_hyps o_line_idents !o_hyp_map n_line_idents !n_hyp_map in
+
+ (*print_list hyps_diff_list;*)
+ (*db_print_list hyps_diff_list;*)
+
+ List.iter2 (fun exp act ->
+ assert_equal ~msg:"added" ~printer:db_string_of_pp exp (flatten act))
+ expected hyps_diff_list
+let _ = add_test "diff_hyps compacted with split" t
+
+
+(* other potential tests
+coqtop/terminal formatting BLOCKED: CAN'T GET TAGS IN FORMATTER
+ white space at end of line
+ spanning diffs
+shorten_diff_span
+
+MAYBE NOT WORTH IT
+diff_pp/add_diff_tags
+ add/remove - show it preserves, recurs and processes:
+ nested in boxes
+ breaks, etc. preserved
+diff_pp_combined with/without removed
+*)
+
+
+let _ = run_tests __FILE__ log_out_ch (List.rev !tests)
diff --git a/test-suite/unit-tests/src/utest.ml b/test-suite/unit-tests/src/utest.ml
new file mode 100644
index 00000000..0cb1780e
--- /dev/null
+++ b/test-suite/unit-tests/src/utest.ml
@@ -0,0 +1,76 @@
+open OUnit
+
+(* general case to build a test *)
+let mk_test nm test = nm >: test
+
+(* common cases for building tests *)
+let mk_eq_test nm descr expected actual =
+ mk_test nm (TestCase (fun _ -> assert_equal ~msg:descr expected actual))
+
+let mk_bool_test nm descr actual =
+ mk_test nm (TestCase (fun _ -> assert_bool descr actual))
+
+let cfprintf oc = Printf.(kfprintf (fun oc -> fprintf oc "\n%!") oc)
+
+(* given test result, print message, return success boolean *)
+let logger out_ch result =
+ let cprintf s = cfprintf out_ch s in
+ match result with
+ | RSuccess path ->
+ cprintf "TEST SUCCEEDED: %s" (string_of_path path);
+ true
+ | RError (path,msg)
+ | RFailure (path,msg) ->
+ cprintf "TEST FAILED: %s (%s)" (string_of_path path) msg;
+ false
+ | RSkip (path,msg)
+ | RTodo (path,msg) ->
+ cprintf "TEST DID NOT SUCCEED: %s (%s)" (string_of_path path) msg;
+ false
+
+(* run one OUnit test case, return successes, no. of tests *)
+(* notionally one test, which might be a TestList *)
+let run_one logit test =
+ let rec process_results rs =
+ match rs with
+ [] -> (0,0)
+ | (r::rest) ->
+ let succ = if logit r then 1 else 0 in
+ let succ_results,tot_results = process_results rest in
+ (succ + succ_results,tot_results + 1)
+ in
+ let results = perform_test (fun _ -> ()) test in
+ process_results results
+
+let open_log_out_ch ml_fn =
+ let log_fn = ml_fn ^ ".log" in
+ open_out log_fn
+
+(* run list of OUnit test cases, log results *)
+let run_tests ml_fn out_ch tests =
+ let cprintf s = cfprintf out_ch s in
+ let ceprintf s = cfprintf stderr s in
+ let logit = logger out_ch in
+ let rec run_some tests succ tot =
+ match tests with
+ [] -> (succ,tot)
+ | (t::ts) ->
+ let succ_one,tot_one = run_one logit t in
+ run_some ts (succ + succ_one) (tot + tot_one)
+ in
+ (* format for test-suite summary to find status
+ success if all tests succeeded, else failure
+ *)
+ let succ,tot = run_some tests 0 0 in
+ cprintf
+ "*** Ran %d tests, with %d successes and %d failures ***"
+ tot succ (tot - succ);
+ if succ = tot then
+ cprintf
+ "==========> SUCCESS <==========\n %s...Ok" ml_fn
+ else begin
+ cprintf
+ "==========> FAILURE <==========\n %s...Error!" ml_fn;
+ ceprintf "FAILED %s.log" ml_fn
+ end;
+ close_out out_ch
diff --git a/test-suite/unit-tests/src/utest.mli b/test-suite/unit-tests/src/utest.mli
new file mode 100644
index 00000000..2e0f26e9
--- /dev/null
+++ b/test-suite/unit-tests/src/utest.mli
@@ -0,0 +1,18 @@
+(** give a name to a unit test *)
+val mk_test : string -> OUnit.test -> OUnit.test
+
+(** simple ways to build a test *)
+val mk_eq_test : string -> string -> 'a -> 'a -> OUnit.test
+val mk_bool_test : string -> string -> bool -> OUnit.test
+
+(** run unit tests *)
+(* the string argument should be the name of the .ml file
+ containing the tests; use __FILE__ for that purpose.
+ *)
+val run_tests : string -> out_channel -> OUnit.test list -> unit
+
+(** open output channel for the test log file *)
+(* the string argument should be the name of the .ml file
+ containing the tests; use __FILE__ for that purpose.
+ *)
+val open_log_out_ch : string -> out_channel
diff --git a/test-suite/vio/numeral.v b/test-suite/vio/numeral.v
new file mode 100644
index 00000000..f28355bb
--- /dev/null
+++ b/test-suite/vio/numeral.v
@@ -0,0 +1,21 @@
+Lemma foo : True.
+Proof.
+Check 0 : nat.
+Check 0 : nat.
+exact I.
+Qed.
+
+Lemma bar : True.
+Proof.
+pose (0 : nat).
+exact I.
+Qed.
+
+Require Import Coq.Strings.Ascii.
+Open Scope char_scope.
+
+Lemma baz : True.
+Proof.
+pose "s".
+exact I.
+Qed.
diff --git a/theories/Arith/Compare_dec.v b/theories/Arith/Compare_dec.v
index 713aef85..6f220f20 100644
--- a/theories/Arith/Compare_dec.v
+++ b/theories/Arith/Compare_dec.v
@@ -135,10 +135,10 @@ Qed.
See now [Nat.compare] and its properties.
In scope [nat_scope], the notation for [Nat.compare] is "?=" *)
-Notation nat_compare := Nat.compare (compat "8.6").
+Notation nat_compare := Nat.compare (compat "8.7").
-Notation nat_compare_spec := Nat.compare_spec (compat "8.6").
-Notation nat_compare_eq_iff := Nat.compare_eq_iff (compat "8.6").
+Notation nat_compare_spec := Nat.compare_spec (compat "8.7").
+Notation nat_compare_eq_iff := Nat.compare_eq_iff (compat "8.7").
Notation nat_compare_S := Nat.compare_succ (only parsing).
Lemma nat_compare_lt n m : n<m <-> (n ?= m) = Lt.
diff --git a/theories/Bool/Bool.v b/theories/Bool/Bool.v
index edf78ed5..66a82008 100644
--- a/theories/Bool/Bool.v
+++ b/theories/Bool/Bool.v
@@ -814,3 +814,10 @@ Defined.
(** Reciprocally, from a decidability, we could state a
[reflect] as soon as we have a [bool_of_sumbool]. *)
+
+(** For instance, we could state the correctness of [Bool.eqb] via [reflect]: *)
+
+Lemma eqb_spec (b b' : bool) : reflect (b = b') (eqb b b').
+Proof.
+ destruct b, b'; now constructor.
+Qed.
diff --git a/theories/Compat/Coq88.v b/theories/Compat/Coq88.v
index 4142af05..950cd824 100644
--- a/theories/Compat/Coq88.v
+++ b/theories/Compat/Coq88.v
@@ -9,3 +9,19 @@
(************************************************************************)
(** Compatibility file for making Coq act similar to Coq v8.8 *)
+Require Export Coq.Compat.Coq89.
+
+(** In Coq 8.9, prim token notations follow [Import] rather than
+ [Require]. So we make all of the relevant notations accessible in
+ compatibility mode. *)
+Require Coq.Strings.Ascii Coq.Strings.String.
+Require Coq.ZArith.BinIntDef Coq.PArith.BinPosDef Coq.NArith.BinNatDef.
+Require Coq.Reals.Rdefinitions.
+Require Coq.Numbers.Cyclic.Int31.Int31.
+Declare ML Module "string_syntax_plugin".
+Declare ML Module "ascii_syntax_plugin".
+Declare ML Module "r_syntax_plugin".
+Declare ML Module "int31_syntax_plugin".
+Numeral Notation BinNums.Z BinIntDef.Z.of_int BinIntDef.Z.to_int : Z_scope.
+Numeral Notation BinNums.positive BinPosDef.Pos.of_int BinPosDef.Pos.to_int : positive_scope.
+Numeral Notation BinNums.N BinNatDef.N.of_int BinNatDef.N.to_int : N_scope.
diff --git a/ide/ide_slave.mli b/theories/Compat/Coq89.v
index 9db9ecd1..d2567188 100644
--- a/ide/ide_slave.mli
+++ b/theories/Compat/Coq89.v
@@ -8,5 +8,4 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-(* This empty file avoids a race condition that occurs when compiling a .ml file
- that does not have a corresponding .mli file *)
+(** Compatibility file for making Coq act similar to Coq v8.9 *)
diff --git a/theories/FSets/FMapFacts.v b/theories/FSets/FMapFacts.v
index 99705966..2d5a7983 100644
--- a/theories/FSets/FMapFacts.v
+++ b/theories/FSets/FMapFacts.v
@@ -26,7 +26,7 @@ Hint Extern 1 (Equivalence _) => constructor; congruence.
Module WFacts_fun (E:DecidableType)(Import M:WSfun E).
-Notation option_map := option_map (compat "8.6").
+Notation option_map := option_map (compat "8.7").
Notation eq_dec := E.eq_dec.
Definition eqb x y := if eq_dec x y then true else false.
diff --git a/theories/FSets/FMapFullAVL.v b/theories/FSets/FMapFullAVL.v
index 34529678..c0db8646 100644
--- a/theories/FSets/FMapFullAVL.v
+++ b/theories/FSets/FMapFullAVL.v
@@ -27,7 +27,7 @@
*)
-Require Import FunInd Recdef FMapInterface FMapList ZArith Int FMapAVL ROmega.
+Require Import FunInd Recdef FMapInterface FMapList ZArith Int FMapAVL Lia.
Set Implicit Arguments.
Unset Strict Implicit.
@@ -39,7 +39,7 @@ Import Raw.Proofs.
Local Open Scope pair_scope.
Local Open Scope Int_scope.
-Ltac omega_max := i2z_refl; romega with Z.
+Ltac omega_max := i2z_refl; lia.
Section Elt.
Variable elt : Type.
@@ -697,7 +697,7 @@ Module IntMake_ord (I:Int)(X: OrderedType)(D : OrderedType) <:
end.
Proof.
intros; unfold cardinal_e_2; simpl;
- abstract (do 2 rewrite cons_cardinal_e; romega with * ).
+ abstract (do 2 rewrite cons_cardinal_e; lia ).
Defined.
Definition Cmp c :=
diff --git a/theories/FSets/FSetEqProperties.v b/theories/FSets/FSetEqProperties.v
index 56844f47..59b2f789 100644
--- a/theories/FSets/FSetEqProperties.v
+++ b/theories/FSets/FSetEqProperties.v
@@ -333,7 +333,7 @@ Proof.
auto with set.
Qed.
-(* caracterisation of [union] via [subset] *)
+(* characterisation of [union] via [subset] *)
Lemma union_subset_1: subset s (union s s')=true.
Proof.
@@ -408,7 +408,7 @@ intros; apply equal_1; apply inter_add_2.
rewrite not_mem_iff; auto.
Qed.
-(* caracterisation of [union] via [subset] *)
+(* characterisation of [union] via [subset] *)
Lemma inter_subset_1: subset (inter s s') s=true.
Proof.
diff --git a/theories/Init/Datatypes.v b/theories/Init/Datatypes.v
index 05b741f0..1e6843d5 100644
--- a/theories/Init/Datatypes.v
+++ b/theories/Init/Datatypes.v
@@ -12,7 +12,6 @@ Set Implicit Arguments.
Require Import Notations.
Require Import Logic.
-Declare ML Module "nat_syntax_plugin".
(********************************************************************)
(** * Datatypes with zero and one element *)
diff --git a/theories/Init/Decimal.v b/theories/Init/Decimal.v
index 57163b1b..1ff00ec1 100644
--- a/theories/Init/Decimal.v
+++ b/theories/Init/Decimal.v
@@ -42,10 +42,10 @@ Notation zero := (D0 Nil).
Inductive int := Pos (d:uint) | Neg (d:uint).
-Delimit Scope uint_scope with uint.
-Bind Scope uint_scope with uint.
-Delimit Scope int_scope with int.
-Bind Scope int_scope with int.
+Delimit Scope dec_uint_scope with uint.
+Bind Scope dec_uint_scope with uint.
+Delimit Scope dec_int_scope with int.
+Bind Scope dec_int_scope with int.
(** This representation favors simplicity over canonicity.
For normalizing numbers, we need to remove head zero digits,
@@ -161,3 +161,9 @@ with succ_double d :=
end.
End Little.
+
+(** Pseudo-conversion functions used when declaring
+ Numeral Notations on [uint] and [int]. *)
+
+Definition uint_of_uint (i:uint) := i.
+Definition int_of_int (i:int) := i.
diff --git a/theories/Init/Logic.v b/theories/Init/Logic.v
index 15ca5abc..9d60cf54 100644
--- a/theories/Init/Logic.v
+++ b/theories/Init/Logic.v
@@ -29,6 +29,13 @@ Definition not (A:Prop) := A -> False.
Notation "~ x" := (not x) : type_scope.
+(** Create the "core" hint database, and set its transparent state for
+ variables and constants explicitely. *)
+
+Create HintDb core.
+Hint Variables Opaque : core.
+Hint Constants Opaque : core.
+
Hint Unfold not: core.
(** [and A B], written [A /\ B], is the conjunction of [A] and [B]
diff --git a/theories/Init/Nat.v b/theories/Init/Nat.v
index ad1bc717..eb4ba0e5 100644
--- a/theories/Init/Nat.v
+++ b/theories/Init/Nat.v
@@ -24,6 +24,10 @@ Definition t := nat.
(** ** Constants *)
+Local Notation "0" := O.
+Local Notation "1" := (S O).
+Local Notation "2" := (S (S O)).
+
Definition zero := 0.
Definition one := 1.
Definition two := 2.
diff --git a/theories/Init/Peano.v b/theories/Init/Peano.v
index d5322d09..65e5e76a 100644
--- a/theories/Init/Peano.v
+++ b/theories/Init/Peano.v
@@ -31,6 +31,7 @@ Require Import Logic.
Require Coq.Init.Nat.
Open Scope nat_scope.
+Local Notation "0" := O.
Definition eq_S := f_equal S.
Definition f_equal_nat := f_equal (A:=nat).
diff --git a/theories/Init/Prelude.v b/theories/Init/Prelude.v
index 802f18c0..6d98bcb3 100644
--- a/theories/Init/Prelude.v
+++ b/theories/Init/Prelude.v
@@ -19,9 +19,24 @@ Require Export Peano.
Require Export Coq.Init.Wf.
Require Export Coq.Init.Tactics.
Require Export Coq.Init.Tauto.
-(* Initially available plugins
- (+ nat_syntax_plugin loaded in Datatypes) *)
+(* Some initially available plugins. See also:
+ - ltac_plugin (in Notations)
+ - tauto_plugin (in Tauto).
+*)
Declare ML Module "cc_plugin".
Declare ML Module "ground_plugin".
+Declare ML Module "numeral_notation_plugin".
+
+(* Parsing / printing of decimal numbers *)
+Arguments Nat.of_uint d%dec_uint_scope.
+Arguments Nat.of_int d%dec_int_scope.
+Numeral Notation Decimal.uint Decimal.uint_of_uint Decimal.uint_of_uint
+ : dec_uint_scope.
+Numeral Notation Decimal.int Decimal.int_of_int Decimal.int_of_int
+ : dec_int_scope.
+
+(* Parsing / printing of [nat] numbers *)
+Numeral Notation nat Nat.of_uint Nat.to_uint : nat_scope (abstract after 5000).
+
(* Default substrings not considered by queries like SearchAbout *)
Add Search Blacklist "_subproof" "_subterm" "Private_".
diff --git a/theories/Init/Specif.v b/theories/Init/Specif.v
index b6afba29..76632312 100644
--- a/theories/Init/Specif.v
+++ b/theories/Init/Specif.v
@@ -745,16 +745,16 @@ Hint Resolve exist exist2 existT existT2: core.
(* Compatibility *)
-Notation sigS := sigT (compat "8.6").
-Notation existS := existT (compat "8.6").
-Notation sigS_rect := sigT_rect (compat "8.6").
-Notation sigS_rec := sigT_rec (compat "8.6").
-Notation sigS_ind := sigT_ind (compat "8.6").
-Notation projS1 := projT1 (compat "8.6").
-Notation projS2 := projT2 (compat "8.6").
-
-Notation sigS2 := sigT2 (compat "8.6").
-Notation existS2 := existT2 (compat "8.6").
-Notation sigS2_rect := sigT2_rect (compat "8.6").
-Notation sigS2_rec := sigT2_rec (compat "8.6").
-Notation sigS2_ind := sigT2_ind (compat "8.6").
+Notation sigS := sigT (compat "8.7").
+Notation existS := existT (compat "8.7").
+Notation sigS_rect := sigT_rect (compat "8.7").
+Notation sigS_rec := sigT_rec (compat "8.7").
+Notation sigS_ind := sigT_ind (compat "8.7").
+Notation projS1 := projT1 (compat "8.7").
+Notation projS2 := projT2 (compat "8.7").
+
+Notation sigS2 := sigT2 (compat "8.7").
+Notation existS2 := existT2 (compat "8.7").
+Notation sigS2_rect := sigT2_rect (compat "8.7").
+Notation sigS2_rec := sigT2_rec (compat "8.7").
+Notation sigS2_ind := sigT2_ind (compat "8.7").
diff --git a/theories/Logic/Berardi.v b/theories/Logic/Berardi.v
index c6836a1c..ed4d69ab 100644
--- a/theories/Logic/Berardi.v
+++ b/theories/Logic/Berardi.v
@@ -82,7 +82,7 @@ End Retracts.
(** This lemma is basically a commutation of implication and existential
quantification: (EX x | A -> P(x)) <=> (A -> EX x | P(x))
which is provable in classical logic ( => is already provable in
- intuitionnistic logic). *)
+ intuitionistic logic). *)
Lemma L1 : forall A B:Prop, retract_cond (pow A) (pow B).
Proof.
@@ -136,7 +136,7 @@ trivial.
Qed.
-Theorem classical_proof_irrelevence : T = F.
+Theorem classical_proof_irrelevance : T = F.
Proof.
generalize not_has_fixpoint.
unfold Not_b.
@@ -148,4 +148,7 @@ intros not_true is_true.
elim not_true; trivial.
Qed.
+
+Notation classical_proof_irrelevence := classical_proof_irrelevance (compat "8.8").
+
End Berardis_paradox.
diff --git a/theories/Logic/Diaconescu.v b/theories/Logic/Diaconescu.v
index 3317766c..66e82ddb 100644
--- a/theories/Logic/Diaconescu.v
+++ b/theories/Logic/Diaconescu.v
@@ -234,8 +234,6 @@ Qed.
(** An alternative more concise proof can be done by directly using
the guarded relational choice *)
-Declare Implicit Tactic auto.
-
Lemma proof_irrel_rel_choice_imp_eq_dec' : a1=a2 \/ ~a1=a2.
Proof.
assert (decide: forall x:A, x=a1 \/ x=a2 ->
diff --git a/theories/Logic/EqdepFacts.v b/theories/Logic/EqdepFacts.v
index d938b315..8e59941f 100644
--- a/theories/Logic/EqdepFacts.v
+++ b/theories/Logic/EqdepFacts.v
@@ -125,7 +125,7 @@ Proof.
apply eq_dep_intro.
Qed.
-Notation eq_sigS_eq_dep := eq_sigT_eq_dep (compat "8.6"). (* Compatibility *)
+Notation eq_sigS_eq_dep := eq_sigT_eq_dep (compat "8.7"). (* Compatibility *)
Lemma eq_dep_eq_sigT :
forall (U:Type) (P:U -> Type) (p q:U) (x:P p) (y:P q),
diff --git a/theories/MSets/MSetEqProperties.v b/theories/MSets/MSetEqProperties.v
index 1ee098cb..4f2fdcf9 100644
--- a/theories/MSets/MSetEqProperties.v
+++ b/theories/MSets/MSetEqProperties.v
@@ -333,7 +333,7 @@ Proof.
auto with set.
Qed.
-(* caracterisation of [union] via [subset] *)
+(* characterisation of [union] via [subset] *)
Lemma union_subset_1: subset s (union s s')=true.
Proof.
@@ -408,7 +408,7 @@ intros; apply equal_1; apply inter_add_2.
rewrite not_mem_iff; auto.
Qed.
-(* caracterisation of [union] via [subset] *)
+(* characterisation of [union] via [subset] *)
Lemma inter_subset_1: subset (inter s s') s=true.
Proof.
diff --git a/theories/NArith/BinNat.v b/theories/NArith/BinNat.v
index 5d3ec5ab..92c124ec 100644
--- a/theories/NArith/BinNat.v
+++ b/theories/NArith/BinNat.v
@@ -930,6 +930,8 @@ Bind Scope N_scope with N.t N.
(** Exportation of notations *)
+Numeral Notation N N.of_uint N.to_uint : N_scope.
+
Infix "+" := N.add : N_scope.
Infix "-" := N.sub : N_scope.
Infix "*" := N.mul : N_scope.
@@ -964,33 +966,33 @@ Notation N_ind := N_ind (only parsing).
Notation N0 := N0 (only parsing).
Notation Npos := N.pos (only parsing).
-Notation Ndiscr := N.discr (compat "8.6").
+Notation Ndiscr := N.discr (compat "8.7").
Notation Ndouble_plus_one := N.succ_double (only parsing).
-Notation Ndouble := N.double (compat "8.6").
-Notation Nsucc := N.succ (compat "8.6").
-Notation Npred := N.pred (compat "8.6").
-Notation Nsucc_pos := N.succ_pos (compat "8.6").
-Notation Ppred_N := Pos.pred_N (compat "8.6").
+Notation Ndouble := N.double (compat "8.7").
+Notation Nsucc := N.succ (compat "8.7").
+Notation Npred := N.pred (compat "8.7").
+Notation Nsucc_pos := N.succ_pos (compat "8.7").
+Notation Ppred_N := Pos.pred_N (compat "8.7").
Notation Nplus := N.add (only parsing).
Notation Nminus := N.sub (only parsing).
Notation Nmult := N.mul (only parsing).
-Notation Neqb := N.eqb (compat "8.6").
-Notation Ncompare := N.compare (compat "8.6").
-Notation Nlt := N.lt (compat "8.6").
-Notation Ngt := N.gt (compat "8.6").
-Notation Nle := N.le (compat "8.6").
-Notation Nge := N.ge (compat "8.6").
-Notation Nmin := N.min (compat "8.6").
-Notation Nmax := N.max (compat "8.6").
-Notation Ndiv2 := N.div2 (compat "8.6").
-Notation Neven := N.even (compat "8.6").
-Notation Nodd := N.odd (compat "8.6").
-Notation Npow := N.pow (compat "8.6").
-Notation Nlog2 := N.log2 (compat "8.6").
+Notation Neqb := N.eqb (compat "8.7").
+Notation Ncompare := N.compare (compat "8.7").
+Notation Nlt := N.lt (compat "8.7").
+Notation Ngt := N.gt (compat "8.7").
+Notation Nle := N.le (compat "8.7").
+Notation Nge := N.ge (compat "8.7").
+Notation Nmin := N.min (compat "8.7").
+Notation Nmax := N.max (compat "8.7").
+Notation Ndiv2 := N.div2 (compat "8.7").
+Notation Neven := N.even (compat "8.7").
+Notation Nodd := N.odd (compat "8.7").
+Notation Npow := N.pow (compat "8.7").
+Notation Nlog2 := N.log2 (compat "8.7").
Notation nat_of_N := N.to_nat (only parsing).
Notation N_of_nat := N.of_nat (only parsing).
-Notation N_eq_dec := N.eq_dec (compat "8.6").
+Notation N_eq_dec := N.eq_dec (compat "8.7").
Notation Nrect := N.peano_rect (only parsing).
Notation Nrect_base := N.peano_rect_base (only parsing).
Notation Nrect_step := N.peano_rect_succ (only parsing).
@@ -999,11 +1001,11 @@ Notation Nrec := N.peano_rec (only parsing).
Notation Nrec_base := N.peano_rec_base (only parsing).
Notation Nrec_succ := N.peano_rec_succ (only parsing).
-Notation Npred_succ := N.pred_succ (compat "8.6").
+Notation Npred_succ := N.pred_succ (compat "8.7").
Notation Npred_minus := N.pred_sub (only parsing).
-Notation Nsucc_pred := N.succ_pred (compat "8.6").
+Notation Nsucc_pred := N.succ_pred (compat "8.7").
Notation Ppred_N_spec := N.pos_pred_spec (only parsing).
-Notation Nsucc_pos_spec := N.succ_pos_spec (compat "8.6").
+Notation Nsucc_pos_spec := N.succ_pos_spec (compat "8.7").
Notation Ppred_Nsucc := N.pos_pred_succ (only parsing).
Notation Nplus_0_l := N.add_0_l (only parsing).
Notation Nplus_0_r := N.add_0_r (only parsing).
@@ -1011,7 +1013,7 @@ Notation Nplus_comm := N.add_comm (only parsing).
Notation Nplus_assoc := N.add_assoc (only parsing).
Notation Nplus_succ := N.add_succ_l (only parsing).
Notation Nsucc_0 := N.succ_0_discr (only parsing).
-Notation Nsucc_inj := N.succ_inj (compat "8.6").
+Notation Nsucc_inj := N.succ_inj (compat "8.7").
Notation Nminus_N0_Nle := N.sub_0_le (only parsing).
Notation Nminus_0_r := N.sub_0_r (only parsing).
Notation Nminus_succ_r:= N.sub_succ_r (only parsing).
@@ -1021,29 +1023,29 @@ Notation Nmult_1_r := N.mul_1_r (only parsing).
Notation Nmult_comm := N.mul_comm (only parsing).
Notation Nmult_assoc := N.mul_assoc (only parsing).
Notation Nmult_plus_distr_r := N.mul_add_distr_r (only parsing).
-Notation Neqb_eq := N.eqb_eq (compat "8.6").
+Notation Neqb_eq := N.eqb_eq (compat "8.7").
Notation Nle_0 := N.le_0_l (only parsing).
-Notation Ncompare_refl := N.compare_refl (compat "8.6").
+Notation Ncompare_refl := N.compare_refl (compat "8.7").
Notation Ncompare_Eq_eq := N.compare_eq (only parsing).
Notation Ncompare_eq_correct := N.compare_eq_iff (only parsing).
-Notation Nlt_irrefl := N.lt_irrefl (compat "8.6").
-Notation Nlt_trans := N.lt_trans (compat "8.6").
+Notation Nlt_irrefl := N.lt_irrefl (compat "8.7").
+Notation Nlt_trans := N.lt_trans (compat "8.7").
Notation Nle_lteq := N.lt_eq_cases (only parsing).
-Notation Nlt_succ_r := N.lt_succ_r (compat "8.6").
-Notation Nle_trans := N.le_trans (compat "8.6").
-Notation Nle_succ_l := N.le_succ_l (compat "8.6").
-Notation Ncompare_spec := N.compare_spec (compat "8.6").
+Notation Nlt_succ_r := N.lt_succ_r (compat "8.7").
+Notation Nle_trans := N.le_trans (compat "8.7").
+Notation Nle_succ_l := N.le_succ_l (compat "8.7").
+Notation Ncompare_spec := N.compare_spec (compat "8.7").
Notation Ncompare_0 := N.compare_0_r (only parsing).
Notation Ndouble_div2 := N.div2_double (only parsing).
Notation Ndouble_plus_one_div2 := N.div2_succ_double (only parsing).
-Notation Ndouble_inj := N.double_inj (compat "8.6").
+Notation Ndouble_inj := N.double_inj (compat "8.7").
Notation Ndouble_plus_one_inj := N.succ_double_inj (only parsing).
-Notation Npow_0_r := N.pow_0_r (compat "8.6").
-Notation Npow_succ_r := N.pow_succ_r (compat "8.6").
-Notation Nlog2_spec := N.log2_spec (compat "8.6").
-Notation Nlog2_nonpos := N.log2_nonpos (compat "8.6").
-Notation Neven_spec := N.even_spec (compat "8.6").
-Notation Nodd_spec := N.odd_spec (compat "8.6").
+Notation Npow_0_r := N.pow_0_r (compat "8.7").
+Notation Npow_succ_r := N.pow_succ_r (compat "8.7").
+Notation Nlog2_spec := N.log2_spec (compat "8.7").
+Notation Nlog2_nonpos := N.log2_nonpos (compat "8.7").
+Notation Neven_spec := N.even_spec (compat "8.7").
+Notation Nodd_spec := N.odd_spec (compat "8.7").
Notation Nlt_not_eq := N.lt_neq (only parsing).
Notation Ngt_Nlt := N.gt_lt (only parsing).
diff --git a/theories/NArith/BinNatDef.v b/theories/NArith/BinNatDef.v
index 5de75537..be12fffa 100644
--- a/theories/NArith/BinNatDef.v
+++ b/theories/NArith/BinNatDef.v
@@ -13,6 +13,10 @@ Require Import BinPos.
Local Open Scope N_scope.
+Local Notation "0" := N0.
+Local Notation "1" := (Npos 1).
+Local Notation "2" := (Npos 2).
+
(**********************************************************************)
(** * Binary natural numbers, definitions of operations *)
(**********************************************************************)
@@ -398,4 +402,9 @@ Definition to_uint n :=
Definition to_int n := Decimal.Pos (to_uint n).
+Numeral Notation N of_uint to_uint : N_scope.
+
End N.
+
+(** Re-export the notation for those who just [Import NatIntDef] *)
+Numeral Notation N N.of_uint N.to_uint : N_scope.
diff --git a/theories/NArith/Ndec.v b/theories/NArith/Ndec.v
index 67c30f22..e2b2b490 100644
--- a/theories/NArith/Ndec.v
+++ b/theories/NArith/Ndec.v
@@ -22,8 +22,8 @@ Local Open Scope N_scope.
(** Obsolete results about boolean comparisons over [N],
kept for compatibility with IntMap and SMC. *)
-Notation Peqb := Pos.eqb (compat "8.6").
-Notation Neqb := N.eqb (compat "8.6").
+Notation Peqb := Pos.eqb (compat "8.7").
+Notation Neqb := N.eqb (compat "8.7").
Notation Peqb_correct := Pos.eqb_refl (only parsing).
Notation Neqb_correct := N.eqb_refl (only parsing).
Notation Neqb_comm := N.eqb_sym (only parsing).
diff --git a/theories/NArith/Ndigits.v b/theories/NArith/Ndigits.v
index 3ccaa721..a2a2430e 100644
--- a/theories/NArith/Ndigits.v
+++ b/theories/NArith/Ndigits.v
@@ -517,6 +517,23 @@ Definition N2Bv (n:N) : Bvector (N.size_nat n) :=
| Npos p => P2Bv p
end.
+Fixpoint P2Bv_sized (m : nat) (p : positive) : Bvector m :=
+ match m with
+ | O => []
+ | S m =>
+ match p with
+ | xI p => true :: P2Bv_sized m p
+ | xO p => false :: P2Bv_sized m p
+ | xH => true :: Bvect_false m
+ end
+ end.
+
+Definition N2Bv_sized (m : nat) (n : N) : Bvector m :=
+ match n with
+ | N0 => Bvect_false m
+ | Npos p => P2Bv_sized m p
+ end.
+
Fixpoint Bv2N (n:nat)(bv:Bvector n) : N :=
match bv with
| Vector.nil _ => N0
@@ -561,6 +578,7 @@ Qed.
(** To state nonetheless a second result about composition of
conversions, we define a conversion on a given number of bits : *)
+#[deprecated(since = "8.9.0", note = "Use N2Bv_sized instead.")]
Fixpoint N2Bv_gen (n:nat)(a:N) : Bvector n :=
match n return Bvector n with
| 0 => Bnil
@@ -670,3 +688,28 @@ rewrite H.
destruct a, b, (Bv2N n v1), (Bv2N n v2);
simpl; auto.
Qed.
+
+Lemma N2Bv_sized_Nsize (n : N) :
+ N2Bv_sized (N.size_nat n) n = N2Bv n.
+Proof with simpl; auto.
+ destruct n...
+ induction p...
+ all: rewrite IHp...
+Qed.
+
+Lemma N2Bv_sized_Bv2N (n : nat) (v : Bvector n) :
+ N2Bv_sized n (Bv2N n v) = v.
+Proof with simpl; auto.
+ induction v...
+ destruct h;
+ unfold N2Bv_sized;
+ destruct (Bv2N n v) as [|[]];
+ rewrite <- IHv...
+Qed.
+
+Lemma N2Bv_N2Bv_sized_above (a : N) (k : nat) :
+ N2Bv_sized (N.size_nat a + k) a = N2Bv a ++ Bvect_false k.
+Proof with auto.
+ destruct a...
+ induction p; simpl; f_equal...
+Qed.
diff --git a/theories/NArith/Ndiv_def.v b/theories/NArith/Ndiv_def.v
index 7c9fd869..885c0d48 100644
--- a/theories/NArith/Ndiv_def.v
+++ b/theories/NArith/Ndiv_def.v
@@ -24,10 +24,10 @@ Lemma Pdiv_eucl_remainder a b :
snd (Pdiv_eucl a b) < Npos b.
Proof. now apply (N.pos_div_eucl_remainder a (Npos b)). Qed.
-Notation Ndiv_eucl := N.div_eucl (compat "8.6").
-Notation Ndiv := N.div (compat "8.6").
+Notation Ndiv_eucl := N.div_eucl (compat "8.7").
+Notation Ndiv := N.div (compat "8.7").
Notation Nmod := N.modulo (only parsing).
Notation Ndiv_eucl_correct := N.div_eucl_spec (only parsing).
Notation Ndiv_mod_eq := N.div_mod' (only parsing).
-Notation Nmod_lt := N.mod_lt (compat "8.6").
+Notation Nmod_lt := N.mod_lt (compat "8.7").
diff --git a/theories/NArith/Nsqrt_def.v b/theories/NArith/Nsqrt_def.v
index e771fe91..f0433283 100644
--- a/theories/NArith/Nsqrt_def.v
+++ b/theories/NArith/Nsqrt_def.v
@@ -13,8 +13,8 @@ Require Import BinNat.
(** Obsolete file, see [BinNat] now,
only compatibility notations remain here. *)
-Notation Nsqrtrem := N.sqrtrem (compat "8.6").
-Notation Nsqrt := N.sqrt (compat "8.6").
-Notation Nsqrtrem_spec := N.sqrtrem_spec (compat "8.6").
+Notation Nsqrtrem := N.sqrtrem (compat "8.7").
+Notation Nsqrt := N.sqrt (compat "8.7").
+Notation Nsqrtrem_spec := N.sqrtrem_spec (compat "8.7").
Notation Nsqrt_spec := (fun n => N.sqrt_spec n (N.le_0_l n)) (only parsing).
-Notation Nsqrtrem_sqrt := N.sqrtrem_sqrt (compat "8.6").
+Notation Nsqrtrem_sqrt := N.sqrtrem_sqrt (compat "8.7").
diff --git a/theories/Numbers/AltBinNotations.v b/theories/Numbers/AltBinNotations.v
new file mode 100644
index 00000000..c7e39996
--- /dev/null
+++ b/theories/Numbers/AltBinNotations.v
@@ -0,0 +1,69 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** * Alternative Binary Numeral Notations *)
+
+(** Faster but less safe parsers and printers of [positive], [N], [Z]. *)
+
+(** By default, literals in types [positive], [N], [Z] are parsed and
+ printed via the [Numeral Notation] command, by conversion from/to
+ the [Decimal.int] representation. When working with numbers with
+ thousands of digits and more, conversion from/to [Decimal.int] can
+ become significantly slow. If that becomes a problem for your
+ development, this file provides some alternative [Numeral
+ Notation] commmands that use [Z] as bridge type. To enable these
+ commands, just be sure to [Require] this file after other files
+ defining numeral notations.
+
+ Note: up to Coq 8.8, literals in types [positive], [N], [Z] were
+ parsed and printed using a native ML library of arbitrary
+ precision integers named bigint.ml. From 8.9, the default is to
+ parse and print using a Coq library converting sequences of
+ digits, hence reducing the amount of ML code to trust. But this
+ method is slower. This file then gives access to the legacy
+ method, trading efficiency against a larger ML trust base relying
+ on bigint.ml. *)
+
+Require Import BinNums.
+
+(** [positive] *)
+
+Definition pos_of_z z :=
+ match z with
+ | Zpos p => Some p
+ | _ => None
+ end.
+
+Definition pos_to_z p := Zpos p.
+
+Numeral Notation positive pos_of_z pos_to_z : positive_scope.
+
+(** [N] *)
+
+Definition n_of_z z :=
+ match z with
+ | Z0 => Some N0
+ | Zpos p => Some (Npos p)
+ | Zneg _ => None
+ end.
+
+Definition n_to_z n :=
+ match n with
+ | N0 => Z0
+ | Npos p => Zpos p
+ end.
+
+Numeral Notation N n_of_z n_to_z : N_scope.
+
+(** [Z] *)
+
+Definition z_of_z (z:Z) := z.
+
+Numeral Notation Z z_of_z z_of_z : Z_scope.
diff --git a/theories/Numbers/BinNums.v b/theories/Numbers/BinNums.v
index f8b3d9e1..3ba9d1f5 100644
--- a/theories/Numbers/BinNums.v
+++ b/theories/Numbers/BinNums.v
@@ -12,13 +12,11 @@
Set Implicit Arguments.
-Declare ML Module "z_syntax_plugin".
-
(** [positive] is a datatype representing the strictly positive integers
in a binary way. Starting from 1 (represented by [xH]), one can
add a new least significant digit via [xO] (digit 0) or [xI] (digit 1).
- Numbers in [positive] can also be denoted using a decimal notation;
- e.g. [6%positive] abbreviates [xO (xI xH)] *)
+ Numbers in [positive] will also be denoted using a decimal notation;
+ e.g. [6%positive] will abbreviate [xO (xI xH)] *)
Inductive positive : Set :=
| xI : positive -> positive
@@ -32,8 +30,8 @@ Arguments xI _%positive.
(** [N] is a datatype representing natural numbers in a binary way,
by extending the [positive] datatype with a zero.
- Numbers in [N] can also be denoted using a decimal notation;
- e.g. [6%N] abbreviates [Npos (xO (xI xH))] *)
+ Numbers in [N] will also be denoted using a decimal notation;
+ e.g. [6%N] will abbreviate [Npos (xO (xI xH))] *)
Inductive N : Set :=
| N0 : N
@@ -47,8 +45,8 @@ Arguments Npos _%positive.
An integer is either zero or a strictly positive number
(coded as a [positive]) or a strictly negative number
(whose opposite is stored as a [positive] value).
- Numbers in [Z] can also be denoted using a decimal notation;
- e.g. [(-6)%Z] abbreviates [Zneg (xO (xI xH))] *)
+ Numbers in [Z] will also be denoted using a decimal notation;
+ e.g. [(-6)%Z] will abbreviate [Zneg (xO (xI xH))] *)
Inductive Z : Set :=
| Z0 : Z
diff --git a/theories/Numbers/Cyclic/Int31/Cyclic31.v b/theories/Numbers/Cyclic/Int31/Cyclic31.v
index bd4f0279..4a1f24b9 100644
--- a/theories/Numbers/Cyclic/Int31/Cyclic31.v
+++ b/theories/Numbers/Cyclic/Int31/Cyclic31.v
@@ -21,9 +21,7 @@ Require Import Znumtheory.
Require Import Zgcd_alt.
Require Import Zpow_facts.
Require Import CyclicAxioms.
-Require Import ROmega.
-
-Declare ML Module "int31_syntax_plugin".
+Require Import Lia.
Local Open Scope nat_scope.
Local Open Scope int31_scope.
@@ -128,7 +126,7 @@ Section Basics.
Lemma nshiftl_S_tail :
forall n x, nshiftl x (S n) = nshiftl (shiftl x) n.
- Proof.
+ Proof.
intros n; elim n; simpl; intros; now f_equal.
Qed.
@@ -1239,7 +1237,7 @@ Section Int31_Specs.
destruct (Z_lt_le_dec (X+Y) wB).
contradict H1; auto using Zmod_small with zarith.
rewrite <- (Z_mod_plus_full (X+Y) (-1) wB).
- rewrite Zmod_small; romega.
+ rewrite Zmod_small; lia.
generalize (Z.compare_eq ((X+Y) mod wB) (X+Y)); intros Heq.
destruct Z.compare; intros;
@@ -1263,7 +1261,7 @@ Section Int31_Specs.
destruct (Z_lt_le_dec (X+Y+1) wB).
contradict H1; auto using Zmod_small with zarith.
rewrite <- (Z_mod_plus_full (X+Y+1) (-1) wB).
- rewrite Zmod_small; romega.
+ rewrite Zmod_small; lia.
generalize (Z.compare_eq ((X+Y+1) mod wB) (X+Y+1)); intros Heq.
destruct Z.compare; intros;
@@ -1301,8 +1299,8 @@ Section Int31_Specs.
unfold interp_carry; rewrite phi_phi_inv, Z.compare_eq_iff; intros.
destruct (Z_lt_le_dec (X-Y) 0).
rewrite <- (Z_mod_plus_full (X-Y) 1 wB).
- rewrite Zmod_small; romega.
- contradict H1; apply Zmod_small; romega.
+ rewrite Zmod_small; lia.
+ contradict H1; apply Zmod_small; lia.
generalize (Z.compare_eq ((X-Y) mod wB) (X-Y)); intros Heq.
destruct Z.compare; intros;
@@ -1320,8 +1318,8 @@ Section Int31_Specs.
unfold interp_carry; rewrite phi_phi_inv, Z.compare_eq_iff; intros.
destruct (Z_lt_le_dec (X-Y-1) 0).
rewrite <- (Z_mod_plus_full (X-Y-1) 1 wB).
- rewrite Zmod_small; romega.
- contradict H1; apply Zmod_small; romega.
+ rewrite Zmod_small; lia.
+ contradict H1; apply Zmod_small; lia.
generalize (Z.compare_eq ((X-Y-1) mod wB) (X-Y-1)); intros Heq.
destruct Z.compare; intros;
@@ -1358,7 +1356,7 @@ Section Int31_Specs.
change [|1|] with 1; change [|0|] with 0.
rewrite <- (Z_mod_plus_full (0-[|x|]) 1 wB).
rewrite Zminus_mod_idemp_l.
- rewrite Zmod_small; generalize (phi_bounded x); romega.
+ rewrite Zmod_small; generalize (phi_bounded x); lia.
Qed.
Lemma spec_pred_c : forall x, [-|sub31c x 1|] = [|x|] - 1.
diff --git a/theories/Numbers/Cyclic/Int31/Int31.v b/theories/Numbers/Cyclic/Int31/Int31.v
index 9f8da831..927f430f 100644
--- a/theories/Numbers/Cyclic/Int31/Int31.v
+++ b/theories/Numbers/Cyclic/Int31/Int31.v
@@ -15,11 +15,15 @@ Require Import Wf_nat.
Require Export ZArith.
Require Export DoubleType.
+Declare ML Module "int31_syntax_plugin".
+
+Local Unset Elimination Schemes.
+
(** * 31-bit integers *)
(** This file contains basic definitions of a 31-bit integer
arithmetic. In fact it is more general than that. The only reason
- for this use of 31 is the underlying mecanism for hardware-efficient
+ for this use of 31 is the underlying mechanism for hardware-efficient
computations by A. Spiwack. Apart from this, a switch to, say,
63-bit integers is now just a matter of replacing every occurrences
of 31 by 63. This is actually made possible by the use of
@@ -48,6 +52,10 @@ Inductive int31 : Type := I31 : digits31 int31.
Register digits as int31 bits in "coq_int31" by True.
Register int31 as int31 type in "coq_int31" by True.
+Scheme int31_ind := Induction for int31 Sort Prop.
+Scheme int31_rec := Induction for int31 Sort Set.
+Scheme int31_rect := Induction for int31 Sort Type.
+
Delimit Scope int31_scope with int31.
Bind Scope int31_scope with int31.
Local Open Scope int31_scope.
diff --git a/theories/Numbers/DecimalString.v b/theories/Numbers/DecimalString.v
index 1a3220f6..591024ba 100644
--- a/theories/Numbers/DecimalString.v
+++ b/theories/Numbers/DecimalString.v
@@ -94,7 +94,7 @@ Definition int_of_string s :=
match s with
| EmptyString => Some (Pos Nil)
| String a s' =>
- if ascii_dec a "-" then option_map Neg (uint_of_string s')
+ if Ascii.eqb a "-" then option_map Neg (uint_of_string s')
else option_map Pos (uint_of_string s)
end.
@@ -131,8 +131,8 @@ Proof.
- unfold int_of_string.
destruct (string_of_uint d) eqn:Hd.
+ now destruct d.
- + destruct ascii_dec; subst.
- * now destruct d.
+ + case Ascii.eqb_spec.
+ * intros ->. now destruct d.
* rewrite <- Hd, usu; auto.
- rewrite usu; auto.
Qed.
@@ -141,8 +141,8 @@ Lemma sis s d :
int_of_string s = Some d -> string_of_int d = s.
Proof.
destruct s; [intros [= <-]| ]; simpl; trivial.
- destruct ascii_dec; subst; simpl.
- - destruct (uint_of_string s) eqn:Hs; simpl; intros [= <-].
+ case Ascii.eqb_spec.
+ - intros ->. destruct (uint_of_string s) eqn:Hs; simpl; intros [= <-].
simpl; f_equal. now apply sus.
- destruct d; [ | now destruct uint_of_char].
simpl string_of_int.
@@ -178,7 +178,7 @@ Definition int_of_string s :=
match s with
| EmptyString => None
| String a s' =>
- if ascii_dec a "-" then option_map Neg (uint_of_string s')
+ if Ascii.eqb a "-" then option_map Neg (uint_of_string s')
else option_map Pos (uint_of_string s)
end.
@@ -228,8 +228,8 @@ Proof.
unfold int_of_string.
destruct (string_of_uint d) eqn:Hd.
+ now destruct d.
- + destruct ascii_dec; subst.
- * now destruct d.
+ + case Ascii.eqb_spec.
+ * intros ->. now destruct d.
* rewrite <- Hd, usu; auto. now intros ->.
- intros _ H.
rewrite usu; auto. now intros ->.
@@ -253,8 +253,8 @@ Lemma sis s d :
int_of_string s = Some d -> string_of_int d = s.
Proof.
destruct s; [intros [=]| ]; simpl.
- destruct ascii_dec; subst; simpl.
- - destruct (uint_of_string s) eqn:Hs; simpl; intros [= <-].
+ case Ascii.eqb_spec.
+ - intros ->. destruct (uint_of_string s) eqn:Hs; simpl; intros [= <-].
simpl; f_equal. now apply sus.
- destruct d; [ | now destruct uint_of_char].
simpl string_of_int.
diff --git a/theories/Numbers/Integer/Abstract/ZBits.v b/theories/Numbers/Integer/Abstract/ZBits.v
index 2da44528..4aabda77 100644
--- a/theories/Numbers/Integer/Abstract/ZBits.v
+++ b/theories/Numbers/Integer/Abstract/ZBits.v
@@ -80,7 +80,7 @@ Proof.
now apply testbit_even_succ.
Qed.
-(** Alternative caracterisations of [testbit] *)
+(** Alternative characterisations of [testbit] *)
(** This concise equation could have been taken as specification
for testbit in the interface, but it would have been hard to
@@ -102,10 +102,10 @@ Proof.
left. destruct b; split; simpl; order'.
Qed.
-(** This caracterisation that uses only basic operations and
+(** This characterisation that uses only basic operations and
power was initially taken as specification for testbit.
We describe [a] as having a low part and a high part, with
- the corresponding bit in the middle. This caracterisation
+ the corresponding bit in the middle. This characterisation
is moderatly complex to implement, but also moderately
usable... *)
diff --git a/theories/Numbers/Integer/Abstract/ZDivEucl.v b/theories/Numbers/Integer/Abstract/ZDivEucl.v
index d7f25a66..5a7bd9ab 100644
--- a/theories/Numbers/Integer/Abstract/ZDivEucl.v
+++ b/theories/Numbers/Integer/Abstract/ZDivEucl.v
@@ -13,7 +13,7 @@ Require Import ZAxioms ZMulOrder ZSgnAbs NZDiv.
(** * Euclidean Division for integers, Euclid convention
We use here the "usual" formulation of the Euclid Theorem
- [forall a b, b<>0 -> exists b q, a = b*q+r /\ 0 < r < |b| ]
+ [forall a b, b<>0 -> exists r q, a = b*q+r /\ 0 <= r < |b| ]
The outcome of the modulo function is hence always positive.
This corresponds to convention "E" in the following paper:
diff --git a/theories/Numbers/Natural/Abstract/NBits.v b/theories/Numbers/Natural/Abstract/NBits.v
index e1391f59..90663de3 100644
--- a/theories/Numbers/Natural/Abstract/NBits.v
+++ b/theories/Numbers/Natural/Abstract/NBits.v
@@ -78,7 +78,7 @@ Proof.
apply testbit_even_succ, le_0_l.
Qed.
-(** Alternative caracterisations of [testbit] *)
+(** Alternative characterisations of [testbit] *)
(** This concise equation could have been taken as specification
for testbit in the interface, but it would have been hard to
@@ -99,10 +99,10 @@ Proof.
destruct b; order'.
Qed.
-(** This caracterisation that uses only basic operations and
+(** This characterisation that uses only basic operations and
power was initially taken as specification for testbit.
We describe [a] as having a low part and a high part, with
- the corresponding bit in the middle. This caracterisation
+ the corresponding bit in the middle. This characterisation
is moderatly complex to implement, but also moderately
usable... *)
diff --git a/theories/PArith/BinPos.v b/theories/PArith/BinPos.v
index 000d895e..01ecdd71 100644
--- a/theories/PArith/BinPos.v
+++ b/theories/PArith/BinPos.v
@@ -1871,6 +1871,8 @@ Bind Scope positive_scope with Pos.t positive.
(** Exportation of notations *)
+Numeral Notation positive Pos.of_int Pos.to_uint : positive_scope.
+
Infix "+" := Pos.add : positive_scope.
Infix "-" := Pos.sub : positive_scope.
Infix "*" := Pos.mul : positive_scope.
@@ -1905,12 +1907,12 @@ Notation IsNul := Pos.IsNul (only parsing).
Notation IsPos := Pos.IsPos (only parsing).
Notation IsNeg := Pos.IsNeg (only parsing).
-Notation Psucc := Pos.succ (compat "8.6").
+Notation Psucc := Pos.succ (compat "8.7").
Notation Pplus := Pos.add (only parsing).
Notation Pplus_carry := Pos.add_carry (only parsing).
-Notation Ppred := Pos.pred (compat "8.6").
-Notation Piter_op := Pos.iter_op (compat "8.6").
-Notation Piter_op_succ := Pos.iter_op_succ (compat "8.6").
+Notation Ppred := Pos.pred (compat "8.7").
+Notation Piter_op := Pos.iter_op (compat "8.7").
+Notation Piter_op_succ := Pos.iter_op_succ (compat "8.7").
Notation Pmult_nat := (Pos.iter_op plus) (only parsing).
Notation nat_of_P := Pos.to_nat (only parsing).
Notation P_of_succ_nat := Pos.of_succ_nat (only parsing).
@@ -1920,29 +1922,29 @@ Notation positive_mask_rect := Pos.mask_rect (only parsing).
Notation positive_mask_ind := Pos.mask_ind (only parsing).
Notation positive_mask_rec := Pos.mask_rec (only parsing).
Notation Pdouble_plus_one_mask := Pos.succ_double_mask (only parsing).
-Notation Pdouble_mask := Pos.double_mask (compat "8.6").
+Notation Pdouble_mask := Pos.double_mask (compat "8.7").
Notation Pdouble_minus_two := Pos.double_pred_mask (only parsing).
Notation Pminus_mask := Pos.sub_mask (only parsing).
Notation Pminus_mask_carry := Pos.sub_mask_carry (only parsing).
Notation Pminus := Pos.sub (only parsing).
Notation Pmult := Pos.mul (only parsing).
Notation iter_pos := @Pos.iter (only parsing).
-Notation Ppow := Pos.pow (compat "8.6").
-Notation Pdiv2 := Pos.div2 (compat "8.6").
-Notation Pdiv2_up := Pos.div2_up (compat "8.6").
+Notation Ppow := Pos.pow (compat "8.7").
+Notation Pdiv2 := Pos.div2 (compat "8.7").
+Notation Pdiv2_up := Pos.div2_up (compat "8.7").
Notation Psize := Pos.size_nat (only parsing).
Notation Psize_pos := Pos.size (only parsing).
Notation Pcompare x y m := (Pos.compare_cont m x y) (only parsing).
-Notation Plt := Pos.lt (compat "8.6").
-Notation Pgt := Pos.gt (compat "8.6").
-Notation Ple := Pos.le (compat "8.6").
-Notation Pge := Pos.ge (compat "8.6").
-Notation Pmin := Pos.min (compat "8.6").
-Notation Pmax := Pos.max (compat "8.6").
-Notation Peqb := Pos.eqb (compat "8.6").
+Notation Plt := Pos.lt (compat "8.7").
+Notation Pgt := Pos.gt (compat "8.7").
+Notation Ple := Pos.le (compat "8.7").
+Notation Pge := Pos.ge (compat "8.7").
+Notation Pmin := Pos.min (compat "8.7").
+Notation Pmax := Pos.max (compat "8.7").
+Notation Peqb := Pos.eqb (compat "8.7").
Notation positive_eq_dec := Pos.eq_dec (only parsing).
Notation xI_succ_xO := Pos.xI_succ_xO (only parsing).
-Notation Psucc_discr := Pos.succ_discr (compat "8.6").
+Notation Psucc_discr := Pos.succ_discr (compat "8.7").
Notation Psucc_o_double_minus_one_eq_xO :=
Pos.succ_pred_double (only parsing).
Notation Pdouble_minus_one_o_succ_eq_xI :=
@@ -1951,9 +1953,9 @@ Notation xO_succ_permute := Pos.double_succ (only parsing).
Notation double_moins_un_xO_discr :=
Pos.pred_double_xO_discr (only parsing).
Notation Psucc_not_one := Pos.succ_not_1 (only parsing).
-Notation Ppred_succ := Pos.pred_succ (compat "8.6").
+Notation Ppred_succ := Pos.pred_succ (compat "8.7").
Notation Psucc_pred := Pos.succ_pred_or (only parsing).
-Notation Psucc_inj := Pos.succ_inj (compat "8.6").
+Notation Psucc_inj := Pos.succ_inj (compat "8.7").
Notation Pplus_carry_spec := Pos.add_carry_spec (only parsing).
Notation Pplus_comm := Pos.add_comm (only parsing).
Notation Pplus_succ_permute_r := Pos.add_succ_r (only parsing).
@@ -2000,17 +2002,17 @@ Notation Pmult_xO_discr := Pos.mul_xO_discr (only parsing).
Notation Pmult_reg_r := Pos.mul_reg_r (only parsing).
Notation Pmult_reg_l := Pos.mul_reg_l (only parsing).
Notation Pmult_1_inversion_l := Pos.mul_eq_1_l (only parsing).
-Notation Psquare_xO := Pos.square_xO (compat "8.6").
-Notation Psquare_xI := Pos.square_xI (compat "8.6").
+Notation Psquare_xO := Pos.square_xO (compat "8.7").
+Notation Psquare_xI := Pos.square_xI (compat "8.7").
Notation iter_pos_swap_gen := Pos.iter_swap_gen (only parsing).
Notation iter_pos_swap := Pos.iter_swap (only parsing).
Notation iter_pos_succ := Pos.iter_succ (only parsing).
Notation iter_pos_plus := Pos.iter_add (only parsing).
Notation iter_pos_invariant := Pos.iter_invariant (only parsing).
-Notation Ppow_1_r := Pos.pow_1_r (compat "8.6").
-Notation Ppow_succ_r := Pos.pow_succ_r (compat "8.6").
-Notation Peqb_refl := Pos.eqb_refl (compat "8.6").
-Notation Peqb_eq := Pos.eqb_eq (compat "8.6").
+Notation Ppow_1_r := Pos.pow_1_r (compat "8.7").
+Notation Ppow_succ_r := Pos.pow_succ_r (compat "8.7").
+Notation Peqb_refl := Pos.eqb_refl (compat "8.7").
+Notation Peqb_eq := Pos.eqb_eq (compat "8.7").
Notation Pcompare_refl_id := Pos.compare_cont_refl (only parsing).
Notation Pcompare_eq_iff := Pos.compare_eq_iff (only parsing).
Notation Pcompare_Gt_Lt := Pos.compare_cont_Gt_Lt (only parsing).
@@ -2020,23 +2022,23 @@ Notation Pcompare_Lt_Gt := Pos.compare_cont_Lt_Gt (only parsing).
Notation Pcompare_antisym := Pos.compare_cont_antisym (only parsing).
Notation ZC1 := Pos.gt_lt (only parsing).
Notation ZC2 := Pos.lt_gt (only parsing).
-Notation Pcompare_spec := Pos.compare_spec (compat "8.6").
+Notation Pcompare_spec := Pos.compare_spec (compat "8.7").
Notation Pcompare_p_Sp := Pos.lt_succ_diag_r (only parsing).
-Notation Pcompare_succ_succ := Pos.compare_succ_succ (compat "8.6").
+Notation Pcompare_succ_succ := Pos.compare_succ_succ (compat "8.7").
Notation Pcompare_1 := Pos.nlt_1_r (only parsing).
Notation Plt_1 := Pos.nlt_1_r (only parsing).
-Notation Plt_1_succ := Pos.lt_1_succ (compat "8.6").
-Notation Plt_lt_succ := Pos.lt_lt_succ (compat "8.6").
-Notation Plt_irrefl := Pos.lt_irrefl (compat "8.6").
-Notation Plt_trans := Pos.lt_trans (compat "8.6").
-Notation Plt_ind := Pos.lt_ind (compat "8.6").
-Notation Ple_lteq := Pos.le_lteq (compat "8.6").
-Notation Ple_refl := Pos.le_refl (compat "8.6").
-Notation Ple_lt_trans := Pos.le_lt_trans (compat "8.6").
-Notation Plt_le_trans := Pos.lt_le_trans (compat "8.6").
-Notation Ple_trans := Pos.le_trans (compat "8.6").
-Notation Plt_succ_r := Pos.lt_succ_r (compat "8.6").
-Notation Ple_succ_l := Pos.le_succ_l (compat "8.6").
+Notation Plt_1_succ := Pos.lt_1_succ (compat "8.7").
+Notation Plt_lt_succ := Pos.lt_lt_succ (compat "8.7").
+Notation Plt_irrefl := Pos.lt_irrefl (compat "8.7").
+Notation Plt_trans := Pos.lt_trans (compat "8.7").
+Notation Plt_ind := Pos.lt_ind (compat "8.7").
+Notation Ple_lteq := Pos.le_lteq (compat "8.7").
+Notation Ple_refl := Pos.le_refl (compat "8.7").
+Notation Ple_lt_trans := Pos.le_lt_trans (compat "8.7").
+Notation Plt_le_trans := Pos.lt_le_trans (compat "8.7").
+Notation Ple_trans := Pos.le_trans (compat "8.7").
+Notation Plt_succ_r := Pos.lt_succ_r (compat "8.7").
+Notation Ple_succ_l := Pos.le_succ_l (compat "8.7").
Notation Pplus_compare_mono_l := Pos.add_compare_mono_l (only parsing).
Notation Pplus_compare_mono_r := Pos.add_compare_mono_r (only parsing).
Notation Pplus_lt_mono_l := Pos.add_lt_mono_l (only parsing).
@@ -2055,8 +2057,8 @@ Notation Pmult_le_mono_r := Pos.mul_le_mono_r (only parsing).
Notation Pmult_le_mono := Pos.mul_le_mono (only parsing).
Notation Plt_plus_r := Pos.lt_add_r (only parsing).
Notation Plt_not_plus_l := Pos.lt_not_add_l (only parsing).
-Notation Ppow_gt_1 := Pos.pow_gt_1 (compat "8.6").
-Notation Ppred_mask := Pos.pred_mask (compat "8.6").
+Notation Ppow_gt_1 := Pos.pow_gt_1 (compat "8.7").
+Notation Ppred_mask := Pos.pred_mask (compat "8.7").
Notation Pminus_mask_succ_r := Pos.sub_mask_succ_r (only parsing).
Notation Pminus_mask_carry_spec := Pos.sub_mask_carry_spec (only parsing).
Notation Pminus_succ_r := Pos.sub_succ_r (only parsing).
diff --git a/theories/PArith/BinPosDef.v b/theories/PArith/BinPosDef.v
index 07031474..7f307335 100644
--- a/theories/PArith/BinPosDef.v
+++ b/theories/PArith/BinPosDef.v
@@ -26,6 +26,8 @@ Require Export BinNums.
for the number 6 (which is 110 in binary notation).
*)
+Local Notation "1" := xH.
+
Notation "p ~ 1" := (xI p)
(at level 7, left associativity, format "p '~' '1'") : positive_scope.
Notation "p ~ 0" := (xO p)
@@ -325,14 +327,14 @@ Definition sqrtrem_step (f g:positive->positive) p :=
let r' := g (f r) in
if s' <=? r' then (s~1, sub_mask r' s')
else (s~0, IsPos r')
- | (s,_) => (s~0, sub_mask (g (f 1)) 4)
+ | (s,_) => (s~0, sub_mask (g (f 1)) 1~0~0)
end.
Fixpoint sqrtrem p : positive * mask :=
match p with
| 1 => (1,IsNul)
- | 2 => (1,IsPos 1)
- | 3 => (1,IsPos 2)
+ | 1~0 => (1,IsPos 1)
+ | 1~1 => (1,IsPos 1~0)
| p~0~0 => sqrtrem_step xO xO (sqrtrem p)
| p~0~1 => sqrtrem_step xO xI (sqrtrem p)
| p~1~0 => sqrtrem_step xI xO (sqrtrem p)
@@ -614,4 +616,9 @@ Definition to_uint p := Decimal.rev (to_little_uint p).
Definition to_int n := Decimal.Pos (to_uint n).
+Numeral Notation positive of_int to_uint : positive_scope.
+
End Pos.
+
+(** Re-export the notation for those who just [Import BinPosDef] *)
+Numeral Notation positive Pos.of_int Pos.to_uint : positive_scope.
diff --git a/theories/Program/Tactics.v b/theories/Program/Tactics.v
index bc838818..edbae653 100644
--- a/theories/Program/Tactics.v
+++ b/theories/Program/Tactics.v
@@ -326,7 +326,7 @@ Ltac program_solve_wf :=
Create HintDb program discriminated.
-Ltac program_simpl := program_simplify ; try typeclasses eauto with program ; try program_solve_wf.
+Ltac program_simpl := program_simplify ; try typeclasses eauto 10 with program ; try program_solve_wf.
Obligation Tactic := program_simpl.
diff --git a/theories/Reals/Machin.v b/theories/Reals/Machin.v
index cdf98cbd..8f7e07ac 100644
--- a/theories/Reals/Machin.v
+++ b/theories/Reals/Machin.v
@@ -8,7 +8,7 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-Require Import Fourier.
+Require Import Lra.
Require Import Rbase.
Require Import Rtrigo1.
Require Import Ranalysis_reg.
@@ -67,7 +67,7 @@ assert (atan x <= PI/4).
assert (atan y < PI/4).
rewrite <- atan_1; apply atan_increasing.
assumption.
-rewrite Ropp_div; split; fourier.
+rewrite Ropp_div; split; lra.
Qed.
(* A simple formula, reasonably efficient. *)
@@ -77,8 +77,8 @@ assert (utility : 0 < PI/2) by (apply PI2_RGT_0).
rewrite <- atan_1.
rewrite (atan_sub_correct 1 (/2)).
apply f_equal, f_equal; unfold atan_sub; field.
- apply Rgt_not_eq; fourier.
- apply tech; try split; try fourier.
+ apply Rgt_not_eq; lra.
+ apply tech; try split; try lra.
apply atan_bound.
Qed.
@@ -86,7 +86,7 @@ Lemma Machin_4_5_239 : PI/4 = 4 * atan (/5) - atan(/239).
Proof.
rewrite <- atan_1.
rewrite (atan_sub_correct 1 (/5));
- [ | apply Rgt_not_eq; fourier | apply tech; try split; fourier |
+ [ | apply Rgt_not_eq; lra | apply tech; try split; lra |
apply atan_bound ].
replace (4 * atan (/5) - atan (/239)) with
(atan (/5) + (atan (/5) + (atan (/5) + (atan (/5) + -
@@ -95,17 +95,17 @@ apply f_equal.
replace (atan_sub 1 (/5)) with (2/3) by
(unfold atan_sub; field).
rewrite (atan_sub_correct (2/3) (/5));
- [apply f_equal | apply Rgt_not_eq; fourier | apply tech; try split; fourier |
+ [apply f_equal | apply Rgt_not_eq; lra | apply tech; try split; lra |
apply atan_bound ].
replace (atan_sub (2/3) (/5)) with (7/17) by
(unfold atan_sub; field).
rewrite (atan_sub_correct (7/17) (/5));
- [apply f_equal | apply Rgt_not_eq; fourier | apply tech; try split; fourier |
+ [apply f_equal | apply Rgt_not_eq; lra | apply tech; try split; lra |
apply atan_bound ].
replace (atan_sub (7/17) (/5)) with (9/46) by
(unfold atan_sub; field).
rewrite (atan_sub_correct (9/46) (/5));
- [apply f_equal | apply Rgt_not_eq; fourier | apply tech; try split; fourier |
+ [apply f_equal | apply Rgt_not_eq; lra | apply tech; try split; lra |
apply atan_bound ].
rewrite <- atan_opp; apply f_equal.
unfold atan_sub; field.
@@ -115,7 +115,7 @@ Lemma Machin_2_3_7 : PI/4 = 2 * atan(/3) + (atan (/7)).
Proof.
rewrite <- atan_1.
rewrite (atan_sub_correct 1 (/3));
- [ | apply Rgt_not_eq; fourier | apply tech; try split; fourier |
+ [ | apply Rgt_not_eq; lra | apply tech; try split; lra |
apply atan_bound ].
replace (2 * atan (/3) + atan (/7)) with
(atan (/3) + (atan (/3) + atan (/7))) by ring.
@@ -123,7 +123,7 @@ apply f_equal.
replace (atan_sub 1 (/3)) with (/2) by
(unfold atan_sub; field).
rewrite (atan_sub_correct (/2) (/3));
- [apply f_equal | apply Rgt_not_eq; fourier | apply tech; try split; fourier |
+ [apply f_equal | apply Rgt_not_eq; lra | apply tech; try split; lra |
apply atan_bound ].
apply f_equal; unfold atan_sub; field.
Qed.
@@ -138,19 +138,19 @@ Lemma PI_2_3_7_ineq :
sum_f_R0 (tg_alt PI_2_3_7_tg) (S (2 * N)) <= PI / 4 <=
sum_f_R0 (tg_alt PI_2_3_7_tg) (2 * N).
Proof.
-assert (dec3 : 0 <= /3 <= 1) by (split; fourier).
-assert (dec7 : 0 <= /7 <= 1) by (split; fourier).
+assert (dec3 : 0 <= /3 <= 1) by (split; lra).
+assert (dec7 : 0 <= /7 <= 1) by (split; lra).
assert (decr : Un_decreasing PI_2_3_7_tg).
apply Ratan_seq_decreasing in dec3.
apply Ratan_seq_decreasing in dec7.
intros n; apply Rplus_le_compat.
- apply Rmult_le_compat_l; [ fourier | exact (dec3 n)].
+ apply Rmult_le_compat_l; [ lra | exact (dec3 n)].
exact (dec7 n).
assert (cv : Un_cv PI_2_3_7_tg 0).
apply Ratan_seq_converging in dec3.
apply Ratan_seq_converging in dec7.
intros eps ep.
- assert (ep' : 0 < eps /3) by fourier.
+ assert (ep' : 0 < eps /3) by lra.
destruct (dec3 _ ep') as [N1 Pn1]; destruct (dec7 _ ep') as [N2 Pn2].
exists (N1 + N2)%nat; intros n Nn.
unfold PI_2_3_7_tg.
@@ -161,14 +161,14 @@ assert (cv : Un_cv PI_2_3_7_tg 0).
apply Rplus_lt_compat.
unfold R_dist, Rminus, Rdiv.
rewrite <- (Rmult_0_r 2), <- Ropp_mult_distr_r_reverse.
- rewrite <- Rmult_plus_distr_l, Rabs_mult, (Rabs_pos_eq 2);[|fourier].
- rewrite Rmult_assoc; apply Rmult_lt_compat_l;[fourier | ].
+ rewrite <- Rmult_plus_distr_l, Rabs_mult, (Rabs_pos_eq 2);[|lra].
+ rewrite Rmult_assoc; apply Rmult_lt_compat_l;[lra | ].
apply (Pn1 n); omega.
apply (Pn2 n); omega.
rewrite Machin_2_3_7.
-rewrite !atan_eq_ps_atan; try (split; fourier).
+rewrite !atan_eq_ps_atan; try (split; lra).
unfold ps_atan; destruct (in_int (/3)); destruct (in_int (/7));
- try match goal with id : ~ _ |- _ => case id; split; fourier end.
+ try match goal with id : ~ _ |- _ => case id; split; lra end.
destruct (ps_atan_exists_1 (/3)) as [v3 Pv3].
destruct (ps_atan_exists_1 (/7)) as [v7 Pv7].
assert (main : Un_cv (sum_f_R0 (tg_alt PI_2_3_7_tg)) (2 * v3 + v7)).
diff --git a/theories/Reals/PSeries_reg.v b/theories/Reals/PSeries_reg.v
index 61d1b5af..146d6910 100644
--- a/theories/Reals/PSeries_reg.v
+++ b/theories/Reals/PSeries_reg.v
@@ -15,7 +15,7 @@ Require Import Ranalysis1.
Require Import MVT.
Require Import Max.
Require Import Even.
-Require Import Fourier.
+Require Import Lra.
Local Open Scope R_scope.
(* Boule is French for Ball *)
@@ -431,7 +431,7 @@ assert (ctrho : forall n z, Boule c d z -> continuity_pt (rho_ n) z).
intros y dyz; unfold rho_; destruct (Req_EM_T y x) as [xy | xny].
rewrite xy in dyz.
destruct (Rle_dec delta (Rabs (z - x))).
- rewrite Rmin_left, R_dist_sym in dyz; unfold R_dist in dyz; fourier.
+ rewrite Rmin_left, R_dist_sym in dyz; unfold R_dist in dyz; lra.
rewrite Rmin_right, R_dist_sym in dyz; unfold R_dist in dyz;
[case (Rlt_irrefl _ dyz) |apply Rlt_le, Rnot_le_gt; assumption].
reflexivity.
@@ -449,7 +449,7 @@ assert (ctrho : forall n z, Boule c d z -> continuity_pt (rho_ n) z).
assert (CVU rho_ rho c d ).
intros eps ep.
assert (ep8 : 0 < eps/8).
- fourier.
+ lra.
destruct (cvu _ ep8) as [N Pn1].
assert (cauchy1 : forall n p, (N <= n)%nat -> (N <= p)%nat ->
forall z, Boule c d z -> Rabs (f' n z - f' p z) < eps/4).
@@ -537,7 +537,7 @@ assert (CVU rho_ rho c d ).
simpl; unfold R_dist.
unfold Rminus; rewrite (Rplus_comm y), Rplus_assoc, Rplus_opp_r, Rplus_0_r.
rewrite Rabs_pos_eq;[ |apply Rlt_le; assumption ].
- apply Rlt_le_trans with (Rmin (Rmin d' d2) delta);[fourier | ].
+ apply Rlt_le_trans with (Rmin (Rmin d' d2) delta);[lra | ].
apply Rle_trans with (Rmin d' d2); apply Rmin_l.
apply Rle_trans with (1 := R_dist_tri _ _ (rho_ p (y + Rmin (Rmin d' d2) delta/2))).
apply Rplus_le_compat.
@@ -548,33 +548,32 @@ assert (CVU rho_ rho c d ).
replace (rho_ p (y + Rmin (Rmin d' d2) delta / 2)) with
((f p (y + Rmin (Rmin d' d2) delta / 2) - f p x)/
((y + Rmin (Rmin d' d2) delta / 2) - x)).
- apply step_2; auto; try fourier.
+ apply step_2; auto; try lra.
assert (0 < pos delta) by (apply cond_pos).
apply Boule_convex with y (y + delta/2).
assumption.
destruct (Pdelta (y + delta/2)); auto.
- rewrite xy; unfold Boule; rewrite Rabs_pos_eq; try fourier; auto.
- split; try fourier.
+ rewrite xy; unfold Boule; rewrite Rabs_pos_eq; try lra; auto.
+ split; try lra.
apply Rplus_le_compat_l, Rmult_le_compat_r;[ | apply Rmin_r].
now apply Rlt_le, Rinv_0_lt_compat, Rlt_0_2.
- apply Rminus_not_eq_right; rewrite xy; apply Rgt_not_eq; fourier.
unfold rho_.
destruct (Req_EM_T (y + Rmin (Rmin d' d2) delta/2) x) as [ymx | ymnx].
- case (RIneq.Rle_not_lt _ _ (Req_le _ _ ymx)); fourier.
+ case (RIneq.Rle_not_lt _ _ (Req_le _ _ ymx)); lra.
reflexivity.
unfold rho_.
destruct (Req_EM_T (y + Rmin (Rmin d' d2) delta / 2) x) as [ymx | ymnx].
- case (RIneq.Rle_not_lt _ _ (Req_le _ _ ymx)); fourier.
+ case (RIneq.Rle_not_lt _ _ (Req_le _ _ ymx)); lra.
reflexivity.
- apply Rlt_le, Pd2; split;[split;[exact I | apply Rlt_not_eq; fourier] | ].
+ apply Rlt_le, Pd2; split;[split;[exact I | apply Rlt_not_eq; lra] | ].
simpl; unfold R_dist.
unfold Rminus; rewrite (Rplus_comm y), Rplus_assoc, Rplus_opp_r, Rplus_0_r.
- rewrite Rabs_pos_eq;[ | fourier].
- apply Rlt_le_trans with (Rmin (Rmin d' d2) delta); [fourier |].
+ rewrite Rabs_pos_eq;[ | lra].
+ apply Rlt_le_trans with (Rmin (Rmin d' d2) delta); [lra |].
apply Rle_trans with (Rmin d' d2).
solve[apply Rmin_l].
solve[apply Rmin_r].
- apply Rlt_le, Rlt_le_trans with (eps/4);[ | fourier].
+ apply Rlt_le, Rlt_le_trans with (eps/4);[ | lra].
unfold rho_; destruct (Req_EM_T y x); solve[auto].
assert (unif_ac' : forall p, (N <= p)%nat ->
forall y, Boule c d y -> Rabs (rho y - rho_ p y) < eps).
@@ -589,7 +588,7 @@ assert (CVU rho_ rho c d ).
intros eps' ep'; simpl; exists 0%nat; intros; rewrite R_dist_eq; assumption.
intros p pN y b_y.
replace eps with (eps/2 + eps/2) by field.
- assert (ep2 : 0 < eps/2) by fourier.
+ assert (ep2 : 0 < eps/2) by lra.
destruct (cvrho y b_y _ ep2) as [N2 Pn2].
apply Rle_lt_trans with (1 := R_dist_tri _ _ (rho_ (max N N2) y)).
apply Rplus_lt_le_compat.
diff --git a/theories/Reals/R_sqrt.v b/theories/Reals/R_sqrt.v
index d4035fad..6991923b 100644
--- a/theories/Reals/R_sqrt.v
+++ b/theories/Reals/R_sqrt.v
@@ -155,6 +155,22 @@ Proof.
| apply (sqrt_positivity x (Rlt_le 0 x H1)) ].
Qed.
+Lemma Rlt_mult_inv_pos : forall x y:R, 0 < x -> 0 < y -> 0 < x * / y.
+intros x y H H0; try assumption.
+replace 0 with (x * 0).
+apply Rmult_lt_compat_l; auto with real.
+ring.
+Qed.
+
+Lemma Rle_mult_inv_pos : forall x y:R, 0 <= x -> 0 < y -> 0 <= x * / y.
+intros x y H H0; try assumption.
+case H; intros.
+red; left.
+apply Rlt_mult_inv_pos; auto with real.
+rewrite <- H1.
+red; right; ring.
+Qed.
+
Lemma sqrt_div_alt :
forall x y : R, 0 < y -> sqrt (x / y) = sqrt x / sqrt y.
Proof.
@@ -176,14 +192,14 @@ Proof.
clearbody Hx'. clear Hx.
apply Rsqr_inj.
apply sqrt_pos.
- apply Fourier_util.Rle_mult_inv_pos.
+ apply Rle_mult_inv_pos.
apply Rsqrt_positivity.
now apply sqrt_lt_R0.
rewrite Rsqr_div, 2!Rsqr_sqrt.
unfold Rsqr.
now rewrite Rsqrt_Rsqrt.
now apply Rlt_le.
- now apply Fourier_util.Rle_mult_inv_pos.
+ now apply Rle_mult_inv_pos.
apply Rgt_not_eq.
now apply sqrt_lt_R0.
Qed.
diff --git a/theories/Reals/Ranalysis5.v b/theories/Reals/Ranalysis5.v
index afb78e1c..e66130b3 100644
--- a/theories/Reals/Ranalysis5.v
+++ b/theories/Reals/Ranalysis5.v
@@ -12,7 +12,7 @@ Require Import Rbase.
Require Import Ranalysis_reg.
Require Import Rfunctions.
Require Import Rseries.
-Require Import Fourier.
+Require Import Lra.
Require Import RiemannInt.
Require Import SeqProp.
Require Import Max.
@@ -56,7 +56,7 @@ Proof.
}
rewrite f_eq_g in Htemp by easy.
unfold id in Htemp.
- fourier.
+ lra.
Qed.
Lemma derivable_pt_id_interv : forall (lb ub x:R),
@@ -99,7 +99,7 @@ assert (forall x l, lb < x < ub -> (derivable_pt_abs f x l <-> derivable_pt_abs
apply Req_le ; apply Rabs_right ; apply Rgt_ge ; assumption.
split.
assert (Sublemma : forall x y z, -z < y - x -> x < y + z).
- intros ; fourier.
+ intros ; lra.
apply Sublemma.
apply Sublemma2. rewrite Rabs_Ropp.
apply Rlt_le_trans with (r2:=a-lb) ; [| apply RRle_abs] ;
@@ -108,7 +108,7 @@ assert (forall x l, lb < x < ub -> (derivable_pt_abs f x l <-> derivable_pt_abs
apply Rlt_le_trans with (r2:=Rmin (ub - a) (a - lb)) ; [| apply Rmin_r] ;
apply Rlt_le_trans with (r2:=Rmin delta (Rmin (ub - a) (a - lb))) ; [| apply Rmin_r] ; assumption.
assert (Sublemma : forall x y z, y < z - x -> x + y < z).
- intros ; fourier.
+ intros ; lra.
apply Sublemma.
apply Sublemma2.
apply Rlt_le_trans with (r2:=ub-a) ; [| apply RRle_abs] ;
@@ -137,7 +137,7 @@ assert (forall x l, lb < x < ub -> (derivable_pt_abs f x l <-> derivable_pt_abs
apply Req_le ; apply Rabs_right ; apply Rgt_ge ; assumption.
split.
assert (Sublemma : forall x y z, -z < y - x -> x < y + z).
- intros ; fourier.
+ intros ; lra.
apply Sublemma.
apply Sublemma2. rewrite Rabs_Ropp.
apply Rlt_le_trans with (r2:=a-lb) ; [| apply RRle_abs] ;
@@ -146,7 +146,7 @@ assert (forall x l, lb < x < ub -> (derivable_pt_abs f x l <-> derivable_pt_abs
apply Rlt_le_trans with (r2:=Rmin (ub - a) (a - lb)) ; [| apply Rmin_r] ;
apply Rlt_le_trans with (r2:=Rmin delta (Rmin (ub - a) (a - lb))) ; [| apply Rmin_r] ; assumption.
assert (Sublemma : forall x y z, y < z - x -> x + y < z).
- intros ; fourier.
+ intros ; lra.
apply Sublemma.
apply Sublemma2.
apply Rlt_le_trans with (r2:=ub-a) ; [| apply RRle_abs] ;
@@ -415,7 +415,7 @@ Ltac case_le H :=
let h' := fresh in
match t with ?x <= ?y => case (total_order_T x y);
[intros h'; case h'; clear h' |
- intros h'; clear -H h'; elimtype False; fourier ] end.
+ intros h'; clear -H h'; elimtype False; lra ] end.
(* end hide *)
@@ -539,37 +539,37 @@ intros f g lb ub lb_lt_ub f_incr_interv f_eq_g f_cont_interv b b_encad.
assert (x1_encad : lb <= x1 <= ub).
split. apply RmaxLess2.
apply Rlt_le. rewrite Hx1. rewrite Sublemma.
- split. apply Rlt_trans with (r2:=x) ; fourier.
+ split. apply Rlt_trans with (r2:=x) ; lra.
assumption.
assert (x2_encad : lb <= x2 <= ub).
split. apply Rlt_le ; rewrite Hx2 ; apply Rgt_lt ; rewrite Sublemma2.
- split. apply Rgt_trans with (r2:=x) ; fourier.
+ split. apply Rgt_trans with (r2:=x) ; lra.
assumption.
apply Rmin_r.
assert (x_lt_x2 : x < x2).
rewrite Hx2.
apply Rgt_lt. rewrite Sublemma2.
- split ; fourier.
+ split ; lra.
assert (x1_lt_x : x1 < x).
rewrite Hx1.
rewrite Sublemma.
- split ; fourier.
+ split ; lra.
exists (Rmin (f x - f x1) (f x2 - f x)).
- split. apply Rmin_pos ; apply Rgt_minus. apply f_incr_interv ; [apply RmaxLess2 | | ] ; fourier.
+ split. apply Rmin_pos ; apply Rgt_minus. apply f_incr_interv ; [apply RmaxLess2 | | ] ; lra.
apply f_incr_interv ; intuition.
intros y Temp.
destruct Temp as (_,y_cond).
rewrite <- f_x_b in y_cond.
assert (Temp : forall x y d1 d2, d1 > 0 -> d2 > 0 -> Rabs (y - x) < Rmin d1 d2 -> x - d1 <= y <= x + d2).
intros.
- split. assert (H10 : forall x y z, x - y <= z -> x - z <= y). intuition. fourier.
+ split. assert (H10 : forall x y z, x - y <= z -> x - z <= y). intuition. lra.
apply H10. apply Rle_trans with (r2:=Rabs (y0 - x0)).
replace (Rabs (y0 - x0)) with (Rabs (x0 - y0)). apply RRle_abs.
rewrite <- Rabs_Ropp. unfold Rminus ; rewrite Ropp_plus_distr. rewrite Ropp_involutive.
intuition.
apply Rle_trans with (r2:= Rmin d1 d2). apply Rlt_le ; assumption.
apply Rmin_l.
- assert (H10 : forall x y z, x - y <= z -> x <= y + z). intuition. fourier.
+ assert (H10 : forall x y z, x - y <= z -> x <= y + z). intuition. lra.
apply H10. apply Rle_trans with (r2:=Rabs (y0 - x0)). apply RRle_abs.
apply Rle_trans with (r2:= Rmin d1 d2). apply Rlt_le ; assumption.
apply Rmin_r.
@@ -602,12 +602,12 @@ intros f g lb ub lb_lt_ub f_incr_interv f_eq_g f_cont_interv b b_encad.
assert (x1_neq_x' : x1 <> x').
intro Hfalse. rewrite Hfalse, f_x'_y in y_cond.
assert (Hf : Rabs (y - f x) < f x - y).
- apply Rlt_le_trans with (r2:=Rmin (f x - y) (f x2 - f x)). fourier.
+ apply Rlt_le_trans with (r2:=Rmin (f x - y) (f x2 - f x)). lra.
apply Rmin_l.
assert(Hfin : f x - y < f x - y).
apply Rle_lt_trans with (r2:=Rabs (y - f x)).
replace (Rabs (y - f x)) with (Rabs (f x - y)). apply RRle_abs.
- rewrite <- Rabs_Ropp. replace (- (f x - y)) with (y - f x) by field ; reflexivity. fourier.
+ rewrite <- Rabs_Ropp. replace (- (f x - y)) with (y - f x) by field ; reflexivity. lra.
apply (Rlt_irrefl (f x - y)) ; assumption.
split ; intuition.
assert (x'_lb : x - eps < x').
@@ -619,17 +619,17 @@ intros f g lb ub lb_lt_ub f_incr_interv f_eq_g f_cont_interv b b_encad.
assert (x1_neq_x' : x' <> x2).
intro Hfalse. rewrite <- Hfalse, f_x'_y in y_cond.
assert (Hf : Rabs (y - f x) < y - f x).
- apply Rlt_le_trans with (r2:=Rmin (f x - f x1) (y - f x)). fourier.
+ apply Rlt_le_trans with (r2:=Rmin (f x - f x1) (y - f x)). lra.
apply Rmin_r.
assert(Hfin : y - f x < y - f x).
- apply Rle_lt_trans with (r2:=Rabs (y - f x)). apply RRle_abs. fourier.
+ apply Rle_lt_trans with (r2:=Rabs (y - f x)). apply RRle_abs. lra.
apply (Rlt_irrefl (y - f x)) ; assumption.
split ; intuition.
assert (x'_ub : x' < x + eps).
apply Sublemma3.
split. intuition. apply Rlt_not_eq.
apply Rlt_le_trans with (r2:=x2) ; [ |rewrite Hx2 ; apply Rmin_l] ; intuition.
- apply Rabs_def1 ; fourier.
+ apply Rabs_def1 ; lra.
assumption.
split. apply Rle_trans with (r2:=x1) ; intuition.
apply Rle_trans with (r2:=x2) ; intuition.
@@ -742,7 +742,7 @@ intros f g lb ub x Prf g_cont_pur lb_lt_ub x_encad Prg_incr f_eq_g df_neq.
assert (lb <= x + h <= ub).
split.
assert (Sublemma : forall x y z, -z <= y - x -> x <= y + z).
- intros ; fourier.
+ intros ; lra.
apply Sublemma.
apply Rlt_le ; apply Sublemma2. rewrite Rabs_Ropp.
apply Rlt_le_trans with (r2:=x-lb) ; [| apply RRle_abs] ;
@@ -751,7 +751,7 @@ intros f g lb ub x Prf g_cont_pur lb_lt_ub x_encad Prg_incr f_eq_g df_neq.
apply Rlt_le_trans with (r2:=delta''). assumption. intuition. apply Rmin_r.
apply Rgt_minus. intuition.
assert (Sublemma : forall x y z, y <= z - x -> x + y <= z).
- intros ; fourier.
+ intros ; lra.
apply Sublemma.
apply Rlt_le ; apply Sublemma2.
apply Rlt_le_trans with (r2:=ub-x) ; [| apply RRle_abs] ;
@@ -767,7 +767,7 @@ intros f g lb ub x Prf g_cont_pur lb_lt_ub x_encad Prg_incr f_eq_g df_neq.
assumption.
split ; [|intuition].
assert (Sublemma : forall x y z, - z <= y - x -> x <= y + z).
- intros ; fourier.
+ intros ; lra.
apply Sublemma ; apply Rlt_le ; apply Sublemma2. rewrite Rabs_Ropp.
apply Rlt_le_trans with (r2:=x-lb) ; [| apply RRle_abs] ;
apply Rlt_le_trans with (r2:=Rmin (x - lb) (ub - x)) ; [| apply Rmin_l] ;
@@ -1031,7 +1031,7 @@ Lemma derivable_pt_lim_CVU : forall (fn fn':nat -> R -> R) (f g:R->R)
derivable_pt_lim f x (g x).
Proof.
intros fn fn' f g x c' r xinb Dfn_eq_fn' fn_CV_f fn'_CVU_g g_cont eps eps_pos.
-assert (eps_8_pos : 0 < eps / 8) by fourier.
+assert (eps_8_pos : 0 < eps / 8) by lra.
elim (g_cont x xinb _ eps_8_pos) ; clear g_cont ;
intros delta1 (delta1_pos, g_cont).
destruct (Ball_in_inter _ _ _ _ _ xinb
@@ -1041,11 +1041,11 @@ exists delta; intros h hpos hinbdelta.
assert (eps'_pos : 0 < (Rabs h) * eps / 4).
unfold Rdiv ; rewrite Rmult_assoc ; apply Rmult_lt_0_compat.
apply Rabs_pos_lt ; assumption.
-fourier.
+lra.
destruct (fn_CV_f x xinb ((Rabs h) * eps / 4) eps'_pos) as [N2 fnx_CV_fx].
assert (xhinbxdelta : Boule x delta (x + h)).
clear -hinbdelta; apply Rabs_def2 in hinbdelta; unfold Boule; simpl.
- destruct hinbdelta; apply Rabs_def1; fourier.
+ destruct hinbdelta; apply Rabs_def1; lra.
assert (t : Boule c' r (x + h)).
apply Pdelta in xhinbxdelta; tauto.
destruct (fn_CV_f (x+h) t ((Rabs h) * eps / 4) eps'_pos) as [N1 fnxh_CV_fxh].
@@ -1064,17 +1064,17 @@ assert (Main : Rabs ((f (x+h) - fn N (x+h)) - (f x - fn N x) + (fn N (x+h) - fn
exists (fn' N c) ; apply Dfn_eq_fn'.
assert (t : Boule x delta c).
apply Rabs_def2 in xhinbxdelta; destruct xhinbxdelta; destruct c_encad.
- apply Rabs_def2 in xinb; apply Rabs_def1; fourier.
+ apply Rabs_def2 in xinb; apply Rabs_def1; lra.
apply Pdelta in t; tauto.
assert (pr2 : forall c : R, x + h < c < x -> derivable_pt id c).
solve[intros; apply derivable_id].
- assert (xh_x : x+h < x) by fourier.
+ assert (xh_x : x+h < x) by lra.
assert (pr3 : forall c : R, x + h <= c <= x -> continuity_pt (fn N) c).
intros c c_encad ; apply derivable_continuous_pt.
exists (fn' N c) ; apply Dfn_eq_fn' ; intuition.
assert (t : Boule x delta c).
apply Rabs_def2 in xhinbxdelta; destruct xhinbxdelta.
- apply Rabs_def2 in xinb; apply Rabs_def1; fourier.
+ apply Rabs_def2 in xinb; apply Rabs_def1; lra.
apply Pdelta in t; tauto.
assert (pr4 : forall c : R, x + h <= c <= x -> continuity_pt id c).
solve[intros; apply derivable_continuous ; apply derivable_id].
@@ -1117,7 +1117,7 @@ assert (Main : Rabs ((f (x+h) - fn N (x+h)) - (f x - fn N x) + (fn N (x+h) - fn
assert (t : Boule x delta c).
destruct P.
apply Rabs_def2 in xhinbxdelta; destruct xhinbxdelta.
- apply Rabs_def2 in xinb; apply Rabs_def1; fourier.
+ apply Rabs_def2 in xinb; apply Rabs_def1; lra.
apply Pdelta in t; tauto.
apply Rlt_trans with (Rabs h * eps / 4 + Rabs h * eps / 4 + Rabs h * (eps / 8) +
Rabs h * (eps / 8)).
@@ -1131,27 +1131,27 @@ assert (Main : Rabs ((f (x+h) - fn N (x+h)) - (f x - fn N x) + (fn N (x+h) - fn
apply Rlt_trans with (Rabs h).
apply Rabs_def1.
apply Rlt_trans with 0.
- destruct P; fourier.
+ destruct P; lra.
apply Rabs_pos_lt ; assumption.
- rewrite <- Rabs_Ropp, Rabs_pos_eq, Ropp_involutive;[ | fourier].
- destruct P; fourier.
+ rewrite <- Rabs_Ropp, Rabs_pos_eq, Ropp_involutive;[ | lra].
+ destruct P; lra.
clear -Pdelta xhinbxdelta.
apply Pdelta in xhinbxdelta; destruct xhinbxdelta as [_ P'].
apply Rabs_def2 in P'; simpl in P'; destruct P';
- apply Rabs_def1; fourier.
+ apply Rabs_def1; lra.
rewrite Rplus_assoc ; rewrite Rplus_assoc ; rewrite <- Rmult_plus_distr_l.
replace (Rabs h * eps / 4 + (Rabs h * eps / 4 + Rabs h * (eps / 8 + eps / 8))) with
(Rabs h * (eps / 4 + eps / 4 + eps / 8 + eps / 8)) by field.
apply Rmult_lt_compat_l.
apply Rabs_pos_lt ; assumption.
- fourier.
+ lra.
assert (H := pr1 c P) ; elim H ; clear H ; intros l Hl.
assert (Temp : l = fn' N c).
assert (bc'rc : Boule c' r c).
assert (t : Boule x delta c).
clear - xhinbxdelta P.
destruct P; apply Rabs_def2 in xhinbxdelta; destruct xhinbxdelta.
- apply Rabs_def1; fourier.
+ apply Rabs_def1; lra.
apply Pdelta in t; tauto.
assert (Hl' := Dfn_eq_fn' c N bc'rc).
unfold derivable_pt_abs in Hl; clear -Hl Hl'.
@@ -1175,17 +1175,17 @@ assert (Main : Rabs ((f (x+h) - fn N (x+h)) - (f x - fn N x) + (fn N (x+h) - fn
exists (fn' N c) ; apply Dfn_eq_fn'.
assert (t : Boule x delta c).
apply Rabs_def2 in xhinbxdelta; destruct xhinbxdelta; destruct c_encad.
- apply Rabs_def2 in xinb; apply Rabs_def1; fourier.
+ apply Rabs_def2 in xinb; apply Rabs_def1; lra.
apply Pdelta in t; tauto.
assert (pr2 : forall c : R, x < c < x + h -> derivable_pt id c).
solve[intros; apply derivable_id].
- assert (xh_x : x < x + h) by fourier.
+ assert (xh_x : x < x + h) by lra.
assert (pr3 : forall c : R, x <= c <= x + h -> continuity_pt (fn N) c).
intros c c_encad ; apply derivable_continuous_pt.
exists (fn' N c) ; apply Dfn_eq_fn' ; intuition.
assert (t : Boule x delta c).
apply Rabs_def2 in xhinbxdelta; destruct xhinbxdelta.
- apply Rabs_def2 in xinb; apply Rabs_def1; fourier.
+ apply Rabs_def2 in xinb; apply Rabs_def1; lra.
apply Pdelta in t; tauto.
assert (pr4 : forall c : R, x <= c <= x + h -> continuity_pt id c).
solve[intros; apply derivable_continuous ; apply derivable_id].
@@ -1223,7 +1223,7 @@ assert (Main : Rabs ((f (x+h) - fn N (x+h)) - (f x - fn N x) + (fn N (x+h) - fn
assert (t : Boule x delta c).
destruct P.
apply Rabs_def2 in xhinbxdelta; destruct xhinbxdelta.
- apply Rabs_def2 in xinb; apply Rabs_def1; fourier.
+ apply Rabs_def2 in xinb; apply Rabs_def1; lra.
apply Pdelta in t; tauto.
apply Rlt_trans with (Rabs h * eps / 4 + Rabs h * eps / 4 + Rabs h * (eps / 8) +
Rabs h * (eps / 8)).
@@ -1236,27 +1236,27 @@ assert (Main : Rabs ((f (x+h) - fn N (x+h)) - (f x - fn N x) + (fn N (x+h) - fn
apply Rlt_not_eq ; exact (proj1 P).
apply Rlt_trans with (Rabs h).
apply Rabs_def1.
- destruct P; rewrite Rabs_pos_eq;fourier.
+ destruct P; rewrite Rabs_pos_eq;lra.
apply Rle_lt_trans with 0.
- assert (t := Rabs_pos h); clear -t; fourier.
- clear -P; destruct P; fourier.
+ assert (t := Rabs_pos h); clear -t; lra.
+ clear -P; destruct P; lra.
clear -Pdelta xhinbxdelta.
apply Pdelta in xhinbxdelta; destruct xhinbxdelta as [_ P'].
apply Rabs_def2 in P'; simpl in P'; destruct P';
- apply Rabs_def1; fourier.
+ apply Rabs_def1; lra.
rewrite Rplus_assoc ; rewrite Rplus_assoc ; rewrite <- Rmult_plus_distr_l.
replace (Rabs h * eps / 4 + (Rabs h * eps / 4 + Rabs h * (eps / 8 + eps / 8))) with
(Rabs h * (eps / 4 + eps / 4 + eps / 8 + eps / 8)) by field.
apply Rmult_lt_compat_l.
apply Rabs_pos_lt ; assumption.
- fourier.
+ lra.
assert (H := pr1 c P) ; elim H ; clear H ; intros l Hl.
assert (Temp : l = fn' N c).
assert (bc'rc : Boule c' r c).
assert (t : Boule x delta c).
clear - xhinbxdelta P.
destruct P; apply Rabs_def2 in xhinbxdelta; destruct xhinbxdelta.
- apply Rabs_def1; fourier.
+ apply Rabs_def1; lra.
apply Pdelta in t; tauto.
assert (Hl' := Dfn_eq_fn' c N bc'rc).
unfold derivable_pt_abs in Hl; clear -Hl Hl'.
diff --git a/theories/Reals/Ratan.v b/theories/Reals/Ratan.v
index ce39d5ff..03e6ff61 100644
--- a/theories/Reals/Ratan.v
+++ b/theories/Reals/Ratan.v
@@ -8,7 +8,7 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-Require Import Fourier.
+Require Import Lra.
Require Import Rbase.
Require Import PSeries_reg.
Require Import Rtrigo1.
@@ -32,7 +32,7 @@ intros x y; unfold Rdiv; rewrite <-Ropp_mult_distr_l_reverse; reflexivity.
Qed.
Definition pos_half_prf : 0 < /2.
-Proof. fourier. Qed.
+Proof. lra. Qed.
Definition pos_half := mkposreal (/2) pos_half_prf.
@@ -40,15 +40,15 @@ Lemma Boule_half_to_interval :
forall x , Boule (/2) pos_half x -> 0 <= x <= 1.
Proof.
unfold Boule, pos_half; simpl.
-intros x b; apply Rabs_def2 in b; destruct b; split; fourier.
+intros x b; apply Rabs_def2 in b; destruct b; split; lra.
Qed.
Lemma Boule_lt : forall c r x, Boule c r x -> Rabs x < Rabs c + r.
Proof.
unfold Boule; intros c r x h.
apply Rabs_def2 in h; destruct h; apply Rabs_def1;
- (destruct (Rle_lt_dec 0 c);[rewrite Rabs_pos_eq; fourier |
- rewrite <- Rabs_Ropp, Rabs_pos_eq; fourier]).
+ (destruct (Rle_lt_dec 0 c);[rewrite Rabs_pos_eq; lra |
+ rewrite <- Rabs_Ropp, Rabs_pos_eq; lra]).
Qed.
(* The following lemma does not belong here. *)
@@ -117,53 +117,53 @@ intros [ | N] Npos n decr to0 cv nN.
case (even_odd_cor n) as [p' [neven | nodd]].
rewrite neven.
destruct (alternated_series_ineq _ _ p' decr to0 cv) as [D E].
- unfold R_dist; rewrite Rabs_pos_eq;[ | fourier].
+ unfold R_dist; rewrite Rabs_pos_eq;[ | lra].
assert (dist : (p <= p')%nat) by omega.
assert (t := decreasing_prop _ _ _ (CV_ALT_step1 f decr) dist).
apply Rle_trans with (sum_f_R0 (tg_alt f) (2 * p) - l).
unfold Rminus; apply Rplus_le_compat_r; exact t.
match goal with _ : ?a <= l, _ : l <= ?b |- _ =>
replace (f (S (2 * p))) with (b - a) by
- (rewrite tech5; unfold tg_alt; rewrite pow_1_odd; ring); fourier
+ (rewrite tech5; unfold tg_alt; rewrite pow_1_odd; ring); lra
end.
rewrite nodd; destruct (alternated_series_ineq _ _ p' decr to0 cv) as [D E].
unfold R_dist; rewrite <- Rabs_Ropp, Rabs_pos_eq, Ropp_minus_distr;
- [ | fourier].
+ [ | lra].
assert (dist : (p <= p')%nat) by omega.
apply Rle_trans with (l - sum_f_R0 (tg_alt f) (S (2 * p))).
unfold Rminus; apply Rplus_le_compat_l, Ropp_le_contravar.
solve[apply Rge_le, (growing_prop _ _ _ (CV_ALT_step0 f decr) dist)].
unfold Rminus; rewrite tech5, Ropp_plus_distr, <- Rplus_assoc.
- unfold tg_alt at 2; rewrite pow_1_odd; fourier.
+ unfold tg_alt at 2; rewrite pow_1_odd; lra.
rewrite Nodd; destruct (alternated_series_ineq _ _ p decr to0 cv) as [B _].
destruct (alternated_series_ineq _ _ (S p) decr to0 cv) as [_ C].
assert (keep : (2 * S p = S (S ( 2 * p)))%nat) by ring.
case (even_odd_cor n) as [p' [neven | nodd]].
rewrite neven;
destruct (alternated_series_ineq _ _ p' decr to0 cv) as [D E].
- unfold R_dist; rewrite Rabs_pos_eq;[ | fourier].
+ unfold R_dist; rewrite Rabs_pos_eq;[ | lra].
assert (dist : (S p < S p')%nat) by omega.
apply Rle_trans with (sum_f_R0 (tg_alt f) (2 * S p) - l).
unfold Rminus; apply Rplus_le_compat_r,
(decreasing_prop _ _ _ (CV_ALT_step1 f decr)).
omega.
rewrite keep, tech5; unfold tg_alt at 2; rewrite <- keep, pow_1_even.
- fourier.
+ lra.
rewrite nodd; destruct (alternated_series_ineq _ _ p' decr to0 cv) as [D E].
- unfold R_dist; rewrite <- Rabs_Ropp, Rabs_pos_eq;[ | fourier].
+ unfold R_dist; rewrite <- Rabs_Ropp, Rabs_pos_eq;[ | lra].
rewrite Ropp_minus_distr.
apply Rle_trans with (l - sum_f_R0 (tg_alt f) (S (2 * p))).
unfold Rminus; apply Rplus_le_compat_l, Ropp_le_contravar, Rge_le,
(growing_prop _ _ _ (CV_ALT_step0 f decr)); omega.
generalize C; rewrite keep, tech5; unfold tg_alt.
rewrite <- keep, pow_1_even.
- assert (t : forall a b c, a <= b + 1 * c -> a - b <= c) by (intros; fourier).
+ assert (t : forall a b c, a <= b + 1 * c -> a - b <= c) by (intros; lra).
solve[apply t].
clear WLOG; intros Hyp [ | n] decr to0 cv _.
generalize (alternated_series_ineq f l 0 decr to0 cv).
unfold R_dist, tg_alt; simpl; rewrite !Rmult_1_l, !Rmult_1_r.
assert (f 1%nat <= f 0%nat) by apply decr.
- intros [A B]; rewrite Rabs_pos_eq; fourier.
+ intros [A B]; rewrite Rabs_pos_eq; lra.
apply Rle_trans with (f 1%nat).
apply (Hyp 1%nat (le_n 1) (S n) decr to0 cv).
omega.
@@ -180,7 +180,7 @@ Lemma Alt_CVU : forall (f : nat -> R -> R) g h c r,
CVU (fun N x => sum_f_R0 (tg_alt (fun i => f i x)) N) g c r.
Proof.
intros f g h c r decr to0 to_g bound bound0 eps ep.
-assert (ep' : 0 <eps/2) by fourier.
+assert (ep' : 0 <eps/2) by lra.
destruct (bound0 _ ep) as [N Pn]; exists N.
intros n y nN dy.
rewrite <- Rabs_Ropp, Ropp_minus_distr; apply Rle_lt_trans with (f n y).
@@ -201,14 +201,14 @@ intros x; destruct (Rle_lt_dec 0 x).
replace (x ^ 2) with (x * x) by field.
apply Rmult_le_pos; assumption.
replace (x ^ 2) with ((-x) * (-x)) by field.
-apply Rmult_le_pos; fourier.
+apply Rmult_le_pos; lra.
Qed.
Lemma pow2_abs : forall x, Rabs x ^ 2 = x ^ 2.
Proof.
intros x; destruct (Rle_lt_dec 0 x).
rewrite Rabs_pos_eq;[field | assumption].
-rewrite <- Rabs_Ropp, Rabs_pos_eq;[field | fourier].
+rewrite <- Rabs_Ropp, Rabs_pos_eq;[field | lra].
Qed.
(** * Properties of tangent *)
@@ -307,18 +307,18 @@ destruct (MVT_cor1 cos (PI/2) x derivable_cos xgtpi2) as
[c [Pc [cint1 cint2]]].
revert Pc; rewrite cos_PI2, Rminus_0_r.
rewrite <- (pr_nu cos c (derivable_pt_cos c)), derive_pt_cos.
-assert (0 < c < 2) by (split; assert (t := PI2_RGT_0); fourier).
+assert (0 < c < 2) by (split; assert (t := PI2_RGT_0); lra).
assert (0 < sin c) by now apply sin_pos_tech.
intros Pc.
case (Rlt_not_le _ _ cx).
rewrite <- (Rplus_0_l (cos x)), Pc, Ropp_mult_distr_l_reverse.
-apply Rle_minus, Rmult_le_pos;[apply Rlt_le; assumption | fourier ].
+apply Rle_minus, Rmult_le_pos;[apply Rlt_le; assumption | lra ].
Qed.
Lemma PI2_3_2 : 3/2 < PI/2.
Proof.
-apply PI2_lower_bound;[split; fourier | ].
-destruct (pre_cos_bound (3/2) 1) as [t _]; [fourier | fourier | ].
+apply PI2_lower_bound;[split; lra | ].
+destruct (pre_cos_bound (3/2) 1) as [t _]; [lra | lra | ].
apply Rlt_le_trans with (2 := t); clear t.
unfold cos_approx; simpl; unfold cos_term.
rewrite !INR_IZR_INZ.
@@ -330,7 +330,7 @@ apply Rdiv_lt_0_compat ; now apply IZR_lt.
Qed.
Lemma PI2_1 : 1 < PI/2.
-Proof. assert (t := PI2_3_2); fourier. Qed.
+Proof. assert (t := PI2_3_2); lra. Qed.
Lemma tan_increasing :
forall x y:R,
@@ -347,7 +347,7 @@ intros x y Z_le_x x_lt_y y_le_1.
derivable_pt tan x).
intros ; apply derivable_pt_tan ; intuition.
apply derive_increasing_interv with (a:=-PI/2) (b:=PI/2) (pr:=local_derivable_pt_tan) ; intuition.
- fourier.
+ lra.
assert (Temp := pr_nu tan t (derivable_pt_tan t t_encad) (local_derivable_pt_tan t t_encad)) ;
rewrite <- Temp ; clear Temp.
assert (Temp := derive_pt_tan t t_encad) ; rewrite Temp ; clear Temp.
@@ -414,49 +414,49 @@ Qed.
(** * Definition of arctangent as the reciprocal function of tangent and proof of this status *)
Lemma tan_1_gt_1 : tan 1 > 1.
Proof.
-assert (0 < cos 1) by (apply cos_gt_0; assert (t:=PI2_1); fourier).
+assert (0 < cos 1) by (apply cos_gt_0; assert (t:=PI2_1); lra).
assert (t1 : cos 1 <= 1 - 1/2 + 1/24).
- destruct (pre_cos_bound 1 0) as [_ t]; try fourier; revert t.
+ destruct (pre_cos_bound 1 0) as [_ t]; try lra; revert t.
unfold cos_approx, cos_term; simpl; intros t; apply Rle_trans with (1:=t).
clear t; apply Req_le; field.
assert (t2 : 1 - 1/6 <= sin 1).
- destruct (pre_sin_bound 1 0) as [t _]; try fourier; revert t.
+ destruct (pre_sin_bound 1 0) as [t _]; try lra; revert t.
unfold sin_approx, sin_term; simpl; intros t; apply Rle_trans with (2:=t).
clear t; apply Req_le; field.
pattern 1 at 2; replace 1 with
- (cos 1 / cos 1) by (field; apply Rgt_not_eq; fourier).
+ (cos 1 / cos 1) by (field; apply Rgt_not_eq; lra).
apply Rlt_gt; apply (Rmult_lt_compat_r (/ cos 1) (cos 1) (sin 1)).
apply Rinv_0_lt_compat; assumption.
apply Rle_lt_trans with (1 := t1); apply Rlt_le_trans with (2 := t2).
-fourier.
+lra.
Qed.
Definition frame_tan y : {x | 0 < x < PI/2 /\ Rabs y < tan x}.
Proof.
destruct (total_order_T (Rabs y) 1) as [Hs|Hgt].
- assert (yle1 : Rabs y <= 1) by (destruct Hs; fourier).
+ assert (yle1 : Rabs y <= 1) by (destruct Hs; lra).
clear Hs; exists 1; split;[split; [exact Rlt_0_1 | exact PI2_1] | ].
apply Rle_lt_trans with (1 := yle1); exact tan_1_gt_1.
assert (0 < / (Rabs y + 1)).
- apply Rinv_0_lt_compat; fourier.
+ apply Rinv_0_lt_compat; lra.
set (u := /2 * / (Rabs y + 1)).
assert (0 < u).
- apply Rmult_lt_0_compat; [fourier | assumption].
+ apply Rmult_lt_0_compat; [lra | assumption].
assert (vlt1 : / (Rabs y + 1) < 1).
apply Rmult_lt_reg_r with (Rabs y + 1).
- assert (t := Rabs_pos y); fourier.
- rewrite Rinv_l; [rewrite Rmult_1_l | apply Rgt_not_eq]; fourier.
+ assert (t := Rabs_pos y); lra.
+ rewrite Rinv_l; [rewrite Rmult_1_l | apply Rgt_not_eq]; lra.
assert (vlt2 : u < 1).
apply Rlt_trans with (/ (Rabs y + 1)).
rewrite double_var.
- assert (t : forall x, 0 < x -> x < x + x) by (clear; intros; fourier).
+ assert (t : forall x, 0 < x -> x < x + x) by (clear; intros; lra).
unfold u; rewrite Rmult_comm; apply t.
unfold Rdiv; rewrite Rmult_comm; assumption.
assumption.
assert(int : 0 < PI / 2 - u < PI / 2).
split.
assert (t := PI2_1); apply Rlt_Rminus, Rlt_trans with (2 := t); assumption.
- assert (dumb : forall x y, 0 < y -> x - y < x) by (clear; intros; fourier).
+ assert (dumb : forall x y, 0 < y -> x - y < x) by (clear; intros; lra).
apply dumb; clear dumb; assumption.
exists (PI/2 - u).
assert (tmp : forall x y, 0 < x -> y < 1 -> x * y < x).
@@ -473,7 +473,7 @@ split.
assert (sin u < u).
assert (t1 : 0 <= u) by (apply Rlt_le; assumption).
assert (t2 : u <= 4) by
- (apply Rle_trans with 1;[apply Rlt_le | fourier]; assumption).
+ (apply Rle_trans with 1;[apply Rlt_le | lra]; assumption).
destruct (pre_sin_bound u 0 t1 t2) as [_ t].
apply Rle_lt_trans with (1 := t); clear t1 t2 t.
unfold sin_approx; simpl; unfold sin_term; simpl ((-1) ^ 0);
@@ -503,17 +503,17 @@ split.
solve[apply Rinv_0_lt_compat, INR_fact_lt_0].
apply Rlt_trans with (2 := vlt2).
simpl; unfold u; apply tmp; auto; rewrite Rmult_1_r; assumption.
- apply Rlt_trans with (Rabs y + 1);[fourier | ].
+ apply Rlt_trans with (Rabs y + 1);[lra | ].
pattern (Rabs y + 1) at 1; rewrite <- (Rinv_involutive (Rabs y + 1));
- [ | apply Rgt_not_eq; fourier].
+ [ | apply Rgt_not_eq; lra].
rewrite <- Rinv_mult_distr.
apply Rinv_lt_contravar.
apply Rmult_lt_0_compat.
- apply Rmult_lt_0_compat;[fourier | assumption].
+ apply Rmult_lt_0_compat;[lra | assumption].
assumption.
replace (/(Rabs y + 1)) with (2 * u).
- fourier.
- unfold u; field; apply Rgt_not_eq; clear -Hgt; fourier.
+ lra.
+ unfold u; field; apply Rgt_not_eq; clear -Hgt; lra.
solve[discrR].
apply Rgt_not_eq; assumption.
unfold tan.
@@ -522,22 +522,22 @@ set (u' := PI / 2); unfold Rdiv; apply Rmult_lt_compat_r; unfold u'.
rewrite cos_shift; assumption.
assert (vlt3 : u < /4).
replace (/4) with (/2 * /2) by field.
- unfold u; apply Rmult_lt_compat_l;[fourier | ].
+ unfold u; apply Rmult_lt_compat_l;[lra | ].
apply Rinv_lt_contravar.
- apply Rmult_lt_0_compat; fourier.
- fourier.
-assert (1 < PI / 2 - u) by (assert (t := PI2_3_2); fourier).
+ apply Rmult_lt_0_compat; lra.
+ lra.
+assert (1 < PI / 2 - u) by (assert (t := PI2_3_2); lra).
apply Rlt_trans with (sin 1).
- assert (t' : 1 <= 4) by fourier.
+ assert (t' : 1 <= 4) by lra.
destruct (pre_sin_bound 1 0 (Rlt_le _ _ Rlt_0_1) t') as [t _].
apply Rlt_le_trans with (2 := t); clear t.
- simpl plus; replace (sin_approx 1 1) with (5/6);[fourier | ].
+ simpl plus; replace (sin_approx 1 1) with (5/6);[lra | ].
unfold sin_approx, sin_term; simpl; field.
apply sin_increasing_1.
- assert (t := PI2_1); fourier.
+ assert (t := PI2_1); lra.
apply Rlt_le, PI2_1.
- assert (t := PI2_1); fourier.
- fourier.
+ assert (t := PI2_1); lra.
+ lra.
assumption.
Qed.
@@ -547,7 +547,7 @@ intros x h; rewrite Ropp_div; apply Ropp_lt_contravar; assumption.
Qed.
Lemma pos_opp_lt : forall x, 0 < x -> -x < x.
-Proof. intros; fourier. Qed.
+Proof. intros; lra. Qed.
Lemma tech_opp_tan : forall x y, -tan x < y -> tan (-x) < y.
Proof.
@@ -562,7 +562,7 @@ set (pr := (conj (tech_opp_tan _ _ (proj2 (Rabs_def2 _ _ Ptan_ub)))
destruct (exists_atan_in_frame (-ub) ub y (pos_opp_lt _ ub0) (ub_opp _ ubpi2)
ubpi2 pr) as [v [[vl vu] vq]].
exists v; clear pr.
-split;[rewrite Ropp_div; split; fourier | assumption].
+split;[rewrite Ropp_div; split; lra | assumption].
Qed.
Definition atan x := let (v, _) := pre_atan x in v.
@@ -581,7 +581,7 @@ Lemma atan_opp : forall x, atan (- x) = - atan x.
Proof.
intros x; generalize (atan_bound (-x)); rewrite Ropp_div;intros [a b].
generalize (atan_bound x); rewrite Ropp_div; intros [c d].
-apply tan_is_inj; try rewrite Ropp_div; try split; try fourier.
+apply tan_is_inj; try rewrite Ropp_div; try split; try lra.
rewrite tan_neg, !atan_right_inv; reflexivity.
Qed.
@@ -604,23 +604,23 @@ assert (int_tan : forall y, tan (- ub) <= y -> y <= tan ub ->
rewrite <- (atan_right_inv y); apply tan_increasing.
destruct (atan_bound y); assumption.
assumption.
- fourier.
- fourier.
+ lra.
+ lra.
destruct (Rle_lt_dec (atan y) ub) as [h | abs]; auto.
assert (tan ub < y).
rewrite <- (atan_right_inv y); apply tan_increasing.
- rewrite Ropp_div; fourier.
+ rewrite Ropp_div; lra.
assumption.
destruct (atan_bound y); assumption.
- fourier.
+ lra.
assert (incr : forall x y, -ub <= x -> x < y -> y <= ub -> tan x < tan y).
intros y z l yz u; apply tan_increasing.
- rewrite Ropp_div; fourier.
+ rewrite Ropp_div; lra.
assumption.
- fourier.
+ lra.
assert (der : forall a, -ub <= a <= ub -> derivable_pt tan a).
intros a [la ua]; apply derivable_pt_tan.
- rewrite Ropp_div; split; fourier.
+ rewrite Ropp_div; split; lra.
assert (df_neq : derive_pt tan (atan x)
(derivable_pt_recip_interv_prelim1 tan atan
(- ub) ub x lb_lt_ub xint inv_p int_tan incr der) <> 0).
@@ -651,7 +651,7 @@ Qed.
Lemma atan_0 : atan 0 = 0.
Proof.
apply tan_is_inj; try (apply atan_bound).
- assert (t := PI_RGT_0); rewrite Ropp_div; split; fourier.
+ assert (t := PI_RGT_0); rewrite Ropp_div; split; lra.
rewrite atan_right_inv, tan_0.
reflexivity.
Qed.
@@ -659,7 +659,7 @@ Qed.
Lemma atan_1 : atan 1 = PI/4.
Proof.
assert (ut := PI_RGT_0).
-assert (-PI/2 < PI/4 < PI/2) by (rewrite Ropp_div; split; fourier).
+assert (-PI/2 < PI/4 < PI/2) by (rewrite Ropp_div; split; lra).
assert (t := atan_bound 1).
apply tan_is_inj; auto.
rewrite tan_PI4, atan_right_inv; reflexivity.
@@ -688,23 +688,23 @@ assert (int_tan : forall y, tan (- ub) <= y -> y <= tan ub ->
rewrite <- (atan_right_inv y); apply tan_increasing.
destruct (atan_bound y); assumption.
assumption.
- fourier.
- fourier.
+ lra.
+ lra.
destruct (Rle_lt_dec (atan y) ub) as [h | abs]; auto.
assert (tan ub < y).
rewrite <- (atan_right_inv y); apply tan_increasing.
- rewrite Ropp_div; fourier.
+ rewrite Ropp_div; lra.
assumption.
destruct (atan_bound y); assumption.
- fourier.
+ lra.
assert (incr : forall x y, -ub <= x -> x < y -> y <= ub -> tan x < tan y).
intros y z l yz u; apply tan_increasing.
- rewrite Ropp_div; fourier.
+ rewrite Ropp_div; lra.
assumption.
- fourier.
+ lra.
assert (der : forall a, -ub <= a <= ub -> derivable_pt tan a).
intros a [la ua]; apply derivable_pt_tan.
- rewrite Ropp_div; split; fourier.
+ rewrite Ropp_div; split; lra.
assert (df_neq : derive_pt tan (atan x)
(derivable_pt_recip_interv_prelim1 tan atan
(- ub) ub x lb_lt_ub xint inv_p int_tan incr der) <> 0).
@@ -883,7 +883,7 @@ Proof.
destruct (Rle_lt_dec 0 x).
assert (pr : 0 <= x <= 1) by tauto.
exact (ps_atan_exists_01 x pr).
-assert (pr : 0 <= -x <= 1) by (destruct Hx; split; fourier).
+assert (pr : 0 <= -x <= 1) by (destruct Hx; split; lra).
destruct (ps_atan_exists_01 _ pr) as [v Pv].
exists (-v).
apply (Un_cv_ext (fun n => (- 1) * sum_f_R0 (tg_alt (Ratan_seq (- x))) n)).
@@ -898,8 +898,8 @@ Proof.
destruct (Rle_lt_dec x 1).
destruct (Rle_lt_dec (-1) x).
left;split; auto.
- right;intros [a1 a2]; fourier.
-right;intros [a1 a2]; fourier.
+ right;intros [a1 a2]; lra.
+right;intros [a1 a2]; lra.
Qed.
Definition ps_atan (x : R) : R :=
@@ -922,7 +922,7 @@ unfold ps_atan.
unfold Rdiv; rewrite !Rmult_0_l, Rmult_0_r; reflexivity.
intros eps ep; exists 0%nat; intros n _; unfold R_dist.
rewrite Rminus_0_r, Rabs_pos_eq; auto with real.
-case h2; split; fourier.
+case h2; split; lra.
Qed.
Lemma ps_atan_exists_1_opp :
@@ -948,9 +948,9 @@ destruct (in_int (- x)) as [inside | outside].
destruct (in_int x) as [ins' | outs'].
generalize (ps_atan_exists_1_opp x inside ins').
intros h; exact h.
- destruct inside; case outs'; split; fourier.
+ destruct inside; case outs'; split; lra.
destruct (in_int x) as [ins' | outs'].
- destruct outside; case ins'; split; fourier.
+ destruct outside; case ins'; split; lra.
apply atan_opp.
Qed.
@@ -1057,7 +1057,7 @@ Proof.
intros x n.
assert (dif : - x ^ 2 <> 1).
apply Rlt_not_eq; apply Rle_lt_trans with 0;[ | apply Rlt_0_1].
-assert (t := pow2_ge_0 x); fourier.
+assert (t := pow2_ge_0 x); lra.
replace (1 + x ^ 2) with (1 - - (x ^ 2)) by ring; rewrite <- (tech3 _ n dif).
apply sum_eq; unfold tg_alt, Datan_seq; intros i _.
rewrite pow_mult, <- Rpow_mult_distr.
@@ -1073,7 +1073,7 @@ intros x y n n_lb x_encad ; assert (x_pos : x >= 0) by intuition.
apply False_ind ; intuition.
clear -x_encad x_pos y_pos ; induction n ; unfold Datan_seq.
case x_pos ; clear x_pos ; intro x_pos.
- simpl ; apply Rmult_gt_0_lt_compat ; intuition. fourier.
+ simpl ; apply Rmult_gt_0_lt_compat ; intuition. lra.
rewrite x_pos ; rewrite pow_i. replace (y ^ (2*1)) with (y*y).
apply Rmult_gt_0_compat ; assumption.
simpl ; field.
@@ -1084,7 +1084,7 @@ intros x y n n_lb x_encad ; assert (x_pos : x >= 0) by intuition.
case x_pos ; clear x_pos ; intro x_pos.
rewrite Hrew ; rewrite Hrew.
apply Rmult_gt_0_lt_compat ; intuition.
- apply Rmult_gt_0_lt_compat ; intuition ; fourier.
+ apply Rmult_gt_0_lt_compat ; intuition ; lra.
rewrite x_pos.
rewrite pow_i ; intuition.
Qed.
@@ -1141,7 +1141,7 @@ elim (pow_lt_1_zero _ x_ub2 _ eps'_pos) ; intros N HN ; exists N.
intros n Hn.
assert (H1 : - x^2 <> 1).
apply Rlt_not_eq; apply Rle_lt_trans with (2 := Rlt_0_1).
-assert (t := pow2_ge_0 x); fourier.
+assert (t := pow2_ge_0 x); lra.
rewrite Datan_sum_eq.
unfold R_dist.
assert (tool : forall a b, a / b - /b = (-1 + a) /b).
@@ -1179,13 +1179,13 @@ apply (Alt_CVU (fun x n => Datan_seq n x)
(Datan_seq (Rabs c + r)) c r).
intros x inb; apply Datan_seq_decreasing;
try (apply Boule_lt in inb; apply Rabs_def2 in inb;
- destruct inb; fourier).
+ destruct inb; lra).
intros x inb; apply Datan_seq_CV_0;
try (apply Boule_lt in inb; apply Rabs_def2 in inb;
- destruct inb; fourier).
+ destruct inb; lra).
intros x inb; apply (Datan_lim x);
try (apply Boule_lt in inb; apply Rabs_def2 in inb;
- destruct inb; fourier).
+ destruct inb; lra).
intros x [ | n] inb.
solve[unfold Datan_seq; apply Rle_refl].
rewrite <- (Datan_seq_Rabs x); apply Rlt_le, Datan_seq_increasing.
@@ -1193,7 +1193,7 @@ apply (Alt_CVU (fun x n => Datan_seq n x)
apply Boule_lt in inb; intuition.
solve[apply Rabs_pos].
apply Datan_seq_CV_0.
- apply Rlt_trans with 0;[fourier | ].
+ apply Rlt_trans with 0;[lra | ].
apply Rplus_le_lt_0_compat.
solve[apply Rabs_pos].
destruct r; assumption.
@@ -1226,7 +1226,7 @@ intros N x x_lb x_ub.
apply Hdelta ; assumption.
unfold id ; field ; assumption.
intros eps eps_pos.
- assert (eps_3_pos : (eps/3) > 0) by fourier.
+ assert (eps_3_pos : (eps/3) > 0) by lra.
elim (IHN (eps/3) eps_3_pos) ; intros delta1 Hdelta1.
assert (Main : derivable_pt_lim (fun x : R =>tg_alt (Ratan_seq x) (S N)) x ((tg_alt (Datan_seq x)) (S N))).
clear -Tool ; intros eps' eps'_pos.
@@ -1297,7 +1297,7 @@ intros N x x_lb x_ub.
intuition ; apply Rlt_le_trans with (r2:=delta) ; intuition unfold delta, mydelta.
apply Rmin_l.
apply Rmin_r.
- fourier.
+ lra.
Qed.
Lemma Ratan_CVU' :
@@ -1310,7 +1310,7 @@ apply (Alt_CVU (fun i r => Ratan_seq r i) ps_atan PI_tg (/2) pos_half);
now intros; apply Ratan_seq_converging, Boule_half_to_interval.
intros x b; apply Boule_half_to_interval in b.
unfold ps_atan; destruct (in_int x) as [inside | outside];
- [ | destruct b; case outside; split; fourier].
+ [ | destruct b; case outside; split; lra].
destruct (ps_atan_exists_1 x inside) as [v Pv].
apply Un_cv_ext with (2 := Pv);[reflexivity].
intros x n b; apply Boule_half_to_interval in b.
@@ -1330,7 +1330,7 @@ exists N; intros n x nN b_y.
case (Rtotal_order 0 x) as [xgt0 | [x0 | x0]].
assert (Boule (/2) {| pos := / 2; cond_pos := pos_half_prf|} x).
revert b_y; unfold Boule; simpl; intros b_y; apply Rabs_def2 in b_y.
- destruct b_y; unfold Boule; simpl; apply Rabs_def1; fourier.
+ destruct b_y; unfold Boule; simpl; apply Rabs_def1; lra.
apply Pn; assumption.
rewrite <- x0, ps_atan0_0.
rewrite <- (sum_eq (fun _ => 0)), sum_cte, Rmult_0_l, Rminus_0_r, Rabs_pos_eq.
@@ -1343,7 +1343,7 @@ replace (ps_atan x - sum_f_R0 (tg_alt (Ratan_seq x)) n) with
rewrite Rabs_Ropp.
assert (Boule (/2) {| pos := / 2; cond_pos := pos_half_prf|} (-x)).
revert b_y; unfold Boule; simpl; intros b_y; apply Rabs_def2 in b_y.
- destruct b_y; unfold Boule; simpl; apply Rabs_def1; fourier.
+ destruct b_y; unfold Boule; simpl; apply Rabs_def1; lra.
apply Pn; assumption.
unfold Rminus; rewrite ps_atan_opp, Ropp_plus_distr, sum_Ratan_seq_opp.
rewrite !Ropp_involutive; reflexivity.
@@ -1372,7 +1372,7 @@ apply continuity_inv.
apply continuity_plus.
apply continuity_const ; unfold constant ; intuition.
apply derivable_continuous ; apply derivable_pow.
-intro x ; apply Rgt_not_eq ; apply Rge_gt_trans with (1+0) ; [|fourier] ;
+intro x ; apply Rgt_not_eq ; apply Rge_gt_trans with (1+0) ; [|lra] ;
apply Rplus_ge_compat_l.
replace (x^2) with (x²).
apply Rle_ge ; apply Rle_0_sqr.
@@ -1393,11 +1393,11 @@ apply derivable_pt_lim_CVU with
assumption.
intros y N inb; apply Rabs_def2 in inb; destruct inb.
apply Datan_is_datan.
- fourier.
- fourier.
+ lra.
+ lra.
intros y inb; apply Rabs_def2 in inb; destruct inb.
- assert (y_gt_0 : -1 < y) by fourier.
- assert (y_lt_1 : y < 1) by fourier.
+ assert (y_gt_0 : -1 < y) by lra.
+ assert (y_lt_1 : y < 1) by lra.
intros eps eps_pos ; elim (Ratan_is_ps_atan eps eps_pos).
intros N HN ; exists N; intros n n_lb ; apply HN ; tauto.
apply Datan_CVU_prelim.
@@ -1406,8 +1406,8 @@ apply derivable_pt_lim_CVU with
replace ((c + r - (c - r)) / 2) with (r :R) by field.
assert (Rabs c < 1 - r).
unfold Boule in Pcr1; destruct r; simpl in *; apply Rabs_def1;
- apply Rabs_def2 in Pcr1; destruct Pcr1; fourier.
- fourier.
+ apply Rabs_def2 in Pcr1; destruct Pcr1; lra.
+ lra.
intros; apply Datan_continuity.
Qed.
@@ -1426,7 +1426,7 @@ Lemma ps_atan_continuity_pt_1 : forall eps : R,
dist R_met (ps_atan x) (Alt_PI/4) < eps).
Proof.
intros eps eps_pos.
-assert (eps_3_pos : eps / 3 > 0) by fourier.
+assert (eps_3_pos : eps / 3 > 0) by lra.
elim (Ratan_is_ps_atan (eps / 3) eps_3_pos) ; intros N1 HN1.
unfold Alt_PI.
destruct exist_PI as [v Pv]; replace ((4 * v)/4) with v by field.
@@ -1461,10 +1461,10 @@ rewrite Rplus_assoc ; apply Rabs_triang.
unfold D_x, no_cond ; split ; [ | apply Rgt_not_eq ] ; intuition.
intuition.
apply HN2; unfold N; omega.
- fourier.
+ lra.
rewrite <- Rabs_Ropp, Ropp_minus_distr; apply HN1.
unfold N; omega.
- fourier.
+ lra.
assumption.
field.
ring.
@@ -1486,11 +1486,11 @@ intros x x_encad Pratan Prmymeta.
rewrite Hrew1.
replace (Rsqr x) with (x ^ 2) by (unfold Rsqr; ring).
unfold Rdiv; rewrite Rmult_1_l; reflexivity.
- fourier.
+ lra.
assumption.
intros; reflexivity.
- fourier.
- assert (t := tan_1_gt_1); split;destruct x_encad; fourier.
+ lra.
+ assert (t := tan_1_gt_1); split;destruct x_encad; lra.
intros; reflexivity.
Qed.
@@ -1503,46 +1503,46 @@ assert (pr1 : forall c : R, 0 < c < x -> derivable_pt (atan - ps_atan) c).
apply derivable_pt_minus.
exact (derivable_pt_atan c).
apply derivable_pt_ps_atan.
- destruct x_encad; destruct c_encad; split; fourier.
+ destruct x_encad; destruct c_encad; split; lra.
assert (pr2 : forall c : R, 0 < c < x -> derivable_pt id c).
- intros ; apply derivable_pt_id; fourier.
+ intros ; apply derivable_pt_id; lra.
assert (delta_cont : forall c : R, 0 <= c <= x -> continuity_pt (atan - ps_atan) c).
intros c [[c_encad1 | c_encad1 ] [c_encad2 | c_encad2]];
apply continuity_pt_minus.
apply derivable_continuous_pt ; apply derivable_pt_atan.
apply derivable_continuous_pt ; apply derivable_pt_ps_atan.
- split; destruct x_encad; fourier.
+ split; destruct x_encad; lra.
apply derivable_continuous_pt, derivable_pt_atan.
apply derivable_continuous_pt, derivable_pt_ps_atan.
- subst c; destruct x_encad; split; fourier.
+ subst c; destruct x_encad; split; lra.
apply derivable_continuous_pt, derivable_pt_atan.
apply derivable_continuous_pt, derivable_pt_ps_atan.
- subst c; split; fourier.
+ subst c; split; lra.
apply derivable_continuous_pt, derivable_pt_atan.
apply derivable_continuous_pt, derivable_pt_ps_atan.
- subst c; destruct x_encad; split; fourier.
+ subst c; destruct x_encad; split; lra.
assert (id_cont : forall c : R, 0 <= c <= x -> continuity_pt id c).
intros ; apply derivable_continuous ; apply derivable_id.
-assert (x_lb : 0 < x) by (destruct x_encad; fourier).
+assert (x_lb : 0 < x) by (destruct x_encad; lra).
elim (MVT (atan - ps_atan)%F id 0 x pr1 pr2 x_lb delta_cont id_cont) ; intros d Temp ; elim Temp ; intros d_encad Main.
clear - Main x_encad.
assert (Temp : forall (pr: derivable_pt (atan - ps_atan) d), derive_pt (atan - ps_atan) d pr = 0).
intro pr.
assert (d_encad3 : -1 < d < 1).
- destruct d_encad; destruct x_encad; split; fourier.
+ destruct d_encad; destruct x_encad; split; lra.
pose (pr3 := derivable_pt_minus atan ps_atan d (derivable_pt_atan d) (derivable_pt_ps_atan d d_encad3)).
rewrite <- pr_nu_var2_interv with (f:=(atan - ps_atan)%F) (g:=(atan - ps_atan)%F) (lb:=0) (ub:=x) (pr1:=pr3) (pr2:=pr).
unfold pr3. rewrite derive_pt_minus.
rewrite Datan_eq_DatanSeq_interv with (Prmymeta := derivable_pt_atan d).
intuition.
assumption.
- destruct d_encad; fourier.
+ destruct d_encad; lra.
assumption.
reflexivity.
assert (iatan0 : atan 0 = 0).
apply tan_is_inj.
apply atan_bound.
- rewrite Ropp_div; assert (t := PI2_RGT_0); split; fourier.
+ rewrite Ropp_div; assert (t := PI2_RGT_0); split; lra.
rewrite tan_0, atan_right_inv; reflexivity.
generalize Main; rewrite Temp, Rmult_0_r.
replace ((atan - ps_atan)%F x) with (atan x - ps_atan x) by intuition.
@@ -1560,19 +1560,19 @@ Qed.
Theorem Alt_PI_eq : Alt_PI = PI.
Proof.
apply Rmult_eq_reg_r with (/4); fold (Alt_PI/4); fold (PI/4);
- [ | apply Rgt_not_eq; fourier].
+ [ | apply Rgt_not_eq; lra].
assert (0 < PI/6) by (apply PI6_RGT_0).
assert (t1:= PI2_1).
assert (t2 := PI_4).
assert (m := Alt_PI_RGT_0).
-assert (-PI/2 < 1 < PI/2) by (rewrite Ropp_div; split; fourier).
+assert (-PI/2 < 1 < PI/2) by (rewrite Ropp_div; split; lra).
apply cond_eq; intros eps ep.
change (R_dist (Alt_PI/4) (PI/4) < eps).
assert (ca : continuity_pt atan 1).
apply derivable_continuous_pt, derivable_pt_atan.
assert (Xe : exists eps', exists eps'',
eps' + eps'' <= eps /\ 0 < eps' /\ 0 < eps'').
- exists (eps/2); exists (eps/2); repeat apply conj; fourier.
+ exists (eps/2); exists (eps/2); repeat apply conj; lra.
destruct Xe as [eps' [eps'' [eps_ineq [ep' ep'']]]].
destruct (ps_atan_continuity_pt_1 _ ep') as [alpha [a0 Palpha]].
destruct (ca _ ep'') as [beta [b0 Pbeta]].
@@ -1585,14 +1585,14 @@ assert (Xa : exists a, 0 < a < 1 /\ R_dist a 1 < alpha /\
assert ((1 - alpha /2) <= Rmax (1 - alpha /2) (1 - beta /2)) by apply Rmax_l.
assert ((1 - beta /2) <= Rmax (1 - alpha /2) (1 - beta /2)) by apply Rmax_r.
assert (Rmax (1 - alpha /2) (1 - beta /2) < 1)
- by (apply Rmax_lub_lt; fourier).
- split;[split;[ | apply Rmax_lub_lt]; fourier | ].
+ by (apply Rmax_lub_lt; lra).
+ split;[split;[ | apply Rmax_lub_lt]; lra | ].
assert (0 <= 1 - Rmax (/ 2) (Rmax (1 - alpha / 2) (1 - beta / 2))).
assert (Rmax (/2) (Rmax (1 - alpha / 2)
- (1 - beta /2)) <= 1) by (apply Rmax_lub; fourier).
- fourier.
+ (1 - beta /2)) <= 1) by (apply Rmax_lub; lra).
+ lra.
split; unfold R_dist; rewrite <-Rabs_Ropp, Ropp_minus_distr,
- Rabs_pos_eq;fourier.
+ Rabs_pos_eq;lra.
destruct Xa as [a [[Pa0 Pa1] [P1 P2]]].
apply Rle_lt_trans with (1 := R_dist_tri _ _ (ps_atan a)).
apply Rlt_le_trans with (2 := eps_ineq).
diff --git a/theories/Reals/Rbasic_fun.v b/theories/Reals/Rbasic_fun.v
index aa886cee..59e01486 100644
--- a/theories/Reals/Rbasic_fun.v
+++ b/theories/Reals/Rbasic_fun.v
@@ -15,7 +15,7 @@
Require Import Rbase.
Require Import R_Ifp.
-Require Import Fourier.
+Require Import Lra.
Local Open Scope R_scope.
Implicit Type r : R.
@@ -357,7 +357,7 @@ Qed.
Lemma Rle_abs : forall x:R, x <= Rabs x.
Proof.
- intro; unfold Rabs; case (Rcase_abs x); intros; fourier.
+ intro; unfold Rabs; case (Rcase_abs x); intros; lra.
Qed.
Definition RRle_abs := Rle_abs.
diff --git a/theories/Reals/Rderiv.v b/theories/Reals/Rderiv.v
index dfa5c710..aaf691ed 100644
--- a/theories/Reals/Rderiv.v
+++ b/theories/Reals/Rderiv.v
@@ -16,7 +16,7 @@
Require Import Rbase.
Require Import Rfunctions.
Require Import Rlimit.
-Require Import Fourier.
+Require Import Lra.
Require Import Omega.
Local Open Scope R_scope.
@@ -77,7 +77,7 @@ Proof.
elim (Rmin_Rgt (/ 2) x 0); intros a b; cut (0 < 2).
intro; generalize (Rinv_0_lt_compat 2 H3); intro; fold (/ 2 > 0) in H4;
apply (b (conj H4 H)).
- fourier.
+ lra.
intros; elim H3; clear H3; intros;
generalize
(let (H1, H2) :=
@@ -167,7 +167,7 @@ Proof.
unfold Rabs; destruct (Rcase_abs 2) as [Hlt|Hge]; auto.
cut (0 < 2).
intro H7; elim (Rlt_asym 0 2 H7 Hlt).
- fourier.
+ lra.
apply Rabs_no_R0.
discrR.
Qed.
diff --git a/theories/Reals/Reals.v b/theories/Reals/Reals.v
index b249b519..3ef368bb 100644
--- a/theories/Reals/Reals.v
+++ b/theories/Reals/Reals.v
@@ -30,3 +30,4 @@ Require Export SeqSeries.
Require Export Rtrigo.
Require Export Ranalysis.
Require Export Integration.
+Require Import Fourier.
diff --git a/theories/Reals/Rlimit.v b/theories/Reals/Rlimit.v
index b14fcc4d..e3e995d2 100644
--- a/theories/Reals/Rlimit.v
+++ b/theories/Reals/Rlimit.v
@@ -15,7 +15,7 @@
Require Import Rbase.
Require Import Rfunctions.
-Require Import Fourier.
+Require Import Lra.
Local Open Scope R_scope.
(*******************************)
@@ -24,7 +24,7 @@ Local Open Scope R_scope.
(*********)
Lemma eps2_Rgt_R0 : forall eps:R, eps > 0 -> eps * / 2 > 0.
Proof.
- intros; fourier.
+ intros; lra.
Qed.
(*********)
@@ -45,14 +45,14 @@ Qed.
Lemma Rlt_eps2_eps : forall eps:R, eps > 0 -> eps * / 2 < eps.
Proof.
intros.
- fourier.
+ lra.
Qed.
(*********)
Lemma Rlt_eps4_eps : forall eps:R, eps > 0 -> eps * / (2 + 2) < eps.
Proof.
intros.
- fourier.
+ lra.
Qed.
(*********)
diff --git a/theories/Reals/Rpower.v b/theories/Reals/Rpower.v
index c6fac951..d465523a 100644
--- a/theories/Reals/Rpower.v
+++ b/theories/Reals/Rpower.v
@@ -25,7 +25,7 @@ Require Import R_sqrt.
Require Import Sqrt_reg.
Require Import MVT.
Require Import Ranalysis4.
-Require Import Fourier.
+Require Import Lra.
Local Open Scope R_scope.
Lemma P_Rmin : forall (P:R -> Prop) (x y:R), P x -> P y -> P (Rmin x y).
@@ -714,7 +714,7 @@ Qed.
Lemma Rlt_Rpower_l a b c: 0 < c -> 0 < a < b -> a ^R c < b ^R c.
Proof.
intros c0 [a0 ab]; apply exp_increasing.
-now apply Rmult_lt_compat_l; auto; apply ln_increasing; fourier.
+now apply Rmult_lt_compat_l; auto; apply ln_increasing; lra.
Qed.
Lemma Rle_Rpower_l a b c: 0 <= c -> 0 < a <= b -> a ^R c <= b ^R c.
@@ -722,7 +722,7 @@ Proof.
intros [c0 | c0];
[ | intros; rewrite <- c0, !Rpower_O; [apply Rle_refl | |] ].
intros [a0 [ab|ab]].
- now apply Rlt_le, Rlt_Rpower_l;[ | split]; fourier.
+ now apply Rlt_le, Rlt_Rpower_l;[ | split]; lra.
rewrite ab; apply Rle_refl.
apply Rlt_le_trans with a; tauto.
tauto.
@@ -754,10 +754,10 @@ assert (cmp : 0 < x + sqrt (x ^ 2 + 1)).
replace (x ^ 2) with ((-x) ^ 2) by ring.
assert (sqrt ((- x) ^ 2) < sqrt ((-x)^2+1)).
apply sqrt_lt_1_alt.
- split;[apply pow_le | ]; fourier.
+ split;[apply pow_le | ]; lra.
pattern x at 1; replace x with (- (sqrt ((- x) ^ 2))).
- assert (t:= sqrt_pos ((-x)^2)); fourier.
- simpl; rewrite Rmult_1_r, sqrt_square, Ropp_involutive;[reflexivity | fourier].
+ assert (t:= sqrt_pos ((-x)^2)); lra.
+ simpl; rewrite Rmult_1_r, sqrt_square, Ropp_involutive;[reflexivity | lra].
apply Rplus_lt_le_0_compat;[apply Rnot_le_gt; assumption | apply sqrt_pos].
rewrite exp_ln;[ | assumption].
rewrite exp_Ropp, exp_ln;[ | assumption].
@@ -770,7 +770,7 @@ apply Rmult_eq_reg_l with (2 * (x + sqrt (x ^ 2 + 1)));[ |
apply Rgt_not_eq, Rmult_lt_0_compat;[apply Rlt_0_2 | assumption]].
assert (pow2_sqrt : forall x, 0 <= x -> sqrt x ^ 2 = x) by
(intros; simpl; rewrite Rmult_1_r, sqrt_sqrt; auto).
-field_simplify;[rewrite pow2_sqrt;[field | ] | apply Rgt_not_eq; fourier].
+field_simplify;[rewrite pow2_sqrt;[field | ] | apply Rgt_not_eq; lra].
apply Rplus_le_le_0_compat;[simpl; rewrite Rmult_1_r; apply (Rle_0_sqr x)|apply Rlt_le, Rlt_0_1].
Qed.
@@ -784,12 +784,12 @@ assert (0 < x + sqrt (x ^ 2 + 1)).
replace (x ^ 2) with ((-x) ^ 2) by ring.
assert (sqrt ((- x) ^ 2) < sqrt ((-x)^2+1)).
apply sqrt_lt_1_alt.
- split;[apply pow_le|]; fourier.
+ split;[apply pow_le|]; lra.
pattern x at 1; replace x with (- (sqrt ((- x) ^ 2))).
- assert (t:= sqrt_pos ((-x)^2)); fourier.
- simpl; rewrite Rmult_1_r, sqrt_square, Ropp_involutive; auto; fourier.
+ assert (t:= sqrt_pos ((-x)^2)); lra.
+ simpl; rewrite Rmult_1_r, sqrt_square, Ropp_involutive; auto; lra.
assert (0 < x ^ 2 + 1).
- apply Rplus_le_lt_0_compat;[simpl; rewrite Rmult_1_r; apply Rle_0_sqr|fourier].
+ apply Rplus_le_lt_0_compat;[simpl; rewrite Rmult_1_r; apply Rle_0_sqr|lra].
replace (/sqrt (x ^ 2 + 1)) with
(/(x + sqrt (x ^ 2 + 1)) *
(1 + (/(2 * sqrt (x ^ 2 + 1)) * (INR 2 * x ^ 1 + 0)))).
@@ -817,7 +817,7 @@ intros x y xy.
case (Rle_dec (arcsinh y) (arcsinh x));[ | apply Rnot_le_lt ].
intros abs; case (Rlt_not_le _ _ xy).
rewrite <- (sinh_arcsinh y), <- (sinh_arcsinh x).
-destruct abs as [lt | q];[| rewrite q; fourier].
+destruct abs as [lt | q];[| rewrite q; lra].
apply Rlt_le, sinh_lt; assumption.
Qed.
diff --git a/theories/Reals/Rsqrt_def.v b/theories/Reals/Rsqrt_def.v
index 6a3dd976..9b8dd1db 100644
--- a/theories/Reals/Rsqrt_def.v
+++ b/theories/Reals/Rsqrt_def.v
@@ -392,7 +392,7 @@ Definition cond_positivity (x:R) : bool :=
| right _ => false
end.
-(** Sequential caracterisation of continuity *)
+(** Sequential characterisation of continuity *)
Lemma continuity_seq :
forall (f:R -> R) (Un:nat -> R) (l:R),
continuity_pt f l -> Un_cv Un l -> Un_cv (fun i:nat => f (Un i)) (f l).
diff --git a/theories/Reals/Rtrigo.v b/theories/Reals/Rtrigo.v
index ffc0adf5..ddd8722e 100644
--- a/theories/Reals/Rtrigo.v
+++ b/theories/Reals/Rtrigo.v
@@ -18,7 +18,7 @@ Require Export Cos_rel.
Require Export Cos_plus.
Require Import ZArith_base.
Require Import Zcomplements.
-Require Import Fourier.
+Require Import Lra.
Require Import Ranalysis1.
Require Import Rsqrt_def.
Require Import PSeries_reg.
diff --git a/theories/Reals/Rtrigo1.v b/theories/Reals/Rtrigo1.v
index bf00f736..a75fd2dd 100644
--- a/theories/Reals/Rtrigo1.v
+++ b/theories/Reals/Rtrigo1.v
@@ -18,7 +18,7 @@ Require Export Cos_rel.
Require Export Cos_plus.
Require Import ZArith_base.
Require Import Zcomplements.
-Require Import Fourier.
+Require Import Lra.
Require Import Ranalysis1.
Require Import Rsqrt_def.
Require Import PSeries_reg.
@@ -175,10 +175,10 @@ Qed.
Lemma sin_gt_cos_7_8 : sin (7 / 8) > cos (7 / 8).
Proof.
-assert (lo1 : 0 <= 7/8) by fourier.
-assert (up1 : 7/8 <= 4) by fourier.
-assert (lo : -2 <= 7/8) by fourier.
-assert (up : 7/8 <= 2) by fourier.
+assert (lo1 : 0 <= 7/8) by lra.
+assert (up1 : 7/8 <= 4) by lra.
+assert (lo : -2 <= 7/8) by lra.
+assert (up : 7/8 <= 2) by lra.
destruct (pre_sin_bound _ 0 lo1 up1) as [lower _ ].
destruct (pre_cos_bound _ 0 lo up) as [_ upper].
apply Rle_lt_trans with (1 := upper).
@@ -205,12 +205,12 @@ Definition PI_2_aux : {z | 7/8 <= z <= 7/4 /\ -cos z = 0}.
assert (cc : continuity (fun r =>- cos r)).
apply continuity_opp, continuity_cos.
assert (cvp : 0 < cos (7/8)).
- assert (int78 : -2 <= 7/8 <= 2) by (split; fourier).
+ assert (int78 : -2 <= 7/8 <= 2) by (split; lra).
destruct int78 as [lower upper].
case (pre_cos_bound _ 0 lower upper).
unfold cos_approx; simpl sum_f_R0; unfold cos_term.
intros cl _; apply Rlt_le_trans with (2 := cl); simpl.
- fourier.
+ lra.
assert (cun : cos (7/4) < 0).
replace (7/4) with (7/8 + 7/8) by field.
rewrite cos_plus.
@@ -218,7 +218,7 @@ assert (cun : cos (7/4) < 0).
exact sin_gt_cos_7_8.
apply Rlt_le; assumption.
apply Rlt_le; apply Rlt_trans with (1 := cvp); exact sin_gt_cos_7_8.
-apply IVT; auto; fourier.
+apply IVT; auto; lra.
Qed.
Definition PI2 := proj1_sig PI_2_aux.
@@ -270,7 +270,7 @@ Qed.
Lemma sin_pos_tech : forall x, 0 < x < 2 -> 0 < sin x.
intros x [int1 int2].
assert (lo : 0 <= x) by (apply Rlt_le; assumption).
-assert (up : x <= 4) by (apply Rlt_le, Rlt_trans with (1:=int2); fourier).
+assert (up : x <= 4) by (apply Rlt_le, Rlt_trans with (1:=int2); lra).
destruct (pre_sin_bound _ 0 lo up) as [t _]; clear lo up.
apply Rlt_le_trans with (2:= t); clear t.
unfold sin_approx; simpl sum_f_R0; unfold sin_term; simpl.
@@ -280,13 +280,13 @@ end.
assert (t' : x ^ 2 <= 4).
replace 4 with (2 ^ 2) by field.
apply (pow_incr x 2); split; apply Rlt_le; assumption.
-apply Rmult_lt_0_compat;[assumption | fourier ].
+apply Rmult_lt_0_compat;[assumption | lra ].
Qed.
Lemma sin_PI2 : sin (PI / 2) = 1.
replace (PI / 2) with PI2 by (unfold PI; field).
assert (int' : 0 < PI2 < 2).
- destruct pi2_int; split; fourier.
+ destruct pi2_int; split; lra.
assert (lo2 := sin_pos_tech PI2 int').
assert (t2 : Rabs (sin PI2) = 1).
rewrite <- Rabs_R1; apply Rsqr_eq_abs_0.
@@ -295,10 +295,10 @@ revert t2; rewrite Rabs_pos_eq;[| apply Rlt_le]; tauto.
Qed.
Lemma PI_RGT_0 : PI > 0.
-Proof. unfold PI; destruct pi2_int; fourier. Qed.
+Proof. unfold PI; destruct pi2_int; lra. Qed.
Lemma PI_4 : PI <= 4.
-Proof. unfold PI; destruct pi2_int; fourier. Qed.
+Proof. unfold PI; destruct pi2_int; lra. Qed.
(**********)
Lemma PI_neq0 : PI <> 0.
@@ -344,13 +344,13 @@ Lemma cos_bound : forall (a : R) (n : nat), - PI / 2 <= a -> a <= PI / 2 ->
Proof.
intros a n lower upper; apply pre_cos_bound.
apply Rle_trans with (2 := lower).
- apply Rmult_le_reg_r with 2; [fourier |].
+ apply Rmult_le_reg_r with 2; [lra |].
replace ((-PI/2) * 2) with (-PI) by field.
- assert (t := PI_4); fourier.
+ assert (t := PI_4); lra.
apply Rle_trans with (1 := upper).
-apply Rmult_le_reg_r with 2; [fourier | ].
+apply Rmult_le_reg_r with 2; [lra | ].
replace ((PI/2) * 2) with PI by field.
-generalize PI_4; intros; fourier.
+generalize PI_4; intros; lra.
Qed.
(**********)
Lemma neg_cos : forall x:R, cos (x + PI) = - cos x.
@@ -749,19 +749,19 @@ Qed.
Lemma _PI2_RLT_0 : - (PI / 2) < 0.
Proof.
assert (H := PI_RGT_0).
- fourier.
+ lra.
Qed.
Lemma PI4_RLT_PI2 : PI / 4 < PI / 2.
Proof.
assert (H := PI_RGT_0).
- fourier.
+ lra.
Qed.
Lemma PI2_Rlt_PI : PI / 2 < PI.
Proof.
assert (H := PI_RGT_0).
- fourier.
+ lra.
Qed.
(***************************************************)
diff --git a/theories/Reals/Rtrigo_calc.v b/theories/Reals/Rtrigo_calc.v
index 7cbfc630..78797c87 100644
--- a/theories/Reals/Rtrigo_calc.v
+++ b/theories/Reals/Rtrigo_calc.v
@@ -205,7 +205,6 @@ Proof with trivial.
rewrite cos2; unfold Rsqr; rewrite sin_PI6; rewrite sqrt_def...
field.
left ; prove_sup0.
- discrR.
Qed.
Lemma tan_PI6 : tan (PI / 6) = 1 / sqrt 3.
diff --git a/theories/Strings/Ascii.v b/theories/Strings/Ascii.v
index 5154b75b..31a7fb8a 100644
--- a/theories/Strings/Ascii.v
+++ b/theories/Strings/Ascii.v
@@ -40,6 +40,40 @@ Proof.
decide equality; apply bool_dec.
Defined.
+Local Open Scope lazy_bool_scope.
+
+Definition eqb (a b : ascii) : bool :=
+ match a, b with
+ | Ascii a0 a1 a2 a3 a4 a5 a6 a7,
+ Ascii b0 b1 b2 b3 b4 b5 b6 b7 =>
+ Bool.eqb a0 b0 &&& Bool.eqb a1 b1 &&& Bool.eqb a2 b2 &&& Bool.eqb a3 b3
+ &&& Bool.eqb a4 b4 &&& Bool.eqb a5 b5 &&& Bool.eqb a6 b6 &&& Bool.eqb a7 b7
+ end.
+
+Infix "=?" := eqb : char_scope.
+
+Lemma eqb_spec (a b : ascii) : reflect (a = b) (a =? b)%char.
+Proof.
+ destruct a, b; simpl.
+ do 8 (case Bool.eqb_spec; [ intros -> | constructor; now intros [= ] ]).
+ now constructor.
+Qed.
+
+Local Ltac t_eqb :=
+ repeat first [ congruence
+ | progress subst
+ | apply conj
+ | match goal with
+ | [ |- context[eqb ?x ?y] ] => destruct (eqb_spec x y)
+ end
+ | intro ].
+Lemma eqb_refl x : (x =? x)%char = true. Proof. t_eqb. Qed.
+Lemma eqb_sym x y : (x =? y)%char = (y =? x)%char. Proof. t_eqb. Qed.
+Lemma eqb_eq n m : (n =? m)%char = true <-> n = m. Proof. t_eqb. Qed.
+Lemma eqb_neq x y : (x =? y)%char = false <-> x <> y. Proof. t_eqb. Qed.
+Lemma eqb_compat: Morphisms.Proper (Morphisms.respectful eq (Morphisms.respectful eq eq)) eqb.
+Proof. t_eqb. Qed.
+
(** * Conversion between natural numbers modulo 256 and ascii characters *)
(** Auxiliary function that turns a positive into an ascii by
diff --git a/theories/Strings/BinaryString.v b/theories/Strings/BinaryString.v
new file mode 100644
index 00000000..6df0a917
--- /dev/null
+++ b/theories/Strings/BinaryString.v
@@ -0,0 +1,147 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+Require Import Ascii String.
+Require Import BinNums.
+Import BinNatDef.
+Import BinIntDef.
+Import BinPosDef.
+
+Local Open Scope positive_scope.
+Local Open Scope string_scope.
+
+Definition ascii_to_digit (ch : ascii) : option N
+ := (if ascii_dec ch "0" then Some 0
+ else if ascii_dec ch "1" then Some 1
+ else None)%N.
+
+Fixpoint pos_bin_app (p q:positive) : positive :=
+ match q with
+ | q~0 => (pos_bin_app p q)~0
+ | q~1 => (pos_bin_app p q)~1
+ | 1 => p~1
+ end.
+
+Module Raw.
+ Fixpoint of_pos (p : positive) (rest : string) : string
+ := match p with
+ | 1 => String "1" rest
+ | p'~0 => of_pos p' (String "0" rest)
+ | p'~1 => of_pos p' (String "1" rest)
+ end.
+
+ Fixpoint to_N (s : string) (rest : N)
+ : N
+ := match s with
+ | "" => rest
+ | String ch s'
+ => to_N
+ s'
+ match ascii_to_digit ch with
+ | Some v => N.add v (N.double rest)
+ | None => N0
+ end
+ end.
+
+ Fixpoint to_N_of_pos (p : positive) (rest : string) (base : N)
+ : to_N (of_pos p rest) base
+ = to_N rest match base with
+ | N0 => N.pos p
+ | Npos v => Npos (pos_bin_app v p)
+ end.
+ Proof.
+ destruct p as [p|p|]; destruct base; try reflexivity;
+ cbn; rewrite to_N_of_pos; reflexivity.
+ Qed.
+End Raw.
+
+Definition of_pos (p : positive) : string
+ := String "0" (String "b" (Raw.of_pos p "")).
+Definition of_N (n : N) : string
+ := match n with
+ | N0 => "0b0"
+ | Npos p => of_pos p
+ end.
+Definition of_Z (z : Z) : string
+ := match z with
+ | Zneg p => String "-" (of_pos p)
+ | Z0 => "0b0"
+ | Zpos p => of_pos p
+ end.
+Definition of_nat (n : nat) : string
+ := of_N (N.of_nat n).
+
+Definition to_N (s : string) : N
+ := match s with
+ | String s0 (String sb s)
+ => if ascii_dec s0 "0"
+ then if ascii_dec sb "b"
+ then Raw.to_N s N0
+ else N0
+ else N0
+ | _ => N0
+ end.
+Definition to_pos (s : string) : positive
+ := match to_N s with
+ | N0 => 1
+ | Npos p => p
+ end.
+Definition to_Z (s : string) : Z
+ := let '(is_neg, n) := match s with
+ | String s0 s'
+ => if ascii_dec s0 "-"
+ then (true, to_N s')
+ else (false, to_N s)
+ | EmptyString => (false, to_N s)
+ end in
+ match n with
+ | N0 => Z0
+ | Npos p => if is_neg then Zneg p else Zpos p
+ end.
+Definition to_nat (s : string) : nat
+ := N.to_nat (to_N s).
+
+Lemma to_N_of_N (n : N)
+ : to_N (of_N n)
+ = n.
+Proof.
+ destruct n; [ reflexivity | apply Raw.to_N_of_pos ].
+Qed.
+
+Lemma Z_of_of_Z (z : Z)
+ : to_Z (of_Z z)
+ = z.
+Proof.
+ cbv [of_Z to_Z]; destruct z as [|z|z]; cbn;
+ try reflexivity;
+ rewrite Raw.to_N_of_pos; cbn; reflexivity.
+Qed.
+
+Lemma to_nat_of_nat (n : nat)
+ : to_nat (of_nat n)
+ = n.
+Proof.
+ cbv [to_nat of_nat];
+ rewrite to_N_of_N, Nnat.Nat2N.id; reflexivity.
+Qed.
+
+Lemma to_pos_of_pos (p : positive)
+ : to_pos (of_pos p)
+ = p.
+Proof.
+ cbv [of_pos to_pos to_N]; cbn;
+ rewrite Raw.to_N_of_pos; cbn; reflexivity.
+Qed.
+
+Example of_pos_1 : of_pos 1 = "0b1" := eq_refl.
+Example of_pos_2 : of_pos 2 = "0b10" := eq_refl.
+Example of_pos_3 : of_pos 3 = "0b11" := eq_refl.
+Example of_N_0 : of_N 0 = "0b0" := eq_refl.
+Example of_Z_0 : of_Z 0 = "0b0" := eq_refl.
+Example of_Z_m1 : of_Z (-1) = "-0b1" := eq_refl.
+Example of_nat_0 : of_nat 0 = "0b0" := eq_refl.
diff --git a/theories/Strings/HexString.v b/theories/Strings/HexString.v
new file mode 100644
index 00000000..9ea93c90
--- /dev/null
+++ b/theories/Strings/HexString.v
@@ -0,0 +1,229 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+Require Import Ascii String.
+Require Import BinNums.
+Import BinNatDef.
+Import BinIntDef.
+Import BinPosDef.
+
+Local Open Scope positive_scope.
+Local Open Scope string_scope.
+
+Local Notation "a || b"
+ := (if a then true else if b then true else false).
+Definition ascii_to_digit (ch : ascii) : option N
+ := (if ascii_dec ch "0" then Some 0
+ else if ascii_dec ch "1" then Some 1
+ else if ascii_dec ch "2" then Some 2
+ else if ascii_dec ch "3" then Some 3
+ else if ascii_dec ch "4" then Some 4
+ else if ascii_dec ch "5" then Some 5
+ else if ascii_dec ch "6" then Some 6
+ else if ascii_dec ch "7" then Some 7
+ else if ascii_dec ch "8" then Some 8
+ else if ascii_dec ch "9" then Some 9
+ else if ascii_dec ch "a" || ascii_dec ch "A" then Some 10
+ else if ascii_dec ch "b" || ascii_dec ch "B" then Some 11
+ else if ascii_dec ch "c" || ascii_dec ch "C" then Some 12
+ else if ascii_dec ch "d" || ascii_dec ch "D" then Some 13
+ else if ascii_dec ch "e" || ascii_dec ch "E" then Some 14
+ else if ascii_dec ch "f" || ascii_dec ch "F" then Some 15
+ else None)%N.
+
+Fixpoint pos_hex_app (p q:positive) : positive :=
+ match q with
+ | 1 => p~0~0~0~1
+ | 2 => p~0~0~1~0
+ | 3 => p~0~0~1~1
+ | 4 => p~0~1~0~0
+ | 5 => p~0~1~0~1
+ | 6 => p~0~1~1~0
+ | 7 => p~0~1~1~1
+ | 8 => p~1~0~0~0
+ | 9 => p~1~0~0~1
+ | 10 => p~1~0~1~0
+ | 11 => p~1~0~1~1
+ | 12 => p~1~1~0~0
+ | 13 => p~1~1~0~1
+ | 14 => p~1~1~1~0
+ | 15 => p~1~1~1~1
+ | q~0~0~0~0 => (pos_hex_app p q)~0~0~0~0
+ | q~0~0~0~1 => (pos_hex_app p q)~0~0~0~1
+ | q~0~0~1~0 => (pos_hex_app p q)~0~0~1~0
+ | q~0~0~1~1 => (pos_hex_app p q)~0~0~1~1
+ | q~0~1~0~0 => (pos_hex_app p q)~0~1~0~0
+ | q~0~1~0~1 => (pos_hex_app p q)~0~1~0~1
+ | q~0~1~1~0 => (pos_hex_app p q)~0~1~1~0
+ | q~0~1~1~1 => (pos_hex_app p q)~0~1~1~1
+ | q~1~0~0~0 => (pos_hex_app p q)~1~0~0~0
+ | q~1~0~0~1 => (pos_hex_app p q)~1~0~0~1
+ | q~1~0~1~0 => (pos_hex_app p q)~1~0~1~0
+ | q~1~0~1~1 => (pos_hex_app p q)~1~0~1~1
+ | q~1~1~0~0 => (pos_hex_app p q)~1~1~0~0
+ | q~1~1~0~1 => (pos_hex_app p q)~1~1~0~1
+ | q~1~1~1~0 => (pos_hex_app p q)~1~1~1~0
+ | q~1~1~1~1 => (pos_hex_app p q)~1~1~1~1
+ end.
+
+Module Raw.
+ Fixpoint of_pos (p : positive) (rest : string) : string
+ := match p with
+ | 1 => String "1" rest
+ | 2 => String "2" rest
+ | 3 => String "3" rest
+ | 4 => String "4" rest
+ | 5 => String "5" rest
+ | 6 => String "6" rest
+ | 7 => String "7" rest
+ | 8 => String "8" rest
+ | 9 => String "9" rest
+ | 10 => String "a" rest
+ | 11 => String "b" rest
+ | 12 => String "c" rest
+ | 13 => String "d" rest
+ | 14 => String "e" rest
+ | 15 => String "f" rest
+ | p'~0~0~0~0 => of_pos p' (String "0" rest)
+ | p'~0~0~0~1 => of_pos p' (String "1" rest)
+ | p'~0~0~1~0 => of_pos p' (String "2" rest)
+ | p'~0~0~1~1 => of_pos p' (String "3" rest)
+ | p'~0~1~0~0 => of_pos p' (String "4" rest)
+ | p'~0~1~0~1 => of_pos p' (String "5" rest)
+ | p'~0~1~1~0 => of_pos p' (String "6" rest)
+ | p'~0~1~1~1 => of_pos p' (String "7" rest)
+ | p'~1~0~0~0 => of_pos p' (String "8" rest)
+ | p'~1~0~0~1 => of_pos p' (String "9" rest)
+ | p'~1~0~1~0 => of_pos p' (String "a" rest)
+ | p'~1~0~1~1 => of_pos p' (String "b" rest)
+ | p'~1~1~0~0 => of_pos p' (String "c" rest)
+ | p'~1~1~0~1 => of_pos p' (String "d" rest)
+ | p'~1~1~1~0 => of_pos p' (String "e" rest)
+ | p'~1~1~1~1 => of_pos p' (String "f" rest)
+ end.
+
+ Fixpoint to_N (s : string) (rest : N)
+ : N
+ := match s with
+ | "" => rest
+ | String ch s'
+ => to_N
+ s'
+ match ascii_to_digit ch with
+ | Some v => N.add v (N.mul 16 rest)
+ | None => N0
+ end
+ end.
+
+ Fixpoint to_N_of_pos (p : positive) (rest : string) (base : N)
+ : to_N (of_pos p rest) base
+ = to_N rest match base with
+ | N0 => N.pos p
+ | Npos v => Npos (pos_hex_app v p)
+ end.
+ Proof.
+ do 4 try destruct p as [p|p|]; destruct base; try reflexivity;
+ cbn; rewrite to_N_of_pos; reflexivity.
+ Qed.
+End Raw.
+
+Definition of_pos (p : positive) : string
+ := String "0" (String "x" (Raw.of_pos p "")).
+Definition of_N (n : N) : string
+ := match n with
+ | N0 => "0x0"
+ | Npos p => of_pos p
+ end.
+Definition of_Z (z : Z) : string
+ := match z with
+ | Zneg p => String "-" (of_pos p)
+ | Z0 => "0x0"
+ | Zpos p => of_pos p
+ end.
+Definition of_nat (n : nat) : string
+ := of_N (N.of_nat n).
+
+Definition to_N (s : string) : N
+ := match s with
+ | String s0 (String so s)
+ => if ascii_dec s0 "0"
+ then if ascii_dec so "x"
+ then Raw.to_N s N0
+ else N0
+ else N0
+ | _ => N0
+ end.
+Definition to_pos (s : string) : positive
+ := match to_N s with
+ | N0 => 1
+ | Npos p => p
+ end.
+Definition to_Z (s : string) : Z
+ := let '(is_neg, n) := match s with
+ | String s0 s'
+ => if ascii_dec s0 "-"
+ then (true, to_N s')
+ else (false, to_N s)
+ | EmptyString => (false, to_N s)
+ end in
+ match n with
+ | N0 => Z0
+ | Npos p => if is_neg then Zneg p else Zpos p
+ end.
+Definition to_nat (s : string) : nat
+ := N.to_nat (to_N s).
+
+Lemma to_N_of_N (n : N)
+ : to_N (of_N n)
+ = n.
+Proof.
+ destruct n; [ reflexivity | apply Raw.to_N_of_pos ].
+Qed.
+
+Lemma to_Z_of_Z (z : Z)
+ : to_Z (of_Z z)
+ = z.
+Proof.
+ cbv [of_Z to_Z]; destruct z as [|z|z]; cbn;
+ try reflexivity;
+ rewrite Raw.to_N_of_pos; cbn; reflexivity.
+Qed.
+
+Lemma to_nat_of_nat (n : nat)
+ : to_nat (of_nat n)
+ = n.
+Proof.
+ cbv [to_nat of_nat];
+ rewrite to_N_of_N, Nnat.Nat2N.id; reflexivity.
+Qed.
+
+Lemma to_pos_of_pos (p : positive)
+ : to_pos (of_pos p)
+ = p.
+Proof.
+ cbv [of_pos to_pos to_N]; cbn;
+ rewrite Raw.to_N_of_pos; cbn; reflexivity.
+Qed.
+
+Example of_pos_1 : of_pos 1 = "0x1" := eq_refl.
+Example of_pos_2 : of_pos 2 = "0x2" := eq_refl.
+Example of_pos_3 : of_pos 3 = "0x3" := eq_refl.
+Example of_pos_7 : of_pos 7 = "0x7" := eq_refl.
+Example of_pos_8 : of_pos 8 = "0x8" := eq_refl.
+Example of_pos_9 : of_pos 9 = "0x9" := eq_refl.
+Example of_pos_10 : of_pos 10 = "0xa" := eq_refl.
+Example of_pos_11 : of_pos 11 = "0xb" := eq_refl.
+Example of_pos_12 : of_pos 12 = "0xc" := eq_refl.
+Example of_pos_13 : of_pos 13 = "0xd" := eq_refl.
+Example of_pos_14 : of_pos 14 = "0xe" := eq_refl.
+Example of_pos_15 : of_pos 15 = "0xf" := eq_refl.
+Example of_pos_16 : of_pos 16 = "0x10" := eq_refl.
+Example of_N_0 : of_N 0 = "0x0" := eq_refl.
+Example of_Z_0 : of_Z 0 = "0x0" := eq_refl.
+Example of_Z_m1 : of_Z (-1) = "-0x1" := eq_refl.
+Example of_nat_0 : of_nat 0 = "0x0" := eq_refl.
diff --git a/theories/Strings/OctalString.v b/theories/Strings/OctalString.v
new file mode 100644
index 00000000..fe8cc9aa
--- /dev/null
+++ b/theories/Strings/OctalString.v
@@ -0,0 +1,179 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+Require Import Ascii String.
+Require Import BinNums.
+Import BinNatDef.
+Import BinIntDef.
+Import BinPosDef.
+
+Local Open Scope positive_scope.
+Local Open Scope string_scope.
+
+Definition ascii_to_digit (ch : ascii) : option N
+ := (if ascii_dec ch "0" then Some 0
+ else if ascii_dec ch "1" then Some 1
+ else if ascii_dec ch "2" then Some 2
+ else if ascii_dec ch "3" then Some 3
+ else if ascii_dec ch "4" then Some 4
+ else if ascii_dec ch "5" then Some 5
+ else if ascii_dec ch "6" then Some 6
+ else if ascii_dec ch "7" then Some 7
+ else None)%N.
+
+Fixpoint pos_oct_app (p q:positive) : positive :=
+ match q with
+ | 1 => p~0~0~1
+ | 2 => p~0~1~0
+ | 3 => p~0~1~1
+ | 4 => p~1~0~0
+ | 5 => p~1~0~1
+ | 6 => p~1~1~0
+ | 7 => p~1~1~1
+ | q~0~0~0 => (pos_oct_app p q)~0~0~0
+ | q~0~0~1 => (pos_oct_app p q)~0~0~1
+ | q~0~1~0 => (pos_oct_app p q)~0~1~0
+ | q~0~1~1 => (pos_oct_app p q)~0~1~1
+ | q~1~0~0 => (pos_oct_app p q)~1~0~0
+ | q~1~0~1 => (pos_oct_app p q)~1~0~1
+ | q~1~1~0 => (pos_oct_app p q)~1~1~0
+ | q~1~1~1 => (pos_oct_app p q)~1~1~1
+ end.
+
+Module Raw.
+ Fixpoint of_pos (p : positive) (rest : string) : string
+ := match p with
+ | 1 => String "1" rest
+ | 2 => String "2" rest
+ | 3 => String "3" rest
+ | 4 => String "4" rest
+ | 5 => String "5" rest
+ | 6 => String "6" rest
+ | 7 => String "7" rest
+ | p'~0~0~0 => of_pos p' (String "0" rest)
+ | p'~0~0~1 => of_pos p' (String "1" rest)
+ | p'~0~1~0 => of_pos p' (String "2" rest)
+ | p'~0~1~1 => of_pos p' (String "3" rest)
+ | p'~1~0~0 => of_pos p' (String "4" rest)
+ | p'~1~0~1 => of_pos p' (String "5" rest)
+ | p'~1~1~0 => of_pos p' (String "6" rest)
+ | p'~1~1~1 => of_pos p' (String "7" rest)
+ end.
+
+ Fixpoint to_N (s : string) (rest : N)
+ : N
+ := match s with
+ | "" => rest
+ | String ch s'
+ => to_N
+ s'
+ match ascii_to_digit ch with
+ | Some v => N.add v (N.mul 8 rest)
+ | None => N0
+ end
+ end.
+
+ Fixpoint to_N_of_pos (p : positive) (rest : string) (base : N)
+ : to_N (of_pos p rest) base
+ = to_N rest match base with
+ | N0 => N.pos p
+ | Npos v => Npos (pos_oct_app v p)
+ end.
+ Proof.
+ do 3 try destruct p as [p|p|]; destruct base; try reflexivity;
+ cbn; rewrite to_N_of_pos; reflexivity.
+ Qed.
+End Raw.
+
+Definition of_pos (p : positive) : string
+ := String "0" (String "o" (Raw.of_pos p "")).
+Definition of_N (n : N) : string
+ := match n with
+ | N0 => "0o0"
+ | Npos p => of_pos p
+ end.
+Definition of_Z (z : Z) : string
+ := match z with
+ | Zneg p => String "-" (of_pos p)
+ | Z0 => "0o0"
+ | Zpos p => of_pos p
+ end.
+Definition of_nat (n : nat) : string
+ := of_N (N.of_nat n).
+
+Definition to_N (s : string) : N
+ := match s with
+ | String s0 (String so s)
+ => if ascii_dec s0 "0"
+ then if ascii_dec so "o"
+ then Raw.to_N s N0
+ else N0
+ else N0
+ | _ => N0
+ end.
+Definition to_pos (s : string) : positive
+ := match to_N s with
+ | N0 => 1
+ | Npos p => p
+ end.
+Definition to_Z (s : string) : Z
+ := let '(is_neg, n) := match s with
+ | String s0 s'
+ => if ascii_dec s0 "-"
+ then (true, to_N s')
+ else (false, to_N s)
+ | EmptyString => (false, to_N s)
+ end in
+ match n with
+ | N0 => Z0
+ | Npos p => if is_neg then Zneg p else Zpos p
+ end.
+Definition to_nat (s : string) : nat
+ := N.to_nat (to_N s).
+
+Lemma to_N_of_N (n : N)
+ : to_N (of_N n)
+ = n.
+Proof.
+ destruct n; [ reflexivity | apply Raw.to_N_of_pos ].
+Qed.
+
+Lemma to_Z_of_Z (z : Z)
+ : to_Z (of_Z z)
+ = z.
+Proof.
+ cbv [of_Z to_Z]; destruct z as [|z|z]; cbn;
+ try reflexivity;
+ rewrite Raw.to_N_of_pos; cbn; reflexivity.
+Qed.
+
+Lemma to_nat_of_nat (n : nat)
+ : to_nat (of_nat n)
+ = n.
+Proof.
+ cbv [to_nat of_nat];
+ rewrite to_N_of_N, Nnat.Nat2N.id; reflexivity.
+Qed.
+
+Lemma to_pos_of_pos (p : positive)
+ : to_pos (of_pos p)
+ = p.
+Proof.
+ cbv [of_pos to_pos to_N]; cbn;
+ rewrite Raw.to_N_of_pos; cbn; reflexivity.
+Qed.
+
+Example of_pos_1 : of_pos 1 = "0o1" := eq_refl.
+Example of_pos_2 : of_pos 2 = "0o2" := eq_refl.
+Example of_pos_3 : of_pos 3 = "0o3" := eq_refl.
+Example of_pos_7 : of_pos 7 = "0o7" := eq_refl.
+Example of_pos_8 : of_pos 8 = "0o10" := eq_refl.
+Example of_N_0 : of_N 0 = "0o0" := eq_refl.
+Example of_Z_0 : of_Z 0 = "0o0" := eq_refl.
+Example of_Z_m1 : of_Z (-1) = "-0o1" := eq_refl.
+Example of_nat_0 : of_nat 0 = "0o0" := eq_refl.
diff --git a/theories/Strings/String.v b/theories/Strings/String.v
index 2be6618a..be9a10c6 100644
--- a/theories/Strings/String.v
+++ b/theories/Strings/String.v
@@ -14,6 +14,7 @@
Require Import Arith.
Require Import Ascii.
+Require Import Bool.
Declare ML Module "string_syntax_plugin".
(** *** Definition of strings *)
@@ -35,6 +36,39 @@ Proof.
decide equality; apply ascii_dec.
Defined.
+Local Open Scope lazy_bool_scope.
+
+Fixpoint eqb s1 s2 : bool :=
+ match s1, s2 with
+ | EmptyString, EmptyString => true
+ | String c1 s1', String c2 s2' => Ascii.eqb c1 c2 &&& eqb s1' s2'
+ | _,_ => false
+ end.
+
+Infix "=?" := eqb : string_scope.
+
+Lemma eqb_spec s1 s2 : Bool.reflect (s1 = s2) (s1 =? s2)%string.
+Proof.
+ revert s2. induction s1; destruct s2; try (constructor; easy); simpl.
+ case Ascii.eqb_spec; simpl; [intros -> | constructor; now intros [= ]].
+ case IHs1; [intros ->; now constructor | constructor; now intros [= ]].
+Qed.
+
+Local Ltac t_eqb :=
+ repeat first [ congruence
+ | progress subst
+ | apply conj
+ | match goal with
+ | [ |- context[eqb ?x ?y] ] => destruct (eqb_spec x y)
+ end
+ | intro ].
+Lemma eqb_refl x : (x =? x)%string = true. Proof. t_eqb. Qed.
+Lemma eqb_sym x y : (x =? y)%string = (y =? x)%string. Proof. t_eqb. Qed.
+Lemma eqb_eq n m : (n =? m)%string = true <-> n = m. Proof. t_eqb. Qed.
+Lemma eqb_neq x y : (x =? y)%string = false <-> x <> y. Proof. t_eqb. Qed.
+Lemma eqb_compat: Morphisms.Proper (Morphisms.respectful eq (Morphisms.respectful eq eq)) eqb.
+Proof. t_eqb. Qed.
+
(** *** Concatenation of strings *)
Reserved Notation "x ++ y" (right associativity, at level 60).
diff --git a/theories/Structures/GenericMinMax.v b/theories/Structures/GenericMinMax.v
index 05edc6cc..4d04667c 100644
--- a/theories/Structures/GenericMinMax.v
+++ b/theories/Structures/GenericMinMax.v
@@ -83,7 +83,7 @@ End GenericMinMax.
Module MinMaxLogicalProperties (Import O:TotalOrder')(Import M:HasMinMax O).
Module Import Private_Tac := !MakeOrderTac O O.
-(** An alternative caracterisation of [max], equivalent to
+(** An alternative characterisation of [max], equivalent to
[max_l /\ max_r] *)
Lemma max_spec n m :
diff --git a/theories/Unicode/Utf8_core.v b/theories/Unicode/Utf8_core.v
index 5a8931a8..d4cdb064 100644
--- a/theories/Unicode/Utf8_core.v
+++ b/theories/Unicode/Utf8_core.v
@@ -14,10 +14,10 @@
(* Logic *)
Notation "∀ x .. y , P" := (forall x, .. (forall y, P) ..)
(at level 200, x binder, y binder, right associativity,
- format "'[ ' ∀ x .. y ']' , P") : type_scope.
+ format "'[ ' '[ ' ∀ x .. y ']' , '/' P ']'") : type_scope.
Notation "∃ x .. y , P" := (exists x, .. (exists y, P) ..)
(at level 200, x binder, y binder, right associativity,
- format "'[ ' ∃ x .. y ']' , P") : type_scope.
+ format "'[ ' '[ ' ∃ x .. y ']' , '/' P ']'") : type_scope.
Notation "x ∨ y" := (x \/ y) (at level 85, right associativity) : type_scope.
Notation "x ∧ y" := (x /\ y) (at level 80, right associativity) : type_scope.
@@ -31,4 +31,4 @@ Notation "x ≠ y" := (x <> y) (at level 70) : type_scope.
(* Abstraction *)
Notation "'λ' x .. y , t" := (fun x => .. (fun y => t) ..)
(at level 200, x binder, y binder, right associativity,
- format "'[ ' 'λ' x .. y ']' , t").
+ format "'[ ' '[ ' 'λ' x .. y ']' , '/' t ']'").
diff --git a/theories/Vectors/VectorDef.v b/theories/Vectors/VectorDef.v
index f6f3cafa..ba3e4110 100644
--- a/theories/Vectors/VectorDef.v
+++ b/theories/Vectors/VectorDef.v
@@ -312,5 +312,6 @@ Notation "h :: t" := (h :: t) (at level 60, right associativity)
Notation "[ x ]" := (x :: []) : vector_scope.
Notation "[ x ; y ; .. ; z ]" := (cons _ x _ (cons _ y _ .. (cons _ z _ (nil _)) ..)) : vector_scope.
Notation "v [@ p ]" := (nth v p) (at level 1, format "v [@ p ]") : vector_scope.
+Infix "++" := append : vector_scope.
Open Scope vector_scope.
End VectorNotations.
diff --git a/theories/ZArith/BinInt.v b/theories/ZArith/BinInt.v
index cf7397b5..12413453 100644
--- a/theories/ZArith/BinInt.v
+++ b/theories/ZArith/BinInt.v
@@ -1248,6 +1248,8 @@ Bind Scope Z_scope with Z.t Z.
(** Re-export Notations *)
+Numeral Notation Z Z.of_int Z.to_int : Z_scope.
+
Infix "+" := Z.add : Z_scope.
Notation "- x" := (Z.opp x) : Z_scope.
Infix "-" := Z.sub : Z_scope.
@@ -1569,40 +1571,40 @@ End Z2Pos.
Notation Zdouble_plus_one := Z.succ_double (only parsing).
Notation Zdouble_minus_one := Z.pred_double (only parsing).
-Notation Zdouble := Z.double (compat "8.6").
+Notation Zdouble := Z.double (compat "8.7").
Notation ZPminus := Z.pos_sub (only parsing).
-Notation Zsucc' := Z.succ (compat "8.6").
-Notation Zpred' := Z.pred (compat "8.6").
-Notation Zplus' := Z.add (compat "8.6").
+Notation Zsucc' := Z.succ (compat "8.7").
+Notation Zpred' := Z.pred (compat "8.7").
+Notation Zplus' := Z.add (compat "8.7").
Notation Zplus := Z.add (only parsing). (* Slightly incompatible *)
-Notation Zopp := Z.opp (compat "8.6").
-Notation Zsucc := Z.succ (compat "8.6").
-Notation Zpred := Z.pred (compat "8.6").
+Notation Zopp := Z.opp (compat "8.7").
+Notation Zsucc := Z.succ (compat "8.7").
+Notation Zpred := Z.pred (compat "8.7").
Notation Zminus := Z.sub (only parsing).
Notation Zmult := Z.mul (only parsing).
-Notation Zcompare := Z.compare (compat "8.6").
-Notation Zsgn := Z.sgn (compat "8.6").
-Notation Zle := Z.le (compat "8.6").
-Notation Zge := Z.ge (compat "8.6").
-Notation Zlt := Z.lt (compat "8.6").
-Notation Zgt := Z.gt (compat "8.6").
-Notation Zmax := Z.max (compat "8.6").
-Notation Zmin := Z.min (compat "8.6").
-Notation Zabs := Z.abs (compat "8.6").
-Notation Zabs_nat := Z.abs_nat (compat "8.6").
-Notation Zabs_N := Z.abs_N (compat "8.6").
+Notation Zcompare := Z.compare (compat "8.7").
+Notation Zsgn := Z.sgn (compat "8.7").
+Notation Zle := Z.le (compat "8.7").
+Notation Zge := Z.ge (compat "8.7").
+Notation Zlt := Z.lt (compat "8.7").
+Notation Zgt := Z.gt (compat "8.7").
+Notation Zmax := Z.max (compat "8.7").
+Notation Zmin := Z.min (compat "8.7").
+Notation Zabs := Z.abs (compat "8.7").
+Notation Zabs_nat := Z.abs_nat (compat "8.7").
+Notation Zabs_N := Z.abs_N (compat "8.7").
Notation Z_of_nat := Z.of_nat (only parsing).
Notation Z_of_N := Z.of_N (only parsing).
Notation Zind := Z.peano_ind (only parsing).
-Notation Zopp_0 := Z.opp_0 (compat "8.6").
-Notation Zopp_involutive := Z.opp_involutive (compat "8.6").
-Notation Zopp_inj := Z.opp_inj (compat "8.6").
+Notation Zopp_0 := Z.opp_0 (compat "8.7").
+Notation Zopp_involutive := Z.opp_involutive (compat "8.7").
+Notation Zopp_inj := Z.opp_inj (compat "8.7").
Notation Zplus_0_l := Z.add_0_l (only parsing).
Notation Zplus_0_r := Z.add_0_r (only parsing).
Notation Zplus_comm := Z.add_comm (only parsing).
Notation Zopp_plus_distr := Z.opp_add_distr (only parsing).
-Notation Zopp_succ := Z.opp_succ (compat "8.6").
+Notation Zopp_succ := Z.opp_succ (compat "8.7").
Notation Zplus_opp_r := Z.add_opp_diag_r (only parsing).
Notation Zplus_opp_l := Z.add_opp_diag_l (only parsing).
Notation Zplus_assoc := Z.add_assoc (only parsing).
@@ -1611,11 +1613,11 @@ Notation Zplus_reg_l := Z.add_reg_l (only parsing).
Notation Zplus_succ_l := Z.add_succ_l (only parsing).
Notation Zplus_succ_comm := Z.add_succ_comm (only parsing).
Notation Zsucc_discr := Z.neq_succ_diag_r (only parsing).
-Notation Zsucc_inj := Z.succ_inj (compat "8.6").
-Notation Zsucc'_inj := Z.succ_inj (compat "8.6").
-Notation Zsucc'_pred' := Z.succ_pred (compat "8.6").
-Notation Zpred'_succ' := Z.pred_succ (compat "8.6").
-Notation Zpred'_inj := Z.pred_inj (compat "8.6").
+Notation Zsucc_inj := Z.succ_inj (compat "8.7").
+Notation Zsucc'_inj := Z.succ_inj (compat "8.7").
+Notation Zsucc'_pred' := Z.succ_pred (compat "8.7").
+Notation Zpred'_succ' := Z.pred_succ (compat "8.7").
+Notation Zpred'_inj := Z.pred_inj (compat "8.7").
Notation Zsucc'_discr := Z.neq_succ_diag_r (only parsing).
Notation Zminus_0_r := Z.sub_0_r (only parsing).
Notation Zminus_diag := Z.sub_diag (only parsing).
diff --git a/theories/ZArith/BinIntDef.v b/theories/ZArith/BinIntDef.v
index db4de0b9..8cb62622 100644
--- a/theories/ZArith/BinIntDef.v
+++ b/theories/ZArith/BinIntDef.v
@@ -14,6 +14,10 @@ Require Import BinPos BinNat.
Local Open Scope Z_scope.
+Local Notation "0" := Z0.
+Local Notation "1" := (Zpos 1).
+Local Notation "2" := (Zpos 2).
+
(***********************************************************)
(** * Binary Integers, Definitions of Operations *)
(***********************************************************)
@@ -53,7 +57,7 @@ Definition succ_double x :=
Definition pred_double x :=
match x with
- | 0 => -1
+ | 0 => neg 1
| neg p => neg p~1
| pos p => pos (Pos.pred_double p)
end.
@@ -104,7 +108,7 @@ Definition succ x := x + 1.
(** ** Predecessor *)
-Definition pred x := x + -1.
+Definition pred x := x + neg 1.
(** ** Subtraction *)
@@ -171,7 +175,7 @@ Definition sgn z :=
match z with
| 0 => 0
| pos p => 1
- | neg p => -1
+ | neg p => neg 1
end.
(** Boolean equality and comparisons *)
@@ -635,4 +639,9 @@ Definition lxor a b :=
| neg a, neg b => of_N (N.lxor (Pos.pred_N a) (Pos.pred_N b))
end.
+Numeral Notation Z of_int to_int : Z_scope.
+
End Z.
+
+(** Re-export the notation for those who just [Import BinIntDef] *)
+Numeral Notation Z Z.of_int Z.to_int : Z_scope.
diff --git a/theories/ZArith/ZArith_dec.v b/theories/ZArith/ZArith_dec.v
index 9bcdb73a..6cadf30f 100644
--- a/theories/ZArith/ZArith_dec.v
+++ b/theories/ZArith/ZArith_dec.v
@@ -34,7 +34,7 @@ Lemma Zcompare_rec (P:Set) (n m:Z) :
((n ?= m) = Eq -> P) -> ((n ?= m) = Lt -> P) -> ((n ?= m) = Gt -> P) -> P.
Proof. apply Zcompare_rect. Defined.
-Notation Z_eq_dec := Z.eq_dec (compat "8.6").
+Notation Z_eq_dec := Z.eq_dec (compat "8.7").
Section decidability.
diff --git a/theories/ZArith/Zabs.v b/theories/ZArith/Zabs.v
index 0d8450e3..057eb499 100644
--- a/theories/ZArith/Zabs.v
+++ b/theories/ZArith/Zabs.v
@@ -29,17 +29,17 @@ Local Open Scope Z_scope.
(**********************************************************************)
(** * Properties of absolute value *)
-Notation Zabs_eq := Z.abs_eq (compat "8.6").
+Notation Zabs_eq := Z.abs_eq (compat "8.7").
Notation Zabs_non_eq := Z.abs_neq (only parsing).
Notation Zabs_Zopp := Z.abs_opp (only parsing).
Notation Zabs_pos := Z.abs_nonneg (only parsing).
-Notation Zabs_involutive := Z.abs_involutive (compat "8.6").
+Notation Zabs_involutive := Z.abs_involutive (compat "8.7").
Notation Zabs_eq_case := Z.abs_eq_cases (only parsing).
-Notation Zabs_triangle := Z.abs_triangle (compat "8.6").
+Notation Zabs_triangle := Z.abs_triangle (compat "8.7").
Notation Zsgn_Zabs := Z.sgn_abs (only parsing).
Notation Zabs_Zsgn := Z.abs_sgn (only parsing).
Notation Zabs_Zmult := Z.abs_mul (only parsing).
-Notation Zabs_square := Z.abs_square (compat "8.6").
+Notation Zabs_square := Z.abs_square (compat "8.7").
(** * Proving a property of the absolute value by cases *)
diff --git a/theories/ZArith/Zcompare.v b/theories/ZArith/Zcompare.v
index c8432e27..6ccb0153 100644
--- a/theories/ZArith/Zcompare.v
+++ b/theories/ZArith/Zcompare.v
@@ -183,15 +183,15 @@ Qed.
(** Compatibility notations *)
-Notation Zcompare_refl := Z.compare_refl (compat "8.6").
+Notation Zcompare_refl := Z.compare_refl (compat "8.7").
Notation Zcompare_Eq_eq := Z.compare_eq (only parsing).
Notation Zcompare_Eq_iff_eq := Z.compare_eq_iff (only parsing).
-Notation Zcompare_spec := Z.compare_spec (compat "8.6").
-Notation Zmin_l := Z.min_l (compat "8.6").
-Notation Zmin_r := Z.min_r (compat "8.6").
-Notation Zmax_l := Z.max_l (compat "8.6").
-Notation Zmax_r := Z.max_r (compat "8.6").
-Notation Zabs_eq := Z.abs_eq (compat "8.6").
+Notation Zcompare_spec := Z.compare_spec (compat "8.7").
+Notation Zmin_l := Z.min_l (compat "8.7").
+Notation Zmin_r := Z.min_r (compat "8.7").
+Notation Zmax_l := Z.max_l (compat "8.7").
+Notation Zmax_r := Z.max_r (compat "8.7").
+Notation Zabs_eq := Z.abs_eq (compat "8.7").
Notation Zabs_non_eq := Z.abs_neq (only parsing).
Notation Zsgn_0 := Z.sgn_null (only parsing).
Notation Zsgn_1 := Z.sgn_pos (only parsing).
diff --git a/theories/ZArith/Zdiv.v b/theories/ZArith/Zdiv.v
index 15d0e487..74614e11 100644
--- a/theories/ZArith/Zdiv.v
+++ b/theories/ZArith/Zdiv.v
@@ -21,11 +21,11 @@ Local Open Scope Z_scope.
specifications and properties are in [BinInt]. *)
Notation Zdiv_eucl_POS := Z.pos_div_eucl (only parsing).
-Notation Zdiv_eucl := Z.div_eucl (compat "8.6").
-Notation Zdiv := Z.div (compat "8.6").
+Notation Zdiv_eucl := Z.div_eucl (compat "8.7").
+Notation Zdiv := Z.div (compat "8.7").
Notation Zmod := Z.modulo (only parsing).
-Notation Zdiv_eucl_eq := Z.div_eucl_eq (compat "8.6").
+Notation Zdiv_eucl_eq := Z.div_eucl_eq (compat "8.7").
Notation Z_div_mod_eq_full := Z.div_mod (only parsing).
Notation Zmod_POS_bound := Z.pos_div_eucl_bound (only parsing).
Notation Zmod_pos_bound := Z.mod_pos_bound (only parsing).
diff --git a/theories/ZArith/Zeven.v b/theories/ZArith/Zeven.v
index 00a58b51..9e83bfc1 100644
--- a/theories/ZArith/Zeven.v
+++ b/theories/ZArith/Zeven.v
@@ -141,8 +141,8 @@ Notation Zodd_bool_pred := Z.odd_pred (only parsing).
(** * Definition of [Z.quot2], [Z.div2] and properties wrt [Zeven]
and [Zodd] *)
-Notation Zdiv2 := Z.div2 (compat "8.6").
-Notation Zquot2 := Z.quot2 (compat "8.6").
+Notation Zdiv2 := Z.div2 (compat "8.7").
+Notation Zquot2 := Z.quot2 (compat "8.7").
(** Properties of [Z.div2] *)
diff --git a/theories/ZArith/Zmax.v b/theories/ZArith/Zmax.v
index 7f595fcf..26bd9e81 100644
--- a/theories/ZArith/Zmax.v
+++ b/theories/ZArith/Zmax.v
@@ -18,22 +18,22 @@ Local Open Scope Z_scope.
(** Exact compatibility *)
-Notation Zmax_case := Z.max_case (compat "8.6").
-Notation Zmax_case_strong := Z.max_case_strong (compat "8.6").
+Notation Zmax_case := Z.max_case (compat "8.7").
+Notation Zmax_case_strong := Z.max_case_strong (compat "8.7").
Notation Zmax_right := Z.max_r (only parsing).
-Notation Zle_max_l := Z.le_max_l (compat "8.6").
-Notation Zle_max_r := Z.le_max_r (compat "8.6").
-Notation Zmax_lub := Z.max_lub (compat "8.6").
-Notation Zmax_lub_lt := Z.max_lub_lt (compat "8.6").
+Notation Zle_max_l := Z.le_max_l (compat "8.7").
+Notation Zle_max_r := Z.le_max_r (compat "8.7").
+Notation Zmax_lub := Z.max_lub (compat "8.7").
+Notation Zmax_lub_lt := Z.max_lub_lt (compat "8.7").
Notation Zle_max_compat_r := Z.max_le_compat_r (only parsing).
Notation Zle_max_compat_l := Z.max_le_compat_l (only parsing).
Notation Zmax_idempotent := Z.max_id (only parsing).
Notation Zmax_n_n := Z.max_id (only parsing).
-Notation Zmax_comm := Z.max_comm (compat "8.6").
-Notation Zmax_assoc := Z.max_assoc (compat "8.6").
+Notation Zmax_comm := Z.max_comm (compat "8.7").
+Notation Zmax_assoc := Z.max_assoc (compat "8.7").
Notation Zmax_irreducible_dec := Z.max_dec (only parsing).
Notation Zmax_le_prime := Z.max_le (only parsing).
-Notation Zsucc_max_distr := Z.succ_max_distr (compat "8.6").
+Notation Zsucc_max_distr := Z.succ_max_distr (compat "8.7").
Notation Zmax_SS := Z.succ_max_distr (only parsing).
Notation Zplus_max_distr_l := Z.add_max_distr_l (only parsing).
Notation Zplus_max_distr_r := Z.add_max_distr_r (only parsing).
diff --git a/theories/ZArith/Zmin.v b/theories/ZArith/Zmin.v
index 6bc72227..5509ee78 100644
--- a/theories/ZArith/Zmin.v
+++ b/theories/ZArith/Zmin.v
@@ -18,20 +18,20 @@ Local Open Scope Z_scope.
(** Exact compatibility *)
-Notation Zmin_case := Z.min_case (compat "8.6").
-Notation Zmin_case_strong := Z.min_case_strong (compat "8.6").
-Notation Zle_min_l := Z.le_min_l (compat "8.6").
-Notation Zle_min_r := Z.le_min_r (compat "8.6").
-Notation Zmin_glb := Z.min_glb (compat "8.6").
-Notation Zmin_glb_lt := Z.min_glb_lt (compat "8.6").
+Notation Zmin_case := Z.min_case (compat "8.7").
+Notation Zmin_case_strong := Z.min_case_strong (compat "8.7").
+Notation Zle_min_l := Z.le_min_l (compat "8.7").
+Notation Zle_min_r := Z.le_min_r (compat "8.7").
+Notation Zmin_glb := Z.min_glb (compat "8.7").
+Notation Zmin_glb_lt := Z.min_glb_lt (compat "8.7").
Notation Zle_min_compat_r := Z.min_le_compat_r (only parsing).
Notation Zle_min_compat_l := Z.min_le_compat_l (only parsing).
Notation Zmin_idempotent := Z.min_id (only parsing).
Notation Zmin_n_n := Z.min_id (only parsing).
-Notation Zmin_comm := Z.min_comm (compat "8.6").
-Notation Zmin_assoc := Z.min_assoc (compat "8.6").
+Notation Zmin_comm := Z.min_comm (compat "8.7").
+Notation Zmin_assoc := Z.min_assoc (compat "8.7").
Notation Zmin_irreducible_inf := Z.min_dec (only parsing).
-Notation Zsucc_min_distr := Z.succ_min_distr (compat "8.6").
+Notation Zsucc_min_distr := Z.succ_min_distr (compat "8.7").
Notation Zmin_SS := Z.succ_min_distr (only parsing).
Notation Zplus_min_distr_r := Z.add_min_distr_r (only parsing).
Notation Zmin_plus := Z.add_min_distr_r (only parsing).
diff --git a/theories/ZArith/Znumtheory.v b/theories/ZArith/Znumtheory.v
index f5444c31..e6066d53 100644
--- a/theories/ZArith/Znumtheory.v
+++ b/theories/ZArith/Znumtheory.v
@@ -27,20 +27,20 @@ Open Scope Z_scope.
- properties of the efficient [Z.gcd] function
*)
-Notation Zgcd := Z.gcd (compat "8.6").
-Notation Zggcd := Z.ggcd (compat "8.6").
-Notation Zggcd_gcd := Z.ggcd_gcd (compat "8.6").
-Notation Zggcd_correct_divisors := Z.ggcd_correct_divisors (compat "8.6").
-Notation Zgcd_divide_l := Z.gcd_divide_l (compat "8.6").
-Notation Zgcd_divide_r := Z.gcd_divide_r (compat "8.6").
-Notation Zgcd_greatest := Z.gcd_greatest (compat "8.6").
-Notation Zgcd_nonneg := Z.gcd_nonneg (compat "8.6").
-Notation Zggcd_opp := Z.ggcd_opp (compat "8.6").
+Notation Zgcd := Z.gcd (compat "8.7").
+Notation Zggcd := Z.ggcd (compat "8.7").
+Notation Zggcd_gcd := Z.ggcd_gcd (compat "8.7").
+Notation Zggcd_correct_divisors := Z.ggcd_correct_divisors (compat "8.7").
+Notation Zgcd_divide_l := Z.gcd_divide_l (compat "8.7").
+Notation Zgcd_divide_r := Z.gcd_divide_r (compat "8.7").
+Notation Zgcd_greatest := Z.gcd_greatest (compat "8.7").
+Notation Zgcd_nonneg := Z.gcd_nonneg (compat "8.7").
+Notation Zggcd_opp := Z.ggcd_opp (compat "8.7").
(** The former specialized inductive predicate [Z.divide] is now
a generic existential predicate. *)
-Notation Zdivide := Z.divide (compat "8.6").
+Notation Zdivide := Z.divide (compat "8.7").
(** Its former constructor is now a pseudo-constructor. *)
@@ -48,7 +48,7 @@ Definition Zdivide_intro a b q (H:b=q*a) : Z.divide a b := ex_intro _ q H.
(** Results concerning divisibility*)
-Notation Zdivide_refl := Z.divide_refl (compat "8.6").
+Notation Zdivide_refl := Z.divide_refl (compat "8.7").
Notation Zone_divide := Z.divide_1_l (only parsing).
Notation Zdivide_0 := Z.divide_0_r (only parsing).
Notation Zmult_divide_compat_l := Z.mul_divide_mono_l (only parsing).
@@ -97,8 +97,8 @@ Notation Zdivide_1 := Z.divide_1_r (only parsing).
(** If [a] divides [b] and [b] divides [a] then [a] is [b] or [-b]. *)
-Notation Zdivide_antisym := Z.divide_antisym (compat "8.6").
-Notation Zdivide_trans := Z.divide_trans (compat "8.6").
+Notation Zdivide_antisym := Z.divide_antisym (compat "8.7").
+Notation Zdivide_trans := Z.divide_trans (compat "8.7").
(** If [a] divides [b] and [b<>0] then [|a| <= |b|]. *)
@@ -800,7 +800,7 @@ Proof.
rewrite <- Zdivide_Zdiv_eq; auto.
Qed.
-Notation Zgcd_comm := Z.gcd_comm (compat "8.6").
+Notation Zgcd_comm := Z.gcd_comm (compat "8.7").
Lemma Zgcd_ass a b c : Z.gcd (Z.gcd a b) c = Z.gcd a (Z.gcd b c).
Proof.
diff --git a/theories/ZArith/Zorder.v b/theories/ZArith/Zorder.v
index a1ec4b35..208e84ae 100644
--- a/theories/ZArith/Zorder.v
+++ b/theories/ZArith/Zorder.v
@@ -66,10 +66,10 @@ Qed.
(** * Relating strict and large orders *)
-Notation Zgt_lt := Z.gt_lt (compat "8.6").
-Notation Zlt_gt := Z.lt_gt (compat "8.6").
-Notation Zge_le := Z.ge_le (compat "8.6").
-Notation Zle_ge := Z.le_ge (compat "8.6").
+Notation Zgt_lt := Z.gt_lt (compat "8.7").
+Notation Zlt_gt := Z.lt_gt (compat "8.7").
+Notation Zge_le := Z.ge_le (compat "8.7").
+Notation Zle_ge := Z.le_ge (compat "8.7").
Notation Zgt_iff_lt := Z.gt_lt_iff (only parsing).
Notation Zge_iff_le := Z.ge_le_iff (only parsing).
@@ -123,7 +123,7 @@ Qed.
(** Reflexivity *)
-Notation Zle_refl := Z.le_refl (compat "8.6").
+Notation Zle_refl := Z.le_refl (compat "8.7").
Notation Zeq_le := Z.eq_le_incl (only parsing).
Hint Resolve Z.le_refl: zarith.
@@ -143,7 +143,7 @@ Qed.
(** Irreflexivity *)
-Notation Zlt_irrefl := Z.lt_irrefl (compat "8.6").
+Notation Zlt_irrefl := Z.lt_irrefl (compat "8.7").
Notation Zlt_not_eq := Z.lt_neq (only parsing).
Lemma Zgt_irrefl n : ~ n > n.
@@ -167,7 +167,7 @@ Notation Zle_or_lt := Z.le_gt_cases (only parsing).
(** Transitivity of strict orders *)
-Notation Zlt_trans := Z.lt_trans (compat "8.6").
+Notation Zlt_trans := Z.lt_trans (compat "8.7").
Lemma Zgt_trans n m p : n > m -> m > p -> n > p.
Proof.
@@ -176,8 +176,8 @@ Qed.
(** Mixed transitivity *)
-Notation Zlt_le_trans := Z.lt_le_trans (compat "8.6").
-Notation Zle_lt_trans := Z.le_lt_trans (compat "8.6").
+Notation Zlt_le_trans := Z.lt_le_trans (compat "8.7").
+Notation Zle_lt_trans := Z.le_lt_trans (compat "8.7").
Lemma Zle_gt_trans n m p : m <= n -> m > p -> n > p.
Proof.
@@ -191,7 +191,7 @@ Qed.
(** Transitivity of large orders *)
-Notation Zle_trans := Z.le_trans (compat "8.6").
+Notation Zle_trans := Z.le_trans (compat "8.7").
Lemma Zge_trans n m p : n >= m -> m >= p -> n >= p.
Proof.
@@ -257,8 +257,8 @@ Qed.
(** Relating strict and large order using successor or predecessor *)
-Notation Zlt_succ_r := Z.lt_succ_r (compat "8.6").
-Notation Zle_succ_l := Z.le_succ_l (compat "8.6").
+Notation Zlt_succ_r := Z.lt_succ_r (compat "8.7").
+Notation Zle_succ_l := Z.le_succ_l (compat "8.7").
Lemma Zgt_le_succ n m : m > n -> Z.succ n <= m.
Proof.
@@ -336,8 +336,8 @@ Qed.
(** Special cases of ordered integers *)
-Notation Zlt_0_1 := Z.lt_0_1 (compat "8.6").
-Notation Zle_0_1 := Z.le_0_1 (compat "8.6").
+Notation Zlt_0_1 := Z.lt_0_1 (compat "8.7").
+Notation Zle_0_1 := Z.le_0_1 (compat "8.7").
Lemma Zle_neg_pos : forall p q:positive, Zneg p <= Zpos q.
Proof.
diff --git a/theories/ZArith/Zpow_facts.v b/theories/ZArith/Zpow_facts.v
index a9bc5bd0..881ead1c 100644
--- a/theories/ZArith/Zpow_facts.v
+++ b/theories/ZArith/Zpow_facts.v
@@ -233,7 +233,7 @@ Qed.
(** * Z.square: a direct definition of [z^2] *)
-Notation Psquare := Pos.square (compat "8.6").
-Notation Zsquare := Z.square (compat "8.6").
+Notation Psquare := Pos.square (compat "8.7").
+Notation Zsquare := Z.square (compat "8.7").
Notation Psquare_correct := Pos.square_spec (only parsing).
Notation Zsquare_correct := Z.square_spec (only parsing).
diff --git a/theories/ZArith/Zquot.v b/theories/ZArith/Zquot.v
index e93ebb1a..264109dc 100644
--- a/theories/ZArith/Zquot.v
+++ b/theories/ZArith/Zquot.v
@@ -8,7 +8,7 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-Require Import Nnat ZArith_base ROmega ZArithRing Zdiv Morphisms.
+Require Import Nnat ZArith_base Lia ZArithRing Zdiv Morphisms.
Local Open Scope Z_scope.
@@ -37,17 +37,17 @@ Notation Ndiv_Zquot := N2Z.inj_quot (only parsing).
Notation Nmod_Zrem := N2Z.inj_rem (only parsing).
Notation Z_quot_rem_eq := Z.quot_rem' (only parsing).
Notation Zrem_lt := Z.rem_bound_abs (only parsing).
-Notation Zquot_unique := Z.quot_unique (compat "8.6").
-Notation Zrem_unique := Z.rem_unique (compat "8.6").
-Notation Zrem_1_r := Z.rem_1_r (compat "8.6").
-Notation Zquot_1_r := Z.quot_1_r (compat "8.6").
-Notation Zrem_1_l := Z.rem_1_l (compat "8.6").
-Notation Zquot_1_l := Z.quot_1_l (compat "8.6").
-Notation Z_quot_same := Z.quot_same (compat "8.6").
+Notation Zquot_unique := Z.quot_unique (compat "8.7").
+Notation Zrem_unique := Z.rem_unique (compat "8.7").
+Notation Zrem_1_r := Z.rem_1_r (compat "8.7").
+Notation Zquot_1_r := Z.quot_1_r (compat "8.7").
+Notation Zrem_1_l := Z.rem_1_l (compat "8.7").
+Notation Zquot_1_l := Z.quot_1_l (compat "8.7").
+Notation Z_quot_same := Z.quot_same (compat "8.7").
Notation Z_quot_mult := Z.quot_mul (only parsing).
-Notation Zquot_small := Z.quot_small (compat "8.6").
-Notation Zrem_small := Z.rem_small (compat "8.6").
-Notation Zquot2_quot := Zquot2_quot (compat "8.6").
+Notation Zquot_small := Z.quot_small (compat "8.7").
+Notation Zrem_small := Z.rem_small (compat "8.7").
+Notation Zquot2_quot := Zquot2_quot (compat "8.7").
(** Particular values taken for [a÷0] and [(Z.rem a 0)].
We avise to not rely on these arbitrary values. *)
@@ -129,33 +129,33 @@ Qed.
Theorem Zrem_lt_pos a b : 0<=a -> b<>0 -> 0 <= Z.rem a b < Z.abs b.
Proof.
intros; generalize (Z.rem_nonneg a b) (Z.rem_bound_abs a b);
- romega with *.
+ lia.
Qed.
Theorem Zrem_lt_neg a b : a<=0 -> b<>0 -> -Z.abs b < Z.rem a b <= 0.
Proof.
intros; generalize (Z.rem_nonpos a b) (Z.rem_bound_abs a b);
- romega with *.
+ lia.
Qed.
Theorem Zrem_lt_pos_pos a b : 0<=a -> 0<b -> 0 <= Z.rem a b < b.
Proof.
- intros; generalize (Zrem_lt_pos a b); romega with *.
+ intros; generalize (Zrem_lt_pos a b); lia.
Qed.
Theorem Zrem_lt_pos_neg a b : 0<=a -> b<0 -> 0 <= Z.rem a b < -b.
Proof.
- intros; generalize (Zrem_lt_pos a b); romega with *.
+ intros; generalize (Zrem_lt_pos a b); lia.
Qed.
Theorem Zrem_lt_neg_pos a b : a<=0 -> 0<b -> -b < Z.rem a b <= 0.
Proof.
- intros; generalize (Zrem_lt_neg a b); romega with *.
+ intros; generalize (Zrem_lt_neg a b); lia.
Qed.
Theorem Zrem_lt_neg_neg a b : a<=0 -> b<0 -> b < Z.rem a b <= 0.
Proof.
- intros; generalize (Zrem_lt_neg a b); romega with *.
+ intros; generalize (Zrem_lt_neg a b); lia.
Qed.
@@ -171,12 +171,12 @@ Lemma Remainder_equiv : forall a b r,
Remainder a b r <-> Remainder_alt a b r.
Proof.
unfold Remainder, Remainder_alt; intuition.
- - romega with *.
- - romega with *.
- - rewrite <-(Z.mul_opp_opp). apply Z.mul_nonneg_nonneg; romega.
+ - lia.
+ - lia.
+ - rewrite <-(Z.mul_opp_opp). apply Z.mul_nonneg_nonneg; lia.
- assert (0 <= Z.sgn r * Z.sgn a).
{ rewrite <-Z.sgn_mul, Z.sgn_nonneg; auto. }
- destruct r; simpl Z.sgn in *; romega with *.
+ destruct r; simpl Z.sgn in *; lia.
Qed.
Theorem Zquot_mod_unique_full a b q r :
@@ -185,7 +185,7 @@ Proof.
destruct 1 as [(H,H0)|(H,H0)]; intros.
apply Zdiv_mod_unique with b; auto.
apply Zrem_lt_pos; auto.
- romega with *.
+ lia.
rewrite <- H1; apply Z.quot_rem'.
rewrite <- (Z.opp_involutive a).
@@ -193,7 +193,7 @@ Proof.
generalize (Zdiv_mod_unique b (-q) (-a÷b) (-r) (Z.rem (-a) b)).
generalize (Zrem_lt_pos (-a) b).
rewrite <-Z.quot_rem', Z.mul_opp_r, <-Z.opp_add_distr, <-H1.
- romega with *.
+ lia.
Qed.
Theorem Zquot_unique_full a b q r :
diff --git a/tools/CoqMakefile.in b/tools/CoqMakefile.in
index f7e30eae..403ad617 100644
--- a/tools/CoqMakefile.in
+++ b/tools/CoqMakefile.in
@@ -86,7 +86,6 @@ COQC ?= "$(COQBIN)coqc"
COQTOP ?= "$(COQBIN)coqtop"
COQCHK ?= "$(COQBIN)coqchk"
COQDEP ?= "$(COQBIN)coqdep"
-GALLINA ?= "$(COQBIN)gallina"
COQDOC ?= "$(COQBIN)coqdoc"
COQMKFILE ?= "$(COQBIN)coq_makefile"
@@ -148,7 +147,11 @@ TIME_OF_PRETTY_BUILD_EXTRA_FILES ?= - # also output to the command line
# Flags #######################################################################
#
-# We define a bunch of variables combining the parameters
+# We define a bunch of variables combining the parameters.
+# To add additional flags to coq, coqchk or coqdoc, set the
+# {COQ,COQCHK,COQDOC}EXTRAFLAGS variable to whatever you want to add.
+# To overwrite the default choice and set your own flags entirely, set the
+# {COQ,COQCHK,COQDOC}FLAGS variable.
SHOW := $(if $(VERBOSE),@true "",@echo "")
HIDE := $(if $(VERBOSE),,@)
@@ -168,9 +171,16 @@ DYNOBJ:=.cmxs
DYNLIB:=.cmxs
endif
-COQFLAGS?=-q $(OPT) $(COQLIBS) $(OTHERFLAGS)
-COQCHKFLAGS?=-silent -o $(COQLIBS)
-COQDOCFLAGS?=-interpolate -utf8
+# these variables are meant to be overriden if you want to add *extra* flags
+COQEXTRAFLAGS?=
+COQCHKEXTRAFLAGS?=
+COQDOCEXTRAFLAGS?=
+
+# these flags do NOT contain the libraries, to make them easier to overwrite
+COQFLAGS?=-q $(OPT) $(OTHERFLAGS) $(COQEXTRAFLAGS)
+COQCHKFLAGS?=-silent -o $(COQCHKEXTRAFLAGS)
+COQDOCFLAGS?=-interpolate -utf8 $(COQDOCEXTRAFLAGS)
+
COQDOCLIBS?=$(COQLIBS_NOML)
# The version of Coq being run and the version of coq_makefile that
@@ -245,7 +255,6 @@ VO = vo
VOFILES = $(VFILES:.v=.$(VO))
GLOBFILES = $(VFILES:.v=.glob)
-GFILES = $(VFILES:.v=.g)
HTMLFILES = $(VFILES:.v=.html)
GHTMLFILES = $(VFILES:.v=.g.html)
BEAUTYFILES = $(addsuffix .beautified,$(VFILES))
@@ -384,7 +393,7 @@ quick: $(VOFILES:.vo=.vio)
.PHONY: quick
vio2vo:
- $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) \
+ $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) \
-schedule-vio2vo $(J) $(VOFILES:%.vo=%.vio)
.PHONY: vio2vo
@@ -396,17 +405,17 @@ quick2vo:
done); \
echo "VIO2VO: $$VIOFILES"; \
if [ -n "$$VIOFILES" ]; then \
- $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) -schedule-vio2vo $(J) $$VIOFILES; \
+ $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) -schedule-vio2vo $(J) $$VIOFILES; \
fi
.PHONY: quick2vo
checkproofs:
- $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) \
+ $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) \
-schedule-vio-checking $(J) $(VOFILES:%.vo=%.vio)
.PHONY: checkproofs
validate: $(VOFILES)
- $(TIMER) $(COQCHK) $(COQCHKFLAGS) $^
+ $(TIMER) $(COQCHK) $(COQCHKFLAGS) $(COQLIBS) $^
.PHONY: validate
only: $(TGTS)
@@ -431,8 +440,6 @@ all-mli.tex: $(MLIFILES:.mli=.cmi)
$(HIDE)$(CAMLDOC) -latex \
-o $@ -m A $(CAMLDEBUG) $(CAMLDOCFLAGS) $(MLIFILES)
-gallina: $(GFILES)
-
all.ps: $(VFILES)
$(SHOW)'COQDOC -ps $(GAL)'
$(HIDE)$(COQDOC) \
@@ -553,7 +560,6 @@ clean::
$(HIDE)find . -name .coq-native -type d -empty -delete
$(HIDE)rm -f $(VOFILES)
$(HIDE)rm -f $(VOFILES:.vo=.vio)
- $(HIDE)rm -f $(GFILES)
$(HIDE)rm -f $(BEAUTYFILES) $(VFILES:=.old)
$(HIDE)rm -f all.ps all-gal.ps all.pdf all-gal.pdf all.glob all-mli.tex
$(HIDE)rm -f $(VFILES:.v=.glob)
@@ -654,15 +660,15 @@ endif
$(VOFILES): %.vo: %.v
$(SHOW)COQC $<
- $(HIDE)$(TIMER) $(COQC) $(COQDEBUG) $(TIMING_ARG) $(COQFLAGS) $< $(TIMING_EXTRA)
+ $(HIDE)$(TIMER) $(COQC) $(COQDEBUG) $(TIMING_ARG) $(COQFLAGS) $(COQLIBS) $< $(TIMING_EXTRA)
# FIXME ?merge with .vo / .vio ?
$(GLOBFILES): %.glob: %.v
- $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $<
+ $(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) $<
$(VFILES:.v=.vio): %.vio: %.v
$(SHOW)COQC -quick $<
- $(HIDE)$(TIMER) $(COQC) -quick $(COQDEBUG) $(COQFLAGS) $<
+ $(HIDE)$(TIMER) $(COQC) -quick $(COQDEBUG) $(COQFLAGS) $(COQLIBS) $<
$(addsuffix .timing.diff,$(VFILES)): %.timing.diff : %.before-timing %.after-timing
$(SHOW)PYTHON TIMING-DIFF $<
@@ -670,11 +676,7 @@ $(addsuffix .timing.diff,$(VFILES)): %.timing.diff : %.before-timing %.after-tim
$(BEAUTYFILES): %.v.beautified: %.v
$(SHOW)'BEAUTIFY $<'
- $(HIDE)$(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) -beautify $<
-
-$(GFILES): %.g: %.v
- $(SHOW)'GALLINA $<'
- $(HIDE)$(GALLINA) $<
+ $(HIDE)$(TIMER) $(COQC) $(COQDEBUG) $(COQFLAGS) $(COQLIBS) -beautify $<
$(TEXFILES): %.tex: %.v
$(SHOW)'COQDOC -latex $<'
@@ -764,6 +766,7 @@ printenv::
@echo 'OCAMLFIND = $(OCAMLFIND)'
@echo 'PP = $(PP)'
@echo 'COQFLAGS = $(COQFLAGS)'
+ @echo 'COQLIB = $(COQLIBS)'
@echo 'COQLIBINSTALL = $(COQLIBINSTALL)'
@echo 'COQDOCINSTALL = $(COQDOCINSTALL)'
.PHONY: printenv
diff --git a/tools/coq-font-lock.el b/tools/coq-font-lock.el
deleted file mode 100644
index 068e6400..00000000
--- a/tools/coq-font-lock.el
+++ /dev/null
@@ -1,137 +0,0 @@
-;; coq-font-lock.el --- Coq syntax highlighting for Emacs - compatibilty code
-;; Pierre Courtieu, may 2009
-;;
-;; Authors: Pierre Courtieu
-;; License: GPL (GNU GENERAL PUBLIC LICENSE)
-;; Maintainer: Pierre Courtieu <Pierre.Courtieu@cnam.fr>
-
-;; This is copy paste from ProofGeneral by David Aspinall
-;; <David.Aspinall@ed.ac.uk>. ProofGeneral is under GPL and Copyright
-;; (C) LFCS Edinburgh.
-
-
-;;; Commentary:
-;; This file contains the code necessary to coq-syntax.el and
-;; coq-db.el from ProofGeneral. It is also pocked from ProofGeneral.
-
-
-;;; History:
-;; First created from ProofGeneral may 28th 2009
-
-
-;;; Code:
-
-(setq coq-version-is-V8-1 t)
-(defun coq-build-regexp-list-from-db (db &optional filter)
- "Take a keyword database DB and return the list of regexps for font-lock.
-If non-nil Optional argument FILTER is a function applying to each line of DB.
-For each line if FILTER returns nil, then the keyword is not added to the
-regexp. See `coq-syntax-db' for DB structure."
- (let ((l db) (res ()))
- (while l
- (let* ((hd (car l)) (tl (cdr l)) ; hd is the first infos list
- (e1 (car hd)) (tl1 (cdr hd)) ; e1 = menu entry
- (e2 (car tl1)) (tl2 (cdr tl1)) ; e2 = abbreviation
- (e3 (car tl2)) (tl3 (cdr tl2)) ; e3 = completion
- (e4 (car-safe tl3)) (tl4 (cdr-safe tl3)) ; e4 = state changing
- (e5 (car-safe tl4)) (tl5 (cdr-safe tl4)) ; e5 = colorization string
- )
- ;; TODO delete doublons
- (when (and e5 (or (not filter) (funcall filter hd)))
- (setq res (nconc res (list e5)))) ; careful: nconc destructive!
- (setq l tl)))
- res
- ))
-(defun filter-state-preserving (l)
- ; checkdoc-params: (l)
- "Not documented."
- (not (nth 3 l))) ; fourth argument is nil --> state preserving command
-
-(defun filter-state-changing (l)
- ; checkdoc-params: (l)
- "Not documented."
- (nth 3 l)) ; fourth argument is nil --> state preserving command
-
-;; Generic font-lock
-
-(defvar proof-id "\\(\\w\\(\\w\\|\\s_\\)*\\)"
- "A regular expression for parsing identifiers.")
-
-;; For font-lock, we treat ,-separated identifiers as one identifier
-;; and refontify commata using \{proof-zap-commas}.
-
-(defun proof-anchor-regexp (e)
- "Anchor (\\`) and group the regexp E."
- (concat "\\`\\(" e "\\)"))
-
-(defun proof-ids (proof-id &optional sepregexp)
- "Generate a regular expression for separated lists of identifiers PROOF-ID.
-Default is comma separated, or SEPREGEXP if set."
- (concat proof-id "\\(\\s-*" (or sepregexp ",") "\\s-*"
- proof-id "\\)*"))
-
-(defun proof-ids-to-regexp (l)
- "Maps a non-empty list of tokens `L' to a regexp matching any element."
- (if (featurep 'xemacs)
- (mapconcat (lambda (s) (concat "\\_<" s "\\_>")) l "\\|") ;; old version
- (concat "\\_<\\(?:" (mapconcat 'identity l "\\|") "\\)\\_>")))
-
-;; TODO: get rid of this list. Does 'default work widely enough
-;; by now?
-(defconst pg-defface-window-systems
- '(x ;; bog standard
- mswindows ;; Windows
- w32 ;; Windows
- gtk ;; gtk emacs (obsolete?)
- mac ;; used by Aquamacs
- carbon ;; used by Carbon XEmacs
- ns ;; NeXTstep Emacs (Emacs.app)
- x-toolkit) ;; possible catch all (but probably not)
- "A list of possible values for variable `window-system'.
-If you are on a window system and your value of variable
-`window-system' is not listed here, you may not get the correct
-syntax colouring behaviour.")
-
-(defmacro proof-face-specs (bl bd ow)
- "Return a spec for `defface' with BL for light bg, BD for dark, OW o/w."
- `(append
- (apply 'append
- (mapcar
- (lambda (ty) (list
- (list (list (list 'type ty) '(class color)
- (list 'background 'light))
- (quote ,bl))
- (list (list (list 'type ty) '(class color)
- (list 'background 'dark))
- (quote ,bd))))
- pg-defface-window-systems))
- (list (list t (quote ,ow)))))
-
-;;A new face for tactics
-(defface coq-solve-tactics-face
- (proof-face-specs
- (:foreground "forestgreen" t) ; for bright backgrounds
- (:foreground "forestgreen" t) ; for dark backgrounds
- ()) ; for black and white
- "Face for names of closing tactics in proof scripts."
- :group 'proof-faces)
-
-;;A new face for tactics which fail when they don't kill the current goal
-(defface coq-solve-tactics-face
- (proof-face-specs
- (:foreground "red" t) ; for bright backgrounds
- (:foreground "red" t) ; for dark backgrounds
- ()) ; for black and white
- "Face for names of closing tactics in proof scripts."
- :group 'proof-faces)
-
-
-(defconst coq-solve-tactics-face 'coq-solve-tactics-face
- "Expression that evaluates to a face.
-Required so that 'proof-solve-tactics-face is a proper facename")
-
-(defconst proof-tactics-name-face 'coq-solve-tactics-face)
-(defconst proof-tacticals-name-face 'coq-solve-tactics-face)
-
-(provide 'coq-font-lock)
-;;; coq-font-lock.el ends here
diff --git a/tools/coq_makefile.ml b/tools/coq_makefile.ml
index 5402765f..0e56cc3c 100644
--- a/tools/coq_makefile.ml
+++ b/tools/coq_makefile.ml
@@ -59,7 +59,7 @@ let usage_coq_makefile () =
\n _-extra-phony foo bar \"\"_ is a regular way to add the target \"bar\" as\
\n as a dependencies of an already defined target \"foo\".\
\n[-I dir]: look for Objective Caml dependencies in \"dir\"\
-\n[-R physicalpath logicalpath]: look for Coq dependencies resursively\
+\n[-R physicalpath logicalpath]: look for Coq dependencies recursively\
\n starting from \"physicalpath\". The logical path associated to the\
\n physical path is \"logicalpath\".\
\n[-Q physicalpath logicalpath]: look for Coq dependencies starting from\
@@ -210,7 +210,7 @@ let windrive s =
else ""
;;
-let generate_conf_coq_config oc args =
+let generate_conf_coq_config oc =
section oc "Coq configuration.";
let src_dirs = Coq_config.all_src_dirs in
Envars.print_config ~prefix_var_name:"COQMF_" oc src_dirs;
@@ -274,7 +274,7 @@ let generate_conf oc project args =
fprintf oc "# %s\n\n" (String.concat " " (List.map quote args));
generate_conf_files oc project;
generate_conf_includes oc project;
- generate_conf_coq_config oc args;
+ generate_conf_coq_config oc;
generate_conf_defs oc project;
generate_conf_doc oc project;
generate_conf_extra_target oc project.extra_targets;
diff --git a/tools/coqdep.ml b/tools/coqdep.ml
index 12b5cab0..7db0b289 100644
--- a/tools/coqdep.ml
+++ b/tools/coqdep.ml
@@ -8,15 +8,24 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Printf
+open Format
open Coqdep_lexer
open Coqdep_common
-open System
+open Minisys
(** The basic parts of coqdep (i.e. the parts used by [coqdep -boot])
are now in [Coqdep_common]. The code that remains here concerns
the other options. Calling this complete coqdep with the [-boot]
option should be equivalent to calling [coqdep_boot].
+
+ As of today, this module depends on the following Coq modules:
+
+ - Flags
+ - Envars
+ - CoqProject_file
+
+ All of it for `coqlib` handling. Ideally we would like to clean
+ coqlib handling up so this can be bootstrapped earlier.
*)
let option_D = ref false
@@ -31,8 +40,7 @@ let warning_mult suf iter =
let d' = Hashtbl.find tab f in
if (Filename.dirname (file_name f d))
<> (Filename.dirname (file_name f d')) then begin
- eprintf "*** Warning : the file %s is defined twice!\n" (f ^ suf);
- flush stderr
+ coqdep_warning "the file %s is defined twice!" (f ^ suf)
end
with Not_found -> () end;
Hashtbl.add tab f d
@@ -80,9 +88,7 @@ let mL_dep_list b f =
while true do
let (Use_module str) = caml_action buf in
if str = b then begin
- eprintf "*** Warning : in file %s the" f;
- eprintf " notation %s. is useless !\n" b;
- flush stderr
+ coqdep_warning "in file %s the notation %s. is useless !\n" f b
end else
if not (List.mem str !deja_vu) then addQueue deja_vu str
done; []
@@ -98,16 +104,13 @@ let affiche_Declare f dcl =
printf "\n*** In file %s: \n" f;
printf "Declare ML Module";
List.iter (fun str -> printf " \"%s\"" str) dcl;
- printf ".\n";
- flush stdout
+ printf ".\n%!"
let warning_Declare f dcl =
- eprintf "*** Warning : in file %s, the ML modules" f;
- eprintf " declaration should be\n";
+ eprintf "*** Warning : in file %s, the ML modules declaration should be\n" f;
eprintf "*** Declare ML Module";
List.iter (fun str -> eprintf " \"%s\"" str) dcl;
- eprintf ".\n";
- flush stderr
+ eprintf ".\n%!"
let traite_Declare f =
let decl_list = ref ([] : string list) in
@@ -149,7 +152,7 @@ let declare_dependencies () =
List.iter
(fun (name,_) ->
traite_Declare (name^".v");
- flush stdout)
+ pp_print_flush std_formatter ())
(List.rev !vAccu)
(** DAGs guaranteed to be transitive reductions *)
@@ -426,11 +429,11 @@ let coq_dependencies_dump chan dumpboxes =
(DAG.empty, List.fold_left (fun ih (file, _) -> insert_raw_graph file ih) [] !vAccu,
List.map fst !vAccu) !vAccu
in
- fprintf chan "digraph dependencies {\n"; flush chan;
+ fprintf chan "digraph dependencies {\n";
if dumpboxes then print_graphs chan (pop_common_prefix graphs)
else List.iter (fun (name, _) -> fprintf chan "\"%s\"[label=\"%s\"]\n" name (basename_noext name)) !vAccu;
DAG.iter (fun name dep -> fprintf chan "\"%s\" -> \"%s\"\n" dep name) deps;
- fprintf chan "}\n"
+ fprintf chan "}\n%!"
end
@@ -498,7 +501,7 @@ let rec parse = function
| "-suffix" :: s :: ll -> suffixe := s ; parse ll
| "-suffix" :: [] -> usage ()
| "-slash" :: ll ->
- Printf.eprintf "warning: option -slash has no effect and is deprecated.\n";
+ coqdep_warning "warning: option -slash has no effect and is deprecated.";
parse ll
| "-dyndep" :: "no" :: ll -> option_dynlink := No; parse ll
| "-dyndep" :: "opt" :: ll -> option_dynlink := Opt; parse ll
@@ -509,6 +512,9 @@ let rec parse = function
| f :: ll -> treat_file None f; parse ll
| [] -> ()
+(* Exception to be raised by Envars *)
+exception CoqlibError of string
+
let coqdep () =
if Array.length Sys.argv < 2 then usage ();
if not Coq_config.has_natdynlink then option_dynlink := No;
@@ -520,18 +526,17 @@ let coqdep () =
if !option_boot then begin
add_rec_dir_import add_known "theories" ["Coq"];
add_rec_dir_import add_known "plugins" ["Coq"];
- add_caml_dir "tactics";
add_rec_dir_import (fun _ -> add_caml_known) "theories" ["Coq"];
add_rec_dir_import (fun _ -> add_caml_known) "plugins" ["Coq"];
end else begin
- Envars.set_coqlib ~fail:(fun msg -> CErrors.user_err Pp.(str msg));
+ Envars.set_coqlib ~fail:(fun msg -> raise (CoqlibError msg));
let coqlib = Envars.coqlib () in
add_rec_dir_import add_coqlib_known (coqlib//"theories") ["Coq"];
add_rec_dir_import add_coqlib_known (coqlib//"plugins") ["Coq"];
let user = coqlib//"user-contrib" in
if Sys.file_exists user then add_rec_dir_no_import add_coqlib_known user [];
List.iter (fun s -> add_rec_dir_no_import add_coqlib_known s [])
- (Envars.xdg_dirs ~warn:(fun x -> Feedback.msg_warning (Pp.str x)));
+ (Envars.xdg_dirs ~warn:(fun x -> coqdep_warning "%s" x));
List.iter (fun s -> add_rec_dir_no_import add_coqlib_known s []) Envars.coqpath;
end;
List.iter (fun (f,d) -> add_mli_known f d ".mli") !mliAccu;
@@ -547,13 +552,13 @@ let coqdep () =
| None -> ()
| Some (box, file) ->
let chan = open_out file in
- try Graph.coq_dependencies_dump chan box; close_out chan
+ let chan_fmt = formatter_of_out_channel chan in
+ try Graph.coq_dependencies_dump chan_fmt box; close_out chan
with e -> close_out chan; raise e
end
let _ =
try
coqdep ()
- with CErrors.UserError(s,p) ->
- let pp = (match s with | None -> p | Some s -> Pp.(str s ++ str ": " ++ p)) in
- Format.eprintf "%a@\n%!" Pp.pp_with pp
+ with CoqlibError msg ->
+ eprintf "*** Error: %s@\n%!" msg
diff --git a/tools/coqdep_common.ml b/tools/coqdep_common.ml
index db69a3b7..23b8bc11 100644
--- a/tools/coqdep_common.ml
+++ b/tools/coqdep_common.ml
@@ -8,9 +8,9 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Printf
-open Coqdep_lexer
+open Format
open Unix
+open Coqdep_lexer
open Minisys
(** [coqdep_boot] is a stripped-down version of [coqdep], whose
@@ -20,14 +20,15 @@ open Minisys
options (see for instance [option_dynlink] below).
*)
+let coqdep_warning args =
+ eprintf "*** Warning: @[";
+ kfprintf (fun fmt -> fprintf fmt "@]\n%!") err_formatter args
+
module StrSet = Set.Make(String)
module StrList = struct type t = string list let compare = compare end
module StrListMap = Map.Make(StrList)
-let stderr = Pervasives.stderr
-let stdout = Pervasives.stdout
-
type dynlink = Opt | Byte | Both | No | Variable
let option_c = ref false
@@ -114,8 +115,7 @@ let same_path_opt s s' =
let warning_ml_clash x s suff s' suff' =
if suff = suff' && not (same_path_opt s s') then
- eprintf
- "*** Warning: %s%s already found in %s (discarding %s%s)\n" x suff
+ coqdep_warning "%s%s already found in %s (discarding %s%s)\n" x suff
(match s with None -> "." | Some d -> d)
((match s' with None -> "." | Some d -> d) // x) suff
@@ -180,13 +180,11 @@ let error_cannot_parse s (i,j) =
exit 1
let warning_module_notfound f s =
- eprintf "*** Warning: in file %s, library %s is required and has not been found in the loadpath!\n%!"
+ coqdep_warning "in file %s, library %s is required and has not been found in the loadpath!"
f (String.concat "." s)
let warning_declare f s =
- eprintf "*** Warning: in file %s, declared ML module " f;
- eprintf "%s has not been found!\n" s;
- flush stderr
+ coqdep_warning "in file %s, declared ML module %s has not been found!" f s
let warning_clash file dir =
match StrListMap.find dir !clash_v with
@@ -203,8 +201,7 @@ let warning_clash file dir =
| _ -> assert false
let warning_cannot_open_dir dir =
- eprintf "*** Warning: cannot open %s\n" dir;
- flush stderr
+ coqdep_warning "cannot open %s" dir
let safe_assoc from verbose file k =
if verbose && StrListMap.mem k !clash_v then warning_clash file k;
@@ -451,15 +448,13 @@ let mL_dependencies () =
in
let efullname = escape fullname in
printf "%s.cmo:%s%s\n" efullname dep intf;
- printf "%s.cmx:%s%s\n" efullname dep_opt intf;
- flush stdout)
+ printf "%s.cmx:%s%s\n%!" efullname dep_opt intf)
(List.rev !mlAccu);
List.iter
(fun (name,dirname) ->
let fullname = file_name name dirname in
let (dep,_) = traite_fichier_ML fullname ".mli" in
- printf "%s.cmi:%s\n" (escape fullname) dep;
- flush stdout)
+ printf "%s.cmi:%s\n%!" (escape fullname) dep)
(List.rev !mliAccu);
List.iter
(fun (name,dirname) ->
@@ -468,8 +463,7 @@ let mL_dependencies () =
let efullname = escape fullname in
printf "%s_MLLIB_DEPENDENCIES:=%s\n" efullname (String.concat " " dep);
printf "%s.cma:$(addsuffix .cmo,$(%s_MLLIB_DEPENDENCIES))\n" efullname efullname;
- printf "%s.cmxa:$(addsuffix .cmx,$(%s_MLLIB_DEPENDENCIES))\n" efullname efullname;
- flush stdout)
+ printf "%s.cmxa:$(addsuffix .cmx,$(%s_MLLIB_DEPENDENCIES))\n%!" efullname efullname)
(List.rev !mllibAccu);
List.iter
(fun (name,dirname) ->
@@ -483,7 +477,7 @@ let mL_dependencies () =
List.iter (fun dep ->
printf "%s.cmx : FOR_PACK=-for-pack %s\n" dep efullname_capital)
dep;
- flush stdout)
+ printf "%!")
(List.rev !mlpackAccu)
let coq_dependencies () =
@@ -496,8 +490,7 @@ let coq_dependencies () =
printf "\n";
printf "%s.vio: %s.v" ename ename;
traite_fichier_Coq ".vio" true (name ^ ".v");
- printf "\n";
- flush stdout)
+ printf "\n%!")
(List.rev !vAccu)
let rec suffixes = function
diff --git a/tools/coqdep_common.mli b/tools/coqdep_common.mli
index d0d79324..91d2b458 100644
--- a/tools/coqdep_common.mli
+++ b/tools/coqdep_common.mli
@@ -10,6 +10,8 @@
module StrSet : Set.S with type elt = string
+val coqdep_warning : ('a, Format.formatter, unit, unit) format4 -> 'a
+
(** [find_dir_logpath dir] Return the logical path of directory [dir]
if it has been given one. Raise [Not_found] otherwise. In
particular we can check if "." has been attributed a logical path
diff --git a/tools/coqdoc/index.ml b/tools/coqdoc/index.ml
index df493fdf..724d3838 100644
--- a/tools/coqdoc/index.ml
+++ b/tools/coqdoc/index.ml
@@ -77,7 +77,7 @@ let add_ref m loc m' sp id ty =
let find m l = Hashtbl.find reftable (m, l)
-let find_string m s = let (m,s,t) = Hashtbl.find byidtable s in Ref (m,s,t)
+let find_string s = let (m,s,t) = Hashtbl.find byidtable s in Ref (m,s,t)
(* Coq modules *)
@@ -185,7 +185,8 @@ let type_name = function
let prepare_entry s = function
| Notation ->
(* We decode the encoding done in Dumpglob.cook_notation of coqtop *)
- (* Encoded notations have the form section:sc:x_'++'_x where: *)
+ (* Encoded notations have the form section:entry:sc:x_'++'_x *)
+ (* where: *)
(* - the section, if any, ends with a "." *)
(* - the scope can be empty *)
(* - tokens are separated with "_" *)
@@ -202,10 +203,12 @@ let prepare_entry s = function
let err () = eprintf "Invalid notation in globalization file\n"; exit 1 in
let h = try String.index_from s 0 ':' with _ -> err () in
let i = try String.index_from s (h+1) ':' with _ -> err () in
- let sc = String.sub s (h+1) (i-h-1) in
- let ntn = Bytes.make (String.length s - i) ' ' in
+ let m = try String.index_from s (i+1) ':' with _ -> err () in
+ let entry = String.sub s (h+1) (i-h-1) in
+ let sc = String.sub s (i+1) (m-i-1) in
+ let ntn = Bytes.make (String.length s - m) ' ' in
let k = ref 0 in
- let j = ref (i+1) in
+ let j = ref (m+1) in
let quoted = ref false in
let l = String.length s - 1 in
while !j <= l do
@@ -227,7 +230,8 @@ let prepare_entry s = function
incr j
done;
let ntn = Bytes.sub_string ntn 0 !k in
- if sc = "" then ntn else ntn ^ " (" ^ sc ^ ")"
+ let ntn = if sc = "" then ntn else ntn ^ " (" ^ sc ^ ")" in
+ if entry = "" then ntn else entry ^ ":" ^ ntn
| _ ->
s
diff --git a/tools/coqdoc/index.mli b/tools/coqdoc/index.mli
index 5cd30138..7c9aad67 100644
--- a/tools/coqdoc/index.mli
+++ b/tools/coqdoc/index.mli
@@ -41,7 +41,7 @@ type index_entry =
val find : coq_module -> loc -> index_entry
(* Find what data is referred to by some string in some coq module *)
-val find_string : coq_module -> string -> index_entry
+val find_string : string -> index_entry
val add_module : coq_module -> unit
diff --git a/tools/coqdoc/output.ml b/tools/coqdoc/output.ml
index d2522700..750698a1 100644
--- a/tools/coqdoc/output.ml
+++ b/tools/coqdoc/output.ml
@@ -76,7 +76,7 @@ let is_tactic =
[ "intro"; "intros"; "apply"; "rewrite"; "refine"; "case"; "clear"; "injection";
"elimtype"; "progress"; "setoid_rewrite"; "left"; "right"; "constructor";
"econstructor"; "decide equality"; "abstract"; "exists"; "cbv"; "simple destruct";
- "info"; "fourier"; "field"; "specialize"; "evar"; "solve"; "instanciate"; "info_auto"; "info_eauto";
+ "info"; "field"; "specialize"; "evar"; "solve"; "instantiate"; "info_auto"; "info_eauto";
"quote"; "eexact"; "autorewrite";
"destruct"; "destruction"; "destruct_call"; "dependent"; "elim"; "extensionality";
"f_equal"; "generalize"; "generalize_eqs"; "generalize_eqs_vars"; "induction"; "rename"; "move"; "omega";
@@ -431,7 +431,7 @@ module Latex = struct
else if !Cdglobals.interpolate && !in_doc (* always a var otherwise *)
then
try
- let tag = Index.find_string (get_module false) s in
+ let tag = Index.find_string s in
reference (translate s) tag
with _ -> Tokens.output_tagged_ident_string s
else Tokens.output_tagged_ident_string s
@@ -706,7 +706,7 @@ module Html = struct
else if is_keyword s then
printf "<span class=\"id\" title=\"keyword\">%s</span>" (translate s)
else if !Cdglobals.interpolate && !in_doc (* always a var otherwise *) then
- try reference (translate s) (Index.find_string (get_module false) s)
+ try reference (translate s) (Index.find_string s)
with Not_found -> Tokens.output_tagged_ident_string s
else
Tokens.output_tagged_ident_string s
diff --git a/tools/coqworkmgr.ml b/tools/coqworkmgr.ml
index 68aadcfc..bfea141b 100644
--- a/tools/coqworkmgr.ml
+++ b/tools/coqworkmgr.ml
@@ -169,7 +169,7 @@ let main () =
"-j",Arg.Set_int max_tokens, "max number of concurrent jobs";
"-d",Arg.Set debug, "do not detach (debug)"] in
let usage =
- "Prints on stdout an env variable assignement to be picked up by coq\n"^
+ "Prints on stdout an env variable assignment to be picked up by coq\n"^
"instances in order to limit the maximum number of concurrent workers.\n"^
"The default value is 2.\n"^
"Usage:" in
diff --git a/tools/fake_ide.ml b/tools/fake_ide.ml
index d48c6d0a..01620112 100644
--- a/tools/fake_ide.ml
+++ b/tools/fake_ide.ml
@@ -8,7 +8,7 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-(** Fake_ide : Simulate a [coqide] talking to a [coqtop -ideslave] *)
+(** Fake_ide : Simulate a [coqide] talking to a [coqidetop] *)
let error s =
prerr_endline ("fake_id: error: "^s);
@@ -284,7 +284,7 @@ let read_command inc = Parser.parse grammar inc
let usage () =
error (Printf.sprintf
- "A fake coqide process talking to a coqtop -ideslave.\n\
+ "A fake coqide process talking to a coqtop -toploop coqidetop.\n\
Usage: %s (file|-) [<coqtop>]\n\
Input syntax is the following:\n%s\n"
(Filename.basename Sys.argv.(0))
@@ -296,20 +296,8 @@ let main =
if Sys.os_type = "Unix" then Sys.set_signal Sys.sigpipe
(Sys.Signal_handle
(fun _ -> prerr_endline "Broken Pipe (coqtop died ?)"; exit 1));
- let def_args = ["--xml_format=Ppcmds"; "-ideslave"] in
- let coqtop_name = (* from ide/ideutils.ml *)
- let prog_name = "fake_ide" in
- let len_prog_name = String.length prog_name in
- let fake_ide_path = Sys.executable_name in
- let fake_ide_path_len = String.length fake_ide_path in
- let pos = fake_ide_path_len - len_prog_name in
- let rex = Str.regexp_string prog_name in
- try
- let i = Str.search_backward rex fake_ide_path pos in
- String.sub fake_ide_path 0 i ^ "coqtop" ^
- String.sub fake_ide_path (i + len_prog_name)
- (fake_ide_path_len - i - len_prog_name)
- with Not_found -> assert false in
+ let def_args = ["--xml_format=Ppcmds"] in
+ let idetop_name = System.get_toplevel_path "coqidetop" in
let coqtop_args, input_file = match Sys.argv with
| [| _; f |] -> Array.of_list def_args, f
| [| _; f; ct |] ->
@@ -318,7 +306,7 @@ let main =
| _ -> usage () in
let inc = if input_file = "-" then stdin else open_in input_file in
let coq =
- let _p, cin, cout = Coqide.spawn coqtop_name coqtop_args in
+ let _p, cin, cout = Coqide.spawn idetop_name coqtop_args in
let ip = Xml_parser.make (Xml_parser.SChannel cin) in
let op = Xml_printer.make (Xml_printer.TChannel cout) in
Xml_parser.check_eof ip false;
diff --git a/tools/gallina-db.el b/tools/gallina-db.el
deleted file mode 100644
index 9664f69f..00000000
--- a/tools/gallina-db.el
+++ /dev/null
@@ -1,240 +0,0 @@
-;;; gallina-db.el --- coq keywords database utility functions
-;;
-;; Author: Pierre Courtieu <courtieu@lri.fr>
-;; License: GPL (GNU GENERAL PUBLIC LICENSE)
-;;
-
-;;; We store all information on keywords (tactics or command) in big
-;; tables (ex: `coq-tactics-db') From there we get: menus including
-;; "smart" commands, completions for command coq-insert-...
-;; abbrev tables and font-lock keyword
-
-;;; real value defined below
-
-;;; Commentary:
-;;
-
-;;; Code:
-
-;(require 'proof-config) ; for proof-face-specs, a macro
-;(require 'holes)
-
-(defconst coq-syntax-db nil
- "Documentation-only variable, for coq keyword databases.
-Each element of a keyword database contains the definition of a \"form\", of the
-form:
-
-(MENUNAME ABBREV INSERT STATECH KWREG INSERT-FUN HIDE)
-
-MENUNAME is the name of form (or form variant) as it should appear in menus or
-completion lists.
-
-ABBREV is the abbreviation for completion via \\[expand-abbrev].
-
-INSERT is the complete text of the form, which may contain holes denoted by
-\"#\" or \"@{xxx}\".
-
-If non-nil the optional STATECH specifies that the command is not state
-preserving for coq.
-
-If non-nil the optional KWREG is the regexp to colorize correponding to the
-keyword. ex: \"simple\\\\s-+destruct\" (\\\\s-+ meaning \"one or more spaces\").
-*WARNING*: A regexp longer than another one should be put FIRST. For example:
-
- (\"Module Type\" ... ... t \"Module\\s-+Type\")
- (\"Module\" ... ... t \"Module\")
-
-Is ok because the longer regexp is recognized first.
-
-If non-nil the optional INSERT-FUN is the function to be called when inserting
-the form (instead of inserting INSERT, except when using \\[expand-abbrev]). This
-allows writing functions asking for more information to assist the user.
-
-If non-nil the optional HIDE specifies that this form should not appear in the
-menu but only in interactive completions.
-
-Example of what could be in your emacs init file:
-
-(defvar coq-user-tactics-db
- '(
- (\"mytac\" \"mt\" \"mytac # #\" t \"mytac\")
- (\"myassert by\" \"massb\" \"myassert ( # : # ) by #\" t \"assert\")
- ))
-
-Explanation of the first line: the tactic menu entry mytac, abbreviated by mt,
-will insert \"mytac # #\" where #s are holes to fill, and \"mytac\" becomes a
-new keyword to colorize." )
-
-(defun coq-insert-from-db (db prompt)
- "Ask for a keyword, with completion on keyword database DB and insert.
-Insert corresponding string with holes at point. If an insertion function is
-present for the keyword, call it instead. see `coq-syntax-db' for DB
-structure."
- (let* ((tac (completing-read (concat prompt " (tab for completion) : ")
- db nil nil))
- (infos (cddr (assoc tac db)))
- (s (car infos)) ; completion to insert
- (f (car-safe (cdr-safe (cdr-safe (cdr infos))))) ; insertion function
- (pt (point)))
- (if f (funcall f) ; call f if present
- (insert (or s tac)) ; insert completion and indent otherwise
- (holes-replace-string-by-holes-backward-jump pt)
- (indent-according-to-mode))))
-
-
-
-(defun coq-build-regexp-list-from-db (db &optional filter)
- "Take a keyword database DB and return the list of regexps for font-lock.
-If non-nil Optional argument FILTER is a function applying to each line of DB.
-For each line if FILTER returns nil, then the keyword is not added to the
-regexp. See `coq-syntax-db' for DB structure."
- (let ((l db) (res ()))
- (while l
- (let* ((hd (car l)) (tl (cdr l)) ; hd is the first infos list
- (e1 (car hd)) (tl1 (cdr hd)) ; e1 = menu entry
- (e2 (car tl1)) (tl2 (cdr tl1)) ; e2 = abbreviation
- (e3 (car tl2)) (tl3 (cdr tl2)) ; e3 = completion
- (e4 (car-safe tl3)) (tl4 (cdr-safe tl3)) ; e4 = state changing
- (e5 (car-safe tl4)) (tl5 (cdr-safe tl4)) ; e5 = colorization string
- )
- ;; TODO delete doublons
- (when (and e5 (or (not filter) (funcall filter hd)))
- (setq res (nconc res (list e5)))) ; careful: nconc destructive!
- (setq l tl)))
- res
- ))
-
-;; Computes the max length of strings in a list
-(defun max-length-db (db)
- "Return the length of the longest first element (menu label) of DB.
-See `coq-syntax-db' for DB structure."
- (let ((l db) (res 0))
- (while l
- (let ((lgth (length (car (car l)))))
- (setq res (max lgth res))
- (setq l (cdr l))))
- res))
-
-
-
-(defun coq-build-menu-from-db-internal (db lgth menuwidth)
- "Take a keyword database DB and return one insertion submenu.
-Argument LGTH is the max size of the submenu. Argument MENUWIDTH is the width
-of the largest line in the menu (without abbrev and shortcut specifications).
-Used by `coq-build-menu-from-db', which you should probably use instead. See
-`coq-syntax-db' for DB structure."
- (let ((l db) (res ()) (size lgth)
- (keybind-abbrev (substitute-command-keys " \\[expand-abbrev]")))
- (while (and l (> size 0))
- (let* ((hd (car l))(tl (cdr l)) ; hd is a list of length 3 or 4
- (e1 (car hd)) (tl1 (cdr hd)) ; e1 = menu entry
- (e2 (car tl1)) (tl2 (cdr tl1)) ; e2 = abbreviation
- (e3 (car tl2)) (tl3 (cdr tl2)) ; e3 = completion
- (e4 (car-safe tl3)) (tl4 (cdr-safe tl3)) ; e4 = state changing
- (e5 (car-safe tl4)) (tl5 (cdr-safe tl4)) ; e5 = colorization string
- (e6 (car-safe tl5)) ; e6 = function for smart insertion
- (e7 (car-safe (cdr-safe tl5))) ; e7 = if non-nil : hide in menu
- (entry-with (max (- menuwidth (length e1)) 0))
- (spaces (make-string entry-with ? ))
- ;;(restofmenu (coq-build-menu-from-db-internal tl (- size 1) menuwidth))
- )
- (when (not e7) ;; if not hidden
- (let ((menu-entry
- (vector
- ;; menu entry label
- (concat e1 (if (not e2) "" (concat spaces "(" e2 keybind-abbrev ")")))
- ;;insertion function if present otherwise insert completion
- (if e6 e6 `(holes-insert-and-expand ,e3))
- t)))
- (setq res (nconc res (list menu-entry)))));; append *in place*
- (setq l tl)
- (setq size (- size 1))))
- res))
-
-
-(defun coq-build-title-menu (db size)
- "Build a title for the first submenu of DB, of size SIZE.
-Return the string made of the first and the SIZE nth first element of DB,
-separated by \"...\". Used by `coq-build-menu-from-db'. See `coq-syntax-db'
-for DB structure."
- (concat (car-safe (car-safe db))
- " ... "
- (car-safe (car-safe (nthcdr (- size 1) db)))))
-
-(defun coq-sort-menu-entries (menu)
- (sort menu
- (lambda (x y) (string<
- (downcase (elt x 0))
- (downcase (elt y 0))))))
-
-(defun coq-build-menu-from-db (db &optional size)
- "Take a keyword database DB and return a list of insertion menus for them.
-Submenus contain SIZE entries (default 30). See `coq-syntax-db' for DB
-structure."
- ;; sort is destructive for the list, so copy list before sorting
- (let* ((l (coq-sort-menu-entries (copy-list db))) (res ())
- (wdth (+ 2 (max-length-db db)))
- (sz (or size 30)) (lgth (length l)))
- (while l
- (if (<= lgth sz)
- (setq res ;; careful: nconc destructive!
- (nconc res (list (cons
- (coq-build-title-menu l lgth)
- (coq-build-menu-from-db-internal l lgth wdth)))))
- (setq res ; careful: nconc destructive!
- (nconc res (list (cons
- (coq-build-title-menu l sz)
- (coq-build-menu-from-db-internal l sz wdth))))))
- (setq l (nthcdr sz l))
- (setq lgth (length l)))
- res))
-
-(defun coq-build-abbrev-table-from-db (db)
- "Take a keyword database DB and return an abbrev table.
-See `coq-syntax-db' for DB structure."
- (let ((l db) (res ()))
- (while l
- (let* ((hd (car l))(tl (cdr l)) ; hd is a list of length 3 or 4
- (e1 (car hd)) (tl1 (cdr hd)) ; e1 = menu entry
- (e2 (car tl1)) (tl2 (cdr tl1)) ; e2 = abbreviation
- (e3 (car tl2)) (tl3 (cdr tl2)) ; e3 = completion
- )
- ;; careful: nconc destructive!
- (when e2
- (setq res (nconc res (list `(,e2 ,e3 holes-abbrev-complete)))))
- (setq l tl)))
- res))
-
-
-(defun filter-state-preserving (l)
- ; checkdoc-params: (l)
- "Not documented."
- (not (nth 3 l))) ; fourth argument is nil --> state preserving command
-
-(defun filter-state-changing (l)
- ; checkdoc-params: (l)
- "Not documented."
- (nth 3 l)) ; fourth argument is nil --> state preserving command
-
-(defconst coq-solve-tactics-face 'coq-solve-tactics-face
- "Expression that evaluates to a face.
-Required so that 'proof-solve-tactics-face is a proper facename")
-
-
-;;A new face for tactics which fail when they don't kill the current goal
-(defface coq-solve-tactics-face
- '((t (:background "red")))
- "Face for names of closing tactics in proof scripts."
- :group 'proof-faces)
-
-
-
-
-
-(provide 'gallina-db)
-
-;;; gallina-db.el ends here
-
-;** Local Variables: ***
-;** fill-column: 80 ***
-;** End: ***
diff --git a/tools/gallina-syntax.el b/tools/gallina-syntax.el
deleted file mode 100644
index 662762b0..00000000
--- a/tools/gallina-syntax.el
+++ /dev/null
@@ -1,980 +0,0 @@
-;; gallina-syntax.el Font lock expressions for Coq
-;; Copyright (C) 1997-2007 LFCS Edinburgh.
-;; Authors: Thomas Kleymann, Healfdene Goguen, Pierre Courtieu
-;; License: GPL (GNU GENERAL PUBLIC LICENSE)
-;; Maintainer: Pierre Courtieu <courtieu@lri.fr>
-
-;; gallina-syntax.el,v 9.9 2008/07/21 15:14:58 pier Exp
-
-;(require 'proof-syntax)
-;(require 'proof-utils) ; proof-locate-executable
-(require 'gallina-db)
-
-
-
- ;;; keyword databases
-
-
-(defcustom coq-user-tactics-db nil
- "User defined tactic information. See `coq-syntax-db' for
- syntax. It is not necessary to add your own tactics here (it is not
- needed by the synchronizing/backtracking system). You may however do
- so for the following reasons:
-
- 1 your tactics will be colorized by font-lock
-
- 2 your tactics will be added to the menu and to completion when
- calling \\[coq-insert-tactic]
-
- 3 you may define an abbreviation for your tactic."
-
- :type '(repeat sexp)
- :group 'coq)
-
-
-(defcustom coq-user-commands-db nil
- "User defined command information. See `coq-syntax-db' for
- syntax. It is not necessary to add your own commands here (it is not
- needed by the synchronizing/backtracking system). You may however do
- so for the following reasons:
-
- 1 your commands will be colorized by font-lock
-
- 2 your commands will be added to the menu and to completion when
- calling \\[coq-insert-command]
-
- 3 you may define an abbreviation for your command."
-
- :type '(repeat sexp)
- :group 'coq)
-
-(defcustom coq-user-tacticals-db nil
- "User defined tactical information. See `coq-syntax-db' for
- syntax. It is not necessary to add your own commands here (it is not
- needed by the synchronizing/backtracking system). You may however do
- so for the following reasons:
-
- 1 your commands will be colorized by font-lock
-
- 2 your commands will be added to the menu and to completion when
- calling \\[coq-insert-command]
-
- 3 you may define an abbreviation for your command."
-
- :type '(repeat sexp)
- :group 'coq)
-
-(defcustom coq-user-solve-tactics-db nil
- "User defined closing tactics. See `coq-syntax-db' for
- syntax. It is not necessary to add your own commands here (it is not
- needed by the synchronizing/backtracking system). You may however do
- so for the following reasons:
-
- 1 your commands will be colorized by font-lock
-
- 2 your commands will be added to the menu and to completion when
- calling \\[coq-insert-command]
-
- 3 you may define an abbreviation for your command."
-
- :type '(repeat sexp)
- :group 'coq)
-
-
-
-(defcustom coq-user-reserved-db nil
- "User defined reserved keywords information. See `coq-syntax-db' for
- syntax. It is not necessary to add your own commands here (it is not
- needed by the synchronizing/backtracking system). You may however do
- so for the following reasons:
-
- 1 your commands will be colorized by font-lock
-
- 2 your commands will be added to the menu and to completion when
- calling \\[coq-insert-command]
-
- 3 you may define an abbreviation for your command."
-
- :type '(repeat sexp)
- :group 'coq)
-
-
-
-(defvar coq-tactics-db
- (append
- coq-user-tactics-db
- '(
- ("absurd " "abs" "absurd " t "absurd")
- ("apply" "ap" "apply " t "apply")
- ("assert by" "assb" "assert ( # : # ) by #" t "assert")
- ("assert" "ass" "assert ( # : # )" t)
- ;; ("assumption" "as" "assumption" t "assumption")
- ("auto with arith" "awa" "auto with arith" t)
- ("auto with" "aw" "auto with @{db}" t)
- ("auto" "a" "auto" t "auto")
- ("autorewrite with in using" "arwiu" "autorewrite with @{db,db...} in @{hyp} using @{tac}" t)
- ("autorewrite with in" "arwi" "autorewrite with @{db,db...} in @{hyp}" t)
- ("autorewrite with using" "arwu" "autorewrite with @{db,db...} using @{tac}" t)
- ("autorewrite with" "ar" "autorewrite with @{db,db...}" t "autorewrite")
- ("case" "c" "case " t "case")
- ("cbv" "cbv" "cbv beta [#] delta iota zeta" t "cbv")
- ("change in" "chi" "change # in #" t)
- ("change with in" "chwi" "change # with # in #" t)
- ("change with" "chw" "change # with" t)
- ("change" "ch" "change " t "change")
- ("clear" "cl" "clear" t "clear")
- ("clearbody" "cl" "clearbody" t "clearbody")
- ("cofix" "cof" "cofix" t "cofix")
- ("coinduction" "coind" "coinduction" t "coinduction")
- ("compare" "cmpa" "compare # #" t "compare")
- ("compute" "cmpu" "compute" t "compute")
- ;; ("congruence" "cong" "congruence" t "congruence")
- ("constructor" "cons" "constructor" t "constructor")
- ;; ("contradiction" "contr" "contradiction" t "contradiction")
- ("cut" "cut" "cut" t "cut")
- ("cutrewrite" "cutr" "cutrewrite -> # = #" t "cutrewrite")
- ;; ("decide equality" "deg" "decide equality" t "decide\\s-+equality")
- ("decompose record" "decr" "decompose record #" t "decompose\\s-+record")
- ("decompose sum" "decs" "decompose sum #" t "decompose\\s-+sum")
- ("decompose" "dec" "decompose [#] #" t "decompose")
- ("dependent inversion" "depinv" "dependent inversion" t "dependent\\s-+inversion")
- ("dependent inversion with" "depinvw" "dependent inversion # with #" t)
- ("dependent inversion_clear" "depinvc" "dependent inversion_clear" t "dependent\\s-+inversion_clear")
- ("dependent inversion_clear with" "depinvw" "dependent inversion_clear # with #" t)
- ("dependent rewrite ->" "depr" "dependent rewrite -> @{id}" t "dependent\\s-+rewrite")
- ("dependent rewrite <-" "depr<" "dependent rewrite <- @{id}" t)
- ("destruct as" "desa" "destruct # as #" t)
- ("destruct using" "desu" "destruct # using #" t)
- ("destruct" "des" "destruct " t "destruct")
- ;; ("discriminate" "dis" "discriminate" t "discriminate")
- ("discrR" "discrR" "discrR" t "discrR")
- ("double induction" "dind" "double induction # #" t "double\\s-+induction")
- ("eapply" "eap" "eapply #" t "eapply")
- ("eauto with arith" "eawa" "eauto with arith" t)
- ("eauto with" "eaw" "eauto with @{db}" t)
- ("eauto" "ea" "eauto" t "eauto")
- ("econstructor" "econs" "econstructor" t "econstructor")
- ("eexists" "eex" "eexists" t "eexists")
- ("eleft" "eleft" "eleft" t "eleft")
- ("elim using" "elu" "elim # using #" t)
- ("elim" "e" "elim #" t "elim")
- ("elimtype" "elt" "elimtype" "elimtype")
- ("eright" "erig" "eright" "eright")
- ("esplit" "esp" "esplit" t "esplit")
- ;; ("exact" "exa" "exact" t "exact")
- ("exists" "ex" "exists #" t "exists")
- ;; ("fail" "fa" "fail" nil)
- ;; ("field" "field" "field" t "field")
- ("firstorder" "fsto" "firstorder" t "firstorder")
- ("firstorder with" "fsto" "firstorder with #" t)
- ("firstorder with using" "fsto" "firstorder # with #" t)
- ("fold" "fold" "fold #" t "fold")
- ;; ("fourier" "four" "fourier" t "fourier")
- ("functional induction" "fi" "functional induction @{f} @{args}" t "functional\\s-+induction")
- ("generalize dependent" "gd" "generalize dependent #" t "generalize\\s-+dependent")
- ("generalize" "g" "generalize #" t "generalize")
- ("hnf" "hnf" "hnf" t "hnf")
- ("idtac" "id" "idtac" nil "idtac") ; also in tacticals with abbrev id
- ("idtac \"" "id\"" "idtac \"#\"") ; also in tacticals
- ("induction" "ind" "induction #" t "induction")
- ("induction using" "indu" "induction # using #" t)
- ("injection" "inj" "injection #" t "injection")
- ("instantiate" "inst" "instantiate" t "instantiate")
- ("intro" "i" "intro" t "intro")
- ("intro after" "ia" "intro # after #" t)
- ("intros" "is" "intros #" t "intros")
- ("intros! (guess names)" nil "intros #" nil nil coq-insert-intros)
- ("intros until" "isu" "intros until #" t)
- ("intuition" "intu" "intuition #" t "intuition")
- ("inversion" "inv" "inversion #" t "inversion")
- ("inversion in" "invi" "inversion # in #" t)
- ("inversion using" "invu" "inversion # using #" t)
- ("inversion using in" "invui" "inversion # using # in #" t)
- ("inversion_clear" "invcl" "inversion_clear" t "inversion_clear")
- ("lapply" "lap" "lapply" t "lapply")
- ("lazy" "lazy" "lazy beta [#] delta iota zeta" t "lazy")
- ("left" "left" "left" t "left")
- ("linear" "lin" "linear" t "linear")
- ("load" "load" "load" t "load")
- ("move after" "mov" "move # after #" t "move")
- ("omega" "o" "omega" t "omega")
- ("pattern" "pat" "pattern" t "pattern")
- ("pattern(s)" "pats" "pattern # , #" t)
- ("pattern at" "pata" "pattern # at #" t)
- ("pose" "po" "pose ( # := # )" t "pose")
- ("prolog" "prol" "prolog" t "prolog")
- ("quote" "quote" "quote" t "quote")
- ("quote []" "quote2" "quote # [#]" t)
- ("red" "red" "red" t "red")
- ("refine" "ref" "refine" t "refine")
- ;; ("reflexivity" "refl" "reflexivity #" t "reflexivity")
- ("rename into" "ren" "rename # into #" t "rename")
- ("replace with" "rep" "replace # with #" t "replace")
- ("replace with in" "repi" "replace # with # in #" t)
- ("rewrite <- in" "ri<" "rewrite <- # in #" t)
- ("rewrite <-" "r<" "rewrite <- #" t)
- ("rewrite in" "ri" "rewrite # in #" t)
- ("rewrite" "r" "rewrite #" t "rewrite")
- ("right" "rig" "right" t "right")
- ;; ("ring" "ring" "ring #" t "ring")
- ("set in * |-" "seth" "set ( # := #) in * |-" t)
- ("set in *" "set*" "set ( # := #) in *" t)
- ("set in |- *" "setg" "set ( # := #) in |- *" t)
- ("set in" "seti" "set ( # := #) in #" t)
- ("set" "set" "set ( # := #)" t "set")
- ("setoid_replace with" "strep2" "setoid_replace # with #" t "setoid_replace")
- ("setoid replace with" "strep" "setoid replace # with #" t "setoid\\s-+replace")
- ("setoid_rewrite" "strew" "setoid_rewrite #" t "setoid_rewrite")
- ("setoid rewrite" "strew" "setoid rewrite #" t "setoid\\s-+rewrite")
- ("simpl" "s" "simpl" t "simpl")
- ("simpl" "sa" "simpl # at #" t)
- ("simple destruct" "sdes" "simple destruct" t "simple\\s-+destruct")
- ("simple inversion" "sinv" "simple inversion" t "simple\\s-+inversion")
- ("simple induction" "sind" "simple induction" t "simple\\s-+induction")
- ("simplify_eq" "simeq" "simplify_eq @{hyp}" t "simplify_eq")
- ("specialize" "spec" "specialize" t "specialize")
- ("split" "sp" "split" t "split")
- ("split_Rabs" "spra" "splitRabs" t "split_Rabs")
- ("split_Rmult" "sprm" "splitRmult" t "split_Rmult")
- ("stepl" "stl" "stepl #" t "stepl")
- ("stepl by" "stlb" "stepl # by #" t)
- ("stepr" "str" "stepr #" t "stepr")
- ("stepr by" "strb" "stepr # by #" t)
- ("subst" "su" "subst #" t "subst")
- ("symmetry" "sy" "symmetry" t "symmetry")
- ("symmetry in" "syi" "symmetry in #" t)
- ;; ("tauto" "ta" "tauto" t "tauto")
- ("transitivity" "trans" "transitivity #" t "transitivity")
- ("trivial" "t" "trivial" t "trivial")
- ("trivial with" "tw" "trivial with @{db}" t)
- ("unfold" "u" "unfold #" t "unfold")
- ("unfold(s)" "us" "unfold # , #" t)
- ("unfold in" "unfi" "unfold # in #" t)
- ("unfold at" "unfa" "unfold # at #" t)
- ))
- "Coq tactics information list. See `coq-syntax-db' for syntax. "
- )
-
-(defvar coq-solve-tactics-db
- (append
- coq-user-solve-tactics-db
- '(
- ("assumption" "as" "assumption" t "assumption")
- ("by" "by" "by #" t "by")
- ("congruence" "cong" "congruence" t "congruence")
- ("contradiction" "contr" "contradiction" t "contradiction")
- ("decide equality" "deg" "decide equality" t "decide\\s-+equality")
- ("discriminate" "dis" "discriminate" t "discriminate")
- ("exact" "exa" "exact" t "exact")
- ("fourier" "four" "fourier" t "fourier")
- ("fail" "fa" "fail" nil)
- ("field" "field" "field" t "field")
- ("omega" "o" "omega" t "omega")
- ("reflexivity" "refl" "reflexivity #" t "reflexivity")
- ("ring" "ring" "ring #" t "ring")
- ("solve" nil "solve [ # | # ]" nil "solve")
- ("tauto" "ta" "tauto" t "tauto")
- ))
- "Coq tactic(al)s that solve a subgoal."
- )
-
-
-(defvar coq-tacticals-db
- (append
- coq-user-tacticals-db
- '(
- ("info" nil "info #" nil "info")
- ("first" nil "first [ # | # ]" nil "first")
- ("abstract" nil "abstract @{tac} using @{name}." nil "abstract")
- ("do" nil "do @{num} @{tac}" nil "do")
- ("idtac" nil "idtac") ; also in tactics
- ; ("idtac \"" nil "idtac \"#\"") ; also in tactics
- ("fail" "fa" "fail" nil "fail")
- ; ("fail \"" "fa\"" "fail" nil) ;
- ; ("orelse" nil "orelse #" t "orelse")
- ("repeat" nil "repeat #" nil "repeat")
- ("try" nil "try #" nil "try")
- ("progress" nil "progress #" nil "progress")
- ("|" nil "[ # | # ]" nil)
- ("||" nil "# || #" nil)
- ))
- "Coq tacticals information list. See `coq-syntax-db' for syntax.")
-
-
-
-
-(defvar coq-decl-db
- '(
- ("Axiom" "ax" "Axiom # : #" t "Axiom")
- ("Hint Constructors" "hc" "Hint Constructors # : #." t "Hint\\s-+Constructors")
- ("Hint Extern" "he" "Hint Extern @{cost} @{pat} => @{tac} : @{db}." t "Hint\\s-+Extern")
- ("Hint Immediate" "hi" "Hint Immediate # : @{db}." t "Hint\\s-+Immediate")
- ("Hint Resolve" "hr" "Hint Resolve # : @{db}." t "Hint\\s-+Resolve")
- ("Hint Rewrite ->" "hrw" "Hint Rewrite -> @{t1,t2...} using @{tac} : @{db}." t "Hint\\s-+Rewrite")
- ("Hint Rewrite <-" "hrw" "Hint Rewrite <- @{t1,t2...} using @{tac} : @{db}." t )
- ("Hint Unfold" "hu" "Hint Unfold # : #." t "Hint\\s-+Unfold")
- ("Hypothesis" "hyp" "Hypothesis #: #" t "Hypothesis")
- ("Hypotheses" "hyp" "Hypotheses #: #" t "Hypotheses")
- ("Parameter" "par" "Parameter #: #" t "Parameter")
- ("Parameters" "par" "Parameter #: #" t "Parameters")
- ("Conjecture" "conj" "Conjecture #: #." t "Conjecture")
- ("Variable" "v" "Variable #: #." t "Variable")
- ("Variables" "vs" "Variables # , #: #." t "Variables")
- ("Coercion" "coerc" "Coercion @{id} : @{typ1} >-> @{typ2}." t "Coercion")
- )
- "Coq declaration keywords information list. See `coq-syntax-db' for syntax."
- )
-
-(defvar coq-defn-db
- '(
- ("CoFixpoint" "cfix" "CoFixpoint # (#:#) : # :=\n#." t "CoFixpoint")
- ("CoInductive" "coindv" "CoInductive # : # :=\n|# : #." t "CoInductive")
- ("Declare Module : :=" "dm" "Declare Module # : # := #." t "Declare\\s-+Module")
- ("Declare Module <: :=" "dm2" "Declare Module # <: # := #." t);; careful
- ("Declare Module Import : :=" "dmi" "Declare Module # : # := #." t)
- ("Declare Module Import <: :=" "dmi2" "Declare Module # <: # := #." t);; careful
- ("Declare Module Export : :=" "dme" "Declare Module # : # := #." t)
- ("Declare Module Export <: :=" "dme2" "Declare Module # <: # := #." t);; careful
- ("Definition" "def" "Definition #:# := #." t "Definition");; careful
- ("Definition (2 args)" "def2" "Definition # (# : #) (# : #):# := #." t)
- ("Definition (3 args)" "def3" "Definition # (# : #) (# : #) (# : #):# := #." t)
- ("Definition (4 args)" "def4" "Definition # (# : #) (# : #) (# : #) (# : #):# := #." t)
- ("Program Definition" "pdef" "Program Definition #:# := #." t "Program\\s-+Definition");; careful ?
- ("Program Definition (2 args)" "pdef2" "Program Definition # (# : #) (# : #):# := #." t)
- ("Program Definition (3 args)" "pdef3" "Program Definition # (# : #) (# : #) (# : #):# := #." t)
- ("Program Definition (4 args)" "pdef4" "Program Definition # (# : #) (# : #) (# : #) (# : #):# := #." t)
- ("Derive Inversion" nil "Derive Inversion @{id} with # Sort #." t "Derive\\s-+Inversion")
- ("Derive Dependent Inversion" nil "Derive Dependent Inversion @{id} with # Sort #." t "Derive\\s-+Dependent\\s-+Inversion")
- ("Derive Inversion_clear" nil "Derive Inversion_clear @{id} with # Sort #." t)
- ("Fixpoint" "fix" "Fixpoint # (#:#) {struct @{arg}} : # :=\n#." t "Fixpoint")
- ("Program Fixpoint" "pfix" "Program Fixpoint # (#:#) {struct @{arg}} : # :=\n#." t "Program\\s-+Fixpoint")
- ("Program Fixpoint measure" "pfixm" "Program Fixpoint # (#:#) {measure @{arg} @{f}} : # :=\n#." t)
- ("Program Fixpoint wf" "pfixwf" "Program Fixpoint # (#:#) {wf @{arg} @{f}} : # :=\n#." t)
- ("Function" "func" "Function # (#:#) {struct @{arg}} : # :=\n#." t "Function")
- ("Function measure" "funcm" "Function # (#:#) {measure @{f} @{arg}} : # :=\n#." t)
- ("Function wf" "func wf" "Function # (#:#) {wf @{R} @{arg}} : # :=\n#." t)
- ("Functional Scheme with" "fsw" "Functional Scheme @{name} := Induction for @{fun} with @{mutfuns}." t )
- ("Functional Scheme" "fs" "Functional Scheme @{name} := Induction for @{fun}." t "Functional\\s-+Scheme")
- ("Inductive" "indv" "Inductive # : # := # : #." t "Inductive")
- ("Inductive (2 args)" "indv2" "Inductive # : # :=\n| # : #\n| # : #." t )
- ("Inductive (3 args)" "indv3" "Inductive # : # :=\n| # : #\n| # : #\n| # : #." t )
- ("Inductive (4 args)" "indv4" "Inductive # : # :=\n| # : #\n| # : #\n| # : #\n| # : #." t )
- ("Inductive (5 args)" "indv5" "Inductive # : # :=\n| # : #\n| # : #\n| # : #\n| # : #\n| # : #." t )
- ("Variant" "indv" "Variant # : # := # : #." t "Variant")
- ("Variant (2 args)" "indv2" "Variant # : # :=\n| # : #\n| # : #." t )
- ("Variant (3 args)" "indv3" "Variant # : # :=\n| # : #\n| # : #\n| # : #." t )
- ("Variant (4 args)" "indv4" "Variant # : # :=\n| # : #\n| # : #\n| # : #\n| # : #." t )
- ("Variant (5 args)" "indv5" "Variant # : # :=\n| # : #\n| # : #\n| # : #\n| # : #\n| # : #." t )
- ("Let" "Let" "Let # : # := #." t "Let")
- ("Ltac" "ltac" "Ltac # := #" t "Ltac")
- ("Module :=" "mo" "Module # : # := #." t ) ; careful
- ("Module <: :=" "mo2" "Module # <: # := #." t ) ; careful
- ("Module Import :=" "moi" "Module Import # : # := #." t ) ; careful
- ("Module Import <: :=" "moi2" "Module Import # <: # := #." t ) ; careful
- ("Module Export :=" "moe" "Module Export # : # := #." t ) ; careful
- ("Module Export <: :=" "moe2" "Module Export# <: # := #." t ) ; careful
- ("Record" "rec" "Record # : # := {\n# : #;\n# : # }" t "Record")
- ("Scheme" "sc" "Scheme @{name} := #." t "Scheme")
- ("Scheme Induction" "sci" "Scheme @{name} := Induction for # Sort #." t)
- ("Scheme Minimality" "scm" "Scheme @{name} := Minimality for # Sort #." t)
- ("Structure" "str" "Structure # : # := {\n# : #;\n# : # }" t "Structure")
- )
- "Coq definition keywords information list. See `coq-syntax-db' for syntax. "
- )
-
-;; modules and section are indented like goal starters
-(defvar coq-goal-starters-db
- '(
- ("Add Morphism" "addmor" "Add Morphism @{f} : @{id}" t "Add\\s-+Morphism")
- ("Chapter" "chp" "Chapter # : #." t "Chapter")
- ("Corollary" "cor" "Corollary # : #.\nProof.\n#\nQed." t "Corollary")
- ("Declare Module :" "dmi" "Declare Module # : #.\n#\nEnd #." t)
- ("Declare Module <:" "dmi2" "Declare Module # <: #.\n#\nEnd #." t)
- ("Definition goal" "defg" "Definition #:#.\n#\nQed." t);; careful
- ("Fact" "fct" "Fact # : #." t "Fact")
- ("Goal" nil "Goal #." t "Goal")
- ("Lemma" "l" "Lemma # : #.\nProof.\n#\nQed." t "Lemma")
- ("Program Lemma" "pl" "Program Lemma # : #.\nProof.\n#\nQed." t "Program\\s-+Lemma")
- ("Module! (interactive)" nil "Module # : #.\n#\nEnd #." nil nil coq-insert-section-or-module)
- ("Module Type" "mti" "Module Type #.\n#\nEnd #." t "Module\\s-+Type") ; careful
- ("Module :" "moi" "Module # : #.\n#\nEnd #." t "Module") ; careful
- ("Module <:" "moi2" "Module # <: #.\n#\nEnd #." t ) ; careful
- ("Remark" "rk" "Remark # : #.\n#\nQed." t "Remark")
- ("Section" "sec" "Section #." t "Section")
- ("Theorem" "th" "Theorem # : #.\n#\nQed." t "Theorem")
- ("Program Theorem" "pth" "Program Theorem # : #.\nProof.\n#\nQed." t "Program\\s-+Theorem")
- ("Obligation" "obl" "Obligation #.\n#\nQed." t "Obligation")
- ("Next Obligation" "nobl" "Next Obligation.\n#\nQed." t "Next Obligation")
- )
- "Coq goal starters keywords information list. See `coq-syntax-db' for syntax. "
- )
-
-;; command that are not declarations, definition or goal starters
-(defvar coq-other-commands-db
- '(
- ;; ("Abort" nil "Abort." t "Abort" nil nil);don't appear in menu
- ("About" nil "About #." nil "About")
- ("Add" nil "Add #." nil "Add" nil t)
- ("Add Abstract Ring" nil "Add Abstract Ring #." t "Add\\s-+Abstract\\s-+Ring")
- ("Add Abstract Semi Ring" nil "Add Abstract Semi Ring #." t "Add\\s-+Abstract\\s-+Semi\\s-+Ring")
- ("Add Field" nil "Add Field #." t "Add\\s-+Field")
- ("Add LoadPath" nil "Add LoadPath #." nil "Add\\s-+LoadPath")
- ("Add ML Path" nil "Add ML Path #." nil "Add\\s-+ML\\s-+Path")
- ("Add Morphism" nil "Add Morphism #." t "Add\\s-+Morphism")
- ("Add Printing" nil "Add Printing #." t "Add\\s-+Printing")
- ("Add Printing Constructor" nil "Add Printing Constructor #." t "Add\\s-+Printing\\s-+Constructor")
- ("Add Printing If" nil "Add Printing If #." t "Add\\s-+Printing\\s-+If")
- ("Add Printing Let" nil "Add Printing Let #." t "Add\\s-+Printing\\s-+Let")
- ("Add Printing Record" nil "Add Printing Record #." t "Add\\s-+Printing\\s-+Record")
- ("Add Rec LoadPath" nil "Add Rec LoadPath #." nil "Add\\s-+Rec\\s-+LoadPath")
- ("Add Rec ML Path" nil "Add Rec ML Path #." nil "Add\\s-+Rec\\s-+ML\\s-+Path")
- ("Add Ring" nil "Add Ring #." t "Add\\s-+Ring")
- ("Add Semi Ring" nil "Add Semi Ring #." t "Add\\s-+Semi\\s-+Ring")
- ("Add Setoid" nil "Add Setoid #." t "Add\\s-+Setoid")
- ("Admit Obligations" "oblsadmit" "Admit Obligations." nil "Admit\\s-+Obligations")
- ("Arguments Scope" "argsc" "Arguments Scope @{id} [ @{_} ]" t "Arguments\\s-+Scope")
- ("Bind Scope" "bndsc" "Bind Scope @{scope} with @{type}" t "Bind\\s-+Scope")
- ("Canonical Structure" nil "Canonical Structure #." t "Canonical\\s-+Structure")
- ("Cd" nil "Cd #." nil "Cd")
- ("Check" nil "Check" nil "Check")
- ("Close Local Scope" "cllsc" "Close Local Scope #" t "Close\\s-+Local\\s-+Scope")
- ("Close Scope" "clsc" "Close Scope #" t "Close\\s-+Scope")
- ("Comments" nil "Comments #." nil "Comments")
- ("Delimit Scope" "delsc" "Delimit Scope @{scope} with @{id}." t "Delimit\\s-+Scope" )
- ("Eval" nil "Eval #." nil "Eval")
- ("Export" nil "Export #." t "Export")
- ("Extract Constant" "extrc" "Extract Constant @{id} => \"@{id}\"." nil "Extract\\s-+Constant")
- ("Extract Inlined Constant" "extric" "Extract Inlined Constant @{id} => \"@{id}\"." nil "Extract\\s-+Inlined\\s-+Constant")
- ("Extract Inductive" "extri" "Extract Inductive @{id} => \"@{id}\" [\"@{id}\" \"@{id...}\"]." nil "Extract")
- ("Extraction" "extr" "Extraction @{id}." nil "Extraction")
- ("Extraction (in a file)" "extrf" "Extraction \"@{file}\" @{id}." nil)
- ("Extraction Inline" nil "Extraction Inline #." t "Extraction\\s-+Inline")
- ("Extraction NoInline" nil "Extraction NoInline #." t "Extraction\\s-+NoInline")
- ("Extraction Language" "extrlang" "Extraction Language #." t "Extraction\\s-+Language")
- ("Extraction Library" "extrl" "Extraction Library @{id}." nil "Extraction\\s-+Library")
- ("Focus" nil "Focus #." nil "Focus")
- ("Identity Coercion" nil "Identity Coercion #." t "Identity\\s-+Coercion")
- ("Implicit Arguments Off" nil "Implicit Arguments Off." t "Implicit\\s-+Arguments\\s-+Off")
- ("Implicit Arguments On" nil "Implicit Arguments On." t "Implicit\\s-+Arguments\\s-+On")
- ("Implicit Arguments" nil "Implicit Arguments # [#]." t "Implicit\\s-+Arguments")
- ("Import" nil "Import #." t "Import")
- ("Infix" "inf" "Infix \"#\" := # (at level #) : @{scope}." t "Infix")
- ("Inspect" nil "Inspect #." nil "Inspect")
- ("Locate" nil "Locate" nil "Locate")
- ("Locate File" nil "Locate File \"#\"." nil "Locate\\s-+File")
- ("Locate Library" nil "Locate Library #." nil "Locate\\s-+Library")
- ("Notation (assoc)" "notas" "Notation \"#\" := # (at level #, # associativity)." t)
- ("Notation (at assoc)" "notassc" "Notation \"#\" := # (at level #, # associativity) : @{scope}." t)
- ("Notation (at at scope)" "notasc" "Notation \"#\" := # (at level #, # at level #) : @{scope}." t)
- ("Notation (at at)" "nota" "Notation \"#\" := # (at level #, # at level #)." t)
- ("Notation (only parsing)" "notsp" "Notation # := # (only parsing)." t)
- ("Notation Local (only parsing)" "notslp" "Notation Local # := # (only parsing)." t)
- ("Notation Local" "notsl" "Notation Local # := #." t "Notation\\s-+Local")
- ("Notation (simple)" "nots" "Notation # := #." t "Notation")
- ("Opaque" nil "Opaque #." nil "Opaque")
- ("Obligations Tactic" nil "Obligations Tactic := #." t "Obligations\\s-+Tactic")
- ("Open Local Scope" "oplsc" "Open Local Scope #" t "Open\\s-+Local\\s-+Scope")
- ("Open Scope" "opsc" "Open Scope #" t "Open\\s-+Scope")
- ("Print Coercions" nil "Print Coercions." nil "Print\\s-+Coercions")
- ("Print Hint" nil "Print Hint." nil "Print\\s-+Hint" coq-PrintHint)
- ("Print" "p" "Print #." nil "Print")
- ("Qed" nil "Qed." nil "Qed")
- ("Pwd" nil "Pwd." nil "Pwd")
- ("Recursive Extraction" "recextr" "Recursive Extraction @{id}." nil "Recursive\\s-+Extraction")
- ("Recursive Extraction Library" "recextrl" "Recursive Extraction Library @{id}." nil "Recursive\\s-+Extraction\\s-+Library")
- ("Recursive Extraction Module" "recextrm" "Recursive Extraction Module @{id}." nil "Recursive\\s-+Extraction\\s-+Module")
- ("Remove LoadPath" nil "Remove LoadPath" nil "Remove\\s-+LoadPath")
- ("Remove LoadPath" nil "Remove LoadPath" nil "Remove\\s-+LoadPath")
- ("Remove Printing If" nil "Remove Printing If #." t "Remove\\s-+Printing\\s-+If")
- ("Remove Printing Let" nil "Remove Printing Let #." t "Remove\\s-+Printing\\s-+Let")
- ("Require Export" nil "Require Export #." t "Require\\s-+Export")
- ("Require Import" nil "Require Import #." t "Require\\s-+Import")
- ("Require" nil "Require #." t "Require")
- ("Reserved Notation" nil "Reserved Notation" nil "Reserved\\s-+Notation")
- ("Reset Extraction Inline" nil "Reset Extraction Inline." t "Reset\\s-+Extraction\\s-+Inline")
- ("Search" nil "Search #" nil "Search")
- ("SearchAbout" nil "SearchAbout #" nil "SearchAbout")
- ("SearchPattern" nil "SearchPattern #" nil "SearchPattern")
- ("SearchRewrite" nil "SearchRewrite #" nil "SearchRewrite")
- ("Set Extraction AutoInline" nil "Set Extraction AutoInline" t "Set\\s-+Extraction\\s-+AutoInline")
- ("Set Extraction Optimize" nil "Set Extraction Optimize" t "Set\\s-+Extraction\\s-+Optimize")
- ("Set Implicit Arguments" nil "Set Implicit Arguments" t "Set\\s-+Implicit\\s-+Arguments")
- ("Set Strict Implicit" nil "Set Strict Implicit" t "Set\\s-+Strict\\s-+Implicit")
- ("Set Printing Synth" nil "Set Printing Synth" t "Set\\s-+Printing\\s-+Synth")
- ("Set Printing Wildcard" nil "Set Printing Wildcard" t "Set\\s-+Printing\\s-+Wildcard")
- ("Set Printing All" "sprall" "Set Printing All" t "Set\\s-+Printing\\s-+All")
- ("Set Printing Records" nil "Set Printing Records" t "Set\\s-+Printing\\s-+Records")
- ("Set Hyps Limit" nil "Set Hyps Limit #." nil "Set\\s-+Hyps\\s-+Limit")
- ("Set Printing Coercions" nil "Set Printing Coercions." t "Set\\s-+Printing\\s-+Coercions")
- ("Set Printing Notations" "sprn" "Set Printing Notations" t "Set\\s-+Printing\\s-+Notations")
- ("Set Undo" nil "Set Undo #." nil "Set\\s-+Undo")
- ("Show" nil "Show #." nil "Show")
- ("Solve Obligations" "oblssolve" "Solve Obligations using #." nil "Solve\\s-+Obligations")
- ("Test" nil "Test" nil "Test" nil t)
- ("Test Printing Depth" nil "Test Printing Depth." nil "Test\\s-+Printing\\s-+Depth")
- ("Test Printing If" nil "Test Printing If #." nil "Test\\s-+Printing\\s-+If")
- ("Test Printing Let" nil "Test Printing Let #." nil "Test\\s-+Printing\\s-+Let")
- ("Test Printing Synth" nil "Test Printing Synth." nil "Test\\s-+Printing\\s-+Synth")
- ("Test Printing Width" nil "Test Printing Width." nil "Test\\s-+Printing\\s-+Width")
- ("Test Printing Wildcard" nil "Test Printing Wildcard." nil "Test\\s-+Printing\\s-+Wildcard")
- ("Transparent" nil "Transparent #." nil "Transparent")
- ("Unfocus" nil "Unfocus." nil "Unfocus")
- ("Unset Extraction AutoInline" nil "Unset Extraction AutoInline" t "Unset\\s-+Extraction\\s-+AutoInline")
- ("Unset Extraction Optimize" nil "Unset Extraction Optimize" t "Unset\\s-+Extraction\\s-+Optimize")
- ("Unset Implicit Arguments" nil "Unset Implicit Arguments" t "Unset\\s-+Implicit\\s-+Arguments")
- ("Unset Strict Implicit" nil "Unset Strict Implicit" t "Unset\\s-+Strict\\s-+Implicit")
- ("Unset Printing Synth" nil "Unset Printing Synth" t "Unset\\s-+Printing\\s-+Synth")
- ("Unset Printing Wildcard" nil "Unset Printing Wildcard" t "Unset\\s-+Printing\\s-+Wildcard")
- ("Unset Hyps Limit" nil "Unset Hyps Limit" nil "Unset\\s-+Hyps\\s-+Limit")
- ("Unset Printing All" "unsprall" "Unset Printing All" nil "Unset\\s-+Printing\\s-+All")
- ("Unset Printing Coercion" nil "Unset Printing Coercion #." t "Unset\\s-+Printing\\s-+Coercion")
- ("Unset Printing Coercions" nil "Unset Printing Coercions." nil "Unset\\s-+Printing\\s-+Coercions")
- ("Unset Printing Notations" "unsprn" "Unset Printing Notations" nil "Unset\\s-+Printing\\s-+Notations")
- ("Unset Undo" nil "Unset Undo." nil "Unset\\s-+Undo")
- ; ("print" "pr" "print #" "print")
- )
- "Command that are not declarations, definition or goal starters."
- )
-
-(defvar coq-commands-db
- (append coq-decl-db coq-defn-db coq-goal-starters-db
- coq-other-commands-db coq-user-commands-db)
- "Coq all commands keywords information list. See `coq-syntax-db' for syntax. "
- )
-
-
-(defvar coq-terms-db
- '(
- ("fun (1 args)" "f" "fun #:# => #" nil "fun")
- ("fun (2 args)" "f2" "fun (#:#) (#:#) => #")
- ("fun (3 args)" "f3" "fun (#:#) (#:#) (#:#) => #")
- ("fun (4 args)" "f4" "fun (#:#) (#:#) (#:#) (#:#) => #")
- ("forall" "fo" "forall #:#,#" nil "forall")
- ("forall (2 args)" "fo2" "forall (#:#) (#:#), #")
- ("forall (3 args)" "fo3" "forall (#:#) (#:#) (#:#), #")
- ("forall (4 args)" "fo4" "forall (#:#) (#:#) (#:#) (#:#), #")
- ("if" "if" "if # then # else #" nil "if")
- ("let in" "li" "let # := # in #" nil "let")
- ("match! (from type)" nil "" nil "match" coq-insert-match)
- ("match with" "m" "match # with\n| # => #\nend")
- ("match with 2" "m2" "match # with\n| # => #\n| # => #\nend")
- ("match with 3" "m3" "match # with\n| # => #\n| # => #\n| # => #\nend")
- ("match with 4" "m4" "match # with\n| # => #\n| # => #\n| # => #\n| # => #\nend")
- ("match with 5" "m5" "match # with\n| # => #\n| # => #\n| # => #\n| # => #\n| # => #\nend")
- )
- "Coq terms keywords information list. See `coq-syntax-db' for syntax. "
- )
-
-
-
-
-
-
-
- ;;; Goals (and module/sections) starters detection
-
-
-;; ----- keywords for font-lock.
-
-;; FIXME da: this one function breaks the nice configuration of Proof General:
-;; would like to have proof-goal-regexp instead.
-;; Unfortunately Coq allows "Definition" and friends to perhaps have a goal,
-;; so it appears more difficult than just a proof-goal-regexp setting.
-;; Future improvement may simply to be allow a function value for
-;; proof-goal-regexp.
-
-;; FIXME Pierre: the right way IMHO here would be to set a span
-;; property 'goalcommand when coq prompt says it (if the name of
-;; current proof has changed).
-
-;; excerpt of Jacek Chrzaszcz, implementer of the module system: sorry
-;; for the french:
-;;*) suivant les suggestions de Chritine, pas de mode preuve dans un type de
-;; module (donc pas de Definition truc:machin. Lemma, Theorem ... )
-;;
-;; *) la commande Module M [ ( : | <: ) MTYP ] [ := MEXPR ] est valable
-;; uniquement hors d'un MT
-;; - si :=MEXPR est absent, elle demarre un nouveau module interactif
-;; - si :=MEXPR est present, elle definit un module
-;; (la fonction vernac_define_module dans toplevel/vernacentries)
-;;
-;; *) la nouvelle commande Declare Module M [ ( : | <: ) MTYP ] [ := MEXPR ]
-;; est valable uniquement dans un MT
-;; - si :=MEXPR absent, :MTYP absent, elle demarre un nouveau module
-;; interactif
-;; - si (:=MEXPR absent, :MTYP present)
-;; ou (:=MEXPR present, :MTYP absent)
-;; elle declare un module.
-;; (la fonction vernac_declare_module dans toplevel/vernacentries)
-
-(defun coq-count-match (regexp strg)
- "Count the number of (maximum, non overlapping) matching substring
- of STRG matching REGEXP. Empty match are counted once."
- (let ((nbmatch 0) (str strg))
- (while (and (proof-string-match regexp str) (not (string-equal str "")))
- (incf nbmatch)
- (if (= (match-end 0) 0) (setq str (substring str 1))
- (setq str (substring str (match-end 0)))))
- nbmatch))
-
-;; This function is used for amalgamating a proof into a single
-;; goal-save region (proof-goal-command-p used in
-;; proof-done-advancing-save in generic/proof-script.el) for coq <
-;; 8.0. It is the test when looking backward the start of the proof.
-;; It is NOT used for coq > v8.1
-;; (coq-find-and-forget in gallina.el uses state numbers, proof numbers and
-;; lemma names given in the prompt)
-
-;; compatibility with v8.0, will delete it some day
-(defun coq-goal-command-str-v80-p (str)
- "See `coq-goal-command-p'."
- (let* ((match (coq-count-match "\\<match\\>" str))
- (with (coq-count-match "\\<with\\>" str))
- (letwith (+ (coq-count-match "\\<let\\>" str) (- with match)))
- (affect (coq-count-match ":=" str)))
-
- (and (proof-string-match coq-goal-command-regexp str)
- (not ;
- (and
- (proof-string-match "\\`\\(Local\\|Definition\\|Lemma\\|Module\\)\\>" str)
- (not (= letwith affect))))
- (not (proof-string-match "\\`Declare\\s-+Module\\(\\w\\|\\s-\\|<\\)*:" str))
- )
- )
- )
-
-;; Module and or section openings are detected syntactically. Module
-;; *openings* are difficult to detect because there can be Module
-;; ...with X := ... . So we need to count :='s to detect real openings.
-
-;; TODO: have opened section/chapter in the prompt too, and get rid of
-;; syntactical tests everywhere
-(defun coq-module-opening-p (str)
- "Decide whether STR is a module or section opening or not.
-Used by `coq-goal-command-p'"
- (let* ((match (coq-count-match "\\<match\\>" str))
- (with (coq-count-match "\\<with\\>" str))
- (letwith (+ (coq-count-match "\\<let\\>" str) (- with match)))
- (affect (coq-count-match ":=" str)))
- (and (proof-string-match "\\`\\(Module\\)\\>" str)
- (= letwith affect))
- ))
-
-(defun coq-section-command-p (str)
- (proof-string-match "\\`\\(Section\\|Chapter\\)\\>" str))
-
-
-(defun coq-goal-command-str-v81-p (str)
- "Decide syntactically whether STR is a goal start or not. Use
- `coq-goal-command-p-v81' on a span instead if possible."
- (coq-goal-command-str-v80-p str)
- )
-
-;; This is the function that tests if a SPAN is a goal start. All it
-;; has to do is look at the 'goalcmd attribute of the span.
-;; It also looks if this is not a module start.
-
-;; TODO: have also attributes 'modulecmd and 'sectioncmd. This needs
-;; something in the coq prompt telling the name of all opened modules
-;; (like for open goals), and use it to set goalcmd --> no more need
-;; to look at Modules and section (actually indentation will still
-;; need it)
-(defun coq-goal-command-p-v81 (span)
- "see `coq-goal-command-p'"
- (or (span-property span 'goalcmd)
- ;; module and section starts are detected here
- (let ((str (or (span-property span 'cmd) "")))
- (or (coq-section-command-p str)
- (coq-module-opening-p str))
- )))
-
-;; In coq > 8.1 This is used only for indentation.
-(defun coq-goal-command-str-p (str)
- "Decide whether argument is a goal or not. Use
- `coq-goal-command-p' on a span instead if posible."
- (cond
- (coq-version-is-V8-1 (coq-goal-command-str-v81-p str))
- (coq-version-is-V8-0 (coq-goal-command-str-v80-p str))
- (t (coq-goal-command-str-v80-p str));; this is temporary
- ))
-
-;; This is used for backtracking
-(defun coq-goal-command-p (span)
- "Decide whether argument is a goal or not."
- (cond
- (coq-version-is-V8-1 (coq-goal-command-p-v81 span))
- (coq-version-is-V8-0 (coq-goal-command-str-v80-p (span-property span 'cmd)))
- (t (coq-goal-command-str-v80-p (span-property span 'cmd)));; this is temporary
- ))
-
-(defvar coq-keywords-save-strict
- '("Defined"
- "Qed"
- "End"
- "Admitted"
- "Abort"
- ))
-
-(defvar coq-keywords-save
- (append coq-keywords-save-strict '("Proof"))
- )
-
-(defun coq-save-command-p (span str)
- "Decide whether argument is a Save command or not"
- (or (proof-string-match coq-save-command-regexp-strict str)
- (and (proof-string-match "\\`Proof\\>" str)
- (not (proof-string-match "Proof\\s-*\\(\\.\\|\\<with\\>\\)" str)))
- )
- )
-
-
-(defvar coq-keywords-kill-goal
- '("Abort"))
-
-;; Following regexps are all state changing
-(defvar coq-keywords-state-changing-misc-commands
- (coq-build-regexp-list-from-db coq-commands-db 'filter-state-changing))
-
-(defvar coq-keywords-goal
- (coq-build-regexp-list-from-db coq-goal-starters-db))
-
-(defvar coq-keywords-decl
- (coq-build-regexp-list-from-db coq-decl-db))
-
-(defvar coq-keywords-defn
- (coq-build-regexp-list-from-db coq-defn-db))
-
-
-(defvar coq-keywords-state-changing-commands
- (append
- coq-keywords-state-changing-misc-commands
- coq-keywords-decl ; all state changing
- coq-keywords-defn ; idem
- coq-keywords-goal)) ; idem
-
-
-;;
-(defvar coq-keywords-state-preserving-commands
- (coq-build-regexp-list-from-db coq-commands-db 'filter-state-preserving))
-
-;; concat this is faster that redoing coq-build-regexp-list-from-db on
-;; whole commands-db
-(defvar coq-keywords-commands
- (append coq-keywords-state-changing-commands
- coq-keywords-state-preserving-commands)
- "All commands keyword.")
-
-(defvar coq-solve-tactics
- (coq-build-regexp-list-from-db coq-solve-tactics-db)
- "Keywords for closing tactic(al)s.")
-
-(defvar coq-tacticals
- (coq-build-regexp-list-from-db coq-tacticals-db)
- "Keywords for tacticals in a Coq script.")
-
-
- ;; From JF Monin:
-(defvar coq-reserved
- (append
- coq-user-reserved-db
- '(
- "False" "True" "after" "as" "cofix" "fix" "forall" "fun" "match"
- "return" "struct" "else" "end" "if" "in" "into" "let" "then"
- "using" "with" "beta" "delta" "iota" "zeta" "after" "until"
- "at" "Sort" "Time"))
- "Reserved keywords of Coq.")
-
-
-(defvar coq-state-changing-tactics
- (coq-build-regexp-list-from-db coq-tactics-db 'filter-state-changing))
-
-(defvar coq-state-preserving-tactics
- (coq-build-regexp-list-from-db coq-tactics-db 'filter-state-preserving))
-
-
-(defvar coq-tactics
- (append coq-state-changing-tactics coq-state-preserving-tactics))
-
-(defvar coq-retractable-instruct
- (append coq-state-changing-tactics coq-keywords-state-changing-commands))
-
-(defvar coq-non-retractable-instruct
- (append coq-state-preserving-tactics
- coq-keywords-state-preserving-commands))
-
-(defvar coq-keywords
- (append coq-keywords-goal coq-keywords-save coq-keywords-decl
- coq-keywords-defn coq-keywords-commands)
- "All keywords in a Coq script.")
-
-
-
-(defvar coq-symbols
- '("|"
- "||"
- ":"
- ";"
- ","
- "("
- ")"
- "["
- "]"
- "{"
- "}"
- ":="
- "=>"
- "->"
- ".")
- "Punctuation Symbols used by Coq.")
-
-;; ----- regular expressions
-(defvar coq-error-regexp "^\\(Error:\\|Discarding pattern\\|Syntax error:\\|System Error:\\|User Error:\\|User error:\\|Anomaly[:.]\\|Toplevel input[,]\\)"
- "A regexp indicating that the Coq process has identified an error.")
-
-(defvar coq-id proof-id)
-(defvar coq-id-shy "\\(?:\\w\\(?:\\w\\|\\s_\\)*\\)")
-
-(defvar coq-ids (proof-ids coq-id " "))
-
-(defun coq-first-abstr-regexp (paren end)
- (concat paren "\\s-*\\(" coq-ids "\\)\\s-*" end))
-
-(defcustom coq-variable-highlight-enable t
- "Activates partial bound variable highlighting"
- :type 'boolean
- :group 'coq)
-
-
-(defvar coq-font-lock-terms
- (if coq-variable-highlight-enable
- (list
- ;; lambda binders
- (list (coq-first-abstr-regexp "\\<fun\\>" "\\(?:=>\\|:\\)") 1 'font-lock-variable-name-face)
- ;; forall binder
- (list (coq-first-abstr-regexp "\\<forall\\>" "\\(?:,\\|:\\)") 1 'font-lock-variable-name-face)
- ; (list "\\<forall\\>"
- ; (list 0 font-lock-type-face)
- ; (list (concat "[^ :]\\s-*\\(" coq-ids "\\)\\s-*") nil nil
- ; (list 0 font-lock-variable-name-face)))
- ;; parenthesized binders
- (list (coq-first-abstr-regexp "(" ":[ a-zA-Z]") 1 'font-lock-variable-name-face)
- ))
- "*Font-lock table for Coq terms.")
-
-
-
-;; According to Coq, "Definition" is both a declaration and a goal.
-;; It is understood here as being a goal. This is important for
-;; recognizing global identifiers, see coq-global-p.
-(defconst coq-save-command-regexp-strict
- (proof-anchor-regexp
- (concat "\\(Time\\s-+\\|\\)\\(" (proof-ids-to-regexp coq-keywords-save-strict)
- "\\)")))
-(defconst coq-save-command-regexp
- (proof-anchor-regexp
- (concat "\\(Time\\s-+\\|\\)\\(" (proof-ids-to-regexp coq-keywords-save)
- "\\)")))
-(defconst coq-save-with-hole-regexp
- (concat "\\(Time\\s-+\\|\\)\\(" (proof-ids-to-regexp coq-keywords-save-strict)
- "\\)\\s-+\\(" coq-id "\\)\\s-*\\."))
-
-(defconst coq-goal-command-regexp
- (proof-anchor-regexp (proof-ids-to-regexp coq-keywords-goal)))
-
-(defconst coq-goal-with-hole-regexp
- (concat "\\(" (proof-ids-to-regexp coq-keywords-goal)
- "\\)\\s-+\\(" coq-id "\\)\\s-*:?"))
-
-(defconst coq-decl-with-hole-regexp
- (concat "\\(" (proof-ids-to-regexp coq-keywords-decl)
- "\\)\\s-+\\(" coq-ids "\\)\\s-*:"))
-
-;; (defconst coq-decl-with-hole-regexp
-;; (if coq-variable-highlight-enable coq-decl-with-hole-regexp-1 'nil))
-
-(defconst coq-defn-with-hole-regexp
- (concat "\\(" (proof-ids-to-regexp coq-keywords-defn)
- "\\)\\s-+\\(" coq-id "\\)"))
-
-;; must match:
-;; "with f x y :" (followed by = or not)
-;; "with f x y (z:" (not followed by =)
-;; BUT NOT:
-;; "with f ... (x:="
-;; "match ... with .. => "
-(defconst coq-with-with-hole-regexp
- (concat "\\(with\\)\\s-+\\(" coq-id "\\)\\s-*\\([^=(.]*:\\|[^(]*(\\s-*"
- coq-id "\\s-*:[^=]\\)"))
-;; marche aussi a peu pres
-;; (concat "\\(with\\)\\s-+\\(" coq-id "\\)\\s-*\\([^(.]*:\\|.*)[^(.]*:=\\)"))
-;;"\\<Prop\\>\\|\\<Set\\>\\|\\<Type\\>"
-(defvar coq-font-lock-keywords-1
- (append
- coq-font-lock-terms
- (list
- (cons (proof-ids-to-regexp coq-solve-tactics) 'coq-solve-tactics-face)
- (cons (proof-ids-to-regexp coq-keywords) 'font-lock-keyword-face)
- (cons (proof-ids-to-regexp coq-reserved) 'font-lock-type-face)
- (cons (proof-ids-to-regexp coq-tactics ) 'proof-tactics-name-face)
- (cons (proof-ids-to-regexp coq-tacticals) 'proof-tacticals-name-face)
- (cons (proof-ids-to-regexp (list "Set" "Type" "Prop")) 'font-lock-type-face)
- (cons "============================" 'font-lock-keyword-face)
- (cons "Subtree proved!" 'font-lock-keyword-face)
- (cons "subgoal [0-9]+ is:" 'font-lock-keyword-face)
- (list "^\\([^ \n]+\\) \\(is defined\\)"
- (list 2 'font-lock-keyword-face t)
- (list 1 'font-lock-function-name-face t))
-
- (list coq-goal-with-hole-regexp 2 'font-lock-function-name-face))
- (if coq-variable-highlight-enable (list (list coq-decl-with-hole-regexp 2 'font-lock-variable-name-face)))
- (list
- (list coq-defn-with-hole-regexp 2 'font-lock-function-name-face)
- (list coq-with-with-hole-regexp 2 'font-lock-function-name-face)
- (list coq-save-with-hole-regexp 2 'font-lock-function-name-face)
- ;; Remove spurious variable and function faces on commas.
- '(proof-zap-commas))))
-
-(defvar coq-font-lock-keywords coq-font-lock-keywords-1)
-
-(defun coq-init-syntax-table ()
- "Set appropriate values for syntax table in current buffer."
-
- (modify-syntax-entry ?\$ ".")
- (modify-syntax-entry ?\/ ".")
- (modify-syntax-entry ?\\ ".")
- (modify-syntax-entry ?+ ".")
- (modify-syntax-entry ?- ".")
- (modify-syntax-entry ?= ".")
- (modify-syntax-entry ?% ".")
- (modify-syntax-entry ?< ".")
- (modify-syntax-entry ?> ".")
- (modify-syntax-entry ?\& ".")
- (modify-syntax-entry ?_ "_")
- (modify-syntax-entry ?\' "_")
- (modify-syntax-entry ?\| ".")
-
-;; should maybe be "_" but it makes coq-find-and-forget (in gallina.el) bug
- (modify-syntax-entry ?\. ".")
-
- (condition-case nil
- ;; Try to use Emacs-21's nested comments.
- (modify-syntax-entry ?\* ". 23n")
- ;; Revert to non-nested comments if that failed.
- (error (modify-syntax-entry ?\* ". 23")))
- (modify-syntax-entry ?\( "()1")
- (modify-syntax-entry ?\) ")(4"))
-
-
-(defconst coq-generic-expression
- (mapcar (lambda (kw)
- (list (capitalize kw)
- (concat "\\<" kw "\\>" "\\s-+\\(\\w+\\)\\W" )
- 1))
- (append coq-keywords-decl coq-keywords-defn coq-keywords-goal)))
-
-(provide 'gallina-syntax)
- ;;; gallina-syntax.el ends here
-
-; Local Variables: ***
-; indent-tabs-mode: nil ***
-; End: ***
diff --git a/tools/gallina.el b/tools/gallina.el
deleted file mode 100644
index cbc13118..00000000
--- a/tools/gallina.el
+++ /dev/null
@@ -1,142 +0,0 @@
-;; gallina.el --- Coq mode editing commands for Emacs
-;;
-;; Jean-Christophe Filliatre, march 1995
-;; Shamelessly copied from caml.el, Xavier Leroy, july 1993.
-;;
-;; modified by Marco Maggesi <maggesi@math.unifi.it> for gallina-inferior
-
-; compatibility code for proofgeneral files
-(require 'coq-font-lock)
-; ProofGeneral files. remember to remove coq version tests in
-; gallina-syntax.el
-(require 'gallina-syntax)
-
-(defvar coq-mode-map nil
- "Keymap used in Coq mode.")
-(if coq-mode-map
- ()
- (setq coq-mode-map (make-sparse-keymap))
- (define-key coq-mode-map "\t" 'coq-indent-command)
- (define-key coq-mode-map "\M-\t" 'coq-unindent-command)
- (define-key coq-mode-map "\C-c\C-c" 'compile)
-)
-
-(defvar coq-mode-syntax-table nil
- "Syntax table in use in Coq mode buffers.")
-(if coq-mode-syntax-table
- ()
- (setq coq-mode-syntax-table (make-syntax-table))
- ; ( is first character of comment start
- (modify-syntax-entry ?\( "()1" coq-mode-syntax-table)
- ; * is second character of comment start,
- ; and first character of comment end
- (modify-syntax-entry ?* ". 23" coq-mode-syntax-table)
- ; ) is last character of comment end
- (modify-syntax-entry ?\) ")(4" coq-mode-syntax-table)
- ; quote is a string-like delimiter (for character literals)
- (modify-syntax-entry ?' "\"" coq-mode-syntax-table)
- ; quote is part of words
- (modify-syntax-entry ?' "w" coq-mode-syntax-table)
-)
-
-(defvar coq-mode-indentation 2
- "*Indentation for each extra tab in Coq mode.")
-
-(defun coq-mode-variables ()
- (set-syntax-table coq-mode-syntax-table)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start (concat "^$\\|" page-delimiter))
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'paragraph-ignore-fill-prefix)
- (setq paragraph-ignore-fill-prefix t)
- (make-local-variable 'require-final-newline)
- (setq require-final-newline t)
- (make-local-variable 'comment-start)
- (setq comment-start "(* ")
- (make-local-variable 'comment-end)
- (setq comment-end " *)")
- (make-local-variable 'comment-column)
- (setq comment-column 40)
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "(\\*+ *")
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments nil)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'coq-indent-command)
- (make-local-variable 'font-lock-keywords)
- (setq font-lock-defaults '(coq-font-lock-keywords-1)))
-
-;;; The major mode
-
-(defun coq-mode ()
- "Major mode for editing Coq code.
-Tab at the beginning of a line indents this line like the line above.
-Extra tabs increase the indentation level.
-\\{coq-mode-map}
-The variable coq-mode-indentation indicates how many spaces are
-inserted for each indentation level."
- (interactive)
- (kill-all-local-variables)
- (setq major-mode 'coq-mode)
- (setq mode-name "coq")
- (use-local-map coq-mode-map)
- (coq-mode-variables)
- (run-hooks 'coq-mode-hook))
-
-;;; Indentation stuff
-
-(defun coq-in-indentation ()
- "Tests whether all characters between beginning of line and point
-are blanks."
- (save-excursion
- (skip-chars-backward " \t")
- (bolp)))
-
-(defun coq-indent-command ()
- "Indent the current line in Coq mode.
-When the point is at the beginning of an empty line, indent this line like
-the line above.
-When the point is at the beginning of an indented line
-\(i.e. all characters between beginning of line and point are blanks\),
-increase the indentation by one level.
-The indentation size is given by the variable coq-mode-indentation.
-In all other cases, insert a tabulation (using insert-tab)."
- (interactive)
- (let* ((begline
- (save-excursion
- (beginning-of-line)
- (point)))
- (current-offset
- (- (point) begline))
- (previous-indentation
- (save-excursion
- (if (eq (forward-line -1) 0) (current-indentation) 0))))
- (cond ((and (bolp)
- (looking-at "[ \t]*$")
- (> previous-indentation 0))
- (indent-to previous-indentation))
- ((coq-in-indentation)
- (indent-to (+ current-offset coq-mode-indentation)))
- (t
- (insert-tab)))))
-
-(defun coq-unindent-command ()
- "Decrease indentation by one level in Coq mode.
-Works only if the point is at the beginning of an indented line
-\(i.e. all characters between beginning of line and point are blanks\).
-Does nothing otherwise."
- (interactive)
- (let* ((begline
- (save-excursion
- (beginning-of-line)
- (point)))
- (current-offset
- (- (point) begline)))
- (if (and (>= current-offset coq-mode-indentation)
- (coq-in-indentation))
- (backward-delete-char-untabify coq-mode-indentation))))
-
-;;; gallina.el ends here
-
-(provide 'gallina)
diff --git a/tools/gallina.ml b/tools/gallina.ml
deleted file mode 100644
index c7ff76be..00000000
--- a/tools/gallina.ml
+++ /dev/null
@@ -1,63 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-open Gallina_lexer
-
-let vfiles = ref ([] : string list)
-
-let option_moins = ref false
-
-let option_stdout = ref false
-
-let traite_fichier f =
- try
- let chan_in = open_in (f^".v") in
- let buf = Lexing.from_channel chan_in in
- if not !option_stdout then chan_out := open_out (f ^ ".g");
- try
- while true do Gallina_lexer.action buf done
- with Fin_fichier -> begin
- flush !chan_out;
- close_in chan_in;
- if not !option_stdout then close_out !chan_out
- end
- with Sys_error _ ->
- ()
-
-let traite_stdin () =
- try
- let buf = Lexing.from_channel stdin in
- try
- while true do Gallina_lexer.action buf done
- with Fin_fichier ->
- flush !chan_out
- with Sys_error _ ->
- ()
-
-let _ =
- let lg_command = Array.length Sys.argv in
- if lg_command < 2 then begin
- output_string stderr "Usage: gallina [-] [-stdout] file1 file2 ...\n";
- flush stderr;
- exit 1
- end;
- let treat = function
- | "-" -> option_moins := true
- | "-stdout" -> option_stdout := true
- | "-nocomments" -> comments := false
- | f ->
- if Filename.check_suffix f ".v" then
- vfiles := (Filename.chop_suffix f ".v") :: !vfiles
- in
- Array.iter treat Sys.argv;
- if !option_moins then
- traite_stdin ()
- else
- List.iter traite_fichier !vfiles
diff --git a/tools/gallina_lexer.mll b/tools/gallina_lexer.mll
deleted file mode 100644
index 1a594aeb..00000000
--- a/tools/gallina_lexer.mll
+++ /dev/null
@@ -1,126 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-{
-
- let chan_out = ref stdout
-
- let comment_depth = ref 0
- let cRcpt = ref 0
- let comments = ref true
- let print s = output_string !chan_out s
-
- exception Fin_fichier
-
-}
-
-let space = [' ' '\t' '\n' '\r']
-let enddot = '.' (' ' | '\t' | '\n' | '\r' | eof)
-
-rule action = parse
- | "Theorem" space { print "Theorem "; body lexbuf;
- cRcpt := 1; action lexbuf }
- | "Lemma" space { print "Lemma "; body lexbuf;
- cRcpt := 1; action lexbuf }
- | "Fact" space { print "Fact "; body lexbuf;
- cRcpt := 1; action lexbuf }
- | "Remark" space { print "Remark "; body lexbuf;
- cRcpt := 1; action lexbuf }
- | "Goal" space { print "Goal "; body lexbuf;
- cRcpt := 1; action lexbuf }
- | "Correctness" space { print "Correctness "; body_pgm lexbuf;
- cRcpt := 1; action lexbuf }
- | "Definition" space { print "Definition "; body_def lexbuf;
- cRcpt := 1; action lexbuf }
- | "Hint" space { skip_until_point lexbuf ; action lexbuf }
- | "Hints" space { skip_until_point lexbuf ; action lexbuf }
- | "Transparent" space { skip_until_point lexbuf ; action lexbuf }
- | "Immediate" space { skip_until_point lexbuf ; action lexbuf }
- | "Syntax" space { skip_until_point lexbuf ; action lexbuf }
- | "(*" { (if !comments then print "(*");
- comment_depth := 1;
- comment lexbuf;
- cRcpt := 0; action lexbuf }
- | [' ' '\t']* '\n' { if !cRcpt < 2 then print "\n";
- cRcpt := !cRcpt+1; action lexbuf}
- | eof { (raise Fin_fichier : unit)}
- | _ { print (Lexing.lexeme lexbuf); cRcpt := 0; action lexbuf }
-
-and comment = parse
- | "(*" { (if !comments then print "(*");
- comment_depth := succ !comment_depth; comment lexbuf }
- | "*)" { (if !comments then print "*)");
- comment_depth := pred !comment_depth;
- if !comment_depth > 0 then comment lexbuf }
- | "*)" [' ''\t']*'\n' { (if !comments then print (Lexing.lexeme lexbuf));
- comment_depth := pred !comment_depth;
- if !comment_depth > 0 then comment lexbuf }
- | eof { raise Fin_fichier }
- | _ { (if !comments then print (Lexing.lexeme lexbuf));
- comment lexbuf }
-
-and skip_comment = parse
- | "(*" { comment_depth := succ !comment_depth; skip_comment lexbuf }
- | "*)" { comment_depth := pred !comment_depth;
- if !comment_depth > 0 then skip_comment lexbuf }
- | eof { raise Fin_fichier }
- | _ { skip_comment lexbuf }
-
-and body_def = parse
- | [^'.']* ":=" { print (Lexing.lexeme lexbuf); () }
- | _ { print (Lexing.lexeme lexbuf); body lexbuf }
-
-and body = parse
- | enddot { print ".\n"; skip_proof lexbuf }
- | ":=" { print ".\n"; skip_proof lexbuf }
- | "(*" { print "(*"; comment_depth := 1;
- comment lexbuf; body lexbuf }
- | eof { raise Fin_fichier }
- | _ { print (Lexing.lexeme lexbuf); body lexbuf }
-
-and body_pgm = parse
- | enddot { print ".\n"; skip_proof lexbuf }
- | "(*" { print "(*"; comment_depth := 1;
- comment lexbuf; body_pgm lexbuf }
- | eof { raise Fin_fichier }
- | _ { print (Lexing.lexeme lexbuf); body_pgm lexbuf }
-
-and skip_until_point = parse
- | '.' '\n' { () }
- | enddot { end_of_line lexbuf }
- | "(*" { comment_depth := 1;
- skip_comment lexbuf; skip_until_point lexbuf }
- | eof { raise Fin_fichier }
- | _ { skip_until_point lexbuf }
-
-and end_of_line = parse
- | [' ' '\t' ]* { end_of_line lexbuf }
- | '\n' { () }
- | eof { raise Fin_fichier }
- | _ { print (Lexing.lexeme lexbuf) }
-
-and skip_proof = parse
- | "Save" space
- { skip_until_point lexbuf }
- | "Qed." { end_of_line lexbuf }
- | "Qed" space
- { skip_until_point lexbuf }
- | "Defined." { end_of_line lexbuf }
- | "Defined" space
- { skip_until_point lexbuf }
- | "Abort." { end_of_line lexbuf }
- | "Abort" space
- { skip_until_point lexbuf }
- | "Proof" space { skip_until_point lexbuf }
- | "Proof" [' ' '\t']* '.' { skip_proof lexbuf }
- | "(*" { comment_depth := 1;
- skip_comment lexbuf; skip_proof lexbuf }
- | eof { raise Fin_fichier }
- | _ { skip_proof lexbuf }
diff --git a/tools/inferior-coq.el b/tools/inferior-coq.el
deleted file mode 100644
index 453bd139..00000000
--- a/tools/inferior-coq.el
+++ /dev/null
@@ -1,324 +0,0 @@
-;;; inferior-coq.el --- Run an inferior Coq process.
-;;;
-;;; Copyright (C) Marco Maggesi <maggesi@math.unifi.it>
-;;; Time-stamp: "2002-02-28 12:15:04 maggesi"
-
-
-;; Emacs Lisp Archive Entry
-;; Filename: inferior-coq.el
-;; Version: 1.0
-;; Keywords: process coq
-;; Author: Marco Maggesi <maggesi@math.unifi.it>
-;; Maintainer: Marco Maggesi <maggesi@math.unifi.it>
-;; Description: Run an inferior Coq process.
-;; URL: http://www.math.unifi.it/~maggesi/
-;; Compatibility: Emacs20, Emacs21, XEmacs21
-
-;; This is free software; you can redistribute it and/or modify it under
-;; the terms of the GNU General Public License as published by the Free
-;; Software Foundation; either version 2, or (at your option) any later
-;; version.
-;;
-;; This is distributed in the hope that it will be useful, but WITHOUT
-;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-;; for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-;; MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; Coq is a proof assistant (http://coq.inria.fr/). This code run an
-;; inferior Coq process and defines functions to send bits of code
-;; from other buffers to the inferior process. This is a
-;; customisation of comint-mode (see comint.el). For a more complex
-;; and full featured Coq interface under Emacs look at Proof General
-;; (http://zermelo.dcs.ed.ac.uk/~proofgen/).
-;;
-;; Written by Marco Maggesi <maggesi@math.unifi.it> with code heavly
-;; borrowed from emacs cmuscheme.el
-;;
-;; Please send me bug reports, bug fixes, and extensions, so that I can
-;; merge them into the master source.
-
-;;; Installation:
-
-;; You need to have gallina.el already installed (it comes with the
-;; standard Coq distribution) in order to use this code. Put this
-;; file somewhere in you load-path and add the following lines in your
-;; "~/.emacs":
-;;
-;; (setq auto-mode-alist (cons '("\\.v$" . coq-mode) auto-mode-alist))
-;; (autoload 'coq-mode "gallina" "Major mode for editing Coq vernacular." t)
-;; (autoload 'run-coq "inferior-coq" "Run an inferior Coq process." t)
-;; (autoload 'run-coq-other-window "inferior-coq"
-;; "Run an inferior Coq process in a new window." t)
-;; (autoload 'run-coq-other-frame "inferior-coq"
-;; "Run an inferior Coq process in a new frame." t)
-
-;;; Usage:
-
-;; Call `M-x "run-coq'.
-;;
-;; Functions and key bindings (Learn more keys with `C-c C-h' or `C-h m'):
-;; C-return ('M-x coq-send-line) send the current line.
-;; C-c C-r (`M-x coq-send-region') send the current region.
-;; C-c C-a (`M-x coq-send-abort') send the command "Abort".
-;; C-c C-t (`M-x coq-send-restart') send the command "Restart".
-;; C-c C-s (`M-x coq-send-show') send the command "Show".
-;; C-c C-u (`M-x coq-send-undo') send the command "Undo".
-;; C-c C-v (`M-x coq-check-region') run command "Check" on region.
-;; C-c . (`M-x coq-come-here') Restart and send until current point.
-
-;;; Change Log:
-
-;; From -0.0 to 1.0 brought into existence.
-
-
-(require 'gallina)
-(require 'comint)
-
-(setq coq-program-name "coqtop")
-
-(defgroup inferior-coq nil
- "Run a coq process in a buffer."
- :group 'coq)
-
-(defcustom inferior-coq-mode-hook nil
- "*Hook for customising inferior-coq mode."
- :type 'hook
- :group 'coq)
-
-(defvar inferior-coq-mode-map
- (let ((m (make-sparse-keymap)))
- (define-key m "\C-c\C-r" 'coq-send-region)
- (define-key m "\C-c\C-a" 'coq-send-abort)
- (define-key m "\C-c\C-t" 'coq-send-restart)
- (define-key m "\C-c\C-s" 'coq-send-show)
- (define-key m "\C-c\C-u" 'coq-send-undo)
- (define-key m "\C-c\C-v" 'coq-check-region)
- m))
-
-;; Install the process communication commands in the coq-mode keymap.
-(define-key coq-mode-map [(control return)] 'coq-send-line)
-(define-key coq-mode-map "\C-c\C-r" 'coq-send-region)
-(define-key coq-mode-map "\C-c\C-a" 'coq-send-abort)
-(define-key coq-mode-map "\C-c\C-t" 'coq-send-restart)
-(define-key coq-mode-map "\C-c\C-s" 'coq-send-show)
-(define-key coq-mode-map "\C-c\C-u" 'coq-send-undo)
-(define-key coq-mode-map "\C-c\C-v" 'coq-check-region)
-(define-key coq-mode-map "\C-c." 'coq-come-here)
-
-(defvar coq-buffer)
-
-(define-derived-mode inferior-coq-mode comint-mode "Inferior Coq"
- "\
-Major mode for interacting with an inferior Coq process.
-
-The following commands are available:
-\\{inferior-coq-mode-map}
-
-A Coq process can be fired up with M-x run-coq.
-
-Customisation: Entry to this mode runs the hooks on comint-mode-hook
-and inferior-coq-mode-hook (in that order).
-
-You can send text to the inferior Coq process from other buffers
-containing Coq source.
-
-Functions and key bindings (Learn more keys with `C-c C-h'):
- C-return ('M-x coq-send-line) send the current line.
- C-c C-r (`M-x coq-send-region') send the current region.
- C-c C-a (`M-x coq-send-abort') send the command \"Abort\".
- C-c C-t (`M-x coq-send-restart') send the command \"Restart\".
- C-c C-s (`M-x coq-send-show') send the command \"Show\".
- C-c C-u (`M-x coq-send-undo') send the command \"Undo\".
- C-c C-v (`M-x coq-check-region') run command \"Check\" on region.
- C-c . (`M-x coq-come-here') Restart and send until current point.
-"
- ;; Customise in inferior-coq-mode-hook
- (setq comint-prompt-regexp "^[^<]* < *")
- (coq-mode-variables)
- (setq mode-line-process '(":%s"))
- (setq comint-input-filter (function coq-input-filter))
- (setq comint-get-old-input (function coq-get-old-input)))
-
-(defcustom inferior-coq-filter-regexp "\\`\\s *\\S ?\\S ?\\s *\\'"
- "*Input matching this regexp are not saved on the history list.
-Defaults to a regexp ignoring all inputs of 0, 1, or 2 letters."
- :type 'regexp
- :group 'inferior-coq)
-
-(defun coq-input-filter (str)
- "Don't save anything matching `inferior-coq-filter-regexp'."
- (not (string-match inferior-coq-filter-regexp str)))
-
-(defun coq-get-old-input ()
- "Snarf the sexp ending at point."
- (save-excursion
- (let ((end (point)))
- (backward-sexp)
- (buffer-substring (point) end))))
-
-(defun coq-args-to-list (string)
- (let ((where (string-match "[ \t]" string)))
- (cond ((null where) (list string))
- ((not (= where 0))
- (cons (substring string 0 where)
- (coq-args-to-list (substring string (+ 1 where)
- (length string)))))
- (t (let ((pos (string-match "[^ \t]" string)))
- (if (null pos)
- nil
- (coq-args-to-list (substring string pos
- (length string)))))))))
-
-;;;###autoload
-(defun run-coq (cmd)
- "Run an inferior Coq process, input and output via buffer *coq*.
-If there is a process already running in `*coq*', switch to that buffer.
-With argument, allows you to edit the command line (default is value
-of `coq-program-name'). Runs the hooks `inferior-coq-mode-hook'
-\(after the `comint-mode-hook' is run).
-\(Type \\[describe-mode] in the process buffer for a list of commands.)"
-
- (interactive (list (if current-prefix-arg
- (read-string "Run Coq: " coq-program-name)
- coq-program-name)))
- (if (not (comint-check-proc "*coq*"))
- (let ((cmdlist (coq-args-to-list cmd)))
- (set-buffer (apply 'make-comint "coq" (car cmdlist)
- nil (cdr cmdlist)))
- (inferior-coq-mode)))
- (setq coq-program-name cmd)
- (setq coq-buffer "*coq*")
- (switch-to-buffer "*coq*"))
-;;;###autoload (add-hook 'same-window-buffer-names "*coq*")
-
-;;;###autoload
-(defun run-coq-other-window (cmd)
- "Run an inferior Coq process, input and output via buffer *coq*.
-If there is a process already running in `*coq*', switch to that buffer.
-With argument, allows you to edit the command line (default is value
-of `coq-program-name'). Runs the hooks `inferior-coq-mode-hook'
-\(after the `comint-mode-hook' is run).
-\(Type \\[describe-mode] in the process buffer for a list of commands.)"
-
- (interactive (list (if current-prefix-arg
- (read-string "Run Coq: " coq-program-name)
- coq-program-name)))
- (if (not (comint-check-proc "*coq*"))
- (let ((cmdlist (coq-args-to-list cmd)))
- (set-buffer (apply 'make-comint "coq" (car cmdlist)
- nil (cdr cmdlist)))
- (inferior-coq-mode)))
- (setq coq-program-name cmd)
- (setq coq-buffer "*coq*")
- (pop-to-buffer "*coq*"))
-;;;###autoload (add-hook 'same-window-buffer-names "*coq*")
-
-(defun run-coq-other-frame (cmd)
- "Run an inferior Coq process, input and output via buffer *coq*.
-If there is a process already running in `*coq*', switch to that buffer.
-With argument, allows you to edit the command line (default is value
-of `coq-program-name'). Runs the hooks `inferior-coq-mode-hook'
-\(after the `comint-mode-hook' is run).
-\(Type \\[describe-mode] in the process buffer for a list of commands.)"
-
- (interactive (list (if current-prefix-arg
- (read-string "Run Coq: " coq-program-name)
- coq-program-name)))
- (if (not (comint-check-proc "*coq*"))
- (let ((cmdlist (coq-args-to-list cmd)))
- (set-buffer (apply 'make-comint "coq" (car cmdlist)
- nil (cdr cmdlist)))
- (inferior-coq-mode)))
- (setq coq-program-name cmd)
- (setq coq-buffer "*coq*")
- (switch-to-buffer-other-frame "*coq*"))
-
-(defun switch-to-coq (eob-p)
- "Switch to the coq process buffer.
-With argument, position cursor at end of buffer."
- (interactive "P")
- (if (get-buffer coq-buffer)
- (pop-to-buffer coq-buffer)
- (error "No current process buffer. See variable `coq-buffer'"))
- (cond (eob-p
- (push-mark)
- (goto-char (point-max)))))
-
-(defun coq-send-region (start end)
- "Send the current region to the inferior Coq process."
- (interactive "r")
- (comint-send-region (coq-proc) start end)
- (comint-send-string (coq-proc) "\n"))
-
-(defun coq-send-line ()
- "Send the current line to the Coq process."
- (interactive)
- (save-excursion
- (end-of-line)
- (let ((end (point)))
- (beginning-of-line)
- (coq-send-region (point) end)))
- (forward-line 1))
-
-(defun coq-send-abort ()
- "Send the command \"Abort.\" to the inferior Coq process."
- (interactive)
- (comint-send-string (coq-proc) "Abort.\n"))
-
-(defun coq-send-restart ()
- "Send the command \"Restart.\" to the inferior Coq process."
- (interactive)
- (comint-send-string (coq-proc) "Restart.\n"))
-
-(defun coq-send-undo ()
- "Reset coq to the initial state and send the region between the
- beginning of file and the point."
- (interactive)
- (comint-send-string (coq-proc) "Undo.\n"))
-
-(defun coq-check-region (start end)
- "Run the commmand \"Check\" on the current region."
- (interactive "r")
- (comint-proc-query (coq-proc)
- (concat "Check "
- (buffer-substring start end)
- ".\n")))
-
-(defun coq-send-show ()
- "Send the command \"Show.\" to the inferior Coq process."
- (interactive)
- (comint-send-string (coq-proc) "Show.\n"))
-
-(defun coq-come-here ()
- "Reset coq to the initial state and send the region between the
- beginning of file and the point."
- (interactive)
- (comint-send-string (coq-proc) "Reset Initial.\n")
- (coq-send-region 1 (point)))
-
-(defvar coq-buffer nil "*The current coq process buffer.")
-
-(defun coq-proc ()
- "Return the current coq process. See variable `coq-buffer'."
- (let ((proc (get-buffer-process (if (eq major-mode 'inferior-coq-mode)
- (current-buffer)
- coq-buffer))))
- (or proc
- (error "No current process. See variable `coq-buffer'"))))
-
-(defcustom inferior-coq-load-hook nil
- "This hook is run when inferior-coq is loaded in.
-This is a good place to put keybindings."
- :type 'hook
- :group 'inferior-coq)
-
-(run-hooks 'inferior-coq-load-hook)
-
-(provide 'inferior-coq)
diff --git a/stm/proofworkertop.ml b/topbin/coqproofworker_bin.ml
index 4b85a05a..7ae91cfb 100644
--- a/stm/proofworkertop.ml
+++ b/topbin/coqproofworker_bin.ml
@@ -10,7 +10,5 @@
module W = AsyncTaskQueue.MakeWorker(Stm.ProofTask) ()
-let () = Coqtop.toploop_init := WorkerLoop.loop W.init_stdout
-
-let () = Coqtop.toploop_run := (fun _ ~state:_ -> W.main_loop ())
-
+let () =
+ WorkerLoop.start ~init:W.init_stdout ~loop:W.main_loop
diff --git a/stm/queryworkertop.ml b/topbin/coqqueryworker_bin.ml
index aa00102a..98c85812 100644
--- a/stm/queryworkertop.ml
+++ b/topbin/coqqueryworker_bin.ml
@@ -10,7 +10,4 @@
module W = AsyncTaskQueue.MakeWorker(Stm.QueryTask) ()
-let () = Coqtop.toploop_init := WorkerLoop.loop W.init_stdout
-
-let () = Coqtop.toploop_run := (fun _ ~state:_ -> W.main_loop ())
-
+let () = WorkerLoop.start ~init:W.init_stdout ~loop:W.main_loop
diff --git a/stm/tacworkertop.ml b/topbin/coqtacticworker_bin.ml
index 3b91df86..2634baa8 100644
--- a/stm/tacworkertop.ml
+++ b/topbin/coqtacticworker_bin.ml
@@ -10,7 +10,4 @@
module W = AsyncTaskQueue.MakeWorker(Stm.TacTask) ()
-let () = Coqtop.toploop_init := WorkerLoop.loop W.init_stdout
-
-let () = Coqtop.toploop_run := (fun _ ~state:_ -> W.main_loop ())
-
+let () = WorkerLoop.start ~init:W.init_stdout ~loop:W.main_loop
diff --git a/toplevel/coqtop_opt_bin.ml b/topbin/coqtop_bin.ml
index ea4c0ea5..4490db59 100644
--- a/toplevel/coqtop_opt_bin.ml
+++ b/topbin/coqtop_bin.ml
@@ -13,4 +13,4 @@ let drop_setup () = Mltop.remove ()
(* Main coqtop initialization *)
let _ =
drop_setup ();
- Coqtop.start()
+ Coqtop.(start_coq coqtop_toplevel)
diff --git a/toplevel/coqtop_byte_bin.ml b/topbin/coqtop_byte_bin.ml
index 0b65cebb..abe39783 100644
--- a/toplevel/coqtop_byte_bin.ml
+++ b/topbin/coqtop_byte_bin.ml
@@ -31,4 +31,4 @@ let drop_setup () =
(* Main coqtop initialization *)
let _ =
drop_setup ();
- Coqtop.start()
+ Coqtop.(start_coq coqtop_toplevel)
diff --git a/toplevel/coqargs.ml b/toplevel/coqargs.ml
index eacd1dcf..01056b6a 100644
--- a/toplevel/coqargs.ml
+++ b/toplevel/coqargs.ml
@@ -10,8 +10,8 @@
let warning s = Flags.(with_option warn Feedback.msg_warning (Pp.strbrk s))
-let fatal_error ?extra exn =
- Topfmt.print_err_exn ?extra exn;
+let fatal_error exn =
+ Topfmt.print_err_exn Topfmt.ParsingCommandLine exn;
let exit_code = if CErrors.(is_anomaly exn || not (handled exn)) then 129 else 1 in
exit exit_code
@@ -52,7 +52,6 @@ type coq_cmdopts = {
compilation_mode : compilation_mode;
toplevel_name : Names.DirPath.t;
- toploop : string option;
compile_list: (string * bool) list; (* bool is verbosity *)
compilation_output_name : string option;
@@ -69,6 +68,7 @@ type coq_cmdopts = {
impredicative_set : Declarations.set_predicativity;
stm_flags : Stm.AsyncOpts.stm_opt;
debug : bool;
+ diffs_set : bool;
time : bool;
filter_opts : bool;
@@ -81,6 +81,8 @@ type coq_cmdopts = {
print_config: bool;
output_context : bool;
+ print_emacs : bool;
+
inputstate : string option;
outputstate : string option;
@@ -100,7 +102,6 @@ let init_args = {
compilation_mode = BuildVo;
toplevel_name = Names.(DirPath.make [Id.of_string "Top"]);
- toploop = None;
compile_list = [];
compilation_output_name = None;
@@ -117,6 +118,7 @@ let init_args = {
impredicative_set = Declarations.PredicativeSet;
stm_flags = Stm.AsyncOpts.default_opts;
debug = false;
+ diffs_set = false;
time = false;
filter_opts = false;
@@ -129,6 +131,8 @@ let init_args = {
print_config = false;
output_context = false;
+ print_emacs = false;
+
inputstate = None;
outputstate = None;
}
@@ -148,9 +152,9 @@ let add_vo_require opts d p export =
let add_compat_require opts v =
match v with
- | Flags.V8_6 -> add_vo_require opts "Coq.Compat.Coq86" None (Some false)
| Flags.V8_7 -> add_vo_require opts "Coq.Compat.Coq87" None (Some false)
- | Flags.Current -> add_vo_require opts "Coq.Compat.Coq88" None (Some false)
+ | Flags.V8_8 -> add_vo_require opts "Coq.Compat.Coq88" None (Some false)
+ | Flags.Current -> add_vo_require opts "Coq.Compat.Coq89" None (Some false)
let set_batch_mode opts =
Flags.quiet := true;
@@ -191,11 +195,8 @@ let set_vio_checking_j opts opt j =
(** Options for proof general *)
let set_emacs opts =
- if not (Option.is_empty opts.toploop) then
- CErrors.user_err Pp.(str "Flag -emacs is incompatible with a custom toplevel loop");
- Coqloop.print_emacs := true;
Printer.enable_goal_tags_printing := true;
- { opts with color = `OFF }
+ { opts with color = `OFF; print_emacs = true }
let set_color opts = function
| "yes" | "on" -> { opts with color = `ON }
@@ -310,12 +311,9 @@ let usage batch =
let lp = Coqinit.toplevel_init_load_path () in
(* Necessary for finding the toplevels below *)
List.iter Mltop.add_coq_path lp;
- if batch then Usage.print_usage_coqc ()
- else begin
- Mltop.load_ml_objects_raw_rex
- (Str.regexp (if Mltop.is_native then "^.*top.cmxs$" else "^.*top.cma$"));
- Usage.print_usage_coqtop ()
- end
+ if batch
+ then Usage.print_usage_coqc ()
+ else Usage.print_usage_coqtop ()
(* Main parsing routine *)
let parse_args arglist : coq_cmdopts * string list =
@@ -401,7 +399,7 @@ let parse_args arglist : coq_cmdopts * string list =
}}
|"-async-proofs-worker-priority" ->
- WorkerLoop.async_proofs_worker_priority := get_priority opt (next ());
+ CoqworkmgrApi.async_proofs_worker_priority := get_priority opt (next ());
oval
|"-async-proofs-private-flags" ->
@@ -427,7 +425,7 @@ let parse_args arglist : coq_cmdopts * string list =
|"-worker-id" -> set_worker_id opt (next ()); oval
|"-compat" ->
- let v = G_vernac.parse_compat_version ~allow_old:false (next ()) in
+ let v = G_vernac.parse_compat_version (next ()) in
Flags.compat_version := v;
add_compat_require oval v
@@ -500,11 +498,6 @@ let parse_args arglist : coq_cmdopts * string list =
let oval = add_compile oval false (next ()) in
{ oval with compilation_mode = Vio2Vo }
- |"-toploop" ->
- if !Coqloop.print_emacs then
- CErrors.user_err Pp.(str "Flags -toploop and -emacs are incompatible");
- { oval with toploop = Some (next ()) }
-
|"-w" | "-W" ->
let w = next () in
if w = "none" then
@@ -535,15 +528,15 @@ let parse_args arglist : coq_cmdopts * string list =
|"-color" -> set_color oval (next ())
|"-config"|"--config" -> { oval with print_config = true }
|"-debug" -> Coqinit.set_debug (); oval
+ |"-diffs" -> let opt = next () in
+ if List.exists (fun x -> opt = x) ["off"; "on"; "removed"] then
+ Proof_diffs.write_diffs_option opt
+ else
+ (prerr_endline ("Error: on|off|removed expected after -diffs"); exit 1);
+ { oval with diffs_set = true }
|"-stm-debug" -> Stm.stm_debug := true; oval
|"-emacs" -> set_emacs oval
|"-filteropts" -> { oval with filter_opts = true }
- |"-ideslave" ->
- if !Coqloop.print_emacs then
- CErrors.user_err Pp.(str "Flags -ideslave and -emacs are incompatible");
- Flags.ide_slave := true;
- { oval with toploop = Some "coqidetop" }
-
|"-impredicative-set" ->
{ oval with impredicative_set = Declarations.ImpredicativeSet }
|"-indices-matter" -> Indtypes.enforce_indices_matter (); oval
diff --git a/toplevel/coqargs.mli b/toplevel/coqargs.mli
index de9b6a68..7b0cdcf1 100644
--- a/toplevel/coqargs.mli
+++ b/toplevel/coqargs.mli
@@ -27,7 +27,6 @@ type coq_cmdopts = {
compilation_mode : compilation_mode;
toplevel_name : Names.DirPath.t;
- toploop : string option;
compile_list: (string * bool) list; (* bool is verbosity *)
compilation_output_name : string option;
@@ -44,6 +43,7 @@ type coq_cmdopts = {
impredicative_set : Declarations.set_predicativity;
stm_flags : Stm.AsyncOpts.stm_opt;
debug : bool;
+ diffs_set : bool;
time : bool;
filter_opts : bool;
@@ -56,6 +56,8 @@ type coq_cmdopts = {
print_config: bool;
output_context : bool;
+ print_emacs : bool;
+
inputstate : string option;
outputstate : string option;
diff --git a/toplevel/coqinit.ml b/toplevel/coqinit.ml
index 96a0bd5e..e1d35e53 100644
--- a/toplevel/coqinit.ml
+++ b/toplevel/coqinit.ml
@@ -23,12 +23,12 @@ let set_debug () =
let rcdefaultname = "coqrc"
-let load_rcfile ~rcfile ~time ~state =
+let load_rcfile ~rcfile ~state =
try
match rcfile with
| Some rcfile ->
if CUnix.file_readable_p rcfile then
- Vernac.load_vernac ~time ~echo:false ~interactive:false ~check:true ~state rcfile
+ Vernac.load_vernac ~echo:false ~interactive:false ~check:true ~state rcfile
else raise (Sys_error ("Cannot read rcfile: "^ rcfile))
| None ->
try
@@ -39,7 +39,7 @@ let load_rcfile ~rcfile ~time ~state =
Envars.home ~warn / "."^rcdefaultname^"."^Coq_config.version;
Envars.home ~warn / "."^rcdefaultname
] in
- Vernac.load_vernac ~time ~echo:false ~interactive:false ~check:true ~state inferedrc
+ Vernac.load_vernac ~echo:false ~interactive:false ~check:true ~state inferedrc
with Not_found -> state
(*
Flags.if_verbose
@@ -75,16 +75,12 @@ let ml_path_if c p =
let f x = { recursive = false; path_spec = MlPath x } in
if c then List.map f p else []
-(* LoadPath for toploop toplevels *)
+(* LoadPath for developers *)
let toplevel_init_load_path () =
let coqlib = Envars.coqlib () in
(* NOTE: These directories are searched from last to first *)
(* first, developer specific directory to open *)
- ml_path_if Coq_config.local [coqlib/"dev"] @
-
- (* main loops *)
- ml_path_if (Coq_config.local || !Flags.boot) [coqlib/"stm"; coqlib/"ide"] @
- ml_path_if (System.exists_dir (coqlib/"toploop")) [coqlib/"toploop"]
+ ml_path_if Coq_config.local [coqlib/"dev"]
(* LoadPath for Coq user libraries *)
let libs_init_load_path ~load_init =
@@ -96,6 +92,14 @@ let libs_init_load_path ~load_init =
let coqpath = Envars.coqpath in
let coq_path = Names.DirPath.make [Libnames.coq_root] in
+ (* current directory (not recursively!) *)
+ [ { recursive = false;
+ path_spec = VoPath { unix_path = ".";
+ coq_path = Libnames.default_root_prefix;
+ implicit = false;
+ has_ml = AddTopML }
+ } ] @
+
(* then standard library and plugins *)
[build_stdlib_path ~load_init ~unix_path:(coqlib/"theories") ~coq_path ~with_ml:false;
build_stdlib_path ~load_init ~unix_path:(coqlib/"plugins") ~coq_path ~with_ml:true ] @
@@ -106,15 +110,7 @@ let libs_init_load_path ~load_init =
) @
(* then directories in XDG_DATA_DIRS and XDG_DATA_HOME and COQPATH *)
- List.map (fun s -> build_userlib_path ~unix_path:s) (xdg_dirs @ coqpath) @
-
- (* then current directory (not recursively!) *)
- [ { recursive = false;
- path_spec = VoPath { unix_path = ".";
- coq_path = Libnames.default_root_prefix;
- implicit = false;
- has_ml = AddTopML }
- } ]
+ List.map (fun s -> build_userlib_path ~unix_path:s) (xdg_dirs @ coqpath)
(* Initialises the Ocaml toplevel before launching it, so that it can
find the "include" file in the *source* directory *)
diff --git a/toplevel/coqinit.mli b/toplevel/coqinit.mli
index 71b5523c..c891e736 100644
--- a/toplevel/coqinit.mli
+++ b/toplevel/coqinit.mli
@@ -12,12 +12,12 @@
val set_debug : unit -> unit
-val load_rcfile : rcfile:(string option) -> time:bool -> state:Vernac.State.t -> Vernac.State.t
+val load_rcfile : rcfile:(string option) -> state:Vernac.State.t -> Vernac.State.t
val init_ocaml_path : unit -> unit
(* LoadPath for toploop toplevels *)
-val toplevel_init_load_path : unit -> Mltop.coq_path list
+val toplevel_init_load_path : unit -> Mltop.coq_path list
(* LoadPath for Coq user libraries *)
val libs_init_load_path : load_init:bool -> Mltop.coq_path list
diff --git a/toplevel/coqloop.ml b/toplevel/coqloop.ml
index 3239d360..59a464a2 100644
--- a/toplevel/coqloop.ml
+++ b/toplevel/coqloop.ml
@@ -23,7 +23,7 @@ type input_buffer = {
mutable str : Bytes.t; (* buffer of already read characters *)
mutable len : int; (* number of chars in the buffer *)
mutable bols : int list; (* offsets in str of beginning of lines *)
- mutable tokens : Pcoq.Gram.coq_parsable; (* stream of tokens *)
+ mutable tokens : Pcoq.Parsable.t; (* stream of tokens *)
mutable start : int } (* stream count of the first char of the buffer *)
(* Double the size of the buffer. *)
@@ -76,7 +76,7 @@ let reset_input_buffer doc ic ibuf =
ibuf.str <- Bytes.empty;
ibuf.len <- 0;
ibuf.bols <- [];
- ibuf.tokens <- Pcoq.Gram.parsable (Stream.from (prompt_char doc ic ibuf));
+ ibuf.tokens <- Pcoq.Parsable.make (Stream.from (prompt_char doc ic ibuf));
ibuf.start <- 0
(* Functions to print underlined locations from an input buffer. *)
@@ -150,29 +150,28 @@ let print_highlight_location ib loc =
let valid_buffer_loc ib loc =
let (b,e) = Loc.unloc loc in b-ib.start >= 0 && e-ib.start < ib.len && b<=e
-
(* Toplevel error explanation. *)
-let error_info_for_buffer ?loc buf =
- Option.map (fun loc ->
+let error_info_for_buffer ?loc phase buf =
+ match loc with
+ | None -> Topfmt.pr_phase ?loc phase
+ | Some loc ->
let fname = loc.Loc.fname in
- let hl, loc =
(* We are in the toplevel *)
- match fname with
- | Loc.ToplevelInput ->
- let nloc = adjust_loc_buf buf loc in
- if valid_buffer_loc buf loc then
- (fnl () ++ print_highlight_location buf nloc, nloc)
- (* in the toplevel, but not a valid buffer *)
- else (mt (), nloc)
- (* we are in batch mode, don't adjust location *)
- | Loc.InFile _ ->
- (mt (), loc)
- in Topfmt.pr_loc loc ++ hl
- ) loc
+ match fname with
+ | Loc.ToplevelInput ->
+ let nloc = adjust_loc_buf buf loc in
+ if valid_buffer_loc buf loc then
+ match Topfmt.pr_phase ~loc:nloc phase with
+ | None -> None
+ | Some hd -> Some (hd ++ fnl () ++ print_highlight_location buf nloc)
+ (* in the toplevel, but not a valid buffer *)
+ else Topfmt.pr_phase ~loc phase
+ (* we are in batch mode, don't adjust location *)
+ | Loc.InFile _ -> Topfmt.pr_phase ~loc phase
(* Actual printing routine *)
-let print_error_for_buffer ?loc lvl msg buf =
- let pre_hdr = error_info_for_buffer ?loc buf in
+let print_error_for_buffer ?loc phase lvl msg buf =
+ let pre_hdr = error_info_for_buffer ?loc phase buf in
if !print_emacs
then Topfmt.emacs_logger ?pre_hdr lvl msg
else Topfmt.std_logger ?pre_hdr lvl msg
@@ -229,7 +228,7 @@ let top_buffer =
str = Bytes.empty;
len = 0;
bols = [];
- tokens = Pcoq.Gram.parsable (Stream.of_list []);
+ tokens = Pcoq.Parsable.make (Stream.of_list []);
start = 0 }
let set_prompt prompt =
@@ -254,15 +253,15 @@ let parse_to_dot =
let rec discard_to_dot () =
try
- Pcoq.Gram.entry_parse parse_to_dot top_buffer.tokens
+ Pcoq.Entry.parse parse_to_dot top_buffer.tokens
with
| Token.Error _ | CLexer.Error.E _ -> discard_to_dot ()
| Stm.End_of_input -> raise Stm.End_of_input
| e when CErrors.noncritical e -> ()
let read_sentence ~state input =
- let open Vernac.State in
- try Stm.parse_sentence ~doc:state.doc state.sid input
+ (* XXX: careful with ignoring the state Eugene!*)
+ try G_toplevel.parse_toplevel input
with reraise ->
let reraise = CErrors.push reraise in
discard_to_dot ();
@@ -282,7 +281,7 @@ let extract_default_loc loc doc_id sid : Loc.t option =
with _ -> loc
(** Coqloop Console feedback handler *)
-let coqloop_feed (fb : Feedback.feedback) = let open Feedback in
+let coqloop_feed phase (fb : Feedback.feedback) = let open Feedback in
match fb.contents with
| Processed -> ()
| Incomplete -> ()
@@ -301,43 +300,9 @@ let coqloop_feed (fb : Feedback.feedback) = let open Feedback in
(* TopErr.print_error_for_buffer ?loc lvl msg top_buffer *)
| Message (Warning,loc,msg) ->
let loc = extract_default_loc loc fb.doc_id fb.span_id in
- TopErr.print_error_for_buffer ?loc Warning msg top_buffer
+ TopErr.print_error_for_buffer ?loc phase Warning msg top_buffer
| Message (lvl,loc,msg) ->
- TopErr.print_error_for_buffer ?loc lvl msg top_buffer
-
-(** [do_vernac] reads and executes a toplevel phrase, and print error
- messages when an exception is raised, except for the following:
- - Drop: kill the Coq toplevel, going down to the Caml toplevel if it exists.
- Otherwise, exit.
- - End_of_input: Ctrl-D was typed in, we will quit.
-
- In particular, this is normally the only place where a Sys.Break
- is caught and handled (i.e. not re-raised).
-*)
-
-let do_vernac ~time ~state =
- let open Vernac.State in
- top_stderr (fnl());
- if !print_emacs then top_stderr (str (top_buffer.prompt state.doc));
- resynch_buffer top_buffer;
- try
- let input = (top_buffer.tokens, None) in
- Vernac.process_expr ~time ~state (read_sentence ~state (fst input))
- with
- | Stm.End_of_input | CErrors.Quit ->
- top_stderr (fnl ()); raise CErrors.Quit
- | CErrors.Drop -> (* Last chance *)
- if Mltop.is_ocaml_top() then raise CErrors.Drop
- else (Feedback.msg_warning (str "There is no ML toplevel."); state)
- (* Exception printing should be done by the feedback listener,
- however this is not yet ready so we rely on the exception for
- now. *)
- | any ->
- let (e, info) = CErrors.push any in
- let loc = Loc.get_loc info in
- let msg = CErrors.iprint (e, info) in
- TopErr.print_error_for_buffer ?loc Feedback.Error msg top_buffer;
- state
+ TopErr.print_error_for_buffer ?loc phase lvl msg top_buffer
(** Main coq loop : read vernacular expressions until Drop is entered.
Ctrl-C is handled internally as Sys.Break instead of aborting Coq.
@@ -353,12 +318,6 @@ let loop_flush_all () =
Format.pp_print_flush !Topfmt.std_ft ();
Format.pp_print_flush !Topfmt.err_ft ()
-let pr_open_cur_subgoals () =
- try
- let proof = Proof_global.give_me_the_proof () in
- Printer.pr_open_subgoals ~proof
- with Proof_global.NoCurrentProof -> Pp.str ""
-
(* Goal equality heuristic. *)
let pequal cmp1 cmp2 (a1,a2) (b1,b2) = cmp1 a1 b1 && cmp2 a2 b2
let evleq e1 e2 = CList.equal Evar.equal e1 e2
@@ -369,53 +328,117 @@ let cproof p1 p2 =
CList.equal Evar.equal a3 b3 &&
CList.equal Evar.equal a4 b4
+let drop_last_doc = ref None
+
+(* todo: could add other Set/Unset commands, such as "Printing Universes" *)
+let print_anyway_opts = [
+ [ "Diffs" ];
+ ]
+
+let print_anyway c =
+ let open Vernacexpr in
+ match c with
+ | VernacExpr (_, VernacSetOption (_, opt, _))
+ | VernacExpr (_, VernacUnsetOption (_, opt)) ->
+ List.mem opt print_anyway_opts
+ | _ -> false
+
(* We try to behave better when goal printing raises an exception
[usually Ctrl-C]
This is mostly a hack as we should protect printing in a more
generic way, but that'll do for now *)
-let top_goal_print oldp newp =
+let top_goal_print ~doc c oldp newp =
try
let proof_changed = not (Option.equal cproof oldp newp) in
- let print_goals = not !Flags.quiet &&
- proof_changed && Proof_global.there_are_pending_proofs () in
- if print_goals then Feedback.msg_notice (pr_open_cur_subgoals ())
+ let print_goals = proof_changed && Proof_global.there_are_pending_proofs () ||
+ print_anyway c in
+ if not !Flags.quiet && print_goals then begin
+ let dproof = Stm.get_prev_proof ~doc (Stm.get_current_state ~doc) in
+ Printer.print_and_diff dproof newp
+ end
with
- | CErrors.Drop | CErrors.Quit as exn -> raise exn
| exn ->
let (e, info) = CErrors.push exn in
let loc = Loc.get_loc info in
let msg = CErrors.iprint (e, info) in
- TopErr.print_error_for_buffer ?loc Feedback.Error msg top_buffer
+ TopErr.print_error_for_buffer ?loc Topfmt.InteractiveLoop Feedback.Error msg top_buffer
-let drop_last_doc = ref None
+(* Careful to keep this loop tail-rec *)
+let rec vernac_loop ~state =
+ let open CAst in
+ let open Vernac.State in
+ let open G_toplevel in
+ loop_flush_all ();
+ top_stderr (fnl());
+ if !print_emacs then top_stderr (str (top_buffer.prompt state.doc));
+ resynch_buffer top_buffer;
+ (* execute one command *)
+ try
+ let input = top_buffer.tokens in
+ match read_sentence ~state input with
+ | {v=VernacBacktrack(bid,_,_)} ->
+ let bid = Stateid.of_int bid in
+ let doc, res = Stm.edit_at ~doc:state.doc bid in
+ assert (res = `NewTip);
+ let state = { state with doc; sid = bid } in
+ vernac_loop ~state
+
+ | {v=VernacQuit} ->
+ exit 0
+ | {v=VernacDrop} ->
+ if Mltop.is_ocaml_top()
+ then (drop_last_doc := Some state; state)
+ else (Feedback.msg_warning (str "There is no ML toplevel."); vernac_loop ~state)
+ | {v=VernacControl c; loc} ->
+ let nstate = Vernac.process_expr ~state (make ?loc c) in
+ top_goal_print ~doc:state.doc c state.proof nstate.proof;
+ vernac_loop ~state:nstate
+ with
+ | Stm.End_of_input ->
+ top_stderr (fnl ()); exit 0
+ (* Exception printing should be done by the feedback listener,
+ however this is not yet ready so we rely on the exception for
+ now. *)
+ | any ->
+ let (e, info) = CErrors.push any in
+ let loc = Loc.get_loc info in
+ let msg = CErrors.iprint (e, info) in
+ TopErr.print_error_for_buffer ?loc Topfmt.InteractiveLoop Feedback.Error msg top_buffer;
+ vernac_loop ~state
-let rec loop ~time ~state =
+let rec loop ~state =
let open Vernac.State in
Sys.catch_break true;
try
reset_input_buffer state.doc stdin top_buffer;
- (* Be careful to keep this loop tail-recursive *)
- let rec vernac_loop ~state =
- let nstate = do_vernac ~time ~state in
- top_goal_print state.proof nstate.proof;
- loop_flush_all ();
- vernac_loop ~state:nstate
- in vernac_loop ~state
+ vernac_loop ~state
with
- | CErrors.Drop ->
- (* Due to using exceptions as a form of control, state here goes
- out of sync as [do_vernac] will never return. We must thus do
- this hack until we make `Drop` a toplevel-only command. See
- bug #6872. *)
- let state = { state with sid = Stm.get_current_state ~doc:state.doc } in
- drop_last_doc := Some state;
- state
- | CErrors.Quit -> exit 0
| any ->
- top_stderr (str "Anomaly: main loop exited with exception: " ++
- str (Printexc.to_string any) ++
- fnl() ++
- str"Please report" ++
- strbrk" at " ++ str Coq_config.wwwbugtracker ++ str ".");
- loop ~time ~state
+ top_stderr
+ (hov 0 (str "Anomaly: main loop exited with exception:" ++ spc () ++
+ str (Printexc.to_string any)) ++ spc () ++
+ hov 0 (str "Please report at " ++ str Coq_config.wwwbugtracker ++ str "."));
+ loop ~state
+
+(* Default toplevel loop *)
+let warning s = Flags.(with_option warn Feedback.msg_warning (strbrk s))
+
+let drop_args = ref None
+let loop ~opts ~state =
+ drop_args := Some opts;
+ let open Coqargs in
+ print_emacs := opts.print_emacs;
+ (* We initialize the console only if we run the toploop_run *)
+ let tl_feed = Feedback.add_feeder (coqloop_feed Topfmt.InteractiveLoop) in
+ if Dumpglob.dump () then begin
+ Flags.if_verbose warning "Dumpglob cannot be used in interactive mode.";
+ Dumpglob.noglob ()
+ end;
+ let _ = loop ~state in
+ (* Initialise and launch the Ocaml toplevel *)
+ Coqinit.init_ocaml_path();
+ Mltop.ocaml_toploop();
+ (* We delete the feeder after the OCaml toploop has ended so users
+ of Drop can see the feedback. *)
+ Feedback.del_feeder tl_feed
diff --git a/toplevel/coqloop.mli b/toplevel/coqloop.mli
index bbb9b138..b11f13d3 100644
--- a/toplevel/coqloop.mli
+++ b/toplevel/coqloop.mli
@@ -10,9 +10,6 @@
(** The Coq toplevel loop. *)
-(** -emacs option: printing includes emacs tags. *)
-val print_emacs : bool ref
-
(** A buffer for the character read from a channel. We store the command
* entered to be able to report errors without pretty-printing. *)
@@ -21,7 +18,7 @@ type input_buffer = {
mutable str : Bytes.t; (** buffer of already read characters *)
mutable len : int; (** number of chars in the buffer *)
mutable bols : int list; (** offsets in str of begining of lines *)
- mutable tokens : Pcoq.Gram.coq_parsable; (** stream of tokens *)
+ mutable tokens : Pcoq.Parsable.t; (** stream of tokens *)
mutable start : int } (** stream count of the first char of the buffer *)
(** The input buffer of stdin. *)
@@ -30,13 +27,11 @@ val top_buffer : input_buffer
val set_prompt : (unit -> string) -> unit
(** Toplevel feedback printer. *)
-val coqloop_feed : Feedback.feedback -> unit
-
-(** Parse and execute one vernac command. *)
-val do_vernac : time:bool -> state:Vernac.State.t -> Vernac.State.t
-
-(** Main entry point of Coq: read and execute vernac commands. *)
-val loop : time:bool -> state:Vernac.State.t -> Vernac.State.t
+val coqloop_feed : Topfmt.execution_phase -> Feedback.feedback -> unit
(** Last document seen after `Drop` *)
val drop_last_doc : Vernac.State.t option ref
+val drop_args : Coqargs.coq_cmdopts option ref
+
+(** Main entry point of Coq: read and execute vernac commands. *)
+val loop : opts:Coqargs.coq_cmdopts -> state:Vernac.State.t -> unit
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index 943b66f6..09ecb7ec 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -30,29 +30,14 @@ let print_header () =
Feedback.msg_notice (str "Welcome to Coq " ++ str ver ++ str " (" ++ str rev ++ str ")");
flush_all ()
-let warning s = Flags.(with_option warn Feedback.msg_warning (strbrk s))
-
(* Feedback received in the init stage, this is different as the STM
will not be generally be initialized, thus stateid, etc... may be
bogus. For now we just print to the console too *)
-let coqtop_init_feed = Coqloop.coqloop_feed
-
-(* Default toplevel loop *)
-let console_toploop_run opts ~state =
- (* We initialize the console only if we run the toploop_run *)
- let tl_feed = Feedback.add_feeder Coqloop.coqloop_feed in
- if Dumpglob.dump () then begin
- Flags.if_verbose warning "Dumpglob cannot be used in interactive mode.";
- Dumpglob.noglob ()
- end;
- let _ = Coqloop.loop ~time:opts.time ~state in
- (* Initialise and launch the Ocaml toplevel *)
- Coqinit.init_ocaml_path();
- Mltop.ocaml_toploop();
- (* We let the feeder in place for users of Drop *)
- Feedback.del_feeder tl_feed
+let coqtop_init_feed = Coqloop.coqloop_feed Topfmt.Initialization
-let toploop_run = ref console_toploop_run
+let coqtop_doc_feed = Coqloop.coqloop_feed Topfmt.LoadingPrelude
+
+let coqtop_rcfile_feed = Coqloop.coqloop_feed Topfmt.LoadingRcFile
let memory_stat = ref false
let print_memory_stat () =
@@ -95,15 +80,22 @@ let load_vernacular opts ~state =
(fun state (f_in, echo) ->
let s = Loadpath.locate_file f_in in
(* Should make the beautify logic clearer *)
- let load_vernac f = Vernac.load_vernac ~time:opts.time ~echo ~interactive:false ~check:true ~state f in
+ let load_vernac f = Vernac.load_vernac ~echo ~interactive:false ~check:true ~state f in
if !Flags.beautify
then Flags.with_option Flags.beautify_file load_vernac f_in
else load_vernac s
) state (List.rev opts.load_vernacular_list)
-let load_init_vernaculars opts ~state =
- let state = if opts.load_rcfile then
- Coqinit.load_rcfile ~rcfile:opts.rcfile ~time:opts.time ~state
+let load_init_vernaculars cur_feeder opts ~state =
+ let state =
+ if opts.load_rcfile then begin
+ Feedback.del_feeder !cur_feeder;
+ let rc_feeder = Feedback.add_feeder coqtop_rcfile_feed in
+ let state = Coqinit.load_rcfile ~rcfile:opts.rcfile ~state in
+ Feedback.del_feeder rc_feeder;
+ cur_feeder := Feedback.add_feeder coqtop_init_feed;
+ state
+ end
else begin
Flags.if_verbose Feedback.msg_info (str"Skipping rcfile loading.");
state
@@ -147,8 +139,8 @@ let fatal_error msg =
flush_all ();
exit 1
-let fatal_error_exn ?extra exn =
- Topfmt.print_err_exn ?extra exn;
+let fatal_error_exn exn =
+ Topfmt.print_err_exn Topfmt.Initialization exn;
flush_all ();
let exit_code =
if CErrors.(is_anomaly exn || not (handled exn)) then 129 else 1
@@ -194,7 +186,7 @@ let ensure_exists f =
fatal_error (hov 0 (str "Can't find file" ++ spc () ++ str f))
(* Compile a vernac file *)
-let compile opts ~echo ~f_in ~f_out =
+let compile cur_feeder opts ~echo ~f_in ~f_out =
let open Vernac.State in
let check_pending_proofs () =
let pfs = Proof_global.get_all_proof_names () in
@@ -218,13 +210,18 @@ let compile opts ~echo ~f_in ~f_out =
| None -> long_f_dot_v ^ "o"
| Some f -> ensure_vo long_f_dot_v f in
- let doc, sid = Stm.(new_doc
+ Feedback.del_feeder !cur_feeder;
+ let doc_feeder = Feedback.add_feeder coqtop_doc_feed in
+ let doc, sid =
+ Stm.(new_doc
{ doc_type = VoDoc long_f_dot_vo;
iload_path; require_libs; stm_options;
}) in
+ Feedback.del_feeder doc_feeder;
+ cur_feeder := Feedback.add_feeder coqtop_init_feed;
- let state = { doc; sid; proof = None } in
- let state = load_init_vernaculars opts ~state in
+ let state = { doc; sid; proof = None; time = opts.time } in
+ let state = load_init_vernaculars cur_feeder opts ~state in
let ldir = Stm.get_ldir ~doc:state.doc in
Aux_file.(start_aux_file
~aux_file:(aux_file_name_for long_f_dot_vo)
@@ -232,7 +229,7 @@ let compile opts ~echo ~f_in ~f_out =
Dumpglob.start_dump_glob ~vfile:long_f_dot_v ~vofile:long_f_dot_vo;
Dumpglob.dump_string ("F" ^ Names.DirPath.to_string ldir ^ "\n");
let wall_clock1 = Unix.gettimeofday () in
- let state = Vernac.load_vernac ~time:opts.time ~echo ~check:true ~interactive:false ~state long_f_dot_v in
+ let state = Vernac.load_vernac ~echo ~check:true ~interactive:false ~state long_f_dot_v in
let _doc = Stm.join ~doc:state.doc in
let wall_clock2 = Unix.gettimeofday () in
check_pending_proofs ();
@@ -265,15 +262,20 @@ let compile opts ~echo ~f_in ~f_out =
async_proofs_tac_error_resilience = `None;
} in
- let doc, sid = Stm.(new_doc
+ Feedback.del_feeder !cur_feeder;
+ let doc_feeder = Feedback.add_feeder coqtop_doc_feed in
+ let doc, sid =
+ Stm.(new_doc
{ doc_type = VioDoc long_f_dot_vio;
iload_path; require_libs; stm_options;
}) in
+ Feedback.del_feeder doc_feeder;
+ cur_feeder := Feedback.add_feeder coqtop_init_feed;
- let state = { doc; sid; proof = None } in
- let state = load_init_vernaculars opts ~state in
+ let state = { doc; sid; proof = None; time = opts.time } in
+ let state = load_init_vernaculars cur_feeder opts ~state in
let ldir = Stm.get_ldir ~doc:state.doc in
- let state = Vernac.load_vernac ~time:opts.time ~echo ~check:false ~interactive:false ~state long_f_dot_v in
+ let state = Vernac.load_vernac ~echo ~check:false ~interactive:false ~state long_f_dot_v in
let doc = Stm.finish ~doc:state.doc in
check_pending_proofs ();
let _doc = Stm.snapshot_vio ~doc ldir long_f_dot_vio in
@@ -288,22 +290,22 @@ let compile opts ~echo ~f_in ~f_out =
let univs, proofs = Stm.finish_tasks lfdv univs disch proofs tasks in
Library.save_library_raw lfdv sum lib univs proofs
-let compile opts ~echo ~f_in ~f_out =
+let compile cur_feeder opts ~echo ~f_in ~f_out =
ignore(CoqworkmgrApi.get 1);
- compile opts ~echo ~f_in ~f_out;
+ compile cur_feeder opts ~echo ~f_in ~f_out;
CoqworkmgrApi.giveback 1
-let compile_file opts (f_in, echo) =
+let compile_file cur_feeder opts (f_in, echo) =
let f_out = opts.compilation_output_name in
if !Flags.beautify then
Flags.with_option Flags.beautify_file
- (fun f_in -> compile opts ~echo ~f_in ~f_out) f_in
+ (fun f_in -> compile cur_feeder opts ~echo ~f_in ~f_out) f_in
else
- compile opts ~echo ~f_in ~f_out
+ compile cur_feeder opts ~echo ~f_in ~f_out
-let compile_files opts =
+let compile_files cur_feeder opts =
let compile_list = List.rev opts.compile_list in
- List.iter (compile_file opts) compile_list
+ List.iter (compile_file cur_feeder opts) compile_list
(******************************************************************************)
(* VIO Dispatching *)
@@ -337,8 +339,8 @@ let do_vio opts =
(******************************************************************************)
(* Color Options *)
(******************************************************************************)
-let init_color color_mode =
- let has_color = match color_mode with
+let init_color opts =
+ let has_color = match opts.color with
| `OFF -> false
| `ON -> true
| `AUTO ->
@@ -348,32 +350,23 @@ let init_color color_mode =
its TERM variable is set to "dumb". *)
try Sys.getenv "TERM" <> "dumb" with Not_found -> false
in
- if has_color then begin
- let colors = try Some (Sys.getenv "COQ_COLORS") with Not_found -> None in
- match colors with
- | None ->
- (** Default colors *)
- Topfmt.default_styles ();
- Topfmt.init_terminal_output ~color:true
- | Some "" ->
- (** No color output *)
- Topfmt.init_terminal_output ~color:false
- | Some s ->
- (** Overwrite all colors *)
- Topfmt.parse_color_config s;
- Topfmt.init_terminal_output ~color:true
- end
- else
- Topfmt.init_terminal_output ~color:false
-
-let toploop_init = ref begin fun opts x ->
- let () = init_color opts.color in
- let () = CoqworkmgrApi.init !WorkerLoop.async_proofs_worker_priority in
- x
- end
+ let term_color =
+ if has_color then begin
+ let colors = try Some (Sys.getenv "COQ_COLORS") with Not_found -> None in
+ match colors with
+ | None -> Topfmt.default_styles (); true (** Default colors *)
+ | Some "" -> false (** No color output *)
+ | Some s -> Topfmt.parse_color_config s; true (** Overwrite all colors *)
+ end
+ else
+ false
+ in
+ if Proof_diffs.show_diffs () && not term_color && not opts.batch_mode then
+ (prerr_endline "Error: -diffs requires enabling -color"; exit 1);
+ Topfmt.init_terminal_output ~color:term_color
let print_style_tags opts =
- let () = init_color opts.color in
+ let () = init_color opts in
let tags = Topfmt.dump_tags () in
let iter (t, st) =
let opt = Terminal.eval st ^ t ^ Terminal.reset ^ "\n" in
@@ -391,7 +384,7 @@ let print_style_tags opts =
(** GC tweaking *)
(** Coq is a heavy user of persistent data structures and symbolic ASTs, so the
- minor heap is heavily sollicited. Unfortunately, the default size is far too
+ minor heap is heavily solicited. Unfortunately, the default size is far too
small, so we enlarge it a lot (128 times larger).
To better handle huge memory consumers, we also augment the default major
@@ -414,14 +407,14 @@ let init_gc () =
Gc.space_overhead = 120}
(** Main init routine *)
-let init_toplevel arglist =
+let init_toplevel custom_init arglist =
(* Coq's init process, phase 1:
OCaml parameters, basic structures, and IO
*)
CProfile.init_profile ();
init_gc ();
Sys.catch_break false; (* Ctrl-C is fatal during the initialisation *)
- let init_feeder = Feedback.add_feeder coqtop_init_feed in
+ let init_feeder = ref (Feedback.add_feeder coqtop_init_feed) in
Lib.init();
(* Coq's init process, phase 2:
@@ -436,20 +429,30 @@ let init_toplevel arglist =
* early since the master waits us to connect back *)
Spawned.init_channels ();
Envars.set_coqlib ~fail:(fun msg -> CErrors.user_err Pp.(str msg));
- if opts.print_where then (print_endline(Envars.coqlib ()); exit(exitcode opts));
- if opts.print_config then (Envars.print_config stdout Coq_config.all_src_dirs; exit (exitcode opts));
- if opts.print_tags then (print_style_tags opts; exit (exitcode opts));
- if opts.filter_opts then (print_string (String.concat "\n" extras); exit 0);
+ if opts.print_where then begin
+ print_endline (Envars.coqlib ());
+ exit (exitcode opts)
+ end;
+ if opts.print_config then begin
+ Envars.print_config stdout Coq_config.all_src_dirs;
+ exit (exitcode opts)
+ end;
+ if opts.print_tags then begin
+ print_style_tags opts;
+ exit (exitcode opts)
+ end;
+ if opts.filter_opts then begin
+ print_string (String.concat "\n" extras);
+ exit 0;
+ end;
let top_lp = Coqinit.toplevel_init_load_path () in
List.iter Mltop.add_coq_path top_lp;
- Option.iter Mltop.load_ml_object_raw opts.toploop;
- let extras = !toploop_init opts extras in
+ let opts, extras = custom_init ~opts extras in
if not (CList.is_empty extras) then begin
prerr_endline ("Don't know what to do with "^String.concat " " extras);
prerr_endline "See -help for the list of supported options";
exit 1
end;
- Flags.if_verbose print_header ();
Mltop.init_known_plugins ();
Global.set_engagement opts.impredicative_set;
@@ -478,41 +481,54 @@ let init_toplevel arglist =
let iload_path = build_load_path opts in
let require_libs = require_libs opts in
let stm_options = opts.stm_flags in
- try
- let open Vernac.State in
- let doc, sid =
- Stm.(new_doc
- { doc_type = Interactive opts.toplevel_name;
- iload_path; require_libs; stm_options;
- }) in
- let state = { doc; sid; proof = None } in
- Some (load_init_vernaculars opts ~state), opts
- with any -> flush_all(); fatal_error_exn any
+ let open Vernac.State in
+ Feedback.del_feeder !init_feeder;
+ let doc_feeder = Feedback.add_feeder coqtop_doc_feed in
+ let doc, sid =
+ Stm.(new_doc
+ { doc_type = Interactive opts.toplevel_name;
+ iload_path; require_libs; stm_options;
+ }) in
+ Feedback.del_feeder doc_feeder;
+ init_feeder := Feedback.add_feeder coqtop_init_feed;
+ let state = { doc; sid; proof = None; time = opts.time } in
+ Some (load_init_vernaculars init_feeder opts ~state), opts
(* Non interactive: we perform a sequence of compilation steps *)
end else begin
- try
- compile_files opts;
- (* Careful this will modify the load-path and state so after
- this point some stuff may not be safe anymore. *)
- do_vio opts;
- (* Allow the user to output an arbitrary state *)
- outputstate opts;
- None, opts
- with any -> flush_all(); fatal_error_exn any
+ compile_files init_feeder opts;
+ (* Careful this will modify the load-path and state so after
+ this point some stuff may not be safe anymore. *)
+ do_vio opts;
+ (* Allow the user to output an arbitrary state *)
+ outputstate opts;
+ None, opts
end;
with any ->
flush_all();
- let extra = Some (str "Error during initialization: ") in
- fatal_error_exn ?extra any
+ fatal_error_exn any
end in
- Feedback.del_feeder init_feeder;
+ Feedback.del_feeder !init_feeder;
res
-let start () =
- match init_toplevel (List.tl (Array.to_list Sys.argv)) with
+type custom_toplevel = {
+ init : opts:coq_cmdopts -> string list -> coq_cmdopts * string list;
+ run : opts:coq_cmdopts -> state:Vernac.State.t -> unit;
+}
+
+let coqtop_init ~opts extra =
+ init_color opts;
+ CoqworkmgrApi.(init !async_proofs_worker_priority);
+ if CList.is_empty extra then
+ Flags.if_verbose print_header ();
+ opts, extra
+
+let coqtop_toplevel = { init = coqtop_init; run = Coqloop.loop; }
+
+let start_coq custom =
+ match init_toplevel custom.init (List.tl (Array.to_list Sys.argv)) with
(* Batch mode *)
| Some state, opts when not opts.batch_mode ->
- !toploop_run opts ~state;
+ custom.run ~opts ~state;
exit 1
| _ , opts ->
flush_all();
diff --git a/toplevel/coqtop.mli b/toplevel/coqtop.mli
index 056279bb..641448f1 100644
--- a/toplevel/coqtop.mli
+++ b/toplevel/coqtop.mli
@@ -8,15 +8,21 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-(** The Coq main module. The following function [start] will parse the
- command line, print the banner, initialize the load path, load the input
- state, load the files given on the command line, load the resource file,
- produce the output state if any, and finally will launch [Coqloop.loop]. *)
+(** Definition of custom toplevels.
+ [init] is used to do custom command line argument parsing.
+ [run] launches a custom toplevel.
+*)
+type custom_toplevel = {
+ init : opts:Coqargs.coq_cmdopts -> string list -> Coqargs.coq_cmdopts * string list;
+ run : opts:Coqargs.coq_cmdopts -> state:Vernac.State.t -> unit;
+}
-val init_toplevel : string list -> Vernac.State.t option * Coqargs.coq_cmdopts
+val coqtop_toplevel : custom_toplevel
-val start : unit -> unit
+(** The Coq main module. [start custom] will parse the command line,
+ print the banner, initialize the load path, load the input state,
+ load the files given on the command line, load the resource file,
+ produce the output state if any, and finally will launch
+ [custom.run]. *)
-(* For other toploops *)
-val toploop_init : (Coqargs.coq_cmdopts -> string list -> string list) ref
-val toploop_run : (Coqargs.coq_cmdopts -> state:Vernac.State.t -> unit) ref
+val start_coq : custom_toplevel -> unit
diff --git a/toplevel/g_toplevel.mlg b/toplevel/g_toplevel.mlg
new file mode 100644
index 00000000..5aba3d6b
--- /dev/null
+++ b/toplevel/g_toplevel.mlg
@@ -0,0 +1,54 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+{
+open Pcoq
+open Pcoq.Prim
+open Vernacexpr
+
+(* Vernaculars specific to the toplevel *)
+type vernac_toplevel =
+ | VernacBacktrack of int * int * int
+ | VernacDrop
+ | VernacQuit
+ | VernacControl of vernac_control
+
+module Toplevel_ : sig
+ val vernac_toplevel : vernac_toplevel CAst.t Entry.t
+end = struct
+ let gec_vernac s = Entry.create ("toplevel:" ^ s)
+ let vernac_toplevel = gec_vernac "vernac_toplevel"
+end
+
+open Toplevel_
+
+}
+
+GRAMMAR EXTEND Gram
+ GLOBAL: vernac_toplevel;
+ vernac_toplevel: FIRST
+ [ [ IDENT "Drop"; "." -> { CAst.make VernacDrop }
+ | IDENT "Quit"; "." -> { CAst.make VernacQuit }
+ | IDENT "Backtrack"; n = natural ; m = natural ; p = natural; "." ->
+ { CAst.make (VernacBacktrack (n,m,p)) }
+ | cmd = Pvernac.main_entry ->
+ { match cmd with
+ | None -> raise Stm.End_of_input
+ | Some (loc,c) -> CAst.make ~loc (VernacControl c) }
+ ]
+ ]
+ ;
+END
+
+{
+
+let parse_toplevel pa = Pcoq.Entry.parse vernac_toplevel pa
+
+}
diff --git a/toplevel/toplevel.mllib b/toplevel/toplevel.mllib
index 9fb2e33d..597173e5 100644
--- a/toplevel/toplevel.mllib
+++ b/toplevel/toplevel.mllib
@@ -1,6 +1,8 @@
Vernac
Usage
-Coqloop
Coqinit
Coqargs
+G_toplevel
+Coqloop
Coqtop
+WorkerLoop
diff --git a/toplevel/usage.ml b/toplevel/usage.ml
index 504ffa52..d85fed5f 100644
--- a/toplevel/usage.ml
+++ b/toplevel/usage.ml
@@ -72,7 +72,8 @@ let print_usage_channel co command =
\n -boot boot mode (implies -q and -batch)\
\n -bt print backtraces (requires configure debug flag)\
\n -debug debug mode (implies -bt)\
-\n -stm-debug STM debug mode (will trace every transaction) \
+\n -diffs (on|off|removed) highlight differences between proof steps\
+\n -stm-debug STM debug mode (will trace every transaction)\
\n -emacs tells Coq it is executed under Emacs\
\n -noglob do not dump globalizations\
\n -dump-glob f dump globalizations in file f (to be used by coqdoc)\
diff --git a/toplevel/vernac.ml b/toplevel/vernac.ml
index fdd0d4ed..c914bbec 100644
--- a/toplevel/vernac.ml
+++ b/toplevel/vernac.ml
@@ -28,10 +28,6 @@ let checknav_deep {CAst.loc;v=ast} =
if is_deep_navigation_vernac ast then
CErrors.user_err ?loc (str "Navigation commands forbidden in nested commands.")
-let disable_drop = function
- | Drop -> CErrors.user_err Pp.(str "Drop is forbidden.")
- | e -> e
-
(* Echo from a buffer based on position.
XXX: Should move to utility file. *)
let vernac_echo ?loc in_chan = let open Loc in
@@ -80,17 +76,21 @@ module State = struct
doc : Stm.doc;
sid : Stateid.t;
proof : Proof.t option;
+ time : bool;
}
end
-let interp_vernac ~time ~check ~interactive ~state ({CAst.loc;_} as com) =
+let interp_vernac ~check ~interactive ~state ({CAst.loc;_} as com) =
let open State in
try
(* The -time option is only supported from console-based clients
due to the way it prints. *)
- if time then print_cmd_header com;
- let com = if time then CAst.make ?loc @@ VernacTime(time,com) else com in
+ let com = if state.time
+ then begin
+ print_cmd_header com;
+ CAst.make ?loc @@ VernacTime(state.time,com)
+ end else com in
let doc, nsid, ntip = Stm.add ~doc:state.doc ~ontop:state.sid (not !Flags.quiet) com in
(* Main STM interaction *)
@@ -102,7 +102,7 @@ let interp_vernac ~time ~check ~interactive ~state ({CAst.loc;_} as com) =
(* Stm.observe nsid; *)
let ndoc = if check then Stm.finish ~doc else doc in
let new_proof = Proof_global.give_me_the_proof_opt () in
- { doc = ndoc; sid = nsid; proof = new_proof }
+ { state with doc = ndoc; sid = nsid; proof = new_proof; }
with reraise ->
(* XXX: In non-interactive mode edit_at seems to do very weird
things, so we better avoid it while we investigate *)
@@ -115,13 +115,13 @@ let interp_vernac ~time ~check ~interactive ~state ({CAst.loc;_} as com) =
end in iraise (reraise, info)
(* Load a vernac file. CErrors are annotated with file and location *)
-let load_vernac_core ~time ~echo ~check ~interactive ~state file =
+let load_vernac_core ~echo ~check ~interactive ~state file =
(* Keep in sync *)
let in_chan = open_utf8_file_in file in
let in_echo = if echo then Some (open_utf8_file_in file) else None in
let input_cleanup () = close_in in_chan; Option.iter close_in in_echo in
- let in_pa = Pcoq.Gram.parsable ~file:(Loc.InFile file) (Stream.of_channel in_chan) in
+ let in_pa = Pcoq.Parsable.make ~file:(Loc.InFile file) (Stream.of_channel in_chan) in
let rstate = ref state in
(* For beautify, list of parsed sids *)
let rids = ref [] in
@@ -154,22 +154,22 @@ let load_vernac_core ~time ~echo ~check ~interactive ~state file =
Option.iter (vernac_echo ?loc) in_echo;
checknav_simple ast;
- let state = Flags.silently (interp_vernac ~time ~check ~interactive ~state:!rstate) ast in
+ let state = Flags.silently (interp_vernac ~check ~interactive ~state:!rstate) ast in
rids := state.sid :: !rids;
rstate := state;
done;
input_cleanup ();
- !rstate, !rids, Pcoq.Gram.comment_state in_pa
+ !rstate, !rids, Pcoq.Parsable.comment_state in_pa
with any -> (* whatever the exception *)
let (e, info) = CErrors.push any in
input_cleanup ();
match e with
- | Stm.End_of_input -> !rstate, !rids, Pcoq.Gram.comment_state in_pa
- | reraise -> iraise (disable_drop e, info)
+ | Stm.End_of_input -> !rstate, !rids, Pcoq.Parsable.comment_state in_pa
+ | reraise -> iraise (e, info)
-let process_expr ~time ~state loc_ast =
+let process_expr ~state loc_ast =
checknav_deep loc_ast;
- interp_vernac ~time ~interactive:true ~check:true ~state loc_ast
+ interp_vernac ~interactive:true ~check:true ~state loc_ast
(******************************************************************************)
(* Beautify-specific code *)
@@ -220,8 +220,8 @@ let beautify_pass ~doc ~comments ~ids ~filename =
(* Main driver for file loading. For now, we only do one beautify
pass. *)
-let load_vernac ~time ~echo ~check ~interactive ~state filename =
- let ostate, ids, comments = load_vernac_core ~time ~echo ~check ~interactive ~state filename in
+let load_vernac ~echo ~check ~interactive ~state filename =
+ let ostate, ids, comments = load_vernac_core ~echo ~check ~interactive ~state filename in
(* Pass for beautify *)
if !Flags.beautify then beautify_pass ~doc:ostate.State.doc ~comments ~ids:List.(rev ids) ~filename;
(* End pass *)
diff --git a/toplevel/vernac.mli b/toplevel/vernac.mli
index 51758642..12695402 100644
--- a/toplevel/vernac.mli
+++ b/toplevel/vernac.mli
@@ -15,6 +15,7 @@ module State : sig
doc : Stm.doc;
sid : Stateid.t;
proof : Proof.t option;
+ time : bool;
}
end
@@ -23,10 +24,10 @@ end
expected to handle and print errors in form of exceptions, however
care is taken so the state machine is left in a consistent
state. *)
-val process_expr : time:bool -> state:State.t -> Vernacexpr.vernac_control CAst.t -> State.t
+val process_expr : state:State.t -> Vernacexpr.vernac_control CAst.t -> State.t
(** [load_vernac echo sid file] Loads [file] on top of [sid], will
echo the commands if [echo] is set. Callers are expected to handle
and print errors in form of exceptions. *)
-val load_vernac : time:bool -> echo:bool -> check:bool -> interactive:bool ->
+val load_vernac : echo:bool -> check:bool -> interactive:bool ->
state:State.t -> string -> State.t
diff --git a/stm/workerLoop.ml b/toplevel/workerLoop.ml
index 5445925b..ee6d5e88 100644
--- a/stm/workerLoop.ml
+++ b/toplevel/workerLoop.ml
@@ -8,18 +8,22 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-(* Default priority *)
-open CoqworkmgrApi
-let async_proofs_worker_priority = ref Low
-
let rec parse = function
| "--xml_format=Ppcmds" :: rest -> parse rest
| x :: rest -> x :: parse rest
| [] -> []
-let loop init _coq_args extra_args =
- let args = parse extra_args in
+let arg_init init ~opts extra_args =
+ let extra_args = parse extra_args in
Flags.quiet := true;
init ();
- CoqworkmgrApi.init !async_proofs_worker_priority;
- args
+ CoqworkmgrApi.(init !async_proofs_worker_priority);
+ opts, extra_args
+
+let start ~init ~loop =
+ let open Coqtop in
+ let custom = {
+ init = arg_init init;
+ run = (fun ~opts:_ ~state:_ -> loop ());
+ } in
+ start_coq custom
diff --git a/stm/workerLoop.mli b/toplevel/workerLoop.mli
index f02edb9b..e497dee6 100644
--- a/stm/workerLoop.mli
+++ b/toplevel/workerLoop.mli
@@ -8,7 +8,7 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-(* Default priority *)
-val async_proofs_worker_priority : CoqworkmgrApi.priority ref
-
-val loop : (unit -> unit) -> Coqargs.coq_cmdopts -> string list -> string list
+(* Register a STM worker *)
+val start :
+ init:(unit -> unit) ->
+ loop:(unit -> unit) -> unit
diff --git a/vernac/assumptions.mli b/vernac/assumptions.mli
index 7e13f8f2..751e79d8 100644
--- a/vernac/assumptions.mli
+++ b/vernac/assumptions.mli
@@ -23,11 +23,11 @@ open Printer
val traverse :
Label.t -> constr ->
(Refset_env.t * Refset_env.t Refmap_env.t *
- (Label.t * Context.Rel.t * types) list Refmap_env.t)
+ (Label.t * Constr.rel_context * types) list Refmap_env.t)
(** Collects all the assumptions (optionally including opaque definitions)
on which a term relies (together with their type). The above warning of
{!traverse} also applies. *)
val assumptions :
?add_opaque:bool -> ?add_transparent:bool -> transparent_state ->
- global_reference -> constr -> types ContextObjectMap.t
+ GlobRef.t -> constr -> types ContextObjectMap.t
diff --git a/vernac/auto_ind_decl.ml b/vernac/auto_ind_decl.ml
index 0404d015..3bf3925b 100644
--- a/vernac/auto_ind_decl.ml
+++ b/vernac/auto_ind_decl.ml
@@ -24,7 +24,8 @@ open Globnames
open Inductiveops
open Tactics
open Ind_tables
-open Misctypes
+open Namegen
+open Tactypes
open Proofview.Notations
module RelDecl = Context.Rel.Declaration
@@ -54,20 +55,20 @@ exception EqUnknown of string
exception UndefinedCst of string
exception InductiveWithProduct
exception InductiveWithSort
-exception ParameterWithoutEquality of global_reference
+exception ParameterWithoutEquality of GlobRef.t
exception NonSingletonProp of inductive
exception DecidabilityMutualNotSupported
exception NoDecidabilityCoInductive
-let constr_of_global g = lazy (Universes.constr_of_global g)
+let constr_of_global g = lazy (UnivGen.constr_of_global g)
(* Some pre declaration of constant we are going to use *)
let bb = constr_of_global Coqlib.glob_bool
-let andb_prop = fun _ -> Universes.constr_of_global (Coqlib.build_bool_type()).Coqlib.andb_prop
+let andb_prop = fun _ -> UnivGen.constr_of_global (Coqlib.build_bool_type()).Coqlib.andb_prop
let andb_true_intro = fun _ ->
- Universes.constr_of_global
+ UnivGen.constr_of_global
(Coqlib.build_bool_type()).Coqlib.andb_true_intro
let tt = constr_of_global Coqlib.glob_true
@@ -76,9 +77,9 @@ let ff = constr_of_global Coqlib.glob_false
let eq = constr_of_global Coqlib.glob_eq
-let sumbool () = Universes.constr_of_global (Coqlib.build_coq_sumbool ())
+let sumbool () = UnivGen.constr_of_global (Coqlib.build_coq_sumbool ())
-let andb = fun _ -> Universes.constr_of_global (Coqlib.build_bool_type()).Coqlib.andb
+let andb = fun _ -> UnivGen.constr_of_global (Coqlib.build_bool_type()).Coqlib.andb
let induct_on c = induction false None c None None
@@ -186,10 +187,10 @@ let build_beq_scheme mode kn =
*)
let compute_A_equality rel_list nlist eqA ndx t =
let lifti = ndx in
- let sigma = Evd.empty (** FIXME *) in
let rec aux c =
- let (c,a) = Reductionops.whd_betaiota_stack Evd.empty c in
- match EConstr.kind sigma c with
+ let (c,a) = Reductionops.whd_betaiota_stack Evd.empty EConstr.(of_constr c) in
+ let (c,a) = EConstr.Unsafe.(to_constr c, List.map to_constr a) in
+ match Constr.kind c with
| Rel x -> mkRel (x-nlist+ndx), Safe_typing.empty_private_constants
| Var x ->
let eid = Id.of_string ("eq_"^(Id.to_string x)) in
@@ -198,7 +199,7 @@ let build_beq_scheme mode kn =
with Not_found -> raise (ParameterWithoutEquality (VarRef x))
in
mkVar eid, Safe_typing.empty_private_constants
- | Cast (x,_,_) -> aux (EConstr.applist (x,a))
+ | Cast (x,_,_) -> aux (Term.applist (x,a))
| App _ -> assert false
| Ind ((kn',i as ind'),u) (*FIXME: universes *) ->
if MutInd.equal kn kn' then mkRel(eqA-nlist-i+nb_ind-1), Safe_typing.empty_private_constants
@@ -213,8 +214,8 @@ let build_beq_scheme mode kn =
List.fold_left Safe_typing.concat_private eff (List.rev effs)
in
let args =
- Array.append
- (Array.of_list (List.map (fun x -> lift lifti (EConstr.Unsafe.to_constr x)) a)) eqa in
+ Array.append
+ (Array.of_list (List.map (fun x -> lift lifti x) a)) eqa in
if Int.equal (Array.length args) 0 then eq, eff
else mkApp (eq, args), eff
with Not_found -> raise(EqNotFound (ind', fst ind))
@@ -224,10 +225,9 @@ let build_beq_scheme mode kn =
| Lambda _-> raise (EqUnknown "abstraction")
| LetIn _ -> raise (EqUnknown "let-in")
| Const (kn, u) ->
- let u = EConstr.EInstance.kind sigma u in
(match Environ.constant_opt_value_in env (kn, u) with
| None -> raise (ParameterWithoutEquality (ConstRef kn))
- | Some c -> aux (EConstr.applist (EConstr.of_constr c,a)))
+ | Some c -> aux (Term.applist (c,a)))
| Proj _ -> raise (EqUnknown "projection")
| Construct _ -> raise (EqUnknown "constructor")
| Case _ -> raise (EqUnknown "match")
@@ -271,7 +271,7 @@ let build_beq_scheme mode kn =
nparrec
(nparrec+3+2*nb_cstr_args)
(nb_cstr_args+ndx+1)
- (EConstr.of_constr cc)
+ cc
in
eff := Safe_typing.concat_private eff' !eff;
Array.set eqs ndx
@@ -408,9 +408,9 @@ let do_replace_lb mode lb_scheme_key aavoid narg p q =
lb_type_of_p >>= fun (lb_type_of_p,eff) ->
Proofview.tclEVARMAP >>= fun sigma ->
let lb_args = Array.append (Array.append
- (Array.map (fun x -> x) v)
- (Array.map (fun x -> do_arg sigma x 1) v))
- (Array.map (fun x -> do_arg sigma x 2) v)
+ v
+ (Array.Smart.map (fun x -> do_arg sigma x 1) v))
+ (Array.Smart.map (fun x -> do_arg sigma x 2) v)
in let app = if Array.is_empty lb_args
then lb_type_of_p else mkApp (lb_type_of_p,lb_args)
in
@@ -479,9 +479,9 @@ let do_replace_bl mode bl_scheme_key (ind,u as indu) aavoid narg lft rgt =
user_err err_msg
in let bl_args =
Array.append (Array.append
- (Array.map (fun x -> x) v)
- (Array.map (fun x -> do_arg sigma x 1) v))
- (Array.map (fun x -> do_arg sigma x 2) v )
+ v
+ (Array.Smart.map (fun x -> do_arg sigma x 1) v))
+ (Array.Smart.map (fun x -> do_arg sigma x 2) v )
in
let app = if Array.is_empty bl_args
then bl_t1 else mkApp (bl_t1,bl_args)
@@ -543,7 +543,7 @@ let eqI ind l =
and e, eff =
try let c, eff = find_scheme beq_scheme_kind ind in mkConst c, eff
with Not_found -> user_err ~hdr:"AutoIndDecl.eqI"
- (str "The boolean equality on " ++ MutInd.print (fst ind) ++ str " is needed.");
+ (str "The boolean equality on " ++ Printer.pr_inductive (Global.env ()) ind ++ str " is needed.");
in (if Array.equal Constr.equal eA [||] then e else mkApp(e,eA)), eff
(**********************************************************************)
@@ -643,7 +643,7 @@ repeat ( apply andb_prop in z;let z1:= fresh "Z" in destruct z as [z1 z]).
| App (c,ca) -> (
match EConstr.kind sigma c with
| Ind (indeq, u) ->
- if eq_gr (IndRef indeq) Coqlib.glob_eq
+ if GlobRef.equal (IndRef indeq) Coqlib.glob_eq
then
Tacticals.New.tclTHEN
(do_replace_bl mode bl_scheme_key ind
@@ -871,7 +871,7 @@ let compute_dec_goal ind lnamesparrec nparrec =
create_input (
mkNamedProd n (mkFullInd ind (2*nparrec)) (
mkNamedProd m (mkFullInd ind (2*nparrec+1)) (
- mkApp(sumbool(),[|eqnm;mkApp (Universes.constr_of_global @@ Coqlib.build_coq_not(),[|eqnm|])|])
+ mkApp(sumbool(),[|eqnm;mkApp (UnivGen.constr_of_global @@ Coqlib.build_coq_not(),[|eqnm|])|])
)
)
)
@@ -931,7 +931,7 @@ let compute_dec_tact ind lnamesparrec nparrec =
(* left *)
Tacticals.New.tclTHENLIST [
simplest_left;
- apply (EConstr.of_constr (mkApp(blI,Array.map(fun x->mkVar x) xargs)));
+ apply (EConstr.of_constr (mkApp(blI,Array.map mkVar xargs)));
Auto.default_auto
]
;
@@ -947,7 +947,7 @@ let compute_dec_tact ind lnamesparrec nparrec =
assert_by (Name freshH3)
(EConstr.of_constr (mkApp(eq,[|bb;mkApp(eqI,[|mkVar freshm;mkVar freshm|]);tt|])))
(Tacticals.New.tclTHENLIST [
- apply (EConstr.of_constr (mkApp(lbI,Array.map (fun x->mkVar x) xargs)));
+ apply (EConstr.of_constr (mkApp(lbI,Array.map mkVar xargs)));
Auto.default_auto
]);
Equality.general_rewrite_bindings_in true
diff --git a/vernac/auto_ind_decl.mli b/vernac/auto_ind_decl.mli
index 5cc783df..11f26c7c 100644
--- a/vernac/auto_ind_decl.mli
+++ b/vernac/auto_ind_decl.mli
@@ -23,7 +23,7 @@ exception EqUnknown of string
exception UndefinedCst of string
exception InductiveWithProduct
exception InductiveWithSort
-exception ParameterWithoutEquality of Globnames.global_reference
+exception ParameterWithoutEquality of GlobRef.t
exception NonSingletonProp of inductive
exception DecidabilityMutualNotSupported
exception NoDecidabilityCoInductive
diff --git a/vernac/class.ml b/vernac/class.ml
index 59d93310..614b2181 100644
--- a/vernac/class.ml
+++ b/vernac/class.ml
@@ -37,7 +37,7 @@ type coercion_error_kind =
| ForbiddenSourceClass of cl_typ
| NoTarget
| WrongTarget of cl_typ * cl_typ
- | NotAClass of global_reference
+ | NotAClass of GlobRef.t
exception CoercionError of coercion_error_kind
@@ -67,13 +67,13 @@ let explain_coercion_error g = function
let check_reference_arity ref =
let env = Global.env () in
let c, _ = Global.type_of_global_in_context env ref in
- if not (Reductionops.is_arity env Evd.empty (EConstr.of_constr c)) (** FIXME *) then
+ if not (Reductionops.is_arity env (Evd.from_env env) (EConstr.of_constr c)) (** FIXME *) then
raise (CoercionError (NotAClass ref))
let check_arity = function
| CL_FUN | CL_SORT -> ()
| CL_CONST cst -> check_reference_arity (ConstRef cst)
- | CL_PROJ cst -> check_reference_arity (ConstRef cst)
+ | CL_PROJ p -> check_reference_arity (ConstRef (Projection.Repr.constant p))
| CL_SECVAR id -> check_reference_arity (VarRef id)
| CL_IND kn -> check_reference_arity (IndRef kn)
@@ -92,8 +92,8 @@ let uniform_cond sigma ctx lt =
let class_of_global = function
| ConstRef sp ->
- if Environ.is_projection sp (Global.env ())
- then CL_PROJ sp else CL_CONST sp
+ (match Recordops.find_primitive_projection sp with
+ | Some p -> CL_PROJ p | None -> CL_CONST sp)
| IndRef sp -> CL_IND sp
| VarRef id -> CL_SECVAR id
| ConstructRef _ as c ->
@@ -143,8 +143,8 @@ let get_target t ind =
CL_FUN
else
match pi1 (find_class_type Evd.empty (EConstr.of_constr t)) with
- | CL_CONST p when Environ.is_projection p (Global.env ()) ->
- CL_PROJ p
+ | CL_CONST p when Recordops.is_primitive_projection p ->
+ CL_PROJ (Option.get @@ Recordops.find_primitive_projection p)
| x -> x
let strength_of_cl = function
@@ -165,7 +165,8 @@ let get_strength stre ref cls clt =
let ident_key_of_class = function
| CL_FUN -> "Funclass"
| CL_SORT -> "Sortclass"
- | CL_CONST sp | CL_PROJ sp -> Label.to_string (Constant.label sp)
+ | CL_CONST sp -> Label.to_string (Constant.label sp)
+ | CL_PROJ sp -> Label.to_string (Projection.Repr.label sp)
| CL_IND (sp,_) -> Label.to_string (MutInd.label sp)
| CL_SECVAR id -> Id.to_string id
@@ -181,6 +182,7 @@ let build_id_coercion idf_opt source poly =
let sigma, vs = match source with
| CL_CONST sp -> Evd.fresh_global env sigma (ConstRef sp)
| _ -> error_not_transparent source in
+ let vs = EConstr.Unsafe.to_constr vs in
let c = match constant_opt_value_in env (destConst vs) with
| Some c -> c
| None -> error_not_transparent source in
@@ -302,12 +304,12 @@ let try_add_new_coercion_with_source ref ~local poly ~source =
try_add_new_coercion_core ref ~local poly (Some source) None false
let add_coercion_hook poly local ref =
- let stre = match local with
+ let local = match local with
+ | Discharge
| Local -> true
| Global -> false
- | Discharge -> assert false
in
- let () = try_add_new_coercion ref ~local:stre poly in
+ let () = try_add_new_coercion ref ~local poly in
let msg = pr_global_env Id.Set.empty ref ++ str " is now a coercion" in
Flags.if_verbose Feedback.msg_info msg
diff --git a/vernac/class.mli b/vernac/class.mli
index 33d31fe1..f7e837f3 100644
--- a/vernac/class.mli
+++ b/vernac/class.mli
@@ -10,19 +10,18 @@
open Names
open Classops
-open Globnames
(** Classes and coercions. *)
(** [try_add_new_coercion_with_target ref s src tg] declares [ref] as a coercion
from [src] to [tg] *)
-val try_add_new_coercion_with_target : global_reference -> local:bool ->
+val try_add_new_coercion_with_target : GlobRef.t -> local:bool ->
Decl_kinds.polymorphic ->
source:cl_typ -> target:cl_typ -> unit
(** [try_add_new_coercion ref s] declares [ref], assumed to be of type
[(x1:T1)...(xn:Tn)src->tg], as a coercion from [src] to [tg] *)
-val try_add_new_coercion : global_reference -> local:bool ->
+val try_add_new_coercion : GlobRef.t -> local:bool ->
Decl_kinds.polymorphic -> unit
(** [try_add_new_coercion_subclass cst s] expects that [cst] denotes a
@@ -34,7 +33,7 @@ val try_add_new_coercion_subclass : cl_typ -> local:bool ->
(** [try_add_new_coercion_with_source ref s src] declares [ref] as a coercion
from [src] to [tg] where the target is inferred from the type of [ref] *)
-val try_add_new_coercion_with_source : global_reference -> local:bool ->
+val try_add_new_coercion_with_source : GlobRef.t -> local:bool ->
Decl_kinds.polymorphic -> source:cl_typ -> unit
(** [try_add_new_identity_coercion id s src tg] enriches the
@@ -47,4 +46,4 @@ val add_coercion_hook : Decl_kinds.polymorphic -> unit Lemmas.declaration_hook
val add_subclass_hook : Decl_kinds.polymorphic -> unit Lemmas.declaration_hook
-val class_of_global : global_reference -> cl_typ
+val class_of_global : GlobRef.t -> cl_typ
diff --git a/vernac/classes.ml b/vernac/classes.ml
index 76d427ad..e491761a 100644
--- a/vernac/classes.ml
+++ b/vernac/classes.ml
@@ -41,8 +41,8 @@ let _ = Goptions.declare_bool_option {
let typeclasses_db = "typeclass_instances"
let set_typeclass_transparency c local b =
- Hints.add_hints local [typeclasses_db]
- (Hints.HintsTransparencyEntry ([c], b))
+ Hints.add_hints ~local [typeclasses_db]
+ (Hints.HintsTransparencyEntry (Hints.HintsReferences [c], b))
let _ =
Hook.set Typeclasses.add_instance_hint_hook
@@ -50,24 +50,25 @@ let _ =
let inst' = match inst with IsConstr c -> Hints.IsConstr (EConstr.of_constr c, Univ.ContextSet.empty)
| IsGlobal gr -> Hints.IsGlobRef gr
in
- let info =
- let open Vernacexpr in
- { info with hint_pattern =
- Option.map
- (Constrintern.intern_constr_pattern (Global.env()) Evd.(from_env Global.(env())))
- info.hint_pattern } in
Flags.silently (fun () ->
- Hints.add_hints local [typeclasses_db]
+ Hints.add_hints ~local [typeclasses_db]
(Hints.HintsResolveEntry
[info, poly, false, Hints.PathHints path, inst'])) ());
Hook.set Typeclasses.set_typeclass_transparency_hook set_typeclass_transparency;
Hook.set Typeclasses.classes_transparent_state_hook
(fun () -> Hints.Hint_db.transparent_state (Hints.searchtable_map typeclasses_db))
+let intern_info {hint_priority;hint_pattern} =
+ let env = Global.env() in
+ let sigma = Evd.from_env env in
+ let hint_pattern = Option.map (Constrintern.intern_constr_pattern env sigma) hint_pattern in
+ {hint_priority;hint_pattern}
+
(** TODO: add subinstances *)
let existing_instance glob g info =
let c = global g in
let info = Option.default Hints.empty_hint_info info in
+ let info = intern_info info in
let instance, _ = Global.type_of_global_in_context (Global.env ()) c in
let _, r = Term.decompose_prod_assum instance in
match class_of_constr Evd.empty (EConstr.of_constr r) with
@@ -76,8 +77,8 @@ let existing_instance glob g info =
~hdr:"declare_instance"
(Pp.str "Constant does not build instances of a declared type class.")
-let mismatched_params env n m = mismatched_ctx_inst env Parameters n m
-let mismatched_props env n m = mismatched_ctx_inst env Properties n m
+let mismatched_params env n m = Implicit_quantifiers.mismatched_ctx_inst_err env Parameters n m
+let mismatched_props env n m = Implicit_quantifiers.mismatched_ctx_inst_err env Properties n m
(* Declare everything in the parameters as implicit, and the class instance as well *)
@@ -108,15 +109,15 @@ open Pp
let instance_hook k info global imps ?hook cst =
Impargs.maybe_declare_manual_implicits false cst ~enriching:false imps;
+ let info = intern_info info in
Typeclasses.declare_instance (Some info) (not global) cst;
(match hook with Some h -> h cst | None -> ())
let declare_instance_constant k info global imps ?hook id decl poly sigma term termtype =
let kind = IsDefinition Instance in
let sigma =
- let env = Global.env () in
- let levels = Univ.LSet.union (Univops.universes_of_constr env termtype)
- (Univops.universes_of_constr env term) in
+ let levels = Univ.LSet.union (Univops.universes_of_constr termtype)
+ (Univops.universes_of_constr term) in
Evd.restrict_universe_context sigma levels
in
let uctx = Evd.check_univ_decl ~poly sigma decl in
@@ -135,7 +136,7 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
?(tac:unit Proofview.tactic option) ?hook pri =
let env = Global.env() in
let ({CAst.loc;v=instid}, pl) = instid in
- let sigma, decl = Univdecls.interp_univ_decl_opt env pl in
+ let sigma, decl = Constrexpr_ops.interp_univ_decl_opt env pl in
let tclass, ids =
match bk with
| Decl_kinds.Implicit ->
@@ -143,7 +144,7 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
(fun avoid (clname, _) ->
match clname with
| Some cl ->
- let t = CAst.make @@ CHole (None, Misctypes.IntroAnonymous, None) in
+ let t = CAst.make @@ CHole (None, Namegen.IntroAnonymous, None) in
t, avoid
| None -> failwith ("new instance: under-applied typeclass"))
cl
@@ -196,8 +197,8 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
in
let (_, ty_constr) = instance_constructor (k,u) subst in
let termtype = it_mkProd_or_LetIn ty_constr (ctx' @ ctx) in
- let sigma,_ = Evarutil.nf_evars_and_universes sigma in
- Pretyping.check_evars env Evd.empty sigma termtype;
+ let sigma = Evd.minimize_universes sigma in
+ Pretyping.check_evars env (Evd.from_env env) sigma termtype;
let univs = Evd.check_univ_decl ~poly sigma decl in
let termtype = to_constr sigma termtype in
let cst = Declare.declare_constant ~internal:Declare.InternalTacticRequest id
@@ -227,10 +228,7 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
let sigma, c = interp_casted_constr_evars env' sigma term cty in
Some (Inr (c, subst)), sigma
| Some (Inl props) ->
- let get_id = CAst.map (function
- | Ident id' -> id'
- | Qualid id' -> snd (repr_qualid id'))
- in
+ let get_id qid = CAst.make ?loc:qid.CAst.loc @@ qualid_basename qid in
let props, rest =
List.fold_left
(fun (props, rest) decl ->
@@ -253,7 +251,7 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
k.cl_projs;
c :: props, rest'
with Not_found ->
- ((CAst.make @@ CHole (None(* Some Evar_kinds.GoalEvar *), Misctypes.IntroAnonymous, None)) :: props), rest
+ ((CAst.make @@ CHole (None(* Some Evar_kinds.GoalEvar *), Namegen.IntroAnonymous, None)) :: props), rest
else props, rest)
([], props) k.cl_props
in
@@ -289,11 +287,11 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
let sigma = Typeclasses.resolve_typeclasses ~filter:Typeclasses.all_evars ~fail:false env sigma in
let sigma = Evarutil.nf_evar_map_undefined sigma in
(* Beware of this step, it is required as to minimize universes. *)
- let sigma, _nf = Evarutil.nf_evar_map_universes sigma in
+ let sigma = Evd.minimize_universes sigma in
(* Check that the type is free of evars now. *)
- Pretyping.check_evars env Evd.empty sigma termtype;
+ Pretyping.check_evars env (Evd.from_env env) sigma termtype;
let termtype = to_constr sigma termtype in
- let term = Option.map (to_constr sigma) term in
+ let term = Option.map (to_constr ~abort_on_undefined_evars:false sigma) term in
if not (Evd.has_undefined sigma) && not (Option.is_empty term) then
declare_instance_constant k pri global imps ?hook id decl
poly sigma (Option.get term) termtype
@@ -302,7 +300,8 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
if program_mode then
let hook vis gr _ =
let cst = match gr with ConstRef kn -> kn | _ -> assert false in
- Impargs.declare_manual_implicits false gr ~enriching:false [imps];
+ Impargs.declare_manual_implicits false gr ~enriching:false [imps];
+ let pri = intern_info pri in
Typeclasses.declare_instance (Some pri) (not global) (ConstRef cst)
in
let obls, constr, typ =
@@ -365,8 +364,8 @@ let context poly l =
let sigma = Evd.from_env env in
let sigma, (_, ((env', fullctx), impls)) = interp_context_evars env sigma l in
(* Note, we must use the normalized evar from now on! *)
- let sigma,_ = Evarutil.nf_evars_and_universes sigma in
- let ce t = Pretyping.check_evars env Evd.empty sigma t in
+ let sigma = Evd.minimize_universes sigma in
+ let ce t = Pretyping.check_evars env (Evd.from_env env) sigma t in
let () = List.iter (fun decl -> Context.Rel.Declaration.iter_constr ce decl) fullctx in
let ctx =
try named_of_rel_context fullctx
@@ -424,13 +423,13 @@ let context poly l =
let decl = (Discharge, poly, Definitional) in
let nstatus = match b with
| None ->
- pi3 (ComAssumption.declare_assumption false decl (t, univs) Universes.empty_binders [] impl
- Vernacexpr.NoInline (CAst.make id))
+ pi3 (ComAssumption.declare_assumption false decl (t, univs) UnivNames.empty_binders [] impl
+ Declaremods.NoInline (CAst.make id))
| Some b ->
let decl = (Discharge, poly, Definition) in
let entry = Declare.definition_entry ~univs ~types:t b in
let hook = Lemmas.mk_hook (fun _ gr -> gr) in
- let _ = DeclareDef.declare_definition id decl entry Universes.empty_binders [] hook in
+ let _ = DeclareDef.declare_definition id decl entry UnivNames.empty_binders [] hook in
Lib.sections_are_opened () || Lib.is_modtype_strict ()
in
status && nstatus
diff --git a/vernac/classes.mli b/vernac/classes.mli
index 0342c840..9c37364c 100644
--- a/vernac/classes.mli
+++ b/vernac/classes.mli
@@ -16,23 +16,23 @@ open Libnames
(** Errors *)
-val mismatched_params : env -> constr_expr list -> Context.Rel.t -> 'a
+val mismatched_params : env -> constr_expr list -> Constr.rel_context -> 'a
-val mismatched_props : env -> constr_expr list -> Context.Rel.t -> 'a
+val mismatched_props : env -> constr_expr list -> Constr.rel_context -> 'a
(** Instance declaration *)
-val existing_instance : bool -> reference -> Vernacexpr.hint_info_expr option -> unit
+val existing_instance : bool -> qualid -> Hints.hint_info_expr option -> unit
(** globality, reference, optional priority and pattern information *)
val declare_instance_constant :
typeclass ->
- Vernacexpr.hint_info_expr -> (** priority *)
+ Hints.hint_info_expr -> (** priority *)
bool -> (** globality *)
Impargs.manual_explicitation list -> (** implicits *)
- ?hook:(Globnames.global_reference -> unit) ->
+ ?hook:(GlobRef.t -> unit) ->
Id.t -> (** name *)
- Univdecls.universe_decl ->
+ UState.universe_decl ->
bool -> (* polymorphic *)
Evd.evar_map -> (* Universes *)
Constr.t -> (** body *)
@@ -50,8 +50,8 @@ val new_instance :
(bool * constr_expr) option ->
?generalize:bool ->
?tac:unit Proofview.tactic ->
- ?hook:(Globnames.global_reference -> unit) ->
- Vernacexpr.hint_info_expr ->
+ ?hook:(GlobRef.t -> unit) ->
+ Hints.hint_info_expr ->
Id.t
(** Setting opacity *)
diff --git a/vernac/comAssumption.ml b/vernac/comAssumption.ml
index 6a590758..750ed35c 100644
--- a/vernac/comAssumption.ml
+++ b/vernac/comAssumption.ml
@@ -20,7 +20,6 @@ open Constrintern
open Impargs
open Decl_kinds
open Pretyping
-open Vernacexpr
open Entries
(* 2| Variable/Hypothesis/Parameter/Axiom declarations *)
@@ -66,7 +65,7 @@ match local with
| Global | Local | Discharge ->
let do_instance = should_axiom_into_instance local in
let local = DeclareDef.get_locality ident ~kind:"axiom" local in
- let inl = match nl with
+ let inl = let open Declaremods in match nl with
| NoInline -> None
| DefaultInline -> Some (Flags.get_inline_level())
| InlineAt i -> Some i
@@ -137,7 +136,7 @@ let do_assumptions kind nl l =
let open Context.Named.Declaration in
let env = Global.env () in
let udecl, l = process_assumptions_udecls kind l in
- let sigma, udecl = Univdecls.interp_univ_decl_opt env udecl in
+ let sigma, udecl = interp_univ_decl_opt env udecl in
let l =
if pi2 kind (* poly *) then
(* Separate declarations so that A B : Type puts A and B in different levels. *)
@@ -158,13 +157,13 @@ let do_assumptions kind nl l =
((sigma,env,ienv),((is_coe,idl),t,imps)))
(sigma,env,empty_internalization_env) l
in
- let sigma = solve_remaining_evars all_and_fail_flags env sigma Evd.empty in
+ let sigma = solve_remaining_evars all_and_fail_flags env sigma (Evd.from_env env) in
(* The universe constraints come from the whole telescope. *)
let sigma = Evd.minimize_universes sigma in
let nf_evar c = EConstr.to_constr sigma c in
let uvars, l = List.fold_left_map (fun uvars (coe,t,imps) ->
let t = nf_evar t in
- let uvars = Univ.LSet.union uvars (Univops.universes_of_constr env t) in
+ let uvars = Univ.LSet.union uvars (Univops.universes_of_constr t) in
uvars, (coe,t,imps))
Univ.LSet.empty l
in
@@ -175,7 +174,7 @@ let do_assumptions kind nl l =
let t = replace_vars subst t in
let refs, status' = declare_assumptions idl is_coe kind (t,uctx) ubinders imps nl in
let subst' = List.map2
- (fun {CAst.v=id} (c,u) -> (id, Universes.constr_of_global_univ (c,u)))
+ (fun {CAst.v=id} (c,u) -> (id, UnivGen.constr_of_global_univ (c,u)))
idl refs
in
subst'@subst, status' && status, next_uctx uctx)
diff --git a/vernac/comAssumption.mli b/vernac/comAssumption.mli
index 56e32437..56932360 100644
--- a/vernac/comAssumption.mli
+++ b/vernac/comAssumption.mli
@@ -11,7 +11,6 @@
open Names
open Constr
open Entries
-open Globnames
open Vernacexpr
open Constrexpr
open Decl_kinds
@@ -19,7 +18,7 @@ open Decl_kinds
(** {6 Parameters/Assumptions} *)
val do_assumptions : locality * polymorphic * assumption_object_kind ->
- Vernacexpr.inline -> (ident_decl list * constr_expr) with_coercion list -> bool
+ Declaremods.inline -> (ident_decl list * constr_expr) with_coercion list -> bool
(************************************************************************)
(** Internal API *)
@@ -31,6 +30,6 @@ val do_assumptions : locality * polymorphic * assumption_object_kind ->
nor in a module type and meant to be instantiated. *)
val declare_assumption : coercion_flag -> assumption_kind ->
types in_constant_universes_entry ->
- Universes.universe_binders -> Impargs.manual_implicits ->
- bool (** implicit *) -> Vernacexpr.inline -> variable CAst.t ->
- global_reference * Univ.Instance.t * bool
+ UnivNames.universe_binders -> Impargs.manual_implicits ->
+ bool (** implicit *) -> Declaremods.inline -> variable CAst.t ->
+ GlobRef.t * Univ.Instance.t * bool
diff --git a/vernac/comDefinition.ml b/vernac/comDefinition.ml
index b18a60a1..60f9d674 100644
--- a/vernac/comDefinition.ml
+++ b/vernac/comDefinition.ml
@@ -10,39 +10,19 @@
open Pp
open Util
-open Constr
-open Environ
open Entries
open Redexpr
open Declare
open Constrintern
open Pretyping
-open Context.Rel.Declaration
-
(* Commands of the interface: Constant definitions *)
-let rec under_binders env sigma f n c =
- if Int.equal n 0 then f env sigma (EConstr.of_constr c) else
- match Constr.kind c with
- | Lambda (x,t,c) ->
- mkLambda (x,t,under_binders (push_rel (LocalAssum (x,t)) env) sigma f (n-1) c)
- | LetIn (x,b,t,c) ->
- mkLetIn (x,b,t,under_binders (push_rel (LocalDef (x,b,t)) env) sigma f (n-1) c)
- | _ -> assert false
-
-let red_constant_entry n ce sigma = function
- | None -> ce
+let red_constant_body red_opt env sigma body = match red_opt with
+ | None -> sigma, body
| Some red ->
- let proof_out = ce.const_entry_body in
- let env = Global.env () in
- let (redfun, _) = reduction_of_red_expr env red in
- let redfun env sigma c =
- let (_, c) = redfun env sigma c in
- EConstr.Unsafe.to_constr c
- in
- { ce with const_entry_body = Future.chain proof_out
- (fun ((body,ctx),eff) -> (under_binders env sigma redfun n body,ctx),eff) }
+ let red, _ = reduction_of_red_expr env red in
+ red env sigma body
let warn_implicits_in_term =
CWarnings.create ~name:"implicits-in-term" ~category:"implicits"
@@ -65,7 +45,7 @@ let interp_definition pl bl poly red_option c ctypopt =
let open EConstr in
let env = Global.env() in
(* Explicitly bound universes and constraints *)
- let evd, decl = Univdecls.interp_univ_decl_opt env pl in
+ let evd, decl = Constrexpr_ops.interp_univ_decl_opt env pl in
(* Build the parameters *)
let evd, (impls, ((env_bl, ctx), imps1)) = interp_context_evars env evd bl in
(* Build the type *)
@@ -84,16 +64,18 @@ let interp_definition pl bl poly red_option c ctypopt =
check_imps ~impsty ~impsbody;
evd, c, imps1@Impargs.lift_implicits (Context.Rel.nhyps ctx) impsty, Some ty
in
+ (* Do the reduction *)
+ let evd, c = red_constant_body red_option env_bl evd c in
(* universe minimization *)
let evd = Evd.minimize_universes evd in
(* Substitute evars and universes, and add parameters.
Note: in program mode some evars may remain. *)
- let ctx = List.map (EConstr.to_rel_decl evd) ctx in
- let c = Term.it_mkLambda_or_LetIn (EConstr.to_constr evd c) ctx in
- let tyopt = Option.map (fun ty -> Term.it_mkProd_or_LetIn (EConstr.to_constr evd ty) ctx) tyopt in
+ let ctx = List.map Termops.(map_rel_decl (to_constr ~abort_on_undefined_evars:false evd)) ctx in
+ let c = Term.it_mkLambda_or_LetIn (EConstr.to_constr ~abort_on_undefined_evars:false evd c) ctx in
+ let tyopt = Option.map (fun ty -> Term.it_mkProd_or_LetIn (EConstr.to_constr ~abort_on_undefined_evars:false evd ty) ctx) tyopt in
(* Keep only useful universes. *)
let uvars_fold uvars c =
- Univ.LSet.union uvars (universes_of_constr env evd (of_constr c))
+ Univ.LSet.union uvars (universes_of_constr evd (of_constr c))
in
let uvars = List.fold_left uvars_fold Univ.LSet.empty (Option.List.cons tyopt [c]) in
let evd = Evd.restrict_universe_context evd uvars in
@@ -101,10 +83,12 @@ let interp_definition pl bl poly red_option c ctypopt =
let uctx = Evd.check_univ_decl ~poly evd decl in
(* We're done! *)
let ce = definition_entry ?types:tyopt ~univs:uctx c in
- (red_constant_entry (Context.Rel.length ctx) ce evd red_option, evd, decl, imps)
+ (ce, evd, decl, imps)
let check_definition (ce, evd, _, imps) =
- check_evars_are_solved (Global.env ()) evd Evd.empty;
+ let env = Global.env () in
+ let empty_sigma = Evd.from_env env in
+ check_evars_are_solved env evd empty_sigma;
ce
let do_definition ~program_mode ident k univdecl bl red_option c ctypopt hook =
@@ -118,7 +102,7 @@ let do_definition ~program_mode ident k univdecl bl red_option c ctypopt hook =
assert(Univ.ContextSet.is_empty ctx);
let typ = match ce.const_entry_type with
| Some t -> t
- | None -> EConstr.to_constr evd (Retyping.get_type_of env evd (EConstr.of_constr c))
+ | None -> EConstr.to_constr ~abort_on_undefined_evars:false evd (Retyping.get_type_of env evd (EConstr.of_constr c))
in
Obligations.check_evars env evd;
let obls, _, c, cty =
diff --git a/vernac/comDefinition.mli b/vernac/comDefinition.mli
index 6f81c457..7f1c902c 100644
--- a/vernac/comDefinition.mli
+++ b/vernac/comDefinition.mli
@@ -29,4 +29,4 @@ val do_definition : program_mode:bool ->
val interp_definition :
universe_decl_expr option -> local_binder_expr list -> polymorphic -> red_expr option -> constr_expr ->
constr_expr option -> Safe_typing.private_constants definition_entry * Evd.evar_map *
- Univdecls.universe_decl * Impargs.manual_implicits
+ UState.universe_decl * Impargs.manual_implicits
diff --git a/vernac/comFixpoint.ml b/vernac/comFixpoint.ml
index 1c141c01..37258c2d 100644
--- a/vernac/comFixpoint.ml
+++ b/vernac/comFixpoint.ml
@@ -13,7 +13,6 @@ open Decl_kinds
open Pretyping
open Evarutil
open Evarconv
-open Misctypes
module RelDecl = Context.Rel.Declaration
@@ -173,11 +172,12 @@ let interp_recursive ~program_mode ~cofix fixl notations =
| None , acc -> acc
| x , None -> x
| Some ls , Some us ->
- let lsu = ls.univdecl_instance and usu = us.univdecl_instance in
+ let open UState in
+ let lsu = ls.univdecl_instance and usu = us.univdecl_instance in
if not (CList.for_all2eq (fun x y -> Id.equal x.CAst.v y.CAst.v) lsu usu) then
user_err Pp.(str "(co)-recursive definitions should all have the same universe binders");
Some us) fixl None in
- let sigma, decl = Univdecls.interp_univ_decl_opt env all_universes in
+ let sigma, decl = interp_univ_decl_opt env all_universes in
let sigma, (fixctxs, fiximppairs, fixannots) =
on_snd List.split3 @@
List.fold_left_map (fun sigma -> interp_fix_context env sigma ~cofix) sigma fixl in
@@ -199,9 +199,7 @@ let interp_recursive ~program_mode ~cofix fixl notations =
try
let sigma, h_term = fix_proto sigma in
let app = mkApp (h_term, [|sort; t|]) in
- let _evd = ref sigma in
- let res = Typing.e_solve_evars env _evd app in
- !_evd, res
+ Typing.solve_evars env sigma app
with e when CErrors.noncritical e -> sigma, t
in
sigma, LocalAssum (id,fixprot) :: env'
@@ -224,8 +222,9 @@ let interp_recursive ~program_mode ~cofix fixl notations =
(* Instantiate evars and check all are resolved *)
let sigma = solve_unif_constraints_with_heuristics env_rec sigma in
- let sigma, _ = nf_evars_and_universes sigma in
- let fixdefs = List.map (fun c -> Option.map EConstr.(to_constr sigma) c) fixdefs in
+ let sigma = Evd.minimize_universes sigma in
+ (* XXX: We still have evars here in Program *)
+ let fixdefs = List.map (fun c -> Option.map EConstr.(to_constr ~abort_on_undefined_evars:false sigma) c) fixdefs in
let fixtypes = List.map EConstr.(to_constr sigma) fixtypes in
let fixctxs = List.map (fun (_,ctx) -> ctx) fixctxs in
@@ -233,7 +232,7 @@ let interp_recursive ~program_mode ~cofix fixl notations =
(env,rec_sign,decl,sigma), (fixnames,fixdefs,fixtypes), List.combine3 fixctxs fiximps fixannots
let check_recursive isfix env evd (fixnames,fixdefs,_) =
- check_evars_are_solved env evd Evd.empty;
+ check_evars_are_solved env evd (Evd.from_env env);
if List.for_all Option.has_some fixdefs then begin
let fixdefs = List.map Option.get fixdefs in
check_mutuality env evd isfix (List.combine fixnames fixdefs)
@@ -263,7 +262,7 @@ let declare_fixpoint local poly ((fixnames,fixdefs,fixtypes),pl,ctx,fiximps) ind
let env = Global.env() in
let indexes = search_guard env indexes fixdecls in
let fiximps = List.map (fun (n,r,p) -> r) fiximps in
- let vars = Univops.universes_of_constr env (mkFix ((indexes,0),fixdecls)) in
+ let vars = Univops.universes_of_constr (mkFix ((indexes,0),fixdecls)) in
let fixdecls =
List.map_i (fun i _ -> mkFix ((indexes,i),fixdecls)) 0 fixnames in
let evd = Evd.from_ctx ctx in
@@ -296,8 +295,7 @@ let declare_cofixpoint local poly ((fixnames,fixdefs,fixtypes),pl,ctx,fiximps) n
let fixdefs = List.map Option.get fixdefs in
let fixdecls = prepare_recursive_declaration fixnames fixtypes fixdefs in
let fixdecls = List.map_i (fun i _ -> mkCoFix (i,fixdecls)) 0 fixnames in
- let env = Global.env () in
- let vars = Univops.universes_of_constr env (List.hd fixdecls) in
+ let vars = Univops.universes_of_constr (List.hd fixdecls) in
let fixdecls = List.map Safe_typing.mk_pure_proof fixdecls in
let fiximps = List.map (fun (len,imps,idx) -> imps) fiximps in
let evd = Evd.from_ctx ctx in
diff --git a/vernac/comFixpoint.mli b/vernac/comFixpoint.mli
index 36c2993a..b1a9c8a5 100644
--- a/vernac/comFixpoint.mli
+++ b/vernac/comFixpoint.mli
@@ -33,7 +33,7 @@ val do_cofixpoint :
type structured_fixpoint_expr = {
fix_name : Id.t;
fix_univs : Constrexpr.universe_decl_expr option;
- fix_annot : Misctypes.lident option;
+ fix_annot : lident option;
fix_binders : local_binder_expr list;
fix_body : constr_expr option;
fix_type : constr_expr
@@ -49,7 +49,7 @@ val interp_recursive :
structured_fixpoint_expr list -> decl_notation list ->
(* env / signature / univs / evar_map *)
- (Environ.env * EConstr.named_context * Univdecls.universe_decl * Evd.evar_map) *
+ (Environ.env * EConstr.named_context * UState.universe_decl * Evd.evar_map) *
(* names / defs / types *)
(Id.t list * Constr.constr option list * Constr.types list) *
(* ctx per mutual def / implicits / struct annotations *)
@@ -74,20 +74,20 @@ type recursive_preentry =
val interp_fixpoint :
cofix:bool ->
structured_fixpoint_expr list -> decl_notation list ->
- recursive_preentry * Univdecls.universe_decl * UState.t *
+ recursive_preentry * UState.universe_decl * UState.t *
(EConstr.rel_context * Impargs.manual_implicits * int option) list
(** Registering fixpoints and cofixpoints in the environment *)
(** [Not used so far] *)
val declare_fixpoint :
locality -> polymorphic ->
- recursive_preentry * Univdecls.universe_decl * UState.t *
- (Context.Rel.t * Impargs.manual_implicits * int option) list ->
+ recursive_preentry * UState.universe_decl * UState.t *
+ (Constr.rel_context * Impargs.manual_implicits * int option) list ->
Proof_global.lemma_possible_guards -> decl_notation list -> unit
val declare_cofixpoint : locality -> polymorphic ->
- recursive_preentry * Univdecls.universe_decl * UState.t *
- (Context.Rel.t * Impargs.manual_implicits * int option) list ->
+ recursive_preentry * UState.universe_decl * UState.t *
+ (Constr.rel_context * Impargs.manual_implicits * int option) list ->
decl_notation list -> unit
(** Very private function, do not use *)
diff --git a/vernac/comInductive.ml b/vernac/comInductive.ml
index 05c40dbd..ad1ffa35 100644
--- a/vernac/comInductive.ml
+++ b/vernac/comInductive.ml
@@ -27,9 +27,7 @@ open Impargs
open Reductionops
open Indtypes
open Pretyping
-open Evarutil
open Indschemes
-open Misctypes
open Context.Rel.Declaration
open Entries
@@ -46,8 +44,8 @@ let rec complete_conclusion a cs = CAst.map_with_loc (fun ?loc -> function
user_err ?loc
(strbrk"Cannot infer the non constant arguments of the conclusion of "
++ Id.print cs ++ str ".");
- let args = List.map (fun id -> CAst.(make ?loc @@ CRef(make ?loc @@ Ident id,None))) params in
- CAppExpl ((None,CAst.make ?loc @@ Ident name,None),List.rev args)
+ let args = List.map (fun id -> CAst.(make ?loc @@ CRef(qualid_of_ident ?loc id,None))) params in
+ CAppExpl ((None,qualid_of_ident ?loc name,None),List.rev args)
| c -> c
)
@@ -128,7 +126,7 @@ let make_conclusion_flexible sigma ty poly =
else sigma
let is_impredicative env u =
- u = Prop Null || (is_impredicative_set env && u = Prop Pos)
+ u = Prop || (is_impredicative_set env && u = Set)
let interp_ind_arity env sigma ind =
let c = intern_gen IsType env sigma ind.ind_arity in
@@ -148,7 +146,6 @@ let interp_cstrs env sigma impls mldata arity ind =
let sigma, (ctyps'', cimpls) =
on_snd List.split @@
List.fold_left_map (fun sigma l ->
- on_snd (on_fst EConstr.Unsafe.to_constr) @@
interp_type_evars_impls env sigma ~impls l) sigma ctyps' in
sigma, (cnames, ctyps'', cimpls)
@@ -159,7 +156,7 @@ let sign_level env evd sign =
| LocalDef _ -> lev, push_rel d env
| LocalAssum _ ->
let s = destSort (Reduction.whd_all env
- (EConstr.Unsafe.to_constr (nf_evar evd (Retyping.get_type_of env evd (EConstr.of_constr (RelDecl.get_type d))))))
+ (EConstr.to_constr evd (Retyping.get_type_of env evd (EConstr.of_constr (RelDecl.get_type d)))))
in
let u = univ_of_sort s in
(Univ.sup u lev, push_rel d env))
@@ -178,10 +175,76 @@ let is_flexible_sort evd u =
| Some l -> Evd.is_flexible_level evd l
| None -> false
+(**********************************************************************)
+(* Tools for template 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.
+*)
+
+let is_direct_sort_constraint s v = match s with
+ | Some u -> Univ.univ_level_mem u v
+ | None -> false
+
+let solve_constraints_system levels level_bounds =
+ 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 inductive_levels env evd poly arities inds =
let destarities = List.map (fun x -> x, Reduction.dest_arity env x) arities in
let levels = List.map (fun (x,(ctx,a)) ->
- if a = Prop Null then None
+ if a = Prop then None
else Some (univ_of_sort a)) destarities
in
let cstrs_levels, min_levels, sizes =
@@ -206,8 +269,8 @@ let inductive_levels env evd poly arities inds =
in
(* Take the transitive closure of the system of constructors *)
(* level constraints and remove the recursive dependencies *)
- let levels' = Universes.solve_constraints_system (Array.of_list levels)
- (Array.of_list cstrs_levels) (Array.of_list min_levels)
+ let levels' = solve_constraints_system (Array.of_list levels)
+ (Array.of_list cstrs_levels)
in
let evd, arities =
CList.fold_left3 (fun (evd, arities) cu (arity,(ctx,du)) len ->
@@ -234,14 +297,14 @@ let inductive_levels env evd poly arities inds =
(** "Polymorphic" type constraint and more than one constructor,
should not land in Prop. Add constraint only if it would
land in Prop directly (no informative arguments as well). *)
- Evd.set_leq_sort env evd (Prop Pos) du
+ Evd.set_leq_sort env evd Set du
else evd
in
let duu = Sorts.univ_of_sort du in
let evd =
if not (Univ.is_small_univ duu) && Univ.Universe.equal cu duu then
if is_flexible_sort evd duu && not (Evd.check_leq evd Univ.type0_univ duu) then
- Evd.set_eq_sort env evd (Prop Null) du
+ Evd.set_eq_sort env evd Prop du
else evd
else Evd.set_eq_sort env evd (Type cu) du
in
@@ -263,14 +326,17 @@ let check_param = function
| CLocalPattern {CAst.loc} ->
Loc.raise ?loc (Stream.Error "pattern with quote not allowed here")
-let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
+let interp_mutual_inductive_gen env0 (uparamsl,paramsl,indl) notations cum poly prv finite =
check_all_names_different indl;
List.iter check_param paramsl;
- let env0 = Global.env() in
+ if not (List.is_empty uparamsl) && not (List.is_empty notations)
+ then user_err (str "Inductives with uniform parameters may not have attached notations.");
let pl = (List.hd indl).ind_univs in
- let sigma, decl = Univdecls.interp_univ_decl_opt env0 pl in
+ let sigma, decl = interp_univ_decl_opt env0 pl in
+ let sigma, (uimpls, ((env_uparams, ctx_uparams), useruimpls)) =
+ interp_context_evars env0 sigma uparamsl in
let sigma, (impls, ((env_params, ctx_params), userimpls)) =
- interp_context_evars env0 sigma paramsl
+ interp_context_evars ~impl_env:uimpls env_uparams sigma paramsl
in
let indnames = List.map (fun ind -> ind.ind_name) indl in
@@ -282,15 +348,15 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
let sigma, arities = List.fold_left_map (fun sigma -> interp_ind_arity env_params sigma) sigma indl in
let fullarities = List.map (fun (c, _, _) -> EConstr.it_mkProd_or_LetIn c ctx_params) arities in
- let env_ar = push_types env0 indnames fullarities in
+ let env_ar = push_types env_uparams indnames fullarities in
let env_ar_params = EConstr.push_rel_context ctx_params env_ar in
(* Compute interpretation metadatas *)
let indimpls = List.map (fun (_, _, impls) -> userimpls @
lift_implicits (Context.Rel.nhyps ctx_params) impls) arities in
let arities = List.map pi1 arities and aritypoly = List.map pi2 arities in
- let impls = compute_internalization_env env0 sigma ~impls (Inductive (params,true)) indnames fullarities indimpls in
- let ntn_impls = compute_internalization_env env0 sigma (Inductive (params,true)) indnames fullarities indimpls in
+ let impls = compute_internalization_env env_uparams sigma ~impls (Inductive (params,true)) indnames fullarities indimpls in
+ let ntn_impls = compute_internalization_env env_uparams sigma (Inductive (params,true)) indnames fullarities indimpls in
let mldatas = List.map2 (mk_mltype_data sigma env_params params) arities indnames in
let sigma, constructors =
@@ -301,23 +367,44 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
List.fold_left3_map (fun sigma -> interp_cstrs env_ar_params sigma impls) sigma mldatas arities indl)
() in
+ (* generalize over the uniform parameters *)
+ let nparams = Context.Rel.length ctx_params in
+ let nuparams = Context.Rel.length ctx_uparams in
+ let uargs = Context.Rel.to_extended_vect EConstr.mkRel 0 ctx_uparams in
+ let uparam_subst =
+ List.init (List.length indl) EConstr.(fun i -> mkApp (mkRel (i + 1 + nuparams), uargs))
+ @ List.init nuparams EConstr.(fun i -> mkRel (i + 1)) in
+ let generalize_constructor c = EConstr.Unsafe.to_constr (EConstr.Vars.substnl uparam_subst nparams c) in
+ let constructors = List.map (fun (cnames,ctypes,cimpls) ->
+ (cnames,List.map generalize_constructor ctypes,cimpls))
+ constructors
+ in
+ let ctx_params = ctx_params @ ctx_uparams in
+ let userimpls = useruimpls @ (lift_implicits (Context.Rel.nhyps ctx_uparams) userimpls) in
+ let indimpls = List.map (fun iimpl -> useruimpls @ (lift_implicits (Context.Rel.nhyps ctx_uparams) iimpl)) indimpls in
+ let fullarities = List.map (fun c -> EConstr.it_mkProd_or_LetIn c ctx_uparams) fullarities in
+ let env_ar = push_types env0 indnames fullarities in
+ let env_ar_params = EConstr.push_rel_context ctx_params env_ar in
+
(* Try further to solve evars, and instantiate them *)
- let sigma = solve_remaining_evars all_and_fail_flags env_params sigma Evd.empty in
+ let sigma = solve_remaining_evars all_and_fail_flags env_params sigma (Evd.from_env env_params) in
(* Compute renewed arities *)
- let sigma, nf = nf_evars_and_universes sigma in
+ let sigma = Evd.minimize_universes sigma in
+ let nf = Evarutil.nf_evars_universes sigma in
let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf cl,impsl)) constructors in
let arities = List.map EConstr.(to_constr sigma) arities in
let sigma = List.fold_left2 (fun sigma ty poly -> make_conclusion_flexible sigma ty poly) sigma arities aritypoly in
let sigma, arities = inductive_levels env_ar_params sigma poly arities constructors in
- let sigma, nf' = nf_evars_and_universes sigma in
- let arities = List.map nf' arities in
- let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf' cl,impsl)) constructors in
+ let sigma = Evd.minimize_universes sigma in
+ let nf = Evarutil.nf_evars_universes sigma in
+ let arities = List.map nf arities in
+ let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf cl,impsl)) constructors in
let ctx_params = List.map Termops.(map_rel_decl (EConstr.to_constr sigma)) ctx_params in
let uctx = Evd.check_univ_decl ~poly sigma decl in
- List.iter (fun c -> check_evars env_params Evd.empty sigma (EConstr.of_constr c)) arities;
- Context.Rel.iter (fun c -> check_evars env0 Evd.empty sigma (EConstr.of_constr c)) ctx_params;
+ List.iter (fun c -> check_evars env_params (Evd.from_env env_params) sigma (EConstr.of_constr c)) arities;
+ Context.Rel.iter (fun c -> check_evars env0 (Evd.from_env env0) sigma (EConstr.of_constr c)) ctx_params;
List.iter (fun (_,ctyps,_) ->
- List.iter (fun c -> check_evars env_ar_params Evd.empty sigma (EConstr.of_constr c)) ctyps)
+ List.iter (fun c -> check_evars env_ar_params (Evd.from_env env_ar_params) sigma (EConstr.of_constr c)) ctyps)
constructors;
(* Build the inductive entries *)
@@ -357,6 +444,9 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
InferCumulativity.infer_inductive env_ar mind_ent
else mind_ent), Evd.universe_binders sigma, impls
+let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
+ interp_mutual_inductive_gen (Global.env()) ([],paramsl,indl) notations cum poly prv finite
+
(* Very syntactical equality *)
let eq_local_binders bl1 bl2 =
List.equal local_binder_eq bl1 bl2
@@ -378,7 +468,7 @@ let extract_params indl =
let extract_inductive indl =
List.map (fun (({CAst.v=indname},pl),_,ar,lc) -> {
ind_name = indname; ind_univs = pl;
- ind_arity = Option.cata (fun x -> x) (CAst.make @@ CSort (GType [])) ar;
+ ind_arity = Option.cata (fun x -> x) (CAst.make @@ CSort (Glob_term.GType [])) ar;
ind_lc = List.map (fun (_,({CAst.v=id},t)) -> (id,t)) lc
}) indl
@@ -439,10 +529,15 @@ type one_inductive_impls =
Impargs.manual_explicitation list (* for inds *)*
Impargs.manual_explicitation list list (* for constrs *)
-let do_mutual_inductive indl cum poly prv finite =
- let indl,coes,ntns = extract_mutual_inductive_declaration_components indl in
+type uniform_inductive_flag =
+ | UniformParameters
+ | NonUniformParameters
+
+let do_mutual_inductive indl cum poly prv ~uniform finite =
+ let (params,indl),coes,ntns = extract_mutual_inductive_declaration_components indl in
(* Interpret the types *)
- let mie,pl,impls = interp_mutual_inductive indl ntns cum poly prv finite in
+ let indl = match uniform with UniformParameters -> (params, [], indl) | NonUniformParameters -> ([], params, indl) in
+ let mie,pl,impls = interp_mutual_inductive_gen (Global.env()) indl ntns cum poly prv finite in
(* Declare the mutual inductive block with its associated schemes *)
ignore (declare_mutual_inductive_with_eliminations mie pl impls);
(* Declare the possible notations of inductive types *)
diff --git a/vernac/comInductive.mli b/vernac/comInductive.mli
index 83393572..4e30ed7d 100644
--- a/vernac/comInductive.mli
+++ b/vernac/comInductive.mli
@@ -19,9 +19,14 @@ open Decl_kinds
(** Entry points for the vernacular commands Inductive and CoInductive *)
+type uniform_inductive_flag =
+ | UniformParameters
+ | NonUniformParameters
+
val do_mutual_inductive :
(one_inductive_expr * decl_notation list) list -> cumulative_inductive_flag ->
- polymorphic -> private_flag -> Declarations.recursivity_kind -> unit
+ polymorphic -> private_flag -> uniform:uniform_inductive_flag ->
+ Declarations.recursivity_kind -> unit
(************************************************************************)
(** Internal API *)
@@ -37,7 +42,7 @@ type one_inductive_impls =
Impargs.manual_implicits list (** for constrs *)
val declare_mutual_inductive_with_eliminations :
- mutual_inductive_entry -> Universes.universe_binders -> one_inductive_impls list ->
+ mutual_inductive_entry -> UnivNames.universe_binders -> one_inductive_impls list ->
MutInd.t
(** Exported for Funind *)
@@ -64,4 +69,4 @@ val extract_mutual_inductive_declaration_components :
val interp_mutual_inductive :
structured_inductive_expr -> decl_notation list -> cumulative_inductive_flag ->
polymorphic -> private_flag -> Declarations.recursivity_kind ->
- mutual_inductive_entry * Universes.universe_binders * one_inductive_impls list
+ mutual_inductive_entry * UnivNames.universe_binders * one_inductive_impls list
diff --git a/vernac/comProgramFixpoint.ml b/vernac/comProgramFixpoint.ml
index b95741ca..ad21a6d9 100644
--- a/vernac/comProgramFixpoint.ml
+++ b/vernac/comProgramFixpoint.ml
@@ -44,7 +44,7 @@ let mkSubset sigma name typ prop =
let sigT = Lazy.from_fun build_sigma_type
-let make_qref s = CAst.make @@ Qualid (qualid_of_string s)
+let make_qref s = qualid_of_string s
let lt_ref = make_qref "Init.Peano.lt"
let rec telescope sigma l =
@@ -91,7 +91,7 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
let lift_rel_context n l = Termops.map_rel_context_with_binders (liftn n) l in
Coqlib.check_required_library ["Coq";"Program";"Wf"];
let env = Global.env() in
- let sigma, decl = Univdecls.interp_univ_decl_opt env pl in
+ let sigma, decl = Constrexpr_ops.interp_univ_decl_opt env pl in
let sigma, (_, ((env', binders_rel), impls)) = interp_context_evars env sigma bl in
let len = List.length binders_rel in
let top_env = push_rel_context binders_rel env in
@@ -187,12 +187,12 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
let sigma, def =
let sigma, h_a_term = Evarutil.new_global sigma (delayed_force fix_sub_ref) in
let sigma, h_e_term = Evarutil.new_evar env sigma
- ~src:(Loc.tag @@ Evar_kinds.QuestionMark (Evar_kinds.Define false,Anonymous)) wf_proof in
+ ~src:(Loc.tag @@ Evar_kinds.QuestionMark {
+ Evar_kinds.default_question_mark with Evar_kinds.qm_obligation=Evar_kinds.Define false;
+ }) wf_proof in
sigma, mkApp (h_a_term, [| argtyp ; wf_rel ; h_e_term; prop |])
in
- let _evd = ref sigma in
- let def = Typing.e_solve_evars env _evd def in
- let sigma = !_evd in
+ let sigma, def = Typing.solve_evars env sigma def in
let sigma = Evarutil.nf_evar_map sigma in
let def = mkApp (def, [|intern_body_lam|]) in
let binders_rel = nf_evar_context sigma binders_rel in
@@ -214,7 +214,7 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
(** FIXME: include locality *)
let c = Declare.declare_constant recname (DefinitionEntry ce, IsDefinition Definition) in
let gr = ConstRef c in
- let () = Universes.register_universe_binders gr (Evd.universe_binders sigma) in
+ let () = UnivNames.register_universe_binders gr (Evd.universe_binders sigma) in
if Impargs.is_implicit_args () || not (List.is_empty impls) then
Impargs.declare_manual_implicits false gr [impls]
in
@@ -229,7 +229,8 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
in
(* XXX: Capturing sigma here... bad bad *)
let hook = Lemmas.mk_hook (hook sigma) in
- let fullcoqc = EConstr.to_constr sigma def in
+ (* XXX: Grounding non-ground terms here... bad bad *)
+ let fullcoqc = EConstr.to_constr ~abort_on_undefined_evars:false sigma def in
let fullctyp = EConstr.to_constr sigma typ in
Obligations.check_evars env sigma;
let evars, _, evars_def, evars_typ =
@@ -254,16 +255,17 @@ let do_program_recursive local poly fixkind fixl ntns =
interp_recursive ~cofix ~program_mode:true fixl ntns
in
(* Program-specific code *)
- (* Get the interesting evars, those that were not instanciated *)
+ (* Get the interesting evars, those that were not instantiated *)
let evd = Typeclasses.resolve_typeclasses ~filter:Typeclasses.no_goals ~fail:true env evd in
(* Solve remaining evars *)
let evd = nf_evar_map_undefined evd in
let collect_evars id def typ imps =
(* Generalize by the recursive prototypes *)
let def =
- EConstr.to_constr evd (Termops.it_mkNamedLambda_or_LetIn (EConstr.of_constr def) rec_sign)
+ EConstr.to_constr ~abort_on_undefined_evars:false evd (Termops.it_mkNamedLambda_or_LetIn (EConstr.of_constr def) rec_sign)
and typ =
- EConstr.to_constr evd (Termops.it_mkNamedProd_or_LetIn (EConstr.of_constr typ) rec_sign)
+ (* Worrying... *)
+ EConstr.to_constr ~abort_on_undefined_evars:false evd (Termops.it_mkNamedProd_or_LetIn (EConstr.of_constr typ) rec_sign)
in
let evm = collect_evars_of_term evd def typ in
let evars, _, def, typ =
diff --git a/vernac/declareDef.mli b/vernac/declareDef.mli
index 010874e2..c5e704a5 100644
--- a/vernac/declareDef.mli
+++ b/vernac/declareDef.mli
@@ -8,17 +8,17 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Decl_kinds
open Names
+open Decl_kinds
val get_locality : Id.t -> kind:string -> Decl_kinds.locality -> bool
val declare_definition : Id.t -> definition_kind ->
- Safe_typing.private_constants Entries.definition_entry -> Universes.universe_binders -> Impargs.manual_implicits ->
- Globnames.global_reference Lemmas.declaration_hook -> Globnames.global_reference
+ Safe_typing.private_constants Entries.definition_entry -> UnivNames.universe_binders -> Impargs.manual_implicits ->
+ GlobRef.t Lemmas.declaration_hook -> GlobRef.t
val declare_fix : ?opaque:bool -> definition_kind ->
- Universes.universe_binders -> Entries.constant_universes_entry ->
+ UnivNames.universe_binders -> Entries.constant_universes_entry ->
Id.t -> Safe_typing.private_constants Entries.proof_output ->
Constr.types -> Impargs.manual_implicits ->
- Globnames.global_reference
+ GlobRef.t
diff --git a/parsing/egramcoq.ml b/vernac/egramcoq.ml
index 5f63d21c..16101396 100644
--- a/parsing/egramcoq.ml
+++ b/vernac/egramcoq.ml
@@ -8,14 +8,14 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open CErrors
open Util
-open Pcoq
+open CErrors
+open Names
+open Libnames
open Constrexpr
-open Notation_term
open Extend
-open Libnames
-open Names
+open Notation_gram
+open Pcoq
(**********************************************************************)
(* This determines (depending on the associativity of the current
@@ -54,6 +54,17 @@ let default_pattern_levels =
let default_constr_levels = (default_levels, default_pattern_levels)
+let find_levels levels = function
+ | InConstrEntry -> levels, String.Map.find "constr" levels
+ | InCustomEntry s ->
+ try levels, String.Map.find s levels
+ with Not_found ->
+ String.Map.add s ([],[]) levels, ([],[])
+
+let save_levels levels custom lev =
+ let s = match custom with InConstrEntry -> "constr" | InCustomEntry s -> s in
+ String.Map.add s lev levels
+
(* At a same level, LeftA takes precedence over RightA and NoneA *)
(* In case, several associativity exists for a level, we make two levels, *)
(* first LeftA, then RightA and NoneA together *)
@@ -125,24 +136,24 @@ let rec list_mem_assoc_triple x = function
let register_empty_levels accu forpat levels =
let rec filter accu = function
| [] -> ([], accu)
- | n :: rem ->
+ | (where,n) :: rem ->
let rem, accu = filter accu rem in
- let (clev, plev) = accu in
+ let accu, (clev, plev) = find_levels accu where in
let levels = if forpat then plev else clev in
if not (list_mem_assoc_triple n levels) then
let nlev, ans = find_position_gen levels true None (Some n) in
let nlev = if forpat then (clev, nlev) else (nlev, plev) in
- ans :: rem, nlev
+ (where, ans) :: rem, save_levels accu where nlev
else rem, accu
in
filter accu levels
-let find_position accu forpat assoc level =
- let (clev, plev) = accu in
+let find_position accu custom forpat assoc level =
+ let accu, (clev, plev) = find_levels accu custom in
let levels = if forpat then plev else clev in
let nlev, ans = find_position_gen levels false assoc level in
let nlev = if forpat then (clev, nlev) else (nlev, plev) in
- (ans, nlev)
+ (ans, save_levels accu custom nlev)
(**************************************************************************)
(*
@@ -228,10 +239,10 @@ type _ target =
type prod_info = production_level * production_position
type (_, _) entry =
-| TTName : ('self, Misctypes.lname) entry
-| TTReference : ('self, reference) entry
+| TTName : ('self, lname) entry
+| TTReference : ('self, qualid) entry
| TTBigint : ('self, Constrexpr.raw_natural_number) entry
-| TTConstr : prod_info * 'r target -> ('r, 'r) entry
+| TTConstr : notation_entry * prod_info * 'r target -> ('r, 'r) entry
| TTConstrList : prod_info * Tok.t list * 'r target -> ('r, 'r list) entry
| TTPattern : int -> ('self, cases_pattern_expr) entry
| TTOpenBinderList : ('self, local_binder_expr list) entry
@@ -239,17 +250,58 @@ type (_, _) entry =
type _ any_entry = TTAny : ('s, 'r) entry -> 's any_entry
+let constr_custom_entry : (string, Constrexpr.constr_expr) entry_command =
+ create_entry_command "constr" (fun s st -> [s], st)
+let pattern_custom_entry : (string, Constrexpr.cases_pattern_expr) entry_command =
+ create_entry_command "pattern" (fun s st -> [s], st)
+
+let custom_entry_locality = Summary.ref ~name:"LOCAL-CUSTOM-ENTRY" String.Set.empty
+(** If the entry is present then local *)
+
+let create_custom_entry ~local s =
+ if List.mem s ["constr";"pattern";"ident";"global";"binder";"bigint"] then
+ user_err Pp.(quote (str s) ++ str " is a reserved entry name.");
+ let sc = "constr:"^s in
+ let sp = "pattern:"^s in
+ let _ = extend_entry_command constr_custom_entry sc in
+ let _ = extend_entry_command pattern_custom_entry sp in
+ let () = if local then custom_entry_locality := String.Set.add s !custom_entry_locality in
+ ()
+
+let find_custom_entry s =
+ let sc = "constr:"^s in
+ let sp = "pattern:"^s in
+ try (find_custom_entry constr_custom_entry sc, find_custom_entry pattern_custom_entry sp)
+ with Not_found -> user_err Pp.(str "Undeclared custom entry: " ++ str s ++ str ".")
+
+let locality_of_custom_entry s = String.Set.mem s !custom_entry_locality
+
(* This computes the name of the level where to add a new rule *)
-let interp_constr_entry_key : type r. r target -> int -> r Gram.entry * int option =
- fun forpat level -> match forpat with
+let interp_constr_entry_key : type r. _ -> r target -> int -> r Entry.t * int option =
+ fun custom forpat level ->
+ match custom with
+ | InCustomEntry s ->
+ (let (entry_for_constr, entry_for_patttern) = find_custom_entry s in
+ match forpat with
+ | ForConstr -> entry_for_constr, Some level
+ | ForPattern -> entry_for_patttern, Some level)
+ | InConstrEntry ->
+ match forpat with
| ForConstr ->
if level = 200 then Constr.binder_constr, None
else Constr.operconstr, Some level
| ForPattern -> Constr.pattern, Some level
-let target_entry : type s. s target -> s Gram.entry = function
-| ForConstr -> Constr.operconstr
-| ForPattern -> Constr.pattern
+let target_entry : type s. notation_entry -> s target -> s Entry.t = function
+| InConstrEntry ->
+ (function
+ | ForConstr -> Constr.operconstr
+ | ForPattern -> Constr.pattern)
+| InCustomEntry s ->
+ let (entry_for_constr, entry_for_patttern) = find_custom_entry s in
+ function
+ | ForConstr -> entry_for_constr
+ | ForPattern -> entry_for_patttern
let is_self from e = match e with
| (NumLevel n, BorderProd (Right, _ (* Some(NonA|LeftA) *))) -> false
@@ -273,25 +325,25 @@ let make_sep_rules = function
let r = mkrule (List.rev tkl) in
Arules [r]
-let symbol_of_target : type s. _ -> _ -> _ -> s target -> (s, s) symbol = fun p assoc from forpat ->
- if is_binder_level from p then Aentryl (target_entry forpat, 200)
+let symbol_of_target : type s. _ -> _ -> _ -> _ -> s target -> (s, s) symbol = fun custom p assoc from forpat ->
+ if custom = InConstrEntry && is_binder_level from p then Aentryl (target_entry InConstrEntry forpat, "200")
else if is_self from p then Aself
else
- let g = target_entry forpat in
+ let g = target_entry custom forpat in
let lev = adjust_level assoc from p in
begin match lev with
| None -> Aentry g
| Some None -> Anext
- | Some (Some (lev, cur)) -> Aentryl (g, lev)
+ | Some (Some (lev, cur)) -> Aentryl (g, string_of_int lev)
end
let symbol_of_entry : type s r. _ -> _ -> (s, r) entry -> (s, r) symbol = fun assoc from typ -> match typ with
-| TTConstr (p, forpat) -> symbol_of_target p assoc from forpat
+| TTConstr (s, p, forpat) -> symbol_of_target s p assoc from forpat
| TTConstrList (typ', [], forpat) ->
- Alist1 (symbol_of_target typ' assoc from forpat)
+ Alist1 (symbol_of_target InConstrEntry typ' assoc from forpat)
| TTConstrList (typ', tkl, forpat) ->
- Alist1sep (symbol_of_target typ' assoc from forpat, make_sep_rules tkl)
-| TTPattern p -> Aentryl (Constr.pattern, p)
+ Alist1sep (symbol_of_target InConstrEntry typ' assoc from forpat, make_sep_rules tkl)
+| TTPattern p -> Aentryl (Constr.pattern, string_of_int p)
| TTClosedBinderList [] -> Alist1 (Aentry Constr.binder)
| TTClosedBinderList tkl -> Alist1sep (Aentry Constr.binder, make_sep_rules tkl)
| TTName -> Aentry Prim.name
@@ -303,16 +355,15 @@ let interp_entry forpat e = match e with
| ETProdName -> TTAny TTName
| ETProdReference -> TTAny TTReference
| ETProdBigint -> TTAny TTBigint
-| ETProdConstr p -> TTAny (TTConstr (p, forpat))
+| ETProdConstr (s,p) -> TTAny (TTConstr (s, p, forpat))
| ETProdPattern p -> TTAny (TTPattern p)
-| ETProdOther _ -> assert false (** not used *)
| ETProdConstrList (p, tkl) -> TTAny (TTConstrList (p, tkl, forpat))
| ETProdBinderList ETBinderOpen -> TTAny TTOpenBinderList
| ETProdBinderList (ETBinderClosed tkl) -> TTAny (TTClosedBinderList tkl)
let cases_pattern_expr_of_name { CAst.loc; v = na } = CAst.make ?loc @@ match na with
| Anonymous -> CPatAtom None
- | Name id -> CPatAtom (Some (CAst.make ?loc @@ Ident id))
+ | Name id -> CPatAtom (Some (qualid_of_ident ?loc id))
type 'r env = {
constrs : 'r list;
@@ -420,20 +471,23 @@ let target_to_bool : type r. r target -> bool = function
| ForConstr -> false
| ForPattern -> true
-let prepare_empty_levels forpat (pos,p4assoc,name,reinit) =
+let prepare_empty_levels forpat (where,(pos,p4assoc,name,reinit)) =
let empty = (pos, [(name, p4assoc, [])]) in
- if forpat then ExtendRule (Constr.pattern, reinit, empty)
- else ExtendRule (Constr.operconstr, reinit, empty)
-
-let rec pure_sublevels : type a b c. int option -> (a, b, c) rule -> int list = fun level r -> match r with
-| Stop -> []
-| Next (rem, Aentryl (_, i)) ->
- let rem = pure_sublevels level rem in
- begin match level with
- | Some j when Int.equal i j -> rem
- | _ -> i :: rem
- end
-| Next (rem, _) -> pure_sublevels level rem
+ ExtendRule (target_entry where forpat, reinit, empty)
+
+let rec pure_sublevels' custom assoc from forpat level = function
+| [] -> []
+| GramConstrNonTerminal (e,_) :: rem ->
+ let rem = pure_sublevels' custom assoc from forpat level rem in
+ let push where p rem =
+ match symbol_of_target custom p assoc from forpat with
+ | Aentryl (_,i) when level <> Some (int_of_string i) -> (where,int_of_string i) :: rem
+ | _ -> rem in
+ (match e with
+ | ETProdPattern i -> push InConstrEntry (NumLevel i,InternalProd) rem
+ | ETProdConstr (s,p) -> push s p rem
+ | _ -> rem)
+| (GramConstrTerminal _ | GramConstrListMark _) :: rem -> pure_sublevels' custom assoc from forpat level rem
let make_act : type r. r target -> _ -> r gen_eval = function
| ForConstr -> fun notation loc env ->
@@ -444,17 +498,17 @@ let make_act : type r. r target -> _ -> r gen_eval = function
CAst.make ~loc @@ CPatNotation (notation, env, [])
let extend_constr state forpat ng =
- let n,_,_ = ng.notgram_level in
+ let custom,n,_,_ = ng.notgram_level in
let assoc = ng.notgram_assoc in
- let (entry, level) = interp_constr_entry_key forpat n in
+ let (entry, level) = interp_constr_entry_key custom forpat n in
let fold (accu, state) pt =
let AnyTyRule r = make_ty_rule assoc n forpat pt in
let symbs = ty_erase r in
- let pure_sublevels = pure_sublevels level symbs in
+ let pure_sublevels = pure_sublevels' custom assoc n forpat level pt in
let isforpat = target_to_bool forpat in
let needed_levels, state = register_empty_levels state isforpat pure_sublevels in
- let (pos,p4assoc,name,reinit), state = find_position state isforpat assoc level in
- let empty_rules = List.map (prepare_empty_levels isforpat) needed_levels in
+ let (pos,p4assoc,name,reinit), state = find_position state custom isforpat assoc level in
+ let empty_rules = List.map (prepare_empty_levels forpat) needed_levels in
let empty = { constrs = []; constrlists = []; binders = []; binderlists = [] } in
let act = ty_eval r (make_act forpat ng.notgram_notation) empty in
let rule = (name, p4assoc, [Rule (symbs, act)]) in
@@ -467,7 +521,7 @@ let constr_levels = GramState.field ()
let extend_constr_notation ng state =
let levels = match GramState.get state constr_levels with
- | None -> default_constr_levels
+ | None -> String.Map.add "constr" default_constr_levels String.Map.empty
| Some lev -> lev
in
(* Add the notation in constr *)
diff --git a/parsing/egramcoq.mli b/vernac/egramcoq.mli
index e15add10..3a6f8ae0 100644
--- a/parsing/egramcoq.mli
+++ b/vernac/egramcoq.mli
@@ -15,5 +15,8 @@
(** {5 Adding notations} *)
-val extend_constr_grammar : Notation_term.one_notation_grammar -> unit
+val extend_constr_grammar : Notation_gram.one_notation_grammar -> unit
(** Add a term notation rule to the parsing system. *)
+
+val create_custom_entry : local:bool -> string -> unit
+val locality_of_custom_entry : string -> bool
diff --git a/parsing/egramml.ml b/vernac/egramml.ml
index 90cd7d10..c5dedc88 100644
--- a/parsing/egramml.ml
+++ b/vernac/egramml.ml
@@ -64,6 +64,15 @@ let make_rule f prod =
let act = ty_eval ty_rule f in
Extend.Rule (symb, act)
+let rec proj_symbol : type a b c. (a, b, c) ty_user_symbol -> (a, b, c) genarg_type = function
+| TUentry a -> ExtraArg a
+| TUentryl (a,l) -> ExtraArg a
+| TUopt(o) -> OptArg (proj_symbol o)
+| TUlist1 l -> ListArg (proj_symbol l)
+| TUlist1sep (l,_) -> ListArg (proj_symbol l)
+| TUlist0 l -> ListArg (proj_symbol l)
+| TUlist0sep (l,_) -> ListArg (proj_symbol l)
+
(** Vernac grammar extensions *)
let vernac_exts = ref []
@@ -77,7 +86,7 @@ let get_extend_vernac_rule (s, i) =
| Failure _ -> raise Not_found
let extend_vernac_command_grammar s nt gl =
- let nt = Option.default Vernac_.command nt in
+ let nt = Option.default Pvernac.Vernac_.command nt in
vernac_exts := (s,gl) :: !vernac_exts;
let mkact loc l = VernacExtend (s, l) in
let rules = [make_rule mkact gl] in
diff --git a/parsing/egramml.mli b/vernac/egramml.mli
index 31aa1a98..c4f4fcfa 100644
--- a/parsing/egramml.mli
+++ b/vernac/egramml.mli
@@ -21,11 +21,13 @@ type 's grammar_prod_item =
('s, 'a) Extend.symbol) Loc.located -> 's grammar_prod_item
val extend_vernac_command_grammar :
- Vernacexpr.extend_name -> vernac_expr Pcoq.Gram.entry option ->
+ Vernacexpr.extend_name -> vernac_expr Pcoq.Entry.t option ->
vernac_expr grammar_prod_item list -> unit
val get_extend_vernac_rule : Vernacexpr.extend_name -> vernac_expr grammar_prod_item list
+val proj_symbol : ('a, 'b, 'c) Extend.ty_user_symbol -> ('a, 'b, 'c) Genarg.genarg_type
+
(** Utility function reused in Egramcoq : *)
val make_rule :
diff --git a/vernac/explainErr.ml b/vernac/explainErr.ml
index f9167f96..7cf4e648 100644
--- a/vernac/explainErr.ml
+++ b/vernac/explainErr.ml
@@ -55,7 +55,7 @@ let process_vernac_interp_error exn = match fst exn with
let msg =
if !Constrextern.print_universes then
str "." ++ spc() ++
- Univ.explain_universe_inconsistency Universes.pr_with_global_universes i
+ Univ.explain_universe_inconsistency UnivNames.pr_with_global_universes i
else
mt() in
wrap_vernac_error exn (str "Universe inconsistency" ++ msg ++ str ".")
@@ -64,8 +64,12 @@ let process_vernac_interp_error exn = match fst exn with
wrap_vernac_error exn (Himsg.explain_type_error ctx Evd.empty te)
| PretypeError(ctx,sigma,te) ->
wrap_vernac_error exn (Himsg.explain_pretype_error ctx sigma te)
+ | Notation.NumeralNotationError(ctx,sigma,te) ->
+ wrap_vernac_error exn (Himsg.explain_numeral_notation_error ctx sigma te)
| Typeclasses_errors.TypeClassError(env, te) ->
wrap_vernac_error exn (Himsg.explain_typeclass_error env te)
+ | Implicit_quantifiers.MismatchedContextInstance(e,c,l,x) ->
+ wrap_vernac_error exn (Himsg.explain_mismatched_contexts e c l x)
| InductiveError e ->
wrap_vernac_error exn (Himsg.explain_inductive_error e)
| Modops.ModuleTypingError e ->
diff --git a/vernac/g_proofs.mlg b/vernac/g_proofs.mlg
new file mode 100644
index 00000000..ecc7d3ff
--- /dev/null
+++ b/vernac/g_proofs.mlg
@@ -0,0 +1,140 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+{
+
+open Glob_term
+open Constrexpr
+open Vernacexpr
+open Hints
+open Proof_global
+
+open Pcoq
+open Pcoq.Prim
+open Pcoq.Constr
+open Pvernac.Vernac_
+
+let thm_token = G_vernac.thm_token
+
+let hint = Entry.create "hint"
+
+let warn_deprecated_focus =
+ CWarnings.create ~name:"deprecated-focus" ~category:"deprecated"
+ (fun () ->
+ Pp.strbrk
+ "The Focus command is deprecated; use bullets or focusing brackets instead"
+ )
+
+let warn_deprecated_focus_n n =
+ CWarnings.create ~name:"deprecated-focus" ~category:"deprecated"
+ (fun () ->
+ Pp.(str "The Focus command is deprecated;" ++ spc ()
+ ++ str "use '" ++ int n ++ str ": {' instead")
+ )
+
+let warn_deprecated_unfocus =
+ CWarnings.create ~name:"deprecated-unfocus" ~category:"deprecated"
+ (fun () -> Pp.strbrk "The Unfocus command is deprecated")
+
+}
+
+(* Proof commands *)
+GRAMMAR EXTEND Gram
+ GLOBAL: hint command;
+
+ opt_hintbases:
+ [ [ -> { [] }
+ | ":"; l = LIST1 [id = IDENT -> { id } ] -> { l } ] ]
+ ;
+ command:
+ [ [ IDENT "Goal"; c = lconstr ->
+ { VernacDefinition (Decl_kinds.(NoDischarge, Definition), ((CAst.make ~loc Names.Anonymous), None), ProveBody ([], c)) }
+ | IDENT "Proof" -> { VernacProof (None,None) }
+ | IDENT "Proof" ; IDENT "Mode" ; mn = string -> { VernacProofMode mn }
+ | IDENT "Proof"; c = lconstr -> { VernacExactProof c }
+ | IDENT "Abort" -> { VernacAbort None }
+ | IDENT "Abort"; IDENT "All" -> { VernacAbortAll }
+ | IDENT "Abort"; id = identref -> { VernacAbort (Some id) }
+ | IDENT "Existential"; n = natural; c = constr_body ->
+ { VernacSolveExistential (n,c) }
+ | IDENT "Admitted" -> { VernacEndProof Admitted }
+ | IDENT "Qed" -> { VernacEndProof (Proved (Opaque,None)) }
+ | IDENT "Save"; id = identref ->
+ { VernacEndProof (Proved (Opaque, Some id)) }
+ | IDENT "Defined" -> { VernacEndProof (Proved (Transparent,None)) }
+ | IDENT "Defined"; id=identref ->
+ { VernacEndProof (Proved (Transparent,Some id)) }
+ | IDENT "Restart" -> { VernacRestart }
+ | IDENT "Undo" -> { VernacUndo 1 }
+ | IDENT "Undo"; n = natural -> { VernacUndo n }
+ | IDENT "Undo"; IDENT "To"; n = natural -> { VernacUndoTo n }
+ | IDENT "Focus" ->
+ { warn_deprecated_focus ~loc ();
+ VernacFocus None }
+ | IDENT "Focus"; n = natural ->
+ { warn_deprecated_focus_n n ~loc ();
+ VernacFocus (Some n) }
+ | IDENT "Unfocus" ->
+ { warn_deprecated_unfocus ~loc ();
+ VernacUnfocus }
+ | IDENT "Unfocused" -> { VernacUnfocused }
+ | IDENT "Show" -> { VernacShow (ShowGoal OpenSubgoals) }
+ | IDENT "Show"; n = natural -> { VernacShow (ShowGoal (NthGoal n)) }
+ | IDENT "Show"; id = ident -> { VernacShow (ShowGoal (GoalId id)) }
+ | IDENT "Show"; IDENT "Script" -> { VernacShow ShowScript }
+ | IDENT "Show"; IDENT "Existentials" -> { VernacShow ShowExistentials }
+ | IDENT "Show"; IDENT "Universes" -> { VernacShow ShowUniverses }
+ | IDENT "Show"; IDENT "Conjectures" -> { VernacShow ShowProofNames }
+ | IDENT "Show"; IDENT "Proof" -> { VernacShow ShowProof }
+ | IDENT "Show"; IDENT "Intro" -> { VernacShow (ShowIntros false) }
+ | IDENT "Show"; IDENT "Intros" -> { VernacShow (ShowIntros true) }
+ | IDENT "Show"; IDENT "Match"; id = reference -> { VernacShow (ShowMatch id) }
+ | IDENT "Guarded" -> { VernacCheckGuard }
+ (* Hints for Auto and EAuto *)
+ | IDENT "Create"; IDENT "HintDb" ;
+ id = IDENT ; b = [ "discriminated" -> { true } | -> { false } ] ->
+ { VernacCreateHintDb (id, b) }
+ | IDENT "Remove"; IDENT "Hints"; ids = LIST1 global; dbnames = opt_hintbases ->
+ { VernacRemoveHints (dbnames, ids) }
+ | IDENT "Hint"; h = hint; dbnames = opt_hintbases ->
+ { VernacHints (dbnames, h) }
+ ] ];
+ reference_or_constr:
+ [ [ r = global -> { HintsReference r }
+ | c = constr -> { HintsConstr c } ] ]
+ ;
+ hint:
+ [ [ IDENT "Resolve"; lc = LIST1 reference_or_constr; info = hint_info ->
+ { HintsResolve (List.map (fun x -> (info, true, x)) lc) }
+ | IDENT "Resolve"; "->"; lc = LIST1 global; n = OPT natural ->
+ { HintsResolveIFF (true, lc, n) }
+ | IDENT "Resolve"; "<-"; lc = LIST1 global; n = OPT natural ->
+ { HintsResolveIFF (false, lc, n) }
+ | IDENT "Immediate"; lc = LIST1 reference_or_constr -> { HintsImmediate lc }
+ | IDENT "Variables"; IDENT "Transparent" -> { HintsTransparency (HintsVariables, true) }
+ | IDENT "Variables"; IDENT "Opaque" -> { HintsTransparency (HintsVariables, false) }
+ | IDENT "Constants"; IDENT "Transparent" -> { HintsTransparency (HintsConstants, true) }
+ | IDENT "Constants"; IDENT "Opaque" -> { HintsTransparency (HintsConstants, false) }
+ | IDENT "Transparent"; lc = LIST1 global -> { HintsTransparency (HintsReferences lc, true) }
+ | IDENT "Opaque"; lc = LIST1 global -> { HintsTransparency (HintsReferences lc, false) }
+ | IDENT "Mode"; l = global; m = mode -> { HintsMode (l, m) }
+ | IDENT "Unfold"; lqid = LIST1 global -> { HintsUnfold lqid }
+ | IDENT "Constructors"; lc = LIST1 global -> { HintsConstructors lc } ] ]
+ ;
+ constr_body:
+ [ [ ":="; c = lconstr -> { c }
+ | ":"; t = lconstr; ":="; c = lconstr -> { CAst.make ~loc @@ CCast(c,CastConv t) } ] ]
+ ;
+ mode:
+ [ [ l = LIST1 [ "+" -> { ModeInput }
+ | "!" -> { ModeNoHeadEvar }
+ | "-" -> { ModeOutput } ] -> { l } ] ]
+ ;
+END
diff --git a/vernac/g_vernac.mlg b/vernac/g_vernac.mlg
new file mode 100644
index 00000000..ecd19c47
--- /dev/null
+++ b/vernac/g_vernac.mlg
@@ -0,0 +1,1208 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+{
+
+open Pp
+open CErrors
+open Util
+open Names
+open Glob_term
+open Vernacexpr
+open Constrexpr
+open Constrexpr_ops
+open Extend
+open Decl_kinds
+open Declaremods
+open Declarations
+open Namegen
+open Tok (* necessary for camlp5 *)
+
+open Pcoq
+open Pcoq.Prim
+open Pcoq.Constr
+open Pcoq.Module
+open Pvernac.Vernac_
+
+let vernac_kw = [ ";"; ","; ">->"; ":<"; "<:"; "where"; "at" ]
+let _ = List.iter CLexer.add_keyword vernac_kw
+
+(* Rem: do not join the different GEXTEND into one, it breaks native *)
+(* compilation on PowerPC and Sun architectures *)
+
+let query_command = Entry.create "vernac:query_command"
+
+let subprf = Entry.create "vernac:subprf"
+
+let class_rawexpr = Entry.create "vernac:class_rawexpr"
+let thm_token = Entry.create "vernac:thm_token"
+let def_body = Entry.create "vernac:def_body"
+let decl_notation = Entry.create "vernac:decl_notation"
+let record_field = Entry.create "vernac:record_field"
+let of_type_with_opt_coercion = Entry.create "vernac:of_type_with_opt_coercion"
+let instance_name = Entry.create "vernac:instance_name"
+let section_subset_expr = Entry.create "vernac:section_subset_expr"
+
+let make_bullet s =
+ let open Proof_bullet in
+ let n = String.length s in
+ match s.[0] with
+ | '-' -> Dash n
+ | '+' -> Plus n
+ | '*' -> Star n
+ | _ -> assert false
+
+let parse_compat_version = let open Flags in function
+ | "8.9" -> Current
+ | "8.8" -> V8_8
+ | "8.7" -> V8_7
+ | ("8.6" | "8.5" | "8.4" | "8.3" | "8.2" | "8.1" | "8.0") as s ->
+ CErrors.user_err ~hdr:"get_compat_version"
+ Pp.(str "Compatibility with version " ++ str s ++ str " not supported.")
+ | s ->
+ CErrors.user_err ~hdr:"get_compat_version"
+ Pp.(str "Unknown compatibility version \"" ++ str s ++ str "\".")
+
+}
+
+GRAMMAR EXTEND Gram
+ GLOBAL: vernac_control gallina_ext noedit_mode subprf;
+ vernac_control: FIRST
+ [ [ IDENT "Time"; c = located_vernac -> { VernacTime (false,c) }
+ | IDENT "Redirect"; s = ne_string; c = located_vernac -> { VernacRedirect (s, c) }
+ | IDENT "Timeout"; n = natural; v = vernac_control -> { VernacTimeout(n,v) }
+ | IDENT "Fail"; v = vernac_control -> { VernacFail v }
+ | v = decorated_vernac -> { let (f, v) = v in VernacExpr(f, v) } ]
+ ]
+ ;
+ decorated_vernac:
+ [ [ a = attributes ; fv = vernac -> { let (f, v) = fv in (List.append a f, v) }
+ | fv = vernac -> { fv } ]
+ ]
+ ;
+ attributes:
+ [ [ "#[" ; a = attribute_list ; "]" -> { a } ]
+ ]
+ ;
+ attribute_list:
+ [ [ a = LIST0 attribute SEP "," -> { a } ]
+ ]
+ ;
+ attribute:
+ [ [ k = ident ; v = attribute_value -> { Names.Id.to_string k, v } ]
+ ]
+ ;
+ attribute_value:
+ [ [ "=" ; v = string -> { VernacFlagLeaf v }
+ | "(" ; a = attribute_list ; ")" -> { VernacFlagList a }
+ | -> { VernacFlagEmpty } ]
+ ]
+ ;
+ vernac:
+ [ [ IDENT "Local"; v = vernac_poly -> { let (f, v) = v in (("local", VernacFlagEmpty) :: f, v) }
+ | IDENT "Global"; v = vernac_poly -> { let (f, v) = v in (("global", VernacFlagEmpty) :: f, v) }
+
+ | v = vernac_poly -> { v } ]
+ ]
+ ;
+ vernac_poly:
+ [ [ IDENT "Polymorphic"; v = vernac_aux -> { let (f, v) = v in (("polymorphic", VernacFlagEmpty) :: f, v) }
+ | IDENT "Monomorphic"; v = vernac_aux -> { let (f, v) = v in (("monomorphic", VernacFlagEmpty) :: f, v) }
+ | v = vernac_aux -> { v } ]
+ ]
+ ;
+ vernac_aux:
+ (* Better to parse "." here: in case of failure (e.g. in coerce_to_var), *)
+ (* "." is still in the stream and discard_to_dot works correctly *)
+ [ [ IDENT "Program"; g = gallina; "." -> { (["program", VernacFlagEmpty], g) }
+ | IDENT "Program"; g = gallina_ext; "." -> { (["program", VernacFlagEmpty], g) }
+ | g = gallina; "." -> { ([], g) }
+ | g = gallina_ext; "." -> { ([], g) }
+ | c = command; "." -> { ([], c) }
+ | c = syntax; "." -> { ([], c) }
+ | c = subprf -> { ([], c) }
+ ] ]
+ ;
+ vernac_aux: LAST
+ [ [ prfcom = command_entry -> { ([], prfcom) } ] ]
+ ;
+ noedit_mode:
+ [ [ c = query_command -> { c None } ] ]
+ ;
+
+ subprf:
+ [ [ s = BULLET -> { VernacBullet (make_bullet s) }
+ | "{" -> { VernacSubproof None }
+ | "}" -> { VernacEndSubproof }
+ ] ]
+ ;
+
+ located_vernac:
+ [ [ v = vernac_control -> { CAst.make ~loc v } ] ]
+ ;
+END
+
+{
+
+let warn_plural_command =
+ CWarnings.create ~name:"plural-command" ~category:"pedantic" ~default:CWarnings.Disabled
+ (fun kwd -> strbrk (Printf.sprintf "Command \"%s\" expects more than one assumption." kwd))
+
+let test_plural_form loc kwd = function
+ | [(_,([_],_))] ->
+ warn_plural_command ~loc kwd
+ | _ -> ()
+
+let test_plural_form_types loc kwd = function
+ | [([_],_)] ->
+ warn_plural_command ~loc kwd
+ | _ -> ()
+
+let lname_of_lident : lident -> lname =
+ CAst.map (fun s -> Name s)
+
+let name_of_ident_decl : ident_decl -> name_decl =
+ on_fst lname_of_lident
+
+}
+
+(* Gallina declarations *)
+GRAMMAR EXTEND Gram
+ GLOBAL: gallina gallina_ext thm_token def_body of_type_with_opt_coercion
+ record_field decl_notation rec_definition ident_decl univ_decl;
+
+ gallina:
+ (* Definition, Theorem, Variable, Axiom, ... *)
+ [ [ thm = thm_token; id = ident_decl; bl = binders; ":"; c = lconstr;
+ l = LIST0
+ [ "with"; id = ident_decl; bl = binders; ":"; c = lconstr ->
+ { (id,(bl,c)) } ] ->
+ { VernacStartTheoremProof (thm, (id,(bl,c))::l) }
+ | stre = assumption_token; nl = inline; bl = assum_list ->
+ { VernacAssumption (stre, nl, bl) }
+ | tk = assumptions_token; nl = inline; bl = assum_list ->
+ { let (kwd,stre) = tk in
+ test_plural_form loc kwd bl;
+ VernacAssumption (stre, nl, bl) }
+ | d = def_token; id = ident_decl; b = def_body ->
+ { VernacDefinition (d, name_of_ident_decl id, b) }
+ | IDENT "Let"; id = identref; b = def_body ->
+ { VernacDefinition ((DoDischarge, Let), (lname_of_lident id, None), b) }
+ (* Gallina inductive declarations *)
+ | cum = OPT cumulativity_token; priv = private_token; f = finite_token;
+ indl = LIST1 inductive_definition SEP "with" ->
+ { let (k,f) = f in
+ let indl=List.map (fun ((a,b,c,d),e) -> ((a,b,c,k,d),e)) indl in
+ VernacInductive (cum, priv,f,indl) }
+ | "Fixpoint"; recs = LIST1 rec_definition SEP "with" ->
+ { VernacFixpoint (NoDischarge, recs) }
+ | IDENT "Let"; "Fixpoint"; recs = LIST1 rec_definition SEP "with" ->
+ { VernacFixpoint (DoDischarge, recs) }
+ | "CoFixpoint"; corecs = LIST1 corec_definition SEP "with" ->
+ { VernacCoFixpoint (NoDischarge, corecs) }
+ | IDENT "Let"; "CoFixpoint"; corecs = LIST1 corec_definition SEP "with" ->
+ { VernacCoFixpoint (DoDischarge, corecs) }
+ | IDENT "Scheme"; l = LIST1 scheme SEP "with" -> { VernacScheme l }
+ | IDENT "Combined"; IDENT "Scheme"; id = identref; IDENT "from";
+ l = LIST1 identref SEP "," -> { VernacCombinedScheme (id, l) }
+ | IDENT "Register"; IDENT "Inline"; id = identref ->
+ { VernacRegister(id, RegisterInline) }
+ | IDENT "Universe"; l = LIST1 identref -> { VernacUniverse l }
+ | IDENT "Universes"; l = LIST1 identref -> { VernacUniverse l }
+ | IDENT "Constraint"; l = LIST1 univ_constraint SEP "," -> { VernacConstraint l }
+ ] ]
+ ;
+
+ thm_token:
+ [ [ "Theorem" -> { Theorem }
+ | IDENT "Lemma" -> { Lemma }
+ | IDENT "Fact" -> { Fact }
+ | IDENT "Remark" -> { Remark }
+ | IDENT "Corollary" -> { Corollary }
+ | IDENT "Proposition" -> { Proposition }
+ | IDENT "Property" -> { Property } ] ]
+ ;
+ def_token:
+ [ [ "Definition" -> { (NoDischarge,Definition) }
+ | IDENT "Example" -> { (NoDischarge,Example) }
+ | IDENT "SubClass" -> { (NoDischarge,SubClass) } ] ]
+ ;
+ assumption_token:
+ [ [ "Hypothesis" -> { (DoDischarge, Logical) }
+ | "Variable" -> { (DoDischarge, Definitional) }
+ | "Axiom" -> { (NoDischarge, Logical) }
+ | "Parameter" -> { (NoDischarge, Definitional) }
+ | IDENT "Conjecture" -> { (NoDischarge, Conjectural) } ] ]
+ ;
+ assumptions_token:
+ [ [ IDENT "Hypotheses" -> { ("Hypotheses", (DoDischarge, Logical)) }
+ | IDENT "Variables" -> { ("Variables", (DoDischarge, Definitional)) }
+ | IDENT "Axioms" -> { ("Axioms", (NoDischarge, Logical)) }
+ | IDENT "Parameters" -> { ("Parameters", (NoDischarge, Definitional)) }
+ | IDENT "Conjectures" -> { ("Conjectures", (NoDischarge, Conjectural)) } ] ]
+ ;
+ inline:
+ [ [ IDENT "Inline"; "("; i = INT; ")" -> { InlineAt (int_of_string i) }
+ | IDENT "Inline" -> { DefaultInline }
+ | -> { NoInline } ] ]
+ ;
+ univ_constraint:
+ [ [ l = universe_level; ord = [ "<" -> { Univ.Lt } | "=" -> { Univ.Eq } | "<=" -> { Univ.Le } ];
+ r = universe_level -> { (l, ord, r) } ] ]
+ ;
+ univ_decl :
+ [ [ "@{" ; l = LIST0 identref; ext = [ "+" -> { true } | -> { false } ];
+ cs = [ "|"; l' = LIST0 univ_constraint SEP ",";
+ ext = [ "+" -> { true } | -> { false } ]; "}" -> { (l',ext) }
+ | ext = [ "}" -> { true } | "|}" -> { false } ] -> { ([], ext) } ]
+ ->
+ { let open UState in
+ { univdecl_instance = l;
+ univdecl_extensible_instance = ext;
+ univdecl_constraints = fst cs;
+ univdecl_extensible_constraints = snd cs } }
+ ] ]
+ ;
+ ident_decl:
+ [ [ i = identref; l = OPT univ_decl -> { (i, l) }
+ ] ]
+ ;
+ finite_token:
+ [ [ IDENT "Inductive" -> { (Inductive_kw,Finite) }
+ | IDENT "CoInductive" -> { (CoInductive,CoFinite) }
+ | IDENT "Variant" -> { (Variant,BiFinite) }
+ | IDENT "Record" -> { (Record,BiFinite) }
+ | IDENT "Structure" -> { (Structure,BiFinite) }
+ | IDENT "Class" -> { (Class true,BiFinite) } ] ]
+ ;
+ cumulativity_token:
+ [ [ IDENT "Cumulative" -> { VernacCumulative }
+ | IDENT "NonCumulative" -> { VernacNonCumulative } ] ]
+ ;
+ private_token:
+ [ [ IDENT "Private" -> { true } | -> { false } ] ]
+ ;
+ (* Simple definitions *)
+ def_body:
+ [ [ bl = binders; ":="; red = reduce; c = lconstr ->
+ { if List.exists (function CLocalPattern _ -> true | _ -> false) bl
+ then
+ (* FIXME: "red" will be applied to types in bl and Cast with remain *)
+ let c = mkCLambdaN ~loc bl c in
+ DefineBody ([], red, c, None)
+ else
+ (match c with
+ | { CAst.v = CCast(c, CastConv t) } -> DefineBody (bl, red, c, Some t)
+ | _ -> DefineBody (bl, red, c, None)) }
+ | bl = binders; ":"; t = lconstr; ":="; red = reduce; c = lconstr ->
+ { let ((bl, c), tyo) =
+ if List.exists (function CLocalPattern _ -> true | _ -> false) bl
+ then
+ (* FIXME: "red" will be applied to types in bl and Cast with remain *)
+ let c = CAst.make ~loc @@ CCast (c, CastConv t) in
+ (([],mkCLambdaN ~loc bl c), None)
+ else ((bl, c), Some t)
+ in
+ DefineBody (bl, red, c, tyo) }
+ | bl = binders; ":"; t = lconstr ->
+ { ProveBody (bl, t) } ] ]
+ ;
+ reduce:
+ [ [ IDENT "Eval"; r = red_expr; "in" -> { Some r }
+ | -> { None } ] ]
+ ;
+ one_decl_notation:
+ [ [ ntn = ne_lstring; ":="; c = constr;
+ scopt = OPT [ ":"; sc = IDENT -> { sc } ] -> { (ntn,c,scopt) } ] ]
+ ;
+ decl_sep:
+ [ [ IDENT "and" -> { () } ] ]
+ ;
+ decl_notation:
+ [ [ "where"; l = LIST1 one_decl_notation SEP decl_sep -> { l }
+ | -> { [] } ] ]
+ ;
+ (* Inductives and records *)
+ opt_constructors_or_fields:
+ [ [ ":="; lc = constructor_list_or_record_decl -> { lc }
+ | -> { RecordDecl (None, []) } ] ]
+ ;
+ inductive_definition:
+ [ [ oc = opt_coercion; id = ident_decl; indpar = binders;
+ c = OPT [ ":"; c = lconstr -> { c } ];
+ lc=opt_constructors_or_fields; ntn = decl_notation ->
+ { (((oc,id),indpar,c,lc),ntn) } ] ]
+ ;
+ constructor_list_or_record_decl:
+ [ [ "|"; l = LIST1 constructor SEP "|" -> { Constructors l }
+ | id = identref ; c = constructor_type; "|"; l = LIST0 constructor SEP "|" ->
+ { Constructors ((c id)::l) }
+ | id = identref ; c = constructor_type -> { Constructors [ c id ] }
+ | cstr = identref; "{"; fs = record_fields; "}" ->
+ { RecordDecl (Some cstr,fs) }
+ | "{";fs = record_fields; "}" -> { RecordDecl (None,fs) }
+ | -> { Constructors [] } ] ]
+ ;
+(*
+ csort:
+ [ [ s = sort -> CSort (loc,s) ] ]
+ ;
+*)
+ opt_coercion:
+ [ [ ">" -> { true }
+ | -> { false } ] ]
+ ;
+ (* (co)-fixpoints *)
+ rec_definition:
+ [ [ id = ident_decl;
+ bl = binders_fixannot;
+ ty = type_cstr;
+ def = OPT [":="; def = lconstr -> { def } ]; ntn = decl_notation ->
+ { let bl, annot = bl in ((id,annot,bl,ty,def),ntn) } ] ]
+ ;
+ corec_definition:
+ [ [ id = ident_decl; bl = binders; ty = type_cstr;
+ def = OPT [":="; def = lconstr -> { def }]; ntn = decl_notation ->
+ { ((id,bl,ty,def),ntn) } ] ]
+ ;
+ type_cstr:
+ [ [ ":"; c=lconstr -> { c }
+ | -> { CAst.make ~loc @@ CHole (None, IntroAnonymous, None) } ] ]
+ ;
+ (* Inductive schemes *)
+ scheme:
+ [ [ kind = scheme_kind -> { (None,kind) }
+ | id = identref; ":="; kind = scheme_kind -> { (Some id,kind) } ] ]
+ ;
+ scheme_kind:
+ [ [ IDENT "Induction"; "for"; ind = smart_global;
+ IDENT "Sort"; s = sort_family-> { InductionScheme(true,ind,s) }
+ | IDENT "Minimality"; "for"; ind = smart_global;
+ IDENT "Sort"; s = sort_family-> { InductionScheme(false,ind,s) }
+ | IDENT "Elimination"; "for"; ind = smart_global;
+ IDENT "Sort"; s = sort_family-> { CaseScheme(true,ind,s) }
+ | IDENT "Case"; "for"; ind = smart_global;
+ IDENT "Sort"; s = sort_family-> { CaseScheme(false,ind,s) }
+ | IDENT "Equality"; "for" ; ind = smart_global -> { EqualityScheme(ind) } ] ]
+ ;
+ (* Various Binders *)
+(*
+ (* ... without coercions *)
+ binder_nodef:
+ [ [ b = binder_let ->
+ (match b with
+ CLocalAssum(l,ty) -> (l,ty)
+ | CLocalDef _ ->
+ Util.user_err_loc
+ (loc,"fix_param",Pp.str"defined binder not allowed here.")) ] ]
+ ;
+*)
+ (* ... with coercions *)
+ record_field:
+ [ [ bd = record_binder; pri = OPT [ "|"; n = natural -> { n } ];
+ ntn = decl_notation -> { (bd,pri),ntn } ] ]
+ ;
+ record_fields:
+ [ [ f = record_field; ";"; fs = record_fields -> { f :: fs }
+ | f = record_field; ";" -> { [f] }
+ | f = record_field -> { [f] }
+ | -> { [] }
+ ] ]
+ ;
+ record_binder_body:
+ [ [ l = binders; oc = of_type_with_opt_coercion;
+ t = lconstr -> { fun id -> (oc,AssumExpr (id,mkCProdN ~loc l t)) }
+ | l = binders; oc = of_type_with_opt_coercion;
+ t = lconstr; ":="; b = lconstr -> { fun id ->
+ (oc,DefExpr (id,mkCLambdaN ~loc l b,Some (mkCProdN ~loc l t))) }
+ | l = binders; ":="; b = lconstr -> { fun id ->
+ match b.CAst.v with
+ | CCast(b', (CastConv t|CastVM t|CastNative t)) ->
+ (None,DefExpr(id,mkCLambdaN ~loc l b',Some (mkCProdN ~loc l t)))
+ | _ ->
+ (None,DefExpr(id,mkCLambdaN ~loc l b,None)) } ] ]
+ ;
+ record_binder:
+ [ [ id = name -> { (None,AssumExpr(id, CAst.make ~loc @@ CHole (None, IntroAnonymous, None))) }
+ | id = name; f = record_binder_body -> { f id } ] ]
+ ;
+ assum_list:
+ [ [ bl = LIST1 assum_coe -> { bl } | b = simple_assum_coe -> { [b] } ] ]
+ ;
+ assum_coe:
+ [ [ "("; a = simple_assum_coe; ")" -> { a } ] ]
+ ;
+ simple_assum_coe:
+ [ [ idl = LIST1 ident_decl; oc = of_type_with_opt_coercion; c = lconstr ->
+ { (not (Option.is_empty oc),(idl,c)) } ] ]
+ ;
+
+ constructor_type:
+ [[ l = binders;
+ t= [ coe = of_type_with_opt_coercion; c = lconstr ->
+ { fun l id -> (not (Option.is_empty coe),(id,mkCProdN ~loc l c)) }
+ | ->
+ { fun l id -> (false,(id,mkCProdN ~loc l (CAst.make ~loc @@ CHole (None, IntroAnonymous, None)))) } ]
+ -> { t l }
+ ]]
+;
+
+ constructor:
+ [ [ id = identref; c=constructor_type -> { c id } ] ]
+ ;
+ of_type_with_opt_coercion:
+ [ [ ":>>" -> { Some false }
+ | ":>"; ">" -> { Some false }
+ | ":>" -> { Some true }
+ | ":"; ">"; ">" -> { Some false }
+ | ":"; ">" -> { Some true }
+ | ":" -> { None } ] ]
+ ;
+END
+
+{
+
+let only_starredidentrefs =
+ Gram.Entry.of_parser "test_only_starredidentrefs"
+ (fun strm ->
+ let rec aux n =
+ match Util.stream_nth n strm with
+ | KEYWORD "." -> ()
+ | KEYWORD ")" -> ()
+ | (IDENT _ | KEYWORD "Type" | KEYWORD "*") -> aux (n+1)
+ | _ -> raise Stream.Failure in
+ aux 0)
+let starredidentreflist_to_expr l =
+ match l with
+ | [] -> SsEmpty
+ | x :: xs -> List.fold_right (fun i acc -> SsUnion(i,acc)) xs x
+
+let warn_deprecated_include_type =
+ CWarnings.create ~name:"deprecated-include-type" ~category:"deprecated"
+ (fun () -> strbrk "Include Type is deprecated; use Include instead")
+
+}
+
+(* Modules and Sections *)
+GRAMMAR EXTEND Gram
+ GLOBAL: gallina_ext module_expr module_type section_subset_expr;
+
+ gallina_ext:
+ [ [ (* Interactive module declaration *)
+ IDENT "Module"; export = export_token; id = identref;
+ bl = LIST0 module_binder; sign = of_module_type;
+ body = is_module_expr ->
+ { VernacDefineModule (export, id, bl, sign, body) }
+ | IDENT "Module"; "Type"; id = identref;
+ bl = LIST0 module_binder; sign = check_module_types;
+ body = is_module_type ->
+ { VernacDeclareModuleType (id, bl, sign, body) }
+ | IDENT "Declare"; IDENT "Module"; export = export_token; id = identref;
+ bl = LIST0 module_binder; ":"; mty = module_type_inl ->
+ { VernacDeclareModule (export, id, bl, mty) }
+ (* Section beginning *)
+ | IDENT "Section"; id = identref -> { VernacBeginSection id }
+ | IDENT "Chapter"; id = identref -> { VernacBeginSection id }
+
+ (* This end a Section a Module or a Module Type *)
+ | IDENT "End"; id = identref -> { VernacEndSegment id }
+
+ (* Naming a set of section hyps *)
+ | IDENT "Collection"; id = identref; ":="; expr = section_subset_expr ->
+ { VernacNameSectionHypSet (id, expr) }
+
+ (* Requiring an already compiled module *)
+ | IDENT "Require"; export = export_token; qidl = LIST1 global ->
+ { VernacRequire (None, export, qidl) }
+ | IDENT "From" ; ns = global ; IDENT "Require"; export = export_token
+ ; qidl = LIST1 global ->
+ { VernacRequire (Some ns, export, qidl) }
+ | IDENT "Import"; qidl = LIST1 global -> { VernacImport (false,qidl) }
+ | IDENT "Export"; qidl = LIST1 global -> { VernacImport (true,qidl) }
+ | IDENT "Include"; e = module_type_inl; l = LIST0 ext_module_expr ->
+ { VernacInclude(e::l) }
+ | IDENT "Include"; "Type"; e = module_type_inl; l = LIST0 ext_module_type ->
+ { warn_deprecated_include_type ~loc ();
+ VernacInclude(e::l) } ] ]
+ ;
+ export_token:
+ [ [ IDENT "Import" -> { Some false }
+ | IDENT "Export" -> { Some true }
+ | -> { None } ] ]
+ ;
+ ext_module_type:
+ [ [ "<+"; mty = module_type_inl -> { mty } ] ]
+ ;
+ ext_module_expr:
+ [ [ "<+"; mexpr = module_expr_inl -> { mexpr } ] ]
+ ;
+ check_module_type:
+ [ [ "<:"; mty = module_type_inl -> { mty } ] ]
+ ;
+ check_module_types:
+ [ [ mtys = LIST0 check_module_type -> { mtys } ] ]
+ ;
+ of_module_type:
+ [ [ ":"; mty = module_type_inl -> { Enforce mty }
+ | mtys = check_module_types -> { Check mtys } ] ]
+ ;
+ is_module_type:
+ [ [ ":="; mty = module_type_inl ; l = LIST0 ext_module_type -> { (mty::l) }
+ | -> { [] } ] ]
+ ;
+ is_module_expr:
+ [ [ ":="; mexpr = module_expr_inl; l = LIST0 ext_module_expr -> { (mexpr::l) }
+ | -> { [] } ] ]
+ ;
+ functor_app_annot:
+ [ [ "["; IDENT "inline"; "at"; IDENT "level"; i = INT; "]" ->
+ { InlineAt (int_of_string i) }
+ | "["; IDENT "no"; IDENT "inline"; "]" -> { NoInline }
+ | -> { DefaultInline }
+ ] ]
+ ;
+ module_expr_inl:
+ [ [ "!"; me = module_expr -> { (me,NoInline) }
+ | me = module_expr; a = functor_app_annot -> { (me,a) } ] ]
+ ;
+ module_type_inl:
+ [ [ "!"; me = module_type -> { (me,NoInline) }
+ | me = module_type; a = functor_app_annot -> { (me,a) } ] ]
+ ;
+ (* Module binder *)
+ module_binder:
+ [ [ "("; export = export_token; idl = LIST1 identref; ":";
+ mty = module_type_inl; ")" -> { (export,idl,mty) } ] ]
+ ;
+ (* Module expressions *)
+ module_expr:
+ [ [ me = module_expr_atom -> { me }
+ | me1 = module_expr; me2 = module_expr_atom -> { CAst.make ~loc @@ CMapply (me1,me2) }
+ ] ]
+ ;
+ module_expr_atom:
+ [ [ qid = qualid -> { CAst.make ~loc @@ CMident qid } | "("; me = module_expr; ")" -> { me } ] ]
+ ;
+ with_declaration:
+ [ [ "Definition"; fqid = fullyqualid; udecl = OPT univ_decl; ":="; c = Constr.lconstr ->
+ { CWith_Definition (fqid,udecl,c) }
+ | IDENT "Module"; fqid = fullyqualid; ":="; qid = qualid ->
+ { CWith_Module (fqid,qid) }
+ ] ]
+ ;
+ module_type:
+ [ [ qid = qualid -> { CAst.make ~loc @@ CMident qid }
+ | "("; mt = module_type; ")" -> { mt }
+ | mty = module_type; me = module_expr_atom ->
+ { CAst.make ~loc @@ CMapply (mty,me) }
+ | mty = module_type; "with"; decl = with_declaration ->
+ { CAst.make ~loc @@ CMwith (mty,decl) }
+ ] ]
+ ;
+ (* Proof using *)
+ section_subset_expr:
+ [ [ only_starredidentrefs; l = LIST0 starredidentref ->
+ { starredidentreflist_to_expr l }
+ | e = ssexpr -> { e } ]]
+ ;
+ starredidentref:
+ [ [ i = identref -> { SsSingl i }
+ | i = identref; "*" -> { SsFwdClose(SsSingl i) }
+ | "Type" -> { SsType }
+ | "Type"; "*" -> { SsFwdClose SsType } ]]
+ ;
+ ssexpr:
+ [ "35"
+ [ "-"; e = ssexpr -> { SsCompl e } ]
+ | "50"
+ [ e1 = ssexpr; "-"; e2 = ssexpr-> { SsSubstr(e1,e2) }
+ | e1 = ssexpr; "+"; e2 = ssexpr-> { SsUnion(e1,e2) } ]
+ | "0"
+ [ i = starredidentref -> { i }
+ | "("; only_starredidentrefs; l = LIST0 starredidentref; ")"->
+ { starredidentreflist_to_expr l }
+ | "("; only_starredidentrefs; l = LIST0 starredidentref; ")"; "*" ->
+ { SsFwdClose(starredidentreflist_to_expr l) }
+ | "("; e = ssexpr; ")"-> { e }
+ | "("; e = ssexpr; ")"; "*" -> { SsFwdClose e } ] ]
+ ;
+END
+
+(* Extensions: implicits, coercions, etc. *)
+GRAMMAR EXTEND Gram
+ GLOBAL: gallina_ext instance_name hint_info;
+
+ gallina_ext:
+ [ [ (* Transparent and Opaque *)
+ IDENT "Transparent"; l = LIST1 smart_global ->
+ { VernacSetOpacity (Conv_oracle.transparent, l) }
+ | IDENT "Opaque"; l = LIST1 smart_global ->
+ { VernacSetOpacity (Conv_oracle.Opaque, l) }
+ | IDENT "Strategy"; l =
+ LIST1 [ v=strategy_level; "["; q=LIST1 smart_global; "]" -> { (v,q) } ] ->
+ { VernacSetStrategy l }
+ (* Canonical structure *)
+ | IDENT "Canonical"; IDENT "Structure"; qid = global ->
+ { VernacCanonical CAst.(make ~loc @@ AN qid) }
+ | IDENT "Canonical"; IDENT "Structure"; ntn = by_notation ->
+ { VernacCanonical CAst.(make ~loc @@ ByNotation ntn) }
+ | IDENT "Canonical"; IDENT "Structure"; qid = global; d = def_body ->
+ { let s = coerce_reference_to_id qid in
+ VernacDefinition ((NoDischarge,CanonicalStructure),((CAst.make (Name s)),None),d) }
+
+ (* Coercions *)
+ | IDENT "Coercion"; qid = global; d = def_body ->
+ { let s = coerce_reference_to_id qid in
+ VernacDefinition ((NoDischarge,Coercion),((CAst.make (Name s)),None),d) }
+ | IDENT "Identity"; IDENT "Coercion"; f = identref; ":";
+ s = class_rawexpr; ">->"; t = class_rawexpr ->
+ { VernacIdentityCoercion (f, s, t) }
+ | IDENT "Coercion"; qid = global; ":"; s = class_rawexpr; ">->";
+ t = class_rawexpr ->
+ { VernacCoercion (CAst.make ~loc @@ AN qid, s, t) }
+ | IDENT "Coercion"; ntn = by_notation; ":"; s = class_rawexpr; ">->";
+ t = class_rawexpr ->
+ { VernacCoercion (CAst.make ~loc @@ ByNotation ntn, s, t) }
+
+ | IDENT "Context"; c = LIST1 binder ->
+ { VernacContext (List.flatten c) }
+
+ | IDENT "Instance"; namesup = instance_name; ":";
+ expl = [ "!" -> { Decl_kinds.Implicit } | -> { Decl_kinds.Explicit } ] ; t = operconstr LEVEL "200";
+ info = hint_info ;
+ props = [ ":="; "{"; r = record_declaration; "}" -> { Some (true,r) } |
+ ":="; c = lconstr -> { Some (false,c) } | -> { None } ] ->
+ { VernacInstance (false,snd namesup,(fst namesup,expl,t),props,info) }
+
+ | IDENT "Existing"; IDENT "Instance"; id = global;
+ info = hint_info ->
+ { VernacDeclareInstances [id, info] }
+
+ | IDENT "Existing"; IDENT "Instances"; ids = LIST1 global;
+ pri = OPT [ "|"; i = natural -> { i } ] ->
+ { let info = { Typeclasses.hint_priority = pri; hint_pattern = None } in
+ let insts = List.map (fun i -> (i, info)) ids in
+ VernacDeclareInstances insts }
+
+ | IDENT "Existing"; IDENT "Class"; is = global -> { VernacDeclareClass is }
+
+ (* Arguments *)
+ | IDENT "Arguments"; qid = smart_global;
+ args = LIST0 argument_spec_block;
+ more_implicits = OPT
+ [ ","; impl = LIST1
+ [ impl = LIST0 more_implicits_block -> { List.flatten impl } ]
+ SEP "," -> { impl }
+ ];
+ mods = OPT [ ":"; l = LIST1 arguments_modifier SEP "," -> { l } ] ->
+ { let mods = match mods with None -> [] | Some l -> List.flatten l in
+ let slash_position = ref None in
+ let rec parse_args i = function
+ | [] -> []
+ | `Id x :: args -> x :: parse_args (i+1) args
+ | `Slash :: args ->
+ if Option.is_empty !slash_position then
+ (slash_position := Some i; parse_args i args)
+ else
+ user_err Pp.(str "The \"/\" modifier can occur only once")
+ in
+ let args = parse_args 0 (List.flatten args) in
+ let more_implicits = Option.default [] more_implicits in
+ VernacArguments (qid, args, more_implicits, !slash_position, mods) }
+
+ | IDENT "Implicit"; "Type"; bl = reserv_list ->
+ { VernacReserve bl }
+
+ | IDENT "Implicit"; IDENT "Types"; bl = reserv_list ->
+ { test_plural_form_types loc "Implicit Types" bl;
+ VernacReserve bl }
+
+ | IDENT "Generalizable";
+ gen = [IDENT "All"; IDENT "Variables" -> { Some [] }
+ | IDENT "No"; IDENT "Variables" -> { None }
+ | ["Variable" -> { () } | IDENT "Variables" -> { () } ];
+ idl = LIST1 identref -> { Some idl } ] ->
+ { VernacGeneralizable gen } ] ]
+ ;
+ arguments_modifier:
+ [ [ IDENT "simpl"; IDENT "nomatch" -> { [`ReductionDontExposeCase] }
+ | IDENT "simpl"; IDENT "never" -> { [`ReductionNeverUnfold] }
+ | IDENT "default"; IDENT "implicits" -> { [`DefaultImplicits] }
+ | IDENT "clear"; IDENT "implicits" -> { [`ClearImplicits] }
+ | IDENT "clear"; IDENT "scopes" -> { [`ClearScopes] }
+ | IDENT "rename" -> { [`Rename] }
+ | IDENT "assert" -> { [`Assert] }
+ | IDENT "extra"; IDENT "scopes" -> { [`ExtraScopes] }
+ | IDENT "clear"; IDENT "scopes"; IDENT "and"; IDENT "implicits" ->
+ { [`ClearImplicits; `ClearScopes] }
+ | IDENT "clear"; IDENT "implicits"; IDENT "and"; IDENT "scopes" ->
+ { [`ClearImplicits; `ClearScopes] }
+ ] ]
+ ;
+ scope:
+ [ [ "%"; key = IDENT -> { key } ] ]
+ ;
+ argument_spec: [
+ [ b = OPT "!"; id = name ; s = OPT scope ->
+ { id.CAst.v, not (Option.is_empty b), Option.map (fun x -> CAst.make ~loc x) s }
+ ]
+ ];
+ (* List of arguments implicit status, scope, modifiers *)
+ argument_spec_block: [
+ [ item = argument_spec ->
+ { let name, recarg_like, notation_scope = item in
+ [`Id { name=name; recarg_like=recarg_like;
+ notation_scope=notation_scope;
+ implicit_status = NotImplicit}] }
+ | "/" -> { [`Slash] }
+ | "("; items = LIST1 argument_spec; ")"; sc = OPT scope ->
+ { let f x = match sc, x with
+ | None, x -> x | x, None -> Option.map (fun y -> CAst.make ~loc y) x
+ | Some _, Some _ -> user_err Pp.(str "scope declared twice") in
+ List.map (fun (name,recarg_like,notation_scope) ->
+ `Id { name=name; recarg_like=recarg_like;
+ notation_scope=f notation_scope;
+ implicit_status = NotImplicit}) items }
+ | "["; items = LIST1 argument_spec; "]"; sc = OPT scope ->
+ { let f x = match sc, x with
+ | None, x -> x | x, None -> Option.map (fun y -> CAst.make ~loc y) x
+ | Some _, Some _ -> user_err Pp.(str "scope declared twice") in
+ List.map (fun (name,recarg_like,notation_scope) ->
+ `Id { name=name; recarg_like=recarg_like;
+ notation_scope=f notation_scope;
+ implicit_status = Implicit}) items }
+ | "{"; items = LIST1 argument_spec; "}"; sc = OPT scope ->
+ { let f x = match sc, x with
+ | None, x -> x | x, None -> Option.map (fun y -> CAst.make ~loc y) x
+ | Some _, Some _ -> user_err Pp.(str "scope declared twice") in
+ List.map (fun (name,recarg_like,notation_scope) ->
+ `Id { name=name; recarg_like=recarg_like;
+ notation_scope=f notation_scope;
+ implicit_status = MaximallyImplicit}) items }
+ ]
+ ];
+ (* Same as [argument_spec_block], but with only implicit status and names *)
+ more_implicits_block: [
+ [ name = name -> { [(name.CAst.v, Vernacexpr.NotImplicit)] }
+ | "["; items = LIST1 name; "]" ->
+ { List.map (fun name -> (name.CAst.v, Vernacexpr.Implicit)) items }
+ | "{"; items = LIST1 name; "}" ->
+ { List.map (fun name -> (name.CAst.v, Vernacexpr.MaximallyImplicit)) items }
+ ]
+ ];
+ strategy_level:
+ [ [ IDENT "expand" -> { Conv_oracle.Expand }
+ | IDENT "opaque" -> { Conv_oracle.Opaque }
+ | n=INT -> { Conv_oracle.Level (int_of_string n) }
+ | "-"; n=INT -> { Conv_oracle.Level (- int_of_string n) }
+ | IDENT "transparent" -> { Conv_oracle.transparent } ] ]
+ ;
+ instance_name:
+ [ [ name = ident_decl; sup = OPT binders ->
+ { (CAst.map (fun id -> Name id) (fst name), snd name),
+ (Option.default [] sup) }
+ | -> { ((CAst.make ~loc Anonymous), None), [] } ] ]
+ ;
+ hint_info:
+ [ [ "|"; i = OPT natural; pat = OPT constr_pattern ->
+ { { Typeclasses.hint_priority = i; hint_pattern = pat } }
+ | -> { { Typeclasses.hint_priority = None; hint_pattern = None } } ] ]
+ ;
+ reserv_list:
+ [ [ bl = LIST1 reserv_tuple -> { bl } | b = simple_reserv -> { [b] } ] ]
+ ;
+ reserv_tuple:
+ [ [ "("; a = simple_reserv; ")" -> { a } ] ]
+ ;
+ simple_reserv:
+ [ [ idl = LIST1 identref; ":"; c = lconstr -> { (idl,c) } ] ]
+ ;
+
+END
+
+GRAMMAR EXTEND Gram
+ GLOBAL: command query_command class_rawexpr gallina_ext;
+
+ gallina_ext:
+ [ [ IDENT "Export"; "Set"; table = option_table; v = option_value ->
+ { VernacSetOption (true, table, v) }
+ | IDENT "Export"; IDENT "Unset"; table = option_table ->
+ { VernacUnsetOption (true, table) }
+ ] ];
+
+ command:
+ [ [ IDENT "Comments"; l = LIST0 comment -> { VernacComments l }
+
+ (* Hack! Should be in grammar_ext, but camlp5 factorizes badly *)
+ | IDENT "Declare"; IDENT "Instance"; namesup = instance_name; ":";
+ expl = [ "!" -> { Decl_kinds.Implicit } | -> { Decl_kinds.Explicit } ] ; t = operconstr LEVEL "200";
+ info = hint_info ->
+ { VernacInstance (true, snd namesup, (fst namesup, expl, t), None, info) }
+
+ (* System directory *)
+ | IDENT "Pwd" -> { VernacChdir None }
+ | IDENT "Cd" -> { VernacChdir None }
+ | IDENT "Cd"; dir = ne_string -> { VernacChdir (Some dir) }
+
+ | IDENT "Load"; verbosely = [ IDENT "Verbose" -> { true } | -> { false } ];
+ s = [ s = ne_string -> { s } | s = IDENT -> { s } ] ->
+ { VernacLoad (verbosely, s) }
+ | IDENT "Declare"; IDENT "ML"; IDENT "Module"; l = LIST1 ne_string ->
+ { VernacDeclareMLModule l }
+
+ | IDENT "Locate"; l = locatable -> { VernacLocate l }
+
+ (* Managing load paths *)
+ | IDENT "Add"; IDENT "LoadPath"; dir = ne_string; alias = as_dirpath ->
+ { VernacAddLoadPath (false, dir, alias) }
+ | IDENT "Add"; IDENT "Rec"; IDENT "LoadPath"; dir = ne_string;
+ alias = as_dirpath -> { VernacAddLoadPath (true, dir, alias) }
+ | IDENT "Remove"; IDENT "LoadPath"; dir = ne_string ->
+ { VernacRemoveLoadPath dir }
+
+ (* For compatibility *)
+ | IDENT "AddPath"; dir = ne_string; "as"; alias = as_dirpath ->
+ { VernacAddLoadPath (false, dir, alias) }
+ | IDENT "AddRecPath"; dir = ne_string; "as"; alias = as_dirpath ->
+ { VernacAddLoadPath (true, dir, alias) }
+ | IDENT "DelPath"; dir = ne_string ->
+ { VernacRemoveLoadPath dir }
+
+ (* Type-Checking (pas dans le refman) *)
+ | "Type"; c = lconstr -> { VernacGlobalCheck c }
+
+ (* Printing (careful factorization of entries) *)
+ | IDENT "Print"; p = printable -> { VernacPrint p }
+ | IDENT "Print"; qid = smart_global; l = OPT univ_name_list -> { VernacPrint (PrintName (qid,l)) }
+ | IDENT "Print"; IDENT "Module"; "Type"; qid = global ->
+ { VernacPrint (PrintModuleType qid) }
+ | IDENT "Print"; IDENT "Module"; qid = global ->
+ { VernacPrint (PrintModule qid) }
+ | IDENT "Print"; IDENT "Namespace" ; ns = dirpath ->
+ { VernacPrint (PrintNamespace ns) }
+ | IDENT "Inspect"; n = natural -> { VernacPrint (PrintInspect n) }
+
+ | IDENT "Add"; IDENT "ML"; IDENT "Path"; dir = ne_string ->
+ { VernacAddMLPath (false, dir) }
+ | IDENT "Add"; IDENT "Rec"; IDENT "ML"; IDENT "Path"; dir = ne_string ->
+ { VernacAddMLPath (true, dir) }
+
+ (* For acting on parameter tables *)
+ | "Set"; table = option_table; v = option_value ->
+ { VernacSetOption (false, table, v) }
+ | IDENT "Unset"; table = option_table ->
+ { VernacUnsetOption (false, table) }
+
+ | IDENT "Print"; IDENT "Table"; table = option_table ->
+ { VernacPrintOption table }
+
+ | IDENT "Add"; table = IDENT; field = IDENT; v = LIST1 option_ref_value
+ -> { VernacAddOption ([table;field], v) }
+ (* A global value below will be hidden by a field above! *)
+ (* In fact, we give priority to secondary tables *)
+ (* No syntax for tertiary tables due to conflict *)
+ (* (but they are unused anyway) *)
+ | IDENT "Add"; table = IDENT; v = LIST1 option_ref_value ->
+ { VernacAddOption ([table], v) }
+
+ | IDENT "Test"; table = option_table; "for"; v = LIST1 option_ref_value
+ -> { VernacMemOption (table, v) }
+ | IDENT "Test"; table = option_table ->
+ { VernacPrintOption table }
+
+ | IDENT "Remove"; table = IDENT; field = IDENT; v= LIST1 option_ref_value
+ -> { VernacRemoveOption ([table;field], v) }
+ | IDENT "Remove"; table = IDENT; v = LIST1 option_ref_value ->
+ { VernacRemoveOption ([table], v) } ]]
+ ;
+ query_command: (* TODO: rapprocher Eval et Check *)
+ [ [ IDENT "Eval"; r = red_expr; "in"; c = lconstr; "." ->
+ { fun g -> VernacCheckMayEval (Some r, g, c) }
+ | IDENT "Compute"; c = lconstr; "." ->
+ { fun g -> VernacCheckMayEval (Some (Genredexpr.CbvVm None), g, c) }
+ | IDENT "Check"; c = lconstr; "." ->
+ { fun g -> VernacCheckMayEval (None, g, c) }
+ (* Searching the environment *)
+ | IDENT "About"; qid = smart_global; l = OPT univ_name_list; "." ->
+ { fun g -> VernacPrint (PrintAbout (qid,l,g)) }
+ | IDENT "SearchHead"; c = constr_pattern; l = in_or_out_modules; "." ->
+ { fun g -> VernacSearch (SearchHead c,g, l) }
+ | IDENT "SearchPattern"; c = constr_pattern; l = in_or_out_modules; "." ->
+ { fun g -> VernacSearch (SearchPattern c,g, l) }
+ | IDENT "SearchRewrite"; c = constr_pattern; l = in_or_out_modules; "." ->
+ { fun g -> VernacSearch (SearchRewrite c,g, l) }
+ | IDENT "Search"; s = searchabout_query; l = searchabout_queries; "." ->
+ { let (sl,m) = l in fun g -> VernacSearch (SearchAbout (s::sl),g, m) }
+ (* compatibility: SearchAbout *)
+ | IDENT "SearchAbout"; s = searchabout_query; l = searchabout_queries; "." ->
+ { fun g -> let (sl,m) = l in VernacSearch (SearchAbout (s::sl),g, m) }
+ (* compatibility: SearchAbout with "[ ... ]" *)
+ | IDENT "SearchAbout"; "["; sl = LIST1 searchabout_query; "]";
+ l = in_or_out_modules; "." ->
+ { fun g -> VernacSearch (SearchAbout sl,g, l) }
+ ] ]
+ ;
+ printable:
+ [ [ IDENT "Term"; qid = smart_global; l = OPT univ_name_list -> { PrintName (qid,l) }
+ | IDENT "All" -> { PrintFullContext }
+ | IDENT "Section"; s = global -> { PrintSectionContext s }
+ | IDENT "Grammar"; ent = IDENT ->
+ (* This should be in "syntax" section but is here for factorization*)
+ { PrintGrammar ent }
+ | IDENT "LoadPath"; dir = OPT dirpath -> { PrintLoadPath dir }
+ | IDENT "Modules" ->
+ { user_err Pp.(str "Print Modules is obsolete; use Print Libraries instead") }
+ | IDENT "Libraries" -> { PrintModules }
+
+ | IDENT "ML"; IDENT "Path" -> { PrintMLLoadPath }
+ | IDENT "ML"; IDENT "Modules" -> { PrintMLModules }
+ | IDENT "Debug"; IDENT "GC" -> { PrintDebugGC }
+ | IDENT "Graph" -> { PrintGraph }
+ | IDENT "Classes" -> { PrintClasses }
+ | IDENT "TypeClasses" -> { PrintTypeClasses }
+ | IDENT "Instances"; qid = smart_global -> { PrintInstances qid }
+ | IDENT "Coercions" -> { PrintCoercions }
+ | IDENT "Coercion"; IDENT "Paths"; s = class_rawexpr; t = class_rawexpr
+ -> { PrintCoercionPaths (s,t) }
+ | IDENT "Canonical"; IDENT "Projections" -> { PrintCanonicalConversions }
+ | IDENT "Tables" -> { PrintTables }
+ | IDENT "Options" -> { PrintTables (* A Synonymous to Tables *) }
+ | IDENT "Hint" -> { PrintHintGoal }
+ | IDENT "Hint"; qid = smart_global -> { PrintHint qid }
+ | IDENT "Hint"; "*" -> { PrintHintDb }
+ | IDENT "HintDb"; s = IDENT -> { PrintHintDbName s }
+ | IDENT "Scopes" -> { PrintScopes }
+ | IDENT "Scope"; s = IDENT -> { PrintScope s }
+ | IDENT "Visibility"; s = OPT IDENT -> { PrintVisibility s }
+ | IDENT "Implicit"; qid = smart_global -> { PrintImplicit qid }
+ | IDENT "Universes"; fopt = OPT ne_string -> { PrintUniverses (false, fopt) }
+ | IDENT "Sorted"; IDENT "Universes"; fopt = OPT ne_string -> { PrintUniverses (true, fopt) }
+ | IDENT "Assumptions"; qid = smart_global -> { PrintAssumptions (false, false, qid) }
+ | IDENT "Opaque"; IDENT "Dependencies"; qid = smart_global -> { PrintAssumptions (true, false, qid) }
+ | IDENT "Transparent"; IDENT "Dependencies"; qid = smart_global -> { PrintAssumptions (false, true, qid) }
+ | IDENT "All"; IDENT "Dependencies"; qid = smart_global -> { PrintAssumptions (true, true, qid) }
+ | IDENT "Strategy"; qid = smart_global -> { PrintStrategy (Some qid) }
+ | IDENT "Strategies" -> { PrintStrategy None } ] ]
+ ;
+ class_rawexpr:
+ [ [ IDENT "Funclass" -> { FunClass }
+ | IDENT "Sortclass" -> { SortClass }
+ | qid = smart_global -> { RefClass qid } ] ]
+ ;
+ locatable:
+ [ [ qid = smart_global -> { LocateAny qid }
+ | IDENT "Term"; qid = smart_global -> { LocateTerm qid }
+ | IDENT "File"; f = ne_string -> { LocateFile f }
+ | IDENT "Library"; qid = global -> { LocateLibrary qid }
+ | IDENT "Module"; qid = global -> { LocateModule qid } ] ]
+ ;
+ option_value:
+ [ [ -> { BoolValue true }
+ | n = integer -> { IntValue (Some n) }
+ | s = STRING -> { StringValue s } ] ]
+ ;
+ option_ref_value:
+ [ [ id = global -> { QualidRefValue id }
+ | s = STRING -> { StringRefValue s } ] ]
+ ;
+ option_table:
+ [ [ fl = LIST1 [ x = IDENT -> { x } ] -> { fl } ]]
+ ;
+ as_dirpath:
+ [ [ d = OPT [ "as"; d = dirpath -> { d } ] -> { d } ] ]
+ ;
+ ne_in_or_out_modules:
+ [ [ IDENT "inside"; l = LIST1 global -> { SearchInside l }
+ | IDENT "outside"; l = LIST1 global -> { SearchOutside l } ] ]
+ ;
+ in_or_out_modules:
+ [ [ m = ne_in_or_out_modules -> { m }
+ | -> { SearchOutside [] } ] ]
+ ;
+ comment:
+ [ [ c = constr -> { CommentConstr c }
+ | s = STRING -> { CommentString s }
+ | n = natural -> { CommentInt n } ] ]
+ ;
+ positive_search_mark:
+ [ [ "-" -> { false } | -> { true } ] ]
+ ;
+ scope:
+ [ [ "%"; key = IDENT -> { key } ] ]
+ ;
+ searchabout_query:
+ [ [ b = positive_search_mark; s = ne_string; sc = OPT scope ->
+ { (b, SearchString (s,sc)) }
+ | b = positive_search_mark; p = constr_pattern ->
+ { (b, SearchSubPattern p) }
+ ] ]
+ ;
+ searchabout_queries:
+ [ [ m = ne_in_or_out_modules -> { ([],m) }
+ | s = searchabout_query; l = searchabout_queries ->
+ { let (sl,m) = l in (s::sl,m) }
+ | -> { ([],SearchOutside []) }
+ ] ]
+ ;
+ univ_name_list:
+ [ [ "@{" ; l = LIST0 name; "}" -> { l } ] ]
+ ;
+END
+
+GRAMMAR EXTEND Gram
+ GLOBAL: command;
+
+ command:
+ [ [
+(* State management *)
+ IDENT "Write"; IDENT "State"; s = IDENT -> { VernacWriteState s }
+ | IDENT "Write"; IDENT "State"; s = ne_string -> { VernacWriteState s }
+ | IDENT "Restore"; IDENT "State"; s = IDENT -> { VernacRestoreState s }
+ | IDENT "Restore"; IDENT "State"; s = ne_string -> { VernacRestoreState s }
+
+(* Resetting *)
+ | IDENT "Reset"; IDENT "Initial" -> { VernacResetInitial }
+ | IDENT "Reset"; id = identref -> { VernacResetName id }
+ | IDENT "Back" -> { VernacBack 1 }
+ | IDENT "Back"; n = natural -> { VernacBack n }
+ | IDENT "BackTo"; n = natural -> { VernacBackTo n }
+
+(* Tactic Debugger *)
+ | IDENT "Debug"; IDENT "On" ->
+ { VernacSetOption (false, ["Ltac";"Debug"], BoolValue true) }
+
+ | IDENT "Debug"; IDENT "Off" ->
+ { VernacSetOption (false, ["Ltac";"Debug"], BoolValue false) }
+
+(* registration of a custom reduction *)
+
+ | IDENT "Declare"; IDENT "Reduction"; s = IDENT; ":=";
+ r = red_expr ->
+ { VernacDeclareReduction (s,r) }
+
+(* factorized here, though relevant for syntax extensions *)
+
+ | IDENT "Declare"; IDENT "Custom"; IDENT "Entry"; s = IDENT ->
+ { VernacDeclareCustomEntry s }
+
+ ] ];
+ END
+
+(* Grammar extensions *)
+
+GRAMMAR EXTEND Gram
+ GLOBAL: syntax;
+
+ syntax:
+ [ [ IDENT "Open"; IDENT "Scope"; sc = IDENT ->
+ { VernacOpenCloseScope (true,sc) }
+
+ | IDENT "Close"; IDENT "Scope"; sc = IDENT ->
+ { VernacOpenCloseScope (false,sc) }
+
+ | IDENT "Delimit"; IDENT "Scope"; sc = IDENT; "with"; key = IDENT ->
+ { VernacDelimiters (sc, Some key) }
+ | IDENT "Undelimit"; IDENT "Scope"; sc = IDENT ->
+ { VernacDelimiters (sc, None) }
+
+ | IDENT "Bind"; IDENT "Scope"; sc = IDENT; "with";
+ refl = LIST1 class_rawexpr -> { VernacBindScope (sc,refl) }
+
+ | IDENT "Infix"; op = ne_lstring; ":="; p = constr;
+ modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> { l } | -> { [] } ];
+ sc = OPT [ ":"; sc = IDENT -> { sc } ] ->
+ { VernacInfix ((op,modl),p,sc) }
+ | IDENT "Notation"; id = identref;
+ idl = LIST0 ident; ":="; c = constr; b = only_parsing ->
+ { VernacSyntacticDefinition
+ (id,(idl,c),b) }
+ | IDENT "Notation"; s = lstring; ":=";
+ c = constr;
+ modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> { l } | -> { [] } ];
+ sc = OPT [ ":"; sc = IDENT -> { sc } ] ->
+ { VernacNotation (c,(s,modl),sc) }
+ | IDENT "Format"; IDENT "Notation"; n = STRING; s = STRING; fmt = STRING ->
+ { VernacNotationAddFormat (n,s,fmt) }
+
+ | IDENT "Reserved"; IDENT "Infix"; s = ne_lstring;
+ l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> { l } | -> { [] } ] ->
+ { let s = CAst.map (fun s -> "x '"^s^"' y") s in
+ VernacSyntaxExtension (true,(s,l)) }
+
+ | IDENT "Reserved"; IDENT "Notation";
+ s = ne_lstring;
+ l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> { l } | -> { [] } ]
+ -> { VernacSyntaxExtension (false, (s,l)) }
+
+ (* "Print" "Grammar" should be here but is in "command" entry in order
+ to factorize with other "Print"-based vernac entries *)
+ ] ]
+ ;
+ only_parsing:
+ [ [ "("; IDENT "only"; IDENT "parsing"; ")" ->
+ { Some Flags.Current }
+ | "("; IDENT "compat"; s = STRING; ")" ->
+ { Some (parse_compat_version s) }
+ | -> { None } ] ]
+ ;
+ level:
+ [ [ IDENT "level"; n = natural -> { NumLevel n }
+ | IDENT "next"; IDENT "level" -> { NextLevel } ] ]
+ ;
+ syntax_modifier:
+ [ [ "at"; IDENT "level"; n = natural -> { SetLevel n }
+ | "in"; IDENT "custom"; x = IDENT -> { SetCustomEntry (x,None) }
+ | "in"; IDENT "custom"; x = IDENT; "at"; IDENT "level"; n = natural ->
+ { SetCustomEntry (x,Some n) }
+ | IDENT "left"; IDENT "associativity" -> { SetAssoc LeftA }
+ | IDENT "right"; IDENT "associativity" -> { SetAssoc RightA }
+ | IDENT "no"; IDENT "associativity" -> { SetAssoc NonA }
+ | IDENT "only"; IDENT "printing" -> { SetOnlyPrinting }
+ | IDENT "only"; IDENT "parsing" -> { SetOnlyParsing }
+ | IDENT "compat"; s = STRING ->
+ { SetCompatVersion (parse_compat_version s) }
+ | IDENT "format"; s1 = [s = STRING -> { CAst.make ~loc s } ];
+ s2 = OPT [s = STRING -> { CAst.make ~loc s } ] ->
+ { begin match s1, s2 with
+ | { CAst.v = k }, Some s -> SetFormat(k,s)
+ | s, None -> SetFormat ("text",s) end }
+ | x = IDENT; ","; l = LIST1 [id = IDENT -> { id } ] SEP ","; "at";
+ lev = level -> { SetItemLevel (x::l,None,Some lev) }
+ | x = IDENT; "at"; lev = level -> { SetItemLevel ([x],None,Some lev) }
+ | x = IDENT; "at"; lev = level; b = constr_as_binder_kind ->
+ { SetItemLevel ([x],Some b,Some lev) }
+ | x = IDENT; b = constr_as_binder_kind -> { SetItemLevel ([x],Some b,None) }
+ | x = IDENT; typ = syntax_extension_type -> { SetEntryType (x,typ) }
+ ] ]
+ ;
+ syntax_extension_type:
+ [ [ IDENT "ident" -> { ETIdent } | IDENT "global" -> { ETGlobal }
+ | IDENT "bigint" -> { ETBigint }
+ | IDENT "binder" -> { ETBinder true }
+ | IDENT "constr" -> { ETConstr (InConstrEntry,None,None) }
+ | IDENT "constr"; n = OPT at_level; b = OPT constr_as_binder_kind -> { ETConstr (InConstrEntry,b,n) }
+ | IDENT "pattern" -> { ETPattern (false,None) }
+ | IDENT "pattern"; "at"; IDENT "level"; n = natural -> { ETPattern (false,Some n) }
+ | IDENT "strict"; IDENT "pattern" -> { ETPattern (true,None) }
+ | IDENT "strict"; IDENT "pattern"; "at"; IDENT "level"; n = natural -> { ETPattern (true,Some n) }
+ | IDENT "closed"; IDENT "binder" -> { ETBinder false }
+ | IDENT "custom"; x = IDENT; n = OPT at_level; b = OPT constr_as_binder_kind ->
+ { ETConstr (InCustomEntry x,b,n) }
+ ] ]
+ ;
+ at_level:
+ [ [ "at"; n = level -> { n } ] ]
+ ;
+ constr_as_binder_kind:
+ [ [ "as"; IDENT "ident" -> { Notation_term.AsIdent }
+ | "as"; IDENT "pattern" -> { Notation_term.AsIdentOrPattern }
+ | "as"; IDENT "strict"; IDENT "pattern" -> { Notation_term.AsStrictPattern } ] ]
+ ;
+END
diff --git a/vernac/himsg.ml b/vernac/himsg.ml
index 2d2f1cd2..d232f086 100644
--- a/vernac/himsg.ml
+++ b/vernac/himsg.ml
@@ -75,11 +75,7 @@ let rec contract3' env sigma a b c = function
| MetaOccurInBody _ | InstanceNotSameType _ | ProblemBeyondCapabilities
| UnifUnivInconsistency _ as x -> contract3 env sigma a b c, x
| CannotSolveConstraint ((pb,env',t,u),x) ->
- let t = EConstr.of_constr t in
- let u = EConstr.of_constr u in
let env',t,u = contract2 env' sigma t u in
- let t = EConstr.Unsafe.to_constr t in
- let u = EConstr.Unsafe.to_constr u in
let y,x = contract3' env sigma a b c x in
y,CannotSolveConstraint ((pb,env',t,u),x)
@@ -90,7 +86,7 @@ let j_nf_betaiotaevar env sigma j =
uj_type = Reductionops.nf_betaiota env sigma j.uj_type }
let jv_nf_betaiotaevar env sigma jl =
- Array.map (fun j -> j_nf_betaiotaevar env sigma j) jl
+ Array.Smart.map (fun j -> j_nf_betaiotaevar env sigma j) jl
(** Printers *)
@@ -198,12 +194,6 @@ let rec pr_disjunction pr = function
| a::l -> pr a ++ str "," ++ spc () ++ pr_disjunction pr l
| [] -> assert false
-let pr_puniverses f env (c,u) =
- f env c ++
- (if Flags.is_universe_polymorphism () && not (Univ.Instance.is_empty u) then
- str"(*" ++ Univ.Instance.pr Universes.pr_with_global_universes u ++ str"*)"
- else mt())
-
let explain_elim_arity env sigma ind sorts c pj okinds =
let open EConstr in
let env = make_all_name_different env sigma in
@@ -266,7 +256,7 @@ let explain_ill_formed_branch env sigma c ci actty expty =
let pa, pe = pr_explicit env sigma (simp actty) (simp expty) in
strbrk "In pattern-matching on term" ++ brk(1,1) ++ pc ++
spc () ++ strbrk "the branch for constructor" ++ spc () ++
- quote (pr_puniverses pr_constructor env ci) ++
+ quote (pr_pconstructor env sigma ci) ++
spc () ++ str "has type" ++ brk(1,1) ++ pa ++ spc () ++
str "which should be" ++ brk(1,1) ++ pe ++ str "."
@@ -318,12 +308,10 @@ let explain_unification_error env sigma p1 p2 = function
| UnifUnivInconsistency p ->
if !Constrextern.print_universes then
[str "universe inconsistency: " ++
- Univ.explain_universe_inconsistency Universes.pr_with_global_universes p]
+ Univ.explain_universe_inconsistency UnivNames.pr_with_global_universes p]
else
[str "universe inconsistency"]
| CannotSolveConstraint ((pb,env,t,u),e) ->
- let t = EConstr.of_constr t in
- let u = EConstr.of_constr u in
let env = make_all_name_different env sigma in
(strbrk "cannot satisfy constraint " ++ pr_leconstr_env env sigma t ++
str " == " ++ pr_leconstr_env env sigma u)
@@ -403,11 +391,10 @@ let explain_unexpected_type env sigma actual_type expected_type =
str "where" ++ spc () ++ prexp ++ str " was expected."
let explain_not_product env sigma c =
- let c = EConstr.to_constr sigma c in
- let pr = pr_lconstr_env env sigma c in
+ let pr = pr_econstr_env env sigma c in
str "The type of this term is a product" ++ spc () ++
str "while it is expected to be" ++
- (if Constr.is_Type c then str " a sort" else (brk(1,1) ++ pr)) ++ str "."
+ (if EConstr.isType sigma c then str " a sort" else (brk(1,1) ++ pr)) ++ str "."
(* TODO: use the names *)
(* (co)fixpoints *)
@@ -526,11 +513,15 @@ let pr_trailing_ne_context_of env sigma =
then str "."
else (str " in environment:"++ pr_context_unlimited env sigma)
-let rec explain_evar_kind env sigma evk ty = function
+let rec explain_evar_kind env sigma evk ty =
+ let open Evar_kinds in
+ function
| Evar_kinds.NamedHole id ->
strbrk "the existential variable named " ++ Id.print id
- | Evar_kinds.QuestionMark _ ->
+ | Evar_kinds.QuestionMark {qm_record_field=None} ->
strbrk "this placeholder of type " ++ ty
+ | Evar_kinds.QuestionMark {qm_record_field=Some {fieldname; recordname}} ->
+ str "field " ++ (Printer.pr_constant env fieldname) ++ str " of record " ++ (Printer.pr_inductive env recordname)
| Evar_kinds.CasesType false ->
strbrk "the type of this pattern-matching problem"
| Evar_kinds.CasesType true ->
@@ -559,23 +550,29 @@ let rec explain_evar_kind env sigma evk ty = function
| Evar_kinds.VarInstance id ->
strbrk "an instance of type " ++ ty ++
str " for the variable " ++ Id.print id
- | Evar_kinds.SubEvar evk' ->
+ | Evar_kinds.SubEvar (where,evk') ->
let evi = Evd.find sigma evk' in
let pc = match evi.evar_body with
- | Evar_defined c -> pr_leconstr_env env sigma (EConstr.of_constr c)
+ | Evar_defined c -> pr_leconstr_env env sigma c
| Evar_empty -> assert false in
- let ty' = EConstr.of_constr evi.evar_concl in
+ let ty' = evi.evar_concl in
+ (match where with
+ | Some Evar_kinds.Body -> str "the body of "
+ | Some Evar_kinds.Domain -> str "the domain of "
+ | Some Evar_kinds.Codomain -> str "the codomain of "
+ | None ->
pr_existential_key sigma evk ++ str " of type " ++ ty ++
str " in the partial instance " ++ pc ++
- str " found for " ++ explain_evar_kind env sigma evk'
+ str " found for ") ++
+ explain_evar_kind env sigma evk'
(pr_leconstr_env env sigma ty') (snd evi.evar_source)
let explain_typeclass_resolution env sigma evi k =
- match Typeclasses.class_of_constr sigma (EConstr.of_constr evi.evar_concl) with
+ match Typeclasses.class_of_constr sigma evi.evar_concl with
| Some _ ->
let env = Evd.evar_filtered_env evi in
fnl () ++ str "Could not find an instance for " ++
- pr_lconstr_env env sigma evi.evar_concl ++
+ pr_leconstr_env env sigma evi.evar_concl ++
pr_trailing_ne_context_of env sigma
| _ -> mt()
@@ -584,14 +581,14 @@ let explain_placeholder_kind env sigma c e =
| Some (SeveralInstancesFound n) ->
strbrk " (several distinct possible type class instances found)"
| None ->
- match Typeclasses.class_of_constr sigma (EConstr.of_constr c) with
+ match Typeclasses.class_of_constr sigma c with
| Some _ -> strbrk " (no type class instance found)"
| _ -> mt ()
let explain_unsolvable_implicit env sigma evk explain =
let evi = Evarutil.nf_evar_info sigma (Evd.find_undefined sigma evk) in
let env = Evd.evar_filtered_env evi in
- let type_of_hole = pr_lconstr_env env sigma evi.evar_concl in
+ let type_of_hole = pr_leconstr_env env sigma evi.evar_concl in
let pe = pr_trailing_ne_context_of env sigma in
strbrk "Cannot infer " ++
explain_evar_kind env sigma evk type_of_hole (snd evi.evar_source) ++
@@ -634,8 +631,7 @@ let explain_refiner_cannot_generalize env sigma ty =
pr_leconstr_env env sigma ty ++ str "."
let explain_no_occurrence_found env sigma c id =
- let c = EConstr.to_constr sigma c in
- str "Found no subterm matching " ++ pr_lconstr_env env sigma c ++
+ str "Found no subterm matching " ++ pr_leconstr_env env sigma c ++
str " in " ++
(match id with
| Some id -> Id.print id
@@ -682,6 +678,11 @@ let explain_unsatisfied_constraints env sigma cst =
Univ.pr_constraints (Termops.pr_evd_level sigma) cst ++
spc () ++ str "(maybe a bugged tactic)."
+let explain_undeclared_universe env sigma l =
+ strbrk "Undeclared universe: " ++
+ Termops.pr_evd_level sigma l ++
+ spc () ++ str "(maybe a bugged tactic)."
+
let explain_type_error env sigma err =
let env = make_all_name_different env sigma in
match err with
@@ -719,6 +720,8 @@ let explain_type_error env sigma err =
explain_wrong_case_info env ind ci
| UnsatisfiedConstraints cst ->
explain_unsatisfied_constraints env sigma cst
+ | UndeclaredUniverse l ->
+ explain_undeclared_universe env sigma l
let pr_position (cl,pos) =
let clpos = match cl with
@@ -760,7 +763,7 @@ let pr_constraints printenv env sigma evars cstrs =
let evs =
prlist
(fun (ev, evi) -> fnl () ++ pr_existential_key sigma ev ++
- str " : " ++ pr_lconstr_env env' sigma evi.evar_concl ++ fnl ()) l
+ str " : " ++ pr_leconstr_env env' sigma evi.evar_concl ++ fnl ()) l
in
h 0 (pe ++ evs ++ pr_evar_constraints sigma cstrs)
else
@@ -849,9 +852,9 @@ let explain_not_match_error = function
str "the body of definitions differs"
| NotConvertibleTypeField (env, typ1, typ2) ->
str "expected type" ++ spc () ++
- quote (Printer.safe_pr_lconstr_env env Evd.empty typ2) ++ spc () ++
+ quote (Printer.safe_pr_lconstr_env env (Evd.from_env env) typ2) ++ spc () ++
str "but found type" ++ spc () ++
- quote (Printer.safe_pr_lconstr_env env Evd.empty typ1)
+ quote (Printer.safe_pr_lconstr_env env (Evd.from_env env) typ1)
| NotSameConstructorNamesField ->
str "constructor names differ"
| NotSameInductiveNameInBlockField ->
@@ -884,12 +887,12 @@ let explain_not_match_error = function
str"polymorphic universe instances do not match"
| IncompatibleUniverses incon ->
str"the universe constraints are inconsistent: " ++
- Univ.explain_universe_inconsistency Universes.pr_with_global_universes incon
+ Univ.explain_universe_inconsistency UnivNames.pr_with_global_universes incon
| IncompatiblePolymorphism (env, t1, t2) ->
str "conversion of polymorphic values generates additional constraints: " ++
- quote (Printer.safe_pr_lconstr_env env Evd.empty t1) ++ spc () ++
+ quote (Printer.safe_pr_lconstr_env env (Evd.from_env env) t1) ++ spc () ++
str "compared to " ++ spc () ++
- quote (Printer.safe_pr_lconstr_env env Evd.empty t2)
+ quote (Printer.safe_pr_lconstr_env env (Evd.from_env env) t2)
| IncompatibleConstraints cst ->
str " the expected (polymorphic) constraints do not imply " ++
let cst = Univ.AUContext.instantiate (Univ.AUContext.instance cst) cst in
@@ -1009,8 +1012,9 @@ let explain_module_internalization_error = function
(* Typeclass errors *)
let explain_not_a_class env c =
- let c = EConstr.to_constr Evd.empty c in
- pr_constr_env env Evd.empty c ++ str" is not a declared type class."
+ let sigma = Evd.from_env env in
+ let c = EConstr.to_constr sigma c in
+ pr_constr_env env sigma c ++ str" is not a declared type class."
let explain_unbound_method env cid { CAst.v = id } =
str "Unbound method name " ++ Id.print (id) ++ spc () ++
@@ -1023,14 +1027,13 @@ let pr_constr_exprs exprs =
let explain_mismatched_contexts env c i j =
str"Mismatched contexts while declaring instance: " ++ brk (1,1) ++
- hov 1 (str"Expected:" ++ brk (1, 1) ++ pr_rel_context env Evd.empty j) ++
+ hov 1 (str"Expected:" ++ brk (1, 1) ++ pr_rel_context env (Evd.from_env env) j) ++
fnl () ++ brk (1,1) ++
hov 1 (str"Found:" ++ brk (1, 1) ++ pr_constr_exprs i)
let explain_typeclass_error env = function
| NotAClass c -> explain_not_a_class env c
| UnboundMethod (cid, id) -> explain_unbound_method env cid id
- | MismatchedContextInstance (c,i,j) -> explain_mismatched_contexts env c i j
(* Refiner errors *)
@@ -1085,19 +1088,19 @@ let explain_refiner_error env sigma = function
(* Inductive errors *)
let error_non_strictly_positive env c v =
- let pc = pr_lconstr_env env Evd.empty c in
- let pv = pr_lconstr_env env Evd.empty v in
+ let pc = pr_lconstr_env env (Evd.from_env env) c in
+ let pv = pr_lconstr_env env (Evd.from_env env) v in
str "Non strictly positive occurrence of " ++ pv ++ str " in" ++
brk(1,1) ++ pc ++ str "."
let error_ill_formed_inductive env c v =
- let pc = pr_lconstr_env env Evd.empty c in
- let pv = pr_lconstr_env env Evd.empty v in
+ let pc = pr_lconstr_env env (Evd.from_env env) c in
+ let pv = pr_lconstr_env env (Evd.from_env env) v in
str "Not enough arguments applied to the " ++ pv ++
str " in" ++ brk(1,1) ++ pc ++ str "."
let error_ill_formed_constructor env id c v nparams nargs =
- let pv = pr_lconstr_env env Evd.empty v in
+ let pv = pr_lconstr_env env (Evd.from_env env) v in
let atomic = Int.equal (nb_prod Evd.empty (EConstr.of_constr c)) (** FIXME *) 0 in
str "The type of constructor" ++ brk(1,1) ++ Id.print id ++ brk(1,1) ++
str "is not valid;" ++ brk(1,1) ++
@@ -1117,12 +1120,12 @@ let error_ill_formed_constructor env id c v nparams nargs =
let pr_ltype_using_barendregt_convention_env env c =
(* Use goal_concl_style as an approximation of Barendregt's convention (?) *)
- quote (pr_goal_concl_style_env env Evd.empty (EConstr.of_constr c))
+ quote (pr_goal_concl_style_env env (Evd.from_env env) (EConstr.of_constr c))
let error_bad_ind_parameters env c n v1 v2 =
let pc = pr_ltype_using_barendregt_convention_env env c in
- let pv1 = pr_lconstr_env env Evd.empty v1 in
- let pv2 = pr_lconstr_env env Evd.empty v2 in
+ let pv1 = pr_lconstr_env env (Evd.from_env env) v1 in
+ let pv2 = pr_lconstr_env env (Evd.from_env env) v2 in
str "Last occurrence of " ++ pv2 ++ str " must have " ++ pv1 ++
str " as " ++ pr_nth n ++ str " argument in" ++ brk(1,1) ++ pc ++ str "."
@@ -1140,7 +1143,7 @@ let error_same_names_overlap idl =
prlist_with_sep pr_comma Id.print idl ++ str "."
let error_not_an_arity env c =
- str "The type" ++ spc () ++ pr_lconstr_env env Evd.empty c ++ spc () ++
+ str "The type" ++ spc () ++ pr_lconstr_env env (Evd.from_env env) c ++ spc () ++
str "is not an arity."
let error_bad_entry () =
@@ -1230,12 +1233,7 @@ let explain_wrong_numarg_inductive env ind n =
str " expects " ++ decline_string n "argument" ++ str "."
let explain_unused_clause env pats =
-(* Without localisation
- let s = if List.length pats > 1 then "s" else "" in
- (str ("Unused clause with pattern"^s) ++ spc () ++
- hov 0 (pr_sequence pr_cases_pattern pats) ++ str ")")
-*)
- str "This clause is redundant."
+ str "Pattern \"" ++ hov 0 (prlist_with_sep pr_comma pr_cases_pattern pats) ++ strbrk "\" is redundant in this clause."
let explain_non_exhaustive env pats =
str "Non exhaustive pattern-matching: no clause found for " ++
@@ -1307,6 +1305,7 @@ let map_ptype_error f = function
| IllTypedRecBody (n, na, jv, t) ->
IllTypedRecBody (n, na, Array.map (on_judgment f) jv, Array.map f t)
| UnsatisfiedConstraints g -> UnsatisfiedConstraints g
+| UndeclaredUniverse l -> UndeclaredUniverse l
let explain_reduction_tactic_error = function
| Tacred.InvalidAbstraction (env,sigma,c,(env',e)) ->
@@ -1314,4 +1313,14 @@ let explain_reduction_tactic_error = function
str "The abstracted term" ++ spc () ++
quote (pr_goal_concl_style_env env sigma c) ++
spc () ++ str "is not well typed." ++ fnl () ++
- explain_type_error env' Evd.empty e
+ explain_type_error env' (Evd.from_env env') e
+
+let explain_numeral_notation_error env sigma = function
+ | Notation.UnexpectedTerm c ->
+ (strbrk "Unexpected term " ++
+ pr_constr_env env sigma c ++
+ strbrk " while parsing a numeral notation.")
+ | Notation.UnexpectedNonOptionTerm c ->
+ (strbrk "Unexpected non-option term " ++
+ pr_constr_env env sigma c ++
+ strbrk " while parsing a numeral notation.")
diff --git a/vernac/himsg.mli b/vernac/himsg.mli
index 0e20d18c..02b3c455 100644
--- a/vernac/himsg.mli
+++ b/vernac/himsg.mli
@@ -25,6 +25,8 @@ val explain_pretype_error : env -> Evd.evar_map -> pretype_error -> Pp.t
val explain_inductive_error : inductive_error -> Pp.t
+val explain_mismatched_contexts : env -> contexts -> Constrexpr.constr_expr list -> Constr.rel_context -> Pp.t
+
val explain_typeclass_error : env -> typeclass_error -> Pp.t
val explain_recursion_scheme_error : recursion_scheme_error -> Pp.t
@@ -44,3 +46,5 @@ val explain_module_internalization_error :
val map_pguard_error : ('c -> 'd) -> 'c pguard_error -> 'd pguard_error
val map_ptype_error : ('c -> 'd) -> ('c, 'c) ptype_error -> ('d, 'd) ptype_error
+
+val explain_numeral_notation_error : env -> Evd.evar_map -> Notation.numeral_notation_error -> Pp.t
diff --git a/vernac/indschemes.ml b/vernac/indschemes.ml
index 49414862..e86e1087 100644
--- a/vernac/indschemes.ml
+++ b/vernac/indschemes.ml
@@ -380,7 +380,7 @@ let do_mutual_induction_scheme ?(force_mutual=false) lnamedepindsort =
match inst with
| None ->
let _, ctx = Global.type_of_global_in_context env0 (IndRef ind) in
- let u, ctx = Universes.fresh_instance_from ctx None in
+ let u, ctx = UnivGen.fresh_instance_from ctx None in
let evd = Evd.from_ctx (UState.of_context_set ctx) in
evd, (ind,u), Some u
| Some ui -> evd, (ind, ui), inst
diff --git a/vernac/indschemes.mli b/vernac/indschemes.mli
index 43915788..ebfc76de 100644
--- a/vernac/indschemes.mli
+++ b/vernac/indschemes.mli
@@ -36,17 +36,17 @@ val declare_rewriting_schemes : inductive -> unit
*)
val do_mutual_induction_scheme : ?force_mutual:bool ->
- (Misctypes.lident * bool * inductive * Sorts.family) list -> unit
+ (lident * bool * inductive * Sorts.family) list -> unit
(** Main calls to interpret the Scheme command *)
-val do_scheme : (Misctypes.lident option * scheme) list -> unit
+val do_scheme : (lident option * scheme) list -> unit
(** Combine a list of schemes into a conjunction of them *)
val build_combined_scheme : env -> Constant.t list -> Evd.evar_map * constr * types
-val do_combined_scheme : Misctypes.lident -> Misctypes.lident list -> unit
+val do_combined_scheme : lident -> lident list -> unit
(** Hook called at each inductive type definition *)
diff --git a/vernac/lemmas.ml b/vernac/lemmas.ml
index 30dd6ec7..880a11be 100644
--- a/vernac/lemmas.ml
+++ b/vernac/lemmas.ml
@@ -34,7 +34,7 @@ open Impargs
module RelDecl = Context.Rel.Declaration
module NamedDecl = Context.Named.Declaration
-type 'a declaration_hook = Decl_kinds.locality -> Globnames.global_reference -> 'a
+type 'a declaration_hook = Decl_kinds.locality -> GlobRef.t -> 'a
let mk_hook hook = hook
let call_hook fix_exn hook l c =
try hook l c
@@ -71,17 +71,13 @@ let adjust_guardness_conditions const = function
List.interval 0 (List.length ((lam_assum c))))
lemma_guard (Array.to_list fixdefs) in
*)
- let add c cb e =
- let exists c e =
- try ignore(Environ.lookup_constant c e); true
- with Not_found -> false in
- if exists c e then e else Environ.add_constant c cb e in
- let env = List.fold_left (fun env { eff } ->
- match eff with
- | SEsubproof (c, cb,_) -> add c cb env
- | SEscheme (l,_) ->
- List.fold_left (fun e (_,c,cb,_) -> add c cb e) env l)
- env (Safe_typing.side_effects_of_private_constants eff) in
+ let fold env eff =
+ try
+ let _ = Environ.lookup_constant eff.seff_constant env in
+ env
+ with Not_found -> Environ.add_constant eff.seff_constant eff.seff_body env
+ in
+ let env = List.fold_left fold env (Safe_typing.side_effects_of_private_constants eff) in
let indexes =
search_guard env
possible_indexes fixdecls in
@@ -334,8 +330,8 @@ let universe_proof_terminator compute_guard hook =
Feedback.feedback Feedback.AddedAxiom
| Proved (opaque,idopt,proof) ->
let is_opaque, export_seff = match opaque with
- | Vernacexpr.Transparent -> false, true
- | Vernacexpr.Opaque -> true, false
+ | Transparent -> false, true
+ | Opaque -> true, false
in
let proof = get_proof proof compute_guard
(hook (Some (proof.Proof_global.universes))) is_opaque in
@@ -436,7 +432,7 @@ let start_proof_with_initialization kind sigma decl recguard thms snl hook =
let start_proof_com ?inference_hook kind thms hook =
let env0 = Global.env () in
let decl = fst (List.hd thms) in
- let evd, decl = Univdecls.interp_univ_decl_opt env0 (snd decl) in
+ let evd, decl = Constrexpr_ops.interp_univ_decl_opt env0 (snd decl) in
let evd, thms = List.fold_left_map (fun evd ((id, _), (bl, t)) ->
let evd, (impls, ((env, ctx), imps)) = interp_context_evars env0 evd bl in
let evd, (t', imps') = interp_type_evars_impls ~impls env evd t in
@@ -451,12 +447,12 @@ let start_proof_com ?inference_hook kind thms hook =
(ids, imps @ lift_implicits (Context.Rel.nhyps ctx) imps'))))
evd thms in
let recguard,thms,snl = look_for_possibly_mutual_statements evd thms in
- let evd, _nf = Evarutil.nf_evars_and_universes evd in
+ let evd = Evd.minimize_universes evd in
(* XXX: This nf_evar is critical too!! We are normalizing twice if
you look at the previous lines... *)
let thms = List.map (fun (n, (t, info)) -> (n, (nf_evar evd t, info))) thms in
let () =
- let open Misctypes in
+ let open UState in
if not (decl.univdecl_extensible_instance && decl.univdecl_extensible_constraints) then
ignore (Evd.check_univ_decl ~poly:(pi2 kind) evd decl)
in
diff --git a/vernac/lemmas.mli b/vernac/lemmas.mli
index ad4c278e..c9e4876e 100644
--- a/vernac/lemmas.mli
+++ b/vernac/lemmas.mli
@@ -13,21 +13,21 @@ open Decl_kinds
type 'a declaration_hook
val mk_hook :
- (Decl_kinds.locality -> Globnames.global_reference -> 'a) -> 'a declaration_hook
+ (Decl_kinds.locality -> GlobRef.t -> 'a) -> 'a declaration_hook
val call_hook :
- Future.fix_exn -> 'a declaration_hook -> Decl_kinds.locality -> Globnames.global_reference -> 'a
+ Future.fix_exn -> 'a declaration_hook -> Decl_kinds.locality -> GlobRef.t -> 'a
(** A hook start_proof calls on the type of the definition being started *)
val set_start_hook : (EConstr.types -> unit) -> unit
-val start_proof : Id.t -> ?pl:Univdecls.universe_decl -> goal_kind -> Evd.evar_map ->
+val start_proof : Id.t -> ?pl:UState.universe_decl -> goal_kind -> Evd.evar_map ->
?terminator:(Proof_global.lemma_possible_guards -> unit declaration_hook -> Proof_global.proof_terminator) ->
?sign:Environ.named_context_val -> EConstr.types ->
?init_tac:unit Proofview.tactic -> ?compute_guard:Proof_global.lemma_possible_guards ->
unit declaration_hook -> unit
-val start_proof_univs : Id.t -> ?pl:Univdecls.universe_decl -> goal_kind -> Evd.evar_map ->
+val start_proof_univs : Id.t -> ?pl:UState.universe_decl -> goal_kind -> Evd.evar_map ->
?terminator:(Proof_global.lemma_possible_guards -> (UState.t option -> unit declaration_hook) -> Proof_global.proof_terminator) ->
?sign:Environ.named_context_val -> EConstr.types ->
?init_tac:unit Proofview.tactic -> ?compute_guard:Proof_global.lemma_possible_guards ->
@@ -39,7 +39,7 @@ val start_proof_com :
unit declaration_hook -> unit
val start_proof_with_initialization :
- goal_kind -> Evd.evar_map -> Univdecls.universe_decl ->
+ goal_kind -> Evd.evar_map -> UState.universe_decl ->
(bool * Proof_global.lemma_possible_guards * unit Proofview.tactic list option) option ->
(Id.t (* name of thm *) *
(EConstr.types (* type of thm *) * (Name.t list (* names to pre-introduce *) * Impargs.manual_explicitation list))) list
diff --git a/vernac/metasyntax.ml b/vernac/metasyntax.ml
index 8c9d8f6b..d66a1214 100644
--- a/vernac/metasyntax.ml
+++ b/vernac/metasyntax.ml
@@ -15,6 +15,7 @@ open Names
open Constrexpr
open Constrexpr_ops
open Notation_term
+open Notation_gram
open Notation_ops
open Ppextend
open Extend
@@ -48,7 +49,7 @@ let entry_buf = Buffer.create 64
let pr_entry e =
let () = Buffer.clear entry_buf in
let ft = Format.formatter_of_buffer entry_buf in
- let () = Pcoq.Gram.entry_print ft e in
+ let () = Pcoq.Entry.print ft e in
str (Buffer.contents entry_buf)
let pr_registered_grammar name =
@@ -76,22 +77,22 @@ let pr_grammar = function
pr_entry Pcoq.Constr.pattern
| "vernac" ->
str "Entry vernac_control is" ++ fnl () ++
- pr_entry Pcoq.Vernac_.vernac_control ++
+ pr_entry Pvernac.Vernac_.vernac_control ++
str "Entry command is" ++ fnl () ++
- pr_entry Pcoq.Vernac_.command ++
+ pr_entry Pvernac.Vernac_.command ++
str "Entry syntax is" ++ fnl () ++
- pr_entry Pcoq.Vernac_.syntax ++
+ pr_entry Pvernac.Vernac_.syntax ++
str "Entry gallina is" ++ fnl () ++
- pr_entry Pcoq.Vernac_.gallina ++
+ pr_entry Pvernac.Vernac_.gallina ++
str "Entry gallina_ext is" ++ fnl () ++
- pr_entry Pcoq.Vernac_.gallina_ext
+ pr_entry Pvernac.Vernac_.gallina_ext
| name -> pr_registered_grammar name
(**********************************************************************)
(* Parse a format (every terminal starting with a letter or a single
quote (except a single quote alone) must be quoted) *)
-let parse_format ({CAst.loc;v=str} : Misctypes.lstring) =
+let parse_format ({CAst.loc;v=str} : lstring) =
let len = String.length str in
(* TODO: update the line of the location when the string contains newlines *)
let make_loc i j = Option.map (Loc.shift_loc (i+1) (j-len)) loc in
@@ -282,20 +283,30 @@ let error_not_same_scope x y =
(**********************************************************************)
(* Build pretty-printing rules *)
+let pr_notation_entry = function
+ | InConstrEntry -> str "constr"
+ | InCustomEntry s -> str "custom " ++ str s
+
let prec_assoc = function
| RightA -> (L,E)
| LeftA -> (E,L)
| NonA -> (L,L)
-let precedence_of_position_and_level from = function
+let precedence_of_position_and_level from_level = function
| NumLevel n, BorderProd (_,None) -> n, Prec n
| NumLevel n, BorderProd (b,Some a) ->
n, let (lp,rp) = prec_assoc a in if b == Left then lp else rp
| NumLevel n, InternalProd -> n, Prec n
- | NextLevel, _ -> from, L
-
-let precedence_of_entry_type from = function
- | ETConstr x | ETConstrAsBinder (_,x) -> precedence_of_position_and_level from x
+ | NextLevel, _ -> from_level, L
+
+let precedence_of_entry_type (from_custom,from_level) = function
+ | ETConstr (custom,_,x) when notation_entry_eq custom from_custom ->
+ precedence_of_position_and_level from_level x
+ | ETConstr (custom,_,(NumLevel n,_)) -> n, Prec n
+ | ETConstr (custom,_,(NextLevel,_)) ->
+ user_err (strbrk "\"next level\" is only for sub-expressions in the same entry as where the notation is (" ++
+ quote (pr_notation_entry custom) ++ strbrk " is different from " ++
+ quote (pr_notation_entry from_custom) ++ str ").")
| ETPattern (_,n) -> let n = match n with None -> 0 | Some n -> n in n, Prec n
| _ -> 0, E (* should not matter *)
@@ -366,15 +377,14 @@ let unparsing_metavar i from typs =
let x = List.nth typs (i-1) in
let prec = snd (precedence_of_entry_type from x) in
match x with
- | ETConstr _ | ETConstrAsBinder _ | ETReference | ETBigint ->
+ | ETConstr _ | ETGlobal | ETBigint ->
UnpMetaVar (i,prec)
| ETPattern _ ->
UnpBinderMetaVar (i,prec)
- | ETName ->
- UnpBinderMetaVar (i,Prec 0)
+ | ETIdent ->
+ UnpBinderMetaVar (i,prec)
| ETBinder isopen ->
assert false
- | ETOther _ -> failwith "TODO"
(* Heuristics for building default printing rules *)
@@ -560,11 +570,10 @@ let hunks_of_format (from,(vars,typs)) symfmt =
(**********************************************************************)
(* Build parsing rules *)
-let assoc_of_type n (_,typ) = precedence_of_entry_type n typ
+let assoc_of_type from n (_,typ) = precedence_of_entry_type (from,n) typ
let is_not_small_constr = function
ETProdConstr _ -> true
- | ETProdOther("constr","binder_constr") -> true
| _ -> false
let rec define_keywords_aux = function
@@ -594,9 +603,9 @@ let distribute a ll = List.map (fun l -> a @ l) ll
t;sep;t;...;t;sep;t;...;t;sep;t (p+n times)
t;sep;t;...;t;sep;t;...;t;sep;t;LIST1(t,sep) *)
-let expand_list_rule typ tkl x n p ll =
+let expand_list_rule s typ tkl x n p ll =
let camlp5_message_name = Some (add_suffix x ("_"^string_of_int n)) in
- let main = GramConstrNonTerminal (ETProdConstr typ, camlp5_message_name) in
+ let main = GramConstrNonTerminal (ETProdConstr (s,typ), camlp5_message_name) in
let tks = List.map (fun x -> GramConstrTerminal x) tkl in
let rec aux i hds ll =
if i < p then aux (i+1) (main :: tks @ hds) ll
@@ -612,7 +621,7 @@ let expand_list_rule typ tkl x n p ll =
let is_constr_typ typ x etyps =
match List.assoc x etyps with
- | ETConstr typ' | ETConstrAsBinder (_,typ') -> typ = typ'
+ | ETConstr (_,_,typ') -> typ = typ'
| _ -> false
let include_possible_similar_trailing_pattern typ etyps sl l =
@@ -626,13 +635,12 @@ let include_possible_similar_trailing_pattern typ etyps sl l =
try_aux 0 l
let prod_entry_type = function
- | ETName -> ETProdName
- | ETReference -> ETProdReference
+ | ETIdent -> ETProdName
+ | ETGlobal -> ETProdReference
| ETBigint -> ETProdBigint
| ETBinder _ -> assert false (* See check_binder_type *)
- | ETConstr p | ETConstrAsBinder (_,p) -> ETProdConstr p
+ | ETConstr (s,_,p) -> ETProdConstr (s,p)
| ETPattern (_,n) -> ETProdPattern (match n with None -> 0 | Some n -> n)
- | ETOther (s,t) -> ETProdOther (s,t)
let make_production etyps symbols =
let rec aux = function
@@ -650,9 +658,9 @@ let make_production etyps symbols =
| Break _ -> []
| _ -> anomaly (Pp.str "Found a non terminal token in recursive notation separator.")) sl) in
match List.assoc x etyps with
- | ETConstr typ ->
+ | ETConstr (s,_,typ) ->
let p,l' = include_possible_similar_trailing_pattern typ etyps sl l in
- expand_list_rule typ tkl x 1 p (aux l')
+ expand_list_rule s typ tkl x 1 p (aux l')
| ETBinder o ->
check_open_binder o sl x;
let typ = if o then (assert (tkl = []); ETBinderOpen) else ETBinderClosed tkl in
@@ -674,8 +682,7 @@ let rec find_symbols c_current c_next c_last = function
(x,c_next)::(find_symbols c_next c_next c_last sl')
let border = function
- | (_,ETConstr(_,BorderProd (_,a))) :: _ -> a
- | (_,(ETConstrAsBinder(_,(_,BorderProd (_,a))))) :: _ -> a
+ | (_,(ETConstr(_,_,(_,BorderProd (_,a))))) :: _ -> a
| _ -> None
let recompute_assoc typs =
@@ -697,30 +704,31 @@ let pr_arg_level from (lev,typ) =
| (n,_) -> str "Unknown level" in
Ppvernac.pr_set_entry_type (fun _ -> (*TO CHECK*) mt()) typ ++
(match typ with
- | ETConstr _ | ETConstrAsBinder _ | ETPattern _ -> spc () ++ pplev lev
+ | ETConstr _ | ETPattern _ -> spc () ++ pplev lev
| _ -> mt ())
-let pr_level ntn (from,args,typs) =
- str "at level " ++ int from ++ spc () ++ str "with arguments" ++ spc() ++
- prlist_with_sep pr_comma (pr_arg_level from) (List.combine args typs)
+let pr_level ntn (from,fromlevel,args,typs) =
+ (match from with InConstrEntry -> mt () | InCustomEntry s -> str "in " ++ str s ++ spc()) ++
+ str "at level " ++ int fromlevel ++ spc () ++ str "with arguments" ++ spc() ++
+ prlist_with_sep pr_comma (pr_arg_level fromlevel) (List.combine args typs)
let error_incompatible_level ntn oldprec prec =
user_err
- (str "Notation " ++ qstring ntn ++ str " is already defined" ++ spc() ++
+ (str "Notation " ++ pr_notation ntn ++ str " is already defined" ++ spc() ++
pr_level ntn oldprec ++
spc() ++ str "while it is now required to be" ++ spc() ++
pr_level ntn prec ++ str ".")
let error_parsing_incompatible_level ntn ntn' oldprec prec =
user_err
- (str "Notation " ++ qstring ntn ++ str " relies on a parsing rule for " ++ qstring ntn' ++ spc() ++
+ (str "Notation " ++ pr_notation ntn ++ str " relies on a parsing rule for " ++ pr_notation ntn' ++ spc() ++
str " which is already defined" ++ spc() ++
pr_level ntn oldprec ++
spc() ++ str "while it is now required to be" ++ spc() ++
pr_level ntn prec ++ str ".")
type syntax_extension = {
- synext_level : Notation_term.level;
+ synext_level : Notation_gram.level;
synext_notation : notation;
synext_notgram : notation_grammar;
synext_unparsing : unparsing list;
@@ -737,10 +745,10 @@ type syntax_extension_obj = locality_flag * syntax_extension
let check_and_extend_constr_grammar ntn rule =
try
let ntn_for_grammar = rule.notgram_notation in
- if String.equal ntn ntn_for_grammar then raise Not_found;
+ if notation_eq ntn ntn_for_grammar then raise Not_found;
let prec = rule.notgram_level in
- let oldprec = Notation.level_of_notation ntn_for_grammar in
- if not (Notation.level_eq prec oldprec) then error_parsing_incompatible_level ntn ntn_for_grammar oldprec prec;
+ let oldprec = Notgram_ops.level_of_notation ntn_for_grammar in
+ if not (Notgram_ops.level_eq prec oldprec) then error_parsing_incompatible_level ntn ntn_for_grammar oldprec prec;
with Not_found ->
Egramcoq.extend_constr_grammar rule
@@ -749,17 +757,17 @@ let cache_one_syntax_extension se =
let prec = se.synext_level in
let onlyprint = se.synext_notgram.notgram_onlyprinting in
try
- let oldprec = Notation.level_of_notation ~onlyprint ntn in
- if not (Notation.level_eq prec oldprec) then error_incompatible_level ntn oldprec prec;
+ let oldprec = Notgram_ops.level_of_notation ~onlyprint ntn in
+ if not (Notgram_ops.level_eq prec oldprec) then error_incompatible_level ntn oldprec prec;
with Not_found ->
if is_active_compat se.synext_compat then begin
(* Reserve the notation level *)
- Notation.declare_notation_level ntn prec ~onlyprint;
+ Notgram_ops.declare_notation_level ntn prec ~onlyprint;
(* Declare the parsing rule *)
if not onlyprint then List.iter (check_and_extend_constr_grammar ntn) se.synext_notgram.notgram_rules;
(* Declare the notation rule *)
- Notation.declare_notation_rule ntn
- ~extra:se.synext_extra (se.synext_unparsing, pi1 prec) se.synext_notgram
+ declare_notation_rule ntn
+ ~extra:se.synext_extra (se.synext_unparsing, let (_,lev,_,_) = prec in lev) se.synext_notgram
end
let cache_syntax_extension (_, (_, sy)) =
@@ -796,20 +804,24 @@ module NotationMods = struct
type notation_modifier = {
assoc : gram_assoc option;
level : int option;
+ custom : notation_entry;
etyps : (Id.t * simple_constr_prod_entry_key) list;
+ subtyps : (Id.t * production_level) list;
(* common to syn_data below *)
only_parsing : bool;
only_printing : bool;
compat : Flags.compat_version option;
- format : Misctypes.lstring option;
+ format : lstring option;
extra : (string * string) list;
}
let default = {
assoc = None;
level = None;
+ custom = InConstrEntry;
etyps = [];
+ subtyps = [];
only_parsing = false;
only_printing = false;
compat = None;
@@ -820,53 +832,75 @@ let default = {
end
let interp_modifiers modl = let open NotationMods in
- let rec interp acc = function
- | [] -> acc
+ let rec interp subtyps acc = function
+ | [] -> subtyps, acc
| SetEntryType (s,typ) :: l ->
let id = Id.of_string s in
if Id.List.mem_assoc id acc.etyps then
user_err ~hdr:"Metasyntax.interp_modifiers"
(str s ++ str " is already assigned to an entry or constr level.");
- interp { acc with etyps = (id,typ) :: acc.etyps; } l
- | SetItemLevel ([],n) :: l ->
- interp acc l
- | SetItemLevelAsBinder ([],_,_) :: l ->
- interp acc l
- | SetItemLevel (s::idl,n) :: l ->
+ interp subtyps { acc with etyps = (id,typ) :: acc.etyps; } l
+ | SetItemLevel ([],bko,n) :: l ->
+ interp subtyps acc l
+ | SetItemLevel (s::idl,bko,n) :: l ->
let id = Id.of_string s in
if Id.List.mem_assoc id acc.etyps then
user_err ~hdr:"Metasyntax.interp_modifiers"
(str s ++ str " is already assigned to an entry or constr level.");
- let typ = ETConstr (Some n) in
- interp { acc with etyps = (id,typ)::acc.etyps; } (SetItemLevel (idl,n)::l)
- | SetItemLevelAsBinder (s::idl,bk,n) :: l ->
- let id = Id.of_string s in
- if Id.List.mem_assoc id acc.etyps then
- user_err ~hdr:"Metasyntax.interp_modifiers"
- (str s ++ str " is already assigned to an entry or constr level.");
- let typ = ETConstrAsBinder (bk,n) in
- interp { acc with etyps = (id,typ)::acc.etyps; } (SetItemLevelAsBinder (idl,bk,n)::l)
+ interp ((id,bko,n)::subtyps) acc (SetItemLevel (idl,bko,n)::l)
| SetLevel n :: l ->
- interp { acc with level = Some n; } l
+ (match acc.custom with
+ | InCustomEntry s ->
+ if acc.level <> None then
+ user_err (str ("isolated \"at level " ^ string_of_int n ^ "\" unexpected."))
+ else
+ user_err (str ("use \"in custom " ^ s ^ " at level " ^ string_of_int n ^
+ "\"") ++ spc () ++ str "rather than" ++ spc () ++
+ str ("\"at level " ^ string_of_int n ^ "\"") ++
+ spc () ++ str "isolated.")
+ | InConstrEntry ->
+ if acc.level <> None then
+ user_err (str "A level is already assigned.");
+ interp subtyps { acc with level = Some n; } l)
+ | SetCustomEntry (s,n) :: l ->
+ if acc.level <> None then
+ (if n = None then
+ user_err (str ("use \"in custom " ^ s ^ " at level " ^
+ string_of_int (Option.get acc.level) ^
+ "\"") ++ spc () ++ str "rather than" ++ spc () ++
+ str ("\"at level " ^
+ string_of_int (Option.get acc.level) ^ "\"") ++
+ spc () ++ str "isolated.")
+ else
+ user_err (str ("isolated \"at level " ^ string_of_int (Option.get acc.level) ^ "\" unexpected.")));
+ if acc.custom <> InConstrEntry then
+ user_err (str "Entry is already assigned to custom " ++ str s ++ (match acc.level with None -> mt () | Some lev -> str " at level " ++ int lev) ++ str ".");
+ interp subtyps { acc with custom = InCustomEntry s; level = n } l
| SetAssoc a :: l ->
if not (Option.is_empty acc.assoc) then user_err Pp.(str "An associativity is given more than once.");
- interp { acc with assoc = Some a; } l
+ interp subtyps { acc with assoc = Some a; } l
| SetOnlyParsing :: l ->
- interp { acc with only_parsing = true; } l
+ interp subtyps { acc with only_parsing = true; } l
| SetOnlyPrinting :: l ->
- interp { acc with only_printing = true; } l
+ interp subtyps { acc with only_printing = true; } l
| SetCompatVersion v :: l ->
- interp { acc with compat = Some v; } l
+ interp subtyps { acc with compat = Some v; } l
| SetFormat ("text",s) :: l ->
if not (Option.is_empty acc.format) then user_err Pp.(str "A format is given more than once.");
- interp { acc with format = Some s; } l
- | SetFormat (k,{CAst.v=s}) :: l ->
- interp { acc with extra = (k,s)::acc.extra; } l
- in interp default modl
+ interp subtyps { acc with format = Some s; } l
+ | SetFormat (k,s) :: l ->
+ interp subtyps { acc with extra = (k,s.CAst.v)::acc.extra; } l
+ in
+ let subtyps,mods = interp [] default modl in
+ (* interpret item levels wrt to main entry *)
+ let extra_etyps = List.map (fun (id,bko,n) -> (id,ETConstr (mods.custom,bko,n))) subtyps in
+ { mods with etyps = extra_etyps@mods.etyps }
let check_infix_modifiers modifiers =
- let t = (interp_modifiers modifiers).NotationMods.etyps in
- if not (List.is_empty t) then
+ let mods = interp_modifiers modifiers in
+ let t = mods.NotationMods.etyps in
+ let u = mods.NotationMods.subtyps in
+ if not (List.is_empty t) || not (List.is_empty u) then
user_err Pp.(str "Explicit entry level or type unexpected in infix notation.")
let check_useless_entry_types recvars mainvars etyps =
@@ -907,21 +941,18 @@ let get_compat_version mods =
(* Compute precedences from modifiers (or find default ones) *)
-let set_entry_type etyps (x,typ) =
+let set_entry_type from etyps (x,typ) =
let typ = try
match List.assoc x etyps, typ with
- | ETConstr (Some n), (_,BorderProd (left,_)) ->
- ETConstr (n,BorderProd (left,None))
- | ETConstr (Some n), (_,InternalProd) -> ETConstr (n,InternalProd)
- | ETConstrAsBinder (bk, Some n), (_,BorderProd (left,_)) ->
- ETConstrAsBinder (bk, (n,BorderProd (left,None)))
- | ETConstrAsBinder (bk, Some n), (_,InternalProd) ->
- ETConstrAsBinder (bk, (n,InternalProd))
+ | ETConstr (s,bko,Some n), (_,BorderProd (left,_)) ->
+ ETConstr (s,bko,(n,BorderProd (left,None)))
+ | ETConstr (s,bko,Some n), (_,InternalProd) ->
+ ETConstr (s,bko,(n,InternalProd))
| ETPattern (b,n), _ -> ETPattern (b,n)
- | (ETName | ETBigint | ETReference | ETBinder _ | ETOther _ as x), _ -> x
- | ETConstr None, _ -> ETConstr typ
- | ETConstrAsBinder (bk,None), _ -> ETConstrAsBinder (bk,typ)
- with Not_found -> ETConstr typ
+ | (ETIdent | ETBigint | ETGlobal | ETBinder _ as x), _ -> x
+ | ETConstr (s,bko,None), _ -> ETConstr (s,bko,typ)
+ with Not_found ->
+ ETConstr (from,None,typ)
in (x,typ)
let join_auxiliary_recursive_types recvars etyps =
@@ -941,8 +972,8 @@ let join_auxiliary_recursive_types recvars etyps =
let internalization_type_of_entry_type = function
| ETBinder _ -> NtnInternTypeOnlyBinder
- | ETConstr _ | ETConstrAsBinder _ | ETBigint | ETReference
- | ETName | ETPattern _ | ETOther _ -> NtnInternTypeAny
+ | ETConstr _ | ETBigint | ETGlobal
+ | ETIdent | ETPattern _ -> NtnInternTypeAny
let set_internalization_type typs =
List.map (fun (_, e) -> internalization_type_of_entry_type e) typs
@@ -953,20 +984,28 @@ let make_internalization_vars recvars mainvars typs =
maintyps @ extratyps
let make_interpretation_type isrec isonlybinding = function
- | ETConstr _ ->
- if isrec then NtnTypeConstrList else
- if isonlybinding then
- (* Parsed as constr, but interpreted as a binder: default is to parse it as an ident only *)
- NtnTypeBinder (NtnBinderParsedAsConstr AsIdent)
- else NtnTypeConstr
- | ETConstrAsBinder (bk,_) -> NtnTypeBinder (NtnBinderParsedAsConstr bk)
- | ETName -> NtnTypeBinder NtnParsedAsIdent
+ (* Parsed as constr list *)
+ | ETConstr (_,None,_) when isrec -> NtnTypeConstrList
+ (* Parsed as constr, but interpreted as a binder: default is to parse it as an ident only *)
+ | ETConstr (_,Some bk,_) -> NtnTypeBinder (NtnBinderParsedAsConstr bk)
+ | ETConstr (_,None,_) when isonlybinding -> NtnTypeBinder (NtnBinderParsedAsConstr AsIdent)
+ (* Parsed as constr, interpreted as constr *)
+ | ETConstr (_,None,_) -> NtnTypeConstr
+ (* Others *)
+ | ETIdent -> NtnTypeBinder NtnParsedAsIdent
| ETPattern (ppstrict,_) -> NtnTypeBinder (NtnParsedAsPattern ppstrict) (* Parsed as ident/pattern, primarily interpreted as binder; maybe strict at printing *)
- | ETBigint | ETReference | ETOther _ -> NtnTypeConstr
+ | ETBigint | ETGlobal -> NtnTypeConstr
| ETBinder _ ->
if isrec then NtnTypeBinderList
else anomaly Pp.(str "Type binder is only for use in recursive notations for binders.")
+let subentry_of_constr_prod_entry = function
+ | ETConstr (InCustomEntry s,_,(NumLevel n,_)) -> InCustomEntryLevel (s,n)
+ (* level and use of parentheses for coercion is hard-wired for "constr";
+ we don't remember the level *)
+ | ETConstr (InConstrEntry,_,_) -> InConstrEntrySomeLevel
+ | _ -> InConstrEntrySomeLevel
+
let make_interpretation_vars recvars allvars typs =
let eq_subscope (sc1, l1) (sc2, l2) =
Option.equal String.equal sc1 sc2 &&
@@ -982,7 +1021,9 @@ let make_interpretation_vars recvars allvars typs =
let mainvars =
Id.Map.filter (fun x _ -> not (Id.List.mem x useless_recvars)) allvars in
Id.Map.mapi (fun x (isonlybinding, sc) ->
- (sc, make_interpretation_type (Id.List.mem_assoc x recvars) isonlybinding (Id.List.assoc x typs))) mainvars
+ let typ = Id.List.assoc x typs in
+ ((subentry_of_constr_prod_entry typ,sc),
+ make_interpretation_type (Id.List.mem_assoc x recvars) isonlybinding typ)) mainvars
let check_rule_productivity l =
if List.for_all (function NonTerminal _ | Break _ -> true | _ -> false) l then
@@ -1008,17 +1049,42 @@ let warn_non_reversible_notation =
str " not occur in the right-hand side." ++ spc() ++
strbrk "The notation will not be used for printing as it is not reversible.")
-let is_not_printable onlyparse reversibility = function
-| NVar _ ->
- if not onlyparse then warn_notation_bound_to_variable ();
- true
+let make_custom_entry custom level =
+ match custom with
+ | InConstrEntry -> InConstrEntrySomeLevel
+ | InCustomEntry s -> InCustomEntryLevel (s,level)
+
+type entry_coercion_kind =
+ | IsEntryCoercion of notation_entry_level
+ | IsEntryGlobal of string * int
+ | IsEntryIdent of string * int
+
+let is_coercion = function
+ | Some (custom,n,_,[e]) ->
+ (match e, custom with
+ | ETConstr _, _ ->
+ let customkey = make_custom_entry custom n in
+ let subentry = subentry_of_constr_prod_entry e in
+ if notation_entry_level_eq subentry customkey then None
+ else Some (IsEntryCoercion subentry)
+ | ETGlobal, InCustomEntry s -> Some (IsEntryGlobal (s,n))
+ | ETIdent, InCustomEntry s -> Some (IsEntryIdent (s,n))
+ | _ -> None)
+ | Some _ -> assert false
+ | None -> None
+
+let printability level onlyparse reversibility = function
+| NVar _ when reversibility = APrioriReversible ->
+ let coe = is_coercion level in
+ if not onlyparse && coe = None then
+ warn_notation_bound_to_variable ();
+ true, coe
| _ ->
- if not onlyparse && reversibility <> APrioriReversible then
+ (if not onlyparse && reversibility <> APrioriReversible then
(warn_non_reversible_notation reversibility; true)
- else onlyparse
+ else onlyparse),None
-
-let find_precedence lev etyps symbols onlyprint =
+let find_precedence custom lev etyps symbols onlyprint =
let first_symbol =
let rec aux = function
| Break _ :: t -> aux t
@@ -1042,10 +1108,9 @@ let find_precedence lev etyps symbols onlyprint =
else [],Option.get lev
else
user_err Pp.(str "The level of the leftmost non-terminal cannot be changed.") in
- (try match List.assoc x etyps with
- | ETConstr _ -> test ()
- | ETConstrAsBinder (_,Some _) -> test ()
- | (ETName | ETBigint | ETReference) ->
+ (try match List.assoc x etyps, custom with
+ | ETConstr (s,_,Some _), s' when s = s' -> test ()
+ | (ETIdent | ETBigint | ETGlobal), _ ->
begin match lev with
| None ->
([Feedback.msg_info ?loc:None ,strbrk "Setting notation at level 0."],0)
@@ -1054,7 +1119,7 @@ let find_precedence lev etyps symbols onlyprint =
| _ ->
user_err Pp.(str "A notation starting with an atomic expression must be at level 0.")
end
- | (ETPattern _ | ETBinder _ | ETOther _ | ETConstrAsBinder _) ->
+ | (ETPattern _ | ETBinder _ | ETConstr _), _ ->
(* Give a default ? *)
if Option.is_empty lev then
user_err Pp.(str "Need an explicit level.")
@@ -1072,7 +1137,7 @@ let find_precedence lev etyps symbols onlyprint =
[],Option.get lev
let check_curly_brackets_notation_exists () =
- try let _ = Notation.level_of_notation "{ _ }" in ()
+ try let _ = Notgram_ops.level_of_notation (InConstrEntrySomeLevel,"{ _ }") in ()
with Not_found ->
user_err Pp.(str "Notations involving patterns of the form \"{ _ }\" are treated \n\
specially and require that the notation \"{ _ }\" is already reserved.")
@@ -1102,7 +1167,7 @@ let remove_curly_brackets l =
module SynData = struct
- type subentry_types = (Id.t * (production_level * production_position) constr_entry_key_gen) list
+ type subentry_types = (Id.t * constr_entry_key) list
(* XXX: Document *)
type syn_data = {
@@ -1114,7 +1179,7 @@ module SynData = struct
only_parsing : bool;
only_printing : bool;
compat : Flags.compat_version option;
- format : Misctypes.lstring option;
+ format : lstring option;
extra : (string * string) list;
(* XXX: Callback to printing, must remove *)
@@ -1136,7 +1201,7 @@ module SynData = struct
end
-let find_subentry_types n assoc etyps symbols =
+let find_subentry_types from n assoc etyps symbols =
let innerlevel = NumLevel 200 in
let typs =
find_symbols
@@ -1144,11 +1209,21 @@ let find_subentry_types n assoc etyps symbols =
(innerlevel,InternalProd)
(NumLevel n,BorderProd(Right,assoc))
symbols in
- let sy_typs = List.map (set_entry_type etyps) typs in
- let prec = List.map (assoc_of_type n) sy_typs in
+ let sy_typs = List.map (set_entry_type from etyps) typs in
+ let prec = List.map (assoc_of_type from n) sy_typs in
sy_typs, prec
-let compute_syntax_data df modifiers =
+let check_locality_compatibility local custom i_typs =
+ if not local then
+ let subcustom = List.map_filter (function _,ETConstr (InCustomEntry s,_,_) -> Some s | _ -> None) i_typs in
+ let allcustoms = match custom with InCustomEntry s -> s::subcustom | _ -> subcustom in
+ List.iter (fun s ->
+ if Egramcoq.locality_of_custom_entry s then
+ user_err (strbrk "Notation has to be declared local as it depends on custom entry " ++ str s ++
+ strbrk " which is local."))
+ (List.uniquize allcustoms)
+
+let compute_syntax_data local df modifiers =
let open SynData in
let open NotationMods in
let mods = interp_modifiers modifiers in
@@ -1161,25 +1236,28 @@ let compute_syntax_data df modifiers =
let _ = check_binder_type recvars mods.etyps in
(* Notations for interp and grammar *)
- let ntn_for_interp = make_notation_key symbols in
- let symbols_for_grammar = remove_curly_brackets symbols in
+ let msgs,n = find_precedence mods.custom mods.level mods.etyps symbols onlyprint in
+ let custom = make_custom_entry mods.custom n in
+ let ntn_for_interp = make_notation_key custom symbols in
+ let symbols_for_grammar =
+ if custom = InConstrEntrySomeLevel then remove_curly_brackets symbols else symbols in
let need_squash = not (List.equal Notation.symbol_eq symbols symbols_for_grammar) in
- let ntn_for_grammar = if need_squash then make_notation_key symbols_for_grammar else ntn_for_interp in
- if not onlyprint then check_rule_productivity symbols_for_grammar;
- let msgs,n = find_precedence mods.level mods.etyps symbols onlyprint in
+ let ntn_for_grammar = if need_squash then make_notation_key custom symbols_for_grammar else ntn_for_interp in
+ if mods.custom = InConstrEntry && not onlyprint then check_rule_productivity symbols_for_grammar;
(* To globalize... *)
let etyps = join_auxiliary_recursive_types recvars mods.etyps in
let sy_typs, prec =
- find_subentry_types n assoc etyps symbols in
+ find_subentry_types mods.custom n assoc etyps symbols in
let sy_typs_for_grammar, prec_for_grammar =
if need_squash then
- find_subentry_types n assoc etyps symbols_for_grammar
+ find_subentry_types mods.custom n assoc etyps symbols_for_grammar
else
sy_typs, prec in
let i_typs = set_internalization_type sy_typs in
+ check_locality_compatibility local mods.custom sy_typs;
let pa_sy_data = (sy_typs_for_grammar,symbols_for_grammar) in
let pp_sy_data = (sy_typs,symbols) in
- let sy_fulldata = (ntn_for_grammar,(n,prec_for_grammar,List.map snd sy_typs_for_grammar),need_squash) in
+ let sy_fulldata = (ntn_for_grammar,(mods.custom,n,prec_for_grammar,List.map snd sy_typs_for_grammar),need_squash) in
let df' = ((Lib.library_dp(),Lib.current_dirpath true),df) in
let i_data = ntn_for_interp, df' in
@@ -1198,15 +1276,15 @@ let compute_syntax_data df modifiers =
mainvars;
intern_typs = i_typs;
- level = (n,prec,List.map snd sy_typs);
+ level = (mods.custom,n,prec,List.map snd sy_typs);
pa_syntax_data = pa_sy_data;
pp_syntax_data = pp_sy_data;
not_data = sy_fulldata;
}
-let compute_pure_syntax_data df mods =
+let compute_pure_syntax_data local df mods =
let open SynData in
- let sd = compute_syntax_data df mods in
+ let sd = compute_syntax_data local df mods in
let msgs =
if sd.only_parsing then
(Feedback.msg_warning ?loc:None,
@@ -1221,6 +1299,7 @@ type notation_obj = {
notobj_local : bool;
notobj_scope : scope_name option;
notobj_interp : interpretation;
+ notobj_coercion : entry_coercion_kind option;
notobj_onlyparse : bool;
notobj_onlyprint : bool;
notobj_compat : Flags.compat_version option;
@@ -1242,7 +1321,13 @@ let open_notation i (_, nobj) =
let () = Notation.declare_notation_interpretation ntn scope pat df ~onlyprint in
(* Declare the uninterpretation *)
if not nobj.notobj_onlyparse then
- Notation.declare_uninterpretation (NotationRule (scope, ntn)) pat
+ Notation.declare_uninterpretation (NotationRule (scope, ntn)) pat;
+ (* Declare a possible coercion *)
+ (match nobj.notobj_coercion with
+ | Some (IsEntryCoercion entry) -> Notation.declare_entry_coercion ntn entry
+ | Some (IsEntryGlobal (entry,n)) -> Notation.declare_custom_entry_has_global entry n
+ | Some (IsEntryIdent (entry,n)) -> Notation.declare_custom_entry_has_ident entry n
+ | None -> ())
end
let cache_notation o =
@@ -1285,10 +1370,10 @@ exception NoSyntaxRule
let recover_notation_syntax ntn =
try
- let prec = Notation.level_of_notation ~onlyprint:true ntn (* Be as little restrictive as possible *) in
- let pp_rule,_ = Notation.find_notation_printing_rule ntn in
- let pp_extra_rules = Notation.find_notation_extra_printing_rules ntn in
- let pa_rule = Notation.find_notation_parsing_rules ntn in
+ let prec = Notgram_ops.level_of_notation ~onlyprint:true ntn (* Be as little restrictive as possible *) in
+ let pp_rule,_ = find_notation_printing_rule ntn in
+ let pp_extra_rules = find_notation_extra_printing_rules ntn in
+ let pa_rule = find_notation_parsing_rules ntn in
{ synext_level = prec;
synext_notation = ntn;
synext_notgram = pa_rule;
@@ -1300,7 +1385,7 @@ let recover_notation_syntax ntn =
raise NoSyntaxRule
let recover_squash_syntax sy =
- let sq = recover_notation_syntax "{ _ }" in
+ let sq = recover_notation_syntax (InConstrEntrySomeLevel,"{ _ }") in
sy :: sq.synext_notgram.notgram_rules
(**********************************************************************)
@@ -1335,8 +1420,9 @@ let make_pp_rule level (typs,symbols) fmt =
(* let make_syntax_rules i_typs (ntn,prec,need_squash) sy_data fmt extra onlyprint compat = *)
let make_syntax_rules (sd : SynData.syn_data) = let open SynData in
let ntn_for_grammar, prec_for_grammar, need_squash = sd.not_data in
+ let custom,level,_,_ = sd.level in
let pa_rule = make_pa_rule prec_for_grammar sd.pa_syntax_data ntn_for_grammar need_squash in
- let pp_rule = make_pp_rule (pi1 sd.level) sd.pp_syntax_data sd.format in {
+ let pp_rule = make_pp_rule (custom,level) sd.pp_syntax_data sd.format in {
synext_level = sd.level;
synext_notation = fst sd.info;
synext_notgram = { notgram_onlyprinting = sd.only_printing; notgram_rules = pa_rule };
@@ -1354,7 +1440,7 @@ let to_map l =
let add_notation_in_scope local df env c mods scope =
let open SynData in
- let sd = compute_syntax_data df mods in
+ let sd = compute_syntax_data local df mods in
(* Prepare the interpretation *)
(* Prepare the parsing and printing rules *)
let sy_rules = make_syntax_rules sd in
@@ -1366,13 +1452,14 @@ let add_notation_in_scope local df env c mods scope =
let (acvars, ac, reversibility) = interp_notation_constr env nenv c in
let interp = make_interpretation_vars sd.recvars acvars (fst sd.pa_syntax_data) in
let map (x, _) = try Some (x, Id.Map.find x interp) with Not_found -> None in
- let onlyparse = is_not_printable sd.only_parsing reversibility ac in
+ let onlyparse,coe = printability (Some sd.level) sd.only_parsing reversibility ac in
let notation = {
notobj_local = local;
notobj_scope = scope;
notobj_interp = (List.map_filter map i_vars, ac);
(** Order is important here! *)
notobj_onlyparse = onlyparse;
+ notobj_coercion = coe;
notobj_onlyprint = sd.only_printing;
notobj_compat = sd.compat;
notobj_notation = sd.info;
@@ -1386,16 +1473,17 @@ let add_notation_in_scope local df env c mods scope =
let add_notation_interpretation_core local df env ?(impls=empty_internalization_env) c scope onlyparse onlyprint compat =
let (recvars,mainvars,symbs) = analyze_notation_tokens ~onlyprint df in
(* Recover types of variables and pa/pp rules; redeclare them if needed *)
- let i_typs, onlyprint = if not (is_numeral symbs) then begin
- let sy = recover_notation_syntax (make_notation_key symbs) in
+ let level, i_typs, onlyprint = if not (is_numeral symbs) then begin
+ let sy = recover_notation_syntax (make_notation_key InConstrEntrySomeLevel symbs) in
let () = Lib.add_anonymous_leaf (inSyntaxExtension (local,sy)) in
(** If the only printing flag has been explicitly requested, put it back *)
let onlyprint = onlyprint || sy.synext_notgram.notgram_onlyprinting in
- pi3 sy.synext_level, onlyprint
- end else [], false in
+ let _,_,_,typs = sy.synext_level in
+ Some sy.synext_level, typs, onlyprint
+ end else None, [], false in
(* Declare interpretation *)
let path = (Lib.library_dp(), Lib.current_dirpath true) in
- let df' = (make_notation_key symbs, (path,df)) in
+ let df' = (make_notation_key InConstrEntrySomeLevel symbs, (path,df)) in
let i_vars = make_internalization_vars recvars mainvars (List.map internalization_type_of_entry_type i_typs) in
let nenv = {
ninterp_var_type = to_map i_vars;
@@ -1404,13 +1492,14 @@ let add_notation_interpretation_core local df env ?(impls=empty_internalization_
let (acvars, ac, reversibility) = interp_notation_constr env ~impls nenv c in
let interp = make_interpretation_vars recvars acvars (List.combine mainvars i_typs) in
let map (x, _) = try Some (x, Id.Map.find x interp) with Not_found -> None in
- let onlyparse = is_not_printable onlyparse reversibility ac in
+ let onlyparse,coe = printability level onlyparse reversibility ac in
let notation = {
notobj_local = local;
notobj_scope = scope;
notobj_interp = (List.map_filter map i_vars, ac);
(** Order is important here! *)
notobj_onlyparse = onlyparse;
+ notobj_coercion = coe;
notobj_onlyprint = onlyprint;
notobj_compat = compat;
notobj_notation = df';
@@ -1421,7 +1510,7 @@ let add_notation_interpretation_core local df env ?(impls=empty_internalization_
(* Notations without interpretation (Reserved Notation) *)
let add_syntax_extension local ({CAst.loc;v=df},mods) = let open SynData in
- let psd = compute_pure_syntax_data df mods in
+ let psd = compute_pure_syntax_data local df mods in
let sy_rules = make_syntax_rules {psd with compat = None} in
Flags.if_verbose (List.iter (fun (f,x) -> f x)) psd.msgs;
Lib.add_anonymous_leaf (inSyntaxExtension(local,sy_rules))
@@ -1461,12 +1550,12 @@ let add_notation local env c ({CAst.loc;v=df},modifiers) sc =
let add_notation_extra_printing_rule df k v =
let notk =
let _,_, symbs = analyze_notation_tokens ~onlyprint:true df in
- make_notation_key symbs in
- Notation.add_notation_extra_printing_rule notk k v
+ make_notation_key InConstrEntrySomeLevel symbs in
+ add_notation_extra_printing_rule notk k v
(* Infix notations *)
-let inject_var x = CAst.make @@ CRef (CAst.make @@ Ident (Id.of_string x),None)
+let inject_var x = CAst.make @@ CRef (qualid_of_ident (Id.of_string x),None)
let add_infix local env ({CAst.loc;v=inf},modifiers) pr sc =
check_infix_modifiers modifiers;
@@ -1545,7 +1634,35 @@ let add_syntactic_definition env ident (vars,c) local onlyparse =
List.map map vars, reversibility, pat
in
let onlyparse = match onlyparse with
- | None when (is_not_printable false reversibility pat) -> Some Flags.Current
+ | None when fst (printability None false reversibility pat) -> Some Flags.Current
| p -> p
in
Syntax_def.declare_syntactic_definition local ident onlyparse (vars,pat)
+
+(**********************************************************************)
+(* Declaration of custom entry *)
+
+let load_custom_entry _ _ = ()
+
+let open_custom_entry _ (_,(local,s)) =
+ Egramcoq.create_custom_entry ~local s
+
+let cache_custom_entry o =
+ load_custom_entry 1 o;
+ open_custom_entry 1 o
+
+let subst_custom_entry (subst,x) = x
+
+let classify_custom_entry (local,s as o) =
+ if local then Dispose else Substitute o
+
+let inCustomEntry : locality_flag * string -> obj =
+ declare_object {(default_object "CUSTOM-ENTRIES") with
+ cache_function = cache_custom_entry;
+ open_function = open_custom_entry;
+ load_function = load_custom_entry;
+ subst_function = subst_custom_entry;
+ classify_function = classify_custom_entry}
+
+let declare_custom_entry local s =
+ Lib.add_anonymous_leaf (inCustomEntry (local,s))
diff --git a/vernac/metasyntax.mli b/vernac/metasyntax.mli
index a6c12e08..73bee712 100644
--- a/vernac/metasyntax.mli
+++ b/vernac/metasyntax.mli
@@ -14,7 +14,6 @@ open Notation
open Constrexpr
open Notation_term
open Environ
-open Misctypes
val add_token_obj : string -> unit
@@ -61,3 +60,5 @@ val pr_grammar : string -> Pp.t
val check_infix_modifiers : syntax_modifier list -> unit
val with_syntax_protection : ('a -> 'b) -> 'a -> 'b
+
+val declare_custom_entry : locality_flag -> string -> unit
diff --git a/vernac/misctypes.ml b/vernac/misctypes.ml
new file mode 100644
index 00000000..ef9cd3c3
--- /dev/null
+++ b/vernac/misctypes.ml
@@ -0,0 +1,75 @@
+(* Compat module, to be removed in 8.10 *)
+open Names
+
+type lident = Names.lident
+[@@ocaml.deprecated "use [Names.lident"]
+type lname = Names.lname
+[@@ocaml.deprecated "use [Names.lname]"]
+type lstring = Names.lstring
+[@@ocaml.deprecated "use [Names.lstring]"]
+
+type 'a or_by_notation_r = 'a Constrexpr.or_by_notation_r =
+ | AN of 'a [@ocaml.deprecated "use version in [Constrexpr]"]
+ | ByNotation of (string * string option) [@ocaml.deprecated "use version in [Constrexpr]"]
+[@@ocaml.deprecated "use [Constrexpr.or_by_notation_r]"]
+
+type 'a or_by_notation = 'a Constrexpr.or_by_notation
+[@@ocaml.deprecated "use [Constrexpr.or_by_notation]"]
+
+type intro_pattern_naming_expr = Namegen.intro_pattern_naming_expr =
+ | IntroIdentifier of Id.t [@ocaml.deprecated "Use version in [Namegen]"]
+ | IntroFresh of Id.t [@ocaml.deprecated "Use version in [Namegen]"]
+ | IntroAnonymous [@ocaml.deprecated "Use version in [Namegen]"]
+[@@ocaml.deprecated "use [Namegen.intro_pattern_naming_expr]"]
+
+type 'a or_var = 'a Locus.or_var =
+ | ArgArg of 'a [@ocaml.deprecated "Use version in [Locus]"]
+ | ArgVar of Names.lident [@ocaml.deprecated "Use version in [Locus]"]
+[@@ocaml.deprecated "use [Locus.or_var]"]
+
+type quantified_hypothesis = Tactypes.quantified_hypothesis =
+ AnonHyp of int [@ocaml.deprecated "Use version in [Tactypes]"]
+ | NamedHyp of Id.t [@ocaml.deprecated "Use version in [Tactypes]"]
+[@@ocaml.deprecated "use [Tactypes.quantified_hypothesis]"]
+
+type multi = Equality.multi =
+ | Precisely of int [@ocaml.deprecated "use version in [Equality]"]
+ | UpTo of int [@ocaml.deprecated "use version in [Equality]"]
+ | RepeatStar [@ocaml.deprecated "use version in [Equality]"]
+ | RepeatPlus [@ocaml.deprecated "use version in [Equality]"]
+[@@ocaml.deprecated "use [Equality.multi]"]
+
+type 'a bindings = 'a Tactypes.bindings =
+ | ImplicitBindings of 'a list [@ocaml.deprecated "use version in [Tactypes]"]
+ | ExplicitBindings of 'a Tactypes.explicit_bindings [@ocaml.deprecated "use version in [Tactypes]"]
+ | NoBindings [@ocaml.deprecated "use version in [Tactypes]"]
+[@@ocaml.deprecated "use [Tactypes.bindings]"]
+
+type 'constr intro_pattern_expr = 'constr Tactypes.intro_pattern_expr =
+ | IntroForthcoming of bool [@ocaml.deprecated "use version in [Tactypes]"]
+ | IntroNaming of Namegen.intro_pattern_naming_expr [@ocaml.deprecated "use version in [Tactypes]"]
+ | IntroAction of 'constr Tactypes.intro_pattern_action_expr [@ocaml.deprecated "use version in [Tactypes]"]
+and 'constr intro_pattern_action_expr = 'constr Tactypes.intro_pattern_action_expr =
+ | IntroWildcard [@ocaml.deprecated "use [Tactypes]"]
+ | IntroOrAndPattern of 'constr Tactypes.or_and_intro_pattern_expr [@ocaml.deprecated "use [Tactypes]"]
+ | IntroInjection of ('constr intro_pattern_expr) CAst.t list [@ocaml.deprecated "use [Tactypes]"]
+ | IntroApplyOn of 'constr CAst.t * 'constr intro_pattern_expr CAst.t [@ocaml.deprecated "use [Tactypes]"]
+ | IntroRewrite of bool [@ocaml.deprecated "use [Tactypes]"]
+and 'constr or_and_intro_pattern_expr = 'constr Tactypes.or_and_intro_pattern_expr =
+ | IntroOrPattern of ('constr intro_pattern_expr) CAst.t list list [@ocaml.deprecated "use [Tactypes]"]
+ | IntroAndPattern of ('constr intro_pattern_expr) CAst.t list [@ocaml.deprecated "use [Tactypes]"]
+[@@ocaml.deprecated "use version in [Tactypes]"]
+
+type 'id move_location = 'id Logic.move_location =
+ | MoveAfter of 'id [@ocaml.deprecated "use version in [Logic]"]
+ | MoveBefore of 'id [@ocaml.deprecated "use version in [Logic]"]
+ | MoveFirst [@ocaml.deprecated "use version in [Logic]"]
+ | MoveLast [@ocaml.deprecated "use version in [Logic]"]
+[@@ocaml.deprecated "use version in [Logic]"]
+
+type 'a cast_type = 'a Glob_term.cast_type =
+ | CastConv of 'a [@ocaml.deprecated "use version in [Glob_term]"]
+ | CastVM of 'a [@ocaml.deprecated "use version in [Glob_term]"]
+ | CastCoerce [@ocaml.deprecated "use version in [Glob_term]"]
+ | CastNative of 'a [@ocaml.deprecated "use version in [Glob_term]"]
+[@@ocaml.deprecated "use version in [Glob_term]"]
diff --git a/vernac/mltop.ml b/vernac/mltop.ml
index 343b0925..d25dea14 100644
--- a/vernac/mltop.ml
+++ b/vernac/mltop.ml
@@ -345,13 +345,6 @@ let load_ml_object mname ?path fname=
let dir_ml_load m = ignore(dir_ml_load m)
let add_known_module m = add_known_module m None
-let load_ml_object_raw fname = dir_ml_load (file_of_name fname)
-let load_ml_objects_raw_rex rex =
- List.iter (fun (_,fp) ->
- let name = file_of_name (Filename.basename fp) in
- try dir_ml_load name
- with e -> prerr_endline (Printexc.to_string e))
- (System.where_in_path_rex !coq_mlpath_copy rex)
(* Summary of declared ML Modules *)
@@ -396,8 +389,6 @@ let trigger_ml_object verb cache reinit ?path name =
if cache then perform_cache_obj name
end
-let load_ml_object n m = ignore(load_ml_object n m)
-
let unfreeze_ml_modules x =
reset_loaded_modules ();
List.iter
diff --git a/vernac/mltop.mli b/vernac/mltop.mli
index da195f4f..ed1f9a12 100644
--- a/vernac/mltop.mli
+++ b/vernac/mltop.mli
@@ -68,9 +68,6 @@ val add_coq_path : coq_path -> unit
(** List of modules linked to the toplevel *)
val add_known_module : string -> unit
val module_is_known : string -> bool
-val load_ml_object : string -> string -> unit
-val load_ml_object_raw : string -> unit
-val load_ml_objects_raw_rex : Str.regexp -> unit
(** {5 Initialization functions} *)
diff --git a/vernac/obligations.ml b/vernac/obligations.ml
index 765d6851..2f7dee9a 100644
--- a/vernac/obligations.ml
+++ b/vernac/obligations.ml
@@ -40,7 +40,7 @@ let check_evars env evm =
type oblinfo =
{ ev_name: int * Id.t;
- ev_hyps: Context.Named.t;
+ ev_hyps: Constr.named_context;
ev_status: bool * Evar_kinds.obligation_definition_status;
ev_chop: int option;
ev_src: Evar_kinds.t Loc.located;
@@ -209,8 +209,10 @@ let eterm_obligations env name evm fs ?status t ty =
List.fold_right
(fun (id, (n, nstr), ev) l ->
let hyps = Evd.evar_filtered_context ev in
- let hyps = trunc_named_context nc_len hyps in
- let evtyp, deps, transp = etype_of_evar l hyps ev.evar_concl in
+ let hyps = trunc_named_context nc_len hyps in
+ let hyps = EConstr.Unsafe.to_named_context hyps in
+ let concl = EConstr.Unsafe.to_constr ev.evar_concl in
+ let evtyp, deps, transp = etype_of_evar l hyps concl in
let evtyp, hyps, chop =
match chop_product fs evtyp with
| Some t -> t, trunc_named_context fs hyps, fs
@@ -218,7 +220,7 @@ let eterm_obligations env name evm fs ?status t ty =
in
let loc, k = evar_source id evm in
let status = match k with
- | Evar_kinds.QuestionMark (o,_) -> o
+ | Evar_kinds.QuestionMark { Evar_kinds.qm_obligation=o } -> o
| _ -> match status with
| Some o -> o
| None -> Evar_kinds.Define (not (Program.get_proofs_transparency ()))
@@ -257,14 +259,16 @@ let eterm_obligations env name evm fs ?status t ty =
let tactics_module = ["Program";"Tactics"]
let safe_init_constant md name () =
Coqlib.check_required_library ("Coq"::md);
- Universes.constr_of_global (Coqlib.coq_reference "Obligations" md name)
+ UnivGen.constr_of_global (Coqlib.coq_reference "Obligations" md name)
let hide_obligation = safe_init_constant tactics_module "obligation"
let pperror cmd = CErrors.user_err ~hdr:"Program" cmd
let error s = pperror (str s)
let reduce c =
- EConstr.Unsafe.to_constr (Reductionops.clos_norm_flags CClosure.betaiota (Global.env ()) Evd.empty (EConstr.of_constr c))
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ EConstr.Unsafe.to_constr (Reductionops.clos_norm_flags CClosure.betaiota env sigma (EConstr.of_constr c))
exception NoObligations of Id.t option
@@ -294,17 +298,17 @@ type obligation =
type obligations = (obligation array * int)
type fixpoint_kind =
- | IsFixpoint of (Misctypes.lident option * Constrexpr.recursion_order_expr) list
+ | IsFixpoint of (lident option * Constrexpr.recursion_order_expr) list
| IsCoFixpoint
-type notations = (Misctypes.lstring * Constrexpr.constr_expr * Notation_term.scope_name option) list
+type notations = (lstring * Constrexpr.constr_expr * Notation_term.scope_name option) list
type program_info_aux = {
prg_name: Id.t;
prg_body: constr;
prg_type: constr;
prg_ctx: UState.t;
- prg_univdecl: Univdecls.universe_decl;
+ prg_univdecl: UState.universe_decl;
prg_obligations: obligations;
prg_deps : Id.t list;
prg_fixkind : fixpoint_kind option ;
@@ -338,7 +342,7 @@ open Goptions
let _ =
declare_bool_option
{ optdepr = false;
- optname = "Hidding of Program obligations";
+ optname = "Hiding of Program obligations";
optkey = ["Hide";"Obligations"];
optread = get_hide_obligations;
optwrite = set_hide_obligations; }
@@ -356,7 +360,7 @@ let _ =
optread = get_shrink_obligations;
optwrite = set_shrink_obligations; }
-let evar_of_obligation o = make_evar (Global.named_context_val ()) o.obl_type
+let evar_of_obligation o = make_evar (Global.named_context_val ()) (EConstr.of_constr o.obl_type)
let get_obligation_body expand obl =
match obl.obl_body with
@@ -470,16 +474,15 @@ let subst_body expand prg =
let declare_definition prg =
let body, typ = subst_body true prg in
- let nf = Universes.nf_evars_and_universes_opt_subst (fun x -> None)
+ let nf = UnivSubst.nf_evars_and_universes_opt_subst (fun x -> None)
(UState.subst prg.prg_ctx) in
let opaque = prg.prg_opaque in
let fix_exn = Hook.get get_fix_exn () in
let typ = nf typ in
let body = nf body in
- let env = Global.env () in
let uvars = Univ.LSet.union
- (Univops.universes_of_constr env typ)
- (Univops.universes_of_constr env body) in
+ (Univops.universes_of_constr typ)
+ (Univops.universes_of_constr body) in
let uctx = UState.restrict prg.prg_ctx uvars in
let univs = UState.check_univ_decl ~poly:(pi2 prg.prg_kind) uctx prg.prg_univdecl in
let ce = definition_entry ~fix_exn ~opaque ~types:typ ~univs body in
@@ -555,7 +558,7 @@ let declare_mutual_definition l =
(* Declare the recursive definitions *)
let univs = UState.const_univ_entry ~poly first.prg_ctx in
let fix_exn = Hook.get get_fix_exn () in
- let kns = List.map4 (DeclareDef.declare_fix ~opaque (local, poly, kind) Universes.empty_binders univs)
+ let kns = List.map4 (DeclareDef.declare_fix ~opaque (local, poly, kind) UnivNames.empty_binders univs)
fixnames fixdecls fixtypes fiximps in
(* Declare notations *)
List.iter (Metasyntax.add_notation_interpretation (Global.env())) first.prg_notations;
@@ -611,7 +614,7 @@ let shrink_body c ty =
let unfold_entry cst = Hints.HintsUnfoldEntry [EvalConstRef cst]
let add_hint local prg cst =
- Hints.add_hints local [Id.to_string prg.prg_name] (unfold_entry cst)
+ Hints.add_hints ~local [Id.to_string prg.prg_name] (unfold_entry cst)
let it_mkLambda_or_LetIn_or_clean t ctx =
let open Context.Rel.Declaration in
@@ -743,7 +746,7 @@ let all_programs () =
type progress =
| Remain of int
| Dependent
- | Defined of global_reference
+ | Defined of GlobRef.t
let obligations_message rem =
if rem > 0 then
@@ -814,10 +817,9 @@ let rec string_of_list sep f = function
let solve_by_tac name evi t poly ctx =
let id = name in
- let concl = EConstr.of_constr evi.evar_concl in
(* spiwack: the status is dropped. *)
let (entry,_,ctx') = Pfedit.build_constant_by_tactic
- id ~goal_kind:(goal_kind poly) ctx evi.evar_hyps concl (Tacticals.New.tclCOMPLETE t) in
+ id ~goal_kind:(goal_kind poly) ctx evi.evar_hyps evi.evar_concl (Tacticals.New.tclCOMPLETE t) in
let env = Global.env () in
let entry = Safe_typing.inline_private_constants_in_definition_entry env entry in
let body, () = Future.force entry.const_entry_body in
@@ -849,12 +851,12 @@ let obligation_terminator name num guard hook auto pf =
let obl = obls.(num) in
let status =
match obl.obl_status, opq with
- | (_, Evar_kinds.Expand), Vernacexpr.Opaque -> err_not_transp ()
- | (true, _), Vernacexpr.Opaque -> err_not_transp ()
- | (false, _), Vernacexpr.Opaque -> Evar_kinds.Define true
- | (_, Evar_kinds.Define true), Vernacexpr.Transparent ->
+ | (_, Evar_kinds.Expand), Opaque -> err_not_transp ()
+ | (true, _), Opaque -> err_not_transp ()
+ | (false, _), Opaque -> Evar_kinds.Define true
+ | (_, Evar_kinds.Define true), Transparent ->
Evar_kinds.Define false
- | (_, status), Vernacexpr.Transparent -> status
+ | (_, status), Transparent -> status
in
let obl = { obl with obl_status = false, status } in
let ctx =
@@ -893,7 +895,7 @@ let obligation_terminator name num guard hook auto pf =
let obligation_hook prg obl num auto ctx' _ gr =
let obls, rem = prg.prg_obligations in
- let cst = match gr with ConstRef cst -> cst | _ -> assert false in
+ let cst = match gr with GlobRef.ConstRef cst -> cst | _ -> assert false in
let transparent = evaluable_constant cst (Global.env ()) in
let () = match obl.obl_status with
(true, Evar_kinds.Expand)
@@ -1071,9 +1073,11 @@ let show_obligations_of_prg ?(msg=true) prg =
if !showed > 0 then (
decr showed;
let x = subst_deps_obl obls x in
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
Feedback.msg_info (str "Obligation" ++ spc() ++ int (succ i) ++ spc () ++
str "of" ++ spc() ++ Id.print n ++ str ":" ++ spc () ++
- hov 1 (Printer.pr_constr_env (Global.env ()) Evd.empty x.obl_type ++
+ hov 1 (Printer.pr_constr_env env sigma x.obl_type ++
str "." ++ fnl ())))
| Some _ -> ())
obls
@@ -1089,11 +1093,13 @@ let show_obligations ?(msg=true) n =
let show_term n =
let prg = get_prog_err n in
let n = prg.prg_name in
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
(Id.print n ++ spc () ++ str":" ++ spc () ++
- Printer.pr_constr_env (Global.env ()) Evd.empty prg.prg_type ++ spc () ++ str ":=" ++ fnl ()
- ++ Printer.pr_constr_env (Global.env ()) Evd.empty prg.prg_body)
+ Printer.pr_constr_env env sigma prg.prg_type ++ spc () ++ str ":=" ++ fnl ()
+ ++ Printer.pr_constr_env env sigma prg.prg_body)
-let add_definition n ?term t ctx ?(univdecl=Univdecls.default_univ_decl)
+let add_definition n ?term t ctx ?(univdecl=UState.default_univ_decl)
?(implicits=[]) ?(kind=Global,false,Definition) ?tactic
?(reduce=reduce) ?(hook=Lemmas.mk_hook (fun _ _ _ -> ())) ?(opaque = false) obls =
let sign = Decls.initialize_named_context_for_proof () in
@@ -1113,7 +1119,7 @@ let add_definition n ?term t ctx ?(univdecl=Univdecls.default_univ_decl)
| Remain rem -> Flags.if_verbose (fun () -> show_obligations ~msg:false (Some n)) (); res
| _ -> res)
-let add_mutual_definitions l ctx ?(univdecl=Univdecls.default_univ_decl) ?tactic
+let add_mutual_definitions l ctx ?(univdecl=UState.default_univ_decl) ?tactic
?(kind=Global,false,Definition) ?(reduce=reduce)
?(hook=Lemmas.mk_hook (fun _ _ _ -> ())) ?(opaque = false) notations fixkind =
let sign = Decls.initialize_named_context_for_proof () in
diff --git a/vernac/obligations.mli b/vernac/obligations.mli
index cc2cacd8..a37c30aa 100644
--- a/vernac/obligations.mli
+++ b/vernac/obligations.mli
@@ -12,7 +12,6 @@ open Environ
open Constr
open Evd
open Names
-open Globnames
(* This is a hack to make it possible for Obligations to craft a Qed
* behind the scenes. The fix_exn the Stm attaches to the Future proof
@@ -49,13 +48,13 @@ type obligation_info =
type progress = (* Resolution status of a program *)
| Remain of int (* n obligations remaining *)
| Dependent (* Dependent on other definitions *)
- | Defined of global_reference (* Defined as id *)
+ | Defined of GlobRef.t (* Defined as id *)
val default_tactic : unit Proofview.tactic ref
val add_definition : Names.Id.t -> ?term:constr -> types ->
UState.t ->
- ?univdecl:Univdecls.universe_decl -> (* Universe binders and constraints *)
+ ?univdecl:UState.universe_decl -> (* Universe binders and constraints *)
?implicits:(Constrexpr.explicitation * (bool * bool * bool)) list ->
?kind:Decl_kinds.definition_kind ->
?tactic:unit Proofview.tactic ->
@@ -63,17 +62,17 @@ val add_definition : Names.Id.t -> ?term:constr -> types ->
?hook:(UState.t -> unit) Lemmas.declaration_hook -> ?opaque:bool -> obligation_info -> progress
type notations =
- (Misctypes.lstring * Constrexpr.constr_expr * Notation_term.scope_name option) list
+ (lstring * Constrexpr.constr_expr * Notation_term.scope_name option) list
type fixpoint_kind =
- | IsFixpoint of (Misctypes.lident option * Constrexpr.recursion_order_expr) list
+ | IsFixpoint of (lident option * Constrexpr.recursion_order_expr) list
| IsCoFixpoint
val add_mutual_definitions :
(Names.Id.t * constr * types *
(Constrexpr.explicitation * (bool * bool * bool)) list * obligation_info) list ->
UState.t ->
- ?univdecl:Univdecls.universe_decl -> (* Universe binders and constraints *)
+ ?univdecl:UState.universe_decl -> (* Universe binders and constraints *)
?tactic:unit Proofview.tactic ->
?kind:Decl_kinds.definition_kind ->
?reduce:(constr -> constr) ->
diff --git a/printing/ppvernac.ml b/vernac/ppvernac.ml
index 5c5b7206..ecebcf52 100644
--- a/printing/ppvernac.ml
+++ b/vernac/ppvernac.ml
@@ -16,12 +16,12 @@ open Util
open CAst
open Extend
-open Vernacexpr
-open Pputils
-open Libnames
+open Decl_kinds
open Constrexpr
open Constrexpr_ops
-open Decl_kinds
+open Vernacexpr
+open Declaremods
+open Pputils
open Ppconstr
@@ -54,7 +54,7 @@ open Decl_kinds
(if extensible then str"+" else mt())
let pr_universe_decl l =
- let open Misctypes in
+ let open UState in
match l with
| None -> mt ()
| Some l ->
@@ -78,13 +78,13 @@ open Decl_kinds
let pr_lname_decl (n, u) =
pr_lname n ++ pr_universe_decl u
- let pr_smart_global = Pputils.pr_or_by_notation pr_reference
+ let pr_smart_global = Pputils.pr_or_by_notation pr_qualid
- let pr_ltac_ref = Libnames.pr_reference
+ let pr_ltac_ref = Libnames.pr_qualid
- let pr_module = Libnames.pr_reference
+ let pr_module = Libnames.pr_qualid
- let pr_import_module = Libnames.pr_reference
+ let pr_import_module = Libnames.pr_qualid
let sep_end = function
| VernacBullet _
@@ -97,25 +97,27 @@ open Decl_kinds
let sep = fun _ -> spc()
let sep_v2 = fun _ -> str"," ++ spc()
+ let pr_notation_entry = function
+ | InConstrEntry -> keyword "constr"
+ | InCustomEntry s -> keyword "custom" ++ spc () ++ str s
+
let pr_at_level = function
| NumLevel n -> keyword "at" ++ spc () ++ keyword "level" ++ spc () ++ int n
| NextLevel -> keyword "at" ++ spc () ++ keyword "next" ++ spc () ++ keyword "level"
- let pr_constr_as_binder_kind = function
- | AsIdent -> keyword "as ident"
- | AsIdentOrPattern -> keyword "as pattern"
- | AsStrictPattern -> keyword "as strict pattern"
+ let pr_constr_as_binder_kind = let open Notation_term in function
+ | AsIdent -> spc () ++ keyword "as ident"
+ | AsIdentOrPattern -> spc () ++ keyword "as pattern"
+ | AsStrictPattern -> spc () ++ keyword "as strict pattern"
let pr_strict b = if b then str "strict " else mt ()
let pr_set_entry_type pr = function
- | ETName -> str"ident"
- | ETReference -> str"global"
+ | ETIdent -> str"ident"
+ | ETGlobal -> str"global"
| ETPattern (b,None) -> pr_strict b ++ str"pattern"
| ETPattern (b,Some n) -> pr_strict b ++ str"pattern" ++ spc () ++ pr_at_level (NumLevel n)
- | ETConstr lev -> str"constr" ++ pr lev
- | ETOther (_,e) -> str e
- | ETConstrAsBinder (bk,lev) -> pr lev ++ spc () ++ pr_constr_as_binder_kind bk
+ | ETConstr (s,bko,lev) -> pr_notation_entry s ++ pr lev ++ pr_opt pr_constr_as_binder_kind bko
| ETBigint -> str "bigint"
| ETBinder true -> str "binder"
| ETBinder false -> str "closed binder"
@@ -144,26 +146,17 @@ open Decl_kinds
| SearchString (s,sc) -> qs s ++ pr_opt (fun sc -> str "%" ++ str sc) sc
let pr_search a gopt b pr_p =
- pr_opt (fun g -> Proof_bullet.pr_goal_selector g ++ str ":"++ spc()) gopt
+ pr_opt (fun g -> Goal_select.pr_goal_selector g ++ str ":"++ spc()) gopt
++
match a with
| SearchHead c -> keyword "SearchHead" ++ spc() ++ pr_p c ++ pr_in_out_modules b
| SearchPattern c -> keyword "SearchPattern" ++ spc() ++ pr_p c ++ pr_in_out_modules b
| SearchRewrite c -> keyword "SearchRewrite" ++ spc() ++ pr_p c ++ pr_in_out_modules b
| SearchAbout sl ->
- keyword "Search" ++ spc() ++ prlist_with_sep spc pr_search_about sl ++ pr_in_out_modules b
-
- let pr_locality local = if local then keyword "Local" else keyword "Global"
-
- let pr_explanation (e,b,f) =
- let a = match e with
- | ExplByPos (n,_) -> anomaly (Pp.str "No more supported.")
- | ExplByName id -> pr_id id in
- let a = if f then str"!" ++ a else a in
- if b then str "[" ++ a ++ str "]" else a
+ keyword "Search" ++ spc() ++ prlist_with_sep spc pr_search_about sl ++ pr_in_out_modules b
let pr_option_ref_value = function
- | QualidRefValue id -> pr_reference id
+ | QualidRefValue id -> pr_qualid id
| StringRefValue s -> qs s
let pr_printoption table b =
@@ -181,50 +174,55 @@ open Decl_kinds
| BoolValue b -> mt()
in pr_printoption a None ++ pr_opt_value b
- let pr_topcmd _ = str"(* <Warning> : No printer for toplevel commands *)"
-
let pr_opt_hintbases l = match l with
| [] -> mt()
| _ as z -> str":" ++ spc() ++ prlist_with_sep sep str z
- let pr_reference_or_constr pr_c = function
- | HintsReference r -> pr_reference r
+ let pr_reference_or_constr pr_c = let open Hints in function
+ | HintsReference r -> pr_qualid r
| HintsConstr c -> pr_c c
- let pr_hint_mode = function
+ let pr_hint_mode = let open Hints in function
| ModeInput -> str"+"
| ModeNoHeadEvar -> str"!"
| ModeOutput -> str"-"
- let pr_hint_info pr_pat { hint_priority = pri; hint_pattern = pat } =
+ let pr_hint_info pr_pat { Typeclasses.hint_priority = pri; hint_pattern = pat } =
pr_opt (fun x -> str"|" ++ int x) pri ++
pr_opt (fun y -> (if Option.is_empty pri then str"| " else mt()) ++ pr_pat y) pat
let pr_hints db h pr_c pr_pat =
let opth = pr_opt_hintbases db in
let pph =
+ let open Hints in
match h with
| HintsResolve l ->
keyword "Resolve " ++ prlist_with_sep sep
(fun (info, _, c) -> pr_reference_or_constr pr_c c ++ pr_hint_info pr_pat info)
l
+ | HintsResolveIFF (l2r, l, n) ->
+ keyword "Resolve " ++ str (if l2r then "->" else "<-")
+ ++ prlist_with_sep sep pr_qualid l
| HintsImmediate l ->
keyword "Immediate" ++ spc() ++
prlist_with_sep sep (fun c -> pr_reference_or_constr pr_c c) l
| HintsUnfold l ->
- keyword "Unfold" ++ spc () ++ prlist_with_sep sep pr_reference l
+ keyword "Unfold" ++ spc () ++ prlist_with_sep sep pr_qualid l
| HintsTransparency (l, b) ->
keyword (if b then "Transparent" else "Opaque")
++ spc ()
- ++ prlist_with_sep sep pr_reference l
+ ++ (match l with
+ | HintsVariables -> keyword "Variables"
+ | HintsConstants -> keyword "Constants"
+ | HintsReferences l -> prlist_with_sep sep pr_qualid l)
| HintsMode (m, l) ->
keyword "Mode"
++ spc ()
- ++ pr_reference m ++ spc() ++
+ ++ pr_qualid m ++ spc() ++
prlist_with_sep spc pr_hint_mode l
| HintsConstructors c ->
keyword "Constructors"
- ++ spc() ++ prlist_with_sep spc pr_reference c
+ ++ spc() ++ prlist_with_sep spc pr_qualid c
| HintsExtern (n,c,tac) ->
let pat = match c with None -> mt () | Some pat -> pr_pat pat in
keyword "Extern" ++ spc() ++ int n ++ spc() ++ pat ++ str" =>" ++
@@ -238,7 +236,7 @@ open Decl_kinds
keyword "Definition" ++ spc() ++ pr_lfqid id ++ pr_universe_decl udecl ++ str" := " ++ p
| CWith_Module (id,qid) ->
keyword "Module" ++ spc() ++ pr_lfqid id ++ str" := " ++
- pr_ast pr_qualid qid
+ pr_qualid qid
let rec pr_module_ast leading_space pr_c = function
| { loc ; v = CMident qid } ->
@@ -291,7 +289,7 @@ open Decl_kinds
prlist_strict (pr_module_vardecls pr_c) l
let pr_type_option pr_c = function
- | { v = CHole (k, Misctypes.IntroAnonymous, _) } -> mt()
+ | { v = CHole (k, Namegen.IntroAnonymous, _) } -> mt()
| _ as c -> brk(0,2) ++ str" :" ++ pr_c c
let pr_decl_notation prc ({loc; v=ntn},c,scopt) =
@@ -383,12 +381,11 @@ open Decl_kinds
let pr_thm_token k = keyword (Kindops.string_of_theorem_kind k)
let pr_syntax_modifier = function
- | SetItemLevel (l,n) ->
- prlist_with_sep sep_v2 str l ++ spc () ++ pr_at_level n
- | SetItemLevelAsBinder (l,bk,n) ->
- prlist_with_sep sep_v2 str l ++
- spc() ++ pr_at_level_opt n ++ spc() ++ pr_constr_as_binder_kind bk
+ | SetItemLevel (l,bko,n) ->
+ prlist_with_sep sep_v2 str l ++ spc () ++ pr_at_level_opt n ++
+ pr_opt pr_constr_as_binder_kind bko
| SetLevel n -> pr_at_level (NumLevel n)
+ | SetCustomEntry (s,n) -> keyword "in" ++ spc() ++ keyword "custom" ++ spc() ++ str s ++ (match n with None -> mt () | Some n -> pr_at_level (NumLevel n))
| SetAssoc LeftA -> keyword "left associativity"
| SetAssoc RightA -> keyword "right associativity"
| SetAssoc NonA -> keyword "no associativity"
@@ -456,7 +453,7 @@ open Decl_kinds
| PrintFullContext ->
keyword "Print All"
| PrintSectionContext s ->
- keyword "Print Section" ++ spc() ++ Libnames.pr_reference s
+ keyword "Print Section" ++ spc() ++ Libnames.pr_qualid s
| PrintGrammar ent ->
keyword "Print Grammar" ++ spc() ++ str ent
| PrintLoadPath dir ->
@@ -504,9 +501,9 @@ open Decl_kinds
| PrintName (qid,udecl) ->
keyword "Print" ++ spc() ++ pr_smart_global qid ++ pr_univ_name_list udecl
| PrintModuleType qid ->
- keyword "Print Module Type" ++ spc() ++ pr_reference qid
+ keyword "Print Module Type" ++ spc() ++ pr_qualid qid
| PrintModule qid ->
- keyword "Print Module" ++ spc() ++ pr_reference qid
+ keyword "Print Module" ++ spc() ++ pr_qualid qid
| PrintInspect n ->
keyword "Inspect" ++ spc() ++ int n
| PrintScopes ->
@@ -516,7 +513,7 @@ open Decl_kinds
| PrintVisibility s ->
keyword "Print Visibility" ++ pr_opt str s
| PrintAbout (qid,l,gopt) ->
- pr_opt (fun g -> Proof_bullet.pr_goal_selector g ++ str ":"++ spc()) gopt
+ pr_opt (fun g -> Goal_select.pr_goal_selector g ++ str ":"++ spc()) gopt
++ keyword "About" ++ spc() ++ pr_smart_global qid ++ pr_univ_name_list l
| PrintImplicit qid ->
keyword "Print Implicit" ++ spc() ++ pr_smart_global qid
@@ -593,8 +590,6 @@ open Decl_kinds
)
| VernacUndoTo i ->
return (keyword "Undo" ++ spc() ++ keyword "To" ++ pr_intarg i)
- | VernacBacktrack (i,j,k) ->
- return (keyword "Backtrack" ++ spc() ++ prlist_with_sep sep int [i;j;k])
| VernacFocus i ->
return (keyword "Focus" ++ pr_opt int i)
| VernacShow s ->
@@ -611,7 +606,7 @@ open Decl_kinds
| ShowUniverses -> keyword "Show Universes"
| ShowProofNames -> keyword "Show Conjectures"
| ShowIntros b -> keyword "Show " ++ (if b then keyword "Intros" else keyword "Intro")
- | ShowMatch id -> keyword "Show Match " ++ pr_reference id
+ | ShowMatch id -> keyword "Show Match " ++ pr_qualid id
in
return (pr_showable s)
| VernacCheckGuard ->
@@ -655,16 +650,6 @@ open Decl_kinds
keyword "Bind Scope" ++ spc () ++ str sc ++
spc() ++ keyword "with" ++ spc () ++ prlist_with_sep spc pr_class_rawexpr cll
)
- | VernacArgumentsScope (q,scl) ->
- let pr_opt_scope = function
- | None -> str"_"
- | Some sc -> str sc
- in
- return (
- keyword "Arguments Scope"
- ++ spc() ++ pr_smart_global q
- ++ spc() ++ str"[" ++ prlist_with_sep sep pr_opt_scope scl ++ str"]"
- )
| VernacInfix (({v=s},mv),q,sn) -> (* A Verifier *)
return (
hov 0 (hov 0 (keyword "Infix "
@@ -691,6 +676,10 @@ open Decl_kinds
return (
keyword "Format Notation " ++ qs s ++ spc () ++ qs k ++ spc() ++ qs v
)
+ | VernacDeclareCustomEntry s ->
+ return (
+ keyword "Declare Custom Entry " ++ str s
+ )
(* Gallina *)
| VernacDefinition ((discharge,kind),id,b) -> (* A verifier... *)
@@ -737,6 +726,7 @@ open Decl_kinds
return (keyword "Admitted")
| VernacEndProof (Proved (opac,o)) -> return (
+ let open Proof_global in
match o with
| None -> (match opac with
| Transparent -> keyword "Defined"
@@ -788,8 +778,9 @@ open Decl_kinds
if p then
let cm =
match cum with
- | GlobalCumulativity | LocalCumulativity -> "Cumulative"
- | GlobalNonCumulativity | LocalNonCumulativity -> "NonCumulative"
+ | Some VernacCumulative -> "Cumulative"
+ | Some VernacNonCumulative -> "NonCumulative"
+ | None -> ""
in
cm ^ " " ^ kind
else kind
@@ -916,7 +907,7 @@ open Decl_kinds
| VernacDeclareInstances insts ->
let pr_inst (id, info) =
- pr_reference id ++ pr_hint_info pr_constr_pattern_expr info
+ pr_qualid id ++ pr_hint_info pr_constr_pattern_expr info
in
return (
hov 1 (keyword "Existing" ++ spc () ++
@@ -926,7 +917,7 @@ open Decl_kinds
| VernacDeclareClass id ->
return (
- hov 1 (keyword "Existing" ++ spc () ++ keyword "Class" ++ spc () ++ pr_reference id)
+ hov 1 (keyword "Existing" ++ spc () ++ keyword "Class" ++ spc () ++ pr_qualid id)
)
(* Modules and Module Types *)
@@ -1018,18 +1009,6 @@ open Decl_kinds
| Some Flags.Current -> [SetOnlyParsing]
| Some v -> [SetCompatVersion v]))
)
- | VernacDeclareImplicits (q,[]) ->
- return (
- hov 2 (keyword "Implicit Arguments" ++ spc() ++ pr_smart_global q)
- )
- | VernacDeclareImplicits (q,impls) ->
- return (
- hov 1 (keyword "Implicit Arguments" ++ spc () ++
- spc() ++ pr_smart_global q ++ spc() ++
- prlist_with_sep spc (fun imps ->
- str"[" ++ prlist_with_sep sep pr_explanation imps ++ str"]")
- impls)
- )
| VernacArguments (q, args, more_implicits, nargs, mods) ->
return (
hov 2 (
@@ -1153,7 +1132,7 @@ open Decl_kinds
| None -> hov 2 (keyword "Check" ++ spc() ++ pr_lconstr c)
in
let pr_i = match io with None -> mt ()
- | Some i -> Proof_bullet.pr_goal_selector i ++ str ": " in
+ | Some i -> Goal_select.pr_goal_selector i ++ str ": " in
return (pr_i ++ pr_mayeval r c)
| VernacGlobalCheck c ->
return (hov 2 (keyword "Type" ++ pr_constrarg c))
@@ -1188,10 +1167,6 @@ open Decl_kinds
++ prlist_with_sep sep (pr_comment pr_constr) l)
)
- (* Toplevel control *)
- | VernacToplevelControl exn ->
- return (pr_topcmd exn)
-
(* For extension *)
| VernacExtend (s,c) ->
return (pr_extend s c)
@@ -1211,7 +1186,8 @@ open Decl_kinds
| VernacProofMode s ->
return (keyword "Proof Mode" ++ str s)
| VernacBullet b ->
- return (begin match b with
+ (* XXX: Redundant with Proof_bullet.print *)
+ return (let open Proof_bullet in begin match b with
| Dash n -> str (String.make n '-')
| Star n -> str (String.make n '*')
| Plus n -> str (String.make n '+')
@@ -1219,25 +1195,28 @@ open Decl_kinds
| VernacSubproof None ->
return (str "{")
| VernacSubproof (Some i) ->
- return (Proof_bullet.pr_goal_selector i ++ str ":" ++ spc () ++ str "{")
+ return (Goal_select.pr_goal_selector i ++ str ":" ++ spc () ++ str "{")
| VernacEndSubproof ->
return (str "}")
-let pr_vernac_flag =
+let rec pr_vernac_flag (k, v) =
+ let k = keyword k in
+ match v with
+ | VernacFlagEmpty -> k
+ | VernacFlagLeaf v -> k ++ str " = " ++ qs v
+ | VernacFlagList m -> k ++ str "( " ++ pr_vernac_flags m ++ str " )"
+and pr_vernac_flags m =
+ prlist_with_sep (fun () -> str ", ") pr_vernac_flag m
+
+let pr_vernac_attributes =
function
- | VernacPolymorphic true -> keyword "Polymorphic"
- | VernacPolymorphic false -> keyword "Monomorphic"
- | VernacProgram -> keyword "Program"
- | VernacLocal local -> pr_locality local
+ | [] -> mt ()
+ | flags -> str "#[" ++ pr_vernac_flags flags ++ str "]" ++ cut ()
let rec pr_vernac_control v =
let return = tag_vernac v in
match v with
- | VernacExpr (f, v') ->
- List.fold_right
- (fun f a -> pr_vernac_flag f ++ spc() ++ a)
- f
- (pr_vernac_expr v' ++ sep_end v')
+ | VernacExpr (f, v') -> pr_vernac_attributes f ++ pr_vernac_expr v' ++ sep_end v'
| VernacTime (_,{v}) ->
return (keyword "Time" ++ spc() ++ pr_vernac_control v)
| VernacRedirect (s, {v}) ->
diff --git a/printing/ppvernac.mli b/vernac/ppvernac.mli
index 4aa24bf5..4aa24bf5 100644
--- a/printing/ppvernac.mli
+++ b/vernac/ppvernac.mli
diff --git a/vernac/proof_using.ml b/vernac/proof_using.ml
index f8b085f3..3e2bd987 100644
--- a/vernac/proof_using.ml
+++ b/vernac/proof_using.ml
@@ -18,14 +18,6 @@ module NamedDecl = Context.Named.Declaration
let known_names = Summary.ref [] ~name:"proofusing-nameset"
-let in_nameset =
- let open Libobject in
- declare_object { (default_object "proofusing-nameset") with
- cache_function = (fun (_,x) -> known_names := x :: !known_names);
- classify_function = (fun _ -> Dispose);
- discharge_function = (fun _ -> None)
- }
-
let rec close_fwd e s =
let s' =
List.fold_left (fun s decl ->
@@ -73,7 +65,7 @@ let process_expr env e ty =
let s = Id.Set.union v_ty (process_expr env e ty) in
Id.Set.elements s
-let name_set id expr = Lib.add_anonymous_leaf (in_nameset (id,expr))
+let name_set id expr = known_names := (id,expr) :: !known_names
let minimize_hyps env ids =
let rec aux ids =
@@ -178,7 +170,7 @@ let suggest_variable env id =
let value = ref None
let using_to_string us = Pp.string_of_ppcmds (Ppvernac.pr_using us)
-let using_from_string us = Pcoq.Gram.(entry_parse G_vernac.section_subset_expr (parsable (Stream.of_string us)))
+let using_from_string us = Pcoq.Entry.parse G_vernac.section_subset_expr (Pcoq.Parsable.make (Stream.of_string us))
let _ =
Goptions.declare_stringopt_option
diff --git a/vernac/pvernac.ml b/vernac/pvernac.ml
new file mode 100644
index 00000000..b2fa8ec9
--- /dev/null
+++ b/vernac/pvernac.ml
@@ -0,0 +1,55 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Pcoq
+
+let uvernac = create_universe "vernac"
+
+module Vernac_ =
+ struct
+ let gec_vernac s = Entry.create ("vernac:" ^ s)
+
+ (* The different kinds of vernacular commands *)
+ let gallina = gec_vernac "gallina"
+ let gallina_ext = gec_vernac "gallina_ext"
+ let command = gec_vernac "command"
+ let syntax = gec_vernac "syntax_command"
+ let vernac_control = gec_vernac "Vernac.vernac_control"
+ let rec_definition = gec_vernac "Vernac.rec_definition"
+ let red_expr = new_entry utactic "red_expr"
+ let hint_info = gec_vernac "hint_info"
+ (* Main vernac entry *)
+ let main_entry = Entry.create "vernac"
+ let noedit_mode = gec_vernac "noedit_command"
+
+ let () =
+ let open Extend in
+ let act_vernac v loc = Some (loc, v) in
+ let act_eoi _ loc = None in
+ let rule = [
+ Rule (Next (Stop, Atoken Tok.EOI), act_eoi);
+ Rule (Next (Stop, Aentry vernac_control), act_vernac);
+ ] in
+ Pcoq.grammar_extend main_entry None (None, [None, None, rule])
+
+ let command_entry_ref = ref noedit_mode
+ let command_entry =
+ Gram.Entry.of_parser "command_entry"
+ (fun strm -> Gram.Entry.parse_token !command_entry_ref strm)
+
+ end
+
+let main_entry = Vernac_.main_entry
+
+let set_command_entry e = Vernac_.command_entry_ref := e
+let get_command_entry () = !Vernac_.command_entry_ref
+
+let () =
+ register_grammar Stdarg.wit_red_expr (Vernac_.red_expr);
diff --git a/vernac/pvernac.mli b/vernac/pvernac.mli
new file mode 100644
index 00000000..b2f8f714
--- /dev/null
+++ b/vernac/pvernac.mli
@@ -0,0 +1,36 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Pcoq
+open Genredexpr
+open Vernacexpr
+
+val uvernac : gram_universe
+
+module Vernac_ :
+ sig
+ val gallina : vernac_expr Entry.t
+ val gallina_ext : vernac_expr Entry.t
+ val command : vernac_expr Entry.t
+ val syntax : vernac_expr Entry.t
+ val vernac_control : vernac_control Entry.t
+ val rec_definition : (fixpoint_expr * decl_notation list) Entry.t
+ val noedit_mode : vernac_expr Entry.t
+ val command_entry : vernac_expr Entry.t
+ val red_expr : raw_red_expr Entry.t
+ val hint_info : Hints.hint_info_expr Entry.t
+ end
+
+(** The main entry: reads an optional vernac command *)
+val main_entry : (Loc.t * vernac_control) option Entry.t
+
+(** Handling of the proof mode entry *)
+val get_command_entry : unit -> vernac_expr Entry.t
+val set_command_entry : vernac_expr Entry.t -> unit
diff --git a/vernac/record.ml b/vernac/record.ml
index 78e68e8a..8dd123de 100644
--- a/vernac/record.ml
+++ b/vernac/record.ml
@@ -96,13 +96,13 @@ let binder_of_decl = function
| Vernacexpr.AssumExpr(n,t) -> (n,None,t)
| Vernacexpr.DefExpr(n,c,t) ->
(n,Some c, match t with Some c -> c
- | None -> CAst.make ?loc:n.CAst.loc @@ CHole (None, Misctypes.IntroAnonymous, None))
+ | None -> CAst.make ?loc:n.CAst.loc @@ CHole (None, Namegen.IntroAnonymous, None))
let binders_of_decls = List.map binder_of_decl
-let typecheck_params_and_fields finite def id poly pl t ps nots fs =
+let typecheck_params_and_fields finite def poly pl ps records =
let env0 = Global.env () in
- let sigma, decl = Univdecls.interp_univ_decl_opt env0 pl in
+ let sigma, decl = Constrexpr_ops.interp_univ_decl_opt env0 pl in
let _ =
let error bk {CAst.loc; v=name} =
match bk, name with
@@ -117,12 +117,12 @@ let typecheck_params_and_fields finite def id poly pl t ps nots fs =
Loc.raise ?loc (Stream.Error "pattern with quote not allowed in record parameters")) ps
in
let sigma, (impls_env, ((env1,newps), imps)) = interp_context_evars env0 sigma ps in
- let sigma, typ, sort, template = match t with
+ let fold (sigma, template) (_, t, _, _) = match t with
| Some t ->
let env = EConstr.push_rel_context newps env0 in
let poly =
match t with
- | { CAst.v = CSort (Misctypes.GType []) } -> true | _ -> false in
+ | { CAst.v = CSort (Glob_term.GType []) } -> true | _ -> false in
let sigma, s = interp_type_evars env sigma ~impls:empty_internalization_env t in
let sred = Reductionops.whd_allnolet env sigma s in
(match EConstr.kind sigma sred with
@@ -132,28 +132,36 @@ let typecheck_params_and_fields finite def id poly pl t ps nots fs =
match Evd.is_sort_variable sigma s' with
| Some l ->
let sigma = Evd.make_flexible_variable sigma ~algebraic:true l in
- sigma, s, s', true
+ (sigma, template), (s, s')
| None ->
- sigma, s, s', false
- else sigma, s, s', false)
+ (sigma, false), (s, s')
+ else (sigma, false), (s, s'))
| _ -> user_err ?loc:(constr_loc t) (str"Sort expected."))
| None ->
let uvarkind = Evd.univ_flexible_alg in
let sigma, s = Evd.new_sort_variable uvarkind sigma in
- sigma, EConstr.mkSort s, s, true
+ (sigma, template), (EConstr.mkSort s, s)
in
- let arity = EConstr.it_mkProd_or_LetIn typ newps in
- let env_ar = EConstr.push_rel_context newps (EConstr.push_rel (LocalAssum (Name id,arity)) env0) in
+ let (sigma, template), typs = List.fold_left_map fold (sigma, true) records in
+ let arities = List.map (fun (typ, _) -> EConstr.it_mkProd_or_LetIn typ newps) typs in
+ let fold accu (id, _, _, _) arity = EConstr.push_rel (LocalAssum (Name id,arity)) accu in
+ let env_ar = EConstr.push_rel_context newps (List.fold_left2 fold env0 records arities) in
let assums = List.filter is_local_assum newps in
- let params = List.map (RelDecl.get_name %> Name.get_id) assums in
- let ty = Inductive (params,(finite != Declarations.BiFinite)) in
- let impls_env = compute_internalization_env env0 sigma ~impls:impls_env ty [id] [arity] [imps] in
- let env2,sigma,impls,newfs,data =
- interp_fields_evars env_ar sigma impls_env nots (binders_of_decls fs)
+ let impls_env =
+ let params = List.map (RelDecl.get_name %> Name.get_id) assums in
+ let ty = Inductive (params, (finite != Declarations.BiFinite)) in
+ let ids = List.map (fun (id, _, _, _) -> id) records in
+ let imps = List.map (fun _ -> imps) arities in
+ compute_internalization_env env0 sigma ~impls:impls_env ty ids arities imps
in
+ let fold sigma (_, _, nots, fs) arity =
+ let _, sigma, impls, newfs, _ = interp_fields_evars env_ar sigma impls_env nots (binders_of_decls fs) in
+ (sigma, (impls, newfs))
+ in
+ let (sigma, data) = List.fold_left2_map fold sigma records arities in
let sigma =
- Pretyping.solve_remaining_evars Pretyping.all_and_fail_flags env_ar sigma Evd.empty in
- let sigma, typ =
+ Pretyping.solve_remaining_evars Pretyping.all_and_fail_flags env_ar sigma (Evd.from_env env_ar) in
+ let fold sigma (typ, sort) (_, newfs) =
let _, univ = compute_constructor_level sigma env_ar newfs in
if not def && (Sorts.is_prop sort ||
(Sorts.is_set sort && is_impredicative_set env0)) then
@@ -164,20 +172,24 @@ let typecheck_params_and_fields finite def id poly pl t ps nots fs =
Option.cata (Evd.is_flexible_level sigma) false (Evd.is_sort_variable sigma sort) then
(* We can assume that the level in aritysort is not constrained
and clear it, if it is flexible *)
- Evd.set_eq_sort env_ar sigma (Prop Pos) sort,
- EConstr.mkSort (Sorts.sort_of_univ univ)
+ Evd.set_eq_sort env_ar sigma Set sort, EConstr.mkSort (Sorts.sort_of_univ univ)
else sigma, typ
in
- let sigma, _ = Evarutil.nf_evars_and_universes sigma in
- let newfs = List.map (EConstr.to_rel_decl sigma) newfs in
+ let (sigma, typs) = List.fold_left2_map fold sigma typs data in
+ let sigma = Evd.minimize_universes sigma in
let newps = List.map (EConstr.to_rel_decl sigma) newps in
- let typ = EConstr.to_constr sigma typ in
- let ce t = Pretyping.check_evars env0 Evd.empty sigma (EConstr.of_constr t) in
let univs = Evd.check_univ_decl ~poly sigma decl in
let ubinders = Evd.universe_binders sigma in
- List.iter (iter_constr ce) (List.rev newps);
+ let ce t = Pretyping.check_evars env0 (Evd.from_env env0) sigma (EConstr.of_constr t) in
+ let () = List.iter (iter_constr ce) (List.rev newps) in
+ let map (impls, newfs) typ =
+ let newfs = List.map (EConstr.to_rel_decl sigma) newfs in
+ let typ = EConstr.to_constr sigma typ in
List.iter (iter_constr ce) (List.rev newfs);
- ubinders, univs, typ, template, imps, newps, impls, newfs
+ (typ, impls, newfs)
+ in
+ let ans = List.map2 map data typs in
+ ubinders, univs, template, newps, imps, ans
let degenerate_decl decl =
let id = match RelDecl.get_name decl with
@@ -261,9 +273,10 @@ let subst_projection fid l c =
raise (NotDefinable (MissingProj (fid,List.rev !bad_projs)));
c''
-let instantiate_possibly_recursive_type indu paramdecls fields =
+let instantiate_possibly_recursive_type ind u ntypes paramdecls fields =
let subst = List.map_i (fun i _ -> mkRel i) 1 paramdecls in
- Termops.substl_rel_context (subst@[mkIndU indu]) fields
+ let subst' = List.init ntypes (fun i -> mkIndU ((ind, ntypes - i - 1), u)) in
+ Termops.substl_rel_context (subst @ subst') fields
let warn_non_primitive_record =
CWarnings.create ~name:"non-primitive-record" ~category:"record"
@@ -281,19 +294,18 @@ let declare_projections indsp ctx ?(kind=StructureComponent) binder_name coers u
| Monomorphic_const_entry ctx -> Univ.Instance.empty
in
let paramdecls = Inductive.inductive_paramdecls (mib, u) in
- let indu = indsp, u in
let r = mkIndU (indsp,u) in
let rp = applist (r, Context.Rel.to_extended_list mkRel 0 paramdecls) in
let paramargs = Context.Rel.to_extended_list mkRel 1 paramdecls in (*def in [[params;x:rp]]*)
let x = Name binder_name in
- let fields = instantiate_possibly_recursive_type indu paramdecls fields in
+ let fields = instantiate_possibly_recursive_type (fst indsp) u mib.mind_ntypes paramdecls fields in
let lifted_fields = Termops.lift_rel_context 1 fields in
let primitive =
if !primitive_flag then
let is_primitive =
match mib.mind_record with
- | Some (Some _) -> true
- | Some None | None -> false
+ | PrimRecord _ -> true
+ | FakeRecord | NotRecord -> false
in
if not is_primitive then
warn_non_primitive_record (env,indsp);
@@ -312,12 +324,16 @@ let declare_projections indsp ctx ?(kind=StructureComponent) binder_name coers u
| Name fid -> try
let kn, term =
if is_local_assum decl && primitive then
- (** Already defined in the kernel silently *)
- let gr = Nametab.locate (Libnames.qualid_of_ident fid) in
- let kn = destConstRef gr in
+ let p = Projection.Repr.make indsp
+ ~proj_npars:mib.mind_nparams
+ ~proj_arg:i
+ (Label.of_id fid)
+ in
+ (** Already defined by declare_mind silently *)
+ let kn = Projection.Repr.constant p in
Declare.definition_message fid;
- Universes.register_universe_binders gr ubinders;
- kn, mkProj (Projection.make kn false,mkRel 1)
+ UnivNames.register_universe_binders (ConstRef kn) ubinders;
+ kn, mkProj (Projection.make p false,mkRel 1)
else
let ccl = subst_projection fid subst ti in
let body = match decl with
@@ -352,7 +368,7 @@ let declare_projections indsp ctx ?(kind=StructureComponent) binder_name coers u
applist (mkConstU (kn,u),proj_args)
in
Declare.definition_message fid;
- Universes.register_universe_binders (ConstRef kn) ubinders;
+ UnivNames.register_universe_binders (ConstRef kn) ubinders;
kn, constr_fip
with Type_errors.TypeError (ctx,te) ->
raise (NotDefinable (BadTypedProj (fid,ctx,te)))
@@ -374,12 +390,9 @@ let declare_projections indsp ctx ?(kind=StructureComponent) binder_name coers u
open Typeclasses
-let declare_structure finite ubinders univs id idbuild paramimpls params arity template
- fieldimpls fields ?(kind=StructureComponent) ?name is_coe coers =
- let nparams = List.length params and nfields = List.length fields in
- let args = Context.Rel.to_extended_list mkRel nfields params in
- let ind = applist (mkRel (1+nparams+nfields), args) in
- let type_constructor = it_mkProd_or_LetIn ind fields in
+
+let declare_structure finite ubinders univs paramimpls params template ?(kind=StructureComponent) ?name record_data =
+ let nparams = List.length params in
let template, ctx =
match univs with
| Monomorphic_ind_entry ctx ->
@@ -389,37 +402,51 @@ let declare_structure finite ubinders univs id idbuild paramimpls params arity t
| Cumulative_ind_entry cumi ->
false, Polymorphic_const_entry (Univ.CumulativityInfo.univ_context cumi)
in
- let binder_name =
+ let binder_name =
match name with
- | None -> Id.of_string (Unicode.lowercase_first_char (Id.to_string id))
+ | None ->
+ let map (id, _, _, _, _, _, _) =
+ Id.of_string (Unicode.lowercase_first_char (Id.to_string id))
+ in
+ Array.map_of_list map record_data
| Some n -> n
in
- let mie_ind =
+ let ntypes = List.length record_data in
+ let mk_block i (id, idbuild, arity, _, fields, _, _) =
+ let nfields = List.length fields in
+ let args = Context.Rel.to_extended_list mkRel nfields params in
+ let ind = applist (mkRel (ntypes - i + nparams + nfields), args) in
+ let type_constructor = it_mkProd_or_LetIn ind fields in
{ mind_entry_typename = id;
mind_entry_arity = arity;
mind_entry_template = template;
mind_entry_consnames = [idbuild];
mind_entry_lc = [type_constructor] }
in
+ let blocks = List.mapi mk_block record_data in
let mie =
{ mind_entry_params = List.map degenerate_decl params;
mind_entry_record = Some (if !primitive_flag then Some binder_name else None);
mind_entry_finite = finite;
- mind_entry_inds = [mie_ind];
+ mind_entry_inds = blocks;
mind_entry_private = None;
mind_entry_universes = univs;
}
in
let mie = InferCumulativity.infer_inductive (Global.env ()) mie in
- let kn = ComInductive.declare_mutual_inductive_with_eliminations mie ubinders [(paramimpls,[])] in
- let rsp = (kn,0) in (* This is ind path of idstruc *)
- let cstr = (rsp,1) in
- let kinds,sp_projs = declare_projections rsp ctx ~kind binder_name coers ubinders fieldimpls fields in
- let build = ConstructRef cstr in
- let poly = match ctx with | Polymorphic_const_entry _ -> true | Monomorphic_const_entry _ -> false in
- let () = if is_coe then Class.try_add_new_coercion build ~local:false poly in
- Recordops.declare_structure(rsp,cstr,List.rev kinds,List.rev sp_projs);
- rsp
+ let impls = List.map (fun _ -> paramimpls, []) record_data in
+ let kn = ComInductive.declare_mutual_inductive_with_eliminations mie ubinders impls in
+ let map i (_, _, _, fieldimpls, fields, is_coe, coers) =
+ let rsp = (kn, i) in (* This is ind path of idstruc *)
+ let cstr = (rsp, 1) in
+ let kinds,sp_projs = declare_projections rsp ctx ~kind binder_name.(i) coers ubinders fieldimpls fields in
+ let build = ConstructRef cstr in
+ let poly = match ctx with | Polymorphic_const_entry _ -> true | Monomorphic_const_entry _ -> false in
+ let () = if is_coe then Class.try_add_new_coercion build ~local:false poly in
+ let () = Recordops.declare_structure(rsp,cstr,List.rev kinds,List.rev sp_projs) in
+ rsp
+ in
+ List.mapi map record_data
let implicits_of_context ctx =
List.map_i (fun i name ->
@@ -431,28 +458,29 @@ let implicits_of_context ctx =
1 (List.rev (Anonymous :: (List.map RelDecl.get_name ctx)))
let declare_class finite def cum ubinders univs id idbuild paramimpls params arity
- template fieldimpls fields ?(kind=StructureComponent) is_coe coers priorities =
+ template fieldimpls fields ?(kind=StructureComponent) coers priorities =
let fieldimpls =
(* Make the class implicit in the projections, and the params if applicable. *)
let len = List.length params in
let impls = implicits_of_context params in
List.map (fun x -> impls @ Impargs.lift_implicits (succ len) x) fieldimpls
in
- let binder_name = Namegen.next_ident_away (snd id) (Termops.vars_of_env (Global.env())) in
- let impl, projs =
+ let binder_name = Namegen.next_ident_away id (Termops.vars_of_env (Global.env())) in
+ let data =
match fields with
| [LocalAssum (Name proj_name, field) | LocalDef (Name proj_name, _, field)] when def ->
let class_body = it_mkLambda_or_LetIn field params in
let class_type = it_mkProd_or_LetIn arity params in
let class_entry =
Declare.definition_entry ~types:class_type ~univs class_body in
- let cst = Declare.declare_constant (snd id)
+ let cst = Declare.declare_constant id
(DefinitionEntry class_entry, IsDefinition Definition)
in
- let cstu = (cst, match univs with
- | Polymorphic_const_entry univs -> Univ.UContext.instance univs
- | Monomorphic_const_entry _ -> Univ.Instance.empty)
+ let inst, univs = match univs with
+ | Polymorphic_const_entry uctx -> Univ.UContext.instance uctx, univs
+ | Monomorphic_const_entry _ -> Univ.Instance.empty, Monomorphic_const_entry Univ.ContextSet.empty
in
+ let cstu = (cst, inst) in
let inst_type = appvectc (mkConstU cstu)
(Termops.rel_vect 0 (List.length params)) in
let proj_type =
@@ -465,15 +493,15 @@ let declare_class finite def cum ubinders univs id idbuild paramimpls params ari
in
let cref = ConstRef cst in
Impargs.declare_manual_implicits false cref [paramimpls];
- Universes.register_universe_binders cref ubinders;
+ UnivNames.register_universe_binders cref ubinders;
Impargs.declare_manual_implicits false (ConstRef proj_cst) [List.hd fieldimpls];
- Universes.register_universe_binders (ConstRef proj_cst) ubinders;
+ UnivNames.register_universe_binders (ConstRef proj_cst) ubinders;
Classes.set_typeclass_transparency (EvalConstRef cst) false false;
let sub = match List.hd coers with
| Some b -> Some ((if b then Backward else Forward), List.hd priorities)
| None -> None
in
- cref, [Name proj_name, sub, Some proj_cst]
+ [cref, [Name proj_name, sub, Some proj_cst]]
| _ ->
let univs =
match univs with
@@ -485,18 +513,21 @@ let declare_class finite def cum ubinders univs id idbuild paramimpls params ari
| Monomorphic_const_entry univs ->
Monomorphic_ind_entry univs
in
- let ind = declare_structure Declarations.BiFinite ubinders univs (snd id) idbuild paramimpls
- params arity template fieldimpls fields
- ~kind:Method ~name:binder_name false (List.map (fun _ -> false) fields)
- in
+ let record_data = [id, idbuild, arity, fieldimpls, fields, false, List.map (fun _ -> false) fields] in
+ let inds = declare_structure Declarations.BiFinite ubinders univs paramimpls
+ params template ~kind:Method ~name:[|binder_name|] record_data
+ in
let coers = List.map2 (fun coe pri ->
Option.map (fun b ->
if b then Backward, pri else Forward, pri) coe)
coers priorities
in
- let l = List.map3 (fun decl b y -> RelDecl.get_name decl, b, y)
- (List.rev fields) coers (Recordops.lookup_projections ind)
- in IndRef ind, l
+ let map ind =
+ let l = List.map3 (fun decl b y -> RelDecl.get_name decl, b, y)
+ (List.rev fields) coers (Recordops.lookup_projections ind)
+ in IndRef ind, l
+ in
+ List.map map inds
in
let ctx_context =
List.map (fun decl ->
@@ -517,16 +548,19 @@ let declare_class finite def cum ubinders univs id idbuild paramimpls params ari
| Monomorphic_const_entry _ ->
Univ.AUContext.empty, ctx_context, fields
in
- let k =
- { cl_univs = univs;
- cl_impl = impl;
- cl_strict = !typeclasses_strict;
- cl_unique = !typeclasses_unique;
- cl_context = ctx_context;
- cl_props = fields;
- cl_projs = projs }
- in
+ let map (impl, projs) =
+ let k =
+ { cl_univs = univs;
+ cl_impl = impl;
+ cl_strict = !typeclasses_strict;
+ cl_unique = !typeclasses_unique;
+ cl_context = ctx_context;
+ cl_props = fields;
+ cl_projs = projs }
+ in
add_class k; impl
+ in
+ List.map map data
let add_constant_class cst =
@@ -562,48 +596,87 @@ let add_inductive_class ind =
cl_unique = !typeclasses_unique }
in add_class k
+let warn_already_existing_class =
+ CWarnings.create ~name:"already-existing-class" ~category:"automation" Pp.(fun g ->
+ Printer.pr_global g ++ str " is already declared as a typeclass.")
+
let declare_existing_class g =
- match g with
- | ConstRef x -> add_constant_class x
- | IndRef x -> add_inductive_class x
- | _ -> user_err ~hdr:"declare_existing_class"
- (Pp.str"Unsupported class type, only constants and inductives are allowed")
+ if Typeclasses.is_class g then warn_already_existing_class g
+ else
+ match g with
+ | ConstRef x -> add_constant_class x
+ | IndRef x -> add_inductive_class x
+ | _ -> user_err ~hdr:"declare_existing_class"
+ (Pp.str"Unsupported class type, only constants and inductives are allowed")
open Vernacexpr
-(* [fs] corresponds to fields and [ps] to parameters; [coers] is a
- list telling if the corresponding fields must me declared as coercions
- or subinstances. *)
-let definition_structure (kind,cum,poly,finite,(is_coe,({CAst.loc;v=idstruc},pl)),ps,cfs,idbuild,s) =
- let cfs,notations = List.split cfs in
- let cfs,priorities = List.split cfs in
- let coers,fs = List.split cfs in
- let extract_name acc = function
+let check_unique_names records =
+ let extract_name acc (((_, bnd), _), _) = match bnd with
Vernacexpr.AssumExpr({CAst.v=Name id},_) -> id::acc
| Vernacexpr.DefExpr ({CAst.v=Name id},_,_) -> id::acc
| _ -> acc in
- let allnames = idstruc::(List.fold_left extract_name [] fs) in
- let () = match List.duplicates Id.equal allnames with
+ let allnames =
+ List.fold_left (fun acc (_, id, _, _, cfs, _, _) ->
+ id.CAst.v :: (List.fold_left extract_name acc cfs)) [] records
+ in
+ match List.duplicates Id.equal allnames with
| [] -> ()
| id :: _ -> user_err (str "Two objects have the same name" ++ spc () ++ quote (Id.print id))
- in
+
+let check_priorities kind records =
let isnot_class = match kind with Class false -> false | _ -> true in
- if isnot_class && List.exists (fun opt -> not (Option.is_empty opt)) priorities then
- user_err Pp.(str "Priorities only allowed for type class substructures");
- (* Now, younger decl in params and fields is on top *)
- let pl, univs, arity, template, implpars, params, implfs, fields =
+ let has_priority (_, _, _, _, cfs, _, _) =
+ List.exists (fun ((_, pri), _) -> not (Option.is_empty pri)) cfs
+ in
+ if isnot_class && List.exists has_priority records then
+ user_err Pp.(str "Priorities only allowed for type class substructures")
+
+let extract_record_data records =
+ let map (is_coe, id, _, _, cfs, idbuild, s) =
+ let fs = List.map (fun (((_, f), _), _) -> f) cfs in
+ id.CAst.v, s, List.map snd cfs, fs
+ in
+ let data = List.map map records in
+ let pss = List.map (fun (_, _, _, ps, _, _, _) -> ps) records in
+ let ps = match pss with
+ | [] -> CErrors.anomaly (str "Empty record block")
+ | ps :: rem ->
+ let eq_local_binders bl1 bl2 = List.equal local_binder_eq bl1 bl2 in
+ let () =
+ if not (List.for_all (eq_local_binders ps) rem) then
+ user_err (str "Parameters should be syntactically the \
+ same for each inductive type.")
+ in
+ ps
+ in
+ (** FIXME: Same issue as #7754 *)
+ let _, _, pl, _, _, _, _ = List.hd records in
+ pl, ps, data
+
+(* [fs] corresponds to fields and [ps] to parameters; [coers] is a
+ list telling if the corresponding fields must me declared as coercions
+ or subinstances. *)
+let definition_structure kind cum poly finite records =
+ let () = check_unique_names records in
+ let () = check_priorities kind records in
+ let pl, ps, data = extract_record_data records in
+ let pl, univs, template, params, implpars, data =
States.with_state_protection (fun () ->
- typecheck_params_and_fields finite (kind = Class true) idstruc poly pl s ps notations fs) () in
+ typecheck_params_and_fields finite (kind = Class true) poly pl ps data) () in
match kind with
| Class def ->
- let priorities = List.map (fun id -> {hint_priority = id; hint_pattern = None}) priorities in
- declare_class finite def cum pl univs (loc,idstruc) idbuild
- implpars params arity template implfs fields is_coe coers priorities
+ let (_, id, _, _, cfs, idbuild, _), (arity, implfs, fields) = match records, data with
+ | [r], [d] -> r, d
+ | _, _ -> CErrors.user_err (str "Mutual definitional classes are not handled")
+ in
+ let priorities = List.map (fun ((_, id), _) -> {hint_priority = id; hint_pattern = None}) cfs in
+ let coers = List.map (fun (((coe, _), _), _) -> coe) cfs in
+ declare_class finite def cum pl univs id.CAst.v idbuild
+ implpars params arity template implfs fields coers priorities
| _ ->
- let implfs = List.map
- (fun impls -> implpars @ Impargs.lift_implicits
- (succ (List.length params)) impls) implfs
- in
+ let map impls = implpars @ Impargs.lift_implicits (succ (List.length params)) impls in
+ let data = List.map (fun (arity, implfs, fields) -> (arity, List.map map implfs, fields)) data in
let univs =
match univs with
| Polymorphic_const_entry univs ->
@@ -614,7 +687,11 @@ let definition_structure (kind,cum,poly,finite,(is_coe,({CAst.loc;v=idstruc},pl)
| Monomorphic_const_entry univs ->
Monomorphic_ind_entry univs
in
- let ind = declare_structure finite pl univs idstruc
- idbuild implpars params arity template implfs
- fields is_coe (List.map (fun coe -> not (Option.is_empty coe)) coers) in
- IndRef ind
+ let map (arity, implfs, fields) (is_coe, id, _, _, cfs, idbuild, _) =
+ let coers = List.map (fun (((coe, _), _), _) -> coe) cfs in
+ let coe = List.map (fun coe -> not (Option.is_empty coe)) coers in
+ id.CAst.v, idbuild, arity, implfs, fields, is_coe, coe
+ in
+ let data = List.map2 map data records in
+ let inds = declare_structure finite pl univs implpars params template data in
+ List.map (fun ind -> IndRef ind) inds
diff --git a/vernac/record.mli b/vernac/record.mli
index 992da2aa..567f2b31 100644
--- a/vernac/record.mli
+++ b/vernac/record.mli
@@ -11,7 +11,6 @@
open Names
open Vernacexpr
open Constrexpr
-open Globnames
val primitive_flag : bool ref
@@ -21,15 +20,20 @@ val declare_projections :
?kind:Decl_kinds.definition_object_kind ->
Id.t ->
bool list ->
- Universes.universe_binders ->
+ UnivNames.universe_binders ->
Impargs.manual_implicits list ->
- Context.Rel.t ->
+ Constr.rel_context ->
(Name.t * bool) list * Constant.t option list
val definition_structure :
- inductive_kind * Decl_kinds.cumulative_inductive_flag * Decl_kinds.polymorphic *
- Declarations.recursivity_kind * ident_decl with_coercion * local_binder_expr list *
+ inductive_kind -> Decl_kinds.cumulative_inductive_flag -> Decl_kinds.polymorphic ->
+ Declarations.recursivity_kind ->
+ (coercion_flag *
+ Names.lident *
+ universe_decl_expr option *
+ local_binder_expr list *
(local_decl_expr with_instance with_priority with_notation) list *
- Id.t * constr_expr option -> global_reference
+ Id.t * constr_expr option) list ->
+ GlobRef.t list
-val declare_existing_class : global_reference -> unit
+val declare_existing_class : GlobRef.t -> unit
diff --git a/vernac/search.ml b/vernac/search.ml
index a2a4fb40..e8ccec11 100644
--- a/vernac/search.ml
+++ b/vernac/search.ml
@@ -22,8 +22,8 @@ open Nametab
module NamedDecl = Context.Named.Declaration
-type filter_function = global_reference -> env -> constr -> bool
-type display_function = global_reference -> env -> constr -> unit
+type filter_function = GlobRef.t -> env -> constr -> bool
+type display_function = GlobRef.t -> env -> constr -> unit
(* This option restricts the output of [SearchPattern ...],
[SearchAbout ...], etc. to the names of the symbols matching the
@@ -61,7 +61,7 @@ let iter_named_context_name_type f =
List.iter (fun decl -> f (NamedDecl.get_id decl) (NamedDecl.get_type decl))
(* General search over hypothesis of a goal *)
-let iter_hypothesis glnum (fn : global_reference -> env -> constr -> unit) =
+let iter_hypothesis glnum (fn : GlobRef.t -> env -> constr -> unit) =
let env = Global.env () in
let iter_hyp idh typ = fn (VarRef idh) env typ in
let evmap,e = Pfedit.get_goal_context glnum in
@@ -69,7 +69,7 @@ let iter_hypothesis glnum (fn : global_reference -> env -> constr -> unit) =
iter_named_context_name_type iter_hyp pfctxt
(* General search over declarations *)
-let iter_declarations (fn : global_reference -> env -> constr -> unit) =
+let iter_declarations (fn : GlobRef.t -> env -> constr -> unit) =
let env = Global.env () in
let iter_obj (sp, kn) lobj = match object_tag lobj with
| "VARIABLE" ->
@@ -117,8 +117,7 @@ module ConstrPriority = struct
(* The priority is memoised here. Because of the very localised use
of this module, it is not worth it making a convenient interface. *)
- type t =
- Globnames.global_reference * Environ.env * Constr.t * priority
+ type t = GlobRef.t * Environ.env * Constr.t * priority
and priority = int
module ConstrSet = CSet.Make(Constr)
@@ -216,7 +215,7 @@ let name_of_reference ref = Id.to_string (basename_of_global ref)
let search_about_filter query gr env typ = match query with
| GlobSearchSubPattern pat ->
- Constr_matching.is_matching_appsubterm ~closed:false env Evd.empty pat (EConstr.of_constr typ)
+ Constr_matching.is_matching_appsubterm ~closed:false env (Evd.from_env env) pat (EConstr.of_constr typ)
| GlobSearchString s ->
String.string_contains ~where:(name_of_reference gr) ~what:s
@@ -227,7 +226,7 @@ let search_pattern gopt pat mods pr_search =
let blacklist_filter = blacklist_filter_aux () in
let filter ref env typ =
module_filter mods ref env typ &&
- pattern_filter pat ref env Evd.empty (* FIXME *) (EConstr.of_constr typ) &&
+ pattern_filter pat ref env (Evd.from_env env) (* FIXME *) (EConstr.of_constr typ) &&
blacklist_filter ref env typ
in
let iter ref env typ =
@@ -251,8 +250,8 @@ let search_rewrite gopt pat mods pr_search =
let blacklist_filter = blacklist_filter_aux () in
let filter ref env typ =
module_filter mods ref env typ &&
- (pattern_filter pat1 ref env Evd.empty (* FIXME *) (EConstr.of_constr typ) ||
- pattern_filter pat2 ref env Evd.empty (EConstr.of_constr typ)) &&
+ (pattern_filter pat1 ref env (Evd.from_env env) (* FIXME *) (EConstr.of_constr typ) ||
+ pattern_filter pat2 ref env (Evd.from_env env) (EConstr.of_constr typ)) &&
blacklist_filter ref env typ
in
let iter ref env typ =
@@ -266,7 +265,7 @@ let search_by_head gopt pat mods pr_search =
let blacklist_filter = blacklist_filter_aux () in
let filter ref env typ =
module_filter mods ref env typ &&
- head_filter pat ref env Evd.empty (* FIXME *) (EConstr.of_constr typ) &&
+ head_filter pat ref env (Evd.from_env env) (* FIXME *) (EConstr.of_constr typ) &&
blacklist_filter ref env typ
in
let iter ref env typ =
@@ -330,12 +329,12 @@ let interface_search =
toggle (Str.string_match regexp id 0) flag
in
let match_type (pat, flag) =
- toggle (Constr_matching.is_matching env Evd.empty pat (EConstr.of_constr constr)) flag
+ toggle (Constr_matching.is_matching env (Evd.from_env env) pat (EConstr.of_constr constr)) flag
in
let match_subtype (pat, flag) =
toggle
(Constr_matching.is_matching_appsubterm ~closed:false
- env Evd.empty pat (EConstr.of_constr constr)) flag
+ env (Evd.from_env env) pat (EConstr.of_constr constr)) flag
in
let match_module (mdl, flag) =
toggle (Libnames.is_dirpath_prefix_of mdl path) flag
diff --git a/vernac/search.mli b/vernac/search.mli
index a1fb7ed3..0dc82c1c 100644
--- a/vernac/search.mli
+++ b/vernac/search.mli
@@ -12,7 +12,6 @@ open Names
open Constr
open Environ
open Pattern
-open Globnames
(** {6 Search facilities. } *)
@@ -20,8 +19,8 @@ type glob_search_about_item =
| GlobSearchSubPattern of constr_pattern
| GlobSearchString of string
-type filter_function = global_reference -> env -> constr -> bool
-type display_function = global_reference -> env -> constr -> unit
+type filter_function = GlobRef.t -> env -> constr -> bool
+type display_function = GlobRef.t -> env -> constr -> unit
(** {6 Generic filter functions} *)
diff --git a/vernac/topfmt.ml b/vernac/topfmt.ml
index 1d720330..f842ca5e 100644
--- a/vernac/topfmt.ml
+++ b/vernac/topfmt.ml
@@ -181,6 +181,10 @@ let default_tag_map () = let open Terminal in [
; "tactic.keyword" , make ~bold:true ()
; "tactic.primitive" , make ~fg_color:`LIGHT_GREEN ()
; "tactic.string" , make ~fg_color:`LIGHT_RED ()
+ ; "diff.added" , make ~bg_color:(`RGB(0,141,0)) ~underline:true ()
+ ; "diff.removed" , make ~bg_color:(`RGB(170,0,0)) ~underline:true ()
+ ; "diff.added.bg" , make ~bg_color:(`RGB(0,91,0)) ()
+ ; "diff.removed.bg" , make ~bg_color:(`RGB(91,0,0)) ()
]
let tag_map = ref CString.Map.empty
@@ -198,72 +202,103 @@ let parse_color_config file =
let dump_tags () = CString.Map.bindings !tag_map
+let empty = Terminal.make ()
+let default_style = Terminal.reset_style
+
+let get_style tag =
+ try CString.Map.find tag !tag_map
+ with Not_found -> empty;;
+
+let get_open_seq tags =
+ let style = List.fold_left (fun a b -> Terminal.merge a (get_style b)) default_style tags in
+ Terminal.eval (Terminal.diff default_style style);;
+
+let get_close_seq tags =
+ let style = List.fold_left (fun a b -> Terminal.merge a (get_style b)) default_style tags in
+ Terminal.eval (Terminal.diff style default_style);;
+
+let diff_tag_stack = ref [] (* global, just like std_ft *)
+
(** Not thread-safe. We should put a lock somewhere if we print from
different threads. Do we? *)
let make_style_stack () =
(** Default tag is to reset everything *)
- let empty = Terminal.make () in
- let default_tag = Terminal.({
- fg_color = Some `DEFAULT;
- bg_color = Some `DEFAULT;
- bold = Some false;
- italic = Some false;
- underline = Some false;
- negative = Some false;
- prefix = None;
- suffix = None;
- })
- in
let style_stack = ref [] in
let peek () = match !style_stack with
- | [] -> default_tag (** Anomalous case, but for robustness *)
+ | [] -> default_style (** Anomalous case, but for robustness *)
| st :: _ -> st
in
- let push tag =
- let style =
- try CString.Map.find tag !tag_map
- with | Not_found -> empty
- in
- (** Use the merging of the latest tag and the one being currently pushed.
- This may be useful if for instance the latest tag changes the background and
- the current one the foreground, so that the two effects are additioned. *)
+ let open_tag tag =
+ let (tpfx, ttag) = split_tag tag in
+ if tpfx = end_pfx then "" else
+ let style = get_style ttag in
+ (** Merge the current settings and the style being pushed. This allows
+ restoring the previous settings correctly in a pop when both set the same
+ attribute. Example: current settings have red FG, the pushed style has
+ green FG. When popping the style, we should set red FG, not default FG. *)
let style = Terminal.merge (peek ()) style in
+ let diff = Terminal.diff (peek ()) style in
style_stack := style :: !style_stack;
- Terminal.eval style
+ if tpfx = start_pfx then diff_tag_stack := ttag :: !diff_tag_stack;
+ Terminal.eval diff
in
- let pop _ = match !style_stack with
- | [] -> (** Something went wrong, we fallback *)
- Terminal.eval default_tag
- | _ :: rem -> style_stack := rem;
- Terminal.eval (peek ())
+ let close_tag tag =
+ let (tpfx, _) = split_tag tag in
+ if tpfx = start_pfx then "" else begin
+ if tpfx = end_pfx then diff_tag_stack := (try List.tl !diff_tag_stack with tl -> []);
+ match !style_stack with
+ | [] -> (** Something went wrong, we fallback *)
+ Terminal.eval default_style
+ | cur :: rem -> style_stack := rem;
+ if cur = (peek ()) then "" else
+ if rem = [] then Terminal.reset else
+ Terminal.eval (Terminal.diff cur (peek ()))
+ end
in
let clear () = style_stack := [] in
- push, pop, clear
+ open_tag, close_tag, clear
let make_printing_functions () =
- let empty = Terminal.make () in
let print_prefix ft tag =
- let style =
- try CString.Map.find tag !tag_map
- with | Not_found -> empty
- in
- match style.Terminal.prefix with Some s -> Format.pp_print_string ft s | None -> ()
- in
+ let (tpfx, ttag) = split_tag tag in
+ if tpfx <> end_pfx then
+ let style = get_style ttag in
+ match style.Terminal.prefix with Some s -> Format.pp_print_string ft s | None -> () in
+
let print_suffix ft tag =
- let style =
- try CString.Map.find tag !tag_map
- with | Not_found -> empty
- in
- match style.Terminal.suffix with Some s -> Format.pp_print_string ft s | None -> ()
- in
+ let (tpfx, ttag) = split_tag tag in
+ if tpfx <> start_pfx then
+ let style = get_style ttag in
+ match style.Terminal.suffix with Some s -> Format.pp_print_string ft s | None -> () in
+
print_prefix, print_suffix
+let init_output_fns () =
+ let reopen_highlight = ref "" in
+ let open Format in
+ let fns = Format.pp_get_formatter_out_functions !std_ft () in
+ let newline () =
+ if !diff_tag_stack <> [] then begin
+ let close = get_close_seq !diff_tag_stack in
+ fns.out_string close 0 (String.length close);
+ reopen_highlight := get_open_seq (List.rev !diff_tag_stack);
+ end;
+ fns.out_string "\n" 0 1 in
+ let string s off n =
+ if !reopen_highlight <> "" && String.trim (String.sub s off n) <> "" then begin
+ fns.out_string !reopen_highlight 0 (String.length !reopen_highlight);
+ reopen_highlight := ""
+ end;
+ fns.out_string s off n in
+ let new_fns = { fns with out_string = string; out_newline = newline } in
+ Format.pp_set_formatter_out_functions !std_ft new_fns;;
+
let init_terminal_output ~color =
- let push_tag, pop_tag, clear_tag = make_style_stack () in
+ let open_tag, close_tag, clear_tag = make_style_stack () in
let print_prefix, print_suffix = make_printing_functions () in
let tag_handler ft = {
- Format.mark_open_tag = push_tag;
- Format.mark_close_tag = pop_tag;
+ Format.mark_open_tag = open_tag;
+ Format.mark_close_tag = close_tag;
Format.print_open_tag = print_prefix ft;
Format.print_close_tag = print_suffix ft;
} in
@@ -271,6 +306,7 @@ let init_terminal_output ~color =
(* Use 0-length markers *)
begin
std_logger_cleanup := clear_tag;
+ init_output_fns ();
Format.pp_set_mark_tags !std_ft true;
Format.pp_set_mark_tags !err_ft true
end
@@ -291,6 +327,14 @@ let init_terminal_output ~color =
let emacs_logger = gen_logger Emacs.quote_info Emacs.quote_warning
(* This is specific to the toplevel *)
+
+type execution_phase =
+ | ParsingCommandLine
+ | Initialization
+ | LoadingPrelude
+ | LoadingRcFile
+ | InteractiveLoop
+
let pr_loc loc =
let fname = loc.Loc.fname in
match fname with
@@ -303,13 +347,28 @@ let pr_loc loc =
int (loc.bp-loc.bol_pos) ++ str"-" ++ int (loc.ep-loc.bol_pos) ++
str":")
-let print_err_exn ?extra any =
+let pr_phase ?loc phase =
+ match phase, loc with
+ | LoadingRcFile, loc ->
+ (* For when all errors go through feedback:
+ str "While loading rcfile:" ++
+ Option.cata (fun loc -> fnl () ++ pr_loc loc) (mt ()) loc *)
+ Option.map pr_loc loc
+ | LoadingPrelude, loc ->
+ Some (str "While loading initial state:" ++ Option.cata (fun loc -> fnl () ++ pr_loc loc) (mt ()) loc)
+ | _, Some loc -> Some (pr_loc loc)
+ | ParsingCommandLine, _
+ | Initialization, _ -> None
+ | InteractiveLoop, _ ->
+ (* Note: interactive messages such as "foo is defined" are not located *)
+ None
+
+let print_err_exn phase any =
let (e, info) = CErrors.push any in
let loc = Loc.get_loc info in
- let msg_loc = Option.cata pr_loc (mt ()) loc in
- let pre_hdr = pr_opt_no_spc (fun x -> x) extra ++ msg_loc in
+ let pre_hdr = pr_phase ?loc phase in
let msg = CErrors.iprint (e, info) ++ fnl () in
- std_logger ~pre_hdr Feedback.Error msg
+ std_logger ?pre_hdr Feedback.Error msg
let with_output_to_file fname func input =
let channel = open_out (String.concat "." [fname; "out"]) in
diff --git a/vernac/topfmt.mli b/vernac/topfmt.mli
index 579b456a..73dcb006 100644
--- a/vernac/topfmt.mli
+++ b/vernac/topfmt.mli
@@ -53,8 +53,17 @@ val init_terminal_output : color:bool -> unit
(** Error printing *)
(* To be deprecated when we can fully move to feedback-based error
printing. *)
+
+type execution_phase =
+ | ParsingCommandLine
+ | Initialization
+ | LoadingPrelude
+ | LoadingRcFile
+ | InteractiveLoop
+
val pr_loc : Loc.t -> Pp.t
-val print_err_exn : ?extra:Pp.t -> exn -> unit
+val pr_phase : ?loc:Loc.t -> execution_phase -> Pp.t option
+val print_err_exn : execution_phase -> exn -> unit
(** [with_output_to_file file f x] executes [f x] with logging
redirected to a file [file] *)
diff --git a/vernac/vernac.mllib b/vernac/vernac.mllib
index f001b572..356951b6 100644
--- a/vernac/vernac.mllib
+++ b/vernac/vernac.mllib
@@ -1,10 +1,18 @@
+Vernacexpr
+Pvernac
+G_vernac
+G_proofs
Vernacprop
-Proof_using
-Lemmas
Himsg
ExplainErr
-Class
Locality
+Egramml
+Vernacinterp
+Ppvernac
+Proof_using
+Lemmas
+Class
+Egramcoq
Metasyntax
Auto_ind_decl
Search
@@ -20,7 +28,8 @@ Classes
Record
Assumptions
Vernacstate
-Vernacinterp
Mltop
Topfmt
Vernacentries
+
+Misctypes
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index fceb0bf3..f7ba3053 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -29,7 +29,6 @@ open Decl_kinds
open Constrexpr
open Redexpr
open Lemmas
-open Misctypes
open Locality
open Vernacinterp
@@ -184,29 +183,27 @@ let print_modules () =
pr_vertical_list DirPath.print only_loaded
-let print_module r =
- let qid = qualid_of_reference r in
+let print_module qid =
try
- let globdir = Nametab.locate_dir qid.v in
+ let globdir = Nametab.locate_dir qid in
match globdir with
DirModule { obj_dir; obj_mp; _ } ->
Printmod.print_module (Printmod.printable_body obj_dir) obj_mp
| _ -> raise Not_found
with
- Not_found -> user_err (str"Unknown Module " ++ pr_qualid qid.v)
+ Not_found -> user_err (str"Unknown Module " ++ pr_qualid qid)
-let print_modtype r =
- let qid = qualid_of_reference r in
+let print_modtype qid =
try
- let kn = Nametab.locate_modtype qid.v in
+ let kn = Nametab.locate_modtype qid in
Printmod.print_modtype kn
with Not_found ->
(* Is there a module of this name ? If yes we display its type *)
try
- let mp = Nametab.locate_module qid.v in
+ let mp = Nametab.locate_module qid in
Printmod.print_module false mp
with Not_found ->
- user_err (str"Unknown Module Type or Module " ++ pr_qualid qid.v)
+ user_err (str"Unknown Module Type or Module " ++ pr_qualid qid)
let print_namespace ns =
let ns = List.rev (Names.DirPath.repr ns) in
@@ -266,15 +263,13 @@ let print_namespace ns =
let matches mp = match match_modulepath ns mp with
| Some [] -> true
| _ -> false in
- let constants = (Environ.pre_env (Global.env ())).Pre_env.env_globals.Pre_env.env_constants in
let constants_in_namespace =
- Cmap_env.fold (fun c (body,_) acc ->
- let kn = Constant.user c in
- if matches (KerName.modpath kn) then
- acc++fnl()++hov 2 (print_constant kn body)
- else
- acc
- ) constants (str"")
+ Environ.fold_constants (fun c body acc ->
+ let kn = Constant.user c in
+ if matches (KerName.modpath kn)
+ then acc++fnl()++hov 2 (print_constant kn body)
+ else acc)
+ (Global.env ()) (str"")
in
(print_list Id.print ns)++str":"++fnl()++constants_in_namespace
@@ -368,33 +363,32 @@ let msg_found_library = function
| Library.LibInPath, fulldir, file ->
hov 0 (DirPath.print fulldir ++ strbrk " is bound to file " ++ str file)
-let err_unmapped_library ?loc ?from qid =
+let err_unmapped_library ?from qid =
let dir = fst (repr_qualid qid) in
let prefix = match from with
| None -> str "."
| Some from ->
str " and prefix " ++ DirPath.print from ++ str "."
in
- user_err ?loc
+ user_err ?loc:qid.CAst.loc
~hdr:"locate_library"
(strbrk "Cannot find a physical path bound to logical path matching suffix " ++
DirPath.print dir ++ prefix)
-let err_notfound_library ?loc ?from qid =
+let err_notfound_library ?from qid =
let prefix = match from with
| None -> str "."
| Some from ->
str " with prefix " ++ DirPath.print from ++ str "."
in
- user_err ?loc ~hdr:"locate_library"
+ user_err ?loc:qid.CAst.loc ~hdr:"locate_library"
(strbrk "Unable to locate library " ++ pr_qualid qid ++ prefix)
-let print_located_library r =
- let {loc;v=qid} = qualid_of_reference r in
+let print_located_library qid =
try msg_found_library (Library.locate_qualified_library ~warn:false qid)
with
- | Library.LibUnmappedDir -> err_unmapped_library ?loc qid
- | Library.LibNotFound -> err_notfound_library ?loc qid
+ | Library.LibUnmappedDir -> err_unmapped_library qid
+ | Library.LibNotFound -> err_notfound_library qid
let smart_global r =
let gr = Smartlocate.smart_global r in
@@ -437,6 +431,10 @@ let vernac_notation ~atts =
let local = enforce_module_locality atts.locality in
Metasyntax.add_notation local (Global.env())
+let vernac_custom_entry ~atts s =
+ let local = enforce_module_locality atts.locality in
+ Metasyntax.declare_custom_entry local s
+
(***********)
(* Gallina *)
@@ -449,7 +447,7 @@ let start_proof_and_print k l hook =
let evi = Evarutil.nf_evar_info sigma evi in
let env = Evd.evar_filtered_env evi in
try
- let concl = EConstr.of_constr evi.Evd.evar_concl in
+ let concl = evi.Evd.evar_concl in
if not (Evarutil.is_ground_env sigma env &&
Evarutil.is_ground_term sigma concl)
then raise Exit;
@@ -518,7 +516,7 @@ let vernac_exact_proof c =
(* spiwack: for simplicity I do not enforce that "Proof proof_term" is
called only at the begining of a proof. *)
let status = Pfedit.by (Tactics.exact_proof c) in
- save_proof (Vernacexpr.(Proved(Opaque,None)));
+ save_proof (Vernacexpr.(Proved(Proof_global.Opaque,None)));
if not status then Feedback.feedback Feedback.AddedAxiom
let vernac_assumption ~atts discharge kind l nl =
@@ -534,38 +532,52 @@ let vernac_assumption ~atts discharge kind l nl =
if not status then Feedback.feedback Feedback.AddedAxiom
let should_treat_as_cumulative cum poly =
- if poly then
- match cum with
- | GlobalCumulativity | LocalCumulativity -> true
- | GlobalNonCumulativity | LocalNonCumulativity -> false
- else
- match cum with
- | GlobalCumulativity | GlobalNonCumulativity -> false
- | LocalCumulativity ->
- user_err Pp.(str "The Cumulative prefix can only be used in a polymorphic context.")
- | LocalNonCumulativity ->
- user_err Pp.(str "The NonCumulative prefix can only be used in a polymorphic context.")
-
-let vernac_record cum k poly finite struc binders sort nameopt cfs =
+ match cum with
+ | Some VernacCumulative ->
+ if poly then true
+ else user_err Pp.(str "The Cumulative prefix can only be used in a polymorphic context.")
+ | Some VernacNonCumulative ->
+ if poly then false
+ else user_err Pp.(str "The NonCumulative prefix can only be used in a polymorphic context.")
+ | None -> poly && Flags.is_polymorphic_inductive_cumulativity ()
+
+let uniform_inductive_parameters = ref false
+
+let should_treat_as_uniform () =
+ if !uniform_inductive_parameters
+ then ComInductive.UniformParameters
+ else ComInductive.NonUniformParameters
+
+let vernac_record cum k poly finite records =
let is_cumulative = should_treat_as_cumulative cum poly in
- let const = match nameopt with
- | None -> add_prefix "Build_" (fst (snd struc)).v
- | Some ({v=id} as lid) ->
- Dumpglob.dump_definition lid false "constr"; id in
- if Dumpglob.dump () then (
- Dumpglob.dump_definition (fst (snd struc)) false "rec";
- List.iter (fun (((_, x), _), _) ->
- match x with
- | Vernacexpr.AssumExpr ({loc;v=Name id}, _) -> Dumpglob.dump_definition (make ?loc id) false "proj"
- | _ -> ()) cfs);
- ignore(Record.definition_structure (k,is_cumulative,poly,finite,struc,binders,cfs,const,sort))
+ let map ((coe, (id, pl)), binders, sort, nameopt, cfs) =
+ let const = match nameopt with
+ | None -> add_prefix "Build_" id.v
+ | Some lid ->
+ let () = Dumpglob.dump_definition lid false "constr" in
+ lid.v
+ in
+ let () =
+ if Dumpglob.dump () then
+ let () = Dumpglob.dump_definition id false "rec" in
+ let iter (((_, x), _), _) = match x with
+ | Vernacexpr.AssumExpr ({loc;v=Name id}, _) ->
+ Dumpglob.dump_definition (make ?loc id) false "proj"
+ | _ -> ()
+ in
+ List.iter iter cfs
+ in
+ coe, id, pl, binders, cfs, const, sort
+ in
+ let records = List.map map records in
+ ignore(Record.definition_structure k is_cumulative poly finite records)
(** When [poly] is true the type is declared polymorphic. When [lo] is true,
then the type is declared private (as per the [Private] keyword). [finite]
indicates whether the type is inductive, co-inductive or
neither. *)
let vernac_inductive ~atts cum lo finite indl =
- let is_cumulative = should_treat_as_cumulative cum atts.polymorphic in
+ let open Pp in
if Dumpglob.dump () then
List.iter (fun (((coe,(lid,_)), _, _, _, cstrs), _) ->
match cstrs with
@@ -575,34 +587,86 @@ let vernac_inductive ~atts cum lo finite indl =
Dumpglob.dump_definition lid false "constr") cstrs
| _ -> () (* dumping is done by vernac_record (called below) *) )
indl;
+ let is_record = function
+ | ((_ , _ , _ , _, RecordDecl _), _) -> true
+ | _ -> false
+ in
+ let is_constructor = function
+ | ((_ , _ , _ , _, Constructors _), _) -> true
+ | _ -> false
+ in
+ let is_defclass = match indl with
+ | [ ( id , bl , c , Class _, Constructors [l]), [] ] -> Some (id, bl, c, l)
+ | _ -> None
+ in
+ if Option.has_some is_defclass then
+ (** Definitional class case *)
+ let (id, bl, c, l) = Option.get is_defclass in
+ let (coe, (lid, ce)) = l in
+ let coe' = if coe then Some true else None in
+ let f = (((coe', AssumExpr ((make ?loc:lid.loc @@ Name lid.v), ce)), None), []) in
+ vernac_record cum (Class true) atts.polymorphic finite [id, bl, c, None, [f]]
+ else if List.for_all is_record indl then
+ (** Mutual record case *)
+ let check_kind ((_, _, _, kind, _), _) = match kind with
+ | Variant ->
+ user_err (str "The Variant keyword does not support syntax { ... }.")
+ | Record | Structure | Class _ | Inductive_kw | CoInductive -> ()
+ in
+ let () = List.iter check_kind indl in
+ let check_where ((_, _, _, _, _), wh) = match wh with
+ | [] -> ()
+ | _ :: _ ->
+ user_err (str "where clause not supported for records")
+ in
+ let () = List.iter check_where indl in
+ let unpack ((id, bl, c, _, decl), _) = match decl with
+ | RecordDecl (oc, fs) ->
+ (id, bl, c, oc, fs)
+ | Constructors _ -> assert false (** ruled out above *)
+ in
+ let ((_, _, _, kind, _), _) = List.hd indl in
+ let kind = match kind with Class _ -> Class false | _ -> kind in
+ let recordl = List.map unpack indl in
+ vernac_record cum kind atts.polymorphic finite recordl
+ else if List.for_all is_constructor indl then
+ (** Mutual inductive case *)
+ let check_kind ((_, _, _, kind, _), _) = match kind with
+ | (Record | Structure) ->
+ user_err (str "The Record keyword is for types defined using the syntax { ... }.")
+ | Class _ ->
+ user_err (str "Inductive classes not supported")
+ | Variant | Inductive_kw | CoInductive -> ()
+ in
+ let () = List.iter check_kind indl in
+ let check_name ((na, _, _, _, _), _) = match na with
+ | (true, _) ->
+ user_err (str "Variant types do not handle the \"> Name\" \
+ syntax, which is reserved for records. Use the \":>\" \
+ syntax on constructors instead.")
+ | _ -> ()
+ in
+ let () = List.iter check_name indl in
+ let unpack (((_, id) , bl, c, _, decl), ntn) = match decl with
+ | Constructors l -> (id, bl, c, l), ntn
+ | RecordDecl _ -> assert false (* ruled out above *)
+ in
+ let indl = List.map unpack indl in
+ let is_cumulative = should_treat_as_cumulative cum atts.polymorphic in
+ let uniform = should_treat_as_uniform () in
+ ComInductive.do_mutual_inductive indl is_cumulative atts.polymorphic lo ~uniform finite
+ else
+ user_err (str "Mixed record-inductive definitions are not allowed")
+(*
+
match indl with
- | [ ( _ , _ , _ ,(Record|Structure), Constructors _ ),_ ] ->
- user_err Pp.(str "The Record keyword is for types defined using the syntax { ... }.")
- | [ (_ , _ , _ ,Variant, RecordDecl _),_ ] ->
- user_err Pp.(str "The Variant keyword does not support syntax { ... }.")
- | [ ( id , bl , c , b, RecordDecl (oc,fs) ), [] ] ->
- vernac_record cum (match b with Class _ -> Class false | _ -> b)
- atts.polymorphic finite id bl c oc fs
| [ ( id , bl , c , Class _, Constructors [l]), [] ] ->
let f =
let (coe, ({loc;v=id}, ce)) = l in
let coe' = if coe then Some true else None in
(((coe', AssumExpr ((make ?loc @@ Name id), ce)), None), [])
- in vernac_record cum (Class true) atts.polymorphic finite id bl c None [f]
- | [ ( _ , _, _, Class _, Constructors _), [] ] ->
- user_err Pp.(str "Inductive classes not supported")
- | [ ( id , bl , c , Class _, _), _ :: _ ] ->
- user_err Pp.(str "where clause not supported for classes")
- | [ ( _ , _ , _ , _, RecordDecl _ ) , _ ] ->
- user_err Pp.(str "where clause not supported for (co)inductive records")
- | _ -> let unpack = function
- | ( (false, id) , bl , c , _ , Constructors l ) , ntn -> ( id , bl , c , l ) , ntn
- | ( (true,_),_,_,_,Constructors _),_ ->
- user_err Pp.(str "Variant types do not handle the \"> Name\" syntax, which is reserved for records. Use the \":>\" syntax on constructors instead.")
- | _ -> user_err Pp.(str "Cannot handle mutually (co)inductive records.")
- in
- let indl = List.map unpack indl in
- ComInductive.do_mutual_inductive indl is_cumulative atts.polymorphic lo finite
+ in vernac_record cum (Class true) atts.polymorphic finite [id, bl, c, None, [f]]
+ *)
let vernac_fixpoint ~atts discharge l =
let local = enforce_locality_exp atts.locality discharge in
@@ -640,7 +704,7 @@ let vernac_scheme l =
let vernac_combined_scheme lid l =
if Dumpglob.dump () then
(Dumpglob.dump_definition lid false "def";
- List.iter (fun {loc;v=id} -> dump_global (make ?loc @@ Misctypes.AN (make ?loc @@ Ident id))) l);
+ List.iter (fun {loc;v=id} -> dump_global (make ?loc @@ AN (qualid_of_ident ?loc id))) l);
Indschemes.do_combined_scheme lid l
let vernac_universe ~atts l =
@@ -661,7 +725,7 @@ let vernac_constraint ~atts l =
(* Modules *)
let vernac_import export refl =
- Library.import_module export (List.map qualid_of_reference refl)
+ Library.import_module export refl
let vernac_declare_module export {loc;v=id} binders_ast mty_ast =
(* We check the state of the system (in section, in module type)
@@ -675,11 +739,11 @@ let vernac_declare_module export {loc;v=id} binders_ast mty_ast =
else (idl,ty)) binders_ast in
let mp =
Declaremods.declare_module Modintern.interp_module_ast
- id binders_ast (Enforce mty_ast) []
+ id binders_ast (Declaremods.Enforce mty_ast) []
in
Dumpglob.dump_moddef ?loc mp "mod";
Flags.if_verbose Feedback.msg_info (str "Module " ++ Id.print id ++ str " is declared");
- Option.iter (fun export -> vernac_import export [make @@ Ident id]) export
+ Option.iter (fun export -> vernac_import export [qualid_of_ident id]) export
let vernac_define_module export {loc;v=id} (binders_ast : module_binder list) mty_ast_o mexpr_ast_l =
(* We check the state of the system (in section, in module type)
@@ -704,7 +768,7 @@ let vernac_define_module export {loc;v=id} (binders_ast : module_binder list) mt
List.iter
(fun (export,id) ->
Option.iter
- (fun export -> vernac_import export [make @@ Ident id]) export
+ (fun export -> vernac_import export [qualid_of_ident id]) export
) argsexport
| _::_ ->
let binders_ast = List.map
@@ -719,14 +783,14 @@ let vernac_define_module export {loc;v=id} (binders_ast : module_binder list) mt
Dumpglob.dump_moddef ?loc mp "mod";
Flags.if_verbose Feedback.msg_info
(str "Module " ++ Id.print id ++ str " is defined");
- Option.iter (fun export -> vernac_import export [make @@ Ident id])
+ Option.iter (fun export -> vernac_import export [qualid_of_ident id])
export
let vernac_end_module export {loc;v=id} =
let mp = Declaremods.end_module () in
Dumpglob.dump_modref ?loc mp "mod";
Flags.if_verbose Feedback.msg_info (str "Module " ++ Id.print id ++ str " is defined");
- Option.iter (fun export -> vernac_import export [make ?loc @@ Ident id]) export
+ Option.iter (fun export -> vernac_import export [qualid_of_ident ?loc id]) export
let vernac_declare_module_type {loc;v=id} binders_ast mty_sign mty_ast_l =
if Lib.sections_are_opened () then
@@ -751,7 +815,7 @@ let vernac_declare_module_type {loc;v=id} binders_ast mty_sign mty_ast_l =
List.iter
(fun (export,id) ->
Option.iter
- (fun export -> vernac_import export [make ?loc @@ Ident id]) export
+ (fun export -> vernac_import export [qualid_of_ident ?loc id]) export
) argsexport
| _ :: _ ->
@@ -813,22 +877,20 @@ let warn_require_in_section =
let vernac_require from import qidl =
if Lib.sections_are_opened () then warn_require_in_section ();
- let qidl = List.map qualid_of_reference qidl in
let root = match from with
| None -> None
| Some from ->
- let qid = Libnames.qualid_of_reference from in
- let (hd, tl) = Libnames.repr_qualid qid.v in
+ let (hd, tl) = Libnames.repr_qualid from in
Some (Libnames.add_dirpath_suffix hd tl)
in
- let locate {loc;v=qid} =
+ let locate qid =
try
let warn = not !Flags.quiet in
let (_, dir, f) = Library.locate_qualified_library ?root ~warn qid in
(dir, f)
with
- | Library.LibUnmappedDir -> err_unmapped_library ?loc ?from:root qid
- | Library.LibNotFound -> err_notfound_library ?loc ?from:root qid
+ | Library.LibUnmappedDir -> err_unmapped_library ?from:root qid
+ | Library.LibNotFound -> err_notfound_library ?from:root qid
in
let modrefl = List.map locate qidl in
if Dumpglob.dump () then
@@ -858,7 +920,7 @@ let vernac_identity_coercion ~atts id qids qidt =
let vernac_instance ~atts abst sup inst props pri =
let global = not (make_section_locality atts.locality) in
- Dumpglob.dump_constraint inst false "inst";
+ Dumpglob.dump_constraint (fst (pi1 inst)) false "inst";
let program_mode = Flags.is_program_mode () in
ignore(Classes.new_instance ~program_mode ~abstract:abst ~global atts.polymorphic sup inst props pri)
@@ -912,7 +974,7 @@ let vernac_set_used_variables e =
if List.is_empty to_clear then (p, ())
else
let tac = Tactics.clear to_clear in
- fst (Pfedit.solve SelectAll None tac p), ()
+ fst (Pfedit.solve Goal_select.SelectAll None tac p), ()
end
(*****************************)
@@ -980,7 +1042,7 @@ let vernac_remove_hints ~atts dbs ids =
let vernac_hints ~atts lb h =
let local = enforce_module_locality atts.locality in
- Hints.add_hints local lb (Hints.interp_hints atts.polymorphic h)
+ Hints.add_hints ~local lb (Hints.interp_hints atts.polymorphic h)
let vernac_syntactic_definition ~atts lid x y =
Dumpglob.dump_definition lid false "syndef";
@@ -1134,15 +1196,16 @@ let vernac_arguments ~atts reference args more_implicits nargs_for_red flags =
let names = rename prev_names names in
let renaming_specified = Option.has_some !example_renaming in
- if !rename_flag_required && not rename_flag then
- user_err ~hdr:"vernac_declare_arguments"
- (strbrk "To rename arguments the \"rename\" flag must be specified."
- ++ spc () ++
- match !example_renaming with
- | None -> mt ()
- | Some (o,n) ->
- str "Argument " ++ Name.print o ++
- str " renamed to " ++ Name.print n ++ str ".");
+ if !rename_flag_required && not rename_flag then begin
+ let msg =
+ match !example_renaming with
+ | None ->
+ strbrk "To rename arguments the \"rename\" flag must be specified."
+ | Some (o,n) ->
+ strbrk "Flag \"rename\" expected to rename " ++ Name.print o ++
+ strbrk " into " ++ Name.print n ++ str "."
+ in user_err ~hdr:"vernac_declare_arguments" msg
+ end;
let duplicate_names =
List.duplicates Name.equal (List.filter ((!=) Anonymous) names)
@@ -1271,7 +1334,7 @@ let vernac_reserve bl =
let vernac_generalizable ~atts =
let local = make_non_locality atts.locality in
- Implicit_quantifiers.declare_generalizable local
+ Implicit_quantifiers.declare_generalizable ~local
let _ =
declare_bool_option
@@ -1420,6 +1483,14 @@ let _ =
optwrite = Flags.make_polymorphic_inductive_cumulativity }
let _ =
+ declare_bool_option
+ { optdepr = false;
+ optname = "Uniform inductive parameters";
+ optkey = ["Uniform"; "Inductive"; "Parameters"];
+ optread = (fun () -> !uniform_inductive_parameters);
+ optwrite = (fun b -> uniform_inductive_parameters := b) }
+
+let _ =
declare_int_option
{ optdepr = false;
optname = "the level of inlining during functor application";
@@ -1434,8 +1505,8 @@ let _ =
{ optdepr = false;
optname = "kernel term sharing";
optkey = ["Kernel"; "Term"; "Sharing"];
- optread = (fun () -> !CClosure.share);
- optwrite = (fun b -> CClosure.share := b) }
+ optread = (fun () -> (Global.typing_flags ()).Declarations.share_reduction);
+ optwrite = (fun b -> Global.set_reduction_sharing b) }
let _ =
declare_bool_option
@@ -1468,22 +1539,22 @@ let _ =
optkey = ["Printing";"Universes"];
optread = (fun () -> !Constrextern.print_universes);
optwrite = (fun b -> Constrextern.print_universes:=b) }
-
+
let _ =
declare_bool_option
{ optdepr = false;
optname = "dumping bytecode after compilation";
optkey = ["Dump";"Bytecode"];
- optread = Flags.get_dump_bytecode;
- optwrite = Flags.set_dump_bytecode }
+ optread = (fun () -> !Cbytegen.dump_bytecode);
+ optwrite = (:=) Cbytegen.dump_bytecode }
let _ =
declare_bool_option
{ optdepr = false;
optname = "dumping VM lambda code after compilation";
optkey = ["Dump";"Lambda"];
- optread = Flags.get_dump_lambda;
- optwrite = Flags.set_dump_lambda }
+ optread = (fun () -> !Clambda.dump_lambda);
+ optwrite = (:=) Clambda.dump_lambda }
let _ =
declare_bool_option
@@ -1614,7 +1685,7 @@ let get_current_context_of_args = function
let query_command_selector ?loc = function
| None -> None
- | Some (SelectNth n) -> Some n
+ | Some (Goal_select.SelectNth n) -> Some n
| _ -> user_err ?loc ~hdr:"query_command_selector"
(str "Query commands only support the single numbered goal selector.")
@@ -1622,17 +1693,16 @@ let vernac_check_may_eval ~atts redexp glopt rc =
let glopt = query_command_selector ?loc:atts.loc glopt in
let (sigma, env) = get_current_context_of_args glopt in
let sigma, c = interp_open_constr env sigma rc in
- let c = EConstr.Unsafe.to_constr c in
let sigma = Evarconv.solve_unif_constraints_with_heuristics env sigma in
Evarconv.check_problems_are_solved env sigma;
- let sigma,nf = Evarutil.nf_evars_and_universes sigma in
+ let sigma = Evd.minimize_universes sigma in
let uctx = Evd.universe_context_set sigma in
let env = Environ.push_context_set uctx (Evarutil.nf_env_evar sigma env) in
- let c = nf c in
let j =
- if Evarutil.has_undefined_evars sigma (EConstr.of_constr c) then
- Evarutil.j_nf_evar sigma (Retyping.get_judgment_of env sigma (EConstr.of_constr c))
+ if Evarutil.has_undefined_evars sigma c then
+ Evarutil.j_nf_evar sigma (Retyping.get_judgment_of env sigma c)
else
+ let c = EConstr.to_constr sigma c in
(* OK to call kernel which does not support evars *)
Termops.on_judgment EConstr.of_constr (Arguments_renaming.rename_typing env c)
in
@@ -1656,7 +1726,9 @@ let vernac_check_may_eval ~atts redexp glopt rc =
let vernac_declare_reduction ~atts s r =
let local = make_locality atts.locality in
- declare_red_expr local s (snd (Hook.get f_interp_redexp (Global.env()) Evd.empty r))
+ let env = Global.env () in
+ let sigma = Evd.from_env env in
+ declare_red_expr local s (snd (Hook.get f_interp_redexp env sigma r))
(* The same but avoiding the current goal context if any *)
let vernac_global_check c =
@@ -1690,10 +1762,10 @@ let print_about_hyp_globs ?loc ref_or_by_not udecl glopt =
let glnumopt = query_command_selector ?loc glopt in
let gl,id =
match glnumopt, ref_or_by_not.v with
- | None,AN {v=Ident id} -> (* goal number not given, catch any failure *)
- (try get_nth_goal 1,id with _ -> raise NoHyp)
- | Some n,AN {v=Ident id} -> (* goal number given, catch if wong *)
- (try get_nth_goal n,id
+ | None,AN qid when qualid_is_ident qid -> (* goal number not given, catch any failure *)
+ (try get_nth_goal 1, qualid_basename qid with _ -> raise NoHyp)
+ | Some n,AN qid when qualid_is_ident qid -> (* goal number given, catch if wong *)
+ (try get_nth_goal n, qualid_basename qid
with
Failure _ -> user_err ?loc ~hdr:"print_about_hyp_globs"
(str "No such goal: " ++ int n ++ str "."))
@@ -1746,7 +1818,7 @@ let vernac_print ~atts env sigma =
else str"There may remain asynchronous universe constraints"
in
begin match dst with
- | None -> UGraph.pr_universes Universes.pr_with_global_universes univ ++ pr_remaining
+ | None -> UGraph.pr_universes UnivNames.pr_with_global_universes univ ++ pr_remaining
| Some s -> dump_universes_gen univ s
end
| PrintHint r -> Hints.pr_hint_ref env sigma (smart_global r)
@@ -1774,11 +1846,10 @@ let vernac_print ~atts env sigma =
Printer.pr_assumptionset env sigma nassums
| PrintStrategy r -> print_strategy r
-let global_module r =
- let {loc;v=qid} = qualid_of_reference r in
+let global_module qid =
try Nametab.full_name_module qid
with Not_found ->
- user_err ?loc ~hdr:"global_module"
+ user_err ?loc:qid.CAst.loc ~hdr:"global_module"
(str "Module/section " ++ pr_qualid qid ++ str " not found.")
let interp_search_restriction = function
@@ -1916,9 +1987,10 @@ let vernac_subproof gln =
Proof_global.simple_with_current_proof (fun _ p ->
match gln with
| None -> Proof.focus subproof_cond () 1 p
- | Some (SelectNth n) -> Proof.focus subproof_cond () n p
+ | Some (Goal_select.SelectNth n) -> Proof.focus subproof_cond () n p
+ | Some (Goal_select.SelectId id) -> Proof.focus_id subproof_cond () id p
| _ -> user_err ~hdr:"bracket_selector"
- (str "Brackets only support the single numbered goal selector."))
+ (str "Brackets do not support multi-goal selectors."))
let vernac_end_subproof () =
Proof_global.simple_with_current_proof (fun _ p ->
@@ -1974,7 +2046,7 @@ let vernac_load interp fname =
interp x in
let parse_sentence = Flags.with_option Flags.we_are_parsing
(fun po ->
- match Pcoq.Gram.entry_parse Pcoq.main_entry po with
+ match Pcoq.Entry.parse Pvernac.main_entry po with
| Some x -> x
| None -> raise End_of_input) in
let fname =
@@ -1983,7 +2055,7 @@ let vernac_load interp fname =
let input =
let longfname = Loadpath.locate_file fname in
let in_chan = open_utf8_file_in longfname in
- Pcoq.Gram.parsable ~file:(Loc.InFile longfname) (Stream.of_channel in_chan) in
+ Pcoq.Parsable.make ~file:(Loc.InFile longfname) (Stream.of_channel in_chan) in
begin
try while true do interp (snd (parse_sentence input)) done
with End_of_input -> ()
@@ -2009,10 +2081,6 @@ let interp ?proof ~atts ~st c =
| VernacRestart -> CErrors.user_err (str "Restart cannot be used through the Load command")
| VernacUndo _ -> CErrors.user_err (str "Undo cannot be used through the Load command")
| VernacUndoTo _ -> CErrors.user_err (str "UndoTo cannot be used through the Load command")
- | VernacBacktrack _ -> CErrors.user_err (str "Backtrack cannot be used through the Load command")
-
- (* Toplevel control *)
- | VernacToplevelControl e -> raise e
(* Resetting *)
| VernacResetName _ -> anomaly (str "VernacResetName not handled by Stm.")
@@ -2029,12 +2097,13 @@ let interp ?proof ~atts ~st c =
| VernacDelimiters (sc,lr) -> vernac_delimiters sc lr
| VernacBindScope (sc,rl) -> vernac_bind_scope sc rl
| VernacOpenCloseScope (b, s) -> vernac_open_close_scope ~atts (b,s)
- | VernacArgumentsScope (qid,scl) -> vernac_arguments_scope ~atts qid scl
| VernacInfix (mv,qid,sc) -> vernac_infix ~atts mv qid sc
| VernacNotation (c,infpl,sc) ->
vernac_notation ~atts c infpl sc
| VernacNotationAddFormat(n,k,v) ->
Metasyntax.add_notation_extra_printing_rule n k v
+ | VernacDeclareCustomEntry s ->
+ vernac_custom_entry ~atts s
(* Gallina *)
| VernacDefinition ((discharge,kind),lid,d) ->
@@ -2044,7 +2113,7 @@ let interp ?proof ~atts ~st c =
| VernacExactProof c -> vernac_exact_proof c
| VernacAssumption ((discharge,kind),nl,l) ->
vernac_assumption ~atts discharge kind l nl
- | VernacInductive (cum, priv,finite,l) -> vernac_inductive ~atts cum priv finite l
+ | VernacInductive (cum, priv, finite, l) -> vernac_inductive ~atts cum priv finite l
| VernacFixpoint (discharge, l) -> vernac_fixpoint ~atts discharge l
| VernacCoFixpoint (discharge, l) -> vernac_cofixpoint ~atts discharge l
| VernacScheme l -> vernac_scheme l
@@ -2103,8 +2172,6 @@ let interp ?proof ~atts ~st c =
vernac_hints ~atts dbnames hints
| VernacSyntacticDefinition (id,c,b) ->
vernac_syntactic_definition ~atts id c b
- | VernacDeclareImplicits (qid,l) ->
- vernac_declare_implicits ~atts qid l
| VernacArguments (qid, args, more_implicits, nargs, flags) ->
vernac_arguments ~atts qid args more_implicits nargs flags
| VernacReserve bl -> vernac_reserve bl
@@ -2165,6 +2232,7 @@ let check_vernac_supports_locality c l =
| Some _, (
VernacOpenCloseScope _
| VernacSyntaxExtension _ | VernacInfix _ | VernacNotation _
+ | VernacDeclareCustomEntry _
| VernacDefinition _ | VernacFixpoint _ | VernacCoFixpoint _
| VernacAssumption _ | VernacStartTheoremProof _
| VernacCoercion _ | VernacIdentityCoercion _
@@ -2172,7 +2240,7 @@ let check_vernac_supports_locality c l =
| VernacDeclareMLModule _
| VernacCreateHintDb _ | VernacRemoveHints _ | VernacHints _
| VernacSyntacticDefinition _
- | VernacArgumentsScope _ | VernacDeclareImplicits _ | VernacArguments _
+ | VernacArguments _
| VernacGeneralizable _
| VernacSetOpacity _ | VernacSetStrategy _
| VernacSetOption _ | VernacUnsetOption _
@@ -2255,37 +2323,67 @@ let with_fail st b f =
| HasNotFailed ->
user_err ~hdr:"Fail" (str "The command has not failed!")
| HasFailed msg ->
- if not !Flags.quiet || !Flags.test_mode || !Flags.ide_slave then Feedback.msg_info
+ if not !Flags.quiet || !Flags.test_mode then Feedback.msg_info
(str "The command has indeed failed with message:" ++ fnl () ++ msg)
| _ -> assert false
end
+let attributes_of_flags f atts =
+ let assert_empty k v =
+ if v <> VernacFlagEmpty
+ then user_err Pp.(str "Attribute " ++ str k ++ str " does not accept arguments")
+ in
+ List.fold_left
+ (fun (polymorphism, atts) (k, v) ->
+ match k with
+ | "program" when not atts.program ->
+ assert_empty k v;
+ (polymorphism, { atts with program = true })
+ | "program" ->
+ user_err Pp.(str "Program mode specified twice")
+ | "polymorphic" when polymorphism = None ->
+ assert_empty k v;
+ (Some true, atts)
+ | "monomorphic" when polymorphism = None ->
+ assert_empty k v;
+ (Some false, atts)
+ | ("polymorphic" | "monomorphic") ->
+ user_err Pp.(str "Polymorphism specified twice")
+ | "local" when Option.is_empty atts.locality ->
+ assert_empty k v;
+ (polymorphism, { atts with locality = Some true })
+ | "global" when Option.is_empty atts.locality ->
+ assert_empty k v;
+ (polymorphism, { atts with locality = Some false })
+ | ("local" | "global") ->
+ user_err Pp.(str "Locality specified twice")
+ | "deprecated" when Option.is_empty atts.deprecated ->
+ begin match v with
+ | VernacFlagList [ "since", VernacFlagLeaf since ; "note", VernacFlagLeaf note ]
+ | VernacFlagList [ "note", VernacFlagLeaf note ; "since", VernacFlagLeaf since ] ->
+ let since = Some since and note = Some note in
+ (polymorphism, { atts with deprecated = Some (mk_deprecation ~since ~note ()) })
+ | VernacFlagList [ "since", VernacFlagLeaf since ] ->
+ let since = Some since in
+ (polymorphism, { atts with deprecated = Some (mk_deprecation ~since ()) })
+ | VernacFlagList [ "note", VernacFlagLeaf note ] ->
+ let note = Some note in
+ (polymorphism, { atts with deprecated = Some (mk_deprecation ~note ()) })
+ | _ -> CErrors.user_err (Pp.str "Ill formed “deprecated” attribute")
+ end
+ | "deprecated" ->
+ user_err Pp.(str "Deprecation specified twice")
+ | _ -> user_err Pp.(str "Unknown attribute " ++ str k)
+ )
+ (None, atts)
+ f
+
let interp ?(verbosely=true) ?proof ~st {CAst.loc;v=c} =
let orig_univ_poly = Flags.is_universe_polymorphism () in
let orig_program_mode = Flags.is_program_mode () in
- let flags f atts =
- List.fold_left
- (fun (polymorphism, atts) f ->
- match f with
- | VernacProgram when not atts.program ->
- (polymorphism, { atts with program = true })
- | VernacProgram ->
- user_err Pp.(str "Program mode specified twice")
- | VernacPolymorphic b when polymorphism = None ->
- (Some b, atts)
- | VernacPolymorphic _ ->
- user_err Pp.(str "Polymorphism specified twice")
- | VernacLocal b when Option.is_empty atts.locality ->
- (polymorphism, { atts with locality = Some b })
- | VernacLocal _ ->
- user_err Pp.(str "Locality specified twice")
- )
- (None, atts)
- f
- in
let rec control = function
| VernacExpr (f, v) ->
- let (polymorphism, atts) = flags f { loc; locality = None; polymorphic = false; program = orig_program_mode; } in
+ let (polymorphism, atts) = attributes_of_flags f (mk_atts ~program:orig_program_mode ()) in
aux ~polymorphism ~atts v
| VernacFail v -> with_fail st true (fun () -> control v)
| VernacTimeout (n,v) ->
@@ -2347,3 +2445,121 @@ let interp ?verbosely ?proof ~st cmd =
let exn = CErrors.push exn in
Vernacstate.invalidate_cache ();
iraise exn
+
+(** VERNAC EXTEND registering *)
+
+open Genarg
+open Extend
+
+type classifier = Genarg.raw_generic_argument list -> vernac_classification
+
+type (_, _) ty_sig =
+| TyNil : (atts:atts -> st:Vernacstate.t -> Vernacstate.t, Vernacexpr.vernac_classification) ty_sig
+| TyTerminal : string * ('r, 's) ty_sig -> ('r, 's) ty_sig
+| TyNonTerminal :
+ string option * ('a, 'b, 'c) Extend.ty_user_symbol * ('r, 's) ty_sig -> ('a -> 'r, 'a -> 's) ty_sig
+
+type ty_ml = TyML : bool * ('r, 's) ty_sig * 'r * 's option -> ty_ml
+
+let type_error () = CErrors.anomaly (Pp.str "Ill-typed VERNAC EXTEND")
+
+let rec untype_classifier : type r s. (r, s) ty_sig -> s -> classifier = function
+| TyNil -> fun f args ->
+ begin match args with
+ | [] -> f
+ | _ :: _ -> type_error ()
+ end
+| TyTerminal (_, ty) -> fun f args -> untype_classifier ty f args
+| TyNonTerminal (_, tu, ty) -> fun f args ->
+ begin match args with
+ | [] -> type_error ()
+ | Genarg.GenArg (Rawwit tag, v) :: args ->
+ match Genarg.genarg_type_eq tag (Egramml.proj_symbol tu) with
+ | None -> type_error ()
+ | Some Refl -> untype_classifier ty (f v) args
+ end
+
+(** Stupid GADTs forces us to duplicate the definition just for typing *)
+let rec untype_command : type r s. (r, s) ty_sig -> r -> plugin_args vernac_command = function
+| TyNil -> fun f args ->
+ begin match args with
+ | [] -> f
+ | _ :: _ -> type_error ()
+ end
+| TyTerminal (_, ty) -> fun f args -> untype_command ty f args
+| TyNonTerminal (_, tu, ty) -> fun f args ->
+ begin match args with
+ | [] -> type_error ()
+ | Genarg.GenArg (Rawwit tag, v) :: args ->
+ match Genarg.genarg_type_eq tag (Egramml.proj_symbol tu) with
+ | None -> type_error ()
+ | Some Refl -> untype_command ty (f v) args
+ end
+
+let rec untype_user_symbol : type s a b c. (a, b, c) Extend.ty_user_symbol -> (s, a) Extend.symbol = function
+| TUlist1 l -> Alist1 (untype_user_symbol l)
+| TUlist1sep (l, s) -> Alist1sep (untype_user_symbol l, Atoken (CLexer.terminal s))
+| TUlist0 l -> Alist0 (untype_user_symbol l)
+| TUlist0sep (l, s) -> Alist0sep (untype_user_symbol l, Atoken (CLexer.terminal s))
+| TUopt o -> Aopt (untype_user_symbol o)
+| TUentry a -> Aentry (Pcoq.genarg_grammar (ExtraArg a))
+| TUentryl (a, i) -> Aentryl (Pcoq.genarg_grammar (ExtraArg a), string_of_int i)
+
+let rec untype_grammar : type r s. (r, s) ty_sig -> vernac_expr Egramml.grammar_prod_item list = function
+| TyNil -> []
+| TyTerminal (tok, ty) -> Egramml.GramTerminal tok :: untype_grammar ty
+| TyNonTerminal (id, tu, ty) ->
+ let t = Option.map (fun _ -> rawwit (Egramml.proj_symbol tu)) id in
+ let symb = untype_user_symbol tu in
+ Egramml.GramNonTerminal (Loc.tag (t, symb)) :: untype_grammar ty
+
+let _ = untype_classifier, untype_command, untype_grammar, untype_user_symbol
+
+let classifiers : classifier array String.Map.t ref = ref String.Map.empty
+
+let get_vernac_classifier (name, i) args =
+ (String.Map.find name !classifiers).(i) args
+
+let declare_vernac_classifier name f =
+ classifiers := String.Map.add name f !classifiers
+
+let vernac_extend ~command ?classifier ?entry ext =
+ let get_classifier (TyML (_, ty, _, cl)) = match cl with
+ | Some cl -> untype_classifier ty cl
+ | None ->
+ match classifier with
+ | Some cl -> fun _ -> cl command
+ | None ->
+ let e = match entry with
+ | None -> "COMMAND"
+ | Some e -> Pcoq.Gram.Entry.name e
+ in
+ let msg = Printf.sprintf "\
+ Vernac entry \"%s\" misses a classifier. \
+ A classifier is a function that returns an expression \
+ of type vernac_classification (see Vernacexpr). You can: \n\
+ - 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."
+ command e e e command
+ in
+ CErrors.user_err (Pp.strbrk msg)
+ in
+ let cl = Array.map_of_list get_classifier ext in
+ let iter i (TyML (depr, ty, f, _)) =
+ let f = untype_command ty f in
+ let r = untype_grammar ty in
+ let () = vinterp_add depr (command, i) f in
+ Egramml.extend_vernac_command_grammar (command, i) entry r
+ in
+ let () = declare_vernac_classifier command cl in
+ List.iteri iter ext
diff --git a/vernac/vernacentries.mli b/vernac/vernacentries.mli
index f6199e82..fb2a30ba 100644
--- a/vernac/vernacentries.mli
+++ b/vernac/vernacentries.mli
@@ -8,13 +8,11 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Misctypes
-
-val dump_global : Libnames.reference or_by_notation -> unit
+val dump_global : Libnames.qualid Constrexpr.or_by_notation -> unit
(** Vernacular entries *)
val vernac_require :
- Libnames.reference option -> bool option -> Libnames.reference list -> unit
+ Libnames.qualid option -> bool option -> Libnames.qualid list -> unit
(** The main interpretation function of vernacular expressions *)
val interp :
@@ -40,3 +38,37 @@ val interp_redexp_hook : (Environ.env -> Evd.evar_map -> Genredexpr.raw_red_expr
Evd.evar_map * Redexpr.red_expr) Hook.t
val universe_polymorphism_option_name : string list
+
+(** Elaborate a [atts] record out of a list of flags.
+ Also returns whether polymorphism is explicitly (un)set. *)
+val attributes_of_flags : Vernacexpr.vernac_flags -> Vernacinterp.atts -> bool option * Vernacinterp.atts
+
+(** {5 VERNAC EXTEND} *)
+
+type classifier = Genarg.raw_generic_argument list -> Vernacexpr.vernac_classification
+
+type (_, _) ty_sig =
+| TyNil : (atts:Vernacinterp.atts -> st:Vernacstate.t -> Vernacstate.t, Vernacexpr.vernac_classification) ty_sig
+| TyTerminal : string * ('r, 's) ty_sig -> ('r, 's) ty_sig
+| TyNonTerminal :
+ string option *
+ ('a, 'b, 'c) Extend.ty_user_symbol * ('r, 's) ty_sig ->
+ ('a -> 'r, 'a -> 's) ty_sig
+
+type ty_ml = TyML : bool (** deprecated *) * ('r, 's) ty_sig * 'r * 's option -> ty_ml
+
+(** Wrapper to dynamically extend vernacular commands. *)
+val vernac_extend :
+ command:string ->
+ ?classifier:(string -> Vernacexpr.vernac_classification) ->
+ ?entry:Vernacexpr.vernac_expr Pcoq.Entry.t ->
+ ty_ml list -> unit
+
+(** {5 STM classifiers} *)
+
+val get_vernac_classifier :
+ Vernacexpr.extend_name -> classifier
+
+(** Low-level API, not for casual user. *)
+val declare_vernac_classifier :
+ string -> classifier array -> unit
diff --git a/intf/vernacexpr.ml b/vernac/vernacexpr.ml
index df061bfb..7d8595e4 100644
--- a/intf/vernacexpr.ml
+++ b/vernac/vernacexpr.ml
@@ -9,23 +9,19 @@
(************************************************************************)
open Names
-open Misctypes
open Constrexpr
open Libnames
(** Vernac expressions, produced by the parser *)
-type class_rawexpr = FunClass | SortClass | RefClass of reference or_by_notation
-
-(* spiwack: I'm choosing, for now, to have [goal_selector] be a
- different type than [goal_reference] mostly because if it makes sense
- to print a goal that is out of focus (or already solved) it doesn't
- make sense to apply a tactic to it. Hence it the types may look very
- similar, they do not seem to mean the same thing. *)
-type goal_selector =
- | SelectNth of int
- | SelectList of (int * int) list
- | SelectId of Id.t
- | SelectAll
+type class_rawexpr = FunClass | SortClass | RefClass of qualid or_by_notation
+
+type goal_selector = Goal_select.t =
+ | SelectAlreadyFocused [@ocaml.deprecated "Use Goal_select.SelectAlreadyFocused"]
+ | SelectNth of int [@ocaml.deprecated "Use Goal_select.SelectNth"]
+ | SelectList of (int * int) list [@ocaml.deprecated "Use Goal_select.SelectList"]
+ | SelectId of Id.t [@ocaml.deprecated "Use Goal_select.SelectId"]
+ | SelectAll [@ocaml.deprecated "Use Goal_select.SelectAll"]
+[@@ocaml.deprecated "Use Goal_select.t"]
type goal_identifier = string
type scope_name = string
@@ -35,43 +31,43 @@ type goal_reference =
| NthGoal of int
| GoalId of Id.t
-type univ_name_list = Universes.univ_name_list
-[@@ocaml.deprecated "Use [Universes.univ_name_list]"]
+type univ_name_list = UnivNames.univ_name_list
+[@@ocaml.deprecated "Use [UnivNames.univ_name_list]"]
type printable =
| PrintTables
| PrintFullContext
- | PrintSectionContext of reference
+ | PrintSectionContext of qualid
| PrintInspect of int
| PrintGrammar of string
| PrintLoadPath of DirPath.t option
| PrintModules
- | PrintModule of reference
- | PrintModuleType of reference
+ | PrintModule of qualid
+ | PrintModuleType of qualid
| PrintNamespace of DirPath.t
| PrintMLLoadPath
| PrintMLModules
| PrintDebugGC
- | PrintName of reference or_by_notation * Universes.univ_name_list option
+ | PrintName of qualid or_by_notation * UnivNames.univ_name_list option
| PrintGraph
| PrintClasses
| PrintTypeClasses
- | PrintInstances of reference or_by_notation
+ | PrintInstances of qualid or_by_notation
| PrintCoercions
| PrintCoercionPaths of class_rawexpr * class_rawexpr
| PrintCanonicalConversions
| PrintUniverses of bool * string option
- | PrintHint of reference or_by_notation
+ | PrintHint of qualid or_by_notation
| PrintHintGoal
| PrintHintDbName of string
| PrintHintDb
| PrintScopes
| PrintScope of string
| PrintVisibility of string option
- | PrintAbout of reference or_by_notation * Universes.univ_name_list option * goal_selector option
- | PrintImplicit of reference or_by_notation
- | PrintAssumptions of bool * bool * reference or_by_notation
- | PrintStrategy of reference or_by_notation option
+ | PrintAbout of qualid or_by_notation * UnivNames.univ_name_list option * Goal_select.t option
+ | PrintImplicit of qualid or_by_notation
+ | PrintAssumptions of bool * bool * qualid or_by_notation
+ | PrintStrategy of qualid or_by_notation option
type search_about_item =
| SearchSubPattern of constr_pattern_expr
@@ -84,11 +80,11 @@ type searchable =
| SearchAbout of (bool * search_about_item) list
type locatable =
- | LocateAny of reference or_by_notation
- | LocateTerm of reference or_by_notation
- | LocateLibrary of reference
- | LocateModule of reference
- | LocateOther of string * reference
+ | LocateAny of qualid or_by_notation
+ | LocateTerm of qualid or_by_notation
+ | LocateLibrary of qualid
+ | LocateModule of qualid
+ | LocateOther of string * qualid
| LocateFile of string
type showable =
@@ -99,44 +95,61 @@ type showable =
| ShowUniverses
| ShowProofNames
| ShowIntros of bool
- | ShowMatch of reference
+ | ShowMatch of qualid
type comment =
| CommentConstr of constr_expr
| CommentString of string
| CommentInt of int
-type reference_or_constr =
- | HintsReference of reference
- | HintsConstr of constr_expr
-
-type hint_mode =
- | ModeInput (* No evars *)
- | ModeNoHeadEvar (* No evar at the head *)
- | ModeOutput (* Anything *)
-
-type 'a hint_info_gen =
- { hint_priority : int option;
- hint_pattern : 'a option }
-
-type hint_info_expr = constr_pattern_expr hint_info_gen
-
-type hints_expr =
- | HintsResolve of (hint_info_expr * bool * reference_or_constr) list
- | HintsImmediate of reference_or_constr list
- | HintsUnfold of reference list
- | HintsTransparency of reference list * bool
- | HintsMode of reference * hint_mode list
- | HintsConstructors of reference list
+type reference_or_constr = Hints.reference_or_constr =
+ | HintsReference of qualid [@ocaml.deprecated "Use Hints.HintsReference"]
+ | HintsConstr of constr_expr [@ocaml.deprecated "Use Hints.HintsConstr"]
+[@@ocaml.deprecated "Please use [Hints.reference_or_constr]"]
+
+type hint_mode = Hints.hint_mode =
+ | ModeInput [@ocaml.deprecated "Use Hints.ModeInput"]
+ | ModeNoHeadEvar [@ocaml.deprecated "Use Hints.ModeNoHeadEvar"]
+ | ModeOutput [@ocaml.deprecated "Use Hints.ModeOutput"]
+[@@ocaml.deprecated "Please use [Hints.hint_mode]"]
+
+type 'a hint_info_gen = 'a Typeclasses.hint_info_gen =
+ { hint_priority : int option; [@ocaml.deprecated "Use Typeclasses.hint_priority"]
+ hint_pattern : 'a option [@ocaml.deprecated "Use Typeclasses.hint_pattern"] }
+[@@ocaml.deprecated "Please use [Typeclasses.hint_info_gen]"]
+
+type hint_info_expr = Hints.hint_info_expr
+[@@ocaml.deprecated "Please use [Hints.hint_info_expr]"]
+
+type hints_expr = Hints.hints_expr =
+ | HintsResolve of (Hints.hint_info_expr * bool * Hints.reference_or_constr) list
+ [@ocaml.deprecated "Use the constructor in module [Hints]"]
+ | HintsResolveIFF of bool * qualid list * int option
+ [@ocaml.deprecated "Use the constructor in module [Hints]"]
+ | HintsImmediate of Hints.reference_or_constr list
+ [@ocaml.deprecated "Use the constructor in module [Hints]"]
+ | HintsUnfold of qualid list
+ [@ocaml.deprecated "Use the constructor in module [Hints]"]
+ | HintsTransparency of qualid Hints.hints_transparency_target * bool
+ [@ocaml.deprecated "Use the constructor in module [Hints]"]
+ | HintsMode of qualid * Hints.hint_mode list
+ [@ocaml.deprecated "Use the constructor in module [Hints]"]
+ | HintsConstructors of qualid list
+ [@ocaml.deprecated "Use the constructor in module [Hints]"]
| HintsExtern of int * constr_expr option * Genarg.raw_generic_argument
+ [@ocaml.deprecated "Use the constructor in module [Hints]"]
+[@@ocaml.deprecated "Please use [Hints.hints_expr]"]
type search_restriction =
- | SearchInside of reference list
- | SearchOutside of reference list
+ | SearchInside of qualid list
+ | SearchOutside of qualid list
type rec_flag = bool (* true = Rec; false = NoRec *)
type verbose_flag = bool (* true = Verbose; false = Silent *)
-type opacity_flag = Opaque | Transparent
+type opacity_flag = Proof_global.opacity_flag =
+ Opaque [@ocaml.deprecated "Use Proof_global.Opaque"]
+ | Transparent [@ocaml.deprecated "Use Proof_global.Transparent"]
+ [@ocaml.deprecated "Please use [Proof_global.opacity_flag]"]
type coercion_flag = bool (* true = AddCoercion false = NoCoercion *)
type instance_flag = bool option
(* Some true = Backward instance; Some false = Forward instance, None = NoInstance *)
@@ -156,7 +169,7 @@ type option_value = Goptions.option_value =
type option_ref_value =
| StringRefValue of string
- | QualidRefValue of reference
+ | QualidRefValue of qualid
(** Identifier and optional list of bound universes and constraints. *)
@@ -197,16 +210,15 @@ type one_inductive_expr =
ident_decl * local_binder_expr list * constr_expr option * constructor_expr list
type typeclass_constraint = name_decl * Decl_kinds.binding_kind * constr_expr
-
and typeclass_context = typeclass_constraint list
type proof_expr =
ident_decl * (local_binder_expr list * constr_expr)
type syntax_modifier =
- | SetItemLevel of string list * Extend.production_level
- | SetItemLevelAsBinder of string list * Extend.constr_as_binder_kind * Extend.production_level option
+ | SetItemLevel of string list * Notation_term.constr_as_binder_kind option * Extend.production_level option
| SetLevel of int
+ | SetCustomEntry of string * int option
| SetAssoc of Extend.gram_assoc
| SetEntryType of string * Extend.simple_constr_prod_entry_key
| SetOnlyParsing
@@ -217,12 +229,12 @@ type syntax_modifier =
type proof_end =
| Admitted
(* name in `Save ident` when closing goal *)
- | Proved of opacity_flag * lident option
+ | Proved of Proof_global.opacity_flag * lident option
type scheme =
- | InductionScheme of bool * reference or_by_notation * sort_expr
- | CaseScheme of bool * reference or_by_notation * sort_expr
- | EqualityScheme of reference or_by_notation
+ | InductionScheme of bool * qualid or_by_notation * sort_expr
+ | CaseScheme of bool * qualid or_by_notation * sort_expr
+ | EqualityScheme of qualid or_by_notation
type section_subset_expr =
| SsEmpty
@@ -269,41 +281,42 @@ type extend_name =
(* This type allows registering the inlining of constants in native compiler.
It will be extended with primitive inductive types and operators *)
-type register_kind =
+type register_kind =
| RegisterInline
-type bullet =
- | Dash of int
- | Star of int
- | Plus of int
+type bullet = Proof_bullet.t
+[@@ocaml.deprecated "Alias type, please use [Proof_bullet.t]"]
(** {6 Types concerning the module layer} *)
(** Rigid / flexible module signature *)
-type 'a module_signature =
+type 'a module_signature = 'a Declaremods.module_signature =
| Enforce of 'a (** ... : T *)
+ [@ocaml.deprecated "Use the constructor in module [Declaremods]"]
| Check of 'a list (** ... <: T1 <: T2, possibly empty *)
+ [@ocaml.deprecated "Use the constructor in module [Declaremods]"]
+[@@ocaml.deprecated "please use [Declaremods.module_signature]."]
(** Which module inline annotations should we honor,
either None or the ones whose level is less or equal
to the given integer *)
-type inline =
+type inline = Declaremods.inline =
| NoInline
+ [@ocaml.deprecated "Use the constructor in module [Declaremods]"]
| DefaultInline
+ [@ocaml.deprecated "Use the constructor in module [Declaremods]"]
| InlineAt of int
+ [@ocaml.deprecated "Use the constructor in module [Declaremods]"]
+[@@ocaml.deprecated "please use [Declaremods.inline]."]
-type module_ast_inl = module_ast * inline
+type module_ast_inl = module_ast * Declaremods.inline
type module_binder = bool option * lident list * module_ast_inl
-(** Cumulativity can be set globally, locally or unset locally and it
- can not enabled at all. *)
-type cumulative_inductive_parsing_flag =
- | GlobalCumulativity
- | GlobalNonCumulativity
- | LocalCumulativity
- | LocalNonCumulativity
+(** [Some b] if locally enabled/disabled according to [b], [None] if
+ we should use the global flag. *)
+type vernac_cumulative = VernacCumulative | VernacNonCumulative
(** {6 The type of vernacular expressions} *)
@@ -330,6 +343,7 @@ type nonrec vernac_expr =
constr_expr * (lstring * syntax_modifier list) *
scope_name option
| VernacNotationAddFormat of string * string * string
+ | VernacDeclareCustomEntry of string
(* Gallina *)
| VernacDefinition of (Decl_kinds.discharge * Decl_kinds.definition_object_kind) * name_decl * definition_expr
@@ -337,47 +351,47 @@ type nonrec vernac_expr =
| VernacEndProof of proof_end
| VernacExactProof of constr_expr
| VernacAssumption of (Decl_kinds.discharge * Decl_kinds.assumption_object_kind) *
- inline * (ident_decl list * constr_expr) with_coercion list
- | VernacInductive of cumulative_inductive_parsing_flag * Decl_kinds.private_flag * inductive_flag * (inductive_expr * decl_notation list) list
+ Declaremods.inline * (ident_decl list * constr_expr) with_coercion list
+ | VernacInductive of vernac_cumulative option * Decl_kinds.private_flag * inductive_flag * (inductive_expr * decl_notation list) list
| VernacFixpoint of Decl_kinds.discharge * (fixpoint_expr * decl_notation list) list
| VernacCoFixpoint of Decl_kinds.discharge * (cofixpoint_expr * decl_notation list) list
| VernacScheme of (lident option * scheme) list
| VernacCombinedScheme of lident * lident list
| VernacUniverse of lident list
- | VernacConstraint of glob_constraint list
+ | VernacConstraint of Glob_term.glob_constraint list
(* Gallina extensions *)
| VernacBeginSection of lident
| VernacEndSegment of lident
| VernacRequire of
- reference option * export_flag option * reference list
- | VernacImport of export_flag * reference list
- | VernacCanonical of reference or_by_notation
- | VernacCoercion of reference or_by_notation *
+ qualid option * export_flag option * qualid list
+ | VernacImport of export_flag * qualid list
+ | VernacCanonical of qualid or_by_notation
+ | VernacCoercion of qualid or_by_notation *
class_rawexpr * class_rawexpr
| VernacIdentityCoercion of lident * class_rawexpr * class_rawexpr
- | VernacNameSectionHypSet of lident * section_subset_expr
+ | VernacNameSectionHypSet of lident * section_subset_expr
(* Type classes *)
| VernacInstance of
bool * (* abstract instance *)
local_binder_expr list * (* super *)
- typeclass_constraint * (* instance name, class name, params *)
- (bool * constr_expr) option * (* props *)
- hint_info_expr
+ typeclass_constraint * (* instance name, class name, params *)
+ (bool * constr_expr) option * (* props *)
+ Hints.hint_info_expr
| VernacContext of local_binder_expr list
| VernacDeclareInstances of
- (reference * hint_info_expr) list (* instances names, priorities and patterns *)
+ (qualid * Hints.hint_info_expr) list (* instances names, priorities and patterns *)
- | VernacDeclareClass of reference (* inductive or definition name *)
+ | VernacDeclareClass of qualid (* inductive or definition name *)
(* Modules and Module Types *)
| VernacDeclareModule of bool option * lident *
module_binder list * module_ast_inl
| VernacDefineModule of bool option * lident * module_binder list *
- module_ast_inl module_signature * module_ast_inl list
+ module_ast_inl Declaremods.module_signature * module_ast_inl list
| VernacDeclareModuleType of lident *
module_binder list * module_ast_inl list * module_ast_inl list
| VernacInclude of module_ast_inl list
@@ -405,37 +419,33 @@ type nonrec vernac_expr =
(* Commands *)
| VernacCreateHintDb of string * bool
- | VernacRemoveHints of string list * reference list
- | VernacHints of string list * hints_expr
+ | VernacRemoveHints of string list * qualid list
+ | VernacHints of string list * Hints.hints_expr
| VernacSyntacticDefinition of lident * (Id.t list * constr_expr) *
onlyparsing_flag
- | VernacDeclareImplicits of reference or_by_notation *
- (explicitation * bool * bool) list list
- | VernacArguments of reference or_by_notation *
+ | VernacArguments of qualid or_by_notation *
vernac_argument_status list (* Main arguments status list *) *
(Name.t * vernac_implicit_status) list list (* Extra implicit status lists *) *
int option (* Number of args to trigger reduction *) *
[ `ReductionDontExposeCase | `ReductionNeverUnfold | `Rename |
`ExtraScopes | `Assert | `ClearImplicits | `ClearScopes |
`DefaultImplicits ] list
- | VernacArgumentsScope of reference or_by_notation *
- scope_name option list
| VernacReserve of simple_binder list
| VernacGeneralizable of (lident list) option
- | VernacSetOpacity of (Conv_oracle.level * reference or_by_notation list)
+ | VernacSetOpacity of (Conv_oracle.level * qualid or_by_notation list)
| VernacSetStrategy of
- (Conv_oracle.level * reference or_by_notation list) list
+ (Conv_oracle.level * qualid or_by_notation list) list
| VernacUnsetOption of export_flag * Goptions.option_name
| VernacSetOption of export_flag * Goptions.option_name * option_value
| VernacAddOption of Goptions.option_name * option_ref_value list
| VernacRemoveOption of Goptions.option_name * option_ref_value list
| VernacMemOption of Goptions.option_name * option_ref_value list
| VernacPrintOption of Goptions.option_name
- | VernacCheckMayEval of Genredexpr.raw_red_expr option * goal_selector option * constr_expr
+ | VernacCheckMayEval of Genredexpr.raw_red_expr option * Goal_select.t option * constr_expr
| VernacGlobalCheck of constr_expr
| VernacDeclareReduction of string * Genredexpr.raw_red_expr
| VernacPrint of printable
- | VernacSearch of searchable * goal_selector option * search_restriction
+ | VernacSearch of searchable * Goal_select.t option * search_restriction
| VernacLocate of locatable
| VernacRegister of lident * register_kind
| VernacComments of comment list
@@ -446,30 +456,28 @@ type nonrec vernac_expr =
| VernacRestart
| VernacUndo of int
| VernacUndoTo of int
- | VernacBacktrack of int*int*int
| VernacFocus of int option
| VernacUnfocus
| VernacUnfocused
- | VernacBullet of bullet
- | VernacSubproof of goal_selector option
+ | VernacBullet of Proof_bullet.t
+ | VernacSubproof of Goal_select.t option
| VernacEndSubproof
| VernacShow of showable
| VernacCheckGuard
| VernacProof of Genarg.raw_generic_argument option * section_subset_expr option
| VernacProofMode of string
- (* Toplevel control *)
- | VernacToplevelControl of exn
(* For extension *)
| VernacExtend of extend_name * Genarg.raw_generic_argument list
-type nonrec vernac_flag =
- | VernacProgram
- | VernacPolymorphic of bool
- | VernacLocal of bool
+type vernac_flags = (string * vernac_flag_value) list
+and vernac_flag_value =
+ | VernacFlagEmpty
+ | VernacFlagLeaf of string
+ | VernacFlagList of vernac_flags
type vernac_control =
- | VernacExpr of vernac_flag list * vernac_expr
+ | VernacExpr of vernac_flags * vernac_expr
(* boolean is true when the `-time` batch-mode command line flag was set.
the flag is used to print differently in `-time` vs `Time foo` *)
| VernacTime of bool * vernac_control CAst.t
@@ -508,14 +516,13 @@ type vernac_type =
| VtProofMode of string
(* Queries are commands assumed to be "pure", that is to say, they
don't modify the interpretation state. *)
- | VtQuery of vernac_part_of_script * Feedback.route_id
+ | VtQuery
(* To be removed *)
| VtMeta
| VtUnknown
and vernac_qed_type = VtKeep | VtKeepAsAxiom | VtDrop (* Qed/Admitted, Abort *)
and vernac_start = string * opacity_guarantee * Id.t list
and vernac_sideff_type = Id.t list
-and vernac_part_of_script = bool
and opacity_guarantee =
| GuaranteesOpacity (** Only generates opaque terms at [Qed] *)
| Doesn'tGuaranteeOpacity (** May generate transparent terms even with [Qed].*)
@@ -530,14 +537,3 @@ type vernac_when =
| VtNow
| VtLater
type vernac_classification = vernac_type * vernac_when
-
-
-(** Deprecated stuff *)
-type universe_decl_expr = Constrexpr.universe_decl_expr
-[@@ocaml.deprecated "alias of Constrexpr.universe_decl_expr"]
-
-type ident_decl = Constrexpr.ident_decl
-[@@ocaml.deprecated "alias of Constrexpr.ident_decl"]
-
-type name_decl = Constrexpr.name_decl
-[@@ocaml.deprecated "alias of Constrexpr.name_decl"]
diff --git a/vernac/vernacinterp.ml b/vernac/vernacinterp.ml
index 1f2d2e4b..1bb1414f 100644
--- a/vernac/vernacinterp.ml
+++ b/vernac/vernacinterp.ml
@@ -12,15 +12,22 @@ open Util
open Pp
open CErrors
-type deprecation = bool
+type deprecation = { since : string option ; note : string option }
+
+let mk_deprecation ?(since=None) ?(note=None) () =
+ { since ; note }
type atts = {
loc : Loc.t option;
locality : bool option;
polymorphic : bool;
program : bool;
+ deprecated : deprecation option;
}
+let mk_atts ?(loc=None) ?(locality=None) ?(polymorphic=false) ?(program=false) ?(deprecated=None) () : atts =
+ { loc ; locality ; polymorphic ; program ; deprecated }
+
type 'a vernac_command = 'a -> atts:atts -> st:Vernacstate.t -> Vernacstate.t
type plugin_args = Genarg.raw_generic_argument list
@@ -28,7 +35,7 @@ type plugin_args = Genarg.raw_generic_argument list
(* Table of vernac entries *)
let vernac_tab =
(Hashtbl.create 211 :
- (Vernacexpr.extend_name, deprecation * plugin_args vernac_command) Hashtbl.t)
+ (Vernacexpr.extend_name, bool * plugin_args vernac_command) Hashtbl.t)
let vinterp_add depr s f =
try
@@ -79,7 +86,6 @@ let call opn converted_args ~atts ~st =
phase := "Executing command";
hunk ~atts ~st
with
- | Drop -> raise Drop
| reraise ->
let reraise = CErrors.push reraise in
if !Flags.debug then
diff --git a/vernac/vernacinterp.mli b/vernac/vernacinterp.mli
index 935cacf7..46468b30 100644
--- a/vernac/vernacinterp.mli
+++ b/vernac/vernacinterp.mli
@@ -10,21 +10,27 @@
(** Interpretation of extended vernac phrases. *)
-type deprecation = bool
+type deprecation = { since : string option ; note : string option }
+
+val mk_deprecation : ?since: string option -> ?note: string option -> unit -> deprecation
type atts = {
loc : Loc.t option;
locality : bool option;
polymorphic : bool;
program : bool;
+ deprecated : deprecation option;
}
+val mk_atts : ?loc: Loc.t option -> ?locality: bool option ->
+ ?polymorphic: bool -> ?program: bool -> ?deprecated: deprecation option -> unit -> atts
+
type 'a vernac_command = 'a -> atts:atts -> st:Vernacstate.t -> Vernacstate.t
type plugin_args = Genarg.raw_generic_argument list
val vinterp_init : unit -> unit
-val vinterp_add : deprecation -> Vernacexpr.extend_name -> plugin_args vernac_command -> unit
+val vinterp_add : bool -> Vernacexpr.extend_name -> plugin_args vernac_command -> unit
val overwriting_vinterp_add : Vernacexpr.extend_name -> plugin_args vernac_command -> unit
val call : Vernacexpr.extend_name -> plugin_args -> atts:atts -> st:Vernacstate.t -> Vernacstate.t
diff --git a/vernac/vernacprop.ml b/vernac/vernacprop.ml
index a837b77a..0fdd2faa 100644
--- a/vernac/vernacprop.ml
+++ b/vernac/vernacprop.ml
@@ -31,7 +31,6 @@ let rec has_Fail = function
let is_navigation_vernac_expr = function
| VernacResetInitial
| VernacResetName _
- | VernacBacktrack _
| VernacBackTo _
| VernacBack _ -> true
| _ -> false