aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml132
-rw-r--r--.github/CODEOWNERS39
-rw-r--r--.gitignore19
-rw-r--r--.gitlab-ci.yml292
-rw-r--r--.merlin2
-rw-r--r--.travis.yml43
-rw-r--r--CHANGES40
-rw-r--r--CONTRIBUTING.md8
-rw-r--r--CREDITS3
-rw-r--r--INSTALL.doc58
-rw-r--r--META.coq13
-rw-r--r--Makefile5
-rw-r--r--Makefile.checker24
-rw-r--r--Makefile.ci13
-rw-r--r--Makefile.common4
-rw-r--r--Makefile.doc246
-rw-r--r--README.md1
-rw-r--r--appveyor.yml12
-rw-r--r--checker/cic.mli2
-rw-r--r--checker/closure.ml4
-rw-r--r--checker/closure.mli4
-rw-r--r--checker/environ.mli2
-rw-r--r--checker/reduction.ml4
-rw-r--r--checker/subtyping.ml2
-rw-r--r--checker/term.ml2
-rw-r--r--checker/values.ml2
-rw-r--r--clib/cArray.ml3
-rw-r--r--clib/cArray.mli6
-rw-r--r--clib/cList.ml2
-rw-r--r--clib/cList.mli5
-rw-r--r--clib/option.mli1
-rw-r--r--configure.ml57
-rw-r--r--default.nix8
-rw-r--r--dev/base_include1
-rw-r--r--dev/build/windows/makecoq_mingw.sh29
-rw-r--r--dev/build/windows/patches_coq/lablgtk-2.18.3.patch44
-rw-r--r--dev/ci/README.md77
-rwxr-xr-x[-rw-r--r--]dev/ci/ci-basic-overlay.sh26
-rwxr-xr-xdev/ci/ci-compcert.sh1
-rwxr-xr-xdev/ci/ci-cross-crypto.sh11
-rwxr-xr-xdev/ci/ci-fcsl-pcm.sh12
-rwxr-xr-xdev/ci/ci-fiat-crypto.sh2
-rwxr-xr-xdev/ci/ci-iris-lambda-rust.sh15
-rwxr-xr-xdev/ci/ci-mtac2.sh (renamed from dev/ci/ci-metacoq.sh)6
-rwxr-xr-xdev/ci/ci-pidetop.sh13
-rwxr-xr-xdev/ci/ci-vst.sh6
-rw-r--r--dev/ci/docker/README.md65
-rw-r--r--dev/ci/docker/bionic_coq/Dockerfile46
-rwxr-xr-xdev/ci/docker/bionic_coq/hooks/post_push8
-rw-r--r--dev/ci/gitlab.bat50
-rw-r--r--dev/ci/user-overlays/06454-ejgallego-evar+strict_to_constr.sh8
-rw-r--r--dev/ci/user-overlays/07136-evar-map-econstr.sh7
-rw-r--r--dev/ci/user-overlays/07152-ejgallego-api+vernac_expr_iso.sh12
-rw-r--r--dev/core.dbg1
-rw-r--r--dev/doc/MERGING.md2
-rw-r--r--dev/doc/changes.md29
-rw-r--r--dev/doc/coq-src-description.txt6
-rw-r--r--dev/doc/debugging.md2
-rw-r--r--dev/ocamldebug-coq.run2
-rwxr-xr-xdev/tools/check-owners-pr.sh32
-rwxr-xr-xdev/tools/check-owners.sh138
-rw-r--r--dev/tools/coqdev.el12
-rwxr-xr-xdev/tools/merge-pr.sh8
-rwxr-xr-xdev/tools/pre-commit12
-rw-r--r--dev/top_printers.ml6
-rw-r--r--dev/top_printers.mli2
-rw-r--r--doc/LICENSE18
-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/refman/AddRefMan-pre.tex63
-rw-r--r--doc/refman/RefMan-gal.tex1737
-rw-r--r--doc/refman/RefMan-ltac.tex1829
-rw-r--r--doc/refman/Reference-Manual.tex136
-rw-r--r--doc/refman/Universes.tex393
-rw-r--r--doc/refman/biblio.bib1397
-rw-r--r--doc/refman/coq-listing.tex152
-rw-r--r--doc/refman/coqide-queries.pngbin66656 -> 0 bytes
-rw-r--r--doc/refman/coqide.pngbin59662 -> 0 bytes
-rw-r--r--doc/refman/headers.hva44
-rw-r--r--doc/refman/headers.sty88
-rw-r--r--doc/refman/index.html14
-rw-r--r--doc/refman/menu.html32
-rw-r--r--doc/sphinx/_static/CoqNotations.ttfbin0 -> 37988 bytes
-rw-r--r--doc/sphinx/_static/UbuntuMono-Square.ttfbin38104 -> 0 bytes
-rw-r--r--doc/sphinx/_static/notations.css12
-rw-r--r--doc/sphinx/addendum/extended-pattern-matching.rst19
-rw-r--r--doc/sphinx/addendum/extraction.rst139
-rw-r--r--doc/sphinx/addendum/generalized-rewriting.rst88
-rw-r--r--doc/sphinx/addendum/implicit-coercions.rst134
-rw-r--r--doc/sphinx/addendum/micromega.rst64
-rw-r--r--doc/sphinx/addendum/miscellaneous-extensions.rst14
-rw-r--r--doc/sphinx/addendum/nsatz.rst2
-rw-r--r--doc/sphinx/addendum/omega.rst53
-rw-r--r--doc/sphinx/addendum/parallel-proof-processing.rst6
-rw-r--r--doc/sphinx/addendum/program.rst20
-rw-r--r--doc/sphinx/addendum/ring.rst20
-rw-r--r--doc/sphinx/addendum/type-classes.rst383
-rw-r--r--doc/sphinx/addendum/universe-polymorphism.rst445
-rw-r--r--doc/sphinx/biblio.bib24
-rw-r--r--doc/sphinx/credits.rst36
-rw-r--r--doc/sphinx/index.rst6
-rw-r--r--doc/sphinx/introduction.rst15
-rw-r--r--doc/sphinx/language/cic.rst247
-rw-r--r--doc/sphinx/language/coq-library.rst17
-rw-r--r--doc/sphinx/language/gallina-extensions.rst625
-rw-r--r--doc/sphinx/language/gallina-specification-language.rst1384
-rw-r--r--doc/sphinx/practical-tools/coq-commands.rst35
-rw-r--r--doc/sphinx/practical-tools/coqide.rst20
-rw-r--r--doc/sphinx/practical-tools/utilities.rst243
-rw-r--r--doc/sphinx/proof-engine/detailed-tactic-examples.rst17
-rw-r--r--doc/sphinx/proof-engine/ltac.rst1310
-rw-r--r--doc/sphinx/proof-engine/proof-handling.rst596
-rw-r--r--doc/sphinx/proof-engine/ssreflect-proof-language.rst46
-rw-r--r--doc/sphinx/proof-engine/tactics.rst1364
-rw-r--r--doc/sphinx/proof-engine/vernacular-commands.rst1584
-rw-r--r--doc/sphinx/replaces.rst4
-rw-r--r--doc/sphinx/user-extensions/proof-schemes.rst67
-rw-r--r--doc/sphinx/user-extensions/syntax-extensions.rst83
-rw-r--r--doc/tools/coqrst/coqdomain.py33
-rw-r--r--doc/tools/coqrst/notations/CoqNotations.ttfbin0 -> 37988 bytes
-rw-r--r--doc/tools/coqrst/notations/TacticNotations.g9
-rw-r--r--doc/tools/coqrst/notations/TacticNotations.tokens3
-rw-r--r--doc/tools/coqrst/notations/TacticNotationsLexer.py48
-rw-r--r--doc/tools/coqrst/notations/TacticNotationsLexer.tokens3
-rw-r--r--doc/tools/coqrst/notations/TacticNotationsParser.py71
-rw-r--r--doc/tools/coqrst/notations/UbuntuMono-Square.ttfbin38200 -> 0 bytes
-rwxr-xr-xdoc/tools/coqrst/notations/fontsupport.py7
-rw-r--r--doc/tools/coqrst/notations/html.py3
-rw-r--r--doc/tools/coqrst/notations/sphinx.py21
-rw-r--r--doc/tutorial/Tutorial.tex1575
-rw-r--r--engine/eConstr.ml143
-rw-r--r--engine/eConstr.mli26
-rw-r--r--engine/engine.mllib1
-rw-r--r--engine/evar_kinds.ml (renamed from intf/evar_kinds.ml)3
-rw-r--r--engine/evarutil.ml101
-rw-r--r--engine/evarutil.mli32
-rw-r--r--engine/evd.ml89
-rw-r--r--engine/evd.mli133
-rw-r--r--engine/proofview.ml9
-rw-r--r--engine/termops.ml17
-rw-r--r--engine/termops.mli8
-rw-r--r--engine/universes.ml317
-rw-r--r--engine/universes.mli20
-rw-r--r--ide/coqOps.ml6
-rw-r--r--ide/ide_slave.ml2
-rw-r--r--interp/constrextern.mli7
-rw-r--r--interp/constrintern.ml8
-rw-r--r--interp/constrintern.mli11
-rw-r--r--interp/declare.mli2
-rw-r--r--interp/dumpglob.mli4
-rw-r--r--interp/impargs.ml4
-rw-r--r--interp/impargs.mli11
-rw-r--r--interp/implicit_quantifiers.mli5
-rw-r--r--interp/interp.mllib1
-rw-r--r--interp/notation.ml51
-rw-r--r--interp/notation.mli17
-rw-r--r--interp/notation_ops.ml14
-rw-r--r--interp/notation_term.ml (renamed from intf/notation_term.ml)3
-rw-r--r--interp/reserve.ml2
-rw-r--r--interp/smartlocate.mli8
-rw-r--r--interp/stdarg.mli7
-rw-r--r--intf/intf.mllib11
-rw-r--r--kernel/byterun/coq_interp.c21
-rw-r--r--kernel/byterun/coq_interp.h9
-rw-r--r--kernel/byterun/coq_memory.c72
-rw-r--r--kernel/byterun/coq_memory.h7
-rw-r--r--kernel/cClosure.ml4
-rw-r--r--kernel/cClosure.mli4
-rw-r--r--kernel/cbytegen.ml4
-rw-r--r--kernel/cbytegen.mli3
-rw-r--r--kernel/clambda.ml4
-rw-r--r--kernel/clambda.mli3
-rw-r--r--kernel/constr.ml10
-rw-r--r--kernel/constr.mli8
-rw-r--r--kernel/csymtable.ml31
-rw-r--r--kernel/csymtable.mli2
-rw-r--r--kernel/environ.mli2
-rw-r--r--kernel/kernel.mllib2
-rw-r--r--kernel/names.ml44
-rw-r--r--kernel/names.mli57
-rw-r--r--kernel/term.ml2
-rw-r--r--kernel/term.mli6
-rw-r--r--kernel/typeops.mli4
-rw-r--r--kernel/uGraph.ml15
-rw-r--r--kernel/uGraph.mli5
-rw-r--r--kernel/univ.ml15
-rw-r--r--kernel/univ.mli2
-rw-r--r--kernel/vm.ml9
-rw-r--r--kernel/vmvalues.ml24
-rw-r--r--kernel/vmvalues.mli6
-rw-r--r--lib/cWarnings.ml4
-rw-r--r--lib/cWarnings.mli2
-rw-r--r--lib/control.ml5
-rw-r--r--lib/control.mli5
-rw-r--r--lib/coqProject_file.ml415
-rw-r--r--lib/flags.ml9
-rw-r--r--lib/flags.mli32
-rw-r--r--lib/loc.ml5
-rw-r--r--lib/loc.mli4
-rw-r--r--library/coqlib.ml34
-rw-r--r--library/coqlib.mli123
-rw-r--r--library/decl_kinds.ml (renamed from intf/decl_kinds.ml)0
-rw-r--r--library/declaremods.ml16
-rw-r--r--library/declaremods.mli16
-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/library.mllib2
-rw-r--r--library/misctypes.ml (renamed from intf/misctypes.ml)0
-rw-r--r--library/nametab.ml1
-rw-r--r--library/nametab.mli22
-rw-r--r--parsing/g_vernac.ml48
-rw-r--r--parsing/pcoq.mli2
-rw-r--r--plugins/cc/ccalgo.ml48
-rw-r--r--plugins/cc/cctac.ml2
-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/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.ml2
-rw-r--r--plugins/firstorder/rules.mli9
-rw-r--r--plugins/firstorder/sequent.ml28
-rw-r--r--plugins/firstorder/sequent.mli22
-rw-r--r--plugins/fourier/fourierR.ml2
-rw-r--r--plugins/funind/functional_principles_proofs.ml3
-rw-r--r--plugins/funind/functional_principles_types.ml15
-rw-r--r--plugins/funind/glob_term_to_relation.ml4
-rw-r--r--plugins/funind/glob_termops.ml11
-rw-r--r--plugins/funind/glob_termops.mli2
-rw-r--r--plugins/funind/indfun.ml28
-rw-r--r--plugins/funind/indfun.mli3
-rw-r--r--plugins/funind/indfun_common.mli6
-rw-r--r--plugins/funind/invfun.ml8
-rw-r--r--plugins/funind/invfun.mli2
-rw-r--r--plugins/funind/recdef.ml20
-rw-r--r--plugins/ltac/extratactics.ml44
-rw-r--r--plugins/ltac/g_ltac.ml43
-rw-r--r--plugins/ltac/pptactic.ml1
-rw-r--r--plugins/ltac/pptactic.mli2
-rw-r--r--plugins/ltac/rewrite.ml8
-rw-r--r--plugins/ltac/taccoerce.mli2
-rw-r--r--plugins/ltac/tacexpr.ml5
-rw-r--r--plugins/ltac/tacexpr.mli5
-rw-r--r--plugins/ltac/tacinterp.ml3
-rw-r--r--plugins/ltac/tactic_debug.ml6
-rw-r--r--plugins/setoid_ring/Algebra_syntax.v9
-rw-r--r--plugins/setoid_ring/Integral_domain.v10
-rw-r--r--plugins/setoid_ring/RealField.v10
-rw-r--r--plugins/setoid_ring/Ring_tac.v10
-rw-r--r--plugins/setoid_ring/Rings_Q.v10
-rw-r--r--plugins/setoid_ring/Rings_R.v10
-rw-r--r--plugins/setoid_ring/Rings_Z.v10
-rw-r--r--plugins/setoid_ring/newring.ml10
-rw-r--r--plugins/setoid_ring/newring.mli3
-rw-r--r--plugins/ssr/ssrcommon.ml27
-rw-r--r--plugins/ssr/ssrcommon.mli4
-rw-r--r--plugins/ssr/ssrelim.ml4
-rw-r--r--plugins/ssr/ssrequality.ml21
-rw-r--r--plugins/ssr/ssripats.ml23
-rw-r--r--plugins/ssr/ssrview.ml4
-rw-r--r--plugins/ssrmatching/ssrmatching.ml424
-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.ml5
-rw-r--r--pretyping/cbv.ml2
-rw-r--r--pretyping/cbv.mli2
-rw-r--r--pretyping/classops.ml2
-rw-r--r--pretyping/classops.mli2
-rw-r--r--pretyping/coercion.ml2
-rw-r--r--pretyping/constrexpr.ml (renamed from intf/constrexpr.ml)0
-rw-r--r--pretyping/detyping.ml2
-rw-r--r--pretyping/evarconv.ml36
-rw-r--r--pretyping/evarconv.mli2
-rw-r--r--pretyping/evardefine.ml12
-rw-r--r--pretyping/evarsolve.ml59
-rw-r--r--pretyping/evarsolve.mli2
-rw-r--r--pretyping/extend.ml (renamed from intf/extend.ml)0
-rw-r--r--pretyping/genredexpr.ml (renamed from intf/genredexpr.ml)0
-rw-r--r--pretyping/glob_ops.ml2
-rw-r--r--pretyping/glob_term.ml (renamed from intf/glob_term.ml)3
-rw-r--r--pretyping/indrec.mli2
-rw-r--r--pretyping/inductiveops.mli4
-rw-r--r--pretyping/locus.ml (renamed from intf/locus.ml)0
-rw-r--r--pretyping/nativenorm.ml6
-rw-r--r--pretyping/pattern.ml (renamed from intf/pattern.ml)3
-rw-r--r--pretyping/patternops.ml4
-rw-r--r--pretyping/patternops.mli10
-rw-r--r--pretyping/pretyping.ml12
-rw-r--r--pretyping/pretyping.mllib9
-rw-r--r--pretyping/program.mli38
-rw-r--r--pretyping/recordops.ml4
-rw-r--r--pretyping/recordops.mli13
-rw-r--r--pretyping/reductionops.ml25
-rw-r--r--pretyping/reductionops.mli12
-rw-r--r--pretyping/retyping.ml10
-rw-r--r--pretyping/retyping.mli2
-rw-r--r--pretyping/tacred.ml8
-rw-r--r--pretyping/tacred.mli11
-rw-r--r--pretyping/typeclasses.ml27
-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.ml9
-rw-r--r--pretyping/typing.mli2
-rw-r--r--pretyping/unification.ml32
-rw-r--r--pretyping/vernacexpr.ml (renamed from intf/vernacexpr.ml)52
-rw-r--r--pretyping/vnorm.ml6
-rw-r--r--printing/ppvernac.ml20
-rw-r--r--printing/prettyp.ml3
-rw-r--r--printing/prettyp.mli3
-rw-r--r--printing/printer.ml20
-rw-r--r--printing/printer.mli5
-rw-r--r--proofs/clenv.ml23
-rw-r--r--proofs/evar_refiner.ml8
-rw-r--r--proofs/goal.ml23
-rw-r--r--proofs/goal.mli3
-rw-r--r--proofs/goal_select.ml68
-rw-r--r--proofs/goal_select.mli26
-rw-r--r--proofs/logic.ml68
-rw-r--r--proofs/pfedit.ml26
-rw-r--r--proofs/pfedit.mli2
-rw-r--r--proofs/proof_bullet.ml68
-rw-r--r--proofs/proof_bullet.mli19
-rw-r--r--proofs/proof_global.ml3
-rw-r--r--proofs/proofs.mllib1
-rw-r--r--proofs/refine.ml16
-rw-r--r--proofs/tacmach.mli2
-rw-r--r--stm/proofBlockDelimiter.ml6
-rw-r--r--stm/proofBlockDelimiter.mli4
-rw-r--r--stm/stm.ml91
-rw-r--r--stm/stm.mli11
-rw-r--r--stm/workerLoop.ml4
-rw-r--r--stm/workerLoop.mli4
-rw-r--r--tactics/auto.ml5
-rw-r--r--tactics/btermdn.ml2
-rw-r--r--tactics/class_tactics.ml10
-rw-r--r--tactics/elimschemes.ml4
-rw-r--r--tactics/equality.ml13
-rw-r--r--tactics/hints.ml50
-rw-r--r--tactics/hints.mli39
-rw-r--r--tactics/hipattern.ml6
-rw-r--r--tactics/hipattern.mli2
-rw-r--r--tactics/inv.ml2
-rw-r--r--tactics/tacticals.ml19
-rw-r--r--tactics/tacticals.mli6
-rw-r--r--tactics/tactics.ml80
-rw-r--r--tactics/tactics.mli5
-rw-r--r--tactics/term_dnet.ml2
-rw-r--r--test-suite/Makefile37
-rw-r--r--test-suite/bugs/closed/1501.v (renamed from test-suite/bugs/opened/1501.v)61
-rw-r--r--test-suite/bugs/closed/2001.v2
-rw-r--r--test-suite/bugs/closed/2456.v (renamed from test-suite/bugs/opened/2456.v)7
-rw-r--r--test-suite/bugs/closed/2814.v (renamed from test-suite/bugs/opened/2814.v)1
-rw-r--r--test-suite/bugs/closed/3100.v (renamed from test-suite/bugs/opened/3100.v)0
-rw-r--r--test-suite/bugs/closed/3230.v (renamed from test-suite/bugs/opened/3230.v)0
-rw-r--r--test-suite/bugs/closed/3320.v (renamed from test-suite/bugs/opened/3320.v)3
-rw-r--r--test-suite/bugs/closed/3350.v2
-rw-r--r--test-suite/bugs/closed/4722.v1
l---------test-suite/bugs/closed/4722/tata1
-rw-r--r--test-suite/bugs/closed/7462.v13
-rw-r--r--test-suite/bugs/opened/3209.v17
-rw-r--r--test-suite/bugs/opened/3263.v232
-rw-r--r--test-suite/bugs/opened/3916.v3
-rw-r--r--test-suite/bugs/opened/3948.v25
-rw-r--r--test-suite/bugs/opened/4813.v4
-rwxr-xr-xtest-suite/coq-makefile/timing/run.sh2
-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/Notations3.out10
-rw-r--r--test-suite/output/Notations3.v5
-rw-r--r--test-suite/output/UnclosedBlocks.out1
-rwxr-xr-xtest-suite/save-logs.sh2
-rw-r--r--test-suite/success/ShowExtraction.v2
-rw-r--r--test-suite/success/cc.v14
-rw-r--r--test-suite/success/evars.v5
-rw-r--r--test-suite/success/goal_selector.v14
-rw-r--r--test-suite/success/intros.v24
-rw-r--r--test-suite/success/name_mangling.v3
-rw-r--r--test-suite/success/ssr_delayed_clear_rename.v5
-rw-r--r--theories/Arith/Div2.v4
-rw-r--r--theories/Arith/Even.v4
-rw-r--r--theories/Arith/PeanoNat.v10
-rw-r--r--theories/Lists/Streams.v2
-rw-r--r--theories/PArith/BinPos.v2
-rw-r--r--theories/Sorting/Heap.v4
-rw-r--r--tools/CoqMakefile.in2
-rw-r--r--tools/coqdep.ml53
-rw-r--r--tools/coqdep_common.ml49
-rw-r--r--tools/coqdep_common.mli2
-rw-r--r--tools/ocamllibdep.mll12
-rw-r--r--toplevel/coqargs.ml4
-rw-r--r--toplevel/coqloop.ml55
-rw-r--r--toplevel/coqloop.mli2
-rw-r--r--toplevel/coqtop.ml129
-rw-r--r--toplevel/coqtop.mli3
-rw-r--r--vernac/assumptions.mli2
-rw-r--r--vernac/auto_ind_decl.ml4
-rw-r--r--vernac/auto_ind_decl.mli2
-rw-r--r--vernac/class.ml3
-rw-r--r--vernac/class.mli9
-rw-r--r--vernac/classes.ml11
-rw-r--r--vernac/classes.mli10
-rw-r--r--vernac/comAssumption.ml3
-rw-r--r--vernac/comAssumption.mli7
-rw-r--r--vernac/comDefinition.ml4
-rw-r--r--vernac/comFixpoint.ml5
-rw-r--r--vernac/comInductive.ml12
-rw-r--r--vernac/comProgramFixpoint.ml8
-rw-r--r--vernac/declareDef.mli6
-rw-r--r--vernac/himsg.ml23
-rw-r--r--vernac/lemmas.ml4
-rw-r--r--vernac/lemmas.mli4
-rw-r--r--vernac/metasyntax.ml6
-rw-r--r--vernac/obligations.ml19
-rw-r--r--vernac/obligations.mli3
-rw-r--r--vernac/record.ml4
-rw-r--r--vernac/record.mli5
-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.ml29
451 files changed, 9762 insertions, 19868 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 352ec5a51..14c102ced 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -8,103 +8,41 @@ defaults:
# reference syntax)
working_directory: ~/coq
docker:
- - image: ocaml/opam:ubuntu
+ - image: coqci/base:V2018-05-07-V2
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"
-
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
-
-opam-switch: &opam-switch
- name: Select opam switch
- command: |
- source ~/.profile
- opam switch ${COMPILER}
+ echo . ~/.profile >> $BASH_ENV
+ 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: |
- source ~/.profile
- # 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" }}-
- - coq-opam-cache-v1-{{ arch }}-{{ checksum "COMPILER" }}- # this grabs old cache if checksum doesn't match
- - run:
- name: Update opam lists
- command: |
- source ~/.profile
- opam repository set-url default https://opam.ocaml.org
- opam update
- - run:
- name: Install opam packages
- command: |
- source ~/.profile
- opam switch -j ${NJOBS} ${COMPILER}
- opam install -j ${NJOBS} -y camlp5.${CAMLP5_VER} ocamlfind ${EXTRA_OPAM}
- - run:
- name: Clean cache
- command: |
- source ~/.profile
- 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: |
- source ~/.profile
-
./configure -local -native-compiler ${NATIVE_COMP} -coqide no
- run: &build-build
name: Build
command: |
- source ~/.profile
make -j ${NJOBS} byte
make -j ${NJOBS}
make test-suite/misc/universes/all_stdlib.v
- persist_to_workspace:
- root: *workspace
+ root: &workspace ~/
paths:
- coq/
@@ -114,29 +52,21 @@ opam-switch: &opam-switch
<<: *params
steps:
- run: *before_script
- - attach_workspace: *attach_workspace
+ - attach_workspace: &attach_workspace
+ at: *workspace
+
- run:
name: Test
command: |
- source ~/.profile
dev/ci/ci-wrapper.sh ${CIRCLE_JOB}
- persist_to_workspace:
root: *workspace
paths:
- coq/
- environment: &ci-template-vars
- <<: *envvars
- EXTRA_PACKAGES: *timing-packages
# Defines individual jobs, see the workflows section below for job orchestration
jobs:
- opam-boot:
- <<: *opam-boot-template
- environment:
- <<: *envvars
- EXTRA_OPAM: "ocamlgraph ppx_tools_versioned ppx_deriving ocaml-migrate-parsetree"
-
# Build and prepare test environment
build: *build-template
@@ -145,24 +75,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
@@ -173,20 +97,17 @@ jobs:
geocoq:
<<: *ci-template
+ fcsl-pcm:
+ <<: *ci-template
+
fiat-crypto:
<<: *ci-template
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
@@ -199,9 +120,6 @@ jobs:
hott:
<<: *ci-template
- environment:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "time python autoconf automake"
iris-lambda-rust:
<<: *ci-template
@@ -212,11 +130,14 @@ jobs:
math-comp:
<<: *ci-template
+ mtac2:
+ <<: *ci-template
+
+ pidetop:
+ <<: *ci-template
+
sf:
<<: *ci-template
- environment:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "time python wget"
unimath:
<<: *ci-template
@@ -226,14 +147,11 @@ jobs:
workflows:
version: 2
+
# Run on each push
main:
jobs:
- - opam-boot
-
- - build:
- requires:
- - opam-boot
+ - build
- bignums: &req-main
requires:
@@ -245,9 +163,11 @@ workflows:
- 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
@@ -255,6 +175,7 @@ workflows:
requires:
- build
- bignums
+ - mtac2: *req-main
- corn:
requires:
- build
@@ -267,6 +188,7 @@ workflows:
- 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 2d8fc791b..2ca827492 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -8,16 +8,25 @@
########## 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
+
/.travis.yml @ejgallego
# Secondary maintainer @SkySkimmer
/.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
@@ -68,6 +77,11 @@
/engine/ @ppedrot
# Secondary maintainer @aspiwack
+/engine/universes.* @SkySkimmer
+/engine/univops.* @SkySkimmer
+/engine/uState.* @SkySkimmer
+# Secondary maintainer @mattam82
+
########## Grammar macros ##########
/grammar/ @ppedrot
@@ -83,11 +97,6 @@
/interp/ @herbelin
# Secondary maintainer @ejgallego
-########## Interfaces ##########
-
-/intf/ @letouzey
-# Secondary maintainer @ppedrot
-
########## Kernel ##########
/kernel/ @maximedenes
@@ -96,6 +105,11 @@
/kernel/byterun/ @maximedenes
# Secondary maintainer @silene
+/kernel/sorts.* @SkySkimmer
+/kernel/uGraph.* @SkySkimmer
+/kernel/univ.* @SkySkimmer
+# Secondary maintainer @mattam82
+
########## Library ##########
/library/ @silene
@@ -293,7 +307,7 @@
########## Build system ##########
/Makefile* @letouzey
-# Secondary maintainer @maximdenes
+# Secondary maintainer @gares
/configure* @letouzey
# Secondary maintainer @ejgallego
@@ -304,6 +318,12 @@
/dev/build/windows @MSoegtropIMC
# Secondary maintainer @maximedenes
+# This file belongs to CI
+/Makefile.ci @ejgallego
+# Secondary maintainer @SkySkimmer
+
+/Makefile.doc @maximedenes
+# Secondary maintainer @silene
########## Developer tools ##########
@@ -324,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 267534365..e2a97b3a1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,6 +61,7 @@ plugins/micromega/csdpcert
plugins/micromega/.micromega.ml.generated
kernel/byterun/dllcoqrun.so
coqdoc.sty
+coqdoc.css
time-of-build.log
time-of-build-pretty.log
time-of-build-before.log
@@ -96,21 +97,6 @@ doc/faq/axioms.eps
doc/faq/axioms.eps_t
doc/faq/axioms.pdf_t
doc/faq/axioms.png
-doc/refman/.csdp.cache
-doc/refman/trace
-doc/refman/Reference-Manual.ps
-doc/refman/Reference-Manual.html
-doc/refman/Reference-Manual.out
-doc/refman/Reference-Manual.sh
-doc/refman/cover.html
-doc/refman/styles.hva
-doc/refman/coqide-queries.eps
-doc/refman/coqide.eps
-doc/refman/euclid.ml
-doc/refman/euclid.mli
-doc/refman/heapsort.ml
-doc/refman/heapsort.mli
-doc/refman/html/
doc/stdlib/Library.out
doc/stdlib/Library.ps
doc/stdlib/Library.coqdoc.tex
@@ -177,9 +163,6 @@ dev/myinclude
# coqide generated files (when testing)
*.crashcoqide
-/doc/refman/Reference-Manual.hoptind
-/doc/refman/Reference-Manual.optidx
-/doc/refman/Reference-Manual.optind
user-contrib
.*.sw*
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f0d7463fc..095099690 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,61 +1,35 @@
-image: ocaml/opam:ubuntu
-
-# this doesn't seem to work
-cache:
- paths:
- - .opamcache
+image: coqci/base:V2018-05-07-V2
stages:
- build
- test
+# some default values
variables:
- # some default values
- NJOBS: "2"
- COMPILER: "system"
- CAMLP5_VER: "6.14"
-
- # some useful values
- COMPILER_32BIT: "4.02.3+32bit"
-
- COMPILER_BLEEDING_EDGE: "4.06.0"
- CAMLP5_VER_BLEEDING_EDGE: "7.03"
-
- TIMING_PACKAGES: "time python"
-
- COQIDE_PACKAGES: "libgtk2.0-dev libgtksourceview2.0-dev"
- #COQIDE_PACKAGES_32BIT: "libgtk2.0-dev:i386 libgtksourceview2.0-dev:i386"
- COQIDE_OPAM: "lablgtk-extras"
- COQIDE_OPAM_BE: "lablgtk.2.18.6 lablgtk-extras.1.6"
- COQDOC_PACKAGES: "texlive-latex-base texlive-latex-recommended texlive-latex-extra texlive-math-extra texlive-fonts-recommended texlive-fonts-extra latex-xcolor ghostscript transfig imagemagick tipa python3-pip"
- COQDOC_OPAM: "hevea"
- SPHINX_PACKAGES: "bs4 sphinx sphinx_rtd_theme pexpect antlr4-python3-runtime sphinxcontrib-bibtex"
-
+ # Format: $IMAGE-V$DATE [Cache is not used as of today but kept here
+ # for reference]
+ CACHEKEY: bionic_coq-V2018-05-07-V2
+ # 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: ""
before_script:
- - ls # figure out if artifacts are around
- - printenv
-# - if [ "$COMPILER" = "$COMPILER_32BIT" ]; then sudo dpkg --add-architecture i386; fi
- - if [ -n "${EXTRA_PACKAGES}" ]; then sudo apt-get update -qq && sudo apt-get install -y -qq ${EXTRA_PACKAGES}; fi
- - if [ -n "${PIP_PACKAGES}" ]; then sudo pip3 install ${PIP_PACKAGES}; fi
-
- # setup cache
- - if [ ! "(" -d .opamcache ")" ]; then mv ~/.opam .opamcache; else mv ~/.opam ~/.opam-old; fi
- - ln -s $(readlink -f .opamcache) ~/.opam
-
- # the default repo in this docker image is a local directory
- # at the time of 4aaeb8abf it lagged behind the official
- # repository such that camlp5 7.01 was not available
- - opam repository set-url default https://opam.ocaml.org
- - opam update
- - opam switch ${COMPILER}
+ - cat /proc/{cpu,mem}info || true
+ - ls -a # figure out if artifacts are around
+ - printenv | sort
+ - 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 config list
- - opam install -j ${NJOBS} -y camlp5.${CAMLP5_VER} ocamlfind num ${EXTRA_OPAM}
- - rm -rf ~/.opam/log/
- opam list
+ - opam config list
-# TODO figure out how to build doc for installed coq
+################ GITLAB CACHING ######################
+# - use artifacts between jobs #
+######################################################
+
+# TODO figure out how to build doc for installed Coq
.build-template: &build-template
stage: build
artifacts:
@@ -69,12 +43,12 @@ before_script:
- set -e
- 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'
@@ -89,41 +63,49 @@ before_script:
.warnings-template: &warnings-template
# keep warnings in test stage so we can test things even when warnings occur
stage: test
- dependencies: []
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"
+# 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
stage: test
+ dependencies:
+ - not-a-real-job
script:
- cd test-suite
- make clean
# 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
paths:
- test-suite/logs
+# set dependencies when using
.validate-template: &validate-template
stage: test
+ dependencies:
+ - not-a-real-job
script:
- cd _install_ci
- find lib/coq/ -name '*.vo' -print0 > vofiles
@@ -135,179 +117,209 @@ 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:
- - build
+ - build:base
variables: &ci-template-vars
TEST_TARGET: "$CI_JOB_NAME"
- EXTRA_PACKAGES: "$TIMING_PACKAGES"
-build:
+.ci-template-flambda: &ci-template-flambda
+ <<: *ci-template
+ dependencies:
+ - build:edge+flambda
+ variables:
+ <<: *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:base:
<<: *build-template
variables:
- EXTRA_CONF: "-native-compiler yes -coqide opt -with-doc yes"
- EXTRA_PACKAGES: "$COQIDE_PACKAGES $COQDOC_PACKAGES"
- EXTRA_OPAM: "$COQIDE_OPAM $COQDOC_OPAM"
- 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
+ variables:
+ OPAM_VARIANT: "+32bit"
+ COQ_EXTRA_CONF: "-native-compiler yes"
+
+build:edge:
<<: *build-template
variables:
- EXTRA_CONF: "-native-compiler yes"
- EXTRA_PACKAGES: "gcc-multilib"
- COMPILER: "$COMPILER_32BIT"
+ OPAM_SWITCH: edge
+ COQ_EXTRA_CONF: "-native-compiler yes -coqide opt"
-build:bleeding-edge:
+build:edge+flambda:
<<: *build-template
variables:
- EXTRA_CONF: "-native-compiler yes -coqide opt"
- COMPILER: "$COMPILER_BLEEDING_EDGE"
- CAMLP5_VER: "$CAMLP5_VER_BLEEDING_EDGE"
- EXTRA_PACKAGES: "$COQIDE_PACKAGES"
- EXTRA_OPAM: "$COQIDE_OPAM_BE"
+ OPAM_SWITCH: edge
+ OPAM_VARIANT: "+flambda"
+ COQ_EXTRA_CONF: "-native-compiler no -coqide opt -flambda-opts "
+ COQ_EXTRA_CONF_QUOTE: "-O3 -unbox-closures"
-warnings:
+windows64:
+ <<: *windows-template
+ variables:
+ ARCH: "64"
+
+windows32:
+ <<: *windows-template
+ variables:
+ ARCH: "32"
+
+warnings:base:
<<: *warnings-template
# warnings:32bit:
# <<: *warnings-template
# variables:
# <<: *warnings-variables
-# EXTRA_PACKAGES: "$gcc-multilib COQIDE_PACKAGES_32BIT"
-# COMPILER: "$COMPILER_32BIT"
-warnings:bleeding-edge:
+warnings:edge:
<<: *warnings-template
variables:
- <<: *warnings-variables
- COMPILER: "$COMPILER_BLEEDING_EDGE"
- CAMLP5_VER: "$CAMLP5_VER_BLEEDING_EDGE"
- EXTRA_OPAM: "$COQIDE_OPAM_BE"
+ OPAM_SWITCH: edge
-test-suite:
+test-suite:base:
<<: *test-suite-template
dependencies:
- - build
+ - build:base
+
+test-suite:base+32bit:
+ <<: *test-suite-template
+ dependencies:
+ - build:base+32bit
variables:
- EXTRA_PACKAGES: "$TIMING_PACKAGES"
+ OPAM_VARIANT: "+32bit"
-test-suite:32bit:
+test-suite:edge:
<<: *test-suite-template
dependencies:
- - build:32bit
+ - build:edge
variables:
- COMPILER: "$COMPILER_32BIT"
- EXTRA_PACKAGES: "gcc-multilib $TIMING_PACKAGES"
+ OPAM_SWITCH: edge
-test-suite:bleeding-edge:
+test-suite:edge+flambda:
<<: *test-suite-template
dependencies:
- - build:bleeding-edge
+ - build:edge+flambda
variables:
- COMPILER: "$COMPILER_BLEEDING_EDGE"
- CAMLP5_VER: "$CAMLP5_VER_BLEEDING_EDGE"
- EXTRA_PACKAGES: "$TIMING_PACKAGES"
+ OPAM_SWITCH: edge
+ OPAM_VARIANT: "+flambda"
-validate:
+validate:base:
<<: *validate-template
dependencies:
- - build
+ - build:base
-validate:32bit:
+validate:base+32bit:
<<: *validate-template
dependencies:
- - build:32bit
+ - build:base+32bit
variables:
- COMPILER: "$COMPILER_32BIT"
- 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_OPAM: "ocamlgraph"
- EXTRA_PACKAGES: "$TIMING_PACKAGES autoconf"
ci-coquelicot:
<<: *ci-template
- variables:
- <<: *ci-template-vars
- EXTRA_PACKAGES: "$TIMING_PACKAGES autoconf"
+
+ci-cross-crypto:
+ <<: *ci-template
ci-elpi:
<<: *ci-template
- variables:
- <<: *ci-template-vars
- EXTRA_OPAM: "ppx_tools_versioned ppx_deriving ocaml-migrate-parsetree"
ci-equations:
<<: *ci-template
-ci-geocoq:
+ci-fcsl-pcm:
<<: *ci-template
- allow_failure: true
-# 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-math-comp:
+ <<: *ci-template-flambda
+
+ci-mtac2:
<<: *ci-template
-ci-math-comp:
+ci-pidetop:
<<: *ci-template
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 d60f5037b..40db60950 100644
--- a/.merlin
+++ b/.merlin
@@ -10,8 +10,6 @@ S kernel
B kernel
S kernel/byterun
B kernel/byterun
-S intf
-B intf
S library
B library
S engine
diff --git a/.travis.yml b/.travis.yml
index e56204b0e..88eed5186 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -39,11 +39,11 @@ 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"
@@ -54,7 +54,7 @@ env:
- 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" EXTRA_OPAM="num" FINDLIB_VER="${FINDLIB_VER_BE}"
+ - 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:
@@ -67,7 +67,7 @@ matrix:
- 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,9 +76,12 @@ 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=""
- - TEST_TARGET="ci-elpi" EXTRA_OPAM="ppx_tools_versioned ppx_deriving ocaml-migrate-parsetree"
- if: NOT (type = pull_request)
env:
- TEST_TARGET="ci-equations"
@@ -87,6 +90,9 @@ matrix:
- 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:
@@ -114,6 +120,12 @@ matrix:
- TEST_TARGET="ci-math-comp"
- if: NOT (type = pull_request)
env:
+ - TEST_TARGET="ci-mtac2"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-pidetop"
+ - if: NOT (type = pull_request)
+ env:
- TEST_TARGET="ci-sf"
- if: NOT (type = pull_request)
env:
@@ -137,7 +149,7 @@ matrix:
- env:
- TEST_TARGET="test-suite"
- EXTRA_CONF="-coqide opt -with-doc yes"
- - EXTRA_OPAM="hevea ${LABLGTK}"
+ - EXTRA_OPAM="${LABLGTK}"
before_install: &sphinx-install
- sudo pip3 install bs4 sphinx sphinx_rtd_theme pexpect antlr4-python3-runtime sphinxcontrib-bibtex
addons:
@@ -157,8 +169,6 @@ matrix:
- texlive-fonts-extra
- latex-xcolor
- ghostscript
- - transfig
- - imagemagick
- tipa
- python3
- python3-pip
@@ -170,7 +180,7 @@ matrix:
- FINDLIB_VER="${FINDLIB_VER_BE}"
- CAMLP5_VER="${CAMLP5_VER_BE}"
- EXTRA_CONF="-coqide opt -with-doc yes"
- - EXTRA_OPAM="num hevea ${LABLGTK_BE}"
+ - EXTRA_OPAM="${LABLGTK_BE}"
before_install: *sphinx-install
addons:
apt:
@@ -186,7 +196,7 @@ matrix:
- CAMLP5_VER="${CAMLP5_VER_BE}"
- NATIVE_COMP="no"
- EXTRA_CONF="-coqide opt -with-doc yes -flambda-opts -O3"
- - EXTRA_OPAM="num hevea ${LABLGTK_BE}"
+ - EXTRA_OPAM="${LABLGTK_BE}"
before_install: *sphinx-install
addons:
apt:
@@ -198,9 +208,7 @@ matrix:
- env:
- MAIN_TARGET="coqocaml"
- EXTRA_CONF="-byte-only -coqide byte -warn-error yes"
- - EXTRA_OPAM="hevea ${LABLGTK}"
- # dummy target
- - BUILD_TARGET="clean"
+ - EXTRA_OPAM="${LABLGTK}"
addons:
apt:
sources:
@@ -217,9 +225,7 @@ matrix:
- FINDLIB_VER="${FINDLIB_VER_BE}"
- CAMLP5_VER="${CAMLP5_VER_BE}"
- EXTRA_CONF="-byte-only -coqide byte -warn-error yes"
- - EXTRA_OPAM="num hevea ${LABLGTK_BE}"
- # dummy target
- - BUILD_TARGET="clean"
+ - EXTRA_OPAM="${LABLGTK_BE}"
addons:
apt:
sources:
@@ -275,9 +281,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 camlp5${CAMLP5_VER} ocamlfind${FINDLIB_VER} ${EXTRA_OPAM}
+- opam install -j ${NJOBS} -y num camlp5${CAMLP5_VER} ocamlfind${FINDLIB_VER} ${EXTRA_OPAM}
- opam list
script:
diff --git a/CHANGES b/CHANGES
index 234d6c0db..cdc1ff6a6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,22 +1,45 @@
Changes from 8.8.2 to 8.9+beta1
===============================
+Tactics
+
+- Added toplevel goal selector ! which expects a single focused goal.
+ Use with Set Default Goal Selector to force focusing before tactics
+ are called.
+
Tools
- Coq_makefile lets one override or extend the following variables from
the command line: COQFLAGS, COQCHKFLAGS, COQDOCFLAGS.
+ COQFLAGS is now entirely separate from COQLIBS, so in custom Makefiles
+ $(COQFLAGS) should be replaced by $(COQFLAGS) $(COQLIBS).
Vernacular Commands
- Removed deprecated commands Arguments Scope and Implicit Arguments
(not the option). Use the Arguments command instead.
+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
- Support for fix/cofix added in Ltac "match" and "lazymatch".
-- Ltac backtraces now contain include trace information about tactics
+- Ltac backtraces now include trace information about tactics
called by OCaml-defined tactics.
+- Option "Ltac Debug" now applies also to terms built using Ltac functions.
+
+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
===============================
@@ -27,6 +50,18 @@ Tools
Coq was ignoring previous runs and the -async-proofs-delegation-threshold
option did not have the expected behavior.
+Tactic language
+
+- The undocumented "nameless" forms `fix N`, `cofix N` have been
+ deprecated; please use `fix/cofix ident N` to explicitely name
+ hypothesis to be introduced.
+
+Documentation
+
+- The reference manual is now fully ported to Sphinx.
+
+Other small deprecations and bug fixes.
+
Changes from 8.7.2 to 8.8+beta1
===============================
@@ -93,6 +128,7 @@ Tactics
of the execution.
- `vm_compute` now supports existential variables.
- Calls to `shelve` and `give_up` within calls to tactic `refine` now working.
+- Deprecated tactic `appcontext` was removed.
Focusing
@@ -196,6 +232,7 @@ Options
+ `Refolding Reduction`
+ `Standard Proposition Elimination`
+ + `Dependent Propositions Elimination`
+ `Discriminate Introduction`
+ `Shrink Abstract`
+ `Tactic Pattern Unification`
@@ -203,6 +240,7 @@ Options
+ `Injection L2R Pattern Order`
+ `Record Elimination Schemes`
+ `Match Strict`
+ + `Tactic Compat Context`
+ `Typeclasses Legacy Resolution`
+ `Typeclasses Module Eta`
+ `Typeclass Resolution After Apply`
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/CREDITS b/CREDITS
index 8675b1a64..f59bfca86 100644
--- a/CREDITS
+++ b/CREDITS
@@ -128,6 +128,8 @@ of the Coq Proof assistant during the indicated time:
Matej Košík (INRIA, 2015-2017)
Pierre Letouzey (LRI, 2000-2004, PPS, 2005-2008,
INRIA-PPS then IRIF, 2009-now)
+ Yishuai Li (ORCID: https://orcid.org/0000-0002-5728-5903
+ U. Penn, 2018)
Patrick Loiseleur (Paris Sud, 1997-1999)
Evgeny Makarov (INRIA, 2007)
Gregory Malecha (Harvard University 2013-2015,
@@ -148,6 +150,7 @@ of the Coq Proof assistant during the indicated time:
Pierre-Marie Pédrot (INRIA-PPS, 2011-2015, INRIA-Ascola, 2015-2016,
University of Ljubljana, 2016-2017,
MPI-SWS, 2017-2018)
+ Clément Pit-Claudel (MIT, 2015-2018)
Matthias Puech (INRIA-Bologna, 2008-2011)
Yann Régis-Gianas (INRIA-PPS then IRIF, 2009-now)
Clément Renard (INRIA, 2001-2004)
diff --git a/INSTALL.doc b/INSTALL.doc
index b71115bfa..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,12 +20,7 @@ To produce all the documents, the following tools are needed:
- latex (latex2e)
- pdflatex
- dvips
- - bibtex
- makeindex
- - fig2dev (transfig)
- - convert (ImageMagick)
- - hevea
- - hacha
- Python 3
- Sphinx 1.6.5 (http://www.sphinx-doc.org/en/stable/)
- sphinx_rtd_theme
@@ -34,17 +29,26 @@ To produce all the documents, the following tools are needed:
- Antlr4 runtime for Python 3
-Under Debian based operating systems (Debian, Ubuntu, ...) a
-working set of packages for compiling the documentation for Coq is:
+Under recent Debian based operating systems (Debian 10 "Buster",
+Ubuntu 18.04, ...) a working set of packages for compiling the
+documentation for Coq is:
+
+ texlive-latex-extra texlive-fonts-recommended python3-sphinx
+ python3-pexpect python3-sphinx-rtd-theme python3-bs4
+ python3-sphinxcontrib.bibtex python3-pip
+
+Then, install the Python3 Antlr4 package:
- texlive texlive-latex-extra texlive-math-extra texlive-fonts-extra
- texlive-humanities texlive-pictures latex-xcolor hevea transfig
- imagemagick
- python3 python-pip3
+ pip3 install antlr4-python3-runtime
-To install the Python packages required to build the user manual, run:
- pip3 install sphinx sphinx_rtd_theme beautifulsoup4 antlr4-python3-runtime pexpect
+Nix users should get the correct development environment to build the
+HTML documentation from Coq's `default.nix`. [Note Nix setup doesn't
+include the LaTeX packages needed to build the full documentation.]
+If you are in an older/different distribution you can install the
+Python packages required to build the user manual using python3-pip:
+
+ pip3 install sphinx sphinx_rtd_theme beautifulsoup4 antlr4-python3-runtime pexpect sphinxcontrib-bibtex
Compilation
-----------
@@ -66,17 +70,8 @@ Alternatively, you can use some specific targets:
make doc-html
to produce all html documents
- make refman
- to produce all formats 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 sphinx
+ to produce the HTML version of the reference manual
make stdlib
to produce all formats of the Coq standard library
@@ -93,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/META.coq b/META.coq
index 30bfdd67a..3414ccbd4 100644
--- a/META.coq
+++ b/META.coq
@@ -90,19 +90,6 @@ package "library" (
)
-package "intf" (
-
- description = "Coq Public Data Types"
- version = "8.8"
-
- requires = "coq.library"
-
- directory = "intf"
-
- archive(byte) = "intf.cma"
- archive(native) = "intf.cmxa"
-)
-
package "engine" (
description = "Coq Tactic Engine"
diff --git a/Makefile b/Makefile
index c31534f36..793afb661 100644
--- a/Makefile
+++ b/Makefile
@@ -235,11 +235,8 @@ docclean:
doc/stdlib/*Library.coqdoc.tex doc/stdlib/library.files \
doc/stdlib/library.files.ls doc/stdlib/FullLibrary.tex
rm -f doc/*/*.ps doc/*/*.pdf doc/*/*.eps doc/*/*.pdf_t doc/*/*.eps_t
- rm -rf doc/refman/html doc/stdlib/html doc/tutorial/tutorial.v.html
- rm -f doc/refman/euclid.ml doc/refman/euclid.mli
- rm -f doc/refman/heapsort.ml doc/refman/heapsort.mli
+ rm -rf doc/stdlib/html doc/tutorial/tutorial.v.html
rm -f doc/common/version.tex
- rm -f doc/refman/styles.hva doc/refman/cover.html doc/refman/Reference-Manual.html
rm -f doc/coq.tex
rm -rf doc/sphinx/_build
diff --git a/Makefile.checker b/Makefile.checker
index 172c64af3..dd1f6d514 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,15 @@ 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)
+
+$(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) $(filter checker/%, $(MLFILES) $(MLIFILES) $(CHECKGENFILES)) $(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 $<'
diff --git a/Makefile.ci b/Makefile.ci
index 3c26bf964..ce725d19d 100644
--- a/Makefile.ci
+++ b/Makefile.ci
@@ -15,8 +15,10 @@ CI_TARGETS=ci-bignums \
ci-coquelicot \
ci-corn \
ci-cpdt \
+ ci-cross-crypto \
ci-elpi \
ci-equations \
+ ci-fcsl-pcm \
ci-fiat-crypto \
ci-fiat-parsers \
ci-flocq \
@@ -27,7 +29,8 @@ CI_TARGETS=ci-bignums \
ci-ltac2 \
ci-math-classes \
ci-math-comp \
- ci-metacoq \
+ ci-mtac2 \
+ ci-pidetop \
ci-sf \
ci-tlc \
ci-unimath \
@@ -35,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
@@ -47,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 9a30e2a4c..eed41fbe7 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -75,7 +75,7 @@ INSTALLSH:=./install.sh
MKDIR:=install -d
CORESRCDIRS:=\
- config clib lib kernel intf kernel/byterun library \
+ config clib lib kernel kernel/byterun library \
engine pretyping interp proofs parsing printing \
tactics vernac stm toplevel
@@ -102,7 +102,7 @@ BYTERUN:=$(addprefix kernel/byterun/, \
# respecting this order is useful for developers that want to load or link
# the libraries directly
-CORECMA:=clib/clib.cma lib/lib.cma kernel/kernel.cma intf/intf.cma library/library.cma \
+CORECMA:=clib/clib.cma lib/lib.cma kernel/kernel.cma library/library.cma \
engine/engine.cma pretyping/pretyping.cma interp/interp.cma proofs/proofs.cma \
parsing/parsing.cma printing/printing.cma tactics/tactics.cma vernac/vernac.cma \
stm/stm.cma toplevel/toplevel.cma
diff --git a/Makefile.doc b/Makefile.doc
index e52da403a..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,23 +25,10 @@ doc-no:
######################################################################
LATEX:=latex
-BIBTEX:=BIBINPUTS=.: bibtex -min-crossrefs=10
MAKEINDEX:=makeindex
PDFLATEX:=pdflatex
DVIPS:=dvips
-FIG2DEV:=fig2dev
-CONVERT:=convert
-HEVEA:=hevea
-HACHA:=hacha
-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
@@ -56,56 +40,33 @@ ALLSPHINXOPTS= -d $(SPHINXBUILDDIR)/doctrees $(SPHINXOPTS)
DOCCOMMON:=doc/common/version.tex doc/common/title.tex doc/common/macros.tex
-REFMANCOQTEXFILES:=$(addprefix doc/refman/, \
- RefMan-gal.v.tex \
- RefMan-ltac.v.tex \
- Universes.v.tex)
-
-REFMANTEXFILES:=$(addprefix doc/refman/, \
- headers.sty Reference-Manual.tex) \
- $(REFMANCOQTEXFILES) \
-
-REFMANEPSFILES:=doc/refman/coqide.eps doc/refman/coqide-queries.eps
-
-REFMANFILES:=$(REFMANTEXFILES) $(DOCCOMMON) $(REFMANEPSFILES) doc/refman/biblio.bib
-
-REFMANPNGFILES:=$(REFMANEPSFILES:.eps=.png)
-
-
######################################################################
### General rules
######################################################################
-.PHONY: doc sphinxdoc-html doc-pdf doc-ps refman refman-quick tutorial
-.PHONY: stdlib full-stdlib rectutorial refman-html-dir
+.PHONY: doc doc-html doc-pdf doc-ps
+.PHONY: stdlib full-stdlib
-INDEXURLS:=doc/refman/html/index_urls.txt
+doc: sphinx stdlib
-doc: sphinx refman tutorial rectutorial stdlib $(INDEXURLS)
+ifndef QUICK
+SPHINX_DEPS := coq
+endif
-sphinx: coq
+sphinx: $(SPHINX_DEPS)
$(SHOW)'SPHINXBUILD doc/sphinx'
- $(HIDE)COQBIN="$(PWD)/bin" $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) doc/sphinx $(SPHINXBUILDDIR)/html
+ $(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/refman/html/index.html \
- doc/stdlib/html/index.html doc/RecTutorial/RecTutorial.html
+ doc/stdlib/html/index.html sphinx
doc-pdf:\
- doc/tutorial/Tutorial.v.pdf doc/refman/Reference-Manual.pdf \
- doc/stdlib/Library.pdf doc/RecTutorial/RecTutorial.pdf
+ doc/stdlib/Library.pdf
doc-ps:\
- doc/tutorial/Tutorial.v.ps doc/refman/Reference-Manual.ps \
- doc/stdlib/Library.ps doc/RecTutorial/RecTutorial.ps
-
-refman: \
- doc/refman/html/index.html doc/refman/Reference-Manual.ps doc/refman/Reference-Manual.pdf
-
-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
@@ -113,45 +74,13 @@ stdlib: \
full-stdlib: \
doc/stdlib/html/index.html doc/stdlib/FullLibrary.ps doc/stdlib/FullLibrary.pdf
-rectutorial: doc/RecTutorial/RecTutorial.html \
- doc/RecTutorial/RecTutorial.ps doc/RecTutorial/RecTutorial.pdf
-
######################################################################
### Implicit rules
######################################################################
-ifdef QUICK
-%.v.tex: %.tex
- $(COQTEX) $(COQTEXOPTS) $<
-else
-%.v.tex: %.tex $(COQTEX) $(COQTOPEXE) $(ALLVO)
- $(COQTEX) $(COQTEXOPTS) $<
-endif
-
%.ps: %.dvi
(cd `dirname $<`; $(DVIPS) -q -o `basename $@` `basename $<`)
-%.png: %.fig
- $(FIG2DEV) -L png -m 2 $< $@
-
-%.pdf: %.fig
- $(FIG2DEV) -L pdftex $< $@
- $(FIG2DEV) -L pdftex_t -p `basename $@` $< $@_t
-
-%.eps: %.fig
- $(FIG2DEV) -L pstex $< $@
- $(FIG2DEV) -L pstex_t -p `basename $@` $< $@_t
-
-%.eps: %.png
- $(CONVERT) $< $@
-
-######################################################################
-# Macros for filtering outputs
-######################################################################
-
-HIDEBIBTEXINFO=| grep -v "^A level-1 auxiliary file"
-SHOWMAKEINDEXERROR=egrep '^!! Input index error|^\*\* Input style error|^ --'
-
######################################################################
# Common
######################################################################
@@ -162,99 +91,6 @@ doc/common/version.tex: config/Makefile
printf '\\newcommand{\\coqversion}{$(VERSION)}' > doc/common/version.tex
######################################################################
-# Reference Manual
-######################################################################
-
-
-### Reference Manual (printable format)
-
-# The second LATEX compilation is necessary otherwise the pages of the index
-# are not correct (don't know why...) - BB
-doc/refman/Reference-Manual.dvi: $(REFMANFILES) doc/refman/Reference-Manual.tex
- @(cd doc/refman;\
- $(LATEX) -interaction=batchmode Reference-Manual;\
- $(BIBTEX) -terse Reference-Manual $(HIDEBIBTEXINFO);\
- $(LATEX) -interaction=batchmode Reference-Manual > /dev/null;\
- $(MAKEINDEX) -q Reference-Manual;\
- $(SHOWMAKEINDEXERROR) Reference-Manual.ilg;\
- $(MAKEINDEX) -q Reference-Manual.tacidx -o Reference-Manual.tacind;\
- $(SHOWMAKEINDEXERROR) Reference-Manual.ilg;\
- $(MAKEINDEX) -q Reference-Manual.comidx -o Reference-Manual.comind;\
- $(SHOWMAKEINDEXERROR) Reference-Manual.ilg;\
- $(MAKEINDEX) -q Reference-Manual.optidx -o Reference-Manual.optind;\
- $(SHOWMAKEINDEXERROR) Reference-Manual.ilg;\
- $(MAKEINDEX) -q Reference-Manual.erridx -o Reference-Manual.errind;\
- $(SHOWMAKEINDEXERROR) Reference-Manual.ilg;\
- $(LATEX) -interaction=batchmode Reference-Manual > /dev/null;\
- $(LATEX) -interaction=batchmode Reference-Manual > /dev/null;\
- ../tools/show_latex_messages -no-overfull Reference-Manual.log)
-
-doc/refman/Reference-Manual.pdf: doc/refman/Reference-Manual.dvi $(REFMANPNGFILES)
- (cd doc/refman;\
- $(PDFLATEX) -interaction=batchmode Reference-Manual.tex;\
- ../tools/show_latex_messages -no-overfull Reference-Manual.log)
-
-### Reference Manual (browsable format)
-
-doc/refman/Reference-Manual.html: doc/refman/styles.hva doc/refman/headers.hva doc/refman/Reference-Manual.dvi # to ensure bbl file
- (cd doc/refman; BIBINPUTS=.: $(HEVEA) $(HEVEAOPTS) ./styles.hva ./Reference-Manual.tex)
-
-doc/refman/cover.html: doc/common/styles/html/$(HTMLSTYLE)/cover.html
- sed -e "s/COQVERSION/$(VERSION)/g" $< > $@
-
-doc/refman/styles.hva: doc/common/styles/html/$(HTMLSTYLE)/styles.hva
- $(INSTALLLIB) $< doc/refman
-
-INDEXES:= doc/refman/html/command-index.html doc/refman/html/tactic-index.html
-
-refman-html-dir $(INDEXES): doc/refman/html/index.html ;
-
-doc/refman/html/index.html: doc/refman/Reference-Manual.html $(REFMANPNGFILES) \
- doc/refman/cover.html doc/refman/styles.hva doc/refman/index.html
- - rm -rf doc/refman/html
- $(MKDIR) doc/refman/html
- $(INSTALLLIB) $(REFMANPNGFILES) doc/refman/html
- (cd doc/refman/html; $(HACHA) -nolinks -tocbis -o toc.html ../styles.hva ../Reference-Manual.html)
- $(INSTALLLIB) doc/refman/cover.html doc/refman/html/index.html
- @touch $(INDEXES)
- (cd doc/common/styles/html/$(HTMLSTYLE);\
- for f in `find . -name \*.css`; do \
- $(MKDIR) $$(dirname ../../../../refman/html/$$f);\
- $(INSTALLLIB) $$f ../../../../refman/html/$$f;\
- done)
-
-refman-quick:
- (cd doc/refman;\
- $(PDFLATEX) -interaction=batchmode Reference-Manual.tex;\
- ../tools/show_latex_messages -no-overfull Reference-Manual.log && \
- $(HEVEA) $(HEVEAOPTS) ./Reference-Manual.tex)
-
-######################################################################
-# Index file for CoqIDE
-######################################################################
-
-$(INDEXURLS): $(INDEXES)
- cat $< | grep li-indexenv | grep href= | sed -e 's@.*>\([^<]*\)</span>.*, <a href="\([^"]*\)">.*@\1,\2@' > $@
-
-
-######################################################################
-# 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
######################################################################
@@ -328,63 +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:
- $(MKDIR) $(addprefix $(FULLDOCDIR)/html/, refman stdlib)
- (for f in `cd doc/refman/html; find . -type f`; do \
- $(MKDIR) $$(dirname $(FULLDOCDIR)/html/refman/$$f);\
- $(INSTALLLIB) doc/refman/html/$$f $(FULLDOCDIR)/html/refman/$$f;\
- done)
+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/refman/Reference-Manual.pdf \
- doc/stdlib/Library.pdf $(FULLDOCDIR)/pdf
- $(INSTALLLIB) doc/refman/Reference-Manual.ps \
- 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-index-urls:
- $(MKDIR) $(FULLDATADIR)
- $(INSTALLLIB) $(INDEXURLS) $(FULLDATADIR)
+ $(INSTALLLIB) doc/stdlib/Library.pdf $(FULLDOCDIR)/pdf
+ $(INSTALLLIB) doc/stdlib/Library.ps $(FULLDOCDIR)/ps
install-doc-sphinx:
$(MKDIR) $(FULLDOCDIR)/sphinx
@@ -470,13 +271,6 @@ $(OCAMLDOCDIR)/%.pdf: $(OCAMLDOCDIR)/%.tex
$(HIDE)(cd $(OCAMLDOCDIR) ; pdflatex -interaction=batchmode $*.tex && pdflatex -interaction=batchmode $*.tex)
$(HIDE)(cd doc/tools/; ./show_latex_messages -no-overfull ../../$(OCAMLDOCDIR)/$*.log)
-###########################################################################
-# local web server
-###########################################################################
-
-serve-refman-8080: refman
- cd doc/refman/html; python3 -m http.server 8080
-
# For emacs:
# Local Variables:
# mode: makefile
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/cic.mli b/checker/cic.mli
index 42629ced2..c4b00d0dc 100644
--- a/checker/cic.mli
+++ b/checker/cic.mli
@@ -104,7 +104,7 @@ type constr =
| Case of case_info * constr * constr * constr array
| Fix of constr pfixpoint
| CoFix of constr pcofixpoint
- | Proj of projection * constr
+ | Proj of Projection.t * constr
type existential = constr pexistential
type rec_declaration = constr prec_declaration
diff --git a/checker/closure.ml b/checker/closure.ml
index 184af0e13..bfba6c161 100644
--- a/checker/closure.ml
+++ b/checker/closure.ml
@@ -251,7 +251,7 @@ and fterm =
| FInd of pinductive
| FConstruct of pconstructor
| FApp of fconstr * fconstr array
- | FProj of projection * fconstr
+ | FProj of Projection.t * fconstr
| FFix of fixpoint * fconstr subs
| FCoFix of cofixpoint * fconstr subs
| FCaseT of case_info * constr * fconstr * constr array * fconstr subs (* predicate and branches are closures *)
@@ -281,7 +281,7 @@ let update v1 (no,t) =
type stack_member =
| Zapp of fconstr array
| ZcaseT of case_info * constr * constr array * fconstr subs
- | Zproj of int * int * projection
+ | Zproj of int * int * Projection.t
| Zfix of fconstr * stack
| Zshift of int
| Zupdate of fconstr
diff --git a/checker/closure.mli b/checker/closure.mli
index f68c0468a..4cf02ae2b 100644
--- a/checker/closure.mli
+++ b/checker/closure.mli
@@ -87,7 +87,7 @@ type fterm =
| FInd of pinductive
| FConstruct of pconstructor
| FApp of fconstr * fconstr array
- | FProj of projection * fconstr
+ | FProj of Projection.t * fconstr
| FFix of fixpoint * fconstr subs
| FCoFix of cofixpoint * fconstr subs
| FCaseT of case_info * constr * fconstr * constr array * fconstr subs (* predicate and branches are closures *)
@@ -107,7 +107,7 @@ type fterm =
type stack_member =
| Zapp of fconstr array
| ZcaseT of case_info * constr * constr array * fconstr subs
- | Zproj of int * int * projection
+ | Zproj of int * int * Projection.t
| Zfix of fconstr * stack
| Zshift of int
| Zupdate of fconstr
diff --git a/checker/environ.mli b/checker/environ.mli
index 36e0ea027..81da83875 100644
--- a/checker/environ.mli
+++ b/checker/environ.mli
@@ -58,7 +58,7 @@ val constant_value : env -> Constant.t puniverses -> constr
val evaluable_constant : Constant.t -> env -> bool
val is_projection : Constant.t -> env -> bool
-val lookup_projection : projection -> env -> projection_body
+val lookup_projection : Projection.t -> env -> projection_body
(* Inductives *)
val mind_equiv : env -> inductive -> inductive -> bool
diff --git a/checker/reduction.ml b/checker/reduction.ml
index 97255dd49..072dec63f 100644
--- a/checker/reduction.ml
+++ b/checker/reduction.ml
@@ -54,7 +54,7 @@ let compare_stack_shape stk1 stk2 =
type lft_constr_stack_elt =
Zlapp of (lift * fconstr) array
- | Zlproj of Names.projection * lift
+ | Zlproj of Names.Projection.t * lift
| Zlfix of (lift * fconstr) * lft_constr_stack
| Zlcase of case_info * lift * fconstr * fconstr array
and lft_constr_stack = lft_constr_stack_elt list
@@ -142,7 +142,7 @@ let compare_stacks f fmind lft1 stk1 lft2 stk2 =
| (Zlfix(fx1,a1),Zlfix(fx2,a2)) ->
f fx1 fx2; cmp_rec a1 a2
| (Zlproj (c1,l1),Zlproj (c2,l2)) ->
- if not (Names.eq_con_chk
+ if not (Names.Constant.UserOrd.equal
(Names.Projection.constant c1)
(Names.Projection.constant c2)) then
raise NotConvertible
diff --git a/checker/subtyping.ml b/checker/subtyping.ml
index ee73eb1ab..5cb38cb81 100644
--- a/checker/subtyping.ml
+++ b/checker/subtyping.ml
@@ -224,7 +224,7 @@ let check_inductive env mp1 l info1 mib2 spec2 subst1 subst2=
| Some None, Some None -> true
| Some (Some (id1,p1,pb1)), Some (Some (id2,p2,pb2)) ->
Id.equal id1 id2 &&
- Array.for_all2 eq_con_chk p1 p2 &&
+ Array.for_all2 Constant.UserOrd.equal p1 p2 &&
Array.for_all2 eq_projection_body pb1 pb2
| _, _ -> false
in
diff --git a/checker/term.ml b/checker/term.ml
index 19034a57d..0236f7867 100644
--- a/checker/term.ml
+++ b/checker/term.ml
@@ -390,7 +390,7 @@ let compare_constr f t1 t2 =
f h1 h2 && List.for_all2 f l1 l2
else false
| Evar (e1,l1), Evar (e2,l2) -> Int.equal e1 e2 && Array.equal f l1 l2
- | Const c1, Const c2 -> eq_puniverses eq_con_chk c1 c2
+ | Const c1, Const c2 -> eq_puniverses Constant.UserOrd.equal c1 c2
| Ind c1, Ind c2 -> eq_puniverses eq_ind_chk c1 c2
| Construct ((c1,i1),u1), Construct ((c2,i2),u2) -> Int.equal i1 i2 && eq_ind_chk c1 c2
&& Univ.Instance.equal u1 u2
diff --git a/checker/values.ml b/checker/values.ml
index 160653d9b..1ac8d7cef 100644
--- a/checker/values.ml
+++ b/checker/values.ml
@@ -15,7 +15,7 @@
To ensure this file is up-to-date, 'make' now compares the md5 of cic.mli
with a copy we maintain here:
-MD5 2c3436106636784886f122c8ab578098 checker/cic.mli
+MD5 c4fdf8a846aed45c27b5acb1add7d1c6 checker/cic.mli
*)
diff --git a/clib/cArray.ml b/clib/cArray.ml
index 5eb20bc16..071f4689b 100644
--- a/clib/cArray.ml
+++ b/clib/cArray.ml
@@ -62,9 +62,12 @@ sig
val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b array -> 'c array -> 'a * 'd array
val fold_right2_map : ('a -> 'b -> 'c -> 'd * 'c) -> 'a array -> 'b array -> 'c -> 'd array * 'c
val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b array -> 'a * 'c array
+ [@@ocaml.deprecated "Same as [fold_left_map]"]
val fold_map' : ('a -> 'c -> 'b * 'c) -> 'a array -> 'c -> 'b array * 'c
+ [@@ocaml.deprecated "Same as [fold_right_map]"]
val fold_map2' :
('a -> 'b -> 'c -> 'd * 'c) -> 'a array -> 'b array -> 'c -> 'd array * 'c
+ [@@ocaml.deprecated "Same as [fold_right2_map]"]
val distinct : 'a array -> bool
val rev_of_list : 'a list -> 'a array
val rev_to_list : 'a array -> 'a list
diff --git a/clib/cArray.mli b/clib/cArray.mli
index f4f60f8aa..9c2f521f4 100644
--- a/clib/cArray.mli
+++ b/clib/cArray.mli
@@ -114,14 +114,14 @@ sig
(** Same with two arrays, folding on the left *)
val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b array -> 'a * 'c array
- (** @deprecated Same as [fold_left_map] *)
+ [@@ocaml.deprecated "Same as [fold_left_map]"]
val fold_map' : ('a -> 'c -> 'b * 'c) -> 'a array -> 'c -> 'b array * 'c
- (** @deprecated Same as [fold_right_map] *)
+ [@@ocaml.deprecated "Same as [fold_right_map]"]
val fold_map2' :
('a -> 'b -> 'c -> 'd * 'c) -> 'a array -> 'b array -> 'c -> 'd array * 'c
- (** @deprecated Same as [fold_right2_map] *)
+ [@@ocaml.deprecated "Same as [fold_right2_map]"]
val distinct : 'a array -> bool
(** Return [true] if every element of the array is unique (for default
diff --git a/clib/cList.ml b/clib/cList.ml
index 80bb18477..8727f4696 100644
--- a/clib/cList.ml
+++ b/clib/cList.ml
@@ -102,7 +102,9 @@ sig
val fold_left3_map : ('a -> 'b -> 'c -> 'd -> 'a * 'e) -> 'a -> 'b list -> 'c list -> 'd list -> 'a * 'e list
val fold_left4_map : ('a -> 'b -> 'c -> 'd -> 'e -> 'a * 'r) -> 'a -> 'b list -> 'c list -> 'd list -> 'e list -> 'a * 'r list
val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
+ [@@ocaml.deprecated "Same as [fold_left_map]"]
val fold_map' : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
+ [@@ocaml.deprecated "Same as [fold_right_map]"]
val map_assoc : ('a -> 'b) -> ('c * 'a) list -> ('c * 'b) list
val assoc_f : 'a eq -> 'a -> ('a * 'b) list -> 'b
val remove_assoc_f : 'a eq -> 'a -> ('a * 'b) list -> ('a * 'b) list
diff --git a/clib/cList.mli b/clib/cList.mli
index db37050aa..fd6d6a158 100644
--- a/clib/cList.mli
+++ b/clib/cList.mli
@@ -228,11 +228,10 @@ sig
(** Same with four lists, folding on the left *)
val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
- (* [@@ocaml.deprecated "Same as [fold_left_map]"] *)
- (** @deprecated Same as [fold_left_map] *)
+ [@@ocaml.deprecated "Same as [fold_left_map]"]
val fold_map' : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
- (** @deprecated Same as [fold_right_map] *)
+ [@@ocaml.deprecated "Same as [fold_right_map]"]
val map_assoc : ('a -> 'b) -> ('c * 'a) list -> ('c * 'b) list
val assoc_f : 'a eq -> 'a -> ('a * 'b) list -> 'b
diff --git a/clib/option.mli b/clib/option.mli
index 67b42268a..14fa9da38 100644
--- a/clib/option.mli
+++ b/clib/option.mli
@@ -98,6 +98,7 @@ val fold_right_map : ('b -> 'a -> 'c * 'a) -> 'b option -> 'a -> 'c option * 'a
(** @deprecated Same as [fold_left_map] *)
val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b option -> 'a * 'c option
+[@@ocaml.deprecated "Same as [fold_left_map]"]
(** [cata f e x] is [e] if [x] is [None] and [f a] if [x] is [Some a] *)
val cata : ('a -> 'b) -> 'b -> 'a option -> 'b
diff --git a/configure.ml b/configure.ml
index 6c052b63b..d4750700b 100644
--- a/configure.ml
+++ b/configure.ml
@@ -21,11 +21,18 @@ let distributed_exec = ["coqtop";"coqc";"coqchk";"coqdoc";"coqworkmgr";
let verbose = ref false (* for debugging this script *)
+let red, yellow, reset =
+ if Unix.isatty Unix.stdout && Unix.isatty Unix.stderr && Sys.os_type = "Unix"
+ then "\027[31m", "\027[33m", "\027[0m"
+ else "", "", ""
+
(** * Utility functions *)
let cfprintf oc = kfprintf (fun oc -> fprintf oc "\n%!") oc
let cprintf s = cfprintf stdout s
let ceprintf s = cfprintf stderr s
-let die msg = ceprintf "%s\nConfiguration script failed!" msg; exit 1
+let die msg = ceprintf "%s%s%s\nConfiguration script failed!" red msg reset; exit 1
+
+let warn s = cprintf ("%sWarning: " ^^ s ^^ "%s") yellow reset
let s2i = int_of_string
let i2s = string_of_int
@@ -109,7 +116,7 @@ let run ?(fatal=true) ?(err=StdErr) prog args =
let cmd = String.concat " " (prog::args) in
let exn = match e with Failure s -> s | _ -> Printexc.to_string e in
let msg = sprintf "Error while running '%s' (%s)" cmd exn in
- if fatal then die msg else (cprintf "W: %s" msg; "", [])
+ if fatal then die msg else (warn "%s" msg; "", [])
let tryrun prog args = run ~fatal:false ~err:DevNull prog args
@@ -205,7 +212,7 @@ let win_aware_quote_executable str =
sprintf "%S" str
else
let _ = if contains_suspicious_characters str then
- cprintf "*Warning* The string %S contains suspicious characters; ocamlfind might fail" str in
+ warn "The string %S contains suspicious characters; ocamlfind might fail" str in
Str.global_replace (Str.regexp "\\\\") "/" str
(** * Date *)
@@ -414,8 +421,8 @@ let args_options = Arg.align [
" Do not add debugging information in the Coq executables";
"-profiling", arg_set (fun p profile -> { p with profile }),
" Add profiling information in the Coq executables";
- "-annotate", Arg.Unit (fun () -> cprintf "*Warning* -annotate is deprecated. Please use -annot or -bin-annot instead."),
- " Deprecated. Please use -annot or -bin-annot instead";
+ "-annotate", Arg.Unit (fun () -> die "-annotate has been removed. Please use -annot or -bin-annot instead."),
+ " Removed option. Please use -annot or -bin-annot instead";
"-annot", arg_set (fun p annot -> { p with annot }),
" Dumps ml text annotation files while compiling Coq (e.g. for Tuareg)";
"-bin-annot", arg_set (fun p bin_annot -> { p with bin_annot }),
@@ -598,7 +605,7 @@ let check_caml_version () =
else
let () = cprintf "Your version of OCaml is %s." caml_version in
if !prefs.force_caml_version then
- cprintf "*Warning* Your version of OCaml is outdated."
+ warn "Your version of OCaml is outdated."
else
die "You need OCaml 4.02.1 or later."
@@ -620,7 +627,7 @@ let check_findlib_version () =
else
let () = cprintf "Your version of OCamlfind is %s." findlib_version in
if !prefs.force_findlib_version then
- cprintf "*Warning* Your version of OCamlfind is outdated."
+ warn "Your version of OCamlfind is outdated."
else
die "You need OCamlfind 1.4.1 or later."
@@ -731,17 +738,17 @@ let camlp5libdir = shorten_camllib fullcamlp5libdir
(** * Native compiler *)
-let msg_byteonly () =
- cprintf "Only the bytecode version of Coq will be available."
+let msg_byteonly =
+ "Only the bytecode version of Coq will be available."
let msg_no_ocamlopt () =
- cprintf "Cannot find the OCaml native-code compiler."; msg_byteonly ()
+ warn "Cannot find the OCaml native-code compiler.\n%s" msg_byteonly
let msg_no_camlp5_cmxa () =
- cprintf "Cannot find the native-code library of camlp5."; msg_byteonly ()
+ warn "Cannot find the native-code library of camlp5.\n%s" msg_byteonly
let msg_no_dynlink_cmxa () =
- cprintf "Cannot find native-code dynlink library."; msg_byteonly ();
+ warn "Cannot find native-code dynlink library.\n%s" msg_byteonly;
cprintf "For building a native-code Coq, you may try to first";
cprintf "compile and install a dummy dynlink.cmxa (see dev/dynlink.ml)";
cprintf "and then run ./configure -natdynlink no"
@@ -757,8 +764,7 @@ let check_native () =
else
let () =
if version <> caml_version then
- cprintf
- "Warning: Native and bytecode compilers do not have the same version!"
+ warn "Native and bytecode compilers do not have the same version!"
in cprintf "You have native-code compilation. Good!"
let best_compiler =
@@ -813,7 +819,7 @@ let get_source = function
(** Is some location a suitable LablGtk2 installation ? *)
let check_lablgtkdir ?(fatal=false) src dir =
- let yell msg = if fatal then die msg else (cprintf "%s" msg; false) in
+ let yell msg = if fatal then die msg else (warn "%s" msg; false) in
let msg = get_source src in
if not (dir_exists dir) then
yell (sprintf "No such directory '%s' (%s)." dir msg)
@@ -849,7 +855,7 @@ let get_lablgtkdir () =
let check_lablgtk_version src dir = match src with
| Manual | Stdlib ->
- cprintf "Warning: could not check the version of lablgtk2.\nMake sure your version is at least 2.18.3.";
+ warn "Could not check the version of lablgtk2.\nMake sure your version is at least 2.18.3.";
(true, "an unknown version")
| OCamlFind ->
let v, _ = tryrun camlexec.find ["query"; "-format"; "%v"; "lablgtk2"] in
@@ -860,7 +866,11 @@ let check_lablgtk_version src dir = match src with
else if vi < [2; 18; 3] then
begin
(* Version 2.18.3 is known to report incorrectly as 2.18.0, and Launchpad packages report as version 2.16.0 due to a misconfigured META file; see https://bugs.launchpad.net/ubuntu/+source/lablgtk2/+bug/1577236 *)
- cprintf "Warning: Your installed lablgtk reports as %s.\n It is possible that the installed version is actually more recent\n but reports an incorrect version. If the installed version is\n actually more recent than 2.18.3, that's fine; if it is not,\n CoqIDE will compile but may be very unstable." v;
+ warn "Your installed lablgtk reports as %s.\n\
+It is possible that the installed version is actually more recent\n\
+but reports an incorrect version. If the installed version is\n\
+actually more recent than 2.18.3, that's fine; if it is not,\n
+CoqIDE will compile but may be very unstable." v;
(true, "an unknown version")
end
else
@@ -1212,7 +1222,7 @@ let write_configml f =
let core_src_dirs = [ "config"; "dev"; "lib"; "clib"; "kernel"; "library";
"engine"; "pretyping"; "interp"; "parsing"; "proofs";
- "tactics"; "toplevel"; "printing"; "intf";
+ "tactics"; "toplevel"; "printing";
"grammar"; "ide"; "stm"; "vernac" ] in
let core_src_dirs = List.fold_left (fun acc core_src_subdir -> acc ^ " \"" ^ core_src_subdir ^ "\";\n")
""
@@ -1237,17 +1247,6 @@ let write_configml f =
let _ = write_configml "config/coq_config.ml"
-(** * Symlinks or copies for the checker *)
-
-let _ =
- let prog, args, prf =
- if arch = "win32" then "cp", [], ""
- else "ln", ["-s"], "../" in
- List.iter (fun file ->
- ignore(run "rm" ["-f"; "checker/"^file]);
- ignore(run ~fatal:true prog (args @ [prf^"kernel/"^file;"checker/"^file])))
- [ "esubst.ml"; "esubst.mli"; "names.ml"; "names.mli" ]
-
(** * Build the config/Makefile file *)
let write_makefile f =
diff --git a/default.nix b/default.nix
index 26c6e4b90..effee720d 100644
--- a/default.nix
+++ b/default.nix
@@ -32,6 +32,7 @@
}:
with pkgs;
+with stdenv.lib;
stdenv.mkDerivation rec {
@@ -61,8 +62,7 @@ stdenv.mkDerivation rec {
] else []) ++ (if doCheck then
# Test-suite dependencies
- let inherit (stdenv.lib) versionAtLeast optional; in
- /* ncurses is required to build an OCaml REPL */
+ # ncurses is required to build an OCaml REPL
optional (!versionAtLeast ocaml.version "4.07") ncurses
++ [
python
@@ -90,6 +90,10 @@ stdenv.mkDerivation rec {
prefixKey = "-prefix ";
+ buildFlags = [ "world" ] ++ optional buildDoc "doc-html";
+
+ installTargets = [ "install" ] ++ optional buildDoc "install-doc-html";
+
inherit doCheck;
}
diff --git a/dev/base_include b/dev/base_include
index e76044f41..2f7183dd6 100644
--- a/dev/base_include
+++ b/dev/base_include
@@ -15,7 +15,6 @@
#directory "tactics";;
#directory "printing";;
#directory "grammar";;
-#directory "intf";;
#directory "stm";;
#directory "vernac";;
diff --git a/dev/build/windows/makecoq_mingw.sh b/dev/build/windows/makecoq_mingw.sh
index 18f1a2f16..3608f7305 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 #####################
@@ -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/ci/README.md b/dev/ci/README.md
index bb13587e9..87f03aa99 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,38 @@ 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. 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 +111,29 @@ 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
----------------------------
-
-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
----------------------------
+Advanced GitLab CI 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.
diff --git a/dev/ci/ci-basic-overlay.sh b/dev/ci/ci-basic-overlay.sh
index 48e01e9e9..b7faea13e 100644..100755
--- a/dev/ci/ci-basic-overlay.sh
+++ b/dev/ci/ci-basic-overlay.sh
@@ -19,13 +19,13 @@
: "${UniMath_CI_GITURL:=https://github.com/UniMath/UniMath.git}"
########################################################################
-# Unicoq + Metacoq
+# Unicoq + Mtac2
########################################################################
: "${unicoq_CI_BRANCH:=master}"
: "${unicoq_CI_GITURL:=https://github.com/unicoq/unicoq.git}"
-: "${metacoq_CI_BRANCH:=master}"
-: "${metacoq_CI_GITURL:=https://github.com/MetaCoq/MetaCoq.git}"
+: "${mtac2_CI_BRANCH:=master-sync}"
+: "${mtac2_CI_GITURL:=https://github.com/Mtac2/Mtac2.git}"
########################################################################
# Mathclasses + Corn
@@ -91,6 +91,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}"
@@ -142,7 +148,7 @@
########################################################################
# Equations
########################################################################
-: "${Equations_CI_BRANCH:=8.8+alpha}"
+: "${Equations_CI_BRANCH:=master}"
: "${Equations_CI_GITURL:=https://github.com/mattam82/Coq-Equations.git}"
########################################################################
@@ -150,3 +156,15 @@
########################################################################
: "${Elpi_CI_BRANCH:=coq-master}"
: "${Elpi_CI_GITURL:=https://github.com/LPCIC/coq-elpi.git}"
+
+########################################################################
+# fcsl-pcm
+########################################################################
+: "${fcsl_pcm_CI_BRANCH:=master}"
+: "${fcsl_pcm_CI_GITURL:=https://github.com/imdea-software/fcsl-pcm.git}"
+
+########################################################################
+# pidetop
+########################################################################
+: "${pidetop_CI_BRANCH:=v8.9}"
+: "${pidetop_CI_GITURL:=https://bitbucket.org/coqpide/pidetop.git}"
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-fcsl-pcm.sh b/dev/ci/ci-fcsl-pcm.sh
new file mode 100755
index 000000000..fdc4c729b
--- /dev/null
+++ b/dev/ci/ci-fcsl-pcm.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+ci_dir="$(dirname "$0")"
+. "${ci_dir}/ci-common.sh"
+
+fcsl_pcm_CI_DIR="${CI_BUILD_DIR}/fcsl-pcm"
+
+install_ssreflect
+
+git_checkout "${fcsl_pcm_CI_BRANCH}" "${fcsl_pcm_CI_GITURL}" "${fcsl_pcm_CI_DIR}"
+
+( cd "${fcsl_pcm_CI_DIR}" && make )
diff --git a/dev/ci/ci-fiat-crypto.sh b/dev/ci/ci-fiat-crypto.sh
index 6c8dce5bd..845addb4c 100755
--- a/dev/ci/ci-fiat-crypto.sh
+++ b/dev/ci/ci-fiat-crypto.sh
@@ -8,4 +8,4 @@ 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 )
+( cd "${fiat_crypto_CI_DIR}" && make lite lite-display )
diff --git a/dev/ci/ci-iris-lambda-rust.sh b/dev/ci/ci-iris-lambda-rust.sh
index b019fa059..1af0f634c 100755
--- a/dev/ci/ci-iris-lambda-rust.sh
+++ b/dev/ci/ci-iris-lambda-rust.sh
@@ -9,27 +9,20 @@ lambdaRust_CI_DIR="${CI_BUILD_DIR}/lambdaRust"
install_ssreflect
-# Add or update the opam repo we need for dependency resolution
-opam repo add iris-dev https://gitlab.mpi-sws.org/FP/opam-dev.git -p 0 || opam update iris-dev
-
# Setup lambdaRust first
git_checkout "${lambdaRust_CI_BRANCH}" "${lambdaRust_CI_GITURL}" "${lambdaRust_CI_DIR}"
# Extract required version of Iris
-Iris_VERSION=$(grep -F coq-iris < "${lambdaRust_CI_DIR}/opam" | grep -E 'dev\.([0-9.-]+)' -o)
-Iris_URL=$(opam show "coq-iris.$Iris_VERSION" -f upstream-url)
-read -r -a Iris_URL_PARTS <<< "$(echo "$Iris_URL" | tr '#' ' ')"
+Iris_SHA=$(grep -F coq-iris < "${lambdaRust_CI_DIR}/opam" | sed 's/.*"dev\.[0-9.-]\+\.\([0-9a-z]\+\)".*/\1/')
# Setup Iris
-git_checkout "${Iris_CI_BRANCH}" "${Iris_URL_PARTS[0]}" "${Iris_CI_DIR}" "${Iris_URL_PARTS[1]}"
+git_checkout "${Iris_CI_BRANCH}" "${Iris_CI_GITURL}" "${Iris_CI_DIR}" "${Iris_SHA}"
# Extract required version of std++
-stdpp_VERSION=$(grep -F coq-stdpp < "${Iris_CI_DIR}/opam" | grep -E 'dev\.([0-9.-]+)' -o)
-stdpp_URL=$(opam show "coq-stdpp.$stdpp_VERSION" -f upstream-url)
-read -r -a stdpp_URL_PARTS <<< "$(echo "$stdpp_URL" | tr '#' ' ')"
+stdpp_SHA=$(grep -F coq-stdpp < "${Iris_CI_DIR}/opam" | sed 's/.*"dev\.[0-9.-]\+\.\([0-9a-z]\+\)".*/\1/')
# Setup std++
-git_checkout "${stdpp_CI_BRANCH}" "${stdpp_URL_PARTS[0]}" "${stdpp_CI_DIR}" "${stdpp_URL_PARTS[1]}"
+git_checkout "${stdpp_CI_BRANCH}" "${stdpp_CI_GITURL}" "${stdpp_CI_DIR}" "${stdpp_SHA}"
# Build std++
( cd "${stdpp_CI_DIR}" && make && make install )
diff --git a/dev/ci/ci-metacoq.sh b/dev/ci/ci-mtac2.sh
index a66dc1e76..1372acb8e 100755
--- a/dev/ci/ci-metacoq.sh
+++ b/dev/ci/ci-mtac2.sh
@@ -4,7 +4,7 @@ ci_dir="$(dirname "$0")"
. "${ci_dir}/ci-common.sh"
unicoq_CI_DIR=${CI_BUILD_DIR}/unicoq
-metacoq_CI_DIR=${CI_BUILD_DIR}/MetaCoq
+mtac2_CI_DIR=${CI_BUILD_DIR}/Mtac2
# Setup UniCoq
@@ -14,6 +14,6 @@ git_checkout "${unicoq_CI_BRANCH}" "${unicoq_CI_GITURL}" "${unicoq_CI_DIR}"
# Setup MetaCoq
-git_checkout "${metacoq_CI_BRANCH}" "${metacoq_CI_GITURL}" "${metacoq_CI_DIR}"
+git_checkout "${mtac2_CI_BRANCH}" "${mtac2_CI_GITURL}" "${mtac2_CI_DIR}"
-( cd "${metacoq_CI_DIR}" && coq_makefile -f _CoqProject -o Makefile && make )
+( cd "${mtac2_CI_DIR}" && coq_makefile -f _CoqProject -o Makefile && make )
diff --git a/dev/ci/ci-pidetop.sh b/dev/ci/ci-pidetop.sh
new file mode 100755
index 000000000..d04b9637c
--- /dev/null
+++ b/dev/ci/ci-pidetop.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+# $0 is not the safest way, but...
+ci_dir="$(dirname "$0")"
+. "${ci_dir}/ci-common.sh"
+
+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 )
+
+echo -en '4\nexit' | coqtop -main-channel stdfds -toploop pidetop
diff --git a/dev/ci/ci-vst.sh b/dev/ci/ci-vst.sh
index 3c0044bfe..79001c547 100755
--- a/dev/ci/ci-vst.sh
+++ b/dev/ci/ci-vst.sh
@@ -8,6 +8,6 @@ VST_CI_DIR="${CI_BUILD_DIR}/VST"
# opam install -j ${NJOBS} -y menhir
git_checkout "${VST_CI_BRANCH}" "${VST_CI_GITURL}" "${VST_CI_DIR}"
-# Targets are: msl veric floyd progs , we remove progs to save time
-# Patch to avoid the upper version limit
-( cd "${VST_CI_DIR}" && make IGNORECOQVERSION=true .loadpath version.vo msl veric floyd )
+# 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 )
diff --git a/dev/ci/docker/README.md b/dev/ci/docker/README.md
new file mode 100644
index 000000000..8e677f6f2
--- /dev/null
+++ b/dev/ci/docker/README.md
@@ -0,0 +1,65 @@
+## 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`
+
+Autobuild is the preferred build method [see below]; if you are a
+member of the `coqci` organization, the automated build will push the
+image to the `coqci/name:$VERSION` tag using a Docker hub hook.
+
+## Updating the Image and Syncronization with CI files
+
+Unfortunately, at this point some manual synchronization is needed
+between the `Dockerfile` and `.gitlab-ci.yml`. In particular, the
+checklist is:
+
+- check the name and version of the image setup in `hooks/post_push`
+ have to match.
+- check `COMPILER` variables do match.
+
+Once you are sure the variables are right, then proceed to trigger an
+autobuild or do a manual build, et voilà !
+
+## Docker Autobuilding.
+
+We provide basic support for auto-building, see:
+
+https://docs.docker.com/docker-cloud/builds/advanced/
+
+If you are member of the `coqci` Docker organization, trigger an
+autobuild in your account and the image will be pushed to it as we
+set the proper tag in `hooks/post_push`.
+
+We still need to figure out how properly setup a more automated,
+organization-wide auto-building process.
+
+## 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`
+
+Now your docker image is ready to be used. To upload to `coqci`:
+- `docker tag base:$VERSION coqci/base:$VERSION`
+- `docker push coqci/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;
+- Learn more about Docker registry for GITLAB https://gitlab.com/coq/coq/container_registry .
diff --git a/dev/ci/docker/bionic_coq/Dockerfile b/dev/ci/docker/bionic_coq/Dockerfile
new file mode 100644
index 000000000..689d203a1
--- /dev/null
+++ b/dev/ci/docker/bionic_coq/Dockerfile
@@ -0,0 +1,46 @@
+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/docker/bionic_coq/hooks/post_push b/dev/ci/docker/bionic_coq/hooks/post_push
new file mode 100755
index 000000000..307680aa5
--- /dev/null
+++ b/dev/ci/docker/bionic_coq/hooks/post_push
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+
+COQCI_VERSION=V2018-05-07-V2
+docker tag $IMAGE_NAME $DOCKER_REPO:$COQCI_VERSION
+docker push $DOCKER_REPO:$COQCI_VERSION
+
+docker tag $IMAGE_NAME coqci/base:$COQCI_VERSION
+docker push coqci/base:$COQCI_VERSION
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/06454-ejgallego-evar+strict_to_constr.sh b/dev/ci/user-overlays/06454-ejgallego-evar+strict_to_constr.sh
new file mode 100644
index 000000000..f4cb71cf1
--- /dev/null
+++ b/dev/ci/user-overlays/06454-ejgallego-evar+strict_to_constr.sh
@@ -0,0 +1,8 @@
+if [ "$CI_PULL_REQUEST" = "6454" ] || [ "$CI_BRANCH" = "evar+strict_to_constr" ]; then
+
+ # ltac2_CI_BRANCH=econstr+more_fix
+ # ltac2_CI_GITURL=https://github.com/ejgallego/ltac2
+
+ Equations_CI_BRANCH=evar+strict_to_constr
+ Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
+fi
diff --git a/dev/ci/user-overlays/07136-evar-map-econstr.sh b/dev/ci/user-overlays/07136-evar-map-econstr.sh
new file mode 100644
index 000000000..06aa62726
--- /dev/null
+++ b/dev/ci/user-overlays/07136-evar-map-econstr.sh
@@ -0,0 +1,7 @@
+if [ "$CI_PULL_REQUEST" = "7136" ] || [ "$CI_BRANCH" = "evar-map-econstr" ]; then
+ Equations_CI_BRANCH=8.9+alpha
+ Equations_CI_GITURL=https://github.com/SkySkimmer/Coq-Equations.git
+
+ Elpi_CI_BRANCH=coq-7136
+ Elpi_CI_GITURL=https://github.com/SkySkimmer/coq-elpi.git
+fi
diff --git a/dev/ci/user-overlays/07152-ejgallego-api+vernac_expr_iso.sh b/dev/ci/user-overlays/07152-ejgallego-api+vernac_expr_iso.sh
new file mode 100644
index 000000000..7e554684e
--- /dev/null
+++ b/dev/ci/user-overlays/07152-ejgallego-api+vernac_expr_iso.sh
@@ -0,0 +1,12 @@
+if [ "$CI_PULL_REQUEST" = "7152" ] || [ "$CI_BRANCH" = "api+vernac_expr_iso" ]; then
+
+ # Equations_CI_BRANCH=ssr+correct_packing
+ # Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
+
+ # ltac2_CI_BRANCH=ssr+correct_packing
+ # ltac2_CI_GITURL=https://github.com/ejgallego/ltac2
+
+ Elpi_CI_BRANCH=api+vernac_expr_iso
+ Elpi_CI_GITURL=https://github.com/ejgallego/coq-elpi.git
+
+fi
diff --git a/dev/core.dbg b/dev/core.dbg
index 57c136900..edf67020a 100644
--- a/dev/core.dbg
+++ b/dev/core.dbg
@@ -16,5 +16,4 @@ load_printer tactics.cma
load_printer vernac.cma
load_printer stm.cma
load_printer toplevel.cma
-load_printer intf.cma
load_printer ltac_plugin.cmo
diff --git a/dev/doc/MERGING.md b/dev/doc/MERGING.md
index 3a2df6a81..84ff94c66 100644
--- a/dev/doc/MERGING.md
+++ b/dev/doc/MERGING.md
@@ -70,7 +70,7 @@ To merge the PR proceed in the following way
```
$ git checkout master
$ git pull
-$ dev/tools/merge-pr XXXX
+$ dev/tools/merge-pr.sh XXXX
$ git push upstream
```
where `XXXX` is the number of the PR to be merged and `upstream` is the name
diff --git a/dev/doc/changes.md b/dev/doc/changes.md
index ab78b0956..6d7c0d368 100644
--- a/dev/doc/changes.md
+++ b/dev/doc/changes.md
@@ -1,3 +1,27 @@
+## Changes between Coq 8.8 and Coq 8.9
+
+### ML API
+
+Proof engine
+
+- More functions have been changed to use `EConstr`, notably the
+ functions in `Evd`, and in particular `Evd.define`.
+
+ Note that the core function `EConstr.to_constr` now _enforces_ by
+ default that the resulting term is ground, that is to say, free of
+ Evars. This is usually what you want, as open terms should be of
+ type `EConstr.t` to benefit from the invariants the `EConstr` API is
+ meant to guarantee.
+
+ In case you'd like to violate this API invariant, you can use the
+ `abort_on_undefined_evars` flag to `EConstr.to_constr`, but note
+ that setting this flag to false is deprecated so it is only meant to
+ be used as to help port pre-EConstr code.
+
+- A few type alias have been deprecated, in all cases the message
+ should indicate what the canonical form is. An important change is
+ the move of `Globnames.global_reference` to `Names.GlobRef.t`.
+
## Changes between Coq 8.7 and Coq 8.8
### Bug tracker
@@ -74,6 +98,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/doc/coq-src-description.txt b/dev/doc/coq-src-description.txt
index b3d49b7e5..764d48295 100644
--- a/dev/doc/coq-src-description.txt
+++ b/dev/doc/coq-src-description.txt
@@ -17,12 +17,6 @@ toplevel
Special components
------------------
-intf :
-
- Contains mli-only interfaces, many of them providing a.s.t.
- used for dialog bewteen coq components. Ex: Constrexpr.constr_expr
- produced by parsing and transformed by interp.
-
grammar :
Camlp5 syntax extensions. The file grammar/grammar.cma is used
diff --git a/dev/doc/debugging.md b/dev/doc/debugging.md
index fd3cbd1bc..14a1cc693 100644
--- a/dev/doc/debugging.md
+++ b/dev/doc/debugging.md
@@ -47,7 +47,7 @@ Debugging with ocamldebug from Emacs
7. some hints:
- To debug a failure/error/anomaly, add a breakpoint in
- Vernac.vernac_com at the with clause of the "try ... interp com
+ `Vernac.interp_vernac` (in `toplevel/vernac.ml`) at the with clause of the "try ... interp com
with ..." block, then go "back" a few steps to find where the
failure/error/anomaly has been raised
- Alternatively, for an error or an anomaly, add breakpoints in the middle
diff --git a/dev/ocamldebug-coq.run b/dev/ocamldebug-coq.run
index f3e60edea..8f1c165dd 100644
--- a/dev/ocamldebug-coq.run
+++ b/dev/ocamldebug-coq.run
@@ -18,7 +18,7 @@ exec $OCAMLDEBUG \
-I $CAMLP5LIB -I +threads \
-I $COQTOP \
-I $COQTOP/config -I $COQTOP/printing -I $COQTOP/grammar -I $COQTOP/clib \
- -I $COQTOP/lib -I $COQTOP/intf -I $COQTOP/kernel -I $COQTOP/kernel/byterun \
+ -I $COQTOP/lib -I $COQTOP/kernel -I $COQTOP/kernel/byterun \
-I $COQTOP/library -I $COQTOP/engine \
-I $COQTOP/pretyping -I $COQTOP/parsing -I $COQTOP/vernac \
-I $COQTOP/interp -I $COQTOP/proofs -I $COQTOP/tactics -I $COQTOP/stm \
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..9dd12087a 100644
--- a/dev/tools/coqdev.el
+++ b/dev/tools/coqdev.el
@@ -103,5 +103,17 @@ 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)
+
(provide 'coqdev)
;;; coqdev ends here
diff --git a/dev/tools/merge-pr.sh b/dev/tools/merge-pr.sh
index 1c94f630f..00d04e6b3 100755
--- a/dev/tools/merge-pr.sh
+++ b/dev/tools/merge-pr.sh
@@ -5,7 +5,7 @@ set -o pipefail
API=https://api.github.com/repos/coq/coq
OFFICIAL_REMOTE_GIT_URL="git@github.com:coq/coq"
-OFFICIAL_REMOTE_HTTPS_URL="https://github.com/coq/coq"
+OFFICIAL_REMOTE_HTTPS_URL="github.com/coq/coq"
# This script depends (at least) on git (>= 2.7) and jq.
# It should be used like this: dev/tools/merge-pr.sh /PR number/
@@ -91,8 +91,10 @@ fi
REMOTE_URL=$(git remote get-url "$REMOTE" --all)
if [ "$REMOTE_URL" != "${OFFICIAL_REMOTE_GIT_URL}" ] && \
[ "$REMOTE_URL" != "${OFFICIAL_REMOTE_GIT_URL}.git" ] && \
- [ "$REMOTE_URL" != "${OFFICIAL_REMOTE_HTTPS_URL}" ] && \
- [ "$REMOTE_URL" != "${OFFICIAL_REMOTE_HTTPS_URL}.git" ]; then
+ [ "$REMOTE_URL" != "https://${OFFICIAL_REMOTE_HTTPS_URL}" ] && \
+ [ "$REMOTE_URL" != "https://${OFFICIAL_REMOTE_HTTPS_URL}.git" ] && \
+ [[ "$REMOTE_URL" != "https://"*"@${OFFICIAL_REMOTE_HTTPS_URL}" ]] && \
+ [[ "$REMOTE_URL" != "https://"*"@${OFFICIAL_REMOTE_HTTPS_URL}.git" ]] ; then
error "remote ${BLUE}$REMOTE${RESET} does not point to the official Coq repo"
error "that is ${BLUE}$OFFICIAL_REMOTE_GIT_URL"
error "it points to ${BLUE}$REMOTE_URL${RESET} instead"
diff --git a/dev/tools/pre-commit b/dev/tools/pre-commit
index a514b8866..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.)"
@@ -27,8 +27,8 @@ then
# reset work tree and index
# NB: untracked files which were not added are untouched
- git apply --cached -R "$index"
- git apply -R "$tree"
+ git apply --whitespace=nowarn --cached -R "$index"
+ git apply --whitespace=nowarn -R "$tree"
# Fix index
# For end of file newlines we must go through the worktree
@@ -45,7 +45,7 @@ then
# making git fail. Don't fail now: we fix the worktree first.
if [ -s "$fixed_index" ]
then
- git apply -R "$fixed_index"
+ git apply --whitespace=nowarn -R "$fixed_index"
fi
# Fix worktree
diff --git a/dev/top_printers.ml b/dev/top_printers.ml
index ba0c54407..8d5b5bef4 100644
--- a/dev/top_printers.ml
+++ b/dev/top_printers.ml
@@ -162,8 +162,8 @@ let pp_state_t n = pp (Reductionops.pr_state n)
(* proof printers *)
let pr_evar ev = Pp.int (Evar.repr ev)
let ppmetas metas = pp(Termops.pr_metaset metas)
-let ppevm evd = pp(Termops.pr_evar_map ~with_univs:!Flags.univ_print (Some 2) evd)
-let ppevmall evd = pp(Termops.pr_evar_map ~with_univs:!Flags.univ_print None evd)
+let ppevm evd = pp(Termops.pr_evar_map ~with_univs:!Detyping.print_universes (Some 2) evd)
+let ppevmall evd = pp(Termops.pr_evar_map ~with_univs:!Detyping.print_universes None evd)
let pr_existentialset evars =
prlist_with_sep spc pr_evar (Evar.Set.elements evars)
let ppexistentialset evars =
@@ -181,7 +181,7 @@ let ppproofview p =
pp(pr_enum Goal.pr_goal gls ++ fnl () ++ Termops.pr_evar_map (Some 1) sigma)
let ppopenconstr (x : Evd.open_constr) =
- let (evd,c) = x in pp (Termops.pr_evar_map (Some 2) evd ++ envpp pr_constr_env c)
+ let (evd,c) = x in pp (Termops.pr_evar_map (Some 2) evd ++ envpp pr_econstr_env c)
(* spiwack: deactivated until a replacement is found
let pppftreestate p = pp(print_pftreestate p)
*)
diff --git a/dev/top_printers.mli b/dev/top_printers.mli
index dad6dcc1c..c23ba964c 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
diff --git a/doc/LICENSE b/doc/LICENSE
index 7ae31b089..c223a4e16 100644
--- a/doc/LICENSE
+++ b/doc/LICENSE
@@ -2,15 +2,17 @@ The Coq Reference Manual is a collective work from the Coq Development
Team whose members are listed in the file CREDITS of the Coq source
package. All related documents (the LaTeX and BibTeX sources, the
embedded png files, and the PostScript, PDF and html outputs) are
-copyright (c) INRIA 1999-2006, with the exception of the Ubuntu font files
-(UbuntuMono-Square.ttf and UbuntuMono-B.ttf), derived from UbuntuMono-Regular,
-which is Copyright 2010,2011 Canonical Ltd and licensed under the Ubuntu font
+copyright (c) INRIA 1999-2006, with the exception of the Ubuntu font
+file UbuntuMono-B.ttf, which is
+Copyright 2010,2011 Canonical Ltd and licensed under the Ubuntu font
license, version 1.0
-(https://www.ubuntu.com/legal/terms-and-policies/font-licence). The material
-connected to the Reference Manual may be distributed only subject to the terms
-and conditions set forth in the Open Publication License, v1.0 or later (the
-latest version is presently available at http://www.opencontent.org/openpub/).
-Options A and B are *not* elected.
+(https://www.ubuntu.com/legal/terms-and-policies/font-licence), and its
+derivative CoqNotations.ttf distributed under the same license. The
+material connected to the Reference Manual may be distributed only
+subject to the terms and conditions set forth in the Open Publication
+License, v1.0 or later (the latest version is presently available at
+http://www.opencontent.org/openpub/). Options A and B are *not*
+elected.
The Coq Tutorial is a work by Gérard Huet, Gilles Kahn and Christine
Paulin-Mohring. All documents (the LaTeX source and the PostScript,
diff --git a/doc/RecTutorial/RecTutorial.tex b/doc/RecTutorial/RecTutorial.tex
deleted file mode 100644
index d0884be0d..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 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 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 as the current theorem, 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 4b0ab3125..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 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/refman/AddRefMan-pre.tex b/doc/refman/AddRefMan-pre.tex
deleted file mode 100644
index 856a823de..000000000
--- a/doc/refman/AddRefMan-pre.tex
+++ /dev/null
@@ -1,63 +0,0 @@
-%\coverpage{Addendum to the Reference Manual}{\ }
-%\addcontentsline{toc}{part}{Additional documentation}
-%BEGIN LATEX
-\setheaders{Presentation of the Addendum}
-%END LATEX
-\chapter*{Presentation of the Addendum}
-%HEVEA\cutname{addendum.html}
-
-Here you will find several pieces of additional documentation for the
-\Coq\ Reference Manual. Each of this chapters is concentrated on a
-particular topic, that should interest only a fraction of the \Coq\
-users: that's the reason why they are apart from the Reference
-Manual.
-
-\begin{description}
-
-\item[Extended pattern-matching] This chapter details the use of
- generalized pattern-matching. It is contributed by Cristina Cornes
- and Hugo Herbelin.
-
-\item[Implicit coercions] This chapter details the use of the coercion
- mechanism. It is contributed by Amokrane Saïbi.
-
-%\item[Proof of imperative programs] This chapter explains how to
-% prove properties of annotated programs with imperative features.
-% It is contributed by Jean-Christophe Filliâtre
-
-\item[Program extraction] This chapter explains how to extract in practice ML
- files from $\FW$ terms. It is contributed by Jean-Christophe
- Filliâtre and Pierre Letouzey.
-
-\item[Program] This chapter explains the use of the \texttt{Program}
- vernacular which allows the development of certified
- programs in \Coq. It is contributed by Matthieu Sozeau and replaces
- the previous \texttt{Program} tactic by Catherine Parent.
-
-%\item[Natural] This chapter is due to Yann Coscoy. It is the user
-% manual of the tools he wrote for printing proofs in natural
-% language. At this time, French and English languages are supported.
-
-\item[omega] \texttt{omega}, written by Pierre Crégut, solves a whole
- class of arithmetic problems.
-
-\item[The {\tt ring} tactic] This is a tactic to do AC rewriting. This
- chapter explains how to use it and how it works.
- The chapter is contributed by Patrick Loiseleur.
-
-\item[The {\tt Setoid\_replace} tactic] This is a
- tactic to do rewriting on types equipped with specific (only partially
- substitutive) equality. The chapter is contributed by Clément Renard.
-
-\item[Calling external provers] This chapter describes several tactics
- which call external provers.
-
-\end{description}
-
-\atableofcontents
-
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
diff --git a/doc/refman/RefMan-gal.tex b/doc/refman/RefMan-gal.tex
deleted file mode 100644
index 41ea0a5dc..000000000
--- a/doc/refman/RefMan-gal.tex
+++ /dev/null
@@ -1,1737 +0,0 @@
-\chapter{The \gallina{} specification language
-\label{Gallina}\index{Gallina}}
-%HEVEA\cutname{gallina.html}
-\label{BNF-syntax} % Used referred to as a chapter label
-
-This chapter describes \gallina, the specification language of {\Coq}.
-It allows developing mathematical theories and proofs of specifications
-of programs. The theories are built from axioms, hypotheses,
-parameters, lemmas, theorems and definitions of constants, functions,
-predicates and sets. The syntax of logical objects involved in
-theories is described in Section~\ref{term}. The language of
-commands, called {\em The Vernacular} is described in section
-\ref{Vernacular}.
-
-In {\Coq}, logical objects are typed to ensure their logical
-correctness. The rules implemented by the typing algorithm are described in
-Chapter \ref{Cic}.
-
-\subsection*{About the grammars in the manual
-\index{BNF metasyntax}}
-
-Grammars are presented in Backus-Naur form (BNF). Terminal symbols are
-set in {\tt typewriter font}. In addition, there are special
-notations for regular expressions.
-
-An expression enclosed in square brackets \zeroone{\ldots} means at
-most one occurrence of this expression (this corresponds to an
-optional component).
-
-The notation ``\nelist{\entry}{sep}'' stands for a non empty
-sequence of expressions parsed by {\entry} and
-separated by the literal ``{\tt sep}''\footnote{This is similar to the
-expression ``{\entry} $\{$ {\tt sep} {\entry} $\}$'' in
-standard BNF, or ``{\entry}~{$($} {\tt sep} {\entry} {$)$*}'' in
-the syntax of regular expressions.}.
-
-Similarly, the notation ``\nelist{\entry}{}'' stands for a non
-empty sequence of expressions parsed by the ``{\entry}'' entry,
-without any separator between.
-
-Finally, the notation ``\sequence{\entry}{\tt sep}'' stands for a
-possibly empty sequence of expressions parsed by the ``{\entry}'' entry,
-separated by the literal ``{\tt sep}''.
-
-\section{Lexical conventions
-\label{lexical}\index{Lexical conventions}}
-
-\paragraph{Blanks}
-Space, newline and horizontal tabulation are considered as blanks.
-Blanks are ignored but they separate tokens.
-
-\paragraph{Comments}
-
-Comments in {\Coq} are enclosed between {\tt (*} and {\tt
- *)}\index{Comments}, and can be nested. They can contain any
-character. However, string literals must be correctly closed. Comments
-are treated as blanks.
-
-\paragraph{Identifiers and access identifiers}
-
-Identifiers, written {\ident}, are sequences of letters, digits,
-\verb!_! and \verb!'!, that do not start with a digit or \verb!'!.
-That is, they are recognized by the following lexical class:
-
-\index{ident@\ident}
-\begin{center}
-\begin{tabular}{rcl}
-{\firstletter} & ::= & {\tt a..z} $\mid$ {\tt A..Z} $\mid$ {\tt \_}
-$\mid$ {\tt unicode-letter}
-\\
-{\subsequentletter} & ::= & {\tt a..z} $\mid$ {\tt A..Z} $\mid$ {\tt 0..9}
-$\mid$ {\tt \_} % $\mid$ {\tt \$}
-$\mid$ {\tt '}
-$\mid$ {\tt unicode-letter}
-$\mid$ {\tt unicode-id-part} \\
-{\ident} & ::= & {\firstletter} \sequencewithoutblank{\subsequentletter}{}
-\end{tabular}
-\end{center}
-All characters are meaningful. In particular, identifiers are
-case-sensitive. The entry {\tt unicode-letter} non-exhaustively
-includes Latin, Greek, Gothic, Cyrillic, Arabic, Hebrew, Georgian,
-Hangul, Hiragana and Katakana characters, CJK ideographs, mathematical
-letter-like symbols, hyphens, non-breaking space, {\ldots} The entry
-{\tt unicode-id-part} non-exhaustively includes symbols for prime
-letters and subscripts.
-
-Access identifiers, written {\accessident}, are identifiers prefixed
-by \verb!.! (dot) without blank. They are used in the syntax of qualified
-identifiers.
-
-\paragraph{Natural numbers and integers}
-Numerals are sequences of digits. Integers are numerals optionally preceded by a minus sign.
-
-\index{num@{\num}}
-\index{integer@{\integer}}
-\begin{center}
-\begin{tabular}{r@{\quad::=\quad}l}
-{\digit} & {\tt 0..9} \\
-{\num} & \nelistwithoutblank{\digit}{} \\
-{\integer} & \zeroone{\tt -}{\num} \\
-\end{tabular}
-\end{center}
-
-\paragraph[Strings]{Strings\label{strings}
-\index{string@{\qstring}}}
-Strings are delimited by \verb!"! (double quote), and enclose a
-sequence of any characters different from \verb!"! or the sequence
-\verb!""! to denote the double quote character. In grammars, the
-entry for quoted strings is {\qstring}.
-
-\paragraph{Keywords}
-The following identifiers are reserved keywords, and cannot be
-employed otherwise:
-\begin{center}
-\begin{tabular}{llllll}
-\verb!_! &
-\verb!as! &
-\verb!at! &
-\verb!cofix! &
-\verb!else! &
-\verb!end! \\
-%
-\verb!exists! &
-\verb!exists2! &
-\verb!fix! &
-\verb!for! &
-\verb!forall! &
-\verb!fun! \\
-%
-\verb!if! &
-\verb!IF! &
-\verb!in! &
-\verb!let! &
-\verb!match! &
-\verb!mod! \\
-%
-\verb!Prop! &
-\verb!return! &
-\verb!Set! &
-\verb!then! &
-\verb!Type! &
-\verb!using! \\
-%
-\verb!where! &
-\verb!with! &
-\end{tabular}
-\end{center}
-
-
-\paragraph{Special tokens}
-The following sequences of characters are special tokens:
-\begin{center}
-\begin{tabular}{lllllll}
-\verb/!/ &
-\verb!%! &
-\verb!&! &
-\verb!&&! &
-\verb!(! &
-\verb!()! &
-\verb!)! \\
-%
-\verb!*! &
-\verb!+! &
-\verb!++! &
-\verb!,! &
-\verb!-! &
-\verb!->! &
-\verb!.! \\
-%
-\verb!.(! &
-\verb!..! &
-\verb!/! &
-\verb!/\! &
-\verb!:! &
-\verb!::! &
-\verb!:<! \\
-%
-\verb!:=! &
-\verb!:>! &
-\verb!;! &
-\verb!<! &
-\verb!<-! &
-\verb!<->! &
-\verb!<:! \\
-%
-\verb!<=! &
-\verb!<>! &
-\verb!=! &
-\verb!=>! &
-\verb!=_D! &
-\verb!>! &
-\verb!>->! \\
-%
-\verb!>=! &
-\verb!?! &
-\verb!?=! &
-\verb!@! &
-\verb![! &
-\verb!\/! &
-\verb!]! \\
-%
-\verb!^! &
-\verb!{! &
-\verb!|! &
-\verb!|-! &
-\verb!||! &
-\verb!}! &
-\verb!~! \\
-\end{tabular}
-\end{center}
-
-Lexical ambiguities are resolved according to the ``longest match''
-rule: when a sequence of non alphanumerical characters can be decomposed
-into several different ways, then the first token is the longest
-possible one (among all tokens defined at this moment), and so on.
-
-\section{Terms \label{term}\index{Terms}}
-
-\subsection{Syntax of terms}
-
-Figures \ref{term-syntax} and \ref{term-syntax-aux} describe the basic syntax of
-the terms of the {\em Calculus of Inductive Constructions} (also
-called \CIC). The formal presentation of {\CIC} is given in Chapter
-\ref{Cic}. Extensions of this syntax are given in chapter
-\ref{Gallina-extension}. How to customize the syntax is described in Chapter
-\ref{Addoc-syntax}.
-
-\begin{figure}[htbp]
-\begin{centerframe}
-\begin{tabular}{lcl@{\quad~}r} % warning: page width exceeded with \qquad
-{\term} & ::= &
- {\tt forall} {\binders} {\tt ,} {\term} &(\ref{products})\\
- & $|$ & {\tt fun} {\binders} {\tt =>} {\term} &(\ref{abstractions})\\
- & $|$ & {\tt fix} {\fixpointbodies} &(\ref{fixpoints})\\
- & $|$ & {\tt cofix} {\cofixpointbodies} &(\ref{fixpoints})\\
- & $|$ & {\tt let} {\ident} \zeroone{\binders} {\typecstr} {\tt :=} {\term}
- {\tt in} {\term} &(\ref{let-in})\\
- & $|$ & {\tt let fix} {\fixpointbody} {\tt in} {\term} &(\ref{fixpoints})\\
- & $|$ & {\tt let cofix} {\cofixpointbody}
- {\tt in} {\term} &(\ref{fixpoints})\\
- & $|$ & {\tt let} {\tt (} \sequence{\name}{,} {\tt )} \zeroone{\ifitem}
- {\tt :=} {\term}
- {\tt in} {\term} &(\ref{caseanalysis}, \ref{Mult-match})\\
- & $|$ & {\tt let '} {\pattern} \zeroone{{\tt in} {\term}} {\tt :=} {\term}
- \zeroone{\returntype} {\tt in} {\term} & (\ref{caseanalysis}, \ref{Mult-match})\\
- & $|$ & {\tt if} {\term} \zeroone{\ifitem} {\tt then} {\term}
- {\tt else} {\term} &(\ref{caseanalysis}, \ref{Mult-match})\\
- & $|$ & {\term} {\tt :} {\term} &(\ref{typecast})\\
- & $|$ & {\term} {\tt <:} {\term} &(\ref{typecast})\\
- & $|$ & {\term} {\tt :>} &(\ref{ProgramSyntax})\\
- & $|$ & {\term} {\tt ->} {\term} &(\ref{products})\\
- & $|$ & {\term} \nelist{\termarg}{}&(\ref{applications})\\
- & $|$ & {\tt @} {\qualid} \sequence{\term}{}
- &(\ref{Implicits-explicitation})\\
- & $|$ & {\term} {\tt \%} {\ident} &(\ref{scopechange})\\
- & $|$ & {\tt match} \nelist{\caseitem}{\tt ,}
- \zeroone{\returntype} {\tt with} &\\
- && ~~~\zeroone{\zeroone{\tt |} \nelist{\eqn}{|}} {\tt end}
- &(\ref{caseanalysis})\\
- & $|$ & {\qualid} &(\ref{qualid})\\
- & $|$ & {\sort} &(\ref{Gallina-sorts})\\
- & $|$ & {\num} &(\ref{numerals})\\
- & $|$ & {\_} &(\ref{hole})\\
- & $|$ & {\tt (} {\term} {\tt )} & \\
- & & &\\
-{\termarg} & ::= & {\term} &\\
- & $|$ & {\tt (} {\ident} {\tt :=} {\term} {\tt )}
- &(\ref{Implicits-explicitation})\\
-%% & $|$ & {\tt (} {\num} {\tt :=} {\term} {\tt )}
-%% &(\ref{Implicits-explicitation})\\
-&&&\\
-{\binders} & ::= & \nelist{\binder}{} \\
-&&&\\
-{\binder} & ::= & {\name} & (\ref{Binders}) \\
- & $|$ & {\tt (} \nelist{\name}{} {\tt :} {\term} {\tt )} &\\
- & $|$ & {\tt (} {\name} {\typecstr} {\tt :=} {\term} {\tt )} &\\
- & $|$ & {\tt '} {\pattern} &\\
-& & &\\
-{\name} & ::= & {\ident} &\\
- & $|$ & {\tt \_} &\\
-&&&\\
-{\qualid} & ::= & {\ident} & \\
- & $|$ & {\qualid} {\accessident} &\\
- & & &\\
-{\sort} & ::= & {\tt Prop} ~$|$~ {\tt Set} ~$|$~ {\tt Type} &
-\end{tabular}
-\end{centerframe}
-\caption{Syntax of terms}
-\label{term-syntax}
-\index{term@{\term}}
-\index{sort@{\sort}}
-\end{figure}
-
-
-
-\begin{figure}[htb]
-\begin{centerframe}
-\begin{tabular}{lcl}
-{\fixpointbodies} & ::= &
- {\fixpointbody} \\
- & $|$ & {\fixpointbody} {\tt with} \nelist{\fixpointbody}{{\tt with}}
- {\tt for} {\ident} \\
-{\cofixpointbodies} & ::= &
- {\cofixpointbody} \\
- & $|$ & {\cofixpointbody} {\tt with} \nelist{\cofixpointbody}{{\tt with}}
- {\tt for} {\ident} \\
-&&\\
-{\fixpointbody} & ::= &
- {\ident} {\binders} \zeroone{\annotation} {\typecstr}
- {\tt :=} {\term} \\
-{\cofixpointbody} & ::= & {\ident} \zeroone{\binders} {\typecstr} {\tt :=} {\term} \\
- & &\\
-{\annotation} & ::= & {\tt \{ struct} {\ident} {\tt \}} \\
-&&\\
-{\caseitem} & ::= & {\term} \zeroone{{\tt as} \name}
- \zeroone{{\tt in} \qualid \sequence{\pattern}{}} \\
-&&\\
-{\ifitem} & ::= & \zeroone{{\tt as} {\name}} {\returntype} \\
-&&\\
-{\returntype} & ::= & {\tt return} {\term} \\
-&&\\
-{\eqn} & ::= & \nelist{\multpattern}{\tt |} {\tt =>} {\term}\\
-&&\\
-{\multpattern} & ::= & \nelist{\pattern}{\tt ,}\\
-&&\\
-{\pattern} & ::= & {\qualid} \nelist{\pattern}{} \\
- & $|$ & {\tt @} {\qualid} \nelist{\pattern}{} \\
-
- & $|$ & {\pattern} {\tt as} {\ident} \\
- & $|$ & {\pattern} {\tt \%} {\ident} \\
- & $|$ & {\qualid} \\
- & $|$ & {\tt \_} \\
- & $|$ & {\num} \\
- & $|$ & {\tt (} \nelist{\orpattern}{,} {\tt )} \\
-\\
-{\orpattern} & ::= & \nelist{\pattern}{\tt |}\\
-\end{tabular}
-\end{centerframe}
-\caption{Syntax of terms (continued)}
-\label{term-syntax-aux}
-\end{figure}
-
-
-%%%%%%%
-
-\subsection{Types}
-
-{\Coq} terms are typed. {\Coq} types are recognized by the same
-syntactic class as {\term}. We denote by {\type} the semantic subclass
-of types inside the syntactic class {\term}.
-\index{type@{\type}}
-
-
-\subsection{Qualified identifiers and simple identifiers
-\label{qualid}
-\label{ident}}
-
-{\em Qualified identifiers} ({\qualid}) denote {\em global constants}
-(definitions, lemmas, theorems, remarks or facts), {\em global
-variables} (parameters or axioms), {\em inductive
-types} or {\em constructors of inductive types}.
-{\em Simple identifiers} (or shortly {\ident}) are a
-syntactic subset of qualified identifiers. Identifiers may also
-denote local {\em variables}, what qualified identifiers do not.
-
-\subsection{Numerals
-\label{numerals}}
-
-Numerals have no definite semantics in the calculus. They are mere
-notations that can be bound to objects through the notation mechanism
-(see Chapter~\ref{Addoc-syntax} for details). Initially, numerals are
-bound to Peano's representation of natural numbers
-(see~\ref{libnats}).
-
-Note: negative integers are not at the same level as {\num}, for this
-would make precedence unnatural.
-
-\subsection{Sorts
-\index{Sorts}
-\index{Type@{\Type}}
-\index{Set@{\Set}}
-\index{Prop@{\Prop}}
-\index{Sorts}
-\label{Gallina-sorts}}
-
-There are three sorts \Set, \Prop\ and \Type.
-\begin{itemize}
-\item \Prop\ is the universe of {\em logical propositions}.
-The logical propositions themselves are typing the proofs.
-We denote propositions by {\form}. This constitutes a semantic
-subclass of the syntactic class {\term}.
-\index{form@{\form}}
-\item \Set\ is is the universe of {\em program
-types} or {\em specifications}.
-The specifications themselves are typing the programs.
-We denote specifications by {\specif}. This constitutes a semantic
-subclass of the syntactic class {\term}.
-\index{specif@{\specif}}
-\item {\Type} is the type of {\Set} and {\Prop}
-\end{itemize}
-\noindent More on sorts can be found in Section~\ref{Sorts}.
-
-\subsection{Binders
-\label{Binders}
-\index{binders}}
-
-Various constructions such as {\tt fun}, {\tt forall}, {\tt fix} and
-{\tt cofix} {\em bind} variables. A binding is represented by an
-identifier. If the binding variable is not used in the expression, the
-identifier can be replaced by the symbol {\tt \_}. When the type of a
-bound variable cannot be synthesized by the system, it can be
-specified with the notation {\tt (}\,{\ident}\,{\tt :}\,{\type}\,{\tt
-)}. There is also a notation for a sequence of binding variables
-sharing the same type: {\tt (}\,{\ident$_1$}\ldots{\ident$_n$}\,{\tt
-:}\,{\type}\,{\tt )}. A binder can also be any pattern prefixed by a quote,
-e.g. {\tt '(x,y)}.
-
-Some constructions allow the binding of a variable to value. This is
-called a ``let-binder''. The entry {\binder} of the grammar accepts
-either an assumption binder as defined above or a let-binder.
-The notation in the
-latter case is {\tt (}\,{\ident}\,{\tt :=}\,{\term}\,{\tt )}. In a
-let-binder, only one variable can be introduced at the same
-time. It is also possible to give the type of the variable as follows:
-{\tt (}\,{\ident}\,{\tt :}\,{\term}\,{\tt :=}\,{\term}\,{\tt )}.
-
-Lists of {\binder} are allowed. In the case of {\tt fun} and {\tt
- forall}, it is intended that at least one binder of the list is an
-assumption otherwise {\tt fun} and {\tt forall} gets identical. Moreover,
-parentheses can be omitted in the case of a single sequence of
-bindings sharing the same type (e.g.: {\tt fun~(x~y~z~:~A)~=>~t} can
-be shortened in {\tt fun~x~y~z~:~A~=>~t}).
-
-\subsection{Abstractions
-\label{abstractions}
-\index{abstractions}}
-\index{fun@{{\tt fun \ldots => \ldots}}}
-
-The expression ``{\tt fun} {\ident} {\tt :} {\type} {\tt =>}~{\term}''
-defines the {\em abstraction} of the variable {\ident}, of type
-{\type}, over the term {\term}. It denotes a function of the variable
-{\ident} that evaluates to the expression {\term} (e.g. {\tt fun x:$A$
-=> x} denotes the identity function on type $A$).
-% The variable {\ident} is called the {\em parameter} of the function
-% (we sometimes say the {\em formal parameter}).
-The keyword {\tt fun} can be followed by several binders as given in
-Section~\ref{Binders}. Functions over several variables are
-equivalent to an iteration of one-variable functions. For instance the
-expression ``{\tt fun}~{\ident$_{1}$}~{\ldots}~{\ident$_{n}$}~{\tt
-:}~\type~{\tt =>}~{\term}'' denotes the same function as ``{\tt
-fun}~{\ident$_{1}$}~{\tt :}~\type~{\tt =>}~{\ldots}~{\tt
-fun}~{\ident$_{n}$}~{\tt :}~\type~{\tt =>}~{\term}''. If a let-binder
-occurs in the list of binders, it is expanded to a let-in definition
-(see Section~\ref{let-in}).
-
-\subsection{Products
-\label{products}
-\index{products}}
-\index{forall@{{\tt forall \ldots, \ldots}}}
-
-The expression ``{\tt forall}~{\ident}~{\tt :}~{\type}{\tt
-,}~{\term}'' denotes the {\em product} of the variable {\ident} of
-type {\type}, over the term {\term}. As for abstractions, {\tt forall}
-is followed by a binder list, and products over several variables are
-equivalent to an iteration of one-variable products.
-Note that {\term} is intended to be a type.
-
-If the variable {\ident} occurs in {\term}, the product is called {\em
-dependent product}. The intention behind a dependent product {\tt
-forall}~$x$~{\tt :}~{$A$}{\tt ,}~{$B$} is twofold. It denotes either
-the universal quantification of the variable $x$ of type $A$ in the
-proposition $B$ or the functional dependent product from $A$ to $B$ (a
-construction usually written $\Pi_{x:A}.B$ in set theory).
-
-Non dependent product types have a special notation: ``$A$ {\tt ->}
-$B$'' stands for ``{\tt forall \_:}$A${\tt ,}~$B$''. The {\em non dependent
-product} is used both to denote the propositional implication and
-function types.
-
-\subsection{Applications
-\label{applications}
-\index{applications}}
-
-The expression \term$_0$ \term$_1$ denotes the application of
-\term$_0$ to \term$_1$.
-
-The expression {\tt }\term$_0$ \term$_1$ ... \term$_n${\tt}
-denotes the application of the term \term$_0$ to the arguments
-\term$_1$ ... then \term$_n$. It is equivalent to {\tt (} {\ldots}
-{\tt (} {\term$_0$} {\term$_1$} {\tt )} {\ldots} {\tt )} {\term$_n$} {\tt }:
-associativity is to the left.
-
-The notation {\tt (}\,{\ident}\,{\tt :=}\,{\term}\,{\tt )} for
-arguments is used for making explicit the value of implicit arguments
-(see Section~\ref{Implicits-explicitation}).
-
-\subsection{Type cast
-\label{typecast}
-\index{Cast}}
-\index{cast@{{\tt(\ldots: \ldots)}}}
-
-The expression ``{\term}~{\tt :}~{\type}'' is a type cast
-expression. It enforces the type of {\term} to be {\type}.
-
-``{\term}~{\tt <:}~{\type}'' locally sets up the virtual machine for checking
-that {\term} has type {\type}.
-
-\subsection{Inferable subterms
-\label{hole}
-\index{\_}}
-
-Expressions often contain redundant pieces of information. Subterms that
-can be automatically inferred by {\Coq} can be replaced by the
-symbol ``\_'' and {\Coq} will guess the missing piece of information.
-
-\subsection{Let-in definitions
-\label{let-in}
-\index{Let-in definitions}
-\index{let-in}}
-\index{let@{{\tt let \ldots := \ldots in \ldots}}}
-
-
-{\tt let}~{\ident}~{\tt :=}~{\term$_1$}~{\tt in}~{\term$_2$} denotes
-the local binding of \term$_1$ to the variable $\ident$ in
-\term$_2$.
-There is a syntactic sugar for let-in definition of functions: {\tt
-let} {\ident} {\binder$_1$} {\ldots} {\binder$_n$} {\tt :=} {\term$_1$}
-{\tt in} {\term$_2$} stands for {\tt let} {\ident} {\tt := fun}
-{\binder$_1$} {\ldots} {\binder$_n$} {\tt =>} {\term$_1$} {\tt in}
-{\term$_2$}.
-
-\subsection{Definition by case analysis
-\label{caseanalysis}
-\index{match@{\tt match\ldots with\ldots end}}}
-
-Objects of inductive types can be destructurated by a case-analysis
-construction called {\em pattern-matching} expression. A
-pattern-matching expression is used to analyze the structure of an
-inductive objects and to apply specific treatments accordingly.
-
-This paragraph describes the basic form of pattern-matching. See
-Section~\ref{Mult-match} and Chapter~\ref{Mult-match-full} for the
-description of the general form. The basic form of pattern-matching is
-characterized by a single {\caseitem} expression, a {\multpattern}
-restricted to a single {\pattern} and {\pattern} restricted to the
-form {\qualid} \nelist{\ident}{}.
-
-The expression {\tt match} {\term$_0$} {\returntype} {\tt with}
-{\pattern$_1$} {\tt =>} {\term$_1$} {\tt $|$} {\ldots} {\tt $|$}
-{\pattern$_n$} {\tt =>} {\term$_n$} {\tt end}, denotes a {\em
-pattern-matching} over the term {\term$_0$} (expected to be of an
-inductive type $I$). The terms {\term$_1$}\ldots{\term$_n$} are the
-{\em branches} of the pattern-matching expression. Each of
-{\pattern$_i$} has a form \qualid~\nelist{\ident}{} where {\qualid}
-must denote a constructor. There should be exactly one branch for
-every constructor of $I$.
-
-The {\returntype} expresses the type returned by the whole {\tt match}
-expression. There are several cases. In the {\em non dependent} case,
-all branches have the same type, and the {\returntype} is the common
-type of branches. In this case, {\returntype} can usually be omitted
-as it can be inferred from the type of the branches\footnote{Except if
-the inductive type is empty in which case there is no equation that can be
-used to infer the return type.}.
-
-In the {\em dependent} case, there are three subcases. In the first
-subcase, the type in each branch may depend on the exact value being
-matched in the branch. In this case, the whole pattern-matching itself
-depends on the term being matched. This dependency of the term being
-matched in the return type is expressed with an ``{\tt as {\ident}}''
-clause where {\ident} is dependent in the return type.
-For instance, in the following example:
-\begin{coq_example*}
-Inductive bool : Type := true : bool | false : bool.
-Inductive eq (A:Type) (x:A) : A -> Prop := eq_refl : eq A x x.
-Inductive or (A:Prop) (B:Prop) : Prop :=
-| or_introl : A -> or A B
-| or_intror : B -> or A B.
-Definition bool_case (b:bool) : or (eq bool b true) (eq bool b false)
-:= match b as x return or (eq bool x true) (eq bool x false) with
- | true => or_introl (eq bool true true) (eq bool true false)
- (eq_refl bool true)
- | false => or_intror (eq bool false true) (eq bool false false)
- (eq_refl bool false)
- end.
-\end{coq_example*}
-the branches have respective types {\tt or (eq bool true true) (eq
-bool true false)} and {\tt or (eq bool false true) (eq bool false
-false)} while the whole pattern-matching expression has type {\tt or
-(eq bool b true) (eq bool b false)}, the identifier {\tt x} being used
-to represent the dependency. Remark that when the term being matched
-is a variable, the {\tt as} clause can be omitted and the term being
-matched can serve itself as binding name in the return type. For
-instance, the following alternative definition is accepted and has the
-same meaning as the previous one.
-\begin{coq_eval}
-Reset bool_case.
-\end{coq_eval}
-\begin{coq_example*}
-Definition bool_case (b:bool) : or (eq bool b true) (eq bool b false)
-:= match b return or (eq bool b true) (eq bool b false) with
- | true => or_introl (eq bool true true) (eq bool true false)
- (eq_refl bool true)
- | false => or_intror (eq bool false true) (eq bool false false)
- (eq_refl bool false)
- end.
-\end{coq_example*}
-
-The second subcase is only relevant for annotated inductive types such
-as the equality predicate (see Section~\ref{Equality}), the order
-predicate on natural numbers % (see Section~\ref{le}) % undefined reference
-or the type of
-lists of a given length (see Section~\ref{listn}). In this configuration,
-the type of each branch can depend on the type dependencies specific
-to the branch and the whole pattern-matching expression has a type
-determined by the specific dependencies in the type of the term being
-matched. This dependency of the return type in the annotations of the
-inductive type is expressed using a
- ``in~I~\_~$\ldots$~\_~\pattern$_1$~$\ldots$~\pattern$_n$'' clause, where
-\begin{itemize}
-\item $I$ is the inductive type of the term being matched;
-
-\item the {\_}'s are matching the parameters of the inductive type:
-the return type is not dependent on them.
-
-\item the \pattern$_i$'s are matching the annotations of the inductive
- type: the return type is dependent on them
-
-\item in the basic case which we describe below, each \pattern$_i$ is a
- name \ident$_i$; see \ref{match-in-patterns} for the general case
-
-\end{itemize}
-
-For instance, in the following example:
-\begin{coq_example*}
-Definition eq_sym (A:Type) (x y:A) (H:eq A x y) : eq A y x :=
- match H in eq _ _ z return eq A z x with
- | eq_refl _ _ => eq_refl A x
- end.
-\end{coq_example*}
-the type of the branch has type {\tt eq~A~x~x} because the third
-argument of {\tt eq} is {\tt x} in the type of the pattern {\tt
-refl\_equal}. On the contrary, the type of the whole pattern-matching
-expression has type {\tt eq~A~y~x} because the third argument of {\tt
-eq} is {\tt y} in the type of {\tt H}. This dependency of the case
-analysis in the third argument of {\tt eq} is expressed by the
-identifier {\tt z} in the return type.
-
-Finally, the third subcase is a combination of the first and second
-subcase. In particular, it only applies to pattern-matching on terms
-in a type with annotations. For this third subcase, both
-the clauses {\tt as} and {\tt in} are available.
-
-There are specific notations for case analysis on types with one or
-two constructors: ``{\tt if {\ldots} then {\ldots} else {\ldots}}''
-and ``{\tt let (}\nelist{\ldots}{,}{\tt ) := } {\ldots} {\tt in}
-{\ldots}'' (see Sections~\ref{if-then-else} and~\ref{Letin}).
-
-%\SeeAlso Section~\ref{Mult-match} for convenient extensions of pattern-matching.
-
-\subsection{Recursive functions
-\label{fixpoints}
-\index{fix@{fix \ident$_i$\{\dots\}}}}
-
-The expression ``{\tt fix} \ident$_1$ \binder$_1$ {\tt :} {\type$_1$}
-\texttt{:=} \term$_1$ {\tt with} {\ldots} {\tt with} \ident$_n$
-\binder$_n$~{\tt :} {\type$_n$} \texttt{:=} \term$_n$ {\tt for}
-{\ident$_i$}'' denotes the $i$\nth component of a block of functions
-defined by mutual well-founded recursion. It is the local counterpart
-of the {\tt Fixpoint} command. See Section~\ref{Fixpoint} for more
-details. When $n=1$, the ``{\tt for}~{\ident$_i$}'' clause is omitted.
-
-The expression ``{\tt cofix} \ident$_1$~\binder$_1$ {\tt :}
-{\type$_1$} {\tt with} {\ldots} {\tt with} \ident$_n$ \binder$_n$ {\tt
-:} {\type$_n$}~{\tt for} {\ident$_i$}'' denotes the $i$\nth component of
-a block of terms defined by a mutual guarded co-recursion. It is the
-local counterpart of the {\tt CoFixpoint} command. See
-Section~\ref{CoFixpoint} for more details. When $n=1$, the ``{\tt
-for}~{\ident$_i$}'' clause is omitted.
-
-The association of a single fixpoint and a local
-definition have a special syntax: ``{\tt let fix}~$f$~{\ldots}~{\tt
- :=}~{\ldots}~{\tt in}~{\ldots}'' stands for ``{\tt let}~$f$~{\tt :=
- fix}~$f$~\ldots~{\tt :=}~{\ldots}~{\tt in}~{\ldots}''. The same
- applies for co-fixpoints.
-
-
-\section{The Vernacular
-\label{Vernacular}}
-
-\begin{figure}[tbp]
-\begin{centerframe}
-\begin{tabular}{lcl}
-{\sentence} & ::= & {\assumption} \\
- & $|$ & {\definition} \\
- & $|$ & {\inductive} \\
- & $|$ & {\fixpoint} \\
- & $|$ & {\assertion} {\proof} \\
-&&\\
-%% Assumptions
-{\assumption} & ::= & {\assumptionkeyword} {\assums} {\tt .} \\
-&&\\
-{\assumptionkeyword} & $\!\!$ ::= & {\tt Axiom} $|$ {\tt Conjecture} \\
- & $|$ & {\tt Parameter} $|$ {\tt Parameters} \\
- & $|$ & {\tt Variable} $|$ {\tt Variables} \\
- & $|$ & {\tt Hypothesis} $|$ {\tt Hypotheses}\\
-&&\\
-{\assums} & ::= & \nelist{\ident}{} {\tt :} {\term} \\
- & $|$ & \nelist{{\tt (} \nelist{\ident}{} {\tt :} {\term} {\tt )}}{} \\
-&&\\
-%% Definitions
-{\definition} & ::= &
- \zeroone{\tt Local} {\tt Definition} {\ident} \zeroone{\binders} {\typecstr} {\tt :=} {\term} {\tt .} \\
- & $|$ & {\tt Let} {\ident} \zeroone{\binders} {\typecstr} {\tt :=} {\term} {\tt .} \\
-&&\\
-%% Inductives
-{\inductive} & ::= &
- {\tt Inductive} \nelist{\inductivebody}{with} {\tt .} \\
- & $|$ & {\tt CoInductive} \nelist{\inductivebody}{with} {\tt .} \\
- & & \\
-{\inductivebody} & ::= &
- {\ident} \zeroone{\binders} {\typecstr} {\tt :=} \\
- && ~~\zeroone{\zeroone{\tt |} \nelist{$\!${\ident}$\!$ \zeroone{\binders} {\typecstr}}{|}} \\
- & & \\ %% TODO: where ...
-%% Fixpoints
-{\fixpoint} & ::= & {\tt Fixpoint} \nelist{\fixpointbody}{with} {\tt .} \\
- & $|$ & {\tt CoFixpoint} \nelist{\cofixpointbody}{with} {\tt .} \\
-&&\\
-%% Lemmas & proofs
-{\assertion} & ::= &
- {\statkwd} {\ident} \zeroone{\binders} {\tt :} {\term} {\tt .} \\
-&&\\
- {\statkwd} & ::= & {\tt Theorem} $|$ {\tt Lemma} \\
- & $|$ & {\tt Remark} $|$ {\tt Fact}\\
- & $|$ & {\tt Corollary} $|$ {\tt Proposition} \\
- & $|$ & {\tt Definition} $|$ {\tt Example} \\\\
-&&\\
-{\proof} & ::= & {\tt Proof} {\tt .} {\dots} {\tt Qed} {\tt .}\\
- & $|$ & {\tt Proof} {\tt .} {\dots} {\tt Defined} {\tt .}\\
- & $|$ & {\tt Proof} {\tt .} {\dots} {\tt Admitted} {\tt .}\\
-\end{tabular}
-\end{centerframe}
-\caption{Syntax of sentences}
-\label{sentences-syntax}
-\end{figure}
-
-Figure \ref{sentences-syntax} describes {\em The Vernacular} which is the
-language of commands of \gallina. A sentence of the vernacular
-language, like in many natural languages, begins with a capital letter
-and ends with a dot.
-
-The different kinds of command are described hereafter. They all suppose
-that the terms occurring in the sentences are well-typed.
-
-%%
-%% Axioms and Parameters
-%%
-\subsection{Assumptions
-\index{Declarations}
-\label{Declarations}}
-
-Assumptions extend the environment\index{Environment} with axioms,
-parameters, hypotheses or variables. An assumption binds an {\ident}
-to a {\type}. It is accepted by {\Coq} if and only if this {\type} is
-a correct type in the environment preexisting the declaration and if
-{\ident} was not previously defined in the same module. This {\type}
-is considered to be the type (or specification, or statement) assumed
-by {\ident} and we say that {\ident} has type {\type}.
-
-\subsubsection{{\tt Axiom {\ident} :{\term} .}
-\comindex{Axiom}
-\label{Axiom}}
-
-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 postulate.
-
-\begin{ErrMsgs}
-\item \errindex{{\ident} already exists}
-\end{ErrMsgs}
-
-\begin{Variants}
-\item \comindex{Parameter}\comindex{Parameters}
- {\tt Parameter {\ident} :{\term}.} \\
- Is equivalent to {\tt Axiom {\ident} : {\term}}
-
-\item {\tt Parameter {\ident$_1$} {\ldots} {\ident$_n$} {\tt :}{\term}.}\\
- Adds $n$ parameters with specification {\term}
-
-\item
- {\tt Parameter\,%
-(\,{\ident$_{1,1}$} {\ldots} {\ident$_{1,k_1}$}\,{\tt :}\,{\term$_1$} {\tt )}\;%
-\ldots\;{\tt (}\,{\ident$_{n,1}$}{\ldots}{\ident$_{n,k_n}$}\,{\tt :}\,%
-{\term$_n$} {\tt )}.}\\
- Adds $n$ blocks of parameters with different specifications.
-
-\item {\tt Local Axiom {\ident} : {\term}.}\\
-\comindex{Local Axiom}
- Such axioms are never made accessible through their unqualified name by
- {\tt Import} and its variants (see \ref{Import}). You have to explicitly
- give their fully qualified name to refer to them.
-
-\item \comindex{Conjecture}
- {\tt Conjecture {\ident} :{\term}.}\\
- Is equivalent to {\tt Axiom {\ident} : {\term}}.
-\end{Variants}
-
-\noindent {\bf Remark: } It is possible to replace {\tt Parameter} by
-{\tt Parameters}.
-
-
-\subsubsection{{\tt Variable {\ident} :{\term}}.
-\comindex{Variable}
-\comindex{Variables}
-\label{Variable}}
-
-This command links {\term} to the name {\ident} in the context of the
-current section (see Section~\ref{Section} for a description of the section
-mechanism). When the current section is closed, name {\ident} will be
-unknown and every object using this variable will be explicitly
-parametrized (the variable is {\em discharged}). Using the {\tt
-Variable} command out of any section is equivalent to using {\tt
-Local Parameter}.
-
-\begin{ErrMsgs}
-\item \errindex{{\ident} already exists}
-\end{ErrMsgs}
-
-\begin{Variants}
-\item {\tt Variable {\ident$_1$} {\ldots} {\ident$_n$} {\tt :}{\term}.}\\
- Links {\term} to names {\ident$_1$} {\ldots} {\ident$_n$}.
-\item
- {\tt Variable\,%
-(\,{\ident$_{1,1}$} {\ldots} {\ident$_{1,k_1}$}\,{\tt :}\,{\term$_1$} {\tt )}\;%
-\ldots\;{\tt (}\,{\ident$_{n,1}$} {\ldots}{\ident$_{n,k_n}$}\,{\tt :}\,%
-{\term$_n$} {\tt )}.}\\
- Adds $n$ blocks of variables with different specifications.
-\item \comindex{Hypothesis}
- \comindex{Hypotheses}
- {\tt Hypothesis {\ident} {\tt :}{\term}.} \\
- \texttt{Hypothesis} is a synonymous of \texttt{Variable}
-\end{Variants}
-
-\noindent {\bf Remark: } It is possible to replace {\tt Variable} by
-{\tt Variables} and {\tt Hypothesis} by {\tt Hypotheses}.
-
-It is advised to use the keywords \verb:Axiom: and \verb:Hypothesis:
-for logical postulates (i.e. when the assertion {\term} is of sort
-\verb:Prop:), and to use the keywords \verb:Parameter: and
-\verb:Variable: in other cases (corresponding to the declaration of an
-abstract mathematical entity).
-
-%%
-%% Definitions
-%%
-\subsection{Definitions
-\index{Definitions}
-\label{Basic-definitions}}
-
-Definitions extend the environment\index{Environment} with
-associations of names to terms. A definition can be seen as a way to
-give a meaning to a name or as a way to abbreviate a term. In any
-case, the name can later be replaced at any time by its definition.
-
-The operation of unfolding a name into its definition is called
-$\delta$-conversion\index{delta-reduction@$\delta$-reduction} (see
-Section~\ref{delta}). A definition is accepted by the system if and
-only if the defined term is well-typed in the current context of the
-definition and if the name is not already used. The name defined by
-the definition is called a {\em constant}\index{Constant} and the term
-it refers to is its {\em body}. A definition has a type which is the
-type of its body.
-
-A formal presentation of constants and environments is given in
-Section~\ref{Typed-terms}.
-
-\subsubsection{\tt Definition {\ident} := {\term}.
-\label{Definition}
-\comindex{Definition}}
-
-This command binds {\term} to the name {\ident} in the
-environment, provided that {\term} is well-typed.
-
-\begin{ErrMsgs}
-\item \errindex{{\ident} already exists}
-\end{ErrMsgs}
-
-\begin{Variants}
-\item {\tt Definition} {\ident} {\tt :} {\term$_1$} {\tt :=} {\term$_2$}{\tt .}\\
- It checks that the type of {\term$_2$} is definitionally equal to
- {\term$_1$}, and registers {\ident} as being of type {\term$_1$},
- and bound to value {\term$_2$}.
-\item {\tt Definition} {\ident} {\binder$_1$} {\ldots} {\binder$_n$}
- {\tt :} \term$_1$ {\tt :=} {\term$_2$}{\tt .}\\
- This is equivalent to \\
- {\tt Definition} {\ident} {\tt : forall}%
- {\binder$_1$} {\ldots} {\binder$_n$}{\tt ,}\,\term$_1$\,{\tt :=}\,%
- {\tt fun}\,{\binder$_1$} {\ldots} {\binder$_n$}\,{\tt =>}\,{\term$_2$}\,%
- {\tt .}
-
-\item {\tt Local Definition {\ident} := {\term}.}\\
-\comindex{Local Definition}
- Such definitions are never made accessible through their unqualified name by
- {\tt Import} and its variants (see \ref{Import}). You have to explicitly
- give their fully qualified name to refer to them.
-\item {\tt Example {\ident} := {\term}.}\\
-{\tt Example} {\ident} {\tt :} {\term$_1$} {\tt :=} {\term$_2$}{\tt .}\\
-{\tt Example} {\ident} {\binder$_1$} {\ldots} {\binder$_n$}
- {\tt :} {\term$_1$} {\tt :=} {\term$_2$}{\tt .}\\
-\comindex{Example}
-These are synonyms of the {\tt Definition} forms.
-\end{Variants}
-
-\begin{ErrMsgs}
-\item \errindex{The term {\term} has type {\type} while it is expected to have type {\type}}
-\end{ErrMsgs}
-
-\SeeAlso Sections \ref{Opaque}, \ref{Transparent}, \ref{unfold}.
-
-\subsubsection{\tt Let {\ident} := {\term}.
-\comindex{Let}}
-
-This command binds the value {\term} to the name {\ident} in the
-environment of the current section. The name {\ident} disappears
-when the current section is eventually closed, and, all
-persistent objects (such as theorems) defined within the
-section and depending on {\ident} are prefixed by the let-in definition
-{\tt let {\ident} := {\term} in}. Using the {\tt
-Let} command out of any section is equivalent to using {\tt
-Local Definition}.
-
-\begin{ErrMsgs}
-\item \errindex{{\ident} already exists}
-\end{ErrMsgs}
-
-\begin{Variants}
-\item {\tt Let {\ident} : {\term$_1$} := {\term$_2$}.}
-\item {\tt Let Fixpoint {\ident} \nelist{\fixpointbody}{with} {\tt .}.}
-\item {\tt Let CoFixpoint {\ident} \nelist{\cofixpointbody}{with} {\tt .}.}
-\end{Variants}
-
-\SeeAlso Sections \ref{Section} (section mechanism), \ref{Opaque},
-\ref{Transparent} (opaque/transparent constants), \ref{unfold} (tactic
- {\tt unfold}).
-
-%%
-%% Inductive Types
-%%
-\subsection{Inductive definitions
-\index{Inductive definitions}
-\label{gal-Inductive-Definitions}
-\comindex{Inductive}
-\label{Inductive}
-\comindex{Variant}
-\label{Variant}}
-
-We gradually explain simple inductive types, simple
-annotated inductive types, simple parametric inductive types,
-mutually inductive types. We explain also co-inductive types.
-
-\subsubsection{Simple inductive types}
-
-The definition of a simple inductive type has the following form:
-
-\medskip
-\begin{tabular}{l}
-{\tt Inductive} {\ident} {\tt :} {\sort} {\tt :=} \\
-\begin{tabular}{clcl}
- & {\ident$_1$} & {\tt :} & {\type$_1$} \\
- {\tt |} & {\ldots} && \\
- {\tt |} & {\ident$_n$} & {\tt :} & {\type$_n$} \\
-\end{tabular}
-\end{tabular}
-\medskip
-
-The name {\ident} is the name of the inductively defined type and
-{\sort} is the universes where it lives.
-The names {\ident$_1$}, {\ldots}, {\ident$_n$}
-are the names of its constructors and {\type$_1$}, {\ldots},
-{\type$_n$} their respective types. The types of the constructors have
-to satisfy a {\em positivity condition} (see Section~\ref{Positivity})
-for {\ident}. This condition ensures the soundness of the inductive
-definition. If this is the case, the names {\ident},
-{\ident$_1$}, {\ldots}, {\ident$_n$} are added to the environment with
-their respective types. Accordingly to the universe where
-the inductive type lives ({\it e.g.} its type {\sort}), {\Coq} provides a
-number of destructors for {\ident}. Destructors are named
-{\ident}{\tt\_ind}, {\ident}{\tt \_rec} or {\ident}{\tt \_rect} which
-respectively correspond to elimination principles on {\tt Prop}, {\tt
-Set} and {\tt Type}. The type of the destructors expresses structural
-induction/recursion principles over objects of {\ident}. We give below
-two examples of the use of the {\tt Inductive} definitions.
-
-The set of natural numbers is defined as:
-\begin{coq_example}
-Inductive nat : Set :=
- | O : nat
- | S : nat -> nat.
-\end{coq_example}
-
-The type {\tt nat} is defined as the least \verb:Set: containing {\tt
- O} and closed by the {\tt S} constructor. The names {\tt nat},
-{\tt O} and {\tt S} are added to the environment.
-
-Now let us have a look at the elimination principles. They are three
-of them:
-{\tt nat\_ind}, {\tt nat\_rec} and {\tt nat\_rect}. The type of {\tt
- nat\_ind} is:
-\begin{coq_example}
-Check nat_ind.
-\end{coq_example}
-
-This is the well known structural induction principle over natural
-numbers, i.e. the second-order form of Peano's induction principle.
-It allows proving some universal property of natural numbers ({\tt
-forall n:nat, P n}) by induction on {\tt n}.
-
-The types of {\tt nat\_rec} and {\tt nat\_rect} are similar, except
-that they pertain to {\tt (P:nat->Set)} and {\tt (P:nat->Type)}
-respectively . They correspond to primitive induction principles
-(allowing dependent types) respectively over sorts \verb:Set: and
-\verb:Type:. The constant {\ident}{\tt \_ind} is always provided,
-whereas {\ident}{\tt \_rec} and {\ident}{\tt \_rect} can be impossible
-to derive (for example, when {\ident} is a proposition).
-
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-\begin{Variants}
-\item
-\begin{coq_example*}
-Inductive nat : Set := O | S (_:nat).
-\end{coq_example*}
-In the case where inductive types have no annotations (next section
-gives an example of such annotations),
-%the positivity condition implies that
-a constructor can be defined by only giving the type of
-its arguments.
-\end{Variants}
-
-\subsubsection{Simple annotated inductive types}
-
-In an annotated inductive types, the universe where the inductive
-type is defined is no longer a simple sort, but what is called an
-arity, which is a type whose conclusion is a sort.
-
-As an example of annotated inductive types, let us define the
-$even$ predicate:
-
-\begin{coq_example}
-Inductive even : nat -> Prop :=
- | even_0 : even O
- | even_SS : forall n:nat, even n -> even (S (S n)).
-\end{coq_example}
-
-The type {\tt nat->Prop} means that {\tt even} is a unary predicate
-(inductively defined) over natural numbers. The type of its two
-constructors are the defining clauses of the predicate {\tt even}. The
-type of {\tt even\_ind} is:
-
-\begin{coq_example}
-Check even_ind.
-\end{coq_example}
-
-From a mathematical point of view it asserts that the natural numbers
-satisfying the predicate {\tt even} are exactly in the smallest set of
-naturals satisfying the clauses {\tt even\_0} or {\tt even\_SS}. This
-is why, when we want to prove any predicate {\tt P} over elements of
-{\tt even}, it is enough to prove it for {\tt O} and to prove that if
-any natural number {\tt n} satisfies {\tt P} its double successor {\tt
- (S (S n))} satisfies also {\tt P}. This is indeed analogous to the
-structural induction principle we got for {\tt nat}.
-
-\begin{ErrMsgs}
-\item \errindex{Non strictly positive occurrence of {\ident} in {\type}}
-\item \errindex{The conclusion of {\type} is not valid; it must be
-built from {\ident}}
-\end{ErrMsgs}
-
-\subsubsection{Parametrized inductive types}
-In the previous example, each constructor introduces a
-different instance of the predicate {\tt even}. In some cases,
-all the constructors introduces the same generic instance of the
-inductive definition, in which case, instead of an annotation, we use
-a context of parameters which are binders shared by all the
-constructors of the definition.
-
-% Inductive types may be parameterized. Parameters differ from inductive
-% type annotations in the fact that recursive invokations of inductive
-% types must always be done with the same values of parameters as its
-% specification.
-
-The general scheme is:
-\begin{center}
-{\tt Inductive} {\ident} {\binder$_1$}\ldots{\binder$_k$} : {\term} :=
- {\ident$_1$}: {\term$_1$} | {\ldots} | {\ident$_n$}: \term$_n$
-{\tt .}
-\end{center}
-Parameters differ from inductive type annotations in the fact that the
-conclusion of each type of constructor {\term$_i$} invoke the inductive
-type with the same values of parameters as its specification.
-
-
-
-A typical example is the definition of polymorphic lists:
-\begin{coq_example*}
-Inductive list (A:Set) : Set :=
- | nil : list A
- | cons : A -> list A -> list A.
-\end{coq_example*}
-
-Note that in the type of {\tt nil} and {\tt cons}, we write {\tt
- (list A)} and not just {\tt list}.\\ The constructors {\tt nil} and
-{\tt cons} will have respectively types:
-
-\begin{coq_example}
-Check nil.
-Check cons.
-\end{coq_example}
-
-Types of destructors are also quantified with {\tt (A:Set)}.
-
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-\begin{Variants}
-\item
-\begin{coq_example*}
-Inductive list (A:Set) : Set := nil | cons (_:A) (_:list A).
-\end{coq_example*}
-This is an alternative definition of lists where we specify the
-arguments of the constructors rather than their full type.
-\item
-\begin{coq_example*}
-Variant sum (A B:Set) : Set := left : A -> sum A B | right : B -> sum A B.
-\end{coq_example*}
-The {\tt Variant} keyword is identical to the {\tt Inductive} keyword,
-except that it disallows recursive definition of types (in particular
-lists cannot be defined with the {\tt Variant} keyword). No induction
-scheme is generated for this variant, unless the option
-{\tt Nonrecursive Elimination Schemes} is set
-(see~\ref{set-nonrecursive-elimination-schemes}).
-\end{Variants}
-
-\begin{ErrMsgs}
-\item \errindex{The {\num}th argument of {\ident} must be {\ident'} in
-{\type}}
-\end{ErrMsgs}
-
-\paragraph{New from \Coq{} V8.1} The condition on parameters for
-inductive definitions has been relaxed since \Coq{} V8.1. It is now
-possible in the type of a constructor, to invoke recursively the
-inductive definition on an argument which is not the parameter itself.
-
-One can define~:
-\begin{coq_example}
-Inductive list2 (A:Set) : Set :=
- | nil2 : list2 A
- | cons2 : A -> list2 (A*A) -> list2 A.
-\end{coq_example}
-\begin{coq_eval}
-Reset list2.
-\end{coq_eval}
-that can also be written by specifying only the type of the arguments:
-\begin{coq_example*}
-Inductive list2 (A:Set) : Set := nil2 | cons2 (_:A) (_:list2 (A*A)).
-\end{coq_example*}
-But the following definition will give an error:
-\begin{coq_example}
-Fail Inductive listw (A:Set) : Set :=
- | nilw : listw (A*A)
- | consw : A -> listw (A*A) -> listw (A*A).
-\end{coq_example}
-Because the conclusion of the type of constructors should be {\tt
- listw A} in both cases.
-
-A parametrized inductive definition can be defined using
-annotations instead of parameters but it will sometimes give a
-different (bigger) sort for the inductive definition and will produce
-a less convenient rule for case elimination.
-
-\SeeAlso Sections~\ref{Cic-inductive-definitions} and~\ref{Tac-induction}.
-
-
-\subsubsection{Mutually defined inductive types
-\comindex{Inductive}
-\label{Mutual-Inductive}}
-
-The definition of a block of mutually inductive types has the form:
-
-\medskip
-{\tt
-\begin{tabular}{l}
-Inductive {\ident$_1$} : {\type$_1$} := \\
-\begin{tabular}{clcl}
- & {\ident$_1^1$} &:& {\type$_1^1$} \\
- | & {\ldots} && \\
- | & {\ident$_{n_1}^1$} &:& {\type$_{n_1}^1$}
-\end{tabular} \\
-with\\
-~{\ldots} \\
-with {\ident$_m$} : {\type$_m$} := \\
-\begin{tabular}{clcl}
- & {\ident$_1^m$} &:& {\type$_1^m$} \\
- | & {\ldots} \\
- | & {\ident$_{n_m}^m$} &:& {\type$_{n_m}^m$}.
-\end{tabular}
-\end{tabular}
-}
-\medskip
-
-\noindent It has the same semantics as the above {\tt Inductive}
-definition for each \ident$_1$, {\ldots}, \ident$_m$. All names
-\ident$_1$, {\ldots}, \ident$_m$ and \ident$_1^1$, \dots,
-\ident$_{n_m}^m$ are simultaneously added to the environment. Then
-well-typing of constructors can be checked. Each one of the
-\ident$_1$, {\ldots}, \ident$_m$ can be used on its own.
-
-It is also possible to parametrize these inductive definitions.
-However, 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:
-
-\medskip
-\begin{tabular}{l}
-{\tt Inductive} {\ident$_1$} {\params} {\tt :} {\type$_1$} {\tt :=} \\
-\begin{tabular}{clcl}
- & {\ident$_1^1$} &{\tt :}& {\type$_1^1$} \\
- {\tt |} & {\ldots} && \\
- {\tt |} & {\ident$_{n_1}^1$} &{\tt :}& {\type$_{n_1}^1$}
-\end{tabular} \\
-{\tt with}\\
-~{\ldots} \\
-{\tt with} {\ident$_m$} {\params} {\tt :} {\type$_m$} {\tt :=} \\
-\begin{tabular}{clcl}
- & {\ident$_1^m$} &{\tt :}& {\type$_1^m$} \\
- {\tt |} & {\ldots} \\
- {\tt |} & {\ident$_{n_m}^m$} &{\tt :}& {\type$_{n_m}^m$}.
-\end{tabular}
-\end{tabular}
-\medskip
-
-\Example
-The typical example of a mutual inductive data type is the one for
-trees and forests. We assume given two types $A$ and $B$ as variables.
-It can be declared the following way.
-
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-\begin{coq_example*}
-Variables A B : Set.
-Inductive tree : Set :=
- node : A -> forest -> tree
-with forest : Set :=
- | leaf : B -> forest
- | cons : tree -> forest -> forest.
-\end{coq_example*}
-
-This declaration generates automatically six induction
-principles. They are respectively
-called {\tt tree\_rec}, {\tt tree\_ind}, {\tt
- tree\_rect}, {\tt forest\_rec}, {\tt forest\_ind}, {\tt
- forest\_rect}. These ones are not the most general ones but are
-just the induction principles corresponding to each inductive part
-seen as a single inductive definition.
-
-To illustrate this point on our example, we give the types of {\tt
- tree\_rec} and {\tt forest\_rec}.
-
-\begin{coq_example}
-Check tree_rec.
-Check forest_rec.
-\end{coq_example}
-
-Assume we want to parametrize our mutual inductive definitions with
-the two type variables $A$ and $B$, the declaration should be done the
-following way:
-
-\begin{coq_eval}
-Reset tree.
-\end{coq_eval}
-\begin{coq_example*}
-Inductive tree (A B:Set) : Set :=
- node : A -> forest A B -> tree A B
-with forest (A B:Set) : Set :=
- | leaf : B -> forest A B
- | cons : tree A B -> forest A B -> forest A B.
-\end{coq_example*}
-
-Assume we define an inductive definition inside a section. When the
-section is closed, the variables declared in the section and occurring
-free in the declaration are added as parameters to the inductive
-definition.
-
-\SeeAlso Section~\ref{Section}.
-
-\subsubsection{Co-inductive types
-\label{CoInductiveTypes}
-\comindex{CoInductive}}
-
-The objects of an inductive type are well-founded with respect to the
-constructors of the type. In other words, such objects contain only a
-{\it finite} number of constructors. Co-inductive types arise from
-relaxing this condition, and admitting types whose objects contain an
-infinity of constructors. Infinite objects are introduced by a
-non-ending (but effective) process of construction, defined in terms
-of the constructors of the type.
-
-An example of a co-inductive type is the type of infinite sequences of
-natural numbers, usually called streams. It can be introduced in \Coq\
-using the \texttt{CoInductive} command:
-\begin{coq_example}
-CoInductive Stream : Set :=
- Seq : nat -> Stream -> Stream.
-\end{coq_example}
-
-The syntax of this command is the same as the command \texttt{Inductive}
-(see Section~\ref{gal-Inductive-Definitions}). Notice that no
-principle of induction is derived from the definition of a
-co-inductive type, since such principles only make sense for inductive
-ones. For co-inductive ones, the only elimination principle is case
-analysis. For example, the usual destructors on streams
-\texttt{hd:Stream->nat} and \texttt{tl:Str->Str} can be defined as
-follows:
-\begin{coq_example}
-Definition hd (x:Stream) := let (a,s) := x in a.
-Definition tl (x:Stream) := let (a,s) := x in s.
-\end{coq_example}
-
-Definition of co-inductive predicates and blocks of mutually
-co-inductive definitions are also allowed. An example of a
-co-inductive predicate is the extensional equality on streams:
-
-\begin{coq_example}
-CoInductive EqSt : Stream -> Stream -> Prop :=
- eqst :
- forall s1 s2:Stream,
- hd s1 = hd s2 -> EqSt (tl s1) (tl s2) -> EqSt s1 s2.
-\end{coq_example}
-
-In order to prove the extensionally equality of two streams $s_1$ and
-$s_2$ we have to construct an infinite proof of equality, that is,
-an infinite object of type $(\texttt{EqSt}\;s_1\;s_2)$. We will see
-how to introduce infinite objects in Section~\ref{CoFixpoint}.
-
-%%
-%% (Co-)Fixpoints
-%%
-\subsection{Definition of recursive functions}
-
-\subsubsection{Definition of functions by recursion over inductive objects}
-
-This section describes the primitive form of definition by recursion
-over inductive objects. See Section~\ref{Function} for more advanced
-constructions. The command:
-\begin{center}
- \texttt{Fixpoint {\ident} {\params} {\tt \{struct}
- \ident$_0$ {\tt \}} : type$_0$ := \term$_0$
- \comindex{Fixpoint}\label{Fixpoint}}
-\end{center}
-allows defining functions by pattern-matching over inductive objects
-using a fixed point construction.
-The meaning of this declaration is to define {\it ident} a recursive
-function with arguments specified by the binders in {\params} such
-that {\it ident} applied to arguments corresponding to these binders
-has type \type$_0$, and is equivalent to the expression \term$_0$. The
-type of the {\ident} is consequently {\tt forall {\params} {\tt,}
- \type$_0$} and the value is equivalent to {\tt fun {\params} {\tt
- =>} \term$_0$}.
-
-To be accepted, a {\tt Fixpoint} definition has to satisfy some
-syntactical constraints on a special argument called the decreasing
-argument. They are needed to ensure that the {\tt Fixpoint} definition
-always terminates. The point of the {\tt \{struct \ident {\tt \}}}
-annotation is to let the user tell the system which argument decreases
-along the recursive calls. For instance, one can define the addition
-function as :
-
-\begin{coq_example}
-Fixpoint add (n m:nat) {struct n} : nat :=
- match n with
- | O => m
- | S p => S (add p m)
- end.
-\end{coq_example}
-
-The {\tt \{struct \ident {\tt \}}} annotation may be left implicit, in
-this case the system try successively arguments from left to right
-until it finds one that satisfies the decreasing condition. Note that
-some fixpoints may have several arguments that fit as decreasing
-arguments, and this choice influences the reduction of the
-fixpoint. Hence an explicit annotation must be used if the leftmost
-decreasing argument is not the desired one. Writing explicit
-annotations can also speed up type-checking of large mutual fixpoints.
-
-The {\tt match} operator matches a value (here \verb:n:) with the
-various constructors of its (inductive) type. The remaining arguments
-give the respective values to be returned, as functions of the
-parameters of the corresponding constructor. Thus here when \verb:n:
-equals \verb:O: we return \verb:m:, and when \verb:n: equals
-\verb:(S p): we return \verb:(S (add p m)):.
-
-The {\tt match} operator is formally described
-in detail in Section~\ref{Caseexpr}. The system recognizes that in
-the inductive call {\tt (add p m)} the first argument actually
-decreases because it is a {\em pattern variable} coming from {\tt match
- n with}.
-
-\Example The following definition is not correct and generates an
-error message:
-
-\begin{coq_eval}
-Set Printing Depth 50.
-\end{coq_eval}
-% (********** The following is not correct and should produce **********)
-% (********* Error: Recursive call to wrongplus ... **********)
-\begin{coq_example}
-Fail Fixpoint wrongplus (n m:nat) {struct n} : nat :=
- match m with
- | O => n
- | S p => S (wrongplus n p)
- end.
-\end{coq_example}
-
-because the declared decreasing argument {\tt n} actually does not
-decrease in the recursive call. The function computing the addition
-over the second argument should rather be written:
-
-\begin{coq_example*}
-Fixpoint plus (n m:nat) {struct m} : nat :=
- match m with
- | O => n
- | S p => S (plus n p)
- end.
-\end{coq_example*}
-
-The ordinary match operation on natural numbers can be mimicked in the
-following way.
-\begin{coq_example*}
-Fixpoint nat_match
- (C:Set) (f0:C) (fS:nat -> C -> C) (n:nat) {struct n} : C :=
- match n with
- | O => f0
- | S p => fS p (nat_match C f0 fS p)
- end.
-\end{coq_example*}
-The recursive call may not only be on direct subterms of the recursive
-variable {\tt n} but also on a deeper subterm and we can directly
-write the function {\tt mod2} which gives the remainder modulo 2 of a
-natural number.
-\begin{coq_example*}
-Fixpoint mod2 (n:nat) : nat :=
- match n with
- | O => O
- | S p => match p with
- | O => S O
- | S q => mod2 q
- end
- end.
-\end{coq_example*}
-In order to keep the strong normalization property, the fixed point
-reduction will only be performed when the argument in position of the
-decreasing argument (which type should be in an inductive definition)
-starts with a constructor.
-
-The {\tt Fixpoint} construction enjoys also the {\tt with} extension
-to define functions over mutually defined inductive types or more
-generally any mutually recursive definitions.
-
-\begin{Variants}
-\item {\tt Fixpoint} {\ident$_1$} {\params$_1$} {\tt :} {\type$_1$} {\tt :=} {\term$_1$}\\
- {\tt with} {\ldots} \\
- {\tt with} {\ident$_m$} {\params$_m$} {\tt :} {\type$_m$} {\tt :=} {\term$_m$}\\
- Allows to define simultaneously {\ident$_1$}, {\ldots},
- {\ident$_m$}.
-\end{Variants}
-
-\Example
-The size of trees and forests can be defined the following way:
-\begin{coq_eval}
-Reset Initial.
-Variables A B : Set.
-Inductive tree : Set :=
- node : A -> forest -> tree
-with forest : Set :=
- | leaf : B -> forest
- | cons : tree -> forest -> forest.
-\end{coq_eval}
-\begin{coq_example*}
-Fixpoint tree_size (t:tree) : nat :=
- match t with
- | node a f => S (forest_size f)
- end
- with forest_size (f:forest) : nat :=
- match f with
- | leaf b => 1
- | cons t f' => (tree_size t + forest_size f')
- end.
-\end{coq_example*}
-A generic command {\tt Scheme} is useful to build automatically various
-mutual induction principles. It is described in Section~\ref{Scheme}.
-
-\subsubsection{Definitions of recursive objects in co-inductive types}
-
-The command:
-\begin{center}
- \texttt{CoFixpoint {\ident} : \type$_0$ := \term$_0$}
- \comindex{CoFixpoint}\label{CoFixpoint}
-\end{center}
-introduces a method for constructing an infinite object of a
-coinduc\-tive type. For example, the stream containing all natural
-numbers can be introduced applying the following method to the number
-\texttt{O} (see Section~\ref{CoInductiveTypes} for the definition of
-{\tt Stream}, {\tt hd} and {\tt tl}):
-\begin{coq_eval}
-Reset Initial.
-CoInductive Stream : Set :=
- Seq : nat -> Stream -> Stream.
-Definition hd (x:Stream) := match x with
- | Seq a s => a
- end.
-Definition tl (x:Stream) := match x with
- | Seq a s => s
- end.
-\end{coq_eval}
-\begin{coq_example}
-CoFixpoint from (n:nat) : Stream := Seq n (from (S n)).
-\end{coq_example}
-
-Oppositely to recursive ones, there is no decreasing argument in a
-co-recursive definition. To be admissible, a method of construction
-must provide at least one extra constructor of the infinite object for
-each iteration. A syntactical guard condition is imposed on
-co-recursive definitions in order to ensure this: each recursive call
-in the definition must be protected by at least one constructor, and
-only by constructors. That is the case in the former definition, where
-the single recursive call of \texttt{from} is guarded by an
-application of \texttt{Seq}. On the contrary, the following recursive
-function does not satisfy the guard condition:
-
-\begin{coq_eval}
-Set Printing Depth 50.
-\end{coq_eval}
-% (********** The following is not correct and should produce **********)
-% (***************** Error: Unguarded recursive call *******************)
-\begin{coq_example}
-Fail CoFixpoint filter (p:nat -> bool) (s:Stream) : Stream :=
- if p (hd s) then Seq (hd s) (filter p (tl s)) else filter p (tl s).
-\end{coq_example}
-
-The elimination of co-recursive definition is done lazily, i.e. the
-definition is expanded only when it occurs at the head of an
-application which is the argument of a case analysis expression. In
-any other context, it is considered as a canonical expression which is
-completely evaluated. We can test this using the command
-\texttt{Eval}, which computes the normal forms of a term:
-
-\begin{coq_example}
-Eval compute in (from 0).
-Eval compute in (hd (from 0)).
-Eval compute in (tl (from 0)).
-\end{coq_example}
-
-\begin{Variants}
-\item{\tt CoFixpoint {\ident$_1$} {\params} :{\type$_1$} :=
- {\term$_1$}}\\ As for most constructions, arguments of co-fixpoints
- expressions can be introduced before the {\tt :=} sign.
-\item{\tt CoFixpoint} {\ident$_1$} {\tt :} {\type$_1$} {\tt :=} {\term$_1$}\\
- {\tt with}\\
- \mbox{}\hspace{0.1cm} {\ldots} \\
- {\tt with} {\ident$_m$} {\tt :} {\type$_m$} {\tt :=} {\term$_m$}\\
-As in the \texttt{Fixpoint} command (see Section~\ref{Fixpoint}), it
-is possible to introduce a block of mutually dependent methods.
-\end{Variants}
-
-%%
-%% Theorems & Lemmas
-%%
-\subsection{Assertions and proofs}
-\label{Assertions}
-
-An assertion states a proposition (or a type) of which the proof (or
-an inhabitant of the type) is interactively built using tactics. The
-interactive proof mode is described in
-Chapter~\ref{Proof-handling} and the tactics in Chapter~\ref{Tactics}.
-The basic assertion command is:
-
-\subsubsection{\tt Theorem {\ident} \zeroone{\binders} : {\type}.
-\comindex{Theorem}}
-
-After the statement is asserted, {\Coq} needs a proof. Once a proof of
-{\type} under the assumptions represented by {\binders} is given and
-validated, the proof is generalized into a proof of {\tt forall
- \zeroone{\binders}, {\type}} and the theorem is bound to the name
-{\ident} in the environment.
-
-\begin{ErrMsgs}
-
-\item \errindex{The term {\form} has type {\ldots} which should be Set,
- Prop or Type}
-
-\item \errindexbis{{\ident} already exists}{already exists}
-
- The name you provided is already defined. You have then to choose
- another name.
-
-\end{ErrMsgs}
-
-\begin{Variants}
-\item {\tt Lemma {\ident} \zeroone{\binders} : {\type}.}\comindex{Lemma}\\
- {\tt Remark {\ident} \zeroone{\binders} : {\type}.}\comindex{Remark}\\
- {\tt Fact {\ident} \zeroone{\binders} : {\type}.}\comindex{Fact}\\
- {\tt Corollary {\ident} \zeroone{\binders} : {\type}.}\comindex{Corollary}\\
- {\tt Proposition {\ident} \zeroone{\binders} : {\type}.}\comindex{Proposition}
-
-These commands are synonyms of \texttt{Theorem {\ident} \zeroone{\binders} : {\type}}.
-
-\item {\tt Theorem \nelist{{\ident} \zeroone{\binders}: {\type}}{with}.}
-
-This command is useful for theorems that are proved by simultaneous
-induction over a mutually inductive assumption, or that assert mutually
-dependent statements in some mutual co-inductive type. It is equivalent
-to {\tt Fixpoint} or {\tt CoFixpoint}
-(see Section~\ref{CoFixpoint}) but using tactics to build the proof of
-the statements (or the body of the specification, depending on the
-point of view). The inductive or co-inductive types on which the
-induction or coinduction has to be done is assumed to be non ambiguous
-and is guessed by the system.
-
-Like in a {\tt Fixpoint} or {\tt CoFixpoint} definition, the induction
-hypotheses have to be used on {\em structurally smaller} arguments
-(for a {\tt Fixpoint}) or be {\em guarded by a constructor} (for a {\tt
- CoFixpoint}). The verification that recursive proof arguments are
-correct is done only at the time of registering the lemma in the
-environment. To know if the use of induction hypotheses is correct at
-some time of the interactive development of a proof, use the command
-{\tt Guarded} (see Section~\ref{Guarded}).
-
-The command can be used also with {\tt Lemma},
-{\tt Remark}, etc. instead of {\tt Theorem}.
-
-\item {\tt Definition {\ident} \zeroone{\binders} : {\type}.}
-
-This allows defining a term of type {\type} using the proof editing mode. It
-behaves as {\tt Theorem} but is intended to be used in conjunction with
- {\tt Defined} (see \ref{Defined}) in order to define a
- constant of which the computational behavior is relevant.
-
-The command can be used also with {\tt Example} instead
-of {\tt Definition}.
-
-\SeeAlso Sections~\ref{Opaque} and~\ref{Transparent} ({\tt Opaque}
-and {\tt Transparent}) and~\ref{unfold} (tactic {\tt unfold}).
-
-\item {\tt Let {\ident} \zeroone{\binders} : {\type}.}
-
-Like {\tt Definition {\ident} \zeroone{\binders} : {\type}.} except
-that the definition is turned into a let-in definition generalized over
-the declarations depending on it after closing the current section.
-
-\item {\tt Fixpoint \nelist{{\ident} {\binders} \zeroone{\annotation} {\typecstr} \zeroone{{\tt :=} {\term}}}{with}.}
-\comindex{Fixpoint}
-
-This generalizes the syntax of {\tt 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 {\tt
- Defined}.
-
-\item {\tt CoFixpoint \nelist{{\ident} \zeroone{\binders} {\typecstr} \zeroone{{\tt :=} {\term}}}{with}.}
-\comindex{CoFixpoint}
-
-This generalizes the syntax of {\tt CoFixpoint} so that one or more bodies
-can be defined interactively using the proof editing mode.
-
-\end{Variants}
-
-\subsubsection{{\tt Proof.} {\dots} {\tt Qed.}
-\comindex{Proof}
-\comindex{Qed}}
-
-A proof starts by the keyword {\tt 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{Proof-handling}. When
-the proof is completed it should be validated and put in the
-environment using the keyword {\tt Qed}.
-\medskip
-
-\ErrMsg
-\begin{enumerate}
-\item \errindex{{\ident} already exists}
-\end{enumerate}
-
-\begin{Remarks}
-\item Several statements can be simultaneously asserted.
-\item 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.
-\item {\tt Proof} is recommended but can currently be omitted. On the
-opposite side, {\tt Qed} (or {\tt Defined}, see below) is mandatory to
-validate a proof.
-\item Proofs ended by {\tt Qed} are declared opaque. Their content
- cannot be unfolded (see \ref{Conversion-tactics}), thus realizing
- some form of {\em proof-irrelevance}. To be able to unfold a proof,
- the proof should be ended by {\tt Defined} (see below).
-\end{Remarks}
-
-\begin{Variants}
-\item \comindex{Defined}
- {\tt Proof.} {\dots} {\tt Defined.}\\
- Same as {\tt Proof.} {\dots} {\tt 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{Conversion-tactics}, \ref{Opaque}, \ref{Transparent}).
-%Not claimed to be part of Gallina...
-%\item {\tt Proof.} {\dots} {\tt Save.}\\
-% Same as {\tt Proof.} {\dots} {\tt Qed.}
-%\item {\tt Goal} \type {\dots} {\tt Save} \ident \\
-% Same as {\tt Lemma} \ident {\tt :} \type \dots {\tt Save.}
-% This is intended to be used in the interactive mode.
-\item \comindex{Admitted}
- {\tt Proof.} {\dots} {\tt Admitted.}\\
- Turns the current asserted statement into an axiom and exits the
- proof mode.
-\end{Variants}
-
-% Local Variables:
-% mode: LaTeX
-% TeX-master: "Reference-Manual"
-% End:
-
diff --git a/doc/refman/RefMan-ltac.tex b/doc/refman/RefMan-ltac.tex
deleted file mode 100644
index 3ed697d8b..000000000
--- a/doc/refman/RefMan-ltac.tex
+++ /dev/null
@@ -1,1829 +0,0 @@
-\chapter[The tactic language]{The tactic language\label{TacticLanguage}}
-%HEVEA\cutname{ltac.html}
-
-%\geometry{a4paper,body={5in,8in}}
-
-This chapter gives a compact documentation of Ltac, the tactic
-language available in {\Coq}. We start by giving the syntax, and next,
-we present the informal semantics. If you want to know more regarding
-this language and especially about its foundations, you can refer
-to~\cite{Del00}. Chapter~\ref{Tactics-examples} is devoted to giving
-examples of use of this language on small but also with non-trivial
-problems.
-
-
-\section{Syntax}
-
-\def\tacexpr{\textrm{\textsl{expr}}}
-\def\tacexprlow{\textrm{\textsl{tacexpr$_1$}}}
-\def\tacexprinf{\textrm{\textsl{tacexpr$_2$}}}
-\def\tacexprpref{\textrm{\textsl{tacexpr$_3$}}}
-\def\atom{\textrm{\textsl{atom}}}
-%%\def\recclause{\textrm{\textsl{rec\_clause}}}
-\def\letclause{\textrm{\textsl{let\_clause}}}
-\def\matchrule{\textrm{\textsl{match\_rule}}}
-\def\contextrule{\textrm{\textsl{context\_rule}}}
-\def\contexthyp{\textrm{\textsl{context\_hyp}}}
-\def\tacarg{\nterm{tacarg}}
-\def\cpattern{\nterm{cpattern}}
-\def\selector{\textrm{\textsl{selector}}}
-\def\toplevelselector{\textrm{\textsl{toplevel\_selector}}}
-
-The syntax of the tactic language is given Figures~\ref{ltac}
-and~\ref{ltac-aux}. See Chapter~\ref{BNF-syntax} for a description of
-the BNF metasyntax used in these grammar rules. Various already
-defined entries will be used in this chapter: entries
-{\naturalnumber}, {\integer}, {\ident}, {\qualid}, {\term},
-{\cpattern} and {\atomictac} represent respectively the natural and
-integer numbers, the authorized identificators and qualified names,
-{\Coq}'s terms and patterns and all the atomic tactics described in
-Chapter~\ref{Tactics}. The syntax of {\cpattern} is the same as that
-of terms, but it is extended with pattern matching metavariables. In
-{\cpattern}, a pattern-matching metavariable is represented with the
-syntax {\tt ?id} where {\tt id} is an {\ident}. The notation {\tt \_}
-can also be used to denote metavariable whose instance is
-irrelevant. In the notation {\tt ?id}, the identifier allows us to
-keep instantiations and to make constraints whereas {\tt \_} shows
-that we are not interested in what will be matched. On the right hand
-side of pattern-matching clauses, the named metavariable are used
-without the question mark prefix. There is also a special notation for
-second-order pattern-matching problems: in an applicative pattern of
-the form {\tt @?id id$_1$ \ldots id$_n$}, the variable {\tt id}
-matches any complex expression with (possible) dependencies in the
-variables {\tt id$_1$ \ldots id$_n$} and returns a functional term of
-the form {\tt fun id$_1$ \ldots id$_n$ => {\term}}.
-
-
-The main entry of the grammar is {\tacexpr}. This language is used in
-proof mode but it can also be used in toplevel definitions as shown in
-Figure~\ref{ltactop}.
-
-\begin{Remarks}
-\item The infix tacticals ``\dots\ {\tt ||} \dots'', ``\dots\ {\tt +}
- \dots'', and ``\dots\ {\tt ;} \dots'' are associative.
-
-\item In {\tacarg}, there is an overlap between {\qualid} as a
-direct tactic argument and {\qualid} as a particular case of
-{\term}. The resolution is done by first looking for a reference of
-the tactic language and if it fails, for a reference to a term. To
-force the resolution as a reference of the tactic language, use the
-form {\tt ltac :} {\qualid}. To force the resolution as a reference to
-a term, use the syntax {\tt ({\qualid})}.
-
-\item As shown by the figure, tactical {\tt ||} binds more than the
-prefix tacticals {\tt try}, {\tt repeat}, {\tt do} and
-{\tt abstract} which themselves bind more than the postfix tactical
-``{\tt \dots\ ;[ \dots\ ]}'' which binds more than ``\dots\ {\tt ;}
-\dots''.
-
-For instance
-\begin{quote}
-{\tt try repeat \tac$_1$ ||
- \tac$_2$;\tac$_3$;[\tac$_{31}$|\dots|\tac$_{3n}$];\tac$_4$.}
-\end{quote}
-is understood as
-\begin{quote}
-{\tt (try (repeat (\tac$_1$ || \tac$_2$)));} \\
-{\tt ((\tac$_3$;[\tac$_{31}$|\dots|\tac$_{3n}$]);\tac$_4$).}
-\end{quote}
-\end{Remarks}
-
-
-\begin{figure}[htbp]
-\begin{centerframe}
-\begin{tabular}{lcl}
-{\tacexpr} & ::= &
- {\tacexpr} {\tt ;} {\tacexpr}\\
-& | & {\tt [>} \nelist{\tacexpr}{|} {\tt ]}\\
-& | & {\tacexpr} {\tt ; [} \nelist{\tacexpr}{|} {\tt ]}\\
-& | & {\tacexprpref}\\
-\\
-{\tacexprpref} & ::= &
- {\tt do} {\it (}{\naturalnumber} {\it |} {\ident}{\it )} {\tacexprpref}\\
-& | & {\tt progress} {\tacexprpref}\\
-& | & {\tt repeat} {\tacexprpref}\\
-& | & {\tt try} {\tacexprpref}\\
-& | & {\tt once} {\tacexprpref}\\
-& | & {\tt exactly\_once} {\tacexprpref}\\
-& | & {\tt timeout} {\it (}{\naturalnumber} {\it |} {\ident}{\it )} {\tacexprpref}\\
-& | & {\tt time} \zeroone{\qstring} {\tacexprpref}\\
-& | & {\tt only} {\selector} {\tt :} {\tacexprpref}\\
-& | & {\tacexprinf} \\
-\\
-{\tacexprinf} & ::= &
- {\tacexprlow} {\tt ||} {\tacexprpref}\\
-& | & {\tacexprlow} {\tt +} {\tacexprpref}\\
-& | & {\tt tryif} {\tacexprlow} {\tt then} {\tacexprlow} {\tt else} {\tacexprlow}\\
-& | & {\tacexprlow}\\
-\\
-{\tacexprlow} & ::= &
-{\tt fun} \nelist{\name}{} {\tt =>} {\atom}\\
-& | &
-{\tt let} \zeroone{\tt rec} \nelist{\letclause}{\tt with} {\tt in}
-{\atom}\\
-& | &
-{\tt match goal with} \nelist{\contextrule}{\tt |} {\tt end}\\
-& | &
-{\tt match reverse goal with} \nelist{\contextrule}{\tt |} {\tt end}\\
-& | &
-{\tt match} {\tacexpr} {\tt with} \nelist{\matchrule}{\tt |} {\tt end}\\
-& | &
-{\tt lazymatch goal with} \nelist{\contextrule}{\tt |} {\tt end}\\
-& | &
-{\tt lazymatch reverse goal with} \nelist{\contextrule}{\tt |} {\tt end}\\
-& | &
-{\tt lazymatch} {\tacexpr} {\tt with} \nelist{\matchrule}{\tt |} {\tt end}\\
-& | &
-{\tt multimatch goal with} \nelist{\contextrule}{\tt |} {\tt end}\\
-& | &
-{\tt multimatch reverse goal with} \nelist{\contextrule}{\tt |} {\tt end}\\
-& | &
-{\tt multimatch} {\tacexpr} {\tt with} \nelist{\matchrule}{\tt |} {\tt end}\\
-& | & {\tt abstract} {\atom}\\
-& | & {\tt abstract} {\atom} {\tt using} {\ident} \\
-& | & {\tt first [} \nelist{\tacexpr}{\tt |} {\tt ]}\\
-& | & {\tt solve [} \nelist{\tacexpr}{\tt |} {\tt ]}\\
-& | & {\tt idtac} \sequence{\messagetoken}{}\\
-& | & {\tt fail} \zeroone{\naturalnumber} \sequence{\messagetoken}{}\\
-& | & {\tt gfail} \zeroone{\naturalnumber} \sequence{\messagetoken}{}\\
-& | & {\tt fresh} ~|~ {\tt fresh} {\qstring}|~ {\tt fresh} {\qualid}\\
-& | & {\tt context} {\ident} {\tt [} {\term} {\tt ]}\\
-& | & {\tt eval} {\nterm{redexpr}} {\tt in} {\term}\\
-& | & {\tt type of} {\term}\\
-& | & {\tt external} {\qstring} {\qstring} \nelist{\tacarg}{}\\
-& | & {\tt constr :} {\term}\\
-& | & {\tt uconstr :} {\term}\\
-& | & {\tt type\_term} {\term}\\
-& | & {\tt numgoals} \\
-& | & {\tt guard} {\it test}\\
-& | & {\tt assert\_fails} {\tacexprpref}\\
-& | & {\tt assert\_succeds} {\tacexprpref}\\
-& | & \atomictac\\
-& | & {\qualid} \nelist{\tacarg}{}\\
-& | & {\atom}
-\end{tabular}
-\end{centerframe}
-\caption{Syntax of the tactic language}
-\label{ltac}
-\end{figure}
-
-
-
-\begin{figure}[htbp]
-\begin{centerframe}
-\begin{tabular}{lcl}
-{\atom} & ::= &
- {\qualid} \\
-& | & ()\\
-& | & {\integer}\\
-& | & {\tt (} {\tacexpr} {\tt )}\\
-\\
-{\messagetoken}\!\!\!\!\!\! & ::= & {\qstring} ~|~ {\ident} ~|~ {\integer} \\
-\\
-\tacarg & ::= &
- {\qualid}\\
-& $|$ & {\tt ()} \\
-& $|$ & {\tt ltac :} {\atom}\\
-& $|$ & {\term}\\
-\\
-\letclause & ::= & {\ident} \sequence{\name}{} {\tt :=} {\tacexpr}\\
-\\
-\contextrule & ::= &
- \nelist{\contexthyp}{\tt ,} {\tt |-}{\cpattern} {\tt =>} {\tacexpr}\\
-& $|$ & {\tt |-} {\cpattern} {\tt =>} {\tacexpr}\\
-& $|$ & {\tt \_ =>} {\tacexpr}\\
-\\
-\contexthyp & ::= & {\name} {\tt :} {\cpattern}\\
- & $|$ & {\name} {\tt :=} {\cpattern} \zeroone{{\tt :} {\cpattern}}\\
-\\
-\matchrule & ::= &
- {\cpattern} {\tt =>} {\tacexpr}\\
-& $|$ & {\tt context} {\zeroone{\ident}} {\tt [} {\cpattern} {\tt ]}
- {\tt =>} {\tacexpr}\\
-& $|$ & {\tt \_ =>} {\tacexpr}\\
-\\
-{\it test} & ::= &
- {\integer} {\tt \,=\,} {\integer}\\
-& $|$ & {\integer} {\tt \,<\,} {\integer}\\
-& $|$ & {\integer} {\tt <=} {\integer}\\
-& $|$ & {\integer} {\tt \,>\,} {\integer}\\
-& $|$ & {\integer} {\tt >=} {\integer}\\
-\\
-\selector & ::= &
- [{\ident}]\\
-& $|$ & {\integer}\\
-& $|$ & \nelist{{\it (}{\integer} {\it |} {\integer} {\tt -} {\integer}{\it )}}
- {\tt ,}\\
-\\
-\toplevelselector & ::= &
- \selector\\
-& $|$ & {\tt all}\\
-& $|$ & {\tt par}
-\end{tabular}
-\end{centerframe}
-\caption{Syntax of the tactic language (continued)}
-\label{ltac-aux}
-\end{figure}
-
-\begin{figure}[ht]
-\begin{centerframe}
-\begin{tabular}{lcl}
-\nterm{top} & ::= & \zeroone{\tt Local} {\tt Ltac} \nelist{\nterm{ltac\_def}} {\tt with} \\
-\\
-\nterm{ltac\_def} & ::= & {\ident} \sequence{\ident}{} {\tt :=}
-{\tacexpr}\\
-& $|$ &{\qualid} \sequence{\ident}{} {\tt ::=}{\tacexpr}
-\end{tabular}
-\end{centerframe}
-\caption{Tactic toplevel definitions}
-\label{ltactop}
-\end{figure}
-
-
-%%
-%% Semantics
-%%
-\section{Semantics}
-%\index[tactic]{Tacticals}
-\index{Tacticals}
-%\label{Tacticals}
-
-Tactic expressions can only be applied in the context of a proof. The
-evaluation yields either a term, an integer or a tactic. Intermediary
-results can be terms or integers but the final result must be a tactic
-which is then applied to the focused goals.
-
-There is a special case for {\tt match goal} expressions of which
-the clauses evaluate to tactics. Such expressions can only be used as
-end result of a tactic expression (never as argument of a non recursive local
-definition or of an application).
-
-The rest of this section explains the semantics of every construction
-of Ltac.
-
-
-%% \subsection{Values}
-
-%% Values are given by Figure~\ref{ltacval}. All these values are tactic values,
-%% i.e. to be applied to a goal, except {\tt Fun}, {\tt Rec} and $arg$ values.
-
-%% \begin{figure}[ht]
-%% \noindent{}\framebox[6in][l]
-%% {\parbox{6in}
-%% {\begin{center}
-%% \begin{tabular}{lp{0.1in}l}
-%% $vexpr$ & ::= & $vexpr$ {\tt ;} $vexpr$\\
-%% & | & $vexpr$ {\tt ; [} {\it (}$vexpr$ {\tt |}{\it )}$^*$ $vexpr$ {\tt
-%% ]}\\
-%% & | & $vatom$\\
-%% \\
-%% $vatom$ & ::= & {\tt Fun} \nelist{\inputfun}{} {\tt ->} {\tacexpr}\\
-%% %& | & {\tt Rec} \recclause\\
-%% & | &
-%% {\tt Rec} \nelist{\recclause}{\tt And} {\tt In}
-%% {\tacexpr}\\
-%% & | &
-%% {\tt Match Context With} {\it (}$context\_rule$ {\tt |}{\it )}$^*$
-%% $context\_rule$\\
-%% & | & {\tt (} $vexpr$ {\tt )}\\
-%% & | & $vatom$ {\tt Orelse} $vatom$\\
-%% & | & {\tt Do} {\it (}{\naturalnumber} {\it |} {\ident}{\it )} $vatom$\\
-%% & | & {\tt Repeat} $vatom$\\
-%% & | & {\tt Try} $vatom$\\
-%% & | & {\tt First [} {\it (}$vexpr$ {\tt |}{\it )}$^*$ $vexpr$ {\tt ]}\\
-%% & | & {\tt Solve [} {\it (}$vexpr$ {\tt |}{\it )}$^*$ $vexpr$ {\tt ]}\\
-%% & | & {\tt Idtac}\\
-%% & | & {\tt Fail}\\
-%% & | & {\primitivetactic}\\
-%% & | & $arg$
-%% \end{tabular}
-%% \end{center}}}
-%% \caption{Values of ${\cal L}_{tac}$}
-%% \label{ltacval}
-%% \end{figure}
-
-%% \subsection{Evaluation}
-
-\subsubsection[Sequence]{Sequence\tacindex{;}
-\index{Tacticals!;@{\tt {\tac$_1$};\tac$_2$}}}
-
-A sequence is an expression of the following form:
-\begin{quote}
-{\tacexpr}$_1$ {\tt ;} {\tacexpr}$_2$
-\end{quote}
-The expression {\tacexpr}$_1$ is evaluated to $v_1$, which must be
-a tactic value. The tactic $v_1$ is applied to the current goal,
-possibly producing more goals. Then {\tacexpr}$_2$ is evaluated to
-produce $v_2$, which must be a tactic value. The tactic $v_2$ is applied to
-all the goals produced by the prior application. Sequence is associative.
-
-\subsubsection[Local application of tactics]{Local application of tactics\tacindex{[>\ldots$\mid$\ldots$\mid$\ldots]}\tacindex{;[\ldots$\mid$\ldots$\mid$\ldots]}\index{Tacticals![> \mid ]@{\tt {\tac$_0$};[{\tac$_1$}$\mid$\ldots$\mid$\tac$_n$]}}\index{Tacticals!; [ \mid ]@{\tt {\tac$_0$};[{\tac$_1$}$\mid$\ldots$\mid$\tac$_n$]}}}
-%\tacindex{; [ | ]}
-%\index{; [ | ]@{\tt ;[\ldots$\mid$\ldots$\mid$\ldots]}}
-
-Different tactics can be applied to the different goals using the following form:
-\begin{quote}
-{\tt [ >} {\tacexpr}$_1$ {\tt |} $...$ {\tt |} {\tacexpr}$_n$ {\tt ]}
-\end{quote}
-The expressions {\tacexpr}$_i$ are evaluated to $v_i$, for $i=0,...,n$
-and all have to be tactics. The $v_i$ is applied to the $i$-th goal,
-for $=1,...,n$. It fails if the number of focused goals is not exactly $n$.
-
-\begin{Variants}
- \item If no tactic is given for the $i$-th goal, it behaves as if
- the tactic {\tt idtac} were given. For instance, {\tt [~> | auto
- ]} is a shortcut for {\tt [ > idtac | auto ]}.
-
- \item {\tt [ >} {\tacexpr}$_1$ {\tt |} $...$ {\tt |}
- {\tacexpr}$_i$ {\tt |} {\tacexpr} {\tt ..} {\tt |}
- {\tacexpr}$_{i+1+j}$ {\tt |} $...$ {\tt |} {\tacexpr}$_n$ {\tt ]}
-
- In this variant, {\tt expr} is used for each goal numbered from
- $i+1$ to $i+j$ (assuming $n$ is the number of goals).
-
- Note that {\tt ..} is part of the syntax, while $...$ is the meta-symbol used
- to describe a list of {\tacexpr} of arbitrary length.
- goals numbered from $i+1$ to $i+j$.
-
- \item {\tt [ >} {\tacexpr}$_1$ {\tt |} $...$ {\tt |}
- {\tacexpr}$_i$ {\tt |} {\tt ..} {\tt |} {\tacexpr}$_{i+1+j}$ {\tt |}
- $...$ {\tt |} {\tacexpr}$_n$ {\tt ]}
-
- In this variant, {\tt idtac} is used for the goals numbered from
- $i+1$ to $i+j$.
-
- \item {\tt [ >} {\tacexpr} {\tt ..} {\tt ]}
-
- In this variant, the tactic {\tacexpr} is applied independently to
- each of the goals, rather than globally. In particular, if there
- are no goal, the tactic is not run at all. A tactic which
- expects multiple goals, such as {\tt swap}, would act as if a single
- goal is focused.
-
- \item {\tacexpr} {\tt ; [ } {\tacexpr}$_1$ {\tt |} $...$ {\tt |} {\tacexpr}$_n$ {\tt ]}
-
- This variant of local tactic application is paired with a
- sequence. In this variant, $n$ must be the number of goals
- generated by the application of {\tacexpr} to each of the
- individual goals independently. All the above variants work in
- this form too. Formally, {\tacexpr} {\tt ; [} $...$ {\tt ]} is
- equivalent to
- \begin{quote}
- {\tt [ >} {\tacexpr} {\tt ; [ >} $...$ {\tt ]} {\tt ..} {\tt ]}
- \end{quote}
-
-\end{Variants}
-
-\subsubsection[Goal selectors]{Goal selectors\label{ltac:selector}
-\tacindex{\tt :}\index{Tacticals!:@{\tt :}}}
-
-We can restrict the application of a tactic to a subset of
-the currently focused goals with:
-\begin{quote}
- {\toplevelselector} {\tt :} {\tacexpr}
-\end{quote}
-We can also use selectors as a tactical, which allows to use them nested in
-a tactic expression, by using the keyword {\tt only}:
-\begin{quote}
- {\tt only} {\selector} {\tt :} {\tacexpr}
-\end{quote}
-When selecting several goals, the tactic {\tacexpr} is applied globally to
-all selected goals.
-
-\begin{Variants}
- \item{} [{\ident}] {\tt :} {\tacexpr}
-
- In this variant, {\tacexpr} is applied locally to a goal
- previously named by the user (see~\ref{ExistentialVariables}).
-
- \item {\num} {\tt :} {\tacexpr}
-
- In this variant, {\tacexpr} is applied locally to the
- {\num}-th goal.
-
- \item $n_1$-$m_1$, \dots, $n_k$-$m_k$ {\tt :} {\tacexpr}
-
- In this variant, {\tacexpr} is applied globally to the subset
- of goals described by the given ranges. You can write a single
- $n$ as a shortcut for $n$-$n$ when specifying multiple ranges.
-
- \item {\tt all:} {\tacexpr}
-
- In this variant, {\tacexpr} is applied to all focused goals.
- {\tt all:} can only be used at the toplevel of a tactic expression.
-
- \item {\tt par:} {\tacexpr}
-
- In this variant, {\tacexpr} is applied to all focused goals
- in parallel. The number of workers can be controlled via the
- command line option {\tt -async-proofs-tac-j} taking as argument
- the desired number of workers. Limitations: {\tt par: } only works
- on goals containing no existential variables and {\tacexpr} must
- either solve the goal completely or do nothing (i.e. it cannot make
- some progress).
- {\tt par:} can only be used at the toplevel of a tactic expression.
-
-\end{Variants}
-
-\ErrMsg \errindex{No such goal}
-
-\subsubsection[For loop]{For loop\tacindex{do}
-\index{Tacticals!do@{\tt do}}}
-
-There is a for loop that repeats a tactic {\num} times:
-\begin{quote}
-{\tt do} {\num} {\tacexpr}
-\end{quote}
-{\tacexpr} is evaluated to $v$ which must be a tactic value.
-This tactic value $v$ is
-applied {\num} times. Supposing ${\num}>1$, after the first
-application of $v$, $v$ is applied, at least once, to the generated
-subgoals and so on. It fails if the application of $v$ fails before
-the {\num} applications have been completed.
-
-\subsubsection[Repeat loop]{Repeat loop\tacindex{repeat}
-\index{Tacticals!repeat@{\tt repeat}}}
-
-We have a repeat loop with:
-\begin{quote}
-{\tt repeat} {\tacexpr}
-\end{quote}
-{\tacexpr} is evaluated to $v$. If $v$ denotes a tactic, this tactic
-is applied to each focused goal independently. If the application
-succeeds, the tactic is applied recursively to all the generated subgoals
-until it eventually fails. The recursion stops in a subgoal when the
-tactic has failed \emph{to make progress}. The tactic {\tt repeat
- {\tacexpr}} itself never fails.
-
-\subsubsection[Error catching]{Error catching\tacindex{try}
-\index{Tacticals!try@{\tt try}}}
-
-We can catch the tactic errors with:
-\begin{quote}
-{\tt try} {\tacexpr}
-\end{quote}
-{\tacexpr} is evaluated to $v$ which must be a tactic value.
-The tactic value $v$ is
-applied to each focused goal independently. If the application of $v$
-fails in a goal, it catches the error and leaves the goal
-unchanged. If the level of the exception is positive, then the
-exception is re-raised with its level decremented.
-
-\subsubsection[Detecting progress]{Detecting progress\tacindex{progress}}
-
-We can check if a tactic made progress with:
-\begin{quote}
-{\tt progress} {\tacexpr}
-\end{quote}
-{\tacexpr} is evaluated to $v$ which must be a tactic value.
-The tactic value $v$ is
-applied to each focued subgoal independently. If the application of
-$v$ 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.
-
-\ErrMsg \errindex{Failed to progress}
-
-\subsubsection[Backtracking branching]{Backtracking branching\tacindex{$+$}
-\index{Tacticals!or@{\tt $+$}}}
-
-We can branch with the following structure:
-\begin{quote}
-{\tacexpr}$_1$ {\tt +} {\tacexpr}$_2$
-\end{quote}
-{\tacexpr}$_1$ and {\tacexpr}$_2$ are evaluated to $v_1$ and
-$v_2$ which must be tactic values. The tactic value $v_1$ is applied to each
-focused goal independently and if it fails or a later tactic fails,
-then the proof backtracks to the current goal and $v_2$ is applied.
-
-Tactics can be seen as having several successes. When a tactic fails
-it asks for more successes of the prior tactics. {\tacexpr}$_1$ {\tt
- +} {\tacexpr}$_2$ has all the successes of $v_1$ followed by all the
-successes of $v_2$. Algebraically, ({\tacexpr}$_1$ {\tt +}
-{\tacexpr}$_2$);{\tacexpr}$_3$ $=$ ({\tacexpr}$_1$;{\tacexpr}$_3$)
-{\tt +} ({\tacexpr}$_2$;{\tacexpr}$_3$).
-
-Branching is left-associative.
-
-\subsubsection[First tactic to work]{First tactic to work\tacindex{first}
-\index{Tacticals!first@{\tt first}}}
-
-Backtracking branching may be too expensive. In this case we may
-restrict to a local, left biased, branching and consider the first
-tactic to work (i.e. which does not fail) among a panel of tactics:
-\begin{quote}
-{\tt first [} {\tacexpr}$_1$ {\tt |} $...$ {\tt |} {\tacexpr}$_n$ {\tt ]}
-\end{quote}
-{\tacexpr}$_i$ are evaluated to $v_i$ and $v_i$ must be tactic values,
-for $i=1,...,n$. Supposing $n>1$, it applies, in each focused goal
-independently, $v_1$, if it works, it stops otherwise it tries to
-apply $v_2$ and so on. It fails when there is no applicable tactic. In
-other words, {\tt first [} {\tacexpr}$_1$ {\tt |} $...$ {\tt |}
- {\tacexpr}$_n$ {\tt ]} behaves, in each goal, as the the first $v_i$
-to have \emph{at least} one success.
-
-\ErrMsg \errindex{No applicable tactic}
-
-\variant {\tt first {\tacexpr}}
-
-This is an Ltac alias that gives a primitive access to the {\tt first} tactical
-as a Ltac definition without going through a parsing rule. It expects to be
-given a list of tactics through a {\tt Tactic Notation}, allowing to write
-notations of the following form.
-
-\Example
-
-\begin{quote}
-{\tt Tactic Notation "{foo}" tactic\_list(tacs) := first tacs.}
-\end{quote}
-
-\subsubsection[Left-biased branching]{Left-biased branching\tacindex{$\mid\mid$}
-\index{Tacticals!orelse@{\tt $\mid\mid$}}}
-
-Yet another way of branching without backtracking is the following structure:
-\begin{quote}
-{\tacexpr}$_1$ {\tt ||} {\tacexpr}$_2$
-\end{quote}
-{\tacexpr}$_1$ and {\tacexpr}$_2$ are evaluated to $v_1$ and
-$v_2$ which must be tactic values. The tactic value $v_1$ is applied in each
-subgoal independently and if it fails \emph{to progress} then $v_2$ is
-applied. {\tacexpr}$_1$ {\tt ||} {\tacexpr}$_2$ is equivalent to {\tt
- first [} {\tt progress} {\tacexpr}$_1$ {\tt |}
- {\tacexpr}$_2$ {\tt ]} (except that if it fails, it fails like
-$v_2$). Branching is left-associative.
-
-\subsubsection[Generalized biased branching]{Generalized biased branching\tacindex{tryif}
-\index{Tacticals!tryif@{\tt tryif}}}
-
-The tactic
-\begin{quote}
-{\tt tryif {\tacexpr}$_1$ then {\tacexpr}$_2$ else {\tacexpr}$_3$}
-\end{quote}
-is a generalization of the biased-branching tactics above. The
-expression {\tacexpr}$_1$ is evaluated to $v_1$, which is then applied
-to each subgoal independently. For each goal where $v_1$ succeeds at
-least once, {\tacexpr}$_2$ is evaluated to $v_2$ which is then applied
-collectively to the generated subgoals. The $v_2$ tactic can trigger
-backtracking points in $v_1$: where $v_1$ succeeds at least once, {\tt
- tryif {\tacexpr}$_1$ then {\tacexpr}$_2$ else {\tacexpr}$_3$} is
-equivalent to $v_1;v_2$. In each of the goals where $v_1$ does not
-succeed at least once, {\tacexpr}$_3$ is evaluated in $v_3$ which is
-is then applied to the goal.
-
-\subsubsection[Soft cut]{Soft cut\tacindex{once}\index{Tacticals!once@{\tt once}}}
-
-Another way of restricting backtracking is to restrict a tactic to a
-single success \emph{a posteriori}:
-\begin{quote}
-{\tt once} {\tacexpr}
-\end{quote}
-{\tacexpr} is evaluated to $v$ which must be a tactic value.
-The tactic value $v$ is
-applied but only its first success is used. If $v$ fails, {\tt once}
-{\tacexpr} fails like $v$. If $v$ has a least one success, {\tt once}
-{\tacexpr} succeeds once, but cannot produce more successes.
-
-\subsubsection[Checking the successes]{Checking the successes\tacindex{exactly\_once}\index{Tacticals!exactly\_once@{\tt exactly\_once}}}
-
-Coq provides an experimental way to check that a tactic has \emph{exactly one} success:
-\begin{quote}
-{\tt exactly\_once} {\tacexpr}
-\end{quote}
-{\tacexpr} is evaluated to $v$ which must be a tactic value.
-The tactic value $v$ is
-applied if it has at most one success. If $v$ fails, {\tt
- exactly\_once} {\tacexpr} fails like $v$. If $v$ has a exactly one
-success, {\tt exactly\_once} {\tacexpr} succeeds like $v$. If $v$ has
-two or more successes, {\tt exactly\_once} {\tacexpr} fails.
-
-The experimental status of this tactic pertains to the fact if $v$ performs side effects, they may occur in a unpredictable way. Indeed, normally $v$ would only be executed up to the first success until backtracking is needed, however {\tt exactly\_once} needs to look ahead to see whether a second success exists, and may run further effects immediately.
-
-\ErrMsg \errindex{This tactic has more than one success}
-
-\subsubsection[Checking the failure]{Checking the failure\tacindex{assert\_fails}\index{Tacticals!assert\_fails@{\tt assert\_fails}}}
-
-Coq provides a derived tactic to check that a tactic \emph{fails}:
-\begin{quote}
-{\tt assert\_fails} {\tacexpr}
-\end{quote}
-This behaves like {\tt tryif {\tacexpr} then fail 0 tac "succeeds" else idtac}.
-
-\subsubsection[Checking the success]{Checking the success\tacindex{assert\_succeeds}\index{Tacticals!assert\_succeeds@{\tt assert\_succeeds}}}
-
-Coq provides a derived tactic to check that a tactic has \emph{at least one} success:
-\begin{quote}
-{\tt assert\_succeeds} {\tacexpr}
-\end{quote}
-This behaves like {\tt tryif (assert\_fails tac) then fail 0 tac "fails" else idtac}.
-
-\subsubsection[Solving]{Solving\tacindex{solve}
-\index{Tacticals!solve@{\tt solve}}}
-
-We may consider the first to solve (i.e. which generates no subgoal) among a
-panel of tactics:
-\begin{quote}
-{\tt solve [} {\tacexpr}$_1$ {\tt |} $...$ {\tt |} {\tacexpr}$_n$ {\tt ]}
-\end{quote}
-{\tacexpr}$_i$ are evaluated to $v_i$ and $v_i$ must be tactic values,
-for $i=1,...,n$. Supposing $n>1$, it applies $v_1$ to each goal
-independently, if it doesn't solve the goal then it tries to apply
-$v_2$ and so on. It fails if there is no solving tactic.
-
-\ErrMsg \errindex{Cannot solve the goal}
-
-\variant {\tt solve {\tacexpr}}
-
-This is an Ltac alias that gives a primitive access to the {\tt solve} tactical.
-See the {\tt first} tactical for more information.
-
-\subsubsection[Identity]{Identity\label{ltac:idtac}\tacindex{idtac}
-\index{Tacticals!idtac@{\tt idtac}}}
-
-The constant {\tt idtac} is the identity tactic: it leaves any goal
-unchanged but it appears in the proof script.
-
-\variant {\tt idtac \nelist{\messagetoken}{}}
-
-This prints the given tokens. Strings and integers are printed
-literally. If a (term) variable is given, its contents are printed.
-
-
-\subsubsection[Failing]{Failing\tacindex{fail}
-\index{Tacticals!fail@{\tt fail}}
-\tacindex{gfail}\index{Tacticals!gfail@{\tt gfail}}}
-
-The tactic {\tt fail} is the always-failing tactic: it does not solve
-any goal. It is useful for defining other tacticals since it can be
-caught by {\tt try}, {\tt repeat}, {\tt match goal}, or the branching
-tacticals. The {\tt fail} tactic will, however, succeed if all the
-goals have already been solved.
-
-\begin{Variants}
-\item {\tt fail $n$}\\ The number $n$ is the failure level. If no
- level is specified, it defaults to $0$. The level is used by {\tt
- try}, {\tt repeat}, {\tt match goal} and the branching tacticals.
- If $0$, it makes {\tt match goal} considering the next clause
- (backtracking). If non zero, the current {\tt match goal} block,
- {\tt try}, {\tt repeat}, or branching command is aborted and the
- level is decremented. In the case of {\tt +}, a non-zero level skips
- the first backtrack point, even if the call to {\tt fail $n$} is not
- enclosed in a {\tt +} command, respecting the algebraic identity.
-
-\item {\tt fail \nelist{\messagetoken}{}}\\
-The given tokens are used for printing the failure message.
-
-\item {\tt fail $n$ \nelist{\messagetoken}{}}\\
-This is a combination of the previous variants.
-
-\item {\tt gfail}\\
-This variant fails even if there are no goals left.
-
-\item {\tt gfail \nelist{\messagetoken}{}}\\
-{\tt gfail $n$ \nelist{\messagetoken}{}}\\
-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
-printed as part of the failure: term construction always forces the
-tactic into the goals, meaning that if there are no goals when it is
-evaluated, a tactic call like {\tt let x:=H in fail 0 x} will succeed.
-
-\end{Variants}
-
-\ErrMsg \errindex{Tactic Failure {\it message} (level $n$)}.
-
-\subsubsection[Timeout]{Timeout\tacindex{timeout}
-\index{Tacticals!timeout@{\tt timeout}}}
-
-We can force a tactic to stop if it has not finished after a certain
-amount of time:
-\begin{quote}
-{\tt timeout} {\num} {\tacexpr}
-\end{quote}
-{\tacexpr} is evaluated to $v$ which must be a tactic value.
-The tactic value $v$ is
-applied normally, except that it is interrupted after ${\num}$ seconds
-if it is still running. In this case the outcome is a failure.
-
-Warning: For the moment, {\tt timeout} is based on elapsed time in
-seconds, which is very
-machine-dependent: a script that works on a quick machine may fail
-on a slow one. The converse is even possible if you combine a
-{\tt timeout} with some other tacticals. This tactical is hence
-proposed only for convenience during debug or other development
-phases, we strongly advise you to not leave any {\tt timeout} in
-final scripts. Note also that this tactical isn't available on
-the native Windows port of Coq.
-
-\subsubsection{Timing a tactic\tacindex{time}
-\index{Tacticals!time@{\tt time}}}
-
-A tactic execution can be timed:
-\begin{quote}
- {\tt time} {\qstring} {\tacexpr}
-\end{quote}
-evaluates {\tacexpr}
-and displays the time the tactic expression ran, whether it fails or
-successes. In case of several successes, the time for each successive
-runs is displayed. Time is in seconds and is machine-dependent. The
-{\qstring} argument is optional. When provided, it is used to identify
-this particular occurrence of {\tt time}.
-
-\subsubsection{Timing a tactic that evaluates to a term\tacindex{time\_constr}\tacindex{restart\_timer}\tacindex{finish\_timing}
-\index{Tacticals!time\_constr@{\tt time\_constr}}}
-\index{Tacticals!restart\_timer@{\tt restart\_timer}}
-\index{Tacticals!finish\_timing@{\tt finish\_timing}}
-
-Tactic expressions that produce terms can be timed with the experimental tactic
-\begin{quote}
- {\tt time\_constr} {\tacexpr}
-\end{quote}
-which evaluates {\tacexpr\tt{ ()}}
-and displays the time the tactic expression evaluated, assuming successful evaluation.
-Time is in seconds and is machine-dependent.
-
-This tactic currently does not support nesting, and will report times based on the innermost execution.
-This is due to the fact that it is implemented using the tactics
-\begin{quote}
- {\tt restart\_timer} {\qstring}
-\end{quote}
-and
-\begin{quote}
- {\tt finish\_timing} ({\qstring}) {\qstring}
-\end{quote}
-which (re)set and display an optionally named timer, respectively.
-The parenthesized {\qstring} argument to {\tt finish\_timing} is also
-optional, and determines the label associated with the timer for
-printing.
-
-By copying the definition of {\tt time\_constr} from the standard
-library, users can achive support for a fixed pattern of nesting by
-passing different {\qstring} parameters to {\tt restart\_timer} and
-{\tt finish\_timing} at each level of nesting. For example:
-
-\begin{coq_example}
-Ltac time_constr1 tac :=
- let eval_early := match goal with _ => restart_timer "(depth 1)" end in
- let ret := tac () in
- let eval_early := match goal with _ => finish_timing ( "Tactic evaluation" ) "(depth 1)" end in
- ret.
-
-Goal True.
- let v := time_constr
- ltac:(fun _ =>
- let x := time_constr1 ltac:(fun _ => constr:(10 * 10)) in
- let y := time_constr1 ltac:(fun _ => eval compute in x) in
- y) in
- pose v.
-Abort.
-\end{coq_example}
-
-\subsubsection[Local definitions]{Local definitions\index{Ltac!let@\texttt{let}}
-\index{Ltac!let rec@\texttt{let rec}}
-\index{let@\texttt{let}!in Ltac}
-\index{let rec@\texttt{let rec}!in Ltac}}
-
-Local definitions can be done as follows:
-\begin{quote}
-{\tt let} {\ident}$_1$ {\tt :=} {\tacexpr}$_1$\\
-{\tt with} {\ident}$_2$ {\tt :=} {\tacexpr}$_2$\\
-...\\
-{\tt with} {\ident}$_n$ {\tt :=} {\tacexpr}$_n$ {\tt in}\\
-{\tacexpr}
-\end{quote}
-each {\tacexpr}$_i$ is evaluated to $v_i$, then, {\tacexpr} is
-evaluated by substituting $v_i$ to each occurrence of {\ident}$_i$,
-for $i=1,...,n$. There is no dependencies between the {\tacexpr}$_i$
-and the {\ident}$_i$.
-
-Local definitions can be recursive by using {\tt let rec} instead of
-{\tt let}. In this latter case, the definitions are evaluated lazily
-so that the {\tt rec} keyword can be used also in non recursive cases
-so as to avoid the eager evaluation of local definitions.
-
-\subsubsection{Application}
-
-An application is an expression of the following form:
-\begin{quote}
-{\qualid} {\tacarg}$_1$ ... {\tacarg}$_n$
-\end{quote}
-The reference {\qualid} must be bound to some defined tactic
-definition expecting at least $n$ arguments. The expressions
-{\tacexpr}$_i$ are evaluated to $v_i$, for $i=1,...,n$.
-%If {\tacexpr} is a {\tt Fun} or {\tt Rec} value then the body is evaluated by
-%substituting $v_i$ to the formal parameters, for $i=1,...,n$. For recursive
-%clauses, the bodies are lazily substituted (when an identifier to be evaluated
-%is the name of a recursive clause).
-
-%\subsection{Application of tactic values}
-
-\subsubsection[Function construction]{Function construction\index{fun@\texttt{fun}!in Ltac}
-\index{Ltac!fun@\texttt{fun}}}
-
-A parameterized tactic can be built anonymously (without resorting to
-local definitions) with:
-\begin{quote}
-{\tt fun} {\ident${}_1$} ... {\ident${}_n$} {\tt =>} {\tacexpr}
-\end{quote}
-Indeed, local definitions of functions are a syntactic sugar for
-binding a {\tt fun} tactic to an identifier.
-
-\subsubsection[Pattern matching on terms]{Pattern matching on terms\index{Ltac!match@\texttt{match}}
-\index{match@\texttt{match}!in Ltac}}
-
-We can carry out pattern matching on terms with:
-\begin{quote}
-{\tt match} {\tacexpr} {\tt with}\\
-~~~{\cpattern}$_1$ {\tt =>} {\tacexpr}$_1$\\
-~{\tt |} {\cpattern}$_2$ {\tt =>} {\tacexpr}$_2$\\
-~...\\
-~{\tt |} {\cpattern}$_n$ {\tt =>} {\tacexpr}$_n$\\
-~{\tt |} {\tt \_} {\tt =>} {\tacexpr}$_{n+1}$\\
-{\tt end}
-\end{quote}
-The expression {\tacexpr} is evaluated and should yield a term which
-is matched against {\cpattern}$_1$. The matching is non-linear: if a
-metavariable occurs more than once, it should match the same
-expression every time. It is first-order except on the
-variables of the form {\tt @?id} that occur in head position of an
-application. For these variables, the matching is second-order and
-returns a functional term.
-
-Alternatively, when a metavariable of the form {\tt ?id} occurs under
-binders, say $x_1$, \ldots, $x_n$ and the expression matches, the
-metavariable is instantiated by a term which can then be used in any
-context which also binds the variables $x_1$, \ldots, $x_n$ with
-same types. This provides with a primitive form of matching
-under context which does not require manipulating a functional term.
-
-If the matching with {\cpattern}$_1$ succeeds, then {\tacexpr}$_1$ is
-evaluated into some value by substituting the pattern matching
-instantiations to the metavariables. If {\tacexpr}$_1$ evaluates to a
-tactic and the {\tt match} expression is in position to be applied to
-a goal (e.g. it is not bound to a variable by a {\tt let in}), then
-this tactic is applied. If the tactic succeeds, the list of resulting
-subgoals is the result of the {\tt match} expression. If
-{\tacexpr}$_1$ does not evaluate to a tactic or if the {\tt match}
-expression is not in position to be applied to a goal, then the result
-of the evaluation of {\tacexpr}$_1$ is the result of the {\tt match}
-expression.
-
-If the matching with {\cpattern}$_1$ fails, or if it succeeds but the
-evaluation of {\tacexpr}$_1$ fails, or if the evaluation of
-{\tacexpr}$_1$ succeeds but returns a tactic in execution position
-whose execution fails, then {\cpattern}$_2$ is used and so on. The
-pattern {\_} matches any term and shunts all remaining patterns if
-any. If all clauses fail (in particular, there is no pattern {\_})
-then a no-matching-clause error is raised.
-
-Failures in subsequent tactics do not cause backtracking to select new
-branches or inside the right-hand side of the selected branch even if
-it has backtracking points.
-
-\begin{ErrMsgs}
-
-\item \errindex{No matching clauses for match}
-
- No pattern can be used and, in particular, there is no {\tt \_} pattern.
-
-\item \errindex{Argument of match does not evaluate to a term}
-
- This happens when {\tacexpr} does not denote a term.
-
-\end{ErrMsgs}
-
-\begin{Variants}
-
-\item \index{multimatch@\texttt{multimatch}!in Ltac}
-\index{Ltac!multimatch@\texttt{multimatch}}
-Using {\tt multimatch} instead of {\tt match} will allow subsequent
-tactics to backtrack into a right-hand side tactic which has
-backtracking points left and trigger the selection of a new matching
-branch when all the backtracking points of the right-hand side have
-been consumed.
-
-The syntax {\tt match \ldots} is, in fact, a shorthand for
-{\tt once multimatch \ldots}.
-
-\item \index{lazymatch@\texttt{lazymatch}!in Ltac}
-\index{Ltac!lazymatch@\texttt{lazymatch}}
-Using {\tt lazymatch} instead of {\tt match} will perform the same
-pattern matching procedure but will commit to the first matching
-branch rather than trying a new matching if the right-hand side
-fails. If the right-hand side of the selected branch is a tactic with
-backtracking points, then subsequent failures cause this tactic to
-backtrack.
-
-\item \index{context@\texttt{context}!in pattern}
-There is a special form of patterns to match a subterm against the
-pattern:
-\begin{quote}
-{\tt context} {\ident} {\tt [} {\cpattern} {\tt ]}
-\end{quote}
-It matches any term with a subterm matching {\cpattern}. If there is
-a match, the optional {\ident} is assigned the ``matched context'', i.e.
-the initial term where the matched subterm is replaced by a
-hole. The example below will show how to use such term contexts.
-
-If the evaluation of the right-hand-side of a valid match fails, the
-next matching subterm is tried. If no further subterm matches, the
-next clause is tried. Matching subterms are considered top-bottom and
-from left to right (with respect to the raw printing obtained by
-setting option {\tt Printing All}, see Section~\ref{SetPrintingAll}).
-
-\begin{coq_example}
-Ltac f x :=
- match x with
- context f [S ?X] =>
- idtac X; (* To display the evaluation order *)
- assert (p := eq_refl 1 : X=1); (* To filter the case X=1 *)
- let x:= context f[O] in assert (x=O) (* To observe the context *)
- end.
-Goal True.
-f (3+4).
-\end{coq_example}
-
-\end{Variants}
-
-\subsubsection[Pattern matching on goals]{Pattern matching on goals\index{Ltac!match goal@\texttt{match goal}}\label{ltac-match-goal}
-\index{Ltac!match reverse goal@\texttt{match reverse goal}}
-\index{match goal@\texttt{match goal}!in Ltac}
-\index{match reverse goal@\texttt{match reverse goal}!in Ltac}}
-
-We can make pattern matching on goals using the following expression:
-\begin{quote}
-\begin{tabbing}
-{\tt match goal with}\\
-~~\={\tt |} $hyp_{1,1}${\tt ,}...{\tt ,}$hyp_{1,m_1}$
- ~~{\tt |-}{\cpattern}$_1${\tt =>} {\tacexpr}$_1$\\
- \>{\tt |} $hyp_{2,1}${\tt ,}...{\tt ,}$hyp_{2,m_2}$
- ~~{\tt |-}{\cpattern}$_2${\tt =>} {\tacexpr}$_2$\\
-~~...\\
- \>{\tt |} $hyp_{n,1}${\tt ,}...{\tt ,}$hyp_{n,m_n}$
- ~~{\tt |-}{\cpattern}$_n${\tt =>} {\tacexpr}$_n$\\
- \>{\tt |\_}~~~~{\tt =>} {\tacexpr}$_{n+1}$\\
-{\tt end}
-\end{tabbing}
-\end{quote}
-
-If each hypothesis pattern $hyp_{1,i}$, with $i=1,...,m_1$
-is matched (non-linear first-order unification) by an hypothesis of
-the goal and if {\cpattern}$_1$ is matched by the conclusion of the
-goal, then {\tacexpr}$_1$ is evaluated to $v_1$ by substituting the
-pattern matching to the metavariables and the real hypothesis names
-bound to the possible hypothesis names occurring in the hypothesis
-patterns. If $v_1$ is a tactic value, then it is applied to the
-goal. If this application fails, then another combination of
-hypotheses is tried with the same proof context pattern. If there is
-no other combination of hypotheses then the second proof context
-pattern is tried and so on. If the next to last proof context pattern
-fails then {\tacexpr}$_{n+1}$ is evaluated to $v_{n+1}$ and $v_{n+1}$
-is applied. Note also that matching against subterms (using the {\tt
-context} {\ident} {\tt [} {\cpattern} {\tt ]}) is available and is
-also subject to yielding several matchings.
-
-Failures in subsequent tactics do not cause backtracking to select new
-branches or combinations of hypotheses, or inside the right-hand side
-of the selected branch even if it has backtracking points.
-
-\ErrMsg \errindex{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.
-
-\medskip
-
-It is important to know that each hypothesis of the goal can be
-matched by at most one hypothesis pattern. The order of matching is
-the following: hypothesis patterns are examined from the right to the
-left (i.e. $hyp_{i,m_i}$ before $hyp_{i,1}$). For each hypothesis
-pattern, the goal hypothesis are matched in order (fresher hypothesis
-first), but it possible to reverse this order (older first) with
-the {\tt match reverse goal with} variant.
-
-\variant
-
-\index{multimatch goal@\texttt{multimatch goal}!in Ltac}
-\index{Ltac!multimatch goal@\texttt{multimatch goal}}
-\index{multimatch reverse goal@\texttt{multimatch reverse goal}!in Ltac}
-\index{Ltac!multimatch reverse goal@\texttt{multimatch reverse goal}}
-
-Using {\tt multimatch} instead of {\tt match} will allow subsequent
-tactics to backtrack into a right-hand side tactic which has
-backtracking points left and trigger the selection of a new matching
-branch or combination of hypotheses when all the backtracking points
-of the right-hand side have been consumed.
-
-The syntax {\tt match [reverse] goal \ldots} is, in fact, a shorthand for
-{\tt once multimatch [reverse] goal \ldots}.
-
-\index{lazymatch goal@\texttt{lazymatch goal}!in Ltac}
-\index{Ltac!lazymatch goal@\texttt{lazymatch goal}}
-\index{lazymatch reverse goal@\texttt{lazymatch reverse goal}!in Ltac}
-\index{Ltac!lazymatch reverse goal@\texttt{lazymatch reverse goal}}
-Using {\tt lazymatch} instead of {\tt match} will perform the same
-pattern matching procedure but will commit to the first matching
-branch with the first matching combination of hypotheses rather than
-trying a new matching if the right-hand side fails. If the right-hand
-side of the selected branch is a tactic with backtracking points, then
-subsequent failures cause this tactic to backtrack.
-
-\subsubsection[Filling a term context]{Filling a term context\index{context@\texttt{context}!in expression}}
-
-The following expression is not a tactic in the sense that it does not
-produce subgoals but generates a term to be used in tactic
-expressions:
-\begin{quote}
-{\tt context} {\ident} {\tt [} {\tacexpr} {\tt ]}
-\end{quote}
-{\ident} must denote a context variable bound by a {\tt context}
-pattern of a {\tt match} expression. This expression evaluates
-replaces the hole of the value of {\ident} by the value of
-{\tacexpr}.
-
-\ErrMsg \errindex{not a context variable}
-
-
-\subsubsection[Generating fresh hypothesis names]{Generating fresh hypothesis names\index{Ltac!fresh@\texttt{fresh}}
-\index{fresh@\texttt{fresh}!in Ltac}}
-
-Tactics sometimes have to generate new names for hypothesis. Letting
-the system decide a name with the {\tt intro} tactic is not so good
-since it is very awkward to retrieve the name the system gave.
-The following expression returns an identifier:
-\begin{quote}
-{\tt fresh} \nelist{\textrm{\textsl{component}}}{}
-\end{quote}
-It evaluates to an identifier unbound in the goal. This fresh
-identifier is obtained by concatenating the value of the
-\textrm{\textsl{component}}'s (each of them is, either an {\qualid} which
-has to refer to a (unqualified) name, or directly a name denoted by a
-{\qstring}). If the resulting name is already used, it is padded
-with a number so that it becomes fresh. If no component is
-given, the name is a fresh derivative of the name {\tt H}.
-
-\subsubsection[Computing in a constr]{Computing in a constr\index{Ltac!eval@\texttt{eval}}
-\index{eval@\texttt{eval}!in Ltac}}
-
-Evaluation of a term can be performed with:
-\begin{quote}
-{\tt eval} {\nterm{redexpr}} {\tt in} {\term}
-\end{quote}
-where \nterm{redexpr} is a reduction tactic among {\tt red}, {\tt
-hnf}, {\tt compute}, {\tt simpl}, {\tt cbv}, {\tt lazy}, {\tt unfold},
-{\tt fold}, {\tt pattern}.
-
-\subsubsection{Recovering the type of a term}
-%\tacindex{type of}
-\index{Ltac!type of@\texttt{type of}}
-\index{type of@\texttt{type of}!in Ltac}
-
-The following returns the type of {\term}:
-
-\begin{quote}
-{\tt type of} {\term}
-\end{quote}
-
-\subsubsection[Manipulating untyped terms]{Manipulating untyped terms\index{Ltac!uconstr@\texttt{uconstr}}
-\index{uconstr@\texttt{uconstr}!in Ltac}
-\index{Ltac!type\_term@\texttt{type\_term}}
-\index{type\_term@\texttt{type\_term}!in Ltac}}
-
-The terms built in Ltac are well-typed by default. It may not be
-appropriate for building large terms using a recursive Ltac function:
-the term has to be entirely type checked at each step, resulting in
-potentially very slow behavior. It is possible to build untyped terms
-using Ltac with the syntax
-
-\begin{quote}
-{\tt uconstr :} {\term}
-\end{quote}
-
-An untyped term, in Ltac, can contain references to hypotheses or to
-Ltac variables containing typed or untyped terms. An untyped term can
-be type-checked using the function {\tt type\_term} whose argument is
-parsed as an untyped term and returns a well-typed term which can be
-used in tactics.
-
-\begin{quote}
-{\tt type\_term} {\term}
-\end{quote}
-
-Untyped terms built using {\tt uconstr :} can also be used as
-arguments to the {\tt refine} tactic~\ref{refine}. In that case the
-untyped term is type checked against the conclusion of the goal, and
-the holes which are not solved by the typing procedure are turned into
-new subgoals.
-
-\subsubsection[Counting the goals]{Counting the goals\index{Ltac!numgoals@\texttt{numgoals}}\index{numgoals@\texttt{numgoals}!in Ltac}}
-
-The number of goals under focus can be recovered using the {\tt
- numgoals} function. Combined with the {\tt guard} command below, it
-can be used to branch over the number of goals produced by previous tactics.
-
-\begin{coq_example*}
-Ltac pr_numgoals := let n := numgoals in idtac "There are" n "goals".
-
-Goal True /\ True /\ True.
-split;[|split].
-\end{coq_example*}
-\begin{coq_example}
-all:pr_numgoals.
-\end{coq_example}
-
-\subsubsection[Testing boolean expressions]{Testing boolean expressions\index{Ltac!guard@\texttt{guard}}\index{guard@\texttt{guard}!in Ltac}}
-
-The {\tt guard} tactic tests a boolean expression, and fails if the expression evaluates to false. If the expression evaluates to true, it succeeds without affecting the proof.
-
-\begin{quote}
-{\tt guard} {\it test}
-\end{quote}
-
-The accepted tests are simple integer comparisons.
-
-\begin{coq_example*}
-Goal True /\ True /\ True.
-split;[|split].
-\end{coq_example*}
-\begin{coq_example}
-all:let n:= numgoals in guard n<4.
-Fail all:let n:= numgoals in guard n=2.
-\end{coq_example}
-\begin{ErrMsgs}
-
-\item \errindex{Condition not satisfied}
-
-\end{ErrMsgs}
-
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-
-\subsubsection[Proving a subgoal as a separate lemma]{Proving a subgoal as a separate lemma\tacindex{abstract}\tacindex{transparent\_abstract}
-\index{Tacticals!abstract@{\tt abstract}}\index{Tacticals!transparent\_abstract@{\tt transparent\_abstract}}}
-
-From the outside ``\texttt{abstract \tacexpr}'' is the same as
-{\tt solve \tacexpr}. Internally it saves an auxiliary lemma called
-{\ident}\texttt{\_subproof}\textit{n} where {\ident} is the name of the
-current goal and \textit{n} is chosen so that this is a fresh name.
-Such an auxiliary lemma is inlined in the final proof term.
-
-This tactical is useful with tactics such as \texttt{omega} or
-\texttt{discriminate} that generate huge proof terms. With that tool
-the user can avoid the explosion at time of the \texttt{Save} command
-without having to cut manually the proof in smaller lemmas.
-
-It may be useful to generate lemmas minimal w.r.t. the assumptions they depend
-on. This can be obtained thanks to the option below.
-
-\begin{Variants}
-\item \texttt{abstract {\tacexpr} using {\ident}}.\\
- Give explicitly the name of the auxiliary lemma.
- Use this feature at your own risk; explicitly named and reused subterms
- don't play well with asynchronous proofs.
-\item \texttt{transparent\_abstract {\tacexpr}}.\\
- Save the subproof in a transparent lemma rather than an opaque one.
- Use this feature at your own risk; building computationally relevant terms
- with tactics is fragile.
-\item \texttt{transparent\_abstract {\tacexpr} using {\ident}}.\\
- Give explicitly the name of the auxiliary transparent lemma.
- Use this feature at your own risk; building computationally relevant terms
- with tactics is fragile, and explicitly named and reused subterms
- don't play well with asynchronous proofs.
-\end{Variants}
-
-\ErrMsg \errindex{Proof is not complete}
-
-\section[Tactic toplevel definitions]{Tactic toplevel definitions\comindex{Ltac}}
-
-\subsection{Defining {\ltac} functions}
-
-Basically, {\ltac} toplevel definitions are made as follows:
-%{\tt Tactic Definition} {\ident} {\tt :=} {\tacexpr}\\
-%
-%{\tacexpr} is evaluated to $v$ and $v$ is associated to {\ident}. Next, every
-%script is evaluated by substituting $v$ to {\ident}.
-%
-%We can define functional definitions by:\\
-\begin{quote}
-{\tt Ltac} {\ident} {\ident}$_1$ ... {\ident}$_n$ {\tt :=}
-{\tacexpr}
-\end{quote}
-This defines a new {\ltac} function that can be used in any tactic
-script or new {\ltac} toplevel definition.
-
-\Rem The preceding definition can equivalently be written:
-\begin{quote}
-{\tt Ltac} {\ident} {\tt := fun} {\ident}$_1$ ... {\ident}$_n$
-{\tt =>} {\tacexpr}
-\end{quote}
-Recursive and mutual recursive function definitions are also
-possible with the syntax:
-\begin{quote}
-{\tt Ltac} {\ident}$_1$ {\ident}$_{1,1}$ ...
-{\ident}$_{1,m_1}$~~{\tt :=} {\tacexpr}$_1$\\
-{\tt with} {\ident}$_2$ {\ident}$_{2,1}$ ... {\ident}$_{2,m_2}$~~{\tt :=}
-{\tacexpr}$_2$\\
-...\\
-{\tt with} {\ident}$_n$ {\ident}$_{n,1}$ ... {\ident}$_{n,m_n}$~~{\tt :=}
-{\tacexpr}$_n$
-\end{quote}
-\medskip
-It is also possible to \emph{redefine} an existing user-defined tactic
-using the syntax:
-\begin{quote}
-{\tt Ltac} {\qualid} {\ident}$_1$ ... {\ident}$_n$ {\tt ::=}
-{\tacexpr}
-\end{quote}
-A previous definition of {\qualid} must exist in the environment.
-The new definition will always be used instead of the old one and
-it goes across module boundaries.
-
-If preceded by the keyword {\tt Local} the tactic definition will not
-be exported outside the current module.
-
-\subsection[Printing {\ltac} tactics]{Printing {\ltac} tactics\comindex{Print Ltac}}
-
-Defined {\ltac} functions can be displayed using the command
-
-\begin{quote}
-{\tt Print Ltac {\qualid}.}
-\end{quote}
-
-The command {\tt Print Ltac Signatures\comindex{Print Ltac Signatures}} displays a list of all user-defined tactics, with their arguments.
-
-\section{Debugging {\ltac} tactics}
-
-\subsection[Info trace]{Info trace\comindex{Info}\optindex{Info Level}}
-
-It is possible 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 {\tt Info} command can be used with the following syntax.
-
-\begin{quote}
-{\tt Info} {\num} {\tacexpr}.
-\end{quote}
-
-The number {\num} is the unfolding level of tactics in the trace. At level $0$, the trace contains a sequence of tactics in the actual script, at level $1$, the trace will be the concatenation of the traces of these tactics, etc\ldots
-
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-\begin{coq_example*}
-Ltac t x := exists x; reflexivity.
-
-Goal exists n, n=0.
-\end{coq_example*}
-\begin{coq_example}
-Info 0 t 1||t 0.
-\end{coq_example}
-\begin{coq_example*}
-Undo.
-\end{coq_example*}
-\begin{coq_example}
-Info 1 t 1||t 0.
-\end{coq_example}
-
-The trace produced by {\tt 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 {\tt Info} contains (in comments) the messages produced by the {\tt idtac} tacticals~\ref{ltac:idtac} at the right possition in the script. In particular, the calls to {\tt idtac} in branches which failed are not printed.
-
-An alternative to the {\tt Info} command is to use the {\tt Info Level} option as follows:
-
-\begin{quote}
-{\tt Set Info Level} \num.
-\end{quote}
-
-This will automatically print the same trace as {\tt Info \num} at each tactic call. The unfolding level can be overridden by a call to the {\tt Info} command. And this option can be turned off with:
-
-\begin{quote}
-{\tt Unset Info Level} \num.
-\end{quote}
-
-The current value for the {\tt Info Level} option can be checked using the {\tt Test Info Level} command.
-
-\subsection[Interactive debugger]{Interactive debugger\optindex{Ltac Debug}\optindex{Ltac Batch Debug}}
-
-The {\ltac} interpreter comes with a step-by-step debugger. The
-debugger can be activated using the command
-
-\begin{quote}
-{\tt Set Ltac Debug.}
-\end{quote}
-
-\noindent and deactivated using the command
-
-\begin{quote}
-{\tt Unset Ltac Debug.}
-\end{quote}
-
-To know if the debugger is on, use the command \texttt{Test Ltac Debug}.
-When the debugger is activated, it stops at every step of the
-evaluation of the current {\ltac} expression and it prints information
-on what it is doing. The debugger stops, prompting for a command which
-can be one of the following:
-
-\medskip
-\begin{tabular}{ll}
-simple newline: & go to the next step\\
-h: & get help\\
-x: & exit current evaluation\\
-s: & continue current evaluation without stopping\\
-r $n$: & advance $n$ steps further\\
-r {\qstring}: & advance up to the next call to ``{\tt idtac} {\qstring}''\\
-\end{tabular}
-
-A non-interactive mode for the debugger is available via the command
-
-\begin{quote}
-{\tt Set Ltac Batch Debug.}
-\end{quote}
-
-This option has the effect of presenting a newline at every prompt,
-when the debugger is on. The debug log thus created, which does not
-require user input to generate when this option is set, can then be
-run through external tools such as \texttt{diff}.
-
-\subsection[Profiling {\ltac} tactics]{Profiling {\ltac} tactics\optindex{Ltac Profiling}\comindex{Show Ltac Profile}\comindex{Reset Ltac Profile}}
-
-It is possible to measure the time spent in invocations of primitive tactics as well as tactics defined in {\ltac} and their inner invocations. The primary use is the development of complex tactics, which can sometimes be so slow as to impede interactive usage. The reasons for the performence degradation can be intricate, like a slowly performing {\ltac} match or a sub-tactic whose performance only degrades in certain situations. The profiler generates a call tree and indicates the time spent in a tactic depending its calling context. Thus it allows to locate the part of a tactic definition that contains the performance bug.
-
-\begin{quote}
-{\tt Set Ltac Profiling}.
-\end{quote}
-Enables the profiler
-
-\begin{quote}
-{\tt Unset Ltac Profiling}.
-\end{quote}
-Disables the profiler
-
-\begin{quote}
-{\tt Show Ltac Profile}.
-\end{quote}
-Prints the profile
-
-\begin{quote}
-{\tt Show Ltac Profile} {\qstring}.
-\end{quote}
-Prints a profile for all tactics that start with {\qstring}. Append a period (.) to the string if you only want exactly that name.
-
-\begin{quote}
-{\tt Reset Ltac Profile}.
-\end{quote}
-Resets the profile, that is, deletes all accumulated information. Note that backtracking across a {\tt Reset Ltac Profile} will not restore the information.
-
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-\begin{coq_example*}
-Require Import Coq.omega.Omega.
-
-Ltac mytauto := tauto.
-Ltac tac := intros; repeat split; omega || mytauto.
-
-Notation max x y := (x + (y - x)) (only parsing).
-\end{coq_example*}
-\begin{coq_example*}
-Goal forall x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z,
- max x (max y z) = max (max x y) z /\ max x (max y z) = max (max x y) z
- /\ (A /\ B /\ C /\ D /\ E /\ F /\ G /\ H /\ I /\ J /\ K /\ L /\ M /\ N /\ O /\ P /\ Q /\ R /\ S /\ T /\ U /\ V /\ W /\ X /\ Y /\ Z
- -> Z /\ Y /\ X /\ W /\ V /\ U /\ T /\ S /\ R /\ Q /\ P /\ O /\ N /\ M /\ L /\ K /\ J /\ I /\ H /\ G /\ F /\ E /\ D /\ C /\ B /\ A).
-Proof.
-\end{coq_example*}
-\begin{coq_example}
- Set Ltac Profiling.
- tac.
-\end{coq_example}
-{\let\textit\texttt% use tt mode for the output of ltacprof
-\begin{coq_example}
- Show Ltac Profile.
-\end{coq_example}
-\begin{coq_example}
- Show Ltac Profile "omega".
-\end{coq_example}
-}
-\begin{coq_example*}
-Abort.
-Unset Ltac Profiling.
-\end{coq_example*}
-
-\tacindex{start ltac profiling}\tacindex{stop ltac profiling}
-The following two tactics behave like {\tt idtac} but enable and disable the profiling. They allow you to exclude parts of a proof script from profiling.
-
-\begin{quote}
-{\tt start ltac profiling}.
-\end{quote}
-
-\begin{quote}
-{\tt stop ltac profiling}.
-\end{quote}
-
-\tacindex{reset ltac profile}\tacindex{show ltac profile}
-The following tactics behave like the corresponding vernacular commands and allow displaying and resetting the profile from tactic scripts for benchmarking purposes.
-
-\begin{quote}
-{\tt reset ltac profile}.
-\end{quote}
-
-\begin{quote}
-{\tt show ltac profile}.
-\end{quote}
-
-\begin{quote}
-{\tt show ltac profile} {\qstring}.
-\end{quote}
-
-You can also pass the {\tt -profile-ltac} command line option to {\tt coqc}, which performs a {\tt Set Ltac Profiling} at the beginning of each document, and a {\tt Show Ltac Profile} at the end.
-
-Note that the profiler currently does not handle backtracking into multi-success tactics, and issues a warning to this effect in many cases when such backtracking occurs.
-
-\subsection[Run-time optimization tactic]{Run-time optimization tactic\label{tactic-optimizeheap}}.
-
-The following tactic behaves like {\tt idtac}, and running it compacts the heap in the
-OCaml run-time system. It is analogous to the Vernacular command {\tt Optimize Heap} (see~\ref{vernac-optimizeheap}).
-
-\tacindex{optimize\_heap}
-\begin{quote}
-{\tt optimize\_heap}.
-\end{quote}
-
-\endinput
-
-\subsection{Permutation on closed lists}
-
-\begin{figure}[b]
-\begin{center}
-\fbox{\begin{minipage}{0.95\textwidth}
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-\begin{coq_example*}
-Require Import List.
-Section Sort.
-Variable A : Set.
-Inductive permut : list A -> list A -> Prop :=
- | permut_refl : forall l, permut l l
- | permut_cons :
- forall a l0 l1, permut l0 l1 -> permut (a :: l0) (a :: l1)
- | permut_append : forall a l, permut (a :: l) (l ++ a :: nil)
- | permut_trans :
- forall l0 l1 l2, permut l0 l1 -> permut l1 l2 -> permut l0 l2.
-End Sort.
-\end{coq_example*}
-\end{center}
-\caption{Definition of the permutation predicate}
-\label{permutpred}
-\end{figure}
-
-
-Another more complex example is the problem of permutation on closed
-lists. The aim is to show that a closed list is a permutation of
-another one. First, we define the permutation predicate as shown on
-Figure~\ref{permutpred}.
-
-\begin{figure}[p]
-\begin{center}
-\fbox{\begin{minipage}{0.95\textwidth}
-\begin{coq_example}
-Ltac Permut n :=
- match goal with
- | |- (permut _ ?l ?l) => apply permut_refl
- | |- (permut _ (?a :: ?l1) (?a :: ?l2)) =>
- let newn := eval compute in (length l1) in
- (apply permut_cons; Permut newn)
- | |- (permut ?A (?a :: ?l1) ?l2) =>
- match eval compute in n with
- | 1 => fail
- | _ =>
- let l1' := constr:(l1 ++ a :: nil) in
- (apply (permut_trans A (a :: l1) l1' l2);
- [ apply permut_append | compute; Permut (pred n) ])
- end
- end.
-Ltac PermutProve :=
- match goal with
- | |- (permut _ ?l1 ?l2) =>
- match eval compute in (length l1 = length l2) with
- | (?n = ?n) => Permut n
- end
- end.
-\end{coq_example}
-\end{minipage}}
-\end{center}
-\caption{Permutation tactic}
-\label{permutltac}
-\end{figure}
-
-\begin{figure}[p]
-\begin{center}
-\fbox{\begin{minipage}{0.95\textwidth}
-\begin{coq_example*}
-Lemma permut_ex1 :
- permut nat (1 :: 2 :: 3 :: nil) (3 :: 2 :: 1 :: nil).
-Proof.
-PermutProve.
-Qed.
-
-Lemma permut_ex2 :
- permut nat
- (0 :: 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: 9 :: nil)
- (0 :: 2 :: 4 :: 6 :: 8 :: 9 :: 7 :: 5 :: 3 :: 1 :: nil).
-Proof.
-PermutProve.
-Qed.
-\end{coq_example*}
-\end{minipage}}
-\end{center}
-\caption{Examples of {\tt PermutProve} use}
-\label{permutlem}
-\end{figure}
-
-Next, we can write naturally the tactic and the result can be seen on
-Figure~\ref{permutltac}. We can notice that we use two toplevel
-definitions {\tt PermutProve} and {\tt Permut}. The function to be
-called is {\tt PermutProve} which computes the lengths of the two
-lists and calls {\tt Permut} with the length if the two lists have the
-same length. {\tt Permut} works as expected. If the two lists are
-equal, it concludes. Otherwise, if the lists have identical first
-elements, it applies {\tt Permut} on the tail of the lists. Finally,
-if the lists have different first elements, it puts the first element
-of one of the lists (here the second one which appears in the {\tt
- permut} predicate) at the end if that is possible, i.e., if the new
-first element has been at this place previously. To verify that all
-rotations have been done for a list, we use the length of the list as
-an argument for {\tt Permut} and this length is decremented for each
-rotation down to, but not including, 1 because for a list of length
-$n$, we can make exactly $n-1$ rotations to generate at most $n$
-distinct lists. Here, it must be noticed that we use the natural
-numbers of {\Coq} for the rotation counter. On Figure~\ref{ltac}, we
-can see that it is possible to use usual natural numbers but they are
-only used as arguments for primitive tactics and they cannot be
-handled, in particular, we cannot make computations with them. So, a
-natural choice is to use {\Coq} data structures so that {\Coq} makes
-the computations (reductions) by {\tt eval compute in} and we can get
-the terms back by {\tt match}.
-
-With {\tt PermutProve}, we can now prove lemmas such those shown on
-Figure~\ref{permutlem}.
-
-
-\subsection{Deciding intuitionistic propositional logic}
-
-\begin{figure}[tbp]
-\begin{center}
-\fbox{\begin{minipage}{0.95\textwidth}
-\begin{coq_example}
-Ltac Axioms :=
- match goal with
- | |- True => trivial
- | _:False |- _ => elimtype False; assumption
- | _:?A |- ?A => auto
- end.
-Ltac DSimplif :=
- repeat
- (intros;
- match goal with
- | id:(~ _) |- _ => red in id
- | id:(_ /\ _) |- _ =>
- elim id; do 2 intro; clear id
- | id:(_ \/ _) |- _ =>
- elim id; intro; clear id
- | id:(?A /\ ?B -> ?C) |- _ =>
- cut (A -> B -> C);
- [ intro | intros; apply id; split; assumption ]
- | id:(?A \/ ?B -> ?C) |- _ =>
- cut (B -> C);
- [ cut (A -> C);
- [ intros; clear id
- | intro; apply id; left; assumption ]
- | intro; apply id; right; assumption ]
- | id0:(?A -> ?B),id1:?A |- _ =>
- cut B; [ intro; clear id0 | apply id0; assumption ]
- | |- (_ /\ _) => split
- | |- (~ _) => red
- end).
-\end{coq_example}
-\end{minipage}}
-\end{center}
-\caption{Deciding intuitionistic propositions (1)}
-\label{tautoltaca}
-\end{figure}
-
-\begin{figure}
-\begin{center}
-\fbox{\begin{minipage}{0.95\textwidth}
-\begin{coq_example}
-Ltac TautoProp :=
- DSimplif;
- Axioms ||
- match goal with
- | id:((?A -> ?B) -> ?C) |- _ =>
- cut (B -> C);
- [ intro; cut (A -> B);
- [ intro; cut C;
- [ intro; clear id | apply id; assumption ]
- | clear id ]
- | intro; apply id; intro; assumption ]; TautoProp
- | id:(~ ?A -> ?B) |- _ =>
- cut (False -> B);
- [ intro; cut (A -> False);
- [ intro; cut B;
- [ intro; clear id | apply id; assumption ]
- | clear id ]
- | intro; apply id; red; intro; assumption ]; TautoProp
- | |- (_ \/ _) => (left; TautoProp) || (right; TautoProp)
- end.
-\end{coq_example}
-\end{minipage}}
-\end{center}
-\caption{Deciding intuitionistic propositions (2)}
-\label{tautoltacb}
-\end{figure}
-
-The pattern matching on goals allows a complete and so a powerful
-backtracking when returning tactic values. An interesting application
-is the problem of deciding intuitionistic propositional logic.
-Considering the contraction-free sequent calculi {\tt LJT*} of
-Roy~Dyckhoff (\cite{Dyc92}), it is quite natural to code such a tactic
-using the tactic language. On Figure~\ref{tautoltaca}, the tactic {\tt
- Axioms} tries to conclude using usual axioms. The {\tt DSimplif}
-tactic applies all the reversible rules of Dyckhoff's system.
-Finally, on Figure~\ref{tautoltacb}, the {\tt TautoProp} tactic (the
-main tactic to be called) simplifies with {\tt DSimplif}, tries to
-conclude with {\tt Axioms} and tries several paths using the
-backtracking rules (one of the four Dyckhoff's rules for the left
-implication to get rid of the contraction and the right or).
-
-\begin{figure}[tb]
-\begin{center}
-\fbox{\begin{minipage}{0.95\textwidth}
-\begin{coq_example*}
-Lemma tauto_ex1 : forall A B:Prop, A /\ B -> A \/ B.
-Proof.
-TautoProp.
-Qed.
-
-Lemma tauto_ex2 :
- forall A B:Prop, (~ ~ B -> B) -> (A -> B) -> ~ ~ A -> B.
-Proof.
-TautoProp.
-Qed.
-\end{coq_example*}
-\end{minipage}}
-\end{center}
-\caption{Proofs of tautologies with {\tt TautoProp}}
-\label{tautolem}
-\end{figure}
-
-For example, with {\tt TautoProp}, we can prove tautologies like those of
-Figure~\ref{tautolem}.
-
-
-\subsection{Deciding type isomorphisms}
-
-A more tricky problem is to decide equalities between types and modulo
-isomorphisms. Here, we choose to use the isomorphisms of the simply typed
-$\lb{}$-calculus with Cartesian product and $unit$ type (see, for example,
-\cite{RC95}). The axioms of this $\lb{}$-calculus are given by
-Figure~\ref{isosax}.
-
-\begin{figure}
-\begin{center}
-\fbox{\begin{minipage}{0.95\textwidth}
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-\begin{coq_example*}
-Open Scope type_scope.
-Section Iso_axioms.
-Variables A B C : Set.
-Axiom Com : A * B = B * A.
-Axiom Ass : A * (B * C) = A * B * C.
-Axiom Cur : (A * B -> C) = (A -> B -> C).
-Axiom Dis : (A -> B * C) = (A -> B) * (A -> C).
-Axiom P_unit : A * unit = A.
-Axiom AR_unit : (A -> unit) = unit.
-Axiom AL_unit : (unit -> A) = A.
-Lemma Cons : B = C -> A * B = A * C.
-Proof.
-intro Heq; rewrite Heq; reflexivity.
-Qed.
-End Iso_axioms.
-\end{coq_example*}
-\end{minipage}}
-\end{center}
-\caption{Type isomorphism axioms}
-\label{isosax}
-\end{figure}
-
-The tactic to judge equalities modulo this axiomatization can be written as
-shown on Figures~\ref{isosltac1} and~\ref{isosltac2}. The algorithm is quite
-simple. Types are reduced using axioms that can be oriented (this done by {\tt
-MainSimplif}). The normal forms are sequences of Cartesian
-products without Cartesian product in the left component. These normal forms
-are then compared modulo permutation of the components (this is done by {\tt
-CompareStruct}). The main tactic to be called and realizing this algorithm is
-{\tt IsoProve}.
-
-\begin{figure}
-\begin{center}
-\fbox{\begin{minipage}{0.95\textwidth}
-\begin{coq_example}
-Ltac DSimplif trm :=
- match trm with
- | (?A * ?B * ?C) =>
- rewrite <- (Ass A B C); try MainSimplif
- | (?A * ?B -> ?C) =>
- rewrite (Cur A B C); try MainSimplif
- | (?A -> ?B * ?C) =>
- rewrite (Dis A B C); try MainSimplif
- | (?A * unit) =>
- rewrite (P_unit A); try MainSimplif
- | (unit * ?B) =>
- rewrite (Com unit B); try MainSimplif
- | (?A -> unit) =>
- rewrite (AR_unit A); try MainSimplif
- | (unit -> ?B) =>
- rewrite (AL_unit B); try MainSimplif
- | (?A * ?B) =>
- (DSimplif A; try MainSimplif) || (DSimplif B; try MainSimplif)
- | (?A -> ?B) =>
- (DSimplif A; try MainSimplif) || (DSimplif B; try MainSimplif)
- end
- with MainSimplif :=
- match goal with
- | |- (?A = ?B) => try DSimplif A; try DSimplif B
- end.
-Ltac Length trm :=
- match trm with
- | (_ * ?B) => let succ := Length B in constr:(S succ)
- | _ => constr:1
- end.
-Ltac assoc := repeat rewrite <- Ass.
-\end{coq_example}
-\end{minipage}}
-\end{center}
-\caption{Type isomorphism tactic (1)}
-\label{isosltac1}
-\end{figure}
-
-\begin{figure}
-\begin{center}
-\fbox{\begin{minipage}{0.95\textwidth}
-\begin{coq_example}
-Ltac DoCompare n :=
- match goal with
- | [ |- (?A = ?A) ] => reflexivity
- | [ |- (?A * ?B = ?A * ?C) ] =>
- apply Cons; let newn := Length B in DoCompare newn
- | [ |- (?A * ?B = ?C) ] =>
- match eval compute in n with
- | 1 => fail
- | _ =>
- pattern (A * B) at 1; rewrite Com; assoc; DoCompare (pred n)
- end
- end.
-Ltac CompareStruct :=
- match goal with
- | [ |- (?A = ?B) ] =>
- let l1 := Length A
- with l2 := Length B in
- match eval compute in (l1 = l2) with
- | (?n = ?n) => DoCompare n
- end
- end.
-Ltac IsoProve := MainSimplif; CompareStruct.
-\end{coq_example}
-\end{minipage}}
-\end{center}
-\caption{Type isomorphism tactic (2)}
-\label{isosltac2}
-\end{figure}
-
-Figure~\ref{isoslem} gives examples of what can be solved by {\tt IsoProve}.
-
-\begin{figure}
-\begin{center}
-\fbox{\begin{minipage}{0.95\textwidth}
-\begin{coq_example*}
-Lemma isos_ex1 :
- forall A B:Set, A * unit * B = B * (unit * A).
-Proof.
-intros; IsoProve.
-Qed.
-
-Lemma isos_ex2 :
- forall A B C:Set,
- (A * unit -> B * (C * unit)) =
- (A * unit -> (C -> unit) * C) * (unit -> A -> B).
-Proof.
-intros; IsoProve.
-Qed.
-\end{coq_example*}
-\end{minipage}}
-\end{center}
-\caption{Type equalities solved by {\tt IsoProve}}
-\label{isoslem}
-\end{figure}
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
diff --git a/doc/refman/Reference-Manual.tex b/doc/refman/Reference-Manual.tex
deleted file mode 100644
index 061686e12..000000000
--- a/doc/refman/Reference-Manual.tex
+++ /dev/null
@@ -1,136 +0,0 @@
-%\RequirePackage{ifpdf}
-%\ifpdf
-% \documentclass[11pt,a4paper,pdftex]{book}
-%\else
- \documentclass[11pt,a4paper]{book}
-%\fi
-
-\usepackage[utf8]{inputenc}
-\usepackage[T1]{fontenc}
-\usepackage{textcomp}
-\usepackage{times}
-\usepackage{url}
-\usepackage{verbatim}
-\usepackage{amsmath}
-\usepackage{amssymb}
-\usepackage{alltt}
-\usepackage{hevea}
-\usepackage{ifpdf}
-\usepackage[headings]{fullpage}
-\usepackage{headers} % in this directory
-\usepackage{multicol}
-\usepackage{xspace}
-\usepackage{pmboxdraw}
-\usepackage{float}
-\usepackage{color}
- \definecolor{dkblue}{rgb}{0,0.1,0.5}
- \definecolor{lightblue}{rgb}{0,0.5,0.5}
- \definecolor{dkgreen}{rgb}{0,0.4,0}
- \definecolor{dk2green}{rgb}{0.4,0,0}
- \definecolor{dkviolet}{rgb}{0.6,0,0.8}
- \definecolor{dkpink}{rgb}{0.2,0,0.6}
-\usepackage{listings}
- \def\lstlanguagefiles{coq-listing.tex}
-\usepackage{tabularx}
-\usepackage{array,longtable}
-
-\floatstyle{boxed}
-\restylefloat{figure}
-
-% for coqide
-\ifpdf % si on est pas en pdflatex
- \usepackage[pdftex]{graphicx}
-\else
- \usepackage[dvips]{graphicx}
-\fi
-
-
-%\includeonly{Setoid}
-
-\input{../common/version.tex}
-\input{../common/macros.tex}% extension .tex pour htmlgen
-\input{../common/title.tex}% extension .tex pour htmlgen
-%\input{headers}
-
-\usepackage[linktocpage,colorlinks,bookmarks=true,bookmarksnumbered=true]{hyperref}
-% The manual advises to load hyperref package last to be able to redefine
-% necessary commands.
-% The above should work for both latex and pdflatex. Even if PDF is produced
-% through DVI and PS using dvips and ps2pdf, hyperlinks should still work.
-% linktocpage option makes page numbers, not section names, to be links in
-% the table of contents.
-% colorlinks option colors the links instead of using boxes.
-
-% The command \tocnumber was added to HEVEA in version 1.06-6.
-% It instructs HEVEA to put chapter numbers into the table of
-% content entries. The table of content is produced by HACHA using
-% the options -tocbis -o toc.html. HEVEA produces a warning when
-% a command is not recognized, so versions earlier than 1.06-6 can
-% still be used.
-%HEVEA\tocnumber
-
-\begin{document}
-%BEGIN LATEX
-\sloppy\hbadness=5000
-%END LATEX
-
-%BEGIN LATEX
-\coverpage{Reference Manual}
-{The Coq Development Team}
-{This material may be distributed only subject to the terms and
-conditions set forth in the Open Publication License, v1.0 or later
-(the latest version is presently available at
-\url{http://www.opencontent.org/openpub}).
-Options A and B of the licence are {\em not} elected.}
-%END LATEX
-
-%\defaultheaders
-
-%BEGIN LATEX
-\tableofcontents
-%END LATEX
-
-\part{The language}
-%BEGIN LATEX
-\defaultheaders
-%END LATEX
-\include{RefMan-gal.v}% Gallina
-
-
-\part{The proof engine}
-\include{RefMan-ltac.v}% Writing tactics
-
-\lstset{language=SSR}
-\lstset{moredelim=[is][]{|*}{*|}}
-\lstset{moredelim=*[is][\itshape\rmfamily]{/*}{*/}}
-
-%BEGIN LATEX
-\RefManCutCommand{BEGINADDENDUM=\thepage}
-%END LATEX
-\part{Addendum to the Reference Manual}
-\include{AddRefMan-pre}%
-\include{Universes.v}% Universe polymorphes
-%BEGIN LATEX
-\RefManCutCommand{ENDADDENDUM=\thepage}
-%END LATEX
-\nocite{*}
-\bibliographystyle{plain}
-\bibliography{biblio}
-\cutname{biblio.html}
-
-\printrefmanindex{default}{Global Index}{general-index.html}
-\printrefmanindex{tactic}{Tactics Index}{tactic-index.html}
-\printrefmanindex{command}{Vernacular Commands Index}{command-index.html}
-\printrefmanindex{option}{Vernacular Options Index}{option-index.html}
-\printrefmanindex{error}{Index of Error Messages}{error-index.html}
-
-%BEGIN LATEX
-\cleardoublepage
-\phantomsection
-\addcontentsline{toc}{chapter}{\listfigurename}
-\listoffigures
-%END LATEX
-
-\end{document}
-
-
diff --git a/doc/refman/Universes.tex b/doc/refman/Universes.tex
deleted file mode 100644
index c7d39c0f3..000000000
--- a/doc/refman/Universes.tex
+++ /dev/null
@@ -1,393 +0,0 @@
-\achapter{Polymorphic Universes}
-%HEVEA\cutname{universes.html}
-\aauthor{Matthieu Sozeau}
-
-\label{Universes-full}
-\index{Universes!presentation}
-
-\asection{General Presentation}
-
-\begin{flushleft}
- \em The status of Universe Polymorphism is experimental.
-\end{flushleft}
-
-This section describes the universe polymorphic extension of Coq.
-Universe polymorphism makes it possible to write generic definitions making use of
-universes and reuse them at different and sometimes incompatible universe levels.
-
-A standard example of the difference between universe \emph{polymorphic} and
-\emph{monomorphic} definitions is given by the identity function:
-
-\begin{coq_example*}
-Definition identity {A : Type} (a : A) := a.
-\end{coq_example*}
-
-By default, constant declarations are monomorphic, hence the identity
-function declares a global universe (say \texttt{Top.1}) for its
-domain. Subsequently, if we try to self-apply the identity, we will get
-an error:
-
-\begin{coq_eval}
-Set Printing Universes.
-\end{coq_eval}
-\begin{coq_example}
-Fail Definition selfid := identity (@identity).
-\end{coq_example}
-
-Indeed, the global level \texttt{Top.1} would have to be strictly smaller than itself
-for this self-application to typecheck, as the type of \texttt{(@identity)} is
-\texttt{forall (A : Type@{Top.1}), A -> A} whose type is itself \texttt{Type@{Top.1+1}}.
-
-A universe polymorphic identity function binds its domain universe level
-at the definition level instead of making it global.
-
-\begin{coq_example}
-Polymorphic Definition pidentity {A : Type} (a : A) := a.
-About pidentity.
-\end{coq_example}
-
-It is then possible to reuse the constant at different levels, like so:
-
-\begin{coq_example}
-Definition selfpid := pidentity (@pidentity).
-\end{coq_example}
-
-Of course, the two instances of \texttt{pidentity} in this definition
-are different. This can be seen when \texttt{Set Printing Universes} is
-on:
-
-\begin{coq_example}
-Print selfpid.
-\end{coq_example}
-
-Now \texttt{pidentity} is used at two different levels: at the head of
-the application it is instantiated at \texttt{Top.3} while in the
-argument position it is instantiated at \texttt{Top.4}. This definition
-is only valid as long as \texttt{Top.4} is strictly smaller than
-\texttt{Top.3}, as show by the constraints. Note that this definition is
-monomorphic (not universe polymorphic), so the two universes
-(in this case \texttt{Top.3} and \texttt{Top.4}) are actually global levels.
-
-When printing \texttt{pidentity}, we can see the universes it binds in
-the annotation \texttt{@\{Top.2\}}. Additionally, when \texttt{Set
- Printing Universes} is on we print the ``universe context'' of
-\texttt{pidentity} consisting of the bound universes and the
-constraints they must verify (for \texttt{pidentity} there are no
-constraints).
-
-Inductive types can also be declared universes polymorphic on universes
-appearing in their parameters or fields. A typical example is given by
-monoids:
-
-\begin{coq_example}
-Polymorphic Record Monoid := { mon_car :> Type; mon_unit : mon_car;
- mon_op : mon_car -> mon_car -> mon_car }.
-Print Monoid.
-\end{coq_example}
-
-The \texttt{Monoid}'s carrier universe is polymorphic, hence it is
-possible to instantiate it for example with \texttt{Monoid} itself.
-First we build the trivial unit monoid in \texttt{Set}:
-\begin{coq_example}
-Definition unit_monoid : Monoid :=
- {| mon_car := unit; mon_unit := tt; mon_op x y := tt |}.
-\end{coq_example}
-
-From this we can build a definition for the monoid of
-\texttt{Set}-monoids (where multiplication would be given by the product
-of monoids).
-
-\begin{coq_example*}
-Polymorphic Definition monoid_monoid : Monoid.
- refine (@Build_Monoid Monoid unit_monoid (fun x y => x)).
-Defined.
-\end{coq_example*}
-\begin{coq_example}
-Print monoid_monoid.
-\end{coq_example}
-
-As one can see from the constraints, this monoid is ``large'', it lives
-in a universe strictly higher than \texttt{Set}.
-
-\asection{\tt Polymorphic, Monomorphic}
-\comindex{Polymorphic}
-\comindex{Monomorphic}
-\optindex{Universe Polymorphism}
-
-As shown in the examples, polymorphic definitions and inductives can be
-declared using the \texttt{Polymorphic} prefix. There also exists an
-option \texttt{Set Universe Polymorphism} which will implicitly prepend
-it to any definition of the user. In that case, to make a definition
-producing global universe constraints, one can use the
-\texttt{Monomorphic} prefix. Many other commands support the
-\texttt{Polymorphic} flag, including:
-
-\begin{itemize}
-\item \texttt{Lemma}, \texttt{Axiom}, and all the other ``definition''
- keywords support polymorphism.
-\item \texttt{Variables}, \texttt{Context}, \texttt{Universe} and
- \texttt{Constraint} in a section support polymorphism. This means
- that the universe variables (and associated constraints) are
- discharged polymorphically over definitions that use them. In other
- words, two definitions in the section sharing a common variable will
- both get parameterized by the universes produced by the variable
- declaration. This is in contrast to a ``mononorphic'' variable which
- introduces global universes and constraints, making the two
- definitions depend on the \emph{same} global universes associated to
- the variable.
-\item \texttt{Hint \{Resolve, Rewrite\}} will use the auto/rewrite hint
- polymorphically, not at a single instance.
-\end{itemize}
-
-\asection{{\tt Cumulative, NonCumulative}}
-\comindex{Cumulative}
-\comindex{NonCumulative}
-\optindex{Polymorphic Inductive Cumulativity}
-
-Polymorphic inductive types, coinductive types, variants and records can be
-declared cumulative using the \texttt{Cumulative} prefix. Alternatively,
-there is an option \texttt{Set Polymorphic Inductive Cumulativity} which when set,
-makes all subsequent \emph{polymorphic} inductive definitions cumulative. When set,
-inductive types and the like can be enforced to be
-\emph{non-cumulative} using the \texttt{NonCumulative} prefix. Consider the examples below.
-\begin{coq_example*}
-Polymorphic Cumulative Inductive list {A : Type} :=
-| nil : list
-| cons : A -> list -> list.
-\end{coq_example*}
-\begin{coq_example}
-Print list.
-\end{coq_example}
-When printing \texttt{list}, the universe context indicates the
-subtyping constraints by prefixing the level names with symbols.
-
-Because inductive subtypings are only produced by comparing inductives
-to themselves with universes changed, they amount to variance
-information: each universe is either invariant, covariant or
-irrelevant (there are no contravariant subtypings in Coq),
-respectively represented by the symbols \texttt{=}, \texttt{+} and
-\texttt{*}.
-
-Here we see that \texttt{list} binds an irrelevant universe, so any
-two instances of \texttt{list} are convertible:
-$\WTEGCONV{\mathtt{list@\{i\}} A}{\mathtt{list@\{j\}} B}$ whenever
-$\WTEGCONV{A}{B}$ and furthermore their corresponding (when fully
-applied to convertible arguments) constructors.
-
-See Chapter~\ref{Cic} for more details on convertibility and subtyping.
-The following is an example of a record with non-trivial subtyping relation:
-\begin{coq_example*}
-Polymorphic Cumulative Record packType := {pk : Type}.
-\end{coq_example*}
-\begin{coq_example}
-Print packType.
-\end{coq_example}
-\texttt{packType} binds a covariant universe, i.e.
-$\WTEGCONV{\mathtt{packType@\{i\}}}{\mathtt{packType@\{j\}}}$ whenever
-\texttt{i $\leq$ j}.
-
-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 \texttt{Cumulative} or
-\texttt{NonCumulative} prefix in a monomorphic context.
-Notice that this is not the case for the option \texttt{Set Polymorphic Inductive Cumulativity}.
-That is, this option, when set, makes all subsequent \emph{polymorphic}
-inductive declarations cumulative (unless, of course the \texttt{NonCumulative} prefix is used)
-but has no effect on \emph{monomorphic} inductive declarations.
-Consider the following examples.
-\begin{coq_example}
-Monomorphic Cumulative Inductive Unit := unit.
-\end{coq_example}
-\begin{coq_example}
-Monomorphic NonCumulative Inductive Unit := unit.
-\end{coq_example}
-\begin{coq_example*}
-Set Polymorphic Inductive Cumulativity.
-Inductive Unit := unit.
-\end{coq_example*}
-\begin{coq_example}
-Print Unit.
-\end{coq_example}
-
-\subsection*{An example of a proof using cumulativity}
-
-\begin{coq_example}
-Set Universe Polymorphism.
-Set Polymorphic Inductive Cumulativity.
-
-Inductive eq@{i} {A : Type@{i}} (x : A) : A -> Type@{i} := eq_refl : eq x x.
-
-Definition funext_type@{a b e} (A : Type@{a}) (B : A -> Type@{b})
- := forall f g : (forall a, B a),
- (forall x, eq@{e} (f x) (g x))
- -> eq@{e} f g.
-
-Section down.
- Universes a b e e'.
- Constraint e' < e.
- Lemma funext_down {A B}
- (H : @funext_type@{a b e} A B) : @funext_type@{a b e'} A B.
- Proof.
- exact H.
- Defined.
-\end{coq_example}
-
-\subsection{\tt Cumulativity Weak Constraints}
-\optindex{Cumulativity Weak Constraints}
-
-This option, on by default, causes ``weak'' constraints to be produced
-when comparing universes in an irrelevant position. Processing weak
-constraints is delayed until minimization time. A weak constraint
-between {\tt u} and {\tt v} when neither is smaller than the other and
-one is flexible causes them to be unified. Otherwise the constraint is
-silently discarded.
-
-This heuristic is experimental and may change in future versions.
-Disabling weak constraints is more predictable but may produce
-arbitrary numbers of universes.
-
-\asection{Global and local universes}
-
-Each universe is declared in a global or local environment before it can
-be used. To ensure compatibility, every \emph{global} universe is set to
-be strictly greater than \Set~when it is introduced, while every
-\emph{local} (i.e. polymorphically quantified) universe is introduced as
-greater or equal to \Set.
-
-\asection{Conversion and unification}
-
-The semantics of conversion and unification have to be modified a little
-to account for the new universe instance arguments to polymorphic
-references. The semantics respect the fact that definitions are
-transparent, so indistinguishable from their bodies during conversion.
-
-This is accomplished by changing one rule of unification, the
-first-order approximation rule, which applies when two applicative terms
-with the same head are compared. It tries to short-cut unfolding by
-comparing the arguments directly. In case the constant is universe
-polymorphic, we allow this rule to fire only when unifying the universes
-results in instantiating a so-called flexible universe variables (not
-given by the user). Similarly for conversion, if such an equation of
-applicative terms fail due to a universe comparison not being satisfied,
-the terms are unfolded. This change implies that conversion and
-unification can have different unfolding behaviors on the same
-development with universe polymorphism switched on or off.
-
-\asection{Minimization}
-\optindex{Universe Minimization ToSet}
-
-Universe polymorphism with cumulativity tends to generate many useless
-inclusion constraints in general. Typically at each application of a
-polymorphic constant $f$, if an argument has expected type
-\verb|Type@{i}| and is given a term of type \verb|Type@{j}|, a $j \le i$
-constraint will be generated. It is however often the case that an
-equation $j = i$ would be more appropriate, when $f$'s
-universes are fresh for example. Consider the following example:
-
-\begin{coq_eval}
-Set Printing Universes.
-\end{coq_eval}
-\begin{coq_example}
-Definition id0 := @pidentity nat 0.
-Print id0.
-\end{coq_example}
-
-This definition is elaborated by minimizing the universe of id to level
-\Set~while the more general definition would keep the fresh level i
-generated at the application of id and a constraint that $\Set \le i$.
-This minimization process is applied only to fresh universe
-variables. It simply adds an equation between the variable and its lower
-bound if it is an atomic universe (i.e. not an algebraic \texttt{max()}
-universe).
-
-The option \texttt{Unset Universe Minimization ToSet} disallows
-minimization to the sort $\Set$ and only collapses floating universes
-between themselves.
-
-\asection{Explicit Universes}
-
-The syntax has been extended to allow users to explicitly bind names to
-universes and explicitly instantiate polymorphic definitions.
-
-\subsection{\tt Universe {\ident}.
- \comindex{Universe}
- \label{UniverseCmd}}
-
-In the monorphic case, this command declares a new global universe named
-{\ident}, which can be referred to using its qualified name as
-well. Global universe names live in a separate namespace. The command
-supports the polymorphic flag only in sections, meaning the universe
-quantification will be discharged on each section definition
-independently. One cannot mix polymorphic and monomorphic declarations
-in the same section.
-
-\subsection{\tt Constraint {\ident} {\textit{ord}} {\ident}.
- \comindex{Constraint}
- \label{ConstraintCmd}}
-
-This command declares a new constraint between named universes.
-The order relation can be one of $<$, $\le$ or $=$. If consistent,
-the constraint is then enforced in the global environment. Like
-\texttt{Universe}, it can be used with the \texttt{Polymorphic} prefix
-in sections only to declare constraints discharged at section closing time.
-One cannot declare a global constraint on polymorphic universes.
-
-\begin{ErrMsgs}
-\item \errindex{Undeclared universe {\ident}}.
-\item \errindex{Universe inconsistency}
-\end{ErrMsgs}
-
-\subsection{Polymorphic definitions}
-For polymorphic definitions, the declaration of (all) universe levels
-introduced by a definition uses the following syntax:
-
-\begin{coq_example*}
-Polymorphic Definition le@{i j} (A : Type@{i}) : Type@{j} := A.
-\end{coq_example*}
-\begin{coq_example}
-Print le.
-\end{coq_example}
-
-During refinement we find that $j$ must be larger or equal than $i$, as
-we are using $A : Type@{i} <= Type@{j}$, hence the generated
-constraint. At the 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 \texttt{Show Universes} to display
-the current context of universes.
-
-Definitions can also be instantiated explicitly, giving their full instance:
-\begin{coq_example}
-Check (pidentity@{Set}).
-Universes k l.
-Check (le@{k l}).
-\end{coq_example}
-
-User-named universes and the anonymous universe implicitly attached to
-an explicit $Type$ are considered rigid for unification and are never
-minimized. Flexible anonymous universes can be produced with an
-underscore or by omitting the annotation to a polymorphic definition.
-
-\begin{coq_example}
- Check (fun x => x) : Type -> Type.
- Check (fun x => x) : Type -> Type@{_}.
-
- Check le@{k _}.
- Check le.
-\end{coq_example}
-
-\subsection{\tt Unset Strict Universe Declaration.
- \optindex{Strict Universe Declaration}
- \label{StrictUniverseDeclaration}}
-
-The command \texttt{Unset Strict Universe Declaration} 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
-defined. This is meant mainly for debugging purposes.
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
diff --git a/doc/refman/biblio.bib b/doc/refman/biblio.bib
deleted file mode 100644
index e69725838..000000000
--- a/doc/refman/biblio.bib
+++ /dev/null
@@ -1,1397 +0,0 @@
-@String{jfp = "Journal of Functional Programming"}
-@String{lncs = "Lecture Notes in Computer Science"}
-@String{lnai = "Lecture Notes in Artificial Intelligence"}
-@String{SV = "{Sprin-ger-Verlag}"}
-
-@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 = {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}
-}
-
-@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}
-}
-
-@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{Bee85,
- author = {M.J. Beeson},
- publisher = SV,
- title = {Foundations of Constructive Mathematics, Metamathematical Studies},
- year = {1985}
-}
-
-@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}
-}
-
-@InProceedings{Bou97,
- title = {Using reflection to build efficient and certified decision procedure
-s},
- author = {S. Boutin},
- booktitle = {TACS'97},
- editor = {Martin Abadi and Takahashi Ito},
- publisher = SV,
- series = lncs,
- volume = 1281,
- year = {1997}
-}
-
-@PhDThesis{Bou97These,
- author = {S. Boutin},
- title = {R\'eflexions sur les quotients},
- school = {Paris 7},
- year = 1997,
- type = {th\`ese d'Universit\'e},
- month = apr
-}
-
-@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{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}
-}
-
-@TechReport{COQ02,
- author = {The Coq Development Team},
- institution = {INRIA},
- month = Feb,
- number = {255},
- title = {{The Coq Proof Assistant Reference Manual Version 7.2}},
- year = {2002}
-}
-
-@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}
-}
-
-@Book{Caml,
- author = {P. Weis and X. Leroy},
- publisher = {InterEditions},
- title = {Le langage Caml},
- year = {1993}
-}
-
-@InProceedings{ChiPotSimp03,
- author = {Laurent Chicli and Lo\"{\i}c Pottier and Carlos Simpson},
- title = {Mathematical Quotients and Quotient Types in Coq},
- booktitle = {TYPES},
- crossref = {DBLP:conf/types/2002},
- year = {2002}
-}
-
-@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 = SV,
- series = LNCS,
- title = {{Constructions : A Higher Order Proof System for Mechanizing Mathematics}},
- volume = {203},
- year = {1985}
-}
-
-@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}
-}
-
-@InProceedings{CoPa89,
- author = {Th. Coquand and C. Paulin-Mohring},
- booktitle = {Proceedings of Colog'88},
- editor = {P. Martin-L\"of and G. Mints},
- publisher = SV,
- series = LNCS,
- title = {Inductively defined types},
- volume = {417},
- year = {1990}
-}
-
-@Book{Con86,
- author = {R.L. {Constable et al.}},
- publisher = {Prentice-Hall},
- title = {{Implementing Mathematics with the Nuprl Proof Development System}},
- year = {1986}
-}
-
-@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{Coq91,
- author = {Th. Coquand},
- booktitle = {Proceedings 9th Int. Congress of Logic, Methodology and Philosophy of Science},
- title = {{A New Paradox in Type Theory}},
- month = {August},
- year = {1991}
-}
-
-@InProceedings{Coq92,
- author = {Th. Coquand},
- title = {{Pattern Matching with Dependent Types}},
- year = {1992},
- crossref = {Bastad92}
-}
-
-@InProceedings{Coquand93,
- author = {Th. Coquand},
- booktitle = {Types for Proofs and Programs},
- editor = {H. Barendregt and T. Nipokow},
- publisher = SV,
- series = LNCS,
- title = {{Infinite objects in Type Theory}},
- volume = {806},
- year = {1993},
- pages = {62-78}
-}
-
-@inproceedings{Corbineau08types,
- author = {P. Corbineau},
- title = {A Declarative Language for the Coq Proof Assistant},
- editor = {M. Miculan and I. Scagnetto and F. Honsell},
- booktitle = {TYPES '07, Cividale del Friuli, Revised Selected Papers},
- publisher = {Springer},
- series = LNCS,
- volume = {4941},
- year = {2007},
- pages = {69-84},
- ee = {http://dx.doi.org/10.1007/978-3-540-68103-8_5},
-}
-
-@PhDThesis{Cor97,
- author = {C. Cornes},
- month = nov,
- school = {{Universit\'e Paris 7}},
- title = {Conception d'un langage de haut niveau de représentation de preuves},
- type = {Th\`ese de Doctorat},
- year = {1997}
-}
-
-@MastersThesis{Cou94a,
- author = {J. Courant},
- month = sep,
- school = {DEA d'Informatique, ENS Lyon},
- title = {Explicitation de preuves par r\'ecurrence implicite},
- year = {1994}
-}
-
-@book{Cur58,
- author = {Haskell B. Curry and Robert Feys and William Craig},
- title = {Combinatory Logic},
- volume = 1,
- publisher = "North-Holland",
- year = 1958,
- note = {{\S{9E}}},
-}
-
-@InProceedings{Del99,
- author = {Delahaye, D.},
- title = {Information Retrieval in a Coq Proof Library using
- Type Isomorphisms},
- booktitle = {Proceedings of TYPES '99, L\"okeberg},
- publisher = SV,
- series = lncs,
- year = {1999},
- url =
- "\\{\sf ftp://ftp.inria.fr/INRIA/Projects/coq/David.Delahaye/papers/}"#
- "{\sf TYPES99-SIsos.ps.gz}"
-}
-
-@InProceedings{Del00,
- author = {Delahaye, D.},
- title = {A {T}actic {L}anguage for the {S}ystem {{\sf Coq}}},
- booktitle = {Proceedings of Logic for Programming and Automated Reasoning
- (LPAR), Reunion Island},
- publisher = SV,
- series = LNCS,
- volume = {1955},
- pages = {85--95},
- month = {November},
- year = {2000},
- url =
- "{\sf ftp://ftp.inria.fr/INRIA/Projects/coq/David.Delahaye/papers/}"#
- "{\sf LPAR2000-ltac.ps.gz}"
-}
-
-@InProceedings{DelMay01,
- author = {Delahaye, D. and Mayero, M.},
- title = {{\tt Field}: une proc\'edure de d\'ecision pour les nombres r\'eels en {\Coq}},
- booktitle = {Journ\'ees Francophones des Langages Applicatifs, Pontarlier},
- publisher = {INRIA},
- month = {Janvier},
- year = {2001},
- url =
- "\\{\sf ftp://ftp.inria.fr/INRIA/Projects/coq/David.Delahaye/papers/}"#
- "{\sf JFLA2000-Field.ps.gz}"
-}
-
-@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-Rendus 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 = SV,
- 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{Dow92a,
- author = {G. Dowek},
- title = {The Undecidability of Pattern Matching in Calculi where Primitive Recursive Functions are Representable},
- year = 1993,
- journal = tcs,
- volume = 107,
- number = 2,
- pages = {349-356}
-}
-
-@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ö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 Calcul des Pr\'edicats Direct. Étude et impl\'ementation dans le syst\`eme {\Coq}},
- 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}
-}
-
-@Article{Filliatre03jfp,
- author = {J.-C. Filliâtre},
- title = {Verification of Non-Functional Programs
- using Interpretations in Type Theory},
- journal = jfp,
- volume = 13,
- number = 4,
- pages = {709--745},
- month = jul,
- year = 2003,
- note = {[English translation of \cite{Filliatre99}]},
- url = {http://www.lri.fr/~filliatr/ftp/publis/jphd.ps.gz},
- topics = {team, lri},
- type_publi = {irevcomlec}
-}
-
-@PhDThesis{Filliatre99,
- author = {J.-C. Filli\^atre},
- title = {Preuve de programmes imp\'eratifs en th\'eorie des types},
- type = {Thèse de Doctorat},
- school = {Universit\'e Paris-Sud},
- year = 1999,
- month = {July},
- url = {\url{http://www.lri.fr/~filliatr/ftp/publis/these.ps.gz}}
-}
-
-@Unpublished{Filliatre99c,
- author = {J.-C. Filli\^atre},
- title = {{Formal Proof of a Program: Find}},
- month = {January},
- year = 2000,
- note = {Submitted to \emph{Science of Computer Programming}},
- url = {\url{http://www.lri.fr/~filliatr/ftp/publis/find.ps.gz}}
-}
-
-@InProceedings{FilliatreMagaud99,
- author = {J.-C. Filli\^atre and N. Magaud},
- title = {Certification of sorting algorithms in the system {\Coq}},
- booktitle = {Theorem Proving in Higher Order Logics:
- Emerging Trends},
- year = 1999,
- url = {\url{http://www.lri.fr/~filliatr/ftp/publis/Filliatre-Magaud.ps.gz}}
-}
-
-@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}
-}
-
-@Book{Fourier,
- author = {Jean-Baptiste-Joseph Fourier},
- publisher = {Gauthier-Villars},
- title = {Fourier's method to solve linear
- inequations/equations systems.},
- year = {1890}
-}
-
-@InProceedings{Gim94,
- author = {E. Gim\'enez},
- booktitle = {Types'94 : Types for Proofs and Programs},
- note = {Extended version in LIP research report 95-07, ENS Lyon},
- publisher = SV,
- series = LNCS,
- title = {Codifying guarded definitions with recursive schemes},
- volume = {996},
- year = {1994}
-}
-
-@PhDThesis{Gim96,
- author = {E. Gim\'enez},
- title = {Un calcul des constructions infinies et son application \'a la v\'erification de syst\`emes communicants},
- school = {\'Ecole Normale Sup\'erieure de Lyon},
- year = {1996}
-}
-
-@TechReport{Gim98,
- author = {E. Gim\'enez},
- title = {A Tutorial on Recursive Types in Coq},
- institution = {INRIA},
- year = 1998,
- month = mar
-}
-
-@Unpublished{GimCas05,
- author = {E. Gim\'enez and P. Cast\'eran},
- title = {A Tutorial on [Co-]Inductive Types in Coq},
- institution = {INRIA},
- year = 2005,
- month = jan,
- note = {available at \url{http://coq.inria.fr/doc}}
-}
-
-@InProceedings{Gimenez95b,
- 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 = SV,
- year = {1995}
-}
-
-@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}
-}
-
-@TechReport{Har95,
- author = {John Harrison},
- title = {Metatheory and Reflection in Theorem Proving: A Survey and Critique},
- institution = {SRI International Cambridge Computer Science Research Centre,},
- year = 1995,
- type = {Technical Report},
- number = {CRC-053},
- abstract = {http://www.cl.cam.ac.uk/users/jrh/papers.html}
-}
-
-@MastersThesis{Hir94,
- author = {D. Hirschkoff},
- month = sep,
- school = {DEA IARFA, Ecole des Ponts et Chauss\'ees, Paris},
- title = {Écriture d'une tactique arithm\'etique pour le syst\`eme {\Coq}},
- year = {1994}
-}
-
-@InProceedings{HofStr98,
- author = {Martin Hofmann and Thomas Streicher},
- title = {The groupoid interpretation of type theory},
- booktitle = {Proceedings of the meeting Twenty-five years of constructive type theory},
- publisher = {Oxford University Press},
- year = {1998}
-}
-
-@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}
-}
-
-@InProceedings{Hue87tapsoft,
- author = {G. Huet},
- title = {Programming of Future Generation Computers},
- booktitle = {Proceedings of TAPSOFT87},
- series = LNCS,
- volume = 249,
- pages = {276--286},
- year = 1987,
- publisher = SV
-}
-
-@InProceedings{Hue87,
- author = {G. Huet},
- booktitle = {Programming of Future Generation Computers},
- editor = {K. Fuchi and M. Nivat},
- note = {Also in \cite{Hue87tapsoft}},
- 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}
-}
-
-@Unpublished{Hue88b,
- author = {G. Huet},
- title = {Extending the Calculus of Constructions with Type:Type},
- year = 1988,
- note = {Unpublished}
-}
-
-@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 = SV,
- 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}
-}
-
-@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}
-}
-
-@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}
-}
-
-@Book{LE92,
- editor = {G. Huet and G. Plotkin},
- publisher = {Cambridge University Press},
- title = {Logical Environments},
- year = {1992}
-}
-
-@Book{LF91,
- editor = {G. Huet and G. Plotkin},
- publisher = {Cambridge University Press},
- title = {Logical Frameworks},
- year = {1991}
-}
-
-@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}
-}
-
-@InProceedings{LePa94,
- author = {F. Leclerc and C. Paulin-Mohring},
- booktitle = {{Types for Proofs and Programs, Types' 93}},
- editor = {H. Barendregt and T. Nipkow},
- publisher = SV,
- series = {LNCS},
- title = {{Programming with Streams in Coq. A case study : The Sieve of Eratosthenes}},
- volume = {806},
- year = {1994}
-}
-
-@TechReport{Leroy90,
- author = {X. Leroy},
- title = {The {ZINC} experiment: an economical implementation
-of the {ML} language},
- institution = {INRIA},
- number = {117},
- year = {1990}
-}
-
-@InProceedings{Let02,
- author = {P. Letouzey},
- title = {A New Extraction for Coq},
- booktitle = {TYPES},
- year = 2002,
- crossref = {DBLP:conf/types/2002},
- url = {draft at \url{http://www.pps.jussieu.fr/~letouzey/download/extraction2002.ps.gz}}
-}
-
-@PhDThesis{Luo90,
- author = {Z. Luo},
- title = {An Extended Calculus of Constructions},
- school = {University of Edinburgh},
- year = {1990}
-}
-
-@inproceedings{Luttik97specificationof,
- Author = {Sebastiaan P. Luttik and Eelco Visser},
- Booktitle = {2nd International Workshop on the Theory and Practice of Algebraic Specifications (ASF+SDF'97), Electronic Workshops in Computing},
- Publisher = {Springer-Verlag},
- Title = {Specification of Rewriting Strategies},
- Year = {1997}}
-
-@Book{MaL84,
- author = {{P. Martin-L\"of}},
- publisher = {Bibliopolis},
- series = {Studies in Proof Theory},
- title = {Intuitionistic Type Theory},
- year = {1984}
-}
-
-@Article{MaSi94,
- author = {P. Manoury and M. Simonot},
- title = {Automatizing Termination Proofs of Recursively Defined Functions.},
- journal = {TCS},
- volume = {135},
- number = {2},
- year = {1994},
- pages = {319-343},
-}
-
-@InProceedings{Miquel00,
- author = {A. Miquel},
- title = {A Model for Impredicative Type Systems with Universes,
-Intersection Types and Subtyping},
- booktitle = {{Proceedings of the 15th Annual IEEE Symposium on Logic in Computer Science (LICS'00)}},
- publisher = {IEEE Computer Society Press},
- year = {2000}
-}
-
-@PhDThesis{Miquel01a,
- author = {A. Miquel},
- title = {Le Calcul des Constructions implicite: syntaxe et s\'emantique},
- month = {dec},
- school = {{Universit\'e Paris 7}},
- year = {2001}
-}
-
-@InProceedings{Miquel01b,
- author = {A. Miquel},
- title = {The Implicit Calculus of Constructions: Extending Pure Type Systems with an Intersection Type Binder and Subtyping},
- booktitle = {{Proceedings of the fifth International Conference on Typed Lambda Calculi and Applications (TLCA01), Krakow, Poland}},
- publisher = SV,
- series = {LNCS},
- number = 2044,
- year = {2001}
-}
-
-@InProceedings{MiWer02,
- author = {A. Miquel and B. Werner},
- title = {The Not So Simple Proof-Irrelevant Model of CC},
- booktitle = {TYPES},
- year = {2002},
- pages = {240-258},
- ee = {http://link.springer.de/link/service/series/0558/bibs/2646/26460240.htm},
- crossref = {DBLP:conf/types/2002},
- bibsource = {DBLP, http://dblp.uni-trier.de}
-}
-
-@proceedings{DBLP:conf/types/2002,
- editor = {H. Geuvers and F. Wiedijk},
- title = {Types for Proofs and Programs, Second International Workshop,
- TYPES 2002, Berg en Dal, The Netherlands, April 24-28, 2002,
- Selected Papers},
- booktitle = {TYPES},
- publisher = SV,
- series = LNCS,
- volume = {2646},
- year = {2003},
- isbn = {3-540-14031-X},
- bibsource = {DBLP, http://dblp.uni-trier.de}
-}
-
-@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 = SV,
- series = {LNCS},
- title = {{Inductive Definitions in the System Coq - Rules and Properties}},
- year = {1993}
-}
-
-@Book{Moh97,
- author = {C. Paulin-Mohring},
- month = jan,
- publisher = {{ENS Lyon}},
- title = {{Le syst\`eme Coq. \mbox{Th\`ese d'habilitation}}},
- year = {1997}
-}
-
-@MastersThesis{Mun94,
- author = {C. Muñoz},
- month = sep,
- school = {DEA d'Informatique Fondamentale, Universit\'e Paris 7},
- title = {D\'emonstration automatique dans la logique propositionnelle intuitionniste},
- year = {1994}
-}
-
-@PhDThesis{Mun97d,
- author = {C. Mu{\~{n}}oz},
- title = {Un calcul de substitutions pour la repr\'esentation
- de preuves partielles en th\'eorie de types},
- school = {Universit\'e Paris 7},
- year = {1997},
- note = {Version en anglais disponible comme rapport de
- recherche INRIA RR-3309},
- type = {Th\`ese de Doctorat}
-}
-
-@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 = SV,
- series = {LNCS},
- title = {{ProPre : A Programming language with proofs}},
- year = {1992}
-}
-
-@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}
-}
-
-@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 = SV,
- series = {LNCS},
- title = {{Synthesizing proofs from programs in
-the Calculus of Inductive Constructions}},
- volume = {947},
- year = {1995}
-}
-
-@InProceedings{Prasad93,
- author = {K.V. Prasad},
- booktitle = {{Proceedings of CONCUR'93}},
- publisher = SV,
- series = {LNCS},
- title = {{Programming with broadcasts}},
- volume = {715},
- year = {1993}
-}
-
-@Book{RC95,
- author = {di~Cosmo, R.},
- title = {Isomorphisms of Types: from $\lambda$-calculus to information
- retrieval and language design},
- series = {Progress in Theoretical Computer Science},
- publisher = {Birkhauser},
- year = {1995},
- note = {ISBN-0-8176-3763-X}
-}
-
-@TechReport{Rou92,
- author = {J. Rouyer},
- institution = {INRIA},
- month = nov,
- number = {1795},
- title = {{Développement de l'Algorithme d'Unification dans le Calcul des Constructions}},
- year = {1992}
-}
-
-@Article{Rushby98,
- title = {Subtypes for Specifications: Predicate Subtyping in
- {PVS}},
- author = {John Rushby and Sam Owre and N. Shankar},
- journal = {IEEE Transactions on Software Engineering},
- pages = {709--720},
- volume = 24,
- number = 9,
- month = sep,
- year = 1998
-}
-
-@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{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}
-}
-
-@PhDThesis{Wer94,
- author = {B. Werner},
- school = {Universit\'e Paris 7},
- title = {Une th\'eorie des constructions inductives},
- type = {Th\`ese de Doctorat},
- year = {1994}
-}
-
-@PhDThesis{Bar99,
- author = {B. Barras},
- school = {Universit\'e Paris 7},
- title = {Auto-validation d'un système de preuves avec familles inductives},
- type = {Th\`ese de Doctorat},
- year = {1999}
-}
-
-@Unpublished{ddr98,
- author = {D. de Rauglaudre},
- title = {Camlp4 version 1.07.2},
- year = {1998},
- note = {In Camlp4 distribution}
-}
-
-@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}
-}
-
-@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}
-}
-
-@TechReport{maranget94,
- author = {L. Maranget},
- institution = {INRIA},
- number = {2385},
- title = {{Two Techniques for Compiling Lazy Pattern Matching}},
- year = {1994}
-}
-
-@InProceedings{puel-suarez90,
- author = {L.Puel and A. Su\'arez},
- booktitle = {{Conference Lisp and Functional Programming}},
- series = {ACM},
- publisher = SV,
- title = {{Compiling Pattern Matching by Term
-Decomposition}},
- year = {1990}
-}
-
-@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}
-}
-
-@inproceedings{sozeau06,
- author = {Matthieu Sozeau},
- title = {Subset Coercions in {C}oq},
- year = {2007},
- booktitle = {TYPES'06},
- pages = {237-252},
- volume = {4502},
- publisher = "Springer",
- series = {LNCS}
-}
-
-@inproceedings{sozeau08,
- Author = {Matthieu Sozeau and Nicolas Oury},
- booktitle = {TPHOLs'08},
- Pdf = {http://www.lri.fr/~sozeau/research/publications/drafts/classes.pdf},
- Title = {{F}irst-{C}lass {T}ype {C}lasses},
- Year = {2008},
-}
-
-@Misc{streicher93semantical,
- author = {T. Streicher},
- title = {Semantical Investigations into Intensional Type Theory},
- note = {Habilitationsschrift, LMU Munchen.},
- year = {1993}
-}
-
-@Misc{Pcoq,
- author = {Lemme Team},
- title = {Pcoq a graphical user-interface for {Coq}},
- note = {\url{http://www-sop.inria.fr/lemme/pcoq/}}
-}
-
-@Misc{ProofGeneral,
- author = {David Aspinall},
- title = {Proof General},
- note = {\url{https://proofgeneral.github.io/}}
-}
-
-@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},
- booktitle = {The Implementation of Functional Programming
-Languages},
- editor = {S.L. Peyton Jones},
- publisher = {Prentice-Hall},
- year = {1987}
-}
-
-@inproceedings{DBLP:conf/types/CornesT95,
- author = {Cristina Cornes and
- Delphine Terrasse},
- title = {Automating Inversion of Inductive Predicates in Coq},
- booktitle = {TYPES},
- year = {1995},
- pages = {85-104},
- crossref = {DBLP:conf/types/1995},
- bibsource = {DBLP, http://dblp.uni-trier.de}
-}
-@proceedings{DBLP:conf/types/1995,
- editor = {Stefano Berardi and
- Mario Coppo},
- title = {Types for Proofs and Programs, International Workshop TYPES'95,
- Torino, Italy, June 5-8, 1995, Selected Papers},
- booktitle = {TYPES},
- publisher = {Springer},
- series = {Lecture Notes in Computer Science},
- volume = {1158},
- year = {1996},
- isbn = {3-540-61780-9},
- bibsource = {DBLP, http://dblp.uni-trier.de}
-}
-
-@inproceedings{DBLP:conf/types/McBride00,
- author = {Conor McBride},
- title = {Elimination with a Motive},
- booktitle = {TYPES},
- year = {2000},
- pages = {197-216},
- ee = {http://link.springer.de/link/service/series/0558/bibs/2277/22770197.htm},
- crossref = {DBLP:conf/types/2000},
- bibsource = {DBLP, http://dblp.uni-trier.de}
-}
-
-@proceedings{DBLP:conf/types/2000,
- editor = {Paul Callaghan and
- Zhaohui Luo and
- James McKinna and
- Robert Pollack},
- title = {Types for Proofs and Programs, International Workshop, TYPES
- 2000, Durham, UK, December 8-12, 2000, Selected Papers},
- booktitle = {TYPES},
- publisher = {Springer},
- series = {Lecture Notes in Computer Science},
- volume = {2277},
- year = {2002},
- isbn = {3-540-43287-6},
- bibsource = {DBLP, http://dblp.uni-trier.de}
-}
-
-@INPROCEEDINGS{sugar,
- author = {Alessandro Giovini and Teo Mora and Gianfranco Niesi and Lorenzo Robbiano and Carlo Traverso},
- title = {"One sugar cube, please" or Selection strategies in the Buchberger algorithm},
- booktitle = { Proceedings of the ISSAC'91, ACM Press},
- year = {1991},
- pages = {5--4},
- publisher = {}
-}
-
-@article{LeeWerner11,
- author = {Gyesik Lee and
- Benjamin Werner},
- title = {Proof-irrelevant model of {CC} with predicative induction
- and judgmental equality},
- journal = {Logical Methods in Computer Science},
- volume = {7},
- number = {4},
- year = {2011},
- ee = {http://dx.doi.org/10.2168/LMCS-7(4:5)2011},
- bibsource = {DBLP, http://dblp.uni-trier.de}
-}
-
-@Comment{cross-references, must be at end}
-
-@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{Nijmegen93,
- editor = {H. Barendregt and T. Nipkow},
- publisher = SV,
- series = LNCS,
- title = {Types for Proofs and Programs},
- volume = {806},
- year = {1994}
-}
-
-@article{ TheOmegaPaper,
- author = "W. Pugh",
- title = "The Omega test: a fast and practical integer programming algorithm for dependence analysis",
- journal = "Communication of the ACM",
- pages = "102--114",
- year = "1992",
-}
-
-@inproceedings{CSwcu,
- hal_id = {hal-00816703},
- url = {http://hal.inria.fr/hal-00816703},
- title = {{Canonical Structures for the working Coq user}},
- author = {Mahboubi, Assia and Tassi, Enrico},
- booktitle = {{ITP 2013, 4th Conference on Interactive Theorem Proving}},
- publisher = {Springer},
- pages = {19-34},
- address = {Rennes, France},
- volume = {7998},
- editor = {Sandrine Blazy and Christine Paulin and David Pichardie },
- series = {LNCS },
- doi = {10.1007/978-3-642-39634-2\_5 },
- year = {2013},
-}
-
-@article{CSlessadhoc,
- author = {Gonthier, Georges and Ziliani, Beta and Nanevski, Aleksandar and Dreyer, Derek},
- title = {How to Make Ad Hoc Proof Automation Less Ad Hoc},
- journal = {SIGPLAN Not.},
- issue_date = {September 2011},
- volume = {46},
- number = {9},
- month = sep,
- year = {2011},
- issn = {0362-1340},
- pages = {163--175},
- numpages = {13},
- url = {http://doi.acm.org/10.1145/2034574.2034798},
- doi = {10.1145/2034574.2034798},
- acmid = {2034798},
- publisher = {ACM},
- address = {New York, NY, USA},
- keywords = {canonical structures, coq, custom proof automation, hoare type theory, interactive theorem proving, tactics, type classes},
-}
-
-@inproceedings{CompiledStrongReduction,
- author = {Benjamin Gr{\'{e}}goire and
- Xavier Leroy},
- editor = {Mitchell Wand and
- Simon L. Peyton Jones},
- title = {A compiled implementation of strong reduction},
- booktitle = {Proceedings of the Seventh {ACM} {SIGPLAN} International Conference
- on Functional Programming {(ICFP} '02), Pittsburgh, Pennsylvania,
- USA, October 4-6, 2002.},
- pages = {235--246},
- publisher = {{ACM}},
- year = {2002},
- url = {http://doi.acm.org/10.1145/581478.581501},
- doi = {10.1145/581478.581501},
- timestamp = {Tue, 11 Jun 2013 13:49:16 +0200},
- biburl = {http://dblp.uni-trier.de/rec/bib/conf/icfp/GregoireL02},
- bibsource = {dblp computer science bibliography, http://dblp.org}
-}
-
-@inproceedings{FullReduction,
- author = {Mathieu Boespflug and
- Maxime D{\'{e}}n{\`{e}}s and
- Benjamin Gr{\'{e}}goire},
- editor = {Jean{-}Pierre Jouannaud and
- Zhong Shao},
- title = {Full Reduction at Full Throttle},
- booktitle = {Certified Programs and Proofs - First International Conference, {CPP}
- 2011, Kenting, Taiwan, December 7-9, 2011. Proceedings},
- series = {Lecture Notes in Computer Science},
- volume = {7086},
- pages = {362--377},
- publisher = {Springer},
- year = {2011},
- url = {http://dx.doi.org/10.1007/978-3-642-25379-9_26},
- doi = {10.1007/978-3-642-25379-9_26},
- timestamp = {Thu, 17 Nov 2011 13:33:48 +0100},
- biburl = {http://dblp.uni-trier.de/rec/bib/conf/cpp/BoespflugDG11},
- bibsource = {dblp computer science bibliography, http://dblp.org}
-}
diff --git a/doc/refman/coq-listing.tex b/doc/refman/coq-listing.tex
deleted file mode 100644
index c69c3b1b8..000000000
--- a/doc/refman/coq-listing.tex
+++ /dev/null
@@ -1,152 +0,0 @@
-%=======================================================================
-% Listings LaTeX package style for Gallina + SSReflect (Assia Mahboubi 2007)
-
-\lstdefinelanguage{SSR} {
-
-% Anything betweeen $ becomes LaTeX math mode
-mathescape=true,
-% Comments may or not include Latex commands
-texcl=false,
-
-
-% Vernacular commands
-morekeywords=[1]{
-From, Section, Module, End, Require, Import, Export, Defensive, Function,
-Variable, Variables, Parameter, Parameters, Axiom, Hypothesis, Hypotheses,
-Notation, Local, Tactic, Reserved, Scope, Open, Close, Bind, Delimit,
-Definition, Let, Ltac, Fixpoint, CoFixpoint, Add, Morphism, Relation,
-Implicit, Arguments, Set, Unset, Contextual, Strict, Prenex, Implicits,
-Inductive, CoInductive, Record, Structure, Canonical, Coercion,
-Theorem, Lemma, Corollary, Proposition, Fact, Remark, Example,
-Proof, Goal, Save, Qed, Defined, Hint, Resolve, Rewrite, View,
-Search, Show, Print, Printing, All, Graph, Projections, inside,
-outside, Locate, Maximal},
-
-% Gallina
-morekeywords=[2]{forall, exists, exists2, fun, fix, cofix, struct,
- match, with, end, as, in, return, let, if, is, then, else,
- for, of, nosimpl},
-
-% Sorts
-morekeywords=[3]{Type, Prop},
-
-% Various tactics, some are std Coq subsumed by ssr, for the manual purpose
-morekeywords=[4]{
- pose, set, move, case, elim, apply, clear,
- hnf, intro, intros, generalize, rename, pattern, after,
- destruct, induction, using, refine, inversion, injection,
- rewrite, congr, unlock, compute, ring, field,
- replace, fold, unfold, change, cutrewrite, simpl,
- have, gen, generally, suff, wlog, suffices, without, loss, nat_norm,
- assert, cut, trivial, revert, bool_congr, nat_congr, abstract,
- symmetry, transitivity, auto, split, left, right, autorewrite},
-
-% Terminators
-morekeywords=[5]{
- by, done, exact, reflexivity, tauto, romega, omega,
- assumption, solve, contradiction, discriminate},
-
-
-% Control
-morekeywords=[6]{do, last, first, try, idtac, repeat},
-
-% Various symbols
-% For the ssr manual we turn off the prettyprint of formulas
-% literate=
-% {->}{{$\rightarrow\,$}}2
-% {->}{{\tt ->}}3
-% {<-}{{$\leftarrow\,$}}2
-% {<-}{{\tt <-}}2
-% {>->}{{$\mapsto$}}3
-% {<=}{{$\leq$}}1
-% {>=}{{$\geq$}}1
-% {<>}{{$\neq$}}1
-% {/\\}{{$\wedge$}}2
-% {\\/}{{$\vee$}}2
-% {<->}{{$\leftrightarrow\;$}}3
-% {<=>}{{$\Leftrightarrow\;$}}3
-% {:nat}{{$~\in\mathbb{N}$}}3
-% {fforall\ }{{$\forall_f\,$}}1
-% {forall\ }{{$\forall\,$}}1
-% {exists\ }{{$\exists\,$}}1
-% {negb}{{$\neg$}}1
-% {spp}{{:*:\,}}1
-% {~}{{$\sim$}}1
-% {\\in}{{$\in\;$}}1
-% {/\\}{$\land\,$}1
-% {:*:}{{$*$}}2
-% {=>}{{$\,\Rightarrow\ $}}1
-% {=>}{{\tt =>}}2
-% {:=}{{{\tt:=}\,\,}}2
-% {==}{{$\equiv$}\,}2
-% {!=}{{$\neq$}\,}2
-% {^-1}{{$^{-1}$}}1
-% {elt'}{elt'}1
-% {=}{{\tt=}\,\,}2
-% {+}{{\tt+}\,\,}2,
-literate=
- {isn't }{{{\ttfamily\color{dkgreen} isn't }}}1,
-
-% Comments delimiters, we do turn this off for the manual
-%comment=[s]{(*}{*)},
-
-% Spaces are not displayed as a special character
-showstringspaces=false,
-
-% String delimiters
-morestring=[b]",
-morestring=[d]",
-
-% Size of tabulations
-tabsize=3,
-
-% Enables ASCII chars 128 to 255
-extendedchars=true,
-
-% Case sensitivity
-sensitive=true,
-
-% Automatic breaking of long lines
-breaklines=true,
-
-% Default style fors listings
-basicstyle=\ttfamily,
-
-% Position of captions is bottom
-captionpos=b,
-
-% Full flexible columns
-columns=[l]fullflexible,
-
-% Style for (listings') identifiers
-identifierstyle={\ttfamily\color{black}},
-% Note : highlighting of Coq identifiers is done through a new
-% delimiter definition through an lstset at the begining of the
-% document. Don't know how to do better.
-
-% Style for declaration keywords
-keywordstyle=[1]{\ttfamily\color{dkviolet}},
-
-% Style for gallina keywords
-keywordstyle=[2]{\ttfamily\color{dkgreen}},
-
-% Style for sorts keywords
-keywordstyle=[3]{\ttfamily\color{lightblue}},
-
-% Style for tactics keywords
-keywordstyle=[4]{\ttfamily\color{dkblue}},
-
-% Style for terminators keywords
-keywordstyle=[5]{\ttfamily\color{red}},
-
-
-%Style for iterators
-keywordstyle=[6]{\ttfamily\color{dkpink}},
-
-% Style for strings
-stringstyle=\ttfamily,
-
-% Style for comments
-commentstyle=\rmfamily,
-
-}
diff --git a/doc/refman/coqide-queries.png b/doc/refman/coqide-queries.png
deleted file mode 100644
index 7a46ac4e6..000000000
--- a/doc/refman/coqide-queries.png
+++ /dev/null
Binary files differ
diff --git a/doc/refman/coqide.png b/doc/refman/coqide.png
deleted file mode 100644
index e300401c9..000000000
--- a/doc/refman/coqide.png
+++ /dev/null
Binary files differ
diff --git a/doc/refman/headers.hva b/doc/refman/headers.hva
deleted file mode 100644
index 9714a29be..000000000
--- a/doc/refman/headers.hva
+++ /dev/null
@@ -1,44 +0,0 @@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% File headers.hva
-% Hevea version of headers.sty
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Commands for indexes
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\usepackage{index}
-\makeindex
-
-
-\newindex{tactic}{tacidx}{tacind}{Tactics Index}
-\newindex{command}{comidx}{comind}{Vernacular Commands Index}
-\newindex{option}{optidx}{optind}{Vernacular Options Index}
-\newindex{error}{erridx}{errind}{Index of Error Messages}
-\renewindex{default}{idx}{ind}{Global Index}
-
-\newcommand{\printrefmanindex}[3]{%
-\addcontentsline{toc}{chapter}{#2}%
-\printindex[#1]%
-\cutname{#3}%
-}
-
-\newcommand{\tacindex}[1]{%
-\index{#1@\texttt{#1}}\index[tactic]{#1@\texttt{#1}}}
-\newcommand{\comindex}[1]{%
-\index{#1@\texttt{#1}}\index[command]{#1@\texttt{#1}}}
-\newcommand{\optindex}[1]{%
-\index{#1@\texttt{#1}}\index[option]{#1@\texttt{#1}}}
-\newcommand{\errindex}[1]{\texttt{#1}\index[error]{#1}}
-\newcommand{\errindexbis}[2]{\texttt{#1}\index[error]{#2}}
-\newcommand{\ttindex}[1]{\index{#1@\texttt{#1}}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% For the Addendum table of contents
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\newcommand{\aauthor}[1]{{\LARGE \bf #1} \bigskip} % 3 \bigskip's that were here originally
- % may be good for LaTeX but too much for HTML
-\newcommand{\atableofcontents}{}
-\newcommand{\achapter}[1]{\chapter{#1}}
-\newcommand{\asection}{\section}
-\newcommand{\asubsection}{\subsection}
-\newcommand{\asubsubsection}{\subsubsection}
diff --git a/doc/refman/headers.sty b/doc/refman/headers.sty
deleted file mode 100644
index fb39f687d..000000000
--- a/doc/refman/headers.sty
+++ /dev/null
@@ -1,88 +0,0 @@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% File headers.sty
-% Commands for pretty headers, multiple indexes, and the appendix.
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\usepackage{fancyhdr}
-
-\setlength{\headheight}{14pt}
-
-\pagestyle{fancyplain}
-
-\newcommand{\coqfooter}{\tiny Coq Reference Manual, V\coqversion{}, \today}
-
-\cfoot{}
-\lfoot[{\coqfooter}]{}
-\rfoot[]{{\coqfooter}}
-
-\newcommand{\setheaders}[1]{\rhead[\fancyplain{}{\textbf{#1}}]{\fancyplain{}{\thepage}}\lhead[\fancyplain{}{\thepage}]{\fancyplain{}{\textbf{#1}}}}
-\newcommand{\defaultheaders}{\rhead[\fancyplain{}{\leftmark}]{\fancyplain{}{\thepage}}\lhead[\fancyplain{}{\thepage}]{\fancyplain{}{\rightmark}}}
-
-\renewcommand{\chaptermark}[1]{\markboth{{\bf \thechapter~#1}}{}}
-\renewcommand{\sectionmark}[1]{\markright{\thesection~#1}}
-\renewcommand{\contentsname}{%
-\protect\setheaders{Table of contents}Table of contents}
-\renewcommand{\bibname}{\protect\setheaders{Bibliography}%
-\protect\RefManCutCommand{BEGINBIBLIO=\thepage}%
-\protect\addcontentsline{toc}{chapter}{Bibliography}Bibliography}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Commands for indexes
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\usepackage{index}
-\makeindex
-
-\newindex{tactic}{tacidx}{tacind}{Tactics Index}
-\newindex{command}{comidx}{comind}{Vernacular Commands Index}
-\newindex{option}{optidx}{optind}{Vernacular Options Index}
-\newindex{error}{erridx}{errind}{Index of Error Messages}
-\renewindex{default}{idx}{ind}{Global Index}
-
-\newcommand{\printrefmanindex}[3]{%
-\cleardoublepage%
-\phantomsection%
-\setheaders{#2}%
-\addcontentsline{toc}{chapter}{#2}%
-\printindex[#1]%
-\cutname{#3}%
-}
-
-\newcommand{\tacindex}[1]{%
-\index{#1@\texttt{#1}}\index[tactic]{#1@\texttt{#1}}}
-\newcommand{\comindex}[1]{%
-\index{#1@\texttt{#1}}\index[command]{#1@\texttt{#1}}}
-\newcommand{\optindex}[1]{%
-\index{#1@\texttt{#1}}\index[option]{#1@\texttt{#1}}}
-\newcommand{\errindex}[1]{\texttt{#1}\index[error]{#1}}
-\newcommand{\errindexbis}[2]{\texttt{#1}\index[error]{#2}}
-\newcommand{\ttindex}[1]{\index{#1@\texttt{#1}}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% For the Addendum table of contents
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\newcommand{\aauthor}[1]{{\LARGE \bf #1} \bigskip \bigskip \bigskip}
-\newcommand{\atableofcontents}{\section*{Contents}\@starttoc{atoc}}
-\newcommand{\achapter}[1]{
- \chapter{#1}\addcontentsline{atoc}{chapter}{#1}}
-\newcommand{\asection}[1]{
- \section{#1}\addcontentsline{atoc}{section}{#1}}
-\newcommand{\asubsection}[1]{
- \subsection{#1}\addcontentsline{atoc}{subsection}{#1}}
-\newcommand{\asubsubsection}[1]{
- \subsubsection{#1}\addcontentsline{atoc}{subsubsection}{#1}}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Reference-Manual.sh is generated to cut the Postscript
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%\@starttoc{sh}
-\newwrite\RefManCut@out%
-\immediate\openout\RefManCut@out\jobname.sh
-\newcommand{\RefManCutCommand}[1]{%
-\immediate\write\RefManCut@out{#1}}
-\newcommand{\RefManCutClose}{%
-\immediate\closeout\RefManCut@out}
-
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
diff --git a/doc/refman/index.html b/doc/refman/index.html
deleted file mode 100644
index b937350e6..000000000
--- a/doc/refman/index.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<HTML>
-
-<HEAD>
-
-<TITLE>The Coq Proof Assistant Reference Manual</TITLE>
-
-</HEAD>
-
-<FRAMESET ROWS=90%,*>
- <FRAME SRC="cover.html" NAME="UP">
- <FRAME SRC="menu.html">
-</FRAMESET>
-
-</HTML>
diff --git a/doc/refman/menu.html b/doc/refman/menu.html
deleted file mode 100644
index 7312ad344..000000000
--- a/doc/refman/menu.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<HTML>
-
-<BODY>
-
-<CENTER>
-
-<TABLE BORDER="0" CELLPADDING=10>
-<TR>
-<TD><CENTER><A HREF="cover.html" TARGET="UP"><FONT SIZE=2>Cover page</FONT></A></CENTER></TD>
-<TD><CENTER><A HREF="toc.html" TARGET="UP"><FONT SIZE=2>Table of contents</FONT></A></CENTER></TD>
-<TD><CENTER><A HREF="biblio.html" TARGET="UP"><FONT SIZE=2>
-Bibliography</FONT></A></CENTER></TD>
-<TD><CENTER><A HREF="general-index.html" TARGET="UP"><FONT SIZE=2>
-Global Index
-</FONT></A></CENTER></TD>
-<TD><CENTER><A HREF="tactic-index.html" TARGET="UP"><FONT SIZE=2>
-Tactics Index
-</FONT></A></CENTER></TD>
-<TD><CENTER><A HREF="command-index.html" TARGET="UP"><FONT SIZE=2>
-Vernacular Commands Index
-</FONT></A></CENTER></TD>
-<TD><CENTER><A HREF="option-index.html" TARGET="UP"><FONT SIZE=2>
-Vernacular Options Index
-</FONT></A></CENTER></TD>
-<TD><CENTER><A HREF="error-index.html" TARGET="UP"><FONT SIZE=2>
-Index of Error Messages
-</FONT></A></CENTER></TD>
-</TABLE>
-
-</CENTER>
-
-</BODY></HTML>
diff --git a/doc/sphinx/_static/CoqNotations.ttf b/doc/sphinx/_static/CoqNotations.ttf
new file mode 100644
index 000000000..da8f2850d
--- /dev/null
+++ b/doc/sphinx/_static/CoqNotations.ttf
Binary files differ
diff --git a/doc/sphinx/_static/UbuntuMono-Square.ttf b/doc/sphinx/_static/UbuntuMono-Square.ttf
deleted file mode 100644
index 12b7c6d51..000000000
--- a/doc/sphinx/_static/UbuntuMono-Square.ttf
+++ /dev/null
Binary files differ
diff --git a/doc/sphinx/_static/notations.css b/doc/sphinx/_static/notations.css
index 9b7b826d5..f899945a3 100644
--- a/doc/sphinx/_static/notations.css
+++ b/doc/sphinx/_static/notations.css
@@ -22,10 +22,10 @@
}
@font-face { /* This font has been edited to center all characters */
- font-family: 'UbuntuMono-Square';
+ font-family: 'CoqNotations';
font-style: normal;
font-weight: 800;
- src: local('UbuntuMono-Square'), url(./UbuntuMono-Square.ttf) format('truetype');
+ src: local('CoqNotations'), url(./CoqNotations.ttf) format('truetype');
}
.notation .notation-sup, .notation .notation-sub {
@@ -34,15 +34,15 @@
color: black;
/* cursor: help; */
display: inline-block;
- font-size: 0.5em;
+ font-size: 0.45em;
font-weight: bolder;
- font-family: UbuntuMono-Square, monospace;
- height: 2em;
+ font-family: CoqNotations, monospace;
+ height: 2.2em;
line-height: 1.6em;
position: absolute;
right: -1em; /* half of the width */
text-align: center;
- width: 2em;
+ width: 2.2em;
}
.notation .repeat {
diff --git a/doc/sphinx/addendum/extended-pattern-matching.rst b/doc/sphinx/addendum/extended-pattern-matching.rst
index 64d4eddf0..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
@@ -305,6 +305,8 @@ explicitations (as for terms 2.7.11).
end).
+.. _matching-dependent:
+
Matching objects of dependent types
-----------------------------------
@@ -414,6 +416,7 @@ length, by writing
I have a copy of :g:`b` in type :g:`listn 0` resp :g:`listn (S n')`.
+.. _match-in-patterns:
Patterns in ``in``
~~~~~~~~~~~~~~~~~~
@@ -427,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
@@ -588,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 d7f97edab..cb93d48a4 100644
--- a/doc/sphinx/addendum/extraction.rst
+++ b/doc/sphinx/addendum/extraction.rst
@@ -1,16 +1,16 @@
-.. _extraction:
-
.. include:: ../replaces.rst
-Extraction of programs in OCaml and Haskell
-============================================
+.. _extraction:
+
+Extraction of programs in |OCaml| and Haskell
+=============================================
:Authors: Jean-Christophe Filliâtre and Pierre Letouzey
We present here the |Coq| extraction commands, used to build certified
and relatively efficient functional programs, extracting them from
either |Coq| functions or |Coq| proofs of specifications. The
-functional languages available as output are currently OCaml, Haskell
+functional languages available as output are currently |OCaml|, Haskell
and Scheme. In the following, "ML" will be used (abusively) to refer
to any of the three.
@@ -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,43 +57,43 @@ 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
+ to a temporary |OCaml| file, just as in ``Extraction "file"``. Then
this temporary file and its signature are compiled with the same
- OCaml compiler used to built |Coq|. This command succeeds only
- if the extraction and the OCaml compilation succeed. It fails
- if the current target language of the extraction is not OCaml.
+ |OCaml| compiler used to built |Coq|. This command succeeds only
+ if the extraction and the |OCaml| compilation succeed. It fails
+ if the current target language of the extraction is not |OCaml|.
Extraction Options
-------------------
@@ -102,26 +102,26 @@ Setting the target language
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ability to fix target language is the first and more important
-of the extraction options. Default is ``Ocaml``.
+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
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Since OCaml is a strict language, the extracted code has to
+Since |OCaml| is a strict language, the extracted code has to
be optimized in order to be efficient (for instance, when using
induction principles we do not want to compute all the recursive calls
but only the needed ones). So the extraction mechanism provides an
automatic optimization routine that will be called each time the user
-want to generate OCaml programs. The optimizations can be split in two
+want to generate |OCaml| programs. The optimizations can be split in two
groups: the type-preserving ones (essentially constant inlining and
reductions) and the non type-preserving ones (some function
abstractions of dummy types are removed when it is deemed safe in order
to have more elegant types). Therefore some constants may not appear in the
-resulting monolithic OCaml program. In the case of modular extraction,
+resulting monolithic |OCaml| program. In the case of modular extraction,
even if some inlining is done, the inlined constant are nevertheless
printed, to ensure session-independent programs.
@@ -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,21 +253,20 @@ 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``
- will have an effect on the realized and inlined axiom.
+ 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
terms given to realize the axioms do have the expected types. In
@@ -286,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:
@@ -295,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
@@ -315,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
@@ -323,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,
@@ -336,10 +335,10 @@ native boolean type instead of |Coq| one. The syntax is the following:
argument is considered to have one unit argument, in order to block
early evaluation of the branch: ``| O => bar`` leads to the functional
form ``(fun () -> bar)``. For instance, when extracting ``nat``
- into OCaml ``int``, the code to provide has type:
+ 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.
@@ -347,17 +346,17 @@ native boolean type instead of |Coq| one. The syntax is the following:
* Extracting an inductive type to a pre-existing ML inductive type
is quite sound. But extracting to a general type (by providing an
ad-hoc pattern-matching) will often **not** be fully rigorously
- correct. For instance, when extracting ``nat`` to OCaml ``int``,
+ correct. For instance, when extracting ``nat`` to |OCaml| ``int``,
it is theoretically possible to build ``nat`` values that are
- larger than OCaml ``max_int``. It is the user's responsibility to
+ larger than |OCaml| ``max_int``. It is the user's responsibility to
be sure that no overflow or other bad events occur in practice.
* Translating an inductive type to an arbitrary ML type does **not**
magically improve the asymptotic complexity of functions, even if the
ML type is an efficient representation. For instance, when extracting
- ``nat`` to OCaml ``int``, the function ``Nat.mul`` stays quadratic.
+ ``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:
@@ -369,9 +368,9 @@ Typical examples are the following:
.. note::
- When extracting to Ocaml, if an inductive constructor or type has arity 2 and
+ When extracting to |OCaml|, if an inductive constructor or type has arity 2 and
the corresponding string is enclosed by parentheses, and the string meets
- Ocaml's lexical criteria for an infix symbol, then the rest of the string is
+ |OCaml|'s lexical criteria for an infix symbol, then the rest of the string is
used as infix constructor or type.
.. coqtop:: in
@@ -380,7 +379,7 @@ Typical examples are the following:
Extract Inductive prod => "(*)" [ "(,)" ].
As an example of translation to a non-inductive datatype, let's turn
-``nat`` into OCaml ``int`` (see caveat above):
+``nat`` into |OCaml| ``int`` (see caveat above):
.. coqtop:: in
@@ -389,28 +388,28 @@ 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
code that is meant to be linked with the extracted code.
-For instance the module ``List`` exists both in |Coq| and in OCaml.
+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.
-For OCaml, a typical use of these commands is
+For |OCaml|, a typical use of these commands is
``Extraction Blacklist String List``.
Differences between |Coq| and ML type systems
@@ -418,7 +417,7 @@ Differences between |Coq| and ML type systems
Due to differences between |Coq| and ML type systems,
some extracted programs are not directly typable in ML.
-We now solve this problem (at least in OCaml) by adding
+We now solve this problem (at least in |OCaml|) by adding
when needed some unsafe casting ``Obj.magic``, which give
a generic type ``'a`` to any term.
@@ -432,7 +431,7 @@ function:
Definition dp {A B:Type}(x:A)(y:B)(f:forall C:Type, C->C) := (f A x, f B y).
-In Ocaml, for instance, the direct extracted term would be::
+In |OCaml|, for instance, the direct extracted term would be::
let dp x y f = Pair((f () x),(f () y))
@@ -455,12 +454,12 @@ of a constructor; for example:
Inductive anything : Type := dummy : forall A:Set, A -> anything.
which corresponds to the definition of an ML dynamic type.
-In OCaml, we must cast any argument of the constructor dummy
+In |OCaml|, we must cast any argument of the constructor dummy
(no GADT are produced yet by the extraction).
Even with those unsafe castings, you should never get error like
``segmentation fault``. In fact even if your program may seem
-ill-typed to the Ocaml type-checker, it can't go wrong : it comes
+ill-typed to the |OCaml| type-checker, it can't go wrong : it comes
from a Coq well-typed terms, so for example inductive types will always
have the correct number of arguments, etc. Of course, when launching
manually some extracted function, you should apply it to arguments
@@ -470,14 +469,14 @@ More details about the correctness of the extracted programs can be
found in :cite:`Let02`.
We have to say, though, that in most "realistic" programs, these problems do not
-occur. For example all the programs of Coq library are accepted by the OCaml
+occur. For example all the programs of Coq library are accepted by the |OCaml|
type-checker without any ``Obj.magic`` (see examples below).
Some examples
-------------
We present here two examples of extractions, taken from the
-|Coq| Standard Library. We choose OCaml as target language,
+|Coq| Standard Library. We choose |OCaml| as target language,
but all can be done in the other dialects with slight modifications.
We then indicate where to find other examples and tests of extraction.
@@ -493,7 +492,7 @@ This module contains a theorem ``eucl_dev``, whose type is::
where ``diveucl`` is a type for the pair of the quotient and the
modulo, plus some logical assertions that disappear during extraction.
-We can now extract this program to OCaml:
+We can now extract this program to |OCaml|:
.. coqtop:: none
@@ -513,7 +512,7 @@ You can then copy-paste the output to a file ``euclid.ml`` or let
Extraction "euclid" eucl_dev.
-Let us play the resulting program (in an OCaml toplevel)::
+Let us play the resulting program (in an |OCaml| toplevel)::
#use "euclid.ml";;
type nat = O | S of nat
@@ -527,7 +526,7 @@ Let us play the resulting program (in an OCaml toplevel)::
# eucl_dev (S (S O)) (S (S (S (S (S O)))));;
- : diveucl = Divex (S (S O), S O)
-It is easier to test on OCaml integers::
+It is easier to test on |OCaml| integers::
# let rec nat_of_int = function 0 -> O | n -> S (nat_of_int (n-1));;
val nat_of_int : int -> nat = <fun>
diff --git a/doc/sphinx/addendum/generalized-rewriting.rst b/doc/sphinx/addendum/generalized-rewriting.rst
index da9e97e6f..e10e16c10 100644
--- a/doc/sphinx/addendum/generalized-rewriting.rst
+++ b/doc/sphinx/addendum/generalized-rewriting.rst
@@ -1,14 +1,12 @@
-.. _generalizedrewriting:
-
------------------------
- Generalized rewriting
------------------------
+.. include:: ../preamble.rst
+.. include:: ../replaces.rst
-:Author: Matthieu Sozeau
+.. _generalizedrewriting:
Generalized rewriting
=====================
+:Author: Matthieu Sozeau
This chapter presents the extension of several equality related
tactics to work over user-defined structures (called setoids) that are
@@ -181,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.
@@ -220,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
@@ -319,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
@@ -429,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
@@ -479,7 +477,7 @@ The declaration itself amounts to the definition of an object of the
record type ``Coq.Classes.RelationClasses.Equivalence`` and a hint added
to the ``typeclass_instances`` hint database. Morphism declarations are
also instances of a type class defined in ``Classes.Morphisms``. See the
-documentation on type classes :ref:`TODO-chapter-20-type-classes`
+documentation on type classes :ref:`typeclasses`
and the theories files in Classes for further explanations.
One can inform the rewrite tactic about morphisms and relations just
@@ -532,21 +530,26 @@ 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``.
.. tacv:: setoid_reflexivity
+ :name: setoid_reflexivity
.. tacv:: setoid_symmetry [in @ident]
+ :name: setoid_symmetry
.. tacv:: setoid_transitivity
+ :name: setoid_transitivity
.. tacv:: setoid_rewrite [@orientation] @term [at @occs] [in @ident]
+ :name: setoid_rewrite
.. tacv:: setoid_replace @term with @term [in @ident] [using relation @term] [by @tactic]
+ :name: setoid_replace
The ``using relation`` arguments cannot be passed to the unprefixed form.
@@ -561,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.
@@ -585,7 +590,7 @@ Deprecated syntax and backward incompatibilities
Due to backward compatibility reasons, the following syntax for the
declaration of setoids and morphisms is also accepted.
-.. tacv:: Add Setoid @A @Aeq @ST as @ident
+.. cmd:: Add Setoid @A @Aeq @ST as @ident
where ``Aeq`` is a congruence relation without parameters, ``A`` is its carrier
and ``ST`` is an object of type (``Setoid_Theory A Aeq``) (i.e. a record
@@ -593,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
@@ -607,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
@@ -621,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.
@@ -669,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.
@@ -707,22 +714,20 @@ 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:`TODO-20.6.7-typeclasses-transparency`).
-
+:cmd:`Typeclasses Opaque`.
Strategies for rewriting
------------------------
-
Definitions
~~~~~~~~~~~
-The generalized rewriting tactic is based on a set of strategies that
-can be combined to obtain custom rewriting procedures. Its set of
-strategies is based on Elan’s rewriting strategies :ref:`TODO-102-biblio`. Rewriting
+The generalized rewriting tactic is based on a set of strategies that can be
+combined to obtain custom rewriting procedures. Its set of strategies is based
+on Elan’s rewriting strategies :cite:`Luttik97specificationof`. Rewriting
strategies are applied using the tactic ``rewrite_strat s`` where ``s`` is a
-strategy expression. Strategies are defined inductively as described
-by the following grammar:
+strategy expression. Strategies are defined inductively as described by the
+following grammar:
.. productionlist:: rewriting
s, t, u : `strategy`
@@ -808,11 +813,11 @@ 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:`TODO-8.7-performing-computations`) and succeeds
+expression (see :ref:`performingcomputations`) and succeeds
if it reduces the subterm under consideration. The ``fold`` strategy takes
a term ``c`` and tries to *unify* it to the current subterm, converting it to ``c``
on success, it is stronger than the tactic ``fold``.
@@ -822,7 +827,8 @@ Usage
~~~~~
-.. tacv:: rewrite_strat @s [in @ident]
+.. tacn:: rewrite_strat @s [in @ident]
+ :name: rewrite_strat
Rewrite using the strategy s in hypothesis ident or the conclusion.
diff --git a/doc/sphinx/addendum/implicit-coercions.rst b/doc/sphinx/addendum/implicit-coercions.rst
index f5ca5be44..152f4f655 100644
--- a/doc/sphinx/addendum/implicit-coercions.rst
+++ b/doc/sphinx/addendum/implicit-coercions.rst
@@ -1,7 +1,7 @@
-.. _implicitcoercions:
-
.. include:: ../replaces.rst
+.. _implicitcoercions:
+
Implicit Coercions
====================
@@ -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,49 +124,49 @@ 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:: Ambigous 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`.
- .. 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.
- .. 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.
- .. 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.
- .. 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.
Assumptions can be declared as coercions at declaration time.
This extends the grammar of assumptions from
-Figure :ref:`TODO-1.3-sentences-syntax` as follows:
+Figure :ref:`vernacular` as follows:
..
FIXME:
@@ -186,7 +186,7 @@ assumptions are declared as coercions.
Similarly, constructors of inductive types can be declared as coercions at
definition time of the inductive type. This extends and modifies the
-grammar of inductive types from Figure :ref:`TODO-1.3-sentences-syntax` as follows:
+grammar of inductive types from Figure :ref:`vernacular` as follows:
..
FIXME:
@@ -202,7 +202,7 @@ grammar of inductive types from Figure :ref:`TODO-1.3-sentences-syntax` as follo
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,14 @@ 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
`ident` is defined and an identity coercion of name
@@ -228,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.
@@ -236,67 +237,67 @@ 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.
Activating the Printing of Coercions
-------------------------------------
-.. cmd:: Set Printing Coercions.
+.. opt:: Printing Coercions
+
+ When on, this option forces all the coercions to be printed.
+ By default, coercions are not printed.
+
+.. cmd:: Add Printing Coercion @qualid
- This command forces all the coercions to be printed.
- Conversely, to skip the printing of coercions, use
- ``Unset Printing Coercions``. By default, coercions are not printed.
+ This command forces coercion denoted by :n:`@qualid` to be printed.
+ By default, a coercion is never printed.
-.. cmd:: Add Printing Coercion @qualid.
+.. cmd:: Remove Printing Coercion @qualid
- This command forces coercion denoted by `qualid` to be printed.
- To skip the printing of coercion `qualid`, use
- ``Remove Printing Coercion`` `qualid`. By default, a coercion is never printed.
+ Use this command, to skip the printing of coercion :n:`@qualid`.
+.. _coercions-classes-as-records:
Classes as Records
------------------
-We allow the definition of *Structures with Inheritance* (or
-classes as records) by extending the existing ``Record`` macro
-(see Section :ref:`TODO-2.1-Record`). Its new syntax is:
+We allow the definition of *Structures with Inheritance* (or classes as records)
+by extending the existing :cmd:`Record` macro. Its new syntax is:
-.. cmd:: 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
- of the constuctor (it will be ``Build_``\ `ident` if not given).
- The other identifiers are the names of the fields, and the `term`
- are their respective types. If ``:>`` is used instead of ``:`` in
- the declaration of a field, then the name of this field is automatically
- declared as a coercion from the record name to the class of this
- field type. Remark that the fields always verify the uniform
- inheritance condition. If the optional ``>`` is given before the
- record name, then the constructor name is automatically declared as
- a coercion from the class of the last field type to the record name
- (this may fail if the uniform inheritance condition is not
- satisfied).
+ The first identifier `ident` is the name of the defined record and
+ `sort` is its type. The optional identifier after ``:=`` is the name
+ of the constuctor (it will be ``Build_``\ `ident` if not given).
+ The other identifiers are the names of the fields, and the `term`
+ are their respective types. If ``:>`` is used instead of ``:`` in
+ the declaration of a field, then the name of this field is automatically
+ declared as a coercion from the record name to the class of this
+ field type. Remark that the fields always verify the uniform
+ inheritance condition. If the optional ``>`` is given before the
+ record name, then the constructor name is automatically declared as
+ a coercion from the class of the last field type to the record name
+ (this may fail if the uniform inheritance condition is not
+ satisfied).
-.. note::
+.. cmdv:: Structure {? >} @ident {? @binders} : @sort := {? @ident} { {+; @ident :{? >} @term } }
+ :name: Structure
- The keyword ``Structure`` is a synonym of ``Record``.
-
-..
- FIXME: \comindex{Structure}
+ This is a synonym of :cmd:`Record`.
Coercions and Sections
@@ -312,20 +313,17 @@ coercions which do not verify the uniform inheritance condition any longer
are also forgotten.
Coercions and Modules
---------------------=
-
-From |Coq| version 8.3, the coercions present in a module are activated
-only when the module is explicitly imported. Formerly, the coercions
-were activated as soon as the module was required, whatever it was
-imported or not.
-
-To recover the behavior of the versions of |Coq| prior to 8.3, use the
-following command:
+---------------------
-.. cmd:: Set Automatic Coercions Import.
+.. opt:: Automatic Coercions Import
-To cancel the effect of the option, use instead ``Unset Automatic Coercions Import``.
+ Since |Coq| version 8.3, the coercions present in a module are activated
+ only when the module is explicitly imported. Formerly, the coercions
+ were activated as soon as the module was required, whatever it was
+ imported or not.
+ This option makes it possible to recover the behavior of the versions of
+ |Coq| prior to 8.3.
Examples
--------
diff --git a/doc/sphinx/addendum/micromega.rst b/doc/sphinx/addendum/micromega.rst
index e850587c8..f887a5fee 100644
--- a/doc/sphinx/addendum/micromega.rst
+++ b/doc/sphinx/addendum/micromega.rst
@@ -13,20 +13,19 @@ tactics for solving arithmetic goals over :math:`\mathbb{Z}`, :math:`\mathbb{Q}`
It also possible to get the tactics for integers by a ``Require Import Lia``,
rationals ``Require Import Lqa`` and reals ``Require Import Lra``.
-+ ``lia`` is a decision procedure for linear integer arithmetic (see Section :ref:`lia <lia>`);
-+ ``nia`` is an incomplete proof procedure for integer non-linear
- arithmetic (see Section :ref:`nia <nia>`);
-+ ``lra`` is a decision procedure for linear (real or rational) arithmetic
- (see Section :ref:`lra <lra>`);
-+ ``nra`` is an incomplete proof procedure for non-linear (real or
- rational) arithmetic (see Section :ref:`nra <nra>`);
-+ ``psatz D n`` where ``D`` is :math:`\mathbb{Z}` or :math:`\mathbb{Q}` or :math:`\mathbb{R}`, and
++ :tacn:`lia` is a decision procedure for linear integer arithmetic;
++ :tacn:`nia` is an incomplete proof procedure for integer non-linear
+ arithmetic;
++ :tacn:`lra` is a decision procedure for linear (real or rational) arithmetic;
++ :tacn:`nra` is an incomplete proof procedure for non-linear (real or
+ rational) arithmetic;
++ :tacn:`psatz` ``D n`` where ``D`` is :math:`\mathbb{Z}` or :math:`\mathbb{Q}` or :math:`\mathbb{R}`, and
``n`` is an optional integer limiting the proof search depth
is an incomplete proof procedure for non-linear arithmetic.
It is based on John Harrison’s HOL Light
driver to the external prover `csdp` [#]_. Note that the `csdp` driver is
generating a *proof cache* which makes it possible to rerun scripts
- even without `csdp` (see Section :ref:`psatz <psatz>`).
+ even without `csdp`.
The tactics solve propositional formulas parameterized by atomic
arithmetic expressions interpreted over a domain :math:`D` ∈ {ℤ, ℚ, ℝ}.
@@ -91,12 +90,13 @@ For each conjunct :math:`C_i`, the tactic calls a oracle which searches for
expression* that is normalized by the ring tactic (see :ref:`theringandfieldtacticfamilies`)
and checked to be :math:`-1`.
-.. _lra:
-
`lra`: a decision procedure for linear real and rational arithmetic
-------------------------------------------------------------------
-The `lra` tactic is searching for *linear* refutations using Fourier
+.. tacn:: lra
+ :name: lra
+
+This tactic is searching for *linear* refutations using Fourier
elimination [#]_. As a result, this tactic explores a subset of the *Cone*
defined as
@@ -107,16 +107,17 @@ The deductive power of `lra` is the combined deductive power of
tactic *e.g.*, :math:`x = 10 * x / 10` is solved by `lra`.
-.. _lia:
-
`lia`: a tactic for linear integer arithmetic
---------------------------------------------
-The tactic lia offers an alternative to the omega and romega tactic
-(see :ref:`omega`). Roughly speaking, the deductive power of lia is
-the combined deductive power of `ring_simplify` and `omega`. However, it
-solves linear goals that `omega` and `romega` do not solve, such as the
-following so-called *omega nightmare* :cite:`TheOmegaPaper`.
+.. tacn:: lia
+ :name: lia
+
+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
+so-called *omega nightmare* :cite:`TheOmegaPaper`.
.. coqtop:: in
@@ -124,8 +125,8 @@ following so-called *omega nightmare* :cite:`TheOmegaPaper`.
27 <= 11 * x + 13 * y <= 45 ->
-10 <= 7 * x - 9 * y <= 4 -> False.
-The estimation of the relative efficiency of `lia` *vs* `omega` and `romega`
-is under evaluation.
+The estimation of the relative efficiency of :tacn:`lia` *vs* :tacn:`omega` and
+:tacn:`romega` is under evaluation.
High level view of `lia`
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -182,12 +183,13 @@ Our current oracle tries to find an expression :math:`e` with a small range
with an equation :math:`e = i` for :math:`i \in [c_1,c_2]` and recursively search for
a proof.
-.. _nra:
-
`nra`: a proof procedure for non-linear arithmetic
--------------------------------------------------
-The `nra` tactic is an *experimental* proof procedure for non-linear
+.. tacn:: nra
+ :name: nra
+
+This tactic is an *experimental* proof procedure for non-linear
arithmetic. The tactic performs a limited amount of non-linear
reasoning before running the linear prover of `lra`. This pre-processing
does the following:
@@ -202,21 +204,23 @@ does the following:
After this pre-processing, the linear prover of `lra` searches for a
proof by abstracting monomials by variables.
-.. _nia:
-
`nia`: a proof procedure for non-linear integer arithmetic
----------------------------------------------------------
-The `nia` tactic is a proof procedure for non-linear integer arithmetic.
+.. tacn:: nia
+ :name: nia
+
+This tactic is a proof procedure for non-linear integer arithmetic.
It performs a pre-processing similar to `nra`. The obtained goal is
solved using the linear integer prover `lia`.
-.. _psatz:
-
`psatz`: a proof procedure for non-linear arithmetic
----------------------------------------------------
-The `psatz` tactic explores the :math:`\mathit{Cone}` by increasing degrees – hence the
+.. tacn:: psatz
+ :name: psatz
+
+This tactic explores the :math:`\mathit{Cone}` by increasing degrees – hence the
depth parameter :math:`n`. In theory, such a proof search is complete – if the
goal is provable the search eventually stops. Unfortunately, the
external oracle is using numeric (approximate) optimization techniques
diff --git a/doc/sphinx/addendum/miscellaneous-extensions.rst b/doc/sphinx/addendum/miscellaneous-extensions.rst
index b0343a8f0..80ea8a116 100644
--- a/doc/sphinx/addendum/miscellaneous-extensions.rst
+++ b/doc/sphinx/addendum/miscellaneous-extensions.rst
@@ -3,18 +3,10 @@
.. _miscellaneousextensions:
Miscellaneous extensions
-=======================
-
-:Source: https://coq.inria.fr/distrib/current/refman/miscellaneous.html
-:Converted by: Paul Steckler
-
-.. contents::
- :local:
- :depth: 1
-----
+========================
Program derivation
------------------
+------------------
|Coq| comes with an extension called ``Derive``, which supports program
derivation. Typically in the style of Bird and Meertens or derivations
@@ -28,7 +20,7 @@ The first `ident` can appear in `term`. This command opens a new proof
presenting the user with a goal for term in which the name `ident` is
bound to an existential variable `?x` (formally, there are other goals
standing for the existential variables but they are shelved, as
-described in Section :ref:`TODO-8.17.4`).
+described in :tacn:`shelve`).
When the proof ends two constants are defined:
diff --git a/doc/sphinx/addendum/nsatz.rst b/doc/sphinx/addendum/nsatz.rst
index ef9b3505d..387d61495 100644
--- a/doc/sphinx/addendum/nsatz.rst
+++ b/doc/sphinx/addendum/nsatz.rst
@@ -19,7 +19,7 @@ where :math:`P, Q, P₁,Q₁,\ldots,Pₛ, Qₛ` are polynomials and :math:`A` is
domain, i.e. a commutative ring with no zero divisor. For example, :math:`A`
can be :math:`\mathbb{R}`, :math:`\mathbb{Z}`, or :math:`\mathbb{Q}`.
Note that the equality :math:`=` used in these goals can be
-any setoid equality (see :ref:`TODO-27.2.2`) , not only Leibnitz equality.
+any setoid equality (see :ref:`tactics-enabled-on-user-provided-relations`) , not only Leibnitz equality.
It also proves formulas
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/parallel-proof-processing.rst b/doc/sphinx/addendum/parallel-proof-processing.rst
index 8c1b9d152..edb8676a5 100644
--- a/doc/sphinx/addendum/parallel-proof-processing.rst
+++ b/doc/sphinx/addendum/parallel-proof-processing.rst
@@ -39,14 +39,14 @@ Proof annotations
To process a proof asynchronously |Coq| needs to know the precise
statement of the theorem without looking at the proof. This requires
some annotations if the theorem is proved inside a Section (see
-Section :ref:`TODO-2.4`).
+Section :ref:`section-mechanism`).
When a section ends, |Coq| looks at the proof object to decide which
section variables are actually used and hence have to be quantified in
the statement of the theorem. To avoid making the construction of
proofs mandatory when ending a section, one can start each proof with
-the ``Proof using`` command (Section :ref:`TODO-7.1.5`) that declares which section
-variables the theorem uses.
+the ``Proof using`` command (Section :ref:`proof-editing-mode`) that
+declares which section variables the theorem uses.
The presence of ``Proof`` using is needed to process proofs asynchronously
in interactive mode.
diff --git a/doc/sphinx/addendum/program.rst b/doc/sphinx/addendum/program.rst
index eb50e52dc..b685e68e4 100644
--- a/doc/sphinx/addendum/program.rst
+++ b/doc/sphinx/addendum/program.rst
@@ -135,7 +135,7 @@ support types, avoiding uses of proof-irrelevance that would come up
when reasoning with equality on the subset types themselves.
The next two commands are similar to their standard counterparts
-Definition (see Section `TODO-1.3.2-Definition`_) and Fixpoint (see Section `TODO-1.3.4-Fixpoint`_)
+:cmd:`Definition` and :cmd:`Fixpoint`
in that they define constants. However, they may require the user to
prove some goals to construct the final definitions.
@@ -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
+ .. 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:
@@ -174,14 +175,14 @@ Program Definition
.. TODO refer to production in alias
-See also: Sections `TODO-6.10.1-Opaque`_, `TODO-6.10.2-Transparent`_, `TODO-8.7.5-unfold`_
+See also: Sections :ref:`vernac-controlling-the-reduction-strategies`, :tacn:`unfold`
.. _program_fixpoint:
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:
@@ -196,7 +197,7 @@ The optional order annotation follows the grammar:
+ :g:`wf R x` which is equivalent to :g:`measure x (R)`.
The structural fixpoint operator behaves just like the one of |Coq| (see
-Section `TODO-1.3.4-Fixpoint`_), except it may also generate obligations. It works
+:cmd:`Fixpoint`), except it may also generate obligations. It works
with mutually recursive definitions too.
.. coqtop:: reset none
@@ -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
@@ -276,6 +277,7 @@ obligations (e.g. when defining mutually recursive blocks). The
optional tactic is replaced by the default one if not specified.
.. cmd:: {? Local|Global} Obligation Tactic := @tactic
+ :name: Obligation Tactic
Sets the default obligation solving tactic applied to all obligations
automatically, whether to solve them or when starting to prove one,
@@ -348,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 b861892cb..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
@@ -701,7 +701,7 @@ for |Coq|’s type-checker. Let us see why:
At each step of rewriting, the whole context is duplicated in the
proof term. Then, a tactic that does hundreds of rewriting generates
huge proof terms. Since ``ACDSimpl`` was too slow, Samuel Boutin rewrote
-it using reflection (see his article in TACS’97 [Bou97]_). Later, it
+it using reflection (see :cite:`Bou97`). Later, it
was rewritten by Patrick Loiseleur: the new tactic does not any
more require ``ACDSimpl`` to compile and it makes use of |bdi|-reduction not
only to replace the rewriting steps, but also to achieve the
diff --git a/doc/sphinx/addendum/type-classes.rst b/doc/sphinx/addendum/type-classes.rst
index becebb421..6c7258f9c 100644
--- a/doc/sphinx/addendum/type-classes.rst
+++ b/doc/sphinx/addendum/type-classes.rst
@@ -5,9 +5,6 @@
Type Classes
============
-:Source: https://coq.inria.fr/distrib/current/refman/type-classes.html
-:Author: Matthieu Sozeau
-
This chapter presents a quick reference of the commands related to type
classes. For an actual introduction to type classes, there is a
description of the system :cite:`sozeau08` and the literature on type
@@ -71,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.
@@ -151,11 +148,10 @@ database.
Sections and contexts
---------------------
-To ease the parametrization of developments by type classes, we
-provide a new way to introduce variables into section contexts,
-compatible with the implicit argument mechanism. The new command works
-similarly to the ``Variables`` vernacular (:ref:`TODO-1.3.2-Definitions`), except it
-accepts any binding context as argument. For example:
+To ease the parametrization of developments by type classes, we provide a new
+way to introduce variables into section contexts, compatible with the implicit
+argument mechanism. The new command works similarly to the :cmd:`Variables`
+vernacular, except it accepts any binding context as argument. For example:
.. coqtop:: all
@@ -273,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:
@@ -303,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.
@@ -318,233 +309,235 @@ 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.
-Variants:
-
-
-.. cmd:: 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.
-.. cmd:: 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.
-.. cmd:: Program Instance
+.. cmdv:: Program Instance
+ :name: Program Instance
- Switches the type-checking to Program (chapter :ref:`program`) and
+ Switches the type-checking to Program (chapter :ref:`programs`) and
uses the obligation mechanism to manage missing fields.
-.. cmd:: 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
+ :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
+
+ The tactic autoapply applies a term using the transparency information
+ of the hint database ident, and does *no* typeclass resolution. This can
+ be used in :cmd:`Hint Extern`’s for typeclass instances (in the hint
+ database ``typeclass_instances``) to allow backtracking on the typeclass
+ subgoals created by the lemma application, rather than doing type class
+ resolution locally at the hint application time.
+.. _TypeclassesTransparent:
-.. _typeclasses-eauto:
-
-``typeclasses eauto``
-~~~~~~~~~~~~~~~~~~~~~
-
-The ``typeclasses eauto`` tactic uses a different resolution engine than
-eauto and 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]``
+Typeclasses Transparent, Typclasses Opaque
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *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.
+.. cmd:: Typeclasses Transparent {+ @ident}
-#. ``typeclasses eauto with {+ @ident}``
+ This command defines makes the identifiers transparent during type class
+ resolution.
- 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).
+.. cmd:: Typeclasses Opaque {+ @ident}
-.. _autoapply:
+ 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`).
-``autoapply term with ident``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+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:
-The tactic autoapply applies a term using the transparency information
-of the hint database ident, and does *no* typeclass resolution. This can
-be used in ``Hint Extern``’s for typeclass instances (in the hint
-database ``typeclass_instances``) to allow backtracking on the typeclass
-subgoals created by the lemma application, rather than doing type class
-resolution locally at the hint application time.
+::
-.. _TypeclassesTransparent:
+ relation A := A -> A -> Prop.
-Typeclasses Transparent, Typclasses Opaque
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+This is equivalent to ``Hint Transparent, Opaque ident : typeclass_instances``.
-.. cmd:: Typeclasses { Transparent | Opaque } {+ @ident}
- This commands defines the transparency of the given identifiers
- during type class resolution. 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:
+Options
+~~~~~~~
-::
+.. opt:: Typeclasses Dependency Order
- relation A := A -> A -> Prop.
+ 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 8.5 and below). This can result in
+ quite different performance behaviors of proof search.
-This is equivalent to ``Hint Transparent, Opaque ident : typeclass_instances``.
+.. opt:: Typeclasses Filtered Unification
-Set Typeclasses Dependency Order
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ This option, available since Coq 8.6 and off by default, switches the
+ hint application procedure to a filter-then-unify strategy. To apply a
+ hint, we first check that the goal *matches* syntactically the
+ inferred or specified pattern of the hint, and only then try to
+ *unify* the goal with the conclusion of the hint. This can drastically
+ improve performance by calling unification less often, matching
+ syntactic patterns being very quick. This also provides more control
+ on the triggering of instances. For example, forcing a constant to
+ explicitely appear in the pattern will make it never apply on a goal
+ where there is a hole in that place.
-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
-quite different performance behaviors of proof search.
+.. opt:: Typeclasses Limit Intros
-Set Typeclasses Filtered Unification
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ This option (on by default) controls the ability to apply hints while
+ avoiding (functional) eta-expansions in the generated proof term. It
+ does so by allowing hints that conclude in a product to apply to a
+ goal with a matching product directly, avoiding an introduction.
+ *Warning:* this can be expensive as it requires rebuilding hint
+ clauses dynamically, and does not benefit from the invertibility
+ status of the product introduction rule, resulting in potentially more
+ expensive proof-search (i.e. more useless backtracking).
-This option, available since Coq 8.6 and off by default, switches the
-hint application procedure to a filter-then-unify strategy. To apply a
-hint, we first check that the goal *matches* syntactically the
-inferred or specified pattern of the hint, and only then try to
-*unify* the goal with the conclusion of the hint. This can drastically
-improve performance by calling unification less often, matching
-syntactic patterns being very quick. This also provides more control
-on the triggering of instances. For example, forcing a constant to
-explicitely appear in the pattern will make it never apply on a goal
-where there is a hole in that place.
+.. opt:: Typeclass Resolution For Conversion
-Set Typeclasses Limit Intros
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ This option (on by default) controls the use of typeclass resolution
+ when a unification problem cannot be solved during elaboration/type-
+ inference. With this option on, when a unification fails, typeclass
+ resolution is tried before launching unification once again.
-This option (on by default) controls the ability to apply hints while
-avoiding (functional) eta-expansions in the generated proof term. It
-does so by allowing hints that conclude in a product to apply to a
-goal with a matching product directly, avoiding an introduction.
-*Warning:* this can be expensive as it requires rebuilding hint
-clauses dynamically, and does not benefit from the invertibility
-status of the product introduction rule, resulting in potentially more
-expensive proof-search (i.e. more useless backtracking).
+.. opt:: Typeclasses Strict Resolution
+ Typeclass declarations introduced when this option is set have a
+ stricter resolution behavior (the option is off by default). When
+ looking for unifications of a goal with an instance of this class, we
+ “freeze” all the existentials appearing in the goals, meaning that
+ they are considered rigid during unification and cannot be
+ instantiated.
-Set Typeclass Resolution For Conversion
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-This option (on by default) controls the use of typeclass resolution
-when a unification problem cannot be solved during elaboration/type-
-inference. With this option on, when a unification fails, typeclass
-resolution is tried before launching unification once again.
+.. opt:: Typeclasses Unique Solutions
+ When a typeclass resolution is launched we ensure that it has a single
+ solution or fail. This ensures that the resolution is canonical, but
+ can make proof search much more expensive.
-Set Typeclasses Strict Resolution
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Typeclass declarations introduced when this option is set have a
-stricter resolution behavior (the option is off by default). When
-looking for unifications of a goal with an instance of this class, we
-“freeze” all the existentials appearing in the goals, meaning that
-they are considered rigid during unification and cannot be
-instantiated.
+.. opt:: Typeclasses Unique Instances
+ Typeclass declarations introduced when this option is set have a more
+ efficient resolution behavior (the option is off by default). When a
+ solution to the typeclass goal of this class is found, we never
+ backtrack on it, assuming that it is canonical.
-Set Typeclasses Unique Solutions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. opt:: Typeclasses Debug {? Verbosity @num}
-When a typeclass resolution is launched we ensure that it has a single
-solution or fail. This ensures that the resolution is canonical, but
-can make proof search much more expensive.
+ 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
-Set Typeclasses Unique Instances
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ This option allows to switch the behavior of instance declarations made through
+ the Instance command.
-Typeclass declarations introduced when this option is set have a more
-efficient resolution behavior (the option is off by default). When a
-solution to the typeclass goal of this class is found, we never
-backtrack on it, assuming that it is canonical.
+ + 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 `:=`
~~~~~~~~~~~~~~~~~~~~~~
@@ -561,27 +554,3 @@ Typeclasses eauto `:=`
default) or breadth-first search.
+ ``depth`` This sets the depth limit of the search.
-
-
-Set Typeclasses Debug
-~~~~~~~~~~~~~~~~~~~~~
-
-.. cmd:: Set 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…).
-
-
-Set Refine Instance Mode
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-The option Refine Instance Mode 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
new file mode 100644
index 000000000..6e7ccba63
--- /dev/null
+++ b/doc/sphinx/addendum/universe-polymorphism.rst
@@ -0,0 +1,445 @@
+.. include:: ../replaces.rst
+
+.. _polymorphicuniverses:
+
+Polymorphic Universes
+======================
+
+:Author: Matthieu Sozeau
+
+General Presentation
+---------------------
+
+.. warning::
+
+ The status of Universe Polymorphism is experimental.
+
+This section describes the universe polymorphic extension of |Coq|.
+Universe polymorphism makes it possible to write generic definitions
+making use of universes and reuse them at different and sometimes
+incompatible universe levels.
+
+A standard example of the difference between universe *polymorphic*
+and *monomorphic* definitions is given by the identity function:
+
+.. coqtop:: in
+
+ Definition identity {A : Type} (a : A) := a.
+
+By default, constant declarations are monomorphic, hence the identity
+function declares a global universe (say ``Top.1``) for its domain.
+Subsequently, if we try to self-apply the identity, we will get an
+error:
+
+.. coqtop:: all
+
+ Fail Definition selfid := identity (@identity).
+
+Indeed, the global level ``Top.1`` would have to be strictly smaller than
+itself for this self-application to typecheck, as the type of
+:g:`(@identity)` is :g:`forall (A : Type@{Top.1}), A -> A` whose type is itself
+:g:`Type@{Top.1+1}`.
+
+A universe polymorphic identity function binds its domain universe
+level at the definition level instead of making it global.
+
+.. coqtop:: in
+
+ Polymorphic Definition pidentity {A : Type} (a : A) := a.
+
+.. coqtop:: all
+
+ About pidentity.
+
+It is then possible to reuse the constant at different levels, like
+so:
+
+.. coqtop:: in
+
+ Definition selfpid := pidentity (@pidentity).
+
+Of course, the two instances of :g:`pidentity` in this definition are
+different. This can be seen when the :opt:`Printing Universes` option is on:
+
+.. coqtop:: none
+
+ Set Printing Universes.
+
+.. coqtop:: all
+
+ Print selfpid.
+
+Now :g:`pidentity` is used at two different levels: at the head of the
+application it is instantiated at ``Top.3`` while in the argument position
+it is instantiated at ``Top.4``. This definition is only valid as long as
+``Top.4`` is strictly smaller than ``Top.3``, as show by the constraints. Note
+that this definition is monomorphic (not universe polymorphic), so the
+two universes (in this case ``Top.3`` and ``Top.4``) are actually global
+levels.
+
+When printing :g:`pidentity`, we can see the universes it binds in
+the annotation :g:`@{Top.2}`. Additionally, when
+: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).
+
+Inductive types can also be declared universes polymorphic on
+universes appearing in their parameters or fields. A typical example
+is given by monoids:
+
+.. coqtop:: in
+
+ Polymorphic Record Monoid := { mon_car :> Type; mon_unit : mon_car;
+ mon_op : mon_car -> mon_car -> mon_car }.
+
+.. coqtop:: in
+
+ Print Monoid.
+
+The Monoid's carrier universe is polymorphic, hence it is possible to
+instantiate it for example with :g:`Monoid` itself. First we build the
+trivial unit monoid in :g:`Set`:
+
+.. coqtop:: in
+
+ Definition unit_monoid : Monoid :=
+ {| mon_car := unit; mon_unit := tt; mon_op x y := tt |}.
+
+From this we can build a definition for the monoid of :g:`Set`\-monoids
+(where multiplication would be given by the product of monoids).
+
+.. coqtop:: in
+
+ Polymorphic Definition monoid_monoid : Monoid.
+ refine (@Build_Monoid Monoid unit_monoid (fun x y => x)).
+ Defined.
+
+.. coqtop:: all
+
+ Print monoid_monoid.
+
+As one can see from the constraints, this monoid is “large”, it lives
+in a universe strictly higher than :g:`Set`.
+
+Polymorphic, Monomorphic
+-------------------------
+
+.. cmd:: Polymorphic @definition
+
+ As shown in the examples, polymorphic definitions and inductives can be
+ declared using the ``Polymorphic`` prefix.
+
+.. opt:: Universe Polymorphism
+
+ Once enabled, this option will implicitly prepend ``Polymorphic`` to any
+ definition of the user.
+
+.. cmd:: Monomorphic @definition
+
+ When the :opt:`Universe Polymorphism` option is set, to make a definition
+ producing global universe constraints, one can use the ``Monomorphic`` prefix.
+
+Many other commands support the ``Polymorphic`` flag, including:
+
+.. TODO add links on each of these?
+
+- ``Lemma``, ``Axiom``, and all the other “definition” keywords support
+ polymorphism.
+
+- ``Variables``, ``Context``, ``Universe`` and ``Constraint`` in a section support
+ polymorphism. This means that the universe variables (and associated
+ constraints) are discharged polymorphically over definitions that use
+ them. In other words, two definitions in the section sharing a common
+ variable will both get parameterized by the universes produced by the
+ variable declaration. This is in contrast to a “mononorphic” variable
+ which introduces global universes and constraints, making the two
+ definitions depend on the *same* global universes associated to the
+ variable.
+
+- :cmd:`Hint Resolve` and :cmd:`Hint Rewrite` will use the auto/rewrite hint
+ polymorphically, not at a single instance.
+
+Cumulative, NonCumulative
+-------------------------
+
+Polymorphic inductive types, coinductive types, variants and records can be
+declared cumulative using the :g:`Cumulative` prefix.
+
+.. cmd:: Cumulative @inductive
+
+ Declares the inductive as cumulative
+
+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`
+prefix.
+
+.. cmd:: NonCumulative @inductive
+
+ Declares the inductive as non-cumulative
+
+.. opt:: Polymorphic Inductive Cumulativity
+
+ When this option is on, it sets all following polymorphic inductive
+ types as cumulative (it is off by default).
+
+Consider the examples below.
+
+.. coqtop:: in
+
+ Polymorphic Cumulative Inductive list {A : Type} :=
+ | nil : list
+ | cons : A -> list -> list.
+
+.. coqtop:: all
+
+ Print list.
+
+When printing :g:`list`, the universe context indicates the subtyping
+constraints by prefixing the level names with symbols.
+
+Because inductive subtypings are only produced by comparing inductives
+to themselves with universes changed, they amount to variance
+information: each universe is either invariant, covariant or
+irrelevant (there are no contravariant subtypings in Coq),
+respectively represented by the symbols `=`, `+` and `*`.
+
+Here we see that :g:`list` binds an irrelevant universe, so any two
+instances of :g:`list` are convertible: :math:`E[Γ] ⊢ \mathsf{list}@\{i\}~A
+=_{βδιζη} \mathsf{list}@\{j\}~B` whenever :math:`E[Γ] ⊢ A =_{βδιζη} B` and
+this applies also to their corresponding constructors, when
+they are comparable at the same type.
+
+See :ref:`Conversion-rules` for more details on convertibility and subtyping.
+The following is an example of a record with non-trivial subtyping relation:
+
+.. coqtop:: all
+
+ Polymorphic Cumulative Record packType := {pk : Type}.
+
+:g:`packType` binds a covariant universe, i.e.
+
+.. math::
+
+ E[Γ] ⊢ \mathsf{packType}@\{i\} =_{βδιζη}
+ \mathsf{packType}@\{j\}~\mbox{ whenever }~i ≤ j
+
+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 :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.
+
+Consider the following examples.
+
+.. coqtop:: all reset
+
+ Monomorphic Cumulative Inductive Unit := unit.
+
+.. coqtop:: all reset
+
+ Monomorphic NonCumulative Inductive Unit := unit.
+
+.. coqtop:: all reset
+
+ Set Polymorphic Inductive Cumulativity.
+ Inductive Unit := unit.
+
+An example of a proof using cumulativity
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. coqtop:: in
+
+ Set Universe Polymorphism.
+ Set Polymorphic Inductive Cumulativity.
+
+ Inductive eq@{i} {A : Type@{i}} (x : A) : A -> Type@{i} := eq_refl : eq x x.
+
+ Definition funext_type@{a b e} (A : Type@{a}) (B : A -> Type@{b})
+ := forall f g : (forall a, B a),
+ (forall x, eq@{e} (f x) (g x))
+ -> eq@{e} f g.
+
+ Section down.
+ Universes a b e e'.
+ Constraint e' < e.
+ Lemma funext_down {A B}
+ (H : @funext_type@{a b e} A B) : @funext_type@{a b e'} A B.
+ Proof.
+ exact H.
+ Defined.
+ End down.
+
+Cumulativity Weak Constraints
+-----------------------------
+
+.. opt:: Cumulativity Weak Constraints
+
+This option, on by default, causes "weak" constraints to be produced
+when comparing universes in an irrelevant position. Processing weak
+constraints is delayed until minimization time. A weak constraint
+between `u` and `v` when neither is smaller than the other and
+one is flexible causes them to be unified. Otherwise the constraint is
+silently discarded.
+
+This heuristic is experimental and may change in future versions.
+Disabling weak constraints is more predictable but may produce
+arbitrary numbers of universes.
+
+
+Global and local universes
+---------------------------
+
+Each universe is declared in a global or local environment before it
+can be used. To ensure compatibility, every *global* universe is set
+to be strictly greater than :g:`Set` when it is introduced, while every
+*local* (i.e. polymorphically quantified) universe is introduced as
+greater or equal to :g:`Set`.
+
+
+Conversion and unification
+---------------------------
+
+The semantics of conversion and unification have to be modified a
+little to account for the new universe instance arguments to
+polymorphic references. The semantics respect the fact that
+definitions are transparent, so indistinguishable from their bodies
+during conversion.
+
+This is accomplished by changing one rule of unification, the first-
+order approximation rule, which applies when two applicative terms
+with the same head are compared. It tries to short-cut unfolding by
+comparing the arguments directly. In case the constant is universe
+polymorphic, we allow this rule to fire only when unifying the
+universes results in instantiating a so-called flexible universe
+variables (not given by the user). Similarly for conversion, if such
+an equation of applicative terms fail due to a universe comparison not
+being satisfied, the terms are unfolded. This change implies that
+conversion and unification can have different unfolding behaviors on
+the same development with universe polymorphism switched on or off.
+
+
+Minimization
+-------------
+
+Universe polymorphism with cumulativity tends to generate many useless
+inclusion constraints in general. Typically at each application of a
+polymorphic constant :g:`f`, if an argument has expected type :g:`Type@{i}`
+and is given a term of type :g:`Type@{j}`, a :math:`j ≤ i` constraint will be
+generated. It is however often the case that an equation :math:`j = i` would
+be more appropriate, when :g:`f`\'s universes are fresh for example.
+Consider the following example:
+
+.. coqtop:: none
+
+ Polymorphic Definition pidentity {A : Type} (a : A) := a.
+ Set Printing Universes.
+
+.. coqtop:: in
+
+ Definition id0 := @pidentity nat 0.
+
+.. coqtop:: all
+
+ Print id0.
+
+This definition is elaborated by minimizing the universe of :g:`id0` to
+level :g:`Set` while the more general definition would keep the fresh level
+:g:`i` generated at the application of :g:`id` and a constraint that :g:`Set` :math:`≤ i`.
+This minimization process is applied only to fresh universe variables.
+It simply adds an equation between the variable and its lower bound if
+it is an atomic universe (i.e. not an algebraic max() universe).
+
+.. opt:: Universe Minimization ToSet
+
+ Turning this option off (it is on by default) disallows minimization
+ to the sort :g:`Set` and only collapses floating universes between
+ themselves.
+
+
+Explicit Universes
+-------------------
+
+The syntax has been extended to allow users to explicitly bind names
+to universes and explicitly instantiate polymorphic definitions.
+
+.. 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
+ as well. Global universe names live in a separate namespace. The
+ command supports the polymorphic flag only in sections, meaning the
+ universe quantification will be discharged on each section definition
+ independently. One cannot mix polymorphic and monomorphic
+ declarations in the same section.
+
+
+.. 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
+ is then enforced in the global environment. Like ``Universe``, it can be
+ used with the ``Polymorphic`` prefix in sections only to declare
+ constraints discharged at section closing time. One cannot declare a
+ global constraint on polymorphic universes.
+
+ .. exn:: Undeclared universe @ident.
+
+ .. exn:: Universe inconsistency.
+
+
+Polymorphic definitions
+~~~~~~~~~~~~~~~~~~~~~~~
+
+For polymorphic definitions, the declaration of (all) universe levels
+introduced by a definition uses the following syntax:
+
+.. coqtop:: in
+
+ Polymorphic Definition le@{i j} (A : Type@{i}) : Type@{j} := A.
+
+.. coqtop:: all
+
+ Print le.
+
+During refinement we find that :g:`j` must be larger or equal than :g:`i`, as we
+are using :g:`A : Type@{i} <= Type@{j}`, hence the generated constraint. At the
+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 :cmd:`Show Universes` to display the current context of universes.
+
+Definitions can also be instantiated explicitly, giving their full
+instance:
+
+.. coqtop:: all
+
+ Check (pidentity@{Set}).
+ Monomorphic Universes k l.
+ Check (le@{k l}).
+
+User-named universes and the anonymous universe implicitly attached to
+an explicit :g:`Type` are considered rigid for unification and are never
+minimized. Flexible anonymous universes can be produced with an
+underscore or by omitting the annotation to a polymorphic definition.
+
+.. coqtop:: all
+
+ Check (fun x => x) : Type -> Type.
+ Check (fun x => x) : Type -> Type@{_}.
+
+ Check le@{k _}.
+ Check le.
+
+.. opt:: Strict Universe Declaration.
+
+ 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
+ defined. This is meant mainly for debugging purposes.
diff --git a/doc/sphinx/biblio.bib b/doc/sphinx/biblio.bib
index 247f32103..aeb45611e 100644
--- a/doc/sphinx/biblio.bib
+++ b/doc/sphinx/biblio.bib
@@ -675,7 +675,6 @@ s},
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}
@@ -791,8 +790,7 @@ Matching and Term Rewriting},
@TechReport{Leroy90,
author = {X. Leroy},
- title = {The {ZINC} experiment: an economical implementation
-of the {ML} language},
+ title = {The {ZINC} experiment: an economical implementation of the {ML} language},
institution = {INRIA},
number = {117},
year = {1990}
@@ -815,11 +813,12 @@ of the {ML} language},
}
@inproceedings{Luttik97specificationof,
- Author = {Sebastiaan P. Luttik and Eelco Visser},
- Booktitle = {2nd International Workshop on the Theory and Practice of Algebraic Specifications (ASF+SDF'97), Electronic Workshops in Computing},
- Publisher = {Springer-Verlag},
- Title = {Specification of Rewriting Strategies},
- Year = {1997}}
+ author = {Sebastiaan P. Luttik and Eelco Visser},
+ booktitle = {2nd International Workshop on the Theory and Practice of Algebraic Specifications (ASF+SDF'97), Electronic Workshops in Computing},
+ publisher = {Springer-Verlag},
+ title = {Specification of Rewriting Strategies},
+ year = {1997}
+}
@Book{MaL84,
author = {{P. Martin-L\"of}},
@@ -1202,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/credits.rst b/doc/sphinx/credits.rst
index fac0d0a4f..a75659798 100644
--- a/doc/sphinx/credits.rst
+++ b/doc/sphinx/credits.rst
@@ -1307,9 +1307,9 @@ features and deprecations, cleanups of the internals of the system along
with a few new features. The main user visible changes are:
- Kernel: fix a subject reduction failure due to allowing fixpoints
- on non-recursive values, which allows to recover full parametricity
- for CIC, by Matthieu Sozeau. Handling of evars in the VM (the kernel
- still does not accept evars) by Pierre-Marie Pédrot.
+ on non-recursive values, by Matthieu Sozeau.
+ Handling of evars in the VM (the kernel still does not accept evars)
+ by Pierre-Marie Pédrot.
- Notations: many improvements on recursive notations and support for
destructuring patterns in the syntax of notations by Hugo Herbelin.
@@ -1338,7 +1338,14 @@ with a few new features. The main user visible changes are:
- Documentation: a large community effort resulted in the migration
of the reference manual to the Sphinx documentation tool. The result
- is this manual.
+ is this manual. The new documentation infrastructure (based on Sphinx)
+ is by Clément Pit-Claudel. The migration was coordinated by Maxime Dénès
+ and Paul Steckler, with some help of Théo Zimmermann during the
+ final integration phase. The 14 people who ported the manual are
+ Calvin Beck, Heiko Becker, Yves Bertot, Maxime Dénès, Richard Ford,
+ Pierre Letouzey, Assia Mahboubi, Clément Pit-Claudel,
+ Laurence Rideau, Matthieu Sozeau, Paul Steckler, Enrico Tassi,
+ Laurent Théry, Nikita Zyuzin.
- Tools: experimental ``-mangle-names`` option to coqtop/coqc for
linting proof scripts, by Jasper Hugunin.
@@ -1366,17 +1373,16 @@ The OPAM repository for |Coq| packages has been maintained by Guillaume
Melquiond, Matthieu Sozeau, Enrico Tassi with contributions from many
users. A list of packages is available at https://coq.inria.fr/opam/www.
-The 40 contributors for this version are Yves Bertot, Joachim
-Breitner, Tej Chajed, Arthur Charguéraud, Jacques-Pascal Deplaix, Maxime
-Dénès, Jim Fehrle, Yannick Forster, Gaëtan Gilbert, Jason Gross, Samuel
-Gruetter, Thomas Hebb, Hugo Herbelin, Jasper Hugunin, Emilio Jesus
-Gallego Arias, Ralf Jung, Johannes Kloos, Matej Košík, Robbert Krebbers,
-Tony Beta Lambda, Vincent Laporte, Pierre Letouzey, Farzon Lotfi,
-Cyprien Mangin, Guillaume Melquiond, Raphaël Monat, Carl Patenaude
-Poulin, Pierre-Marie Pédrot, Matthew Ryan, Matt Quinn, Sigurd Schneider,
-Bernhard Schommer, Matthieu Sozeau, Arnaud Spiwack, Paul Steckler,
-Enrico Tassi, Anton Trunov, Martin Vassor, Vadim Zaliva and Théo
-Zimmermann.
+The 44 contributors for this version are Yves Bertot, Joachim Breitner, Tej
+Chajed, Arthur Charguéraud, Jacques-Pascal Deplaix, Maxime Dénès, Jim Fehrle,
+Julien Forest, Yannick Forster, Gaëtan Gilbert, Jason Gross, Samuel Gruetter,
+Thomas Hebb, Hugo Herbelin, Jasper Hugunin, Emilio Jesus Gallego Arias, Ralf
+Jung, Johannes Kloos, Matej Košík, Robbert Krebbers, Tony Beta Lambda, Vincent
+Laporte, Peter LeFanu Lumsdaine, Pierre Letouzey, Farzon Lotfi, Cyprien Mangin,
+Guillaume Melquiond, Raphaël Monat, Carl Patenaude Poulin, Pierre-Marie Pédrot,
+Clément Pit-Claudel, Matthew Ryan, Matt Quinn, Sigurd Schneider, Bernhard
+Schommer, Michael Soegtrop, Matthieu Sozeau, Arnaud Spiwack, Paul Steckler,
+Enrico Tassi, Anton Trunov, Martin Vassor, Vadim Zaliva and Théo Zimmermann.
Version 8.8 is the third release of |Coq| developed on a time-based
development cycle. Its development spanned 6 months from the release of
diff --git a/doc/sphinx/index.rst b/doc/sphinx/index.rst
index 15e4ff3bc..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
@@ -16,6 +13,7 @@ Table of contents
.. toctree::
:caption: The language
+ language/gallina-specification-language
language/gallina-extensions
language/coq-library
language/cic
@@ -27,6 +25,7 @@ Table of contents
proof-engine/vernacular-commands
proof-engine/proof-handling
proof-engine/tactics
+ proof-engine/ltac
proof-engine/detailed-tactic-examples
proof-engine/ssreflect-proof-language
@@ -59,6 +58,7 @@ Table of contents
addendum/generalized-rewriting
addendum/parallel-proof-processing
addendum/miscellaneous-extensions
+ addendum/universe-polymorphism
.. toctree::
:caption: Reference
diff --git a/doc/sphinx/introduction.rst b/doc/sphinx/introduction.rst
index 514745c1b..75ff72c4d 100644
--- a/doc/sphinx/introduction.rst
+++ b/doc/sphinx/introduction.rst
@@ -2,12 +2,11 @@
Introduction
------------------------
-This document is the Reference Manual of version 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
@@ -60,7 +59,7 @@ continuous reading. However, it has some structure that is explained
below.
- The first part describes the specification language, |Gallina|.
- Chapters :ref:`thegallinaspecificationlanguage` and :ref:`extensionsofgallina` describe the concrete
+ Chapters :ref:`gallinaspecificationlanguage` and :ref:`extensionsofgallina` describe the concrete
syntax as well as the meaning of programs, theorems and proofs in the
Calculus of Inductive Constructions. Chapter :ref:`thecoqlibrary` describes the
standard library of |Coq|. Chapter :ref:`calculusofinductiveconstructions` is a mathematical description
@@ -76,7 +75,7 @@ below.
Chapter :ref:`proofhandling`. In Chapter :ref:`tactics`, all commands that
realize one or more steps of the proof are presented: we call them
*tactics*. The language to combine these tactics into complex proof
- strategies is given in Chapter :ref:`thetacticlanguage`. Examples of tactics
+ strategies is given in Chapter :ref:`ltac`. Examples of tactics
are described in Chapter :ref:`detailedexamplesoftactics`.
- The third part describes how to extend the syntax of |Coq|. It
diff --git a/doc/sphinx/language/cic.rst b/doc/sphinx/language/cic.rst
index 7ed652409..f6bab0267 100644
--- a/doc/sphinx/language/cic.rst
+++ b/doc/sphinx/language/cic.rst
@@ -97,7 +97,7 @@ ensure the existence of a mapping of the universes to the positive
integers, the graph of constraints must remain acyclic. Typing
expressions that violate the acyclicity of the graph of constraints
results in a Universe inconsistency error (see also Section
-:ref:`TODO-2.10`).
+:ref:`printing-universes`).
.. _Terms:
@@ -373,19 +373,22 @@ following rules.
-**Remark**: **Prod-Prop** and **Prod-Set** typing-rules make sense if we consider the
-semantic difference between :math:`\Prop` and :math:`\Set`:
+.. note::
+ **Prod-Prop** and **Prod-Set** typing-rules make sense if we consider the
+ semantic difference between :math:`\Prop` and :math:`\Set`:
-+ All values of a type that has a sort :math:`\Set` are extractable.
-+ No values of a type that has a sort :math:`\Prop` are extractable.
+ + All values of a type that has a sort :math:`\Set` are extractable.
+ + No values of a type that has a sort :math:`\Prop` are extractable.
-**Remark**: We may have :math:`\letin{x}{t:T}{u}` well-typed without having
-:math:`((λ x:T.u) t)` well-typed (where :math:`T` is a type of
-:math:`t`). This is because the value :math:`t` associated to
-:math:`x` may be used in a conversion rule (see Section :ref:`Conversion-rules`).
+.. note::
+ We may have :math:`\letin{x}{t:T}{u}` well-typed without having
+ :math:`((λ x:T.u) t)` well-typed (where :math:`T` is a type of
+ :math:`t`). This is because the value :math:`t` associated to
+ :math:`x` may be used in a conversion rule
+ (see Section :ref:`Conversion-rules`).
.. _Conversion-rules:
@@ -398,9 +401,11 @@ can decide if two programs are *intentionally* equal (one says
*convertible*). Convertibility is described in this section.
-.. _β-reduction:
+.. _beta-reduction:
+
+β-reduction
+~~~~~~~~~~~
-**β-reduction.**
We want to be able to identify some terms as we can identify the
application of a function to a given argument with its result. For
instance the identity function over a given type T can be written
@@ -424,9 +429,11 @@ theoretically of great importance but we will not detail them here and
refer the interested reader to :cite:`Coq85`.
-.. _ι-reduction:
+.. _iota-reduction:
+
+ι-reduction
+~~~~~~~~~~~
-**ι-reduction.**
A specific conversion rule is associated to the inductive objects in
the global environment. We shall give later on (see Section
:ref:`Well-formed-inductive-definitions`) the precise rules but it
@@ -435,9 +442,11 @@ constructor behaves as expected. This reduction is called ι-reduction
and is more precisely studied in :cite:`Moh93,Wer94`.
-.. _δ-reduction:
+.. _delta-reduction:
+
+δ-reduction
+~~~~~~~~~~~
-**δ-reduction.**
We may have variables defined in local contexts or constants defined
in the global environment. It is legal to identify such a reference
with its value, that is to expand (or unfold) it into its value. This
@@ -458,9 +467,11 @@ reduction is called δ-reduction and shows as follows.
E[Γ] ⊢ c~\triangleright_δ~t
-.. _ζ-reduction:
+.. _zeta-reduction:
+
+ζ-reduction
+~~~~~~~~~~~
-**ζ-reduction.**
|Coq| allows also to remove local definitions occurring in terms by
replacing the defined variable by its value. The declaration being
destroyed, this reduction differs from δ-reduction. It is called
@@ -475,9 +486,11 @@ destroyed, this reduction differs from δ-reduction. It is called
E[Γ] ⊢ \letin{x}{u}{t}~\triangleright_ζ~\subst{t}{x}{u}
-.. _η-expansion:
+.. _eta-expansion:
+
+η-expansion
+~~~~~~~~~~~
-**η-expansion.**
Another important concept is η-expansion. It is legal to identify any
term :math:`t` of functional type :math:`∀ x:T, U` with its so-called η-expansion
@@ -487,34 +500,38 @@ term :math:`t` of functional type :math:`∀ x:T, U` with its so-called η-expan
for :math:`x` an arbitrary variable name fresh in :math:`t`.
-**Remark**: We deliberately do not define η-reduction:
+.. note::
-.. math::
- λ x:T. (t~x) \not\triangleright_η t
+ We deliberately do not define η-reduction:
-This is because, in general, the type of :math:`t` need not to be convertible
-to the type of :math:`λ x:T. (t~x)`. E.g., if we take :math:`f` such that:
+ .. math::
+ λ x:T. (t~x) \not\triangleright_η t
-.. math::
- f : ∀ x:\Type(2),\Type(1)
+ This is because, in general, the type of :math:`t` need not to be convertible
+ to the type of :math:`λ x:T. (t~x)`. E.g., if we take :math:`f` such that:
+
+ .. math::
+ f : ∀ x:\Type(2),\Type(1)
-then
+ then
-.. math::
- λ x:\Type(1),(f~x) : ∀ x:\Type(1),\Type(1)
+ .. math::
+ λ x:\Type(1),(f~x) : ∀ x:\Type(1),\Type(1)
-We could not allow
+ We could not allow
-.. math::
- λ x:Type(1),(f x) \triangleright_η f
+ .. math::
+ λ x:Type(1),(f x) \triangleright_η f
-because the type of the reduced term :math:`∀ x:\Type(2),\Type(1)` would not be
-convertible to the type of the original term :math:`∀ x:\Type(1),\Type(1).`
+ because the type of the reduced term :math:`∀ x:\Type(2),\Type(1)` would not be
+ convertible to the type of the original term :math:`∀ x:\Type(1),\Type(1).`
+
+.. _convertibility:
-.. _Convertibility:
+Convertibility
+~~~~~~~~~~~~~~
-**Convertibility.**
Let us write :math:`E[Γ] ⊢ t \triangleright u` for the contextual closure of the
relation :math:`t` reduces to :math:`u` in the global environment
:math:`E` and local context :math:`Γ` with one of the previous
@@ -704,8 +721,6 @@ called the *context of parameters*. Furthermore, we must have that
each :math:`T` in :math:`(t:T)∈Γ_I` can be written as: :math:`∀Γ_P,∀Γ_{\mathit{Arr}(t)}, S` where
:math:`Γ_{\mathit{Arr}(t)}` is called the *Arity* of the inductive type t and :math:`S` is called
the sort of the inductive type t (not to be confused with :math:`\Sort` which is the set of sorts).
-
-
** Examples** The declaration for parameterized lists is:
.. math::
@@ -794,18 +809,18 @@ contains an inductive declaration.
---------------------
E[Γ] ⊢ c : C
-**Example.**
-Provided that our environment :math:`E` contains inductive definitions we showed before,
-these two inference rules above enable us to conclude that:
+.. example::
+ Provided that our environment :math:`E` contains inductive definitions we showed before,
+ these two inference rules above enable us to conclude that:
-.. math::
- \begin{array}{l}
+ .. math::
+ \begin{array}{l}
E[Γ] ⊢ \even : \nat→\Prop\\
E[Γ] ⊢ \odd : \nat→\Prop\\
E[Γ] ⊢ \even\_O : \even~O\\
E[Γ] ⊢ \even\_S : \forall~n:\nat, \odd~n → \even~(S~n)\\
E[Γ] ⊢ \odd\_S : \forall~n:\nat, \even~n → \odd~(S~n)
- \end{array}
+ \end{array}
@@ -820,8 +835,9 @@ to inconsistent systems. We restrict ourselves to definitions which
satisfy a syntactic criterion of positivity. Before giving the formal
rules, we need a few definitions:
+Arity of a given sort
++++++++++++++++++++++
-**Type is an Arity of Sort S.**
A type :math:`T` is an *arity of sort s* if it converts to the sort s or to a
product :math:`∀ x:T,U` with :math:`U` an arity of sort s.
@@ -831,7 +847,8 @@ product :math:`∀ x:T,U` with :math:`U` an arity of sort s.
:math:`\Prop`.
-**Type is an Arity.**
+Arity
++++++
A type :math:`T` is an *arity* if there is a :math:`s∈ \Sort` such that :math:`T` is an arity of
sort s.
@@ -841,32 +858,34 @@ sort s.
:math:`A→ Set` and :math:`∀ A:\Prop,A→ \Prop` are arities.
-**Type of Constructor of I.**
+Type constructor
+++++++++++++++++
We say that T is a *type of constructor of I* in one of the following
two cases:
-
+ :math:`T` is :math:`(I~t_1 … t_n )`
+ :math:`T` is :math:`∀ x:U,T'` where :math:`T'` is also a type of constructor of :math:`I`
-
-
.. example::
:math:`\nat` and :math:`\nat→\nat` are types of constructor of :math:`\nat`.
:math:`∀ A:Type,\List~A` and :math:`∀ A:Type,A→\List~A→\List~A` are types of constructor of :math:`\List`.
-**Positivity Condition.**
+.. _positivity:
+
+Positivity Condition
+++++++++++++++++++++
+
The type of constructor :math:`T` will be said to *satisfy the positivity
condition* for a constant :math:`X` in the following cases:
-
+ :math:`T=(X~t_1 … t_n )` and :math:`X` does not occur free in any :math:`t_i`
+ :math:`T=∀ x:U,V` and :math:`X` occurs only strictly positively in :math:`U` and the type :math:`V`
satisfies the positivity condition for :math:`X`.
-
-**Occurs Strictly Positively.**
+Strict positivity
++++++++++++++++++
+
The constant :math:`X` *occurs strictly positively* in :math:`T` in the following
cases:
@@ -886,63 +905,51 @@ cases:
any of the :math:`t_i`, and the (instantiated) types of constructor
:math:`\subst{C_i}{p_j}{a_j}_{j=1… m}` of :math:`I` satisfy the nested positivity condition for :math:`X`
-**Nested Positivity Condition.**
+Nested Positivity
++++++++++++++++++
+
The type of constructor :math:`T` of :math:`I` *satisfies the nested positivity
condition* for a constant :math:`X` in the following cases:
-
+ :math:`T=(I~b_1 … b_m~u_1 … u_p)`, :math:`I` is an inductive definition with :math:`m`
parameters and :math:`X` does not occur in any :math:`u_i`
+ :math:`T=∀ x:U,V` and :math:`X` occurs only strictly positively in :math:`U` and the type :math:`V`
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:
- Module TreeExample.
- Inductive tree (A:Type) : Type :=
- | leaf : tree A
- | node : A -> (nat -> tree A) -> tree A.
+ .. coqtop:: in
+
+ Inductive nattree (A:Type) : Type :=
+ | leaf : nattree A
+ | node : A -> (nat -> nattree A) -> nattree A.
End TreeExample.
-::
+ Then every instantiated constructor of ``nattree A`` satisfies the nested positivity
+ condition for ``nattree``:
- [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:
-**Correctness rules.**
+Correctness rules
++++++++++++++++++
+
We shall now describe the rules allowing the introduction of a new
inductive definition.
@@ -1009,7 +1016,9 @@ has type :math:`\Type(k)` with :math:`k<j` and :math:`k≤ i`.
.. _Template-polymorphism:
-**Template polymorphism.**
+Template polymorphism
++++++++++++++++++++++
+
Inductive types declared in Type are polymorphic over their arguments
in Type. If :math:`A` is an arity of some sort and s is a sort, we write :math:`A_{/s}`
for the arity obtained from :math:`A` by replacing its sort with s.
@@ -1053,7 +1062,7 @@ provided that the following side conditions hold:
we have :math:`(E[Γ_{I′} ;Γ_{P′}] ⊢ C_i : s_{q_i})_{i=1… n}` ;
+ the sorts :math:`s_i` are such that all eliminations, to
:math:`\Prop`, :math:`\Set` and :math:`\Type(j)`, are allowed
- (see Section Destructors_).
+ (see Section :ref:`Destructors`).
@@ -1083,14 +1092,14 @@ The sorts :math:`s_j` are chosen canonically so that each :math:`s_j` is minimal
respect to the hierarchy :math:`\Prop ⊂ \Set_p ⊂ \Type` where :math:`\Set_p` is predicative
:math:`\Set`. More precisely, an empty or small singleton inductive definition
(i.e. an inductive definition of which all inductive types are
-singleton – see paragraph Destructors_) is set in :math:`\Prop`, a small non-singleton
+singleton – see Section :ref:`Destructors`) is set in :math:`\Prop`, a small non-singleton
inductive type is set in :math:`\Set` (even in case :math:`\Set` is impredicative – see
Section The-Calculus-of-Inductive-Construction-with-impredicative-Set_),
and otherwise in the Type hierarchy.
Note that the side-condition about allowed elimination sorts in the
rule **Ind-Family** is just to avoid to recompute the allowed elimination
-sorts at each instance of a pattern-matching (see section Destructors_). As
+sorts at each instance of a pattern-matching (see Section :ref:`Destructors`). As
an example, let us consider the following definition:
.. example::
@@ -1106,7 +1115,7 @@ in the Type hierarchy. Here, the parameter :math:`A` has this property, hence,
if :g:`option` is applied to a type in :math:`\Set`, the result is in :math:`\Set`. Note that
if :g:`option` is applied to a type in :math:`\Prop`, then, the result is not set in
:math:`\Prop` but in :math:`\Set` still. This is because :g:`option` is not a singleton type
-(see section Destructors_) and it would lose the elimination to :math:`\Set` and :math:`\Type`
+(see Section :ref:`Destructors`) and it would lose the elimination to :math:`\Set` and :math:`\Type`
if set in :math:`\Prop`.
.. example::
@@ -1135,9 +1144,10 @@ eliminations schemes are allowed.
Check (fun (A:Prop) (B:Set) => prod A B).
Check (fun (A:Type) (B:Prop) => prod A B).
-Remark: Template polymorphism used to be called “sort-polymorphism of
-inductive types” before universe polymorphism (see Chapter :ref:`polymorphicuniverses`) was
-introduced.
+.. note::
+ Template polymorphism used to be called “sort-polymorphism of
+ inductive types” before universe polymorphism
+ (see Chapter :ref:`polymorphicuniverses`) was introduced.
.. _Destructors:
@@ -1213,9 +1223,11 @@ Coquand in :cite:`Coq92`. One is the definition by pattern-matching. The
second one is a definition by guarded fixpoints.
-.. _The-match…with-end-construction:
+.. _match-construction:
+
+The match ... with ... end construction
++++++++++++++++++++++++++++++++++++++++
-**The match…with …end construction**
The basic idea of this operator is that we have an object :math:`m` in an
inductive type :math:`I` and we want to prove a property which possibly
depends on :math:`m`. For this, it is enough to prove the property for
@@ -1272,7 +1284,7 @@ and :math:`I:A` and :math:`λ a x . P : B` then by :math:`[I:A|B]` we mean that
:math:`λ a x . P` with :math:`m` in the above match-construct.
-.. _Notations:
+.. _cic_notations:
**Notations.** The :math:`[I:A|B]` is defined as the smallest relation satisfying the
following rules: We write :math:`[I|B]` for :math:`[I:A|B]` where :math:`A` is the type of :math:`I`.
@@ -1473,20 +1485,20 @@ definition :math:`\ind{r}{Γ_I}{Γ_C}` with :math:`Γ_C = [c_1 :C_1 ;…;c_n :C_
-**Example.**
-Below is a typing rule for the term shown in the previous example:
+.. example::
+ Below is a typing rule for the term shown in the previous example:
-.. inference:: list example
+ .. inference:: list example
- \begin{array}{l}
- E[Γ] ⊢ t : (\List ~\nat) \\
- E[Γ] ⊢ P : B \\
- [(\List ~\nat)|B] \\
- E[Γ] ⊢ f_1 : {(\kw{nil} ~\nat)}^P \\
- E[Γ] ⊢ f_2 : {(\kw{cons} ~\nat)}^P
- \end{array}
- ------------------------------------------------
- E[Γ] ⊢ \case(t,P,f_1 |f_2 ) : (P~t)
+ \begin{array}{l}
+ E[Γ] ⊢ t : (\List ~\nat) \\
+ E[Γ] ⊢ P : B \\
+ [(\List ~\nat)|B] \\
+ E[Γ] ⊢ f_1 : {(\kw{nil} ~\nat)}^P \\
+ E[Γ] ⊢ f_2 : {(\kw{cons} ~\nat)}^P
+ \end{array}
+ ------------------------------------------------
+ E[Γ] ⊢ \case(t,P,f_1 |f_2 ) : (P~t)
.. _Definition-of-ι-reduction:
@@ -1619,9 +1631,8 @@ Given a variable :math:`y` of type an inductive definition in a declaration
ones in which one of the :math:`I_l` occurs) are structurally smaller than y.
-The following definitions are correct, we enter them using the ``Fixpoint``
-command as described in Section :ref:`TODO-1.3.4` and show the internal
-representation.
+The following definitions are correct, we enter them using the :cmd:`Fixpoint`
+command and show the internal representation.
.. example::
.. coqtop:: all
@@ -1678,7 +1689,7 @@ possible:
**Mutual induction**
The principles of mutual induction can be automatically generated
-using the Scheme command described in Section :ref:`TODO-13.1`.
+using the Scheme command described in Section :ref:`proofschemes-induction-principles`.
.. _Admissible-rules-for-global-environments:
diff --git a/doc/sphinx/language/coq-library.rst b/doc/sphinx/language/coq-library.rst
index 29053d6a5..6af6e7897 100644
--- a/doc/sphinx/language/coq-library.rst
+++ b/doc/sphinx/language/coq-library.rst
@@ -5,9 +5,6 @@
The |Coq| library
=================
-:Source: https://coq.inria.fr/distrib/current/refman/stdlib.html
-:Converted by: Pierre Letouzey
-
.. index::
single: Theories
@@ -22,7 +19,7 @@ The |Coq| library is structured into two parts:
developments of |Coq| axiomatizations about sets, lists, sorting,
arithmetic, etc. This library comes with the system and its modules
are directly accessible through the ``Require`` command (see
- Section :ref:`TODO-6.5.1-Require`);
+ Section :ref:`compiled-files`);
In addition, user-provided libraries or developments are provided by
|Coq| users' community. These libraries and developments are available
@@ -51,6 +48,7 @@ at the |Coq| root directory; this includes the modules
``Tactics``.
Module ``Logic_Type`` also makes it in the initial state.
+.. _init-notations:
Notations
~~~~~~~~~
@@ -93,6 +91,8 @@ Notation Precedence Associativity
``_ ^ _`` 30 right
================ ============ ===============
+.. _coq-library-logic:
+
Logic
~~~~~
@@ -524,7 +524,7 @@ provides a scope ``nat_scope`` gathering standard notations for
common operations (``+``, ``*``) and a decimal notation for
numbers, allowing for instance to write ``3`` for :g:`S (S (S O)))`. This also works on
the left hand side of a ``match`` expression (see for example
-section :ref:`TODO-refine-example`). This scope is opened by default.
+section :tacn:`refine`). This scope is opened by default.
.. example::
@@ -756,7 +756,7 @@ subdirectories:
These directories belong to the initial load path of the system, and
the modules they provide are compiled at installation time. So they
are directly accessible with the command ``Require`` (see
-Section :ref:`TODO-6.5.1-Require`).
+Section :ref:`compiled-files`).
The different modules of the |Coq| standard library are documented
online at http://coq.inria.fr/stdlib.
@@ -930,9 +930,8 @@ tactics (see Chapter :ref:`tactics`), there are also:
Goal forall x y z:R, x * y * z <> 0.
intros; split_Rmult.
-These tactics has been written with the tactic language Ltac
-described in Chapter :ref:`thetacticlanguage`.
-
+These tactics has been written with the tactic language |Ltac|
+described in Chapter :ref:`ltac`.
List library
~~~~~~~~~~~~
diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst
index 1d6c11b38..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,
@@ -41,7 +41,9 @@ Remark that the type of a particular identifier may depend on a previously-given
order of the fields is important. Finally, each `param` is a parameter of the record.
More generally, a record may have explicitly defined (a.k.a. manifest)
-fields. For instance, we might have::
+fields. For instance, we might have:
+
+.. coqtop:: in
Record ident param : sort := { ident₁ : type₁ ; ident₂ := term₂ ; ident₃ : type₃ }.
@@ -50,6 +52,8 @@ may depend on |ident_1|.
.. example::
+ The set of rational numbers may be defined as:
+
.. coqtop:: reset all
Record Rat : Set := mkRat
@@ -66,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.
@@ -101,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.
@@ -144,7 +148,7 @@ available:
It can be activated for printing with
-.. cmd:: Set Printing Projections.
+.. opt:: Printing Projections
.. example::
@@ -169,7 +173,7 @@ and the syntax `term.(@qualid` |term_1| |term_n| `)` to `@qualid` |term_1| `…`
In each case, `term` is the object projected and the
other arguments are the parameters of the inductive type.
-.. note::. Records defined with the ``Record`` keyword are not allowed to be
+.. note:: Records defined with the ``Record`` keyword are not allowed to be
recursive (references to the record's name in the type of its field
raises an error). To define recursive records, one can use the ``Inductive``
and ``CoInductive`` keywords, resulting in an inductive or co-inductive record.
@@ -179,9 +183,9 @@ other arguments are the parameters of the inductive type.
.. note:: Induction schemes are automatically generated for inductive records.
Automatic generation of induction schemes for non-recursive records
defined with the ``Record`` keyword can be activated with the
- ``Nonrecursive Elimination Schemes`` option (see :ref:`TODO-13.1.1-nonrecursive-elimination-schemes`).
+ ``Nonrecursive Elimination Schemes`` option (see :ref:`proofschemes-induction-principles`).
-.. note::``Structure`` is a synonym of the keyword ``Record``.
+.. note:: ``Structure`` is a synonym of the keyword ``Record``.
.. warn:: @ident cannot be defined.
@@ -189,9 +193,9 @@ other arguments are the parameters of the inductive type.
This message is followed by an explanation of this impossibility.
There may be three reasons:
- #. The name `ident` already exists in the environment (see Section :ref:`TODO-1.3.1-axioms`).
+ #. The name `ident` already exists in the environment (see :cmd:`Axiom`).
#. The body of `ident` uses an incorrect elimination for
- `ident` (see Sections :ref:`TODO-1.3.4-fixpoint` and :ref:`TODO-4.5.3-case-expr`).
+ `ident` (see :cmd:`Fixpoint` and :ref:`Destructors`).
#. The type of the projections `ident` depends on previous
projections which themselves could not be defined.
@@ -208,16 +212,18 @@ other arguments are the parameters of the inductive type.
During the definition of the one-constructor inductive definition, all
the errors of inductive definitions, as described in Section
-:ref:`TODO-1.3.3-inductive-definitions`, may also occur.
+:ref:`gallina-inductive-definitions`, may also occur.
-**See also** Coercions and records in Section :ref:`TODO-18.9-coercions-and-records` of the chapter devoted to coercions.
+**See also** Coercions and records in Section :ref:`coercions-classes-as-records` of the chapter devoted to coercions.
.. _primitive_projections:
Primitive Projections
~~~~~~~~~~~~~~~~~~~~~
-The option ``Set Primitive Projections`` turns on the use of primitive
+.. opt:: Primitive Projections
+
+Turns on the use of primitive
projections when defining subsequent records (even through the ``Inductive``
and ``CoInductive`` commands). Primitive projections
extended the Calculus of Inductive Constructions with a new binary
@@ -229,21 +235,27 @@ terms when manipulating parameterized records and typechecking time.
On the user level, primitive projections can be used as a replacement
for the usual defined ones, although there are a few notable differences.
-The internally omitted parameters can be reconstructed at printing time
-even though they are absent in the actual AST manipulated by the kernel. This
-can be obtained by setting the ``Printing Primitive Projection Parameters``
-flag. Another compatibility printing can be activated thanks to the
-``Printing Primitive Projection Compatibility`` option which governs the
+.. opt:: Printing Primitive Projection Parameters
+
+This compatibility option reconstructs internally omitted parameters at
+printing time (even though they are absent in the actual AST manipulated
+by the kernel).
+
+.. opt:: Printing Primitive Projection Compatibility
+
+This compatibility option (on by default) governs the
printing of pattern-matching over primitive records.
Primitive Record Types
++++++++++++++++++++++
-When the ``Set Primitive Projections`` option is on, definitions of
+When the :opt:`Primitive Projections` option is on, definitions of
record types change meaning. When a type is declared with primitive
projections, its :g:`match` construct is disabled (see :ref:`primitive_projections` though).
To eliminate the (co-)inductive type, one must use its defined primitive projections.
+.. The following paragraph is quite redundant with what is above
+
For compatibility, the parameters still appear to the user when
printing terms even though they are absent in the actual AST
manipulated by the kernel. This can be changed by unsetting the
@@ -304,7 +316,7 @@ printed back as :g:`match` constructs.
Variants and extensions of :g:`match`
-------------------------------------
-.. _extended pattern-matching:
+.. _mult-match:
Multiple and nested pattern-matching
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -316,10 +328,11 @@ patterns are allowed, as in ML-like languages.
The extension just acts as a macro that is expanded during parsing
into a sequence of match on simple patterns. Especially, a
construction defined using the extended match is generally printed
-under its expanded form (see ``Set Printing Matching`` in :ref:`controlling-match-pp`).
+under its expanded form (see :opt:`Printing Matching`).
-See also: :ref:`extended pattern-matching`.
+See also: :ref:`extendedpatternmatching`.
+.. _if-then-else:
Pattern-matching on boolean values: the if expression
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -462,116 +475,63 @@ of :g:`match` expressions.
Printing nested patterns
+++++++++++++++++++++++++
+.. opt:: Printing Matching
+
The Calculus of Inductive Constructions knows pattern-matching only
over simple patterns. It is however convenient to re-factorize nested
pattern-matching into a single pattern-matching over a nested
-pattern. |Coq|’s printer tries to do such limited re-factorization.
-
-.. cmd:: Set Printing Matching.
-
-This tells |Coq| to try to use nested patterns. This is the default
-behavior.
+pattern.
-.. cmd:: Unset Printing Matching.
+When this option is on (default), |Coq|’s printer tries to do such
+limited re-factorization.
+Turning it off tells |Coq| to print only simple pattern-matching problems
+in the same way as the |Coq| kernel handles them.
-This tells |Coq| to print only simple pattern-matching problems in the
-same way as the |Coq| kernel handles them.
-
-.. cmd:: Test Printing Matching.
-
-This tells if the printing matching mode is on or off. The default is
-on.
Factorization of clauses with same right-hand side
++++++++++++++++++++++++++++++++++++++++++++++++++
+.. 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
-printing matching mode is on, whether |Coq|'s printer shall try to do this kind
-of factorization is governed by the following commands:
-
-.. cmd:: Set Printing Factorizable Match Patterns.
-
-This tells |Coq|'s printer to try to use disjunctive patterns. This is the
-default behavior.
-
-.. cmd:: Unset Printing Factorizable Match Patterns.
-
-This tells |Coq|'s printer not to try to use disjunctive patterns.
-
-.. cmd:: Test Printing Factorizable Match Patterns.
-
-This tells if the factorization of clauses with same right-hand side is on or
-off.
+printing matching mode is on, this option (on by default) tells |Coq|'s
+printer to try to do this kind of factorization.
Use of a 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
disjunction of patterns can be replaced with a `_` default clause. Assuming that
-the printing matching mode and the factorization mode are on, whether |Coq|'s
-printer shall try to use a default clause is governed by the following commands:
-
-.. cmd:: Set Printing Allow Default Clause.
-
-This tells |Coq|'s printer to use a default clause when relevant. This is the
-default behavior.
-
-.. cmd:: Unset Printing Allow Default Clause.
-
-This tells |Coq|'s printer not to use a default clause.
-
-.. cmd:: Test Printing Allow Default Clause.
-
-This tells if the use of a default clause is allowed.
+the printing matching mode and the factorization mode are on, this option (on by
+default) tells |Coq|'s printer to use a default clause when relevant.
Printing of wildcard patterns
++++++++++++++++++++++++++++++
-Some variables in a pattern may not occur in the right-hand side of
-the pattern-matching clause. There are options to control the display
-of these variables.
-
-.. cmd:: Set Printing Wildcard.
+.. opt:: Printing Wildcard
-The variables having no occurrences in the right-hand side of the
+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
+variables having no occurrences in the right-hand side of the
pattern-matching clause are just printed using the wildcard symbol
“_”.
-.. cmd:: Unset Printing Wildcard.
-
-The variables, even useless, are printed using their usual name. But
-some non-dependent variables have no name. These ones are still
-printed using a “_”.
-
-.. cmd:: Test Printing Wildcard.
-
-This tells if the wildcard printing mode is on or off. The default is
-to print wildcard for useless variables.
-
Printing of the elimination predicate
+++++++++++++++++++++++++++++++++++++
+.. 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
-depend of the matched term.
-
-.. cmd:: Set Printing Synth.
-
-The result type is not printed when |Coq| knows that it can re-
+depend of the matched term. When this option is on (default),
+the result type is not printed when |Coq| knows that it can re-
synthesize it.
-.. cmd:: Unset Printing Synth.
-
-This forces the result type to be always printed.
-
-.. cmd:: Test Printing Synth.
-
-This tells if the non-printing of synthesizable types is on or off.
-The default is to not print synthesizable types.
-
Printing matching on irrefutable patterns
++++++++++++++++++++++++++++++++++++++++++
@@ -579,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.
@@ -611,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.
@@ -662,12 +622,12 @@ 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
objects*, namely: an induction principle that reflects the recursive
-structure of the function (see Section :ref:`TODO-8.5.5-functional-induction`) and its fixpoint equality.
+structure of the function (see :tacn:`function induction`) and its fixpoint equality.
The meaning of this declaration is to define a function ident,
similarly to ``Fixpoint`. Like in ``Fixpoint``, the decreasing argument must
be given (unless the function is not recursive), but it might not
@@ -680,8 +640,8 @@ The ``Function`` construction also enjoys the ``with`` extension to define
mutually recursive definitions. However, this feature does not work
for non structurally recursive functions.
-See the documentation of functional induction (:ref:`TODO-8.5.5-functional-induction`)
-and ``Functional Scheme`` (:ref:`TODO-13.2-functional-scheme`) for how to use
+See the documentation of functional induction (:tacn:`function induction`)
+and ``Functional Scheme`` (:ref:`functional-scheme`) for how to use
the induction principle to easily reason about the function.
Remark: To obtain the right principle, it is better to put rigid
@@ -729,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
@@ -743,16 +703,16 @@ 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.
-See also: :ref:`TODO-13.2-generating-ind-principles` and ref:`TODO-8.5.5-functional-induction`
+See also: :ref:`functional-scheme` and :tacn:`function induction`
Depending on the ``{…}`` annotation, different definition mechanisms are
used by ``Function``. A more precise description is given below.
@@ -763,7 +723,7 @@ used by ``Function``. A more precise description is given below.
the following are defined:
+ `ident_rect`, `ident_rec` and `ident_ind`, which reflect the pattern
- matching structure of `term` (see the documentation of :ref:`TODO-1.3.3-Inductive`);
+ matching structure of `term` (see :cmd:`Inductive`);
+ The inductive `R_ident` corresponding to the graph of `ident` (silently);
+ `ident_complete` and `ident_correct` which are inversion information
linking the function and its graph.
@@ -812,21 +772,22 @@ used by ``Function``. A more precise description is given below.
hand. Remark: Proof obligations are presented as several subgoals
belonging to a Lemma `ident`\ :math:`_{\sf tcc}`.
+.. _section-mechanism:
Section mechanism
-----------------
The sectioning mechanism can be used to to organize a proof in
structured sections. Then local declarations become available (see
-Section :ref:`TODO-1.3.2-Definitions`).
+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
@@ -859,7 +820,7 @@ Section :ref:`TODO-1.3.2-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:**
@@ -888,44 +849,44 @@ together, as well as a means of massive abstraction.
In the syntax of module application, the ! prefix indicates that any
`Inline` directive in the type of the functor arguments will be ignored
-(see :ref:`named_module_type` below).
+(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`.
- .. 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`. 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
@@ -933,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
@@ -945,42 +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.
-.. _named_module_type:
-
-.. 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`.
@@ -988,43 +947,44 @@ 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`.
-.. cmd:: @assumption_keyword Inline @assums.
+.. cmd:: @assumption_keyword Inline @assums
+ :name: Inline
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`.
@@ -1188,107 +1148,107 @@ some of the fields and give one of its possible implementations:
Notice that ``M`` is a correct body for the component ``M2`` since its ``T``
component is equal ``nat`` and hence ``M1.T`` as specified.
-**Remarks:**
+.. note::
-#. Modules and module types can be nested components of each other.
-#. One can have sections inside a module or a module type, but not a
- module or a module type inside a section.
-#. Commands like ``Hint`` or ``Notation`` can also appear inside modules and
- module types. Note that in case of a module definition like:
+ #. Modules and module types can be nested components of each other.
+ #. One can have sections inside a module or a module type, but not a
+ module or a module type inside a section.
+ #. Commands like ``Hint`` or ``Notation`` can also appear inside modules and
+ module types. Note that in case of a module definition like:
-::
+ ::
- Module N : SIG := M.
+ Module N : SIG := M.
-or::
+ or::
- Module N : SIG. … End N.
+ Module N : SIG. … End N.
-hints and the like valid for ``N`` are not those defined in ``M`` (or the module body) but the ones defined
-in ``SIG``.
+ hints and the like valid for ``N`` are not those defined in ``M``
+ (or the module body) but the ones defined in ``SIG``.
.. _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:`TODO-12.1-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``.
-
-.. cmd:: Locate Module @qualid.
-
- Prints the full name of the module `qualid`.
+ 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
---------------------------------
+.. _names-of-libraries:
+
Names of libraries
~~~~~~~~~~~~~~~~~~
@@ -1296,15 +1256,16 @@ The theories developed in |Coq| are stored in *library files* which are
hierarchically classified into *libraries* and *sublibraries*. To
express this hierarchy, library names are represented by qualified
identifiers qualid, i.e. as list of identifiers separated by dots (see
-:ref:`TODO-1.2.3-identifiers`). For instance, the library file ``Mult`` of the standard
+:ref:`gallina-identifiers`). For instance, the library file ``Mult`` of the standard
|Coq| library ``Arith`` is named ``Coq.Arith.Mult``. The identifier that starts
the name of a library is called a *library root*. All library files of
the standard library of |Coq| have the reserved root |Coq| but library
file names based on other roots can be obtained by using |Coq| commands
-(coqc, coqtop, coqdep, …) options ``-Q`` or ``-R`` (see :ref:`TODO-14.3.3-command-line-options`).
+(coqc, coqtop, coqdep, …) options ``-Q`` or ``-R`` (see :ref:`command-line-options`).
Also, when an interactive |Coq| session starts, a library of root ``Top`` is
-started, unless option ``-top`` or ``-notop`` is set (see :ref:`TODO-14.3.3-command-line-options`).
+started, unless option ``-top`` or ``-notop`` is set (see :ref:`command-line-options`).
+.. _qualified-names:
Qualified names
~~~~~~~~~~~~~~~
@@ -1339,13 +1300,13 @@ names also applies to library file names.
|Coq| maintains a table called the name table which maps partially qualified
names of constructions to absolute names. This table is updated by the
-commands ``Require`` (see :ref:`TODO-6.5.1-Require`), Import and Export (see :ref:`import_qualid`) and
+commands :cmd:`Require`, :cmd:`Import` and :cmd:`Export` and
also each time a new declaration is added to the context. An absolute
name is called visible from a given short or partially qualified name
when this latter name is enough to denote it. This means that the
short or partially qualified name is mapped to the absolute name in
|Coq| name table. Definitions flagged as Local are only accessible with
-their fully qualified name (see :ref:`TODO-1.3.2-definitions`).
+their fully qualified name (see :ref:`gallina-definitions`).
It may happen that a visible name is hidden by the short name or a
qualified name of another construction. In this case, the name that
@@ -1367,16 +1328,15 @@ accessible, absolute names can never be hidden.
Locate nat.
-See also: Command Locate in :ref:`TODO-6.3.10-locate-qualid` and Locate Library in
-:ref:`TODO-6.6.11-locate-library`.
+See also: Commands :cmd:`Locate` and :cmd:`Locate Library`.
+.. _libraries-and-filesystem:
Libraries and filesystem
~~~~~~~~~~~~~~~~~~~~~~~~
-Please note that the questions described here have been subject to
-redesign in |Coq| v8.5. Former versions of |Coq| use the same terminology
-to describe slightly different things.
+.. note:: The questions described here have been subject to redesign in |Coq| 8.5.
+ Former versions of |Coq| use the same terminology to describe slightly different things.
Compiled files (``.vo`` and ``.vio``) store sub-libraries. In order to refer
to them inside |Coq|, a translation from file-system names to |Coq| names
@@ -1412,7 +1372,7 @@ translation and with an empty logical prefix.
The command line option ``-R`` is a variant of ``-Q`` which has the strictly
same behavior regarding loadpaths, but which also makes the
corresponding ``.vo`` files available through their short names in a way
-not unlike the ``Import`` command (see :ref:`import_qualid`). For instance, ``-R`` `path` ``Lib``
+not unlike the ``Import`` command (see :ref:`here <import_qualid>`). For instance, ``-R`` `path` ``Lib``
associates to the ``filepath/fOO/Bar/File.vo`` the logical name
``Lib.fOO.Bar.File``, but allows this file to be accessed through the
short names ``fOO.Bar.File,Bar.File`` and ``File``. If several files with
@@ -1420,7 +1380,7 @@ identical base name are present in different subdirectories of a
recursive loadpath, which of these files is found first may be system-
dependent and explicit qualification is recommended. The ``From`` argument
of the ``Require`` command can be used to bypass the implicit shortening
-by providing an absolute root to the required file (see :ref:`TODO-6.5.1-require-qualid`).
+by providing an absolute root to the required file (see :ref:`compiled-files`).
There also exists another independent loadpath mechanism attached to
OCaml object files (``.cmo`` or ``.cmxs``) rather than |Coq| object
@@ -1428,11 +1388,12 @@ files as described above. The OCaml loadpath is managed using
the option ``-I`` `path` (in the OCaml world, there is neither a
notion of logical name prefix nor a way to access files in
subdirectories of path). See the command ``Declare`` ``ML`` ``Module`` in
-:ref:`TODO-6.5-compiled-files` to understand the need of the OCaml loadpath.
+:ref:`compiled-files` to understand the need of the OCaml loadpath.
-See :ref:`TODO-14.3.3-command-line-options` for a more general view over the |Coq| command
+See :ref:`command-line-options` for a more general view over the |Coq| command
line options.
+.. _ImplicitArguments:
Implicit arguments
------------------
@@ -1477,7 +1438,9 @@ For instance, the first argument of
in module ``List.v`` is strict because :g:`list` is an inductive type and :g:`A`
will always be inferable from the type :g:`list A` of the third argument of
-:g:`cons`. On the contrary, the second argument of a term of type
+:g:`cons`. Also, the first argument of :g:`cons` is strict with respect to the second one,
+since the first argument is exactly the type of the second argument.
+On the contrary, the second argument of a term of type
::
forall P:nat->Prop, forall n:nat, P n -> ex nat P
@@ -1548,10 +1511,9 @@ inserted. In the second case, the function is considered to be
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
-command ``Set Maximal Implicit Insertion`` (see Section :ref:`controlling-insertion-implicit-args`).
+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
+:cmd:`Arguments (implicits)` or globally by the :opt:`Maximal Implicit Insertion` option.
See also :ref:`displaying-implicit-args`.
@@ -1564,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 “_”.
@@ -1603,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
@@ -1626,7 +1589,8 @@ 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
arguments of `qualid` where the ones to be declared implicit are
@@ -1639,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 }
@@ -1648,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
@@ -1706,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
@@ -1780,14 +1744,10 @@ appear strictly in the body of the type, they are implicit.
Mode for automatic declaration of implicit arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-In case one wants to systematically declare implicit the arguments
-detectable as such, one may switch to the automatic declaration of
-implicit arguments mode by using the command:
-
-.. cmd:: Set Implicit Arguments.
+.. opt:: Implicit Arguments
-Conversely, one may unset the mode by using ``Unset Implicit Arguments``.
-The mode is off by default. Auto-detection of implicit arguments is
+This option (off by default) allows to systematically declare implicit
+the arguments detectable as such. Auto-detection of implicit arguments is
governed by options controlling whether strict and contextual implicit
arguments have to be considered or not.
@@ -1796,76 +1756,55 @@ arguments have to be considered or not.
Controlling strict implicit arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. 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
arguments plus, for historical reasons, a small subset of the non-strict
implicit arguments. To relax this constraint and to set
-implicit all non strict implicit arguments by default, use the command:
-
-.. cmd:: Unset Strict Implicit.
-
-Conversely, use the command ``Set Strict Implicit`` to restore the
-original mode that declares implicit only the strict implicit
-arguments plus a small subset of the non strict implicit arguments.
+implicit all non strict implicit arguments by default, you can turn this
+option off.
-In the other way round, to capture exactly the strict implicit
-arguments and no more than the strict implicit arguments, use the
-command
+.. opt:: Strongly Strict Implicit
-.. cmd:: Set Strongly Strict Implicit.
-
-Conversely, use the command ``Unset Strongly Strict Implicit`` to let the
-option “Strict Implicit” decide what to do.
-
-Remark: In versions of |Coq| prior to version 8.0, the default was to
-declare the strict implicit arguments as implicit.
+Use this option (off by default) to capture exactly the strict implicit
+arguments and no more than the strict implicit arguments.
.. _controlling-contextual-implicit-args:
Controlling contextual implicit arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-By default, |Coq| does not automatically set implicit the contextual
-implicit arguments. To tell |Coq| to infer also contextual implicit
-argument, use command
+.. opt:: Contextual Implicit
-.. cmd:: Set Contextual Implicit.
-
-Conversely, use command ``Unset Contextual Implicit`` to unset the
-contextual implicit mode.
+By default, |Coq| does not automatically set implicit the contextual
+implicit arguments. You can turn this option on to tell |Coq| to also
+infer contextual implicit argument.
.. _controlling-rev-pattern-implicit-args:
Controlling reversible-pattern implicit arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-By default, |Coq| does not automatically set implicit the reversible-pattern
-implicit arguments. To tell |Coq| to infer also reversible-
-pattern implicit argument, use command
-
-.. cmd:: Set Reversible Pattern Implicit.
+.. opt:: Reversible Pattern Implicit
-Conversely, use command ``Unset Reversible Pattern Implicit`` to unset the
-reversible-pattern implicit mode.
+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
+reversible-pattern implicit argument.
.. _controlling-insertion-implicit-args:
Controlling the insertion of implicit arguments not followed by explicit arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Implicit arguments can be declared to be automatically inserted when a
-function is partially applied and the next argument of the function is
-an implicit one. In case the implicit arguments are automatically
-declared (with the command ``Set Implicit Arguments``), the command
-
-.. cmd:: Set Maximal Implicit Insertion.
+.. opt:: Maximal Implicit Insertion
-is used to tell to declare the implicit arguments with a maximal
-insertion status. By default, automatically declared implicit
-arguments are not declared to be insertable maximally. To restore the
-default mode for maximal insertion, use the command
+Assuming the implicit argument mode is on, this option (off by default)
+declares implicit arguments to be automatically inserted when a
+function is partially applied and the next argument of the function is
+an implicit one.
-.. cmd:: Unset Maximal Implicit Insertion.
+.. _explicit-applications:
Explicit applications
~~~~~~~~~~~~~~~~~~~~~
@@ -1904,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
@@ -1930,33 +1869,25 @@ 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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-By default the basic pretty-printing rules hide the inferable implicit
-arguments of an application. To force printing all implicit arguments,
-use command
-
-.. cmd:: Set Printing Implicit.
+.. opt:: Printing Implicit
-Conversely, to restore the hiding of implicit arguments, use command
+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.
-.. cmd:: Unset Printing Implicit.
+.. opt:: Printing Implicit Defensive
-By default the basic pretty-printing rules display the implicit
+By default, the basic pretty-printing rules display the implicit
arguments that are not detected as strict implicit arguments. This
“defensive” mode can quickly make the display cumbersome so this can
-be deactivated by using the command
-
-.. cmd:: Unset Printing Implicit Defensive.
-
-Conversely, to force the display of non strict arguments, use command
+be deactivated by turning this option off.
-.. cmd:: Set Printing Implicit Defensive.
-
-See also: ``Set Printing All`` in :ref:`printing_constructions_full`.
+See also: :opt:`Printing All`.
Interaction with subtyping
~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1981,17 +1912,14 @@ but succeeds in
Deactivation of implicit arguments for parsing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Use of implicit arguments can be deactivated by issuing the command:
+.. opt:: Parsing Explicit
-.. cmd:: Set Parsing Explicit.
+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
-to be given as if none arguments were implicit. By symmetry, this also
-affects printing. To restore parsing and normal printing of implicit
-arguments, use:
-
-.. cmd:: Unset Parsing Explicit.
+to be given as if no arguments were implicit. By symmetry, this also
+affects printing.
Canonical structures
~~~~~~~~~~~~~~~~~~~~
@@ -2006,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.
@@ -2047,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`.
@@ -2079,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
@@ -2101,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.
@@ -2140,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
@@ -2148,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.
@@ -2177,6 +2105,7 @@ implicitly, as maximally-inserted arguments. In these binders, the
binding name for the bound object is optional, whereas the type is
mandatory, dually to regular binders.
+.. _Coercions:
Coercions
---------
@@ -2201,43 +2130,38 @@ to coercions are provided in :ref:`implicitcoercions`.
Printing constructions in full
------------------------------
+.. opt:: Printing All
+
Coercions, implicit arguments, the type of pattern-matching, but also
notations (see :ref:`syntaxextensionsandinterpretationscopes`) can obfuscate the behavior of some
tactics (typically the tactics applying to occurrences of subterms are
-sensitive to the implicit arguments). The command
-
-.. cmd:: Set Printing All.
-
+sensitive to the implicit arguments). Turning this option on
deactivates all high-level printing features such as coercions,
implicit arguments, returned type of pattern-matching, notations and
various syntactic sugar for pattern-matching or record projections.
-Otherwise said, ``Set Printing All`` includes the effects of the commands
-``Set Printing Implicit``, ``Set Printing Coercions``, ``Set Printing Synth``,
-``Unset Printing Projections``, and ``Unset Printing Notations``. To reactivate
-the high-level printing features, use the command
+Otherwise said, :opt:`Printing All` includes the effects of the options
+:opt:`Printing Implicit`, :opt:`Printing Coercions`, :opt:`Printing Synth`,
+:opt:`Printing Projections`, and :opt:`Printing Notations`. To reactivate
+the high-level printing features, use the command ``Unset Printing All``.
-.. cmd:: Unset Printing All.
+.. _printing-universes:
Printing universes
------------------
-The following command:
+.. opt:: Printing Universes
-.. cmd:: Set Printing Universes.
-
-activates the display of the actual level of each occurrence of ``Type``.
-See :ref:`TODO-4.1.1-sorts` for details. This wizard option, in combination
-with ``Set Printing All`` (see :ref:`printing_constructions_full`) can help to diagnose failures
-to unify terms apparently identical but internally different in the
-Calculus of Inductive Constructions. To reactivate the display of the
-actual level of the occurrences of Type, use
-
-.. cmd:: Unset 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
+combination with :opt:`Printing All` can help to diagnose failures to unify
+terms apparently identical but internally different in the Calculus of Inductive
+Constructions.
The constraints on the internal level of the occurrences of Type
-(see :ref:`TODO-4.1.1-sorts`) can be printed using the command
+(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
equivalent to a numbered label reflecting its level (with a linear
@@ -2245,12 +2169,13 @@ ordering) in the universe hierarchy.
This command also accepts an optional output filename:
-.. cmd:: 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
unspecified if `string` doesn’t end in ``.dot`` or ``.gv``.
+.. _existential-variables:
Existential variables
---------------------
@@ -2260,9 +2185,9 @@ subterms to eventually be replaced by actual subterms.
Existential variables are generated in place of unsolvable implicit
arguments or “_” placeholders when using commands such as ``Check`` (see
-Section :ref:`TODO-6.3.1-check`) or when using tactics such as ``refine`` (see Section
-:ref:`TODO-8.2.3-refine`), as well as in place of unsolvable instances when using
-tactics such that ``eapply`` (see Section :ref:`TODO-8.2.4-apply`). An existential
+Section :ref:`requests-to-the-environment`) or when using tactics such as
+:tacn:`refine`, as well as in place of unsolvable instances when using
+tactics such that :tacn:`eapply`. An existential
variable is defined in a context, which is the context of variables of
the placeholder which generated the existential variable, and a type,
which is the expected type of the placeholder.
@@ -2307,25 +2232,19 @@ existential variable used in the same context as its context of definition is wr
Existential variables can be named by the user upon creation using
the syntax ``?``\ `ident`. This is useful when the existential
variable needs to be explicitly handled later in the script (e.g.
-with a named-goal selector, see :ref:`TODO-9.2-goal-selectors`).
+with a named-goal selector, see :ref:`goal-selectors`).
.. _explicit-display-existentials:
Explicit displaying of existential instances for pretty-printing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The command:
-
-.. cmd:: Set Printing Existential Instances.
-
-activates the full display of how the context of an existential
-variable is instantiated at each of the occurrences of the existential
-variable.
+.. opt:: Printing Existential Instances
-To deactivate the full display of the instances of existential
-variables, use
+This option (off by default) activates the full display of how the
+context of an existential variable is instantiated at each of the
+occurrences of the existential variable.
-.. cmd:: Unset Printing Existential Instances.
Solving existential variables using tactics
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2338,7 +2257,7 @@ is not specified and is implementation-dependent. The inner tactic may
use any variable defined in its scope, including repeated alternations
between variables introduced by term binding as well as those
introduced by tactic binding. The expression `tacexpr` can be any tactic
-expression as described in :ref:`thetacticlanguage`.
+expression as described in :ref:`ltac`.
.. coqtop:: all
@@ -2349,5 +2268,5 @@ using highly automated tactics without resorting to writing the proof-term
by means of the interactive proof engine.
This mechanism is comparable to the ``Declare Implicit Tactic`` command
-defined at :ref:`TODO-8.9.7-implicit-automation`, except that the used
+defined at :ref:`tactics-implicit-automation`, except that the used
tactic is local to each hole instead of being declared globally.
diff --git a/doc/sphinx/language/gallina-specification-language.rst b/doc/sphinx/language/gallina-specification-language.rst
new file mode 100644
index 000000000..39735a6ed
--- /dev/null
+++ b/doc/sphinx/language/gallina-specification-language.rst
@@ -0,0 +1,1384 @@
+.. _gallinaspecificationlanguage:
+
+------------------------------------
+ The Gallina specification language
+------------------------------------
+
+This chapter describes Gallina, the specification language of Coq. It allows
+developing mathematical theories and to prove specifications of programs. The
+theories are built from axioms, hypotheses, parameters, lemmas, theorems and
+definitions of constants, functions, predicates and sets. The syntax of logical
+objects involved in theories is described in Section :ref:`term`. The
+language of commands, called *The Vernacular* is described in Section
+:ref:`vernacular`.
+
+In Coq, logical objects are typed to ensure their logical correctness. The
+rules implemented by the typing algorithm are described in Chapter :ref:`calculusofinductiveconstructions`.
+
+
+About the grammars in the manual
+================================
+
+Grammars are presented in Backus-Naur form (BNF). Terminal symbols are
+set in black ``typewriter font``. In addition, there are special notations for
+regular expressions.
+
+An expression enclosed in square brackets ``[…]`` means at most one
+occurrence of this expression (this corresponds to an optional
+component).
+
+The notation “``entry sep … sep entry``” stands for a non empty sequence
+of expressions parsed by entry and separated by the literal “``sep``” [1]_.
+
+Similarly, the notation “``entry … entry``” stands for a non empty
+sequence of expressions parsed by the “``entry``” entry, without any
+separator between.
+
+At the end, the notation “``[entry sep … sep entry]``” stands for a
+possibly empty sequence of expressions parsed by the “``entry``” entry,
+separated by the literal “``sep``”.
+
+
+Lexical conventions
+===================
+
+Blanks
+ Space, newline and horizontal tabulation are considered as blanks.
+ Blanks are ignored but they separate tokens.
+
+Comments
+ Comments in Coq are enclosed between ``(*`` and ``*)``, and can be nested.
+ They can contain any character. However, string literals must be
+ correctly closed. Comments are treated as blanks.
+
+Identifiers and access identifiers
+ Identifiers, written ident, are sequences of letters, digits, ``_`` and
+ ``'``, that do not start with a digit or ``'``. That is, they are
+ recognized by the following lexical class:
+
+ .. productionlist:: coq
+ first_letter : a..z ∣ A..Z ∣ _ ∣ unicode-letter
+ subsequent_letter : a..z ∣ A..Z ∣ 0..9 ∣ _ ∣ ' ∣ unicode-letter ∣ unicode-id-part
+ ident : `first_letter` [`subsequent_letter` … `subsequent_letter`]
+ access_ident : . `ident`
+
+ All characters are meaningful. In particular, identifiers are case-
+ sensitive. The entry ``unicode-letter`` non-exhaustively includes Latin,
+ Greek, Gothic, Cyrillic, Arabic, Hebrew, Georgian, Hangul, Hiragana
+ and Katakana characters, CJK ideographs, mathematical letter-like
+ symbols, hyphens, non-breaking space, … The entry ``unicode-id-part`` non-
+ exhaustively includes symbols for prime letters and subscripts.
+
+ Access identifiers, written :token:`access_ident`, are identifiers prefixed by
+ `.` (dot) without blank. They are used in the syntax of qualified
+ identifiers.
+
+Natural numbers and integers
+ Numerals are sequences of digits. Integers are numerals optionally
+ preceded by a minus sign.
+
+ .. productionlist:: coq
+ digit : 0..9
+ num : `digit` … `digit`
+ integer : [-] `num`
+
+Strings
+ Strings are delimited by ``"`` (double quote), and enclose a sequence of
+ any characters different from ``"`` or the sequence ``""`` to denote the
+ double quote character. In grammars, the entry for quoted strings is
+ :production:`string`.
+
+Keywords
+ The following identifiers are reserved keywords, and cannot be
+ employed otherwise::
+
+ _ as at cofix else end exists exists2 fix for
+ forall fun if IF in let match mod Prop return
+ Set then Type using where with
+
+Special tokens
+ The following sequences of characters are special tokens::
+
+ ! % & && ( () ) * + ++ , - -> . .( ..
+ / /\ : :: :< := :> ; < <- <-> <: <= <> =
+ => =_D > >-> >= ? ?= @ [ \/ ] ^ { | |-
+ || } ~
+
+ Lexical ambiguities are resolved according to the “longest match”
+ rule: when a sequence of non alphanumerical characters can be
+ decomposed into several different ways, then the first token is the
+ longest possible one (among all tokens defined at this moment), and so
+ on.
+
+.. _term:
+
+Terms
+=====
+
+Syntax of terms
+---------------
+
+The following grammars describe the basic syntax of the terms of the
+*Calculus of Inductive Constructions* (also called Cic). The formal
+presentation of Cic is given in Chapter :ref:`calculusofinductiveconstructions`. Extensions of this syntax
+are given in Chapter :ref:`extensionsofgallina`. How to customize the syntax
+is described in Chapter :ref:`syntaxextensionsandinterpretationscopes`.
+
+.. productionlist:: coq
+ term : forall `binders` , `term`
+ : | fun `binders` => `term`
+ : | fix `fix_bodies`
+ : | cofix `cofix_bodies`
+ : | let `ident` [`binders`] [: `term`] := `term` in `term`
+ : | let fix `fix_body` in `term`
+ : | let cofix `cofix_body` in `term`
+ : | let ( [`name` , … , `name`] ) [`dep_ret_type`] := `term` in `term`
+ : | let ' `pattern` [in `term`] := `term` [`return_type`] in `term`
+ : | if `term` [`dep_ret_type`] then `term` else `term`
+ : | `term` : `term`
+ : | `term` <: `term`
+ : | `term` :>
+ : | `term` -> `term`
+ : | `term` arg … arg
+ : | @ `qualid` [`term` … `term`]
+ : | `term` % `ident`
+ : | match `match_item` , … , `match_item` [`return_type`] with
+ : [[|] `equation` | … | `equation`] end
+ : | `qualid`
+ : | `sort`
+ : | num
+ : | _
+ : | ( `term` )
+ arg : `term`
+ : | ( `ident` := `term` )
+ binders : `binder` … `binder`
+ binder : `name`
+ : | ( `name` … `name` : `term` )
+ : | ( `name` [: `term`] := `term` )
+ name : `ident` | _
+ qualid : `ident` | `qualid` `access_ident`
+ sort : Prop | Set | Type
+ fix_bodies : `fix_body`
+ : | `fix_body` with `fix_body` with … with `fix_body` for `ident`
+ cofix_bodies : `cofix_body`
+ : | `cofix_body` with `cofix_body` with … with `cofix_body` for `ident`
+ fix_body : `ident` `binders` [annotation] [: `term`] := `term`
+ cofix_body : `ident` [`binders`] [: `term`] := `term`
+ annotation : { struct `ident` }
+ match_item : `term` [as `name`] [in `qualid` [`pattern` … `pattern`]]
+ dep_ret_type : [as `name`] `return_type`
+ return_type : return `term`
+ equation : `mult_pattern` | … | `mult_pattern` => `term`
+ mult_pattern : `pattern` , … , `pattern`
+ pattern : `qualid` `pattern` … `pattern`
+ : | @ `qualid` `pattern` … `pattern`
+ : | `pattern` as `ident`
+ : | `pattern` % `ident`
+ : | `qualid`
+ : | _
+ : | num
+ : | ( `or_pattern` , … , `or_pattern` )
+ or_pattern : `pattern` | … | `pattern`
+
+
+Types
+-----
+
+Coq terms are typed. Coq types are recognized by the same syntactic
+class as :token`term`. We denote by :token:`type` the semantic subclass
+of types inside the syntactic class :token:`term`.
+
+.. _gallina-identifiers:
+
+Qualified identifiers and simple identifiers
+--------------------------------------------
+
+*Qualified identifiers* (:token:`qualid`) denote *global constants*
+(definitions, lemmas, theorems, remarks or facts), *global variables*
+(parameters or axioms), *inductive types* or *constructors of inductive
+types*. *Simple identifiers* (or shortly :token:`ident`) are a syntactic subset
+of qualified identifiers. Identifiers may also denote local *variables*,
+what qualified identifiers do not.
+
+Numerals
+--------
+
+Numerals have no definite semantics in the calculus. They are mere
+notations that can be bound to objects through the notation mechanism
+(see Chapter :ref:`syntaxextensionsandinterpretationscopes` for details).
+Initially, numerals are bound to Peano’s representation of natural
+numbers (see :ref:`datatypes`).
+
+.. note::
+
+ negative integers are not at the same level as :token:`num`, for this
+ would make precedence unnatural.
+
+Sorts
+-----
+
+There are three sorts :g:`Set`, :g:`Prop` and :g:`Type`.
+
+- :g:`Prop` is the universe of *logical propositions*. The logical propositions
+ themselves are typing the proofs. We denote propositions by *form*.
+ This constitutes a semantic subclass of the syntactic class :token:`term`.
+
+- :g:`Set` is is the universe of *program types* or *specifications*. The
+ specifications themselves are typing the programs. We denote
+ specifications by *specif*. This constitutes a semantic subclass of
+ the syntactic class :token:`term`.
+
+- :g:`Type` is the type of :g:`Prop` and :g:`Set`
+
+More on sorts can be found in Section :ref:`sorts`.
+
+.. _binders:
+
+Binders
+-------
+
+Various constructions such as :g:`fun`, :g:`forall`, :g:`fix` and :g:`cofix`
+*bind* variables. A binding is represented by an identifier. If the binding
+variable is not used in the expression, the identifier can be replaced by the
+symbol :g:`_`. When the type of a bound variable cannot be synthesized by the
+system, it can be specified with the notation ``(ident : type)``. There is also
+a notation for a sequence of binding variables sharing the same type:
+``(``:token:`ident`:math:`_1`…:token:`ident`:math:`_n` : :token:`type```)``. A
+binder can also be any pattern prefixed by a quote, e.g. :g:`'(x,y)`.
+
+Some constructions allow the binding of a variable to value. This is
+called a “let-binder”. The entry :token:`binder` of the grammar accepts
+either an assumption binder as defined above or a let-binder. The notation in
+the latter case is ``(ident := term)``. In a let-binder, only one
+variable can be introduced at the same time. It is also possible to give
+the type of the variable as follows:
+``(ident : term := term)``.
+
+Lists of :token:`binder` are allowed. In the case of :g:`fun` and :g:`forall`,
+it is intended that at least one binder of the list is an assumption otherwise
+fun and forall gets identical. Moreover, parentheses can be omitted in
+the case of a single sequence of bindings sharing the same type (e.g.:
+:g:`fun (x y z : A) => t` can be shortened in :g:`fun x y z : A => t`).
+
+Abstractions
+------------
+
+The expression ``fun ident : type => term`` defines the
+*abstraction* of the variable :token:`ident`, of type :token:`type`, over the term
+:token:`term`. It denotes a function of the variable :token:`ident` that evaluates to
+the expression :token:`term` (e.g. :g:`fun x : A => x` denotes the identity
+function on type :g:`A`). The keyword :g:`fun` can be followed by several
+binders as given in Section :ref:`binders`. Functions over
+several variables are equivalent to an iteration of one-variable
+functions. For instance the expression
+“fun :token:`ident`\ :math:`_{1}` … :token:`ident`\ :math:`_{n}` 
+: :token:`type` => :token:`term`”
+denotes the same function as “ fun :token:`ident`\
+:math:`_{1}` : :token:`type` => … 
+fun :token:`ident`\ :math:`_{n}` : :token:`type` => :token:`term`”. If
+a let-binder occurs in
+the list of binders, it is expanded to a let-in definition (see
+Section :ref:`let-in`).
+
+Products
+--------
+
+The expression :g:`forall ident : type, term` denotes the
+*product* of the variable :token:`ident` of type :token:`type`, over the term :token:`term`.
+As for abstractions, :g:`forall` is followed by a binder list, and products
+over several variables are equivalent to an iteration of one-variable
+products. Note that :token:`term` is intended to be a type.
+
+If the variable :token:`ident` occurs in :token:`term`, the product is called
+*dependent product*. The intention behind a dependent product
+:g:`forall x : A, B` is twofold. It denotes either
+the universal quantification of the variable :g:`x` of type :g:`A`
+in the proposition :g:`B` or the functional dependent product from
+:g:`A` to :g:`B` (a construction usually written
+:math:`\Pi_{x:A}.B` in set theory).
+
+Non dependent product types have a special notation: :g:`A -> B` stands for
+:g:`forall _ : A, B`. The *non dependent product* is used both to denote
+the propositional implication and function types.
+
+Applications
+------------
+
+The expression :token:`term`\ :math:`_0` :token:`term`\ :math:`_1` denotes the
+application of :token:`term`\ :math:`_0` to :token:`term`\ :math:`_1`.
+
+The expression :token:`term`\ :math:`_0` :token:`term`\ :math:`_1` ...
+:token:`term`\ :math:`_n` denotes the application of the term
+:token:`term`\ :math:`_0` to the arguments :token:`term`\ :math:`_1` ... then
+:token:`term`\ :math:`_n`. It is equivalent to ( … ( :token:`term`\ :math:`_0`
+:token:`term`\ :math:`_1` ) … ) :token:`term`\ :math:`_n` : associativity is to the
+left.
+
+The notation ``(ident := term)`` for arguments is used for making
+explicit the value of implicit arguments (see
+Section :ref:`explicit-applications`).
+
+Type cast
+---------
+
+The expression ``term : type`` is a type cast expression. It enforces
+the type of :token:`term` to be :token:`type`.
+
+``term <: type`` locally sets up the virtual machine for checking that
+:token:`term` has type :token:`type`.
+
+Inferable subterms
+------------------
+
+Expressions often contain redundant pieces of information. Subterms that can be
+automatically inferred by Coq can be replaced by the symbol ``_`` and Coq will
+guess the missing piece of information.
+
+.. _let-in:
+
+Let-in definitions
+------------------
+
+``let`` :token:`ident` := :token:`term`:math:`_1` in :token:`term`:math:`_2`
+denotes the local binding of :token:`term`:math:`_1` to the variable
+:token:`ident` in :token:`term`:math:`_2`. There is a syntactic sugar for let-in
+definition of functions: ``let`` :token:`ident` :token:`binder`:math:`_1` …
+:token:`binder`:math:`_n` := :token:`term`:math:`_1` in :token:`term`:math:`_2`
+stands for ``let`` :token:`ident` := ``fun`` :token:`binder`:math:`_1` …
+:token:`binder`:math:`_n` => :token:`term`:math:`_1` in :token:`term`:math:`_2`.
+
+Definition by case analysis
+---------------------------
+
+Objects of inductive types can be destructurated by a case-analysis
+construction called *pattern-matching* expression. A pattern-matching
+expression is used to analyze the structure of an inductive objects and
+to apply specific treatments accordingly.
+
+This paragraph describes the basic form of pattern-matching. See
+Section :ref:`Mult-match` and Chapter :ref:`extendedpatternmatching` for the description
+of the general form. The basic form of pattern-matching is characterized
+by a single :token:`match_item` expression, a :token:`mult_pattern` restricted to a
+single :token:`pattern` and :token:`pattern` restricted to the form
+:token:`qualid` :token:`ident`.
+
+The expression match :token:`term`:math:`_0` :token:`return_type` with
+:token:`pattern`:math:`_1` => :token:`term`:math:`_1` :math:`|` … :math:`|`
+:token:`pattern`:math:`_n` => :token:`term`:math:`_n` end, denotes a
+:token:`pattern-matching` over the term :token:`term`:math:`_0` (expected to be
+of an inductive type :math:`I`). The terms :token:`term`:math:`_1`\ …\
+:token:`term`:math:`_n` are the :token:`branches` of the pattern-matching
+expression. Each of :token:`pattern`:math:`_i` has a form :token:`qualid`
+:token:`ident` where :token:`qualid` must denote a constructor. There should be
+exactly one branch for every constructor of :math:`I`.
+
+The :token:`return_type` expresses the type returned by the whole match
+expression. There are several cases. In the *non dependent* case, all
+branches have the same type, and the :token:`return_type` is the common type of
+branches. In this case, :token:`return_type` can usually be omitted as it can be
+inferred from the type of the branches [2]_.
+
+In the *dependent* case, there are three subcases. In the first subcase,
+the type in each branch may depend on the exact value being matched in
+the branch. In this case, the whole pattern-matching itself depends on
+the term being matched. This dependency of the term being matched in the
+return type is expressed with an “as :token:`ident`” clause where :token:`ident`
+is dependent in the return type. For instance, in the following example:
+
+.. coqtop:: in
+
+ Inductive bool : Type := true : bool | false : bool.
+ Inductive eq (A:Type) (x:A) : A -> Prop := eq_refl : eq A x x.
+ Inductive or (A:Prop) (B:Prop) : Prop :=
+ | or_introl : A -> or A B
+ | or_intror : B -> or A B.
+
+ Definition bool_case (b:bool) : or (eq bool b true) (eq bool b false) :=
+ match b as x return or (eq bool x true) (eq bool x false) with
+ | true => or_introl (eq bool true true) (eq bool true false)
+ (eq_refl bool true)
+ | false => or_intror (eq bool false true) (eq bool false false)
+ (eq_refl bool false)
+ end.
+
+the branches have respective types or :g:`eq bool true true :g:`eq bool true
+false` and or :g:`eq bool false true` :g:`eq bool false false` while the whole
+pattern-matching expression has type or :g:`eq bool b true` :g:`eq bool b
+false`, the identifier :g:`x` being used to represent the dependency. Remark
+that when the term being matched is a variable, the as clause can be
+omitted and the term being matched can serve itself as binding name in
+the return type. For instance, the following alternative definition is
+accepted and has the same meaning as the previous one.
+
+.. coqtop:: in
+
+ Definition bool_case (b:bool) : or (eq bool b true) (eq bool b false) :=
+ match b return or (eq bool b true) (eq bool b false) with
+ | true => or_introl (eq bool true true) (eq bool true false)
+ (eq_refl bool true)
+ | false => or_intror (eq bool false true) (eq bool false false)
+ (eq_refl bool false)
+ end.
+
+The second subcase is only relevant for annotated inductive types such
+as the equality predicate (see Section :ref:`Equality`),
+the order predicate on natural numbers or the type of lists of a given
+length (see Section :ref:`matching-dependent`). In this configuration, the
+type of each branch can depend on the type dependencies specific to the
+branch and the whole pattern-matching expression has a type determined
+by the specific dependencies in the type of the term being matched. This
+dependency of the return type in the annotations of the inductive type
+is expressed using a “in I _ ... _ :token:`pattern`:math:`_1` ...
+:token:`pattern`:math:`_n`” clause, where
+
+- :math:`I` is the inductive type of the term being matched;
+
+- the :g:`_` are matching the parameters of the inductive type: the
+ return type is not dependent on them.
+
+- the :token:`pattern`:math:`_i` are matching the annotations of the
+ inductive type: the return type is dependent on them
+
+- in the basic case which we describe below, each :token:`pattern`:math:`_i`
+ is a name :token:`ident`:math:`_i`; see :ref:`match-in-patterns` for the
+ general case
+
+For instance, in the following example:
+
+.. coqtop:: in
+
+ Definition eq_sym (A:Type) (x y:A) (H:eq A x y) : eq A y x :=
+ match H in eq _ _ z return eq A z x with
+ | eq_refl _ => eq_refl A x
+ end.
+
+the type of the branch has type :g:`eq A x x` because the third argument of
+g:`eq` is g:`x` in the type of the pattern :g:`refl_equal`. On the contrary, the
+type of the whole pattern-matching expression has type :g:`eq A y x` because the
+third argument of eq is y in the type of H. This dependency of the case analysis
+in the third argument of :g:`eq` is expressed by the identifier g:`z` in the
+return type.
+
+Finally, the third subcase is a combination of the first and second
+subcase. In particular, it only applies to pattern-matching on terms in
+a type with annotations. For this third subcase, both the clauses as and
+in are available.
+
+There are specific notations for case analysis on types with one or two
+constructors: “if … then … else …” and “let (…, ” (see
+Sections :ref:`if-then-else` and :ref:`let-in`).
+
+Recursive functions
+-------------------
+
+The expression “fix :token:`ident`:math:`_1` :token:`binder`:math:`_1` :
+:token:`type`:math:`_1` ``:=`` :token:`term`:math:`_1` with … with
+:token:`ident`:math:`_n` :token:`binder`:math:`_n` : :token:`type`:math:`_n`
+``:=`` :token:`term`:math:`_n` for :token:`ident`:math:`_i`” denotes the
+:math:`i`\ component of a block of functions defined by mutual well-founded
+recursion. It is the local counterpart of the :cmd:`Fixpoint` command. When
+:math:`n=1`, the “for :token:`ident`:math:`_i`” clause is omitted.
+
+The expression “cofix :token:`ident`:math:`_1` :token:`binder`:math:`_1` :
+:token:`type`:math:`_1` with … with :token:`ident`:math:`_n` :token:`binder`:math:`_n`
+: :token:`type`:math:`_n` for :token:`ident`:math:`_i`” denotes the
+:math:`i`\ component of a block of terms defined by a mutual guarded
+co-recursion. It is the local counterpart of the ``CoFixpoint`` command. See
+Section :ref:`CoFixpoint` for more details. When
+:math:`n=1`, the “ for :token:`ident`:math:`_i`” clause is omitted.
+
+The association of a single fixpoint and a local definition have a special
+syntax: “let fix f … := … in …” stands for “let f := fix f … := … in …”. The
+same applies for co-fixpoints.
+
+.. _vernacular:
+
+The Vernacular
+==============
+
+.. productionlist:: coq
+ sentence : `assumption`
+ : | `definition`
+ : | `inductive`
+ : | `fixpoint`
+ : | `assertion` `proof`
+ assumption : `assumption_keyword` `assums`.
+ assumption_keyword : Axiom | Conjecture
+ : | Parameter | Parameters
+ : | Variable | Variables
+ : | Hypothesis | Hypotheses
+ assums : `ident` … `ident` : `term`
+ : | ( `ident` … `ident` : `term` ) … ( `ident` … `ident` : `term` )
+ definition : [Local] Definition `ident` [`binders`] [: `term`] := `term` .
+ : | Let `ident` [`binders`] [: `term`] := `term` .
+ inductive : Inductive `ind_body` with … with `ind_body` .
+ : | CoInductive `ind_body` with … with `ind_body` .
+ ind_body : `ident` [`binders`] : `term` :=
+ : [[|] `ident` [`binders`] [:`term`] | … | `ident` [`binders`] [:`term`]]
+ fixpoint : Fixpoint `fix_body` with … with `fix_body` .
+ : | CoFixpoint `cofix_body` with … with `cofix_body` .
+ assertion : `assertion_keyword` `ident` [`binders`] : `term` .
+ assertion_keyword : Theorem | Lemma
+ : | Remark | Fact
+ : | Corollary | Proposition
+ : | Definition | Example
+ proof : Proof . … Qed .
+ : | Proof . … Defined .
+ : | Proof . … Admitted .
+
+.. todo:: This use of … in this grammar is inconsistent
+
+This grammar describes *The Vernacular* which is the language of
+commands of Gallina. A sentence of the vernacular language, like in
+many natural languages, begins with a capital letter and ends with a
+dot.
+
+The different kinds of command are described hereafter. They all suppose
+that the terms occurring in the sentences are well-typed.
+
+.. _gallina-assumptions:
+
+Assumptions
+-----------
+
+Assumptions extend the environment with axioms, parameters, hypotheses
+or variables. An assumption binds an :token:`ident` to a :token:`type`. It is accepted
+by Coq if and only if this :token:`type` is a correct type in the environment
+preexisting the declaration and if :token:`ident` was not previously defined in
+the same module. This :token:`type` is considered to be the type (or
+specification, or statement) assumed by :token:`ident` and we say that :token:`ident`
+has type :token:`type`.
+
+.. _Axiom:
+
+.. 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
+ postulate.
+
+.. exn:: @ident already exists.
+ :name: @ident already exists. (Axiom)
+
+.. cmdv:: Parameter @ident : @term
+ :name: Parameter
+
+ Is equivalent to ``Axiom`` :token:`ident` : :token:`term`
+
+.. cmdv:: Parameter {+ @ident } : @term
+
+ Adds parameters with specification :token:`term`
+
+.. cmdv:: Parameter {+ ( {+ @ident } : @term ) }
+
+ Adds blocks of parameters with different specifications.
+
+.. cmdv:: Parameters {+ ( {+ @ident } : @term ) }
+
+ Synonym of ``Parameter``.
+
+.. 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
+ qualified name to refer to them.
+
+.. cmdv:: Conjecture @ident : @term
+ :name: Conjecture
+
+ Is equivalent to ``Axiom`` :token:`ident` : :token:`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
+the section mechanism). When the current section is closed, name :token:`ident`
+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.
+ :name: @ident already exists. (Variable)
+
+.. cmdv:: Variable {+ @ident } : @term
+
+ Links :token:`term` to each :token:`ident`.
+
+.. cmdv:: Variable {+ ( {+ @ident } : @term) }
+
+ Adds blocks of variables with different specifications.
+
+.. cmdv:: Variables {+ ( {+ @ident } : @term) }
+ :name: Variables
+
+.. cmdv:: Hypothesis {+ ( {+ @ident } : @term) }
+ :name: Hypothesis
+
+.. cmdv:: Hypotheses {+ ( {+ @ident } : @term) }
+
+Synonyms of ``Variable``.
+
+It is advised to use the keywords ``Axiom`` and ``Hypothesis`` for
+logical postulates (i.e. when the assertion *term* is of sort ``Prop``),
+and to use the keywords ``Parameter`` and ``Variable`` in other cases
+(corresponding to the declaration of an abstract mathematical entity).
+
+.. _gallina-definitions:
+
+Definitions
+-----------
+
+Definitions extend the environment with associations of names to terms.
+A definition can be seen as a way to give a meaning to a name or as a
+way to abbreviate a term. In any case, the name can later be replaced at
+any time by its definition.
+
+The operation of unfolding a name into its definition is called
+:math:`\delta`-conversion (see Section :ref:`delta-reduction`). A
+definition is accepted by the system if and only if the defined term is
+well-typed in the current context of the definition and if the name is
+not already used. The name defined by the definition is called a
+*constant* and the term it refers to is its *body*. A definition has a
+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
+
+ This command binds :token:`term` to the name :token:`ident` in the environment,
+ provided that :token:`term` is well-typed.
+
+.. exn:: @ident already exists.
+ :name: @ident already exists. (Definition)
+
+.. 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
+
+ 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
+
+ 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
+ :name: Example
+
+.. cmdv:: Example @ident : @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.
+
+See also :cmd:`Opaque`, :cmd:`Transparent`, :tacn:`unfold`.
+
+.. 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
+current section is eventually closed, and, all persistent objects (such
+as theorems) defined within the section and depending on :token:`ident` are
+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.
+ :name: @ident already exists. (Let)
+
+.. cmdv:: Let @ident : @term := @term
+
+.. cmdv:: Let Fixpoint @ident @fix_body {* with @fix_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`.
+
+.. _gallina-inductive-definitions:
+
+Inductive definitions
+---------------------
+
+We gradually explain simple inductive types, simple annotated inductive
+types, simple parametric inductive types, mutually inductive types. We
+explain also co-inductive types.
+
+Simple inductive types
+~~~~~~~~~~~~~~~~~~~~~~
+
+The definition of a simple inductive type has the following form:
+
+.. cmd:: Inductive @ident : @sort := {? | } @ident : @type {* | @ident : @type }
+
+The name :token:`ident` is the name of the inductively defined type and
+:token:`sort` is the universes where it lives. The :token:`ident` are the names
+of its constructors and :token:`type` their respective types. The types of the
+constructors have to satisfy a *positivity condition* (see Section
+:ref:`positivity`) for :token:`ident`. This condition ensures the soundness of
+the inductive definition. If this is the case, the :token:`ident` are added to
+the environment with their respective types. Accordingly to the universe where
+the inductive type lives (e.g. its type :token:`sort`), Coq provides a number of
+destructors for :token:`ident`. Destructors are named ``ident_ind``,
+``ident_rec`` or ``ident_rect`` which respectively correspond to
+elimination principles on :g:`Prop`, :g:`Set` and :g:`Type`. The type of the
+destructors expresses structural induction/recursion principles over objects of
+:token:`ident`. We give below two examples of the use of the Inductive
+definitions.
+
+The set of natural numbers is defined as:
+
+.. coqtop:: all
+
+ Inductive nat : Set :=
+ | O : nat
+ | S : nat -> nat.
+
+The type nat is defined as the least :g:`Set` containing :g:`O` and closed by
+the :g:`S` constructor. The names :g:`nat`, :g:`O` and :g:`S` are added to the
+environment.
+
+Now let us have a look at the elimination principles. They are three of them:
+:g:`nat_ind`, :g:`nat_rec` and :g:`nat_rect`. The type of :g:`nat_ind` is:
+
+.. coqtop:: all
+
+ Check nat_ind.
+
+This is the well known structural induction principle over natural
+numbers, i.e. the second-order form of Peano’s induction principle. It
+allows proving some universal property of natural numbers (:g:`forall
+n:nat, P n`) by induction on :g:`n`.
+
+The types of :g:`nat_rec` and :g:`nat_rect` are similar, except that they pertain
+to :g:`(P:nat->Set)` and :g:`(P:nat->Type)` respectively. They correspond to
+primitive induction principles (allowing dependent types) respectively
+over sorts ``Set`` and ``Type``. The constant ``ident_ind`` is always
+provided, whereas ``ident_rec`` and ``ident_rect`` can be impossible
+to derive (for example, when :token:`ident` is a proposition).
+
+.. coqtop:: in
+
+ Inductive nat : Set := O | S (_:nat).
+
+In the case where inductive types have no annotations (next section
+gives an example of such annotations), a constructor can be defined
+by only giving the type of its arguments.
+
+Simple annotated inductive types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In an annotated inductive types, the universe where the inductive type
+is defined is no longer a simple sort, but what is called an arity,
+which is a type whose conclusion is a sort.
+
+As an example of annotated inductive types, let us define the
+:g:`even` predicate:
+
+.. coqtop:: all
+
+ Inductive even : nat -> Prop :=
+ | even_0 : even O
+ | even_SS : forall n:nat, even n -> even (S (S n)).
+
+The type :g:`nat->Prop` means that even is a unary predicate (inductively
+defined) over natural numbers. The type of its two constructors are the
+defining clauses of the predicate even. The type of :g:`even_ind` is:
+
+.. coqtop:: all
+
+ Check even_ind.
+
+From a mathematical point of view it asserts that the natural numbers satisfying
+the predicate even are exactly in the smallest set of naturals satisfying the
+clauses :g:`even_0` or :g:`even_SS`. This is why, when we want to prove any
+predicate :g:`P` over elements of :g:`even`, it is enough to prove it for :g:`O`
+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:: The conclusion of @type is not valid; it must be built from @ident.
+
+Parametrized inductive types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the previous example, each constructor introduces a different
+instance of the predicate even. In some cases, all the constructors
+introduces the same generic instance of the inductive definition, in
+which case, instead of an annotation, we use a context of parameters
+which are binders shared by all the constructors of the definition.
+
+The general scheme is:
+
+.. cmdv:: Inductive @ident {+ @binder} : @term := {? | } @ident : @type {* | @ident : @type}
+
+Parameters differ from inductive type annotations in the fact that the
+conclusion of each type of constructor :g:`term` invoke the inductive type with
+the same values of parameters as its specification.
+
+A typical example is the definition of polymorphic lists:
+
+.. coqtop:: in
+
+ Inductive list (A:Set) : Set :=
+ | nil : list A
+ | cons : A -> list A -> list A.
+
+.. note::
+
+ In the type of :g:`nil` and :g:`cons`, we write :g:`(list A)` and not
+ just :g:`list`. The constructors :g:`nil` and :g:`cons` will have respectively
+ types:
+
+ .. coqtop:: all
+
+ Check nil.
+ Check cons.
+
+ Types of destructors are also quantified with :g:`(A:Set)`.
+
+Variants
+++++++++
+
+.. coqtop:: in
+
+ Inductive list (A:Set) : Set := nil | cons (_:A) (_:list A).
+
+This is an alternative definition of lists where we specify the
+arguments of the constructors rather than their full type.
+
+.. coqtop:: in
+
+ Variant sum (A B:Set) : Set := left : A -> sum A B | right : B -> sum A B.
+
+The ``Variant`` keyword is identical to the ``Inductive`` keyword, except
+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.
+
+New from Coq V8.1
++++++++++++++++++
+
+The condition on parameters for inductive definitions has been relaxed
+since Coq V8.1. It is now possible in the type of a constructor, to
+invoke recursively the inductive definition on an argument which is not
+the parameter itself.
+
+One can define :
+
+.. coqtop:: all
+
+ Inductive list2 (A:Set) : Set :=
+ | nil2 : list2 A
+ | cons2 : A -> list2 (A*A) -> list2 A.
+
+that can also be written by specifying only the type of the arguments:
+
+.. coqtop:: all reset
+
+ Inductive list2 (A:Set) : Set := nil2 | cons2 (_:A) (_:list2 (A*A)).
+
+But the following definition will give an error:
+
+.. coqtop:: all
+
+ Fail Inductive listw (A:Set) : Set :=
+ | nilw : listw (A*A)
+ | consw : A -> listw (A*A) -> listw (A*A).
+
+Because the conclusion of the type of constructors should be :g:`listw A` in
+both cases.
+
+A parametrized inductive definition can be defined using annotations
+instead of parameters but it will sometimes give a different (bigger)
+sort for the inductive definition and will produce a less convenient
+rule for case elimination.
+
+See also Section :ref:`inductive-definitions` and the :tacn:`induction`
+tactic.
+
+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 }}
+
+It has the same semantics as the above ``Inductive`` definition for each
+:token:`ident` All :token:`ident` are simultaneously added to the environment.
+Then well-typing of constructors can be checked. Each one of the :token:`ident`
+can be used on its own.
+
+It is also possible to parametrize these inductive definitions. However,
+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 }}
+
+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
+be declared the following way.
+
+.. coqtop:: in
+
+ Variables A B : Set.
+
+ Inductive tree : Set :=
+ node : A -> forest -> tree
+
+ with forest : Set :=
+ | leaf : B -> forest
+ | cons : tree -> forest -> forest.
+
+This declaration generates automatically six induction principles. They are
+respectively called :g:`tree_rec`, :g:`tree_ind`, :g:`tree_rect`,
+:g:`forest_rec`, :g:`forest_ind`, :g:`forest_rect`. These ones are not the most
+general ones but are just the induction principles corresponding to each
+inductive part seen as a single inductive definition.
+
+To illustrate this point on our example, we give the types of :g:`tree_rec`
+and :g:`forest_rec`.
+
+.. coqtop:: all
+
+ Check tree_rec.
+
+ Check forest_rec.
+
+Assume we want to parametrize our mutual inductive definitions with the
+two type variables :g:`A` and :g:`B`, the declaration should be
+done the following way:
+
+.. coqtop:: in
+
+ Inductive tree (A B:Set) : Set :=
+ node : A -> forest A B -> tree A B
+
+ with forest (A B:Set) : Set :=
+ | leaf : B -> forest A B
+ | cons : tree A B -> forest A B -> forest A B.
+
+Assume we define an inductive definition inside a section. When the
+section is closed, the variables declared in the section and occurring
+free in the declaration are added as parameters to the inductive
+definition.
+
+See also Section :ref:`section-mechanism`.
+
+.. _coinductive-types:
+
+Co-inductive types
+~~~~~~~~~~~~~~~~~~
+
+The objects of an inductive type are well-founded with respect to the
+constructors of the type. In other words, such objects contain only a
+*finite* number of constructors. Co-inductive types arise from relaxing
+this condition, and admitting types whose objects contain an infinity of
+constructors. Infinite objects are introduced by a non-ending (but
+effective) process of construction, defined in terms of the constructors
+of the type.
+
+An example of a co-inductive type is the type of infinite sequences of
+natural numbers, usually called streams. It can be introduced in
+Coq using the ``CoInductive`` command:
+
+.. coqtop:: all
+
+ CoInductive Stream : Set :=
+ Seq : nat -> Stream -> Stream.
+
+The syntax of this command is the same as the command :cmd:`Inductive`. Notice
+that no principle of induction is derived from the definition of a co-inductive
+type, since such principles only make sense for inductive ones. For co-inductive
+ones, the only elimination principle is case analysis. For example, the usual
+destructors on streams :g:`hd:Stream->nat` and :g:`tl:Str->Str` can be defined
+as follows:
+
+.. coqtop:: all
+
+ Definition hd (x:Stream) := let (a,s) := x in a.
+ Definition tl (x:Stream) := let (a,s) := x in s.
+
+Definition of co-inductive predicates and blocks of mutually
+co-inductive definitions are also allowed. An example of a co-inductive
+predicate is the extensional equality on streams:
+
+.. coqtop:: all
+
+ CoInductive EqSt : Stream -> Stream -> Prop :=
+ eqst : forall s1 s2:Stream,
+ hd s1 = hd s2 -> EqSt (tl s1) (tl s2) -> EqSt s1 s2.
+
+In order to prove the extensionally equality of two streams :g:`s1` and :g:`s2`
+we have to construct an infinite proof of equality, that is, an infinite object
+of type :g:`(EqSt s1 s2)`. We will see how to introduce infinite objects in
+Section :ref:`cofixpoint`.
+
+Definition of recursive functions
+---------------------------------
+
+Definition of functions by recursion over inductive objects
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This section describes the primitive form of definition by recursion over
+inductive objects. See the :cmd:`Function` command for more advanced
+constructions.
+
+.. _Fixpoint:
+
+.. 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
+define :token:`ident` a recursive function with arguments specified by the
+binders in :token:`params` such that :token:`ident` applied to arguments corresponding
+to these binders has type :token:`type`:math:`_0`, and is equivalent to the
+expression :token:`term`:math:`_0`. The type of the :token:`ident` is consequently
+:g:`forall` :token:`params`, :token:`type`:math:`_0` and the value is equivalent to
+:g:`fun` :token:`params` :g:`=>` :token:`term`:math:`_0`.
+
+To be accepted, a ``Fixpoint`` definition has to satisfy some syntactical
+constraints on a special argument called the decreasing argument. They
+are needed to ensure that the Fixpoint definition always terminates. The
+point of the {struct :token:`ident`} annotation is to let the user tell the
+system which argument decreases along the recursive calls. For instance,
+one can define the addition function as :
+
+.. coqtop:: all
+
+ Fixpoint add (n m:nat) {struct n} : nat :=
+ match n with
+ | O => m
+ | S p => S (add p m)
+ end.
+
+The ``{struct`` :token:`ident```}`` annotation may be left implicit, in this case the
+system try successively arguments from left to right until it finds one that
+satisfies the decreasing condition.
+
+.. note::
+
+ Some fixpoints may have several arguments that fit as decreasing
+ arguments, and this choice influences the reduction of the fixpoint. Hence an
+ explicit annotation must be used if the leftmost decreasing argument is not the
+ desired one. Writing explicit annotations can also speed up type-checking of
+ large mutual fixpoints.
+
+The match operator matches a value (here :g:`n`) with the various
+constructors of its (inductive) type. The remaining arguments give the
+respective values to be returned, as functions of the parameters of the
+corresponding constructor. Thus here when :g:`n` equals :g:`O` we return
+:g:`m`, and when :g:`n` equals :g:`(S p)` we return :g:`(S (add p m))`.
+
+The match operator is formally described in detail in Section
+:ref:`match-construction`.
+The system recognizes that in the inductive call :g:`(add p m)` the first
+argument actually decreases because it is a *pattern variable* coming from
+:g:`match n with`.
+
+.. example::
+
+ The following definition is not correct and generates an error message:
+
+ .. coqtop:: all
+
+ Fail Fixpoint wrongplus (n m:nat) {struct n} : nat :=
+ match m with
+ | O => n
+ | S p => S (wrongplus n p)
+ end.
+
+ because the declared decreasing argument n actually does not decrease in
+ the recursive call. The function computing the addition over the second
+ argument should rather be written:
+
+ .. coqtop:: all
+
+ Fixpoint plus (n m:nat) {struct m} : nat :=
+ match m with
+ | O => n
+ | S p => S (plus n p)
+ end.
+
+.. example::
+
+ The ordinary match operation on natural numbers can be mimicked in the
+ following way.
+
+ .. coqtop:: all
+
+ Fixpoint nat_match
+ (C:Set) (f0:C) (fS:nat -> C -> C) (n:nat) {struct n} : C :=
+ match n with
+ | O => f0
+ | S p => fS p (nat_match C f0 fS p)
+ end.
+
+.. example::
+
+ The recursive call may not only be on direct subterms of the recursive
+ variable n but also on a deeper subterm and we can directly write the
+ function mod2 which gives the remainder modulo 2 of a natural number.
+
+ .. coqtop:: all
+
+ Fixpoint mod2 (n:nat) : nat :=
+ match n with
+ | O => O
+ | S p => match p with
+ | O => S O
+ | S q => mod2 q
+ end
+ end.
+
+In order to keep the strong normalization property, the fixed point
+reduction will only be performed when the argument in position of the
+decreasing argument (which type should be in an inductive definition)
+starts with a constructor.
+
+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}
+
+allows to define simultaneously fixpoints.
+
+The size of trees and forests can be defined the following way:
+
+.. coqtop:: all
+
+ Fixpoint tree_size (t:tree) : nat :=
+ match t with
+ | node a f => S (forest_size f)
+ end
+ with forest_size (f:forest) : nat :=
+ match f with
+ | leaf b => 1
+ | cons t f' => (tree_size t + forest_size f')
+ end.
+
+A generic command Scheme is useful to build automatically various mutual
+induction principles. It is described in Section
+:ref:`proofschemes-induction-principles`.
+
+.. _cofixpoint:
+
+Definitions of recursive objects in co-inductive types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. 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
+introduced applying the following method to the number :g:`O` (see
+Section :ref:`coinductive-types` for the definition of :g:`Stream`, :g:`hd` and
+:g:`tl`):
+
+.. coqtop:: all
+
+ CoFixpoint from (n:nat) : Stream := Seq n (from (S n)).
+
+Oppositely to recursive ones, there is no decreasing argument in a
+co-recursive definition. To be admissible, a method of construction must
+provide at least one extra constructor of the infinite object for each
+iteration. A syntactical guard condition is imposed on co-recursive
+definitions in order to ensure this: each recursive call in the
+definition must be protected by at least one constructor, and only by
+constructors. That is the case in the former definition, where the
+single recursive call of :g:`from` is guarded by an application of
+:g:`Seq`. On the contrary, the following recursive function does not
+satisfy the guard condition:
+
+.. coqtop:: all
+
+ Fail CoFixpoint filter (p:nat -> bool) (s:Stream) : Stream :=
+ if p (hd s) then Seq (hd s) (filter p (tl s)) else filter p (tl s).
+
+The elimination of co-recursive definition is done lazily, i.e. the
+definition is expanded only when it occurs at the head of an application
+which is the argument of a case analysis expression. In any other
+context, it is considered as a canonical expression which is completely
+evaluated. We can test this using the command ``Eval``, which computes
+the normal forms of a term:
+
+.. coqtop:: all
+
+ Eval compute in (from 0).
+ Eval compute in (hd (from 0)).
+ Eval compute in (tl (from 0)).
+
+.. cmdv:: CoFixpoint @ident @params : @type := @term
+
+ As for most constructions, arguments of co-fixpoints expressions
+ can be introduced before the :g:`:=` sign.
+
+.. cmdv:: CoFixpoint @ident : @type := @term {+ with @ident : @type := @term }
+
+ As in the :cmd:`Fixpoint` command, it is possible to introduce a block of
+ mutually dependent methods.
+
+.. _Assertions:
+
+Assertions and proofs
+---------------------
+
+An assertion states a proposition (or a type) of which the proof (or an
+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
+
+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.
+
+.. exn:: The term @term has type @type which should be Set, Prop or Type.
+
+.. exn:: @ident already exists.
+ :name: @ident already exists. (Theorem)
+
+ The name you provided is already defined. You have then to choose
+ another name.
+
+.. cmdv:: Lemma @ident : @type
+ :name: Lemma
+
+.. cmdv:: Remark @ident : @type
+ :name: Remark
+
+.. cmdv:: Fact @ident : @type
+ :name: Fact
+
+.. cmdv:: Corollary @ident : @type
+ :name: Corollary
+
+.. cmdv:: Proposition @ident : @type
+ :name: Proposition
+
+ These commands are synonyms of ``Theorem`` :token:`ident` : :token:`type`.
+
+.. 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
+ statements in some mutual co-inductive type. It is equivalent to
+ :cmd:`Fixpoint` or :cmd:`CoFixpoint` but using tactics to build the proof of
+ the statements (or the body of the specification, depending on the point of
+ view). The inductive or co-inductive types on which the induction or
+ coinduction has to be done is assumed to be non ambiguous and is guessed by
+ the system.
+
+ Like in a :cmd:`Fixpoint` or :cmd:`CoFixpoint` definition, the induction hypotheses
+ have to be used on *structurally smaller* arguments (for a :cmd:`Fixpoint`) or
+ be *guarded by a constructor* (for a :cmd:`CoFixpoint`). The verification that
+ recursive proof arguments are correct is done only at the time of registering
+ the lemma in the environment. To know if the use of induction hypotheses is
+ correct at some time of the interactive development of a proof, use the
+ command :cmd:`Guarded`.
+
+ The command can be used also with :cmd:`Lemma`, :cmd:`Remark`, etc. instead of
+ :cmd:`Theorem`.
+
+.. 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
+ :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`.
+
+.. 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
+
+ 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
+
+ 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
+
+ When the proof is completed it should be validated and put in the environment
+ using the keyword Qed.
+
+.. exn:: @ident already exists.
+ :name: @ident already exists. (Qed)
+
+.. note::
+
+ #. Several statements can be simultaneously asserted.
+
+ #. 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.
+
+ #. Proofs ended by 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`).
+
+.. cmdv:: Admitted
+ :name: Admitted
+
+ Turns the current asserted statement into an axiom and exits the proof mode.
+
+.. [1]
+ This is similar to the expression “*entry* :math:`\{` sep *entry*
+ :math:`\}`” in standard BNF, or “*entry* :math:`(` sep *entry*
+ :math:`)`\ \*” in the syntax of regular expressions.
+
+.. [2]
+ Except if the inductive type is empty in which case there is no
+ equation that can be used to infer the return type.
diff --git a/doc/sphinx/practical-tools/coq-commands.rst b/doc/sphinx/practical-tools/coq-commands.rst
index 1ff808894..83dddab4f 100644
--- a/doc/sphinx/practical-tools/coq-commands.rst
+++ b/doc/sphinx/practical-tools/coq-commands.rst
@@ -16,6 +16,8 @@ The options are (basically) the same for the first two commands, and
roughly described below. You can also look at the ``man`` pages of
``coqtop`` and ``coqc`` for more details.
+.. _interactive-use:
+
Interactive use (coqtop)
------------------------
@@ -39,10 +41,12 @@ Batch compilation (coqc)
The ``coqc`` command takes a name *file* as argument. Then it looks for a
vernacular file named *file*.v, and tries to compile it into a
-*file*.vo file (See :ref:`TODO-6.5`). Warning: The name *file* should be a
-regular |Coq| identifier, as defined in Section :ref:'TODO-1.1'. It should contain
-only letters, digits or underscores (_). For instance, ``/bar/foo/toto.v`` is valid, but
-``/bar/foo/to-to.v`` is invalid.
+*file*.vo file (See :ref:`compiled-files`).
+
+.. caution:: The name *file* should be a
+ regular |Coq| identifier, as defined in Section :ref:'TODO-1.1'. It should contain
+ only letters, digits or underscores (_). For instance, ``/bar/foo/toto.v`` is valid, but
+ ``/bar/foo/to-to.v`` is invalid.
Customization at launch time
@@ -63,6 +67,7 @@ This 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``.
+.. _customization-by-environment-variables:
By environment variables
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -70,7 +75,7 @@ By environment variables
Load path can be specified to the |Coq| system by setting up ``$COQPATH``
environment variable. It is a list of directories separated by
``:`` (``;`` on Windows). |Coq| will also honor ``$XDG_DATA_HOME`` and
-``$XDG_DATA_DIRS`` (see Section :ref:`TODO-2.6.3`).
+``$XDG_DATA_DIRS`` (see Section :ref:`libraries-and-filesystem`).
Some |Coq| commands call other |Coq| commands. In this case, they look for
the commands in directory specified by ``$COQBIN``. If this variable is
@@ -84,6 +89,8 @@ list of assignments of the form ``name=``:n:``{*; attr}`` where
ANSI escape code. The list of highlight tags can be retrieved with the
``-list-tags`` command-line option of ``coqtop``.
+.. _command-line-options:
+
By command line options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -91,25 +98,25 @@ The following command-line options are recognized by the commands ``coqc``
and ``coqtop``, unless stated otherwise:
:-I *directory*, -include *directory*: Add physical path *directory*
- to the OCaml loadpath. See also: :ref:`TODO-2.6.1` and the
- command Declare ML Module Section :ref:`TODO-6.5`.
+ to the OCaml loadpath. See also: :ref:`names-of-libraries` and the
+ command Declare ML Module Section :ref:`compiled-files`.
:-Q *directory* dirpath: Add physical path *directory* to the list of
directories where |Coq| looks for a file and bind it to the the logical
directory *dirpath*. The subdirectory structure of *directory* is
recursively available from |Coq| using absolute names (extending the
- dirpath prefix) (see Section :ref:`TODO-2.6.2`).Note that only those
+ dirpath prefix) (see Section :ref:`qualified-names`).Note that only those
subdirectories and files which obey the lexical conventions of what is
- an ident (see Section :ref:`TODO-1.1`) are taken into account. Conversely, the
+ an :n:`@ident` are taken into account. Conversely, the
underlying file systems or operating systems may be more restrictive
than |Coq|. While Linux’s ext4 file system supports any |Coq| recursive
layout (within the limit of 255 bytes per file name), the default on
NTFS (Windows) or HFS+ (MacOS X) file systems is on the contrary to
disallow two files differing only in the case in the same directory.
- See also: Section :ref:`TODO-2.6.1`.
+ See also: Section :ref:`names-of-libraries`.
:-R *directory* dirpath: Do as -Q *directory* dirpath but make the
subdirectory structure of *directory* recursively visible so that the
recursive contents of physical *directory* is available from |Coq| using
- short or partially qualified names. See also: Section :ref:`TODO-2.6.1`.
+ short or partially qualified names. See also: Section :ref:`names-of-libraries`.
:-top dirpath: Set the toplevel module name to dirpath instead of Top.
Not valid for `coqc` as the toplevel module name is inferred from the
name of the output file.
@@ -145,7 +152,7 @@ and ``coqtop``, unless stated otherwise:
-compile-verbose.
:-w (all|none|w₁,…,wₙ): Configure the display of warnings. This
option expects all, none or a comma-separated list of warning names or
- categories (see Section :ref:`TODO-6.9.3`).
+ categories (see Section :ref:`controlling-display`).
:-color (on|off|auto): Enable or not the coloring of output of `coqtop`.
Default is auto, meaning that `coqtop` dynamically decides, depending on
whether the output channel supports ANSI escape sequences.
@@ -164,13 +171,13 @@ 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
with a previous version.
:-dump-glob *file*: Dump references for global names in file *file*
- (to be used by coqdoc, see :ref:`TODO-15.4`). By default, if *file.v* is being
+ (to be used by coqdoc, see :ref:`coqdoc`). By default, if *file.v* is being
compiled, *file.glob* is used.
:-no-glob: Disable the dumping of references for global names.
:-image *file*: Set the binary image to be used by `coqc` to be *file*
diff --git a/doc/sphinx/practical-tools/coqide.rst b/doc/sphinx/practical-tools/coqide.rst
index 1fcfc665b..f9903e610 100644
--- a/doc/sphinx/practical-tools/coqide.rst
+++ b/doc/sphinx/practical-tools/coqide.rst
@@ -10,7 +10,7 @@ used as a user-friendly replacement to `coqtop`. Its main purpose is to
allow the user to navigate forward and backward into a Coq vernacular
file, executing corresponding commands or undoing them respectively.
-CoqIDE is run by typing the command `coqide` on the command line.
+|CoqIDE| is run by typing the command `coqide` on the command line.
Without argument, the main screen is displayed with an “unnamed
buffer”, and with a file name as argument, another buffer displaying
the contents of that file. Additionally, `coqide` accepts the same
@@ -43,7 +43,7 @@ is the one where Coq commands are currently executed.
Buffers may be edited as in any text editor, and classical basic
editing commands (Copy/Paste, …) are available in the *Edit* menu.
-CoqIDE offers only basic editing commands, so if you need more complex
+|CoqIDE| offers only basic editing commands, so if you need more complex
editing commands, you may launch your favorite text editor on the
current buffer, using the *Edit/External Editor* menu.
@@ -75,7 +75,7 @@ There are two additional buttons for navigation within the running buffer. The
"down" button with a line goes directly to the end; the "up" button with a line
goes back to the beginning. The handling of errors when using the go-to-the-end
button depends on whether |Coq| is running in asynchronous mode or not (see
-Chapter :ref:`Asyncprocessing`). If it is not running in that mode, execution
+Chapter :ref:`asynchronousandparallelproofprocessing`). If it is not running in that mode, execution
stops as soon as an error is found. Otherwise, execution continues, and the
error is marked with an underline in the error foreground color, with a
background in the error background color (pink by default). The same
@@ -86,14 +86,14 @@ If you ever try to execute a command which happens to run during a
long time, and would like to abort it before its termination, you may
use the interrupt button (the white cross on a red circle).
-There are other buttons on the CoqIDE toolbar: a button to save the running
+There are other buttons on the |CoqIDE| toolbar: a button to save the running
buffer; a button to close the current buffer (an "X"); buttons to switch among
buffers (left and right arrows); an "information" button; and a "gears" button.
-The "information" button is described in Section :ref:`sec:trytactics`.
+The "information" button is described in Section :ref:`try-tactics-automatically`.
The "gears" button submits proof terms to the |Coq| kernel for type-checking.
-When |Coq| uses asynchronous processing (see Chapter :ref:`Asyncprocessing`),
+When |Coq| uses asynchronous processing (see Chapter :ref:`asynchronousandparallelproofprocessing`),
proofs may have been completed without kernel-checking of generated proof terms.
The presence of unchecked proof terms is indicated by ``Qed`` statements that
have a subdued *being-processed* color (light blue by default), rather than the
@@ -150,18 +150,16 @@ arguments.
Queries
------------
-.. _coqide_queryselected:
-
.. image:: ../_static/coqide-queries.png
:alt: |CoqIDE| queries
We call *query* any vernacular command that does not change the current state,
such as ``Check``, ``Search``, etc. To run such commands interactively, without
-writing them in scripts, CoqIDE offers a *query pane*. The query pane can be
+writing them in scripts, |CoqIDE| offers a *query pane*. The query pane can be
displayed on demand by using the ``View`` menu, or using the shortcut ``F1``.
Queries can also be performed by selecting a particular phrase, then choosing an
item from the ``Queries`` menu. The response then appears in the message window.
-Figure :ref:`fig:queryselected` shows the result after selecting of the phrase
+The image above shows the result after selecting of the phrase
``Nat.mul`` in the script window, and choosing ``Print`` from the ``Queries``
menu.
@@ -221,7 +219,7 @@ still edit this configuration file by hand, but this is more involved.
Using Unicode symbols
--------------------------
-CoqIDE is based on GTK+ and inherits from it support for Unicode in
+|CoqIDE| is based on GTK+ and inherits from it support for Unicode in
its text windows. Consequently a large set of symbols is available for
notations.
diff --git a/doc/sphinx/practical-tools/utilities.rst b/doc/sphinx/practical-tools/utilities.rst
index 620c002ff..59a88771a 100644
--- a/doc/sphinx/practical-tools/utilities.rst
+++ b/doc/sphinx/practical-tools/utilities.rst
@@ -33,6 +33,7 @@ For example, to statically link |L_tac|, you can just do:
% ocamlfind ocamlopt -thread -rectypes -linkall -linkpkg \
-package coq.toplevel -package coq.ltac \
toplevel/coqtop\_bin.ml -o my\_toplevel.native
+
and similarly for other plugins.
@@ -43,7 +44,7 @@ The majority of |Coq| projects are very similar: a collection of ``.v``
files and eventually some ``.ml`` ones (a |Coq| plugin). The main piece of
metadata needed in order to build the project are the command line
options to ``coqc`` (e.g. ``-R``, ``-I``, see also: Section
-:ref:`bycommandline`). Collecting the list of files and options is the job
+:ref:`command-line-options`). Collecting the list of files and options is the job
of the ``_CoqProject`` file.
A simple example of a ``_CoqProject`` file follows:
@@ -59,7 +60,7 @@ A simple example of a ``_CoqProject`` file follows:
src/qux_plugin.mlpack
-Currently, both |CoqIDE| and |ProofGeneral| (version ≥ ``4.3pre``)
+Currently, both |CoqIDE| and Proof-General (version ≥ ``4.3pre``)
understand ``_CoqProject`` files and invoke |Coq| with the desired options.
The ``coq_makefile`` utility can be used to set up a build infrastructure
@@ -77,7 +78,7 @@ CoqMakefile
is a generic makefile for ``GNU Make`` that provides
targets to build the project (both ``.v`` and ``.ml*`` files), to install it
system-wide in the ``coq-contrib`` directory (i.e. where |Coq| is installed)
- as well as to invoke |coqdoc| to generate |HTML| documentation.
+ as well as to invoke coqdoc to generate HTML documentation.
CoqMakefile.conf
contains make variables assignments that reflect
@@ -89,7 +90,7 @@ An optional file ``CoqMakefile.local`` can be provided by the user in order to
extend ``CoqMakefile``. In particular one can declare custom actions to be
performed before or after the build process. Similarly one can customize the
install target or even provide new targets. Extension points are documented in
-paragraph :ref:`coqmakefile:local`.
+paragraph :ref:`coqmakefilelocal`.
The extensions of the files listed in ``_CoqProject`` is used in order to
decide how to build them. In particular:
@@ -113,32 +114,38 @@ distinct plugins because of a clash in their auxiliary module names.
.. _coqmakefilelocal:
CoqMakefile.local
-+++++++++++++++++
-
-
+~~~~~~~~~~~~~~~~~
The optional file ``CoqMakefile.local`` is included by the generated
file ``CoqMakefile``. It can contain two kinds of directives.
-Variable assignment
- The variable must belong to the variables listed in the ``Parameters`` section of the generated makefile.
- Here we describe only few of them.
- :CAMLPKGS:
- can be used to specify third party findlib packages, and is
- passed to the OCaml compiler on building or linking of modules. Eg:
- ``-package yojson``.
- :CAMLFLAGS:
- can be used to specify additional flags to the |OCaml|
- compiler, like ``-bin-annot`` or ``-w``....
- :COQC, COQDEP, COQDOC:
- can be set in order to use alternative binaries
- (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`` lets you build a plugin containing OCaml code that depends on the OCaml code of ``Unicoq``.
-
-Rule extension
- The following makefile rules can be extended.
-
- .. example ::
+**Variable assignment**
+
+The variable must belong to the variables listed in the ``Parameters``
+section of the generated makefile.
+Here we describe only few of them.
+
+:CAMLPKGS:
+ can be used to specify third party findlib packages, and is
+ passed to the OCaml compiler on building or linking of modules. Eg:
+ ``-package yojson``.
+:CAMLFLAGS:
+ can be used to specify additional flags to the |OCaml|
+ compiler, like ``-bin-annot`` or ``-w``....
+:COQC, COQDEP, COQDOC:
+ can be set in order to use alternative binaries
+ (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``
+ lets you build a plugin containing OCaml code that depends on the
+ OCaml code of ``Unicoq``.
+
+**Rule extension**
+
+The following makefile rules can be extended.
+
+.. example::
::
@@ -147,42 +154,41 @@ Rule extension
install-extra::
cp ThisExtraFile /there/it/goes
- ``pre-all::``
- run before the all target. One can use this to configure
- the project, or initialize sub modules or check dependencies are met.
+``pre-all::``
+ run before the ``all`` target. One can use this to configure
+ the project, or initialize sub modules or check dependencies are met.
- ``post-all::``
- run after the all target. One can use this to run a test
- suite, or compile extracted code.
+``post-all::``
+ run after the ``all`` target. One can use this to run a test
+ suite, or compile extracted code.
+``install-extra::``
+ run after ``install``. One can use this to install extra files.
- ``install-extra::``
- run after install. One can use this to install extra files.
+``install-doc::``
+ One can use this to install extra doc.
- ``install-doc::``
- One can use this to install extra doc.
+``uninstall::``
+ \
- ``uninstall::``
- \
+``uninstall-doc::``
+ \
- ``uninstall-doc::``
- \
+``clean::``
+ \
- ``clean::``
- \
+``cleanall::``
+ \
- ``cleanall::``
- \
+``archclean::``
+ \
- ``archclean::``
- \
-
- ``merlin-hook::``
- One can append lines to the generated .merlin file extending this
- target.
+``merlin-hook::``
+ One can append lines to the generated ``.merlin`` file extending this
+ target.
Timing targets and performance testing
-++++++++++++++++++++++++++++++++++++++
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The generated ``Makefile`` supports the generation of two kinds of timing
data: per-file build-times, and per-line times for an individual file.
@@ -311,8 +317,8 @@ line timing data:
+ ``print-pretty-single-time-diff``
::
-
print-pretty-single-time-diff BEFORE=path/to/file.v.before-timing AFTER=path/to/file.v.after-timing
+
this target will make a sorted table of the per-line timing differences
between the timing logs in the ``BEFORE`` and ``AFTER`` files, display it, and
save it to the file specified by the ``TIME_OF_PRETTY_BUILD_FILE`` variable,
@@ -357,7 +363,7 @@ line timing data:
Reusing/extending the generated Makefile
-++++++++++++++++++++++++++++++++++++++++
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Including the generated makefile with an include directive is
discouraged. The contents of this file, including variable names and
@@ -400,8 +406,8 @@ have a generic target for invoking unknown targets.
-Building a subset of the targets with -j
-++++++++++++++++++++++++++++++++++++++++
+Building a subset of the targets with ``-j``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To build, say, two targets foo.vo and bar.vo in parallel one can use
``make only TGTS="foo.vo bar.vo" -j``.
@@ -451,14 +457,16 @@ automatically compute the dependencies among the files part of the
project.
+.. _coqdoc:
+
Documenting |Coq| files with coqdoc
-----------------------------------
-|coqdoc| is a documentation tool for the proof assistant |Coq|, similar to
-``javadoc`` or ``ocamldoc``. The task of |coqdoc| is
+coqdoc is a documentation tool for the proof assistant |Coq|, similar to
+``javadoc`` or ``ocamldoc``. The task of coqdoc is
-#. to produce a nice |Latex| and/or |HTML| document from the |Coq|
+#. to produce a nice |Latex| and/or HTML document from the |Coq|
sources, readable for a human and not only for the proof assistant;
#. to help the user navigating in his own (or third-party) sources.
@@ -468,18 +476,18 @@ Principles
~~~~~~~~~~
Documentation is inserted into |Coq| files as *special comments*. Thus
-your files will compile as usual, whether you use |coqdoc| or not. |coqdoc|
+your files will compile as usual, whether you use coqdoc or not. coqdoc
presupposes that the given |Coq| files are well-formed (at least
lexically). Documentation starts with ``(**``, followed by a space, and
ends with the pending ``*)``. The documentation format is inspired by Todd
A. Coram’s *Almost Free Text (AFT)* tool: it is mainly ``ASCII`` text with
-some syntax-light controls, described below. |coqdoc| is robust: it
+some syntax-light controls, described below. coqdoc is robust: it
shouldn’t fail, whatever the input is. But remember: “garbage in,
garbage out”.
|Coq| material inside documentation.
-++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++
|Coq| material is quoted between the delimiters ``[`` and ``]``. Square brackets
may be nested, the inner ones being understood as being part of the
@@ -494,7 +502,7 @@ followed by a newline and the latter must follow a newline.
Pretty-printing.
++++++++++++++++
-|coqdoc| uses different faces for identifiers and keywords. The pretty-
+coqdoc uses different faces for identifiers and keywords. The pretty-
printing of |Coq| tokens (identifiers or symbols) can be controlled
using one of the following commands:
@@ -512,8 +520,8 @@ or
(** printing *token* $...LATEX math...$ #...html...# *)
-It gives the |Latex| and |HTML| texts to be produced for the given |Coq|
-token. One of the |Latex| or |HTML| text may be omitted, causing the
+It gives the |Latex| and HTML texts to be produced for the given |Coq|
+token. One of the |Latex| or HTML text may be omitted, causing the
default pretty-printing to be used for this token.
The printing for one token can be removed with
@@ -530,27 +538,28 @@ Initially, the pretty-printing table contains the following mapping:
`->` → `<-` ← `*` ×
`<=` ≤ `>=` ≥ `=>` ⇒
`<>` ≠ `<->` ↔ `|-` ⊢
-`\/` ∨ `/\` ∧ `~` ¬
+`\/` ∨ `/\\` ∧ `~` ¬
==== === ==== ===== === ==== ==== ===
Any of these can be overwritten or suppressed using the printing
commands.
-.. note ::
- The recognition of tokens is done by a (``ocaml``) lex
- automaton and thus applies the longest-match rule. For instance, `->~`
- is recognized as a single token, where |Coq| sees two tokens. It is the
- responsibility of the user to insert space between tokens *or* to give
- pretty-printing rules for the possible combinations, e.g.
+.. note::
+
+ The recognition of tokens is done by a (``ocaml``) lex
+ automaton and thus applies the longest-match rule. For instance, `->~`
+ is recognized as a single token, where |Coq| sees two tokens. It is the
+ responsibility of the user to insert space between tokens *or* to give
+ pretty-printing rules for the possible combinations, e.g.
- ::
+ ::
(** printing ->~ %\ensuremath{\rightarrow\lnot}% *)
-Sections.
-+++++++++
+Sections
+++++++++
Sections are introduced by 1 to 4 leading stars (i.e. at the beginning
of the line) followed by a space. One star is a section, two stars a
@@ -559,7 +568,7 @@ line.
.. example::
- ::
+ ::
(** * Well-founded relations
@@ -614,18 +623,18 @@ emphasis. Usually, these are spaces or punctuation.
-Escaping to |Latex| and |HTML|.
+Escaping to |Latex| and HTML.
+++++++++++++++++++++++++++++++
-Pure |Latex| or |HTML| material can be inserted using the following
+Pure |Latex| or HTML material can be inserted using the following
escape sequences:
+ ``$...LATEX stuff...$`` inserts some |Latex| material in math mode.
- Simply discarded in |HTML| output.
+ Simply discarded in HTML output.
+ ``%...LATEX stuff...%`` inserts some |Latex| material. Simply
- discarded in |HTML| output.
-+ ``#...HTML stuff...#`` inserts some |HTML| material. Simply discarded in
+ discarded in HTML output.
++ ``#...HTML stuff...#`` inserts some HTML material. Simply discarded in
|Latex| output.
.. note::
@@ -654,7 +663,7 @@ at the beginning of a line.
Hyperlinks
++++++++++
-Hyperlinks can be inserted into the |HTML| output, so that any
+Hyperlinks can be inserted into the HTML output, so that any
identifier is linked to the place of its definition.
``coqc file.v`` automatically dumps localization information in
@@ -662,7 +671,7 @@ identifier is linked to the place of its definition.
file``. Take care of erasing this global file, if any, when starting
the whole compilation process.
-Then invoke |coqdoc| or ``coqdoc --glob-from file`` to tell |coqdoc| to look
+Then invoke coqdoc or ``coqdoc --glob-from file`` to tell coqdoc to look
for name resolutions into the file ``file`` (it will look in ``file.glob``
by default).
@@ -703,17 +712,17 @@ be used around a whole proof.
Usage
~~~~~
-|coqdoc| is invoked on a shell command line as follows:
+coqdoc is invoked on a shell command line as follows:
``coqdoc <options and files>``.
Any command line argument which is not an option is considered to be a
file (even if it starts with a ``-``). |Coq| files are identified by the
suffixes ``.v`` and ``.g`` and |Latex| files by the suffix ``.tex``.
-:|HTML| output: This is the default output. One |HTML| file is created for
+:HTML output: This is the default output. One HTML file is created for
each |Coq| file given on the command line, together with a file
- ``index.html`` (unless ``option-no-index is passed``). The |HTML| pages use a
- style sheet named ``style.css``. Such a file is distributed with |coqdoc|.
+ ``index.html`` (unless ``option-no-index is passed``). The HTML pages use a
+ style sheet named ``style.css``. Such a file is distributed with coqdoc.
:|Latex| output: A single |Latex| file is created, on standard
output. It can be redirected to a file with option ``-o``. The order of
files on the command line is kept in the final document. |Latex|
@@ -732,7 +741,7 @@ Command line options
**Overall options**
- :--|HTML|: Select a |HTML| output.
+ :--HTML: Select a HTML output.
:--|Latex|: Select a |Latex| output.
:--dvi: Select a DVI output.
:--ps: Select a PostScript output.
@@ -760,7 +769,7 @@ Command line options
**Index options**
- Default behavior is to build an index, for the |HTML| output only,
+ Default behavior is to build an index, for the HTML output only,
into ``index.html``.
:--no-index: Do not output the index.
@@ -775,7 +784,7 @@ Command line options
:-toc, --table-of-contents: Insert a table of contents. For a |Latex|
output, it inserts a ``\tableofcontents`` at the beginning of the
- document. For a |HTML| output, it builds a table of contents into
+ document. For a HTML output, it builds a table of contents into
``toc.html``.
:--toc-depth int: Only include headers up to depth ``int`` in the table of
contents.
@@ -795,28 +804,28 @@ Command line options
directory ``coqdir`` (similarly to |Coq| option ``-R``).
.. note::
- option ``-R`` only has
- effect on the files *following* it on the command line, so you will
- probably need to put this option first.
+
+ option ``-R`` only has
+ effect on the files *following* it on the command line, so you will
+ probably need to put this option first.
**Title options**
:-s , --short: Do not insert titles for the files. The default
- behavior is to insert a title like “Library Foo” for each file.
+ behavior is to insert a title like “Library Foo” for each file.
:--lib-name string: Print “string Foo” instead of “Library Foo” in
- titles. For example “Chapter” and “Module” are reasonable choices.
+ titles. For example “Chapter” and “Module” are reasonable choices.
:--no-lib-name: Print just “Foo” instead of “Library Foo” in titles.
:--lib-subtitles: Look for library subtitles. When enabled, the
- beginning of each file is checked for a comment of the form:
-
- ::
+ beginning of each file is checked for a comment of the form:
+ ::
- (** * ModuleName : text *)
+ (** * ModuleName : text *)
- where ``ModuleName`` must be the name of the file. If it is present, the
- text is used as a subtitle for the module in appropriate places.
+ where ``ModuleName`` must be the name of the file. If it is present, the
+ text is used as a subtitle for the module in appropriate places.
:-t string, --title string: Set the document title.
@@ -854,11 +863,11 @@ Command line options
:-latin1, --latin1: Select ISO-8859-1 input files. It is equivalent to
--inputenc latin1 --charset iso-8859-1.
:-utf8, --utf8: Set --inputenc utf8x for |Latex| output and--charset
- utf-8 for |HTML| output. Also use Unicode replacements for a couple of
+ utf-8 for HTML output. Also use Unicode replacements for a couple of
standard plain ASCII notations such as → for ``->`` and ∀ for ``forall``. |Latex|
UTF-8 support can be found
at `<http://www.ctan.org/pkg/unicode>`_. For the interpretation of Unicode
- characters by |Latex|, extra packages which |coqdoc| does not provide
+ characters by |Latex|, extra packages which coqdoc does not provide
by default might be required, such as textgreek for some Greek letters
or ``stmaryrd`` for some mathematical symbols. If a Unicode character is
missing an interpretation in the utf8x input encoding, add
@@ -866,13 +875,13 @@ Command line options
and declarations can be added with option ``-p``.
:--inputenc string: Give a |Latex| input encoding, as an option to |Latex|
package ``inputenc``.
- :--charset string: Specify the |HTML| character set, to be inserted in
- the |HTML| header.
+ :--charset string: Specify the HTML character set, to be inserted in
+ the HTML header.
The coqdoc |Latex| style file
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In case you choose to produce a document without the default |Latex|
preamble (by using option ``--no-preamble``), then you must insert into
@@ -929,16 +938,16 @@ There are options to produce the |Coq| parts in smaller font, italic,
between horizontal rules, etc. See the man page of ``coq-tex`` for more
details.
-|Coq| and |GNU| |Emacs|
+|Coq| and GNU Emacs
-----------------------
-The |Coq| |Emacs| mode
+The |Coq| Emacs mode
~~~~~~~~~~~~~~~~~~~~~~~~~
-|Coq| comes with a Major mode for |GNU| |Emacs|, ``gallina.el``. This mode
+|Coq| comes with a Major mode for GNU Emacs, ``gallina.el``. This mode
provides syntax highlighting and also a rudimentary indentation
-facility in the style of the ``Caml`` |GNU| |Emacs| mode.
+facility in the style of the ``Caml`` GNU Emacs mode.
Add the following lines to your ``.emacs`` file:
@@ -956,26 +965,26 @@ facility:
+ pressing ``Tab`` at the beginning of a line indents the line like the
line above;
-+ extra ``Tab``s increase the indentation level (by 2 spaces by default);
++ extra tabulations increase the indentation level (by 2 spaces by default);
+ ``M-Tab`` decreases the indentation level.
-An inferior mode to run |Coq| under |Emacs|, by Marco Maggesi, is also
+An inferior mode to run |Coq| under Emacs, by Marco Maggesi, is also
included in the distribution, in file ``inferior-coq.el``. Instructions to
use it are contained in this file.
-Proof General
+Proof-General
~~~~~~~~~~~~~
-|ProofGeneral| is a generic interface for proof assistants based on
-|Emacs|. The main idea is that the |Coq| commands you are editing are sent
-to a |Coq| toplevel running behind |Emacs| and the answers of the system
-automatically inserted into other |Emacs| buffers. Thus you don’t need
+Proof-General is a generic interface for proof assistants based on
+Emacs. The main idea is that the |Coq| commands you are editing are sent
+to a |Coq| toplevel running behind Emacs and the answers of the system
+automatically inserted into other Emacs buffers. Thus you don’t need
to copy-paste the |Coq| material from your files to the |Coq| toplevel or
conversely from the |Coq| toplevel to some files.
-|ProofGeneral| is developed and distributed independently of the system
+Proof-General is developed and distributed independently of the system
|Coq|. It is freely available at `<https://proofgeneral.github.io/>`_.
diff --git a/doc/sphinx/proof-engine/detailed-tactic-examples.rst b/doc/sphinx/proof-engine/detailed-tactic-examples.rst
index 932f96788..84810ddba 100644
--- a/doc/sphinx/proof-engine/detailed-tactic-examples.rst
+++ b/doc/sphinx/proof-engine/detailed-tactic-examples.rst
@@ -6,6 +6,8 @@ Detailed examples of tactics
This chapter presents detailed examples of certain tactics, to
illustrate their behavior.
+.. _dependent-induction:
+
dependent induction
-------------------
@@ -316,7 +318,7 @@ explicit proof terms:
This concludes our example.
-See also: The ``induction`` :ref:`TODO-9-induction`, ``case`` :ref:`TODO-9-induction` and ``inversion`` :ref:`TODO-8.14-inversion` tactics.
+See also: The :tacn:`induction`, :tacn:`case`, and :tacn:`inversion` tactics.
autorewrite
@@ -403,6 +405,8 @@ Example 2: Mac Carthy function
autorewrite with base1 using reflexivity || simpl.
+.. _quote:
+
quote
-----
@@ -544,8 +548,7 @@ Combining variables and constants
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
One can have both variables and constants in abstracts terms; for
-example, this is the case for the ``ring`` tactic
-:ref:`TODO-25-ringandfieldtacticfamilies`. Then one must provide to
+example, this is the case for the :tacn:`ring` tactic. Then one must provide to
``quote`` a list of *constructors of constants*. For example, if the list
is ``[O S]`` then closed natural numbers will be considered as constants
and other terms as variables.
@@ -606,7 +609,7 @@ don’t expect miracles from it!
See also: comments of source file ``plugins/quote/quote.ml``
-See also: the ``ring`` tactic :ref:`TODO-25-ringandfieldtacticfamilies`
+See also: the :tacn:`ring` tactic.
Using the tactical language
@@ -733,7 +736,7 @@ and this length is decremented for each rotation down to, but not
including, 1 because for a list of length ``n``, we can make exactly
``n−1`` rotations to generate at most ``n`` distinct lists. Here, it
must be noticed that we use the natural numbers of Coq for the
-rotation counter. On Figure :ref:`TODO-9.1-tactic-language`, we can
+rotation counter. In :ref:`ltac-syntax`, we can
see that it is possible to use usual natural numbers but they are only
used as arguments for primitive tactics and they cannot be handled, in
particular, we cannot make computations with them. So, a natural
@@ -830,7 +833,7 @@ The pattern matching on goals allows a complete and so a powerful
backtracking when returning tactic values. An interesting application
is the problem of deciding intuitionistic propositional logic.
Considering the contraction-free sequent calculi LJT* of Roy Dyckhoff
-:ref:`TODO-56-biblio`, it is quite natural to code such a tactic
+:cite:`Dyc92`, it is quite natural to code such a tactic
using the tactic language as shown on figures: :ref:`Deciding
intuitionistic propositions (1) <decidingintuitionistic1>` and
:ref:`Deciding intuitionistic propositions (2)
@@ -868,7 +871,7 @@ Deciding type isomorphisms
A more tricky problem is to decide equalities between types and modulo
isomorphisms. Here, we choose to use the isomorphisms of the simply
typed λ-calculus with Cartesian product and unit type (see, for
-example, [:ref:`TODO-45`]). The axioms of this λ-calculus are given below.
+example, :cite:`RC95`). The axioms of this λ-calculus are given below.
.. coqtop:: in reset
diff --git a/doc/sphinx/proof-engine/ltac.rst b/doc/sphinx/proof-engine/ltac.rst
new file mode 100644
index 000000000..2b128b98f
--- /dev/null
+++ b/doc/sphinx/proof-engine/ltac.rst
@@ -0,0 +1,1310 @@
+.. include:: ../preamble.rst
+.. include:: ../replaces.rst
+
+.. _ltac:
+
+The tactic language
+===================
+
+This chapter gives a compact documentation of |Ltac|, the tactic language
+available in |Coq|. We start by giving the syntax, and next, we present the
+informal semantics. If you want to know more regarding this language and
+especially about its foundations, you can refer to :cite:`Del00`. Chapter
+:ref:`detailedexamplesoftactics` is devoted to giving examples of use of this
+language on small but also with non-trivial problems.
+
+.. _ltac-syntax:
+
+Syntax
+------
+
+The syntax of the tactic language is given below. See Chapter
+:ref:`gallinaspecificationlanguage` for a description of the BNF metasyntax used
+in these grammar rules. Various already defined entries will be used in this
+chapter: entries :token:`natural`, :token:`integer`, :token:`ident`,
+:token:`qualid`, :token:`term`, :token:`cpattern` and :token:`atomic_tactic`
+represent respectively the natural and integer numbers, the authorized
+identificators and qualified names, Coq terms and patterns and all the atomic
+tactics described in Chapter :ref:`tactics`. The syntax of :token:`cpattern` is
+the same as that of terms, but it is extended with pattern matching
+metavariables. In :token:`cpattern`, a pattern-matching metavariable is
+represented with the syntax :g:`?id` where :g:`id` is an :token:`ident`. The
+notation :g:`_` can also be used to denote metavariable whose instance is
+irrelevant. In the notation :g:`?id`, the identifier allows us to keep
+instantiations and to make constraints whereas :g:`_` shows that we are not
+interested in what will be matched. On the right hand side of pattern-matching
+clauses, the named metavariable are used without the question mark prefix. There
+is also a special notation for second-order pattern-matching problems: in an
+applicative pattern of the form :g:`@?id id1 … idn`, the variable id matches any
+complex expression with (possible) dependencies in the variables :g:`id1 … idn`
+and returns a functional term of the form :g:`fun id1 … idn => term`.
+
+The main entry of the grammar is :n:`@expr`. This language is used in proof
+mode but it can also be used in toplevel definitions as shown below.
+
+.. note::
+
+ - The infix tacticals “… \|\| …”, “… + …”, and “… ; …” are associative.
+
+ - In :token:`tacarg`, there is an overlap between qualid as a direct tactic
+ argument and :token:`qualid` as a particular case of term. The resolution is
+ done by first looking for a reference of the tactic language and if
+ it fails, for a reference to a term. To force the resolution as a
+ reference of the tactic language, use the form :g:`ltac:(@qualid)`. To
+ force the resolution as a reference to a term, use the syntax
+ :g:`(@qualid)`.
+
+ - As shown by the figure, tactical ``\|\|`` binds more than the prefix
+ tacticals try, repeat, do and abstract which themselves bind more
+ than the postfix tactical “… ;[ … ]” which binds more than “… ; …”.
+
+ For instance
+
+ .. coqtop:: in
+
+ try repeat tac1 || tac2; tac3; [tac31 | ... | tac3n]; tac4.
+
+ is understood as
+
+ .. coqtop:: in
+
+ try (repeat (tac1 || tac2));
+ ((tac3; [tac31 | ... | tac3n]); tac4).
+
+.. productionlist:: coq
+ expr : `expr` ; `expr`
+ : | [> `expr` | ... | `expr` ]
+ : | `expr` ; [ `expr` | ... | `expr` ]
+ : | `tacexpr3`
+ tacexpr3 : do (`natural` | `ident`) tacexpr3
+ : | progress `tacexpr3`
+ : | repeat `tacexpr3`
+ : | try `tacexpr3`
+ : | once `tacexpr3`
+ : | exactly_once `tacexpr3`
+ : | timeout (`natural` | `ident`) `tacexpr3`
+ : | time [`string`] `tacexpr3`
+ : | only `selector`: `tacexpr3`
+ : | `tacexpr2`
+ tacexpr2 : `tacexpr1` || `tacexpr3`
+ : | `tacexpr1` + `tacexpr3`
+ : | tryif `tacexpr1` then `tacexpr1` else `tacexpr1`
+ : | `tacexpr1`
+ tacexpr1 : fun `name` ... `name` => `atom`
+ : | let [rec] `let_clause` with ... with `let_clause` in `atom`
+ : | match goal with `context_rule` | ... | `context_rule` end
+ : | match reverse goal with `context_rule` | ... | `context_rule` end
+ : | match `expr` with `match_rule` | ... | `match_rule` end
+ : | lazymatch goal with `context_rule` | ... | `context_rule` end
+ : | lazymatch reverse goal with `context_rule` | ... | `context_rule` end
+ : | lazymatch `expr` with `match_rule` | ... | `match_rule` end
+ : | multimatch goal with `context_rule` | ... | `context_rule` end
+ : | multimatch reverse goal with `context_rule` | ... | `context_rule` end
+ : | multimatch `expr` with `match_rule` | ... | `match_rule` end
+ : | abstract `atom`
+ : | abstract `atom` using `ident`
+ : | first [ `expr` | ... | `expr` ]
+ : | solve [ `expr` | ... | `expr` ]
+ : | idtac [ `message_token` ... `message_token`]
+ : | fail [`natural`] [`message_token` ... `message_token`]
+ : | fresh | fresh `string` | fresh `qualid`
+ : | context `ident` [`term`]
+ : | eval `redexpr` in `term`
+ : | type of `term`
+ : | constr : `term`
+ : | uconstr : `term`
+ : | type_term `term`
+ : | numgoals
+ : | guard `test`
+ : | assert_fails `tacexpr3`
+ : | assert_suceeds `tacexpr3`
+ : | `atomic_tactic`
+ : | `qualid` `tacarg` ... `tacarg`
+ : | `atom`
+ atom : `qualid`
+ : | ()
+ : | `integer`
+ : | ( `expr` )
+ message_token : `string` | `ident` | `integer`
+ tacarg : `qualid`
+ : | ()
+ : | ltac : `atom`
+ : | `term`
+ let_clause : `ident` [`name` ... `name`] := `expr`
+ context_rule : `context_hyp`, ..., `context_hyp` |- `cpattern` => `expr`
+ : | `cpattern` => `expr`
+ : | |- `cpattern` => `expr`
+ : | _ => `expr`
+ context_hyp : `name` : `cpattern`
+ : | `name` := `cpattern` [: `cpattern`]
+ match_rule : `cpattern` => `expr`
+ : | context [ident] [ `cpattern` ] => `expr`
+ : | _ => `expr`
+ test : `integer` = `integer`
+ : | `integer` (< | <= | > | >=) `integer`
+ selector : [`ident`]
+ : | `integer`
+ : (`integer` | `integer` - `integer`), ..., (`integer` | `integer` - `integer`)
+ toplevel_selector : `selector`
+ : | `all`
+ : | `par`
+
+.. productionlist:: coq
+ top : [Local] Ltac `ltac_def` with ... with `ltac_def`
+ ltac_def : `ident` [`ident` ... `ident`] := `expr`
+ : | `qualid` [`ident` ... `ident`] ::= `expr`
+
+.. _ltac-semantics:
+
+Semantics
+---------
+
+Tactic expressions can only be applied in the context of a proof. The
+evaluation yields either a term, an integer or a tactic. Intermediary
+results can be terms or integers but the final result must be a tactic
+which is then applied to the focused goals.
+
+There is a special case for ``match goal`` expressions of which the clauses
+evaluate to tactics. Such expressions can only be used as end result of
+a tactic expression (never as argument of a non recursive local
+definition or of an application).
+
+The rest of this section explains the semantics of every construction of
+|Ltac|.
+
+Sequence
+~~~~~~~~
+
+A sequence is an expression of the following form:
+
+.. tacn:: @expr ; @expr
+ :name: ;
+
+ The expression :n:`@expr__1` is evaluated to :n:`v__1`, which must be
+ a tactic value. The tactic :n:`v__1` is applied to the current goal,
+ possibly producing more goals. Then :n:`@expr__2` is evaluated to
+ produce :n:`v__2`, which must be a tactic value. The tactic
+ :n:`v__2` is applied to all the goals produced by the prior
+ application. Sequence is associative.
+
+Local application of tactics
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Different tactics can be applied to the different goals using the
+following form:
+
+.. tacn:: [> {*| @expr }]
+ :name: [> ... | ... | ... ] (dispatch)
+
+ The expressions :n:`@expr__i` are evaluated to :n:`v__i`, for
+ i=0,...,n and all have to be tactics. The :n:`v__i` is applied to the
+ i-th goal, for =1,...,n. It fails if the number of focused goals is not
+ exactly n.
+
+ .. note::
+
+ If no tactic is given for the i-th goal, it behaves as if the tactic idtac
+ were given. For instance, ``[> | auto]`` is a shortcut for ``[> idtac | auto
+ ]``.
+
+ .. tacv:: [> {*| @expr} | @expr .. | {*| @expr}]
+
+ In this variant, token:`expr` is used for each goal coming after those
+ covered by the first list of :n:`@expr` but before those coevered by the
+ last list of :n:`@expr`.
+
+ .. tacv:: [> {*| @expr} | .. | {*| @expr}]
+
+ In this variant, idtac is used for the goals not covered by the two lists of
+ :n:`@expr`.
+
+ .. tacv:: [> @expr .. ]
+
+ In this variant, the tactic :n:`@expr` is applied independently to each of
+ the goals, rather than globally. In particular, if there are no goal, the
+ tactic is not run at all. A tactic which expects multiple goals, such as
+ ``swap``, would act as if a single goal is focused.
+
+ .. tacv:: expr ; [{*| @expr}]
+
+ This variant of local tactic application is paired with a sequence. In this
+ variant, there must be as many :n:`@expr` in the list as goals generated
+ by the application of the first :n:`@expr` to each of the individual goals
+ independently. All the above variants work in this form too.
+ Formally, :n:`@expr ; [ ... ]` is equivalent to :n:`[> @expr ; [> ... ] .. ]`.
+
+.. _goal-selectors:
+
+Goal selectors
+~~~~~~~~~~~~~~
+
+We can restrict the application of a tactic to a subset of the currently
+focused goals with:
+
+.. tacn:: @toplevel_selector : @expr
+ :name: ... : ... (goal selector)
+
+ We can also use selectors as a tactical, which allows to use them nested
+ 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.
+
+ .. tacv:: [@ident] : @expr
+
+ In this variant, :n:`@expr` is applied locally to a goal previously named
+ by the user (see :ref:`existential-variables`).
+
+ .. tacv:: @num : @expr
+
+ In this variant, :n:`@expr` is applied locally to the :token:`num`-th goal.
+
+ .. tacv:: {+, @num-@num} : @expr
+
+ In this variant, :n:`@expr` is applied globally to the subset of goals
+ described by the given ranges. You can write a single ``n`` as a shortcut
+ 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.
+
+ .. tacv:: !: @expr
+
+ In this variant, if exactly one goal is focused :n:`expr` is
+ applied to it. Otherwise the tactical fails. ``!:`` can only be
+ 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
+ ``-async-proofs-tac-j`` taking as argument the desired number of workers.
+ Limitations: ``par:`` only works on goals containing no existential
+ variables and :n:`@expr` must either solve the goal completely or do
+ 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)
+
+ .. TODO change error message index entry
+
+For loop
+~~~~~~~~
+
+There is a for loop that repeats a tactic :token:`num` times:
+
+.. tacn:: do @num @expr
+ :name: do
+
+ :n:`@expr` is evaluated to ``v`` which must be a tactic value. This tactic
+ value ``v`` is applied :token:`num` times. Supposing :token:`num` > 1, after the
+ first application of ``v``, ``v`` is applied, at least once, to the generated
+ subgoals and so on. It fails if the application of ``v`` fails before the num
+ applications have been completed.
+
+Repeat loop
+~~~~~~~~~~~
+
+We have a repeat loop with:
+
+.. tacn:: repeat @expr
+ :name: repeat
+
+ :n:`@expr` is evaluated to ``v``. If ``v`` denotes a tactic, this tactic is
+ applied to each focused goal independently. If the application succeeds, the
+ tactic is applied recursively to all the generated subgoals until it eventually
+ fails. The recursion stops in a subgoal when the tactic has failed *to make
+ progress*. The tactic :n:`repeat @expr` itself never fails.
+
+Error catching
+~~~~~~~~~~~~~~
+
+We can catch the tactic errors with:
+
+.. tacn:: try @expr
+ :name: try
+
+ :n:`@expr` is evaluated to ``v`` which must be a tactic value. The tactic
+ value ``v`` is applied to each focused goal independently. If the application of
+ ``v`` fails in a goal, it catches the error and leaves the goal unchanged. If the
+ level of the exception is positive, then the exception is re-raised with its
+ level decremented.
+
+Detecting progress
+~~~~~~~~~~~~~~~~~~
+
+We can check if a tactic made progress with:
+
+.. tacn:: progress expr
+ :name: progress
+
+ :n:`@expr` is evaluated to v which must be a tactic value. The tactic value ``v``
+ is applied to each focued subgoal independently. If the application of ``v``
+ 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.
+
+Backtracking branching
+~~~~~~~~~~~~~~~~~~~~~~
+
+We can branch with the following structure:
+
+.. tacn:: @expr__1 + @expr__2
+ :name: + (backtracking branching)
+
+ :n:`@expr__1` and :n:`@expr__2` are evaluated respectively to :n:`v__1` and
+ :n:`v__2` which must be tactic values. The tactic value :n:`v__1` is applied to
+ each focused goal independently and if it fails or a later tactic fails, then
+ the proof backtracks to the current goal and :n:`v__2` is applied.
+
+ Tactics can be seen as having several successes. When a tactic fails it
+ asks for more successes of the prior tactics.
+ :n:`@expr__1 + @expr__2` has all the successes of :n:`v__1` followed by all the
+ successes of :n:`v__2`. Algebraically,
+ :n:`(@expr__1 + @expr__2); @expr__3 = (@expr__1; @expr__3) + (@expr__2; @expr__3)`.
+
+ Branching is left-associative.
+
+First tactic to work
+~~~~~~~~~~~~~~~~~~~~
+
+Backtracking branching may be too expensive. In this case we may
+restrict to a local, left biased, branching and consider the first
+tactic to work (i.e. which does not fail) among a panel of tactics:
+
+.. tacn:: first [{*| @expr}]
+ :name: first
+
+ The :n:`@expr__i` are evaluated to :n:`v__i` and :n:`v__i` must be
+ tactic values, for i=1,...,n. Supposing n>1, it applies, in each focused
+ goal independently, :n:`v__1`, if it works, it stops otherwise it
+ tries to apply :n:`v__2` and so on. It fails when there is no
+ applicable tactic. In other words,
+ :n:`first [:@expr__1 | ... | @expr__n]` behaves, in each goal, as the the first
+ :n:`v__i` to have *at least* one success.
+
+ .. exn:: No applicable tactic.
+
+ .. tacv:: first @expr
+
+ This is an |Ltac| alias that gives a primitive access to the first
+ tactical as a |Ltac| definition without going through a parsing rule. It
+ expects to be given a list of tactics through a ``Tactic Notation``,
+ allowing to write notations of the following form:
+
+ .. example::
+
+ .. coqtop:: in
+
+ Tactic Notation "foo" tactic_list(tacs) := first tacs.
+
+Left-biased branching
+~~~~~~~~~~~~~~~~~~~~~
+
+Yet another way of branching without backtracking is the following
+structure:
+
+.. tacn:: @expr__1 || @expr__2
+ :name: || (left-biased branching)
+
+ :n:`@expr__1` and :n:`@expr__2` are evaluated respectively to :n:`v__1` and
+ :n:`v__2` which must be tactic values. The tactic value :n:`v__1` is
+ applied in each subgoal independently and if it fails *to progress* then
+ :n:`v__2` is applied. :n:`@expr__1 || @expr__2` is
+ equivalent to :n:`first [ progress @expr__1 | @expr__2 ]` (except that
+ if it fails, it fails like :n:`v__2`). Branching is left-associative.
+
+Generalized biased branching
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The tactic
+
+.. tacn:: tryif @expr__1 then @expr__2 else @expr__3
+ :name: tryif
+
+ is a generalization of the biased-branching tactics above. The
+ expression :n:`@expr__1` is evaluated to :n:`v__1`, which is then
+ applied to each subgoal independently. For each goal where :n:`v__1`
+ succeeds at least once, :n:`@expr__2` is evaluated to :n:`v__2` which
+ is then applied collectively to the generated subgoals. The :n:`v__2`
+ tactic can trigger backtracking points in :n:`v__1`: where :n:`v__1`
+ succeeds at least once,
+ :n:`tryif @expr__1 then @expr__2 else @expr__3` is equivalent to
+ :n:`v__1; v__2`. In each of the goals where :n:`v__1` does not succeed at least
+ once, :n:`@expr__3` is evaluated in :n:`v__3` which is is then applied to the
+ goal.
+
+Soft cut
+~~~~~~~~
+
+Another way of restricting backtracking is to restrict a tactic to a
+single success *a posteriori*:
+
+.. tacn:: once @expr
+ :name: once
+
+ :n:`@expr` is evaluated to ``v`` which must be a tactic value. The tactic value
+ ``v`` is applied but only its first success is used. If ``v`` fails,
+ :n:`once @expr` fails like ``v``. If ``v`` has a least one success,
+ :n:`once @expr` succeeds once, but cannot produce more successes.
+
+Checking the successes
+~~~~~~~~~~~~~~~~~~~~~~
+
+Coq provides an experimental way to check that a tactic has *exactly
+one* success:
+
+.. tacn:: exactly_once @expr
+ :name: exactly_once
+
+ :n:`@expr` is evaluated to ``v`` which must be a tactic value. The tactic value
+ ``v`` is applied if it has at most one success. If ``v`` fails,
+ :n:`exactly_once @expr` fails like ``v``. If ``v`` has a exactly one success,
+ :n:`exactly_once @expr` succeeds like ``v``. If ``v`` has two or more
+ successes, exactly_once expr fails.
+
+ .. warning::
+
+ The experimental status of this tactic pertains to the fact if ``v``
+ performs side effects, they may occur in a unpredictable way. Indeed,
+ normally ``v`` would only be executed up to the first success until
+ backtracking is needed, however exactly_once needs to look ahead to see
+ whether a second success exists, and may run further effects
+ immediately.
+
+ .. exn:: This tactic has more than one success.
+
+Checking the failure
+~~~~~~~~~~~~~~~~~~~~
+
+Coq provides a derived tactic to check that a tactic *fails*:
+
+.. tacn:: assert_fails @expr
+ :name: assert_fails
+
+ This behaves like :n:`tryif @expr then fail 0 tac "succeeds" else idtac`.
+
+Checking the success
+~~~~~~~~~~~~~~~~~~~~
+
+Coq provides a derived tactic to check that a tactic has *at least one*
+success:
+
+.. tacn:: assert_succeeds @expr
+ :name: assert_suceeds
+
+ This behaves like
+ :n:`tryif (assert_fails tac) then fail 0 tac "fails" else idtac`.
+
+Solving
+~~~~~~~
+
+We may consider the first to solve (i.e. which generates no subgoal)
+among a panel of tactics:
+
+.. tacn:: solve [{*| @expr}]
+ :name: solve
+
+ The :n:`@expr__i` are evaluated to :n:`v__i` and :n:`v__i` must be
+ tactic values, for i=1,...,n. Supposing n>1, it applies :n:`v__1` to
+ 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.
+
+ .. tacv:: solve @expr
+
+ This is an |Ltac| alias that gives a primitive access to the :n:`solve:`
+ tactical. See the :n:`first` tactical for more information.
+
+Identity
+~~~~~~~~
+
+The constant :n:`idtac` is the identity tactic: it leaves any goal unchanged but
+it appears in the proof script.
+
+.. tacn:: idtac {* message_token}
+ :name: idtac
+
+ This prints the given tokens. Strings and integers are printed
+ literally. If a (term) variable is given, its contents are printed.
+
+Failing
+~~~~~~~
+
+.. tacn:: fail
+ :name: 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. The
+ :tacn:`fail` tactic will, however, succeed if all the goals have already been
+ solved.
+
+ .. 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
+ tacticals. If 0, it makes :tacn:`match goal` considering the next clause
+ (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 @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 @num {* message_token}
+
+ This is a combination of the previous variants.
+
+ .. tacv:: gfail
+ :name: gfail
+
+ This variant fails even if there are no goals left.
+
+ .. tacv:: gfail {* 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
+ printed as part of the failure: term construction always forces the
+ 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 @num).
+
+Timeout
+~~~~~~~
+
+We can force a tactic to stop if it has not finished after a certain
+amount of time:
+
+.. tacn:: timeout @num @expr
+ :name: timeout
+
+ :n:`@expr` is evaluated to ``v`` which must be a tactic value. The tactic value
+ ``v`` is applied normally, except that it is interrupted after :n:`@num` seconds
+ if it is still running. In this case the outcome is a failure.
+
+ .. warning::
+
+ For the moment, timeout is based on elapsed time in seconds,
+ which is very machine-dependent: a script that works on a quick machine
+ may fail on a slow one. The converse is even possible if you combine a
+ timeout with some other tacticals. This tactical is hence proposed only
+ for convenience during debug or other development phases, we strongly
+ advise you to not leave any timeout in final scripts. Note also that
+ this tactical isn’t available on the native Windows port of Coq.
+
+Timing a tactic
+~~~~~~~~~~~~~~~
+
+A tactic execution can be timed:
+
+.. tacn:: time @string @expr
+ :name: time
+
+ evaluates :n:`@expr` and displays the time the tactic expression ran, whether it
+ fails or successes. In case of several successes, the time for each successive
+ runs is displayed. Time is in seconds and is machine-dependent. The :n:`@string`
+ argument is optional. When provided, it is used to identify this particular
+ occurrence of time.
+
+Timing a tactic that evaluates to a term
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Tactic expressions that produce terms can be timed with the experimental
+tactic
+
+.. tacn:: time_constr expr
+ :name: time_constr
+
+ which evaluates :n:`@expr ()` and displays the time the tactic expression
+ evaluated, assuming successful evaluation. Time is in seconds and is
+ machine-dependent.
+
+ This tactic currently does not support nesting, and will report times
+ based on the innermost execution. This is due to the fact that it is
+ implemented using the tactics
+
+ .. tacn:: restart_timer @string
+ :name: restart_timer
+
+ and
+
+ .. tacn:: finish_timing {? @string} @string
+ :name: finish_timing
+
+ which (re)set and display an optionally named timer, respectively. The
+ parenthesized string argument to :n:`finish_timing` is also optional, and
+ determines the label associated with the timer for printing.
+
+ By copying the definition of :n:`time_constr` from the standard library,
+ users can achive support for a fixed pattern of nesting by passing
+ different :n:`@string` parameters to :n:`restart_timer` and :n:`finish_timing`
+ at each level of nesting.
+
+ .. example::
+
+ .. coqtop:: all
+
+ Ltac time_constr1 tac :=
+ let eval_early := match goal with _ => restart_timer "(depth 1)" end in
+ let ret := tac () in
+ let eval_early := match goal with _ => finish_timing ( "Tactic evaluation" ) "(depth 1)" end in
+ ret.
+
+ Goal True.
+ let v := time_constr
+ ltac:(fun _ =>
+ let x := time_constr1 ltac:(fun _ => constr:(10 * 10)) in
+ let y := time_constr1 ltac:(fun _ => eval compute in x) in
+ y) in
+ pose v.
+ Abort.
+
+Local definitions
+~~~~~~~~~~~~~~~~~
+
+Local definitions can be done as follows:
+
+.. tacn:: let @ident__1 := @expr__1 {* with @ident__i := @expr__i} in @expr
+
+ each :n:`@expr__i` is evaluated to :n:`v__i`, then, :n:`@expr` is evaluated
+ by substituting :n:`v__i` to each occurrence of :n:`@ident__i`, for
+ i=1,...,n. There is no dependencies between the :n:`@expr__i` and the
+ :n:`@ident__i`.
+
+ Local definitions can be recursive by using :n:`let rec` instead of :n:`let`.
+ In this latter case, the definitions are evaluated lazily so that the rec
+ keyword can be used also in non recursive cases so as to avoid the eager
+ evaluation of local definitions.
+
+ .. but rec changes the binding!!
+
+Application
+~~~~~~~~~~~
+
+An application is an expression of the following form:
+
+.. tacn:: @qualid {+ @tacarg}
+
+ The reference :n:`@qualid` must be bound to some defined tactic definition
+ expecting at least as many arguments as the provided :n:`tacarg`. The
+ expressions :n:`@expr__i` are evaluated to :n:`v__i`, for i=1,...,n.
+
+ .. what expressions ??
+
+Function construction
+~~~~~~~~~~~~~~~~~~~~~
+
+A parameterized tactic can be built anonymously (without resorting to
+local definitions) with:
+
+.. tacn:: fun {+ @ident} => @expr
+
+ Indeed, local definitions of functions are a syntactic sugar for binding
+ a :n:`fun` tactic to an identifier.
+
+Pattern matching on terms
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We can carry out pattern matching on terms with:
+
+.. tacn:: match @expr with {+| @cpattern__i => @expr__i} end
+
+ The expression :n:`@expr` is evaluated and should yield a term which is
+ matched against :n:`cpattern__1`. The matching is non-linear: if a
+ metavariable occurs more than once, it should match the same expression
+ every time. It is first-order except on the variables of the form :n:`@?id`
+ that occur in head position of an application. For these variables, the
+ matching is second-order and returns a functional term.
+
+ Alternatively, when a metavariable of the form :n:`?id` occurs under binders,
+ say :n:`x__1, …, x__n` and the expression matches, the
+ metavariable is instantiated by a term which can then be used in any
+ context which also binds the variables :n:`x__1, …, x__n` with
+ same types. This provides with a primitive form of matching under
+ context which does not require manipulating a functional term.
+
+ If the matching with :n:`@cpattern__1` succeeds, then :n:`@expr__1` is
+ evaluated into some value by substituting the pattern matching
+ instantiations to the metavariables. If :n:`@expr__1` evaluates to a
+ tactic and the match expression is in position to be applied to a goal
+ (e.g. it is not bound to a variable by a :n:`let in`), then this tactic is
+ applied. If the tactic succeeds, the list of resulting subgoals is the
+ result of the match expression. If :n:`@expr__1` does not evaluate to a
+ tactic or if the match expression is not in position to be applied to a
+ goal, then the result of the evaluation of :n:`@expr__1` is the result
+ of the match expression.
+
+ If the matching with :n:`@cpattern__1` fails, or if it succeeds but the
+ evaluation of :n:`@expr__1` fails, or if the evaluation of
+ :n:`@expr__1` succeeds but returns a tactic in execution position whose
+ execution fails, then :n:`cpattern__2` is used and so on. The pattern
+ :n:`_` matches any term and shunts all remaining patterns if any. If all
+ clauses fail (in particular, there is no pattern :n:`_`) then a
+ no-matching-clause error is raised.
+
+ Failures in subsequent tactics do not cause backtracking to select new
+ branches or inside the right-hand side of the selected branch even if it
+ has backtracking points.
+
+ .. 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.
+
+ This happens when :n:`@expr` does not denote a term.
+
+ .. tacv:: multimatch @expr with {+| @cpattern__i => @expr__i} end
+
+ Using multimatch instead of match will allow subsequent tactics to
+ backtrack into a right-hand side tactic which has backtracking points
+ left and trigger the selection of a new matching branch when all the
+ backtracking points of the right-hand side have been consumed.
+
+ The syntax :n:`match …` is, in fact, a shorthand for :n:`once multimatch …`.
+
+ .. tacv:: lazymatch @expr with {+| @cpattern__i => @expr__i} end
+
+ Using lazymatch instead of match will perform the same pattern
+ matching procedure but will commit to the first matching branch
+ rather than trying a new matching if the right-hand side fails. If
+ the right-hand side of the selected branch is a tactic with
+ backtracking points, then subsequent failures cause this tactic to
+ backtrack.
+
+ .. tacv:: context @ident [@cpattern]
+
+ This special form of patterns matches any term with a subterm matching
+ cpattern. If there is a match, the optional :n:`@ident` is assigned the "matched
+ context", i.e. the initial term where the matched subterm is replaced by a
+ hole. The example below will show how to use such term contexts.
+
+ If the evaluation of the right-hand-side of a valid match fails, the next
+ matching subterm is tried. If no further subterm matches, the next clause
+ is tried. Matching subterms are considered top-bottom and from left to
+ right (with respect to the raw printing obtained by setting option
+ :opt:`Printing All`).
+
+ .. example::
+
+ .. coqtop:: all
+
+ Ltac f x :=
+ match x with
+ context f [S ?X] =>
+ idtac X; (* To display the evaluation order *)
+ assert (p := eq_refl 1 : X=1); (* To filter the case X=1 *)
+ let x:= context f[O] in assert (x=O) (* To observe the context *)
+ end.
+ Goal True.
+ f (3+4).
+
+.. _ltac-match-goal:
+
+Pattern matching on goals
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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
+ goal and if :n:`cpattern_1` is matched by the conclusion of the goal,
+ then :n:`@expr__1` is evaluated to :n:`v__1` by substituting the
+ pattern matching to the metavariables and the real hypothesis names
+ bound to the possible hypothesis names occurring in the hypothesis
+ patterns. If :n:`v__1` is a tactic value, then it is applied to the
+ goal. If this application fails, then another combination of hypotheses
+ is tried with the same proof context pattern. If there is no other
+ combination of hypotheses then the second proof context pattern is tried
+ and so on. If the next to last proof context pattern fails then
+ the last :n:`@expr` is evaluated to :n:`v` and :n:`v` is
+ applied. Note also that matching against subterms (using the :n:`context
+ @ident [ @cpattern ]`) is available and is also subject to yielding several
+ matchings.
+
+ Failures in subsequent tactics do not cause backtracking to select new
+ 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.
+
+ No clause succeeds, i.e. all matching patterns, if any, fail at the
+ application of the right-hand-side.
+
+ .. note::
+
+ It is important to know that each hypothesis of the goal can be matched
+ by at most one hypothesis pattern. The order of matching is the
+ following: hypothesis patterns are examined from the right to the left
+ (i.e. hyp\ :sub:`i,m`\ :sub:`i`` before hyp\ :sub:`i,1`). For each
+ hypothesis pattern, the goal hypothesis are matched in order (fresher
+ hypothesis first), but it possible to reverse this order (older first)
+ with the :n:`match reverse goal with` variant.
+
+ .. tacv:: multimatch goal with {+| {+ hyp} |- @cpattern => @expr } | _ => @expr end
+
+ Using :n:`multimatch` instead of :n:`match` will allow subsequent tactics
+ to backtrack into a right-hand side tactic which has backtracking points
+ left and trigger the selection of a new matching branch or combination of
+ hypotheses when all the backtracking points of the right-hand side have
+ been consumed.
+
+ The syntax :n:`match [reverse] goal …` is, in fact, a shorthand for
+ :n:`once multimatch [reverse] goal …`.
+
+ .. tacv:: lazymatch goal with {+| {+ hyp} |- @cpattern => @expr } | _ => @expr end
+
+ Using lazymatch instead of match will perform the same pattern matching
+ procedure but will commit to the first matching branch with the first
+ matching combination of hypotheses rather than trying a new matching if
+ the right-hand side fails. If the right-hand side of the selected branch
+ is a tactic with backtracking points, then subsequent failures cause
+ this tactic to backtrack.
+
+Filling a term context
+~~~~~~~~~~~~~~~~~~~~~~
+
+The following expression is not a tactic in the sense that it does not
+produce subgoals but generates a term to be used in tactic expressions:
+
+.. tacn:: context @ident [@expr]
+
+ :n:`@ident` must denote a context variable bound by a context pattern of a
+ 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.
+
+Generating fresh hypothesis names
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Tactics sometimes have to generate new names for hypothesis. Letting the
+system decide a name with the intro tactic is not so good since it is
+very awkward to retrieve the name the system gave. The following
+expression returns an identifier:
+
+.. tacn:: fresh {* component}
+
+ It evaluates to an identifier unbound in the goal. This fresh identifier
+ is obtained by concatenating the value of the :n:`@component`s (each of them
+ is, either a :n:`@qualid` which has to refer to a (unqualified) name, or
+ directly a name denoted by a :n:`@string`).
+
+ .. I don't understand this component thing. Couldn't we give the grammar?
+
+ If the resulting name is already used, it is padded with a number so that it
+ becomes fresh. If no component is given, the name is a fresh derivative of
+ the name ``H``.
+
+Computing in a constr
+~~~~~~~~~~~~~~~~~~~~~
+
+Evaluation of a term can be performed with:
+
+.. tacn:: eval @redexpr in @term
+
+ where :n:`@redexpr` is a reduction tactic among :tacn:`red`, :tacn:`hnf`,
+ :tacn:`compute`, :tacn:`simpl`, :tacn:`cbv`, :tacn:`lazy`, :tacn:`unfold`,
+ :tacn:`fold`, :tacn:`pattern`.
+
+Recovering the type of a term
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following returns the type of term:
+
+.. tacn:: type of @term
+
+Manipulating untyped terms
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. tacn:: uconstr : @term
+
+ The terms built in |Ltac| are well-typed by default. It may not be
+ appropriate for building large terms using a recursive |Ltac| function: the
+ term has to be entirely type checked at each step, resulting in potentially
+ very slow behavior. It is possible to build untyped terms using |Ltac| with
+ the :n:`uconstr : @term` syntax.
+
+.. tacn:: type_term @term
+
+ An untyped term, in |Ltac|, can contain references to hypotheses or to
+ |Ltac| variables containing typed or untyped terms. An untyped term can be
+ type-checked using the function type_term whose argument is parsed as an
+ untyped term and returns a well-typed term which can be used in tactics.
+
+Untyped terms built using :n:`uconstr :` can also be used as arguments to the
+:tacn:`refine` tactic. In that case the untyped term is type
+checked against the conclusion of the goal, and the holes which are not solved
+by the typing procedure are turned into new subgoals.
+
+Counting the goals
+~~~~~~~~~~~~~~~~~~
+
+.. tacn:: numgoals
+
+ The number of goals under focus can be recovered using the :n:`numgoals`
+ function. Combined with the guard command below, it can be used to
+ branch over the number of goals produced by previous tactics.
+
+ .. example::
+
+ .. coqtop:: in
+
+ Ltac pr_numgoals := let n := numgoals in idtac "There are" n "goals".
+
+ Goal True /\ True /\ True.
+ split;[|split].
+
+ .. coqtop:: all
+
+ all:pr_numgoals.
+
+Testing boolean expressions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. tacn:: guard @test
+ :name: guard
+
+ The :tacn:`guard` tactic tests a boolean expression, and fails if the expression
+ evaluates to false. If the expression evaluates to true, it succeeds
+ without affecting the proof.
+
+ The accepted tests are simple integer comparisons.
+
+ .. example::
+
+ .. coqtop:: in
+
+ Goal True /\ True /\ True.
+ split;[|split].
+
+ .. coqtop:: all
+
+ all:let n:= numgoals in guard n<4.
+ Fail all:let n:= numgoals in guard n=2.
+
+ .. exn:: Condition not satisfied.
+
+Proving a subgoal as a separate lemma
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. tacn:: abstract @expr
+ :name: abstract
+
+ From the outside, :n:`abstract @expr` is the same as :n:`solve @expr`.
+ Internally it saves an auxiliary lemma called ``ident_subproofn`` where
+ ``ident`` is the name of the current goal and ``n`` is chosen so that this is
+ a fresh name. Such an auxiliary lemma is inlined in the final proof term.
+
+ This tactical is useful with tactics such as :tacn:`omega` or
+ :tacn:`discriminate` that generate huge proof terms. With that tool the user
+ can avoid the explosion at time of the Save command without having to cut
+ manually the proof in smaller lemmas.
+
+ It may be useful to generate lemmas minimal w.r.t. the assumptions they
+ depend on. This can be obtained thanks to the option below.
+
+ .. tacv:: abstract @expr using @ident
+
+ Give explicitly the name of the auxiliary lemma.
+
+ .. warning::
+
+ Use this feature at your own risk; explicitly named and reused subterms
+ don’t play well with asynchronous proofs.
+
+ .. tacv:: transparent_abstract @expr
+ :name: transparent_abstract
+
+ Save the subproof in a transparent lemma rather than an opaque one.
+
+ .. warning::
+
+ Use this feature at your own risk; building computationally relevant
+ terms with tactics is fragile.
+
+ .. tacv:: transparent_abstract @expr using @ident
+
+ Give explicitly the name of the auxiliary transparent lemma.
+
+ .. warning::
+
+ Use this feature at your own risk; building computationally relevant terms
+ 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)
+
+Tactic toplevel definitions
+---------------------------
+
+Defining |Ltac| functions
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Basically, |Ltac| toplevel definitions are made as follows:
+
+.. cmd:: Ltac @ident {* @ident} := @expr
+
+ This defines a new |Ltac| function that can be used in any tactic
+ script or new |Ltac| toplevel definition.
+
+ .. note::
+
+ The preceding definition can equivalently be written:
+
+ :n:`Ltac @ident := fun {+ @ident} => @expr`
+
+ Recursive and mutual recursive function definitions are also possible
+ with the syntax:
+
+ .. cmdv:: Ltac @ident {* @ident} {* with @ident {* @ident}} := @expr
+
+ It is also possible to *redefine* an existing user-defined tactic using the syntax:
+
+ .. cmdv:: Ltac @qualid {* @ident} ::= @expr
+
+ A previous definition of qualid must exist in the environment. The new
+ definition will always be used instead of the old one and it goes across
+ module boundaries.
+
+ If preceded by the keyword Local the tactic definition will not be
+ exported outside the current module.
+
+Printing |Ltac| tactics
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. cmd:: Print Ltac @qualid
+
+ Defined |Ltac| functions can be displayed using this command.
+
+.. cmd:: Print Ltac Signatures
+
+ This command displays a list of all user-defined tactics, with their arguments.
+
+Debugging |Ltac| tactics
+------------------------
+
+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 :cmd:`Info` command can be
+ used with the following syntax.
+
+
+ The number :n:`@num` is the unfolding level of tactics in the trace. At level
+ 0, the trace contains a sequence of tactics in the actual script, at level 1,
+ the trace will be the concatenation of the traces of these tactics, etc…
+
+ .. example::
+
+ .. coqtop:: in reset
+
+ Ltac t x := exists x; reflexivity.
+ Goal exists n, n=0.
+
+ .. coqtop:: all
+
+ Info 0 t 1||t 0.
+
+ .. coqtop:: in
+
+ Undo.
+
+ .. coqtop:: all
+
+ Info 1 t 1||t 0.
+
+ 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 :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
+
+ 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
+ :cmd:`Info` command.
+
+Interactive debugger
+~~~~~~~~~~~~~~~~~~~~
+
+.. opt:: Ltac Debug
+
+ This option governs the step-by-step debugger that comes with the |Ltac| interpreter
+
+When the debugger is activated, it stops at every step of the evaluation of
+the current |Ltac| expression and it prints information on what it is doing.
+The debugger stops, prompting for a command which can be one of the
+following:
+
++-----------------+-----------------------------------------------+
+| simple newline: | go to the next step |
++-----------------+-----------------------------------------------+
+| h: | get help |
++-----------------+-----------------------------------------------+
+| x: | exit current evaluation |
++-----------------+-----------------------------------------------+
+| s: | continue current evaluation without stopping |
++-----------------+-----------------------------------------------+
+| r n: | advance n steps further |
++-----------------+-----------------------------------------------+
+| r string: | advance up to the next call to “idtac string” |
++-----------------+-----------------------------------------------+
+
+A non-interactive mode for the debugger is available via the option:
+
+.. opt:: Ltac Batch Debug
+
+ This option has the effect of presenting a newline at every prompt, when
+ the debugger is on. The debug log thus created, which does not require
+ user input to generate when this option is set, can then be run through
+ external tools such as diff.
+
+Profiling |Ltac| tactics
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is possible to measure the time spent in invocations of primitive
+tactics as well as tactics defined in |Ltac| and their inner
+invocations. The primary use is the development of complex tactics,
+which can sometimes be so slow as to impede interactive usage. The
+reasons for the performence degradation can be intricate, like a slowly
+performing |Ltac| match or a sub-tactic whose performance only
+degrades in certain situations. The profiler generates a call tree and
+indicates the time spent in a tactic depending its calling context. Thus
+it allows to locate the part of a tactic definition that contains the
+performance bug.
+
+.. opt:: Ltac Profiling
+
+ This option enables and disables the profiler.
+
+.. cmd:: Show Ltac Profile
+
+ Prints the profile
+
+ .. cmdv:: Show Ltac Profile @string
+
+ Prints a profile for all tactics that start with :n:`@string`. Append a period
+ (.) to the string if you only want exactly that name.
+
+.. cmd:: Reset Ltac Profile
+
+ Resets the profile, that is, deletes all accumulated information.
+
+ .. warning::
+
+ Backtracking across a :cmd:`Reset Ltac Profile` will not restore the information.
+
+.. coqtop:: reset in
+
+ Require Import Coq.omega.Omega.
+
+ Ltac mytauto := tauto.
+ Ltac tac := intros; repeat split; omega || mytauto.
+
+ Notation max x y := (x + (y - x)) (only parsing).
+
+ Goal forall x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z,
+ max x (max y z) = max (max x y) z /\ max x (max y z) = max (max x y) z
+ /\ (A /\ B /\ C /\ D /\ E /\ F /\ G /\ H /\ I /\ J /\ K /\ L /\ M /\ N /\ O /\ P /\ Q /\ R /\ S /\ T /\ U /\ V /\ W /\ X /\ Y /\ Z
+ -> Z /\ Y /\ X /\ W /\ V /\ U /\ T /\ S /\ R /\ Q /\ P /\ O /\ N /\ M /\ L /\ K /\ J /\ I /\ H /\ G /\ F /\ E /\ D /\ C /\ B /\ A).
+ Proof.
+
+.. coqtop:: all
+
+ Set Ltac Profiling.
+ tac.
+ Show Ltac Profile.
+ Show Ltac Profile "omega".
+
+.. coqtop:: in
+
+ Abort.
+ Unset Ltac Profiling.
+
+.. tacn:: start ltac profiling
+ :name: start ltac profiling
+
+ This tactic behaves like :tacn:`idtac` but enables the profiler.
+
+.. tacn:: stop ltac profiling
+ :name: stop ltac profiling
+
+ Similarly to :tacn:`start ltac profiling`, this tactic behaves like
+ :tacn:`idtac`. Together, they allow you to exclude parts of a proof script
+ from profiling.
+
+.. tacn:: reset ltac profile
+ :name: reset ltac profile
+
+ This tactic behaves like the corresponding vernacular command
+ and allow displaying and resetting the profile from tactic scripts for
+ benchmarking purposes.
+
+.. tacn:: show ltac profile
+ :name: show ltac profile
+
+ This tactic behaves like the corresponding vernacular command
+ and allow displaying and resetting the profile from tactic scripts for
+ benchmarking purposes.
+
+.. tacn:: show ltac profile @string
+ :name: show ltac profile
+
+ This tactic behaves like the corresponding vernacular command
+ and allow displaying and resetting the profile from tactic scripts for
+ benchmarking purposes.
+
+You can also pass the ``-profile-ltac`` command line option to ``coqc``, which
+turns the :opt:`Ltac Profiling` option on at the beginning of each document,
+and performs a :cmd:`Show Ltac Profile` at the end.
+
+.. warning::
+
+ Note that the profiler currently does not handle backtracking into
+ multi-success tactics, and issues a warning to this effect in many cases
+ when such backtracking occurs.
+
+Run-time optimization tactic
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. tacn:: optimize_heap
+ :name: optimize_heap
+
+This tactic behaves like :n:`idtac`, except that running it compacts the
+heap in the OCaml run-time system. It is analogous to the Vernacular
+command :cmd:`Optimize Heap`.
diff --git a/doc/sphinx/proof-engine/proof-handling.rst b/doc/sphinx/proof-engine/proof-handling.rst
index 52cde52c6..069cf8a6d 100644
--- a/doc/sphinx/proof-engine/proof-handling.rst
+++ b/doc/sphinx/proof-engine/proof-handling.rst
@@ -8,176 +8,188 @@
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
having applied some tactics, the list of goals contains the subgoals
generated by the tactics.
-To each subgoal is associated a number of hypotheses called the *local
-context* of the goal. Initially, the local context contains the local
-variables and hypotheses of the current section (see Section :ref:`TODO_gallina_assumptions`)
-and the local variables and hypotheses of the theorem statement. It is
-enriched by the use of certain tactics (see e.g. ``intro`` in Section
-:ref:`managingthelocalcontext`).
+To each subgoal is associated a number of hypotheses called the *local context*
+of the goal. Initially, the local context contains the local variables and
+hypotheses of the current section (see Section :ref:`gallina-assumptions`) and
+the local variables and hypotheses of the theorem statement. It is enriched by
+the use of certain tactics (see e.g. :tacn:`intro`).
When a proof is completed, the message ``Proof completed`` is displayed.
One can then register this proof as a defined constant in the
environment. Because there exists a correspondence between proofs and
-terms of λ-calculus, known as the *Curry-Howard isomorphism* [[How80]_,
-[Bar81]_, [Gir89]_, [Hue88]_ ], |Coq|
-stores proofs as terms of |Cic|. Those terms
-are called *proof terms*.
+terms of λ-calculus, known as the *Curry-Howard isomorphism*
+:cite:`How80,Bar81,Gir89,Hue88`, |Coq| stores proofs as terms of |Cic|. Those
+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:
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:
-
-.. cmd:: Theorem @ident [@binders] : @form.
-
-The list of assertion commands is given in Section :ref:TODO-assertions_and_proof`. The
-command ``Goal`` can also be used.
-
-.. 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).
-
-.. cmd:: Qed.
-
-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.
-
-
-.. exn:: Attempt to save an incomplete proof
+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 :ref:`Assertions`. The command
+:cmd:`Goal` can also be used.
-.. note::
+.. cmd:: Goal @form
- Sometimes an error occurs when building the proof term, because
- tactics do not enforce completely the term construction
- constraints.
+ 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).
-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.
+.. cmd:: Qed
+ :name: Qed (interactive proof)
-.. cmdv:: Defined.
+ 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.
-Defines the proved term as a transparent constant.
+ .. exn:: Attempt to save an incomplete proof.
-.. cmdv:: Save @ident.
+ .. note::
-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.
+ 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.
-.. cmd:: Admitted.
+ .. cmdv:: Defined
+ :name: Defined (interactive proof)
-This command is available in interactive editing proof mode to give up
-the current proof and declare the initial goal as an axiom.
+ Defines the proved term as a transparent constant.
+ .. cmdv:: Save @ident
+ :name: Save
-.. cmd:: Proof @term.
+ 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.
-This command applies in proof editing mode. It is equivalent to
+.. cmd:: Admitted
+ :name: Admitted (interactive proof)
-.. cmd:: exact @term. Qed.
+ This command is available in interactive editing mode to give up
+ the current proof and declare the initial goal as an axiom.
-That is, you have to give the full proof in one gulp, as a
-proof term (see Section :ref:`applyingtheorems`).
+.. cmd:: Abort
+ 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.
-.. cmdv:: Proof.
+ .. exn:: No focused proof (No proof-editing in progress).
-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``.
+ .. cmdv:: Abort @ident
+ Aborts the editing of the proof named :token:`ident` (in case you have
+ nested proofs).
-See also: ``Proof with tactic.`` in Section
-:ref:`setimpautotactics`.
+ .. 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:`TODO-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
+ :name: Proof (interactive 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:`setimpautotactics`.
+.. 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
@@ -186,176 +198,151 @@ Proof using options
The following options modify the behavior of ``Proof using``.
-.. cmdv:: Set 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``.
-.. cmdv:: Set Suggest Proof Using.
+.. opt:: Suggest Proof Using
-When ``Qed`` is performed, suggest a using annotation if the user did not
-provide one.
+ When :cmd:`Qed` is performed, suggest a ``using`` annotation if the user did not
+ provide one.
.. _`nameaset`:
Name a set of section hypotheses for ``Proof using``
````````````````````````````````````````````````````
-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".
+.. 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.
-.. cmdv:: Collection Many := Fewer - (x y).
+ .. example::
-Define the collection named "Many" containing the set difference of
-"Fewer" and the unnamed collection ``x`` ``y``.
+ Define the collection named ``Some`` containing ``x``, ``y`` and ``z``::
+ Collection Some := x y z.
-.. cmd:: Abort.
+ Define the collection named ``Fewer`` containing only ``x`` and ``y``::
-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.
+ Collection Fewer := Some - z
+ Define the collection named ``Many`` containing the set union or set
+ difference of ``Fewer`` and ``Some``::
-.. exn:: No focused proof (No proof-editing in progress)
+ Collection Many := Fewer + Some
+ Collection Many := Fewer - Some
+ Define the collection named ``Many`` containing the set difference of
+ ``Fewer`` and the unnamed collection ``x y``::
+ Collection Many := Fewer - (x y)
-.. cmdv:: Abort @ident.
-Aborts the editing of the proof named :n:`@ident`.
-.. cmdv:: Abort All.
+.. cmd:: Existential @num := @term
-Aborts all current goals, switching back to the |Coq|
-toplevel.
+ 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 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
-.. cmd:: Existential @num := @term.
-
-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 instantiate.
-
-
-See also: ``instantiate (num:= term).`` in Section
-:ref:`TODO-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
+ :name: Restart
-.. cmdv:: 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.
+.. cmd:: Focus
-.. exn:: No focused proof to restart
+ 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.
+ .. deprecated:: 8.8
-.. cmd:: Focus.
+ Prefer the use of bullets or focusing brackets (see below).
-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.
+.. cmdv:: Focus @num
+ This focuses the attention on the :token:`num` th subgoal to prove.
-.. cmdv:: Focus @num.
+ .. deprecated:: 8.8
-This focuses the attention on the :n:`@num` th subgoal to
-prove.
+ Prefer the use of focusing brackets with a goal selector (see below).
-*This command is deprecated since 8.8*: prefer the use of bullets or
-focusing brackets instead, including :n:`@num : %{`
+.. cmd:: Unfocus
-.. cmd:: Unfocus.
+ This command restores to focus the goal that were suspended by the
+ last :cmd:`Focus` command.
-This command restores to focus the goal that were suspended by the
-last ``Focus`` command.
+ .. deprecated:: 8.8
-*This command is deprecated since 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
+ .. 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:
Bullets
```````
@@ -404,152 +391,156 @@ 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:
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:`exvariables`) 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`
+
+ .. example::
+ .. coqtop:: all
- Show Match nat.
+ Show Match nat.
-.. exn:: Unknown inductive type
+ .. exn:: Unknown inductive type.
-.. exn:: 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. 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
------------------------------------------------
-.. opt:: Hyps Limit @num.
+.. 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
@@ -558,17 +549,16 @@ When unset, it goes back to the default mode which is to print all
available hypotheses.
-.. opt:: Automatic Introduction.
+.. 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
+option is on, which is the default, binders are automatically put in
the local context of the goal to prove.
-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 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.
Controlling memory usage
@@ -578,15 +568,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.
-.. 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 ``optimize_heap`` (see~:ref:`tactic-optimizeheap`)
+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 bd71e5ed8..63cd0f3ea 100644
--- a/doc/sphinx/proof-engine/ssreflect-proof-language.rst
+++ b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
@@ -6,10 +6,7 @@
The |SSR| proof language
------------------------------
-:Source: https://coq.inria.fr/distrib/current/refman/ssreflect.html
-:Converted by: Enrico Tassi
-
-Author: Georges Gonthier, Assia Mahboubi, Enrico Tassi
+:Authors: Georges Gonthier, Assia Mahboubi, Enrico Tassi
Introduction
@@ -426,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
@@ -496,7 +493,10 @@ inferred from the whole context of the goal (see for example section
Definitions
~~~~~~~~~~~
-The pose tactic allows to add a defined constant to a proof context.
+.. tacn:: pose
+ :name: pose (ssreflect)
+
+This tactic allows to add a defined constant to a proof context.
|SSR| generalizes this tactic in several ways. In particular, the
|SSR| pose tactic supports *open syntax*: the body of the
definition does not need surrounding parentheses. For instance:
@@ -1352,6 +1352,7 @@ Discharge
The general syntax of the discharging tactical ``:`` is:
.. tacn:: @tactic {? @ident } : {+ @d_item } {? @clear_switch }
+ :name: ... : ... (ssreflect)
.. prodn::
d_item ::= {? @occ_switch %| @clear_switch } @term
@@ -1503,9 +1504,11 @@ side of an equation.
The abstract tactic
```````````````````
-The ``abstract`` tactic assigns an ``abstract`` constant previously
-introduced with the ``[: name ]`` intro pattern
-(see section :ref:`introduction_ssr`).
+.. tacn:: abstract: {+ d_item}
+ :name abstract (ssreflect)
+
+This tactic assigns an abstract constant previously introduced with the ``[:
+name ]`` intro pattern (see section :ref:`introduction_ssr`).
In a goal like the following::
@@ -1812,6 +1815,8 @@ of a :token:`d_item` immediately following this ``/`` switch,
using the syntax:
.. tacv:: case: {+ @d_item } / {+ @d_item }
+ :name: case (ssreflect)
+
.. tacv:: elim: {+ @d_item } / {+ @d_item }
The :token:`d_item` on the right side of the ``/`` switch are discharged as
@@ -2135,7 +2140,7 @@ tactic using the given second tactic, and fails if it does not succeed.
Its analogue
.. tacn:: @tactic ; first by @tactic
- :name: first
+ :name: first (ssreflect)
tries to solve the first subgoal generated by the first tactic using the
second given tactic, and fails if it does not succeed.
@@ -2152,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
@@ -2163,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
@@ -2215,7 +2220,7 @@ Iteration
thanks to the do tactical, whose general syntax is:
.. tacn:: do {? @mult } ( @tactic | [ {+| @tactic } ] )
- :name: do
+ :name: do (ssreflect)
where :token:`mult` is a *multiplier*.
@@ -2752,12 +2757,9 @@ type classes inference.
No inference for ``t``. Unresolved instances are
quantified in the (inferred) type of ``t`` and abstracted in ``t``.
+.. opt:: SsrHave NoTCResolution
-The behavior of |SSR| 1.4 and below (never resolve type classes)
-can be restored with the option
-
-.. cmd:: Set SsrHave NoTCResolution.
-
+ This option restores the behavior of |SSR| 1.4 and below (never resolve type classes).
Variants: the suff and wlog tactics
```````````````````````````````````
@@ -3730,6 +3732,7 @@ We provide a special tactic unlock for unfolding such definitions
while removing “locks”, e.g., the tactic:
.. tacn:: unlock {? @occ_switch } @ident
+ :name: unlock
replaces the occurrence(s) of :token:`ident` coded by the
:token:`occ_switch` with the corresponding body.
@@ -5188,6 +5191,7 @@ equivalences are indeed taken into account, otherwise only single
|SSR| proposes an extension of the Search command. Its syntax is:
.. cmd:: Search {? @pattern } {* {? - } %( @string %| @pattern %) {? % @ident} } {? in {+ {? - } @qualid } }
+ :name: Search (ssreflect)
where :token:`qualid` is the name of an open module. This command returns
the list of lemmas:
@@ -5318,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 2af73c28e..0318bddde 100644
--- a/doc/sphinx/proof-engine/tactics.rst
+++ b/doc/sphinx/proof-engine/tactics.rst
@@ -24,7 +24,7 @@ Each (sub)goal is denoted with a number. The current goal is numbered
1. By default, a tactic is applied to the current goal, but one can
address a particular goal in the list by writing n:tactic which means
“apply tactic tactic to goal number n”. We can show the list of
-subgoals by typing Show (see Section :ref:`TODO-7.3.1-Show`).
+subgoals by typing Show (see Section :ref:`requestinginformation`).
Since not every rule applies to a given statement, every tactic cannot
be used to reduce any goal. In other words, before applying a tactic
@@ -34,15 +34,16 @@ satisfied. If it is not the case, the tactic raises an error message.
Tactics are built from atomic tactics and tactic expressions (which
extends the folklore notion of tactical) to combine those atomic
tactics. This chapter is devoted to atomic tactics. The tactic
-language will be described in Chapter :ref:`TODO-9-Thetacticlanguage`.
+language will be described in Chapter :ref:`ltac`.
+
+.. _invocation-of-tactics:
Invocation of tactics
-------------------------
A tactic is applied as an ordinary command. It may be preceded by a
-goal selector (see Section :ref:`TODO-9.2-Semantics`). If no selector is
-specified, the default selector (see Section
-:ref:`TODO-8.1.1-Setdefaultgoalselector`) is used.
+goal selector (see Section :ref:`ltac-semantics`). If no selector is
+specified, the default selector is used.
.. _tactic_invocation_grammar:
@@ -50,20 +51,22 @@ specified, the default selector (see Section
tactic_invocation : toplevel_selector : tactic.
: |tactic .
-.. cmd:: Set Default Goal Selector @toplevel_selector.
+.. opt:: Default Goal Selector @toplevel_selector
+
+ This option controls the default selector, used when no selector is
+ specified when applying a tactic. The initial value is 1, hence the
+ tactics are, by default, applied to the first goal.
-After using this command, the default selector – used when no selector
-is specified when applying a tactic – is set to the chosen value. The
-initial value is 1, hence the tactics are, by default, applied to the
-first goal. Using Set Default Goal Selector ‘‘all’’ will make is so
-that tactics are, by default, applied to every goal simultaneously.
-Then, to apply a tactic tac to the first goal only, you can write
-1:tac. Although more selectors are available, only ‘‘all’’ or a single
-natural number are valid default goal selectors.
+ Using value ``all`` will make it so that tactics are, by default,
+ applied to every goal simultaneously. Then, to apply a tactic tac
+ to the first goal only, you can write ``1:tac``.
-.. cmd:: Test Default Goal Selector.
+ Using value ``!`` enforces that all tactics are used either on a
+ single focused goal or with a local selector (’’strict focusing
+ mode’’).
-This command displays the current default selector.
+ Although more selectors are available, only ``all``, ``!`` or a
+ single natural number are valid default goal selectors.
.. _bindingslist:
@@ -89,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:`TODO-9-Thetacticlanguage`) 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.
@@ -122,14 +125,12 @@ following syntax:
The role of an occurrence clause is to select a set of occurrences of a term in
a goal. In the first case, the :n:`@ident {? at {* num}}` parts indicate that
-occurrences have to be selected in the hypotheses named :n:`@ident`. If no numbers
-are given for hypothesis :n:`@ident`, then all the occurrences of `term` in the
-hypothesis are selected. If numbers are given, they refer to occurrences of
-`term` when the term is printed using option ``Set Printing All`` (see
-:ref:`TODO-2.9-Printingconstructionsinfull`), counting from left to right. In
-particular, occurrences of `term` in implicit arguments (see
-:ref:`TODO-2.7-Implicitarguments`) or coercions (see :ref:`TODO-2.8-Coercions`)
-are counted.
+occurrences have to be selected in the hypotheses named :n:`@ident`. If no
+numbers are given for hypothesis :n:`@ident`, then all the occurrences of `term`
+in the hypothesis are selected. If numbers are given, they refer to occurrences
+of `term` when the term is printed using option :opt:`Printing All`, counting
+from left to right. In particular, occurrences of `term` in implicit arguments
+(see :ref:`ImplicitArguments`) or coercions (see :ref:`Coercions`) are counted.
If a minus sign is given between at and the list of occurrences, it
negates the condition so that the clause denotes all the occurrences
@@ -150,14 +151,15 @@ 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:`TODO-8.3.7-Managingthelocalcontext`,
-:ref:`TODO-8.5.2-Caseanalysisandinduction`,
-:ref:`TODO-2.9-Printingconstructionsinfull`.
+See also: :ref:`Managingthelocalcontext`,
+:ref:`caseanalysisandinduction`,
+:ref:`printing_constructions_full`.
+.. _applyingtheorems:
Applying theorems
---------------------
@@ -165,195 +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:`TODO-4.3-Conversionrules`).
+ 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.
+ .. 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
+ .. 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
+ .. 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
+ .. 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
-:ref:`change <change_term>` 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:
-.. cmd:: 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:`TODO-2.11-ExistentialVariables`). 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.
+ .. 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}}
+ .. 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``:
@@ -435,7 +445,7 @@ sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
``forall A, ... -> A``. Excluding this kind of lemma can be avoided by
setting the following option:
-.. opt:: Set Universal Lemma Under Conjunction.
+.. opt:: Universal Lemma Under Conjunction
This option, which preserves compatibility with versions of Coq prior to
8.4 is also available for :n:`apply @term in @ident` (see :tacn:`apply ... in`).
@@ -493,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
@@ -501,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
@@ -539,14 +549,16 @@ sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
The terms in the @bindings_list are checked in the context where constructor is executed and not in the context where @apply is executed (the introductions are not taken into account).
.. tacv:: split
+ :name: split
This applies only if :g:`I` has a single constructor. It is then
equivalent to :n:`constructor 1.`. It is typically used in the case of a
conjunction :g:`A` :math:`\wedge` :g:`B`.
-.. exn:: Not an inductive goal with 1 constructor.
+.. exn:: Not an inductive goal with 1 constructor
.. tacv:: exists @val
+ :name: exists
This applies only if :g:`I` has a single constructor. It is then equivalent
to :n:`intros; constructor 1 with @bindings_list.` It is typically used in
@@ -559,7 +571,10 @@ sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
This iteratively applies :n:`exists @bindings_list`.
.. tacv:: left
+ :name: left
+
.. tacv:: right
+ :name: right
These tactics apply only if :g:`I` has two constructors, for
instance in the case of a disjunction :g:`A` :math:`\vee` :g:`B`.
@@ -577,15 +592,25 @@ sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
for the appropriate ``i``.
.. tacv:: econstructor
+ :name: econstructor
+
.. tacv:: eexists
+ :name: eexists
+
.. tacv:: esplit
+ :name: esplit
+
.. tacv:: eleft
+ :name: eleft
+
.. tacv:: eright
+ :name: eright
- These tactics and their variants behave like ``constructor``, ``exists``,
- ``split``, ``left``, ``right`` and their variants but they introduce
- existential variables instead of failing when the instantiation of a
- variable cannot be found (cf. :tacn:`eapply` and :tacn:`apply`).
+ These tactics and their variants behave like :tacn:`constructor`,
+ :tacn:`exists`, :tacn:`split`, :tacn:`left`, :tacn:`right` and their variants
+ but they introduce existential variables instead of failing when the
+ instantiation of a variable cannot be found (cf. :tacn:`eapply` and
+ :tacn:`apply`).
.. _managingthelocalcontext:
@@ -598,27 +623,32 @@ Managing the local context
This tactic applies to a goal that is either a product or starts with a let
binder. If the goal is a product, the tactic implements the "Lam" rule given in
-:ref:`TODO-4.2-Typing-rules` [1]_. If the goal starts with a let binder, then the
+: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.
.. exn:: No product even after head-reduction.
-.. exn:: ident is already used.
+.. 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.
@@ -628,18 +658,18 @@ be applied or the goal is not head-reducible.
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
- (see :ref:`TODO-2.6.2-Qualified-names`).
+ (see :ref:`Qualified-names`).
.. tacv:: intros {+ @ident}.
This is equivalent to the composed tactic
:n:`intro @ident; ... ; intro @ident`. More generally, the ``intros`` tactic
takes a pattern as argument in order to introduce names for components
of an inductive definition or to clear introduced hypotheses. This is
- explained in :ref:`TODO-8.3.2`.
+ explained in :ref:`Managingthelocalcontext`.
.. tacv:: intros until @ident
@@ -647,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
@@ -676,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
@@ -685,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 ...
@@ -730,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`:
@@ -827,15 +857,10 @@ quantification or an implication.
so that all the arguments of the i-th constructors of the corresponding
inductive type are introduced can be controlled with the following option:
- .. cmd:: Set Bracketing Last Introduction Pattern.
-
- Force completion, if needed, when the last introduction pattern is a
- disjunctive or conjunctive pattern (this is the default).
-
- .. cmd:: Unset Bracketing Last Introduction Pattern.
+ .. opt:: Bracketing Last Introduction Pattern
- Deactivate completion when the last introduction pattern is a disjunctive or
- conjunctive pattern.
+ Force completion, if needed, when the last introduction pattern is a
+ disjunctive or conjunctive pattern (on by default).
.. tacn:: clear @ident
:name: clear
@@ -855,11 +880,12 @@ quantification or an implication.
This is equivalent to :n:`clear @ident. ... clear @ident.`
.. tacv:: clearbody @ident
+ :name: clearbody
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}
@@ -876,7 +902,7 @@ quantification or an implication.
it.
.. tacn:: revert {+ @ident}
- :name: revert ...
+ :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
@@ -892,7 +918,7 @@ the inverse of :tacn:`intro`.
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
@@ -926,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
@@ -955,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
@@ -968,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
@@ -992,6 +1018,7 @@ The name of the hypothesis in the proof-term, however, is left unchanged.
.. tacv:: eset (@ident {+ @binder} := @term ) in @goal_occurrences
.. tacv:: eset @term in @goal_occurrences
+ :name: eset
While the different variants of :tacn:`set` expect that no existential
variables are generated by the tactic, :n:`eset` removes this constraint. In
@@ -999,6 +1026,7 @@ The name of the hypothesis in the proof-term, however, is left unchanged.
:tacn:`epose`, i.e. when the :`@term` does not occur in the goal.
.. tacv:: remember @term as @ident
+ :name: remember
This behaves as :n:`set (@ident:= @term ) in *` and using a logical
(Leibniz’s) equality instead of a local definition.
@@ -1016,6 +1044,8 @@ The name of the hypothesis in the proof-term, however, is left unchanged.
.. tacv:: eremember @term as @ident
.. tacv:: eremember @term as @ident in @goal_occurrences
.. tacv:: eremember @term as @ident eqn:@ident
+ :name: eremember
+
While the different variants of :n:`remember` expect that no existential
variables are generated by the tactic, :n:`eremember` removes this constraint.
@@ -1067,7 +1097,7 @@ The name of the hypothesis in the proof-term, however, is left unchanged.
This decomposes record types (inductive types with one constructor, like
"and" and "exists" and those defined with the Record macro, see
- :ref:`TODO-2.1`).
+ :ref:`record-types`).
.. _controllingtheproofflow:
@@ -1082,14 +1112,14 @@ 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`.
.. tacv:: assert form
- This behaves as :n:`assert (@ident : form ) but :n:`@ident` is generated by
+ This behaves as :n:`assert (@ident : form)` but :n:`@ident` is generated by
Coq.
.. tacv:: assert form by tactic
@@ -1097,7 +1127,8 @@ Controlling the proof flow
This tactic behaves like :n:`assert` but applies tactic to solve the subgoals
generated by assert.
- .. exn:: Proof is not complete
+ .. exn:: Proof is not complete.
+ :name: Proof is not complete. (assert)
.. tacv:: assert form as intro_pattern
@@ -1118,9 +1149,10 @@ 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
.. tacv:: assert (@ident := @term)
@@ -1130,6 +1162,7 @@ Controlling the proof flow
to prove it.
.. tacv:: pose proof @term {? as intro_pattern}
+ :name: pose proof
This tactic behaves like :n:`assert T {? as intro_pattern} by exact @term`
where :g:`T` is the type of :g:`term`. In particular,
@@ -1143,6 +1176,7 @@ Controlling the proof flow
the tactic, :n:`epose proof` removes this constraint.
.. tacv:: enough (@ident : form)
+ :name: enough
This adds a new hypothesis of name :n:`@ident` asserting :n:`form` to the
goal the tactic :n:`enough` is applied to. A new subgoal stating :n:`form` is
@@ -1168,22 +1202,27 @@ Controlling the proof flow
applied to all of them.
.. tacv:: eenough (@ident : form) by tactic
+ :name: eenough
+
.. tacv:: eenough form by tactic
+
.. tacv:: eenough form as intro_pattern by tactic
While the different variants of :n:`enough` expect that no existential
variables are generated by the tactic, :n:`eenough` removes this constraint.
-.. tacv:: cut form
+.. tacv:: cut @form
+ :name: cut
This tactic applies to any goal. It implements the non-dependent case of
- the “App” rule given in :ref:`TODO-4.2`. (This is Modus Ponens inference
+ the “App” rule given in :ref:`typing-rules`. (This is Modus Ponens inference
rule.) :n:`cut U` transforms the current goal :g:`T` into the two following
subgoals: :g:`U -> T` and :g:`U`. The subgoal :g:`U -> T` comes first in the
list of remaining subgoal to prove.
.. tacv:: specialize (ident {* @term}) {? as intro_pattern}
.. tacv:: specialize ident with @bindings_list {? as intro_pattern}
+ :name: specialize
The tactic :n:`specialize` works on local hypothesis :n:`@ident`. The
premises of this hypothesis (either universal quantifications or
@@ -1202,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
@@ -1236,7 +1275,7 @@ name of the variable (here :g:`n`) is chosen based on :g:`T`.
This is equivalent to :n:`generalize @term` but it generalizes only over the
specified occurrences of :n:`@term` (counting from left to right on the
- expression printed using option :g:`Set Printing All`).
+ expression printed using option :opt:`Printing All`).
.. tacv:: generalize @term as @ident
@@ -1268,7 +1307,7 @@ name of the variable (here :g:`n`) is chosen based on :g:`T`.
:n:`refine @term` (preferred alternative).
.. note:: To be able to refer to an existential variable by name, the user
- must have given the name explicitly (see :ref:`TODO-2.11`).
+ must have given the name explicitly (see :ref:`Existential-Variables`).
.. note:: When you are referring to hypotheses which you did not name
explicitly, be aware that Coq may make a different decision on how to
@@ -1327,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
@@ -1353,11 +1392,13 @@ goals cannot be closed with :g:`Qed` but only with :g:`Admitted`.
then required to prove that False is indeed provable in the current
context. This tactic is a macro for :n:`elimtype False`.
+.. _CaseAnalysisAndInduction:
+
Case analysis and induction
-------------------------------
The tactics presented in this section implement induction or case
-analysis on inductive or co-inductive objects (see :ref:`TODO-4.5`).
+analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`).
.. tacn:: destruct @term
:name: destruct
@@ -1423,6 +1464,7 @@ analysis on inductive or co-inductive objects (see :ref:`TODO-4.5`).
dependent premises of the type of :n:`@term` (see :ref:`syntax of bindings <bindingslist>`).
.. tacv:: edestruct @term
+ :name: edestruct
This tactic behaves like :n:`destruct @term` except that it does not fail if
the instance of a dependent premises of the type of :n:`@term` is not
@@ -1449,6 +1491,7 @@ analysis on inductive or co-inductive objects (see :ref:`TODO-4.5`).
the effects of the `with`, `as`, `eqn:`, `using`, and `in` clauses.
.. tacv:: case term
+ :name: case
The tactic :n:`case` is a more basic tactic to perform case analysis without
recursion. It behaves as :n:`elim @term` but using a case-analysis
@@ -1458,14 +1501,15 @@ analysis on inductive or co-inductive objects (see :ref:`TODO-4.5`).
Analogous to :n:`elim @term with @bindings_list` above.
-.. tacv:: ecase @term
-.. tacv:: ecase @term with @bindings_list
+.. tacv:: ecase @term {? with @bindings_list }
+ :name: ecase
In case the type of :n:`@term` has dependent premises, or dependent premises
whose values are not inferable from the :n:`with @bindings_list` clause,
:n:`ecase` turns them into existential variables to be resolved later on.
.. tacv:: simple destruct @ident
+ :name: simple destruct
This tactic behaves as :n:`intros until @ident; case @ident` when :n:`@ident`
is a quantified variable of the goal.
@@ -1528,9 +1572,9 @@ analysis on inductive or co-inductive objects (see :ref:`TODO-4.5`).
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.
@@ -1556,6 +1600,7 @@ analysis on inductive or co-inductive objects (see :ref:`TODO-4.5`).
premises of the type of :n:`term` (see :ref:`bindings list <bindingslist>`).
.. tacv:: einduction @term
+ :name: einduction
This tactic behaves like :tacn:`induction` except that it does not fail if
some dependent premise of the type of :n:`@term` is not inferable. Instead,
@@ -1628,6 +1673,7 @@ analysis on inductive or co-inductive objects (see :ref:`TODO-4.5`).
(see :ref:`bindings list <bindingslist>`).
.. tacv:: eelim @term
+ :name: eelim
In case the type of :n:`@term` has dependent premises, this turns them into
existential variables to be resolved later on.
@@ -1646,7 +1692,8 @@ analysis on inductive or co-inductive objects (see :ref:`TODO-4.5`).
These are the most general forms of ``elim`` and ``eelim``. It combines the
effects of the ``using`` clause and of the two uses of the ``with`` clause.
-.. tacv:: elimtype form
+.. tacv:: elimtype @form
+ :name: elimtype
The argument :n:`form` must be inductively defined. :n:`elimtype I` is
equivalent to :n:`cut I. intro Hn; elim Hn; clear Hn.` Therefore the
@@ -1656,6 +1703,7 @@ analysis on inductive or co-inductive objects (see :ref:`TODO-4.5`).
:n:`elimtype I; 2:exact t.`
.. tacv:: simple induction @ident
+ :name: simple induction
This tactic behaves as :n:`intros until @ident; elim @ident` when
:n:`@ident` is a quantified variable of the goal.
@@ -1740,13 +1788,14 @@ analysis on inductive or co-inductive objects (see :ref:`TODO-4.5`).
other ones need not be further generalized.
.. tacv:: dependent destruction @ident
+ :name: dependent destruction
This performs the generalization of the instance :n:`@ident` but uses
``destruct`` instead of induction on the generalized hypothesis. This gives
results equivalent to ``inversion`` or ``dependent inversion`` if the
hypothesis is dependent.
-See also :ref:`TODO-10.1-dependentinduction` for a larger example of ``dependent induction``
+See also the larger example of :tacn:`dependent induction`
and an explanation of the underlying technique.
.. tacn:: function induction (@qualid {+ @term})
@@ -1754,8 +1803,8 @@ and an explanation of the underlying technique.
The tactic functional induction performs case analysis and induction
following the definition of a function. It makes use of a principle
- generated by ``Function`` (see :ref:`TODO-2.3-Advancedrecursivefunctions`) or
- ``Functional Scheme`` (see :ref:`TODO-13.2-Generationofinductionschemeswithfunctionalscheme`).
+ generated by ``Function`` (see :ref:`advanced-recursive-functions`) or
+ ``Functional Scheme`` (see :ref:`functional-scheme`).
Note that this tactic is only available after a
.. example::
@@ -1781,26 +1830,26 @@ and an explanation of the underlying technique.
:n:`functional induction (f x1 x2 x3)` is actually a wrapper for
:n:`induction x1, x2, x3, (f x1 x2 x3) using @qualid` followed by a cleaning
phase, where :n:`@qualid` is the induction principle registered for :g:`f`
- (by the ``Function`` (see :ref:`TODO-2.3-Advancedrecursivefunctions`) or
- ``Functional Scheme`` (see :ref:`TODO-13.2-Generationofinductionschemeswithfunctionalscheme`)
+ (by the ``Function`` (see :ref:`advanced-recursive-functions`) or
+ ``Functional Scheme`` (see :ref:`functional-scheme`)
command) corresponding to the sort of the goal. Therefore
``functional induction`` may fail if the induction scheme :n:`@qualid` is not
- defined. See also :ref:`TODO-2.3-Advancedrecursivefunctions` for the function
+ defined. See also :ref:`advanced-recursive-functions` for the function
terms accepted by ``Function``.
.. note::
There is a difference between obtaining an induction scheme
- for a function by using :g:`Function` (see :ref:`TODO-2.3-Advancedrecursivefunctions`)
+ for a function by using :g:`Function` (see :ref:`advanced-recursive-functions`)
and by using :g:`Functional Scheme` after a normal definition using
- :g:`Fixpoint` or :g:`Definition`. See :ref:`TODO-2.3-Advancedrecursivefunctions`
+ :g:`Fixpoint` or :g:`Definition`. See :ref:`advanced-recursive-functions`
for details.
-See also: :ref:`TODO-2.3-Advancedrecursivefunctions`
- :ref:`TODO-13.2-Generationofinductionschemeswithfunctionalscheme`
+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
@@ -1833,8 +1882,8 @@ See also: :ref:`TODO-2.3-Advancedrecursivefunctions`
: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
@@ -1849,6 +1898,7 @@ See also: :ref:`TODO-2.3-Advancedrecursivefunctions`
.. tacv:: ediscriminate @num
.. tacv:: ediscriminate @term {? with @bindings_list}
+ :name: ediscriminate
This works the same as ``discriminate`` but if the type of :n:`@term`, or the
type of the hypothesis referred to by :n:`@num`, has uninstantiated
@@ -1861,7 +1911,7 @@ See also: :ref:`TODO-2.3-Advancedrecursivefunctions`
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
@@ -1872,7 +1922,7 @@ See also: :ref:`TODO-2.3-Advancedrecursivefunctions`
: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
@@ -1882,90 +1932,96 @@ See also: :ref:`TODO-2.3-Advancedrecursivefunctions`
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:`TODO-13.1-GenerationofinductionprincipleswithScheme`),
-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}
+ 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.
-It is possible to 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). To obtain this
-behavior, the option ``Set Structural Injection`` must be activated. This
-option is off by default.
+ .. 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.
+
+ .. opt:: Keep Proof Equalities
-By default, ``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 behavior can be
-turned off by setting the option ``Set 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.
.. tacn:: inversion @ident
:name: inversion
@@ -1984,15 +2040,15 @@ turned off by setting the option ``Set Keep Proof Equalities``.
.. note::
As ``inversion`` proofs may be large in size, we recommend the
user to stock the lemmas whenever the same instance needs to be
- inverted several times. See :ref:`TODO-13.3-Generationofinversionprincipleswithderiveinversion`.
+ inverted several times. See :ref:`derive-inversion`.
.. note::
Part of the behavior of the ``inversion`` tactic is to generate
equalities between expressions that appeared in the hypothesis that is
being processed. By default, no equalities are generated if they
relate two proofs (i.e. equalities between :n:`@terms` whose type is in sort
- :g:`Prop`). This behavior can be turned off by using the option ``Set Keep
- Proof Equalities``.
+ :g:`Prop`). This behavior can be turned off by using the option
+ :opt`Keep Proof Equalities`.
.. tacv:: inversion @num
@@ -2093,13 +2149,13 @@ turned off by setting the option ``Set Keep Proof Equalities``.
: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
@@ -2108,7 +2164,7 @@ turned off by setting the option ``Set Keep Proof Equalities``.
.. 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
@@ -2117,6 +2173,7 @@ turned off by setting the option ``Set Keep Proof Equalities``.
:n:`dependent inversion_clear @ident with @term`.
.. tacv:: simple inversion @ident
+ :name: simple inversion
It is a very primitive inversion tactic that derives all the necessary
equalities but it does not simplify the constraints as ``inversion`` does.
@@ -2300,7 +2357,7 @@ turned off by setting the option ``Set Keep Proof Equalities``.
arguments are correct is done only at the time of registering the
lemma in the environment. To know if the use of induction hypotheses
is correct at some time of the interactive development of a proof, use
- the command ``Guarded`` (see :ref:`TODO-7.3.2-Guarded`).
+ the command ``Guarded`` (see Section :ref:`requestinginformation`).
.. tacv:: fix @ident @num with {+ (ident {+ @binder} [{struct @ident}] : @type)}
@@ -2321,7 +2378,7 @@ turned off by setting the option ``Set Keep Proof Equalities``.
done only at the time of registering the lemma in the environment. To
know if the use of coinduction hypotheses is correct at some time of
the interactive development of a proof, use the command ``Guarded``
- (see :ref:`TODO-7.3.2-Guarded`).
+ (see Section :ref:`requestinginformation`).
.. tacv:: cofix @ident with {+ (@ident {+ @binder} : @type)}
@@ -2335,7 +2392,7 @@ Rewriting expressions
---------------------
These tactics use the equality :g:`eq:forall A:Type, A->A->Prop` defined in
-file ``Logic.v`` (see :ref:`TODO-3.1.2-Logic`). The notation for :g:`eq T t u` is
+file ``Logic.v`` (see :ref:`coq-library-logic`). The notation for :g:`eq T t u` is
simply :g:`t=u` dropping the implicit type of :g:`t` and :g:`u`.
.. tacn:: rewrite @term
@@ -2354,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.
@@ -2378,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.
@@ -2417,6 +2474,7 @@ subgoals.
leading to failure if these n rewrites are not possible.
.. tacv:: erewrite @term
+ :name: erewrite
This tactic works as :n:`rewrite @term` but turning
unresolved bindings into existential variables, if any, instead of
@@ -2431,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
@@ -2463,6 +2521,7 @@ subgoals.
clause argument must not contain any type of nor value of.
.. tacv:: cutrewrite <- (@term = @term)
+ :cutrewrite:
This tactic is deprecated. It acts like :n:`replace @term with @term`, or,
equivalently as :n:`enough (@term = @term) as <-`.
@@ -2506,30 +2565,30 @@ unfolded and cleared.
context for which an equality of the form :n:`@ident = t` or :n:`t = @ident`
or :n:`@ident := t` exists, with :n:`@ident` not occurring in `t`.
- .. note::
- The behavior of subst can be controlled using option ``Set Regular Subst
- Tactic.`` When this option is activated, subst also deals with the
- following corner cases:
+ .. opt:: Regular Subst Tactic
- + A context with ordered hypotheses :n:`@ident`:sub:`1` :n:`= @ident`:sub:`2`
- and :n:`@ident`:sub:`1` :n:`= t`, or :n:`t′ = @ident`:sub:`1`` with `t′` not
- a variable, and no other hypotheses of the form :n:`@ident`:sub:`2` :n:`= u`
- or :n:`u = @ident`:sub:`2`; without the option, a second call to
- subst would be necessary to replace :n:`@ident`:sub:`2` by `t` or
- `t′` respectively.
- + The presence of a recursive equation which without the option would
- be a cause of failure of :tacn:`subst`.
- + A context with cyclic dependencies as with hypotheses :n:`@ident`:sub:`1` :n:`= f @ident`:sub:`2`
- and :n:`@ident`:sub:`2` :n:`= g @ident`:sub:`1` which without the
- option would be a cause of failure of :tacn:`subst`.
+ This option controls the behavior of :tacn:`subst`. When it is
+ activated, :tacn:`subst` also deals with the following corner cases:
- Additionally, it prevents a local definition such as :n:`@ident := t` to be
- unfolded which otherwise it would exceptionally unfold in configurations
- containing hypotheses of the form :n:`@ident = u`, or :n:`u′ = @ident`
- with `u′` not a variable. Finally, it preserves the initial order of
- hypotheses, which without the option it may break. The option is on by
- default.
+ + A context with ordered hypotheses :n:`@ident`:sub:`1` :n:`= @ident`:sub:`2`
+ and :n:`@ident`:sub:`1` :n:`= t`, or :n:`t′ = @ident`:sub:`1`` with `t′` not
+ a variable, and no other hypotheses of the form :n:`@ident`:sub:`2` :n:`= u`
+ or :n:`u = @ident`:sub:`2`; without the option, a second call to
+ subst would be necessary to replace :n:`@ident`:sub:`2` by `t` or
+ `t′` respectively.
+ + The presence of a recursive equation which without the option would
+ be a cause of failure of :tacn:`subst`.
+ + A context with cyclic dependencies as with hypotheses :n:`@ident`:sub:`1` :n:`= f @ident`:sub:`2`
+ and :n:`@ident`:sub:`2` :n:`= g @ident`:sub:`1` which without the
+ option would be a cause of failure of :tacn:`subst`.
+
+ Additionally, it prevents a local definition such as :n:`@ident := t` to be
+ unfolded which otherwise it would exceptionally unfold in configurations
+ containing hypotheses of the form :n:`@ident = u`, or :n:`u′ = @ident`
+ with `u′` not a variable. Finally, it preserves the initial order of
+ hypotheses, which without the option it may break. The option is on by
+ default.
.. tacn:: stepl @term
@@ -2543,32 +2602,39 @@ where `eq` is typically a setoid equality. The application of :n:`stepl @term`
then replaces the goal by :n:`R @term @term` and adds a new goal stating
:n:`eq @term @term`.
-Lemmas are added to the database using the command ``Declare Left Step @term.``
+.. cmd:: Declare Left Step @term
+
+ Adds :n:`@term` to the database used by :tacn:`stepl`.
+
The tactic is especially useful for parametric setoids which are not accepted
as regular setoids for :tacn:`rewrite` and :tacn:`setoid_replace` (see
-:ref:`TODO-27-Generalizedrewriting`).
+:ref:`Generalizedrewriting`).
.. tacv:: stepl @term by tactic
- This applies :n:`stepl @term` then applies tactic to the second goal.
+ This applies :n:`stepl @term` then applies tactic to the second goal.
.. tacv:: stepr @term stepr @term by tactic
+ :name: stepr
+
+ This behaves as :tacn:`stepl` but on the right-hand-side of the binary
+ relation. Lemmas are expected to be of the form :g:`forall x y z, R x y -> eq
+ y z -> R x z`.
+
+ .. cmd:: Declare Right Step @term
- This behaves as :tacn:`stepl` but on the right-hand-side of the binary
- relation. Lemmas are expected to be of the form :g:`forall x y z, R x y -> eq
- y z -> R x z` and are registered using the command ``Declare Right Step
- @term.``
+ Adds :n:`@term` to the database used by :tacn:`stepr`.
.. tacn:: change @term
:name: change
- This tactic applies to any goal. It implements the rule ``Conv`` given in
- :ref:`TODO-4.4-Subtypingrules`. :g:`change U` replaces the current goal `T`
- with `U` providing that `U` is well-formed and that `T` and `U` are
- convertible.
+ This tactic applies to any goal. It implements the rule ``Conv`` given in
+ :ref:`subtyping-rules`. :g:`change U` replaces the current goal `T`
+ 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
@@ -2581,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
@@ -2637,7 +2703,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
the normalization of the goal according to the specified flags. In
correspondence with the kinds of reduction considered in Coq namely
:math:`\beta` (reduction of functional application), :math:`\delta`
- (unfolding of transparent constants, see :ref:`TODO-6.10.2-Transparent`),
+ (unfolding of transparent constants, see :ref:`vernac-controlling-the-reduction-strategies`),
:math:`\iota` (reduction of
pattern-matching over a constructed term, and unfolding of :g:`fix` and
:g:`cofix` expressions) and :math:`\zeta` (contraction of local definitions), the
@@ -2649,7 +2715,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
second case the constant to unfold to all but the ones explicitly mentioned.
Notice that the ``delta`` flag does not apply to variables bound by a let-in
construction inside the :n:`@term` itself (use here the ``zeta`` flag). In
- any cases, opaque constants are not unfolded (see :ref:`TODO-6.10.1-Opaque`).
+ any cases, opaque constants are not unfolded (see :ref:`vernac-controlling-the-reduction-strategies`).
Normalization according to the flags is done by first evaluating the
head of the expression into a *weak-head* normal form, i.e. until the
@@ -2704,6 +2770,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
and :n:`lazy beta delta -{+ @qualid} iota zeta`.
.. tacv:: vm_compute
+ :name: vm_compute
This tactic evaluates the goal using the optimized call-by-value evaluation
bytecode-based virtual machine described in :cite:`CompiledStrongReduction`.
@@ -2713,6 +2780,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
reflection-based tactics.
.. tacv:: native_compute
+ :name: native_compute
This tactic evaluates the goal by compilation to Objective Caml as described
in :cite:`FullReduction`. If Coq is running in native code, it can be
@@ -2754,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
@@ -2768,7 +2836,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
:n:`hnf`.
.. note::
- The :math:`\delta` rule only applies to transparent constants (see :ref:`TODO-6.10.1-Opaque`
+ The :math:`\delta` rule only applies to transparent constants (see :ref:`vernac-controlling-the-reduction-strategies`
on transparency and opacity).
.. tacn:: cbn
@@ -2881,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
@@ -2906,12 +2974,12 @@ the conversion in hypotheses :n:`{+ @ident}`.
This tactic applies to any goal. The argument qualid must denote a
defined transparent constant or local definition (see
- :ref:`TODO-1.3.2-Definitions` and :ref:`TODO-6.10.2-Transparent`). The tactic
+ :ref:`gallina-definitions` and :ref:`vernac-controlling-the-reduction-strategies`). The tactic
``unfold`` applies the :math:`\delta` rule to each occurrence of the constant to which
: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
@@ -2928,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
@@ -2942,7 +3010,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
This is variant of :n:`unfold @string` where :n:`@string` gets its
interpretation from the scope bound to the delimiting key :n:`key`
- instead of its default interpretation (see :ref:`TODO-12.2.2-Localinterpretationrulesfornotations`).
+ instead of its default interpretation (see :ref:`Localinterpretationrulesfornotations`).
.. tacv:: unfold {+, qualid_or_string at {+, @num}}
This is the most general form, where :n:`qualid_or_string` is either a
@@ -3020,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:
@@ -3071,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.
@@ -3090,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::
@@ -3103,7 +3174,7 @@ the :tacn:`auto` and :tacn:`trivial` tactics:
.. opt:: Info Auto
.. opt:: Debug Auto
.. opt:: Info Trivial
-.. opt:: Info Trivial
+.. opt:: Debug Trivial
See also: :ref:`The Hints Databases for auto and eauto <thehintsdatabasesforautoandeauto>`
@@ -3123,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}}
@@ -3200,7 +3271,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.
@@ -3211,7 +3283,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
--------------------------
@@ -3221,225 +3293,245 @@ 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
-.. cmd:: Hint hint_definition : {+ @ident}
+.. cmd:: Hint @hint_definition : {+ @ident}
-**Variants:**
+ .. cmdv:: Hint @hint_definition
+
+ No database name is given: the hint is registered in the core database.
+
+ .. cmdv:: Local Hint @hint_definition : {+ @ident}
+
+ This is used to declare hints that must not be exported to the other modules
+ that require and import the current module. Inside a section, the option
+ Local is useless since hints do not survive anyway to the closure of
+ sections.
+
+ .. cmdv:: Local Hint @hint_definition
-.. cmd:: Hint hint_definition
+ Idem for the core database.
- No database name is given: the hint is registered in the core database.
+ .. cmdv:: Hint Resolve @term {? | {? @num} {? @pattern}}
+ :name: Hint Resolve
-.. cmd:: Local Hint hint_definition : {+ @ident}
+ 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 is used to declare hints that must not be exported to the other modules
- that require and import the current module. Inside a section, the option
- Local is useless since hints do not survive anyway to the closure of
- sections.
+ .. exn:: @term cannot be used as a hint
-.. cmd:: Local Hint hint_definition
+ The head symbol of the type of :n:`@term` is a bound variable such that
+ this tactic cannot be associated to a constant.
- Idem for the core database.
+ .. cmdv:: Hint Resolve {+ @term}
-The ``hint_definition`` is one of the following expressions:
+ Adds each :n:`Hint Resolve @term`.
-+ :n:`Resolve @term {? | {? @num} {? @pattern}}`
- 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 ``eauto`` is a transitivity lemma.
+ .. cmdv:: Hint Resolve -> @term
- .. exn:: @term cannot be used as a hint
+ Adds the left-to-right implication of an equivalence as a hint (informally
+ the hint will be used as :n:`apply <- @term`, although as mentionned
+ before, the tactic actually used is a restricted version of
+ :tacn:`apply`).
- The head symbol of the type of :n:`@term` is a bound variable such that
- this tactic cannot be associated to a constant.
+ .. cmdv:: Resolve <- @term
- **Variants:**
+ Adds the right-to-left implication of an equivalence as a hint.
- + :n:`Resolve {+ @term}`
- Adds each :n:`Resolve @term`.
+ .. cmdv:: Hint Immediate @term
+ :name: Hint Immediate
- + :n:`Resolve -> @term`
- Adds the left-to-right implication of an equivalence as a hint (informally
- the hint will be used as :n:`apply <- @term`, although as mentionned
- before, the tactic actually used is a restricted version of ``apply``).
+ 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 :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
+ never generates subgoals) is always 1, so that it is not used by :tacn:`trivial`
+ itself.
- + :n:`Resolve <- @term`
- Adds the right-to-left implication of an equivalence as a hint.
+ .. exn:: @term cannot be used as a hint
-+ :n:`Immediate @term`
- 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
- 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
- never generates subgoals) is always 1, so that it is not used by ``trivial``
- itself.
+ .. cmdv:: Immediate {+ @term}
- .. exn:: @term cannot be used as a hint
+ Adds each :n:`Hint Immediate @term`.
- **Variants:**
+ .. cmdv:: Hint Constructors @ident
+ :name: Hint Constructors
- + :n:`Immediate {+ @term}`
- Adds each :n:`Immediate @term`.
+ If :n:`@ident` is an inductive type, this command adds all its constructors as
+ hints of type ``Resolve``. Then, when the conclusion of current goal has the form
+ :n:`(@ident ...)`, :tacn:`auto` will try to apply each constructor.
-+ :n:`Constructors @ident`
- If :n:`@ident` is an inductive type, this command adds all its constructors as
- hints of type Resolve. Then, when the conclusion of current goal has the form
- :n:`(@ident ...)`, ``auto`` will try to apply each constructor.
+ .. exn:: @ident is not an inductive type
- .. exn:: @ident is not an inductive type
+ .. cmdv:: Hint Constructors {+ @ident}
- **Variants:**
+ Adds each :n:`Hint Constructors @ident`.
- + :n:`Constructors {+ @ident}`
- Adds each :n:`Constructors @ident`.
+ .. cmdv:: Hint Unfold @qualid
+ :name: Hint Unfold
-+ :n:`Unfold @qualid`
- This adds the tactic :n:`unfold @qualid` to the hint list that will only be
- used when the head constant of the goal is :n:`@ident`.
- Its cost is 4.
+ This adds the tactic :n:`unfold @qualid` to the hint list that will only be
+ used when the head constant of the goal is :n:`@ident`.
+ Its cost is 4.
- **Variants:**
+ .. cmdv:: Hint Unfold {+ @ident}
- + :n:`Unfold {+ @ident}`
- Adds each :n:`Unfold @ident`.
+ Adds each :n:`Hint Unfold @ident`.
-+ :n:`Transparent`, :n:`Opaque @qualid`
- This adds a transparency hint to the database, making :n:`@qualid` a
- transparent or opaque constant during resolution. This information is used
- during unification of the goal with any lemma in the database and inside the
- discrimination network to relax or constrain it in the case of discriminated
- databases.
+ .. cmdv:: Hint %( Transparent %| Opaque %) @qualid
+ :name: Hint %( Transparent %| Opaque %)
- **Variants:**
+ This adds a transparency hint to the database, making :n:`@qualid` a
+ transparent or opaque constant during resolution. This information is used
+ during unification of the goal with any lemma in the database and inside the
+ discrimination network to relax or constrain it in the case of discriminated
+ databases.
+
+ .. cmdv:: Hint %( Transparent %| Opaque %) {+ @ident}
- + :n:`Transparent`, :n:`Opaque {+ @ident}`
Declares each :n:`@ident` as a transparent or opaque constant.
-+ :n:`Extern @num {? @pattern} => tactic`
- This hint type is to extend ``auto`` with tactics other than ``apply`` and
- ``unfold``. For that, we must specify a cost, an optional :n:`@pattern` and a
- :n:`tactic` to execute. Here is an example::
-
- 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:
-
- .. example::
- .. coqtop:: reset all
-
- 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.
-
-+ :n:`Cut @regexp`
-
- .. warning:: these hints currently only apply to typeclass
- proof search and the ``typeclasses eauto`` tactic (:ref:`TODO-20.6.5-typeclasseseauto`).
-
- 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 ``Print HintDb`` to verify the current cut expression:
-
- .. productionlist:: `regexp`
- e : ident hint or instance identifier
- :|_ any hint
- :| e\|e′ disjunction
- :| e e′ sequence
- :| e * Kleene star
- :| emp empty
- :| 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`.
-
-+ :n:`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.
+ .. cmdv:: Hint Extern @num {? @pattern} => tactic
+ :name: Hint Extern
-.. note::
- One can use an ``Extern`` hint with no pattern to do pattern-matching on
- hypotheses using ``match goal`` with inside the tactic.
+ 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::
+
+ .. coqtop:: in
+
+ 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:
+
+ .. example::
+
+ .. coqtop:: reset all
+
+ 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.
+
+ .. cmdv:: Hint Cut @regexp
+
+ .. warning::
+
+ These hints currently only apply to typeclass proof search and the
+ :tacn:`typeclasses eauto` tactic.
+
+ 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
+ :| e\|e′ disjunction
+ :| e e′ sequence
+ :| e * Kleene star
+ :| emp empty
+ :| 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.
Hint databases defined in the Coq standard library
@@ -3521,7 +3613,7 @@ at every moment.
(left to right). Notice that the rewriting bases are distinct from the ``auto``
hint bases and thatauto does not take them into account.
- This command is synchronous with the section mechanism (see :ref:`TODO-2.4-Sectionmechanism`):
+ This command is synchronous with the section mechanism (see :ref:`section-mechanism`):
when closing a section, all aliases created by ``Hint Rewrite`` in that
section are lost. Conversely, when loading a module, all ``Hint Rewrite``
declarations at the global level of that module are loaded.
@@ -3561,7 +3653,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).
@@ -3569,73 +3661,70 @@ 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.
-**Variants:**
-
-.. cmd:: Set Loose Hint Behavior "Lax"
+.. opt:: Loose Hint Behavior %( "Lax" %| "Warn" %| "Strict" %)
+ :name: Loose Hint Behavior
- This is the default, and corresponds to the historical behavior, that
- is, hints defined outside of a section have a global scope.
+ This option accepts three values, which control the behavior of hints w.r.t.
+ :cmd:`Import`:
-.. cmd:: Set Loose Hint Behavior "Warn"
+ - "Lax": this is the default, and corresponds to the historical behavior,
+ that is, hints defined outside of a section have a global scope.
- When set, it outputs a warning when a non-imported hint is used. Note that
- this is an over-approximation, because a hint may be triggered by a run that
- will eventually fail and backtrack, resulting in the hint not being actually
- useful for the proof.
+ - "Warn": outputs a warning when a non-imported hint is used. Note that this
+ is an over-approximation, because a hint may be triggered by a run that
+ will eventually fail and backtrack, resulting in the hint not being
+ actually useful for the proof.
-.. cmd:: Set Loose Hint Behavior "Strict"
+ - "Strict": changes the behavior of an unloaded hint to a immediate fail
+ tactic, allowing to emulate an import-scoped hint mechanism.
- When set, it changes the behavior of an unloaded hint to a immediate fail
- tactic, allowing to emulate an import-scoped hint mechanism.
+.. _tactics-implicit-automation:
Setting implicit automation tactics
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Proof with tactic
+.. cmd:: Proof with @tactic
This command may be used to start a proof. It defines a default tactic
to be used each time a tactic command ``tactic``:sub:`1` is ended by ``...``.
In this case the tactic command typed by the user is equivalent to
``tactic``:sub:`1` ``;tactic``.
-See also: Proof. in :ref:`TODO-7.1.4-Proofterm`.
+ See also: ``Proof.`` in :ref:`proof-editing-mode`.
-**Variants:**
-.. cmd:: Proof with tactic using {+ @ident}
+ .. cmdv:: Proof with tactic using {+ @ident}
- Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`TODO-7.1.5-Proofusing`
+ Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`proof-editing-mode`
-.. cmd:: Proof using {+ @ident} with tactic
+ .. cmdv:: Proof using {+ @ident} with @tactic
- Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`TODO-7.1.5-Proofusing`
+ Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`proof-editing-mode`
-.. cmd:: Declare Implicit Tactic tactic
+ .. cmd:: Declare Implicit Tactic @tactic
- This command declares a tactic to be used to solve implicit arguments
- that Coq does not know how to solve by unification. It is used every
- time the term argument of a tactic has one of its holes not fully
- resolved.
+ This command declares a tactic to be used to solve implicit arguments
+ that Coq does not know how to solve by unification. It is used every
+ time the term argument of a tactic has one of its holes not fully
+ resolved.
-Here is an example:
+ .. example::
-.. example::
+ .. coqtop:: all
- .. coqtop:: all
-
- Parameter quo : nat -> forall n:nat, n<>0 -> nat.
- Notation "x // y" := (quo x y _) (at level 40).
- Declare Implicit Tactic assumption.
- Goal forall n m, m<>0 -> { q:nat & { r | q * m + r = n } }.
- intros.
- exists (n // m).
+ Parameter quo : nat -> forall n:nat, n<>0 -> nat.
+ Notation "x // y" := (quo x y _) (at level 40).
+ Declare Implicit Tactic assumption.
+ Goal forall n m, m<>0 -> { q:nat & { r | q * m + r = n } }.
+ intros.
+ exists (n // m).
- The tactic ``exists (n // m)`` did not fail. The hole was solved
- by ``assumption`` so that it behaved as ``exists (quo n m H)``.
+ The tactic ``exists (n // m)`` did not fail. The hole was solved
+ by ``assumption`` so that it behaved as ``exists (quo n m H)``.
.. _decisionprocedures:
@@ -3680,11 +3769,12 @@ Therefore, the use of :tacn:`intros` in the previous proof is unnecessary.
an instantiation of `x` is necessary.
.. tacv:: dtauto
+ :name: dtauto
- While :tacn:`tauto` recognizes inductively defined connectives isomorphic to
- the standard connective ``and, prod, or, sum, False, Empty_set, unit, True``,
- :tacn:`dtauto` recognizes also all inductive types with one constructors and
- no indices, i.e. record-style connectives.
+ While :tacn:`tauto` recognizes inductively defined connectives isomorphic to
+ the standard connective ``and, prod, or, sum, False, Empty_set, unit, True``,
+ :tacn:`dtauto` recognizes also all inductive types with one constructors and
+ no indices, i.e. record-style connectives.
.. tacn:: intuition @tactic
:name: intuition
@@ -3713,7 +3803,7 @@ and then uses :tacn:`auto` which completes the proof.
Originally due to César Muñoz, these tactics (:tacn:`tauto` and
:tacn:`intuition`) have been completely re-engineered by David Delahaye using
-mainly the tactic language (see :ref:`TODO-9-thetacticlanguage`). The code is
+mainly the tactic language (see :ref:`ltac`). The code is
now much shorter and a significant increase in performance has been noticed.
The general behavior with respect to dependent types, unfolding and
introductions has slightly changed to get clearer semantics. This may lead to
@@ -3721,26 +3811,20 @@ 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.
-Some aspects of the tactic :tacn:`intuition` can be controlled using options.
-To avoid that inner negations which do not need to be unfolded are
-unfolded, use:
+.. opt:: Intuition Negation Unfolding
-.. cmd:: Unset Intuition Negation Unfolding
-
-
-To do that all negations of the goal are unfolded even inner ones
-(this is the default), use:
-
-.. cmd:: Set Intuition Negation Unfolding
+ Controls whether :tacn:`intuition` unfolds inner negations which do not need
+ to be unfolded. This option is on by default.
.. tacn:: rtauto
:name: rtauto
@@ -3764,14 +3848,18 @@ 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.
-The default tactic used by :tacn:`firstorder` when no rule applies is :g:`auto
-with \*`, it can be reset locally or globally using the ``Set Firstorder
-Solver`` tactic vernacular command and printed using ``Print 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.
+
+ .. cmd:: Print Firstorder Solver
+
+ Prints the default tactic used by :tacn:`firstorder` when no rule applies.
.. tacv:: firstorder @tactic
- Tries to solve the goal with :n:`@tactic` when no logical rule may apply.
+ Tries to solve the goal with :n:`@tactic` when no logical rule may apply.
.. tacv:: firstorder using {+ @qualid}
@@ -3788,8 +3876,9 @@ Solver``.
This combines the effects of the different variants of :tacn:`firstorder`.
-Proof-search is bounded by a depth parameter which can be set by
-typing the ``Set Firstorder Depth n`` vernacular command.
+.. opt:: Firstorder Depth @num
+
+ This option controls the proof-search depth bound.
.. tacn:: congruence
:name: congruence
@@ -3830,11 +3919,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
@@ -3846,7 +3936,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
@@ -3865,7 +3955,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
@@ -3873,12 +3963,12 @@ 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
Unification takes the transparency information defined in the hint database
- :n:`@ident` into account (see :ref:`the hints databases for auto and eauto <the-hints-databases-for-auto-and-eauto>`).
+ :n:`@ident` into account (see :ref:`the hints databases for auto and eauto <thehintsdatabasesforautoandeauto>`).
.. tacn:: is_evar @term
:name: is_evar
@@ -3887,7 +3977,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
@@ -3896,7 +3986,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
@@ -3904,7 +3994,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:
@@ -3928,10 +4018,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 ...
@@ -4009,6 +4099,7 @@ symbol :g:`=`.
.. tacv:: esimplify_eq @num
.. tacv:: esimplify_eq @term {? with @bindings_list}
+ :name: esimplify_eq
This works the same as ``simplify_eq`` but if the type of :n:`@term`, or the
type of the hypothesis referred to by :n:`@num`, has uninstantiated
@@ -4031,6 +4122,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.
@@ -4044,12 +4136,12 @@ Inversion
:tacn:`functional inversion` is a tactic that performs inversion on hypothesis
:n:`@ident` of the form :n:`@qualid {+ @term} = @term` or :n:`@term = @qualid
{+ @term}` where :n:`@qualid` must have been defined using Function (see
-:ref:`TODO-2.3-advancedrecursivefunctions`). Note that this tactic is only
+:ref:`advanced-recursive-functions`). Note that this tactic is only
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.
@@ -4077,10 +4169,10 @@ This kind of inversion has nothing to do with the tactic :tacn:`inversion`
above. This tactic does :g:`change (@ident t)`, where `t` is a term built in
order to ensure the convertibility. In other words, it does inversion of the
function :n:`@ident`. This function must be a fixpoint on a simple recursive
-datatype: see :ref:`TODO-10.3-quote` for the full details.
+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.
@@ -4109,6 +4201,8 @@ using the ``Require Import`` command.
Use ``classical_right`` to prove the right part of the disjunction with
the assumption that the negation of left part holds.
+.. _tactics-automatizing:
+
Automatizing
------------
@@ -4148,7 +4242,7 @@ formulas built with `~`, `\/`, `/\`, `->` on top of equalities,
inequalities and disequalities on both the type :g:`nat` of natural numbers
and :g:`Z` of binary integers. This tactic must be loaded by the command
``Require Import Omega``. See the additional documentation about omega
-(see Chapter :ref:`TODO-21-omega`).
+(see Chapter :ref:`omega`).
.. tacn:: ring
@@ -4168,7 +4262,7 @@ given in the conclusion of the goal by their normal forms. If no term
is given, then the conclusion should be an equation and both hand
sides are normalized.
-See :ref:`TODO-Chapter-25-Theringandfieldtacticfamilies` for more information on
+See :ref:`Theringandfieldtacticfamilies` for more information on
the tactic and how to declare new ring structures. All declared field structures
can be printed with the ``Print Rings`` command.
@@ -4194,7 +4288,7 @@ denominators. So it produces an equation without division nor inverse.
All of these 3 tactics may generate a subgoal in order to prove that
denominators are different from zero.
-See :ref:`TODO-Chapter-25-Theringandfieldtacticfamilies` for more information on the tactic and how to
+See :ref:`Theringandfieldtacticfamilies` for more information on the tactic and how to
declare new field structures. All declared field structures can be
printed with the Print Fields command.
@@ -4286,24 +4380,24 @@ This tactics reverses the list of the focused goals.
This tactic moves all goals under focus to a shelf. While on the
shelf, goals will not be focused on. They can be solved by
unification, or they can be called back into focus with the command
- :tacn:`Unshelve`.
+ :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.
-.. tacn:: Unshelve
- :name: Unshelve
+.. cmd:: Unshelve
This command moves all the goals on the shelf (see :tacn:`shelve`)
from the shelf into focus, by appending them to the end of the current
@@ -4334,11 +4428,11 @@ A simple example has more value than a long explanation:
The tactics macros are synchronous with the Coq section mechanism: a
tactic definition is deleted from the current environment when you
-close the section (see also :ref:`TODO-2.4Sectionmechanism`) where it was
+close the section (see also :ref:`section-mechanism`) where it was
defined. If you want that a tactic macro defined in a module is usable in the
modules that require it, you should put it outside of any section.
-:ref:`TODO-9-Thetacticlanguage` gives examples of more complex
+:ref:`ltac` gives examples of more complex
user-defined tactics.
.. [1] Actually, only the second subgoal will be generated since the
diff --git a/doc/sphinx/proof-engine/vernacular-commands.rst b/doc/sphinx/proof-engine/vernacular-commands.rst
index 0bb6eea23..c37233734 100644
--- a/doc/sphinx/proof-engine/vernacular-commands.rst
+++ b/doc/sphinx/proof-engine/vernacular-commands.rst
@@ -14,62 +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.
+.. cmd:: About @qualid
+ :name: About
-.. cmdv:: About @qualid.
+ 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 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:: About @qualid\@@name
-.. cmdv:: Print @qualid\@@name
+ This locally renames the polymorphic universes of :n:`@qualid`.
+ An underscore means the raw universe is printed.
-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``.
-.. cmd:: Print All.
+.. cmd:: Print All
-This command displays information about the current state of the
-environment, including sections and modules.
+ This command displays information about the current state of the
+ environment, including sections and modules.
+ .. cmdv:: Inspect @num
+ :name: Inspect
-Variants:
+ This command displays the :n:`@num` last objects of the
+ current environment, including sections and modules.
+ .. cmdv:: Print Section @ident
-.. cmdv:: Inspect @num.
-
-This command displays the :n:`@num` last objects of the
-current environment, including sections and modules.
-
-.. 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:
@@ -77,137 +78,144 @@ section.
Flags, Options and Tables
-----------------------------
-|Coq| configurability is based on flags (e.g. Set Printing All in
-Section :ref:`TODO-2.9-printing-full`), options (e.g. ``Set Printing Widthinteger`` in Section
-:ref:`TODO-6.9.6-set-printing-width`), or tables (e.g. ``Add Printing Record ident``, in Section
-:ref:`TODO-2.2.4-add-printing-record`). The names of flags, options and tables are made of non-empty sequences of identifiers
-(conventionally with capital initial
-letter). The general commands handling flags, options and tables are
-given below.
+|Coq| configurability is based on flags (e.g. :opt:`Printing All`), options
+(e.g. :opt:`Printing Width`), or tables (e.g. :cmd:`Add Printing Record`). The
+names of flags, options and tables are made of non-empty sequences of
+identifiers (conventionally with capital initial letter). The general commands
+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.
-
+.. cmd:: Set @flag
-Variants:
+ This command switches :n:`@flag` on. The original state of :n:`@flag`
+ is restored when the current module ends.
+ .. cmdv:: Local Set @flag
-.. cmdv:: Local 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 when the current *section* ends.
+ .. cmdv:: Global Set @flag
-.. 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.
-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:: Export Set @flag
+ 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.
-.. cmd:: Unset @flag.
+.. cmd:: 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 module ends.
+ .. cmdv:: Local Unset @flag
-Variants:
+ 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.
+.. cmd:: Test @flag
-.. cmd:: Test @flag.
+ This command prints whether :n:`@flag` is on or off.
-This command prints whether :n:`@flag` is on or off.
+.. cmd:: Set @option @value
-.. cmd:: Set @option @value.
+ This command sets :n:`@option` to :n:`@value`. The original value of ` option` is
+ restored when the current module ends.
-This command sets :n:`@option` to :n:`@value`. The original value of ` option` is
-restored when the current module ends.
+ .. TODO : option and value are not syntax entries
+ .. cmdv:: Local Set @option @value
-Variants:
+ This command sets :n:`@option` to :n:`@value`. The
+ original value of :n:`@option` is restored at the end of the module.
-.. TODO : option and value are not syntax entries
+ .. cmdv:: Global Set @option @value
-.. cmdv:: Local 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 restored at the end of the module.
+ .. cmdv:: Export Set @option
-.. cmdv:: Global Set @option @value.
+ 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 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.
+.. cmd:: Unset @option
+ This command turns off :n:`@option`.
-.. cmd:: Unset @option.
+ .. cmdv:: Local Unset @option
-This command resets option to its default value.
+ This command turns off :n:`@option`. The original state of :n:`@option`
+ is restored when the current *section* ends.
+ .. cmdv:: Global Unset @option
-Variants:
+ 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:: Export Unset @option
-.. cmdv:: Local 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.
-This command resets :n:`@option` to its default
-value. The original state of :n:`@option` is restored when the current
-*section* ends.
-.. cmdv:: Global Unset @option.
+.. cmd:: Test @option
-This command resets :n:`@option` to its default
-value. 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 prints the current value of :n:`@option`.
+.. TODO : table is not a syntax entry
-.. cmd:: Test @option.
-
-This command prints the current value of :n:`@option`.
+.. cmd:: Add @table @value
+ :name: Add `table` `value`
+.. cmd:: Remove @table @value
+ :name: Remove `table` `value`
-.. TODO : table is not a syntax entry
+.. cmd:: Test @table @value
+ :name: Test `table` `value`
-.. cmd:: Add @table @value.
-.. cmd:: Remove @table @value.
-.. cmd:: Test @table @value.
-.. cmd:: Test @table for @value.
-.. cmd:: Print Table @table.
+.. cmd:: Test @table for @value
+ :name: Test `table` for `value`
-These are general commands for tables.
+.. cmd:: Print Table @table
-.. cmd:: Print Options.
+These are general commands for tables.
-This command lists all available flags, options and tables.
+.. cmd:: Print Options
-Variants:
+ 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:
@@ -215,361 +223,333 @@ 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:`TODO-8.1-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:`TODO-8.7-performing-computations`.
-
-
-.. 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:`TODO-8.7-performing-computations`.
-
-
-.. cmd::Extraction @term.
+.. cmd:: Eval @convtactic in @term
-This command displays the extracted term from :n:`@term`. The extraction is
-processed according to the distinction between ``Set`` and ``Prop``; that is
-to say, between logical and computational content (see Section
-:ref:`TODO-4.1.1-sorts`). The extracted term is displayed in OCaml
-syntax,
-where global identifiers are still displayed as in |Coq| terms.
+ 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`.
-Variants:
+.. cmd:: Compute @term
-.. cmdv:: Recursive Extraction {+ @qualid }.
+ 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`.
-Recursively extracts all
-the material needed for the extraction of the qualified identifiers.
+ See also: Section :ref:`performingcomputations`.
-See also: Chapter ref:`TODO-23-chapter-extraction`.
+.. 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.
+ .. cmdv:: Print Opaque Dependencies @qualid
+ :name: Print Opaque Dependencies
-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.
+ Displays the set of opaque constants :n:`@qualid` relies on in addition to
+ the assumptions.
+ .. cmdv:: Print Transparent Dependencies @qualid
+ :name: Print Transparent Dependencies
-Variants:
+ Displays the set of transparent constants :n:`@qualid` relies on
+ in addition to the assumptions.
+ .. cmdv:: Print All Dependencies @qualid
+ :name: Print All Dependencies
-.. cmdv:: Print Opaque Dependencies @qualid.
+ Displays all assumptions and constants :n:`@qualid` relies on.
-Displays the set of opaque constants :n:`@qualid` relies on in addition to
-the assumptions.
-.. cmdv:: Print Transparent Dependencies @qualid.
+.. cmd:: Search @qualid
-Displays the set of
-transparent constants :n:`@qualid` relies on in addition to the assumptions.
+ 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:: Print All Dependencies @qualid.
+ .. exn:: The reference @qualid was not found in the current environment.
-Displays all assumptions and constants :n:`@qualid` relies on.
+ There is no constant in the environment named qualid.
+ .. 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`.
-.. cmd:: Search @qualid.
+ .. cmdv:: Search @string%@key
-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.
+ 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
-Error messages:
+ 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:: Search { + [-]@term_pattern_string }
-.. exn:: The reference @qualid was not found in the current environment
+ 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.
-There is no constant in the environment named qualid.
+ .. cmdv:: Search @term_pattern_string … @term_pattern_string inside {+ @qualid }
-Variants:
+ This restricts the search to constructions defined in the modules
+ named by the given :n:`qualid` sequence.
-.. cmdv:: Search @string.
+ .. cmdv:: Search @term_pattern_string … @term_pattern_string outside {+ @qualid }
-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:`TODO-12.1-notations`), the command works like ``Search`` :n:`@qualid`.
+ This restricts the search to constructions not defined in the modules
+ named by the given :n:`qualid` sequence.
-.. cmdv:: Search @string%@key.
+ .. cmdv:: @selector: Search [-]@term_pattern_string … [-]@term_pattern_string
-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:`TODO-12.2.2-local-interpretation-rules-for-notations`).
+ 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:: Search @term_pattern.
+ .. example::
-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).
+ .. coqtop:: in
-.. cmdv:: Search { + [-]@term_pattern_string }.
+ Require Import ZArith.
-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.
+ .. coqtop:: all
-.. cmdv:: Search @term_pattern_string … @term_pattern_string inside {+ @qualid } .
+ Search Z.mul Z.add "distr".
-This restricts the search to constructions defined in the modules named by the given :n:`qualid` sequence.
+ Search "+"%Z "*"%Z "distr" -positive -Prop.
-.. cmdv:: Search @term_pattern_string … @term_pattern_string outside {+ @qualid }.
+ Search (?x * _ + ?x * _)%Z outside OmegaLemmas.
-This restricts the search to constructions not defined in the modules named by the given :n:`qualid` sequence.
+ .. cmdv:: SearchAbout
+ :name: SearchAbout
-.. cmdv:: @selector: Search [-]@term_pattern_string … [-]@term_pattern_string.
+ .. deprecated:: 8.5
-This specifies the goal on which to search hypothesis (see
-Section :ref:`TODO-8.1-invocation-of-tactics`).
-By default the 1st goal is searched. This variant can
-be combined with other variants presented here.
+ 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:: in
+.. cmd:: SearchHead @term
- Require Import ZArith.
+ 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.
-.. coqtop:: all
+ .. example::
- Search Z.mul Z.add "distr".
+ .. coqtop:: reset all
- Search "+"%Z "*"%Z "distr" -positive -Prop.
+ SearchHead le.
- Search (?x * _ + ?x * _)%Z outside OmegaLemmas.
+ SearchHead (@eq bool).
-.. 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.
+ .. cmdv:: SearchHead @term inside {+ @qualid }
+ This restricts the search to constructions defined in the modules named
+ by the given :n:`qualid` sequence.
-.. cmd:: SearchHead @term.
+ .. cmdv:: SearchHead term outside {+ @qualid }
-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.
+ This restricts the search to constructions not defined in the modules
+ named by the given :n:`qualid` sequence.
+ .. exn:: Module/section @qualid not found.
+ No module :n:`@qualid` has been required (see Section :ref:`compiled-files`).
-.. coqtop:: reset all
+ .. cmdv:: @selector: SearchHead @term
- SearchHead le.
+ 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.
- SearchHead (@eq bool).
+ .. note:: Up to |Coq| version 8.4, ``SearchHead`` was named ``Search``.
-Variants:
+.. cmd:: SearchPattern @term
-.. cmdv:: SearchHead @term inside {+ @qualid }.
+ 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.
-This restricts the search to constructions defined in the modules named by the given :n:`qualid` sequence.
+ .. example::
-.. cmdv:: SearchHead term outside {+ @qualid }.
+ .. coqtop:: in
-This restricts the search to constructions not defined in the modules named by the given :n:`qualid` sequence.
+ Require Import Arith.
-Error messages:
+ .. coqtop:: all
-.. exn:: Module/section @qualid not found
+ SearchPattern (_ + _ = _ + _).
-No module :n:`@qualid` has been required
-(see Section :ref:`TODO-6.5.1-require`).
+ SearchPattern (nat -> bool).
-.. cmdv:: @selector: SearchHead @term.
+ SearchPattern (forall l : list _, _ l l).
-This specifies the goal on which to
-search hypothesis (see Section :ref:`TODO-8.1-invocation-of-tactics`).
-By default the 1st goal is
-searched. This variant can be combined with other variants presented
-here.
+ Patterns need not be linear: you can express that the same expression
+ must occur in two places by using pattern variables `?ident`.
-.. note:: Up to |Coq| version 8.4, ``SearchHead`` was named ``Search``.
+ .. example::
-.. cmd:: SearchPattern @term.
+ .. coqtop:: all
-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.
+ SearchPattern (?X1 + _ = _ + ?X1).
-.. coqtop:: in
+ .. cmdv:: SearchPattern @term inside {+ @qualid }
- Require Import Arith.
+ This restricts the search to constructions defined in the modules
+ named by the given :n:`qualid` sequence.
-.. coqtop:: all
+ .. cmdv:: SearchPattern @term outside {+ @qualid }
- SearchPattern (_ + _ = _ + _).
+ This restricts the search to constructions not defined in the modules
+ named by the given :n:`qualid` sequence.
- SearchPattern (nat -> bool).
+ .. cmdv:: @selector: SearchPattern @term
- SearchPattern (forall l : list _, _ l l).
+ 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.
-Patterns need not be linear: you can express that the same expression
-must occur in two places by using pattern variables `?ident`.
+.. cmd:: SearchRewrite @term
-.. coqtop:: all
+ 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 “_”.
- SearchPattern (?X1 + _ = _ + ?X1).
+ .. example::
-Variants:
+ .. coqtop:: in
+ Require Import Arith.
-.. cmdv:: SearchPattern @term inside {+ @qualid } .
+ .. coqtop:: all
-This restricts the search to constructions defined in the modules named by the given :n:`qualid` sequence.
+ SearchRewrite (_ + _ + _).
-.. cmdv:: SearchPattern @term outside {+ @qualid }.
+ .. cmdv:: SearchRewrite term inside {+ @qualid }
-This restricts the search to constructions not defined in the modules named by the given :n:`qualid` sequence.
+ This restricts the search to constructions defined in the modules
+ named by the given :n:`qualid` sequence.
-.. cmdv:: @selector: SearchPattern @term.
+ .. cmdv:: SearchRewrite @term outside {+ @qualid }
-This specifies the goal on which to
-search hypothesis (see Section :ref:`TODO-8.1-invocation-of-tactics`). By default the 1st goal is
-searched. This variant can be combined with other variants presented
-here.
+ This restricts the search to constructions not defined in the modules
+ named by the given :n:`qualid` sequence.
+ .. cmdv:: @selector: SearchRewrite @term
-
-.. cmdv:: 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 “_”.
-
-.. 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:`TODO-8.1-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
+ 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_``.
-.. cmd:: Locate @qualid.
+ .. cmd:: Remove Search Blacklist @string
-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.
+ This command allows expunging this blacklist.
-.. coqtop:: none
- Set Printing Depth 50.
+.. cmd:: Locate @qualid
-.. coqtop:: all
+ 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 nat.
+ .. example::
- Locate Datatypes.O.
+ .. coqtop:: all
- Locate Init.Datatypes.O.
+ Locate nat.
- Locate Coq.Init.Datatypes.O.
+ Locate Datatypes.O.
- Locate I.Dont.Exist.
+ Locate Init.Datatypes.O.
-Variants:
+ Locate Coq.Init.Datatypes.O.
+ Locate I.Dont.Exist.
-.. cmdv:: Locate Term @qualid.
+ .. cmdv:: Locate Term @qualid
-As Locate but restricted to terms.
+ As Locate but restricted to terms.
-.. cmdv:: Locate Module @qualid.
+ .. cmdv:: Locate Module @qualid
-As Locate but restricted to modules.
+ As Locate but restricted to modules.
-.. cmdv:: Locate Ltac @qualid.
+ .. cmdv:: Locate Ltac @qualid
-As Locate but restricted to tactics.
+ As Locate but restricted to tactics.
-
-See also: Section :ref:`TODO-12.1.10-LocateSymbol`
+See also: Section :ref:`locating-notations`
.. _loading-files:
@@ -585,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:`TODO-2.6.3-libraries-and-filesystem`)
-
-Files loaded this way cannot leave proofs open, and the ``Load``
-command cannot be used inside a proof either.
-
-Variants:
+.. 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`)
-.. cmdv:: Load @string.
+ Files loaded this way cannot leave proofs open, and the ``Load``
+ command cannot be used inside a proof either.
-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 @string
-.. cmdv:: Load Verbose @ident.
+ 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 @string.
+ .. cmdv:: Load Verbose @ident
-Display, while loading,
-the answers of |Coq| to each command (including tactics) contained in
-the loaded file See also: Section :ref:`TODO-6.9.1-silent`.
+ .. cmdv:: Load Verbose @string
-Error messages:
+ 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
+ .. exn:: Can’t find file @ident on loadpath.
-.. exn:: Load is not supported inside proofs
+ .. 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:
@@ -626,155 +601,143 @@ Compiled files
------------------
This section describes the commands used to load compiled files (see
-Chapter :ref:`TODO-14-coq-commands` for documentation on how to compile a file). A compiled
+Chapter :ref:`thecoqcommands` for documentation on how to compile a file). A compiled
file is a particular case of module called *library file*.
-.. cmd:: Require @qualid.
+.. 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.
+ 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.
-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:`TODO-2.6.3-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.
+ 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.
-Variants:
+ .. cmdv:: Require Import @qualid
+ :name: Require Import
-.. 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 :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 loads and declares the module :n:`@qualid`
-and its dependencies then imports the contents of :n:`@qualid` as described
-in Section :ref:`TODO-2.5.8-import`.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 Export @qualid
+ :name: Require Export
-.. cmdv:: Require 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 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 [Import | Export] {+ @qualid }
-.. cmdv:: Require [Import | Export] {+ @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 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:: From @dirpath Require @qualid
-.. 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.
-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.
+ .. exn:: Cannot load qualid: no physical path bound to dirpath.
+ .. exn:: Cannot find library foo in loadpath.
+ 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`).
-Error messages:
+ .. exn:: Compiled library @ident.vo makes inconsistent assumptions over library qualid.
-.. exn:: Cannot load qualid: no physical path bound to dirpath
+ 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:: Cannot find library foo in loadpath
+ .. exn:: Bad magic number.
-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:`TODO-2.6.3-libraries-and-filesystem`).
+ 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:: Compiled library ident.vo makes inconsistent assumptions over library qualid
+ .. exn:: The file `ident.vo` contains library dirpath and not library dirpath’.
-The command tried to load library file `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 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:: Bad magic number
-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:: Require is not allowed inside a module or a module type.
-.. exn:: The file `ident.vo` contains library dirpath and not library dirpath’
+ 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>`).
-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
+See also: Chapter :ref:`thecoqcommands`
-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:`TODO-2.5.8-import`).
+.. 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.
-See also: Chapter :ref:`TODO-14-coq-commands`
+.. cmd:: Declare ML Module {+ @string }
-.. cmd:: Print Libraries.
+ 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).
-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.
+ .. cmdv:: Local Declare ML Module {+ @string }
+ 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 } .
+ .. exn:: File not found on loadpath: @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:`TODO-2.6.3-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:`TODO-14-coq-commands`), or when |Coq| has been compiled with a
-version of OCaml that supports native Dynlink (≥ 3.11).
+ .. exn:: Loading of ML object file forbidden in a native Coq.
-Variants:
+.. cmd:: Print ML Modules
-
-.. cmdv:: Local Declare ML Module {+ @string }.
-
-This variant is not
-exported to the modules that import the module where they occur, even
-if outside a section.
-
-
-
-Error messages:
-
-.. exn:: File not found on loadpath : @string
-
-.. exn:: Loading of ML object file forbidden in a native |Coq|
-
-
-
-.. 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 Section :ref:`TODO-6.6.10-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:
@@ -783,114 +746,97 @@ Loadpath
------------
Loadpaths are preferably managed using |Coq| command line options (see
-Section `2.6.3-libraries-and-filesystem`) but there remain vernacular commands to manage them
+Section `libraries-and-filesystem`) but there remain vernacular commands to manage them
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.
+.. cmd:: Pwd
-Is equivalent to Pwd.
+ This command displays the current working directory.
+.. cmd:: Cd @string
-.. cmd:: Add LoadPath @string as @dirpath.
+ This command changes the current directory according to :n:`@string` which
+ can be any valid path.
-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:: Cd
-Variants:
+ Is equivalent to Pwd.
-.. cmdv:: Add LoadPath @string.
+.. cmd:: Add LoadPath @string as @dirpath
-Performs as Add LoadPath :n:`@string` as :n:`@dirpath` but
-for the empty directory path.
+ 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
+ Performs as Add LoadPath :n:`@string` as :n:`@dirpath` but
+ for the empty 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:: Add Rec LoadPath @string as @dirpath
-Variants:
+ 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.
+ .. cmdv:: Add Rec LoadPath @string
-.. cmdv:: Add Rec LoadPath @string.
+ Works as :cmd:`Add Rec LoadPath` :n:`@string` as :n:`@dirpath` but for the empty
+ logical directory path.
-Works as ``Add Rec LoadPath`` :n:`@string` as :n:`@dirpath` but for the empty
-logical directory path.
+.. cmd:: Remove LoadPath @string
+ This command removes the path :n:`@string` from the current |Coq| loadpath.
-.. cmd:: Remove LoadPath @string.
-This command removes the path :n:`@string` from the current |Coq| loadpath.
+.. cmd:: Print LoadPath
+ This command displays the current |Coq| loadpath.
-.. cmd:: Print LoadPath.
+ .. cmdv:: Print LoadPath @dirpath
-This command displays the current |Coq| loadpath.
+ Works as :cmd:`Print LoadPath` but displays only
+ the paths that extend the :n:`@dirpath` prefix.
-Variants:
+.. 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`).
-.. cmdv:: Print LoadPath @dirpath.
-Works as ``Print LoadPath`` but displays only
-the paths that extend the :n:`@dirpath` prefix.
+.. 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 :cmd:`Declare ML Module`).
-.. 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:`TODO-6.5-compiled-files`).
+.. 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`).
-.. cmd:: Add Rec ML Path @string.
+.. _locate-file:
-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:`TODO-6.5-compiled-files`).
+.. 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.
-.. 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:`TODO-6.5-compiled-files`).
+.. cmd:: Locate Library @dirpath
-
-.. 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.
-
-
-.. 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:
@@ -903,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:`TODO-7-proof-handling`). 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:`TODO-7-proof-handling`).
- + *third number* : Number of Abort to perform, i.e. the number of currently
- opened nested proofs that must be canceled (see Chapter :ref:`TODO-7-proof-handling`).
+ + *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:
@@ -1000,227 +923,143 @@ Quitting and debugging
--------------------------
-.. 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:: Quit
+ This command permits to quit |Coq|.
-::
- #use "include";;
+.. 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:
-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:
+ ::
+ #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:
- go();;
+ ::
+ go();;
+ .. warning::
-Warnings:
-
-
-#. It only works with the bytecode version of |Coq| (i.e. `coqtop.byte`,
- see Section `TODO-14.1-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 `14.3.2-customization-by-envionment-variables`).
-
+ #. 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.
-
-This command executes the vernacular command :n:`@command` and displays the
-time needed to execute it.
-
+.. cmd:: Time @command
-.. cmd:: Redirect @string @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`, redirecting its
-output to ":n:`@string`.out".
+.. cmd:: Redirect @string @command
-.. cmd:: Timeout @num @command.
+ This command executes the vernacular command :n:`@command`, redirecting its
+ output to ":n:`@string`.out".
-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.
+.. cmd:: Timeout @num @command
-.. cmd:: Set Default Timeout @num.
+ 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.
-After using this command, all subsequent commands behave as if they
-were passed to a Timeout command. Commands already starting by a
-`Timeout` are unaffected.
+ .. 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.
-.. cmd:: Unset Default Timeout.
-This command turns off the use of a default timeout.
+.. cmd:: Fail @command
-.. cmd:: Test Default Timeout.
+ 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.
-This command displays whether some default timeout has been set or not.
+ .. exn:: The command has not failed!
-.. 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.
-
-Error messages:
-
-.. exn:: The command has not failed!
.. _controlling-display:
Controlling display
-----------------------
+.. opt:: Silent
-.. cmd:: Set Silent.
-
-This command turns off the normal displaying.
-
-
-.. cmd:: Unset Silent.
-
-This command turns the normal display on.
-
-TODO : check that spaces are handled well
-
-.. cmd:: Set Warnings ‘‘(@ident {* , @ident } )’’.
-
-This command configures the display of warnings. It is experimental,
-and expects, between quotes, a comma-separated list of warning names
-or categories. Adding - in front of a warning or category disables it,
-adding + makes it an error. It is possible to use the special
-categories all and default, the latter containing the warnings enabled
-by default. The flags are interpreted from left to right, so in case
-of an overlap, the flags on the right have higher priority, meaning
-that `A,-A` is equivalent to `-A`.
-
-
-.. cmd:: Set Search Output Name Only.
-
-This command restricts the output of search commands to identifier
-names; turning it on causes invocations of ``Search``, ``SearchHead``,
-``SearchPattern``, ``SearchRewrite`` etc. to omit types from their output,
-printing only identifiers.
-
-
-.. cmd:: Unset Search Output Name Only.
-
-This command turns type display in search results back on.
-
-
-.. cmd:: Set Printing Width @integer.
-
-This command sets which left-aligned part of the width of the screen
-is used for display.
-
-
-.. cmd:: Unset Printing Width.
-
-This command resets the width of the screen used for display to its
-default value (which is 78 at the time of writing this documentation).
+ This option controls the normal displaying.
+.. opt:: Warnings "{+, {? %( - %| + %) } @ident }"
-.. cmd:: Test Printing Width.
+ This option configures the display of warnings. It is experimental, and
+ expects, between quotes, a comma-separated list of warning names or
+ categories. Adding - in front of a warning or category disables it, adding +
+ makes it an error. It is possible to use the special categories all and
+ default, the latter containing the warnings enabled by default. The flags are
+ interpreted from left to right, so in case of an overlap, the flags on the
+ right have higher priority, meaning that `A,-A` is equivalent to `-A`.
-This command displays the current screen width used for display.
+.. opt:: Search Output Name Only
+ This option restricts the output of search commands to identifier names;
+ turning it on causes invocations of :cmd:`Search`, :cmd:`SearchHead`,
+ :cmd:`SearchPattern`, :cmd:`SearchRewrite` etc. to omit types from their
+ output, printing only identifiers.
-.. cmd:: Set Printing Depth @integer.
+.. opt:: Printing Width @num
+ :name: Printing Width
-This command sets the nesting depth of the formatter used for pretty-
-printing. Beyond this depth, display of subterms is replaced by dots.
+ 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 @num
+ :name: Printing Depth
-.. cmd:: Unset 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
+ time of writing this documentation, the default value is 50.
-This command resets the nesting depth of the formatter used for
-pretty-printing to its default value (at the time of writing this
-documentation, the default value is 50).
+.. opt:: Printing Compact Contexts
+ This option controls the compact display mode for goals contexts. When on,
+ the printer tries to reduce the vertical size of goals contexts by putting
+ several variables (even if of different types) on the same line provided it
+ does not exceed the printing width (see :opt:`Printing Width`). At the time
+ of writing this documentation, it is off by default.
-.. cmd:: Test Printing Depth.
+.. opt:: Printing Unfocused
-This command displays the current nesting depth used for display.
+ This option controls whether unfocused goals are displayed. Such goals are
+ created by focusing other goals with bullets (see :ref:`bullets` or
+ :ref:`curly braces <curly-braces>`). It is off by default.
+.. opt:: Printing Dependent Evars Line
-.. cmd:: Unset Printing Compact Contexts.
+ This option controls the printing of the “(dependent evars: …)” line when
+ ``-emacs`` is passed.
-This command resets the displaying of goals contexts to non compact
-mode (default at the time of writing this documentation). Non compact
-means that consecutive variables of different types are printed on
-different lines.
-
-
-.. cmd:: Set Printing Compact Contexts.
-
-This command sets the displaying of goals contexts to compact mode.
-The printer tries to reduce the vertical size of goals contexts by
-putting several variables (even if of different types) on the same
-line provided it does not exceed the printing width (See Set Printing
-Width above).
-
-
-.. cmd:: Test Printing Compact Contexts.
-
-This command displays the current state of compaction of goal.
-
-
-.. cmd:: Unset Printing Unfocused.
-
-This command resets the displaying of goals to focused goals only
-(default). Unfocused goals are created by focusing other goals with
-bullets (see :ref:`TODO-7.2.7-bullets`) or curly braces (see `7.2.6-curly-braces`).
-
-
-.. cmd:: Set Printing Unfocused.
-
-This command enables the displaying of unfocused goals. The goals are
-displayed after the focused ones and are distinguished by a separator.
-
-
-.. cmd:: Test Printing Unfocused.
-
-This command displays the current state of unfocused goals display.
-
-
-.. cmd:: Set Printing Dependent Evars Line.
-
-This command enables the printing of the “(dependent evars: …)” line
-when -emacs is passed.
-
-
-.. cmd:: Unset Printing Dependent Evars Line.
-
-This command disables the printing of the “(dependent evars: …)” line
-when -emacs is passed.
+.. _vernac-controlling-the-reduction-strategies:
Controlling the reduction strategies and the conversion algorithm
----------------------------------------------------------------------
@@ -1232,84 +1071,83 @@ conversion algorithm lazily compares applicative terms while the other
is a brute-force but efficient algorithm that first normalizes the
terms before comparing them. The second algorithm is based on a
bytecode representation of terms similar to the bytecode
-representation used in the ZINC virtual machine [`98`]. It is
+representation used in the ZINC virtual machine :cite:`Leroy90`. It is
especially useful for intensive computation of algebraic values, such
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:`TODO-4.3-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.
-
-
-See also: sections :ref:`TODO-8.7-performing-computations`, :ref:`TODO-8.16-automatizing`, :ref:`TODO-7.1-switching-on-off-proof-editing-mode`
-
-
-Error messages:
+.. 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).
-.. exn:: The reference @qualid was not found in the current environment
+ :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.
-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.
+ .. cmdv:: Global Opaque {+ @qualid }
+ :name: Global Opaque
-.. cmd:: Transparent {+ @qualid }.
+ The scope of :cmd:`Opaque` is limited to the current section, or current
+ file, unless the variant :cmd:`Global Opaque` is used.
-This command is the converse of `Opaque`` and it applies on unfoldable
-constants to restore their unfoldability after an Opaque command.
+ See also: sections :ref:`performingcomputations`, :ref:`tactics-automatizing`,
+ :ref:`proof-editing-mode`
-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.
+ .. exn:: The reference @qualid was not found in the current environment.
-The scope of Transparent is limited to the current section, or current
-file, unless the variant ``Global Transparent`` is
-used.
+ 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 }
-Error messages:
+ 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.
-.. exn:: The reference @qualid was not found in the current environment
+ .. cmdv:: Global Transparent {+ @qualid }
+ :name: Global Transparent
-There is no constant referred by :n:`@qualid` in the environment.
+ The scope of Transparent is limited to the current section, or current
+ file, unless the variant :cmd:`Global Transparent` is
+ used.
+ .. 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:`TODO-8.7-performing-computations`, :ref:`TODO-8.16-automatizing`, :ref:`TODO-7.1-switching-on-off-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).
@@ -1322,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:`TODO-8.7-performing-computations`
+ See also: sections :ref:`performingcomputations`
.. _controlling-locality-of-commands:
@@ -1376,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:
@@ -1386,29 +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:`TODO-2.8-coercions`) and ``Strategy`` (see Section :ref:`TODO-6.10.3-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 ``Implicit Arguments`` (see
- Section :ref:`TODO-2.7-implicit-arguments`), Ltac (see Chapter :ref:`TODO-9-tactic-language`) or ``Notation`` (see Section
- :ref:`TODO-12.1-notations`) 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.
+ 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:`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:`TODO-6.10-opaque`) 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/replaces.rst b/doc/sphinx/replaces.rst
index 1b2e17221..28a04f90c 100644
--- a/doc/sphinx/replaces.rst
+++ b/doc/sphinx/replaces.rst
@@ -35,7 +35,9 @@
.. |ident_n,1| replace:: `ident`\ :math:`_{n,1}`
.. |ident_n,k_n| replace:: `ident`\ :math:`_{n,k_n}`
.. |ident_n| replace:: `ident`\ :math:`_{n}`
+.. |Latex| replace:: :smallcaps:`LaTeX`
.. |L_tac| replace:: `L`:sub:`tac`
+.. |Ltac| replace:: `L`:sub:`tac`
.. |ML| replace:: :smallcaps:`ML`
.. |mod_0| replace:: `mod`\ :math:`_{0}`
.. |mod_1| replace:: `mod`\ :math:`_{1}`
@@ -54,7 +56,7 @@
.. |module_type_n| replace:: `module_type`\ :math:`_{n}`
.. |N| replace:: ``N``
.. |nat| replace:: ``nat``
-.. |Ocaml| replace:: :smallcaps:`OCaml`
+.. |OCaml| replace:: :smallcaps:`OCaml`
.. |p_1| replace:: `p`\ :math:`_{1}`
.. |p_i| replace:: `p`\ :math:`_{i}`
.. |p_n| replace:: `p`\ :math:`_{n}`
diff --git a/doc/sphinx/user-extensions/proof-schemes.rst b/doc/sphinx/user-extensions/proof-schemes.rst
index 583b73e53..682553c31 100644
--- a/doc/sphinx/user-extensions/proof-schemes.rst
+++ b/doc/sphinx/user-extensions/proof-schemes.rst
@@ -3,6 +3,8 @@
Proof schemes
===============
+.. _proofschemes-induction-principles:
+
Generation of induction principles with ``Scheme``
--------------------------------------------------------
@@ -10,7 +12,7 @@ The ``Scheme`` command is a high-level tool for generating automatically
(possibly mutual) induction principles for given types and sorts. Its
syntax follows the schema:
-.. cmd:: Scheme ident := Induction for ident' Sort sort {* with ident := Induction for ident' Sort sort}
+.. cmd:: Scheme @ident := Induction for @ident Sort sort {* with @ident := Induction for @ident Sort sort}
where each `ident'ᵢ` is a different inductive type identifier
belonging to the same package of mutual inductive definitions. This
@@ -18,17 +20,18 @@ command generates the `identᵢ`s to be mutually recursive
definitions. Each term `identᵢ` proves a general principle of mutual
induction for objects in type `identᵢ`.
-.. cmdv:: Scheme ident := Minimality for ident' Sort sort {* with ident := Minimality for ident' Sort sort}
+.. cmdv:: Scheme @ident := Minimality for @ident Sort sort {* with @ident := Minimality for @ident' Sort sort}
Same as before but defines a non-dependent elimination principle more
natural in case of inductively defined relations.
-.. cmdv:: Scheme Equality for ident
+.. 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.
-.. cmdv:: Scheme Induction for ident Sort sort {* with Induction for ident Sort sort}
+.. cmdv:: Scheme Induction for @ident Sort sort {* with Induction for @ident Sort sort}
If you do not provide the name of the schemes, they will be automatically computed from the
sorts involved (works also with Minimality).
@@ -101,26 +104,34 @@ induction for objects in type `identᵢ`.
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``.
-The types declared with the keywords ``Variant`` (see :ref:`TODO-1.3.3`) and ``Record``
-(see :ref:`Record Types <record-types>`) do not have an automatic declaration of the induction
-principles. It can be activated with the command
-``Set Nonrecursive Elimination Schemes``. It can be deactivated again with
-``Unset Nonrecursive Elimination Schemes``.
-
-In addition, the ``Case Analysis Schemes`` flag governs the generation of
-case analysis lemmas for inductive types, i.e. corresponding to the
-pattern-matching term alone and without fixpoint.
-You can also activate the automatic declaration of those Boolean
-equalities (see the second variant of ``Scheme``) with respectively the
-commands ``Set Boolean Equality Schemes`` and ``Set Decidable Equality
-Schemes``. However you have to be careful with this option since Coq may
-now reject well-defined inductive types because it cannot compute a
-Boolean equality for them.
+.. 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.
+
+.. opt:: Case Analysis Schemes
+
+ This flag governs the generation of case analysis lemmas for inductive types,
+ i.e. corresponding to the pattern-matching term alone and without fixpoint.
+
+.. opt:: Boolean Equality Schemes
+
+.. opt:: Decidable Equality Schemes
+
+These flags control the automatic declaration of those Boolean equalities (see
+the second variant of ``Scheme``).
+
+.. warning::
+
+ You have to be careful with this option since Coq may now reject well-defined
+ inductive types because it cannot compute a Boolean equality for them.
.. opt:: Rewriting Schemes
@@ -133,7 +144,7 @@ The ``Combined Scheme`` command is a tool for combining induction
principles generated by the ``Scheme command``. Its syntax follows the
schema :
-.. cmd:: Combined Scheme ident from {+, ident}
+.. cmd:: Combined Scheme @ident from {+, ident}
where each identᵢ after the ``from`` is a different inductive principle that must
belong to the same package of mutual inductive principle definitions.
@@ -163,6 +174,8 @@ concluded by the conjunction of their conclusions.
Check tree_forest_mutind.
+.. _functional-scheme:
+
Generation of induction principles with ``Functional`` ``Scheme``
-----------------------------------------------------------------
@@ -172,7 +185,7 @@ generating automatically induction principles corresponding to
available via ``Require Import FunInd``. Its syntax then follows the
schema:
-.. cmd:: Functional Scheme ident := Induction for ident' Sort sort {* with ident := Induction for ident' Sort sort}
+.. cmd:: Functional Scheme @ident := Induction for ident' Sort sort {* with @ident := Induction for @ident Sort sort}
where each `ident'ᵢ` is a different mutually defined function
name (the names must be in the same order as when they were defined). This
@@ -229,7 +242,7 @@ definition written by the user.
simpl; auto with arith.
Qed.
- We can use directly the functional induction (:ref:`TODO-8.5.5`) tactic instead
+ We can use directly the functional induction (:tacn:`function induction`) tactic instead
of the pattern/apply trick:
.. coqtop:: all
@@ -305,13 +318,15 @@ definition written by the user.
.. coqtop:: all
Check tree_size_ind2.
+
+.. _derive-inversion:
Generation of inversion principles with ``Derive`` ``Inversion``
-----------------------------------------------------------------
The syntax of ``Derive`` ``Inversion`` follows the schema:
-.. cmd:: Derive Inversion ident with forall (x : T), I t Sort sort
+.. cmd:: Derive Inversion @ident with forall (x : T), I t Sort sort
This command generates an inversion principle for the `inversion … using`
tactic. Let `I` be an inductive predicate and `x` the variables occurring
@@ -320,17 +335,17 @@ sort `sort` corresponding to the instance `∀ (x:T), I t` with the name
`ident` in the global environment. When applied, it is equivalent to
having inverted the instance with the tactic `inversion`.
-.. cmdv:: Derive Inversion_clear ident with forall (x:T), I t Sort sort
+.. cmdv:: Derive Inversion_clear @ident with forall (x:T), I t Sort sort
When applied, it is equivalent to having inverted the instance with the
tactic inversion replaced by the tactic `inversion_clear`.
-.. cmdv:: Derive Dependent Inversion ident with forall (x:T), I t Sort sort
+.. cmdv:: Derive Dependent Inversion @ident with forall (x:T), I t Sort sort
When applied, it is equivalent to having inverted the instance with
the tactic `dependent inversion`.
-.. cmdv:: Derive Dependent Inversion_clear ident with forall(x:T), I t Sort sort
+.. cmdv:: Derive Dependent Inversion_clear @ident with forall(x:T), I t Sort sort
When applied, it is equivalent to having inverted the instance
with the tactic `dependent inversion_clear`.
diff --git a/doc/sphinx/user-extensions/syntax-extensions.rst b/doc/sphinx/user-extensions/syntax-extensions.rst
index 6e6d66447..3b95a37ed 100644
--- a/doc/sphinx/user-extensions/syntax-extensions.rst
+++ b/doc/sphinx/user-extensions/syntax-extensions.rst
@@ -10,12 +10,12 @@ parses and prints objects, i.e. the translations between the concrete
and internal representations of terms and commands.
The main commands to provide custom symbolic notations for terms are
-``Notation`` and ``Infix``. They are described in section 12.1. There is also a
+``Notation`` and ``Infix``. They are described in section :ref:`Notations`. There is also a
variant of ``Notation`` which does not modify the parser. This provides with a
form of abbreviation and it is described in Section :ref:`Abbreviations`. It is
sometimes expected that the same symbolic notation has different meanings in
different contexts. To achieve this form of overloading, |Coq| offers a notion
-of interpretation scope. This is described in Section :ref:`scopes`.
+of interpretation scope. This is described in Section :ref:`Scopes`.
The main command to provide custom notations for tactics is ``Tactic Notation``.
It is described in Section :ref:`TacticNotation`.
@@ -24,12 +24,16 @@ It is described in Section :ref:`TacticNotation`.
Set Printing Depth 50.
+.. _Notations:
+
Notations
---------
Basic notations
~~~~~~~~~~~~~~~
+.. cmd:: Notation
+
A *notation* is a symbolic expression denoting some term or term
pattern.
@@ -68,7 +72,7 @@ have to be given.
.. note::
The right-hand side of a notation is interpreted at the time the notation is
- given. In particular, disambiguiation of constants, implicit arguments (see
+ given. In particular, disambiguation of constants, implicit arguments (see
Section :ref:`ImplicitArguments`), coercions (see Section :ref:`Coercions`),
etc. are resolved at the time of the declaration of the notation.
@@ -196,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.
@@ -343,13 +347,13 @@ inductive type or a recursive constant and a notation for it.
Simultaneous definition of terms and notations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Thanks to reserved notations, the inductive, co-inductive, record, recursive
-and corecursive definitions can benefit of customized notations. To do
-this, insert a ``where`` notation clause after the definition of the
-(co)inductive type or (co)recursive term (or after the definition of
-each of them in case of mutual definitions). The exact syntax is given
-on Figure 12.1 for inductive, co-inductive, recursive and corecursive
-definitions and on Figure :ref:`record-syntax` for records. Here are examples:
+Thanks to reserved notations, the inductive, co-inductive, record, recursive and
+corecursive definitions can benefit of customized notations. To do this, insert
+a ``where`` notation clause after the definition of the (co)inductive type or
+(co)recursive term (or after the definition of each of them in case of mutual
+definitions). The exact syntax is given by :token:`decl_notation` for inductive,
+co-inductive, recursive and corecursive definitions and in :ref:`record-types`
+for records. Here are examples:
.. coqtop:: in
@@ -379,23 +383,21 @@ Displaying informations about notations
:opt:`Printing All`
To disable other elements in addition to notations.
+.. _locating-notations:
+
Locating notations
~~~~~~~~~~~~~~~~~~
-.. cmd:: Locate @symbol
-
- To know to which notations a given symbol belongs to, use the command
- ``Locate symbol``, where symbol is any (composite) symbol surrounded by double
- quotes. To locate a particular notation, use a string where the variables of the
- notation are replaced by “_” and where possible single quotes inserted around
- identifiers or tokens starting with a single quote are dropped.
+To know to which notations a given symbol belongs to, use the :cmd:`Locate`
+command. You can call it on any (composite) symbol surrounded by double quotes.
+To locate a particular notation, use a string where the variables of the
+notation are replaced by “_” and where possible single quotes inserted around
+identifiers or tokens starting with a single quote are dropped.
- .. coqtop:: all
-
- Locate "exists".
- Locate "exists _ .. _ , _".
+.. coqtop:: all
- .. todo:: See also: Section 6.3.10.
+ Locate "exists".
+ Locate "exists _ .. _ , _".
Notations and binders
~~~~~~~~~~~~~~~~~~~~~
@@ -433,8 +435,7 @@ Binders bound in the notation and parsed as patterns
In the same way as patterns can be used as binders, as in
:g:`fun '(x,y) => x+y` or :g:`fun '(existT _ x _) => x`, notations can be
-defined so that any pattern (in the sense of the entry :n:`@pattern` of
-Figure :ref:`term-syntax-aux`) can be used in place of the
+defined so that any :n:`@pattern` can be used in place of the
binder. Here is an example:
.. coqtop:: in reset
@@ -473,7 +474,7 @@ variable. Here is an example showing the difference:
The default level for a ``pattern`` is 0. One can use a different level by
using ``pattern at level`` :math:`n` where the scale is the same as the one for
-terms (Figure :ref:`init-notations`).
+terms (see :ref:`init-notations`).
Binders bound in the notation and parsed as terms
+++++++++++++++++++++++++++++++++++++++++++++++++
@@ -489,7 +490,7 @@ the following:
This is so because the grammar also contains rules starting with :g:`{}` and
followed by a term, such as the rule for the notation :g:`{ A } + { B }` for the
-constant :g:`sumbool` (see Section :ref:`sumbool`).
+constant :g:`sumbool` (see Section :ref:`specification`).
Then, in the rule, ``x ident`` is replaced by ``x at level 99 as ident`` meaning
that ``x`` is parsed as a term at level 99 (as done in the notation for
@@ -689,8 +690,7 @@ side. E.g.:
Summary
~~~~~~~
-Syntax of notations
-~~~~~~~~~~~~~~~~~~~
+**Syntax of notations**
The different syntactic variants of the command Notation are given on the
following figure. The optional :token:`scope` is described in the Section 12.2.
@@ -743,8 +743,7 @@ following figure. The optional :token:`scope` is described in the Section 12.2.
given to some notation, say ``"{ y } & { z }"`` in fact applies to the
underlying ``"{ x }"``\-free rule which is ``"y & z"``).
-Persistence of notations
-~~~~~~~~~~~~~~~~~~~~~~~~
+**Persistence of notations**
Notations do not survive the end of sections.
@@ -753,6 +752,8 @@ Notations do not survive the end of sections.
Notations survive modules unless the command ``Local Notation`` is used instead
of ``Notation``.
+.. _Scopes:
+
Interpretation scopes
----------------------
@@ -827,6 +828,8 @@ lonely notations. These scopes, in opening order, are ``core_scope``,
These variants survive sections. They behave as if Global were absent when
not inside a section.
+.. _LocalInterpretationRulesForNotations:
+
Local interpretation rules for notations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -857,6 +860,7 @@ Binding arguments of a constant to an interpretation scope
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.. cmd:: Arguments @qualid {+ @name%@scope}
+ :name: Arguments (scopes)
It is possible to set in advance that some arguments of a given constant have
to be interpreted in a given scope. The command is
@@ -895,7 +899,7 @@ Binding arguments of a constant to an interpretation scope
.. cmdv:: Arguments @qualid {+ @name%scope} : extra scopes
Defines extra argument scopes, to be used in case of coercion to Funclass
- (see Chapter :ref:`Coercions-full`) or with a computed type.
+ (see Chapter :ref:`implicitcoercions`) or with a computed type.
.. cmdv:: Global Arguments @qualid {+ @name%@scope}
@@ -912,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::
@@ -955,7 +958,7 @@ Binding types of arguments to an interpretation scope
type :g:`t` in :g:`f t a` is not recognized as an argument to be interpreted
in scope ``scope``.
- More generally, any coercion :n:`@class` (see Chapter :ref:`Coercions-full`)
+ More generally, any coercion :n:`@class` (see Chapter :ref:`implicitcoercions`)
can be bound to an interpretation scope. The command to do it is
:n:`Bind Scope @scope with @class`
@@ -1125,6 +1128,8 @@ Displaying informations about scopes
class of all the existing interpretation scopes. It also displays the
lonely notations.
+.. _Abbreviations:
+
Abbreviations
--------------
@@ -1187,6 +1192,8 @@ Abbreviations
denoted expression is performed at definition time. Type-checking is
done only at the time of use of the abbreviation.
+.. _TacticNotation:
+
Tactic Notations
-----------------
@@ -1194,7 +1201,7 @@ Tactic notations allow to customize the syntax of the tactics of the
tactic language. Tactic notations obey the following syntax:
.. productionlist:: coq
- tacn : [Local] Tactic Notation [`tactic_level`] [`prod_item` … `prod_item`] := `tactic`.
+ tacn : Tactic Notation [`tactic_level`] [`prod_item` … `prod_item`] := `tactic`.
prod_item : `string` | `tactic_argument_type`(`ident`)
tactic_level : (at level `natural`)
tactic_argument_type : ident | simple_intropattern | reference
@@ -1205,7 +1212,7 @@ tactic language. Tactic notations obey the following syntax:
: | tactic | tactic0 | tactic1 | tactic2 | tactic3
: | tactic4 | tactic5
-.. cmd:: {? Local} Tactic Notation {? (at level @level)} {+ @prod_item} := @tactic.
+.. cmd:: Tactic Notation {? (at level @level)} {+ @prod_item} := @tactic.
A tactic notation extends the parser and pretty-printer of tactics with a new
rule made of the list of production items. It then evaluates into the
diff --git a/doc/tools/coqrst/coqdomain.py b/doc/tools/coqrst/coqdomain.py
index 663ab9d37..21093bd90 100644
--- a/doc/tools/coqrst/coqdomain.py
+++ b/doc/tools/coqrst/coqdomain.py
@@ -108,7 +108,7 @@ class CoqObject(ObjectDescription):
annotation = self.annotation + ' '
signode += addnodes.desc_annotation(annotation, annotation)
self._render_signature(signature, signode)
- return self._name_from_signature(signature)
+ return self.options.get("name") or self._name_from_signature(signature)
@property
def _index_suffix(self):
@@ -145,14 +145,6 @@ class CoqObject(ObjectDescription):
index_text = name + self._index_suffix
self.indexnode['entries'].append(('single', index_text, target, '', None))
- def run(self):
- """Small extension of the parent's run method, handling user-provided names."""
- [idx, node] = super().run()
- custom_name = self.options.get("name")
- if custom_name:
- self.add_target_and_index(custom_name, "", node.children[0])
- return [idx, node]
-
def add_target_and_index(self, name, _, signode):
"""Create a target and an index entry for name"""
if name:
@@ -194,13 +186,18 @@ class VernacObject(NotationObject):
annotation = "Command"
def _name_from_signature(self, signature):
- return stringify_with_ellipses(signature)
+ m = re.match(r"[a-zA-Z ]+", signature)
+ if m:
+ return m.group(0).strip()
class VernacVariantObject(VernacObject):
"""An object to represent variants of Coq commands"""
index_suffix = "(cmdv)"
annotation = "Variant"
+ def _name_from_signature(self, signature):
+ return None
+
class TacticNotationObject(NotationObject):
"""An object to represent Coq tactic notations"""
subdomain = "tacn"
@@ -735,14 +732,14 @@ 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),
+ 'tac': 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
diff --git a/doc/tools/coqrst/notations/CoqNotations.ttf b/doc/tools/coqrst/notations/CoqNotations.ttf
new file mode 100644
index 000000000..da8f2850d
--- /dev/null
+++ b/doc/tools/coqrst/notations/CoqNotations.ttf
Binary files differ
diff --git a/doc/tools/coqrst/notations/TacticNotations.g b/doc/tools/coqrst/notations/TacticNotations.g
index 68658fe49..a889ebda7 100644
--- a/doc/tools/coqrst/notations/TacticNotations.g
+++ b/doc/tools/coqrst/notations/TacticNotations.g
@@ -20,13 +20,14 @@ repeat: LGROUP (ATOM)? WHITESPACE blocks (WHITESPACE)? RBRACE;
curlies: LBRACE (whitespace)? blocks (whitespace)? RBRACE;
whitespace: WHITESPACE;
meta: METACHAR;
-atomic: ATOM;
-hole: ID;
+atomic: ATOM (SUB)?;
+hole: ID (SUB)?;
LGROUP: '{' [+*?];
LBRACE: '{';
RBRACE: '}';
METACHAR: '%' [|(){}];
-ATOM: '@' | ~[@{} ]+;
-ID: '@' [a-zA-Z0-9_]+;
+ATOM: '@' | '_' | ~[@_{} ]+;
+ID: '@' ('_'? [a-zA-Z0-9])+;
+SUB: '_' '_' [a-zA-Z0-9]+;
WHITESPACE: ' '+;
diff --git a/doc/tools/coqrst/notations/TacticNotations.tokens b/doc/tools/coqrst/notations/TacticNotations.tokens
index 76ed2b065..88b38f97a 100644
--- a/doc/tools/coqrst/notations/TacticNotations.tokens
+++ b/doc/tools/coqrst/notations/TacticNotations.tokens
@@ -4,6 +4,7 @@ RBRACE=3
METACHAR=4
ATOM=5
ID=6
-WHITESPACE=7
+SUB=7
+WHITESPACE=8
'{'=2
'}'=3
diff --git a/doc/tools/coqrst/notations/TacticNotationsLexer.py b/doc/tools/coqrst/notations/TacticNotationsLexer.py
index 61d8d2f9e..27293e7e0 100644
--- a/doc/tools/coqrst/notations/TacticNotationsLexer.py
+++ b/doc/tools/coqrst/notations/TacticNotationsLexer.py
@@ -7,24 +7,28 @@ import sys
def serializedATN():
with StringIO() as buf:
- buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\t")
- buf.write(".\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
- buf.write("\4\b\t\b\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\5\3\6\3")
- buf.write("\6\6\6\36\n\6\r\6\16\6\37\5\6\"\n\6\3\7\3\7\6\7&\n\7\r")
- buf.write("\7\16\7\'\3\b\6\b+\n\b\r\b\16\b,\2\2\t\3\3\5\4\7\5\t\6")
- buf.write("\13\7\r\b\17\t\3\2\6\4\2,-AA\4\2*+}\177\6\2\"\"BB}}\177")
- buf.write("\177\6\2\62;C\\aac|\2\61\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3")
- buf.write("\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2")
- buf.write("\2\3\21\3\2\2\2\5\24\3\2\2\2\7\26\3\2\2\2\t\30\3\2\2\2")
- buf.write("\13!\3\2\2\2\r#\3\2\2\2\17*\3\2\2\2\21\22\7}\2\2\22\23")
- buf.write("\t\2\2\2\23\4\3\2\2\2\24\25\7}\2\2\25\6\3\2\2\2\26\27")
- buf.write("\7\177\2\2\27\b\3\2\2\2\30\31\7\'\2\2\31\32\t\3\2\2\32")
- buf.write("\n\3\2\2\2\33\"\7B\2\2\34\36\n\4\2\2\35\34\3\2\2\2\36")
- buf.write("\37\3\2\2\2\37\35\3\2\2\2\37 \3\2\2\2 \"\3\2\2\2!\33\3")
- buf.write("\2\2\2!\35\3\2\2\2\"\f\3\2\2\2#%\7B\2\2$&\t\5\2\2%$\3")
- buf.write("\2\2\2&\'\3\2\2\2\'%\3\2\2\2\'(\3\2\2\2(\16\3\2\2\2)+")
- buf.write("\7\"\2\2*)\3\2\2\2+,\3\2\2\2,*\3\2\2\2,-\3\2\2\2-\20\3")
- buf.write("\2\2\2\7\2\37!\',\2")
+ buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\n")
+ buf.write(":\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
+ buf.write("\4\b\t\b\4\t\t\t\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3")
+ buf.write("\5\3\6\3\6\6\6 \n\6\r\6\16\6!\5\6$\n\6\3\7\3\7\5\7(\n")
+ buf.write("\7\3\7\6\7+\n\7\r\7\16\7,\3\b\3\b\3\b\6\b\62\n\b\r\b\16")
+ buf.write("\b\63\3\t\6\t\67\n\t\r\t\16\t8\2\2\n\3\3\5\4\7\5\t\6\13")
+ buf.write("\7\r\b\17\t\21\n\3\2\7\4\2,-AA\4\2*+}\177\4\2BBaa\7\2")
+ buf.write("\"\"BBaa}}\177\177\5\2\62;C\\c|\2?\2\3\3\2\2\2\2\5\3\2")
+ buf.write("\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2")
+ buf.write("\2\17\3\2\2\2\2\21\3\2\2\2\3\23\3\2\2\2\5\26\3\2\2\2\7")
+ buf.write("\30\3\2\2\2\t\32\3\2\2\2\13#\3\2\2\2\r%\3\2\2\2\17.\3")
+ buf.write("\2\2\2\21\66\3\2\2\2\23\24\7}\2\2\24\25\t\2\2\2\25\4\3")
+ buf.write("\2\2\2\26\27\7}\2\2\27\6\3\2\2\2\30\31\7\177\2\2\31\b")
+ buf.write("\3\2\2\2\32\33\7\'\2\2\33\34\t\3\2\2\34\n\3\2\2\2\35$")
+ buf.write("\t\4\2\2\36 \n\5\2\2\37\36\3\2\2\2 !\3\2\2\2!\37\3\2\2")
+ buf.write("\2!\"\3\2\2\2\"$\3\2\2\2#\35\3\2\2\2#\37\3\2\2\2$\f\3")
+ buf.write("\2\2\2%*\7B\2\2&(\7a\2\2\'&\3\2\2\2\'(\3\2\2\2()\3\2\2")
+ buf.write("\2)+\t\6\2\2*\'\3\2\2\2+,\3\2\2\2,*\3\2\2\2,-\3\2\2\2")
+ buf.write("-\16\3\2\2\2./\7a\2\2/\61\7a\2\2\60\62\t\6\2\2\61\60\3")
+ buf.write("\2\2\2\62\63\3\2\2\2\63\61\3\2\2\2\63\64\3\2\2\2\64\20")
+ buf.write("\3\2\2\2\65\67\7\"\2\2\66\65\3\2\2\2\678\3\2\2\28\66\3")
+ buf.write("\2\2\289\3\2\2\29\22\3\2\2\2\t\2!#\',\638\2")
return buf.getvalue()
@@ -40,7 +44,8 @@ class TacticNotationsLexer(Lexer):
METACHAR = 4
ATOM = 5
ID = 6
- WHITESPACE = 7
+ SUB = 7
+ WHITESPACE = 8
channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
@@ -50,10 +55,11 @@ class TacticNotationsLexer(Lexer):
"'{'", "'}'" ]
symbolicNames = [ "<INVALID>",
- "LGROUP", "LBRACE", "RBRACE", "METACHAR", "ATOM", "ID", "WHITESPACE" ]
+ "LGROUP", "LBRACE", "RBRACE", "METACHAR", "ATOM", "ID", "SUB",
+ "WHITESPACE" ]
ruleNames = [ "LGROUP", "LBRACE", "RBRACE", "METACHAR", "ATOM", "ID",
- "WHITESPACE" ]
+ "SUB", "WHITESPACE" ]
grammarFileName = "TacticNotations.g"
diff --git a/doc/tools/coqrst/notations/TacticNotationsLexer.tokens b/doc/tools/coqrst/notations/TacticNotationsLexer.tokens
index 76ed2b065..88b38f97a 100644
--- a/doc/tools/coqrst/notations/TacticNotationsLexer.tokens
+++ b/doc/tools/coqrst/notations/TacticNotationsLexer.tokens
@@ -4,6 +4,7 @@ RBRACE=3
METACHAR=4
ATOM=5
ID=6
-WHITESPACE=7
+SUB=7
+WHITESPACE=8
'{'=2
'}'=3
diff --git a/doc/tools/coqrst/notations/TacticNotationsParser.py b/doc/tools/coqrst/notations/TacticNotationsParser.py
index c7e28af52..645f07897 100644
--- a/doc/tools/coqrst/notations/TacticNotationsParser.py
+++ b/doc/tools/coqrst/notations/TacticNotationsParser.py
@@ -7,29 +7,31 @@ import sys
def serializedATN():
with StringIO() as buf:
- buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\t")
- buf.write("F\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b")
+ buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\n")
+ buf.write("J\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b")
buf.write("\t\b\4\t\t\t\4\n\t\n\3\2\3\2\3\2\3\3\3\3\5\3\32\n\3\3")
buf.write("\3\7\3\35\n\3\f\3\16\3 \13\3\3\4\3\4\3\4\3\4\3\4\5\4\'")
buf.write("\n\4\3\5\3\5\5\5+\n\5\3\5\3\5\3\5\5\5\60\n\5\3\5\3\5\3")
buf.write("\6\3\6\5\6\66\n\6\3\6\3\6\5\6:\n\6\3\6\3\6\3\7\3\7\3\b")
- buf.write("\3\b\3\t\3\t\3\n\3\n\3\n\2\2\13\2\4\6\b\n\f\16\20\22\2")
- buf.write("\2\2F\2\24\3\2\2\2\4\27\3\2\2\2\6&\3\2\2\2\b(\3\2\2\2")
- buf.write("\n\63\3\2\2\2\f=\3\2\2\2\16?\3\2\2\2\20A\3\2\2\2\22C\3")
- buf.write("\2\2\2\24\25\5\4\3\2\25\26\7\2\2\3\26\3\3\2\2\2\27\36")
- buf.write("\5\6\4\2\30\32\5\f\7\2\31\30\3\2\2\2\31\32\3\2\2\2\32")
- buf.write("\33\3\2\2\2\33\35\5\6\4\2\34\31\3\2\2\2\35 \3\2\2\2\36")
- buf.write("\34\3\2\2\2\36\37\3\2\2\2\37\5\3\2\2\2 \36\3\2\2\2!\'")
- buf.write("\5\20\t\2\"\'\5\16\b\2#\'\5\22\n\2$\'\5\b\5\2%\'\5\n\6")
- buf.write("\2&!\3\2\2\2&\"\3\2\2\2&#\3\2\2\2&$\3\2\2\2&%\3\2\2\2")
- buf.write("\'\7\3\2\2\2(*\7\3\2\2)+\7\7\2\2*)\3\2\2\2*+\3\2\2\2+")
- buf.write(",\3\2\2\2,-\7\t\2\2-/\5\4\3\2.\60\7\t\2\2/.\3\2\2\2/\60")
- buf.write("\3\2\2\2\60\61\3\2\2\2\61\62\7\5\2\2\62\t\3\2\2\2\63\65")
- buf.write("\7\4\2\2\64\66\5\f\7\2\65\64\3\2\2\2\65\66\3\2\2\2\66")
- buf.write("\67\3\2\2\2\679\5\4\3\28:\5\f\7\298\3\2\2\29:\3\2\2\2")
- buf.write(":;\3\2\2\2;<\7\5\2\2<\13\3\2\2\2=>\7\t\2\2>\r\3\2\2\2")
- buf.write("?@\7\6\2\2@\17\3\2\2\2AB\7\7\2\2B\21\3\2\2\2CD\7\b\2\2")
- buf.write("D\23\3\2\2\2\t\31\36&*/\659")
+ buf.write("\3\b\3\t\3\t\5\tD\n\t\3\n\3\n\5\nH\n\n\3\n\2\2\13\2\4")
+ buf.write("\6\b\n\f\16\20\22\2\2\2L\2\24\3\2\2\2\4\27\3\2\2\2\6&")
+ buf.write("\3\2\2\2\b(\3\2\2\2\n\63\3\2\2\2\f=\3\2\2\2\16?\3\2\2")
+ buf.write("\2\20A\3\2\2\2\22E\3\2\2\2\24\25\5\4\3\2\25\26\7\2\2\3")
+ buf.write("\26\3\3\2\2\2\27\36\5\6\4\2\30\32\5\f\7\2\31\30\3\2\2")
+ buf.write("\2\31\32\3\2\2\2\32\33\3\2\2\2\33\35\5\6\4\2\34\31\3\2")
+ buf.write("\2\2\35 \3\2\2\2\36\34\3\2\2\2\36\37\3\2\2\2\37\5\3\2")
+ buf.write("\2\2 \36\3\2\2\2!\'\5\20\t\2\"\'\5\16\b\2#\'\5\22\n\2")
+ buf.write("$\'\5\b\5\2%\'\5\n\6\2&!\3\2\2\2&\"\3\2\2\2&#\3\2\2\2")
+ buf.write("&$\3\2\2\2&%\3\2\2\2\'\7\3\2\2\2(*\7\3\2\2)+\7\7\2\2*")
+ buf.write(")\3\2\2\2*+\3\2\2\2+,\3\2\2\2,-\7\n\2\2-/\5\4\3\2.\60")
+ buf.write("\7\n\2\2/.\3\2\2\2/\60\3\2\2\2\60\61\3\2\2\2\61\62\7\5")
+ buf.write("\2\2\62\t\3\2\2\2\63\65\7\4\2\2\64\66\5\f\7\2\65\64\3")
+ buf.write("\2\2\2\65\66\3\2\2\2\66\67\3\2\2\2\679\5\4\3\28:\5\f\7")
+ buf.write("\298\3\2\2\29:\3\2\2\2:;\3\2\2\2;<\7\5\2\2<\13\3\2\2\2")
+ buf.write("=>\7\n\2\2>\r\3\2\2\2?@\7\6\2\2@\17\3\2\2\2AC\7\7\2\2")
+ buf.write("BD\7\t\2\2CB\3\2\2\2CD\3\2\2\2D\21\3\2\2\2EG\7\b\2\2F")
+ buf.write("H\7\t\2\2GF\3\2\2\2GH\3\2\2\2H\23\3\2\2\2\13\31\36&*/")
+ buf.write("\659CG")
return buf.getvalue()
@@ -46,7 +48,7 @@ class TacticNotationsParser ( Parser ):
literalNames = [ "<INVALID>", "<INVALID>", "'{'", "'}'" ]
symbolicNames = [ "<INVALID>", "LGROUP", "LBRACE", "RBRACE", "METACHAR",
- "ATOM", "ID", "WHITESPACE" ]
+ "ATOM", "ID", "SUB", "WHITESPACE" ]
RULE_top = 0
RULE_blocks = 1
@@ -68,7 +70,8 @@ class TacticNotationsParser ( Parser ):
METACHAR=4
ATOM=5
ID=6
- WHITESPACE=7
+ SUB=7
+ WHITESPACE=8
def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
super().__init__(input, output)
@@ -502,6 +505,9 @@ class TacticNotationsParser ( Parser ):
def ATOM(self):
return self.getToken(TacticNotationsParser.ATOM, 0)
+ def SUB(self):
+ return self.getToken(TacticNotationsParser.SUB, 0)
+
def getRuleIndex(self):
return TacticNotationsParser.RULE_atomic
@@ -518,10 +524,19 @@ class TacticNotationsParser ( Parser ):
localctx = TacticNotationsParser.AtomicContext(self, self._ctx, self.state)
self.enterRule(localctx, 14, self.RULE_atomic)
+ self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
self.state = 63
self.match(TacticNotationsParser.ATOM)
+ self.state = 65
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la==TacticNotationsParser.SUB:
+ self.state = 64
+ self.match(TacticNotationsParser.SUB)
+
+
except RecognitionException as re:
localctx.exception = re
self._errHandler.reportError(self, re)
@@ -539,6 +554,9 @@ class TacticNotationsParser ( Parser ):
def ID(self):
return self.getToken(TacticNotationsParser.ID, 0)
+ def SUB(self):
+ return self.getToken(TacticNotationsParser.SUB, 0)
+
def getRuleIndex(self):
return TacticNotationsParser.RULE_hole
@@ -555,10 +573,19 @@ class TacticNotationsParser ( Parser ):
localctx = TacticNotationsParser.HoleContext(self, self._ctx, self.state)
self.enterRule(localctx, 16, self.RULE_hole)
+ self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 65
+ self.state = 67
self.match(TacticNotationsParser.ID)
+ self.state = 69
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la==TacticNotationsParser.SUB:
+ self.state = 68
+ self.match(TacticNotationsParser.SUB)
+
+
except RecognitionException as re:
localctx.exception = re
self._errHandler.reportError(self, re)
diff --git a/doc/tools/coqrst/notations/UbuntuMono-Square.ttf b/doc/tools/coqrst/notations/UbuntuMono-Square.ttf
deleted file mode 100644
index a53a9a0f0..000000000
--- a/doc/tools/coqrst/notations/UbuntuMono-Square.ttf
+++ /dev/null
Binary files differ
diff --git a/doc/tools/coqrst/notations/fontsupport.py b/doc/tools/coqrst/notations/fontsupport.py
index 3402ea2aa..a3efd97f5 100755
--- a/doc/tools/coqrst/notations/fontsupport.py
+++ b/doc/tools/coqrst/notations/fontsupport.py
@@ -63,8 +63,7 @@ def trim_font(fnt):
def center_glyphs(src_font_path, dst_font_path, dst_name):
fnt = trim_font(fontforge.open(src_font_path))
- size = max(max(g.width for g in fnt.glyphs()),
- max(glyph_height(g) for g in fnt.glyphs()))
+ size = max(g.width for g in fnt.glyphs())
fnt.ascent, fnt.descent = size, 0
for glyph in fnt.glyphs():
scale_single_glyph(glyph, size, size)
@@ -77,5 +76,5 @@ if __name__ == '__main__':
from os.path import dirname, join, abspath
curdir = dirname(abspath(__file__))
ubuntumono_path = join(curdir, "UbuntuMono-B.ttf")
- ubuntumono_mod_path = join(curdir, "UbuntuMono-Square.ttf")
- center_glyphs(ubuntumono_path, ubuntumono_mod_path, "UbuntuMono-Square")
+ ubuntumono_mod_path = join(curdir, "CoqNotations.ttf")
+ center_glyphs(ubuntumono_path, ubuntumono_mod_path, "CoqNotations")
diff --git a/doc/tools/coqrst/notations/html.py b/doc/tools/coqrst/notations/html.py
index 9c94a4b2d..87a41cf9f 100644
--- a/doc/tools/coqrst/notations/html.py
+++ b/doc/tools/coqrst/notations/html.py
@@ -41,6 +41,9 @@ class TacticNotationsToHTMLVisitor(TacticNotationsVisitor):
def visitHole(self, ctx:TacticNotationsParser.HoleContext):
tags.span(ctx.ID().getText()[1:], _class="hole")
+ sub = ctx.SUB()
+ if sub:
+ tags.sub(sub.getText()[1:])
def visitMeta(self, ctx:TacticNotationsParser.MetaContext):
txt = ctx.METACHAR().getText()[1:]
diff --git a/doc/tools/coqrst/notations/sphinx.py b/doc/tools/coqrst/notations/sphinx.py
index 26a5f6968..e05b83418 100644
--- a/doc/tools/coqrst/notations/sphinx.py
+++ b/doc/tools/coqrst/notations/sphinx.py
@@ -56,19 +56,36 @@ class TacticNotationsToSphinxVisitor(TacticNotationsVisitor):
def visitAtomic(self, ctx:TacticNotationsParser.AtomicContext):
atom = ctx.ATOM().getText()
- return [nodes.inline(atom, atom)]
+ sub = ctx.SUB()
+ node = nodes.inline(atom, atom)
+
+ if sub:
+ sub_index = sub.getText()[2:]
+ node += nodes.subscript(sub_index, sub_index)
+
+ return [node]
def visitHole(self, ctx:TacticNotationsParser.HoleContext):
hole = ctx.ID().getText()
token_name = hole[1:]
node = nodes.inline(hole, token_name, classes=["hole"])
+
+ sub = ctx.SUB()
+ if sub:
+ sub_index = sub.getText()[2:]
+ node += nodes.subscript(sub_index, sub_index)
+
return [addnodes.pending_xref(token_name, node, reftype='token', refdomain='std', reftarget=token_name)]
def visitMeta(self, ctx:TacticNotationsParser.MetaContext):
meta = ctx.METACHAR().getText()
metachar = meta[1:] # remove escape char
token_name = metachar
- return [nodes.inline(metachar, token_name, classes=["meta"])]
+ if (metachar == "{") or (metachar == "}"):
+ classes=[]
+ else:
+ classes=["meta"]
+ return [nodes.inline(metachar, token_name, classes=classes)]
def visitWhitespace(self, ctx:TacticNotationsParser.WhitespaceContext):
return [nodes.Text(" ")]
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 bd47a04f1..d30cb74d7 100644
--- a/engine/eConstr.ml
+++ b/engine/eConstr.ml
@@ -13,132 +13,8 @@ open Util
open Names
open Constr
open Context
-open Evd
-
-module API :
-sig
-module ESorts :
-sig
-type t
-val make : Sorts.t -> t
-val kind : Evd.evar_map -> t -> Sorts.t
-val unsafe_to_sorts : t -> Sorts.t
-end
-module EInstance :
-sig
-type t
-val make : Univ.Instance.t -> t
-val kind : Evd.evar_map -> t -> Univ.Instance.t
-val empty : t
-val is_empty : t -> bool
-val unsafe_to_instance : t -> Univ.Instance.t
-end
-type t
-val kind : Evd.evar_map -> t -> (t, t, ESorts.t, EInstance.t) Constr.kind_of_term
-val kind_upto : Evd.evar_map -> constr -> (constr, types, Sorts.t, Univ.Instance.t) Constr.kind_of_term
-val kind_of_type : Evd.evar_map -> t -> (t, t) Term.kind_of_type
-val whd_evar : Evd.evar_map -> t -> t
-val of_kind : (t, t, ESorts.t, EInstance.t) Constr.kind_of_term -> t
-val of_constr : Constr.t -> t
-val to_constr : evar_map -> t -> Constr.t
-val unsafe_to_constr : t -> Constr.t
-val unsafe_eq : (t, Constr.t) eq
-val of_named_decl : (Constr.t, Constr.types) Context.Named.Declaration.pt -> (t, t) Context.Named.Declaration.pt
-val unsafe_to_named_decl : (t, t) Context.Named.Declaration.pt -> (Constr.t, Constr.types) Context.Named.Declaration.pt
-val unsafe_to_rel_decl : (t, t) Context.Rel.Declaration.pt -> (Constr.t, Constr.types) Context.Rel.Declaration.pt
-val of_rel_decl : (Constr.t, Constr.types) Context.Rel.Declaration.pt -> (t, t) Context.Rel.Declaration.pt
-val to_rel_decl : Evd.evar_map -> (t, t) Context.Rel.Declaration.pt -> (Constr.t, Constr.types) Context.Rel.Declaration.pt
-end =
-struct
-
-module ESorts =
-struct
- type t = Sorts.t
- let make s = s
- let kind sigma = function
- | Sorts.Type u -> Sorts.sort_of_univ (Evd.normalize_universe sigma u)
- | s -> s
- let unsafe_to_sorts s = s
-end
-
-module EInstance =
-struct
- type t = Univ.Instance.t
- let make i = i
- let kind sigma i =
- if Univ.Instance.is_empty i then i
- else Evd.normalize_universe_instance sigma i
- let empty = Univ.Instance.empty
- let is_empty = Univ.Instance.is_empty
- let unsafe_to_instance t = t
-end
-type t = Constr.t
-
-let safe_evar_value sigma ev =
- try Some (Evd.existential_value sigma ev)
- with NotInstantiatedEvar | Not_found -> None
-
-let rec whd_evar sigma c =
- match Constr.kind c with
- | Evar ev ->
- begin match safe_evar_value sigma ev with
- | Some c -> whd_evar sigma c
- | None -> c
- end
- | App (f, args) when isEvar f ->
- (** Enforce smart constructor invariant on applications *)
- let ev = destEvar f in
- begin match safe_evar_value sigma ev with
- | None -> c
- | Some f -> whd_evar sigma (mkApp (f, args))
- end
- | Cast (c0, k, t) when isEvar c0 ->
- (** Enforce smart constructor invariant on casts. *)
- let ev = destEvar c0 in
- begin match safe_evar_value sigma ev with
- | None -> c
- | Some c -> whd_evar sigma (mkCast (c, k, t))
- end
- | _ -> c
-
-let kind sigma c = Constr.kind (whd_evar sigma c)
-let kind_upto = kind
-let kind_of_type sigma c = Term.kind_of_type (whd_evar sigma c)
-let of_kind = Constr.of_kind
-let of_constr c = c
-let unsafe_to_constr c = c
-let unsafe_eq = Refl
-
-let rec to_constr sigma c = match Constr.kind c with
-| Evar ev ->
- begin match safe_evar_value sigma ev with
- | Some c -> to_constr sigma c
- | None -> Constr.map (fun c -> to_constr sigma c) c
- end
-| Sort (Sorts.Type u) ->
- let u' = Evd.normalize_universe sigma u in
- if u' == u then c else mkSort (Sorts.sort_of_univ u')
-| Const (c', u) when not (Univ.Instance.is_empty u) ->
- let u' = Evd.normalize_universe_instance sigma u in
- if u' == u then c else mkConstU (c', u')
-| Ind (i, u) when not (Univ.Instance.is_empty u) ->
- let u' = Evd.normalize_universe_instance sigma u in
- if u' == u then c else mkIndU (i, u')
-| Construct (co, u) when not (Univ.Instance.is_empty u) ->
- let u' = Evd.normalize_universe_instance sigma u in
- if u' == u then c else mkConstructU (co, u')
-| _ -> Constr.map (fun c -> to_constr sigma c) c
-
-let of_named_decl d = d
-let unsafe_to_named_decl d = d
-let of_rel_decl d = d
-let unsafe_to_rel_decl d = d
-let to_rel_decl sigma d = Context.Rel.Declaration.map_constr (to_constr sigma) d
-
-end
-
-include API
+include Evd.MiniEConstr
type types = t
type constr = t
@@ -381,8 +257,7 @@ let decompose_prod_n_assum sigma n c =
in
prodec_rec Context.Rel.empty n c
-let existential_type sigma (evk, args) =
- of_constr (existential_type sigma (evk, Array.map unsafe_to_constr args))
+let existential_type = Evd.existential_type
let map sigma f c = match kind sigma c with
| (Rel _ | Meta _ | Var _ | Sort _ | Const _ | Ind _
@@ -625,6 +500,7 @@ let eq_universes env sigma cstrs cv_pb ref nargs l l' =
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
match ref with
| VarRef _ -> assert false (* variables don't have instances *)
| ConstRef _ ->
@@ -743,7 +619,7 @@ let universes_of_constr env sigma c =
LSet.fold LSet.add (Universe.levels u) s
| Evar (k, args) ->
let concl = Evd.evar_concl (Evd.find sigma k) in
- fold sigma aux (aux s (of_constr concl)) c
+ fold sigma aux (aux s concl) c
| _ -> fold sigma aux s c
in aux LSet.empty c
@@ -901,6 +777,10 @@ let named_context e = cast_named_context (sym unsafe_eq) (named_context e)
let val_of_named_context e = val_of_named_context (cast_named_context unsafe_eq e)
let named_context_of_val e = cast_named_context (sym unsafe_eq) (named_context_of_val e)
+let of_existential : Constr.existential -> existential =
+ let gen : type a b. (a,b) eq -> 'c * b array -> 'c * a array = fun Refl x -> x in
+ gen unsafe_eq
+
let lookup_rel i e = cast_rel_decl (sym unsafe_eq) (lookup_rel i e)
let lookup_named n e = cast_named_decl (sym unsafe_eq) (lookup_named n e)
let lookup_named_val n e = cast_named_decl (sym unsafe_eq) (lookup_named_val n e)
@@ -916,7 +796,7 @@ let map_rel_context_in_env f env sign =
let fresh_global ?loc ?rigid ?names env sigma reference =
let (evd,t) = Evd.fresh_global ?loc ?rigid ?names env sigma reference in
- evd, of_constr t
+ evd, t
let is_global sigma gr c =
Globnames.is_global gr (to_constr sigma c)
@@ -928,5 +808,10 @@ let to_instance = EInstance.unsafe_to_instance
let to_constr = unsafe_to_constr
let to_rel_decl = unsafe_to_rel_decl
let to_named_decl = unsafe_to_named_decl
+let to_named_context =
+ let gen : type a b. (a, b) eq -> (a,a) Context.Named.pt -> (b,b) Context.Named.pt
+ = fun Refl x -> x
+ in
+ gen unsafe_eq
let eq = unsafe_eq
end
diff --git a/engine/eConstr.mli b/engine/eConstr.mli
index 28c9dd3c2..743888a9b 100644
--- a/engine/eConstr.mli
+++ b/engine/eConstr.mli
@@ -13,7 +13,7 @@ open Names
open Constr
open Environ
-type t
+type t = Evd.econstr
(** Type of incomplete terms. Essentially a wrapper around {!Constr.t} ensuring
that {!Constr.kind} does not observe defined evars. *)
@@ -68,11 +68,14 @@ val kind : Evd.evar_map -> t -> (t, t, ESorts.t, EInstance.t) Constr.kind_of_ter
val kind_upto : Evd.evar_map -> Constr.t -> (Constr.t, Constr.t, Sorts.t, Univ.Instance.t) Constr.kind_of_term
-val to_constr : Evd.evar_map -> t -> Constr.t
-(** Returns the evar-normal form of the argument, and cast it as a theoretically
- evar-free term. In practice this function does not check that the result
- is actually evar-free, it is currently the duty of the caller to do so.
- This might change in the future. *)
+val to_constr : ?abort_on_undefined_evars:bool -> Evd.evar_map -> t -> Constr.t
+(** Returns the evar-normal form of the argument. Note that this
+ function is supposed to be called when the original term has not
+ more free-evars anymore. If you need compatibility with the old
+ semantics, set [abort_on_undefined_evars] to [false].
+
+ For getting the evar-normal form of a term with evars see
+ {!Evarutil.nf_evar}. *)
val kind_of_type : Evd.evar_map -> t -> (t, t) Term.kind_of_type
@@ -108,7 +111,7 @@ val mkLetIn : Name.t * t * t * t -> t
val mkApp : t * t array -> t
val mkConst : Constant.t -> t
val mkConstU : Constant.t * EInstance.t -> t
-val mkProj : (projection * t) -> t
+val mkProj : (Projection.t * t) -> t
val mkInd : inductive -> t
val mkIndU : inductive * EInstance.t -> t
val mkConstruct : constructor -> t
@@ -173,7 +176,7 @@ val destEvar : Evd.evar_map -> t -> t pexistential
val destInd : Evd.evar_map -> t -> inductive * EInstance.t
val destConstruct : Evd.evar_map -> t -> constructor * EInstance.t
val destCase : Evd.evar_map -> t -> case_info * t * t * t array
-val destProj : Evd.evar_map -> t -> projection * t
+val destProj : Evd.evar_map -> t -> Projection.t * t
val destFix : Evd.evar_map -> t -> (t, t) pfixpoint
val destCoFix : Evd.evar_map -> t -> (t, t) pcofixpoint
@@ -281,12 +284,13 @@ val map_rel_context_in_env :
(* XXX Missing Sigma proxy *)
val fresh_global :
?loc:Loc.t -> ?rigid:Evd.rigid -> ?names:Univ.Instance.t -> Environ.env ->
- Evd.evar_map -> Globnames.global_reference -> Evd.evar_map * t
+ Evd.evar_map -> GlobRef.t -> Evd.evar_map * t
-val is_global : Evd.evar_map -> Globnames.global_reference -> t -> bool
+val is_global : Evd.evar_map -> GlobRef.t -> t -> bool
(** {5 Extra} *)
+val of_existential : Constr.existential -> existential
val of_named_decl : (Constr.t, Constr.types) Context.Named.Declaration.pt -> (t, types) Context.Named.Declaration.pt
val of_rel_decl : (Constr.t, Constr.types) Context.Rel.Declaration.pt -> (t, types) Context.Rel.Declaration.pt
@@ -305,6 +309,8 @@ sig
val to_named_decl : (t, types) Context.Named.Declaration.pt -> (Constr.t, Constr.types) Context.Named.Declaration.pt
(** Physical identity. Does not care for defined evars. *)
+ val to_named_context : (t, types) Context.Named.pt -> Context.Named.t
+
val to_sorts : ESorts.t -> Sorts.t
(** Physical identity. Does not care for normalization. *)
diff --git a/engine/engine.mllib b/engine/engine.mllib
index a3614f6c4..a5df5a9fa 100644
--- a/engine/engine.mllib
+++ b/engine/engine.mllib
@@ -2,6 +2,7 @@ Universes
Univops
UState
Nameops
+Evar_kinds
Evd
EConstr
Namegen
diff --git a/intf/evar_kinds.ml b/engine/evar_kinds.ml
index c964ecf1f..6e123d642 100644
--- a/intf/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 45760c6b4..6c27d5937 100644
--- a/engine/evarutil.ml
+++ b/engine/evarutil.ml
@@ -23,7 +23,8 @@ module RelDecl = Context.Rel.Declaration
module NamedDecl = Context.Named.Declaration
let safe_evar_value sigma ev =
- try Some (Evd.existential_value sigma ev)
+ let ev = EConstr.of_existential ev in
+ try Some (EConstr.Unsafe.to_constr @@ Evd.existential_value sigma ev)
with NotInstantiatedEvar | Not_found -> None
(** Combinators *)
@@ -44,11 +45,11 @@ let evd_comb2 f evdref x y =
z
let e_new_global evdref x =
- EConstr.of_constr (evd_comb1 (Evd.fresh_global (Global.env())) evdref x)
+ evd_comb1 (Evd.fresh_global (Global.env())) evdref x
let new_global evd x =
let (evd, c) = Evd.fresh_global (Global.env()) evd x in
- (evd, EConstr.of_constr c)
+ (evd, c)
(****************************************************)
(* Expanding/testing/exposing existential variables *)
@@ -61,7 +62,7 @@ exception Uninstantiated_evar of Evar.t
let rec flush_and_check_evars sigma c =
match kind c with
| Evar (evk,_ as ev) ->
- (match existential_opt_value sigma ev with
+ (match existential_opt_value0 sigma ev with
| None -> raise (Uninstantiated_evar evk)
| Some c -> flush_and_check_evars sigma c)
| _ -> Constr.map (flush_and_check_evars sigma) c
@@ -72,9 +73,9 @@ let flush_and_check_evars sigma c =
(** Term exploration up to instantiation. *)
let kind_of_term_upto = EConstr.kind_upto
-let nf_evar0 sigma t = EConstr.to_constr sigma (EConstr.of_constr t)
+let nf_evar0 sigma t = EConstr.to_constr ~abort_on_undefined_evars:false sigma (EConstr.of_constr t)
let whd_evar = EConstr.whd_evar
-let nf_evar sigma c = EConstr.of_constr (EConstr.to_constr sigma c)
+let nf_evar sigma c = EConstr.of_constr (EConstr.to_constr ~abort_on_undefined_evars:false sigma c)
let j_nf_evar sigma j =
{ uj_val = nf_evar sigma j.uj_val;
@@ -102,7 +103,8 @@ let nf_evar_map_universes evm =
if Univ.LMap.is_empty subst then evm, nf_evar0 evm
else
let f = nf_evars_universes evm in
- Evd.raw_map (fun _ -> map_evar_info f) evm, f
+ let f' c = EConstr.of_constr (f (EConstr.Unsafe.to_constr c)) in
+ Evd.raw_map (fun _ -> map_evar_info f') evm, f
let nf_named_context_evar sigma ctx =
Context.Named.map (nf_evar0 sigma) ctx
@@ -115,7 +117,7 @@ let nf_env_evar sigma env =
let rel' = nf_rel_context_evar sigma (EConstr.rel_context env) in
EConstr.push_rel_context rel' (reset_with_named_context (val_of_named_context nc') env)
-let nf_evar_info evc info = map_evar_info (nf_evar0 evc) info
+let nf_evar_info evc info = map_evar_info (nf_evar evc) info
let nf_evar_map evm =
Evd.raw_map (fun _ evi -> nf_evar_info evm evi) evm
@@ -340,7 +342,15 @@ let update_var src tgt subst =
let csubst_var = Id.Map.add id (Constr.mkVar tgt) subst.csubst_var in
{ subst with csubst_var; csubst_rev }
-let push_rel_decl_to_named_context sigma decl (subst, avoid, nc) =
+type naming_mode =
+ | KeepUserNameAndRenameExistingButSectionNames
+ | KeepUserNameAndRenameExistingEvenSectionNames
+ | KeepExistingNames
+ | FailIfConflict
+
+let push_rel_decl_to_named_context
+ ?(hypnaming=KeepUserNameAndRenameExistingButSectionNames)
+ sigma decl (subst, avoid, nc) =
let open EConstr in
let open Vars in
let map_decl f d =
@@ -371,7 +381,9 @@ let push_rel_decl_to_named_context sigma decl (subst, avoid, nc) =
next_ident_away (id_of_name_using_hdchar empty_env sigma (RelDecl.get_type decl) na) avoid
in
match extract_if_neq id na with
- | Some id0 when not (is_section_variable id0) ->
+ | Some id0 when hypnaming = KeepUserNameAndRenameExistingEvenSectionNames ||
+ hypnaming = KeepUserNameAndRenameExistingButSectionNames &&
+ not (is_section_variable id0) ->
(* spiwack: if [id<>id0], rather than introducing a new
binding named [id], we will keep [id0] (the name given
by the user) and rename [id0] into [id] in the named
@@ -380,6 +392,8 @@ let push_rel_decl_to_named_context sigma decl (subst, avoid, nc) =
let d = decl |> NamedDecl.of_rel_decl (fun _ -> id0) |> map_decl (csubst_subst subst) in
let nc = List.map (replace_var_named_declaration id0 id) nc in
(push_var id0 subst, Id.Set.add id avoid, d :: nc)
+ | Some id0 when hypnaming = FailIfConflict ->
+ user_err Pp.(Id.print id0 ++ str " is already used.")
| _ ->
(* spiwack: if [id0] is a section variable renaming it is
incorrect. We revert to a less robust behaviour where
@@ -388,7 +402,7 @@ let push_rel_decl_to_named_context sigma decl (subst, avoid, nc) =
let d = decl |> NamedDecl.of_rel_decl (fun _ -> id) |> map_decl (csubst_subst subst) in
(push_var id subst, Id.Set.add id avoid, d :: nc)
-let push_rel_context_to_named_context env sigma typ =
+let push_rel_context_to_named_context ?hypnaming env sigma typ =
(* compute the instances relative to the named context and rel_context *)
let open Context.Named.Declaration in
let open EConstr in
@@ -403,7 +417,7 @@ let push_rel_context_to_named_context env sigma typ =
(* with vars of the rel context *)
(* We do keep the instances corresponding to local definition (see above) *)
let (subst, _, env) =
- Context.Rel.fold_outside (fun d acc -> push_rel_decl_to_named_context sigma d acc)
+ Context.Rel.fold_outside (fun d acc -> push_rel_decl_to_named_context ?hypnaming sigma d acc)
(rel_context env) ~init:(empty_csubst, avoid, named_context env) in
(val_of_named_context env, csubst_subst subst typ, inst_rels@inst_vars, subst)
@@ -414,7 +428,6 @@ let push_rel_context_to_named_context env sigma typ =
let default_source = Loc.tag @@ Evar_kinds.InternalHole
let restrict_evar evd evk filter ?src candidates =
- let candidates = Option.map (fun l -> List.map EConstr.Unsafe.to_constr l) candidates in
let evd, evk' = Evd.restrict evk filter ?candidates ?src evd in
Evd.declare_future_goal evk' evd, evk'
@@ -424,8 +437,6 @@ let new_pure_evar_full evd evi =
(evd, evk)
let new_pure_evar sign evd ?(src=default_source) ?(filter = Filter.identity) ?candidates ?(store = Store.empty) ?naming ?(principal=false) typ =
- let typ = EConstr.Unsafe.to_constr typ in
- let candidates = Option.map (fun l -> List.map EConstr.Unsafe.to_constr l) candidates in
let default_naming = Misctypes.IntroAnonymous in
let naming = Option.default default_naming naming in
let name = match naming with
@@ -469,8 +480,8 @@ let new_evar_from_context sign evd ?src ?filter ?candidates ?store ?naming ?prin
(* [new_evar] declares a new existential in an env env with type typ *)
(* Converting the env into the sign of the evar to define *)
-let new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
- let sign,typ',instance,subst = push_rel_context_to_named_context env evd typ in
+let new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal ?hypnaming typ =
+ let sign,typ',instance,subst = push_rel_context_to_named_context ?hypnaming env evd typ in
let map c = csubst_subst subst c in
let candidates = Option.map (fun l -> List.map map l) candidates in
let instance =
@@ -479,13 +490,13 @@ let new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
| Some filter -> Filter.filter_list filter instance in
new_evar_instance sign evd typ' ?src ?filter ?candidates ?store ?naming ?principal instance
-let new_type_evar env evd ?src ?filter ?naming ?principal rigid =
+let new_type_evar env evd ?src ?filter ?naming ?principal ?hypnaming rigid =
let (evd', s) = new_sort_variable rigid evd in
- let (evd', e) = new_evar env evd' ?src ?filter ?naming ?principal (EConstr.mkSort s) in
+ let (evd', e) = new_evar env evd' ?src ?filter ?naming ?principal ?hypnaming (EConstr.mkSort s) in
evd', (e, s)
-let e_new_type_evar env evdref ?src ?filter ?naming ?principal rigid =
- let (evd, c) = new_type_evar env !evdref ?src ?filter ?naming ?principal rigid in
+let e_new_type_evar env evdref ?src ?filter ?naming ?principal ?hypnaming rigid =
+ let (evd, c) = new_type_evar env !evdref ?src ?filter ?naming ?principal ?hypnaming rigid in
evdref := evd;
c
@@ -499,8 +510,8 @@ let e_new_Type ?(rigid=Evd.univ_flexible) env evdref =
evdref := evd'; EConstr.mkSort s
(* The same using side-effect *)
-let e_new_evar env evdref ?(src=default_source) ?filter ?candidates ?store ?naming ?principal ty =
- let (evd',ev) = new_evar env !evdref ~src:src ?filter ?candidates ?store ?naming ?principal ty in
+let e_new_evar env evdref ?(src=default_source) ?filter ?candidates ?store ?naming ?principal ?hypnaming ty =
+ let (evd',ev) = new_evar env !evdref ~src:src ?filter ?candidates ?store ?naming ?principal ?hypnaming ty in
evdref := evd';
ev
@@ -513,7 +524,7 @@ let generalize_evar_over_rels sigma (ev,args) =
List.fold_left2
(fun (c,inst as x) a d ->
if isRel sigma a then (mkNamedProd_or_LetIn d c,a::inst) else x)
- (EConstr.of_constr evi.evar_concl,[]) (Array.to_list args) sign
+ (evi.evar_concl,[]) (Array.to_list args) sign
(************************************)
(* Removing a dependency in an evar *)
@@ -523,7 +534,7 @@ type clear_dependency_error =
| OccurHypInSimpleClause of Id.t option
| EvarTypingBreak of existential
-exception ClearDependencyError of Id.t * clear_dependency_error
+exception ClearDependencyError of Id.t * clear_dependency_error * GlobRef.t option
exception Depends of Id.t
@@ -534,13 +545,13 @@ let rec check_and_clear_in_constr env evdref err ids global c =
is a section variable *)
match kind c with
| Var id' ->
- if Id.Set.mem id' ids then raise (ClearDependencyError (id', err)) else c
+ if Id.Set.mem id' ids then raise (ClearDependencyError (id', err, None)) else c
| ( Const _ | Ind _ | Construct _ ) ->
let () = if global then
let check id' =
if Id.Set.mem id' ids then
- raise (ClearDependencyError (id',err))
+ raise (ClearDependencyError (id',err,Some (Globnames.global_of_constr c)))
in
Id.Set.iter check (Environ.vars_of_global env c)
in
@@ -549,7 +560,8 @@ let rec check_and_clear_in_constr env evdref err ids global c =
| Evar (evk,l as ev) ->
if Evd.is_defined !evdref evk then
(* If evk is already defined we replace it by its definition *)
- let nc = Evd.existential_value !evdref ev in
+ let nc = Evd.existential_value !evdref (EConstr.of_existential ev) in
+ let nc = EConstr.Unsafe.to_constr nc in
(check_and_clear_in_constr env evdref err ids global nc)
else
(* We check for dependencies to elements of ids in the
@@ -559,8 +571,7 @@ let rec check_and_clear_in_constr env evdref err ids global c =
removed *)
let evi = Evd.find_undefined !evdref evk in
let ctxt = Evd.evar_filtered_context evi in
- let ctxt = List.map (fun d -> map_named_decl EConstr.of_constr d) ctxt in
- let (rids,filter) =
+ let (rids,filter) =
List.fold_right2
(fun h a (ri,filter) ->
try
@@ -586,9 +597,10 @@ let rec check_and_clear_in_constr env evdref err ids global c =
try
let nids = Id.Map.domain rids in
let global = Id.Set.exists is_section_variable nids in
- check_and_clear_in_constr env evdref (EvarTypingBreak ev) nids global (evar_concl evi)
- with ClearDependencyError (rid,err) ->
- raise (ClearDependencyError (Id.Map.find rid rids,err)) in
+ let concl = EConstr.Unsafe.to_constr (evar_concl evi) in
+ check_and_clear_in_constr env evdref (EvarTypingBreak ev) nids global concl
+ with ClearDependencyError (rid,err,where) ->
+ raise (ClearDependencyError (Id.Map.find rid rids,err,where)) in
if Id.Map.is_empty rids then c
else
@@ -597,7 +609,7 @@ let rec check_and_clear_in_constr env evdref err ids global c =
let evd = !evdref in
let (evd,_) = restrict_evar evd evk filter None in
evdref := evd;
- Evd.existential_value !evdref ev
+ Evd.existential_value0 !evdref ev
| _ -> Constr.map (check_and_clear_in_constr env evdref err ids global) c
@@ -643,7 +655,7 @@ let clear_hyps2_in_evi env evdref hyps t concl ids =
let queue_set q is_dependent set =
Evar.Set.iter (fun a -> Queue.push (is_dependent,a) q) set
let queue_term q is_dependent c =
- queue_set q is_dependent (evars_of_term c)
+ queue_set q is_dependent (evars_of_term (EConstr.Unsafe.to_constr c))
let process_dependent_evar q acc evm is_dependent e =
let evi = Evd.find evm e in
@@ -656,12 +668,12 @@ let process_dependent_evar q acc evm is_dependent e =
match decl with
| LocalAssum _ -> ()
| LocalDef (_,b,_) -> queue_term q true b
- end (Environ.named_context_of_val evi.evar_hyps);
+ end (EConstr.named_context_of_val evi.evar_hyps);
match evi.evar_body with
| Evar_empty ->
if is_dependent then Evar.Map.add e None acc else acc
| Evar_defined b ->
- let subevars = evars_of_term b in
+ let subevars = evars_of_term (EConstr.Unsafe.to_constr b) in
(* evars appearing in the definition of an evar [e] are marked
as dependent when [e] is dependent itself: if [e] is a
non-dependent goal, then, unless they are reach from another
@@ -729,11 +741,11 @@ let undefined_evars_of_named_context evd nc =
~init:Evar.Set.empty
let undefined_evars_of_evar_info evd evi =
- Evar.Set.union (undefined_evars_of_term evd (EConstr.of_constr evi.evar_concl))
+ Evar.Set.union (undefined_evars_of_term evd evi.evar_concl)
(Evar.Set.union
(match evi.evar_body with
| Evar_empty -> Evar.Set.empty
- | Evar_defined b -> undefined_evars_of_term evd (EConstr.of_constr b))
+ | Evar_defined b -> undefined_evars_of_term evd b)
(undefined_evars_of_named_context evd
(named_context_of_val evi.evar_hyps)))
@@ -781,10 +793,11 @@ let filtered_undefined_evars_of_evar_info ?cache sigma evi =
in
let accu = match evi.evar_body with
| Evar_empty -> Evar.Set.empty
- | Evar_defined b -> evars_of_term b
+ | Evar_defined b -> evars_of_term (EConstr.Unsafe.to_constr b)
in
- let accu = Evar.Set.union (undefined_evars_of_term sigma (EConstr.of_constr evi.evar_concl)) accu in
- evars_of_named_context cache accu (evar_filtered_context evi)
+ let accu = Evar.Set.union (undefined_evars_of_term sigma evi.evar_concl) accu in
+ let ctxt = EConstr.Unsafe.to_named_context (evar_filtered_context evi) in
+ evars_of_named_context cache accu ctxt
(* spiwack: this is a more complete version of
{!Termops.occur_evar}. The latter does not look recursively into an
@@ -794,7 +807,7 @@ let occur_evar_upto sigma n c =
let c = EConstr.Unsafe.to_constr c in
let rec occur_rec c = match kind c with
| Evar (sp,_) when Evar.equal sp n -> raise Occur
- | Evar e -> Option.iter occur_rec (existential_opt_value sigma e)
+ | Evar e -> Option.iter occur_rec (existential_opt_value0 sigma e)
| _ -> Constr.iter occur_rec c
in
try occur_rec c; false with Occur -> true
@@ -849,6 +862,8 @@ let compare_constructor_instances evd u u' =
let eq_constr_univs_test sigma1 sigma2 t u =
(* spiwack: mild code duplication with {!Evd.eq_constr_univs}. *)
let open Evd in
+ let t = EConstr.Unsafe.to_constr t
+ and u = EConstr.Unsafe.to_constr u in
let fold cstr sigma =
try Some (add_universe_constraints sigma cstr)
with Univ.UniverseInconsistency _ | UniversesDiffer -> None
diff --git a/engine/evarutil.mli b/engine/evarutil.mli
index 972b0b9e1..3bbd2923c 100644
--- a/engine/evarutil.mli
+++ b/engine/evarutil.mli
@@ -30,11 +30,17 @@ val new_evar_from_context :
?naming:Misctypes.intro_pattern_naming_expr ->
?principal:bool -> types -> evar_map * EConstr.t
+type naming_mode =
+ | KeepUserNameAndRenameExistingButSectionNames
+ | KeepUserNameAndRenameExistingEvenSectionNames
+ | KeepExistingNames
+ | FailIfConflict
+
val new_evar :
env -> evar_map -> ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
?candidates:constr list -> ?store:Store.t ->
?naming:Misctypes.intro_pattern_naming_expr ->
- ?principal:bool -> types -> evar_map * EConstr.t
+ ?principal:bool -> ?hypnaming:naming_mode -> types -> evar_map * EConstr.t
val new_pure_evar :
named_context_val -> evar_map -> ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
@@ -49,18 +55,20 @@ val e_new_evar :
env -> evar_map ref -> ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
?candidates:constr list -> ?store:Store.t ->
?naming:Misctypes.intro_pattern_naming_expr ->
- ?principal:bool -> types -> constr
+ ?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 -> rigid ->
+ ?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 -> rigid -> constr * Sorts.t
+ ?naming:Misctypes.intro_pattern_naming_expr ->
+ ?principal:bool -> ?hypnaming:naming_mode -> rigid -> constr * Sorts.t
val new_Type : ?rigid:rigid -> env -> evar_map -> evar_map * constr
val e_new_Type : ?rigid:rigid -> env -> evar_map ref -> constr
@@ -70,8 +78,8 @@ val restrict_evar : evar_map -> Evar.t -> Filter.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
+val e_new_global : evar_map ref -> GlobRef.t -> 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
@@ -178,11 +186,14 @@ val nf_evar_map_undefined : evar_map -> evar_map
val nf_evars_universes : evar_map -> Constr.constr -> Constr.constr
val nf_evars_and_universes : evar_map -> evar_map * (Constr.constr -> Constr.constr)
+[@@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. *)
val nf_evar_map_universes : evar_map -> evar_map * (Constr.constr -> Constr.constr)
+[@@ocaml.deprecated "Use Evd.minimize_universes and nf_evar_map and nf_evars_universes"]
(** Replacing all evars, possibly raising [Uninstantiated_evar] *)
exception Uninstantiated_evar of Evar.t
@@ -201,7 +212,7 @@ val kind_of_term_upto : evar_map -> Constr.constr ->
universes. The term [t] is interpreted in [sigma1] while [u] is
interpreted in [sigma2]. The universe constraints in [sigma2] are
assumed to be an extention of those in [sigma1]. *)
-val eq_constr_univs_test : evar_map -> evar_map -> Constr.constr -> Constr.constr -> bool
+val eq_constr_univs_test : evar_map -> evar_map -> constr -> constr -> bool
(** [compare_cumulative_instances cv_pb variance u1 u2 sigma] Returns
[Inl sigma'] where [sigma'] is [sigma] augmented with universe
@@ -224,7 +235,7 @@ type clear_dependency_error =
| OccurHypInSimpleClause of Id.t option
| EvarTypingBreak of Constr.existential
-exception ClearDependencyError of Id.t * clear_dependency_error
+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
@@ -240,10 +251,11 @@ val csubst_subst : csubst -> constr -> constr
type ext_named_context =
csubst * Id.Set.t * named_context
-val push_rel_decl_to_named_context :
+val push_rel_decl_to_named_context : ?hypnaming:naming_mode ->
evar_map -> rel_declaration -> ext_named_context -> ext_named_context
-val push_rel_context_to_named_context : Environ.env -> evar_map -> types ->
+val push_rel_context_to_named_context : ?hypnaming:naming_mode ->
+ Environ.env -> evar_map -> types ->
named_context_val * types * constr list * csubst
val generalize_evar_over_rels : evar_map -> existential -> types * constr list
diff --git a/engine/evd.ml b/engine/evd.ml
index f6e13e1f4..af22de5cd 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -21,6 +21,9 @@ open Environ
(* module RelDecl = Context.Rel.Declaration *)
module NamedDecl = Context.Named.Declaration
+type econstr = constr
+type etypes = types
+
(** Generic filters *)
module Filter :
sig
@@ -537,10 +540,14 @@ let existential_value d (n, args) =
| Evar_empty ->
raise NotInstantiatedEvar
+let existential_value0 = existential_value
+
let existential_opt_value d ev =
try Some (existential_value d ev)
with NotInstantiatedEvar -> None
+let existential_opt_value0 = existential_opt_value
+
let existential_type d (n, args) =
let info =
try find d n
@@ -548,6 +555,8 @@ let existential_type d (n, args) =
anomaly (str "Evar " ++ str (string_of_existential n) ++ str " was not declared.") in
instantiate_evar_array info info.evar_concl args
+let existential_type0 = existential_type
+
let add_constraints d c =
{ d with universes = UState.add_constraints d.universes c }
@@ -1065,6 +1074,7 @@ let meta_ftype evd mv =
| Clval(_,_,b) -> b
let meta_type evd mv = (meta_ftype evd mv).rebus
+let meta_type0 = meta_type
let meta_declare mv v ?(name=Anonymous) evd =
let metas = Metamap.add mv (Cltyp(name,mk_freelisted v)) evd.metas in
@@ -1217,3 +1227,82 @@ let normalize_evar_universe_context_variables = UState.normalize_variables
let abstract_undefined_variables = UState.abstract_undefined_variables
let normalize_evar_universe_context = UState.minimize
let nf_constraints = minimize_universes
+
+module MiniEConstr = struct
+
+ module ESorts =
+ struct
+ type t = Sorts.t
+ let make s = s
+ let kind sigma = function
+ | Sorts.Type u -> Sorts.sort_of_univ (normalize_universe sigma u)
+ | s -> s
+ let unsafe_to_sorts s = s
+ end
+
+ module EInstance =
+ struct
+ type t = Univ.Instance.t
+ let make i = i
+ let kind sigma i =
+ if Univ.Instance.is_empty i then i
+ else normalize_universe_instance sigma i
+ let empty = Univ.Instance.empty
+ let is_empty = Univ.Instance.is_empty
+ let unsafe_to_instance t = t
+ end
+
+ type t = econstr
+
+ let safe_evar_value sigma ev =
+ try Some (existential_value sigma ev)
+ with NotInstantiatedEvar | Not_found -> None
+
+ let rec whd_evar sigma c =
+ match Constr.kind c with
+ | Evar ev ->
+ begin match safe_evar_value sigma ev with
+ | Some c -> whd_evar sigma c
+ | None -> c
+ end
+ | App (f, args) when isEvar f ->
+ (** Enforce smart constructor invariant on applications *)
+ let ev = destEvar f in
+ begin match safe_evar_value sigma ev with
+ | None -> c
+ | Some f -> whd_evar sigma (mkApp (f, args))
+ end
+ | Cast (c0, k, t) when isEvar c0 ->
+ (** Enforce smart constructor invariant on casts. *)
+ let ev = destEvar c0 in
+ begin match safe_evar_value sigma ev with
+ | None -> c
+ | Some c -> whd_evar sigma (mkCast (c, k, t))
+ end
+ | _ -> c
+
+ let kind sigma c = Constr.kind (whd_evar sigma c)
+ let kind_upto = kind
+ let kind_of_type sigma c = Term.kind_of_type (whd_evar sigma c)
+ let of_kind = Constr.of_kind
+ let of_constr c = c
+ let unsafe_to_constr c = c
+ let unsafe_eq = Refl
+
+ let to_constr ?(abort_on_undefined_evars=true) sigma c =
+ let evar_value =
+ 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
+ Universes.nf_evars_and_universes_opt_subst evar_value (universe_subst sigma) c
+
+ let of_named_decl d = d
+ let unsafe_to_named_decl d = d
+ let of_rel_decl d = d
+ let unsafe_to_rel_decl d = d
+ let to_rel_decl sigma d = Context.Rel.Declaration.map_constr (to_constr sigma) d
+
+end
diff --git a/engine/evd.mli b/engine/evd.mli
index 911799c44..509db525d 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -28,6 +28,9 @@ open Environ
It also contains conversion constraints, debugging information and
information about meta variables. *)
+type econstr
+type etypes = econstr
+
(** {5 Existential variables and unification states} *)
type evar = Evar.t
@@ -86,16 +89,16 @@ end
type evar_body =
| Evar_empty
- | Evar_defined of constr
+ | Evar_defined of econstr
module Store : Store.S
(** Datatype used to store additional information in evar maps. *)
type evar_info = {
- evar_concl : constr;
+ evar_concl : econstr;
(** Type of the evar. *)
- evar_hyps : named_context_val;
+ evar_hyps : named_context_val; (** TODO econstr? *)
(** Context of the evar. *)
evar_body : evar_body;
(** Optional content of the evar. *)
@@ -105,16 +108,16 @@ type evar_info = {
in the solution *)
evar_source : Evar_kinds.t located;
(** Information about the evar. *)
- evar_candidates : constr list option;
+ evar_candidates : econstr list option;
(** List of possible solutions when known that it is a finite list *)
evar_extra : Store.t
(** Extra store, used for clever hacks. *)
}
-val make_evar : named_context_val -> types -> evar_info
-val evar_concl : evar_info -> constr
-val evar_context : evar_info -> Context.Named.t
-val evar_filtered_context : evar_info -> Context.Named.t
+val make_evar : named_context_val -> etypes -> evar_info
+val evar_concl : evar_info -> econstr
+val evar_context : evar_info -> (econstr, etypes) Context.Named.pt
+val evar_filtered_context : evar_info -> (econstr, etypes) Context.Named.pt
val evar_hyps : evar_info -> named_context_val
val evar_filtered_hyps : evar_info -> named_context_val
val evar_body : evar_info -> evar_body
@@ -122,8 +125,8 @@ val evar_filter : evar_info -> Filter.t
val evar_env : evar_info -> env
val evar_filtered_env : evar_info -> env
-val map_evar_body : (constr -> constr) -> evar_body -> evar_body
-val map_evar_info : (constr -> constr) -> evar_info -> evar_info
+val map_evar_body : (econstr -> econstr) -> evar_body -> evar_body
+val map_evar_info : (econstr -> econstr) -> evar_info -> evar_info
(** {6 Unification state} **)
@@ -190,7 +193,7 @@ val raw_map_undefined : (Evar.t -> evar_info -> evar_info) -> evar_map -> evar_m
(** Same as {!raw_map}, but restricted to undefined evars. For efficiency
reasons. *)
-val define : Evar.t-> constr -> evar_map -> evar_map
+val define : Evar.t-> econstr -> evar_map -> evar_map
(** Set the body of an evar to the given constr. It is expected that:
{ul
{- The evar is already present in the evarmap.}
@@ -198,7 +201,7 @@ val define : Evar.t-> constr -> evar_map -> evar_map
{- All the evars present in the constr should be present in the evar map.}
} *)
-val cmap : (constr -> constr) -> evar_map -> evar_map
+val cmap : (econstr -> econstr) -> evar_map -> evar_map
(** Map the function on all terms in the evar map. *)
val is_evar : evar_map -> Evar.t-> bool
@@ -222,20 +225,26 @@ val drop_all_defined : evar_map -> evar_map
exception NotInstantiatedEvar
-val existential_value : evar_map -> existential -> constr
+val existential_value : evar_map -> econstr pexistential -> econstr
(** [existential_value sigma ev] raises [NotInstantiatedEvar] if [ev] has
no body and [Not_found] if it does not exist in [sigma] *)
-val existential_type : evar_map -> existential -> types
+val existential_value0 : evar_map -> existential -> constr
+
+val existential_type : evar_map -> econstr pexistential -> etypes
-val existential_opt_value : evar_map -> existential -> constr option
+val existential_type0 : evar_map -> existential -> types
+
+val existential_opt_value : evar_map -> econstr pexistential -> econstr option
(** Same as {!existential_value} but returns an option instead of raising an
exception. *)
+val existential_opt_value0 : evar_map -> existential -> constr option
+
val evar_instance_array : (Context.Named.Declaration.t -> 'a -> bool) -> evar_info ->
'a array -> (Id.t * 'a) list
-val instantiate_evar_array : evar_info -> constr -> constr array -> constr
+val instantiate_evar_array : evar_info -> econstr -> econstr array -> econstr
val evars_reset_evd : ?with_conv_pbs:bool -> ?with_univs:bool ->
evar_map -> evar_map -> evar_map
@@ -243,7 +252,7 @@ val evars_reset_evd : ?with_conv_pbs:bool -> ?with_univs:bool ->
(** {6 Misc} *)
-val restrict : Evar.t-> Filter.t -> ?candidates:constr list ->
+val restrict : Evar.t-> Filter.t -> ?candidates:econstr list ->
?src:Evar_kinds.t located -> evar_map -> evar_map * Evar.t
(** Restrict an undefined evar into a new evar by filtering context and
possibly limiting the instances to a set of candidates *)
@@ -251,7 +260,7 @@ val restrict : Evar.t-> Filter.t -> ?candidates:constr list ->
val is_restricted_evar : evar_info -> Evar.t option
(** Tell if an evar comes from restriction of another evar, and if yes, which *)
-val downcast : Evar.t-> types -> evar_map -> evar_map
+val downcast : Evar.t-> etypes -> evar_map -> evar_map
(** Change the type of an undefined evar to a new type assumed to be a
subtype of its current type; subtyping must be ensured by caller *)
@@ -341,7 +350,7 @@ val shelve_on_future_goals : Evar.t list -> future_goals -> future_goals
Evar maps also keep track of the universe constraints defined at a given
point. This section defines the relevant manipulation functions. *)
-val whd_sort_variable : evar_map -> constr -> constr
+val whd_sort_variable : evar_map -> econstr -> econstr
exception UniversesDiffer
@@ -397,8 +406,8 @@ type 'a freelisted = {
rebus : 'a;
freemetas : Metaset.t }
-val metavars_of : constr -> Metaset.t
-val mk_freelisted : constr -> constr freelisted
+val metavars_of : econstr -> Metaset.t
+val mk_freelisted : econstr -> econstr freelisted
val map_fl : ('a -> 'b) -> 'a freelisted -> 'b freelisted
(** Status of an instance found by unification wrt to the meta it solves:
@@ -436,12 +445,12 @@ type instance_status = instance_constraint * instance_typing_status
(** Clausal environments *)
type clbinding =
- | Cltyp of Name.t * constr freelisted
- | Clval of Name.t * (constr freelisted * instance_status) * constr freelisted
+ | Cltyp of Name.t * econstr freelisted
+ | Clval of Name.t * (econstr freelisted * instance_status) * econstr freelisted
(** Unification constraints *)
type conv_pb = Reduction.conv_pb
-type evar_constraint = conv_pb * env * constr * constr
+type evar_constraint = conv_pb * env * econstr * econstr
val add_conv_pb : ?tail:bool -> evar_constraint -> evar_map -> evar_map
val extract_changed_conv_pbs : evar_map ->
@@ -457,7 +466,7 @@ val loc_of_conv_pb : evar_map -> evar_constraint -> Loc.t option
val evars_of_term : constr -> Evar.Set.t
(** including evars in instances of evars *)
-val evars_of_named_context : Context.Named.t -> Evar.Set.t
+val evars_of_named_context : (econstr, etypes) Context.Named.pt -> Evar.Set.t
val evars_of_filtered_evar_info : evar_info -> Evar.Set.t
@@ -465,19 +474,20 @@ val evars_of_filtered_evar_info : evar_info -> Evar.Set.t
val meta_list : evar_map -> (metavariable * clbinding) list
val meta_defined : evar_map -> metavariable -> bool
-val meta_value : evar_map -> metavariable -> constr
+val meta_value : evar_map -> metavariable -> econstr
(** [meta_fvalue] raises [Not_found] if meta not in map or [Anomaly] if
meta has no value *)
-val meta_fvalue : evar_map -> metavariable -> constr freelisted * instance_status
-val meta_opt_fvalue : evar_map -> metavariable -> (constr freelisted * instance_status) option
-val meta_type : evar_map -> metavariable -> types
-val meta_ftype : evar_map -> metavariable -> types freelisted
+val meta_fvalue : evar_map -> metavariable -> econstr freelisted * instance_status
+val meta_opt_fvalue : evar_map -> metavariable -> (econstr freelisted * instance_status) option
+val meta_type : evar_map -> metavariable -> etypes
+val meta_type0 : evar_map -> metavariable -> types
+val meta_ftype : evar_map -> metavariable -> etypes freelisted
val meta_name : evar_map -> metavariable -> Name.t
val meta_declare :
- metavariable -> types -> ?name:Name.t -> evar_map -> evar_map
-val meta_assign : metavariable -> constr * instance_status -> evar_map -> evar_map
-val meta_reassign : metavariable -> constr * instance_status -> evar_map -> evar_map
+ metavariable -> etypes -> ?name:Name.t -> evar_map -> evar_map
+val meta_assign : metavariable -> econstr * instance_status -> evar_map -> evar_map
+val meta_reassign : metavariable -> econstr * instance_status -> evar_map -> evar_map
val clear_metas : evar_map -> evar_map
@@ -485,10 +495,10 @@ val clear_metas : evar_map -> evar_map
val meta_merge : ?with_univs:bool -> evar_map -> evar_map -> evar_map
val undefined_metas : evar_map -> metavariable list
-val map_metas_fvalue : (constr -> constr) -> evar_map -> evar_map
-val map_metas : (constr -> constr) -> evar_map -> evar_map
+val map_metas_fvalue : (econstr -> econstr) -> evar_map -> evar_map
+val map_metas : (econstr -> econstr) -> evar_map -> evar_map
-type metabinding = metavariable * constr * instance_status
+type metabinding = metavariable * econstr * instance_status
val retract_coercible_metas : evar_map -> metabinding list * evar_map
@@ -639,13 +649,13 @@ 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 * constr
+ evar_map -> GlobRef.t -> evar_map * econstr
(********************************************************************)
(* constr with holes and pending resolution of classes, conversion *)
(* problems, candidates, etc. *)
-type open_constr = evar_map * constr (* Special case when before is empty *)
+type open_constr = evar_map * econstr (* Special case when before is empty *)
(** Partially constructed constrs. *)
@@ -665,3 +675,50 @@ val create_evar_defs : evar_map -> evar_map
(** Create an [evar_map] with empty meta map: *)
+(** Use this module only to bootstrap EConstr *)
+module MiniEConstr : sig
+ module ESorts : sig
+ type t
+ val make : Sorts.t -> t
+ val kind : evar_map -> t -> Sorts.t
+ val unsafe_to_sorts : t -> Sorts.t
+ end
+
+ module EInstance : sig
+ type t
+ val make : Univ.Instance.t -> t
+ val kind : evar_map -> t -> Univ.Instance.t
+ val empty : t
+ val is_empty : t -> bool
+ val unsafe_to_instance : t -> Univ.Instance.t
+ end
+
+ type t = econstr
+
+ val kind : evar_map -> t -> (t, t, ESorts.t, EInstance.t) Constr.kind_of_term
+ val kind_upto : evar_map -> constr -> (constr, types, Sorts.t, Univ.Instance.t) Constr.kind_of_term
+ val kind_of_type : evar_map -> t -> (t, t) Term.kind_of_type
+
+ val whd_evar : evar_map -> t -> t
+
+ val of_kind : (t, t, ESorts.t, EInstance.t) Constr.kind_of_term -> t
+
+ val of_constr : Constr.t -> t
+
+ val to_constr : ?abort_on_undefined_evars:bool -> evar_map -> t -> Constr.t
+
+ val unsafe_to_constr : t -> Constr.t
+
+ val unsafe_eq : (t, Constr.t) eq
+
+ val of_named_decl : (Constr.t, Constr.types) Context.Named.Declaration.pt ->
+ (t, t) Context.Named.Declaration.pt
+ val unsafe_to_named_decl : (t, t) Context.Named.Declaration.pt ->
+ (Constr.t, Constr.types) Context.Named.Declaration.pt
+ val unsafe_to_rel_decl : (t, t) Context.Rel.Declaration.pt ->
+ (Constr.t, Constr.types) Context.Rel.Declaration.pt
+ val of_rel_decl : (Constr.t, Constr.types) Context.Rel.Declaration.pt ->
+ (t, t) Context.Rel.Declaration.pt
+ val to_rel_decl : evar_map -> (t, t) Context.Rel.Declaration.pt ->
+ (Constr.t, Constr.types) Context.Rel.Declaration.pt
+end
diff --git a/engine/proofview.ml b/engine/proofview.ml
index 639f48e77..54237ceb4 100644
--- a/engine/proofview.ml
+++ b/engine/proofview.ml
@@ -45,9 +45,9 @@ let compact el ({ solution } as pv) =
let pruned_solution = Evd.drop_all_defined solution in
let apply_subst_einfo _ ei =
Evd.({ ei with
- evar_concl = nf0 ei.evar_concl;
+ evar_concl = nf ei.evar_concl;
evar_hyps = Environ.map_named_val nf0 ei.evar_hyps;
- evar_candidates = Option.map (List.map nf0) ei.evar_candidates }) in
+ evar_candidates = Option.map (List.map nf) ei.evar_candidates }) in
let new_solution = Evd.raw_map_undefined apply_subst_einfo pruned_solution in
let new_size = Evd.fold (fun _ _ i -> i+1) new_solution 0 in
Feedback.msg_info (Pp.str (Printf.sprintf "Evars: %d -> %d\n" size new_size));
@@ -875,8 +875,7 @@ module Progress = struct
(** equality function on hypothesis contexts *)
let eq_named_context_val sigma1 sigma2 ctx1 ctx2 =
- let open Environ in
- let c1 = named_context_of_val ctx1 and c2 = named_context_of_val ctx2 in
+ let c1 = EConstr.named_context_of_val ctx1 and c2 = EConstr.named_context_of_val ctx2 in
let eq_named_declaration d1 d2 =
match d1, d2 with
| LocalAssum (i1,t1), LocalAssum (i2,t2) ->
@@ -1101,7 +1100,7 @@ module Goal = struct
let gmake_with info env sigma goal state =
{ env = Environ.reset_with_named_context (Evd.evar_filtered_hyps info) env ;
sigma = sigma ;
- concl = EConstr.of_constr (Evd.evar_concl info);
+ concl = Evd.evar_concl info;
state = state ;
self = goal }
diff --git a/engine/termops.ml b/engine/termops.ml
index b7531f6fc..df43be28e 100644
--- a/engine/termops.ml
+++ b/engine/termops.ml
@@ -115,7 +115,7 @@ let pr_evar_suggested_name evk sigma =
| _,Evar_kinds.GoalEvar -> Id.of_string "Goal"
| _ ->
let env = reset_with_named_context evi.evar_hyps (Global.env()) in
- Namegen.id_of_name_using_hdchar env sigma (EConstr.of_constr evi.evar_concl) Anonymous
+ Namegen.id_of_name_using_hdchar env sigma evi.evar_concl Anonymous
in
let names = EvMap.mapi base_id (undefined_map sigma) in
let id = EvMap.find evk names in
@@ -154,7 +154,7 @@ let protect f x =
with e -> str "EXCEPTION: " ++ str (Printexc.to_string e)
let print_kconstr a =
- protect (fun c -> print_constr (EConstr.of_constr c)) a
+ protect (fun c -> print_constr c) a
let pr_meta_map evd =
let open Evd in
@@ -197,11 +197,11 @@ let pr_evar_source = function
let print_constr = print_kconstr in
let id = Option.get ido in
str "parameter " ++ Id.print id ++ spc () ++ str "of" ++
- spc () ++ print_constr (printable_constr_of_global c)
+ spc () ++ print_constr (EConstr.of_constr @@ printable_constr_of_global c)
| Evar_kinds.InternalHole -> str "internal placeholder"
| Evar_kinds.TomatchTypeParameter (ind,n) ->
let print_constr = print_kconstr in
- pr_nth n ++ str " argument of type " ++ print_constr (mkInd ind)
+ pr_nth n ++ str " argument of type " ++ print_constr (EConstr.mkInd ind)
| Evar_kinds.GoalEvar -> str "goal evar"
| Evar_kinds.ImpossibleCase -> str "type of impossible pattern-matching clause"
| Evar_kinds.MatchingVar _ -> str "matching variable"
@@ -256,7 +256,7 @@ let compute_evar_dependency_graph sigma =
in
match evar_body evi with
| Evar_empty -> acc
- | Evar_defined c -> Evar.Set.fold fold_ev (evars_of_term c) acc
+ | Evar_defined c -> Evar.Set.fold fold_ev (evars_of_term (EConstr.Unsafe.to_constr c)) acc
in
Evd.fold fold sigma EvMap.empty
@@ -314,7 +314,8 @@ let print_env_short env =
let print_constr = print_kconstr in
let pr_rel_decl = function
| RelDecl.LocalAssum (n,_) -> Name.print n
- | RelDecl.LocalDef (n,b,_) -> str "(" ++ Name.print n ++ str " := " ++ print_constr b ++ str ")"
+ | RelDecl.LocalDef (n,b,_) -> str "(" ++ Name.print n ++ str " := "
+ ++ print_constr (EConstr.of_constr b) ++ str ")"
in
let pr_named_decl = NamedDecl.to_rel_decl %> pr_rel_decl in
let nc = List.rev (named_context env) in
@@ -335,11 +336,11 @@ let pr_evar_constraints sigma pbs =
Namegen.make_all_name_different env sigma
in
print_env_short env ++ spc () ++ str "|-" ++ spc () ++
- protect (print_constr_env env sigma) (EConstr.of_constr t1) ++ spc () ++
+ protect (print_constr_env env sigma) t1 ++ spc () ++
str (match pbty with
| Reduction.CONV -> "=="
| Reduction.CUMUL -> "<=") ++
- spc () ++ protect (print_constr_env env Evd.empty) (EConstr.of_constr t2)
+ spc () ++ protect (print_constr_env env Evd.empty) t2
in
prlist_with_sep fnl pr_evconstr pbs
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/universes.ml b/engine/universes.ml
index e5f9212a7..938f5ad9c 100644
--- a/engine/universes.ml
+++ b/engine/universes.ml
@@ -74,7 +74,7 @@ let subst_ubinder (subst,(ref,l as orig)) =
let discharge_ubinder (_,(ref,l)) =
Some (Lib.discharge_global ref, l)
-let ubinder_obj : Globnames.global_reference * universe_binders -> Libobject.obj =
+let ubinder_obj : GlobRef.t * universe_binders -> Libobject.obj =
let open Libobject in
declare_object { (default_object "universe binder") with
cache_function = cache_ubinder;
@@ -524,8 +524,6 @@ let new_global_univ () =
(** Simplification *)
-module LevelUnionFind = Unionfind.Make (Univ.LSet) (Univ.LMap)
-
let add_list_map u t map =
try
let l = LMap.find u map in
@@ -533,8 +531,6 @@ let add_list_map u t map =
with Not_found ->
LMap.add u [t] map
-module UF = LevelUnionFind
-
(** Precondition: flexible <= ctx *)
let choose_canonical ctx flexible algs s =
let global = LSet.diff s ctx in
@@ -596,35 +592,6 @@ let subst_univs_constr =
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
@@ -683,6 +650,35 @@ let normalize_opt_subst 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 (ref subst) in
+ let lsubst = level_subst_of subst in
+ let rec aux c =
+ match kind c with
+ | Evar (evk, args) ->
+ let args = Array.map aux args in
+ (match try f (evk, args) with Not_found -> None with
+ | None -> mkEvar (evk, args)
+ | Some c -> aux c)
+ | Const pu ->
+ let pu' = subst_univs_fn_puniverses lsubst pu in
+ if pu' == pu then c else mkConstU pu'
+ | Ind pu ->
+ let pu' = subst_univs_fn_puniverses lsubst pu in
+ if pu' == pu then c else mkIndU pu'
+ | Construct pu ->
+ let pu' = subst_univs_fn_puniverses lsubst pu in
+ if pu' == pu then c else mkConstructU pu'
+ | Sort (Type u) ->
+ let u' = Univ.subst_univs_universe subst u in
+ if u' == u then c else mkSort (sort_of_univ u')
+ | _ -> Constr.map aux c
+ in aux
+
let make_opt_subst s =
fun x ->
(match Univ.LMap.find x s with
@@ -709,6 +705,7 @@ let pr_universe_body = function
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
@@ -742,10 +739,12 @@ let lower_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 (enf,alg,v',lower) ->
- if not alg && enf && Universe.equal v' v then raise (Found (k, lower)))
+ 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)
@@ -765,18 +764,18 @@ let compute_lbound left =
sup (Universe.super l) lbound
else None))
None left
-
-let instantiate_with_lbound u lbound lower alg enforce (ctx, us, algs, insts, cstrs) =
+
+let instantiate_with_lbound u lbound lower ~alg ~enforce (ctx, us, algs, insts, cstrs) =
if enforce then
let inst = Universe.make u in
let cstrs' = enforce_leq lbound inst cstrs in
(ctx, us, LSet.remove u algs,
- LMap.add u (enforce,alg,lbound,lower) insts, cstrs'),
- (enforce, alg, inst, lower)
+ 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)
+ 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
@@ -790,73 +789,82 @@ let _pr_constraints_map (cmap:constraints_map) =
let remove_alg l (ctx, us, algs, insts, cstrs) =
(ctx, us, LSet.remove l algs, insts, cstrs)
-let remove_lower u lower =
- let levels = Universe.levels u in
- LSet.fold (fun l acc -> LMap.remove l acc) levels lower
-
+let 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' =
+ let lbounds =
match compute_lbound (List.map (fun (d,l) -> d, Universe.make l) lower) with
| None -> lbounds
- | Some lbound -> LMap.add r (true, false, lbound, lower_of_list lower)
+ | Some lbound -> LMap.add r {enforce=true; alg=false; lbound; lower=lower_of_list lower}
lbounds
- in (Univ.LMap.remove r left, 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 rec instance (ctx, us, algs, insts, cstrs as acc) u =
let acc, left, lower =
- try
- let l = LMap.find u left in
+ 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', (enf,alg,l',lower) = aux acc l in
+ (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',
+ in acc', (d, l') :: left,
lower_add l d newlow, lower_union lower lower')
(acc, [], LMap.empty, LMap.empty) l
in
- let not_lower (d,l) =
- (* We're checking if (d,l) is already implied by the lower
- constraints on some level u. If it represents l < u (d is Lt
- or d is Le and i > 0, the i < 0 case is impossible due to
- invariants of Univ), and the lower constraints only have l <=
- u then it is not implied. *)
- Univ.Universe.exists
- (fun (l,i) ->
- let d =
- if i == 0 then d
- else match d with
- | Le -> Lt
- | d -> d
- in
- try let d' = LMap.find l lower in
- (* If d is stronger than the already implied lower
- * constraints we must keep it. *)
- compare_constraint_type d d' > 0
- with Not_found ->
- (** No constraint existing on l *) true) l
- in
- let left = List.uniquize (List.filter not_lower left) in
+ let left = List.uniquize (List.filter (not_lower lower) left) in
(acc, left, LMap.union newlow lower)
- with Not_found -> acc, [], LMap.empty
- and right =
- try Some (LMap.find u right)
- with Not_found -> None
in
let instantiate_lbound lbound =
let alg = LSet.mem u algs in
if alg then
(* u is algebraic: we instantiate it with its lower bound, if any,
or enforce the constraints if it is bounded from the top. *)
- let lower = remove_lower lbound lower in
- instantiate_with_lbound u lbound lower true false acc
+ 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 *)
@@ -867,125 +875,96 @@ let minimize_univ_variables ctx us algs left right cstrs =
if not (Level.equal l u) then
(* Should check that u does not
have upper constraints that are not already in right *)
- let acc' = remove_alg l acc in
- instantiate_with_lbound u lbound lower false false acc'
- else acc, (true, false, lbound, lower)
+ 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 ->
- try
- (* Another universe represents the same lower bound,
- we can share them with no harm. *)
- let can, lower = find_inst insts lbound in
- let lower = LMap.remove can lower in
- instantiate_with_lbound u (Universe.make can) lower false false acc
- with Not_found ->
- (* We set u as the canonical universe representing lbound *)
- instantiate_with_lbound u lbound lower false true acc
+ 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 acc' acc =
- match right with
- | None -> acc
- | Some cstrs ->
- let dangling = List.filter (fun (d, r) -> not (LMap.mem r us)) cstrs in
- if List.is_empty dangling then acc
- else
- let ((ctx', us, algs, insts, cstrs), (enf,_,inst,lower as b)) = acc in
- let cstrs' = List.fold_left (fun cstrs (d, r) ->
- if d == Univ.Le then
- enforce_leq inst (Universe.make r) cstrs
- else
- try let lev = Option.get (Universe.level inst) in
- Constraint.add (lev, d, r) cstrs
- with Option.IsNone -> failwith "")
- cstrs dangling
- in
- (ctx', us, algs, insts, cstrs'), b
+ 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 acc' (acc, (true, false, Universe.make u, lower))
- else
- let lbound = compute_lbound left in
- match lbound with
- | None -> (* Nothing to do *)
- acc' (acc, (true, false, Universe.make u, lower))
- | Some lbound ->
- try acc' (instantiate_lbound lbound)
- with Failure _ -> acc' (acc, (true, false, Universe.make u, lower))
- and aux (ctx', us, algs, seen, cstrs as acc) u =
+ 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) ->
+ 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)
+ else LSet.remove u ctx, us, LSet.remove u algs, seen, cstrs)
us (ctx, us, algs, lbounds, cstrs)
let normalize_context_set g ctx us algs weak =
let (ctx, csts) = ContextSet.levels ctx, ContextSet.constraints ctx in
- let uf = UF.create () in
(** Keep the Prop/Set <= i constraints separate for minimization *)
let smallles, csts =
- Constraint.fold (fun (l,d,r as cstr) (smallles, noneqs) ->
- if d == Le then
- if Univ.Level.is_small l then
- if is_set_minimization () && LSet.mem r ctx then
- (Constraint.add cstr smallles, noneqs)
- else (smallles, noneqs)
- else if Level.is_small r then
- if Level.is_prop r then
- raise (Univ.UniverseInconsistency
- (Le,Universe.make l,Universe.make r,None))
- else (smallles, Constraint.add (l,Eq,r) noneqs)
- else (smallles, Constraint.add cstr noneqs)
- else (smallles, Constraint.add cstr noneqs))
- csts (Constraint.empty, Constraint.empty)
+ 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 =
+ let csts, partition =
(* We first put constraints in a normal-form: all self-loops are collapsed
to equalities. *)
- let g = Univ.LSet.fold (fun v g -> UGraph.add_universe v false g)
+ let g = LSet.fold (fun v g -> UGraph.add_universe v false g)
ctx UGraph.initial_universes
in
- let g =
- Univ.Constraint.fold
- (fun (l, d, r) g ->
- let g =
- if not (Level.is_small l || LSet.mem l ctx) then
- try UGraph.add_universe l false g
- with UGraph.AlreadyDeclared -> g
- else g
- in
- let g =
- if not (Level.is_small r || LSet.mem r ctx) then
- try UGraph.add_universe r false g
- with UGraph.AlreadyDeclared -> g
- else g
- in g) csts g
+ 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 = Univ.Constraint.fold UGraph.enforce_constraint 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.fold (fun (l,d,r as cstr) noneqs ->
- if d == Eq then (UF.union l r uf; noneqs)
- else (* We ignore the trivial Prop/Set <= i constraints. *)
- if d == Le && Univ.Level.is_small l then noneqs
- else if Univ.Level.is_prop l && d == Lt && Univ.Level.is_set r
- then noneqs
- else Constraint.add cstr noneqs)
- csts Constraint.empty
+ 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 partition = UF.partition uf in
let flex x = LMap.mem x us in
let ctx, us, eqs = List.fold_left (fun (ctx, us, cstrs) s ->
let canon, (global, rigid, flexible) = choose_canonical ctx flex algs s in
(* Add equalities for globals which can't be merged anymore. *)
let cstrs = LSet.fold (fun g cst ->
- Constraint.add (canon, Univ.Eq, g) cst) global
+ 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, Univ.Eq, g) cst) rigid
+ Constraint.add (canon, Eq, g) cst) rigid
cstrs
in
let canonu = Some (Universe.make canon) in
diff --git a/engine/universes.mli b/engine/universes.mli
index 4823c5746..e6bee42bb 100644
--- a/engine/universes.mli
+++ b/engine/universes.mli
@@ -37,8 +37,8 @@ type universe_binders = Univ.Level.t Names.Id.Map.t
val empty_binders : universe_binders
-val register_universe_binders : Globnames.global_reference -> universe_binders -> unit
-val universe_binders_of_global : Globnames.global_reference -> universe_binders
+val register_universe_binders : GlobRef.t -> universe_binders -> unit
+val universe_binders_of_global : GlobRef.t -> universe_binders
type univ_name_list = Misctypes.lname list
@@ -48,7 +48,7 @@ type univ_name_list = Misctypes.lname list
May error if the lengths mismatch.
Otherwise return [universe_binders_of_global ref]. *)
-val universe_binders_with_opt_names : Globnames.global_reference ->
+val universe_binders_with_opt_names : Names.GlobRef.t ->
Univ.Level.t list -> univ_name_list option -> universe_binders
(** The global universe counter *)
@@ -132,7 +132,7 @@ val fresh_inductive_instance : env -> inductive ->
val fresh_constructor_instance : env -> constructor ->
pconstructor in_universe_context_set
-val fresh_global_instance : ?names:Univ.Instance.t -> env -> Globnames.global_reference ->
+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 ->
@@ -144,9 +144,9 @@ 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 -> Globnames.global_reference puniverses
+val global_of_constr : constr -> GlobRef.t puniverses
-val constr_of_global_univ : Globnames.global_reference puniverses -> constr
+val constr_of_global_univ : GlobRef.t puniverses -> constr
val extend_context : 'a in_universe_context_set -> ContextSet.t ->
'a in_universe_context_set
@@ -162,8 +162,6 @@ val extend_context : 'a in_universe_context_set -> ContextSet.t ->
(a global one if there is one) and transitively saturate
the constraints w.r.t to the equalities. *)
-module UF : Unionfind.PartitionSig with type elt = Level.t
-
val level_subst_of : universe_subst_fn -> universe_level_subst_fn
val subst_univs_constraints : universe_subst_fn -> Constraint.t -> Constraint.t
@@ -206,16 +204,16 @@ val normalize_universe_subst : universe_subst ref ->
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 constr_of_global : GlobRef.t -> constr
(** ** DEPRECATED ** synonym of [constr_of_global] *)
-val constr_of_reference : Globnames.global_reference -> constr
+val constr_of_reference : GlobRef.t -> constr
[@@ocaml.deprecated "synonym of [constr_of_global]"]
(** 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
+val type_of_global : GlobRef.t -> types in_universe_context_set
(** Full universes substitutions into terms *)
diff --git a/ide/coqOps.ml b/ide/coqOps.ml
index 78fbce5c8..6c3438a4b 100644
--- a/ide/coqOps.ml
+++ b/ide/coqOps.ml
@@ -362,7 +362,12 @@ object(self)
let query = Coq.query (route_id,(phrase,sid)) in
Coq.bind (Coq.seq action query) next
+ method private still_valid { edit_id = id } =
+ try ignore(Doc.find_id document (fun _ { edit_id = id1 } -> id = id1)); true
+ with Not_found -> false
+
method private mark_as_needed sentence =
+ if self#still_valid sentence then begin
Minilib.log_pp Pp.(str "Marking " ++ dbg_to_string buffer false None sentence);
let start = buffer#get_iter_at_mark sentence.start in
let stop = buffer#get_iter_at_mark sentence.stop in
@@ -383,6 +388,7 @@ object(self)
in
List.iter (fun t -> buffer#remove_tag t ~start ~stop) all_tags;
List.iter (fun t -> buffer#apply_tag t ~start ~stop) tags
+ end
method private attach_tooltip ?loc sentence text =
let start_sentence, stop_sentence, phrase = self#get_sentence sentence in
diff --git a/ide/ide_slave.ml b/ide/ide_slave.ml
index 5abd7803a..d8fdfdb1b 100644
--- a/ide/ide_slave.ml
+++ b/ide/ide_slave.ml
@@ -510,7 +510,7 @@ let () = Coqtop.toploop_init := (fun coq_args extra_args ->
let args = parse extra_args in
Flags.quiet := true;
CoqworkmgrApi.(init High);
- args)
+ coq_args, args)
let () = Coqtop.toploop_run := loop
diff --git a/interp/constrextern.mli b/interp/constrextern.mli
index 8ab70283c..6f5887ca2 100644
--- a/interp/constrextern.mli
+++ b/interp/constrextern.mli
@@ -13,7 +13,6 @@ open Termops
open EConstr
open Environ
open Libnames
-open Globnames
open Glob_term
open Pattern
open Constrexpr
@@ -40,7 +39,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 +57,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 f2cd07c94..def8425ec 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -433,7 +433,7 @@ let glob_local_binder_of_extended = DAst.with_loc_val (fun ?loc -> function
let t = DAst.make ?loc @@ GHole(Evar_kinds.BinderType na,Misctypes.IntroAnonymous,None) in
(na,bk,Some c,t)
| GLocalPattern (_,_,_,_) ->
- Loc.raise ?loc (Stream.Error "pattern with quote not allowed here.")
+ Loc.raise ?loc (Stream.Error "pattern with quote not allowed here")
)
let intern_cases_pattern_fwd = ref (fun _ -> failwith "intern_cases_pattern_fwd")
@@ -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.mli b/interp/declare.mli
index 084d746e6..f8cffbb1e 100644
--- a/interp/declare.mli
+++ b/interp/declare.mli
@@ -83,7 +83,7 @@ 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 -> Universes.universe_binders -> unit
val declare_universe_context : polymorphic -> Univ.ContextSet.t -> 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 1eeb8e41a..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
@@ -130,7 +129,7 @@ val make_implicits_list : implicit_status list -> implicits_list list
val drop_first_implicits : int -> implicits_list -> implicits_list
-val projection_implicits : env -> projection -> implicit_status list ->
+val projection_implicits : env -> Projection.t -> implicit_status list ->
implicit_status list
val select_impargs_size : int -> implicits_list list -> implicit_status 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/interp.mllib b/interp/interp.mllib
index bb22cf468..61313acc4 100644
--- a/interp/interp.mllib
+++ b/interp/interp.mllib
@@ -1,6 +1,7 @@
Tactypes
Stdarg
Genintern
+Notation_term
Notation_ops
Notation
Syntax_def
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 aa9a6ed0d..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))
@@ -210,7 +210,7 @@ let glob_constr_of_notation_constr_with_binders ?loc g f e nc =
let e',na = protect g e na in
GIf (f e c,(na,Option.map (f e') po),f e b1,f e b2)
| NRec (fk,idl,dll,tl,bl) ->
- let e,dll = Array.fold_left_map (List.fold_map (fun e (na,oc,b) ->
+ let e,dll = Array.fold_left_map (List.fold_left_map (fun e (na,oc,b) ->
let e,na = protect g e na in
(e,(na,Explicit,Option.map (f e) oc,f e b)))) e dll in
let e',idl = Array.fold_left_map (to_id (protect g)) e idl in
@@ -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/intf/notation_term.ml b/interp/notation_term.ml
index a9c2e2a53..1a46746cc 100644
--- a/intf/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/intf/intf.mllib b/intf/intf.mllib
deleted file mode 100644
index 2b8960d3f..000000000
--- a/intf/intf.mllib
+++ /dev/null
@@ -1,11 +0,0 @@
-Constrexpr
-Evar_kinds
-Genredexpr
-Locus
-Extend
-Notation_term
-Decl_kinds
-Glob_term
-Misctypes
-Pattern
-Vernacexpr
diff --git a/kernel/byterun/coq_interp.c b/kernel/byterun/coq_interp.c
index af89712d5..cfeb0a9ee 100644
--- a/kernel/byterun/coq_interp.c
+++ b/kernel/byterun/coq_interp.c
@@ -163,8 +163,11 @@ extern void caml_process_pending_signals(void);
/* The interpreter itself */
value coq_interprete
-(code_t coq_pc, value coq_accu, value coq_env, long coq_extra_args)
+(code_t coq_pc, value coq_accu, value coq_atom_tbl, value coq_global_data, value coq_env, long coq_extra_args)
{
+ /* coq_accu is not allocated on the OCaml heap */
+ CAMLparam2(coq_atom_tbl, coq_global_data);
+
/*Declaration des variables */
#ifdef PC_REG
register code_t pc PC_REG;
@@ -196,7 +199,7 @@ value coq_interprete
coq_instr_table = (char **) coq_jumptable;
coq_instr_base = coq_Jumptbl_base;
#endif
- return Val_unit;
+ CAMLreturn(Val_unit);
}
#if defined(THREADED_CODE) && defined(ARCH_SIXTYFOUR) && !defined(ARCH_CODE32)
coq_jumptbl_base = coq_Jumptbl_base;
@@ -1460,7 +1463,7 @@ value coq_interprete
Instruct(STOP){
print_instr("STOP");
coq_sp = sp;
- return accu;
+ CAMLreturn(accu);
}
@@ -1512,12 +1515,16 @@ value coq_push_vstack(value stk, value max_stack_size) {
return Val_unit;
}
-value coq_interprete_ml(value tcode, value a, value e, value ea) {
+value coq_interprete_ml(value tcode, value a, value t, value g, value e, value ea) {
print_instr("coq_interprete");
- return coq_interprete((code_t)tcode, a, e, Long_val(ea));
+ return coq_interprete((code_t)tcode, a, t, g, e, Long_val(ea));
print_instr("end coq_interprete");
}
-value coq_eval_tcode (value tcode, value e) {
- return coq_interprete_ml(tcode, Val_unit, e, 0);
+value coq_interprete_byte(value* argv, int argn){
+ return coq_interprete_ml(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+}
+
+value coq_eval_tcode (value tcode, value t, value g, value e) {
+ return coq_interprete_ml(tcode, Val_unit, t, g, e, 0);
}
diff --git a/kernel/byterun/coq_interp.h b/kernel/byterun/coq_interp.h
index 60865c32e..c04e9e00b 100644
--- a/kernel/byterun/coq_interp.h
+++ b/kernel/byterun/coq_interp.h
@@ -17,11 +17,10 @@ value coq_push_arguments(value args);
value coq_push_vstack(value stk);
-value coq_interprete_ml(value tcode, value a, value e, value ea);
+value coq_interprete_ml(value tcode, value a, value t, value g, value e, value ea);
+value coq_interprete_byte(value* argv, int argn);
value coq_interprete
- (code_t coq_pc, value coq_accu, value coq_env, long coq_extra_args);
-
-value coq_eval_tcode (value tcode, value e);
-
+ (code_t coq_pc, value coq_accu, value coq_atom_tbl, value coq_global_data, value coq_env, long coq_extra_args);
+value coq_eval_tcode (value tcode, value t, value g, value e);
diff --git a/kernel/byterun/coq_memory.c b/kernel/byterun/coq_memory.c
index 45cfae509..b2917a55e 100644
--- a/kernel/byterun/coq_memory.c
+++ b/kernel/byterun/coq_memory.c
@@ -24,10 +24,6 @@ value * coq_stack_threshold;
asize_t coq_max_stack_size = Coq_max_stack_size;
/* global_data */
-
-value coq_global_data;
-value coq_atom_tbl;
-
int drawinstr;
/* interp state */
@@ -58,9 +54,6 @@ static void (*coq_prev_scan_roots_hook) (scanning_action);
static void coq_scan_roots(scanning_action action)
{
register value * i;
- /* Scan the global variables */
- (*action)(coq_global_data, &coq_global_data);
- (*action)(coq_atom_tbl, &coq_atom_tbl);
/* Scan the stack */
for (i = coq_sp; i < coq_stack_high; i++) {
(*action) (*i, i);
@@ -79,24 +72,10 @@ void init_coq_stack()
coq_max_stack_size = Coq_max_stack_size;
}
-void init_coq_global_data(long requested_size)
-{
- int i;
- coq_global_data = alloc_shr(requested_size, 0);
- for (i = 0; i < requested_size; i++)
- Field (coq_global_data, i) = Val_unit;
-}
-
-void init_coq_atom_tbl(long requested_size){
- int i;
- coq_atom_tbl = alloc_shr(requested_size, 0);
- for (i = 0; i < requested_size; i++) Field (coq_atom_tbl, i) = Val_unit;
-}
-
void init_coq_interpreter()
{
coq_sp = coq_stack_high;
- coq_interprete(NULL, Val_unit, Val_unit, 0);
+ coq_interprete(NULL, Val_unit, Atom(0), Atom(0), Val_unit, 0);
}
static int coq_vm_initialized = 0;
@@ -112,8 +91,6 @@ value init_coq_vm(value unit) /* ML */
#endif /* THREADED_CODE */
/* Allocate the table of global and the stack */
init_coq_stack();
- init_coq_global_data(Coq_global_data_Size);
- init_coq_atom_tbl(40);
/* Initialing the interpreter */
init_coq_interpreter();
@@ -157,53 +134,6 @@ void realloc_coq_stack(asize_t required_space)
#undef shift
}
-value get_coq_global_data(value unit) /* ML */
-{
- return coq_global_data;
-}
-
-value get_coq_atom_tbl(value unit) /* ML */
-{
- return coq_atom_tbl;
-}
-
-value realloc_coq_global_data(value size) /* ML */
-{
- mlsize_t requested_size, actual_size, i;
- value new_global_data;
- requested_size = Long_val(size);
- actual_size = Wosize_val(coq_global_data);
- if (requested_size >= actual_size) {
- requested_size = (requested_size + 0x100) & 0xFFFFFF00;
- new_global_data = alloc_shr(requested_size, 0);
- for (i = 0; i < actual_size; i++)
- initialize(&Field(new_global_data, i), Field(coq_global_data, i));
- for (i = actual_size; i < requested_size; i++){
- Field (new_global_data, i) = Val_long (0);
- }
- coq_global_data = new_global_data;
- }
- return Val_unit;
-}
-
-value realloc_coq_atom_tbl(value size) /* ML */
-{
- mlsize_t requested_size, actual_size, i;
- value new_atom_tbl;
- requested_size = Long_val(size);
- actual_size = Wosize_val(coq_atom_tbl);
- if (requested_size >= actual_size) {
- requested_size = (requested_size + 0x100) & 0xFFFFFF00;
- new_atom_tbl = alloc_shr(requested_size, 0);
- for (i = 0; i < actual_size; i++)
- initialize(&Field(new_atom_tbl, i), Field(coq_atom_tbl, i));
- for (i = actual_size; i < requested_size; i++)
- Field (new_atom_tbl, i) = Val_long (0);
- coq_atom_tbl = new_atom_tbl;
- }
- return Val_unit;
-}
-
value coq_set_drawinstr(value unit)
{
drawinstr = 1;
diff --git a/kernel/byterun/coq_memory.h b/kernel/byterun/coq_memory.h
index cec34f566..9375b15de 100644
--- a/kernel/byterun/coq_memory.h
+++ b/kernel/byterun/coq_memory.h
@@ -20,7 +20,6 @@
#define Coq_stack_size (4096 * sizeof(value))
#define Coq_stack_threshold (256 * sizeof(value))
-#define Coq_global_data_Size (4096 * sizeof(value))
#define Coq_max_stack_size (256 * 1024)
#define TRANSP 0
@@ -34,9 +33,7 @@ extern value * coq_stack_threshold;
/* global_data */
-extern value coq_global_data;
extern int coq_all_transp;
-extern value coq_atom_tbl;
extern int drawinstr;
/* interp state */
@@ -53,10 +50,6 @@ value init_coq_vm(value unit); /* ML */
value re_init_coq_vm(value unit); /* ML */
void realloc_coq_stack(asize_t required_space);
-value get_coq_global_data(value unit); /* ML */
-value realloc_coq_global_data(value size); /* ML */
-value get_coq_atom_tbl(value unit); /* ML */
-value realloc_coq_atom_tbl(value size); /* ML */
value coq_set_transp_value(value transp); /* ML */
value get_coq_transp_value(value unit); /* ML */
#endif /* _COQ_MEMORY_ */
diff --git a/kernel/cClosure.ml b/kernel/cClosure.ml
index 5f683790c..08114abc4 100644
--- a/kernel/cClosure.ml
+++ b/kernel/cClosure.ml
@@ -96,7 +96,7 @@ module type RedFlagsSig = sig
val red_transparent : reds -> transparent_state
val mkflags : red_kind list -> reds
val red_set : reds -> red_kind -> bool
- val red_projection : reds -> projection -> bool
+ val red_projection : reds -> Projection.t -> bool
end
module RedFlags = (struct
@@ -364,7 +364,7 @@ and fterm =
| FInd of pinductive
| FConstruct of pconstructor
| FApp of fconstr * fconstr array
- | FProj of projection * fconstr
+ | FProj of Projection.t * fconstr
| FFix of fixpoint * fconstr subs
| FCoFix of cofixpoint * fconstr subs
| FCaseT of case_info * constr * fconstr * constr array * fconstr subs (* predicate and branches are closures *)
diff --git a/kernel/cClosure.mli b/kernel/cClosure.mli
index 3a7f77d52..e2f5a3b82 100644
--- a/kernel/cClosure.mli
+++ b/kernel/cClosure.mli
@@ -74,7 +74,7 @@ module type RedFlagsSig = sig
(** This tests if the projection is in unfolded state already or
is unfodable due to delta. *)
- val red_projection : reds -> projection -> bool
+ val red_projection : reds -> Projection.t -> bool
end
module RedFlags : RedFlagsSig
@@ -132,7 +132,7 @@ type fterm =
| FInd of inductive Univ.puniverses
| FConstruct of constructor Univ.puniverses
| FApp of fconstr * fconstr array
- | FProj of projection * fconstr
+ | FProj of Projection.t * fconstr
| FFix of fixpoint * fconstr subs
| FCoFix of cofixpoint * fconstr subs
| FCaseT of case_info * constr * fconstr * constr array * fconstr subs (* predicate and branches are closures *)
diff --git a/kernel/cbytegen.ml b/kernel/cbytegen.ml
index 70dc6867a..a771945dd 100644
--- a/kernel/cbytegen.ml
+++ b/kernel/cbytegen.ml
@@ -829,6 +829,8 @@ let is_univ_copy max u =
else
false
+let dump_bytecode = ref false
+
let dump_bytecodes init code fvs =
let open Pp in
(str "code =" ++ fnl () ++
@@ -872,7 +874,7 @@ let compile ~fail_on_error ?universes:(universes=0) env c =
reloc, init_code
in
let fv = List.rev (!(reloc.in_env).fv_rev) in
- (if !Flags.dump_bytecode then
+ (if !dump_bytecode then
Feedback.msg_debug (dump_bytecodes init_code !fun_code fv)) ;
Some (init_code,!fun_code, Array.of_list fv)
with TooLargeInductive msg ->
diff --git a/kernel/cbytegen.mli b/kernel/cbytegen.mli
index abab58b60..1c4cdcbeb 100644
--- a/kernel/cbytegen.mli
+++ b/kernel/cbytegen.mli
@@ -25,3 +25,6 @@ val compile_constant_body : fail_on_error:bool ->
(** Shortcut of the previous function used during module strengthening *)
val compile_alias : Names.Constant.t -> body_code
+
+(** Dump the bytecode after compilation (for debugging purposes) *)
+val dump_bytecode : bool ref
diff --git a/kernel/clambda.ml b/kernel/clambda.ml
index 7b637c20e..641d424e2 100644
--- a/kernel/clambda.ml
+++ b/kernel/clambda.ml
@@ -807,7 +807,7 @@ and lambda_of_args env start args =
(*********************************)
-
+let dump_lambda = ref false
let optimize_lambda lam =
let lam = simplify subst_id lam in
@@ -819,7 +819,7 @@ let lambda_of_constr ~optimize genv c =
Renv.push_rels env (Array.of_list ids);
let lam = lambda_of_constr env c in
let lam = if optimize then optimize_lambda lam else lam in
- if !Flags.dump_lambda then
+ if !dump_lambda then
Feedback.msg_debug (pp_lam lam);
lam
diff --git a/kernel/clambda.mli b/kernel/clambda.mli
index 89b7fd8e3..6cf46163e 100644
--- a/kernel/clambda.mli
+++ b/kernel/clambda.mli
@@ -25,3 +25,6 @@ val dynamic_int31_compilation : bool -> lambda array -> lambda
(*spiwack: compiling function to insert dynamic decompilation before
matching integers (in case they are in processor representation) *)
val int31_escape_before_match : bool -> lambda -> lambda
+
+(** Dump the VM lambda code after compilation (for debugging purposes) *)
+val dump_lambda : bool ref
diff --git a/kernel/constr.ml b/kernel/constr.ml
index ba7fecadf..bc486210d 100644
--- a/kernel/constr.ml
+++ b/kernel/constr.ml
@@ -100,7 +100,7 @@ type ('constr, 'types, 'sort, 'univs) kind_of_term =
| Case of case_info * 'constr * 'constr * 'constr array
| Fix of ('constr, 'types) pfixpoint
| CoFix of ('constr, 'types) pcofixpoint
- | Proj of projection * 'constr
+ | Proj of Projection.t * 'constr
(* constr is the fixpoint of the previous type. Requires option
-rectypes of the Caml compiler to be set *)
type t = (t, t, Sorts.t, Instance.t) kind_of_term
@@ -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 98c0eaa28..b35ea6653 100644
--- a/kernel/constr.mli
+++ b/kernel/constr.mli
@@ -122,7 +122,7 @@ val mkConst : Constant.t -> constr
val mkConstU : pconstant -> constr
(** Constructs a projection application *)
-val mkProj : (projection * constr) -> constr
+val mkProj : (Projection.t * constr) -> constr
(** Inductive types *)
@@ -220,7 +220,7 @@ type ('constr, 'types, 'sort, 'univs) kind_of_term =
| Case of case_info * 'constr * 'constr * 'constr array
| Fix of ('constr, 'types) pfixpoint
| CoFix of ('constr, 'types) pcofixpoint
- | Proj of projection * 'constr
+ | Proj of Projection.t * 'constr
(** User view of [constr]. For [App], it is ensured there is at
least one argument and the function is not itself an applicative
@@ -318,7 +318,7 @@ where [info] is pretty-printing information *)
val destCase : constr -> case_info * constr * constr * constr array
(** Destructs a projection *)
-val destProj : constr -> projection * constr
+val destProj : constr -> Projection.t * constr
(** Destructs the {% $ %}i{% $ %}th function of the block
[Fixpoint f{_ 1} ctx{_ 1} = b{_ 1}
@@ -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/csymtable.ml b/kernel/csymtable.ml
index 012948954..4f3cbf289 100644
--- a/kernel/csymtable.ml
+++ b/kernel/csymtable.ml
@@ -26,7 +26,9 @@ open Cbytegen
module NamedDecl = Context.Named.Declaration
module RelDecl = Context.Rel.Declaration
-external eval_tcode : tcode -> values array -> values = "coq_eval_tcode"
+external eval_tcode : tcode -> atom array -> vm_global -> values array -> values = "coq_eval_tcode"
+
+type global_data = { mutable glob_len : int; mutable glob_val : values array }
(*******************)
(* Linkage du code *)
@@ -37,21 +39,28 @@ external eval_tcode : tcode -> values array -> values = "coq_eval_tcode"
(* [global_data] contient les valeurs des constantes globales
(axiomes,definitions), les annotations des switch et les structured
constant *)
-external global_data : unit -> values array = "get_coq_global_data"
+let global_data = {
+ glob_len = 0;
+ glob_val = Array.make 4096 crazy_val;
+}
-(* [realloc_global_data n] augmente de n la taille de [global_data] *)
-external realloc_global_data : int -> unit = "realloc_coq_global_data"
+let get_global_data () = Vmvalues.vm_global global_data.glob_val
-let check_global_data n =
- if n >= Array.length (global_data()) then realloc_global_data n
+let realloc_global_data n =
+ let n = min (2 * n + 0x100) Sys.max_array_length in
+ let ans = Array.make n crazy_val in
+ let src = global_data.glob_val in
+ let () = Array.blit src 0 ans 0 (Array.length src) in
+ global_data.glob_val <- ans
-let num_global = ref 0
+let check_global_data n =
+ if n >= Array.length global_data.glob_val then realloc_global_data n
let set_global v =
- let n = !num_global in
+ let n = global_data.glob_len in
check_global_data n;
- (global_data()).(n) <- v;
- incr num_global;
+ global_data.glob_val.(n) <- v;
+ global_data.glob_len <- global_data.glob_len + 1;
n
(* table pour les structured_constant et les annotations des switchs *)
@@ -164,7 +173,7 @@ and eval_to_patch env (buff,pl,fv) =
in
let tc = patch buff pl slots in
let vm_env = Array.map (slot_for_fv env) fv in
- eval_tcode tc vm_env
+ eval_tcode tc (get_atom_rel ()) (vm_global global_data.glob_val) vm_env
and val_of_constr env c =
match compile ~fail_on_error:true env c with
diff --git a/kernel/csymtable.mli b/kernel/csymtable.mli
index 19b2b8b50..d32cfba36 100644
--- a/kernel/csymtable.mli
+++ b/kernel/csymtable.mli
@@ -18,3 +18,5 @@ val val_of_constr : env -> constr -> Vmvalues.values
val set_opaque_const : Constant.t -> unit
val set_transparent_const : Constant.t -> unit
+
+val get_global_data : unit -> Vmvalues.vm_global
diff --git a/kernel/environ.mli b/kernel/environ.mli
index 4e6ac1e72..fdd84b25b 100644
--- a/kernel/environ.mli
+++ b/kernel/environ.mli
@@ -168,7 +168,7 @@ val constant_opt_value_in : env -> Constant.t puniverses -> constr option
(** {6 Primitive projections} *)
-val lookup_projection : Names.projection -> env -> projection_body
+val lookup_projection : Names.Projection.t -> env -> projection_body
val is_projection : Constant.t -> env -> bool
(** {5 Inductive types } *)
diff --git a/kernel/kernel.mllib b/kernel/kernel.mllib
index 370185a72..5d270125a 100644
--- a/kernel/kernel.mllib
+++ b/kernel/kernel.mllib
@@ -43,6 +43,6 @@ Subtyping
Mod_typing
Nativelibrary
Safe_typing
-Vm
Csymtable
+Vm
Vconv
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 ffd96781b..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
@@ -547,6 +532,8 @@ val eq_constant_key : Constant.t -> Constant.t -> bool
(** equalities on constant and inductive names (for the checker) *)
val eq_con_chk : Constant.t -> Constant.t -> bool
+[@@ocaml.deprecated "Same as [Constant.UserOrd.equal]."]
+
val eq_ind_chk : inductive -> inductive -> bool
(** {6 Deprecated functions. For backward compatibility.} *)
@@ -633,27 +620,27 @@ val eq_label : Label.t -> Label.t -> bool
(** {5 Unique bound module names} *)
type mod_bound_id = MBId.t
-(** Alias type. *)
+[@@ocaml.deprecated "Same as [MBId.t]."]
-val mod_bound_id_ord : mod_bound_id -> mod_bound_id -> int
+val mod_bound_id_ord : MBId.t -> MBId.t -> int
[@@ocaml.deprecated "Same as [MBId.compare]."]
-val mod_bound_id_eq : mod_bound_id -> mod_bound_id -> bool
+val mod_bound_id_eq : MBId.t -> MBId.t -> bool
[@@ocaml.deprecated "Same as [MBId.equal]."]
-val make_mbid : DirPath.t -> Id.t -> mod_bound_id
+val make_mbid : DirPath.t -> Id.t -> MBId.t
[@@ocaml.deprecated "Same as [MBId.make]."]
-val repr_mbid : mod_bound_id -> int * Id.t * DirPath.t
+val repr_mbid : MBId.t -> int * Id.t * DirPath.t
[@@ocaml.deprecated "Same as [MBId.repr]."]
-val id_of_mbid : mod_bound_id -> Id.t
+val id_of_mbid : MBId.t -> Id.t
[@@ocaml.deprecated "Same as [MBId.to_id]."]
-val string_of_mbid : mod_bound_id -> string
+val string_of_mbid : MBId.t -> string
[@@ocaml.deprecated "Same as [MBId.to_string]."]
-val debug_string_of_mbid : mod_bound_id -> string
+val debug_string_of_mbid : MBId.t -> string
[@@ocaml.deprecated "Same as [MBId.debug_to_string]."]
(** {5 Names} *)
@@ -745,6 +732,30 @@ module Projection : sig
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/term.ml b/kernel/term.ml
index 403ed881c..e1affb1c0 100644
--- a/kernel/term.ml
+++ b/kernel/term.ml
@@ -92,7 +92,7 @@ type ('constr, 'types, 'sort, 'univs) kind_of_term =
| Case of case_info * 'constr * 'constr * 'constr array
| Fix of ('constr, 'types) pfixpoint
| CoFix of ('constr, 'types) pcofixpoint
- | Proj of projection * 'constr
+ | Proj of Projection.t * 'constr
type values = Vmvalues.values
diff --git a/kernel/term.mli b/kernel/term.mli
index 7cb3b662d..ee84dcb2b 100644
--- a/kernel/term.mli
+++ b/kernel/term.mli
@@ -155,7 +155,7 @@ val destCase : constr -> case_info * constr * constr * constr array
[@@ocaml.deprecated "Alias for [Constr.destCase]"]
(** Destructs a projection *)
-val destProj : constr -> projection * constr
+val destProj : constr -> Projection.t * constr
[@@ocaml.deprecated "Alias for [Constr.destProj]"]
(** Destructs the {% $ %}i{% $ %}th function of the block
@@ -403,7 +403,7 @@ val mkApp : constr * constr array -> constr
[@@ocaml.deprecated "Alias for Constr"]
val mkConst : Constant.t -> constr
[@@ocaml.deprecated "Alias for Constr"]
-val mkProj : projection * constr -> constr
+val mkProj : Projection.t * constr -> constr
[@@ocaml.deprecated "Alias for Constr"]
val mkInd : inductive -> constr
[@@ocaml.deprecated "Alias for Constr"]
@@ -571,7 +571,7 @@ type ('constr, 'types, 'sort, 'univs) kind_of_term =
| Case of Constr.case_info * 'constr * 'constr * 'constr array
| Fix of ('constr, 'types) Constr.pfixpoint
| CoFix of ('constr, 'types) Constr.pcofixpoint
- | Proj of projection * 'constr
+ | Proj of Projection.t * 'constr
[@@ocaml.deprecated "Alias for Constr.kind_of_term"]
type values = Vmvalues.values
diff --git a/kernel/typeops.mli b/kernel/typeops.mli
index bff40b017..85b2cfffd 100644
--- a/kernel/typeops.mli
+++ b/kernel/typeops.mli
@@ -60,7 +60,7 @@ val judge_of_constant : env -> pconstant -> unsafe_judgment
(** {6 type of an applied projection } *)
-val judge_of_projection : env -> Names.projection -> unsafe_judgment -> unsafe_judgment
+val judge_of_projection : env -> Projection.t -> unsafe_judgment -> unsafe_judgment
(** {6 Type of application. } *)
val judge_of_apply :
@@ -100,7 +100,7 @@ val judge_of_case : env -> case_info
-> unsafe_judgment -> unsafe_judgment -> unsafe_judgment array
-> unsafe_judgment
-val type_of_projection_constant : env -> Names.projection puniverses -> types
+val type_of_projection_constant : env -> Projection.t puniverses -> types
val type_of_constant_in : env -> pconstant -> types
diff --git a/kernel/uGraph.ml b/kernel/uGraph.ml
index 5d1644614..e6b27077b 100644
--- a/kernel/uGraph.ml
+++ b/kernel/uGraph.ml
@@ -21,7 +21,7 @@ open Univ
(* Revisions by Bruno Barras, Hugo Herbelin, Pierre Letouzey, Matthieu
Sozeau, Pierre-Marie Pédrot, Jacques-Henri Jourdan *)
-let error_inconsistency o u v (p:explanation option) =
+let error_inconsistency o u v p =
raise (UniverseInconsistency (o,Universe.make u,Universe.make v,p))
(* Universes are stratified by a partial ordering $\le$.
@@ -557,8 +557,7 @@ let get_explanation strict u v g =
else match traverse strict u with Some exp -> exp | None -> assert false
let get_explanation strict u v g =
- if !Flags.univ_print then Some (get_explanation strict u v g)
- else None
+ Some (lazy (get_explanation strict u v g))
(* To compare two nodes, we simply do a forward search.
We implement two improvements:
@@ -768,18 +767,18 @@ let normalize_universes g =
g.entries g
let constraints_of_universes g =
+ let module UF = Unionfind.Make (LSet) (LMap) in
+ let uf = UF.create () in
let constraints_of u v acc =
match v with
| Canonical {univ=u; ltle} ->
UMap.fold (fun v strict acc->
let typ = if strict then Lt else Le in
Constraint.add (u,typ,v) acc) ltle acc
- | Equiv v -> Constraint.add (u,Eq,v) acc
+ | Equiv v -> UF.union u v uf; acc
in
- UMap.fold constraints_of g.entries Constraint.empty
-
-let constraints_of_universes g =
- constraints_of_universes (normalize_universes g)
+ let csts = UMap.fold constraints_of g.entries Constraint.empty in
+ csts, UF.partition uf
(** [sort_universes g] builds a totally ordered universe graph. The
output graph should imply the input graph (and the implication
diff --git a/kernel/uGraph.mli b/kernel/uGraph.mli
index d4fba63fb..cca2eb472 100644
--- a/kernel/uGraph.mli
+++ b/kernel/uGraph.mli
@@ -59,7 +59,10 @@ val empty_universes : t
val sort_universes : t -> t
-val constraints_of_universes : t -> Constraint.t
+(** [constraints_of_universes g] returns [csts] and [partition] where
+ [csts] are the non-Eq constraints and [partition] is the partition
+ of the universes into equivalence classes. *)
+val constraints_of_universes : t -> Constraint.t * LSet.t list
val check_subtype : AUContext.t check_function
(** [check_subtype univ ctx1 ctx2] checks whether [ctx2] is an instance of
diff --git a/kernel/univ.ml b/kernel/univ.ml
index ea3a52295..8e19fa4e5 100644
--- a/kernel/univ.ml
+++ b/kernel/univ.ml
@@ -541,11 +541,11 @@ let constraint_type_ord c1 c2 = match c1, c2 with
(* Universe inconsistency: error raised when trying to enforce a relation
that would create a cycle in the graph of universes. *)
-type univ_inconsistency = constraint_type * universe * universe * explanation option
+type univ_inconsistency = constraint_type * universe * universe * explanation Lazy.t option
exception UniverseInconsistency of univ_inconsistency
-let error_inconsistency o u v (p:explanation option) =
+let error_inconsistency o u v p =
raise (UniverseInconsistency (o,make u,make v,p))
(* Constraints and sets of constraints. *)
@@ -1235,13 +1235,16 @@ let explain_universe_inconsistency prl (o,u,v,p) =
| Eq -> str"=" | Lt -> str"<" | Le -> str"<="
in
let reason = match p with
- | None | Some [] -> mt()
+ | None -> mt()
| Some p ->
- str " because" ++ spc() ++ pr_uni v ++
+ let p = Lazy.force p in
+ if p = [] then mt ()
+ else
+ str " because" ++ spc() ++ pr_uni v ++
prlist (fun (r,v) -> spc() ++ pr_rel r ++ str" " ++ pr_uni v)
- p ++
+ p ++
(if Universe.equal (snd (List.last p)) u then mt() else
- (spc() ++ str "= " ++ pr_uni u))
+ (spc() ++ str "= " ++ pr_uni u))
in
str "Cannot enforce" ++ spc() ++ pr_uni u ++ spc() ++
pr_rel o ++ spc() ++ pr_uni v ++ reason
diff --git a/kernel/univ.mli b/kernel/univ.mli
index aaed899bf..b68bbdf35 100644
--- a/kernel/univ.mli
+++ b/kernel/univ.mli
@@ -205,7 +205,7 @@ val enforce_leq_level : Level.t constraint_function
Constraint.t...
*)
type explanation = (constraint_type * Universe.t) list
-type univ_inconsistency = constraint_type * Universe.t * Universe.t * explanation option
+type univ_inconsistency = constraint_type * Universe.t * Universe.t * explanation Lazy.t option
exception UniverseInconsistency of univ_inconsistency
diff --git a/kernel/vm.ml b/kernel/vm.ml
index 14aeb732f..d7eedc226 100644
--- a/kernel/vm.ml
+++ b/kernel/vm.ml
@@ -42,8 +42,11 @@ external push_vstack : vstack -> int -> unit = "coq_push_vstack"
(* interpreteur *)
-external interprete : tcode -> values -> vm_env -> int -> values =
- "coq_interprete_ml"
+external coq_interprete : tcode -> values -> atom array -> vm_global -> vm_env -> int -> values =
+ "coq_interprete_byte" "coq_interprete_ml"
+
+let interprete code v env k =
+ coq_interprete code v (get_atom_rel ()) (Csymtable.get_global_data ()) env k
(* Functions over arguments *)
@@ -184,6 +187,6 @@ let apply_whd k whd =
push_val v;
interprete (cofix_upd_code to_up) (cofix_upd_val to_up) (cofix_upd_env to_up) 0
| Vatom_stk(a,stk) ->
- apply_stack (val_of_atom a) stk v
+ apply_stack (val_of_atom a) stk v
| Vuniv_level lvl -> assert false
diff --git a/kernel/vmvalues.ml b/kernel/vmvalues.ml
index 0e0cb4e58..6a41efac2 100644
--- a/kernel/vmvalues.ml
+++ b/kernel/vmvalues.ml
@@ -43,6 +43,7 @@ let fix_val v = (Obj.magic v : values)
let cofix_upd_val v = (Obj.magic v : values)
type vm_env
+type vm_global
let fun_env v = (Obj.magic v : vm_env)
let fix_env v = (Obj.magic v : vm_env)
let cofix_env v = (Obj.magic v : vm_env)
@@ -51,6 +52,8 @@ type vstack = values array
let fun_of_val v = (Obj.magic v : vfun)
+let vm_global (v : values array) = (Obj.magic v : vm_global)
+
(*******************************************)
(* Machine code *** ************************)
(*******************************************)
@@ -407,13 +410,20 @@ let check_fix f1 f2 =
else false
else false
-external atom_rel : unit -> atom array = "get_coq_atom_tbl"
-external realloc_atom_rel : int -> unit = "realloc_coq_atom_tbl"
+let atom_rel : atom array ref =
+ let init i = Aid (RelKey i) in
+ ref (Array.init 40 init)
+
+let get_atom_rel () = !atom_rel
+
+let realloc_atom_rel n =
+ let n = min (2 * n + 0x100) Sys.max_array_length in
+ let init i = Aid (RelKey i) in
+ let ans = Array.init n init in
+ atom_rel := ans
let relaccu_tbl =
- let atom_rel = atom_rel() in
- let len = Array.length atom_rel in
- for i = 0 to len - 1 do atom_rel.(i) <- Aid (RelKey i) done;
+ let len = Array.length !atom_rel in
ref (Array.init len mkAccuCode)
let relaccu_code i =
@@ -422,9 +432,7 @@ let relaccu_code i =
else
begin
realloc_atom_rel i;
- let atom_rel = atom_rel () in
- let nl = Array.length atom_rel in
- for j = len to nl - 1 do atom_rel.(j) <- Aid(RelKey j) done;
+ let nl = Array.length !atom_rel in
relaccu_tbl :=
Array.init nl
(fun j -> if j < len then !relaccu_tbl.(j) else mkAccuCode j);
diff --git a/kernel/vmvalues.mli b/kernel/vmvalues.mli
index c6e342a96..550791b2c 100644
--- a/kernel/vmvalues.mli
+++ b/kernel/vmvalues.mli
@@ -15,6 +15,7 @@ open Cbytecodes
type values
type vm_env
+type vm_global
type vprod
type vfun
type vfix
@@ -33,6 +34,8 @@ val fix_env : vfix -> vm_env
val cofix_env : vcofix -> vm_env
val cofix_upd_env : to_update -> vm_env
+val vm_global : values array -> vm_global
+
(** Cast a value known to be a function, unsafe in general *)
val fun_of_val : values -> vfun
@@ -69,6 +72,9 @@ type atom =
| Aind of inductive
| Asort of Sorts.t
+val get_atom_rel : unit -> atom array
+(** Global table of rels *)
+
(** Zippers *)
type zipper =
diff --git a/lib/cWarnings.ml b/lib/cWarnings.ml
index 92c86eaea..fda25a0a6 100644
--- a/lib/cWarnings.ml
+++ b/lib/cWarnings.ml
@@ -22,11 +22,8 @@ type t = {
let warnings : (string, t) Hashtbl.t = Hashtbl.create 97
let categories : (string, string list) Hashtbl.t = Hashtbl.create 97
-let current_loc = ref None
let flags = ref ""
-let set_current_loc loc = current_loc := loc
-
let get_flags () = !flags
let add_warning_in_category ~name ~category =
@@ -170,7 +167,6 @@ let create ~name ~category ?(default=Enabled) pp =
set_flags !flags;
fun ?loc x ->
let w = Hashtbl.find warnings name in
- let loc = Option.append loc !current_loc in
match w.status with
| Disabled -> ()
| AsError -> CErrors.user_err ?loc (pp x)
diff --git a/lib/cWarnings.mli b/lib/cWarnings.mli
index fa96b18c8..f97a53c4d 100644
--- a/lib/cWarnings.mli
+++ b/lib/cWarnings.mli
@@ -10,8 +10,6 @@
type status = Disabled | Enabled | AsError
-val set_current_loc : Loc.t option -> unit
-
val create : name:string -> category:string -> ?default:status ->
('a -> Pp.t) -> ?loc:Loc.t -> 'a -> unit
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 8491873e0..56940f1cf 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -60,7 +60,6 @@ let profile = false
let ide_slave = ref false
let raw_print = ref false
-let univ_print = ref false
let we_are_parsing = ref false
@@ -160,11 +159,3 @@ let print_mod_uid = ref false
let profile_ltac = ref false
let profile_ltac_cutoff = ref 2.0
-
-let dump_bytecode = ref false
-let set_dump_bytecode = (:=) dump_bytecode
-let get_dump_bytecode () = !dump_bytecode
-
-let dump_lambda = ref false
-let set_dump_lambda = (:=) dump_lambda
-let get_dump_lambda () = !dump_lambda
diff --git a/lib/flags.mli b/lib/flags.mli
index 85aaf879f..17776d68a 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -10,6 +10,25 @@
(** Global options of the system. *)
+(** WARNING: don't add new entries to this file!
+
+ This file is own its way to deprecation in favor of a purely
+ functional state, but meanwhile it will contain options that are
+ truly global to the system such as [compat] or [debug]
+
+ If you are thinking about adding a global flag, well, just
+ don't. First of all, options make testins exponentially more
+ expensive, due to the growth of flag combinations. So please make
+ some effort in order for your idea to work in a configuration-free
+ manner.
+
+ If you absolutely must pass an option to your new system, then do
+ so as a functional argument so flags are exposed to unit
+ testing. Then, register such parameters with the proper
+ state-handling mechanism of the top-level subsystem of Coq.
+
+ *)
+
(** Command-line flags *)
val boot : bool ref
@@ -42,9 +61,6 @@ val we_are_parsing : bool ref
(* Set Printing All flag. For some reason it is a global flag *)
val raw_print : bool ref
-(* Univ print flag, never set anywere. Maybe should belong to Univ? *)
-val univ_print : bool ref
-
type compat_version = V8_6 | V8_7 | Current
val compat_version : compat_version ref
val version_compare : compat_version -> compat_version -> int
@@ -129,13 +145,3 @@ val print_mod_uid : bool ref
val profile_ltac : bool ref
val profile_ltac_cutoff : float ref
-
-(** Dump the bytecode after compilation (for debugging purposes) *)
-val dump_bytecode : bool ref
-val set_dump_bytecode : bool -> unit
-val get_dump_bytecode : unit -> bool
-
-(** Dump the VM lambda code after compilation (for debugging purposes) *)
-val dump_lambda : bool ref
-val set_dump_lambda : bool -> unit
-val get_dump_lambda : unit -> bool
diff --git a/lib/loc.ml b/lib/loc.ml
index 6f5283aab..1a09091bf 100644
--- a/lib/loc.ml
+++ b/lib/loc.ml
@@ -62,6 +62,11 @@ let merge_opt l1 l2 = match l1, l2 with
| None, Some l -> Some l
| Some l1, Some l2 -> Some (merge l1 l2)
+let finer l1 l2 = match l1, l2 with
+ | None, _ -> false
+ | Some l , None -> true
+ | Some l1, Some l2 -> l1.fname = l2.fname && merge l1 l2 = l2
+
let unloc loc = (loc.bp, loc.ep)
let shift_loc kb kp loc = { loc with bp = loc.bp + kb ; ep = loc.ep + kp }
diff --git a/lib/loc.mli b/lib/loc.mli
index 813c45fbb..23df1ebd9 100644
--- a/lib/loc.mli
+++ b/lib/loc.mli
@@ -42,6 +42,10 @@ val merge : t -> t -> t
val merge_opt : t option -> t option -> t option
(** Merge locations, usually generating the largest possible span *)
+val finer : t option -> t option -> bool
+(** Answers [true] when the first location is more defined, or, when
+ both defined, included in the second one *)
+
val shift_loc : int -> int -> t -> t
(** [shift_loc loc n p] shifts the beginning of location by [n] and
the end by [p]; it is assumed that the shifts do not change the
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/intf/decl_kinds.ml b/library/decl_kinds.ml
index 0d3285311..0d3285311 100644
--- a/intf/decl_kinds.ml
+++ b/library/decl_kinds.ml
diff --git a/library/declaremods.ml b/library/declaremods.ml
index 762efc5e3..1d5df49cf 100644
--- a/library/declaremods.ml
+++ b/library/declaremods.ml
@@ -17,11 +17,25 @@ open Entries
open Libnames
open Libobject
open Mod_subst
-open Vernacexpr
open Misctypes
(** {6 Inlining levels} *)
+(** Rigid / flexible module signature *)
+
+type 'a module_signature =
+ | Enforce of 'a (** ... : T *)
+ | Check of 'a list (** ... <: T1 <: T2, possibly empty *)
+
+(** Which module inline annotations should we honor,
+ either None or the ones whose level is less or equal
+ to the given integer *)
+
+type inline =
+ | NoInline
+ | DefaultInline
+ | InlineAt of int
+
let default_inline () = Some (Flags.get_inline_level ())
let inl2intopt = function
diff --git a/library/declaremods.mli b/library/declaremods.mli
index fd8d29614..4aee7feae 100644
--- a/library/declaremods.mli
+++ b/library/declaremods.mli
@@ -9,10 +9,24 @@
(************************************************************************)
open Names
-open Vernacexpr
(** {6 Modules } *)
+(** Rigid / flexible module signature *)
+
+type 'a module_signature =
+ | Enforce of 'a (** ... : T *)
+ | Check of 'a list (** ... <: T1 <: T2, possibly empty *)
+
+(** Which module inline annotations should we honor,
+ either None or the ones whose level is less or equal
+ to the given integer *)
+
+type inline =
+ | NoInline
+ | DefaultInline
+ | InlineAt of int
+
type 'modast module_interpretor =
Environ.env -> Misctypes.module_kind -> 'modast ->
Entries.module_struct_entry * Misctypes.module_kind * Univ.ContextSet.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/library.mllib b/library/library.mllib
index e43bfb5a1..1c0368847 100644
--- a/library/library.mllib
+++ b/library/library.mllib
@@ -4,7 +4,9 @@ Libobject
Summary
Nametab
Global
+Decl_kinds
Lib
+Misctypes
Declaremods
Loadpath
Library
diff --git a/intf/misctypes.ml b/library/misctypes.ml
index 72db3b31c..72db3b31c 100644
--- a/intf/misctypes.ml
+++ b/library/misctypes.ml
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/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index 593dcbf58..a1c563f53 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -17,6 +17,7 @@ open Constrexpr
open Constrexpr_ops
open Extend
open Decl_kinds
+open Declaremods
open Declarations
open Misctypes
open Tok (* necessary for camlp5 *)
@@ -47,6 +48,7 @@ let instance_name = Gram.entry_create "vernac:instance_name"
let section_subset_expr = Gram.entry_create "vernac:section_subset_expr"
let make_bullet s =
+ let open Proof_bullet in
let n = String.length s in
match s.[0] with
| '-' -> Dash n
@@ -644,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
@@ -769,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..0fbf2f567 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -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/cc/ccalgo.ml b/plugins/cc/ccalgo.ml
index 5a4818926..8e53a044d 100644
--- a/plugins/cc/ccalgo.ml
+++ b/plugins/cc/ccalgo.ml
@@ -9,7 +9,7 @@
(************************************************************************)
(* This file implements the basic congruence-closure algorithm by *)
-(* Downey,Sethi and Tarjan. *)
+(* Downey, Sethi and Tarjan. *)
(* Plus some e-matching and constructor handling by P. Corbineau *)
open CErrors
@@ -18,7 +18,6 @@ open Names
open Sorts
open Constr
open Vars
-open Evd
open Goptions
open Tacmach
open Util
@@ -272,7 +271,8 @@ type state =
mutable rew_depth:int;
mutable changed:bool;
by_type: Int.Set.t Typehash.t;
- mutable gls:Goal.goal Evd.sigma}
+ mutable env:Environ.env;
+ sigma:Evd.evar_map}
let dummy_node =
{
@@ -307,7 +307,8 @@ let empty depth gls:state =
rew_depth=depth;
by_type=Constrhash.create init_size;
changed=false;
- gls=gls
+ env=pf_env gls;
+ sigma=project gls
}
let forest state = state.uf
@@ -426,7 +427,7 @@ let cc_product s1 s2 =
mkLambda(_B_,mkSort(s2),_body_))
let rec constr_of_term = function
- Symb s-> applist_projection s []
+ Symb s-> s
| Product(s1,s2) -> cc_product s1 s2
| Eps id -> mkVar id
| Constructor cinfo -> mkConstructU cinfo.ci_constr
@@ -434,25 +435,7 @@ let rec constr_of_term = function
make_app [(constr_of_term s2)] s1
and make_app l=function
Appli (s1,s2)->make_app ((constr_of_term s2)::l) s1
- | other ->
- applist_proj other l
-and applist_proj c l =
- match c with
- | Symb s -> applist_projection s l
- | _ -> Term.applistc (constr_of_term c) l
-and applist_projection c l =
- match Constr.kind c with
- | Const c when Environ.is_projection (fst c) (Global.env()) ->
- let p = Projection.make (fst c) false in
- (match l with
- | [] -> (* Expand the projection *)
- let ty = Typeops.type_of_constant_in (Global.env ()) c in (* FIXME constraints *)
- let pb = Environ.lookup_projection p (Global.env()) in
- let ctx,_ = Term.decompose_prod_n_assum (pb.Declarations.proj_npars + 1) ty in
- Term.it_mkLambda_or_LetIn (mkProj(p,mkRel 1)) ctx
- | hd :: tl ->
- Term.applistc (mkProj (p, hd)) tl)
- | _ -> Term.applistc c l
+ | other -> Term.applist (constr_of_term other,l)
let rec canonize_name sigma c =
let c = EConstr.Unsafe.to_constr c in
@@ -511,8 +494,8 @@ let rec add_term state t=
Not_found ->
let b=next uf in
let trm = constr_of_term t in
- let typ = pf_unsafe_type_of state.gls (EConstr.of_constr trm) in
- let typ = canonize_name (project state.gls) typ in
+ let typ = Typing.unsafe_type_of state.env state.sigma (EConstr.of_constr trm) in
+ let typ = canonize_name state.sigma typ in
let new_node=
match t with
Symb _ | Product (_,_) ->
@@ -820,11 +803,10 @@ let one_step state =
let __eps__ = Id.of_string "_eps_"
let new_state_var typ state =
- let id = pf_get_new_id __eps__ state.gls in
- let {it=gl ; sigma=sigma} = state.gls in
- let gls = Goal.V82.new_goal_with sigma gl [Context.Named.Declaration.LocalAssum (id,typ)] in
- state.gls<- gls;
- id
+ let ids = Environ.ids_of_named_context_val (Environ.named_context_val state.env) in
+ let id = Namegen.next_ident_away __eps__ ids in
+ state.env<- EConstr.push_named (Context.Named.Declaration.LocalAssum (id,typ)) state.env;
+ id
let complete_one_class state i=
match (get_representative state.uf i).inductive_status with
@@ -832,9 +814,9 @@ let complete_one_class state i=
let rec app t typ n =
if n<=0 then t else
let _,etyp,rest= destProd typ in
- let id = new_state_var etyp state in
+ let id = new_state_var (EConstr.of_constr etyp) state in
app (Appli(t,Eps id)) (substl [mkVar id] rest) (n-1) in
- let _c = pf_unsafe_type_of state.gls
+ let _c = Typing.unsafe_type_of state.env state.sigma
(EConstr.of_constr (constr_of_term (term state.uf pac.cnode))) in
let _c = EConstr.Unsafe.to_constr _c in
let _args =
diff --git a/plugins/cc/cctac.ml b/plugins/cc/cctac.ml
index d19817e74..c4db49cd3 100644
--- a/plugins/cc/cctac.ml
+++ b/plugins/cc/cctac.ml
@@ -90,7 +90,7 @@ let rec decompose_term env sigma t=
decompose_term env sigma c
| _ ->
let t = Termops.strip_outer_cast sigma t in
- if closed0 sigma t then Symb (EConstr.to_constr sigma t) else raise Not_found
+ if closed0 sigma t then Symb (EConstr.to_constr ~abort_on_undefined_evars:false sigma t) else raise Not_found
(* decompose equality in members and type *)
open Termops
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/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..2d7a3e37b 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
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 285991797..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
@@ -77,17 +77,17 @@ module CM=Map.Make(Constr)
module History=Set.Make(Hitem)
let cm_add sigma typ nam cm=
- let typ = EConstr.to_constr sigma typ in
+ let typ = EConstr.to_constr ~abort_on_undefined_evars:false sigma typ in
try
let l=CM.find typ cm in CM.add typ (nam::l) cm
with
Not_found->CM.add typ [nam] cm
let cm_remove sigma typ nam cm=
- let typ = EConstr.to_constr sigma typ in
+ let typ = EConstr.to_constr ~abort_on_undefined_evars:false sigma typ in
try
let l=CM.find typ cm in
- let l0=List.filter (fun id-> not (Globnames.eq_gr id nam)) l in
+ let l0=List.filter (fun id-> not (GlobRef.equal id nam)) l in
match l0 with
[]->CM.remove typ cm
| _ ->CM.add typ l0 cm
@@ -97,7 +97,7 @@ module HP=Heap.Functional(OrderedFormula)
type t=
{redexes:HP.t;
- context:(global_reference list) CM.t;
+ context:(GlobRef.t list) CM.t;
latoms:constr list;
gl:types;
glatom:constr option;
@@ -117,7 +117,7 @@ let lookup sigma item seq=
let p (id2,o)=
match o with
None -> false
- | Some (m2, t2)-> Globnames.eq_gr id id2 && m2>m && more_general sigma (m2, EConstr.of_constr t2) (m, EConstr.of_constr t) in
+ | Some (m2, t2)-> GlobRef.equal id id2 && m2>m && more_general sigma (m2, EConstr.of_constr t2) (m, EConstr.of_constr t) in
History.exists p seq.history
let add_formula env sigma side nam t seq =
@@ -152,7 +152,7 @@ let re_add_formula_list sigma lf seq=
redexes=List.fold_right HP.add lf seq.redexes;
context=List.fold_right do_one lf seq.context}
-let find_left sigma t seq=List.hd (CM.find (EConstr.to_constr sigma t) seq.context)
+let find_left sigma t seq=List.hd (CM.find (EConstr.to_constr ~abort_on_undefined_evars:false sigma t) seq.context)
(*let rev_left seq=
try
@@ -187,9 +187,9 @@ let empty_seq depth=
let expand_constructor_hints =
List.map_append (function
- | IndRef ind ->
+ | GlobRef.IndRef ind ->
List.init (Inductiveops.nconstructors ind)
- (fun i -> ConstructRef (ind,i+1))
+ (fun i -> GlobRef.ConstructRef (ind,i+1))
| gr ->
[gr])
@@ -197,7 +197,7 @@ let extend_with_ref_list env sigma l seq =
let l = expand_constructor_hints l in
let f gr (seq, sigma) =
let sigma, c = Evd.fresh_global env sigma gr in
- let sigma, typ= Typing.type_of env sigma (EConstr.of_constr c) in
+ let sigma, typ= Typing.type_of env sigma c in
(add_formula env sigma Hyp gr typ seq, sigma) in
List.fold_right f l (seq, sigma)
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..0ea70c19f 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
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index d04887a48..8da0e1c4f 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -1050,8 +1050,7 @@ let do_replace (evd:Evd.evar_map ref) params rec_arg_num rev_args_id f fun_num a
(Global.env ()) !evd
(Constrintern.locate_reference (qualid_of_ident equation_lemma_id))
in
- let res = EConstr.of_constr res in
- evd:=evd';
+ evd:=evd';
let _ = Typing.e_type_of ~refresh:true (Global.env ()) evd res in
res
in
diff --git a/plugins/funind/functional_principles_types.ml b/plugins/funind/functional_principles_types.ml
index 804548ce5..04a23cdb9 100644
--- a/plugins/funind/functional_principles_types.ml
+++ b/plugins/funind/functional_principles_types.ml
@@ -266,7 +266,7 @@ let change_property_sort evd toSort princ princName =
(Global.env ()) evd (Constrintern.locate_reference (Libnames.qualid_of_ident princName)) in
let init =
let nargs = (princ_info.nparams + (List.length princ_info.predicates)) in
- mkApp(princName_as_constr,
+ mkApp(EConstr.Unsafe.to_constr princName_as_constr,
Array.init nargs
(fun i -> mkRel (nargs - i )))
in
@@ -630,11 +630,14 @@ 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 (EConstr.of_constr f) in
- if isConst f
- then (destConst f,sort)
- else user_err Pp.(pr_constr_env (Global.env ()) !evd f ++spc () ++ str "should be the named of a globally defined function")
- )
+ let _ = Typing.e_type_of ~refresh:true (Global.env ()) evd f in
+ let c, u =
+ try EConstr.destConst !evd f
+ with DestKO ->
+ user_err Pp.(pr_econstr_env (Global.env ()) !evd f ++spc () ++ str "should be the named of a globally defined function")
+ in
+ (c, EConstr.EInstance.kind !evd u), sort
+ )
fas
) in
let bodies_types =
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 40ea40b6b..ae238b846 100644
--- a/plugins/funind/glob_termops.ml
+++ b/plugins/funind/glob_termops.ml
@@ -563,7 +563,8 @@ let resolve_and_replace_implicits ?(flags=Pretyping.all_and_fail_flags) ?(expect
(* FIXME : JF (30/03/2017) I'm not completely sure to have split understand as needed.
If someone knows how to prevent solved existantial removal in understand, please do not hesitate to change the computation of [ctx] here *)
let ctx,_,_ = Pretyping.ise_pretype_gen flags env sigma Glob_ops.empty_lvar expected_type rt in
- let ctx, f = Evarutil.nf_evars_and_universes ctx in
+ let ctx = Evd.minimize_universes ctx in
+ let f c = EConstr.of_constr (Evarutil.nf_evars_universes ctx (EConstr.Unsafe.to_constr c)) in
(* then we map [rt] to replace the implicit holes by their values *)
let rec change rt =
@@ -575,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)
| _ -> ()
)
@@ -586,8 +587,8 @@ If someone knows how to prevent solved existantial removal in understand, pleas
with Found evi -> (* we found the evar corresponding to this hole *)
match evi.evar_body with
| Evar_defined c ->
- (* we just have to lift the solution in glob_term *)
- Detyping.detype Detyping.Now false Id.Set.empty env ctx (EConstr.of_constr (f c))
+ (* we just have to lift the solution in glob_term *)
+ Detyping.detype Detyping.Now false Id.Set.empty env ctx (f c)
| Evar_empty -> rt (* the hole was not solved : we do nothing *)
)
| (GHole(BinderType na,_,_)) -> (* we only want to deal with implicit arguments *)
@@ -609,7 +610,7 @@ If someone knows how to prevent solved existantial removal in understand, pleas
match evi.evar_body with
| Evar_defined c ->
(* we just have to lift the solution in glob_term *)
- Detyping.detype Detyping.Now false Id.Set.empty env ctx (EConstr.of_constr (f c))
+ Detyping.detype Detyping.Now false Id.Set.empty env ctx (f c)
| Evar_empty -> rt (* the hole was not solved : we d when falseo nothing *)
in
res
diff --git a/plugins/funind/glob_termops.mli b/plugins/funind/glob_termops.mli
index 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 9c350483b..7df57b577 100644
--- a/plugins/funind/indfun.ml
+++ b/plugins/funind/indfun.ml
@@ -77,8 +77,7 @@ let functional_induction with_clean c princl pat =
user_err (str "Cannot find induction principle for "
++ Printer.pr_leconstr_env (Tacmach.pf_env g) sigma (mkConst c') )
in
- let princ = EConstr.of_constr princ in
- (princ,NoBindings,Tacmach.pf_unsafe_type_of g' princ,g')
+ (princ,NoBindings,Tacmach.pf_unsafe_type_of g' princ,g')
| _ -> raise (UserError(None,str "functional induction must be used with a function" ))
end
| Some ((princ,binding)) ->
@@ -91,10 +90,19 @@ let functional_induction with_clean c princl pat =
if princ_infos.Tactics.farg_in_concl
then [c] else []
in
+ if List.length args + List.length c_list = 0
+ then user_err Pp.(str "Cannot recognize a valid functional scheme" );
let encoded_pat_as_patlist =
- List.make (List.length args + List.length c_list - 1) None @ [pat] in
- List.map2 (fun c pat -> ((None,Ltac_plugin.Tacexpr.ElimOnConstr (fun env sigma -> (sigma,(c,NoBindings)) )),(None,pat),None))
- (args@c_list) encoded_pat_as_patlist
+ List.make (List.length args + List.length c_list - 1) None @ [pat]
+ in
+ List.map2
+ (fun c pat ->
+ ((None,
+ Ltac_plugin.Tacexpr.ElimOnConstr (fun env sigma -> (sigma,(c,NoBindings)))),
+ (None,pat),
+ None))
+ (args@c_list)
+ encoded_pat_as_patlist
in
let princ' = Some (princ,bindings) in
let princ_vars =
@@ -252,7 +260,6 @@ let derive_inversion fix_names =
let evd,c =
Evd.fresh_global
(Global.env ()) evd (Constrintern.locate_reference (Libnames.qualid_of_ident id)) in
- let c = EConstr.of_constr c in
let (cst, u) = destConst evd c in
evd, (cst, EInstance.kind evd u) :: l
)
@@ -274,8 +281,7 @@ let derive_inversion fix_names =
(Global.env ()) evd
(Constrintern.locate_reference (Libnames.qualid_of_ident (mk_rel_id id)))
in
- let id = EConstr.of_constr id in
- evd,(fst (destInd evd id))::l
+ evd,(fst (destInd evd id))::l
)
fix_names
(evd',[])
@@ -379,7 +385,7 @@ let generate_principle (evd:Evd.evar_map ref) pconstants on_error
let evd = ref (Evd.from_env env) in
let evd',uprinc = Evd.fresh_global env !evd princ in
let _ = evd := evd' in
- let princ_type = Typing.e_type_of ~refresh:true env evd (EConstr.of_constr uprinc) in
+ let princ_type = Typing.e_type_of ~refresh:true env evd uprinc in
let princ_type = EConstr.Unsafe.to_constr princ_type in
Functional_principles_types.generate_functional_principle
evd
@@ -416,7 +422,6 @@ let register_struct is_rec (fixpoint_exprl:(Vernacexpr.fixpoint_expr * Vernacexp
let evd,c =
Evd.fresh_global
(Global.env ()) evd (Constrintern.locate_reference (Libnames.qualid_of_ident fname)) in
- let c = EConstr.of_constr c in
let (cst, u) = destConst evd c in
let u = EInstance.kind evd u in
evd,((cst, u) :: l)
@@ -433,7 +438,6 @@ let register_struct is_rec (fixpoint_exprl:(Vernacexpr.fixpoint_expr * Vernacexp
let evd,c =
Evd.fresh_global
(Global.env ()) evd (Constrintern.locate_reference (Libnames.qualid_of_ident fname)) in
- let c = EConstr.of_constr c in
let (cst, u) = destConst evd c in
let u = EInstance.kind evd u in
evd,((cst, u) :: l)
@@ -842,7 +846,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.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 ae84eaa93..28e85268a 100644
--- a/plugins/funind/invfun.ml
+++ b/plugins/funind/invfun.ml
@@ -102,7 +102,6 @@ let generate_type evd g_to_f f graph i =
let evd',graph =
Evd.fresh_global (Global.env ()) !evd (Globnames.IndRef (fst (destInd !evd graph)))
in
- let graph = EConstr.of_constr graph in
evd:=evd';
let graph_arity = Typing.e_type_of (Global.env ()) evd graph in
let ctxt,_ = decompose_prod_assum !evd graph_arity in
@@ -172,7 +171,6 @@ let find_induction_principle evd f =
| None -> raise Not_found
| Some rect_lemma ->
let evd',rect_lemma = Evd.fresh_global (Global.env ()) !evd (Globnames.ConstRef rect_lemma) in
- let rect_lemma = EConstr.of_constr rect_lemma in
let evd',typ = Typing.type_of ~refresh:true (Global.env ()) evd' rect_lemma in
evd:=evd';
rect_lemma,typ
@@ -823,8 +821,7 @@ let derive_correctness make_scheme (funs: pconstant list) (graphs:inductive list
(* let lem_cst = fst (destConst (Constrintern.global_reference lem_id)) in *)
let _,lem_cst_constr = Evd.fresh_global
(Global.env ()) !evd (Constrintern.locate_reference (Libnames.qualid_of_ident lem_id)) in
- let lem_cst_constr = EConstr.of_constr lem_cst_constr in
- let (lem_cst,_) = destConst !evd lem_cst_constr in
+ let (lem_cst,_) = destConst !evd lem_cst_constr in
update_Function {finfo with correctness_lemma = Some lem_cst};
)
@@ -884,8 +881,7 @@ let derive_correctness make_scheme (funs: pconstant list) (graphs:inductive list
let finfo = find_Function_infos (fst f_as_constant) in
let _,lem_cst_constr = Evd.fresh_global
(Global.env ()) !evd (Constrintern.locate_reference (Libnames.qualid_of_ident lem_id)) in
- let lem_cst_constr = EConstr.of_constr lem_cst_constr in
- let (lem_cst,_) = destConst !evd lem_cst_constr in
+ let (lem_cst,_) = destConst !evd lem_cst_constr in
update_Function {finfo with completeness_lemma = Some lem_cst}
)
funs)
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 fb9ae64bf..2a3a85fcc 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -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 *)
@@ -1456,7 +1456,7 @@ let com_terminate
-let start_equation (f:global_reference) (term_f:global_reference)
+let start_equation (f:GlobRef.t) (term_f:GlobRef.t)
(cont_tactic:Id.t list -> tactic) g =
let sigma = project g in
let ids = pf_ids_of_hyps g in
@@ -1473,7 +1473,7 @@ let start_equation (f:global_reference) (term_f:global_reference)
observe_tac (str "prove_eq") (cont_tactic x)]) g;;
let (com_eqn : int -> Id.t ->
- global_reference -> global_reference -> global_reference
+ GlobRef.t -> GlobRef.t -> GlobRef.t
-> Constr.t -> unit) =
fun nb_arg eq_name functional_ref f_ref terminate_ref equation_lemma_type ->
let open CVars in
@@ -1533,14 +1533,12 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
let env = Global.env() in
let evd = Evd.from_env env in
let evd, function_type = interp_type_evars env evd type_of_f in
- let function_type = EConstr.Unsafe.to_constr function_type in
- let env = push_named (Context.Named.Declaration.LocalAssum (function_name,function_type)) env in
+ let env = EConstr.push_named (Context.Named.Declaration.LocalAssum (function_name,function_type)) env in
(* Pp.msgnl (str "function type := " ++ Printer.pr_lconstr function_type); *)
let evd, ty = interp_type_evars env evd ~impls:rec_impls eq in
- let ty = EConstr.Unsafe.to_constr ty in
- let evd, nf = Evarutil.nf_evars_and_universes evd in
- let equation_lemma_type = nf_betaiotazeta (EConstr.of_constr (nf ty)) in
- let function_type = nf function_type in
+ let evd = Evd.minimize_universes evd in
+ let equation_lemma_type = nf_betaiotazeta (Evarutil.nf_evar evd ty) in
+ let function_type = EConstr.to_constr ~abort_on_undefined_evars:false evd function_type in
let equation_lemma_type = EConstr.Unsafe.to_constr equation_lemma_type in
(* Pp.msgnl (str "lemma type := " ++ Printer.pr_lconstr equation_lemma_type ++ fnl ()); *)
let res_vars,eq' = decompose_prod equation_lemma_type in
diff --git a/plugins/ltac/extratactics.ml4 b/plugins/ltac/extratactics.ml4
index 2e90ce90c..797dfbe23 100644
--- a/plugins/ltac/extratactics.ml4
+++ b/plugins/ltac/extratactics.ml4
@@ -296,7 +296,6 @@ let project_hint ~poly pri l2r r =
let env = Global.env() in
let sigma = Evd.from_env env in
let sigma, c = Evd.fresh_global env sigma gr in
- let c = EConstr.of_constr c in
let t = Retyping.get_type_of env sigma c in
let t =
Tacred.reduce_to_quantified_ref env sigma (Lazy.force coq_iff_ref) t in
@@ -307,7 +306,6 @@ let project_hint ~poly pri l2r r =
let p =
if l2r then build_coq_iff_left_proj () else build_coq_iff_right_proj () in
let sigma, p = Evd.fresh_global env sigma p in
- let p = EConstr.of_constr p in
let c = Reductionops.whd_beta sigma (mkApp (c, Context.Rel.to_extended_vect mkRel 0 sign)) in
let c = it_mkLambda_or_LetIn
(mkApp (p,[|mkArrow a (lift 1 b);mkArrow b (lift 1 a);c|])) sign in
@@ -317,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/g_ltac.ml4 b/plugins/ltac/g_ltac.ml4
index 0c42a8bb2..4857beffa 100644
--- a/plugins/ltac/g_ltac.ml4
+++ b/plugins/ltac/g_ltac.ml4
@@ -325,6 +325,7 @@ GEXTEND Gram
;
toplevel_selector:
[ [ sel = selector_body; ":" -> sel
+ | "!"; ":" -> SelectAlreadyFocused
| IDENT "all"; ":" -> SelectAll ] ]
;
tactic_mode:
@@ -415,7 +416,7 @@ let is_explicit_terminator = function TacSolve _ -> true | _ -> false
VERNAC tactic_mode EXTEND VernacSolve
| [ - ltac_selector_opt(g) ltac_info_opt(n) tactic(t) ltac_use_default(def) ] =>
[ classify_as_proofstep ] -> [
- let g = Option.default (Proof_bullet.get_default_goal_selector ()) g in
+ let g = Option.default (Goal_select.get_default_goal_selector ()) g in
vernac_solve g n t def
]
| [ - "par" ":" ltac_info_opt(n) tactic(t) ltac_use_default(def) ] =>
diff --git a/plugins/ltac/pptactic.ml b/plugins/ltac/pptactic.ml
index 11bb7a234..bd02d85d5 100644
--- a/plugins/ltac/pptactic.ml
+++ b/plugins/ltac/pptactic.ml
@@ -515,6 +515,7 @@ let string_of_genarg_arg (ArgumentType arg) =
else int i ++ str "-" ++ int j
let pr_goal_selector toplevel = function
+ | SelectAlreadyFocused -> str "!:"
| SelectNth i -> int i ++ str ":"
| SelectList l -> prlist_with_sep (fun () -> str ", ") pr_range_selector l ++ str ":"
| SelectId id -> str "[" ++ Id.print id ++ str "]:"
diff --git a/plugins/ltac/pptactic.mli b/plugins/ltac/pptactic.mli
index aea00c240..799a52cc8 100644
--- a/plugins/ltac/pptactic.mli
+++ b/plugins/ltac/pptactic.mli
@@ -84,7 +84,7 @@ type pp_tactic = {
pptac_prods : grammar_terminals;
}
-val pr_goal_selector : toplevel:bool -> Vernacexpr.goal_selector -> Pp.t
+val pr_goal_selector : toplevel:bool -> Goal_select.t -> Pp.t
val declare_notation_tactic_pprule : KerName.t -> pp_tactic -> unit
diff --git a/plugins/ltac/rewrite.ml b/plugins/ltac/rewrite.ml
index d32a2faef..9eb55aa5e 100644
--- a/plugins/ltac/rewrite.ml
+++ b/plugins/ltac/rewrite.ml
@@ -428,7 +428,8 @@ let split_head = function
| [] -> assert(false)
let eq_pb (ty, env, x, y as pb) (ty', env', x', y' as pb') =
- pb == pb' || (ty == ty' && Constr.equal x x' && Constr.equal y y')
+ let equal x y = Constr.equal (EConstr.Unsafe.to_constr x) (EConstr.Unsafe.to_constr y) in
+ pb == pb' || (ty == ty' && equal x x' && equal y y')
let problem_inclusion x y =
List.for_all (fun pb -> List.exists (fun pb' -> eq_pb pb pb') y) x
@@ -626,9 +627,9 @@ let solve_remaining_by env sigma holes by =
(** Evar should not be defined, but just in case *)
| Some evi ->
let env = Environ.reset_with_named_context evi.evar_hyps env in
- let ty = EConstr.of_constr evi.evar_concl in
+ let ty = evi.evar_concl in
let c, sigma = Pfedit.refine_by_tactic env sigma ty solve_tac in
- Evd.define evk c sigma
+ Evd.define evk (EConstr.of_constr c) sigma
in
List.fold_left solve sigma indep
@@ -1862,7 +1863,6 @@ let declare_projection n instance_id r =
let env = Global.env () in
let sigma = Evd.from_env env in
let sigma,c = Evd.fresh_global env sigma r in
- let c = EConstr.of_constr c in
let ty = Retyping.get_type_of env sigma c in
let term = proper_projection sigma c ty in
let sigma, typ = Typing.type_of env sigma term in
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/tacexpr.ml b/plugins/ltac/tacexpr.ml
index 3baa475ab..17f5e5d41 100644
--- a/plugins/ltac/tacexpr.ml
+++ b/plugins/ltac/tacexpr.ml
@@ -35,7 +35,8 @@ type advanced_flag = bool (* true = advanced false = basic *)
type letin_flag = bool (* true = use local def false = use Leibniz *)
type clear_flag = bool option (* true = clear hyp, false = keep hyp, None = use default *)
-type goal_selector = Vernacexpr.goal_selector =
+type goal_selector = Goal_select.t =
+ | SelectAlreadyFocused
| SelectNth of int
| SelectList of (int * int) list
| SelectId of Id.t
@@ -269,7 +270,7 @@ and 'a gen_tactic_expr =
('p,'a gen_tactic_expr) match_rule list
| TacFun of 'a gen_tactic_fun_ast
| TacArg of 'a gen_tactic_arg located
- | TacSelect of Vernacexpr.goal_selector * 'a gen_tactic_expr
+ | TacSelect of Goal_select.t * 'a gen_tactic_expr
(* For ML extensions *)
| TacML of (ml_tactic_entry * 'a gen_tactic_arg list) Loc.located
(* For syntax extensions *)
diff --git a/plugins/ltac/tacexpr.mli b/plugins/ltac/tacexpr.mli
index 3baa475ab..17f5e5d41 100644
--- a/plugins/ltac/tacexpr.mli
+++ b/plugins/ltac/tacexpr.mli
@@ -35,7 +35,8 @@ type advanced_flag = bool (* true = advanced false = basic *)
type letin_flag = bool (* true = use local def false = use Leibniz *)
type clear_flag = bool option (* true = clear hyp, false = keep hyp, None = use default *)
-type goal_selector = Vernacexpr.goal_selector =
+type goal_selector = Goal_select.t =
+ | SelectAlreadyFocused
| SelectNth of int
| SelectList of (int * int) list
| SelectId of Id.t
@@ -269,7 +270,7 @@ and 'a gen_tactic_expr =
('p,'a gen_tactic_expr) match_rule list
| TacFun of 'a gen_tactic_fun_ast
| TacArg of 'a gen_tactic_arg located
- | TacSelect of Vernacexpr.goal_selector * 'a gen_tactic_expr
+ | TacSelect of Goal_select.t * 'a gen_tactic_expr
(* For ML extensions *)
| TacML of (ml_tactic_entry * 'a gen_tactic_arg list) Loc.located
(* For syntax extensions *)
diff --git a/plugins/ltac/tacinterp.ml b/plugins/ltac/tacinterp.ml
index 6a4bf577b..84049d4ed 100644
--- a/plugins/ltac/tacinterp.ml
+++ b/plugins/ltac/tacinterp.ml
@@ -2010,7 +2010,8 @@ let interp_redexp env sigma r =
let _ =
let eval lfun env sigma ty tac =
- let ist = { lfun = lfun; extra = TacStore.empty; } in
+ let extra = TacStore.set TacStore.empty f_debug (get_debug ()) in
+ let ist = { lfun = lfun; extra; } in
let tac = interp_tactic ist tac in
let (c, sigma) = Pfedit.refine_by_tactic env sigma ty tac in
(EConstr.of_constr c, sigma)
diff --git a/plugins/ltac/tactic_debug.ml b/plugins/ltac/tactic_debug.ml
index 57a11d947..105b5c59a 100644
--- a/plugins/ltac/tactic_debug.ml
+++ b/plugins/ltac/tactic_debug.ml
@@ -399,8 +399,6 @@ let skip_extensions trace =
| [] -> [] in
List.rev (aux (List.rev trace))
-let finer_loc loc1 loc2 = Loc.merge_opt loc1 loc2 = loc2
-
let extract_ltac_trace ?loc trace =
let trace = skip_extensions trace in
let (tloc,c),tail = List.sep_last trace in
@@ -408,7 +406,7 @@ let extract_ltac_trace ?loc trace =
(* We entered a user-defined tactic,
we display the trace with location of the call *)
let msg = hov 0 (explain_ltac_call_trace c tail loc ++ fnl()) in
- (if finer_loc loc tloc then loc else tloc), Some msg
+ (if Loc.finer loc tloc then loc else tloc), Some msg
else
(* We entered a primitive tactic, we don't display trace but
report on the finest location *)
@@ -417,7 +415,7 @@ let extract_ltac_trace ?loc trace =
let rec aux best_loc = function
| (loc,_)::tail ->
if Option.is_empty best_loc ||
- not (Option.is_empty loc) && finer_loc loc best_loc
+ not (Option.is_empty loc) && Loc.finer loc best_loc
then
aux loc tail
else
diff --git a/plugins/setoid_ring/Algebra_syntax.v b/plugins/setoid_ring/Algebra_syntax.v
index e896554ea..1204bbd2e 100644
--- a/plugins/setoid_ring/Algebra_syntax.v
+++ b/plugins/setoid_ring/Algebra_syntax.v
@@ -1,3 +1,12 @@
+(************************************************************************)
+(* * 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) *)
+(************************************************************************)
Class Zero (A : Type) := zero : A.
Notation "0" := zero.
diff --git a/plugins/setoid_ring/Integral_domain.v b/plugins/setoid_ring/Integral_domain.v
index 0c16fe1a3..98407cb6d 100644
--- a/plugins/setoid_ring/Integral_domain.v
+++ b/plugins/setoid_ring/Integral_domain.v
@@ -1,3 +1,13 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
Require Export Cring.
diff --git a/plugins/setoid_ring/RealField.v b/plugins/setoid_ring/RealField.v
index facd2e062..38bc58a65 100644
--- a/plugins/setoid_ring/RealField.v
+++ b/plugins/setoid_ring/RealField.v
@@ -1,3 +1,13 @@
+(************************************************************************)
+(* * 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 Nnat.
Require Import ArithRing.
Require Export Ring Field.
diff --git a/plugins/setoid_ring/Ring_tac.v b/plugins/setoid_ring/Ring_tac.v
index 36d1e7c54..e8efb362e 100644
--- a/plugins/setoid_ring/Ring_tac.v
+++ b/plugins/setoid_ring/Ring_tac.v
@@ -1,3 +1,13 @@
+(************************************************************************)
+(* * 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) *)
+(************************************************************************)
+
Set Implicit Arguments.
Require Import Setoid.
Require Import BinPos.
diff --git a/plugins/setoid_ring/Rings_Q.v b/plugins/setoid_ring/Rings_Q.v
index fd7654713..ae91ee166 100644
--- a/plugins/setoid_ring/Rings_Q.v
+++ b/plugins/setoid_ring/Rings_Q.v
@@ -1,3 +1,13 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
Require Export Cring.
Require Export Integral_domain.
diff --git a/plugins/setoid_ring/Rings_R.v b/plugins/setoid_ring/Rings_R.v
index fd219c235..901b36ed3 100644
--- a/plugins/setoid_ring/Rings_R.v
+++ b/plugins/setoid_ring/Rings_R.v
@@ -1,3 +1,13 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
Require Export Cring.
Require Export Integral_domain.
diff --git a/plugins/setoid_ring/Rings_Z.v b/plugins/setoid_ring/Rings_Z.v
index 605a23a98..75e77ab6e 100644
--- a/plugins/setoid_ring/Rings_Z.v
+++ b/plugins/setoid_ring/Rings_Z.v
@@ -1,3 +1,13 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
Require Export Cring.
Require Export Integral_domain.
Require Export Ncring_initial.
diff --git a/plugins/setoid_ring/newring.ml b/plugins/setoid_ring/newring.ml
index 99bb8440c..5facf2a80 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
@@ -186,8 +186,8 @@ let dummy_goal env sigma =
Goal.V82.mk_goal sigma (named_context_val env) EConstr.mkProp Evd.Store.empty in
{Evd.it = gl; Evd.sigma = sigma}
-let constr_of v = match Value.to_constr v with
- | Some c -> EConstr.Unsafe.to_constr c
+let constr_of evd v = match Value.to_constr v with
+ | Some c -> EConstr.to_constr evd c
| None -> failwith "Ring.exec_tactic: anomaly"
let tactic_res = ref [||]
@@ -221,8 +221,8 @@ let exec_tactic env evd n f args =
(** Evaluate the whole result *)
let gl = dummy_goal env evd in
let gls = Proofview.V82.of_tactic (Tacinterp.eval_tactic_ist ist (ltac_call f (args@[getter]))) gl in
- let evd, nf = Evarutil.nf_evars_and_universes (Refiner.project gls) in
- let nf c = nf (constr_of c) in
+ let evd = Evd.minimize_universes (Refiner.project gls) in
+ let nf c = constr_of evd c in
Array.map nf !tactic_res, Evd.universe_context_set evd
let stdlib_modules =
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 d5118da4c..e9e045a53 100644
--- a/plugins/ssr/ssrcommon.ml
+++ b/plugins/ssr/ssrcommon.ml
@@ -504,16 +504,17 @@ let nf_evar sigma t =
EConstr.Unsafe.to_constr (Evarutil.nf_evar sigma (EConstr.of_constr t))
let pf_abs_evars2 gl rigid (sigma, c0) =
- let c0 = EConstr.to_constr sigma c0 in
+ let c0 = EConstr.to_constr ~abort_on_undefined_evars:false sigma c0 in
let sigma0, ucst = project gl, Evd.evar_universe_context sigma in
let nenv = env_size (pf_env gl) in
let abs_evar n k =
let evi = Evd.find sigma k in
- let dc = CList.firstn n (evar_filtered_context evi) in
+ let concl = EConstr.Unsafe.to_constr evi.evar_concl in
+ let dc = EConstr.Unsafe.to_named_context (CList.firstn n (evar_filtered_context evi)) in
let abs_dc c = function
| NamedDecl.LocalDef (x,b,t) -> mkNamedLetIn x b t (mkArrow t c)
| NamedDecl.LocalAssum (x,t) -> mkNamedProd x t c in
- let t = Context.Named.fold_inside abs_dc ~init:evi.evar_concl dc in
+ let t = Context.Named.fold_inside abs_dc ~init:concl dc in
nf_evar sigma t in
let rec put evlist c = match Constr.kind c with
| Evar (k, a) ->
@@ -569,11 +570,12 @@ let pf_abs_evars_pirrel gl (sigma, c0) =
let nenv = env_size (pf_env gl) in
let abs_evar n k =
let evi = Evd.find sigma k in
- let dc = CList.firstn n (evar_filtered_context evi) in
+ let concl = EConstr.Unsafe.to_constr evi.evar_concl in
+ let dc = EConstr.Unsafe.to_named_context (CList.firstn n (evar_filtered_context evi)) in
let abs_dc c = function
| NamedDecl.LocalDef (x,b,t) -> mkNamedLetIn x b t (mkArrow t c)
| NamedDecl.LocalAssum (x,t) -> mkNamedProd x t c in
- let t = Context.Named.fold_inside abs_dc ~init:evi.evar_concl dc in
+ let t = Context.Named.fold_inside abs_dc ~init:concl dc in
nf_evar sigma0 (nf_evar sigma t) in
let rec put evlist c = match Constr.kind c with
| Evar (k, a) ->
@@ -581,7 +583,7 @@ let pf_abs_evars_pirrel gl (sigma, c0) =
let n = max 0 (Array.length a - nenv) in
let k_ty =
Retyping.get_sort_family_of
- (pf_env gl) sigma (EConstr.of_constr (Evd.evar_concl (Evd.find sigma k))) in
+ (pf_env gl) sigma (Evd.evar_concl (Evd.find sigma k)) in
let is_prop = k_ty = InProp in
let t = abs_evar n k in (k, (n, t, is_prop)) :: put evlist t
| _ -> Constr.fold put evlist c in
@@ -746,7 +748,7 @@ let pf_mkSsrConst name gl =
let pf_fresh_global name gl =
let sigma, env, it = project gl, pf_env gl, sig_it gl in
let sigma,t = Evd.fresh_global env sigma name in
- t, re_sig it sigma
+ EConstr.Unsafe.to_constr t, re_sig it sigma
let mkProt t c gl =
let prot, gl = pf_mkSsrConst "protect_term" gl in
@@ -800,8 +802,11 @@ let rec is_name_in_ipats name = function
List.exists (function SsrHyp(_,id) -> id = name) clr
|| is_name_in_ipats name tl
| IPatId id :: tl -> id = name || is_name_in_ipats name tl
- | (IPatCase l | IPatDispatch l) :: tl -> List.exists (is_name_in_ipats name) l || is_name_in_ipats name tl
- | _ :: tl -> is_name_in_ipats name tl
+ | IPatAbstractVars ids :: tl ->
+ CList.mem_f Id.equal name ids || is_name_in_ipats name tl
+ | (IPatCase l | IPatDispatch l | IPatInj l) :: tl ->
+ List.exists (is_name_in_ipats name) l || is_name_in_ipats name tl
+ | (IPatView _ | IPatAnon _ | IPatSimpl _ | IPatRewrite _ | IPatTac _ | IPatNoop) :: tl -> is_name_in_ipats name tl
| [] -> false
let view_error s gv =
@@ -980,7 +985,7 @@ let applyn ~with_evars ?beta ?(with_shelve=false) n t gl =
if not (EConstr.Vars.closed0 sigma ty) then
raise dependent_apply_error;
let m = Evarutil.new_meta () in
- loop (meta_declare m (EConstr.Unsafe.to_constr ty) sigma) bo ((EConstr.mkMeta m)::args) (n-1)
+ loop (meta_declare m ty sigma) bo ((EConstr.mkMeta m)::args) (n-1)
| _ -> assert false
in loop sigma t [] n in
pp(lazy(str"Refiner.refiner " ++ Printer.pr_econstr_env (pf_env gl) (project gl) t));
@@ -1500,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 717657a24..87d107d65 100644
--- a/plugins/ssr/ssrelim.ml
+++ b/plugins/ssr/ssrelim.ml
@@ -356,7 +356,7 @@ let ssrelim ?(ind=ref None) ?(is_case=false) deps what ?elim eqid elim_intro_tac
let ev = List.fold_left Evar.Set.union Evar.Set.empty patterns_ev in
let ty_ev = Evar.Set.fold (fun i e ->
let ex = i in
- let i_ty = EConstr.of_constr (Evd.evar_concl (Evd.find (project gl) ex)) in
+ let i_ty = Evd.evar_concl (Evd.find (project gl) ex) in
Evar.Set.union e (evars_of_term i_ty))
ev Evar.Set.empty in
let inter = Evar.Set.inter ev ty_ev in
@@ -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 57635edac..7d7655d29 100644
--- a/plugins/ssr/ssrequality.ml
+++ b/plugins/ssr/ssrequality.ml
@@ -276,7 +276,7 @@ let unfoldintac occ rdx t (kt,_) gl =
let foldtac occ rdx ft gl =
let sigma0, concl0, env0 = project gl, pf_concl gl, pf_env gl in
let sigma, t = ft in
- let t = EConstr.to_constr sigma t in
+ let t = EConstr.to_constr ~abort_on_undefined_evars:false sigma t in
let fold, conclude = match rdx with
| Some (_, (In_T _ | In_X_In_T _)) | None ->
let ise = Evd.create_evar_defs sigma in
@@ -359,7 +359,7 @@ let pirrel_rewrite pred rdx rdx_ty new_rdx dir (sigma, c) c_ty gl =
let evs = Evar.Set.elements (Evarutil.undefined_evars_of_term sigma t) in
let open_evs = List.filter (fun k ->
Sorts.InProp <> Retyping.get_sort_family_of
- env sigma (EConstr.of_constr (Evd.evar_concl (Evd.find sigma k))))
+ env sigma (Evd.evar_concl (Evd.find sigma k)))
evs in
if open_evs <> [] then Some name else None)
(List.combine (Array.to_list args) names)
@@ -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
@@ -478,10 +478,10 @@ let rwprocess_rule dir rule gl =
| _ -> let ra = Array.append a [|r|] in
function 1 ->
let sigma, pi1 = Evd.fresh_global env sigma coq_prod.Coqlib.proj1 in
- EConstr.mkApp (EConstr.of_constr pi1, ra), sigma
+ EConstr.mkApp (pi1, ra), sigma
| _ ->
let sigma, pi2 = Evd.fresh_global env sigma coq_prod.Coqlib.proj2 in
- EConstr.mkApp (EConstr.of_constr pi2, ra), sigma in
+ 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
let s, sigma = sr sigma 2 in
loop (converse_dir d) sigma s a.(1) rs 0
@@ -557,7 +557,7 @@ let rwrxtac occ rdx_pat dir rule gl =
let rpat env sigma0 (sigma, pats) (d, r, lhs, rhs) =
let sigma, pat =
let rw_progress rhs t evd = rw_progress rhs (EConstr.of_constr t) evd in
- mk_tpattern env sigma0 (sigma,EConstr.to_constr sigma r) (rw_progress rhs) d (EConstr.to_constr sigma lhs) in
+ mk_tpattern env sigma0 (sigma, EConstr.to_constr ~abort_on_undefined_evars:false sigma r) (rw_progress rhs) d (EConstr.to_constr ~abort_on_undefined_evars:false sigma lhs) in
sigma, pats @ [pat] in
let rpats = List.fold_left (rpat env0 sigma0) (r_sigma,[]) rules in
let find_R, end_R = mk_tpattern_matcher sigma0 occ ~upats_origin rpats in
@@ -567,7 +567,7 @@ let rwrxtac occ rdx_pat dir rule gl =
let r = ref None in
(fun env c _ h -> do_once r (fun () -> find_rule (EConstr.of_constr c), c); mkRel h),
(fun concl -> closed0_check concl e gl;
- let (d,(ev,ctx,c)) , x = assert_done r in (d,(ev,ctx, EConstr.to_constr ev c)) , x) in
+ let (d,(ev,ctx,c)) , x = assert_done r in (d,(ev,ctx, EConstr.to_constr ~abort_on_undefined_evars:false ev c)) , x) in
let concl0 = EConstr.Unsafe.to_constr concl0 in
let concl = eval_pattern env0 sigma0 concl0 rdx_pat occ find_R in
let (d, r), rdx = conclude concl in
@@ -589,7 +589,10 @@ let ssrinstancesofrule ist dir arg gl =
let rpat env sigma0 (sigma, pats) (d, r, lhs, rhs) =
let sigma, pat =
let rw_progress rhs t evd = rw_progress rhs (EConstr.of_constr t) evd in
- mk_tpattern env sigma0 (sigma,EConstr.to_constr sigma r) (rw_progress rhs) d (EConstr.to_constr sigma lhs) in
+ mk_tpattern env sigma0
+ (sigma,EConstr.to_constr ~abort_on_undefined_evars:false sigma r)
+ (rw_progress rhs) d
+ (EConstr.to_constr ~abort_on_undefined_evars:false sigma lhs) in
sigma, pats @ [pat] in
let rpats = List.fold_left (rpat env0 sigma0) (r_sigma,[]) rules in
mk_tpattern_matcher ~all_instances:true ~raise_NoMatch:true sigma0 None ~upats_origin rpats in
diff --git a/plugins/ssr/ssripats.ml b/plugins/ssr/ssripats.ml
index 7897cb170..b397c5531 100644
--- a/plugins/ssr/ssripats.ml
+++ b/plugins/ssr/ssripats.ml
@@ -218,15 +218,16 @@ let rec ipat_tac1 future_ipats ipat : unit tactic =
Ssrview.tclIPAT_VIEWS ~views:l
~conclusion:(fun ~to_clear:clr -> intro_clear clr future_ipats)
| IPatDispatch ipatss ->
- tclEXTEND (List.map ipat_tac ipatss) (tclUNIT ()) []
+ tclEXTEND (List.map (ipat_tac future_ipats) ipatss) (tclUNIT ()) []
| IPatId id -> Ssrcommon.tclINTRO_ID id
| IPatCase ipatss ->
- tclIORPAT (Ssrcommon.tclWITHTOP tac_case) ipatss
+ tclIORPAT (Ssrcommon.tclWITHTOP tac_case) future_ipats ipatss
| IPatInj ipatss ->
tclIORPAT (Ssrcommon.tclWITHTOP
- (fun t -> V82.tactic ~nf_evars:false (Ssrelim.perform_injection t))) ipatss
+ (fun t -> V82.tactic ~nf_evars:false (Ssrelim.perform_injection t)))
+ future_ipats ipatss
| IPatAnon Drop -> intro_drop
| IPatAnon One -> Ssrcommon.tclINTRO_ANON
@@ -254,17 +255,17 @@ let rec ipat_tac1 future_ipats ipat : unit tactic =
| IPatTac t -> t
-and ipat_tac pl : unit tactic =
+and ipat_tac future_ipats pl : unit tactic =
match pl with
| [] -> tclUNIT ()
| pat :: pl ->
- Ssrcommon.tcl0G (tclLOG pat (ipat_tac1 pl)) <*>
+ Ssrcommon.tcl0G (tclLOG pat (ipat_tac1 (pl @ future_ipats))) <*>
isTICK pat <*>
- ipat_tac pl
+ ipat_tac future_ipats pl
-and tclIORPAT tac = function
+and tclIORPAT tac future_ipats = function
| [[]] -> tac
- | p -> Tacticals.New.tclTHENS tac (List.map ipat_tac p)
+ | p -> Tacticals.New.tclTHENS tac (List.map (ipat_tac future_ipats) p)
let split_at_first_case ipats =
let rec loop acc = function
@@ -285,7 +286,7 @@ let main ?eqtac ~first_case_is_dispatch ipats =
let case = ssr_exception first_case_is_dispatch case in
let case = option_to_list case in
let eqtac = option_to_list (Option.map (fun x -> IPatTac x) eqtac) in
- Ssrcommon.tcl0G (ipat_tac (ip_before @ case @ eqtac @ ip_after) <*> intro_end)
+ Ssrcommon.tcl0G (ipat_tac [] (ip_before @ case @ eqtac @ ip_after) <*> intro_end)
end (* }}} *)
@@ -418,7 +419,7 @@ let tclLAST_GEN ~to_ind ((oclr, occ), t) conclusion = tclINDEPENDENTL begin
Goal.enter_one begin fun g ->
let pat = Ssrmatching.interp_cpattern sigma0 t None in
let cl0, env, sigma, hyps = Goal.(concl g, env g, sigma g, hyps g) in
- let cl = EConstr.to_constr sigma cl0 in
+ let cl = EConstr.to_constr ~abort_on_undefined_evars:false sigma cl0 in
let (c, ucst), cl =
try Ssrmatching.fill_occ_pattern ~raise_NoMatch:true env sigma cl pat occ 1
with Ssrmatching.NoMatch -> Ssrmatching.redex_of_pattern env pat, cl in
@@ -623,7 +624,7 @@ let tacFIND_ABSTRACT_PROOF check_lock abstract_n =
Goal.enter_one ~__LOC__ begin fun g ->
let sigma, env = Goal.(sigma g, env g) in
let l = Evd.fold_undefined (fun e ei l ->
- match EConstr.kind sigma (EConstr.of_constr ei.Evd.evar_concl) with
+ match EConstr.kind sigma ei.Evd.evar_concl with
| Term.App(hd, [|ty; n; lock|])
when (not check_lock ||
(occur_existential_or_casted_meta sigma ty &&
diff --git a/plugins/ssr/ssrview.ml b/plugins/ssr/ssrview.ml
index aa614fbc1..fc50b24a6 100644
--- a/plugins/ssr/ssrview.ml
+++ b/plugins/ssr/ssrview.ml
@@ -254,7 +254,7 @@ let finalize_view s0 ?(simple_types=true) p =
Goal.enter_one ~__LOC__ begin fun g ->
let env = Goal.env g in
let sigma = Goal.sigma g in
- let evars_of_p = Evd.evars_of_term (EConstr.to_constr sigma p) in
+ let evars_of_p = Evd.evars_of_term (EConstr.to_constr ~abort_on_undefined_evars:false sigma p) in
let filter x _ = Evar.Set.mem x evars_of_p in
let sigma = Typeclasses.resolve_typeclasses ~fail:false ~filter env sigma in
let p = Reductionops.nf_evar sigma p in
@@ -265,7 +265,7 @@ Goal.enter_one ~__LOC__ begin fun g ->
List.fold_left (fun l k ->
if Evd.is_defined sigma k then
let bo = get_body Evd.(evar_body (find sigma k)) in
- k :: l @ Evar.Set.elements (evars_of_econstr sigma bo)
+ k :: l @ Evar.Set.elements (evars_of_econstr sigma (EConstr.Unsafe.to_constr bo))
else l
) [] s in
let und0 = (* Unassigned evars in the initial goal *)
diff --git a/plugins/ssrmatching/ssrmatching.ml4 b/plugins/ssrmatching/ssrmatching.ml4
index 2ba6acc03..a10437a63 100644
--- a/plugins/ssrmatching/ssrmatching.ml4
+++ b/plugins/ssrmatching/ssrmatching.ml4
@@ -283,7 +283,7 @@ exception NoProgress
(* comparison can be much faster than the HO one. *)
let unif_EQ env sigma p c =
- let evars = existential_opt_value sigma, Evd.universes sigma in
+ let evars = existential_opt_value0 sigma, Evd.universes sigma in
try let _ = Reduction.conv env p ~evars c in true with _ -> false
let unif_EQ_args env sigma pa a =
@@ -337,7 +337,7 @@ let nf_open_term sigma0 ise c =
let s = ise and s' = ref sigma0 in
let rec nf c' = match kind c' with
| Evar ex ->
- begin try nf (existential_value s ex) with _ ->
+ begin try nf (existential_value0 s ex) with _ ->
let k, a = ex in let a' = Array.map nf a in
if not (Evd.mem !s' k) then
s' := Evd.add !s' k (Evarutil.nf_evar_info s (Evd.find s k));
@@ -347,7 +347,9 @@ let nf_open_term sigma0 ise c =
let copy_def k evi () =
if evar_body evi != Evd.Evar_empty then () else
match Evd.evar_body (Evd.find s k) with
- | Evar_defined c' -> s' := Evd.define k (nf c') !s'
+ | Evar_defined c' ->
+ let c' = EConstr.of_constr (nf (EConstr.Unsafe.to_constr c')) in
+ s' := Evd.define k c' !s'
| _ -> () in
let c' = nf c in let _ = Evd.fold copy_def sigma0 () in
!s', Evd.evar_universe_context s, EConstr.of_constr c'
@@ -446,7 +448,7 @@ let evars_for_FO ~hack env sigma0 (ise0:evar_map) c0 =
let nenv = env_size env + if hack then 1 else 0 in
let rec put c = match kind c with
| Evar (k, a as ex) ->
- begin try put (existential_value !sigma ex)
+ begin try put (existential_value0 !sigma ex)
with NotInstantiatedEvar ->
if Evd.mem sigma0 k then map put c else
let evi = Evd.find !sigma k in
@@ -457,11 +459,13 @@ let evars_for_FO ~hack env sigma0 (ise0:evar_map) c0 =
| Context.Named.Declaration.LocalAssum (x, t) ->
mkVar x :: d, mkNamedProd x (put t) c in
let a, t =
- Context.Named.fold_inside abs_dc ~init:([], (put evi.evar_concl)) dc in
+ Context.Named.fold_inside abs_dc
+ ~init:([], (put @@ EConstr.Unsafe.to_constr evi.evar_concl))
+ (EConstr.Unsafe.to_named_context dc) in
let m = Evarutil.new_meta () in
- ise := meta_declare m t !ise;
- sigma := Evd.define k (applistc (mkMeta m) a) !sigma;
- put (existential_value !sigma ex)
+ ise := meta_declare m (EConstr.of_constr t) !ise;
+ sigma := Evd.define k (EConstr.of_constr (applistc (mkMeta m) a)) !sigma;
+ put (existential_value0 !sigma ex)
end
| _ -> map put c in
let c1 = put c0 in !ise, c1
@@ -541,7 +545,7 @@ let splay_app ise =
| App (f, a') -> loop f (Array.append a' a)
| Cast (c', _, _) -> loop c' a
| Evar ex ->
- (try loop (existential_value ise ex) a with _ -> c, a)
+ (try loop (existential_value0 ise ex) a with _ -> c, a)
| _ -> c, a in
fun c -> match kind c with
| App (f, a) -> loop f a
@@ -1255,7 +1259,7 @@ let eval_pattern ?raise_NoMatch env0 sigma0 concl0 pattern occ do_subst =
let fs sigma x = nf_evar sigma x in
let pop_evar sigma e p =
let { Evd.evar_body = e_body } as e_def = Evd.find sigma e in
- let e_body = match e_body with Evar_defined c -> c
+ let e_body = match e_body with Evar_defined c -> EConstr.Unsafe.to_constr c
| _ -> errorstrm (str "Matching the pattern " ++ pr_constr_env env0 sigma0 p ++
str " did not instantiate ?" ++ int (Evar.repr e) ++ spc () ++
str "Does the variable bound by the \"in\" construct occur "++
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 73be9d6b7..4c87b4e7e 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -1015,7 +1015,7 @@ let adjust_impossible_cases pb pred tomatch submat =
| Evar (evk,_) when snd (evar_source evk !(pb.evdref)) == Evar_kinds.ImpossibleCase ->
if not (Evd.is_defined !(pb.evdref) evk) then begin
let evd, default = use_unit_judge !(pb.evdref) in
- pb.evdref := Evd.define evk (EConstr.Unsafe.to_constr default.uj_type) evd
+ pb.evdref := Evd.define evk default.uj_type evd
end;
add_assert_false_case pb tomatch
| _ ->
@@ -2581,7 +2581,8 @@ let compile_program_cases ?loc style (typing_function, evdref) tycon env lvar
let body = it_mkLambda_or_LetIn (applist (j.uj_val, args)) lets in
let j =
{ uj_val = it_mkLambda_or_LetIn body tomatchs_lets;
- uj_type = EConstr.of_constr (EConstr.to_constr !evdref tycon); }
+ (* XXX: is this normalization needed? *)
+ uj_type = Evarutil.nf_evar !evdref tycon; }
in j
(**************************************************************************)
diff --git a/pretyping/cbv.ml b/pretyping/cbv.ml
index a2155697e..cb0fc3257 100644
--- a/pretyping/cbv.ml
+++ b/pretyping/cbv.ml
@@ -71,7 +71,7 @@ and cbv_stack =
| TOP
| APP of cbv_value array * cbv_stack
| CASE of constr * constr array * case_info * cbv_value subs * cbv_stack
- | PROJ of projection * Declarations.projection_body * cbv_stack
+ | PROJ of Projection.t * Declarations.projection_body * cbv_stack
(* les vars pourraient etre des constr,
cela permet de retarder les lift: utile ?? *)
diff --git a/pretyping/cbv.mli b/pretyping/cbv.mli
index 2ac59911c..cdaa39c53 100644
--- a/pretyping/cbv.mli
+++ b/pretyping/cbv.mli
@@ -41,7 +41,7 @@ and cbv_stack =
| TOP
| APP of cbv_value array * cbv_stack
| CASE of constr * constr array * case_info * cbv_value subs * cbv_stack
- | PROJ of projection * Declarations.projection_body * cbv_stack
+ | PROJ of Projection.t * Declarations.projection_body * cbv_stack
val shift_value : int -> cbv_value -> cbv_value
diff --git a/pretyping/classops.ml b/pretyping/classops.ml
index a0804b72b..afa8a12fc 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
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 04cb6a59f..6dc3687a0 100644
--- a/pretyping/coercion.ml
+++ b/pretyping/coercion.ml
@@ -251,7 +251,7 @@ and coerce ?loc env evdref (x : EConstr.constr) (y : EConstr.constr)
let (n, dom, rng) = destLambda !evdref t in
if isEvar !evdref dom then
let (domk, args) = destEvar !evdref dom in
- evdref := define domk (EConstr.Unsafe.to_constr a) !evdref;
+ evdref := define domk a !evdref;
else ();
t, rng
| _ -> raise NoSubtacCoercion
diff --git a/intf/constrexpr.ml b/pretyping/constrexpr.ml
index fda31756a..fda31756a 100644
--- a/intf/constrexpr.ml
+++ b/pretyping/constrexpr.ml
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index bb563220b..56e582891 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -36,7 +36,7 @@ type _ delay =
| Later : [ `thunk ] delay
(** Should we keep details of universes during detyping ? *)
-let print_universes = Flags.univ_print
+let print_universes = ref false
(** If true, prints local context of evars, whatever print_arguments *)
let print_evar_arguments = ref false
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index d37090a65..144166a34 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -114,9 +114,6 @@ let flex_kind_of_term ts env evd c sk =
| Fix _ -> Rigid (* happens when the fixpoint is partially applied *)
| Cast _ | App _ | Case _ -> assert false
-let add_conv_pb (pb, env, x, y) sigma =
- Evd.add_conv_pb (pb, env, EConstr.Unsafe.to_constr x, EConstr.Unsafe.to_constr y) sigma
-
let apprec_nohdbeta ts env evd c =
let (t,sk as appr) = Reductionops.whd_nored_state evd (c, []) in
if Stack.not_purely_applicative sk
@@ -1045,7 +1042,7 @@ let choose_less_dependent_instance evk evd term args =
let subst' = List.filter (fun (id,c) -> EConstr.eq_constr evd c term) subst in
match subst' with
| [] -> None
- | (id, _) :: _ -> Some (Evd.define evk (Constr.mkVar id) evd)
+ | (id, _) :: _ -> Some (Evd.define evk (mkVar id) evd)
let apply_on_subterm env evdref f c t =
let rec applyrec (env,(k,c) as acc) t =
@@ -1085,7 +1082,7 @@ let filter_possible_projections evd c ty ctxt args =
let a = Array.unsafe_get args i in
(match decl with
| NamedDecl.LocalAssum _ -> false
- | NamedDecl.LocalDef (_,c,_) -> not (isRel evd (EConstr.of_constr c) || isVar evd (EConstr.of_constr c))) ||
+ | NamedDecl.LocalDef (_,c,_) -> not (isRel evd c || isVar evd c)) ||
a == c ||
(* Here we make an approximation, for instance, we could also be *)
(* interested in finding a term u convertible to c such that a occurs *)
@@ -1135,7 +1132,7 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
end
| decl'::ctxt', c::l, occs::occsl ->
let id = NamedDecl.get_id decl' in
- let t = EConstr.of_constr (NamedDecl.get_type decl') in
+ let t = NamedDecl.get_type decl' in
let evs = ref [] in
let ty = Retyping.get_type_of env_rhs evd c in
let filter' = filter_possible_projections evd c ty ctxt args in
@@ -1183,7 +1180,7 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
(* We force abstraction over this unconstrained occurrence *)
(* and we use typing to propagate this instantiation *)
(* This is an arbitrary choice *)
- let evd = Evd.define evk (Constr.mkVar id) evd in
+ let evd = Evd.define evk (mkVar id) evd in
match evar_conv_x ts env_evar evd CUMUL idty evty with
| UnifFailure _ -> user_err Pp.(str "Cannot find an instance")
| Success evd ->
@@ -1205,14 +1202,11 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
(evar_conv_x full_transparent_state)
with IllTypedInstance _ -> raise (TypingFailed evd)
in
- Evd.define evk (EConstr.Unsafe.to_constr rhs) evd
+ Evd.define evk rhs evd
in
abstract_free_holes evd subst, true
with TypingFailed evd -> evd, false
-let to_pb (pb, env, t1, t2) =
- (pb, env, EConstr.Unsafe.to_constr t1, EConstr.Unsafe.to_constr t2)
-
let second_order_matching_with_args ts env evd pbty ev l t =
(*
let evd,ev = evar_absorb_arguments env evd ev l in
@@ -1222,7 +1216,7 @@ let second_order_matching_with_args ts env evd pbty ev l t =
else UnifFailure (evd, ConversionFailed (env,mkApp(mkEvar ev,l),t))
if b then Success evd else
*)
- let pb = to_pb (pbty,env,mkApp(mkEvar ev,l),t) in
+ let pb = (pbty,env,mkApp(mkEvar ev,l),t) in
UnifFailure (evd, CannotSolveConstraint (pb,ProblemBeyondCapabilities))
let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
@@ -1245,7 +1239,7 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
| Some evd -> Success evd
| None ->
let reason = ProblemBeyondCapabilities in
- UnifFailure (evd, CannotSolveConstraint (to_pb (pbty,env,t1,t2),reason)))
+ UnifFailure (evd, CannotSolveConstraint ((pbty,env,t1,t2),reason)))
| (Rel _|Var _), Evar (evk2,args2) when app_empty
&& List.for_all (fun a -> EConstr.eq_constr evd a term1 || isEvar evd a)
(remove_instance_local_defs evd evk2 args2) ->
@@ -1255,7 +1249,7 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
| Some evd -> Success evd
| None ->
let reason = ProblemBeyondCapabilities in
- UnifFailure (evd, CannotSolveConstraint (to_pb (pbty,env,t1,t2),reason)))
+ UnifFailure (evd, CannotSolveConstraint ((pbty,env,t1,t2),reason)))
| Evar (evk1,args1), Evar (evk2,args2) when Evar.equal evk1 evk2 ->
let f env evd pbty x y = is_fconv ~reds:ts pbty env evd x y in
Success (solve_refl ~can_drop:true f env evd
@@ -1295,10 +1289,10 @@ let error_cannot_unify env evd pb ?reason t1 t2 =
let check_problems_are_solved env evd =
match snd (extract_all_conv_pbs evd) with
- | (pbty,env,t1,t2) as pb::_ -> error_cannot_unify env evd pb (EConstr.of_constr t1) (EConstr.of_constr t2)
+ | (pbty,env,t1,t2) as pb::_ -> error_cannot_unify env evd pb t1 t2
| _ -> ()
-exception MaxUndefined of (Evar.t * evar_info * Constr.t list)
+exception MaxUndefined of (Evar.t * evar_info * EConstr.t list)
let max_undefined_with_candidates evd =
let fold evk evi () = match evi.evar_candidates with
@@ -1326,7 +1320,7 @@ let rec solve_unconstrained_evars_with_candidates ts evd =
| a::l ->
try
let conv_algo = evar_conv_x ts in
- let evd = check_evar_instance evd evk (EConstr.of_constr a) conv_algo in
+ let evd = check_evar_instance evd evk a conv_algo in
let evd = Evd.define evk a evd in
match reconsider_unif_constraints conv_algo evd with
| Success evd -> solve_unconstrained_evars_with_candidates ts evd
@@ -1348,7 +1342,7 @@ let solve_unconstrained_impossible_cases env evd =
let ty = j_type j in
let conv_algo = evar_conv_x full_transparent_state in
let evd' = check_evar_instance evd' evk ty conv_algo in
- Evd.define evk (EConstr.Unsafe.to_constr ty) evd'
+ Evd.define evk ty evd'
| _ -> evd') evd evd
let solve_unif_constraints_with_heuristics env
@@ -1357,8 +1351,6 @@ let solve_unif_constraints_with_heuristics env
let rec aux evd pbs progress stuck =
match pbs with
| (pbty,env,t1,t2 as pb) :: pbs ->
- let t1 = EConstr.of_constr t1 in
- let t2 = EConstr.of_constr t2 in
(match apply_conversion_problem_heuristic ts env evd pbty t1 t2 with
| Success evd' ->
let (evd', rest) = extract_all_conv_pbs evd' in
@@ -1375,9 +1367,7 @@ let solve_unif_constraints_with_heuristics env
match stuck with
| [] -> (* We're finished *) evd
| (pbty,env,t1,t2 as pb) :: _ ->
- let t1 = EConstr.of_constr t1 in
- let t2 = EConstr.of_constr t2 in
- (* There remains stuck problems *)
+ (* There remains stuck problems *)
error_cannot_unify env evd pb t1 t2
in
let (evd,pbs) = extract_all_conv_pbs evd in
diff --git a/pretyping/evarconv.mli b/pretyping/evarconv.mli
index 627430708..9270d6e3a 100644
--- a/pretyping/evarconv.mli
+++ b/pretyping/evarconv.mli
@@ -38,7 +38,7 @@ val e_cumul : env -> ?ts:transparent_state -> evar_map ref -> constr -> constr -
val solve_unif_constraints_with_heuristics : env -> ?ts:transparent_state -> evar_map -> evar_map
val consider_remaining_unif_problems : env -> ?ts:transparent_state -> evar_map -> evar_map
-(** @deprecated Alias for [solve_unif_constraints_with_heuristics] *)
+[@@ocaml.deprecated "Alias for [solve_unif_constraints_with_heuristics]"]
(** Check all pending unification problems are solved and raise an
error otherwise *)
diff --git a/pretyping/evardefine.ml b/pretyping/evardefine.ml
index 4cffbbb83..b452755b1 100644
--- a/pretyping/evardefine.ml
+++ b/pretyping/evardefine.ml
@@ -77,7 +77,7 @@ let define_pure_evar_as_product evd evk =
let evi = Evd.find_undefined evd evk in
let evenv = evar_env evi in
let id = next_ident_away idx (Environ.ids_of_named_context_val evi.evar_hyps) in
- let concl = Reductionops.whd_all evenv evd (EConstr.of_constr evi.evar_concl) in
+ let concl = Reductionops.whd_all evenv evd evi.evar_concl in
let s = destSort evd concl in
let evksrc = evar_source evk evd in
let src = subterm_source evk ~where:Domain evksrc in
@@ -101,7 +101,7 @@ let define_pure_evar_as_product evd evk =
evd3, rng
in
let prod = mkProd (Name id, dom, subst_var id rng) in
- let evd3 = Evd.define evk (EConstr.Unsafe.to_constr prod) evd2 in
+ let evd3 = Evd.define evk prod evd2 in
evd3,prod
(* Refine an applied evar to a product and returns its instantiation *)
@@ -128,7 +128,7 @@ let define_pure_evar_as_lambda env evd evk =
let open Context.Named.Declaration in
let evi = Evd.find_undefined evd evk in
let evenv = evar_env evi in
- let typ = Reductionops.whd_all evenv evd (EConstr.of_constr (evar_concl evi)) in
+ let typ = Reductionops.whd_all evenv evd (evar_concl evi) in
let evd1,(na,dom,rng) = match EConstr.kind evd typ with
| Prod (na,dom,rng) -> (evd,(na,dom,rng))
| Evar ev' -> let evd,typ = define_evar_as_product evd ev' in evd,destProd evd typ
@@ -141,7 +141,7 @@ let define_pure_evar_as_lambda env evd evk =
let src = subterm_source evk ~where:Body (evar_source evk evd1) in
let evd2,body = new_evar newenv evd1 ~src (subst1 (mkVar id) rng) ~filter in
let lam = mkLambda (Name id, dom, subst_var id body) in
- Evd.define evk (EConstr.Unsafe.to_constr lam) evd2, lam
+ Evd.define evk lam evd2, lam
let define_evar_as_lambda env evd (evk,args) =
let evd,lam = define_pure_evar_as_lambda env evd evk in
@@ -166,9 +166,9 @@ let define_evar_as_sort env evd (ev,args) =
let evd, u = new_univ_variable univ_rigid evd in
let evi = Evd.find_undefined evd ev in
let s = Type u in
- let concl = Reductionops.whd_all (evar_env evi) evd (EConstr.of_constr evi.evar_concl) in
+ let concl = Reductionops.whd_all (evar_env evi) evd evi.evar_concl in
let sort = destSort evd concl in
- let evd' = Evd.define ev (Constr.mkSort s) evd in
+ let evd' = Evd.define ev (mkSort s) evd in
Evd.set_leq_sort env evd' (Type (Univ.super u)) (ESorts.kind evd' sort), s
(* Propagation of constraints through application and abstraction:
diff --git a/pretyping/evarsolve.ml b/pretyping/evarsolve.ml
index 96d80741a..b7eaff078 100644
--- a/pretyping/evarsolve.ml
+++ b/pretyping/evarsolve.ml
@@ -89,9 +89,9 @@ let refresh_universes ?(status=univ_rigid) ?(onlyalg=false) ?(refreshset=false)
Array.iter (refresh_term_evars onevars false) args
| Evar (ev, a) when onevars ->
let evi = Evd.find !evdref ev in
- let ty' = refresh ~onlyalg univ_flexible ~direction:true (EConstr.of_constr evi.evar_concl) in
+ let ty' = refresh ~onlyalg univ_flexible ~direction:true evi.evar_concl in
if !modified then
- evdref := Evd.add !evdref ev {evi with evar_concl = EConstr.Unsafe.to_constr ty'}
+ evdref := Evd.add !evdref ev {evi with evar_concl = ty'}
else ()
| _ -> EConstr.iter !evdref (refresh_term_evars onevars false) t
and refresh_polymorphic_positions args pos =
@@ -137,8 +137,6 @@ let test_success conv_algo env evd c c' rhs =
is_success (conv_algo env evd c c' rhs)
let add_conv_oriented_pb ?(tail=true) (pbty,env,t1,t2) evd =
- let t1 = EConstr.Unsafe.to_constr t1 in
- let t2 = EConstr.Unsafe.to_constr t2 in
match pbty with
| Some true -> add_conv_pb ~tail (Reduction.CUMUL,env,t1,t2) evd
| Some false -> add_conv_pb ~tail (Reduction.CUMUL,env,t2,t1) evd
@@ -197,7 +195,7 @@ let restrict_evar_key evd evk filter candidates =
| None -> evar_filter evi
| Some filter -> filter in
let candidates = match candidates with
- | NoUpdate -> Option.map (fun l -> List.map EConstr.of_constr l) evi.evar_candidates
+ | NoUpdate -> evi.evar_candidates
| UpdateWith c -> Some c in
restrict_evar evd evk filter candidates
end
@@ -600,7 +598,6 @@ let solve_pattern_eqn env sigma l c =
let make_projectable_subst aliases sigma evi args =
let sign = evar_filtered_context evi in
- let sign = List.map (fun d -> map_named_decl EConstr.of_constr d) sign in
let evar_aliases = compute_var_aliases sign sigma in
let (_,full_subst,cstr_subst) =
List.fold_right
@@ -877,7 +874,7 @@ let choose_projection evi sols =
let rec do_projection_effects define_fun env ty evd = function
| ProjectVar -> evd
| ProjectEvar ((evk,argsv),evi,id,p) ->
- let evd = Evd.define evk (Constr.mkVar id) evd in
+ let evd = Evd.define evk (mkVar id) evd in
(* TODO: simplify constraints involving evk *)
let evd = do_projection_effects define_fun env ty evd p in
let ty = whd_all env evd (Lazy.force ty) in
@@ -887,7 +884,7 @@ let rec do_projection_effects define_fun env ty evd = function
one (however, regarding coercions, because t is obtained by
unif, we know that no coercion can be inserted) *)
let subst = make_pure_subst evi argsv in
- let ty' = replace_vars subst (EConstr.of_constr evi.evar_concl) in
+ let ty' = replace_vars subst evi.evar_concl in
if isEvar evd ty' then define_fun env evd (Some false) (destEvar evd ty') ty else evd
else
evd
@@ -1004,7 +1001,7 @@ let filter_effective_candidates evd evi filter candidates =
let filter_candidates evd evk filter candidates_update =
let evi = Evd.find_undefined evd evk in
let candidates = match candidates_update with
- | NoUpdate -> Option.map (fun l -> List.map EConstr.of_constr l) evi.evar_candidates
+ | NoUpdate -> evi.evar_candidates
| UpdateWith c -> Some c
in
match candidates with
@@ -1023,13 +1020,12 @@ let closure_of_filter evd evk = function
| None -> None
| Some filter ->
let evi = Evd.find_undefined evd evk in
- let vars = collect_vars evd (EConstr.of_constr (evar_concl evi)) in
+ let vars = collect_vars evd (evar_concl evi) in
let test b decl = b || Id.Set.mem (get_id decl) vars ||
match decl with
| LocalAssum _ ->
false
| LocalDef (_,c,_) ->
- let c = EConstr.of_constr c in
not (isRel evd c || isVar evd c)
in
let newfilter = Filter.map_along test filter (evar_context evi) in
@@ -1062,7 +1058,7 @@ let do_restrict_hyps evd (evk,args as ev) filter candidates =
match candidates,filter with
| UpdateWith [], _ -> user_err Pp.(str "Not solvable.")
| UpdateWith [nc],_ ->
- let evd = Evd.define evk (EConstr.Unsafe.to_constr nc) evd in
+ let evd = Evd.define evk nc evd in
raise (EvarSolvedWhileRestricting (evd,mkEvar ev))
| NoUpdate, None -> evd,ev
| _ -> restrict_applied_evar evd ev filter candidates
@@ -1113,9 +1109,6 @@ let postpone_non_unique_projection env evd pbty (evk,argsv as ev) sols rhs =
* Note: argument f is the function used to instantiate evars.
*)
-let instantiate_evar_array evi c args =
- EConstr.of_constr (instantiate_evar_array evi (EConstr.Unsafe.to_constr c) (Array.map EConstr.Unsafe.to_constr args))
-
let filter_compatible_candidates conv_algo env evd evi args rhs c =
let c' = instantiate_evar_array evi c args in
match conv_algo env evd Reduction.CONV rhs c' with
@@ -1135,8 +1128,6 @@ let restrict_candidates conv_algo env evd filter1 (evk1,argsv1) (evk2,argsv2) =
| _, None -> filter_candidates evd evk1 filter1 NoUpdate
| None, Some _ -> raise DoesNotPreserveCandidateRestriction
| Some l1, Some l2 ->
- let l1 = List.map EConstr.of_constr l1 in
- let l2 = List.map EConstr.of_constr l2 in
let l1 = filter_effective_candidates evd evi1 filter1 l1 in
let l1' = List.filter (fun c1 ->
let c1' = instantiate_evar_array evi1 c1 argsv1 in
@@ -1242,9 +1233,9 @@ let check_evar_instance evd evk1 body conv_algo =
try Retyping.get_type_of ~lax:true evenv evd body
with Retyping.RetypeError _ -> user_err Pp.(str "Ill-typed evar instance")
in
- match conv_algo evenv evd Reduction.CUMUL ty (EConstr.of_constr evi.evar_concl) with
+ match conv_algo evenv evd Reduction.CUMUL ty evi.evar_concl with
| Success evd -> evd
- | UnifFailure _ -> raise (IllTypedInstance (evenv,ty,EConstr.of_constr evi.evar_concl))
+ | UnifFailure _ -> raise (IllTypedInstance (evenv,ty, evi.evar_concl))
let update_evar_source ev1 ev2 evd =
let loc, evs2 = evar_source ev2 evd in
@@ -1257,7 +1248,7 @@ let update_evar_source ev1 ev2 evd =
let solve_evar_evar_l2r force f g env evd aliases pbty ev1 (evk2,_ as ev2) =
try
let evd,body = project_evar_on_evar force g env evd aliases 0 pbty ev1 ev2 in
- let evd' = Evd.define evk2 (EConstr.Unsafe.to_constr body) evd in
+ let evd' = Evd.define evk2 body evd in
let evd' = update_evar_source (fst (destEvar evd body)) evk2 evd' in
check_evar_instance evd' evk2 body g
with EvarSolvedOnTheFly (evd,c) ->
@@ -1292,17 +1283,19 @@ let solve_evar_evar_aux force f g env evd pbty (evk1,args1 as ev1) (evk2,args2 a
let solve_evar_evar ?(force=false) f g env evd pbty (evk1,args1 as ev1) (evk2,args2 as ev2) =
let pbty = if force then None else pbty in
let evi = Evd.find evd evk1 in
- let downcast evk t evd = downcast evk (EConstr.Unsafe.to_constr t) evd in
+ let downcast evk t evd = downcast evk t evd in
let evd =
try
(* ?X : Π Δ. Type i = ?Y : Π Δ'. Type j.
The body of ?X and ?Y just has to be of type Π Δ. Type k for some k <= i, j. *)
let evienv = Evd.evar_env evi in
- let ctx1, i = Reduction.dest_arity evienv evi.evar_concl in
+ let concl1 = EConstr.Unsafe.to_constr evi.evar_concl in
+ let ctx1, i = Reduction.dest_arity evienv concl1 in
let ctx1 = List.map (fun c -> map_rel_decl EConstr.of_constr c) ctx1 in
let evi2 = Evd.find evd evk2 in
let evi2env = Evd.evar_env evi2 in
- let ctx2, j = Reduction.dest_arity evi2env evi2.evar_concl in
+ let concl2 = EConstr.Unsafe.to_constr evi2.evar_concl in
+ let ctx2, j = Reduction.dest_arity evi2env concl2 in
let ctx2 = List.map (fun c -> map_rel_decl EConstr.of_constr c) ctx2 in
let ui, uj = univ_of_sort i, univ_of_sort j in
if i == j || Evd.check_eq evd ui uj
@@ -1375,14 +1368,14 @@ let solve_candidates conv_algo env evd (evk,argsv) rhs =
| Some l ->
let l' =
List.map_filter
- (fun c -> filter_compatible_candidates conv_algo env evd evi argsv rhs (EConstr.of_constr c)) l in
+ (fun c -> filter_compatible_candidates conv_algo env evd evi argsv rhs c) l in
match l' with
| [] -> raise IncompatibleCandidates
| [c,evd] ->
(* solve_candidates might have been called recursively in the mean *)
(* time and the evar been solved by the filtering process *)
if Evd.is_undefined evd evk then
- let evd' = Evd.define evk (EConstr.Unsafe.to_constr c) evd in
+ let evd' = Evd.define evk c evd in
check_evar_instance evd' evk c conv_algo
else evd
| l when List.length l < List.length l' ->
@@ -1401,8 +1394,8 @@ let occur_evar_upto_types sigma n c =
Array.iter occur_rec args
else (
seen := Evar.Set.add sp !seen;
- Option.iter occur_rec (existential_opt_value sigma e);
- occur_rec (Evd.existential_type sigma e))
+ Option.iter occur_rec (existential_opt_value0 sigma e);
+ occur_rec (Evd.existential_type0 sigma e))
| _ -> Constr.iter occur_rec c
in
try occur_rec c; false with Occur -> true
@@ -1529,7 +1522,7 @@ let rec invert_definition conv_algo choose env evd pbty (evk,argsv as ev) rhs =
(* Try to project (a restriction of) the left evar ... *)
try
let evd,body = project_evar_on_evar false conv_algo env' evd aliases 0 None ev'' ev' in
- let evd = Evd.define evk' (EConstr.Unsafe.to_constr body) evd in
+ let evd = Evd.define evk' body evd in
check_evar_instance evd evk' body conv_algo
with
| EvarSolvedOnTheFly _ -> assert false (* ev has no candidates *)
@@ -1592,14 +1585,14 @@ let rec invert_definition conv_algo choose env evd pbty (evk,argsv as ev) rhs =
Id.Set.subset (collect_vars evd rhs) !names
in
let body =
- if fast rhs then EConstr.of_constr (EConstr.to_constr evd rhs) (** FIXME? *)
+ if fast rhs then nf_evar evd rhs (** FIXME? *)
else
let t' = imitate (env,0) rhs in
if !progress then
(recheck_applications conv_algo (evar_env evi) evdref t'; t')
else t'
in (!evdref,body)
-
+
(* [define] tries to solve the problem "?ev[args] = rhs" when "?ev" is
* an (uninstantiated) evar such that "hyps |- ?ev : typ". Otherwise said,
* [define] tries to find an instance lhs such that
@@ -1644,7 +1637,7 @@ and evar_define conv_algo ?(choose=false) env evd pbty (evk,argsv as ev) rhs =
print_constr body);
raise e in*)
let evd' = check_evar_instance evd' evk body conv_algo in
- Evd.define evk (EConstr.Unsafe.to_constr body) evd'
+ Evd.define evk body evd'
with
| NotEnoughInformationToProgress sols ->
postpone_non_unique_projection env evd pbty ev sols rhs
@@ -1691,8 +1684,6 @@ and evar_define conv_algo ?(choose=false) env evd pbty (evk,argsv as ev) rhs =
*)
let status_changed evd lev (pbty,_,t1,t2) =
- let t1 = EConstr.of_constr t1 in
- let t2 = EConstr.of_constr t2 in
(try Evar.Set.mem (head_evar evd t1) lev with NoHeadEvar -> false) ||
(try Evar.Set.mem (head_evar evd t2) lev with NoHeadEvar -> false)
@@ -1702,7 +1693,7 @@ let reconsider_unif_constraints conv_algo evd =
(fun p (pbty,env,t1,t2 as x) ->
match p with
| Success evd ->
- (match conv_algo env evd pbty (EConstr.of_constr t1) (EConstr.of_constr t2) with
+ (match conv_algo env evd pbty t1 t2 with
| Success _ as x -> x
| UnifFailure (i,e) -> UnifFailure (i,CannotSolveConstraint (x,e)))
| UnifFailure _ as x -> x)
diff --git a/pretyping/evarsolve.mli b/pretyping/evarsolve.mli
index 9b21599b6..3f05c58c4 100644
--- a/pretyping/evarsolve.mli
+++ b/pretyping/evarsolve.mli
@@ -63,7 +63,7 @@ val solve_simple_eqn : conv_fun -> ?choose:bool -> env -> evar_map ->
val reconsider_unif_constraints : conv_fun -> evar_map -> unification_result
val reconsider_conv_pbs : conv_fun -> evar_map -> unification_result
-(** @deprecated Alias for [reconsider_unif_constraints] *)
+[@@ocaml.deprecated "Alias for [reconsider_unif_constraints]"]
val is_unification_pattern_evar : env -> evar_map -> existential -> constr list ->
constr -> alias list option
diff --git a/intf/extend.ml b/pretyping/extend.ml
index 734b859f6..734b859f6 100644
--- a/intf/extend.ml
+++ b/pretyping/extend.ml
diff --git a/intf/genredexpr.ml b/pretyping/genredexpr.ml
index 80697461a..80697461a 100644
--- a/intf/genredexpr.ml
+++ b/pretyping/genredexpr.ml
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/intf/glob_term.ml b/pretyping/glob_term.ml
index 84be15552..3c3f75a68 100644
--- a/intf/glob_term.ml
+++ b/pretyping/glob_term.ml
@@ -17,7 +17,6 @@
arguments and pattern-matching compilation are not. *)
open Names
-open Globnames
open Decl_kinds
open Misctypes
@@ -36,7 +35,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.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/inductiveops.mli b/pretyping/inductiveops.mli
index 296f25d3f..b0d714b03 100644
--- a/pretyping/inductiveops.mli
+++ b/pretyping/inductiveops.mli
@@ -129,8 +129,8 @@ val allowed_sorts : env -> inductive -> Sorts.family list
val has_dependent_elim : mutual_inductive_body -> bool
(** Primitive projections *)
-val projection_nparams : projection -> int
-val projection_nparams_env : env -> projection -> int
+val projection_nparams : Projection.t -> int
+val projection_nparams_env : env -> Projection.t -> int
val type_of_projection_knowing_arg : env -> evar_map -> Projection.t ->
EConstr.t -> EConstr.types -> types
diff --git a/intf/locus.ml b/pretyping/locus.ml
index 95a2e495b..95a2e495b 100644
--- a/intf/locus.ml
+++ b/pretyping/locus.ml
diff --git a/pretyping/nativenorm.ml b/pretyping/nativenorm.ml
index fcbf50fea..85911394f 100644
--- a/pretyping/nativenorm.ml
+++ b/pretyping/nativenorm.ml
@@ -401,9 +401,9 @@ and nf_evar env sigma evk ty args =
mkEvar (evk, Array.of_list args), ty
let evars_of_evar_map sigma =
- { Nativelambda.evars_val = Evd.existential_opt_value sigma;
- Nativelambda.evars_typ = Evd.existential_type sigma;
- Nativelambda.evars_metas = Evd.meta_type sigma }
+ { Nativelambda.evars_val = Evd.existential_opt_value0 sigma;
+ Nativelambda.evars_typ = Evd.existential_type0 sigma;
+ Nativelambda.evars_metas = Evd.meta_type0 sigma }
(* fork perf process, return profiler's process id *)
let start_profiler_linux profile_fn =
diff --git a/intf/pattern.ml b/pretyping/pattern.ml
index 76367b612..7dd0954bc 100644
--- a/intf/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
diff --git a/pretyping/patternops.ml b/pretyping/patternops.ml
index e52112fda..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
@@ -184,7 +184,7 @@ let pattern_of_constr env sigma t =
| Evar_kinds.GoalEvar | Evar_kinds.VarInstance _ ->
(* These are the two evar kinds used for existing goals *)
(* see Proofview.mark_in_evm *)
- if Evd.is_defined sigma evk then pattern_of_constr env (Evd.existential_value sigma ev)
+ if Evd.is_defined sigma evk then pattern_of_constr env (Evd.existential_value0 sigma ev)
else PEvar (evk,Array.map (pattern_of_constr env) ctxt)
| Evar_kinds.MatchingVar (Evar_kinds.SecondOrderPatVar ido) -> assert false
| _ ->
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 4962b89a0..e68a25a87 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -117,7 +117,7 @@ open ExtraEnv
exception Found of int array
let nf_fix sigma (nas, cs, ts) =
- let inj c = EConstr.to_constr sigma c in
+ let inj c = EConstr.to_constr ~abort_on_undefined_evars:false sigma c in
(nas, Array.map inj cs, Array.map inj ts)
let search_guard ?loc env possible_indexes fixdefs =
@@ -315,7 +315,7 @@ let apply_inference_hook hook evdref frozen = match frozen with
then
try
let sigma, c = hook sigma evk in
- Evd.define evk (EConstr.Unsafe.to_constr c) sigma
+ Evd.define evk c sigma
with Exit ->
sigma
else
@@ -532,7 +532,7 @@ let pretype_global ?loc rigid env evd gr us =
interp_instance ?loc evd ~len l
in
let (sigma, c) = Evd.fresh_global ?loc ~rigid ?names:instance env.ExtraEnv.env evd gr in
- (sigma, EConstr.of_constr c)
+ (sigma, c)
let pretype_ref ?loc evdref env ref us =
match ref with
@@ -1109,7 +1109,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
and pretype_instance k0 resolve_tc env evdref lvar loc hyps evk update =
let f decl (subst,update) =
let id = NamedDecl.get_id decl in
- let t = replace_vars subst (EConstr.of_constr (NamedDecl.get_type decl)) in
+ let t = replace_vars subst (NamedDecl.get_type decl) in
let c, update =
try
let c = List.assoc id update in
@@ -1118,7 +1118,7 @@ and pretype_instance k0 resolve_tc env evdref lvar loc hyps evk update =
with Not_found ->
try
let (n,_,t') = lookup_rel_id id (rel_context env) in
- if is_conv env.ExtraEnv.env !evdref t t' then mkRel n, update else raise Not_found
+ if is_conv env.ExtraEnv.env !evdref t (lift n t') then mkRel n, update else raise Not_found
with Not_found ->
try
let t' = env |> lookup_named id |> NamedDecl.get_type in
@@ -1150,7 +1150,7 @@ and pretype_type k0 resolve_tc valcon (env : ExtraEnv.t) evdref lvar c = match D
(* Correction of bug #5315 : we need to define an evar for *all* holes *)
let evkt = e_new_evar env evdref ~src:(loc, knd) ~naming (mkSort s) in
let ev,_ = destEvar !evdref evkt in
- evdref := Evd.define ev (to_constr !evdref v) !evdref;
+ evdref := Evd.define ev (nf_evar !evdref v) !evdref;
(* End of correction of bug #5315 *)
{ utj_val = v;
utj_type = s }
diff --git a/pretyping/pretyping.mllib b/pretyping/pretyping.mllib
index ae4ad0be7..d98026bc6 100644
--- a/pretyping/pretyping.mllib
+++ b/pretyping/pretyping.mllib
@@ -1,5 +1,5 @@
Geninterp
-Ltac_pretype
+Locus
Locusops
Pretype_errors
Reductionops
@@ -16,12 +16,19 @@ Evarsolve
Recordops
Evarconv
Typing
+Constrexpr
+Genredexpr
Miscops
+Glob_term
+Ltac_pretype
Glob_ops
Redops
+Pattern
Patternops
Constr_matching
Tacred
+Extend
+Vernacexpr
Typeclasses_errors
Typeclasses
Classops
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 9e3e68f05..a4d447902 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -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
@@ -275,12 +275,12 @@ sig
type cst_member =
| Cst_const of pconstant
- | Cst_proj of projection
+ | Cst_proj of Projection.t
type 'a member =
| App of 'a app_node
| Case of case_info * 'a * 'a array * Cst_stack.t
- | Proj of int * int * projection * Cst_stack.t
+ | Proj of int * int * Projection.t * Cst_stack.t
| Fix of ('a, 'a) pfixpoint * 'a t * Cst_stack.t
| Cst of cst_member * int * int list * 'a t * Cst_stack.t
and 'a t = 'a member list
@@ -332,12 +332,12 @@ struct
type cst_member =
| Cst_const of pconstant
- | Cst_proj of projection
+ | Cst_proj of Projection.t
type 'a member =
| App of 'a app_node
| Case of case_info * 'a * 'a array * Cst_stack.t
- | Proj of int * int * projection * Cst_stack.t
+ | Proj of int * int * Projection.t * Cst_stack.t
| Fix of ('a, 'a) pfixpoint * 'a t * Cst_stack.t
| Cst of cst_member * int * int list * 'a t * Cst_stack.t
and 'a t = 'a member list
@@ -871,7 +871,7 @@ let rec whd_state_gen ?csts ~refold ~tactic_mode flags env sigma =
| Evar ev -> fold ()
| Meta ev ->
(match safe_meta_value sigma ev with
- | Some body -> whrec cst_l (EConstr.of_constr body, stack)
+ | Some body -> whrec cst_l (body, stack)
| None -> fold ())
| Const (c,u as const) ->
reduction_effect_hook env sigma (EConstr.to_constr sigma x)
@@ -1106,7 +1106,7 @@ let local_whd_state_gen flags sigma =
| Evar ev -> s
| Meta ev ->
(match safe_meta_value sigma ev with
- Some c -> whrec (EConstr.of_constr c,stack)
+ Some c -> whrec (c,stack)
| None -> s)
| Construct ((ind,c),u) ->
@@ -1392,7 +1392,7 @@ let vm_infer_conv ?(pb=Reduction.CUMUL) env t1 t2 =
(********************************************************************)
let whd_meta sigma c = match EConstr.kind sigma c with
- | Meta p -> (try EConstr.of_constr (meta_value sigma p) with Not_found -> c)
+ | Meta p -> (try meta_value sigma p with Not_found -> c)
| _ -> c
let default_plain_instance_ident = Id.of_string "H"
@@ -1612,7 +1612,7 @@ let meta_value evd mv =
match meta_opt_fvalue evd mv with
| Some (b,_) ->
let metas = Metamap.bind valrec b.freemetas in
- instance evd metas (EConstr.of_constr b.rebus)
+ instance evd metas b.rebus
| None -> mkMeta mv
in
valrec mv
@@ -1625,9 +1625,8 @@ let meta_instance sigma b =
instance sigma c_sigma b.rebus
let nf_meta sigma c =
- let c = EConstr.Unsafe.to_constr c in
let cl = mk_freelisted c in
- meta_instance sigma { cl with rebus = EConstr.of_constr cl.rebus }
+ meta_instance sigma { cl with rebus = cl.rebus }
(* Instantiate metas that create beta/iota redexes *)
@@ -1648,7 +1647,6 @@ let meta_reducible_instance evd b =
(match
try
let g, s = Metamap.find m metas in
- let g = EConstr.of_constr g in
let is_coerce = match s with CoerceToType -> true | _ -> false in
if isConstruct evd g || not is_coerce then Some g else None
with Not_found -> None
@@ -1660,7 +1658,6 @@ let meta_reducible_instance evd b =
(match
try
let g, s = Metamap.find m metas in
- let g = EConstr.of_constr g in
let is_coerce = match s with CoerceToType -> true | _ -> false in
if isLambda evd g || not is_coerce then Some g else None
with Not_found -> None
@@ -1669,7 +1666,6 @@ let meta_reducible_instance evd b =
| None -> mkApp (f,Array.map irec l))
| Meta m ->
(try let g, s = Metamap.find m metas in
- let g = EConstr.of_constr g in
let is_coerce = match s with CoerceToType -> true | _ -> false in
if not is_coerce then irec g else u
with Not_found -> u)
@@ -1678,7 +1674,6 @@ let meta_reducible_instance evd b =
(match
try
let g, s = Metamap.find m metas in
- let g = EConstr.of_constr g in
let is_coerce = match s with CoerceToType -> true | _ -> false in
if isConstruct evd g || not is_coerce then Some g else None
with Not_found -> None
diff --git a/pretyping/reductionops.mli b/pretyping/reductionops.mli
index 29dc3ed0f..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 ->
@@ -70,12 +70,12 @@ module Stack : sig
type cst_member =
| Cst_const of pconstant
- | Cst_proj of projection
+ | Cst_proj of Projection.t
type 'a member =
| App of 'a app_node
| Case of case_info * 'a * 'a array * Cst_stack.t
- | Proj of int * int * projection * Cst_stack.t
+ | Proj of int * int * Projection.t * Cst_stack.t
| Fix of ('a, 'a) pfixpoint * 'a t * Cst_stack.t
| Cst of cst_member * int (** current foccussed arg *) * int list (** remaining args *)
* 'a t * Cst_stack.t
diff --git a/pretyping/retyping.ml b/pretyping/retyping.ml
index 3582b6447..746a68b21 100644
--- a/pretyping/retyping.ml
+++ b/pretyping/retyping.ml
@@ -57,8 +57,8 @@ let get_type_from_constraints env sigma t =
if isEvar sigma (fst (decompose_app_vect sigma t)) then
match
List.map_filter (fun (pbty,env,t1,t2) ->
- if is_fconv Reduction.CONV env sigma t (EConstr.of_constr t1) then Some t2
- else if is_fconv Reduction.CONV env sigma t (EConstr.of_constr t2) then Some t1
+ if is_fconv Reduction.CONV env sigma t t1 then Some t2
+ else if is_fconv Reduction.CONV env sigma t t2 then Some t1
else None)
(snd (Evd.extract_all_conv_pbs sigma))
with
@@ -99,7 +99,7 @@ let retype ?(polyprop=true) sigma =
let rec type_of env cstr =
match EConstr.kind sigma cstr with
| Meta n ->
- (try strip_outer_cast sigma (EConstr.of_constr (Evd.meta_ftype sigma n).Evd.rebus)
+ (try strip_outer_cast sigma (Evd.meta_ftype sigma n).Evd.rebus
with Not_found -> retype_error (BadMeta n))
| Rel n ->
let ty = RelDecl.get_type (lookup_rel n env) in
@@ -115,7 +115,7 @@ let retype ?(polyprop=true) sigma =
try Inductiveops.find_rectype env sigma t
with Not_found ->
try
- let t = EConstr.of_constr (get_type_from_constraints env sigma t) in
+ let t = get_type_from_constraints env sigma t in
Inductiveops.find_rectype env sigma t
with Not_found -> retype_error BadRecursiveType
in
@@ -170,7 +170,7 @@ let retype ?(polyprop=true) sigma =
and type_of_global_reference_knowing_parameters env c args =
let argtyps =
- Array.map (fun c -> lazy (EConstr.to_constr sigma (type_of env c))) args in
+ Array.map (fun c -> lazy (EConstr.to_constr ~abort_on_undefined_evars:false sigma (type_of env c))) args in
match EConstr.kind sigma c with
| Ind (ind, u) ->
let u = EInstance.kind sigma u in
diff --git a/pretyping/retyping.mli b/pretyping/retyping.mli
index 40424ead4..2aff0c777 100644
--- a/pretyping/retyping.mli
+++ b/pretyping/retyping.mli
@@ -50,6 +50,6 @@ val type_of_global_reference_knowing_conclusion :
val sorts_of_context : env -> evar_map -> rel_context -> Sorts.t list
-val expand_projection : env -> evar_map -> Names.projection -> constr -> constr list -> constr
+val expand_projection : env -> evar_map -> Names.Projection.t -> constr -> constr list -> constr
val print_retype_error : retype_error -> Pp.t
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index 518d2f604..5a47acd22 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -416,7 +416,7 @@ exception Partial
reduction is solved by the expanded fix term. *)
let solve_arity_problem env sigma fxminargs c =
let evm = ref sigma in
- let set_fix i = evm := Evd.define i (Constr.mkVar vfx) !evm in
+ let set_fix i = evm := Evd.define i (mkVar vfx) !evm in
let rec check strict c =
let c' = whd_betaiotazeta sigma c in
let (h,rcargs) = decompose_app_vect sigma c' in
@@ -558,7 +558,7 @@ let match_eval_ref_value env sigma constr stack =
else
None
| Proj (p, c) when not (Projection.unfolded p) ->
- reduction_effect_hook env sigma (EConstr.to_constr sigma constr)
+ reduction_effect_hook env sigma (EConstr.to_constr ~abort_on_undefined_evars:false sigma constr)
(lazy (EConstr.to_constr sigma (applist (constr,stack))));
if is_evaluable env (EvalConstRef (Projection.constant p)) then
Some (mkProj (Projection.unfold p, c))
@@ -641,7 +641,7 @@ let whd_nothing_for_iota env sigma s =
| _ -> s)
| Evar ev -> s
| Meta ev ->
- (try whrec (EConstr.of_constr (Evd.meta_value sigma ev), stack)
+ (try whrec (Evd.meta_value sigma ev, stack)
with Not_found -> s)
| Const (const, u) when is_transparent_constant full_transparent_state const ->
let u = EInstance.kind sigma u in
@@ -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 08051fd3a..4386144fe 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 =
@@ -158,7 +165,7 @@ let rec is_class_type evd c =
| _ -> is_class_constr evd c
let is_class_evar evd evi =
- is_class_type evd (EConstr.of_constr evi.Evd.evar_concl)
+ is_class_type evd evi.Evd.evar_concl
(*
* classes persistent object
@@ -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 =
@@ -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 4c834f2f8..aaec73f04 100644
--- a/pretyping/typing.ml
+++ b/pretyping/typing.ml
@@ -29,13 +29,12 @@ let meta_type evd mv =
let ty =
try Evd.meta_ftype evd mv
with Not_found -> anomaly (str "unknown meta ?" ++ str (Nameops.string_of_meta mv) ++ str ".") in
- let ty = Evd.map_fl EConstr.of_constr ty in
meta_instance evd ty
let inductive_type_knowing_parameters env sigma (ind,u) jl =
let u = Unsafe.to_instance u in
let mspec = lookup_mind_specif env ind in
- let paramstyp = Array.map (fun j -> lazy (EConstr.to_constr sigma j.uj_type)) jl in
+ let paramstyp = Array.map (fun j -> lazy (EConstr.to_constr ~abort_on_undefined_evars:false sigma j.uj_type)) jl in
Inductive.type_of_inductive_knowing_parameters env (mspec,u) paramstyp
let e_type_judgment env evdref j =
@@ -129,7 +128,7 @@ let e_is_correct_arity env evdref c pj ind specif params =
then error ()
| Evar (ev,_), [] ->
let evd, s = Evd.fresh_sort_in_family env !evdref (max_sort allowed_sorts) in
- evdref := Evd.define ev (Constr.mkSort s) evd
+ evdref := Evd.define ev (mkSort s) evd
| _, (LocalDef _ as d)::ar' ->
srec (push_rel d env) (lift 1 pt') ar'
| _ ->
@@ -155,7 +154,7 @@ let e_type_case_branches env evdref (ind,largs) pj c =
let p = pj.uj_val in
let params = List.map EConstr.Unsafe.to_constr params in
let () = e_is_correct_arity env evdref c pj ind specif params in
- let lc = build_branches_type ind specif params (EConstr.to_constr !evdref p) in
+ let lc = build_branches_type ind specif params (EConstr.to_constr ~abort_on_undefined_evars:false !evdref 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
@@ -207,7 +206,7 @@ let enrich_env env evdref =
Environ.env_of_pre_env penv'
let check_fix env sigma pfix =
- let inj c = EConstr.to_constr sigma c in
+ let inj c = EConstr.to_constr ~abort_on_undefined_evars:false sigma c in
let (idx, (ids, cs, ts)) = pfix in
check_fix env (idx, (ids, Array.map inj cs, Array.map inj ts))
diff --git a/pretyping/typing.mli b/pretyping/typing.mli
index fe83a2cc8..4905adf1f 100644
--- a/pretyping/typing.mli
+++ b/pretyping/typing.mli
@@ -55,4 +55,4 @@ val judge_of_abstraction : Environ.env -> Name.t ->
unsafe_type_judgment -> unsafe_judgment -> unsafe_judgment
val judge_of_product : Environ.env -> Name.t ->
unsafe_type_judgment -> unsafe_type_judgment -> unsafe_judgment
-val judge_of_projection : env -> evar_map -> projection -> unsafe_judgment -> unsafe_judgment
+val judge_of_projection : env -> evar_map -> Projection.t -> unsafe_judgment -> unsafe_judgment
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index f2f922fd5..d98ce9aba 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -84,7 +84,7 @@ let occur_meta_or_undefined_evar evd c =
| Evar (ev,args) ->
(match evar_body (Evd.find evd ev) with
| Evar_defined c ->
- occrec c; Array.iter occrec args
+ occrec (EConstr.Unsafe.to_constr c); Array.iter occrec args
| Evar_empty -> raise Occur)
| _ -> Constr.iter occrec c
in try occrec c; false with Occur | Not_found -> true
@@ -189,10 +189,9 @@ let pose_all_metas_as_evars env evd t =
let rec aux t = match EConstr.kind !evdref t with
| Meta mv ->
(match Evd.meta_opt_fvalue !evdref mv with
- | Some ({rebus=c},_) -> EConstr.of_constr c
+ | Some ({rebus=c},_) -> c
| None ->
let {rebus=ty;freemetas=mvs} = Evd.meta_ftype evd mv in
- let ty = EConstr.of_constr ty in
let ty = if Evd.Metaset.is_empty mvs then ty else aux ty in
let ty =
if Flags.version_strictly_greater Flags.V8_6
@@ -200,7 +199,7 @@ let pose_all_metas_as_evars env evd t =
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 (EConstr.Unsafe.to_constr ev,(Conv,TypeNotProcessed)) !evdref;
+ evdref := meta_assign mv (ev,(Conv,TypeNotProcessed)) !evdref;
ev)
| _ ->
EConstr.map !evdref aux t in
@@ -466,7 +465,7 @@ let use_metas_pattern_unification sigma flags nb l =
type key =
| IsKey of CClosure.table_key
- | IsProj of projection * EConstr.constr
+ | IsProj of Projection.t * EConstr.constr
let expand_table_key env = function
| ConstKey cst -> constant_opt_value_in env cst
@@ -1060,7 +1059,7 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
(evd,t2::ks, m-1)
else
let mv = new_meta () in
- let evd' = meta_declare mv (EConstr.Unsafe.to_constr (substl ks b)) evd in
+ let evd' = meta_declare mv (substl ks b) evd in
(evd', mkMeta mv :: ks, m - 1))
(sigma,[],List.length bs) bs
in
@@ -1247,7 +1246,7 @@ let try_to_coerce env evd c cty tycon =
let j = make_judge c cty in
let (evd',j') = inh_conv_coerce_rigid_to true env evd j tycon in
let evd' = Evarconv.solve_unif_constraints_with_heuristics env evd' in
- let evd' = Evd.map_metas_fvalue (fun c -> EConstr.Unsafe.to_constr (nf_evar evd' (EConstr.of_constr c))) evd' in
+ let evd' = Evd.map_metas_fvalue (fun c -> nf_evar evd' c) evd' in
(evd',j'.uj_val)
let w_coerce_to_type env evd c cty mvty =
@@ -1359,11 +1358,11 @@ let w_merge env with_types flags (evd,metas,evars : subst0) =
if meta_defined evd mv then
let {rebus=c'},(status',_) = meta_fvalue evd mv in
let (take_left,st,(evd,metas',evars')) =
- merge_instances env evd flags status' status (EConstr.of_constr c') c
+ merge_instances env evd flags status' status c' c
in
let evd' =
if take_left then evd
- else meta_reassign mv (EConstr.Unsafe.to_constr c,(st,TypeProcessed)) evd
+ else meta_reassign mv (c,(st,TypeProcessed)) evd
in
w_merge_rec evd' (metas'@metas@metas'') (evars'@evars'') eqns
else
@@ -1372,7 +1371,7 @@ let w_merge env with_types flags (evd,metas,evars : subst0) =
if isMetaOf evd mv (whd_all env evd c) then evd
else error_cannot_unify env evd (mkMeta mv,c)
else
- meta_assign mv (EConstr.Unsafe.to_constr c,(status,TypeProcessed)) evd in
+ meta_assign mv (c,(status,TypeProcessed)) evd in
w_merge_rec evd' (metas''@metas) evars'' eqns
| [] ->
(* Process type eqns *)
@@ -1396,17 +1395,17 @@ let w_merge env with_types flags (evd,metas,evars : subst0) =
let (evd', c) = applyHead sp_env evd nargs hdc in
let (evd'',mc,ec) =
unify_0 sp_env evd' CUMUL flags
- (get_type_of sp_env evd' c) (EConstr.of_constr ev.evar_concl) in
+ (get_type_of sp_env evd' c) ev.evar_concl in
let evd''' = w_merge_rec evd'' mc ec [] in
if evd' == evd'''
- then Evd.define sp (EConstr.Unsafe.to_constr c) evd'''
- else Evd.define sp (EConstr.Unsafe.to_constr (Evarutil.nf_evar evd''' c)) evd''' in
+ then Evd.define sp c evd'''
+ else Evd.define sp (Evarutil.nf_evar evd''' c) evd''' in
let check_types evd =
let metas = Evd.meta_list evd in
let eqns = List.fold_left (fun acc (mv, b) ->
match b with
- | Clval (n, (t, (c, TypeNotProcessed)), v) -> (mv, c, EConstr.of_constr t.rebus) :: acc
+ | Clval (n, (t, (c, TypeNotProcessed)), v) -> (mv, c, t.rebus) :: acc
| _ -> acc) [] metas
in w_merge_rec evd [] [] eqns
in
@@ -1417,11 +1416,6 @@ let w_merge env with_types flags (evd,metas,evars : subst0) =
in
if with_types then check_types res else res
-let retract_coercible_metas evd =
- let (metas, evd) = retract_coercible_metas evd in
- let map (mv, c, st) = (mv, EConstr.of_constr c, st) in
- (List.map map metas, evd)
-
let w_unify_meta_types env ?(flags=default_unify_flags ()) evd =
let metas,evd = retract_coercible_metas evd in
w_merge env true flags.merge_unify_flags (evd,metas,[])
diff --git a/intf/vernacexpr.ml b/pretyping/vernacexpr.ml
index 06f969f19..3a49d6cf8 100644
--- a/intf/vernacexpr.ml
+++ b/pretyping/vernacexpr.ml
@@ -16,16 +16,13 @@ open Libnames
(** Vernac expressions, produced by the parser *)
type class_rawexpr = FunClass | SortClass | RefClass of reference or_by_notation
-(* spiwack: I'm choosing, for now, to have [goal_selector] be a
- different type than [goal_reference] mostly because if it makes sense
- to print a goal that is out of focus (or already solved) it doesn't
- make sense to apply a tactic to it. Hence it the types may look very
- similar, they do not seem to mean the same thing. *)
-type goal_selector =
+type goal_selector = Goal_select.t =
+ | SelectAlreadyFocused
| SelectNth of int
| SelectList of (int * int) list
| SelectId of Id.t
| SelectAll
+[@@ocaml.deprecated "Use Goal_select.t"]
type goal_identifier = string
type scope_name = string
@@ -68,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_selector option
+ | PrintAbout of reference or_by_notation * Universes.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
@@ -115,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
@@ -197,7 +196,6 @@ type one_inductive_expr =
ident_decl * local_binder_expr list * constr_expr option * constructor_expr list
type typeclass_constraint = name_decl * Decl_kinds.binding_kind * constr_expr
-
and typeclass_context = typeclass_constraint list
type proof_expr =
@@ -269,32 +267,32 @@ type extend_name =
(* This type allows registering the inlining of constants in native compiler.
It will be extended with primitive inductive types and operators *)
-type register_kind =
+type register_kind =
| RegisterInline
-type bullet =
- | Dash of int
- | Star of int
- | Plus of int
+type bullet = Proof_bullet.t
+[@@ocaml.deprecated "Alias type, please use [Proof_bullet.t]"]
(** {6 Types concerning the module layer} *)
(** Rigid / flexible module signature *)
-type 'a module_signature =
+type 'a module_signature = 'a Declaremods.module_signature =
| Enforce of 'a (** ... : T *)
| Check of 'a list (** ... <: T1 <: T2, possibly empty *)
+[@@ocaml.deprecated "please use [Declaremods.module_signature]."]
(** Which module inline annotations should we honor,
either None or the ones whose level is less or equal
to the given integer *)
-type inline =
+type inline = Declaremods.inline =
| NoInline
| DefaultInline
| InlineAt of int
+[@@ocaml.deprecated "please use [Declaremods.inline]."]
-type module_ast_inl = module_ast * inline
+type module_ast_inl = module_ast * Declaremods.inline
type module_binder = bool option * lident list * module_ast_inl
(** [Some b] if locally enabled/disabled according to [b], [None] if
@@ -333,7 +331,7 @@ type nonrec vernac_expr =
| VernacEndProof of proof_end
| VernacExactProof of constr_expr
| VernacAssumption of (Decl_kinds.discharge * Decl_kinds.assumption_object_kind) *
- inline * (ident_decl list * constr_expr) with_coercion list
+ Declaremods.inline * (ident_decl list * constr_expr) with_coercion list
| VernacInductive of vernac_cumulative option * Decl_kinds.private_flag * inductive_flag * (inductive_expr * decl_notation list) list
| VernacFixpoint of Decl_kinds.discharge * (fixpoint_expr * decl_notation list) list
| VernacCoFixpoint of Decl_kinds.discharge * (cofixpoint_expr * decl_notation list) list
@@ -360,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 *)
@@ -373,7 +371,7 @@ type nonrec vernac_expr =
| VernacDeclareModule of bool option * lident *
module_binder list * module_ast_inl
| VernacDefineModule of bool option * lident * module_binder list *
- module_ast_inl module_signature * module_ast_inl list
+ module_ast_inl Declaremods.module_signature * module_ast_inl list
| VernacDeclareModuleType of lident *
module_binder list * module_ast_inl list * module_ast_inl list
| VernacInclude of module_ast_inl list
@@ -423,11 +421,11 @@ type nonrec vernac_expr =
| VernacRemoveOption of Goptions.option_name * option_ref_value list
| VernacMemOption of Goptions.option_name * option_ref_value list
| VernacPrintOption of Goptions.option_name
- | VernacCheckMayEval of Genredexpr.raw_red_expr option * goal_selector option * constr_expr
+ | VernacCheckMayEval of Genredexpr.raw_red_expr option * Goal_select.t option * constr_expr
| VernacGlobalCheck of constr_expr
| VernacDeclareReduction of string * Genredexpr.raw_red_expr
| VernacPrint of printable
- | VernacSearch of searchable * goal_selector option * search_restriction
+ | VernacSearch of searchable * Goal_select.t option * search_restriction
| VernacLocate of locatable
| VernacRegister of lident * register_kind
| VernacComments of comment list
@@ -441,8 +439,8 @@ type nonrec vernac_expr =
| VernacFocus of int option
| VernacUnfocus
| VernacUnfocused
- | VernacBullet of bullet
- | VernacSubproof of goal_selector option
+ | VernacBullet of Proof_bullet.t
+ | VernacSubproof of Goal_select.t option
| VernacEndSubproof
| VernacShow of showable
| VernacCheckGuard
diff --git a/pretyping/vnorm.ml b/pretyping/vnorm.ml
index 3c9b8bc33..049c3aff5 100644
--- a/pretyping/vnorm.ml
+++ b/pretyping/vnorm.ml
@@ -205,7 +205,7 @@ and nf_univ_args ~nb_univs mk env sigma stk =
and nf_evar env sigma evk stk =
let evi = try Evd.find sigma evk with Not_found -> assert false in
let hyps = Environ.named_context_of_val (Evd.evar_filtered_hyps evi) in
- let concl = Evd.evar_concl evi in
+ let concl = EConstr.Unsafe.to_constr @@ Evd.evar_concl evi in
if List.is_empty hyps then
nf_stk env sigma (mkEvar (evk, [||])) concl stk
else match stk with
@@ -381,8 +381,8 @@ let cbv_vm env sigma c t =
if Termops.occur_meta sigma c then
CErrors.user_err Pp.(str "vm_compute does not support metas.");
(** This evar-normalizes terms beforehand *)
- let c = EConstr.to_constr sigma c in
- let t = EConstr.to_constr sigma t in
+ let c = EConstr.to_constr ~abort_on_undefined_evars:false sigma c in
+ let t = EConstr.to_constr ~abort_on_undefined_evars:false sigma t in
let v = Vconv.val_of_constr env c in
EConstr.of_constr (nf_val env sigma v t)
diff --git a/printing/ppvernac.ml b/printing/ppvernac.ml
index 7eb8396ac..f26ac0bf9 100644
--- a/printing/ppvernac.ml
+++ b/printing/ppvernac.ml
@@ -16,12 +16,13 @@ open Util
open CAst
open Extend
-open Vernacexpr
-open Pputils
open Libnames
+open Decl_kinds
open Constrexpr
open Constrexpr_ops
-open Decl_kinds
+open Vernacexpr
+open Declaremods
+open Pputils
open Ppconstr
@@ -144,7 +145,7 @@ open Decl_kinds
| SearchString (s,sc) -> qs s ++ pr_opt (fun sc -> str "%" ++ str sc) sc
let pr_search a gopt b pr_p =
- pr_opt (fun g -> Proof_bullet.pr_goal_selector g ++ str ":"++ spc()) gopt
+ pr_opt (fun g -> Goal_select.pr_goal_selector g ++ str ":"++ spc()) gopt
++
match a with
| SearchHead c -> keyword "SearchHead" ++ spc() ++ pr_p c ++ pr_in_out_modules b
@@ -187,7 +188,7 @@ open Decl_kinds
| 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
@@ -507,7 +508,7 @@ open Decl_kinds
| PrintVisibility s ->
keyword "Print Visibility" ++ pr_opt str s
| PrintAbout (qid,l,gopt) ->
- pr_opt (fun g -> Proof_bullet.pr_goal_selector g ++ str ":"++ spc()) gopt
+ pr_opt (fun g -> Goal_select.pr_goal_selector g ++ str ":"++ spc()) gopt
++ keyword "About" ++ spc() ++ pr_smart_global qid ++ pr_univ_name_list l
| PrintImplicit qid ->
keyword "Print Implicit" ++ spc() ++ pr_smart_global qid
@@ -1121,7 +1122,7 @@ open Decl_kinds
| None -> hov 2 (keyword "Check" ++ spc() ++ pr_lconstr c)
in
let pr_i = match io with None -> mt ()
- | Some i -> Proof_bullet.pr_goal_selector i ++ str ": " in
+ | Some i -> Goal_select.pr_goal_selector i ++ str ": " in
return (pr_i ++ pr_mayeval r c)
| VernacGlobalCheck c ->
return (hov 2 (keyword "Type" ++ pr_constrarg c))
@@ -1175,7 +1176,8 @@ open Decl_kinds
| VernacProofMode s ->
return (keyword "Proof Mode" ++ str s)
| VernacBullet b ->
- return (begin match b with
+ (* XXX: Redundant with Proof_bullet.print *)
+ return (let open Proof_bullet in begin match b with
| Dash n -> str (String.make n '-')
| Star n -> str (String.make n '*')
| Plus n -> str (String.make n '+')
@@ -1183,7 +1185,7 @@ open Decl_kinds
| VernacSubproof None ->
return (str "{")
| VernacSubproof (Some i) ->
- return (Proof_bullet.pr_goal_selector i ++ str ":" ++ spc () ++ str "{")
+ return (Goal_select.pr_goal_selector i ++ str ":" ++ spc () ++ str "{")
| VernacEndSubproof ->
return (str "}")
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index 1f17d844f..185b1648c 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -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 ->
diff --git a/printing/prettyp.mli b/printing/prettyp.mli
index 213f0aeeb..2f2dcd563 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
@@ -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
diff --git a/printing/printer.ml b/printing/printer.ml
index 199aa79c6..edcce874d 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -93,13 +93,13 @@ let _ = Hook.set Refine.pr_constr pr_constr_env
let pr_lconstr_goal_style_env env sigma c = pr_leconstr_core true env sigma (EConstr.of_constr c)
let pr_constr_goal_style_env env sigma c = pr_econstr_core true env sigma (EConstr.of_constr c)
-let pr_open_lconstr_env env sigma (_,c) = pr_lconstr_env env sigma c
-let pr_open_constr_env env sigma (_,c) = pr_constr_env env sigma c
-
let pr_econstr_n_env env sigma c = pr_econstr_n_core false env sigma c
let pr_leconstr_env env sigma c = pr_leconstr_core false env sigma c
let pr_econstr_env env sigma c = pr_econstr_core false env sigma c
+let pr_open_lconstr_env env sigma (_,c) = pr_leconstr_env env sigma c
+let pr_open_constr_env env sigma (_,c) = pr_econstr_env env sigma c
+
(* NB do not remove the eta-redexes! Global.env() has side-effects... *)
let pr_lconstr t =
let (sigma, env) = Pfedit.get_current_context () in
@@ -108,12 +108,12 @@ let pr_constr t =
let (sigma, env) = Pfedit.get_current_context () in
pr_constr_env env sigma t
-let pr_open_lconstr (_,c) = pr_lconstr c
-let pr_open_constr (_,c) = pr_constr c
-
let pr_leconstr c = pr_lconstr (EConstr.Unsafe.to_constr c)
let pr_econstr c = pr_constr (EConstr.Unsafe.to_constr c)
+let pr_open_lconstr (_,c) = pr_leconstr c
+let pr_open_constr (_,c) = pr_econstr c
+
let pr_constr_under_binders_env_gen pr env sigma (ids,c) =
(* Warning: clashes can occur with variables of same name in env but *)
(* we also need to preserve the actual names of the patterns *)
@@ -541,12 +541,12 @@ let pr_evgl_sign sigma evi =
if List.is_empty ids then mt () else
(str " (" ++ prlist_with_sep pr_comma pr_id ids ++ str " cannot be used)")
in
- let pc = pr_lconstr_env env sigma evi.evar_concl in
+ let pc = pr_leconstr_env env sigma evi.evar_concl in
let candidates =
match evi.evar_body, evi.evar_candidates with
| Evar_empty, Some l ->
spc () ++ str "= {" ++
- prlist_with_sep (fun () -> str "|") (pr_lconstr_env env sigma) l ++ str "}"
+ prlist_with_sep (fun () -> str "|") (pr_leconstr_env env sigma) l ++ str "}"
| _ ->
mt ()
in
@@ -622,8 +622,8 @@ let print_evar_constraints gl sigma =
end
in
let pr_evconstr (pbty,env,t1,t2) =
- let t1 = Evarutil.nf_evar sigma (EConstr.of_constr t1)
- and t2 = Evarutil.nf_evar sigma (EConstr.of_constr t2) in
+ let t1 = Evarutil.nf_evar sigma t1
+ and t2 = Evarutil.nf_evar sigma t2 in
let env =
(** We currently allow evar instances to refer to anonymous de Bruijn
indices, so we protect the error printing code in this case by giving
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/proofs/clenv.ml b/proofs/clenv.ml
index 03ff580ad..aeaf16723 100644
--- a/proofs/clenv.ml
+++ b/proofs/clenv.ml
@@ -62,9 +62,6 @@ let clenv_get_type_of ce c = Retyping.get_type_of (cl_env ce) (cl_sigma ce) c
exception NotExtensibleClause
-let mk_freelisted c =
- map_fl EConstr.of_constr (mk_freelisted (EConstr.Unsafe.to_constr c))
-
let clenv_push_prod cl =
let typ = whd_all (cl_env cl) (cl_sigma cl) (clenv_type cl) in
let rec clrec typ = match EConstr.kind cl.evd typ with
@@ -73,7 +70,7 @@ let clenv_push_prod cl =
let mv = new_meta () in
let dep = not (noccurn (cl_sigma cl) 1 u) in
let na' = if dep then na else Anonymous in
- let e' = meta_declare mv (EConstr.Unsafe.to_constr t) ~name:na' cl.evd in
+ let e' = meta_declare mv t ~name:na' cl.evd in
let concl = if dep then subst1 (mkMeta mv) u else u in
let def = applist (cl.templval.rebus,[mkMeta mv]) in
{ templval = mk_freelisted def;
@@ -107,8 +104,7 @@ let clenv_environments evd bound t =
let mv = new_meta () in
let dep = not (noccurn evd 1 t2) in
let na' = if dep then na else Anonymous in
- let t1 = EConstr.Unsafe.to_constr t1 in
- let e' = meta_declare mv t1 ~name:na' e in
+ let e' = meta_declare mv t1 ~name:na' e in
clrec (e', (mkMeta mv)::metas) (Option.map ((+) (-1)) n)
(if dep then (subst1 (mkMeta mv) t2) else t2)
| (n, LetIn (na,b,_,t)) -> clrec (e,metas) n (subst1 b t)
@@ -167,13 +163,13 @@ let clenv_assign mv rhs clenv =
user_err Pp.(str "clenv_assign: circularity in unification");
try
if meta_defined clenv.evd mv then
- if not (EConstr.eq_constr clenv.evd (EConstr.of_constr (fst (meta_fvalue clenv.evd mv)).rebus) rhs) then
+ if not (EConstr.eq_constr clenv.evd (fst (meta_fvalue clenv.evd mv)).rebus rhs) then
error_incompatible_inst clenv mv
else
clenv
else
let st = (Conv,TypeNotProcessed) in
- {clenv with evd = meta_assign mv (EConstr.Unsafe.to_constr rhs_fls.rebus,st) clenv.evd}
+ {clenv with evd = meta_assign mv (rhs_fls.rebus,st) clenv.evd}
with Not_found ->
user_err Pp.(str "clenv_assign: undefined meta")
@@ -218,7 +214,7 @@ let clenv_assign mv rhs clenv =
*)
let clenv_metas_in_type_of_meta evd mv =
- (mk_freelisted (meta_instance evd (map_fl EConstr.of_constr (meta_ftype evd mv)))).freemetas
+ (mk_freelisted (meta_instance evd (meta_ftype evd mv))).freemetas
let dependent_in_type_of_metas clenv mvs =
List.fold_right
@@ -288,11 +284,11 @@ let adjust_meta_source evd mv = function
in situations like "ex_intro (fun x => P) ?ev p" *)
let f = function (mv',(Cltyp (_,t) | Clval (_,_,t))) ->
if Metaset.mem mv t.freemetas then
- let f,l = decompose_app evd (EConstr.of_constr t.rebus) in
+ let f,l = decompose_app evd t.rebus in
match EConstr.kind evd f with
| Meta mv'' ->
(match meta_opt_fvalue evd mv'' with
- | Some (c,_) -> match_name (EConstr.of_constr c.rebus) l
+ | Some (c,_) -> match_name c.rebus l
| None -> None)
| _ -> None
else None in
@@ -502,7 +498,6 @@ let clenv_assign_binding clenv k c =
let k_typ = clenv_hnf_constr clenv (clenv_meta_type clenv k) in
let c_typ = nf_betaiota clenv.env clenv.evd (clenv_get_type_of clenv c) in
let status,clenv',c = clenv_unify_binding_type clenv c c_typ k_typ in
- let c = EConstr.Unsafe.to_constr c in
{ clenv' with evd = meta_assign k (c,(Conv,status)) clenv'.evd }
let clenv_match_args bl clenv =
@@ -515,7 +510,7 @@ let clenv_match_args bl clenv =
(fun clenv {CAst.loc;v=(b,c)} ->
let k = meta_of_binder clenv loc mvs b in
if meta_defined clenv.evd k then
- if EConstr.eq_constr clenv.evd (EConstr.of_constr (fst (meta_fvalue clenv.evd k)).rebus) c then clenv
+ if EConstr.eq_constr clenv.evd (fst (meta_fvalue clenv.evd k)).rebus c then clenv
else error_already_defined b
else
clenv_assign_binding clenv k c)
@@ -677,7 +672,7 @@ let define_with_type sigma env ev c =
let j = Environ.make_judge c ty in
let (sigma, j) = Coercion.inh_conv_coerce_to true env sigma j t in
let (ev, _) = destEvar sigma ev in
- let sigma = Evd.define ev (EConstr.Unsafe.to_constr j.Environ.uj_val) sigma in
+ let sigma = Evd.define ev j.Environ.uj_val sigma in
sigma
let solve_evar_clause env sigma hyp_only clause = function
diff --git a/proofs/evar_refiner.ml b/proofs/evar_refiner.ml
index 0d197c92c..c80f370fd 100644
--- a/proofs/evar_refiner.ml
+++ b/proofs/evar_refiner.ml
@@ -25,8 +25,6 @@ open Ltac_pretype
type glob_constr_ltac_closure = ltac_var_map * glob_constr
let depends_on_evar sigma evk _ (pbty,_,t1,t2) =
- let t1 = EConstr.of_constr t1 in
- let t2 = EConstr.of_constr t2 in
try Evar.equal (head_evar sigma t1) evk
with NoHeadEvar ->
try Evar.equal (head_evar sigma t2) evk
@@ -35,12 +33,12 @@ let depends_on_evar sigma evk _ (pbty,_,t1,t2) =
let define_and_solve_constraints evk c env evd =
if Termops.occur_evar evd evk c then
Pretype_errors.error_occur_check env evd evk c;
- let evd = define evk (EConstr.Unsafe.to_constr c) evd in
+ let evd = define evk c evd in
let (evd,pbs) = extract_changed_conv_pbs evd (depends_on_evar evd evk) in
match
List.fold_left
(fun p (pbty,env,t1,t2) -> match p with
- | Success evd -> Evarconv.evar_conv_x full_transparent_state env evd pbty (EConstr.of_constr t1) (EConstr.of_constr t2)
+ | Success evd -> Evarconv.evar_conv_x full_transparent_state env evd pbty t1 t2
| UnifFailure _ as x -> x) (Success evd)
pbs
with
@@ -59,7 +57,7 @@ let w_refine (evk,evi) (ltac_var,rawc) sigma =
Pretyping.fail_evar = false;
Pretyping.expand_evars = true } in
try Pretyping.understand_ltac flags
- env sigma ltac_var (Pretyping.OfType (EConstr.of_constr evi.evar_concl)) rawc
+ env sigma ltac_var (Pretyping.OfType evi.evar_concl) rawc
with e when CErrors.noncritical e ->
let loc = Glob_ops.loc_of_glob_constr rawc in
user_err ?loc
diff --git a/proofs/goal.ml b/proofs/goal.ml
index ba7e458f3..1440d1636 100644
--- a/proofs/goal.ml
+++ b/proofs/goal.ml
@@ -48,7 +48,7 @@ module V82 = struct
(* Access to ".evar_concl" *)
let concl evars gl =
let evi = Evd.find evars gl in
- EConstr.of_constr evi.Evd.evar_concl
+ evi.Evd.evar_concl
(* Access to ".evar_extra" *)
let extra evars gl =
@@ -61,7 +61,6 @@ module V82 = struct
be shelved. It must not appear as a future_goal, so the future
goals are restored to their initial value after the evar is
created. *)
- let concl = EConstr.Unsafe.to_constr concl in
let prev_future_goals = Evd.save_future_goals evars in
let evi = { Evd.evar_hyps = hyps;
Evd.evar_concl = concl;
@@ -86,7 +85,7 @@ module V82 = struct
if not (Evarutil.occur_evar_upto sigma evk c) then ()
else Pretype_errors.error_occur_check Environ.empty_env sigma evk c
in
- Evd.define evk (EConstr.Unsafe.to_constr c) sigma
+ Evd.define evk c sigma
(* Instantiates a goal with an open term, using name of goal for evk' *)
let partial_solution_to sigma evk evk' c =
@@ -100,7 +99,9 @@ module V82 = struct
let same_goal evars1 gl1 evars2 gl2 =
let evi1 = Evd.find evars1 gl1 in
let evi2 = Evd.find evars2 gl2 in
- Constr.equal evi1.Evd.evar_concl evi2.Evd.evar_concl &&
+ let c1 = EConstr.Unsafe.to_constr evi1.Evd.evar_concl in
+ let c2 = EConstr.Unsafe.to_constr evi2.Evd.evar_concl in
+ Constr.equal c1 c2 &&
Environ.eq_named_context_val evi1.Evd.evar_hyps evi2.Evd.evar_hyps
let weak_progress glss gls =
@@ -117,20 +118,6 @@ module V82 = struct
with a good implementation of them.
*)
- (* Used for congruence closure *)
- let new_goal_with sigma gl extra_hyps =
- let evi = Evd.find sigma gl in
- let hyps = evi.Evd.evar_hyps in
- let new_hyps =
- List.fold_right Environ.push_named_context_val extra_hyps hyps in
- let filter = evi.Evd.evar_filter in
- let new_filter = Evd.Filter.extend (List.length extra_hyps) filter in
- let new_evi =
- { evi with Evd.evar_hyps = new_hyps; Evd.evar_filter = new_filter } in
- let new_evi = Typeclasses.mark_unresolvable new_evi in
- let (sigma, evk) = Evarutil.new_pure_evar_full Evd.empty new_evi in
- { Evd.it = evk ; sigma = sigma; }
-
(* Used by the compatibility layer and typeclasses *)
let nf_evar sigma gl =
let evi = Evd.find sigma gl in
diff --git a/proofs/goal.mli b/proofs/goal.mli
index dc9863156..b8c979ad7 100644
--- a/proofs/goal.mli
+++ b/proofs/goal.mli
@@ -64,9 +64,6 @@ module V82 : sig
(* Principal part of tclNOTSAMEGOAL *)
val same_goal : Evd.evar_map -> goal -> Evd.evar_map -> goal -> bool
- (* Used for congruence closure *)
- val new_goal_with : Evd.evar_map -> goal -> Context.Named.t -> goal Evd.sigma
-
(* Used by the compatibility layer and typeclasses *)
val nf_evar : Evd.evar_map -> goal -> goal * Evd.evar_map
diff --git a/proofs/goal_select.ml b/proofs/goal_select.ml
new file mode 100644
index 000000000..65a94a2c6
--- /dev/null
+++ b/proofs/goal_select.ml
@@ -0,0 +1,68 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Names
+
+(* spiwack: I'm choosing, for now, to have [goal_selector] be a
+ different type than [goal_reference] mostly because if it makes sense
+ to print a goal that is out of focus (or already solved) it doesn't
+ make sense to apply a tactic to it. Hence it the types may look very
+ similar, they do not seem to mean the same thing. *)
+type t =
+ | SelectAlreadyFocused
+ | SelectNth of int
+ | SelectList of (int * int) list
+ | SelectId of Id.t
+ | SelectAll
+
+(* Default goal selector: selector chosen when a tactic is applied
+ without an explicit selector. *)
+let default_goal_selector = ref (SelectNth 1)
+let get_default_goal_selector () = !default_goal_selector
+
+let pr_range_selector (i, j) =
+ if i = j then Pp.int i
+ else Pp.(int i ++ str "-" ++ int j)
+
+let pr_goal_selector = function
+ | SelectAlreadyFocused -> Pp.str "!"
+ | SelectAll -> Pp.str "all"
+ | SelectNth i -> Pp.int i
+ | SelectList l ->
+ Pp.(str "["
+ ++ prlist_with_sep pr_comma pr_range_selector l
+ ++ str "]")
+ | SelectId id -> Names.Id.print id
+
+let parse_goal_selector = function
+ | "!" -> SelectAlreadyFocused
+ | "all" -> SelectAll
+ | i ->
+ let err_msg = "The default selector must be \"all\" or a natural number." in
+ begin try
+ let i = int_of_string i in
+ if i < 0 then CErrors.user_err Pp.(str err_msg);
+ SelectNth i
+ with Failure _ -> CErrors.user_err Pp.(str err_msg)
+ end
+
+let _ = let open Goptions in
+ declare_string_option
+ { optdepr = false;
+ optname = "default goal selector" ;
+ optkey = ["Default";"Goal";"Selector"] ;
+ optread = begin fun () ->
+ Pp.string_of_ppcmds
+ (pr_goal_selector !default_goal_selector)
+ end;
+ optwrite = begin fun n ->
+ default_goal_selector := parse_goal_selector n
+ end
+ }
diff --git a/proofs/goal_select.mli b/proofs/goal_select.mli
new file mode 100644
index 000000000..b1c572388
--- /dev/null
+++ b/proofs/goal_select.mli
@@ -0,0 +1,26 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Names
+
+(* spiwack: I'm choosing, for now, to have [goal_selector] be a
+ different type than [goal_reference] mostly because if it makes sense
+ to print a goal that is out of focus (or already solved) it doesn't
+ make sense to apply a tactic to it. Hence it the types may look very
+ similar, they do not seem to mean the same thing. *)
+type t =
+ | SelectAlreadyFocused
+ | SelectNth of int
+ | SelectList of (int * int) list
+ | SelectId of Id.t
+ | SelectAll
+
+val pr_goal_selector : t -> Pp.t
+val get_default_goal_selector : unit -> t
diff --git a/proofs/logic.ml b/proofs/logic.ml
index e5294715e..4934afa83 100644
--- a/proofs/logic.ml
+++ b/proofs/logic.ml
@@ -289,7 +289,15 @@ let collect_meta_variables c =
let rec collrec deep acc c = match kind c with
| Meta mv -> if deep then error_unsupported_deep_meta () else mv::acc
| Cast(c,_,_) -> collrec deep acc c
- | (App _| Case _) -> Constr.fold (collrec deep) acc c
+ | Case(ci,p,c,br) ->
+ (* Hack assuming only two situations: the legacy one that branches,
+ if with Metas, are Meta, and the new one with eta-let-expanded
+ branches *)
+ let br = Array.map2 (fun n b -> try snd (Term.decompose_lam_n_decls n b) with UserError _ -> b) ci.ci_cstr_ndecls br in
+ Array.fold_left (collrec deep)
+ (Constr.fold (collrec deep) (Constr.fold (collrec deep) acc p) c)
+ br
+ | App _ -> Constr.fold (collrec deep) acc c
| Proj (_, c) -> collrec deep acc c
| _ -> Constr.fold (collrec true) acc c
in
@@ -387,12 +395,7 @@ let rec mk_refgoals sigma goal goalacc conclty trm =
| Case (ci,p,c,lf) ->
let (acc',lbrty,conclty',sigma,p',c') = mk_casegoals sigma goal goalacc p c in
let sigma = check_conv_leq_goal env sigma trm conclty' conclty in
- let (acc'',sigma, rbranches) =
- Array.fold_left2
- (fun (lacc,sigma,bacc) ty fi ->
- let (r,_,s,b') = mk_refgoals sigma goal lacc ty fi in r,s,(b'::bacc))
- (acc',sigma,[]) lbrty lf
- in
+ let (acc'',sigma,rbranches) = treat_case sigma goal ci lbrty lf acc' in
let lf' = Array.rev_of_list rbranches in
let ans =
if p' == p && c' == c && Array.equal (==) lf' lf then trm
@@ -440,12 +443,7 @@ and mk_hdgoals sigma goal goalacc trm =
| Case (ci,p,c,lf) ->
let (acc',lbrty,conclty',sigma,p',c') = mk_casegoals sigma goal goalacc p c in
- let (acc'',sigma,rbranches) =
- Array.fold_left2
- (fun (lacc,sigma,bacc) ty fi ->
- let (r,_,s,b') = mk_refgoals sigma goal lacc ty fi in r,s,(b'::bacc))
- (acc',sigma,[]) lbrty lf
- in
+ let (acc'',sigma,rbranches) = treat_case sigma goal ci lbrty lf acc' in
let lf' = Array.rev_of_list rbranches in
let ans =
if p' == p && c' == c && Array.equal (==) lf' lf then trm
@@ -497,6 +495,50 @@ and mk_casegoals sigma goal goalacc p c =
let (lbrty,conclty) = type_case_branches_with_names env sigma indspec p c in
(acc'',lbrty,conclty,sigma,p',c')
+and treat_case sigma goal ci lbrty lf acc' =
+ let rec strip_outer_cast c = match kind c with
+ | Cast (c,_,_) -> strip_outer_cast c
+ | _ -> c in
+ let decompose_app_vect c = match kind c with
+ | App (f,cl) -> (f, cl)
+ | _ -> (c,[||]) in
+ let env = Goal.V82.env sigma goal in
+ Array.fold_left3
+ (fun (lacc,sigma,bacc) ty fi l ->
+ if isMeta (strip_outer_cast fi) then
+ (* Support for non-eta-let-expanded Meta as found in *)
+ (* destruct/case with an non eta-let expanded elimination scheme *)
+ let (r,_,s,fi') = mk_refgoals sigma goal lacc ty fi in
+ r,s,(fi'::bacc)
+ else
+ (* Deal with a branch in expanded form of the form
+ Case(ci,p,c,[|eta-let-exp(Meta);...;eta-let-exp(Meta)|]) as
+ if it were not so, so as to preserve compatibility with when
+ destruct/case generated schemes of the form
+ Case(ci,p,c,[|Meta;...;Meta|];
+ CAUTION: it does not deal with the general case of eta-zeta
+ reduced branches having a form different from Meta, as it
+ would be theoretically the case with third-party code *)
+ let n = List.length l in
+ let ctx, body = Term.decompose_lam_n_decls n fi in
+ let head, args = decompose_app_vect body in
+ (* Strip cast because clenv_cast_meta adds a cast when the branch is
+ eta-expanded but when not when the branch has the single-meta
+ form [Meta] *)
+ let head = strip_outer_cast head in
+ if isMeta head then begin
+ assert (args = Context.Rel.to_extended_vect mkRel 0 ctx);
+ let head' = lift (-n) head in
+ let (r,_,s,head'') = mk_refgoals sigma goal lacc ty head' in
+ let fi' = it_mkLambda_or_LetIn (mkApp (head'',args)) ctx in
+ (r,s,fi'::bacc)
+ end
+ else
+ (* Supposed to be meta-free *)
+ let sigma, t'ty = goal_type_of env sigma fi in
+ let sigma = check_conv_leq_goal env sigma fi t'ty ty in
+ (lacc,sigma,fi::bacc))
+ (acc',sigma,[]) lbrty lf ci.ci_pp_info.cstr_tags
let convert_hyp check sign sigma d =
let id = NamedDecl.get_id d in
diff --git a/proofs/pfedit.ml b/proofs/pfedit.ml
index 8725f51cd..03c0969fa 100644
--- a/proofs/pfedit.ml
+++ b/proofs/pfedit.ml
@@ -100,11 +100,23 @@ let solve ?with_end_tac gi info_lvl tac pr =
| None -> tac
| Some _ -> Proofview.Trace.record_info_trace tac
in
- let tac = match gi with
- | Vernacexpr.SelectNth i -> Proofview.tclFOCUS i i tac
- | Vernacexpr.SelectList l -> Proofview.tclFOCUSLIST l tac
- | Vernacexpr.SelectId id -> Proofview.tclFOCUSID id tac
- | Vernacexpr.SelectAll -> tac
+ let tac = let open Goal_select in match gi with
+ | SelectAlreadyFocused ->
+ let open Proofview.Notations in
+ Proofview.numgoals >>= fun n ->
+ if n == 1 then tac
+ else
+ let e = CErrors.UserError
+ (None,
+ Pp.(str "Expected a single focused goal but " ++
+ int n ++ str " goals are focused."))
+ in
+ Proofview.tclZERO e
+
+ | SelectNth i -> Proofview.tclFOCUS i i tac
+ | SelectList l -> Proofview.tclFOCUSLIST l tac
+ | SelectId id -> Proofview.tclFOCUSID id tac
+ | SelectAll -> tac
in
let tac =
if use_unification_heuristics () then
@@ -121,7 +133,7 @@ let solve ?with_end_tac gi info_lvl tac pr =
with
Proof_global.NoCurrentProof -> CErrors.user_err Pp.(str "No focused proof")
-let by tac = Proof_global.with_current_proof (fun _ -> solve (Vernacexpr.SelectNth 1) None tac)
+let by tac = Proof_global.with_current_proof (fun _ -> solve (Goal_select.SelectNth 1) None tac)
let instantiate_nth_evar_com n com =
Proof_global.simple_with_current_proof (fun _ p -> Proof.V82.instantiate_evar n com p)
@@ -233,7 +245,7 @@ let apply_implicit_tactic tac = (); fun env sigma evk ->
(Environ.named_context env) ->
let tac = Proofview.tclTHEN tac (Proofview.tclEXTEND [] (Proofview.tclZERO (CErrors.UserError (None,Pp.str"Proof is not complete."))) []) in
(try
- let c = Evarutil.nf_evars_universes sigma evi.evar_concl in
+ let c = Evarutil.nf_evars_universes sigma (EConstr.Unsafe.to_constr evi.evar_concl) in
let c = EConstr.of_constr c in
if Evarutil.has_undefined_evars sigma c then raise Exit;
let (ans, _, ctx) =
diff --git a/proofs/pfedit.mli b/proofs/pfedit.mli
index 65cde3a3a..805635dfa 100644
--- a/proofs/pfedit.mli
+++ b/proofs/pfedit.mli
@@ -75,7 +75,7 @@ val current_proof_statement :
tac] applies [tac] to all subgoals. *)
val solve : ?with_end_tac:unit Proofview.tactic ->
- Vernacexpr.goal_selector -> int option -> unit Proofview.tactic ->
+ Goal_select.t -> int option -> unit Proofview.tactic ->
Proof.t -> Proof.t * bool
(** [by tac] applies tactic [tac] to the 1st subgoal of the current
diff --git a/proofs/proof_bullet.ml b/proofs/proof_bullet.ml
index e22d382f7..cc3e79f85 100644
--- a/proofs/proof_bullet.ml
+++ b/proofs/proof_bullet.ml
@@ -10,19 +10,22 @@
open Proof
-type t = Vernacexpr.bullet
+type t =
+ | Dash of int
+ | Star of int
+ | Plus of int
let bullet_eq b1 b2 = match b1, b2 with
-| Vernacexpr.Dash n1, Vernacexpr.Dash n2 -> n1 = n2
-| Vernacexpr.Star n1, Vernacexpr.Star n2 -> n1 = n2
-| Vernacexpr.Plus n1, Vernacexpr.Plus n2 -> n1 = n2
+| Dash n1, Dash n2 -> n1 = n2
+| Star n1, Star n2 -> n1 = n2
+| Plus n1, Plus n2 -> n1 = n2
| _ -> false
let pr_bullet b =
match b with
- | Vernacexpr.Dash n -> Pp.(str (String.make n '-'))
- | Vernacexpr.Star n -> Pp.(str (String.make n '*'))
- | Vernacexpr.Plus n -> Pp.(str (String.make n '+'))
+ | Dash n -> Pp.(str (String.make n '-'))
+ | Star n -> Pp.(str (String.make n '*'))
+ | Plus n -> Pp.(str (String.make n '+'))
type behavior = {
@@ -195,52 +198,5 @@ let put p b =
let suggest p =
(!current_behavior).suggest p
-(**********************************************************)
-(* *)
-(* Default goal selector *)
-(* *)
-(**********************************************************)
-
-
-(* Default goal selector: selector chosen when a tactic is applied
- without an explicit selector. *)
-let default_goal_selector = ref (Vernacexpr.SelectNth 1)
-let get_default_goal_selector () = !default_goal_selector
-
-let pr_range_selector (i, j) =
- if i = j then Pp.int i
- else Pp.(int i ++ str "-" ++ int j)
-
-let pr_goal_selector = function
- | Vernacexpr.SelectAll -> Pp.str "all"
- | Vernacexpr.SelectNth i -> Pp.int i
- | Vernacexpr.SelectList l ->
- Pp.(str "["
- ++ prlist_with_sep pr_comma pr_range_selector l
- ++ str "]")
- | Vernacexpr.SelectId id -> Names.Id.print id
-
-let parse_goal_selector = function
- | "all" -> Vernacexpr.SelectAll
- | i ->
- let err_msg = "The default selector must be \"all\" or a natural number." in
- begin try
- let i = int_of_string i in
- if i < 0 then CErrors.user_err Pp.(str err_msg);
- Vernacexpr.SelectNth i
- with Failure _ -> CErrors.user_err Pp.(str err_msg)
- end
-
-let _ =
- Goptions.(declare_string_option{optdepr = false;
- optname = "default goal selector" ;
- optkey = ["Default";"Goal";"Selector"] ;
- optread = begin fun () ->
- Pp.string_of_ppcmds
- (pr_goal_selector !default_goal_selector)
- end;
- optwrite = begin fun n ->
- default_goal_selector := parse_goal_selector n
- end
- })
-
+let pr_goal_selector = Goal_select.pr_goal_selector
+let get_default_goal_selector = Goal_select.get_default_goal_selector
diff --git a/proofs/proof_bullet.mli b/proofs/proof_bullet.mli
index ffbaa0fac..a09a7ec1d 100644
--- a/proofs/proof_bullet.mli
+++ b/proofs/proof_bullet.mli
@@ -14,7 +14,10 @@
(* *)
(**********************************************************)
-type t = Vernacexpr.bullet
+type t =
+ | Dash of int
+ | Star of int
+ | Plus of int
(** A [behavior] is the data of a put function which
is called when a bullet prefixes a tactic, a suggest function
@@ -42,12 +45,8 @@ val register_behavior : behavior -> unit
val put : Proof.t -> t -> Proof.t
val suggest : Proof.t -> Pp.t
-(**********************************************************)
-(* *)
-(* Default goal selector *)
-(* *)
-(**********************************************************)
-
-val pr_goal_selector : Vernacexpr.goal_selector -> Pp.t
-val get_default_goal_selector : unit -> Vernacexpr.goal_selector
-
+(** Deprecated *)
+val pr_goal_selector : Goal_select.t -> Pp.t
+[@@ocaml.deprecated "Please use [Goal_select.pr_goal_selector]"]
+val get_default_goal_selector : unit -> Goal_select.t
+[@@ocaml.deprecated "Please use [Goal_select.get_default_goal_selector]"]
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index d6c0e3341..842003bc8 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -83,6 +83,7 @@ type proof_ending =
| Proved of Vernacexpr.opacity_flag *
Misctypes.lident option *
proof_object
+
type proof_terminator = proof_ending -> unit
type closed_proof = proof_object * proof_terminator
@@ -340,7 +341,7 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now
have existential variables in the initial types of goals, we need to
normalise them for the kernel. *)
let subst_evar k =
- Proof.in_proof proof (fun m -> Evd.existential_opt_value m k) in
+ Proof.in_proof proof (fun m -> Evd.existential_opt_value0 m k) in
let nf = Universes.nf_evars_and_universes_opt_subst subst_evar
(UState.subst universes) in
let make_body =
diff --git a/proofs/proofs.mllib b/proofs/proofs.mllib
index 058e839b4..197f71ca9 100644
--- a/proofs/proofs.mllib
+++ b/proofs/proofs.mllib
@@ -5,6 +5,7 @@ Proof_type
Logic
Refine
Proof
+Goal_select
Proof_bullet
Proof_global
Redexpr
diff --git a/proofs/refine.ml b/proofs/refine.ml
index 909556b1e..5a2d82977 100644
--- a/proofs/refine.ml
+++ b/proofs/refine.ml
@@ -15,7 +15,7 @@ open Context.Named.Declaration
module NamedDecl = Context.Named.Declaration
let extract_prefix env info =
- let ctx1 = List.rev (Environ.named_context env) in
+ let ctx1 = List.rev (EConstr.named_context env) in
let ctx2 = List.rev (Evd.evar_context info) in
let rec share l1 l2 accu = match l1, l2 with
| d1 :: l1, d2 :: l2 ->
@@ -29,21 +29,21 @@ let typecheck_evar ev env sigma =
let info = Evd.find sigma ev in
(** Typecheck the hypotheses. *)
let type_hyp (sigma, env) decl =
- let t = EConstr.of_constr (NamedDecl.get_type decl) in
+ let 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 (EConstr.of_constr body) t
+ | LocalDef (_,body,_) -> Typing.e_check env evdref body t
in
- (!evdref, Environ.push_named decl env)
+ (!evdref, EConstr.push_named decl env)
in
let (common, changed) = extract_prefix env info in
- let env = Environ.reset_with_named_context (Environ.val_of_named_context common) env in
+ let env = Environ.reset_with_named_context (EConstr.val_of_named_context common) env in
let (sigma, env) = List.fold_left type_hyp (sigma, env) changed in
(** Typecheck the conclusion *)
let evdref = ref sigma in
- let _ = Typing.e_sort_of env evdref (EConstr.of_constr (Evd.evar_concl info)) in
+ let _ = Typing.e_sort_of env evdref (Evd.evar_concl info) in
!evdref
let typecheck_proof c concl env sigma =
@@ -106,7 +106,6 @@ let generic_refine ~typecheck f gl =
let evs = Evd.map_filter_future_goals (Proofview.Unsafe.advance sigma) evs in
let comb,shelf,given_up,evkmain = Evd.dispatch_future_goals evs in
(** Proceed to the refinement *)
- let c = EConstr.Unsafe.to_constr c in
let sigma = match Proofview.Unsafe.advance sigma self with
| None ->
(** Nothing to do, the goal has been solved by side-effect *)
@@ -124,7 +123,8 @@ let generic_refine ~typecheck f gl =
(** Mark goals *)
let sigma = CList.fold_left Proofview.Unsafe.mark_as_goal sigma comb in
let comb = CList.map (fun x -> Proofview.goal_with_state x state) comb in
- let trace () = Pp.(hov 2 (str"simple refine"++spc()++ Hook.get pr_constrv env sigma c)) in
+ let trace () = Pp.(hov 2 (str"simple refine"++spc()++
+ Hook.get pr_constrv env sigma (EConstr.Unsafe.to_constr c))) in
Proofview.Trace.name_tactic trace (Proofview.tclUNIT v) >>= fun v ->
Proofview.Unsafe.tclSETENV (Environ.reset_context env) <*>
Proofview.Unsafe.tclEVARS sigma <*>
diff --git a/proofs/tacmach.mli b/proofs/tacmach.mli
index 770d0940a..de96f8510 100644
--- a/proofs/tacmach.mli
+++ b/proofs/tacmach.mli
@@ -95,7 +95,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/proofBlockDelimiter.ml b/stm/proofBlockDelimiter.ml
index 23f976120..b8af2bcd5 100644
--- a/stm/proofBlockDelimiter.ml
+++ b/stm/proofBlockDelimiter.ml
@@ -23,8 +23,8 @@ val crawl :
static_block_declaration option
val unit_val : Stm.DynBlockData.t
-val of_bullet_val : Vernacexpr.bullet -> Stm.DynBlockData.t
-val to_bullet_val : Stm.DynBlockData.t -> Vernacexpr.bullet
+val of_bullet_val : Proof_bullet.t -> Stm.DynBlockData.t
+val to_bullet_val : Stm.DynBlockData.t -> Proof_bullet.t
val of_vernac_control_val : Vernacexpr.vernac_control -> Stm.DynBlockData.t
val to_vernac_control_val : Stm.DynBlockData.t -> Vernacexpr.vernac_control
@@ -41,7 +41,7 @@ let simple_goal sigma g gs =
let open Evd in
let open Evarutil in
let evi = Evd.find sigma g in
- Set.is_empty (evars_of_term evi.evar_concl) &&
+ Set.is_empty (evars_of_term (EConstr.Unsafe.to_constr evi.evar_concl)) &&
Set.is_empty (evars_of_filtered_evar_info (nf_evar_info sigma evi)) &&
not (List.exists (Proofview.depends_on sigma g) gs)
diff --git a/stm/proofBlockDelimiter.mli b/stm/proofBlockDelimiter.mli
index 9784de114..eacd3687a 100644
--- a/stm/proofBlockDelimiter.mli
+++ b/stm/proofBlockDelimiter.mli
@@ -38,6 +38,6 @@ val crawl :
val unit_val : Stm.DynBlockData.t
(* Bullets *)
-val of_bullet_val : Vernacexpr.bullet -> Stm.DynBlockData.t
-val to_bullet_val : Stm.DynBlockData.t -> Vernacexpr.bullet
+val of_bullet_val : Proof_bullet.t -> Stm.DynBlockData.t
+val to_bullet_val : Stm.DynBlockData.t -> Proof_bullet.t
diff --git a/stm/stm.ml b/stm/stm.ml
index ba0a2017a..9ea6a305e 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -92,11 +92,11 @@ let execution_error ?loc state_id msg =
module Hooks = struct
let state_computed, state_computed_hook = Hook.make
- ~default:(fun state_id ~in_cache ->
+ ~default:(fun ~doc:_ state_id ~in_cache ->
feedback ~id:state_id Processed) ()
let state_ready, state_ready_hook = Hook.make
- ~default:(fun state_id -> ()) ()
+ ~default:(fun ~doc:_ state_id -> ()) ()
let forward_feedback, forward_feedback_hook =
let m = Mutex.create () in
@@ -106,7 +106,7 @@ let forward_feedback, forward_feedback_hook =
with e -> Mutex.unlock m; raise e) ()
let unreachable_state, unreachable_state_hook = Hook.make
- ~default:(fun _ _ -> ()) ()
+ ~default:(fun ~doc:_ _ _ -> ()) ()
include Hook
@@ -578,7 +578,7 @@ end = struct (* {{{ *)
| None -> raise Vcs_aux.Expired
let set_state id s =
(get_info id).state <- s;
- if async_proofs_is_master !cur_opt then Hooks.(call state_ready id)
+ if async_proofs_is_master !cur_opt then Hooks.(call state_ready ~doc:dummy_doc (* XXX should be taken in input *) id)
let get_state id = (get_info id).state
let reached id =
let info = get_info id in
@@ -770,6 +770,7 @@ module State : sig
Warning: an optimization in installed_cached requires that state
modifying functions are always executed using this wrapper. *)
val define :
+ doc:doc ->
?safe_id:Stateid.t ->
?redefine:bool -> ?cache:Summary.marshallable ->
?feedback_processed:bool -> (unit -> unit) -> Stateid.t -> unit
@@ -919,7 +920,7 @@ end = struct (* {{{ *)
let e2 = Summary.project_from_summary s2 Global.global_env_summary_tag in
e1 == e2
- let define ?safe_id ?(redefine=false) ?(cache=`No) ?(feedback_processed=true)
+ let define ~doc ?safe_id ?(redefine=false) ?(cache=`No) ?(feedback_processed=true)
f id
=
feedback ~id:id (ProcessingIn !Flags.async_proofs_worker_id);
@@ -938,7 +939,7 @@ end = struct (* {{{ *)
stm_prerr_endline (fun () -> "setting cur id to "^str_id);
cur_id := id;
if feedback_processed then
- Hooks.(call state_computed id ~in_cache:false);
+ Hooks.(call state_computed ~doc id ~in_cache:false);
VCS.reached id;
if Proof_global.there_are_pending_proofs () then
VCS.goals id (Proof_global.get_open_goals ())
@@ -954,7 +955,7 @@ end = struct (* {{{ *)
| Some _, None -> (e, info)
| Some (_,at), Some id -> (e, Stateid.add info ~valid:id at) in
if cache = `Yes || cache = `Shallow then freeze_invalid id ie;
- Hooks.(call unreachable_state id ie);
+ Hooks.(call unreachable_state ~doc id ie);
Exninfo.iraise ie
let init_state = ref None
@@ -1352,6 +1353,7 @@ module rec ProofTask : sig
and type request := request
val build_proof_here :
+ doc:doc ->
?loc:Loc.t ->
drop_pt:bool ->
Stateid.t * Stateid.t -> Stateid.t ->
@@ -1466,11 +1468,12 @@ end = struct (* {{{ *)
execution_error start (Pp.strbrk s);
feedback (InProgress ~-1)
- let build_proof_here ?loc ~drop_pt (id,valid) eop =
+ let build_proof_here ~doc ?loc ~drop_pt (id,valid) eop =
Future.create (State.exn_on id ~valid) (fun () ->
let wall_clock1 = Unix.gettimeofday () in
- if VCS.is_interactive () = `No then Reach.known_state ~cache:`No eop
- else Reach.known_state ~cache:`Shallow eop;
+ if VCS.is_interactive () = `No
+ then Reach.known_state ~doc ~cache:`No eop
+ else Reach.known_state ~doc ~cache:`Shallow eop;
let wall_clock2 = Unix.gettimeofday () in
Aux_file.record_in_aux_at ?loc "proof_build_time"
(Printf.sprintf "%.3f" (wall_clock2 -. wall_clock1));
@@ -1484,7 +1487,7 @@ end = struct (* {{{ *)
VCS.print ();
let proof, future_proof, time =
let wall_clock = Unix.gettimeofday () in
- let fp = build_proof_here ?loc ~drop_pt:drop exn_info stop in
+ let fp = build_proof_here ~doc:dummy_doc (* XXX should be document *) ?loc ~drop_pt:drop exn_info stop in
let proof = Future.force fp in
proof, fp, Unix.gettimeofday () -. wall_clock in
(* We typecheck the proof with the kernel (in the worker) to spot
@@ -1577,7 +1580,7 @@ end = struct (* {{{ *)
msg_warning Pp.(strbrk("Marshalling error: "^s^". "^
"The system state could not be sent to the worker process. "^
"Falling back to local, lazy, evaluation."));
- t_assign(`Comp(build_proof_here ?loc:t_loc ~drop_pt t_exn_info t_stop));
+ t_assign(`Comp(build_proof_here ~doc:dummy_doc (* XXX should be stored in a closure, it is the same doc that was used to generate the task *) ?loc:t_loc ~drop_pt t_exn_info t_stop));
feedback (InProgress ~-1)
end (* }}} *)
@@ -1587,6 +1590,7 @@ and Slaves : sig
(* (eventually) remote calls *)
val build_proof :
+ doc:doc ->
?loc:Loc.t -> drop_pt:bool ->
exn_info:(Stateid.t * Stateid.t) -> block_start:Stateid.t -> block_stop:Stateid.t ->
name:string -> future_proof * AsyncTaskQueue.cancel_switch
@@ -1634,7 +1638,7 @@ end = struct (* {{{ *)
with VCS.Expired -> cur in
aux stop in
try
- Reach.known_state ~cache:`No stop;
+ Reach.known_state ~doc:dummy_doc (* XXX should be document *) ~cache:`No stop;
if drop then
let _proof = Proof_global.return_proof ~allow_partial:true () in
`OK_ADMITTED
@@ -1647,7 +1651,7 @@ end = struct (* {{{ *)
Proof_global.close_proof ~keep_body_ucst_separate:true (fun x -> x) in
(* We jump at the beginning since the kernel handles side effects by also
* looking at the ones that happen to be present in the current env *)
- Reach.known_state ~cache:`No start;
+ Reach.known_state ~doc:dummy_doc (* XXX should be document *) ~cache:`No start;
(* STATE SPEC:
* - start: First non-expired state! [This looks very fishy]
* - end : start + qed
@@ -1754,7 +1758,7 @@ end = struct (* {{{ *)
BuildProof { t_states = s2 } -> overlap_rel s1 s2
| _ -> 0)
- let build_proof ?loc ~drop_pt ~exn_info ~block_start ~block_stop ~name:pname =
+ let build_proof ~doc ?loc ~drop_pt ~exn_info ~block_start ~block_stop ~name:pname =
let id, valid as t_exn_info = exn_info in
let cancel_switch = ref false in
if TaskQueue.n_workers (Option.get !queue) = 0 then
@@ -1769,7 +1773,7 @@ end = struct (* {{{ *)
TaskQueue.enqueue_task (Option.get !queue) task ~cancel_switch;
f, cancel_switch
end else
- ProofTask.build_proof_here ?loc ~drop_pt t_exn_info block_stop, cancel_switch
+ ProofTask.build_proof_here ~doc ?loc ~drop_pt t_exn_info block_stop, cancel_switch
else
let f, t_assign = Future.create_delegate ~name:pname (State.exn_on id ~valid) in
let t_uuid = Future.uuid f in
@@ -1892,11 +1896,11 @@ end = struct (* {{{ *)
let perform { r_state = id; r_state_fb; r_document = vcs; r_ast; r_goal } =
Option.iter VCS.restore vcs;
try
- Reach.known_state ~cache:`No id;
+ Reach.known_state ~doc:dummy_doc (* XXX should be vcs *) ~cache:`No id;
stm_purify (fun () ->
let _,_,_,_,sigma0 = Proof.proof (Proof_global.give_me_the_proof ()) in
let g = Evd.find sigma0 r_goal in
- let is_ground c = Evarutil.is_ground_term sigma0 (EConstr.of_constr c) in
+ let is_ground c = Evarutil.is_ground_term sigma0 c in
if not (
is_ground Evd.(evar_concl g) &&
List.for_all (Context.Named.Declaration.for_all is_ground)
@@ -1919,7 +1923,6 @@ end = struct (* {{{ *)
match Evd.(evar_body (find sigma r_goal)) with
| Evd.Evar_empty -> RespNoProgress
| Evd.Evar_defined t ->
- let t = EConstr.of_constr t in
let t = Evarutil.nf_evar sigma t in
if Evarutil.is_ground_term sigma t then
let t = EConstr.Unsafe.to_constr t in
@@ -2048,7 +2051,7 @@ end = struct (* {{{ *)
let perform { r_where; r_doc; r_what; r_for } =
VCS.restore r_doc;
VCS.print ();
- Reach.known_state ~cache:`No r_where;
+ Reach.known_state ~doc:dummy_doc (* XXX should be r_doc *) ~cache:`No r_where;
(* STATE *)
let st = Vernacstate.freeze_interp_state `No in
try
@@ -2093,7 +2096,8 @@ end (* }}} *)
and Reach : sig
val known_state :
- ?redefine_qed:bool -> cache:Summary.marshallable -> Stateid.t -> unit
+ doc:doc -> ?redefine_qed:bool -> cache:Summary.marshallable ->
+ Stateid.t -> unit
end = struct (* {{{ *)
@@ -2251,7 +2255,7 @@ let log_processing_sync id name reason = log_string Printf.(sprintf
let wall_clock_last_fork = ref 0.0
-let known_state ?(redefine_qed=false) ~cache id =
+let known_state ~doc ?(redefine_qed=false) ~cache id =
let error_absorbing_tactic id blockname exn =
(* We keep the static/dynamic part of block detection separate, since
@@ -2284,7 +2288,7 @@ let known_state ?(redefine_qed=false) ~cache id =
Proof_global.unfreeze proof;
Proof_global.with_current_proof (fun _ p ->
feedback ~id:id Feedback.AddedAxiom;
- fst (Pfedit.solve Vernacexpr.SelectAll None tac p), ());
+ fst (Pfedit.solve Goal_select.SelectAll None tac p), ());
(* STATE SPEC:
* - start: Modifies the input state adding a proof.
* - end : maybe after recovery command.
@@ -2346,7 +2350,7 @@ let known_state ?(redefine_qed=false) ~cache id =
and reach ?safe_id ?(redefine_qed=false) ?(cache=cache) id =
stm_prerr_endline (fun () -> "reaching: " ^ Stateid.to_string id);
if not redefine_qed && State.is_cached ~cache id then begin
- Hooks.(call state_computed id ~in_cache:true);
+ Hooks.(call state_computed ~doc id ~in_cache:true);
stm_prerr_endline (fun () -> "reached (cache)");
State.install_cached id
end else
@@ -2427,7 +2431,7 @@ let known_state ?(redefine_qed=false) ~cache id =
^" proof. Reprocess the command declaring "
^"the proof's statement to avoid that."));
let fp, cancel =
- Slaves.build_proof
+ Slaves.build_proof ~doc
?loc ~drop_pt ~exn_info ~block_start ~block_stop ~name in
Future.replace ofp fp;
qed.fproof <- Some (fp, cancel);
@@ -2439,10 +2443,10 @@ let known_state ?(redefine_qed=false) ~cache id =
reach ~cache:`Shallow block_start;
let fp, cancel =
if delegate then
- Slaves.build_proof
+ Slaves.build_proof ~doc
?loc ~drop_pt ~exn_info ~block_start ~block_stop ~name
else
- ProofTask.build_proof_here ?loc
+ ProofTask.build_proof_here ~doc ?loc
~drop_pt exn_info block_stop, ref false
in
qed.fproof <- Some (fp, cancel);
@@ -2512,7 +2516,7 @@ let known_state ?(redefine_qed=false) ~cache id =
let cache_step =
if !cur_opt.async_proofs_cache = Some Force then `Yes
else cache_step in
- State.define ?safe_id
+ State.define ~doc ?safe_id
~cache:cache_step ~redefine:redefine_qed ~feedback_processed step id;
stm_prerr_endline (fun () -> "reached: "^ Stateid.to_string id) in
reach ~redefine_qed id
@@ -2601,7 +2605,7 @@ let new_doc { doc_type ; iload_path; require_libs; stm_options } =
load_objs require_libs;
(* We record the state at this point! *)
- State.define ~cache:`Yes ~redefine:true (fun () -> ()) Stateid.initial;
+ State.define ~doc ~cache:`Yes ~redefine:true (fun () -> ()) Stateid.initial;
Backtrack.record ();
Slaves.init ();
if async_proofs_is_master !cur_opt then begin
@@ -2622,7 +2626,7 @@ let new_doc { doc_type ; iload_path; require_libs; stm_options } =
let observe ~doc id =
let vcs = VCS.backup () in
try
- Reach.known_state ~cache:(VCS.is_interactive ()) id;
+ Reach.known_state ~doc ~cache:(VCS.is_interactive ()) id;
VCS.print ();
doc
with e ->
@@ -2715,7 +2719,7 @@ let merge_proof_branch ~valid ?id qast keep brname =
VCS.rewrite_merge qed_id ~ours:(Qed (qed ofp)) ~at:master_id brname;
VCS.delete_branch brname;
VCS.gc ();
- let _st = Reach.known_state ~redefine_qed:true ~cache:`No qed_id in
+ let _st : unit = Reach.known_state ~doc:dummy_doc (* XXX should be taken in input *) ~redefine_qed:true ~cache:`No qed_id in
VCS.checkout VCS.Branch.master;
`Unfocus qed_id
| { VCS.kind = `Master } ->
@@ -2767,7 +2771,7 @@ 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 process_transaction ?(newtip=Stateid.fresh ())
+let process_transaction ~doc ?(newtip=Stateid.fresh ())
({ verbose; loc; expr } as x) c =
stm_pperr_endline (fun () -> str "{{{ processing: " ++ pr_ast x);
let vcs = VCS.backup () in
@@ -2872,11 +2876,11 @@ let process_transaction ?(newtip=Stateid.fresh ())
let in_proof = not (VCS.Branch.equal head VCS.Branch.master) in
let id = VCS.new_node ~id:newtip () in
let head_id = VCS.get_branch_pos head in
- let _st = Reach.known_state ~cache:`Yes head_id in (* ensure it is ok *)
+ let _st : unit = Reach.known_state ~doc ~cache:`Yes head_id in (* ensure it is ok *)
let step () =
VCS.checkout VCS.Branch.master;
let mid = VCS.get_branch_pos VCS.Branch.master in
- let _st' = Reach.known_state ~cache:(VCS.is_interactive ()) mid in
+ let _st' : unit = Reach.known_state ~doc ~cache:(VCS.is_interactive ()) mid in
let st = Vernacstate.freeze_interp_state `No in
ignore(stm_vernac_interp id st x);
(* Vernac x may or may not start a proof *)
@@ -2902,7 +2906,7 @@ let process_transaction ?(newtip=Stateid.fresh ())
end;
VCS.checkout_shallowest_proof_branch ();
end in
- State.define ~safe_id:head_id ~cache:`Yes step id;
+ State.define ~doc ~safe_id:head_id ~cache:`Yes step id;
Backtrack.record (); `Ok
| VtUnknown, VtLater ->
@@ -3013,11 +3017,10 @@ let add ~doc ~ontop ?newtip verb { CAst.loc; v=ast } =
str ") than the tip: " ++ str (Stateid.to_string cur_tip) ++ str "." ++ fnl () ++
str "This is not supported yet, sorry.");
let indentation, strlen = compute_indentation ?loc ontop in
- CWarnings.set_current_loc loc;
(* XXX: Classifiy vernac should be moved inside process transaction *)
let clas = Vernac_classifier.classify_vernac ast in
let aast = { verbose = verb; indentation; strlen; loc; expr = ast } in
- match process_transaction ?newtip aast clas with
+ match process_transaction ~doc ?newtip aast clas with
| `Ok -> doc, VCS.cur_tip (), `NewTip
| `Unfocus qed_id -> doc, qed_id, `Unfocus (VCS.cur_tip ())
@@ -3032,12 +3035,11 @@ type focus = {
let query ~doc ~at ~route s =
stm_purify (fun s ->
if Stateid.equal at Stateid.dummy then ignore(finish ~doc:dummy_doc)
- else Reach.known_state ~cache:`Yes at;
+ else Reach.known_state ~doc ~cache:`Yes at;
try
while true do
let { CAst.loc; v=ast } = parse_sentence ~doc at s in
let indentation, strlen = compute_indentation ?loc at in
- CWarnings.set_current_loc loc;
let st = State.get_cached at in
let aast = { verbose = true; indentation; strlen; loc; expr = ast } in
ignore(stm_vernac_interp ~route at st aast)
@@ -3095,7 +3097,7 @@ let edit_at ~doc id =
VCS.edit_branch (`Edit (mode, qed_id, master_id, keep, old_branch));
VCS.delete_boxes_of id;
cancel_switch := true;
- Reach.known_state ~cache:(VCS.is_interactive ()) id;
+ Reach.known_state ~doc ~cache:(VCS.is_interactive ()) id;
VCS.checkout_shallowest_proof_branch ();
`Focus { stop = qed_id; start = master_id; tip } in
let no_edit = function
@@ -3118,7 +3120,7 @@ let edit_at ~doc id =
VCS.gc ();
VCS.print ();
if not !cur_opt.async_proofs_full then
- Reach.known_state ~cache:(VCS.is_interactive ()) id;
+ Reach.known_state ~doc ~cache:(VCS.is_interactive ()) id;
VCS.checkout_shallowest_proof_branch ();
`NewTip in
try
@@ -3147,7 +3149,7 @@ let edit_at ~doc id =
| true, None, _ ->
if on_cur_branch id then begin
VCS.reset_branch (VCS.current_branch ()) id;
- Reach.known_state ~cache:(VCS.is_interactive ()) id;
+ Reach.known_state ~doc ~cache:(VCS.is_interactive ()) id;
VCS.checkout_shallowest_proof_branch ();
`NewTip
end else if is_ancestor_of_cur_branch id then begin
@@ -3210,4 +3212,9 @@ let forward_feedback_hook = Hooks.forward_feedback_hook
let unreachable_state_hook = Hooks.unreachable_state_hook
let () = Hook.set Obligations.stm_get_fix_exn (fun () -> !State.fix_exn_ref)
+type document = VCS.vcs
+let backup () = VCS.backup ()
+let restore d = VCS.restore d
+
+
(* vim:set foldmethod=marker: *)
diff --git a/stm/stm.mli b/stm/stm.mli
index 7a720aa72..aed7274d0 100644
--- a/stm/stm.mli
+++ b/stm/stm.mli
@@ -263,11 +263,12 @@ val register_proof_block_delimiter :
* the alternative toploop for the worker can be selected by changing
* the name of the Task(s) above) *)
-val state_computed_hook : (Stateid.t -> in_cache:bool -> unit) Hook.t
-val unreachable_state_hook : (Stateid.t -> Exninfo.iexn -> unit) Hook.t
+val state_computed_hook : (doc:doc -> Stateid.t -> in_cache:bool -> unit) Hook.t
+val unreachable_state_hook :
+ (doc:doc -> Stateid.t -> Exninfo.iexn -> unit) Hook.t
(* ready means that master has it at hand *)
-val state_ready_hook : (Stateid.t -> unit) Hook.t
+val state_ready_hook : (doc:doc -> Stateid.t -> unit) Hook.t
(* Messages from the workers to the master *)
val forward_feedback_hook : (Feedback.feedback -> unit) Hook.t
@@ -283,3 +284,7 @@ val get_all_proof_names : doc:doc -> Id.t list
(** Enable STM debugging *)
val stm_debug : bool ref
+
+type document
+val backup : unit -> document
+val restore : document -> unit
diff --git a/stm/workerLoop.ml b/stm/workerLoop.ml
index 5445925b1..5130b019a 100644
--- a/stm/workerLoop.ml
+++ b/stm/workerLoop.ml
@@ -17,9 +17,9 @@ let rec parse = function
| x :: rest -> x :: parse rest
| [] -> []
-let loop init _coq_args extra_args =
+let loop init coq_args extra_args =
let args = parse extra_args in
Flags.quiet := true;
init ();
CoqworkmgrApi.init !async_proofs_worker_priority;
- args
+ coq_args, args
diff --git a/stm/workerLoop.mli b/stm/workerLoop.mli
index f02edb9bb..37ec6dacc 100644
--- a/stm/workerLoop.mli
+++ b/stm/workerLoop.mli
@@ -11,4 +11,6 @@
(* Default priority *)
val async_proofs_worker_priority : CoqworkmgrApi.priority ref
-val loop : (unit -> unit) -> Coqargs.coq_cmdopts -> string list -> string list
+val loop :
+ (unit -> unit) -> Coqargs.coq_cmdopts -> string list ->
+ Coqargs.coq_cmdopts * string list
diff --git a/tactics/auto.ml b/tactics/auto.ml
index 0c0d9bcfc..15a24fb37 100644
--- a/tactics/auto.ml
+++ b/tactics/auto.ml
@@ -8,8 +8,6 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-module CVars = Vars
-
open Pp
open Util
open Names
@@ -82,14 +80,13 @@ let connect_hint_clenv poly (c, _, ctx) clenv gl =
if poly then
(** Refresh the instance of the hint *)
let (subst, ctx) = Universes.fresh_universe_context_set_instance ctx in
- let map c = CVars.subst_univs_level_constr subst c in
let emap c = Vars.subst_univs_level_constr subst c in
let evd = Evd.merge_context_set Evd.univ_flexible evd ctx in
(** Only metas are mentioning the old universes. *)
let clenv = {
templval = Evd.map_fl emap clenv.templval;
templtyp = Evd.map_fl emap clenv.templtyp;
- evd = Evd.map_metas map evd;
+ evd = Evd.map_metas emap evd;
env = Proofview.Goal.env gl;
} in
clenv, emap c
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 0260460e6..bbcf8def6 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -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
@@ -1030,8 +1030,8 @@ module Intpart = Unionfind.Make(Evar.Set)(Evar.Map)
let deps_of_constraints cstrs evm p =
List.iter (fun (_, _, x, y) ->
- let evx = Evarutil.undefined_evars_of_term evm (EConstr.of_constr x) in
- let evy = Evarutil.undefined_evars_of_term evm (EConstr.of_constr y) in
+ let evx = Evarutil.undefined_evars_of_term evm x in
+ let evy = Evarutil.undefined_evars_of_term evm y in
Intpart.union_set (Evar.Set.union evx evy) p)
cstrs
@@ -1076,7 +1076,7 @@ let error_unresolvable env comp evd =
| Some s -> Evar.Set.mem ev s
in
let fold ev evi (found, accu) =
- let ev_class = class_of_constr evd (EConstr.of_constr evi.evar_concl) in
+ let ev_class = class_of_constr evd evi.evar_concl in
if not (Option.is_empty ev_class) && is_part ev then
(* focus on one instance if only one was searched for *)
if not found then (true, Some ev)
diff --git a/tactics/elimschemes.ml b/tactics/elimschemes.ml
index 6bd4866c6..70f73df5c 100644
--- a/tactics/elimschemes.ml
+++ b/tactics/elimschemes.ml
@@ -46,8 +46,8 @@ let optimize_non_type_induction_scheme kind dep sort _ ind =
mib.mind_nparams in
let sigma, sort = Evd.fresh_sort_in_family env sigma sort in
let sigma, t', c' = weaken_sort_scheme env sigma false sort npars c t in
- let sigma, nf = Evarutil.nf_evars_and_universes sigma in
- (nf c', Evd.evar_universe_context sigma), eff
+ let sigma = Evd.minimize_universes sigma in
+ (Evarutil.nf_evars_universes sigma c', Evd.evar_universe_context sigma), eff
else
let sigma, pind = Evd.fresh_inductive_instance env sigma ind in
let sigma, c = build_induction_scheme env sigma pind dep sort in
diff --git a/tactics/equality.ml b/tactics/equality.ml
index 98f627f21..b6bbd0be4 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -1108,8 +1108,6 @@ let make_tuple env sigma (rterm,rty) lind =
let p = mkLambda (na, a, rty) in
let sigma, exist_term = Evd.fresh_global env sigma sigdata.intro in
let sigma, sig_term = Evd.fresh_global env sigma sigdata.typ in
- let exist_term = EConstr.of_constr exist_term in
- let sig_term = EConstr.of_constr sig_term in
sigma,
(applist(exist_term,[a;p;(mkRel lind);rterm]),
applist(sig_term,[a;p]))
@@ -1203,7 +1201,6 @@ let sig_clausal_form env sigma sort_of_ty siglen ty dflt =
let w_type = unsafe_type_of env !evdref w in
if Evarconv.e_cumul env evdref w_type a then
let exist_term = Evarutil.evd_comb1 (Evd.fresh_global env) evdref sigdata.intro in
- let exist_term = EConstr.of_constr exist_term in
applist(exist_term,[a;p_i_minus_1;w;tuple_tail])
else
user_err Pp.(str "Cannot solve a unification problem.")
@@ -1372,7 +1369,6 @@ let inject_at_positions env sigma l2r (eq,_,(t,t1,t2)) eq_clause posns tac =
let sigma, (injbody,resty) = build_injector e_env !evdref t1' (mkVar e) cpath in
let injfun = mkNamedLambda e t injbody in
let sigma,congr = Evd.fresh_global env sigma eq.congr in
- let congr = EConstr.of_constr congr in
let pf = applist(congr,[t;resty;injfun;t1;t2]) in
let sigma, pf_typ = Typing.type_of env sigma pf in
let inj_clause = apply_on_clause (pf,pf_typ) eq_clause in
@@ -1761,8 +1757,17 @@ type subst_tactic_flags = {
let default_subst_tactic_flags =
{ only_leibniz = false; rewrite_dependent_proof = true }
+let warn_deprecated_simple_subst =
+ CWarnings.create ~name:"deprecated-simple-subst" ~category:"deprecated"
+ (fun () -> strbrk"\"simple subst\" is deprecated")
+
let subst_all ?(flags=default_subst_tactic_flags) () =
+ let () =
+ if flags.only_leibniz || not flags.rewrite_dependent_proof then
+ warn_deprecated_simple_subst ()
+ in
+
if !regular_subst_tactic then
(* First step: find hypotheses to treat in linear time *)
diff --git a/tactics/hints.ml b/tactics/hints.ml
index a285d6b93..d02bab186 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 }
@@ -792,7 +792,7 @@ let make_exact_entry env sigma info poly ?(name=PathAny) (c, cty, ctx) =
match EConstr.kind sigma cty with
| Prod _ -> failwith "make_exact_entry"
| _ ->
- let pat = Patternops.pattern_of_constr env sigma (EConstr.to_constr sigma cty) in
+ let pat = Patternops.pattern_of_constr env sigma (EConstr.to_constr ~abort_on_undefined_evars:false sigma cty) in
let hd =
try head_pattern_bound pat
with BoundPattern -> failwith "make_exact_entry"
@@ -814,7 +814,7 @@ let make_apply_entry env sigma (eapply,hnf,verbose) info poly ?(name=PathAny) (c
let sigma' = Evd.merge_context_set univ_flexible sigma ctx in
let ce = mk_clenv_from_env env sigma' None (c,cty) in
let c' = clenv_type (* ~reduce:false *) ce in
- let pat = Patternops.pattern_of_constr env ce.evd (EConstr.to_constr sigma c') in
+ let pat = Patternops.pattern_of_constr env ce.evd (EConstr.to_constr ~abort_on_undefined_evars:false sigma c') in
let hd =
try head_pattern_bound pat
with BoundPattern -> failwith "make_apply_entry" in
@@ -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/inv.ml b/tactics/inv.ml
index d76c9a697..412954989 100644
--- a/tactics/inv.ml
+++ b/tactics/inv.ml
@@ -124,12 +124,10 @@ let make_inv_predicate env evd indf realargs id status concl =
in
let eq_term = eqdata.Coqlib.eq in
let eq = Evarutil.evd_comb1 (Evd.fresh_global env) evd eq_term in
- let eq = EConstr.of_constr eq in
let eqn = applist (eq,[eqnty;lhs;rhs]) in
let eqns = (Anonymous, lift n eqn) :: eqns in
let refl_term = eqdata.Coqlib.refl in
let refl_term = Evarutil.evd_comb1 (Evd.fresh_global env) evd refl_term in
- let refl_term = EConstr.of_constr refl_term in
let refl = mkApp (refl_term, [|eqnty; rhs|]) in
let _ = Evarutil.evd_comb1 (Typing.type_of env) evd refl in
let args = refl :: args in
diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml
index a97ae8f65..6c7db26c7 100644
--- a/tactics/tacticals.ml
+++ b/tactics/tacticals.ml
@@ -263,7 +263,7 @@ let pf_with_evars glsev k gls =
tclTHEN (Refiner.tclEVARS evd) (k a) gls
let pf_constr_of_global gr k =
- pf_with_evars (fun gls -> on_snd EConstr.of_constr (pf_apply Evd.fresh_global gls gr)) k
+ pf_with_evars (fun gls -> pf_apply Evd.fresh_global gls gr) k
(** Tacticals of Ltac defined directly in term of Proofview *)
module New = struct
@@ -492,11 +492,13 @@ module New = struct
Proofview.tclINDEPENDENT (Proofview.tclPROGRESS t)
(* Select a subset of the goals *)
- let tclSELECT = function
- | Vernacexpr.SelectNth i -> Proofview.tclFOCUS i i
- | Vernacexpr.SelectList l -> Proofview.tclFOCUSLIST l
- | Vernacexpr.SelectId id -> Proofview.tclFOCUSID id
- | Vernacexpr.SelectAll -> fun tac -> tac
+ let tclSELECT = let open Goal_select in function
+ | SelectNth i -> Proofview.tclFOCUS i i
+ | SelectList l -> Proofview.tclFOCUSLIST l
+ | SelectId id -> Proofview.tclFOCUSID id
+ | SelectAll -> anomaly ~label:"tclSELECT" Pp.(str "SelectAll not allowed here")
+ | SelectAlreadyFocused ->
+ anomaly ~label:"tclSELECT" Pp.(str "SelectAlreadyFocused not allowed here")
(* Check that holes in arguments have been resolved *)
@@ -506,7 +508,7 @@ module New = struct
let evi = Evd.find sigma evk in
match Evd.evar_body evi with
| Evd.Evar_empty -> Some (evk,evi)
- | Evd.Evar_defined c -> match Constr.kind c with
+ | Evd.Evar_defined c -> match Constr.kind (EConstr.Unsafe.to_constr c) with
| Term.Evar (evk,l) -> is_undefined_up_to_restriction sigma evk
| _ ->
(* We make the assumption that there is no way to refine an
@@ -709,7 +711,7 @@ module New = struct
let gl_make_elim ind = begin fun gl ->
let gr = Indrec.lookup_eliminator (fst ind) (elimination_sort_of_goal gl) in
let (sigma, c) = pf_apply Evd.fresh_global gl gr in
- (sigma, EConstr.of_constr c)
+ (sigma, c)
end
let gl_make_case_dep (ind, u) = begin fun gl ->
@@ -769,7 +771,6 @@ module New = struct
Proofview.tclEVARMAP >>= fun sigma ->
Proofview.tclENV >>= fun env ->
let (sigma, c) = Evd.fresh_global env sigma ref in
- let c = EConstr.of_constr c in
Proofview.Unsafe.tclEVARS sigma <*> Proofview.tclUNIT c
end
diff --git a/tactics/tacticals.mli b/tactics/tacticals.mli
index 340d8fbf3..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 *)
@@ -223,7 +223,7 @@ module New : sig
val tclCOMPLETE : 'a tactic -> 'a tactic
val tclSOLVE : unit tactic list -> unit tactic
val tclPROGRESS : unit tactic -> unit tactic
- val tclSELECT : Vernacexpr.goal_selector -> 'a tactic -> 'a tactic
+ val tclSELECT : Goal_select.t -> 'a tactic -> 'a tactic
val tclWITHHOLES : bool -> 'a tactic -> Evd.evar_map -> 'a tactic
val tclDELAYEDWITHHOLES : bool -> 'a delayed_open -> ('a -> unit tactic) -> unit tactic
@@ -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 d0ec3358a..ee76ad077 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -198,32 +198,40 @@ end
let convert x y = convert_gen Reduction.CONV x y
let convert_leq x y = convert_gen Reduction.CUMUL x y
-let clear_dependency_msg env sigma id = function
+let clear_in_global_msg = function
+ | None -> mt ()
+ | Some ref -> str " implicitly in " ++ Printer.pr_global ref
+
+let clear_dependency_msg env sigma id err inglobal =
+ let pp = clear_in_global_msg inglobal in
+ match err with
| Evarutil.OccurHypInSimpleClause None ->
- Id.print id ++ str " is used in conclusion."
+ Id.print id ++ str " is used" ++ pp ++ str " in conclusion."
| Evarutil.OccurHypInSimpleClause (Some id') ->
- Id.print id ++ strbrk " is used in hypothesis " ++ Id.print id' ++ str"."
+ Id.print id ++ strbrk " is used" ++ pp ++ str " in hypothesis " ++ Id.print id' ++ str"."
| Evarutil.EvarTypingBreak ev ->
str "Cannot remove " ++ Id.print id ++
strbrk " without breaking the typing of " ++
Printer.pr_existential env sigma ev ++ str"."
-let error_clear_dependency env sigma id err =
- user_err (clear_dependency_msg env sigma id err)
+let error_clear_dependency env sigma id err inglobal =
+ user_err (clear_dependency_msg env sigma id err inglobal)
-let replacing_dependency_msg env sigma id = function
+let replacing_dependency_msg env sigma id err inglobal =
+ let pp = clear_in_global_msg inglobal in
+ match err with
| Evarutil.OccurHypInSimpleClause None ->
- str "Cannot change " ++ Id.print id ++ str ", it is used in conclusion."
+ str "Cannot change " ++ Id.print id ++ str ", it is used" ++ pp ++ str " in conclusion."
| Evarutil.OccurHypInSimpleClause (Some id') ->
str "Cannot change " ++ Id.print id ++
- strbrk ", it is used in hypothesis " ++ Id.print id' ++ str"."
+ strbrk ", it is used" ++ pp ++ str " in hypothesis " ++ Id.print id' ++ str"."
| Evarutil.EvarTypingBreak ev ->
str "Cannot change " ++ Id.print id ++
strbrk " without breaking the typing of " ++
Printer.pr_existential env sigma ev ++ str"."
-let error_replacing_dependency env sigma id err =
- user_err (replacing_dependency_msg env sigma id err)
+let error_replacing_dependency env sigma id err inglobal =
+ user_err (replacing_dependency_msg env sigma id err inglobal)
(* This tactic enables the user to remove hypotheses from the signature.
* Some care is taken to prevent him from removing variables that are
@@ -242,7 +250,7 @@ let clear_gen fail = function
let evdref = ref sigma in
let (hyps, concl) =
try clear_hyps_in_evi env evdref (named_context_val env) concl ids
- with Evarutil.ClearDependencyError (id,err) -> fail env sigma id err
+ 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)
@@ -426,8 +434,8 @@ let clear_hyps2 env sigma ids sign t cl =
let evdref = ref (Evd.clear_metas sigma) in
let (hyps,t,cl) = Evarutil.clear_hyps2_in_evi env evdref sign t cl ids in
(hyps, t, cl, !evdref)
- with Evarutil.ClearDependencyError (id,err) ->
- error_replacing_dependency env sigma id err
+ with Evarutil.ClearDependencyError (id,err,inglobal) ->
+ error_replacing_dependency env sigma id err inglobal
let internal_cut_gen ?(check=true) dir replace id t =
Proofview.Goal.enter begin fun gl ->
@@ -557,8 +565,13 @@ let mutual_fix f n rest j = Proofview.Goal.enter begin fun gl ->
end
end
+let warning_nameless_fix =
+ CWarnings.create ~name:"nameless-fix" ~category:"deprecated" Pp.(fun () ->
+ str "fix/cofix without a name are deprecated, please use the named version.")
+
let fix ido n = match ido with
| None ->
+ warning_nameless_fix ();
Proofview.Goal.enter begin fun gl ->
let name = Proof_global.get_current_proof_name () in
let id = new_fresh_id Id.Set.empty name gl in
@@ -610,6 +623,7 @@ end
let cofix ido = match ido with
| None ->
+ warning_nameless_fix ();
Proofview.Goal.enter begin fun gl ->
let name = Proof_global.get_current_proof_name () in
let id = new_fresh_id Id.Set.empty name gl in
@@ -965,6 +979,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 *)
@@ -1258,7 +1277,6 @@ let cut c =
end
let error_uninstantiated_metas t clenv =
- let t = EConstr.Unsafe.to_constr t in
let na = meta_name clenv.evd (List.hd (Metaset.elements (metavars_of t))) in
let id = match na with Name id -> id | _ -> anomaly (Pp.str "unnamed dependent meta.")
in user_err (str "Cannot find an instance for " ++ Id.print id ++ str".")
@@ -1268,7 +1286,7 @@ let check_unresolved_evars_of_metas sigma clenv =
(* Refiner.pose_all_metas_as_evars are resolved *)
List.iter (fun (mv,b) -> match b with
| Clval (_,(c,_),_) ->
- (match Constr.kind c.rebus with
+ (match Constr.kind (EConstr.Unsafe.to_constr c.rebus) with
| Evar (evk,_) when Evd.is_undefined clenv.evd evk
&& not (Evd.mem sigma evk) ->
error_uninstantiated_metas (mkMeta mv) clenv
@@ -1445,9 +1463,7 @@ let is_nonrec mind = (Global.lookup_mind (fst mind)).mind_finite == Declarations
let find_ind_eliminator ind s gl =
let gr = lookup_eliminator ind s in
- let evd, c = Tacmach.New.pf_apply Evd.fresh_global gl gr in
- let c = EConstr.of_constr c in
- evd, c
+ Tacmach.New.pf_apply Evd.fresh_global gl gr
let find_eliminator c gl =
let ((ind,u),t) = Tacmach.New.pf_reduce_to_quantified_ind gl (Tacmach.New.pf_unsafe_type_of gl c) in
@@ -2612,9 +2628,7 @@ let letin_tac_gen with_eq (id,depdecls,lastlhyp,ccl,c) ty =
let eqdata = build_coq_eq_data () in
let args = if lr then [t;mkVar id;c] else [t;c;mkVar id]in
let (sigma, eq) = Evd.fresh_global env sigma eqdata.eq in
- let eq = EConstr.of_constr eq in
let (sigma, refl) = Evd.fresh_global env sigma eqdata.refl in
- let refl = EConstr.of_constr refl in
let eq = applist (eq,args) in
let refl = applist (refl, [t;mkVar id]) in
let term = mkNamedLetIn id c t (mkLetIn (Name heq, refl, eq, ccl)) in
@@ -2668,9 +2682,7 @@ let mkletin_goal env sigma store with_eq dep (id,lastlhyp,ccl,c) ty =
let eqdata = build_coq_eq_data () in
let args = if lr then [t;mkVar id;c] else [t;c;mkVar id]in
let (sigma, eq) = Evd.fresh_global env sigma eqdata.eq in
- let eq = EConstr.of_constr eq in
let (sigma, refl) = Evd.fresh_global env sigma eqdata.refl in
- let refl = EConstr.of_constr refl in
let eq = applist (eq,args) in
let refl = applist (refl, [t;mkVar id]) in
let newenv = insert_before [LocalAssum (heq,eq); decl] lastlhyp env in
@@ -3008,8 +3020,24 @@ let unfold_body x =
end
end
+let warn_cannot_remove_as_expected =
+ CWarnings.create ~name:"cannot-remove-as-expected" ~category:"tactics"
+ (fun (id,inglobal) ->
+ let pp = match inglobal with
+ | None -> mt ()
+ | Some ref -> str ", it is used implicitly in " ++ Printer.pr_global ref in
+ str "Cannot remove " ++ Id.print id ++ pp ++ str ".")
+
+let clear_for_destruct ids =
+ Proofview.tclORELSE
+ (clear_gen (fun env sigma id err inglobal -> raise (ClearDependencyError (id,err,inglobal))) ids)
+ (function
+ | ClearDependencyError (id,err,inglobal),_ -> warn_cannot_remove_as_expected (id,inglobal); Proofview.tclUNIT ()
+ | e -> iraise e)
+
(* Either unfold and clear if defined or simply clear if not a definition *)
-let expand_hyp id = Tacticals.New.tclTRY (unfold_body id) <*> clear [id]
+let expand_hyp id =
+ Tacticals.New.tclTRY (unfold_body id) <*> clear_for_destruct [id]
(*****************************)
(* High-level induction *)
@@ -3425,7 +3453,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,...) *)
@@ -4930,9 +4958,9 @@ let cache_term_by_tactic_then ~opaque ?(goal_type=None) id gk tac tacK =
let evd, ctx, concl =
(* FIXME: should be done only if the tactic succeeds *)
- let evd, nf = nf_evars_and_universes !evdref in
+ let evd = Evd.minimize_universes !evdref in
let ctx = Evd.universe_context_set evd in
- evd, ctx, nf concl
+ evd, ctx, Evarutil.nf_evars_universes evd concl
in
let concl = EConstr.of_constr concl in
let solve_tac = tclCOMPLETE (tclTHEN (tclDO (List.length sign) intro) tac) in
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 8239600b1..9d84cd5c7 100644
--- a/test-suite/Makefile
+++ b/test-suite/Makefile
@@ -79,6 +79,8 @@ log_anomaly = "==========> FAILURE <=========="
log_failure = "==========> FAILURE <=========="
log_intro = "==========> TESTING $(1) <=========="
+FAIL = >&2 echo 'FAILED $@'
+
#######################################################################
# Testing subsystems
#######################################################################
@@ -115,25 +117,24 @@ run: $(SUBSYSTEMS)
bugs: $(BUGS)
clean:
- rm -f trace .lia.cache
- $(SHOW) "RM <**/*.stamp> <**/*.vo> <**/*.vio> <**/*.log>"
+ rm -f trace .lia.cache output/MExtraction.out
+ $(SHOW) "RM <**/*.vo> <**/*.vio> <**/*.log> <**/*.glob>"
$(HIDE)find . \( \
- -name '*.stamp' -o -name '*.vo' -o -name '*.vio' -o -name '*.log' \
+ -name '*.vo' -o -name '*.vio' -o -name '*.log' -o -name '*.glob' \
\) -print0 | xargs -0 rm -f
distclean: clean
- $(HIDE)find . -name '*.log' -print0 | xargs -0 rm -f
+ $(SHOW) "RM <**/*.aux>"
+ $(HIDE)find . -name '*.aux' -print0 | xargs -0 rm -f
#######################################################################
# Per-subsystem targets
#######################################################################
-define mkstamp
-$(1): $(1).stamp ; @true
-$(1).stamp: $(patsubst %.v,%.v.log,$(wildcard $(1)/*.v)) ; \
- $(HIDE)touch $$@
+define vdeps
+$(1): $(patsubst %.v,%.v.log,$(wildcard $(1)/*.v))
endef
-$(foreach S,$(VSUBSYSTEMS),$(eval $(call mkstamp,$(S))))
+$(foreach S,$(VSUBSYSTEMS),$(eval $(call vdeps,$(S))))
#######################################################################
# Summary
@@ -221,6 +222,7 @@ $(addsuffix .log,$(wildcard bugs/opened/*.v)): %.v.log: %.v
else \
echo $(log_failure); \
echo " $<...Error! (bug seems to be closed, please check)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -236,6 +238,7 @@ $(addsuffix .log,$(wildcard bugs/closed/*.v)): %.v.log: %.v
else \
echo $(log_failure); \
echo " $<...Error! (bug seems to be opened, please check)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -251,6 +254,7 @@ $(addsuffix .log,$(wildcard prerequisite/*.v)): %.v.log: %.v
if [ $$R != 0 ]; then \
echo $(log_failure); \
echo " $<...could not be prepared" ; \
+ $(FAIL); \
else \
echo $(log_success); \
echo " $<...correctly prepared" ; \
@@ -269,6 +273,7 @@ $(addsuffix .log,$(wildcard success/*.v micromega/*.v modules/*.v)): %.v.log: %.
else \
echo $(log_failure); \
echo " $<...Error! (should be accepted)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -285,6 +290,7 @@ $(addsuffix .log,$(wildcard stm/*.v)): %.v.log: %.v
else \
echo $(log_failure); \
echo " $<...Error! (should be accepted)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -299,6 +305,7 @@ $(addsuffix .log,$(wildcard failure/*.v)): %.v.log: %.v $(PREREQUISITELOG)
else \
echo $(log_failure); \
echo " $<...Error! (should be rejected)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -321,6 +328,7 @@ $(addsuffix .log,$(wildcard output/*.v)): %.v.log: %.v %.out $(PREREQUISITELOG)
else \
echo $(log_failure); \
echo " $<...Error! (unexpected output)"; \
+ $(FAIL); \
fi; \
rm $$tmpoutput; \
} > "$@"
@@ -363,6 +371,7 @@ $(addsuffix .log,$(wildcard output-modulo-time/*.v)): %.v.log: %.v %.out
else \
echo $(log_failure); \
echo " $<...Error! (unexpected output)"; \
+ $(FAIL); \
fi; \
rm $$tmpoutput; \
rm $$tmpexpected; \
@@ -379,6 +388,7 @@ $(addsuffix .log,$(wildcard interactive/*.v)): %.v.log: %.v $(PREREQUISITELOG)
else \
echo $(log_failure); \
echo " $<...Error! (should be accepted)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -411,6 +421,7 @@ $(addsuffix .log,$(wildcard complexity/*.v)): %.v.log: %.v $(PREREQUISITELOG)
else \
echo $(log_failure); \
echo " $<...Error! (should run faster)"; \
+ $(FAIL); \
fi; \
fi; \
} > "$@"
@@ -428,6 +439,7 @@ $(addsuffix .log,$(wildcard ideal-features/*.v)): %.v.log: %.v $(PREREQUISITELOG
else \
echo $(log_failure); \
echo " $<...Good news! (wish seems to be granted, please check)"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -462,6 +474,7 @@ $(patsubst %.sh,%.log,$(wildcard misc/*.sh)): %.log: %.sh $(PREREQUISITELOG)
else \
echo $(log_failure); \
echo " $<...Error!"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -480,6 +493,7 @@ ide : $(patsubst %.fake,%.fake.log,$(wildcard ide/*.fake))
else \
echo $(log_failure); \
echo " $<...Error!"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -499,6 +513,7 @@ vio: $(patsubst %.v,%.vio.log,$(wildcard vio/*.v))
else \
echo $(log_failure); \
echo " $<...Error!"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -517,6 +532,7 @@ coqchk: $(patsubst %.v,%.chk.log,$(wildcard coqchk/*.v))
else \
echo $(log_failure); \
echo " $<...Error!"; \
+ $(FAIL); \
fi; \
} > "$@"
@@ -536,6 +552,7 @@ coqwc/%.v.log : coqwc/%.v
else \
echo $(log_failure); \
echo " $<...Error! (unexpected output)"; \
+ $(FAIL); \
fi; \
rm $$tmpoutput; \
} > "$@"
@@ -556,6 +573,7 @@ coq-makefile/%.log : coq-makefile/%/run.sh
else \
echo $(log_failure); \
echo " $<...Error!"; \
+ $(FAIL); \
fi; \
) > "$@"
@@ -580,5 +598,6 @@ $(addsuffix .log,$(wildcard coqdoc/*.v)): %.v.log: %.v %.html.out %.tex.out $(PR
else \
echo $(log_failure); \
echo " $<...Error! (unexpected output)"; \
+ $(FAIL); \
fi; \
} > "$@"
diff --git a/test-suite/bugs/opened/1501.v b/test-suite/bugs/closed/1501.v
index b36f21da1..e771e192d 100644
--- a/test-suite/bugs/opened/1501.v
+++ b/test-suite/bugs/closed/1501.v
@@ -3,6 +3,7 @@ Set Implicit Arguments.
Require Export Relation_Definitions.
Require Export Setoid.
+Require Import Morphisms.
Section Essais.
@@ -40,57 +41,27 @@ Parameter
Hint Resolve equiv_refl equiv_sym equiv_trans: monad.
-Instance equiv_rel A: Equivalence (@equiv A).
-Proof.
- constructor.
- intros xa; apply equiv_refl.
- intros xa xb; apply equiv_sym.
- intros xa xb xc; apply equiv_trans.
-Defined.
-
-Definition fequiv (A B: Type) (f g: A -> K B) := forall (x:A), (equiv (f x) (g
-x)).
-
-Lemma fequiv_refl : forall (A B: Type) (f : A -> K B), fequiv f f.
-Proof.
- unfold fequiv; auto with monad.
-Qed.
-
-Lemma fequiv_sym : forall (A B: Type) (x y : A -> K B), fequiv x y -> fequiv y
-x.
-Proof.
- unfold fequiv; auto with monad.
-Qed.
+Add Parametric Relation A : (K A) (@equiv A)
+ reflexivity proved by (@equiv_refl A)
+ symmetry proved by (@equiv_sym A)
+ transitivity proved by (@equiv_trans A)
+ as equiv_rel.
-Lemma fequiv_trans : forall (A B: Type) (x y z : A -> K B), fequiv x y ->
-fequiv
-y z -> fequiv x z.
+Add Parametric Morphism A B : (@bind A B)
+ with signature (@equiv A) ==> (pointwise_relation A (@equiv B)) ==> (@equiv B)
+ as bind_mor.
Proof.
- unfold fequiv; intros; eapply equiv_trans; auto with monad.
-Qed.
-
-Instance fequiv_re A B: Equivalence (@fequiv A B).
-Proof.
- constructor.
- intros f; apply fequiv_refl.
- intros f g; apply fequiv_sym.
- intros f g h; apply fequiv_trans.
-Defined.
-
-Instance bind_mor A B: Morphisms.Proper (@equiv _ ==> @fequiv _ _ ==> @equiv _) (@bind A B).
-Proof.
- unfold fequiv; intros x y xy_equiv f g fg_equiv; apply bind_compat; auto.
+ unfold pointwise_relation; intros; apply bind_compat; auto.
Qed.
Lemma test:
forall (A B: Type) (m1 m2 m3: K A) (f: A -> A -> K B),
- (equiv m1 m2) -> (equiv m2 m3) ->
- equiv (bind m1 (fun a => bind m2 (fun a' => f a a')))
- (bind m2 (fun a => bind m3 (fun a' => f a a'))).
+ (equiv m1 m2) -> (equiv m2 m3) ->
+ equiv (bind m1 (fun a => bind m2 (fun a' => f a a')))
+ (bind m2 (fun a => bind m3 (fun a' => f a a'))).
Proof.
intros A B m1 m2 m3 f H1 H2.
setoid_rewrite H1. (* this works *)
- Fail setoid_rewrite H2.
-Abort.
-(* trivial by equiv_refl.
-Qed.*)
+ setoid_rewrite H2.
+ reflexivity.
+Qed.
diff --git a/test-suite/bugs/closed/2001.v b/test-suite/bugs/closed/2001.v
index d0b3bf173..652c65706 100644
--- a/test-suite/bugs/closed/2001.v
+++ b/test-suite/bugs/closed/2001.v
@@ -7,7 +7,7 @@ Inductive T : Set :=
| v : T.
Definition f (s:nat) (t:T) : nat.
-fix 2.
+fix f 2.
intros s t.
refine
match t with
diff --git a/test-suite/bugs/opened/2456.v b/test-suite/bugs/closed/2456.v
index 5294adefd..e5a392c4d 100644
--- a/test-suite/bugs/opened/2456.v
+++ b/test-suite/bugs/closed/2456.v
@@ -50,4 +50,9 @@ Fail dependent destruction commute1;
dependent destruction catchCommuteDetails;
dependent destruction commute2;
dependent destruction catchCommuteDetails generalizing X.
-Admitted.
+revert X.
+dependent destruction commute1;
+dependent destruction catchCommuteDetails;
+dependent destruction commute2;
+dependent destruction catchCommuteDetails.
+Abort.
diff --git a/test-suite/bugs/opened/2814.v b/test-suite/bugs/closed/2814.v
index a740b4384..99da1e3e4 100644
--- a/test-suite/bugs/opened/2814.v
+++ b/test-suite/bugs/closed/2814.v
@@ -3,3 +3,4 @@ Require Import Program.
Goal forall (x : Type) (f g : Type -> Type) (H : f x ~= g x), False.
intros.
Fail induction H.
+Abort.
diff --git a/test-suite/bugs/opened/3100.v b/test-suite/bugs/closed/3100.v
index 6f35a74dc..6f35a74dc 100644
--- a/test-suite/bugs/opened/3100.v
+++ b/test-suite/bugs/closed/3100.v
diff --git a/test-suite/bugs/opened/3230.v b/test-suite/bugs/closed/3230.v
index 265310b1a..265310b1a 100644
--- a/test-suite/bugs/opened/3230.v
+++ b/test-suite/bugs/closed/3230.v
diff --git a/test-suite/bugs/opened/3320.v b/test-suite/bugs/closed/3320.v
index 05cf73281..a5c243d8e 100644
--- a/test-suite/bugs/opened/3320.v
+++ b/test-suite/bugs/closed/3320.v
@@ -1,4 +1,5 @@
Goal forall x : nat, True.
- fix 1.
+ fix goal 1.
assumption.
Fail Qed.
+Undo.
diff --git a/test-suite/bugs/closed/3350.v b/test-suite/bugs/closed/3350.v
index c041c401f..c1ff292b3 100644
--- a/test-suite/bugs/closed/3350.v
+++ b/test-suite/bugs/closed/3350.v
@@ -55,7 +55,7 @@ Lemma lower_ind (P: forall n (p i:Fin.t (S n)), option (Fin.t n) -> Prop)
P (S n) (Fin.FS p) (Fin.FS i) None) :
forall n (p i:Fin.t (S n)), P n p i (lower p i).
Proof.
- fix 2. intros n p.
+ fix lower_ind 2. intros n p.
refine (match p as p1 in Fin.t (S n1)
return forall (i1:Fin.t (S n1)), P n1 p1 i1 (lower p1 i1)
with
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/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/opened/3209.v b/test-suite/bugs/opened/3209.v
deleted file mode 100644
index 3203afa13..000000000
--- a/test-suite/bugs/opened/3209.v
+++ /dev/null
@@ -1,17 +0,0 @@
-Inductive eqT {A} (x : A) : A -> Type :=
- reflT : eqT x x.
-Definition Bi_inv (A B : Type) (f : (A -> B)) :=
- sigT (fun (g : B -> A) =>
- sigT (fun (h : B -> A) =>
- sigT (fun (α : forall b : B, eqT (f (g b)) b) =>
- forall a : A, eqT (h (f a)) a))).
-Definition TEquiv (A B : Type) := sigT (fun (f : A -> B) => Bi_inv _ _ f).
-
-Axiom UA : forall (A B : Type), TEquiv (TEquiv A B) (eqT A B).
-Definition idtoeqv {A B} (e : eqT A B) : TEquiv A B :=
- sigT_rect (fun _ => TEquiv A B)
- (fun (f : TEquiv A B -> eqT A B) H =>
- sigT_rect (fun _ => TEquiv A B)
- (fun g _ => g e)
- H)
- (UA A B).
diff --git a/test-suite/bugs/opened/3263.v b/test-suite/bugs/opened/3263.v
deleted file mode 100644
index f0c707bd1..000000000
--- a/test-suite/bugs/opened/3263.v
+++ /dev/null
@@ -1,232 +0,0 @@
-Require Import TestSuite.admit.
-(* File reduced by coq-bug-finder from originally 10918 lines, then 3649 lines to 3177 lines, then from 3189 lines to 3164 lines, then from 2653 lines to 2496 lines, 2653 lines, then from 1642 lines to 651 lines, then from 736 lines to 473 lines, then from 433 lines to 275 lines, then from 258 lines to 235 lines. *)
-Generalizable All Variables.
-Set Implicit Arguments.
-
-Arguments fst {_ _} _.
-Arguments snd {_ _} _.
-
-Axiom cheat : forall {T}, T.
-
-Reserved Notation "g 'o' f" (at level 40, left associativity).
-
-Inductive paths {A : Type} (a : A) : A -> Type := idpath : paths a a.
-Arguments idpath {A a} , [A] a.
-Notation "x = y" := (paths x y) : type_scope.
-
-Definition symmetry {A : Type} {x y : A} (p : x = y) : y = x
- := match p with idpath => idpath end.
-
-Delimit Scope morphism_scope with morphism.
-Delimit Scope category_scope with category.
-Delimit Scope object_scope with object.
-Record PreCategory (object : Type) :=
- Build_PreCategory' {
- object :> Type := object;
- morphism : object -> object -> Type;
- identity : forall x, morphism x x;
- compose : forall s d d',
- morphism d d'
- -> morphism s d
- -> morphism s d'
- where "f 'o' g" := (compose f g);
- associativity : forall x1 x2 x3 x4
- (m1 : morphism x1 x2)
- (m2 : morphism x2 x3)
- (m3 : morphism x3 x4),
- (m3 o m2) o m1 = m3 o (m2 o m1);
- associativity_sym : forall x1 x2 x3 x4
- (m1 : morphism x1 x2)
- (m2 : morphism x2 x3)
- (m3 : morphism x3 x4),
- m3 o (m2 o m1) = (m3 o m2) o m1;
- left_identity : forall a b (f : morphism a b), identity b o f = f;
- right_identity : forall a b (f : morphism a b), f o identity a = f;
- identity_identity : forall x, identity x o identity x = identity x
- }.
-Bind Scope category_scope with PreCategory.
-Arguments PreCategory {_}.
-Arguments identity {_} [!C%category] x%object : rename.
-
-Arguments compose {_} [!C%category s%object d%object d'%object] m1%morphism m2%morphism : rename.
-
-Infix "o" := compose : morphism_scope.
-
-Delimit Scope functor_scope with functor.
-Local Open Scope morphism_scope.
-Record Functor `(C : @PreCategory objC, D : @PreCategory objD) :=
- {
- object_of :> C -> D;
- morphism_of : forall s d, morphism C s d
- -> morphism D (object_of s) (object_of d);
- composition_of : forall s d d'
- (m1 : morphism C s d) (m2: morphism C d d'),
- morphism_of _ _ (m2 o m1)
- = (morphism_of _ _ m2) o (morphism_of _ _ m1);
- identity_of : forall x, morphism_of _ _ (identity x)
- = identity (object_of x)
- }.
-Bind Scope functor_scope with Functor.
-
-Arguments morphism_of {_} [C%category] {_} [D%category] F%functor [s%object d%object] m%morphism : rename, simpl nomatch.
-
-Notation "F '_1' m" := (morphism_of F m) (at level 10, no associativity) : morphism_scope.
-
-Class IsIsomorphism `{C : @PreCategory objC} {s d} (m : morphism C s d) :=
- {
- morphism_inverse : morphism C d s;
- left_inverse : morphism_inverse o m = identity _;
- right_inverse : m o morphism_inverse = identity _
- }.
-
-Definition opposite `(C : @PreCategory objC) : PreCategory
- := @Build_PreCategory'
- C
- (fun s d => morphism C d s)
- (identity (C := C))
- (fun _ _ _ m1 m2 => m2 o m1)
- (fun _ _ _ _ _ _ _ => @associativity_sym _ _ _ _ _ _ _ _ _)
- (fun _ _ _ _ _ _ _ => @associativity _ _ _ _ _ _ _ _ _)
- (fun _ _ => @right_identity _ _ _ _)
- (fun _ _ => @left_identity _ _ _ _)
- (@identity_identity _ C).
-
-Notation "C ^op" := (opposite C) (at level 3) : category_scope.
-
-Definition prod `(C : @PreCategory objC, D : @PreCategory objD) : @PreCategory (objC * objD).
- refine (@Build_PreCategory'
- (C * D)%type
- (fun s d => (morphism C (fst s) (fst d)
- * morphism D (snd s) (snd d))%type)
- (fun x => (identity (fst x), identity (snd x)))
- (fun s d d' m2 m1 => (fst m2 o fst m1, snd m2 o snd m1))
- _
- _
- _
- _
- _); admit.
-Defined.
-Infix "*" := prod : category_scope.
-
-Definition compose_functor `(C : @PreCategory objC, D : @PreCategory objD, E : @PreCategory objE) (G : Functor D E) (F : Functor C D) : Functor C E
- := Build_Functor
- C E
- (fun c => G (F c))
- (fun _ _ m => morphism_of G (morphism_of F m))
- cheat
- cheat.
-
-Infix "o" := compose_functor : functor_scope.
-
-Record NaturalTransformation `(C : @PreCategory objC, D : @PreCategory objD) (F G : Functor C D) :=
- Build_NaturalTransformation' {
- components_of :> forall c, morphism D (F c) (G c);
- commutes : forall s d (m : morphism C s d),
- components_of d o F _1 m = G _1 m o components_of s;
-
- commutes_sym : forall s d (m : C.(morphism) s d),
- G _1 m o components_of s = components_of d o F _1 m
- }.
-Definition functor_category `(C : @PreCategory objC, D : @PreCategory objD) : PreCategory
- := @Build_PreCategory' (Functor C D)
- (@NaturalTransformation _ C _ D)
- cheat
- cheat
- cheat
- cheat
- cheat
- cheat
- cheat.
-
-Definition opposite_functor `(F : @Functor objC C objD D) : Functor C^op D^op
- := Build_Functor (C^op) (D^op)
- (object_of F)
- (fun s d => morphism_of F (s := d) (d := s))
- (fun d' d s m1 m2 => composition_of F s d d' m2 m1)
- (identity_of F).
-
-Definition opposite_invL `(F : @Functor objC C^op objD D) : Functor C D^op
- := Build_Functor C (D^op)
- (object_of F)
- (fun s d => morphism_of F (s := d) (d := s))
- (fun d' d s m1 m2 => composition_of F s d d' m2 m1)
- (identity_of F).
-Notation "F ^op" := (opposite_functor F) : functor_scope.
-
-Notation "F ^op'L" := (opposite_invL F) (at level 3) : functor_scope.
-Definition fst `{C : @PreCategory objC, D : @PreCategory objD} : Functor (C * D) C
- := Build_Functor (C * D) C
- (@fst _ _)
- (fun _ _ => @fst _ _)
- (fun _ _ _ _ _ => idpath)
- (fun _ => idpath).
-
-Definition snd `{C : @PreCategory objC, D : @PreCategory objD} : Functor (C * D) D
- := Build_Functor (C * D) D
- (@snd _ _)
- (fun _ _ => @snd _ _)
- (fun _ _ _ _ _ => idpath)
- (fun _ => idpath).
-Definition prod_functor `(F : @Functor objC C objD D, F' : @Functor objC C objD' D')
-: Functor C (D * D')
- := Build_Functor
- C (D * D')
- (fun c => (F c, F' c))
- (fun s d m => (F _1 m, F' _1 m))%morphism
- cheat
- cheat.
-Definition pair `(F : @Functor objC C objD D, F' : @Functor objC' C' objD' D') : Functor (C * C') (D * D')
- := (prod_functor (F o fst) (F' o snd))%functor.
-Notation cat_of obj :=
- (@Build_PreCategory' obj
- (fun x y => forall _ : x, y)
- (fun _ x => x)
- (fun _ _ _ f g x => f (g x))%core
- (fun _ _ _ _ _ _ _ => idpath)
- (fun _ _ _ _ _ _ _ => idpath)
- (fun _ _ _ => idpath)
- (fun _ _ _ => idpath)
- (fun _ => idpath)).
-
-Definition hom_functor `(C : @PreCategory objC) : Functor (C^op * C) (cat_of Type)
- := Build_Functor _ _ cheat cheat cheat cheat.
-
-Definition induced_hom_natural_transformation `(F : @Functor objC C objD D)
-: NaturalTransformation (hom_functor C) (hom_functor D o pair F^op F)
- := Build_NaturalTransformation' _ _ cheat cheat cheat.
-
-Class IsFullyFaithful `(F : @Functor objC C objD D)
- := is_fully_faithful
- : forall x y : C,
- IsIsomorphism (induced_hom_natural_transformation F (x, y)).
-
-Definition coyoneda `(A : @PreCategory objA) : Functor A^op (@functor_category _ A _ (cat_of Type))
- := cheat.
-
-Definition yoneda `(A : @PreCategory objA) : Functor A (@functor_category _ A^op _ (cat_of Type))
- := (((coyoneda A^op)^op'L)^op'L)%functor.
-Definition coyoneda_embedding `(A : @PreCategory objA) : @IsFullyFaithful _ _ _ _ (@coyoneda _ A).
-Admitted.
-
-Definition yoneda_embedding_fast `(A : @PreCategory objA) : @IsFullyFaithful _ _ _ _ (@yoneda _ A).
-Proof.
- intros a b.
- pose proof (coyoneda_embedding A^op a b) as CYE.
- unfold yoneda.
- Time let t := (type of CYE) in
- let t' := (eval simpl in t) in pose proof ((fun (x : t) => (x : t')) CYE) as CYE'. (* Finished transaction in 0. secs (0.216013u,0.004s) *)
- Fail Timeout 1 let t := match goal with |- ?G => constr:(G) end in
- let t' := (eval simpl in t) in exact ((fun (x : t') => (x : t)) CYE').
- Time let t := match goal with |- ?G => constr:(G) end in
- let t' := (eval simpl in t) in exact ((fun (x : t') => (x : t)) CYE'). (* Finished transaction in 0. secs (0.248016u,0.s) *)
-Fail Timeout 2 Defined.
-Time Defined. (* Finished transaction in 1. secs (0.432027u,0.s) *)
-
-Definition yoneda_embedding `(A : @PreCategory objA) : @IsFullyFaithful _ _ _ _ (@yoneda _ A).
-Proof.
- intros a b.
- pose proof (coyoneda_embedding A^op a b) as CYE.
- unfold yoneda; simpl in *.
- Fail Timeout 1 exact CYE.
- Time exact CYE. (* Finished transaction in 0. secs (0.012001u,0.s) *)
-Fail Timeout 60 Defined. (* Timeout! *)
diff --git a/test-suite/bugs/opened/3916.v b/test-suite/bugs/opened/3916.v
deleted file mode 100644
index fd95503e6..000000000
--- a/test-suite/bugs/opened/3916.v
+++ /dev/null
@@ -1,3 +0,0 @@
-Require Import List.
-
-Fail Hint Resolve -> in_map. (* Also happens when using <- instead of -> *)
diff --git a/test-suite/bugs/opened/3948.v b/test-suite/bugs/opened/3948.v
deleted file mode 100644
index 5c4b4277b..000000000
--- a/test-suite/bugs/opened/3948.v
+++ /dev/null
@@ -1,25 +0,0 @@
-Module Type S.
-Parameter t : Type.
-End S.
-
-Module Bar(X : S).
-Proof.
- Definition elt := X.t.
- Axiom fold : elt.
-End Bar.
-
-Module Make (X: S) := Bar(X).
-
-Declare Module X : S.
-
-Module Type Interface.
- Parameter constant : unit.
-End Interface.
-
-Module DepMap : Interface.
- Module Dom := Make(X).
- Definition constant : unit :=
- let _ := @Dom.fold in tt.
-End DepMap.
-
-Print Assumptions DepMap.constant.
diff --git a/test-suite/bugs/opened/4813.v b/test-suite/bugs/opened/4813.v
index b75170179..2ac553593 100644
--- a/test-suite/bugs/opened/4813.v
+++ b/test-suite/bugs/opened/4813.v
@@ -1,5 +1,5 @@
-(* An example one would like to see succeeding *)
+Require Import Program.Tactics.
Record T := BT { t : Set }.
Record U (x : T) := BU { u : t x -> Prop }.
-Fail Definition A (H : unit -> Prop) : U (BT unit) := BU _ H.
+Program Definition A (H : unit -> Prop) : U (BT unit) := BU _ H.
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/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..f303214b9
--- /dev/null
+++ b/test-suite/misc/coqc_dash_o.sh
@@ -0,0 +1,15 @@
+#!/bin/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/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/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/success/ShowExtraction.v b/test-suite/success/ShowExtraction.v
index e34c240c5..a4a35003d 100644
--- a/test-suite/success/ShowExtraction.v
+++ b/test-suite/success/ShowExtraction.v
@@ -12,7 +12,7 @@ Fail Show Extraction.
Lemma decListA : forall (xs ys : list A), {xs=ys}+{xs<>ys}.
Proof.
Show Extraction.
-fix 1.
+fix decListA 1.
destruct xs as [|x xs], ys as [|y ys].
Show Extraction.
- now left.
diff --git a/test-suite/success/cc.v b/test-suite/success/cc.v
index bbfe5ec42..49a8b9cf4 100644
--- a/test-suite/success/cc.v
+++ b/test-suite/success/cc.v
@@ -151,3 +151,17 @@ Section JLeivant.
congruence.
Qed.
End JLeivant.
+
+(* An example with primitive projections *)
+
+Module PrimitiveProjections.
+Set Primitive Projections.
+Record t (A:Type) := { f : A }.
+Goal forall g (a:t nat), @f nat = g -> f a = 0 -> g a = 0.
+congruence.
+Undo.
+intros.
+unfold f in H0. (* internally turn the projection to unfolded form *)
+congruence.
+Qed.
+End PrimitiveProjections.
diff --git a/test-suite/success/evars.v b/test-suite/success/evars.v
index 5b13f35d5..253b48e4d 100644
--- a/test-suite/success/evars.v
+++ b/test-suite/success/evars.v
@@ -421,3 +421,8 @@ Goal exists n : nat, n = n -> True.
eexists.
set (H := _ = _).
Abort.
+
+(* Check interpretation of default evar instance in pretyping *)
+(* (reported as bug #7356) *)
+
+Check fun (P : nat -> Prop) (x:nat) (h:P x) => exist _ ?[z] (h : P ?z).
diff --git a/test-suite/success/goal_selector.v b/test-suite/success/goal_selector.v
index 868140517..0951c5c8d 100644
--- a/test-suite/success/goal_selector.v
+++ b/test-suite/success/goal_selector.v
@@ -53,3 +53,17 @@ Goal True -> exists (x : Prop), x.
Proof.
intro H; eexists ?[x]; only [x]: exact True. 1: assumption.
Qed.
+
+(* Strict focusing! *)
+Set Default Goal Selector "!".
+
+Goal True -> True /\ True /\ True.
+Proof.
+ intro.
+ split;only 2:split.
+ Fail exact I.
+ Fail !:exact I.
+ 1:exact I.
+ - !:exact H.
+ - exact I.
+Qed.
diff --git a/test-suite/success/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/name_mangling.v b/test-suite/success/name_mangling.v
index 571dde880..e98241420 100644
--- a/test-suite/success/name_mangling.v
+++ b/test-suite/success/name_mangling.v
@@ -122,8 +122,7 @@ Lemma a : forall n, n = 0.
Proof.
fix a 1.
Check a.
-fix 1.
-Fail Check a0.
+Fail fix a 1.
Abort.
(* Test stability of "induction" *)
diff --git a/test-suite/success/ssr_delayed_clear_rename.v b/test-suite/success/ssr_delayed_clear_rename.v
new file mode 100644
index 000000000..951e5aff7
--- /dev/null
+++ b/test-suite/success/ssr_delayed_clear_rename.v
@@ -0,0 +1,5 @@
+Require Import ssreflect.
+Example foo (t t1 t2 : True) : True /\ True -> True -> True.
+Proof.
+move=>[{t1 t2 t} t1 t2] t.
+Abort.
diff --git a/theories/Arith/Div2.v b/theories/Arith/Div2.v
index 42956c475..a5e457831 100644
--- a/theories/Arith/Div2.v
+++ b/theories/Arith/Div2.v
@@ -30,7 +30,7 @@ Lemma ind_0_1_SS :
P 0 -> P 1 -> (forall n, P n -> P (S (S n))) -> forall n, P n.
Proof.
intros P H0 H1 H2.
- fix 1.
+ fix ind_0_1_SS 1.
destruct n as [|[|n]].
- exact H0.
- exact H1.
@@ -105,7 +105,7 @@ Hint Resolve double_S: arith.
Lemma even_odd_double n :
(even n <-> n = double (div2 n)) /\ (odd n <-> n = S (double (div2 n))).
Proof.
- revert n. fix 1. destruct n as [|[|n]].
+ revert n. fix even_odd_double 1. destruct n as [|[|n]].
- (* n = 0 *)
split; split; auto with arith. inversion 1.
- (* n = 1 *)
diff --git a/theories/Arith/Even.v b/theories/Arith/Even.v
index baf119732..a1d0e9fcc 100644
--- a/theories/Arith/Even.v
+++ b/theories/Arith/Even.v
@@ -38,7 +38,7 @@ Hint Constructors odd: arith.
Lemma even_equiv : forall n, even n <-> Nat.Even n.
Proof.
- fix 1.
+ fix even_equiv 1.
destruct n as [|[|n]]; simpl.
- split; [now exists 0 | constructor].
- split.
@@ -52,7 +52,7 @@ Qed.
Lemma odd_equiv : forall n, odd n <-> Nat.Odd n.
Proof.
- fix 1.
+ fix odd_equiv 1.
destruct n as [|[|n]]; simpl.
- split.
+ inversion_clear 1.
diff --git a/theories/Arith/PeanoNat.v b/theories/Arith/PeanoNat.v
index 4e4938a99..bc58995fd 100644
--- a/theories/Arith/PeanoNat.v
+++ b/theories/Arith/PeanoNat.v
@@ -315,7 +315,7 @@ Import Private_Parity.
Lemma even_spec : forall n, even n = true <-> Even n.
Proof.
- fix 1.
+ fix even_spec 1.
destruct n as [|[|n]]; simpl.
- split; [ now exists 0 | trivial ].
- split; [ discriminate | intro H; elim (Even_1 H) ].
@@ -325,7 +325,7 @@ Qed.
Lemma odd_spec : forall n, odd n = true <-> Odd n.
Proof.
unfold odd.
- fix 1.
+ fix odd_spec 1.
destruct n as [|[|n]]; simpl.
- split; [ discriminate | intro H; elim (Odd_0 H) ].
- split; [ now exists 0 | trivial ].
@@ -473,7 +473,7 @@ Notation "( x | y )" := (divide x y) (at level 0) : nat_scope.
Lemma gcd_divide : forall a b, (gcd a b | a) /\ (gcd a b | b).
Proof.
- fix 1.
+ fix gcd_divide 1.
intros [|a] b; simpl.
split.
now exists 0.
@@ -502,7 +502,7 @@ Qed.
Lemma gcd_greatest : forall a b c, (c|a) -> (c|b) -> (c|gcd a b).
Proof.
- fix 1.
+ fix gcd_greatest 1.
intros [|a] b; simpl; auto.
fold (b mod (S a)).
intros c H H'. apply gcd_greatest; auto.
@@ -536,7 +536,7 @@ Qed.
Lemma le_div2 n : div2 (S n) <= n.
Proof.
revert n.
- fix 1.
+ fix le_div2 1.
destruct n; simpl; trivial. apply lt_succ_r.
destruct n; [simpl|]; trivial. now constructor.
Qed.
diff --git a/theories/Lists/Streams.v b/theories/Lists/Streams.v
index 310c651e8..8a01b8fb1 100644
--- a/theories/Lists/Streams.v
+++ b/theories/Lists/Streams.v
@@ -196,7 +196,7 @@ Lemma ForAll_map : forall (P:Stream B -> Prop) (S:Stream A), ForAll (fun s => P
(map s)) S <-> ForAll P (map S).
Proof.
intros P S.
-split; generalize S; clear S; cofix; intros S; constructor;
+split; generalize S; clear S; cofix ForAll_map; intros S; constructor;
destruct H as [H0 H]; firstorder.
Qed.
diff --git a/theories/PArith/BinPos.v b/theories/PArith/BinPos.v
index 8d0896db7..000d895e1 100644
--- a/theories/PArith/BinPos.v
+++ b/theories/PArith/BinPos.v
@@ -1655,7 +1655,7 @@ Qed.
Lemma sqrtrem_spec p : SqrtSpec (sqrtrem p) p.
Proof.
-revert p. fix 1.
+revert p. fix sqrtrem_spec 1.
destruct p; try destruct p; try (constructor; easy);
apply sqrtrem_step_spec; auto.
Qed.
diff --git a/theories/Sorting/Heap.v b/theories/Sorting/Heap.v
index d9e5ad676..2ef162be4 100644
--- a/theories/Sorting/Heap.v
+++ b/theories/Sorting/Heap.v
@@ -148,10 +148,10 @@ Section defs.
forall l1:list A, Sorted leA l1 ->
forall l2:list A, Sorted leA l2 -> merge_lem l1 l2.
Proof.
- fix 1; intros; destruct l1.
+ fix merge 1; intros; destruct l1.
apply merge_exist with l2; auto with datatypes.
rename l1 into l.
- revert l2 H0. fix 1. intros.
+ revert l2 H0. fix merge0 1. intros.
destruct l2 as [|a0 l0].
apply merge_exist with (a :: l); simpl; auto with datatypes.
induction (leA_dec a a0) as [Hle|Hle].
diff --git a/tools/CoqMakefile.in b/tools/CoqMakefile.in
index f6539d80b..e5f22f25e 100644
--- a/tools/CoqMakefile.in
+++ b/tools/CoqMakefile.in
@@ -382,7 +382,7 @@ real-all: $(VOFILES) $(if $(USEBYTE),bytefiles,optfiles)
.PHONY: real-all
real-all.timing.diff: $(VOFILES:.vo=.v.timing.diff)
-.PHONE: real-all.timing.diff
+.PHONY: real-all.timing.diff
bytefiles: $(CMOFILES) $(CMAFILES)
.PHONY: bytefiles
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/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/toplevel/coqargs.ml b/toplevel/coqargs.ml
index a1a07fce8..17e848c5a 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
diff --git a/toplevel/coqloop.ml b/toplevel/coqloop.ml
index d0989cfcc..da9169514 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
@@ -272,8 +271,17 @@ let read_sentence ~state input =
(* TopErr.print_toplevel_parse_error reraise top_buffer; *)
Exninfo.iraise reraise
+let extract_default_loc loc doc_id sid : Loc.t option =
+ match loc with
+ | Some _ -> loc
+ | None ->
+ try
+ let doc = Stm.get_doc doc_id in
+ Option.cata fst None Stm.(get_ast ~doc sid)
+ 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 -> ()
@@ -290,8 +298,11 @@ let coqloop_feed (fb : Feedback.feedback) = let open Feedback in
(* Re-enable when we switch back to feedback-based error printing *)
| Message (Error,loc,msg) -> ()
(* 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 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.
@@ -341,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 =
@@ -383,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 =
diff --git a/toplevel/coqloop.mli b/toplevel/coqloop.mli
index 39a9de4f8..6d9867fb9 100644
--- a/toplevel/coqloop.mli
+++ b/toplevel/coqloop.mli
@@ -30,7 +30,7 @@ val top_buffer : input_buffer
val set_prompt : (unit -> string) -> unit
(** Toplevel feedback printer. *)
-val coqloop_feed : Feedback.feedback -> unit
+val coqloop_feed : Topfmt.execution_phase -> Feedback.feedback -> unit
(** Main entry point of Coq: read and execute vernac commands. *)
val loop : state:Vernac.State.t -> Vernac.State.t
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index 0dabed6b7..809490166 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -35,12 +35,16 @@ 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
+let coqtop_init_feed = Coqloop.coqloop_feed Topfmt.Initialization
+
+let coqtop_doc_feed = Coqloop.coqloop_feed Topfmt.LoadingPrelude
+
+let coqtop_rcfile_feed = Coqloop.coqloop_feed Topfmt.LoadingRcFile
(* 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
+ let tl_feed = Feedback.add_feeder (Coqloop.coqloop_feed Topfmt.InteractiveLoop) in
if Dumpglob.dump () then begin
Flags.if_verbose warning "Dumpglob cannot be used in interactive mode.";
Dumpglob.noglob ()
@@ -101,9 +105,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 +158,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 +205,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 +229,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 +281,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 +309,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 *)
@@ -368,7 +390,7 @@ let init_color color_mode =
let toploop_init = ref begin fun opts x ->
let () = init_color opts.color in
let () = CoqworkmgrApi.init !WorkerLoop.async_proofs_worker_priority in
- x
+ opts, x
end
let print_style_tags opts =
@@ -420,7 +442,7 @@ let init_toplevel arglist =
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:
@@ -435,14 +457,26 @@ let init_toplevel arglist =
* early since the master waits us to connect back *)
Spawned.init_channels ();
Envars.set_coqlib ~fail:(fun msg -> CErrors.user_err Pp.(str msg));
- if opts.print_where then (print_endline(Envars.coqlib ()); exit(exitcode opts));
- if opts.print_config then (Envars.print_config stdout Coq_config.all_src_dirs; exit (exitcode opts));
- if opts.print_tags then (print_style_tags opts; exit (exitcode opts));
- if opts.filter_opts then (print_string (String.concat "\n" extras); exit 0);
+ if opts.print_where then begin
+ print_endline (Envars.coqlib ());
+ exit (exitcode opts)
+ end;
+ if opts.print_config then begin
+ Envars.print_config stdout Coq_config.all_src_dirs;
+ exit (exitcode opts)
+ end;
+ if opts.print_tags then begin
+ print_style_tags opts;
+ exit (exitcode opts)
+ end;
+ if opts.filter_opts then begin
+ print_string (String.concat "\n" extras);
+ exit 0;
+ end;
let top_lp = Coqinit.toplevel_init_load_path () in
List.iter Mltop.add_coq_path top_lp;
Option.iter Mltop.load_ml_object_raw opts.toploop;
- let extras = !toploop_init opts extras in
+ let opts, extras = !toploop_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";
@@ -477,34 +511,33 @@ 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 () =
diff --git a/toplevel/coqtop.mli b/toplevel/coqtop.mli
index 056279bbd..fcc569ca0 100644
--- a/toplevel/coqtop.mli
+++ b/toplevel/coqtop.mli
@@ -18,5 +18,6 @@ val init_toplevel : string list -> Vernac.State.t option * Coqargs.coq_cmdopts
val start : unit -> unit
(* For other toploops *)
-val toploop_init : (Coqargs.coq_cmdopts -> string list -> string list) ref
+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
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..5e602289b 100644
--- a/vernac/auto_ind_decl.ml
+++ b/vernac/auto_ind_decl.ml
@@ -54,7 +54,7 @@ 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
@@ -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
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 59d933108..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
@@ -181,6 +181,7 @@ let build_id_coercion idf_opt source poly =
let sigma, vs = match source with
| CL_CONST sp -> Evd.fresh_global env sigma (ConstRef sp)
| _ -> error_not_transparent source in
+ let vs = EConstr.Unsafe.to_constr vs in
let c = match constant_opt_value_in env (destConst vs) with
| Some c -> c
| None -> error_not_transparent source in
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 76d427add..1ac597695 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())))
@@ -196,7 +195,7 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
in
let (_, ty_constr) = instance_constructor (k,u) subst in
let termtype = it_mkProd_or_LetIn ty_constr (ctx' @ ctx) in
- let sigma,_ = Evarutil.nf_evars_and_universes sigma in
+ let sigma = Evd.minimize_universes sigma in
Pretyping.check_evars env Evd.empty sigma termtype;
let univs = Evd.check_univ_decl ~poly sigma decl in
let termtype = to_constr sigma termtype in
@@ -289,11 +288,11 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
let sigma = Typeclasses.resolve_typeclasses ~filter:Typeclasses.all_evars ~fail:false env sigma in
let sigma = Evarutil.nf_evar_map_undefined sigma in
(* Beware of this step, it is required as to minimize universes. *)
- let sigma, _nf = Evarutil.nf_evar_map_universes sigma in
+ let sigma = Evd.minimize_universes sigma in
(* Check that the type is free of evars now. *)
Pretyping.check_evars env Evd.empty sigma termtype;
let termtype = to_constr sigma termtype in
- let term = Option.map (to_constr sigma) term in
+ let term = Option.map (to_constr ~abort_on_undefined_evars:false sigma) term in
if not (Evd.has_undefined sigma) && not (Option.is_empty term) then
declare_instance_constant k pri global imps ?hook id decl
poly sigma (Option.get term) termtype
@@ -365,7 +364,7 @@ let context poly l =
let sigma = Evd.from_env env in
let sigma, (_, ((env', fullctx), impls)) = interp_context_evars env sigma l in
(* Note, we must use the normalized evar from now on! *)
- let sigma,_ = Evarutil.nf_evars_and_universes sigma in
+ let sigma = Evd.minimize_universes sigma in
let ce t = Pretyping.check_evars env Evd.empty sigma t in
let () = List.iter (fun decl -> Context.Rel.Declaration.iter_constr ce decl) fullctx in
let ctx =
@@ -425,7 +424,7 @@ let context poly l =
let nstatus = match b with
| None ->
pi3 (ComAssumption.declare_assumption false decl (t, univs) Universes.empty_binders [] impl
- Vernacexpr.NoInline (CAst.make id))
+ Declaremods.NoInline (CAst.make id))
| Some b ->
let decl = (Discharge, poly, Definition) in
let entry = Declare.definition_entry ~univs ~types:t b in
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 6a590758f..26a46a752 100644
--- a/vernac/comAssumption.ml
+++ b/vernac/comAssumption.ml
@@ -20,7 +20,6 @@ open Constrintern
open Impargs
open Decl_kinds
open Pretyping
-open Vernacexpr
open Entries
(* 2| Variable/Hypothesis/Parameter/Axiom declarations *)
@@ -66,7 +65,7 @@ match local with
| Global | Local | Discharge ->
let do_instance = should_axiom_into_instance local in
let local = DeclareDef.get_locality ident ~kind:"axiom" local in
- let inl = match nl with
+ let inl = let open Declaremods in match nl with
| NoInline -> None
| DefaultInline -> Some (Flags.get_inline_level())
| InlineAt i -> Some i
diff --git a/vernac/comAssumption.mli b/vernac/comAssumption.mli
index 56e324376..2f2c7c4e2 100644
--- a/vernac/comAssumption.mli
+++ b/vernac/comAssumption.mli
@@ -11,7 +11,6 @@
open Names
open Constr
open Entries
-open Globnames
open Vernacexpr
open Constrexpr
open Decl_kinds
@@ -19,7 +18,7 @@ open Decl_kinds
(** {6 Parameters/Assumptions} *)
val do_assumptions : locality * polymorphic * assumption_object_kind ->
- Vernacexpr.inline -> (ident_decl list * constr_expr) with_coercion list -> bool
+ Declaremods.inline -> (ident_decl list * constr_expr) with_coercion list -> bool
(************************************************************************)
(** Internal API *)
@@ -32,5 +31,5 @@ val do_assumptions : locality * polymorphic * assumption_object_kind ->
val declare_assumption : coercion_flag -> assumption_kind ->
types in_constant_universes_entry ->
Universes.universe_binders -> Impargs.manual_implicits ->
- bool (** implicit *) -> Vernacexpr.inline -> variable CAst.t ->
- global_reference * Univ.Instance.t * bool
+ bool (** implicit *) -> Declaremods.inline -> variable CAst.t ->
+ GlobRef.t * Univ.Instance.t * bool
diff --git a/vernac/comDefinition.ml b/vernac/comDefinition.ml
index b18a60a1f..9aa61ab46 100644
--- a/vernac/comDefinition.ml
+++ b/vernac/comDefinition.ml
@@ -88,8 +88,8 @@ let interp_definition pl bl poly red_option c ctypopt =
let evd = Evd.minimize_universes evd in
(* Substitute evars and universes, and add parameters.
Note: in program mode some evars may remain. *)
- let ctx = List.map (EConstr.to_rel_decl evd) ctx in
- let c = Term.it_mkLambda_or_LetIn (EConstr.to_constr evd c) ctx in
+ let 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
(* Keep only useful universes. *)
let uvars_fold uvars c =
diff --git a/vernac/comFixpoint.ml b/vernac/comFixpoint.ml
index a794c2db0..7b382dacc 100644
--- a/vernac/comFixpoint.ml
+++ b/vernac/comFixpoint.ml
@@ -224,8 +224,9 @@ let interp_recursive ~program_mode ~cofix fixl notations =
(* Instantiate evars and check all are resolved *)
let sigma = solve_unif_constraints_with_heuristics env_rec sigma in
- let sigma, _ = nf_evars_and_universes sigma in
- let fixdefs = List.map (fun c -> Option.map EConstr.(to_constr sigma) c) fixdefs in
+ let sigma = Evd.minimize_universes sigma in
+ (* XXX: We still have evars here in Program *)
+ let fixdefs = List.map (fun c -> Option.map EConstr.(to_constr ~abort_on_undefined_evars:false sigma) c) fixdefs in
let fixtypes = List.map EConstr.(to_constr sigma) fixtypes in
let fixctxs = List.map (fun (_,ctx) -> ctx) fixctxs in
diff --git a/vernac/comInductive.ml b/vernac/comInductive.ml
index db2f16525..101298ef4 100644
--- a/vernac/comInductive.ml
+++ b/vernac/comInductive.ml
@@ -261,7 +261,7 @@ let check_param = function
| CLocalAssum (nas, Default _, _) -> List.iter check_named nas
| CLocalAssum (nas, Generalized _, _) -> ()
| CLocalPattern {CAst.loc} ->
- Loc.raise ?loc (Stream.Error "pattern with quote not allowed here.")
+ Loc.raise ?loc (Stream.Error "pattern with quote not allowed here")
let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
check_all_names_different indl;
@@ -304,14 +304,16 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
(* Try further to solve evars, and instantiate them *)
let sigma = solve_remaining_evars all_and_fail_flags env_params sigma Evd.empty in
(* Compute renewed arities *)
- let sigma, nf = nf_evars_and_universes sigma in
+ let sigma = Evd.minimize_universes sigma in
+ let nf = Evarutil.nf_evars_universes sigma in
let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf cl,impsl)) constructors in
let arities = List.map EConstr.(to_constr sigma) arities in
let sigma = List.fold_left2 (fun sigma ty poly -> make_conclusion_flexible sigma ty poly) sigma arities aritypoly in
let sigma, arities = inductive_levels env_ar_params sigma poly arities constructors in
- let sigma, nf' = nf_evars_and_universes sigma in
- let arities = List.map nf' arities in
- let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf' cl,impsl)) constructors in
+ let sigma = Evd.minimize_universes sigma in
+ let nf = Evarutil.nf_evars_universes sigma in
+ let arities = List.map nf arities in
+ let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf cl,impsl)) constructors in
let ctx_params = List.map Termops.(map_rel_decl (EConstr.to_constr sigma)) ctx_params in
let uctx = Evd.check_univ_decl ~poly sigma decl in
List.iter (fun c -> check_evars env_params Evd.empty sigma (EConstr.of_constr c)) arities;
diff --git a/vernac/comProgramFixpoint.ml b/vernac/comProgramFixpoint.ml
index b95741ca4..745f1df1d 100644
--- a/vernac/comProgramFixpoint.ml
+++ b/vernac/comProgramFixpoint.ml
@@ -229,7 +229,8 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
in
(* XXX: Capturing sigma here... bad bad *)
let hook = Lemmas.mk_hook (hook sigma) in
- let fullcoqc = EConstr.to_constr sigma def in
+ (* XXX: Grounding non-ground terms here... bad bad *)
+ let fullcoqc = EConstr.to_constr ~abort_on_undefined_evars:false sigma def in
let fullctyp = EConstr.to_constr sigma typ in
Obligations.check_evars env sigma;
let evars, _, evars_def, evars_typ =
@@ -261,9 +262,10 @@ let do_program_recursive local poly fixkind fixl ntns =
let collect_evars id def typ imps =
(* Generalize by the recursive prototypes *)
let def =
- EConstr.to_constr evd (Termops.it_mkNamedLambda_or_LetIn (EConstr.of_constr def) rec_sign)
+ EConstr.to_constr ~abort_on_undefined_evars:false evd (Termops.it_mkNamedLambda_or_LetIn (EConstr.of_constr def) rec_sign)
and typ =
- EConstr.to_constr evd (Termops.it_mkNamedProd_or_LetIn (EConstr.of_constr typ) rec_sign)
+ (* Worrying... *)
+ EConstr.to_constr ~abort_on_undefined_evars:false evd (Termops.it_mkNamedProd_or_LetIn (EConstr.of_constr typ) rec_sign)
in
let evm = collect_evars_of_term evd def typ in
let evars, _, def, typ =
diff --git a/vernac/declareDef.mli b/vernac/declareDef.mli
index 010874e23..12973f51b 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
+ GlobRef.t Lemmas.declaration_hook -> GlobRef.t
val declare_fix : ?opaque:bool -> definition_kind ->
Universes.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/himsg.ml b/vernac/himsg.ml
index 698ee4703..acb461cac 100644
--- a/vernac/himsg.ml
+++ b/vernac/himsg.ml
@@ -75,11 +75,7 @@ let rec contract3' env sigma a b c = function
| MetaOccurInBody _ | InstanceNotSameType _ | ProblemBeyondCapabilities
| UnifUnivInconsistency _ as x -> contract3 env sigma a b c, x
| CannotSolveConstraint ((pb,env',t,u),x) ->
- let t = EConstr.of_constr t in
- let u = EConstr.of_constr u in
let env',t,u = contract2 env' sigma t u in
- let t = EConstr.Unsafe.to_constr t in
- let u = EConstr.Unsafe.to_constr u in
let y,x = contract3' env sigma a b c x in
y,CannotSolveConstraint ((pb,env',t,u),x)
@@ -322,8 +318,6 @@ let explain_unification_error env sigma p1 p2 = function
else
[str "universe inconsistency"]
| CannotSolveConstraint ((pb,env,t,u),e) ->
- let t = EConstr.of_constr t in
- let u = EConstr.of_constr u in
let env = make_all_name_different env sigma in
(strbrk "cannot satisfy constraint " ++ pr_leconstr_env env sigma t ++
str " == " ++ pr_leconstr_env env sigma u)
@@ -562,9 +556,9 @@ let rec explain_evar_kind env sigma evk ty = function
| Evar_kinds.SubEvar (where,evk') ->
let evi = Evd.find sigma evk' in
let pc = match evi.evar_body with
- | Evar_defined c -> pr_leconstr_env env sigma (EConstr.of_constr c)
+ | Evar_defined c -> pr_leconstr_env env sigma c
| Evar_empty -> assert false in
- let ty' = EConstr.of_constr evi.evar_concl in
+ let ty' = evi.evar_concl in
(match where with
| Some Evar_kinds.Body -> str "the body of "
| Some Evar_kinds.Domain -> str "the domain of "
@@ -577,11 +571,11 @@ let rec explain_evar_kind env sigma evk ty = function
(pr_leconstr_env env sigma ty') (snd evi.evar_source)
let explain_typeclass_resolution env sigma evi k =
- match Typeclasses.class_of_constr sigma (EConstr.of_constr evi.evar_concl) with
+ match Typeclasses.class_of_constr sigma evi.evar_concl with
| Some _ ->
let env = Evd.evar_filtered_env evi in
fnl () ++ str "Could not find an instance for " ++
- pr_lconstr_env env sigma evi.evar_concl ++
+ pr_leconstr_env env sigma evi.evar_concl ++
pr_trailing_ne_context_of env sigma
| _ -> mt()
@@ -590,14 +584,14 @@ let explain_placeholder_kind env sigma c e =
| Some (SeveralInstancesFound n) ->
strbrk " (several distinct possible type class instances found)"
| None ->
- match Typeclasses.class_of_constr sigma (EConstr.of_constr c) with
+ match Typeclasses.class_of_constr sigma c with
| Some _ -> strbrk " (no type class instance found)"
| _ -> mt ()
let explain_unsolvable_implicit env sigma evk explain =
let evi = Evarutil.nf_evar_info sigma (Evd.find_undefined sigma evk) in
let env = Evd.evar_filtered_env evi in
- let type_of_hole = pr_lconstr_env env sigma evi.evar_concl in
+ let type_of_hole = pr_leconstr_env env sigma evi.evar_concl in
let pe = pr_trailing_ne_context_of env sigma in
strbrk "Cannot infer " ++
explain_evar_kind env sigma evk type_of_hole (snd evi.evar_source) ++
@@ -640,8 +634,7 @@ let explain_refiner_cannot_generalize env sigma ty =
pr_leconstr_env env sigma ty ++ str "."
let explain_no_occurrence_found env sigma c id =
- let c = EConstr.to_constr sigma c in
- str "Found no subterm matching " ++ pr_lconstr_env env sigma c ++
+ str "Found no subterm matching " ++ pr_leconstr_env env sigma c ++
str " in " ++
(match id with
| Some id -> Id.print id
@@ -766,7 +759,7 @@ let pr_constraints printenv env sigma evars cstrs =
let evs =
prlist
(fun (ev, evi) -> fnl () ++ pr_existential_key sigma ev ++
- str " : " ++ pr_lconstr_env env' sigma evi.evar_concl ++ fnl ()) l
+ str " : " ++ pr_leconstr_env env' sigma evi.evar_concl ++ fnl ()) l
in
h 0 (pe ++ evs ++ pr_evar_constraints sigma cstrs)
else
diff --git a/vernac/lemmas.ml b/vernac/lemmas.ml
index 30dd6ec74..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
@@ -451,7 +451,7 @@ let start_proof_com ?inference_hook kind thms hook =
(ids, imps @ lift_implicits (Context.Rel.nhyps ctx) imps'))))
evd thms in
let recguard,thms,snl = look_for_possibly_mutual_statements evd thms in
- let evd, _nf = Evarutil.nf_evars_and_universes evd in
+ let evd = Evd.minimize_universes evd in
(* XXX: This nf_evar is critical too!! We are normalizing twice if
you look at the previous lines... *)
let thms = List.map (fun (n, (t, info)) -> (n, (nf_evar evd t, info))) thms in
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/obligations.ml b/vernac/obligations.ml
index 064e40b9b..ae1065ef5 100644
--- a/vernac/obligations.ml
+++ b/vernac/obligations.ml
@@ -209,8 +209,10 @@ let eterm_obligations env name evm fs ?status t ty =
List.fold_right
(fun (id, (n, nstr), ev) l ->
let hyps = Evd.evar_filtered_context ev in
- let hyps = trunc_named_context nc_len hyps in
- let evtyp, deps, transp = etype_of_evar l hyps ev.evar_concl in
+ let hyps = trunc_named_context nc_len hyps in
+ let hyps = EConstr.Unsafe.to_named_context hyps in
+ let concl = EConstr.Unsafe.to_constr ev.evar_concl in
+ let evtyp, deps, transp = etype_of_evar l hyps concl in
let evtyp, hyps, chop =
match chop_product fs evtyp with
| Some t -> t, trunc_named_context fs hyps, fs
@@ -356,7 +358,7 @@ let _ =
optread = get_shrink_obligations;
optwrite = set_shrink_obligations; }
-let evar_of_obligation o = make_evar (Global.named_context_val ()) o.obl_type
+let evar_of_obligation o = make_evar (Global.named_context_val ()) (EConstr.of_constr o.obl_type)
let get_obligation_body expand obl =
match obl.obl_body with
@@ -559,7 +561,7 @@ let declare_mutual_definition l =
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
@@ -742,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
@@ -768,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)
@@ -813,10 +815,9 @@ let rec string_of_list sep f = function
let solve_by_tac name evi t poly ctx =
let id = name in
- let concl = EConstr.of_constr evi.evar_concl in
(* spiwack: the status is dropped. *)
let (entry,_,ctx') = Pfedit.build_constant_by_tactic
- id ~goal_kind:(goal_kind poly) ctx evi.evar_hyps concl (Tacticals.New.tclCOMPLETE t) in
+ id ~goal_kind:(goal_kind poly) ctx evi.evar_hyps evi.evar_concl (Tacticals.New.tclCOMPLETE t) in
let env = Global.env () in
let entry = Safe_typing.inline_private_constants_in_definition_entry env entry in
let body, () = Future.force entry.const_entry_body in
@@ -890,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 6e745b2af..b89c0060d 100644
--- a/vernac/record.ml
+++ b/vernac/record.ml
@@ -114,7 +114,7 @@ let typecheck_params_and_fields finite def id poly pl t ps nots fs =
(function CLocalDef (b, _, _) -> error default_binder_kind b
| CLocalAssum (ls, bk, ce) -> List.iter (error bk) ls
| CLocalPattern {CAst.loc} ->
- Loc.raise ?loc (Stream.Error "pattern with quote not allowed in record parameters.")) ps
+ Loc.raise ?loc (Stream.Error "pattern with quote not allowed in record parameters")) ps
in
let sigma, (impls_env, ((env1,newps), imps)) = interp_context_evars env0 sigma ps in
let sigma, typ, sort, template = match t with
@@ -168,7 +168,7 @@ let typecheck_params_and_fields finite def id poly pl t ps nots fs =
EConstr.mkSort (Sorts.sort_of_univ univ)
else sigma, typ
in
- let sigma, _ = Evarutil.nf_evars_and_universes sigma in
+ let sigma = Evd.minimize_universes sigma in
let newfs = List.map (EConstr.to_rel_decl sigma) newfs in
let newps = List.map (EConstr.to_rel_decl sigma) newps in
let typ = EConstr.to_constr sigma typ in
diff --git a/vernac/record.mli b/vernac/record.mli
index 992da2aa5..308c9e9b9 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
@@ -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 b44c7cccb..f0e41d27c 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -449,7 +449,7 @@ let start_proof_and_print k l hook =
let evi = Evarutil.nf_evar_info sigma evi in
let env = Evd.evar_filtered_env evi in
try
- let concl = EConstr.of_constr evi.Evd.evar_concl in
+ let concl = evi.Evd.evar_concl in
if not (Evarutil.is_ground_env sigma env &&
Evarutil.is_ground_term sigma concl)
then raise Exit;
@@ -672,7 +672,7 @@ let vernac_declare_module export {loc;v=id} binders_ast mty_ast =
else (idl,ty)) binders_ast in
let mp =
Declaremods.declare_module Modintern.interp_module_ast
- id binders_ast (Enforce mty_ast) []
+ id binders_ast (Declaremods.Enforce mty_ast) []
in
Dumpglob.dump_moddef ?loc mp "mod";
Flags.if_verbose Feedback.msg_info (str "Module " ++ Id.print id ++ str " is declared");
@@ -909,7 +909,7 @@ let vernac_set_used_variables e =
if List.is_empty to_clear then (p, ())
else
let tac = Tactics.clear to_clear in
- fst (Pfedit.solve SelectAll None tac p), ()
+ fst (Pfedit.solve Goal_select.SelectAll None tac p), ()
end
(*****************************)
@@ -1465,22 +1465,22 @@ let _ =
optkey = ["Printing";"Universes"];
optread = (fun () -> !Constrextern.print_universes);
optwrite = (fun b -> Constrextern.print_universes:=b) }
-
+
let _ =
declare_bool_option
{ optdepr = false;
optname = "dumping bytecode after compilation";
optkey = ["Dump";"Bytecode"];
- optread = Flags.get_dump_bytecode;
- optwrite = Flags.set_dump_bytecode }
+ optread = (fun () -> !Cbytegen.dump_bytecode);
+ optwrite = (:=) Cbytegen.dump_bytecode }
let _ =
declare_bool_option
{ optdepr = false;
optname = "dumping VM lambda code after compilation";
optkey = ["Dump";"Lambda"];
- optread = Flags.get_dump_lambda;
- optwrite = Flags.set_dump_lambda }
+ optread = (fun () -> !Clambda.dump_lambda);
+ optwrite = (:=) Clambda.dump_lambda }
let _ =
declare_bool_option
@@ -1611,7 +1611,7 @@ let get_current_context_of_args = function
let query_command_selector ?loc = function
| None -> None
- | Some (SelectNth n) -> Some n
+ | Some (Goal_select.SelectNth n) -> Some n
| _ -> user_err ?loc ~hdr:"query_command_selector"
(str "Query commands only support the single numbered goal selector.")
@@ -1619,17 +1619,16 @@ let vernac_check_may_eval ~atts redexp glopt rc =
let glopt = query_command_selector ?loc:atts.loc glopt in
let (sigma, env) = get_current_context_of_args glopt in
let sigma', c = interp_open_constr env sigma rc in
- let c = EConstr.Unsafe.to_constr c in
let sigma' = Evarconv.solve_unif_constraints_with_heuristics env sigma' in
Evarconv.check_problems_are_solved env sigma';
- let sigma',nf = Evarutil.nf_evars_and_universes sigma' in
+ let sigma' = Evd.minimize_universes sigma' in
let uctx = Evd.universe_context_set sigma' in
let env = Environ.push_context_set uctx (Evarutil.nf_env_evar sigma' env) in
- let c = nf c in
let j =
- if Evarutil.has_undefined_evars sigma' (EConstr.of_constr c) then
- Evarutil.j_nf_evar sigma' (Retyping.get_judgment_of env sigma' (EConstr.of_constr c))
+ if Evarutil.has_undefined_evars sigma' c then
+ Evarutil.j_nf_evar sigma' (Retyping.get_judgment_of env sigma' c)
else
+ let c = EConstr.to_constr sigma' c in
(* OK to call kernel which does not support evars *)
Termops.on_judgment EConstr.of_constr (Arguments_renaming.rename_typing env c)
in
@@ -1912,7 +1911,7 @@ let vernac_subproof gln =
Proof_global.simple_with_current_proof (fun _ p ->
match gln with
| None -> Proof.focus subproof_cond () 1 p
- | Some (SelectNth n) -> Proof.focus subproof_cond () n p
+ | Some (Goal_select.SelectNth n) -> Proof.focus subproof_cond () n p
| _ -> user_err ~hdr:"bracket_selector"
(str "Brackets only support the single numbered goal selector."))