aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml155
-rw-r--r--.github/CODEOWNERS25
-rw-r--r--.gitignore2
-rw-r--r--.gitlab-ci.yml353
-rw-r--r--.merlin2
-rw-r--r--.travis.yml79
-rw-r--r--CHANGES29
-rw-r--r--CONTRIBUTING.md8
-rw-r--r--INSTALL.doc30
-rw-r--r--Makefile7
-rw-r--r--Makefile.build42
-rw-r--r--Makefile.checker35
-rw-r--r--Makefile.ci9
-rw-r--r--Makefile.common45
-rw-r--r--Makefile.dev2
-rw-r--r--Makefile.doc109
-rw-r--r--Makefile.ide52
-rw-r--r--Makefile.install10
-rw-r--r--Makefile.vofiles40
-rw-r--r--README.md1
-rw-r--r--appveyor.yml12
-rw-r--r--checker/univ.ml8
-rw-r--r--checker/univ.mli12
-rw-r--r--configure.ml16
-rw-r--r--default.nix4
-rw-r--r--dev/base_include2
-rw-r--r--dev/build/windows/makecoq_mingw.sh33
-rw-r--r--dev/build/windows/patches_coq/lablgtk-2.18.3.patch44
-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.md105
-rw-r--r--dev/ci/appveyor.sh2
-rwxr-xr-xdev/ci/ci-basic-overlay.sh8
-rw-r--r--dev/ci/ci-common.sh12
-rwxr-xr-xdev/ci/ci-compcert.sh1
-rwxr-xr-xdev/ci/ci-cross-crypto.sh11
-rwxr-xr-xdev/ci/ci-fiat-crypto.sh4
-rwxr-xr-xdev/ci/ci-geocoq.sh4
-rwxr-xr-xdev/ci/ci-math-classes.sh2
-rwxr-xr-xdev/ci/ci-math-comp.sh11
-rwxr-xr-xdev/ci/ci-pidetop.sh15
-rwxr-xr-xdev/ci/ci-unimath.sh5
-rwxr-xr-xdev/ci/ci-vst.sh5
-rw-r--r--dev/ci/docker/README.md36
-rw-r--r--dev/ci/docker/bionic_coq/Dockerfile49
-rw-r--r--dev/ci/gitlab.bat50
-rw-r--r--dev/ci/user-overlays/06859-ejgallego-stm+top.sh6
-rw-r--r--dev/ci/user-overlays/07213-ppedrot-fast-constr-match-no-context.sh6
-rw-r--r--dev/core.dbg2
-rw-r--r--dev/doc/MERGING.md5
-rw-r--r--dev/doc/changes.md22
-rw-r--r--dev/ocamldebug-coq.run18
-rwxr-xr-xdev/tools/check-owners-pr.sh32
-rwxr-xr-xdev/tools/check-owners.sh138
-rw-r--r--dev/tools/coqdev.el45
-rwxr-xr-xdev/tools/pre-commit6
-rw-r--r--dev/top_printers.ml6
-rw-r--r--dev/top_printers.mli6
-rw-r--r--doc/RecTutorial/RecTutorial.tex3690
-rw-r--r--doc/RecTutorial/RecTutorial.v1231
-rw-r--r--doc/RecTutorial/coqartmacros.tex180
-rw-r--r--doc/RecTutorial/manbiblio.bib870
-rw-r--r--doc/RecTutorial/morebib.bib55
-rw-r--r--doc/RecTutorial/recmacros.tex75
-rw-r--r--doc/sphinx/MIGRATING238
-rw-r--r--doc/sphinx/README.rst325
-rw-r--r--doc/sphinx/README.template.rst117
-rw-r--r--doc/sphinx/addendum/extended-pattern-matching.rst16
-rw-r--r--doc/sphinx/addendum/extraction.rst74
-rw-r--r--doc/sphinx/addendum/generalized-rewriting.rst52
-rw-r--r--doc/sphinx/addendum/implicit-coercions.rst81
-rw-r--r--doc/sphinx/addendum/micromega.rst7
-rw-r--r--doc/sphinx/addendum/miscellaneous-extensions.rst2
-rw-r--r--doc/sphinx/addendum/omega.rst53
-rw-r--r--doc/sphinx/addendum/program.rst13
-rw-r--r--doc/sphinx/addendum/ring.rst18
-rw-r--r--doc/sphinx/addendum/type-classes.rst241
-rw-r--r--doc/sphinx/addendum/universe-polymorphism.rst14
-rw-r--r--doc/sphinx/biblio.bib9
-rwxr-xr-xdoc/sphinx/conf.py12
-rw-r--r--doc/sphinx/index.rst3
-rw-r--r--doc/sphinx/introduction.rst11
-rw-r--r--doc/sphinx/language/cic.rst56
-rw-r--r--doc/sphinx/language/gallina-extensions.rst250
-rw-r--r--doc/sphinx/language/gallina-specification-language.rst193
-rw-r--r--doc/sphinx/practical-tools/coq-commands.rst17
-rw-r--r--doc/sphinx/practical-tools/utilities.rst2
-rw-r--r--doc/sphinx/proof-engine/ltac.rst66
-rw-r--r--doc/sphinx/proof-engine/proof-handling.rst597
-rw-r--r--doc/sphinx/proof-engine/ssreflect-proof-language.rst12
-rw-r--r--doc/sphinx/proof-engine/tactics.rst859
-rw-r--r--doc/sphinx/proof-engine/vernacular-commands.rst1403
-rw-r--r--doc/sphinx/user-extensions/proof-schemes.rst17
-rw-r--r--doc/sphinx/user-extensions/syntax-extensions.rst7
-rw-r--r--doc/tools/coqrst/coqdoc/main.py3
-rw-r--r--doc/tools/coqrst/coqdomain.py344
-rwxr-xr-xdoc/tools/coqrst/regen_readme.py58
-rw-r--r--doc/tools/coqrst/repl/coqtop.py4
-rw-r--r--doc/tutorial/Tutorial.tex1575
-rw-r--r--engine/eConstr.ml37
-rw-r--r--engine/eConstr.mli10
-rw-r--r--engine/engine.mllib5
-rw-r--r--engine/evar_kinds.ml3
-rw-r--r--engine/evarutil.ml45
-rw-r--r--engine/evarutil.mli72
-rw-r--r--engine/evd.ml56
-rw-r--r--engine/evd.mli14
-rw-r--r--engine/termops.ml4
-rw-r--r--engine/termops.mli8
-rw-r--r--engine/uState.ml61
-rw-r--r--engine/uState.mli10
-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.ml105
-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.ml1174
-rw-r--r--engine/universes.mli258
-rw-r--r--ide/coq.ml4
-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)28
-rw-r--r--ide/ideutils.ml18
-rw-r--r--interp/constrextern.mli8
-rw-r--r--interp/constrintern.ml24
-rw-r--r--interp/constrintern.mli11
-rw-r--r--interp/declare.ml8
-rw-r--r--interp/declare.mli4
-rw-r--r--interp/dumpglob.mli4
-rw-r--r--interp/impargs.ml4
-rw-r--r--interp/impargs.mli9
-rw-r--r--interp/implicit_quantifiers.mli5
-rw-r--r--interp/notation.ml51
-rw-r--r--interp/notation.mli17
-rw-r--r--interp/notation_ops.ml12
-rw-r--r--interp/notation_term.ml3
-rw-r--r--interp/reserve.ml2
-rw-r--r--interp/smartlocate.mli8
-rw-r--r--interp/stdarg.mli7
-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.c34
-rw-r--r--kernel/byterun/coq_memory.c20
-rw-r--r--kernel/byterun/coq_values.c31
-rw-r--r--kernel/cemitcodes.ml4
-rw-r--r--kernel/constr.ml8
-rw-r--r--kernel/constr.mli2
-rw-r--r--kernel/names.ml44
-rw-r--r--kernel/names.mli38
-rw-r--r--kernel/vmvalues.ml32
-rw-r--r--lib/control.ml5
-rw-r--r--lib/control.mli5
-rw-r--r--lib/coqProject_file.ml415
-rw-r--r--lib/flags.ml2
-rw-r--r--lib/flags.mli3
-rw-r--r--lib/stateid.ml10
-rw-r--r--lib/system.ml18
-rw-r--r--lib/system.mli20
-rw-r--r--library/coqlib.ml34
-rw-r--r--library/coqlib.mli123
-rw-r--r--library/global.mli12
-rw-r--r--library/globnames.ml13
-rw-r--r--library/globnames.mli55
-rw-r--r--library/keys.ml7
-rw-r--r--library/keys.mli4
-rw-r--r--library/lib.ml23
-rw-r--r--library/lib.mli72
-rw-r--r--library/libnames.ml3
-rw-r--r--library/libnames.mli2
-rw-r--r--library/misctypes.ml19
-rw-r--r--library/nametab.ml1
-rw-r--r--library/nametab.mli22
-rw-r--r--man/coqtop.12
-rw-r--r--parsing/g_constr.ml41
-rw-r--r--parsing/g_vernac.ml46
-rw-r--r--parsing/pcoq.mli6
-rw-r--r--plugins/btauto/refl_btauto.ml4
-rw-r--r--plugins/cc/cctac.ml7
-rw-r--r--plugins/extraction/common.mli3
-rw-r--r--plugins/extraction/extract_env.ml2
-rw-r--r--plugins/extraction/extract_env.mli3
-rw-r--r--plugins/extraction/extraction.ml2
-rw-r--r--plugins/extraction/miniml.ml25
-rw-r--r--plugins/extraction/miniml.mli25
-rw-r--r--plugins/extraction/mlutil.ml16
-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.mli69
-rw-r--r--plugins/firstorder/formula.ml2
-rw-r--r--plugins/firstorder/formula.mli8
-rw-r--r--plugins/firstorder/instances.ml2
-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.ml20
-rw-r--r--plugins/firstorder/sequent.mli22
-rw-r--r--plugins/fourier/fourierR.ml10
-rw-r--r--plugins/funind/functional_principles_proofs.ml13
-rw-r--r--plugins/funind/functional_principles_types.ml8
-rw-r--r--plugins/funind/glob_term_to_relation.ml4
-rw-r--r--plugins/funind/glob_termops.ml2
-rw-r--r--plugins/funind/glob_termops.mli2
-rw-r--r--plugins/funind/indfun.ml5
-rw-r--r--plugins/funind/indfun.mli3
-rw-r--r--plugins/funind/indfun_common.ml8
-rw-r--r--plugins/funind/indfun_common.mli6
-rw-r--r--plugins/funind/invfun.ml10
-rw-r--r--plugins/funind/invfun.mli2
-rw-r--r--plugins/funind/recdef.ml16
-rw-r--r--plugins/ltac/evar_tactics.ml4
-rw-r--r--plugins/ltac/extratactics.ml42
-rw-r--r--plugins/ltac/rewrite.ml7
-rw-r--r--plugins/ltac/taccoerce.mli2
-rw-r--r--plugins/ltac/tacinterp.ml6
-rw-r--r--plugins/ltac/tactic_matching.ml2
-rw-r--r--plugins/micromega/coq_micromega.ml2
-rw-r--r--plugins/nsatz/nsatz.ml2
-rw-r--r--plugins/omega/coq_omega.ml2
-rw-r--r--plugins/quote/quote.ml2
-rw-r--r--plugins/romega/const_omega.ml10
-rw-r--r--plugins/rtauto/refl_tauto.ml8
-rw-r--r--plugins/setoid_ring/newring.ml78
-rw-r--r--plugins/setoid_ring/newring.mli3
-rw-r--r--plugins/ssr/ssrcommon.ml4
-rw-r--r--plugins/ssr/ssrcommon.mli4
-rw-r--r--plugins/ssr/ssrelim.ml2
-rw-r--r--plugins/ssr/ssrequality.ml8
-rw-r--r--plugins/ssr/ssrfwd.ml4
-rw-r--r--plugins/ssr/ssrtacticals.ml5
-rw-r--r--plugins/ssrmatching/ssrmatching.ml47
-rw-r--r--plugins/syntax/ascii_syntax.ml2
-rw-r--r--plugins/syntax/int31_syntax.ml2
-rw-r--r--plugins/syntax/nat_syntax.ml9
-rw-r--r--plugins/syntax/r_syntax.ml6
-rw-r--r--plugins/syntax/string_syntax.ml5
-rw-r--r--plugins/syntax/z_syntax.ml8
-rw-r--r--pretyping/arguments_renaming.ml2
-rw-r--r--pretyping/arguments_renaming.mli5
-rw-r--r--pretyping/cases.ml57
-rw-r--r--pretyping/classops.ml6
-rw-r--r--pretyping/classops.mli2
-rw-r--r--pretyping/coercion.ml44
-rw-r--r--pretyping/constr_matching.ml6
-rw-r--r--pretyping/constr_matching.mli2
-rw-r--r--pretyping/constrexpr.ml6
-rw-r--r--pretyping/detyping.mli1
-rw-r--r--pretyping/evarconv.ml27
-rw-r--r--pretyping/evarconv.mli8
-rw-r--r--pretyping/glob_ops.ml2
-rw-r--r--pretyping/glob_term.ml22
-rw-r--r--pretyping/indrec.ml4
-rw-r--r--pretyping/indrec.mli2
-rw-r--r--pretyping/miscops.ml2
-rw-r--r--pretyping/miscops.mli2
-rw-r--r--pretyping/pattern.ml5
-rw-r--r--pretyping/patternops.ml2
-rw-r--r--pretyping/patternops.mli10
-rw-r--r--pretyping/pretyping.ml39
-rw-r--r--pretyping/pretyping.mli2
-rw-r--r--pretyping/program.ml4
-rw-r--r--pretyping/program.mli38
-rw-r--r--pretyping/recordops.ml4
-rw-r--r--pretyping/recordops.mli13
-rw-r--r--pretyping/reductionops.ml10
-rw-r--r--pretyping/reductionops.mli8
-rw-r--r--pretyping/tacred.ml2
-rw-r--r--pretyping/tacred.mli11
-rw-r--r--pretyping/typeclasses.ml29
-rw-r--r--pretyping/typeclasses.mli48
-rw-r--r--pretyping/typeclasses_errors.ml4
-rw-r--r--pretyping/typeclasses_errors.mli6
-rw-r--r--pretyping/typing.ml397
-rw-r--r--pretyping/typing.mli11
-rw-r--r--pretyping/unification.ml20
-rw-r--r--pretyping/vernacexpr.ml22
-rw-r--r--printing/ppconstr.ml6
-rw-r--r--printing/ppconstr.mli4
-rw-r--r--printing/ppvernac.ml2
-rw-r--r--printing/prettyp.ml11
-rw-r--r--printing/prettyp.mli11
-rw-r--r--printing/printer.ml2
-rw-r--r--printing/printer.mli5
-rw-r--r--printing/printmod.ml4
-rw-r--r--printing/printmod.mli2
-rw-r--r--proofs/proof_global.ml2
-rw-r--r--proofs/refine.ml23
-rw-r--r--proofs/refiner.mli3
-rw-r--r--proofs/tacmach.ml4
-rw-r--r--proofs/tacmach.mli5
-rw-r--r--stm/asyncTaskQueue.ml18
-rw-r--r--stm/coqworkmgrApi.ml4
-rw-r--r--stm/coqworkmgrApi.mli3
-rw-r--r--stm/proofworkertop.mllib1
-rw-r--r--stm/queryworkertop.mllib1
-rw-r--r--stm/stm.ml28
-rw-r--r--stm/stm.mllib1
-rw-r--r--stm/tacworkertop.mllib1
-rw-r--r--stm/vernac_classifier.ml9
-rw-r--r--stm/vernac_classifier.mli1
-rw-r--r--tactics/auto.ml2
-rw-r--r--tactics/autorewrite.ml2
-rw-r--r--tactics/btermdn.ml2
-rw-r--r--tactics/class_tactics.ml6
-rw-r--r--tactics/eauto.ml9
-rw-r--r--tactics/eqschemes.ml24
-rw-r--r--tactics/equality.ml40
-rw-r--r--tactics/hints.ml48
-rw-r--r--tactics/hints.mli39
-rw-r--r--tactics/hipattern.ml6
-rw-r--r--tactics/hipattern.mli2
-rw-r--r--tactics/ind_tables.ml2
-rw-r--r--tactics/tacticals.mli4
-rw-r--r--tactics/tactics.ml47
-rw-r--r--tactics/tactics.mli5
-rw-r--r--tactics/term_dnet.ml2
-rw-r--r--test-suite/Makefile75
-rw-r--r--test-suite/README.md3
-rw-r--r--test-suite/bugs/closed/2969.v2
-rw-r--r--test-suite/bugs/closed/3377.v3
-rw-r--r--test-suite/bugs/closed/4069.v2
-rw-r--r--test-suite/bugs/closed/4198.v2
-rw-r--r--test-suite/bugs/closed/4722.v1
l---------test-suite/bugs/closed/4722/tata1
-rw-r--r--test-suite/bugs/closed/4782.v2
-rw-r--r--test-suite/bugs/closed/7462.v13
-rw-r--r--test-suite/bugs/closed/7554.v12
-rwxr-xr-xtest-suite/check7
-rwxr-xr-xtest-suite/coq-makefile/timing/run.sh2
-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/misc/.gitignore2
-rwxr-xr-xtest-suite/misc/4722.sh15
-rwxr-xr-xtest-suite/misc/coqc_dash_o.sh15
-rw-r--r--test-suite/misc/coqc_dash_o.v1
-rw-r--r--test-suite/output/Cases.v1
-rw-r--r--test-suite/output/Notations3.out10
-rw-r--r--test-suite/output/Notations3.v5
-rw-r--r--test-suite/output/UnclosedBlocks.out1
-rw-r--r--test-suite/output/ltac.v3
-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/ssr_mini_mathcomp.v1472
-rw-r--r--test-suite/prerequisite/ssr_ssrsyntax1.v36
-rwxr-xr-xtest-suite/save-logs.sh2
-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/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.v22
-rw-r--r--test-suite/ssr/intro_beta.v25
-rw-r--r--test-suite/ssr/intro_noop.v37
-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.v19
-rw-r--r--test-suite/ssr/multiview.v58
-rw-r--r--test-suite/ssr/occarrow.v23
-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/set_lamda.v27
-rw-r--r--test-suite/ssr/set_pattern.v64
-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 ide/ide_slave.mli)10
-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/success/Inversion.v2
-rw-r--r--test-suite/success/RecTutorial.v2
-rw-r--r--test-suite/success/destruct.v1
-rw-r--r--test-suite/success/intros.v24
-rw-r--r--test-suite/success/refine.v4
-rw-r--r--test-suite/success/sideff.v2
-rw-r--r--test-suite/unit-tests/.merlin6
-rw-r--r--test-suite/unit-tests/clib/inteq.ml13
-rw-r--r--test-suite/unit-tests/clib/unicode_tests.ml15
-rw-r--r--test-suite/unit-tests/src/utest.ml74
-rw-r--r--test-suite/unit-tests/src/utest.mli12
-rw-r--r--tools/coqdep.ml53
-rw-r--r--tools/coqdep_common.ml49
-rw-r--r--tools/coqdep_common.mli2
-rw-r--r--tools/fake_ide.ml22
-rw-r--r--tools/ocamllibdep.mll12
-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.ml37
-rw-r--r--toplevel/coqargs.mli3
-rw-r--r--toplevel/coqinit.ml8
-rw-r--r--toplevel/coqloop.ml67
-rw-r--r--toplevel/coqloop.mli12
-rw-r--r--toplevel/coqtop.ml149
-rw-r--r--toplevel/coqtop.mli25
-rw-r--r--toplevel/toplevel.mllib5
-rw-r--r--toplevel/workerLoop.ml (renamed from stm/workerLoop.ml)20
-rw-r--r--toplevel/workerLoop.mli14
-rw-r--r--vernac/assumptions.mli2
-rw-r--r--vernac/auto_ind_decl.ml16
-rw-r--r--vernac/auto_ind_decl.mli2
-rw-r--r--vernac/class.ml2
-rw-r--r--vernac/class.mli9
-rw-r--r--vernac/classes.ml5
-rw-r--r--vernac/classes.mli10
-rw-r--r--vernac/comAssumption.ml2
-rw-r--r--vernac/comAssumption.mli5
-rw-r--r--vernac/comDefinition.ml4
-rw-r--r--vernac/comFixpoint.ml4
-rw-r--r--vernac/comInductive.ml73
-rw-r--r--vernac/comInductive.mli4
-rw-r--r--vernac/comProgramFixpoint.ml6
-rw-r--r--vernac/declareDef.mli10
-rw-r--r--vernac/explainErr.ml2
-rw-r--r--vernac/himsg.ml6
-rw-r--r--vernac/indschemes.ml2
-rw-r--r--vernac/lemmas.ml2
-rw-r--r--vernac/lemmas.mli4
-rw-r--r--vernac/metasyntax.ml6
-rw-r--r--vernac/mltop.ml9
-rw-r--r--vernac/mltop.mli3
-rw-r--r--vernac/obligations.ml14
-rw-r--r--vernac/obligations.mli3
-rw-r--r--vernac/record.ml10
-rw-r--r--vernac/record.mli7
-rw-r--r--vernac/search.ml11
-rw-r--r--vernac/search.mli5
-rw-r--r--vernac/topfmt.ml35
-rw-r--r--vernac/topfmt.mli11
-rw-r--r--vernac/vernacentries.ml4
461 files changed, 11654 insertions, 13854 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 451b711be..4d2fb1a4d 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -8,83 +8,30 @@ defaults:
# reference syntax)
working_directory: ~/coq
docker:
- - image: ocaml/opam:ubuntu
+ - image: $CI_REGISTRY_IMAGE:$CACHEKEY
environment: &envvars
- # required by some of the targets, e.g. compcert, passed for
- # instance to opam to configure the number of parallel jobs
- # allowed
- NJOBS: 2
- COMPILER: "system"
- CAMLP5_VER: "6.14"
- NATIVE_COMP: "yes"
-
- # some useful values
- TIMING_PACKAGES: &timing-packages "time python"
+ CACHEKEY: "bionic_coq-V2018-05-07-V2"
+ CI_REGISTRY_IMAGE: registry.gitlab.com/coq/coq
version: 2
before_script: &before_script
- name: Install system packages
+ name: Setup OPAM Switch
command: |
echo export TERM=xterm >> ~/.profile
source ~/.profile
- printenv
- if [ -n "${EXTRA_PACKAGES}" ]; then sudo apt-get update -yq && sudo apt-get install -yq --no-install-recommends ${EXTRA_PACKAGES}; fi
echo . ~/.profile >> $BASH_ENV
-
-opam-switch: &opam-switch
- name: Select opam switch
- command: |
- opam switch ${COMPILER}
+ printenv | sort
+ opam switch "$COMPILER"
opam config list
opam list
-.opam-boot-template: &opam-boot-template
- <<: *params
- steps:
- - checkout
- - run: *before_script
- - run:
- name: Cache selection
- command: |
- # We can't use environment variables in cache names
- # So put it in a file and use the checksum
- echo "$COMPILER" > COMPILER
- - restore_cache:
- keys:
- - coq-opam-cache-v1-{{ arch }}-{{ checksum "COMPILER" }}-{{ checksum ".circleci/config.yml" }}-
- - run:
- name: Update opam lists
- command: |
- opam repository set-url default https://opam.ocaml.org
- opam update
- - run:
- name: Install opam packages
- command: |
- opam switch -j ${NJOBS} ${COMPILER}
- opam install -j ${NJOBS} -y camlp5.${CAMLP5_VER} ocamlfind ${EXTRA_OPAM}
- - run:
- name: Clean cache
- command: |
- rm -rf ~/.opam/log/
- - save_cache:
- key: coq-opam-cache-v1-{{ arch }}-{{ checksum "COMPILER" }}-{{ checksum ".circleci/config.yml" }}-
- paths:
- - ~/.opam
- - persist_to_workspace:
- root: &workspace ~/
- paths:
- - .opam/
-
.build-template: &build-template
<<: *params
steps:
- checkout
- run: *before_script
- - attach_workspace: &attach_workspace
- at: *workspace
- - run: *opam-switch
- run: &build-configure
name: Configure
command: |
@@ -96,17 +43,21 @@ opam-switch: &opam-switch
make -j ${NJOBS}
make test-suite/misc/universes/all_stdlib.v
- persist_to_workspace:
- root: *workspace
+ root: &workspace ~/
paths:
- coq/
- environment: *envvars
+ environment:
+ <<: *envvars
+ NATIVE_COMP: "yes"
.ci-template: &ci-template
<<: *params
steps:
- run: *before_script
- - attach_workspace: *attach_workspace
+ - attach_workspace: &attach_workspace
+ at: *workspace
+
- run:
name: Test
command: |
@@ -115,19 +66,11 @@ opam-switch: &opam-switch
root: *workspace
paths:
- coq/
- environment: &ci-template-vars
- <<: *envvars
- EXTRA_PACKAGES: *timing-packages
+ environment: *envvars
# Defines individual jobs, see the workflows section below for job orchestration
jobs:
- opam-boot:
- <<: *opam-boot-template
- environment:
- <<: *envvars
- EXTRA_OPAM: "ocamlgraph elpi"
-
# Build and prepare test environment
build: *build-template
@@ -136,24 +79,18 @@ jobs:
color:
<<: *ci-template
- environment:
- <<: *ci-template-vars
- EXTRA_PACKAGES: *timing-packages
compcert:
<<: *ci-template
coq-dpdgraph:
<<: *ci-template
- environment:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "time python autoconf automake"
coquelicot:
<<: *ci-template
- environment:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "time python autoconf automake"
+
+ cross-crypto:
+ <<: *ci-template
elpi:
<<: *ci-template
@@ -172,15 +109,9 @@ jobs:
fiat-parsers:
<<: *ci-template
- environment:
- <<: *ci-template-vars
- EXTRA_PACKAGES: *timing-packages
flocq:
<<: *ci-template
- environment:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "time python autoconf automake"
math-classes:
<<: *ci-template
@@ -193,9 +124,6 @@ jobs:
hott:
<<: *ci-template
- environment:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "time python autoconf automake"
iris-lambda-rust:
<<: *ci-template
@@ -214,9 +142,6 @@ jobs:
sf:
<<: *ci-template
- environment:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "time python wget"
unimath:
<<: *ci-template
@@ -226,14 +151,11 @@ jobs:
workflows:
version: 2
+
# Run on each push
main:
jobs:
- - opam-boot
-
- - build:
- requires:
- - opam-boot
+ - build
- bignums: &req-main
requires:
@@ -242,21 +164,22 @@ workflows:
requires:
- build
- bignums
- - compcert: *req-main
- - coq-dpdgraph: *req-main
- - coquelicot: *req-main
- - elpi: *req-main
- - equations: *req-main
- - geocoq: *req-main
- - fcsl-pcm: *req-main
- - fiat-crypto: *req-main
- - fiat-parsers: *req-main
- - flocq: *req-main
+ # - compcert: *req-main
+ # - coq-dpdgraph: *req-main
+ # - coquelicot: *req-main
+ # - cross-crypto: *req-main
+ # - elpi: *req-main
+ # - equations: *req-main
+ # - geocoq: *req-main
+ # - fcsl-pcm: *req-main
+ # - fiat-crypto: *req-main
+ # - fiat-parsers: *req-main
+ # - flocq: *req-main
- math-classes:
requires:
- build
- bignums
- - mtac2: *req-main
+ # - mtac2: *req-main
- corn:
requires:
- build
@@ -265,11 +188,11 @@ workflows:
requires:
- build
- corn
- - hott: *req-main
- - iris-lambda-rust: *req-main
- - ltac2: *req-main
- - math-comp: *req-main
- - pidetop: *req-main
- - sf: *req-main
- - unimath: *req-main
- - vst: *req-main
+ # - hott: *req-main
+ # - iris-lambda-rust: *req-main
+ # - ltac2: *req-main
+ # - math-comp: *req-main
+ # - pidetop: *req-main
+ # - sf: *req-main
+ # - unimath: *req-main
+ # - vst: *req-main
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 74bbda553..2ca827492 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -8,9 +8,13 @@
########## CI infrastructure ##########
-/dev/ci/*.sh @ejgallego
+/dev/ci/ @ejgallego
# Secondary maintainer @SkySkimmer
+/dev/ci/user-overlays/*.sh @ghost
+# Trick to avoid getting review requests
+# each time someone adds an overlay
+
/.circleci/ @SkySkimmer
# Secondary maintainer @ejgallego
@@ -20,7 +24,9 @@
/.gitlab-ci.yml @SkySkimmer
# Secondary maintainer @ejgallego
-/appveyor.yml @maximedenes
+/appveyor.yml @maximedenes
+/dev/ci/appveyor.* @maximedenes
+/dev/ci/*.bat @maximedenes
# Secondary maintainer @SkySkimmer
/default.nix @Zimmi48
@@ -71,6 +77,11 @@
/engine/ @ppedrot
# Secondary maintainer @aspiwack
+/engine/universes.* @SkySkimmer
+/engine/univops.* @SkySkimmer
+/engine/uState.* @SkySkimmer
+# Secondary maintainer @mattam82
+
########## Grammar macros ##########
/grammar/ @ppedrot
@@ -94,6 +105,11 @@
/kernel/byterun/ @maximedenes
# Secondary maintainer @silene
+/kernel/sorts.* @SkySkimmer
+/kernel/uGraph.* @SkySkimmer
+/kernel/univ.* @SkySkimmer
+# Secondary maintainer @mattam82
+
########## Library ##########
/library/ @silene
@@ -291,7 +307,7 @@
########## Build system ##########
/Makefile* @letouzey
-# Secondary maintainer @maximdenes
+# Secondary maintainer @gares
/configure* @letouzey
# Secondary maintainer @ejgallego
@@ -328,3 +344,6 @@
/dev/tools/pre-commit @SkySkimmer
/dev/tools/sudo-apt-get-update @JasonGross
+
+/dev/tools/check-owners*.sh @SkySkimmer
+# Secondary maintainer @maximedenes
diff --git a/.gitignore b/.gitignore
index e2a97b3a1..f1960ba68 100644
--- a/.gitignore
+++ b/.gitignore
@@ -88,6 +88,8 @@ test-suite/coqdoc/Coqdoc.*
test-suite/coqdoc/index.html
test-suite/coqdoc/coqdoc.css
test-suite/output/MExtraction.out
+test-suite/oUnit-anon.cache
+test-suite/unit-tests/**/*.test
# documentation
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d16dc5b78..4784f0db0 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,76 +1,53 @@
-image: ubuntu:bionic
+image: "$IMAGE"
stages:
- - opam-boot
+ - docker
- build
- test
# some default values
variables:
- # Format: $IMAGE-V$DATE-$HOUR-$MINUTE
- CACHEKEY: bionic-V2018-04-29-00-50
- DEBIAN_FRONTEND: "noninteractive"
- NJOBS: "2"
- COMPILER: "4.02.3"
- CAMLP5_VER: "6.14"
- OPAMROOT: "$CI_PROJECT_DIR/.opamcache"
- OPAMROOTISOK: "true"
-
- # some useful values
- COMPILER_32BIT: "4.02.3+32bit"
-
- COMPILER_BLEEDING_EDGE: "4.06.1"
- CAMLP5_VER_BLEEDING_EDGE: "7.05"
-
- TIMING_PACKAGES: "time python3"
-
- COQIDE_PACKAGES: "libgtk2.0-dev libgtksourceview2.0-dev"
- #COQIDE_PACKAGES_32BIT: "libgtk2.0-dev:i386 libgtksourceview2.0-dev:i386"
- COQIDE_OPAM: "lablgtk.2.18.5 conf-gtksourceview.2"
- COQIDE_OPAM_BE: "lablgtk.2.18.6 conf-gtksourceview.2"
- COQDOC_PACKAGES: "texlive-latex-extra texlive-fonts-recommended hevea python3-sphinx python3-pexpect python3-sphinx-rtd-theme python3-bs4 python3-sphinxcontrib.bibtex python3-pip"
- SPHINX_PACKAGES: "antlr4-python3-runtime"
- ELPI_OPAM: "elpi"
+ # Format: $IMAGE-V$DATE [Cache is not used as of today but kept here
+ # for reference]
+ CACHEKEY: "bionic_coq-V2018-05-07-V2"
+ 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: ""
+
+docker-boot:
+ stage: docker
+ image: docker:stable
+ services:
+ - docker:dind
+ before_script: []
+ script:
+ - docker login -u gitlab-ci-token -p "$CI_JOB_TOKEN" "$CI_REGISTRY"
+ - cd dev/ci/docker/bionic_coq/
+ - if docker pull "$IMAGE"; then echo "Image prebuilt!"; exit 0; fi
+ - docker build -t "$IMAGE" .
+ - docker push "$IMAGE"
+ except:
+ variables:
+ - $SKIP_DOCKER == "true"
before_script:
- cat /proc/{cpu,mem}info || true
- ls -a # figure out if artifacts are around
- - printenv
-# - if [ "$COMPILER" = "$COMPILER_32BIT" ]; then sudo dpkg --add-architecture i386; fi
- - apt-get update -qq && apt-get install -y -qq m4 opam ${EXTRA_PACKAGES}
- # This should be replaced by standard debian packages once python3-antlr4 makes to the archive.
- - if [ -n "${PIP_PACKAGES}" ]; then pip3 install ${PIP_PACKAGES}; fi
- # if no cache running opam config fails!
- - if [ -d .opamcache ]; then eval $(opam config env); fi
-
-################ OPAM SYSTEM ######################
-# - use cache between pipelines
-# - use artifacts between jobs
-# (in https://gitlab.com/SkySkimmer/coq/-/jobs/63255417
-# the cache wasn't available at the build step)
-# every non opam-boot job must set dependencies (for ci it's in the template)
-# otherwise all opam-boot artifacts are used together and we get some random switch
-
-# set cache key when using
-.opam-boot-template: &opam-boot-template
- stage: opam-boot
- artifacts:
- name: "opam-$COMPILER"
- paths:
- - .opamcache
- expire_in: 1 week
- script:
- - opam init -a -y -j $NJOBS --compiler=${COMPILER} default https://opam.ocaml.org
- - eval $(opam config env)
- - opam update
- - opam config list
- - opam list
- - opam install -j ${NJOBS} -y camlp5.${CAMLP5_VER} ocamlfind num ${EXTRA_OPAM}
- - rm -rf ~/.opam/log/
- - opam list
-
-# TODO figure out how to build doc for installed coq
-# set dependencies when using
+ - printenv -0 | sort -z | tr '\0' '\n'
+ - declare -A switch_table
+ - switch_table=( ["base"]="$COMPILER" ["edge"]="$COMPILER_BE" )
+ - opam switch -y "${switch_table[$OPAM_SWITCH]}$OPAM_VARIANT"
+ - eval $(opam config env)
+ - opam list
+ - opam config list
+
+################ GITLAB CACHING ######################
+# - use artifacts between jobs #
+######################################################
+
+# TODO figure out how to build doc for installed Coq
.build-template: &build-template
stage: build
artifacts:
@@ -80,21 +57,16 @@ before_script:
- config/Makefile
- test-suite/misc/universes/all_stdlib.v
expire_in: 1 week
- dependencies:
- - not-a-real-job
script:
- set -e
- - printenv
- - opam config list
- - opam list
- echo 'start:coq.config'
- - ./configure -prefix "$(pwd)/_install_ci" ${EXTRA_CONF}
+ - ./configure -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" byte
+ - make -j "$NJOBS"
- make test-suite/misc/universes/all_stdlib.v
- echo 'end:coq:build'
@@ -106,28 +78,28 @@ before_script:
- set +e
-# set dependencies when using
.warnings-template: &warnings-template
# keep warnings in test stage so we can test things even when warnings occur
stage: test
- dependencies:
- - not-a-real-job
script:
- set -e
- echo 'start:coq.config'
- - ./configure -local ${EXTRA_CONF}
+ - ./configure -local ${COQ_EXTRA_CONF}
- echo 'end:coq.config'
- echo 'start:coq.build'
- - make -j ${NJOBS} coqocaml
+ - make -j "$NJOBS" coqocaml
- echo 'end:coq:build'
- set +e
variables: &warnings-variables
- EXTRA_CONF: "-native-compiler yes -coqide byte -byte-only"
- EXTRA_PACKAGES: "$COQIDE_PACKAGES"
- EXTRA_OPAM: "$COQIDE_OPAM"
+ COQ_EXTRA_CONF: "-native-compiler yes -coqide byte -byte-only -warn-error yes"
+
+# every non build job must set dependencies otherwise all build
+# artifacts are used together and we may get some random Coq. To that
+# purpose, we add a spurious dependency `not-a-real-job` that must be
+# overridden otherwise the CI will fail.
# set dependencies when using
.test-suite-template: &test-suite-template
@@ -140,7 +112,7 @@ before_script:
# careful with the ending /
- BIN=$(readlink -f ../_install_ci/bin)/
- LIB=$(readlink -f ../_install_ci/lib/coq)/
- - make -j ${NJOBS} BIN="$BIN" LIB="$LIB" all
+ - make -j "$NJOBS" BIN="$BIN" LIB="$LIB" all
artifacts:
name: "$CI_JOB_NAME.logs"
when: on_failure
@@ -163,202 +135,198 @@ before_script:
script:
- set -e
- echo 'start:coq.test'
- - make -f Makefile.ci -j ${NJOBS} ${TEST_TARGET}
+ - make -f Makefile.ci -j "$NJOBS" ${TEST_TARGET}
- echo 'end:coq.test'
- set +e
dependencies:
- - opam-boot
- - build
+ - build:base
variables: &ci-template-vars
TEST_TARGET: "$CI_JOB_NAME"
- EXTRA_PACKAGES: "$TIMING_PACKAGES"
-
-opam-boot:
- <<: *opam-boot-template
- cache:
- paths: &cache-paths
- - .opamcache
- key: "main-$CACHEKEY"
- variables:
- EXTRA_OPAM: "$COQIDE_OPAM ocamlgraph $ELPI_OPAM"
- EXTRA_PACKAGES: "$COQIDE_PACKAGES"
-
-opam-boot:32bit:
- <<: *opam-boot-template
- cache:
- paths: *cache-paths
- key: "32bit-$CACHEKEY"
- variables:
- COMPILER: "$COMPILER_32BIT"
- EXTRA_PACKAGES: "gcc-multilib"
-
-opam-boot:bleeding-edge:
- <<: *opam-boot-template
- cache:
- paths: *cache-paths
- key: "be-$CACHEKEY"
+
+.ci-template-flambda: &ci-template-flambda
+ <<: *ci-template
+ dependencies:
+ - build:edge+flambda
variables:
- COMPILER: "$COMPILER_BLEEDING_EDGE"
- CAMLP5_VER: "$CAMLP5_VER_BLEEDING_EDGE"
- EXTRA_PACKAGES: "$COQIDE_PACKAGES"
- EXTRA_OPAM: "$COQIDE_OPAM_BE"
+ <<: *ci-template-vars
+ OPAM_SWITCH: "edge"
+ OPAM_VARIANT: "+flambda"
+
+.windows-template: &windows-template
+ stage: test
+ artifacts:
+ name: "%CI_JOB_NAME%"
+ paths:
+ - dev\nsis\*.exe
+ - coq-opensource-archive-windows-*.zip
+ expire_in: 1 week
+ dependencies: []
+ tags:
+ - windows
+ before_script: []
+ script:
+ - call dev/ci/gitlab.bat
+ only:
+ variables:
+ - $WINDOWS == "enabled"
-build:
+build:base:
<<: *build-template
- dependencies:
- - opam-boot
variables:
- EXTRA_CONF: "-native-compiler yes -coqide opt -with-doc yes"
- EXTRA_PACKAGES: "$COQIDE_PACKAGES $COQDOC_PACKAGES"
- PIP_PACKAGES: "$SPHINX_PACKAGES"
+ COQ_EXTRA_CONF: "-native-compiler yes -coqide opt -with-doc yes"
# no coqide for 32bit: libgtk installation problems
-build:32bit:
+build:base+32bit:
<<: *build-template
- dependencies:
- - opam-boot:32bit
variables:
- EXTRA_CONF: "-native-compiler yes"
- EXTRA_PACKAGES: "gcc-multilib"
+ OPAM_VARIANT: "+32bit"
+ COQ_EXTRA_CONF: "-native-compiler yes"
-build:bleeding-edge:
+build:edge:
<<: *build-template
- dependencies:
- - opam-boot:bleeding-edge
variables:
- EXTRA_CONF: "-native-compiler yes -coqide opt"
- EXTRA_PACKAGES: "$COQIDE_PACKAGES"
+ OPAM_SWITCH: edge
+ COQ_EXTRA_CONF: "-native-compiler yes -coqide opt"
-warnings:
+build:edge+flambda:
+ <<: *build-template
+ variables:
+ OPAM_SWITCH: edge
+ OPAM_VARIANT: "+flambda"
+ COQ_EXTRA_CONF: "-native-compiler no -coqide opt -flambda-opts "
+ COQ_EXTRA_CONF_QUOTE: "-O3 -unbox-closures"
+
+windows64:
+ <<: *windows-template
+ variables:
+ ARCH: "64"
+
+windows32:
+ <<: *windows-template
+ variables:
+ ARCH: "32"
+
+warnings:base:
<<: *warnings-template
- dependencies:
- - opam-boot
# warnings:32bit:
# <<: *warnings-template
# variables:
# <<: *warnings-variables
-# EXTRA_PACKAGES: "$gcc-multilib COQIDE_PACKAGES_32BIT"
-# dependencies:
-# - opam-boot:32bit
-warnings:bleeding-edge:
+warnings:edge:
<<: *warnings-template
+ variables:
+ <<: *warnings-variables
+ OPAM_SWITCH: edge
+
+test-suite:base:
+ <<: *test-suite-template
dependencies:
- - opam-boot:bleeding-edge
+ - build:base
-test-suite:
+test-suite:base+32bit:
<<: *test-suite-template
dependencies:
- - opam-boot
- - build
+ - build:base+32bit
variables:
- EXTRA_PACKAGES: "$TIMING_PACKAGES"
+ OPAM_VARIANT: "+32bit"
-test-suite:32bit:
+test-suite:edge:
<<: *test-suite-template
dependencies:
- - opam-boot:32bit
- - build:32bit
+ - build:edge
variables:
- EXTRA_PACKAGES: "gcc-multilib $TIMING_PACKAGES"
+ OPAM_SWITCH: edge
-test-suite:bleeding-edge:
+test-suite:edge+flambda:
<<: *test-suite-template
dependencies:
- - opam-boot:bleeding-edge
- - build:bleeding-edge
+ - build:edge+flambda
variables:
- EXTRA_PACKAGES: "$TIMING_PACKAGES"
+ OPAM_SWITCH: edge
+ OPAM_VARIANT: "+flambda"
-validate:
+validate:base:
<<: *validate-template
dependencies:
- - opam-boot
- - build
+ - build:base
-validate:32bit:
+validate:base+32bit:
<<: *validate-template
dependencies:
- - opam-boot:32bit
- - build:32bit
+ - build:base+32bit
variables:
- EXTRA_PACKAGES: "gcc-multilib"
+ OPAM_VARIANT: "+32bit"
+
+validate:edge:
+ <<: *validate-template
+ dependencies:
+ - build:edge
+ variables:
+ OPAM_SWITCH: edge
+
+validate:edge+flambda:
+ <<: *validate-template
+ dependencies:
+ - build:edge+flambda
+ variables:
+ OPAM_SWITCH: edge
+ OPAM_VARIANT: "+flambda"
ci-bignums:
<<: *ci-template
ci-color:
- <<: *ci-template
- variables:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "$TIMING_PACKAGES"
+ <<: *ci-template-flambda
ci-compcert:
- <<: *ci-template
+ <<: *ci-template-flambda
ci-coq-dpdgraph:
<<: *ci-template
- variables:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "$TIMING_PACKAGES autoconf"
ci-coquelicot:
<<: *ci-template
- variables:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "$TIMING_PACKAGES autoconf"
-ci-elpi:
+ci-cross-crypto:
<<: *ci-template
-ci-equations:
+ci-elpi:
<<: *ci-template
-ci-geocoq:
+ci-equations:
<<: *ci-template
- allow_failure: true
ci-fcsl-pcm:
<<: *ci-template
-# ci-fiat-crypto:
-# <<: *ci-template
-# # out of memory error
-# allow_failure: true
+ci-fiat-crypto:
+ <<: *ci-template-flambda
ci-fiat-parsers:
<<: *ci-template
- variables:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "$TIMING_PACKAGES"
ci-flocq:
<<: *ci-template
- variables:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "$TIMING_PACKAGES autoconf"
ci-formal-topology:
- <<: *ci-template
+ <<: *ci-template-flambda
+
+ci-geocoq:
+ <<: *ci-template-flambda
ci-hott:
<<: *ci-template
- variables:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "$TIMING_PACKAGES autoconf"
ci-iris-lambda-rust:
- <<: *ci-template
+ <<: *ci-template-flambda
ci-ltac2:
<<: *ci-template
-ci-math-classes:
- <<: *ci-template
-
ci-math-comp:
- <<: *ci-template
+ <<: *ci-template-flambda
ci-mtac2:
<<: *ci-template
@@ -368,12 +336,9 @@ ci-pidetop:
ci-sf:
<<: *ci-template
- variables:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "$TIMING_PACKAGES wget"
ci-unimath:
- <<: *ci-template
+ <<: *ci-template-flambda
ci-vst:
- <<: *ci-template
+ <<: *ci-template-flambda
diff --git a/.merlin b/.merlin
index 40db60950..404a7e793 100644
--- a/.merlin
+++ b/.merlin
@@ -32,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/.travis.yml b/.travis.yml
index fce19f9d9..8218467d2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -39,35 +39,41 @@ env:
- NJOBS=2
# system is == 4.02.3
- COMPILER="system"
- - COMPILER_BE="4.06.0"
+ - COMPILER_BE="4.06.1"
- CAMLP5_VER=".6.14"
- - CAMLP5_VER_BE=".7.03"
+ - CAMLP5_VER_BE=".7.05"
- FINDLIB_VER=".1.4.1"
- - FINDLIB_VER_BE=".1.7.3"
+ - FINDLIB_VER_BE=".1.8.0"
- LABLGTK="lablgtk.2.18.3 lablgtk-extras.1.6"
- LABLGTK_BE="lablgtk.2.18.6 lablgtk-extras.1.6"
- NATIVE_COMP="yes"
- COQ_DEST="-local"
- MAIN_TARGET="world"
- # Main test suites
- matrix:
- - TEST_TARGET="test-suite" COMPILER="4.02.3+32bit"
- - TEST_TARGET="validate" TW="travis_wait"
- - TEST_TARGET="validate" COMPILER="4.02.3+32bit" TW="travis_wait"
- - TEST_TARGET="validate" COMPILER="${COMPILER_BE}+flambda" CAMLP5_VER="${CAMLP5_VER_BE}" NATIVE_COMP="no" EXTRA_CONF="-flambda-opts -O3" FINDLIB_VER="${FINDLIB_VER_BE}"
matrix:
include:
- if: NOT (type = pull_request)
env:
+ - TEST_TARGET="test-suite" COMPILER="4.02.3+32bit" EXTRA_OPAM="ounit"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="validate" TW="travis_wait"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="validate" COMPILER="4.02.3+32bit" TW="travis_wait"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="validate" COMPILER="${COMPILER_BE}+flambda" CAMLP5_VER="${CAMLP5_VER_BE}" NATIVE_COMP="no" EXTRA_CONF="-flambda-opts -O3" FINDLIB_VER="${FINDLIB_VER_BE}"
+ - if: NOT (type = pull_request)
+ env:
- TEST_TARGET="ci-bignums"
- if: NOT (type = pull_request)
env:
- TEST_TARGET="ci-color"
- if: NOT (type = pull_request)
env:
- - TEST_TARGET="ci-compcert"
+ - TEST_TARGET="ci-compcert" EXTRA_OPAM="menhir"
- if: NOT (type = pull_request)
env:
- TEST_TARGET="ci-coq-dpdgraph" EXTRA_OPAM="ocamlgraph"
@@ -76,6 +82,9 @@ matrix:
- TEST_TARGET="ci-coquelicot"
- if: NOT (type = pull_request)
env:
+ - TEST_TARGET="ci-cross-crypto"
+ - if: NOT (type = pull_request)
+ env:
- TEST_TARGET="ci-elpi" EXTRA_OPAM="elpi"
# ppx_tools_versioned requires a specific version findlib
- FINDLIB_VER=""
@@ -84,39 +93,24 @@ matrix:
- TEST_TARGET="ci-equations"
- if: NOT (type = pull_request)
env:
- - TEST_TARGET="ci-geocoq"
- - if: NOT (type = pull_request)
- env:
- TEST_TARGET="ci-fcsl-pcm"
- if: NOT (type = pull_request)
env:
- - TEST_TARGET="ci-fiat-crypto"
- - if: NOT (type = pull_request)
- env:
- TEST_TARGET="ci-fiat-parsers"
- if: NOT (type = pull_request)
env:
- TEST_TARGET="ci-flocq"
- if: NOT (type = pull_request)
env:
- - TEST_TARGET="ci-formal-topology"
- - if: NOT (type = pull_request)
- env:
- TEST_TARGET="ci-hott"
- if: NOT (type = pull_request)
env:
- - TEST_TARGET="ci-iris-lambda-rust"
- - if: NOT (type = pull_request)
- env:
- TEST_TARGET="ci-ltac2"
- if: NOT (type = pull_request)
env:
- TEST_TARGET="ci-math-classes"
- if: NOT (type = pull_request)
env:
- - TEST_TARGET="ci-math-comp"
- - if: NOT (type = pull_request)
- env:
- TEST_TARGET="ci-mtac2"
- if: NOT (type = pull_request)
env:
@@ -124,12 +118,6 @@ matrix:
- if: NOT (type = pull_request)
env:
- TEST_TARGET="ci-sf"
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="ci-unimath"
- - if: NOT (type = pull_request)
- env:
- - TEST_TARGET="ci-vst"
- env:
- TEST_TARGET="lint"
@@ -143,10 +131,11 @@ matrix:
- dev/lint-repository.sh
# Full Coq test-suite with two compilers
- - env:
+ - if: NOT (type = pull_request)
+ env:
- TEST_TARGET="test-suite"
- EXTRA_CONF="-coqide opt -with-doc yes"
- - EXTRA_OPAM="hevea ${LABLGTK}"
+ - EXTRA_OPAM="${LABLGTK} ounit"
before_install: &sphinx-install
- sudo pip3 install bs4 sphinx sphinx_rtd_theme pexpect antlr4-python3-runtime sphinxcontrib-bibtex
addons:
@@ -171,13 +160,14 @@ matrix:
- python3-pip
- python3-setuptools
- - env:
+ - if: NOT (type = pull_request)
+ env:
- TEST_TARGET="test-suite"
- COMPILER="${COMPILER_BE}"
- FINDLIB_VER="${FINDLIB_VER_BE}"
- CAMLP5_VER="${CAMLP5_VER_BE}"
- EXTRA_CONF="-coqide opt -with-doc yes"
- - EXTRA_OPAM="hevea ${LABLGTK_BE}"
+ - EXTRA_OPAM="${LABLGTK_BE} ounit"
before_install: *sphinx-install
addons:
apt:
@@ -186,14 +176,15 @@ matrix:
packages: *extra-packages
# Full test-suite with flambda
- - env:
+ - if: NOT (type = pull_request)
+ env:
- TEST_TARGET="test-suite"
- COMPILER="${COMPILER_BE}+flambda"
- FINDLIB_VER="${FINDLIB_VER_BE}"
- CAMLP5_VER="${CAMLP5_VER_BE}"
- NATIVE_COMP="no"
- EXTRA_CONF="-coqide opt -with-doc yes -flambda-opts -O3"
- - EXTRA_OPAM="hevea ${LABLGTK_BE}"
+ - EXTRA_OPAM="${LABLGTK_BE} ounit"
before_install: *sphinx-install
addons:
apt:
@@ -202,10 +193,11 @@ matrix:
packages: *extra-packages
# Ocaml warnings with two compilers
- - env:
+ - if: NOT (type = pull_request)
+ env:
- MAIN_TARGET="coqocaml"
- EXTRA_CONF="-byte-only -coqide byte -warn-error yes"
- - EXTRA_OPAM="hevea ${LABLGTK}"
+ - EXTRA_OPAM="${LABLGTK}"
addons:
apt:
sources:
@@ -216,13 +208,14 @@ matrix:
- libgtk2.0-dev
- libgtksourceview2.0-dev
- - env:
+ - if: NOT (type = pull_request)
+ env:
- MAIN_TARGET="coqocaml"
- COMPILER="${COMPILER_BE}"
- FINDLIB_VER="${FINDLIB_VER_BE}"
- CAMLP5_VER="${CAMLP5_VER_BE}"
- EXTRA_CONF="-byte-only -coqide byte -warn-error yes"
- - EXTRA_OPAM="hevea ${LABLGTK_BE}"
+ - EXTRA_OPAM="${LABLGTK_BE}"
addons:
apt:
sources:
@@ -236,6 +229,7 @@ matrix:
- CAMLP5_VER=".6.17"
- NATIVE_COMP="no"
- COQ_DEST="-local"
+ - EXTRA_OPAM="ounit"
before_install:
- brew update
- brew unlink python
@@ -278,9 +272,10 @@ install:
- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then travis_retry ./dev/tools/sudo-apt-get-update.sh -q; fi
- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then sudo apt-get install -y opam aspcud gcc-multilib; fi
- opam init -j ${NJOBS} --compiler=${COMPILER} -n -y
+- opam switch "$COMPILER" && opam update
- eval $(opam config env)
- opam config list
-- opam install -j ${NJOBS} -y num camlp5${CAMLP5_VER} ocamlfind${FINDLIB_VER} ${EXTRA_OPAM}
+- opam install -j ${NJOBS} -y num ocamlfind${FINDLIB_VER} jbuilder camlp5${CAMLP5_VER} ${EXTRA_OPAM}
- opam list
script:
diff --git a/CHANGES b/CHANGES
index a270aef96..aea7ec2f6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -18,6 +18,15 @@ 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.
+
+Tactics
+
+- Introduction tactics "intro"/"intros" on a goal which is an
+ existential variable now force a refinement of the goal into a
+ dependent product rather than failing.
Tactic language
@@ -27,6 +36,26 @@ Tactic language
called by OCaml-defined tactics.
- Option "Ltac Debug" now applies also to terms built using Ltac functions.
+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.
+
+Changes from 8.8.0 to 8.8.1
+===========================
+
+Notations
+
+- Fixed unexpected collision between only-parsing and only-printing
+ notations (issue #7462).
+
Changes from 8.8+beta1 to 8.8.0
===============================
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1a3c99369..7fb976ee0 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -28,7 +28,13 @@ 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).
-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.
+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.
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.
diff --git a/INSTALL.doc b/INSTALL.doc
index f8a085280..13e6440d0 100644
--- a/INSTALL.doc
+++ b/INSTALL.doc
@@ -4,13 +4,13 @@
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.
+The reference manual is written is reStructuredText and compiled
+using Sphinx (see `doc/sphinx/README.rst`) to learn more.
+
+The documentation for the standard library is generated from
+the `.v` source files using coqdoc.
Prerequisite
------------
@@ -20,9 +20,7 @@ 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
@@ -35,7 +33,7 @@ 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
+ texlive-latex-extra texlive-fonts-recommended python3-sphinx
python3-pexpect python3-sphinx-rtd-theme python3-bs4
python3-sphinxcontrib.bibtex python3-pip
@@ -44,7 +42,7 @@ 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
+HTML documentation from Coq's `default.nix`. [Note Nix setup doesn't
include the LaTeX packages needed to build the full documentation.]
If you are in an older/different distribution you can install the
@@ -75,15 +73,6 @@ Alternatively, you can use some specific targets:
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
@@ -99,7 +88,4 @@ To install all produced documents, do:
make DOCDIR=/some/directory/for/documentation install-doc
-DOCDIR defauts to /usr/share/doc/coq
-
-
-
+DOCDIR defaults to /usr/share/doc/coq
diff --git a/Makefile b/Makefile
index 793afb661..38be3013d 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
@@ -214,12 +214,11 @@ cruftclean: ml4clean
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
@@ -245,7 +244,7 @@ archclean: clean-ide optclean voclean
rm -f $(ALLSTDLIB).*
optclean:
- rm -f $(COQTOPEXE) $(CHICKEN)
+ rm -f $(COQTOPEXE) $(CHICKEN) $(TOPBIN)
rm -f $(TOOLS) $(PRIVATEBINARIES) $(CSDPCERT)
find . -name '*.cmx' -o -name '*.cmx[as]' -o -name '*.[soa]' -o -name '*.so' | xargs rm -f
diff --git a/Makefile.build b/Makefile.build
index 7d0785a5b..1326027ca 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
@@ -386,29 +387,34 @@ grammar/%.cmi: grammar/%.mli
.PHONY: coqbinaries coqbyte
-coqbinaries: $(COQTOPEXE) $(CHICKEN) $(CSDPCERT) $(FAKEIDE)
+coqbinaries: $(TOPBIN) $(CHICKEN) $(CSDPCERT) $(FAKEIDE)
+coqbyte: $(TOPBYTE) $(CHICKENBYTE)
-coqbyte: $(COQTOPBYTE) $(CHICKENBYTE)
-
-COQTOP_OPT=toplevel/coqtop_opt_bin.ml
-COQTOP_BYTE=toplevel/coqtop_byte_bin.ml
+# Special rule for coqtop
+$(COQTOPEXE): $(TOPBIN:.opt=.$(BEST))
+ 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 \
+ $(HIDE)$(OCAMLOPT) -linkall -linkpkg $(MLINCLUDES) \
-I kernel/byterun/ -cclib -lcoqrun \
$(SYSMOD) -package camlp5.gramlib \
- $(LINKCMX) $(OPTFLAGS) $(LINKMETADATA) $(COQTOP_OPT) -o $@
+ $(LINKCMX) $(OPTFLAGS) $(LINKMETADATA) $< -o $@
$(STRIP) $@
$(CODESIGN) $@
-else
-$(COQTOPEXE): $(COQTOPBYTE)
- cp $< $@
-endif
+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) \
@@ -500,7 +506,7 @@ 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 $@'
@@ -544,16 +550,16 @@ $(COQWORKMGRBYTE): $(COQWORKMGRCMO)
$(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
-$(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 -package str -package dynlink)
$(FAKEIDEBYTE): $(FAKEIDECMO) | $(IDETOPLOOPCMA)
$(SHOW)'OCAMLC -o $@'
diff --git a/Makefile.checker b/Makefile.checker
index 172c64af3..0ec565d61 100644
--- a/Makefile.checker
+++ b/Makefile.checker
@@ -34,6 +34,20 @@ 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 $@'
@@ -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 78fec466c..ce725d19d 100644
--- a/Makefile.ci
+++ b/Makefile.ci
@@ -15,6 +15,7 @@ CI_TARGETS=ci-bignums \
ci-coquelicot \
ci-corn \
ci-cpdt \
+ ci-cross-crypto \
ci-elpi \
ci-equations \
ci-fcsl-pcm \
@@ -37,6 +38,12 @@ CI_TARGETS=ci-bignums \
.PHONY: ci-all $(CI_TARGETS)
+ci-help:
+ echo '*** Coq CI system, please specify a target to build.'
+ false
+
+ci-all: $(CI_TARGETS)
+
ci-color: ci-bignums
ci-math-classes: ci-bignums
@@ -49,8 +56,6 @@ ci-formal-topology: ci-corn
$(CI_TARGETS): ci-%:
+./dev/ci/ci-wrapper.sh $*
-ci-all: $(CI_TARGETS)
-
# For emacs:
# Local Variables:
# mode: makefile
diff --git a/Makefile.common b/Makefile.common
index e500ff9b4..5b1def40a 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -14,8 +14,11 @@
# Executables
###########################################################################
-COQTOPBYTE:=bin/coqtop.byte$(EXE)
+TOPBIN:=$(addsuffix .opt$(EXE), $(addprefix bin/, coqtop coqproofworker coqtacticworker coqqueryworker))
+TOPBYTE:=$(TOPBIN:.opt$(EXE)=.byte$(EXE))
+
COQTOPEXE:=bin/coqtop$(EXE)
+COQTOPBYTE:=bin/coqtop.byte$(EXE)
COQDEP:=bin/coqdep$(EXE)
COQDEPBYTE:=bin/coqdep.byte$(EXE)
@@ -117,16 +120,10 @@ BYTERUN:=$(addprefix kernel/byterun/, \
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
###########################################################################
@@ -175,40 +172,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)
-LIBFILES:=$(ALLVO) $(call vo_to_cm,$(ALLVO)) \
- $(call vo_to_obj,$(ALLVO)) \
- $(VFILES) $(GLOBFILES)
-
# For emacs:
# Local Variables:
# mode: makefile
diff --git a/Makefile.dev b/Makefile.dev
index 0461fe072..8f7d21694 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
diff --git a/Makefile.doc b/Makefile.doc
index 9b6013d8d..41ae11b86 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 INSTALL.doc to learn about the dependencies
# The main entry point :
@@ -28,20 +25,10 @@ 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
SPHINXOPTS= -j4
@@ -57,31 +44,29 @@ DOCCOMMON:=doc/common/version.tex doc/common/title.tex doc/common/macros.tex
### General rules
######################################################################
-.PHONY: doc sphinxdoc-html doc-pdf doc-ps tutorial
-.PHONY: stdlib full-stdlib rectutorial
+.PHONY: doc doc-html doc-pdf doc-ps
+.PHONY: stdlib full-stdlib
-doc: sphinx tutorial rectutorial stdlib
+doc: sphinx stdlib
+
+ifndef QUICK
+SPHINX_DEPS := coq
+endif
-sphinx: coq
+sphinx: $(SPHINX_DEPS)
$(SHOW)'SPHINXBUILD doc/sphinx'
$(HIDE)COQBIN="$(PWD)/bin" $(SPHINXBUILD) -W -b html $(ALLSPHINXOPTS) doc/sphinx $(SPHINXBUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(SPHINXBUILDDIR)/html."
doc-html:\
- doc/tutorial/Tutorial.v.html \
- doc/stdlib/html/index.html doc/RecTutorial/RecTutorial.html
+ doc/stdlib/html/index.html sphinx
doc-pdf:\
- doc/tutorial/Tutorial.v.pdf \
- doc/stdlib/Library.pdf doc/RecTutorial/RecTutorial.pdf
+ doc/stdlib/Library.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
@@ -89,32 +74,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
######################################################################
@@ -124,23 +91,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
######################################################################
@@ -214,53 +164,28 @@ 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)
$(INSTALLLIB) doc/LICENSE $(FULLDOCDIR)/LICENSE.doc
-install-doc-html:
+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
diff --git a/Makefile.ide b/Makefile.ide
index ac4ba75d4..37f698e0c 100644
--- a/Makefile.ide
+++ b/Makefile.ide
@@ -36,7 +36,7 @@ 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
@@ -45,7 +45,9 @@ COQIDEFLAGS=$(addprefix -I , $(IDESRCDIRS)) $(COQIDEINCLUDES)
IDEDEPS:=clib/clib.cma lib/lib.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,15 +90,15 @@ 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) $^
+ $(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) -o $@ \
+ -linkpkg -package str,unix,dynlink,threads,lablgtk2.sourceview2 $(IDEFLAGS:.cma=.cmxa) $^
$(STRIP) $@
else
$(COQIDE): $(COQIDEBYTE)
@@ -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,29 @@ 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 kernel/byterun/ -cclib -lcoqrun \
+ $(SYSMOD) -package camlp5.gramlib \
+ $(LINKCMX) $(IDETOPCMX) $(OPTFLAGS) $(LINKMETADATA) $< -o $@
+ $(STRIP) $@
+ $(CODESIGN) $@
+
+$(IDETOPBYTE): ide/idetop.ml $(LINKCMO) $(LIBCOQRUN) $(IDETOPCMA)
+ $(SHOW)'COQMKTOP -o $@'
+ $(HIDE)$(OCAMLC) -linkall -linkpkg $(MLINCLUDES) -I ide \
+ -I kernel/byterun/ -cclib -lcoqrun $(VMBYTEFLAGS) \
+ $(SYSMOD) -package camlp5.gramlib \
+ $(LINKCMO) $(IDETOPCMA) $(BYTEFLAGS) $< -o $@
+
####################
## Install targets
####################
@@ -164,13 +189,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,8 +229,7 @@ $(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) $^
+ -linkpkg -package str,unix,dynlink,threads,lablgtk2.sourceview2 $(IDEFLAGS:.cma=.cmxa) $^
$(STRIP) $@
$(COQIDEAPP)/Contents/Resources/share: $(COQIDEAPP)/Contents
diff --git a/Makefile.install b/Makefile.install
index 02695287b..0764b61fc 100644
--- a/Makefile.install
+++ b/Makefile.install
@@ -70,17 +70,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) $(TOPBIN) $(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)
diff --git a/Makefile.vofiles b/Makefile.vofiles
new file mode 100644
index 000000000..fc902c4a8
--- /dev/null
+++ b/Makefile.vofiles
@@ -0,0 +1,40 @@
+
+# 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)
+LIBFILES:=$(ALLVO) $(call vo_to_cm,$(ALLVO)) \
+ $(call vo_to_obj,$(ALLVO)) \
+ $(VFILES) $(GLOBFILES)
+
+# For emacs:
+# Local Variables:
+# mode: makefile
+# End:
diff --git a/README.md b/README.md
index 883630acf..4956da36d 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)
[![Circle CI](https://circleci.com/gh/coq/coq/tree/master.svg?style=shield)](https://circleci.com/gh/coq/workflows/coq/tree/master)
diff --git a/appveyor.yml b/appveyor.yml
index 44a93d15d..cd3b88d00 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -10,10 +10,6 @@ image:
environment:
CYGMIRROR: http://ftp.inf.tu-dresden.de/software/windows/cygwin32
matrix:
- - USEOPAM: false
- ARCH: 32
- - USEOPAM: false
- ARCH: 64
- USEOPAM: true
ARCH: 64
@@ -21,11 +17,3 @@ build_script:
- cmd: 'call %APPVEYOR_BUILD_FOLDER%\dev\ci\appveyor.bat'
test: off
-
-artifacts:
- - path: 'dev\nsis\*.exe'
- name: installer
-
- - path: 'coq-opensource-archive-*.zip'
- name: opensource-archive
-
diff --git a/checker/univ.ml b/checker/univ.ml
index fc0764077..7d285b6fe 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
diff --git a/checker/univ.mli b/checker/univ.mli
index 935f0a2b8..6cd3b3638 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
@@ -140,7 +141,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} *)
@@ -216,6 +224,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/configure.ml b/configure.ml
index e77310eb7..45c3bb67a 100644
--- a/configure.ml
+++ b/configure.ml
@@ -16,8 +16,9 @@ let coq_macos_version = "8.7.90" (** "[...] should be a string comprised of
three non-negative, period-separated integers [...]" *)
let vo_magic = 8791
let state_magic = 58791
-let distributed_exec = ["coqtop";"coqc";"coqchk";"coqdoc";"coqworkmgr";
-"coqdoc";"coq_makefile";"coq-tex";"gallina";"coqwc";"csdpcert";"coqdep"]
+let distributed_exec =
+ ["coqtop.opt"; "coqidetop.opt"; "coqqueryworker.opt"; "coqproofworker.opt"; "coqtacticworker.opt";
+ "coqc";"coqchk";"coqdoc";"coqworkmgr";"coq_makefile";"coq-tex";"gallina";"coqwc";"csdpcert";"coqdep"]
let verbose = ref false (* for debugging this script *)
@@ -1247,17 +1248,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 =
diff --git a/default.nix b/default.nix
index 0b4794274..effee720d 100644
--- a/default.nix
+++ b/default.nix
@@ -90,9 +90,9 @@ stdenv.mkDerivation rec {
prefixKey = "-prefix ";
- buildFlags = optionals buildDoc [ "world" "sphinx" ];
+ buildFlags = [ "world" ] ++ optional buildDoc "doc-html";
- installTargets = [ "install" ] ++ optional buildDoc "install-doc-sphinx";
+ installTargets = [ "install" ] ++ optional buildDoc "install-doc-html";
inherit doCheck;
diff --git a/dev/base_include b/dev/base_include
index 2f7183dd6..2f5d8aa84 100644
--- a/dev/base_include
+++ b/dev/base_include
@@ -231,7 +231,7 @@ 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));;
-let go () = Coqloop.loop ~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/windows/makecoq_mingw.sh b/dev/build/windows/makecoq_mingw.sh
index 18f1a2f16..ecc45735f 100644
--- a/dev/build/windows/makecoq_mingw.sh
+++ b/dev/build/windows/makecoq_mingw.sh
@@ -144,24 +144,24 @@ LOGTARGET=other
# Log command output - take log target name from command name (like log1 make => log target is "<module>-make")
log1() {
- "$@" > "$LOGS/$LOGTARGET-$1.log" 2> "$LOGS/$LOGTARGET-$1.err"
+ "$@" > >(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)
}
# Log command output - take log target name from command name and first argument (like log2 make install => log target is "<module>-make-install")
log2() {
- "$@" > "$LOGS/$LOGTARGET-$1-$2.log" 2> "$LOGS/$LOGTARGET-$1-$2.err"
+ "$@" > >(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)
}
# 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() {
- "$@" > "$LOGS/$LOGTARGET-$1-$3.log" 2> "$LOGS/$LOGTARGET-$1-$3.err"
+ "$@" > >(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)
}
# Log command output - log target name is first argument (like logn untar tar xvaf ... => log target is "<module>-untar")
logn() {
LOGTARGETEX=$1
shift
- "$@" > "$LOGS/$LOGTARGET-$LOGTARGETEX.log" 2> "$LOGS/$LOGTARGET-$LOGTARGETEX.err"
+ "$@" > >(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)
}
###################### 'UNFIX' SED #####################
@@ -847,7 +847,7 @@ function make_ocaml {
function make_ocaml_tools {
make_findlib
- make_menhir
+ # make_menhir
make_camlp5
}
@@ -856,7 +856,7 @@ function make_ocaml_tools {
function make_ocaml_libs {
make_findlib
make_lablgtk
- make_stdint
+ # make_stdint
}
##### FINDLIB Ocaml library manager #####
@@ -954,11 +954,26 @@ function make_lablgtk {
# lablgtk shows occasional errors with -j, so don't pass $MAKE_OPT
- # See https://sympa.inria.fr/sympa/arc/caml-list/2015-10/msg00204.html for the make || true + strip
- logn make-world-pre make world || true
- "$TARGET_ARCH-strip.exe" --strip-unneeded src/dlllablgtk2.dll
+ # lablgtk binary needs to be stripped - otherwise flexdll goes wild
+ # Fix version 1: explicit strip after failed build - this randomly fails in CI
+ # See https://sympa.inria.fr/sympa/arc/caml-list/2015-10/msg00204.html
+ # logn make-world-pre make world || true
+ # $TARGET_ARCH-strip.exe --strip-unneeded src/dlllablgtk2.dll
+
+ # Fix version 2: Strip by passing linker argument rather than explicit call to strip
+ # See https://github.com/alainfrisch/flexdll/issues/6
+ # Argument to ocamlmklib: -ldopt "-link -Wl,-s"
+ # -ldopt is the okamlmklib linker prefix option
+ # -link is the flexlink linker prefix option
+ # -Wl, is the gcc (linker driver) linker prefix option
+ # -s is the gnu linker option for stripping symbols
+ # These changes are included in dev/build/windows/patches_coq/lablgtk-2.18.3.patch
log2 make world
+
+ # lablgtk does not escape FINDLIBDIR path, which can contain backslashes
+ sed -i "s|^FINDLIBDIR=.*|FINDLIBDIR=$PREFIXOCAML/libocaml/site-lib|" config.make
+
log2 make install
log2 make clean
build_post
diff --git a/dev/build/windows/patches_coq/lablgtk-2.18.3.patch b/dev/build/windows/patches_coq/lablgtk-2.18.3.patch
index 0691c1fc8..23c303135 100644
--- a/dev/build/windows/patches_coq/lablgtk-2.18.3.patch
+++ b/dev/build/windows/patches_coq/lablgtk-2.18.3.patch
@@ -1,6 +1,12 @@
-diff -u -r lablgtk-2.18.3/configure lablgtk-2.18.3.patched/configure
---- lablgtk-2.18.3/configure 2014-10-29 08:51:05.000000000 +0100
-+++ lablgtk-2.18.3.patched/configure 2015-10-29 08:58:08.543985500 +0100
+diff/patch file created on Wed, Apr 25, 2018 11:08:05 AM with:
+difftar-folder.sh ../coq-msoegtrop/dev/build/windows/source_cache/lablgtk-2.18.3.tar.gz lablgtk-2.18.3 1
+TARFILE= ../coq-msoegtrop/dev/build/windows/source_cache/lablgtk-2.18.3.tar.gz
+FOLDER= lablgtk-2.18.3
+TARSTRIP= 1
+TARPREFIX= lablgtk-2.18.3/
+ORIGFOLDER= lablgtk-2.18.3.orig
+--- lablgtk-2.18.3.orig/configure 2014-10-29 08:51:05.000000000 +0100
++++ lablgtk-2.18.3/configure 2018-04-25 10:58:54.454501600 +0200
@@ -2667,7 +2667,7 @@
fi
@@ -10,10 +16,8 @@ diff -u -r lablgtk-2.18.3/configure lablgtk-2.18.3.patched/configure
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring ocamlfind" >&5
$as_echo "$as_me: WARNING: Ignoring ocamlfind" >&2;}
OCAMLFIND=no
-
-diff -u -r lablgtk-2.18.3/src/glib.mli lablgtk-2.18.3.patched/src/glib.mli
---- lablgtk-2.18.3/src/glib.mli 2014-10-29 08:51:06.000000000 +0100
-+++ lablgtk-2.18.3.patched/src/glib.mli 2016-01-25 09:50:59.884715200 +0100
+--- lablgtk-2.18.3.orig/src/glib.mli 2014-10-29 08:51:06.000000000 +0100
++++ lablgtk-2.18.3/src/glib.mli 2018-04-25 10:58:54.493555500 +0200
@@ -75,6 +75,7 @@
type condition = [ `ERR | `HUP | `IN | `NVAL | `OUT | `PRI]
type id
@@ -22,10 +26,8 @@ diff -u -r lablgtk-2.18.3/src/glib.mli lablgtk-2.18.3.patched/src/glib.mli
val add_watch :
cond:condition list -> callback:(condition list -> bool) -> ?prio:int -> channel -> id
val remove : id -> unit
-
-diff -u -r lablgtk-2.18.3/src/glib.ml lablgtk-2.18.3.patched/src/glib.ml
---- lablgtk-2.18.3/src/glib.ml 2014-10-29 08:51:06.000000000 +0100
-+++ lablgtk-2.18.3.patched/src/glib.ml 2016-01-25 09:50:59.891715900 +0100
+--- lablgtk-2.18.3.orig/src/glib.ml 2014-10-29 08:51:06.000000000 +0100
++++ lablgtk-2.18.3/src/glib.ml 2018-04-25 10:58:54.479543500 +0200
@@ -72,6 +72,8 @@
type id
external channel_of_descr : Unix.file_descr -> channel
@@ -35,10 +37,22 @@ diff -u -r lablgtk-2.18.3/src/glib.ml lablgtk-2.18.3.patched/src/glib.ml
external remove : id -> unit = "ml_g_source_remove"
external add_watch :
cond:condition list -> callback:(condition list -> bool) -> ?prio:int -> channel -> id
-
-diff -u -r lablgtk-2.18.3/src/ml_glib.c lablgtk-2.18.3.patched/src/ml_glib.c
---- lablgtk-2.18.3/src/ml_glib.c 2014-10-29 08:51:06.000000000 +0100
-+++ lablgtk-2.18.3.patched/src/ml_glib.c 2016-01-25 09:50:59.898716600 +0100
+--- lablgtk-2.18.3.orig/src/Makefile 2014-10-29 08:51:06.000000000 +0100
++++ lablgtk-2.18.3/src/Makefile 2018-04-25 10:58:54.506522500 +0200
+@@ -461,9 +461,9 @@
+ do rm -f "$(BINDIR)"/$$f; done
+
+ lablgtk.cma liblablgtk2$(XA): $(COBJS) $(MLOBJS)
+- $(LIBRARIAN) -o lablgtk -oc lablgtk2 $^ $(GTKLIBS)
++ $(LIBRARIAN) -ldopt "-link -Wl,-s" -o lablgtk -oc lablgtk2 $^ $(GTKLIBS)
+ lablgtk.cmxa: $(COBJS) $(MLOBJS:.cmo=.cmx)
+- $(LIBRARIAN) -o lablgtk -oc lablgtk2 $^ $(GTKLIBS)
++ $(LIBRARIAN) -ldopt "-link -Wl,-s" -o lablgtk -oc lablgtk2 $^ $(GTKLIBS)
+ lablgtk.cmxs: DYNLINKLIBS=$(GTK_LIBS)
+
+ lablgtkgl.cma liblablgtkgl2$(XA): $(GLCOBJS) $(GLMLOBJS)
+--- lablgtk-2.18.3.orig/src/ml_glib.c 2014-10-29 08:51:06.000000000 +0100
++++ lablgtk-2.18.3/src/ml_glib.c 2018-04-25 10:58:54.539535600 +0200
@@ -25,6 +25,8 @@
#include <string.h>
#include <locale.h>
diff --git a/dev/checker.dbg b/dev/checker.dbg
new file mode 100644
index 000000000..b2323b617
--- /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 000000000..327e636c5
--- /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 000000000..40ae1a7b0
--- /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 000000000..2f9500c5c
--- /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 bb13587e9..ed3442e0d 100644
--- a/dev/ci/README.md
+++ b/dev/ci/README.md
@@ -36,9 +36,8 @@ On the condition that:
- You do not push, to the branches that we test, commits that haven't been
first tested to compile with the corresponding branch(es) of Coq.
-- Your development compiles in less than 35 minutes with just two threads.
- If this is not the case, consider adding a "lite" target that compiles just
- part of it.
+- You maintain a reasonable build time for your development, or you provide
+ a "lite" target that we can use.
In case you forget to comply with these last three conditions, we would reach
out to you and give you a 30-day grace period during which your development
@@ -54,9 +53,10 @@ Add a new `ci-mydev.sh` script to [`dev/ci`](/dev/ci) (have a look at
set the corresponding variables in
[`ci-basic-overlay.sh`](/dev/ci/ci-basic-overlay.sh); add the corresponding
target to [`Makefile.ci`](/Makefile.ci); add new jobs to
-[`.travis.yml`](/.travis.yml) and [`.gitlab-ci.yml`](/.gitlab-ci.yml) so that
-this new target is run. **Do not hesitate to submit an incomplete pull request
-if you need help to finish it.**
+[`.gitlab-ci.yml`](/.gitlab-ci.yml),
+[`.circleci/config.yml`](/.circleci/config.yml) and
+[`.travis.yml`](/.travis.yml) so that this new target is run. **Do not
+hesitate to submit an incomplete pull request if you need help to finish it.**
You may also be interested in having your development tested in our
performance benchmark. Currently this is done by providing an OPAM package
@@ -71,24 +71,39 @@ When you submit a pull request (PR) on Coq GitHub repository, this will
automatically launch a battery of CI tests. The PR will not be integrated
unless these tests pass.
-Currently, we have two CI platforms:
+We are currently running tests on the following platforms:
-- Travis is the main CI platform. It tests the compilation of Coq, of the
+- GitLab CI is the main CI platform. It tests the compilation of Coq, of the
documentation, and of CoqIDE on Linux with several versions of OCaml /
camlp5, and with warnings as errors; it runs the test-suite and tests the
- compilation of several external developments. It also tests the compilation
- of Coq on OS X.
+ compilation of several external developments.
+
+- Circle CI runs tests that are redundant with GitLab CI and may be removed
+ eventually.
+
+- Travis CI is used to test the compilation of Coq and run the test-suite on
+ macOS. It also runs a linter that checks whitespace discipline. A
+ [pre-commit hook](/dev/tools/pre-commit) is automatically installed by
+ `./configure`. It should allow complying with this discipline without pain.
- AppVeyor is used to test the compilation of Coq and run the test-suite on
Windows.
-You can anticipate the results of these tests prior to submitting your PR
-by having them run of your fork of Coq, on GitHub or GitLab. This can be
-especially helpful given that our Travis platform is often overloaded and
-therefore there can be a significant delay before these tests are actually
-run on your PR. To take advantage of this, simply create a Travis account
-and link it to your GitHub account, or activate the pipelines on your GitLab
-fork.
+You can anticipate the results of most of these tests prior to submitting your
+PR by running GitLab CI on your private branches. To do so follow these steps:
+
+1. Log into GitLab CI (the easiest way is to sign in with your GitHub account).
+2. Click on "New Project".
+3. Choose "CI / CD for external repository" then click on "GitHub".
+4. Find your fork of the Coq repository and click on "Connect".
+5. If GitLab did not do so automatically, [enable the Container Registry](https://docs.gitlab.com/ee/user/project/container_registry.html#enable-the-container-registry-for-your-project).
+6. You are encouraged to go to the CI / CD general settings and increase the
+ timeout from 1h to 2h for better reliability.
+
+Now everytime you push (including force-push unless you changed the default
+GitLab setting) to your fork on GitHub, it will be synchronized on GitLab and
+CI will be run. You will receive an e-mail with a report of the failures if
+there are some.
You can also run one CI target locally (using `make ci-somedev`).
@@ -97,36 +112,56 @@ so that it doesn't, or provide a branch fixing these developments (or at
least work with the author of the development / other Coq developers to
prepare these fixes). Then, add an overlay in
[`dev/ci/user-overlays`](/dev/ci/user-overlays) (see the README there)
-in a separate commit in your PR.
+as part of your PR.
The process to merge your PR is then to submit PRs to the external
development repositories, merge the latter first (if the fixes are
-backward-compatible), drop the overlay commit and merge the PR on Coq then.
+backward-compatible), and merge the PR on Coq then.
See also [`test-suite/README.md`](/test-suite/README.md) for information about adding new tests to the test-suite.
-Travis specific information
----------------------------
+Advanced GitLab CI information
+------------------------------
-Travis rebuilds all of Coq's executables and stdlib for each job. Coq
-is built with `./configure -local`, then used for the job's test.
-
-
-GitLab specific information
----------------------------
-
-GitLab is set up to use the "build artifact" feature to avoid
-rebuilding Coq. In one job, Coq is built with `./configure -prefix
-install` and `make install` is run, then the `install` directory
+GitLab CI is set up to use the "build artifact" feature to avoid
+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, in two different copies varying in the OCaml
- version used to build Coq
+ 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.
As an exception to the above, jobs testing that compilation triggers
-no Ocaml warnings build Coq in parallel with other tests.
+no OCaml warnings build Coq in parallel with other tests.
+
+### GitLab and Windows
+
+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).
+
+The Windows jobs are enabled on Coq's repository, where pipelines for
+pull requests run.
+
+### GitLab and Docker
+
+System and opam packages are installed in a Docker image. The image is
+automatically built and uploaded to your GitLab registry, and is
+loaded by subsequent jobs.
+
+**IMPORTANT**: When updating Coq's CI docker image, you must modify
+the `CACHEKEY` variable in `.gitlab-ci.yml`, `.circleci/config.yml`,
+and `Dockerfile`.
+
+The Docker building job reuses the uploaded image if it is available,
+but if you wish to save more time you can skip the job by setting
+`SKIP_DOCKER` to `true`.
+
+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.
diff --git a/dev/ci/appveyor.sh b/dev/ci/appveyor.sh
index 93e7bd99a..c72705c7f 100644
--- a/dev/ci/appveyor.sh
+++ b/dev/ci/appveyor.sh
@@ -5,5 +5,5 @@ tar -xf opam64.tar.xz
bash opam64/install.sh
opam init -a mingw https://github.com/fdopen/opam-repository-mingw.git --comp 4.02.3+mingw64c --switch 4.02.3+mingw64c
eval "$(opam config env)"
-opam install -y ocamlfind camlp5
+opam install -y 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 1ae2ad0ac..5c882ee85 100755
--- a/dev/ci/ci-basic-overlay.sh
+++ b/dev/ci/ci-basic-overlay.sh
@@ -11,6 +11,8 @@
########################################################################
: "${mathcomp_CI_BRANCH:=master}"
: "${mathcomp_CI_GITURL:=https://github.com/math-comp/math-comp.git}"
+: "${oddorder_CI_BRANCH:=master}"
+: "${oddorder_CI_GITURL:=https://github.com/math-comp/odd-order.git}"
########################################################################
# UniMath
@@ -91,6 +93,12 @@
: "${VST_CI_GITURL:=https://github.com/PrincetonUniversity/VST.git}"
########################################################################
+# cross-crypto
+########################################################################
+: "${cross_crypto_CI_BRANCH:=master}"
+: "${cross_crypto_CI_GITURL:=https://github.com/mit-plv/cross-crypto.git}"
+
+########################################################################
# fiat_parsers
########################################################################
: "${fiat_parsers_CI_BRANCH:=master}"
diff --git a/dev/ci/ci-common.sh b/dev/ci/ci-common.sh
index 189734a0b..f867fd189 100644
--- a/dev/ci/ci-common.sh
+++ b/dev/ci/ci-common.sh
@@ -10,6 +10,10 @@ if [ -n "${GITLAB_CI}" ];
then
export COQBIN="$PWD/_install_ci/bin"
export CI_BRANCH="$CI_COMMIT_REF_NAME"
+ if [[ ${CI_BRANCH#pr-} =~ ^[0-9]*$ ]]
+ then
+ export CI_PULL_REQUEST="${CI_BRANCH#pr-}"
+ fi
else
if [ -n "${TRAVIS}" ];
then
@@ -67,11 +71,6 @@ git_checkout()
echo "${_DEST}: $(git log -1 --format='%s | %H | %cd | %aN')" )
}
-checkout_mathcomp()
-{
- git_checkout "${mathcomp_CI_BRANCH}" "${mathcomp_CI_GITURL}" "${1}"
-}
-
make()
{
# +x: add x only if defined
@@ -89,7 +88,8 @@ install_ssreflect()
{
echo 'Installing ssreflect' && echo -en 'travis_fold:start:ssr.install\\r'
- checkout_mathcomp "${mathcomp_CI_DIR}"
+ git_checkout "${mathcomp_CI_BRANCH}" "${mathcomp_CI_GITURL}" "${mathcomp_CI_DIR}"
+
( cd "${mathcomp_CI_DIR}/mathcomp" && \
sed -i.bak '/ssrtest/d' Make && \
sed -i.bak '/odd_order/d' Make && \
diff --git a/dev/ci/ci-compcert.sh b/dev/ci/ci-compcert.sh
index fbdeff20c..8d490591b 100755
--- a/dev/ci/ci-compcert.sh
+++ b/dev/ci/ci-compcert.sh
@@ -5,7 +5,6 @@ ci_dir="$(dirname "$0")"
CompCert_CI_DIR="${CI_BUILD_DIR}/CompCert"
-opam install -j "$NJOBS" -y menhir
git_checkout "${CompCert_CI_BRANCH}" "${CompCert_CI_GITURL}" "${CompCert_CI_DIR}"
( cd "${CompCert_CI_DIR}" && ./configure -ignore-coq-version x86_32-linux && make && make check-proof )
diff --git a/dev/ci/ci-cross-crypto.sh b/dev/ci/ci-cross-crypto.sh
new file mode 100755
index 000000000..a0d3aa655
--- /dev/null
+++ b/dev/ci/ci-cross-crypto.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+ci_dir="$(dirname "$0")"
+. "${ci_dir}/ci-common.sh"
+
+cross_crypto_CI_DIR="${CI_BUILD_DIR}/cross-crypto"
+
+git_checkout "${cross_crypto_CI_BRANCH}" "${cross_crypto_CI_GITURL}" "${cross_crypto_CI_DIR}"
+( cd "${cross_crypto_CI_DIR}" && git submodule update --init --recursive )
+
+( cd "${cross_crypto_CI_DIR}" && make )
diff --git a/dev/ci/ci-fiat-crypto.sh b/dev/ci/ci-fiat-crypto.sh
index 845addb4c..5d96c2499 100755
--- a/dev/ci/ci-fiat-crypto.sh
+++ b/dev/ci/ci-fiat-crypto.sh
@@ -6,6 +6,8 @@ ci_dir="$(dirname "$0")"
fiat_crypto_CI_DIR="${CI_BUILD_DIR}/fiat-crypto"
git_checkout "${fiat_crypto_CI_BRANCH}" "${fiat_crypto_CI_GITURL}" "${fiat_crypto_CI_DIR}"
+
( cd "${fiat_crypto_CI_DIR}" && git submodule update --init --recursive )
-( cd "${fiat_crypto_CI_DIR}" && make lite lite-display )
+fiat_crypto_CI_TARGETS="print-nobigmem nobigmem nonautogenerated-specific nonautogenerated-specific-display"
+( cd "${fiat_crypto_CI_DIR}" && make ${fiat_crypto_CI_TARGETS} )
diff --git a/dev/ci/ci-geocoq.sh b/dev/ci/ci-geocoq.sh
index bd1d88993..920272bcf 100755
--- a/dev/ci/ci-geocoq.sh
+++ b/dev/ci/ci-geocoq.sh
@@ -7,6 +7,4 @@ GeoCoq_CI_DIR="${CI_BUILD_DIR}/GeoCoq"
git_checkout "${GeoCoq_CI_BRANCH}" "${GeoCoq_CI_GITURL}" "${GeoCoq_CI_DIR}"
-( cd "${GeoCoq_CI_DIR}" && \
- ./configure-ci.sh && \
- make )
+( cd "${GeoCoq_CI_DIR}" && ./configure.sh && make )
diff --git a/dev/ci/ci-math-classes.sh b/dev/ci/ci-math-classes.sh
index 4fc06e895..6a064b297 100755
--- a/dev/ci/ci-math-classes.sh
+++ b/dev/ci/ci-math-classes.sh
@@ -7,4 +7,4 @@ math_classes_CI_DIR="${CI_BUILD_DIR}/math-classes"
git_checkout "${math_classes_CI_BRANCH}" "${math_classes_CI_GITURL}" "${math_classes_CI_DIR}"
-( cd "${math_classes_CI_DIR}" && make && make install )
+( cd "${math_classes_CI_DIR}" && ./configure.sh && make && make install )
diff --git a/dev/ci/ci-math-comp.sh b/dev/ci/ci-math-comp.sh
index 8c6b910bb..20328baf2 100755
--- a/dev/ci/ci-math-comp.sh
+++ b/dev/ci/ci-math-comp.sh
@@ -5,11 +5,10 @@ ci_dir="$(dirname "$0")"
. "${ci_dir}/ci-common.sh"
mathcomp_CI_DIR="${CI_BUILD_DIR}/math-comp"
+oddorder_CI_DIR="${CI_BUILD_DIR}/odd-order"
-checkout_mathcomp "${mathcomp_CI_DIR}"
+git_checkout "${mathcomp_CI_BRANCH}" "${mathcomp_CI_GITURL}" "${mathcomp_CI_DIR}"
+git_checkout "${oddorder_CI_BRANCH}" "${oddorder_CI_GITURL}" "${oddorder_CI_DIR}"
-# odd_order takes too much time for travis.
-( cd "${mathcomp_CI_DIR}/mathcomp" && \
- sed -i.bak '/PFsection/d' Make && \
- sed -i.bak '/stripped_odd_order_theorem/d' Make && \
- make Makefile.coq && make -f Makefile.coq all )
+( cd "${mathcomp_CI_DIR}/mathcomp" && make && make install )
+( cd "${oddorder_CI_DIR}/" && make )
diff --git a/dev/ci/ci-pidetop.sh b/dev/ci/ci-pidetop.sh
index d04b9637c..2ac4d2167 100755
--- a/dev/ci/ci-pidetop.sh
+++ b/dev/ci/ci-pidetop.sh
@@ -8,6 +8,17 @@ pidetop_CI_DIR="${CI_BUILD_DIR}/pidetop"
git_checkout "${pidetop_CI_BRANCH}" "${pidetop_CI_GITURL}" "${pidetop_CI_DIR}"
-( cd "${pidetop_CI_DIR}" && coq_makefile -f Make -o Makefile.top && make -f Makefile.top "-j${NJOBS}" && make install-toploop -f Makefile.top )
+# 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
+ COQOCAMLLIB="$COQBIN/../lib/"
+ COQLIB="$COQBIN/../lib/coq/"
+else
+ COQOCAMLLIB="$COQBIN/../"
+ COQLIB="$COQBIN/../"
+fi
-echo -en '4\nexit' | coqtop -main-channel stdfds -toploop pidetop
+( cd "${pidetop_CI_DIR}" && OCAMLPATH="$COQOCAMLLIB" jbuilder build @install )
+
+echo -en '4\nexit' | "$pidetop_CI_DIR/_build/install/default/bin/pidetop" -coqlib "$COQLIB" -main-channel stdfds
diff --git a/dev/ci/ci-unimath.sh b/dev/ci/ci-unimath.sh
index 62a949f59..aa20fe1ff 100755
--- a/dev/ci/ci-unimath.sh
+++ b/dev/ci/ci-unimath.sh
@@ -7,7 +7,4 @@ UniMath_CI_DIR="${CI_BUILD_DIR}/UniMath"
git_checkout "${UniMath_CI_BRANCH}" "${UniMath_CI_GITURL}" "${UniMath_CI_DIR}"
-( cd "${UniMath_CI_DIR}" && \
- sed -i.bak '/Folds/d' Makefile && \
- sed -i.bak '/HomologicalAlgebra/d' Makefile && \
- make BUILD_COQ=no )
+( cd "${UniMath_CI_DIR}" && make BUILD_COQ=no )
diff --git a/dev/ci/ci-vst.sh b/dev/ci/ci-vst.sh
index 79001c547..7a097eaab 100755
--- a/dev/ci/ci-vst.sh
+++ b/dev/ci/ci-vst.sh
@@ -5,9 +5,6 @@ ci_dir="$(dirname "$0")"
VST_CI_DIR="${CI_BUILD_DIR}/VST"
-# opam install -j ${NJOBS} -y menhir
git_checkout "${VST_CI_BRANCH}" "${VST_CI_GITURL}" "${VST_CI_DIR}"
-# We have to omit progs as otherwise we timeout on Travis; on Gitlab
-# we will be able to just use `make`
-( cd "${VST_CI_DIR}" && make IGNORECOQVERSION=true -o progs )
+( cd "${VST_CI_DIR}" && make IGNORECOQVERSION=true )
diff --git a/dev/ci/docker/README.md b/dev/ci/docker/README.md
new file mode 100644
index 000000000..919e2a735
--- /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
new file mode 100644
index 000000000..a1178ee2a
--- /dev/null
+++ b/dev/ci/docker/bionic_coq/Dockerfile
@@ -0,0 +1,49 @@
+# CACHEKEY: "bionic_coq-V2018-05-07-V2"
+# ^^ Update when modifying this file.
+
+FROM ubuntu:bionic
+LABEL maintainer="e@x80.org"
+
+ENV DEBIAN_FRONTEND="noninteractive"
+
+RUN apt-get update -qq && apt-get install -y -qq m4 wget time gcc-multilib opam \
+ libgtk2.0-dev libgtksourceview2.0-dev \
+ texlive-latex-extra texlive-fonts-recommended hevea \
+ python3-sphinx python3-pexpect python3-sphinx-rtd-theme python3-bs4 python3-sphinxcontrib.bibtex python3-pip
+
+RUN pip3 install antlr4-python3-runtime
+
+# Basic OPAM setup
+ENV NJOBS="2" \
+ OPAMROOT=/root/.opamcache \
+ OPAMROOTISOK="true"
+
+# Base opam is the set of base packages required by Coq
+ENV COMPILER="4.02.3" \
+ BASE_OPAM="num ocamlfind jbuilder ounit"
+
+RUN opam init -a -y -j $NJOBS --compiler="$COMPILER" default https://opam.ocaml.org && eval $(opam config env) && opam update
+
+# Setup of the base switch; CI_OPAM contains Coq's CI dependencies.
+ENV CAMLP5_VER="6.14" \
+ COQIDE_OPAM="lablgtk.2.18.5 conf-gtksourceview.2" \
+ CI_OPAM="menhir elpi ocamlgraph"
+
+RUN opam switch -y -j $NJOBS "$COMPILER" && eval $(opam config env) && \
+ opam install -j $NJOBS $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
+
+# BE switch
+ENV COMPILER_BE="4.06.1" \
+ CAMLP5_VER_BE="7.05" \
+ COQIDE_OPAM_BE="lablgtk.2.18.6 conf-gtksourceview.2"
+
+RUN opam switch -y -j $NJOBS $COMPILER_BE && eval $(opam config env) && \
+ opam install -j $NJOBS $BASE_OPAM camlp5.$CAMLP5_VER_BE $COQIDE_OPAM_BE
+
+# BE+flambda switch
+RUN opam switch -y -j $NJOBS "${COMPILER_BE}+flambda" && eval $(opam config env) && \
+ opam install -j $NJOBS $BASE_OPAM camlp5.$CAMLP5_VER_BE $COQIDE_OPAM_BE $CI_OPAM
diff --git a/dev/ci/gitlab.bat b/dev/ci/gitlab.bat
new file mode 100644
index 000000000..70278e6d0
--- /dev/null
+++ b/dev/ci/gitlab.bat
@@ -0,0 +1,50 @@
+@ECHO OFF
+
+REM This script builds and signs the Windows packages on Gitlab
+
+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
+)
+
+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 DESTCOQ=C:\coq%ARCH%_inst
+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 -make=N ^
+ -setup %CI_PROJECT_DIR%\%SETUP% || GOTO ErrorExit
+
+copy "%CYGROOT%\build\coq-local\dev\nsis\*.exe" dev\nsis || GOTO ErrorExit
+7z a coq-opensource-archive-windows-%ARCHLONG%.zip %CYGROOT%\build\tarballs\* || GOTO ErrorExit
+
+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
+ )
+)
+
+GOTO :EOF
+
+:ErrorExit
+ ECHO ERROR %0 failed
+ EXIT /b 1
diff --git a/dev/ci/user-overlays/06859-ejgallego-stm+top.sh b/dev/ci/user-overlays/06859-ejgallego-stm+top.sh
new file mode 100644
index 000000000..ca0076b46
--- /dev/null
+++ b/dev/ci/user-overlays/06859-ejgallego-stm+top.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+if [ "$CI_PULL_REQUEST" = "6859" ] || [ "$CI_BRANCH" = "stm+top" ] || [ "$CI_BRANCH" = "pr-6859" ]; then
+ pidetop_CI_BRANCH=stm+top
+ pidetop_CI_GITURL=https://bitbucket.org/ejgallego/pidetop.git
+fi
diff --git a/dev/ci/user-overlays/07213-ppedrot-fast-constr-match-no-context.sh b/dev/ci/user-overlays/07213-ppedrot-fast-constr-match-no-context.sh
new file mode 100644
index 000000000..517088a24
--- /dev/null
+++ b/dev/ci/user-overlays/07213-ppedrot-fast-constr-match-no-context.sh
@@ -0,0 +1,6 @@
+if [ "$CI_PULL_REQUEST" = "7213" ] || [ "$CI_BRANCH" = "fast-constr-match-no-context" ]; then
+
+ ltac2_CI_BRANCH=fast-constr-match-no-context
+ ltac2_CI_GITURL=https://github.com/ppedrot/ltac2
+
+fi
diff --git a/dev/core.dbg b/dev/core.dbg
index edf67020a..972ba701e 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
diff --git a/dev/doc/MERGING.md b/dev/doc/MERGING.md
index 84ff94c66..a466124c1 100644
--- a/dev/doc/MERGING.md
+++ b/dev/doc/MERGING.md
@@ -109,9 +109,8 @@ There are two cases to consider:
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 tutorial to
-creating your own GPG key:
-<https://ekaia.org/blog/2009/05/10/creating-new-gpgkey/>
+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.
diff --git a/dev/doc/changes.md b/dev/doc/changes.md
index 2bad21bb2..ff448abe8 100644
--- a/dev/doc/changes.md
+++ b/dev/doc/changes.md
@@ -2,9 +2,15 @@
### ML API
+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
+- 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
@@ -18,6 +24,15 @@ Proof engine
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`.
+
+### 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.
+
## Changes between Coq 8.7 and Coq 8.8
### Bug tracker
@@ -94,6 +109,11 @@ Declaration of printers for arguments used only in vernac command
happen. An alternative is to register the corresponding argument as
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
The STM API has seen a general overhaul. The main change is the
diff --git a/dev/ocamldebug-coq.run b/dev/ocamldebug-coq.run
index 8f1c165dd..2bec09de2 100644
--- a/dev/ocamldebug-coq.run
+++ b/dev/ocamldebug-coq.run
@@ -14,7 +14,15 @@
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 \
@@ -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/check-owners-pr.sh b/dev/tools/check-owners-pr.sh
new file mode 100755
index 000000000..d2910279b
--- /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 000000000..1a97508ab
--- /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 62fdaec80..70a9756e5 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
@@ -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/pre-commit b/dev/tools/pre-commit
index b56925c37..ad2f2f93e 100755
--- a/dev/tools/pre-commit
+++ b/dev/tools/pre-commit
@@ -14,9 +14,9 @@ then
# We fix whitespace in the index and in the working tree
# separately to preserve non-added changes.
- index=$(mktemp "git-fix-ws-index.XXXXX")
- fixed_index=$(mktemp "git-fix-ws-index-fixed.XXXXX")
- tree=$(mktemp "git-fix-ws-tree.XXXXX")
+ index=$(mktemp "git-fix-ws-index.XXXXXX")
+ fixed_index=$(mktemp "git-fix-ws-index-fixed.XXXXXX")
+ tree=$(mktemp "git-fix-ws-tree.XXXXXX")
1>&2 echo "Patches are saved in '$index', '$fixed_index' and '$tree'."
1>&2 echo "If an error destroys your changes you can recover using them."
1>&2 echo "(The files are cleaned up on success.)"
diff --git a/dev/top_printers.ml b/dev/top_printers.ml
index 8d5b5bef4..cb1abc4a9 100644
--- a/dev/top_printers.ml
+++ b/dev/top_printers.ml
@@ -203,17 +203,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
diff --git a/dev/top_printers.mli b/dev/top_printers.mli
index dad6dcc1c..63d7d5805 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/doc/RecTutorial/RecTutorial.tex b/doc/RecTutorial/RecTutorial.tex
deleted file mode 100644
index 01369b900..000000000
--- a/doc/RecTutorial/RecTutorial.tex
+++ /dev/null
@@ -1,3690 +0,0 @@
-\documentclass[11pt]{article}
-\title{A Tutorial on [Co-]Inductive Types in Coq}
-\author{Eduardo Gim\'enez\thanks{Eduardo.Gimenez@inria.fr},
-Pierre Cast\'eran\thanks{Pierre.Casteran@labri.fr}}
-\date{May 1998 --- \today}
-
-\usepackage{multirow}
-% \usepackage{aeguill}
-% \externaldocument{RefMan-gal.v}
-% \externaldocument{RefMan-ext.v}
-% \externaldocument{RefMan-tac.v}
-% \externaldocument{RefMan-oth}
-% \externaldocument{RefMan-tus.v}
-% \externaldocument{RefMan-syn.v}
-% \externaldocument{Extraction.v}
-\input{recmacros}
-\input{coqartmacros}
-\newcommand{\refmancite}[1]{{}}
-% \newcommand{\refmancite}[1]{\cite{coqrefman}}
-% \newcommand{\refmancite}[1]{\cite[#1] {]{coqrefman}}
-
-\usepackage[utf8]{inputenc}
-\usepackage[T1]{fontenc}
-\usepackage{makeidx}
-% \usepackage{multind}
-\usepackage{alltt}
-\usepackage{verbatim}
-\usepackage{amssymb}
-\usepackage{amsmath}
-\usepackage{theorem}
-\usepackage[dvips]{epsfig}
-\usepackage{epic}
-\usepackage{eepic}
-% \usepackage{ecltree}
-\usepackage{moreverb}
-\usepackage{color}
-\usepackage{pifont}
-\usepackage{xr}
-\usepackage{url}
-
-\usepackage{alltt}
-\renewcommand{\familydefault}{ptm}
-\renewcommand{\seriesdefault}{m}
-\renewcommand{\shapedefault}{n}
-\newtheorem{exercise}{Exercise}[section]
-\makeindex
-\begin{document}
-\maketitle
-
-\begin{abstract}
-This document\footnote{The first versions of this document were entirely written by Eduardo Gimenez.
-Pierre Cast\'eran wrote the 2004 and 2006 revisions.} is an introduction to the definition and
-use of inductive and co-inductive types in the {\coq} proof environment. It explains how types like natural numbers and infinite streams are defined
-in {\coq}, and the kind of proof techniques that can be used to reason
-about them (case analysis, induction, inversion of predicates,
-co-induction, etc). Each technique is illustrated through an
-executable and self-contained {\coq} script.
-\end{abstract}
-%\RRkeyword{Proof environments, recursive types.}
-%\makeRT
-
-\addtocontents{toc}{\protect \thispagestyle{empty}}
-\pagenumbering{arabic}
-
-\cleardoublepage
-\tableofcontents
-\clearpage
-
-\section{About this document}
-
-This document is an introduction to the definition and use of
-inductive and co-inductive types in the {\coq} proof environment. It was born from the
-notes written for the course about the version V5.10 of {\coq}, given
-by Eduardo Gimenez at
-the Ecole Normale Sup\'erieure de Lyon in March 1996. This article is
-a revised and improved version of these notes for the version V8.0 of
-the system.
-
-
-We assume that the reader has some familiarity with the
-proofs-as-programs paradigm of Logic \cite{Coquand:metamathematical} and the generalities
-of the {\coq} system \cite{coqrefman}. You would take a greater advantage of
-this document if you first read the general tutorial about {\coq} and
-{\coq}'s FAQ, both available on \cite{coqsite}.
-A text book \cite{coqart}, accompanied with a lot of
-examples and exercises \cite{Booksite}, presents a detailed description
-of the {\coq} system and its underlying
-formalism: the Calculus of Inductive Construction.
-Finally, the complete description of {\coq} is given in the reference manual
-\cite{coqrefman}. Most of the tactics and commands we describe have
-several options, which we do not present exhaustively.
-If some script herein uses a non described feature, please refer to
-the Reference Manual.
-
-
-If you are familiar with other proof environments
-based on type theory and the LCF style ---like PVS, LEGO, Isabelle,
-etc--- then you will find not difficulty to guess the unexplained
-details.
-
-The better way to read this document is to start up the {\coq} system,
-type by yourself the examples and exercises, and observe the
-behavior of the system. All the examples proposed in this tutorial
-can be downloaded from the same site as the present document.
-
-
-The tutorial is organised as follows. The next section describes how
-inductive types are defined in {\coq}, and introduces some useful ones,
-like natural numbers, the empty type, the propositional equality type,
-and the logical connectives. Section \ref{CaseAnalysis} explains
-definitions by pattern-matching and their connection with the
-principle of case analysis. This principle is the most basic
-elimination rule associated with inductive or co-inductive types
- and follows a
-general scheme that we illustrate for some of the types introduced in
-Section \ref{Introduction}. Section \ref{CaseTechniques} illustrates
-the pragmatics of this principle, showing different proof techniques
-based on it. Section \ref{StructuralInduction} introduces definitions
-by structural recursion and proofs by induction.
-Section~\ref{CaseStudy} presents some elaborate techniques
-about dependent case analysis. Finally, Section
-\ref{CoInduction} is a brief introduction to co-inductive types
---i.e., types containing infinite objects-- and the principle of
-co-induction.
-
-
-Thanks to Bruno Barras, Yves Bertot, Hugo Herbelin, Jean-Fran\c{c}ois Monin
-and Michel L\'evy for their help.
-
-\subsection*{Lexical conventions}
-The \texttt{typewriter} font is used to represent text
-input by the user, while the \textit{italic} font is used to represent
-the text output by the system as answers.
-
-
-Moreover, the mathematical symbols \coqle{}, \coqdiff, \(\exists\),
-\(\forall\), \arrow{}, $\rightarrow{}$ \coqor{}, \coqand{}, and \funarrow{}
-stand for the character strings \citecoq{<=}, \citecoq{<>},
-\citecoq{exists}, \citecoq{forall}, \citecoq{->}, \citecoq{<-},
-\texttt{\char'134/}, \texttt{/\char'134}, and \citecoq{=>},
-respectively. For instance, the \coq{} statement
-%V8 A prendre
-% inclusion numero 1
-% traduction numero 1
-\begin{alltt}
-\hide{Open Scope nat_scope. Check (}forall A:Type,(exists x : A, forall (y:A), x <> y) -> 2 = 3\hide{).}
-\end{alltt}
-is written as follows in this tutorial:
-%V8 A prendre
-% inclusion numero 2
-% traduction numero 2
-\begin{alltt}
-\hide{Check (}{\prodsym}A:Type,(\exsym{}x:A, {\prodsym}y:A, x {\coqdiff} y) \arrow{} 2 = 3\hide{).}
-\end{alltt}
-
-When a fragment of \coq{} input text appears in the middle of
-regular text, we often place this fragment between double quotes
-``\dots.'' These double quotes do not belong to the \coq{} syntax.
-
-Finally, any
-string enclosed between \texttt{(*} and \texttt{*)} is a comment and
-is ignored by the \coq{} system.
-
-\section{Introducing Inductive Types}
-\label{Introduction}
-
-Inductive types are types closed with respect to their introduction
-rules. These rules explain the most basic or \textsl{canonical} ways
-of constructing an element of the type. In this sense, they
-characterize the recursive type. Different rules must be considered as
-introducing different objects. In order to fix ideas, let us introduce
-in {\coq} the most well-known example of a recursive type: the type of
-natural numbers.
-
-%V8 A prendre
-\begin{alltt}
-Inductive nat : Set :=
- | O : nat
- | S : nat\arrow{}nat.
-\end{alltt}
-
-The definition of a recursive type has two main parts. First, we
-establish what kind of recursive type we will characterize (a set, in
-this case). Second, we present the introduction rules that define the
-type ({\Z} and {\SUCC}), also called its {\sl constructors}. The constructors
-{\Z} and {\SUCC} determine all the elements of this type. In other
-words, if $n\mbox{:}\nat$, then $n$ must have been introduced either
-by the rule {\Z} or by an application of the rule {\SUCC} to a
-previously constructed natural number. In this sense, we can say
-that {\nat} is \emph{closed}. On the contrary, the type
-$\Set$ is an {\it open} type, since we do not know {\it a priori} all
-the possible ways of introducing an object of type \texttt{Set}.
-
-After entering this command, the constants {\nat}, {\Z} and {\SUCC} are
-available in the current context. We can see their types using the
-\texttt{Check} command \refmancite{Section \ref{Check}}:
-
-%V8 A prendre
-\begin{alltt}
-Check nat.
-\it{}nat : Set
-\tt{}Check O.
-\it{}O : nat
-\tt{}Check S.
-\it{}S : nat {\arrow} nat
-\end{alltt}
-
-Moreover, {\coq} adds to the context three constants named
- $\natind$, $\natrec$ and $\natrect$, which
- correspond to different principles of structural induction on
-natural numbers that {\coq} infers automatically from the definition. We
-will come back to them in Section \ref{StructuralInduction}.
-
-
-In fact, the type of natural numbers as well as several useful
-theorems about them are already defined in the basic library of {\coq},
-so there is no need to introduce them. Therefore, let us throw away
-our (re)definition of {\nat}, using the command \texttt{Reset}.
-
-%V8 A prendre
-\begin{alltt}
-Reset nat.
-Print nat.
-\it{}Inductive nat : Set := O : nat | S : nat \arrow{} nat
-For S: Argument scope is [nat_scope]
-\end{alltt}
-
-Notice that \coq{}'s \emph{interpretation scope} for natural numbers
-(called \texttt{nat\_scope})
-allows us to read and write natural numbers in decimal form (see \cite{coqrefman}). For instance, the constructor \texttt{O} can be read or written
-as the digit $0$, and the term ``~\texttt{S (S (S O))}~'' as $3$.
-
-%V8 A prendre
-\begin{alltt}
-Check O.
-\it 0 : nat.
-\tt
-Check (S (S (S O))).
-\it 3 : nat
-\end{alltt}
-
-Let us now take a look to some other
-recursive types contained in the standard library of {\coq}.
-
-\subsection{Lists}
-Lists are defined in library \citecoq{List}\footnote{Notice that in versions of
-{\coq}
-prior to 8.1, the parameter $A$ had sort \citecoq{Set} instead of \citecoq{Type};
-the constant \citecoq{list} was thus of type \citecoq{Set\arrow{} Set}.}
-
-
-\begin{alltt}
-Require Import List.
-Print list.
-\it
-Inductive list (A : Type) : Type:=
- nil : list A | cons : A {\arrow} list A {\arrow} list A
-For nil: Argument A is implicit
-For cons: Argument A is implicit
-For list: Argument scope is [type_scope]
-For nil: Argument scope is [type_scope]
-For cons: Argument scopes are [type_scope _ _]
-\end{alltt}
-
-In this definition, \citecoq{A} is a \emph{general parameter}, global
-to both constructors.
-This kind of definition allows us to build a whole family of
-inductive types, indexed over the sort \citecoq{Type}.
-This can be observed if we consider the type of identifiers
-\citecoq{list}, \citecoq{cons} and \citecoq{nil}.
-Notice the notation \citecoq{(A := \dots)} which must be used
-when {\coq}'s type inference algorithm cannot infer the implicit
-parameter \citecoq{A}.
-\begin{alltt}
-Check list.
-\it list
- : Type {\arrow} Type
-
-\tt Check (nil (A:=nat)).
-\it nil
- : list nat
-
-\tt Check (nil (A:= nat {\arrow} nat)).
-\it nil
- : list (nat {\arrow} nat)
-
-\tt Check (fun A: Type {\funarrow} (cons (A:=A))).
-\it fun A : Type {\funarrow} cons (A:=A)
- : {\prodsym} A : Type, A {\arrow} list A {\arrow} list A
-
-\tt Check (cons 3 (cons 2 nil)).
-\it 3 :: 2 :: nil
- : list nat
-
-\tt Check (nat :: bool ::nil).
-\it nat :: bool :: nil
- : list Set
-
-\tt Check ((3<=4) :: True ::nil).
-\it (3<=4) :: True :: nil
- : list Prop
-
-\tt Check (Prop::Set::nil).
-\it Prop::Set::nil
- : list Type
-\end{alltt}
-
-\subsection{Vectors.}
-\label{vectors}
-
-Like \texttt{list}, \citecoq{vector} is a polymorphic type:
-if $A$ is a type, and $n$ a natural number, ``~\citecoq{vector $A$ $n$}~''
-is the type of vectors of elements of $A$ and size $n$.
-
-
-\begin{alltt}
-Require Import Bvector.
-
-Print vector.
-\it
-Inductive vector (A : Type) : nat {\arrow} Type :=
- Vnil : vector A 0
- | Vcons : A {\arrow} {\prodsym} n : nat, vector A n {\arrow} vector A (S n)
-For vector: Argument scopes are [type_scope nat_scope]
-For Vnil: Argument scope is [type_scope]
-For Vcons: Argument scopes are [type_scope _ nat_scope _]
-\end{alltt}
-
-
-Remark the difference between the two parameters $A$ and $n$:
-The first one is a \textsl{general parameter}, global to all the
-introduction rules,while the second one is an \textsl{index}, which is
-instantiated differently in the introduction rules.
-Such types parameterized by regular
-values are called \emph{dependent types}.
-
-\begin{alltt}
-Check (Vnil nat).
-\it Vnil nat
- : vector nat 0
-
-\tt Check (fun (A:Type)(a:A){\funarrow} Vcons _ a _ (Vnil _)).
-\it fun (A : Type) (a : A) {\funarrow} Vcons A a 0 (Vnil A)
- : {\prodsym} A : Type, A {\arrow} vector A 1
-
-
-\tt Check (Vcons _ 5 _ (Vcons _ 3 _ (Vnil _))).
-\it Vcons nat 5 1 (Vcons nat 3 0 (Vnil nat))
- : vector nat 2
-\end{alltt}
-
-\subsection{The contradictory proposition.}
-Another example of an inductive type is the contradictory proposition.
-This type inhabits the universe of propositions, and has no element
-at all.
-%V8 A prendre
-\begin{alltt}
-Print False.
-\it{} Inductive False : Prop :=
-\end{alltt}
-
-\noindent Notice that no constructor is given in this definition.
-
-\subsection{The tautological proposition.}
-Similarly, the
-tautological proposition {\True} is defined as an inductive type
-with only one element {\I}:
-
-%V8 A prendre
-\begin{alltt}
-Print True.
-\it{}Inductive True : Prop := I : True
-\end{alltt}
-
-\subsection{Relations as inductive types.}
-Some relations can also be introduced in a smart way as an inductive family
-of propositions. Let us take as example the order $n \leq m$ on natural
-numbers, called \citecoq{le} in {\coq}.
- This relation is introduced through
-the following definition, quoted from the standard library\footnote{In the interpretation scope
-for Peano arithmetic:
-\citecoq{nat\_scope}, ``~\citecoq{n <= m}~'' is equivalent to
-``~\citecoq{le n m}~'' .}:
-
-
-
-
-%V8 A prendre
-\begin{alltt}
-Print le. \it
-Inductive le (n:nat) : nat\arrow{}Prop :=
-| le_n: n {\coqle} n
-| le_S: {\prodsym} m, n {\coqle} m \arrow{} n {\coqle} S m.
-\end{alltt}
-
-Notice that in this definition $n$ is a general parameter,
-while the second argument of \citecoq{le} is an index (see section
-~\ref{vectors}).
- This definition
-introduces the binary relation $n {\leq} m$ as the family of unary predicates
-``\textsl{to be greater or equal than a given $n$}'', parameterized by $n$.
-
-The introduction rules of this type can be seen as a sort of Prolog
-rules for proving that a given integer $n$ is less or equal than another one.
-In fact, an object of type $n{\leq} m$ is nothing but a proof
-built up using the constructors \textsl{le\_n} and
-\textsl{le\_S} of this type. As an example, let us construct
-a proof that zero is less or equal than three using {\coq}'s interactive
-proof mode.
-Such an object can be obtained applying three times the second
-introduction rule of \citecoq{le}, to a proof that zero is less or equal
-than itself,
-which is provided by the first constructor of \citecoq{le}:
-
-%V8 A prendre
-\begin{alltt}
-Theorem zero_leq_three: 0 {\coqle} 3.
-Proof.
-\it{} 1 subgoal
-
-============================
- 0 {\coqle} 3
-
-\tt{}Proof.
- constructor 2.
-
-\it{} 1 subgoal
-============================
- 0 {\coqle} 2
-
-\tt{} constructor 2.
-\it{} 1 subgoal
-============================
- 0 {\coqle} 1
-
-\tt{} constructor 2
-\it{} 1 subgoal
-============================
- 0 {\coqle} 0
-
-\tt{} constructor 1.
-
-\it{}Proof completed
-\tt{}Qed.
-\end{alltt}
-
-\noindent When
-the current goal is an inductive type, the tactic
-``~\citecoq{constructor $i$}~'' \refmancite{Section \ref{constructor}} applies the $i$-th constructor in the
-definition of the type. We can take a look at the proof constructed
-using the command \texttt{Print}:
-
-%V8 A prendre
-\begin{alltt}
-Print Print zero_leq_three.
-\it{}zero_leq_three =
-zero_leq_three = le_S 0 2 (le_S 0 1 (le_S 0 0 (le_n 0)))
- : 0 {\coqle} 3
-\end{alltt}
-
-When the parameter $i$ is not supplied, the tactic \texttt{constructor}
-tries to apply ``~\texttt{constructor $1$}~'', ``~\texttt{constructor $2$}~'',\dots,
-``~\texttt{constructor $n$}~'' where $n$ is the number of constructors
-of the inductive type (2 in our example) of the conclusion of the goal.
-Our little proof can thus be obtained iterating the tactic
-\texttt{constructor} until it fails:
-
-%V8 A prendre
-\begin{alltt}
-Lemma zero_leq_three': 0 {\coqle} 3.
- repeat constructor.
-Qed.
-\end{alltt}
-
-Notice that the strict order on \texttt{nat}, called \citecoq{lt}
-is not inductively defined: the proposition $n<p$ (notation for \citecoq{lt $n$ $p$})
-is reducible to \citecoq{(S $n$) $\leq$ p}.
-
-\begin{alltt}
-Print lt.
-\it
-lt = fun n m : nat {\funarrow} S n {\coqle} m
- : nat {\arrow} nat {\arrow} Prop
-\tt
-Lemma zero_lt_three : 0 < 3.
-Proof.
- repeat constructor.
-Qed.
-
-Print zero_lt_three.
-\it zero_lt_three = le_S 1 2 (le_S 1 1 (le_n 1))
- : 0 < 3
-\end{alltt}
-
-
-
-\subsection{About general parameters (\coq{} version $\geq$ 8.1)}
-\label{parameterstuff}
-
-Since version $8.1$, it is possible to write more compact inductive definitions
-than in earlier versions.
-
-Consider the following alternative definition of the relation $\leq$ on
-type \citecoq{nat}:
-
-\begin{alltt}
-Inductive le'(n:nat):nat -> Prop :=
- | le'_n : le' n n
- | le'_S : forall p, le' (S n) p -> le' n p.
-
-Hint Constructors le'.
-\end{alltt}
-
-We notice that the type of the second constructor of \citecoq{le'}
-has an argument whose type is \citecoq{le' (S n) p}.
-This constrasts with earlier versions
-of {\coq}, in which a general parameter $a$ of an inductive
-type $I$ had to appear only in applications of the form $I\,\dots\,a$.
-
-Since version $8.1$, if $a$ is a general parameter of an inductive
-type $I$, the type of an argument of a constructor of $I$ may be
-of the form $I\,\dots\,t_a$ , where $t_a$ is any term.
-Notice that the final type of the constructors must be of the form
-$I\,\dots\,a$, since these constructors describe how to form
-inhabitants of type $I\,\dots\,a$ (this is the role of parameter $a$).
-
-Another example of this new feature is {\coq}'s definition of accessibility
-(see Section~\ref{WellFoundedRecursion}), which has a general parameter
-$x$; the constructor for the predicate
-``$x$ is accessible'' takes an argument of type ``$y$ is accessible''.
-
-
-
-In earlier versions of {\coq}, a relation like \citecoq{le'} would have to be
-defined without $n$ being a general parameter.
-
-\begin{alltt}
-Reset le'.
-
-Inductive le': nat-> nat -> Prop :=
- | le'_n : forall n, le' n n
- | le'_S : forall n p, le' (S n) p -> le' n p.
-\end{alltt}
-
-
-
-
-\subsection{The propositional equality type.} \label{equality}
-In {\coq}, the propositional equality between two inhabitants $a$ and
-$b$ of
-the same type $A$ ,
-noted $a=b$, is introduced as a family of recursive predicates
-``~\textsl{to be equal to $a$}~'', parameterised by both $a$ and its type
-$A$. This family of types has only one introduction rule, which
-corresponds to reflexivity.
-Notice that the syntax ``\citecoq{$a$ = $b$}~'' is an abbreviation
-for ``\citecoq{eq $a$ $b$}~'', and that the parameter $A$ is \emph{implicit},
-as it can be infered from $a$.
-%V8 A prendre
-\begin{alltt}
-Print eq.
-\it{} Inductive eq (A : Type) (x : A) : A \arrow{} Prop :=
- eq_refl : x = x
-For eq: Argument A is implicit
-For eq_refl: Argument A is implicit
-For eq: Argument scopes are [type_scope _ _]
-For eq_refl: Argument scopes are [type_scope _]
-\end{alltt}
-
-Notice also that the first parameter $A$ of \texttt{eq} has type
-\texttt{Type}. The type system of {\coq} allows us to consider equality between
-various kinds of terms: elements of a set, proofs, propositions,
-types, and so on.
-Look at \cite{coqrefman, coqart} to get more details on {\coq}'s type
-system, as well as implicit arguments and argument scopes.
-
-
-\begin{alltt}
-Lemma eq_3_3 : 2 + 1 = 3.
-Proof.
- reflexivity.
-Qed.
-
-Lemma eq_proof_proof : eq_refl (2*6) = eq_refl (3*4).
-Proof.
- reflexivity.
-Qed.
-
-Print eq_proof_proof.
-\it eq_proof_proof =
-eq_refl (eq_refl (3 * 4))
- : eq_refl (2 * 6) = eq_refl (3 * 4)
-\tt
-
-Lemma eq_lt_le : ( 2 < 4) = (3 {\coqle} 4).
-Proof.
- reflexivity.
-Qed.
-
-Lemma eq_nat_nat : nat = nat.
-Proof.
- reflexivity.
-Qed.
-
-Lemma eq_Set_Set : Set = Set.
-Proof.
- reflexivity.
-Qed.
-\end{alltt}
-
-\subsection{Logical connectives.} \label{LogicalConnectives}
-The conjunction and disjunction of two propositions are also examples
-of recursive types:
-
-\begin{alltt}
-Inductive or (A B : Prop) : Prop :=
- or_introl : A \arrow{} A {\coqor} B | or_intror : B \arrow{} A {\coqor} B
-
-Inductive and (A B : Prop) : Prop :=
- conj : A \arrow{} B \arrow{} A {\coqand} B
-
-\end{alltt}
-
-The propositions $A$ and $B$ are general parameters of these
-connectives. Choosing different universes for
-$A$ and $B$ and for the inductive type itself gives rise to different
-type constructors. For example, the type \textsl{sumbool} is a
-disjunction but with computational contents.
-
-\begin{alltt}
-Inductive sumbool (A B : Prop) : Set :=
- left : A \arrow{} \{A\} + \{B\} | right : B \arrow{} \{A\} + \{B\}
-\end{alltt}
-
-
-
-This type --noted \texttt{\{$A$\}+\{$B$\}} in {\coq}-- can be used in {\coq}
-programs as a sort of boolean type, to check whether it is $A$ or $B$
-that is true. The values ``~\citecoq{left $p$}~'' and
-``~\citecoq{right $q$}~'' replace the boolean values \textsl{true} and
-\textsl{false}, respectively. The advantage of this type over
-\textsl{bool} is that it makes available the proofs $p$ of $A$ or $q$
-of $B$, which could be necessary to construct a verification proof
-about the program.
-For instance, let us consider the certified program \citecoq{le\_lt\_dec}
-of the Standard Library.
-
-\begin{alltt}
-Require Import Compare_dec.
-Check le_lt_dec.
-\it
-le_lt_dec
- : {\prodsym} n m : nat, \{n {\coqle} m\} + \{m < n\}
-
-\end{alltt}
-
-We use \citecoq{le\_lt\_dec} to build a function for computing
-the max of two natural numbers:
-
-\begin{alltt}
-Definition max (n p :nat) := match le_lt_dec n p with
- | left _ {\funarrow} p
- | right _ {\funarrow} n
- end.
-\end{alltt}
-
-In the following proof, the case analysis on the term
-``~\citecoq{le\_lt\_dec n p}~'' gives us an access to proofs
-of $n\leq p$ in the first case, $p<n$ in the other.
-
-\begin{alltt}
-Theorem le_max : {\prodsym} n p, n {\coqle} p {\arrow} max n p = p.
-Proof.
- intros n p ; unfold max ; case (le_lt_dec n p); simpl.
-\it
-2 subgoals
-
- n : nat
- p : nat
- ============================
- n {\coqle} p {\arrow} n {\coqle} p {\arrow} p = p
-
-subgoal 2 is:
- p < n {\arrow} n {\coqle} p {\arrow} n = p
-\tt
- trivial.
- intros; absurd (p < p); eauto with arith.
-Qed.
-\end{alltt}
-
-
- Once the program verified, the proofs are
-erased by the extraction procedure:
-
-\begin{alltt}
-Extraction max.
-\it
-(** val max : nat {\arrow} nat {\arrow} nat **)
-
-let max n p =
- match le_lt_dec n p with
- | Left {\arrow} p
- | Right {\arrow} n
-\end{alltt}
-
-Another example of use of \citecoq{sumbool} is given in Section
-\ref{WellFoundedRecursion}: the theorem \citecoq{eq\_nat\_dec} of
-library \citecoq{Coq.Arith.Peano\_dec} is used in an euclidean division
-algorithm.
-
-\subsection{The existential quantifier.}\label{ex-def}
-The existential quantifier is yet another example of a logical
-connective introduced as an inductive type.
-
-\begin{alltt}
-Inductive ex (A : Type) (P : A \arrow{} Prop) : Prop :=
- ex_intro : {\prodsym} x : A, P x \arrow{} ex P
-\end{alltt}
-
-Notice that {\coq} uses the abreviation ``~\citecoq{\exsym\,$x$:$A$, $B$}~''
-for \linebreak ``~\citecoq{ex (fun $x$:$A$ \funarrow{} $B$)}~''.
-
-
-\noindent The former quantifier inhabits the universe of propositions.
-As for the conjunction and disjunction connectives, there is also another
-version of existential quantification inhabiting the universes $\Type_i$,
-which is written \texttt{sig $P$}. The syntax
-``~\citecoq{\{$x$:$A$ | $B$\}}~'' is an abreviation for ``~\citecoq{sig (fun $x$:$A$ {\funarrow} $B$)}~''.
-
-
-
-%\paragraph{The logical connectives.} Conjuction and disjuction are
-%also introduced as recursive types:
-%\begin{alltt}
-%Print or.
-%\end{alltt}
-%begin{alltt}
-%Print and.
-%\end{alltt}
-
-
-\subsection{Mutually Dependent Definitions}
-\label{MutuallyDependent}
-
-Mutually dependent definitions of recursive types are also allowed in
-{\coq}. A typical example of these kind of declaration is the
-introduction of the trees of unbounded (but finite) width:
-\label{Forest}
-\begin{alltt}
-Inductive tree(A:Type) : Type :=
- node : A {\arrow} forest A \arrow{} tree A
-with forest (A: Set) : Type :=
- nochild : forest A |
- addchild : tree A \arrow{} forest A \arrow{} forest A.
-\end{alltt}
-\noindent Yet another example of mutually dependent types are the
-predicates \texttt{even} and \texttt{odd} on natural numbers:
-\label{Even}
-\begin{alltt}
-Inductive
- even : nat\arrow{}Prop :=
- evenO : even O |
- evenS : {\prodsym} n, odd n \arrow{} even (S n)
-with
- odd : nat\arrow{}Prop :=
- oddS : {\prodsym} n, even n \arrow{} odd (S n).
-\end{alltt}
-
-\begin{alltt}
-Lemma odd_49 : odd (7 * 7).
- simpl; repeat constructor.
-Qed.
-\end{alltt}
-
-
-
-\section{Case Analysis and Pattern-matching}
-\label{CaseAnalysis}
-\subsection{Non-dependent Case Analysis}
-An \textsl{elimination rule} for the type $A$ is some way to use an
-object $a:A$ in order to define an object in some type $B$.
-A natural elimination rule for an inductive type is \emph{case analysis}.
-
-
-For instance, any value of type {\nat} is built using either \texttt{O} or \texttt{S}.
-Thus, a systematic way of building a value of type $B$ from any
-value of type {\nat} is to associate to \texttt{O} a constant $t_O:B$ and
-to every term of the form ``~\texttt{S $p$}~'' a term $t_S:B$. The following
-construction has type $B$:
-\begin{alltt}
-match \(n\) return \(B\) with O \funarrow \(t\sb{O}\) | S p \funarrow \(t\sb{S}\) end
-\end{alltt}
-
-
-In most of the cases, {\coq} is able to infer the type $B$ of the object
-defined, so the ``\texttt{return $B$}'' part can be omitted.
-
-The computing rules associated with this construct are the expected ones
-(the notation $t_S\{q/\texttt{p}\}$ stands for the substitution of $p$ by
-$q$ in $t_S$ :)
-
-\begin{eqnarray*}
-\texttt{match $O$ return $b$ with O {\funarrow} $t_O$ | S p {\funarrow} $t_S$ end} &\Longrightarrow& t_O\\
-\texttt{match $S\;q$ return $b$ with O {\funarrow} $t_O$ | S p {\funarrow} $t_S$ end} &\Longrightarrow& t_S\{q/\texttt{p}\}
-\end{eqnarray*}
-
-
-\subsubsection{Example: the predecessor function.}\label{firstpred}
-An example of a definition by case analysis is the function which
-computes the predecessor of any given natural number:
-\begin{alltt}
-Definition pred (n:nat) := match n with
- | O {\funarrow} O
- | S m {\funarrow} m
- end.
-
-Eval simpl in pred 56.
-\it{} = 55
- : nat
-\tt
-Eval simpl in pred 0.
-\it{} = 0
- : nat
-
-\tt{}Eval simpl in fun p {\funarrow} pred (S p).
-\it{} = fun p : nat {\funarrow} p
- : nat {\arrow} nat
-\end{alltt}
-
-As in functional programming, tuples and wild-cards can be used in
-patterns \refmancite{Section \ref{ExtensionsOfCases}}. Such
-definitions are automatically compiled by {\coq} into an expression which
-may contain several nested case expressions. For example, the
-exclusive \emph{or} on booleans can be defined as follows:
-\begin{alltt}
-Definition xorb (b1 b2:bool) :=
- match b1, b2 with
- | false, true {\funarrow} true
- | true, false {\funarrow} true
- | _ , _ {\funarrow} false
- end.
-\end{alltt}
-
-This kind of definition is compiled in {\coq} as follows\footnote{{\coq} uses
-the conditional ``~\citecoq{if $b$ then $a$ else $b$}~'' as an abreviation to
-``~\citecoq{match $b$ with true \funarrow{} $a$ | false \funarrow{} $b$ end}~''.}:
-
-\begin{alltt}
-Print xorb.
-xorb =
-fun b1 b2 : bool {\funarrow}
-if b1 then if b2 then false else true
- else if b2 then true else false
- : bool {\arrow} bool {\arrow} bool
-\end{alltt}
-
-\subsection{Dependent Case Analysis}
-\label{DependentCase}
-
-For a pattern matching construct of the form
-``~\citecoq{match n with \dots end}~'' a more general typing rule
-is obtained considering that the type of the whole expression
-may also depend on \texttt{n}.
- For instance, let us consider some function
-$Q:\texttt{nat}\arrow{}\texttt{Type}$, and $n:\citecoq{nat}$.
-In order to build a term of type $Q\;n$, we can associate
-to the constructor \texttt{O} some term $t_O: Q\;\texttt{O}$ and to
-the pattern ``~\texttt{S p}~'' some term $t_S : Q\;(S\;p)$.
-Notice that the terms $t_O$ and $t_S$ do not have the same type.
-
-The syntax of the \emph{dependent case analysis} and its
-associated typing rule make precise how the resulting
-type depends on the argument of the pattern matching, and
-which constraint holds on the branches of the pattern matching:
-
-\label{Prod-sup-rule}
-\[
-\begin{array}[t]{l}
-Q: \texttt{nat}{\arrow}\texttt{Type}\quad{t_O}:{{Q\;\texttt{O}}} \quad
-\smalljuge{p:\texttt{nat}}{t_p}{{Q\;(\texttt{S}\;p)}} \quad n:\texttt{nat} \\
-\hline
-{\texttt{match \(n\) as \(n\sb{0}\) return \(Q\;n\sb{0}\) with | O \funarrow \(t\sb{O}\) | S p \funarrow \(t\sb{S}\) end}}:{{Q\;n}}
-\end{array}
-\]
-
-
-The interest of this rule of \textsl{dependent} pattern-matching is
-that it can also be read as the following logical principle (when $Q$ has type \citecoq{nat\arrow{}Prop}
-by \texttt{Prop} in the type of $Q$): in order to prove
-that a property $Q$ holds for all $n$, it is sufficient to prove that
-$Q$ holds for {\Z} and that for all $p:\nat$, $Q$ holds for
-$(\SUCC\;p)$. The former, non-dependent version of case analysis can
-be obtained from this latter rule just taking $Q$ as a constant
-function on $n$.
-
-Notice that destructuring $n$ into \citecoq{O} or ``~\citecoq{S p}~''
- doesn't
-make appear in the goal the equalities ``~$n=\citecoq{O}$~''
- and ``~$n=\citecoq{S p}$~''.
-They are ``internalized'' in the rules above (see section~\ref{inversion}.)
-
-\subsubsection{Example: strong specification of the predecessor function.}
-
-In Section~\ref{firstpred}, the predecessor function was defined directly
-as a function from \texttt{nat} to \texttt{nat}. It remains to prove
-that this function has some desired properties. Another way to proceed
-is to, first introduce a specification of what is the predecessor of a
-natural number, under the form of a {\coq} type, then build an inhabitant
-of this type: in other words, a realization of this specification. This way, the correctness
-of this realization is ensured by {\coq}'s type system.
-
-A reasonable specification for $\pred$ is to say that for all $n$
-there exists another $m$ such that either $m=n=0$, or $(\SUCC\;m)$
-is equal to $n$. The function $\pred$ should be just the way to
-compute such an $m$.
-
-\begin{alltt}
-Definition pred_spec (n:nat) :=
- \{m:nat | n=0{\coqand} m=0 {\coqor} n = S m\}.
-
-Definition predecessor : {\prodsym} n:nat, pred_spec n.
- intro n; case n.
-\it{}
- n : nat
- ============================
- pred_spec 0
-
-\tt{} unfold pred_spec;exists 0;auto.
-\it{}
- =========================================
- {\prodsym} n0 : nat, pred_spec (S n0)
-\tt{}
- unfold pred_spec; intro n0; exists n0; auto.
-Defined.
-\end{alltt}
-
-If we print the term built by {\coq}, its dependent pattern-matching structure can be observed:
-
-\begin{alltt}
-predecessor = fun n : nat {\funarrow}
-\textbf{match n as n0 return (pred_spec n0) with}
-\textbf{| O {\funarrow}}
- exist (fun m : nat {\funarrow} 0 = 0 {\coqand} m = 0 {\coqor} 0 = S m) 0
- (or_introl (0 = 1)
- (conj (eq_refl 0) (eq_refl 0)))
-\textbf{| S n0 {\funarrow}}
- exist (fun m : nat {\funarrow} S n0 = 0 {\coqand} m = 0 {\coqor} S n0 = S m) n0
- (or_intror (S n0 = 0 {\coqand} n0 = 0) (eq_refl (S n0)))
-\textbf{end} : {\prodsym} n : nat, \textbf{pred_spec n}
-\end{alltt}
-
-
-Notice that there are many variants to the pattern ``~\texttt{intros \dots; case \dots}~''. Look at for tactics
-``~\texttt{destruct}~'', ``~\texttt{intro \emph{pattern}}~'', etc. in
-the reference manual and/or the book.
-
-\noindent The command \texttt{Extraction} \refmancite{Section
-\ref{ExtractionIdent}} can be used to see the computational
-contents associated to the \emph{certified} function \texttt{predecessor}:
-\begin{alltt}
-Extraction predecessor.
-\it
-(** val predecessor : nat {\arrow} pred_spec **)
-
-let predecessor = function
- | O {\arrow} O
- | S n0 {\arrow} n0
-\end{alltt}
-
-
-\begin{exercise} \label{expand}
-Prove the following theorem:
-\begin{alltt}
-Theorem nat_expand : {\prodsym} n:nat,
- n = match n with
- | 0 {\funarrow} 0
- | S p {\funarrow} S p
- end.
-\end{alltt}
-\end{exercise}
-
-\subsection{Some Examples of Case Analysis}
-\label{CaseScheme}
-The reader will find in the Reference manual all details about
-typing case analysis (chapter 4: Calculus of Inductive Constructions,
-and chapter 15: Extended Pattern-Matching).
-
-The following commented examples will show the different situations to consider.
-
-
-%\subsubsection{General Scheme}
-
-%Case analysis is then the most basic elimination rule that {\coq}
-%provides for inductive types. This rule follows a general schema,
-%valid for any inductive type $I$. First, if $I$ has type
-%``~$\forall\,(z_1:A_1)\ldots(z_r:A_r),S$~'', with $S$ either $\Set$, $\Prop$ or
-%$\Type$, then a case expression on $p$ of type ``~$R\;a_1\ldots a_r$~''
-% inhabits ``~$Q\;a_1\ldots a_r\;p$~''. The types of the branches of the case expression
-%are obtained from the definition of the type in this way: if the type
-%of the $i$-th constructor $c_i$ of $R$ is
-%``~$\forall\, (x_1:T_1)\ldots
-%(x_n:T_n),(R\;q_1\ldots q_r)$~'', then the $i-th$ branch must have the
-%form ``~$c_i\; x_1\; \ldots \;x_n\; \funarrow{}\; t_i$~'' where
-%$$(x_1:T_1),\ldots, (x_n:T_n) \vdash t_i : Q\;q_1\ldots q_r)$$
-% for non-dependent case
-%analysis, and $$(x_1:T_1)\ldots (x_n:T_n)\vdash t_i :Q\;q_1\ldots
-%q_r\;({c}_i\;x_1\;\ldots x_n)$$ for dependent one. In the
-%following section, we illustrate this general scheme for different
-%recursive types.
-%%\textbf{A vérifier}
-
-\subsubsection{The Empty Type}
-
-In a definition by case analysis, there is one branch for each
-introduction rule of the type. Hence, in a definition by case analysis
-on $p:\False$ there are no cases to be considered. In other words, the
-rule of (non-dependent) case analysis for the type $\False$ is
-(for $s$ in \texttt{Prop}, \texttt{Set} or \texttt{Type}):
-
-\begin{center}
-\snregla {\JM{Q}{s}\;\;\;\;\;
- \JM{p}{\False}}
- {\JM{\texttt{match $p$ return $Q$ with end}}{Q}}
-\end{center}
-
-As a corollary, if we could construct an object in $\False$, then it
-could be possible to define an object in any type. The tactic
-\texttt{contradiction} \refmancite{Section \ref{Contradiction}}
-corresponds to the application of the elimination rule above. It
-searches in the context for an absurd hypothesis (this is, a
-hypothesis whose type is $\False$) and then proves the goal by a case
-analysis of it.
-
-\begin{alltt}
-Theorem fromFalse : False \arrow{} 0=1.
-Proof.
- intro H.
- contradiction.
-Qed.
-\end{alltt}
-
-
-In {\coq} the negation is defined as follows :
-
-\begin{alltt}
-Definition not (P:Prop) := P {\arrow} False
-\end{alltt}
-
-The proposition ``~\citecoq{not $A$}~'' is also written ``~$\neg A$~''.
-
-If $A$ and $B$ are propositions, $a$ is a proof of $A$ and
-$H$ is a proof of $\neg A$,
-the term ``~\citecoq{match $H\;a$ return $B$ with end}~'' is a proof term of
-$B$.
-Thus, if your goal is $B$ and you have some hypothesis $H:\neg A$,
-the tactic ``~\citecoq{case $H$}~'' generates a new subgoal with
-statement $A$, as shown by the following example\footnote{Notice that
-$a\coqdiff b$ is just an abreviation for ``~\coqnot a= b~''}.
-
-\begin{alltt}
-Fact Nosense : 0 {\coqdiff} 0 {\arrow} 2 = 3.
-Proof.
- intro H; case H.
-\it
-===========================
- 0 = 0
-\tt
- reflexivity.
-Qed.
-\end{alltt}
-
-The tactic ``~\texttt{absurd $A$}~'' (where $A$ is any proposition),
-is based on the same principle, but
-generates two subgoals: $A$ and $\neg A$, for solving $B$.
-
-\subsubsection{The Equality Type}
-
-Let $A:\Type$, $a$, $b$ of type $A$, and $\pi$ a proof of
-$a=b$. Non dependent case analysis of $\pi$ allows us to
-associate to any proof of ``~$Q\;a$~'' a proof of ``~$Q\;b$~'',
-where $Q:A\arrow{} s$ (where $s\in\{\Prop, \Set, \Type\}$).
-The following term is a proof of ``~$Q\;a\, \arrow{}\, Q\;b$~''.
-
-\begin{alltt}
-fun H : Q a {\funarrow}
- match \(\pi\) in (_ = y) return Q y with
- eq_refl {\funarrow} H
- end
-\end{alltt}
-Notice the header of the \texttt{match} construct.
-It expresses how the resulting type ``~\citecoq{Q y}~'' depends on
-the \emph{type} of \texttt{p}.
-Notice also that in the pattern introduced by the keyword \texttt{in},
-the parameter \texttt{a} in the type ``~\texttt{a = y}~'' must be
-implicit, and replaced by a wildcard '\texttt{\_}'.
-
-
-Therefore, case analysis on a proof of the equality $a=b$
-amounts to replacing all the occurrences of the term $b$ with the term
-$a$ in the goal to be proven. Let us illustrate this through an
-example: the transitivity property of this equality.
-\begin{alltt}
-Theorem trans : {\prodsym} n m p:nat, n=m \arrow{} m=p \arrow{} n=p.
-Proof.
- intros n m p eqnm.
-\it{}
- n : nat
- m : nat
- p : nat
- eqnm : n = m
- ============================
- m = p {\arrow} n = p
-\tt{} case eqnm.
-\it{}
- n : nat
- m : nat
- p : nat
- eqnm : n = m
- ============================
- n = p {\arrow} n = p
-\tt{} trivial.
-Qed.
-\end{alltt}
-
-%\noindent The case analysis on the hypothesis $H:n=m$ yields the
-%tautological subgoal $n=p\rightarrow n=p$, that is directly proven by
-%the tactic \texttt{Trivial}.
-
-\begin{exercise}
-Prove the symmetry property of equality.
-\end{exercise}
-
-Instead of using \texttt{case}, we can use the tactic
-\texttt{rewrite} \refmancite{Section \ref{Rewrite}}. If $H$ is a proof
-of $a=b$, then
-``~\citecoq{rewrite $H$}~''
- performs a case analysis on a proof of $b=a$, obtained by applying a
-symmetry theorem to $H$. This application of symmetry allows us to rewrite
-the equality from left to right, which looks more natural. An optional
-parameter (either \texttt{\arrow{}} or \texttt{$\leftarrow$}) can be used to precise
-in which sense the equality must be rewritten. By default,
-``~\texttt{rewrite} $H$~'' corresponds to ``~\texttt{rewrite \arrow{}} $H$~''
-\begin{alltt}
-Lemma Rw : {\prodsym} x y: nat, y = y * x {\arrow} y * x * x = y.
- intros x y e; do 2 rewrite <- e.
-\it
-1 subgoal
-
- x : nat
- y : nat
- e : y = y * x
- ============================
- y = y
-\tt
- reflexivity.
-Qed.
-\end{alltt}
-
-Notice that, if $H:a=b$, then the tactic ``~\texttt{rewrite $H$}~''
- replaces \textsl{all} the
-occurrences of $a$ by $b$. However, in certain situations we could be
-interested in rewriting some of the occurrences, but not all of them.
-This can be done using the tactic \texttt{pattern} \refmancite{Section
-\ref{Pattern}}. Let us consider yet another example to
-illustrate this.
-
-Let us start with some simple theorems of arithmetic; two of them
-are already proven in the Standard Library, the last is left as an exercise.
-
-\begin{alltt}
-\it
-mult_1_l
- : {\prodsym} n : nat, 1 * n = n
-
-mult_plus_distr_r
- : {\prodsym} n m p : nat, (n + m) * p = n * p + m * p
-
-mult_distr_S : {\prodsym} n p : nat, n * p + p = (S n)* p.
-\end{alltt}
-
-Let us now prove a simple result:
-
-\begin{alltt}
-Lemma four_n : {\prodsym} n:nat, n+n+n+n = 4*n.
-Proof.
- intro n;rewrite <- (mult_1_l n).
-\it
- n : nat
- ============================
- 1 * n + 1 * n + 1 * n + 1 * n = 4 * (1 * n)
-\end{alltt}
-
-We can see that the \texttt{rewrite} tactic call replaced \emph{all}
-the occurrences of \texttt{n} by the term ``~\citecoq{1 * n}~''.
-If we want to do the rewriting ony on the leftmost occurrence of
-\texttt{n}, we can mark this occurrence using the \texttt{pattern}
-tactic:
-
-
-\begin{alltt}
- Undo.
- intro n; pattern n at 1.
- \it
- n : nat
- ============================
- (fun n0 : nat {\funarrow} n0 + n + n + n = 4 * n) n
-\end{alltt}
-Applying the tactic ``~\citecoq{pattern n at 1}~'' allowed us
-to explicitly abstract the first occurrence of \texttt{n} from the
-goal, putting this goal under the form ``~\citecoq{$Q$ n}~'',
-thus pointing to \texttt{rewrite} the particular predicate on $n$
-that we search to prove.
-
-
-\begin{alltt}
- rewrite <- mult_1_l.
-\it
-1 subgoal
-
- n : nat
- ============================
- 1 * n + n + n + n = 4 * n
-\tt
- repeat rewrite mult_distr_S.
-\it
- n : nat
- ============================
- 4 * n = 4 * n
-\tt
- trivial.
-Qed.
-\end{alltt}
-
-\subsubsection{The Predicate $n {\leq} m$}
-
-
-The last but one instance of the elimination schema that we will illustrate is
-case analysis for the predicate $n {\leq} m$:
-
-Let $n$ and $p$ be terms of type \citecoq{nat}, and $Q$ a predicate
-of type $\citecoq{nat}\arrow{}\Prop$.
-If $H$ is a proof of ``~\texttt{n {\coqle} p}~'',
-$H_0$ a proof of ``~\texttt{$Q$ n}~'' and
-$H_S$ a proof of the statement ``~\citecoq{{\prodsym}m:nat, n {\coqle} m {\arrow} Q (S m)}~'',
-then the term
-\begin{alltt}
-match H in (_ {\coqle} q) return (Q q) with
- | le_n {\funarrow} H0
- | le_S m Hm {\funarrow} HS m Hm
-end
-\end{alltt}
- is a proof term of ``~\citecoq{$Q$ $p$}~''.
-
-
-The two patterns of this \texttt{match} construct describe
-all possible forms of proofs of ``~\citecoq{n {\coqle} m}~'' (notice
-again that the general parameter \texttt{n} is implicit in
- the ``~\texttt{in \dots}~''
-clause and is absent from the match patterns.
-
-
-Notice that the choice of introducing some of the arguments of the
-predicate as being general parameters in its definition has
-consequences on the rule of case analysis that is derived. In
-particular, the type $Q$ of the object defined by the case expression
-only depends on the indexes of the predicate, and not on the general
-parameters. In the definition of the predicate $\leq$, the first
-argument of this relation is a general parameter of the
-definition. Hence, the predicate $Q$ to be proven only depends on the
-second argument of the relation. In other words, the integer $n$ is
-also a general parameter of the rule of case analysis.
-
-An example of an application of this rule is the following theorem,
-showing that any integer greater or equal than $1$ is the successor of another
-natural number:
-
-\begin{alltt}
-Lemma predecessor_of_positive :
- {\prodsym} n, 1 {\coqle} n {\arrow} {\exsym} p:nat, n = S p.
-Proof.
- intros n H;case H.
-\it
- n : nat
- H : 1 {\coqle} n
- ============================
- {\exsym} p : nat, 1 = S p
-\tt
- exists 0; trivial.
-\it
-
- n : nat
- H : 1 {\coqle} n
- ============================
- {\prodsym} m : nat, 0 {\coqle} m {\arrow} {\exsym} p : nat, S m = S p
-\tt
- intros m _ .
- exists m.
- trivial.
-Qed.
-\end{alltt}
-
-
-\subsubsection{Vectors}
-
-The \texttt{vector} polymorphic and dependent family of types will
-give an idea of the most general scheme of pattern-matching.
-
-For instance, let us define a function for computing the tail of
-any vector. Notice that we shall build a \emph{total} function,
-by considering that the tail of an empty vector is this vector itself.
-In that sense, it will be slightly different from the \texttt{Vtail}
-function of the Standard Library, which is defined only for vectors
-of type ``~\citecoq{vector $A$ (S $n$)}~''.
-
-The header of the function we want to build is the following:
-
-\begin{verbatim}
-Definition Vtail_total
- (A : Type) (n : nat) (v : vector A n) : vector A (pred n):=
-\end{verbatim}
-
-Since the branches will not have the same type
-(depending on the parameter \texttt{n}),
-the body of this function is a dependent pattern matching on
-\citecoq{v}.
-So we will have :
-\begin{verbatim}
-match v in (vector _ n0) return (vector A (pred n0)) with
-\end{verbatim}
-
-The first branch deals with the constructor \texttt{Vnil} and must
-return a value in ``~\citecoq{vector A (pred 0)}~'', convertible
-to ``~\citecoq{vector A 0}~''. So, we propose:
-\begin{alltt}
-| Vnil {\funarrow} Vnil A
-\end{alltt}
-
-The second branch considers a vector in ``~\citecoq{vector A (S n0)}~''
-of the form
-``~\citecoq{Vcons A n0 v0}~'', with ``~\citecoq{v0:vector A n0}~'',
-and must return a value of type ``~\citecoq{vector A (pred (S n0))}~'',
-which is convertible to ``~\citecoq{vector A n0}~''.
-This second branch is thus :
-\begin{alltt}
-| Vcons _ n0 v0 {\funarrow} v0
-\end{alltt}
-
-Here is the full definition:
-
-\begin{alltt}
-Definition Vtail_total
- (A : Type) (n : nat) (v : vector A n) : vector A (pred n):=
-match v in (vector _ n0) return (vector A (pred n0)) with
-| Vnil {\funarrow} Vnil A
-| Vcons _ n0 v0 {\funarrow} v0
-end.
-\end{alltt}
-
-
-\subsection{Case Analysis and Logical Paradoxes}
-
-In the previous section we have illustrated the general scheme for
-generating the rule of case analysis associated to some recursive type
-from the definition of the type. However, if the logical soundness is
-to be preserved, certain restrictions to this schema are
-necessary. This section provides a brief explanation of these
-restrictions.
-
-
-\subsubsection{The Positivity Condition}
-\label{postypes}
-
-In order to make sense of recursive types as types closed under their
-introduction rules, a constraint has to be imposed on the possible
-forms of such rules. This constraint, known as the
-\textsl{positivity condition}, is necessary to prevent the user from
-naively introducing some recursive types which would open the door to
-logical paradoxes. An example of such a dangerous type is the
-``inductive type'' \citecoq{Lambda}, whose only constructor is
-\citecoq{lambda} of type \citecoq{(Lambda\arrow False)\arrow Lambda}.
- Following the pattern
-given in Section \ref{CaseScheme}, the rule of (non dependent) case
-analysis for \citecoq{Lambda} would be the following:
-
-\begin{center}
-\snregla {\JM{Q}{\Prop}\;\;\;\;\;
- \JM{p}{\texttt{Lambda}}\;\;\;\;\;
- {h : {\texttt{Lambda}}\arrow\False\; \vdash\; t\,:\,Q}}
- {\JM{\citecoq{match $p$ return $Q$ with lambda h {\funarrow} $t$ end}}{Q}}
-\end{center}
-
-In order to avoid paradoxes, it is impossible to construct
-the type \citecoq{Lambda} in {\coq}:
-
-\begin{alltt}
-Inductive Lambda : Set :=
- lambda : (Lambda {\arrow} False) {\arrow} Lambda.
-\it
-Error: Non strictly positive occurrence of "Lambda" in
- "(Lambda {\arrow} False) {\arrow} Lambda"
-\end{alltt}
-
-In order to explain this danger, we
-will declare some constants for simulating the construction of
-\texttt{Lambda} as an inductive type.
-
-Let us open some section, and declare two variables, the first one for
-\texttt{Lambda}, the other for the constructor \texttt{lambda}.
-
-\begin{alltt}
-Section Paradox.
-Variable Lambda : Set.
-Variable lambda : (Lambda {\arrow} False) {\arrow}Lambda.
-\end{alltt}
-
-Since \texttt{Lambda} is not a truely inductive type, we can't use
-the \texttt{match} construct. Nevertheless, we can simulate it by a
-variable \texttt{matchL} such that the term
-``~\citecoq{matchL $l$ $Q$ (fun $h$ : Lambda {\arrow} False {\funarrow} $t$)}~''
-should be understood as
-``~\citecoq{match $l$ return $Q$ with | lambda h {\funarrow} $t$)}~''
-
-
-\begin{alltt}
-Variable matchL : Lambda {\arrow}
- {\prodsym} Q:Prop, ((Lambda {\arrow}False) {\arrow} Q) {\arrow}
- Q.
-\end{alltt}
-
->From these constants, it is possible to define application by case
-analysis. Then, through auto-application, the well-known looping term
-$(\lambda x.(x\;x)\;\lambda x.(x\;x))$ provides a proof of falsehood.
-
-\begin{alltt}
-Definition application (f x: Lambda) :False :=
- matchL f False (fun h {\funarrow} h x).
-
-Definition Delta : Lambda :=
- lambda (fun x : Lambda {\funarrow} application x x).
-
-Definition loop : False := application Delta Delta.
-
-Theorem two_is_three : 2 = 3.
-Proof.
- elim loop.
-Qed.
-
-End Paradox.
-\end{alltt}
-
-\noindent This example can be seen as a formulation of Russell's
-paradox in type theory associating $(\textsl{application}\;x\;x)$ to the
-formula $x\not\in x$, and \textsl{Delta} to the set $\{ x \mid
-x\not\in x\}$. If \texttt{matchL} would satisfy the reduction rule
-associated to case analysis, that is,
-$$ \citecoq{matchL (lambda $f$) $Q$ $h$} \Longrightarrow h\;f$$
-then the term \texttt{loop}
-would compute into itself. This is not actually surprising, since the
-proof of the logical soundness of {\coq} strongly lays on the property
-that any well-typed term must terminate. Hence, non-termination is
-usually a synonymous of inconsistency.
-
-%\paragraph{} In this case, the construction of a non-terminating
-%program comes from the so-called \textsl{negative occurrence} of
-%$\Lambda$ in the type of the constructor $\lambda$. In order to be
-%admissible for {\coq}, all the occurrences of the recursive type in its
-%own introduction rules must be positive, in the sense on the following
-%definition:
-%
-%\begin{enumerate}
-%\item $R$ is positive in $(R\;\vec{t})$;
-%\item $R$ is positive in $(x: A)C$ if it does not
-%occur in $A$ and $R$ is positive in $C$;
-%\item if $P\equiv (\vec{x}:\vec{T})Q$, then $R$ is positive in $(P
-%\rightarrow C)$ if $R$ does not occur in $\vec{T}$, $R$ is positive
-%in $C$, and either
-%\begin{enumerate}
-%\item $Q\equiv (R\;\vec{q})$ or
-%\item $Q\equiv (J\;\vec{t})$, \label{relax}
-% where $J$ is a recursive type, and for any term $t_i$ either :
-% \begin{enumerate}
-% \item $R$ does not occur in $t_i$, or
-% \item $t_i\equiv (z:\vec{Z})(R\;\vec{q})$, $R$ does not occur
-% in $\vec{Z}$, $t_i$ instantiates a general
-% parameter of $J$, and this parameter is positive in the
-% arguments of the constructors of $J$.
-% \end{enumerate}
-%\end{enumerate}
-%\end{enumerate}
-%\noindent Those types obtained by erasing option (\ref{relax}) in the
-%definition above are called \textsl{strictly positive} types.
-
-
-\subsubsection*{Remark} In this case, the construction of a non-terminating
-program comes from the so-called \textsl{negative occurrence} of
-\texttt{Lambda} in the argument of the constructor \texttt{lambda}.
-
-The reader will find in the Reference Manual a complete formal
-definition of the notions of \emph{positivity condition} and
-\emph{strict positivity} that an inductive definition must satisfy.
-
-
-%In order to be
-%admissible for {\coq}, the type $R$ must be positive in the types of the
-%arguments of its own introduction rules, in the sense on the following
-%definition:
-
-%\textbf{La définition du manuel de référence est plus complexe:
-%la recopier ou donner seulement des exemples?
-%}
-%\begin{enumerate}
-%\item $R$ is positive in $T$ if $R$ does not occur in $T$;
-%\item $R$ is positive in $(R\;\vec{t})$ if $R$ does not occur in $\vec{t}$;
-%\item $R$ is positive in $(x:A)C$ if it does not
-% occur in $A$ and $R$ is positive in $C$;
-%\item $R$ is positive in $(J\;\vec{t})$, \label{relax}
-% if $J$ is a recursive type, and for any term $t_i$ either :
-% \begin{enumerate}
-% \item $R$ does not occur in $t_i$, or
-% \item $R$ is positive in $t_i$, $t_i$ instantiates a general
-% parameter of $J$, and this parameter is positive in the
-% arguments of the constructors of $J$.
-% \end{enumerate}
-%\end{enumerate}
-
-%\noindent When we can show that $R$ is positive without using the item
-%(\ref{relax}) of the definition above, then we say that $R$ is
-%\textsl{strictly positive}.
-
-%\textbf{Changer le discours sur les ordinaux}
-
-Notice that the positivity condition does not forbid us to
-put functional recursive
-arguments in the constructors.
-
-For instance, let us consider the type of infinitely branching trees,
-with labels in \texttt{Z}.
-\begin{alltt}
-Require Import ZArith.
-
-Inductive itree : Set :=
-| ileaf : itree
-| inode : Z {\arrow} (nat {\arrow} itree) {\arrow} itree.
-\end{alltt}
-
-In this representation, the $i$-th child of a tree
-represented by ``~\texttt{inode $z$ $s$}~'' is obtained by applying
-the function $s$ to $i$.
-The following definitions show how to construct a tree with a single
-node, a tree of height 1 and a tree of height 2:
-
-\begin{alltt}
-Definition isingle l := inode l (fun i {\funarrow} ileaf).
-
-Definition t1 := inode 0 (fun n {\funarrow} isingle (Z.of_nat n)).
-
-Definition t2 :=
- inode 0
- (fun n : nat {\funarrow}
- inode (Z.of_nat n)
- (fun p {\funarrow} isingle (Z.of_nat (n*p)))).
-\end{alltt}
-
-
-Let us define a preorder on infinitely branching trees.
- In order to compare two non-leaf trees,
-it is necessary to compare each of their children
- without taking care of the order in which they
-appear:
-
-\begin{alltt}
-Inductive itree_le : itree{\arrow} itree {\arrow} Prop :=
- | le_leaf : {\prodsym} t, itree_le ileaf t
- | le_node : {\prodsym} l l' s s',
- Z.le l l' {\arrow}
- ({\prodsym} i, {\exsym} j:nat, itree_le (s i) (s' j)){\arrow}
- itree_le (inode l s) (inode l' s').
-
-\end{alltt}
-
-Notice that a call to the predicate \texttt{itree\_le} appears as
-a general parameter of the inductive type \texttt{ex} (see Sect.\ref{ex-def}).
-This kind of definition is accepted by {\coq}, but may lead to some
-difficulties, since the induction principle automatically
-generated by the system
-is not the most appropriate (see chapter 14 of~\cite{coqart} for a detailed
-explanation).
-
-
-The following definition, obtained by
-skolemising the
-proposition \linebreak $\forall\, i,\exists\, j,(\texttt{itree\_le}\;(s\;i)\;(s'\;j))$ in
-the type of \texttt{itree\_le}, does not present this problem:
-
-
-\begin{alltt}
-Inductive itree_le' : itree{\arrow} itree {\arrow} Prop :=
- | le_leaf' : {\prodsym} t, itree_le' ileaf t
- | le_node' : {\prodsym} l l' s s' g,
- Z.le l l' {\arrow}
- ({\prodsym} i, itree_le' (s i) (s' (g i))) {\arrow}
- itree_le' (inode l s) (inode l' s').
-
-\end{alltt}
-\iffalse
-\begin{alltt}
-Lemma t1_le'_t2 : itree_le' t1 t2.
-Proof.
- unfold t1, t2.
- constructor 2 with (fun i : nat {\funarrow} 2 * i).
- auto with zarith.
- unfold isingle;
- intro i ; constructor 2 with (fun i :nat {\funarrow} i).
- auto with zarith.
- constructor .
-Qed.
-\end{alltt}
-\fi
-
-%In general, strictly positive definitions are preferable to only
-%positive ones. The reason is that it is sometimes difficult to derive
-%structural induction combinators for the latter ones. Such combinators
-%are automatically generated for strictly positive types, but not for
-%the only positive ones. Nevertheless, sometimes non-strictly positive
-%definitions provide a smarter or shorter way of declaring a recursive
-%type.
-
-Another example is the type of trees
- of unbounded width, in which a recursive subterm
-\texttt{(ltree A)} instantiates the type of polymorphic lists:
-
-\begin{alltt}
-Require Import List.
-
-Inductive ltree (A:Set) : Set :=
- lnode : A {\arrow} list (ltree A) {\arrow} ltree A.
-\end{alltt}
-
-This declaration can be transformed
-adding an extra type to the definition, as was done in Section
-\ref{MutuallyDependent}.
-
-
-\subsubsection{Impredicative Inductive Types}
-
-An inductive type $I$ inhabiting a universe $U$ is \textsl{predicative}
-if the introduction rules of $I$ do not make a universal
-quantification on a universe containing $U$. All the recursive types
-previously introduced are examples of predicative types. An example of
-an impredicative one is the following type:
-%\textsl{exT}, the dependent product
-%of a certain set (or proposition) $x$, and a proof of a property $P$
-%about $x$.
-
-%\begin{alltt}
-%Print exT.
-%\end{alltt}
-%\textbf{ttention, EXT c'est ex!}
-%\begin{alltt}
-%Check (exists P:Prop, P {\arrow} not P).
-%\end{alltt}
-
-%This type is useful for expressing existential quantification over
-%types, like ``there exists a proposition $x$ such that $(P\;x)$''
-%---written $(\textsl{EXT}\; x:Prop \mid (P\;x))$ in {\coq}. However,
-
-\begin{alltt}
-Inductive prop : Prop :=
- prop_intro : Prop {\arrow} prop.
-\end{alltt}
-
-Notice
-that the constructor of this type can be used to inject any
-proposition --even itself!-- into the type.
-
-\begin{alltt}
-Check (prop_intro prop).\it
-prop_intro prop
- : prop
-\end{alltt}
-
-A careless use of such a
-self-contained objects may lead to a variant of Burali-Forti's
-paradox. The construction of Burali-Forti's paradox is more
-complicated than Russel's one, so we will not describe it here, and
-point the interested reader to \cite{Bar98,Coq86}.
-
-
-Another example is the second order existential quantifier for propositions:
-
-\begin{alltt}
-Inductive ex_Prop (P : Prop {\arrow} Prop) : Prop :=
- exP_intro : {\prodsym} X : Prop, P X {\arrow} ex_Prop P.
-\end{alltt}
-
-%\begin{alltt}
-%(*
-%Check (match prop_inject with (prop_intro p _) {\funarrow} p end).
-
-%Error: Incorrect elimination of "prop_inject" in the inductive type
-% ex
-%The elimination predicate ""fun _ : prop {\funarrow} Prop" has type
-% "prop {\arrow} Type"
-%It should be one of :
-% "Prop"
-
-%Elimination of an inductive object of sort : "Prop"
-%is not allowed on a predicate in sort : "Type"
-%because non-informative objects may not construct informative ones.
-
-%*)
-%Print prop_inject.
-
-%(*
-%prop_inject =
-%prop_inject = prop_intro prop (fun H : prop {\funarrow} H)
-% : prop
-%*)
-%\end{alltt}
-
-% \textbf{Et par ça?
-%}
-
-Notice that predicativity on sort \citecoq{Set} forbids us to build
-the following definitions.
-
-
-\begin{alltt}
-Inductive aSet : Set :=
- aSet_intro: Set {\arrow} aSet.
-
-\it{}User error: Large non-propositional inductive types must be in Type
-\tt
-Inductive ex_Set (P : Set {\arrow} Prop) : Set :=
- exS_intro : {\prodsym} X : Set, P X {\arrow} ex_Set P.
-
-\it{}User error: Large non-propositional inductive types must be in Type
-\end{alltt}
-
-Nevertheless, one can define types like \citecoq{aSet} and \citecoq{ex\_Set}, as inhabitants of \citecoq{Type}.
-
-\begin{alltt}
-Inductive ex_Set (P : Set {\arrow} Prop) : Type :=
- exS_intro : {\prodsym} X : Set, P X {\arrow} ex_Set P.
-\end{alltt}
-
-In the following example, the inductive type \texttt{typ} can be defined,
-but the term associated with the interactive Definition of
-\citecoq{typ\_inject} is incompatible with {\coq}'s hierarchy of universes:
-
-
-\begin{alltt}
-Inductive typ : Type :=
- typ_intro : Type {\arrow} typ.
-
-Definition typ_inject: typ.
- split; exact typ.
-\it Proof completed
-
-\tt{}Defined.
-\it Error: Universe Inconsistency.
-\tt
-Abort.
-\end{alltt}
-
-One possible way of avoiding this new source of paradoxes is to
-restrict the kind of eliminations by case analysis that can be done on
-impredicative types. In particular, projections on those universes
-equal or bigger than the one inhabited by the impredicative type must
-be forbidden \cite{Coq86}. A consequence of this restriction is that it
-is not possible to define the first projection of the type
-``~\citecoq{ex\_Prop $P$}~'':
-\begin{alltt}
-Check (fun (P:Prop{\arrow}Prop)(p: ex_Prop P) {\funarrow}
- match p with exP_intro X HX {\funarrow} X end).
-\it
-Error:
-Incorrect elimination of "p" in the inductive type
-"ex_Prop", the return type has sort "Type" while it should be
-"Prop"
-
-Elimination of an inductive object of sort "Prop"
-is not allowed on a predicate in sort "Type"
-because proofs can be eliminated only to build proofs.
-\end{alltt}
-
-%In order to explain why, let us consider for example the following
-%impredicative type \texttt{ALambda}.
-%\begin{alltt}
-%Inductive ALambda : Set :=
-% alambda : (A:Set)(A\arrow{}False)\arrow{}ALambda.
-%
-%Definition Lambda : Set := ALambda.
-%Definition lambda : (ALambda\arrow{}False)\arrow{}ALambda := (alambda ALambda).
-%Lemma CaseAL : (Q:Prop)ALambda\arrow{}((ALambda\arrow{}False)\arrow{}Q)\arrow{}Q.
-%\end{alltt}
-%
-%This type contains all the elements of the dangerous type $\Lambda$
-%described at the beginning of this section. Try to construct the
-%non-ending term $(\Delta\;\Delta)$ as an object of
-%\texttt{ALambda}. Why is it not possible?
-
-\subsubsection{Extraction Constraints}
-
-There is a final constraint on case analysis that is not motivated by
-the potential introduction of paradoxes, but for compatibility reasons
-with {\coq}'s extraction mechanism \refmancite{Appendix
-\ref{CamlHaskellExtraction}}. This mechanism is based on the
-classification of basic types into the universe $\Set$ of sets and the
-universe $\Prop$ of propositions. The objects of a type in the
-universe $\Set$ are considered as relevant for computation
-purposes. The objects of a type in $\Prop$ are considered just as
-formalised comments, not necessary for execution. The extraction
-mechanism consists in erasing such formal comments in order to obtain
-an executable program. Hence, in general, it is not possible to define
-an object in a set (that should be kept by the extraction mechanism)
-by case analysis of a proof (which will be thrown away).
-
-Nevertheless, this general rule has an exception which is important in
-practice: if the definition proceeds by case analysis on a proof of a
-\textsl{singleton proposition} or an empty type (\emph{e.g.} \texttt{False}),
- then it is allowed. A singleton
-proposition is a non-recursive proposition with a single constructor
-$c$, all whose arguments are proofs. For example, the propositional
-equality and the conjunction of two propositions are examples of
-singleton propositions.
-
-%From the point of view of the extraction
-%mechanism, such types are isomorphic to a type containing a single
-%object $c$, so a definition $\Case{x}{c \Rightarrow b}$ is
-%directly replaced by $b$ as an extra optimisation.
-
-\subsubsection{Strong Case Analysis on Proofs}
-
-One could consider allowing
- to define a proposition $Q$ by case
-analysis on the proofs of another recursive proposition $R$. As we
-will see in Section \ref{Discrimination}, this would enable one to prove that
-different introduction rules of $R$ construct different
-objects. However, this property would be in contradiction with the principle
-of excluded middle of classical logic, because this principle entails
-that the proofs of a proposition cannot be distinguished. This
-principle is not provable in {\coq}, but it is frequently introduced by
-the users as an axiom, for reasoning in classical logic. For this
-reason, the definition of propositions by case analysis on proofs is
- not allowed in {\coq}.
-
-\begin{alltt}
-
-Definition comes_from_the_left (P Q:Prop)(H:P{\coqor}Q): Prop :=
- match H with
- | or_introl p {\funarrow} True
- | or_intror q {\funarrow} False
- end.
-\it
-Error:
-Incorrect elimination of "H" in the inductive type
-"or", the return type has sort "Type" while it should be
-"Prop"
-
-Elimination of an inductive object of sort "Prop"
-is not allowed on a predicate in sort "Type"
-because proofs can be eliminated only to build proofs.
-
-\end{alltt}
-
-On the other hand, if we replace the proposition $P {\coqor} Q$ with
-the informative type $\{P\}+\{Q\}$, the elimination is accepted:
-
-\begin{alltt}
-Definition comes_from_the_left_sumbool
- (P Q:Prop)(x:\{P\} + \{Q\}): Prop :=
- match x with
- | left p {\funarrow} True
- | right q {\funarrow} False
- end.
-\end{alltt}
-
-
-\subsubsection{Summary of Constraints}
-
-To end with this section, the following table summarizes which
-universe $U_1$ may inhabit an object of type $Q$ defined by case
-analysis on $x:R$, depending on the universe $U_2$ inhabited by the
-inductive types $R$.\footnote{In the box indexed by $U_1=\citecoq{Type}$
-and $U_2=\citecoq{Set}$, the answer ``yes'' takes into account the
-predicativity of sort \citecoq{Set}. If you are working with the
-option ``impredicative-set'', you must put in this box the
-condition ``if $R$ is predicative''.}
-
-
-\begin{center}
-%%% displease hevea less by using * in multirow rather than \LL
-\renewcommand{\multirowsetup}{\centering}
-%\newlength{\LL}
-%\settowidth{\LL}{$x : R : U_2$}
-\begin{tabular}{|c|c|c|c|c|}
-\hline
-\multirow{5}*{$x : R : U_2$} &
-\multicolumn{4}{|c|}{$Q : U_1$}\\
-\hline
-& &\textsl{Set} & \textsl{Prop} & \textsl{Type}\\
-\cline{2-5}
-&\textsl{Set} & yes & yes & yes\\
-\cline{2-5}
-&\textsl{Prop} & if $R$ singleton & yes & no\\
-\cline{2-5}
-&\textsl{Type} & yes & yes & yes\\
-\hline
-\end{tabular}
-\end{center}
-
-\section{Some Proof Techniques Based on Case Analysis}
-\label{CaseTechniques}
-
-In this section we illustrate the use of case analysis as a proof
-principle, explaining the proof techniques behind three very useful
-{\coq} tactics, called \texttt{discriminate}, \texttt{injection} and
-\texttt{inversion}.
-
-\subsection{Discrimination of introduction rules}
-\label{Discrimination}
-
-In the informal semantics of recursive types described in Section
-\ref{Introduction} it was said that each of the introduction rules of a
-recursive type is considered as being different from all the others.
-It is possible to capture this fact inside the logical system using
-the propositional equality. We take as example the following theorem,
-stating that \textsl{O} constructs a natural number different
-from any of those constructed with \texttt{S}.
-
-\begin{alltt}
-Theorem S_is_not_O : {\prodsym} n, S n {\coqdiff} 0.
-\end{alltt}
-
-In order to prove this theorem, we first define a proposition by case
-analysis on natural numbers, so that the proposition is true for {\Z}
-and false for any natural number constructed with {\SUCC}. This uses
-the empty and singleton type introduced in Sections \ref{Introduction}.
-
-\begin{alltt}
-Definition Is_zero (x:nat):= match x with
- | 0 {\funarrow} True
- | _ {\funarrow} False
- end.
-\end{alltt}
-
-\noindent Then, we prove the following lemma:
-
-\begin{alltt}
-Lemma O_is_zero : {\prodsym} m, m = 0 {\arrow} Is_zero m.
-Proof.
- intros m H; subst m.
-\it{}
-================
- Is_zero 0
-\tt{}
-simpl;trivial.
-Qed.
-\end{alltt}
-
-\noindent Finally, the proof of \texttt{S\_is\_not\_O} follows by the
-application of the previous lemma to $S\;n$.
-
-
-\begin{alltt}
-
- red; intros n Hn.
- \it{}
- n : nat
- Hn : S n = 0
- ============================
- False \tt
-
- apply O_is_zero with (m := S n).
- assumption.
-Qed.
-\end{alltt}
-
-
-The tactic \texttt{discriminate} \refmancite{Section \ref{Discriminate}} is
-a special-purpose tactic for proving disequalities between two
-elements of a recursive type introduced by different constructors. It
-generalizes the proof method described here for natural numbers to any
-[co]-inductive type. This tactic is also capable of proving disequalities
-where the difference is not in the constructors at the head of the
-terms, but deeper inside them. For example, it can be used to prove
-the following theorem:
-
-\begin{alltt}
-Theorem disc2 : {\prodsym} n, S (S n) {\coqdiff} 1.
-Proof.
- intros n Hn; discriminate.
-Qed.
-\end{alltt}
-
-When there is an assumption $H$ in the context stating a false
-equality $t_1=t_2$, \texttt{discriminate} solves the goal by first
-proving $(t_1\not =t_2)$ and then reasoning by absurdity with respect
-to $H$:
-
-\begin{alltt}
-Theorem disc3 : {\prodsym} n, S (S n) = 0 {\arrow} {\prodsym} Q:Prop, Q.
-Proof.
- intros n Hn Q.
- discriminate.
-Qed.
-\end{alltt}
-
-\noindent In this case, the proof proceeds by absurdity with respect
-to the false equality assumed, whose negation is proved by
-discrimination.
-
-\subsection{Injectiveness of introduction rules}
-
-Another useful property about recursive types is the
-\textsl{injectiveness} of introduction rules, i.e., that whenever two
-objects were built using the same introduction rule, then this rule
-should have been applied to the same element. This can be stated
-formally using the propositional equality:
-
-\begin{alltt}
-Theorem inj : {\prodsym} n m, S n = S m {\arrow} n = m.
-Proof.
-\end{alltt}
-
-\noindent This theorem is just a corollary of a lemma about the
-predecessor function:
-
-\begin{alltt}
- Lemma inj_pred : {\prodsym} n m, n = m {\arrow} pred n = pred m.
- Proof.
- intros n m eq_n_m.
- rewrite eq_n_m.
- trivial.
- Qed.
-\end{alltt}
-\noindent Once this lemma is proven, the theorem follows directly
-from it:
-\begin{alltt}
- intros n m eq_Sn_Sm.
- apply inj_pred with (n:= S n) (m := S m); assumption.
-Qed.
-\end{alltt}
-
-This proof method is implemented by the tactic \texttt{injection}
-\refmancite{Section \ref{injection}}. This tactic is applied to
-a term $t$ of type ``~$c\;{t_1}\;\dots\;t_n = c\;t'_1\;\dots\;t'_n$~'', where $c$ is some constructor of
-an inductive type. The tactic \texttt{injection} is applied as deep as
-possible to derive the equality of all pairs of subterms of $t_i$ and $t'_i$
-placed in the same position. All these equalities are put as antecedents
-of the current goal.
-
-
-
-Like \texttt{discriminate}, the tactic \citecoq{injection}
-can be also applied if $x$ does not
-occur in a direct sub-term, but somewhere deeper inside it. Its
-application may leave some trivial goals that can be easily solved
-using the tactic \texttt{trivial}.
-
-\begin{alltt}
-
- Lemma list_inject : {\prodsym} (A:Type)(a b :A)(l l':list A),
- a :: b :: l = b :: a :: l' {\arrow} a = b {\coqand} l = l'.
-Proof.
- intros A a b l l' e.
-
-
-\it
- e : a :: b :: l = b :: a :: l'
- ============================
- a = b {\coqand} l = l'
-\tt
- injection e.
-\it
- ============================
- l = l' {\arrow} b = a {\arrow} a = b {\arrow} a = b {\coqand} l = l'
-
-\tt{} auto.
-Qed.
-\end{alltt}
-
-\subsection{Inversion Techniques}\label{inversion}
-
-In section \ref{DependentCase}, we motivated the rule of dependent case
-analysis as a way of internalizing the informal equalities $n=O$ and
-$n=\SUCC\;p$ associated to each case. This internalisation
-consisted in instantiating $n$ with the corresponding term in the type
-of each branch. However, sometimes it could be better to internalise
-these equalities as extra hypotheses --for example, in order to use
-the tactics \texttt{rewrite}, \texttt{discriminate} or
-\texttt{injection} presented in the previous sections. This is
-frequently the case when the element analysed is denoted by a term
-which is not a variable, or when it is an object of a particular
-instance of a recursive family of types. Consider for example the
-following theorem:
-
-\begin{alltt}
-Theorem not_le_Sn_0 : {\prodsym} n:nat, ~ (S n {\coqle} 0).
-\end{alltt}
-
-\noindent Intuitively, this theorem should follow by case analysis on
-the hypothesis $H:(S\;n\;\leq\;\Z)$, because no introduction rule allows
-to instantiate the arguments of \citecoq{le} with respectively a successor
-and zero. However, there
-is no way of capturing this with the typing rule for case analysis
-presented in section \ref{Introduction}, because it does not take into
-account what particular instance of the family the type of $H$ is.
-Let us try it:
-\begin{alltt}
-Proof.
- red; intros n H; case H.
-\it 2 subgoals
-
- n : nat
- H : S n {\coqle} 0
- ============================
- False
-
-subgoal 2 is:
- {\prodsym} m : nat, S n {\coqle} m {\arrow} False
-\tt
-Undo.
-\end{alltt}
-
-\noindent What is necessary here is to make available the equalities
-``~$\SUCC\;n = \Z$~'' and ``~$\SUCC\;m = \Z$~''
- as extra hypotheses of the
-branches, so that the goal can be solved using the
-\texttt{Discriminate} tactic. In order to obtain the desired
-equalities as hypotheses, let us prove an auxiliary lemma, that our
-theorem is a corollary of:
-
-\begin{alltt}
- Lemma not_le_Sn_0_with_constraints :
- {\prodsym} n p , S n {\coqle} p {\arrow} p = 0 {\arrow} False.
- Proof.
- intros n p H; case H .
-\it
-2 subgoals
-
- n : nat
- p : nat
- H : S n {\coqle} p
- ============================
- S n = 0 {\arrow} False
-
-subgoal 2 is:
- {\prodsym} m : nat, S n {\coqle} m {\arrow} S m = 0 {\arrow} False
-\tt
- intros;discriminate.
- intros;discriminate.
-Qed.
-\end{alltt}
-\noindent Our main theorem can now be solved by an application of this lemma:
-\begin{alltt}
-Show.
-\it
-2 subgoals
-
- n : nat
- p : nat
- H : S n {\coqle} p
- ============================
- S n = 0 {\arrow} False
-
-subgoal 2 is:
- {\prodsym} m : nat, S n {\coqle} m {\arrow} S m = 0 {\arrow} False
-\tt
- eapply not_le_Sn_0_with_constraints; eauto.
-Qed.
-\end{alltt}
-
-
-The general method to address such situations consists in changing the
-goal to be proven into an implication, introducing as preconditions
-the equalities needed to eliminate the cases that make no
-sense. This proof technique is implemented by the tactic
-\texttt{inversion} \refmancite{Section \ref{Inversion}}. In order
-to prove a goal $G\;\vec{q}$ from an object of type $R\;\vec{t}$,
-this tactic automatically generates a lemma $\forall, \vec{x}.
-(R\;\vec{x}) \rightarrow \vec{x}=\vec{t}\rightarrow \vec{B}\rightarrow
-(G\;\vec{q})$, where the list of propositions $\vec{B}$ correspond to
-the subgoals that cannot be directly proven using
-\texttt{discriminate}. This lemma can either be saved for later
-use, or generated interactively. In this latter case, the subgoals
-yielded by the tactic are the hypotheses $\vec{B}$ of the lemma. If the
-lemma has been stored, then the tactic \linebreak
- ``~\citecoq{inversion \dots using \dots}~'' can be
-used to apply it.
-
-Let us show both techniques on our previous example:
-
-\subsubsection{Interactive mode}
-
-\begin{alltt}
-Theorem not_le_Sn_0' : {\prodsym} n:nat, ~ (S n {\coqle} 0).
-Proof.
- red; intros n H ; inversion H.
-Qed.
-\end{alltt}
-
-
-\subsubsection{Static mode}
-
-\begin{alltt}
-
-Derive Inversion le_Sn_0_inv with ({\prodsym} n :nat, S n {\coqle} 0).
-Theorem le_Sn_0'' : {\prodsym} n p : nat, ~ S n {\coqle} 0 .
-Proof.
- intros n p H;
- inversion H using le_Sn_0_inv.
-Qed.
-\end{alltt}
-
-
-In the example above, all the cases are solved using discriminate, so
-there remains no subgoal to be proven (i.e. the list $\vec{B}$ is
-empty). Let us present a second example, where this list is not empty:
-
-
-\begin{alltt}
-TTheorem le_reverse_rules :
- {\prodsym} n m:nat, n {\coqle} m {\arrow}
- n = m {\coqor}
- {\exsym} p, n {\coqle} p {\coqand} m = S p.
-Proof.
- intros n m H; inversion H.
-\it
-2 subgoals
-
-
-
-
- n : nat
- m : nat
- H : n {\coqle} m
- H0 : n = m
- ============================
- m = m {\coqor} ({\exsym} p : nat, m {\coqle} p {\coqand} m = S p)
-
-subgoal 2 is:
- n = S m0 {\coqor} ({\exsym} p : nat, n {\coqle} p {\coqand} S m0 = S p)
-\tt
- left;trivial.
- right; exists m0; split; trivial.
-\it
-Proof completed
-\end{alltt}
-
-This example shows how this tactic can be used to ``reverse'' the
-introduction rules of a recursive type, deriving the possible premises
-that could lead to prove a given instance of the predicate. This is
-why these tactics are called \texttt{inversion} tactics: they go back
-from conclusions to premises.
-
-The hypotheses corresponding to the propositional equalities are not
-needed in this example, since the tactic does the necessary rewriting
-to solve the subgoals. When the equalities are no longer needed after
-the inversion, it is better to use the tactic
-\texttt{Inversion\_clear}. This variant of the tactic clears from the
-context all the equalities introduced.
-
-\begin{alltt}
-Restart.
- intros n m H; inversion_clear H.
-\it
-\it
-
- n : nat
- m : nat
- ============================
- m = m {\coqor} ({\exsym} p : nat, m {\coqle} p {\coqand} m = S p)
-\tt
- left;trivial.
-\it
- n : nat
- m : nat
- m0 : nat
- H0 : n {\coqle} m0
- ============================
- n = S m0 {\coqor} ({\exsym} p : nat, n {\coqle} p {\coqand} S m0 = S p)
-\tt
- right; exists m0; split; trivial.
-Qed.
-\end{alltt}
-
-
-%This proof technique works in most of the cases, but not always. In
-%particular, it could not if the list $\vec{t}$ contains a term $t_j$
-%whose type $T$ depends on a previous term $t_i$, with $i<j$. Remark
-%that if this is the case, the propositional equality $x_j=t_j$ is not
-%well-typed, since $x_j:T(x_i)$ but $t_j:T(t_i)$, and both types are
-%not convertible (otherwise, the problem could be solved using the
-%tactic \texttt{Case}).
-
-
-
-\begin{exercise}
-Consider the following language of arithmetic expression, and
-its operational semantics, described by a set of rewriting rules.
-%\textbf{J'ai enlevé une règle de commutativité de l'addition qui
-%me paraissait bizarre du point de vue de la sémantique opérationnelle}
-
-\begin{alltt}
-Inductive ArithExp : Set :=
- | Zero : ArithExp
- | Succ : ArithExp {\arrow} ArithExp
- | Plus : ArithExp {\arrow} ArithExp {\arrow} ArithExp.
-
-Inductive RewriteRel : ArithExp {\arrow} ArithExp {\arrow} Prop :=
- | RewSucc : {\prodsym} e1 e2 :ArithExp,
- RewriteRel e1 e2 {\arrow}
- RewriteRel (Succ e1) (Succ e2)
- | RewPlus0 : {\prodsym} e:ArithExp,
- RewriteRel (Plus Zero e) e
- | RewPlusS : {\prodsym} e1 e2:ArithExp,
- RewriteRel e1 e2 {\arrow}
- RewriteRel (Plus (Succ e1) e2)
- (Succ (Plus e1 e2)).
-
-\end{alltt}
-\begin{enumerate}
-\item Prove that \texttt{Zero} cannot be rewritten any further.
-\item Prove that an expression of the form ``~$\texttt{Succ}\;e$~'' is always
-rewritten
-into an expression of the same form.
-\end{enumerate}
-\end{exercise}
-
-%Theorem zeroNotCompute : (e:ArithExp)~(RewriteRel Zero e).
-%Intro e.
-%Red.
-%Intro H.
-%Inversion_clear H.
-%Defined.
-%Theorem evalPlus :
-% (e1,e2:ArithExp)
-% (RewriteRel (Succ e1) e2)\arrow{}(EX e3 : ArithExp | e2=(Succ e3)).
-%Intros e1 e2 H.
-%Inversion_clear H.
-%Exists e3;Reflexivity.
-%Qed.
-
-
-\section{Inductive Types and Structural Induction}
-\label{StructuralInduction}
-
-Elements of inductive types are well-founded with
-respect to the structural order induced by the constructors of the
-type. In addition to case analysis, this extra hypothesis about
-well-foundedness justifies a stronger elimination rule for them, called
-\textsl{structural induction}. This form of elimination consists in
-defining a value ``~$f\;x$~'' from some element $x$ of the inductive type
-$I$, assuming that values have been already associated in the same way
-to the sub-parts of $x$ of type $I$.
-
-
-Definitions by structural induction are expressed through the
-\texttt{Fixpoint} command \refmancite{Section
-\ref{Fixpoint}}. This command is quite close to the
-\texttt{let-rec} construction of functional programming languages.
-For example, the following definition introduces the addition of two
-natural numbers (already defined in the Standard Library:)
-
-\begin{alltt}
-Fixpoint plus (n p:nat) \{struct n\} : nat :=
- match n with
- | 0 {\funarrow} p
- | S m {\funarrow} S (plus m p)
- end.
-\end{alltt}
-
-The definition is by structural induction on the first argument of the
-function. This is indicated by the ``~\citecoq{\{struct n\}}~''
-directive in the function's header\footnote{This directive is optional
-in the case of a function of a single argument}.
- In
-order to be accepted, the definition must satisfy a syntactical
-condition, called the \textsl{guardedness condition}. Roughly
-speaking, this condition constrains the arguments of a recursive call
-to be pattern variables, issued from a case analysis of the formal
-argument of the function pointed by the \texttt{struct} directive.
- In the case of the
-function \texttt{plus}, the argument \texttt{m} in the recursive call is a
-pattern variable issued from a case analysis of \texttt{n}. Therefore, the
-definition is accepted.
-
-Notice that we could have defined the addition with structural induction
-on its second argument:
-\begin{alltt}
-Fixpoint plus' (n p:nat) \{struct p\} : nat :=
- match p with
- | 0 {\funarrow} n
- | S q {\funarrow} S (plus' n q)
- end.
-\end{alltt}
-
-%This notation is useful when defining a function whose decreasing
-%argument has a dependent type. As an example, consider the following
-%recursivly defined proof of the theorem
-%$(n,m:\texttt{nat})n<m \rightarrow (S\;n)<(S\;m)$:
-%\begin{alltt}
-%Fixpoint lt_n_S [n,m:nat;p:(lt n m)] : (lt (S n) (S m)) :=
-% <[n0:nat](lt (S n) (S n0))>
-% Cases p of
-% lt_intro1 {\funarrow} (lt_intro1 (S n))
-% | (lt_intro2 m1 p2) {\funarrow} (lt_intro2 (S n) (S m1) (lt_n_S n m1 p2))
-% end.
-%\end{alltt}
-
-%The guardedness condition must be satisfied only by the last argument
-%of the enclosed list. For example, the following declaration is an
-%alternative way of defining addition:
-
-%\begin{alltt}
-%Reset add.
-%Fixpoint add [n:nat] : nat\arrow{}nat :=
-% Cases n of
-% O {\funarrow} [x:nat]x
-% | (S m) {\funarrow} [x:nat](add m (S x))
-% end.
-%\end{alltt}
-
-In the following definition of addition,
-the second argument of {\tt plus{'}{'}} grows at each
-recursive call. However, as the first one always decreases, the
-definition is sound.
-\begin{alltt}
-Fixpoint plus'' (n p:nat) \{struct n\} : nat :=
- match n with
- | 0 {\funarrow} p
- | S m {\funarrow} plus'' m (S p)
- end.
-\end{alltt}
-
- Moreover, the argument in the recursive call
-could be a deeper component of $n$. This is the case in the following
-definition of a boolean function determining whether a number is even
-or odd:
-
-\begin{alltt}
-Fixpoint even_test (n:nat) : bool :=
- match n
- with 0 {\funarrow} true
- | 1 {\funarrow} false
- | S (S p) {\funarrow} even_test p
- end.
-\end{alltt}
-
-Mutually dependent definitions by structural induction are also
-allowed. For example, the previous function \textsl{even} could alternatively
-be defined using an auxiliary function \textsl{odd}:
-
-\begin{alltt}
-Reset even_test.
-
-
-
-Fixpoint even_test (n:nat) : bool :=
- match n
- with
- | 0 {\funarrow} true
- | S p {\funarrow} odd_test p
- end
-with odd_test (n:nat) : bool :=
- match n
- with
- | 0 {\funarrow} false
- | S p {\funarrow} even_test p
- end.
-\end{alltt}
-
-%\begin{exercise}
-%Define a function by structural induction that computes the number of
-%nodes of a tree structure defined in page \pageref{Forest}.
-%\end{exercise}
-
-Definitions by structural induction are computed
- only when they are applied, and the decreasing argument
-is a term having a constructor at the head. We can check this using
-the \texttt{Eval} command, which computes the normal form of a well
-typed term.
-
-\begin{alltt}
-Eval simpl in even_test.
-\it
- = even_test
- : nat {\arrow} bool
-\tt
-Eval simpl in (fun x : nat {\funarrow} even x).
-\it
- = fun x : nat {\funarrow} even x
- : nat {\arrow} Prop
-\tt
-Eval simpl in (fun x : nat => plus 5 x).
-\it
- = fun x : nat {\funarrow} S (S (S (S (S x))))
-
-\tt
-Eval simpl in (fun x : nat {\funarrow} even_test (plus 5 x)).
-\it
- = fun x : nat {\funarrow} odd_test x
- : nat {\arrow} bool
-\tt
-Eval simpl in (fun x : nat {\funarrow} even_test (plus x 5)).
-\it
- = fun x : nat {\funarrow} even_test (x + 5)
- : nat {\arrow} bool
-\end{alltt}
-
-
-%\begin{exercise}
-%Prove that the second definition of even satisfies the following
-%theorem:
-%\begin{verbatim}
-%Theorem unfold_even :
-% (x:nat)
-% (even x)= (Cases x of
-% O {\funarrow} true
-% | (S O) {\funarrow} false
-% | (S (S m)) {\funarrow} (even m)
-% end).
-%\end{verbatim}
-%\end{exercise}
-
-\subsection{Proofs by Structural Induction}
-
-The principle of structural induction can be also used in order to
-define proofs, that is, to prove theorems. Let us call an
-\textsl{elimination combinator} any function that, given a predicate
-$P$, defines a proof of ``~$P\;x$~'' by structural induction on $x$. In
-{\coq}, the principle of proof by induction on natural numbers is a
-particular case of an elimination combinator. The definition of this
-combinator depends on three general parameters: the predicate to be
-proven, the base case, and the inductive step:
-
-\begin{alltt}
-Section Principle_of_Induction.
-Variable P : nat {\arrow} Prop.
-Hypothesis base_case : P 0.
-Hypothesis inductive_step : {\prodsym} n:nat, P n {\arrow} P (S n).
-Fixpoint nat_ind (n:nat) : (P n) :=
- match n return P n with
- | 0 {\funarrow} base_case
- | S m {\funarrow} inductive_step m (nat_ind m)
- end.
-
-End Principle_of_Induction.
-\end{alltt}
-
-As this proof principle is used very often, {\coq} automatically generates it
-when an inductive type is introduced. Similar principles
-\texttt{nat\_rec} and \texttt{nat\_rect} for defining objects in the
-universes $\Set$ and $\Type$ are also automatically generated
-\footnote{In fact, whenever possible, {\coq} generates the
-principle \texttt{$I$\_rect}, then derives from it the
-weaker principles \texttt{$I$\_ind} and \texttt{$I$\_rec}.
-If some principle has to be defined by hand, the user may try
-to build \texttt{$I$\_rect} (if possible). Thanks to {\coq}'s conversion
-rule, this principle can be used directly to build proofs and/or
-programs.}. The
-command \texttt{Scheme} \refmancite{Section \ref{Scheme}} can be
-used to generate an elimination combinator from certain parameters,
-like the universe that the defined objects must inhabit, whether the
-case analysis in the definitions must be dependent or not, etc. For
-example, it can be used to generate an elimination combinator for
-reasoning on even natural numbers from the mutually dependent
-predicates introduced in page \pageref{Even}. We do not display the
-combinators here by lack of space, but you can see them using the
-\texttt{Print} command.
-
-\begin{alltt}
-Scheme Even_induction := Minimality for even Sort Prop
-with Odd_induction := Minimality for odd Sort Prop.
-\end{alltt}
-
-\begin{alltt}
-Theorem even_plus_four : {\prodsym} n:nat, even n {\arrow} even (4+n).
-Proof.
- intros n H.
- elim H using Even_induction with (P0 := fun n {\funarrow} odd (4+n));
- simpl;repeat constructor;assumption.
-Qed.
-\end{alltt}
-
-Another example of an elimination combinator is the principle
-of double induction on natural numbers, introduced by the following
-definition:
-
-\begin{alltt}
-Section Principle_of_Double_Induction.
-Variable P : nat {\arrow} nat {\arrow}Prop.
-Hypothesis base_case1 : {\prodsym} m:nat, P 0 m.
-Hypothesis base_case2 : {\prodsym} n:nat, P (S n) 0.
-Hypothesis inductive_step : {\prodsym} n m:nat, P n m {\arrow}
- \,\, P (S n) (S m).
-
-Fixpoint nat_double_ind (n m:nat)\{struct n\} : P n m :=
- match n, m return P n m with
- | 0 , x {\funarrow} base_case1 x
- | (S x), 0 {\funarrow} base_case2 x
- | (S x), (S y) {\funarrow} inductive_step x y (nat_double_ind x y)
- end.
-End Principle_of_Double_Induction.
-\end{alltt}
-
-Changing the type of $P$ into $\nat\rightarrow\nat\rightarrow\Type$,
-another combinator for constructing
-(certified) programs, \texttt{nat\_double\_rect}, can be defined in exactly the same way.
-This definition is left as an exercise.\label{natdoublerect}
-
-\iffalse
-\begin{alltt}
-Section Principle_of_Double_Recursion.
-Variable P : nat {\arrow} nat {\arrow} Type.
-Hypothesis base_case1 : {\prodsym} x:nat, P 0 x.
-Hypothesis base_case2 : {\prodsym} x:nat, P (S x) 0.
-Hypothesis inductive_step : {\prodsym} n m:nat, P n m {\arrow} P (S n) (S m).
-Fixpoint nat_double_rect (n m:nat)\{struct n\} : P n m :=
- match n, m return P n m with
- 0 , x {\funarrow} base_case1 x
- | (S x), 0 {\funarrow} base_case2 x
- | (S x), (S y) {\funarrow} inductive_step x y (nat_double_rect x y)
- end.
-End Principle_of_Double_Recursion.
-\end{alltt}
-\fi
-For instance the function computing the minimum of two natural
-numbers can be defined in the following way:
-
-\begin{alltt}
-Definition min : nat {\arrow} nat {\arrow} nat :=
- nat_double_rect (fun (x y:nat) {\funarrow} nat)
- (fun (x:nat) {\funarrow} 0)
- (fun (y:nat) {\funarrow} 0)
- (fun (x y r:nat) {\funarrow} S r).
-Eval compute in (min 5 8).
-\it
-= 5 : nat
-\end{alltt}
-
-
-%\begin{exercise}
-%
-%Define the combinator \texttt{nat\_double\_rec}, and apply it
-%to give another definition of \citecoq{le\_lt\_dec} (using the theorems
-%of the \texttt{Arith} library).
-%\end{exercise}
-
-\subsection{Using Elimination Combinators.}
-The tactic \texttt{apply} can be used to apply one of these proof
-principles during the development of a proof.
-
-\begin{alltt}
-Lemma not_circular : {\prodsym} n:nat, n {\coqdiff} S n.
-Proof.
- intro n.
- apply nat_ind with (P:= fun n {\funarrow} n {\coqdiff} S n).
-\it
-
-
-
-2 subgoals
-
- n : nat
- ============================
- 0 {\coqdiff} 1
-
-
-subgoal 2 is:
- {\prodsym} n0 : nat, n0 {\coqdiff} S n0 {\arrow} S n0 {\coqdiff} S (S n0)
-
-\tt
- discriminate.
- red; intros n0 Hn0 eqn0Sn0;injection eqn0Sn0;trivial.
-Qed.
-\end{alltt}
-
-The tactic \texttt{elim} \refmancite{Section \ref{Elim}} is a
-refinement of \texttt{apply}, specially designed for the application
-of elimination combinators. If $t$ is an object of an inductive type
-$I$, then ``~\citecoq{elim $t$}~'' tries to find an abstraction $P$ of the
-current goal $G$ such that $(P\;t)\equiv G$. Then it solves the goal
-applying ``~$I\texttt{\_ind}\;P$~'', where $I$\texttt{\_ind} is the
-combinator associated to $I$. The different cases of the induction
-then appear as subgoals that remain to be solved.
-In the previous proof, the tactic call ``~\citecoq{apply nat\_ind with (P:= fun n {\funarrow} n {\coqdiff} S n)}~'' can simply be replaced with ``~\citecoq{elim n}~''.
-
-The option ``~\citecoq{\texttt{elim} $t$ \texttt{using} $C$}~''
- allows the use of a
-derived combinator $C$ instead of the default one. Consider the
-following theorem, stating that equality is decidable on natural
-numbers:
-
-\label{iseqpage}
-\begin{alltt}
-Lemma eq_nat_dec : {\prodsym} n p:nat, \{n=p\}+\{n {\coqdiff} p\}.
-Proof.
- intros n p.
-\end{alltt}
-
-Let us prove this theorem using the combinator \texttt{nat\_double\_rect}
-of section~\ref{natdoublerect}. The example also illustrates how
-\texttt{elim} may sometimes fail in finding a suitable abstraction $P$
-of the goal. Note that if ``~\texttt{elim n}~''
- is used directly on the
-goal, the result is not the expected one.
-
-\vspace{12pt}
-
-%\pagebreak
-\begin{alltt}
- elim n using nat_double_rect.
-\it
-4 subgoals
-
- n : nat
- p : nat
- ============================
- {\prodsym} x : nat, \{x = p\} + \{x {\coqdiff} p\}
-
-subgoal 2 is:
- nat {\arrow} \{0 = p\} + \{0 {\coqdiff} p\}
-
-subgoal 3 is:
- nat {\arrow} {\prodsym} m : nat, \{m = p\} + \{m {\coqdiff} p\} {\arrow} \{S m = p\} + \{S m {\coqdiff} p\}
-
-subgoal 4 is:
- nat
-\end{alltt}
-
-The four sub-goals obtained do not correspond to the premises that
-would be expected for the principle \texttt{nat\_double\_rec}. The
-problem comes from the fact that
-this principle for eliminating $n$
-has a universally quantified formula as conclusion, which confuses
-\texttt{elim} about the right way of abstracting the goal.
-
-%In effect, let us consider the type of the goal before the call to
-%\citecoq{elim}: ``~\citecoq{\{n = p\} + \{n {\coqdiff} p\}}~''.
-
-%Among all the abstractions that can be built by ``~\citecoq{elim n}~''
-%let us consider this one
-%$P=$\citecoq{fun n :nat {\funarrow} fun q : nat {\funarrow} {\{q= p\} + \{q {\coqdiff} p\}}}.
-%It is easy to verify that
-%$P$ has type \citecoq{nat {\arrow} nat {\arrow} Set}, and that, if some
-%$q:\citecoq{nat}$ is given, then $P\;q\;$ matches the current goal.
-%Then applying \citecoq{nat\_double\_rec} with $P$ generates
-%four goals, corresponding to
-
-
-
-
-Therefore,
-in this case the abstraction must be explicited using the
-\texttt{pattern} tactic. Once the right abstraction is provided, the rest of
-the proof is immediate:
-
-\begin{alltt}
-Undo.
- pattern p,n.
-\it
- n : nat
- p : nat
- ============================
- (fun n0 n1 : nat {\funarrow} \{n1 = n0\} + \{n1 {\coqdiff} n0\}) p n
-\tt
- elim n using nat_double_rec.
-\it
-3 subgoals
-
- n : nat
- p : nat
- ============================
- {\prodsym} x : nat, \{x = 0\} + \{x {\coqdiff} 0\}
-
-subgoal 2 is:
- {\prodsym} x : nat, \{0 = S x\} + \{0 {\coqdiff} S x\}
-subgoal 3 is:
- {\prodsym} n0 m : nat, \{m = n0\} + \{m {\coqdiff} n0\} {\arrow} \{S m = S n0\} + \{S m {\coqdiff} S n0\}
-
-\tt
- destruct x; auto.
- destruct x; auto.
- intros n0 m H; case H.
- intro eq; rewrite eq ; auto.
- intro neg; right; red ; injection 1; auto.
-Defined.
-\end{alltt}
-
-
-Notice that the tactic ``~\texttt{decide equality}~''
-\refmancite{Section\ref{DecideEquality}} generalises the proof
-above to a large class of inductive types. It can be used for proving
-a proposition of the form
-$\forall\,(x,y:R),\{x=y\}+\{x{\coqdiff}y\}$, where $R$ is an inductive datatype
-all whose constructors take informative arguments ---like for example
-the type {\nat}:
-
-\begin{alltt}
-Definition eq_nat_dec' : {\prodsym} n p:nat, \{n=p\} + \{n{\coqdiff}p\}.
- decide equality.
-Defined.
-\end{alltt}
-
-\begin{exercise}
-\begin{enumerate}
-\item Define a recursive function of name \emph{nat2itree}
-that maps any natural number $n$ into an infinitely branching
-tree of height $n$.
-\item Provide an elimination combinator for these trees.
-\item Prove that the relation \citecoq{itree\_le} is a preorder
-(i.e. reflexive and transitive).
-\end{enumerate}
-\end{exercise}
-
-\begin{exercise} \label{zeroton}
-Define the type of lists, and a predicate ``being an ordered list''
-using an inductive family. Then, define the function
-$(from\;n)=0::1\;\ldots\; n::\texttt{nil}$ and prove that it always generates an
-ordered list.
-\end{exercise}
-
-\begin{exercise}
-Prove that \citecoq{le' n p} and \citecoq{n $\leq$ p} are logically equivalent
-for all n and p. (\citecoq{le'} is defined in section \ref{parameterstuff}).
-\end{exercise}
-
-
-\subsection{Well-founded Recursion}
-\label{WellFoundedRecursion}
-
-Structural induction is a strong elimination rule for inductive types.
-This method can be used to define any function whose termination is
-a consequence of the well-foundedness of a certain order relation $R$ decreasing
-at each recursive call. What makes this principle so strong is the
-possibility of reasoning by structural induction on the proof that
-certain $R$ is well-founded. In order to illustrate this we have
-first to introduce the predicate of accessibility.
-
-\begin{alltt}
-Print Acc.
-\it
-Inductive Acc (A : Type) (R : A {\arrow} A {\arrow} Prop) (x:A) : Prop :=
- Acc_intro : ({\prodsym} y : A, R y x {\arrow} Acc R y) {\arrow} Acc R x
-For Acc: Argument A is implicit
-For Acc_intro: Arguments A, R are implicit
-
-\dots
-\end{alltt}
-
-\noindent This inductive predicate characterizes those elements $x$ of
-$A$ such that any descending $R$-chain $\ldots x_2\;R\;x_1\;R\;x$
-starting from $x$ is finite. A well-founded relation is a relation
-such that all the elements of $A$ are accessible.
-\emph{Notice the use of parameter $x$ (see Section~\ref{parameterstuff}, page
-\pageref{parameterstuff}).}
-
-Consider now the problem of representing in {\coq} the following ML
-function $\textsl{div}(x,y)$ on natural numbers, which computes
-$\lceil\frac{x}{y}\rceil$ if $y>0$ and yields $x$ otherwise.
-
-\begin{verbatim}
-let rec div x y =
- if x = 0 then 0
- else if y = 0 then x
- else (div (x-y) y)+1;;
-\end{verbatim}
-
-
-The equality test on natural numbers can be implemented using the
-function \textsl{eq\_nat\_dec} that is defined page \pageref{iseqpage}. Giving $x$ and
-$y$, this function yields either the value $(\textsl{left}\;p)$ if
-there exists a proof $p:x=y$, or the value $(\textsl{right}\;q)$ if
-there exists $q:a\not = b$. The subtraction function is already
-defined in the library \citecoq{Minus}.
-
-Hence, direct translation of the ML function \textsl{div} would be:
-
-\begin{alltt}
-Require Import Minus.
-
-Fixpoint div (x y:nat)\{struct x\}: nat :=
- if eq_nat_dec x 0
- then 0
- else if eq_nat_dec y 0
- then x
- else S (div (x-y) y).
-
-\it Error:
-Recursive definition of div is ill-formed.
-In environment
-div : nat {\arrow} nat {\arrow} nat
-x : nat
-y : nat
-_ : x {\coqdiff} 0
-_ : y {\coqdiff} 0
-
-Recursive call to div has principal argument equal to
-"x - y"
-instead of a subterm of x
-\end{alltt}
-
-
-The program \texttt{div} is rejected by {\coq} because it does not verify
-the syntactical condition to ensure termination. In particular, the
-argument of the recursive call is not a pattern variable issued from a
-case analysis on $x$.
-We would have the same problem if we had the directive
-``~\citecoq{\{struct y\}}~'' instead of ``~\citecoq{\{struct x\}}~''.
-However, we know that this program always
-stops. One way to justify its termination is to define it by
-structural induction on a proof that $x$ is accessible trough the
-relation $<$. Notice that any natural number $x$ is accessible
-for this relation. In order to do this, it is first necessary to prove
-some auxiliary lemmas, justifying that the first argument of
-\texttt{div} decreases at each recursive call.
-
-\begin{alltt}
-Lemma minus_smaller_S : {\prodsym} x y:nat, x - y < S x.
-Proof.
- intros x y; pattern y, x;
- elim x using nat_double_ind.
- destruct x0; auto with arith.
- simpl; auto with arith.
- simpl; auto with arith.
-Qed.
-
-
-Lemma minus_smaller_positive :
- {\prodsym} x y:nat, x {\coqdiff}0 {\arrow} y {\coqdiff} 0 {\arrow} x - y < x.
-Proof.
- destruct x; destruct y;
- ( simpl;intros; apply minus_smaller ||
- intros; absurd (0=0); auto).
-Qed.
-\end{alltt}
-
-\noindent The last two lemmas are necessary to prove that for any pair
-of positive natural numbers $x$ and $y$, if $x$ is accessible with
-respect to \citecoq{lt}, then so is $x-y$.
-
-\begin{alltt}
-Definition minus_decrease : {\prodsym} x y:nat, Acc lt x {\arrow}
- x {\coqdiff} 0 {\arrow}
- y {\coqdiff} 0 {\arrow}
- Acc lt (x-y).
-Proof.
- intros x y H; case H.
- intros Hz posz posy.
- apply Hz; apply minus_smaller_positive; assumption.
-Defined.
-\end{alltt}
-
-Let us take a look at the proof of the lemma \textsl{minus\_decrease}, since
-the way in which it has been proven is crucial for what follows.
-\begin{alltt}
-Print minus_decrease.
-\it
-minus_decrease =
-fun (x y : nat) (H : Acc lt x) {\funarrow}
-match H in (Acc _ y0) return (y0 {\coqdiff} 0 {\arrow} y {\coqdiff} 0 {\arrow} Acc lt (y0 - y)) with
-| Acc_intro z Hz {\funarrow}
- fun (posz : z {\coqdiff} 0) (posy : y {\coqdiff} 0) {\funarrow}
- Hz (z - y) (minus_smaller_positive z y posz posy)
-end
- : {\prodsym} x y : nat, Acc lt x {\arrow} x {\coqdiff} 0 {\arrow} y {\coqdiff} 0 {\arrow} Acc lt (x - y)
-
-\end{alltt}
-\noindent Notice that the function call
-$(\texttt{minus\_decrease}\;n\;m\;H)$
-indeed yields an accessibility proof that is \textsl{structurally
-smaller} than its argument $H$, because it is (an application of) its
-recursive component $Hz$. This enables to justify the following
-definition of \textsl{div\_aux}:
-
-\begin{alltt}
-Definition div_aux (x y:nat)(H: Acc lt x):nat.
- fix div_aux 3.
- intros.
- refine (if eq_nat_dec x 0
- then 0
- else if eq_nat_dec y 0
- then y
- else div_aux (x-y) y _).
-\it
- div_aux : {\prodsym} x : nat, nat {\arrow} Acc lt x {\arrow} nat
- x : nat
- y : nat
- H : Acc lt x
- _ : x {\coqdiff} 0
- _0 : y {\coqdiff} 0
- ============================
- Acc lt (x - y)
-
-\tt
- apply (minus_decrease x y H);auto.
-Defined.
-\end{alltt}
-
-The main division function is easily defined, using the theorem
-\citecoq{lt\_wf} of the library \citecoq{Wf\_nat}. This theorem asserts that
-\citecoq{nat} is well founded w.r.t. \citecoq{lt}, thus any natural number
-is accessible.
-\begin{alltt}
-Definition div x y := div_aux x y (lt_wf x).
-\end{alltt}
-
-Let us explain the proof above. In the definition of \citecoq{div\_aux},
-what decreases is not $x$ but the \textsl{proof} of the accessibility
-of $x$. The tactic ``~\texttt{fix div\_aux 3}~'' is used to indicate that the proof
-proceeds by structural induction on the third argument of the theorem
---that is, on the accessibility proof. It also introduces a new
-hypothesis in the context, named ``~\texttt{div\_aux}~'', and with the
-same type as the goal. Then, the proof is refined with an incomplete
-proof term, containing a hole \texttt{\_}. This hole corresponds to the proof
-of accessibility for $x-y$, and is filled up with the (smaller!)
-accessibility proof provided by the function \texttt{minus\_decrease}.
-
-
-\noindent Let us take a look to the term \textsl{div\_aux} defined:
-
-\pagebreak
-\begin{alltt}
-Print div_aux.
-\it
-div_aux =
-(fix div_aux (x y : nat) (H : Acc lt x) \{struct H\} : nat :=
- match eq_nat_dec x 0 with
- | left _ {\funarrow} 0
- | right _ {\funarrow}
- match eq_nat_dec y 0 with
- | left _ {\funarrow} y
- | right _0 {\funarrow} div_aux (x - y) y (minus_decrease x y H _ _0)
- end
- end)
- : {\prodsym} x : nat, nat {\arrow} Acc lt x {\arrow} nat
-
-\end{alltt}
-
-If the non-informative parts from this proof --that is, the
-accessibility proof-- are erased, then we obtain exactly the program
-that we were looking for.
-\begin{alltt}
-
-Extraction div.
-
-\it
-let div x y =
- div_aux x y
-\tt
-
-Extraction div_aux.
-
-\it
-let rec div_aux x y =
- match eq_nat_dec x O with
- | Left {\arrow} O
- | Right {\arrow}
- (match eq_nat_dec y O with
- | Left {\arrow} y
- | Right {\arrow} div_aux (minus x y) y)
-\end{alltt}
-
-This methodology enables the representation
-of any program whose termination can be proved in {\coq}. Once the
-expected properties from this program have been verified, the
-justification of its termination can be thrown away, keeping just the
-desired computational behavior for it.
-
-\section{A case study in dependent elimination}\label{CaseStudy}
-
-Dependent types are very expressive, but ignoring some useful
-techniques can cause some problems to the beginner.
-Let us consider again the type of vectors (see section~\ref{vectors}).
-We want to prove a quite trivial property: the only value of type
-``~\citecoq{vector A 0}~'' is ``~\citecoq{Vnil $A$}~''.
-
-Our first naive attempt leads to a \emph{cul-de-sac}.
-\begin{alltt}
-Lemma vector0_is_vnil :
- {\prodsym} (A:Type)(v:vector A 0), v = Vnil A.
-Proof.
- intros A v;inversion v.
-\it
-1 subgoal
-
- A : Set
- v : vector A 0
- ============================
- v = Vnil A
-\tt
-Abort.
-\end{alltt}
-
-Another attempt is to do a case analysis on a vector of any length
-$n$, under an explicit hypothesis $n=0$. The tactic
-\texttt{discriminate} will help us to get rid of the case
-$n=\texttt{S $p$}$.
-Unfortunately, even the statement of our lemma is refused!
-
-\begin{alltt}
- Lemma vector0_is_vnil_aux :
- {\prodsym} (A:Type)(n:nat)(v:vector A n), n = 0 {\arrow} v = Vnil A.
-
-\it
-Error: In environment
-A : Type
-n : nat
-v : vector A n
-e : n = 0
-The term "Vnil A" has type "vector A 0" while it is expected to have type
- "vector A n"
-\end{alltt}
-
-In effect, the equality ``~\citecoq{v = Vnil A}~'' is ill-typed and this is
-because the type ``~\citecoq{vector A n}~'' is not \emph{convertible}
-with ``~\citecoq{vector A 0}~''.
-
-This problem can be solved if we consider the heterogeneous
-equality \citecoq{JMeq} \cite{conor:motive}
-which allows us to consider terms of different types, even if this
-equality can only be proven for terms in the same type.
-The axiom \citecoq{JMeq\_eq}, from the library \citecoq{JMeq} allows us to convert a
-heterogeneous equality to a standard one.
-
-\begin{alltt}
-Lemma vector0_is_vnil_aux :
- {\prodsym} (A:Type)(n:nat)(v:vector A n),
- n= 0 {\arrow} JMeq v (Vnil A).
-Proof.
- destruct v.
- auto.
- intro; discriminate.
-Qed.
-\end{alltt}
-
-Our property of vectors of null length can be easily proven:
-
-\begin{alltt}
-Lemma vector0_is_vnil : {\prodsym} (A:Type)(v:vector A 0), v = Vnil A.
- intros a v;apply JMeq_eq.
- apply vector0_is_vnil_aux.
- trivial.
-Qed.
-\end{alltt}
-
-It is interesting to look at another proof of
-\citecoq{vector0\_is\_vnil}, which illustrates a technique developed
-and used by various people (consult in the \emph{Coq-club} mailing
-list archive the contributions by Yves Bertot, Pierre Letouzey, Laurent Théry,
-Jean Duprat, and Nicolas Magaud, Venanzio Capretta and Conor McBride).
-This technique is also used for unfolding infinite list definitions
-(see chapter13 of~\cite{coqart}).
-Notice that this definition does not rely on any axiom (\emph{e.g.} \texttt{JMeq\_eq}).
-
-We first give a new definition of the identity on vectors. Before that,
-we make the use of constructors and selectors lighter thanks to
-the implicit arguments feature:
-
-\begin{alltt}
-Implicit Arguments Vcons [A n].
-Implicit Arguments Vnil [A].
-Implicit Arguments Vhead [A n].
-Implicit Arguments Vtail [A n].
-
-Definition Vid : {\prodsym} (A : Type)(n:nat), vector A n {\arrow} vector A n.
-Proof.
- destruct n; intro v.
- exact Vnil.
- exact (Vcons (Vhead v) (Vtail v)).
-Defined.
-\end{alltt}
-
-
-Then we prove that \citecoq{Vid} is the identity on vectors:
-
-\begin{alltt}
-Lemma Vid_eq : {\prodsym} (n:nat) (A:Type)(v:vector A n), v=(Vid _ n v).
-Proof.
- destruct v.
-
-\it
- A : Type
- ============================
- Vnil = Vid A 0 Vnil
-
-subgoal 2 is:
- Vcons a v = Vid A (S n) (Vcons a v)
-\tt
- reflexivity.
- reflexivity.
-Defined.
-\end{alltt}
-
-Why defining a new identity function on vectors? The following
-dialogue shows that \citecoq{Vid} has some interesting computational
-properties:
-
-\begin{alltt}
-Eval simpl in (fun (A:Type)(v:vector A 0) {\funarrow} (Vid _ _ v)).
-\it = fun (A : Type) (_ : vector A 0) {\funarrow} Vnil
- : {\prodsym} A : Type, vector A 0 {\arrow} vector A 0
-
-\end{alltt}
-
-Notice that the plain identity on vectors doesn't convert \citecoq{v}
-into \citecoq{Vnil}.
-\begin{alltt}
-Eval simpl in (fun (A:Type)(v:vector A 0) {\funarrow} v).
-\it = fun (A : Type) (v : vector A 0) {\funarrow} v
- : {\prodsym} A : Type, vector A 0 {\arrow} vector A 0
-\end{alltt}
-
-Then we prove easily that any vector of length 0 is \citecoq{Vnil}:
-
-\begin{alltt}
-Theorem zero_nil : {\prodsym} A (v:vector A 0), v = Vnil.
-Proof.
- intros.
- change (Vnil (A:=A)) with (Vid _ 0 v).
-\it
-1 subgoal
-
- A : Type
- v : vector A 0
- ============================
- v = Vid A 0 v
-\tt
- apply Vid_eq.
-Defined.
-\end{alltt}
-
-A similar result can be proven about vectors of strictly positive
-length\footnote{As for \citecoq{Vid} and \citecoq{Vid\_eq}, this definition
-is from Jean Duprat.}.
-
-\begin{alltt}
-
-
-Theorem decomp :
- {\prodsym} (A : Type) (n : nat) (v : vector A (S n)),
- v = Vcons (Vhead v) (Vtail v).
-Proof.
- intros.
- change (Vcons (Vhead v) (Vtail v)) with (Vid _ (S n) v).
-\it
- 1 subgoal
-
- A : Type
- n : nat
- v : vector A (S n)
- ============================
- v = Vid A (S n) v
-
-\tt{} apply Vid_eq.
-Defined.
-\end{alltt}
-
-
-Both lemmas: \citecoq{zero\_nil} and \citecoq{decomp},
-can be used to easily derive a double recursion principle
-on vectors of same length:
-
-
-\begin{alltt}
-Definition vector_double_rect :
- {\prodsym} (A:Type) (P: {\prodsym} (n:nat),(vector A n){\arrow}(vector A n) {\arrow} Type),
- P 0 Vnil Vnil {\arrow}
- ({\prodsym} n (v1 v2 : vector A n) a b, P n v1 v2 {\arrow}
- P (S n) (Vcons a v1) (Vcons b v2)) {\arrow}
- {\prodsym} n (v1 v2 : vector A n), P n v1 v2.
- induction n.
- intros; rewrite (zero_nil _ v1); rewrite (zero_nil _ v2).
- auto.
- intros v1 v2; rewrite (decomp _ _ v1);rewrite (decomp _ _ v2).
- apply X0; auto.
-Defined.
-\end{alltt}
-
-Notice that, due to the conversion rule of {\coq}'s type system,
-this function can be used directly with \citecoq{Prop} or \citecoq{Type}
-instead of type (thus it is useless to build
-\citecoq{vector\_double\_ind} and \citecoq{vector\_double\_rec}) from scratch.
-
-We finish this example with showing how to define the bitwise
-\emph{or} on boolean vectors of the same length,
-and proving a little property about this
-operation.
-
-\begin{alltt}
-Definition bitwise_or n v1 v2 : vector bool n :=
- vector_double_rect
- bool
- (fun n v1 v2 {\funarrow} vector bool n)
- Vnil
- (fun n v1 v2 a b r {\funarrow} Vcons (orb a b) r) n v1 v2.
-\end{alltt}
-
-Let us define recursively the $n$-th element of a vector. Notice
-that it must be a partial function, in case $n$ is greater or equal
-than the length of the vector. Since {\coq} only considers total
-functions, the function returns a value in an \emph{option} type.
-
-\begin{alltt}
-Fixpoint vector_nth (A:Type)(n:nat)(p:nat)(v:vector A p)
- \{struct v\}
- : option A :=
- match n,v with
- _ , Vnil {\funarrow} None
- | 0 , Vcons b _ _ {\funarrow} Some b
- | S n', Vcons _ p' v' {\funarrow} vector_nth A n' p' v'
- end.
-Implicit Arguments vector_nth [A p].
-\end{alltt}
-
-We can now prove --- using the double induction combinator ---
-a simple property relying \citecoq{vector\_nth} and \citecoq{bitwise\_or}:
-
-\begin{alltt}
-Lemma nth_bitwise :
- {\prodsym} (n:nat) (v1 v2: vector bool n) i a b,
- vector_nth i v1 = Some a {\arrow}
- vector_nth i v2 = Some b {\arrow}
- vector_nth i (bitwise_or _ v1 v2) = Some (orb a b).
-Proof.
- intros n v1 v2; pattern n,v1,v2.
- apply vector_double_rect.
- simpl.
- destruct i; discriminate 1.
- destruct i; simpl;auto.
- injection 1; injection 2;intros; subst a; subst b; auto.
-Qed.
-\end{alltt}
-
-
-\section{Co-inductive Types and Non-ending Constructions}
-\label{CoInduction}
-
-The objects of an inductive type are well-founded with respect to
-the constructors of the type. In other words, these objects are built
-by applying \emph{a finite number of times} the constructors of the type.
-Co-inductive types are obtained by relaxing this condition,
-and may contain non-well-founded objects \cite{EG96,EG95a}. An
-example of a co-inductive type is the type of infinite
-sequences formed with elements of type $A$, also called streams. This
-type can be introduced through the following definition:
-
-\begin{alltt}
- CoInductive Stream (A: Type) :Type :=
- | Cons : A\arrow{}Stream A\arrow{}Stream A.
-\end{alltt}
-
-If we are interested in finite or infinite sequences, we consider the type
-of \emph{lazy lists}:
-
-\begin{alltt}
-CoInductive LList (A: Type) : Type :=
- | LNil : LList A
- | LCons : A {\arrow} LList A {\arrow} LList A.
-\end{alltt}
-
-
-It is also possible to define co-inductive types for the
-trees with infinitely-many branches (see Chapter 13 of~\cite{coqart}).
-
-Structural induction is the way of expressing that inductive types
-only contain well-founded objects. Hence, this elimination principle
-is not valid for co-inductive types, and the only elimination rule for
-streams is case analysis. This principle can be used, for example, to
-define the destructors \textsl{head} and \textsl{tail}.
-
-\begin{alltt}
- Definition head (A:Type)(s : Stream A) :=
- match s with Cons a s' {\funarrow} a end.
-
- Definition tail (A : Type)(s : Stream A) :=
- match s with Cons a s' {\funarrow} s' end.
-\end{alltt}
-
-Infinite objects are defined by means of (non-ending) methods of
-construction, like in lazy functional programming languages. Such
-methods can be defined using the \texttt{CoFixpoint} command
-\refmancite{Section \ref{CoFixpoint}}. For example, the following
-definition introduces the infinite list $[a,a,a,\ldots]$:
-
-\begin{alltt}
- CoFixpoint repeat (A:Type)(a:A) : Stream A :=
- Cons a (repeat a).
-\end{alltt}
-
-
-However, not every co-recursive definition is an admissible method of
-construction. Similarly to the case of structural induction, the
-definition must verify a \textsl{guardedness} condition to be
-accepted. This condition states that any recursive call in the
-definition must be protected --i.e, be an argument of-- some
-constructor, and only an argument of constructors \cite{EG94a}. The
-following definitions are examples of valid methods of construction:
-
-\begin{alltt}
-CoFixpoint iterate (A: Type)(f: A {\arrow} A)(a : A) : Stream A:=
- Cons a (iterate f (f a)).
-
-CoFixpoint map
- (A B:Type)(f: A {\arrow} B)(s : Stream A) : Stream B:=
- match s with Cons a tl {\funarrow} Cons (f a) (map f tl) end.
-\end{alltt}
-
-\begin{exercise}
-Define two different methods for constructing the stream which
-infinitely alternates the values \citecoq{true} and \citecoq{false}.
-\end{exercise}
-\begin{exercise}
-Using the destructors \texttt{head} and \texttt{tail}, define a function
-which takes the n-th element of an infinite stream.
-\end{exercise}
-
-A non-ending method of construction is computed lazily. This means
-that its definition is unfolded only when the object that it
-introduces is eliminated, that is, when it appears as the argument of
-a case expression. We can check this using the command
-\texttt{Eval}.
-
-\begin{alltt}
-Eval simpl in (fun (A:Type)(a:A) {\funarrow} repeat a).
-\it = fun (A : Type) (a : A) {\funarrow} repeat a
- : {\prodsym} A : Type, A {\arrow} Stream A
-\tt
-Eval simpl in (fun (A:Type)(a:A) {\funarrow} head (repeat a)).
-\it = fun (A : Type) (a : A) {\funarrow} a
- : {\prodsym} A : Type, A {\arrow} A
-\end{alltt}
-
-%\begin{exercise}
-%Prove the following theorem:
-%\begin{verbatim}
-%Theorem expand_repeat : (a:A)(repeat a)=(Cons a (repeat a)).
-%\end{verbatim}
-%Hint: Prove first the streams version of the lemma in exercise
-%\ref{expand}.
-%\end{exercise}
-
-\subsection{Extensional Properties}
-
-Case analysis is also a valid proof principle for infinite
-objects. However, this principle is not sufficient to prove
-\textsl{extensional} properties, that is, properties concerning the
-whole infinite object \cite{EG95a}. A typical example of an
-extensional property is the predicate expressing that two streams have
-the same elements. In many cases, the minimal reflexive relation $a=b$
-that is used as equality for inductive types is too small to capture
-equality between streams. Consider for example the streams
-$\texttt{iterate}\;f\;(f\;x)$ and
-$(\texttt{map}\;f\;(\texttt{iterate}\;f\;x))$. Even though these two streams have
-the same elements, no finite expansion of their definitions lead to
-equal terms. In other words, in order to deal with extensional
-properties, it is necessary to construct infinite proofs. The type of
-infinite proofs of equality can be introduced as a co-inductive
-predicate, as follows:
-\begin{alltt}
-CoInductive EqSt (A: Type) : Stream A {\arrow} Stream A {\arrow} Prop :=
- eqst : {\prodsym} s1 s2: Stream A,
- head s1 = head s2 {\arrow}
- EqSt (tail s1) (tail s2) {\arrow}
- EqSt s1 s2.
-\end{alltt}
-
-It is possible to introduce proof principles for reasoning about
-infinite objects as combinators defined through
-\texttt{CoFixpoint}. However, oppositely to the case of inductive
-types, proof principles associated to co-inductive types are not
-elimination but \textsl{introduction} combinators. An example of such
-a combinator is Park's principle for proving the equality of two
-streams, usually called the \textsl{principle of co-induction}. It
-states that two streams are equal if they satisfy a
-\textit{bisimulation}. A bisimulation is a binary relation $R$ such
-that any pair of streams $s_1$ ad $s_2$ satisfying $R$ have equal
-heads, and tails also satisfying $R$. This principle is in fact a
-method for constructing an infinite proof:
-
-\begin{alltt}
-Section Parks_Principle.
-Variable A : Type.
-Variable R : Stream A {\arrow} Stream A {\arrow} Prop.
-Hypothesis bisim1 : {\prodsym} s1 s2:Stream A,
- R s1 s2 {\arrow} head s1 = head s2.
-
-Hypothesis bisim2 : {\prodsym} s1 s2:Stream A,
- R s1 s2 {\arrow} R (tail s1) (tail s2).
-
-CoFixpoint park_ppl :
- {\prodsym} s1 s2:Stream A, R s1 s2 {\arrow} EqSt s1 s2 :=
- fun s1 s2 (p : R s1 s2) {\funarrow}
- eqst s1 s2 (bisim1 s1 s2 p)
- (park_ppl (tail s1)
- (tail s2)
- (bisim2 s1 s2 p)).
-End Parks_Principle.
-\end{alltt}
-
-Let us use the principle of co-induction to prove the extensional
-equality mentioned above.
-\begin{alltt}
-Theorem map_iterate : {\prodsym} (A:Type)(f:A{\arrow}A)(x:A),
- EqSt (iterate f (f x))
- (map f (iterate f x)).
-Proof.
- intros A f x.
- apply park_ppl with
- (R:= fun s1 s2 {\funarrow}
- {\exsym} x: A, s1 = iterate f (f x) {\coqand}
- s2 = map f (iterate f x)).
-
- intros s1 s2 (x0,(eqs1,eqs2));
- rewrite eqs1; rewrite eqs2; reflexivity.
- intros s1 s2 (x0,(eqs1,eqs2)).
- exists (f x0);split;
- [rewrite eqs1|rewrite eqs2]; reflexivity.
- exists x;split; reflexivity.
-Qed.
-\end{alltt}
-
-The use of Park's principle is sometimes annoying, because it requires
-to find an invariant relation and prove that it is indeed a
-bisimulation. In many cases, a shorter proof can be obtained trying
-to construct an ad-hoc infinite proof, defined by a guarded
-declaration. The tactic ``~``\texttt{Cofix $f$}~'' can be used to do
-that. Similarly to the tactic \texttt{fix} indicated in Section
-\ref{WellFoundedRecursion}, this tactic introduces an extra hypothesis
-$f$ into the context, whose type is the same as the current goal. Note
-that the applications of $f$ in the proof \textsl{must be guarded}. In
-order to prevent us from doing unguarded calls, we can define a tactic
-that always apply a constructor before using $f$ \refmancite{Chapter
-\ref{WritingTactics}} :
-
-\begin{alltt}
-Ltac infiniteproof f :=
- cofix f;
- constructor;
- [clear f| simpl; try (apply f; clear f)].
-\end{alltt}
-
-
-In the example above, this tactic produces a much simpler proof
-that the former one:
-
-\begin{alltt}
-Theorem map_iterate' : {\prodsym} ((A:Type)f:A{\arrow}A)(x:A),
- EqSt (iterate f (f x))
- (map f (iterate f x)).
-Proof.
- infiniteproof map_iterate'.
- reflexivity.
-Qed.
-\end{alltt}
-
-\begin{exercise}
-Define a co-inductive type of name $Nat$ that contains non-standard
-natural numbers --this is, verifying
-
-$$\exists m \in \mbox{\texttt{Nat}}, \forall\, n \in \mbox{\texttt{Nat}}, n<m$$.
-\end{exercise}
-
-\begin{exercise}
-Prove that the extensional equality of streams is an equivalence relation
-using Park's co-induction principle.
-\end{exercise}
-
-
-\begin{exercise}
-Provide a suitable definition of ``being an ordered list'' for infinite lists
-and define a principle for proving that an infinite list is ordered. Apply
-this method to the list $[0,1,\ldots ]$. Compare the result with
-exercise \ref{zeroton}.
-\end{exercise}
-
-\subsection{About injection, discriminate, and inversion}
-Since co-inductive types are closed w.r.t. their constructors,
-the techniques shown in Section~\ref{CaseTechniques} work also
-with these types.
-
-Let us consider the type of lazy lists, introduced on page~\pageref{CoInduction}.
-The following lemmas are straightforward applications
- of \texttt{discriminate} and \citecoq{injection}:
-
-\begin{alltt}
-Lemma Lnil_not_Lcons : {\prodsym} (A:Type)(a:A)(l:LList A),
- LNil {\coqdiff} (LCons a l).
-Proof.
- intros;discriminate.
-Qed.
-
-Lemma injection_demo : {\prodsym} (A:Type)(a b : A)(l l': LList A),
- LCons a (LCons b l) = LCons b (LCons a l') {\arrow}
- a = b {\coqand} l = l'.
-Proof.
- intros A a b l l' e; injection e; auto.
-Qed.
-
-\end{alltt}
-
-In order to show \citecoq{inversion} at work, let us define
-two predicates on lazy lists:
-
-\begin{alltt}
-Inductive Finite (A:Type) : LList A {\arrow} Prop :=
-| Lnil_fin : Finite (LNil (A:=A))
-| Lcons_fin : {\prodsym} a l, Finite l {\arrow} Finite (LCons a l).
-
-CoInductive Infinite (A:Type) : LList A {\arrow} Prop :=
-| LCons_inf : {\prodsym} a l, Infinite l {\arrow} Infinite (LCons a l).
-\end{alltt}
-
-\noindent
-First, two easy theorems:
-\begin{alltt}
-Lemma LNil_not_Infinite : {\prodsym} (A:Type), ~ Infinite (LNil (A:=A)).
-Proof.
- intros A H;inversion H.
-Qed.
-
-Lemma Finite_not_Infinite : {\prodsym} (A:Type)(l:LList A),
- Finite l {\arrow} ~ Infinite l.
-Proof.
- intros A l H; elim H.
- apply LNil_not_Infinite.
- intros a l0 F0 I0' I1.
- case I0'; inversion_clear I1.
- trivial.
-Qed.
-\end{alltt}
-
-
-On the other hand, the next proof uses the \citecoq{cofix} tactic.
-Notice the destructuration of \citecoq{l}, which allows us to
-apply the constructor \texttt{LCons\_inf}, thus satisfying
- the guard condition:
-\begin{alltt}
-Lemma Not_Finite_Infinite : {\prodsym} (A:Type)(l:LList A),
- ~ Finite l {\arrow} Infinite l.
-Proof.
- cofix H.
- destruct l.
- intro;
- absurd (Finite (LNil (A:=A)));
- [auto|constructor].
-\it
-
-
-
-
-1 subgoal
-
- H : forall (A : Type) (l : LList A), ~ Finite l -> Infinite l
- A : Type
- a : A
- l : LList A
- H0 : ~ Finite (LCons a l)
- ============================
- Infinite l
-\end{alltt}
-At this point, one must not apply \citecoq{H}! . It would be possible
-to solve the current goal by an inversion of ``~\citecoq{Finite (LCons a l)}~'', but, since the guard condition would be violated, the user
-would get an error message after typing \citecoq{Qed}.
-In order to satisfy the guard condition, we apply the constructor of
-\citecoq{Infinite}, \emph{then} apply \citecoq{H}.
-
-\begin{alltt}
- constructor.
- apply H.
- red; intro H1;case H0.
- constructor.
- trivial.
-Qed.
-\end{alltt}
-
-
-
-
-The reader is invited to replay this proof and understand each of its steps.
-
-
-\bibliographystyle{abbrv}
-\bibliography{manbiblio,morebib}
-
-\end{document}
-
diff --git a/doc/RecTutorial/RecTutorial.v b/doc/RecTutorial/RecTutorial.v
deleted file mode 100644
index 4a17e0818..000000000
--- a/doc/RecTutorial/RecTutorial.v
+++ /dev/null
@@ -1,1231 +0,0 @@
-Unset Automatic Introduction.
-
-Check (forall A:Type, (exists x:A, forall (y:A), x <> y) -> 2 = 3).
-
-
-
-Inductive nat : Set :=
- | O : nat
- | S : nat->nat.
-Check nat.
-Check O.
-Check S.
-
-Reset nat.
-Print nat.
-
-
-Print le.
-
-Theorem zero_leq_three: 0 <= 3.
-
-Proof.
- constructor 2.
- constructor 2.
- constructor 2.
- constructor 1.
-
-Qed.
-
-Print zero_leq_three.
-
-
-Lemma zero_leq_three': 0 <= 3.
- repeat constructor.
-Qed.
-
-
-Lemma zero_lt_three : 0 < 3.
-Proof.
- repeat constructor.
-Qed.
-
-Print zero_lt_three.
-
-Inductive le'(n:nat):nat -> Prop :=
- | le'_n : le' n n
- | le'_S : forall p, le' (S n) p -> le' n p.
-
-Hint Constructors le'.
-
-
-Require Import List.
-
-Print list.
-
-Check list.
-
-Check (nil (A:=nat)).
-
-Check (nil (A:= nat -> nat)).
-
-Check (fun A: Type => (cons (A:=A))).
-
-Check (cons 3 (cons 2 nil)).
-
-Check (nat :: bool ::nil).
-
-Check ((3<=4) :: True ::nil).
-
-Check (Prop::Set::nil).
-
-Require Import Bvector.
-
-Print Vector.t.
-
-Check (Vector.nil nat).
-
-Check (fun (A:Type)(a:A)=> Vector.cons _ a _ (Vector.nil _)).
-
-Check (Vector.cons _ 5 _ (Vector.cons _ 3 _ (Vector.nil _))).
-
-Lemma eq_3_3 : 2 + 1 = 3.
-Proof.
- reflexivity.
-Qed.
-Print eq_3_3.
-
-Lemma eq_proof_proof : eq_refl (2*6) = eq_refl (3*4).
-Proof.
- reflexivity.
-Qed.
-Print eq_proof_proof.
-
-Lemma eq_lt_le : ( 2 < 4) = (3 <= 4).
-Proof.
- reflexivity.
-Qed.
-
-Lemma eq_nat_nat : nat = nat.
-Proof.
- reflexivity.
-Qed.
-
-Lemma eq_Set_Set : Set = Set.
-Proof.
- reflexivity.
-Qed.
-
-Lemma eq_Type_Type : Type = Type.
-Proof.
- reflexivity.
-Qed.
-
-
-Check (2 + 1 = 3).
-
-
-Check (Type = Type).
-
-Goal Type = Type.
-reflexivity.
-Qed.
-
-
-Print or.
-
-Print and.
-
-
-Print sumbool.
-
-Print ex.
-
-Require Import ZArith.
-Require Import Compare_dec.
-
-Check le_lt_dec.
-
-Definition max (n p :nat) := match le_lt_dec n p with
- | left _ => p
- | right _ => n
- end.
-
-Theorem le_max : forall n p, n <= p -> max n p = p.
-Proof.
- intros n p ; unfold max ; case (le_lt_dec n p); simpl.
- trivial.
- intros; absurd (p < p); eauto with arith.
-Qed.
-
-Require Extraction.
-Extraction max.
-
-
-
-
-
-
-Inductive tree(A:Type) : Type :=
- node : A -> forest A -> tree A
-with
- forest (A: Type) : Type :=
- nochild : forest A |
- addchild : tree A -> forest A -> forest A.
-
-
-
-
-
-Inductive
- even : nat->Prop :=
- evenO : even O |
- evenS : forall n, odd n -> even (S n)
-with
- odd : nat->Prop :=
- oddS : forall n, even n -> odd (S n).
-
-Lemma odd_49 : odd (7 * 7).
- simpl; repeat constructor.
-Qed.
-
-
-
-Definition nat_case :=
- fun (Q : Type)(g0 : Q)(g1 : nat -> Q)(n:nat) =>
- match n return Q with
- | 0 => g0
- | S p => g1 p
- end.
-
-Eval simpl in (nat_case nat 0 (fun p => p) 34).
-
-Eval simpl in (fun g0 g1 => nat_case nat g0 g1 34).
-
-Eval simpl in (fun g0 g1 => nat_case nat g0 g1 0).
-
-
-Definition pred (n:nat) := match n with O => O | S m => m end.
-
-Eval simpl in pred 56.
-
-Eval simpl in pred 0.
-
-Eval simpl in fun p => pred (S p).
-
-
-Definition xorb (b1 b2:bool) :=
-match b1, b2 with
- | false, true => true
- | true, false => true
- | _ , _ => false
-end.
-
-
- Definition pred_spec (n:nat) := {m:nat | n=0 /\ m=0 \/ n = S m}.
-
-
- Definition predecessor : forall n:nat, pred_spec n.
- intro n;case n.
- unfold pred_spec;exists 0;auto.
- unfold pred_spec; intro n0;exists n0; auto.
- Defined.
-
-Print predecessor.
-
-Extraction predecessor.
-
-Theorem nat_expand :
- forall n:nat, n = match n with 0 => 0 | S p => S p end.
- intro n;case n;simpl;auto.
-Qed.
-
-Check (fun p:False => match p return 2=3 with end).
-
-Theorem fromFalse : False -> 0=1.
- intro absurd.
- contradiction.
-Qed.
-
-Section equality_elimination.
- Variables (A: Type)
- (a b : A)
- (p : a = b)
- (Q : A -> Type).
- Check (fun H : Q a =>
- match p in (eq _ y) return Q y with
- eq_refl => H
- end).
-
-End equality_elimination.
-
-
-Theorem trans : forall n m p:nat, n=m -> m=p -> n=p.
-Proof.
- intros n m p eqnm.
- case eqnm.
- trivial.
-Qed.
-
-Lemma Rw : forall x y: nat, y = y * x -> y * x * x = y.
- intros x y e; do 2 rewrite <- e.
- reflexivity.
-Qed.
-
-
-Require Import Arith.
-
-Check mult_1_l.
-(*
-mult_1_l
- : forall n : nat, 1 * n = n
-*)
-
-Check mult_plus_distr_r.
-(*
-mult_plus_distr_r
- : forall n m p : nat, (n + m) * p = n * p + m * p
-
-*)
-
-Lemma mult_distr_S : forall n p : nat, n * p + p = (S n)* p.
- simpl;auto with arith.
-Qed.
-
-Lemma four_n : forall n:nat, n+n+n+n = 4*n.
- intro n;rewrite <- (mult_1_l n).
-
- Undo.
- intro n; pattern n at 1.
-
-
- rewrite <- mult_1_l.
- repeat rewrite mult_distr_S.
- trivial.
-Qed.
-
-
-Section Le_case_analysis.
- Variables (n p : nat)
- (H : n <= p)
- (Q : nat -> Prop)
- (H0 : Q n)
- (HS : forall m, n <= m -> Q (S m)).
- Check (
- match H in (_ <= q) return (Q q) with
- | le_n _ => H0
- | le_S _ m Hm => HS m Hm
- end
- ).
-
-
-End Le_case_analysis.
-
-
-Lemma predecessor_of_positive : forall n, 1 <= n -> exists p:nat, n = S p.
-Proof.
- intros n H; case H.
- exists 0; trivial.
- intros m Hm; exists m;trivial.
-Qed.
-
-Definition Vtail_total
- (A : Type) (n : nat) (v : Vector.t A n) : Vector.t A (pred n):=
-match v in (Vector.t _ n0) return (Vector.t A (pred n0)) with
-| Vector.nil _ => Vector.nil A
-| Vector.cons _ _ n0 v0 => v0
-end.
-
-Definition Vtail' (A:Type)(n:nat)(v:Vector.t A n) : Vector.t A (pred n).
- intros A n v; case v.
- simpl.
- exact (Vector.nil A).
- simpl.
- auto.
-Defined.
-
-(*
-Inductive Lambda : Set :=
- lambda : (Lambda -> False) -> Lambda.
-
-
-Error: Non strictly positive occurrence of "Lambda" in
- "(Lambda -> False) -> Lambda"
-
-*)
-
-Section Paradox.
- Variable Lambda : Set.
- Variable lambda : (Lambda -> False) ->Lambda.
-
- Variable matchL : Lambda -> forall Q:Prop, ((Lambda ->False) -> Q) -> Q.
- (*
- understand matchL Q l (fun h : Lambda -> False => t)
-
- as match l return Q with lambda h => t end
- *)
-
- Definition application (f x: Lambda) :False :=
- matchL f False (fun h => h x).
-
- Definition Delta : Lambda := lambda (fun x : Lambda => application x x).
-
- Definition loop : False := application Delta Delta.
-
- Theorem two_is_three : 2 = 3.
- Proof.
- elim loop.
- Qed.
-
-End Paradox.
-
-
-Require Import ZArith.
-
-
-
-Inductive itree : Set :=
-| ileaf : itree
-| inode : Z-> (nat -> itree) -> itree.
-
-Definition isingle l := inode l (fun i => ileaf).
-
-Definition t1 := inode 0 (fun n => isingle (Z.of_nat (2*n))).
-
-Definition t2 := inode 0
- (fun n : nat =>
- inode (Z.of_nat n)
- (fun p => isingle (Z.of_nat (n*p)))).
-
-
-Inductive itree_le : itree-> itree -> Prop :=
- | le_leaf : forall t, itree_le ileaf t
- | le_node : forall l l' s s',
- Z.le l l' ->
- (forall i, exists j:nat, itree_le (s i) (s' j)) ->
- itree_le (inode l s) (inode l' s').
-
-
-Theorem itree_le_trans :
- forall t t', itree_le t t' ->
- forall t'', itree_le t' t'' -> itree_le t t''.
- induction t.
- constructor 1.
-
- intros t'; case t'.
- inversion 1.
- intros z0 i0 H0.
- intro t'';case t''.
- inversion 1.
- intros.
- inversion_clear H1.
- constructor 2.
- inversion_clear H0;eauto with zarith.
- inversion_clear H0.
- intro i2; case (H4 i2).
- intros.
- generalize (H i2 _ H0).
- intros.
- case (H3 x);intros.
- generalize (H5 _ H6).
- exists x0;auto.
-Qed.
-
-
-
-Inductive itree_le' : itree-> itree -> Prop :=
- | le_leaf' : forall t, itree_le' ileaf t
- | le_node' : forall l l' s s' g,
- Z.le l l' ->
- (forall i, itree_le' (s i) (s' (g i))) ->
- itree_le' (inode l s) (inode l' s').
-
-
-
-
-
-Lemma t1_le_t2 : itree_le t1 t2.
- unfold t1, t2.
- constructor.
- auto with zarith.
- intro i; exists (2 * i).
- unfold isingle.
- constructor.
- auto with zarith.
- exists i;constructor.
-Qed.
-
-
-
-Lemma t1_le'_t2 : itree_le' t1 t2.
- unfold t1, t2.
- constructor 2 with (fun i : nat => 2 * i).
- auto with zarith.
- unfold isingle;
- intro i ; constructor 2 with (fun i :nat => i).
- auto with zarith.
- constructor .
-Qed.
-
-
-Require Import List.
-
-Inductive ltree (A:Set) : Set :=
- lnode : A -> list (ltree A) -> ltree A.
-
-Inductive prop : Prop :=
- prop_intro : Prop -> prop.
-
-Check (prop_intro prop).
-
-Inductive ex_Prop (P : Prop -> Prop) : Prop :=
- exP_intro : forall X : Prop, P X -> ex_Prop P.
-
-Lemma ex_Prop_inhabitant : ex_Prop (fun P => P -> P).
-Proof.
- exists (ex_Prop (fun P => P -> P)).
- trivial.
-Qed.
-
-
-
-
-(*
-
-Check (fun (P:Prop->Prop)(p: ex_Prop P) =>
- match p with exP_intro X HX => X end).
-Error:
-Incorrect elimination of "p" in the inductive type
-"ex_Prop", the return type has sort "Type" while it should be
-"Prop"
-
-Elimination of an inductive object of sort "Prop"
-is not allowed on a predicate in sort "Type"
-because proofs can be eliminated only to build proofs
-
-*)
-
-
-Inductive typ : Type :=
- typ_intro : Type -> typ.
-
-Definition typ_inject: typ.
-split.
-Fail exact typ.
-(*
-Error: Universe Inconsistency.
-*)
-Abort.
-(*
-
-Inductive aSet : Set :=
- aSet_intro: Set -> aSet.
-
-
-User error: Large non-propositional inductive types must be in Type
-
-*)
-
-Inductive ex_Set (P : Set -> Prop) : Type :=
- exS_intro : forall X : Set, P X -> ex_Set P.
-
-
-Inductive comes_from_the_left (P Q:Prop): P \/ Q -> Prop :=
- c1 : forall p, comes_from_the_left P Q (or_introl (A:=P) Q p).
-
-Goal (comes_from_the_left _ _ (or_introl True I)).
-split.
-Qed.
-
-Goal ~(comes_from_the_left _ _ (or_intror True I)).
- red;inversion 1.
- (* discriminate H0.
- *)
-Abort.
-
-Reset comes_from_the_left.
-
-(*
-
-
-
-
-
-
- Definition comes_from_the_left (P Q:Prop)(H:P \/ Q): Prop :=
- match H with
- | or_introl p => True
- | or_intror q => False
- end.
-
-Error:
-Incorrect elimination of "H" in the inductive type
-"or", the return type has sort "Type" while it should be
-"Prop"
-
-Elimination of an inductive object of sort "Prop"
-is not allowed on a predicate in sort "Type"
-because proofs can be eliminated only to build proofs
-
-*)
-
-Definition comes_from_the_left_sumbool
- (P Q:Prop)(x:{P}+{Q}): Prop :=
- match x with
- | left p => True
- | right q => False
- end.
-
-
-
-
-Close Scope Z_scope.
-
-
-
-
-
-Theorem S_is_not_O : forall n, S n <> 0.
-
-Definition Is_zero (x:nat):= match x with
- | 0 => True
- | _ => False
- end.
- Lemma O_is_zero : forall m, m = 0 -> Is_zero m.
- Proof.
- intros m H; subst m.
- (*
- ============================
- Is_zero 0
- *)
- simpl;trivial.
- Qed.
-
- red; intros n Hn.
- apply O_is_zero with (m := S n).
- assumption.
-Qed.
-
-Theorem disc2 : forall n, S (S n) <> 1.
-Proof.
- intros n Hn; discriminate.
-Qed.
-
-
-Theorem disc3 : forall n, S (S n) = 0 -> forall Q:Prop, Q.
-Proof.
- intros n Hn Q.
- discriminate.
-Qed.
-
-
-
-Theorem inj_succ : forall n m, S n = S m -> n = m.
-Proof.
-
-
-Lemma inj_pred : forall n m, n = m -> pred n = pred m.
-Proof.
- intros n m eq_n_m.
- rewrite eq_n_m.
- trivial.
-Qed.
-
- intros n m eq_Sn_Sm.
- apply inj_pred with (n:= S n) (m := S m); assumption.
-Qed.
-
-Lemma list_inject : forall (A:Type)(a b :A)(l l':list A),
- a :: b :: l = b :: a :: l' -> a = b /\ l = l'.
-Proof.
- intros A a b l l' e.
- injection e.
- auto.
-Qed.
-
-
-Theorem not_le_Sn_0 : forall n:nat, ~ (S n <= 0).
-Proof.
- red; intros n H.
- case H.
-Undo.
-
-Lemma not_le_Sn_0_with_constraints :
- forall n p , S n <= p -> p = 0 -> False.
-Proof.
- intros n p H; case H ;
- intros; discriminate.
-Qed.
-
-eapply not_le_Sn_0_with_constraints; eauto.
-Qed.
-
-
-Theorem not_le_Sn_0' : forall n:nat, ~ (S n <= 0).
-Proof.
- red; intros n H ; inversion H.
-Qed.
-
-Derive Inversion le_Sn_0_inv with (forall n :nat, S n <= 0).
-Check le_Sn_0_inv.
-
-Theorem le_Sn_0'' : forall n p : nat, ~ S n <= 0 .
-Proof.
- intros n p H;
- inversion H using le_Sn_0_inv.
-Qed.
-
-Derive Inversion_clear le_Sn_0_inv' with (forall n :nat, S n <= 0).
-Check le_Sn_0_inv'.
-
-
-Theorem le_reverse_rules :
- forall n m:nat, n <= m ->
- n = m \/
- exists p, n <= p /\ m = S p.
-Proof.
- intros n m H; inversion H.
- left;trivial.
- right; exists m0; split; trivial.
-Restart.
- intros n m H; inversion_clear H.
- left;trivial.
- right; exists m0; split; trivial.
-Qed.
-
-Inductive ArithExp : Set :=
- Zero : ArithExp
- | Succ : ArithExp -> ArithExp
- | Plus : ArithExp -> ArithExp -> ArithExp.
-
-Inductive RewriteRel : ArithExp -> ArithExp -> Prop :=
- RewSucc : forall e1 e2 :ArithExp,
- RewriteRel e1 e2 -> RewriteRel (Succ e1) (Succ e2)
- | RewPlus0 : forall e:ArithExp,
- RewriteRel (Plus Zero e) e
- | RewPlusS : forall e1 e2:ArithExp,
- RewriteRel e1 e2 ->
- RewriteRel (Plus (Succ e1) e2) (Succ (Plus e1 e2)).
-
-
-
-Fixpoint plus (n p:nat) {struct n} : nat :=
- match n with
- | 0 => p
- | S m => S (plus m p)
- end.
-
-Fixpoint plus' (n p:nat) {struct p} : nat :=
- match p with
- | 0 => n
- | S q => S (plus' n q)
- end.
-
-Fixpoint plus'' (n p:nat) {struct n} : nat :=
- match n with
- | 0 => p
- | S m => plus'' m (S p)
- end.
-
-
-Fixpoint even_test (n:nat) : bool :=
- match n
- with 0 => true
- | 1 => false
- | S (S p) => even_test p
- end.
-
-
-Reset even_test.
-
-Fixpoint even_test (n:nat) : bool :=
- match n
- with
- | 0 => true
- | S p => odd_test p
- end
-with odd_test (n:nat) : bool :=
- match n
- with
- | 0 => false
- | S p => even_test p
- end.
-
-
-
-Eval simpl in even_test.
-
-
-
-Eval simpl in (fun x : nat => even_test x).
-
-Eval simpl in (fun x : nat => plus 5 x).
-Eval simpl in (fun x : nat => even_test (plus 5 x)).
-
-Eval simpl in (fun x : nat => even_test (plus x 5)).
-
-
-Section Principle_of_Induction.
-Variable P : nat -> Prop.
-Hypothesis base_case : P 0.
-Hypothesis inductive_step : forall n:nat, P n -> P (S n).
-Fixpoint nat_ind (n:nat) : (P n) :=
- match n return P n with
- | 0 => base_case
- | S m => inductive_step m (nat_ind m)
- end.
-
-End Principle_of_Induction.
-
-Scheme Even_induction := Minimality for even Sort Prop
-with Odd_induction := Minimality for odd Sort Prop.
-
-Theorem even_plus_four : forall n:nat, even n -> even (4+n).
-Proof.
- intros n H.
- elim H using Even_induction with (P0 := fun n => odd (4+n));
- simpl;repeat constructor;assumption.
-Qed.
-
-
-Section Principle_of_Double_Induction.
-Variable P : nat -> nat ->Prop.
-Hypothesis base_case1 : forall x:nat, P 0 x.
-Hypothesis base_case2 : forall x:nat, P (S x) 0.
-Hypothesis inductive_step : forall n m:nat, P n m -> P (S n) (S m).
-Fixpoint nat_double_ind (n m:nat){struct n} : P n m :=
- match n, m return P n m with
- | 0 , x => base_case1 x
- | (S x), 0 => base_case2 x
- | (S x), (S y) => inductive_step x y (nat_double_ind x y)
- end.
-End Principle_of_Double_Induction.
-
-Section Principle_of_Double_Recursion.
-Variable P : nat -> nat -> Type.
-Hypothesis base_case1 : forall x:nat, P 0 x.
-Hypothesis base_case2 : forall x:nat, P (S x) 0.
-Hypothesis inductive_step : forall n m:nat, P n m -> P (S n) (S m).
-Fixpoint nat_double_rect (n m:nat){struct n} : P n m :=
- match n, m return P n m with
- | 0 , x => base_case1 x
- | (S x), 0 => base_case2 x
- | (S x), (S y) => inductive_step x y (nat_double_rect x y)
- end.
-End Principle_of_Double_Recursion.
-
-Definition min : nat -> nat -> nat :=
- nat_double_rect (fun (x y:nat) => nat)
- (fun (x:nat) => 0)
- (fun (y:nat) => 0)
- (fun (x y r:nat) => S r).
-
-Eval compute in (min 5 8).
-Eval compute in (min 8 5).
-
-
-
-Lemma not_circular : forall n:nat, n <> S n.
-Proof.
- intro n.
- apply nat_ind with (P:= fun n => n <> S n).
- discriminate.
- red; intros n0 Hn0 eqn0Sn0;injection eqn0Sn0;trivial.
-Qed.
-
-Definition eq_nat_dec : forall n p:nat , {n=p}+{n <> p}.
-Proof.
- intros n p.
- apply nat_double_rect with (P:= fun (n q:nat) => {q=p}+{q <> p}).
-Undo.
- pattern p,n.
- elim n using nat_double_rect.
- destruct x; auto.
- destruct x; auto.
- intros n0 m H; case H.
- intro eq; rewrite eq ; auto.
- intro neg; right; red ; injection 1; auto.
-Defined.
-
-Definition eq_nat_dec' : forall n p:nat, {n=p}+{n <> p}.
- decide equality.
-Defined.
-
-
-
-Require Import Le.
-Lemma le'_le : forall n p, le' n p -> n <= p.
-Proof.
- induction 1;auto with arith.
-Qed.
-
-Lemma le'_n_Sp : forall n p, le' n p -> le' n (S p).
-Proof.
- induction 1;auto.
-Qed.
-
-Hint Resolve le'_n_Sp.
-
-
-Lemma le_le' : forall n p, n<=p -> le' n p.
-Proof.
- induction 1;auto with arith.
-Qed.
-
-
-Print Acc.
-
-
-Require Import Minus.
-
-(*
-Fixpoint div (x y:nat){struct x}: nat :=
- if eq_nat_dec x 0
- then 0
- else if eq_nat_dec y 0
- then x
- else S (div (x-y) y).
-
-Error:
-Recursive definition of div is ill-formed.
-In environment
-div : nat -> nat -> nat
-x : nat
-y : nat
-_ : x <> 0
-_ : y <> 0
-
-Recursive call to div has principal argument equal to
-"x - y"
-instead of a subterm of x
-
-*)
-
-Lemma minus_smaller_S: forall x y:nat, x - y < S x.
-Proof.
- intros x y; pattern y, x;
- elim x using nat_double_ind.
- destruct x0; auto with arith.
- simpl; auto with arith.
- simpl; auto with arith.
-Qed.
-
-Lemma minus_smaller_positive : forall x y:nat, x <>0 -> y <> 0 ->
- x - y < x.
-Proof.
- destruct x; destruct y;
- ( simpl;intros; apply minus_smaller_S ||
- intros; absurd (0=0); auto).
-Qed.
-
-Definition minus_decrease : forall x y:nat, Acc lt x ->
- x <> 0 ->
- y <> 0 ->
- Acc lt (x-y).
-Proof.
- intros x y H; case H.
- intros Hz posz posy.
- apply Hz; apply minus_smaller_positive; assumption.
-Defined.
-
-Print minus_decrease.
-
-
-Definition div_aux (x y:nat)(H: Acc lt x):nat.
- fix div_aux 3.
- intros.
- refine (if eq_nat_dec x 0
- then 0
- else if eq_nat_dec y 0
- then y
- else div_aux (x-y) y _).
- apply (minus_decrease x y H);assumption.
-Defined.
-
-
-Print div_aux.
-(*
-div_aux =
-(fix div_aux (x y : nat) (H : Acc lt x) {struct H} : nat :=
- match eq_nat_dec x 0 with
- | left _ => 0
- | right _ =>
- match eq_nat_dec y 0 with
- | left _ => y
- | right _0 => div_aux (x - y) y (minus_decrease x y H _ _0)
- end
- end)
- : forall x : nat, nat -> Acc lt x -> nat
-*)
-
-Require Import Wf_nat.
-Definition div x y := div_aux x y (lt_wf x).
-
-Extraction div.
-(*
-let div x y =
- div_aux x y
-*)
-
-Extraction div_aux.
-
-(*
-let rec div_aux x y =
- match eq_nat_dec x O with
- | Left -> O
- | Right ->
- (match eq_nat_dec y O with
- | Left -> y
- | Right -> div_aux (minus x y) y)
-*)
-
-Lemma vector0_is_vnil : forall (A:Type)(v:Vector.t A 0), v = Vector.nil A.
-Proof.
- intros A v;inversion v.
-Abort.
-
-(*
- Lemma vector0_is_vnil_aux : forall (A:Type)(n:nat)(v:Vector.t A n),
- n= 0 -> v = Vector.nil A.
-
-Toplevel input, characters 40281-40287
-> Lemma vector0_is_vnil_aux : forall (A:Set)(n:nat)(v:Vector.t A n), n= 0 -> v = Vector.nil A.
-> ^^^^^^
-Error: In environment
-A : Set
-n : nat
-v : Vector.t A n
-e : n = 0
-The term "Vector.nil A" has type "Vector.t A 0" while it is expected to have type
- "Vector.t A n"
-*)
- Require Import JMeq.
-
-
-(* On devrait changer Set en Type ? *)
-
-Lemma vector0_is_vnil_aux : forall (A:Type)(n:nat)(v:Vector.t A n),
- n= 0 -> JMeq v (Vector.nil A).
-Proof.
- destruct v.
- auto.
- intro; discriminate.
-Qed.
-
-Lemma vector0_is_vnil : forall (A:Type)(v:Vector.t A 0), v = Vector.nil A.
-Proof.
- intros a v;apply JMeq_eq.
- apply vector0_is_vnil_aux.
- trivial.
-Qed.
-
-
-Implicit Arguments Vector.cons [A n].
-Implicit Arguments Vector.nil [A].
-Implicit Arguments Vector.hd [A n].
-Implicit Arguments Vector.tl [A n].
-
-Definition Vid : forall (A : Type)(n:nat), Vector.t A n -> Vector.t A n.
-Proof.
- destruct n; intro v.
- exact Vector.nil.
- exact (Vector.cons (Vector.hd v) (Vector.tl v)).
-Defined.
-
-Eval simpl in (fun (A:Type)(v:Vector.t A 0) => (Vid _ _ v)).
-
-Eval simpl in (fun (A:Type)(v:Vector.t A 0) => v).
-
-
-
-Lemma Vid_eq : forall (n:nat) (A:Type)(v:Vector.t A n), v=(Vid _ n v).
-Proof.
- destruct v.
- reflexivity.
- reflexivity.
-Defined.
-
-Theorem zero_nil : forall A (v:Vector.t A 0), v = Vector.nil.
-Proof.
- intros.
- change (Vector.nil (A:=A)) with (Vid _ 0 v).
- apply Vid_eq.
-Defined.
-
-
-Theorem decomp :
- forall (A : Type) (n : nat) (v : Vector.t A (S n)),
- v = Vector.cons (Vector.hd v) (Vector.tl v).
-Proof.
- intros.
- change (Vector.cons (Vector.hd v) (Vector.tl v)) with (Vid _ (S n) v).
- apply Vid_eq.
-Defined.
-
-
-
-Definition vector_double_rect :
- forall (A:Type) (P: forall (n:nat),(Vector.t A n)->(Vector.t A n) -> Type),
- P 0 Vector.nil Vector.nil ->
- (forall n (v1 v2 : Vector.t A n) a b, P n v1 v2 ->
- P (S n) (Vector.cons a v1) (Vector.cons b v2)) ->
- forall n (v1 v2 : Vector.t A n), P n v1 v2.
- induction n.
- intros; rewrite (zero_nil _ v1); rewrite (zero_nil _ v2).
- auto.
- intros v1 v2; rewrite (decomp _ _ v1);rewrite (decomp _ _ v2).
- apply X0; auto.
-Defined.
-
-Require Import Bool.
-
-Definition bitwise_or n v1 v2 : Vector.t bool n :=
- vector_double_rect bool (fun n v1 v2 => Vector.t bool n)
- Vector.nil
- (fun n v1 v2 a b r => Vector.cons (orb a b) r) n v1 v2.
-
-Fixpoint vector_nth (A:Type)(n:nat)(p:nat)(v:Vector.t A p){struct v}
- : option A :=
- match n,v with
- _ , Vector.nil => None
- | 0 , Vector.cons b _ => Some b
- | S n', @Vector.cons _ _ p' v' => vector_nth A n' p' v'
- end.
-
-Implicit Arguments vector_nth [A p].
-
-
-Lemma nth_bitwise : forall (n:nat) (v1 v2: Vector.t bool n) i a b,
- vector_nth i v1 = Some a ->
- vector_nth i v2 = Some b ->
- vector_nth i (bitwise_or _ v1 v2) = Some (orb a b).
-Proof.
- intros n v1 v2; pattern n,v1,v2.
- apply vector_double_rect.
- simpl.
- destruct i; discriminate 1.
- destruct i; simpl;auto.
- injection 1; injection 2;intros; subst a; subst b; auto.
-Qed.
-
- Set Implicit Arguments.
-
- CoInductive Stream (A:Type) : Type :=
- | Cons : A -> Stream A -> Stream A.
-
- CoInductive LList (A: Type) : Type :=
- | LNil : LList A
- | LCons : A -> LList A -> LList A.
-
-
-
-
-
- Definition head (A:Type)(s : Stream A) := match s with Cons a s' => a end.
-
- Definition tail (A : Type)(s : Stream A) :=
- match s with Cons a s' => s' end.
-
- CoFixpoint repeat (A:Type)(a:A) : Stream A := Cons a (repeat a).
-
- CoFixpoint iterate (A: Type)(f: A -> A)(a : A) : Stream A:=
- Cons a (iterate f (f a)).
-
- CoFixpoint map (A B:Type)(f: A -> B)(s : Stream A) : Stream B:=
- match s with Cons a tl => Cons (f a) (map f tl) end.
-
-Eval simpl in (fun (A:Type)(a:A) => repeat a).
-
-Eval simpl in (fun (A:Type)(a:A) => head (repeat a)).
-
-
-CoInductive EqSt (A: Type) : Stream A -> Stream A -> Prop :=
- eqst : forall s1 s2: Stream A,
- head s1 = head s2 ->
- EqSt (tail s1) (tail s2) ->
- EqSt s1 s2.
-
-
-Section Parks_Principle.
-Variable A : Type.
-Variable R : Stream A -> Stream A -> Prop.
-Hypothesis bisim1 : forall s1 s2:Stream A, R s1 s2 ->
- head s1 = head s2.
-Hypothesis bisim2 : forall s1 s2:Stream A, R s1 s2 ->
- R (tail s1) (tail s2).
-
-CoFixpoint park_ppl : forall s1 s2:Stream A, R s1 s2 ->
- EqSt s1 s2 :=
- fun s1 s2 (p : R s1 s2) =>
- eqst s1 s2 (bisim1 p)
- (park_ppl (bisim2 p)).
-End Parks_Principle.
-
-
-Theorem map_iterate : forall (A:Type)(f:A->A)(x:A),
- EqSt (iterate f (f x)) (map f (iterate f x)).
-Proof.
- intros A f x.
- apply park_ppl with
- (R:= fun s1 s2 => exists x: A,
- s1 = iterate f (f x) /\ s2 = map f (iterate f x)).
-
- intros s1 s2 (x0,(eqs1,eqs2));rewrite eqs1;rewrite eqs2;reflexivity.
- intros s1 s2 (x0,(eqs1,eqs2)).
- exists (f x0);split;[rewrite eqs1|rewrite eqs2]; reflexivity.
- exists x;split; reflexivity.
-Qed.
-
-Ltac infiniteproof f :=
- cofix f; constructor; [clear f| simpl; try (apply f; clear f)].
-
-
-Theorem map_iterate' : forall (A:Type)(f:A->A)(x:A),
- EqSt (iterate f (f x)) (map f (iterate f x)).
-infiniteproof map_iterate'.
- reflexivity.
-Qed.
-
-
-Implicit Arguments LNil [A].
-
-Lemma Lnil_not_Lcons : forall (A:Type)(a:A)(l:LList A),
- LNil <> (LCons a l).
- intros;discriminate.
-Qed.
-
-Lemma injection_demo : forall (A:Type)(a b : A)(l l': LList A),
- LCons a (LCons b l) = LCons b (LCons a l') ->
- a = b /\ l = l'.
-Proof.
- intros A a b l l' e; injection e; auto.
-Qed.
-
-
-Inductive Finite (A:Type) : LList A -> Prop :=
-| Lnil_fin : Finite (LNil (A:=A))
-| Lcons_fin : forall a l, Finite l -> Finite (LCons a l).
-
-CoInductive Infinite (A:Type) : LList A -> Prop :=
-| LCons_inf : forall a l, Infinite l -> Infinite (LCons a l).
-
-Lemma LNil_not_Infinite : forall (A:Type), ~ Infinite (LNil (A:=A)).
-Proof.
- intros A H;inversion H.
-Qed.
-
-Lemma Finite_not_Infinite : forall (A:Type)(l:LList A),
- Finite l -> ~ Infinite l.
-Proof.
- intros A l H; elim H.
- apply LNil_not_Infinite.
- intros a l0 F0 I0' I1.
- case I0'; inversion_clear I1.
- trivial.
-Qed.
-
-Lemma Not_Finite_Infinite : forall (A:Type)(l:LList A),
- ~ Finite l -> Infinite l.
-Proof.
- cofix H.
- destruct l.
- intro; absurd (Finite (LNil (A:=A)));[auto|constructor].
- constructor.
- apply H.
- red; intro H1;case H0.
- constructor.
- trivial.
-Qed.
-
-
-
diff --git a/doc/RecTutorial/coqartmacros.tex b/doc/RecTutorial/coqartmacros.tex
deleted file mode 100644
index 72d749269..000000000
--- a/doc/RecTutorial/coqartmacros.tex
+++ /dev/null
@@ -1,180 +0,0 @@
-\usepackage{url}
-
-\newcommand{\variantspringer}[1]{#1}
-\newcommand{\marginok}[1]{\marginpar{\raggedright OK:#1}}
-\newcommand{\tab}{{\null\hskip1cm}}
-\newcommand{\Ltac}{\mbox{\emph{$\cal L$}tac}}
-\newcommand{\coq}{\mbox{\emph{Coq}}}
-\newcommand{\lcf}{\mbox{\emph{LCF}}}
-\newcommand{\hol}{\mbox{\emph{HOL}}}
-\newcommand{\pvs}{\mbox{\emph{PVS}}}
-\newcommand{\isabelle}{\mbox{\emph{Isabelle}}}
-\newcommand{\prolog}{\mbox{\emph{Prolog}}}
-\newcommand{\goalbar}{\tt{}============================\it}
-\newcommand{\gallina}{\mbox{\emph{Gallina}}}
-\newcommand{\joker}{\texttt{\_}}
-\newcommand{\eprime}{\(\e^{\prime}\)}
-\newcommand{\Ztype}{\citecoq{Z}}
-\newcommand{\propsort}{\citecoq{Prop}}
-\newcommand{\setsort}{\citecoq{Set}}
-\newcommand{\typesort}{\citecoq{Type}}
-\newcommand{\ocaml}{\mbox{\emph{OCAML}}}
-\newcommand{\haskell}{\mbox{\emph{Haskell}}}
-\newcommand{\why}{\mbox{\emph{Why}}}
-\newcommand{\Pascal}{\mbox{\emph{Pascal}}}
-
-\newcommand{\ml}{\mbox{\emph{ML}}}
-
-\newcommand{\scheme}{\mbox{\emph{Scheme}}}
-\newcommand{\lisp}{\mbox{\emph{Lisp}}}
-
-\newcommand{\implarrow}{\mbox{$\Rightarrow$}}
-\newcommand{\metavar}[1]{?#1}
-\newcommand{\notincoq}[1]{#1}
-\newcommand{\coqscope}[1]{\%#1}
-\newcommand{\arrow}{\mbox{$\rightarrow$}}
-\newcommand{\fleche}{\arrow}
-\newcommand{\funarrow}{\mbox{$\Rightarrow$}}
-\newcommand{\ltacarrow}{\funarrow}
-\newcommand{\coqand}{\mbox{\(\wedge\)}}
-\newcommand{\coqor}{\mbox{\(\vee\)}}
-\newcommand{\coqnot}{\mbox{\(\neg\)}}
-\newcommand{\hide}[1]{}
-\newcommand{\hidedots}[1]{...}
-\newcommand{\sig}[3]{\texttt{\{}#1\texttt{:}#2 \texttt{|} #3\texttt{\}}}
-\renewcommand{\neg}{\sim}
-\renewcommand{\marginpar}[1]{}
-
-\addtocounter{secnumdepth}{1}
-\providecommand{\og}{«}
-\providecommand{\fg}{»}
-
-
-\newcommand{\hard}{\mbox{\small *}}
-\newcommand{\xhard}{\mbox{\small **}}
-\newcommand{\xxhard}{\mbox{\small ***}}
-
-%%% Operateurs, etc.
-\newcommand{\impl}{\mbox{$\rightarrow$}}
-\newcommand{\appli}[2]{\mbox{\tt{#1 #2}}}
-\newcommand{\applis}[1]{\mbox{\texttt{#1}}}
-\newcommand{\abst}[3]{\mbox{\tt{fun #1:#2 \funarrow #3}}}
-\newcommand{\coqle}{\mbox{$\leq$}}
-\newcommand{\coqge}{\mbox{$\geq$}}
-\newcommand{\coqdiff}{\mbox{$\neq$}}
-\newcommand{\coqiff}{\mbox{$\leftrightarrow$}}
-\newcommand{\prodsym}{\mbox{\(\forall\,\)}}
-\newcommand{\exsym}{\mbox{\(\exists\,\)}}
-
-\newcommand{\substsign}{/}
-\newcommand{\subst}[3]{\mbox{#1\{#2\substsign{}#3\}}}
-\newcommand{\anoabst}[2]{\mbox{\tt[#1]#2}}
-\newcommand{\letin}[3]{\mbox{\tt let #1:=#2 in #3}}
-\newcommand{\prodep}[3]{\mbox{\tt \(\forall\,\)#1:#2,$\,$#3}}
-\newcommand{\prodplus}[2]{\mbox{\tt\(\forall\,\)$\,$#1,$\,$#2}}
-\newcommand{\dom}[1]{\textrm{dom}(#1)} % domaine d'un contexte (log function)
-\newcommand{\norm}[1]{\textrm{n}(#1)} % forme normale (log function)
-\newcommand{\coqZ}[1]{\mbox{\tt{`#1`}}}
-\newcommand{\coqnat}[1]{\mbox{\tt{#1}}}
-\newcommand{\coqcart}[2]{\mbox{\tt{#1*#2}}}
-\newcommand{\alphacong}{\mbox{$\,\cong_{\alpha}\,$}} % alpha-congruence
-\newcommand{\betareduc}{\mbox{$\,\rightsquigarrow_{\!\beta}$}\,} % beta reduction
-%\newcommand{\betastar}{\mbox{$\,\Rightarrow_{\!\beta}^{*}\,$}} % beta reduction
-\newcommand{\deltareduc}{\mbox{$\,\rightsquigarrow_{\!\delta}$}\,} % delta reduction
-\newcommand{\dbreduc}{\mbox{$\,\rightsquigarrow_{\!\delta\beta}$}\,} % delta,beta reduction
-\newcommand{\ireduc}{\mbox{$\,\rightsquigarrow_{\!\iota}$}\,} % delta,beta reduction
-
-
-% jugement de typage
-\newcommand{\these}{\boldsymbol{\large \vdash}}
-\newcommand{\disj}{\mbox{$\backslash/$}}
-\newcommand{\conj}{\mbox{$/\backslash$}}
-%\newcommand{\juge}[3]{\mbox{$#1 \boldsymbol{\vdash} #2 : #3 $}}
-\newcommand{\juge}[4]{\mbox{$#1,#2 \these #3 \boldsymbol{:} #4 $}}
-\newcommand{\smalljuge}[3]{\mbox{$#1 \these #2 \boldsymbol{:} #3 $}}
-\newcommand{\goal}[3]{\mbox{$#1,#2 \these^{\!\!\!?} #3 $}}
-\newcommand{\sgoal}[2]{\mbox{$#1\these^{\!\!\!\!?} #2 $}}
-\newcommand{\reduc}[5]{\mbox{$#1,#2 \these #3 \rhd_{#4}#5 $}}
-\newcommand{\convert}[5]{\mbox{$#1,#2 \these #3 =_{#4}#5 $}}
-\newcommand{\convorder}[5]{\mbox{$#1,#2 \these #3\leq _{#4}#5 $}}
-\newcommand{\wouff}[2]{\mbox{$\emph{WF}(#1)[#2]$}}
-
-
-%\newcommand{\mthese}{\underset{M}{\vdash}}
-\newcommand{\mthese}{\boldsymbol{\vdash}_{\!\!M}}
-\newcommand{\type}{\boldsymbol{:}}
-
-% jugement absolu
-
-%\newcommand{\ajuge}[2]{\mbox{$ \boldsymbol{\vdash} #1 : #2 $}}
-\newcommand{\ajuge}[2]{\mbox{$\these #1 \boldsymbol{:} #2 $}}
-
-%%% logique minimale
-\newcommand{\propzero}{\mbox{$P_0$}} % types de Fzero
-
-%%% logique propositionnelle classique
-\newcommand {\ff}{\boldsymbol{f}} % faux
-\newcommand {\vv}{\boldsymbol{t}} % vrai
-
-\newcommand{\verite}{\mbox{$\cal{B}$}} % {\ff,\vv}
-\newcommand{\sequ}[2]{\mbox{$#1 \vdash #2 $}} % sequent
-\newcommand{\strip}[1]{#1^o} % enlever les variables d'un contexte
-
-
-
-%%% tactiques
-\newcommand{\decomp}{\delta} % decomposition
-\newcommand{\recomp}{\rho} % recomposition
-
-%%% divers
-\newcommand{\cqfd}{\mbox{\textbf{cqfd}}}
-\newcommand{\fail}{\mbox{\textbf{F}}}
-\newcommand{\succes}{\mbox{$\blacksquare$}}
-%%% Environnements
-
-
-%% Fzero
-\newcommand{\con}{\mbox{$\cal C$}}
-\newcommand{\var}{\mbox{$\cal V$}}
-
-\newcommand{\atomzero}{\mbox{${\cal A}_0$}} % types de base de Fzero
-\newcommand{\typezero}{\mbox{${\cal T}_0$}} % types de Fzero
-\newcommand{\termzero}{\mbox{$\Lambda_0$}} % termes de Fzero
-\newcommand{\conzero}{\mbox{$\cal C_0$}} % contextes de Fzero
-
-\newcommand{\buts}{\mbox{$\cal B$}} % buts
-
-%%% for drawing terms
-% abstraction [x:t]e
-\newcommand{\PicAbst}[3]{\begin{bundle}{\bf abst}\chunk{#1}\chunk{#2}\chunk{#3}%
- \end{bundle}}
-
-% the same in de Bruijn form
-\newcommand{\PicDbj}[2]{\begin{bundle}{\bf abst}\chunk{#1}\chunk{#2}
- \end{bundle}}
-
-
-% applications
-\newcommand{\PicAppl}[2]{\begin{bundle}{\bf appl}\chunk{#1}\chunk{#2}%
- \end{bundle}}
-
-% variables
-\newcommand{\PicVar}[1]{\begin{bundle}{\bf var}\chunk{#1}
- \end{bundle}}
-
-% constantes
-\newcommand{\PicCon}[1]{\begin{bundle}{\bf const}\chunk{#1}\end{bundle}}
-
-% arrows
-\newcommand{\PicImpl}[2]{\begin{bundle}{\impl}\chunk{#1}\chunk{#2}%
- \end{bundle}}
-
-
-
-%%%% scripts coq
-\newcommand{\prompt}{\mbox{\sl Coq $<\;$}}
-\newcommand{\natquicksort}{\texttt{nat\_quicksort}}
-\newcommand{\citecoq}[1]{\mbox{\texttt{#1}}}
-\newcommand{\safeit}{\it}
-\newtheorem{remarque}{Remark}[section]
-%\newtheorem{definition}{Definition}[chapter]
diff --git a/doc/RecTutorial/manbiblio.bib b/doc/RecTutorial/manbiblio.bib
deleted file mode 100644
index caee81782..000000000
--- a/doc/RecTutorial/manbiblio.bib
+++ /dev/null
@@ -1,870 +0,0 @@
-
-@STRING{toappear="To appear"}
-@STRING{lncs="Lecture Notes in Computer Science"}
-
-@TECHREPORT{RefManCoq,
- AUTHOR = {Bruno~Barras, Samuel~Boutin,
- Cristina~Cornes, Judicaël~Courant, Yann~Coscoy, David~Delahaye,
- Daniel~de~Rauglaudre, Jean-Christophe~Filliâtre, Eduardo~Giménez,
- Hugo~Herbelin, Gérard~Huet, Henri~Laulhère, César~Muñoz,
- Chetan~Murthy, Catherine~Parent-Vigouroux, Patrick~Loiseleur,
- Christine~Paulin-Mohring, Amokrane~Saïbi, Benjamin~Werner},
- INSTITUTION = {INRIA},
- TITLE = {{The Coq Proof Assistant Reference Manual -- Version V6.2}},
- YEAR = {1998}
-}
-
-@INPROCEEDINGS{Aud91,
- AUTHOR = {Ph. Audebaud},
- BOOKTITLE = {Proceedings of the sixth Conf. on Logic in Computer Science.},
- PUBLISHER = {IEEE},
- TITLE = {Partial {Objects} in the {Calculus of Constructions}},
- YEAR = {1991}
-}
-
-@PHDTHESIS{Aud92,
- AUTHOR = {Ph. Audebaud},
- SCHOOL = {{Universit\'e} Bordeaux I},
- TITLE = {Extension du Calcul des Constructions par Points fixes},
- YEAR = {1992}
-}
-
-@INPROCEEDINGS{Audebaud92b,
- AUTHOR = {Ph. Audebaud},
- BOOKTITLE = {{Proceedings of the 1992 Workshop on Types for Proofs and Programs}},
- EDITOR = {{B. Nordstr\"om and K. Petersson and G. Plotkin}},
- NOTE = {Also Research Report LIP-ENS-Lyon},
- PAGES = {pp 21--34},
- TITLE = {{CC+ : an extension of the Calculus of Constructions with fixpoints}},
- YEAR = {1992}
-}
-
-@INPROCEEDINGS{Augustsson85,
- AUTHOR = {L. Augustsson},
- TITLE = {{Compiling Pattern Matching}},
- BOOKTITLE = {Conference Functional Programming and
-Computer Architecture},
- YEAR = {1985}
-}
-
-@INPROCEEDINGS{EG94a,
- AUTHOR = {E. Gim\'enez},
- EDITORS = {P. Dybjer and B. Nordstr\"om and J. Smith},
- BOOKTITLE = {Workshop on Types for Proofs and Programs},
- PAGES = {39-59},
- SERIES = {LNCS},
- NUMBER = {996},
- TITLE = {{Codifying guarded definitions with recursive schemes}},
- YEAR = {1994},
- PUBLISHER = {Springer-Verlag},
-}
-
-@INPROCEEDINGS{EG95a,
- AUTHOR = {E. Gim\'enez},
- BOOKTITLE = {Workshop on Types for Proofs and Programs},
- SERIES = {LNCS},
- NUMBER = {1158},
- PAGES = {135-152},
- TITLE = {An application of co-Inductive types in Coq:
- verification of the Alternating Bit Protocol},
- EDITORS = {S. Berardi and M. Coppo},
- PUBLISHER = {Springer-Verlag},
- YEAR = {1995}
-}
-
-@PhdThesis{EG96,
- author = {E. Gim\'enez},
- title = {A Calculus of Infinite Constructions and its
- application to the verification of communicating systems},
- school = {Ecole Normale Sup\'erieure de Lyon},
- year = {1996}
-}
-
-@ARTICLE{BaCo85,
- AUTHOR = {J.L. Bates and R.L. Constable},
- JOURNAL = {ACM transactions on Programming Languages and Systems},
- TITLE = {Proofs as {Programs}},
- VOLUME = {7},
- YEAR = {1985}
-}
-
-@BOOK{Bar81,
- AUTHOR = {H.P. Barendregt},
- PUBLISHER = {North-Holland},
- TITLE = {The Lambda Calculus its Syntax and Semantics},
- YEAR = {1981}
-}
-
-@TECHREPORT{Bar91,
- AUTHOR = {H. Barendregt},
- INSTITUTION = {Catholic University Nijmegen},
- NOTE = {In Handbook of Logic in Computer Science, Vol II},
- NUMBER = {91-19},
- TITLE = {Lambda {Calculi with Types}},
- YEAR = {1991}
-}
-
-@BOOK{Bastad92,
- EDITOR = {B. Nordstr\"om and K. Petersson and G. Plotkin},
- PUBLISHER = {Available by ftp at site ftp.inria.fr},
- TITLE = {Proceedings of the 1992 Workshop on Types for Proofs and Programs},
- YEAR = {1992}
-}
-
-@BOOK{Bee85,
- AUTHOR = {M.J. Beeson},
- PUBLISHER = {Springer-Verlag},
- TITLE = {Foundations of Constructive Mathematics, Metamathematical Studies},
- YEAR = {1985}
-}
-
-@ARTICLE{BeKe92,
- AUTHOR = {G. Bellin and J. Ketonen},
- JOURNAL = {Theoretical Computer Science},
- PAGES = {115--142},
- TITLE = {A decision procedure revisited : Notes on direct logic, linear logic and its implementation},
- VOLUME = {95},
- YEAR = {1992}
-}
-
-@BOOK{Bis67,
- AUTHOR = {E. Bishop},
- PUBLISHER = {McGraw-Hill},
- TITLE = {Foundations of Constructive Analysis},
- YEAR = {1967}
-}
-
-@BOOK{BoMo79,
- AUTHOR = {R.S. Boyer and J.S. Moore},
- KEY = {BoMo79},
- PUBLISHER = {Academic Press},
- SERIES = {ACM Monograph},
- TITLE = {A computational logic},
- YEAR = {1979}
-}
-
-@MASTERSTHESIS{Bou92,
- AUTHOR = {S. Boutin},
- MONTH = sep,
- SCHOOL = {{Universit\'e Paris 7}},
- TITLE = {Certification d'un compilateur {ML en Coq}},
- YEAR = {1992}
-}
-
-@ARTICLE{Bru72,
- AUTHOR = {N.J. de Bruijn},
- JOURNAL = {Indag. Math.},
- TITLE = {{Lambda-Calculus Notation with Nameless Dummies, a Tool for Automatic Formula Manipulation, with Application to the Church-Rosser Theorem}},
- VOLUME = {34},
- YEAR = {1972}
-}
-
-@INCOLLECTION{Bru80,
- AUTHOR = {N.J. de Bruijn},
- BOOKTITLE = {to H.B. Curry : Essays on Combinatory Logic, Lambda Calculus and Formalism.},
- EDITOR = {J.P. Seldin and J.R. Hindley},
- PUBLISHER = {Academic Press},
- TITLE = {A survey of the project {Automath}},
- YEAR = {1980}
-}
-
-@TECHREPORT{Leroy90,
- AUTHOR = {X. Leroy},
- TITLE = {The {ZINC} experiment: an economical implementation
-of the {ML} language},
- INSTITUTION = {INRIA},
- NUMBER = {117},
- YEAR = {1990}
-}
-
-@BOOK{Caml,
- AUTHOR = {P. Weis and X. Leroy},
- PUBLISHER = {InterEditions},
- TITLE = {Le langage Caml},
- YEAR = {1993}
-}
-
-@TECHREPORT{CoC89,
- AUTHOR = {Projet Formel},
- INSTITUTION = {INRIA},
- NUMBER = {110},
- TITLE = {{The Calculus of Constructions. Documentation and user's guide, Version 4.10}},
- YEAR = {1989}
-}
-
-@INPROCEEDINGS{CoHu85a,
- AUTHOR = {Th. Coquand and G. Huet},
- ADDRESS = {Linz},
- BOOKTITLE = {EUROCAL'85},
- PUBLISHER = {Springer-Verlag},
- SERIES = {LNCS},
- TITLE = {{Constructions : A Higher Order Proof System for Mechanizing Mathematics}},
- VOLUME = {203},
- YEAR = {1985}
-}
-
-@Misc{Bar98,
- author = {B. Barras},
- title = {A formalisation of
- \uppercase{B}urali-\uppercase{F}orti's paradox in Coq},
- howpublished = {Distributed within the bunch of contribution to the
- Coq system},
- year = {1998},
- month = {March},
- note = {\texttt{http://pauillac.inria.fr/coq}}
-}
-
-
-@INPROCEEDINGS{CoHu85b,
- AUTHOR = {Th. Coquand and G. Huet},
- BOOKTITLE = {Logic Colloquium'85},
- EDITOR = {The Paris Logic Group},
- PUBLISHER = {North-Holland},
- TITLE = {{Concepts Math\'ematiques et Informatiques formalis\'es dans le Calcul des Constructions}},
- YEAR = {1987}
-}
-
-@ARTICLE{CoHu86,
- AUTHOR = {Th. Coquand and G. Huet},
- JOURNAL = {Information and Computation},
- NUMBER = {2/3},
- TITLE = {The {Calculus of Constructions}},
- VOLUME = {76},
- YEAR = {1988}
-}
-
-@BOOK{Con86,
- AUTHOR = {R.L. {Constable et al.}},
- PUBLISHER = {Prentice-Hall},
- TITLE = {{Implementing Mathematics with the Nuprl Proof Development System}},
- YEAR = {1986}
-}
-
-@INPROCEEDINGS{CoPa89,
- AUTHOR = {Th. Coquand and C. Paulin-Mohring},
- BOOKTITLE = {Proceedings of Colog'88},
- EDITOR = {P. Martin-L{\"o}f and G. Mints},
- PUBLISHER = {Springer-Verlag},
- SERIES = {LNCS},
- TITLE = {Inductively defined types},
- VOLUME = {417},
- YEAR = {1990}
-}
-
-@PHDTHESIS{Coq85,
- AUTHOR = {Th. Coquand},
- MONTH = jan,
- SCHOOL = {Universit\'e Paris~7},
- TITLE = {Une Th\'eorie des Constructions},
- YEAR = {1985}
-}
-
-@INPROCEEDINGS{Coq86,
- AUTHOR = {Th. Coquand},
- ADDRESS = {Cambridge, MA},
- BOOKTITLE = {Symposium on Logic in Computer Science},
- PUBLISHER = {IEEE Computer Society Press},
- TITLE = {{An Analysis of Girard's Paradox}},
- YEAR = {1986}
-}
-
-@INPROCEEDINGS{Coq90,
- AUTHOR = {Th. Coquand},
- BOOKTITLE = {Logic and Computer Science},
- EDITOR = {P. Oddifredi},
- NOTE = {INRIA Research Report 1088, also in~\cite{CoC89}},
- PUBLISHER = {Academic Press},
- TITLE = {{Metamathematical Investigations of a Calculus of Constructions}},
- YEAR = {1990}
-}
-
-@INPROCEEDINGS{Coq92,
- AUTHOR = {Th. Coquand},
- BOOKTITLE = {in \cite{Bastad92}},
- TITLE = {{Pattern Matching with Dependent Types}},
- YEAR = {1992},
- crossref = {Bastad92}
-}
-
-@TECHREPORT{COQ93,
- AUTHOR = {G. Dowek and A. Felty and H. Herbelin and G. Huet and C. Murthy and C. Parent and C. Paulin-Mohring and B. Werner},
- INSTITUTION = {INRIA},
- MONTH = may,
- NUMBER = {154},
- TITLE = {{The Coq Proof Assistant User's Guide Version 5.8}},
- YEAR = {1993}
-}
-
-@INPROCEEDINGS{Coquand93,
- AUTHOR = {Th. Coquand},
- BOOKTITLE = {in \cite{Nijmegen93}},
- TITLE = {{Infinite Objects in Type Theory}},
- YEAR = {1993},
- crossref = {Nijmegen93}
-}
-
-@MASTERSTHESIS{Cou94a,
- AUTHOR = {J. Courant},
- MONTH = sep,
- SCHOOL = {DEA d'Informatique, ENS Lyon},
- TITLE = {Explicitation de preuves par r\'ecurrence implicite},
- YEAR = {1994}
-}
-
-@TECHREPORT{CPar93,
- AUTHOR = {C. Parent},
- INSTITUTION = {Ecole {Normale} {Sup\'erieure} de {Lyon}},
- MONTH = oct,
- NOTE = {Also in~\cite{Nijmegen93}},
- NUMBER = {93-29},
- TITLE = {Developing certified programs in the system {Coq}- {The} {Program} tactic},
- YEAR = {1993}
-}
-
-@PHDTHESIS{CPar95,
- AUTHOR = {C. Parent},
- SCHOOL = {Ecole {Normale} {Sup\'erieure} de {Lyon}},
- TITLE = {{Synth\`ese de preuves de programmes dans le Calcul des Constructions Inductives}},
- YEAR = {1995}
-}
-
-@TECHREPORT{Dow90,
- AUTHOR = {G. Dowek},
- INSTITUTION = {INRIA},
- NUMBER = {1283},
- TITLE = {{Naming and Scoping in a Mathematical Vernacular}},
- TYPE = {Research Report},
- YEAR = {1990}
-}
-
-@ARTICLE{Dow91a,
- AUTHOR = {G. Dowek},
- JOURNAL = {{Compte Rendu de l'Acad\'emie des Sciences}},
- NOTE = {(The undecidability of Third Order Pattern Matching in Calculi with Dependent Types or Type Constructors)},
- NUMBER = {12},
- PAGES = {951--956},
- TITLE = {{L'Ind\'ecidabilit\'e du Filtrage du Troisi\`eme Ordre dans les Calculs avec Types D\'ependants ou Constructeurs de Types}},
- VOLUME = {I, 312},
- YEAR = {1991}
-}
-
-@INPROCEEDINGS{Dow91b,
- AUTHOR = {G. Dowek},
- BOOKTITLE = {Proceedings of Mathematical Foundation of Computer Science},
- NOTE = {Also INRIA Research Report},
- PAGES = {151--160},
- PUBLISHER = {Springer-Verlag},
- SERIES = {LNCS},
- TITLE = {{A Second Order Pattern Matching Algorithm in the Cube of Typed {$\lambda$}-calculi}},
- VOLUME = {520},
- YEAR = {1991}
-}
-
-@PHDTHESIS{Dow91c,
- AUTHOR = {G. Dowek},
- MONTH = dec,
- SCHOOL = {{Universit\'e Paris 7}},
- TITLE = {{D\'emonstration automatique dans le Calcul des Constructions}},
- YEAR = {1991}
-}
-
-@ARTICLE{dowek93,
- AUTHOR = {G. Dowek},
- TITLE = {{A Complete Proof Synthesis Method for the Cube of Type Systems}},
- JOURNAL = {Journal Logic Computation},
- VOLUME = {3},
- NUMBER = {3},
- PAGES = {287--315},
- MONTH = {June},
- YEAR = {1993}
-}
-
-@UNPUBLISHED{Dow92a,
- AUTHOR = {G. Dowek},
- NOTE = {To appear in Theoretical Computer Science},
- TITLE = {{The Undecidability of Pattern Matching in Calculi where Primitive Recursive Functions are Representable}},
- YEAR = {1992}
-}
-
-@ARTICLE{Dow94a,
- AUTHOR = {G. Dowek},
- JOURNAL = {Annals of Pure and Applied Logic},
- VOLUME = {69},
- PAGES = {135--155},
- TITLE = {Third order matching is decidable},
- YEAR = {1994}
-}
-
-@INPROCEEDINGS{Dow94b,
- AUTHOR = {G. Dowek},
- BOOKTITLE = {Proceedings of the second international conference on typed lambda calculus and applications},
- TITLE = {{Lambda-calculus, Combinators and the Comprehension Schema}},
- YEAR = {1995}
-}
-
-@INPROCEEDINGS{Dyb91,
- AUTHOR = {P. Dybjer},
- BOOKTITLE = {Logical Frameworks},
- EDITOR = {G. Huet and G. Plotkin},
- PAGES = {59--79},
- PUBLISHER = {Cambridge University Press},
- TITLE = {{Inductive sets and families in {Martin-L{\"o}f's Type Theory} and their set-theoretic semantics : An inversion principle for {Martin-L\"of's} type theory}},
- VOLUME = {14},
- YEAR = {1991}
-}
-
-@ARTICLE{Dyc92,
- AUTHOR = {Roy Dyckhoff},
- JOURNAL = {The Journal of Symbolic Logic},
- MONTH = sep,
- NUMBER = {3},
- TITLE = {Contraction-free sequent calculi for intuitionistic logic},
- VOLUME = {57},
- YEAR = {1992}
-}
-
-@MASTERSTHESIS{Fil94,
- AUTHOR = {J.-C. Filli\^atre},
- MONTH = sep,
- SCHOOL = {DEA d'Informatique, ENS Lyon},
- TITLE = {Une proc\'edure de d\'ecision pour le {C}alcul des {P}r\'edicats {D}irect. {E}tude et impl\'ementation dans le syst\`eme {C}oq},
- YEAR = {1994}
-}
-
-@TECHREPORT{Filliatre95,
- AUTHOR = {J.-C. Filli\^atre},
- INSTITUTION = {LIP-ENS-Lyon},
- TITLE = {{A decision procedure for Direct Predicate Calculus}},
- TYPE = {Research report},
- NUMBER = {96--25},
- YEAR = {1995}
-}
-
-@UNPUBLISHED{Fle90,
- AUTHOR = {E. Fleury},
- MONTH = jul,
- NOTE = {Rapport de Stage},
- TITLE = {Implantation des algorithmes de {Floyd et de Dijkstra} dans le {Calcul des Constructions}},
- YEAR = {1990}
-}
-
-
-@TechReport{Gim98,
- author = {E. Gim\'nez},
- title = {A Tutorial on Recursive Types in Coq},
- institution = {INRIA},
- year = {1998}
-}
-
-@TECHREPORT{HKP97,
- author = {G. Huet and G. Kahn and Ch. Paulin-Mohring},
- title = {The {Coq} Proof Assistant - A tutorial, Version 6.1},
- institution = {INRIA},
- type = {rapport technique},
- month = {Août},
- year = {1997},
- note = {Version révisée distribuée avec {Coq}},
- number = {204},
-}
-
-@INPROCEEDINGS{Gir70,
- AUTHOR = {J.-Y. Girard},
- BOOKTITLE = {Proceedings of the 2nd Scandinavian Logic Symposium},
- PUBLISHER = {North-Holland},
- TITLE = {Une extension de l'interpr\'etation de {G\"odel} \`a l'analyse, et son application \`a l'\'elimination des coupures dans l'analyse et la th\'eorie des types},
- YEAR = {1970}
-}
-
-@PHDTHESIS{Gir72,
- AUTHOR = {J.-Y. Girard},
- SCHOOL = {Universit\'e Paris~7},
- TITLE = {Interpr\'etation fonctionnelle et \'elimination des coupures de l'arithm\'etique d'ordre sup\'erieur},
- YEAR = {1972}
-}
-
-@BOOK{Gir89,
- AUTHOR = {J.-Y. Girard and Y. Lafont and P. Taylor},
- PUBLISHER = {Cambridge University Press},
- SERIES = {Cambridge Tracts in Theoretical Computer Science 7},
- TITLE = {Proofs and Types},
- YEAR = {1989}
-}
-
-@MASTERSTHESIS{Hir94,
- AUTHOR = {D. Hirschkoff},
- MONTH = sep,
- SCHOOL = {DEA IARFA, Ecole des Ponts et Chauss\'ees, Paris},
- TITLE = {{Ecriture d'une tactique arithm\'etique pour le syst\`eme Coq}},
- YEAR = {1994}
-}
-
-@INCOLLECTION{How80,
- AUTHOR = {W.A. Howard},
- BOOKTITLE = {to H.B. Curry : Essays on Combinatory Logic, Lambda Calculus and Formalism.},
- EDITOR = {J.P. Seldin and J.R. Hindley},
- NOTE = {Unpublished 1969 Manuscript},
- PUBLISHER = {Academic Press},
- TITLE = {The Formulae-as-Types Notion of Constructions},
- YEAR = {1980}
-}
-
-@INCOLLECTION{HuetLevy79,
- AUTHOR = {G. Huet and J.-J. L\'{e}vy},
- TITLE = {Call by Need Computations in Non-Ambigous
-Linear Term Rewriting Systems},
- NOTE = {Also research report 359, INRIA, 1979},
- BOOKTITLE = {Computational Logic, Essays in Honor of
-Alan Robinson},
- EDITOR = {J.-L. Lassez and G. Plotkin},
- PUBLISHER = {The MIT press},
- YEAR = {1991}
-}
-
-@INPROCEEDINGS{Hue87,
- AUTHOR = {G. Huet},
- BOOKTITLE = {Programming of Future Generation Computers},
- EDITOR = {K. Fuchi and M. Nivat},
- NOTE = {Also in Proceedings of TAPSOFT87, LNCS 249, Springer-Verlag, 1987, pp 276--286},
- PUBLISHER = {Elsevier Science},
- TITLE = {Induction Principles Formalized in the {Calculus of Constructions}},
- YEAR = {1988}
-}
-
-@INPROCEEDINGS{Hue88,
- AUTHOR = {G. Huet},
- BOOKTITLE = {A perspective in Theoretical Computer Science. Commemorative Volume for Gift Siromoney},
- EDITOR = {R. Narasimhan},
- NOTE = {Also in~\cite{CoC89}},
- PUBLISHER = {World Scientific Publishing},
- TITLE = {{The Constructive Engine}},
- YEAR = {1989}
-}
-
-@BOOK{Hue89,
- EDITOR = {G. Huet},
- PUBLISHER = {Addison-Wesley},
- SERIES = {The UT Year of Programming Series},
- TITLE = {Logical Foundations of Functional Programming},
- YEAR = {1989}
-}
-
-@INPROCEEDINGS{Hue92,
- AUTHOR = {G. Huet},
- BOOKTITLE = {Proceedings of 12th FST/TCS Conference, New Delhi},
- PAGES = {229--240},
- PUBLISHER = {Springer Verlag},
- SERIES = {LNCS},
- TITLE = {{The Gallina Specification Language : A case study}},
- VOLUME = {652},
- YEAR = {1992}
-}
-
-@ARTICLE{Hue94,
- AUTHOR = {G. Huet},
- JOURNAL = {J. Functional Programming},
- PAGES = {371--394},
- PUBLISHER = {Cambridge University Press},
- TITLE = {Residual theory in $\lambda$-calculus: a formal development},
- VOLUME = {4,3},
- YEAR = {1994}
-}
-
-@ARTICLE{KeWe84,
- AUTHOR = {J. Ketonen and R. Weyhrauch},
- JOURNAL = {Theoretical Computer Science},
- PAGES = {297--307},
- TITLE = {A decidable fragment of {P}redicate {C}alculus},
- VOLUME = {32},
- YEAR = {1984}
-}
-
-@BOOK{Kle52,
- AUTHOR = {S.C. Kleene},
- PUBLISHER = {North-Holland},
- SERIES = {Bibliotheca Mathematica},
- TITLE = {Introduction to Metamathematics},
- YEAR = {1952}
-}
-
-@BOOK{Kri90,
- AUTHOR = {J.-L. Krivine},
- PUBLISHER = {Masson},
- SERIES = {Etudes et recherche en informatique},
- TITLE = {Lambda-calcul {types et mod\`eles}},
- YEAR = {1990}
-}
-
-@ARTICLE{Laville91,
- AUTHOR = {A. Laville},
- TITLE = {Comparison of Priority Rules in Pattern
-Matching and Term Rewriting},
- JOURNAL = {Journal of Symbolic Computation},
- VOLUME = {11},
- PAGES = {321--347},
- YEAR = {1991}
-}
-
-@BOOK{LE92,
- EDITOR = {G. Huet and G. Plotkin},
- PUBLISHER = {Cambridge University Press},
- TITLE = {Logical Environments},
- YEAR = {1992}
-}
-
-@INPROCEEDINGS{LePa94,
- AUTHOR = {F. Leclerc and C. Paulin-Mohring},
- BOOKTITLE = {{Types for Proofs and Programs, Types' 93}},
- EDITOR = {H. Barendregt and T. Nipkow},
- PUBLISHER = {Springer-Verlag},
- SERIES = {LNCS},
- TITLE = {{Programming with Streams in Coq. A case study : The Sieve of Eratosthenes}},
- VOLUME = {806},
- YEAR = {1994}
-}
-
-@BOOK{LF91,
- EDITOR = {G. Huet and G. Plotkin},
- PUBLISHER = {Cambridge University Press},
- TITLE = {Logical Frameworks},
- YEAR = {1991}
-}
-
-@BOOK{MaL84,
- AUTHOR = {{P. Martin-L\"of}},
- PUBLISHER = {Bibliopolis},
- SERIES = {Studies in Proof Theory},
- TITLE = {Intuitionistic Type Theory},
- YEAR = {1984}
-}
-
-@INPROCEEDINGS{manoury94,
- AUTHOR = {P. Manoury},
- TITLE = {{A User's Friendly Syntax to Define
-Recursive Functions as Typed $\lambda-$Terms}},
- BOOKTITLE = {{Types for Proofs and Programs, TYPES'94}},
- SERIES = {LNCS},
- VOLUME = {996},
- MONTH = jun,
- YEAR = {1994}
-}
-
-@ARTICLE{MaSi94,
- AUTHOR = {P. Manoury and M. Simonot},
- JOURNAL = {TCS},
- TITLE = {Automatizing termination proof of recursively defined function},
- YEAR = {To appear}
-}
-
-@TECHREPORT{maranget94,
- AUTHOR = {L. Maranget},
- INSTITUTION = {INRIA},
- NUMBER = {2385},
- TITLE = {{Two Techniques for Compiling Lazy Pattern Matching}},
- YEAR = {1994}
-}
-
-@INPROCEEDINGS{Moh89a,
- AUTHOR = {C. Paulin-Mohring},
- ADDRESS = {Austin},
- BOOKTITLE = {Sixteenth Annual ACM Symposium on Principles of Programming Languages},
- MONTH = jan,
- PUBLISHER = {ACM},
- TITLE = {Extracting ${F}_{\omega}$'s programs from proofs in the {Calculus of Constructions}},
- YEAR = {1989}
-}
-
-@PHDTHESIS{Moh89b,
- AUTHOR = {C. Paulin-Mohring},
- MONTH = jan,
- SCHOOL = {{Universit\'e Paris 7}},
- TITLE = {Extraction de programmes dans le {Calcul des Constructions}},
- YEAR = {1989}
-}
-
-@INPROCEEDINGS{Moh93,
- AUTHOR = {C. Paulin-Mohring},
- BOOKTITLE = {Proceedings of the conference Typed Lambda Calculi and Applications},
- EDITOR = {M. Bezem and J.-F. Groote},
- NOTE = {Also LIP research report 92-49, ENS Lyon},
- NUMBER = {664},
- PUBLISHER = {Springer-Verlag},
- SERIES = {LNCS},
- TITLE = {{Inductive Definitions in the System Coq - Rules and Properties}},
- YEAR = {1993}
-}
-
-@MASTERSTHESIS{Mun94,
- AUTHOR = {C. Mu\~noz},
- MONTH = sep,
- SCHOOL = {DEA d'Informatique Fondamentale, Universit\'e Paris 7},
- TITLE = {D\'emonstration automatique dans la logique propositionnelle intuitionniste},
- YEAR = {1994}
-}
-
-@BOOK{Nijmegen93,
- EDITOR = {H. Barendregt and T. Nipkow},
- PUBLISHER = {Springer-Verlag},
- SERIES = {LNCS},
- TITLE = {Types for Proofs and Programs},
- VOLUME = {806},
- YEAR = {1994}
-}
-
-@BOOK{NoPS90,
- AUTHOR = {B. {Nordstr\"om} and K. Peterson and J. Smith},
- BOOKTITLE = {Information Processing 83},
- PUBLISHER = {Oxford Science Publications},
- SERIES = {International Series of Monographs on Computer Science},
- TITLE = {Programming in {Martin-L\"of's} Type Theory},
- YEAR = {1990}
-}
-
-@ARTICLE{Nor88,
- AUTHOR = {B. {Nordstr\"om}},
- JOURNAL = {BIT},
- TITLE = {Terminating General Recursion},
- VOLUME = {28},
- YEAR = {1988}
-}
-
-@BOOK{Odi90,
- EDITOR = {P. Odifreddi},
- PUBLISHER = {Academic Press},
- TITLE = {Logic and Computer Science},
- YEAR = {1990}
-}
-
-@INPROCEEDINGS{PaMS92,
- AUTHOR = {M. Parigot and P. Manoury and M. Simonot},
- ADDRESS = {St. Petersburg, Russia},
- BOOKTITLE = {Logic Programming and automated reasoning},
- EDITOR = {A. Voronkov},
- MONTH = jul,
- NUMBER = {624},
- PUBLISHER = {Springer-Verlag},
- SERIES = {LNCS},
- TITLE = {{ProPre : A Programming language with proofs}},
- YEAR = {1992}
-}
-
-@ARTICLE{Par92,
- AUTHOR = {M. Parigot},
- JOURNAL = {Theoretical Computer Science},
- NUMBER = {2},
- PAGES = {335--356},
- TITLE = {{Recursive Programming with Proofs}},
- VOLUME = {94},
- YEAR = {1992}
-}
-
-@INPROCEEDINGS{Parent95b,
- AUTHOR = {C. Parent},
- BOOKTITLE = {{Mathematics of Program Construction'95}},
- PUBLISHER = {Springer-Verlag},
- SERIES = {LNCS},
- TITLE = {{Synthesizing proofs from programs in
-the Calculus of Inductive Constructions}},
- VOLUME = {947},
- YEAR = {1995}
-}
-
-@ARTICLE{PaWe92,
- AUTHOR = {C. Paulin-Mohring and B. Werner},
- JOURNAL = {Journal of Symbolic Computation},
- PAGES = {607--640},
- TITLE = {{Synthesis of ML programs in the system Coq}},
- VOLUME = {15},
- YEAR = {1993}
-}
-
-@INPROCEEDINGS{Prasad93,
- AUTHOR = {K.V. Prasad},
- BOOKTITLE = {{Proceedings of CONCUR'93}},
- PUBLISHER = {Springer-Verlag},
- SERIES = {LNCS},
- TITLE = {{Programming with broadcasts}},
- VOLUME = {715},
- YEAR = {1993}
-}
-
-@INPROCEEDINGS{puel-suarez90,
- AUTHOR = {L.Puel and A. Su\'arez},
- BOOKTITLE = {{Conference Lisp and Functional Programming}},
- SERIES = {ACM},
- PUBLISHER = {Springer-Verlag},
- TITLE = {{Compiling Pattern Matching by Term
-Decomposition}},
- YEAR = {1990}
-}
-
-@UNPUBLISHED{Rou92,
- AUTHOR = {J. Rouyer},
- MONTH = aug,
- NOTE = {To appear as a technical report},
- TITLE = {{D\'eveloppement de l'Algorithme d'Unification dans le Calcul des Constructions}},
- YEAR = {1992}
-}
-
-@TECHREPORT{Saibi94,
- AUTHOR = {A. Sa\"{\i}bi},
- INSTITUTION = {INRIA},
- MONTH = dec,
- NUMBER = {2345},
- TITLE = {{Axiomatization of a lambda-calculus with explicit-substitutions in the Coq System}},
- YEAR = {1994}
-}
-
-@MASTERSTHESIS{saidi94,
- AUTHOR = {H. Saidi},
- MONTH = sep,
- SCHOOL = {DEA d'Informatique Fondamentale, Universit\'e Paris 7},
- TITLE = {R\'esolution d'\'equations dans le syst\`eme T
- de G\"odel},
- YEAR = {1994}
-}
-
-@MASTERSTHESIS{Ter92,
- AUTHOR = {D. Terrasse},
- MONTH = sep,
- SCHOOL = {IARFA},
- TITLE = {{Traduction de TYPOL en COQ. Application \`a Mini ML}},
- YEAR = {1992}
-}
-
-@TECHREPORT{ThBeKa92,
- AUTHOR = {L. Th\'ery and Y. Bertot and G. Kahn},
- INSTITUTION = {INRIA Sophia},
- MONTH = may,
- NUMBER = {1684},
- TITLE = {Real theorem provers deserve real user-interfaces},
- TYPE = {Research Report},
- YEAR = {1992}
-}
-
-@BOOK{TrDa89,
- AUTHOR = {A.S. Troelstra and D. van Dalen},
- PUBLISHER = {North-Holland},
- SERIES = {Studies in Logic and the foundations of Mathematics, volumes 121 and 123},
- TITLE = {Constructivism in Mathematics, an introduction},
- YEAR = {1988}
-}
-
-@INCOLLECTION{wadler87,
- AUTHOR = {P. Wadler},
- TITLE = {Efficient Compilation of Pattern Matching},
- BOOKTITLE = {The Implementation of Functional Programming
-Languages},
- EDITOR = {S.L. Peyton Jones},
- PUBLISHER = {Prentice-Hall},
- YEAR = {1987}
-}
-
-@PHDTHESIS{Wer94,
- AUTHOR = {B. Werner},
- SCHOOL = {Universit\'e Paris 7},
- TITLE = {Une th\'eorie des constructions inductives},
- TYPE = {Th\`ese de Doctorat},
- YEAR = {1994}
-}
-
-
diff --git a/doc/RecTutorial/morebib.bib b/doc/RecTutorial/morebib.bib
deleted file mode 100644
index 438f2133d..000000000
--- a/doc/RecTutorial/morebib.bib
+++ /dev/null
@@ -1,55 +0,0 @@
-@book{coqart,
- title = "Interactive Theorem Proving and Program Development.
- Coq'Art: The Calculus of Inductive Constructions",
- author = {Yves Bertot and Pierre Castéran},
- publisher = "Springer Verlag",
- series = "Texts in Theoretical Computer Science. An EATCS series",
- year = 2004
-}
-
-@Article{Coquand:Huet,
- author = {Thierry Coquand and Gérard Huet},
- title = {The Calculus of Constructions},
- journal = {Information and Computation},
- year = {1988},
- volume = {76},
-}
-
-@INcollection{Coquand:metamathematical,
- author = "Thierry Coquand",
- title = "Metamathematical Investigations on a Calculus of Constructions",
- booktitle="Logic and Computer Science",
- year = {1990},
- editor="P. Odifreddi",
- publisher = "Academic Press",
-}
-
-@Misc{coqrefman,
- title = {The {C}oq reference manual},
- author={{C}oq {D}evelopment Team},
- note= {LogiCal Project, \texttt{http://coq.inria.fr/}}
- }
-
-@Misc{coqsite,
- author= {{C}oq {D}evelopment Team},
- title = {The \emph{Coq} proof assistant},
- note = {Documentation, system download. {C}ontact: \texttt{http://coq.inria.fr/}}
-}
-
-
-
-@Misc{Booksite,
- author = {Yves Bertot and Pierre Cast\'eran},
- title = {Coq'{A}rt: examples and exercises},
- note = {\url{http://www.labri.fr/Perso/~casteran/CoqArt}}
-}
-
-
-@InProceedings{conor:motive,
- author ="Conor McBride",
- title = "Elimination with a motive",
- booktitle = "Types for Proofs and Programs'2000",
- volume = 2277,
- pages = "197-217",
- year = "2002",
-}
diff --git a/doc/RecTutorial/recmacros.tex b/doc/RecTutorial/recmacros.tex
deleted file mode 100644
index 0334553f2..000000000
--- a/doc/RecTutorial/recmacros.tex
+++ /dev/null
@@ -1,75 +0,0 @@
-%===================================
-% Style of the document
-%===================================
-%\newtheorem{example}{Example}[section]
-%\newtheorem{exercise}{Exercise}[section]
-
-
-\newcommand{\comentario}[1]{\texttt{#1}}
-
-%===================================
-% Keywords
-%===================================
-
-\newcommand{\Prop}{\texttt{Prop}}
-\newcommand{\Set}{\texttt{Set}}
-\newcommand{\Type}{\texttt{Type}}
-\newcommand{\true}{\texttt{true}}
-\newcommand{\false}{\texttt{false}}
-\newcommand{\Lth}{\texttt{Lth}}
-
-\newcommand{\Nat}{\texttt{nat}}
-\newcommand{\nat}{\texttt{nat}}
-\newcommand{\Z} {\texttt{O}}
-\newcommand{\SUCC}{\texttt{S}}
-\newcommand{\pred}{\texttt{pred}}
-
-\newcommand{\False}{\texttt{False}}
-\newcommand{\True}{\texttt{True}}
-\newcommand{\I}{\texttt{I}}
-
-\newcommand{\natind}{\texttt{nat\_ind}}
-\newcommand{\natrec}{\texttt{nat\_rec}}
-\newcommand{\natrect}{\texttt{nat\_rect}}
-
-\newcommand{\eqT}{\texttt{eqT}}
-\newcommand{\identityT}{\texttt{identityT}}
-
-\newcommand{\map}{\texttt{map}}
-\newcommand{\iterates}{\texttt{iterates}}
-
-
-%===================================
-% Numbering
-%===================================
-
-
-\newtheorem{definition}{Definition}[section]
-\newtheorem{example}{Example}[section]
-
-
-%===================================
-% Judgements
-%===================================
-
-
-\newcommand{\JM}[2]{\ensuremath{#1 : #2}}
-
-%===================================
-% Expressions
-%===================================
-
-\newcommand{\Case}[3][]{\ensuremath{#1\textsf{Case}~#2~\textsf of}~#3~\textsf{end}}
-
-%=======================================
-
-\newcommand{\snreglados} [3] {\begin{tabular}{c} \ensuremath{#1} \\[2pt]
- \ensuremath{#2}\\ \hline \ensuremath{#3} \end{tabular}}
-
-
-\newcommand{\snregla} [2] {\begin{tabular}{c}
- \ensuremath{#1}\\ \hline \ensuremath{#2} \end{tabular}}
-
-
-%=======================================
-
diff --git a/doc/sphinx/MIGRATING b/doc/sphinx/MIGRATING
deleted file mode 100644
index fa6fe1537..000000000
--- a/doc/sphinx/MIGRATING
+++ /dev/null
@@ -1,238 +0,0 @@
-How to migrate the Coq Reference Manual to Sphinx
-=================================================
-
-# Install Python3 packages (requires Python 3, python3-pip, python3-setuptools)
-
- * pip3 install bs4 sphinx sphinx_rtd_theme pexpect antlr4-python3-runtime sphinxcontrib-bibtex
-
-# You may want to do this under a virtualenv, particularly if you end up with issues finding sphinxcontrib.bibtex. http://docs.python-guide.org/en/latest/dev/virtualenvs/
-
- * pip3 install virtualenv
- * virtualenv coqsphinxing # you may want to use -p to specify the python version
- * source coqsphinxing/bin/activate # activate the virtual environment
-
-# After activating the virtual environment you can run the above pip3 command to install sphinx. You will have to activate the virtual environment before building the docs in your session.
-
-# Add this Elisp code to .emacs, if you're using emacs (recommended):
-
- (defun sphinx/quote-coq-refman-region (left right &optional beg end count)
- (unless beg
- (if (region-active-p)
- (setq beg (region-beginning) end (region-end))
- (setq beg (point) end nil)))
- (unless count
- (setq count 1))
- (save-excursion
- (goto-char (or end beg))
- (dotimes (_ count) (insert right)))
- (save-excursion
- (goto-char beg)
- (dotimes (_ count) (insert left)))
- (if (and end (characterp left)) ;; Second test handles the ::`` case
- (goto-char (+ (* 2 count) end))
- (goto-char (+ count beg))))
-
- (defun sphinx/coqtop (beg end)
- (interactive (list (region-beginning) (region-end)))
- (replace-regexp "^Coq < " " " nil beg end)
- (indent-rigidly beg end -3)
- (goto-char beg)
- (insert ".. coqtop:: all\n\n"))
-
- (defun sphinx/rst-coq-action ()
- (interactive)
- (pcase (read-char "Command?")
- (?g (sphinx/quote-coq-refman-region ":g:`" "`"))
- (?n (sphinx/quote-coq-refman-region ":n:`" "`"))
- (?t (sphinx/quote-coq-refman-region ":token:`" "`"))
- (?m (sphinx/quote-coq-refman-region ":math:`" "`"))
- (?: (sphinx/quote-coq-refman-region "::`" "`"))
- (?` (sphinx/quote-coq-refman-region "``" "``"))
- (?c (sphinx/coqtop (region-beginning) (region-end)))))
-
- (global-set-key (kbd "<f12>") #'sphinx/rst-coq-action)
-
- With this code installed, you can hit "F12" followed by an appropriate key to do quick markup of text
- (this will make more sense once you've started editing the text).
-
-# Fork the Coq repo, if needed:
-
- https://github.com/coq/coq
-
-# Clone the repo to your work machine
-
-# Add Maxime Dénès's repo as a remote:
-
- git remote add sphinx https://github.com/maximedenes/coq.git
-
- (or choose a name other than "sphinx")
-
- Verify with:
-
- git remote -v
-
-# Fetch from the remote
-
- git fetch sphinx
-
-# Checkout the sphinx-doc branch
-
- git checkout sphinx-doc
-
- You should pull from the repo from time to time to keep your local copy up-to-date:
-
- git pull sphinx sphinx-doc
-
- You may want to create a new branch to do your work in.
-
-# Choose a Reference Manual chapter to work on at
-
- https://docs.google.com/document/d/1Yo7dV4OI0AY9Di-lsEQ3UTmn5ygGLlhxjym7cTCMCWU
-
-# For each chapter, raw ReStructuredText (the Sphinx format), created by the "html2rest" utility,
- is available in the directory porting/raw-rst/
-
- Elsewhere, depending on the chapter, there should be an almost-empty template file already created,
- which is in the location where the final version should go
-
-# Manually edit the .rst file, place it in the correct location
-
- There are small examples in sphinx/porting/, a larger example in language/gallina-extensions.rst
-
- (N.B.: the migration is a work-in-progress, your suggestions are welcome)
-
- Find the chapter you're working on from the online manual at https://coq.inria.fr/distrib/current/refman/.
- At the top of the file, after the chapter heading, add:
-
- :Source: https://coq.inria.fr/distrib/current/refman/the-chapter-file.html
- :Converted by: Your Name
-
- N.B.: These source and converted-by annotations should help for the migration phase. Later on,
- those annotations will be removed, and contributors will be mentioned in the Coq credits.
-
- Remove chapter numbers
-
- Replace section, subsection numbers with reference labels:
-
- .. _some-reference-label:
-
- Place the label before the section or subsection, followed by a blank line.
-
- Note the leading underscore. Use :ref:`some_reference-label` to refer to such a label; note the leading underscore is omitted.
- Many cross-references may be to other chapters. If the required label exists, use it. Otherwise, use a dummy reference of the form
- `TODO-n.n.n-mnemonic` we can fixup later. Example:
-
- :ref:`TODO-1.3.2-definitions`
-
- We can grep for those TODOs, and the existing subsection number makes it easy to find in the exisyting manual.
-
- For the particular case of references to chapters, we can use a
-convention for the cross-reference name, so no TODO is needed.
-
- :ref:`thegallinaspecificationlanguage`
-
-That is, the chapter label is the chapter title, all in lower-case,
-with no spaces or punctuation. For chapters with subtitles marked with
-a ":", like those for Omega and Nsatz, use just the chapter part
-preceding the ":". These labels should already be in the
-placeholder .rst files for each chapter.
-
-
- You can also label other items, like grammars, with the same syntax. To refer to such labels, not involving a
- section or subsection, use the syntax
-
- :ref:`Some link text <label-name>`
-
- Yes, the angle-brackets are needed here!
-
- For bibliographic references (those in biblio.bib), use :cite:`thecitation`.
-
- Grammars will get mangled by the translation. Look for "productionlist" in the examples, also see
- http://www.sphinx-doc.org/en/stable/markup/para.html.
-
- For Coq examples that appear, look at the "coqtop" syntax in porting/tricky-bits.rst. The Sphinx
- script will run coqtop on those examples, and can show the output (or not).
-
- The file replaces.rst contains replacement definitions for some items that are clumsy to write out otherwise.
- Use
-
- .. include:: replaces.rst
-
- to gain access to those definitions in your file (you might need a path prefix). Some especially-important
- replacements are |Cic|, |Coq|, |CoqIDE|, and |Gallina|, which display those names in small-caps. Please use them,
- so that they're rendered consistently.
-
- Similarly, there are some LaTeX macros in preamble.rst that can be useful.
-
- Conventions:
-
- - Keywords and other literal text is double-backquoted (e.g. ``Module``, ``Section``, ``(``, ``,``).
-
- - Metavariables are single-backquotes (e.g. `term`, `ident`)
-
- - Use the cmd directive for Vernacular commands, like:
-
- .. cmd:: Set Printing All.
-
- Within this directive, prefix metavariables (ident, term) with @:
-
- .. cmd:: Add Printing Let @ident.
-
- There's also the "cmdv" directive for variants of a command.
-
- - Use the "exn" and "warn" directives for errors and warnings:
-
- .. exn:: Something's not right.
- .. warn:: You shouldn't do that.
-
- - Use the "example" directive for examples
-
- - Use the "g" role for inline Gallina, like :g:`fun x => x`
-
- - Use code blocks for blocks of Gallina. You can use a double-colon at the end of a line::
-
- your code here
-
- which prints a single colon, or put the double-colon on a newline.
-
-::
-
- your other code here
-
-# Making changes to the text
-
- The goal of the migration is simply to change the storage format from LaTeX to ReStructuredText. The goal is not
- to make any organizational or other substantive changes to the text. If you do notice nits (misspellings, wrong
- verb tense, and so on), please do change them. For example, the programming language that Coq is written in is these days
- called "OCaml", and there are mentions of the older name "Objective Caml" in the reference manual that should be changed.
-
-# Build, view the manual
-
- In the root directory of your local repo, run "make sphinx". You can view the result in a browser by loading the HTML file
- associated with your chapter, which will be contained in the directory doc/sphinx/_build/html/ beneath the repo root directory.
- Make any changes you need until there are no build warnings and the output is perfect. :-)
-
-# Creating pull requests
-
- When your changes are done, commit them, push to your fork:
-
- git commit -m "useful commit message" file
- git push origin sphinx-doc
-
- (or push to another branch, if you've created one). Then go to your GitHub
- fork and create a pull request against Maxime's sphinx-doc
- branch. If your commit is recent, you should see a link on your
- fork's code page to do that. Otherwise, you may need to go to your
- branch on GitHub to do that.
-
-# Issues/Questions/Suggestions
-
- As the migration proceeds, if you have technical issues, have a more general question, or want to suggest something, please contact:
-
- Paul Steckler <steck@stecksoft.com>
- Maxime Dénès <maxime.denes@inria.fr>
-
-# Issues
-
- Should the stuff in replaces.rst go in preamble.rst?
- In LaTeX, some of the grammars add productions to existing nonterminals, like term ++= ... . How to indicate that?
diff --git a/doc/sphinx/README.rst b/doc/sphinx/README.rst
new file mode 100644
index 000000000..5f2f21f2b
--- /dev/null
+++ b/doc/sphinx/README.rst
@@ -0,0 +1,325 @@
+=============================
+ Documenting Coq with Sphinx
+=============================
+
+..
+ README.rst is auto-generated from README.template.rst and the coqrst docs;
+ use ``doc/tools/coqrst/regen_readme.py`` to rebuild it.
+
+Coq's reference manual is written in `reStructuredText <http://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html>`_ (“reST”), and compiled with `Sphinx <http://www.sphinx-doc.org/en/master/>`_.
+
+In addition to standard reST directives (a directive is similar to a LaTeX environment) and roles (a role is similar to a LaTeX command), the ``coqrst`` plugin loaded by the documentation uses a custom *Coq domain* — a set of Coq-specific directives that define *objects* like tactics, commands (vernacs), warnings, etc. —, some custom *directives*, and a few custom *roles*. Finally, this manual uses a small DSL to describe tactic invocations and commands.
+
+Coq objects
+===========
+
+Our Coq domain define multiple `objects`_. Each object has a *signature* (think *type signature*), followed by an optional body (a description of that object). The following example defines two objects: a variant of the ``simpl`` tactic, and an error that it may raise::
+
+ .. tacv:: simpl @pattern at {+ @num}
+ :name: simpl_at
+
+ This applies ``simpl`` only to the :n:`{+ @num}` occurrences of the subterms
+ matching :n:`@pattern` in the current goal.
+
+ .. exn:: Too few occurrences
+
+Objects are automatically collected into indices, and can be linked to using the role version of the object's directive. For example, you could link to the tactic variant above using ``:tacv:`simpl_at```, and to its exception using ``:exn:`Too few occurrences```.
+
+Names (link targets) are auto-generated for most simple objects, though they can always be overwritten using a ``:name:`` option, as shown above.
+
+- Options, errors, warnings have their name set to their signature, with ``...`` replacing all notation bits. For example, the auto-generated name of ``.. exn:: @qualid is not a module`` is ``... is not a module``, and a link to it would take the form ``:exn:`... is not a module```.
+- Vernacs (commands) have their name set to the first word of their signature. For example, the auto-generated name of ``Axiom @ident : @term`` is ``Axiom``, and a link to it would take the form ``:cmd:`Axiom```.
+- Vernac variants, tactic notations, and tactic variants do not have a default name.
+
+Notations
+---------
+
+The signatures of most objects can be written using a succinct DSL for Coq notations (think regular expressions written with a Lispy syntax). A typical signature might look like ``Hint Extern @num {? @pattern} => @tactic``, which means that the ``Hint Extern`` command takes a number (``num``), followed by an optional pattern, and a mandatory tactic. The language has the following constructs (the full grammar is in `TacticNotations.g </doc/tools/coqrst/notations/TacticNotations.g>`_):
+
+``@…``
+ A placeholder (``@ident``, ``@num``, ``@tactic``\ …)
+
+``{? …}``
+ an optional block
+
+``{* …}``, ``{+ …}``
+ an optional (``*``) or mandatory (``+``) block that can be repeated, with repetitions separated by spaces
+
+``{*, …}``, ``{+, …}``
+ an optional or mandatory repeatable block, with repetitions separated by commas
+
+``%|``, ``%{``, …
+ an escaped character (rendered without the leading ``%``)
+
+..
+ FIXME document the new subscript support
+
+As an exercise, what do the following patterns mean?
+
+.. code::
+
+ pattern {+, @term {? at {+ @num}}}
+ generalize {+, @term at {+ @num} as @ident}
+ fix @ident @num with {+ (@ident {+ @binder} {? {struct @ident'}} : @type)}
+
+Objects
+-------
+
+Here is the list of all objects of the Coq domain (The symbol :black_nib: indicates an object whose signature can be written using the notations DSL):
+
+``.. cmd::`` :black_nib: A Coq command.
+ Example::
+
+ .. cmd:: Infix "@symbol" := @term ({+, @modifier}).
+
+ This command is equivalent to :n:`…`.
+
+``.. cmdv::`` :black_nib: A variant of a Coq command.
+ Example::
+
+ .. cmd:: Axiom @ident : @term.
+
+ This command links :token:`term` to the name :token:`term` as its specification in
+ the global context. The fact asserted by :token:`term` is thus assumed as a
+ postulate.
+
+ .. cmdv:: Parameter @ident : @term.
+
+ This is equivalent to :n:`Axiom @ident : @term`.
+
+``.. exn::`` :black_nib: An error raised by a Coq command or tactic.
+ This commonly appears nested in the ``.. tacn::`` that raises the
+ exception.
+
+ Example::
+
+ .. tacv:: assert @form by @tactic
+
+ This tactic applies :n:`@tactic` to solve the subgoals generated by
+ ``assert``.
+
+ .. exn:: Proof is not complete
+
+ Raised if :n:`@tactic` does not fully solve the goal.
+
+``.. opt::`` :black_nib: A Coq option.
+ Example::
+
+ .. opt:: Nonrecursive Elimination Schemes
+
+ This option controls whether types declared with the keywords
+ :cmd:`Variant` and :cmd:`Record` get an automatic declaration of the
+ induction principles.
+
+``.. prodn::`` :black_nib: Grammar productions.
+ This is useful if you intend to document individual grammar productions.
+ Otherwise, use Sphinx's `production lists
+ <http://www.sphinx-doc.org/en/stable/markup/para.html#directive-productionlist>`_.
+
+``.. tacn::`` :black_nib: A tactic, or a tactic notation.
+ Example::
+
+ .. tacn:: do @num @expr
+
+ :token:`expr` is evaluated to ``v`` which must be a tactic value. …
+
+``.. tacv::`` :black_nib: A variant of a tactic.
+ Example::
+
+ .. tacn:: fail
+
+ This is the always-failing tactic: it does not solve any goal. It is
+ useful for defining other tacticals since it can be caught by
+ :tacn:`try`, :tacn:`repeat`, :tacn:`match goal`, or the branching
+ tacticals. …
+
+ .. tacv:: fail @natural
+
+ The number is the failure level. If no level is specified, it
+ defaults to 0. …
+
+``.. thm::`` A theorem.
+ Example::
+
+ .. thm:: Bound on the ceiling function
+
+ Let :math:`p` be an integer and :math:`c` a rational constant. Then
+ :math:`p \ge c \rightarrow p \ge \lceil{c}\rceil`.
+
+``.. warn::`` :black_nib: An warning raised by a Coq command or tactic..
+ Do not mistake this for ``.. warning::``; this directive is for warning
+ messages produced by Coq.
+
+
+ Example::
+
+ .. warn:: Ambiguous path
+
+ When the coercion :token:`qualid` is added to the inheritance graph, non
+ valid coercion paths are ignored.
+
+Coq directives
+==============
+
+In addition to the objects above, the ``coqrst`` Sphinx plugin defines the following directives:
+
+``.. coqtop::`` A reST directive to describe interactions with Coqtop.
+ Usage::
+
+ .. coqtop:: options…
+
+ Coq code to send to coqtop
+
+ Example::
+
+ .. coqtop:: in reset undo
+
+ Print nat.
+ Definition a := 1.
+
+ Here is a list of permissible options:
+
+ - Display options
+
+ - ``all``: Display input and output
+ - ``in``: Display only input
+ - ``out``: Display only output
+ - ``none``: Display neither (useful for setup commands)
+
+ - Behavior options
+
+ - ``reset``: Send a ``Reset Initial`` command before running this block
+ - ``undo``: Send an ``Undo n`` (``n`` = number of sentences) command after
+ running all the commands in this block
+
+ ``coqtop``\ 's state is preserved across consecutive ``.. coqtop::`` blocks
+ of the same document (``coqrst`` creates a single ``coqtop`` process per
+ reST source file). Use the ``reset`` option to reset Coq's state.
+
+``.. coqdoc::`` A reST directive to display Coqtop-formatted source code.
+ Usage::
+
+ .. coqdoc::
+
+ Coq code to highlight
+
+ Example::
+
+ .. coqdoc::
+
+ Definition test := 1.
+
+``.. example::`` A reST directive for examples.
+ This behaves like a generic admonition; see
+ http://docutils.sourceforge.net/docs/ref/rst/directives.html#generic-admonition
+ for more details.
+
+ Example::
+
+ .. example:: Adding a hint to a database
+
+ The following adds ``plus_comm`` to the ``plu`` database:
+
+ .. coqdoc::
+
+ Hint Resolve plus_comm : plu.
+
+``.. inference::`` A reST directive to format inference rules.
+ This also serves as a small illustration of the way to create new Sphinx
+ directives.
+
+ Usage::
+
+ .. inference:: name
+
+ newline-separated premisses
+ ------------------------
+ conclusion
+
+ Example::
+
+ .. inference:: Prod-Pro
+
+ \WTEG{T}{s}
+ s \in \Sort
+ \WTE{\Gamma::(x:T)}{U}{\Prop}
+ -----------------------------
+ \WTEG{\forall~x:T,U}{\Prop}
+
+``.. preamble::`` A reST directive for hidden math.
+ Mostly useful to let MathJax know about `\def`\ s and `\newcommand`\ s.
+
+ Example::
+
+ .. preamble::
+
+ \newcommand{\paren}[#1]{\left(#1\right)}
+
+Coq roles
+=========
+
+In addition to the objects and directives above, the ``coqrst`` Sphinx plugin defines the following roles:
+
+``:g:`` Coq code.
+ Use this for Gallina and Ltac snippets::
+
+ :g:`apply plus_comm; reflexivity`
+ :g:`Set Printing All.`
+ :g:`forall (x: t), P(x)`
+
+``:n:`` Any text using the notation syntax (``@id``, ``{+, …}``, etc.).
+ Use this to explain tactic equivalences. For example, you might write
+ this::
+
+ :n:`generalize @term as @ident` is just like :n:`generalize @term`, but
+ it names the introduced hypothesis :token:`ident`.
+
+ Note that this example also uses ``:token:``. That's because ``ident`` is
+ defined in the the Coq manual as a grammar production, and ``:token:``
+ creates a link to that. When referring to a placeholder that happens to be
+ a grammar production, ``:token:`…``` is typically preferable to ``:n:`@…```.
+
+``:production:`` A grammar production not included in a ``productionlist`` directive.
+ Useful to informally introduce a production, as part of running text.
+
+ Example::
+
+ :production:`string` indicates a quoted string.
+
+ You're not likely to use this role very commonly; instead, use a
+ `production list
+ <http://www.sphinx-doc.org/en/stable/markup/para.html#directive-productionlist>`_
+ and reference its tokens using ``:token:`…```.
+
+Tips and tricks
+===============
+
+Nested lemmas
+-------------
+
+The ``.. coqtop::`` directive does *not* reset Coq after running its contents. That is, the following will create two nested lemmas::
+
+ .. coqtop:: all
+
+ Lemma l1: 1 + 1 = 2.
+
+ .. coqtop:: all
+
+ Lemma l2: 2 + 2 <> 1.
+
+Add either ``undo`` to the first block or ``reset`` to the second block to avoid nesting lemmas.
+
+Abbreviations and macros
+------------------------
+
+Abbreviations and placeholders for specially-formatted names (like ``|Cic|``, ``|Coq|``, ``|CoqIDE|``, ``|Ltac|``, and ``|Gallina|``) are defined in a `separate file </doc/sphinx/replaces.rst>`_ included by most chapters of the manual. Some useful LaTeX macros are defined in `</doc/sphinx/preamble.rst>`_.
+
+Emacs
+-----
+
+The ``dev/tools/coqdev.el`` folder contains a convenient Emacs function to quickly insert Sphinx roles and quotes. It takes a single character (one of ``gntm:```), and inserts one of ``:g:``, ``:n:``, ``:t:``, or an arbitrary role, or double quotes. You can also select a region of text, and wrap it in single or double backticks using that function.
+
+Use the following snippet to bind it to :kbd:`F12` in ``rst-mode``::
+
+ (with-eval-after-load 'rst
+ (define-key rst-mode-map (kbd "<f12>") #'coqdev-sphinx-rst-coq-action))
diff --git a/doc/sphinx/README.template.rst b/doc/sphinx/README.template.rst
new file mode 100644
index 000000000..203251abf
--- /dev/null
+++ b/doc/sphinx/README.template.rst
@@ -0,0 +1,117 @@
+=============================
+ Documenting Coq with Sphinx
+=============================
+
+..
+ README.rst is auto-generated from README.template.rst and the coqrst docs;
+ use ``doc/tools/coqrst/regen_readme.py`` to rebuild it.
+
+Coq's reference manual is written in `reStructuredText <http://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html>`_ (“reST”), and compiled with `Sphinx <http://www.sphinx-doc.org/en/master/>`_.
+
+In addition to standard reST directives (a directive is similar to a LaTeX environment) and roles (a role is similar to a LaTeX command), the ``coqrst`` plugin loaded by the documentation uses a custom *Coq domain* — a set of Coq-specific directives that define *objects* like tactics, commands (vernacs), warnings, etc. —, some custom *directives*, and a few custom *roles*. Finally, this manual uses a small DSL to describe tactic invocations and commands.
+
+Coq objects
+===========
+
+Our Coq domain define multiple `objects`_. Each object has a *signature* (think *type signature*), followed by an optional body (a description of that object). The following example defines two objects: a variant of the ``simpl`` tactic, and an error that it may raise::
+
+ .. tacv:: simpl @pattern at {+ @num}
+ :name: simpl_at
+
+ This applies ``simpl`` only to the :n:`{+ @num}` occurrences of the subterms
+ matching :n:`@pattern` in the current goal.
+
+ .. exn:: Too few occurrences
+
+Objects are automatically collected into indices, and can be linked to using the role version of the object's directive. For example, you could link to the tactic variant above using ``:tacv:`simpl_at```, and to its exception using ``:exn:`Too few occurrences```.
+
+Names (link targets) are auto-generated for most simple objects, though they can always be overwritten using a ``:name:`` option, as shown above.
+
+- Options, errors, warnings have their name set to their signature, with ``...`` replacing all notation bits. For example, the auto-generated name of ``.. exn:: @qualid is not a module`` is ``... is not a module``, and a link to it would take the form ``:exn:`... is not a module```.
+- Vernacs (commands) have their name set to the first word of their signature. For example, the auto-generated name of ``Axiom @ident : @term`` is ``Axiom``, and a link to it would take the form ``:cmd:`Axiom```.
+- Vernac variants, tactic notations, and tactic variants do not have a default name.
+
+Notations
+---------
+
+The signatures of most objects can be written using a succinct DSL for Coq notations (think regular expressions written with a Lispy syntax). A typical signature might look like ``Hint Extern @num {? @pattern} => @tactic``, which means that the ``Hint Extern`` command takes a number (``num``), followed by an optional pattern, and a mandatory tactic. The language has the following constructs (the full grammar is in `TacticNotations.g </doc/tools/coqrst/notations/TacticNotations.g>`_):
+
+``@…``
+ A placeholder (``@ident``, ``@num``, ``@tactic``\ …)
+
+``{? …}``
+ an optional block
+
+``{* …}``, ``{+ …}``
+ an optional (``*``) or mandatory (``+``) block that can be repeated, with repetitions separated by spaces
+
+``{*, …}``, ``{+, …}``
+ an optional or mandatory repeatable block, with repetitions separated by commas
+
+``%|``, ``%{``, …
+ an escaped character (rendered without the leading ``%``)
+
+..
+ FIXME document the new subscript support
+
+As an exercise, what do the following patterns mean?
+
+.. code::
+
+ pattern {+, @term {? at {+ @num}}}
+ generalize {+, @term at {+ @num} as @ident}
+ fix @ident @num with {+ (@ident {+ @binder} {? {struct @ident'}} : @type)}
+
+Objects
+-------
+
+Here is the list of all objects of the Coq domain (The symbol :black_nib: indicates an object whose signature can be written using the notations DSL):
+
+[OBJECTS]
+
+Coq directives
+==============
+
+In addition to the objects above, the ``coqrst`` Sphinx plugin defines the following directives:
+
+[DIRECTIVES]
+
+Coq roles
+=========
+
+In addition to the objects and directives above, the ``coqrst`` Sphinx plugin defines the following roles:
+
+[ROLES]
+
+Tips and tricks
+===============
+
+Nested lemmas
+-------------
+
+The ``.. coqtop::`` directive does *not* reset Coq after running its contents. That is, the following will create two nested lemmas::
+
+ .. coqtop:: all
+
+ Lemma l1: 1 + 1 = 2.
+
+ .. coqtop:: all
+
+ Lemma l2: 2 + 2 <> 1.
+
+Add either ``undo`` to the first block or ``reset`` to the second block to avoid nesting lemmas.
+
+Abbreviations and macros
+------------------------
+
+Abbreviations and placeholders for specially-formatted names (like ``|Cic|``, ``|Coq|``, ``|CoqIDE|``, ``|Ltac|``, and ``|Gallina|``) are defined in a `separate file </doc/sphinx/replaces.rst>`_ included by most chapters of the manual. Some useful LaTeX macros are defined in `</doc/sphinx/preamble.rst>`_.
+
+Emacs
+-----
+
+The ``dev/tools/coqdev.el`` folder contains a convenient Emacs function to quickly insert Sphinx roles and quotes. It takes a single character (one of ``gntm:```), and inserts one of ``:g:``, ``:n:``, ``:t:``, or an arbitrary role, or double quotes. You can also select a region of text, and wrap it in single or double backticks using that function.
+
+Use the following snippet to bind it to :kbd:`F12` in ``rst-mode``::
+
+ (with-eval-after-load 'rst
+ (define-key rst-mode-map (kbd "<f12>") #'coqdev-sphinx-rst-coq-action))
diff --git a/doc/sphinx/addendum/extended-pattern-matching.rst b/doc/sphinx/addendum/extended-pattern-matching.rst
index 1d3b66173..c4f014772 100644
--- a/doc/sphinx/addendum/extended-pattern-matching.rst
+++ b/doc/sphinx/addendum/extended-pattern-matching.rst
@@ -46,7 +46,7 @@ the expressiveness of the theory remains the same. Once the stage of
parsing has finished only simple patterns remain. Re-nesting of
pattern is performed at printing time. An easy way to see the result
of the expansion is to toggle off the nesting performed at printing
-(use here :opt:`Set Printing Matching`), then by printing the term with :cmd:`Print`
+(use here :opt:`Printing Matching`), then by printing the term with :cmd:`Print`
if the term is a constant, or using the command :cmd:`Check`.
The extended ``match`` still accepts an optional *elimination predicate*
@@ -75,7 +75,7 @@ by:
Multiple patterns
-----------------
-Using multiple patterns in the definition of max lets us write:
+Using multiple patterns in the definition of ``max`` lets us write:
.. coqtop:: in undo
@@ -273,7 +273,7 @@ This option (off by default) removes parameters from constructors in patterns:
match l with
| nil => nil
| cons _ l' => l'
- end)
+ end).
Unset Asymmetric Patterns.
Implicit arguments in patterns
@@ -430,7 +430,7 @@ become impossible branches. In an impossible branch, you can answer
anything but False_rect unit has the advantage to be subterm of
anything.
-To be concrete: the tail function can be written:
+To be concrete: the ``tail`` function can be written:
.. coqtop:: in
@@ -591,24 +591,24 @@ generated expression and the original.
Here is a summary of the error messages corresponding to each
situation:
-.. exn:: The constructor @ident expects @num arguments
+.. exn:: The constructor @ident expects @num arguments.
The variable ident is bound several times in pattern termFound a constructor
of inductive type term while a constructor of term is expectedPatterns are
incorrect (because constructors are not applied to the correct number of the
arguments, because they are not linear or they are wrongly typed).
-.. exn:: Non exhaustive pattern-matching
+.. exn:: Non exhaustive pattern-matching.
The pattern matching is not exhaustive.
.. exn:: The elimination predicate term should be of arity @num (for non \
- dependent case) or @num (for dependent case)
+ dependent case) or @num (for dependent case).
The elimination predicate provided to match has not the expected arity.
.. exn:: Unable to infer a match predicate
- Either there is a type incompatibility or the problem involves dependencies
+ Either there is a type incompatibility or the problem involves dependencies.
There is a type mismatch between the different branches. The user should
provide an elimination predicate.
diff --git a/doc/sphinx/addendum/extraction.rst b/doc/sphinx/addendum/extraction.rst
index 38365e403..cb93d48a4 100644
--- a/doc/sphinx/addendum/extraction.rst
+++ b/doc/sphinx/addendum/extraction.rst
@@ -37,11 +37,11 @@ Generating ML Code
The next two commands are meant to be used for rapid preview of
extraction. They both display extracted term(s) inside |Coq|.
-.. cmd:: Extraction @qualid.
+.. cmd:: Extraction @qualid
Extraction of the mentioned object in the |Coq| toplevel.
-.. cmd:: Recursive Extraction @qualid ... @qualid.
+.. cmd:: Recursive Extraction {+ @qualid }
Recursive extraction of all the mentioned objects and
all their dependencies in the |Coq| toplevel.
@@ -49,7 +49,7 @@ extraction. They both display extracted term(s) inside |Coq|.
All the following commands produce real ML files. User can choose to
produce one monolithic file or one file per |Coq| library.
-.. cmd:: Extraction "@file" @qualid ... @qualid.
+.. cmd:: Extraction "@file" {+ @qualid }
Recursive extraction of all the mentioned objects and all
their dependencies in one monolithic `file`.
@@ -57,36 +57,36 @@ produce one monolithic file or one file per |Coq| library.
language to fulfill its syntactic conventions, keeping original
names as much as possible.
-.. cmd:: Extraction Library @ident.
+.. cmd:: Extraction Library @ident
Extraction of the whole |Coq| library ``ident.v`` to an ML module
``ident.ml``. In case of name clash, identifiers are here renamed
using prefixes ``coq_`` or ``Coq_`` to ensure a session-independent
renaming.
-.. cmd:: Recursive Extraction Library @ident.
+.. cmd:: Recursive Extraction Library @ident
Extraction of the |Coq| library ``ident.v`` and all other modules
``ident.v`` depends on.
-.. cmd:: Separate Extraction @qualid ... @qualid.
+.. cmd:: Separate Extraction {+ @qualid }
Recursive extraction of all the mentioned objects and all
their dependencies, just as ``Extraction "file"``,
but instead of producing one monolithic file, this command splits
the produced code in separate ML files, one per corresponding Coq
``.v`` file. This command is hence quite similar to
- ``Recursive Extraction Library``, except that only the needed
+ :cmd:`Recursive Extraction Library`, except that only the needed
parts of Coq libraries are extracted instead of the whole.
The naming convention in case of name clash is the same one as
- ``Extraction Library``: identifiers are here renamed using prefixes
+ :cmd:`Extraction Library`: identifiers are here renamed using prefixes
``coq_`` or ``Coq_``.
The following command is meant to help automatic testing of
the extraction, see for instance the ``test-suite`` directory
in the |Coq| sources.
-.. cmd:: Extraction TestCompile @qualid ... @qualid.
+.. cmd:: Extraction TestCompile {+ @qualid }
All the mentioned objects and all their dependencies are extracted
to a temporary |OCaml| file, just as in ``Extraction "file"``. Then
@@ -104,9 +104,9 @@ Setting the target language
The ability to fix target language is the first and more important
of the extraction options. Default is ``OCaml``.
-.. cmd:: Extraction Language OCaml.
-.. cmd:: Extraction Language Haskell.
-.. cmd:: Extraction Language Scheme.
+.. cmd:: Extraction Language OCaml
+.. cmd:: Extraction Language Haskell
+.. cmd:: Extraction Language Scheme
Inlining and optimizations
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -131,14 +131,14 @@ order to produce more readable code.
The type-preserving optimizations are controlled by the following |Coq| options:
-.. opt:: Extraction Optimize.
+.. opt:: Extraction Optimize
Default is on. This controls all type-preserving optimizations made on
the ML terms (mostly reduction of dummy beta/iota redexes, but also
simplifications on Cases, etc). Turn this option off if you want a
ML term as close as possible to the Coq term.
-.. opt:: Extraction Conservative Types.
+.. opt:: Extraction Conservative Types
Default is off. This controls the non type-preserving optimizations
made on ML terms (which try to avoid function abstraction of dummy
@@ -146,7 +146,7 @@ The type-preserving optimizations are controlled by the following |Coq| options:
implies that ``e':t'`` where ``e'`` and ``t'`` are the extracted
code of ``e`` and ``t`` respectively.
-.. opt:: Extraction KeepSingleton.
+.. opt:: Extraction KeepSingleton
Default is off. Normally, when the extraction of an inductive type
produces a singleton type (i.e. a type with only one constructor, and
@@ -155,7 +155,7 @@ The type-preserving optimizations are controlled by the following |Coq| options:
The typical example is ``sig``. This option allows disabling this
optimization when one wishes to preserve the inductive structure of types.
-.. opt:: Extraction AutoInline.
+.. opt:: Extraction AutoInline
Default is on. The extraction mechanism inlines the bodies of
some defined constants, according to some heuristics
@@ -163,22 +163,22 @@ The type-preserving optimizations are controlled by the following |Coq| options:
Those heuristics are not always perfect; if you want to disable
this feature, turn this option off.
-.. cmd:: Extraction Inline @qualid ... @qualid.
+.. cmd:: Extraction Inline {+ @qualid }
In addition to the automatic inline feature, the constants
mentionned by this command will always be inlined during extraction.
-.. cmd:: Extraction NoInline @qualid ... @qualid.
+.. cmd:: Extraction NoInline {+ @qualid }
Conversely, the constants mentionned by this command will
never be inlined during extraction.
-.. cmd:: Print Extraction Inline.
+.. cmd:: Print Extraction Inline
Prints the current state of the table recording the custom inlinings
declared by the two previous commands.
-.. cmd:: Reset Extraction Inline.
+.. cmd:: Reset Extraction Inline
Empties the table recording the custom inlinings (see the
previous commands).
@@ -213,7 +213,7 @@ code elimination performed during extraction, in a way which
is independent but complementary to the main elimination
principles of extraction (logical parts and types).
-.. cmd:: Extraction Implicit @qualid [ @ident ... @ident ].
+.. cmd:: Extraction Implicit @qualid [ {+ @ident } ]
This experimental command allows declaring some arguments of
`qualid` as implicit, i.e. useless in extracted code and hence to
@@ -223,11 +223,11 @@ principles of extraction (logical parts and types).
by a number indicating its position, starting from 1.
When an actual extraction takes place, an error is normally raised if the
-``Extraction Implicit`` declarations cannot be honored, that is
+:cmd:`Extraction Implicit` declarations cannot be honored, that is
if any of the implicited variables still occurs in the final code.
This behavior can be relaxed via the following option:
-.. opt:: Extraction SafeImplicits.
+.. opt:: Extraction SafeImplicits
Default is on. When this option is off, a warning is emitted
instead of an error if some implicited variables still occur in the
@@ -253,19 +253,19 @@ a closed term, and of course the system cannot guess the program which
realizes an axiom. Therefore, it is possible to tell the system
what ML term corresponds to a given axiom.
-.. cmd:: Extract Constant @qualid => @string.
+.. cmd:: Extract Constant @qualid => @string
Give an ML extraction for the given constant.
The `string` may be an identifier or a quoted string.
-.. cmd:: Extract Inlined Constant @qualid => @string.
+.. cmd:: Extract Inlined Constant @qualid => @string
Same as the previous one, except that the given ML terms will
be inlined everywhere instead of being declared via a ``let``.
.. note::
- This command is sugar for an ``Extract Constant`` followed
- by a ``Extraction Inline``. Hence a ``Reset Extraction Inline``
+ This command is sugar for an :cmd:`Extract Constant` followed
+ by a :cmd:`Extraction Inline`. Hence a :cmd:`Reset Extraction Inline`
will have an effect on the realized and inlined axiom.
.. caution:: It is the responsibility of the user to ensure that the ML
@@ -285,7 +285,7 @@ Notice that in the case of type scheme axiom (i.e. whose type is an
arity, that is a sequence of product finished by a sort), then some type
variables have to be given (as quoted strings). The syntax is then:
-.. cmdv:: Extract Constant @qualid @string ... @string => @string.
+.. cmdv:: Extract Constant @qualid @string ... @string => @string
The number of type variables is checked by the system. For example:
@@ -294,7 +294,7 @@ The number of type variables is checked by the system. For example:
Axiom Y : Set -> Set -> Set.
Extract Constant Y "'a" "'b" => " 'a * 'b ".
-Realizing an axiom via ``Extract Constant`` is only useful in the
+Realizing an axiom via :cmd:`Extract Constant` is only useful in the
case of an informative axiom (of sort ``Type`` or ``Set``). A logical axiom
have no computational content and hence will not appears in extracted
terms. But a warning is nonetheless issued if extraction encounters a
@@ -314,7 +314,7 @@ The system also provides a mechanism to specify ML terms for inductive
types and constructors. For instance, the user may want to use the ML
native boolean type instead of |Coq| one. The syntax is the following:
-.. cmd:: Extract Inductive @qualid => @string [ @string ... @string ].
+.. cmd:: Extract Inductive @qualid => @string [ {+ @string } ]
Give an ML extraction for the given inductive type. You must specify
extractions for the type itself (first `string`) and all its
@@ -322,7 +322,7 @@ native boolean type instead of |Coq| one. The syntax is the following:
the ML extraction must be an ML inductive datatype, and the native
pattern-matching of the language will be used.
-.. cmdv:: Extract Inductive @qualid => @string [ @string ... @string ] @string.
+.. cmdv:: Extract Inductive @qualid => @string [ {+ @string } ] @string
Same as before, with a final extra `string` that indicates how to
perform pattern-matching over this inductive type. In this form,
@@ -338,7 +338,7 @@ native boolean type instead of |Coq| one. The syntax is the following:
into |OCaml| ``int``, the code to provide has type:
``(unit->'a)->(int->'a)->int->'a``.
-.. caution:: As for ``Extract Constant``, this command should be used with care:
+.. caution:: As for :cmd:`Extract Constant`, this command should be used with care:
* The ML code provided by the user is currently **not** checked at all by
extraction, even for syntax errors.
@@ -356,7 +356,7 @@ native boolean type instead of |Coq| one. The syntax is the following:
ML type is an efficient representation. For instance, when extracting
``nat`` to |OCaml| ``int``, the function ``Nat.mul`` stays quadratic.
It might be interesting to associate this translation with
- some specific ``Extract Constant`` when primitive counterparts exist.
+ some specific :cmd:`Extract Constant` when primitive counterparts exist.
Typical examples are the following:
@@ -388,7 +388,7 @@ As an example of translation to a non-inductive datatype, let's turn
Avoiding conflicts with existing filenames
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When using ``Extraction Library``, the names of the extracted files
+When using :cmd:`Extraction Library`, the names of the extracted files
directly depends from the names of the |Coq| files. It may happen that
these filenames are in conflict with already existing files,
either in the standard library of the target language or in other
@@ -396,16 +396,16 @@ code that is meant to be linked with the extracted code.
For instance the module ``List`` exists both in |Coq| and in |OCaml|.
It is possible to instruct the extraction not to use particular filenames.
-.. cmd:: Extraction Blacklist @ident ... @ident.
+.. cmd:: Extraction Blacklist {+ @ident }
Instruct the extraction to avoid using these names as filenames
for extracted code.
-.. cmd:: Print Extraction Blacklist.
+.. cmd:: Print Extraction Blacklist
Show the current list of filenames the extraction should avoid.
-.. cmd:: Reset Extraction Blacklist.
+.. cmd:: Reset Extraction Blacklist
Allow the extraction to use any filename.
diff --git a/doc/sphinx/addendum/generalized-rewriting.rst b/doc/sphinx/addendum/generalized-rewriting.rst
index e4dea3487..e10e16c10 100644
--- a/doc/sphinx/addendum/generalized-rewriting.rst
+++ b/doc/sphinx/addendum/generalized-rewriting.rst
@@ -179,7 +179,7 @@ A parametric relation :g:`Aeq: forall (y1 : β1 ... ym : βm )`,
:g:`relation (A t1 ... tn)` over :g:`(A : αi -> ... αn -> Type)` can be
declared with the following command:
-.. cmd:: Add Parametric Relation (x1 : T1) ... (xn : Tk) : (A t1 ... tn) (Aeq t′1 ... t′m ) {? reflexivity proved by refl} {? symmetry proved by sym} {? transitivity proved by trans} as @ident.
+.. cmd:: Add Parametric Relation (x1 : T1) ... (xn : Tk) : (A t1 ... tn) (Aeq t′1 ... t′m ) {? reflexivity proved by refl} {? symmetry proved by sym} {? transitivity proved by trans} as @ident
after having required the ``Setoid`` module with the ``Require Setoid``
command.
@@ -218,15 +218,15 @@ For Leibniz equality, we may declare:
[reflexivity proved by @refl_equal A]
...
-Some tactics (``reflexivity``, ``symmetry``, ``transitivity``) work only on
+Some tactics (:tacn:`reflexivity`, :tacn:`symmetry`, :tacn:`transitivity`) work only on
relations that respect the expected properties. The remaining tactics
-(``replace``, ``rewrite`` and derived tactics such as ``autorewrite``) do not
+(`replace`, :tacn:`rewrite` and derived tactics such as :tacn:`autorewrite`) do not
require any properties over the relation. However, they are able to
replace terms with related ones only in contexts that are syntactic
compositions of parametric morphism instances declared with the
following command.
-.. cmd:: Add Parametric Morphism (x1 : T1 ) ... (xk : Tk ) : (f t1 ... tn ) with signature sig as @ident.
+.. cmd:: Add Parametric Morphism (x1 : T1 ) ... (xk : Tk ) : (f t1 ... tn ) with signature sig as @ident
The command declares ``f`` as a parametric morphism of signature ``sig``. The
identifier ``id`` gives a unique name to the morphism and it is used as
@@ -317,7 +317,7 @@ instance mechanism. The behavior on section close is to generalize the
instances by the variables of the section (and possibly hypotheses
used in the proofs of instance declarations) but not to export them in
the rest of the development for proof search. One can use the
-``Existing Instance`` command to do so outside the section, using the name of the
+cmd:`Existing Instance` command to do so outside the section, using the name of the
declared morphism suffixed by ``_Morphism``, or use the ``Global`` modifier
for the corresponding class instance declaration
(see :ref:`First Class Setoids and Morphisms <first-class-setoids-and-morphisms>`) at
@@ -427,7 +427,7 @@ equality over ordered lists) ``set_eq ==> set_eq ==> set_eq``
``multiset_eq ==> multiset_eq ==> multiset_eq`` (``multiset_eq``
being the equality over unordered lists).
-To declare multiple signatures for a morphism, repeat the ``Add Morphism``
+To declare multiple signatures for a morphism, repeat the :cmd:`Add Morphism`
command.
When morphisms have multiple signatures it can be the case that a
@@ -530,8 +530,8 @@ Tactics enabled on user provided relations
The following tactics, all prefixed by ``setoid_``, deal with arbitrary
registered relations and morphisms. Moreover, all the corresponding
-unprefixed tactics (i.e. ``reflexivity``, ``symmetry``, ``transitivity``,
-``replace``, ``rewrite``) have been extended to fall back to their prefixed
+unprefixed tactics (i.e. :tacn:`reflexivity`, :tacn:`symmetry`, :tacn:`transitivity`,
+:tacn:`replace`, :tacn:`rewrite`) have been extended to fall back to their prefixed
counterparts when the relation involved is not Leibniz equality.
Notice, however, that using the prefixed tactics it is possible to
pass additional arguments such as ``using relation``.
@@ -564,21 +564,23 @@ on a given type.
Every derived tactic that is based on the unprefixed forms of the
tactics considered above will also work up to user defined relations.
-For instance, it is possible to register hints for ``autorewrite`` that
+For instance, it is possible to register hints for :tacn:`autorewrite` that
are not proof of Leibniz equalities. In particular it is possible to
-exploit ``autorewrite`` to simulate normalization in a term rewriting
+exploit :tacn:`autorewrite` to simulate normalization in a term rewriting
system up to user defined equalities.
Printing relations and morphisms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The ``Print Instances`` command can be used to show the list of currently
+.. cmd:: Print Instances
+
+This command can be used to show the list of currently
registered ``Reflexive`` (using ``Print Instances Reflexive``), ``Symmetric``
or ``Transitive`` relations, Equivalences, PreOrders, PERs, and Morphisms
(implemented as ``Proper`` instances). When the rewriting tactics refuse
to replace a term in a context because the latter is not a composition
-of morphisms, the ``Print Instances`` commands can be useful to understand
+of morphisms, the :cmd:`Print Instances` command can be useful to understand
what additional morphisms should be registered.
@@ -596,7 +598,8 @@ packing together the reflexivity, symmetry and transitivity lemmas).
Notice that the syntax is not completely backward compatible since the
identifier was not required.
-.. cmd:: Add Morphism f : @ident.
+.. cmd:: Add Morphism f : @ident
+ :name: Add Morphism
The latter command also is restricted to the declaration of morphisms
without parameters. It is not fully backward compatible since the
@@ -610,11 +613,11 @@ Notice that several limitations of the old implementation have been
lifted. In particular, it is now possible to declare several relations
with the same carrier and several signatures for the same morphism.
Moreover, it is now also possible to declare several morphisms having
-the same signature. Finally, the replace and rewrite tactics can be
+the same signature. Finally, the :tacn:`replace` and :tacn:`rewrite` tactics can be
used to replace terms in contexts that were refused by the old
implementation. As discussed in the next section, the semantics of the
-new ``setoid_rewrite`` command differs slightly from the old one and
-``rewrite``.
+new :tacn:`setoid_rewrite` tactic differs slightly from the old one and
+:tacn:`rewrite`.
Extensions
@@ -624,8 +627,9 @@ Extensions
Rewriting under binders
~~~~~~~~~~~~~~~~~~~~~~~
-warning:: Due to compatibility issues, this feature is enabled only
-when calling the ``setoid_rewrite`` tactics directly and not ``rewrite``.
+.. warning::
+ Due to compatibility issues, this feature is enabled only
+ when calling the :tacn:`setoid_rewrite` tactic directly and not :tacn:`rewrite`.
To be able to rewrite under binding constructs, one must declare
morphisms with respect to pointwise (setoid) equivalence of functions.
@@ -672,12 +676,12 @@ where ``list_equiv`` implements an equivalence on lists parameterized by
an equivalence on the elements.
Note that when one does rewriting with a lemma under a binder using
-``setoid_rewrite``, the application of the lemma may capture the bound
+:tacn:`setoid_rewrite`, the application of the lemma may capture the bound
variable, as the semantics are different from rewrite where the lemma
-is first matched on the whole term. With the new ``setoid_rewrite``,
+is first matched on the whole term. With the new :tacn:`setoid_rewrite`,
matching is done on each subterm separately and in its local
environment, and all matches are rewritten *simultaneously* by
-default. The semantics of the previous ``setoid_rewrite`` implementation
+default. The semantics of the previous :tacn:`setoid_rewrite` implementation
can almost be recovered using the ``at 1`` modifier.
@@ -710,7 +714,7 @@ defined constants as transparent by default. This may slow down the
resolution due to a lot of unifications (all the declared ``Proper``
instances are tried at each node of the search tree). To speed it up,
declare your constant as rigid for proof search using the command
-``Typeclasses Opaque`` (see :ref:`TypeclassesTransparent`).
+:cmd:`Typeclasses Opaque`.
Strategies for rewriting
------------------------
@@ -809,8 +813,8 @@ strategy. Their counterparts ``bottomup`` and ``topdown`` perform as many
rewritings as possible, starting from the bottom or the top of the
term.
-Hint databases created for ``autorewrite`` can also be used
-by ``rewrite_strat`` using the ``hints`` strategy that applies any of the
+Hint databases created for :tacn:`autorewrite` can also be used
+by :tacn:`rewrite_strat` using the ``hints`` strategy that applies any of the
lemmas at the current subterm. The ``terms`` strategy takes the lemma
names directly as arguments. The ``eval`` strategy expects a reduction
expression (see :ref:`performingcomputations`) and succeeds
diff --git a/doc/sphinx/addendum/implicit-coercions.rst b/doc/sphinx/addendum/implicit-coercions.rst
index c48c2d7ce..09faa0676 100644
--- a/doc/sphinx/addendum/implicit-coercions.rst
+++ b/doc/sphinx/addendum/implicit-coercions.rst
@@ -65,7 +65,7 @@ conditions holds:
We then write :g:`f : C >-> D`. The restriction on the type
of coercions is called *the uniform inheritance condition*.
-.. note:: The abstract classe ``Sortclass`` can be used as a source class, but
+.. note:: The abstract class ``Sortclass`` can be used as a source class, but
the abstract class ``Funclass`` cannot.
To coerce an object :g:`t:C t₁..tₙ` of ``C`` towards ``D``, we have to
@@ -124,45 +124,45 @@ term consists of the successive application of its coercions.
Declaration of Coercions
-------------------------
-.. cmd:: Coercion @qualid : @class >-> @class.
+.. cmd:: Coercion @qualid : @class >-> @class
Declares the construction denoted by `qualid` as a coercion between
the two given classes.
- .. exn:: @qualid not declared
- .. exn:: @qualid is already a coercion
- .. exn:: Funclass cannot be a source class
- .. exn:: @qualid is not a function
- .. exn:: Cannot find the source class of @qualid
- .. exn:: Cannot recognize @class as a source class of @qualid
- .. exn:: @qualid does not respect the uniform inheritance condition
+ .. exn:: @qualid not declared.
+ .. exn:: @qualid is already a coercion.
+ .. exn:: Funclass cannot be a source class.
+ .. exn:: @qualid is not a function.
+ .. exn:: Cannot find the source class of @qualid.
+ .. exn:: Cannot recognize @class as a source class of @qualid.
+ .. exn:: @qualid does not respect the uniform inheritance condition.
.. exn:: Found target class ... instead of ...
- .. warn:: Ambiguous path
+ .. warn:: Ambiguous path.
- When the coercion `qualid` is added to the inheritance graph, non
- valid coercion paths are ignored; they are signaled by a warning
- displaying these paths of the form :g:`[f₁;..;fₙ] : C >-> D`.
+ When the coercion :token:`qualid` is added to the inheritance graph, non
+ valid coercion paths are ignored; they are signaled by a warning
+ displaying these paths of the form :g:`[f₁;..;fₙ] : C >-> D`.
- .. cmdv:: Local Coercion @qualid : @class >-> @class.
+ .. cmdv:: Local Coercion @qualid : @class >-> @class
- Declares the construction denoted by `qualid` as a coercion local to
- the current section.
+ Declares the construction denoted by `qualid` as a coercion local to
+ the current section.
- .. cmdv:: Coercion @ident := @term.
+ .. cmdv:: Coercion @ident := @term
- This defines `ident` just like ``Definition`` `ident` ``:=`` `term`,
- and then declares `ident` as a coercion between it source and its target.
+ This defines `ident` just like ``Definition`` `ident` ``:=`` `term`,
+ and then declares `ident` as a coercion between it source and its target.
- .. cmdv:: Coercion @ident := @term : @type.
+ .. cmdv:: Coercion @ident := @term : @type
- This defines `ident` just like ``Definition`` `ident` : `type` ``:=`` `term`,
- and then declares `ident` as a coercion between it source and its target.
+ This defines `ident` just like ``Definition`` `ident` : `type` ``:=`` `term`,
+ and then declares `ident` as a coercion between it source and its target.
- .. cmdv:: Local Coercion @ident := @term.
+ .. cmdv:: Local Coercion @ident := @term
- This defines `ident` just like ``Let`` `ident` ``:=`` `term`,
- and then declares `ident` as a coercion between it source and its target.
+ This defines `ident` just like ``Let`` `ident` ``:=`` `term`,
+ and then declares `ident` as a coercion between it source and its target.
Assumptions can be declared as coercions at declaration time.
This extends the grammar of assumptions from
@@ -202,7 +202,7 @@ grammar of inductive types from Figure :ref:`vernacular` as follows:
Especially, if the extra ``>`` is present in a constructor
declaration, this constructor is declared as a coercion.
-.. cmd:: Identity Coercion @ident : @class >-> @class.
+.. cmd:: Identity Coercion @ident : @class >-> @class
If ``C`` is the source `class` and ``D`` the destination, we check
that ``C`` is a constant with a body of the form
@@ -211,13 +211,13 @@ declaration, this constructor is declared as a coercion.
function with type :g:`forall (x₁:T₁)..(xₙ:Tₙ)(y:C x₁..xₙ),D t₁..tₘ`,
and we declare it as an identity coercion between ``C`` and ``D``.
- .. exn:: @class must be a transparent constant
+ .. exn:: @class must be a transparent constant.
- .. cmdv:: Local Identity Coercion @ident : @ident >-> @ident.
+ .. cmdv:: Local Identity Coercion @ident : @ident >-> @ident
Idem but locally to the current section.
- .. cmdv:: SubClass @ident := @type.
+ .. cmdv:: SubClass @ident := @type
:name: SubClass
If `type` is a class `ident'` applied to some arguments then
@@ -229,7 +229,7 @@ declaration, this constructor is declared as a coercion.
``Identity Coercion`` `Id_ident_ident'` : `ident` ``>->`` `ident'`.
- .. cmdv:: Local SubClass @ident := @type.
+ .. cmdv:: Local SubClass @ident := @type
Same as before but locally to the current section.
@@ -237,19 +237,19 @@ declaration, this constructor is declared as a coercion.
Displaying Available Coercions
-------------------------------
-.. cmd:: Print Classes.
+.. cmd:: Print Classes
Print the list of declared classes in the current context.
-.. cmd:: Print Coercions.
+.. cmd:: Print Coercions
Print the list of declared coercions in the current context.
-.. cmd:: Print Graph.
+.. cmd:: Print Graph
Print the list of valid coercion paths in the current context.
-.. cmd:: Print Coercion Paths @class @class.
+.. cmd:: Print Coercion Paths @class @class
Print the list of valid coercion paths between the two given classes.
@@ -263,9 +263,12 @@ Activating the Printing of Coercions
.. cmd:: Add Printing Coercion @qualid
- This command forces coercion denoted by :n:`@qualid` to be printed. To skip
- the printing of coercion :n:`@qualid`, use :cmd:`Remove Printing Coercion`. By
- default, a coercion is never printed.
+ This command forces coercion denoted by :n:`@qualid` to be printed.
+ By default, a coercion is never printed.
+
+.. cmd:: Remove Printing Coercion @qualid
+
+ Use this command, to skip the printing of coercion :n:`@qualid`.
.. _coercions-classes-as-records:
@@ -275,7 +278,7 @@ Classes as Records
We allow the definition of *Structures with Inheritance* (or classes as records)
by extending the existing :cmd:`Record` macro. Its new syntax is:
-.. cmdv:: Record {? >} @ident {? @binders} : @sort := {? @ident} { {+; @ident :{? >} @term } }.
+.. cmdv:: Record {? >} @ident {? @binders} : @sort := {? @ident} { {+; @ident :{? >} @term } }
The first identifier `ident` is the name of the defined record and
`sort` is its type. The optional identifier after ``:=`` is the name
@@ -291,7 +294,7 @@ by extending the existing :cmd:`Record` macro. Its new syntax is:
(this may fail if the uniform inheritance condition is not
satisfied).
-.. cmdv:: Structure {? >} @ident {? @binders} : @sort := {? @ident} { {+; @ident :{? >} @term } }.
+.. cmdv:: Structure {? >} @ident {? @binders} : @sort := {? @ident} { {+; @ident :{? >} @term } }
:name: Structure
This is a synonym of :cmd:`Record`.
diff --git a/doc/sphinx/addendum/micromega.rst b/doc/sphinx/addendum/micromega.rst
index 4f8cc34d4..0e9c23b9b 100644
--- a/doc/sphinx/addendum/micromega.rst
+++ b/doc/sphinx/addendum/micromega.rst
@@ -113,7 +113,7 @@ tactic *e.g.*, :math:`x = 10 * x / 10` is solved by `lra`.
.. tacn:: lia
:name: lia
-This tactic offers an alternative to the :tacn:`omega` and :tac:`romega`
+This tactic offers an alternative to the :tacn:`omega` and :tacn:`romega`
tactics. Roughly speaking, the deductive power of lia is the combined deductive
power of :tacn:`ring_simplify` and :tacn:`omega`. However, it solves linear
goals that :tacn:`omega` and :tacn:`romega` do not solve, such as the following
@@ -150,9 +150,10 @@ are a way to take into account the discreteness of :math:`\mathbb{Z}` by roundin
.. _ceil_thm:
-**Theorem**. Let :math:`p` be an integer and :math:`c` a rational constant. Then
+.. thm:: Bound on the ceiling function
- :math:`p \ge c \rightarrow p \ge \lceil{c}\rceil`
+ Let :math:`p` be an integer and :math:`c` a rational constant. Then
+ :math:`p \ge c \rightarrow p \ge \lceil{c}\rceil`.
For instance, from 2 x = 1 we can deduce
diff --git a/doc/sphinx/addendum/miscellaneous-extensions.rst b/doc/sphinx/addendum/miscellaneous-extensions.rst
index 80ea8a116..b6c35d8fa 100644
--- a/doc/sphinx/addendum/miscellaneous-extensions.rst
+++ b/doc/sphinx/addendum/miscellaneous-extensions.rst
@@ -11,7 +11,7 @@ Program derivation
|Coq| comes with an extension called ``Derive``, which supports program
derivation. Typically in the style of Bird and Meertens or derivations
of program refinements. To use the Derive extension it must first be
-required with ``Require Coq.Derive.Derive``. When the extension is loaded,
+required with ``Require Coq.derive.Derive``. When the extension is loaded,
it provides the following command:
.. cmd:: Derive @ident SuchThat @term As @ident
diff --git a/doc/sphinx/addendum/omega.rst b/doc/sphinx/addendum/omega.rst
index 20e40c550..80ce01620 100644
--- a/doc/sphinx/addendum/omega.rst
+++ b/doc/sphinx/addendum/omega.rst
@@ -12,24 +12,29 @@ This tactic does not need any parameter:
.. tacn:: omega
-``omega`` solves a goal in Presburger arithmetic, i.e. a universally
+:tacn:`omega` solves a goal in Presburger arithmetic, i.e. a universally
quantified formula made of equations and inequations. Equations may
be specified either on the type ``nat`` of natural numbers or on
the type ``Z`` of binary-encoded integer numbers. Formulas on
``nat`` are automatically injected into ``Z``. The procedure
may use any hypothesis of the current proof session to solve the goal.
-Multiplication is handled by ``omega`` but only goals where at
+Multiplication is handled by :tacn:`omega` but only goals where at
least one of the two multiplicands of products is a constant are
solvable. This is the restriction meant by "Presburger arithmetic".
If the tactic cannot solve the goal, it fails with an error message.
In any case, the computation eventually stops.
+.. tacv:: romega
+ :name: romega
+
+ To be documented.
+
Arithmetical goals recognized by ``omega``
------------------------------------------
-``omega`` applied only to quantifier-free formulas built from the
+:tacn:`omega` applied only to quantifier-free formulas built from the
connectors::
/\ \/ ~ ->
@@ -38,11 +43,11 @@ on atomic formulas. Atomic formulas are built from the predicates::
= < <= > >=
-on ``nat`` or ``Z``. In expressions of type ``nat``, ``omega`` recognizes::
+on ``nat`` or ``Z``. In expressions of type ``nat``, :tacn:`omega` recognizes::
+ - * S O pred
-and in expressions of type ``Z``, ``omega`` recognizes numeral constants and::
+and in expressions of type ``Z``, :tacn:`omega` recognizes numeral constants and::
+ - * Z.succ Z.pred
@@ -53,32 +58,32 @@ were arbitrary variables of type ``nat`` or ``Z``.
Messages from ``omega``
-----------------------
-When ``omega`` does not solve the goal, one of the following errors
+When :tacn:`omega` does not solve the goal, one of the following errors
is generated:
-.. exn:: omega can't solve this system
+.. exn:: omega can't solve this system.
This may happen if your goal is not quantifier-free (if it is
- universally quantified, try ``intros`` first; if it contains
- existentials quantifiers too, ``omega`` is not strong enough to solve your
+ universally quantified, try :tacn:`intros` first; if it contains
+ existentials quantifiers too, :tacn:`omega` is not strong enough to solve your
goal). This may happen also if your goal contains arithmetical
- operators unknown from ``omega``. Finally, your goal may be really
+ operators unknown from :tacn:`omega`. Finally, your goal may be really
wrong!
-.. exn:: omega: Not a quantifier-free goal
+.. exn:: omega: Not a quantifier-free goal.
If your goal is universally quantified, you should first apply
- ``intro`` as many time as needed.
+ :tacn:`intro` as many times as needed.
-.. exn:: omega: Unrecognized predicate or connective: @ident
+.. exn:: omega: Unrecognized predicate or connective: @ident.
.. exn:: omega: Unrecognized atomic proposition: ...
-.. exn:: omega: Can't solve a goal with proposition variables
+.. exn:: omega: Can't solve a goal with proposition variables.
-.. exn:: omega: Unrecognized proposition
+.. exn:: omega: Unrecognized proposition.
-.. exn:: omega: Can't solve a goal with non-linear products
+.. exn:: omega: Can't solve a goal with non-linear products.
.. exn:: omega: Can't solve a goal with equality on type ...
@@ -115,21 +120,23 @@ Options
.. opt:: Stable Omega
-This deprecated option (on by default) is for compatibility with Coq pre 8.5. It
-resets internal name counters to make executions of ``omega`` independent.
+ .. deprecated:: 8.5
+
+ This deprecated option (on by default) is for compatibility with Coq pre 8.5. It
+ resets internal name counters to make executions of :tacn:`omega` independent.
.. opt:: Omega UseLocalDefs
-This option (on by default) allows ``omega`` to use the bodies of local
-variables.
+ This option (on by default) allows :tacn:`omega` to use the bodies of local
+ variables.
.. opt:: Omega System
-This option (off by default) activate the printing of debug information
+ This option (off by default) activate the printing of debug information
.. opt:: Omega Action
-This option (off by default) activate the printing of debug information
+ This option (off by default) activate the printing of debug information
Technical data
--------------
@@ -149,7 +156,7 @@ Overview of the tactic
Overview of the OMEGA decision procedure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The OMEGA decision procedure involved in the ``omega`` tactic uses
+The OMEGA decision procedure involved in the :tacn:`omega` tactic uses
a small subset of the decision procedure presented in :cite:`TheOmegaPaper`
Here is an overview, look at the original paper for more information.
diff --git a/doc/sphinx/addendum/program.rst b/doc/sphinx/addendum/program.rst
index be30d1bc4..b685e68e4 100644
--- a/doc/sphinx/addendum/program.rst
+++ b/doc/sphinx/addendum/program.rst
@@ -145,13 +145,14 @@ prove some goals to construct the final definitions.
Program Definition
~~~~~~~~~~~~~~~~~~
-.. cmd:: Program Definition @ident := @term.
+.. cmd:: Program Definition @ident := @term
This command types the value term in Russell and generates proof
obligations. Once solved using the commands shown below, it binds the
final |Coq| term to the name ``ident`` in the environment.
- .. exn:: @ident already exists (Program Definition)
+ .. exn:: @ident already exists.
+ :name: @ident already exists. (Program Definition)
.. cmdv:: Program Definition @ident : @type := @term
@@ -166,7 +167,7 @@ Program Definition
.. exn:: In environment … the term: @term does not have type @type. Actually, it has type ...
- .. cmdv:: Program Definition @ident @binders : @type := @term.
+ .. cmdv:: Program Definition @ident @binders : @type := @term
This is equivalent to:
@@ -181,7 +182,7 @@ See also: Sections :ref:`vernac-controlling-the-reduction-strategies`, :tacn:`un
Program Fixpoint
~~~~~~~~~~~~~~~~
-.. cmd:: Program Fixpoint @ident @params {? {@order}} : @type := @term.
+.. cmd:: Program Fixpoint @ident @params {? {@order}} : @type := @term
The optional order annotation follows the grammar:
@@ -254,7 +255,7 @@ using the syntax:
Program Lemma
~~~~~~~~~~~~~
-.. cmd:: Program Lemma @ident : @type.
+.. cmd:: Program Lemma @ident : @type
The Russell language can also be used to type statements of logical
properties. It will generate obligations, try to solve them
@@ -349,7 +350,7 @@ Frequently Asked Questions
---------------------------
-.. exn:: Ill-formed recursive definition
+.. exn:: Ill-formed recursive definition.
This error can happen when one tries to define a function by structural
recursion on a subset object, which means the |Coq| function looks like:
diff --git a/doc/sphinx/addendum/ring.rst b/doc/sphinx/addendum/ring.rst
index ae666a0d4..47d3a7d7c 100644
--- a/doc/sphinx/addendum/ring.rst
+++ b/doc/sphinx/addendum/ring.rst
@@ -171,21 +171,21 @@ performs the simplification in the hypothesis named :n:`@ident`.
Error messages:
-.. exn:: not a valid ring equation
+.. exn:: Not a valid ring equation.
The conclusion of the goal is not provable in the corresponding ring theory.
-.. exn:: arguments of ring_simplify do not have all the same type
+.. exn:: Arguments of ring_simplify do not have all the same type.
``ring_simplify`` cannot simplify terms of several rings at the same
time. Invoke the tactic once per ring structure.
-.. exn:: cannot find a declared ring structure over @term
+.. exn:: Cannot find a declared ring structure over @term.
No ring has been declared for the type of the terms to be simplified.
Use ``Add Ring`` first.
-.. exn:: cannot find a declared ring structure for equality @term
+.. exn:: Cannot find a declared ring structure for equality @term.
Same as above is the case of the ``ring`` tactic.
@@ -303,7 +303,7 @@ following property:
The syntax for adding a new ring is
-.. cmd:: Add Ring @ident : @term {? ( @ring_mod {* , @ring_mod } )}.
+.. cmd:: Add Ring @ident : @term {? ( @ring_mod {* , @ring_mod } )}
The :n:`@ident` is not relevant. It is just used for error messages. The
:n:`@term` is a proof that the ring signature satisfies the (semi-)ring
@@ -396,18 +396,18 @@ div :n:`@term`
Error messages:
-.. exn:: bad ring structure
+.. exn:: Bad ring structure.
The proof of the ring structure provided is not
of the expected type.
-.. exn:: bad lemma for decidability of equality
+.. exn:: Bad lemma for decidability of equality.
The equality function
provided in the case of a computational ring has not the expected
type.
-.. exn:: ring operation should be declared as a morphism
+.. exn:: Ring operation should be declared as a morphism.
A setoid associated to the carrier of the ring structure has been found,
but the ring operation should be declared as morphism. See :ref:`tactics-enabled-on-user-provided-relations`.
@@ -656,7 +656,7 @@ zero for the correctness of the algorithm.
The syntax for adding a new field is
-.. cmd:: Add Field @ident : @term {? ( @field_mod {* , @field_mod } )}.
+.. cmd:: Add Field @ident : @term {? ( @field_mod {* , @field_mod } )}
The :n:`@ident` is not relevant. It is just used for error
messages. :n:`@term` is a proof that the field signature satisfies the
diff --git a/doc/sphinx/addendum/type-classes.rst b/doc/sphinx/addendum/type-classes.rst
index 3e95bd8c4..6c7258f9c 100644
--- a/doc/sphinx/addendum/type-classes.rst
+++ b/doc/sphinx/addendum/type-classes.rst
@@ -68,8 +68,8 @@ the remaining fields, e.g.:
Defined.
One has to take care that the transparency of every field is
-determined by the transparency of the ``Instance`` proof. One can use
-alternatively the ``Program Instance`` variant which has richer facilities
+determined by the transparency of the :cmd:`Instance` proof. One can use
+alternatively the :cmd:`Program Instance` variant which has richer facilities
for dealing with obligations.
@@ -269,12 +269,9 @@ the Existing Instance command to achieve the same effect.
Summary of the commands
-----------------------
+.. cmd:: Class @ident {? @binders} : {? @sort} := {? @ident} { {+; @ident :{? >} @term } }
-.. _Class:
-
-.. cmd:: Class @ident {? @binders} : {? @sort} := {? @ident} { {+; @ident :{? >} @term } }.
-
- The ``Class`` command is used to declare a type class with parameters
+ The :cmd:`Class` command is used to declare a type class with parameters
``binders`` and fields the declared record fields.
Variants:
@@ -299,12 +296,10 @@ Variants:
This variant declares a class a posteriori from a constant or
inductive definition. No methods or instances are defined.
-.. _Instance:
-
.. cmd:: Instance @ident {? @binders} : Class t1 … tn [| priority] := { field1 := b1 ; …; fieldi := bi }
-The ``Instance`` command is used to declare a type class instance named
-``ident`` of the class ``Class`` with parameters ``t1`` to ``tn`` and
+The :cmd:`Instance` command is used to declare a type class instance named
+``ident`` of the class :cmd:`Class` with parameters ``t1`` to ``tn`` and
fields ``b1`` to ``bi``, where each field must be a declared field of
the class. Missing fields must be filled in interactive proof mode.
@@ -314,112 +309,106 @@ optional priority can be declared, 0 being the highest priority as for
auto hints. If the priority is not specified, it defaults to the number
of non-dependent binders of the instance.
-..cmdv:: Instance @ident {? @binders} : forall {? @binders}, Class t1 … tn [| priority] := @term
+.. cmdv:: Instance @ident {? @binders} : forall {? @binders}, Class t1 … tn [| priority] := @term
This syntax is used for declaration of singleton class instances or
for directly giving an explicit term of type ``forall binders, Class
t1 … tn``. One need not even mention the unique field name for
singleton classes.
-..cmdv:: Global Instance
+.. cmdv:: Global Instance
One can use the ``Global`` modifier on instances declared in a
section so that their generalization is automatically redeclared
after the section is closed.
-..cmdv:: Program Instance
+.. cmdv:: Program Instance
+ :name: Program Instance
Switches the type-checking to Program (chapter :ref:`programs`) and
uses the obligation mechanism to manage missing fields.
-..cmdv:: Declare Instance
+.. cmdv:: Declare Instance
+ :name: Declare Instance
In a Module Type, this command states that a corresponding concrete
- instance should exist in any implementation of thisModule Type. This
- is similar to the distinction betweenParameter vs. Definition, or
- between Declare Module and Module.
+ instance should exist in any implementation of this Module Type. This
+ is similar to the distinction between :cmd:`Parameter` vs. :cmd:`Definition`, or
+ between :cmd:`Declare Module` and :cmd:`Module`.
-Besides the ``Class`` and ``Instance`` vernacular commands, there are a
+Besides the :cmd:`Class` and :cmd:`Instance` vernacular commands, there are a
few other commands related to type classes.
-.. _ExistingInstance:
-
-Existing Instance
-~~~~~~~~~~~~~~~~~
-
.. cmd:: Existing Instance {+ @ident} [| priority]
-This commands adds an arbitrary list of constants whose type ends with
-an applied type class to the instance database with an optional
-priority. It can be used for redeclaring instances at the end of
-sections, or declaring structure projections as instances. This is
-equivalent to ``Hint Resolve ident : typeclass_instances``, except it
-registers instances for ``Print Instances``.
-
-.. _Context:
-
-Context
-~~~~~~~
+ This commands adds an arbitrary list of constants whose type ends with
+ an applied type class to the instance database with an optional
+ priority. It can be used for redeclaring instances at the end of
+ sections, or declaring structure projections as instances. This is
+ equivalent to ``Hint Resolve ident : typeclass_instances``, except it
+ registers instances for :cmd:`Print Instances`.
.. cmd:: Context @binders
-Declares variables according to the given binding context, which might
-use :ref:`implicit-generalization`.
+ Declares variables according to the given binding context, which might
+ use :ref:`implicit-generalization`.
.. tacn:: typeclasses eauto
-
-This tactic uses a different resolution engine than :tacn:`eauto` and
-:tacn:`auto`. The main differences are the following:
-
-+ Contrary to ``eauto`` and ``auto``, the resolution is done entirely in
- the new proof engine (as of Coq v8.6), meaning that backtracking is
- available among dependent subgoals, and shelving goals is supported.
- typeclasses eauto is a multi-goal tactic. It analyses the dependencies
- between subgoals to avoid backtracking on subgoals that are entirely
- independent.
-
-+ When called with no arguments, typeclasses eauto uses
- thetypeclass_instances database by default (instead of core).
- Dependent subgoals are automatically shelved, and shelved goals can
- remain after resolution ends (following the behavior ofCoq 8.5).
- *Note: * As of Coq 8.6, all:once (typeclasses eauto) faithfully
- mimicks what happens during typeclass resolution when it is called
- during refinement/type-inference, except that *only* declared class
- subgoals are considered at the start of resolution during type
- inference, while “all” can select non-class subgoals as well. It might
- move to ``all:typeclasses eauto`` in future versions when the
- refinement engine will be able to backtrack.
-
-+ When called with specific databases (e.g. with), typeclasses eauto
- allows shelved goals to remain at any point during search and treat
- typeclasses goals like any other.
-
-+ The transparency information of databases is used consistently for
- all hints declared in them. It is always used when calling the
- unifier. When considering the local hypotheses, we use the transparent
- state of the first hint database given. Using an empty database
- (created with Create HintDb for example) with unfoldable variables and
- constants as the first argument of typeclasses eauto hence makes
- resolution with the local hypotheses use full conversion during
- unification.
-
-
-Variants:
-
-#. ``typeclasses eauto [num]``
-
- *Warning:* The semantics for the limit num
- is different than for auto. By default, if no limit is given the
- search is unbounded. Contrary to auto, introduction steps (intro) are
- counted, which might result in larger limits being necessary when
- searching with typeclasses eauto than auto.
-
-#. ``typeclasses eauto with {+ @ident}``
-
- This variant runs resolution with the given hint databases. It treats
- typeclass subgoals the same as other subgoals (no shelving of
- non-typeclass goals in particular).
+ :name: typeclasses eauto
+
+ This tactic uses a different resolution engine than :tacn:`eauto` and
+ :tacn:`auto`. The main differences are the following:
+
+ + Contrary to :tacn:`eauto` and :tacn:`auto`, the resolution is done entirely in
+ the new proof engine (as of Coq 8.6), meaning that backtracking is
+ available among dependent subgoals, and shelving goals is supported.
+ typeclasses eauto is a multi-goal tactic. It analyses the dependencies
+ between subgoals to avoid backtracking on subgoals that are entirely
+ independent.
+
+ + When called with no arguments, typeclasses eauto uses
+ the ``typeclass_instances`` database by default (instead of core).
+ Dependent subgoals are automatically shelved, and shelved goals can
+ remain after resolution ends (following the behavior of Coq 8.5).
+
+ .. note::
+ As of Coq 8.6, ``all:once (typeclasses eauto)`` faithfully
+ mimicks what happens during typeclass resolution when it is called
+ during refinement/type-inference, except that *only* declared class
+ subgoals are considered at the start of resolution during type
+ inference, while ``all`` can select non-class subgoals as well. It might
+ move to ``all:typeclasses eauto`` in future versions when the
+ refinement engine will be able to backtrack.
+
+ + When called with specific databases (e.g. with), typeclasses eauto
+ allows shelved goals to remain at any point during search and treat
+ typeclasses goals like any other.
+
+ + The transparency information of databases is used consistently for
+ all hints declared in them. It is always used when calling the
+ unifier. When considering the local hypotheses, we use the transparent
+ state of the first hint database given. Using an empty database
+ (created with :cmd:`Create HintDb` for example) with unfoldable variables and
+ constants as the first argument of typeclasses eauto hence makes
+ resolution with the local hypotheses use full conversion during
+ unification.
+
+
+ .. cmdv:: typeclasses eauto @num
+
+ .. warning::
+ The semantics for the limit :n:`@num`
+ is different than for auto. By default, if no limit is given the
+ search is unbounded. Contrary to auto, introduction steps (intro) are
+ counted, which might result in larger limits being necessary when
+ searching with typeclasses eauto than auto.
+
+ .. cmdv:: typeclasses eauto with {+ @ident}
+
+ This variant runs resolution with the given hint databases. It treats
+ typeclass subgoals the same as other subgoals (no shelving of
+ non-typeclass goals in particular).
.. tacn:: autoapply @term with @ident
:name: autoapply
@@ -441,34 +430,36 @@ Typeclasses Transparent, Typclasses Opaque
This command defines makes the identifiers transparent during type class
resolution.
- .. cmdv:: Typeclasses Opaque {+ @ident}
- :name: Typeclasses Opaque
+.. cmd:: Typeclasses Opaque {+ @ident}
+
+ Make the identifiers opaque for typeclass search. It is useful when some
+ constants prevent some unifications and make resolution fail. It is also
+ useful to declare constants which should never be unfolded during
+ proof-search, like fixpoints or anything which does not look like an
+ abbreviation. This can additionally speed up proof search as the typeclass
+ map can be indexed by such rigid constants (see
+ :ref:`thehintsdatabasesforautoandeauto`).
- Make the identifiers opaque for typeclass search. It is useful when some
- constants prevent some unifications and make resolution fail. It is also
- useful to declare constants which should never be unfolded during
- proof-search, like fixpoints or anything which does not look like an
- abbreviation. This can additionally speed up proof search as the typeclass
- map can be indexed by such rigid constants (see
- :ref:`thehintsdatabasesforautoandeauto`).
+By default, all constants and local variables are considered transparent. One
+should take care not to make opaque any constant that is used to abbreviate a
+type, like:
- By default, all constants and local variables are considered transparent. One
- should take care not to make opaque any constant that is used to abbreviate a
- type, like:
+::
- ::
+ relation A := A -> A -> Prop.
- relation A := A -> A -> Prop.
+This is equivalent to ``Hint Transparent, Opaque ident : typeclass_instances``.
- This is equivalent to ``Hint Transparent, Opaque ident : typeclass_instances``.
+Options
+~~~~~~~
.. opt:: Typeclasses Dependency Order
This option (on by default since 8.6) respects the dependency order
between subgoals, meaning that subgoals which are depended on by other
subgoals come first, while the non-dependent subgoals were put before
- the dependent ones previously (Coq v8.5 and below). This can result in
+ the dependent ones previously (Coq 8.5 and below). This can result in
quite different performance behaviors of proof search.
@@ -530,6 +521,23 @@ Typeclasses Transparent, Typclasses Opaque
solution to the typeclass goal of this class is found, we never
backtrack on it, assuming that it is canonical.
+.. opt:: Typeclasses Debug {? Verbosity @num}
+
+ These options allow to see the resolution steps of typeclasses that are
+ performed during search. The ``Debug`` option is synonymous to ``Debug
+ Verbosity 1``, and ``Debug Verbosity 2`` provides more information
+ (tried tactics, shelving of goals, etc…).
+
+.. opt:: Refine Instance Mode
+
+ This option allows to switch the behavior of instance declarations made through
+ the Instance command.
+
+ + When it is on (the default), instances that have unsolved holes in
+ their proof-term silently open the proof mode with the remaining
+ obligations to prove.
+
+ + When it is off, they fail with an error instead.
Typeclasses eauto `:=`
~~~~~~~~~~~~~~~~~~~~~~
@@ -546,26 +554,3 @@ Typeclasses eauto `:=`
default) or breadth-first search.
+ ``depth`` This sets the depth limit of the search.
-
-
-Set Typeclasses Debug
-~~~~~~~~~~~~~~~~~~~~~
-
-.. opt:: Typeclasses Debug {? Verbosity @num}
-
-These options allow to see the resolution steps of typeclasses that are
-performed during search. The ``Debug`` option is synonymous to ``Debug
-Verbosity 1``, and ``Debug Verbosity 2`` provides more information
-(tried tactics, shelving of goals, etc…).
-
-
-.. opt:: Refine Instance Mode
-
-This options allows to switch the behavior of instance declarations made through
-the Instance command.
-
-+ When it is on (the default), instances that have unsolved holes in
- their proof-term silently open the proof mode with the remaining
- obligations to prove.
-
-+ When it is off, they fail with an error instead.
diff --git a/doc/sphinx/addendum/universe-polymorphism.rst b/doc/sphinx/addendum/universe-polymorphism.rst
index c791fc906..6e7ccba63 100644
--- a/doc/sphinx/addendum/universe-polymorphism.rst
+++ b/doc/sphinx/addendum/universe-polymorphism.rst
@@ -79,7 +79,7 @@ levels.
When printing :g:`pidentity`, we can see the universes it binds in
the annotation :g:`@{Top.2}`. Additionally, when
-:g:`Set Printing Universes` is on we print the "universe context" of
+:opt:`Printing Universes` is on we print the "universe context" of
:g:`pidentity` consisting of the bound universes and the
constraints they must verify (for :g:`pidentity` there are no constraints).
@@ -169,7 +169,7 @@ declared cumulative using the :g:`Cumulative` prefix.
Declares the inductive as cumulative
-Alternatively, there is an option :g:`Set Polymorphic Inductive
+Alternatively, there is an option :opt:`Polymorphic Inductive
Cumulativity` which when set, makes all subsequent *polymorphic*
inductive definitions cumulative. When set, inductive types and the
like can be enforced to be non-cumulative using the :g:`NonCumulative`
@@ -229,7 +229,7 @@ Cumulative inductive types, coninductive types, variants and records
only make sense when they are universe polymorphic. Therefore, an
error is issued whenever the user uses the :g:`Cumulative` or
:g:`NonCumulative` prefix in a monomorphic context.
-Notice that this is not the case for the option :g:`Set Polymorphic Inductive Cumulativity`.
+Notice that this is not the case for the option :opt:`Polymorphic Inductive Cumulativity`.
That is, this option, when set, makes all subsequent *polymorphic*
inductive declarations cumulative (unless, of course the :g:`NonCumulative` prefix is used)
but has no effect on *monomorphic* inductive declarations.
@@ -367,7 +367,7 @@ Explicit Universes
The syntax has been extended to allow users to explicitly bind names
to universes and explicitly instantiate polymorphic definitions.
-.. cmd:: Universe @ident.
+.. cmd:: Universe @ident
In the monorphic case, this command declares a new global universe
named :g:`ident`, which can be referred to using its qualified name
@@ -378,7 +378,7 @@ to universes and explicitly instantiate polymorphic definitions.
declarations in the same section.
-.. cmd:: Constraint @ident @ord @ident.
+.. cmd:: Constraint @ident @ord @ident
This command declares a new constraint between named universes. The
order relation :n:`@ord` can be one of :math:`<`, :math:`≤` or :math:`=`. If consistent, the constraint
@@ -412,7 +412,7 @@ end of a definition or proof, we check that the only remaining
universes are the ones declared. In the term and in general in proof
mode, introduced universe names can be referred to in terms. Note that
local universe names shadow global universe names. During a proof, one
-can use :ref:`Show Universes <ShowUniverses>` to display the current context of universes.
+can use :cmd:`Show Universes` to display the current context of universes.
Definitions can also be instantiated explicitly, giving their full
instance:
@@ -438,7 +438,7 @@ underscore or by omitting the annotation to a polymorphic definition.
.. opt:: Strict Universe Declaration.
- The command ``Unset Strict Universe Declaration`` allows one to freely use
+ Turning this option off allows one to freely use
identifiers for universes without declaring them first, with the
semantics that the first use declares it. In this mode, the universe
names are not associated with the definition or proof once it has been
diff --git a/doc/sphinx/biblio.bib b/doc/sphinx/biblio.bib
index 97231c9ec..aeb45611e 100644
--- a/doc/sphinx/biblio.bib
+++ b/doc/sphinx/biblio.bib
@@ -1201,15 +1201,6 @@ Decomposition}},
note = {\url{https://proofgeneral.github.io/}}
}
-@Book{CoqArt,
- title = {Interactive Theorem Proving and Program Development.
- Coq'Art: The Calculus of Inductive Constructions},
- author = {Yves Bertot and Pierre Castéran},
- publisher = {Springer Verlag},
- series = {Texts in Theoretical Computer Science. An EATCS series},
- year = 2004
-}
-
@InCollection{wadler87,
author = {P. Wadler},
title = {Efficient Compilation of Pattern Matching},
diff --git a/doc/sphinx/conf.py b/doc/sphinx/conf.py
index 23bc9a2e4..1f7dd9d68 100755
--- a/doc/sphinx/conf.py
+++ b/doc/sphinx/conf.py
@@ -96,11 +96,13 @@ language = None
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = [
- '_build',
- 'Thumbs.db',
- '.DS_Store',
- 'introduction.rst',
- 'credits.rst'
+ '_build',
+ 'Thumbs.db',
+ '.DS_Store',
+ 'introduction.rst',
+ 'credits.rst',
+ 'README.rst',
+ 'README.template.rst'
]
# The reST default role (used for this markup: `text`) to use for all
diff --git a/doc/sphinx/index.rst b/doc/sphinx/index.rst
index 296330607..136f9088b 100644
--- a/doc/sphinx/index.rst
+++ b/doc/sphinx/index.rst
@@ -3,9 +3,6 @@
.. include:: preamble.rst
.. include:: replaces.rst
-Introduction
-===========================================
-
.. include:: introduction.rst
.. include:: credits.rst
diff --git a/doc/sphinx/introduction.rst b/doc/sphinx/introduction.rst
index 4a313df0c..75ff72c4d 100644
--- a/doc/sphinx/introduction.rst
+++ b/doc/sphinx/introduction.rst
@@ -2,12 +2,11 @@
Introduction
------------------------
-This document is the Reference Manual of the |Coq|  proof
-assistant. A companion volume, the |Coq| Tutorial, is provided for the
-beginners. It is advised to read the Tutorial first. A
-book :cite:`CoqArt` on practical uses of the |Coq| system was
-published in 2004 and is a good support for both the beginner and the
-advanced user.
+This document is the Reference Manual of the |Coq| proof assistant.
+To start using Coq, it is advised to first read a tutorial.
+Links to several tutorials can be found at
+https://coq.inria.fr/documentation (see also
+https://github.com/coq/coq/wiki#coq-tutorials).
The |Coq| system is designed to develop mathematical proofs, and
especially to write formal specifications, programs and to verify that
diff --git a/doc/sphinx/language/cic.rst b/doc/sphinx/language/cic.rst
index 5a2aa0a1f..f6bab0267 100644
--- a/doc/sphinx/language/cic.rst
+++ b/doc/sphinx/language/cic.rst
@@ -917,45 +917,33 @@ condition* for a constant :math:`X` in the following cases:
satisfies the nested positivity condition for :math:`X`
-For instance, if one considers the type
-
.. example::
- .. coqtop:: all
+ For instance, if one considers the following variant of a tree type
+ branching over the natural numbers:
+
+ .. coqtop:: in
- Module TreeExample.
- Inductive tree (A:Type) : Type :=
- | leaf : tree A
- | node : A -> (nat -> tree A) -> tree A.
+ Inductive nattree (A:Type) : Type :=
+ | leaf : nattree A
+ | node : A -> (nat -> nattree A) -> nattree A.
End TreeExample.
-::
+ Then every instantiated constructor of ``nattree A`` satisfies the nested positivity
+ condition for ``nattree``:
- [TODO Note: This commentary does not seem to correspond to the
- preceding example. Instead it is referring to the first example
- in Inductive Definitions section. It seems we should either
- delete the preceding example and refer the the example above of
- type `list A`, or else we should rewrite the commentary below.]
-
- Then every instantiated constructor of list A satisfies the nested positivity
- condition for list
- │
- ├─ concerning type list A of constructor nil:
- │ Type list A of constructor nil satisfies the positivity condition for list
- │ because list does not appear in any (real) arguments of the type of that
- | constructor (primarily because list does not have any (real)
- | arguments) ... (bullet 1)
- │
- ╰─ concerning type ∀ A → list A → list A of constructor cons:
- Type ∀ A : Type, A → list A → list A of constructor cons
- satisfies the positivity condition for list because:
- │
- ├─ list occurs only strictly positively in Type ... (bullet 3)
- │
- ├─ list occurs only strictly positively in A ... (bullet 3)
- │
- ├─ list occurs only strictly positively in list A ... (bullet 4)
- │
- ╰─ list satisfies the positivity condition for list A ... (bullet 1)
+ + Type ``nattree A`` of constructor ``leaf`` satisfies the positivity condition for
+ ``nattree`` because ``nattree`` does not appear in any (real) arguments of the
+ type of that constructor (primarily because ``nattree`` does not have any (real)
+ arguments) ... (bullet 1)
+
+ + Type ``A → (nat → nattree A) → nattree A`` of constructor ``node`` satisfies the
+ positivity condition for ``nattree`` because:
+
+ - ``nattree`` occurs only strictly positively in ``A`` ... (bullet 3)
+
+ - ``nattree`` occurs only strictly positively in ``nat → nattree A`` ... (bullet 3 + 2)
+
+ - ``nattree`` satisfies the positivity condition for ``nattree A`` ... (bullet 1)
.. _Correctness-rules:
diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst
index a93e9b156..53b993edd 100644
--- a/doc/sphinx/language/gallina-extensions.rst
+++ b/doc/sphinx/language/gallina-extensions.rst
@@ -30,7 +30,7 @@ expressions. In this sense, the ``Record`` construction allows defining
In the expression:
-.. cmd:: Record @ident {* @param } {? : @sort} := {? @ident} { {*; @ident {* @binder } : @term } }.
+.. cmd:: Record @ident {* @param } {? : @sort} := {? @ident} { {*; @ident {* @binder } : @term } }
the first identifier `ident` is the name of the defined record and `sort` is its
type. The optional identifier following ``:=`` is the name of its constructor. If it is omitted,
@@ -70,7 +70,7 @@ depends on both ``top`` and ``bottom``.
Let us now see the work done by the ``Record`` macro. First the macro
generates a variant type definition with just one constructor:
-.. cmd:: Variant @ident {* @params} : @sort := @ident {* (@ident : @term_1)}.
+.. cmd:: Variant @ident {* @params} : @sort := @ident {* (@ident : @term_1)}
To build an object of type `ident`, one should provide the constructor
|ident_0| with the appropriate number of terms filling the fields of the record.
@@ -105,15 +105,15 @@ to be all present if the missing ones can be inferred or prompted for
This syntax can be disabled globally for printing by
-.. cmd:: Unset Printing Records.
+.. cmd:: Unset Printing Records
For a given type, one can override this using either
-.. cmd:: Add Printing Record @ident.
+.. cmd:: Add Printing Record @ident
to get record syntax or
-.. cmd:: Add Printing Constructor @ident.
+.. cmd:: Add Printing Constructor @ident
to get constructor syntax.
@@ -475,7 +475,7 @@ of :g:`match` expressions.
Printing nested patterns
+++++++++++++++++++++++++
-.. opt:: Printing Matching.
+.. opt:: Printing Matching
The Calculus of Inductive Constructions knows pattern-matching only
over simple patterns. It is however convenient to re-factorize nested
@@ -491,7 +491,7 @@ in the same way as the |Coq| kernel handles them.
Factorization of clauses with same right-hand side
++++++++++++++++++++++++++++++++++++++++++++++++++
-.. opt:: Printing Factorizable Match Patterns.
+.. opt:: Printing Factorizable Match Patterns
When several patterns share the same right-hand side, it is additionally
possible to share the clauses using disjunctive patterns. Assuming that the
@@ -501,7 +501,7 @@ printer to try to do this kind of factorization.
Use of a default clause
+++++++++++++++++++++++
-.. opt:: Printing Allow Default Clause.
+.. opt:: Printing Allow Default Clause
When several patterns share the same right-hand side which do not depend on the
arguments of the patterns, yet an extra factorization is possible: the
@@ -512,7 +512,7 @@ default) tells |Coq|'s printer to use a default clause when relevant.
Printing of wildcard patterns
++++++++++++++++++++++++++++++
-.. opt:: Printing Wildcard.
+.. opt:: Printing Wildcard
Some variables in a pattern may not occur in the right-hand side of
the pattern-matching clause. When this option is on (default), the
@@ -524,7 +524,7 @@ pattern-matching clause are just printed using the wildcard symbol
Printing of the elimination predicate
+++++++++++++++++++++++++++++++++++++
-.. opt:: Printing Synth.
+.. opt:: Printing Synth
In most of the cases, the type of the result of a matched term is
mechanically synthesizable. Especially, if the result type does not
@@ -539,23 +539,23 @@ Printing matching on irrefutable patterns
If an inductive type has just one constructor, pattern-matching can be
written using the first destructuring let syntax.
-.. cmd:: Add Printing Let @ident.
+.. cmd:: Add Printing Let @ident
This adds `ident` to the list of inductive types for which pattern-matching
is written using a let expression.
-.. cmd:: Remove Printing Let @ident.
+.. cmd:: Remove Printing Let @ident
This removes ident from this list. Note that removing an inductive
type from this list has an impact only for pattern-matching written
using :g:`match`. Pattern-matching explicitly written using a destructuring
:g:`let` are not impacted.
-.. cmd:: Test Printing Let for @ident.
+.. cmd:: Test Printing Let for @ident
This tells if `ident` belongs to the list.
-.. cmd:: Print Table Printing Let.
+.. cmd:: Print Table Printing Let
This prints the list of inductive types for which pattern-matching is
written using a let expression.
@@ -571,20 +571,20 @@ Printing matching on booleans
If an inductive type is isomorphic to the boolean type, pattern-matching
can be written using ``if`` … ``then`` … ``else`` …:
-.. cmd:: Add Printing If @ident.
+.. cmd:: Add Printing If @ident
This adds ident to the list of inductive types for which pattern-matching is
written using an if expression.
-.. cmd:: Remove Printing If @ident.
+.. cmd:: Remove Printing If @ident
This removes ident from this list.
-.. cmd:: Test Printing If for @ident.
+.. cmd:: Test Printing If for @ident
This tells if ident belongs to the list.
-.. cmd:: Print Table Printing If.
+.. cmd:: Print Table Printing If
This prints the list of inductive types for which pattern-matching is
written using an if expression.
@@ -622,7 +622,7 @@ Advanced recursive functions
The following experimental command is available when the ``FunInd`` library has been loaded via ``Require Import FunInd``:
-.. cmd:: Function @ident {* @binder} { @decrease_annot } : @type := @term.
+.. cmd:: Function @ident {* @binder} { @decrease_annot } : @type := @term
This command can be seen as a generalization of ``Fixpoint``. It is actually a wrapper
for several ways of defining a function *and other useful related
@@ -689,11 +689,11 @@ presence of partial application of `wrong` in the body of
For now, dependent cases are not treated for non structurally
terminating functions.
-.. exn:: The recursive argument must be specified
-.. exn:: No argument name @ident
-.. exn:: Cannot use mutual definition with well-founded recursion or measure
+.. exn:: The recursive argument must be specified.
+.. exn:: No argument name @ident.
+.. exn:: Cannot use mutual definition with well-founded recursion or measure.
-.. warn:: Cannot define graph for @ident
+.. warn:: Cannot define graph for @ident.
The generation of the graph relation (`R_ident`) used to compute the induction scheme of ident
raised a typing error. Only `ident` is defined; the induction scheme
@@ -703,12 +703,12 @@ terminating functions.
which ``Function`` cannot deal with yet.
- the definition is not a *pattern-matching tree* as explained above.
-.. warn:: Cannot define principle(s) for @ident
+.. warn:: Cannot define principle(s) for @ident.
The generation of the graph relation (`R_ident`) succeeded but the induction principle
could not be built. Only `ident` is defined. Please report.
-.. warn:: Cannot build functional inversion principle
+.. warn:: Cannot build functional inversion principle.
`functional inversion` will not be available for the function.
@@ -782,12 +782,12 @@ structured sections. Then local declarations become available (see
Section :ref:`gallina-definitions`).
-.. cmd:: Section @ident.
+.. cmd:: Section @ident
This command is used to open a section named `ident`.
-.. cmd:: End @ident.
+.. cmd:: End @ident
This command closes the section named `ident`. After closing of the
section, the local declarations (variables and local definitions) get
@@ -820,7 +820,7 @@ Section :ref:`gallina-definitions`).
Notice the difference between the value of `x’` and `x’’` inside section
`s1` and outside.
- .. exn:: This is not the last opened section
+ .. exn:: This is not the last opened section.
**Remarks:**
@@ -852,25 +852,25 @@ In the syntax of module application, the ! prefix indicates that any
(see the ``Module Type`` command below).
-.. cmd:: Module @ident.
+.. cmd:: Module @ident
This command is used to start an interactive module named `ident`.
-.. cmdv:: Module @ident {* @module_binding}.
+.. cmdv:: Module @ident {* @module_binding}
Starts an interactive functor with
parameters given by module_bindings.
-.. cmdv:: Module @ident : @module_type.
+.. cmdv:: Module @ident : @module_type
Starts an interactive module specifying its module type.
-.. cmdv:: Module @ident {* @module_binding} : @module_type.
+.. cmdv:: Module @ident {* @module_binding} : @module_type
Starts an interactive functor with parameters given by the list of `module binding`, and output module
type `module_type`.
-.. cmdv:: Module @ident <: {+<: @module_type }.
+.. cmdv:: Module @ident <: {+<: @module_type }
Starts an interactive module satisfying each `module_type`.
@@ -879,14 +879,14 @@ In the syntax of module application, the ! prefix indicates that any
Starts an interactive functor with parameters given by the list of `module_binding`. The output module type
is verified against each `module_type`.
-.. cmdv:: Module [ Import | Export ].
+.. cmdv:: Module [ Import | Export ]
Behaves like ``Module``, but automatically imports or exports the module.
Reserved commands inside an interactive module
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Include @module.
+.. cmd:: Include @module
Includes the content of module in the current
interactive module. Here module can be a module expression or a module
@@ -894,11 +894,11 @@ Reserved commands inside an interactive module
expression then the system tries to instantiate module by the current
interactive module.
-.. cmd:: Include {+<+ @module}.
+.. cmd:: Include {+<+ @module}
is a shortcut for the commands ``Include`` `module` for each `module`.
-.. cmd:: End @ident.
+.. cmd:: End @ident
This command closes the interactive module `ident`. If the module type
was given the content of the module is matched against it and an error
@@ -906,40 +906,40 @@ Reserved commands inside an interactive module
functor) its components (constants, inductive types, submodules etc.)
are now available through the dot notation.
- .. exn:: No such label @ident
+ .. exn:: No such label @ident.
- .. exn:: Signature components for label @ident do not match
+ .. exn:: Signature components for label @ident do not match.
- .. exn:: This is not the last opened module
+ .. exn:: This is not the last opened module.
-.. cmd:: Module @ident := @module_expression.
+.. cmd:: Module @ident := @module_expression
This command defines the module identifier `ident` to be equal
to `module_expression`.
- .. cmdv:: Module @ident {* @module_binding} := @module_expression.
+ .. cmdv:: Module @ident {* @module_binding} := @module_expression
Defines a functor with parameters given by the list of `module_binding` and body `module_expression`.
- .. cmdv:: Module @ident {* @module_binding} : @module_type := @module_expression.
+ .. cmdv:: Module @ident {* @module_binding} : @module_type := @module_expression
Defines a functor with parameters given by the list of `module_binding` (possibly none), and output module type `module_type`,
with body `module_expression`.
- .. cmdv:: Module @ident {* @module_binding} <: {+<: @module_type} := @module_expression.
+ .. cmdv:: Module @ident {* @module_binding} <: {+<: @module_type} := @module_expression
Defines a functor with parameters given by module_bindings (possibly none) with body `module_expression`.
The body is checked against each |module_type_i|.
- .. cmdv:: Module @ident {* @module_binding} := {+<+ @module_expression}.
+ .. cmdv:: Module @ident {* @module_binding} := {+<+ @module_expression}
is equivalent to an interactive module where each `module_expression` is included.
-.. cmd:: Module Type @ident.
+.. cmd:: Module Type @ident
This command is used to start an interactive module type `ident`.
- .. cmdv:: Module Type @ident {* @module_binding}.
+ .. cmdv:: Module Type @ident {* @module_binding}
Starts an interactive functor type with parameters given by `module_bindings`.
@@ -947,11 +947,11 @@ This command is used to start an interactive module type `ident`.
Reserved commands inside an interactive module type:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Include @module.
+.. cmd:: Include @module
Same as ``Include`` inside a module.
-.. cmd:: Include {+<+ @module}.
+.. cmd:: Include {+<+ @module}
is a shortcut for the command ``Include`` `module` for each `module`.
@@ -961,30 +961,30 @@ Reserved commands inside an interactive module type:
The instance of this assumption will be automatically expanded at functor application, except when
this functor application is prefixed by a ``!`` annotation.
-.. cmd:: End @ident.
+.. cmd:: End @ident
This command closes the interactive module type `ident`.
- .. exn:: This is not the last opened module type
+ .. exn:: This is not the last opened module type.
-.. cmd:: Module Type @ident := @module_type.
+.. cmd:: Module Type @ident := @module_type
Defines a module type `ident` equal to `module_type`.
- .. cmdv:: Module Type @ident {* @module_binding} := @module_type.
+ .. cmdv:: Module Type @ident {* @module_binding} := @module_type
Defines a functor type `ident` specifying functors taking arguments `module_bindings` and
returning `module_type`.
- .. cmdv:: Module Type @ident {* @module_binding} := {+<+ @module_type }.
+ .. cmdv:: Module Type @ident {* @module_binding} := {+<+ @module_type }
is equivalent to an interactive module type were each `module_type` is included.
-.. cmd:: Declare Module @ident : @module_type.
+.. cmd:: Declare Module @ident : @module_type
Declares a module `ident` of type `module_type`.
- .. cmdv:: Declare Module @ident {* @module_binding} : @module_type.
+ .. cmdv:: Declare Module @ident {* @module_binding} : @module_type
Declares a functor with parameters given by the list of `module_binding` and output module type
`module_type`.
@@ -1170,77 +1170,79 @@ component is equal ``nat`` and hence ``M1.T`` as specified.
.. _import_qualid:
-.. cmd:: Import @qualid.
+.. cmd:: Import @qualid
If `qualid` denotes a valid basic module (i.e. its module type is a
signature), makes its components available by their short names.
-.. example::
+ .. example::
- .. coqtop:: reset all
+ .. coqtop:: reset all
- Module Mod.
+ Module Mod.
- Definition T:=nat.
+ Definition T:=nat.
- Check T.
+ Check T.
- End Mod.
+ End Mod.
- Check Mod.T.
+ Check Mod.T.
- Fail Check T.
+ Fail Check T.
- Import Mod.
+ Import Mod.
- Check T.
+ Check T.
-Some features defined in modules are activated only when a module is
-imported. This is for instance the case of notations (see :ref:`Notations`).
+ Some features defined in modules are activated only when a module is
+ imported. This is for instance the case of notations (see :ref:`Notations`).
-Declarations made with the Local flag are never imported by theImport
-command. Such declarations are only accessible through their fully
-qualified name.
+ Declarations made with the ``Local`` flag are never imported by the :cmd:`Import`
+ command. Such declarations are only accessible through their fully
+ qualified name.
-.. example::
+ .. example::
- .. coqtop:: all
+ .. coqtop:: all
- Module A.
+ Module A.
- Module B.
+ Module B.
- Local Definition T := nat.
+ Local Definition T := nat.
- End B.
+ End B.
- End A.
+ End A.
- Import A.
+ Import A.
- Fail Check B.T.
+ Fail Check B.T.
.. cmdv:: Export @qualid
+ :name: Export
When the module containing the command Export qualid
is imported, qualid is imported as well.
- .. exn:: @qualid is not a module
+ .. exn:: @qualid is not a module.
.. warn:: Trying to mask the absolute name @qualid!
-.. cmd:: Print Module @ident.
+.. cmd:: Print Module @ident
- Prints the module type and (optionally) the body of the module `ident`.
+ Prints the module type and (optionally) the body of the module :n:`@ident`.
-.. cmd:: Print Module Type @ident.
+.. cmd:: Print Module Type @ident
- Prints the module type corresponding to `ident`.
+ Prints the module type corresponding to :n:`@ident`.
.. opt:: Short Module Printing
- This option (off by default) disables the printing of the types of fields,
- leaving only their names, for the commands ``Print Module`` and ``Print Module Type``.
+ This option (off by default) disables the printing of the types of fields,
+ leaving only their names, for the commands :cmd:`Print Module` and
+ :cmd:`Print Module Type`.
Libraries and qualified names
---------------------------------
@@ -1510,9 +1512,8 @@ implicitly applied to the implicit arguments it is waiting for: one
says that the implicit argument is maximally inserted.
Each implicit argument can be declared to have to be inserted maximally or non
-maximally. This can be governed argument per argument by the command ``Implicit
-Arguments`` (see Section :ref:`declare-implicit-args`) or globally by the
-:opt:`Maximal Implicit Insertion` option.
+maximally. This can be governed argument per argument by the command
+:cmd:`Arguments (implicits)` or globally by the :opt:`Maximal Implicit Insertion` option.
See also :ref:`displaying-implicit-args`.
@@ -1525,6 +1526,7 @@ force the given argument to be guessed by replacing it by “_”. If
possible, the correct argument will be automatically generated.
.. exn:: Cannot infer a term for this placeholder.
+ :name: Cannot infer a term for this placeholder. (Casual use of implicit arguments)
|Coq| was not able to deduce an instantiation of a “_”.
@@ -1564,7 +1566,7 @@ absent in every situation but still be able to specify it if needed:
The syntax is supported in all top-level definitions:
-``Definition``, ``Fixpoint``, ``Lemma`` and so on. For (co-)inductive datatype
+:cmd:`Definition`, :cmd:`Fixpoint`, :cmd:`Lemma` and so on. For (co-)inductive datatype
declarations, the semantics are the following: an inductive parameter
declared as an implicit argument need not be repeated in the inductive
definition but will become implicit for the constructors of the
@@ -1587,7 +1589,7 @@ Declaring Implicit Arguments
To set implicit arguments *a posteriori*, one can use the command:
-.. cmd:: Arguments @qualid {* @possibly_bracketed_ident }.
+.. cmd:: Arguments @qualid {* @possibly_bracketed_ident }
:name: Arguments (implicits)
where the list of `possibly_bracketed_ident` is a prefix of the list of
@@ -1601,7 +1603,7 @@ of `qualid`.
Implicit arguments can be cleared with the following syntax:
-.. cmd:: Arguments @qualid : clear implicits.
+.. cmd:: Arguments @qualid : clear implicits
.. cmdv:: Global Arguments @qualid {* @possibly_bracketed_ident }
@@ -1610,13 +1612,13 @@ Implicit arguments can be cleared with the following syntax:
implicit arguments known from inside the section to be the ones
declared by the command.
-.. cmdv:: Local Arguments @qualid {* @possibly_bracketed_ident }.
+.. cmdv:: Local Arguments @qualid {* @possibly_bracketed_ident }
When in a module, tell not to activate the
implicit arguments ofqualid declared by this command to contexts that
require the module.
-.. cmdv:: {? Global | Local } Arguments @qualid {*, {+ @possibly_bracketed_ident } }.
+.. cmdv:: {? Global | Local } Arguments @qualid {*, {+ @possibly_bracketed_ident } }
For names of constants, inductive types,
constructors, lemmas which can only be applied to a fixed number of
@@ -1668,7 +1670,7 @@ Automatic declaration of implicit arguments
|Coq| can also automatically detect what are the implicit arguments of a
defined object. The command is just
-.. cmd:: Arguments @qualid : default implicits.
+.. cmd:: Arguments @qualid : default implicits
The auto-detection is governed by options telling if strict,
contextual, or reversible-pattern implicit arguments must be
@@ -1742,7 +1744,7 @@ appear strictly in the body of the type, they are implicit.
Mode for automatic declaration of implicit arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. opt:: Implicit Arguments.
+.. opt:: Implicit Arguments
This option (off by default) allows to systematically declare implicit
the arguments detectable as such. Auto-detection of implicit arguments is
@@ -1754,7 +1756,7 @@ arguments have to be considered or not.
Controlling strict implicit arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. opt:: Strict Implicit.
+.. opt:: Strict Implicit
When the mode for automatic declaration of implicit arguments is on,
the default is to automatically set implicit only the strict implicit
@@ -1763,7 +1765,7 @@ implicit arguments. To relax this constraint and to set
implicit all non strict implicit arguments by default, you can turn this
option off.
-.. opt:: Strongly Strict Implicit.
+.. opt:: Strongly Strict Implicit
Use this option (off by default) to capture exactly the strict implicit
arguments and no more than the strict implicit arguments.
@@ -1773,7 +1775,7 @@ arguments and no more than the strict implicit arguments.
Controlling contextual implicit arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. opt:: Contextual Implicit.
+.. opt:: Contextual Implicit
By default, |Coq| does not automatically set implicit the contextual
implicit arguments. You can turn this option on to tell |Coq| to also
@@ -1784,7 +1786,7 @@ infer contextual implicit argument.
Controlling reversible-pattern implicit arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. opt:: Reversible Pattern Implicit.
+.. opt:: Reversible Pattern Implicit
By default, |Coq| does not automatically set implicit the reversible-pattern
implicit arguments. You can turn this option on to tell |Coq| to also infer
@@ -1795,7 +1797,7 @@ reversible-pattern implicit argument.
Controlling the insertion of implicit arguments not followed by explicit arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. opt:: Maximal Implicit Insertion.
+.. opt:: Maximal Implicit Insertion
Assuming the implicit argument mode is on, this option (off by default)
declares implicit arguments to be automatically inserted when a
@@ -1841,7 +1843,7 @@ Renaming implicit arguments
Implicit arguments names can be redefined using the following syntax:
-.. cmd:: Arguments @qualid {* @name} : @rename.
+.. cmd:: Arguments @qualid {* @name} : @rename
With the assert flag, ``Arguments`` can be used to assert that a given
object has the expected number of arguments and that these arguments
@@ -1867,18 +1869,18 @@ Displaying what the implicit arguments are
To display the implicit arguments associated to an object, and to know
if each of them is to be used maximally or not, use the command
-.. cmd:: Print Implicit @qualid.
+.. cmd:: Print Implicit @qualid
Explicit displaying of implicit arguments for pretty-printing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. opt:: Printing Implicit.
+.. opt:: Printing Implicit
By default, the basic pretty-printing rules hide the inferable implicit
arguments of an application. Turn this option on to force printing all
implicit arguments.
-.. opt:: Printing Implicit Defensive.
+.. opt:: Printing Implicit Defensive
By default, the basic pretty-printing rules display the implicit
arguments that are not detected as strict implicit arguments. This
@@ -1910,9 +1912,9 @@ but succeeds in
Deactivation of implicit arguments for parsing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. opt:: Parsing Explicit.
+.. opt:: Parsing Explicit
-Turning this option on, deactivates the use of implicit arguments.
+Turning this option on (it is off by default) deactivates the use of implicit arguments.
In this case, all arguments of constants, inductive types,
constructors, etc, including the arguments declared as implicit, have
@@ -1932,7 +1934,7 @@ Assume that `qualid` denotes an object ``(Build_struc`` |c_1| … |c_n| ``)`` in
structure *struct* of which the fields are |x_1|, …, |x_n|. Assume that
`qualid` is declared as a canonical structure using the command
-.. cmd:: Canonical Structure @qualid.
+.. cmd:: Canonical Structure @qualid
Then, each time an equation of the form ``(``\ |x_i| ``_)`` |eq_beta_delta_iota_zeta| |c_i| has to be
solved during the type-checking process, `qualid` is used as a solution.
@@ -1973,11 +1975,11 @@ and ``B`` can be synthesized in the next statement.
Remark: If a same field occurs in several canonical structure, then
only the structure declared first as canonical is considered.
-.. cmdv:: Canonical Structure @ident := @term : @type.
+.. cmdv:: Canonical Structure @ident := @term : @type
-.. cmdv:: Canonical Structure @ident := @term.
+.. cmdv:: Canonical Structure @ident := @term
-.. cmdv:: Canonical Structure @ident : @type := @term.
+.. cmdv:: Canonical Structure @ident : @type := @term
These are equivalent to a regular definition of `ident` followed by the declaration
``Canonical Structure`` `ident`.
@@ -2005,7 +2007,7 @@ It is possible to bind variable names to a given type (e.g. in a
development using arithmetic, it may be convenient to bind the names `n`
or `m` to the type ``nat`` of natural numbers). The command for that is
-.. cmd:: Implicit Types {+ @ident } : @type.
+.. cmd:: Implicit Types {+ @ident } : @type
The effect of the command is to automatically set the type of bound
variables starting with `ident` (either `ident` itself or `ident` followed by
@@ -2027,7 +2029,7 @@ case, this latter type is considered).
Lemma cons_inj_bool : forall (m n:bool) l, n :: l = m :: l -> n = m.
-.. cmdv:: Implicit Type @ident : @type.
+.. cmdv:: Implicit Type @ident : @type
This is useful for declaring the implicit type of a single variable.
@@ -2066,7 +2068,7 @@ the ``Generalizable`` vernacular command to avoid unexpected
generalizations when mistyping identifiers. There are several commands
that specify which variables should be generalizable.
-.. cmd:: Generalizable All Variables.
+.. cmd:: Generalizable All Variables
All variables are candidate for
generalization if they appear free in the context under a
@@ -2074,16 +2076,16 @@ that specify which variables should be generalizable.
of typos. In such cases, the context will probably contain some
unexpected generalized variable.
-.. cmd:: Generalizable No Variables.
+.. cmd:: Generalizable No Variables
Disable implicit generalization entirely. This is the default behavior.
-.. cmd:: Generalizable (Variable | Variables) {+ @ident }.
+.. cmd:: Generalizable (Variable | Variables) {+ @ident }
Allow generalization of the given identifiers only. Calling this command multiple times
adds to the allowed identifiers.
-.. cmd:: Global Generalizable.
+.. cmd:: Global Generalizable
Allows exporting the choice of generalizable variables.
@@ -2128,7 +2130,7 @@ to coercions are provided in :ref:`implicitcoercions`.
Printing constructions in full
------------------------------
-.. opt:: Printing All.
+.. opt:: Printing All
Coercions, implicit arguments, the type of pattern-matching, but also
notations (see :ref:`syntaxextensionsandinterpretationscopes`) can obfuscate the behavior of some
@@ -2147,7 +2149,7 @@ the high-level printing features, use the command ``Unset Printing All``.
Printing universes
------------------
-.. opt:: Printing Universes.
+.. opt:: Printing Universes
Turn this option on to activate the display of the actual level of each
occurrence of :g:`Type`. See :ref:`Sorts` for details. This wizard option, in
@@ -2158,7 +2160,7 @@ Constructions.
The constraints on the internal level of the occurrences of Type
(see :ref:`Sorts`) can be printed using the command
-.. cmd:: Print {? Sorted} Universes.
+.. cmd:: Print {? Sorted} Universes
:name: Print Universes
If the optional ``Sorted`` option is given, each universe will be made
@@ -2167,7 +2169,7 @@ ordering) in the universe hierarchy.
This command also accepts an optional output filename:
-.. cmdv:: Print {? Sorted} Universes @string.
+.. cmdv:: Print {? Sorted} Universes @string
If `string` ends in ``.dot`` or ``.gv``, the constraints are printed in the DOT
language, and can be processed by Graphviz tools. The format is
@@ -2237,7 +2239,7 @@ with a named-goal selector, see :ref:`goal-selectors`).
Explicit displaying of existential instances for pretty-printing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. opt:: Printing Existential Instances.
+.. opt:: Printing Existential Instances
This option (off by default) activates the full display of how the
context of an existential variable is instantiated at each of the
diff --git a/doc/sphinx/language/gallina-specification-language.rst b/doc/sphinx/language/gallina-specification-language.rst
index a9c4dd758..76a016ff6 100644
--- a/doc/sphinx/language/gallina-specification-language.rst
+++ b/doc/sphinx/language/gallina-specification-language.rst
@@ -551,32 +551,33 @@ has type :token:`type`.
.. _Axiom:
-.. cmd:: Axiom @ident : @term.
+.. cmd:: Axiom @ident : @term
- This command links *term* to the name *ident* as its specification in
- the global context. The fact asserted by *term* is thus assumed as a
+ This command links :token:`term` to the name :token:`ident` as its specification in
+ the global context. The fact asserted by :token:`term` is thus assumed as a
postulate.
-.. exn:: @ident already exists (Axiom)
+.. exn:: @ident already exists.
+ :name: @ident already exists. (Axiom)
-.. cmdv:: Parameter @ident : @term.
+.. cmdv:: Parameter @ident : @term
:name: Parameter
Is equivalent to ``Axiom`` :token:`ident` : :token:`term`
-.. cmdv:: Parameter {+ @ident } : @term.
+.. cmdv:: Parameter {+ @ident } : @term
Adds parameters with specification :token:`term`
-.. cmdv:: Parameter {+ ( {+ @ident } : @term ) }.
+.. cmdv:: Parameter {+ ( {+ @ident } : @term ) }
Adds blocks of parameters with different specifications.
-.. cmdv:: Parameters {+ ( {+ @ident } : @term ) }.
+.. cmdv:: Parameters {+ ( {+ @ident } : @term ) }
Synonym of ``Parameter``.
-.. cmdv:: Local Axiom @ident : @term.
+.. cmdv:: Local Axiom @ident : @term
Such axioms are never made accessible through their unqualified name by
:cmd:`Import` and its variants. You have to explicitly give their fully
@@ -587,7 +588,7 @@ has type :token:`type`.
Is equivalent to ``Axiom`` :token:`ident` : :token:`term`.
-.. cmd:: Variable @ident : @term.
+.. cmd:: Variable @ident : @term
This command links :token:`term` to the name :token:`ident` in the context of
the current section (see Section :ref:`section-mechanism` for a description of
@@ -596,22 +597,24 @@ will be unknown and every object using this variable will be explicitly
parametrized (the variable is *discharged*). Using the ``Variable`` command out
of any section is equivalent to using ``Local Parameter``.
-.. exn:: @ident already exists (Variable)
+.. exn:: @ident already exists.
+ :name: @ident already exists. (Variable)
-.. cmdv:: Variable {+ @ident } : @term.
+.. cmdv:: Variable {+ @ident } : @term
Links :token:`term` to each :token:`ident`.
-.. cmdv:: Variable {+ ( {+ @ident } : @term) }.
+.. cmdv:: Variable {+ ( {+ @ident } : @term) }
Adds blocks of variables with different specifications.
-.. cmdv:: Variables {+ ( {+ @ident } : @term) }.
+.. cmdv:: Variables {+ ( {+ @ident } : @term) }
+ :name: Variables
-.. cmdv:: Hypothesis {+ ( {+ @ident } : @term) }.
+.. cmdv:: Hypothesis {+ ( {+ @ident } : @term) }
:name: Hypothesis
-.. cmdv:: Hypotheses {+ ( {+ @ident } : @term) }.
+.. cmdv:: Hypotheses {+ ( {+ @ident } : @term) }
Synonyms of ``Variable``.
@@ -641,46 +644,48 @@ type which is the type of its body.
A formal presentation of constants and environments is given in
Section :ref:`typing-rules`.
-.. cmd:: Definition @ident := @term.
+.. cmd:: Definition @ident := @term
This command binds :token:`term` to the name :token:`ident` in the environment,
provided that :token:`term` is well-typed.
-.. exn:: @ident already exists (Definition)
+.. exn:: @ident already exists.
+ :name: @ident already exists. (Definition)
-.. cmdv:: Definition @ident : @term := @term.
+.. cmdv:: Definition @ident : @term := @term
It checks that the type of :token:`term`:math:`_2` is definitionally equal to
:token:`term`:math:`_1`, and registers :token:`ident` as being of type
:token:`term`:math:`_1`, and bound to value :token:`term`:math:`_2`.
-.. cmdv:: Definition @ident {* @binder } : @term := @term.
+.. cmdv:: Definition @ident {* @binder } : @term := @term
This is equivalent to ``Definition`` :token:`ident` : :g:`forall`
:token:`binder`:math:`_1` … :token:`binder`:math:`_n`, :token:`term`:math:`_1` := 
fun :token:`binder`:math:`_1` …
:token:`binder`:math:`_n` => :token:`term`:math:`_2`.
-.. cmdv:: Local Definition @ident := @term.
+.. cmdv:: Local Definition @ident := @term
Such definitions are never made accessible through their
unqualified name by :cmd:`Import` and its variants.
You have to explicitly give their fully qualified name to refer to them.
-.. cmdv:: Example @ident := @term.
+.. cmdv:: Example @ident := @term
+ :name: Example
-.. cmdv:: Example @ident : @term := @term.
+.. cmdv:: Example @ident : @term := @term
-.. cmdv:: Example @ident {* @binder } : @term := @term.
+.. cmdv:: Example @ident {* @binder } : @term := @term
These are synonyms of the Definition forms.
-.. exn:: The term @term has type @type while it is expected to have type @type
+.. exn:: The term @term has type @type while it is expected to have type @type.
-See also :cmd:`Opaque`, :cmd:`Transparent`, :tac:`unfold`.
+See also :cmd:`Opaque`, :cmd:`Transparent`, :tacn:`unfold`.
-.. cmd:: Let @ident := @term.
+.. cmd:: Let @ident := @term
This command binds the value :token:`term` to the name :token:`ident` in the
environment of the current section. The name :token:`ident` disappears when the
@@ -690,13 +695,14 @@ prefixed by the let-in definition ``let`` :token:`ident` ``:=`` :token:`term`
``in``. Using the ``Let`` command out of any section is equivalent to using
``Local Definition``.
-.. exn:: @ident already exists (Let)
+.. exn:: @ident already exists.
+ :name: @ident already exists. (Let)
-.. cmdv:: Let @ident : @term := @term.
+.. cmdv:: Let @ident : @term := @term
-.. cmdv:: Let Fixpoint @ident @fix_body {* with @fix_body}.
+.. cmdv:: Let Fixpoint @ident @fix_body {* with @fix_body}
-.. cmdv:: Let CoFixpoint @ident @cofix_body {* with @cofix_body}.
+.. cmdv:: Let CoFixpoint @ident @cofix_body {* with @cofix_body}
See also Sections :ref:`section-mechanism`, commands :cmd:`Opaque`,
:cmd:`Transparent`, and tactic :tacn:`unfold`.
@@ -803,9 +809,9 @@ and to prove that if any natural number :g:`n` satisfies :g:`P` its double
successor :g:`(S (S n))` satisfies also :g:`P`. This is indeed analogous to the
structural induction principle we got for :g:`nat`.
-.. exn:: Non strictly positive occurrence of @ident in @type
+.. exn:: Non strictly positive occurrence of @ident in @type.
-.. exn:: The conclusion of @type is not valid; it must be built from @ident
+.. exn:: The conclusion of @type is not valid; it must be built from @ident.
Parametrized inductive types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -864,7 +870,7 @@ that it disallows recursive definition of types (in particular lists cannot
be defined with the Variant keyword). No induction scheme is generated for
this variant, unless :opt:`Nonrecursive Elimination Schemes` is set.
-.. exn:: The @num th argument of @ident must be @ident in @type
+.. exn:: The @num th argument of @ident must be @ident in @type.
New from Coq V8.1
+++++++++++++++++
@@ -912,7 +918,7 @@ Mutually defined inductive types
The definition of a block of mutually inductive types has the form:
-.. cmdv:: Inductive @ident : @term := {? | } @ident : @type {* | @ident : @type } {* with @ident : @term := {? | } @ident : @type {* | @ident : @type }}.
+.. cmdv:: Inductive @ident : @term := {? | } @ident : @type {* | @ident : @type } {* with @ident : @term := {? | } @ident : @type {* | @ident : @type }}
It has the same semantics as the above ``Inductive`` definition for each
:token:`ident` All :token:`ident` are simultaneously added to the environment.
@@ -924,7 +930,7 @@ parameters correspond to a local context in which the whole set of
inductive declarations is done. For this reason, the parameters must be
strictly the same for each inductive types The extended syntax is:
-.. cmdv:: Inductive @ident {+ @binder} : @term := {? | } @ident : @type {* | @ident : @type } {* with @ident {+ @binder} : @term := {? | } @ident : @type {* | @ident : @type }}.
+.. cmdv:: Inductive @ident {+ @binder} : @term := {? | } @ident : @type {* | @ident : @type } {* with @ident {+ @binder} : @term := {? | } @ident : @type {* | @ident : @type }}
The typical example of a mutual inductive data type is the one for trees and
forests. We assume given two types :g:`A` and :g:`B` as variables. It can
@@ -1037,7 +1043,7 @@ constructions.
.. _Fixpoint:
-.. cmd:: Fixpoint @ident @params {struct @ident} : @type := @term.
+.. cmd:: Fixpoint @ident @params {struct @ident} : @type := @term
This command allows defining functions by pattern-matching over inductive objects
using a fixed point construction. The meaning of this declaration is to
@@ -1151,7 +1157,7 @@ The ``Fixpoint`` construction enjoys also the with extension to define functions
over mutually defined inductive types or more generally any mutually recursive
definitions.
-.. cmdv:: Fixpoint @ident @params {struct @ident} : @type := @term {* with @ident {+ @params} : @type := @term}.
+.. cmdv:: Fixpoint @ident @params {struct @ident} : @type := @term {* with @ident {+ @params} : @type := @term}
allows to define simultaneously fixpoints.
@@ -1178,7 +1184,7 @@ induction principles. It is described in Section
Definitions of recursive objects in co-inductive types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: CoFixpoint @ident : @type := @term.
+.. cmd:: CoFixpoint @ident : @type := @term
introduces a method for constructing an infinite object of a coinductive
type. For example, the stream containing all natural numbers can be
@@ -1239,38 +1245,45 @@ inhabitant of the type) is interactively built using tactics. The interactive
proof mode is described in Chapter :ref:`proofhandling` and the tactics in
Chapter :ref:`Tactics`. The basic assertion command is:
-.. cmd:: Theorem @ident : @type.
+.. cmd:: Theorem @ident {? @binders } : @type
-After the statement is asserted, Coq needs a proof. Once a proof of
-:token:`type` under the assumptions represented by :token:`binders` is given and
-validated, the proof is generalized into a proof of forall , :token:`type` and
-the theorem is bound to the name :token:`ident` in the environment.
+ After the statement is asserted, Coq needs a proof. Once a proof of
+ :token:`type` under the assumptions represented by :token:`binders` is given and
+ validated, the proof is generalized into a proof of :n:`forall @binders, @type` and
+ the theorem is bound to the name :token:`ident` in the environment.
-.. exn:: The term @term has type @type which should be Set, Prop or Type
+ .. exn:: The term @term has type @type which should be Set, Prop or Type.
-.. exn:: @ident already exists (Theorem)
+ .. exn:: @ident already exists.
+ :name: @ident already exists. (Theorem)
- The name you provided is already defined. You have then to choose
- another name.
+ The name you provided is already defined. You have then to choose
+ another name.
-.. cmdv:: Lemma @ident : @type.
- :name: Lemma
+ .. exn:: Nested proofs are not allowed unless you turn option Nested Proofs Allowed on.
-.. cmdv:: Remark @ident : @type.
- :name: Remark
+ You are asserting a new statement while already being in proof editing mode.
+ This feature, called nested proofs, is disabled by default.
+ To activate it, turn option :opt:`Nested Proofs Allowed` on.
-.. cmdv:: Fact @ident : @type.
- :name: Fact
+ The following commands are synonyms of :n:`Theorem @ident {? @binders } : type`:
-.. cmdv:: Corollary @ident : @type.
- :name: Corollary
+ .. cmdv:: Lemma @ident {? @binders } : @type
+ :name: Lemma
-.. cmdv:: Proposition @ident : @type.
- :name: Proposition
+ .. cmdv:: Remark @ident {? @binders } : @type
+ :name: Remark
- These commands are synonyms of ``Theorem`` :token:`ident` : :token:`type`.
+ .. cmdv:: Fact @ident {? @binders } : @type
+ :name: Fact
-.. cmdv:: Theorem @ident : @type {* with @ident : @type}.
+ .. cmdv:: Corollary @ident {? @binders } : @type
+ :name: Corollary
+
+ .. cmdv:: Proposition @ident {? @binders } : @type
+ :name: Proposition
+
+.. cmdv:: Theorem @ident : @type {* with @ident : @type}
This command is useful for theorems that are proved by simultaneous induction
over a mutually inductive assumption, or that assert mutually dependent
@@ -1292,79 +1305,65 @@ the theorem is bound to the name :token:`ident` in the environment.
The command can be used also with :cmd:`Lemma`, :cmd:`Remark`, etc. instead of
:cmd:`Theorem`.
-.. cmdv:: Definition @ident : @type.
+.. cmdv:: Definition @ident : @type
This allows defining a term of type :token:`type` using the proof editing
- mode. It behaves as Theorem but is intended to be used in conjunction with
+ mode. It behaves as :cmd:`Theorem` but is intended to be used in conjunction with
:cmd:`Defined` in order to define a constant of which the computational
behavior is relevant.
The command can be used also with :cmd:`Example` instead of :cmd:`Definition`.
- See also :cmd:`Opaque`, :cmd:`Transparent`, :tacn:`unfold`.
+ .. seealso:: :cmd:`Opaque`, :cmd:`Transparent`, :tacn:`unfold`.
-.. cmdv:: Let @ident : @type.
+.. cmdv:: Let @ident : @type
Like Definition :token:`ident` : :token:`type`. except that the definition is
turned into a let-in definition generalized over the declarations depending
on it after closing the current section.
-.. cmdv:: Fixpoint @ident @binders with .
+.. cmdv:: Fixpoint @ident @binders with
This generalizes the syntax of Fixpoint so that one or more bodies
can be defined interactively using the proof editing mode (when a
body is omitted, its type is mandatory in the syntax). When the block
of proofs is completed, it is intended to be ended by Defined.
-.. cmdv:: CoFixpoint @ident with.
+.. cmdv:: CoFixpoint @ident with
This generalizes the syntax of CoFixpoint so that one or more bodies
can be defined interactively using the proof editing mode.
-.. cmd:: Proof
-
- A proof starts by the keyword Proof. Then Coq enters the proof editing mode
- until the proof is completed. The proof editing mode essentially contains
- tactics that are described in chapter :ref:`Tactics`. Besides tactics, there
- are commands to manage the proof editing mode. They are described in Chapter
- :ref:`proofhandling`.
-
-.. cmd:: Qed
+A proof starts by the keyword :cmd:`Proof`. Then Coq enters the proof editing mode
+until the proof is completed. The proof editing mode essentially contains
+tactics that are described in chapter :ref:`Tactics`. Besides tactics, there
+are commands to manage the proof editing mode. They are described in Chapter
+:ref:`proofhandling`.
- When the proof is completed it should be validated and put in the environment
- using the keyword Qed.
-
-.. exn:: @ident already exists (Qed)
+When the proof is completed it should be validated and put in the environment
+using the keyword :cmd:`Qed`.
.. note::
- #. Several statements can be simultaneously asserted.
+ #. Several statements can be simultaneously asserted provided option
+ :opt:`Nested Proofs Allowed` was turned on.
#. Not only other assertions but any vernacular command can be given
while in the process of proving a given assertion. In this case, the
command is understood as if it would have been given before the
- statements still to be proved.
-
- #. Proof is recommended but can currently be omitted. On the opposite
- side, Qed (or Defined, see below) is mandatory to validate a proof.
+ statements still to be proved. Nonetheless, this practice is discouraged
+ and may stop working in future versions.
- #. Proofs ended by Qed are declared opaque. Their content cannot be
+ #. Proofs ended by :cmd:`Qed` are declared opaque. Their content cannot be
unfolded (see :ref:`performingcomputations`), thus
realizing some form of *proof-irrelevance*. To be able to unfold a
- proof, the proof should be ended by Defined (see below).
-
-.. cmdv:: Defined
- :name: Defined
-
- Same as :cmd:`Qed` but the proof is then declared transparent, which means
- that its content can be explicitly used for type-checking and that it can be
- unfolded in conversion tactics (see :ref:`performingcomputations`,
- :cmd:`Opaque`, :cmd:`Transparent`).
+ proof, the proof should be ended by :cmd:`Defined`.
-.. cmdv:: Admitted.
- :name: Admitted
+ #. :cmd:`Proof` is recommended but can currently be omitted. On the opposite
+ side, :cmd:`Qed` (or :cmd:`Defined`) is mandatory to validate a proof.
- Turns the current asserted statement into an axiom and exits the proof mode.
+ #. One can also use :cmd:`Admitted` in place of :cmd:`Qed` to turn the
+ current asserted statement into an axiom and exit the proof editing mode.
.. [1]
This is similar to the expression “*entry* :math:`\{` sep *entry*
diff --git a/doc/sphinx/practical-tools/coq-commands.rst b/doc/sphinx/practical-tools/coq-commands.rst
index 93dcfca4b..ad1f0caa6 100644
--- a/doc/sphinx/practical-tools/coq-commands.rst
+++ b/doc/sphinx/practical-tools/coq-commands.rst
@@ -55,15 +55,20 @@ Customization at launch time
By resource file
~~~~~~~~~~~~~~~~~~~~~~~
-When |Coq| is launched, with either ``coqtop`` or ``coqc``, the resource file
-``$XDG_CONFIG_HOME/coq/coqrc.xxx`` is loaded, where ``$XDG_CONFIG_HOME``
+When |Coq| is launched, with either ``coqtop`` or ``coqc``, the
+resource file ``$XDG_CONFIG_HOME/coq/coqrc.xxx``, if it exists, will
+be implicitly prepended to any document read by Coq, whether it is an
+interactive session or a file to compile. Here, ``$XDG_CONFIG_HOME``
is the configuration directory of the user (by default its home
-directory ``/.config`` and ``xxx`` is the version number (e.g. 8.8). If
+directory ``~/.config``) and ``xxx`` is the version number (e.g. 8.8). If
this file is not found, then the file ``$XDG_CONFIG_HOME/coqrc`` is
-searched. You can also specify an arbitrary name for the resource file
+searched. If not found, it is the file ``~/.coqrc.xxx`` which is searched,
+and, if still not found, the file ``~/.coqrc``. If the latter is also
+absent, no resource file is loaded.
+You can also specify an arbitrary name for the resource file
(see option ``-init-file`` below).
-This file may contain, for instance, ``Add LoadPath`` commands to add
+The resource file may contain, for instance, ``Add LoadPath`` commands to add
directories to the load path of |Coq|. It is possible to skip the
loading of the resource file with the option ``-q``.
@@ -171,7 +176,7 @@ and ``coqtop``, unless stated otherwise:
Coq's auto-generated name scheme with names of the form *ident0*, *ident1*,
etc. The command ``Set Mangle Names`` turns the behavior on in a document,
and ``Set Mangle Names Prefix "ident"`` changes the used prefix. This feature
- s intended to be used as a linter for developments that want to be robust to
+ is intended to be used as a linter for developments that want to be robust to
changes in the auto-generated name scheme. The options are provided to
facilitate tracking down problems.
:-compat *version*: Attempt to maintain some backward-compatibility
diff --git a/doc/sphinx/practical-tools/utilities.rst b/doc/sphinx/practical-tools/utilities.rst
index 59867988a..59a88771a 100644
--- a/doc/sphinx/practical-tools/utilities.rst
+++ b/doc/sphinx/practical-tools/utilities.rst
@@ -137,7 +137,7 @@ Here we describe only few of them.
(e.g. wrappers)
:COQ_SRC_SUBDIRS:
can be extended by including other paths in which ``*.cm*`` files
- are searched. For example ``COQ\_SRC\_SUBDIRS+=user-contrib/Unicoq``
+ are searched. For example ``COQ_SRC_SUBDIRS+=user-contrib/Unicoq``
lets you build a plugin containing OCaml code that depends on the
OCaml code of ``Unicoq``.
diff --git a/doc/sphinx/proof-engine/ltac.rst b/doc/sphinx/proof-engine/ltac.rst
index 7ab11889f..2b128b98f 100644
--- a/doc/sphinx/proof-engine/ltac.rst
+++ b/doc/sphinx/proof-engine/ltac.rst
@@ -248,6 +248,7 @@ focused goals with:
in a tactic expression, by using the keyword ``only``:
.. tacv:: only selector : expr
+ :name: only ... : ...
When selecting several goals, the tactic expr is applied globally to all
selected goals.
@@ -268,6 +269,7 @@ focused goals with:
for ``n-n`` when specifying multiple ranges.
.. tacv:: all: @expr
+ :name: all: ...
In this variant, :n:`@expr` is applied to all focused goals. ``all:`` can only
be used at the toplevel of a tactic expression.
@@ -279,6 +281,7 @@ focused goals with:
used at the toplevel of a tactic expression.
.. tacv:: par: @expr
+ :name: par: ...
In this variant, :n:`@expr` is applied to all focused goals in parallel.
The number of workers can be controlled via the command line option
@@ -288,8 +291,8 @@ focused goals with:
nothing (i.e. it cannot make some progress). ``par:`` can only be used at
the toplevel of a tactic expression.
- .. exn:: No such goal
- :name: No such goal (goal selector)
+ .. exn:: No such goal.
+ :name: No such goal. (Goal selector)
.. TODO change error message index entry
@@ -348,7 +351,7 @@ We can check if a tactic made progress with:
to one of the focused subgoal produced subgoals equal to the initial
goals (up to syntactical equality), then an error of level 0 is raised.
- .. exn:: Failed to progress
+ .. exn:: Failed to progress.
Backtracking branching
~~~~~~~~~~~~~~~~~~~~~~
@@ -389,7 +392,7 @@ tactic to work (i.e. which does not fail) among a panel of tactics:
:n:`first [:@expr__1 | ... | @expr__n]` behaves, in each goal, as the the first
:n:`v__i` to have *at least* one success.
- .. exn:: Error message: No applicable tactic
+ .. exn:: No applicable tactic.
.. tacv:: first @expr
@@ -478,7 +481,7 @@ one* success:
whether a second success exists, and may run further effects
immediately.
- .. exn:: This tactic has more than one success
+ .. exn:: This tactic has more than one success.
Checking the failure
~~~~~~~~~~~~~~~~~~~~
@@ -516,7 +519,7 @@ among a panel of tactics:
each goal independently, if it doesn’t solve the goal then it tries to
apply :n:`v__2` and so on. It fails if there is no solving tactic.
- .. exn:: Cannot solve the goal
+ .. exn:: Cannot solve the goal.
.. tacv:: solve @expr
@@ -547,7 +550,7 @@ Failing
:tacn:`fail` tactic will, however, succeed if all the goals have already been
solved.
- .. tacv:: fail @natural
+ .. tacv:: fail @num
The number is the failure level. If no level is specified, it defaults to 0.
The level is used by :tacn:`try`, :tacn:`repeat`, :tacn:`match goal` and the branching
@@ -555,14 +558,14 @@ Failing
(backtracking). If non zero, the current :tacn:`match goal` block, :tacn:`try`,
:tacn:`repeat`, or branching command is aborted and the level is decremented. In
the case of :n:`+`, a non-zero level skips the first backtrack point, even if
- the call to :n:`fail @natural` is not enclosed in a :n:`+` command,
+ the call to :n:`fail @num` is not enclosed in a :n:`+` command,
respecting the algebraic identity.
.. tacv:: fail {* message_token}
The given tokens are used for printing the failure message.
- .. tacv:: fail @natural {* message_token}
+ .. tacv:: fail @num {* message_token}
This is a combination of the previous variants.
@@ -573,7 +576,7 @@ Failing
.. tacv:: gfail {* message_token}
- .. tacv:: gfail @natural {* message_token}
+ .. tacv:: gfail @num {* message_token}
These variants fail with an error message or an error level even if
there are no goals left. Be careful however if Coq terms have to be
@@ -581,7 +584,7 @@ Failing
tactic into the goals, meaning that if there are no goals when it is
evaluated, a tactic call like :n:`let x:=H in fail 0 x` will succeed.
- .. exn:: Tactic Failure message (level @natural).
+ .. exn:: Tactic Failure message (level @num).
Timeout
~~~~~~~
@@ -760,11 +763,11 @@ We can carry out pattern matching on terms with:
branches or inside the right-hand side of the selected branch even if it
has backtracking points.
- .. exn:: No matching clauses for match
+ .. exn:: No matching clauses for match.
No pattern can be used and, in particular, there is no :n:`_` pattern.
- .. exn:: Argument of match does not evaluate to a term
+ .. exn:: Argument of match does not evaluate to a term.
This happens when :n:`@expr` does not denote a term.
@@ -823,6 +826,7 @@ We can make pattern matching on goals using the following expression:
.. we should provide the full grammar here
.. tacn:: match goal with {+| {+ hyp} |- @cpattern => @expr } | _ => @expr end
+ :name: match goal
If each hypothesis pattern :n:`hyp`\ :sub:`1,i`, with i=1,...,m\ :sub:`1` is
matched (non-linear first-order unification) by an hypothesis of the
@@ -844,7 +848,7 @@ We can make pattern matching on goals using the following expression:
branches or combinations of hypotheses, or inside the right-hand side of
the selected branch even if it has backtracking points.
- .. exn:: No matching clauses for match goal
+ .. exn:: No matching clauses for match goal.
No clause succeeds, i.e. all matching patterns, if any, fail at the
application of the right-hand-side.
@@ -891,7 +895,7 @@ produce subgoals but generates a term to be used in tactic expressions:
match expression. This expression evaluates replaces the hole of the
value of :n:`@ident` by the value of :n:`@expr`.
- .. exn:: not a context variable
+ .. exn:: Not a context variable.
Generating fresh hypothesis names
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1001,7 +1005,7 @@ Testing boolean expressions
all:let n:= numgoals in guard n<4.
Fail all:let n:= numgoals in guard n=2.
- .. exn:: Condition not satisfied
+ .. exn:: Condition not satisfied.
Proving a subgoal as a separate lemma
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1051,8 +1055,8 @@ Proving a subgoal as a separate lemma
with tactics is fragile, and explicitly named and reused subterms
don’t play well with asynchronous proofs.
- .. exn:: Proof is not complete
- :name: Proof is not complete (abstract)
+ .. exn:: Proof is not complete.
+ :name: Proof is not complete. (abstract)
Tactic toplevel definitions
---------------------------
@@ -1092,7 +1096,7 @@ Basically, |Ltac| toplevel definitions are made as follows:
Printing |Ltac| tactics
~~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Print Ltac @qualid.
+.. cmd:: Print Ltac @qualid
Defined |Ltac| functions can be displayed using this command.
@@ -1107,10 +1111,11 @@ Info trace
~~~~~~~~~~
.. cmd:: Info @num @expr
+ :name: Info
This command can be used to print the trace of the path eventually taken by an
|Ltac| script. That is, the list of executed tactics, discarding
- all the branches which have failed. To that end the Info command can be
+ all the branches which have failed. To that end the :cmd:`Info` command can be
used with the following syntax.
@@ -1137,23 +1142,22 @@ Info trace
Info 1 t 1||t 0.
- The trace produced by ``Info`` tries its best to be a reparsable
+ The trace produced by :cmd:`Info` tries its best to be a reparsable
|Ltac| script, but this goal is not achievable in all generality.
So some of the output traces will contain oddities.
- As an additional help for debugging, the trace produced by ``Info`` contains
- (in comments) the messages produced by the idtac
- tacticals \ `4.2 <#ltac%3Aidtac>`__ at the right possition in the
- script. In particular, the calls to idtac in branches which failed are
+ As an additional help for debugging, the trace produced by :cmd:`Info` contains
+ (in comments) the messages produced by the :tacn:`idtac` tactical at the right
+ position in the script. In particular, the calls to idtac in branches which failed are
not printed.
- .. opt:: Info Level @num.
+ .. opt:: Info Level @num
- This option is an alternative to the ``Info`` command.
+ This option is an alternative to the :cmd:`Info` command.
This will automatically print the same trace as :n:`Info @num` at each
tactic call. The unfolding level can be overridden by a call to the
- ``Info`` command.
+ :cmd:`Info` command.
Interactive debugger
~~~~~~~~~~~~~~~~~~~~
@@ -1223,7 +1227,7 @@ performance bug.
.. warning::
- Backtracking across a Reset Ltac Profile will not restore the information.
+ Backtracking across a :cmd:`Reset Ltac Profile` will not restore the information.
.. coqtop:: reset in
@@ -1286,8 +1290,8 @@ performance bug.
benchmarking purposes.
You can also pass the ``-profile-ltac`` command line option to ``coqc``, which
-performs a ``Set Ltac Profiling`` at the beginning of each document, and a
-``Show Ltac Profile`` at the end.
+turns the :opt:`Ltac Profiling` option on at the beginning of each document,
+and performs a :cmd:`Show Ltac Profile` at the end.
.. warning::
diff --git a/doc/sphinx/proof-engine/proof-handling.rst b/doc/sphinx/proof-engine/proof-handling.rst
index 86c94bab3..eba0db3ff 100644
--- a/doc/sphinx/proof-engine/proof-handling.rst
+++ b/doc/sphinx/proof-engine/proof-handling.rst
@@ -8,12 +8,13 @@
In |Coq|’s proof editing mode all top-level commands documented in
Chapter :ref:`vernacularcommands` remain available and the user has access to specialized
commands dealing with proof development pragmas documented in this
-section. He can also use some other specialized commands called
+section. They can also use some other specialized commands called
*tactics*. They are the very tools allowing the user to deal with
logical reasoning. They are documented in Chapter :ref:`tactics`.
-When switching in editing proof mode, the prompt ``Coq <`` is changed into
-``ident <`` where ``ident`` is the declared name of the theorem currently
-edited.
+
+Coq user interfaces usually have a way of marking whether the user has
+switched to proof editing mode. For instance, in coqtop the prompt ``Coq <``   is changed into
+:n:`@ident <`   where :token:`ident` is the declared name of the theorem currently edited.
At each stage of a proof development, one has a list of goals to
prove. Initially, the list consists only in the theorem itself. After
@@ -34,10 +35,10 @@ terms of λ-calculus, known as the *Curry-Howard isomorphism*
terms are called *proof terms*.
-.. exn:: No focused proof
+.. exn:: No focused proof.
-Coq raises this error message when one attempts to use a proof editing command
-out of the proof editing mode.
+ Coq raises this error message when one attempts to use a proof editing command
+ out of the proof editing mode.
.. _proof-editing-mode:
@@ -46,137 +47,151 @@ Switching on/off the proof editing mode
The proof editing mode is entered by asserting a statement, which typically is
the assertion of a theorem using an assertion command like :cmd:`Theorem`. The
-list of assertion commands is given in Section :ref:`Assertions`. The command
+list of assertion commands is given in :ref:`Assertions`. The command
:cmd:`Goal` can also be used.
-.. cmd:: Goal @form.
+.. cmd:: Goal @form
-This is intended for quick assertion of statements, without knowing in
-advance which name to give to the assertion, typically for quick
-testing of the provability of a statement. If the proof of the
-statement is eventually completed and validated, the statement is then
-bound to the name ``Unnamed_thm`` (or a variant of this name not already
-used for another statement).
+ This is intended for quick assertion of statements, without knowing in
+ advance which name to give to the assertion, typically for quick
+ testing of the provability of a statement. If the proof of the
+ statement is eventually completed and validated, the statement is then
+ bound to the name ``Unnamed_thm`` (or a variant of this name not already
+ used for another statement).
.. cmd:: Qed
- :name: Qed (interactive proof)
-
-This command is available in interactive editing proof mode when the
-proof is completed. Then ``Qed`` extracts a proof term from the proof
-script, switches back to Coq top-level and attaches the extracted
-proof term to the declared name of the original goal. This name is
-added to the environment as an opaque constant.
+ This command is available in interactive editing proof mode when the
+ proof is completed. Then :cmd:`Qed` extracts a proof term from the proof
+ script, switches back to Coq top-level and attaches the extracted
+ proof term to the declared name of the original goal. This name is
+ added to the environment as an opaque constant.
-.. exn:: Attempt to save an incomplete proof
+ .. exn:: Attempt to save an incomplete proof.
-.. note::
+ .. note::
- Sometimes an error occurs when building the proof term, because
- tactics do not enforce completely the term construction
- constraints.
+ Sometimes an error occurs when building the proof term, because
+ tactics do not enforce completely the term construction
+ constraints.
-The user should also be aware of the fact that since the
-proof term is completely rechecked at this point, one may have to wait
-a while when the proof is large. In some exceptional cases one may
-even incur a memory overflow.
+ The user should also be aware of the fact that since the
+ proof term is completely rechecked at this point, one may have to wait
+ a while when the proof is large. In some exceptional cases one may
+ even incur a memory overflow.
-.. cmdv:: Defined.
- :name: Defined (interactive proof)
+ .. cmdv:: Defined
+ :name: Defined
-Defines the proved term as a transparent constant.
+ Same as :cmd:`Qed` but the proof is then declared transparent, which means
+ that its content can be explicitly used for type-checking and that it can be
+ unfolded in conversion tactics (see :ref:`performingcomputations`,
+ :cmd:`Opaque`, :cmd:`Transparent`).
-.. cmdv:: Save @ident.
+ .. cmdv:: Save @ident
+ :name: Save
-Forces the name of the original goal to be :n:`@ident`. This
-command (and the following ones) can only be used if the original goal
-has been opened using the ``Goal`` command.
+ Forces the name of the original goal to be :token:`ident`. This
+ command (and the following ones) can only be used if the original goal
+ has been opened using the :cmd:`Goal` command.
-.. cmd:: Admitted.
- :name: Admitted (interactive proof)
+.. cmd:: Admitted
-This command is available in interactive editing proof mode to give up
-the current proof and declare the initial goal as an axiom.
-
-.. cmd:: Proof @term.
- :name: Proof `term`
+ This command is available in interactive editing mode to give up
+ the current proof and declare the initial goal as an axiom.
-This command applies in proof editing mode. It is equivalent to
+.. cmd:: Abort
-.. cmd:: exact @term. Qed.
+ This command cancels the current proof development, switching back to
+ the previous proof development, or to the |Coq| toplevel if no other
+ proof was edited.
-That is, you have to give the full proof in one gulp, as a
-proof term (see Section :ref:`applyingtheorems`).
+ .. exn:: No focused proof (No proof-editing in progress).
-.. cmdv:: Proof.
- :name: Proof (interactive proof)
+ .. cmdv:: Abort @ident
-Is a noop which is useful to delimit the sequence of tactic commands
-which start a proof, after a ``Theorem`` command. It is a good practice to
-use ``Proof``. as an opening parenthesis, closed in the script with a
-closing ``Qed``.
+ Aborts the editing of the proof named :token:`ident` (in case you have
+ nested proofs).
+ .. seealso:: :opt:`Nested Proofs Allowed`
-See also: ``Proof with tactic.`` in Section
-:ref:`tactics-implicit-automation`.
+ .. cmdv:: Abort All
+ Aborts all current goals.
-.. cmd:: Proof using @ident1 ... @identn.
+.. cmd:: Proof @term
+ :name: Proof `term`
-This command applies in proof editing mode. It declares the set of
-section variables (see :ref:`gallina-assumptions`) used by the proof. At ``Qed`` time, the
-system will assert that the set of section variables actually used in
-the proof is a subset of the declared one.
+ This command applies in proof editing mode. It is equivalent to
+ :n:`exact @term. Qed.`
+ That is, you have to give the full proof in one gulp, as a
+ proof term (see Section :ref:`applyingtheorems`).
-The set of declared variables is closed under type dependency. For
-example if ``T`` is variable and a is a variable of type ``T``, the commands
-``Proof using a`` and ``Proof using T a``` are actually equivalent.
+.. cmd:: Proof
+ Is a no-op which is useful to delimit the sequence of tactic commands
+ which start a proof, after a :cmd:`Theorem` command. It is a good practice to
+ use :cmd:`Proof` as an opening parenthesis, closed in the script with a
+ closing :cmd:`Qed`.
-.. cmdv:: Proof using @ident1 ... @identn with @tactic.
+ .. seealso:: :cmd:`Proof with`
-in Section :ref:`tactics-implicit-automation`.
+.. cmd:: Proof using {+ @ident }
-.. cmdv:: Proof using All.
+ This command applies in proof editing mode. It declares the set of
+ section variables (see :ref:`gallina-assumptions`) used by the proof.
+ At :cmd:`Qed` time, the
+ system will assert that the set of section variables actually used in
+ the proof is a subset of the declared one.
-Use all section variables.
+ The set of declared variables is closed under type dependency. For
+ example if ``T`` is variable and a is a variable of type ``T``, the commands
+ ``Proof using a`` and ``Proof using T a`` are actually equivalent.
+ .. cmdv:: Proof using {+ @ident } with @tactic
-.. cmdv:: Proof using Type.
+ Combines in a single line :cmd:`Proof with` and :cmd:`Proof using`.
-.. cmdv:: Proof using.
+ .. seealso:: :ref:`tactics-implicit-automation`
-Use only section variables occurring in the statement.
+ .. cmdv:: Proof using All
+ Use all section variables.
-.. cmdv:: Proof using Type*.
+ .. cmdv:: Proof using {? Type }
-The ``*`` operator computes the forward transitive closure. E.g. if the
-variable ``H`` has type ``p < 5`` then ``H`` is in ``p*`` since ``p`` occurs in the type
-of ``H``. ``Type*`` is the forward transitive closure of the entire set of
-section variables occurring in the statement.
+ Use only section variables occurring in the statement.
+ .. cmdv:: Proof using Type*
-.. cmdv:: Proof using -(@ident1 ... @identn).
+ The ``*`` operator computes the forward transitive closure. E.g. if the
+ variable ``H`` has type ``p < 5`` then ``H`` is in ``p*`` since ``p`` occurs in the type
+ of ``H``. ``Type*`` is the forward transitive closure of the entire set of
+ section variables occurring in the statement.
-Use all section variables except :n:`@ident1` ... :n:`@identn`.
+ .. cmdv:: Proof using -({+ @ident })
+ Use all section variables except the list of :token:`ident`.
-.. cmdv:: Proof using @collection1 + @collection2 .
+ .. cmdv:: Proof using @collection1 + @collection2
+ Use section variables from the union of both collections.
+ See :ref:`nameaset` to know how to form a named collection.
-.. cmdv:: Proof using @collection1 - @collection2 .
+ .. cmdv:: Proof using @collection1 - @collection2
+ Use section variables which are in the first collection but not in the
+ second one.
-.. cmdv:: Proof using @collection - ( @ident1 ... @identn ).
+ .. cmdv:: Proof using @collection - ({+ @ident })
+ Use section variables which are in the first collection but not in the
+ list of :token:`ident`.
-.. cmdv:: Proof using @collection * .
+ .. cmdv:: Proof using @collection *
-Use section variables being, respectively, in the set union, set
-difference, set complement, set forward transitive closure. See
-Section :ref:`nameaset` to know how to form a named collection. The ``*`` operator
-binds stronger than ``+`` and ``-``.
+ Use section variables in the forward transitive closure of the collection.
+ The ``*`` operator binds stronger than ``+`` and ``-``.
Proof using options
@@ -185,16 +200,16 @@ Proof using options
The following options modify the behavior of ``Proof using``.
-.. opt:: Default Proof Using "@expression".
+.. opt:: Default Proof Using "@expression"
- Use :n:`@expression` as the default ``Proof``` using value. E.g. ``Set Default
- Proof Using "a b"``. will complete all ``Proof`` commands not followed by a
- using part with using ``a`` ``b``.
+ Use :n:`@expression` as the default ``Proof using`` value. E.g. ``Set Default
+ Proof Using "a b"`` will complete all ``Proof`` commands not followed by a
+ ``using`` part with ``using a b``.
-.. opt:: Suggest Proof Using.
+.. opt:: Suggest Proof Using
- When ``Qed`` is performed, suggest a using annotation if the user did not
+ When :cmd:`Qed` is performed, suggest a ``using`` annotation if the user did not
provide one.
.. _`nameaset`:
@@ -202,163 +217,132 @@ The following options modify the behavior of ``Proof using``.
Name a set of section hypotheses for ``Proof using``
````````````````````````````````````````````````````
-.. cmd:: Collection @ident := @section_subset_expr
-
-The command ``Collection`` can be used to name a set of section
-hypotheses, with the purpose of making ``Proof using`` annotations more
-compact.
-
-
-.. cmdv:: Collection Some := x y z
-
-Define the collection named "Some" containing ``x``, ``y`` and ``z``.
-
-
-.. cmdv:: Collection Fewer := Some - z
-
-Define the collection named "Fewer" containing only ``x`` and ``y``.
-
-
-.. cmdv:: Collection Many := Fewer + Some
-.. cmdv:: Collection Many := Fewer - Some
-
-Define the collection named "Many" containing the set union or set
-difference of "Fewer" and "Some".
-
-
-.. cmdv:: Collection Many := Fewer - (x y)
-
-Define the collection named "Many" containing the set difference of
-"Fewer" and the unnamed collection ``x`` ``y``
+.. cmd:: Collection @ident := @expression
+ This can be used to name a set of section
+ hypotheses, with the purpose of making ``Proof using`` annotations more
+ compact.
-.. cmd:: Abort.
+ .. example::
-This command cancels the current proof development, switching back to
-the previous proof development, or to the |Coq| toplevel if no other
-proof was edited.
+ Define the collection named ``Some`` containing ``x``, ``y`` and ``z``::
+ Collection Some := x y z.
-.. exn:: No focused proof (No proof-editing in progress)
+ Define the collection named ``Fewer`` containing only ``x`` and ``y``::
+ Collection Fewer := Some - z
+ Define the collection named ``Many`` containing the set union or set
+ difference of ``Fewer`` and ``Some``::
-.. cmdv:: Abort @ident.
+ Collection Many := Fewer + Some
+ Collection Many := Fewer - Some
-Aborts the editing of the proof named :n:`@ident`.
+ Define the collection named ``Many`` containing the set difference of
+ ``Fewer`` and the unnamed collection ``x y``::
-.. cmdv:: Abort All.
+ Collection Many := Fewer - (x y)
-Aborts all current goals, switching back to the |Coq|
-toplevel.
+.. cmd:: Existential @num := @term
-.. cmd:: Existential @num := @term.
+ This command instantiates an existential variable. :token:`num` is an index in
+ the list of uninstantiated existential variables displayed by :cmd:`Show Existentials`.
-This command instantiates an existential variable. :n:`@num` is an index in
-the list of uninstantiated existential variables displayed by ``Show
-Existentials`` (described in Section :ref:`requestinginformation`).
+ This command is intended to be used to instantiate existential
+ variables when the proof is completed but some uninstantiated
+ existential variables remain. To instantiate existential variables
+ during proof edition, you should use the tactic :tacn:`instantiate`.
-This command is intended to be used to instantiate existential
-variables when the proof is completed but some uninstantiated
-existential variables remain. To instantiate existential variables
-during proof edition, you should use the tactic :tacn:`instantiate`.
+.. cmd:: Grab Existential Variables
-
-See also: ``instantiate (num:= term).`` in Section
-:ref:`controllingtheproofflow`.
-See also: ``Grab Existential Variables.`` below.
-
-
-.. cmd:: Grab Existential Variables.
-
-This command can be run when a proof has no more goal to be solved but
-has remaining uninstantiated existential variables. It takes every
-uninstantiated existential variable and turns it into a goal.
+ This command can be run when a proof has no more goal to be solved but
+ has remaining uninstantiated existential variables. It takes every
+ uninstantiated existential variable and turns it into a goal.
Navigation in the proof tree
--------------------------------
+.. cmd:: Undo
-.. cmd:: Undo.
-
-This command cancels the effect of the last command. Thus, it
-backtracks one step.
+ This command cancels the effect of the last command. Thus, it
+ backtracks one step.
+.. cmdv:: Undo @num
-.. cmdv:: Undo @num.
+ Repeats Undo :token:`num` times.
-Repeats Undo :n:`@num` times.
-
-.. cmdv:: Restart.
+.. cmdv:: Restart
:name: Restart
-This command restores the proof editing process to the original goal.
+ This command restores the proof editing process to the original goal.
+ .. exn:: No focused proof to restart.
-.. exn:: No focused proof to restart
+.. cmd:: Focus
+ This focuses the attention on the first subgoal to prove and the
+ printing of the other subgoals is suspended until the focused subgoal
+ is solved or unfocused. This is useful when there are many current
+ subgoals which clutter your screen.
-.. cmd:: Focus.
+ .. deprecated:: 8.8
-This focuses the attention on the first subgoal to prove and the
-printing of the other subgoals is suspended until the focused subgoal
-is solved or unfocused. This is useful when there are many current
-subgoals which clutter your screen.
+ Prefer the use of bullets or focusing brackets (see below).
+.. cmdv:: Focus @num
-.. cmdv:: Focus @num.
+ This focuses the attention on the :token:`num` th subgoal to prove.
-This focuses the attention on the :n:`@num` th subgoal to
-prove.
+ .. deprecated:: 8.8
-*This command is deprecated since 8.8*: prefer the use of bullets or
-focusing brackets instead, including :n:`@num : %{`
+ Prefer the use of focusing brackets with a goal selector (see below).
-.. cmd:: Unfocus.
+.. cmd:: Unfocus
-This command restores to focus the goal that were suspended by the
-last ``Focus`` command.
+ This command restores to focus the goal that were suspended by the
+ last :cmd:`Focus` command.
-*This command is deprecated since 8.8.*
+ .. deprecated:: 8.8
-.. cmd:: Unfocused.
+.. cmd:: Unfocused
-Succeeds if the proof is fully unfocused, fails is there are some
-goals out of focus.
+ Succeeds if the proof is fully unfocused, fails if there are some
+ goals out of focus.
.. _curly-braces:
.. cmd:: %{ %| %}
-The command ``{`` (without a terminating period) focuses on the first
-goal, much like ``Focus.`` does, however, the subproof can only be
-unfocused when it has been fully solved ( *i.e.* when there is no
-focused goal left). Unfocusing is then handled by ``}`` (again, without a
-terminating period). See also example in next section.
+ The command ``{`` (without a terminating period) focuses on the first
+ goal, much like :cmd:`Focus` does, however, the subproof can only be
+ unfocused when it has been fully solved ( *i.e.* when there is no
+ focused goal left). Unfocusing is then handled by ``}`` (again, without a
+ terminating period). See also example in next section.
-Note that when a focused goal is proved a message is displayed
-together with a suggestion about the right bullet or ``}`` to unfocus it
-or focus the next one.
+ Note that when a focused goal is proved a message is displayed
+ together with a suggestion about the right bullet or ``}`` to unfocus it
+ or focus the next one.
-.. cmdv:: @num: %{
+ .. cmdv:: @num: %{
-This focuses on the :n:`@num` th subgoal to prove.
+ This focuses on the :token:`num` th subgoal to prove.
-Error messages:
+ Error messages:
-.. exn:: This proof is focused, but cannot be unfocused this way
+ .. exn:: This proof is focused, but cannot be unfocused this way.
-You are trying to use ``}`` but the current subproof has not been fully solved.
+ You are trying to use ``}`` but the current subproof has not been fully solved.
-.. exn:: No such goal
- :name: No such goal (focusing)
+ .. exn:: No such goal.
+ :name: No such goal. (Focusing)
-.. exn:: Brackets only support the single numbered goal selector
+ .. exn:: Brackets only support the single numbered goal selector.
-See also error messages about bullets below.
+ See also error messages about bullets below.
.. _bullets:
@@ -409,35 +393,30 @@ The following example script illustrates all these features:
assumption.
-.. exn:: Wrong bullet @bullet1 : Current bullet @bullet2 is not finished.
+.. exn:: Wrong bullet @bullet1: Current bullet @bullet2 is not finished.
-Before using bullet :n:`@bullet1` again, you should first finish proving the current focused goal. Note that :n:`@bullet1` and :n:`@bullet2` may be the same.
+ Before using bullet :n:`@bullet1` again, you should first finish proving the current focused goal. Note that :n:`@bullet1` and :n:`@bullet2` may be the same.
-.. exn:: Wrong bullet @bullet1 : Bullet @bullet2 is mandatory here.
+.. exn:: Wrong bullet @bullet1: Bullet @bullet2 is mandatory here.
-You must put :n:`@bullet2` to focus next goal. No other bullet is allowed here.
+ You must put :n:`@bullet2` to focus next goal. No other bullet is allowed here.
.. exn:: No such goal. Focus next goal with bullet @bullet.
-You tried to applied a tactic but no goal where under focus. Using :n:`@bullet` is mandatory here.
+ You tried to apply a tactic but no goal where under focus. Using :n:`@bullet` is mandatory here.
.. exn:: No such goal. Try unfocusing with %{.
-You just finished a goal focused by ``{``, you must unfocus it with ``}``.
+ You just finished a goal focused by ``{``, you must unfocus it with ``}``.
Set Bullet Behavior
```````````````````
+.. opt:: Bullet Behavior %( "None" %| "Strict Subproofs" %)
-The bullet behavior can be controlled by the following commands.
-
-.. opt:: Bullet Behavior "None"
-
-This makes bullets inactive.
-
-.. opt:: Bullet Behavior "Strict Subproofs"
-
-This makes bullets active (this is the default behavior).
+ This option controls the bullet behavior and can take two possible values:
+ - "None": this makes bullets inactive.
+ - "Strict Subproofs": this makes bullets active (this is the default behavior).
.. _requestinginformation:
@@ -445,112 +424,118 @@ Requesting information
----------------------
-.. cmd:: Show.
+.. cmd:: Show
-This command displays the current goals.
+ This command displays the current goals.
+ .. exn:: No focused proof.
-.. cmdv:: Show @num
+ .. cmdv:: Show @num
-Displays only the :n:`@num`-th subgoal.
+ Displays only the :token:`num` th subgoal.
-.. exn:: No such goal
-.. exn:: No focused proof
+ .. exn:: No such goal.
-.. cmdv:: Show @ident.
-Displays the named goal :n:`@ident`. This is useful in
-particular to display a shelved goal but only works if the
-corresponding existential variable has been named by the user
-(see :ref:`existential-variables`) as in the following example.
+ .. cmdv:: Show @ident
-.. example::
+ Displays the named goal :token:`ident`. This is useful in
+ particular to display a shelved goal but only works if the
+ corresponding existential variable has been named by the user
+ (see :ref:`existential-variables`) as in the following example.
- .. coqtop:: all
+ .. example::
- Goal exists n, n = 0.
- eexists ?[n].
- Show n.
+ .. coqtop:: all
-.. cmdv:: Show Script.
+ Goal exists n, n = 0.
+ eexists ?[n].
+ Show n.
-Displays the whole list of tactics applied from the
-beginning of the current proof. This tactics script may contain some
-holes (subgoals not yet proved). They are printed under the form
+ .. cmdv:: Show Script
+ :name: Show Script
-``<Your Tactic Text here>``.
+ Displays the whole list of tactics applied from the
+ beginning of the current proof. This tactics script may contain some
+ holes (subgoals not yet proved). They are printed under the form
-.. cmdv:: Show Proof.
+ ``<Your Tactic Text here>``.
-It displays the proof term generated by the tactics
-that have been applied. If the proof is not completed, this term
-contain holes, which correspond to the sub-terms which are still to be
-constructed. These holes appear as a question mark indexed by an
-integer, and applied to the list of variables in the context, since it
-may depend on them. The types obtained by abstracting away the context
-from the type of each hole-placer are also printed.
+ .. cmdv:: Show Proof
+ :name: Show Proof
-.. cmdv:: Show Conjectures.
+ It displays the proof term generated by the tactics
+ that have been applied. If the proof is not completed, this term
+ contain holes, which correspond to the sub-terms which are still to be
+ constructed. These holes appear as a question mark indexed by an
+ integer, and applied to the list of variables in the context, since it
+ may depend on them. The types obtained by abstracting away the context
+ from the type of each hole-placer are also printed.
-It prints the list of the names of all the
-theorems that are currently being proved. As it is possible to start
-proving a previous lemma during the proof of a theorem, this list may
-contain several names.
+ .. cmdv:: Show Conjectures
+ :name: Show Conjectures
-.. cmdv:: Show Intro.
+ It prints the list of the names of all the
+ theorems that are currently being proved. As it is possible to start
+ proving a previous lemma during the proof of a theorem, this list may
+ contain several names.
-If the current goal begins by at least one product,
-this command prints the name of the first product, as it would be
-generated by an anonymous ``intro``. The aim of this command is to ease
-the writing of more robust scripts. For example, with an appropriate
-Proof General macro, it is possible to transform any anonymous ``intro``
-into a qualified one such as ``intro y13``. In the case of a non-product
-goal, it prints nothing.
+ .. cmdv:: Show Intro
+ :name: Show Intro
-.. cmdv:: Show Intros.
+ If the current goal begins by at least one product,
+ this command prints the name of the first product, as it would be
+ generated by an anonymous :tacn:`intro`. The aim of this command is to ease
+ the writing of more robust scripts. For example, with an appropriate
+ Proof General macro, it is possible to transform any anonymous :tacn:`intro`
+ into a qualified one such as ``intro y13``. In the case of a non-product
+ goal, it prints nothing.
-This command is similar to the previous one, it
-simulates the naming process of an intros.
+ .. cmdv:: Show Intros
+ :name: Show Intros
-.. cmdv:: Show Existentials.
+ This command is similar to the previous one, it
+ simulates the naming process of an :tacn:`intros`.
-It displays the set of all uninstantiated
-existential variables in the current proof tree, along with the type
-and the context of each variable.
+ .. cmdv:: Show Existentials
+ :name: Show Existentials
-.. cmdv:: Show Match @ident.
+ It displays the set of all uninstantiated
+ existential variables in the current proof tree, along with the type
+ and the context of each variable.
-This variant displays a template of the Gallina
-``match`` construct with a branch for each constructor of the type
-:n:`@ident`
+ .. cmdv:: Show Match @ident
-.. example::
- .. coqtop:: all
+ This variant displays a template of the Gallina
+ ``match`` construct with a branch for each constructor of the type
+ :token:`ident`
- Show Match nat.
+ .. example::
+ .. coqtop:: all
-.. exn:: Unknown inductive type
+ Show Match nat.
-.. _ShowUniverses:
+ .. exn:: Unknown inductive type.
-.. cmdv:: Show Universes.
+ .. cmdv:: Show Universes
+ :name: Show Universes
-It displays the set of all universe constraints and
-its normalized form at the current stage of the proof, useful for
-debugging universe inconsistencies.
+ It displays the set of all universe constraints and
+ its normalized form at the current stage of the proof, useful for
+ debugging universe inconsistencies.
-.. cmd:: Guarded.
+.. cmd:: Guarded
-Some tactics (e.g. :tacn:`refine` :ref:`applyingtheorems`) allow to build proofs using
-fixpoint or co-fixpoint constructions. Due to the incremental nature
-of interactive proof construction, the check of the termination (or
-guardedness) of the recursive calls in the fixpoint or cofixpoint
-constructions is postponed to the time of the completion of the proof.
+ Some tactics (e.g. :tacn:`refine`) allow to build proofs using
+ fixpoint or co-fixpoint constructions. Due to the incremental nature
+ of interactive proof construction, the check of the termination (or
+ guardedness) of the recursive calls in the fixpoint or cofixpoint
+ constructions is postponed to the time of the completion of the proof.
-The command ``Guarded`` allows checking if the guard condition for
-fixpoint and cofixpoint is violated at some time of the construction
-of the proof without having to wait the completion of the proof.
+ The command :cmd:`Guarded` allows checking if the guard condition for
+ fixpoint and cofixpoint is violated at some time of the construction
+ of the proof without having to wait the completion of the proof.
Controlling the effect of proof editing commands
@@ -559,24 +544,34 @@ Controlling the effect of proof editing commands
.. opt:: Hyps Limit @num
-This option controls the maximum number of hypotheses displayed in goals
-after the application of a tactic. All the hypotheses remain usable
-in the proof development.
-When unset, it goes back to the default mode which is to print all
-available hypotheses.
+ This option controls the maximum number of hypotheses displayed in goals
+ after the application of a tactic. All the hypotheses remain usable
+ in the proof development.
+ When unset, it goes back to the default mode which is to print all
+ available hypotheses.
.. opt:: Automatic Introduction
-This option controls the way binders are handled
-in assertion commands such as ``Theorem ident [binders] : form``. When the
-option is set, which is the default, binders are automatically put in
-the local context of the goal to prove.
+ This option controls the way binders are handled
+ in assertion commands such as :n:`Theorem @ident {? @binders} : @term`. When the
+ option is on, which is the default, binders are automatically put in
+ the local context of the goal to prove.
+
+ When the option is off, binders are discharged on the statement to be
+ proved and a tactic such as :tacn:`intro` (see Section :ref:`managingthelocalcontext`)
+ has to be used to move the assumptions to the local context.
+
+
+.. opt:: Nested Proofs Allowed
-The option can be unset by issuing ``Unset Automatic Introduction``. When
-the option is unset, binders are discharged on the statement to be
-proved and a tactic such as intro (see Section :ref:`managingthelocalcontext`) has to be
-used to move the assumptions to the local context.
+ When turned on (it is off by default), this option enables support for nested
+ proofs: a new assertion command can be inserted before the current proof is
+ finished, in which case Coq will temporarily switch to the proof of this
+ *nested lemma*. When the proof of the nested lemma is finished (with :cmd:`Qed`
+ or :cmd:`Defined`), its statement will be made available (as if it had been
+ proved before starting the previous proof) and Coq will switch back to the
+ proof of the previous assertion.
Controlling memory usage
@@ -586,15 +581,15 @@ When experiencing high memory usage the following commands can be used
to force |Coq| to optimize some of its internal data structures.
-.. cmd:: Optimize Proof.
+.. cmd:: Optimize Proof
-This command forces |Coq| to shrink the data structure used to represent
-the ongoing proof.
+ This command forces |Coq| to shrink the data structure used to represent
+ the ongoing proof.
-.. cmd:: Optimize Heap.
+.. cmd:: Optimize Heap
-This command forces the |OCaml| runtime to perform a heap compaction.
-This is in general an expensive operation.
-See: `OCaml Gc <http://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html#VALcompact>`_
-There is also an analogous tactic :tac:`optimize_heap`.
+ This command forces the |OCaml| runtime to perform a heap compaction.
+ This is in general an expensive operation.
+ See: `OCaml Gc <http://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html#VALcompact>`_
+ There is also an analogous tactic :tacn:`optimize_heap`.
diff --git a/doc/sphinx/proof-engine/ssreflect-proof-language.rst b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
index 977a5b8fa..63cd0f3ea 100644
--- a/doc/sphinx/proof-engine/ssreflect-proof-language.rst
+++ b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
@@ -423,7 +423,7 @@ an improvement over ``all null s``.
The syntax of the new declaration is
-.. cmd:: Prenex Implicits {+ @ident}.
+.. cmd:: Prenex Implicits {+ @ident}
Let us denote :math:`c_1` … :math:`c_n` the list of identifiers given to a
``Prenex Implicits`` command. The command checks that each ci is the name of
@@ -2157,10 +2157,10 @@ equivalent to:
More generally, the tactic:
-.. tacn:: @tactic; last @natural first
+.. tacn:: @tactic; last @num first
:name: last first
-where :token:`natural` is a |Coq| numeral, or and Ltac variable
+where :token:`num` is a |Coq| numeral, or an Ltac variable
denoting a |Coq|
numeral, having the value k. It rotates the n subgoals G1 , …, Gn
generated by tactic. The first subgoal becomes Gn + 1 − k and the
@@ -2168,7 +2168,7 @@ circular order of subgoals remains unchanged.
Conversely, the tactic:
-.. tacn:: @tactic; first @natural last
+.. tacn:: @tactic; first @num last
:name: first last
rotates the n subgoals G1 , …, Gn generated by tactic in order that
@@ -5322,11 +5322,11 @@ intro item see :ref:`introduction_ssr`
multiplier see :ref:`iteration_ssr`
-.. prodn:: occ_switch ::= { {? + %| - } {* @natural } }
+.. prodn:: occ_switch ::= { {? + %| - } {* @num } }
occur. switch see :ref:`occurrence_selection_ssr`
-.. prodn:: mult ::= {? @natural } @mult_mark
+.. prodn:: mult ::= {? @num } @mult_mark
multiplier see :ref:`iteration_ssr`
diff --git a/doc/sphinx/proof-engine/tactics.rst b/doc/sphinx/proof-engine/tactics.rst
index a3d06ae04..3835524f0 100644
--- a/doc/sphinx/proof-engine/tactics.rst
+++ b/doc/sphinx/proof-engine/tactics.rst
@@ -92,14 +92,14 @@ bindings_list`` where ``bindings_list`` may be of two different forms:
the ``n``-th non dependent premise of the ``term``, as determined by the type
of ``term``.
- .. exn:: No such binder
+ .. exn:: No such binder.
+ A bindings list can also be a simple list of terms :n:`{* term}`.
In that case the references to which these terms correspond are
- determined by the tactic. In case of ``induction``, ``destruct``, ``elim``
- and ``case`` (see :ref:`ltac`) the terms have to
+ determined by the tactic. In case of :tacn:`induction`, :tacn:`destruct`, :tacn:`elim`
+ and :tacn:`case`, the terms have to
provide instances for all the dependent products in the type of term while in
- the case of ``apply``, or of ``constructor`` and its variants, only instances
+ the case of :tacn:`apply`, or of :tacn:`constructor` and its variants, only instances
for the dependent products that are not bound in the conclusion of the type
are required.
@@ -151,8 +151,8 @@ no numbers are given, all occurrences of :n:`@term` in the goal are selected.
Finally, the last notation is an abbreviation for ``* |- *``. Note also
that ``|-`` is optional in the first case when no ``*`` is given.
-Here are some tactics that understand occurrences clauses: ``set``, ``remember``
-, ``induction``, ``destruct``.
+Here are some tactics that understand occurrences clauses: :tacn:`set`, :tacn:`remember`
+, :tacn:`induction`, :tacn:`destruct`.
See also: :ref:`Managingthelocalcontext`,
@@ -167,201 +167,203 @@ Applying theorems
.. tacn:: exact @term
:name: exact
-This tactic applies to any goal. It gives directly the exact proof
-term of the goal. Let ``T`` be our goal, let ``p`` be a term of type ``U`` then
-``exact p`` succeeds iff ``T`` and ``U`` are convertible (see
-:ref:`Conversion-rules`).
+ This tactic applies to any goal. It gives directly the exact proof
+ term of the goal. Let ``T`` be our goal, let ``p`` be a term of type ``U`` then
+ ``exact p`` succeeds iff ``T`` and ``U`` are convertible (see
+ :ref:`Conversion-rules`).
-.. exn:: Not an exact proof.
+ .. exn:: Not an exact proof.
-.. tacv:: eexact @term.
- :name: eexact
+ .. tacv:: eexact @term.
+ :name: eexact
-This tactic behaves like exact but is able to handle terms and goals with
-meta-variables.
+ This tactic behaves like exact but is able to handle terms and goals with
+ meta-variables.
.. tacn:: assumption
:name: assumption
-This tactic looks in the local context for an hypothesis which type is equal to
-the goal. If it is the case, the subgoal is proved. Otherwise, it fails.
+ This tactic looks in the local context for an hypothesis which type is equal to
+ the goal. If it is the case, the subgoal is proved. Otherwise, it fails.
-.. exn:: No such assumption.
+ .. exn:: No such assumption.
-.. tacv:: eassumption
- :name: eassumption
+ .. tacv:: eassumption
+ :name: eassumption
-This tactic behaves like assumption but is able to handle goals with
-meta-variables.
+ This tactic behaves like assumption but is able to handle goals with
+ meta-variables.
.. tacn:: refine @term
:name: refine
-This tactic applies to any goal. It behaves like exact with a big
-difference: the user can leave some holes (denoted by ``_`` or``(_:type)``) in
-the term. refine will generate as many subgoals as there are holes in
-the term. The type of holes must be either synthesized by the system
-or declared by an explicit cast like ``(_:nat->Prop)``. Any subgoal that
-occurs in other subgoals is automatically shelved, as if calling
-shelve_unifiable (see Section 8.17.4). This low-level tactic can be
-useful to advanced users.
+ This tactic applies to any goal. It behaves like :tacn:`exact` with a big
+ difference: the user can leave some holes (denoted by ``_`` or ``(_:type)``) in
+ the term. :tacn:`refine` will generate as many subgoals as there are holes in
+ the term. The type of holes must be either synthesized by the system
+ or declared by an explicit cast like ``(_:nat->Prop)``. Any subgoal that
+ occurs in other subgoals is automatically shelved, as if calling
+ :tacn:`shelve_unifiable`. This low-level tactic can be
+ useful to advanced users.
-.. example::
- .. coqtop:: reset all
+ .. example::
+ .. coqtop:: reset all
- Inductive Option : Set :=
- | Fail : Option
- | Ok : bool -> Option.
+ Inductive Option : Set :=
+ | Fail : Option
+ | Ok : bool -> Option.
- Definition get : forall x:Option, x <> Fail -> bool.
+ Definition get : forall x:Option, x <> Fail -> bool.
- refine
- (fun x:Option =>
- match x return x <> Fail -> bool with
- | Fail => _
- | Ok b => fun _ => b
- end).
+ refine
+ (fun x:Option =>
+ match x return x <> Fail -> bool with
+ | Fail => _
+ | Ok b => fun _ => b
+ end).
- intros; absurd (Fail = Fail); trivial.
+ intros; absurd (Fail = Fail); trivial.
- Defined.
+ Defined.
-.. exn:: invalid argument
+ .. exn:: Invalid argument.
- The tactic ``refine`` does not know what to do with the term you gave.
+ The tactic :tacn:`refine` does not know what to do with the term you gave.
-.. exn:: Refine passed ill-formed term
+ .. exn:: Refine passed ill-formed term.
- The term you gave is not a valid proof (not easy to debug in general). This
- message may also occur in higher-level tactics that call ``refine``
- internally.
+ The term you gave is not a valid proof (not easy to debug in general). This
+ message may also occur in higher-level tactics that call :tacn:`refine`
+ internally.
-.. exn:: Cannot infer a term for this placeholder
+ .. exn:: Cannot infer a term for this placeholder.
+ :name: Cannot infer a term for this placeholder. (refine)
- There is a hole in the term you gave which type cannot be inferred. Put a
- cast around it.
+ There is a hole in the term you gave whose type cannot be inferred. Put a
+ cast around it.
-.. tacv:: simple refine @term
- :name: simple refine
+ .. tacv:: simple refine @term
+ :name: simple refine
- This tactic behaves like refine, but it does not shelve any subgoal. It does
- not perform any beta-reduction either.
+ This tactic behaves like refine, but it does not shelve any subgoal. It does
+ not perform any beta-reduction either.
-.. tacv:: notypeclasses refine @term
+ .. tacv:: notypeclasses refine @term
+ :name: notypeclasses refine
- This tactic behaves like ``refine`` except it performs typechecking without
- resolution of typeclasses.
+ This tactic behaves like :tacn:`refine` except it performs typechecking without
+ resolution of typeclasses.
-.. tacv:: simple notypeclasses refine @term
- :name: simple notypeclasses refine
+ .. tacv:: simple notypeclasses refine @term
+ :name: simple notypeclasses refine
- This tactic behaves like ``simple refine`` except it performs typechecking
- without resolution of typeclasses.
+ This tactic behaves like :tacn:`simple refine` except it performs typechecking
+ without resolution of typeclasses.
-.. tacv:: apply @term
+.. tacn:: apply @term
:name: apply
-This tactic applies to any goal. The argument term is a term well-formed in the
-local context. The tactic apply tries to match the current goal against the
-conclusion of the type of term. If it succeeds, then the tactic returns as many
-subgoals as the number of non-dependent premises of the type of term. If the
-conclusion of the type of term does not match the goal *and* the conclusion is
-an inductive type isomorphic to a tuple type, then each component of the tuple
-is recursively matched to the goal in the left-to-right order.
+ This tactic applies to any goal. The argument term is a term well-formed in the
+ local context. The tactic apply tries to match the current goal against the
+ conclusion of the type of term. If it succeeds, then the tactic returns as many
+ subgoals as the number of non-dependent premises of the type of term. If the
+ conclusion of the type of term does not match the goal *and* the conclusion is
+ an inductive type isomorphic to a tuple type, then each component of the tuple
+ is recursively matched to the goal in the left-to-right order.
-The tactic ``apply`` relies on first-order unification with dependent types
-unless the conclusion of the type of ``term`` is of the form :g:`P (t`:sub:`1`
-:g:`...` :g:`t`:sub:`n` :g:`)` with `P` to be instantiated. In the latter case, the behavior
-depends on the form of the goal. If the goal is of the form
-:g:`(fun x => Q) u`:sub:`1` :g:`...` :g:`u`:sub:`n` and the :g:`t`:sub:`i` and
-:g:`u`:sub:`i` unifies, then :g:`P` is taken to be :g:`(fun x => Q)`. Otherwise,
-``apply`` tries to define :g:`P` by abstracting over :g:`t`:sub:`1` :g:`...`
-:g:`t`:sub:`n` in the goal. See :tacn:`pattern` to transform the goal so that it
-gets the form :g:`(fun x => Q) u`:sub:`1` :g:`...` :g:`u`:sub:`n`.
+ The tactic :tacn:`apply` relies on first-order unification with dependent types
+ unless the conclusion of the type of :token:`term` is of the form :g:`P (t`:sub:`1`
+ :g:`...` :g:`t`:sub:`n` :g:`)` with `P` to be instantiated. In the latter case, the behavior
+ depends on the form of the goal. If the goal is of the form
+ :g:`(fun x => Q) u`:sub:`1` :g:`...` :g:`u`:sub:`n` and the :g:`t`:sub:`i` and
+ :g:`u`:sub:`i` unifies, then :g:`P` is taken to be :g:`(fun x => Q)`. Otherwise,
+ :tacn:`apply` tries to define :g:`P` by abstracting over :g:`t`:sub:`1` :g:`...`
+ :g:`t`:sub:`n` in the goal. See :tacn:`pattern` to transform the goal so that it
+ gets the form :g:`(fun x => Q) u`:sub:`1` :g:`...` :g:`u`:sub:`n`.
-.. exn:: Unable to unify ... with ... .
+ .. exn:: Unable to unify ... with ... .
-The apply tactic failed to match the conclusion of term and the current goal.
-You can help the apply tactic by transforming your goal with the
-:tacn:`change` or :tacn:`pattern` tactics.
+ The apply tactic failed to match the conclusion of :token:`term` and the
+ current goal. You can help the apply tactic by transforming your goal with
+ the :tacn:`change` or :tacn:`pattern` tactics.
-.. exn:: Unable to find an instance for the variables {+ @ident}.
+ .. exn:: Unable to find an instance for the variables {+ @ident}.
-This occurs when some instantiations of the premises of term are not deducible
-from the unification. This is the case, for instance, when you want to apply a
-transitivity property. In this case, you have to use one of the variants below:
+ This occurs when some instantiations of the premises of :token:`term` are not deducible
+ from the unification. This is the case, for instance, when you want to apply a
+ transitivity property. In this case, you have to use one of the variants below:
-.. tacv:: apply @term with {+ @term}
+ .. tacv:: apply @term with {+ @term}
-Provides apply with explicit instantiations for all dependent premises of the
-type of term that do not occur in the conclusion and consequently cannot be
-found by unification. Notice that the collection :n:`{+ @term}` must be given
-according to the order of these dependent premises of the type of term.
+ Provides apply with explicit instantiations for all dependent premises of the
+ type of term that do not occur in the conclusion and consequently cannot be
+ found by unification. Notice that the collection :n:`{+ @term}` must be given
+ according to the order of these dependent premises of the type of term.
-.. exn:: Not the right number of missing arguments.
+ .. exn:: Not the right number of missing arguments.
-.. tacv:: apply @term with @bindings_list
+ .. tacv:: apply @term with @bindings_list
-This also provides apply with values for instantiating premises. Here, variables
-are referred by names and non-dependent products by increasing numbers (see
-:ref:`bindings list <bindingslist>`).
+ This also provides apply with values for instantiating premises. Here, variables
+ are referred by names and non-dependent products by increasing numbers (see
+ :ref:`bindings list <bindingslist>`).
-.. tacv:: apply {+, @term}
+ .. tacv:: apply {+, @term}
-This is a shortcut for ``apply term``:sub:`1`
-``; [.. | ... ; [ .. | apply`` ``term``:sub:`n` ``] ... ]``,
-i.e. for the successive applications of ``term``:sub:`i+1` on the last subgoal
-generated by ``apply term``:sub:`i` , starting from the application of
-``term``:sub:`1`.
+ This is a shortcut for :n:`apply @term`:sub:`1`
+ :n:`; [.. | ... ; [ .. | apply @term`:sub:`n` :n:`] ... ]`,
+ i.e. for the successive applications of :token:`term`:sub:`i+1` on the last subgoal
+ generated by :n:`apply @term`:sub:`i` , starting from the application of
+ :token:`term`:sub:`1`.
-.. tacv:: eapply @term
- :name: eapply
+ .. tacv:: eapply @term
+ :name: eapply
-The tactic ``eapply`` behaves like ``apply`` but it does not fail when no
-instantiations are deducible for some variables in the premises. Rather, it
-turns these variables into existential variables which are variables still to
-instantiate (see :ref:`Existential-Variables`). The instantiation is
-intended to be found later in the proof.
+ The tactic :tacn:`eapply` behaves like :tacn:`apply` but it does not fail when no
+ instantiations are deducible for some variables in the premises. Rather, it
+ turns these variables into existential variables which are variables still to
+ instantiate (see :ref:`Existential-Variables`). The instantiation is
+ intended to be found later in the proof.
-.. tacv:: simple apply @term.
- :name: simple apply
+ .. tacv:: simple apply @term.
+ :name: simple apply
-This behaves like ``apply`` but it reasons modulo conversion only on subterms
-that contain no variables to instantiate. For instance, the following example
-does not succeed because it would require the conversion of ``id ?foo`` and
-``O``.
+ This behaves like :tacn:`apply` but it reasons modulo conversion only on subterms
+ that contain no variables to instantiate. For instance, the following example
+ does not succeed because it would require the conversion of ``id ?foo`` and
+ :g:`O`.
-.. example::
+ .. example::
- .. coqtop:: all
+ .. coqtop:: all
- Definition id (x : nat) := x.
- Hypothesis H : forall y, id y = y.
- Goal O = O.
- Fail simple apply H.
+ Definition id (x : nat) := x.
+ Parameter H : forall y, id y = y.
+ Goal O = O.
+ Fail simple apply H.
-Because it reasons modulo a limited amount of conversion, ``simple apply`` fails
-quicker than ``apply`` and it is then well-suited for uses in user-defined
-tactics that backtrack often. Moreover, it does not traverse tuples as ``apply``
-does.
+ Because it reasons modulo a limited amount of conversion, :tacn:`simple apply` fails
+ quicker than :tacn:`apply` and it is then well-suited for uses in user-defined
+ tactics that backtrack often. Moreover, it does not traverse tuples as :tacn:`apply`
+ does.
-.. tacv:: {? simple} apply {+, @term {? with @bindings_list}}
-.. tacv:: {? simple} eapply {+, @term {? with @bindings_list}}
- :name: simple eapply
+ .. tacv:: {? simple} apply {+, @term {? with @bindings_list}}
+ .. tacv:: {? simple} eapply {+, @term {? with @bindings_list}}
+ :name: simple eapply
-This summarizes the different syntaxes for ``apply`` and ``eapply``.
+ This summarizes the different syntaxes for :tacn:`apply` and :tacn:`eapply`.
-.. tacv:: lapply @term
- :name: lapply
+ .. tacv:: lapply @term
+ :name: lapply
-This tactic applies to any goal, say :g:`G`. The argument term has to be
-well-formed in the current context, its type being reducible to a non-dependent
-product :g:`A -> B` with :g:`B` possibly containing products. Then it generates
-two subgoals :g:`B->G` and :g:`A`. Applying ``lapply H`` (where :g:`H` has type
-:g:`A->B` and :g:`B` does not start with a product) does the same as giving the
-sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
+ This tactic applies to any goal, say :g:`G`. The argument term has to be
+ well-formed in the current context, its type being reducible to a non-dependent
+ product :g:`A -> B` with :g:`B` possibly containing products. Then it generates
+ two subgoals :g:`B->G` and :g:`A`. Applying ``lapply H`` (where :g:`H` has type
+ :g:`A->B` and :g:`B` does not start with a product) does the same as giving the
+ sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
-.. warn:: When @term contains more than one non dependent product the tactic lapply only takes into account the first product.
+ .. warn:: When @term contains more than one non dependent product the tactic lapply only takes into account the first product.
.. example::
Assume we have a transitive relation ``R`` on ``nat``:
@@ -501,7 +503,7 @@ sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
.. tacv:: eapply {+, @term with @bindings_list} in @ident as @intro_pattern.
- This works as :tacn:`apply ... in as` but using ``eapply``.
+ This works as :tacn:`apply ... in ... as` but using ``eapply``.
.. tacv:: simple apply @term in @ident
@@ -509,15 +511,15 @@ sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
on subterms that contain no variables to instantiate. For instance, if
:g:`id := fun x:nat => x` and :g:`H: forall y, id y = y -> True` and
:g:`H0 : O = O` then ``simple apply H in H0`` does not succeed because it
- would require the conversion of :g:`id ?1234` and :g:`O` where :g:`?1234` is
- a variable to instantiate. Tactic :n:`simple apply @term in @ident` does not
+ would require the conversion of :g:`id ?x` and :g:`O` where :g:`?x` is
+ an existential variable to instantiate. Tactic :n:`simple apply @term in @ident` does not
either traverse tuples as :n:`apply @term in @ident` does.
.. tacv:: {? simple} apply {+, @term {? with @bindings_list}} in @ident {? as @intro_pattern}
.. tacv:: {? simple} eapply {+, @term {? with @bindings_list}} in @ident {? as @intro_pattern}
- This summarizes the different syntactic variants of :n:`apply @term in
- @ident` and :n:`eapply @term in @ident`.
+ This summarizes the different syntactic variants of :n:`apply @term in @ident`
+ and :n:`eapply @term in @ident`.
.. tacn:: constructor @num
:name: constructor
@@ -528,8 +530,8 @@ sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
constructor of :g:`I`, then ``constructor i`` is equivalent to
``intros; apply c``:sub:`i`.
-.. exn:: Not an inductive product
-.. exn:: Not enough constructors
+.. exn:: Not an inductive product.
+.. exn:: Not enough constructors.
.. tacv:: constructor
@@ -562,7 +564,7 @@ sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
to :n:`intros; constructor 1 with @bindings_list.` It is typically used in
the case of an existential quantification :math:`\exists`:g:`x, P(x).`
-.. exn:: Not an inductive goal with 1 constructor
+.. exn:: Not an inductive goal with 1 constructor.
.. tacv:: exists @bindings_list
@@ -579,7 +581,7 @@ sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
Then, they are respectively equivalent to ``constructor 1`` and
``constructor 2``.
-.. exn:: Not an inductive goal with 2 constructors
+.. exn:: Not an inductive goal with 2 constructors.
.. tacv:: left with @bindings_list
.. tacv:: right with @bindings_list
@@ -624,17 +626,21 @@ binder. If the goal is a product, the tactic implements the "Lam" rule given in
:ref:`Typing-rules` [1]_. If the goal starts with a let binder, then the
tactic implements a mix of the "Let" and "Conv".
-If the current goal is a dependent product :math:`\forall` :g:`x:T, U` (resp
+If the current goal is a dependent product :g:`forall x:T, U` (resp
:g:`let x:=t in U`) then ``intro`` puts :g:`x:T` (resp :g:`x:=t`) in the local
context. The new subgoal is :g:`U`.
If the goal is a non-dependent product :g:`T`:math:`\rightarrow`:g:`U`, then it
puts in the local context either :g:`Hn:T` (if :g:`T` is of type :g:`Set` or
-:g:`Prop`) or Xn:T (if the type of :g:`T` is :g:`Type`). The optional index
+:g:`Prop`) or :g:`Xn:T` (if the type of :g:`T` is :g:`Type`). The optional index
``n`` is such that ``Hn`` or ``Xn`` is a fresh identifier. In both cases, the
new subgoal is :g:`U`.
-If the goal is neither a product nor starting with a let definition,
+If the goal is an existential variable, ``intro`` forces the resolution of the
+existential variable into a dependent product :math:`forall`:g:`x:?X, ?Y`, puts
+:g:`x:?X` in the local context and leaves :g:`?Y` as a new subgoal allowed to
+depend on :g:`x`.
+
the tactic ``intro`` applies the tactic ``hnf`` until the tactic ``intro`` can
be applied or the goal is not head-reducible.
@@ -642,16 +648,17 @@ be applied or the goal is not head-reducible.
.. exn:: @ident is already used.
.. tacv:: intros
+ :name: intros
This repeats ``intro`` until it meets the head-constant. It never
reduces head-constants and it never fails.
-.. tac:: intro @ident
+.. tacn:: intro @ident
This applies ``intro`` but forces :n:`@ident` to be the name of the
introduced hypothesis.
-.. exn:: name @ident is already used
+.. exn:: Name @ident is already used.
.. note:: If a name used by intro hides the base name of a global
constant then the latter can still be referred to by a qualified name
@@ -670,7 +677,7 @@ be applied or the goal is not head-reducible.
`(@ident:term)` and discharges the variable named `ident` of the current
goal.
-.. exn:: No such hypothesis in current goal
+.. exn:: No such hypothesis in current goal.
.. tacv:: intros until @num
@@ -699,7 +706,7 @@ be applied or the goal is not head-reducible.
too so as to respect the order of dependencies between hypotheses.
Note that :n:`intro at bottom` is a synonym for :n:`intro` with no argument.
-.. exn:: No such hypothesis : @ident.
+.. exn:: No such hypothesis: @ident.
.. tacv:: intro @ident after @ident
.. tacv:: intro @ident before @ident
@@ -708,7 +715,7 @@ be applied or the goal is not head-reducible.
These tactics behave as previously but naming the introduced hypothesis
:n:`@ident`. It is equivalent to :n:`intro @ident` followed by the
- appropriate call to move (see :tacn:`move ... after`).
+ appropriate call to ``move`` (see :tacn:`move ... after ...`).
.. tacn:: intros @intro_pattern_list
:name: intros ...
@@ -753,7 +760,7 @@ be applied or the goal is not head-reducible.
Assuming a goal of type :g:`Q → P` (non-dependent product), or of type
- :math:`\forall`:g:`x:T, P` (dependent product), the behavior of
+ :g:`forall x:T, P` (dependent product), the behavior of
:n:`intros p` is defined inductively over the structure of the introduction
pattern :n:`p`:
@@ -878,7 +885,7 @@ quantification or an implication.
This tactic expects :n:`@ident` to be a local definition then clears its
body. Otherwise said, this tactic turns a definition into an assumption.
-.. exn:: @ident is not a local definition
+.. exn:: @ident is not a local definition.
.. tacv:: clear - {+ @ident}
@@ -897,21 +904,21 @@ quantification or an implication.
.. tacn:: revert {+ @ident}
:name: revert
-This applies to any goal with variables :n:`{+ @ident}`. It moves the hypotheses
-(possibly defined) to the goal, if this respects dependencies. This tactic is
-the inverse of :tacn:`intro`.
+ This applies to any goal with variables :n:`{+ @ident}`. It moves the hypotheses
+ (possibly defined) to the goal, if this respects dependencies. This tactic is
+ the inverse of :tacn:`intro`.
.. exn:: No such hypothesis.
.. exn:: @ident is used in the hypothesis @ident.
-.. tac:: revert dependent @ident
+.. tacn:: revert dependent @ident
This moves to the goal the hypothesis :n:`@ident` and all the hypotheses that
depend on it.
.. tacn:: move @ident after @ident
- :name: move .. after ...
+ :name: move ... after ...
This moves the hypothesis named :n:`@ident` in the local context after the
hypothesis named :n:`@ident`, where “after” is in reference to the
@@ -945,9 +952,9 @@ the inverse of :tacn:`intro`.
This moves ident at the bottom of the local context (at the end of the
context).
-.. exn:: No such hypothesis
-.. exn:: Cannot move @ident after @ident : it occurs in the type of @ident
-.. exn:: Cannot move @ident after @ident : it depends on @ident
+.. exn:: No such hypothesis.
+.. exn:: Cannot move @ident after @ident : it occurs in the type of @ident.
+.. exn:: Cannot move @ident after @ident : it depends on @ident.
.. example::
.. coqtop:: all
@@ -974,8 +981,8 @@ The name of the hypothesis in the proof-term, however, is left unchanged.
particular, the target identifiers may contain identifiers that exist in the
source context, as long as the latter are also renamed by the same tactic.
-.. exn:: No such hypothesis
-.. exn:: @ident is already used
+.. exn:: No such hypothesis.
+.. exn:: @ident is already used.
.. tacn:: set (@ident := @term)
:name: set
@@ -987,7 +994,7 @@ The name of the hypothesis in the proof-term, however, is left unchanged.
first checks that all subterms matching the pattern are compatible before
doing the replacement using the leftmost subterm matching the pattern.
-.. exn:: The variable @ident is already defined
+.. exn:: The variable @ident is already defined.
.. tacv:: set (@ident := @term ) in @goal_occurrences
@@ -1105,7 +1112,7 @@ Controlling the proof flow
:g:`U` [2]_. The subgoal :g:`U` comes first in the list of subgoals remaining to
prove.
-.. exn:: Not a proposition or a type
+.. exn:: Not a proposition or a type.
Arises when the argument form is neither of type :g:`Prop`, :g:`Set` nor
:g:`Type`.
@@ -1115,15 +1122,15 @@ Controlling the proof flow
This behaves as :n:`assert (@ident : form)` but :n:`@ident` is generated by
Coq.
-.. tacv:: assert form by tactic
+.. tacv:: assert @form by @tactic
This tactic behaves like :n:`assert` but applies tactic to solve the subgoals
generated by assert.
- .. exn:: Proof is not complete
- :name: Proof is not complete (assert)
+ .. exn:: Proof is not complete.
+ :name: Proof is not complete. (assert)
-.. tacv:: assert form as intro_pattern
+.. tacv:: assert @form as @intro_pattern
If :n:`intro_pattern` is a naming introduction pattern (see :tacn:`intro`),
the hypothesis is named after this introduction pattern (in particular, if
@@ -1132,7 +1139,7 @@ Controlling the proof flow
introduction pattern, the tactic behaves like :n:`assert form` followed by
the action done by this introduction pattern.
-.. tacv:: assert form as intro_pattern by tactic
+.. tacv:: assert @form as @intro_pattern by @tactic
This combines the two previous variants of :n:`assert`.
@@ -1142,7 +1149,7 @@ Controlling the proof flow
the type of :g:`term`. This is deprecated in favor of :n:`pose proof`. If the
head of term is :n:`@ident`, the tactic behaves as :n:`specialize @term`.
- .. exn:: Variable @ident is already declared
+ .. exn:: Variable @ident is already declared.
.. tacv:: eassert form as intro_pattern by tactic
:name: eassert
@@ -1185,9 +1192,9 @@ Controlling the proof flow
This behaves like :n:`enough form` using :n:`intro_pattern` to name or
destruct the new hypothesis.
-.. tacv:: enough (@ident : form) by tactic
-.. tacv:: enough form by tactic
-.. tacv:: enough form as intro_pattern by tactic
+.. tacv:: enough (@ident : @form) by @tactic
+.. tacv:: enough @form by @tactic
+.. tacv:: enough @form as @intro_pattern by @tactic
This behaves as above but with :n:`tactic` expected to solve the initial goal
after the extra assumption :n:`form` is added and possibly destructed. If the
@@ -1234,8 +1241,8 @@ Controlling the proof flow
the goal. The :n:`as` clause is especially useful in this case to immediately
introduce the instantiated statement as a local hypothesis.
- .. exn:: @ident is used in hypothesis @ident
- .. exn:: @ident is used in conclusion
+ .. exn:: @ident is used in hypothesis @ident.
+ .. exn:: @ident is used in conclusion.
.. tacn:: generalize @term
:name: generalize
@@ -1359,7 +1366,7 @@ goals cannot be closed with :g:`Qed` but only with :g:`Admitted`.
a singleton inductive type (e.g. :g:`True` or :g:`x=x`), or two contradictory
hypotheses.
-.. exn:: No such assumption
+.. exn:: No such assumption.
.. tacv:: contradiction @ident
@@ -1565,9 +1572,9 @@ analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`)
intros n H.
induction n.
-.. exn:: Not an inductive product
+.. exn:: Not an inductive product.
-.. exn:: Unable to find an instance for the variables @ident ... @ident
+.. exn:: Unable to find an instance for the variables @ident ... @ident.
Use in this case the variant :tacn:`elim ... with` below.
@@ -1841,8 +1848,8 @@ See also: :ref:`advanced-recursive-functions`
:ref:`functional-scheme`
:tacn:`inversion`
-.. exn:: Cannot find induction information on @qualid
-.. exn:: Not the right number of induction arguments
+.. exn:: Cannot find induction information on @qualid.
+.. exn:: Not the right number of induction arguments.
.. tacv:: functional induction (@qualid {+ @term}) as @disj_conj_intro_pattern using @term with @bindings_list
@@ -1875,8 +1882,8 @@ See also: :ref:`advanced-recursive-functions`
:n:`@ident` is first introduced in the local context using
:n:`intros until @ident`.
-.. exn:: No primitive equality found
-.. exn:: Not a discriminable equality
+.. exn:: No primitive equality found.
+.. exn:: Not a discriminable equality.
.. tacv:: discriminate @num
@@ -1904,7 +1911,7 @@ See also: :ref:`advanced-recursive-functions`
the form :n:`@term <> @term`, this behaves as
:n:`intro @ident; discriminate @ident`.
- .. exn:: No discriminable equalities
+ .. exn:: No discriminable equalities.
.. tacn:: injection @term
:name: injection
@@ -1915,7 +1922,7 @@ See also: :ref:`advanced-recursive-functions`
:g:`t`:sub:`1` and :g:`t`:sub:`2` are equal too.
If :n:`@term` is a proof of a statement of conclusion :n:`@term = @term`,
- then ``injection`` applies the injectivity of constructors as deep as
+ then :tacn:`injection` applies the injectivity of constructors as deep as
possible to derive the equality of all the subterms of :n:`@term` and
:n:`@term` at positions where the terms start to differ. For example, from
:g:`(S p, S n) = (q, S (S m))` we may derive :g:`S p = q` and
@@ -1925,93 +1932,96 @@ See also: :ref:`advanced-recursive-functions`
equality of all the subterms at positions where they differ and adds them as
antecedents to the conclusion of the current goal.
-.. example::
+ .. example::
- Consider the following goal:
+ Consider the following goal:
- .. coqtop:: reset all
+ .. coqtop:: in
- Inductive list : Set :=
- | nil : list
- | cons : nat -> list -> list.
- Variable P : list -> Prop.
- Goal forall l n, P nil -> cons n l = cons 0 nil -> P l.
- intros.
- injection H0.
+ Inductive list : Set :=
+ | nil : list
+ | cons : nat -> list -> list.
+ Parameter P : list -> Prop.
+ Goal forall l n, P nil -> cons n l = cons 0 nil -> P l.
+ .. coqtop:: all
-Beware that injection yields an equality in a sigma type whenever the
-injected object has a dependent type :g:`P` with its two instances in
-different types :g:`(P t`:sub:`1` :g:`... t`:sub:`n` :g:`)` and
-:g:`(P u`:sub:`1` :g:`... u`:sub:`n` :sub:`)`. If :g:`t`:sub:`1` and
-:g:`u`:sub:`1` are the same and have for type an inductive type for which a decidable
-equality has been declared using the command ``Scheme Equality`` (see :ref:`proofschemes-induction-principles`),
-the use of a sigma type is avoided.
+ intros.
+ injection H0.
-.. note::
- If some quantified hypothesis of the goal is named :n:`@ident`,
- then :n:`injection @ident` first introduces the hypothesis in the local
- context using :n:`intros until @ident`.
+ Beware that injection yields an equality in a sigma type whenever the
+ injected object has a dependent type :g:`P` with its two instances in
+ different types :g:`(P t`:sub:`1` :g:`... t`:sub:`n` :g:`)` and
+ :g:`(P u`:sub:`1` :g:`... u`:sub:`n` :sub:`)`. If :g:`t`:sub:`1` and
+ :g:`u`:sub:`1` are the same and have for type an inductive type for which a decidable
+ equality has been declared using the command :cmd:`Scheme Equality`
+ (see :ref:`proofschemes-induction-principles`),
+ the use of a sigma type is avoided.
-.. exn:: Not a projectable equality but a discriminable one
-.. exn:: Nothing to do, it is an equality between convertible @terms
-.. exn:: Not a primitive equality
-.. exn:: Nothing to inject
+ .. note::
+ If some quantified hypothesis of the goal is named :n:`@ident`,
+ then :n:`injection @ident` first introduces the hypothesis in the local
+ context using :n:`intros until @ident`.
-.. tacv:: injection @num
+ .. exn:: Not a projectable equality but a discriminable one.
+ .. exn:: Nothing to do, it is an equality between convertible @terms.
+ .. exn:: Not a primitive equality.
+ .. exn:: Nothing to inject.
- This does the same thing as :n:`intros until @num` followed by
- :n:`injection @ident` where :n:`@ident` is the identifier for the last
- introduced hypothesis.
+ .. tacv:: injection @num
-.. tacv:: injection @term with @bindings_list
+ This does the same thing as :n:`intros until @num` followed by
+ :n:`injection @ident` where :n:`@ident` is the identifier for the last
+ introduced hypothesis.
- This does the same as :n:`injection @term` but using the given bindings to
- instantiate parameters or hypotheses of :n:`@term`.
+ .. tacv:: injection @term with @bindings_list
-.. tacv:: einjection @num
-.. tacv:: einjection @term {? with @bindings_list}
- :name: einjection
+ This does the same as :n:`injection @term` but using the given bindings to
+ instantiate parameters or hypotheses of :n:`@term`.
- This works the same as :n:`injection` but if the type of :n:`@term`, or the
- type of the hypothesis referred to by :n:`@num`, has uninstantiated
- parameters, these parameters are left as existential variables.
+ .. tacv:: einjection @num
+ :name: einjection
+ .. tacv:: einjection @term {? with @bindings_list}
-.. tacv:: injection
+ This works the same as :n:`injection` but if the type of :n:`@term`, or the
+ type of the hypothesis referred to by :n:`@num`, has uninstantiated
+ parameters, these parameters are left as existential variables.
- If the current goal is of the form :n:`@term <> @term` , this behaves as
- :n:`intro @ident; injection @ident`.
+ .. tacv:: injection
- .. exn:: goal does not satisfy the expected preconditions
+ If the current goal is of the form :n:`@term <> @term` , this behaves as
+ :n:`intro @ident; injection @ident`.
-.. tacv:: injection @term {? with @bindings_list} as {+ @intro_pattern}
-.. tacv:: injection @num as {+ intro_pattern}
-.. tacv:: injection as {+ intro_pattern}
-.. tacv:: einjection @term {? with @bindings_list} as {+ intro_pattern}
-.. tacv:: einjection @num as {+ intro_pattern}
-.. tacv:: einjection as {+ intro_pattern}
+ .. exn:: goal does not satisfy the expected preconditions.
+
+ .. tacv:: injection @term {? with @bindings_list} as {+ @intro_pattern}
+ .. tacv:: injection @num as {+ intro_pattern}
+ .. tacv:: injection as {+ intro_pattern}
+ .. tacv:: einjection @term {? with @bindings_list} as {+ intro_pattern}
+ .. tacv:: einjection @num as {+ intro_pattern}
+ .. tacv:: einjection as {+ intro_pattern}
These variants apply :n:`intros {+ @intro_pattern}` after the call to
- ``injection`` or ``einjection`` so that all equalities generated are moved in
+ :tacn:`injection` or :tacn:`einjection` so that all equalities generated are moved in
the context of hypotheses. The number of :n:`@intro_pattern` must not exceed
the number of equalities newly generated. If it is smaller, fresh
names are automatically generated to adjust the list of :n:`@intro_pattern`
to the number of new equalities. The original equality is erased if it
corresponds to an hypothesis.
-.. opt:: Structural Injection
+ .. opt:: Structural Injection
- This option ensure that :n:`injection @term` erases the original hypothesis
- and leaves the generated equalities in the context rather than putting them
- as antecedents of the current goal, as if giving :n:`injection @term as`
- (with an empty list of names). This option is off by default.
+ This option ensure that :n:`injection @term` erases the original hypothesis
+ and leaves the generated equalities in the context rather than putting them
+ as antecedents of the current goal, as if giving :n:`injection @term as`
+ (with an empty list of names). This option is off by default.
-.. opt:: Keep Proof Equalities
+ .. opt:: Keep Proof Equalities
- By default, :tacn:`injection` only creates new equalities between :n:`@terms`
- whose type is in sort :g:`Type` or :g:`Set`, thus implementing a special
- behavior for objects that are proofs of a statement in :g:`Prop`. This option
- controls this behavior.
+ By default, :tacn:`injection` only creates new equalities between :n:`@terms`
+ whose type is in sort :g:`Type` or :g:`Set`, thus implementing a special
+ behavior for objects that are proofs of a statement in :g:`Prop`. This option
+ controls this behavior.
.. tacn:: inversion @ident
:name: inversion
@@ -2139,13 +2149,13 @@ the use of a sigma type is avoided.
:n:`dependent inversion_clear @ident`.
.. tacv:: dependent inversion @ident with @term
- :name: dependent inversion ...
+ :name: dependent inversion ... with ...
This variant allows you to specify the generalization of the goal. It is
useful when the system fails to generalize the goal automatically. If
- :n:`@ident` has type :g:`(I t)` and :g:`I` has type :math:`\forall`
- :g:`(x:T), s`, then :n:`@term` must be of type :g:`I:`:math:`\forall`
- :g:`(x:T), I x -> s'` where :g:`s'` is the type of the goal.
+ :n:`@ident` has type :g:`(I t)` and :g:`I` has type :g:`forall (x:T), s`,
+ then :n:`@term` must be of type :g:`I:forall (x:T), I x -> s'` where
+ :g:`s'` is the type of the goal.
.. tacv:: dependent inversion @ident as @intro_pattern with @term
@@ -2154,7 +2164,7 @@ the use of a sigma type is avoided.
.. tacv:: dependent inversion_clear @ident with @term
- Like :tacn:`dependent inversion ...` with but clears :n:`@ident` from the
+ Like :tacn:`dependent inversion ... with ...` with but clears :n:`@ident` from the
local context.
.. tacv:: dependent inversion_clear @ident as @intro_pattern with @term
@@ -2401,7 +2411,7 @@ Hence, some of the variables :g:`x`\ :sub:`i` are solved by unification,
and some of the types :g:`A`\ :sub:`1`:g:`, ..., A`\ :sub:`n` become new
subgoals.
-.. exn:: The @term provided does not end with an equation
+.. exn:: The @term provided does not end with an equation.
.. exn:: Tactic generated a subgoal identical to the original goal. This happens if @term does not occur in the goal.
@@ -2425,8 +2435,8 @@ subgoals.
In particular a failure will happen if any of these three simpler tactics
fails.
+ :n:`rewrite H in * |-` will do :n:`rewrite H in H`:sub:`i` for all hypotheses
- :g:`H`:sub:`i` :g:`<> H`. A success will happen as soon as at least one of these
- simpler tactics succeeds.
+ :g:`H`:sub:`i` different from :g:`H`.
+ A success will happen as soon as at least one of these simpler tactics succeeds.
+ :n:`rewrite H in *` is a combination of :n:`rewrite H` and :n:`rewrite H in * |-`
that succeeds if at least one of these two tactics succeeds.
@@ -2479,7 +2489,7 @@ subgoals.
the assumption, or if its symmetric form occurs. It is equivalent to
:n:`cut @term = @term; [intro H`:sub:`n` :n:`; rewrite <- H`:sub:`n` :n:`; clear H`:sub:`n`:n:`|| assumption || symmetry; try assumption]`.
-.. exn:: @terms do not have convertible types
+.. exn:: @terms do not have convertible types.
.. tacv:: replace @term with @term by tactic
@@ -2624,7 +2634,7 @@ as regular setoids for :tacn:`rewrite` and :tacn:`setoid_replace` (see
with `U` providing that `U` is well-formed and that `T` and `U` are
convertible.
-.. exn:: Not convertible
+.. exn:: Not convertible.
.. tacv:: change @term with @term
@@ -2637,7 +2647,7 @@ as regular setoids for :tacn:`rewrite` and :tacn:`setoid_replace` (see
This replaces the occurrences numbered :n:`{+ @num}` of :n:`@term by @term`
in the current goal. The terms :n:`@term` and :n:`@term` must be convertible.
-.. exn:: Too few occurrences
+.. exn:: Too few occurrences.
.. tacv:: change @term in @ident
.. tacv:: change @term with @term in @ident
@@ -2812,7 +2822,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
definition (say :g:`t`) and then reduces
:g:`(t t`:sub:`1` :g:`... t`:sub:`n` :g:`)` according to :math:`\beta`:math:`\iota`:math:`\zeta`-reduction rules.
-.. exn:: Not reducible
+.. exn:: Not reducible.
.. tacn:: hnf
:name: hnf
@@ -2939,7 +2949,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
This applies ``simpl`` only to the :n:`{+ @num}` occurrences of the subterms
matching :n:`@pattern` in the current goal.
- .. exn:: Too few occurrences
+ .. exn:: Too few occurrences.
.. tacv:: simpl @qualid
.. tacv:: simpl @string
@@ -2969,7 +2979,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
:n:`@qualid` refers in the current goal and then replaces it with its
:math:`\beta`:math:`\iota`-normal form.
-.. exn:: @qualid does not denote an evaluable constant
+.. exn:: @qualid does not denote an evaluable constant.
.. tacv:: unfold @qualid in @ident
@@ -2986,9 +2996,9 @@ the conversion in hypotheses :n:`{+ @ident}`.
The lists :n:`{+, @num}` specify the occurrences of :n:`@qualid` to be
unfolded. Occurrences are located from left to right.
- .. exn:: bad occurrence number of @qualid
+ .. exn:: Bad occurrence number of @qualid.
- .. exn:: @qualid does not occur
+ .. exn:: @qualid does not occur.
.. tacv:: unfold @string
@@ -3078,7 +3088,7 @@ Conversion tactics applied to hypotheses
Example: :n:`unfold not in (Type of H1) (Type of H3)`.
-.. exn:: No such hypothesis : ident.
+.. exn:: No such hypothesis: @ident.
.. _automation:
@@ -3129,6 +3139,7 @@ hints of the database named core.
to know what lemmas/assumptions were used.
.. tacv:: debug auto
+ :name: debug auto
Behaves like :tacn:`auto` but shows the tactics it tries to solve the goal,
including failing paths.
@@ -3148,7 +3159,9 @@ hints of the database named core.
.. tacv:: trivial with *
.. tacv:: trivial using {+ @lemma}
.. tacv:: debug trivial
+ :name: debug trivial
.. tacv:: info_trivial
+ :name: info_trivial
.. tacv:: {? info_}trivial {? using {+ @lemma}} {? with {+ @ident}}
.. note::
@@ -3181,7 +3194,7 @@ can solve such a goal:
Goal forall P:nat -> Prop, P 0 -> exists n, P n.
eauto.
-Note that :tacn:`ex_intro` should be declared as a hint.
+Note that ``ex_intro`` should be declared as a hint.
.. tacv:: {? info_}eauto {? @num} {? using {+ @lemma}} {? with {+ @ident}}
@@ -3227,7 +3240,9 @@ the processing of the rewriting rules.
The rewriting rule bases are built with the ``Hint Rewrite vernacular``
command.
-.. warn:: This tactic may loop if you build non terminating rewriting systems.
+.. warning::
+
+ This tactic may loop if you build non terminating rewriting systems.
.. tacv:: autorewrite with {+ @ident} using @tactic
@@ -3258,7 +3273,8 @@ See also: :tacn:`autorewrite` for examples showing the use of this tactic.
This tactic tries to solve the current goal by a number of standard closing steps.
In particular, it tries to close the current goal using the closing tactics
- :tacn:`trivial`, reflexivity, symmetry, contradiction and inversion of hypothesis.
+ :tacn:`trivial`, :tacn:`reflexivity`, :tacn:`symmetry`, :tacn:`contradiction`
+ and :tacn:`inversion` of hypothesis.
If this fails, it tries introducing variables and splitting and-hypotheses,
using the closing tactics afterwards, and splitting the goal using
:tacn:`split` and recursing.
@@ -3269,7 +3285,7 @@ See also: :tacn:`autorewrite` for examples showing the use of this tactic.
.. tacv:: now @tactic
:name: now
- Run :n:`@tac` followed by ``easy``. This is a notation for :n:`@tactic; easy`.
+ Run :n:`@tactic` followed by :tacn:`easy`. This is a notation for :n:`@tactic; easy`.
Controlling automation
--------------------------
@@ -3279,40 +3295,42 @@ Controlling automation
The hints databases for auto and eauto
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The hints for ``auto`` and ``eauto`` are stored in databases. Each database
-maps head symbols to a list of hints. One can use the command
+The hints for :tacn:`auto` and :tacn:`eauto` are stored in databases. Each database
+maps head symbols to a list of hints.
.. cmd:: Print Hint @ident
-to display the hints associated to the head symbol :n:`@ident`
-(see :ref:`Print Hint <printhint>`). Each hint has a cost that is a nonnegative
-integer, and an optional pattern. The hints with lower cost are tried first. A
-hint is tried by ``auto`` when the conclusion of the current goal matches its
-pattern or when it has no pattern.
+ Use this command
+ to display the hints associated to the head symbol :n:`@ident`
+ (see :ref:`Print Hint <printhint>`). Each hint has a cost that is a nonnegative
+ integer, and an optional pattern. The hints with lower cost are tried first. A
+ hint is tried by :tacn:`auto` when the conclusion of the current goal matches its
+ pattern or when it has no pattern.
Creating Hint databases
```````````````````````
-One can optionally declare a hint database using the command ``Create
-HintDb``. If a hint is added to an unknown database, it will be
+One can optionally declare a hint database using the command
+:cmd:`Create HintDb`. If a hint is added to an unknown database, it will be
automatically created.
-.. cmd:: Create HintDb @ident {? discriminated}.
-
-This command creates a new database named :n:`@ident`. The database is
-implemented by a Discrimination Tree (DT) that serves as an index of
-all the lemmas. The DT can use transparency information to decide if a
-constant should be indexed or not (c.f. :ref:`The hints databases for auto and eauto <thehintsdatabasesforautoandeauto>`),
-making the retrieval more efficient. The legacy implementation (the default one
-for new databases) uses the DT only on goals without existentials (i.e., ``auto``
-goals), for non-Immediate hints and do not make use of transparency
-hints, putting more work on the unification that is run after
-retrieval (it keeps a list of the lemmas in case the DT is not used).
-The new implementation enabled by the discriminated option makes use
-of DTs in all cases and takes transparency information into account.
-However, the order in which hints are retrieved from the DT may differ
-from the order in which they were inserted, making this implementation
-observationally different from the legacy one.
+.. cmd:: Create HintDb @ident {? discriminated}
+
+ This command creates a new database named :n:`@ident`. The database is
+ implemented by a Discrimination Tree (DT) that serves as an index of
+ all the lemmas. The DT can use transparency information to decide if a
+ constant should be indexed or not
+ (c.f. :ref:`The hints databases for auto and eauto <thehintsdatabasesforautoandeauto>`),
+ making the retrieval more efficient. The legacy implementation (the default one
+ for new databases) uses the DT only on goals without existentials (i.e., :tacn:`auto`
+ goals), for non-Immediate hints and do not make use of transparency
+ hints, putting more work on the unification that is run after
+ retrieval (it keeps a list of the lemmas in case the DT is not used).
+ The new implementation enabled by the discriminated option makes use
+ of DTs in all cases and takes transparency information into account.
+ However, the order in which hints are retrieved from the DT may differ
+ from the order in which they were inserted, making this implementation
+ observationally different from the legacy one.
The general command to add a hint to some databases :n:`{+ @ident}` is
@@ -3336,21 +3354,21 @@ The general command to add a hint to some databases :n:`{+ @ident}` is
.. cmdv:: Hint Resolve @term {? | {? @num} {? @pattern}}
:name: Hint Resolve
- This command adds :n:`simple apply @term` to the hint list with the head
- symbol of the type of :n:`@term`. The cost of that hint is the number of
- subgoals generated by :n:`simple apply @term` or :n:`@num` if specified. The
- associated :n:`@pattern` is inferred from the conclusion of the type of
- :n:`@term` or the given :n:`@pattern` if specified. In case the inferred type
- of :n:`@term` does not start with a product the tactic added in the hint list
- is :n:`exact @term`. In case this type can however be reduced to a type
- starting with a product, the tactic :n:`simple apply @term` is also stored in
- the hints list. If the inferred type of :n:`@term` contains a dependent
- quantification on a variable which occurs only in the premisses of the type
- and not in its conclusion, no instance could be inferred for the variable by
- unification with the goal. In this case, the hint is added to the hint list
- of :tacn:`eauto` instead of the hint list of auto and a warning is printed. A
- typical example of a hint that is used only by :tacn:`eauto` is a transitivity
- lemma.
+ This command adds :n:`simple apply @term` to the hint list with the head
+ symbol of the type of :n:`@term`. The cost of that hint is the number of
+ subgoals generated by :n:`simple apply @term` or :n:`@num` if specified. The
+ associated :n:`@pattern` is inferred from the conclusion of the type of
+ :n:`@term` or the given :n:`@pattern` if specified. In case the inferred type
+ of :n:`@term` does not start with a product the tactic added in the hint list
+ is :n:`exact @term`. In case this type can however be reduced to a type
+ starting with a product, the tactic :n:`simple apply @term` is also stored in
+ the hints list. If the inferred type of :n:`@term` contains a dependent
+ quantification on a variable which occurs only in the premisses of the type
+ and not in its conclusion, no instance could be inferred for the variable by
+ unification with the goal. In this case, the hint is added to the hint list
+ of :tacn:`eauto` instead of the hint list of auto and a warning is printed. A
+ typical example of a hint that is used only by :tacn:`eauto` is a transitivity
+ lemma.
.. exn:: @term cannot be used as a hint
@@ -3378,7 +3396,7 @@ The general command to add a hint to some databases :n:`{+ @ident}` is
This command adds :n:`simple apply @term; trivial` to the hint list associated
with the head symbol of the type of :n:`@ident` in the given database. This
tactic will fail if all the subgoals generated by :n:`simple apply @term` are
- not solved immediately by the ``trivial`` tactic (which only tries tactics
+ not solved immediately by the :tacn:`trivial` tactic (which only tries tactics
with cost 0).This command is useful for theorems such as the symmetry of
equality or :g:`n+1=m+1 -> n=m` that we may like to introduce with a limited
use in order to avoid useless proof-search. The cost of this tactic (which
@@ -3416,7 +3434,7 @@ The general command to add a hint to some databases :n:`{+ @ident}` is
Adds each :n:`Hint Unfold @ident`.
.. cmdv:: Hint %( Transparent %| Opaque %) @qualid
- :name: Hint ( Transparent | Opaque )
+ :name: Hint %( Transparent %| Opaque %)
This adds a transparency hint to the database, making :n:`@qualid` a
transparent or opaque constant during resolution. This information is used
@@ -3424,52 +3442,55 @@ The general command to add a hint to some databases :n:`{+ @ident}` is
discrimination network to relax or constrain it in the case of discriminated
databases.
- .. cmdv:: Hint %(Transparent | Opaque) {+ @ident}
+ .. cmdv:: Hint %( Transparent %| Opaque %) {+ @ident}
Declares each :n:`@ident` as a transparent or opaque constant.
- .. cmdv:: Hint Extern @num {? @pattern} => tactic
+ .. cmdv:: Hint Extern @num {? @pattern} => @tactic
+ :name: Hint Extern
- This hint type is to extend :tacn:`auto` with tactics other than :tacn:`apply` and
- :tacn:`unfold`. For that, we must specify a cost, an optional :n:`@pattern` and a
- :n:`@tactic` to execute.
+ This hint type is to extend :tacn:`auto` with tactics other than :tacn:`apply` and
+ :tacn:`unfold`. For that, we must specify a cost, an optional :n:`@pattern` and a
+ :n:`@tactic` to execute.
- .. example::
+ .. example::
- .. coqtop:: in
+ .. coqtop:: in
- Hint Extern 4 (~(_ = _)) => discriminate.
+ Hint Extern 4 (~(_ = _)) => discriminate.
- Now, when the head of the goal is a disequality, ``auto`` will try
- discriminate if it does not manage to solve the goal with hints with a
- cost less than 4. One can even use some sub-patterns of the pattern in
- the tactic script. A sub-pattern is a question mark followed by an
- identifier, like ``?X1`` or ``?X2``. Here is an example:
+ Now, when the head of the goal is a disequality, ``auto`` will try
+ discriminate if it does not manage to solve the goal with hints with a
+ cost less than 4.
- .. example::
+ One can even use some sub-patterns of the pattern in
+ the tactic script. A sub-pattern is a question mark followed by an
+ identifier, like ``?X1`` or ``?X2``. Here is an example:
- .. coqtop:: reset all
+ .. example::
- Require Import List.
- Hint Extern 5 ({?X1 = ?X2} + {?X1 <> ?X2}) => generalize X1, X2; decide equality : eqdec.
- Goal forall a b:list (nat * nat), {a = b} + {a <> b}.
- Info 1 auto with eqdec.
+ .. coqtop:: reset all
- .. cmdv:: Hint Cut @regexp
+ Require Import List.
+ Hint Extern 5 ({?X1 = ?X2} + {?X1 <> ?X2}) => generalize X1, X2; decide equality : eqdec.
+ Goal forall a b:list (nat * nat), {a = b} + {a <> b}.
+ Info 1 auto with eqdec.
- .. warning::
+ .. cmdv:: Hint Cut @regexp
- These hints currently only apply to typeclass proof search and the
- :tacn:`typeclasses eauto` tactic.
+ .. warning::
- This command can be used to cut the proof-search tree according to a regular
- expression matching paths to be cut. The grammar for regular expressions is
- the following. Beware, there is no operator precedence during parsing, one can
- check with :cmd:`Print HintDb` to verify the current cut expression:
+ These hints currently only apply to typeclass proof search and the
+ :tacn:`typeclasses eauto` tactic.
- .. productionlist:: `regexp`
+ This command can be used to cut the proof-search tree according to a regular
+ expression matching paths to be cut. The grammar for regular expressions is
+ the following. Beware, there is no operator precedence during parsing, one can
+ check with :cmd:`Print HintDb` to verify the current cut expression:
+
+ .. productionlist:: `regexp`
e : ident hint or instance identifier
- :|_ any hint
+ :| _ any hint
:| e\|e′ disjunction
:| e e′ sequence
:| e * Kleene star
@@ -3477,42 +3498,42 @@ The general command to add a hint to some databases :n:`{+ @ident}` is
:| eps epsilon
:| ( e )
- The `emp` regexp does not match any search path while `eps`
- matches the empty path. During proof search, the path of
- successive successful hints on a search branch is recorded, as a
- list of identifiers for the hints (note Hint Extern’s do not have
- an associated identifier).
- Before applying any hint :n:`@ident` the current path `p` extended with
- :n:`@ident` is matched against the current cut expression `c` associated to
- the hint database. If matching succeeds, the hint is *not* applied. The
- semantics of ``Hint Cut e`` is to set the cut expression to ``c | e``, the
- initial cut expression being `emp`.
-
- .. cmdv:: Hint Mode @qualid {* (+ | ! | -)}
-
- This sets an optional mode of use of the identifier :n:`@qualid`. When
- proof-search faces a goal that ends in an application of :n:`@qualid` to
- arguments :n:`@term ... @term`, the mode tells if the hints associated to
- :n:`@qualid` can be applied or not. A mode specification is a list of n ``+``,
- ``!`` or ``-`` items that specify if an argument of the identifier is to be
- treated as an input (``+``), if its head only is an input (``!``) or an output
- (``-``) of the identifier. For a mode to match a list of arguments, input
- terms and input heads *must not* contain existential variables or be
- existential variables respectively, while outputs can be any term. Multiple
- modes can be declared for a single identifier, in that case only one mode
- needs to match the arguments for the hints to be applied.The head of a term
- is understood here as the applicative head, or the match or projection
- scrutinee’s head, recursively, casts being ignored. ``Hint Mode`` is
- especially useful for typeclasses, when one does not want to support default
- instances and avoid ambiguity in general. Setting a parameter of a class as an
- input forces proof-search to be driven by that index of the class, with ``!``
- giving more flexibility by allowing existentials to still appear deeper in the
- index but not at its head.
-
- .. note::
-
- One can use an ``Extern`` hint with no pattern to do pattern-matching on
- hypotheses using ``match goal`` with inside the tactic.
+ The `emp` regexp does not match any search path while `eps`
+ matches the empty path. During proof search, the path of
+ successive successful hints on a search branch is recorded, as a
+ list of identifiers for the hints (note Hint Extern’s do not have
+ an associated identifier).
+ Before applying any hint :n:`@ident` the current path `p` extended with
+ :n:`@ident` is matched against the current cut expression `c` associated to
+ the hint database. If matching succeeds, the hint is *not* applied. The
+ semantics of ``Hint Cut e`` is to set the cut expression to ``c | e``, the
+ initial cut expression being `emp`.
+
+ .. cmdv:: Hint Mode @qualid {* (+ | ! | -)}
+
+ This sets an optional mode of use of the identifier :n:`@qualid`. When
+ proof-search faces a goal that ends in an application of :n:`@qualid` to
+ arguments :n:`@term ... @term`, the mode tells if the hints associated to
+ :n:`@qualid` can be applied or not. A mode specification is a list of n ``+``,
+ ``!`` or ``-`` items that specify if an argument of the identifier is to be
+ treated as an input (``+``), if its head only is an input (``!``) or an output
+ (``-``) of the identifier. For a mode to match a list of arguments, input
+ terms and input heads *must not* contain existential variables or be
+ existential variables respectively, while outputs can be any term. Multiple
+ modes can be declared for a single identifier, in that case only one mode
+ needs to match the arguments for the hints to be applied.The head of a term
+ is understood here as the applicative head, or the match or projection
+ scrutinee’s head, recursively, casts being ignored. ``Hint Mode`` is
+ especially useful for typeclasses, when one does not want to support default
+ instances and avoid ambiguity in general. Setting a parameter of a class as an
+ input forces proof-search to be driven by that index of the class, with ``!``
+ giving more flexibility by allowing existentials to still appear deeper in the
+ index but not at its head.
+
+ .. note::
+
+ One can use an ``Extern`` hint with no pattern to do pattern-matching on
+ hypotheses using ``match goal`` with inside the tactic.
Hint databases defined in the Coq standard library
@@ -3634,7 +3655,7 @@ described above: either they disappear at the end of a section scope,
or they remain global forever. This causes a scalability issue,
because hints coming from an unrelated part of the code may badly
influence another development. It can be mitigated to some extent
-thanks to the ``Remove Hints`` command (see :ref:`Remove Hints <removehints>`),
+thanks to the :cmd:`Remove Hints` command,
but this is a mere workaround and has some limitations (for instance, external
hints cannot be removed).
@@ -3642,11 +3663,12 @@ A proper way to fix this issue is to bind the hints to their module scope, as
for most of the other objects Coq uses. Hints should only made available when
the module they are defined in is imported, not just required. It is very
difficult to change the historical behavior, as it would break a lot of scripts.
-We propose a smooth transitional path by providing the ``Loose Hint Behavior``
+We propose a smooth transitional path by providing the :opt:`Loose Hint Behavior`
option which accepts three flags allowing for a fine-grained handling of
non-imported hints.
.. opt:: Loose Hint Behavior %( "Lax" %| "Warn" %| "Strict" %)
+ :name: Loose Hint Behavior
This option accepts three values, which control the behavior of hints w.r.t.
:cmd:`Import`:
@@ -3791,14 +3813,15 @@ some incompatibilities.
.. tacv:: intuition
- Is equivalent to :g:`intuition auto with *`.
+ Is equivalent to :g:`intuition auto with *`.
.. tacv:: dintuition
+ :name: dintuition
- While :tacn:`intuition` recognizes inductively defined connectives
- isomorphic to the standard connective ``and, prod, or, sum, False,
- Empty_set, unit, True``, :tacn:`dintuition` recognizes also all inductive
- types with one constructors and no indices, i.e. record-style connectives.
+ While :tacn:`intuition` recognizes inductively defined connectives
+ isomorphic to the standard connective ``and``, ``prod``, ``or``, ``sum``, ``False``,
+ ``Empty_set``, ``unit``, ``True``, :tacn:`dintuition` recognizes also all inductive
+ types with one constructors and no indices, i.e. record-style connectives.
.. opt:: Intuition Negation Unfolding
@@ -3827,11 +3850,14 @@ first- order reasoning, written by Pierre Corbineau. It is not restricted to
usual logical connectives but instead may reason about any first-order class
inductive definition.
-.. opt:: Firstorder Solver
+.. opt:: Firstorder Solver @tactic
The default tactic used by :tacn:`firstorder` when no rule applies is
- :g:`auto with *`, it can be reset locally or globally using this option and
- printed using :cmd:`Print Firstorder Solver`.
+ :g:`auto with *`, it can be reset locally or globally using this option.
+
+ .. cmd:: Print Firstorder Solver
+
+ Prints the default tactic used by :tacn:`firstorder` when no rule applies.
.. tacv:: firstorder @tactic
@@ -3852,7 +3878,7 @@ inductive definition.
This combines the effects of the different variants of :tacn:`firstorder`.
-.. opt:: Firstorder Depth @natural
+.. opt:: Firstorder Depth @num
This option controls the proof-search depth bound.
@@ -3895,11 +3921,12 @@ match against it.
hypotheses using assert in order for :tacn:`congruence` to use them.
.. tacv:: congruence with {+ @term}
+ :name: congruence with
- Adds :n:`{+ @term}` to the pool of terms used by :tacn:`congruence`. This helps
- in case you have partially applied constructors in your goal.
+ Adds :n:`{+ @term}` to the pool of terms used by :tacn:`congruence`. This helps
+ in case you have partially applied constructors in your goal.
-.. exn:: I don’t know how to handle dependent equality
+.. exn:: I don’t know how to handle dependent equality.
The decision procedure managed to find a proof of the goal or of a
discriminable equality but this proof could not be built in Coq because of
@@ -3911,7 +3938,7 @@ match against it.
arguments are supplied for some partially applied constructors. Any term of an
appropriate type will allow the tactic to successfully solve the goal. Those
additional arguments can be given to congruence by filling in the holes in the
- terms given in the error message, using the with variant described above.
+ terms given in the error message, using the :tacn:`congruence with` variant described above.
.. opt:: Congruence Verbose
@@ -3930,7 +3957,7 @@ succeeds, and results in an error otherwise.
This tactic checks whether its arguments are equal modulo alpha
conversion and casts.
-.. exn:: Not equal
+.. exn:: Not equal.
.. tacn:: unify @term @term
:name: unify
@@ -3938,7 +3965,7 @@ succeeds, and results in an error otherwise.
This tactic checks whether its arguments are unifiable, potentially
instantiating existential variables.
-.. exn:: Not unifiable
+.. exn:: Not unifiable.
.. tacv:: unify @term @term with @ident
@@ -3952,7 +3979,7 @@ succeeds, and results in an error otherwise.
variable. Existential variables are uninstantiated variables generated
by :tacn:`eapply` and some other tactics.
-.. exn:: Not an evar
+.. exn:: Not an evar.
.. tacn:: has_evar @term
:name: has_evar
@@ -3961,7 +3988,7 @@ succeeds, and results in an error otherwise.
a subterm. Unlike context patterns combined with ``is_evar``, this tactic
scans all subterms, including those under binders.
-.. exn:: No evars
+.. exn:: No evars.
.. tacn:: is_var @term
:name: is_var
@@ -3969,7 +3996,7 @@ succeeds, and results in an error otherwise.
This tactic checks whether its argument is a variable or hypothesis in
the current goal context or in the opened sections.
-.. exn:: Not a variable or hypothesis
+.. exn:: Not a variable or hypothesis.
.. _equality:
@@ -3993,10 +4020,10 @@ solved by :tacn:`f_equal`.
:name: reflexivity
This tactic applies to a goal that has the form :g:`t=u`. It checks that `t`
-and `u` are convertible and then solves the goal. It is equivalent to apply
-:tacn:`refl_equal`.
+and `u` are convertible and then solves the goal. It is equivalent to
+``apply refl_equal``.
-.. exn:: The conclusion is not a substitutive equation
+.. exn:: The conclusion is not a substitutive equation.
.. exn:: Unable to unify ... with ...
@@ -4086,7 +4113,7 @@ symbol :g:`=`.
:n:`intro @ident; simplify_eq @ident`.
.. tacn:: dependent rewrite -> @ident
- :name: dependent rewrite
+ :name: dependent rewrite ->
This tactic applies to any goal. If :n:`@ident` has type
:g:`(existT B a b)=(existT B a' b')` in the local context (i.e. each
@@ -4097,6 +4124,7 @@ symbol :g:`=`.
:tacn:`injection` and :tacn:`inversion` tactics.
.. tacv:: dependent rewrite <- @ident
+ :name: dependent rewrite <-
Analogous to :tacn:`dependent rewrite ->` but uses the equality from right to
left.
@@ -4114,8 +4142,8 @@ Inversion
available after a ``Require Import FunInd``.
-.. exn:: Hypothesis @ident must contain at least one Function
-.. exn:: Cannot find inversion information for hypothesis @ident
+.. exn:: Hypothesis @ident must contain at least one Function.
+.. exn:: Cannot find inversion information for hypothesis @ident.
This error may be raised when some inversion lemma failed to be generated by
Function.
@@ -4146,7 +4174,7 @@ function :n:`@ident`. This function must be a fixpoint on a simple recursive
datatype: see :ref:`quote` for the full details.
-.. exn:: quote: not a simple fixpoint
+.. exn:: quote: not a simple fixpoint.
Happens when quote is not able to perform inversion properly.
@@ -4356,19 +4384,20 @@ This tactics reverses the list of the focused goals.
unification, or they can be called back into focus with the command
:cmd:`Unshelve`.
-.. tacv:: shelve_unifiable
+ .. tacv:: shelve_unifiable
+ :name: shelve_unifiable
- Shelves only the goals under focus that are mentioned in other goals.
- Goals that appear in the type of other goals can be solved by unification.
+ Shelves only the goals under focus that are mentioned in other goals.
+ Goals that appear in the type of other goals can be solved by unification.
-.. example::
+ .. example::
- .. coqtop:: all reset
+ .. coqtop:: all reset
- Goal exists n, n=0.
- refine (ex_intro _ _ _).
- all:shelve_unifiable.
- reflexivity.
+ Goal exists n, n=0.
+ refine (ex_intro _ _ _).
+ all: shelve_unifiable.
+ reflexivity.
.. cmd:: Unshelve
diff --git a/doc/sphinx/proof-engine/vernacular-commands.rst b/doc/sphinx/proof-engine/vernacular-commands.rst
index 692ff294a..c37233734 100644
--- a/doc/sphinx/proof-engine/vernacular-commands.rst
+++ b/doc/sphinx/proof-engine/vernacular-commands.rst
@@ -14,64 +14,63 @@ Displaying
.. _Print:
-.. cmd:: Print @qualid.
+.. cmd:: Print @qualid
+ :name: Print
-This command displays on the screen information about the declared or
-defined object referred by :n:`@qualid`.
+ This command displays on the screen information about the declared or
+ defined object referred by :n:`@qualid`.
+ Error messages:
-Error messages:
+ .. exn:: @qualid not a defined object.
+ .. exn:: Universe instance should have length @num.
-.. exn:: @qualid not a defined object
+ .. exn:: This object does not support universe names.
-.. exn:: Universe instance should have length :n:`num`.
-.. exn:: This object does not support universe names.
+ .. cmdv:: Print Term @qualid
+ :name: Print Term
+ This is a synonym of :cmd:`Print` :n:`@qualid` when :n:`@qualid`
+ denotes a global constant.
-Variants:
+ .. cmdv:: Print {? Term } @qualid\@@name
+ This locally renames the polymorphic universes of :n:`@qualid`.
+ An underscore means the raw universe is printed.
-.. cmdv:: Print Term @qualid.
-This is a synonym to ``Print`` :n:`@qualid` when :n:`@qualid`
-denotes a global constant.
-
-.. cmdv:: About @qualid.
+.. cmd:: About @qualid
:name: About
-This displays various information about the object
-denoted by :n:`@qualid`: its kind (module, constant, assumption, inductive,
-constructor, abbreviation, …), long name, type, implicit arguments and
-argument scopes. It does not print the body of definitions or proofs.
-
-.. cmdv:: Print @qualid\@@name
+ This displays various information about the object
+ denoted by :n:`@qualid`: its kind (module, constant, assumption, inductive,
+ constructor, abbreviation, …), long name, type, implicit arguments and
+ argument scopes. It does not print the body of definitions or proofs.
-This locally renames the polymorphic universes of :n:`@qualid`.
-An underscore means the raw universe is printed.
-This form can be used with ``Print Term`` and ``About``.
+ .. cmdv:: About @qualid\@@name
-.. cmd:: Print All.
+ This locally renames the polymorphic universes of :n:`@qualid`.
+ An underscore means the raw universe is printed.
-This command displays information about the current state of the
-environment, including sections and modules.
+.. cmd:: Print All
-Variants:
+ This command displays information about the current state of the
+ environment, including sections and modules.
+ .. cmdv:: Inspect @num
+ :name: Inspect
-.. cmdv:: Inspect @num.
- :name: Inspect
+ This command displays the :n:`@num` last objects of the
+ current environment, including sections and modules.
-This command displays the :n:`@num` last objects of the
-current environment, including sections and modules.
+ .. cmdv:: Print Section @ident
-.. cmdv:: Print Section @ident.
-
-The name :n:`@ident` should correspond to a currently open section,
-this command displays the objects defined since the beginning of this
-section.
+ The name :n:`@ident` should correspond to a currently open section,
+ this command displays the objects defined since the beginning of this
+ section.
.. _flags-options-tables:
@@ -87,151 +86,136 @@ handling flags, options and tables are given below.
.. TODO : flag is not a syntax entry
-.. cmd:: Set @flag.
-
-This command switches :n:`@flag` on. The original state of :n:`@flag` is restored
-when the current module ends.
-
-Variants:
-
-.. cmdv:: Local Set @flag.
-
-This command switches :n:`@flag` on. The original state
-of :n:`@flag` is restored when the current *section* ends.
+.. cmd:: Set @flag
-.. cmdv:: Global Set @flag.
+ This command switches :n:`@flag` on. The original state of :n:`@flag`
+ is restored when the current module ends.
-This command switches :n:`@flag` on. The original state
-of :n:`@flag` is *not* restored at the end of the module. Additionally, if
-set in a file, :n:`@flag` is switched on when the file is `Require`-d.
+ .. cmdv:: Local Set @flag
-.. cmdv:: Export Set @flag.
+ This command switches :n:`@flag` on. The original state
+ of :n:`@flag` is restored when the current *section* ends.
- This command switches :n:`@flag` on. The original state
- of :n:`@flag` is restored at the end of the current module, but :n:`@flag`
- is switched on when this module is imported.
+ .. cmdv:: Global Set @flag
+ This command switches :n:`@flag` on. The original state
+ of :n:`@flag` is *not* restored at the end of the module. Additionally, if
+ set in a file, :n:`@flag` is switched on when the file is `Require`-d.
-.. cmd:: Unset @flag.
+ .. cmdv:: Export Set @flag
-This command switches :n:`@flag` off. The original state of :n:`@flag` is restored
-when the current module ends.
+ This command switches :n:`@flag` on. The original state
+ of :n:`@flag` is restored at the end of the current module, but :n:`@flag`
+ is switched on when this module is imported.
-Variants:
+.. cmd:: Unset @flag
-.. cmdv:: Local Unset @flag.
+ This command switches :n:`@flag` off. The original state of
+ :n:`@flag` is restored when the current module ends.
-This command switches :n:`@flag` off. The original
-state of :n:`@flag` is restored when the current *section* ends.
+ .. cmdv:: Local Unset @flag
-.. cmdv:: Global Unset @flag.
+ This command switches :n:`@flag` off. The original
+ state of :n:`@flag` is restored when the current *section* ends.
-This command switches :n:`@flag` off. The original
-state of :n:`@flag` is *not* restored at the end of the module. Additionally,
-if set in a file, :n:`@flag` is switched off when the file is `Require`-d.
+ .. cmdv:: Global Unset @flag
-.. cmdv:: Export Unset @flag.
+ This command switches :n:`@flag` off. The original
+ state of :n:`@flag` is *not* restored at the end of the module. Additionally,
+ if set in a file, :n:`@flag` is switched off when the file is `Require`-d.
- This command switches :n:`@flag` off. The original state
- of :n:`@flag` is restored at the end of the current module, but :n:`@flag`
- is switched off when this module is imported.
+ .. cmdv:: Export Unset @flag
+ This command switches :n:`@flag` off. The original state
+ of :n:`@flag` is restored at the end of the current module, but :n:`@flag`
+ is switched off when this module is imported.
-.. cmd:: Test @flag.
-This command prints whether :n:`@flag` is on or off.
+.. cmd:: Test @flag
+ This command prints whether :n:`@flag` is on or off.
-.. cmd:: Set @option @value.
-This command sets :n:`@option` to :n:`@value`. The original value of ` option` is
-restored when the current module ends.
+.. cmd:: Set @option @value
+ This command sets :n:`@option` to :n:`@value`. The original value of ` option` is
+ restored when the current module ends.
-Variants:
+ .. TODO : option and value are not syntax entries
-.. TODO : option and value are not syntax entries
+ .. cmdv:: Local Set @option @value
-.. cmdv:: Local Set @option @value.
+ This command sets :n:`@option` to :n:`@value`. The
+ original value of :n:`@option` is restored at the end of the module.
-This command sets :n:`@option` to :n:`@value`. The
-original value of :n:`@option` is restored at the end of the module.
+ .. cmdv:: Global Set @option @value
-.. cmdv:: Global Set @option @value.
+ This command sets :n:`@option` to :n:`@value`. The
+ original value of :n:`@option` is *not* restored at the end of the module.
+ Additionally, if set in a file, :n:`@option` is set to value when the file
+ is `Require`-d.
-This command sets :n:`@option` to :n:`@value`. The
-original value of :n:`@option` is *not* restored at the end of the module.
-Additionally, if set in a file, :n:`@option` is set to value when the file
-is `Require`-d.
+ .. cmdv:: Export Set @option
-.. cmdv:: Export Set @option.
+ This command set :n:`@option` to :n:`@value`. The original state
+ of :n:`@option` is restored at the end of the current module, but :n:`@option`
+ is set to :n:`@value` when this module is imported.
- This command set :n:`@option` to :n:`@value`. The original state
- of :n:`@option` is restored at the end of the current module, but :n:`@option`
- is set to :n:`@value` when this module is imported.
-
-.. cmd:: Unset @option.
+.. cmd:: Unset @option
This command turns off :n:`@option`.
+ .. cmdv:: Local Unset @option
-Variants:
-
+ This command turns off :n:`@option`. The original state of :n:`@option`
+ is restored when the current *section* ends.
-.. cmdv:: Local Unset @option.
+ .. cmdv:: Global Unset @option
- This command turns off :n:`@option`. The original state of :n:`@option` is restored when the current
- *section* ends.
+ This command turns off :n:`@option`. The original state of :n:`@option`
+ is *not* restored at the end of the module. Additionally, if unset in a file,
+ :n:`@option` is reset to its default value when the file is `Require`-d.
-.. cmdv:: Global Unset @option.
+ .. cmdv:: Export Unset @option
- This command turns off :n:`@option`. The original state of :n:`@option` is *not* restored at the end of the
- module. Additionally, if unset in a file, :n:`@option` is reset to its
- default value when the file is `Require`-d.
+ This command turns off :n:`@option`. The original state of :n:`@option`
+ is restored at the end of the current module, but :n:`@option` is set to
+ its default value when this module is imported.
-.. cmdv:: Export Unset @option.
-
- This command turns off :n:`@option`. The original state of :n:`@option` is restored at the end of the
- current module, but :n:`@option` is set to its default value when this module
- is imported.
+.. cmd:: Test @option
-.. cmd:: Test @option.
-
-This command prints the current value of :n:`@option`.
+ This command prints the current value of :n:`@option`.
.. TODO : table is not a syntax entry
-.. cmd:: Add @table @value.
+.. cmd:: Add @table @value
:name: Add `table` `value`
-.. cmd:: Remove @table @value.
+.. cmd:: Remove @table @value
:name: Remove `table` `value`
-.. cmd:: Test @table @value.
+.. cmd:: Test @table @value
:name: Test `table` `value`
-.. cmd:: Test @table for @value.
+.. cmd:: Test @table for @value
:name: Test `table` for `value`
-.. cmd:: Print Table @table.
-
-These are general commands for tables.
-
-.. cmd:: Print Options.
+.. cmd:: Print Table @table
-This command lists all available flags, options and tables.
+These are general commands for tables.
-Variants:
+.. cmd:: Print Options
+ This command lists all available flags, options and tables.
-.. cmdv:: Print Tables.
+ .. cmdv:: Print Tables
-This is a synonymous of ``Print Options``.
+ This is a synonymous of :cmd:`Print Options`.
.. _requests-to-the-environment:
@@ -239,358 +223,331 @@ This is a synonymous of ``Print Options``.
Requests to the environment
-------------------------------
-.. cmd:: Check @term.
+.. cmd:: Check @term
-This command displays the type of :n:`@term`. When called in proof mode, the
-term is checked in the local context of the current subgoal.
+ This command displays the type of :n:`@term`. When called in proof mode, the
+ term is checked in the local context of the current subgoal.
-Variants:
+ .. TODO : selector is not a syntax entry
-.. TODO : selector is not a syntax entry
+ .. cmdv:: @selector: Check @term
-.. cmdv:: @selector: Check @term.
+ This variant specifies on which subgoal to perform typing
+ (see Section :ref:`invocation-of-tactics`).
-specifies on which subgoal to perform typing
-(see Section :ref:`invocation-of-tactics`).
.. TODO : convtactic is not a syntax entry
-.. cmd:: Eval @convtactic in @term.
-
-This command performs the specified reduction on :n:`@term`, and displays
-the resulting term with its type. The term to be reduced may depend on
-hypothesis introduced in the first subgoal (if a proof is in
-progress).
-
-
-See also: Section :ref:`performingcomputations`.
-
-
-.. cmd:: Compute @term.
-
-This command performs a call-by-value evaluation of term by using the
-bytecode-based virtual machine. It is a shortcut for ``Eval vm_compute in``
-:n:`@term`.
-
-
-See also: Section :ref:`performingcomputations`.
-
-
-.. cmd::Extraction @term.
-
-This command displays the extracted term from :n:`@term`. The extraction is
-processed according to the distinction between :g:`Set` and :g:`Prop`; that is
-to say, between logical and computational content (see Section :ref:`sorts`).
-The extracted term is displayed in OCaml syntax, where global identifiers are
-still displayed as in |Coq| terms.
-
-
-Variants:
+.. cmd:: Eval @convtactic in @term
+ This command performs the specified reduction on :n:`@term`, and displays
+ the resulting term with its type. The term to be reduced may depend on
+ hypothesis introduced in the first subgoal (if a proof is in
+ progress).
-.. cmdv:: Recursive Extraction {+ @qualid }.
+ See also: Section :ref:`performingcomputations`.
-Recursively extracts all
-the material needed for the extraction of the qualified identifiers.
+.. cmd:: Compute @term
-See also: Chapter :ref:`extraction`.
+ This command performs a call-by-value evaluation of term by using the
+ bytecode-based virtual machine. It is a shortcut for ``Eval vm_compute in``
+ :n:`@term`.
+ See also: Section :ref:`performingcomputations`.
-.. cmd:: Print Assumptions @qualid.
-This commands display all the assumptions (axioms, parameters and
-variables) a theorem or definition depends on. Especially, it informs
-on the assumptions with respect to which the validity of a theorem
-relies.
+.. cmd:: Print Assumptions @qualid
+ This commands display all the assumptions (axioms, parameters and
+ variables) a theorem or definition depends on. Especially, it informs
+ on the assumptions with respect to which the validity of a theorem
+ relies.
-Variants:
+ .. cmdv:: Print Opaque Dependencies @qualid
+ :name: Print Opaque Dependencies
+ Displays the set of opaque constants :n:`@qualid` relies on in addition to
+ the assumptions.
-.. cmdv:: Print Opaque Dependencies @qualid.
+ .. cmdv:: Print Transparent Dependencies @qualid
+ :name: Print Transparent Dependencies
-Displays the set of opaque constants :n:`@qualid` relies on in addition to
-the assumptions.
+ Displays the set of transparent constants :n:`@qualid` relies on
+ in addition to the assumptions.
-.. cmdv:: Print Transparent Dependencies @qualid.
+ .. cmdv:: Print All Dependencies @qualid
+ :name: Print All Dependencies
-Displays the set of
-transparent constants :n:`@qualid` relies on in addition to the assumptions.
+ Displays all assumptions and constants :n:`@qualid` relies on.
-.. cmdv:: Print All Dependencies @qualid.
-Displays all assumptions and constants :n:`@qualid` relies on.
+.. cmd:: Search @qualid
+ This command displays the name and type of all objects (hypothesis of
+ the current goal, theorems, axioms, etc) of the current context whose
+ statement contains :n:`@qualid`. This command is useful to remind the user
+ of the name of library lemmas.
+ .. exn:: The reference @qualid was not found in the current environment.
-.. cmd:: Search @qualid.
+ There is no constant in the environment named qualid.
-This command displays the name and type of all objects (hypothesis of
-the current goal, theorems, axioms, etc) of the current context whose
-statement contains :n:`@qualid`. This command is useful to remind the user
-of the name of library lemmas.
+ .. cmdv:: Search @string
+ If :n:`@string` is a valid identifier, this command
+ displays the name and type of all objects (theorems, axioms, etc) of
+ the current context whose name contains string. If string is a
+ notation’s string denoting some reference :n:`@qualid` (referred to by its
+ main symbol as in `"+"` or by its notation’s string as in `"_ + _"` or
+ `"_ 'U' _"`, see Section :ref:`notations`), the command works like ``Search`` :n:`@qualid`.
-Error messages:
+ .. cmdv:: Search @string%@key
+ The string string must be a notation or the main
+ symbol of a notation which is then interpreted in the scope bound to
+ the delimiting key :n:`@key` (see Section :ref:`LocalInterpretationRulesForNotations`).
-.. exn:: The reference @qualid was not found in the current environment
+ .. cmdv:: Search @term_pattern
-There is no constant in the environment named qualid.
+ This searches for all statements or types of
+ definition that contains a subterm that matches the pattern
+ `term_pattern` (holes of the pattern are either denoted by `_` or by
+ `?ident` when non linear patterns are expected).
-Variants:
+ .. cmdv:: Search { + [-]@term_pattern_string }
-.. cmdv:: Search @string.
+ where
+ :n:`@term_pattern_string` is a term_pattern, a string, or a string followed
+ by a scope delimiting key `%key`. This generalization of ``Search`` searches
+ for all objects whose statement or type contains a subterm matching
+ :n:`@term_pattern` (or :n:`@qualid` if :n:`@string` is the notation for a reference
+ qualid) and whose name contains all string of the request that
+ correspond to valid identifiers. If a term_pattern or a string is
+ prefixed by `-`, the search excludes the objects that mention that
+ term_pattern or that string.
-If :n:`@string` is a valid identifier, this command
-displays the name and type of all objects (theorems, axioms, etc) of
-the current context whose name contains string. If string is a
-notation’s string denoting some reference :n:`@qualid` (referred to by its
-main symbol as in `"+"` or by its notation’s string as in `"_ + _"` or
-`"_ 'U' _"`, see Section :ref:`notations`), the command works like ``Search`` :n:`@qualid`.
+ .. cmdv:: Search @term_pattern_string … @term_pattern_string inside {+ @qualid }
-.. cmdv:: Search @string%@key.
+ This restricts the search to constructions defined in the modules
+ named by the given :n:`qualid` sequence.
-The string string must be a notation or the main
-symbol of a notation which is then interpreted in the scope bound to
-the delimiting key :n:`@key` (see Section :ref:`LocalInterpretationRulesForNotations`).
+ .. cmdv:: Search @term_pattern_string … @term_pattern_string outside {+ @qualid }
-.. cmdv:: Search @term_pattern.
+ This restricts the search to constructions not defined in the modules
+ named by the given :n:`qualid` sequence.
-This searches for all statements or types of
-definition that contains a subterm that matches the pattern
-`term_pattern` (holes of the pattern are either denoted by `_` or by
-`?ident` when non linear patterns are expected).
+ .. cmdv:: @selector: Search [-]@term_pattern_string … [-]@term_pattern_string
-.. cmdv:: Search { + [-]@term_pattern_string }.
+ This specifies the goal on which to search hypothesis (see
+ Section :ref:`invocation-of-tactics`).
+ By default the 1st goal is searched. This variant can
+ be combined with other variants presented here.
-where
-:n:`@term_pattern_string` is a term_pattern, a string, or a string followed
-by a scope delimiting key `%key`. This generalization of ``Search`` searches
-for all objects whose statement or type contains a subterm matching
-:n:`@term_pattern` (or :n:`@qualid` if :n:`@string` is the notation for a reference
-qualid) and whose name contains all string of the request that
-correspond to valid identifiers. If a term_pattern or a string is
-prefixed by `-`, the search excludes the objects that mention that
-term_pattern or that string.
+ .. example::
-.. cmdv:: Search @term_pattern_string … @term_pattern_string inside {+ @qualid } .
+ .. coqtop:: in
-This restricts the search to constructions defined in the modules named by the given :n:`qualid` sequence.
+ Require Import ZArith.
-.. cmdv:: Search @term_pattern_string … @term_pattern_string outside {+ @qualid }.
+ .. coqtop:: all
-This restricts the search to constructions not defined in the modules named by the given :n:`qualid` sequence.
+ Search Z.mul Z.add "distr".
-.. cmdv:: @selector: Search [-]@term_pattern_string … [-]@term_pattern_string.
+ Search "+"%Z "*"%Z "distr" -positive -Prop.
-This specifies the goal on which to search hypothesis (see
-Section :ref:`invocation-of-tactics`).
-By default the 1st goal is searched. This variant can
-be combined with other variants presented here.
+ Search (?x * _ + ?x * _)%Z outside OmegaLemmas.
+ .. cmdv:: SearchAbout
+ :name: SearchAbout
-.. coqtop:: in
+ .. deprecated:: 8.5
- Require Import ZArith.
+ Up to |Coq| version 8.4, :cmd:`Search` had the behavior of current
+ :cmd:`SearchHead` and the behavior of current :cmd:`Search` was obtained with
+ command :cmd:`SearchAbout`. For compatibility, the deprecated name
+ :cmd:`SearchAbout` can still be used as a synonym of :cmd:`Search`. For
+ compatibility, the list of objects to search when using :cmd:`SearchAbout`
+ may also be enclosed by optional ``[ ]`` delimiters.
-.. coqtop:: all
- Search Z.mul Z.add "distr".
+.. cmd:: SearchHead @term
- Search "+"%Z "*"%Z "distr" -positive -Prop.
+ This command displays the name and type of all hypothesis of the
+ current goal (if any) and theorems of the current context whose
+ statement’s conclusion has the form `(term t1 .. tn)`. This command is
+ useful to remind the user of the name of library lemmas.
- Search (?x * _ + ?x * _)%Z outside OmegaLemmas.
+ .. example::
-.. note:: Up to |Coq| version 8.4, ``Search`` had the behavior of current
- ``SearchHead`` and the behavior of current Search was obtained with
- command ``SearchAbout``. For compatibility, the deprecated name
- SearchAbout can still be used as a synonym of Search. For
- compatibility, the list of objects to search when using ``SearchAbout``
- may also be enclosed by optional ``[ ]`` delimiters.
+ .. coqtop:: reset all
+ SearchHead le.
-.. cmd:: SearchHead @term.
+ SearchHead (@eq bool).
-This command displays the name and type of all hypothesis of the
-current goal (if any) and theorems of the current context whose
-statement’s conclusion has the form `(term t1 .. tn)`. This command is
-useful to remind the user of the name of library lemmas.
+ .. cmdv:: SearchHead @term inside {+ @qualid }
+ This restricts the search to constructions defined in the modules named
+ by the given :n:`qualid` sequence.
+ .. cmdv:: SearchHead term outside {+ @qualid }
-.. coqtop:: reset all
+ This restricts the search to constructions not defined in the modules
+ named by the given :n:`qualid` sequence.
- SearchHead le.
+ .. exn:: Module/section @qualid not found.
- SearchHead (@eq bool).
+ No module :n:`@qualid` has been required (see Section :ref:`compiled-files`).
+ .. cmdv:: @selector: SearchHead @term
-Variants:
+ This specifies the goal on which to
+ search hypothesis (see Section :ref:`invocation-of-tactics`).
+ By default the 1st goal is searched. This variant can be combined
+ with other variants presented here.
-.. cmdv:: SearchHead @term inside {+ @qualid }.
+ .. note:: Up to |Coq| version 8.4, ``SearchHead`` was named ``Search``.
-This restricts the search to constructions defined in the modules named by the given :n:`qualid` sequence.
-.. cmdv:: SearchHead term outside {+ @qualid }.
+.. cmd:: SearchPattern @term
-This restricts the search to constructions not defined in the modules named by the given :n:`qualid` sequence.
+ This command displays the name and type of all hypothesis of the
+ current goal (if any) and theorems of the current context whose
+ statement’s conclusion or last hypothesis and conclusion matches the
+ expressionterm where holes in the latter are denoted by `_`.
+ It is a variant of :n:`Search @term_pattern` that does not look for subterms
+ but searches for statements whose conclusion has exactly the expected
+ form, or whose statement finishes by the given series of
+ hypothesis/conclusion.
-Error messages:
+ .. example::
-.. exn:: Module/section @qualid not found
+ .. coqtop:: in
-No module :n:`@qualid` has been required
-(see Section :ref:`compiled-files`).
+ Require Import Arith.
-.. cmdv:: @selector: SearchHead @term.
+ .. coqtop:: all
-This specifies the goal on which to
-search hypothesis (see Section :ref:`invocation-of-tactics`).
-By default the 1st goal is
-searched. This variant can be combined with other variants presented
-here.
+ SearchPattern (_ + _ = _ + _).
-.. note:: Up to |Coq| version 8.4, ``SearchHead`` was named ``Search``.
+ SearchPattern (nat -> bool).
+ SearchPattern (forall l : list _, _ l l).
-.. cmd:: SearchPattern @term.
+ Patterns need not be linear: you can express that the same expression
+ must occur in two places by using pattern variables `?ident`.
-This command displays the name and type of all hypothesis of the
-current goal (if any) and theorems of the current context whose
-statement’s conclusion or last hypothesis and conclusion matches the
-expressionterm where holes in the latter are denoted by `_`.
-It is a
-variant of Search @term_pattern that does not look for subterms but
-searches for statements whose conclusion has exactly the expected
-form, or whose statement finishes by the given series of
-hypothesis/conclusion.
-.. coqtop:: in
+ .. example::
- Require Import Arith.
+ .. coqtop:: all
-.. coqtop:: all
+ SearchPattern (?X1 + _ = _ + ?X1).
- SearchPattern (_ + _ = _ + _).
+ .. cmdv:: SearchPattern @term inside {+ @qualid }
- SearchPattern (nat -> bool).
+ This restricts the search to constructions defined in the modules
+ named by the given :n:`qualid` sequence.
- SearchPattern (forall l : list _, _ l l).
+ .. cmdv:: SearchPattern @term outside {+ @qualid }
-Patterns need not be linear: you can express that the same expression
-must occur in two places by using pattern variables `?ident`.
+ This restricts the search to constructions not defined in the modules
+ named by the given :n:`qualid` sequence.
+ .. cmdv:: @selector: SearchPattern @term
-.. coqtop:: all
+ This specifies the goal on which to
+ search hypothesis (see Section :ref:`invocation-of-tactics`).
+ By default the 1st goal is
+ searched. This variant can be combined with other variants presented
+ here.
- SearchPattern (?X1 + _ = _ + ?X1).
-Variants:
+.. cmd:: SearchRewrite @term
+ This command displays the name and type of all hypothesis of the
+ current goal (if any) and theorems of the current context whose
+ statement’s conclusion is an equality of which one side matches the
+ expression term. Holes in term are denoted by “_”.
-.. cmdv:: SearchPattern @term inside {+ @qualid } .
+ .. example::
-This restricts the search to constructions defined in the modules named by the given :n:`qualid` sequence.
+ .. coqtop:: in
-.. cmdv:: SearchPattern @term outside {+ @qualid }.
+ Require Import Arith.
-This restricts the search to constructions not defined in the modules named by the given :n:`qualid` sequence.
+ .. coqtop:: all
-.. cmdv:: @selector: SearchPattern @term.
+ SearchRewrite (_ + _ + _).
-This specifies the goal on which to
-search hypothesis (see Section :ref:`invocation-of-tactics`). By default the 1st goal is
-searched. This variant can be combined with other variants presented
-here.
+ .. cmdv:: SearchRewrite term inside {+ @qualid }
+ This restricts the search to constructions defined in the modules
+ named by the given :n:`qualid` sequence.
+ .. cmdv:: SearchRewrite @term outside {+ @qualid }
-.. cmdv:: SearchRewrite @term.
+ This restricts the search to constructions not defined in the modules
+ named by the given :n:`qualid` sequence.
-This command displays the name and type of all hypothesis of the
-current goal (if any) and theorems of the current context whose
-statement’s conclusion is an equality of which one side matches the
-expression term. Holes in term are denoted by “_”.
+ .. cmdv:: @selector: SearchRewrite @term
-.. coqtop:: in
-
- Require Import Arith.
-
-.. coqtop:: all
-
- SearchRewrite (_ + _ + _).
-
-Variants:
-
-
-.. cmdv:: SearchRewrite term inside {+ @qualid }.
-
-This restricts the search to constructions defined in the modules named by the given :n:`qualid` sequence.
-
-.. cmdv:: SearchRewrite @term outside {+ @qualid }.
-
-This restricts the search to constructions not defined in the modules named by the given :n:`qualid` sequence.
-
-.. cmdv:: @selector: SearchRewrite @term.
-
-This specifies the goal on which to
-search hypothesis (see Section :ref:`invocation-of-tactics`). By default the 1st goal is
-searched. This variant can be combined with other variants presented
-here.
+ This specifies the goal on which to
+ search hypothesis (see Section :ref:`invocation-of-tactics`).
+ By default the 1st goal is
+ searched. This variant can be combined with other variants presented
+ here.
.. note::
- For the ``Search``, ``SearchHead``, ``SearchPattern`` and ``SearchRewrite``
- queries, it
- is possible to globally filter the search results via the command
- ``Add Search Blacklist`` :n:`@substring`. A lemma whose fully-qualified name
- contains any of the declared substrings will be removed from the
- search results. The default blacklisted substrings are ``_subproof``
- ``Private_``. The command ``Remove Search Blacklist ...`` allows expunging
- this blacklist.
-
+ .. cmd:: Add Search Blacklist @string
-.. cmd:: Locate @qualid.
+ For the ``Search``, ``SearchHead``, ``SearchPattern`` and ``SearchRewrite``
+ queries, it is possible to globally filter the search results using this
+ command. A lemma whose fully-qualified name
+ contains any of the declared strings will be removed from the
+ search results. The default blacklisted substrings are ``_subproof`` and
+ ``Private_``.
-This command displays the full name of objects whose name is a prefix
-of the qualified identifier :n:`@qualid`, and consequently the |Coq| module in
-which they are defined. It searches for objects from the different
-qualified name spaces of |Coq|: terms, modules, Ltac, etc.
+ .. cmd:: Remove Search Blacklist @string
-.. coqtop:: none
+ This command allows expunging this blacklist.
- Set Printing Depth 50.
-.. coqtop:: all
+.. cmd:: Locate @qualid
- Locate nat.
+ This command displays the full name of objects whose name is a prefix
+ of the qualified identifier :n:`@qualid`, and consequently the |Coq| module in
+ which they are defined. It searches for objects from the different
+ qualified name spaces of |Coq|: terms, modules, Ltac, etc.
- Locate Datatypes.O.
+ .. example::
- Locate Init.Datatypes.O.
+ .. coqtop:: all
- Locate Coq.Init.Datatypes.O.
+ Locate nat.
- Locate I.Dont.Exist.
+ Locate Datatypes.O.
-Variants:
+ Locate Init.Datatypes.O.
+ Locate Coq.Init.Datatypes.O.
-.. cmdv:: Locate Term @qualid.
+ Locate I.Dont.Exist.
-As Locate but restricted to terms.
+ .. cmdv:: Locate Term @qualid
-.. cmdv:: Locate Module @qualid.
+ As Locate but restricted to terms.
-As Locate but restricted to modules.
+ .. cmdv:: Locate Module @qualid
-.. cmdv:: Locate Ltac @qualid.
+ As Locate but restricted to modules.
-As Locate but restricted to tactics.
+ .. cmdv:: Locate Ltac @qualid
+ As Locate but restricted to tactics.
See also: Section :ref:`locating-notations`
@@ -608,40 +565,35 @@ toplevel. This kind of file is called a *script* for |Coq|. The standard
(and default) extension of |Coq|’s script files is .v.
-.. cmd:: Load @ident.
-
-This command loads the file named :n:`ident`.v, searching successively in
-each of the directories specified in the *loadpath*. (see Section
-:ref:`libraries-and-filesystem`)
+.. cmd:: Load @ident
-Files loaded this way cannot leave proofs open, and the ``Load``
-command cannot be used inside a proof either.
+ This command loads the file named :n:`ident`.v, searching successively in
+ each of the directories specified in the *loadpath*. (see Section
+ :ref:`libraries-and-filesystem`)
-Variants:
+ Files loaded this way cannot leave proofs open, and the ``Load``
+ command cannot be used inside a proof either.
+ .. cmdv:: Load @string
-.. cmdv:: Load @string.
+ Loads the file denoted by the string :n:`@string`, where
+ string is any complete filename. Then the `~` and .. abbreviations are
+ allowed as well as shell variables. If no extension is specified, |Coq|
+ will use the default extension ``.v``.
-Loads the file denoted by the string :n:`@string`, where
-string is any complete filename. Then the `~` and .. abbreviations are
-allowed as well as shell variables. If no extension is specified, |Coq|
-will use the default extension ``.v``.
+ .. cmdv:: Load Verbose @ident
-.. cmdv:: Load Verbose @ident.
+ .. cmdv:: Load Verbose @string
-.. cmdv:: Load Verbose @string.
+ Display, while loading,
+ the answers of |Coq| to each command (including tactics) contained in
+ the loaded file See also: Section :ref:`controlling-display`.
-Display, while loading,
-the answers of |Coq| to each command (including tactics) contained in
-the loaded file See also: Section :ref:`controlling-display`.
+ .. exn:: Can’t find file @ident on loadpath.
-Error messages:
+ .. exn:: Load is not supported inside proofs.
-.. exn:: Can’t find file @ident on loadpath
-
-.. exn:: Load is not supported inside proofs
-
-.. exn:: Files processed by Load cannot leave open proofs
+ .. exn:: Files processed by Load cannot leave open proofs.
.. _compiled-files:
@@ -653,151 +605,139 @@ Chapter :ref:`thecoqcommands` for documentation on how to compile a file). A com
file is a particular case of module called *library file*.
-.. cmd:: Require @qualid.
-
-This command looks in the loadpath for a file containing module :n:`@qualid`
-and adds the corresponding module to the environment of |Coq|. As
-library files have dependencies in other library files, the command
-``Require`` :n:`@qualid` recursively requires all library files the module
-qualid depends on and adds the corresponding modules to the
-environment of |Coq| too. |Coq| assumes that the compiled files have been
-produced by a valid |Coq| compiler and their contents are then not
-replayed nor rechecked.
-
-To locate the file in the file system, :n:`@qualid` is decomposed under the
-form `dirpath.ident` and the file `ident.vo` is searched in the physical
-directory of the file system that is mapped in |Coq| loadpath to the
-logical path dirpath (see Section :ref:`libraries-and-filesystem`). The mapping between
-physical directories and logical names at the time of requiring the
-file must be consistent with the mapping used to compile the file. If
-several files match, one of them is picked in an unspecified fashion.
+.. cmd:: Require @qualid
+ This command looks in the loadpath for a file containing module :n:`@qualid`
+ and adds the corresponding module to the environment of |Coq|. As
+ library files have dependencies in other library files, the command
+ :cmd:`Require` :n:`@qualid` recursively requires all library files the module
+ qualid depends on and adds the corresponding modules to the
+ environment of |Coq| too. |Coq| assumes that the compiled files have been
+ produced by a valid |Coq| compiler and their contents are then not
+ replayed nor rechecked.
-Variants:
+ To locate the file in the file system, :n:`@qualid` is decomposed under the
+ form `dirpath.ident` and the file `ident.vo` is searched in the physical
+ directory of the file system that is mapped in |Coq| loadpath to the
+ logical path dirpath (see Section :ref:`libraries-and-filesystem`). The mapping between
+ physical directories and logical names at the time of requiring the
+ file must be consistent with the mapping used to compile the file. If
+ several files match, one of them is picked in an unspecified fashion.
-.. cmdv:: Require Import @qualid.
-This loads and declares the module :n:`@qualid`
-and its dependencies then imports the contents of :n:`@qualid` as described
-:ref:`here <import_qualid>`. It does not import the modules on which
-qualid depends unless these modules were themselves required in module
-:n:`@qualid`
-using ``Require Export``, as described below, or recursively required
-through a sequence of ``Require Export``. If the module required has
-already been loaded, ``Require Import`` :n:`@qualid` simply imports it, as ``Import``
-:n:`@qualid` would.
+ .. cmdv:: Require Import @qualid
+ :name: Require Import
-.. cmdv:: Require Export @qualid.
+ This loads and declares the module :n:`@qualid`
+ and its dependencies then imports the contents of :n:`@qualid` as described
+ :ref:`here <import_qualid>`. It does not import the modules on which
+ qualid depends unless these modules were themselves required in module
+ :n:`@qualid`
+ using :cmd:`Require Export`, as described below, or recursively required
+ through a sequence of :cmd:`Require Export`. If the module required has
+ already been loaded, :cmd:`Require Import` :n:`@qualid` simply imports it, as
+ :cmd:`Import` :n:`@qualid` would.
-This command acts as ``Require Import`` :n:`@qualid`,
-but if a further module, say `A`, contains a command ``Require Export`` `B`,
-then the command ``Require Import`` `A` also imports the module `B.`
+ .. cmdv:: Require Export @qualid
+ :name: Require Export
-.. cmdv:: Require [Import | Export] {+ @qualid }.
+ This command acts as :cmd:`Require Import` :n:`@qualid`,
+ but if a further module, say `A`, contains a command :cmd:`Require Export` `B`,
+ then the command :cmd:`Require Import` `A` also imports the module `B.`
-This loads the
-modules named by the :n:`qualid` sequence and their recursive
-dependencies. If
-``Import`` or ``Export`` is given, it also imports these modules and
-all the recursive dependencies that were marked or transitively marked
-as ``Export``.
+ .. cmdv:: Require [Import | Export] {+ @qualid }
-.. cmdv:: From @dirpath Require @qualid.
+ This loads the
+ modules named by the :n:`qualid` sequence and their recursive
+ dependencies. If
+ ``Import`` or ``Export`` is given, it also imports these modules and
+ all the recursive dependencies that were marked or transitively marked
+ as ``Export``.
-This command acts as ``Require``, but picks
-any library whose absolute name is of the form dirpath.dirpath’.qualid
-for some `dirpath’`. This is useful to ensure that the :n:`@qualid` library
-comes from a given package by making explicit its absolute root.
+ .. cmdv:: From @dirpath Require @qualid
+ This command acts as :cmd:`Require`, but picks
+ any library whose absolute name is of the form dirpath.dirpath’.qualid
+ for some `dirpath’`. This is useful to ensure that the :n:`@qualid` library
+ comes from a given package by making explicit its absolute root.
+ .. exn:: Cannot load qualid: no physical path bound to dirpath.
-Error messages:
+ .. exn:: Cannot find library foo in loadpath.
-.. exn:: Cannot load qualid: no physical path bound to dirpath
+ The command did not find the
+ file foo.vo. Either foo.v exists but is not compiled or foo.vo is in a
+ directory which is not in your LoadPath (see Section :ref:`libraries-and-filesystem`).
-.. exn:: Cannot find library foo in loadpath
+ .. exn:: Compiled library @ident.vo makes inconsistent assumptions over library qualid.
-The command did not find the
-file foo.vo. Either foo.v exists but is not compiled or foo.vo is in a
-directory which is not in your LoadPath (see Section :ref:`libraries-and-filesystem`).
+ The command tried to load library file :n:`@ident`.vo that
+ depends on some specific version of library :n:`@qualid` which is not the
+ one already loaded in the current |Coq| session. Probably `ident.v` was
+ not properly recompiled with the last version of the file containing
+ module :n:`@qualid`.
-.. exn:: Compiled library @ident.vo makes inconsistent assumptions over library qualid
+ .. exn:: Bad magic number.
-The command tried to load library file :n:`@ident`.vo that
-depends on some specific version of library :n:`@qualid` which is not the
-one already loaded in the current |Coq| session. Probably `ident.v` was
-not properly recompiled with the last version of the file containing
-module :n:`@qualid`.
+ The file `ident.vo` was found but either it is not a
+ |Coq| compiled module, or it was compiled with an incompatible
+ version of |Coq|.
-.. exn:: Bad magic number
+ .. exn:: The file `ident.vo` contains library dirpath and not library dirpath’.
-The file `ident.vo` was found but either it is not a
-|Coq| compiled module, or it was compiled with an incompatible
-version of |Coq|.
+ The library file `dirpath’` is indirectly required by the
+ ``Require`` command but it is bound in the current loadpath to the
+ file `ident.vo` which was bound to a different library name `dirpath` at
+ the time it was compiled.
-.. exn:: The file `ident.vo` contains library dirpath and not library dirpath’
-The library file `dirpath’` is indirectly required by the
-``Require`` command but it is bound in the current loadpath to the
-file `ident.vo` which was bound to a different library name `dirpath` at
-the time it was compiled.
+ .. exn:: Require is not allowed inside a module or a module type.
-
-.. exn:: Require is not allowed inside a module or a module type
-
-This command
-is not allowed inside a module or a module type being defined. It is
-meant to describe a dependency between compilation units. Note however
-that the commands ``Import`` and ``Export`` alone can be used inside modules
-(see Section :ref:`Import <import_qualid>`).
+ This command
+ is not allowed inside a module or a module type being defined. It is
+ meant to describe a dependency between compilation units. Note however
+ that the commands ``Import`` and ``Export`` alone can be used inside modules
+ (see Section :ref:`Import <import_qualid>`).
See also: Chapter :ref:`thecoqcommands`
-.. cmd:: Print Libraries.
-
-This command displays the list of library files loaded in the
-current |Coq| session. For each of these libraries, it also tells if it
-is imported.
-
-
-.. cmd:: Declare ML Module {+ @string } .
-
-This commands loads the OCaml compiled files
-with names given by the :n:`@string` sequence
-(dynamic link). It is mainly used to load tactics dynamically. The
-files are searched into the current OCaml loadpath (see the
-command ``Add ML Path`` in Section :ref:`libraries-and-filesystem`). Loading of OCaml files is only possible under the bytecode version of ``coqtop`` (i.e.
-``coqtop`` called with option ``-byte``, see chapter :ref:`thecoqcommands`), or when |Coq| has been compiled with a
-version of OCaml that supports native Dynlink (≥ 3.11).
-
-
-Variants:
-
+.. cmd:: Print Libraries
-.. cmdv:: Local Declare ML Module {+ @string }.
+ This command displays the list of library files loaded in the
+ current |Coq| session. For each of these libraries, it also tells if it
+ is imported.
-This variant is not
-exported to the modules that import the module where they occur, even
-if outside a section.
+.. cmd:: Declare ML Module {+ @string }
+ This commands loads the OCaml compiled files
+ with names given by the :n:`@string` sequence
+ (dynamic link). It is mainly used to load tactics dynamically. The
+ files are searched into the current OCaml loadpath (see the
+ command ``Add ML Path`` in Section :ref:`libraries-and-filesystem`).
+ Loading of OCaml files is only possible under the bytecode version of
+ ``coqtop`` (i.e. ``coqtop`` called with option ``-byte``, see chapter
+ :ref:`thecoqcommands`), or when |Coq| has been compiled with a
+ version of OCaml that supports native Dynlink (≥ 3.11).
-Error messages:
+ .. cmdv:: Local Declare ML Module {+ @string }
-.. exn:: File not found on loadpath : @string
+ This variant is not exported to the modules that import the module
+ where they occur, even if outside a section.
-.. exn:: Loading of ML object file forbidden in a native Coq
+ .. exn:: File not found on loadpath: @string.
+ .. exn:: Loading of ML object file forbidden in a native Coq.
-.. cmd:: Print ML Modules.
+.. cmd:: Print ML Modules
-This prints the name of all OCaml modules loaded with ``Declare
-ML Module``. To know from where these module were loaded, the user
-should use the command ``Locate File`` (see :ref:`here <locate-file>`)
+ This prints the name of all OCaml modules loaded with ``Declare
+ ML Module``. To know from where these module were loaded, the user
+ should use the command ``Locate File`` (see :ref:`here <locate-file>`)
.. _loadpath:
@@ -811,110 +751,92 @@ for practical purposes. Such commands are only meant to be issued in
the toplevel, and using them in source files is discouraged.
-.. cmd:: Pwd.
-
-This command displays the current working directory.
-
-
-.. cmd:: Cd @string.
-
-This command changes the current directory according to :n:`@string` which
-can be any valid path.
-
-
-Variants:
-
-
-.. cmdv:: Cd.
-
-Is equivalent to Pwd.
-
-
-
-.. cmd:: Add LoadPath @string as @dirpath.
-
-This command is equivalent to the command line option
-``-Q`` :n:`@string` :n:`@dirpath`. It adds the physical directory string to the current
-|Coq| loadpath and maps it to the logical directory dirpath.
+.. cmd:: Pwd
-Variants:
+ This command displays the current working directory.
-.. cmdv:: Add LoadPath @string.
+.. cmd:: Cd @string
-Performs as Add LoadPath :n:`@string` as :n:`@dirpath` but
-for the empty directory path.
+ This command changes the current directory according to :n:`@string` which
+ can be any valid path.
+ .. cmdv:: Cd
+ Is equivalent to Pwd.
-.. cmd:: Add Rec LoadPath @string as @dirpath.
-This command is equivalent to the command line option
-``-R`` :n:`@string` :n:`@dirpath`. It adds the physical directory string and all its
-subdirectories to the current |Coq| loadpath.
+.. cmd:: Add LoadPath @string as @dirpath
-Variants:
+ This command is equivalent to the command line option
+ ``-Q`` :n:`@string` :n:`@dirpath`. It adds the physical directory string to the current
+ |Coq| loadpath and maps it to the logical directory dirpath.
+ .. cmdv:: Add LoadPath @string
-.. cmdv:: Add Rec LoadPath @string.
+ Performs as Add LoadPath :n:`@string` as :n:`@dirpath` but
+ for the empty directory path.
-Works as ``Add Rec LoadPath`` :n:`@string` as :n:`@dirpath` but for the empty
-logical directory path.
+.. cmd:: Add Rec LoadPath @string as @dirpath
+ This command is equivalent to the command line option
+ ``-R`` :n:`@string` :n:`@dirpath`. It adds the physical directory string and all its
+ subdirectories to the current |Coq| loadpath.
-.. cmd:: Remove LoadPath @string.
+ .. cmdv:: Add Rec LoadPath @string
-This command removes the path :n:`@string` from the current |Coq| loadpath.
+ Works as :cmd:`Add Rec LoadPath` :n:`@string` as :n:`@dirpath` but for the empty
+ logical directory path.
-.. cmd:: Print LoadPath.
+.. cmd:: Remove LoadPath @string
-This command displays the current |Coq| loadpath.
+ This command removes the path :n:`@string` from the current |Coq| loadpath.
-Variants:
+.. cmd:: Print LoadPath
+ This command displays the current |Coq| loadpath.
-.. cmdv:: Print LoadPath @dirpath.
+ .. cmdv:: Print LoadPath @dirpath
-Works as ``Print LoadPath`` but displays only
-the paths that extend the :n:`@dirpath` prefix.
+ Works as :cmd:`Print LoadPath` but displays only
+ the paths that extend the :n:`@dirpath` prefix.
-.. cmd:: Add ML Path @string.
+.. cmd:: Add ML Path @string
-This command adds the path :n:`@string` to the current OCaml
-loadpath (see the command `Declare ML Module`` in Section :ref:`compiled-files`).
+ This command adds the path :n:`@string` to the current OCaml
+ loadpath (see the command `Declare ML Module`` in Section :ref:`compiled-files`).
-.. cmd:: Add Rec ML Path @string.
+.. cmd:: Add Rec ML Path @string
-This command adds the directory :n:`@string` and all its subdirectories to
-the current OCaml loadpath (see the command ``Declare ML Module``
-in Section :ref:`compiled-files`).
+ This command adds the directory :n:`@string` and all its subdirectories to
+ the current OCaml loadpath (see the command :cmd:`Declare ML Module`).
-.. cmd:: Print ML Path @string.
+.. cmd:: Print ML Path @string
-This command displays the current OCaml loadpath. This
-command makes sense only under the bytecode version of ``coqtop``, i.e.
-using option ``-byte``
-(see the command Declare ML Module in Section :ref:`compiled-files`).
+ This command displays the current OCaml loadpath. This
+ command makes sense only under the bytecode version of ``coqtop``, i.e.
+ using option ``-byte``
+ (see the command Declare ML Module in Section :ref:`compiled-files`).
.. _locate-file:
-.. cmd:: Locate File @string.
+.. cmd:: Locate File @string
-This command displays the location of file string in the current
-loadpath. Typically, string is a .cmo or .vo or .v file.
+ This command displays the location of file string in the current
+ loadpath. Typically, string is a .cmo or .vo or .v file.
-.. cmd:: Locate Library @dirpath.
+.. cmd:: Locate Library @dirpath
-This command gives the status of the |Coq| module dirpath. It tells if
-the module is loaded and if not searches in the load path for a module
-of logical name :n:`@dirpath`.
+ This command gives the status of the |Coq| module dirpath. It tells if
+ the module is loaded and if not searches in the load path for a module
+ of logical name :n:`@dirpath`.
.. _backtracking:
@@ -927,95 +849,72 @@ interactively, they cannot be part of a vernacular file loaded via
``Load`` or compiled by ``coqc``.
-.. cmd:: Reset @ident.
-
-This command removes all the objects in the environment since :n:`@ident`
-was introduced, including :n:`@ident`. :n:`@ident` may be the name of a defined or
-declared object as well as the name of a section. One cannot reset
-over the name of a module or of an object inside a module.
-
-
-Error messages:
-
-.. exn:: @ident: no such entry
-
-Variants:
-
-.. cmd:: Reset Initial.
-
-Goes back to the initial state, just after the start
-of the interactive session.
-
-
-
-.. cmd:: Back.
-
-This commands undoes all the effects of the last vernacular command.
-Commands read from a vernacular file via a ``Load`` are considered as a
-single command. Proof management commands are also handled by this
-command (see Chapter :ref:`proofhandling`). For that, Back may have to undo more than
-one command in order to reach a state where the proof management
-information is available. For instance, when the last command is a
-``Qed``, the management information about the closed proof has been
-discarded. In this case, ``Back`` will then undo all the proof steps up to
-the statement of this proof.
-
-
-Variants:
+.. cmd:: Reset @ident
+ This command removes all the objects in the environment since :n:`@ident`
+ was introduced, including :n:`@ident`. :n:`@ident` may be the name of a defined or
+ declared object as well as the name of a section. One cannot reset
+ over the name of a module or of an object inside a module.
-.. cmdv:: Back @num.
+ .. exn:: @ident: no such entry.
-Undoes :n:`@num` vernacular commands. As for Back, some extra
-commands may be undone in order to reach an adequate state. For
-instance Back :n:`@num` will not re-enter a closed proof, but rather go just
-before that proof.
+ .. cmdv:: Reset Initial
+ Goes back to the initial state, just after the start
+ of the interactive session.
-Error messages:
+.. cmd:: Back
+ This command undoes all the effects of the last vernacular command.
+ Commands read from a vernacular file via a :cmd:`Load` are considered as a
+ single command. Proof management commands are also handled by this
+ command (see Chapter :ref:`proofhandling`). For that, Back may have to undo more than
+ one command in order to reach a state where the proof management
+ information is available. For instance, when the last command is a
+ :cmd:`Qed`, the management information about the closed proof has been
+ discarded. In this case, :cmd:`Back` will then undo all the proof steps up to
+ the statement of this proof.
-.. exn:: Invalid backtrack
+ .. cmdv:: Back @num
-The user wants to undo more commands than available in the history.
+ Undo :n:`@num` vernacular commands. As for Back, some extra
+ commands may be undone in order to reach an adequate state. For
+ instance Back :n:`@num` will not re-enter a closed proof, but rather go just
+ before that proof.
-.. cmd:: BackTo @num.
+ .. exn:: Invalid backtrack.
-This command brings back the system to the state labeled :n:`@num`,
-forgetting the effect of all commands executed after this state. The
-state label is an integer which grows after each successful command.
-It is displayed in the prompt when in -emacs mode. Just as ``Back`` (see
-above), the ``BackTo`` command now handles proof states. For that, it may
-have to undo some extra commands and end on a state `num′ ≤ num` if
-necessary.
+ The user wants to undo more commands than available in the history.
+.. cmd:: BackTo @num
-Variants:
+ This command brings back the system to the state labeled :n:`@num`,
+ forgetting the effect of all commands executed after this state. The
+ state label is an integer which grows after each successful command.
+ It is displayed in the prompt when in -emacs mode. Just as :cmd:`Back` (see
+ above), the :cmd:`BackTo` command now handles proof states. For that, it may
+ have to undo some extra commands and end on a state `num′ ≤ num` if
+ necessary.
+ .. cmdv:: Backtrack @num @num @num
+ :name: Backtrack
-.. cmdv:: Backtrack @num @num @num.
+ .. deprecated:: 8.4
-`Backtrack` is a *deprecated* form of
-`BackTo` which allows explicitly manipulating the proof environment. The
-three numbers represent the following:
+ :cmd:`Backtrack` is a *deprecated* form of
+ :cmd:`BackTo` which allows explicitly manipulating the proof environment. The
+ three numbers represent the following:
- + *first number* : State label to reach, as for BackTo.
- + *second number* : *Proof state number* to unbury once aborts have been done.
- |Coq| will compute the number of Undo to perform (see Chapter :ref:`proofhandling`).
- + *third number* : Number of Abort to perform, i.e. the number of currently
- opened nested proofs that must be canceled (see Chapter :ref:`proofhandling`).
+ + *first number* : State label to reach, as for :cmd:`BackTo`.
+ + *second number* : *Proof state number* to unbury once aborts have been done.
+ |Coq| will compute the number of :cmd:`Undo` to perform (see Chapter :ref:`proofhandling`).
+ + *third number* : Number of :cmd:`Abort` to perform, i.e. the number of currently
+ opened nested proofs that must be canceled (see Chapter :ref:`proofhandling`).
+ .. exn:: Invalid backtrack.
-
-
-Error messages:
-
-
-.. exn:: Invalid backtrack
-
-
-The destination state label is unknown.
+ The destination state label is unknown.
.. _quitting-and-debugging:
@@ -1024,86 +923,81 @@ Quitting and debugging
--------------------------
-.. cmd:: Quit.
-
-This command permits to quit |Coq|.
+.. cmd:: Quit
+ This command permits to quit |Coq|.
-.. cmd:: Drop.
-This is used mostly as a debug facility by |Coq|’s implementors and does
-not concern the casual user. This command permits to leave |Coq|
-temporarily and enter the OCaml toplevel. The OCaml
-command:
+.. cmd:: Drop
+ This is used mostly as a debug facility by |Coq|’s implementors and does
+ not concern the casual user. This command permits to leave |Coq|
+ temporarily and enter the OCaml toplevel. The OCaml
+ command:
-::
+ ::
- #use "include";;
+ #use "include";;
+ adds the right loadpaths and loads some toplevel printers for all
+ abstract types of |Coq|- section_path, identifiers, terms, judgments, ….
+ You can also use the file base_include instead, that loads only the
+ pretty-printers for section_paths and identifiers. You can return back
+ to |Coq| with the command:
-adds the right loadpaths and loads some toplevel printers for all
-abstract types of |Coq|- section_path, identifiers, terms, judgments, ….
-You can also use the file base_include instead, that loads only the
-pretty-printers for section_paths and identifiers. You can return back
-to |Coq| with the command:
+ ::
+ go();;
-::
-
- go();;
-
-.. warning::
-
- #. It only works with the bytecode version of |Coq| (i.e. `coqtop.byte`,
- see Section `interactive-use`).
- #. You must have compiled |Coq| from the source package and set the
- environment variable COQTOP to the root of your copy of the sources
- (see Section `customization-by-environment-variables`).
+ .. warning::
+ #. It only works with the bytecode version of |Coq| (i.e. `coqtop.byte`,
+ see Section `interactive-use`).
+ #. You must have compiled |Coq| from the source package and set the
+ environment variable COQTOP to the root of your copy of the sources
+ (see Section `customization-by-environment-variables`).
.. TODO : command is not a syntax entry
-.. cmd:: Time @command.
+.. cmd:: Time @command
-This command executes the vernacular command :n:`@command` and displays the
-time needed to execute it.
+ This command executes the vernacular command :n:`@command` and displays the
+ time needed to execute it.
-.. cmd:: Redirect @string @command.
+.. cmd:: Redirect @string @command
-This command executes the vernacular command :n:`@command`, redirecting its
-output to ":n:`@string`.out".
+ This command executes the vernacular command :n:`@command`, redirecting its
+ output to ":n:`@string`.out".
-.. cmd:: Timeout @num @command.
+.. cmd:: Timeout @num @command
-This command executes the vernacular command :n:`@command`. If the command
-has not terminated after the time specified by the :n:`@num` (time
-expressed in seconds), then it is interrupted and an error message is
-displayed.
+ This command executes the vernacular command :n:`@command`. If the command
+ has not terminated after the time specified by the :n:`@num` (time
+ expressed in seconds), then it is interrupted and an error message is
+ displayed.
+ .. opt:: Default Timeout @num
-.. opt:: Default Timeout @num
+ This option controls a default timeout for subsequent commands, as if they
+ were passed to a :cmd:`Timeout` command. Commands already starting by a
+ :cmd:`Timeout` are unaffected.
- This option controls a default timeout for subsequent commands, as if they
- were passed to a :cmd:`Timeout` command. Commands already starting by a
- :cmd:`Timeout` are unaffected.
-.. cmd:: Fail @command.
+.. cmd:: Fail @command
-For debugging scripts, sometimes it is desirable to know
-whether a command or a tactic fails. If the given :n:`@command`
-fails, the ``Fail`` statement succeeds, without changing the proof
-state, and in interactive mode, the system
-prints a message confirming the failure.
-If the given :n:`@command` succeeds, the statement is an error, and
-it prints a message indicating that the failure did not occur.
+ For debugging scripts, sometimes it is desirable to know
+ whether a command or a tactic fails. If the given :n:`@command`
+ fails, the ``Fail`` statement succeeds, without changing the proof
+ state, and in interactive mode, the system
+ prints a message confirming the failure.
+ If the given :n:`@command` succeeds, the statement is an error, and
+ it prints a message indicating that the failure did not occur.
-Error messages:
+ .. exn:: The command has not failed!
-.. exn:: The command has not failed!
.. _controlling-display:
@@ -1131,13 +1025,15 @@ Controlling display
:cmd:`SearchPattern`, :cmd:`SearchRewrite` etc. to omit types from their
output, printing only identifiers.
-.. opt:: Printing Width @integer
+.. opt:: Printing Width @num
+ :name: Printing Width
This command sets which left-aligned part of the width of the screen is used
for display. At the time of writing this documentation, the default value
is 78.
-.. opt:: Printing Depth @integer
+.. opt:: Printing Depth @num
+ :name: Printing Depth
This option controls the nesting depth of the formatter used for pretty-
printing. Beyond this depth, display of subterms is replaced by dots. At the
@@ -1181,79 +1077,77 @@ as numbers, and for reflection-based tactics. The commands to fine-
tune the reduction strategies and the lazy conversion algorithm are
described first.
-.. cmd:: Opaque {+ @qualid }.
-
-This command has an effect on unfoldable constants, i.e. on constants
-defined by ``Definition`` or ``Let`` (with an explicit body), or by a command
-assimilated to a definition such as ``Fixpoint``, ``Program Definition``, etc,
-or by a proof ended by ``Defined``. The command tells not to unfold the
-constants in the :n:`@qualid` sequence in tactics using δ-conversion (unfolding
-a constant is replacing it by its definition).
-
-``Opaque`` has also an effect on the conversion algorithm of |Coq|, telling
-it to delay the unfolding of a constant as much as possible when |Coq|
-has to check the conversion (see Section :ref:`conversion-rules`) of two distinct
-applied constants.
-
-The scope of ``Opaque`` is limited to the current section, or current
-file, unless the variant ``Global Opaque`` is used.
+.. cmd:: Opaque {+ @qualid }
+ This command has an effect on unfoldable constants, i.e. on constants
+ defined by :cmd:`Definition` or :cmd:`Let` (with an explicit body), or by a command
+ assimilated to a definition such as :cmd:`Fixpoint`, :cmd:`Program Definition`, etc,
+ or by a proof ended by :cmd:`Defined`. The command tells not to unfold the
+ constants in the :n:`@qualid` sequence in tactics using δ-conversion (unfolding
+ a constant is replacing it by its definition).
-See also: sections :ref:`performingcomputations`, :ref:`tactics-automatizing`, :ref:`proof-editing-mode`
+ :cmd:`Opaque` has also an effect on the conversion algorithm of |Coq|, telling
+ it to delay the unfolding of a constant as much as possible when |Coq|
+ has to check the conversion (see Section :ref:`conversion-rules`) of two distinct
+ applied constants.
+ .. cmdv:: Global Opaque {+ @qualid }
+ :name: Global Opaque
-Error messages:
+ The scope of :cmd:`Opaque` is limited to the current section, or current
+ file, unless the variant :cmd:`Global Opaque` is used.
+ See also: sections :ref:`performingcomputations`, :ref:`tactics-automatizing`,
+ :ref:`proof-editing-mode`
-.. exn:: The reference @qualid was not found in the current environment
+ .. exn:: The reference @qualid was not found in the current environment.
-There is no constant referred by :n:`@qualid` in the environment.
-Nevertheless, if you asked ``Opaque`` `foo` `bar` and if `bar` does not exist, `foo` is set opaque.
+ There is no constant referred by :n:`@qualid` in the environment.
+ Nevertheless, if you asked :cmd:`Opaque` `foo` `bar` and if `bar` does
+ not exist, `foo` is set opaque.
-.. cmd:: Transparent {+ @qualid }.
+.. cmd:: Transparent {+ @qualid }
-This command is the converse of `Opaque`` and it applies on unfoldable
-constants to restore their unfoldability after an Opaque command.
+ This command is the converse of :cmd:`Opaque` and it applies on unfoldable
+ constants to restore their unfoldability after an Opaque command.
-Note in particular that constants defined by a proof ended by Qed are
-not unfoldable and Transparent has no effect on them. This is to keep
-with the usual mathematical practice of *proof irrelevance*: what
-matters in a mathematical development is the sequence of lemma
-statements, not their actual proofs. This distinguishes lemmas from
-the usual defined constants, whose actual values are of course
-relevant in general.
+ Note in particular that constants defined by a proof ended by Qed are
+ not unfoldable and Transparent has no effect on them. This is to keep
+ with the usual mathematical practice of *proof irrelevance*: what
+ matters in a mathematical development is the sequence of lemma
+ statements, not their actual proofs. This distinguishes lemmas from
+ the usual defined constants, whose actual values are of course
+ relevant in general.
-The scope of Transparent is limited to the current section, or current
-file, unless the variant ``Global Transparent`` is
-used.
+ .. cmdv:: Global Transparent {+ @qualid }
+ :name: Global Transparent
+ The scope of Transparent is limited to the current section, or current
+ file, unless the variant :cmd:`Global Transparent` is
+ used.
-Error messages:
+ .. exn:: The reference @qualid was not found in the current environment.
+ There is no constant referred by :n:`@qualid` in the environment.
-.. exn:: The reference @qualid was not found in the current environment
-
-There is no constant referred by :n:`@qualid` in the environment.
-
-
-
-See also: sections :ref:`performingcomputations`, :ref:`tactics-automatizing`, :ref:`proof-editing-mode`
+ See also: sections :ref:`performingcomputations`,
+ :ref:`tactics-automatizing`, :ref:`proof-editing-mode`
.. _vernac-strategy:
-.. cmd:: Strategy @level [ {+ @qualid } ].
+.. cmd:: Strategy @level [ {+ @qualid } ]
-This command generalizes the behavior of Opaque and Transparent
-commands. It is used to fine-tune the strategy for unfolding
-constants, both at the tactic level and at the kernel level. This
-command associates a level to the qualified names in the :n:`@qualid`
-sequence. Whenever two
-expressions with two distinct head constants are compared (for
-instance, this comparison can be triggered by a type cast), the one
-with lower level is expanded first. In case of a tie, the second one
-(appearing in the cast type) is expanded.
+ This command generalizes the behavior of Opaque and Transparent
+ commands. It is used to fine-tune the strategy for unfolding
+ constants, both at the tactic level and at the kernel level. This
+ command associates a level to the qualified names in the :n:`@qualid`
+ sequence. Whenever two
+ expressions with two distinct head constants are compared (for
+ instance, this comparison can be triggered by a type cast), the one
+ with lower level is expanded first. In case of a tie, the second one
+ (appearing in the cast type) is expanded.
-Levels can be one of the following (higher to lower):
+ Levels can be one of the following (higher to lower):
+ ``opaque`` : level of opaque constants. They cannot be expanded by
tactics (behaves like +∞, see next item).
@@ -1266,52 +1160,42 @@ Levels can be one of the following (higher to lower):
+ ``expand`` : level of constants that should be expanded first (behaves
like −∞)
+ .. cmdv:: Local Strategy @level [ {+ @qualid } ]
-These directives survive section and module closure, unless the
-command is prefixed by Local. In the latter case, the behavior
-regarding sections and modules is the same as for the ``Transparent`` and
-``Opaque`` commands.
-
-
-.. cmd:: Print Strategy @qualid.
-
-This command prints the strategy currently associated to :n:`@qualid`. It
-fails if :n:`@qualid` is not an unfoldable reference, that is, neither a
-variable nor a constant.
-
-
-Error messages:
-
-
-.. exn:: The reference is not unfoldable.
-
-
+ These directives survive section and module closure, unless the
+ command is prefixed by ``Local``. In the latter case, the behavior
+ regarding sections and modules is the same as for the :cmd:`Transparent` and
+ :cmd:`Opaque` commands.
-Variants:
+.. cmd:: Print Strategy @qualid
-.. cmdv:: Print Strategies.
+ This command prints the strategy currently associated to :n:`@qualid`. It
+ fails if :n:`@qualid` is not an unfoldable reference, that is, neither a
+ variable nor a constant.
-Print all the currently non-transparent strategies.
+ .. exn:: The reference is not unfoldable.
+ .. cmdv:: Print Strategies
+ Print all the currently non-transparent strategies.
-.. cmd:: Declare Reduction @ident := @convtactic.
-This command allows giving a short name to a reduction expression, for
-instance lazy beta delta [foo bar]. This short name can then be used
-in ``Eval`` :n:`@ident` ``in`` ... or ``eval`` directives. This command
-accepts the
-Local modifier, for discarding this reduction name at the end of the
-file or module. For the moment the name cannot be qualified. In
-particular declaring the same name in several modules or in several
-functor applications will be refused if these declarations are not
-local. The name :n:`@ident` cannot be used directly as an Ltac tactic, but
-nothing prevents the user to also perform a
-``Ltac`` `ident` ``:=`` `convtactic`.
+.. cmd:: Declare Reduction @ident := @convtactic
+ This command allows giving a short name to a reduction expression, for
+ instance lazy beta delta [foo bar]. This short name can then be used
+ in ``Eval`` :n:`@ident` ``in`` ... or ``eval`` directives. This command
+ accepts the
+ Local modifier, for discarding this reduction name at the end of the
+ file or module. For the moment the name cannot be qualified. In
+ particular declaring the same name in several modules or in several
+ functor applications will be refused if these declarations are not
+ local. The name :n:`@ident` cannot be used directly as an Ltac tactic, but
+ nothing prevents the user to also perform a
+ ``Ltac`` `ident` ``:=`` `convtactic`.
-See also: sections :ref:`performingcomputations`
+ See also: sections :ref:`performingcomputations`
.. _controlling-locality-of-commands:
@@ -1320,8 +1204,8 @@ Controlling the locality of commands
-----------------------------------------
-.. cmd:: Local @command.
-.. cmd:: Global @command.
+.. cmd:: Local @command
+.. cmd:: Global @command
Some commands support a Local or Global prefix modifier to control the
scope of their effect. There are four kinds of commands:
@@ -1330,28 +1214,29 @@ scope of their effect. There are four kinds of commands:
+ Commands whose default is to extend their effect both outside the
section and the module or library file they occur in. For these
commands, the Local modifier limits the effect of the command to the
- current section or module it occurs in. As an example, the ``Coercion``
- (see Section :ref:`coercions`) and ``Strategy`` (see :ref:`here <vernac-strategy>`)
- commands belong to this category.
+ current section or module it occurs in. As an example, the :cmd:`Coercion`
+ and :cmd:`Strategy` commands belong to this category.
+ Commands whose default behavior is to stop their effect at the end
of the section they occur in but to extent their effect outside the module or
library file they occur in. For these commands, the Local modifier limits the
effect of the command to the current module if the command does not occur in a
section and the Global modifier extends the effect outside the current
sections and current module if the command occurs in a section. As an example,
- the :cmd:`Implicit Arguments`, :cmd:`Ltac` or :cmd:`Notation` commands belong
+ the :cmd:`Arguments`, :cmd:`Ltac` or :cmd:`Notation` commands belong
to this category. Notice that a subclass of these commands do not support
extension of their scope outside sections at all and the Global is not
applicable to them.
+ Commands whose default behavior is to stop their effect at the end
- of the section or module they occur in. For these commands, the Global
+ of the section or module they occur in. For these commands, the ``Global``
modifier extends their effect outside the sections and modules they
- occurs in. The ``Transparent`` and ``Opaque`` (see Section :ref:`vernac-controlling-the-reduction-strategies`) commands belong to this category.
+ occurs in. The :cmd:`Transparent` and :cmd:`Opaque`
+ (see Section :ref:`vernac-controlling-the-reduction-strategies`) commands
+ belong to this category.
+ Commands whose default behavior is to extend their effect outside
sections but not outside modules when they occur in a section and to
extend their effect outside the module or library file they occur in
when no section contains them.For these commands, the Local modifier
limits the effect to the current section or module while the Global
modifier extends the effect outside the module even when the command
- occurs in a section. The ``Set`` and ``Unset`` commands belong to this
+ occurs in a section. The :cmd:`Set` and :cmd:`Unset` commands belong to this
category.
diff --git a/doc/sphinx/user-extensions/proof-schemes.rst b/doc/sphinx/user-extensions/proof-schemes.rst
index e12e4d897..838926d65 100644
--- a/doc/sphinx/user-extensions/proof-schemes.rst
+++ b/doc/sphinx/user-extensions/proof-schemes.rst
@@ -26,6 +26,7 @@ induction for objects in type `identᵢ`.
natural in case of inductively defined relations.
.. cmdv:: Scheme Equality for @ident
+ :name: Scheme Equality
Tries to generate a Boolean equality and a proof of the decidability of the usual equality. If `ident`
involves some other inductive types, their equality has to be defined first.
@@ -105,15 +106,15 @@ Automatic declaration of schemes
.. opt:: Elimination Schemes
-It is possible to deactivate the automatic declaration of the
-induction principles when defining a new inductive type with the
-``Unset Elimination Schemes`` command. It may be reactivated at any time with
-``Set Elimination Schemes``.
+ It is possible to deactivate the automatic declaration of the
+ induction principles when defining a new inductive type with the
+ ``Unset Elimination Schemes`` command. It may be reactivated at any time with
+ ``Set Elimination Schemes``.
.. opt:: Nonrecursive Elimination Schemes
-This option controls whether types declared with the keywords :cmd:`Variant` and
-:cmd:`Record` get an automatic declaration of the induction principles.
+ This option controls whether types declared with the keywords :cmd:`Variant` and
+ :cmd:`Record` get an automatic declaration of the induction principles.
.. opt:: Case Analysis Schemes
@@ -124,8 +125,8 @@ This option controls whether types declared with the keywords :cmd:`Variant` and
.. opt:: Decidable Equality Schemes
-These flags control the automatic declaration of those Boolean equalities (see
-the second variant of ``Scheme``).
+ These flags control the automatic declaration of those Boolean equalities (see
+ the second variant of ``Scheme``).
.. warning::
diff --git a/doc/sphinx/user-extensions/syntax-extensions.rst b/doc/sphinx/user-extensions/syntax-extensions.rst
index c4a7121ce..3b95a37ed 100644
--- a/doc/sphinx/user-extensions/syntax-extensions.rst
+++ b/doc/sphinx/user-extensions/syntax-extensions.rst
@@ -200,7 +200,7 @@ need to force the parsing level of y, as follows.
For the sake of factorization with Coq predefined rules, simple rules
have to be observed for notations starting with a symbol: e.g. rules
starting with “{” or “(” should be put at level 0. The list of Coq
-predefined notations can be found in Chapter 3.
+predefined notations can be found in Chapter :ref:`thecoqlibrary`.
.. cmd:: Print Grammar constr.
@@ -916,9 +916,8 @@ Binding arguments of a constant to an interpretation scope
.. seealso::
- :cmd:`About @qualid`
- The command to show the scopes bound to the arguments of a
- function is described in Section 2.
+ The command :cmd:`About` can be used to show the scopes bound to the
+ arguments of a function.
.. note::
diff --git a/doc/tools/coqrst/coqdoc/main.py b/doc/tools/coqrst/coqdoc/main.py
index d464f75bb..a004959eb 100644
--- a/doc/tools/coqrst/coqdoc/main.py
+++ b/doc/tools/coqrst/coqdoc/main.py
@@ -32,8 +32,9 @@ COQDOC_OPTIONS = ['--body-only', '--no-glob', '--no-index', '--no-externals',
COQDOC_SYMBOLS = ["->", "<-", "<->", "=>", "<=", ">=", "<>", "~", "/\\", "\\/", "|-", "*", "forall", "exists"]
COQDOC_HEADER = "".join("(** remove printing {} *)".format(s) for s in COQDOC_SYMBOLS)
-def coqdoc(coq_code, coqdoc_bin = os.path.join(os.getenv("COQBIN"),"coqdoc")):
+def coqdoc(coq_code, coqdoc_bin=None):
"""Get the output of coqdoc on coq_code."""
+ coqdoc_bin = coqdoc_bin or os.path.join(os.getenv("COQBIN"), "coqdoc")
fd, filename = mkstemp(prefix="coqdoc-", suffix=".v")
try:
os.write(fd, COQDOC_HEADER.encode("utf-8"))
diff --git a/doc/tools/coqrst/coqdomain.py b/doc/tools/coqrst/coqdomain.py
index f09ed4b55..606d725bf 100644
--- a/doc/tools/coqrst/coqdomain.py
+++ b/doc/tools/coqrst/coqdomain.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
##########################################################################
## # The Coq Proof Assistant / The Coq Development Team ##
## v # INRIA, CNRS and contributors - Copyright 1999-2018 ##
@@ -57,30 +58,37 @@ def make_target(objtype, targetid):
return "coq:{}.{}".format(objtype, targetid)
class CoqObject(ObjectDescription):
- """A generic Coq object; all Coq objects are subclasses of this.
+ """A generic Coq object for Sphinx; all Coq objects are subclasses of this.
The fields and methods to override are listed at the top of this class'
implementation. Each object supports the :name: option, which gives an
explicit name to link to.
- See the documentation of CoqDomain for high-level information.
+ See the comments and docstrings in CoqObject for more information.
"""
- # The semantic domain in which this object lives.
+ # The semantic domain in which this object lives (eg. “tac”, “cmd”, “chm”…).
# It matches exactly one of the roles used for cross-referencing.
- subdomain = None
+ subdomain = None # type: str
- # The suffix to use in indices for objects of this type
- index_suffix = None
+ # The suffix to use in indices for objects of this type (eg. “(tac)”)
+ index_suffix = None # type: str
# The annotation to add to headers of objects of this type
- annotation = None
+ # (eg. “Command”, “Theorem”)
+ annotation = None # type: str
def _name_from_signature(self, signature): # pylint: disable=no-self-use, unused-argument
"""Convert a signature into a name to link to.
+ ‘Signature’ is Sphinx parlance for an object's header (think “type
+ signature”); for example, the signature of the simplest form of the
+ ``exact`` tactic is ``exact @id``.
+
Returns None by default, in which case no name will be automatically
- generated.
+ generated. This is a convenient way to automatically generate names
+ (link targets) without having to write explicit names everywhere.
+
"""
return None
@@ -100,7 +108,7 @@ class CoqObject(ObjectDescription):
def handle_signature(self, signature, signode):
"""Prefix signature with the proper annotation, then render it using
- _render_signature.
+ ``_render_signature`` (for example, add “Command” in front of commands).
:returns: the name given to the resulting node, if any
"""
@@ -110,11 +118,6 @@ class CoqObject(ObjectDescription):
self._render_signature(signature, signode)
return self.options.get("name") or self._name_from_signature(signature)
- @property
- def _index_suffix(self):
- if self.index_suffix:
- return " " + self.index_suffix
-
def _record_name(self, name, target_id):
"""Record a name, mapping it to target_id
@@ -141,12 +144,14 @@ class CoqObject(ObjectDescription):
return targetid
def _add_index_entry(self, name, target):
- """Add name (with target) to the main index."""
- index_text = name + self._index_suffix
+ """Add `name` (pointing to `target`) to the main index."""
+ index_text = name
+ if self.index_suffix:
+ index_text += " " + self.index_suffix
self.indexnode['entries'].append(('single', index_text, target, '', None))
def add_target_and_index(self, name, _, signode):
- """Create a target and an index entry for name"""
+ """Attach a link target to `signode` and an index entry for `name`."""
if name:
target = self._add_target(signode, name)
# remove trailing . , found in commands, but not ... (ellipsis)
@@ -156,31 +161,44 @@ class CoqObject(ObjectDescription):
return target
class PlainObject(CoqObject):
- """A base class for objects whose signatures should be rendered literaly."""
+ """A base class for objects whose signatures should be rendered literally."""
def _render_signature(self, signature, signode):
signode += addnodes.desc_name(signature, signature)
class NotationObject(CoqObject):
- """A base class for objects whose signatures should be rendered as nested boxes."""
+ """A base class for objects whose signatures should be rendered as nested boxes.
+
+ Objects that inherit from this class can use the notation grammar (“{+ …}”,
+ “@…”, etc.) in their signature.
+ """
def _render_signature(self, signature, signode):
position = self.state_machine.get_source_and_line(self.lineno)
tacn_node = parse_notation(signature, *position)
signode += addnodes.desc_name(signature, '', tacn_node)
-class TacticObject(PlainObject):
- """An object to represent Coq tactics"""
- subdomain = "tac"
- index_suffix = "(tac)"
- annotation = None
-
class GallinaObject(PlainObject):
- """An object to represent Coq theorems"""
+ r"""A theorem.
+
+ Example::
+
+ .. thm:: Bound on the ceiling function
+
+ Let :math:`p` be an integer and :math:`c` a rational constant. Then
+ :math:`p \ge c \rightarrow p \ge \lceil{c}\rceil`.
+ """
subdomain = "thm"
index_suffix = "(thm)"
annotation = "Theorem"
class VernacObject(NotationObject):
- """An object to represent Coq commands"""
+ """A Coq command.
+
+ Example::
+
+ .. cmd:: Infix "@symbol" := @term ({+, @modifier}).
+
+ This command is equivalent to :n:`…`.
+ """
subdomain = "cmd"
index_suffix = "(cmd)"
annotation = "Command"
@@ -191,7 +209,20 @@ class VernacObject(NotationObject):
return m.group(0).strip()
class VernacVariantObject(VernacObject):
- """An object to represent variants of Coq commands"""
+ """A variant of a Coq command.
+
+ Example::
+
+ .. cmd:: Axiom @ident : @term.
+
+ This command links :token:`term` to the name :token:`term` as its specification in
+ the global context. The fact asserted by :token:`term` is thus assumed as a
+ postulate.
+
+ .. cmdv:: Parameter @ident : @term.
+
+ This is equivalent to :n:`Axiom @ident : @term`.
+ """
index_suffix = "(cmdv)"
annotation = "Variant"
@@ -199,18 +230,49 @@ class VernacVariantObject(VernacObject):
return None
class TacticNotationObject(NotationObject):
- """An object to represent Coq tactic notations"""
+ """A tactic, or a tactic notation.
+
+ Example::
+
+ .. tacn:: do @num @expr
+
+ :token:`expr` is evaluated to ``v`` which must be a tactic value. …
+ """
subdomain = "tacn"
index_suffix = "(tacn)"
annotation = None
class TacticNotationVariantObject(TacticNotationObject):
- """An object to represent variants of Coq tactic notations"""
+ """A variant of a tactic.
+
+ Example::
+
+ .. tacn:: fail
+
+ This is the always-failing tactic: it does not solve any goal. It is
+ useful for defining other tacticals since it can be caught by
+ :tacn:`try`, :tacn:`repeat`, :tacn:`match goal`, or the branching
+ tacticals. …
+
+ .. tacv:: fail @natural
+
+ The number is the failure level. If no level is specified, it
+ defaults to 0. …
+ """
index_suffix = "(tacnv)"
annotation = "Variant"
class OptionObject(NotationObject):
- """An object to represent Coq options"""
+ """A Coq option.
+
+ Example::
+
+ .. opt:: Nonrecursive Elimination Schemes
+
+ This option controls whether types declared with the keywords
+ :cmd:`Variant` and :cmd:`Record` get an automatic declaration of the
+ induction principles.
+ """
subdomain = "opt"
index_suffix = "(opt)"
annotation = "Option"
@@ -219,7 +281,13 @@ class OptionObject(NotationObject):
return stringify_with_ellipses(signature)
class ProductionObject(NotationObject):
- """An object to represent grammar productions"""
+ """Grammar productions.
+
+ This is useful if you intend to document individual grammar productions.
+ Otherwise, use Sphinx's `production lists
+ <http://www.sphinx-doc.org/en/stable/markup/para.html#directive-productionlist>`_.
+ """
+ # FIXME (CPC): I have no idea what this does :/ Someone should add an example.
subdomain = "prodn"
index_suffix = None
annotation = None
@@ -258,7 +326,22 @@ class ProductionObject(NotationObject):
return [idx, node]
class ExceptionObject(NotationObject):
- """An object to represent Coq errors."""
+ """An error raised by a Coq command or tactic.
+
+ This commonly appears nested in the ``.. tacn::`` that raises the
+ exception.
+
+ Example::
+
+ .. tacv:: assert @form by @tactic
+
+ This tactic applies :n:`@tactic` to solve the subgoals generated by
+ ``assert``.
+
+ .. exn:: Proof is not complete
+
+ Raised if :n:`@tactic` does not fully solve the goal.
+ """
subdomain = "exn"
index_suffix = "(err)"
annotation = "Error"
@@ -269,7 +352,19 @@ class ExceptionObject(NotationObject):
return stringify_with_ellipses(signature)
class WarningObject(NotationObject):
- """An object to represent Coq warnings."""
+ """An warning raised by a Coq command or tactic..
+
+ Do not mistake this for ``.. warning::``; this directive is for warning
+ messages produced by Coq.
+
+
+ Example::
+
+ .. warn:: Ambiguous path
+
+ When the coercion :token:`qualid` is added to the inheritance graph, non
+ valid coercion paths are ignored.
+ """
subdomain = "warn"
index_suffix = "(warn)"
annotation = "Warning"
@@ -280,14 +375,33 @@ class WarningObject(NotationObject):
def NotationRole(role, rawtext, text, lineno, inliner, options={}, content=[]):
#pylint: disable=unused-argument, dangerous-default-value
- """And inline role for notations"""
+ """Any text using the notation syntax (``@id``, ``{+, …}``, etc.).
+
+ Use this to explain tactic equivalences. For example, you might write
+ this::
+
+ :n:`generalize @term as @ident` is just like :n:`generalize @term`, but
+ it names the introduced hypothesis :token:`ident`.
+
+ Note that this example also uses ``:token:``. That's because ``ident`` is
+ defined in the the Coq manual as a grammar production, and ``:token:``
+ creates a link to that. When referring to a placeholder that happens to be
+ a grammar production, ``:token:`…``` is typically preferable to ``:n:`@…```.
+ """
notation = utils.unescape(text, 1)
position = inliner.reporter.get_source_and_line(lineno)
return [nodes.literal(rawtext, '', parse_notation(notation, *position, rawtext=rawtext))], []
def coq_code_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
#pylint: disable=dangerous-default-value
- """And inline role for Coq source code"""
+ """Coq code.
+
+ Use this for Gallina and Ltac snippets::
+
+ :g:`apply plus_comm; reflexivity`
+ :g:`Set Printing All.`
+ :g:`forall (x: t), P(x)`
+ """
options['language'] = 'Coq'
return code_role(role, rawtext, text, lineno, inliner, options, content)
## Too heavy:
@@ -300,15 +414,14 @@ def coq_code_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
# node = nodes.literal(rawtext, '', *highlight_using_coqdoc(code), classes=classes)
# return [node], []
-# TODO pass different languages?
-LtacRole = GallinaRole = VernacRole = coq_code_role
+CoqCodeRole = coq_code_role
class CoqtopDirective(Directive):
"""A reST directive to describe interactions with Coqtop.
Usage::
- .. coqtop:: (options)+
+ .. coqtop:: options…
Coq code to send to coqtop
@@ -321,20 +434,28 @@ class CoqtopDirective(Directive):
Here is a list of permissible options:
- Display
- - ‘all’: Display input and output
- - ‘in’: Display only input
- - ‘out’: Display only output
- - ‘none’: Display neither (useful for setup commands)
- Behaviour
- - ‘reset’: Send a `Reset Initial` command before running this block
- - ‘undo’: Send an `Undo n` (n=number of sentences) command after running
- all the commands in this block
+ - Display options
+
+ - ``all``: Display input and output
+ - ``in``: Display only input
+ - ``out``: Display only output
+ - ``none``: Display neither (useful for setup commands)
+
+ - Behavior options
+
+ - ``reset``: Send a ``Reset Initial`` command before running this block
+ - ``undo``: Send an ``Undo n`` (``n`` = number of sentences) command after
+ running all the commands in this block
+
+ ``coqtop``\ 's state is preserved across consecutive ``.. coqtop::`` blocks
+ of the same document (``coqrst`` creates a single ``coqtop`` process per
+ reST source file). Use the ``reset`` option to reset Coq's state.
"""
has_content = True
required_arguments = 0
optional_arguments = 1
final_argument_whitespace = True
+ directive_name = "coqtop"
def run(self):
# Uses a ‘container’ instead of a ‘literal_block’ to disable
@@ -349,12 +470,26 @@ class CoqtopDirective(Directive):
return [node]
class CoqdocDirective(Directive):
- """A reST directive to display Coqtop-formatted source code"""
+ """A reST directive to display Coqtop-formatted source code.
+
+ Usage::
+
+ .. coqdoc::
+
+ Coq code to highlight
+
+ Example::
+
+ .. coqdoc::
+
+ Definition test := 1.
+ """
# TODO implement this as a Pygments highlighter?
has_content = True
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = True
+ directive_name = "coqdoc"
def run(self):
# Uses a ‘container’ instead of a ‘literal_block’ to disable
@@ -365,8 +500,24 @@ class CoqdocDirective(Directive):
return [wrapper]
class ExampleDirective(BaseAdmonition):
- """A reST directive for examples"""
+ """A reST directive for examples.
+
+ This behaves like a generic admonition; see
+ http://docutils.sourceforge.net/docs/ref/rst/directives.html#generic-admonition
+ for more details.
+
+ Example::
+
+ .. example:: Adding a hint to a database
+
+ The following adds ``plus_comm`` to the ``plu`` database:
+
+ .. coqdoc::
+
+ Hint Resolve plus_comm : plu.
+ """
node_class = nodes.admonition
+ directive_name = "example"
def run(self):
# ‘BaseAdmonition’ checks whether ‘node_class’ is ‘nodes.admonition’,
@@ -380,8 +531,17 @@ class ExampleDirective(BaseAdmonition):
class PreambleDirective(MathDirective):
r"""A reST directive for hidden math.
- Mostly useful to let MathJax know about `\def`s and `\newcommand`s
+ Mostly useful to let MathJax know about `\def`\ s and `\newcommand`\ s.
+
+ Example::
+
+ .. preamble::
+
+ \newcommand{\paren}[#1]{\left(#1\right)}
"""
+
+ directive_name = "preamble"
+
def run(self):
self.options['nowrap'] = True
[node] = super().run()
@@ -389,14 +549,17 @@ class PreambleDirective(MathDirective):
return [node]
class InferenceDirective(Directive):
- r"""A small example of what directives let you do in Sphinx.
+ r"""A reST directive to format inference rules.
+
+ This also serves as a small illustration of the way to create new Sphinx
+ directives.
Usage::
.. inference:: name
- \n-separated premisses
- ----------------------
+ newline-separated premisses
+ ------------------------
conclusion
Example::
@@ -413,6 +576,7 @@ class InferenceDirective(Directive):
optional_arguments = 0
has_content = True
final_argument_whitespace = True
+ directive_name = "inference"
def make_math_node(self, latex):
node = displaymath()
@@ -613,7 +777,7 @@ class CoqSubdomainsIndex(Index):
Just as in the original manual, we want to have separate indices for each
Coq subdomain (tactics, commands, options, etc)"""
- name, localname, shortname, subdomains = None, None, None, None # Must be overwritten
+ name, localname, shortname, subdomains = None, None, None, [] # Must be overwritten
def generate(self, docnames=None):
content = defaultdict(list)
@@ -635,7 +799,7 @@ class CoqVernacIndex(CoqSubdomainsIndex):
name, localname, shortname, subdomains = "cmdindex", "Command Index", "commands", ["cmd"]
class CoqTacticIndex(CoqSubdomainsIndex):
- name, localname, shortname, subdomains = "tacindex", "Tactic Index", "tactics", ["tac", "tacn"]
+ name, localname, shortname, subdomains = "tacindex", "Tactic Index", "tactics", ["tacn"]
class CoqOptionIndex(CoqSubdomainsIndex):
name, localname, shortname, subdomains = "optindex", "Option Index", "options", ["opt"]
@@ -665,10 +829,18 @@ class IndexXRefRole(XRefRole):
return title, target
def GrammarProductionRole(typ, rawtext, text, lineno, inliner, options={}, content=[]):
- """An inline role to declare grammar productions that are not in fact included
- in a `productionlist` directive.
+ """A grammar production not included in a ``productionlist`` directive.
- Useful to informally introduce a production, as part of running text
+ Useful to informally introduce a production, as part of running text.
+
+ Example::
+
+ :production:`string` indicates a quoted string.
+
+ You're not likely to use this role very commonly; instead, use a
+ `production list
+ <http://www.sphinx-doc.org/en/stable/markup/para.html#directive-productionlist>`_
+ and reference its tokens using ``:token:`…```.
"""
#pylint: disable=dangerous-default-value, unused-argument
env = inliner.document.settings.env
@@ -681,6 +853,8 @@ def GrammarProductionRole(typ, rawtext, text, lineno, inliner, options={}, conte
env.domaindata['std']['objects']['token', text] = env.docname, targetid
return [node], []
+GrammarProductionRole.role_name = "production"
+
class CoqDomain(Domain):
"""A domain to document Coq code.
@@ -703,7 +877,6 @@ class CoqDomain(Domain):
# ObjType (= directive type) → (Local name, *xref-roles)
'cmd': ObjType('cmd', 'cmd'),
'cmdv': ObjType('cmdv', 'cmd'),
- 'tac': ObjType('tac', 'tac'),
'tacn': ObjType('tacn', 'tacn'),
'tacv': ObjType('tacv', 'tacn'),
'opt': ObjType('opt', 'opt'),
@@ -720,7 +893,6 @@ class CoqDomain(Domain):
# the same role.
'cmd': VernacObject,
'cmdv': VernacVariantObject,
- 'tac': TacticObject,
'tacn': TacticNotationObject,
'tacv': TacticNotationVariantObject,
'opt': OptionObject,
@@ -732,23 +904,18 @@ class CoqDomain(Domain):
roles = {
# Each of these roles lives in a different semantic “subdomain”
- 'cmd': XRefRole(),
- 'tac': XRefRole(),
- 'tacn': XRefRole(),
- 'opt': XRefRole(),
- 'thm': XRefRole(),
- 'prodn' : XRefRole(),
- 'exn': XRefRole(),
- 'warn': XRefRole(),
+ 'cmd': XRefRole(warn_dangling=True),
+ 'tacn': XRefRole(warn_dangling=True),
+ 'opt': XRefRole(warn_dangling=True),
+ 'thm': XRefRole(warn_dangling=True),
+ 'prodn' : XRefRole(warn_dangling=True),
+ 'exn': XRefRole(warn_dangling=True),
+ 'warn': XRefRole(warn_dangling=True),
# This one is special
'index': IndexXRefRole(),
# These are used for highlighting
- 'notation': NotationRole,
- 'gallina': GallinaRole,
- 'ltac': LtacRole,
'n': NotationRole,
- 'g': GallinaRole,
- 'l': LtacRole, #FIXME unused?
+ 'g': CoqCodeRole
}
indices = [CoqVernacIndex, CoqTacticIndex, CoqOptionIndex, CoqGallinaIndex, CoqProductionIndex, CoqExceptionIndex]
@@ -759,7 +926,6 @@ class CoqDomain(Domain):
# others, such as “version”
'objects' : { # subdomain → name → docname, objtype, targetid
'cmd': {},
- 'tac': {},
'tacn': {},
'opt': {},
'thm': {},
@@ -829,11 +995,18 @@ def simplify_source_code_blocks_for_latex(app, doctree, fromdocname): # pylint:
for node in doctree.traverse(is_coqtop_or_coqdoc_block):
if is_html:
node.rawsource = '' # Prevent pygments from kicking in
+ elif 'coqtop-hidden' in node['classes']:
+ node.parent.remove(node)
else:
- if 'coqtop-hidden' in node['classes']:
- node.parent.remove(node)
- else:
- node.replace_self(nodes.literal_block(node.rawsource, node.rawsource, language="Coq"))
+ node.replace_self(nodes.literal_block(node.rawsource, node.rawsource, language="Coq"))
+
+COQ_ADDITIONAL_DIRECTIVES = [CoqtopDirective,
+ CoqdocDirective,
+ ExampleDirective,
+ InferenceDirective,
+ PreambleDirective]
+
+COQ_ADDITIONAL_ROLES = [GrammarProductionRole]
def setup(app):
"""Register the Coq domain"""
@@ -845,12 +1018,13 @@ def setup(app):
# Add domain, directives, and roles
app.add_domain(CoqDomain)
- app.add_role("production", GrammarProductionRole)
- app.add_directive("coqtop", CoqtopDirective)
- app.add_directive("coqdoc", CoqdocDirective)
- app.add_directive("example", ExampleDirective)
- app.add_directive("inference", InferenceDirective)
- app.add_directive("preamble", PreambleDirective)
+
+ for role in COQ_ADDITIONAL_ROLES:
+ app.add_role(role.role_name, role)
+
+ for directive in COQ_ADDITIONAL_DIRECTIVES:
+ app.add_directive(directive.directive_name, directive)
+
app.add_transform(CoqtopBlocksTransform)
app.connect('doctree-resolved', simplify_source_code_blocks_for_latex)
diff --git a/doc/tools/coqrst/regen_readme.py b/doc/tools/coqrst/regen_readme.py
new file mode 100755
index 000000000..e56882a52
--- /dev/null
+++ b/doc/tools/coqrst/regen_readme.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+"""Rebuild sphinx/README.rst from sphinx/README.template.rst."""
+
+import re
+from os import sys, path
+
+SCRIPT_DIR = path.dirname(path.abspath(__file__))
+if __name__ == "__main__" and __package__ is None:
+ sys.path.append(path.dirname(SCRIPT_DIR))
+
+import sphinx
+from coqrst import coqdomain
+
+README_ROLES_MARKER = "[ROLES]"
+README_OBJECTS_MARKER = "[OBJECTS]"
+README_DIRECTIVES_MARKER = "[DIRECTIVES]"
+
+FIRST_LINE_BLANKS = re.compile("^(.*)\n *\n")
+def format_docstring(template, obj, *strs):
+ docstring = obj.__doc__.strip()
+ strs = strs + (FIRST_LINE_BLANKS.sub(r"\1\n", docstring),)
+ return template.format(*strs)
+
+SPHINX_DIR = path.join(SCRIPT_DIR, "../../sphinx/")
+README_PATH = path.join(SPHINX_DIR, "README.rst")
+README_TEMPLATE_PATH = path.join(SPHINX_DIR, "README.template.rst")
+
+def notation_symbol(d):
+ return " :black_nib:" if issubclass(d, coqdomain.NotationObject) else ""
+
+def regen_readme():
+ objects_docs = [format_docstring("``.. {}::``{} {}", obj, objname, notation_symbol(obj))
+ for objname, obj in sorted(coqdomain.CoqDomain.directives.items())]
+
+ roles = ([(name, cls)
+ for name, cls in sorted(coqdomain.CoqDomain.roles.items())
+ if not isinstance(cls, (sphinx.roles.XRefRole, coqdomain.IndexXRefRole))] +
+ [(fn.role_name, fn)
+ for fn in coqdomain.COQ_ADDITIONAL_ROLES])
+ roles_docs = [format_docstring("``:{}:`` {}", role, name)
+ for (name, role) in roles]
+
+ directives_docs = [format_docstring("``.. {}::`` {}", d, d.directive_name)
+ for d in coqdomain.COQ_ADDITIONAL_DIRECTIVES]
+
+ with open(README_TEMPLATE_PATH, encoding="utf-8") as readme:
+ contents = readme.read()
+
+ with open(README_PATH, mode="w", encoding="utf-8") as readme:
+ readme.write(contents
+ .replace(README_ROLES_MARKER, "\n\n".join(roles_docs))
+ .replace(README_OBJECTS_MARKER, "\n\n".join(objects_docs))
+ .replace(README_DIRECTIVES_MARKER, "\n\n".join(directives_docs)))
+
+if __name__ == '__main__':
+ regen_readme()
diff --git a/doc/tools/coqrst/repl/coqtop.py b/doc/tools/coqrst/repl/coqtop.py
index efb5cb550..aeadce4c4 100644
--- a/doc/tools/coqrst/repl/coqtop.py
+++ b/doc/tools/coqrst/repl/coqtop.py
@@ -41,7 +41,9 @@ class CoqTop:
the ansicolors module)
:param args: Additional arugments to coqtop.
"""
- self.coqtop_bin = coqtop_bin or os.path.join(os.getenv('COQBIN'),"coqtop")
+ 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.coqtop = None
diff --git a/doc/tutorial/Tutorial.tex b/doc/tutorial/Tutorial.tex
deleted file mode 100644
index 77ce8574f..000000000
--- a/doc/tutorial/Tutorial.tex
+++ /dev/null
@@ -1,1575 +0,0 @@
-\documentclass[11pt,a4paper]{book}
-\usepackage[T1]{fontenc}
-\usepackage[utf8]{inputenc}
-\usepackage{textcomp}
-\usepackage{pslatex}
-\usepackage{hyperref}
-
-\input{../common/version.tex}
-\input{../common/macros.tex}
-\input{../common/title.tex}
-
-%\makeindex
-
-\begin{document}
-\coverpage{A Tutorial}{Gérard Huet, Gilles Kahn and Christine Paulin-Mohring}{}
-
-%\tableofcontents
-
-\chapter*{Getting started}
-
-\Coq{} is a Proof Assistant for a Logical Framework known as the Calculus
-of Inductive Constructions. It allows the interactive construction of
-formal proofs, and also the manipulation of functional programs
-consistently with their specifications. It runs as a computer program
-on many architectures.
-
-It is available with a variety of user interfaces. The present
-document does not attempt to present a comprehensive view of all the
-possibilities of \Coq, but rather to present in the most elementary
-manner a tutorial on the basic specification language, called Gallina,
-in which formal axiomatisations may be developed, and on the main
-proof tools. For more advanced information, the reader could refer to
-the \Coq{} Reference Manual or the \textit{Coq'Art}, a book by Y.
-Bertot and P. Castéran on practical uses of the \Coq{} system.
-
-Instructions on installation procedures, as well as more comprehensive
-documentation, may be found in the standard distribution of \Coq,
-which may be obtained from \Coq{} web site
-\url{https://coq.inria.fr/}\footnote{You can report any bug you find
-while using \Coq{} at \url{https://coq.inria.fr/bugs}. Make sure to
-always provide a way to reproduce it and to specify the exact version
-you used. You can get this information by running \texttt{coqc -v}}.
-\Coq{} is distributed together with a graphical user interface called
-CoqIDE. Alternative interfaces exist such as
-Proof General\footnote{See \url{https://proofgeneral.github.io/}.}.
-
-In the following examples, lines preceded by the prompt \verb:Coq < :
-represent user input, terminated by a period.
-The following lines usually show \Coq's answer.
-When used from a graphical user interface such as
-CoqIDE, the prompt is not displayed: user input is given in one window
-and \Coq's answers are displayed in a different window.
-
-\chapter{Basic Predicate Calculus}
-
-\section{An overview of the specification language Gallina}
-
-A formal development in Gallina consists in a sequence of {\sl declarations}
-and {\sl definitions}.
-
-\subsection{Declarations}
-
-A declaration associates a {\sl name} with a {\sl specification}.
-A name corresponds roughly to an identifier in a programming
-language, i.e. to a string of letters, digits, and a few ASCII symbols like
-underscore (\verb"_") and prime (\verb"'"), starting with a letter.
-We use case distinction, so that the names \verb"A" and \verb"a" are distinct.
-Certain strings are reserved as key-words of \Coq, and thus are forbidden
-as user identifiers.
-
-A specification is a formal expression which classifies the notion which is
-being declared. There are basically three kinds of specifications:
-{\sl logical propositions}, {\sl mathematical collections}, and
-{\sl abstract types}. They are classified by the three basic sorts
-of the system, called respectively \verb:Prop:, \verb:Set:, and
-\verb:Type:, which are themselves atomic abstract types.
-
-Every valid expression $e$ in Gallina is associated with a specification,
-itself a valid expression, called its {\sl type} $\tau(E)$. We write
-$e:\tau(E)$ for the judgment that $e$ is of type $E$.
-You may request \Coq{} to return to you the type of a valid expression by using
-the command \verb:Check::
-
-\begin{coq_eval}
-Set Printing Width 60.
-\end{coq_eval}
-
-\begin{coq_example}
-Check O.
-\end{coq_example}
-
-Thus we know that the identifier \verb:O: (the name `O', not to be
-confused with the numeral `0' which is not a proper identifier!) is
-known in the current context, and that its type is the specification
-\verb:nat:. This specification is itself classified as a mathematical
-collection, as we may readily check:
-
-\begin{coq_example}
-Check nat.
-\end{coq_example}
-
-The specification \verb:Set: is an abstract type, one of the basic
-sorts of the Gallina language, whereas the notions $nat$ and $O$ are
-notions which are defined in the arithmetic prelude,
-automatically loaded when running the \Coq{} system.
-
-We start by introducing a so-called section name. The role of sections
-is to structure the modelisation by limiting the scope of parameters,
-hypotheses and definitions. It will also give a convenient way to
-reset part of the development.
-
-\begin{coq_example}
-Section Declaration.
-\end{coq_example}
-With what we already know, we may now enter in the system a declaration,
-corresponding to the informal mathematics {\sl let n be a natural
- number}.
-
-\begin{coq_example}
-Variable n : nat.
-\end{coq_example}
-
-If we want to translate a more precise statement, such as
-{\sl let n be a positive natural number},
-we have to add another declaration, which will declare explicitly the
-hypothesis \verb:Pos_n:, with specification the proper logical
-proposition:
-\begin{coq_example}
-Hypothesis Pos_n : (gt n 0).
-\end{coq_example}
-
-Indeed we may check that the relation \verb:gt: is known with the right type
-in the current context:
-
-\begin{coq_example}
-Check gt.
-\end{coq_example}
-
-which tells us that \texttt{gt} is a function expecting two arguments of
-type \texttt{nat} in order to build a logical proposition.
-What happens here is similar to what we are used to in a functional
-programming language: we may compose the (specification) type \texttt{nat}
-with the (abstract) type \texttt{Prop} of logical propositions through the
-arrow function constructor, in order to get a functional type
-\texttt{nat -> Prop}:
-\begin{coq_example}
-Check (nat -> Prop).
-\end{coq_example}
-which may be composed once more with \verb:nat: in order to obtain the
-type \texttt{nat -> nat -> Prop} of binary relations over natural numbers.
-Actually the type \texttt{nat -> nat -> Prop} is an abbreviation for
-\texttt{nat -> (nat -> Prop)}.
-
-Functional notions may be composed in the usual way. An expression $f$
-of type $A\ra B$ may be applied to an expression $e$ of type $A$ in order
-to form the expression $(f~e)$ of type $B$. Here we get that
-the expression \verb:(gt n): is well-formed of type \texttt{nat -> Prop},
-and thus that the expression \verb:(gt n O):, which abbreviates
-\verb:((gt n) O):, is a well-formed proposition.
-\begin{coq_example}
-Check gt n O.
-\end{coq_example}
-
-\subsection{Definitions}
-
-The initial prelude contains a few arithmetic definitions:
-\texttt{nat} is defined as a mathematical collection (type \texttt{Set}),
-constants \texttt{O}, \texttt{S}, \texttt{plus}, are defined as objects of
-types respectively \texttt{nat}, \texttt{nat -> nat}, and \texttt{nat ->
-nat -> nat}.
-You may introduce new definitions, which link a name to a well-typed value.
-For instance, we may introduce the constant \texttt{one} as being defined
-to be equal to the successor of zero:
-\begin{coq_example}
-Definition one := (S O).
-\end{coq_example}
-We may optionally indicate the required type:
-\begin{coq_example}
-Definition two : nat := S one.
-\end{coq_example}
-
-Actually \Coq{} allows several possible syntaxes:
-\begin{coq_example}
-Definition three := S two : nat.
-\end{coq_example}
-
-Here is a way to define the doubling function, which expects an
-argument \verb:m: of type \verb:nat: in order to build its result as
-\verb:(plus m m)::
-
-\begin{coq_example}
-Definition double (m : nat) := plus m m.
-\end{coq_example}
-This introduces the constant \texttt{double} defined as the
-expression \texttt{fun m : nat => plus m m}.
-The abstraction introduced by \texttt{fun} is explained as follows.
-The expression \texttt{fun x : A => e} is well formed of type
-\texttt{A -> B} in a context whenever the expression \texttt{e} is
-well-formed of type \texttt{B} in the given context to which we add the
-declaration that \texttt{x} is of type \texttt{A}. Here \texttt{x} is a
-bound, or dummy variable in the expression \texttt{fun x : A => e}.
-For instance we could as well have defined \texttt{double} as
-\texttt{fun n : nat => (plus n n)}.
-
-Bound (local) variables and free (global) variables may be mixed.
-For instance, we may define the function which adds the constant \verb:n:
-to its argument as
-\begin{coq_example}
-Definition add_n (m:nat) := plus m n.
-\end{coq_example}
-However, note that here we may not rename the formal argument $m$ into $n$
-without capturing the free occurrence of $n$, and thus changing the meaning
-of the defined notion.
-
-Binding operations are well known for instance in logic, where they
-are called quantifiers. Thus we may universally quantify a
-proposition such as $m>0$ in order to get a universal proposition
-$\forall m\cdot m>0$. Indeed this operator is available in \Coq, with
-the following syntax: \texttt{forall m : nat, gt m O}. Similarly to the
-case of the functional abstraction binding, we are obliged to declare
-explicitly the type of the quantified variable. We check:
-\begin{coq_example}
-Check (forall m : nat, gt m 0).
-\end{coq_example}
-
-\begin{coq_eval}
-Reset Initial.
-Set Printing Width 60.
-Set Printing Compact Contexts.
-\end{coq_eval}
-
-\section{Introduction to the proof engine: Minimal Logic}
-
-In the following, we are going to consider various propositions, built
-from atomic propositions $A, B, C$. This may be done easily, by
-introducing these atoms as global variables declared of type \verb:Prop:.
-It is easy to declare several names with the same specification:
-\begin{coq_example}
-Section Minimal_Logic.
-Variables A B C : Prop.
-\end{coq_example}
-
-We shall consider simple implications, such as $A\ra B$, read as
-``$A$ implies $B$''. Note that we overload the arrow symbol, which
-has been used above as the functionality type constructor, and which
-may be used as well as propositional connective:
-\begin{coq_example}
-Check (A -> B).
-\end{coq_example}
-
-Let us now embark on a simple proof. We want to prove the easy tautology
-$((A\ra (B\ra C))\ra (A\ra B)\ra (A\ra C)$.
-We enter the proof engine by the command
-\verb:Goal:, followed by the conjecture we want to verify:
-\begin{coq_example}
-Goal (A -> B -> C) -> (A -> B) -> A -> C.
-\end{coq_example}
-
-The system displays the current goal below a double line, local hypotheses
-(there are none initially) being displayed above the line. We call
-the combination of local hypotheses with a goal a {\sl judgment}.
-We are now in an inner
-loop of the system, in proof mode.
-New commands are available in this
-mode, such as {\sl tactics}, which are proof combining primitives.
-A tactic operates on the current goal by attempting to construct a proof
-of the corresponding judgment, possibly from proofs of some
-hypothetical judgments, which are then added to the current
-list of conjectured judgments.
-For instance, the \verb:intro: tactic is applicable to any judgment
-whose goal is an implication, by moving the proposition to the left
-of the application to the list of local hypotheses:
-\begin{coq_example}
-intro H.
-\end{coq_example}
-
-Several introductions may be done in one step:
-\begin{coq_example}
-intros H' HA.
-\end{coq_example}
-
-We notice that $C$, the current goal, may be obtained from hypothesis
-\verb:H:, provided the truth of $A$ and $B$ are established.
-The tactic \verb:apply: implements this piece of reasoning:
-\begin{coq_example}
-apply H.
-\end{coq_example}
-
-We are now in the situation where we have two judgments as conjectures
-that remain to be proved. Only the first is listed in full, for the
-others the system displays only the corresponding subgoal, without its
-local hypotheses list. Note that \verb:apply: has kept the local
-hypotheses of its father judgment, which are still available for
-the judgments it generated.
-
-In order to solve the current goal, we just have to notice that it is
-exactly available as hypothesis $HA$:
-\begin{coq_example}
-exact HA.
-\end{coq_example}
-
-Now $H'$ applies:
-\begin{coq_example}
-apply H'.
-\end{coq_example}
-
-And we may now conclude the proof as before, with \verb:exact HA.:
-Actually, we may not bother with the name \verb:HA:, and just state that
-the current goal is solvable from the current local assumptions:
-\begin{coq_example}
-assumption.
-\end{coq_example}
-
-The proof is now finished. We are now going to ask \Coq{}'s kernel
-to check and save the proof.
-\begin{coq_example}
-Qed.
-\end{coq_example}
-
-Let us redo the same proof with a few variations. First of all we may name
-the initial goal as a conjectured lemma:
-\begin{coq_example}
-Lemma distr_impl : (A -> B -> C) -> (A -> B) -> A -> C.
-\end{coq_example}
-
-Next, we may omit the names of local assumptions created by the introduction
-tactics, they can be automatically created by the proof engine as new
-non-clashing names.
-\begin{coq_example}
-intros.
-\end{coq_example}
-
-The \verb:intros: tactic, with no arguments, effects as many individual
-applications of \verb:intro: as is legal.
-
-Then, we may compose several tactics together in sequence, or in parallel,
-through {\sl tacticals}, that is tactic combinators. The main constructions
-are the following:
-\begin{itemize}
-\item $T_1 ; T_2$ (read $T_1$ then $T_2$) applies tactic $T_1$ to the current
-goal, and then tactic $T_2$ to all the subgoals generated by $T_1$.
-\item $T; [T_1 | T_2 | ... | T_n]$ applies tactic $T$ to the current
-goal, and then tactic $T_1$ to the first newly generated subgoal,
-..., $T_n$ to the nth.
-\end{itemize}
-
-We may thus complete the proof of \verb:distr_impl: with one composite tactic:
-\begin{coq_example}
-apply H; [ assumption | apply H0; assumption ].
-\end{coq_example}
-
-You should be aware however that relying on automatically generated names is
-not robust to slight updates to this proof script. Consequently, it is
-discouraged in finished proof scripts. As for the composition of tactics with
-\texttt{:} it may hinder the readability of the proof script and it is also
-harder to see what's going on when replaying the proof because composed
-tactics are evaluated in one go.
-
-Actually, such an easy combination of tactics \verb:intro:, \verb:apply:
-and \verb:assumption: may be found completely automatically by an automatic
-tactic, called \verb:auto:, without user guidance:
-
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-\begin{coq_example}
-Lemma distr_impl : (A -> B -> C) -> (A -> B) -> A -> C.
-auto.
-\end{coq_example}
-
-Let us now save lemma \verb:distr_impl::
-\begin{coq_example}
-Qed.
-\end{coq_example}
-
-\section{Propositional Calculus}
-
-\subsection{Conjunction}
-
-We have seen how \verb:intro: and \verb:apply: tactics could be combined
-in order to prove implicational statements. More generally, \Coq{} favors a style
-of reasoning, called {\sl Natural Deduction}, which decomposes reasoning into
-so called {\sl introduction rules}, which tell how to prove a goal whose main
-operator is a given propositional connective, and {\sl elimination rules},
-which tell how to use an hypothesis whose main operator is the propositional
-connective. Let us show how to use these ideas for the propositional connectives
-\verb:/\: and \verb:\/:.
-
-\begin{coq_example}
-Lemma and_commutative : A /\ B -> B /\ A.
-intro H.
-\end{coq_example}
-
-We make use of the conjunctive hypothesis \verb:H: with the \verb:elim: tactic,
-which breaks it into its components:
-\begin{coq_example}
-elim H.
-\end{coq_example}
-
-We now use the conjunction introduction tactic \verb:split:, which splits the
-conjunctive goal into the two subgoals:
-\begin{coq_example}
-split.
-\end{coq_example}
-and the proof is now trivial. Indeed, the whole proof is obtainable as follows:
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-\begin{coq_example}
-Lemma and_commutative : A /\ B -> B /\ A.
-intro H; elim H; auto.
-Qed.
-\end{coq_example}
-
-The tactic \verb:auto: succeeded here because it knows as a hint the
-conjunction introduction operator \verb+conj+
-\begin{coq_example}
-Check conj.
-\end{coq_example}
-
-Actually, the tactic \verb+split+ is just an abbreviation for \verb+apply conj.+
-
-What we have just seen is that the \verb:auto: tactic is more powerful than
-just a simple application of local hypotheses; it tries to apply as well
-lemmas which have been specified as hints. A
-\verb:Hint Resolve: command registers a
-lemma as a hint to be used from now on by the \verb:auto: tactic, whose power
-may thus be incrementally augmented.
-
-\subsection{Disjunction}
-
-In a similar fashion, let us consider disjunction:
-
-\begin{coq_example}
-Lemma or_commutative : A \/ B -> B \/ A.
-intro H; elim H.
-\end{coq_example}
-
-Let us prove the first subgoal in detail. We use \verb:intro: in order to
-be left to prove \verb:B\/A: from \verb:A::
-
-\begin{coq_example}
-intro HA.
-\end{coq_example}
-
-Here the hypothesis \verb:H: is not needed anymore. We could choose to
-actually erase it with the tactic \verb:clear:; in this simple proof it
-does not really matter, but in bigger proof developments it is useful to
-clear away unnecessary hypotheses which may clutter your screen.
-\begin{coq_example}
-clear H.
-\end{coq_example}
-
-The tactic \verb:destruct: combines the effects of \verb:elim:, \verb:intros:,
-and \verb:clear::
-
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-\begin{coq_example}
-Lemma or_commutative : A \/ B -> B \/ A.
-intros H; destruct H.
-\end{coq_example}
-
-The disjunction connective has two introduction rules, since \verb:P\/Q:
-may be obtained from \verb:P: or from \verb:Q:; the two corresponding
-proof constructors are called respectively \verb:or_introl: and
-\verb:or_intror:; they are applied to the current goal by tactics
-\verb:left: and \verb:right: respectively. For instance:
-\begin{coq_example}
-right.
-trivial.
-\end{coq_example}
-The tactic \verb:trivial: works like \verb:auto: with the hints
-database, but it only tries those tactics that can solve the goal in one
-step.
-
-As before, all these tedious elementary steps may be performed automatically,
-as shown for the second symmetric case:
-
-\begin{coq_example}
-auto.
-\end{coq_example}
-
-However, \verb:auto: alone does not succeed in proving the full lemma, because
-it does not try any elimination step.
-It is a bit disappointing that \verb:auto: is not able to prove automatically
-such a simple tautology. The reason is that we want to keep
-\verb:auto: efficient, so that it is always effective to use.
-
-\subsection{Tauto}
-
-A complete tactic for propositional
-tautologies is indeed available in \Coq{} as the \verb:tauto: tactic.
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-\begin{coq_example}
-Lemma or_commutative : A \/ B -> B \/ A.
-tauto.
-Qed.
-\end{coq_example}
-
-It is possible to inspect the actual proof tree constructed by \verb:tauto:,
-using a standard command of the system, which prints the value of any notion
-currently defined in the context:
-\begin{coq_example}
-Print or_commutative.
-\end{coq_example}
-
-It is not easy to understand the notation for proof terms without some
-explanations. The \texttt{fun} prefix, such as \verb+fun H : A\/B =>+,
-corresponds
-to \verb:intro H:, whereas a subterm such as
-\verb:(or_intror: \verb:B H0):
-corresponds to the sequence of tactics \verb:apply or_intror; exact H0:.
-The generic combinator \verb:or_intror: needs to be instantiated by
-the two properties \verb:B: and \verb:A:. Because \verb:A: can be
-deduced from the type of \verb:H0:, only \verb:B: is printed.
-The two instantiations are effected automatically by the tactic
-\verb:apply: when pattern-matching a goal. The specialist will of course
-recognize our proof term as a $\lambda$-term, used as notation for the
-natural deduction proof term through the Curry-Howard isomorphism. The
-naive user of \Coq{} may safely ignore these formal details.
-
-Let us exercise the \verb:tauto: tactic on a more complex example:
-\begin{coq_example}
-Lemma distr_and : A -> B /\ C -> (A -> B) /\ (A -> C).
-tauto.
-Qed.
-\end{coq_example}
-
-\subsection{Classical reasoning}
-
-The tactic \verb:tauto: always comes back with an answer. Here is an example where it
-fails:
-\begin{coq_example}
-Lemma Peirce : ((A -> B) -> A) -> A.
-try tauto.
-\end{coq_example}
-
-Note the use of the \verb:try: tactical, which does nothing if its tactic
-argument fails.
-
-This may come as a surprise to someone familiar with classical reasoning.
-Peirce's lemma is true in Boolean logic, i.e. it evaluates to \verb:true: for
-every truth-assignment to \verb:A: and \verb:B:. Indeed the double negation
-of Peirce's law may be proved in \Coq{} using \verb:tauto::
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-\begin{coq_example}
-Lemma NNPeirce : ~ ~ (((A -> B) -> A) -> A).
-tauto.
-Qed.
-\end{coq_example}
-
-In classical logic, the double negation of a proposition is equivalent to this
-proposition, but in the constructive logic of \Coq{} this is not so. If you
-want to use classical logic in \Coq, you have to import explicitly the
-\verb:Classical: module, which will declare the axiom \verb:classic:
-of excluded middle, and classical tautologies such as de Morgan's laws.
-The \verb:Require: command is used to import a module from \Coq's library:
-\begin{coq_example}
-Require Import Classical.
-Check NNPP.
-\end{coq_example}
-
-and it is now easy (although admittedly not the most direct way) to prove
-a classical law such as Peirce's:
-\begin{coq_example}
-Lemma Peirce : ((A -> B) -> A) -> A.
-apply NNPP; tauto.
-Qed.
-\end{coq_example}
-
-Here is one more example of propositional reasoning, in the shape of
-a Scottish puzzle. A private club has the following rules:
-\begin{enumerate}
-\item Every non-scottish member wears red socks
-\item Every member wears a kilt or doesn't wear red socks
-\item The married members don't go out on Sunday
-\item A member goes out on Sunday if and only if he is Scottish
-\item Every member who wears a kilt is Scottish and married
-\item Every scottish member wears a kilt
-\end{enumerate}
-Now, we show that these rules are so strict that no one can be accepted.
-\begin{coq_example}
-Section club.
-Variables Scottish RedSocks WearKilt Married GoOutSunday : Prop.
-Hypothesis rule1 : ~ Scottish -> RedSocks.
-Hypothesis rule2 : WearKilt \/ ~ RedSocks.
-Hypothesis rule3 : Married -> ~ GoOutSunday.
-Hypothesis rule4 : GoOutSunday <-> Scottish.
-Hypothesis rule5 : WearKilt -> Scottish /\ Married.
-Hypothesis rule6 : Scottish -> WearKilt.
-Lemma NoMember : False.
-tauto.
-Qed.
-\end{coq_example}
-At that point \verb:NoMember: is a proof of the absurdity depending on
-hypotheses.
-We may end the section, in that case, the variables and hypotheses
-will be discharged, and the type of \verb:NoMember: will be
-generalised.
-
-\begin{coq_example}
-End club.
-Check NoMember.
-\end{coq_example}
-
-\section{Predicate Calculus}
-
-Let us now move into predicate logic, and first of all into first-order
-predicate calculus. The essence of predicate calculus is that to try to prove
-theorems in the most abstract possible way, without using the definitions of
-the mathematical notions, but by formal manipulations of uninterpreted
-function and predicate symbols.
-
-\subsection{Sections and signatures}
-
-Usually one works in some domain of discourse, over which range the individual
-variables and function symbols. In \Coq{}, we speak in a language with a rich
-variety of types, so we may mix several domains of discourse, in our
-multi-sorted language. For the moment, we just do a few exercises, over a
-domain of discourse \verb:D: axiomatised as a \verb:Set:, and we consider two
-predicate symbols \verb:P: and \verb:R: over \verb:D:, of arities
-1 and 2, respectively.
-
-\begin{coq_eval}
-Reset Initial.
-Set Printing Width 60.
-Set Printing Compact Contexts.
-\end{coq_eval}
-
-We start by assuming a domain of
-discourse \verb:D:, and a binary relation \verb:R: over \verb:D::
-\begin{coq_example}
-Section Predicate_calculus.
-Variable D : Set.
-Variable R : D -> D -> Prop.
-\end{coq_example}
-
-As a simple example of predicate calculus reasoning, let us assume
-that relation \verb:R: is symmetric and transitive, and let us show that
-\verb:R: is reflexive in any point \verb:x: which has an \verb:R: successor.
-Since we do not want to make the assumptions about \verb:R: global axioms of
-a theory, but rather local hypotheses to a theorem, we open a specific
-section to this effect.
-\begin{coq_example}
-Section R_sym_trans.
-Hypothesis R_symmetric : forall x y : D, R x y -> R y x.
-Hypothesis R_transitive :
- forall x y z : D, R x y -> R y z -> R x z.
-\end{coq_example}
-
-Note the syntax \verb+forall x : D,+ which stands for universal quantification
-$\forall x : D$.
-
-\subsection{Existential quantification}
-
-We now state our lemma, and enter proof mode.
-\begin{coq_example}
-Lemma refl_if : forall x : D, (exists y, R x y) -> R x x.
-\end{coq_example}
-
-The hypotheses that are local to the currently opened sections
-are listed as local hypotheses to the current goals.
-That is because these hypotheses are going to be discharged, as
-we shall see, when we shall close the corresponding sections.
-
-Note the functional syntax for existential quantification. The existential
-quantifier is built from the operator \verb:ex:, which expects a
-predicate as argument:
-\begin{coq_example}
-Check ex.
-\end{coq_example}
-and the notation \verb+(exists x : D, P x)+ is just concrete syntax for
-the expression \verb+(ex D (fun x : D => P x))+.
-Existential quantification is handled in \Coq{} in a similar
-fashion to the connectives \verb:/\: and \verb:\/:: it is introduced by
-the proof combinator \verb:ex_intro:, which is invoked by the specific
-tactic \verb:exists:, and its elimination provides a witness \verb+a : D+ to
-\verb:P:, together with an assumption \verb+h : (P a)+ that indeed \verb+a+
-verifies \verb:P:. Let us see how this works on this simple example.
-\begin{coq_example}
-intros x x_Rlinked.
-\end{coq_example}
-
-Note that \verb:intros: treats universal quantification in the same way
-as the premises of implications. Renaming of bound variables occurs
-when it is needed; for instance, had we started with \verb:intro y:,
-we would have obtained the goal:
-\begin{coq_eval}
-Undo.
-\end{coq_eval}
-\begin{coq_example}
-intro y.
-\end{coq_example}
-\begin{coq_eval}
-Undo.
-intros x x_Rlinked.
-\end{coq_eval}
-
-Let us now use the existential hypothesis \verb:x_Rlinked: to
-exhibit an R-successor y of x. This is done in two steps, first with
-\verb:elim:, then with \verb:intros:
-
-\begin{coq_example}
-elim x_Rlinked.
-intros y Rxy.
-\end{coq_example}
-
-Now we want to use \verb:R_transitive:. The \verb:apply: tactic will know
-how to match \verb:x: with \verb:x:, and \verb:z: with \verb:x:, but needs
-help on how to instantiate \verb:y:, which appear in the hypotheses of
-\verb:R_transitive:, but not in its conclusion. We give the proper hint
-to \verb:apply: in a \verb:with: clause, as follows:
-\begin{coq_example}
-apply R_transitive with y.
-\end{coq_example}
-
-The rest of the proof is routine:
-\begin{coq_example}
-assumption.
-apply R_symmetric; assumption.
-\end{coq_example}
-\begin{coq_example*}
-Qed.
-\end{coq_example*}
-
-Let us now close the current section.
-\begin{coq_example}
-End R_sym_trans.
-\end{coq_example}
-
-All the local hypotheses have been
-discharged in the statement of \verb:refl_if:, which now becomes a general
-theorem in the first-order language declared in section
-\verb:Predicate_calculus:. In this particular example, section
-\verb:R_sym_trans: has not been really useful, since we could have
-instead stated theorem \verb:refl_if: in its general form, and done
-basically the same proof, obtaining \verb:R_symmetric: and
-\verb:R_transitive: as local hypotheses by initial \verb:intros: rather
-than as global hypotheses in the context. But if we had pursued the
-theory by proving more theorems about relation \verb:R:,
-we would have obtained all general statements at the closing of the section,
-with minimal dependencies on the hypotheses of symmetry and transitivity.
-
-\subsection{Paradoxes of classical predicate calculus}
-
-Let us illustrate this feature by pursuing our \verb:Predicate_calculus:
-section with an enrichment of our language: we declare a unary predicate
-\verb:P: and a constant \verb:d::
-\begin{coq_example}
-Variable P : D -> Prop.
-Variable d : D.
-\end{coq_example}
-
-We shall now prove a well-known fact from first-order logic: a universal
-predicate is non-empty, or in other terms existential quantification
-follows from universal quantification.
-\begin{coq_example}
-Lemma weird : (forall x:D, P x) -> exists a, P a.
- intro UnivP.
-\end{coq_example}
-
-First of all, notice the pair of parentheses around
-\verb+forall x : D, P x+ in
-the statement of lemma \verb:weird:.
-If we had omitted them, \Coq's parser would have interpreted the
-statement as a truly trivial fact, since we would
-postulate an \verb:x: verifying \verb:(P x):. Here the situation is indeed
-more problematic. If we have some element in \verb:Set: \verb:D:, we may
-apply \verb:UnivP: to it and conclude, otherwise we are stuck. Indeed
-such an element \verb:d: exists, but this is just by virtue of our
-new signature. This points out a subtle difference between standard
-predicate calculus and \Coq. In standard first-order logic,
-the equivalent of lemma \verb:weird: always holds,
-because such a rule is wired in the inference rules for quantifiers, the
-semantic justification being that the interpretation domain is assumed to
-be non-empty. Whereas in \Coq, where types are not assumed to be
-systematically inhabited, lemma \verb:weird: only holds in signatures
-which allow the explicit construction of an element in the domain of
-the predicate.
-
-Let us conclude the proof, in order to show the use of the \verb:exists:
-tactic:
-\begin{coq_example}
-exists d; trivial.
-Qed.
-\end{coq_example}
-
-Another fact which illustrates the sometimes disconcerting rules of
-classical
-predicate calculus is Smullyan's drinkers' paradox: ``In any non-empty
-bar, there is a person such that if she drinks, then everyone drinks''.
-We modelize the bar by Set \verb:D:, drinking by predicate \verb:P:.
-We shall need classical reasoning. Instead of loading the \verb:Classical:
-module as we did above, we just state the law of excluded middle as a
-local hypothesis schema at this point:
-\begin{coq_example}
-Hypothesis EM : forall A : Prop, A \/ ~ A.
-Lemma drinker : exists x : D, P x -> forall x : D, P x.
-\end{coq_example}
-The proof goes by cases on whether or not
-there is someone who does not drink. Such reasoning by cases proceeds
-by invoking the excluded middle principle, via \verb:elim: of the
-proper instance of \verb:EM::
-\begin{coq_example}
-elim (EM (exists x, ~ P x)).
-\end{coq_example}
-
-We first look at the first case. Let Tom be the non-drinker.
-The following combines at once the effect of \verb:intros: and
-\verb:destruct::
-\begin{coq_example}
-intros (Tom, Tom_does_not_drink).
-\end{coq_example}
-
-We conclude in that case by considering Tom, since his drinking leads to
-a contradiction:
-\begin{coq_example}
-exists Tom; intro Tom_drinks.
-\end{coq_example}
-
-There are several ways in which we may eliminate a contradictory case;
-in this case, we use \verb:contradiction: to let \Coq{} find out the
-two contradictory hypotheses:
-\begin{coq_example}
-contradiction.
-\end{coq_example}
-
-We now proceed with the second case, in which actually any person will do;
-such a John Doe is given by the non-emptiness witness \verb:d::
-\begin{coq_example}
-intro No_nondrinker; exists d; intro d_drinks.
-\end{coq_example}
-
-Now we consider any Dick in the bar, and reason by cases according to its
-drinking or not:
-\begin{coq_example}
-intro Dick; elim (EM (P Dick)); trivial.
-\end{coq_example}
-
-The only non-trivial case is again treated by contradiction:
-\begin{coq_example}
-intro Dick_does_not_drink; absurd (exists x, ~ P x); trivial.
-exists Dick; trivial.
-Qed.
-\end{coq_example}
-
-Now, let us close the main section and look at the complete statements
-we proved:
-\begin{coq_example}
-End Predicate_calculus.
-Check refl_if.
-Check weird.
-Check drinker.
-\end{coq_example}
-
-Note how the three theorems are completely generic in the most general
-fashion;
-the domain \verb:D: is discharged in all of them, \verb:R: is discharged in
-\verb:refl_if: only, \verb:P: is discharged only in \verb:weird: and
-\verb:drinker:, along with the hypothesis that \verb:D: is inhabited.
-Finally, the excluded middle hypothesis is discharged only in
-\verb:drinker:.
-
-Note, too, that the name \verb:d: has vanished from
-the statements of \verb:weird: and \verb:drinker:,
-since \Coq's pretty-printer replaces
-systematically a quantification such as \texttt{forall d : D, E},
-where \texttt{d} does not occur in \texttt{E},
-by the functional notation \texttt{D -> E}.
-Similarly the name \texttt{EM} does not appear in \texttt{drinker}.
-
-Actually, universal quantification, implication,
-as well as function formation, are
-all special cases of one general construct of type theory called
-{\sl dependent product}. This is the mathematical construction
-corresponding to an indexed family of functions. A function
-$f\in \Pi x:D\cdot Cx$ maps an element $x$ of its domain $D$ to its
-(indexed) codomain $Cx$. Thus a proof of $\forall x:D\cdot Px$ is
-a function mapping an element $x$ of $D$ to a proof of proposition $Px$.
-
-
-\subsection{Flexible use of local assumptions}
-
-Very often during the course of a proof we want to retrieve a local
-assumption and reintroduce it explicitly in the goal, for instance
-in order to get a more general induction hypothesis. The tactic
-\verb:generalize: is what is needed here:
-
-\begin{coq_example}
-Section Predicate_Calculus.
-Variables P Q : nat -> Prop.
-Variable R : nat -> nat -> Prop.
-Lemma PQR :
- forall x y:nat, (R x x -> P x -> Q x) -> P x -> R x y -> Q x.
-intros.
-generalize H0.
-\end{coq_example}
-
-Sometimes it may be convenient to state an intermediate fact.
-The tactic \verb:assert: does this and introduces a new subgoal
-for this fact to be proved first. The tactic \verb:enough: does
-the same while keeping this goal for later.
-\begin{coq_example}
-enough (R x x) by auto.
-\end{coq_example}
-We clean the goal by doing an \verb:Abort: command.
-\begin{coq_example*}
-Abort.
-\end{coq_example*}
-
-
-\subsection{Equality}
-
-The basic equality provided in \Coq{} is Leibniz equality, noted infix like
-\texttt{x = y}, when \texttt{x} and \texttt{y} are two expressions of
-type the same Set. The replacement of \texttt{x} by \texttt{y} in any
-term is effected by a variety of tactics, such as \texttt{rewrite}
-and \texttt{replace}.
-
-Let us give a few examples of equality replacement. Let us assume that
-some arithmetic function \verb:f: is null in zero:
-\begin{coq_example}
-Variable f : nat -> nat.
-Hypothesis foo : f 0 = 0.
-\end{coq_example}
-
-We want to prove the following conditional equality:
-\begin{coq_example*}
-Lemma L1 : forall k:nat, k = 0 -> f k = k.
-\end{coq_example*}
-
-As usual, we first get rid of local assumptions with \verb:intro::
-\begin{coq_example}
-intros k E.
-\end{coq_example}
-
-Let us now use equation \verb:E: as a left-to-right rewriting:
-\begin{coq_example}
-rewrite E.
-\end{coq_example}
-This replaced both occurrences of \verb:k: by \verb:O:.
-
-Now \verb:apply foo: will finish the proof:
-
-\begin{coq_example}
-apply foo.
-Qed.
-\end{coq_example}
-
-When one wants to rewrite an equality in a right to left fashion, we should
-use \verb:rewrite <- E: rather than \verb:rewrite E: or the equivalent
-\verb:rewrite -> E:.
-Let us now illustrate the tactic \verb:replace:.
-\begin{coq_example}
-Hypothesis f10 : f 1 = f 0.
-Lemma L2 : f (f 1) = 0.
-replace (f 1) with 0.
-\end{coq_example}
-What happened here is that the replacement left the first subgoal to be
-proved, but another proof obligation was generated by the \verb:replace:
-tactic, as the second subgoal. The first subgoal is solved immediately
-by applying lemma \verb:foo:; the second one transitivity and then
-symmetry of equality, for instance with tactics \verb:transitivity: and
-\verb:symmetry::
-\begin{coq_example}
-apply foo.
-transitivity (f 0); symmetry; trivial.
-\end{coq_example}
-In case the equality $t=u$ generated by \verb:replace: $u$ \verb:with:
-$t$ is an assumption
-(possibly modulo symmetry), it will be automatically proved and the
-corresponding goal will not appear. For instance:
-
-\begin{coq_eval}
-Restart.
-\end{coq_eval}
-\begin{coq_example}
-Lemma L2 : f (f 1) = 0.
-replace (f 1) with (f 0).
-replace (f 0) with 0; trivial.
-Qed.
-\end{coq_example}
-
-\section{Using definitions}
-
-The development of mathematics does not simply proceed by logical
-argumentation from first principles: definitions are used in an essential way.
-A formal development proceeds by a dual process of abstraction, where one
-proves abstract statements in predicate calculus, and use of definitions,
-which in the contrary one instantiates general statements with particular
-notions in order to use the structure of mathematical values for the proof of
-more specialised properties.
-
-\subsection{Unfolding definitions}
-
-Assume that we want to develop the theory of sets represented as characteristic
-predicates over some universe \verb:U:. For instance:
-\begin{coq_example}
-Variable U : Type.
-Definition set := U -> Prop.
-Definition element (x : U) (S : set) := S x.
-Definition subset (A B : set) :=
- forall x : U, element x A -> element x B.
-\end{coq_example}
-
-Now, assume that we have loaded a module of general properties about
-relations over some abstract type \verb:T:, such as transitivity:
-
-\begin{coq_example}
-Definition transitive (T : Type) (R : T -> T -> Prop) :=
- forall x y z : T, R x y -> R y z -> R x z.
-\end{coq_example}
-
-We want to prove that \verb:subset: is a \verb:transitive:
-relation.
-\begin{coq_example}
-Lemma subset_transitive : transitive set subset.
-\end{coq_example}
-
-In order to make any progress, one needs to use the definition of
-\verb:transitive:. The \verb:unfold: tactic, which replaces all
-occurrences of a defined notion by its definition in the current goal,
-may be used here.
-\begin{coq_example}
-unfold transitive.
-\end{coq_example}
-
-Now, we must unfold \verb:subset::
-\begin{coq_example}
-unfold subset.
-\end{coq_example}
-Now, unfolding \verb:element: would be a mistake, because indeed a simple proof
-can be found by \verb:auto:, keeping \verb:element: an abstract predicate:
-\begin{coq_example}
-auto.
-\end{coq_example}
-
-Many variations on \verb:unfold: are provided in \Coq. For instance,
-instead of unfolding all occurrences of \verb:subset:, we may want to
-unfold only one designated occurrence:
-\begin{coq_eval}
-Undo 2.
-\end{coq_eval}
-\begin{coq_example}
-unfold subset at 2.
-\end{coq_example}
-
-One may also unfold a definition in a given local hypothesis, using the
-\verb:in: notation:
-\begin{coq_example}
-intros.
-unfold subset in H.
-\end{coq_example}
-
-Finally, the tactic \verb:red: does only unfolding of the head occurrence
-of the current goal:
-\begin{coq_example}
-red.
-auto.
-Qed.
-\end{coq_example}
-
-
-\subsection{Principle of proof irrelevance}
-
-Even though in principle the proof term associated with a verified lemma
-corresponds to a defined value of the corresponding specification, such
-definitions cannot be unfolded in \Coq: a lemma is considered an {\sl opaque}
-definition. This conforms to the mathematical tradition of {\sl proof
-irrelevance}: the proof of a logical proposition does not matter, and the
-mathematical justification of a logical development relies only on
-{\sl provability} of the lemmas used in the formal proof.
-
-Conversely, ordinary mathematical definitions can be unfolded at will, they
-are {\sl transparent}.
-
-\chapter{Induction}
-
-\begin{coq_eval}
-Reset Initial.
-Set Printing Width 60.
-Set Printing Compact Contexts.
-\end{coq_eval}
-
-\section{Data Types as Inductively Defined Mathematical Collections}
-
-All the notions which were studied until now pertain to traditional
-mathematical logic. Specifications of objects were abstract properties
-used in reasoning more or less constructively; we are now entering
-the realm of inductive types, which specify the existence of concrete
-mathematical constructions.
-
-\subsection{Booleans}
-
-Let us start with the collection of booleans, as they are specified
-in the \Coq's \verb:Prelude: module:
-\begin{coq_example}
-Inductive bool : Set := true | false.
-\end{coq_example}
-
-Such a declaration defines several objects at once. First, a new
-\verb:Set: is declared, with name \verb:bool:. Then the {\sl constructors}
-of this \verb:Set: are declared, called \verb:true: and \verb:false:.
-Those are analogous to introduction rules of the new Set \verb:bool:.
-Finally, a specific elimination rule for \verb:bool: is now available, which
-permits to reason by cases on \verb:bool: values. Three instances are
-indeed defined as new combinators in the global context: \verb:bool_ind:,
-a proof combinator corresponding to reasoning by cases,
-\verb:bool_rec:, an if-then-else programming construct,
-and \verb:bool_rect:, a similar combinator at the level of types.
-Indeed:
-\begin{coq_example}
-Check bool_ind.
-Check bool_rec.
-Check bool_rect.
-\end{coq_example}
-
-Let us for instance prove that every Boolean is true or false.
-\begin{coq_example}
-Lemma duality : forall b:bool, b = true \/ b = false.
-intro b.
-\end{coq_example}
-
-We use the knowledge that \verb:b: is a \verb:bool: by calling tactic
-\verb:elim:, which is this case will appeal to combinator \verb:bool_ind:
-in order to split the proof according to the two cases:
-\begin{coq_example}
-elim b.
-\end{coq_example}
-
-It is easy to conclude in each case:
-\begin{coq_example}
-left; trivial.
-right; trivial.
-\end{coq_example}
-
-Indeed, the whole proof can be done with the combination of the
- \verb:destruct:, which combines \verb:intro: and \verb:elim:,
-with good old \verb:auto::
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-\begin{coq_example}
-Lemma duality : forall b:bool, b = true \/ b = false.
-destruct b; auto.
-Qed.
-\end{coq_example}
-
-\subsection{Natural numbers}
-
-Similarly to Booleans, natural numbers are defined in the \verb:Prelude:
-module with constructors \verb:S: and \verb:O::
-\begin{coq_example}
-Inductive nat : Set :=
- | O : nat
- | S : nat -> nat.
-\end{coq_example}
-
-The elimination principles which are automatically generated are Peano's
-induction principle, and a recursion operator:
-\begin{coq_example}
-Check nat_ind.
-Check nat_rec.
-\end{coq_example}
-
-Let us start by showing how to program the standard primitive recursion
-operator \verb:prim_rec: from the more general \verb:nat_rec::
-\begin{coq_example}
-Definition prim_rec := nat_rec (fun i : nat => nat).
-\end{coq_example}
-
-That is, instead of computing for natural \verb:i: an element of the indexed
-\verb:Set: \verb:(P i):, \verb:prim_rec: computes uniformly an element of
-\verb:nat:. Let us check the type of \verb:prim_rec::
-\begin{coq_example}
-About prim_rec.
-\end{coq_example}
-
-Oops! Instead of the expected type \verb+nat->(nat->nat->nat)->nat->nat+ we
-get an apparently more complicated expression.
-In fact, the two types are convertible and one way of having the proper
-type would be to do some computation before actually defining \verb:prim_rec:
-as such:
-
-\begin{coq_eval}
-Reset Initial.
-Set Printing Width 60.
-Set Printing Compact Contexts.
-\end{coq_eval}
-
-\begin{coq_example}
-Definition prim_rec :=
- Eval compute in nat_rec (fun i : nat => nat).
-About prim_rec.
-\end{coq_example}
-
-Let us now show how to program addition with primitive recursion:
-\begin{coq_example}
-Definition addition (n m:nat) :=
- prim_rec m (fun p rec : nat => S rec) n.
-\end{coq_example}
-
-That is, we specify that \verb+(addition n m)+ computes by cases on \verb:n:
-according to its main constructor; when \verb:n = O:, we get \verb:m:;
- when \verb:n = S p:, we get \verb:(S rec):, where \verb:rec: is the result
-of the recursive computation \verb+(addition p m)+. Let us verify it by
-asking \Coq{} to compute for us say $2+3$:
-\begin{coq_example}
-Eval compute in (addition (S (S O)) (S (S (S O)))).
-\end{coq_example}
-
-Actually, we do not have to do all explicitly. {\Coq} provides a
-special syntax {\tt Fixpoint/match} for generic primitive recursion,
-and we could thus have defined directly addition as:
-
-\begin{coq_example}
-Fixpoint plus (n m:nat) {struct n} : nat :=
- match n with
- | O => m
- | S p => S (plus p m)
- end.
-\end{coq_example}
-
-\begin{coq_eval}
-\begin{coq_example}
-Reset Initial.
-Set Printing Width 60.
-Set Printing Compact Contexts.
-\end{coq_eval}
-
-\subsection{Simple proofs by induction}
-
-Let us now show how to do proofs by structural induction. We start with easy
-properties of the \verb:plus: function we just defined. Let us first
-show that $n=n+0$.
-\begin{coq_example}
-Lemma plus_n_O : forall n : nat, n = n + 0.
-intro n; elim n.
-\end{coq_example}
-
-What happened was that \texttt{elim n}, in order to construct a \texttt{Prop}
-(the initial goal) from a \texttt{nat} (i.e. \texttt{n}), appealed to the
-corresponding induction principle \texttt{nat\_ind} which we saw was indeed
-exactly Peano's induction scheme. Pattern-matching instantiated the
-corresponding predicate \texttt{P} to \texttt{fun n : nat => n = n + 0},
-and we get as subgoals the corresponding instantiations of the base case
-\texttt{(P O)}, and of the inductive step
-\texttt{forall y : nat, P y -> P (S y)}.
-In each case we get an instance of function \texttt{plus} in which its second
-argument starts with a constructor, and is thus amenable to simplification
-by primitive recursion. The \Coq{} tactic \texttt{simpl} can be used for
-this purpose:
-\begin{coq_example}
-simpl.
-auto.
-\end{coq_example}
-
-We proceed in the same way for the base step:
-\begin{coq_example}
-simpl; auto.
-Qed.
-\end{coq_example}
-
-Here \verb:auto: succeeded, because it used as a hint lemma \verb:eq_S:,
-which say that successor preserves equality:
-\begin{coq_example}
-Check eq_S.
-\end{coq_example}
-
-Actually, let us see how to declare our lemma \verb:plus_n_O: as a hint
-to be used by \verb:auto::
-\begin{coq_example}
-Hint Resolve plus_n_O .
-\end{coq_example}
-
-We now proceed to the similar property concerning the other constructor
-\verb:S::
-\begin{coq_example}
-Lemma plus_n_S : forall n m:nat, S (n + m) = n + S m.
-\end{coq_example}
-
-We now go faster, using the tactic \verb:induction:, which does the
-necessary \verb:intros: before applying \verb:elim:. Factoring simplification
-and automation in both cases thanks to tactic composition, we prove this
-lemma in one line:
-\begin{coq_example}
-induction n; simpl; auto.
-Qed.
-Hint Resolve plus_n_S .
-\end{coq_example}
-
-Let us end this exercise with the commutativity of \verb:plus::
-
-\begin{coq_example}
-Lemma plus_com : forall n m:nat, n + m = m + n.
-\end{coq_example}
-
-Here we have a choice on doing an induction on \verb:n: or on \verb:m:, the
-situation being symmetric. For instance:
-\begin{coq_example}
-induction m as [ | m IHm ]; simpl; auto.
-\end{coq_example}
-
-Here \verb:auto: succeeded on the base case, thanks to our hint
-\verb:plus_n_O:, but the induction step requires rewriting, which
-\verb:auto: does not handle:
-
-\begin{coq_example}
-rewrite <- IHm; auto.
-Qed.
-\end{coq_example}
-
-\subsection{Discriminate}
-
-It is also possible to define new propositions by primitive recursion.
-Let us for instance define the predicate which discriminates between
-the constructors \verb:O: and \verb:S:: it computes to \verb:False:
-when its argument is \verb:O:, and to \verb:True: when its argument is
-of the form \verb:(S n)::
-\begin{coq_example}
-Definition Is_S (n : nat) := match n with
- | O => False
- | S p => True
- end.
-\end{coq_example}
-
-Now we may use the computational power of \verb:Is_S: to prove
-trivially that \verb:(Is_S (S n))::
-\begin{coq_example}
-Lemma S_Is_S : forall n:nat, Is_S (S n).
-simpl; trivial.
-Qed.
-\end{coq_example}
-
-But we may also use it to transform a \verb:False: goal into
-\verb:(Is_S O):. Let us show a particularly important use of this feature;
-we want to prove that \verb:O: and \verb:S: construct different values, one
-of Peano's axioms:
-\begin{coq_example}
-Lemma no_confusion : forall n:nat, 0 <> S n.
-\end{coq_example}
-
-First of all, we replace negation by its definition, by reducing the
-goal with tactic \verb:red:; then we get contradiction by successive
-\verb:intros::
-\begin{coq_example}
-red; intros n H.
-\end{coq_example}
-
-Now we use our trick:
-\begin{coq_example}
-change (Is_S 0).
-\end{coq_example}
-
-Now we use equality in order to get a subgoal which computes out to
-\verb:True:, which finishes the proof:
-\begin{coq_example}
-rewrite H; trivial.
-simpl; trivial.
-\end{coq_example}
-
-Actually, a specific tactic \verb:discriminate: is provided
-to produce mechanically such proofs, without the need for the user to define
-explicitly the relevant discrimination predicates:
-
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-\begin{coq_example}
-Lemma no_confusion : forall n:nat, 0 <> S n.
-intro n; discriminate.
-Qed.
-\end{coq_example}
-
-
-\section{Logic programming}
-
-In the same way as we defined standard data-types above, we
-may define inductive families, and for instance inductive predicates.
-Here is the definition of predicate $\le$ over type \verb:nat:, as
-given in \Coq's \verb:Prelude: module:
-\begin{coq_example*}
-Inductive le (n : nat) : nat -> Prop :=
- | le_n : le n n
- | le_S : forall m : nat, le n m -> le n (S m).
-\end{coq_example*}
-
-This definition introduces a new predicate
-\verb+le : nat -> nat -> Prop+,
-and the two constructors \verb:le_n: and \verb:le_S:, which are the
-defining clauses of \verb:le:. That is, we get not only the ``axioms''
-\verb:le_n: and \verb:le_S:, but also the converse property, that
-\verb:(le n m): if and only if this statement can be obtained as a
-consequence of these defining clauses; that is, \verb:le: is the
-minimal predicate verifying clauses \verb:le_n: and \verb:le_S:. This is
-insured, as in the case of inductive data types, by an elimination principle,
-which here amounts to an induction principle \verb:le_ind:, stating this
-minimality property:
-\begin{coq_example}
-Check le.
-Check le_ind.
-\end{coq_example}
-
-Let us show how proofs may be conducted with this principle.
-First we show that $n\le m \Rightarrow n+1\le m+1$:
-\begin{coq_example}
-Lemma le_n_S : forall n m : nat, le n m -> le (S n) (S m).
-intros n m n_le_m.
-elim n_le_m.
-\end{coq_example}
-
-What happens here is similar to the behaviour of \verb:elim: on natural
-numbers: it appeals to the relevant induction principle, here \verb:le_ind:,
-which generates the two subgoals, which may then be solved easily
-with the help of the defining clauses of \verb:le:.
-\begin{coq_example}
-apply le_n; trivial.
-intros; apply le_S; trivial.
-\end{coq_example}
-
-Now we know that it is a good idea to give the defining clauses as hints,
-so that the proof may proceed with a simple combination of
-\verb:induction: and \verb:auto:. \verb:Hint Constructors le:
-is just an abbreviation for \verb:Hint Resolve le_n le_S:.
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-\begin{coq_example}
-Hint Constructors le.
-Lemma le_n_S : forall n m : nat, le n m -> le (S n) (S m).
-\end{coq_example}
-
-We have a slight problem however. We want to say ``Do an induction on
-hypothesis \verb:(le n m):'', but we have no explicit name for it. What we
-do in this case is to say ``Do an induction on the first unnamed hypothesis'',
-as follows.
-\begin{coq_example}
-induction 1; auto.
-Qed.
-\end{coq_example}
-
-Here is a more tricky problem. Assume we want to show that
-$n\le 0 \Rightarrow n=0$. This reasoning ought to follow simply from the
-fact that only the first defining clause of \verb:le: applies.
-\begin{coq_example}
-Lemma tricky : forall n:nat, le n 0 -> n = 0.
-\end{coq_example}
-
-However, here trying something like \verb:induction 1: would lead
-nowhere (try it and see what happens).
-An induction on \verb:n: would not be convenient either.
-What we must do here is analyse the definition of \verb"le" in order
-to match hypothesis \verb:(le n O): with the defining clauses, to find
-that only \verb:le_n: applies, whence the result.
-This analysis may be performed by the ``inversion'' tactic
-\verb:inversion_clear: as follows:
-\begin{coq_example}
-intros n H; inversion_clear H.
-trivial.
-Qed.
-\end{coq_example}
-
-\chapter{Modules}
-
-\begin{coq_eval}
-Reset Initial.
-Set Printing Width 60.
-Set Printing Compact Contexts.
-\end{coq_eval}
-
-\section{Opening library modules}
-
-When you start \Coq{} without further requirements in the command line,
-you get a bare system with few libraries loaded. As we saw, a standard
-prelude module provides the standard logic connectives, and a few
-arithmetic notions. If you want to load and open other modules from
-the library, you have to use the \verb"Require" command, as we saw for
-classical logic above. For instance, if you want more arithmetic
-constructions, you should request:
-\begin{coq_example*}
-Require Import Arith.
-\end{coq_example*}
-
-Such a command looks for a (compiled) module file \verb:Arith.vo: in
-the libraries registered by \Coq. Libraries inherit the structure of
-the file system of the operating system and are registered with the
-command \verb:Add LoadPath:. Physical directories are mapped to
-logical directories. Especially the standard library of \Coq{} is
-pre-registered as a library of name \verb=Coq=. Modules have absolute
-unique names denoting their place in \Coq{} libraries. An absolute
-name is a sequence of single identifiers separated by dots. E.g. the
-module \verb=Arith= has full name \verb=Coq.Arith.Arith= and because
-it resides in eponym subdirectory \verb=Arith= of the standard
-library, it can be as well required by the command
-
-\begin{coq_example*}
-Require Import Coq.Arith.Arith.
-\end{coq_example*}
-
-This may be useful to avoid ambiguities if somewhere, in another branch
-of the libraries known by Coq, another module is also called
-\verb=Arith=. Notice that by default, when a library is registered,
-all its contents, and all the contents of its subdirectories recursively are
-visible and accessible by a short (relative) name as \verb=Arith=.
-Notice also that modules or definitions not explicitly registered in
-a library are put in a default library called \verb=Top=.
-
-The loading of a compiled file is quick, because the corresponding
-development is not type-checked again.
-
-\section{Creating your own modules}
-
-You may create your own module files, by writing {\Coq} commands in a file,
-say \verb:my_module.v:. Such a module may be simply loaded in the current
-context, with command \verb:Load my_module:. It may also be compiled,
-in ``batch'' mode, using the UNIX command
-\verb:coqc:. Compiling the module \verb:my_module.v: creates a
-file \verb:my_module.vo:{} that can be reloaded with command
-\verb:Require: \verb:Import: \verb:my_module:.
-
-If a required module depends on other modules then the latters are
-automatically required beforehand. However their contents is not
-automatically visible. If you want a module \verb=M= required in a
-module \verb=N= to be automatically visible when \verb=N= is required,
-you should use \verb:Require Export M: in your module \verb:N:.
-
-\section{Managing the context}
-
-It is often difficult to remember the names of all lemmas and
-definitions available in the current context, especially if large
-libraries have been loaded. A convenient \verb:Search: command
-is available to lookup all known facts
-concerning a given predicate. For instance, if you want to know all the
-known lemmas about both the successor and the less or equal relation, just ask:
-\begin{coq_eval}
-Reset Initial.
-Set Printing Width 60.
-Set Printing Compact Contexts.
-\end{coq_eval}
-\begin{coq_example}
-Search S le.
-\end{coq_example}
-Another command \verb:SearchHead: displays only lemmas where the searched
-predicate appears at the head position in the conclusion.
-\begin{coq_example}
-SearchHead le.
-\end{coq_example}
-
-The \verb:Search: commands also allows finding the theorems
-containing a given pattern, where \verb:_: can be used in
-place of an arbitrary term. As shown in this example, \Coq{}
-provides usual infix notations for arithmetic operators.
-
-\begin{coq_example}
-Search (_ + _ = _).
-\end{coq_example}
-
-\section{Now you are on your own}
-
-This tutorial is necessarily incomplete. If you wish to pursue serious
-proving in \Coq, you should now get your hands on \Coq's Reference Manual,
-which contains a complete description of all the tactics we saw,
-plus many more.
-You also should look in the library of developed theories which is distributed
-with \Coq, in order to acquaint yourself with various proof techniques.
-
-
-\end{document}
-
diff --git a/engine/eConstr.ml b/engine/eConstr.ml
index a72bdee12..2ab545612 100644
--- a/engine/eConstr.ml
+++ b/engine/eConstr.ml
@@ -446,28 +446,28 @@ let compare_constr sigma cmp c1 c2 =
compare_gen kind (fun _ _ -> Univ.Instance.equal) Sorts.equal 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);
@@ -480,7 +480,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
@@ -491,7 +491,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' =
@@ -499,7 +499,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 _ ->
@@ -514,11 +515,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
@@ -526,7 +527,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
@@ -535,7 +536,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
@@ -573,15 +574,15 @@ let compare_head_gen_proj env sigma equ eqs eqc' nargs m n =
| _ -> 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
diff --git a/engine/eConstr.mli b/engine/eConstr.mli
index 9a5b5ec3a..b0e834b2e 100644
--- a/engine/eConstr.mli
+++ b/engine/eConstr.mli
@@ -201,11 +201,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
@@ -284,9 +284,9 @@ 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} *)
diff --git a/engine/engine.mllib b/engine/engine.mllib
index a5df5a9fa..37e83b623 100644
--- a/engine/engine.mllib
+++ b/engine/engine.mllib
@@ -1,3 +1,8 @@
+UnivNames
+UnivGen
+UnivSubst
+UnivProblem
+UnivMinim
Universes
Univops
UState
diff --git a/engine/evar_kinds.ml b/engine/evar_kinds.ml
index c964ecf1f..6e123d642 100644
--- a/engine/evar_kinds.ml
+++ b/engine/evar_kinds.ml
@@ -9,7 +9,6 @@
(************************************************************************)
open Names
-open Globnames
open Misctypes
(** The kinds of existential variable *)
@@ -24,7 +23,7 @@ type matching_var_kind = FirstOrderPatVar of patvar | SecondOrderPatVar of patva
type subevar_kind = Domain | Codomain | Body
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 *)
diff --git a/engine/evarutil.ml b/engine/evarutil.ml
index 710491f84..cb2d01bdf 100644
--- a/engine/evarutil.ml
+++ b/engine/evarutil.ml
@@ -86,7 +86,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 =
@@ -436,7 +436,7 @@ let new_pure_evar_full evd evi =
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 new_pure_evar?(src=default_source) ?(filter = Filter.identity) ?candidates ?(store = Store.empty) ?naming ?(principal=false) sign evd typ =
let default_naming = Misctypes.IntroAnonymous in
let naming = Option.default default_naming naming in
let name = match naming with
@@ -463,14 +463,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
@@ -480,7 +480,7 @@ 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 ?hypnaming typ =
+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
@@ -490,7 +490,7 @@ let new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal ?hypnami
| 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 ?hypnaming 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 ?hypnaming (EConstr.mkSort s) in
evd', (e, s)
@@ -534,7 +534,7 @@ type clear_dependency_error =
| OccurHypInSimpleClause of Id.t option
| EvarTypingBreak of existential
-exception ClearDependencyError of Id.t * clear_dependency_error * Globnames.global_reference option
+exception ClearDependencyError of Id.t * clear_dependency_error * GlobRef.t option
exception Depends of Id.t
@@ -613,10 +613,11 @@ let rec check_and_clear_in_constr env evdref err ids global c =
| _ -> 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 =
@@ -639,16 +640,16 @@ 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. *)
@@ -829,13 +830,13 @@ let subterm_source evk ?where (loc,k) =
(* 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)
@@ -847,10 +848,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
@@ -869,7 +870,7 @@ let eq_constr_univs_test sigma1 sigma2 t u =
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
diff --git a/engine/evarutil.mli b/engine/evarutil.mli
index e3e8f16c8..3ab2d3e34 100644
--- a/engine/evarutil.mli
+++ b/engine/evarutil.mli
@@ -25,10 +25,11 @@ 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
+ ?principal:bool ->
+ named_context_val -> evar_map -> types -> evar_map * EConstr.t
type naming_mode =
| KeepUserNameAndRenameExistingButSectionNames
@@ -37,49 +38,38 @@ type naming_mode =
| 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 -> ?hypnaming:naming_mode -> types -> evar_map * EConstr.t
+ ?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
+ ?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 -> ?hypnaming:naming_mode -> 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 -> ?hypnaming:naming_mode -> 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 -> ?hypnaming:naming_mode -> rigid -> constr * Sorts.t
+ ?principal:bool -> ?hypnaming:naming_mode ->
+ env -> evar_map -> rigid ->
+ evar_map * (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
val restrict_evar : evar_map -> Evar.t -> Filter.t ->
?src:Evar_kinds.t Loc.located -> constr list option -> evar_map * Evar.t
(** 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
@@ -88,10 +78,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 ->
?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
@@ -187,8 +177,6 @@ val nf_evars_universes : evar_map -> Constr.constr -> Constr.constr
val nf_evars_and_universes : evar_map -> evar_map * (Constr.constr -> Constr.constr)
[@@ocaml.deprecated "Use Evd.minimize_universes and nf_evars_universes"]
-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. *)
@@ -235,13 +223,13 @@ type clear_dependency_error =
| OccurHypInSimpleClause of Id.t option
| EvarTypingBreak of Constr.existential
-exception ClearDependencyError of Id.t * clear_dependency_error * Globnames.global_reference option
+exception ClearDependencyError of Id.t * clear_dependency_error * GlobRef.t option
-val clear_hyps_in_evi : env -> evar_map ref -> named_context_val -> types ->
- Id.Set.t -> named_context_val * 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 ref -> named_context_val -> types -> types ->
- Id.Set.t -> named_context_val * types * 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
@@ -276,3 +264,25 @@ 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:Misctypes.intro_pattern_naming_expr ->
+ ?principal:bool -> ?hypnaming:naming_mode -> types -> constr
+[@@ocaml.deprecated "Use [Evd.new_evar]"]
+
+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 -> ?hypnaming:naming_mode -> rigid -> constr * Sorts.t
+[@@ocaml.deprecated "Use [Evd.new_type_evar]"]
+
+val e_new_Type : ?rigid:rigid -> env -> evar_map ref -> constr
+[@@ocaml.deprecated "Use [Evd.new_Type]"]
+
+val e_new_global : evar_map ref -> GlobRef.t -> constr
+[@@ocaml.deprecated "Use [Evd.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 6dcec2760..03b843655 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -804,19 +804,19 @@ let make_flexible_variable evd ~algebraic u =
(****************************************)
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)
+ with_context_set ?loc rigid evd (UnivGen.fresh_sort_in_family env 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)
+ with_context_set ?loc rigid evd (UnivGen.fresh_global_instance ?names env gr)
let whd_sort_variable evd t = t
@@ -842,13 +842,13 @@ 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 =
@@ -866,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
@@ -878,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
@@ -887,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' =
@@ -1290,30 +1290,14 @@ module MiniEConstr = struct
let unsafe_eq = Refl
let to_constr ?(abort_on_undefined_evars=true) sigma c =
- let rec to_constr c = match Constr.kind c with
- | Evar ev ->
- begin match safe_evar_value sigma ev with
- | Some c -> to_constr c
- | None ->
- if abort_on_undefined_evars then
- anomaly ~label:"econstr" Pp.(str "grounding a non evar-free term")
- else
- Constr.map (fun c -> to_constr c) c
- end
- | Sort (Sorts.Type u) ->
- let u' = 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' = 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' = 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' = normalize_universe_instance sigma u in
- if u' == u then c else mkConstructU (co, u')
- | _ -> Constr.map (fun c -> to_constr c) c
- in to_constr c
+ let evar_value =
+ if not abort_on_undefined_evars then fun ev -> safe_evar_value sigma ev
+ else fun ev ->
+ match safe_evar_value sigma ev with
+ | Some _ as v -> v
+ | None -> anomaly ~label:"econstr" Pp.(str "grounding a non evar-free term")
+ 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
diff --git a/engine/evd.mli b/engine/evd.mli
index 5ce16459c..b2670ee51 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -354,7 +354,7 @@ val whd_sort_variable : evar_map -> econstr -> econstr
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 .
@@ -543,14 +543,14 @@ val empty_evar_universe_context : UState.t
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
+val evar_universe_context_subst : UState.t -> UnivSubst.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
+ UnivNames.universe_binders -> UState.t
[@@ocaml.deprecated "Alias of UState.of_binders"]
val make_evar_universe_context : env -> Misctypes.lident list option -> UState.t
@@ -559,7 +559,7 @@ 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 universe_binders : evar_map -> UnivNames.universe_binders
val add_constraints_context : UState.t ->
Univ.Constraint.t -> UState.t
[@@ocaml.deprecated "Alias of UState.add_constraints"]
@@ -603,7 +603,7 @@ val check_leq : evar_map -> Univ.Universe.t -> Univ.Universe.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
@@ -622,7 +622,7 @@ 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
@@ -649,7 +649,7 @@ val fresh_inductive_instance : ?loc:Loc.t -> env -> evar_map -> inductive -> eva
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 * econstr
+ evar_map -> GlobRef.t -> evar_map * econstr
(********************************************************************)
(* constr with holes and pending resolution of classes, conversion *)
diff --git a/engine/termops.ml b/engine/termops.ml
index df43be28e..c271d9d99 100644
--- a/engine/termops.ml
+++ b/engine/termops.ml
@@ -47,7 +47,7 @@ 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"*)"
let rec pr_constr c = match kind c with
| Rel n -> str "#"++int n
@@ -306,7 +306,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 ())
diff --git a/engine/termops.mli b/engine/termops.mli
index 3b0c4bba6..e2ddcd36e 100644
--- a/engine/termops.mli
+++ b/engine/termops.mli
@@ -112,7 +112,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 vars_of_global_reference : env -> GlobRef.t -> Id.Set.t
val occur_term : Evd.evar_map -> constr -> constr -> bool (** Synonymous of dependent *)
[@@ocaml.deprecated "alias of Termops.dependent"]
@@ -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
diff --git a/engine/uState.ml b/engine/uState.ml
index 6c8dbe3f4..844eb390b 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
@@ -298,7 +300,7 @@ let reference_of_level uctx =
fun l ->
try CAst.make @@ Libnames.Ident (Option.get (Univ.LMap.find l map_rev).uname)
with Not_found | Option.IsNone ->
- Universes.reference_of_level l
+ UnivNames.reference_of_level l
let pr_uctx_level uctx l =
Libnames.pr_reference (reference_of_level uctx l)
@@ -471,7 +473,7 @@ let emit_side_effects eff u =
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 +551,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
+ 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 +603,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 +630,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
diff --git a/engine/uState.mli b/engine/uState.mli
index 48c38fafc..11aaaf389 100644
--- a/engine/uState.mli
+++ b/engine/uState.mli
@@ -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
*)
@@ -104,7 +104,7 @@ 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_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
diff --git a/engine/univGen.ml b/engine/univGen.ml
new file mode 100644
index 000000000..796a1bcc1
--- /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 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)
+
+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 000000000..8169dbda4
--- /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 : env -> 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 000000000..f10e6d2ec
--- /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 000000000..9f80b7acb
--- /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 000000000..6e59a7c9e
--- /dev/null
+++ b/engine/univNames.ml
@@ -0,0 +1,105 @@
+(************************************************************************)
+(* * 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 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 : 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 = 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))
diff --git a/engine/univNames.mli b/engine/univNames.mli
new file mode 100644
index 000000000..e3bc3193d
--- /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 reference_of_level : Level.t -> Libnames.reference
+
+(** 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 = Misctypes.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 000000000..bc2edc13d
--- /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 000000000..ffaebe15a
--- /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 000000000..6a433d9fb
--- /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 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
diff --git a/engine/univSubst.mli b/engine/univSubst.mli
new file mode 100644
index 000000000..26e8d1db9
--- /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 * 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 e98708724..70601987c 100644
--- a/engine/universes.ml
+++ b/engine/universes.ml
@@ -8,1108 +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.reference_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 *)
-
-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)
-
-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 subst_univs_fn_puniverses lsubst (c, u as cu) =
- let u' = Instance.subst_fn lsubst u in
- if u' == u then cu else (c, u')
-
-let nf_evars_and_universes_opt_subst f subst =
- let subst = fun l -> match LMap.find l subst with None -> raise Not_found | Some l' -> l' 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 -> c
- | 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 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 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
-
-(* 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) =
- 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 = List.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)
-
-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 = 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 a0a7749f8..46ff33a47 100644
--- a/engine/universes.mli
+++ b/engine/universes.mli
@@ -8,225 +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
+[@@ocaml.deprecated "Use [UnivNames.pr_with_global_universes]"]
val reference_of_level : Level.t -> Libnames.reference
+[@@ocaml.deprecated "Use [UnivNames.reference_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 : env -> 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]"]
+
+val type_of_global : Globnames.global_reference -> types in_universe_context_set
+[@@ocaml.deprecated "Use [UnivGen.type_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. *)
+(** ****** 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 ->
+val normalize_univ_variables : universe_opt_subst ->
universe_opt_subst * LSet.t * LSet.t * universe_subst
+[@@ocaml.deprecated "Use [UnivSubst.normalize_univ_variables]"]
-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/ide/coq.ml b/ide/coq.ml
index 65456d685..63986935a 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
diff --git a/ide/coqidetop.mllib b/ide/ide_common.mllib
index df988d8f1..050c282ef 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 c66d69c03..64f165cde 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,
@@ -352,7 +351,6 @@ 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)
@@ -430,7 +428,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. *)
@@ -458,7 +456,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 ();
@@ -507,14 +505,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);
- coq_args, 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 bdb39e94a..e96b99299 100644
--- a/ide/ideutils.ml
+++ b/ide/ideutils.ml
@@ -289,16 +289,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 +300,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/interp/constrextern.mli b/interp/constrextern.mli
index 8ab70283c..73c108319 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 -> reference
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 -> reference) -> unit
val get_extern_reference :
- unit -> (?loc:Loc.t -> Id.Set.t -> global_reference -> reference)
+ unit -> (?loc:Loc.t -> Id.Set.t -> GlobRef.t -> reference)
(** 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 7eda89f4e..48f15f897 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -980,17 +980,17 @@ let intern_reference ref =
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.reference * 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 qid intern env ntnvars us args =
@@ -1024,7 +1024,7 @@ let intern_qualid 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)
@@ -1077,7 +1077,7 @@ 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
+ | 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
@@ -1314,7 +1314,7 @@ let sort_fields ~complete loc fields completer =
| [] -> (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 ->
@@ -1352,7 +1352,7 @@ let sort_fields ~complete loc fields completer =
user_err ?loc ~hdr:"intern"
(str "The field \"" ++ pr_reference 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
diff --git a/interp/constrintern.mli b/interp/constrintern.mli
index f5e32dc4c..4dd719e1f 100644
--- a/interp/constrintern.mli
+++ b/interp/constrintern.mli
@@ -13,7 +13,6 @@ open Evd
open Environ
open Misctypes
open Libnames
-open Globnames
open Glob_term
open Pattern
open EConstr
@@ -143,7 +142,7 @@ 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 : reference -> GlobRef.t
(** Expands abbreviations (syndef); raise an error if not existing *)
val interp_reference : ltac_sign -> reference -> glob_constr
@@ -175,11 +174,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 c55a6c69b..bc2d2068a 100644
--- a/interp/declare.ml
+++ b/interp/declare.ml
@@ -487,7 +487,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 +538,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 +564,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
@@ -595,7 +595,7 @@ let input_constraints : constraint_decl -> Libobject.obj =
let do_constraint poly l =
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 () =
diff --git a/interp/declare.mli b/interp/declare.mli
index 084d746e6..4a9f54278 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_constraint : polymorphic -> (Glob_term.glob_level * Univ.constraint_type * Glob_term.glob_level) list ->
unit
diff --git a/interp/dumpglob.mli b/interp/dumpglob.mli
index 43c100008..8dfb4f8f7 100644
--- a/interp/dumpglob.mli
+++ b/interp/dumpglob.mli
@@ -24,7 +24,7 @@ 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
@@ -43,4 +43,4 @@ val dump_constraint :
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/impargs.ml b/interp/impargs.ml
index b424f73de..7e4c4ef4f 100644
--- a/interp/impargs.ml
+++ b/interp/impargs.ml
@@ -505,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"
@@ -626,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
diff --git a/interp/impargs.mli b/interp/impargs.mli
index 103a4f9e9..ea5aa90f6 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.mli b/interp/implicit_quantifiers.mli
index b9815f34d..5f4129ae0 100644
--- a/interp/implicit_quantifiers.mli
+++ b/interp/implicit_quantifiers.mli
@@ -12,7 +12,6 @@ open Names
open Glob_term
open Constrexpr
open Libnames
-open Globnames
val declare_generalizable : Vernacexpr.locality_flag -> Misctypes.lident list option -> unit
@@ -39,10 +38,10 @@ val make_fresh : Id.Set.t -> Environ.env -> Id.t -> Id.t
val implicits_of_glob_constr : ?with_products:bool -> Glob_term.glob_constr -> Impargs.manual_implicits
val combine_params_freevar :
- Id.Set.t -> global_reference option * Context.Rel.Declaration.t ->
+ Id.Set.t -> GlobRef.t option * Context.Rel.Declaration.t ->
Constrexpr.constr_expr * Id.Set.t
val implicit_application : Id.Set.t -> ?allow_partial:bool ->
- (Id.Set.t -> global_reference option * Context.Rel.Declaration.t ->
+ (Id.Set.t -> GlobRef.t option * Context.Rel.Declaration.t ->
Constrexpr.constr_expr * Id.Set.t) ->
constr_expr -> constr_expr * Id.Set.t
diff --git a/interp/notation.ml b/interp/notation.ml
index 47d648135..e6df7b96c 100644
--- a/interp/notation.ml
+++ b/interp/notation.ml
@@ -49,7 +49,6 @@ type notation_location = (DirPath.t * DirPath.t) * string
type notation_data = {
not_interp : interpretation;
not_location : notation_location;
- not_onlyprinting : bool;
}
type scope = {
@@ -259,7 +258,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
@@ -430,13 +429,15 @@ let rec find_without_delimiters find (ntn_scope,ntn) = function
(* Uninterpreted notation levels *)
-let declare_notation_level ntn level =
+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 !notation_level_map
+ notation_level_map := String.Map.add ntn (level,onlyprint) !notation_level_map
-let level_of_notation ntn =
- String.Map.find ntn !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 *)
@@ -449,20 +450,21 @@ let warn_notation_overridden =
let declare_notation_interpretation ntn scopt pat df ~onlyprint =
let scope = match scopt with Some s -> s | None -> default_scope in
let sc = find_scope scope in
- let () =
- if String.Map.mem ntn sc.notations then
- let which_scope = match scopt with
- | None -> mt ()
- | Some _ -> spc () ++ strbrk "in scope" ++ spc () ++ str scope in
- warn_notation_overridden (ntn,which_scope)
- in
- let notdata = {
- not_interp = pat;
- not_location = df;
- not_onlyprinting = onlyprint;
- } in
- let sc = { sc with notations = String.Map.add ntn notdata sc.notations } in
- let () = scope_map := String.Map.add scope sc !scope_map in
+ if not onlyprint then begin
+ let () =
+ if String.Map.mem ntn sc.notations then
+ let which_scope = match scopt with
+ | None -> mt ()
+ | Some _ -> spc () ++ strbrk "in scope" ++ spc () ++ str scope in
+ warn_notation_overridden (ntn,which_scope)
+ in
+ let notdata = {
+ not_interp = pat;
+ not_location = df;
+ } in
+ let sc = { sc with notations = String.Map.add ntn notdata sc.notations } in
+ scope_map := String.Map.add scope sc !scope_map
+ end;
begin match scopt with
| None -> scope_stack := SingleNotation ntn :: !scope_stack
| Some _ -> ()
@@ -487,7 +489,6 @@ let rec find_interpretation ntn find = function
let find_notation ntn sc =
let n = String.Map.find ntn (find_scope sc).notations in
- let () = if n.not_onlyprinting then raise Not_found in
(n.not_interp, n.not_location)
let notation_of_prim_token = function
@@ -631,7 +632,6 @@ let exists_notation_in_scope scopt ntn onlyprint r =
try
let sc = String.Map.find scope !scope_map in
let n = String.Map.find ntn sc.notations in
- onlyprint = n.not_onlyprinting &&
interpretation_eq n.not_interp r
with Not_found -> false
@@ -778,7 +778,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
@@ -1051,7 +1051,7 @@ let locate_notation prglob ntn scope =
| [] -> str "Unknown notation"
| _ ->
str "Notation" ++ fnl () ++
- prlist (fun (ntn,l) ->
+ prlist_with_sep fnl (fun (ntn,l) ->
let scope = find_default ntn scopes in
prlist
(fun (sc,r,(_,df)) ->
@@ -1060,8 +1060,7 @@ let locate_notation prglob ntn scope =
(if String.equal sc default_scope then mt ()
else (spc () ++ str ": " ++ str sc)) ++
(if Option.equal String.equal (Some sc) scope
- then spc () ++ str "(default interpretation)" else mt ())
- ++ fnl ()))
+ then spc () ++ str "(default interpretation)" else mt ())))
l) ntns
let collect_notation_in_scope scope sc known =
diff --git a/interp/notation.mli b/interp/notation.mli
index 6803a7e51..ccc67fe49 100644
--- a/interp/notation.mli
+++ b/interp/notation.mli
@@ -11,7 +11,6 @@
open Bigint
open Names
open Libnames
-open Globnames
open Constrexpr
open Glob_term
open Notation_term
@@ -91,7 +90,7 @@ val declare_string_interpreter : scope_name -> required_module ->
val interp_prim_token : ?loc:Loc.t -> prim_token -> local_scopes ->
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 ->
+val interp_prim_token_cases_pattern_expr : ?loc:Loc.t -> (GlobRef.t -> unit) -> prim_token ->
local_scopes -> glob_constr * (notation_location * scope_name option)
(** Return the primitive token associated to a [term]/[cases_pattern];
@@ -138,13 +137,13 @@ val availability_of_notation : scope_name option * notation -> local_scopes ->
(** {6 Declare and test the level of a (possibly uninterpreted) notation } *)
-val declare_notation_level : notation -> level -> unit
-val level_of_notation : notation -> level (** raise [Not_found] if no level *)
+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 -> delimiters option -> GlobRef.t
(** Checks for already existing notations *)
val exists_notation_in_scope : scope_name option -> notation ->
@@ -152,9 +151,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 +164,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
diff --git a/interp/notation_ops.ml b/interp/notation_ops.ml
index a76f82094..b806dce0b 100644
--- a/interp/notation_ops.ml
+++ b/interp/notation_ops.ml
@@ -28,7 +28,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
@@ -165,15 +165,15 @@ let glob_constr_of_notation_constr_with_binders ?loc g f e nc =
| NApp (a,args) -> GApp (f e a, List.map (f e) args)
| NList (x,y,iter,tail,swap) ->
let t = f e tail in let it = f e iter in
- let innerl = (ldots_var,t)::(if swap then [] else [x, lt @@ GVar y]) in
+ let innerl = (ldots_var,t)::(if swap then [y, lt @@ GVar x] else []) in
let inner = lt @@ GApp (lt @@ GVar (ldots_var),[subst_glob_vars innerl it]) in
- let outerl = (ldots_var,inner)::(if swap then [x, lt @@ GVar y] else []) in
+ let outerl = (ldots_var,inner)::(if swap then [] else [y, lt @@ GVar x]) in
DAst.get (subst_glob_vars outerl it)
| NBinderList (x,y,iter,tail,swap) ->
let t = f e tail in let it = f e iter in
- let innerl = (ldots_var,t)::(if swap then [] else [x, lt @@ GVar y]) in
+ let innerl = (ldots_var,t)::(if swap then [y, lt @@ GVar x] else []) in
let inner = lt @@ GApp (lt @@ GVar ldots_var,[subst_glob_vars innerl it]) in
- let outerl = (ldots_var,inner)::(if swap then [x, lt @@ GVar y] else []) in
+ let outerl = (ldots_var,inner)::(if swap then [] else [y, lt @@ GVar x]) in
DAst.get (subst_glob_vars outerl it)
| NLambda (na,ty,c) ->
let e',disjpat,na = g e na in GLambda (na,Explicit,f e ty,Option.fold_right (apply_cases_pattern ?loc) disjpat (f e' c))
@@ -1123,7 +1123,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 =
diff --git a/interp/notation_term.ml b/interp/notation_term.ml
index a9c2e2a53..1a46746cc 100644
--- a/interp/notation_term.ml
+++ b/interp/notation_term.ml
@@ -9,7 +9,6 @@
(************************************************************************)
open Names
-open Globnames
open Misctypes
open Glob_term
@@ -23,7 +22,7 @@ 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
diff --git a/interp/reserve.ml b/interp/reserve.ml
index 36005121b..b57103cf2 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 *)
diff --git a/interp/smartlocate.mli b/interp/smartlocate.mli
index 7ff7e899e..45037b8b3 100644
--- a/interp/smartlocate.mli
+++ b/interp/smartlocate.mli
@@ -18,22 +18,22 @@ open Misctypes
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 CAst.t -> 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 -> reference -> GlobRef.t
(** The same for inductive types *)
val global_inductive_with_alias : reference -> 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 -> reference or_by_notation -> GlobRef.t
(** The same for inductive types *)
val smart_global_inductive : reference or_by_notation -> inductive
diff --git a/interp/stdarg.mli b/interp/stdarg.mli
index 53d1a522d..dc9c370a1 100644
--- a/interp/stdarg.mli
+++ b/interp/stdarg.mli
@@ -14,7 +14,6 @@ open Loc
open Names
open EConstr
open Libnames
-open Globnames
open Genredexpr
open Pattern
open Constrexpr
@@ -42,7 +41,7 @@ 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_ref : (reference, GlobRef.t located or_var, GlobRef.t) genarg_type
val wit_quant_hyp : quantified_hypothesis uniform_genarg_type
@@ -81,8 +80,8 @@ 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 : (reference, GlobRef.t located or_var, GlobRef.t) genarg_type
+val wit_global : (reference, 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
diff --git a/kernel/byterun/coq_fix_code.c b/kernel/byterun/coq_fix_code.c
index d5feafbf9..be2b05da8 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 5c85389dd..638d6b5ab 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 cfeb0a9ee..8ac1ecc79 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"
@@ -629,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]);
}
@@ -665,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]);
}
@@ -1071,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];
@@ -1476,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;
@@ -1516,8 +1528,10 @@ value coq_push_vstack(value stk, value max_stack_size) {
}
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, t, g, e, Long_val(ea));
+ CAMLreturn (coq_interprete(Code_val(tcode), a, t, g, e, Long_val(ea)));
print_instr("end coq_interprete");
}
diff --git a/kernel/byterun/coq_memory.c b/kernel/byterun/coq_memory.c
index b2917a55e..542a05fd2 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"
@@ -46,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);
@@ -56,6 +62,10 @@ static void coq_scan_roots(scanning_action action)
register value * i;
/* 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 */
@@ -94,8 +104,12 @@ value init_coq_vm(value unit) /* ML */
/* 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 */
diff --git a/kernel/byterun/coq_values.c b/kernel/byterun/coq_values.c
index 528babebf..e05f3fb82 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/cemitcodes.ml b/kernel/cemitcodes.ml
index 14f4f27c0..cea09c510 100644
--- a/kernel/cemitcodes.ml
+++ b/kernel/cemitcodes.ml
@@ -20,7 +20,7 @@ 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 =
@@ -82,7 +82,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 *)
diff --git a/kernel/constr.ml b/kernel/constr.ml
index 4f062d72f..bc486210d 100644
--- a/kernel/constr.ml
+++ b/kernel/constr.ml
@@ -654,7 +654,7 @@ let map_with_binders g f l c0 = match kind c0 with
let bl' = CArray.Fun1.smartmap 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
@@ -692,10 +692,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)) ->
diff --git a/kernel/constr.mli b/kernel/constr.mli
index 0d464840c..b35ea6653 100644
--- a/kernel/constr.mli
+++ b/kernel/constr.mli
@@ -413,7 +413,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/names.ml b/kernel/names.ml
index a3aa71f24..58d311dd5 100644
--- a/kernel/names.ml
+++ b/kernel/names.ml
@@ -701,22 +701,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(
@@ -904,6 +888,34 @@ end
type projection = Projection.t
+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 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
+
let constant_of_kn = Constant.make1
let constant_of_kn_equiv = Constant.make
let make_con = Constant.make3
diff --git a/kernel/names.mli b/kernel/names.mli
index 96e020aed..566fcd0f9 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
@@ -749,6 +734,29 @@ end
type projection = Projection.t
[@@ocaml.deprecated "Alias for [Projection.t]"]
+(** {6 Global reference is a kernel side type for all references together } *)
+
+(* XXX: Should we define GlobRefCan GlobRefUser? *)
+module GlobRef : sig
+
+ 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 equal : t -> t -> bool
+
+end
+
+(** 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 eq_egr : evaluable_global_reference -> evaluable_global_reference -> bool
+
val constant_of_kn_equiv : KerName.t -> KerName.t -> Constant.t
[@@ocaml.deprecated "Same as [Constant.make]"]
diff --git a/kernel/vmvalues.ml b/kernel/vmvalues.ml
index 6a41efac2..7a703e653 100644
--- a/kernel/vmvalues.ml
+++ b/kernel/vmvalues.ml
@@ -59,14 +59,17 @@ let vm_global (v : values array) = (Obj.magic v : vm_global)
(*******************************************)
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 = {
@@ -255,6 +258,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 =
@@ -284,7 +288,7 @@ 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
@@ -370,17 +374,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
@@ -442,13 +449,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
@@ -486,7 +492,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
diff --git a/lib/control.ml b/lib/control.ml
index e67cd8b38..3fbeb168c 100644
--- a/lib/control.ml
+++ b/lib/control.ml
@@ -85,4 +85,7 @@ let timeout_fun = match Sys.os_type with
| "Unix" | "Cygwin" -> { timeout = unix_timeout }
| _ -> { timeout = windows_timeout }
-let timeout n f e = timeout_fun.timeout n f e
+let timeout_fun_ref = ref timeout_fun
+let set_timeout f = timeout_fun_ref := f
+
+let timeout n f e = !timeout_fun_ref.timeout n f e
diff --git a/lib/control.mli b/lib/control.mli
index 415e05462..59e2a1515 100644
--- a/lib/control.mli
+++ b/lib/control.mli
@@ -24,3 +24,8 @@ val check_for_interrupt : unit -> unit
val timeout : int -> ('a -> 'b) -> 'a -> exn -> 'b
(** [timeout n f x e] tries to compute [f x], and if it fails to do so
before [n] seconds, it raises [e] instead. *)
+
+(** Set a particular timeout function; warning, this is an internal
+ API and it is scheduled to go away. *)
+type timeout = { timeout : 'a 'b. int -> ('a -> 'b) -> 'a -> exn -> 'b }
+val set_timeout : timeout -> unit
diff --git a/lib/coqProject_file.ml4 b/lib/coqProject_file.ml4
index d6c340f69..61eb1dafd 100644
--- a/lib/coqProject_file.ml4
+++ b/lib/coqProject_file.ml4
@@ -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 }
@@ -122,7 +130,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);
@@ -140,7 +148,7 @@ let process_cmd_line orig_dir proj args =
| ("-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 +175,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
diff --git a/lib/flags.ml b/lib/flags.ml
index 56940f1cf..7e0065beb 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -57,8 +57,6 @@ let in_toplevel = ref false
let profile = false
-let ide_slave = ref false
-
let raw_print = ref false
let we_are_parsing = ref false
diff --git a/lib/flags.mli b/lib/flags.mli
index 17776d68a..02d8a3adc 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -52,9 +52,6 @@ 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
diff --git a/lib/stateid.ml b/lib/stateid.ml
index a258d5052..5485c4bf1 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 dfede29e8..f109c7192 100644
--- a/lib/system.ml
+++ b/lib/system.ml
@@ -116,18 +116,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 +300,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.argv.(0) 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 3349dfea3..a34280037 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/library/coqlib.ml b/library/coqlib.ml
index 3f01c617c..408e25919 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 8077c47c7..b4bd1b0e0 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/library/global.mli b/library/global.mli
index 015f4d582..906d246ee 100644
--- a/library/global.mli
+++ b/library/global.mli
@@ -123,26 +123,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 } *)
diff --git a/library/globnames.ml b/library/globnames.ml
index 2fa3adba2..6b78d12ba 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
- | (ConstRef _ | IndRef _ | ConstructRef _ | VarRef _), _ -> 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"
@@ -245,3 +237,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 f2b88b870..2fe35ebcc 100644
--- a/library/globnames.mli
+++ b/library/globnames.mli
@@ -14,71 +14,73 @@ 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
+val global_of_constr : constr -> GlobRef.t
(** Obsolete synonyms for constr_of_global and global_of_constr *)
-val reference_of_constr : constr -> global_reference
+val reference_of_constr : constr -> GlobRef.t
[@@ocaml.deprecated "Alias of Globnames.global_of_constr"]
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 +91,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 +102,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/keys.ml b/library/keys.ml
index 34a6adabe..89363455d 100644
--- a/library/keys.ml
+++ b/library/keys.ml
@@ -10,12 +10,13 @@
(** Keys for unification and indexing *)
-open Globnames
+open Names
open Term
+open Globnames
open Libobject
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 1fb9a3de0..198383650 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 543cb45bc..8a54995b9 100644
--- a/library/lib.ml
+++ b/library/lib.ml
@@ -183,22 +183,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
@@ -580,13 +569,11 @@ 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. *)
diff --git a/library/lib.mli b/library/lib.mli
index 26f1718cc..1d77212e9 100644
--- a/library/lib.mli
+++ b/library/lib.mli
@@ -8,7 +8,7 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-
+open Names
(** Lib: record of operations, backtrack, low-level sections *)
(** This module provides a general mechanism to keep a trace of all operations
@@ -28,7 +28,7 @@ type node =
and 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 +54,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 +76,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 +97,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 +124,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]). } *)
@@ -164,31 +164,31 @@ type abstr_info = private {
(** Universe quantification, same length as the substitution *)
}
-val instance_from_variable_context : variable_context -> Names.Id.t array
+val instance_from_variable_context : variable_context -> Id.t array
val named_of_variable_context : variable_context -> Context.Named.t
-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 -> Context.Named.t -> unit
val add_section_kn : Decl_kinds.polymorphic ->
- Names.MutInd.t -> Context.Named.t -> unit
+ MutInd.t -> Context.Named.t -> 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_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 d84731322..4ceea480d 100644
--- a/library/libnames.ml
+++ b/library/libnames.ml
@@ -174,8 +174,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,7 +185,6 @@ 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 =
diff --git a/library/libnames.mli b/library/libnames.mli
index 9dad26129..81e5bc5b1 100644
--- a/library/libnames.mli
+++ b/library/libnames.mli
@@ -125,8 +125,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! *)
val eq_global_dir_reference :
global_dir_reference -> global_dir_reference -> bool
diff --git a/library/misctypes.ml b/library/misctypes.ml
index 72db3b31c..b5d30559d 100644
--- a/library/misctypes.ml
+++ b/library/misctypes.ml
@@ -50,25 +50,6 @@ type 'id move_location =
| 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
diff --git a/library/nametab.ml b/library/nametab.ml
index 2046bf758..995f44706 100644
--- a/library/nametab.ml
+++ b/library/nametab.ml
@@ -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 =
diff --git a/library/nametab.mli b/library/nametab.mli
index cd28518ab..2ec73a986 100644
--- a/library/nametab.mli
+++ b/library/nametab.mli
@@ -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 : reference -> GlobRef.t
val global_inductive : reference -> 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,7 +168,7 @@ 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_global : Id.Set.t -> GlobRef.t -> 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
@@ -177,7 +177,7 @@ val shortest_qualid_of_universe : 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} *)
diff --git a/man/coqtop.1 b/man/coqtop.1
index b1fbb3262..084adfe45 100644
--- a/man/coqtop.1
+++ b/man/coqtop.1
@@ -110,7 +110,7 @@ print Coq version and exit
.TP
.B \-q
-skip loading of rcfile
+skip loading of rcfile (resource file) if any
.TP
.BI \-init\-file \ filename
diff --git a/parsing/g_constr.ml4 b/parsing/g_constr.ml4
index 9c2806bea..a03ef268d 100644
--- a/parsing/g_constr.ml4
+++ b/parsing/g_constr.ml4
@@ -10,6 +10,7 @@
open Names
open Libnames
+open Glob_term
open Constrexpr
open Constrexpr_ops
open Util
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index 3026be248..a1c563f53 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -646,7 +646,7 @@ GEXTEND Gram
| IDENT "Existing"; IDENT "Instances"; ids = LIST1 global;
pri = OPT [ "|"; i = natural -> i ] ->
- let info = { hint_priority = pri; hint_pattern = None } in
+ let info = { Typeclasses.hint_priority = pri; hint_pattern = None } in
let insts = List.map (fun i -> (i, info)) ids in
VernacDeclareInstances insts
@@ -771,8 +771,8 @@ GEXTEND Gram
;
hint_info:
[ [ "|"; i = OPT natural; pat = OPT constr_pattern ->
- { hint_priority = i; hint_pattern = pat }
- | -> { hint_priority = None; hint_pattern = None } ] ]
+ { 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] ] ]
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index 9f186224b..387a62604 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -227,8 +227,8 @@ module Constr :
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 universe_level : Glob_term.glob_level Gram.entry
+ val sort : Glob_term.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
@@ -260,7 +260,7 @@ module Vernac_ :
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 hint_info : Typeclasses.hint_info_expr Gram.entry
end
(** The main entry: reads an optional vernac command *)
diff --git a/plugins/btauto/refl_btauto.ml b/plugins/btauto/refl_btauto.ml
index a09abfa19..7f98ed427 100644
--- a/plugins/btauto/refl_btauto.ml
+++ b/plugins/btauto/refl_btauto.ml
@@ -2,11 +2,11 @@ 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
diff --git a/plugins/cc/cctac.ml b/plugins/cc/cctac.ml
index c4db49cd3..361981c5b 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
@@ -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
diff --git a/plugins/extraction/common.mli b/plugins/extraction/common.mli
index 78545c8bd..07237d750 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 397cb2920..bebd27e11 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
diff --git a/plugins/extraction/extract_env.mli b/plugins/extraction/extract_env.mli
index 591d3bb86..77f1fb5ef 100644
--- a/plugins/extraction/extract_env.mli
+++ b/plugins/extraction/extract_env.mli
@@ -12,7 +12,6 @@
open Names
open Libnames
-open Globnames
val simple_extraction : reference -> unit
val full_extraction : string option -> reference list -> unit
@@ -26,7 +25,7 @@ val extract_and_compile : reference 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 f25f63624..cdd698304 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
diff --git a/plugins/extraction/miniml.ml b/plugins/extraction/miniml.ml
index e1e49d926..ce920ad6a 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 e1e49d926..ce920ad6a 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 0656d487a..0901acc7d 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) =
@@ -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 55a1ee893..d23fdb3d5 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 f33a59edf..b398bc07a 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 6a81f2705..f45773f09 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 54c6d9d72..c3f4cfe65 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 906dfd96e..5bf944434 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
diff --git a/plugins/firstorder/formula.ml b/plugins/firstorder/formula.ml
index 047fc9fbf..a60a966ce 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 2962d9230..e2c6f1c4b 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/instances.ml b/plugins/firstorder/instances.ml
index e8c0b927d..22a3e1f67 100644
--- a/plugins/firstorder/instances.ml
+++ b/plugins/firstorder/instances.ml
@@ -43,7 +43,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 *)
diff --git a/plugins/firstorder/instances.mli b/plugins/firstorder/instances.mli
index 61786ffdc..9f9ade3aa 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 cfcd65619..b13580bc0 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 859388b30..924c26790 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 7c612c0d8..0c752d4a4 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
@@ -87,7 +87,7 @@ let cm_remove sigma typ nam cm=
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 =
@@ -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])
diff --git a/plugins/firstorder/sequent.mli b/plugins/firstorder/sequent.mli
index c4ed3e21f..709b278ec 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/fourier/fourierR.ml b/plugins/fourier/fourierR.ml
index b1c003de2..96be1d893 100644
--- a/plugins/fourier/fourierR.ml
+++ b/plugins/fourier/fourierR.ml
@@ -227,7 +227,7 @@ let ineq1_of_constr (h,t) =
hstrict=false}]
|_-> raise NoIneq)
| Ind ((kn,i),_) ->
- if not (eq_gr (IndRef(kn,i)) Coqlib.glob_eq) then raise NoIneq;
+ if not (GlobRef.equal (IndRef(kn,i)) Coqlib.glob_eq) then raise NoIneq;
let t0= args.(0) in
let t1= args.(1) in
let t2= args.(2) in
@@ -283,15 +283,15 @@ let fourier_lineq lineq1 =
let get = Lazy.force
let cget = get
let eget c = EConstr.of_constr (Lazy.force c)
-let constant path s = Universes.constr_of_global @@
+let constant path s = UnivGen.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 ())
+let coq_False = lazy (UnivGen.constr_of_global @@ build_coq_False ())
+let coq_not = lazy (UnivGen.constr_of_global @@ build_coq_not ())
+let coq_eq = lazy (UnivGen.constr_of_global @@ build_coq_eq ())
(* Rdefinitions *)
let constant_real = constant ["Reals";"Rdefinitions"]
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index 8da0e1c4f..3801fec4b 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -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
@@ -1051,7 +1051,8 @@ let do_replace (evd:Evd.evar_map ref) params rec_arg_num rev_args_id f fun_num a
(Constrintern.locate_reference (qualid_of_ident equation_lemma_id))
in
evd:=evd';
- let _ = Typing.e_type_of ~refresh:true (Global.env ()) evd res in
+ 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
@@ -1602,7 +1603,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 *)
diff --git a/plugins/funind/functional_principles_types.ml b/plugins/funind/functional_principles_types.ml
index 04a23cdb9..a158fc8ff 100644
--- a/plugins/funind/functional_principles_types.ml
+++ b/plugins/funind/functional_principles_types.ml
@@ -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
@@ -630,7 +631,8 @@ let build_scheme fas =
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 f in
+ let sigma, _ = Typing.type_of ~refresh:true (Global.env ()) !evd f in
+ evd := sigma;
let c, u =
try EConstr.destConst !evd f
with DestKO ->
@@ -687,7 +689,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/glob_term_to_relation.ml b/plugins/funind/glob_term_to_relation.ml
index 319b410df..3ba3bafa4 100644
--- a/plugins/funind/glob_term_to_relation.ml
+++ b/plugins/funind/glob_term_to_relation.ml
@@ -885,7 +885,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
@@ -894,7 +894,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 =
diff --git a/plugins/funind/glob_termops.ml b/plugins/funind/glob_termops.ml
index e331dc014..ae238b846 100644
--- a/plugins/funind/glob_termops.ml
+++ b/plugins/funind/glob_termops.ml
@@ -576,7 +576,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)
| _ -> ()
)
diff --git a/plugins/funind/glob_termops.mli b/plugins/funind/glob_termops.mli
index 7088ae596..481a8be3b 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 748d8add2..efbd029e4 100644
--- a/plugins/funind/indfun.ml
+++ b/plugins/funind/indfun.ml
@@ -385,7 +385,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 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
@@ -846,7 +847,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 ->
diff --git a/plugins/funind/indfun.mli b/plugins/funind/indfun.mli
index dcc1c2ea6..24304e361 100644
--- a/plugins/funind/indfun.mli
+++ b/plugins/funind/indfun.mli
@@ -1,3 +1,4 @@
+open Names
open Misctypes
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 a0b9217c7..35c3acd41 100644
--- a/plugins/funind/indfun_common.ml
+++ b/plugins/funind/indfun_common.ml
@@ -117,7 +117,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;;
@@ -471,7 +471,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 +479,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 +492,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 5cc7163aa..346b21ef2 100644
--- a/plugins/funind/indfun_common.mli
+++ b/plugins/funind/indfun_common.mli
@@ -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 28e85268a..180952635 100644
--- a/plugins/funind/invfun.ml
+++ b/plugins/funind/invfun.ml
@@ -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
@@ -103,7 +103,8 @@ let generate_type evd g_to_f f graph i =
Evd.fresh_global (Global.env ()) !evd (Globnames.IndRef (fst (destInd !evd 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
@@ -511,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[
@@ -769,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
diff --git a/plugins/funind/invfun.mli b/plugins/funind/invfun.mli
index ad306ab25..9151fd0e2 100644
--- a/plugins/funind/invfun.mli
+++ b/plugins/funind/invfun.mli
@@ -10,7 +10,7 @@
val invfun :
Misctypes.quantified_hypothesis ->
- Globnames.global_reference option ->
+ 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 e41bf71dd..2464c595f 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -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 =
@@ -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 *)
@@ -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
@@ -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
diff --git a/plugins/ltac/evar_tactics.ml b/plugins/ltac/evar_tactics.ml
index 9382f567b..fb6be430f 100644
--- a/plugins/ltac/evar_tactics.ml
+++ b/plugins/ltac/evar_tactics.ml
@@ -85,9 +85,7 @@ 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
diff --git a/plugins/ltac/extratactics.ml4 b/plugins/ltac/extratactics.ml4
index a5f8060ae..797dfbe23 100644
--- a/plugins/ltac/extratactics.ml4
+++ b/plugins/ltac/extratactics.ml4
@@ -315,7 +315,7 @@ let project_hint ~poly pri l2r r =
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
+ let info = {Typeclasses.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 =
diff --git a/plugins/ltac/rewrite.ml b/plugins/ltac/rewrite.ml
index 9eb55aa5e..1b86583da 100644
--- a/plugins/ltac/rewrite.ml
+++ b/plugins/ltac/rewrite.ml
@@ -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
@@ -1469,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) =
diff --git a/plugins/ltac/taccoerce.mli b/plugins/ltac/taccoerce.mli
index 1fa5e3c07..5185217cd 100644
--- a/plugins/ltac/taccoerce.mli
+++ b/plugins/ltac/taccoerce.mli
@@ -80,7 +80,7 @@ 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 : Environ.env -> Evd.evar_map -> Value.t -> GlobRef.t
val coerce_to_quantified_hypothesis : Evd.evar_map -> Value.t -> quantified_hypothesis
diff --git a/plugins/ltac/tacinterp.ml b/plugins/ltac/tacinterp.ml
index 84049d4ed..a93cf5ae7 100644
--- a/plugins/ltac/tacinterp.ml
+++ b/plugins/ltac/tacinterp.ml
@@ -691,11 +691,9 @@ let interp_may_eval f ist env sigma = function
let (sigma,ic) = f ist env sigma c in
let ctxt = coerce_to_constr_context (Id.Map.find s ist.lfun) 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"
diff --git a/plugins/ltac/tactic_matching.ml b/plugins/ltac/tactic_matching.ml
index b6462c810..c949589e2 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/micromega/coq_micromega.ml b/plugins/micromega/coq_micromega.ml
index 168105e8f..4c0357dd8 100644
--- a/plugins/micromega/coq_micromega.ml
+++ b/plugins/micromega/coq_micromega.ml
@@ -373,7 +373,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
diff --git a/plugins/nsatz/nsatz.ml b/plugins/nsatz/nsatz.ml
index 81b44ffad..d2d4639d2 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/coq_omega.ml b/plugins/omega/coq_omega.ml
index 51cd665f6..e455ebb28 100644
--- a/plugins/omega/coq_omega.ml
+++ b/plugins/omega/coq_omega.ml
@@ -206,7 +206,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
diff --git a/plugins/quote/quote.ml b/plugins/quote/quote.ml
index 912429c31..7464b42dc 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 ad3afafd8..949cba2db 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/rtauto/refl_tauto.ml b/plugins/rtauto/refl_tauto.ml
index 946b6dff4..8a0f48dc4 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/newring.ml b/plugins/setoid_ring/newring.ml
index 33c30e4d3..59ba4b7de 100644
--- a/plugins/setoid_ring/newring.ml
+++ b/plugins/setoid_ring/newring.ml
@@ -78,7 +78,7 @@ and mk_clos_app_but f_map subs f args n =
| None -> mk_atom (mkApp (f, args))
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 add_map s m = protect_maps := String.Map.add s m !protect_maps
@@ -105,7 +105,7 @@ let protect_tac_in map id =
let closed_term t l =
let open Quote_plugin in
Proofview.tclEVARMAP >>= fun sigma ->
- let l = List.map Universes.constr_of_global l in
+ let l = List.map UnivGen.constr_of_global l in
let cs = List.fold_right Quote.ConstrSet.add l Quote.ConstrSet.empty in
if Quote.closed_under sigma cs t then Proofview.tclUNIT () else Tacticals.New.tclFAIL 0 (mt())
@@ -233,7 +233,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 +247,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 +279,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 +505,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 +589,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 +736,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 =
@@ -917,7 +927,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|])
| _ ->
diff --git a/plugins/setoid_ring/newring.mli b/plugins/setoid_ring/newring.mli
index 1d1557b12..0e056a472 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,7 +18,7 @@ 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 closed_term : EConstr.constr -> GlobRef.t list -> unit Proofview.tactic
val add_theory :
Id.t ->
diff --git a/plugins/ssr/ssrcommon.ml b/plugins/ssr/ssrcommon.ml
index d012fd0df..c0026616d 100644
--- a/plugins/ssr/ssrcommon.ml
+++ b/plugins/ssr/ssrcommon.ml
@@ -1221,7 +1221,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)
@@ -1505,7 +1505,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 2b8f1d540..9ba23467e 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/ssrelim.ml b/plugins/ssr/ssrelim.ml
index de8ffb976..87d107d65 100644
--- a/plugins/ssr/ssrelim.ml
+++ b/plugins/ssr/ssrelim.ml
@@ -418,7 +418,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 7748ba2b0..a31022919 100644
--- a/plugins/ssr/ssrequality.ml
+++ b/plugins/ssr/ssrequality.ml
@@ -369,8 +369,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
@@ -435,7 +435,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
@@ -482,7 +482,7 @@ let rwprocess_rule dir rule gl =
| _ ->
let sigma, pi2 = Evd.fresh_global env sigma coq_prod.Coqlib.proj2 in
EConstr.mkApp (pi2, ra), sigma in
- if EConstr.eq_constr sigma a.(0) (EConstr.of_constr (Universes.constr_of_global @@ Coqlib.build_coq_True ())) then
+ 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
diff --git a/plugins/ssr/ssrfwd.ml b/plugins/ssr/ssrfwd.ml
index 6e17e8e15..c6beb08c5 100644
--- a/plugins/ssr/ssrfwd.ml
+++ b/plugins/ssr/ssrfwd.ml
@@ -184,9 +184,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/ssrtacticals.ml b/plugins/ssr/ssrtacticals.ml
index 9cc4f5cec..937e68b06 100644
--- a/plugins/ssr/ssrtacticals.ml
+++ b/plugins/ssr/ssrtacticals.ml
@@ -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
diff --git a/plugins/ssrmatching/ssrmatching.ml4 b/plugins/ssrmatching/ssrmatching.ml4
index a10437a63..0dd3625ba 100644
--- a/plugins/ssrmatching/ssrmatching.ml4
+++ b/plugins/ssrmatching/ssrmatching.ml4
@@ -1099,15 +1099,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
diff --git a/plugins/syntax/ascii_syntax.ml b/plugins/syntax/ascii_syntax.ml
index acb297ddf..47a59ba63 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"]
diff --git a/plugins/syntax/int31_syntax.ml b/plugins/syntax/int31_syntax.ml
index 5529ea700..f10f98e23 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)
diff --git a/plugins/syntax/nat_syntax.ml b/plugins/syntax/nat_syntax.ml
index ad8b54d4d..e158e0b51 100644
--- a/plugins/syntax/nat_syntax.ml
+++ b/plugins/syntax/nat_syntax.ml
@@ -16,11 +16,12 @@ let () = Mltop.add_known_module __coq_plugin_name
(* This file defines the printer for natural numbers in [nat] *)
(*i*)
+open Pp
+open CErrors
+open Names
open Glob_term
open Bigint
open Coqlib
-open Pp
-open CErrors
(*i*)
(**********************************************************************)
@@ -61,10 +62,10 @@ 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)
+ | GRef (s,_) when GlobRef.equal s glob_S -> add_1 (int_of_nat a)
| _ -> raise Non_closed_number
end
- | GRef (z,_) when Globnames.eq_gr z glob_O -> zero
+ | GRef (z,_) when GlobRef.equal z glob_O -> zero
| _ -> raise Non_closed_number
) x
diff --git a/plugins/syntax/r_syntax.ml b/plugins/syntax/r_syntax.ml
index 372e8ff30..94aa14335 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
(**********************************************************************)
diff --git a/plugins/syntax/string_syntax.ml b/plugins/syntax/string_syntax.ml
index 2421cc12f..c22869f4d 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
diff --git a/plugins/syntax/z_syntax.ml b/plugins/syntax/z_syntax.ml
index d5300e474..09fe8bf70 100644
--- a/plugins/syntax/z_syntax.ml
+++ b/plugins/syntax/z_syntax.ml
@@ -71,13 +71,13 @@ let interp_positive ?loc n =
(**********************************************************************)
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 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
+ | GRef (a, _) when GlobRef.equal a glob_xH -> Bigint.one
| _ -> raise Non_closed_number
) x
@@ -132,7 +132,7 @@ let n_of_int ?loc n =
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
+ | GRef (a,_) when GlobRef.equal a glob_N0 -> Bigint.zero
| _ -> raise Non_closed_number
) n
@@ -180,7 +180,7 @@ let z_of_int ?loc n =
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
+ | GRef (a, _) when GlobRef.equal a glob_ZERO -> Bigint.zero
| _ -> raise Non_closed_number
) z
diff --git a/pretyping/arguments_renaming.ml b/pretyping/arguments_renaming.ml
index 84295959f..9d4badc60 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 65e3c3be5..6a776dc96 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 4c87b4e7e..ee7c39982 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 _ -> []
@@ -372,8 +377,7 @@ 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 =
@@ -396,12 +400,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 +424,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)
@@ -1014,8 +1014,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 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
| _ ->
@@ -1681,7 +1681,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
@@ -1712,7 +1712,7 @@ let abstract_tycon ?loc env evdref subst tycon extenv t =
(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 ev = evd_comb1 (Evarutil.new_evar extenv ~src ~filter ~candidates) evdref ty in
lift k ev
in
aux (0,extenv,subst0) t0
@@ -1724,17 +1724,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 +1926,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. *)
diff --git a/pretyping/classops.ml b/pretyping/classops.ml
index a0804b72b..7dbef01c2 100644
--- a/pretyping/classops.ml
+++ b/pretyping/classops.ml
@@ -37,7 +37,7 @@ type cl_info_typ = {
cl_param : int
}
-type coe_typ = global_reference
+type coe_typ = GlobRef.t
module CoeTypMap = Refmap_env
@@ -316,7 +316,7 @@ let lookup_pattern_path_between env (s,t) =
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 subst, ctx = UnivGen.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
@@ -440,7 +440,7 @@ 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 value, ctx = UnivGen.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 =
diff --git a/pretyping/classops.mli b/pretyping/classops.mli
index f8600bbe0..35691ea37 100644
--- a/pretyping/classops.mli
+++ b/pretyping/classops.mli
@@ -36,7 +36,7 @@ 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
diff --git a/pretyping/coercion.ml b/pretyping/coercion.ml
index 6dc3687a0..c9c2445a7 100644
--- a/pretyping/coercion.ml
+++ b/pretyping/coercion.ml
@@ -48,31 +48,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 cst = fst (destConst sigma (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 }
+ sigma, { uj_val = applist (mkProj (p, hd), tl);
+ uj_type = typ }
else
- { uj_val = applist (j_val funj,argl);
- uj_type = typ }
+ 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 =
@@ -94,7 +98,9 @@ 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 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 +197,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. *)
@@ -337,8 +344,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
diff --git a/pretyping/constr_matching.ml b/pretyping/constr_matching.ml
index 89d490a41..0ff6a330f 100644
--- a/pretyping/constr_matching.ml
+++ b/pretyping/constr_matching.ml
@@ -20,7 +20,6 @@ open EConstr
open Vars
open Pattern
open Patternops
-open Misctypes
open Context.Rel.Declaration
open Ltac_pretype
(*i*)
@@ -277,6 +276,7 @@ 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
@@ -427,7 +427,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) )
@@ -451,7 +451,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 3c2c73915..d19789ef4 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/constrexpr.ml b/pretyping/constrexpr.ml
index fda31756a..1443dfb51 100644
--- a/pretyping/constrexpr.ml
+++ b/pretyping/constrexpr.ml
@@ -17,7 +17,7 @@ open Decl_kinds
(** [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) gen_universe_decl
type ident_decl = lident * universe_decl_expr option
type name_decl = lname * universe_decl_expr option
@@ -50,7 +50,7 @@ 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
@@ -98,7 +98,7 @@ and constr_expr_r =
| CHole of Evar_kinds.t option * intro_pattern_naming_expr * Genarg.raw_generic_argument option
| CPatVar of patvar
| CEvar of Glob_term.existential_name * (Id.t * constr_expr) list
- | CSort of glob_sort
+ | CSort of Glob_term.glob_sort
| CCast of constr_expr * constr_expr cast_type
| CNotation of notation * constr_notation_substitution
| CGeneralization of binding_kind * abstraction_kind option * constr_expr
diff --git a/pretyping/detyping.mli b/pretyping/detyping.mli
index 817b8ba6e..5310455fe 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
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 144166a34..062136ff5 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)
@@ -210,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
@@ -1159,17 +1159,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 ->
@@ -1394,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 9270d6e3a..cdf5dd0e5 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/glob_ops.ml b/pretyping/glob_ops.ml
index e89bbf7c3..3ae04cd4f 100644
--- a/pretyping/glob_ops.ml
+++ b/pretyping/glob_ops.ml
@@ -113,7 +113,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
diff --git a/pretyping/glob_term.ml b/pretyping/glob_term.ml
index 84be15552..6ecb479e6 100644
--- a/pretyping/glob_term.ml
+++ b/pretyping/glob_term.ml
@@ -17,12 +17,30 @@
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.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
+
(** The kind of patterns that occurs in "match ... with ... end"
locs here refers to the ident's location, not whole pat *)
@@ -36,7 +54,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
diff --git a/pretyping/indrec.ml b/pretyping/indrec.ml
index 3327c250d..40f4d4ff8 100644
--- a/pretyping/indrec.ml
+++ b/pretyping/indrec.ml
@@ -86,7 +86,7 @@ let mis_make_case_com dep env sigma (ind, u as pind) (mib,mip as specif) kind =
if not (Sorts.List.mem kind (elim_sorts specif)) then
raise
(RecursionSchemeError
- (NotAllowedCaseAnalysis (false, fst (Universes.fresh_sort_in_family env kind), pind)))
+ (NotAllowedCaseAnalysis (false, fst (UnivGen.fresh_sort_in_family env kind), pind)))
in
let ndepar = mip.mind_nrealdecls + 1 in
@@ -550,7 +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
+ (NotAllowedCaseAnalysis (true, fst (UnivGen.fresh_sort_in_family env
kind),(mind,u))))
else if Int.List.mem ni ln then raise
(RecursionSchemeError (NotMutualInScheme (mind,mind)))
diff --git a/pretyping/indrec.mli b/pretyping/indrec.mli
index 119ff5222..d87a19d28 100644
--- a/pretyping/indrec.mli
+++ b/pretyping/indrec.mli
@@ -61,7 +61,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/miscops.ml b/pretyping/miscops.ml
index 0f0af5409..1b536bfda 100644
--- a/pretyping/miscops.ml
+++ b/pretyping/miscops.ml
@@ -29,7 +29,7 @@ let smartmap_cast_type f c =
(** Equalities on [glob_sort] *)
-let glob_sort_eq g1 g2 = match g1, g2 with
+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 ->
diff --git a/pretyping/miscops.mli b/pretyping/miscops.mli
index abe817fe5..1d4504541 100644
--- a/pretyping/miscops.mli
+++ b/pretyping/miscops.mli
@@ -18,7 +18,7 @@ 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
+val glob_sort_eq : Glob_term.glob_sort -> Glob_term.glob_sort -> bool
(** Equalities on [intro_pattern_naming] *)
diff --git a/pretyping/pattern.ml b/pretyping/pattern.ml
index 76367b612..996a2dc36 100644
--- a/pretyping/pattern.ml
+++ b/pretyping/pattern.ml
@@ -9,7 +9,6 @@
(************************************************************************)
open Names
-open Globnames
open Misctypes
(** {5 Patterns} *)
@@ -21,7 +20,7 @@ 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
| PRel of int
@@ -31,7 +30,7 @@ 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 *
diff --git a/pretyping/patternops.ml b/pretyping/patternops.ml
index 27e457e3b..ccfb7f990 100644
--- a/pretyping/patternops.ml
+++ b/pretyping/patternops.ml
@@ -30,7 +30,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
diff --git a/pretyping/patternops.mli b/pretyping/patternops.mli
index 9f0878578..dfbfb147f 100644
--- a/pretyping/patternops.mli
+++ b/pretyping/patternops.mli
@@ -8,12 +8,12 @@
(* * (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 +32,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/pretyping.ml b/pretyping/pretyping.ml
index e68a25a87..6bf852fcd 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -169,14 +169,6 @@ 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 =
@@ -245,7 +237,7 @@ let interp_known_level_info ?loc evd = function
with Not_found ->
user_err ?loc ~hdr:"interp_known_level_info" (str "Undeclared universe " ++ Libnames.pr_reference ref)
-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
@@ -499,7 +491,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
@@ -674,14 +666,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 +694,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
@@ -793,9 +789,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
@@ -1166,10 +1165,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 415c4e172..73f5b77e0 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/program.ml b/pretyping/program.ml
index 52d940d8e..8cfb7966c 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 df0848ba1..a8f511578 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 d070edead..84aceeedd 100644
--- a/pretyping/recordops.ml
+++ b/pretyping/recordops.ml
@@ -144,13 +144,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
diff --git a/pretyping/recordops.mli b/pretyping/recordops.mli
index 1f7b23c0c..748f053b2 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,10 @@ 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
(** {6 Canonical structures } *)
(** A canonical structure declares "canonical" conversion hints between
@@ -52,7 +51,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 +70,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 244b8e60b..34d7a0798 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -83,7 +83,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
+ let termkey = UnivGen.constr_of_global x in
Lib.add_anonymous_leaf (inReductionEffect (termkey,funkey))
@@ -104,7 +104,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
@@ -701,18 +701,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) ->
diff --git a/pretyping/reductionops.mli b/pretyping/reductionops.mli
index b8ac085a7..ad280d9f3 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,7 +41,7 @@ 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 : GlobRef.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 ->
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index 696001ab7..5a47acd22 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -1279,7 +1279,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 aa7604f53..e6065dda8 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 30ddeffa6..11cc6c1f0 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_expr = Constrexpr.constr_pattern_expr 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 * Context.Rel.t;
(* Context of definitions and properties on defs, will not be shared *)
cl_props : Context.Rel.t;
(* The method implementaions as projections. *)
- cl_projs : (Name.t * (direction * Vernacexpr.hint_info_expr) option
+ cl_projs : (Name.t * (direction * hint_info_expr) 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_expr;
(* 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 =
@@ -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 b80c28711..2a8e0b874 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_expr = Constrexpr.constr_pattern_expr hint_info_gen
+
(** This module defines type-classes *)
type typeclass = {
(** The toplevel universe quantification in which the typeclass lives. In
@@ -24,11 +31,11 @@ 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 * Context.Rel.t;
(** Context of definitions and properties on defs, will not be shared *)
cl_props : Context.Rel.t;
@@ -37,7 +44,7 @@ type typeclass = {
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_expr) 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_expr -> 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_expr -> 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_expr -> 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_expr 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_expr ->
+ (GlobRef.t list * hint_info_expr * constr) list
diff --git a/pretyping/typeclasses_errors.ml b/pretyping/typeclasses_errors.ml
index e10c81c24..89c5d7e7b 100644
--- a/pretyping/typeclasses_errors.ml
+++ b/pretyping/typeclasses_errors.ml
@@ -9,17 +9,17 @@
(************************************************************************)
(*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 *)
+ | UnboundMethod of GlobRef.t * Misctypes.lident (* Class name, method *)
| MismatchedContextInstance of contexts * constr_expr list * Context.Rel.t (* found, expected *)
exception TypeClassError of env * typeclass_error
diff --git a/pretyping/typeclasses_errors.mli b/pretyping/typeclasses_errors.mli
index d98295658..4aabc0aee 100644
--- a/pretyping/typeclasses_errors.mli
+++ b/pretyping/typeclasses_errors.mli
@@ -8,23 +8,23 @@
(* * (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 *)
+ | UnboundMethod of GlobRef.t * Misctypes.lident (** Class name, method *)
| MismatchedContextInstance of contexts * constr_expr list * Context.Rel.t (** found, expected *)
exception TypeClassError of env * typeclass_error
val not_a_class : env -> constr -> 'a
-val unbound_method : env -> global_reference -> Misctypes.lident -> 'a
+val unbound_method : env -> GlobRef.t -> Misctypes.lident -> 'a
val mismatched_ctx_inst : env -> contexts -> constr_expr list -> Context.Rel.t -> 'a
diff --git a/pretyping/typing.ml b/pretyping/typing.ml
index aaec73f04..6bd75c93d 100644
--- a/pretyping/typing.ml
+++ b/pretyping/typing.ml
@@ -37,104 +37,115 @@ let inductive_type_knowing_parameters env sigma (ind,u) jl =
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 (mkSort s) evd
+ let sigma, s = Evd.fresh_sort_in_family env 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 =
@@ -147,39 +158,41 @@ 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 ~abort_on_undefined_evars:false !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 =
@@ -192,17 +205,19 @@ let check_allowed_sort env sigma ind c p =
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 }
-
-let enrich_env env evdref =
+ 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 sigma =
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
+ { penv.env_stratification with env_universes = Evd.universes sigma } }) in
Environ.env_of_pre_env penv'
let check_fix env sigma pfix =
@@ -267,165 +282,167 @@ 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
+ begin match ESorts.kind sigma s with
| Prop c ->
- judge_of_prop_contents c
+ sigma, judge_of_prop_contents c
| Type u ->
- judge_of_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 evdref = Array.map (execute env evdref)
+and execute_array env = Array.fold_left_map (execute env)
+
+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 env evdref c =
+ Evarutil.evd_comb1 (type_of ?refresh env) evdref c
-let e_type_of ?(refresh=false) env evdref c =
- let env = enrich_env env evdref in
- let j = execute env evdref c in
+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 4905adf1f..3cf43ace0 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
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index d98ce9aba..62bee5a36 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -198,8 +198,8 @@ let pose_all_metas_as_evars env evd t =
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 src = Evd.evar_source_of_meta mv !evdref in
- let ev = Evarutil.e_new_evar env evdref ~src ty in
- evdref := meta_assign mv (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
@@ -561,16 +561,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 =
@@ -1504,8 +1504,7 @@ let indirectly_dependent sigma 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 {
@@ -1593,9 +1592,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 =
diff --git a/pretyping/vernacexpr.ml b/pretyping/vernacexpr.ml
index 8bf810498..304a5dadd 100644
--- a/pretyping/vernacexpr.ml
+++ b/pretyping/vernacexpr.ml
@@ -32,8 +32,8 @@ 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
@@ -49,7 +49,7 @@ type printable =
| PrintMLLoadPath
| PrintMLModules
| PrintDebugGC
- | PrintName of reference or_by_notation * Universes.univ_name_list option
+ | PrintName of reference or_by_notation * UnivNames.univ_name_list option
| PrintGraph
| PrintClasses
| PrintTypeClasses
@@ -65,7 +65,7 @@ type printable =
| PrintScopes
| PrintScope of string
| PrintVisibility of string option
- | PrintAbout of reference or_by_notation * Universes.univ_name_list option * Goal_select.t option
+ | PrintAbout of reference or_by_notation * UnivNames.univ_name_list option * Goal_select.t option
| PrintImplicit of reference or_by_notation
| PrintAssumptions of bool * bool * reference or_by_notation
| PrintStrategy of reference or_by_notation option
@@ -112,14 +112,16 @@ type hint_mode =
| ModeNoHeadEvar (* No evar at the head *)
| ModeOutput (* Anything *)
-type 'a hint_info_gen =
+type 'a hint_info_gen = 'a Typeclasses.hint_info_gen =
{ hint_priority : int option;
hint_pattern : 'a option }
+[@@ocaml.deprecated "Please use [Typeclasses.hint_info_gen]"]
-type hint_info_expr = constr_pattern_expr hint_info_gen
+type hint_info_expr = Typeclasses.hint_info_expr
+[@@ocaml.deprecated "Please use [Typeclasses.hint_info_expr]"]
type hints_expr =
- | HintsResolve of (hint_info_expr * bool * reference_or_constr) list
+ | HintsResolve of (Typeclasses.hint_info_expr * bool * reference_or_constr) list
| HintsImmediate of reference_or_constr list
| HintsUnfold of reference list
| HintsTransparency of reference list * bool
@@ -336,7 +338,7 @@ type nonrec vernac_expr =
| 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
@@ -356,12 +358,12 @@ type nonrec vernac_expr =
local_binder_expr list * (* super *)
typeclass_constraint * (* instance name, class name, params *)
(bool * constr_expr) option * (* props *)
- hint_info_expr
+ Typeclasses.hint_info_expr
| VernacContext of local_binder_expr list
| VernacDeclareInstances of
- (reference * hint_info_expr) list (* instances names, priorities and patterns *)
+ (reference * Typeclasses.hint_info_expr) list (* instances names, priorities and patterns *)
| VernacDeclareClass of reference (* inductive or definition name *)
diff --git a/printing/ppconstr.ml b/printing/ppconstr.ml
index 412a1cbb4..60268c9de 100644
--- a/printing/ppconstr.ml
+++ b/printing/ppconstr.ml
@@ -170,13 +170,13 @@ 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")
@@ -199,7 +199,7 @@ 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 ->
diff --git a/printing/ppconstr.mli b/printing/ppconstr.mli
index 1f1308b0d..127c4471c 100644
--- a/printing/ppconstr.mli
+++ b/printing/ppconstr.mli
@@ -41,8 +41,8 @@ val pr_name : Name.t -> Pp.t
val pr_qualid : qualid -> Pp.t
val pr_patvar : 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 ->
diff --git a/printing/ppvernac.ml b/printing/ppvernac.ml
index 89117caf4..f26ac0bf9 100644
--- a/printing/ppvernac.ml
+++ b/printing/ppvernac.ml
@@ -188,7 +188,7 @@ open Pputils
| 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
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index 1f17d844f..d036fec21 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -35,8 +35,8 @@ 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;
@@ -93,7 +93,7 @@ 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 =
@@ -328,7 +328,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
@@ -376,7 +376,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 ->
@@ -595,7 +594,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
diff --git a/printing/prettyp.mli b/printing/prettyp.mli
index 213f0aeeb..50042d6c5 100644
--- a/printing/prettyp.mli
+++ b/printing/prettyp.mli
@@ -12,7 +12,6 @@ open Names
open Environ
open Reductionops
open Libnames
-open Globnames
open Misctypes
open Evd
@@ -35,10 +34,10 @@ val print_eval :
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
+ UnivNames.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
+ UnivNames.univ_name_list option -> Pp.t
val print_impargs : reference or_by_notation -> Pp.t
(** Pretty-printing functions for classes and coercions *)
@@ -50,7 +49,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
@@ -85,8 +84,8 @@ val print_located_module : reference -> Pp.t
val print_located_other : string -> reference -> 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;
diff --git a/printing/printer.ml b/printing/printer.ml
index edcce874d..77466605a 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -293,7 +293,7 @@ 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"*)"
+ str"(*" ++ Univ.Instance.pr UnivNames.pr_with_global_universes u ++ str"*)"
else mt ())
let pr_constant env cst = pr_global_env (Termops.vars_of_env env) (ConstRef cst)
diff --git a/printing/printer.mli b/printing/printer.mli
index 41843680b..4af90e6a6 100644
--- a/printing/printer.mli
+++ b/printing/printer.mli
@@ -9,7 +9,6 @@
(************************************************************************)
open Names
-open Globnames
open Constr
open Environ
open Pattern
@@ -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
diff --git a/printing/printmod.ml b/printing/printmod.ml
index e076c10f3..3c805b327 100644
--- a/printing/printmod.ml
+++ b/printing/printmod.ml
@@ -140,7 +140,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 +183,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 =
diff --git a/printing/printmod.mli b/printing/printmod.mli
index b0b0b0a35..48ba866cc 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/proofs/proof_global.ml b/proofs/proof_global.ml
index 842003bc8..97cfccb8d 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -342,7 +342,7 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now
normalise them for the kernel. *)
let subst_evar k =
Proof.in_proof proof (fun m -> Evd.existential_opt_value0 m k) in
- let nf = Universes.nf_evars_and_universes_opt_subst subst_evar
+ let nf = UnivSubst.nf_evars_and_universes_opt_subst subst_evar
(UState.subst universes) in
let make_body =
if poly || now then
diff --git a/proofs/refine.ml b/proofs/refine.ml
index 5a2d82977..b64e7a2e5 100644
--- a/proofs/refine.ml
+++ b/proofs/refine.ml
@@ -30,26 +30,19 @@ let typecheck_evar ev env sigma =
(** Typecheck the hypotheses. *)
let type_hyp (sigma, env) decl =
let t = 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 body t
+ 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, EConstr.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 (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 (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>") ()
@@ -93,7 +86,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 _ =
diff --git a/proofs/refiner.mli b/proofs/refiner.mli
index 5cd703a25..0f83e16ec 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 1889054f8..092bb5c27 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
diff --git a/proofs/tacmach.mli b/proofs/tacmach.mli
index 770d0940a..31496fb3d 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/stm/asyncTaskQueue.ml b/stm/asyncTaskQueue.ml
index b3e1500ae..768d94d30 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 36b5d18ab..841cc08c0 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 2983b619d..be5b29177 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/proofworkertop.mllib b/stm/proofworkertop.mllib
deleted file mode 100644
index f9f6c22d5..000000000
--- 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 c2f73089b..000000000
--- a/stm/queryworkertop.mllib
+++ /dev/null
@@ -1 +0,0 @@
-Queryworkertop
diff --git a/stm/stm.ml b/stm/stm.ml
index 9ea6a305e..6b92e4737 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -1849,7 +1849,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
@@ -2113,12 +2113,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
@@ -2200,8 +2194,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
@@ -2771,6 +2764,14 @@ let process_back_meta_command ~newtip ~head oid aast w =
VCS.commit id (Alias (oid,aast));
Backtrack.record (); if w == VtNow then ignore(finish ~doc:dummy_doc); `Ok
+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 ~doc ?(newtip=Stateid.fresh ())
({ verbose; loc; expr } as x) c =
stm_pperr_endline (fun () -> str "{{{ processing: " ++ pr_ast x);
@@ -2802,6 +2803,15 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
(* 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;
diff --git a/stm/stm.mllib b/stm/stm.mllib
index 72b538016..4b254e811 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 db38fde27..000000000
--- a/stm/tacworkertop.mllib
+++ /dev/null
@@ -1 +0,0 @@
-Tacworkertop
diff --git a/stm/vernac_classifier.ml b/stm/vernac_classifier.ml
index c08cc6e36..e01dcbcb6 100644
--- a/stm/vernac_classifier.ml
+++ b/stm/vernac_classifier.ml
@@ -54,13 +54,20 @@ let idents_of_name : Names.Name.t -> Names.Id.t list =
| 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
diff --git a/stm/vernac_classifier.mli b/stm/vernac_classifier.mli
index abbc04e89..45fbfb42a 100644
--- a/stm/vernac_classifier.mli
+++ b/stm/vernac_classifier.mli
@@ -25,3 +25,4 @@ 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 15a24fb37..77fe31415 100644
--- a/tactics/auto.ml
+++ b/tactics/auto.ml
@@ -79,7 +79,7 @@ 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 (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. *)
diff --git a/tactics/autorewrite.ml b/tactics/autorewrite.ml
index c3857e6b8..627ac31f5 100644
--- a/tactics/autorewrite.ml
+++ b/tactics/autorewrite.ml
@@ -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)
diff --git a/tactics/btermdn.ml b/tactics/btermdn.ml
index 8e50c977e..8f50b0aa2 100644
--- a/tactics/btermdn.ml
+++ b/tactics/btermdn.ml
@@ -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 b11e36bce..ea5d4719c 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -226,7 +226,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
@@ -547,9 +547,9 @@ let make_resolve_hyp env sigma st flags only_classes pri decl =
(List.map_append
(fun (path,info,c) ->
let info =
- { info with Vernacexpr.hint_pattern =
+ { info with hint_pattern =
Option.map (Constrintern.intern_constr_pattern env sigma)
- info.Vernacexpr.hint_pattern }
+ info.hint_pattern }
in
make_resolves env sigma ~name:(PathHints path)
(true,false,not !Flags.quiet) info false
diff --git a/tactics/eauto.ml b/tactics/eauto.ml
index dc310c542..3df9e3f82 100644
--- a/tactics/eauto.ml
+++ b/tactics/eauto.ml
@@ -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/eqschemes.ml b/tactics/eqschemes.ml
index 477de6452..715686ad0 100644
--- a/tactics/eqschemes.ml
+++ b/tactics/eqschemes.ml
@@ -102,7 +102,7 @@ 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.")
@@ -192,7 +192,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 +241,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 +353,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 +392,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 (Global.env ()) 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 +469,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 +495,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 (Global.env ()) 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 +561,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 +573,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 (Global.env ()) 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
@@ -755,7 +755,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 +778,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 b6bbd0be4..8904cd170 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -1176,34 +1176,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
- 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;
@@ -1213,8 +1214,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
@@ -1779,7 +1781,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)) ->
@@ -1830,7 +1832,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/hints.ml b/tactics/hints.ml
index 46d162911..39034a19b 100644
--- a/tactics/hints.ml
+++ b/tactics/hints.ml
@@ -28,12 +28,13 @@ open Termops
open Inductiveops
open Typing
open Decl_kinds
+open Vernacexpr
+open Typeclasses
open Pattern
open Patternops
open Clenv
open Tacred
open Printer
-open Vernacexpr
module NamedDecl = Context.Named.Declaration
@@ -94,7 +95,6 @@ let secvars_of_hyps hyps =
else pred
let empty_hint_info =
- let open Vernacexpr in
{ hint_priority = None; hint_pattern = None }
(************************************************************************)
@@ -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
@@ -126,10 +126,10 @@ type 'a hints_path_gen =
| PathEpsilon
type pre_hints_path = Libnames.reference hints_path_gen
-type hints_path = global_reference 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,7 +153,7 @@ 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 import_level = [ `LAX | `WARN | `STRICT ]
@@ -308,7 +308,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 +365,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)
@@ -474,28 +474,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 +510,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;
}
@@ -664,7 +664,7 @@ 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
{ db with hintdb_map = hintmap; hintdb_nopat = hintnopat }
@@ -876,7 +876,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
@@ -1015,9 +1015,9 @@ type hint_action =
| CreateDB of bool * transparent_state
| AddTransparency of evaluable_global_reference list * 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
@@ -1226,7 +1226,7 @@ type hints_entry =
| HintsCutEntry of hints_path
| HintsUnfoldEntry of evaluable_global_reference list
| HintsTransparencyEntry of evaluable_global_reference list * bool
- | HintsModeEntry of global_reference * hint_mode list
+ | HintsModeEntry of GlobRef.t * hint_mode list
| HintsExternEntry of hint_info * Genarg.glob_generic_argument
let default_prepare_hint_ident = Id.of_string "H"
diff --git a/tactics/hints.mli b/tactics/hints.mli
index 1811150c2..c7de10a2a 100644
--- a/tactics/hints.mli
+++ b/tactics/hints.mli
@@ -12,7 +12,6 @@ open Util
open Names
open EConstr
open Environ
-open Globnames
open Decl_kinds
open Evd
open Misctypes
@@ -25,13 +24,13 @@ open Vernacexpr
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 *)
@@ -51,7 +50,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 {
@@ -81,7 +80,7 @@ type 'a hints_path_gen =
| PathEpsilon
type pre_hints_path = Libnames.reference hints_path_gen
-type hints_path = global_reference 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 +90,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.reference 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.reference 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 +106,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 +143,10 @@ type hint_db = Hint_db.t
type hnf = bool
-type hint_info = (patvar list * constr_pattern) hint_info_gen
+type hint_info = (patvar list * constr_pattern) Typeclasses.hint_info_gen
type hint_term =
- | IsGlobRef of global_reference
+ | IsGlobRef of GlobRef.t
| IsConstr of constr * Univ.ContextSet.t
type hints_entry =
@@ -157,7 +156,7 @@ type hints_entry =
| HintsCutEntry of hints_path
| HintsUnfoldEntry of evaluable_global_reference list
| HintsTransparencyEntry of evaluable_global_reference list * bool
- | HintsModeEntry of global_reference * hint_mode list
+ | 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 +170,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
@@ -264,7 +263,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
diff --git a/tactics/hipattern.ml b/tactics/hipattern.ml
index b012a7ecd..b8f1ed720 100644
--- a/tactics/hipattern.ml
+++ b/tactics/hipattern.ml
@@ -294,13 +294,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 0697d0f19..f04cda123 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 62ead57f3..6d0da0dfa 100644
--- a/tactics/ind_tables.ml
+++ b/tactics/ind_tables.ml
@@ -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)
diff --git a/tactics/tacticals.mli b/tactics/tacticals.mli
index bc2f60186..cbaf691f1 100644
--- a/tactics/tacticals.mli
+++ b/tactics/tacticals.mli
@@ -135,7 +135,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 *)
@@ -268,5 +268,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 3a20c3fc4..01351e249 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -247,13 +247,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
+ 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)
@@ -431,9 +430,8 @@ 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)
+ 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
@@ -447,7 +445,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
@@ -979,6 +977,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 *)
@@ -1982,24 +1985,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))
@@ -3448,7 +3449,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,...) *)
@@ -3810,7 +3811,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
@@ -3835,7 +3839,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
@@ -4362,7 +4367,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 *)
diff --git a/tactics/tactics.mli b/tactics/tactics.mli
index 7809dbf48..46f782eaa 100644
--- a/tactics/tactics.mli
+++ b/tactics/tactics.mli
@@ -16,7 +16,6 @@ open Proof_type
open Evd
open Clenv
open Redexpr
-open Globnames
open Pattern
open Unification
open Misctypes
@@ -177,7 +176,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. } *)
@@ -253,7 +252,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,...) *)
diff --git a/tactics/term_dnet.ml b/tactics/term_dnet.ml
index 753c608ad..611799990 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 *)
diff --git a/test-suite/Makefile b/test-suite/Makefile
index 9d84cd5c7..ce21ff41c 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
#######################################################################
@@ -94,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 unit-tests
PREREQUISITELOG = prerequisite/admit.v.log \
prerequisite/make_local.v.log prerequisite/make_notation.v.log \
@@ -118,13 +123,16 @@ bugs: $(BUGS)
clean:
rm -f trace .lia.cache output/MExtraction.out
- $(SHOW) "RM <**/*.vo> <**/*.vio> <**/*.log> <**/*.glob>"
+ $(SHOW) 'RM <**/*.stamp> <**/*.vo> <**/*.vio> <**/*.log> <**/*.glob>'
$(HIDE)find . \( \
- -name '*.vo' -o -name '*.vio' -o -name '*.log' -o -name '*.glob' \
- \) -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
- $(SHOW) "RM <**/*.aux>"
+ $(SHOW) 'RM <**/*.aux>'
$(HIDE)find . -name '*.aux' -print0 | xargs -0 rm -f
#######################################################################
@@ -158,18 +166,20 @@ 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, "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:
@@ -243,6 +253,44 @@ $(addsuffix .log,$(wildcard bugs/closed/*.v)): %.v.log: %.v
} > "$@"
#######################################################################
+# 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
#######################################################################
@@ -261,7 +309,8 @@ $(addsuffix .log,$(wildcard prerequisite/*.v)): %.v.log: %.v
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)"; \
diff --git a/test-suite/README.md b/test-suite/README.md
index 1d1195646..4572c98cf 100644
--- a/test-suite/README.md
+++ b/test-suite/README.md
@@ -73,3 +73,6 @@ 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.
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 unit tests of OCaml code in `test-suite/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 directory to run them.
diff --git a/test-suite/bugs/closed/2969.v b/test-suite/bugs/closed/2969.v
index a03adbd73..7b1a26178 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/3377.v b/test-suite/bugs/closed/3377.v
index 8e9e3933c..abfcf1d35 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/4069.v b/test-suite/bugs/closed/4069.v
index 606c6e084..668f6bb42 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/4198.v b/test-suite/bugs/closed/4198.v
index eb37141bc..28800ac05 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/4722.v b/test-suite/bugs/closed/4722.v
deleted file mode 100644
index 2d41828f1..000000000
--- a/test-suite/bugs/closed/4722.v
+++ /dev/null
@@ -1 +0,0 @@
-(* -*- coq-prog-args: ("-R" "4722" "Foo") -*- *)
diff --git a/test-suite/bugs/closed/4722/tata b/test-suite/bugs/closed/4722/tata
deleted file mode 120000
index b38e66e75..000000000
--- a/test-suite/bugs/closed/4722/tata
+++ /dev/null
@@ -1 +0,0 @@
-toto \ No newline at end of file
diff --git a/test-suite/bugs/closed/4782.v b/test-suite/bugs/closed/4782.v
index dbd71035d..1e1a4cb9c 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/7462.v b/test-suite/bugs/closed/7462.v
new file mode 100644
index 000000000..40ca39e38
--- /dev/null
+++ b/test-suite/bugs/closed/7462.v
@@ -0,0 +1,13 @@
+(* Adding an only-printing notation should not override existing
+ interpretations for the same notation. *)
+
+Notation "$ x" := (@id nat x) (only parsing, at level 0).
+Notation "$ x" := (@id bool x) (only printing, at level 0).
+Check $1. (* Was: Error: Unknown interpretation for notation "$ _". *)
+
+(* Adding an only-printing notation should not let believe
+ that a parsing rule has been given *)
+
+Notation "$ x" := (@id bool x) (only printing, at level 0).
+Notation "$ x" := (@id nat x) (only parsing, at level 0).
+Check $1. (* Was: Error: Syntax Error: Lexer: Undefined token *)
diff --git a/test-suite/bugs/closed/7554.v b/test-suite/bugs/closed/7554.v
new file mode 100644
index 000000000..12b0aa2cb
--- /dev/null
+++ b/test-suite/bugs/closed/7554.v
@@ -0,0 +1,12 @@
+Require Import Coq.Program.Tactics.
+
+(* these should not result in anomalies *)
+
+Fail Program Lemma foo:
+ forall P, forall H, forall (n:nat), P n.
+
+Fail Program Lemma foo:
+ forall a (P : list a -> Prop), forall H, forall (n:list a), P n.
+
+Fail Program Lemma foo:
+ forall (a : Type) (P : list a -> Prop), forall H, forall (n:list a), P n.
diff --git a/test-suite/check b/test-suite/check
deleted file mode 100755
index 3d14f6bc0..000000000
--- 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/coq-makefile/timing/run.sh b/test-suite/coq-makefile/timing/run.sh
index 11a04d5c2..6737197ee 100755
--- a/test-suite/coq-makefile/timing/run.sh
+++ b/test-suite/coq-makefile/timing/run.sh
@@ -44,6 +44,7 @@ TO_SED_IN_BOTH=(
-e s'/ *$//g' # the number of trailing spaces depends on how many digits percentages end up being; since this varies across runs, we remove trailing spaces
-e s'/[0-9]*\.[0-9]*//g' # the precise timing numbers vary, so we strip them out
-e s'/^-*$/------/g' # When none of the numbers get over 100 (or 1000, in per-file), the width of the table is different, so we normalize the number of dashes for table separators
+ -e s'/+/-/g' # some code lines don't really change, but this can show up as either -0m00.01s or +0m00.01s, so we need to normalize the signs; additionally, some N/A's show up where we expect to get -∞ on the per-line file, and so the ∞-replacement gets the sign wrong, so we must correct it
)
TO_SED_IN_PER_FILE=(
@@ -55,7 +56,6 @@ TO_SED_IN_PER_FILE=(
TO_SED_IN_PER_LINE=(
-e s'/0//g' # unclear whether this is actually needed above and beyond s'/[0-9]*\.[0-9]*//g'; it's been here from the start
-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
- -e s'/+/-/g' # some code lines don't really change, but this can show up as either -0m00.01s or +0m00.01s, so we need to normalize the signs
)
for file in time-of-build-before.log time-of-build-after.log time-of-build-both.log; do
diff --git a/test-suite/ide/undo012.fake b/test-suite/ide/undo012.fake
index b3d1c6d53..c95df1b11 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 921a9d0f0..a3ccefd2c 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 f5fe77470..13e718229 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 a1e5c947b..9cbd64460 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 f9414c1ea..15bd3cc92 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/misc/.gitignore b/test-suite/misc/.gitignore
new file mode 100644
index 000000000..a4083e931
--- /dev/null
+++ b/test-suite/misc/.gitignore
@@ -0,0 +1,2 @@
+4722/
+4722.v
diff --git a/test-suite/misc/4722.sh b/test-suite/misc/4722.sh
new file mode 100755
index 000000000..86bc50b5c
--- /dev/null
+++ b/test-suite/misc/4722.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+set -e
+
+# create test files
+mkdir -p misc/4722
+ln -sf toto misc/4722/tata
+touch misc/4722.v
+
+# run test
+$coqtop "-R" "misc/4722" "Foo" -top Top -load-vernac-source misc/4722.v
+
+# clean up test files
+rm misc/4722/tata
+rmdir misc/4722
+rm misc/4722.v
diff --git a/test-suite/misc/coqc_dash_o.sh b/test-suite/misc/coqc_dash_o.sh
new file mode 100755
index 000000000..0ae7873fd
--- /dev/null
+++ b/test-suite/misc/coqc_dash_o.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+DOUT=misc/tmp_coqc_dash_o/
+OUT=${DOUT}coqc_dash_o.vo
+
+
+mkdir -p "${DOUT}"
+rm -f "${OUT}"
+$coqc misc/coqc_dash_o.v -o "${OUT}"
+if [ ! -f "${OUT}" ]; then
+ printf "coqc -o not working"
+ exit 1
+fi
+rm -fr "${DOUT}"
+exit 0
diff --git a/test-suite/misc/coqc_dash_o.v b/test-suite/misc/coqc_dash_o.v
new file mode 100644
index 000000000..7426dff1a
--- /dev/null
+++ b/test-suite/misc/coqc_dash_o.v
@@ -0,0 +1 @@
+Definition x := nat.
diff --git a/test-suite/output/Cases.v b/test-suite/output/Cases.v
index caf3b2870..4740c009a 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 *)
diff --git a/test-suite/output/Notations3.out b/test-suite/output/Notations3.out
index 304353f55..996af5927 100644
--- a/test-suite/output/Notations3.out
+++ b/test-suite/output/Notations3.out
@@ -231,3 +231,13 @@ fun l : list nat => match l with
: list nat -> list nat
Argument scope is [list_scope]
+Notation
+"'exists' x .. y , p" := ex (fun x => .. (ex (fun y => p)) ..) : type_scope
+(default interpretation)
+"'exists' ! x .. y , p" := ex
+ (unique
+ (fun x => .. (ex (unique (fun y => p))) ..))
+: type_scope (default interpretation)
+Notation
+"( x , y , .. , z )" := pair .. (pair x y) .. z : core_scope
+(default interpretation)
diff --git a/test-suite/output/Notations3.v b/test-suite/output/Notations3.v
index d2d136946..3cf0c913f 100644
--- a/test-suite/output/Notations3.v
+++ b/test-suite/output/Notations3.v
@@ -380,3 +380,8 @@ Definition foo (l : list nat) :=
end.
Print foo.
End Issue7110.
+
+Module LocateNotations.
+Locate "exists".
+Locate "( _ , _ , .. , _ )".
+End LocateNotations.
diff --git a/test-suite/output/UnclosedBlocks.out b/test-suite/output/UnclosedBlocks.out
index b83e94ad4..31481e84a 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/ltac.v b/test-suite/output/ltac.v
index 6adbe95dd..901b1e3aa 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/ssr_explain_match.out b/test-suite/output/ssr_explain_match.out
new file mode 100644
index 000000000..fa2393b91
--- /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 000000000..56ca24b6e
--- /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/ssr_mini_mathcomp.v b/test-suite/prerequisite/ssr_mini_mathcomp.v
new file mode 100644
index 000000000..cb2c56736
--- /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/test-suite/prerequisite/ssr_ssrsyntax1.v b/test-suite/prerequisite/ssr_ssrsyntax1.v
new file mode 100644
index 000000000..2b404e2de
--- /dev/null
+++ b/test-suite/prerequisite/ssr_ssrsyntax1.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-2016 Microsoft Corporation and Inria. *)
+
+Require ssreflect.
+Require Import Arith.
+
+Goal (forall a b, a + b = b + a).
+intros.
+rewrite plus_comm, plus_comm.
+split.
+Abort.
+
+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/save-logs.sh b/test-suite/save-logs.sh
index b61362108..9b8fff09f 100755
--- a/test-suite/save-logs.sh
+++ b/test-suite/save-logs.sh
@@ -9,7 +9,7 @@ mkdir "$SAVEDIR"
# keep this synced with test-suite/Makefile
FAILMARK="==========> FAILURE <=========="
-FAILED=$(mktemp /tmp/coq-check-XXXXX)
+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"
diff --git a/test-suite/ssr/absevarprop.v b/test-suite/ssr/absevarprop.v
new file mode 100644
index 000000000..fa1de0095
--- /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 000000000..7c57d2024
--- /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 000000000..97b7d830f
--- /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 000000000..69b52eace
--- /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 000000000..94b064b02
--- /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 000000000..7e60b04a6
--- /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 000000000..85353dadf
--- /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/ssr/dependent_type_err.v b/test-suite/ssr/dependent_type_err.v
new file mode 100644
index 000000000..a5789d8dd
--- /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 000000000..abf63a20c
--- /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 000000000..908249a36
--- /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 000000000..c7c20d8f8
--- /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 000000000..ef4658287
--- /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 000000000..4971add91
--- /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 000000000..249e006f9
--- /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 000000000..c0592e884
--- /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 000000000..b3a26ed2c
--- /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 000000000..1c998da71
--- /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 000000000..3d6c9d980
--- /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 000000000..aa1f71879
--- /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/test-suite/ssr/if_isnt.v b/test-suite/ssr/if_isnt.v
new file mode 100644
index 000000000..b8f6b7739
--- /dev/null
+++ b/test-suite/ssr/if_isnt.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.
+
+
+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 000000000..8a164bd80
--- /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 000000000..fdc85173a
--- /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/ipatalternation.v b/test-suite/ssr/ipatalternation.v
new file mode 100644
index 000000000..6aa9a954c
--- /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 000000000..380e52af4
--- /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 000000000..bcdf96dde
--- /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/test-suite/ssr/move_after.v b/test-suite/ssr/move_after.v
new file mode 100644
index 000000000..a7a9afea0
--- /dev/null
+++ b/test-suite/ssr/move_after.v
@@ -0,0 +1,19 @@
+(************************************************************************)
+(* * 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.
+
+
+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 000000000..f4e717b38
--- /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/test-suite/ssr/occarrow.v b/test-suite/ssr/occarrow.v
new file mode 100644
index 000000000..49af7ae08
--- /dev/null
+++ b/test-suite/ssr/occarrow.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 : 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.
+
+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 000000000..d69f03ac3
--- /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 000000000..396f4f032
--- /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 000000000..cf61eb436
--- /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 000000000..f7993f402
--- /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/set_lamda.v b/test-suite/ssr/set_lamda.v
new file mode 100644
index 000000000..a012ec680
--- /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 000000000..3ce75e879
--- /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/ssrsyntax2.v b/test-suite/ssr/ssrsyntax2.v
new file mode 100644
index 000000000..af839fabd
--- /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 000000000..ae4589ef3
--- /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 000000000..ca121fdb3
--- /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/ide/ide_slave.mli b/test-suite/ssr/unfold_Opaque.v
index 9db9ecd12..7c2b51de4 100644
--- a/ide/ide_slave.mli
+++ b/test-suite/ssr/unfold_Opaque.v
@@ -8,5 +8,11 @@
(* * (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 *)
+Require Import ssreflect.
+
+Definition x := 3.
+Opaque x.
+
+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 000000000..710941c30
--- /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 000000000..2721470c4
--- /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 000000000..43a8f3b8b
--- /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 000000000..64e1ea84f
--- /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 000000000..dd80f0435
--- /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/success/Inversion.v b/test-suite/success/Inversion.v
index ca8da3948..ee540d710 100644
--- a/test-suite/success/Inversion.v
+++ b/test-suite/success/Inversion.v
@@ -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/RecTutorial.v b/test-suite/success/RecTutorial.v
index 29350d620..6370cab6b 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
diff --git a/test-suite/success/destruct.v b/test-suite/success/destruct.v
index 6fbe61a9b..d1d384659 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/intros.v b/test-suite/success/intros.v
index a329894aa..d37ad9f52 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/refine.v b/test-suite/success/refine.v
index 22fb4d757..40986e57c 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/sideff.v b/test-suite/success/sideff.v
index 3c0b81568..b9a1273b1 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/unit-tests/.merlin b/test-suite/unit-tests/.merlin
new file mode 100644
index 000000000..b2279de74
--- /dev/null
+++ b/test-suite/unit-tests/.merlin
@@ -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 000000000..c07ec293f
--- /dev/null
+++ b/test-suite/unit-tests/clib/inteq.ml
@@ -0,0 +1,13 @@
+open Utest
+
+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__ 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 000000000..9ae405977
--- /dev/null
+++ b/test-suite/unit-tests/clib/unicode_tests.ml
@@ -0,0 +1,15 @@
+open Utest
+
+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__ tests
diff --git a/test-suite/unit-tests/src/utest.ml b/test-suite/unit-tests/src/utest.ml
new file mode 100644
index 000000000..069e6a4bf
--- /dev/null
+++ b/test-suite/unit-tests/src/utest.ml
@@ -0,0 +1,74 @@
+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
+
+(* run list of OUnit test cases, log results *)
+let run_tests ml_fn tests =
+ let log_fn = ml_fn ^ ".log" in
+ let out_ch = open_out log_fn in
+ 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 000000000..70928228b
--- /dev/null
+++ b/test-suite/unit-tests/src/utest.mli
@@ -0,0 +1,12 @@
+(** 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 -> OUnit.test list -> unit
diff --git a/tools/coqdep.ml b/tools/coqdep.ml
index 12b5cab0a..7db0b2890 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 70c983175..23b8bc112 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
@@ -102,10 +103,19 @@ let safe_hash_add cmp clq q (k, (v, b)) =
For the ML files, the string is the basename without extension.
*)
+let same_path_opt s s' =
+ let nf s = (* ./foo/a.ml and foo/a.ml are the same file *)
+ if Filename.is_implicit s
+ then "." // s
+ else s
+ in
+ let s = match s with None -> "." | Some s -> nf s in
+ let s' = match s' with None -> "." | Some s' -> nf s' in
+ s = s'
+
let warning_ml_clash x s suff s' suff' =
- if suff = suff' then
- eprintf
- "*** Warning: %s%s already found in %s (discarding %s%s)\n" x suff
+ if suff = suff' && not (same_path_opt s s') then
+ 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
@@ -170,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
@@ -193,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;
@@ -441,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) ->
@@ -458,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) ->
@@ -473,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 () =
@@ -486,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 d0d793243..91d2b4587 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/fake_ide.ml b/tools/fake_ide.ml
index d48c6d0af..016201128 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/ocamllibdep.mll b/tools/ocamllibdep.mll
index 125c1452d..382c39d3f 100644
--- a/tools/ocamllibdep.mll
+++ b/tools/ocamllibdep.mll
@@ -116,8 +116,18 @@ let error_cannot_parse s (i,j) =
Printf.eprintf "File \"%s\", characters %i-%i: Syntax error\n" s i j;
exit 1
+let same_path_opt s s' =
+ let nf s = (* ./foo/a.ml and foo/a.ml are the same file *)
+ if Filename.is_implicit s
+ then "." // s
+ else s
+ in
+ let s = match s with None -> "." | Some s -> nf s in
+ let s' = match s' with None -> "." | Some s' -> nf s' in
+ s = s'
+
let warning_ml_clash x s suff s' suff' =
- if suff = suff' then
+ if suff = suff' && not (same_path_opt s s') then
eprintf
"*** Warning: %s%s already found in %s (discarding %s%s)\n" x suff
(match s with None -> "." | Some d -> d)
diff --git a/stm/proofworkertop.ml b/topbin/coqproofworker_bin.ml
index 4b85a05ac..7ae91cfbd 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 aa00102aa..98c858121 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 3b91df86e..2634baa83 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 ea4c0ea52..4490db59e 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 0b65cebbb..abe397830 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 a1a07fce8..89602c9b5 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;
@@ -81,6 +80,8 @@ type coq_cmdopts = {
print_config: bool;
output_context : bool;
+ print_emacs : bool;
+
inputstate : string option;
outputstate : string option;
@@ -100,7 +101,6 @@ let init_args = {
compilation_mode = BuildVo;
toplevel_name = Names.(DirPath.make [Id.of_string "Top"]);
- toploop = None;
compile_list = [];
compilation_output_name = None;
@@ -129,6 +129,8 @@ let init_args = {
print_config = false;
output_context = false;
+ print_emacs = false;
+
inputstate = None;
outputstate = None;
}
@@ -191,11 +193,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 +309,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 +397,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" ->
@@ -500,11 +496,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
@@ -538,12 +529,6 @@ let parse_args arglist : coq_cmdopts * string list =
|"-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 de9b6a682..9fb6219a6 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;
@@ -56,6 +55,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 3e7a83085..e61f830f3 100644
--- a/toplevel/coqinit.ml
+++ b/toplevel/coqinit.ml
@@ -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 =
diff --git a/toplevel/coqloop.ml b/toplevel/coqloop.ml
index 63b8b538a..d7ede1c2e 100644
--- a/toplevel/coqloop.ml
+++ b/toplevel/coqloop.ml
@@ -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
@@ -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,9 +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
+ 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,7 +352,7 @@ let top_goal_print oldp newp =
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
(* Careful to keep this loop tail-rec *)
let rec vernac_loop ~state =
@@ -395,7 +394,7 @@ let rec vernac_loop ~state =
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;
+ TopErr.print_error_for_buffer ?loc Topfmt.InteractiveLoop Feedback.Error msg top_buffer;
vernac_loop ~state
let rec loop ~state =
@@ -411,3 +410,25 @@ let rec loop ~state =
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 39a9de4f8..5c07a8bf3 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. *)
@@ -30,10 +27,11 @@ val top_buffer : input_buffer
val set_prompt : (unit -> string) -> unit
(** Toplevel feedback printer. *)
-val coqloop_feed : Feedback.feedback -> unit
-
-(** Main entry point of Coq: read and execute vernac commands. *)
-val loop : 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 e60382f2c..e979d0e54 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 ~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 coqtop_doc_feed = Coqloop.coqloop_feed Topfmt.LoadingPrelude
-let toploop_run = ref console_toploop_run
+let coqtop_rcfile_feed = Coqloop.coqloop_feed Topfmt.LoadingRcFile
let memory_stat = ref false
let print_memory_stat () =
@@ -101,9 +86,16 @@ let load_vernacular opts ~state =
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 ~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; time = opts.time } in
- let state = load_init_vernaculars opts ~state 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)
@@ -265,13 +262,18 @@ 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; time = opts.time } in
- let state = load_init_vernaculars opts ~state 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 ~echo ~check:false ~interactive:false ~state long_f_dot_v in
let doc = Stm.finish ~doc:state.doc in
@@ -288,21 +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:None) f_in
+ (fun f_in -> compile cur_feeder opts ~echo ~f_in ~f_out) f_in
else
- compile opts ~echo ~f_in ~f_out:None
+ 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 *)
@@ -365,12 +368,6 @@ let init_color color_mode =
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
- opts, x
- end
-
let print_style_tags opts =
let () = init_color opts.color in
let tags = Topfmt.dump_tags () in
@@ -413,14 +410,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:
@@ -453,8 +450,7 @@ let init_toplevel arglist =
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 opts, 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";
@@ -489,41 +485,52 @@ 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; time = opts.time } 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.color;
+ CoqworkmgrApi.(init !async_proofs_worker_priority);
+ 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 fcc569ca0..641448f10 100644
--- a/toplevel/coqtop.mli
+++ b/toplevel/coqtop.mli
@@ -8,16 +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 -> Coqargs.coq_cmdopts * 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/toplevel.mllib b/toplevel/toplevel.mllib
index 78b96e5e2..597173e5f 100644
--- a/toplevel/toplevel.mllib
+++ b/toplevel/toplevel.mllib
@@ -1,7 +1,8 @@
Vernac
Usage
-G_toplevel
-Coqloop
Coqinit
Coqargs
+G_toplevel
+Coqloop
Coqtop
+WorkerLoop
diff --git a/stm/workerLoop.ml b/toplevel/workerLoop.ml
index 5130b019a..ee6d5e884 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;
- coq_args, 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/toplevel/workerLoop.mli b/toplevel/workerLoop.mli
new file mode 100644
index 000000000..e497dee6d
--- /dev/null
+++ b/toplevel/workerLoop.mli
@@ -0,0 +1,14 @@
+(************************************************************************)
+(* * 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) *)
+(************************************************************************)
+
+(* Register a STM worker *)
+val start :
+ init:(unit -> unit) ->
+ loop:(unit -> unit) -> unit
diff --git a/vernac/assumptions.mli b/vernac/assumptions.mli
index 7e13f8f28..0e2b0c80e 100644
--- a/vernac/assumptions.mli
+++ b/vernac/assumptions.mli
@@ -30,4 +30,4 @@ val traverse :
{!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 1a6b4dcdb..2a41a50dd 100644
--- a/vernac/auto_ind_decl.ml
+++ b/vernac/auto_ind_decl.ml
@@ -54,20 +54,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 +76,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
@@ -635,7 +635,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
@@ -863,7 +863,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|])|])
)
)
)
diff --git a/vernac/auto_ind_decl.mli b/vernac/auto_ind_decl.mli
index 5cc783df7..11f26c7c3 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 f0b01061b..06e1694f9 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
diff --git a/vernac/class.mli b/vernac/class.mli
index 33d31fe1f..f7e837f3b 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 2e1bd6970..61ce5d6c4 100644
--- a/vernac/classes.ml
+++ b/vernac/classes.ml
@@ -51,7 +51,6 @@ let _ =
| 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())))
@@ -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
+ 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 0342c840e..27d3a4669 100644
--- a/vernac/classes.mli
+++ b/vernac/classes.mli
@@ -22,15 +22,15 @@ val mismatched_props : env -> constr_expr list -> Context.Rel.t -> 'a
(** Instance declaration *)
-val existing_instance : bool -> reference -> Vernacexpr.hint_info_expr option -> unit
+val existing_instance : bool -> reference -> hint_info_expr option -> unit
(** globality, reference, optional priority and pattern information *)
val declare_instance_constant :
typeclass ->
- Vernacexpr.hint_info_expr -> (** priority *)
+ 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 ->
bool -> (* polymorphic *)
@@ -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) ->
+ hint_info_expr ->
Id.t
(** Setting opacity *)
diff --git a/vernac/comAssumption.ml b/vernac/comAssumption.ml
index 26a46a752..722f21171 100644
--- a/vernac/comAssumption.ml
+++ b/vernac/comAssumption.ml
@@ -174,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 a2d20a1d1..56932360a 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
@@ -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 ->
+ UnivNames.universe_binders -> Impargs.manual_implicits ->
bool (** implicit *) -> Declaremods.inline -> variable CAst.t ->
- global_reference * Univ.Instance.t * bool
+ GlobRef.t * Univ.Instance.t * bool
diff --git a/vernac/comDefinition.ml b/vernac/comDefinition.ml
index 9aa61ab46..863adb0d1 100644
--- a/vernac/comDefinition.ml
+++ b/vernac/comDefinition.ml
@@ -90,7 +90,7 @@ let interp_definition pl bl poly red_option c ctypopt =
Note: in program mode some evars may remain. *)
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 evd ty) ctx) tyopt 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))
@@ -118,7 +118,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/comFixpoint.ml b/vernac/comFixpoint.ml
index 7b382dacc..85c0699ea 100644
--- a/vernac/comFixpoint.ml
+++ b/vernac/comFixpoint.ml
@@ -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'
diff --git a/vernac/comInductive.ml b/vernac/comInductive.ml
index 101298ef4..629fcce5a 100644
--- a/vernac/comInductive.ml
+++ b/vernac/comInductive.ml
@@ -29,7 +29,6 @@ open Indtypes
open Pretyping
open Evarutil
open Indschemes
-open Misctypes
open Context.Rel.Declaration
open Entries
@@ -178,6 +177,72 @@ 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)) ->
@@ -206,8 +271,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 ->
@@ -380,7 +445,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
diff --git a/vernac/comInductive.mli b/vernac/comInductive.mli
index 833935724..7ae8e8f71 100644
--- a/vernac/comInductive.mli
+++ b/vernac/comInductive.mli
@@ -37,7 +37,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 +64,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 745f1df1d..f41e0fc44 100644
--- a/vernac/comProgramFixpoint.ml
+++ b/vernac/comProgramFixpoint.ml
@@ -190,9 +190,7 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
~src:(Loc.tag @@ Evar_kinds.QuestionMark (Evar_kinds.Define false,Anonymous)) wf_proof in
sigma, mkApp (h_a_term, [| argtyp ; wf_rel ; h_e_term; prop |])
in
- let _evd = ref sigma in
- let def = Typing.e_solve_evars env _evd def in
- let sigma = !_evd in
+ let sigma, 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 +212,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
diff --git a/vernac/declareDef.mli b/vernac/declareDef.mli
index 010874e23..c5e704a5e 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/vernac/explainErr.ml b/vernac/explainErr.ml
index f9167f969..f68dcae26 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 ".")
diff --git a/vernac/himsg.ml b/vernac/himsg.ml
index acb461cac..3c4fcf714 100644
--- a/vernac/himsg.ml
+++ b/vernac/himsg.ml
@@ -197,7 +197,7 @@ let rec pr_disjunction pr = function
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"*)"
+ str"(*" ++ Univ.Instance.pr UnivNames.pr_with_global_universes u ++ str"*)"
else mt())
let explain_elim_arity env sigma ind sorts c pj okinds =
@@ -314,7 +314,7 @@ 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) ->
@@ -886,7 +886,7 @@ 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 () ++
diff --git a/vernac/indschemes.ml b/vernac/indschemes.ml
index 32885ab88..2deca1e06 100644
--- a/vernac/indschemes.ml
+++ b/vernac/indschemes.ml
@@ -380,7 +380,7 @@ let do_mutual_induction_scheme 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/lemmas.ml b/vernac/lemmas.ml
index aba5e32db..3d627d2f6 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
diff --git a/vernac/lemmas.mli b/vernac/lemmas.mli
index ad4c278e0..398f7d6d0 100644
--- a/vernac/lemmas.mli
+++ b/vernac/lemmas.mli
@@ -13,10 +13,10 @@ 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
diff --git a/vernac/metasyntax.ml b/vernac/metasyntax.ml
index feeca6075..76958b05f 100644
--- a/vernac/metasyntax.ml
+++ b/vernac/metasyntax.ml
@@ -738,12 +738,12 @@ 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 ntn in
+ let oldprec = Notation.level_of_notation ~onlyprint ntn in
if not (Notation.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;
+ Notation.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 *)
@@ -1274,7 +1274,7 @@ exception NoSyntaxRule
let recover_notation_syntax ntn =
try
- let prec = Notation.level_of_notation ntn in
+ 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
diff --git a/vernac/mltop.ml b/vernac/mltop.ml
index 343b0925d..d25dea141 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 da195f4fc..ed1f9a12d 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 3f2792518..1e7721f8f 100644
--- a/vernac/obligations.ml
+++ b/vernac/obligations.ml
@@ -259,7 +259,7 @@ 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
@@ -472,7 +472,7 @@ 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
@@ -555,13 +555,13 @@ 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;
Declare.recursive_message (fixkind != IsCoFixpoint) indexes fixnames;
let gr = List.hd kns in
- let kn = match gr with ConstRef kn -> kn | _ -> assert false in
+ let kn = match gr with GlobRef.ConstRef kn -> kn | _ -> assert false in
Lemmas.call_hook fix_exn first.prg_hook local gr first.prg_ctx;
List.iter progmap_remove l; kn
@@ -744,7 +744,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
@@ -770,7 +770,7 @@ let update_obls prg obls rem =
let progs = List.map (fun x -> get_info (ProgMap.find x !from_prg)) prg'.prg_deps in
if List.for_all (fun x -> obligations_solved x) progs then
let kn = declare_mutual_definition progs in
- Defined (ConstRef kn)
+ Defined (GlobRef.ConstRef kn)
else Dependent)
let is_defined obls x = not (Option.is_empty obls.(x).obl_body)
@@ -891,7 +891,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)
diff --git a/vernac/obligations.mli b/vernac/obligations.mli
index cc2cacd86..4b6165fb1 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,7 +48,7 @@ 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
diff --git a/vernac/record.ml b/vernac/record.ml
index b89c0060d..bf6affd5f 100644
--- a/vernac/record.ml
+++ b/vernac/record.ml
@@ -122,7 +122,7 @@ let typecheck_params_and_fields finite def id poly pl t ps nots fs =
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
@@ -316,7 +316,7 @@ let declare_projections indsp ctx ?(kind=StructureComponent) binder_name coers u
let gr = Nametab.locate (Libnames.qualid_of_ident fid) in
let kn = destConstRef gr in
Declare.definition_message fid;
- Universes.register_universe_binders gr ubinders;
+ UnivNames.register_universe_binders gr ubinders;
kn, mkProj (Projection.make kn false,mkRel 1)
else
let ccl = subst_projection fid subst ti in
@@ -352,7 +352,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)))
@@ -465,9 +465,9 @@ 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)
diff --git a/vernac/record.mli b/vernac/record.mli
index 992da2aa5..b2c039f0b 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,7 +20,7 @@ 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 ->
(Name.t * bool) list * Constant.t option list
@@ -30,6 +29,6 @@ val definition_structure :
inductive_kind * Decl_kinds.cumulative_inductive_flag * Decl_kinds.polymorphic *
Declarations.recursivity_kind * ident_decl with_coercion * 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 -> GlobRef.t
-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 a2a4fb40f..6d07187fe 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)
diff --git a/vernac/search.mli b/vernac/search.mli
index a1fb7ed3e..0dc82c1c3 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 055f6676e..609dac69a 100644
--- a/vernac/topfmt.ml
+++ b/vernac/topfmt.ml
@@ -89,12 +89,14 @@ let set_margin v =
Format.pp_set_margin Format.str_formatter v;
Format.pp_set_margin !std_ft v;
Format.pp_set_margin !deep_ft v;
+ Format.pp_set_margin !err_ft v;
(* Heuristic, based on usage: the column on the right of max_indent
column is 20% of width, capped to 30 characters *)
let m = max (64 * v / 100) (v-30) in
Format.pp_set_max_indent Format.str_formatter m;
Format.pp_set_max_indent !std_ft m;
- Format.pp_set_max_indent !deep_ft m
+ Format.pp_set_max_indent !deep_ft m;
+ Format.pp_set_max_indent !err_ft m
(** Console display of feedback *)
@@ -289,6 +291,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
@@ -301,13 +311,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 579b456a2..73dcb0064 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/vernacentries.ml b/vernac/vernacentries.ml
index f0e41d27c..eae8167c4 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -1741,7 +1741,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)
@@ -2243,7 +2243,7 @@ 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