aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml14
-rw-r--r--.gitattributes3
-rw-r--r--.github/CODEOWNERS25
-rw-r--r--.gitignore18
-rw-r--r--.gitlab-ci.yml163
-rw-r--r--.travis.yml10
-rw-r--r--CHANGES39
-rw-r--r--CONTRIBUTING.md10
-rw-r--r--CREDITS3
-rw-r--r--INSTALL27
-rw-r--r--INSTALL.doc6
-rw-r--r--META.coq2
-rw-r--r--Makefile5
-rw-r--r--Makefile.ci1
-rw-r--r--Makefile.doc140
-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.ml15
-rw-r--r--clib/cArray.mli8
-rw-r--r--clib/cList.ml2
-rw-r--r--clib/cList.mli5
-rw-r--r--clib/option.mli1
-rw-r--r--default.nix8
-rwxr-xr-xdev/build/osx/make-macos-dmg.sh12
-rwxr-xr-xdev/build/windows/MakeCoq_88git_installer.bat27
-rw-r--r--dev/build/windows/MakeCoq_MinGW.bat3
-rw-r--r--dev/build/windows/configure_profile.sh24
-rw-r--r--dev/build/windows/difftar-folder.sh22
-rw-r--r--dev/build/windows/makecoq_mingw.sh273
-rw-r--r--dev/ci/appveyor.sh4
-rwxr-xr-x[-rw-r--r--]dev/ci/ci-basic-overlay.sh8
-rwxr-xr-xdev/ci/ci-bignums.sh8
-rwxr-xr-xdev/ci/ci-color.sh6
-rw-r--r--dev/ci/ci-common.sh9
-rwxr-xr-xdev/ci/ci-compcert.sh8
-rwxr-xr-xdev/ci/ci-coq-dpdgraph.sh8
-rwxr-xr-xdev/ci/ci-coquelicot.sh8
-rwxr-xr-xdev/ci/ci-corn.sh8
-rwxr-xr-xdev/ci/ci-cpdt.sh3
-rwxr-xr-xdev/ci/ci-elpi.sh8
-rwxr-xr-xdev/ci/ci-equations.sh8
-rwxr-xr-xdev/ci/ci-fcsl-pcm.sh12
-rwxr-xr-xdev/ci/ci-fiat-crypto.sh10
-rwxr-xr-xdev/ci/ci-fiat-parsers.sh8
-rwxr-xr-xdev/ci/ci-flocq.sh8
-rwxr-xr-xdev/ci/ci-formal-topology.sh8
-rwxr-xr-xdev/ci/ci-geocoq.sh8
-rwxr-xr-xdev/ci/ci-hott.sh8
-rwxr-xr-xdev/ci/ci-iris-lambda-rust.sh31
-rwxr-xr-xdev/ci/ci-ltac2.sh8
-rwxr-xr-xdev/ci/ci-math-classes.sh8
-rwxr-xr-xdev/ci/ci-math-comp.sh8
-rwxr-xr-xdev/ci/ci-metacoq.sh10
-rwxr-xr-xdev/ci/ci-sf.sh29
-rwxr-xr-xdev/ci/ci-template.sh8
-rwxr-xr-xdev/ci/ci-tlc.sh8
-rwxr-xr-xdev/ci/ci-unimath.sh9
-rwxr-xr-xdev/ci/ci-vst.sh8
-rw-r--r--dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh2
-rw-r--r--dev/ci/user-overlays/06405-maximedenes-rm-local-polymorphic-flag.sh4
-rw-r--r--dev/ci/user-overlays/06454-ejgallego-evar+strict_to_constr.sh8
-rw-r--r--dev/ci/user-overlays/06482-ppedrot-check-poly-effects.sh4
-rw-r--r--dev/ci/user-overlays/06493-gares-API-remove-big-file.sh8
-rw-r--r--dev/ci/user-overlays/06511-ejgallego-econstr+more_fix.sh7
-rw-r--r--dev/ci/user-overlays/06535-fix-push-rel-to-named.sh4
-rw-r--r--dev/ci/user-overlays/06676-gares-proofview-goals-come-with-a-state.sh6
-rw-r--r--dev/ci/user-overlays/06686-ccnv-no-proj.sh4
-rw-r--r--dev/ci/user-overlays/06745-ejgallego-located+vernac.sh13
-rw-r--r--dev/ci/user-overlays/06775-univ-cumul-weak.sh4
-rw-r--r--dev/ci/user-overlays/06831-ejgallego-located+vernac_2.sh14
-rw-r--r--dev/ci/user-overlays/06837-ejgallego-located+libnames.sh15
-rw-r--r--dev/ci/user-overlays/06869-ejgallego-ssr+correct_packing.sh12
-rw-r--r--dev/ci/user-overlays/06923-ppedrot-export-options.sh7
-rw-r--r--dev/ci/user-overlays/06960-ejgallego-ltac+tacdepr.sh12
-rw-r--r--dev/ci/user-overlays/07136-evar-map-econstr.sh7
-rw-r--r--dev/ci/user-overlays/README.md2
-rw-r--r--dev/doc/MERGING.md52
-rw-r--r--dev/doc/changes.md20
-rwxr-xr-xdev/lint-repository.sh2
-rwxr-xr-xdev/tools/backport-pr.sh10
-rwxr-xr-xdev/tools/check-overlays.sh11
-rwxr-xr-xdev/tools/merge-pr.sh65
-rwxr-xr-xdev/tools/pre-commit8
-rw-r--r--dev/top_printers.ml2
-rw-r--r--doc/LICENSE18
-rw-r--r--doc/RecTutorial/RecTutorial.tex6
-rw-r--r--doc/RecTutorial/RecTutorial.v2
-rw-r--r--doc/refman/AddRefMan-pre.tex63
-rw-r--r--doc/refman/AsyncProofs.tex221
-rw-r--r--doc/refman/Classes.tex578
-rw-r--r--doc/refman/Coercion.tex563
-rw-r--r--doc/refman/Extraction.tex620
-rw-r--r--doc/refman/Misc.tex63
-rw-r--r--doc/refman/Nsatz.tex102
-rw-r--r--doc/refman/Polynom.tex736
-rw-r--r--doc/refman/Program.tex329
-rw-r--r--doc/refman/RefMan-gal.tex1737
-rw-r--r--doc/refman/RefMan-ltac.tex1829
-rw-r--r--doc/refman/RefMan-oth.tex1224
-rw-r--r--doc/refman/RefMan-pro.tex581
-rw-r--r--doc/refman/RefMan-uti.tex482
-rw-r--r--doc/refman/Reference-Manual.tex153
-rw-r--r--doc/refman/Setoid.tex842
-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/coqdoc.tex573
-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.rst3
-rw-r--r--doc/sphinx/addendum/extraction.rst585
-rw-r--r--doc/sphinx/addendum/generalized-rewriting.rst847
-rw-r--r--doc/sphinx/addendum/implicit-coercions.rst464
-rw-r--r--doc/sphinx/addendum/micromega.rst64
-rw-r--r--doc/sphinx/addendum/miscellaneous-extensions.rst59
-rw-r--r--doc/sphinx/addendum/nsatz.rst101
-rw-r--r--doc/sphinx/addendum/parallel-proof-processing.rst229
-rw-r--r--doc/sphinx/addendum/program.rst382
-rw-r--r--doc/sphinx/addendum/ring.rst770
-rw-r--r--doc/sphinx/addendum/type-classes.rst571
-rw-r--r--doc/sphinx/addendum/universe-polymorphism.rst445
-rw-r--r--doc/sphinx/biblio.bib15
-rw-r--r--doc/sphinx/credits.rst40
-rw-r--r--doc/sphinx/index.rst15
-rw-r--r--doc/sphinx/introduction.rst6
-rw-r--r--doc/sphinx/language/cic.rst197
-rw-r--r--doc/sphinx/language/coq-library.rst17
-rw-r--r--doc/sphinx/language/gallina-extensions.rst424
-rw-r--r--doc/sphinx/language/gallina-specification-language.rst1376
-rw-r--r--doc/sphinx/practical-tools/coq-commands.rst33
-rw-r--r--doc/sphinx/practical-tools/coqide.rst20
-rw-r--r--doc/sphinx/practical-tools/utilities.rst1008
-rw-r--r--doc/sphinx/proof-engine/detailed-tactic-examples.rst17
-rw-r--r--doc/sphinx/proof-engine/ltac.rst1300
-rw-r--r--doc/sphinx/proof-engine/proof-handling.rst600
-rw-r--r--doc/sphinx/proof-engine/ssreflect-proof-language.rst136
-rw-r--r--doc/sphinx/proof-engine/tactics.rst774
-rw-r--r--doc/sphinx/proof-engine/vernacular-commands.rst1357
-rw-r--r--doc/sphinx/replaces.rst12
-rw-r--r--doc/sphinx/user-extensions/proof-schemes.rst66
-rw-r--r--doc/sphinx/user-extensions/syntax-extensions.rst76
-rw-r--r--doc/tools/coqrst/coqdomain.py17
-rw-r--r--doc/tools/coqrst/notations/CoqNotations.ttfbin0 -> 37988 bytes
-rw-r--r--doc/tools/coqrst/notations/TacticNotations.g11
-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.py9
-rw-r--r--doc/tools/coqrst/notations/sphinx.py21
-rw-r--r--engine/eConstr.ml142
-rw-r--r--engine/eConstr.mli22
-rw-r--r--engine/evarutil.ml55
-rw-r--r--engine/evarutil.mli2
-rw-r--r--engine/evd.ml105
-rw-r--r--engine/evd.mli133
-rw-r--r--engine/proofview.ml21
-rw-r--r--engine/proofview.mli9
-rw-r--r--engine/termops.ml17
-rwxr-xr-xide/MacOS/relatify_with-respect-to_.sh15
-rw-r--r--ide/coqOps.ml6
-rw-r--r--ide/ide_slave.ml2
-rw-r--r--interp/constrextern.ml48
-rw-r--r--interp/constrintern.ml2
-rw-r--r--interp/impargs.ml294
-rw-r--r--interp/impargs.mli2
-rw-r--r--interp/implicit_quantifiers.ml36
-rw-r--r--interp/notation_ops.ml6
-rw-r--r--intf/misctypes.ml13
-rw-r--r--intf/pattern.ml5
-rw-r--r--intf/vernacexpr.ml20
-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.ml27
-rw-r--r--kernel/constr.ml2
-rw-r--r--kernel/constr.mli6
-rw-r--r--kernel/csymtable.ml31
-rw-r--r--kernel/csymtable.mli2
-rw-r--r--kernel/environ.mli2
-rw-r--r--kernel/esubst.ml10
-rw-r--r--kernel/esubst.mli6
-rw-r--r--kernel/kernel.mllib2
-rw-r--r--kernel/names.mli19
-rw-r--r--kernel/term.ml2
-rw-r--r--kernel/term.mli6
-rw-r--r--kernel/typeops.mli4
-rw-r--r--kernel/univ.ml47
-rw-r--r--kernel/univ.mli13
-rw-r--r--kernel/vm.ml9
-rw-r--r--kernel/vmvalues.ml24
-rw-r--r--kernel/vmvalues.mli6
-rw-r--r--lib/aux_file.ml2
-rw-r--r--lib/cWarnings.ml4
-rw-r--r--lib/cWarnings.mli2
-rw-r--r--lib/loc.ml5
-rw-r--r--lib/loc.mli4
-rw-r--r--parsing/g_vernac.ml445
-rw-r--r--plugins/cc/ccalgo.ml48
-rw-r--r--plugins/cc/cctac.ml2
-rw-r--r--plugins/firstorder/sequent.ml8
-rw-r--r--plugins/funind/functional_principles_proofs.ml3
-rw-r--r--plugins/funind/functional_principles_types.ml16
-rw-r--r--plugins/funind/glob_term_to_relation.ml4
-rw-r--r--plugins/funind/glob_termops.ml7
-rw-r--r--plugins/funind/indfun.ml26
-rw-r--r--plugins/funind/invfun.ml10
-rw-r--r--plugins/ltac/extratactics.ml42
-rw-r--r--plugins/ltac/pltac.mli2
-rw-r--r--plugins/ltac/pptactic.mli2
-rw-r--r--plugins/ltac/rewrite.ml8
-rw-r--r--plugins/ltac/tacarg.mli6
-rw-r--r--plugins/ltac/tacexpr.ml18
-rw-r--r--plugins/ltac/tacexpr.mli18
-rw-r--r--plugins/ltac/tacinterp.ml3
-rw-r--r--plugins/ltac/tactic_debug.ml13
-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/ssr/ssrcommon.ml25
-rw-r--r--plugins/ssr/ssrelim.ml2
-rw-r--r--plugins/ssr/ssrequality.ml17
-rw-r--r--plugins/ssr/ssripats.ml33
-rw-r--r--plugins/ssr/ssrparser.ml413
-rw-r--r--plugins/ssr/ssrview.ml4
-rw-r--r--plugins/ssrmatching/ssrmatching.ml424
-rw-r--r--pretyping/cases.ml5
-rw-r--r--pretyping/cbv.ml2
-rw-r--r--pretyping/cbv.mli2
-rw-r--r--pretyping/coercion.ml2
-rw-r--r--pretyping/constr_matching.ml49
-rw-r--r--pretyping/detyping.ml163
-rw-r--r--pretyping/detyping.mli7
-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/glob_ops.ml2
-rw-r--r--pretyping/inductiveops.mli4
-rw-r--r--pretyping/nativenorm.ml6
-rw-r--r--pretyping/patternops.ml134
-rw-r--r--pretyping/pretyping.ml10
-rw-r--r--pretyping/reductionops.ml23
-rw-r--r--pretyping/reductionops.mli4
-rw-r--r--pretyping/retyping.ml10
-rw-r--r--pretyping/retyping.mli2
-rw-r--r--pretyping/tacred.ml6
-rw-r--r--pretyping/typeclasses.ml2
-rw-r--r--pretyping/typing.ml9
-rw-r--r--pretyping/typing.mli2
-rw-r--r--pretyping/unification.ml32
-rw-r--r--pretyping/vnorm.ml6
-rw-r--r--printing/ppvernac.ml36
-rw-r--r--printing/printer.ml20
-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/pfedit.ml2
-rw-r--r--proofs/proof_global.ml2
-rw-r--r--proofs/refine.ml16
-rw-r--r--stm/proofBlockDelimiter.ml2
-rw-r--r--stm/stm.ml143
-rw-r--r--stm/stm.mli47
-rw-r--r--stm/vernac_classifier.ml14
-rw-r--r--stm/workerLoop.ml4
-rw-r--r--stm/workerLoop.mli4
-rw-r--r--tactics/auto.ml5
-rw-r--r--tactics/class_tactics.ml6
-rw-r--r--tactics/equality.ml13
-rw-r--r--tactics/equality.mli10
-rw-r--r--tactics/hints.ml4
-rw-r--r--tactics/inv.ml7
-rw-r--r--tactics/inv.mli5
-rw-r--r--tactics/tacticals.ml34
-rw-r--r--tactics/tacticals.mli2
-rw-r--r--tactics/tactics.ml40
-rw-r--r--tactics/tactics.mli8
-rw-r--r--test-suite/bugs/closed/1341.v2
-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/1844.v2
-rw-r--r--test-suite/bugs/closed/1891.v2
-rw-r--r--test-suite/bugs/closed/1951.v2
-rw-r--r--test-suite/bugs/closed/1981.v2
-rw-r--r--test-suite/bugs/closed/2001.v2
-rw-r--r--test-suite/bugs/closed/2362.v2
-rw-r--r--test-suite/bugs/closed/2378.v6
-rw-r--r--test-suite/bugs/closed/2404.v4
-rw-r--r--test-suite/bugs/closed/2456.v (renamed from test-suite/bugs/opened/2456.v)9
-rw-r--r--test-suite/bugs/closed/2584.v2
-rw-r--r--test-suite/bugs/closed/2667.v4
-rw-r--r--test-suite/bugs/closed/2729.v4
-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/2830.v10
-rw-r--r--test-suite/bugs/closed/3068.v2
-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/3513.v2
-rw-r--r--test-suite/bugs/closed/3647.v6
-rw-r--r--test-suite/bugs/closed/3732.v2
-rw-r--r--test-suite/bugs/closed/4095.v2
-rw-r--r--test-suite/bugs/closed/4865.v2
-rw-r--r--test-suite/bugs/closed/6631.v7
-rw-r--r--test-suite/bugs/closed/6956.v13
-rw-r--r--test-suite/bugs/closed/7092.v70
-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/3295.v4
-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
-rw-r--r--test-suite/complexity/injection.v2
-rwxr-xr-xtest-suite/coq-makefile/coqdoc1/run.sh10
-rwxr-xr-xtest-suite/coq-makefile/coqdoc2/run.sh8
-rwxr-xr-xtest-suite/coq-makefile/findlib-package/run.sh3
-rwxr-xr-xtest-suite/coq-makefile/mlpack1/run.sh2
-rwxr-xr-xtest-suite/coq-makefile/mlpack2/run.sh2
-rwxr-xr-xtest-suite/coq-makefile/multiroot/run.sh7
-rwxr-xr-xtest-suite/coq-makefile/native1/run.sh8
-rwxr-xr-xtest-suite/coq-makefile/plugin1/run.sh2
-rwxr-xr-xtest-suite/coq-makefile/plugin2/run.sh2
-rwxr-xr-xtest-suite/coq-makefile/plugin3/run.sh2
-rwxr-xr-xtest-suite/coq-makefile/quick2vo/run.sh4
-rwxr-xr-xtest-suite/coq-makefile/template/init.sh3
-rwxr-xr-xtest-suite/coq-makefile/template/path-init.sh1
-rwxr-xr-xtest-suite/coq-makefile/timing/precomputed-time-tests/run.sh7
-rwxr-xr-xtest-suite/coq-makefile/timing/run.sh29
-rwxr-xr-xtest-suite/coq-makefile/uninstall1/run.sh7
-rwxr-xr-xtest-suite/coq-makefile/uninstall2/run.sh7
-rwxr-xr-xtest-suite/coq-makefile/vio2vo/run.sh4
-rw-r--r--test-suite/failure/check.v2
-rwxr-xr-xtest-suite/misc/deps-checksum.sh1
-rwxr-xr-xtest-suite/misc/deps-order.sh9
-rwxr-xr-xtest-suite/misc/deps-utf8.sh9
-rwxr-xr-xtest-suite/misc/exitstatus.sh7
-rwxr-xr-xtest-suite/misc/printers.sh5
-rwxr-xr-xtest-suite/misc/universes.sh5
-rw-r--r--test-suite/modules/PO.v4
-rw-r--r--test-suite/modules/Przyklad.v2
-rw-r--r--test-suite/output/Notations3.out8
-rw-r--r--test-suite/output/Notations3.v16
-rw-r--r--test-suite/output/Projections.out2
-rw-r--r--test-suite/output/Projections.v11
-rw-r--r--test-suite/output/bug5778.out4
-rw-r--r--test-suite/output/bug6404.out4
-rw-r--r--test-suite/output/bug6404.v7
-rw-r--r--test-suite/output/ssr_clear.out3
-rw-r--r--test-suite/output/ssr_clear.v6
-rw-r--r--test-suite/prerequisite/make_local.v3
-rw-r--r--test-suite/success/AdvancedTypeClasses.v4
-rw-r--r--test-suite/success/ImplicitArguments.v2
-rw-r--r--test-suite/success/Inductive.v2
-rw-r--r--test-suite/success/Inversion.v2
-rw-r--r--test-suite/success/RecTutorial.v12
-rw-r--r--test-suite/success/Record.v2
-rw-r--r--test-suite/success/Scopes.v2
-rw-r--r--test-suite/success/ShowExtraction.v2
-rw-r--r--test-suite/success/Typeclasses.v4
-rw-r--r--test-suite/success/apply.v2
-rw-r--r--test-suite/success/cc.v14
-rw-r--r--test-suite/success/dependentind.v2
-rw-r--r--test-suite/success/evars.v2
-rw-r--r--test-suite/success/implicit.v12
-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/gallina-syntax.el1
-rw-r--r--toplevel/coqloop.ml42
-rw-r--r--toplevel/coqtop.ml29
-rw-r--r--toplevel/coqtop.mli3
-rw-r--r--toplevel/g_toplevel.ml44
-rw-r--r--vernac/class.ml1
-rw-r--r--vernac/classes.ml2
-rw-r--r--vernac/comDefinition.ml4
-rw-r--r--vernac/comFixpoint.ml3
-rw-r--r--vernac/comInductive.ml2
-rw-r--r--vernac/comProgramFixpoint.ml8
-rw-r--r--vernac/himsg.ml23
-rw-r--r--vernac/obligations.ml11
-rw-r--r--vernac/record.ml2
-rw-r--r--vernac/vernacentries.ml29
-rw-r--r--vernac/vernacprop.ml1
412 files changed, 13940 insertions, 16380 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 352ec5a51..8b6b43a55 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -31,11 +31,11 @@ before_script: &before_script
source ~/.profile
printenv
if [ -n "${EXTRA_PACKAGES}" ]; then sudo apt-get update -yq && sudo apt-get install -yq --no-install-recommends ${EXTRA_PACKAGES}; fi
+ echo . ~/.profile >> $BASH_ENV
opam-switch: &opam-switch
name: Select opam switch
command: |
- source ~/.profile
opam switch ${COMPILER}
opam config list
opam list
@@ -48,7 +48,6 @@ opam-switch: &opam-switch
- 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
@@ -59,19 +58,16 @@ opam-switch: &opam-switch
- 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" }}-
@@ -93,13 +89,10 @@ opam-switch: &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
@@ -118,7 +111,6 @@ opam-switch: &opam-switch
- run:
name: Test
command: |
- source ~/.profile
dev/ci/ci-wrapper.sh ${CIRCLE_JOB}
- persist_to_workspace:
root: *workspace
@@ -173,6 +165,9 @@ jobs:
geocoq:
<<: *ci-template
+ fcsl-pcm:
+ <<: *ci-template
+
fiat-crypto:
<<: *ci-template
@@ -248,6 +243,7 @@ workflows:
- elpi: *req-main
- equations: *req-main
- geocoq: *req-main
+ - fcsl-pcm: *req-main
- fiat-crypto: *req-main
- fiat-parsers: *req-main
- flocq: *req-main
diff --git a/.gitattributes b/.gitattributes
index db179c8d2..e087e1737 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -19,6 +19,7 @@ tools/CoqMakefile.in whitespace=trailing-space
*.css whitespace=trailing-space,tab-in-indent
*.dtd whitespace=trailing-space,tab-in-indent
*.el whitespace=trailing-space,tab-in-indent
+*.g whitespace=trailing-space,tab-in-indent
*.h whitespace=trailing-space,tab-in-indent
*.html whitespace=trailing-space,tab-in-indent
*.hva whitespace=trailing-space,tab-in-indent
@@ -37,9 +38,11 @@ tools/CoqMakefile.in whitespace=trailing-space
*.nsh whitespace=trailing-space,tab-in-indent
*.nsi whitespace=trailing-space,tab-in-indent
*.py whitespace=trailing-space,tab-in-indent
+*.rst whitespace=trailing-space,tab-in-indent
*.sh whitespace=trailing-space,tab-in-indent
*.sty whitespace=trailing-space,tab-in-indent
*.tex whitespace=trailing-space,tab-in-indent
+*.tokens whitespace=trailing-space,tab-in-indent
*.txt whitespace=trailing-space,tab-in-indent
*.v whitespace=trailing-space,tab-in-indent
*.xml whitespace=trailing-space,tab-in-indent
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index fea50c58c..029b55b9a 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -11,6 +11,9 @@
/dev/ci/*.sh @ejgallego
# Secondary maintainer @SkySkimmer
+/.circleci/ @SkySkimmer
+# Secondary maintainer @ejgallego
+
/.travis.yml @ejgallego
# Secondary maintainer @SkySkimmer
@@ -37,6 +40,10 @@
/dev/doc/ @Zimmi48
# Secondary maintainer @maximedenes
+/dev/doc/changes.md @ghost
+# Trick to avoid getting review requests
+# each time someone modifies the dev changelog
+
/doc/ @maximedenes
# Secondary maintainer @silene
@@ -56,6 +63,9 @@
/lib/ @ejgallego
# Secondary maintainer @ppedrot
+/lib/cWarnings.* @maximedenes
+# Secondary maintainer @ejgallego
+
########## Proof engine ##########
/engine/ @ppedrot
@@ -104,8 +114,8 @@
/plugins/btauto/ @ppedrot
# Secondary maintainer @herbelin
-# I don't know Pierre Corbineau's GitHub nickname
-/plugins/cc/ @herbelin
+/plugins/cc/ @PierreCorbineau
+# Secondary maintainer @herbelin
/plugins/derive/ @aspiwack
# Secondary maintainer @ppedrot
@@ -113,8 +123,8 @@
/plugins/extraction/ @letouzey
# Secondary maintainer @maximedenes
-# I don't know Pierre Corbineau's GitHub nickname
-/plugins/firstorder/ @herbelin
+/plugins/firstorder/ @PierreCorbineau
+# Secondary maintainer @herbelin
/plugins/fourier/ @herbelin
# Secondary maintainer @gares
@@ -149,8 +159,8 @@
/plugins/quote/ @herbelin
-# Should be Pierre Corbineau too
-/plugins/rtauto/ @herbelin
+/plugins/rtauto/ @PierreCorbineau
+# Secondary maintainer @herbelin
########## Pretyper ##########
@@ -294,6 +304,9 @@
/META.coq @ejgallego
# Secondary maintainer @letouzey
+/dev/build/windows @MSoegtropIMC
+# Secondary maintainer @maximedenes
+
########## Developer tools ##########
diff --git a/.gitignore b/.gitignore
index 267534365..25c0996cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -96,21 +96,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 +162,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 03e001f4a..7d6b53964 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,19 +1,17 @@
-image: ocaml/opam:ubuntu
-
-# this doesn't seem to work
-cache:
- paths:
- - .opamcache
+image: ubuntu:latest
stages:
+ - opam-boot
- build
- test
variables:
# some default values
NJOBS: "2"
- COMPILER: "system"
+ COMPILER: "4.02.3"
CAMLP5_VER: "6.14"
+ OPAMROOT: "$CI_PROJECT_DIR/.opamcache"
+ OPAMROOTISOK: "true"
# some useful values
COMPILER_32BIT: "4.02.3+32bit"
@@ -30,32 +28,49 @@ variables:
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"
+ ELPI_OPAM: "ppx_tools_versioned ppx_deriving ocaml-migrate-parsetree"
before_script:
- - ls # figure out if artifacts are around
+ - ls -a # 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}
- - 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
+ - apt-get update -qq && apt-get install -y -qq m4 opam ${EXTRA_PACKAGES}
+ - if [ -n "${PIP_PACKAGES}" ]; then pip3 install ${PIP_PACKAGES}; fi
+ # if no cache running opam config fails!
+ - if [ -d .opamcache ]; then eval $(opam config env); fi
+
+################ OPAM SYSTEM ######################
+# - use cache between pipelines
+# - use artifacts between jobs
+# (in https://gitlab.com/SkySkimmer/coq/-/jobs/63255417
+# the cache wasn't available at the build step)
+# every non opam-boot job must set dependencies (for ci it's in the template)
+# otherwise all opam-boot artifacts are used together and we get some random switch
+
+# set cache key when using
+.opam-boot-template: &opam-boot-template
+ stage: opam-boot
+ artifacts:
+ name: "opam-$COMPILER"
+ paths:
+ - .opamcache
+ expire_in: 1 week
+ script:
+ # 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 init -a -y -j $NJOBS --compiler=${COMPILER} default https://opam.ocaml.org
+ - eval $(opam config env)
+ - opam update
+ - opam config list
+ - opam list
+ - opam install -j ${NJOBS} -y camlp5.${CAMLP5_VER} ocamlfind num ${EXTRA_OPAM}
+ - rm -rf ~/.opam/log/
+ - opam list
# TODO figure out how to build doc for installed coq
+# set dependencies when using
.build-template: &build-template
stage: build
artifacts:
@@ -65,8 +80,13 @@ before_script:
- config/Makefile
- test-suite/misc/universes/all_stdlib.v
expire_in: 1 week
+ dependencies:
+ - not-a-real-job
script:
- set -e
+ - printenv
+ - opam config list
+ - opam list
- echo 'start:coq.config'
- ./configure -prefix "$(pwd)/_install_ci" ${EXTRA_CONF}
@@ -85,15 +105,13 @@ before_script:
- echo 'end:coq.install'
- set +e
- variables: &build-variables
- EXTRA_CONF: "-native-compiler yes -coqide opt"
- EXTRA_PACKAGES: "$COQIDE_PACKAGES"
- EXTRA_OPAM: "$COQIDE_OPAM"
+# set dependencies when using
.warnings-template: &warnings-template
# keep warnings in test stage so we can test things even when warnings occur
stage: test
- dependencies: []
+ dependencies:
+ - not-a-real-job
script:
- set -e
@@ -111,8 +129,11 @@ before_script:
EXTRA_PACKAGES: "$COQIDE_PACKAGES"
EXTRA_OPAM: "$COQIDE_OPAM"
+# set dependencies when using
.test-suite-template: &test-suite-template
stage: test
+ dependencies:
+ - not-a-real-job
script:
- cd test-suite
- make clean
@@ -126,8 +147,11 @@ before_script:
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
@@ -143,56 +167,90 @@ before_script:
- echo 'end:coq.test'
- set +e
dependencies:
+ - opam-boot
- build
variables: &ci-template-vars
TEST_TARGET: "$CI_JOB_NAME"
EXTRA_PACKAGES: "$TIMING_PACKAGES"
+opam-boot:
+ <<: *opam-boot-template
+ cache:
+ paths: &cache-paths
+ - .opamcache
+ key: main
+ variables:
+ EXTRA_OPAM: "$COQIDE_OPAM $COQDOC_OPAM ocamlgraph $ELPI_OPAM"
+ EXTRA_PACKAGES: "$COQIDE_PACKAGES"
+
+opam-boot:32bit:
+ <<: *opam-boot-template
+ cache:
+ paths: *cache-paths
+ key: 32bit
+ variables:
+ COMPILER: "$COMPILER_32BIT"
+ EXTRA_PACKAGES: "gcc-multilib"
+
+opam-boot:bleeding-edge:
+ <<: *opam-boot-template
+ cache:
+ paths: *cache-paths
+ key: be
+ variables:
+ COMPILER: "$COMPILER_BLEEDING_EDGE"
+ CAMLP5_VER: "$CAMLP5_VER_BLEEDING_EDGE"
+ EXTRA_PACKAGES: "$COQIDE_PACKAGES"
+ EXTRA_OPAM: "$COQIDE_OPAM_BE"
+
build:
<<: *build-template
+ dependencies:
+ - opam-boot
variables:
- EXTRA_CONF: "-with-doc yes"
- EXTRA_PACKAGES: "$COQDOC_PACKAGES"
- EXTRA_OPAM: "$COQDOC_OPAM"
+ EXTRA_CONF: "-native-compiler yes -coqide opt -with-doc yes"
+ EXTRA_PACKAGES: "$COQIDE_PACKAGES $COQDOC_PACKAGES"
PIP_PACKAGES: "$SPHINX_PACKAGES"
# no coqide for 32bit: libgtk installation problems
build:32bit:
<<: *build-template
+ dependencies:
+ - opam-boot:32bit
variables:
EXTRA_CONF: "-native-compiler yes"
EXTRA_PACKAGES: "gcc-multilib"
- COMPILER: "$COMPILER_32BIT"
build:bleeding-edge:
<<: *build-template
+ dependencies:
+ - opam-boot:bleeding-edge
variables:
- <<: *build-variables
- COMPILER: "$COMPILER_BLEEDING_EDGE"
- CAMLP5_VER: "$CAMLP5_VER_BLEEDING_EDGE"
- EXTRA_OPAM: "$COQIDE_OPAM_BE"
+ EXTRA_CONF: "-native-compiler yes -coqide opt"
+ EXTRA_PACKAGES: "$COQIDE_PACKAGES"
warnings:
<<: *warnings-template
+ dependencies:
+ - opam-boot
# warnings:32bit:
# <<: *warnings-template
# variables:
# <<: *warnings-variables
# EXTRA_PACKAGES: "$gcc-multilib COQIDE_PACKAGES_32BIT"
-# COMPILER: "$COMPILER_32BIT"
+# dependencies:
+# - opam-boot:32bit
warnings:bleeding-edge:
<<: *warnings-template
- variables:
- <<: *warnings-variables
- COMPILER: "$COMPILER_BLEEDING_EDGE"
- CAMLP5_VER: "$CAMLP5_VER_BLEEDING_EDGE"
- EXTRA_OPAM: "$COQIDE_OPAM_BE"
+ dependencies:
+ - opam-boot:bleeding-edge
test-suite:
<<: *test-suite-template
dependencies:
+ - opam-boot
- build
variables:
EXTRA_PACKAGES: "$TIMING_PACKAGES"
@@ -200,31 +258,31 @@ test-suite:
test-suite:32bit:
<<: *test-suite-template
dependencies:
+ - opam-boot:32bit
- build:32bit
variables:
- COMPILER: "$COMPILER_32BIT"
EXTRA_PACKAGES: "gcc-multilib $TIMING_PACKAGES"
test-suite:bleeding-edge:
<<: *test-suite-template
dependencies:
+ - opam-boot:bleeding-edge
- build:bleeding-edge
variables:
- COMPILER: "$COMPILER_BLEEDING_EDGE"
- CAMLP5_VER: "$CAMLP5_VER_BLEEDING_EDGE"
EXTRA_PACKAGES: "$TIMING_PACKAGES"
validate:
<<: *validate-template
dependencies:
+ - opam-boot
- build
validate:32bit:
<<: *validate-template
dependencies:
+ - opam-boot:32bit
- build:32bit
variables:
- COMPILER: "$COMPILER_32BIT"
EXTRA_PACKAGES: "gcc-multilib"
ci-bignums:
@@ -243,7 +301,6 @@ ci-coq-dpdgraph:
<<: *ci-template
variables:
<<: *ci-template-vars
- EXTRA_OPAM: "ocamlgraph"
EXTRA_PACKAGES: "$TIMING_PACKAGES autoconf"
ci-coquelicot:
@@ -254,9 +311,6 @@ ci-coquelicot:
ci-elpi:
<<: *ci-template
- variables:
- <<: *ci-template-vars
- EXTRA_OPAM: "ppx_tools_versioned ppx_deriving ocaml-migrate-parsetree"
ci-equations:
<<: *ci-template
@@ -265,6 +319,9 @@ ci-geocoq:
<<: *ci-template
allow_failure: true
+ci-fcsl-pcm:
+ <<: *ci-template
+
# ci-fiat-crypto:
# <<: *ci-template
# # out of memory error
diff --git a/.travis.yml b/.travis.yml
index 41814e954..fe376431e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -76,9 +76,9 @@ matrix:
- TEST_TARGET="ci-coquelicot"
- if: NOT (type = pull_request)
env:
+ - TEST_TARGET="ci-elpi" EXTRA_OPAM="ppx_tools_versioned ppx_deriving ocaml-migrate-parsetree"
# 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 +87,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:
@@ -199,8 +202,6 @@ matrix:
- MAIN_TARGET="coqocaml"
- EXTRA_CONF="-byte-only -coqide byte -warn-error yes"
- EXTRA_OPAM="hevea ${LABLGTK}"
- # dummy target
- - BUILD_TARGET="clean"
addons:
apt:
sources:
@@ -218,8 +219,6 @@ matrix:
- 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"
addons:
apt:
sources:
@@ -235,6 +234,7 @@ matrix:
- COQ_DEST="-local"
before_install:
- brew update
+ - brew unlink python
- brew install opam gnu-time
- if: NOT (type = pull_request)
diff --git a/CHANGES b/CHANGES
index 24c4cfec0..2db8ace96 100644
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,42 @@ 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.
+
+Tactic language
+
+- Support for fix/cofix added in Ltac "match" and "lazymatch".
+
+- Ltac backtraces now include trace information about tactics
+ called by OCaml-defined tactics.
+- Option "Ltac Debug" now applies also to terms built using Ltac functions.
+
+Changes from 8.8+beta1 to 8.8.0
+===============================
+
+Tools
+
+- Asynchronous proof delegation policy was fixed. Since version 8.7
+ Coq was ignoring previous runs and the -async-proofs-delegation-threshold
+ option did not have the expected behavior.
+
+Tactic language
+
+- The undocumented "nameless" forms `fix N`, `cofix N` have been
+ deprecated; please use `fix/cofix ident N` to explicitely name
+ hypothesis to be introduced.
+
+Documentation
+
+- The reference manual is now fully ported to Sphinx.
+
+Other small deprecations and bug fixes.
Changes from 8.7.2 to 8.8+beta1
===============================
@@ -72,6 +108,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
@@ -175,6 +212,7 @@ Options
+ `Refolding Reduction`
+ `Standard Proposition Elimination`
+ + `Dependent Propositions Elimination`
+ `Discriminate Introduction`
+ `Shrink Abstract`
+ `Tactic Pattern Unification`
@@ -182,6 +220,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 213b87735..1a3c99369 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -38,13 +38,11 @@ Whitespace discipline (do not indent using tabs, no trailing spaces, text files
Here are a few tags Coq developers may add to your PR and what they mean. In general feedback and requests for you as the pull request author will be in the comments and tags are only used to organize pull requests.
-- [needs: rebase](https://github.com/coq/coq/pulls?utf8=%E2%9C%93&q=is%3Aopen%20is%3Apr%20label%3A%22needs%3A%20rebase%22%20) indicates the PR should be rebased on top of the latest `master` branch. See the [GitHub documentation](https://help.github.com/articles/about-git-rebase/) for a brief introduction to using `git rebase`.
+- [needs: rebase](https://github.com/coq/coq/pulls?utf8=%E2%9C%93&q=is%3Aopen%20is%3Apr%20label%3A%22needs%3A%20rebase%22) indicates the PR should be rebased on top of the latest `master` branch. See the [GitHub documentation](https://help.github.com/articles/about-git-rebase/) for a brief introduction to using `git rebase`.
- [needs: fixing](https://github.com/coq/coq/pulls?q=is%3Aopen+is%3Apr+label%3A%22needs%3A+fixing%22) indicates the PR needs a fix, as discussed in the comments.
-- [needs: testing](https://github.com/coq/coq/pulls?q=is%3Aopen+is%3Apr+label%3A%22needs%3A+testing%22) indicates the PR needs testing. This is often used when testing beyond what the test suite can handle is required. For example, performance benchmarking is currently performed with a different infrastructure. Unless some followup is specifically requested you aren't expected to do this additional testing.
+- [needs: benchmarking](https://github.com/coq/coq/pulls?q=is%3Aopen+is%3Apr+label%3A%22needs%3A+benchmarking%22) and [needs: testing](https://github.com/coq/coq/pulls?q=is%3Aopen+is%3Apr+label%3A%22needs%3A+testing%22) indicate the PR needs testing beyond what the test suite can handle. For example, performance benchmarking is currently performed with a different infrastructure. Unless some followup is specifically requested you aren't expected to do this additional testing.
-The release manager uses the following filter to know which PRs seem ready for merge. If you are waiting for a PR to be merged, make sure it appears in this list:
-
-- [Pull requests ready for merge](https://github.com/coq/coq/pulls?utf8=%E2%9C%93&q=is%3Apr%20is%3Aopen%20-label%3A%22needs%3A%20discussion%22%20-label%3A%22needs%3A%20testing%22%20-label%3A%22needs%3A%20fixing%22%20-label%3A%22needs%3A%20progress%22%20-label%3A%22needs%3A%20rebase%22%20-label%3A%22needs%3A%20review%22%20-label%3A%22needs%3A%20help%22%20-label%3A%22needs%3A%20independent%20fix%22%20-label%3A%22needs%3A%20feedback%22%20-label%3A%22help%20wanted%22%20-review%3Achanges_requested%20-status%3Apending%20base%3Amaster%20sort%3Aupdated-asc%20-label%3A%22needs%3A%20squashing%22%20)
+To learn more about the merging process, you can read the [merging documentation for Coq maintainers](/dev/doc/MERGING.md).
## Documentation
@@ -52,7 +50,7 @@ Currently the process for contributing to the documentation is the same as for c
Our issue tracker includes a flag to mark bugs related to documentation. You can view a list of documentation-related bugs using a [GitHub issue search](https://github.com/coq/coq/issues?q=is%3Aopen+is%3Aissue+label%3A%22kind%3A+documentation%22). Many of these bugs can be fixed by contributing writing, without knowledge of Coq's OCaml source code.
-The sources for the [Coq reference manual](https://coq.inria.fr/distrib/current/refman/) are at [`doc/refman`](/doc/refman). These are written in LaTeX and compiled to HTML with [HeVeA](http://hevea.inria.fr/).
+The sources for the [Coq reference manual](https://coq.inria.fr/distrib/current/refman/) are at [`doc/sphinx`](/doc/sphinx). These are written in reStructuredText and compiled to HTML and PDF with [Sphinx](http://www.sphinx-doc.org/).
You may also contribute to the informal documentation available in [Cocorico](https://github.com/coq/coq/wiki) (the Coq wiki), and the [Coq FAQ](https://github.com/coq/coq/wiki/The-Coq-FAQ). Both of these are editable by anyone with a GitHub account.
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 b/INSTALL
index 3b3fd8b83..984b8e290 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,5 +1,5 @@
- INSTALLATION PROCEDURES FOR THE COQ V8.7 SYSTEM
+ INSTALLATION PROCEDURES FOR THE COQ V8.8 SYSTEM
-----------------------------------------------
@@ -27,7 +27,7 @@ WHAT DO YOU NEED ?
port install coq
- To compile Coq V8.7 yourself, you need:
+ To compile Coq V8.8 yourself, you need:
- OCaml version 4.02.3 or later
(available at https://ocaml.org/)
@@ -45,6 +45,10 @@ WHAT DO YOU NEED ?
- for Coqide, the Lablgtk development files, and the GTK libraries
including gtksourceview, see INSTALL.ide for more details
+ Note that camlp5 and lablgtk should be properly registered with
+ findlib/ocamlfind as Coq's makefile will use it to locate the
+ libraries during the build.
+
Opam (https://opam.ocaml.org/) is recommended to install ocaml and
the corresponding packages.
@@ -52,6 +56,16 @@ WHAT DO YOU NEED ?
should get you a reasonable OCaml environment to compile Coq.
+ Advanced users may want to experiment with the OCaml Flambda
+ compiler as way to improve the performance of Coq. In order to
+ profit from Flambda, a special build of the OCaml compiler that has
+ the Flambda optimizer enabled must be installed. For OPAM users,
+ this amounts to installing a compiler switch ending in `+flambda`,
+ such as `4.06.1+flambda`. For other users, YMMV. Once `ocamlopt
+ -config` reports that Flambda is available, some further
+ optimization options can be used; see the entry about -flambda-opts
+ below for more details.
+
QUICK INSTALLATION PROCEDURE.
=============================
@@ -66,7 +80,7 @@ INSTALLATION PROCEDURE IN DETAILS (NORMAL USERS).
computer and that "ocamlc" (or, better, its native code version
"ocamlc.opt") lies in a directory which is present in your $PATH
environment variable. At the time of writing this sentence, all
- versions of Objective Caml later or equal to 4.02.1 are
+ versions of Objective Caml later or equal to 4.02.3 are
supported.
To get Coq in native-code, (it runs 4 to 10 times faster than
@@ -129,9 +143,10 @@ INSTALLATION PROCEDURE IN DETAILS (NORMAL USERS).
and will be replaced by the URL.
-flambda-opts <flags>
- This experimental option will pass specific user flags to the
+ This experimental option will pass specific user flags to the
OCaml optimizing compiler. In most cases, this option is used
- to tweak the flambda backend; we recommend using
+ to tweak the flambda backend; for maximum performance we
+ recommend using
-flambda-opts `-O3 -unbox-closures`
@@ -144,7 +159,7 @@ INSTALLATION PROCEDURE IN DETAILS (NORMAL USERS).
a large amount of RAM (>= 10GiB) in some particular files.
We recommend disabling native compilation (`-native-compiler no`)
- with flambda unless you use a modern (>= 4.06.0) OCaml.
+ with flambda unless you use OCaml >= 4.07.0.
c.f. https://caml.inria.fr/mantis/view.php?id=7630
diff --git a/INSTALL.doc b/INSTALL.doc
index b71115bfa..625c36869 100644
--- a/INSTALL.doc
+++ b/INSTALL.doc
@@ -43,7 +43,7 @@ working set of packages for compiling the documentation for Coq is:
python3 python-pip3
To install the Python packages required to build the user manual, run:
- pip3 install sphinx sphinx_rtd_theme beautifulsoup4 antlr4-python3-runtime pexpect
+ pip3 install sphinx sphinx_rtd_theme beautifulsoup4 antlr4-python3-runtime pexpect sphinxcontrib-bibtex
Compilation
@@ -66,8 +66,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 sphinx
+ to produce the HTML version of the reference manual
make tutorial
to produce all formats of the tutorial
diff --git a/META.coq b/META.coq
index 4e53098c7..30bfdd67a 100644
--- a/META.coq
+++ b/META.coq
@@ -20,7 +20,7 @@ package "clib" (
version = "8.8"
directory = "clib"
- requires = "str, unix, threads"
+ requires = "num, str, unix, threads"
archive(byte) = "clib.cma"
archive(native) = "clib.cmxa"
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.ci b/Makefile.ci
index 3c26bf964..6b30f8723 100644
--- a/Makefile.ci
+++ b/Makefile.ci
@@ -17,6 +17,7 @@ CI_TARGETS=ci-bignums \
ci-cpdt \
ci-elpi \
ci-equations \
+ ci-fcsl-pcm \
ci-fiat-crypto \
ci-fiat-parsers \
ci-flocq \
diff --git a/Makefile.doc b/Makefile.doc
index 4a247f1d9..ce31c5fcb 100644
--- a/Makefile.doc
+++ b/Makefile.doc
@@ -56,60 +56,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-oth.v.tex RefMan-ltac.v.tex \
- RefMan-pro.v.tex \
- Coercion.v.tex Extraction.v.tex \
- Program.v.tex Polynom.v.tex Nsatz.v.tex \
- Setoid.v.tex Classes.v.tex Universes.v.tex \
- Misc.v.tex)
-
-REFMANTEXFILES:=$(addprefix doc/refman/, \
- headers.sty Reference-Manual.tex \
- RefMan-uti.tex \
- AsyncProofs.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 sphinxdoc-html doc-pdf doc-ps tutorial
+.PHONY: stdlib full-stdlib rectutorial
-INDEXURLS:=doc/refman/html/index_urls.txt
-
-doc: sphinx refman tutorial rectutorial stdlib $(INDEXURLS)
+doc: sphinx tutorial rectutorial stdlib
sphinx: coq
$(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/tutorial/Tutorial.v.html \
doc/stdlib/html/index.html doc/RecTutorial/RecTutorial.html
doc-pdf:\
- doc/tutorial/Tutorial.v.pdf doc/refman/Reference-Manual.pdf \
+ doc/tutorial/Tutorial.v.pdf \
doc/stdlib/Library.pdf doc/RecTutorial/RecTutorial.pdf
doc-ps:\
- doc/tutorial/Tutorial.v.ps doc/refman/Reference-Manual.ps \
+ doc/tutorial/Tutorial.v.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
@@ -168,82 +141,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
######################################################################
@@ -368,30 +265,20 @@ install-doc-meta:
$(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)
+ $(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/stdlib/Library.pdf $(FULLDOCDIR)/pdf
+ $(INSTALLLIB) doc/stdlib/Library.ps $(FULLDOCDIR)/ps
$(INSTALLLIB) doc/tutorial/Tutorial.v.pdf $(FULLDOCDIR)/pdf/Tutorial.pdf
$(INSTALLLIB) doc/RecTutorial/RecTutorial.pdf $(FULLDOCDIR)/pdf/RecTutorial.pdf
$(INSTALLLIB) doc/tutorial/Tutorial.v.ps $(FULLDOCDIR)/ps/Tutorial.ps
$(INSTALLLIB) doc/RecTutorial/RecTutorial.ps $(FULLDOCDIR)/ps/RecTutorial.ps
-install-doc-index-urls:
- $(MKDIR) $(FULLDATADIR)
- $(INSTALLLIB) $(INDEXURLS) $(FULLDATADIR)
-
install-doc-sphinx:
$(MKDIR) $(FULLDOCDIR)/sphinx
(for f in `cd doc/sphinx/_build; find . -type f`; do \
@@ -476,13 +363,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/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 b6c033f6d..071f4689b 100644
--- a/clib/cArray.ml
+++ b/clib/cArray.ml
@@ -41,6 +41,8 @@ sig
('a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
val fold_left3 :
('a -> 'b -> 'c -> 'd -> 'a) -> 'a -> 'b array -> 'c array -> 'd array -> 'a
+ val fold_left4 :
+ ('a -> 'b -> 'c -> 'd -> 'e -> 'a) -> 'a -> 'b array -> 'c array -> 'd array -> 'e array -> 'a
val fold_left2_i :
(int -> 'a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
val fold_left_from : int -> ('a -> 'b -> 'a) -> 'a -> 'b array -> 'a
@@ -60,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
@@ -267,6 +272,16 @@ let fold_left3 f a v1 v2 v3 =
invalid_arg "Array.fold_left2";
fold a 0
+let fold_left4 f a v1 v2 v3 v4 =
+ let lv1 = Array.length v1 in
+ let rec fold a n =
+ if n >= lv1 then a
+ else fold (f a (uget v1 n) (uget v2 n) (uget v3 n) (uget v4 n)) (succ n)
+ in
+ if Array.length v2 <> lv1 || Array.length v3 <> lv1 || Array.length v4 <> lv1 then
+ invalid_arg "Array.fold_left4";
+ fold a 0
+
let fold_left_from n f a v =
let len = Array.length v in
let () = if n < 0 then invalid_arg "Array.fold_left_from" in
diff --git a/clib/cArray.mli b/clib/cArray.mli
index 97038b0ac..9c2f521f4 100644
--- a/clib/cArray.mli
+++ b/clib/cArray.mli
@@ -66,6 +66,8 @@ sig
('a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
val fold_left3 :
('a -> 'b -> 'c -> 'd -> 'a) -> 'a -> 'b array -> 'c array -> 'd array -> 'a
+ val fold_left4 :
+ ('a -> 'b -> 'c -> 'd -> 'e -> 'a) -> 'a -> 'b array -> 'c array -> 'd array -> 'e array -> 'a
val fold_left2_i :
(int -> 'a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
val fold_left_from : int -> ('a -> 'b -> 'a) -> 'a -> 'b array -> 'a
@@ -112,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/default.nix b/default.nix
index 26c6e4b90..0b4794274 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 = optionals buildDoc [ "world" "sphinx" ];
+
+ installTargets = [ "install" ] ++ optional buildDoc "install-doc-sphinx";
+
inherit doCheck;
}
diff --git a/dev/build/osx/make-macos-dmg.sh b/dev/build/osx/make-macos-dmg.sh
index dc33838f1..c450e8157 100755
--- a/dev/build/osx/make-macos-dmg.sh
+++ b/dev/build/osx/make-macos-dmg.sh
@@ -10,19 +10,19 @@ VERSION=$(sed -n -e '/^let coq_version/ s/^[^"]*"\([^"]*\)"$/\1/p' configure.ml)
APP=bin/CoqIDE_${VERSION}.app
# Create a .app file with CoqIDE, without signing it
-make PRIVATEBINARIES=$APP -j $NJOBS -l2 $APP
+make PRIVATEBINARIES="$APP" -j "$NJOBS" -l2 "$APP"
# Add Coq to the .app file
-make OLDROOT=$OUTDIR COQINSTALLPREFIX=$APP/Contents/Resources/ install-coq install-ide-toploop
+make OLDROOT="$OUTDIR" COQINSTALLPREFIX="$APP/Contents/Resources/" install-coq install-ide-toploop
# Create the dmg bundle
-mkdir -p $DMGDIR
-ln -sf /Applications $DMGDIR/Applications
-cp -r $APP $DMGDIR
+mkdir -p "$DMGDIR"
+ln -sf /Applications "$DMGDIR/Applications"
+cp -r "$APP" "$DMGDIR"
mkdir -p _build
# Temporary countermeasure to hdiutil error 5341
# head -c9703424 /dev/urandom > $DMGDIR/.padding
-hdiutil create -imagekey zlib-level=9 -volname coq-$VERSION-installer-macos -srcfolder $DMGDIR -ov -format UDZO _build/coq-$VERSION-installer-macos.dmg
+hdiutil create -imagekey zlib-level=9 -volname "coq-$VERSION-installer-macos" -srcfolder "$DMGDIR" -ov -format UDZO "_build/coq-$VERSION-installer-macos.dmg"
diff --git a/dev/build/windows/MakeCoq_88git_installer.bat b/dev/build/windows/MakeCoq_88git_installer.bat
new file mode 100755
index 000000000..b016fb389
--- /dev/null
+++ b/dev/build/windows/MakeCoq_88git_installer.bat
@@ -0,0 +1,27 @@
+@ECHO OFF
+
+REM ========== COPYRIGHT/COPYLEFT ==========
+
+REM (C) 2016 Intel Deutschland GmbH
+REM Author: Michael Soegtrop
+
+REM Released to the public by Intel under the
+REM GNU Lesser General Public License Version 2.1 or later
+REM See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+
+REM ========== BUILD COQ ==========
+
+call MakeCoq_SetRootPath
+
+call MakeCoq_MinGW.bat ^
+ -arch=64 ^
+ -installer=Y ^
+ -coqver=git-v8.8 ^
+ -destcyg=%ROOTPATH%\cygwin_coq64_88_inst ^
+ -destcoq=%ROOTPATH%\coq64_88_inst ^
+ -addon=bignums
+
+IF %ERRORLEVEL% NEQ 0 (
+ ECHO MakeCoq_88git_installer.bat failed with error code %ERRORLEVEL%
+ EXIT /b %ERRORLEVEL%
+)
diff --git a/dev/build/windows/MakeCoq_MinGW.bat b/dev/build/windows/MakeCoq_MinGW.bat
index ccf22cc86..f960ff008 100644
--- a/dev/build/windows/MakeCoq_MinGW.bat
+++ b/dev/build/windows/MakeCoq_MinGW.bat
@@ -34,7 +34,7 @@ REM see -ocaml in ReadMe.txt
SET INSTALLOCAML=N
REM see -make in ReadMe.txt
-SET INSTALLMAKE=Y
+SET INSTALLMAKE=N
REM see -destcyg in ReadMe.txt
SET DESTCYG=C:\bin\cygwin_coq
@@ -267,7 +267,6 @@ IF "%INSTALLMODE%" == "mingwincygwin" (
IF "%MAKEINSTALLER%" == "Y" (
SET INSTALLMODE=relocatable
SET INSTALLOCAML=Y
- SET INSTALLMAKE=Y
)
REM ========== CONFIRM PARAMETERS ==========
diff --git a/dev/build/windows/configure_profile.sh b/dev/build/windows/configure_profile.sh
index 16c972e80..7e606b554 100644
--- a/dev/build/windows/configure_profile.sh
+++ b/dev/build/windows/configure_profile.sh
@@ -14,30 +14,30 @@
rcfile=~/.bash_profile
donefile=~/.bash_profile.upated
+# to learn about `exec >> $file`, see https://www.tldp.org/LDP/abs/html/x17974.html
+exec >> $rcfile
+
if [ ! -f $donefile ] ; then
- echo >> $rcfile
-
- if [ "$1" != "" -a "$1" != " " ]; then
- echo export http_proxy="http://$1" >> $rcfile
- echo export https_proxy="http://$1" >> $rcfile
- echo export ftp_proxy="http://$1" >> $rcfile
+ if [ "$1" != "" ] && [ "$1" != " " ]; then
+ echo export http_proxy="http://$1"
+ echo export https_proxy="http://$1"
+ echo export ftp_proxy="http://$1"
fi
-
- mkdir -p $RESULT_INSTALLDIR_CFMT/bin
+
+ mkdir -p "$RESULT_INSTALLDIR_CFMT/bin"
# A tightly controlled path helps to avoid issues
# Note: the order is important: first have the cygwin binaries, then the mingw binaries in the path!
# Note: /bin is mounted at /usr/bin and /lib at /usr/lib and it is common to use /usr/bin in PATH
# See cat /proc/mounts
- echo "export PATH=/usr/local/bin:/usr/bin:$RESULT_INSTALLDIR_CFMT/bin:/usr/$TARGET_ARCH/sys-root/mingw/bin:/cygdrive/c/Windows/system32:/cygdrive/c/Windows" >> $rcfile
+ echo "export PATH=/usr/local/bin:/usr/bin:$RESULT_INSTALLDIR_CFMT/bin:/usr/$TARGET_ARCH/sys-root/mingw/bin:/cygdrive/c/Windows/system32:/cygdrive/c/Windows"
# find and xargs complain if the environment is larger than (I think) 8k.
# ORIGINAL_PATH (set by cygwin) can be a few k and exceed the limit
- echo unset ORIGINAL_PATH >> $rcfile
-
+ echo unset ORIGINAL_PATH
# Other installations of OCaml will mess up things
- echo unset OCAMLLIB >> $rcfile
+ echo unset OCAMLLIB
touch $donefile
fi
diff --git a/dev/build/windows/difftar-folder.sh b/dev/build/windows/difftar-folder.sh
index cbcf14ec2..3bba451ec 100644
--- a/dev/build/windows/difftar-folder.sh
+++ b/dev/build/windows/difftar-folder.sh
@@ -42,7 +42,7 @@ fi
if [ "$strip" -gt 0 ] ; then
# Get the path/name of the first file from teh tar and extract the first $strip path components
# This assumes that the first file in the tar file has at least $strip many path components
- prefix=$(tar -t -f $tarfile | head -1 | cut -d / -f -$strip)/
+ prefix=$(tar -t -f "$tarfile" | head -1 | cut -d / -f -$strip)/
else
prefix=
fi
@@ -60,13 +60,13 @@ mkdir -p "$empty"
# Print information (this is ignored by patch)
-echo diff/patch file created on $(date) with:
-echo difftar-folder.sh $@
-echo TARFILE= $tarfile
-echo FOLDER= $folder
-echo TARSTRIP= $strip
-echo TARPREFIX= $prefix
-echo ORIGFOLDER= $orig
+echo diff/patch file created on "$(date)" with:
+echo difftar-folder.sh "$@"
+echo TARFILE= "$tarfile"
+echo FOLDER= "$folder"
+echo TARSTRIP= "$strip"
+echo TARPREFIX= "$prefix"
+echo ORIGFOLDER= "$orig"
# Make sure tar uses english output (for Mod time differs)
export LC_ALL=C
@@ -76,14 +76,14 @@ tar --diff -a -f "$tarfile" --strip $strip --directory "$folder" | grep "Mod tim
# Substitute ': Mod time differs' with nothing
file=${file/: Mod time differs/}
# Check if file exists
- if [ -f "$folder/$file" ] ; then
+ if [ -f "$folder/$file" ] ; then
# Extract original file
tar -x -a -f "$tarfile" --strip $strip --directory "$orig" "$prefix$file"
# Compute diff
- diff -u "$orig/$file" "$folder/$file"
+ diff -u "$orig/$file" "$folder/$file"
fi
done
if [ -d "$new" ] ; then
- diff -u -r --unidirectional-new-file $empty $new
+ diff -u -r --unidirectional-new-file "$empty" "$new"
fi
diff --git a/dev/build/windows/makecoq_mingw.sh b/dev/build/windows/makecoq_mingw.sh
index 8e0d2341d..18f1a2f16 100644
--- a/dev/build/windows/makecoq_mingw.sh
+++ b/dev/build/windows/makecoq_mingw.sh
@@ -67,7 +67,7 @@ RMDIR_BEFORE_BUILD=1
###################### ARCHITECTURES #####################
# The OS on which the build of the tool/lib runs
-BUILD=`gcc -dumpmachine`
+BUILD=$(gcc -dumpmachine)
# The OS on which the tool runs
# "`find /bin -name "*mingw32-gcc.exe"`" -dumpmachine
@@ -132,34 +132,38 @@ CYGWIN_REPO_FOLDER=${CYGWIN_REPO_FOLDER//\//%2f}
# Copy files
cp "$CYGWIN_LOCAL_CACHE_WFMT/$CYGWIN_REPO_FOLDER/$CYGWINARCH/setup.ini" $TARBALLS
cp /etc/setup/installed.db $TARBALLS
-
+
###################### LOGGING #####################
# The folder which receives log files
mkdir -p buildlogs
-LOGS=`pwd`/buildlogs
+LOGS=$(pwd)/buildlogs
# The current log target (first part of the log file name)
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
+ "$@" > "$LOGS/$LOGTARGET-$1.log" 2> "$LOGS/$LOGTARGET-$1.err"
}
+# 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
+ "$@" > "$LOGS/$LOGTARGET-$1-$2.log" 2> "$LOGS/$LOGTARGET-$1-$2.err"
}
+# 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
+ "$@" > "$LOGS/$LOGTARGET-$1-$3.log" 2> "$LOGS/$LOGTARGET-$1-$3.err"
}
+# 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
+ "$@" > "$LOGS/$LOGTARGET-$LOGTARGETEX.log" 2> "$LOGS/$LOGTARGET-$LOGTARGETEX.err"
}
-
+
###################### 'UNFIX' SED #####################
# In Cygwin SED used to do CR-LF to LF conversion, but since sed 4.4-1 this was changed
@@ -183,7 +187,7 @@ logn() {
# - create build folder
# - extract source archive
# - patch source file if patch exists
-#
+#
# Parameters
# $1 file server name including protocol prefix
# $2 file name (without extension)
@@ -206,68 +210,68 @@ function get_expand_source_tar {
else
name=$2
fi
-
+
if [ "$#" -ge 6 ] ; then
folder=$6
else
folder=$name
fi
-
+
# Set logging target
logtargetold=$LOGTARGET
LOGTARGET=$name
-
+
# Get the source archive either from the source cache or online
- if [ ! -f $TARBALLS/$name.$3 ] ; then
+ if [ ! -f "$TARBALLS/$name.$3" ] ; then
if [ -f "$SOURCE_LOCAL_CACHE_CFMT/$name.$3" ] ; then
- cp "$SOURCE_LOCAL_CACHE_CFMT/$name.$3" $TARBALLS
+ cp "$SOURCE_LOCAL_CACHE_CFMT/$name.$3" "$TARBALLS"
else
- wget $1/$2.$3
- if file -i $2.$3 | grep text/html; then
- echo Download failed: $1/$2.$3
+ wget "$1/$2.$3"
+ if file -i "$2.$3" | grep text/html; then
+ echo Download failed: "$1/$2.$3"
echo The file wget downloaded is an html file:
- cat $2.$3
+ cat "$2.$3"
exit 1
fi
if [ ! "$2.$3" == "$name.$3" ] ; then
- mv $2.$3 $name.$3
+ mv "$2.$3" "$name.$3"
fi
- mv $name.$3 $TARBALLS
+ mv "$name.$3" "$TARBALLS"
# Save the source archive in the source cache
if [ -d "$SOURCE_LOCAL_CACHE_CFMT" ] ; then
- cp $TARBALLS/$name.$3 "$SOURCE_LOCAL_CACHE_CFMT"
+ cp "$TARBALLS/$name.$3" "$SOURCE_LOCAL_CACHE_CFMT"
fi
fi
fi
-
+
# Remove build directory (clean build)
if [ $RMDIR_BEFORE_BUILD -eq 1 ] ; then
- rm -f -r $folder
+ rm -f -r "$folder"
fi
-
+
# Create build directory and cd
- mkdir -p $folder
- cd $folder
-
+ mkdir -p "$folder"
+ cd "$folder"
+
# Extract source archive
if [ "$3" == "zip" ] ; then
- log1 unzip $TARBALLS/$name.$3
+ log1 unzip "$TARBALLS/$name.$3"
if [ "$strip" == "1" ] ; then
# Ok, this is dirty, but it works and it fails if there are name clashes
- mv */* .
+ mv -- */* .
else
echo "Unzip strip count not supported"
return 1
fi
else
- logn untar tar xvaf $TARBALLS/$name.$3 --strip $strip
+ logn untar tar xvaf "$TARBALLS/$name.$3" --strip $strip
fi
-
+
# Patch if patch file exists
- if [ -f $PATCHES/$name.patch ] ; then
- log1 patch -p1 -i $PATCHES/$name.patch
+ if [ -f "$PATCHES/$name.patch" ] ; then
+ log1 patch -p1 -i "$PATCHES/$name.patch"
fi
-
+
# Go back to base folder
cd ..
@@ -283,7 +287,7 @@ function get_expand_source_tar {
# - cd to build folder and extract source archive
# - create bin_special subfolder and add it to $PATH
# - remember things for build_post
-#
+#
# Parameters
# $1 file server name including protocol prefix
# $2 file name (without extension)
@@ -305,27 +309,27 @@ function build_prep {
else
name=$2
fi
-
+
# Check if build is already done
- if [ ! -f flagfiles/$name.finished ] ; then
+ if [ ! -f "flagfiles/$name.finished" ] ; then
BUILD_PACKAGE_NAME=$name
BUILD_OLDPATH=$PATH
- BUILD_OLDPWD=`pwd`
+ BUILD_OLDPWD=$(pwd)
LOGTARGET=$name
- touch flagfiles/$name.started
-
- get_expand_source_tar $1 $2 $3 $strip $name
-
- cd $name
-
+ touch "flagfiles/$name.started"
+
+ get_expand_source_tar "$1" "$2" "$3" "$strip" "$name"
+
+ cd "$name"
+
# Create a folder and add it to path, where we can put special binaries
# The path is restored in build_post
mkdir bin_special
- PATH=`pwd`/bin_special:$PATH
-
+ PATH=$(pwd)/bin_special:$PATH
+
return 0
- else
+ else
return 1
fi
}
@@ -337,9 +341,9 @@ function build_prep {
# ------------------------------------------------------------------------------
function build_post {
- if [ ! -f flagfiles/$BUILD_PACKAGE_NAME.finished ]; then
- cd $BUILD_OLDPWD
- touch flagfiles/$BUILD_PACKAGE_NAME.finished
+ if [ ! -f "flagfiles/$BUILD_PACKAGE_NAME.finished" ]; then
+ cd "$BUILD_OLDPWD"
+ touch "flagfiles/$BUILD_PACKAGE_NAME.finished"
PATH=$BUILD_OLDPATH
LOGTARGET=other
fi
@@ -362,9 +366,10 @@ function build_post {
# ------------------------------------------------------------------------------
function build_conf_make_inst {
- if build_prep $1 $2 $3 ; then
+ if build_prep "$1" "$2" "$3" ; then
$4
- logn configure ./configure --build=$BUILD --host=$HOST --target=$TARGET --prefix="$PREFIX" "${@:5}"
+ logn configure ./configure --build="$BUILD" --host="$HOST" --target="$TARGET" --prefix="$PREFIX" "${@:5}"
+ # shellcheck disable=SC2086
log1 make $MAKE_OPT
log2 make install
log2 make clean
@@ -383,6 +388,7 @@ function build_conf_make_inst {
function install_glob {
# Check if any files matching the pattern exist
if [ "$(echo $1)" != "$1" ] ; then
+ # shellcheck disable=SC2086
install -D -t $2 $1
fi
}
@@ -398,7 +404,7 @@ function install_glob {
# ------------------------------------------------------------------------------
function install_rec {
- ( cd $1 && find -type f -name "$2" -exec install -D -T $1/{} $3/{} \; )
+ ( cd "$1" && find . -type f -name "$2" -exec install -D -T "$1"/{} "$3"/{} \; )
}
# ------------------------------------------------------------------------------
@@ -411,7 +417,7 @@ function install_rec {
function list_files {
if [ ! -e "/build/filelists/$1" ] ; then
- ( cd "$PREFIXCOQ" && find -type f | sort > /build/filelists/$1 )
+ ( cd "$PREFIXCOQ" && find . -type f | sort > /build/filelists/"$1" )
fi
}
@@ -439,7 +445,7 @@ function diff_files {
# ------------------------------------------------------------------------------
function filter_files {
- egrep "$3" "/build/filelists/$2" > "/build/filelists/$1"
+ grep -E "$3" "/build/filelists/$2" > "/build/filelists/$1"
}
# ------------------------------------------------------------------------------
@@ -453,7 +459,7 @@ function files_to_nsis {
# Split the path in the file list into path and filename and create SetOutPath and File instructions
# Note: File /oname cannot be used, because it does not create the paths as SetOutPath does
# Note: I didn't check if the redundant SetOutPath instructions have a bad impact on installer size or install time
- cat "/build/filelists/$1" | tr '/' '\\' | sed -r 's/^\.(.*)\\([^\\]+)$/SetOutPath $INSTDIR\\\1\nFile ${COQ_SRC_PATH}\\\1\\\2/' > "/build/filelists/$1.nsh"
+ tr '/' '\\' < "/build/filelists/$1" | sed -r 's/^\.(.*)\\([^\\]+)$/SetOutPath $INSTDIR\\\1\nFile ${COQ_SRC_PATH}\\\1\\\2/' > "/build/filelists/$1.nsh"
}
@@ -501,7 +507,7 @@ function make_fontconfig {
make_freetype
make_expat
# CONFIGURE PARAMETERS
- # build/install fails without --disable-docs
+ # build/install fails without --disable-docs
build_conf_make_inst http://www.freedesktop.org/software/fontconfig/release fontconfig-2.11.94 tar.gz true --disable-docs
}
@@ -532,7 +538,7 @@ function make_ncurses {
#
# CONFIGURE PARAMETERS
# --enable-term-driver --enable-sp-funcs is rewuired for mingw (see README.MinGW)
- # additional changes
+ # additional changes
# ADD --with-pkg-config
# ADD --enable-pc-files
# ADD --without-manpages
@@ -604,7 +610,7 @@ function make_gdk-pixbuf {
# CONFIGURE PARAMETERS
# --with-included-loaders=yes statically links the image file format handlers
# This avoids "Cannot open pixbuf loader module file '/usr/x86_64-w64-mingw32/sys-root/mingw/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache': No such file or directory"
- build_conf_make_inst http://ftp.gnome.org/pub/GNOME/sources/gdk-pixbuf/2.32 gdk-pixbuf-2.32.1 tar.xz true --with-included-loaders=yes
+ build_conf_make_inst http://ftp.gnome.org/pub/GNOME/sources/gdk-pixbuf/2.32 gdk-pixbuf-2.32.1 tar.xz true --with-included-loaders=yes
}
##### CAIRO #####
@@ -657,8 +663,8 @@ function make_gtk3 {
build_conf_make_inst http://ftp.gnome.org/pub/gnome/sources/gtk+/3.16 gtk+-3.16.7 tar.xz true
# make all incl. tests and examples runs through fine
- # make install fails with issue with
- #
+ # make install fails with issue with
+ #
# make[5]: Entering directory '/home/soegtrop/GTK/gtk+-3.16.7/demos/gtk-demo'
# test -n "" || ../../gtk/gtk-update-icon-cache --ignore-theme-index --force "/usr/x86_64-w64-mingw32/sys-root/mingw/share/icons/hicolor"
# gtk-update-icon-cache.exe: Failed to open file /usr/x86_64-w64-mingw32/sys-root/mingw/share/icons/hicolor/.icon-theme.cache : No such file or directory
@@ -676,7 +682,8 @@ function make_libxml2 {
if build_prep https://git.gnome.org/browse/libxml2/snapshot libxml2-2.9.1 tar.xz ; then
# ./autogen.sh --build=$BUILD --host=$HOST --target=$TARGET --prefix="$PREFIX" --disable-shared --without-python
# shared library required by gtksourceview
- ./autogen.sh --build=$BUILD --host=$HOST --target=$TARGET --prefix="$PREFIX" --without-python
+ ./autogen.sh --build="$BUILD" --host="$HOST" --target="$TARGET" --prefix="$PREFIX" --without-python
+ # shellcheck disable=SC2086
log1 make $MAKE_OPT all
log2 make install
log2 make clean
@@ -708,12 +715,12 @@ function make_gtk_sourceview2 {
# Install flexdll objects
function install_flexdll {
- cp flexdll.h /usr/$TARGET_ARCH/sys-root/mingw/include
+ cp flexdll.h "/usr/$TARGET_ARCH/sys-root/mingw/include"
if [ "$TARGET_ARCH" == "i686-w64-mingw32" ]; then
- cp flexdll*_mingw.o /usr/$TARGET_ARCH/bin
+ cp flexdll*_mingw.o "/usr/$TARGET_ARCH/bin"
cp flexdll*_mingw.o "$PREFIXOCAML/bin"
elif [ "$TARGET_ARCH" == "x86_64-w64-mingw32" ]; then
- cp flexdll*_mingw64.o /usr/$TARGET_ARCH/bin
+ cp flexdll*_mingw64.o "/usr/$TARGET_ARCH/bin"
cp flexdll*_mingw64.o "$PREFIXOCAML/bin"
else
echo "Unknown target architecture"
@@ -724,8 +731,8 @@ function install_flexdll {
# Install flexlink
function install_flexlink {
- cp flexlink.exe /usr/$TARGET_ARCH/bin
-
+ cp flexlink.exe "/usr/$TARGET_ARCH/bin"
+
cp flexlink.exe "$PREFIXOCAML/bin"
}
@@ -745,8 +752,10 @@ function get_flex_dll_link_bin {
function make_flex_dll_link {
if build_prep http://alain.frisch.fr/flexdll flexdll-0.34 tar.gz ; then
if [ "$TARGET_ARCH" == "i686-w64-mingw32" ]; then
+ # shellcheck disable=SC2086
log1 make $MAKE_OPT build_mingw flexlink.exe
elif [ "$TARGET_ARCH" == "x86_64-w64-mingw32" ]; then
+ # shellcheck disable=SC2086
log1 make $MAKE_OPT build_mingw64 flexlink.exe
else
echo "Unknown target architecture"
@@ -769,11 +778,11 @@ function make_ln {
if [ ! -f flagfiles/myln.finished ] ; then
touch flagfiles/myln.started
mkdir -p myln
- cd myln
+ ( cd myln
cp $PATCHES/ln.c .
- $TARGET_ARCH-gcc -DUNICODE -D_UNICODE -DIGNORE_SYMBOLIC -mconsole -o ln.exe ln.c
+ "$TARGET_ARCH-gcc" -DUNICODE -D_UNICODE -DIGNORE_SYMBOLIC -mconsole -o ln.exe ln.c
install -D ln.exe "$PREFIXCOQ/bin/ln.exe"
- cd ..
+ )
touch flagfiles/myln.finished
fi
}
@@ -799,14 +808,14 @@ function make_ocaml {
# Prefix is fixed in make file - replace it with the real one
# TODO: this might not work if PREFIX contains spaces
sed -i "s|^PREFIX=.*|PREFIX=$PREFIXOCAML|" config/Makefile
-
+
# We don't want to mess up Coq's directory structure so put the OCaml library in a separate folder
# If we refer to the make variable ${PREFIX} below, camlp5 ends up having the wrong path:
# D:\bin\coq64_buildtest_abs_ocaml4\bin>ocamlc -where => D:/bin/coq64_buildtest_abs_ocaml4/libocaml
# D:\bin\coq64_buildtest_abs_ocaml4\bin>camlp4 -where => ${PREFIX}/libocaml\camlp4
# So we put an explicit path in there
sed -i "s|^LIBDIR=.*|LIBDIR=$PREFIXOCAML/libocaml|" config/Makefile
-
+
# Note: ocaml doesn't support -j 8, so don't pass MAKE_OPT
# I verified that 4.02.3 still doesn't support parallel build
log2 make world -f Makefile.nt
@@ -815,12 +824,12 @@ function make_ocaml {
log2 make opt.opt -f Makefile.nt
log2 make install -f Makefile.nt
# TODO log2 make clean -f Makefile.nt Temporarily disabled for ocamlbuild development
-
+
# Move license files and other into into special folder
if [ "$INSTALLMODE" == "absolute" ] || [ "$INSTALLMODE" == "relocatable" ]; then
mkdir -p "$PREFIXOCAML/license_readme/ocaml"
# 4.01 installs these files, 4.02 doesn't. So delete them and copy them from the sources.
- rm -f *.txt
+ rm -f ./*.txt
cp LICENSE "$PREFIXOCAML/license_readme/ocaml/License.txt"
cp INSTALL "$PREFIXOCAML/license_readme/ocaml/Install.txt"
cp README "$PREFIXOCAML/license_readme/ocaml/ReadMe.txt"
@@ -909,9 +918,10 @@ function make_camlp5 {
make_ocaml
make_findlib
if build_prep http://camlp5.gforge.inria.fr/distrib/src camlp5-6.14 tgz 1 ; then
- logn configure ./configure
+ logn configure ./configure
# Somehow my virus scanner has the boot.new/SAVED directory locked after the move for a second => repeat until success
sed -i 's/mv boot.new boot/until mv boot.new boot; do sleep 1; done/' Makefile
+ # shellcheck disable=SC2086
log1 make world.opt $MAKE_OPT
log2 make install
# For some reason gramlib.a is not copied, but it is required by Coq
@@ -939,15 +949,15 @@ function make_lablgtk {
make_gtk_sourceview2
if build_prep https://forge.ocamlcore.org/frs/download.php/1479 lablgtk-2.18.3 tar.gz 1 ; then
# configure should be fixed to search for $TARGET_ARCH-pkg-config.exe
- cp /bin/$TARGET_ARCH-pkg-config.exe bin_special/pkg-config.exe
- logn configure ./configure --build=$BUILD --host=$HOST --target=$TARGET --prefix="$PREFIXOCAML"
-
+ cp "/bin/$TARGET_ARCH-pkg-config.exe" bin_special/pkg-config.exe
+ logn configure ./configure --build="$BUILD" --host="$HOST" --target="$TARGET" --prefix="$PREFIXOCAML"
+
# 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
-
+ "$TARGET_ARCH-strip.exe" --strip-unneeded src/dlllablgtk2.dll
+
log2 make world
log2 make install
log2 make clean
@@ -978,7 +988,7 @@ function make_stdint {
function copy_coq_dll {
if [ "$INSTALLMODE" == "absolute" ] || [ "$INSTALLMODE" == "relocatable" ]; then
- cp /usr/${ARCH}-w64-mingw32/sys-root/mingw/bin/$1 "$PREFIXCOQ/bin/$1"
+ cp "/usr/${ARCH}-w64-mingw32/sys-root/mingw/bin/$1" "$PREFIXCOQ/bin/$1"
fi
}
@@ -994,7 +1004,7 @@ function copy_coq_dlls {
# Do this recursively until there are no further missing DLLs (File close + reopen)
# For running this quickly, just do "cd coq-<ver> ; call copy_coq_dlls ; cd .." at the end of this script.
# Do the same for coqc and ocamlc (usually doesn't result in additional files)
-
+
copy_coq_dll LIBATK-1.0-0.DLL
copy_coq_dll LIBCAIRO-2.DLL
copy_coq_dll LIBEXPAT-1.DLL
@@ -1018,7 +1028,7 @@ function copy_coq_dlls {
copy_coq_dll LIBXML2-2.DLL
copy_coq_dll ZLIB1.DLL
- # Depends on if GTK is built from sources
+ # Depends on if GTK is built from sources
if [ "$GTK_FROM_SOURCES" == "Y" ]; then
copy_coq_dll libiconv-2.dll
else
@@ -1036,21 +1046,21 @@ function copy_coq_dlls {
i686) copy_coq_dll LIBGCC_S_SJLJ-1.DLL ;;
*) false ;;
esac
-
+
# Win pthread version change
copy_coq_dll LIBWINPTHREAD-1.DLL
}
function copy_coq_objects {
# copy objects only from folders which exist in the target lib directory
- find . -type d | while read FOLDER ; do
+ find . -type d | while read -r FOLDER ; do
if [ -e "$PREFIXCOQ/lib/$FOLDER" ] ; then
- install_glob $FOLDER/'*.cmxa' "$PREFIXCOQ/lib/$FOLDER"
- install_glob $FOLDER/'*.cmi' "$PREFIXCOQ/lib/$FOLDER"
- install_glob $FOLDER/'*.cma' "$PREFIXCOQ/lib/$FOLDER"
- install_glob $FOLDER/'*.cmo' "$PREFIXCOQ/lib/$FOLDER"
- install_glob $FOLDER/'*.a' "$PREFIXCOQ/lib/$FOLDER"
- install_glob $FOLDER/'*.o' "$PREFIXCOQ/lib/$FOLDER"
+ install_glob "$FOLDER"/'*.cmxa' "$PREFIXCOQ/lib/$FOLDER"
+ install_glob "$FOLDER"/'*.cmi' "$PREFIXCOQ/lib/$FOLDER"
+ install_glob "$FOLDER"/'*.cma' "$PREFIXCOQ/lib/$FOLDER"
+ install_glob "$FOLDER"/'*.cmo' "$PREFIXCOQ/lib/$FOLDER"
+ install_glob "$FOLDER"/'*.a' "$PREFIXCOQ/lib/$FOLDER"
+ install_glob "$FOLDER"/'*.o' "$PREFIXCOQ/lib/$FOLDER"
fi
done
}
@@ -1066,7 +1076,7 @@ function copq_coq_gtk {
install_glob "$PREFIX/share/gtksourceview-2.0/language-specs/"'*' "$PREFIXCOQ/share/gtksourceview-2.0/language-specs"
install_glob "$PREFIX/share/gtksourceview-2.0/styles/"'*' "$PREFIXCOQ/share/gtksourceview-2.0/styles"
install_rec "$PREFIX/share/themes/" '*' "$PREFIXCOQ/share/themes"
-
+
# This below item look like a bug in make install
if [ -d "$PREFIXCOQ/share/coq/" ] ; then
COQSHARE="$PREFIXCOQ/share/coq/"
@@ -1111,11 +1121,11 @@ function make_coq {
case $COQ_VERSION in
# e.g. git-v8.6 => download from https://github.com/coq/coq/archive/v8.6.zip
# e.g. git-trunk => download from https://github.com/coq/coq/archive/trunk.zip
- git-*)
+ git-*)
COQ_BUILD_PATH=/build/coq-${COQ_VERSION}
- build_prep https://github.com/coq/coq/archive ${COQ_VERSION##git-} zip 1 coq-${COQ_VERSION}
+ build_prep https://github.com/coq/coq/archive "${COQ_VERSION##git-}" zip 1 "coq-${COQ_VERSION}"
;;
-
+
# e.g. /cygdrive/d/coqgit
/*)
# Todo: --exclude-vcs-ignores doesn't work because tools/coqdoc/coqdoc.sty is excluded => fix .gitignore
@@ -1124,11 +1134,11 @@ function make_coq {
tar -zcf $TARBALLS/coq-local.tar.gz --exclude-vcs -C "${COQ_VERSION%/*}" "${COQ_VERSION##*/}"
build_prep NEVER-DOWNLOADED coq-local tar.gz
;;
-
+
# e.g. 8.6 => https://coq.inria.fr/distrib/8.6/files/coq-8.6.tar.gz
*)
COQ_BUILD_PATH=/build/coq-$COQ_VERSION
- build_prep https://coq.inria.fr/distrib/V$COQ_VERSION/files coq-$COQ_VERSION tar.gz
+ build_prep "https://coq.inria.fr/distrib/V$COQ_VERSION/files" "coq-$COQ_VERSION" tar.gz
;;
esac
then
@@ -1142,16 +1152,17 @@ function make_coq {
fi
# The windows resource compiler binary name is hard coded
- sed -i "s/i686-w64-mingw32-windres/$TARGET_ARCH-windres/" Makefile.build
+ sed -i "s/i686-w64-mingw32-windres/$TARGET_ARCH-windres/" Makefile.build
sed -i "s/i686-w64-mingw32-windres/$TARGET_ARCH-windres/" Makefile.ide || true
# 8.4x doesn't support parallel make
if [[ $COQ_VERSION == 8.4* ]] ; then
log1 make
else
+ # shellcheck disable=SC2086
make $MAKE_OPT
fi
-
+
if [ "$INSTALLMODE" == "relocatable" ]; then
./configure -with-doc no -prefix "$PREFIXCOQ" -libdir "$PREFIXCOQ/lib" -mandir "$PREFIXCOQ/man"
fi
@@ -1161,7 +1172,7 @@ function make_coq {
if [ "$INSTALLOCAML" == "Y" ]; then
copy_coq_objects
fi
-
+
copq_coq_gtk
copy_coq_license
@@ -1169,7 +1180,7 @@ function make_coq {
# 1.) find | xargs fails on cygwin, can be fixed by sed -i 's|\| xargs rm -f|-exec rm -fv \{\} \+|' Makefile
# 2.) clean of test suites fails with "cannot run complexity tests (no bogomips found)"
# make clean
-
+
build_post
fi
}
@@ -1180,7 +1191,7 @@ function make_mingw_make {
if build_prep http://ftp.gnu.org/gnu/make make-4.2 tar.bz2 ; then
# The config.h.win32 file is fine - don't edit it
# We need to copy the mingw gcc here as "gcc" - then the batch file will use it
- cp /usr/bin/${ARCH}-w64-mingw32-gcc-6.4.0.exe ./gcc.exe
+ cp "/usr/bin/${ARCH}-w64-mingw32-gcc-6.4.0.exe" ./gcc.exe
# By some magic cygwin bash can run batch files
logn build ./build_w32.bat gcc
# Copy make to Coq folder
@@ -1193,7 +1204,8 @@ function make_mingw_make {
function make_binutils {
if build_prep http://ftp.gnu.org/gnu/binutils binutils-2.27 tar.gz ; then
- logn configure ./configure --build=$BUILD --host=$HOST --target=$TARGET --prefix="$PREFIXCOQ" --program-prefix=$TARGET-
+ logn configure ./configure --build="$BUILD" --host="$HOST" --target="$TARGET" --prefix="$PREFIXCOQ" --program-prefix="$TARGET-"
+ # shellcheck disable=SC2086
log1 make $MAKE_OPT
log2 make install
# log2 make clean
@@ -1219,12 +1231,13 @@ function make_gcc {
mkdir -p "$PREFIXCOQ/mingw/include"
# See https://gcc.gnu.org/install/configure.html
- logn configure ./configure --build=$BUILD --host=$HOST --target=$TARGET \
- --prefix="$PREFIXCOQ" --program-prefix=$TARGET- --disable-win32-registry --with-sysroot="$PREFIXCOQ" \
+ logn configure ./configure --build="$BUILD" --host="$HOST" --target="$TARGET" \
+ --prefix="$PREFIXCOQ" --program-prefix="$TARGET-" --disable-win32-registry --with-sysroot="$PREFIXCOQ" \
--enable-languages=c --disable-nls \
--disable-libsanitizer --disable-libssp --disable-libquadmath --disable-libgomp --disable-libvtv --disable-lto
# --disable-decimal-float seems to be required
# --with-sysroot="$PREFIX" results in configure error that this is not an absolute path
+ # shellcheck disable=SC2086
log1 make $MAKE_OPT
log2 make install
# log2 make clean
@@ -1252,21 +1265,22 @@ function get_cygwin_mingw_sources {
# Take the 2nd field of the last line => ${SOURCE} = x86_64/release/mingw64-x86_64-gcc/mingw64-x86_64-gcc-5.4.0-2-src.tar.xz
# Remove that path part => ${SOURCEFILE} = mingw64-x86_64-gcc-5.4.0-2-src.tar.xz
- grep "mingw" /etc/setup/installed.db | sed 's/\.tar\.bz2 [0-1]$//' | sed 's/ /\//' | while read ARCHIVE ; do
+ grep "mingw" /etc/setup/installed.db | sed 's/\.tar\.bz2 [0-1]$//' | sed 's/ /\//' | while read -r ARCHIVE ; do
local ARCHIVEESC=${ARCHIVE//+/\\+}
- local SOURCE=`egrep -A 1 "install: ($CYGWINARCH|noarch)/release/[-+_/a-z0-9]*$ARCHIVEESC" $TARBALLS/setup.ini | tail -1 | cut -d " " -f 2`
+ local SOURCE
+ SOURCE=$(grep -E -A 1 "install: ($CYGWINARCH|noarch)/release/[-+_/a-z0-9]*$ARCHIVEESC" $TARBALLS/setup.ini | tail -1 | cut -d " " -f 2)
local SOURCEFILE=${SOURCE##*/}
# Get the source file (either from the source cache or online)
- if [ ! -f $TARBALLS/$SOURCEFILE ] ; then
+ if [ ! -f "$TARBALLS/$SOURCEFILE" ] ; then
if [ -f "$SOURCE_LOCAL_CACHE_CFMT/$SOURCEFILE" ] ; then
cp "$SOURCE_LOCAL_CACHE_CFMT/$SOURCEFILE" $TARBALLS
else
wget "$CYGWIN_REPOSITORY/$SOURCE"
- mv $SOURCEFILE $TARBALLS
+ mv "$SOURCEFILE" "$TARBALLS"
# Save the source archive in the source cache
if [ -d "$SOURCE_LOCAL_CACHE_CFMT" ] ; then
- cp $TARBALLS/$SOURCEFILE "$SOURCE_LOCAL_CACHE_CFMT"
+ cp "$TARBALLS/$SOURCEFILE" "$SOURCE_LOCAL_CACHE_CFMT"
fi
fi
fi
@@ -1281,26 +1295,25 @@ function get_cygwin_mingw_sources {
function make_coq_installer {
make_coq
- make_mingw_make
get_cygwin_mingw_sources
# Prepare the file lists for the installer. We created to file list dumps of the target folder during the build:
# ocaml: ocaml + menhir + camlp5 + findlib
# ocaml_coq: as above + coq
# ocaml_coq_addons: as above + lib/user-contrib/*
-
+
# Create coq file list as ocaml_coq / ocaml
diff_files coq ocaml_coq ocaml
-
+
# Filter out object files
- filter_files coq_objects coq '\.(cmxa|cmi|cma|cmo|a|o)$'
-
+ filter_files coq_objects coq '\.(cmxa|cmi|cma|cmo|a|o)$'
+
# Filter out plugin object files
filter_files coq_objects_plugins coq_objects '/lib/plugins/.*\.(cmxa|cmi|cma|cmo|a|o)$'
-
+
# Coq objects objects required for plugin development = coq objects except those for pre installed plugins
diff_files coq_plugindev coq_objects coq_objects_plugins
-
+
# Addons (TODO: including objects that could go to the plugindev thing, but
# then one would have to make that package depend on this one, so not
# implemented yet)
@@ -1308,45 +1321,46 @@ function make_coq_installer {
# Coq files, except objects needed only for plugin development
diff_files coq_base coq coq_plugindev
-
+
# Convert section files to NSIS format
files_to_nsis coq_base
files_to_nsis coq_addons
files_to_nsis coq_plugindev
files_to_nsis ocaml
-
+
# Get and extract NSIS Binaries
if build_prep http://downloads.sourceforge.net/project/nsis/NSIS%202/2.51 nsis-2.51 zip ; then
- NSIS=`pwd`/makensis.exe
+ NSIS=$(pwd)/makensis.exe
chmod u+x "$NSIS"
# Change to Coq folder
- cd $COQ_BUILD_PATH
+ cd "$COQ_BUILD_PATH"
# Copy patched nsi file
cp ../patches/coq_new.nsi dev/nsis
cp ../patches/StrRep.nsh dev/nsis
cp ../patches/ReplaceInFile.nsh dev/nsis
- VERSION=`grep '^VERSION=' config/Makefile | cut -d = -f 2 | tr -d '\r'`
+ VERSION=$(grep '^VERSION=' config/Makefile | cut -d = -f 2 | tr -d '\r')
cd dev/nsis
- logn nsis-installer "$NSIS" -DVERSION=$VERSION -DARCH=$ARCH -DCOQ_SRC_PATH="$PREFIXCOQ" -DCOQ_ICON=..\\..\\ide\\coq.ico -DCOQ_ADDONS="$COQ_ADDONS" coq_new.nsi
-
+ logn nsis-installer "$NSIS" -DVERSION="$VERSION" -DARCH="$ARCH" -DCOQ_SRC_PATH="$PREFIXCOQ" -DCOQ_ICON=..\\..\\ide\\coq.ico -DCOQ_ADDONS="$COQ_ADDONS" coq_new.nsi
+
build_post
fi
}
###################### ADDONS #####################
+
function make_addon_bignums {
- if build_prep https://github.com/coq/bignums/archive/ V8.8+beta1 zip 1; then
+ if build_prep https://github.com/coq/bignums/archive/ V8.8+beta1 zip 1 bignums-8.8+beta1; then
# To make command lines shorter :-(
echo 'COQ_SRC_SUBDIRS:=$(filter-out plugins/%,$(COQ_SRC_SUBDIRS)) plugins/syntax' >> Makefile.coq.local
- logn make make all
- logn make-install make install
+ log1 make all
+ log2 make install
build_post
fi
}
function make_addons {
for addon in $COQ_ADDONS; do
- make_addon_$addon
+ "make_addon_$addon"
done
}
@@ -1374,4 +1388,3 @@ list_files ocaml_coq_addons
if [ "$MAKEINSTALLER" == "Y" ] ; then
make_coq_installer
fi
-
diff --git a/dev/ci/appveyor.sh b/dev/ci/appveyor.sh
index 524a55a42..93e7bd99a 100644
--- a/dev/ci/appveyor.sh
+++ b/dev/ci/appveyor.sh
@@ -4,6 +4,6 @@ wget https://github.com/fdopen/opam-repository-mingw/releases/download/0.0.0.1/o
tar -xf opam64.tar.xz
bash opam64/install.sh
opam init -a mingw https://github.com/fdopen/opam-repository-mingw.git --comp 4.02.3+mingw64c --switch 4.02.3+mingw64c
-eval $(opam config env)
+eval "$(opam config env)"
opam install -y ocamlfind camlp5
-cd $APPVEYOR_BUILD_FOLDER && ./configure -local && make && make byte && make -C test-suite all INTERACTIVE= && make validate
+cd "$APPVEYOR_BUILD_FOLDER" && ./configure -local && make && make byte && make -C test-suite all INTERACTIVE= && make validate
diff --git a/dev/ci/ci-basic-overlay.sh b/dev/ci/ci-basic-overlay.sh
index 48e01e9e9..5566a5117 100644..100755
--- a/dev/ci/ci-basic-overlay.sh
+++ b/dev/ci/ci-basic-overlay.sh
@@ -142,7 +142,7 @@
########################################################################
# Equations
########################################################################
-: "${Equations_CI_BRANCH:=8.8+alpha}"
+: "${Equations_CI_BRANCH:=master}"
: "${Equations_CI_GITURL:=https://github.com/mattam82/Coq-Equations.git}"
########################################################################
@@ -150,3 +150,9 @@
########################################################################
: "${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}"
diff --git a/dev/ci/ci-bignums.sh b/dev/ci/ci-bignums.sh
index c90e516ae..008291967 100755
--- a/dev/ci/ci-bignums.sh
+++ b/dev/ci/ci-bignums.sh
@@ -6,11 +6,11 @@ ci_dir="$(dirname "$0")"
# Let's avoid to source ci-common twice in this case
if [ -z "${CI_BUILD_DIR}" ];
then
- source ${ci_dir}/ci-common.sh
+ . "${ci_dir}/ci-common.sh"
fi
-bignums_CI_DIR=${CI_BUILD_DIR}/Bignums
+bignums_CI_DIR="${CI_BUILD_DIR}/Bignums"
-git_checkout ${bignums_CI_BRANCH} ${bignums_CI_GITURL} ${bignums_CI_DIR}
+git_checkout "${bignums_CI_BRANCH}" "${bignums_CI_GITURL}" "${bignums_CI_DIR}"
-( cd ${bignums_CI_DIR} && make && make install)
+( cd "${bignums_CI_DIR}" && make && make install)
diff --git a/dev/ci/ci-color.sh b/dev/ci/ci-color.sh
index 558e8cbb8..8ce5f2418 100755
--- a/dev/ci/ci-color.sh
+++ b/dev/ci/ci-color.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
CoLoR_CI_DIR=${CI_BUILD_DIR}/color
# Compile CoLoR
-git_checkout ${CoLoR_CI_BRANCH} ${CoLoR_CI_GITURL} ${CoLoR_CI_DIR}
-( cd ${CoLoR_CI_DIR} && make )
+git_checkout "${CoLoR_CI_BRANCH}" "${CoLoR_CI_GITURL}" "${CoLoR_CI_DIR}"
+( cd "${CoLoR_CI_DIR}" && make )
diff --git a/dev/ci/ci-common.sh b/dev/ci/ci-common.sh
index d7a356930..189734a0b 100644
--- a/dev/ci/ci-common.sh
+++ b/dev/ci/ci-common.sh
@@ -20,7 +20,8 @@ else
export CI_PULL_REQUEST="$CIRCLE_PR_NUMBER"
export CI_BRANCH="$CIRCLE_BRANCH"
else # assume local
- export CI_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
+ CI_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
+ export CI_BRANCH
fi
export COQBIN="$PWD/bin"
fi
@@ -35,10 +36,10 @@ ls "$COQBIN"
CI_BUILD_DIR="$PWD/_build_ci"
# shellcheck source=ci-basic-overlay.sh
-source "${ci_dir}/ci-basic-overlay.sh"
+. "${ci_dir}/ci-basic-overlay.sh"
for overlay in "${ci_dir}"/user-overlays/*.sh; do
# shellcheck source=/dev/null
- source "${overlay}"
+ . "${overlay}"
done
mathcomp_CI_DIR="${CI_BUILD_DIR}/math-comp"
@@ -68,7 +69,7 @@ git_checkout()
checkout_mathcomp()
{
- git_checkout ${mathcomp_CI_BRANCH} ${mathcomp_CI_GITURL} ${1}
+ git_checkout "${mathcomp_CI_BRANCH}" "${mathcomp_CI_GITURL}" "${1}"
}
make()
diff --git a/dev/ci/ci-compcert.sh b/dev/ci/ci-compcert.sh
index 6a0ce2aef..fbdeff20c 100755
--- a/dev/ci/ci-compcert.sh
+++ b/dev/ci/ci-compcert.sh
@@ -1,11 +1,11 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-CompCert_CI_DIR=${CI_BUILD_DIR}/CompCert
+CompCert_CI_DIR="${CI_BUILD_DIR}/CompCert"
opam install -j "$NJOBS" -y menhir
-git_checkout ${CompCert_CI_BRANCH} ${CompCert_CI_GITURL} ${CompCert_CI_DIR}
+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 )
+( cd "${CompCert_CI_DIR}" && ./configure -ignore-coq-version x86_32-linux && make && make check-proof )
diff --git a/dev/ci/ci-coq-dpdgraph.sh b/dev/ci/ci-coq-dpdgraph.sh
index 5d6bd6a36..5d57fce1c 100755
--- a/dev/ci/ci-coq-dpdgraph.sh
+++ b/dev/ci/ci-coq-dpdgraph.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-coq_dpdgraph_CI_DIR=${CI_BUILD_DIR}/coq-dpdgraph
+coq_dpdgraph_CI_DIR="${CI_BUILD_DIR}/coq-dpdgraph"
-git_checkout ${coq_dpdgraph_CI_BRANCH} ${coq_dpdgraph_CI_GITURL} ${coq_dpdgraph_CI_DIR}
+git_checkout "${coq_dpdgraph_CI_BRANCH}" "${coq_dpdgraph_CI_GITURL}" "${coq_dpdgraph_CI_DIR}"
-( cd ${coq_dpdgraph_CI_DIR} && autoconf && ./configure && make && make test-suite )
+( cd "${coq_dpdgraph_CI_DIR}" && autoconf && ./configure && make && make test-suite )
diff --git a/dev/ci/ci-coquelicot.sh b/dev/ci/ci-coquelicot.sh
index 40eff03b7..d86d61ef6 100755
--- a/dev/ci/ci-coquelicot.sh
+++ b/dev/ci/ci-coquelicot.sh
@@ -1,12 +1,12 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-Coquelicot_CI_DIR=${CI_BUILD_DIR}/coquelicot
+Coquelicot_CI_DIR="${CI_BUILD_DIR}/coquelicot"
install_ssreflect
-git_checkout ${Coquelicot_CI_BRANCH} ${Coquelicot_CI_GITURL} ${Coquelicot_CI_DIR}
+git_checkout "${Coquelicot_CI_BRANCH}" "${Coquelicot_CI_GITURL}" "${Coquelicot_CI_DIR}"
-( cd ${Coquelicot_CI_DIR} && ./autogen.sh && ./configure && ./remake -j${NJOBS} )
+( cd "${Coquelicot_CI_DIR}" && ./autogen.sh && ./configure && ./remake "-j${NJOBS}" )
diff --git a/dev/ci/ci-corn.sh b/dev/ci/ci-corn.sh
index 54cad5df4..9298fc70a 100755
--- a/dev/ci/ci-corn.sh
+++ b/dev/ci/ci-corn.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-Corn_CI_DIR=${CI_BUILD_DIR}/corn
+Corn_CI_DIR="${CI_BUILD_DIR}/corn"
-git_checkout ${Corn_CI_BRANCH} ${Corn_CI_GITURL} ${Corn_CI_DIR}
+git_checkout "${Corn_CI_BRANCH}" "${Corn_CI_GITURL}" "${Corn_CI_DIR}"
-( cd ${Corn_CI_DIR} && make && make install )
+( cd "${Corn_CI_DIR}" && make && make install )
diff --git a/dev/ci/ci-cpdt.sh b/dev/ci/ci-cpdt.sh
index 8b725f6fe..ca759c7b3 100755
--- a/dev/ci/ci-cpdt.sh
+++ b/dev/ci/ci-cpdt.sh
@@ -1,10 +1,9 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
wget http://adam.chlipala.net/cpdt/cpdt.tgz
tar xvfz cpdt.tgz
( cd cpdt && make clean && make )
-
diff --git a/dev/ci/ci-elpi.sh b/dev/ci/ci-elpi.sh
index c44e0a655..9c58034be 100755
--- a/dev/ci/ci-elpi.sh
+++ b/dev/ci/ci-elpi.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-Elpi_CI_DIR=${CI_BUILD_DIR}/elpi
+Elpi_CI_DIR="${CI_BUILD_DIR}/elpi"
-git_checkout ${Elpi_CI_BRANCH} ${Elpi_CI_GITURL} ${Elpi_CI_DIR}
+git_checkout "${Elpi_CI_BRANCH}" "${Elpi_CI_GITURL}" "${Elpi_CI_DIR}"
-( cd ${Elpi_CI_DIR} && make && make install )
+( cd "${Elpi_CI_DIR}" && make && make install )
diff --git a/dev/ci/ci-equations.sh b/dev/ci/ci-equations.sh
index 62854afac..98735b4ec 100755
--- a/dev/ci/ci-equations.sh
+++ b/dev/ci/ci-equations.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-Equations_CI_DIR=${CI_BUILD_DIR}/Equations
+Equations_CI_DIR="${CI_BUILD_DIR}/Equations"
-git_checkout ${Equations_CI_BRANCH} ${Equations_CI_GITURL} ${Equations_CI_DIR}
+git_checkout "${Equations_CI_BRANCH}" "${Equations_CI_GITURL}" "${Equations_CI_DIR}"
-( cd ${Equations_CI_DIR} && coq_makefile -f _CoqProject -o Makefile && make && make test-suite && make examples && make install)
+( cd "${Equations_CI_DIR}" && coq_makefile -f _CoqProject -o Makefile && make && make test-suite && make examples && make install)
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 5ca3ac47f..845addb4c 100755
--- a/dev/ci/ci-fiat-crypto.sh
+++ b/dev/ci/ci-fiat-crypto.sh
@@ -1,11 +1,11 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-fiat_crypto_CI_DIR=${CI_BUILD_DIR}/fiat-crypto
+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 )
+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-fiat-parsers.sh b/dev/ci/ci-fiat-parsers.sh
index 292331b81..35c228405 100755
--- a/dev/ci/ci-fiat-parsers.sh
+++ b/dev/ci/ci-fiat-parsers.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-fiat_parsers_CI_DIR=${CI_BUILD_DIR}/fiat
+fiat_parsers_CI_DIR="${CI_BUILD_DIR}/fiat"
-git_checkout ${fiat_parsers_CI_BRANCH} ${fiat_parsers_CI_GITURL} ${fiat_parsers_CI_DIR}
+git_checkout "${fiat_parsers_CI_BRANCH}" "${fiat_parsers_CI_GITURL}" "${fiat_parsers_CI_DIR}"
-( cd ${fiat_parsers_CI_DIR} && make parsers parsers-examples && make fiat-core )
+( cd "${fiat_parsers_CI_DIR}" && make parsers parsers-examples && make fiat-core )
diff --git a/dev/ci/ci-flocq.sh b/dev/ci/ci-flocq.sh
index ec19bd993..8599e4d50 100755
--- a/dev/ci/ci-flocq.sh
+++ b/dev/ci/ci-flocq.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-Flocq_CI_DIR=${CI_BUILD_DIR}/flocq
+Flocq_CI_DIR="${CI_BUILD_DIR}/flocq"
-git_checkout ${Flocq_CI_BRANCH} ${Flocq_CI_GITURL} ${Flocq_CI_DIR}
+git_checkout "${Flocq_CI_BRANCH}" "${Flocq_CI_GITURL}" "${Flocq_CI_DIR}"
-( cd ${Flocq_CI_DIR} && ./autogen.sh && ./configure && ./remake -j${NJOBS} )
+( cd "${Flocq_CI_DIR}" && ./autogen.sh && ./configure && ./remake "-j${NJOBS}" )
diff --git a/dev/ci/ci-formal-topology.sh b/dev/ci/ci-formal-topology.sh
index 53eb55fc4..118d15150 100755
--- a/dev/ci/ci-formal-topology.sh
+++ b/dev/ci/ci-formal-topology.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-formal_topology_CI_DIR=${CI_BUILD_DIR}/formal-topology
+formal_topology_CI_DIR="${CI_BUILD_DIR}/formal-topology"
-git_checkout ${formal_topology_CI_BRANCH} ${formal_topology_CI_GITURL} ${formal_topology_CI_DIR}
+git_checkout "${formal_topology_CI_BRANCH}" "${formal_topology_CI_GITURL}" "${formal_topology_CI_DIR}"
-( cd ${formal_topology_CI_DIR} && make )
+( cd "${formal_topology_CI_DIR}" && make )
diff --git a/dev/ci/ci-geocoq.sh b/dev/ci/ci-geocoq.sh
index 8e6448e76..bd1d88993 100755
--- a/dev/ci/ci-geocoq.sh
+++ b/dev/ci/ci-geocoq.sh
@@ -1,12 +1,12 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-GeoCoq_CI_DIR=${CI_BUILD_DIR}/GeoCoq
+GeoCoq_CI_DIR="${CI_BUILD_DIR}/GeoCoq"
-git_checkout ${GeoCoq_CI_BRANCH} ${GeoCoq_CI_GITURL} ${GeoCoq_CI_DIR}
+git_checkout "${GeoCoq_CI_BRANCH}" "${GeoCoq_CI_GITURL}" "${GeoCoq_CI_DIR}"
-( cd ${GeoCoq_CI_DIR} && \
+( cd "${GeoCoq_CI_DIR}" && \
./configure-ci.sh && \
make )
diff --git a/dev/ci/ci-hott.sh b/dev/ci/ci-hott.sh
index 693135a4c..6ded97984 100755
--- a/dev/ci/ci-hott.sh
+++ b/dev/ci/ci-hott.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-HoTT_CI_DIR=${CI_BUILD_DIR}/HoTT
+HoTT_CI_DIR="${CI_BUILD_DIR}"/HoTT
-git_checkout ${HoTT_CI_BRANCH} ${HoTT_CI_GITURL} ${HoTT_CI_DIR}
+git_checkout "${HoTT_CI_BRANCH}" "${HoTT_CI_GITURL}" "${HoTT_CI_DIR}"
-( cd ${HoTT_CI_DIR} && ./autogen.sh && ./configure && make )
+( cd "${HoTT_CI_DIR}" && ./autogen.sh && ./configure && make )
diff --git a/dev/ci/ci-iris-lambda-rust.sh b/dev/ci/ci-iris-lambda-rust.sh
index 267e13359..1af0f634c 100755
--- a/dev/ci/ci-iris-lambda-rust.sh
+++ b/dev/ci/ci-iris-lambda-rust.sh
@@ -1,41 +1,34 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-stdpp_CI_DIR=${CI_BUILD_DIR}/coq-stdpp
-Iris_CI_DIR=${CI_BUILD_DIR}/iris-coq
-lambdaRust_CI_DIR=${CI_BUILD_DIR}/lambdaRust
+stdpp_CI_DIR="${CI_BUILD_DIR}/coq-stdpp"
+Iris_CI_DIR="${CI_BUILD_DIR}/iris-coq"
+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}
+git_checkout "${lambdaRust_CI_BRANCH}" "${lambdaRust_CI_GITURL}" "${lambdaRust_CI_DIR}"
# Extract required version of Iris
-Iris_VERSION=$(cat ${lambdaRust_CI_DIR}/opam | fgrep coq-iris | egrep 'dev\.([0-9.-]+)' -o)
-Iris_URL=$(opam show coq-iris.$Iris_VERSION -f upstream-url)
-read -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=$(cat ${Iris_CI_DIR}/opam | fgrep coq-stdpp | egrep 'dev\.([0-9.-]+)' -o)
-stdpp_URL=$(opam show coq-stdpp.$stdpp_VERSION -f upstream-url)
-read -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 )
+( cd "${stdpp_CI_DIR}" && make && make install )
# Build and validate (except on Travis, i.e., skip if TRAVIS is non-empty) Iris
-( cd ${Iris_CI_DIR} && make && (test -n "${TRAVIS}" || make validate) && make install )
+( cd "${Iris_CI_DIR}" && make && (test -n "${TRAVIS}" || make validate) && make install )
# Build lambdaRust
-( cd ${lambdaRust_CI_DIR} && make && make install )
+( cd "${lambdaRust_CI_DIR}" && make && make install )
diff --git a/dev/ci/ci-ltac2.sh b/dev/ci/ci-ltac2.sh
index 820ff89ee..5981aaaae 100755
--- a/dev/ci/ci-ltac2.sh
+++ b/dev/ci/ci-ltac2.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-ltac2_CI_DIR=${CI_BUILD_DIR}/ltac2
+ltac2_CI_DIR="${CI_BUILD_DIR}/ltac2"
-git_checkout ${ltac2_CI_BRANCH} ${ltac2_CI_GITURL} ${ltac2_CI_DIR}
+git_checkout "${ltac2_CI_BRANCH}" "${ltac2_CI_GITURL}" "${ltac2_CI_DIR}"
-( cd ${ltac2_CI_DIR} && make && make tests && make install )
+( cd "${ltac2_CI_DIR}" && make && make tests && make install )
diff --git a/dev/ci/ci-math-classes.sh b/dev/ci/ci-math-classes.sh
index db4a31e54..4fc06e895 100755
--- a/dev/ci/ci-math-classes.sh
+++ b/dev/ci/ci-math-classes.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-math_classes_CI_DIR=${CI_BUILD_DIR}/math-classes
+math_classes_CI_DIR="${CI_BUILD_DIR}/math-classes"
-git_checkout ${math_classes_CI_BRANCH} ${math_classes_CI_GITURL} ${math_classes_CI_DIR}
+git_checkout "${math_classes_CI_BRANCH}" "${math_classes_CI_GITURL}" "${math_classes_CI_DIR}"
-( cd ${math_classes_CI_DIR} && make && make install )
+( cd "${math_classes_CI_DIR}" && make && make install )
diff --git a/dev/ci/ci-math-comp.sh b/dev/ci/ci-math-comp.sh
index 701403f2c..8c6b910bb 100755
--- a/dev/ci/ci-math-comp.sh
+++ b/dev/ci/ci-math-comp.sh
@@ -2,14 +2,14 @@
# $0 is not the safest way, but...
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-mathcomp_CI_DIR=${CI_BUILD_DIR}/math-comp
+mathcomp_CI_DIR="${CI_BUILD_DIR}/math-comp"
-checkout_mathcomp ${mathcomp_CI_DIR}
+checkout_mathcomp "${mathcomp_CI_DIR}"
# odd_order takes too much time for travis.
-( cd ${mathcomp_CI_DIR}/mathcomp && \
+( cd "${mathcomp_CI_DIR}/mathcomp" && \
sed -i.bak '/PFsection/d' Make && \
sed -i.bak '/stripped_odd_order_theorem/d' Make && \
make Makefile.coq && make -f Makefile.coq all )
diff --git a/dev/ci/ci-metacoq.sh b/dev/ci/ci-metacoq.sh
index c813b1fe9..a66dc1e76 100755
--- a/dev/ci/ci-metacoq.sh
+++ b/dev/ci/ci-metacoq.sh
@@ -1,19 +1,19 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
unicoq_CI_DIR=${CI_BUILD_DIR}/unicoq
metacoq_CI_DIR=${CI_BUILD_DIR}/MetaCoq
# Setup UniCoq
-git_checkout ${unicoq_CI_BRANCH} ${unicoq_CI_GITURL} ${unicoq_CI_DIR}
+git_checkout "${unicoq_CI_BRANCH}" "${unicoq_CI_GITURL}" "${unicoq_CI_DIR}"
-( cd ${unicoq_CI_DIR} && coq_makefile -f Make -o Makefile && make && make install )
+( cd "${unicoq_CI_DIR}" && coq_makefile -f Make -o Makefile && make && make install )
# Setup MetaCoq
-git_checkout ${metacoq_CI_BRANCH} ${metacoq_CI_GITURL} ${metacoq_CI_DIR}
+git_checkout "${metacoq_CI_BRANCH}" "${metacoq_CI_GITURL}" "${metacoq_CI_DIR}"
-( cd ${metacoq_CI_DIR} && coq_makefile -f _CoqProject -o Makefile && make )
+( cd "${metacoq_CI_DIR}" && coq_makefile -f _CoqProject -o Makefile && make )
diff --git a/dev/ci/ci-sf.sh b/dev/ci/ci-sf.sh
index 4e8c7e145..58bbb7229 100755
--- a/dev/ci/ci-sf.sh
+++ b/dev/ci/ci-sf.sh
@@ -1,35 +1,16 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-mkdir -p ${CI_BUILD_DIR} && cd ${CI_BUILD_DIR}
-wget -qO- ${sf_lf_CI_TARURL} | tar xvz
-wget -qO- ${sf_plf_CI_TARURL} | tar xvz
-wget -qO- ${sf_vfa_CI_TARURL} | tar xvz
+mkdir -p "${CI_BUILD_DIR}" && cd "${CI_BUILD_DIR}" || exit 1
+wget -qO- "${sf_lf_CI_TARURL}" | tar xvz
+wget -qO- "${sf_plf_CI_TARURL}" | tar xvz
+wget -qO- "${sf_vfa_CI_TARURL}" | tar xvz
sed -i.bak '1i From Coq Require Extraction.' lf/Extraction.v
sed -i.bak '1i From Coq Require Extraction.' vfa/Extract.v
-# Delete useless calls to try omega; unfold
-patch vfa/SearchTree.v <<EOF
-*** SearchTree.v.bak 2017-09-06 19:12:59.000000000 +0200
---- SearchTree.v 2017-11-21 16:34:41.000000000 +0100
-***************
-*** 674,683 ****
- forall i j : key, ~ (i > j) -> ~ (i < j) -> i=j.
- Proof.
- intros.
-- try omega. (* Oops! [omega] cannot solve this one.
-- The problem is that [i] and [j] have type [key] instead of type [nat].
-- The solution is easy enough: *)
-- unfold key in *.
- omega.
-
- (** So, if you get stuck on an [omega] that ought to work,
---- 674,679 ----
-EOF
-
( cd lf && make clean && make )
( cd plf && sed -i.bak 's/(K,N)/((K,N))/' LibTactics.v && make clean && make )
diff --git a/dev/ci/ci-template.sh b/dev/ci/ci-template.sh
index 25da01a82..e77a55304 100755
--- a/dev/ci/ci-template.sh
+++ b/dev/ci/ci-template.sh
@@ -1,12 +1,12 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
Template_CI_BRANCH=master
Template_CI_GITURL=https://github.com/Template/Template
-Template_CI_DIR=${CI_BUILD_DIR}/Template
+Template_CI_DIR="${CI_BUILD_DIR}/Template"
-git_checkout ${Template_CI_BRANCH} ${Template_CI_GITURL} ${Template_CI_DIR}
+git_checkout "${Template_CI_BRANCH}" "${Template_CI_GITURL}" "${Template_CI_DIR}"
-( cd ${Template_CI_DIR} && make )
+( cd "${Template_CI_DIR}" && make )
diff --git a/dev/ci/ci-tlc.sh b/dev/ci/ci-tlc.sh
index 8ecd8c441..31387c8dd 100755
--- a/dev/ci/ci-tlc.sh
+++ b/dev/ci/ci-tlc.sh
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-tlc_CI_DIR=${CI_BUILD_DIR}/tlc
+tlc_CI_DIR="${CI_BUILD_DIR}/tlc"
-git_checkout ${tlc_CI_BRANCH} ${tlc_CI_GITURL} ${tlc_CI_DIR}
+git_checkout "${tlc_CI_BRANCH}" "${tlc_CI_GITURL}" "${tlc_CI_DIR}"
-( cd ${tlc_CI_DIR} && make )
+( cd "${tlc_CI_DIR}" && make )
diff --git a/dev/ci/ci-unimath.sh b/dev/ci/ci-unimath.sh
index 66b56add7..62a949f59 100755
--- a/dev/ci/ci-unimath.sh
+++ b/dev/ci/ci-unimath.sh
@@ -1,14 +1,13 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-UniMath_CI_DIR=${CI_BUILD_DIR}/UniMath
+UniMath_CI_DIR="${CI_BUILD_DIR}/UniMath"
-git_checkout ${UniMath_CI_BRANCH} ${UniMath_CI_GITURL} ${UniMath_CI_DIR}
+git_checkout "${UniMath_CI_BRANCH}" "${UniMath_CI_GITURL}" "${UniMath_CI_DIR}"
-( cd ${UniMath_CI_DIR} && \
+( cd "${UniMath_CI_DIR}" && \
sed -i.bak '/Folds/d' Makefile && \
sed -i.bak '/HomologicalAlgebra/d' Makefile && \
make BUILD_COQ=no )
-
diff --git a/dev/ci/ci-vst.sh b/dev/ci/ci-vst.sh
index 5760fbafb..3c0044bfe 100755
--- a/dev/ci/ci-vst.sh
+++ b/dev/ci/ci-vst.sh
@@ -1,13 +1,13 @@
#!/usr/bin/env bash
ci_dir="$(dirname "$0")"
-source ${ci_dir}/ci-common.sh
+. "${ci_dir}/ci-common.sh"
-VST_CI_DIR=${CI_BUILD_DIR}/VST
+VST_CI_DIR="${CI_BUILD_DIR}/VST"
# opam install -j ${NJOBS} -y menhir
-git_checkout ${VST_CI_BRANCH} ${VST_CI_GITURL} ${VST_CI_DIR}
+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 )
+( cd "${VST_CI_DIR}" && make IGNORECOQVERSION=true .loadpath version.vo msl veric floyd )
diff --git a/dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh b/dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh
index 7716bcb59..e9ba11414 100644
--- a/dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh
+++ b/dev/ci/user-overlays/00669-maximedenes-ssr-merge.sh
@@ -1,3 +1,5 @@
+#!/bin/sh
+
if [ "$CI_PULL_REQUEST" = "669" ] || [ "$CI_BRANCH" = "ssr-merge" ]; then
mathcomp_CI_BRANCH=ssr-merge
mathcomp_CI_GITURL=https://github.com/maximedenes/math-comp.git
diff --git a/dev/ci/user-overlays/06405-maximedenes-rm-local-polymorphic-flag.sh b/dev/ci/user-overlays/06405-maximedenes-rm-local-polymorphic-flag.sh
deleted file mode 100644
index c2e367038..000000000
--- a/dev/ci/user-overlays/06405-maximedenes-rm-local-polymorphic-flag.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6405" ] || [ "$CI_BRANCH" = "rm-local-polymorphic-flag" ]; then
- Equations_CI_BRANCH=rm-local-polymorphic-flag
- Equations_CI_GITURL=https://github.com/maximedenes/Coq-Equations
-fi
diff --git a/dev/ci/user-overlays/06454-ejgallego-evar+strict_to_constr.sh b/dev/ci/user-overlays/06454-ejgallego-evar+strict_to_constr.sh
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/06482-ppedrot-check-poly-effects.sh b/dev/ci/user-overlays/06482-ppedrot-check-poly-effects.sh
deleted file mode 100644
index 78789a6fc..000000000
--- a/dev/ci/user-overlays/06482-ppedrot-check-poly-effects.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-if [ "$TRAVIS_PULL_REQUEST" = "6483" ] || [ "$TRAVIS_BRANCH" = "check-poly-effects" ]; then
- HoTT_CI_BRANCH=check-poly-effects
- HoTT_CI_GITURL=https://github.com/ppedrot/HoTT.git
-fi
diff --git a/dev/ci/user-overlays/06493-gares-API-remove-big-file.sh b/dev/ci/user-overlays/06493-gares-API-remove-big-file.sh
deleted file mode 100644
index 9677b3525..000000000
--- a/dev/ci/user-overlays/06493-gares-API-remove-big-file.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6493" ] || [ "$CI_BRANCH" = "API/remove-big-file" ]; then
- Equations_CI_BRANCH=API-removal
- Equations_CI_GITURL=https://github.com/gares/Coq-Equations.git
- coq_dpdgraph_CI_BRANCH=API-removal
- coq_dpdgraph_CI_GITURL=https://github.com/gares/coq-dpdgraph.git
- ltac2_CI_BRANCH=API-removal
- ltac2_CI_GITURL=https://github.com/gares/ltac2.git
-fi
diff --git a/dev/ci/user-overlays/06511-ejgallego-econstr+more_fix.sh b/dev/ci/user-overlays/06511-ejgallego-econstr+more_fix.sh
deleted file mode 100644
index 4b681909d..000000000
--- a/dev/ci/user-overlays/06511-ejgallego-econstr+more_fix.sh
+++ /dev/null
@@ -1,7 +0,0 @@
- if [ "$CI_PULL_REQUEST" = "6511" ] || [ "$CI_BRANCH" = "econstr+more_fix" ]; then
- ltac2_CI_BRANCH=econstr+more_fix
- ltac2_CI_GITURL=https://github.com/ejgallego/ltac2
-
- Equations_CI_BRANCH=econstr+more_fix
- Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
-fi
diff --git a/dev/ci/user-overlays/06535-fix-push-rel-to-named.sh b/dev/ci/user-overlays/06535-fix-push-rel-to-named.sh
deleted file mode 100644
index 8a50fb111..000000000
--- a/dev/ci/user-overlays/06535-fix-push-rel-to-named.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6535" ] || [ "$CI_BRANCH" = "fix-push-rel-to-named" ]; then
- Equations_CI_BRANCH=fix-6535
- Equations_CI_GITURL=https://github.com/ppedrot/Coq-Equations
-fi
diff --git a/dev/ci/user-overlays/06676-gares-proofview-goals-come-with-a-state.sh b/dev/ci/user-overlays/06676-gares-proofview-goals-come-with-a-state.sh
deleted file mode 100644
index 2451657d4..000000000
--- a/dev/ci/user-overlays/06676-gares-proofview-goals-come-with-a-state.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6676" ] || [ "$CI_BRANCH" = "proofview/goal-w-state" ]; then
- ltac2_CI_BRANCH=fix-for/6676
- ltac2_CI_GITURL=https://github.com/gares/ltac2.git
- Equations_CI_BRANCH=fix-for/6676
- Equations_CI_GITURL=https://github.com/gares/Coq-Equations.git
-fi
diff --git a/dev/ci/user-overlays/06686-ccnv-no-proj.sh b/dev/ci/user-overlays/06686-ccnv-no-proj.sh
deleted file mode 100644
index 3a3ab44e0..000000000
--- a/dev/ci/user-overlays/06686-ccnv-no-proj.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6686" ] || [ "$CI_BRANCH" = "ccnv-no-proj" ]; then
- Equations_CI_BRANCH=ccnv-fixes
- Equations_CI_GITURL=https://github.com/SkySkimmer/Coq-Equations
-fi
diff --git a/dev/ci/user-overlays/06745-ejgallego-located+vernac.sh b/dev/ci/user-overlays/06745-ejgallego-located+vernac.sh
deleted file mode 100644
index d1d61fec2..000000000
--- a/dev/ci/user-overlays/06745-ejgallego-located+vernac.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6745" ] || [ "$CI_BRANCH" = "located+vernac" ]; then
- ltac2_CI_BRANCH=located+vernac
- ltac2_CI_GITURL=https://github.com/ejgallego/ltac2
-
- Equations_CI_BRANCH=located+vernac
- Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
-
- fiat_parsers_CI_BRANCH=located+vernac
- fiat_parsers_CI_GITURL=https://github.com/ejgallego/fiat
-
- Elpi_CI_BRANCH=located+vernac
- Elpi_CI_GITURL=https://github.com/ejgallego/coq-elpi.git
-fi
diff --git a/dev/ci/user-overlays/06775-univ-cumul-weak.sh b/dev/ci/user-overlays/06775-univ-cumul-weak.sh
deleted file mode 100644
index 8afcbf78a..000000000
--- a/dev/ci/user-overlays/06775-univ-cumul-weak.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6775" ] || [ "$CI_BRANCH" = "univ-cumul" ]; then
- Elpi_CI_BRANCH=coq-master
- Elpi_CI_GITURL=https://github.com/SkySkimmer/coq-elpi.git
-fi
diff --git a/dev/ci/user-overlays/06831-ejgallego-located+vernac_2.sh b/dev/ci/user-overlays/06831-ejgallego-located+vernac_2.sh
deleted file mode 100644
index df3e9cef2..000000000
--- a/dev/ci/user-overlays/06831-ejgallego-located+vernac_2.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6831" ] || [ "$CI_BRANCH" = "located+vernac_2" ]; then
-
- ltac2_CI_BRANCH=located+vernac_2
- ltac2_CI_GITURL=https://github.com/ejgallego/ltac2
-
- Equations_CI_BRANCH=located+vernac_2
- Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
-
- # fiat_parsers_CI_BRANCH=located+vernac
- # fiat_parsers_CI_GITURL=https://github.com/ejgallego/fiat
-
- Elpi_CI_BRANCH=located+vernac_2
- Elpi_CI_GITURL=https://github.com/ejgallego/coq-elpi.git
-fi
diff --git a/dev/ci/user-overlays/06837-ejgallego-located+libnames.sh b/dev/ci/user-overlays/06837-ejgallego-located+libnames.sh
deleted file mode 100644
index a785290e7..000000000
--- a/dev/ci/user-overlays/06837-ejgallego-located+libnames.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6837" ] || [ "$CI_BRANCH" = "located+libnames" ]; then
-
- ltac2_CI_BRANCH=located+libnames
- ltac2_CI_GITURL=https://github.com/ejgallego/ltac2
-
- Equations_CI_BRANCH=located+libnames
- Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
-
- Elpi_CI_BRANCH=located+libnames
- Elpi_CI_GITURL=https://github.com/ejgallego/coq-elpi.git
-
- coq_dpdgraph_CI_BRANCH=located+libnames
- coq_dpdgraph_CI_GITURL=https://github.com/ejgallego/coq-dpdgraph.git
-
-fi
diff --git a/dev/ci/user-overlays/06869-ejgallego-ssr+correct_packing.sh b/dev/ci/user-overlays/06869-ejgallego-ssr+correct_packing.sh
deleted file mode 100644
index 5dedca0ca..000000000
--- a/dev/ci/user-overlays/06869-ejgallego-ssr+correct_packing.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6869" ] || [ "$CI_BRANCH" = "ssr+correct_packing" ]; 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=ssr+correct_packing
- Elpi_CI_GITURL=https://github.com/ejgallego/coq-elpi.git
-
-fi
diff --git a/dev/ci/user-overlays/06923-ppedrot-export-options.sh b/dev/ci/user-overlays/06923-ppedrot-export-options.sh
deleted file mode 100644
index 333a9e84b..000000000
--- a/dev/ci/user-overlays/06923-ppedrot-export-options.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-if [ "$CI_PULL_REQUEST" = "6923" ] || [ "$CI_BRANCH" = "export-options" ]; then
- ltac2_CI_BRANCH=export-options
- ltac2_CI_GITURL=https://github.com/ppedrot/ltac2
-
- Equations_CI_BRANCH=export-options
- Equations_CI_GITURL=https://github.com/ppedrot/Coq-Equations
-fi
diff --git a/dev/ci/user-overlays/06960-ejgallego-ltac+tacdepr.sh b/dev/ci/user-overlays/06960-ejgallego-ltac+tacdepr.sh
new file mode 100644
index 000000000..cf2af9ae9
--- /dev/null
+++ b/dev/ci/user-overlays/06960-ejgallego-ltac+tacdepr.sh
@@ -0,0 +1,12 @@
+if [ "$CI_PULL_REQUEST" = "6960" ] || [ "$CI_BRANCH" = "ltac+tacdepr" ]; then
+
+ # Equations_CI_BRANCH=ssr+correct_packing
+ # Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations
+
+ ltac2_CI_BRANCH=ltac+tacdepr
+ ltac2_CI_GITURL=https://github.com/ejgallego/ltac2
+
+ # Elpi_CI_BRANCH=ssr+correct_packing
+ # Elpi_CI_GITURL=https://github.com/ejgallego/coq-elpi.git
+
+fi
diff --git a/dev/ci/user-overlays/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/README.md b/dev/ci/user-overlays/README.md
index 9f0377cee..a7474e324 100644
--- a/dev/ci/user-overlays/README.md
+++ b/dev/ci/user-overlays/README.md
@@ -7,6 +7,8 @@ The name of your overlay file should be of the form `five_digit_PR_number-GitHub
Example: `00669-maximedenes-ssr-merge.sh` containing
```
+#!/bin/sh
+
if [ "$CI_PULL_REQUEST" = "669" ] || [ "$CI_BRANCH" = "ssr-merge" ]; then
mathcomp_CI_BRANCH=ssr-merge
mathcomp_CI_GITURL=https://github.com/maximedenes/math-comp.git
diff --git a/dev/doc/MERGING.md b/dev/doc/MERGING.md
index 71fc39608..84ff94c66 100644
--- a/dev/doc/MERGING.md
+++ b/dev/doc/MERGING.md
@@ -1,6 +1,7 @@
# Merging changes in Coq
-This document describes how patches (submitted as Pull Requests) should be
+This document describes how patches (submitted as pull requests
+on the `master` branch) should be
merged into the main repository (https://github.com/coq/coq).
## Code owners
@@ -65,14 +66,57 @@ In some rare cases (e.g. the conflicts are in the CHANGES file), it is ok to fix
the conflicts in the merge commit (following the same steps as below), and push
to `master` directly. Don't use the GitHub interface to fix these conflicts.
-The command to be used is:
+To merge the PR proceed in the following way
```
-$ dev/tools/merge-pr XXXX
+$ git checkout master
+$ git pull
+$ dev/tools/merge-pr.sh XXXX
+$ git push upstream
```
-where `XXXX` is the number of the PR to be merged. This operation should be followed by a push.
+where `XXXX` is the number of the PR to be merged and `upstream` is the name
+of your remote pointing to `git@github.com:coq/coq.git`.
+Note that you are only supposed to merge PRs into `master`. PRs should rarely
+target the stable branch, but when it is the case they are the responsibility
+of the release manager.
+
+This script conducts various checks before proceeding to merge. Don't bypass them
+without a good reason to, and in that case, write a comment in the PR thread to
+explain the reason.
Maintainers MUST NOT merge their own patches.
DON'T USE the GitHub interface for merging, since it will prevent the automated
backport script from operating properly, generates bad commit messages, and a
messy history when there are conflicts.
+
+### What to do if the PR has overlays
+
+If the PR breaks compatibility of some developments in CI, then the author must
+have prepared overlays for these developments (see [`dev/ci/README.md`](/dev/ci/README.md))
+and the PR must absolutely update the `CHANGES` file.
+
+There are two cases to consider:
+
+- If the patch is backward compatible (best scenario), then you should get
+ upstream maintainers to integrate it before merging the PR.
+- If the patch is not backward compatible (which is often the case when
+ patching plugins after an update to the Coq API), then you can proceed to
+ merge the PR and then notify upstream they can merge the patch. This is a
+ less preferable scenario because it is probably going to create
+ spurious CI failures for unrelated PRs.
+
+### Merge script dependencies
+
+The merge script passes option `-S` to `git merge` to ensure merge commits
+are signed. Consequently, it depends on the GnuPG command utility being
+installed and a GPG key being available. Here is a short tutorial to
+creating your own GPG key:
+<https://ekaia.org/blog/2009/05/10/creating-new-gpgkey/>
+
+The script depends on a few other utilities. If you are a Nix user, the
+simplest way of getting them is to run `nix-shell` first.
+
+**Note for homebrew (MacOS) users:** it has been reported that installing GnuPG
+is not out of the box. Installing explicitly "pinentry-mac" seems important for
+typing of passphrase to work correctly (see also this
+[Stack Overflow Q-and-A](https://stackoverflow.com/questions/39494631/gpg-failed-to-sign-the-data-fatal-failed-to-write-commit-object-git-2-10-0)).
diff --git a/dev/doc/changes.md b/dev/doc/changes.md
index ab78b0956..2bad21bb2 100644
--- a/dev/doc/changes.md
+++ b/dev/doc/changes.md
@@ -1,3 +1,23 @@
+## 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.
+
## Changes between Coq 8.7 and Coq 8.8
### Bug tracker
diff --git a/dev/lint-repository.sh b/dev/lint-repository.sh
index ee9c8777a..cd09b6d30 100755
--- a/dev/lint-repository.sh
+++ b/dev/lint-repository.sh
@@ -31,4 +31,6 @@ fi
find . "(" -path ./.git -prune ")" -o -type f -print0 |
xargs -0 dev/tools/check-eof-newline.sh || CODE=1
+dev/tools/check-overlays.sh || CODE=1
+
exit $CODE
diff --git a/dev/tools/backport-pr.sh b/dev/tools/backport-pr.sh
index e4359f703..5205350a6 100755
--- a/dev/tools/backport-pr.sh
+++ b/dev/tools/backport-pr.sh
@@ -27,9 +27,9 @@ BRANCH=backport-pr-${PRNUM}
RANGE=$(git log master --grep "Merge PR #${PRNUM}" --format="%P" | sed 's/ /../')
MESSAGE=$(git log master --grep "Merge PR #${PRNUM}" --format="%s" | sed 's/Merge/Backport/')
-if git checkout -b ${BRANCH}; then
+if git checkout -b "${BRANCH}"; then
- if ! git cherry-pick -x ${RANGE}; then
+ if ! git cherry-pick -x "${RANGE}"; then
echo "Please fix the conflicts, then exit."
bash
while ! git cherry-pick --continue; do
@@ -50,7 +50,7 @@ else
fi
-if ! git diff --exit-code HEAD ${BRANCH} -- "*.mli"; then
+if ! git diff --exit-code HEAD "${BRANCH}" -- "*.mli"; then
echo
read -p "Some mli files are modified. Bypass? [y/N] " -n 1 -r
echo
@@ -63,8 +63,8 @@ if [[ "${OPTION}" == "--stop-before-merging" ]]; then
exit 0
fi
-git merge -S --no-ff ${BRANCH} -m "${MESSAGE}"
-git branch -d ${BRANCH}
+git merge -S --no-ff "${BRANCH}" -m "${MESSAGE}"
+git branch -d "${BRANCH}"
# To-Do:
# - Support for backporting a PR before it is merged
diff --git a/dev/tools/check-overlays.sh b/dev/tools/check-overlays.sh
new file mode 100755
index 000000000..f7e05b51c
--- /dev/null
+++ b/dev/tools/check-overlays.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+for f in dev/ci/user-overlays/*
+do
+ if ! ([[ $f = dev/ci/user-overlays/README.md ]] || [[ $f == *.sh ]])
+ then
+ >&2 echo "Bad overlay '$f'."
+ >&2 echo "User overlays need to have extension .sh to be picked up!"
+ exit 1
+ fi
+done
diff --git a/dev/tools/merge-pr.sh b/dev/tools/merge-pr.sh
index 2f6f1af54..00d04e6b3 100755
--- a/dev/tools/merge-pr.sh
+++ b/dev/tools/merge-pr.sh
@@ -4,11 +4,20 @@ set -e
set -o pipefail
API=https://api.github.com/repos/coq/coq
-OFFICIAL_REMOTE_URL="git@github.com:coq/coq"
+OFFICIAL_REMOTE_GIT_URL="git@github.com:coq/coq"
+OFFICIAL_REMOTE_HTTPS_URL="github.com/coq/coq"
-# This script depends (at least) on git and jq.
+# This script depends (at least) on git (>= 2.7) and jq.
# It should be used like this: dev/tools/merge-pr.sh /PR number/
+# Set SLOW_CONF to have the confirmation output wait for a newline
+# E.g. call $ SLOW_CONF= dev/tools/merge-pr.sh /PR number/
+if [ -z ${SLOW_CONF+x} ]; then
+ QUICK_CONF="-n 1"
+else
+ QUICK_CONF=""
+fi
+
RED="\033[31m"
RESET="\033[0m"
GREEN="\033[32m"
@@ -32,7 +41,7 @@ fi
}
ask_confirmation() {
- read -p "Continue anyway? [y/N] " -n 1 -r
+ read -p "Continue anyway? [y/N] " $QUICK_CONF -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]
then
@@ -61,10 +70,12 @@ fi
# Fetching PR metadata
-TITLE=$(curl -s "$API/pulls/$PR" | jq -r '.title')
+PRDATA=$(curl -s "$API/pulls/$PR")
+
+TITLE=$(echo "$PRDATA" | jq -r '.title')
info "title for PR $PR is ${BLUE}$TITLE"
-BASE_BRANCH=$(curl -s "$API/pulls/$PR" | jq -r '.base.label')
+BASE_BRANCH=$(echo "$PRDATA" | jq -r '.base.label')
info "PR $PR targets branch ${BLUE}$BASE_BRANCH"
CURRENT_LOCAL_BRANCH=$(git rev-parse --abbrev-ref HEAD)
@@ -77,11 +88,15 @@ if [ -z "$REMOTE" ]; then
error "please run: git branch --set-upstream-to=THE_REMOTE/$CURRENT_LOCAL_BRANCH"
exit 1
fi
-REMOTE_URL=$(git remote get-url "$REMOTE" --push)
-if [ "$REMOTE_URL" != "$OFFICIAL_REMOTE_URL" -a \
- "$REMOTE_URL" != "$OFFICIAL_REMOTE_URL.git" ]; then
+REMOTE_URL=$(git remote get-url "$REMOTE" --all)
+if [ "$REMOTE_URL" != "${OFFICIAL_REMOTE_GIT_URL}" ] && \
+ [ "$REMOTE_URL" != "${OFFICIAL_REMOTE_GIT_URL}.git" ] && \
+ [ "$REMOTE_URL" != "https://${OFFICIAL_REMOTE_HTTPS_URL}" ] && \
+ [ "$REMOTE_URL" != "https://${OFFICIAL_REMOTE_HTTPS_URL}.git" ] && \
+ [[ "$REMOTE_URL" != "https://"*"@${OFFICIAL_REMOTE_HTTPS_URL}" ]] && \
+ [[ "$REMOTE_URL" != "https://"*"@${OFFICIAL_REMOTE_HTTPS_URL}.git" ]] ; then
error "remote ${BLUE}$REMOTE${RESET} does not point to the official Coq repo"
- error "that is ${BLUE}$OFFICIAL_REMOTE_URL"
+ error "that is ${BLUE}$OFFICIAL_REMOTE_GIT_URL"
error "it points to ${BLUE}$REMOTE_URL${RESET} instead"
ask_confirmation
fi
@@ -105,19 +120,39 @@ if [ "$BASE_BRANCH" != "coq:$CURRENT_LOCAL_BRANCH" ]; then
ask_confirmation
fi;
+# Sanity check: the local branch is up-to-date with upstream
+
+LOCAL_BRANCH_COMMIT=$(git rev-parse HEAD)
+UPSTREAM_COMMIT=$(git rev-parse @{u})
+if [ "$LOCAL_BRANCH_COMMIT" != "$UPSTREAM_COMMIT" ]; then
+
+ # Is it just that the upstream branch is behind?
+ # It could just be that we merged other PRs and we didn't push yet
+
+ if git merge-base --is-ancestor -- "$UPSTREAM_COMMIT" "$LOCAL_BRANCH_COMMIT"; then
+ warning "Your branch is ahead of ${REMOTE}."
+ warning "You should see this warning only if you've just merged another PR and did not push yet."
+ ask_confirmation
+ else
+ error "Local branch is not up-to-date with ${REMOTE}."
+ error "Pull before merging."
+ ask_confirmation
+ fi
+fi
+
# Sanity check: CI failed
-STATUS=$(curl -s "$API/commits/$COMMIT/status" | jq -r '.state')
+STATUS=$(curl -s "$API/commits/$COMMIT/status")
-if [ "$STATUS" != "success" ]; then
- error "CI unsuccessful on ${BLUE}$(curl -s "$API/commits/$COMMIT/status" |
+if [ "$(echo "$STATUS" | jq -r '.state')" != "success" ]; then
+ error "CI unsuccessful on ${BLUE}$(echo "$STATUS" |
jq -r -c '.statuses|map(select(.state != "success"))|map(.context)')"
ask_confirmation
fi;
# Sanity check: has labels named "needs:"
-NEEDS_LABELS=$(curl -s "$API/pulls/$PR" | jq -rc '.labels | map(select(.name | match("needs:"))) | map(.name)')
+NEEDS_LABELS=$(echo "$PRDATA" | jq -rc '.labels | map(select(.name | match("needs:"))) | map(.name)')
if [ "$NEEDS_LABELS" != "[]" ]; then
error "needs:something labels still present: ${BLUE}$NEEDS_LABELS"
ask_confirmation
@@ -125,7 +160,7 @@ fi
# Sanity check: has milestone
-MILESTONE=$(curl -s "$API/pulls/$PR" | jq -rc '.milestone.title')
+MILESTONE=$(echo "$PRDATA" | jq -rc '.milestone.title')
if [ "$MILESTONE" = "null" ]; then
error "no milestone set, please set one"
ask_confirmation
@@ -133,7 +168,7 @@ fi
# Sanity check: has kind
-KIND=$(curl -s "$API/pulls/$PR" | jq -rc '.labels | map(select(.name | match("kind:"))) | map(.name)')
+KIND=$(echo "$PRDATA" | jq -rc '.labels | map(select(.name | match("kind:"))) | map(.name)')
if [ "$KIND" = "[]" ]; then
error "no kind:something label set, please set one"
ask_confirmation
diff --git a/dev/tools/pre-commit b/dev/tools/pre-commit
index c9cdee84a..b56925c37 100755
--- a/dev/tools/pre-commit
+++ b/dev/tools/pre-commit
@@ -5,6 +5,8 @@
set -e
+dev/tools/check-overlays.sh
+
if ! git diff --cached --name-only -z | xargs -0 dev/tools/check-eof-newline.sh ||
! git diff-index --check --cached HEAD >/dev/null 2>&1 ;
then
@@ -25,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
@@ -43,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..f9b402586 100644
--- a/dev/top_printers.ml
+++ b/dev/top_printers.ml
@@ -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/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
index d0884be0d..01369b900 100644
--- a/doc/RecTutorial/RecTutorial.tex
+++ b/doc/RecTutorial/RecTutorial.tex
@@ -2978,7 +2978,7 @@ definition of \textsl{div\_aux}:
\begin{alltt}
Definition div_aux (x y:nat)(H: Acc lt x):nat.
- fix 3.
+ fix div_aux 3.
intros.
refine (if eq_nat_dec x 0
then 0
@@ -3010,10 +3010,10 @@ Definition div x y := div_aux x y (lt_wf x).
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
+of $x$. The tactic ``~\texttt{fix div\_aux 3}~'' is used to indicate that the proof
proceeds by structural induction on the third argument of the theorem
--that is, on the accessibility proof. It also introduces a new
-hypothesis in the context, named as the current theorem, and with the
+hypothesis in the context, named ``~\texttt{div\_aux}~'', and with the
same type as the goal. Then, the proof is refined with an incomplete
proof term, containing a hole \texttt{\_}. This hole corresponds to the proof
of accessibility for $x-y$, and is filled up with the (smaller!)
diff --git a/doc/RecTutorial/RecTutorial.v b/doc/RecTutorial/RecTutorial.v
index 4b0ab3125..4a17e0818 100644
--- a/doc/RecTutorial/RecTutorial.v
+++ b/doc/RecTutorial/RecTutorial.v
@@ -922,7 +922,7 @@ Print minus_decrease.
Definition div_aux (x y:nat)(H: Acc lt x):nat.
- fix 3.
+ fix div_aux 3.
intros.
refine (if eq_nat_dec x 0
then 0
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/AsyncProofs.tex b/doc/refman/AsyncProofs.tex
deleted file mode 100644
index 8f9d876cb..000000000
--- a/doc/refman/AsyncProofs.tex
+++ /dev/null
@@ -1,221 +0,0 @@
-\achapter{Asynchronous and Parallel Proof Processing\label{Asyncprocessing}}
-%HEVEA\cutname{async-proofs.html}
-\aauthor{Enrico Tassi}
-
-\label{pralitp}
-\index{Asynchronous and Parallel Proof Processing!presentation}
-
-This chapter explains how proofs can be asynchronously processed by Coq.
-This feature improves the reactivity of the system when used in interactive
-mode via CoqIDE. In addition, it allows Coq to take advantage of
-parallel hardware when used as a batch compiler by decoupling the checking
-of statements and definitions from the construction and checking of proofs
-objects.
-
-This feature is designed to help dealing with huge libraries of theorems
-characterized by long proofs. In the current state, it may not be beneficial
-on small sets of short files.
-
-This feature has some technical limitations that may make it unsuitable for
-some use cases.
-
-For example, in interactive mode, some errors coming from the kernel of Coq
-are signaled late. The type of errors belonging to this category
-are universe inconsistencies.
-
-At the time of writing, only opaque proofs (ending with \texttt{Qed} or \texttt{Admitted}) can be processed asynchronously.
-
-Finally, asynchronous processing is disabled when running CoqIDE in Windows. The
-current implementation of the feature is not stable on Windows. It can be
-enabled, as described below at \ref{interactivecaveats}, though doing so is not
-recommended.
-
-\section{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 \texttt{Section} (see Section~\ref{Section}).
-
-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
-\texttt{Proof using} command (Section~\ref{ProofUsing}) that declares which
-section variables the theorem uses.
-
-The presence of \texttt{Proof using} is needed to process proofs
-asynchronously in interactive mode.
-
-It is not strictly mandatory in batch mode if it is not the first time
-the file is compiled and if the file itself did not change. When the
-proof does not begin with \texttt{Proof using}, the system records in an
-auxiliary file, produced along with the \texttt{.vo} file, the list of
-section variables used.
-
-\subsubsection{Automatic suggestion of proof annotations}
-
-The command \texttt{Set Suggest Proof Using} makes Coq suggest, when a
-\texttt{Qed} command is processed, a correct proof annotation. It is up
-to the user to modify the proof script accordingly.
-
-\section{Proof blocks and error resilience}
-
-Coq 8.6 introduces a mechanism for error resiliency: in interactive mode Coq
-is able to completely check a document containing errors instead of bailing
-out at the first failure.
-
-Two kind of errors are supported: errors occurring in vernacular commands and
-errors occurring in proofs.
-
-To properly recover from a failing tactic, Coq needs to recognize the structure of
-the proof in order to confine the error to a sub proof. Proof block detection
-is performed by looking at the syntax of the proof script (i.e. also looking at indentation).
-Coq comes with four kind of proof blocks, and an ML API to add new ones.
-
-\begin{description}
-\item[curly] blocks are delimited by \texttt{\{} and \texttt{\}}, see \ref{Proof-handling}
-\item[par] blocks are atomic, i.e. just one tactic introduced by the \texttt{par:} goal selector
-\item[indent] blocks end with a tactic indented less than the previous one
-\item[bullet] blocks are delimited by two equal bullet signs at the same indentation level
-\end{description}
-
-\subsection{Caveats}
-
-When a vernacular command fails the subsequent error messages may be bogus, i.e. caused by
-the first error. Error resiliency for vernacular commands can be switched off passing
-\texttt{-async-proofs-command-error-resilience off} to CoqIDE.
-
-An incorrect proof block detection can result into an incorrect error recovery and
-hence in bogus errors. Proof block detection cannot be precise for bullets or
-any other non well parenthesized proof structure. Error resiliency can be
-turned off or selectively activated for any set of block kind passing to
-CoqIDE one of the following options:
-\texttt{-async-proofs-tactic-error-resilience off},
-\texttt{-async-proofs-tactic-error-resilience all},
-\texttt{-async-proofs-tactic-error-resilience $blocktype_1$,..., $blocktype_n$}.
-Valid proof block types are: ``curly'', ``par'', ``indent'', ``bullet''.
-
-\section{Interactive mode}
-
-At the time of writing the only user interface supporting asynchronous proof
-processing is CoqIDE.
-
-When CoqIDE is started, two Coq processes are created. The master one follows
-the user, giving feedback as soon as possible by skipping proofs, which are
-delegated to the worker process. The worker process, whose state can be seen
-by clicking on the button in the lower right corner of the main CoqIDE window,
-asynchronously processes the proofs. If a proof contains an error, it is
-reported in red in the label of the very same button, that can also be used to
-see the list of errors and jump to the corresponding line.
-
-If a proof is processed asynchronously the corresponding \texttt{Qed} command
-is colored using a lighter color that usual. This signals that
-the proof has been delegated to a worker process (or will be processed
-lazily if the \texttt{-async-proofs lazy} option is used). Once finished, the
-worker process will provide the proof object, but this will not be
-automatically checked by the kernel of the main process. To force
-the kernel to check all the proof objects, one has to click the button
-with the gears. Only then are all the universe constraints checked.
-
-\subsubsection{Caveats}
-\label{interactivecaveats}
-
-The number of worker processes can be increased by passing CoqIDE the
-\texttt{-async-proofs-j $n$} flag. Note that the memory consumption
-increases too, since each worker requires the same amount of memory as
-the master process. Also note that increasing the number of workers may
-reduce the reactivity of the master process to user commands.
-
-To disable this feature, one can pass the \texttt{-async-proofs off} flag to
-CoqIDE. Conversely, on Windows, where the feature is disabled by default,
-pass the \texttt{-async-proofs on} flag to enable it.
-
-Proofs that are known to take little time to process are not delegated to a
-worker process. The threshold can be configure with \texttt{-async-proofs-delegation-threshold}. Default is 0.03 seconds.
-
-\section{Batch mode}
-
-When Coq is used as a batch compiler by running \texttt{coqc} or
-\texttt{coqtop -compile}, it produces a \texttt{.vo} file for each
-\texttt{.v} file. A \texttt{.vo} file contains, among other things,
-theorems statements and proofs. Hence to produce a \texttt{.vo} Coq need
-to process all the proofs of the \texttt{.v} file.
-
-The asynchronous processing of proofs can decouple the generation of a
-compiled file (like the \texttt{.vo} one) that can be loaded by
-\texttt{Require} from the generation and checking of the proof objects.
-The \texttt{-quick} flag can be passed to \texttt{coqc} or
-\texttt{coqtop} to produce, quickly, \texttt{.vio} files. Alternatively,
-when using a \texttt{Makefile} produced by \texttt{coq\_makefile}, the
-\texttt{quick} target can be used to compile all files using the
-\texttt{-quick} flag.
-
-A \texttt{.vio} file can be loaded using \texttt{Require} exactly as a
-\texttt{.vo} file but proofs will not be available (the \texttt{Print}
-command produces an error). Moreover, some universe constraints might be
-missing, so universes inconsistencies might go unnoticed. A
-\texttt{.vio} file does not contain proof objects, but proof tasks,
-i.e. what a worker process can transform into a proof object.
-
-Compiling a set of files with the \texttt{-quick} flag allows one to work,
-interactively, on any file without waiting for all the proofs to be checked.
-
-When working interactively, one can fully check all the \texttt{.v} files by
-running \texttt{coqc} as usual.
-
-Alternatively one can turn each \texttt{.vio} into the corresponding
-\texttt{.vo}. All \texttt{.vio} files can be processed in parallel,
-hence this alternative might be faster. The command \texttt{coqtop
- -schedule-vio2vo 2 a b c} can be used to obtain a good scheduling for 2
-workers to produce \texttt{a.vo}, \texttt{b.vo}, and \texttt{c.vo}. When
-using a \texttt{Makefile} produced by \texttt{coq\_makefile}, the
-\texttt{vio2vo} target can be used for that purpose. Variable \texttt{J}
-should be set to the number of workers, e.g. \texttt{make vio2vo J=2}.
-The only caveat is that, while the \texttt{.vo} files obtained from
-\texttt{.vio} files are complete (they contain all proof terms and
-universe constraints), the satisfiability of all universe constraints has
-not been checked globally (they are checked to be consistent for every
-single proof). Constraints will be checked when these \texttt{.vo} files
-are (recursively) loaded with \texttt{Require}.
-
-There is an extra, possibly even faster, alternative: just check the
-proof tasks stored in \texttt{.vio} files without producing the
-\texttt{.vo} files. This is possibly faster because all the proof tasks
-are independent, hence one can further partition the job to be done
-between workers. The \texttt{coqtop -schedule-vio-checking 6 a b c}
-command can be used to obtain a good scheduling for 6 workers to check
-all the proof tasks of \texttt{a.vio}, \texttt{b.vio}, and
-\texttt{c.vio}. Auxiliary files are used to predict how long a proof task
-will take, assuming it will take the same amount of time it took last
-time. When using a \texttt{Makefile} produced by \texttt{coq\_makefile},
-the \texttt{checkproofs} target can be used to check all \texttt{.vio}
-files. Variable \texttt{J} should be set to the number of workers,
-e.g. \texttt{make checkproofs J=6}. As when converting \texttt{.vio}
-files to \texttt{.vo} files, universe constraints are not checked to be
-globally consistent. Hence this compilation mode is only useful for quick
-regression testing and on developments not making heavy use of the $Type$
-hierarchy.
-
-\section{Limiting the number of parallel workers}
-\label{coqworkmgr}
-
-Many Coq processes may run on the same computer, and each of them may start
-many additional worker processes.
-The \texttt{coqworkmgr} utility lets one limit the number of workers, globally.
-
-The utility accepts the \texttt{-j} argument to specify the maximum number of
-workers (defaults to 2). \texttt{coqworkmgr} automatically starts in the
-background and prints an environment variable assignment like
-\texttt{COQWORKMGR\_SOCKET=localhost:45634}. The user must set this variable in
-all the shells from which Coq processes will be started. If one uses just
-one terminal running the bash shell, then \texttt{export `coqworkmgr -j 4`} will
-do the job.
-
-After that, all Coq processes, e.g. \texttt{coqide} and \texttt{coqc},
-will honor the limit, globally.
-
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
diff --git a/doc/refman/Classes.tex b/doc/refman/Classes.tex
deleted file mode 100644
index da798a238..000000000
--- a/doc/refman/Classes.tex
+++ /dev/null
@@ -1,578 +0,0 @@
-\def\Haskell{\textsc{Haskell}\xspace}
-\def\eol{\setlength\parskip{0pt}\par}
-\def\indent#1{\noindent\kern#1}
-\def\cst#1{\textsf{#1}}
-
-\newcommand\tele[1]{\overrightarrow{#1}}
-
-\achapter{\protect{Type Classes}}
-%HEVEA\cutname{type-classes.html}
-\aauthor{Matthieu Sozeau}
-\label{typeclasses}
-
-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
-classes in \Haskell which also applies.
-
-\asection{Class and Instance declarations}
-\label{ClassesInstances}
-
-The syntax for class and instance declarations is the same as
-record syntax of \Coq:
-\def\kw{\texttt}
-\def\classid{\texttt}
-
-\begin{center}
-\[\begin{array}{l}
-\kw{Class}~\classid{Id}~(\alpha_1 : \tau_1) \cdots (\alpha_n : \tau_n)
-[: \sort] := \{\\
-\begin{array}{p{0em}lcl}
- & \cst{f}_1 & : & \type_1 ; \\
- & \vdots & & \\
- & \cst{f}_m & : & \type_m \}.
-\end{array}\end{array}\]
-\end{center}
-\begin{center}
-\[\begin{array}{l}
-\kw{Instance}~\ident~:~\classid{Id}~\term_1 \cdots \term_n := \{\\
-\begin{array}{p{0em}lcl}
- & \cst{f}_1 & := & \term_{f_1} ; \\
- & \vdots & & \\
- & \cst{f}_m & := & \term_{f_m} \}.
-\end{array}\end{array}\]
-\end{center}
-\begin{coq_eval}
- Reset Initial.
- Generalizable All Variables.
-\end{coq_eval}
-
-The $\tele{\alpha_i : \tau_i}$ variables are called the \emph{parameters}
-of the class and the $\tele{f_k : \type_k}$ are called the
-\emph{methods}. Each class definition gives rise to a corresponding
-record declaration and each instance is a regular definition whose name
-is given by $\ident$ and type is an instantiation of the record type.
-
-We'll use the following example class in the rest of the chapter:
-
-\begin{coq_example*}
-Class EqDec (A : Type) := {
- eqb : A -> A -> bool ;
- eqb_leibniz : forall x y, eqb x y = true -> x = y }.
-\end{coq_example*}
-
-This class implements a boolean equality test which is compatible with
-Leibniz equality on some type. An example implementation is:
-
-\begin{coq_example*}
-Instance unit_EqDec : EqDec unit :=
-{ eqb x y := true ;
- eqb_leibniz x y H :=
- match x, y return x = y with tt, tt => eq_refl tt end }.
-\end{coq_example*}
-
-If one does not give all the members in the \texttt{Instance}
-declaration, Coq enters the proof-mode and the user is asked to build
-inhabitants of the remaining fields, e.g.:
-
-\begin{coq_example*}
-Instance eq_bool : EqDec bool :=
-{ eqb x y := if x then y else negb y }.
-\end{coq_example*}
-\begin{coq_example}
-Proof. intros x y H.
- destruct x ; destruct y ; (discriminate || reflexivity).
-Defined.
-\end{coq_example}
-
-One has to take care that the transparency of every field is determined
-by the transparency of the \texttt{Instance} proof. One can use
-alternatively the \texttt{Program} \texttt{Instance} \comindex{Program Instance} variant which has
-richer facilities for dealing with obligations.
-
-\asection{Binding classes}
-
-Once a type class is declared, one can use it in class binders:
-\begin{coq_example}
-Definition neqb {A} {eqa : EqDec A} (x y : A) := negb (eqb x y).
-\end{coq_example}
-
-When one calls a class method, a constraint is generated that is
-satisfied only in contexts where the appropriate instances can be
-found. In the example above, a constraint \texttt{EqDec A} is generated and
-satisfied by \texttt{{eqa : EqDec A}}. In case no satisfying constraint can be
-found, an error is raised:
-
-\begin{coq_example}
-Fail Definition neqb' (A : Type) (x y : A) := negb (eqb x y).
-\end{coq_example}
-
-The algorithm used to solve constraints is a variant of the eauto tactic
-that does proof search with a set of lemmas (the instances). It will use
-local hypotheses as well as declared lemmas in the
-\texttt{typeclass\_instances} database. Hence the example can also be
-written:
-
-\begin{coq_example}
-Definition neqb' A (eqa : EqDec A) (x y : A) := negb (eqb x y).
-\end{coq_example}
-
-However, the generalizing binders should be used instead as they have
-particular support for type classes:
-\begin{itemize}
-\item They automatically set the maximally implicit status for type
- class arguments, making derived functions as easy to use as class
- methods. In the example above, \texttt{A} and \texttt{eqa} should be
- set maximally implicit.
-\item They support implicit quantification on partially applied type
- classes (\S \ref{implicit-generalization}).
- Any argument not given as part of a type class binder will be
- automatically generalized.
-\item They also support implicit quantification on superclasses
- (\S \ref{classes:superclasses})
-\end{itemize}
-
-Following the previous example, one can write:
-\begin{coq_example}
-Definition neqb_impl `{eqa : EqDec A} (x y : A) := negb (eqb x y).
-\end{coq_example}
-
-Here \texttt{A} is implicitly generalized, and the resulting function
-is equivalent to the one above.
-
-\asection{Parameterized Instances}
-
-One can declare parameterized instances as in \Haskell simply by giving
-the constraints as a binding context before the instance, e.g.:
-
-\begin{coq_example}
-Instance prod_eqb `(EA : EqDec A, EB : EqDec B) : EqDec (A * B) :=
-{ eqb x y := match x, y with
- | (la, ra), (lb, rb) => andb (eqb la lb) (eqb ra rb)
- end }.
-\end{coq_example}
-\begin{coq_eval}
-Admitted.
-\end{coq_eval}
-
-These instances are used just as well as lemmas in the instance hint database.
-
-\asection{Sections and contexts}
-\label{SectionContext}
-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 \texttt{Variables} vernacular
-(see \ref{Variable}), except it accepts any binding context as argument.
-For example:
-
-\begin{coq_example}
-Section EqDec_defs.
- Context `{EA : EqDec A}.
-\end{coq_example}
-
-\begin{coq_example*}
- Global Instance option_eqb : EqDec (option A) :=
- { eqb x y := match x, y with
- | Some x, Some y => eqb x y
- | None, None => true
- | _, _ => false
- end }.
-\end{coq_example*}
-\begin{coq_eval}
-Proof.
-intros x y ; destruct x ; destruct y ; intros H ;
-try discriminate ; try apply eqb_leibniz in H ;
-subst ; auto.
-Defined.
-\end{coq_eval}
-
-\begin{coq_example}
-End EqDec_defs.
-About option_eqb.
-\end{coq_example}
-
-Here the \texttt{Global} modifier redeclares the instance at the end of
-the section, once it has been generalized by the context variables it uses.
-
-\asection{Building hierarchies}
-
-\subsection{Superclasses}
-\label{classes:superclasses}
-One can also parameterize classes by other classes, generating a
-hierarchy of classes and superclasses. In the same way, we give the
-superclasses as a binding context:
-
-\begin{coq_example*}
-Class Ord `(E : EqDec A) :=
- { le : A -> A -> bool }.
-\end{coq_example*}
-
-Contrary to \Haskell, we have no special syntax for superclasses, but
-this declaration is morally equivalent to:
-\begin{verbatim}
-Class `(E : EqDec A) => Ord A :=
- { le : A -> A -> bool }.
-\end{verbatim}
-
-This declaration means that any instance of the \texttt{Ord} class must
-have an instance of \texttt{EqDec}. The parameters of the subclass contain
-at least all the parameters of its superclasses in their order of
-appearance (here \texttt{A} is the only one).
-As we have seen, \texttt{Ord} is encoded as a record type with two parameters:
-a type \texttt{A} and an \texttt{E} of type \texttt{EqDec A}. However, one can
-still use it as if it had a single parameter inside generalizing binders: the
-generalization of superclasses will be done automatically.
-\begin{coq_example*}
-Definition le_eqb `{Ord A} (x y : A) := andb (le x y) (le y x).
-\end{coq_example*}
-
-In some cases, to be able to specify sharing of structures, one may want to give
-explicitly the superclasses. It is is possible to do it directly in regular
-binders, and using the \texttt{!} modifier in class binders. For
-example:
-\begin{coq_example*}
-Definition lt `{eqa : EqDec A, ! Ord eqa} (x y : A) :=
- andb (le x y) (neqb x y).
-\end{coq_example*}
-
-The \texttt{!} modifier switches the way a binder is parsed back to the
-regular interpretation of Coq. In particular, it uses the implicit
-arguments mechanism if available, as shown in the example.
-
-\subsection{Substructures}
-
-Substructures are components of a class which are instances of a class
-themselves. They often arise when using classes for logical properties,
-e.g.:
-
-\begin{coq_eval}
-Require Import Relations.
-\end{coq_eval}
-\begin{coq_example*}
-Class Reflexive (A : Type) (R : relation A) :=
- reflexivity : forall x, R x x.
-Class Transitive (A : Type) (R : relation A) :=
- transitivity : forall x y z, R x y -> R y z -> R x z.
-\end{coq_example*}
-
-This declares singleton classes for reflexive and transitive relations,
-(see \ref{SingletonClass} for an explanation).
-These may be used as part of other classes:
-
-\begin{coq_example*}
-Class PreOrder (A : Type) (R : relation A) :=
-{ PreOrder_Reflexive :> Reflexive A R ;
- PreOrder_Transitive :> Transitive A R }.
-\end{coq_example*}
-
-The syntax \texttt{:>} indicates that each \texttt{PreOrder} can be seen
-as a \texttt{Reflexive} relation. So each time a reflexive relation is
-needed, a preorder can be used instead. This is very similar to the
-coercion mechanism of \texttt{Structure} declarations.
-The implementation simply declares each projection as an instance.
-
-One can also declare existing objects or structure
-projections using the \texttt{Existing Instance} command to achieve the
-same effect.
-
-\section{Summary of the commands
-\label{TypeClassCommands}}
-
-\subsection{\tt Class {\ident} {\binder$_1$ \ldots~\binder$_n$}
- : \sort := \{ field$_1$ ; \ldots ; field$_k$ \}.}
-\comindex{Class}
-\label{Class}
-
-The \texttt{Class} command is used to declare a type class with
-parameters {\binder$_1$} to {\binder$_n$} and fields {\tt field$_1$} to
-{\tt field$_k$}.
-
-\begin{Variants}
-\item \label{SingletonClass} {\tt Class {\ident} {\binder$_1$ \ldots \binder$_n$}
- : \sort := \ident$_1$ : \type$_1$.}
- This variant declares a \emph{singleton} class whose only method is
- {\tt \ident$_1$}. This singleton class is a so-called definitional
- class, represented simply as a definition
- {\tt {\ident} \binder$_1$ \ldots \binder$_n$ := \type$_1$} and whose
- instances are themselves objects of this type. Definitional classes
- are not wrapped inside records, and the trivial projection of an
- instance of such a class is convertible to the instance itself. This can
- be useful to make instances of existing objects easily and to reduce
- proof size by not inserting useless projections. The class
- constant itself is declared rigid during resolution so that the class
- abstraction is maintained.
-
-\item \label{ExistingClass} {\tt Existing Class {\ident}.\comindex{Existing Class}}
- This variant declares a class a posteriori from a constant or
- inductive definition. No methods or instances are defined.
-\end{Variants}
-
-\subsection{\tt Instance {\ident} {\binder$_1$ \ldots \binder$_n$} :
- {Class} {t$_1$ \ldots t$_n$} [| \textit{priority}]
- := \{ field$_1$ := b$_1$ ; \ldots ; field$_i$ := b$_i$ \}}
-\comindex{Instance}
-\label{Instance}
-
-The \texttt{Instance} command is used to declare a type class instance
-named {\ident} of the class \emph{Class} with parameters {t$_1$} to {t$_n$} and
-fields {\tt b$_1$} to {\tt b$_i$}, where each field must be a declared
-field of the class. Missing fields must be filled in interactive proof mode.
-
-An arbitrary context of the form {\tt \binder$_1$ \ldots \binder$_n$}
-can be put after the name of the instance and before the colon to
-declare a parameterized instance.
-An optional \textit{priority} can be declared, 0 being the highest
-priority as for auto hints. If the priority is not specified, it defaults to
-$n$, the number of binders of the instance.
-
-\begin{Variants}
-\item {\tt Instance {\ident} {\binder$_1$ \ldots \binder$_n$} :
- forall {\binder$_{n+1}$ \ldots \binder$_m$},
- {Class} {t$_1$ \ldots t$_n$} [| \textit{priority}] := \term}
- This syntax is used for declaration of singleton class instances or
- for directly giving an explicit term of type
- {\tt forall {\binder$_{n+1}$ \ldots \binder$_m$}, {Class} {t$_1$ \ldots t$_n$}}.
- One need not even mention the unique field name for singleton classes.
-
-\item {\tt Global Instance} One can use the \texttt{Global} modifier on
- instances declared in a section so that their generalization is automatically
- redeclared after the section is closed.
-
-\item {\tt Program Instance} \comindex{Program Instance}
- Switches the type-checking to \Program~(chapter \ref{Program})
- and uses the obligation mechanism to manage missing fields.
-
-\item {\tt Declare Instance} \comindex{Declare Instance}
- In a {\tt Module Type}, this command states that a corresponding
- concrete instance should exist in any implementation of this
- {\tt Module Type}. This is similar to the distinction between
- {\tt Parameter} vs. {\tt Definition}, or between {\tt Declare Module}
- and {\tt Module}.
-
-\end{Variants}
-
-Besides the {\tt Class} and {\tt Instance} vernacular commands, there
-are a few other commands related to type classes.
-
-\subsection{\tt Existing Instance {\ident} [| \textit{priority}]}
-\comindex{Existing Instance}
-\label{ExistingInstance}
-
-This commands adds an arbitrary constant 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 almost equivalent to {\tt Hint Resolve
-{\ident} : typeclass\_instances}.
-
-\begin{Variants}
-\item {\tt Existing Instances {\ident}$_1$ \ldots {\ident}$_n$
- [| \textit{priority}]}
- \comindex{Existing Instances}
- With this command, several existing instances can be declared at once.
-\end{Variants}
-
-\subsection{\tt Context {\binder$_1$ \ldots \binder$_n$}}
-\comindex{Context}
-\label{Context}
-
-Declares variables according to the given binding context, which might
-use implicit generalization (see \ref{SectionContext}).
-
-\asubsection{\tt typeclasses eauto}
-\tacindex{typeclasses eauto}
-\label{typeclasseseauto}
-
-The {\tt typeclasses eauto} tactic uses a different resolution engine
-than {\tt eauto} and {\tt auto}. The main differences are the following:
-\begin{itemize}
-\item Contrary to {\tt eauto} and {\tt 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. {\tt typeclasses eauto} is a multi-goal tactic.
- It analyses the dependencies between subgoals to avoid
- backtracking on subgoals that are entirely independent.
-\item When called with no arguments, {\tt typeclasses eauto} uses the
- {\tt typeclass\_instances} database by default (instead of {\tt
- core}).
- Dependent subgoals are automatically shelved, and shelved
- goals can remain after resolution ends (following the behavior of
- \Coq{} 8.5).
-
- \emph{Note: } As of Coq 8.6, {\tt all:once (typeclasses eauto)}
- faithfully mimicks what happens during typeclass resolution when it is
- called during refinement/type-inference, except that \emph{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 {\tt all:typeclasses eauto} in future versions
- when the refinement engine will be able to backtrack.
-\item When called with specific databases (e.g. {\tt with}), {\tt
- typeclasses eauto} allows shelved goals to remain at any point
- during search and treat typeclasses goals like any other.
-\item 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 {\tt 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.
-\end{itemize}
-
-\begin{Variants}
-\item \label{depth} {\tt typeclasses eauto \zeroone{\num}}
- \emph{Warning:} The semantics for the limit {\num} is different than
- for {\tt auto}. By default, if no limit is given the search is
- unbounded. Contrary to {\tt auto}, introduction steps ({\tt intro})
- are counted, which might result in larger limits being necessary
- when searching with {\tt typeclasses eauto} than {\tt auto}.
-
-\item \label{with} {\tt typeclasses eauto with {\ident}$_1$ \ldots {\ident}$_n$}.
- 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).
-\end{Variants}
-
-\asubsection{\tt autoapply {\term} with {\ident}}
-\tacindex{autoapply}
-
-The tactic {\tt autoapply} applies a term using the transparency
-information of the hint database {\ident}, and does \emph{no} typeclass
-resolution. This can be used in {\tt Hint Extern}'s for typeclass
-instances (in hint db {\tt 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.
-
-\subsection{\tt Typeclasses Transparent, Opaque {\ident$_1$ \ldots \ident$_n$}}
-\comindex{Typeclasses Transparent}
-\comindex{Typeclasses Opaque}
-\label{TypeclassesTransparency}
-
-This commands defines the transparency of {\ident$_1$ \ldots \ident$_n$}
-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{HintTransparency}).
-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 {\tt relation A := A -> A -> Prop}.
-
-This is equivalent to {\tt Hint Transparent,Opaque} {\ident} {\tt: typeclass\_instances}.
-
-\subsection{\tt Set Typeclasses Axioms Are Instances}
-\optindex{Typeclasses Axioms Are Instances}
-
-This option (off by default since 8.8) automatically declares axioms
-whose type is a typeclass at declaration time as instances of that
-class.
-
-\subsection{\tt Set Typeclasses Dependency Order}
-\optindex{Typeclasses Dependency Order}
-
-This option (on by default since 8.6) respects the dependency order between
-subgoals, meaning that subgoals which are depended on by other subgoals
-come first, while the non-dependent subgoals were put before the
-dependent ones previously (Coq v8.5 and below). This can result in quite
-different performance behaviors of proof search.
-
-\subsection{\tt Set Typeclasses Filtered Unification}
-\optindex{Typeclasses Filtered Unification}
-
-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 \emph{matches} syntactically the
-inferred or specified pattern of the hint, and only then try to
-\emph{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.
-
-\subsection{\tt Set Typeclasses Limit Intros}
-\optindex{Typeclasses Limit Intros}
-
-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. \emph{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).
-
-\subsection{\tt Set Typeclass Resolution For Conversion}
-\optindex{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.
-
-\subsection{\tt Set Typeclasses Strict Resolution}
-\optindex{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.
-
-\subsection{\tt Set Typeclasses Unique Solutions}
-\optindex{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.
-
-\subsection{\tt Set Typeclasses Unique Instances}
-\optindex{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.
-
-\subsection{\tt Typeclasses eauto := [debug] [(dfs) | (bfs)] [\emph{depth}]}
-\comindex{Typeclasses eauto}
-\label{TypeclassesEauto}
-
-This command allows more global customization of the type class
-resolution tactic.
-The semantics of the options are:
-\begin{itemize}
-\item {\tt debug} In debug mode, the trace of successfully applied
- tactics is printed.
-\item {\tt dfs, bfs} This sets the search strategy to depth-first search
- (the default) or breadth-first search.
-\item {\emph{depth}} This sets the depth limit of the search.
-\end{itemize}
-
-\subsection{\tt Set Typeclasses Debug [Verbosity {\num}]}
-\optindex{Typeclasses Debug}
-\optindex{Typeclasses Debug Verbosity}
-
-These options allow to see the resolution steps of typeclasses that are
-performed during search. The {\tt Debug} option is synonymous to
-{\tt Debug Verbosity 1}, and {\tt Debug Verbosity 2} provides more
-information (tried tactics, shelving of goals, etc\ldots).
-
-\subsection{\tt Set Refine Instance Mode}
-\optindex{Refine Instance Mode}
-
-The option {\tt Refine Instance Mode} allows to switch the behavior of instance
-declarations made through the {\tt Instance} command.
-\begin{itemize}
-\item 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.
-\item When it is off, they fail with an error instead.
-\end{itemize}
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
diff --git a/doc/refman/Coercion.tex b/doc/refman/Coercion.tex
deleted file mode 100644
index 9862a9b30..000000000
--- a/doc/refman/Coercion.tex
+++ /dev/null
@@ -1,563 +0,0 @@
-\achapter{Implicit Coercions}
-%HEVEA\cutname{coercions.html}
-\aauthor{Amokrane Saïbi}
-
-\label{Coercions-full}
-\index{Coercions!presentation}
-
-\asection{General Presentation}
-
-This section describes the inheritance mechanism of {\Coq}. In {\Coq} with
-inheritance, we are not interested in adding any expressive power to
-our theory, but only convenience. Given a term, possibly not typable,
-we are interested in the problem of determining if it can be well
-typed modulo insertion of appropriate coercions. We allow to write:
-
-\begin{itemize}
-\item $f~a$ where $f:forall~ x:A, B$ and $a:A'$ when $A'$ can
- be seen in some sense as a subtype of $A$.
-\item $x:A$ when $A$ is not a type, but can be seen in
- a certain sense as a type: set, group, category etc.
-\item $f~a$ when $f$ is not a function, but can be seen in a certain sense
- as a function: bijection, functor, any structure morphism etc.
-\end{itemize}
-
-\asection{Classes}
-\index{Coercions!classes}
- A class with $n$ parameters is any defined name with a type
-$forall~ (x_1:A_1)..(x_n:A_n), s$ where $s$ is a sort. Thus a class with
-parameters is considered as a single class and not as a family of
-classes. An object of a class $C$ is any term of type $C~t_1
-.. t_n$. In addition to these user-classes, we have two abstract
-classes:
-
-\begin{itemize}
-\item {\tt Sortclass}, the class of sorts;
- its objects are the terms whose type is a sort (e.g., \texttt{Prop}
- or \texttt{Type}).
-\item {\tt Funclass}, the class of functions;
- its objects are all the terms with a functional
- type, i.e. of form $forall~ x:A, B$.
-\end{itemize}
-
-Formally, the syntax of a classes is defined on Figure~\ref{fig:classes}.
-\begin{figure}
-\begin{centerframe}
-\begin{tabular}{lcl}
-{\class} & ::= & {\qualid} \\
- & $|$ & {\tt Sortclass} \\
- & $|$ & {\tt Funclass}
-\end{tabular}
-\end{centerframe}
-\caption{Syntax of classes}
-\label{fig:classes}
-\end{figure}
-
-\asection{Coercions}
-\index{Coercions!Funclass}
-\index{Coercions!Sortclass}
- A name $f$ can be declared as a coercion between a source user-class
-$C$ with $n$ parameters and a target class $D$ if one of these
-conditions holds:
-
-\newcommand{\oftype}{\!:\!}
-
-\begin{itemize}
-\item $D$ is a user-class, then the type of $f$ must have the form
- $forall~ (x_1 \oftype A_1)..(x_n \oftype A_n)(y\oftype C~x_1..x_n), D~u_1..u_m$ where $m$
- is the number of parameters of $D$.
-\item $D$ is {\tt Funclass}, then the type of $f$ must have the form
- $forall~ (x_1\oftype A_1)..(x_n\oftype A_n)(y\oftype C~x_1..x_n)(x:A), B$.
-\item $D$ is {\tt Sortclass}, then the type of $f$ must have the form
- $forall~ (x_1\oftype A_1)..(x_n\oftype A_n)(y\oftype C~x_1..x_n), s$ with $s$ a sort.
-\end{itemize}
-
-We then write $f:C \mbox{\texttt{>->}} D$. The restriction on the type
-of coercions is called {\em the uniform inheritance condition}.
-Remark: the abstract class {\tt Sortclass} can be used as source class,
-but the abstract class {\tt Funclass} cannot.
-
-To coerce an object $t:C~t_1..t_n$ of $C$ towards $D$, we have to
-apply the coercion $f$ to it; the obtained term $f~t_1..t_n~t$ is
-then an object of $D$.
-
-\asection{Identity Coercions}
-\index{Coercions!identity}
-
- Identity coercions are special cases of coercions used to go around
-the uniform inheritance condition. Let $C$ and $D$ be two classes
-with respectively $n$ and $m$ parameters and
-$f:forall~(x_1:T_1)..(x_k:T_k)(y:C~u_1..u_n), D~v_1..v_m$ a function which
-does not verify the uniform inheritance condition. To declare $f$ as
-coercion, one has first to declare a subclass $C'$ of $C$:
-
-$$C' := fun~ (x_1:T_1)..(x_k:T_k) => C~u_1..u_n$$
-
-\noindent We then define an {\em identity coercion} between $C'$ and $C$:
-\begin{eqnarray*}
-Id\_C'\_C & := & fun~ (x_1:T_1)..(x_k:T_k)(y:C'~x_1..x_k) => (y:C~u_1..u_n)\\
-\end{eqnarray*}
-
-We can now declare $f$ as coercion from $C'$ to $D$, since we can
-``cast'' its type as
-$forall~ (x_1:T_1)..(x_k:T_k)(y:C'~x_1..x_k),D~v_1..v_m$.\\ The identity
-coercions have a special status: to coerce an object $t:C'~t_1..t_k$
-of $C'$ towards $C$, we does not have to insert explicitly $Id\_C'\_C$
-since $Id\_C'\_C~t_1..t_k~t$ is convertible with $t$. However we
-``rewrite'' the type of $t$ to become an object of $C$; in this case,
-it becomes $C~u_1^*..u_k^*$ where each $u_i^*$ is the result of the
-substitution in $u_i$ of the variables $x_j$ by $t_j$.
-
-
-\asection{Inheritance Graph}
-\index{Coercions!inheritance graph}
-Coercions form an inheritance graph with classes as nodes. We call
-{\em coercion path} an ordered list of coercions between two nodes of
-the graph. A class $C$ is said to be a subclass of $D$ if there is a
-coercion path in the graph from $C$ to $D$; we also say that $C$
-inherits from $D$. Our mechanism supports multiple inheritance since a
-class may inherit from several classes, contrary to simple inheritance
-where a class inherits from at most one class. However there must be
-at most one path between two classes. If this is not the case, only
-the {\em oldest} one is valid and the others are ignored. So the order
-of declaration of coercions is important.
-
-We extend notations for coercions to coercion paths. For instance
-$[f_1;..;f_k]:C \mbox{\texttt{>->}} D$ is the coercion path composed
-by the coercions $f_1..f_k$. The application of a coercion path to a
-term consists of the successive application of its coercions.
-
-\asection{Declaration of Coercions}
-
-%%%%% "Class" is useless, since classes are implicitely defined via coercions.
-
-% \asubsection{\tt Class {\qualid}.}\comindex{Class}
-% Declares {\qualid} as a new class.
-
-% \begin{ErrMsgs}
-% \item {\qualid} \errindex{not declared}
-% \item {\qualid} \errindex{is already a class}
-% \item \errindex{Type of {\qualid} does not end with a sort}
-% \end{ErrMsgs}
-
-% \begin{Variant}
-% \item {\tt Class Local {\qualid}.} \\
-% Declares the construction denoted by {\qualid} as a new local class to
-% the current section.
-% \end{Variant}
-
-% END "Class" is useless
-
-\asubsection{\tt Coercion {\qualid} : {\class$_1$} >-> {\class$_2$}.}
-\comindex{Coercion}
-
-Declares the construction denoted by {\qualid} as a coercion between
-{\class$_1$} and {\class$_2$}.
-
-% Useless information
-% The classes {\class$_1$} and {\class$_2$} are first declared if necessary.
-
-\begin{ErrMsgs}
-\item {\qualid} \errindex{not declared}
-\item {\qualid} \errindex{is already a coercion}
-\item \errindex{Funclass cannot be a source class}
-\item {\qualid} \errindex{is not a function}
-\item \errindex{Cannot find the source class of {\qualid}}
-\item \errindex{Cannot recognize {\class$_1$} as a source class of {\qualid}}
-\item {\qualid} \errindex{does not respect the uniform inheritance condition}
-\item \errindex{Found target class {\class} instead of {\class$_2$}}
-
-\end{ErrMsgs}
-
-When the coercion {\qualid} is added to the inheritance graph, non
-valid coercion paths are ignored; they are signaled by a warning.
-\\[0.3cm]
-\noindent {\bf Warning :}
-\begin{enumerate}
-\item \begin{tabbing}
-{\tt Ambiguous paths: }\= $[f_1^1;..;f_{n_1}^1] : C_1\mbox{\tt >->}D_1$\\
- \> {\ldots} \\
- \>$[f_1^m;..;f_{n_m}^m] : C_m\mbox{\tt >->}D_m$
- \end{tabbing}
-\end{enumerate}
-
-\begin{Variants}
-\item {\tt Local Coercion {\qualid} : {\class$_1$} >-> {\class$_2$}.}
-\comindex{Local Coercion}\\
- Declares the construction denoted by {\qualid} as a coercion local to
- the current section.
-
-\item {\tt Coercion {\ident} := {\term}}\comindex{Coercion}\\
- This defines {\ident} just like \texttt{Definition {\ident} :=
- {\term}}, and then declares {\ident} as a coercion between it
- source and its target.
-
-\item {\tt Coercion {\ident} := {\term} : {\type}}\\
- This defines {\ident} just like
- \texttt{Definition {\ident} : {\type} := {\term}}, and then
- declares {\ident} as a coercion between it source and its target.
-
-\item {\tt Local Coercion {\ident} := {\term}}\comindex{Local Coercion}\\
- This defines {\ident} just like \texttt{Let {\ident} :=
- {\term}}, and then declares {\ident} as a coercion between it
- source and its target.
-
-\item Assumptions can be declared as coercions at declaration
-time. This extends the grammar of assumptions from
-Figure~\ref{sentences-syntax} as follows:
-\comindex{Variable \mbox{\rm (and coercions)}}
-\comindex{Axiom \mbox{\rm (and coercions)}}
-\comindex{Parameter \mbox{\rm (and coercions)}}
-\comindex{Hypothesis \mbox{\rm (and coercions)}}
-
-\begin{tabular}{lcl}
-%% Declarations
-{\assumption} & ::= & {\assumptionkeyword} {\assums} {\tt .} \\
-&&\\
-{\assums} & ::= & {\simpleassums} \\
- & $|$ & \nelist{{\tt (} \simpleassums {\tt )}}{} \\
-&&\\
-{\simpleassums} & ::= & \nelist{\ident}{} {\tt :}\zeroone{{\tt >}} {\term}\\
-\end{tabular}
-
-If the extra {\tt >} is present before the type of some assumptions, these
-assumptions are declared as coercions.
-
-\item 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{sentences-syntax} as follows:
-\comindex{Inductive \mbox{\rm (and coercions)}}
-\comindex{CoInductive \mbox{\rm (and coercions)}}
-
-\begin{center}
-\begin{tabular}{lcl}
-%% Inductives
-{\inductive} & ::= &
- {\tt Inductive} \nelist{\inductivebody}{with} {\tt .} \\
- & $|$ & {\tt CoInductive} \nelist{\inductivebody}{with} {\tt .} \\
- & & \\
-{\inductivebody} & ::= &
- {\ident} \zeroone{\binders} {\tt :} {\term} {\tt :=} \\
- && ~~~\zeroone{\zeroone{\tt |} \nelist{\constructor}{|}} \\
- & & \\
-{\constructor} & ::= & {\ident} \zeroone{\binders} \zeroone{{\tt :}\zeroone{\tt >} {\term}} \\
-\end{tabular}
-\end{center}
-
-Especially, if the extra {\tt >} is present in a constructor
-declaration, this constructor is declared as a coercion.
-\end{Variants}
-
-\asubsection{\tt Identity Coercion {\ident}:{\class$_1$} >-> {\class$_2$}.}
-\comindex{Identity Coercion}
-
-We check that {\class$_1$} is a constant with a value of the form
-$fun~ (x_1:T_1)..(x_n:T_n) => (\mbox{\class}_2~t_1..t_m)$ where $m$ is the
-number of parameters of \class$_2$. Then we define an identity
-function with the type
-$forall~ (x_1:T_1)..(x_n:T_n)(y:\mbox{\class}_1~x_1..x_n),
-{\mbox{\class}_2}~t_1..t_m$, and we declare it as an identity
-coercion between {\class$_1$} and {\class$_2$}.
-
-\begin{ErrMsgs}
-\item {\class$_1$} \errindex{must be a transparent constant}
-\end{ErrMsgs}
-
-\begin{Variants}
-\item {\tt Local Identity Coercion {\ident}:{\ident$_1$} >-> {\ident$_2$}.} \\
-Idem but locally to the current section.
-
-\item {\tt SubClass {\ident} := {\type}.} \\
-\comindex{SubClass}
- If {\type} is a class
-{\ident'} applied to some arguments then {\ident} is defined and an
-identity coercion of name {\tt Id\_{\ident}\_{\ident'}} is
-declared. Otherwise said, this is an abbreviation for
-
-{\tt Definition {\ident} := {\type}.}
-
- followed by
-
-{\tt Identity Coercion Id\_{\ident}\_{\ident'}:{\ident} >-> {\ident'}}.
-
-\item {\tt Local SubClass {\ident} := {\type}.} \\
-Same as before but locally to the current section.
-
-\end{Variants}
-
-\asection{Displaying Available Coercions}
-
-\asubsection{\tt Print Classes.}
-\comindex{Print Classes}
-Print the list of declared classes in the current context.
-
-\asubsection{\tt Print Coercions.}
-\comindex{Print Coercions}
-Print the list of declared coercions in the current context.
-
-\asubsection{\tt Print Graph.}
-\comindex{Print Graph}
-Print the list of valid coercion paths in the current context.
-
-\asubsection{\tt Print Coercion Paths {\class$_1$} {\class$_2$}.}
-\comindex{Print Coercion Paths}
-Print the list of valid coercion paths from {\class$_1$} to {\class$_2$}.
-
-\asection{Activating the Printing of Coercions}
-
-\asubsection{\tt Set Printing Coercions.}
-\optindex{Printing Coercions}
-
-This command forces all the coercions to be printed.
-Conversely, to skip the printing of coercions, use
- {\tt Unset Printing Coercions}.
-By default, coercions are not printed.
-
-\asubsection{\tt Add Printing Coercion {\qualid}.}
-\comindex{Add Printing Coercion}
-\comindex{Remove Printing Coercion}
-
-This command forces coercion denoted by {\qualid} to be printed.
-To skip the printing of coercion {\qualid}, use
- {\tt Remove Printing Coercion {\qualid}}.
-By default, a coercion is never printed.
-
-\asection{Classes as Records}
-\label{Coercions-and-records}
-\index{Coercions!and records}
-We allow the definition of {\em Structures with Inheritance} (or
-classes as records) by extending the existing {\tt Record} macro
-(see Section~\ref{Record}). Its new syntax is:
-
-\begin{center}
-\begin{tabular}{l}
-{\tt Record \zeroone{>}~{\ident} \zeroone{\binders} : {\sort} := \zeroone{\ident$_0$} \verb+{+} \\
-~~~~\begin{tabular}{l}
- {\tt \ident$_1$ $[$:$|$:>$]$ \term$_1$ ;} \\
- ... \\
- {\tt \ident$_n$ $[$:$|$:>$]$ \term$_n$ \verb+}+. }
- \end{tabular}
-\end{tabular}
-\end{center}
-The identifier {\ident} is the name of the defined record and {\sort}
-is its type. The identifier {\ident$_0$} is the name of its
-constructor. The identifiers {\ident$_1$}, .., {\ident$_n$} are the
-names of its fields and {\term$_1$}, .., {\term$_n$} their respective
-types. The alternative {\tt $[$:$|$:>$]$} is ``{\tt :}'' or ``{\tt
-:>}''. If {\tt {\ident$_i$}:>{\term$_i$}}, then {\ident$_i$} is
-automatically declared as coercion from {\ident} to the class of
-{\term$_i$}. Remark that {\ident$_i$} always verifies the uniform
-inheritance condition. If the optional ``{\tt >}'' before {\ident} is
-present, then {\ident$_0$} (or the default name {\tt Build\_{\ident}}
-if {\ident$_0$} is omitted) is automatically declared as a coercion
-from the class of {\term$_n$} to {\ident} (this may fail if the
-uniform inheritance condition is not satisfied).
-
-\Rem The keyword {\tt Structure}\comindex{Structure} is a synonym of {\tt
-Record}.
-
-\asection{Coercions and Sections}
-\index{Coercions!and sections}
- The inheritance mechanism is compatible with the section
-mechanism. The global classes and coercions defined inside a section
-are redefined after its closing, using their new value and new
-type. The classes and coercions which are local to the section are
-simply forgotten.
-Coercions with a local source class or a local target class, and
-coercions which do not verify the uniform inheritance condition any longer
-are also forgotten.
-
-\asection{Coercions and Modules}
-\index{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:
-
-\optindex{Automatic Coercions Import}
-\begin{verbatim}
-Set Automatic Coercions Import.
-\end{verbatim}
-
-To cancel the effect of the option, use instead:
-
-\begin{verbatim}
-Unset Automatic Coercions Import.
-\end{verbatim}
-
-\asection{Examples}
-
- There are three situations:
-
-\begin{itemize}
-\item $f~a$ is ill-typed where $f:forall~x:A,B$ and $a:A'$. If there is a
- coercion path between $A'$ and $A$, $f~a$ is transformed into
- $f~a'$ where $a'$ is the result of the application of this
- coercion path to $a$.
-
-We first give an example of coercion between atomic inductive types
-
-%\begin{\small}
-\begin{coq_example}
-Definition bool_in_nat (b:bool) := if b then 0 else 1.
-Coercion bool_in_nat : bool >-> nat.
-Check (0 = true).
-Set Printing Coercions.
-Check (0 = true).
-\end{coq_example}
-%\end{small}
-
-\begin{coq_eval}
-Unset Printing Coercions.
-\end{coq_eval}
-
-\Warning ``\verb|Check true=O.|'' fails. This is ``normal'' behaviour of
-coercions. To validate \verb|true=O|, the coercion is searched from
-\verb=nat= to \verb=bool=. There is none.
-
-We give an example of coercion between classes with parameters.
-
-%\begin{\small}
-\begin{coq_example}
-Parameters
- (C : nat -> Set) (D : nat -> bool -> Set) (E : bool -> Set).
-Parameter f : forall n:nat, C n -> D (S n) true.
-Coercion f : C >-> D.
-Parameter g : forall (n:nat) (b:bool), D n b -> E b.
-Coercion g : D >-> E.
-Parameter c : C 0.
-Parameter T : E true -> nat.
-Check (T c).
-Set Printing Coercions.
-Check (T c).
-\end{coq_example}
-%\end{small}
-
-\begin{coq_eval}
-Unset Printing Coercions.
-\end{coq_eval}
-
-We give now an example using identity coercions.
-
-%\begin{small}
-\begin{coq_example}
-Definition D' (b:bool) := D 1 b.
-Identity Coercion IdD'D : D' >-> D.
-Print IdD'D.
-Parameter d' : D' true.
-Check (T d').
-Set Printing Coercions.
-Check (T d').
-\end{coq_example}
-%\end{small}
-
-\begin{coq_eval}
-Unset Printing Coercions.
-\end{coq_eval}
-
-
- In the case of functional arguments, we use the monotonic rule of
-sub-typing. Approximatively, to coerce $t:forall~x:A, B$ towards
-$forall~x:A',B'$, one have to coerce $A'$ towards $A$ and $B$ towards
-$B'$. An example is given below:
-
-%\begin{small}
-\begin{coq_example}
-Parameters (A B : Set) (h : A -> B).
-Coercion h : A >-> B.
-Parameter U : (A -> E true) -> nat.
-Parameter t : B -> C 0.
-Check (U t).
-Set Printing Coercions.
-Check (U t).
-\end{coq_example}
-%\end{small}
-
-\begin{coq_eval}
-Unset Printing Coercions.
-\end{coq_eval}
-
- Remark the changes in the result following the modification of the
-previous example.
-
-%\begin{small}
-\begin{coq_example}
-Parameter U' : (C 0 -> B) -> nat.
-Parameter t' : E true -> A.
-Check (U' t').
-Set Printing Coercions.
-Check (U' t').
-\end{coq_example}
-%\end{small}
-
-\begin{coq_eval}
-Unset Printing Coercions.
-\end{coq_eval}
-
-\item An assumption $x:A$ when $A$ is not a type, is ill-typed. It is
- replaced by $x:A'$ where $A'$ is the result of the application
- to $A$ of the coercion path between the class of $A$ and {\tt
- Sortclass} if it exists. This case occurs in the abstraction
- $fun~ x:A => t$, universal quantification $forall~x:A, B$,
- global variables and parameters of (co-)inductive definitions
- and functions. In $forall~x:A, B$, such a coercion path may be
- applied to $B$ also if necessary.
-
-%\begin{small}
-\begin{coq_example}
-Parameter Graph : Type.
-Parameter Node : Graph -> Type.
-Coercion Node : Graph >-> Sortclass.
-Parameter G : Graph.
-Parameter Arrows : G -> G -> Type.
-Check Arrows.
-Parameter fg : G -> G.
-Check fg.
-Set Printing Coercions.
-Check fg.
-\end{coq_example}
-%\end{small}
-
-\begin{coq_eval}
-Unset Printing Coercions.
-\end{coq_eval}
-
-\item $f~a$ is ill-typed because $f:A$ is not a function. The term
- $f$ is replaced by the term obtained by applying to $f$ the
- coercion path between $A$ and {\tt Funclass} if it exists.
-
-%\begin{small}
-\begin{coq_example}
-Parameter bij : Set -> Set -> Set.
-Parameter ap : forall A B:Set, bij A B -> A -> B.
-Coercion ap : bij >-> Funclass.
-Parameter b : bij nat nat.
-Check (b 0).
-Set Printing Coercions.
-Check (b 0).
-\end{coq_example}
-%\end{small}
-
-\begin{coq_eval}
-Unset Printing Coercions.
-\end{coq_eval}
-
-Let us see the resulting graph of this session.
-
-%\begin{small}
-\begin{coq_example}
-Print Graph.
-\end{coq_example}
-%\end{small}
-
-\end{itemize}
-
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
diff --git a/doc/refman/Extraction.tex b/doc/refman/Extraction.tex
deleted file mode 100644
index cff7be3e9..000000000
--- a/doc/refman/Extraction.tex
+++ /dev/null
@@ -1,620 +0,0 @@
-\achapter{Extraction of programs in OCaml and Haskell}
-%HEVEA\cutname{extraction.html}
-\label{Extraction}
-\aauthor{Jean-Christophe Filliâtre and Pierre Letouzey}
-\index{Extraction}
-
-\noindent 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{},
-\textsc{Haskell} and \textsc{Scheme}. In the following, ``ML'' will
-be used (abusively) to refer to any of the three.
-
-%% \paragraph{Differences with old versions.}
-%% The current extraction mechanism is new for version 7.0 of {\Coq}.
-%% In particular, the \FW\ toplevel used as an intermediate step between
-%% \Coq\ and ML has been withdrawn. It is also not possible
-%% any more to import ML objects in this \FW\ toplevel.
-%% The current mechanism also differs from
-%% the one in previous versions of \Coq: there is no more
-%% an explicit toplevel for the language (formerly called \textsc{Fml}).
-
-Before using any of the commands or options described in this chapter,
-the extraction framework should first be loaded explicitly
-via {\tt Require Extraction}, or via the more robust
-{\tt From Coq Require Extraction}.
-Note that in earlier versions of Coq, these commands and options were
-directly available without any preliminary {\tt Require}.
-
-\begin{coq_example}
-Require Extraction.
-\end{coq_example}
-
-\asection{Generating ML code}
-\comindex{Extraction}
-\comindex{Recursive Extraction}
-\comindex{Separate Extraction}
-\comindex{Extraction Library}
-\comindex{Recursive Extraction Library}
-
-The next two commands are meant to be used for rapid preview of
-extraction. They both display extracted term(s) inside \Coq.
-
-\begin{description}
-\item {\tt Extraction \qualid{}.} ~\par
- Extraction of a constant or module in the \Coq\ toplevel.
-
-\item {\tt Recursive Extraction} \qualid$_1$ \dots\ \qualid$_n$. ~\par
- Recursive extraction of all the globals (or modules) \qualid$_1$ \dots\
- \qualid$_n$ and all their dependencies in the \Coq\ toplevel.
-\end{description}
-
-%% TODO error messages
-
-\noindent All the following commands produce real ML files. User can choose to produce
-one monolithic file or one file per \Coq\ library.
-
-\begin{description}
-\item {\tt Extraction "{\em file}"}
- \qualid$_1$ \dots\ \qualid$_n$. ~\par
- Recursive extraction of all the globals (or modules) \qualid$_1$ \dots\
- \qualid$_n$ and all their dependencies in one monolithic file {\em file}.
- Global and local identifiers are renamed according to the chosen ML
- language to fulfill its syntactic conventions, keeping original
- names as much as possible.
-
-\item {\tt Extraction Library} \ident. ~\par
- Extraction of the whole \Coq\ library {\tt\ident.v} to an ML module
- {\tt\ident.ml}. In case of name clash, identifiers are here renamed
- using prefixes \verb!coq_! or \verb!Coq_! to ensure a
- session-independent renaming.
-
-\item {\tt Recursive Extraction Library} \ident. ~\par
- Extraction of the \Coq\ library {\tt\ident.v} and all other modules
- {\tt\ident.v} depends on.
-
-\item {\tt Separate Extraction}
- \qualid$_1$ \dots\ \qualid$_n$. ~\par
- Recursive extraction of all the globals (or modules) \qualid$_1$ \dots\
- \qualid$_n$ and all their dependencies, just as {\tt
- Extraction "{\em file}"}, but instead of producing one monolithic
- file, this command splits the produced code in separate ML files, one per
- corresponding Coq {\tt .v} file. This command is hence quite similar
- to {\tt 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
- {\tt Extraction Library}: identifiers are here renamed
- using prefixes \verb!coq_! or \verb!Coq_!.
-\end{description}
-
-\noindent The following command is meant to help automatic testing of
- the extraction, see for instance the {\tt test-suite} directory
- in the \Coq\ sources.
-
-\begin{description}
-\item {\tt Extraction TestCompile} \qualid$_1$ \dots\ \qualid$_n$. ~\par
- All the globals (or modules) \qualid$_1$ \dots\ \qualid$_n$ and all
- their dependencies are extracted to a temporary {\ocaml} file, just as in
- {\tt Extraction "{\em 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 (and it fails if the current target language
- of the extraction is not {\ocaml}).
-\end{description}
-
-\asection{Extraction options}
-
-\asubsection{Setting the target language}
-\comindex{Extraction Language}
-
-The ability to fix target language is the first and more important
-of the extraction options. Default is {\ocaml}.
-\begin{description}
-\item {\tt Extraction Language OCaml}.
-\item {\tt Extraction Language Haskell}.
-\item {\tt Extraction Language Scheme}.
-\end{description}
-
-\asubsection{Inlining and optimizations}
-
-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
-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,
-even if some inlining is done, the inlined constant are nevertheless
-printed, to ensure session-independent programs.
-
-Concerning Haskell, type-preserving optimizations are less useful
-because of laziness. We still make some optimizations, for example in
-order to produce more readable code.
-
-The type-preserving optimizations are controlled by the following \Coq\ options:
-
-\begin{description}
-
-\item \optindex{Extraction Optimize} {\tt Unset Extraction Optimize.}
-
-Default is Set. This controls all type-preserving optimizations made on
-the ML terms (mostly reduction of dummy beta/iota redexes, but also
-simplifications on Cases, etc). Put this option to Unset if you want a
-ML term as close as possible to the Coq term.
-
-\item \optindex{Extraction Conservative Types}
-{\tt Set Extraction Conservative Types.}
-
-Default is Unset. This controls the non type-preserving optimizations
-made on ML terms (which try to avoid function abstraction of dummy
-types). Turn this option to Set to make sure that {\tt e:t}
-implies that {\tt e':t'} where {\tt e'} and {\tt t'} are the extracted
-code of {\tt e} and {\tt t} respectively.
-
-\item \optindex{Extraction KeepSingleton}
-{\tt Set Extraction KeepSingleton.}
-
-Default is Unset. Normally, when the extraction of an inductive type
-produces a singleton type (i.e. a type with only one constructor, and
-only one argument to this constructor), the inductive structure is
-removed and this type is seen as an alias to the inner type.
-The typical example is {\tt sig}. This option allows disabling this
-optimization when one wishes to preserve the inductive structure of types.
-
-\item \optindex{Extraction AutoInline} {\tt Unset Extraction AutoInline.}
-
-Default is Set. The extraction mechanism
-inlines the bodies of some defined constants, according to some heuristics
-like size of bodies, uselessness of some arguments, etc. Those heuristics are
-not always perfect; if you want to disable this feature, do it by Unset.
-
-\item \comindex{Extraction Inline} \comindex{Extraction NoInline}
-{\tt Extraction [Inline|NoInline] \qualid$_1$ \dots\ \qualid$_n$}.
-
-In addition to the automatic inline feature, you can tell to
-inline some more constants by the {\tt Extraction Inline} command. Conversely,
-you can forbid the automatic inlining of some specific constants by
-the {\tt Extraction NoInline} command.
-Those two commands enable a precise control of what is inlined and what is not.
-
-\item \comindex{Print Extraction Inline}
-{\tt Print Extraction Inline}.
-
-Prints the current state of the table recording the custom inlinings
-declared by the two previous commands.
-
-\item \comindex{Reset Extraction Inline}
-{\tt Reset Extraction Inline}.
-
-Puts the table recording the custom inlinings back to empty.
-
-\end{description}
-
-
-\paragraph{Inlining and printing of a constant declaration.}
-
-A user can explicitly ask for a constant to be extracted by two means:
-\begin{itemize}
-\item by mentioning it on the extraction command line
-\item by extracting the whole \Coq\ module of this constant.
-\end{itemize}
-In both cases, the declaration of this constant will be present in the
-produced file.
-But this same constant may or may not be inlined in the following
-terms, depending on the automatic/custom inlining mechanism.
-
-
-For the constants non-explicitly required but needed for dependency
-reasons, there are two cases:
-\begin{itemize}
-\item If an inlining decision is taken, whether automatically or not,
-all occurrences of this constant are replaced by its extracted body, and
-this constant is not declared in the generated file.
-\item If no inlining decision is taken, the constant is normally
- declared in the produced file.
-\end{itemize}
-
-\asubsection{Extra elimination of useless arguments}
-
-The following command provides some extra manual control on the
-code elimination performed during extraction, in a way which
-is independent but complementary to the main elimination
-principles of extraction (logical parts and types).
-
-\begin{description}
-\item \comindex{Extraction Implicit}
- {\tt Extraction Implicit} \qualid\ [ \ident$_1$ \dots\ \ident$_n$ ].
-
-This experimental command allows declaring some arguments of
-\qualid\ as implicit, i.e. useless in extracted code and hence to
-be removed by extraction. Here \qualid\ can be any function or
-inductive constructor, and \ident$_i$ are the names of the concerned
-arguments. In fact, an argument can also be referred by a number
-indicating its position, starting from 1.
-\end{description}
-
-\noindent When an actual extraction takes place, an error is normally raised if the
-{\tt 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:
-
-\begin{description}
-\item \optindex{Extraction SafeImplicits} {\tt Unset Extraction SafeImplicits.}
-
-Default is Set. When this option is Unset, a warning is emitted
-instead of an error if some implicited variables still occur in the
-final code of an extraction. This way, the extracted code may be
-obtained nonetheless and reviewed manually to locate the source of the issue
-(in the code, some comments mark the location of these remaining
-implicited variables).
-Note that this extracted code might not compile or run properly,
-depending of the use of these remaining implicited variables.
-
-\end{description}
-
-\asubsection{Realizing axioms}\label{extraction:axioms}
-
-Extraction will fail if it encounters an informative
-axiom not realized (see Section~\ref{extraction:axioms}).
-A warning will be issued if it encounters a logical axiom, to remind the
-user that inconsistent logical axioms may lead to incorrect or
-non-terminating extracted terms.
-
-It is possible to assume some axioms while developing a proof. Since
-these axioms can be any kind of proposition or object or type, they may
-perfectly well have some computational content. But a program must be
-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.
-
-\comindex{Extract Constant}
-\begin{description}
-\item{\tt Extract Constant \qualid\ => \str.} ~\par
- Give an ML extraction for the given constant.
- The \str\ may be an identifier or a quoted string.
-\item{\tt Extract Inlined Constant \qualid\ => \str.} ~\par
- Same as the previous one, except that the given ML terms will
- be inlined everywhere instead of being declared via a let.
-\end{description}
-
-\noindent Note that the {\tt Extract Inlined Constant} command is sugar
-for an {\tt Extract Constant} followed by a {\tt Extraction Inline}.
-Hence a {\tt Reset Extraction Inline} will have an effect on the
-realized and inlined axiom.
-
-Of course, it is the responsibility of the user to ensure that the ML
-terms given to realize the axioms do have the expected types. In
-fact, the strings containing realizing code are just copied to the
-extracted files. The extraction recognizes whether the realized axiom
-should become a ML type constant or a ML object declaration.
-
-\Example
-\begin{coq_example*}
-Axiom X:Set.
-Axiom x:X.
-Extract Constant X => "int".
-Extract Constant x => "0".
-\end{coq_example*}
-
-\noindent 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. The syntax is then:
-
-\begin{description}
-\item{\tt Extract Constant \qualid\ \str$_1$ \dots\ \str$_n$ => \str.}
-\end{description}
-
-\noindent The number of type variables is checked by the system.
-
-\Example
-\begin{coq_example*}
-Axiom Y : Set -> Set -> Set.
-Extract Constant Y "'a" "'b" => " 'a*'b ".
-\end{coq_example*}
-
-\noindent Realizing an axiom via {\tt 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
-logical axiom. This warning reminds user that inconsistent logical
-axioms may lead to incorrect or non-terminating extracted terms.
-
-If an informative axiom has not been realized before an extraction, a
-warning is also issued and the definition of the axiom is filled with
-an exception labeled {\tt AXIOM TO BE REALIZED}. The user must then
-search these exceptions inside the extracted file and replace them by
-real code.
-
-\comindex{Extract Inductive}
-
-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:
-
-\begin{description}
-\item{\tt Extract Inductive \qualid\ => \str\ [ \str\ \dots\ \str\ ] {\it optstring}.}\par
- Give an ML extraction for the given inductive type. You must specify
- extractions for the type itself (first \str) and all its
- constructors (between square brackets). If given, the final optional
- string should contain a function emulating pattern-matching over this
- inductive type. If this optional string is not given, the ML
- extraction must be an ML inductive datatype, and the native
- pattern-matching of the language will be used.
-\end{description}
-
-\noindent For an inductive type with $k$ constructor, the function used to
-emulate the match should expect $(k+1)$ arguments, first the $k$
-branches in functional form, and then the inductive element to
-destruct. For instance, the match branch \verb$| S n => foo$ gives the
-functional form \verb$(fun n -> foo)$. Note that a constructor with no
-argument is considered to have one unit argument, in order to block
-early evaluation of the branch: \verb$| O => bar$ leads to the functional
-form \verb$(fun () -> bar)$. For instance, when extracting {\tt nat}
-into {\tt int}, the code to provide has type:
-{\tt (unit->'a)->(int->'a)->int->'a}.
-
-As for {\tt Extract Inductive}, this command should be used with care:
-\begin{itemize}
-\item The ML code provided by the user is currently \emph{not} checked at all by
- extraction, even for syntax errors.
-
-\item 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 \emph{not} be fully rigorously
-correct. For instance, when extracting {\tt nat} to {\ocaml}'s {\tt
-int}, it is theoretically possible to build {\tt nat} values that are
-larger than {\ocaml}'s {\tt max\_int}. It is the user's responsibility to
-be sure that no overflow or other bad events occur in practice.
-
-\item Translating an inductive type to an ML type does \emph{not}
-magically improve the asymptotic complexity of functions, even if the
-ML type is an efficient representation. For instance, when extracting
-{\tt nat} to {\ocaml}'s {\tt int}, the function {\tt mult} stays
-quadratic. It might be interesting to associate this translation with
-some specific {\tt Extract Constant} when primitive counterparts exist.
-\end{itemize}
-
-\Example
-Typical examples are the following:
-\begin{coq_eval}
-Require Extraction.
-\end{coq_eval}
-\begin{coq_example}
-Extract Inductive unit => "unit" [ "()" ].
-Extract Inductive bool => "bool" [ "true" "false" ].
-Extract Inductive sumbool => "bool" [ "true" "false" ].
-\end{coq_example}
-
-\noindent 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 used as infix constructor or type.
-
-\begin{coq_example}
-Extract Inductive list => "list" [ "[]" "(::)" ].
-Extract Inductive prod => "(*)" [ "(,)" ].
-\end{coq_example}
-
-\noindent As an example of translation to a non-inductive datatype, let's turn
-{\tt nat} into {\ocaml}'s {\tt int} (see caveat above):
-\begin{coq_example}
-Extract Inductive nat => int [ "0" "succ" ]
- "(fun fO fS n -> if n=0 then fO () else fS (n-1))".
-\end{coq_example}
-
-\asubsection{Avoiding conflicts with existing filenames}
-
-\comindex{Extraction Blacklist}
-
-When using {\tt 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 {\tt List} exists both in \Coq\ and in {\ocaml}.
-It is possible to instruct the extraction not to use particular filenames.
-
-\begin{description}
-\item{\tt Extraction Blacklist} \ident\ \dots\ \ident. ~\par
- Instruct the extraction to avoid using these names as filenames
- for extracted code.
-\item{\tt Print Extraction Blacklist.} ~\par
- Show the current list of filenames the extraction should avoid.
-\item{\tt Reset Extraction Blacklist.} ~\par
- Allow the extraction to use any filename.
-\end{description}
-
-\noindent For {\ocaml}, a typical use of these commands is
-{\tt Extraction Blacklist String List}.
-
-\asection{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
-when needed some unsafe casting {\tt Obj.magic}, which give
-a generic type {\tt 'a} to any term.
-
-For example, here are two kinds of problem that can occur:
-
-\begin{itemize}
- \item If some part of the program is {\em very} polymorphic, there
- may be no ML type for it. In that case the extraction to ML works
- alright but the generated code may be refused by the ML
- type-checker. A very well known example is the {\em distr-pair}
- function:
-\begin{verbatim}
-Definition dp :=
- fun (A B:Set)(x:A)(y:B)(f:forall C:Set, C->C) => (f A x, f B y).
-\end{verbatim}
-
-In {\ocaml}, for instance, the direct extracted term would be
-\begin{verbatim}
-let dp x y f = Pair((f () x),(f () y))
-\end{verbatim}
-
-and would have type
-\begin{verbatim}
-dp : 'a -> 'a -> (unit -> 'a -> 'b) -> ('b,'b) prod
-\end{verbatim}
-
-which is not its original type, but a restriction.
-
-We now produce the following correct version:
-\begin{verbatim}
-let dp x y f = Pair ((Obj.magic f () x), (Obj.magic f () y))
-\end{verbatim}
-
- \item Some definitions of \Coq\ may have no counterpart in ML. This
- happens when there is a quantification over types inside the type
- of a constructor; for example:
-\begin{verbatim}
-Inductive anything : Type := dummy : forall A:Set, A -> anything.
-\end{verbatim}
-
-which corresponds to the definition of an ML dynamic type.
-In {\ocaml}, we must cast any argument of the constructor dummy.
-
-\end{itemize}
-
-\noindent 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
-from a Coq well-typed terms, so for example inductives will always
-have the correct number of arguments, etc.
-
-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 Caml type-checker without any {\tt Obj.magic} (see examples below).
-
-
-
-\asection{Some examples}
-
-We present here two examples of extractions, taken from the
-\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.
-
-\asubsection{A detailed example: Euclidean division}
-
-The file {\tt Euclid} contains the proof of Euclidean division
-(theorem {\tt eucl\_dev}). The natural numbers defined in the example
-files are unary integers defined by two constructors $O$ and $S$:
-\begin{coq_example*}
-Inductive nat : Set :=
- | O : nat
- | S : nat -> nat.
-\end{coq_example*}
-
-\noindent This module contains a theorem {\tt eucl\_dev}, whose type is
-\begin{verbatim}
-forall b:nat, b > 0 -> forall a:nat, diveucl a b
-\end{verbatim}
-where {\tt 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:
-
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-\begin{coq_example}
-Require Extraction.
-Require Import Euclid Wf_nat.
-Extraction Inline gt_wf_rec lt_wf_rec induction_ltof2.
-Recursive Extraction eucl_dev.
-\end{coq_example}
-
-\noindent The inlining of {\tt gt\_wf\_rec} and others is not
-mandatory. It only enhances readability of extracted code.
-You can then copy-paste the output to a file {\tt euclid.ml} or let
-\Coq\ do it for you with the following command:
-
-\begin{verbatim}
-Extraction "euclid" eucl_dev.
-\end{verbatim}
-
-\noindent Let us play the resulting program:
-
-\begin{verbatim}
-# #use "euclid.ml";;
-type nat = O | S of nat
-type sumbool = Left | Right
-val minus : nat -> nat -> nat = <fun>
-val le_lt_dec : nat -> nat -> sumbool = <fun>
-val le_gt_dec : nat -> nat -> sumbool = <fun>
-type diveucl = Divex of nat * nat
-val eucl_dev : nat -> nat -> diveucl = <fun>
-# eucl_dev (S (S O)) (S (S (S (S (S O)))));;
-- : diveucl = Divex (S (S O), S O)
-\end{verbatim}
-It is easier to test on \ocaml\ integers:
-\begin{verbatim}
-# let rec nat_of_int = function 0 -> O | n -> S (nat_of_int (n-1));;
-val nat_of_int : int -> nat = <fun>
-# let rec int_of_nat = function O -> 0 | S p -> 1+(int_of_nat p);;
-val int_of_nat : nat -> int = <fun>
-# let div a b =
- let Divex (q,r) = eucl_dev (nat_of_int b) (nat_of_int a)
- in (int_of_nat q, int_of_nat r);;
-val div : int -> int -> int * int = <fun>
-# div 173 15;;
-- : int * int = (11, 8)
-\end{verbatim}
-
-\noindent Note that these {\tt nat\_of\_int} and {\tt int\_of\_nat} are now
-available via a mere {\tt Require Import ExtrOcamlIntConv} and then
-adding these functions to the list of functions to extract. This file
-{\tt ExtrOcamlIntConv.v} and some others in {\tt plugins/extraction/}
-are meant to help building concrete program via extraction.
-
-\asubsection{Extraction's horror museum}
-
-Some pathological examples of extraction are grouped in the file\\
-{\tt test-suite/success/extraction.v} of the sources of \Coq.
-
-\asubsection{Users' Contributions}
-
-Several of the \Coq\ Users' Contributions use extraction to produce
-certified programs. In particular the following ones have an automatic
-extraction test:
-
-\begin{itemize}
-\item {\tt additions}
-\item {\tt bdds}
-\item {\tt canon-bdds}
-\item {\tt chinese}
-\item {\tt continuations}
-\item {\tt coq-in-coq}
-\item {\tt exceptions}
-\item {\tt firing-squad}
-\item {\tt founify}
-\item {\tt graphs}
-\item {\tt higman-cf}
-\item {\tt higman-nw}
-\item {\tt hardware}
-\item {\tt multiplier}
-\item {\tt search-trees}
-\item {\tt stalmarck}
-\end{itemize}
-
-\noindent {\tt continuations} and {\tt multiplier} are a bit particular. They are
-examples of developments where {\tt Obj.magic} are needed. This is
-probably due to an heavy use of impredicativity. After compilation, those
-two examples run nonetheless, thanks to the correction of the
-extraction~\cite{Let02}.
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
diff --git a/doc/refman/Misc.tex b/doc/refman/Misc.tex
deleted file mode 100644
index ab00fbfe3..000000000
--- a/doc/refman/Misc.tex
+++ /dev/null
@@ -1,63 +0,0 @@
-\achapter{\protect{Miscellaneous extensions}}
-%HEVEA\cutname{miscellaneous.html}
-
-\asection{Program derivation}
-
-Coq comes with an extension called {\tt Derive}, which supports
-program derivation. Typically in the style of Bird and Meertens or
-derivations of program refinements. To use the {\tt Derive} extension
-it must first be required with {\tt Require Coq.Derive.Derive}. When
-the extension is loaded, it provides the following command.
-
-\subsection[\tt Derive \ident$_1$ SuchThat \term{} As \ident$_2$]
- {\tt Derive \ident$_1$ SuchThat \term{} As \ident$_2$\comindex{Derive}}
-
-The name $\ident_1$ can appear in \term. This command opens a new
-proof presenting the user with a goal for \term{} in which the name
-$\ident_1$ is bound to a existential variables {\tt ?x} (formally,
-there are other goals standing for the existential variables but they
-are shelved, as described in Section~\ref{shelve}).
-
-When the proof ends two constants are defined:
-\begin{itemize}
-\item The first one is name $\ident_1$ and is defined as the proof of
- the shelved goal (which is also the value of {\tt ?x}). It is
-always transparent.
-\item The second one is name $\ident_2$. It has type {\tt \term}, and
- its body is the proof of the initially visible goal. It is opaque if
- the proof ends with {\tt Qed}, and transparent if the proof ends
- with {\tt Defined}.
-\end{itemize}
-
-\Example
-\begin{coq_example*}
-Require Coq.derive.Derive.
-Require Import Coq.Numbers.Natural.Peano.NPeano.
-
-Section P.
-
-Variables (n m k:nat).
-
-\end{coq_example*}
-\begin{coq_example}
-Derive p SuchThat ((k*n)+(k*m) = p) As h.
-Proof.
-rewrite <- Nat.mul_add_distr_l.
-subst p.
-reflexivity.
-\end{coq_example}
-\begin{coq_example*}
-Qed.
-
-End P.
-
-\end{coq_example*}
-\begin{coq_example}
-Print p.
-Check h.
-\end{coq_example}
-
-Any property can be used as \term, not only an equation. In
-particular, it could be an order relation specifying some form of
-program refinement or a non-executable property from which deriving a
-program is convenient.
diff --git a/doc/refman/Nsatz.tex b/doc/refman/Nsatz.tex
deleted file mode 100644
index 1401af10f..000000000
--- a/doc/refman/Nsatz.tex
+++ /dev/null
@@ -1,102 +0,0 @@
-\achapter{Nsatz: tactics for proving equalities in integral domains}
-%HEVEA\cutname{nsatz.html}
-\aauthor{Loïc Pottier}
-
-The tactic \texttt{nsatz} proves goals of the form
-
-\[ \begin{array}{l}
- \forall X_1,\ldots,X_n \in A,\\
- P_1(X_1,\ldots,X_n) = Q_1(X_1,\ldots,X_n) , \ldots , P_s(X_1,\ldots,X_n) =Q_s(X_1,\ldots,X_n)\\
- \vdash P(X_1,\ldots,X_n) = Q(X_1,\ldots,X_n)\\
- \end{array}
-\]
-where $P,Q, P_1,Q_1,\ldots,P_s,Q_s$ are polynomials and A is an integral
-domain, i.e. a commutative ring with no zero divisor. For example, A can be
-$\mathbb{R}$, $\mathbb{Z}$, of $\mathbb{Q}$. Note that the equality $=$ used in these
-goals can be any setoid equality
-(see \ref{setoidtactics})
-, not only Leibnitz equality.
-
-It also proves formulas
-\[ \begin{array}{l}
- \forall X_1,\ldots,X_n \in A,\\
- P_1(X_1,\ldots,X_n) = Q_1(X_1,\ldots,X_n) \wedge \ldots \wedge P_s(X_1,\ldots,X_n) =Q_s(X_1,\ldots,X_n)\\
- \rightarrow P(X_1,\ldots,X_n) = Q(X_1,\ldots,X_n)\\
- \end{array}
-\] doing automatic introductions.
-
-\asection{Using the basic tactic \texttt{nsatz}}
-\tacindex{nsatz}
-
-Load the
-\texttt{Nsatz} module: \texttt{Require Import Nsatz}.\\
- and use the tactic \texttt{nsatz}.
-
-\asection{More about \texttt{nsatz}}
-
-Hilbert's Nullstellensatz theorem shows how to reduce proofs of equalities on
-polynomials on a commutative ring A with no zero divisor to algebraic computations: it is easy to see that if a polynomial
-$P$ in $A[X_1,\ldots,X_n]$ verifies $c P^r = \sum_{i=1}^{s} S_i P_i$, with $c
-\in A$, $c \not = 0$, $r$ a positive integer, and the $S_i$s in
-$A[X_1,\ldots,X_n]$, then $P$ is zero whenever polynomials $P_1,...,P_s$ are
-zero (the converse is also true when A is an algebraic closed field:
-the method is complete).
-
-So, proving our initial problem can reduce into finding $S_1,\ldots,S_s$, $c$
-and $r$ such that $c (P-Q)^r = \sum_{i} S_i (P_i-Q_i)$, which will be proved by the
-tactic \texttt{ring}.
-
-This is achieved by the computation of a Groebner basis of the
-ideal generated by $P_1-Q_1,...,P_s-Q_s$, with an adapted version of the Buchberger
-algorithm.
-
-This computation is done after a step of {\em reification}, which is
-performed using {\em Type Classes}
-(see \ref{typeclasses})
-.
-
-The \texttt{Nsatz} module defines the tactic
-\texttt{nsatz}, which can be used without arguments: \\
-\vspace*{3mm}
-\texttt{nsatz}\\
-or with the syntax: \\
-\vspace*{3mm}
-\texttt{nsatz with radicalmax:={\em number}\%N strategy:={\em number}\%Z parameters:={\em list of variables} variables:={\em list of variables}}\\
-where:
-
-\begin{itemize}
- \item \texttt{radicalmax} is a bound when for searching r s.t.$c (P-Q)^r =
-\sum_{i=1..s} S_i (P_i - Q_i)$
-
- \item \texttt{strategy} gives the order on variables $X_1,...X_n$ and
-the strategy used in Buchberger algorithm (see
-\cite{sugar} for details):
-
- \begin{itemize}
- \item strategy = 0: reverse lexicographic order and newest s-polynomial.
- \item strategy = 1: reverse lexicographic order and sugar strategy.
- \item strategy = 2: pure lexicographic order and newest s-polynomial.
- \item strategy = 3: pure lexicographic order and sugar strategy.
- \end{itemize}
-
- \item \texttt{parameters} is the list of variables
-$X_{i_1},\ldots,X_{i_k}$ among $X_1,...,X_n$ which are considered as
- parameters: computation will be performed with rational fractions in these
- variables, i.e. polynomials are considered with coefficients in
-$R(X_{i_1},\ldots,X_{i_k})$. In this case, the coefficient $c$ can be a non
-constant polynomial in $X_{i_1},\ldots,X_{i_k}$, and the tactic produces a goal
-which states that $c$ is not zero.
-
- \item \texttt{variables} is the list of the variables
-in the decreasing order in which they will be used in Buchberger algorithm. If \texttt{variables} = {(@nil
-R)}, then \texttt{lvar} is replaced by all the variables which are not in
-parameters.
-
-\end{itemize}
-
-See file \texttt{Nsatz.v} for many examples, specially in geometry.
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
diff --git a/doc/refman/Polynom.tex b/doc/refman/Polynom.tex
deleted file mode 100644
index d9b8b8c52..000000000
--- a/doc/refman/Polynom.tex
+++ /dev/null
@@ -1,736 +0,0 @@
-\achapter{The \texttt{ring} and \texttt{field} tactic families}
-%HEVEA\cutname{ring.html}
-\aauthor{Bruno Barras, Benjamin Gr\'egoire, Assia
- Mahboubi, Laurent Th\'ery\footnote{based on previous work from
- Patrick Loiseleur and Samuel Boutin}}
-\label{ring}
-\tacindex{ring}
-
-This chapter presents the tactics dedicated to deal with ring and
-field equations.
-
-\asection{What does this tactic do?}
-
-\texttt{ring} does associative-commutative rewriting in ring and semi-ring
-structures. Assume you have two binary functions $\oplus$ and $\otimes$
-that are associative and commutative, with $\oplus$ distributive on
-$\otimes$, and two constants 0 and 1 that are unities for $\oplus$ and
-$\otimes$. A \textit{polynomial} is an expression built on variables $V_0, V_1,
-\dots$ and constants by application of $\oplus$ and $\otimes$.
-
-Let an {\it ordered product} be a product of variables $V_{i_1}
-\otimes \ldots \otimes V_{i_n}$ verifying $i_1 \le i_2 \le \dots \le
-i_n$. Let a \textit{monomial} be the product of a constant and an
-ordered product. We can order the monomials by the lexicographic
-order on products of variables. Let a \textit{canonical sum} be an
-ordered sum of monomials that are all different, i.e. each monomial in
-the sum is strictly less than the following monomial according to the
-lexicographic order. It is an easy theorem to show that every
-polynomial is equivalent (modulo the ring properties) to exactly one
-canonical sum. This canonical sum is called the \textit{normal form}
-of the polynomial. In fact, the actual representation shares monomials
-with same prefixes. So what does \texttt{ring}? It normalizes
-polynomials over any ring or semi-ring structure. The basic use of
-\texttt{ring} is to simplify ring expressions, so that the user does
-not have to deal manually with the theorems of associativity and
-commutativity.
-
-\begin{Examples}
-\item In the ring of integers, the normal form of
-$x (3 + yx + 25(1 - z)) + zx$ is $28x + (-24)xz + xxy$.
-\end{Examples}
-
-\texttt{ring} is also able to compute a normal form modulo monomial
-equalities. For example, under the hypothesis that $2x^2 = yz+1$,
- the normal form of $2(x + 1)x - x - zy$ is $x+1$.
-
-\asection{The variables map}
-
-It is frequent to have an expression built with + and
- $\times$, but rarely on variables only.
-Let us associate a number to each subterm of a ring
-expression in the \gallina\ language. For example in the ring
-\texttt{nat}, consider the expression:
-
-\begin{quotation}
-\begin{verbatim}
-(plus (mult (plus (f (5)) x) x)
- (mult (if b then (4) else (f (3))) (2)))
-\end{verbatim}
-\end{quotation}
-
-\noindent As a ring expression, it has 3 subterms. Give each subterm a
-number in an arbitrary order:
-
-\begin{tabular}{ccl}
-0 & $\mapsto$ & \verb|if b then (4) else (f (3))| \\
-1 & $\mapsto$ & \verb|(f (5))| \\
-2 & $\mapsto$ & \verb|x| \\
-\end{tabular}
-
-\noindent Then normalize the ``abstract'' polynomial
-
-$$((V_1 \otimes V_2) \oplus V_2) \oplus (V_0 \otimes 2) $$
-
-\noindent In our example the normal form is:
-
-$$(2 \otimes V_0) \oplus (V_1 \otimes V_2) \oplus (V_2 \otimes V_2)$$
-
-\noindent Then substitute the variables by their values in the variables map to
-get the concrete normal polynomial:
-
-\begin{quotation}
-\begin{verbatim}
-(plus (mult (2) (if b then (4) else (f (3))))
- (plus (mult (f (5)) x) (mult x x)))
-\end{verbatim}
-\end{quotation}
-
-\asection{Is it automatic?}
-
-Yes, building the variables map and doing the substitution after
-normalizing is automatically done by the tactic. So you can just forget
-this paragraph and use the tactic according to your intuition.
-
-\asection{Concrete usage in \Coq
-\tacindex{ring}
-\tacindex{ring\_simplify}}
-
-The {\tt ring} tactic solves equations upon polynomial expressions of
-a ring (or semi-ring) structure. It proceeds by normalizing both hand
-sides of the equation (w.r.t. associativity, commutativity and
-distributivity, constant propagation, rewriting of monomials)
-and comparing syntactically the results.
-
-{\tt ring\_simplify} applies the normalization procedure described
-above to the terms given. The tactic then replaces all occurrences of
-the terms 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.
-The tactic can also be applied in a hypothesis.
-
-The tactic must be loaded by \texttt{Require Import Ring}. The ring
-structures must be declared with the \texttt{Add Ring} command (see
-below). The ring of booleans is predefined; if one wants to use the
-tactic on \texttt{nat} one must first require the module
-\texttt{ArithRing} (exported by \texttt{Arith});
-for \texttt{Z}, do \texttt{Require Import
-ZArithRing} or simply \texttt{Require Import ZArith};
-for \texttt{N}, do \texttt{Require Import NArithRing} or
-\texttt{Require Import NArith}.
-
-\Example
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-\begin{coq_example*}
-Require Import ZArith.
-\end{coq_example*}
-\begin{coq_example}
-Open Scope Z_scope.
-Goal forall a b c:Z,
- (a + b + c)^2 =
- a * a + b^2 + c * c + 2 * a * b + 2 * a * c + 2 * b * c.
-\end{coq_example}
-\begin{coq_example}
-intros; ring.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-\begin{coq_example}
-Goal forall a b:Z, 2*a*b = 30 ->
- (a+b)^2 = a^2 + b^2 + 30.
-\end{coq_example}
-\begin{coq_example}
-intros a b H; ring [H].
-\end{coq_example}
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-
-\begin{Variants}
- \item {\tt ring [\term$_1$ {\ldots} \term$_n$]} decides the equality of two
- terms modulo ring operations and rewriting of the equalities
- defined by \term$_1$ {\ldots} \term$_n$. Each of \term$_1$
- {\ldots} \term$_n$ has to be a proof of some equality $m = p$,
- where $m$ is a monomial (after ``abstraction''),
- $p$ a polynomial and $=$ the corresponding equality of the ring structure.
-
- \item {\tt ring\_simplify [\term$_1$ {\ldots} \term$_n$] $t_1 \ldots t_m$ in
-{\ident}}
- performs the simplification in the hypothesis named {\tt ident}.
-\end{Variants}
-
-\Warning \texttt{ring\_simplify \term$_1$; ring\_simplify \term$_2$} is
-not equivalent to \texttt{ring\_simplify \term$_1$ \term$_2$}. In the
-latter case the variables map is shared between the two terms, and
-common subterm $t$ of \term$_1$ and \term$_2$ will have the same
-associated variable number. So the first alternative should be
-avoided for terms belonging to the same ring theory.
-
-
-\begin{ErrMsgs}
-\item \errindex{not a valid ring equation}
- The conclusion of the goal is not provable in the corresponding ring
- theory.
-\item \errindex{arguments of ring\_simplify do not have all the same type}
- {\tt ring\_simplify} cannot simplify terms of several rings at the
- same time. Invoke the tactic once per ring structure.
-\item \errindex{cannot find a declared ring structure over {\tt term}}
- No ring has been declared for the type of the terms to be
- simplified. Use {\tt Add Ring} first.
-\item \errindex{cannot find a declared ring structure for equality
- {\tt term}}
- Same as above is the case of the {\tt ring} tactic.
-\end{ErrMsgs}
-
-\asection{Adding a ring structure
-\comindex{Add Ring}}
-
-Declaring a new ring consists in proving that a ring signature (a
-carrier set, an equality, and ring operations: {\tt
-Ring\_theory.ring\_theory} and {\tt Ring\_theory.semi\_ring\_theory})
-satisfies the ring axioms. Semi-rings (rings without $+$ inverse) are
-also supported. The equality can be either Leibniz equality, or any
-relation declared as a setoid (see~\ref{setoidtactics}). The definition
-of ring and semi-rings (see module {\tt Ring\_theory}) is:
-\begin{verbatim}
-Record ring_theory : Prop := mk_rt {
- Radd_0_l : forall x, 0 + x == x;
- Radd_sym : forall x y, x + y == y + x;
- Radd_assoc : forall x y z, x + (y + z) == (x + y) + z;
- Rmul_1_l : forall x, 1 * x == x;
- Rmul_sym : forall x y, x * y == y * x;
- Rmul_assoc : forall x y z, x * (y * z) == (x * y) * z;
- Rdistr_l : forall x y z, (x + y) * z == (x * z) + (y * z);
- Rsub_def : forall x y, x - y == x + -y;
- Ropp_def : forall x, x + (- x) == 0
-}.
-
-Record semi_ring_theory : Prop := mk_srt {
- SRadd_0_l : forall n, 0 + n == n;
- SRadd_sym : forall n m, n + m == m + n ;
- SRadd_assoc : forall n m p, n + (m + p) == (n + m) + p;
- SRmul_1_l : forall n, 1*n == n;
- SRmul_0_l : forall n, 0*n == 0;
- SRmul_sym : forall n m, n*m == m*n;
- SRmul_assoc : forall n m p, n*(m*p) == (n*m)*p;
- SRdistr_l : forall n m p, (n + m)*p == n*p + m*p
-}.
-\end{verbatim}
-
-This implementation of {\tt ring} also features a notion of constant
-that can be parameterized. This can be used to improve the handling of
-closed expressions when operations are effective. It consists in
-introducing a type of \emph{coefficients} and an implementation of the
-ring operations, and a morphism from the coefficient type to the ring
-carrier type. The morphism needs not be injective, nor surjective.
-
-As
-an example, one can consider the real numbers. The set of coefficients
-could be the rational numbers, upon which the ring operations can be
-implemented. The fact that there exists a morphism is defined by the
-following properties:
-\begin{verbatim}
-Record ring_morph : Prop := mkmorph {
- morph0 : [cO] == 0;
- morph1 : [cI] == 1;
- morph_add : forall x y, [x +! y] == [x]+[y];
- morph_sub : forall x y, [x -! y] == [x]-[y];
- morph_mul : forall x y, [x *! y] == [x]*[y];
- morph_opp : forall x, [-!x] == -[x];
- morph_eq : forall x y, x?=!y = true -> [x] == [y]
-}.
-
-Record semi_morph : Prop := mkRmorph {
- Smorph0 : [cO] == 0;
- Smorph1 : [cI] == 1;
- Smorph_add : forall x y, [x +! y] == [x]+[y];
- Smorph_mul : forall x y, [x *! y] == [x]*[y];
- Smorph_eq : forall x y, x?=!y = true -> [x] == [y]
-}.
-\end{verbatim}
-where {\tt c0} and {\tt cI} denote the 0 and 1 of the coefficient set,
-{\tt +!}, {\tt *!}, {\tt -!} are the implementations of the ring
-operations, {\tt ==} is the equality of the coefficients, {\tt ?+!} is
-an implementation of this equality, and {\tt [x]} is a notation for
-the image of {\tt x} by the ring morphism.
-
-
-
-Since {\tt Z} is an initial ring (and {\tt N} is an initial
-semi-ring), it can always be considered as a set of
-coefficients. There are basically three kinds of (semi-)rings:
-\begin{description}
-\item[abstract rings] to be used when operations are not
- effective. The set of coefficients is {\tt Z} (or {\tt N} for
- semi-rings).
-\item[computational rings] to be used when operations are
- effective. The set of coefficients is the ring itself. The user only
- has to provide an implementation for the equality.
-\item[customized ring] for other cases. The user has to provide the
- coefficient set and the morphism.
-\end{description}
-
-This implementation of ring can also recognize simple
-power expressions as ring expressions. A power function is specified by
-the following property:
-\begin{verbatim}
-Section POWER.
- Variable Cpow : Set.
- Variable Cp_phi : N -> Cpow.
- Variable rpow : R -> Cpow -> R.
-
- Record power_theory : Prop := mkpow_th {
- rpow_pow_N : forall r n, req (rpow r (Cp_phi n)) (pow_N rI rmul r n)
- }.
-
-End POWER.
-\end{verbatim}
-
-
-The syntax for adding a new ring is {\tt Add Ring $name$ : $ring$
-($mod_1$,\dots,$mod_2$)}. The name is not relevant. It is just used
-for error messages. The term $ring$ is a proof that the ring signature
-satisfies the (semi-)ring axioms. The optional list of modifiers is
-used to tailor the behavior of the tactic. The following list
-describes their syntax and effects:
-\begin{description}
-\item[abstract] declares the ring as abstract. This is the default.
-\item[decidable \term] declares the ring as computational. The expression
- \term{} is
- the correctness proof of an equality test {\tt ?=!} (which should be
- evaluable). Its type should be of
- the form {\tt forall x y, x?=!y = true $\rightarrow$ x == y}.
-\item[morphism \term] declares the ring as a customized one. The expression
- \term{} is
- a proof that there exists a morphism between a set of coefficient
- and the ring carrier (see {\tt Ring\_theory.ring\_morph} and {\tt
- Ring\_theory.semi\_morph}).
-\item[setoid \term$_1$ \term$_2$] forces the use of given setoid. The
- expression \term$_1$ is a proof that the equality is indeed a setoid
- (see {\tt Setoid.Setoid\_Theory}), and \term$_2$ a proof that the
- ring operations are morphisms (see {\tt Ring\_theory.ring\_eq\_ext} and
- {\tt Ring\_theory.sring\_eq\_ext}). This modifier needs not be used if the
- setoid and morphisms have been declared.
-\item[constants [\ltac]] specifies a tactic expression that, given a term,
- returns either an object of the coefficient set that is mapped to
- the expression via the morphism, or returns {\tt
- InitialRing.NotConstant}. The default behavior is to map only 0 and
- 1 to their counterpart in the coefficient set. This is generally not
- desirable for non trivial computational rings.
-\item[preprocess [\ltac]]
- specifies a tactic that is applied as a preliminary step for {\tt
- ring} and {\tt ring\_simplify}. It can be used to transform a goal
- so that it is better recognized. For instance, {\tt S n} can be
- changed to {\tt plus 1 n}.
-\item[postprocess [\ltac]] specifies a tactic that is applied as a final step
- for {\tt ring\_simplify}. For instance, it can be used to undo
- modifications of the preprocessor.
-\item[power\_tac {\term} [\ltac]] allows {\tt ring} and {\tt ring\_simplify} to
- recognize power expressions with a constant positive integer exponent
- (example: $x^2$). The term {\term} is a proof that a given power function
- satisfies the specification of a power function ({\term} has to be a
- proof of {\tt Ring\_theory.power\_theory}) and {\ltac} specifies a
- tactic expression that, given a term, ``abstracts'' it into an
- object of type {\tt N} whose interpretation via {\tt Cp\_phi} (the
- evaluation function of power coefficient) is the original term, or
- returns {\tt InitialRing.NotConstant} if not a constant coefficient
- (i.e. {\ltac} is the inverse function of {\tt Cp\_phi}).
- See files {\tt plugins/setoid\_ring/ZArithRing.v} and
- {\tt plugins/setoid\_ring/RealField.v} for examples.
- By default the tactic does not recognize power expressions as ring
- expressions.
-\item[sign {\term}] allows {\tt ring\_simplify} to use a minus operation
- when outputting its normal form, i.e writing $x - y$ instead of $x + (-y)$.
- The term {\term} is a proof that a given sign function indicates expressions
- that are signed ({\term} has to be a
- proof of {\tt Ring\_theory.get\_sign}). See {\tt plugins/setoid\_ring/InitialRing.v} for examples of sign function.
-\item[div {\term}] allows {\tt ring} and {\tt ring\_simplify} to use monomials
-with coefficient other than 1 in the rewriting. The term {\term} is a proof that a given division function satisfies the specification of an euclidean
- division function ({\term} has to be a
- proof of {\tt Ring\_theory.div\_theory}). For example, this function is
- called when trying to rewrite $7x$ by $2x = z$ to tell that $7 = 3 * 2 + 1$.
- See {\tt plugins/setoid\_ring/InitialRing.v} for examples of div function.
-
-\end{description}
-
-
-\begin{ErrMsgs}
-\item \errindex{bad ring structure}
- The proof of the ring structure provided is not of the expected type.
-\item \errindex{bad lemma for decidability of equality}
- The equality function provided in the case of a computational ring
- has not the expected type.
-\item \errindex{ring {\it operation} should be declared as a morphism}
- A setoid associated to the carrier of the ring structure as been
- found, but the ring operation should be declared as
- morphism. See~\ref{setoidtactics}.
-\end{ErrMsgs}
-
-\asection{How does it work?}
-
-The code of \texttt{ring} is a good example of tactic written using
-\textit{reflection}. What is reflection? Basically, it is writing
-\Coq{} tactics in \Coq, rather than in \ocaml. From the philosophical
-point of view, it is using the ability of the Calculus of
-Constructions to speak and reason about itself. For the \texttt{ring}
-tactic we used \Coq\ as a programming language and also as a proof
-environment to build a tactic and to prove it correctness.
-
-The interested reader is strongly advised to have a look at the file
-\texttt{Ring\_polynom.v}. Here a type for polynomials is defined:
-
-\begin{small}
-\begin{flushleft}
-\begin{verbatim}
-Inductive PExpr : Type :=
- | PEc : C -> PExpr
- | PEX : positive -> PExpr
- | PEadd : PExpr -> PExpr -> PExpr
- | PEsub : PExpr -> PExpr -> PExpr
- | PEmul : PExpr -> PExpr -> PExpr
- | PEopp : PExpr -> PExpr
- | PEpow : PExpr -> N -> PExpr.
-\end{verbatim}
-\end{flushleft}
-\end{small}
-
-Polynomials in normal form are defined as:
-\begin{small}
-\begin{flushleft}
-\begin{verbatim}
-Inductive Pol : Type :=
- | Pc : C -> Pol
- | Pinj : positive -> Pol -> Pol
- | PX : Pol -> positive -> Pol -> Pol.
-\end{verbatim}
-\end{flushleft}
-\end{small}
-where {\tt Pinj n P} denotes $P$ in which $V_i$ is replaced by
-$V_{i+n}$, and {\tt PX P n Q} denotes $P \otimes V_1^{n} \oplus Q'$,
-$Q'$ being $Q$ where $V_i$ is replaced by $V_{i+1}$.
-
-
-Variables maps are represented by list of ring elements, and two
-interpretation functions, one that maps a variables map and a
-polynomial to an element of the concrete ring, and the second one that
-does the same for normal forms:
-\begin{small}
-\begin{flushleft}
-\begin{verbatim}
-Definition PEeval : list R -> PExpr -> R := [...].
-Definition Pphi_dev : list R -> Pol -> R := [...].
-\end{verbatim}
-\end{flushleft}
-\end{small}
-
-A function to normalize polynomials is defined, and the big theorem is
-its correctness w.r.t interpretation, that is:
-
-\begin{small}
-\begin{flushleft}
-\begin{verbatim}
-Definition norm : PExpr -> Pol := [...].
-Lemma Pphi_dev_ok :
- forall l pe npe, norm pe = npe -> PEeval l pe == Pphi_dev l npe.
-\end{verbatim}
-\end{flushleft}
-\end{small}
-
-So now, what is the scheme for a normalization proof? Let \texttt{p}
-be the polynomial expression that the user wants to normalize. First a
-little piece of ML code guesses the type of \texttt{p}, the ring
-theory \texttt{T} to use, an abstract polynomial \texttt{ap} and a
-variables map \texttt{v} such that \texttt{p} is
-$\beta\delta\iota$-equivalent to \verb|(PEeval v ap)|. Then we
-replace it by \verb|(Pphi_dev v (norm ap))|, using the
-main correctness theorem and we reduce it to a concrete expression
-\texttt{p'}, which is the concrete normal form of
-\texttt{p}. This is summarized in this diagram:
-\begin{center}
-\begin{tabular}{rcl}
-\texttt{p} & $\rightarrow_{\beta\delta\iota}$
- & \texttt{(PEeval v ap)} \\
- & & $=_{\mathrm{(by\ the\ main\ correctness\ theorem)}}$ \\
-\texttt{p'}
- & $\leftarrow_{\beta\delta\iota}$
- & \texttt{(Pphi\_dev v (norm ap))}
-\end{tabular}
-\end{center}
-The user do not see the right part of the diagram.
-From outside, the tactic behaves like a
-$\beta\delta\iota$ simplification extended with AC rewriting rules.
-Basically, the proof is only the application of the main
-correctness theorem to well-chosen arguments.
-
-
-\asection{Dealing with fields
-\tacindex{field}
-\tacindex{field\_simplify}
-\tacindex{field\_simplify\_eq}}
-
-
-The {\tt field} tactic is an extension of the {\tt ring} to deal with
-rational expression. Given a rational expression $F=0$. It first reduces the
-expression $F$ to a common denominator $N/D= 0$ where $N$ and $D$ are two ring
-expressions.
-For example, if we take $F = (1 - 1/x) x - x + 1$, this gives
-$ N= (x -1) x - x^2 + x$ and $D= x$. It then calls {\tt ring}
-to solve $N=0$. Note that {\tt field} also generates non-zero conditions
-for all the denominators it encounters in the reduction.
-In our example, it generates the condition $x \neq 0$. These
-conditions appear as one subgoal which is a conjunction if there are
-several denominators.
-Non-zero conditions are {\it always} polynomial expressions. For example
-when reducing the expression $1/(1 + 1/x)$, two side conditions are
-generated: $x\neq 0$ and $x + 1 \neq 0$. Factorized expressions are
-broken since a field is an integral domain, and when the equality test
-on coefficients is complete w.r.t. the equality of the target field,
-constants can be proven different from zero automatically.
-
-The tactic must be loaded by \texttt{Require Import Field}. New field
-structures can be declared to the system with the \texttt{Add Field}
-command (see below). The field of real numbers is defined in module
-\texttt{RealField} (in texttt{plugins/setoid\_ring}). It is exported
-by module \texttt{Rbase}, so that requiring \texttt{Rbase} or
-\texttt{Reals} is enough to use the field tactics on real
-numbers. Rational numbers in canonical form are also declared as a
-field in module \texttt{Qcanon}.
-
-
-\Example
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-\begin{coq_example*}
-Require Import Reals.
-\end{coq_example*}
-\begin{coq_example}
-Open Scope R_scope.
-Goal forall x, x <> 0 ->
- (1 - 1/x) * x - x + 1 = 0.
-\end{coq_example}
-\begin{coq_example}
-intros; field; auto.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-\begin{coq_example}
-Goal forall x y, y <> 0 -> y = x -> x/y = 1.
-\end{coq_example}
-\begin{coq_example}
-intros x y H H1; field [H1]; auto.
-\end{coq_example}
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-
-\begin{Variants}
- \item {\tt field [\term$_1$ {\ldots} \term$_n$]} decides the equality of two
- terms modulo field operations and rewriting of the equalities
- defined by \term$_1$ {\ldots} \term$_n$. Each of \term$_1$
- {\ldots} \term$_n$ has to be a proof of some equality $m = p$,
- where $m$ is a monomial (after ``abstraction''),
- $p$ a polynomial and $=$ the corresponding equality of the field structure.
- Beware that rewriting works with the equality $m=p$ only if $p$ is a
- polynomial since rewriting is handled by the underlying {\tt ring}
- tactic.
- \item {\tt field\_simplify}
- performs the simplification in the conclusion of the goal, $F_1 = F_2$
- becomes $N_1/D_1 = N_2/D_2$. A normalization step (the same as the
- one for rings) is then applied to $N_1$, $D_1$, $N_2$ and
- $D_2$. This way, polynomials remain in factorized form during the
- fraction simplifications. This yields smaller expressions when
- reducing to the same denominator since common factors can be
- canceled.
-
- \item {\tt field\_simplify [\term$_1$ {\ldots} \term$_n$]}
- performs the simplification in the conclusion of the goal using
- the equalities
- defined by \term$_1$ {\ldots} \term$_n$.
-
- \item {\tt field\_simplify [\term$_1$ {\ldots} \term$_n$] $t_1$ \ldots
-$t_m$}
- performs the simplification in the terms $t_1$ \ldots $t_m$
- of the conclusion of the goal using
- the equalities
- defined by \term$_1$ {\ldots} \term$_n$.
-
- \item {\tt field\_simplify in $H$}
- performs the simplification in the assumption $H$.
-
- \item {\tt field\_simplify [\term$_1$ {\ldots} \term$_n$] in $H$}
- performs the simplification in the assumption $H$ using
- the equalities
- defined by \term$_1$ {\ldots} \term$_n$.
-
- \item {\tt field\_simplify [\term$_1$ {\ldots} \term$_n$] $t_1$ \ldots
-$t_m$ in $H$}
- performs the simplification in the terms $t_1$ \ldots $t_n$
- of the assumption $H$ using
- the equalities
- defined by \term$_1$ {\ldots} \term$_m$.
-
- \item {\tt field\_simplify\_eq}
- performs the simplification in the conclusion of the goal removing
- the denominator. $F_1 = F_2$
- becomes $N_1 D_2 = N_2 D_1$.
-
- \item {\tt field\_simplify\_eq [\term$_1$ {\ldots} \term$_n$]}
- performs the simplification in the conclusion of the goal using
- the equalities
- defined by \term$_1$ {\ldots} \term$_n$.
-
- \item {\tt field\_simplify\_eq} in $H$
- performs the simplification in the assumption $H$.
-
- \item {\tt field\_simplify\_eq [\term$_1$ {\ldots} \term$_n$] in $H$}
- performs the simplification in the assumption $H$ using
- the equalities
- defined by \term$_1$ {\ldots} \term$_n$.
-\end{Variants}
-
-\asection{Adding a new field structure
-\comindex{Add Field}}
-
-Declaring a new field consists in proving that a field signature (a
-carrier set, an equality, and field operations: {\tt
-Field\_theory.field\_theory} and {\tt Field\_theory.semi\_field\_theory})
-satisfies the field axioms. Semi-fields (fields without $+$ inverse) are
-also supported. The equality can be either Leibniz equality, or any
-relation declared as a setoid (see~\ref{setoidtactics}). The definition
-of fields and semi-fields is:
-\begin{verbatim}
-Record field_theory : Prop := mk_field {
- F_R : ring_theory rO rI radd rmul rsub ropp req;
- F_1_neq_0 : ~ 1 == 0;
- Fdiv_def : forall p q, p / q == p * / q;
- Finv_l : forall p, ~ p == 0 -> / p * p == 1
-}.
-
-Record semi_field_theory : Prop := mk_sfield {
- SF_SR : semi_ring_theory rO rI radd rmul req;
- SF_1_neq_0 : ~ 1 == 0;
- SFdiv_def : forall p q, p / q == p * / q;
- SFinv_l : forall p, ~ p == 0 -> / p * p == 1
-}.
-\end{verbatim}
-
-The result of the normalization process is a fraction represented by
-the following type:
-\begin{verbatim}
-Record linear : Type := mk_linear {
- num : PExpr C;
- denum : PExpr C;
- condition : list (PExpr C)
-}.
-\end{verbatim}
-where {\tt num} and {\tt denum} are the numerator and denominator;
-{\tt condition} is a list of expressions that have appeared as a
-denominator during the normalization process. These expressions must
-be proven different from zero for the correctness of the algorithm.
-
-The syntax for adding a new field is {\tt Add Field $name$ : $field$
-($mod_1$,\dots,$mod_2$)}. The name is not relevant. It is just used
-for error messages. $field$ is a proof that the field signature
-satisfies the (semi-)field axioms. The optional list of modifiers is
-used to tailor the behavior of the tactic. Since field tactics are
-built upon ring tactics, all modifiers of the {\tt Add Ring}
-apply. There is only one specific modifier:
-\begin{description}
-\item[completeness \term] allows the field tactic to prove
- automatically that the image of non-zero coefficients are mapped to
- non-zero elements of the field. \term is a proof of {\tt forall x y,
- [x] == [y] -> x?=!y = true}, which is the completeness of equality
- on coefficients w.r.t. the field equality.
-\end{description}
-
-\asection{History of \texttt{ring}}
-
-First Samuel Boutin designed the tactic \texttt{ACDSimpl}.
-This tactic did lot of rewriting. But the proofs
-terms generated by rewriting were too big for \Coq's type-checker.
-Let us see why:
-
-\begin{coq_eval}
-Require Import ZArith.
-Open Scope Z_scope.
-\end{coq_eval}
-\begin{coq_example}
-Goal forall x y z:Z, x + 3 + y + y * z = x + 3 + y + z * y.
-\end{coq_example}
-\begin{coq_example*}
-intros; rewrite (Z.mul_comm y z); reflexivity.
-Save toto.
-\end{coq_example*}
-\begin{coq_example}
-Print toto.
-\end{coq_example}
-
-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 \texttt{ACDSimpl} was too slow, Samuel Boutin rewrote it
-using reflection (see his article in TACS'97 \cite{Bou97}). Later, the
-stuff was rewritten by Patrick
-Loiseleur: the new tactic does not any more require \texttt{ACDSimpl}
-to compile and it makes use of $\beta\delta\iota$-reduction
-not only to replace the rewriting steps, but also to achieve the
-interleaving of computation and
-reasoning (see \ref{DiscussReflection}). He also wrote a
-few ML code for the \texttt{Add Ring} command, that allow to register
-new rings dynamically.
-
-Proofs terms generated by \texttt{ring} are quite small, they are
-linear in the number of $\oplus$ and $\otimes$ operations in the
-normalized terms. Type-checking those terms requires some time because it
-makes a large use of the conversion rule, but
-memory requirements are much smaller.
-
-\asection{Discussion}
-\label{DiscussReflection}
-
-Efficiency is not the only motivation to use reflection
-here. \texttt{ring} also deals with constants, it rewrites for example the
-expression $34 + 2*x -x + 12$ to the expected result $x + 46$. For the
-tactic \texttt{ACDSimpl}, the only constants were 0 and 1. So the
-expression $34 + 2*(x - 1) + 12$ is interpreted as
-$V_0 \oplus V_1 \otimes (V_2 \ominus 1) \oplus V_3$,
-with the variables mapping
-$\{V_0 \mt 34; V_1 \mt 2; V_2 \mt x; V_3 \mt 12 \}$. Then it is
-rewritten to $34 - x + 2*x + 12$, very far from the expected
-result. Here rewriting is not sufficient: you have to do some kind of
-reduction (some kind of \textit{computation}) to achieve the
-normalization.
-
-The tactic \texttt{ring} is not only faster than a classical one:
-using reflection, we get for free integration of computation and
-reasoning that would be very complex to implement in the classic fashion.
-
-Is it the ultimate way to write tactics? The answer is: yes and
-no. The \texttt{ring} tactic uses intensively the conversion rule of
-\CIC, that is replaces proof by computation the most as it is
-possible. It can be useful in all situations where a classical tactic
-generates huge proof terms. Symbolic Processing and Tautologies are in
-that case. But there are also tactics like \texttt{auto} or
-\texttt{linear} that do many complex computations, using side-effects
-and backtracking, and generate a small proof term. Clearly, it would
-be significantly less efficient to replace them by tactics using
-reflection.
-
-Another idea suggested by Benjamin Werner: reflection could be used to
-couple an external tool (a rewriting program or a model checker) with
-\Coq. We define (in \Coq) a type of terms, a type of \emph{traces},
-and prove a correction theorem that states that \emph{replaying
-traces} is safe w.r.t some interpretation. Then we let the external
-tool do every computation (using side-effects, backtracking,
-exception, or others features that are not available in pure lambda
-calculus) to produce the trace: now we can check in Coq{} that the
-trace has the expected semantic by applying the correction lemma.
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
diff --git a/doc/refman/Program.tex b/doc/refman/Program.tex
deleted file mode 100644
index 1e204dc83..000000000
--- a/doc/refman/Program.tex
+++ /dev/null
@@ -1,329 +0,0 @@
-\achapter{\Program{}}
-%HEVEA\cutname{program.html}
-\label{Program}
-\aauthor{Matthieu Sozeau}
-\index{Program}
-
-We present here the \Program\ tactic commands, used to build certified
-\Coq\ programs, elaborating them from their algorithmic skeleton and a
-rich specification \cite{Sozeau06}. It can be thought of as a dual of extraction
-(see Chapter~\ref{Extraction}). The goal of \Program~is to program as in a regular
-functional programming language whilst using as rich a specification as
-desired and proving that the code meets the specification using the whole \Coq{} proof
-apparatus. This is done using a technique originating from the
-``Predicate subtyping'' mechanism of \PVS \cite{Rushby98}, which generates type-checking
-conditions while typing a term constrained to a particular type.
-Here we insert existential variables in the term, which must be filled
-with proofs to get a complete \Coq\ term. \Program\ replaces the
-\Program\ tactic by Catherine Parent \cite{Parent95b} which had a similar goal but is no longer
-maintained.
-
-The languages available as input are currently restricted to \Coq's term
-language, but may be extended to \ocaml{}, \textsc{Haskell} and others
-in the future. We use the same syntax as \Coq\ and permit to use implicit
-arguments and the existing coercion mechanism.
-Input terms and types are typed in an extended system (\Russell) and
-interpreted into \Coq\ terms. The interpretation process may produce
-some proof obligations which need to be resolved to create the final term.
-
-\asection{Elaborating programs}
-The main difference from \Coq\ is that an object in a type $T : \Set$
-can be considered as an object of type $\{ x : T~|~P\}$ for any
-wellformed $P : \Prop$.
-If we go from $T$ to the subset of $T$ verifying property $P$, we must
-prove that the object under consideration verifies it. \Russell\ will
-generate an obligation for every such coercion. In the other direction,
-\Russell\ will automatically insert a projection.
-
-Another distinction is the treatment of pattern-matching. Apart from the
-following differences, it is equivalent to the standard {\tt match}
-operation (see Section~\ref{Caseexpr}).
-\begin{itemize}
-\item Generation of equalities. A {\tt match} expression is always
- generalized by the corresponding equality. As an example,
- the expression:
-
-\begin{verbatim}
- match x with
- | 0 => t
- | S n => u
- end.
-\end{verbatim}
-will be first rewritten to:
-\begin{verbatim}
- (match x as y return (x = y -> _) with
- | 0 => fun H : x = 0 -> t
- | S n => fun H : x = S n -> u
- end) (eq_refl n).
-\end{verbatim}
-
- This permits to get the proper equalities in the context of proof
- obligations inside clauses, without which reasoning is very limited.
-
-\item Generation of inequalities. If a pattern intersects with a
- previous one, an inequality is added in the context of the second
- branch. See for example the definition of {\tt div2} below, where the second
- branch is typed in a context where $\forall p, \_ <> S (S p)$.
-
-\item Coercion. If the object being matched is coercible to an inductive
- type, the corresponding coercion will be automatically inserted. This also
- works with the previous mechanism.
-
-\end{itemize}
-
-There are options to control the generation of equalities
-and coercions.
-
-\begin{itemize}
-\item {\tt Unset Program Cases}\optindex{Program Cases} This deactivates
- the special treatment of pattern-matching generating equalities and
- inequalities when using \Program\ (it is on by default). All
- pattern-matchings and let-patterns are handled using the standard
- algorithm of Coq (see Section~\ref{Mult-match-full}) when this option is
- deactivated.
-\item {\tt Unset Program Generalized Coercion}\optindex{Program
- Generalized Coercion} This deactivates the coercion of general
- inductive types when using \Program\ (the option is on by default).
- Coercion of subset types and pairs is still active in this case.
-\end{itemize}
-
-\subsection{Syntactic control over equalities}
-\label{ProgramSyntax}
-To give more control over the generation of equalities, the typechecker will
-fall back directly to \Coq's usual typing of dependent pattern-matching
-if a {\tt return} or {\tt in} clause is specified. Likewise,
-the {\tt if} construct is not treated specially by \Program{} so boolean
-tests in the code are not automatically reflected in the obligations.
-One can use the {\tt dec} combinator to get the correct hypotheses as in:
-
-\begin{coq_eval}
-Require Import Program Arith.
-\end{coq_eval}
-\begin{coq_example}
-Program Definition id (n : nat) : { x : nat | x = n } :=
- if dec (leb n 0) then 0
- else S (pred n).
-\end{coq_example}
-
-The let tupling construct {\tt let (x1, ..., xn) := t in b}
-does not produce an equality, contrary to the let pattern construct
-{\tt let '(x1, ..., xn) := t in b}.
-Also, {\tt {\term}:>} explicitly asks the system to coerce {\tt \term} to its
-support type. It can be useful in notations, for example:
-\begin{coq_example}
-Notation " x `= y " := (@eq _ (x :>) (y :>)) (only parsing).
-\end{coq_example}
-
-This notation denotes equality on subset types using equality on their
-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~\ref{Basic-definitions}) and Fixpoint (see Section~\ref{Fixpoint}) in that
-they define constants. However, they may require the user to prove some
-goals to construct the final definitions.
-
-\subsection{\tt Program Definition {\ident} := {\term}.
- \comindex{Program Definition}\label{ProgramDefinition}}
-
-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.
-
-\begin{ErrMsgs}
-\item \errindex{{\ident} already exists}
-\end{ErrMsgs}
-
-\begin{Variants}
-\item {\tt Program Definition {\ident} {\tt :}{\term$_1$} :=
- {\term$_2$}.}\\
- It interprets the type {\term$_1$}, potentially generating proof
- obligations to be resolved. Once done with them, we have a \Coq\ type
- {\term$_1'$}. It then checks that the type of the interpretation of
- {\term$_2$} is coercible to {\term$_1'$}, and registers {\ident} as
- being of type {\term$_1'$} once the set of obligations generated
- during the interpretation of {\term$_2$} and the aforementioned
- coercion derivation are solved.
-\item {\tt Program Definition {\ident} {\binder$_1$}\ldots{\binder$_n$}
- {\tt :}\term$_1$ {\tt :=} {\term$_2$}.}\\
- This is equivalent to \\
- {\tt Program Definition\,{\ident}\,{\tt :\,forall} %
- {\binder$_1$}\ldots{\binder$_n$}{\tt ,}\,\term$_1$\,{\tt :=}} \\
- \qquad {\tt fun}\,{\binder$_1$}\ldots{\binder$_n$}\,{\tt =>}\,{\term$_2$}\,%
- {\tt .}
-\end{Variants}
-
-\begin{ErrMsgs}
-\item \errindex{In environment {\dots} the term: {\term$_2$} does not have type
- {\term$_1$}}.\\
- \texttt{Actually, it has type {\term$_3$}}.
-\end{ErrMsgs}
-
-\SeeAlso Sections \ref{Opaque}, \ref{Transparent}, \ref{unfold}
-
-\subsection{\tt Program Fixpoint {\ident} {\params} {\tt \{order\}} : type := \term
- \comindex{Program Fixpoint}
- \label{ProgramFixpoint}}
-
-The structural fixpoint operator behaves just like the one of Coq
-(see Section~\ref{Fixpoint}), except it may also generate obligations.
-It works with mutually recursive definitions too.
-
-\begin{coq_eval}
-Admit Obligations.
-\end{coq_eval}
-\begin{coq_example}
-Program Fixpoint div2 (n : nat) : { x : nat | n = 2 * x \/ n = 2 * x + 1 } :=
- match n with
- | S (S p) => S (div2 p)
- | _ => O
- end.
-\end{coq_example}
-
-Here we have one obligation for each branch (branches for \verb:0: and \verb:(S 0): are
-automatically generated by the pattern-matching compilation algorithm).
-\begin{coq_example}
- Obligation 1.
-\end{coq_example}
-
-One can use a well-founded order or a measure as termination orders using the syntax:
-\begin{coq_eval}
-Reset Initial.
-Require Import Arith.
-Require Import Program.
-\end{coq_eval}
-\begin{coq_example*}
-Program Fixpoint div2 (n : nat) {measure n} :
- { x : nat | n = 2 * x \/ n = 2 * x + 1 } :=
- match n with
- | S (S p) => S (div2 p)
- | _ => O
- end.
-\end{coq_example*}
-
-The order annotation can be either:
-\begin{itemize}
-\item {\tt measure f (R)?} where {\tt f} is a value of type {\tt X}
- computed on any subset of the arguments and the optional
- (parenthesised) term {\tt (R)} is a relation
- on {\tt X}. By default {\tt X} defaults to {\tt nat} and {\tt R} to
- {\tt lt}.
-\item {\tt wf R x} which is equivalent to {\tt measure x (R)}.
-\end{itemize}
-
-\paragraph{Caution}
-When defining structurally recursive functions, the
-generated obligations should have the prototype of the currently defined functional
-in their context. In this case, the obligations should be transparent
-(e.g. defined using {\tt Defined}) so that the guardedness condition on
-recursive calls can be checked by the
-kernel's type-checker. There is an optimization in the generation of
-obligations which gets rid of the hypothesis corresponding to the
-functional when it is not necessary, so that the obligation can be
-declared opaque (e.g. using {\tt Qed}). However, as soon as it appears in the
-context, the proof of the obligation is \emph{required} to be declared transparent.
-
-No such problems arise when using measures or well-founded recursion.
-
-\subsection{\tt Program Lemma {\ident} : type.
- \comindex{Program Lemma}
- \label{ProgramLemma}}
-
-The \Russell\ language can also be used to type statements of logical
-properties. It will generate obligations, try to solve them
-automatically and fail if some unsolved obligations remain.
-In this case, one can first define the lemma's
-statement using {\tt Program Definition} and use it as the goal afterwards.
-Otherwise the proof will be started with the elaborated version as a goal.
-The {\tt Program} prefix can similarly be used as a prefix for {\tt Variable}, {\tt
- Hypothesis}, {\tt Axiom} etc...
-
-\section{Solving obligations}
-The following commands are available to manipulate obligations. The
-optional identifier is used when multiple functions have unsolved
-obligations (e.g. when defining mutually recursive blocks). The optional
-tactic is replaced by the default one if not specified.
-
-\begin{itemize}
-\item {\tt [Local|Global] Obligation Tactic := \tacexpr}\comindex{Obligation Tactic}
- Sets the default obligation
- solving tactic applied to all obligations automatically, whether to
- solve them or when starting to prove one, e.g. using {\tt Next}.
- Local makes the setting last only for the current module. Inside
- sections, local is the default.
-\item {\tt Show Obligation Tactic}\comindex{Show Obligation Tactic}
- Displays the current default tactic.
-\item {\tt Obligations [of \ident]}\comindex{Obligations} Displays all remaining
- obligations.
-\item {\tt Obligation num [of \ident]}\comindex{Obligation} Start the proof of
- obligation {\tt num}.
-\item {\tt Next Obligation [of \ident]}\comindex{Next Obligation} Start the proof of the next
- unsolved obligation.
-\item {\tt Solve Obligations [of \ident] [with
- \tacexpr]}\comindex{Solve Obligations}
- Tries to solve
- each obligation of \ident using the given tactic or the default one.
-\item {\tt Solve All Obligations [with \tacexpr]} Tries to solve
- each obligation of every program using the given tactic or the default
- one (useful for mutually recursive definitions).
-\item {\tt Admit Obligations [of \ident]}\comindex{Admit Obligations}
- Admits all obligations (does not work with structurally recursive programs).
-\item {\tt Preterm [of \ident]}\comindex{Preterm}
- Shows the term that will be fed to
- the kernel once the obligations are solved. Useful for debugging.
-\item {\tt Set Transparent Obligations}\optindex{Transparent Obligations}
- Control whether all obligations should be declared as transparent (the
- default), or if the system should infer which obligations can be declared opaque.
-\item {\tt Set Hide Obligations}\optindex{Hide Obligations}
- Control whether obligations appearing in the term should be hidden
- as implicit arguments of the special constant
- \texttt{Program.Tactics.obligation}.
-\item {\tt Set Shrink Obligations}\optindex{Shrink Obligations}
-\emph{Deprecated since 8.7}
- This option (on by default) controls whether obligations should have their
- context minimized to the set of variables used in the proof of the
- obligation, to avoid unnecessary dependencies.
-\end{itemize}
-
-The module {\tt Coq.Program.Tactics} defines the default tactic for solving
-obligations called {\tt program\_simpl}. Importing
-{\tt Coq.Program.Program} also adds some useful notations, as documented in the file itself.
-
-\section{Frequently Asked Questions
- \label{ProgramFAQ}}
-
-\begin{itemize}
-\item {Ill-formed recursive definitions}
- 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:
-
- \verb$Program Fixpoint f (x : A | P) := match x with A b => f b end.$
-
- Supposing $b : A$, the argument at the recursive call to f is not a
- direct subterm of x as b is wrapped inside an {\tt exist} constructor to build
- an object of type \verb${x : A | P}$. Hence the definition is rejected
- by the guardedness condition checker. However one can use
- wellfounded recursion on subset objects like this:
-
-\begin{verbatim}
-Program Fixpoint f (x : A | P) { measure (size x) } :=
- match x with A b => f b end.
-\end{verbatim}
-
- One will then just have to prove that the measure decreases at each recursive
- call. There are three drawbacks though:
- \begin{enumerate}
- \item A measure function has to be defined;
- \item The reduction is a little more involved, although it works well
- using lazy evaluation;
- \item Mutual recursion on the underlying inductive type isn't possible
- anymore, but nested mutual recursion is always possible.
- \end{enumerate}
-\end{itemize}
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% compile-command: "BIBINPUTS=\".\" make QUICK=1 -C ../.. doc/refman/Reference-Manual.pdf"
-%%% 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/RefMan-oth.tex b/doc/refman/RefMan-oth.tex
deleted file mode 100644
index bef31d3fa..000000000
--- a/doc/refman/RefMan-oth.tex
+++ /dev/null
@@ -1,1224 +0,0 @@
-\chapter[Vernacular commands]{Vernacular commands\label{Vernacular-commands}
-\label{Other-commands}}
-%HEVEA\cutname{vernacular.html}
-
-\section{Displaying}
-
-\subsection[\tt Print {\qualid}.]{\tt Print {\qualid}.\comindex{Print}}
-This command displays on the screen information about the declared or
-defined object referred by {\qualid}.
-
-\begin{ErrMsgs}
-\item {\qualid} \errindex{not a defined object}
-\item \errindex{Universe instance should have length} $n$.
-\item \errindex{This object does not support universe names.}
-\end{ErrMsgs}
-
-\begin{Variants}
-\item {\tt Print Term {\qualid}.}
-\comindex{Print Term}\\
-This is a synonym to {\tt Print {\qualid}} when {\qualid} denotes a
-global constant.
-
-\item {\tt About {\qualid}.}
-\label{About}
-\comindex{About}\\
-This displays various information about the object denoted by {\qualid}:
-its kind (module, constant, assumption, inductive,
-constructor, abbreviation, \ldots), long name, type, implicit
-arguments and argument scopes. It does not print the body of
-definitions or proofs.
-
-\item {\tt Print {\qualid}@\{names\}.}\\
-This locally renames the polymorphic universes of {\qualid}.
-An underscore means the raw universe is printed.
-This form can be used with {\tt Print Term} and {\tt About}.
-
-%\item {\tt Print Proof {\qualid}.}\comindex{Print Proof}\\
-%In case \qualid\ denotes an opaque theorem defined in a section,
-%it is stored on a special unprintable form and displayed as
-%{\tt <recipe>}. {\tt Print Proof} forces the printable form of \qualid\
-%to be computed and displays it.
-\end{Variants}
-
-\subsection[\tt Print All.]{\tt Print All.\comindex{Print All}}
-This command displays information about the current state of the
-environment, including sections and modules.
-
-\begin{Variants}
-\item {\tt Inspect \num.}\comindex{Inspect}\\
-This command displays the {\num} last objects of the current
-environment, including sections and modules.
-\item {\tt Print Section {\ident}.}\comindex{Print Section}\\
-should correspond to a currently open section, this command
-displays the objects defined since the beginning of this section.
-% Discontinued
-%% \item {\tt Print.}\comindex{Print}\\
-%% This command displays the axioms and variables declarations in the
-%% environment as well as the constants defined since the last variable
-%% was introduced.
-\end{Variants}
-
-\section{Flags, Options and Tables}
-
-{\Coq} configurability is based on flags (e.g. {\tt Set Printing All} in
-Section~\ref{SetPrintingAll}), options (e.g. {\tt Set Printing Width
- {\integer}} in Section~\ref{SetPrintingWidth}), or tables (e.g. {\tt
- Add Printing Record {\ident}}, in Section~\ref{AddPrintingLet}). 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.
-
-\subsection[\tt Set {\rm\sl flag}.]{\tt Set {\rm\sl flag}.\comindex{Set}}
-This command switches {\rm\sl flag} on. The original state of
-{\rm\sl flag} is restored when the current module ends.
-
-\begin{Variants}
-\item {\tt Local Set {\rm\sl flag}.}\\
-This command switches {\rm\sl flag} on. The original state of
-{\rm\sl flag} is restored when the current \emph{section} ends.
-\item {\tt Global Set {\rm\sl flag}.}\\
-This command switches {\rm\sl flag} on. The original state of
-{\rm\sl flag} is \emph{not} restored at the end of the module. Additionally,
-if set in a file, {\rm\sl flag} is switched on when the file is
-{\tt Require}-d.
-\end{Variants}
-
-\subsection[\tt Unset {\rm\sl flag}.]{\tt Unset {\rm\sl flag}.\comindex{Unset}}
-This command switches {\rm\sl flag} off. The original state of {\rm\sl flag}
-is restored when the current module ends.
-
-\begin{Variants}
-\item {\tt Local Unset {\rm\sl flag}.\comindex{Local Unset}}\\
-This command switches {\rm\sl flag} off. The original state of {\rm\sl flag}
-is restored when the current \emph{section} ends.
-\item {\tt Global Unset {\rm\sl flag}.\comindex{Global Unset}}\\
-This command switches {\rm\sl flag} off. The original state of
-{\rm\sl flag} is \emph{not} restored at the end of the module. Additionally,
-if set in a file, {\rm\sl flag} is switched off when the file is
-{\tt Require}-d.
-\end{Variants}
-
-\subsection[\tt Test {\rm\sl flag}.]{\tt Test {\rm\sl flag}.\comindex{Test}}
-This command prints whether {\rm\sl flag} is on or off.
-
-\subsection[\tt Set {\rm\sl option} {\rm\sl value}.]{\tt Set {\rm\sl option} {\rm\sl value}.\comindex{Set}}
-This command sets {\rm\sl option} to {\rm\sl value}. The original value of
-{\rm\sl option} is restored when the current module ends.
-
-\begin{Variants}
-\item {\tt Local Set {\rm\sl option} {\rm\sl value}.\comindex{Local Set}}
-This command sets {\rm\sl option} to {\rm\sl value}. The original value of
-{\rm\sl option} is restored at the end of the module.
-\item {\tt Global Set {\rm\sl option} {\rm\sl value}.\comindex{Global Set}}
-This command sets {\rm\sl option} to {\rm\sl value}. The original value of
-{\rm\sl option} is \emph{not} restored at the end of the module. Additionally,
-if set in a file, {\rm\sl option} is set to {\rm\sl value} when the file is
-{\tt Require}-d.
-\end{Variants}
-
-\subsection[\tt Unset {\rm\sl option}.]{\tt Unset {\rm\sl option}.\comindex{Unset}}
-This command resets {\rm\sl option} to its default value.
-
-\begin{Variants}
-\item {\tt Local Unset {\rm\sl option}.\comindex{Local Unset}}\\
-This command resets {\rm\sl option} to its default value. The original state of {\rm\sl option}
-is restored when the current \emph{section} ends.
-\item {\tt Global Unset {\rm\sl option}.\comindex{Global Unset}}\\
-This command resets {\rm\sl option} to its default value. The original state of
-{\rm\sl option} is \emph{not} restored at the end of the module. Additionally,
-if unset in a file, {\rm\sl option} is reset to its default value when the file is
-{\tt Require}-d.
-\end{Variants}
-
-\subsection[\tt Test {\rm\sl option}.]{\tt Test {\rm\sl option}.\comindex{Test}}
-This command prints the current value of {\rm\sl option}.
-
-\subsection{Tables}
-The general commands for tables are {\tt Add {\rm\sf table} {\rm\sl
- value}}, {\tt Remove {\rm\sf table} {\rm\sl value}}, {\tt Test
- {\rm\sf table}}, {\tt Test {\rm\sf table} for {\rm\sl value}} and
- {\tt Print Table {\rm\sf table}}.
-
-\subsection[\tt Print Options.]{\tt Print Options.\comindex{Print Options}}
-This command lists all available flags, options and tables.
-
-\begin{Variants}
-\item {\tt Print Tables}.\comindex{Print Tables}\\
-This is a synonymous of {\tt Print Options.}
-\end{Variants}
-
-\section{Requests to the environment}
-
-\subsection[\tt Check {\term}.]{\tt Check {\term}.\label{Check}
-\comindex{Check}}
-This command displays the type of {\term}. When called in proof mode,
-the term is checked in the local context of the current subgoal.
-
-\begin{Variants}
-\item {\tt selector: Check {\term}}.\\
-specifies on which subgoal to perform typing (see
- Section~\ref{tactic-syntax}).
-\end{Variants}
-
-
-\subsection[\tt Eval {\rm\sl convtactic} in {\term}.]{\tt Eval {\rm\sl convtactic} in {\term}.\comindex{Eval}}
-
-This command performs the specified reduction on {\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).
-
-\SeeAlso Section~\ref{Conversion-tactics}.
-
-\subsection[\tt Compute {\term}.]{\tt Compute {\term}.\comindex{Compute}}
-
-This command performs a call-by-value evaluation of {\term} by using
-the bytecode-based virtual machine. It is a shortcut for
-{\tt Eval vm\_compute in {\term}}.
-
-\SeeAlso Section~\ref{Conversion-tactics}.
-
-\subsection[\tt Extraction \term.]{\tt Extraction \term.\label{ExtractionTerm}
-\comindex{Extraction}}
-This command displays the extracted term from
-{\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{Sorts}). The extracted term is
-displayed in {\ocaml} syntax, where global identifiers are still
-displayed as in \Coq\ terms.
-
-\begin{Variants}
-\item \texttt{Recursive Extraction} {\qualid$_1$} \ldots{} {\qualid$_n$}{\tt .}\\
- Recursively extracts all the material needed for the extraction of
- global {\qualid$_1$}, \ldots, {\qualid$_n$}.
-\end{Variants}
-
-\SeeAlso Chapter~\ref{Extraction}.
-
-\subsection[\tt Print Assumptions {\qualid}.]{\tt Print Assumptions {\qualid}.\comindex{Print Assumptions}}
-\label{PrintAssumptions}
-
-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.
-
-\begin{Variants}
-\item \texttt{\tt Print Opaque Dependencies {\qualid}.
- \comindex{Print Opaque Dependencies}}\\
- Displays the set of opaque constants {\qualid} relies on in addition
- to the assumptions.
-\item \texttt{\tt Print Transparent Dependencies {\qualid}.
- \comindex{Print Transparent Dependencies}}\\
- Displays the set of transparent constants {\qualid} relies on in addition
- to the assumptions.
-\item \texttt{\tt Print All Dependencies {\qualid}.
- \comindex{Print All Dependencies}}\\
- Displays all assumptions and constants {\qualid} relies on.
-\end{Variants}
-
-\subsection[\tt Search {\qualid}.]{\tt Search {\qualid}.\comindex{Search}}
-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 \qualid. This command is useful to remind the user
-of the name of library lemmas.
-
-\begin{ErrMsgs}
-\item \errindex{The reference \qualid\ was not found in the current
-environment}\\
- There is no constant in the environment named \qualid.
-\end{ErrMsgs}
-
-\newcommand{\termpatternorstr}{{\termpattern}\textrm{\textsl{-}}{\str}}
-
-\begin{Variants}
-\item {\tt Search {\str}.}
-
-If {\str} is a valid identifier, this command displays the name and type
-of all objects (theorems, axioms, etc) of the current context whose
-name contains {\str}. If {\str} is a notation's string denoting some
-reference {\qualid} (referred to by its main symbol as in \verb="+"=
-or by its notation's string as in \verb="_ + _"= or \verb="_ 'U' _"=, see
-Section~\ref{Notation}), the command works like {\tt Search
-{\qualid}}.
-
-\item {\tt Search {\str}\%{\delimkey}.}
-
-The string {\str} must be a notation or the main symbol of a notation
-which is then interpreted in the scope bound to the delimiting key
-{\delimkey} (see Section~\ref{scopechange}).
-
-\item {\tt Search {\termpattern}.}
-
-This searches for all statements or types of definition that contains
-a subterm that matches the pattern {\termpattern} (holes of the
-pattern are either denoted by ``{\texttt \_}'' or
-by ``{\texttt ?{\ident}}'' when non linear patterns are expected).
-
-\item {\tt Search \nelist{\zeroone{-}{\termpatternorstr}}{}.}\\
-
-\noindent where {\termpatternorstr} is a
-{\termpattern} or a {\str}, or a {\str} followed by a scope
-delimiting key {\tt \%{\delimkey}}.
-
-This generalization of {\tt Search} searches for all objects
-whose statement or type contains a subterm matching {\termpattern} (or
-{\qualid} if {\str} is the notation for a reference {\qualid}) and
-whose name contains all {\str} of the request that correspond to valid
-identifiers. If a {\termpattern} or a {\str} is prefixed by ``-'', the
-search excludes the objects that mention that {\termpattern} or that
-{\str}.
-
-\item
- {\tt Search} \nelist{{\termpatternorstr}}{}
- {\tt inside} {\module$_1$} \ldots{} {\module$_n$}{\tt .}
-
-This restricts the search to constructions defined in modules
-{\module$_1$} \ldots{} {\module$_n$}.
-
-\item
- {\tt Search \nelist{{\termpatternorstr}}{}
- outside {\module$_1$}...{\module$_n$}.}
-
-This restricts the search to constructions not defined in modules
-{\module$_1$} \ldots{} {\module$_n$}.
-
-\item {\tt selector: Search \nelist{\zeroone{-}{\termpatternorstr}}{}.}
-
- This specifies the goal on which to search hypothesis (see
- Section~\ref{tactic-syntax}). By default the 1st goal is searched.
- This variant can be combined with other variants presented here.
-\end{Variants}
-
-\examples
-
-\begin{coq_example*}
-Require Import ZArith.
-\end{coq_example*}
-\begin{coq_example}
-Search Z.mul Z.add "distr".
-Search "+"%Z "*"%Z "distr" -positive -Prop.
-Search (?x * _ + ?x * _)%Z outside OmegaLemmas.
-\end{coq_example}
-
-\Warning \comindex{SearchAbout} Up to {\Coq} version 8.4, {\tt Search}
-had the behavior of current {\tt SearchHead} and the behavior of
-current {\tt Search} was obtained with command {\tt SearchAbout}. For
-compatibility, the deprecated name {\tt SearchAbout} can still be used
-as a synonym of {\tt Search}. For compatibility, the list of objects to
-search when using {\tt SearchAbout} may also be enclosed by optional
-{\tt [ ]} delimiters.
-
-\subsection[\tt SearchHead {\term}.]{\tt SearchHead {\term}.\comindex{SearchHead}}
-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 {\tt ({\term} t1 ..
- tn)}. This command is useful to remind the user of the name of
-library lemmas.
-
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-
-\begin{coq_example}
-SearchHead le.
-SearchHead (@eq bool).
-\end{coq_example}
-
-\begin{Variants}
-\item
-{\tt SearchHead} {\term} {\tt inside} {\module$_1$} \ldots{} {\module$_n$}{\tt .}
-
-This restricts the search to constructions defined in modules
-{\module$_1$} \ldots{} {\module$_n$}.
-
-\item {\tt SearchHead} {\term} {\tt outside} {\module$_1$} \ldots{} {\module$_n$}{\tt .}
-
-This restricts the search to constructions not defined in modules
-{\module$_1$} \ldots{} {\module$_n$}.
-
-\begin{ErrMsgs}
-\item \errindex{Module/section \module{} not found}
-No module \module{} has been required (see Section~\ref{Require}).
-\end{ErrMsgs}
-
-\item {\tt selector: SearchHead {\term}.}
-
- This specifies the goal on which to search hypothesis (see
- Section~\ref{tactic-syntax}). By default the 1st goal is searched.
- This variant can be combined with other variants presented here.
-
-\end{Variants}
-
-\Warning Up to {\Coq} version 8.4, {\tt SearchHead} was named {\tt Search}.
-
-\subsection[\tt SearchPattern {\termpattern}.]{\tt SearchPattern {\term}.\comindex{SearchPattern}}
-
-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 expression
-{\term} where holes in the latter are denoted by ``{\texttt \_}''. It
-is a variant of {\tt Search
- {\termpattern}} 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.
-
-\begin{coq_example*}
-Require Import Arith.
-\end{coq_example*}
-\begin{coq_example}
-SearchPattern (_ + _ = _ + _).
-SearchPattern (nat -> bool).
-SearchPattern (forall l : list _, _ l l).
-\end{coq_example}
-
-Patterns need not be linear: you can express that the same expression
-must occur in two places by using pattern variables `{\texttt
-?{\ident}}''.
-
-\begin{coq_example}
-SearchPattern (?X1 + _ = _ + ?X1).
-\end{coq_example}
-
-\begin{Variants}
-\item {\tt SearchPattern {\term} inside
-{\module$_1$} \ldots{} {\module$_n$}.}
-
-This restricts the search to constructions defined in modules
-{\module$_1$} \ldots{} {\module$_n$}.
-
-\item {\tt SearchPattern {\term} outside {\module$_1$} \ldots{} {\module$_n$}.}
-
-This restricts the search to constructions not defined in modules
-{\module$_1$} \ldots{} {\module$_n$}.
-
-\item {\tt selector: SearchPattern {\term}.}
-
- This specifies the goal on which to search hypothesis (see
- Section~\ref{tactic-syntax}). By default the 1st goal is searched.
- This variant can be combined with other variants presented here.
-
-\end{Variants}
-
-\subsection[\tt SearchRewrite {\term}.]{\tt SearchRewrite {\term}.\comindex{SearchRewrite}}
-
-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 ``{\texttt \_}''.
-
-\begin{coq_example}
-Require Import Arith.
-SearchRewrite (_ + _ + _).
-\end{coq_example}
-
-\begin{Variants}
-\item {\tt SearchRewrite {\term} inside
-{\module$_1$} \ldots{} {\module$_n$}.}
-
-This restricts the search to constructions defined in modules
-{\module$_1$} \ldots{} {\module$_n$}.
-
-\item {\tt SearchRewrite {\term} outside {\module$_1$} \ldots{} {\module$_n$}.}
-
-This restricts the search to constructions not defined in modules
-{\module$_1$} \ldots{} {\module$_n$}.
-
-\item {\tt selector: SearchRewrite {\term}.}
-
- This specifies the goal on which to search hypothesis (see
- Section~\ref{tactic-syntax}). By default the 1st goal is searched.
- This variant can be combined with other variants presented here.
-
-\end{Variants}
-
-\subsubsection{Nota Bene:}
-For the {\tt Search}, {\tt SearchHead}, {\tt SearchPattern} and
-{\tt SearchRewrite} queries, it is possible to globally filter
-the search results via the command
-{\tt Add Search Blacklist "substring1"}.
-A lemma whose fully-qualified name contains any of the declared substrings
-will be removed from the search results.
-The default blacklisted substrings are {\tt
- "\_subproof" "Private\_"}. The command {\tt Remove Search Blacklist
- ...} allows expunging this blacklist.
-
-% \begin{tabbing}
-% \ \ \ \ \=11.\ \=\kill
-% \>1.\>$A=B\mx{ if }A\stackrel{\bt{}\io{}}{\lra{}}B$\\
-% \>2.\>$\sa{}x:A.B=\sa{}y:A.B[x\la{}y]\mx{ if }y\not\in{}FV(\sa{}x:A.B)$\\
-% \>3.\>$\Pi{}x:A.B=\Pi{}y:A.B[x\la{}y]\mx{ if }y\not\in{}FV(\Pi{}x:A.B)$\\
-% \>4.\>$\sa{}x:A.B=\sa{}x:B.A\mx{ if }x\not\in{}FV(A,B)$\\
-% \>5.\>$\sa{}x:(\sa{}y:A.B).C=\sa{}x:A.\sa{}y:B[y\la{}x].C[x\la{}(x,y)]$\\
-% \>6.\>$\Pi{}x:(\sa{}y:A.B).C=\Pi{}x:A.\Pi{}y:B[y\la{}x].C[x\la{}(x,y)]$\\
-% \>7.\>$\Pi{}x:A.\sa{}y:B.C=\sa{}y:(\Pi{}x:A.B).(\Pi{}x:A.C[y\la{}(y\sm{}x)]$\\
-% \>8.\>$\sa{}x:A.unit=A$\\
-% \>9.\>$\sa{}x:unit.A=A[x\la{}tt]$\\
-% \>10.\>$\Pi{}x:A.unit=unit$\\
-% \>11.\>$\Pi{}x:unit.A=A[x\la{}tt]$
-% \end{tabbing}
-
-% For more informations about the exact working of this command, see
-% \cite{Del97}.
-
-\subsection[\tt Locate {\qualid}.]{\tt Locate {\qualid}.\comindex{Locate}
-\label{Locate}}
-This command displays the full name of objects whose name is a prefix of the
-qualified identifier {\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.
-
-\begin{coq_eval}
-(*************** The last line should produce **************************)
-(*********** Error: I.Dont.Exist not a defined object ******************)
-\end{coq_eval}
-\begin{coq_eval}
-Set Printing Depth 50.
-\end{coq_eval}
-\begin{coq_example}
-Locate nat.
-Locate Datatypes.O.
-Locate Init.Datatypes.O.
-Locate Coq.Init.Datatypes.O.
-Locate I.Dont.Exist.
-\end{coq_example}
-
-\begin{Variants}
-\item {\tt Locate Term {\qualid}.}\comindex{Locate Term}\\
- As {\tt Locate} but restricted to terms.
-
-\item {\tt Locate Module {\qualid}.}
- As {\tt Locate} but restricted to modules.
-
-\item {\tt Locate Ltac {\qualid}.}\comindex{Locate Ltac}\\
- As {\tt Locate} but restricted to tactics.
-\end{Variants}
-
-
-\SeeAlso Section \ref{LocateSymbol}
-
-\section{Loading files}
-
-\Coq\ offers the possibility of loading different
-parts of a whole development stored in separate files. Their contents
-will be loaded as if they were entered from the keyboard. This means
-that the loaded files are ASCII files containing sequences of commands
-for \Coq's toplevel. This kind of file is called a {\em script} for
-\Coq\index{Script file}. The standard (and default) extension of
-\Coq's script files is {\tt .v}.
-
-\subsection[\tt Load {\ident}.]{\tt Load {\ident}.\comindex{Load}\label{Load}}
-This command loads the file named {\ident}{\tt .v}, searching
-successively in each of the directories specified in the {\em
- loadpath}. (see Section~\ref{loadpath})
-
-Files loaded this way cannot leave proofs open, and neither the {\tt
- Load} command can be use inside a proof.
-
-\begin{Variants}
-\item {\tt Load {\str}.}\label{Load-str}\\
- Loads the file denoted by the string {\str}, where {\str} is any
- complete filename. Then the \verb.~. and {\tt ..}
- abbreviations are allowed as well as shell variables. If no
- extension is specified, \Coq\ will use the default extension {\tt
- .v}
-\item {\tt Load Verbose {\ident}.},
- {\tt Load Verbose {\str}}\\
- \comindex{Load Verbose}
- Display, while loading, the answers of \Coq\ to each command
- (including tactics) contained in the loaded file
- \SeeAlso Section~\ref{Begin-Silent}
-\end{Variants}
-
-\begin{ErrMsgs}
-\item \errindex{Can't find file {\ident} on loadpath}
-\item \errindex{Load is not supported inside proofs}
-\item \errindex{Files processed by Load cannot leave open proofs}
-\end{ErrMsgs}
-
-\section[Compiled files]{Compiled files\label{compiled}\index{Compiled files}}
-
-This section describes the commands used to load compiled files (see
-Chapter~\ref{Addoc-coqc} for documentation on how to compile a file).
-A compiled file is a particular case of module called {\em library file}.
-
-%%%%%%%%%%%%
-% Import and Export described in RefMan-mod.tex
-% the minor difference (to avoid multiple Exporting of libraries) in
-% the treatment of normal modules and libraries by Export omitted
-
-\subsection[\tt Require {\qualid}.]{\tt Require {\qualid}.\label{Require}
-\comindex{Require}}
-
-This command looks in the loadpath for a file containing
-module {\qualid} and adds the corresponding module to the environment
-of {\Coq}. As library files have dependencies in other library files,
-the command {\tt Require {\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, {\qualid} is decomposed under
-the form {\dirpath}{\tt .}{\textsl{ident}} and the file {\ident}{\tt
-.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{loadpath}). 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.
-
-\begin{Variants}
-\item {\tt Require Import {\qualid}.} \comindex{Require Import}
-
- This loads and declares the module {\qualid} and its dependencies
- then imports the contents of {\qualid} as described in
- Section~\ref{Import}.
-
- It does not import the modules on which {\qualid} depends unless
- these modules were itself required in module {\qualid} using {\tt
- Require Export}, as described below, or recursively required through
- a sequence of {\tt Require Export}.
-
- If the module required has already been loaded, {\tt Require Import
- {\qualid}} simply imports it, as {\tt Import {\qualid}} would.
-
-\item {\tt Require Export {\qualid}.}
- \comindex{Require Export}
-
- This command acts as {\tt Require Import} {\qualid}, but if a
- further module, say {\it A}, contains a command {\tt Require
- Export} {\it B}, then the command {\tt Require Import} {\it A}
- also imports the module {\it B}.
-
-\item {\tt Require \zeroone{Import {\sl |} Export}} {\qualid}$_1$ {\ldots} {\qualid}$_n${\tt .}
-
- This loads the modules {\qualid}$_1$, \ldots, {\qualid}$_n$ and
- their recursive dependencies. If {\tt Import} or {\tt Export} is
- given, it also imports {\qualid}$_1$, \ldots, {\qualid}$_n$ and all
- the recursive dependencies that were marked or transitively marked
- as {\tt Export}.
-
-\item {\tt From {\dirpath} Require {\qualid}.}
- \comindex{From Require}
-
- This command acts as {\tt Require}, but picks any library whose absolute name
- is of the form {\tt{\dirpath}.{\dirpath'}.{\qualid}} for some {\dirpath'}.
- This is useful to ensure that the {\qualid} library comes from a given
- package by making explicit its absolute root.
-
-\end{Variants}
-
-\begin{ErrMsgs}
-
-\item \errindex{Cannot load {\qualid}: no physical path bound to {\dirpath}}
-
-\item \errindex{Cannot find library foo in loadpath}
-
- The command did not find the file {\tt foo.vo}. Either {\tt
- foo.v} exists but is not compiled or {\tt foo.vo} is in a directory
- which is not in your {\tt LoadPath} (see Section~\ref{loadpath}).
-
-\item \errindex{Compiled library {\ident}.vo makes inconsistent assumptions over library {\qualid}}
-
- The command tried to load library file {\ident}.vo that depends on
- some specific version of library {\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 {\qualid}.
-
-\item \errindex{Bad magic number}
-
- \index{Bad-magic-number@{\tt Bad Magic Number}}
- The file {\tt{\ident}.vo} was found but either it is not a \Coq\
- compiled module, or it was compiled with an older and incompatible
- version of {\Coq}.
-
-\item \errindex{The file {\ident}.vo contains library {\dirpath} and not
- library {\dirpath'}}
-
- The library file {\dirpath'} is indirectly required by the {\tt
- 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.
-
-\item \errindex{Require is not allowed inside a module or a module type}
-
- This command is not allowed inside a module or a module type being defined.
- It is meant to describe a dependency between compilation units. Note however
- that the commands {\tt Import} and {\tt Export} alone can be used inside
- modules (see Section~\ref{Import}).
-
-\end{ErrMsgs}
-
-\SeeAlso Chapter~\ref{Addoc-coqc}
-
-\subsection[\tt Print Libraries.]{\tt Print Libraries.\comindex{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.
-
-\subsection[\tt Declare ML Module {\str$_1$} .. {\str$_n$}.]{\tt Declare ML Module {\str$_1$} .. {\str$_n$}.\comindex{Declare ML Module}}
-This commands loads the {\ocaml} compiled files {\str$_1$} {\ldots}
-{\str$_n$} (dynamic link). It is mainly used to load tactics
-dynamically.
-% (see Chapter~\ref{WritingTactics}).
- The files are
-searched into the current {\ocaml} loadpath (see the command {\tt
-Add ML Path} in the Section~\ref{loadpath}). Loading of {\ocaml}
-files is only possible under the bytecode version of {\tt coqtop}
-(i.e. {\tt coqtop.byte}, see chapter
-\ref{Addoc-coqc}), or when {\Coq} has been compiled with a version of
-{\ocaml} that supports native {\tt Dynlink} ($\ge$ 3.11).
-
-\begin{Variants}
-\item {\tt Local Declare ML Module {\str$_1$} .. {\str$_n$}.}\\
- This variant is not exported to the modules that import the module
- where they occur, even if outside a section.
-\end{Variants}
-
-\begin{ErrMsgs}
-\item \errindex{File not found on loadpath : \str}
-\item \errindex{Loading of ML object file forbidden in a native {\Coq}}
-\end{ErrMsgs}
-
-\subsection[\tt Print ML Modules.]{\tt Print ML Modules.\comindex{Print ML Modules}}
-This print the name of all \ocaml{} modules loaded with \texttt{Declare
- ML Module}. To know from where these module were loaded, the user
-should use the command \texttt{Locate File} (see Section~\ref{Locate File})
-
-\section[Loadpath]{Loadpath}
-
-Loadpaths are preferably managed using {\Coq} command line options
-(see Section~\ref{loadpath}) 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.
-
-\subsection[\tt Pwd.]{\tt Pwd.\comindex{Pwd}\label{Pwd}}
-This command displays the current working directory.
-
-\subsection[\tt Cd {\str}.]{\tt Cd {\str}.\comindex{Cd}}
-This command changes the current directory according to {\str}
-which can be any valid path.
-
-\begin{Variants}
-\item {\tt Cd.}\\
- Is equivalent to {\tt Pwd.}
-\end{Variants}
-
-\subsection[\tt Add LoadPath {\str} as {\dirpath}.]{\tt Add LoadPath {\str} as {\dirpath}.\comindex{Add LoadPath}\label{AddLoadPath}}
-
-This command is equivalent to the command line option {\tt -Q {\str}
- {\dirpath}}. It adds the physical directory {\str} to the current {\Coq}
-loadpath and maps it to the logical directory {\dirpath}.
-
-\begin{Variants}
-\item {\tt Add LoadPath {\str}.}\\
-Performs as {\tt Add LoadPath {\str} as {\dirpath}} but for the empty directory path.
-\end{Variants}
-
-\subsection[\tt Add Rec LoadPath {\str} as {\dirpath}.]{\tt Add Rec LoadPath {\str} as {\dirpath}.\comindex{Add Rec LoadPath}\label{AddRecLoadPath}}
-This command is equivalent to the command line option {\tt -R {\str}
- {\dirpath}}. It adds the physical directory {\str} and all its
-subdirectories to the current {\Coq} loadpath.
-
-\begin{Variants}
-\item {\tt Add Rec LoadPath {\str}.}\\
-Works as {\tt Add Rec LoadPath {\str} as {\dirpath}} but for the empty logical directory path.
-\end{Variants}
-
-\subsection[\tt Remove LoadPath {\str}.]{\tt Remove LoadPath {\str}.\comindex{Remove LoadPath}}
-This command removes the path {\str} from the current \Coq\ loadpath.
-
-\subsection[\tt Print LoadPath.]{\tt Print LoadPath.\comindex{Print LoadPath}}
-This command displays the current \Coq\ loadpath.
-
-\begin{Variants}
-\item {\tt Print LoadPath {\dirpath}.}\\
-Works as {\tt Print LoadPath} but displays only the paths that extend the {\dirpath} prefix.
-\end{Variants}
-
-\subsection[\tt Add ML Path {\str}.]{\tt Add ML Path {\str}.\comindex{Add ML Path}}
-This command adds the path {\str} to the current {\ocaml} loadpath (see
-the command {\tt Declare ML Module} in the Section~\ref{compiled}).
-
-\subsection[\tt Add Rec ML Path {\str}.]{\tt Add Rec ML Path {\str}.\comindex{Add Rec ML Path}}
-This command adds the directory {\str} and all its subdirectories
-to the current {\ocaml} loadpath (see
-the command {\tt Declare ML Module} in the Section~\ref{compiled}).
-
-\subsection[\tt Print ML Path {\str}.]{\tt Print ML Path {\str}.\comindex{Print ML Path}}
-This command displays the current {\ocaml} loadpath.
-This command makes sense only under the bytecode version of {\tt
-coqtop}, i.e. {\tt coqtop.byte} (see the
-command {\tt Declare ML Module} in the section
-\ref{compiled}).
-
-\subsection[\tt Locate File {\str}.]{\tt Locate File {\str}.\comindex{Locate
- File}\label{Locate File}}
-This command displays the location of file {\str} in the current loadpath.
-Typically, {\str} is a \texttt{.cmo} or \texttt{.vo} or \texttt{.v} file.
-
-\subsection[\tt Locate Library {\dirpath}.]{\tt Locate Library {\dirpath}.\comindex{Locate Library}\label{Locate Library}}
-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 {\dirpath}.
-
-\section{Backtracking}
-
-The backtracking commands described in this section can only be used
-interactively, they cannot be part of a vernacular file loaded via
-{\tt Load} or compiled by {\tt coqc}.
-
-\subsection[\tt Reset \ident.]{\tt Reset \ident.\comindex{Reset}}
-This command removes all the objects in the environment since \ident\
-was introduced, including \ident. \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.
-
-\begin{ErrMsgs}
-\item \ident: \errindex{no such entry}
-\end{ErrMsgs}
-
-\begin{Variants}
- \item {\tt Reset Initial.}\comindex{Reset Initial}\\
- Goes back to the initial state, just after the start of the
- interactive session.
-\end{Variants}
-
-\subsection[\tt Back.]{\tt Back.\comindex{Back}}
-
-This commands undoes all the effects of the last vernacular
-command. Commands read from a vernacular file via a {\tt Load} are
-considered as a single command. Proof management commands
-are also handled by this command (see Chapter~\ref{Proof-handling}).
-For that, {\tt 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 {\tt Qed}, the management
-information about the closed proof has been discarded. In this case,
-{\tt Back} will then undo all the proof steps up to the statement of
-this proof.
-
-\begin{Variants}
-\item {\tt Back $n$} \\
- Undoes $n$ vernacular commands. As for {\tt Back}, some extra
- commands may be undone in order to reach an adequate state.
- For instance {\tt Back n} will not re-enter a closed proof,
- but rather go just before that proof.
-\end{Variants}
-
-\begin{ErrMsgs}
-\item \errindex{Invalid backtrack} \\
- The user wants to undo more commands than available in the history.
-\end{ErrMsgs}
-
-\subsection[\tt BackTo $\num$.]{\tt BackTo $\num$.\comindex{BackTo}}
-\label{sec:statenums}
-
-This command brings back the system to the state labeled $\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 \texttt{-emacs} mode.
-Just as {\tt Back} (see above), the {\tt BackTo} command now handles
-proof states. For that, it may have to undo some
-extra commands and end on a state $\num' \leq \num$ if necessary.
-
-\begin{Variants}
-\item {\tt Backtrack $\num_1$ $\num_2$ $\num_3$}.\comindex{Backtrack}\\
- {\tt Backtrack} is a \emph{deprecated} form of {\tt BackTo} which
- allows explicitly manipulating the proof environment. The three
- numbers $\num_1$, $\num_2$ and $\num_3$ represent the following:
-\begin{itemize}
-\item $\num_3$: Number of \texttt{Abort} to perform, i.e. the number
- of currently opened nested proofs that must be canceled (see
- Chapter~\ref{Proof-handling}).
-\item $\num_2$: \emph{Proof state number} to unbury once aborts have
- been done. {\Coq} will compute the number of \texttt{Undo} to perform
- (see Chapter~\ref{Proof-handling}).
-\item $\num_1$: State label to reach, as for {\tt BackTo}.
-\end{itemize}
-\end{Variants}
-
-\begin{ErrMsgs}
-\item \errindex{Invalid backtrack} \\
- The destination state label is unknown.
-\end{ErrMsgs}
-
-\section{Quitting and debugging}
-
-\subsection[\tt Quit.]{\tt Quit.\comindex{Quit}}
-This command permits to quit \Coq.
-
-\subsection[\tt Drop.]{\tt Drop.\comindex{Drop}\label{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:
-
-\begin{flushleft}
-\begin{verbatim}
-#use "include";;
-\end{verbatim}
-\end{flushleft}
-
-\noindent add the right loadpaths and loads some toplevel printers for
-all abstract types of \Coq - section\_path, identifiers, terms, judgments,
-\dots. You can also use the file \texttt{base\_include} instead,
-that loads only the pretty-printers for section\_paths and
-identifiers.
-% See Section~\ref{test-and-debug} more information on the
-% usage of the toplevel.
-You can return back to \Coq{} with the command:
-
-\begin{flushleft}
-\begin{verbatim}
-go();;
-\end{verbatim}
-\end{flushleft}
-
-\begin{Warnings}
-\item It only works with the bytecode version of {\Coq} (i.e. {\tt coqtop} called with option {\tt -byte}, see the contents of Section~\ref{binary-images}).
-\item You must have compiled {\Coq} from the source package and set the
- environment variable \texttt{COQTOP} to the root of your copy of the sources (see Section~\ref{EnvVariables}).
-\end{Warnings}
-
-\subsection[\tt Time \textrm{\textsl{command}}.]{\tt Time \textrm{\textsl{command}}.\comindex{Time}
-\label{time}}
-This command executes the vernacular command \textrm{\textsl{command}}
-and display the time needed to execute it.
-
-\subsection[\tt Redirect "\textrm{\textsl{file}}" \textrm{\textsl{command}}.]{\tt Redirect "\textrm{\textsl{file}}" \textrm{\textsl{command}}.\comindex{Redirect}
-\label{redirect}}
-This command executes the vernacular command \textrm{\textsl{command}}, redirecting its output to ``\textrm{\textsl{file}}.out''.
-
-\subsection[\tt Timeout \textrm{\textsl{int}} \textrm{\textsl{command}}.]{\tt Timeout \textrm{\textsl{int}} \textrm{\textsl{command}}.\comindex{Timeout}
-\label{timeout}}
-
-This command executes the vernacular command \textrm{\textsl{command}}. If
-the command has not terminated after the time specified by the integer
-(time expressed in seconds), then it is interrupted and an error message
-is displayed.
-
-\subsection[\tt Set Default Timeout \textrm{\textsl{int}}.]{\tt Set
- Default Timeout \textrm{\textsl{int}}.\optindex{Default Timeout}}
-
-After using this command, all subsequent commands behave as if they
-were passed to a {\tt Timeout} command. Commands already starting by
-a {\tt Timeout} are unaffected.
-
-\subsection[\tt Unset Default Timeout.]{\tt Unset Default Timeout.\optindex{Default Timeout}}
-
-This command turns off the use of a default timeout.
-
-\subsection[\tt Test Default Timeout.]{\tt Test Default Timeout.\optindex{Default Timeout}}
-
-This command displays whether some default timeout has be set or not.
-
-\subsection[\tt Fail \textrm{\textsl{command-or-tactic}}.]{\tt Fail \textrm{\textsl{command-or-tactic}}.\comindex{Fail}\label{Fail}}
-
-For debugging {\Coq} scripts, sometimes it is desirable to know
-whether a command or a tactic fails. If the given command or tactic
-fails, the {\tt Fail} statement succeeds, without changing the proof
-state, and in interactive mode, {\Coq} prints a message confirming the failure.
-If the command or tactic succeeds, the statement is an error, and
-{\Coq} prints a message indicating that the failure did not occur.
-
-\section{Controlling display}
-
-\subsection[\tt Set Silent.]{\tt Set Silent.\optindex{Silent}
-\label{Begin-Silent}
-\index{Silent mode}}
-This command turns off the normal displaying.
-
-\subsection[\tt Unset Silent.]{\tt Unset Silent.\optindex{Silent}}
-This command turns the normal display on.
-
-\subsection[\tt Set Warnings ``(\nterm{w}$_1$,\ldots,%
- \nterm{w}$_n$)''.]{{\tt Set Warnings ``(\nterm{w}$_1$,\ldots,%
- \nterm{w}$_n$)''}.\optindex{Warnings}}
-\label{SetWarnings}
-This command configures the display of warnings. It is experimental, and
-expects, between quotes, a comma-separated list of warning names or
-categories. Adding~\texttt{-} in front of a warning or category disables it,
-adding~\texttt{+} makes it an error. It is possible to use the special
-categories \texttt{all} and \texttt{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
-\texttt{A,-A} is equivalent to \texttt{-A}.
-
-\subsection[\tt Set Search Output Name Only.]{\tt Set Search Output Name Only.\optindex{Search Output Name Only}
-\label{Search-Output-Name-Only}
-\index{Search Output Name Only mode}}
-This command restricts the output of search commands to identifier names; turning it on causes invocations of {\tt Search}, {\tt SearchHead}, {\tt SearchPattern}, {\tt SearchRewrite} etc. to omit types from their output, printing only identifiers.
-
-\subsection[\tt Unset Search Output Name Only.]{\tt Unset Search Output Name Only.\optindex{Search Output Name Only}}
-This command turns type display in search results back on.
-
-\subsection[\tt Set Printing Width {\integer}.]{\tt Set Printing Width {\integer}.\optindex{Printing Width}}
-\label{SetPrintingWidth}
-This command sets which left-aligned part of the width of the screen
-is used for display.
-
-\subsection[\tt Unset Printing Width.]{\tt Unset Printing Width.\optindex{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).
-
-\subsection[\tt Test Printing Width.]{\tt Test Printing Width.\optindex{Printing Width}}
-This command displays the current screen width used for display.
-
-\subsection[\tt Set Printing Depth {\integer}.]{\tt Set Printing Depth {\integer}.\optindex{Printing Depth}}
-This command sets the nesting depth of the formatter used for
-pretty-printing. Beyond this depth, display of subterms is replaced by
-dots.
-
-\subsection[\tt Unset Printing Depth.]{\tt Unset Printing Depth.\optindex{Printing Depth}}
-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).
-
-\subsection[\tt Test Printing Depth.]{\tt Test Printing Depth.\optindex{Printing Depth}}
-This command displays the current nesting depth used for display.
-
-\subsection[\tt Unset Printing Compact Contexts.]{\tt Unset Printing Compact Contexts.\optindex{Printing Compact Contexts}}
-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.
-
-\subsection[\tt Set Printing Compact Contexts.]{\tt Set Printing Compact Contexts.\optindex{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 {\tt Set
- Printing Width} above).
-
-\subsection[\tt Test Printing Compact Contexts.]{\tt Test Printing Compact Contexts.\optindex{Printing Compact Contexts}}
-This command displays the current state of compaction of goal.
-
-
-\subsection[\tt Unset Printing Unfocused.]{\tt Unset Printing Unfocused.\optindex{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{bullets}) or curly braces (see~\ref{curlybacket}).
-
-\subsection[\tt Set Printing Unfocused.]{\tt Set Printing Unfocused.\optindex{Printing Unfocused}}
-This command enables the displaying of unfocused goals. The goals are
-displayed after the focused ones and are distinguished by a separator.
-
-\subsection[\tt Test Printing Unfocused.]{\tt Test Printing Unfocused.\optindex{Printing Unfocused}}
-This command displays the current state of unfocused goals display.
-
-\subsection[\tt Set Printing Dependent Evars Line.]{\tt Set Printing Dependent Evars Line.\optindex{Printing Dependent Evars Line}}
-This command enables the printing of the ``{\tt (dependent evars: \ldots)}''
-line when {\tt -emacs} is passed.
-
-\subsection[\tt Unset Printing Dependent Evars Line.]{\tt Unset Printing Dependent Evars Line.\optindex{Printing Dependent Evars Line}}
-This command disables the printing of the ``{\tt (dependent evars: \ldots)}''
-line when {\tt -emacs} is passed.
-
-%\subsection{\tt Abstraction ...}
-%Not yet documented.
-
-\section{Controlling the reduction strategies and the conversion algorithm}
-\label{Controlling_reduction_strategy}
-
-{\Coq} provides reduction strategies that the tactics can invoke and
-two different algorithms to check the convertibility of types.
-The first 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~\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.
-
-\subsection[{\tt Opaque} \qualid$_1$ {\ldots} \qualid$_n${\tt .}]{{\tt Opaque} \qualid$_1$ {\ldots} \qualid$_n${\tt .}\comindex{Opaque}\label{Opaque}}
-This command has an effect on unfoldable constants, i.e.
-on constants defined by {\tt Definition} or {\tt Let} (with an explicit
-body), or by a command assimilated to a definition such as {\tt
-Fixpoint}, {\tt Program Definition}, etc, or by a proof ended by {\tt
-Defined}. The command tells not to unfold
-the constants {\qualid$_1$} {\ldots} {\qualid$_n$} in tactics using
-$\delta$-conversion (unfolding a constant is replacing it by its
-definition).
-
-{\tt 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{conv-rules})
-of two distinct applied constants.
-
-The scope of {\tt Opaque} is limited to the current section, or
-current file, unless the variant {\tt Global Opaque \qualid$_1$ {\ldots}
-\qualid$_n$} is used.
-
-\SeeAlso sections \ref{Conversion-tactics}, \ref{Automatizing},
-\ref{Theorem}
-
-\begin{ErrMsgs}
-\item \errindex{The reference \qualid\ was not found in the current
-environment}\\
- There is no constant referred by {\qualid} in the environment.
- Nevertheless, if you asked \texttt{Opaque foo bar}
- and if \texttt{bar} does not exist, \texttt{foo} is set opaque.
-\end{ErrMsgs}
-
-\subsection[{\tt Transparent} \qualid$_1$ {\ldots} \qualid$_n${\tt .}]{{\tt Transparent} \qualid$_1$ {\ldots} \qualid$_n${\tt .}\comindex{Transparent}\label{Transparent}}
-This command is the converse of {\tt Opaque} and it applies on
-unfoldable constants to restore their unfoldability after an {\tt
-Opaque} command.
-
-Note in particular that constants defined by a proof ended by {\tt
-Qed} are not unfoldable and {\tt Transparent} has no effect on
-them. This is to keep with the usual mathematical practice of {\em
-proof irrelevance}: what matters in a mathematical development is the
-sequence of lemma statements, not their actual proofs. This
-distinguishes lemmas from the usual defined constants, whose actual
-values are of course relevant in general.
-
-The scope of {\tt Transparent} is limited to the current section, or
-current file, unless the variant {\tt Global Transparent} \qualid$_1$
-{\ldots} \qualid$_n$ is used.
-
-\begin{ErrMsgs}
-% \item \errindex{Can not set transparent.}\\
-% It is a constant from a required module or a parameter.
-\item \errindex{The reference \qualid\ was not found in the current
-environment}\\
- There is no constant referred by {\qualid} in the environment.
-\end{ErrMsgs}
-
-\SeeAlso sections \ref{Conversion-tactics}, \ref{Automatizing},
-\ref{Theorem}
-
-\subsection{{\tt Strategy} {\it level} {\tt [} \qualid$_1$ {\ldots} \qualid$_n$
- {\tt ].}\comindex{Strategy}\comindex{Local Strategy}\label{Strategy}}
-This command generalizes the behavior of {\tt Opaque} and {\tt
- 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 \qualid$_1$ {\ldots}
-\qualid$_n$. 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):
-\begin{description}
-\item[opaque]: level of opaque constants. They cannot be expanded by
- tactics (behaves like $+\infty$, see next item).
-\item[\num]: levels indexed by an integer. Level $0$ corresponds
- to the default behavior, which corresponds to transparent
- constants. This level can also be referred to as {\bf transparent}.
- Negative levels correspond to constants to be expanded before normal
- transparent constants, while positive levels correspond to constants
- to be expanded after normal transparent constants.
-\item[expand]: level of constants that should be expanded first
- (behaves like $-\infty$)
-\end{description}
-
-These directives survive section and module closure, unless the
-command is prefixed by {\tt Local}. In the latter case, the behavior
-regarding sections and modules is the same as for the {\tt
- Transparent} and {\tt Opaque} commands.
-
-\subsection{{\tt Print Strategy} \qualid{\tt .}\comindex{Print Strategy}\label{PrintStrategy}}
-
-This command prints the strategy currently associated to \qualid{}. It fails if
-\qualid{} is not an unfoldable reference, that is, neither a variable nor a
-constant.
-
-\begin{ErrMsgs}
-\item The reference is not unfoldable.
-\end{ErrMsgs}
-
-\begin{Variants}
-\item {\tt Print Strategies}\comindex{Print Strategies}\\
- Print all the currently non-transparent strategies.
-\end{Variants}
-
-\subsection{\tt Declare Reduction \ident\ := {\rm\sl convtactic}.}
-
-This command allows giving a short name to a reduction expression,
-for instance {\tt lazy beta delta [foo bar]}. This short name can
-then be used in {\tt Eval \ident\ in ...} or {\tt eval} directives.
-This command accepts the {\tt 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 \ident\ cannot be used
-directly as an Ltac tactic, but nothing prevent the user to also
-perform a {\tt Ltac \ident\ := {\rm\sl convtactic}}.
-
-\SeeAlso sections \ref{Conversion-tactics}
-
-\section{Controlling the locality of commands}
-
-\subsection{{\tt Local}, {\tt Global}
-\comindex{Local}
-\comindex{Global}
-}
-
-Some commands support a {\tt Local} or {\tt Global} prefix modifier to
-control the scope of their effect. There are four kinds of commands:
-
-\begin{itemize}
-\item 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 {\tt Local} modifier limits the effect of
- the command to the current section or module it occurs in.
-
- As an example, the {\tt Coercion} (see Section~\ref{Coercions})
- and {\tt Strategy} (see Section~\ref{Strategy})
- commands belong to this category.
-
-\item 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 {\tt Local} modifier limits the effect of
- the command to the current module if the command does not occur in a
- section and the {\tt Global} modifier extends the effect outside the
- current sections and current module if the command occurs in a
- section.
-
- As an example, the {\tt Implicit Arguments} (see
- Section~\ref{Implicit Arguments}), {\tt Ltac} (see
- Chapter~\ref{TacticLanguage}) or {\tt Notation} (see
- Section~\ref{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 {\tt Global} is not
- applicable to them.
-
-\item Commands whose default behavior is to stop their effect at the
- end of the section or module they occur in.
-
- For these commands, the {\tt Global} modifier extends their effect
- outside the sections and modules they occurs in.
-
- The {\tt Transparent} and {\tt Opaque} (see
- Section~\ref{Controlling_reduction_strategy}) commands belong to
- this category.
-
-\item 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 {\tt Local} modifier limits the effect to
- the current section or module while the {\tt Global} modifier extends
- the effect outside the module even when the command occurs in a section.
-
- The {\tt Set} and {\tt Unset} commands belong to this category.
-\end{itemize}
-
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
diff --git a/doc/refman/RefMan-pro.tex b/doc/refman/RefMan-pro.tex
deleted file mode 100644
index bd74a40d7..000000000
--- a/doc/refman/RefMan-pro.tex
+++ /dev/null
@@ -1,581 +0,0 @@
-\chapter[Proof handling]{Proof handling\index{Proof editing}
-\label{Proof-handling}}
-%HEVEA\cutname{proof-handling.html}
-
-In \Coq's proof editing mode all top-level commands documented in
-Chapter~\ref{Vernacular-commands} 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 {\em 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
-\index{Prompt}
-{\tt Coq <} is changed into {\tt {\ident} <} where {\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 {\em \index*{local context}} of the goal.
-Initially, the local context contains the local variables and
-hypotheses of the current section (see Section~\ref{Variable}) and the
-local variables and hypotheses of the theorem statement. It is
-enriched by the use of certain tactics (see e.g. {\tt intro} in
-Section~\ref{intro}).
-
-When a proof is completed, the message {\tt 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 $\lambda$-calculus, known as the {\em Curry-Howard
-isomorphism} \cite{How80,Bar91,Gir89,Hue89}, \Coq~ stores proofs as
-terms of {\sc Cic}. Those terms are called {\em proof
- terms}\index{Proof term}.
-
-\ErrMsg When one attempts to use a proof editing command out of the
-proof editing mode, \Coq~ raises the error message : \errindex{No focused
- proof}.
-
-\section{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:
-
-\begin{quote}
-{\tt Theorem {\ident} \zeroone{\binders} : {\form}.\comindex{Theorem}
-\label{Theorem}}
-\end{quote}
-
-The list of assertion commands is given in
-Section~\ref{Assertions}. The command {\tt Goal} can also be used.
-
-\subsection[Goal {\form}.]{\tt Goal {\form}.\comindex{Goal}\label{Goal}}
-
-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 {\tt Unnamed\_thm} (or a variant of this name not
-already used for another statement).
-
-\subsection[\tt Qed.]{\tt Qed.\comindex{Qed}\label{Qed}}
-This command is available in interactive editing proof mode when the
-proof is completed. Then {\tt 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 {\tt Opaque} constant.
-
-\begin{ErrMsgs}
-\item \errindex{Attempt to save an incomplete proof}
-%\item \ident\ \errindex{already exists}\\
-% The implicit name is already defined. You have then to provide
-% explicitly a new name (see variant 3 below).
-\item 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.
-\end{ErrMsgs}
-
-\begin{Variants}
-
-\item {\tt Defined.}
-\comindex{Defined}
-\label{Defined}
-
- Defines the proved term as a transparent constant.
-
-\item {\tt Save {\ident}.}
-
- Forces the name of the original goal to be {\ident}. This command
- (and the following ones) can only be used if the original goal has
- been opened using the {\tt Goal} command.
-
-\end{Variants}
-
-\subsection[\tt Admitted.]{\tt Admitted.\comindex{Admitted}\label{Admitted}}
-This command is available in interactive editing proof mode to give up
-the current proof and declare the initial goal as an axiom.
-
-\subsection[\tt Proof {\term}.]{\tt Proof {\term}.\comindex{Proof}
-\label{BeginProof}}
-This command applies in proof editing mode. It is equivalent to {\tt
- exact {\term}. Qed.} That is, you have to give the full proof in
-one gulp, as a proof term (see Section~\ref{exact}).
-
-\variant {\tt Proof.}
-
- Is a noop which is useful to delimit the sequence of tactic commands
- which start a proof, after a {\tt Theorem} command. It is a good
- practice to use {\tt Proof.} as an opening parenthesis, closed in
- the script with a closing {\tt Qed.}
-
-\SeeAlso {\tt Proof with {\tac}.} in Section~\ref{ProofWith}.
-
-\subsection[{\tt Proof using} {\ident$_1$} {\ldots} {\ident$_n$}{\tt .}]
-{{\tt Proof using} {\ident$_1$} {\ldots} {\ident$_n$}{\tt .}
-\comindex{Proof using} \label{ProofUsing}}
-
-This command applies in proof editing mode.
-It declares the set of section variables (see~\ref{Variable})
-used by the proof. At {\tt Qed} time, the system will assert that
-the set of section variables actually used in the proof is a subset of
-the declared one.
-
-The set of declared variables is closed under type dependency.
-For example if {\tt T} is variable and {\tt a} is a variable of
-type {\tt T}, the commands {\tt Proof using a} and
-{\tt Proof using T a} are actually equivalent.
-
-\variant {\tt Proof using} {\ident$_1$} {\ldots} {\ident$_n$} {\tt with} {\tac}{\tt .}
-in Section~\ref{ProofWith}.
-
-\variant {\tt Proof using All.}
-
- Use all section variables.
-
-\variant {\tt Proof using Type.}
-\variant {\tt Proof using.}
-
- Use only section variables occurring in the statement.
-
-\variant {\tt Proof using Type*.}
-
- The {\tt *} operator computes the forward transitive closure.
- E.g. if the variable {\tt H} has type {\tt p < 5} then {\tt H} is
- in {\tt p*} since {\tt p} occurs in the type of {\tt H}.
- {\tt Type* } is the forward transitive closure of the entire set of
- section variables occurring in the statement.
-
-\variant {\tt Proof using -( \ident$_1$} {\ldots} {\tt \ident$_n$ ).}
-
- Use all section variables except {\ident$_1$} {\ldots} {\ident$_n$}.
-
-\variant {\tt Proof using \nterm{collection}$_1$ + \nterm{collection}$_2$ .}
-
-\variant {\tt Proof using \nterm{collection}$_1$ - \nterm{collection}$_2$ .}
-
-\variant {\tt Proof using \nterm{collection} - ( \ident$_1$} {\ldots} {\tt \ident$_n$ ).}
-
-\variant {\tt Proof using \nterm{collection} * .}
-
- Use section variables being, respectively, in the set union, set difference,
- set complement, set forward transitive closure.
- See Section~\ref{Collection} to know how to form a named
- collection.
- The {\tt *} operator binds stronger than {\tt +} and {\tt -}.
-
-\subsubsection{{\tt Proof using} options}
-\optindex{Default Proof Using}
-\optindex{Suggest Proof Using}
-% \optindex{Proof Using Clear Unused}
-
-The following options modify the behavior of {\tt Proof using}.
-
-\variant {\tt Set Default Proof Using "expression".}
-
- Use {\tt expression} as the default {\tt Proof using} value.
- E.g. {\tt Set Default Proof Using "a b".} will complete all {\tt Proof }
- commands not followed by a {\tt using} part with {\tt using a b}.
-
-\variant {\tt Set Suggest Proof Using.}
-
- When {\tt Qed} is performed, suggest a {\tt using} annotation if
- the user did not provide one.
-
-% \variant{\tt Unset Proof Using Clear Unused.}
-%
-% When {\tt Proof using a} all section variables but for {\tt a} and
-% the variables used in the type of {\tt a} are cleared.
-% This option can be used to turn off this behavior.
-%
-\subsubsection[\tt Collection]{Name a set of section hypotheses for {\tt Proof using}}
-\comindex{Collection}\label{Collection}
-
-The command {\tt Collection} can be used to name a set of section hypotheses,
-with the purpose of making {\tt Proof using} annotations more compact.
-
-\variant {\tt Collection Some := x y z.}
-
- Define the collection named "Some" containing {\tt x y} and {\tt z}
-
-\variant {\tt Collection Fewer := Some - x.}
-
- Define the collection named "Fewer" containing only {\tt x y}
-
-\variant {\tt Collection Many := Fewer + Some.}
-\variant {\tt Collection Many := Fewer - Some.}
-
- Define the collection named "Many" containing the set union or set difference
- of "Fewer" and "Some".
-
-\variant {\tt Collection Many := Fewer - (x y).}
-
- Define the collection named "Many" containing the set difference
- of "Fewer" and the unnamed collection {\tt x y}.
-
-\subsection[\tt Abort.]{\tt Abort.\comindex{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.
-
-\begin{ErrMsgs}
-\item \errindex{No focused proof (No proof-editing in progress)}
-\end{ErrMsgs}
-
-\begin{Variants}
-
-\item {\tt Abort {\ident}.}
-
- Aborts the editing of the proof named {\ident}.
-
-\item {\tt Abort All.}
-
- Aborts all current goals, switching back to the \Coq\ toplevel.
-
-\end{Variants}
-
-%%%%
-\subsection[\tt Existential {\num} := {\term}.]{\tt Existential {\num} := {\term}.\comindex{Existential}
-\label{Existential}}
-
-This command instantiates an existential variable. {\tt \num}
-is an index in the list of uninstantiated existential variables
-displayed by {\tt Show Existentials} (described in Section~\ref{Show}).
-
-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 {\tt instantiate}.
-
-\SeeAlso {\tt instantiate (\num:= \term).} in Section~\ref{instantiate}.
-\SeeAlso {\tt Grab Existential Variables.} below.
-
-\subsection[\tt Grab Existential Variables.]{\tt Grab Existential Variables.\comindex{Grab Existential Variables}
-\label{GrabEvars}}
-
-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.
-
-%%%%%%%%
-\section{Navigation in the proof tree}
-%%%%%%%%
-
-\subsection[\tt Undo.]{\tt Undo.\comindex{Undo}}
-
-This command cancels the effect of the last command. Thus, it
-backtracks one step.
-
-\begin{Variants}
-
-\item {\tt Undo {\num}.}
-
- Repeats {\tt Undo} {\num} times.
-
-\end{Variants}
-
-\subsection[\tt Restart.]{\tt Restart.\comindex{Restart}}
-This command restores the proof editing process to the original goal.
-
-\begin{ErrMsgs}
-\item \errindex{No focused proof to restart}
-\end{ErrMsgs}
-
-\subsection[\tt Focus.]{\tt Focus.\comindex{Focus}}
-This focuses the attention on the first subgoal to prove and the printing
-of the other subgoals is suspended until the focused subgoal is
-solved or unfocused. This is useful when there are many current
-subgoals which clutter your screen.
-
-\begin{Variant}
-\item {\tt Focus {\num}.}\\
-This focuses the attention on the $\num^{th}$ subgoal to prove.
-\end{Variant}
-
-\emph{This command is deprecated since 8.8: prefer the use of bullets or
- focusing brackets instead, including {\tt {\num}: \{}}.
-
-\subsection[\tt Unfocus.]{\tt Unfocus.\comindex{Unfocus}}
-This command restores to focus the goal that were suspended by the
-last {\tt Focus} command.
-
-\emph{This command is deprecated since 8.8.}
-
-\subsection[\tt Unfocused.]{\tt Unfocused.\comindex{Unfocused}}
-Succeeds in the proof if fully unfocused, fails if there are some
-goals out of focus.
-
-\subsection[\tt \{ \textrm{and} \}]{\tt \{ \textrm{and} \}\comindex{\{}\comindex{\}}}\label{curlybacket}
-The command {\tt \{} (without a terminating period) focuses on the
-first goal, much like {\tt Focus.} does, however, the subproof can
-only be unfocused when it has been fully solved (\emph{i.e.} when
-there is no focused goal left). Unfocusing is then handled by {\tt \}}
-(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 {\tt \}} to
-unfocus it or focus the next one.
-
-\begin{Variants}
-
-\item {\tt {\num}: \{}\\
-This focuses on the $\num^{th}$ subgoal to prove.
-
-\end{Variants}
-
-\begin{ErrMsgs}
-\item \errindex{This proof is focused, but cannot be unfocused
- this way} You are trying to use {\tt \}} but the current subproof
- has not been fully solved.
-\item \errindex{No such goal}
-\item \errindex{Brackets only support the single numbered goal selector}
-\item see also error message about bullets below.
-\end{ErrMsgs}
-
-\subsection[Bullets]{Bullets\comindex{+ (command)}
- \comindex{- (command)}\comindex{* (command)}\index{Bullets}}\label{bullets}
-Alternatively to {\tt \{} and {\tt \}}, proofs can be structured with
-bullets. The use of a bullet $b$ for the first time focuses on the
-first goal $g$, the same bullet cannot be used again until the proof
-of $g$ is completed, then it is mandatory to focus the next goal with $b$. The
-consequence is that $g$ and all goals present when $g$ was focused are
-focused with the same bullet $b$. See the example below.
-
-Different bullets can be used to nest levels. The scope of bullet does
-not go beyond enclosing {\tt \{} and {\tt \}}, so bullets can be
-reused as further nesting levels provided they are delimited by these.
-Available bullets are {\tt -}, {\tt +}, {\tt *}, {\tt --}, {\tt ++}, {\tt **},
-{\tt ---}, {\tt +++}, {\tt ***}, ... (without a
-terminating period).
-
-Note again that when a focused goal is proved a message is displayed
-together with a suggestion about the right bullet or {\tt \}} to
-unfocus it or focus the next one.
-
-Remark: In {\ProofGeneral} (Emacs interface to {\Coq}), you must use
-bullets with the priority ordering shown above to have a correct
-indentation. For example {\tt -} must be the outer bullet and {\tt **}
-the inner one in the example below.
-
-The following example script illustrates all these features:
-\begin{coq_example*}
-Goal (((True/\True)/\True)/\True)/\True.
-Proof.
- split.
- - split.
- + split.
- ** { split.
- - trivial.
- - trivial.
- }
- ** trivial.
- + trivial.
- - assert True.
- { trivial. }
- assumption.
-\end{coq_example*}
-
-
-\begin{ErrMsgs}
-\item \errindex{Wrong bullet {\abullet}1 : Current bullet
- {\abullet}2 is not finished.}
-
- Before using bullet {\abullet}1 again, you should first finish
- proving the current focused goal. Note that {\abullet}1 and
- {\abullet}2 may be the same.
-
-\item \errindex{Wrong bullet {\abullet}1 : Bullet {\abullet}2
- is mandatory here.} You must put {\abullet}2 to focus next goal.
- No other bullet is allowed here.
-
-
-\item \errindex{No such goal. Focus next goal with bullet
- {\abullet}.}
-
- You tried to applied a tactic but no goal where under focus. Using
- {\abullet} is mandatory here.
-
-\item \errindex{No such goal. Try unfocusing with {"{\tt \}}"}.} You
- just finished a goal focused by {\tt \{}, you must unfocus it with "{\tt \}}".
-
-\end{ErrMsgs}
-
-\subsection[\tt Set Bullet Behavior.]{\tt Set Bullet Behavior.\optindex{Bullet Behavior}}
-
-The bullet behavior can be controlled by the following commands.
-
-\begin{quote}
-Set Bullet Behavior "None".
-\end{quote}
-
-This makes bullets inactive.
-
-\begin{quote}
-Set Bullet Behavior "Strict Subproofs".
-\end{quote}
-
-This makes bullets active (this is the default behavior).
-
-\section{Requesting information}
-
-\subsection[\tt Show.]{\tt Show.\comindex{Show}\label{Show}}
-This command displays the current goals.
-
-\begin{Variants}
-\item {\tt Show {\num}.}\\
- Displays only the {\num}-th subgoal.\\
-\begin{ErrMsgs}
-\item \errindex{No such goal}
-\item \errindex{No focused proof}
-\end{ErrMsgs}
-
-\item {\tt Show {\ident}.}\\
- Displays the named goal {\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{ExistentialVariables}) as in the following example.
-
-\begin{coq_eval}
-Reset Initial.
-\end{coq_eval}
-
-\begin{coq_example*}
-Goal exists n, n = 0.
- eexists ?[n].
-\end{coq_example*}
-\begin{coq_example}
- Show n.
-\end{coq_example}
-
-\item {\tt Show Script.}\comindex{Show Script}\\
- 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 \verb!<Your Tactic Text here>!.
-
-\item {\tt Show Proof.}\comindex{Show Proof}\\
-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.
-
-\item {\tt Show Conjectures.}\comindex{Show Conjectures}\\
-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.
-
-\item{\tt Show Intro.}\comindex{Show Intro}\\
-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 {\tt intro}. The aim of this command is to ease the
-writing of more robust scripts. For example, with an appropriate
-{\ProofGeneral} macro, it is possible to transform any anonymous {\tt
- intro} into a qualified one such as {\tt intro y13}.
-In the case of a non-product goal, it prints nothing.
-
-\item{\tt Show Intros.}\comindex{Show Intros}\\
-This command is similar to the previous one, it simulates the naming
-process of an {\tt intros}.
-
-\item{\tt Show Existentials.\label{ShowExistentials}}\comindex{Show Existentials}
-\\ It displays
-the set of all uninstantiated existential variables in the current proof tree,
-along with the type and the context of each variable.
-
-\item{\tt Show Match {\ident}.\label{ShowMatch}}\comindex{Show Match}\\
-This variant displays a template of the Gallina {\tt match} construct
-with a branch for each constructor of the type {\ident}.
-
-Example:
-
-\begin{coq_example}
-Show Match nat.
-\end{coq_example}
-\begin{ErrMsgs}
-\item \errindex{Unknown inductive type}
-\end{ErrMsgs}
-
-\item{\tt Show Universes.\label{ShowUniverses}}\comindex{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.
-
-\end{Variants}
-
-
-\subsection[\tt Guarded.]{\tt Guarded.\comindex{Guarded}\label{Guarded}}
-
-Some tactics (e.g. refine \ref{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 \verb!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."
-
-
-\section{Controlling the effect of proof editing commands}
-
-\subsection[\tt Set Hyps Limit {\num}.]{\tt Set Hyps Limit {\num}.\optindex{Hyps Limit}}
-This command sets the maximum number of hypotheses displayed in
-goals after the application of a tactic.
-All the hypotheses remains usable in the proof development.
-
-
-\subsection[\tt Unset Hyps Limit.]{\tt Unset Hyps Limit.\optindex{Hyps Limit}}
-This command goes back to the default mode which is to print all
-available hypotheses.
-
-
-\subsection[\tt Set Automatic Introduction.]{\tt Set Automatic Introduction.\optindex{Automatic Introduction}\label{Set Automatic Introduction}}
-
-The option {\tt Automatic Introduction} controls the way binders are
-handled in assertion commands such as {\tt Theorem {\ident}
- \zeroone{\binders} : {\form}}. When the option is set, which is the
-default, {\binders} are automatically put in the local context of the
-goal to prove.
-
-The option can be unset by issuing {\tt Unset Automatic Introduction}.
-When the option is unset, {\binders} are discharged on the statement
-to be proved and a tactic such as {\tt intro} (see
-Section~\ref{intro}) has to be used to move the assumptions to the
-local context.
-
-\section{Controlling memory usage\comindex{Optimize Proof}\comindex{Optimize Heap}}
-
-When experiencing high memory usage the following commands can be
-used to force Coq to optimize some of its internal data structures.
-
-\subsection[\tt Optimize Proof.]{\tt Optimize Proof.}
-
-This command forces Coq to shrink the data structure used to represent
-the ongoing proof.
-
-\subsection[\tt Optimize Heap.]{\tt Optimize Heap.\label{vernac-optimizeheap}}
-
-This command forces the OCaml runtime to perform a heap compaction.
-This is in general an expensive operation. See: \\
-\ \url{http://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html#VALcompact} \\
-There is also an analogous tactic {\tt optimize\_heap} (see~\ref{tactic-optimizeheap}).
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
diff --git a/doc/refman/RefMan-uti.tex b/doc/refman/RefMan-uti.tex
deleted file mode 100644
index 962aa98b6..000000000
--- a/doc/refman/RefMan-uti.tex
+++ /dev/null
@@ -1,482 +0,0 @@
-\chapter[Utilities]{Utilities\label{Utilities}}
-%HEVEA\cutname{tools.html}
-
-The distribution provides utilities to simplify some tedious works
-beside proof development, tactics writing or documentation.
-
-\section[Using Coq as a library]{Using Coq as a library}
-
-In previous versions, \texttt{coqmktop} was used to build custom
-toplevels --- for example for better debugging or custom static
-linking. Nowadays, the preferred method is to use \texttt{ocamlfind}.
-
-The most basic custom toplevel is built using:
-\begin{quotation}
-\texttt{\% ocamlfind ocamlopt -thread -rectypes -linkall -linkpkg
- -package coq.toplevel toplevel/coqtop\_bin.ml -o my\_toplevel.native}
-\end{quotation}
-
-For example, to statically link LTAC, you can just do:
-\begin{quotation}
-\texttt{\% ocamlfind ocamlopt -thread -rectypes -linkall -linkpkg
- -package coq.toplevel -package coq.ltac toplevel/coqtop\_bin.ml -o my\_toplevel.native}
-\end{quotation}
-and similarly for other plugins.
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\section[Building a \Coq\ project with {\tt coq\_makefile}]
-{Building a \Coq\ project with {\tt coq\_makefile}
-\label{Makefile}
-\ttindex{Makefile}
-\ttindex{coq\_Makefile}
-\ttindex{\_CoqProject}}
-
-The majority of \Coq\ projects are very similar: a collection of {\tt .v}
-files and eventually some {\tt .ml} ones (a \Coq\ plugin). The main piece
-of metadata needed in order to build the project are the command
-line options to {\tt coqc} (e.g. {\tt -R, -I},
-\SeeAlso Section~\ref{coqoptions}). Collecting the list of files and
-options is the job of the {\tt \_CoqProject} file.
-
-A simple example of a {\tt \_CoqProject} file follows:
-
-\begin{verbatim}
--R theories/ MyCode
-theories/foo.v
-theories/bar.v
--I src/
-src/baz.ml4
-src/bazaux.ml
-src/qux_plugin.mlpack
-\end{verbatim}
-
-Currently, both \CoqIDE{} and Proof General (version $\geq$ 4.3pre) understand
-{\tt \_CoqProject} files and invoke \Coq\ with the desired options.
-
-The {\tt coq\_makefile} utility can be used to set up a build infrastructure
-for the \Coq\ project based on makefiles. The recommended way of
-invoking {\tt coq\_makefile} is the following one:
-
-\begin{verbatim}
-coq_makefile -f _CoqProject -o CoqMakefile
-\end{verbatim}
-
-Such command generates the following files:
-\begin{description}
- \item[{\tt CoqMakefile}] is a generic makefile for GNU Make that provides targets to build the project (both {\tt .v} and {\tt .ml*} files), to install it system-wide in the {\tt coq-contrib} directory (i.e. where \Coq\ is installed) as well as to invoke {\tt coqdoc} to generate html documentation.
-
- \item[{\tt CoqMakefile.conf}] contains make variables assignments that reflect the contents of the {\tt \_CoqProject} file as well as the path relevant to \Coq{}.
-\end{description}
-
-An optional file {\bf {\tt CoqMakefile.local}} can be provided by the user in order to extend {\tt 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}.
-
-The extensions of the files listed in {\tt \_CoqProject} is
-used in order to decide how to build them. In particular:
-
-\begin{itemize}
-\item {\Coq} files must use the \texttt{.v} extension
-\item {\ocaml} files must use the \texttt{.ml} or \texttt{.mli} extension
-\item {\ocaml} files that require pre processing for syntax extensions (like {\tt VERNAC EXTEND}) must use the \texttt{.ml4} extension
-\item In order to generate a plugin one has to list all {\ocaml} modules (i.e. ``Baz'' for ``baz.ml'') in a \texttt{.mlpack} file (or \texttt{.mllib} file).
-\end{itemize}
-
-The use of \texttt{.mlpack} files has to be preferred over \texttt{.mllib}
-files, since it results in a ``packed'' plugin: All auxiliary
-modules (as {\tt Baz} and {\tt Bazaux}) are hidden inside
-the plugin's ``name space'' ({\tt Qux\_plugin}).
-This reduces the chances of begin unable to load two distinct plugins
-because of a clash in their auxiliary module names.
-
-\paragraph{CoqMakefile.local} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\label{coqmakefile:local}
-
-The optional file {\tt CoqMakefile.local} is included by the generated file
-{\tt CoqMakefile}. Such can contain two kinds of directives.
-
-\begin{description}
- \item[Variable assignment] to the variables listed in the {\tt Parameters}
- section of the generated makefile. Here we describe only few of them.
- \begin{description}
- \item[CAMLPKGS] can be used to specify third party findlib packages, and is
- passed to the OCaml compiler on building or linking of modules.
- Eg: {\tt -package yojson}.
- \item[CAMLFLAGS] can be used to specify additional flags to the OCaml
- compiler, like {\tt -bin-annot} or {\tt -w...}.
- \item[COQC, COQDEP, COQDOC] can be set in order to use alternative
- binaries (e.g. wrappers)
- \item[COQ\_SRC\_SUBDIRS] can be extended by including other paths in which {\tt *.cm*} files are searched. For example {\tt COQ\_SRC\_SUBDIRS+=user-contrib/Unicoq} lets you build a plugin containing OCaml code that depends on the OCaml code of {\tt Unicoq}.
- \end{description}
-\item[Rule extension]
- The following makefile rules can be extended. For example
-\begin{verbatim}
-pre-all::
- echo "This line is print before making the all target"
-install-extra::
- cp ThisExtraFile /there/it/goes
-\end{verbatim}
- \begin{description}
- \item[pre-all::] run before the {\tt all} target. One can use this
- to configure the project, or initialize sub modules or check
- dependencies are met.
- \item[post-all::] run after the {\tt all} target. One can use this
- to run a test suite, or compile extracted code.
- \item[install-extra::] run after {\tt install}. One can use this
- to install extra files.
- \item[install-doc::] One can use this to install extra doc.
- \item[uninstall::]
- \item[uninstall-doc::]
- \item[clean::]
- \item[cleanall::]
- \item[archclean::]
- \item[merlin-hook::] One can append lines to the generated {\tt .merlin}
- file extending this target.
- \end{description}
-\end{description}
-
-\paragraph{Timing targets and performance testing} %%%%%%%%%%%%%%%%%%%%%%%%%%%
-The generated \texttt{Makefile} supports the generation of two kinds
-of timing data: per-file build-times, and per-line times for an
-individual file.
-
-The following targets and \texttt{Makefile} variables allow collection
-of per-file timing data:
-\begin{itemize}
-\item \texttt{TIMED=1} --- passing this variable will cause
- \texttt{make} to emit a line describing the user-space build-time
- and peak memory usage for each file built.
-
- \texttt{Note}: On Mac OS, this works best if you've installed
- \texttt{gnu-time}.
-
- \texttt{Example}: For example, the output of \texttt{make TIMED=1}
- may look like this:
-\begin{verbatim}
-COQDEP Fast.v
-COQDEP Slow.v
-COQC Slow.v
-Slow (user: 0.34 mem: 395448 ko)
-COQC Fast.v
-Fast (user: 0.01 mem: 45184 ko)
-\end{verbatim}
-\item \texttt{pretty-timed} --- this target stores the output of
- \texttt{make TIMED=1} into \texttt{time-of-build.log}, and displays
- a table of the times, sorted from slowest to fastest, which is also
- stored in \texttt{time-of-build-pretty.log}. If you want to
- construct the log for targets other than the default one, you can
- pass them via the variable \texttt{TGTS}, e.g., \texttt{make
- pretty-timed TGTS="a.vo b.vo"}.
-
- \texttt{Note}: This target requires \texttt{python} to build the table.
-
- \texttt{Note}: This target will \emph{append} to the timing log; if
- you want a fresh start, you must remove the file
- \texttt{time-of-build.log} or run \texttt{make cleanall}.
-
- \texttt{Example}: For example, the output of \texttt{make
- pretty-timed} may look like this:
-\begin{verbatim}
-COQDEP Fast.v
-COQDEP Slow.v
-COQC Slow.v
-Slow (user: 0.36 mem: 393912 ko)
-COQC Fast.v
-Fast (user: 0.05 mem: 45992 ko)
-Time | File Name
---------------------
-0m00.41s | Total
---------------------
-0m00.36s | Slow
-0m00.05s | Fast
-\end{verbatim}
-\item \texttt{print-pretty-timed-diff} --- this target builds a table
- of timing changes between two compilations; run \texttt{make
- make-pretty-timed-before} to build the log of the ``before''
- times, and run \texttt{make make-pretty-timed-after} to build the
- log of the ``after'' times. The table is printed on the command
- line, and stored in \texttt{time-of-build-both.log}. This target is
- most useful for profiling the difference between two commits to a
- repo.
-
- \texttt{Note}: This target requires \texttt{python} to build the table.
-
- \texttt{Note}: The \texttt{make-pretty-timed-before} and
- \texttt{make-pretty-timed-after} targets will \emph{append} to the
- timing log; if you want a fresh start, you must remove the files
- \texttt{time-of-build-before.log} and
- \texttt{time-of-build-after.log} or run \texttt{make cleanall}
- \emph{before} building either the ``before'' or ``after'' targets.
-
- \texttt{Note}: The table will be sorted first by absolute time
- differences rounded towards zero to a whole-number of seconds, then
- by times in the ``after'' column, and finally lexicographically by
- file name. This will put the biggest changes in either direction
- first, and will prefer sorting by build-time over subsecond changes
- in build time (which are frequently noise); lexicographic sorting
- forces an order on files which take effectively no time to compile.
-
- \texttt{Example}: For example, the output table from \texttt{make
- print-pretty-timed-diff} may look like this:
-\begin{verbatim}
-After | File Name | Before || Change | % Change
---------------------------------------------------------
-0m00.39s | Total | 0m00.35s || +0m00.03s | +11.42%
---------------------------------------------------------
-0m00.37s | Slow | 0m00.01s || +0m00.36s | +3600.00%
-0m00.02s | Fast | 0m00.34s || -0m00.32s | -94.11%
-\end{verbatim}
-\end{itemize}
-
-The following targets and \texttt{Makefile} variables allow collection
-of per-line timing data:
-\begin{itemize}
-\item \texttt{TIMING=1} --- passing this variable will cause
- \texttt{make} to use \texttt{coqc -time} to write to a
- \texttt{.v.timing} file for each \texttt{.v} file compiled, which
- contains line-by-line timing information.
-
- \texttt{Example}: For example, running \texttt{make all TIMING=1} may
- result in a file like this:
-\begin{verbatim}
-Chars 0 - 26 [Require~Coq.ZArith.BinInt.] 0.157 secs (0.128u,0.028s)
-Chars 27 - 68 [Declare~Reduction~comp~:=~vm_c...] 0. secs (0.u,0.s)
-Chars 69 - 162 [Definition~foo0~:=~Eval~comp~i...] 0.153 secs (0.136u,0.019s)
-Chars 163 - 208 [Definition~foo1~:=~Eval~comp~i...] 0.239 secs (0.236u,0.s)
-\end{verbatim}
-
-\item \texttt{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 \texttt{BEFORE} and \texttt{AFTER} files, display it,
- and save it to the file specified by the
- \texttt{TIME\_OF\_PRETTY\_BUILD\_FILE} variable, which defaults to
- \texttt{time-of-build-pretty.log}.
-
- To generate the \texttt{.v.before-timing} or
- \texttt{.v.after-timing} files, you should pass
- \texttt{TIMING=before} or \texttt{TIMING=after} rather than
- \texttt{TIMING=1}.
-
- \texttt{Note}: The sorting used here is the same as in the
- \texttt{print-pretty-timed-diff} target.
-
- \texttt{Note}: This target requires \texttt{python} to build the table.
-
- \texttt{Example}: For example, running
- \texttt{print-pretty-single-time-diff} might give a table like this:
-\begin{verbatim}
-After | Code | Before || Change | % Change
----------------------------------------------------------------------------------------------------
-0m00.50s | Total | 0m04.17s || -0m03.66s | -87.96%
----------------------------------------------------------------------------------------------------
-0m00.145s | Chars 069 - 162 [Definition~foo0~:=~Eval~comp~i...] | 0m00.192s || -0m00.04s | -24.47%
-0m00.126s | Chars 000 - 026 [Require~Coq.ZArith.BinInt.] | 0m00.143s || -0m00.01s | -11.88%
- N/A | Chars 027 - 068 [Declare~Reduction~comp~:=~nati...] | 0m00.s || +0m00.00s | N/A
-0m00.s | Chars 027 - 068 [Declare~Reduction~comp~:=~vm_c...] | N/A || +0m00.00s | N/A
-0m00.231s | Chars 163 - 208 [Definition~foo1~:=~Eval~comp~i...] | 0m03.836s || -0m03.60s | -93.97%
-\end{verbatim}
-
-\item \texttt{all.timing.diff}, \texttt{path/to/file.v.timing.diff}
- --- The \texttt{path/to/file.v.timing.diff} target will make a
- \texttt{.v.timing.diff} file for the corresponding \texttt{.v} file,
- with a table as would be generated by the
- \texttt{print-pretty-single-time-diff} target; it depends on having
- already made the corresponding \texttt{.v.before-timing} and
- \texttt{.v.after-timing} files, which can be made by passing
- \texttt{TIMING=before} and \texttt{TIMING=after}. The
- \texttt{all.timing.diff} target will make such timing difference
- files for all of the \texttt{.v} files that the \texttt{Makefile}
- knows about. It will fail if some \texttt{.v.before-timing} or
- \texttt{.v.after-timing} files don't exist.
-
- \texttt{Note}: This target requires \texttt{python} to build the table.
-\end{itemize}
-
-\paragraph{Reusing/extending the generated Makefile} %%%%%%%%%%%%%%%%%%%%%%%%%
-
-Including the generated makefile with an {\tt include} directive is discouraged.
-The contents of this file, including variable names
-and status of rules shall change in the future. Users are advised to
-include {\tt Makefile.conf} or call a target of the generated Makefile
-as in {\tt make -f Makefile target} from another Makefile.
-
-One way to get access to all targets of the generated
-\texttt{CoqMakefile} is to have a generic target for invoking unknown
-targets. For example:
-\begin{verbatim}
-# KNOWNTARGETS will not be passed along to CoqMakefile
-KNOWNTARGETS := CoqMakefile extra-stuff extra-stuff2
-# KNOWNFILES will not get implicit targets from the final rule, and so
-# depending on them won't invoke the submake
-# Warning: These files get declared as PHONY, so any targets depending
-# on them always get rebuilt
-KNOWNFILES := Makefile _CoqProject
-
-.DEFAULT_GOAL := invoke-coqmakefile
-
-CoqMakefile: Makefile _CoqProject
- $(COQBIN)coq_makefile -f _CoqProject -o CoqMakefile
-
-invoke-coqmakefile: CoqMakefile
- $(MAKE) --no-print-directory -f CoqMakefile $(filter-out $(KNOWNTARGETS),$(MAKECMDGOALS))
-
-.PHONY: invoke-coqmakefile $(KNOWNFILES)
-
-####################################################################
-## Your targets here ##
-####################################################################
-
-# This should be the last rule, to handle any targets not declared above
-%: invoke-coqmakefile
- @true
-\end{verbatim}
-
-\paragraph{Building a subset of the targets with -j} %%%%%%%%%%%%%%%%%%%%%%%%%
-
-To build, say, two targets \texttt{foo.vo} and \texttt{bar.vo}
-in parallel one can use \texttt{make only TGTS="foo.vo bar.vo" -j}.
-
-Note that \texttt{make foo.vo bar.vo -j} has a different meaning for
-the make utility, in particular it may build a shared prerequisite twice.
-
-\paragraph{Notes for users of {\tt coq\_makefile} with version $<$ 8.7} %%%%%%
-
-\begin{itemize}
-\item Support for ``sub-directory'' is deprecated. To perform actions before
- or after the build (like invoking make on a subdirectory) one can
- hook in {\tt pre-all} and {\tt post-all} extension points
-\item \texttt{-extra-phony} and \texttt{-extra} are deprecated. To provide
- additional target ({\tt .PHONY} or not) please use
- {\tt CoqMakefile.local}
-\end{itemize}
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\section[Modules dependencies]{Modules dependencies\label{Dependencies}\index{Dependencies}
- \ttindex{coqdep}}
-
-In order to compute modules dependencies (so to use {\tt make}),
-\Coq\ comes with an appropriate tool, {\tt coqdep}.
-
-{\tt coqdep} computes inter-module dependencies for \Coq\ and
-\ocaml\ programs, and prints the dependencies on the standard
-output in a format readable by make. When a directory is given as
-argument, it is recursively looked at.
-
-Dependencies of \Coq\ modules are computed by looking at {\tt Require}
-commands ({\tt Require}, {\tt Requi\-re Export}, {\tt Require Import},
-but also at the command {\tt Declare ML Module}.
-
-Dependencies of \ocaml\ modules are computed by looking at
-\verb!open! commands and the dot notation {\em module.value}. However,
-this is done approximately and you are advised to use {\tt ocamldep}
-instead for the \ocaml\ modules dependencies.
-
-See the man page of {\tt coqdep} for more details and options.
-
-The build infrastructure generated by {\tt coq\_makefile}
-uses {\tt coqdep} to automatically compute the dependencies
-among the files part of the project.
-
-\section[Documenting \Coq\ files with coqdoc]{Documenting \Coq\ files with coqdoc\label{coqdoc}
-\ttindex{coqdoc}}
-
-\input{./coqdoc}
-
-\section[Embedded \Coq\ phrases inside \LaTeX\ documents]{Embedded \Coq\ phrases inside \LaTeX\ documents\label{Latex}
- \ttindex{coq-tex}\index{Latex@{\LaTeX}}}
-
-When writing a documentation about a proof development, one may want
-to insert \Coq\ phrases inside a \LaTeX\ document, possibly together with
-the corresponding answers of the system. We provide a
-mechanical way to process such \Coq\ phrases embedded in \LaTeX\ files: the
-{\tt coq-tex} filter. This filter extracts Coq phrases embedded in
-LaTeX files, evaluates them, and insert the outcome of the evaluation
-after each phrase.
-
-Starting with a file {\em file}{\tt.tex} containing \Coq\ phrases,
-the {\tt coq-tex} filter produces a file named {\em file}{\tt.v.tex} with
-the \Coq\ outcome.
-
-There are options to produce the \Coq\ parts in smaller font, italic,
-between horizontal rules, etc.
-See the man page of {\tt coq-tex} for more details.
-
-\medskip\noindent {\bf Remark.} This Reference Manual and the Tutorial
-have been completely produced with {\tt coq-tex}.
-
-
-\section[\Coq\ and \emacs]{\Coq\ and \emacs\label{Emacs}\index{Emacs}}
-
-\subsection{The \Coq\ Emacs mode}
-
-\Coq\ comes with a Major mode for \emacs, {\tt gallina.el}. This mode provides
-syntax highlighting
-and also a rudimentary indentation facility
-in the style of the Caml \emacs\ mode.
-
-Add the following lines to your \verb!.emacs! file:
-
-\begin{verbatim}
- (setq auto-mode-alist (cons '("\\.v$" . coq-mode) auto-mode-alist))
- (autoload 'coq-mode "gallina" "Major mode for editing Coq vernacular." t)
-\end{verbatim}
-
-The \Coq\ major mode is triggered by visiting a file with extension {\tt .v},
-or manually with the command \verb!M-x coq-mode!.
-It gives you the correct syntax table for
-the \Coq\ language, and also a rudimentary indentation facility:
-\begin{itemize}
- \item pressing {\sc Tab} at the beginning of a line indents the line like
- the line above;
-
- \item extra {\sc Tab}s increase the indentation level
- (by 2 spaces by default);
-
- \item M-{\sc Tab} decreases the indentation level.
-\end{itemize}
-
-An inferior mode to run \Coq\ under Emacs, by Marco Maggesi, is also
-included in the distribution, in file \texttt{inferior-coq.el}.
-Instructions to use it are contained in this file.
-
-\subsection[{\ProofGeneral}]{{\ProofGeneral}\index{Proof General@{\ProofGeneral}}}
-
-{\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 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 \Coq. It is freely available at \verb!https://proofgeneral.github.io/!.
-
-
-\section[Module specification]{Module specification\label{gallina}\ttindex{gallina}}
-
-Given a \Coq\ vernacular file, the {\tt gallina} filter extracts its
-specification (inductive types declarations, definitions, type of
-lemmas and theorems), removing the proofs parts of the file. The \Coq\
-file {\em file}{\tt.v} gives birth to the specification file
-{\em file}{\tt.g} (where the suffix {\tt.g} stands for \gallina).
-
-See the man page of {\tt gallina} for more details and options.
-
-
-\section[Man pages]{Man pages\label{ManPages}\index{Man pages}}
-
-There are man pages for the commands {\tt coqdep}, {\tt gallina} and
-{\tt coq-tex}. Man pages are installed at installation time
-(see installation instructions in file {\tt INSTALL}, step 6).
-
-%BEGIN LATEX
-\RefManCutCommand{ENDREFMAN=\thepage}
-%END LATEX
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: t
-%%% End:
diff --git a/doc/refman/Reference-Manual.tex b/doc/refman/Reference-Manual.tex
deleted file mode 100644
index 86f123322..000000000
--- a/doc/refman/Reference-Manual.tex
+++ /dev/null
@@ -1,153 +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-oth.v}% Vernacular commands
-\include{RefMan-pro.v}% Proof handling
-\include{RefMan-ltac.v}% Writing tactics
-
-\lstset{language=SSR}
-\lstset{moredelim=[is][]{|*}{*|}}
-\lstset{moredelim=*[is][\itshape\rmfamily]{/*}{*/}}
-
-\part{User extensions}
-%%SUPPRIME \include{RefMan-tus.v}% Writing tactics
-
-\part{Practical tools}
-\include{RefMan-uti}% utilities (gallina, do_Makefile, etc)
-
-%BEGIN LATEX
-\RefManCutCommand{BEGINADDENDUM=\thepage}
-%END LATEX
-\part{Addendum to the Reference Manual}
-\include{AddRefMan-pre}%
-\include{Coercion.v}%
-\include{Classes.v}%
-\include{Extraction.v}%
-\include{Program.v}%
-\include{Polynom.v}% = Ring
-\include{Nsatz.v}%
-\include{Setoid.v}% Tactique pour les setoides
-\include{AsyncProofs}% Paral-ITP
-\include{Universes.v}% Universe polymorphes
-\include{Misc.v}
-%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/Setoid.tex b/doc/refman/Setoid.tex
deleted file mode 100644
index b7b343112..000000000
--- a/doc/refman/Setoid.tex
+++ /dev/null
@@ -1,842 +0,0 @@
-\newtheorem{cscexample}{Example}
-
-\achapter{\protect{Generalized rewriting}}
-%HEVEA\cutname{setoid.html}
-\aauthor{Matthieu Sozeau}
-\label{setoids}
-
-This chapter presents the extension of several equality related tactics
-to work over user-defined structures (called setoids) that are equipped
-with ad-hoc equivalence relations meant to behave as equalities.
-Actually, the tactics have also been generalized to relations weaker
-then equivalences (e.g. rewriting systems). The toolbox also extends the
-automatic rewriting capabilities of the system, allowing the specification of
-custom strategies for rewriting.
-
-This documentation is adapted from the previous setoid documentation by
-Claudio Sacerdoti Coen (based on previous work by Cl\'ement Renard).
-The new implementation is a drop-in replacement for the old one,\footnote{Nicolas
-Tabareau helped with the gluing.} hence most of the documentation still applies.
-
-The work is a complete rewrite of the previous implementation, based on
-the type class infrastructure. It also improves on and generalizes
-the previous implementation in several ways:
-\begin{itemize}
-\item User-extensible algorithm. The algorithm is separated in two
- parts: generations of the rewriting constraints (done in ML) and
- solving of these constraints using type class resolution. As type
- class resolution is extensible using tactics, this allows users to define
- general ways to solve morphism constraints.
-\item Sub-relations. An example extension to the base algorithm is the
- ability to define one relation as a subrelation of another so that
- morphism declarations on one relation can be used automatically for
- the other. This is done purely using tactics and type class search.
-\item Rewriting under binders. It is possible to rewrite under binders
- in the new implementation, if one provides the proper
- morphisms. Again, most of the work is handled in the tactics.
-\item First-class morphisms and signatures. Signatures and morphisms are
- ordinary Coq terms, hence they can be manipulated inside Coq, put
- inside structures and lemmas about them can be proved inside the
- system. Higher-order morphisms are also allowed.
-\item Performance. The implementation is based on a depth-first search for the first
- solution to a set of constraints which can be as fast as linear in the
- size of the term, and the size of the proof term is linear
- in the size of the original term. Besides, the extensibility allows the
- user to customize the proof search if necessary.
-\end{itemize}
-
-\asection{Introduction to generalized rewriting}
-
-\subsection{Relations and morphisms}
-
-A parametric \emph{relation} \texttt{R} is any term of type
-\texttt{forall ($x_1$:$T_1$) \ldots ($x_n$:$T_n$), relation $A$}. The
-expression $A$, which depends on $x_1$ \ldots $x_n$, is called the
-\emph{carrier} of the relation and \texttt{R} is
-said to be a relation over \texttt{A}; the list $x_1,\ldots,x_n$
-is the (possibly empty) list of parameters of the relation.
-
-\firstexample
-\begin{cscexample}[Parametric relation]
-It is possible to implement finite sets of elements of type \texttt{A}
-as unordered list of elements of type \texttt{A}. The function
-\texttt{set\_eq: forall (A: Type), relation (list A)} satisfied by two lists
-with the same elements is a parametric relation over \texttt{(list A)} with
-one parameter \texttt{A}. The type of \texttt{set\_eq} is convertible with
-\texttt{forall (A: Type), list A -> list A -> Prop}.
-\end{cscexample}
-
-An \emph{instance} of a parametric relation \texttt{R} with $n$ parameters
-is any term \texttt{(R $t_1$ \ldots $t_n$)}.
-
-Let \texttt{R} be a relation over \texttt{A} with $n$ parameters.
-A term is a parametric proof of reflexivity for \texttt{R} if it has type
-\texttt{forall ($x_1$:$T_1$) \ldots ($x_n$:$T_n$),
- reflexive (R $x_1$ \ldots $x_n$)}. Similar definitions are given for
-parametric proofs of symmetry and transitivity.
-
-\begin{cscexample}[Parametric relation (cont.)]
-The \texttt{set\_eq} relation of the previous example can be proved to be
-reflexive, symmetric and transitive.
-\end{cscexample}
-
-A parametric unary function $f$ of type
-\texttt{forall ($x_1$:$T_1$) \ldots ($x_n$:$T_n$), $A_1$ -> $A_2$}
-covariantly respects two parametric relation instances $R_1$ and $R_2$ if,
-whenever $x, y$ satisfy $R_1~x~y$, their images $(f~x)$ and $(f~y)$
-satisfy $R_2~(f~x)~(f~y)$ . An $f$ that respects its input and output relations
-will be called a unary covariant \emph{morphism}. We can also say that $f$ is
-a monotone function with respect to $R_1$ and $R_2$.
-The sequence $x_1,\ldots x_n$ represents the parameters of the morphism.
-
-Let $R_1$ and $R_2$ be two parametric relations.
-The \emph{signature} of a parametric morphism of type
-\texttt{forall ($x_1$:$T_1$) \ldots ($x_n$:$T_n$), $A_1$ -> $A_2$} that
-covariantly respects two instances $I_{R_1}$ and $I_{R_2}$ of $R_1$ and $R_2$ is written $I_{R_1} \texttt{++>} I_{R_2}$.
-Notice that the special arrow \texttt{++>}, which reminds the reader
-of covariance, is placed between the two relation instances, not
-between the two carriers. The signature relation instances and morphism will
-be typed in a context introducing variables for the parameters.
-
-The previous definitions are extended straightforwardly to $n$-ary morphisms,
-that are required to be simultaneously monotone on every argument.
-
-Morphisms can also be contravariant in one or more of their arguments.
-A morphism is contravariant on an argument associated to the relation instance
-$R$ if it is covariant on the same argument when the inverse relation
-$R^{-1}$ (\texttt{inverse R} in Coq) is considered.
-The special arrow \texttt{-{}->} is used in signatures
-for contravariant morphisms.
-
-Functions having arguments related by symmetric relations instances are both
-covariant and contravariant in those arguments. The special arrow
-\texttt{==>} is used in signatures for morphisms that are both covariant
-and contravariant.
-
-An instance of a parametric morphism $f$ with $n$ parameters is any term
-\texttt{f $t_1$ \ldots $t_n$}.
-
-\begin{cscexample}[Morphisms]
-Continuing the previous example, let
-\texttt{union: forall (A: Type), list A -> list A -> list A} perform the union
-of two sets by appending one list to the other. \texttt{union} is a binary
-morphism parametric over \texttt{A} that respects the relation instance
-\texttt{(set\_eq A)}. The latter condition is proved by showing
-\texttt{forall (A: Type) (S1 S1' S2 S2': list A), set\_eq A S1 S1' ->
- set\_eq A S2 S2' -> set\_eq A (union A S1 S2) (union A S1' S2')}.
-
-The signature of the function \texttt{union A} is
-\texttt{set\_eq A ==> set\_eq A ==> set\_eq A} for all \texttt{A}.
-\end{cscexample}
-
-\begin{cscexample}[Contravariant morphism]
-The division function \texttt{Rdiv: R -> R -> R} is a morphism of
-signature \texttt{le ++> le -{}-> le} where \texttt{le} is
-the usual order relation over real numbers. Notice that division is
-covariant in its first argument and contravariant in its second
-argument.
-\end{cscexample}
-
-Leibniz equality is a relation and every function is a
-morphism that respects Leibniz equality. Unfortunately, Leibniz equality
-is not always the intended equality for a given structure.
-
-In the next section we will describe the commands to register terms as
-parametric relations and morphisms. Several tactics that deal with equality
-in \Coq\ can also work with the registered relations.
-The exact list of tactic will be given in Sect.~\ref{setoidtactics}.
-For instance, the
-tactic \texttt{reflexivity} can be used to close a goal $R~n~n$ whenever
-$R$ is an instance of a registered reflexive relation. However, the tactics
-that replace in a context $C[]$ one term with another one related by $R$
-must verify that $C[]$ is a morphism that respects the intended relation.
-Currently the verification consists in checking whether $C[]$ is a syntactic
-composition of morphism instances that respects some obvious
-compatibility constraints.
-
-\begin{cscexample}[Rewriting]
-Continuing the previous examples, suppose that the user must prove
-\texttt{set\_eq int (union int (union int S1 S2) S2) (f S1 S2)} under the
-hypothesis \texttt{H: set\_eq int S2 (@nil int)}. It is possible to
-use the \texttt{rewrite} tactic to replace the first two occurrences of
-\texttt{S2} with \texttt{@nil int} in the goal since the context
-\texttt{set\_eq int (union int (union int S1 nil) nil) (f S1 S2)}, being
-a composition of morphisms instances, is a morphism. However the tactic
-will fail replacing the third occurrence of \texttt{S2} unless \texttt{f}
-has also been declared as a morphism.
-\end{cscexample}
-
-\subsection{Adding new relations and morphisms}
-A parametric relation
-\textit{Aeq}\texttt{: forall ($y_1 : \beta_!$ \ldots $y_m : \beta_m$), relation (A $t_1$ \ldots $t_n$)} over
-\textit{(A : $\alpha_i$ -> \ldots $\alpha_n$ -> }\texttt{Type})
-can be declared with the following command:
-
-\comindex{Add Parametric Relation}
-\begin{quote}
- \texttt{Add Parametric Relation} ($x_1 : T_1$) \ldots ($x_n : T_k$) :
- \textit{(A $t_1$ \ldots $t_n$) (Aeq $t'_1$ \ldots $t'_m$)}\\
- ~\zeroone{\texttt{reflexivity proved by} \textit{refl}}\\
- ~\zeroone{\texttt{symmetry proved by} \textit{sym}}\\
- ~\zeroone{\texttt{transitivity proved by} \textit{trans}}\\
- \texttt{~as} \textit{id}.
-\end{quote}
-after having required the \texttt{Setoid} module with the
-\texttt{Require Setoid} command.
-
-The identifier \textit{id} gives a unique name to the morphism and it is
-used by the command to generate fresh names for automatically provided lemmas
-used internally.
-
-Notice that the carrier and relation parameters may refer to the context
-of variables introduced at the beginning of the declaration, but the
-instances need not be made only of variables.
-Also notice that \textit{A} is \emph{not} required to be a term
-having the same parameters as \textit{Aeq}, although that is often the
-case in practice (this departs from the previous implementation).
-
-\comindex{Add Relation}
-In case the carrier and relations are not parametric, one can use the
-command \texttt{Add Relation} instead, whose syntax is the same except
-there is no local context.
-
-The proofs of reflexivity, symmetry and transitivity can be omitted if the
-relation is not an equivalence relation. The proofs must be instances of the
-corresponding relation definitions: e.g. the proof of reflexivity must
-have a type convertible to \texttt{reflexive (A $t_1$ \ldots $t_n$) (Aeq $t'_1$ \ldots
- $t'_n$)}. Each proof may refer to the introduced variables as well.
-
-\begin{cscexample}[Parametric relation]
-For Leibniz equality, we may declare:
-\texttt{Add Parametric Relation (A : Type) :} \texttt{A (@eq A)}\\
-~\zeroone{\texttt{reflexivity proved by} \texttt{@refl\_equal A}}\\
-\ldots
-\end{cscexample}
-
-Some tactics
-(\texttt{reflexivity}, \texttt{symmetry}, \texttt{transitivity}) work only
-on relations that respect the expected properties. The remaining tactics
-(\texttt{replace}, \texttt{rewrite} and derived tactics such as
-\texttt{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.
-
-\comindex{Add Parametric Morphism}
-\begin{quote}
- \texttt{Add Parametric Morphism} ($x_1 : \T_1$) \ldots ($x_k : \T_k$) :
- (\textit{f $t_1$ \ldots $t_n$})\\
- \texttt{~with signature} \textit{sig}\\
- \texttt{~as id}.\\
- \texttt{Proof}\\
- ~\ldots\\
- \texttt{Qed}
-\end{quote}
-
-The command declares \textit{f} as a parametric morphism of signature
-\textit{sig}. The identifier \textit{id} gives a unique name to the morphism
-and it is used as the base name of the type class instance definition
-and as the name of the lemma that proves the well-definedness of the morphism.
-The parameters of the morphism as well as the signature may refer to the
-context of variables.
-The command asks the user to prove interactively that \textit{f} respects
-the relations identified from the signature.
-
-\begin{cscexample}
-We start the example by assuming a small theory over homogeneous sets and
-we declare set equality as a parametric equivalence relation and
-union of two sets as a parametric morphism.
-\begin{coq_example*}
-Require Export Setoid.
-Require Export Relation_Definitions.
-Set Implicit Arguments.
-Parameter set: Type -> Type.
-Parameter empty: forall A, set A.
-Parameter eq_set: forall A, set A -> set A -> Prop.
-Parameter union: forall A, set A -> set A -> set A.
-Axiom eq_set_refl: forall A, reflexive _ (eq_set (A:=A)).
-Axiom eq_set_sym: forall A, symmetric _ (eq_set (A:=A)).
-Axiom eq_set_trans: forall A, transitive _ (eq_set (A:=A)).
-Axiom empty_neutral: forall A (S: set A), eq_set (union S (empty A)) S.
-Axiom union_compat:
- forall (A : Type),
- forall x x' : set A, eq_set x x' ->
- forall y y' : set A, eq_set y y' ->
- eq_set (union x y) (union x' y').
-Add Parametric Relation A : (set A) (@eq_set A)
- reflexivity proved by (eq_set_refl (A:=A))
- symmetry proved by (eq_set_sym (A:=A))
- transitivity proved by (eq_set_trans (A:=A))
- as eq_set_rel.
-Add Parametric Morphism A : (@union A) with
-signature (@eq_set A) ==> (@eq_set A) ==> (@eq_set A) as union_mor.
-Proof. exact (@union_compat A). Qed.
-\end{coq_example*}
-
-\end{cscexample}
-
-It is possible to reduce the burden of specifying parameters using
-(maximally inserted) implicit arguments. If \texttt{A} is always set as
-maximally implicit in the previous example, one can write:
-
-\begin{coq_eval}
-Reset Initial.
-Require Export Setoid.
-Require Export Relation_Definitions.
-Parameter set: Type -> Type.
-Parameter empty: forall {A}, set A.
-Parameter eq_set: forall {A}, set A -> set A -> Prop.
-Parameter union: forall {A}, set A -> set A -> set A.
-Axiom eq_set_refl: forall {A}, reflexive (set A) eq_set.
-Axiom eq_set_sym: forall {A}, symmetric (set A) eq_set.
-Axiom eq_set_trans: forall {A}, transitive (set A) eq_set.
-Axiom empty_neutral: forall A (S: set A), eq_set (union S empty) S.
-Axiom union_compat:
- forall (A : Type),
- forall x x' : set A, eq_set x x' ->
- forall y y' : set A, eq_set y y' ->
- eq_set (union x y) (union x' y').
-\end{coq_eval}
-
-\begin{coq_example*}
-Add Parametric Relation A : (set A) eq_set
- reflexivity proved by eq_set_refl
- symmetry proved by eq_set_sym
- transitivity proved by eq_set_trans
- as eq_set_rel.
-Add Parametric Morphism A : (@union A) with
- signature eq_set ==> eq_set ==> eq_set as union_mor.
-Proof. exact (@union_compat A). Qed.
-\end{coq_example*}
-
-We proceed now by proving a simple lemma performing a rewrite step
-and then applying reflexivity, as we would do working with Leibniz
-equality. Both tactic applications are accepted
-since the required properties over \texttt{eq\_set} and
-\texttt{union} can be established from the two declarations above.
-
-\begin{coq_example*}
-Goal forall (S: set nat),
- eq_set (union (union S empty) S) (union S S).
-Proof. intros. rewrite empty_neutral. reflexivity. Qed.
-\end{coq_example*}
-
-The tables of relations and morphisms are managed by the type class
-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
-\texttt{Existing Instance} command to do so outside the section,
-using the name of the declared morphism suffixed by \texttt{\_Morphism},
-or use the \texttt{Global} modifier for the corresponding class instance
-declaration (see \S\ref{setoid:first-class}) at definition time.
-When loading a compiled file or importing a module,
-all the declarations of this module will be loaded.
-
-\subsection{Rewriting and non reflexive relations}
-To replace only one argument of an n-ary morphism it is necessary to prove
-that all the other arguments are related to themselves by the respective
-relation instances.
-
-\begin{cscexample}
-To replace \texttt{(union S empty)} with \texttt{S} in
-\texttt{(union (union S empty) S) (union S S)} the rewrite tactic must
-exploit the monotony of \texttt{union} (axiom \texttt{union\_compat} in
-the previous example). Applying \texttt{union\_compat} by hand we are left
-with the goal \texttt{eq\_set (union S S) (union S S)}.
-\end{cscexample}
-
-When the relations associated to some arguments are not reflexive, the tactic
-cannot automatically prove the reflexivity goals, that are left to the user.
-
-Setoids whose relation are partial equivalence relations (PER)
-are useful to deal with partial functions. Let \texttt{R} be a PER. We say
-that an element \texttt{x} is defined if \texttt{R x x}. A partial function
-whose domain comprises all the defined elements only is declared as a
-morphism that respects \texttt{R}. Every time a rewriting step is performed
-the user must prove that the argument of the morphism is defined.
-
-\begin{cscexample}
-Let \texttt{eqO} be \texttt{fun x y => x = y $\land$ ~x$\neq$ 0} (the smaller PER over
-non zero elements). Division can be declared as a morphism of signature
-\texttt{eq ==> eq0 ==> eq}. Replace \texttt{x} with \texttt{y} in
-\texttt{div x n = div y n} opens the additional goal \texttt{eq0 n n} that
-is equivalent to \texttt{n=n $\land$ n$\neq$0}.
-\end{cscexample}
-
-\subsection{Rewriting and non symmetric relations}
-When the user works up to relations that are not symmetric, it is no longer
-the case that any covariant morphism argument is also contravariant. As a
-result it is no longer possible to replace a term with a related one in
-every context, since the obtained goal implies the previous one if and
-only if the replacement has been performed in a contravariant position.
-In a similar way, replacement in an hypothesis can be performed only if
-the replaced term occurs in a covariant position.
-
-\begin{cscexample}[Covariance and contravariance]
-Suppose that division over real numbers has been defined as a
-morphism of signature \texttt{Z.div: Z.lt ++> Z.lt -{}-> Z.lt} (i.e.
-\texttt{Z.div} is increasing in its first argument, but decreasing on the
-second one). Let \texttt{<} denotes \texttt{Z.lt}.
-Under the hypothesis \texttt{H: x < y} we have
-\texttt{k < x / y -> k < x / x}, but not
-\texttt{k < y / x -> k < x / x}.
-Dually, under the same hypothesis \texttt{k < x / y -> k < y / y} holds,
-but \texttt{k < y / x -> k < y / y} does not.
-Thus, if the current goal is \texttt{k < x / x}, it is possible to replace
-only the second occurrence of \texttt{x} (in contravariant position)
-with \texttt{y} since the obtained goal must imply the current one.
-On the contrary, if \texttt{k < x / x} is
-an hypothesis, it is possible to replace only the first occurrence of
-\texttt{x} (in covariant position) with \texttt{y} since
-the current hypothesis must imply the obtained one.
-\end{cscexample}
-
-Contrary to the previous implementation, no specific error message will
-be raised when trying to replace a term that occurs in the wrong
-position. It will only fail because the rewriting constraints are not
-satisfiable. However it is possible to use the \texttt{at} modifier to
-specify which occurrences should be rewritten.
-
-As expected, composing morphisms together propagates the variance annotations by
-switching the variance every time a contravariant position is traversed.
-\begin{cscexample}
-Let us continue the previous example and let us consider the goal
-\texttt{x / (x / x) < k}. The first and third occurrences of \texttt{x} are
-in a contravariant position, while the second one is in covariant position.
-More in detail, the second occurrence of \texttt{x} occurs
-covariantly in \texttt{(x / x)} (since division is covariant in its first
-argument), and thus contravariantly in \texttt{x / (x / x)} (since division
-is contravariant in its second argument), and finally covariantly in
-\texttt{x / (x / x) < k} (since \texttt{<}, as every transitive relation,
-is contravariant in its first argument with respect to the relation itself).
-\end{cscexample}
-
-\subsection{Rewriting in ambiguous setoid contexts}
-One function can respect several different relations and thus it can be
-declared as a morphism having multiple signatures.
-
-\begin{cscexample}
-Union over homogeneous lists can be given all the following signatures:
-\texttt{eq ==> eq ==> eq} (\texttt{eq} being the equality over ordered lists)
-\texttt{set\_eq ==> set\_eq ==> set\_eq} (\texttt{set\_eq} being the equality
-over unordered lists up to duplicates),
-\texttt{multiset\_eq ==> multiset\_eq ==> multiset\_eq} (\texttt{multiset\_eq}
-being the equality over unordered lists).
-\end{cscexample}
-
-To declare multiple signatures for a morphism, repeat the \texttt{Add Morphism}
-command.
-
-When morphisms have multiple signatures it can be the case that a rewrite
-request is ambiguous, since it is unclear what relations should be used to
-perform the rewriting. Contrary to the previous implementation, the
-tactic will always choose the first possible solution to the set of
-constraints generated by a rewrite and will not try to find \emph{all}
-possible solutions to warn the user about.
-
-\asection{Commands and tactics}
-\subsection{First class setoids and morphisms}
-\label{setoid:first-class}
-
-The implementation is based on a first-class representation of
-properties of relations and morphisms as type classes. That is,
-the various combinations of properties on relations and morphisms
-are represented as records and instances of theses classes are put
-in a hint database.
-For example, the declaration:
-
-\begin{quote}
- \texttt{Add Parametric Relation} ($x_1 : T_1$) \ldots ($x_n : T_k$) :
- \textit{(A $t_1$ \ldots $t_n$) (Aeq $t'_1$ \ldots $t'_m$)}\\
- ~\zeroone{\texttt{reflexivity proved by} \textit{refl}}\\
- ~\zeroone{\texttt{symmetry proved by} \textit{sym}}\\
- ~\zeroone{\texttt{transitivity proved by} \textit{trans}}\\
- \texttt{~as} \textit{id}.
-\end{quote}
-
-is equivalent to an instance declaration:
-
-\begin{quote}
- \texttt{Instance} ($x_1 : T_1$) \ldots ($x_n : T_k$) \texttt{=>}
- \textit{id} : \texttt{@Equivalence} \textit{(A $t_1$ \ldots $t_n$) (Aeq
- $t'_1$ \ldots $t'_m$)} :=\\
- ~\zeroone{\texttt{Equivalence\_Reflexive :=} \textit{refl}}\\
- ~\zeroone{\texttt{Equivalence\_Symmetric :=} \textit{sym}}\\
- ~\zeroone{\texttt{Equivalence\_Transitive :=} \textit{trans}}.
-\end{quote}
-
-The declaration itself amounts to the definition of an object of the
-record type \texttt{Coq.Classes.RelationClasses.Equivalence} and a
-hint added to the \texttt{typeclass\_instances} hint database.
-Morphism declarations are also instances of a type class defined in
-\texttt{Classes.Morphisms}.
-See the documentation on type classes \ref{typeclasses} and
-the theories files in \texttt{Classes} for further explanations.
-
-One can inform the rewrite tactic about morphisms and relations just by
-using the typeclass mechanism to declare them using \texttt{Instance}
-and \texttt{Context} vernacular commands.
-Any object of type \texttt{Proper} (the type of morphism declarations)
-in the local context will also be automatically used by the rewriting
-tactic to solve constraints.
-
-Other representations of first class setoids and morphisms can also
-be handled by encoding them as records. In the following example,
-the projections of the setoid relation and of the morphism function
-can be registered as parametric relations and morphisms.
-\begin{cscexample}[First class setoids]
-
-\begin{coq_example*}
-Require Import Relation_Definitions Setoid.
-Record Setoid: Type :=
-{ car:Type;
- eq:car->car->Prop;
- refl: reflexive _ eq;
- sym: symmetric _ eq;
- trans: transitive _ eq
-}.
-Add Parametric Relation (s : Setoid) : (@car s) (@eq s)
- reflexivity proved by (refl s)
- symmetry proved by (sym s)
- transitivity proved by (trans s) as eq_rel.
-Record Morphism (S1 S2:Setoid): Type :=
-{ f:car S1 ->car S2;
- compat: forall (x1 x2: car S1), eq S1 x1 x2 -> eq S2 (f x1) (f x2) }.
-Add Parametric Morphism (S1 S2 : Setoid) (M : Morphism S1 S2) :
- (@f S1 S2 M) with signature (@eq S1 ==> @eq S2) as apply_mor.
-Proof. apply (compat S1 S2 M). Qed.
-Lemma test: forall (S1 S2:Setoid) (m: Morphism S1 S2)
- (x y: car S1), eq S1 x y -> eq S2 (f _ _ m x) (f _ _ m y).
-Proof. intros. rewrite H. reflexivity. Qed.
-\end{coq_example*}
-\end{cscexample}
-
-\subsection{Tactics enabled on user provided relations}
-\label{setoidtactics}
-The following tactics, all prefixed by \texttt{setoid\_},
-deal with arbitrary
-registered relations and morphisms. Moreover, all the corresponding unprefixed
-tactics (i.e. \texttt{reflexivity}, \texttt{symmetry}, \texttt{transitivity},
-\texttt{replace}, \texttt{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
-\texttt{using relation}.
-\medskip
-
-\tacindex{setoid\_reflexivity}
-\texttt{setoid\_reflexivity}
-
-\tacindex{setoid\_symmetry}
-\texttt{setoid\_symmetry} \zeroone{\texttt{in} \textit{ident}}
-
-\tacindex{setoid\_transitivity}
-\texttt{setoid\_transitivity}
-
-\tacindex{setoid\_rewrite}
-\texttt{setoid\_rewrite} \zeroone{\textit{orientation}} \textit{term}
-~\zeroone{\texttt{at} \textit{occs}} ~\zeroone{\texttt{in} \textit{ident}}
-
-\tacindex{setoid\_replace}
-\texttt{setoid\_replace} \textit{term} \texttt{with} \textit{term}
-~\zeroone{\texttt{in} \textit{ident}}
-~\zeroone{\texttt{using relation} \textit{term}}
-~\zeroone{\texttt{by} \textit{tactic}}
-\medskip
-
-The \texttt{using relation}
-arguments cannot be passed to the unprefixed form. The latter argument
-tells the tactic what parametric relation should be used to replace
-the first tactic argument with the second one. If omitted, it defaults
-to the \texttt{DefaultRelation} instance on the type of the objects.
-By default, it means the most recent \texttt{Equivalence} instance in
-the environment, but it can be customized by declaring new
-\texttt{DefaultRelation} instances. As Leibniz equality is a declared
-equivalence, it will fall back to it if no other relation is declared 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 \texttt{autorewrite} that are
-not proof of Leibniz equalities. In particular it is possible to exploit
-\texttt{autorewrite} to simulate normalization in a term rewriting system
-up to user defined equalities.
-
-\subsection{Printing relations and morphisms}
-The \texttt{Print Instances} command can be used to show the list of
-currently registered \texttt{Reflexive} (using \texttt{Print Instances Reflexive}),
-\texttt{Symmetric} or \texttt{Transitive} relations,
-\texttt{Equivalence}s, \texttt{PreOrder}s, \texttt{PER}s, and
-Morphisms (implemented as \texttt{Proper} instances). When
- the rewriting tactics refuse to replace a term in a context
-because the latter is not a composition of morphisms, the \texttt{Print Instances}
-commands can be useful to understand what additional morphisms should be
-registered.
-
-\subsection{Deprecated syntax and backward incompatibilities}
-Due to backward compatibility reasons, the following syntax for the
-declaration of setoids and morphisms is also accepted.
-
-\comindex{Add Setoid}
-\begin{quote}
- \texttt{Add Setoid} \textit{A Aeq ST} \texttt{as} \textit{ident}
-\end{quote}
-where \textit{Aeq} is a congruence relation without parameters,
-\textit{A} is its carrier and \textit{ST} is an object of type
-\texttt{(Setoid\_Theory A Aeq)} (i.e. a record packing together the reflexivity,
-symmetry and transitivity lemmas). Notice that the syntax is not completely
-backward compatible since the identifier was not required.
-
-\comindex{Add Morphism}
-\begin{quote}
- \texttt{Add Morphism} \textit{f}:\textit{ident}.\\
- Proof.\\
- \ldots\\
- Qed.
-\end{quote}
-
-The latter command also is restricted to the declaration of morphisms without
-parameters. It is not fully backward compatible since the property the user
-is asked to prove is slightly different: for $n$-ary morphisms the hypotheses
-of the property are permuted; moreover, when the morphism returns a
-proposition, the property is now stated using a bi-implication in place of
-a simple implication. In practice, porting an old development to the new
-semantics is usually quite simple.
-
-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 used to replace terms in
-contexts that were refused by the old implementation. As discussed in
-the next section, the semantics of the new \texttt{setoid\_rewrite}
-command differs slightly from the old one and \texttt{rewrite}.
-
-\asection{Extensions}
-\subsection{Rewriting under binders}
-
-\textbf{Warning}: Due to compatibility issues, this feature is enabled only when calling
-the \texttt{setoid\_rewrite} tactics directly and not \texttt{rewrite}.
-
-To be able to rewrite under binding constructs, one must declare
-morphisms with respect to pointwise (setoid) equivalence of functions.
-Example of such morphisms are the standard \texttt{all} and \texttt{ex}
-combinators for universal and existential quantification respectively.
-They are declared as morphisms in the \texttt{Classes.Morphisms\_Prop}
-module. For example, to declare that universal quantification is a
-morphism for logical equivalence:
-
-\begin{coq_eval}
-Reset Initial.
-Require Import Setoid Morphisms.
-\end{coq_eval}
-\begin{coq_example}
-Instance all_iff_morphism (A : Type) :
- Proper (pointwise_relation A iff ==> iff) (@all A).
-Proof. simpl_relation.
-\end{coq_example}
-\begin{coq_eval}
-Admitted.
-\end{coq_eval}
-
-One then has to show that if two predicates are equivalent at every
-point, their universal quantifications are equivalent. Once we have
-declared such a morphism, it will be used by the setoid rewriting tactic
-each time we try to rewrite under an \texttt{all} application (products
-in \Prop{} are implicitly translated to such applications).
-
-Indeed, when rewriting under a lambda, binding variable $x$, say from
-$P~x$ to $Q~x$ using the relation \texttt{iff}, the tactic will generate
-a proof of \texttt{pointwise\_relation A iff (fun x => P x) (fun x => Q
-x)} from the proof of \texttt{iff (P x) (Q x)} and a constraint of the
-form \texttt{Proper (pointwise\_relation A iff ==> ?) m} will be
-generated for the surrounding morphism \texttt{m}.
-
-Hence, one can add higher-order combinators as morphisms by providing
-signatures using pointwise extension for the relations on the functional
-arguments (or whatever subrelation of the pointwise extension).
-For example, one could declare the \texttt{map} combinator on lists as
-a morphism:
-\begin{coq_eval}
-Require Import List Setoid Morphisms.
-Set Implicit Arguments.
-Inductive list_equiv {A:Type} (eqA : relation A) : relation (list A) :=
-| eq_nil : list_equiv eqA nil nil
-| eq_cons : forall x y, eqA x y ->
- forall l l', list_equiv eqA l l' -> list_equiv eqA (x :: l) (y :: l').
-Generalizable All Variables.
-\end{coq_eval}
-\begin{coq_example*}
-Instance map_morphism `{Equivalence A eqA, Equivalence B eqB} :
- Proper ((eqA ==> eqB) ==> list_equiv eqA ==> list_equiv eqB) (@map A B).
-\end{coq_example*}
-
-where \texttt{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 \texttt{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
-\texttt{setoid\_rewrite}, matching is done on each subterm separately
-and in its local environment, and all matches are rewritten
-\emph{simultaneously} by default. The semantics of the previous
-\texttt{setoid\_rewrite} implementation can almost be recovered using
-the \texttt{at 1} modifier.
-
-\subsection{Sub-relations}
-
-Sub-relations can be used to specify that one relation is included in
-another, so that morphisms signatures for one can be used for the other.
-If a signature mentions a relation $R$ on the left of an arrow
-\texttt{==>}, then the signature also applies for any relation $S$ that
-is smaller than $R$, and the inverse applies on the right of an arrow.
-One can then declare only a few morphisms instances that generate the complete set
-of signatures for a particular constant. By default, the only declared
-subrelation is \texttt{iff}, which is a subrelation of \texttt{impl}
-and \texttt{inverse impl} (the dual of implication). That's why we can
-declare only two morphisms for conjunction:
-\texttt{Proper (impl ==> impl ==> impl) and} and
-\texttt{Proper (iff ==> iff ==> iff) and}. This is sufficient to satisfy
-any rewriting constraints arising from a rewrite using \texttt{iff},
-\texttt{impl} or \texttt{inverse impl} through \texttt{and}.
-
-Sub-relations are implemented in \texttt{Classes.Morphisms} and are a
-prime example of a mostly user-space extension of the algorithm.
-
-\subsection{Constant unfolding}
-
-The resolution tactic is based on type classes and hence regards user-defined
-constants as transparent by default. This may slow down the resolution
-due to a lot of unifications (all the declared \texttt{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 \texttt{Typeclasses Opaque} (see \S
-\ref{TypeclassesTransparency}).
-
-\asection{Strategies for rewriting}
-
-\subsection{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
-\cite{Luttik97specificationof}. Rewriting strategies are applied using
-the tactic \texttt{rewrite\_strat $s$} where $s$ is a strategy
-expression. Strategies are defined inductively as described by the
-following grammar:
-
-\def\str#1{\texttt{#1}}
-
-\def\strline#1#2{& \vert & #1 & \text{#2}}
-\def\strlinea#1#2#3{& \vert & \str{#1}~#2 & \text{#3}}
-
-\[\begin{array}{lcll}
- s, t, u & ::= & ( s ) & \text{strategy} \\
- \strline{c}{lemma} \\
- \strline{\str{<-}~c}{lemma, right-to-left} \\
-
- \strline{\str{fail}}{failure} \\
- \strline{\str{id}}{identity} \\
- \strline{\str{refl}}{reflexivity} \\
- \strlinea{progress}{s}{progress} \\
- \strlinea{try}{s}{failure catch} \\
-
- \strline{s~\str{;}~u}{composition} \\
- \strline{\str{choice}~s~t}{left-biased choice} \\
-
- \strlinea{repeat}{s}{iteration (+)} \\
- \strlinea{any}{s}{iteration (*)} \\
-
- \strlinea{subterm}{s}{one subterm} \\
- \strlinea{subterms}{s}{all subterms} \\
- \strlinea{innermost}{s}{innermost first} \\
- \strlinea{outermost}{s}{outermost first}\\
- \strlinea{bottomup}{s}{bottom-up} \\
- \strlinea{topdown}{s}{top-down} \\
-
- \strlinea{hints}{hintdb}{apply hint} \\
- \strlinea{terms}{c \ldots c}{any of the terms}\\
- \strlinea{eval}{redexpr}{apply reduction}\\
- \strlinea{fold}{c}{fold expression}
-\end{array}\]
-
-Actually a few of these are defined in term of the others using
-a primitive fixpoint operator:
-
-\[\begin{array}{lcl}
- \str{try}~s & = & \str{choice}~s~\str{id} \\
- \str{any}~s & = & \str{fix}~u. \str{try}~(s~\str{;}~u) \\
- \str{repeat}~s & = & s~\str{;}~\str{any}~s \\
- \str{bottomup}~s & = &
- \str{fix}~bu. (\str{choice}~(\str{progress}~(\str{subterms}~bu))~s)~\str{;}~\str{try}~bu \\
- \str{topdown}~s & = &
- \str{fix}~td. (\str{choice}~s~(\str{progress}~(\str{subterms}~td)))~\str{;}~\str{try}~td \\
- \str{innermost}~s & = & \str{fix}~i. (\str{choice}~(\str{subterm}~i)~s) \\
- \str{outermost}~s & = &
- \str{fix}~o. (\str{choice}~s~(\str{subterm}~o))
-\end{array}\]
-
-The basic control strategy semantics are straightforward: strategies are
-applied to subterms of the term to rewrite, starting from the root of
-the term. The lemma strategies unify the left-hand-side of the
-lemma with the current subterm and on success rewrite it to the
-right-hand-side. Composition can be used to continue rewriting on the
-current subterm. The fail strategy always fails while the identity
-strategy succeeds without making progress. The reflexivity strategy
-succeeds, making progress using a reflexivity proof of
-rewriting. Progress tests progress of the argument strategy and fails if
-no progress was made, while \str{try} always succeeds, catching
-failures. Choice is left-biased: it will launch the first strategy and
-fall back on the second one in case of failure. One can iterate a
-strategy at least 1 time using \str{repeat} and at least 0 times using
-\str{any}.
-
-The \str{subterm} and \str{subterms} strategies apply their argument
-strategy $s$ to respectively one or all subterms of the current term
-under consideration, left-to-right. \str{subterm} stops at the first
-subterm for which $s$ made progress. The composite strategies
-\str{innermost} and \str{outermost} perform a single innermost our outermost
-rewrite using their argument strategy. Their counterparts
-\str{bottomup} and \str{topdown} perform as many rewritings as possible,
-starting from the bottom or the top of the term.
-
-Hint databases created for \texttt{autorewrite} can also be used by
-\texttt{rewrite\_strat} using the \str{hints} strategy that applies any
-of the lemmas at the current subterm. The \str{terms} strategy takes the
-lemma names directly as arguments. The \str{eval} strategy expects a
-reduction expression (see \S\ref{Conversion-tactics}) and succeeds if it
-reduces the subterm under consideration. The \str{fold} strategy takes a
-term $c$ and tries to \emph{unify} it to the current subterm, converting
-it to $c$ on success, it is stronger than the tactic \texttt{fold}.
-
-
-\subsection{Usage}
-\tacindex{rewrite\_strat}
-
-\texttt{rewrite\_strat}~\textit{s}~\zeroone{\texttt{in} \textit{ident}}:
-
- Rewrite using the strategy \textit{s} in hypothesis \textit{ident}
- or the conclusion.
-
- \begin{ErrMsgs}
- \item \errindex{Nothing to rewrite}. If the strategy failed.
- \item \errindex{No progress made}. If the strategy succeeded but
- made no progress.
- \item \errindex{Unable to satisfy the rewriting constraints}.
- If the strategy succeeded and made progress but the corresponding
- rewriting constraints are not satisfied.
- \end{ErrMsgs}
-
-
-The \texttt{setoid\_rewrite}~c tactic is basically equivalent to
-\texttt{rewrite\_strat}~(\str{outermost}~c).
-
-
-
-
-
-%%% Local Variables:
-%%% mode: latex
-%%% TeX-master: "Reference-Manual"
-%%% End:
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/coqdoc.tex b/doc/refman/coqdoc.tex
deleted file mode 100644
index 26dbd59e7..000000000
--- a/doc/refman/coqdoc.tex
+++ /dev/null
@@ -1,573 +0,0 @@
-
-%\newcommand{\Coq}{\textsf{Coq}}
-\newcommand{\javadoc}{\textsf{javadoc}}
-\newcommand{\ocamldoc}{\textsf{ocamldoc}}
-\newcommand{\coqdoc}{\textsf{coqdoc}}
-\newcommand{\texmacs}{\TeX{}macs}
-\newcommand{\monurl}[1]{#1}
-%HEVEA\renewcommand{\monurl}[1]{\ahref{#1}{#1}}
-%\newcommand{\lnot}{not} % Hevea handles these symbols nicely
-%\newcommand{\lor}{or}
-%\newcommand{\land}{\&}
-%%% Beware : in a \texttt, -- is displayed as a unique - hence
-%%% the following macro:
-\newcommand{\mm}{\symbol{45}\symbol{45}}
-
-
-\coqdoc\ is a documentation tool for the proof assistant
-\Coq, similar to \javadoc\ or \ocamldoc.
-The task of \coqdoc\ is
-\begin{enumerate}
-\item to produce a nice \LaTeX\ and/or HTML document from the \Coq\
- sources, readable for a human and not only for the proof assistant;
-\item to help the user navigating in his own (or third-party) sources.
-\end{enumerate}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\subsection{Principles}
-
-Documentation is inserted into \Coq\ files as \emph{special comments}.
-Thus 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
-\texttt{(**}, followed by a space, and ends with the pending \texttt{*)}.
-The documentation format is inspired
- by Todd~A.~Coram's \emph{Almost Free Text (AFT)} tool: it is mainly
-ASCII text with some syntax-light controls, described below.
-\coqdoc\ is robust: it shouldn't fail, whatever the input is. But
-remember: ``garbage in, garbage out''.
-
-\paragraph{\Coq\ material inside documentation.}
-\Coq\ material is quoted between the
-delimiters \texttt{[} and \texttt{]}. Square brackets may be nested,
-the inner ones being understood as being part of the quoted code (thus
-you can quote a term like \texttt{fun x => u} by writing
-\texttt{[fun x => u]}). Inside quotations, the code is pretty-printed in
-the same way as it is in code parts.
-
-Pre-formatted vernacular is enclosed by \texttt{[[} and
-\texttt{]]}. The former must be followed by a newline and the latter
-must follow a newline.
-
-\paragraph{Pretty-printing.}
-\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:
-\begin{alltt}
-(** printing \emph{token} %...\LaTeX...% #...HTML...# *)
-\end{alltt}
-or
-\begin{alltt}
-(** printing \emph{token} $...\LaTeX\ math...$ #...HTML...# *)
-\end{alltt}
-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
-\begin{alltt}
-(** remove printing \emph{token} *)
-\end{alltt}
-
-Initially, the pretty-printing table contains the following mapping:
-\begin{center}
- \begin{tabular}{ll@{\qquad\qquad}ll@{\qquad\qquad}ll@{\qquad\qquad}}
- \verb!->! & $\rightarrow$ &
- \verb!<-! & $\leftarrow$ &
- \verb|*| & $\times$ \\
- \verb|<=| & $\le$ &
- \verb|>=| & $\ge$ &
- \verb|=>| & $\Rightarrow$ \\
- \verb|<>| & $\not=$ &
- \verb|<->| & $\leftrightarrow$ &
- \verb!|-! & $\vdash$ \\
- \verb|\/| & $\lor$ &
- \verb|/\| & $\land$ &
- \verb|~| & $\lnot$
- \end{tabular}
-\end{center}
-Any of these can be overwritten or suppressed using the
-\texttt{printing} commands.
-
-Important note: the recognition of tokens is done by a (ocaml)lex
-automaton and thus applies the longest-match rule. For instance,
-\verb!->~! is recognized as a single token, where \Coq\ sees two
-tokens. It is the responsibility of the user to insert space between
-tokens \emph{or} to give pretty-printing rules for the possible
-combinations, e.g.
-\begin{verbatim}
-(** printing ->~ %\ensuremath{\rightarrow\lnot}% *)
-\end{verbatim}
-
-
-\paragraph{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 sub-section, etc.
-The section title is given on the remaining of the line.
-Example:
-\begin{verbatim}
- (** * Well-founded relations
-
- In this section, we introduce... *)
-\end{verbatim}
-
-
-%TODO \paragraph{Fonts.}
-
-
-\paragraph{Lists.}
-List items are introduced by a leading dash. \coqdoc\ uses whitespace
-to determine the depth of a new list item and which text belongs in
-which list items. A list ends when a line of text starts at or before
-the level of indenting of the list's dash. A list item's dash must
-always be the first non-space character on its line (so, in
-particular, a list can not begin on the first line of a comment -
-start it on the second line instead).
-
-Example:
-\begin{verbatim}
- We go by induction on [n]:
- - If [n] is 0...
- - If [n] is [S n'] we require...
-
- two paragraphs of reasoning, and two subcases:
-
- - In the first case...
- - In the second case...
-
- So the theorem holds.
-\end{verbatim}
-
-\paragraph{Rules.}
-More than 4 leading dashes produce a horizontal rule.
-
-\paragraph{Emphasis.}
-Text can be italicized by placing it in underscores. A non-identifier
-character must precede the leading underscore and follow the trailing
-underscore, so that uses of underscores in names aren't mistaken for
-emphasis. Usually, these are spaces or punctuation.
-
-\begin{verbatim}
- This sentence contains some _emphasized text_.
-\end{verbatim}
-
-\paragraph{Escaping to \LaTeX\ and HTML.}
-Pure \LaTeX\ or HTML material can be inserted using the following
-escape sequences:
-\begin{itemize}
-\item \verb+$...LaTeX stuff...$+ inserts some \LaTeX\ material in math mode.
- Simply discarded in HTML output.
-
-\item \verb+%...LaTeX stuff...%+ inserts some \LaTeX\ material.
- Simply discarded in HTML output.
-
-\item \verb+#...HTML stuff...#+ inserts some HTML material. Simply
- discarded in \LaTeX\ output.
-\end{itemize}
-
-Note: to simply output the characters \verb+$+, \verb+%+ and \verb+#+
-and escaping their escaping role, these characters must be doubled.
-
-\paragraph{Verbatim.}
-Verbatim material is introduced by a leading \verb+<<+ and closed by
-\verb+>>+ at the beginning of a line. Example:
-\begin{verbatim}
-Here is the corresponding caml code:
-<<
- let rec fact n =
- if n <= 1 then 1 else n * fact (n-1)
->>
-\end{verbatim}
-
-
-\paragraph{Hyperlinks.}
-Hyperlinks can be inserted into the HTML output, so that any
-identifier is linked to the place of its definition.
-
-\texttt{coqc \emph{file}.v} automatically dumps localization information
-in \texttt{\emph{file}.glob} or appends it to a file specified using option
-\texttt{\mm{}dump-glob \emph{file}}. Take care of erasing this global file, if
-any, when starting the whole compilation process.
-
-Then invoke \texttt{coqdoc} or \texttt{coqdoc \mm{}glob-from \emph{file}} to tell
-\coqdoc\ to look for name resolutions into the file \texttt{\emph{file}}
-(it will look in \texttt{\emph{file}.glob} by default).
-
-Identifiers from the \Coq\ standard library are linked to the \Coq\
-web site at \url{http://coq.inria.fr/library/}. This behavior can be
-changed using command line options \texttt{\mm{}no-externals} and
-\texttt{\mm{}coqlib}; see below.
-
-
-\paragraph{Hiding / Showing parts of the source.}
-Some parts of the source can be hidden using command line options
-\texttt{-g} and \texttt{-l} (see below), or using such comments:
-\begin{alltt}
-(* begin hide *)
-\emph{some Coq material}
-(* end hide *)
-\end{alltt}
-Conversely, some parts of the source which would be hidden can be
-shown using such comments:
-\begin{alltt}
-(* begin show *)
-\emph{some Coq material}
-(* end show *)
-\end{alltt}
-The latter cannot be used around some inner parts of a proof, but can
-be used around a whole proof.
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\subsection{Usage}
-
-\coqdoc\ is invoked on a shell command line as follows:
-\begin{displaymath}
- \texttt{coqdoc }<\textit{options and files}>
-\end{displaymath}
-Any command line argument which is not an option is considered to be a
-file (even if it starts with a \verb!-!). \Coq\ files are identified
-by the suffixes \verb!.v! and \verb!.g! and \LaTeX\ files by the
-suffix \verb!.tex!.
-
-\begin{description}
-\item[HTML output] ~\par
- This is the default output.
- One HTML file is created for each \Coq\ file given on the command line,
- together with a file \texttt{index.html} (unless option
- \texttt{-no-index} is passed). The HTML pages use a style sheet
- named \texttt{style.css}. Such a file is distributed with \coqdoc.
-
-\item[\LaTeX\ output] ~\par
- A single \LaTeX\ file is created, on standard output. It can be
- redirected to a file with option \texttt{-o}.
- The order of files on the command line is kept in the final
- document. \LaTeX\ files given on the command line are copied `as is'
- in the final document .
- DVI and PostScript can be produced directly with the options
- \texttt{-dvi} and \texttt{-ps} respectively.
-
-\item[\texmacs\ output] ~\par
- To translate the input files to \texmacs\ format, to be used by
- the \texmacs\ Coq interface.
- %broken link:
- %(see \url{http://www-sop.inria.fr/lemme/Philippe.Audebaud/tmcoq/}).
-\end{description}
-
-
-\subsubsection*{Command line options}
-
-
-\paragraph{Overall options}
-
-\begin{description}
-
-\item[\texttt{\mm{}html}] ~\par
-
- Select a HTML output.
-
-\item[\texttt{\mm{}latex}] ~\par
-
- Select a \LaTeX\ output.
-
-\item[\texttt{\mm{}dvi}] ~\par
-
- Select a DVI output.
-
-\item[\texttt{\mm{}ps}] ~\par
-
- Select a PostScript output.
-
-\item[\texttt{\mm{}texmacs}] ~\par
-
- Select a \texmacs\ output.
-
-\item[\texttt{\mm{}stdout}] ~\par
-
- Write output to stdout.
-
-\item[\texttt{-o }\textit{file}, \texttt{\mm{}output }\textit{file}] ~\par
-
- Redirect the output into the file `\textit{file}' (meaningless with
- \texttt{-html}).
-
-\item[\texttt{-d }\textit{dir}, \texttt{\mm{}directory }\textit{dir}] ~\par
-
- Output files into directory `\textit{dir}' instead of current
- directory (option \texttt{-d} does not change the filename specified
- with option \texttt{-o}, if any).
-
-\item[\texttt{\mm{}body-only}] ~\par
-
- Suppress the header and trailer of the final document. Thus, you can
- insert the resulting document into a larger one.
-
-\item[\texttt{-p} \textit{string}, \texttt{\mm{}preamble} \textit{string}]~\par
-
- Insert some material in the \LaTeX\ preamble, right before
- \verb!\begin{document}! (meaningless with \texttt{-html}).
-
-\item[\texttt{\mm{}vernac-file }\textit{file},
- \texttt{\mm{}tex-file }\textit{file}] ~\par
-
- Considers the file `\textit{file}' respectively as a \verb!.v!
- (or \verb!.g!) file or a \verb!.tex! file.
-
-\item[\texttt{\mm{}files-from }\textit{file}] ~\par
-
- Read file names to process in file `\textit{file}' as if they were
- given on the command line. Useful for program sources split up into
- several directories.
-
-\item[\texttt{-q}, \texttt{\mm{}quiet}] ~\par
-
- Be quiet. Do not print anything except errors.
-
-\item[\texttt{-h}, \texttt{\mm{}help}] ~\par
-
- Give a short summary of the options and exit.
-
-\item[\texttt{-v}, \texttt{\mm{}version}] ~\par
-
- Print the version and exit.
-
-\end{description}
-
-\paragraph{Index options}
-
-Default behavior is to build an index, for the HTML output only, into
-\texttt{index.html}.
-
-\begin{description}
-
-\item[\texttt{\mm{}no-index}] ~\par
-
- Do not output the index.
-
-\item[\texttt{\mm{}multi-index}] ~\par
-
- Generate one page for each category and each letter in the index,
- together with a top page \texttt{index.html}.
-
-\item[\texttt{\mm{}index }\textit{string}] ~\par
-
- Make the filename of the index \textit{string} instead of ``index''.
- Useful since ``index.html'' is special.
-
-\end{description}
-
-\paragraph{Table of contents option}
-
-\begin{description}
-
-\item[\texttt{-toc}, \texttt{\mm{}table-of-contents}] ~\par
-
- Insert a table of contents.
- For a \LaTeX\ output, it inserts a \verb!\tableofcontents! at the
- beginning of the document. For a HTML output, it builds a table of
- contents into \texttt{toc.html}.
-
-\item[\texttt{\mm{}toc-depth }\textit{int}] ~\par
-
- Only include headers up to depth \textit{int} in the table of
- contents.
-
-\end{description}
-
-\paragraph{Hyperlinks options}
-\begin{description}
-
-\item[\texttt{\mm{}glob-from }\textit{file}] ~\par
-
- Make references using \Coq\ globalizations from file \textit{file}.
- (Such globalizations are obtained with \Coq\ option \texttt{-dump-glob}).
-
-\item[\texttt{\mm{}no-externals}] ~\par
-
- Do not insert links to the \Coq\ standard library.
-
-\item[\texttt{\mm{}external }\textit{url}~\textit{coqdir}] ~\par
-
- Use given URL for linking references whose name starts with prefix
- \textit{coqdir}.
-
-\item[\texttt{\mm{}coqlib }\textit{url}] ~\par
-
- Set base URL for the \Coq\ standard library (default is
- \url{http://coq.inria.fr/library/}). This is equivalent to
- \texttt{\mm{}external }\textit{url}~\texttt{Coq}.
-
-\item[\texttt{-R }\textit{dir }\textit{coqdir}] ~\par
-
- Map physical directory \textit{dir} to \Coq\ logical directory
- \textit{coqdir} (similarly to \Coq\ option \texttt{-R}).
-
- Note: option \texttt{-R} only has effect on the files
- \emph{following} it on the command line, so you will probably need
- to put this option first.
-
-\end{description}
-
-\paragraph{Title options}
-\begin{description}
-\item[\texttt{-s }, \texttt{\mm{}short}] ~\par
-
- Do not insert titles for the files. The default behavior is to
- insert a title like ``Library Foo'' for each file.
-
-\item[\texttt{\mm{}lib-name }\textit{string}] ~\par
-
- Print ``\textit{string} Foo'' instead of ``Library Foo'' in titles.
- For example ``Chapter'' and ``Module'' are reasonable choices.
-
-\item[\texttt{\mm{}no-lib-name}] ~\par
-
- Print just ``Foo'' instead of ``Library Foo'' in titles.
-
-\item[\texttt{\mm{}lib-subtitles}] ~\par
-
- Look for library subtitles. When enabled, the beginning of each
- file is checked for a comment of the form:
-\begin{alltt}
-(** * ModuleName : text *)
-\end{alltt}
- where \texttt{ModuleName} must be the name of the file. If it is
- present, the \texttt{text} is used as a subtitle for the module in
- appropriate places.
-
-\item[\texttt{-t }\textit{string},
- \texttt{\mm{}title }\textit{string}] ~\par
-
- Set the document title.
-
-\end{description}
-
-\paragraph{Contents options}
-\begin{description}
-
-\item[\texttt{-g}, \texttt{\mm{}gallina}] ~\par
-
- Do not print proofs.
-
-\item[\texttt{-l}, \texttt{\mm{}light}] ~\par
-
- Light mode. Suppress proofs (as with \texttt{-g}) and the following commands:
- \begin{itemize}
- \item {}[\texttt{Recursive}] \texttt{Tactic Definition}
- \item \texttt{Hint / Hints}
- \item \texttt{Require}
- \item \texttt{Transparent / Opaque}
- \item \texttt{Implicit Argument / Implicits}
- \item \texttt{Section / Variable / Hypothesis / End}
- \end{itemize}
-
-\end{description}
-The behavior of options \texttt{-g} and \texttt{-l} can be locally
-overridden using the \texttt{(* begin show *)} \dots\ \texttt{(* end
- show *)} environment (see above).
-
-There are a few options to drive the parsing of comments:
-\begin{description}
-\item[\texttt{\mm{}parse-comments}] ~\par
-
- Parses regular comments delimited by \texttt{(*} and \texttt{*)} as
- well. They are typeset inline.
-
-\item[\texttt{\mm{}plain-comments}] ~\par
-
- Do not interpret comments, simply copy them as plain-text.
-
-\item[\texttt{\mm{}interpolate}] ~\par
-
- Use the globalization information to typeset identifiers appearing in
- \Coq{} escapings inside comments.
-\end{description}
-
-
-\paragraph{Language options}
-
-Default behavior is to assume ASCII 7 bits input files.
-
-\begin{description}
-
-\item[\texttt{-latin1}, \texttt{\mm{}latin1}] ~\par
-
- Select ISO-8859-1 input files. It is equivalent to
- \texttt{\mm{}inputenc latin1 \mm{}charset iso-8859-1}.
-
-\item[\texttt{-utf8}, \texttt{\mm{}utf8}] ~\par
-
- Set \texttt{\mm{}inputenc utf8x} for \LaTeX\ output and
- \texttt{\mm{}charset utf-8} for HTML output. Also use Unicode
- replacements for a couple of standard plain ASCII notations such
- as $\rightarrow$ for \texttt{->} and $\forall$ for
- \texttt{forall}. \LaTeX\ UTF-8 support can be found at
- \url{http://www.ctan.org/pkg/unicode}.
-
- For the interpretation of Unicode characters by \LaTeX, extra
- packages which {\coqdoc} does not provide by default might be
- required, such as \texttt{textgreek} for some Greek letters or
- \texttt{stmaryrd} for some mathematical symbols. If a Unicode
- character is missing an interpretation in the \texttt{utf8x} input
- encoding, add
- \verb=\DeclareUnicodeCharacter{=\textit{code}\verb=}{=\textit{latex-interpretation}\verb=}=. Packages
- and declarations can be added with option \texttt{-p}.
-
-\item[\texttt{\mm{}inputenc} \textit{string}] ~\par
-
- Give a \LaTeX\ input encoding, as an option to \LaTeX\ package
- \texttt{inputenc}.
-
-\item[\texttt{\mm{}charset} \textit{string}] ~\par
-
- Specify the HTML character set, to be inserted in the HTML header.
-
-\end{description}
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\subsection[The coqdoc \LaTeX{} style file]{The coqdoc \LaTeX{} style file\label{section:coqdoc.sty}}
-
-In case you choose to produce a document without the default \LaTeX{}
-preamble (by using option \verb|--no-preamble|), then you must insert
-into your own preamble the command
-\begin{quote}
- \verb|\usepackage{coqdoc}|
-\end{quote}
-
-The package optionally takes the argument \verb|[color]| to typeset
-identifiers with colors (this requires the \verb|xcolor| package).
-
-Then you may alter the rendering of the document by
-redefining some macros:
-\begin{description}
-
-\item[\texttt{coqdockw}, \texttt{coqdocid}, \ldots] ~
-
- The one-argument macros for typesetting keywords and identifiers.
- Defaults are sans-serif for keywords and italic for identifiers.
-
- For example, if you would like a slanted font for keywords, you
- may insert
-\begin{verbatim}
- \renewcommand{\coqdockw}[1]{\textsl{#1}}
-\end{verbatim}
- anywhere between \verb|\usepackage{coqdoc}| and
- \verb|\begin{document}|.
-
-\item[\texttt{coqdocmodule}] ~
-
- One-argument macro for typesetting the title of a \verb|.v| file.
- Default is
-\begin{verbatim}
-\newcommand{\coqdocmodule}[1]{\section*{Module #1}}
-\end{verbatim}
- and you may redefine it using \verb|\renewcommand|.
-
-\end{description}
-
-
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..1d3b66173 100644
--- a/doc/sphinx/addendum/extended-pattern-matching.rst
+++ b/doc/sphinx/addendum/extended-pattern-matching.rst
@@ -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``
~~~~~~~~~~~~~~~~~~
diff --git a/doc/sphinx/addendum/extraction.rst b/doc/sphinx/addendum/extraction.rst
new file mode 100644
index 000000000..38365e403
--- /dev/null
+++ b/doc/sphinx/addendum/extraction.rst
@@ -0,0 +1,585 @@
+.. include:: ../replaces.rst
+
+.. _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
+and Scheme. In the following, "ML" will be used (abusively) to refer
+to any of the three.
+
+Before using any of the commands or options described in this chapter,
+the extraction framework should first be loaded explicitly
+via ``Require Extraction``, or via the more robust
+``From Coq Require Extraction``.
+Note that in earlier versions of Coq, these commands and options were
+directly available without any preliminary ``Require``.
+
+.. coqtop:: in
+
+ Require Extraction.
+
+Generating ML Code
+-------------------
+
+.. note::
+
+ In the following, a qualified identifier `qualid`
+ can be used to refer to any kind of |Coq| global "object" : constant,
+ inductive type, inductive constructor or module name.
+
+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.
+
+ Extraction of the mentioned object in the |Coq| toplevel.
+
+.. cmd:: Recursive Extraction @qualid ... @qualid.
+
+ Recursive extraction of all the mentioned objects and
+ all their dependencies in the |Coq| toplevel.
+
+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.
+
+ Recursive extraction of all the mentioned objects and all
+ their dependencies in one monolithic `file`.
+ Global and local identifiers are renamed according to the chosen ML
+ language to fulfill its syntactic conventions, keeping original
+ names as much as possible.
+
+.. 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.
+
+ Extraction of the |Coq| library ``ident.v`` and all other modules
+ ``ident.v`` depends on.
+
+.. cmd:: Separate Extraction @qualid ... @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
+ 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
+ ``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.
+
+ All the mentioned objects and all their dependencies are extracted
+ 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|.
+
+Extraction Options
+-------------------
+
+Setting the target language
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ability to fix target language is the first and more important
+of the extraction options. Default is ``OCaml``.
+
+.. cmd:: Extraction Language OCaml.
+.. cmd:: Extraction Language Haskell.
+.. cmd:: Extraction Language Scheme.
+
+Inlining and optimizations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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
+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,
+even if some inlining is done, the inlined constant are nevertheless
+printed, to ensure session-independent programs.
+
+Concerning Haskell, type-preserving optimizations are less useful
+because of laziness. We still make some optimizations, for example in
+order to produce more readable code.
+
+The type-preserving optimizations are controlled by the following |Coq| options:
+
+.. 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.
+
+ Default is off. This controls the non type-preserving optimizations
+ made on ML terms (which try to avoid function abstraction of dummy
+ types). Turn this option on to make sure that ``e:t``
+ implies that ``e':t'`` where ``e'`` and ``t'`` are the extracted
+ code of ``e`` and ``t`` respectively.
+
+.. 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
+ only one argument to this constructor), the inductive structure is
+ removed and this type is seen as an alias to the inner type.
+ The typical example is ``sig``. This option allows disabling this
+ optimization when one wishes to preserve the inductive structure of types.
+
+.. opt:: Extraction AutoInline.
+
+ Default is on. The extraction mechanism inlines the bodies of
+ some defined constants, according to some heuristics
+ like size of bodies, uselessness of some arguments, etc.
+ Those heuristics are not always perfect; if you want to disable
+ this feature, turn this option off.
+
+.. cmd:: Extraction Inline @qualid ... @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.
+
+ Conversely, the constants mentionned by this command will
+ never be inlined during extraction.
+
+.. 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.
+
+ Empties the table recording the custom inlinings (see the
+ previous commands).
+
+**Inlining and printing of a constant declaration:**
+
+A user can explicitly ask for a constant to be extracted by two means:
+
+ * by mentioning it on the extraction command line
+
+ * by extracting the whole |Coq| module of this constant.
+
+In both cases, the declaration of this constant will be present in the
+produced file. But this same constant may or may not be inlined in
+the following terms, depending on the automatic/custom inlining mechanism.
+
+For the constants non-explicitly required but needed for dependency
+reasons, there are two cases:
+
+ * If an inlining decision is taken, whether automatically or not,
+ all occurrences of this constant are replaced by its extracted body,
+ and this constant is not declared in the generated file.
+
+ * If no inlining decision is taken, the constant is normally
+ declared in the produced file.
+
+Extra elimination of useless arguments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following command provides some extra manual control on the
+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 ].
+
+ This experimental command allows declaring some arguments of
+ `qualid` as implicit, i.e. useless in extracted code and hence to
+ be removed by extraction. Here `qualid` can be any function or
+ inductive constructor, and the given `ident` are the names of
+ the concerned arguments. In fact, an argument can also be referred
+ 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
+if any of the implicited variables still occurs in the final code.
+This behavior can be relaxed via the following option:
+
+.. 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
+ final code of an extraction. This way, the extracted code may be
+ obtained nonetheless and reviewed manually to locate the source of the issue
+ (in the code, some comments mark the location of these remaining
+ implicited variables).
+ Note that this extracted code might not compile or run properly,
+ depending of the use of these remaining implicited variables.
+
+Realizing axioms
+~~~~~~~~~~~~~~~~
+
+Extraction will fail if it encounters an informative axiom not realized.
+A warning will be issued if it encounters a logical axiom, to remind the
+user that inconsistent logical axioms may lead to incorrect or
+non-terminating extracted terms.
+
+It is possible to assume some axioms while developing a proof. Since
+these axioms can be any kind of proposition or object or type, they may
+perfectly well have some computational content. But a program must be
+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.
+
+ Give an ML extraction for the given constant.
+ The `string` may be an identifier or a quoted 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.
+
+.. 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
+ fact, the strings containing realizing code are just copied to the
+ extracted files. The extraction recognizes whether the realized axiom
+ should become a ML type constant or a ML object declaration. For example:
+
+.. coqtop:: in
+
+ Axiom X:Set.
+ Axiom x:X.
+ Extract Constant X => "int".
+ Extract Constant x => "0".
+
+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.
+
+The number of type variables is checked by the system. For example:
+
+.. coqtop:: in
+
+ Axiom Y : Set -> Set -> Set.
+ Extract Constant Y "'a" "'b" => " 'a * 'b ".
+
+Realizing an axiom via ``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
+logical axiom. This warning reminds user that inconsistent logical
+axioms may lead to incorrect or non-terminating extracted terms.
+
+If an informative axiom has not been realized before an extraction, a
+warning is also issued and the definition of the axiom is filled with
+an exception labeled ``AXIOM TO BE REALIZED``. The user must then
+search these exceptions inside the extracted file and replace them by
+real code.
+
+Realizing inductive types
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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 ].
+
+ Give an ML extraction for the given inductive type. You must specify
+ extractions for the type itself (first `string`) and all its
+ constructors (all the `string` between square brackets). In this form,
+ 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.
+
+ Same as before, with a final extra `string` that indicates how to
+ perform pattern-matching over this inductive type. In this form,
+ the ML extraction could be an arbitrary type.
+ For an inductive type with `k` constructors, the function used to
+ emulate the pattern-matching should expect `(k+1)` arguments, first the `k`
+ branches in functional form, and then the inductive element to
+ destruct. For instance, the match branch ``| S n => foo`` gives the
+ functional form ``(fun n -> foo)``. Note that a constructor with no
+ 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:
+ ``(unit->'a)->(int->'a)->int->'a``.
+
+.. caution:: As for ``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.
+
+ * 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``,
+ it is theoretically possible to build ``nat`` values that are
+ 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.
+ It might be interesting to associate this translation with
+ some specific ``Extract Constant`` when primitive counterparts exist.
+
+Typical examples are the following:
+
+.. coqtop:: in
+
+ Extract Inductive unit => "unit" [ "()" ].
+ Extract Inductive bool => "bool" [ "true" "false" ].
+ Extract Inductive sumbool => "bool" [ "true" "false" ].
+
+.. note::
+
+ 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
+ used as infix constructor or type.
+
+.. coqtop:: in
+
+ Extract Inductive list => "list" [ "[]" "(::)" ].
+ Extract Inductive prod => "(*)" [ "(,)" ].
+
+As an example of translation to a non-inductive datatype, let's turn
+``nat`` into |OCaml| ``int`` (see caveat above):
+
+.. coqtop:: in
+
+ Extract Inductive nat => int [ "0" "succ" ] "(fun fO fS n -> if n=0 then fO () else fS (n-1))".
+
+Avoiding conflicts with existing filenames
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When using ``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|.
+It is possible to instruct the extraction not to use particular filenames.
+
+.. cmd:: Extraction Blacklist @ident ... @ident.
+
+ Instruct the extraction to avoid using these names as filenames
+ for extracted code.
+
+.. cmd:: Print Extraction Blacklist.
+
+ Show the current list of filenames the extraction should avoid.
+
+.. cmd:: Reset Extraction Blacklist.
+
+ Allow the extraction to use any filename.
+
+For |OCaml|, a typical use of these commands is
+``Extraction Blacklist String List``.
+
+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
+when needed some unsafe casting ``Obj.magic``, which give
+a generic type ``'a`` to any term.
+
+First, if some part of the program is *very* polymorphic, there
+may be no ML type for it. In that case the extraction to ML works
+alright but the generated code may be refused by the ML
+type-checker. A very well known example is the ``distr-pair``
+function:
+
+.. coqtop:: in
+
+ 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::
+
+ let dp x y f = Pair((f () x),(f () y))
+
+and would have type::
+
+ dp : 'a -> 'a -> (unit -> 'a -> 'b) -> ('b,'b) prod
+
+which is not its original type, but a restriction.
+
+We now produce the following correct version::
+
+ let dp x y f = Pair ((Obj.magic f () x), (Obj.magic f () y))
+
+Secondly, some |Coq| definitions may have no counterpart in ML. This
+happens when there is a quantification over types inside the type
+of a constructor; for example:
+
+.. coqtop:: in
+
+ 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
+(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
+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
+of the right shape (from the |Coq| point-of-view).
+
+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|
+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,
+but all can be done in the other dialects with slight modifications.
+We then indicate where to find other examples and tests of extraction.
+
+A detailed example: Euclidean division
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The file ``Euclid`` contains the proof of Euclidean division.
+The natural numbers used there are unary integers of type ``nat``,
+defined by two constructors ``O`` and ``S``.
+This module contains a theorem ``eucl_dev``, whose type is::
+
+ forall b:nat, b > 0 -> forall a:nat, diveucl a b
+
+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|:
+
+.. coqtop:: none
+
+ Reset Initial.
+
+.. coqtop:: all
+
+ Require Extraction.
+ Require Import Euclid Wf_nat.
+ Extraction Inline gt_wf_rec lt_wf_rec induction_ltof2.
+ Recursive Extraction eucl_dev.
+
+The inlining of ``gt_wf_rec`` and others is not
+mandatory. It only enhances readability of extracted code.
+You can then copy-paste the output to a file ``euclid.ml`` or let
+|Coq| do it for you with the following command::
+
+ Extraction "euclid" eucl_dev.
+
+Let us play the resulting program (in an |OCaml| toplevel)::
+
+ #use "euclid.ml";;
+ type nat = O | S of nat
+ type sumbool = Left | Right
+ val sub : nat -> nat -> nat = <fun>
+ val le_lt_dec : nat -> nat -> sumbool = <fun>
+ val le_gt_dec : nat -> nat -> sumbool = <fun>
+ type diveucl = Divex of nat * nat
+ val eucl_dev : nat -> nat -> diveucl = <fun>
+
+ # 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::
+
+ # let rec nat_of_int = function 0 -> O | n -> S (nat_of_int (n-1));;
+ val nat_of_int : int -> nat = <fun>
+
+ # let rec int_of_nat = function O -> 0 | S p -> 1+(int_of_nat p);;
+ val int_of_nat : nat -> int = <fun>
+
+ # let div a b =
+ let Divex (q,r) = eucl_dev (nat_of_int b) (nat_of_int a)
+ in (int_of_nat q, int_of_nat r);;
+ val div : int -> int -> int * int = <fun>
+
+ # div 173 15;;
+ - : int * int = (11, 8)
+
+Note that these ``nat_of_int`` and ``int_of_nat`` are now
+available via a mere ``Require Import ExtrOcamlIntConv`` and then
+adding these functions to the list of functions to extract. This file
+``ExtrOcamlIntConv.v`` and some others in ``plugins/extraction/``
+are meant to help building concrete program via extraction.
+
+Extraction's horror museum
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some pathological examples of extraction are grouped in the file
+``test-suite/success/extraction.v`` of the sources of |Coq|.
+
+Users' Contributions
+~~~~~~~~~~~~~~~~~~~~
+
+Several of the |Coq| Users' Contributions use extraction to produce
+certified programs. In particular the following ones have an automatic
+extraction test:
+
+ * ``additions`` : https://github.com/coq-contribs/additions
+ * ``bdds`` : https://github.com/coq-contribs/bdds
+ * ``canon-bdds`` : https://github.com/coq-contribs/canon-bdds
+ * ``chinese`` : https://github.com/coq-contribs/chinese
+ * ``continuations`` : https://github.com/coq-contribs/continuations
+ * ``coq-in-coq`` : https://github.com/coq-contribs/coq-in-coq
+ * ``exceptions`` : https://github.com/coq-contribs/exceptions
+ * ``firing-squad`` : https://github.com/coq-contribs/firing-squad
+ * ``founify`` : https://github.com/coq-contribs/founify
+ * ``graphs`` : https://github.com/coq-contribs/graphs
+ * ``higman-cf`` : https://github.com/coq-contribs/higman-cf
+ * ``higman-nw`` : https://github.com/coq-contribs/higman-nw
+ * ``hardware`` : https://github.com/coq-contribs/hardware
+ * ``multiplier`` : https://github.com/coq-contribs/multiplier
+ * ``search-trees`` : https://github.com/coq-contribs/search-trees
+ * ``stalmarck`` : https://github.com/coq-contribs/stalmarck
+
+Note that ``continuations`` and ``multiplier`` are a bit particular. They are
+examples of developments where ``Obj.magic`` are needed. This is
+probably due to an heavy use of impredicativity. After compilation, those
+two examples run nonetheless, thanks to the correction of the
+extraction :cite:`Let02`.
diff --git a/doc/sphinx/addendum/generalized-rewriting.rst b/doc/sphinx/addendum/generalized-rewriting.rst
new file mode 100644
index 000000000..e4dea3487
--- /dev/null
+++ b/doc/sphinx/addendum/generalized-rewriting.rst
@@ -0,0 +1,847 @@
+.. include:: ../preamble.rst
+.. include:: ../replaces.rst
+
+.. _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
+equipped with ad-hoc equivalence relations meant to behave as
+equalities. Actually, the tactics have also been generalized to
+relations weaker then equivalences (e.g. rewriting systems). The
+toolbox also extends the automatic rewriting capabilities of the
+system, allowing the specification of custom strategies for rewriting.
+
+This documentation is adapted from the previous setoid documentation
+by Claudio Sacerdoti Coen (based on previous work by Clément Renard).
+The new implementation is a drop-in replacement for the old one
+[#tabareau]_, hence most of the documentation still applies.
+
+The work is a complete rewrite of the previous implementation, based
+on the type class infrastructure. It also improves on and generalizes
+the previous implementation in several ways:
+
+
++ User-extensible algorithm. The algorithm is separated in two parts:
+ generations of the rewriting constraints (done in ML) and solving of
+ these constraints using type class resolution. As type class
+ resolution is extensible using tactics, this allows users to define
+ general ways to solve morphism constraints.
++ Sub-relations. An example extension to the base algorithm is the
+ ability to define one relation as a subrelation of another so that
+ morphism declarations on one relation can be used automatically for
+ the other. This is done purely using tactics and type class search.
++ Rewriting under binders. It is possible to rewrite under binders in
+ the new implementation, if one provides the proper morphisms. Again,
+ most of the work is handled in the tactics.
++ First-class morphisms and signatures. Signatures and morphisms are
+ ordinary Coq terms, hence they can be manipulated inside Coq, put
+ inside structures and lemmas about them can be proved inside the
+ system. Higher-order morphisms are also allowed.
++ Performance. The implementation is based on a depth-first search for
+ the first solution to a set of constraints which can be as fast as
+ linear in the size of the term, and the size of the proof term is
+ linear in the size of the original term. Besides, the extensibility
+ allows the user to customize the proof search if necessary.
+
+.. [#tabareau] Nicolas Tabareau helped with the gluing.
+
+Introduction to generalized rewriting
+-------------------------------------
+
+
+Relations and morphisms
+~~~~~~~~~~~~~~~~~~~~~~~
+
+A parametric *relation* ``R`` is any term of type
+``forall (x1 :T1 ) ... (xn :Tn ), relation A``.
+The expression ``A``, which depends on ``x1 ... xn`` , is called the *carrier*
+of the relation and ``R`` is said to be a relation over ``A``; the list
+``x1,...,xn`` is the (possibly empty) list of parameters of the relation.
+
+**Example 1 (Parametric relation):**
+
+It is possible to implement finite sets of elements of type ``A`` as
+unordered list of elements of type ``A``.
+The function ``set_eq: forall (A: Type), relation (list A)``
+satisfied by two lists with the same elements is a parametric relation
+over ``(list A)`` with one parameter ``A``. The type of ``set_eq``
+is convertible with ``forall (A: Type), list A -> list A -> Prop.``
+
+An *instance* of a parametric relation ``R`` with n parameters is any term
+``(R t1 ... tn )``.
+
+Let ``R`` be a relation over ``A`` with ``n`` parameters. A term is a parametric
+proof of reflexivity for ``R`` if it has type
+``forall (x1 :T1 ) ... (xn :Tn), reflexive (R x1 ... xn )``.
+Similar definitions are given for parametric proofs of symmetry and transitivity.
+
+**Example 2 (Parametric relation (cont.)):**
+
+The ``set_eq`` relation of the previous example can be proved to be
+reflexive, symmetric and transitive. A parametric unary function ``f`` of type
+``forall (x1 :T1 ) ... (xn :Tn ), A1 -> A2`` covariantly respects two parametric relation instances
+``R1`` and ``R2`` if, whenever ``x``, ``y`` satisfy ``R1 x y``, their images (``f x``) and (``f y``)
+satisfy ``R2 (f x) (f y)``. An ``f`` that respects its input and output
+relations will be called a unary covariant *morphism*. We can also say
+that ``f`` is a monotone function with respect to ``R1`` and ``R2`` . The
+sequence ``x1 ... xn`` represents the parameters of the morphism.
+
+Let ``R1`` and ``R2`` be two parametric relations. The *signature* of a
+parametric morphism of type ``forall (x1 :T1 ) ... (xn :Tn ), A1 -> A2``
+that covariantly respects two instances :math:`I_{R_1}` and :math:`I_{R_2}` of ``R1`` and ``R2``
+is written :math:`I_{R_1} ++> I_{R_2}`. Notice that the special arrow ++>, which
+reminds the reader of covariance, is placed between the two relation
+instances, not between the two carriers. The signature relation
+instances and morphism will be typed in a context introducing
+variables for the parameters.
+
+The previous definitions are extended straightforwardly to n-ary
+morphisms, that are required to be simultaneously monotone on every
+argument.
+
+Morphisms can also be contravariant in one or more of their arguments.
+A morphism is contravariant on an argument associated to the relation
+instance :math`R` if it is covariant on the same argument when the inverse
+relation :math:`R^{−1}` (``inverse R`` in Coq) is considered. The special arrow ``-->``
+is used in signatures for contravariant morphisms.
+
+Functions having arguments related by symmetric relations instances
+are both covariant and contravariant in those arguments. The special
+arrow ``==>`` is used in signatures for morphisms that are both
+covariant and contravariant.
+
+An instance of a parametric morphism :math:`f` with :math:`n`
+parameters is any term :math:`f \, t_1 \ldots t_n`.
+
+**Example 3 (Morphisms):**
+
+Continuing the previous example, let ``union: forall (A: Type), list A -> list A -> list A``
+perform the union of two sets by appending one list to the other. ``union` is a binary
+morphism parametric over ``A`` that respects the relation instance
+``(set_eq A)``. The latter condition is proved by showing:
+
+.. coqtop:: in
+
+ forall (A: Type) (S1 S1’ S2 S2’: list A),
+ set_eq A S1 S1’ ->
+ set_eq A S2 S2’ ->
+ set_eq A (union A S1 S2) (union A S1’ S2’).
+
+The signature of the function ``union A`` is ``set_eq A ==> set_eq A ==> set_eq A``
+for all ``A``.
+
+**Example 4 (Contravariant morphism):**
+
+The division function ``Rdiv: R -> R -> R`` is a morphism of signature
+``le ++> le --> le`` where ``le`` is the usual order relation over
+real numbers. Notice that division is covariant in its first argument
+and contravariant in its second argument.
+
+Leibniz equality is a relation and every function is a morphism that
+respects Leibniz equality. Unfortunately, Leibniz equality is not
+always the intended equality for a given structure.
+
+In the next section we will describe the commands to register terms as
+parametric relations and morphisms. Several tactics that deal with
+equality in Coq can also work with the registered relations. The exact
+list of tactic will be given :ref:`in this section <tactics-enabled-on-user-provided-relations>`.
+For instance, the tactic reflexivity can be used to close a goal ``R n n`` whenever ``R``
+is an instance of a registered reflexive relation. However, the
+tactics that replace in a context ``C[]`` one term with another one
+related by ``R`` must verify that ``C[]`` is a morphism that respects the
+intended relation. Currently the verification consists in checking
+whether ``C[]`` is a syntactic composition of morphism instances that respects some obvious
+compatibility constraints.
+
+
+**Example 5 (Rewriting):**
+
+Continuing the previous examples, suppose that the user must prove
+``set_eq int (union int (union int S1 S2) S2) (f S1 S2)`` under the
+hypothesis ``H: set_eq int S2 (@nil int)``. It
+is possible to use the ``rewrite`` tactic to replace the first two
+occurrences of ``S2`` with ``@nil int`` in the goal since the
+context ``set_eq int (union int (union int S1 nil) nil) (f S1 S2)``,
+being a composition of morphisms instances, is a morphism. However the
+tactic will fail replacing the third occurrence of ``S2`` unless ``f``
+has also been declared as a morphism.
+
+
+Adding new relations and morphisms
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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.
+
+after having required the ``Setoid`` module with the ``Require Setoid``
+command.
+
+The :g:`@ident` gives a unique name to the morphism and it is used
+by the command to generate fresh names for automatically provided
+lemmas used internally.
+
+Notice that the carrier and relation parameters may refer to the
+context of variables introduced at the beginning of the declaration,
+but the instances need not be made only of variables. Also notice that
+``A`` is *not* required to be a term having the same parameters as ``Aeq``,
+although that is often the case in practice (this departs from the
+previous implementation).
+
+
+.. cmd:: Add Relation
+
+In case the carrier and relations are not parametric, one can use this command
+instead, whose syntax is the same except there is no local context.
+
+The proofs of reflexivity, symmetry and transitivity can be omitted if
+the relation is not an equivalence relation. The proofs must be
+instances of the corresponding relation definitions: e.g. the proof of
+reflexivity must have a type convertible to
+:g:`reflexive (A t1 ... tn) (Aeq t′ 1 …t′ n )`.
+Each proof may refer to the introduced variables as well.
+
+**Example 6 (Parametric relation):**
+
+For Leibniz equality, we may declare:
+
+.. coqtop:: in
+
+ Add Parametric Relation (A : Type) : A (@eq A)
+ [reflexivity proved by @refl_equal A]
+ ...
+
+Some tactics (``reflexivity``, ``symmetry``, ``transitivity``) work only on
+relations that respect the expected properties. The remaining tactics
+(``replace``, ``rewrite`` and derived tactics such as ``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.
+
+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
+the base name of the type class instance definition and as the name of
+the lemma that proves the well-definedness of the morphism. The
+parameters of the morphism as well as the signature may refer to the
+context of variables. The command asks the user to prove interactively
+that ``f`` respects the relations identified from the signature.
+
+**Example 7:**
+
+We start the example by assuming a small theory over
+homogeneous sets and we declare set equality as a parametric
+equivalence relation and union of two sets as a parametric morphism.
+
+.. coqtop:: in
+
+ Require Export Setoid.
+ Require Export Relation_Definitions.
+
+ Set Implicit Arguments.
+
+ Parameter set: Type -> Type.
+ Parameter empty: forall A, set A.
+ Parameter eq_set: forall A, set A -> set A -> Prop.
+ Parameter union: forall A, set A -> set A -> set A.
+
+ Axiom eq_set_refl: forall A, reflexive _ (eq_set (A:=A)).
+ Axiom eq_set_sym: forall A, symmetric _ (eq_set (A:=A)).
+ Axiom eq_set_trans: forall A, transitive _ (eq_set (A:=A)).
+ Axiom empty_neutral: forall A (S: set A), eq_set (union S (empty A)) S.
+
+ Axiom union_compat: forall (A : Type),
+ forall x x' : set A, eq_set x x' ->
+ forall y y' : set A, eq_set y y' ->
+ eq_set (union x y) (union x' y').
+
+ Add Parametric Relation A : (set A) (@eq_set A)
+ reflexivity proved by (eq_set_refl (A:=A))
+ symmetry proved by (eq_set_sym (A:=A))
+ transitivity proved by (eq_set_trans (A:=A))
+ as eq_set_rel.
+
+ Add Parametric Morphism A : (@union A) with
+ signature (@eq_set A) ==> (@eq_set A) ==> (@eq_set A) as union_mor.
+ Proof.
+ exact (@union_compat A).
+ Qed.
+
+It is possible to reduce the burden of specifying parameters using
+(maximally inserted) implicit arguments. If ``A`` is always set as
+maximally implicit in the previous example, one can write:
+
+.. coqtop:: in
+
+ Add Parametric Relation A : (set A) eq_set
+ reflexivity proved by eq_set_refl
+ symmetry proved by eq_set_sym
+ transitivity proved by eq_set_trans
+ as eq_set_rel.
+
+.. coqtop:: in
+
+ Add Parametric Morphism A : (@union A) with
+ signature eq_set ==> eq_set ==> eq_set as union_mor.
+
+.. coqtop:: in
+
+ Proof. exact (@union_compat A). Qed.
+
+We proceed now by proving a simple lemma performing a rewrite step and
+then applying reflexivity, as we would do working with Leibniz
+equality. Both tactic applications are accepted since the required
+properties over ``eq_set`` and ``union`` can be established from the two
+declarations above.
+
+.. coqtop:: in
+
+ Goal forall (S: set nat),
+ eq_set (union (union S empty) S) (union S S).
+
+.. coqtop:: in
+
+ Proof. intros. rewrite empty_neutral. reflexivity. Qed.
+
+The tables of relations and morphisms are managed by the type class
+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
+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
+definition time. When loading a compiled file or importing a module,
+all the declarations of this module will be loaded.
+
+
+Rewriting and non reflexive relations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To replace only one argument of an n-ary morphism it is necessary to
+prove that all the other arguments are related to themselves by the
+respective relation instances.
+
+**Example 8:**
+
+To replace ``(union S empty)`` with ``S`` in ``(union (union S empty) S) (union S S)``
+the rewrite tactic must exploit the monotony of ``union`` (axiom ``union_compat``
+in the previous example). Applying ``union_compat`` by hand we are left with the
+goal ``eq_set (union S S) (union S S)``.
+
+When the relations associated to some arguments are not reflexive, the
+tactic cannot automatically prove the reflexivity goals, that are left
+to the user.
+
+Setoids whose relation are partial equivalence relations (PER) are
+useful to deal with partial functions. Let ``R`` be a PER. We say that an
+element ``x`` is defined if ``R x x``. A partial function whose domain
+comprises all the defined elements only is declared as a morphism that
+respects ``R``. Every time a rewriting step is performed the user must
+prove that the argument of the morphism is defined.
+
+**Example 9:**
+
+Let ``eqO`` be ``fun x y => x = y /\ x <> 0`` (the
+smaller PER over non zero elements). Division can be declared as a
+morphism of signature ``eq ==> eq0 ==> eq``. Replace ``x`` with
+``y`` in ``div x n = div y n`` opens the additional goal ``eq0 n n``
+that is equivalent to ``n = n /\ n <> 0``.
+
+
+Rewriting and non symmetric relations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When the user works up to relations that are not symmetric, it is no
+longer the case that any covariant morphism argument is also
+contravariant. As a result it is no longer possible to replace a term
+with a related one in every context, since the obtained goal implies
+the previous one if and only if the replacement has been performed in
+a contravariant position. In a similar way, replacement in an
+hypothesis can be performed only if the replaced term occurs in a
+covariant position.
+
+**Example 10 (Covariance and contravariance):**
+
+Suppose that division over real numbers has been defined as a morphism of signature
+``Z.div: Z.lt ++> Z.lt --> Z.lt`` (i.e. ``Z.div`` is increasing in
+its first argument, but decreasing on the second one). Let ``<``
+denotes ``Z.lt``. Under the hypothesis ``H: x < y`` we have
+``k < x / y -> k < x / x``, but not ``k < y / x -> k < x / x``. Dually,
+under the same hypothesis ``k < x / y -> k < y / y`` holds, but
+``k < y / x -> k < y / y`` does not. Thus, if the current goal is
+``k < x / x``, it is possible to replace only the second occurrence of
+``x`` (in contravariant position) with ``y`` since the obtained goal
+must imply the current one. On the contrary, if ``k < x / x`` is an
+hypothesis, it is possible to replace only the first occurrence of
+``x`` (in covariant position) with ``y`` since the current
+hypothesis must imply the obtained one.
+
+Contrary to the previous implementation, no specific error message
+will be raised when trying to replace a term that occurs in the wrong
+position. It will only fail because the rewriting constraints are not
+satisfiable. However it is possible to use the at modifier to specify
+which occurrences should be rewritten.
+
+As expected, composing morphisms together propagates the variance
+annotations by switching the variance every time a contravariant
+position is traversed.
+
+**Example 11:**
+
+Let us continue the previous example and let us consider
+the goal ``x / (x / x) < k``. The first and third occurrences of
+``x`` are in a contravariant position, while the second one is in
+covariant position. More in detail, the second occurrence of ``x``
+occurs covariantly in ``(x / x)`` (since division is covariant in
+its first argument), and thus contravariantly in ``x / (x / x)``
+(since division is contravariant in its second argument), and finally
+covariantly in ``x / (x / x) < k`` (since ``<``, as every
+transitive relation, is contravariant in its first argument with
+respect to the relation itself).
+
+
+Rewriting in ambiguous setoid contexts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+One function can respect several different relations and thus it can
+be declared as a morphism having multiple signatures.
+
+**Example 12:**
+
+
+Union over homogeneous lists can be given all the
+following signatures: ``eq ==> eq ==> eq`` (``eq`` being the
+equality over ordered lists) ``set_eq ==> set_eq ==> set_eq``
+(``set_eq`` being the equality over unordered lists up to duplicates),
+``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``
+command.
+
+When morphisms have multiple signatures it can be the case that a
+rewrite request is ambiguous, since it is unclear what relations
+should be used to perform the rewriting. Contrary to the previous
+implementation, the tactic will always choose the first possible
+solution to the set of constraints generated by a rewrite and will not
+try to find *all* possible solutions to warn the user about.
+
+
+Commands and tactics
+--------------------
+
+
+.. _first-class-setoids-and-morphisms:
+
+First class setoids and morphisms
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+The implementation is based on a first-class representation of
+properties of relations and morphisms as type classes. That is, the
+various combinations of properties on relations and morphisms are
+represented as records and instances of theses classes are put in a
+hint database. For example, the declaration:
+
+.. coqtop:: in
+
+ 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 id.
+
+
+is equivalent to an instance declaration:
+
+.. coqtop:: in
+
+ Instance (x1 : T1) ... (xn : Tk) => id : @Equivalence (A t1 ... tn) (Aeq t′1 ... t′m) :=
+ [Equivalence_Reflexive := refl]
+ [Equivalence_Symmetric := sym]
+ [Equivalence_Transitive := trans].
+
+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:`typeclasses`
+and the theories files in Classes for further explanations.
+
+One can inform the rewrite tactic about morphisms and relations just
+by using the typeclass mechanism to declare them using Instance and
+Context vernacular commands. Any object of type Proper (the type of
+morphism declarations) in the local context will also be automatically
+used by the rewriting tactic to solve constraints.
+
+Other representations of first class setoids and morphisms can also be
+handled by encoding them as records. In the following example, the
+projections of the setoid relation and of the morphism function can be
+registered as parametric relations and morphisms.
+
+**Example 13 (First class setoids):**
+
+.. coqtop:: in
+
+ Require Import Relation_Definitions Setoid.
+
+ Record Setoid: Type :=
+ { car: Type;
+ eq: car -> car -> Prop;
+ refl: reflexive _ eq;
+ sym: symmetric _ eq;
+ trans: transitive _ eq
+ }.
+
+ Add Parametric Relation (s : Setoid) : (@car s) (@eq s)
+ reflexivity proved by (refl s)
+ symmetry proved by (sym s)
+ transitivity proved by (trans s) as eq_rel.
+
+ Record Morphism (S1 S2:Setoid): Type :=
+ { f: car S1 -> car S2;
+ compat: forall (x1 x2: car S1), eq S1 x1 x2 -> eq S2 (f x1) (f x2)
+ }.
+
+ Add Parametric Morphism (S1 S2 : Setoid) (M : Morphism S1 S2) :
+ (@f S1 S2 M) with signature (@eq S1 ==> @eq S2) as apply_mor.
+ Proof. apply (compat S1 S2 M). Qed.
+
+ Lemma test: forall (S1 S2:Setoid) (m: Morphism S1 S2)
+ (x y: car S1), eq S1 x y -> eq S2 (f _ _ m x) (f _ _ m y).
+ Proof. intros. rewrite H. reflexivity. Qed.
+
+.. _tactics-enabled-on-user-provided-relations:
+
+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
+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.
+The latter argument tells the tactic what parametric relation should
+be used to replace the first tactic argument with the second one. If
+omitted, it defaults to the ``DefaultRelation`` instance on the type of
+the objects. By default, it means the most recent ``Equivalence`` instance
+in the environment, but it can be customized by declaring
+new ``DefaultRelation`` instances. As Leibniz equality is a declared
+equivalence, it will fall back to it if no other relation is declared
+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
+are not proof of Leibniz equalities. In particular it is possible to
+exploit ``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
+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
+what additional morphisms should be registered.
+
+
+Deprecated syntax and backward incompatibilities
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Due to backward compatibility reasons, the following syntax for the
+declaration of setoids and morphisms is also accepted.
+
+.. 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
+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.
+
+The latter command also is restricted to the declaration of morphisms
+without parameters. It is not fully backward compatible since the
+property the user is asked to prove is slightly different: for n-ary
+morphisms the hypotheses of the property are permuted; moreover, when
+the morphism returns a proposition, the property is now stated using a
+bi-implication in place of a simple implication. In practice, porting
+an old development to the new semantics is usually quite simple.
+
+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
+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``.
+
+
+Extensions
+----------
+
+
+Rewriting under binders
+~~~~~~~~~~~~~~~~~~~~~~~
+
+warning:: Due to compatibility issues, this feature is enabled only
+when calling the ``setoid_rewrite`` tactics directly and not ``rewrite``.
+
+To be able to rewrite under binding constructs, one must declare
+morphisms with respect to pointwise (setoid) equivalence of functions.
+Example of such morphisms are the standard ``all`` and ``ex`` combinators for
+universal and existential quantification respectively. They are
+declared as morphisms in the ``Classes.Morphisms_Prop`` module. For
+example, to declare that universal quantification is a morphism for
+logical equivalence:
+
+.. coqtop:: in
+
+ Instance all_iff_morphism (A : Type) :
+ Proper (pointwise_relation A iff ==> iff) (@all A).
+
+.. coqtop:: all
+
+ Proof. simpl_relation.
+
+One then has to show that if two predicates are equivalent at every
+point, their universal quantifications are equivalent. Once we have
+declared such a morphism, it will be used by the setoid rewriting
+tactic each time we try to rewrite under an ``all`` application (products
+in ``Prop`` are implicitly translated to such applications).
+
+Indeed, when rewriting under a lambda, binding variable ``x``, say from ``P x``
+to ``Q x`` using the relation iff, the tactic will generate a proof of
+``pointwise_relation A iff (fun x => P x) (fun x => Q x)`` from the proof
+of ``iff (P x) (Q x)`` and a constraint of the form Proper
+``(pointwise_relation A iff ==> ?) m`` will be generated for the
+surrounding morphism ``m``.
+
+Hence, one can add higher-order combinators as morphisms by providing
+signatures using pointwise extension for the relations on the
+functional arguments (or whatever subrelation of the pointwise
+extension). For example, one could declare the ``map`` combinator on lists
+as a morphism:
+
+.. coqtop:: in
+
+ Instance map_morphism `{Equivalence A eqA, Equivalence B eqB} :
+ Proper ((eqA ==> eqB) ==> list_equiv eqA ==> list_equiv eqB) (@map A B).
+
+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
+variable, as the semantics are different from rewrite where the lemma
+is first matched on the whole term. With the new ``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
+can almost be recovered using the ``at 1`` modifier.
+
+
+Sub-relations
+~~~~~~~~~~~~~
+
+Sub-relations can be used to specify that one relation is included in
+another, so that morphisms signatures for one can be used for the
+other. If a signature mentions a relation ``R`` on the left of an
+arrow ``==>``, then the signature also applies for any relation ``S`` that is
+smaller than ``R``, and the inverse applies on the right of an arrow. One
+can then declare only a few morphisms instances that generate the
+complete set of signatures for a particular constant. By default, the
+only declared subrelation is ``iff``, which is a subrelation of ``impl`` and
+``inverse impl`` (the dual of implication). That’s why we can declare only
+two morphisms for conjunction: ``Proper (impl ==> impl ==> impl) and`` and
+``Proper (iff ==> iff ==> iff) and``. This is sufficient to satisfy any
+rewriting constraints arising from a rewrite using ``iff``, ``impl`` or
+``inverse impl`` through ``and``.
+
+Sub-relations are implemented in ``Classes.Morphisms`` and are a prime
+example of a mostly user-space extension of the algorithm.
+
+
+Constant unfolding
+~~~~~~~~~~~~~~~~~~
+
+The resolution tactic is based on type classes and hence regards user-
+defined constants as transparent by default. This may slow down the
+resolution due to a lot of unifications (all the declared ``Proper``
+instances are tried at each node of the search tree). To speed it up,
+declare your constant as rigid for proof search using the command
+``Typeclasses Opaque`` (see :ref:`TypeclassesTransparent`).
+
+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 :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:
+
+.. productionlist:: rewriting
+ s, t, u : `strategy`
+ : | `lemma`
+ : | `lemma_right_to_left`
+ : | `failure`
+ : | `identity`
+ : | `reflexivity`
+ : | `progress`
+ : | `failure_catch`
+ : | `composition`
+ : | `left_biased_choice`
+ : | `iteration_one_or_more`
+ : | `iteration_zero_or_more`
+ : | `one_subterm`
+ : | `all_subterms`
+ : | `innermost_first`
+ : | `outermost_first`
+ : | `bottom_up`
+ : | `top_down`
+ : | `apply_hint`
+ : | `any_of_the_terms`
+ : | `apply_reduction`
+ : | `fold_expression`
+
+.. productionlist:: rewriting
+ strategy : "(" `s` ")"
+ lemma : `c`
+ lemma_right_to_left : "<-" `c`
+ failure : `fail`
+ identity : `id`
+ reflexivity : `refl`
+ progress : `progress` `s`
+ failure_catch : `try` `s`
+ composition : `s` ";" `u`
+ left_biased_choice : choice `s` `t`
+ iteration_one_or_more : `repeat` `s`
+ iteration_zero_or_more : `any` `s`
+ one_subterm : subterm `s`
+ all_subterms : subterms `s`
+ innermost_first : `innermost` `s`
+ outermost_first : `outermost` `s`
+ bottom_up : `bottomup` `s`
+ top_down : `topdown` `s`
+ apply_hint : hints `hintdb`
+ any_of_the_terms : terms (`c`)+
+ apply_reduction : eval `redexpr`
+ fold_expression : fold `c`
+
+
+Actually a few of these are defined in term of the others using a
+primitive fixpoint operator:
+
+.. productionlist:: rewriting
+ try `s` : choice `s` `id`
+ any `s` : fix `u`. try (`s` ; `u`)
+ repeat `s` : `s` ; `any` `s`
+ bottomup s : fix `bu`. (choice (progress (subterms bu)) s) ; try bu
+ topdown s : fix `td`. (choice s (progress (subterms td))) ; try td
+ innermost s : fix `i`. (choice (subterm i) s)
+ outermost s : fix `o`. (choice s (subterm o))
+
+The basic control strategy semantics are straightforward: strategies
+are applied to subterms of the term to rewrite, starting from the root
+of the term. The lemma strategies unify the left-hand-side of the
+lemma with the current subterm and on success rewrite it to the right-
+hand-side. Composition can be used to continue rewriting on the
+current subterm. The fail strategy always fails while the identity
+strategy succeeds without making progress. The reflexivity strategy
+succeeds, making progress using a reflexivity proof of rewriting.
+Progress tests progress of the argument strategy and fails if no
+progress was made, while ``try`` always succeeds, catching failures.
+Choice is left-biased: it will launch the first strategy and fall back
+on the second one in case of failure. One can iterate a strategy at
+least 1 time using ``repeat`` and at least 0 times using ``any``.
+
+The ``subterm`` and ``subterms`` strategies apply their argument strategy ``s`` to
+respectively one or all subterms of the current term under
+consideration, left-to-right. ``subterm`` stops at the first subterm for
+which ``s`` made progress. The composite strategies ``innermost`` and ``outermost``
+perform a single innermost or outermost rewrite using their argument
+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
+lemmas at the current subterm. The ``terms`` strategy takes the lemma
+names directly as arguments. The ``eval`` strategy expects a reduction
+expression (see :ref:`performingcomputations`) and succeeds
+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``.
+
+
+Usage
+~~~~~
+
+
+.. tacn:: rewrite_strat @s [in @ident]
+ :name: rewrite_strat
+
+ Rewrite using the strategy s in hypothesis ident or the conclusion.
+
+ .. exn:: Nothing to rewrite.
+
+ If the strategy failed.
+
+ .. exn:: No progress made.
+
+ If the strategy succeeded but made no progress.
+
+ .. exn:: Unable to satisfy the rewriting constraints.
+
+ If the strategy succeeded and made progress but the
+ corresponding rewriting constraints are not satisfied.
+
+
+ The ``setoid_rewrite c`` tactic is basically equivalent to
+ ``rewrite_strat (outermost c)``.
+
diff --git a/doc/sphinx/addendum/implicit-coercions.rst b/doc/sphinx/addendum/implicit-coercions.rst
new file mode 100644
index 000000000..c48c2d7ce
--- /dev/null
+++ b/doc/sphinx/addendum/implicit-coercions.rst
@@ -0,0 +1,464 @@
+.. include:: ../replaces.rst
+
+.. _implicitcoercions:
+
+Implicit Coercions
+====================
+
+:Author: Amokrane Saïbi
+
+General Presentation
+---------------------
+
+This section describes the inheritance mechanism of |Coq|. In |Coq| with
+inheritance, we are not interested in adding any expressive power to
+our theory, but only convenience. Given a term, possibly not typable,
+we are interested in the problem of determining if it can be well
+typed modulo insertion of appropriate coercions. We allow to write:
+
+ * :g:`f a` where :g:`f:(forall x:A,B)` and :g:`a:A'` when ``A'`` can
+ be seen in some sense as a subtype of ``A``.
+ * :g:`x:A` when ``A`` is not a type, but can be seen in
+ a certain sense as a type: set, group, category etc.
+ * :g:`f a` when ``f`` is not a function, but can be seen in a certain sense
+ as a function: bijection, functor, any structure morphism etc.
+
+
+Classes
+-------
+
+A class with `n` parameters is any defined name with a type
+:g:`forall (x₁:A₁)..(xₙ:Aₙ),s` where ``s`` is a sort. Thus a class with
+parameters is considered as a single class and not as a family of
+classes. An object of a class ``C`` is any term of type :g:`C t₁ .. tₙ`.
+In addition to these user-classes, we have two abstract classes:
+
+
+ * ``Sortclass``, the class of sorts; its objects are the terms whose type is a
+ sort (e.g. :g:`Prop` or :g:`Type`).
+ * ``Funclass``, the class of functions; its objects are all the terms with a functional
+ type, i.e. of form :g:`forall x:A,B`.
+
+Formally, the syntax of a classes is defined as:
+
+.. productionlist::
+ class: qualid
+ : | `Sortclass`
+ : | `Funclass`
+
+
+Coercions
+---------
+
+A name ``f`` can be declared as a coercion between a source user-class
+``C`` with `n` parameters and a target class ``D`` if one of these
+conditions holds:
+
+ * ``D`` is a user-class, then the type of ``f`` must have the form
+ :g:`forall (x₁:A₁)..(xₙ:Aₙ)(y:C x₁..xₙ), D u₁..uₘ` where `m`
+ is the number of parameters of ``D``.
+ * ``D`` is ``Funclass``, then the type of ``f`` must have the form
+ :g:`forall (x₁:A₁)..(xₙ:Aₙ)(y:C x₁..xₙ)(x:A), B`.
+ * ``D`` is ``Sortclass``, then the type of ``f`` must have the form
+ :g:`forall (x₁:A₁)..(xₙ:Aₙ)(y:C x₁..xₙ), s` with ``s`` a sort.
+
+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
+ the abstract class ``Funclass`` cannot.
+
+To coerce an object :g:`t:C t₁..tₙ` of ``C`` towards ``D``, we have to
+apply the coercion ``f`` to it; the obtained term :g:`f t₁..tₙ t` is
+then an object of ``D``.
+
+
+Identity Coercions
+-------------------
+
+Identity coercions are special cases of coercions used to go around
+the uniform inheritance condition. Let ``C`` and ``D`` be two classes
+with respectively `n` and `m` parameters and
+:g:`f:forall (x₁:T₁)..(xₖ:Tₖ)(y:C u₁..uₙ), D v₁..vₘ` a function which
+does not verify the uniform inheritance condition. To declare ``f`` as
+coercion, one has first to declare a subclass ``C'`` of ``C``:
+
+ :g:`C' := fun (x₁:T₁)..(xₖ:Tₖ) => C u₁..uₙ`
+
+We then define an *identity coercion* between ``C'`` and ``C``:
+
+ :g:`Id_C'_C := fun (x₁:T₁)..(xₖ:Tₖ)(y:C' x₁..xₖ) => (y:C u₁..uₙ)`
+
+We can now declare ``f`` as coercion from ``C'`` to ``D``, since we can
+"cast" its type as
+:g:`forall (x₁:T₁)..(xₖ:Tₖ)(y:C' x₁..xₖ),D v₁..vₘ`.
+
+The identity coercions have a special status: to coerce an object
+:g:`t:C' t₁..tₖ`
+of ``C'`` towards ``C``, we does not have to insert explicitly ``Id_C'_C``
+since :g:`Id_C'_C t₁..tₖ t` is convertible with ``t``. However we
+"rewrite" the type of ``t`` to become an object of ``C``; in this case,
+it becomes :g:`C uₙ'..uₖ'` where each ``uᵢ'`` is the result of the
+substitution in ``uᵢ`` of the variables ``xⱼ`` by ``tⱼ``.
+
+Inheritance Graph
+------------------
+
+Coercions form an inheritance graph with classes as nodes. We call
+*coercion path* an ordered list of coercions between two nodes of
+the graph. A class ``C`` is said to be a subclass of ``D`` if there is a
+coercion path in the graph from ``C`` to ``D``; we also say that ``C``
+inherits from ``D``. Our mechanism supports multiple inheritance since a
+class may inherit from several classes, contrary to simple inheritance
+where a class inherits from at most one class. However there must be
+at most one path between two classes. If this is not the case, only
+the *oldest* one is valid and the others are ignored. So the order
+of declaration of coercions is important.
+
+We extend notations for coercions to coercion paths. For instance
+:g:`[f₁;..;fₖ] : C >-> D` is the coercion path composed
+by the coercions ``f₁..fₖ``. The application of a coercion path to a
+term consists of the successive application of its coercions.
+
+
+Declaration of Coercions
+-------------------------
+
+.. 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:: Found target class ... instead of ...
+
+ .. 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.
+
+ Declares the construction denoted by `qualid` as a coercion local to
+ the current section.
+
+ .. 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.
+
+ 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.
+
+ 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:`vernacular` as follows:
+
+..
+ FIXME:
+ \comindex{Variable \mbox{\rm (and coercions)}}
+ \comindex{Axiom \mbox{\rm (and coercions)}}
+ \comindex{Parameter \mbox{\rm (and coercions)}}
+ \comindex{Hypothesis \mbox{\rm (and coercions)}}
+
+.. productionlist::
+ assumption : assumption_keyword assums .
+ assums : simple_assums
+ : | (simple_assums) ... (simple_assums)
+ simple_assums : ident ... ident :[>] term
+
+If the extra ``>`` is present before the type of some assumptions, these
+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:`vernacular` as follows:
+
+..
+ FIXME:
+ \comindex{Inductive \mbox{\rm (and coercions)}}
+ \comindex{CoInductive \mbox{\rm (and coercions)}}
+
+.. productionlist::
+ inductive : `Inductive` ind_body `with` ... `with` ind_body
+ : | `CoInductive` ind_body `with` ... `with` ind_body
+ ind_body : ident [binders] : term := [[|] constructor | ... | constructor]
+ constructor : ident [binders] [:[>] term]
+
+Especially, if the extra ``>`` is present in a constructor
+declaration, this constructor is declared as a coercion.
+
+.. 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
+ :g:`fun (x₁:T₁)..(xₙ:Tₙ) => D t₁..tₘ` where `m` is the
+ number of parameters of ``D``. Then we define an identity
+ 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
+
+ .. cmdv:: Local Identity Coercion @ident : @ident >-> @ident.
+
+ Idem but locally to the current section.
+
+ .. 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
+ `Id_ident_ident'` is
+ declared. Otherwise said, this is an abbreviation for
+
+ ``Definition`` `ident` ``:=`` `type`.
+
+ ``Identity Coercion`` `Id_ident_ident'` : `ident` ``>->`` `ident'`.
+
+ .. cmdv:: Local SubClass @ident := @type.
+
+ Same as before but locally to the current section.
+
+
+Displaying Available Coercions
+-------------------------------
+
+.. cmd:: Print Classes.
+
+ Print the list of declared classes in the current context.
+
+.. cmd:: Print Coercions.
+
+ Print the list of declared coercions in the current context.
+
+.. cmd:: Print Graph.
+
+ Print the list of valid coercion paths in the current context.
+
+.. cmd:: Print Coercion Paths @class @class.
+
+ Print the list of valid coercion paths between the two given classes.
+
+Activating the Printing of 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 coercion denoted by :n:`@qualid` to be printed. To skip
+ the printing of coercion :n:`@qualid`, use :cmd:`Remove Printing Coercion`. By
+ default, a coercion is never printed.
+
+.. _coercions-classes-as-records:
+
+Classes as Records
+------------------
+
+We allow the definition of *Structures with Inheritance* (or classes as records)
+by extending the existing :cmd:`Record` macro. Its new syntax is:
+
+.. cmdv:: Record {? >} @ident {? @binders} : @sort := {? @ident} { {+; @ident :{? >} @term } }.
+
+ 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).
+
+.. cmdv:: Structure {? >} @ident {? @binders} : @sort := {? @ident} { {+; @ident :{? >} @term } }.
+ :name: Structure
+
+ This is a synonym of :cmd:`Record`.
+
+
+Coercions and Sections
+----------------------
+
+The inheritance mechanism is compatible with the section
+mechanism. The global classes and coercions defined inside a section
+are redefined after its closing, using their new value and new
+type. The classes and coercions which are local to the section are
+simply forgotten.
+Coercions with a local source class or a local target class, and
+coercions which do not verify the uniform inheritance condition any longer
+are also forgotten.
+
+Coercions and Modules
+---------------------
+
+.. opt:: 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
+--------
+
+There are three situations:
+
+Coercion at function application
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:g:`f a` is ill-typed where :g:`f:forall x:A,B` and :g:`a:A'`. If there is a
+coercion path between ``A'`` and ``A``, then :g:`f a` is transformed into
+:g:`f a'` where ``a'`` is the result of the application of this
+coercion path to ``a``.
+
+We first give an example of coercion between atomic inductive types
+
+.. coqtop:: all
+
+ Definition bool_in_nat (b:bool) := if b then 0 else 1.
+ Coercion bool_in_nat : bool >-> nat.
+ Check (0 = true).
+ Set Printing Coercions.
+ Check (0 = true).
+ Unset Printing Coercions.
+
+
+.. warning::
+
+ Note that ``Check true=O`` would fail. This is "normal" behaviour of
+ coercions. To validate ``true=O``, the coercion is searched from
+ ``nat`` to ``bool``. There is none.
+
+We give an example of coercion between classes with parameters.
+
+.. coqtop:: all
+
+ Parameters (C : nat -> Set) (D : nat -> bool -> Set) (E : bool -> Set).
+ Parameter f : forall n:nat, C n -> D (S n) true.
+ Coercion f : C >-> D.
+ Parameter g : forall (n:nat) (b:bool), D n b -> E b.
+ Coercion g : D >-> E.
+ Parameter c : C 0.
+ Parameter T : E true -> nat.
+ Check (T c).
+ Set Printing Coercions.
+ Check (T c).
+ Unset Printing Coercions.
+
+We give now an example using identity coercions.
+
+.. coqtop:: all
+
+ Definition D' (b:bool) := D 1 b.
+ Identity Coercion IdD'D : D' >-> D.
+ Print IdD'D.
+ Parameter d' : D' true.
+ Check (T d').
+ Set Printing Coercions.
+ Check (T d').
+ Unset Printing Coercions.
+
+
+In the case of functional arguments, we use the monotonic rule of
+sub-typing. Approximatively, to coerce :g:`t:forall x:A,B` towards
+:g:`forall x:A',B'`, one have to coerce ``A'`` towards ``A`` and ``B``
+towards ``B'``. An example is given below:
+
+.. coqtop:: all
+
+ Parameters (A B : Set) (h : A -> B).
+ Coercion h : A >-> B.
+ Parameter U : (A -> E true) -> nat.
+ Parameter t : B -> C 0.
+ Check (U t).
+ Set Printing Coercions.
+ Check (U t).
+ Unset Printing Coercions.
+
+Remark the changes in the result following the modification of the
+previous example.
+
+.. coqtop:: all
+
+ Parameter U' : (C 0 -> B) -> nat.
+ Parameter t' : E true -> A.
+ Check (U' t').
+ Set Printing Coercions.
+ Check (U' t').
+ Unset Printing Coercions.
+
+
+Coercion to a type
+~~~~~~~~~~~~~~~~~~
+
+An assumption ``x:A`` when ``A`` is not a type, is ill-typed. It is
+replaced by ``x:A'`` where ``A'`` is the result of the application to
+``A`` of the coercion path between the class of ``A`` and
+``Sortclass`` if it exists. This case occurs in the abstraction
+:g:`fun x:A => t`, universal quantification :g:`forall x:A,B`, global
+variables and parameters of (co-)inductive definitions and
+functions. In :g:`forall x:A,B`, such a coercion path may be applied
+to ``B`` also if necessary.
+
+.. coqtop:: all
+
+ Parameter Graph : Type.
+ Parameter Node : Graph -> Type.
+ Coercion Node : Graph >-> Sortclass.
+ Parameter G : Graph.
+ Parameter Arrows : G -> G -> Type.
+ Check Arrows.
+ Parameter fg : G -> G.
+ Check fg.
+ Set Printing Coercions.
+ Check fg.
+ Unset Printing Coercions.
+
+
+Coercion to a function
+~~~~~~~~~~~~~~~~~~~~~~
+
+``f a`` is ill-typed because ``f:A`` is not a function. The term
+``f`` is replaced by the term obtained by applying to ``f`` the
+coercion path between ``A`` and ``Funclass`` if it exists.
+
+.. coqtop:: all
+
+ Parameter bij : Set -> Set -> Set.
+ Parameter ap : forall A B:Set, bij A B -> A -> B.
+ Coercion ap : bij >-> Funclass.
+ Parameter b : bij nat nat.
+ Check (b 0).
+ Set Printing Coercions.
+ Check (b 0).
+ Unset Printing Coercions.
+
+Let us see the resulting graph after all these examples.
+
+.. coqtop:: all
+
+ Print Graph.
diff --git a/doc/sphinx/addendum/micromega.rst b/doc/sphinx/addendum/micromega.rst
index e850587c8..4f8cc34d4 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 :tac:`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
new file mode 100644
index 000000000..80ea8a116
--- /dev/null
+++ b/doc/sphinx/addendum/miscellaneous-extensions.rst
@@ -0,0 +1,59 @@
+.. include:: ../replaces.rst
+
+.. _miscellaneousextensions:
+
+Miscellaneous extensions
+========================
+
+Program derivation
+------------------
+
+|Coq| comes with an extension called ``Derive``, which supports program
+derivation. Typically in the style of Bird and Meertens or derivations
+of program refinements. To use the Derive extension it must first be
+required with ``Require Coq.Derive.Derive``. When the extension is loaded,
+it provides the following command:
+
+.. cmd:: Derive @ident SuchThat @term As @ident
+
+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 :tacn:`shelve`).
+
+When the proof ends two constants are defined:
+
++ The first one is named using the first `ident` and is defined as the proof of the
+ shelved goal (which is also the value of `?x`). It is always
+ transparent.
++ The second one is named using the second `ident`. It has type `term`, and its body is
+ the proof of the initially visible goal. It is opaque if the proof
+ ends with ``Qed``, and transparent if the proof ends with ``Defined``.
+
+.. example::
+ .. coqtop:: all
+
+ Require Coq.derive.Derive.
+ Require Import Coq.Numbers.Natural.Peano.NPeano.
+
+ Section P.
+
+ Variables (n m k:nat).
+
+ Derive p SuchThat ((k*n)+(k*m) = p) As h.
+ Proof.
+ rewrite <- Nat.mul_add_distr_l.
+ subst p.
+ reflexivity.
+ Qed.
+
+ End P.
+
+ Print p.
+ Check h.
+
+Any property can be used as `term`, not only an equation. In particular,
+it could be an order relation specifying some form of program
+refinement or a non-executable property from which deriving a program
+is convenient.
diff --git a/doc/sphinx/addendum/nsatz.rst b/doc/sphinx/addendum/nsatz.rst
new file mode 100644
index 000000000..387d61495
--- /dev/null
+++ b/doc/sphinx/addendum/nsatz.rst
@@ -0,0 +1,101 @@
+.. include:: ../preamble.rst
+
+.. _nsatz:
+
+Nsatz: tactics for proving equalities in integral domains
+===========================================================
+
+:Author: Loïc Pottier
+
+The tactic `nsatz` proves goals of the form
+
+:math:`\begin{array}{l}
+\forall X_1,\ldots,X_n \in A,\\
+P_1(X_1,\ldots,X_n) = Q_1(X_1,\ldots,X_n) , \ldots , P_s(X_1,\ldots,X_n) =Q_s(X_1,\ldots,X_n)\\
+\vdash P(X_1,\ldots,X_n) = Q(X_1,\ldots,X_n)\\
+\end{array}`
+
+where :math:`P, Q, P₁,Q₁,\ldots,Pₛ, Qₛ` are polynomials and :math:`A` is an integral
+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:`tactics-enabled-on-user-provided-relations`) , not only Leibnitz equality.
+
+It also proves formulas
+
+:math:`\begin{array}{l}
+\forall X_1,\ldots,X_n \in A,\\
+P_1(X_1,\ldots,X_n) = Q_1(X_1,\ldots,X_n) \wedge \ldots \wedge P_s(X_1,\ldots,X_n) =Q_s(X_1,\ldots,X_n)\\
+\rightarrow P(X_1,\ldots,X_n) = Q(X_1,\ldots,X_n)\\
+\end{array}`
+
+doing automatic introductions.
+
+
+Using the basic tactic `nsatz`
+------------------------------
+
+
+Load the Nsatz module:
+
+.. coqtop:: all
+
+ Require Import Nsatz.
+
+and use the tactic `nsatz`.
+
+More about `nsatz`
+---------------------
+
+Hilbert’s Nullstellensatz theorem shows how to reduce proofs of
+equalities on polynomials on a commutative ring :math:`A` with no zero divisor
+to algebraic computations: it is easy to see that if a polynomial :math:`P` in
+:math:`A[X_1,\ldots,X_n]` verifies :math:`c P^r = \sum_{i=1}^{s} S_i P_i`, with
+:math:`c \in A`, :math:`c \not = 0`,
+:math:`r` a positive integer, and the :math:`S_i` s in :math:`A[X_1,\ldots,X_n ]`,
+then :math:`P` is zero whenever polynomials :math:`P_1,\ldots,P_s` are zero
+(the converse is also true when :math:`A` is an algebraic closed field: the method is
+complete).
+
+So, proving our initial problem can reduce into finding :math:`S_1,\ldots,S_s`,
+:math:`c` and :math:`r` such that :math:`c (P-Q)^r = \sum_{i} S_i (P_i-Q_i)`,
+which will be proved by the tactic ring.
+
+This is achieved by the computation of a Gröbner basis of the ideal
+generated by :math:`P_1-Q_1,...,P_s-Q_s`, with an adapted version of the
+Buchberger algorithm.
+
+This computation is done after a step of *reification*, which is
+performed using :ref:`typeclasses`.
+
+The ``Nsatz`` module defines the tactic `nsatz`, which can be used without
+arguments, or with the syntax:
+
+| nsatz with radicalmax:=num%N strategy:=num%Z parameters:= :n:`{* var}` variables:= :n:`{* var}`
+
+where:
+
+* `radicalmax` is a bound when for searching r s.t.
+ :math:`c (P−Q) r = \sum_{i=1..s} S_i (P i − Q i)`
+
+* `strategy` gives the order on variables :math:`X_1,\ldots,X_n` and the strategy
+ used in Buchberger algorithm (see :cite:`sugar` for details):
+
+ * strategy = 0: reverse lexicographic order and newest s-polynomial.
+ * strategy = 1: reverse lexicographic order and sugar strategy.
+ * strategy = 2: pure lexicographic order and newest s-polynomial.
+ * strategy = 3: pure lexicographic order and sugar strategy.
+
+* `parameters` is the list of variables :math:`X_{i_1},\ldots,X_{i_k}` among
+ :math:`X_1,\ldots,X_n` which are considered as parameters: computation will be performed with
+ rational fractions in these variables, i.e. polynomials are considered
+ with coefficients in :math:`R(X_{i_1},\ldots,X_{i_k})`. In this case, the coefficient
+ :math:`c` can be a non constant polynomial in :math:`X_{i_1},\ldots,X_{i_k}`, and the tactic
+ produces a goal which states that :math:`c` is not zero.
+
+* `variables` is the list of the variables in the decreasing order in
+ which they will be used in Buchberger algorithm. If `variables` = `(@nil R)`,
+ then `lvar` is replaced by all the variables which are not in
+ `parameters`.
+
+See file `Nsatz.v` for many examples, especially in geometry.
diff --git a/doc/sphinx/addendum/parallel-proof-processing.rst b/doc/sphinx/addendum/parallel-proof-processing.rst
new file mode 100644
index 000000000..edb8676a5
--- /dev/null
+++ b/doc/sphinx/addendum/parallel-proof-processing.rst
@@ -0,0 +1,229 @@
+.. include:: ../replaces.rst
+
+.. _asynchronousandparallelproofprocessing:
+
+Asynchronous and Parallel Proof Processing
+==========================================
+
+:Author: Enrico Tassi
+
+This chapter explains how proofs can be asynchronously processed by
+|Coq|. This feature improves the reactivity of the system when used in
+interactive mode via |CoqIDE|. In addition, it allows |Coq| to take
+advantage of parallel hardware when used as a batch compiler by
+decoupling the checking of statements and definitions from the
+construction and checking of proofs objects.
+
+This feature is designed to help dealing with huge libraries of
+theorems characterized by long proofs. In the current state, it may
+not be beneficial on small sets of short files.
+
+This feature has some technical limitations that may make it
+unsuitable for some use cases.
+
+For example, in interactive mode, some errors coming from the kernel
+of |Coq| are signaled late. The type of errors belonging to this
+category are universe inconsistencies.
+
+At the time of writing, only opaque proofs (ending with ``Qed`` or
+``Admitted``) can be processed asynchronously.
+
+Finally, asynchronous processing is disabled when running |CoqIDE| in
+Windows. The current implementation of the feature is not stable on
+Windows. It can be enabled, as described below at :ref:`interactive-mode`,
+though doing so is not recommended.
+
+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:`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:`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.
+
+It is not strictly mandatory in batch mode if it is not the first time
+the file is compiled and if the file itself did not change. When the
+proof does not begin with Proof using, the system records in an
+auxiliary file, produced along with the `.vo` file, the list of section
+variables used.
+
+Automatic suggestion of proof annotations
+`````````````````````````````````````````
+
+The command ``Set Suggest Proof Using`` makes |Coq| suggest, when a ``Qed``
+command is processed, a correct proof annotation. It is up to the user
+to modify the proof script accordingly.
+
+
+Proof blocks and error resilience
+--------------------------------------
+
+|Coq| 8.6 introduced a mechanism for error resiliency: in interactive
+mode |Coq| is able to completely check a document containing errors
+instead of bailing out at the first failure.
+
+Two kind of errors are supported: errors occurring in vernacular
+commands and errors occurring in proofs.
+
+To properly recover from a failing tactic, |Coq| needs to recognize the
+structure of the proof in order to confine the error to a sub proof.
+Proof block detection is performed by looking at the syntax of the
+proof script (i.e. also looking at indentation). |Coq| comes with four
+kind of proof blocks, and an ML API to add new ones.
+
+:curly: blocks are delimited by { and }, see Chapter :ref:`proofhandling`
+:par: blocks are atomic, i.e. just one tactic introduced by the `par:`
+ goal selector
+:indent: blocks end with a tactic indented less than the previous one
+:bullet: blocks are delimited by two equal bullet signs at the same
+ indentation level
+
+Caveats
+````````
+
+When a vernacular command fails the subsequent error messages may be
+bogus, i.e. caused by the first error. Error resiliency for vernacular
+commands can be switched off by passing ``-async-proofs-command-error-resilience off``
+to |CoqIDE|.
+
+An incorrect proof block detection can result into an incorrect error
+recovery and hence in bogus errors. Proof block detection cannot be
+precise for bullets or any other non well parenthesized proof
+structure. Error resiliency can be turned off or selectively activated
+for any set of block kind passing to |CoqIDE| one of the following
+options:
+
+- ``-async-proofs-tactic-error-resilience off``
+- ``-async-proofs-tactic-error-resilience all``
+- ``-async-proofs-tactic-error-resilience`` :n:`{*, blocktype}`
+
+Valid proof block types are: “curly”, “par”, “indent”, and “bullet”.
+
+.. _interactive-mode:
+
+Interactive mode
+---------------------
+
+At the time of writing the only user interface supporting asynchronous
+proof processing is |CoqIDE|.
+
+When |CoqIDE| is started, two |Coq| processes are created. The master one
+follows the user, giving feedback as soon as possible by skipping
+proofs, which are delegated to the worker process. The worker process,
+whose state can be seen by clicking on the button in the lower right
+corner of the main |CoqIDE| window, asynchronously processes the proofs.
+If a proof contains an error, it is reported in red in the label of
+the very same button, that can also be used to see the list of errors
+and jump to the corresponding line.
+
+If a proof is processed asynchronously the corresponding Qed command
+is colored using a lighter color that usual. This signals that the
+proof has been delegated to a worker process (or will be processed
+lazily if the ``-async-proofs lazy`` option is used). Once finished, the
+worker process will provide the proof object, but this will not be
+automatically checked by the kernel of the main process. To force the
+kernel to check all the proof objects, one has to click the button
+with the gears. Only then are all the universe constraints checked.
+
+Caveats
+```````
+
+The number of worker processes can be increased by passing |CoqIDE|
+the ``-async-proofs-j n`` flag. Note that the memory consumption increases too,
+since each worker requires the same amount of memory as the master
+process. Also note that increasing the number of workers may reduce
+the reactivity of the master process to user commands.
+
+To disable this feature, one can pass the ``-async-proofs off`` flag to
+|CoqIDE|. Conversely, on Windows, where the feature is disabled by
+default, pass the ``-async-proofs on`` flag to enable it.
+
+Proofs that are known to take little time to process are not delegated
+to a worker process. The threshold can be configure with
+``-async-proofs-delegation-threshold``. Default is 0.03 seconds.
+
+Batch mode
+---------------
+
+When |Coq| is used as a batch compiler by running `coqc` or `coqtop`
+-compile, it produces a `.vo` file for each `.v` file. A `.vo` file contains,
+among other things, theorems statements and proofs. Hence to produce a
+.vo |Coq| need to process all the proofs of the `.v` file.
+
+The asynchronous processing of proofs can decouple the generation of a
+compiled file (like the `.vo` one) that can be loaded by ``Require`` from the
+generation and checking of the proof objects. The ``-quick`` flag can be
+passed to `coqc` or `coqtop` to produce, quickly, `.vio` files.
+Alternatively, when using a Makefile produced by `coq_makefile`,
+the ``quick`` target can be used to compile all files using the ``-quick`` flag.
+
+A `.vio` file can be loaded using ``Require`` exactly as a `.vo` file but
+proofs will not be available (the Print command produces an error).
+Moreover, some universe constraints might be missing, so universes
+inconsistencies might go unnoticed. A `.vio` file does not contain proof
+objects, but proof tasks, i.e. what a worker process can transform
+into a proof object.
+
+Compiling a set of files with the ``-quick`` flag allows one to work,
+interactively, on any file without waiting for all the proofs to be
+checked.
+
+When working interactively, one can fully check all the `.v` files by
+running `coqc` as usual.
+
+Alternatively one can turn each `.vio` into the corresponding `.vo`. All
+.vio files can be processed in parallel, hence this alternative might
+be faster. The command ``coqtop -schedule-vio2vo 2 a b c`` can be used to
+obtain a good scheduling for two workers to produce `a.vo`, `b.vo`, and
+`c.vo`. When using a Makefile produced by `coq_makefile`, the ``vio2vo`` target
+can be used for that purpose. Variable `J` should be set to the number
+of workers, e.g. ``make vio2vo J=2``. The only caveat is that, while the
+.vo files obtained from `.vio` files are complete (they contain all proof
+terms and universe constraints), the satisfiability of all universe
+constraints has not been checked globally (they are checked to be
+consistent for every single proof). Constraints will be checked when
+these `.vo` files are (recursively) loaded with ``Require``.
+
+There is an extra, possibly even faster, alternative: just check the
+proof tasks stored in `.vio` files without producing the `.vo` files. This
+is possibly faster because all the proof tasks are independent, hence
+one can further partition the job to be done between workers. The
+``coqtop -schedule-vio-checking 6 a b c`` command can be used to obtain a
+good scheduling for 6 workers to check all the proof tasks of `a.vio`,
+`b.vio`, and `c.vio`. Auxiliary files are used to predict how long a proof
+task will take, assuming it will take the same amount of time it took
+last time. When using a Makefile produced by coq_makefile, the
+``checkproofs`` target can be used to check all `.vio` files. Variable `J`
+should be set to the number of workers, e.g. ``make checkproofs J=6``. As
+when converting `.vio` files to `.vo` files, universe constraints are not
+checked to be globally consistent. Hence this compilation mode is only
+useful for quick regression testing and on developments not making
+heavy use of the `Type` hierarchy.
+
+Limiting the number of parallel workers
+--------------------------------------------
+
+Many |Coq| processes may run on the same computer, and each of them may
+start many additional worker processes. The `coqworkmgr` utility lets
+one limit the number of workers, globally.
+
+The utility accepts the ``-j`` argument to specify the maximum number of
+workers (defaults to 2). `coqworkmgr` automatically starts in the
+background and prints an environment variable assignment
+like ``COQWORKMGR_SOCKET=localhost:45634``. The user must set this variable
+in all the shells from which |Coq| processes will be started. If one
+uses just one terminal running the bash shell, then
+``export ‘coqworkmgr -j 4‘`` will do the job.
+
+After that, all |Coq| processes, e.g. `coqide` and `coqc`, will honor the
+limit, globally.
diff --git a/doc/sphinx/addendum/program.rst b/doc/sphinx/addendum/program.rst
new file mode 100644
index 000000000..be30d1bc4
--- /dev/null
+++ b/doc/sphinx/addendum/program.rst
@@ -0,0 +1,382 @@
+.. include:: ../preamble.rst
+.. include:: ../replaces.rst
+
+.. this should be just "_program", but refs to it don't work
+
+.. _programs:
+
+Program
+========
+
+:Author: Matthieu Sozeau
+
+We present here the |Program| tactic commands, used to build
+certified |Coq| programs, elaborating them from their algorithmic
+skeleton and a rich specification :cite:`sozeau06`. It can be thought of as a
+dual of :ref:`Extraction <extraction>`. The goal of |Program| is to
+program as in a regular functional programming language whilst using
+as rich a specification as desired and proving that the code meets the
+specification using the whole |Coq| proof apparatus. This is done using
+a technique originating from the “Predicate subtyping” mechanism of
+PVS :cite:`Rushby98`, which generates type-checking conditions while typing a
+term constrained to a particular type. Here we insert existential
+variables in the term, which must be filled with proofs to get a
+complete |Coq| term. |Program| replaces the |Program| tactic by Catherine
+Parent :cite:`Parent95b` which had a similar goal but is no longer maintained.
+
+The languages available as input are currently restricted to |Coq|’s
+term language, but may be extended to OCaml, Haskell and
+others in the future. We use the same syntax as |Coq| and permit to use
+implicit arguments and the existing coercion mechanism. Input terms
+and types are typed in an extended system (Russell) and interpreted
+into |Coq| terms. The interpretation process may produce some proof
+obligations which need to be resolved to create the final term.
+
+
+.. _elaborating-programs:
+
+Elaborating programs
+---------------------
+
+The main difference from |Coq| is that an object in a type T : Set can
+be considered as an object of type { x : T | P} for any wellformed P :
+Prop. If we go from T to the subset of T verifying property P, we must
+prove that the object under consideration verifies it. Russell will
+generate an obligation for every such coercion. In the other
+direction, Russell will automatically insert a projection.
+
+Another distinction is the treatment of pattern-matching. Apart from
+the following differences, it is equivalent to the standard match
+operation (see :ref:`extendedpatternmatching`).
+
+
++ Generation of equalities. A match expression is always generalized
+ by the corresponding equality. As an example, the expression:
+
+ ::
+
+ match x with
+ | 0 => t
+ | S n => u
+ end.
+
+ will be first rewritten to:
+
+ ::
+
+ (match x as y return (x = y -> _) with
+ | 0 => fun H : x = 0 -> t
+ | S n => fun H : x = S n -> u
+ end) (eq_refl n).
+
+ This permits to get the proper equalities in the context of proof
+ obligations inside clauses, without which reasoning is very limited.
+
++ Generation of inequalities. If a pattern intersects with a previous
+ one, an inequality is added in the context of the second branch. See
+ for example the definition of div2 below, where the second branch is
+ typed in a context where ∀ p, _ <> S (S p).
++ Coercion. If the object being matched is coercible to an inductive
+ type, the corresponding coercion will be automatically inserted. This
+ also works with the previous mechanism.
+
+
+There are options to control the generation of equalities and
+coercions.
+
+.. opt:: Program Cases
+
+ This controls the special treatment of pattern-matching generating equalities
+ and inequalities when using |Program| (it is on by default). All
+ pattern-matchings and let-patterns are handled using the standard algorithm
+ of |Coq| (see :ref:`extendedpatternmatching`) when this option is
+ deactivated.
+
+.. opt:: Program Generalized Coercion
+
+ This controls the coercion of general inductive types when using |Program|
+ (the option is on by default). Coercion of subset types and pairs is still
+ active in this case.
+
+.. _syntactic_control:
+
+Syntactic control over equalities
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To give more control over the generation of equalities, the
+typechecker will fall back directly to |Coq|’s usual typing of dependent
+pattern-matching if a return or in clause is specified. Likewise, the
+if construct is not treated specially by |Program| so boolean tests in
+the code are not automatically reflected in the obligations. One can
+use the dec combinator to get the correct hypotheses as in:
+
+.. coqtop:: none
+
+ Require Import Program Arith.
+
+.. coqtop:: all
+
+ Program Definition id (n : nat) : { x : nat | x = n } :=
+ if dec (leb n 0) then 0
+ else S (pred n).
+
+The let tupling construct :g:`let (x1, ..., xn) := t in b` does not
+produce an equality, contrary to the let pattern construct :g:`let ’(x1,
+..., xn) := t in b`. Also, :g:`term :>` explicitly asks the system to
+coerce term to its support type. It can be useful in notations, for
+example:
+
+.. coqtop:: all
+
+ Notation " x `= y " := (@eq _ (x :>) (y :>)) (only parsing).
+
+This notation denotes equality on subset types using equality on their
+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
+: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.
+
+
+.. _program_definition:
+
+Program Definition
+~~~~~~~~~~~~~~~~~~
+
+.. cmd:: Program Definition @ident := @term.
+
+ This command types the value term in Russell and generates proof
+ obligations. Once solved using the commands shown below, it binds the
+ final |Coq| term to the name ``ident`` in the environment.
+
+ .. exn:: @ident already exists (Program Definition)
+
+ .. cmdv:: Program Definition @ident : @type := @term
+
+ It interprets the type ``type``, potentially generating proof
+ obligations to be resolved. Once done with them, we have a |Coq|
+ type |type_0|. It then elaborates the preterm ``term`` into a |Coq|
+ term |term_0|, checking that the type of |term_0| is coercible to
+ |type_0|, and registers ``ident`` as being of type |type_0| once the
+ set of obligations generated during the interpretation of |term_0|
+ and the aforementioned coercion derivation are solved.
+
+ .. exn:: In environment … the term: @term does not have type @type. Actually, it has type ...
+
+
+ .. cmdv:: Program Definition @ident @binders : @type := @term.
+
+ This is equivalent to:
+
+ :g:`Program Definition ident : forall binders, type := fun binders => term`.
+
+ .. TODO refer to production in alias
+
+See also: Sections :ref:`vernac-controlling-the-reduction-strategies`, :tacn:`unfold`
+
+.. _program_fixpoint:
+
+Program Fixpoint
+~~~~~~~~~~~~~~~~
+
+.. cmd:: Program Fixpoint @ident @params {? {@order}} : @type := @term.
+
+The optional order annotation follows the grammar:
+
+.. productionlist:: orderannot
+ order : measure `term` (`term`)? | wf `term` `term`
+
++ :g:`measure f ( R )` where :g:`f` is a value of type :g:`X` computed on
+ any subset of the arguments and the optional (parenthesised) term
+ ``(R)`` is a relation on ``X``. By default ``X`` defaults to ``nat`` and ``R``
+ to ``lt``.
+
++ :g:`wf R x` which is equivalent to :g:`measure x (R)`.
+
+The structural fixpoint operator behaves just like the one of |Coq| (see
+:cmd:`Fixpoint`), except it may also generate obligations. It works
+with mutually recursive definitions too.
+
+.. coqtop:: reset none
+
+ Require Import Program Arith.
+
+.. coqtop:: all
+
+ Program Fixpoint div2 (n : nat) : { x : nat | n = 2 * x \/ n = 2 * x + 1 } :=
+ match n with
+ | S (S p) => S (div2 p)
+ | _ => O
+ end.
+
+Here we have one obligation for each branch (branches for :g:`0` and
+``(S 0)`` are automatically generated by the pattern-matching
+compilation algorithm).
+
+.. coqtop:: all
+
+ Obligation 1.
+
+.. coqtop:: reset none
+
+ Require Import Program Arith.
+
+One can use a well-founded order or a measure as termination orders
+using the syntax:
+
+.. coqtop:: in
+
+ Program Fixpoint div2 (n : nat) {measure n} : { x : nat | n = 2 * x \/ n = 2 * x + 1 } :=
+ match n with
+ | S (S p) => S (div2 p)
+ | _ => O
+ end.
+
+
+
+.. caution:: When defining structurally recursive functions, the generated
+ obligations should have the prototype of the currently defined
+ functional in their context. In this case, the obligations should be
+ transparent (e.g. defined using :g:`Defined`) so that the guardedness
+ condition on recursive calls can be checked by the kernel’s type-
+ checker. There is an optimization in the generation of obligations
+ which gets rid of the hypothesis corresponding to the functional when
+ it is not necessary, so that the obligation can be declared opaque
+ (e.g. using :g:`Qed`). However, as soon as it appears in the context, the
+ proof of the obligation is *required* to be declared transparent.
+
+ No such problems arise when using measures or well-founded recursion.
+
+.. _program_lemma:
+
+Program Lemma
+~~~~~~~~~~~~~
+
+.. 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
+ automatically and fail if some unsolved obligations remain. In this
+ case, one can first define the lemma’s statement using :g:`Program
+ Definition` and use it as the goal afterwards. Otherwise the proof
+ will be started with the elaborated version as a goal. The
+ :g:`Program` prefix can similarly be used as a prefix for
+ :g:`Variable`, :g:`Hypothesis`, :g:`Axiom` etc...
+
+.. _solving_obligations:
+
+Solving obligations
+--------------------
+
+The following commands are available to manipulate obligations. The
+optional identifier is used when multiple functions have unsolved
+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,
+ e.g. using :g:`Next`. :g:`Local` makes the setting last only for the current
+ module. Inside sections, local is the default.
+
+.. cmd:: Show Obligation Tactic
+
+ Displays the current default tactic.
+
+.. cmd:: Obligations {? of @ident}
+
+ Displays all remaining obligations.
+
+.. cmd:: Obligation num {? of @ident}
+
+ Start the proof of obligation num.
+
+.. cmd:: Next Obligation {? of @ident}
+
+ Start the proof of the next unsolved obligation.
+
+.. cmd:: Solve Obligations {? of @ident} {? with @tactic}
+
+ Tries to solve each obligation of ``ident`` using the given ``tactic`` or the default one.
+
+.. cmd:: Solve All Obligations {? with @tactic}
+
+ Tries to solve each obligation of every program using the given
+ tactic or the default one (useful for mutually recursive definitions).
+
+.. cmd:: Admit Obligations {? of @ident}
+
+ Admits all obligations (of ``ident``).
+
+ .. note:: Does not work with structurally recursive programs.
+
+.. cmd:: Preterm {? of @ident}
+
+ Shows the term that will be fed to the kernel once the obligations
+ are solved. Useful for debugging.
+
+.. opt:: Transparent Obligations
+
+ Control whether all obligations should be declared as transparent
+ (the default), or if the system should infer which obligations can be
+ declared opaque.
+
+.. opt:: Hide Obligations
+
+ Control whether obligations appearing in the
+ term should be hidden as implicit arguments of the special
+ constantProgram.Tactics.obligation.
+
+.. opt:: Shrink Obligations
+
+ *Deprecated since 8.7*
+
+ This option (on by default) controls whether obligations should have
+ their context minimized to the set of variables used in the proof of
+ the obligation, to avoid unnecessary dependencies.
+
+The module :g:`Coq.Program.Tactics` defines the default tactic for solving
+obligations called :g:`program_simpl`. Importing :g:`Coq.Program.Program` also
+adds some useful notations, as documented in the file itself.
+
+.. _program-faq:
+
+Frequently Asked Questions
+---------------------------
+
+
+.. 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:
+
+ ::
+
+ Program Fixpoint f (x : A | P) := match x with A b => f b end.
+
+ Supposing ``b : A``, the argument at the recursive call to ``f`` is not a
+ direct subterm of ``x`` as ``b`` is wrapped inside an ``exist`` constructor to
+ build an object of type ``{x : A | P}``. Hence the definition is
+ rejected by the guardedness condition checker. However one can use
+ wellfounded recursion on subset objects like this:
+
+ ::
+
+ Program Fixpoint f (x : A | P) { measure (size x) } :=
+ match x with A b => f b end.
+
+ One will then just have to prove that the measure decreases at each
+ recursive call. There are three drawbacks though:
+
+ #. A measure function has to be defined;
+ #. The reduction is a little more involved, although it works well
+ using lazy evaluation;
+ #. Mutual recursion on the underlying inductive type isn’t possible
+ anymore, but nested mutual recursion is always possible.
+
+.. bibliography:: ../biblio.bib
+ :keyprefix: p-
diff --git a/doc/sphinx/addendum/ring.rst b/doc/sphinx/addendum/ring.rst
new file mode 100644
index 000000000..ae666a0d4
--- /dev/null
+++ b/doc/sphinx/addendum/ring.rst
@@ -0,0 +1,770 @@
+.. include:: ../replaces.rst
+.. |ra| replace:: :math:`\rightarrow_{\beta\delta\iota}`
+.. |la| replace:: :math:`\leftarrow_{\beta\delta\iota}`
+.. |eq| replace:: `=`:sub:`(by the main correctness theorem)`
+.. |re| replace:: ``(PEeval`` `v` `ap`\ ``)``
+.. |le| replace:: ``(Pphi_dev`` `v` ``(norm`` `ap`\ ``))``
+
+
+.. _theringandfieldtacticfamilies:
+
+The ring and field tactic families
+====================================
+
+:Author: Bruno Barras, Benjamin Grégoire, Assia Mahboubi, Laurent Théry [#f1]_
+
+This chapter presents the tactics dedicated to deal with ring and
+field equations.
+
+What does this tactic do?
+------------------------------
+
+``ring`` does associative-commutative rewriting in ring and semi-ring
+structures. Assume you have two binary functions :math:`\oplus` and
+:math:`\otimes` that are associative and commutative, with :math:`\oplus`
+distributive on :math:`\otimes`, and two constants 0 and 1 that are unities for
+:math:`\oplus` and :math:`\otimes`. A polynomial is an expression built on
+variables :math:`V_0`, :math:`V_1`, :math:`\dots` and constants by application
+of :math:`\oplus` and :math:`\otimes`.
+
+Let an ordered product be a product of variables :math:`V_{i_1} \otimes \dots
+\otimes V_{i_n}` verifying :math:`i_1 ≤ i_2 ≤ \dots ≤ i_n` . Let a monomial be
+the product of a constant and an ordered product. We can order the monomials by
+the lexicographic order on products of variables. Let a canonical sum be an
+ordered sum of monomials that are all different, i.e. each monomial in the sum
+is strictly less than the following monomial according to the lexicographic
+order. It is an easy theorem to show that every polynomial is equivalent (modulo
+the ring properties) to exactly one canonical sum. This canonical sum is called
+the normal form of the polynomial. In fact, the actual representation shares
+monomials with same prefixes. So what does ring? It normalizes polynomials over
+any ring or semi-ring structure. The basic use of ``ring`` is to simplify ring
+expressions, so that the user does not have to deal manually with the theorems
+of associativity and commutativity.
+
+
+.. example::
+
+ In the ring of integers, the normal form of
+ :math:`x (3 + yx + 25(1 − z)) + zx`
+ is
+ :math:`28x + (−24)xz + xxy`.
+
+
+``ring`` is also able to compute a normal form modulo monomial equalities.
+For example, under the hypothesis that :math:`2x^2 = yz+1`, the normal form of
+:math:`2(x + 1)x − x − zy` is :math:`x+1`.
+
+The variables map
+----------------------
+
+It is frequent to have an expression built with :math:`+` and :math:`\times`,
+but rarely on variables only. Let us associate a number to each subterm of a
+ring expression in the Gallina language. For example in the ring |nat|, consider
+the expression:
+
+
+::
+
+ (plus (mult (plus (f (5)) x) x)
+ (mult (if b then (4) else (f (3))) (2)))
+
+
+As a ring expression, it has 3 subterms. Give each subterm a number in
+an arbitrary order:
+
+===== =============== =========================
+0 :math:`\mapsto` if b then (4) else (f (3))
+1 :math:`\mapsto` (f (5))
+2 :math:`\mapsto` x
+===== =============== =========================
+
+Then normalize the “abstract” polynomial
+:math:`((V_1 \otimes V_2 ) \oplus V_2) \oplus (V_0 \otimes 2)`
+In our example the normal form is:
+:math:`(2 \otimes V_0 ) \oplus (V_1 \otimes V_2) \oplus (V_2 \otimes V_2 )`.
+Then substitute the variables by their values in the variables map to
+get the concrete normal polynomial:
+
+::
+
+ (plus (mult (2) (if b then (4) else (f (3))))
+ (plus (mult (f (5)) x) (mult x x)))
+
+
+Is it automatic?
+---------------------
+
+Yes, building the variables map and doing the substitution after
+normalizing is automatically done by the tactic. So you can just
+forget this paragraph and use the tactic according to your intuition.
+
+Concrete usage in Coq
+--------------------------
+
+.. tacn:: ring
+
+The ``ring`` tactic solves equations upon polynomial expressions of a ring
+(or semi-ring) structure. It proceeds by normalizing both hand sides
+of the equation (w.r.t. associativity, commutativity and
+distributivity, constant propagation, rewriting of monomials) and
+comparing syntactically the results.
+
+.. tacn:: ring_simplify
+
+``ring_simplify`` applies the normalization procedure described above to
+the terms given. The tactic then replaces all occurrences of the terms
+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. The tactic can also be applied in a hypothesis.
+
+The tactic must be loaded by ``Require Import Ring``. The ring structures
+must be declared with the ``Add Ring`` command (see below). The ring of
+booleans is predefined; if one wants to use the tactic on |nat| one must
+first require the module ``ArithRing`` exported by ``Arith``); for |Z|, do
+``Require Import ZArithRing`` or simply ``Require Import ZArith``; for |N|, do
+``Require Import NArithRing`` or ``Require Import NArith``.
+
+
+.. example::
+
+ .. coqtop:: all
+
+ Require Import ZArith.
+ Open Scope Z_scope.
+ Goal forall a b c:Z,
+ (a + b + c) ^ 2 =
+ a * a + b ^ 2 + c * c + 2 * a * b + 2 * a * c + 2 * b * c.
+ intros; ring.
+ Abort.
+ Goal forall a b:Z,
+ 2 * a * b = 30 -> (a + b) ^ 2 = a ^ 2 + b ^ 2 + 30.
+ intros a b H; ring [H].
+ Abort.
+
+
+.. tacv:: ring [{* @term }]
+
+decides the equality of two terms modulo ring operations and
+the equalities defined by the :n:`@term`\ s.
+Each :n:`@term` has to be a proof of some equality `m = p`, where `m` is a monomial (after “abstraction”), `p` a polynomial and `=` the corresponding equality of the ring structure.
+
+.. tacv:: ring_simplify [{* @term }] {* @term } in @ident
+
+performs the simplification in the hypothesis named :n:`@ident`.
+
+
+.. note::
+
+ .. tacn:: ring_simplify @term1; ring_simplify @term2
+
+ is not equivalent to
+
+ .. tacn:: ring_simplify @term1 @term2
+
+ In the latter case the variables map
+ is shared between the two terms, and common subterm `t` of :n:`@term1` and :n:`@term2`
+ will have the same associated variable number. So the first
+ alternative should be avoided for terms belonging to the same ring
+ theory.
+
+
+Error messages:
+
+
+.. 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
+
+ ``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
+
+ 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
+
+ Same as above is the case of the ``ring`` tactic.
+
+
+Adding a ring structure
+----------------------------
+
+Declaring a new ring consists in proving that a ring signature (a
+carrier set, an equality, and ring operations: ``Ring_theory.ring_theory``
+and ``Ring_theory.semi_ring_theory``) satisfies the ring axioms. Semi-
+rings (rings without + inverse) are also supported. The equality can
+be either Leibniz equality, or any relation declared as a setoid (see
+:ref:`tactics-enabled-on-user-provided-relations`). The definition of ring and semi-rings (see module
+``Ring_theory``) is:
+
+.. coqtop:: in
+
+ Record ring_theory : Prop := mk_rt {
+ Radd_0_l : forall x, 0 + x == x;
+ Radd_sym : forall x y, x + y == y + x;
+ Radd_assoc : forall x y z, x + (y + z) == (x + y) + z;
+ Rmul_1_l : forall x, 1 * x == x;
+ Rmul_sym : forall x y, x * y == y * x;
+ Rmul_assoc : forall x y z, x * (y * z) == (x * y) * z;
+ Rdistr_l : forall x y z, (x + y) * z == (x * z) + (y * z);
+ Rsub_def : forall x y, x - y == x + -y;
+ Ropp_def : forall x, x + (- x) == 0
+ }.
+
+ Record semi_ring_theory : Prop := mk_srt {
+ SRadd_0_l : forall n, 0 + n == n;
+ SRadd_sym : forall n m, n + m == m + n ;
+ SRadd_assoc : forall n m p, n + (m + p) == (n + m) + p;
+ SRmul_1_l : forall n, 1*n == n;
+ SRmul_0_l : forall n, 0*n == 0;
+ SRmul_sym : forall n m, n*m == m*n;
+ SRmul_assoc : forall n m p, n*(m*p) == (n*m)*p;
+ SRdistr_l : forall n m p, (n + m)*p == n*p + m*p
+ }.
+
+
+This implementation of ``ring`` also features a notion of constant that
+can be parameterized. This can be used to improve the handling of
+closed expressions when operations are effective. It consists in
+introducing a type of *coefficients* and an implementation of the ring
+operations, and a morphism from the coefficient type to the ring
+carrier type. The morphism needs not be injective, nor surjective.
+
+As an example, one can consider the real numbers. The set of
+coefficients could be the rational numbers, upon which the ring
+operations can be implemented. The fact that there exists a morphism
+is defined by the following properties:
+
+.. coqtop:: in
+
+ Record ring_morph : Prop := mkmorph {
+ morph0 : [cO] == 0;
+ morph1 : [cI] == 1;
+ morph_add : forall x y, [x +! y] == [x]+[y];
+ morph_sub : forall x y, [x -! y] == [x]-[y];
+ morph_mul : forall x y, [x *! y] == [x]*[y];
+ morph_opp : forall x, [-!x] == -[x];
+ morph_eq : forall x y, x?=!y = true -> [x] == [y]
+ }.
+
+ Record semi_morph : Prop := mkRmorph {
+ Smorph0 : [cO] == 0;
+ Smorph1 : [cI] == 1;
+ Smorph_add : forall x y, [x +! y] == [x]+[y];
+ Smorph_mul : forall x y, [x *! y] == [x]*[y];
+ Smorph_eq : forall x y, x?=!y = true -> [x] == [y]
+ }.
+
+
+where ``c0`` and ``cI`` denote the 0 and 1 of the coefficient set, ``+!``, ``*!``, ``-!``
+are the implementations of the ring operations, ``==`` is the equality of
+the coefficients, ``?+!`` is an implementation of this equality, and ``[x]``
+is a notation for the image of ``x`` by the ring morphism.
+
+Since |Z| is an initial ring (and |N| is an initial semi-ring), it can
+always be considered as a set of coefficients. There are basically
+three kinds of (semi-)rings:
+
+abstract rings
+ to be used when operations are not effective. The set
+ of coefficients is |Z| (or |N| for semi-rings).
+
+computational rings
+ to be used when operations are effective. The
+ set of coefficients is the ring itself. The user only has to provide
+ an implementation for the equality.
+
+customized ring
+ for other cases. The user has to provide the
+ coefficient set and the morphism.
+
+
+This implementation of ring can also recognize simple power
+expressions as ring expressions. A power function is specified by the
+following property:
+
+.. coqtop:: in
+
+ Section POWER.
+ Variable Cpow : Set.
+ Variable Cp_phi : N -> Cpow.
+ Variable rpow : R -> Cpow -> R.
+
+ Record power_theory : Prop := mkpow_th {
+ rpow_pow_N : forall r n, req (rpow r (Cp_phi n)) (pow_N rI rmul r n)
+ }.
+
+ End POWER.
+
+
+The syntax for adding a new ring is
+
+.. 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
+axioms. The optional list of modifiers is used to tailor the behavior
+of the tactic. The following list describes their syntax and effects:
+
+.. prodn::
+ ring_mod ::= abstract %| decidable @term %| morphism @term
+ %| setoid @term @term
+ %| constants [@ltac]
+ %| preprocess [@ltac]
+ %| postprocess [@ltac]
+ %| power_tac @term [@ltac]
+ %| sign @term
+ %| div @term
+
+
+abstract
+ declares the ring as abstract. This is the default.
+
+decidable :n:`@term`
+ declares the ring as computational. The expression
+ :n:`@term` is the correctness proof of an equality test ``?=!``
+ (which hould be evaluable). Its type should be of the form
+ ``forall x y, x ?=! y = true → x == y``.
+
+morphism :n:`@term`
+ declares the ring as a customized one. The expression
+ :n:`@term` is a proof that there exists a morphism between a set of
+ coefficient and the ring carrier (see ``Ring_theory.ring_morph`` and
+ ``Ring_theory.semi_morph``).
+
+setoid :n:`@term` :n:`@term`
+ forces the use of given setoid. The first
+ :n:`@term` is a proof that the equality is indeed a setoid (see
+ ``Setoid.Setoid_Theory``), and the second :n:`@term` a proof that the
+ ring operations are morphisms (see ``Ring_theory.ring_eq_ext`` and
+ ``Ring_theory.sring_eq_ext``).
+ This modifier needs not be used if the setoid and morphisms have been
+ declared.
+
+constants [:n:`@ltac`]
+ specifies a tactic expression :n:`@ltac` that, given a
+ term, returns either an object of the coefficient set that is mapped
+ to the expression via the morphism, or returns
+ ``InitialRing.NotConstant``. The default behavior is to map only 0 and 1
+ to their counterpart in the coefficient set. This is generally not
+ desirable for non trivial computational rings.
+
+preprocess [:n:`@ltac`]
+ specifies a tactic :n:`@ltac` that is applied as a
+ preliminary step for ``ring`` and ``ring_simplify``. It can be used to
+ transform a goal so that it is better recognized. For instance, ``S n``
+ can be changed to ``plus 1 n``.
+
+postprocess [:n:`@ltac`]
+ specifies a tactic :n:`@ltac` that is applied as a final
+ step for ``ring_simplify``. For instance, it can be used to undo
+ modifications of the preprocessor.
+
+power_tac :n:`@term` [:n:`@ltac`]
+ allows ``ring`` and ``ring_simplify`` to recognize
+ power expressions with a constant positive integer exponent (example:
+ ::math:`x^2` ). The term :n:`@term` is a proof that a given power function satisfies
+ the specification of a power function (term has to be a proof of
+ ``Ring_theory.power_theory``) and :n:`@ltac` specifies a tactic expression
+ that, given a term, “abstracts” it into an object of type |N| whose
+ interpretation via ``Cp_phi`` (the evaluation function of power
+ coefficient) is the original term, or returns ``InitialRing.NotConstant``
+ if not a constant coefficient (i.e. |L_tac| is the inverse function of
+ ``Cp_phi``). See files ``plugins/setoid_ring/ZArithRing.v``
+ and ``plugins/setoid_ring/RealField.v`` for examples. By default the tactic
+ does not recognize power expressions as ring expressions.
+
+sign :n:`@term`
+ allows ``ring_simplify`` to use a minus operation when
+ outputting its normal form, i.e writing ``x − y`` instead of ``x + (− y)``. The
+ term `:n:`@term` is a proof that a given sign function indicates expressions
+ that are signed (`term` has to be a proof of ``Ring_theory.get_sign``). See
+ ``plugins/setoid_ring/InitialRing.v`` for examples of sign function.
+
+div :n:`@term`
+ allows ``ring`` and ``ring_simplify`` to use monomials with
+ coefficient other than 1 in the rewriting. The term :n:`@term` is a proof
+ that a given division function satisfies the specification of an
+ euclidean division function (:n:`@term` has to be a proof of
+ ``Ring_theory.div_theory``). For example, this function is called when
+ trying to rewrite :math:`7x` by :math:`2x = z` to tell that :math:`7 = 3 \times 2 + 1`. See
+ ``plugins/setoid_ring/InitialRing.v`` for examples of div function.
+
+Error messages:
+
+.. exn:: bad ring structure
+
+ The proof of the ring structure provided is not
+ of the expected type.
+
+.. 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
+
+ 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`.
+
+How does it work?
+----------------------
+
+The code of ring is a good example of tactic written using *reflection*.
+What is reflection? Basically, it is writing |Coq| tactics in |Coq|, rather
+than in |OCaml|. From the philosophical point of view, it is
+using the ability of the Calculus of Constructions to speak and reason
+about itself. For the ring tactic we used Coq as a programming
+language and also as a proof environment to build a tactic and to
+prove it correctness.
+
+The interested reader is strongly advised to have a look at the
+file ``Ring_polynom.v``. Here a type for polynomials is defined:
+
+
+.. coqtop:: in
+
+ Inductive PExpr : Type :=
+ | PEc : C -> PExpr
+ | PEX : positive -> PExpr
+ | PEadd : PExpr -> PExpr -> PExpr
+ | PEsub : PExpr -> PExpr -> PExpr
+ | PEmul : PExpr -> PExpr -> PExpr
+ | PEopp : PExpr -> PExpr
+ | PEpow : PExpr -> N -> PExpr.
+
+
+Polynomials in normal form are defined as:
+
+
+.. coqtop:: in
+
+ Inductive Pol : Type :=
+ | Pc : C -> Pol
+ | Pinj : positive -> Pol -> Pol
+ | PX : Pol -> positive -> Pol -> Pol.
+
+
+where ``Pinj n P`` denotes ``P`` in which :math:`V_i` is replaced by :math:`V_{i+n}` ,
+and ``PX P n Q`` denotes :math:`P \otimes V_1^n \oplus Q'`, `Q'` being `Q` where :math:`V_i` is replaced by :math:`V_{i+1}`.
+
+Variables maps are represented by list of ring elements, and two
+interpretation functions, one that maps a variables map and a
+polynomial to an element of the concrete ring, and the second one that
+does the same for normal forms:
+
+
+.. coqtop:: in
+
+
+ Definition PEeval : list R -> PExpr -> R := [...].
+ Definition Pphi_dev : list R -> Pol -> R := [...].
+
+
+A function to normalize polynomials is defined, and the big theorem is
+its correctness w.r.t interpretation, that is:
+
+
+.. coqtop:: in
+
+ Definition norm : PExpr -> Pol := [...].
+ Lemma Pphi_dev_ok :
+ forall l pe npe, norm pe = npe -> PEeval l pe == Pphi_dev l npe.
+
+
+So now, what is the scheme for a normalization proof? Let p be the
+polynomial expression that the user wants to normalize. First a little
+piece of |ML| code guesses the type of `p`, the ring theory `T` to use, an
+abstract polynomial `ap` and a variables map `v` such that `p` is |bdi|-
+equivalent to ``(PEeval`` `v` `ap`\ ``)``. Then we replace it by ``(Pphi_dev`` `v`
+``(norm`` `ap`\ ``))``, using the main correctness theorem and we reduce it to a
+concrete expression `p’`, which is the concrete normal form of `p`. This is summarized in this diagram:
+
+========= ====== ====
+`p` |ra| |re|
+\ |eq| \
+`p’` |la| |le|
+========= ====== ====
+
+The user do not see the right part of the diagram. From outside, the
+tactic behaves like a |bdi| simplification extended with AC rewriting
+rules. Basically, the proof is only the application of the main
+correctness theorem to well-chosen arguments.
+
+Dealing with fields
+------------------------
+
+.. tacn:: field
+
+The ``field`` tactic is an extension of the ``ring`` to deal with rational
+expression. Given a rational expression :math:`F = 0`. It first reduces the
+expression `F` to a common denominator :math:`N/D = 0` where `N` and `D`
+are two ring expressions. For example, if we take :math:`F = (1 − 1/x) x − x + 1`, this
+gives :math:`N = (x − 1) x − x^2 + x` and :math:`D = x`. It then calls ring to solve
+:math:`N = 0`.
+Note that ``field`` also generates non-zero conditions for all the
+denominators it encounters in the reduction. In our example, it
+generates the condition :math:`x \neq 0`. These conditions appear as one subgoal
+which is a conjunction if there are several denominators. Non-zero
+conditions are always polynomial expressions. For example when
+reducing the expression :math:`1/(1 + 1/x)`, two side conditions are
+generated: :math:`x \neq 0` and :math:`x + 1 \neq 0`. Factorized expressions are broken since
+a field is an integral domain, and when the equality test on
+coefficients is complete w.r.t. the equality of the target field,
+constants can be proven different from zero automatically.
+
+The tactic must be loaded by ``Require Import Field``. New field
+structures can be declared to the system with the ``Add Field`` command
+(see below). The field of real numbers is defined in module ``RealField``
+(in ``plugins/setoid_ring``). It is exported by module ``Rbase``, so
+that requiring ``Rbase`` or ``Reals`` is enough to use the field tactics on
+real numbers. Rational numbers in canonical form are also declared as
+a field in module ``Qcanon``.
+
+
+.. example::
+
+ .. coqtop:: all
+
+ Require Import Reals.
+ Open Scope R_scope.
+ Goal forall x,
+ x <> 0 -> (1 - 1 / x) * x - x + 1 = 0.
+ intros; field; auto.
+ Abort.
+ Goal forall x y,
+ y <> 0 -> y = x -> x / y = 1.
+ intros x y H H1; field [H1]; auto.
+ Abort.
+
+.. tacv:: field [{* @term}]
+
+ decides the equality of two terms modulo
+ field operations and the equalities defined
+ by the :n:`@term`\ s. Each :n:`@term` has to be a proof of some equality
+ `m` ``=`` `p`, where `m` is a monomial (after “abstraction”), `p` a polynomial
+ and ``=`` the corresponding equality of the field structure.
+
+.. note::
+
+ rewriting works with the equality `m` ``=`` `p` only if `p` is a polynomial since
+ rewriting is handled by the underlying ring tactic.
+
+.. tacv:: field_simplify
+
+ performs the simplification in the conclusion of the
+ goal, :math:`F_1 = F_2` becomes :math:`N_1 / D_1 = N_2 / D_2`. A normalization step
+ (the same as the one for rings) is then applied to :math:`N_1`, :math:`D_1`,
+ :math:`N_2` and :math:`D_2`. This way, polynomials remain in factorized form during the
+ fraction simplifications. This yields smaller expressions when
+ reducing to the same denominator since common factors can be canceled.
+
+.. tacv:: field_simplify [{* @term }]
+
+ performs the simplification in the conclusion of the goal using the equalities
+ defined by the :n:`@term`\ s.
+
+.. tacv:: field_simplify [{* @term }] {* @term }
+
+ performs the simplification in the terms :n:`@terms` of the conclusion of the goal
+ using the equalities defined by :n:`@term`\ s inside the brackets.
+
+.. tacv :: field_simplify in @ident
+
+ performs the simplification in the assumption :n:`@ident`.
+
+.. tacv :: field_simplify [{* @term }] in @ident
+
+ performs the simplification
+ in the assumption :n:`@ident` using the equalities defined by the :n:`@term`\ s.
+
+.. tacv:: field_simplify [{* @term }] {* @term } in @ident
+
+ performs the simplification in the :n:`@term`\ s of the assumption :n:`@ident` using the
+ equalities defined by the :n:`@term`\ s inside the brackets.
+
+.. tacv:: field_simplify_eq
+
+ performs the simplification in the conclusion of
+ the goal removing the denominator. :math:`F_1 = F_2` becomes :math:`N_1 D_2 = N_2 D_1`.
+
+.. tacv:: field_simplify_eq [ {* @term }]
+
+ performs the simplification in
+ the conclusion of the goal using the equalities defined by
+ :n:`@term`\ s.
+
+.. tacv:: field_simplify_eq in @ident
+
+ performs the simplification in the assumption :n:`@ident`.
+
+.. tacv:: field_simplify_eq [{* @term}] in @ident
+
+ performs the simplification in the assumption :n:`@ident` using the equalities defined by
+ :n:`@terms`\ s and removing the denominator.
+
+
+Adding a new field structure
+---------------------------------
+
+Declaring a new field consists in proving that a field signature (a
+carrier set, an equality, and field operations:
+``Field_theory.field_theory`` and ``Field_theory.semi_field_theory``)
+satisfies the field axioms. Semi-fields (fields without + inverse) are
+also supported. The equality can be either Leibniz equality, or any
+relation declared as a setoid (see :ref:`tactics-enabled-on-user-provided-relations`). The definition of
+fields and semi-fields is:
+
+.. coqtop:: in
+
+ Record field_theory : Prop := mk_field {
+ F_R : ring_theory rO rI radd rmul rsub ropp req;
+ F_1_neq_0 : ~ 1 == 0;
+ Fdiv_def : forall p q, p / q == p * / q;
+ Finv_l : forall p, ~ p == 0 -> / p * p == 1
+ }.
+
+ Record semi_field_theory : Prop := mk_sfield {
+ SF_SR : semi_ring_theory rO rI radd rmul req;
+ SF_1_neq_0 : ~ 1 == 0;
+ SFdiv_def : forall p q, p / q == p * / q;
+ SFinv_l : forall p, ~ p == 0 -> / p * p == 1
+ }.
+
+
+The result of the normalization process is a fraction represented by
+the following type:
+
+.. coqtop:: in
+
+ Record linear : Type := mk_linear {
+ num : PExpr C;
+ denum : PExpr C;
+ condition : list (PExpr C)
+ }.
+
+
+where ``num`` and ``denum`` are the numerator and denominator; ``condition`` is a
+list of expressions that have appeared as a denominator during the
+normalization process. These expressions must be proven different from
+zero for the correctness of the algorithm.
+
+The syntax for adding a new field is
+
+.. 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
+(semi-)field axioms. The optional list of modifiers is used to tailor
+the behavior of the tactic.
+
+.. prodn::
+ field_mod := @ring_mod %| completeness @term
+
+Since field tactics are built upon ``ring``
+tactics, all modifiers of the ``Add Ring`` apply. There is only one
+specific modifier:
+
+completeness :n:`@term`
+ allows the field tactic to prove automatically
+ that the image of non-zero coefficients are mapped to non-zero
+ elements of the field. :n:`@term` is a proof of
+
+ ``forall x y, [x] == [y] -> x ?=! y = true``,
+
+ which is the completeness of equality on coefficients
+ w.r.t. the field equality.
+
+
+History of ring
+--------------------
+
+First Samuel Boutin designed the tactic ``ACDSimpl``. This tactic did lot
+of rewriting. But the proofs terms generated by rewriting were too big
+for |Coq|’s type-checker. Let us see why:
+
+.. coqtop:: all
+
+ Require Import ZArith.
+ Open Scope Z_scope.
+ Goal forall x y z : Z,
+ x + 3 + y + y * z = x + 3 + y + z * y.
+ intros; rewrite (Zmult_comm y z); reflexivity.
+ Save foo.
+ Print foo.
+
+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 :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
+interleaving of computation and reasoning (see :ref:`discussion_reflection`). He also wrote a
+few |ML| code for the ``Add Ring`` command, that allow to register new rings
+dynamically.
+
+Proofs terms generated by ring are quite small, they are linear in the
+number of :math:`\oplus` and :math:`\otimes` operations in the normalized terms. Type-checking
+those terms requires some time because it makes a large use of the
+conversion rule, but memory requirements are much smaller.
+
+
+.. _discussion_reflection:
+
+
+Discussion
+----------------
+
+
+Efficiency is not the only motivation to use reflection here. ``ring``
+also deals with constants, it rewrites for example the expression
+``34 + 2 * x − x + 12`` to the expected result ``x + 46``.
+For the tactic ``ACDSimpl``, the only constants were 0 and 1.
+So the expression ``34 + 2 * (x − 1) + 12``
+is interpreted as :math:`V_0 \oplus V_1 \otimes (V_2 \ominus 1) \oplus V_3`\ ,
+with the variables mapping
+:math:`\{V_0 \mapsto 34; V_1 \mapsto 2; V_2 \mapsto x; V_3 \mapsto 12\}`\ .
+Then it is rewritten to ``34 − x + 2 * x + 12``, very far from the expected result.
+Here rewriting is not sufficient: you have to do some kind of reduction
+(some kind of computation) to achieve the normalization.
+
+The tactic ``ring`` is not only faster than a classical one: using
+reflection, we get for free integration of computation and reasoning
+that would be very complex to implement in the classic fashion.
+
+Is it the ultimate way to write tactics? The answer is: yes and no.
+The ``ring`` tactic uses intensively the conversion rule of |Cic|, that is
+replaces proof by computation the most as it is possible. It can be
+useful in all situations where a classical tactic generates huge proof
+terms. Symbolic Processing and Tautologies are in that case. But there
+are also tactics like ``auto`` or ``linear`` that do many complex computations,
+using side-effects and backtracking, and generate a small proof term.
+Clearly, it would be significantly less efficient to replace them by
+tactics using reflection.
+
+Another idea suggested by Benjamin Werner: reflection could be used to
+couple an external tool (a rewriting program or a model checker)
+with |Coq|. We define (in |Coq|) a type of terms, a type of *traces*, and
+prove a correction theorem that states that *replaying traces* is safe
+w.r.t some interpretation. Then we let the external tool do every
+computation (using side-effects, backtracking, exception, or others
+features that are not available in pure lambda calculus) to produce
+the trace: now we can check in |Coq| that the trace has the expected
+semantic by applying the correction lemma.
+
+
+
+
+
+
+.. rubric:: Footnotes
+.. [#f1] based on previous work from Patrick Loiseleur and Samuel Boutin
+
+
+
diff --git a/doc/sphinx/addendum/type-classes.rst b/doc/sphinx/addendum/type-classes.rst
new file mode 100644
index 000000000..3e95bd8c4
--- /dev/null
+++ b/doc/sphinx/addendum/type-classes.rst
@@ -0,0 +1,571 @@
+.. include:: ../replaces.rst
+
+.. _typeclasses:
+
+Type Classes
+============
+
+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
+classes in Haskell which also applies.
+
+
+Class and Instance declarations
+-------------------------------
+
+The syntax for class and instance declarations is the same as the record
+syntax of Coq:
+
+``Class Id (`` |p_1| ``:`` |t_1| ``) ⋯ (`` |p_n| ``:`` |t_n| ``) [:
+sort] := {`` |f_1| ``:`` |u_1| ``; ⋮`` |f_m| ``:`` |u_m| ``}.``
+
+``Instance ident : Id`` |p_1| ``⋯`` |p_n| ``:= {`` |f_1| ``:=`` |t_1| ``; ⋮`` |f_m| ``:=`` |t_m| ``}.``
+
+The |p_i| ``:`` |t_i| variables are called the *parameters* of the class and
+the |f_i| ``:`` |t_i| are called the *methods*. Each class definition gives
+rise to a corresponding record declaration and each instance is a
+regular definition whose name is given by ident and type is an
+instantiation of the record type.
+
+We’ll use the following example class in the rest of the chapter:
+
+.. coqtop:: in
+
+ Class EqDec (A : Type) := {
+ eqb : A -> A -> bool ;
+ eqb_leibniz : forall x y, eqb x y = true -> x = y }.
+
+This class implements a boolean equality test which is compatible with
+Leibniz equality on some type. An example implementation is:
+
+.. coqtop:: in
+
+ Instance unit_EqDec : EqDec unit :=
+ { eqb x y := true ;
+ eqb_leibniz x y H :=
+ match x, y return x = y with tt, tt => eq_refl tt end }.
+
+If one does not give all the members in the Instance declaration, Coq
+enters the proof-mode and the user is asked to build inhabitants of
+the remaining fields, e.g.:
+
+.. coqtop:: in
+
+ Instance eq_bool : EqDec bool :=
+ { eqb x y := if x then y else negb y }.
+
+.. coqtop:: all
+
+ Proof. intros x y H.
+
+.. coqtop:: all
+
+ destruct x ; destruct y ; (discriminate || reflexivity).
+
+.. coqtop:: all
+
+ 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
+for dealing with obligations.
+
+
+Binding classes
+---------------
+
+Once a type class is declared, one can use it in class binders:
+
+.. coqtop:: all
+
+ Definition neqb {A} {eqa : EqDec A} (x y : A) := negb (eqb x y).
+
+When one calls a class method, a constraint is generated that is
+satisfied only in contexts where the appropriate instances can be
+found. In the example above, a constraint ``EqDec A`` is generated and
+satisfied by ``eqa : EqDec A``. In case no satisfying constraint can be
+found, an error is raised:
+
+.. coqtop:: all
+
+ Fail Definition neqb' (A : Type) (x y : A) := negb (eqb x y).
+
+The algorithm used to solve constraints is a variant of the eauto
+tactic that does proof search with a set of lemmas (the instances). It
+will use local hypotheses as well as declared lemmas in
+the ``typeclass_instances`` database. Hence the example can also be
+written:
+
+.. coqtop:: all
+
+ Definition neqb' A (eqa : EqDec A) (x y : A) := negb (eqb x y).
+
+However, the generalizing binders should be used instead as they have
+particular support for type classes:
+
++ They automatically set the maximally implicit status for type class
+ arguments, making derived functions as easy to use as class methods.
+ In the example above, ``A`` and ``eqa`` should be set maximally implicit.
++ They support implicit quantification on partially applied type
+ classes (:ref:`implicit-generalization`). Any argument not given as part of a type class
+ binder will be automatically generalized.
++ They also support implicit quantification on :ref:`superclasses`.
+
+
+Following the previous example, one can write:
+
+.. coqtop:: all
+
+ Generalizable Variables A B C.
+
+ Definition neqb_impl `{eqa : EqDec A} (x y : A) := negb (eqb x y).
+
+Here ``A`` is implicitly generalized, and the resulting function is
+equivalent to the one above.
+
+Parameterized Instances
+-----------------------
+
+One can declare parameterized instances as in Haskell simply by giving
+the constraints as a binding context before the instance, e.g.:
+
+.. coqtop:: in
+
+ Instance prod_eqb `(EA : EqDec A, EB : EqDec B) : EqDec (A * B) :=
+ { eqb x y := match x, y with
+ | (la, ra), (lb, rb) => andb (eqb la lb) (eqb ra rb)
+ end }.
+
+.. coqtop:: none
+
+ Abort.
+
+These instances are used just as well as lemmas in the instance hint
+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 :cmd:`Variables`
+vernacular, except it accepts any binding context as argument. For example:
+
+.. coqtop:: all
+
+ Section EqDec_defs.
+
+ Context `{EA : EqDec A}.
+
+ Global Instance option_eqb : EqDec (option A) :=
+ { eqb x y := match x, y with
+ | Some x, Some y => eqb x y
+ | None, None => true
+ | _, _ => false
+ end }.
+ Admitted.
+
+ End EqDec_defs.
+
+ About option_eqb.
+
+Here the Global modifier redeclares the instance at the end of the
+section, once it has been generalized by the context variables it
+uses.
+
+
+Building hierarchies
+--------------------
+
+.. _superclasses:
+
+Superclasses
+~~~~~~~~~~~~
+
+One can also parameterize classes by other classes, generating a
+hierarchy of classes and superclasses. In the same way, we give the
+superclasses as a binding context:
+
+.. coqtop:: all
+
+ Class Ord `(E : EqDec A) := { le : A -> A -> bool }.
+
+Contrary to Haskell, we have no special syntax for superclasses, but
+this declaration is morally equivalent to:
+
+::
+
+ Class `(E : EqDec A) => Ord A :=
+ { le : A -> A -> bool }.
+
+
+This declaration means that any instance of the ``Ord`` class must have
+an instance of ``EqDec``. The parameters of the subclass contain at
+least all the parameters of its superclasses in their order of
+appearance (here A is the only one). As we have seen, ``Ord`` is encoded
+as a record type with two parameters: a type ``A`` and an ``E`` of type
+``EqDec A``. However, one can still use it as if it had a single
+parameter inside generalizing binders: the generalization of
+superclasses will be done automatically.
+
+.. coqtop:: all
+
+ Definition le_eqb `{Ord A} (x y : A) := andb (le x y) (le y x).
+
+In some cases, to be able to specify sharing of structures, one may
+want to give explicitly the superclasses. It is is possible to do it
+directly in regular binders, and using the ``!`` modifier in class
+binders. For example:
+
+.. coqtop:: all
+
+ Definition lt `{eqa : EqDec A, ! Ord eqa} (x y : A) := andb (le x y) (neqb x y).
+
+The ``!`` modifier switches the way a binder is parsed back to the regular
+interpretation of Coq. In particular, it uses the implicit arguments
+mechanism if available, as shown in the example.
+
+Substructures
+~~~~~~~~~~~~~
+
+Substructures are components of a class which are instances of a class
+themselves. They often arise when using classes for logical
+properties, e.g.:
+
+.. coqtop:: none
+
+ Require Import Relation_Definitions.
+
+.. coqtop:: in
+
+ Class Reflexive (A : Type) (R : relation A) :=
+ reflexivity : forall x, R x x.
+
+ Class Transitive (A : Type) (R : relation A) :=
+ transitivity : forall x y z, R x y -> R y z -> R x z.
+
+This declares singleton classes for reflexive and transitive relations,
+(see the :ref:`singleton class <singleton-class>` variant for an
+explanation). These may be used as part of other classes:
+
+.. coqtop:: all
+
+ Class PreOrder (A : Type) (R : relation A) :=
+ { PreOrder_Reflexive :> Reflexive A R ;
+ PreOrder_Transitive :> Transitive A R }.
+
+The syntax ``:>`` indicates that each ``PreOrder`` can be seen as a
+``Reflexive`` relation. So each time a reflexive relation is needed, a
+preorder can be used instead. This is very similar to the coercion
+mechanism of ``Structure`` declarations. The implementation simply
+declares each projection as an instance.
+
+One can also declare existing objects or structure projections using
+the Existing Instance command to achieve the same effect.
+
+
+Summary of the commands
+-----------------------
+
+
+.. _Class:
+
+.. cmd:: Class @ident {? @binders} : {? @sort} := {? @ident} { {+; @ident :{? >} @term } }.
+
+ The ``Class`` command is used to declare a type class with parameters
+ ``binders`` and fields the declared record fields.
+
+Variants:
+
+.. _singleton-class:
+
+.. cmd:: Class @ident {? @binders} : {? @sort} := @ident : @term
+
+ This variant declares a *singleton* class with a single method. This
+ singleton class is a so-called definitional class, represented simply
+ as a definition ``ident binders := term`` and whose instances are
+ themselves objects of this type. Definitional classes are not wrapped
+ inside records, and the trivial projection of an instance of such a
+ class is convertible to the instance itself. This can be useful to
+ make instances of existing objects easily and to reduce proof size by
+ not inserting useless projections. The class constant itself is
+ declared rigid during resolution so that the class abstraction is
+ maintained.
+
+.. cmd:: Existing Class @ident
+
+ 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
+fields ``b1`` to ``bi``, where each field must be a declared field of
+the class. Missing fields must be filled in interactive proof mode.
+
+An arbitrary context of ``binders`` can be put after the name of the
+instance and before the colon to declare a parameterized instance. An
+optional priority can be declared, 0 being the highest priority as for
+auto hints. If the priority is not specified, it defaults to the number
+of non-dependent binders of the instance.
+
+..cmdv:: Instance @ident {? @binders} : forall {? @binders}, Class t1 … tn [| priority] := @term
+
+ This syntax is used for declaration of singleton class instances or
+ for directly giving an explicit term of type ``forall binders, Class
+ t1 … tn``. One need not even mention the unique field name for
+ singleton classes.
+
+..cmdv:: Global Instance
+
+ One can use the ``Global`` modifier on instances declared in a
+ section so that their generalization is automatically redeclared
+ after the section is closed.
+
+..cmdv:: Program Instance
+
+ Switches the type-checking to Program (chapter :ref:`programs`) and
+ uses the obligation mechanism to manage missing fields.
+
+..cmdv:: 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.
+
+
+Besides the ``Class`` and ``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
+~~~~~~~
+
+.. cmd:: Context @binders
+
+Declares variables according to the given binding context, which might
+use :ref:`implicit-generalization`.
+
+.. tacn:: typeclasses eauto
+
+This tactic uses a different resolution engine than :tacn:`eauto` and
+:tacn:`auto`. The main differences are the following:
+
++ Contrary to ``eauto`` and ``auto``, the resolution is done entirely in
+ the new proof engine (as of Coq v8.6), meaning that backtracking is
+ available among dependent subgoals, and shelving goals is supported.
+ typeclasses eauto is a multi-goal tactic. It analyses the dependencies
+ between subgoals to avoid backtracking on subgoals that are entirely
+ independent.
+
++ When called with no arguments, typeclasses eauto uses
+ thetypeclass_instances database by default (instead of core).
+ Dependent subgoals are automatically shelved, and shelved goals can
+ remain after resolution ends (following the behavior ofCoq 8.5).
+ *Note: * As of Coq 8.6, all:once (typeclasses eauto) faithfully
+ mimicks what happens during typeclass resolution when it is called
+ during refinement/type-inference, except that *only* declared class
+ subgoals are considered at the start of resolution during type
+ inference, while “all” can select non-class subgoals as well. It might
+ move to ``all:typeclasses eauto`` in future versions when the
+ refinement engine will be able to backtrack.
+
++ When called with specific databases (e.g. with), typeclasses eauto
+ allows shelved goals to remain at any point during search and treat
+ typeclasses goals like any other.
+
++ The transparency information of databases is used consistently for
+ all hints declared in them. It is always used when calling the
+ unifier. When considering the local hypotheses, we use the transparent
+ state of the first hint database given. Using an empty database
+ (created with Create HintDb for example) with unfoldable variables and
+ constants as the first argument of typeclasses eauto hence makes
+ resolution with the local hypotheses use full conversion during
+ unification.
+
+
+Variants:
+
+#. ``typeclasses eauto [num]``
+
+ *Warning:* The semantics for the limit num
+ is different than for auto. By default, if no limit is given the
+ search is unbounded. Contrary to auto, introduction steps (intro) are
+ counted, which might result in larger limits being necessary when
+ searching with typeclasses eauto than auto.
+
+#. ``typeclasses eauto with {+ @ident}``
+
+ This variant runs resolution with the given hint databases. It treats
+ typeclass subgoals the same as other subgoals (no shelving of
+ non-typeclass goals in particular).
+
+.. 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 Transparent, Typclasses Opaque
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. cmd:: Typeclasses Transparent {+ @ident}
+
+ This command defines makes the identifiers transparent during type class
+ resolution.
+
+ .. cmdv:: Typeclasses Opaque {+ @ident}
+ :name: Typeclasses Opaque
+
+ Make the identifiers opaque for typeclass search. It is useful when some
+ constants prevent some unifications and make resolution fail. It is also
+ useful to declare constants which should never be unfolded during
+ proof-search, like fixpoints or anything which does not look like an
+ abbreviation. This can additionally speed up proof search as the typeclass
+ map can be indexed by such rigid constants (see
+ :ref:`thehintsdatabasesforautoandeauto`).
+
+ By default, all constants and local variables are considered transparent. One
+ should take care not to make opaque any constant that is used to abbreviate a
+ type, like:
+
+ ::
+
+ relation A := A -> A -> Prop.
+
+ This is equivalent to ``Hint Transparent, Opaque ident : typeclass_instances``.
+
+
+.. opt:: Typeclasses Dependency Order
+
+ This option (on by default since 8.6) respects the dependency order
+ between subgoals, meaning that subgoals which are depended on by other
+ subgoals come first, while the non-dependent subgoals were put before
+ the dependent ones previously (Coq v8.5 and below). This can result in
+ quite different performance behaviors of proof search.
+
+
+.. opt:: Typeclasses Filtered Unification
+
+ 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:: Typeclasses Limit Intros
+
+ 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:: 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 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 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.
+
+
+.. 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.
+
+
+Typeclasses eauto `:=`
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. cmd:: Typeclasses eauto := {? debug} {? {dfs | bfs}} depth
+
+ This command allows more global customization of the type class
+ resolution tactic. The semantics of the options are:
+
+ + ``debug`` In debug mode, the trace of successfully applied tactics is
+ printed.
+
+ + ``dfs, bfs`` This sets the search strategy to depth-first search (the
+ default) or breadth-first search.
+
+ + ``depth`` This sets the depth limit of the search.
+
+
+Set Typeclasses Debug
+~~~~~~~~~~~~~~~~~~~~~
+
+.. opt:: Typeclasses Debug {? Verbosity @num}
+
+These options allow to see the resolution steps of typeclasses that are
+performed during search. The ``Debug`` option is synonymous to ``Debug
+Verbosity 1``, and ``Debug Verbosity 2`` provides more information
+(tried tactics, shelving of goals, etc…).
+
+
+.. opt:: Refine Instance Mode
+
+This options allows to switch the behavior of instance declarations made through
+the Instance command.
+
++ When it is on (the default), instances that have unsolved holes in
+ their proof-term silently open the proof mode with the remaining
+ obligations to prove.
+
++ When it is off, they fail with an error instead.
diff --git a/doc/sphinx/addendum/universe-polymorphism.rst b/doc/sphinx/addendum/universe-polymorphism.rst
new file mode 100644
index 000000000..c791fc906
--- /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
+:g:`Set 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 :g:`Set 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 :g:`Set 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 :ref:`Show Universes <ShowUniverses>` 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.
+
+ The command ``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.
diff --git a/doc/sphinx/biblio.bib b/doc/sphinx/biblio.bib
index 247f32103..97231c9ec 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}},
diff --git a/doc/sphinx/credits.rst b/doc/sphinx/credits.rst
index a60f32645..a75659798 100644
--- a/doc/sphinx/credits.rst
+++ b/doc/sphinx/credits.rst
@@ -376,7 +376,7 @@ contributed by Jean Goubault was integrated in the basic theories.
Pierre Courtieu developed a command and a tactic to reason on the
inductive structure of recursively defined functions.
-Jacek Chrzszcz designed and implemented the module system of |Coq| whose
+Jacek Chrząszcz designed and implemented the module system of |Coq| whose
foundations are in Judicaël Courant’s PhD thesis.
The development was coordinated by C. Paulin.
@@ -478,7 +478,7 @@ Marché and Bruno Barras.
Claude Marché coordinated the edition of the Reference Manual for |Coq|
V8.0.
-Pierre Letouzey and Jacek Chrzszcz respectively maintained the
+Pierre Letouzey and Jacek Chrząszcz respectively maintained the
extraction tool and module system of |Coq|.
Jean-Christophe Filliâtre, Pierre Letouzey, Hugo Herbelin and other
@@ -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 c5d4936b1..296330607 100644
--- a/doc/sphinx/index.rst
+++ b/doc/sphinx/index.rst
@@ -16,6 +16,7 @@ Table of contents
.. toctree::
:caption: The language
+ language/gallina-specification-language
language/gallina-extensions
language/coq-library
language/cic
@@ -24,7 +25,10 @@ Table of contents
.. toctree::
:caption: The proof engine
+ proof-engine/vernacular-commands
+ proof-engine/proof-handling
proof-engine/tactics
+ proof-engine/ltac
proof-engine/detailed-tactic-examples
proof-engine/ssreflect-proof-language
@@ -38,15 +42,26 @@ Table of contents
:caption: Practical tools
practical-tools/coq-commands
+ practical-tools/utilities
practical-tools/coqide
.. toctree::
:caption: Addendum
addendum/extended-pattern-matching
+ addendum/implicit-coercions
addendum/canonical-structures
+ addendum/type-classes
addendum/omega
addendum/micromega
+ addendum/extraction
+ addendum/program
+ addendum/ring
+ addendum/nsatz
+ 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..4a313df0c 100644
--- a/doc/sphinx/introduction.rst
+++ b/doc/sphinx/introduction.rst
@@ -2,7 +2,7 @@
Introduction
------------------------
-This document is the Reference Manual of version of the |Coq|  proof
+This document is the Reference Manual of the |Coq|  proof
assistant. A companion volume, the |Coq| Tutorial, is provided for the
beginners. It is advised to read the Tutorial first. A
book :cite:`CoqArt` on practical uses of the |Coq| system was
@@ -60,7 +60,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 +76,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..5a2aa0a1f 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,11 +905,12 @@ 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`
@@ -937,12 +957,11 @@ For instance, if one considers the type
╰─ list satisfies the positivity condition for list 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 +1028,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 +1074,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 +1104,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 +1127,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 +1156,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 +1235,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 +1296,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 +1497,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 +1643,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 +1701,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 d618d90ad..1a7628d89 100644
--- a/doc/sphinx/language/gallina-extensions.rst
+++ b/doc/sphinx/language/gallina-extensions.rst
@@ -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
@@ -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
++++++++++++++++++++++++++++++++++++++++++
@@ -667,7 +627,7 @@ The following experimental command is available when the ``FunInd`` library has
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
@@ -752,7 +712,7 @@ terminating functions.
`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,13 +772,14 @@ 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.
@@ -888,7 +849,7 @@ 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.
@@ -974,8 +935,6 @@ Reserved commands inside an interactive module
is equivalent to an interactive module where each `module_expression` is included.
-.. _named_module_type:
-
.. cmd:: Module Type @ident.
This command is used to start an interactive module type `ident`.
@@ -996,7 +955,8 @@ Reserved commands inside an interactive module type:
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.
@@ -1188,24 +1148,24 @@ 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:
@@ -1236,7 +1196,7 @@ in ``SIG``.
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`).
+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
@@ -1282,13 +1242,11 @@ qualified name.
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`.
-
Libraries and qualified names
---------------------------------
+.. _names-of-libraries:
+
Names of libraries
~~~~~~~~~~~~~~~~~~
@@ -1296,15 +1254,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 +1298,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 +1326,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 +1370,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 +1378,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 +1386,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
------------------
@@ -1548,10 +1507,10 @@ 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 ``Implicit
+Arguments`` (see Section :ref:`declare-implicit-args`) or globally by the
+:opt:`Maximal Implicit Insertion` option.
See also :ref:`displaying-implicit-args`.
@@ -1627,6 +1586,7 @@ Declaring Implicit Arguments
To set implicit arguments *a posteriori*, one can use the command:
.. 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
@@ -1780,14 +1740,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 +1752,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.
+implicit all non strict implicit arguments by default, you can turn this
+option off.
-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.
+.. opt:: Strongly Strict Implicit.
-In the other way round, to capture exactly the strict implicit
-arguments and no more than the strict implicit arguments, use the
-command
-
-.. 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
-
-.. cmd:: Set Contextual Implicit.
+.. opt:: 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
~~~~~~~~~~~~~~~~~~~~~
@@ -1935,28 +1870,20 @@ if each of them is to be used maximally or not, use the command
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
+.. opt:: Printing Implicit.
-.. cmd:: Set 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
+be deactivated by turning this option off.
-.. cmd:: Unset Printing Implicit Defensive.
-
-Conversely, to force the display of non strict arguments, use command
-
-.. 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 +1908,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, 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
~~~~~~~~~~~~~~~~~~~~
@@ -2109,6 +2033,8 @@ case, this latter type is considered).
Adds blocks of implicit types with different specifications.
+.. _implicit-generalization:
+
Implicit generalization
~~~~~~~~~~~~~~~~~~~~~~~
@@ -2175,6 +2101,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
---------
@@ -2189,12 +2116,7 @@ an inductive type or any constant with a type of the form
Then the user is able to apply an object that is not a function, but
can be coerced to a function, and more generally to consider that a
term of type ``A`` is of type ``B`` provided that there is a declared coercion
-between ``A`` and ``B``. The main command is
-
-.. cmd:: Coercion @qualid : @class >-> @class.
-
-which declares the construction denoted by qualid as a coercion
-between the two given classes.
+between ``A`` and ``B``.
More details and examples, and a description of the commands related
to coercions are provided in :ref:`implicitcoercions`.
@@ -2204,43 +2126,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.
+ :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
@@ -2248,12 +2165,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
---------------------
@@ -2263,9 +2181,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.
@@ -2310,25 +2228,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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2341,7 +2253,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
@@ -2352,5 +2264,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..a9c4dd758
--- /dev/null
+++ b/doc/sphinx/language/gallina-specification-language.rst
@@ -0,0 +1,1376 @@
+.. _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 (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 (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) }.
+
+.. 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 (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.
+
+.. 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`, :tac:`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 (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 (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 (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..93dcfca4b 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.
@@ -170,7 +177,7 @@ and ``coqtop``, unless stated otherwise:
:-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
new file mode 100644
index 000000000..59867988a
--- /dev/null
+++ b/doc/sphinx/practical-tools/utilities.rst
@@ -0,0 +1,1008 @@
+.. include:: ../replaces.rst
+
+.. _utilities:
+
+---------------------
+ Utilities
+---------------------
+
+The distribution provides utilities to simplify some tedious works
+beside proof development, tactics writing or documentation.
+
+
+Using Coq as a library
+----------------------
+
+In previous versions, ``coqmktop`` was used to build custom
+toplevels - for example for better debugging or custom static
+linking. Nowadays, the preferred method is to use ``ocamlfind``.
+
+The most basic custom toplevel is built using:
+
+::
+
+ % ocamlfind ocamlopt -thread -rectypes -linkall -linkpkg \
+ -package coq.toplevel \
+ toplevel/coqtop\_bin.ml -o my\_toplevel.native
+
+
+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.
+
+
+Building a |Coq| project with coq_makefile
+------------------------------------------
+
+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:`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:
+
+::
+
+ -R theories/ MyCode
+ theories/foo.v
+ theories/bar.v
+ -I src/
+ src/baz.ml4
+ src/bazaux.ml
+ src/qux_plugin.mlpack
+
+
+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
+for the |Coq| project based on makefiles. The recommended way of
+invoking ``coq_makefile`` is the following one:
+
+::
+
+ coq_makefile -f _CoqProject -o CoqMakefile
+
+
+Such command generates the following files:
+
+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.
+
+CoqMakefile.conf
+ contains make variables assignments that reflect
+ the contents of the ``_CoqProject`` file as well as the path relevant to
+ |Coq|.
+
+
+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:`coqmakefilelocal`.
+
+The extensions of the files listed in ``_CoqProject`` is used in order to
+decide how to build them. In particular:
+
+
++ |Coq| files must use the ``.v`` extension
++ |OCaml| files must use the ``.ml`` or ``.mli`` extension
++ |OCaml| files that require pre processing for syntax
+ extensions (like ``VERNAC EXTEND``) must use the ``.ml4`` extension
++ In order to generate a plugin one has to list all |OCaml|
+ modules (i.e. ``Baz`` for ``baz.ml``) in a ``.mlpack`` file (or ``.mllib``
+ file).
+
+
+The use of ``.mlpack`` files has to be preferred over ``.mllib`` files,
+since it results in a “packed” plugin: All auxiliary modules (as
+``Baz`` and ``Bazaux``) are hidden inside the plugin’s “name space”
+(``Qux_plugin``). This reduces the chances of begin unable to load two
+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::
+
+ ::
+
+ pre-all::
+ echo "This line is print before making the all target"
+ 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.
+
+``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-doc::``
+ One can use this to install extra doc.
+
+``uninstall::``
+ \
+
+``uninstall-doc::``
+ \
+
+``clean::``
+ \
+
+``cleanall::``
+ \
+
+``archclean::``
+ \
+
+``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.
+
+The following targets and Makefile variables allow collection of per-
+file timing data:
+
+
++ ``TIMED=1``
+ passing this variable will cause ``make`` to emit a line
+ describing the user-space build-time and peak memory usage for each
+ file built.
+
+ .. note::
+ On ``Mac OS``, this works best if you’ve installed ``gnu-time``.
+
+ .. example::
+ For example, the output of ``make TIMED=1`` may look like
+ this:
+
+ ::
+
+ COQDEP Fast.v
+ COQDEP Slow.v
+ COQC Slow.v
+ Slow (user: 0.34 mem: 395448 ko)
+ COQC Fast.v
+ Fast (user: 0.01 mem: 45184 ko)
+
++ ``pretty-timed``
+ this target stores the output of ``make TIMED=1`` into
+ ``time-of-build.log``, and displays a table of the times, sorted from
+ slowest to fastest, which is also stored in ``time-of-build-pretty.log``.
+ If you want to construct the ``log`` for targets other than the default
+ one, you can pass them via the variable ``TGTS``, e.g., ``make pretty-timed
+ TGTS="a.vo b.vo"``.
+
+ .. ::
+ This target requires ``python`` to build the table.
+
+ .. note::
+ This target will *append* to the timing log; if you want a
+ fresh start, you must remove the ``filetime-of-build.log`` or
+ ``run make cleanall``.
+
+ .. example::
+
+ For example, the output of ``make pretty-timed`` may look like this:
+
+ ::
+
+ COQDEP Fast.v
+ COQDEP Slow.v
+ COQC Slow.v
+ Slow (user: 0.36 mem: 393912 ko)
+ COQC Fast.v
+ Fast (user: 0.05 mem: 45992 ko)
+ Time | File Name
+ --------------------
+ 0m00.41s | Total
+ --------------------
+ 0m00.36s | Slow
+ 0m00.05s | Fast
+
+
++ ``print-pretty-timed-diff``
+ this target builds a table of timing
+ changes between two compilations; run ``make make-pretty-timed-before`` to
+ build the log of the “before” times, and run ``make make-pretty-timed-
+ after`` to build the log of the “after” times. The table is printed on
+ the command line, and stored in ``time-of-build-both.log``. This target is
+ most useful for profiling the difference between two commits to a
+ repo.
+
+ .. note::
+ This target requires ``python`` to build the table.
+
+ .. note::
+ The ``make-pretty-timed-before`` and ``make-pretty-timed-after`` targets will
+ *append* to the timing log; if you want a fresh start, you must remove
+ the files ``time-of-build-before.log`` and ``time-of-build-after.log`` or run
+ ``make cleanall`` *before* building either the “before” or “after”
+ targets.
+
+ .. note::
+ The table will be sorted first by absolute time
+ differences rounded towards zero to a whole-number of seconds, then by
+ times in the “after” column, and finally lexicographically by file
+ name. This will put the biggest changes in either direction first, and
+ will prefer sorting by build-time over subsecond changes in build time
+ (which are frequently noise); lexicographic sorting forces an order on
+ files which take effectively no time to compile.
+
+ .. example::
+ For example, the output table from
+ ``make print-pretty-timed-diff`` may look like this:
+
+ ::
+
+ After | File Name | Before || Change | % Change
+ --------------------------------------------------------
+ 0m00.39s | Total | 0m00.35s || +0m00.03s | +11.42%
+ --------------------------------------------------------
+ 0m00.37s | Slow | 0m00.01s || +0m00.36s | +3600.00%
+ 0m00.02s | Fast | 0m00.34s || -0m00.32s | -94.11%
+
+
+The following targets and ``Makefile`` variables allow collection of per-
+line timing data:
+
+
++ ``TIMING=1``
+ passing this variable will cause ``make`` to use ``coqc -time`` to
+ write to a ``.v.timing`` file for each ``.v`` file compiled, which contains
+ line-by-line timing information.
+
+ .. example::
+ For example, running ``make all TIMING=1`` may result in a file like this:
+
+ ::
+
+ Chars 0 - 26 [Require~Coq.ZArith.BinInt.] 0.157 secs (0.128u,0.028s)
+ Chars 27 - 68 [Declare~Reduction~comp~:=~vm_c...] 0. secs (0.u,0.s)
+ Chars 69 - 162 [Definition~foo0~:=~Eval~comp~i...] 0.153 secs (0.136u,0.019s)
+ Chars 163 - 208 [Definition~foo1~:=~Eval~comp~i...] 0.239 secs (0.236u,0.s)
+
++ ``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,
+ which defaults to ``time-of-build-pretty.log``.
+ To generate the ``.v.before-timing`` or ``.v.after-timing`` files, you should
+ pass ``TIMING=before`` or ``TIMING=after`` rather than ``TIMING=1``.
+
+ .. note::
+ The sorting used here is the same as in the ``print-pretty-timed -diff`` target.
+
+ .. note::
+ This target requires python to build the table.
+
+ .. example::
+ For example, running ``print-pretty-single-time-diff`` might give a table like this:
+
+ ::
+
+ After | Code | Before || Change | % Change
+ ---------------------------------------------------------------------------------------------------
+ 0m00.50s | Total | 0m04.17s || -0m03.66s | -87.96%
+ ---------------------------------------------------------------------------------------------------
+ 0m00.145s | Chars 069 - 162 [Definition~foo0~:=~Eval~comp~i...] | 0m00.192s || -0m00.04s | -24.47%
+ 0m00.126s | Chars 000 - 026 [Require~Coq.ZArith.BinInt.] | 0m00.143s || -0m00.01s | -11.88%
+ N/A | Chars 027 - 068 [Declare~Reduction~comp~:=~nati...] | 0m00.s || +0m00.00s | N/A
+ 0m00.s | Chars 027 - 068 [Declare~Reduction~comp~:=~vm_c...] | N/A || +0m00.00s | N/A
+ 0m00.231s | Chars 163 - 208 [Definition~foo1~:=~Eval~comp~i...] | 0m03.836s || -0m03.60s | -93.97%
+
+
++ ``all.timing.diff``, ``path/to/file.v.timing.diff``
+ The ``path/to/file.v.timing.diff`` target will make a ``.v.timing.diff`` file for
+ the corresponding ``.v`` file, with a table as would be generated by
+ the ``print-pretty-single-time-diff`` target; it depends on having already
+ made the corresponding ``.v.before-timing`` and ``.v.after-timing`` files,
+ which can be made by passing ``TIMING=before`` and ``TIMING=after``.
+ The ``all.timing.diff`` target will make such timing difference files for
+ all of the ``.v`` files that the ``Makefile`` knows about. It will fail if
+ some ``.v.before-timing`` or ``.v.after-timing`` files don’t exist.
+
+ .. note::
+ This target requires python to build the table.
+
+
+Reusing/extending the generated Makefile
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Including the generated makefile with an include directive is
+discouraged. The contents of this file, including variable names and
+status of rules shall change in the future. Users are advised to
+include ``Makefile.conf`` or call a target of the generated Makefile as in
+``make -f Makefile target`` from another Makefile.
+
+One way to get access to all targets of the generated ``CoqMakefile`` is to
+have a generic target for invoking unknown targets.
+
+.. example::
+
+ ::
+
+ # KNOWNTARGETS will not be passed along to CoqMakefile
+ KNOWNTARGETS := CoqMakefile extra-stuff extra-stuff2
+ # KNOWNFILES will not get implicit targets from the final rule, and so
+ # depending on them won't invoke the submake
+ # Warning: These files get declared as PHONY, so any targets depending
+ # on them always get rebuilt
+ KNOWNFILES := Makefile _CoqProject
+
+ .DEFAULT_GOAL := invoke-coqmakefile
+
+ CoqMakefile: Makefile _CoqProject
+ $(COQBIN)coq_makefile -f _CoqProject -o CoqMakefile
+
+ invoke-coqmakefile: CoqMakefile
+ $(MAKE) --no-print-directory -f CoqMakefile $(filter-out $(KNOWNTARGETS),$(MAKECMDGOALS))
+
+ .PHONY: invoke-coqmakefile $(KNOWNFILES)
+
+ ####################################################################
+ ## Your targets here ##
+ ####################################################################
+
+ # This should be the last rule, to handle any targets not declared above
+ %: invoke-coqmakefile
+ @true
+
+
+
+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``.
+
+.. note::
+
+ ``make foo.vo bar.vo -j`` has a different meaning for the make
+ utility, in particular it may build a shared prerequisite twice.
+
+
+.. note::
+
+ For users of coq_makefile with version < 8.7
+
+ + Support for “sub-directory” is deprecated. To perform actions before
+ or after the build (like invoking ``make`` on a subdirectory) one can hook
+ in pre-all and post-all extension points.
+ + ``-extra-phony`` and ``-extra`` are deprecated. To provide additional target
+ (``.PHONY`` or not) please use ``CoqMakefile.local``.
+
+
+
+Modules dependencies
+--------------------
+
+In order to compute modules dependencies (so to use ``make``), |Coq| comes
+with an appropriate tool, ``coqdep``.
+
+``coqdep`` computes inter-module dependencies for |Coq| and |OCaml|
+programs, and prints the dependencies on the standard output in a
+format readable by make. When a directory is given as argument, it is
+recursively looked at.
+
+Dependencies of |Coq| modules are computed by looking at ``Require``
+commands (``Require``, ``Require Export``, ``Require Import``), but also at the
+command ``Declare ML Module``.
+
+Dependencies of |OCaml| modules are computed by looking at
+`open` commands and the dot notation *module.value*. However, this is
+done approximately and you are advised to use ``ocamldep`` instead for the
+|OCaml| modules dependencies.
+
+See the man page of ``coqdep`` for more details and options.
+
+The build infrastructure generated by ``coq_makefile`` uses ``coqdep`` to
+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
+
+
+#. 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.
+
+
+
+Principles
+~~~~~~~~~~
+
+Documentation is inserted into |Coq| files as *special comments*. Thus
+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
+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
+quoted code (thus you can quote a term like ``fun x => u`` by writing ``[fun
+x => u]``). Inside quotations, the code is pretty-printed in the same
+way as it is in code parts.
+
+Pre-formatted vernacular is enclosed by ``[[`` and ``]]``. The former must be
+followed by a newline and the latter must follow a newline.
+
+
+Pretty-printing.
+++++++++++++++++
+
+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:
+
+::
+
+
+ (** printing *token* %...LATEX...% #...html...# *)
+
+
+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
+default pretty-printing to be used for this token.
+
+The printing for one token can be removed with
+
+::
+
+
+ (** remove printing *token* *)
+
+
+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.
+
+ ::
+
+ (** printing ->~ %\ensuremath{\rightarrow\lnot}% *)
+
+
+
+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
+sub-section, etc. The section title is given on the remaining of the
+line.
+
+.. example::
+
+ ::
+
+ (** * Well-founded relations
+
+ In this section, we introduce... *)
+
+
+Lists.
+++++++
+
+List items are introduced by a leading dash. coqdoc uses whitespace to
+determine the depth of a new list item and which text belongs in which
+list items. A list ends when a line of text starts at or before the
+level of indenting of the list’s dash. A list item’s dash must always
+be the first non-space character on its line (so, in particular, a
+list can not begin on the first line of a comment - start it on the
+second line instead).
+
+.. example::
+
+ ::
+
+ We go by induction on [n]:
+ - If [n] is 0...
+ - If [n] is [S n'] we require...
+
+ two paragraphs of reasoning, and two subcases:
+
+ - In the first case...
+ - In the second case...
+
+ So the theorem holds.
+
+
+
+Rules.
+++++++
+
+More than 4 leading dashes produce a horizontal rule.
+
+
+Emphasis.
++++++++++
+
+Text can be italicized by placing it in underscores. A non-identifier
+character must precede the leading underscore and follow the trailing
+underscore, so that uses of underscores in names aren’t mistaken for
+emphasis. Usually, these are spaces or punctuation.
+
+::
+
+ This sentence contains some _emphasized text_.
+
+
+
+Escaping to |Latex| and HTML.
++++++++++++++++++++++++++++++++
+
+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.
++ ``%...LATEX stuff...%`` inserts some |Latex| material. Simply
+ discarded in HTML output.
++ ``#...HTML stuff...#`` inserts some HTML material. Simply discarded in
+ |Latex| output.
+
+.. note::
+ to simply output the characters ``$``, ``%`` and ``#`` and escaping
+ their escaping role, these characters must be doubled.
+
+
+Verbatim
+++++++++
+
+Verbatim material is introduced by a leading ``<<`` and closed by ``>>``
+at the beginning of a line.
+
+.. example::
+
+ ::
+
+ Here is the corresponding caml code:
+ <<
+ let rec fact n =
+ if n <= 1 then 1 else n * fact (n-1)
+ >>
+
+
+
+Hyperlinks
+++++++++++
+
+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
+``file.glob`` or appends it to a file specified using option ``--dump-glob
+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
+for name resolutions into the file ``file`` (it will look in ``file.glob``
+by default).
+
+Identifiers from the |Coq| standard library are linked to the Coq web
+site at `<http://coq.inria.fr/library/>`_. This behavior can be changed
+using command line options ``--no-externals`` and ``--coqlib``; see below.
+
+
+Hiding / Showing parts of the source.
++++++++++++++++++++++++++++++++++++++
+
+Some parts of the source can be hidden using command line options ``-g``
+and ``-l`` (see below), or using such comments:
+
+::
+
+
+ (* begin hide *)
+ *some Coq material*
+ (* end hide *)
+
+
+Conversely, some parts of the source which would be hidden can be
+shown using such comments:
+
+::
+
+
+ (* begin show *)
+ *some Coq material*
+ (* end show *)
+
+
+The latter cannot be used around some inner parts of a proof, but can
+be used around a whole proof.
+
+
+Usage
+~~~~~
+
+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
+ 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.
+:|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|
+ files given on the command line are copied ‘as is’ in the final
+ document . DVI and PostScript can be produced directly with the
+ options ``-dvi`` and ``-ps`` respectively.
+:TEXmacs output: To translate the input files to TEXmacs format,
+ to be used by the TEXmacs |Coq| interface.
+
+
+
+Command line options
+++++++++++++++++++++
+
+
+**Overall options**
+
+
+ :--HTML: Select a HTML output.
+ :--|Latex|: Select a |Latex| output.
+ :--dvi: Select a DVI output.
+ :--ps: Select a PostScript output.
+ :--texmacs: Select a TEXmacs output.
+ :--stdout: Write output to stdout.
+ :-o file, --output file: Redirect the output into the file ‘file’
+ (meaningless with ``-html``).
+ :-d dir, --directory dir: Output files into directory ‘dir’ instead of
+ current directory (option ``-d`` does not change the filename specified
+ with option ``-o``, if any).
+ :--body-only: Suppress the header and trailer of the final document.
+ Thus, you can insert the resulting document into a larger one.
+ :-p string, --preamble string: Insert some material in the |Latex|
+ preamble, right before ``\begin{document}`` (meaningless with ``-html``).
+ :--vernac-file file,--tex-file file: Considers the file ‘file’
+ respectively as a ``.v`` (or ``.g``) file or a ``.tex`` file.
+ :--files-from file: Read file names to process in file ‘file’ as if
+ they were given on the command line. Useful for program sources split
+ up into several directories.
+ :-q, --quiet: Be quiet. Do not print anything except errors.
+ :-h, --help: Give a short summary of the options and exit.
+ :-v, --version: Print the version and exit.
+
+
+
+**Index options**
+
+ Default behavior is to build an index, for the HTML output only,
+ into ``index.html``.
+
+ :--no-index: Do not output the index.
+ :--multi-index: Generate one page for each category and each letter in
+ the index, together with a top page ``index.html``.
+ :--index string: Make the filename of the index string instead of
+ “index”. Useful since “index.html” is special.
+
+
+
+**Table of contents option**
+
+ :-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
+ ``toc.html``.
+ :--toc-depth int: Only include headers up to depth ``int`` in the table of
+ contents.
+
+
+**Hyperlinks options**
+
+ :--glob-from file: Make references using |Coq| globalizations from file
+ file. (Such globalizations are obtained with Coq option ``-dump-glob``).
+ :--no-externals: Do not insert links to the |Coq| standard library.
+ :--external url coqdir: Use given URL for linking references whose
+ name starts with prefix ``coqdir``.
+ :--coqlib url: Set base URL for the Coq standard library (default is
+ `<http://coq.inria.fr/library/>`_). This is equivalent to ``--external url
+ Coq``.
+ :-R dir coqdir: Map physical directory dir to |Coq| logical
+ 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.
+
+
+**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.
+ :--lib-name string: Print “string Foo” instead of “Library Foo” in
+ 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:
+
+ ::
+
+ (** * 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.
+ :-t string, --title string: Set the document title.
+
+
+**Contents options**
+
+ :-g, --gallina: Do not print proofs.
+ :-l, --light: Light mode. Suppress proofs (as with ``-g``) and the following commands:
+
+ + [Recursive] Tactic Definition
+ + Hint / Hints
+ + Require
+ + Transparent / Opaque
+ + Implicit Argument / Implicits
+ + Section / Variable / Hypothesis / End
+
+
+
+ The behavior of options ``-g`` and ``-l`` can be locally overridden using the
+ ``(* begin show *) … (* end show *)`` environment (see above).
+
+ There are a few options to drive the parsing of comments:
+
+ :--parse-comments: Parses regular comments delimited by ``(*`` and ``*)`` as
+ well. They are typeset inline.
+ :--plain-comments: Do not interpret comments, simply copy them as
+ plain-text.
+ :--interpolate: Use the globalization information to typeset
+ identifiers appearing in |Coq| escapings inside comments.
+
+**Language options**
+
+
+ Default behavior is to assume ASCII 7 bits input files.
+
+ :-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
+ 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
+ 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
+ ``\DeclareUnicodeCharacter{code}{LATEX-interpretation}``. Packages
+ 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.
+
+
+
+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
+your own preamble the command
+
+::
+
+ \usepackage{coqdoc}
+
+The package optionally takes the argument ``[color]`` to typeset
+identifiers with colors (this requires the ``xcolor`` package).
+
+Then you may alter the rendering of the document by redefining some
+macros:
+
+:coqdockw, coqdocid, …: The one-argument macros for typesetting
+ keywords and identifiers. Defaults are sans-serif for keywords and
+ italic for identifiers.For example, if you would like a slanted font
+ for keywords, you may insert
+
+ ::
+
+ \renewcommand{\coqdockw}[1]{\textsl{#1}}
+
+
+ anywhere between ``\usepackage{coqdoc}`` and ``\begin{document}``.
+
+
+:coqdocmodule:
+ One-argument macro for typesetting the title of a ``.v``
+ file. Default is
+
+ ::
+
+ \newcommand{\coqdocmodule}[1]{\section*{Module #1}}
+
+ and you may redefine it using ``\renewcommand``.
+
+Embedded Coq phrases inside |Latex| documents
+---------------------------------------------
+
+When writing a documentation about a proof development, one may want
+to insert |Coq| phrases inside a |Latex| document, possibly together
+with the corresponding answers of the system. We provide a mechanical
+way to process such |Coq| phrases embedded in |Latex| files: the ``coq-tex``
+filter. This filter extracts |Coq| phrases embedded in |Latex| files,
+evaluates them, and insert the outcome of the evaluation after each
+phrase.
+
+Starting with a file ``file.tex`` containing |Coq| phrases, the ``coq-tex``
+filter produces a file named ``file.v.tex`` with the Coq outcome.
+
+There are options to produce the |Coq| parts in smaller font, italic,
+between horizontal rules, etc. See the man page of ``coq-tex`` for more
+details.
+
+|Coq| and GNU Emacs
+-----------------------
+
+
+The |Coq| Emacs mode
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+|Coq| comes with a Major mode for GNU Emacs, ``gallina.el``. This mode
+provides syntax highlighting and also a rudimentary indentation
+facility in the style of the ``Caml`` GNU Emacs mode.
+
+Add the following lines to your ``.emacs`` file:
+
+::
+
+ (setq auto-mode-alist (cons '("\\.v$" . coq-mode) auto-mode-alist))
+ (autoload 'coq-mode "gallina" "Major mode for editing Coq vernacular." t)
+
+
+The |Coq| major mode is triggered by visiting a file with extension ``.v``,
+or manually with the command ``M-x coq-mode``. It gives you the correct
+syntax table for the |Coq| language, and also a rudimentary indentation
+facility:
+
+
++ pressing ``Tab`` at the beginning of a line indents the line like the
+ line above;
++ extra tabulations increase the indentation level (by 2 spaces by default);
++ ``M-Tab`` decreases the indentation level.
+
+
+An inferior mode to run |Coq| under Emacs, by Marco Maggesi, is also
+included in the distribution, in file ``inferior-coq.el``. Instructions to
+use it are contained in this file.
+
+
+Proof-General
+~~~~~~~~~~~~~
+
+Proof-General is a generic interface for proof assistants based on
+Emacs. The main idea is that the |Coq| commands you are editing are sent
+to a |Coq| toplevel running behind Emacs and the answers of the system
+automatically inserted into other Emacs buffers. Thus you don’t need
+to copy-paste the |Coq| material from your files to the |Coq| toplevel or
+conversely from the |Coq| toplevel to some files.
+
+Proof-General is developed and distributed independently of the system
+|Coq|. It is freely available at `<https://proofgeneral.github.io/>`_.
+
+
+Module specification
+--------------------
+
+Given a |Coq| vernacular file, the gallina filter extracts its
+specification (inductive types declarations, definitions, type of
+lemmas and theorems), removing the proofs parts of the file. The |Coq|
+file ``file.v`` gives birth to the specification file ``file.g`` (where
+the suffix ``.g`` stands for |Gallina|).
+
+See the man page of ``gallina`` for more details and options.
+
+
+Man pages
+---------
+
+There are man pages for the commands ``coqdep``, ``gallina`` and ``coq-tex``. Man
+pages are installed at installation time (see installation
+instructions in file ``INSTALL``, step 6).
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..009758319
--- /dev/null
+++ b/doc/sphinx/proof-engine/ltac.rst
@@ -0,0 +1,1300 @@
+.. 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
+
+ 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
+
+ In this variant, :n:`@expr` is applied to all focused goals. ``all:`` can only
+ be used at the toplevel of a tactic expression.
+
+ .. tacv:: par: @expr
+
+ 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:: Error message: 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 @natural
+
+ 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 @natural` is not enclosed in a :n:`+` command,
+ respecting the algebraic identity.
+
+ .. tacv:: fail {* message_token}
+
+ The given tokens are used for printing the failure message.
+
+ .. tacv:: fail @natural {* message_token}
+
+ 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 @natural {* 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 @natural).
+
+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
+
+ 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
+
+ This command can be used to print the trace of the path eventually taken by an
+ |Ltac| script. That is, the list of executed tactics, discarding
+ all the branches which have failed. To that end the Info command can be
+ 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 ``Info`` tries its best to be a reparsable
+ |Ltac| script, but this goal is not achievable in all generality.
+ So some of the output traces will contain oddities.
+
+ As an additional help for debugging, the trace produced by ``Info`` contains
+ (in comments) the messages produced by the idtac
+ tacticals \ `4.2 <#ltac%3Aidtac>`__ at the right possition in the
+ script. In particular, the calls to idtac in branches which failed are
+ not printed.
+
+ .. opt:: Info Level @num.
+
+ This option is an alternative to the ``Info`` command.
+
+ This will automatically print the same trace as :n:`Info @num` at each
+ tactic call. The unfolding level can be overridden by a call to the
+ ``Info`` command.
+
+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 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
+performs a ``Set Ltac Profiling`` at the beginning of each document, and a
+``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
new file mode 100644
index 000000000..86c94bab3
--- /dev/null
+++ b/doc/sphinx/proof-engine/proof-handling.rst
@@ -0,0 +1,600 @@
+.. include:: ../replaces.rst
+.. _proofhandling:
+
+-------------------
+ Proof handling
+-------------------
+
+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
+*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.
+
+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:`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*
+:cite:`How80,Bar81,Gir89,Hue88`, |Coq| stores proofs as terms of |Cic|. Those
+terms are called *proof terms*.
+
+
+.. exn:: No focused proof
+
+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 using an assertion command like :cmd:`Theorem`. The
+list of assertion commands is given in Section :ref:`Assertions`. The command
+:cmd:`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
+ :name: Qed (interactive proof)
+
+This command is available in interactive editing proof mode when the
+proof is completed. Then ``Qed`` extracts a proof term from the proof
+script, switches back to Coq top-level and attaches the extracted
+proof term to the declared name of the original goal. This name is
+added to the environment as an opaque constant.
+
+
+.. exn:: Attempt to save an incomplete proof
+
+.. note::
+
+ 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.
+
+.. cmdv:: Defined.
+ :name: Defined (interactive proof)
+
+Defines the proved term as a transparent constant.
+
+.. cmdv:: Save @ident.
+
+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.
+
+.. cmd:: Admitted.
+ :name: Admitted (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.
+
+.. cmd:: Proof @term.
+ :name: Proof `term`
+
+This command applies in proof editing mode. It is equivalent to
+
+.. cmd:: exact @term. Qed.
+
+That is, you have to give the full proof in one gulp, as a
+proof term (see Section :ref:`applyingtheorems`).
+
+.. cmdv:: Proof.
+ :name: Proof (interactive proof)
+
+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``.
+
+
+See also: ``Proof with tactic.`` in Section
+:ref:`tactics-implicit-automation`.
+
+
+.. cmd:: Proof using @ident1 ... @identn.
+
+This command applies in proof editing mode. It declares the set of
+section variables (see :ref:`gallina-assumptions`) used by the proof. At ``Qed`` time, the
+system will assert that the set of section variables actually used in
+the proof is a subset of the declared one.
+
+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 @ident1 ... @identn with @tactic.
+
+in Section :ref:`tactics-implicit-automation`.
+
+.. cmdv:: Proof using All.
+
+Use all section variables.
+
+
+.. cmdv:: Proof using Type.
+
+.. cmdv:: Proof using.
+
+Use only section variables occurring in the statement.
+
+
+.. 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.
+
+
+.. cmdv:: Proof using -(@ident1 ... @identn).
+
+Use all section variables except :n:`@ident1` ... :n:`@identn`.
+
+
+.. cmdv:: Proof using @collection1 + @collection2 .
+
+
+.. cmdv:: Proof using @collection1 - @collection2 .
+
+
+.. cmdv:: Proof using @collection - ( @ident1 ... @identn ).
+
+
+.. 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 ``-``.
+
+
+Proof using options
+```````````````````
+
+The following options modify the behavior of ``Proof using``.
+
+
+.. 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``.
+
+
+.. opt:: Suggest Proof Using.
+
+ When ``Qed`` is performed, suggest a using annotation if the user did not
+ provide one.
+
+.. _`nameaset`:
+
+Name a set of section hypotheses for ``Proof using``
+````````````````````````````````````````````````````
+
+.. cmd:: Collection @ident := @section_subset_expr
+
+The command ``Collection`` can be used to name a set of section
+hypotheses, with the purpose of making ``Proof using`` annotations more
+compact.
+
+
+.. cmdv:: Collection Some := x y z
+
+Define the collection named "Some" containing ``x``, ``y`` and ``z``.
+
+
+.. cmdv:: Collection Fewer := Some - z
+
+Define the collection named "Fewer" containing only ``x`` and ``y``.
+
+
+.. cmdv:: Collection Many := Fewer + Some
+.. cmdv:: Collection Many := Fewer - Some
+
+Define the collection named "Many" containing the set union or set
+difference of "Fewer" and "Some".
+
+
+.. cmdv:: Collection Many := Fewer - (x y)
+
+Define the collection named "Many" containing the set difference of
+"Fewer" and the unnamed collection ``x`` ``y``
+
+
+.. cmd:: 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.
+
+
+.. exn:: No focused proof (No proof-editing in progress)
+
+
+
+.. cmdv:: Abort @ident.
+
+Aborts the editing of the proof named :n:`@ident`.
+
+.. cmdv:: Abort All.
+
+Aborts all current goals, switching back to the |Coq|
+toplevel.
+
+
+
+.. 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 :tacn:`instantiate`.
+
+
+See also: ``instantiate (num:= term).`` in Section
+:ref:`controllingtheproofflow`.
+See also: ``Grab Existential Variables.`` below.
+
+
+.. cmd:: Grab Existential Variables.
+
+This command can be run when a proof has no more goal to be solved but
+has remaining uninstantiated existential variables. It takes every
+uninstantiated existential variable and turns it into a goal.
+
+
+Navigation in the proof tree
+--------------------------------
+
+
+.. cmd:: Undo.
+
+This command cancels the effect of the last command. Thus, it
+backtracks one step.
+
+
+.. cmdv:: Undo @num.
+
+Repeats Undo :n:`@num` times.
+
+.. cmdv:: Restart.
+ :name: Restart
+
+This command restores the proof editing process to the original goal.
+
+
+.. exn:: No focused proof to restart
+
+
+.. cmd:: Focus.
+
+This focuses the attention on the first subgoal to prove and the
+printing of the other subgoals is suspended until the focused subgoal
+is solved or unfocused. This is useful when there are many current
+subgoals which clutter your screen.
+
+
+.. cmdv:: Focus @num.
+
+This focuses the attention on the :n:`@num` th subgoal to
+prove.
+
+*This command is deprecated since 8.8*: prefer the use of bullets or
+focusing brackets instead, including :n:`@num : %{`
+
+.. cmd:: Unfocus.
+
+This command restores to focus the goal that were suspended by the
+last ``Focus`` command.
+
+*This command is deprecated since 8.8.*
+
+.. cmd:: Unfocused.
+
+Succeeds if the proof is fully unfocused, fails is 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.
+
+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: %{
+
+This focuses on the :n:`@num` th subgoal to prove.
+
+Error messages:
+
+.. 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.
+
+.. exn:: No such goal
+ :name: No such goal (focusing)
+
+.. exn:: Brackets only support the single numbered goal selector
+
+See also error messages about bullets below.
+
+.. _bullets:
+
+Bullets
+```````
+
+Alternatively to ``{`` and ``}``, proofs can be structured with bullets. The
+use of a bullet ``b`` for the first time focuses on the first goal ``g``, the
+same bullet cannot be used again until the proof of ``g`` is completed,
+then it is mandatory to focus the next goal with ``b``. The consequence is
+that ``g`` and all goals present when ``g`` was focused are focused with the
+same bullet ``b``. See the example below.
+
+Different bullets can be used to nest levels. The scope of bullet does
+not go beyond enclosing ``{`` and ``}``, so bullets can be reused as further
+nesting levels provided they are delimited by these. Available bullets
+are ``-``, ``+``, ``*``, ``--``, ``++``, ``**``, ``---``, ``+++``, ``***``, ... (without a terminating period).
+
+Note again 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::
+
+ In Proof General (``Emacs`` interface to |Coq|), you must use
+ bullets with the priority ordering shown above to have a correct
+ indentation. For example ``-`` must be the outer bullet and ``**`` the inner
+ one in the example below.
+
+The following example script illustrates all these features:
+
+.. example::
+ .. coqtop:: all
+
+ Goal (((True /\ True) /\ True) /\ True) /\ True.
+ Proof.
+ split.
+ - split.
+ + split.
+ ** { split.
+ - trivial.
+ - trivial.
+ }
+ ** trivial.
+ + trivial.
+ - assert True.
+ { trivial. }
+ assumption.
+
+
+.. 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.
+
+.. exn:: Wrong bullet @bullet1 : Bullet @bullet2 is mandatory 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.
+
+.. exn:: No such goal. Try unfocusing with %{.
+
+You just finished a goal focused by ``{``, you must unfocus it with ``}``.
+
+Set Bullet Behavior
+```````````````````
+
+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).
+
+
+.. _requestinginformation:
+
+Requesting information
+----------------------
+
+
+.. cmd:: Show.
+
+This command displays the current goals.
+
+
+.. cmdv:: Show @num
+
+Displays only the :n:`@num`-th subgoal.
+
+.. exn:: No such goal
+.. exn:: No focused proof
+
+.. cmdv:: Show @ident.
+
+Displays the named goal :n:`@ident`. This is useful in
+particular to display a shelved goal but only works if the
+corresponding existential variable has been named by the user
+(see :ref:`existential-variables`) as in the following example.
+
+.. example::
+
+ .. coqtop:: all
+
+ Goal exists n, n = 0.
+ eexists ?[n].
+ Show n.
+
+.. cmdv:: Show Script.
+
+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
+
+``<Your Tactic Text here>``.
+
+.. cmdv:: Show Proof.
+
+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 Conjectures.
+
+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 Intro.
+
+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 Intros.
+
+This command is similar to the previous one, it
+simulates the naming process of an intros.
+
+.. cmdv:: Show Existentials.
+
+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 Match @ident.
+
+This variant displays a template of the Gallina
+``match`` construct with a branch for each constructor of the type
+:n:`@ident`
+
+.. example::
+ .. coqtop:: all
+
+ Show Match nat.
+
+.. exn:: Unknown inductive type
+
+.. _ShowUniverses:
+
+.. cmdv:: 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.
+
+
+.. cmd:: Guarded.
+
+Some tactics (e.g. :tacn:`refine` :ref:`applyingtheorems`) allow to build proofs using
+fixpoint or co-fixpoint constructions. Due to the incremental nature
+of interactive proof construction, the check of the termination (or
+guardedness) of the recursive calls in the fixpoint or cofixpoint
+constructions is postponed to the time of the completion of the proof.
+
+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.
+
+
+Controlling the effect of proof editing commands
+------------------------------------------------
+
+
+.. opt:: Hyps Limit @num
+
+This option controls the maximum number of hypotheses displayed in goals
+after the application of a tactic. All the hypotheses remain usable
+in the proof development.
+When unset, it goes back to the default mode which is to print all
+available hypotheses.
+
+
+.. opt:: Automatic Introduction
+
+This option controls the way binders are handled
+in assertion commands such as ``Theorem ident [binders] : form``. When the
+option is set, which is the default, binders are automatically put in
+the local context of the goal to prove.
+
+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.
+
+
+Controlling memory usage
+------------------------
+
+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.
+
+This command forces |Coq| to shrink the data structure used to represent
+the ongoing proof.
+
+
+.. cmd:: Optimize Heap.
+
+This command forces the |OCaml| runtime to perform a heap compaction.
+This is in general an expensive operation.
+See: `OCaml Gc <http://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html#VALcompact>`_
+There is also an analogous tactic :tac:`optimize_heap`.
diff --git a/doc/sphinx/proof-engine/ssreflect-proof-language.rst b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
index 61dffa024..977a5b8fa 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
@@ -451,7 +448,7 @@ Anonymous arguments
~~~~~~~~~~~~~~~~~~~
When in a definition, the type of a certain argument is mandatory, but
-not its name, one usually use “arrow” abstractions for prenex
+not its name, one usually uses “arrow” abstractions for prenex
arguments, or the ``(_ : term)`` syntax for inner arguments. In |SSR|,
the latter can be replaced by the open syntax ``of term`` or
(equivalently) ``& term``, which are both syntactically equivalent to a
@@ -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:
@@ -518,7 +518,7 @@ is a valid tactic expression.
The pose tactic is also improved for the local definition of higher
order terms. Local definitions of functions can use the same syntax as
-global ones. For example the tactic ``pose`` supoprts parameters:
+global ones. For example, the tactic ``pose`` supoprts parameters:
.. example::
@@ -1295,7 +1295,7 @@ is a synonym for:
intro top; first [refine top | refine (top _) | refine (top _ _) | …]; clear top.
-where ``top`` is fresh name, and the sequence of refine tactics tries to
+where ``top`` is a fresh name, and the sequence of refine tactics tries to
catch the appropriate number of wildcards to be inserted. Note that
this use of the refine tactic implies that the tactic tries to match
the goal up to expansion of constants and evaluation of subterms.
@@ -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::
@@ -1573,7 +1576,7 @@ The :token:`i_pattern` s can be seen as a variant of *intro patterns*
:ref:`tactics`: each performs an introduction operation, i.e., pops some
variables or assumptions from the goal.
-An :token:`s_item` can simplify the set of subgoals or the subgoal themselves:
+An :token:`s_item` can simplify the set of subgoals or the subgoals themselves:
+ ``//`` removes all the “trivial” subgoals that can be resolved by the
|SSR| tactic ``done`` described in :ref:`terminators_ssr`, i.e.,
@@ -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
@@ -1831,7 +1836,7 @@ compact syntax:
case: {2}_ / eqP.
-were ``_`` is interpreted as ``(_ == _)`` since
+where ``_`` is interpreted as ``(_ == _)`` since
``eqP T a b : reflect (a = b) (a == b)`` and reflect is a type family with
one index.
@@ -2074,7 +2079,7 @@ is equivalent to:
do [done | by move=> top; apply top].
-where top is a fresh name affected to the top assumption of the goal.
+where ``top`` is a fresh name assigned to the top assumption of the goal.
This applied form is supported by the : discharge tactical, and the
tactic:
@@ -2090,7 +2095,7 @@ is equivalent to:
(see section :ref:`discharge_ssr` for the documentation of the apply: combination).
-Warning The list of tactics, possibly chained by semi-columns, that
+Warning The list of tactics, possibly chained by semicolons, that
follows a by keyword is considered as a parenthesized block applied to
the current goal. Hence for example if the tactic:
@@ -2123,7 +2128,7 @@ generated by the previous tactic. This covers the frequent cases where
a tactic generates two subgoals one of which can be easily disposed
of.
-This is an other powerful way of linearization of scripts, since it
+This is another powerful way of linearization of scripts, since it
happens very often that a trivial subgoal can be solved in a less than
one line tactic. For instance, the tactic:
@@ -2131,14 +2136,14 @@ one line tactic. For instance, the tactic:
:name: last
tries to solve the last subgoal generated by the first
-tactic using the given second tactic , and fails if it does not succeeds.
-Its analogous
+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 succeeds.
+second given tactic, and fails if it does not succeed.
|SSR| also offers an extension of this facility, by supplying
tactics to *permute* the subgoals generated by a tactic. The tactic:
@@ -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*.
@@ -2259,14 +2264,14 @@ For instance, the tactic:
tactic; do 1? rewrite mult_comm.
-rewrites at most one time the lemma ``mult_com`` in all the subgoals
+rewrites at most one time the lemma ``mult_comm`` in all the subgoals
generated by tactic , whereas the tactic:
.. coqtop:: in
tactic; do 2! rewrite mult_comm.
-rewrites exactly two times the lemma ``mult_com`` in all the subgoals
+rewrites exactly two times the lemma ``mult_comm`` in all the subgoals
generated by tactic, and fails if this rewrite is not possible in some
subgoal.
@@ -2335,10 +2340,10 @@ to the following one:
.. tacv:: @tactic in {+ @clear_switch | {? @ } @ident | ( @ident ) | ( {? @ } @ident := @c_pattern ) } {? * }
In its simplest form the last option lets one rename hypotheses that
-can’t be cleared (like section variables). For example ``(y := x)``
+can’t be cleared (like section variables). For example, ``(y := x)``
generalizes over ``x`` and reintroduces the generalized variable under the
name ``y`` (and does not clear ``x``).
-For a more precise description this form of localization refer
+For a more precise description of this form of localization refer
to :ref:`advanced_generalization_ssr`.
@@ -2351,7 +2356,7 @@ Forward reasoning structures the script by explicitly specifying some
assumptions to be added to the proof context. It is closely associated
with the declarative style of proof, since an extensive use of these
highlighted statements make the script closer to a (very detailed)
-text book proof.
+textbook proof.
Forward chaining tactics allow to state an intermediate lemma and start a
piece of script dedicated to the proof of this statement. The use of closing
@@ -2492,7 +2497,7 @@ also supported (assuming x occurs in the goal only):
have {x} -> : x = y.
-An other frequent use of the intro patterns combined with ``have`` is the
+Another frequent use of the intro patterns combined with ``have`` is the
destruction of existential assumptions like in the tactic:
.. example::
@@ -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
```````````````````````````````````
@@ -2845,8 +2847,8 @@ term -> G.
If the optional list of :token:`itent` is present
on the left side of ``/``, these constants are generalized in the
-premise (term -> G) of the first subgoal. By default the body of local
-definitions is erased. This behavior can be inhibited prefixing the
+premise (term -> G) of the first subgoal. By default bodies of local
+definitions are erased. This behavior can be inhibited by prefixing the
name of the local definition with the ``@`` character.
In the second subgoal, the tactic:
@@ -2936,7 +2938,7 @@ renaming does not require the original variable to be cleared.
The syntax ``(@x := y)`` generates a let-in abstraction but with the
following caveat: ``x`` will not bind ``y``, but its body, whenever ``y`` can be
-unfolded. This cover the case of both local and global definitions, as
+unfolded. This covers the case of both local and global definitions, as
illustrated in the following example.
.. example::
@@ -3035,7 +3037,7 @@ operation should be performed:
specifies if and how the
rewrite operation should be repeated.
+ A rewrite operation matches the occurrences of a *rewrite pattern*,
- and replaces these occurrences by an other term, according to the
+ and replaces these occurrences by another term, according to the
given :token:`r_item`. The optional *redex switch* ``[r_pattern]``,
which should
always be surrounded by brackets, gives explicitly this rewrite
@@ -3329,7 +3331,7 @@ The rewrite tactic can be provided a *tuple* of rewrite rules, or more
generally a tree of such rules, since this tuple can feature arbitrary
inner parentheses. We call *multirule* such a generalized rewrite
rule. This feature is of special interest when it is combined with
-multiplier switches, which makes the rewrite tactic iterates the
+multiplier switches, which makes the rewrite tactic iterate the
rewrite operations prescribed by the rules on the current goal.
@@ -3473,7 +3475,7 @@ efficient ones, e.g. for the purpose of a correctness proof.
Wildcards vs abstractions
`````````````````````````
-The rewrite tactic supports :token:`r_items` containing holes. For example in
+The rewrite tactic supports :token:`r_items` containing holes. For example, in
the tactic ``rewrite (_ : _ * 0 = 0).``
the term ``_ * 0 = 0`` is interpreted as ``forall n : nat, n * 0 = 0.``
Anyway this tactic is *not* equivalent to
@@ -3730,14 +3732,15 @@ 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.
We found that it was usually preferable to prevent the expansion of
some functions by the partial evaluation switch ``/=``, unless this
-allowed the evaluation of a condition. This is possible thanks to an
-other mechanism of term tagging, resting on the following *Notation*:
+allowed the evaluation of a condition. This is possible thanks to another
+mechanism of term tagging, resting on the following *Notation*:
.. coqtop:: in
@@ -3781,7 +3784,7 @@ arithmetic operations. We define for instance:
The operation ``addn`` behaves exactly like ``plus``, except that
``(addn (S n) m)`` will not simplify spontaneously to
-``(S (addn n m))`` (the two terms, however, are inter-convertible).
+``(S (addn n m))`` (the two terms, however, are convertible).
In addition, the unfolding step: ``rewrite /addn``
will replace ``addn`` directly with ``plus``, so the ``nosimpl`` form is
essentially invisible.
@@ -3792,7 +3795,7 @@ essentially invisible.
Congruence
~~~~~~~~~~
-Because of the way matching interferes with type families parameters,
+Because of the way matching interferes with parameters of type families,
the tactic:
.. coqtop:: in
@@ -3912,8 +3915,8 @@ The simple form of patterns used so far, terms possibly containing
wild cards, often require an additional :token:`occ_switch` to be specified.
While this may work pretty fine for small goals, the use of
polymorphic functions and dependent types may lead to an invisible
-duplication of functions arguments. These copies usually end up in
-types hidden by the implicit arguments machinery or by user defined
+duplication of function arguments. These copies usually end up in
+types hidden by the implicit arguments machinery or by user-defined
notations. In these situations computing the right occurrence numbers
is very tedious because they must be counted on the goal as printed
after setting the Printing All flag. Moreover the resulting script is
@@ -3981,7 +3984,7 @@ pattern for the redex looking at the rule used for rewriting.
The first :token:`c_pattern` is the simplest form matching any context but
selecting a specific redex and has been described in the previous
sections. We have seen so far that the possibility of selecting a
-redex using a term with holes is already a powerful mean of redex
+redex using a term with holes is already a powerful means of redex
selection. Similarly, any terms provided by the user in the more
complex forms of :token:`c_patterns`
presented in the tables above can contain
@@ -4064,7 +4067,7 @@ Contextual pattern in set and the : tactical
As already mentioned in section :ref:`abbreviations_ssr` the ``set``
tactic takes as an
argument a term in open syntax. This term is interpreted as the
-simplest for of :token:`c_pattern`. To void confusion in the grammar, open
+simplest form of :token:`c_pattern`. To avoid confusion in the grammar, open
syntax is supported only for the simplest form of patterns, while
parentheses are required around more complex patterns.
@@ -4086,17 +4089,17 @@ parentheses are required around more complex patterns.
set t := (a + _ in X in _ = X).
-Since the user may define an infix notation for ``in`` the former tactic
-may result ambiguous. The disambiguation rule implemented is to prefer
+Since the user may define an infix notation for ``in`` the result of the former
+tactic may be ambiguous. The disambiguation rule implemented is to prefer
patterns over simple terms, but to interpret a pattern with double
-parentheses as a simple term. For example the following tactic would
+parentheses as a simple term. For example, the following tactic would
capture any occurrence of the term ``a in A``.
.. coqtop:: in
set t := ((a in A)).
-Contextual pattern can also be used as arguments of the ``:`` tactical.
+Contextual patterns can also be used as arguments of the ``:`` tactical.
For example:
.. coqtop:: in
@@ -4139,7 +4142,7 @@ Contextual patterns in rewrite
Note that the right hand side of ``addn0`` is undetermined, but the
rewrite pattern specifies the redex explicitly. The right hand side
- of ``addn0`` is unified with the term identified by ``X``, ``0`` here.
+ of ``addn0`` is unified with the term identified by ``X``, here ``0``.
The following pattern does not specify a redex, since it identifies an
@@ -4269,7 +4272,7 @@ generation (see section :ref:`generation_of_equations_ssr`).
.. example::
- The following script illustrate a toy example of this feature. Let us
+ The following script illustrates a toy example of this feature. Let us
define a function adding an element at the end of a list:
.. coqtop:: reset
@@ -4283,7 +4286,7 @@ generation (see section :ref:`generation_of_equations_ssr`).
.. coqtop:: all
Variable d : Type.
- Fixpoint add_last(s : list d) (z : d) {struct s} : list d :=
+ Fixpoint add_last (s : list d) (z : d) {struct s} : list d :=
if s is cons x s' then cons x (add_last s' z) else z :: nil.
One can define an alternative, reversed, induction principle on
@@ -4296,7 +4299,7 @@ generation (see section :ref:`generation_of_equations_ssr`).
forall s : list d, P s.
Then the combination of elimination views with equation names result
- in a concise syntax for reasoning inductively using the user defined
+ in a concise syntax for reasoning inductively using the user-defined
elimination scheme.
.. coqtop:: all
@@ -4305,8 +4308,8 @@ generation (see section :ref:`generation_of_equations_ssr`).
elim/last_ind_list E : l=> [| u v]; last first.
-User provided eliminators (potentially generated with the ``Function``
-|Coq|’s command) can be combined with the type family switches described
+User-provided eliminators (potentially generated with |Coq|’s ``Function``
+command) can be combined with the type family switches described
in section :ref:`type_families_ssr`.
Consider an eliminator ``foo_ind`` of type:
@@ -4341,7 +4344,7 @@ The ``elim/`` tactic distinguishes two cases:
As explained in section :ref:`type_families_ssr`, the initial prefix of
``ei`` can be omitted.
-Here an example of a regular, but non trivial, eliminator.
+Here is an example of a regular, but nontrivial, eliminator.
.. example::
@@ -4423,7 +4426,7 @@ Here an example of a regular, but non trivial, eliminator.
``P`` should be the same as the second argument of ``plus``, in the
second argument of ``P``, but ``y`` and ``z`` do no unify.
-Here an example of a truncated eliminator:
+Here is an example of a truncated eliminator:
.. example::
@@ -4481,7 +4484,7 @@ Interpreting assumptions
~~~~~~~~~~~~~~~~~~~~~~~~
Interpreting an assumption in the context of a proof consists in
-applying it a lemma before generalizing, and/or decomposing this
+applying to it a lemma before generalizing, and/or decomposing this
assumption. For instance, with the extensive use of boolean reflection
(see section :ref:`views_and_reflection_ssr`.4), it is quite frequent
to need to decompose the logical interpretation of (the boolean
@@ -4689,7 +4692,7 @@ the bookkeeping tactical ``=>`` since this would be redundant with the
Boolean reflection
~~~~~~~~~~~~~~~~~~
-In the Calculus of Inductive Construction, there is an obvious
+In the Calculus of Inductive Constructions, there is an obvious
distinction between logical propositions and boolean values. On the
one hand, logical propositions are objects of *sort* ``Prop`` which is
the carrier of intuitionistic reasoning. Logical connectives in
@@ -5002,7 +5005,7 @@ but they also allow complex transformation, involving negations.
Note that views, being part of :token:`i_pattern`, can be used to interpret
assertions too. For example the following script asserts ``a && b`` but
-actually used its propositional interpretation.
+actually uses its propositional interpretation.
.. example::
@@ -5038,7 +5041,7 @@ applied to a goal ``top`` is interpreted in the following way:
Like assumption interpretation view hints, goal interpretation ones
-are user defined lemmas stored (see section :ref:`views_and_reflection_ssr`) in the ``Hint View``
+are user-defined lemmas stored (see section :ref:`views_and_reflection_ssr`) in the ``Hint View``
database bridging the possible gap between the type of ``term`` and the
type of the goal.
@@ -5132,7 +5135,7 @@ See the files ``ssreflect.v`` and ``ssrbool.v`` for examples.
Multiple views
~~~~~~~~~~~~~~
-The hypotheses and the goal can be interpreted applying multiple views
+The hypotheses and the goal can be interpreted by applying multiple views
in sequence. Both move and apply can be followed by an arbitrary
number of ``/term``. The main difference between the following two
tactics
@@ -5188,8 +5191,9 @@ 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 search returns
+where :token:`qualid` is the name of an open module. This command returns
the list of lemmas:
@@ -5214,7 +5218,7 @@ Note that:
+ As for regular terms, patterns can feature scope indications. For
instance, the command: ``Search _ (_ + _)%N.`` lists all the lemmas whose
- statement (conclusion or hypotheses) involve an application of the
+ statement (conclusion or hypotheses) involves an application of the
binary operation denoted by the infix ``+`` symbol in the ``N`` scope (which is
|SSR| scope for natural numbers).
+ Patterns with holes should be surrounded by parentheses.
@@ -5491,7 +5495,7 @@ prenex implicits declaration see :ref:`parametric_polymorphism_ssr`
used for such generated names.
.. [#7] More precisely, it should have a quantified inductive type with a
assumptions and m − a constructors.
-.. [#8] This is an implementation feature: there is not such obstruction
+.. [#8] This is an implementation feature: there is no such obstruction
in the metatheory
.. [#9] The current state of the proof shall be displayed by the Show
Proof command of |Coq| proof mode.
diff --git a/doc/sphinx/proof-engine/tactics.rst b/doc/sphinx/proof-engine/tactics.rst
index da34e3b55..7a45272f2 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,15 @@ specified, the default selector (see Section
tactic_invocation : toplevel_selector : tactic.
: |tactic .
-.. cmd:: Set Default Goal Selector @toplevel_selector.
-
-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.
-
-.. cmd:: Test Default Goal Selector.
+.. opt:: Default Goal Selector @toplevel_selector
-This command displays the current default selector.
+ This option controls 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 value ``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.
.. _bindingslist:
@@ -94,7 +90,7 @@ bindings_list`` where ``bindings_list`` may be of two different forms:
+ 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
+ and ``case`` (see :ref:`ltac`) 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
for the dependent products that are not bound in the conclusion of the type
@@ -122,14 +118,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
@@ -154,10 +148,11 @@ Here are some tactics that understand occurrences clauses: ``set``, ``remember``
, ``induction``, ``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
---------------------
@@ -168,11 +163,12 @@ Applying theorems
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`).
+:ref:`Conversion-rules`).
.. exn:: Not an exact proof.
.. tacv:: eexact @term.
+ :name: eexact
This tactic behaves like exact but is able to handle terms and goals with
meta-variables.
@@ -186,6 +182,7 @@ the goal. If it is the case, the subgoal is proved. Otherwise, it fails.
.. exn:: No such assumption.
.. tacv:: eassumption
+ :name: eassumption
This tactic behaves like assumption but is able to handle goals with
meta-variables.
@@ -238,6 +235,7 @@ useful to advanced users.
cast around it.
.. 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.
@@ -248,6 +246,7 @@ useful to advanced users.
resolution of typeclasses.
.. tacv:: simple notypeclasses refine @term
+ :name: simple notypeclasses refine
This tactic behaves like ``simple refine`` except it performs typechecking
without resolution of typeclasses.
@@ -277,7 +276,7 @@ gets the form :g:`(fun x => Q) u`:sub:`1` :g:`...` :g:`u`:sub:`n`.
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.
+:tacn:`change` or :tacn:`pattern` tactics.
.. exn:: Unable to find an instance for the variables {+ @ident}.
@@ -285,7 +284,7 @@ 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:
-.. 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
@@ -314,10 +313,11 @@ generated by ``apply term``:sub:`i` , starting from the application of
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
+instantiate (see :ref:`Existential-Variables`). The instantiation is
intended to be found later in the proof.
.. 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
@@ -340,11 +340,12 @@ does.
.. 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``.
.. tacv:: lapply @term
- :name: `lapply
+ :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
@@ -435,7 +436,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`).
@@ -520,8 +521,8 @@ sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
constructor of :g:`I`, then ``constructor i`` is equivalent to
``intros; apply c``:sub:`i`.
-.. exn:: Not an inductive product.
-.. exn:: Not enough constructors.
+.. exn:: Not an inductive product
+.. exn:: Not enough constructors
.. tacv:: constructor
@@ -539,34 +540,39 @@ 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
the case of an existential quantification :math:`\exists`:g:`x, P(x).`
-.. exn:: Not an inductive goal with 1 constructor.
+.. exn:: Not an inductive goal with 1 constructor
.. tacv:: exists @bindings_list
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`.
Then, they are respectively equivalent to ``constructor 1`` and
``constructor 2``.
-.. exn:: Not an inductive goal with 2 constructors.
+.. exn:: Not an inductive goal with 2 constructors
.. tacv:: left with @bindings_list
.. tacv:: right with @bindings_list
@@ -577,15 +583,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,7 +614,7 @@ 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
@@ -616,7 +632,7 @@ 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
@@ -632,14 +648,14 @@ be applied or the goal is not head-reducible.
.. 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
@@ -827,15 +843,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.
+ .. opt:: 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.
-
- 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,6 +866,7 @@ 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.
@@ -876,7 +888,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
@@ -992,6 +1004,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 +1012,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 +1030,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 +1083,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:
@@ -1089,7 +1105,7 @@ Controlling the proof flow
.. 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
@@ -1098,6 +1114,7 @@ Controlling the proof flow
generated by assert.
.. exn:: Proof is not complete
+ :name: Proof is not complete (assert)
.. tacv:: assert form as intro_pattern
@@ -1121,6 +1138,7 @@ Controlling the proof flow
.. exn:: Variable @ident is already declared
.. tacv:: eassert form as intro_pattern by tactic
+ :name: eassert
.. tacv:: assert (@ident := @term)
@@ -1130,6 +1148,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 +1162,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 +1188,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
@@ -1236,7 +1261,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 +1293,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
@@ -1353,11 +1378,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 +1450,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 +1477,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 +1487,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.
@@ -1556,6 +1586,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 +1659,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.
@@ -1635,7 +1667,7 @@ analysis on inductive or co-inductive objects (see :ref:`TODO-4.5`).
.. tacv:: elim @term using @term
.. tacv:: elim @term using @term with @bindings_list
- Allows the user to give explicitly an elimination predicate :n:`@term` that
+ Allows the user to give explicitly an induction principle :n:`@term` that
is not the standard one for the underlying inductive type of :n:`@term`. The
:n:`@bindings_list` clause allows instantiating premises of the type of
:n:`@term`.
@@ -1646,7 +1678,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 +1689,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 +1774,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 +1789,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,22 +1816,22 @@ 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
@@ -1849,6 +1884,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
@@ -1902,7 +1938,7 @@ 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`),
+equality has been declared using the command ``Scheme Equality`` (see :ref:`proofschemes-induction-principles`),
the use of a sigma type is avoided.
.. note::
@@ -1928,6 +1964,7 @@ the use of a sigma type is avoided.
.. tacv:: einjection @num
.. tacv:: einjection @term {? with @bindings_list}
+ :name: einjection
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
@@ -1955,17 +1992,19 @@ the use of a sigma type is avoided.
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
-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``.
+ 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, :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 +2023,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
@@ -2117,6 +2156,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 +2340,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 +2361,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 +2375,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
@@ -2417,6 +2457,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
@@ -2463,6 +2504,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 +2548,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
+
+ This option controls the behavior of :tacn:`subst`. When it is
+ activated, :tacn:`subst` also deals with the following corner cases:
- + 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`.
+ + 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.
+ 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,30 +2585,37 @@ 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`.
- 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.``
+ .. cmd:: 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
@@ -2637,7 +2686,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 +2698,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 +2753,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 +2763,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
@@ -2768,7 +2819,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
@@ -2906,7 +2957,7 @@ 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.
@@ -2942,7 +2993,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
@@ -3103,7 +3154,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>`
@@ -3258,188 +3309,203 @@ 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
-.. cmd:: Hint hint_definition
+ No database name is given: the hint is registered in the core database.
- No database name is given: the hint is registered in the core database.
+ .. cmdv:: Local Hint @hint_definition : {+ @ident}
-.. cmd:: 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.
- 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:: Local Hint hint_definition
+ Idem for the core database.
- Idem for the core database.
+ .. cmdv:: Hint Resolve @term {? | {? @num} {? @pattern}}
+ :name: Hint Resolve
-The ``hint_definition`` is one of the following expressions:
+ 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.
-+ :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.
+ .. exn:: @term cannot be used as a hint
- .. exn:: @term cannot be used as a hint
+ The head symbol of the type of :n:`@term` is a bound variable such that
+ this tactic cannot be associated to a constant.
- The head symbol of the type of :n:`@term` is a bound variable such that
- this tactic cannot be associated to a constant.
+ .. cmdv:: Hint Resolve {+ @term}
- **Variants:**
+ Adds each :n:`Hint Resolve @term`.
- + :n:`Resolve {+ @term}`
- Adds each :n:`Resolve @term`.
+ .. cmdv:: Hint Resolve -> @term
- + :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``).
+ 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`).
- + :n:`Resolve <- @term`
- Adds the right-to-left implication of an equivalence as a hint.
+ .. cmdv:: Resolve <- @term
-+ :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.
+ Adds the right-to-left implication of an equivalence as a hint.
- .. exn:: @term cannot be used as a hint
+ .. cmdv:: Hint Immediate @term
+ :name: Hint Immediate
- **Variants:**
+ 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 :tacn:`trivial`
+ itself.
- + :n:`Immediate {+ @term}`
- Adds each :n:`Immediate @term`.
+ .. exn:: @term cannot be used as a hint
-+ :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.
+ .. cmdv:: Immediate {+ @term}
- .. exn:: @ident is not an inductive type
+ Adds each :n:`Hint Immediate @term`.
- **Variants:**
+ .. cmdv:: Hint Constructors @ident
+ :name: Hint Constructors
- + :n:`Constructors {+ @ident}`
- Adds each :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 ...)`, :tacn:`auto` will try to apply each constructor.
-+ :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.
+ .. exn:: @ident is not an inductive type
- **Variants:**
+ .. cmdv:: Hint Constructors {+ @ident}
- + :n:`Unfold {+ @ident}`
- Adds each :n:`Unfold @ident`.
+ Adds each :n:`Hint Constructors @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 Unfold @qualid
+ :name: Hint Unfold
- **Variants:**
+ 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.
- + :n:`Transparent`, :n:`Opaque {+ @ident}`
- Declares each :n:`@ident` as a transparent or opaque constant.
+ .. cmdv:: Hint Unfold {+ @ident}
-+ :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.
+ Adds each :n:`Hint Unfold @ident`.
-.. note::
- One can use an ``Extern`` hint with no pattern to do pattern-matching on
- hypotheses using ``match goal`` with inside the tactic.
+ .. cmdv:: Hint %( Transparent %| Opaque %) @qualid
+ :name: Hint ( Transparent | Opaque )
+
+ This adds a transparency hint to the database, making :n:`@qualid` a
+ transparent or opaque constant during resolution. This information is used
+ 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}
+
+ Declares each :n:`@ident` as a transparent or opaque constant.
+
+ .. cmdv:: Hint Extern @num {? @pattern} => 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 +3587,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.
@@ -3573,69 +3639,65 @@ We propose a smooth transitional path by providing the ``Loose Hint Behavior``
option which accepts three flags allowing for a fine-grained handling of
non-imported hints.
-**Variants:**
+.. opt:: Loose Hint Behavior %( "Lax" %| "Warn" %| "Strict" %)
-.. cmd:: Set Loose Hint Behavior "Lax"
+ This option accepts three values, which control the behavior of hints w.r.t.
+ :cmd:`Import`:
- This is the default, and corresponds to the historical behavior, that
- is, hints defined outside of a section have a global scope.
+ - "Lax": this is the default, and corresponds to the historical behavior,
+ that is, hints defined outside of a section have a global scope.
-.. cmd:: Set Loose Hint Behavior "Warn"
+ - "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.
- 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.
+ - "Strict": changes the behavior of an unloaded hint to a immediate fail
+ tactic, allowing to emulate an import-scoped hint mechanism.
-.. cmd:: Set Loose Hint Behavior "Strict"
-
- 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`.
-
-**Variants:**
+ See also: ``Proof.`` in :ref:`proof-editing-mode`.
-.. cmd:: Proof with tactic using {+ @ident}
- Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`TODO-7.1.5-Proofusing`
+ .. cmdv:: Proof with tactic using {+ @ident}
-.. cmd:: Proof using {+ @ident} with tactic
+ Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`proof-editing-mode`
- Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`TODO-7.1.5-Proofusing`
+ .. cmdv:: Proof using {+ @ident} with @tactic
-.. cmd:: Declare Implicit Tactic tactic
+ Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`proof-editing-mode`
- 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.
+ .. cmd:: Declare Implicit Tactic @tactic
-Here is an example:
+ 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.
-.. 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 +3742,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 +3776,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
@@ -3730,17 +3793,10 @@ some incompatibilities.
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:
-
-.. cmd:: Unset Intuition Negation Unfolding
+.. opt:: 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 +3820,15 @@ 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
+
+ The default tactic used by :tacn:`firstorder` when no rule applies is
+ :g:`auto with *`, it can be reset locally or globally using this option and
+ printed using :cmd:`Print Firstorder Solver`.
.. 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 +3845,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 @natural
+
+ This option controls the proof-search depth bound.
.. tacn:: congruence
:name: congruence
@@ -3878,7 +3936,7 @@ succeeds, and results in an error otherwise.
.. 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
@@ -4009,6 +4067,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
@@ -4020,7 +4079,7 @@ symbol :g:`=`.
:n:`intro @ident; simplify_eq @ident`.
.. tacn:: dependent rewrite -> @ident
- :name: dependent rewrite ->
+ :name: dependent rewrite
This tactic applies to any goal. If :n:`@ident` has type
:g:`(existT B a b)=(existT B a' b')` in the local context (i.e. each
@@ -4044,7 +4103,7 @@ 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``.
@@ -4077,7 +4136,7 @@ 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
@@ -4109,6 +4168,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 +4209,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 +4229,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 +4255,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,7 +4347,7 @@ 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
@@ -4302,8 +4363,7 @@ This tactics reverses the list of the focused goals.
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 +4394,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
new file mode 100644
index 000000000..692ff294a
--- /dev/null
+++ b/doc/sphinx/proof-engine/vernacular-commands.rst
@@ -0,0 +1,1357 @@
+.. include:: ../preamble.rst
+.. include:: ../replaces.rst
+
+.. _vernacularcommands:
+
+Vernacular commands
+=============================
+
+.. _displaying:
+
+Displaying
+--------------
+
+
+.. _Print:
+
+.. cmd:: Print @qualid.
+
+This command displays on the screen information about the declared or
+defined object referred by :n:`@qualid`.
+
+
+Error messages:
+
+
+.. exn:: @qualid not a defined object
+
+.. exn:: Universe instance should have length :n:`num`.
+
+.. exn:: This object does not support universe names.
+
+
+Variants:
+
+
+.. cmdv:: Print Term @qualid.
+
+This is a synonym to ``Print`` :n:`@qualid` when :n:`@qualid`
+denotes a global constant.
+
+.. cmdv:: About @qualid.
+ :name: About
+
+This displays various information about the object
+denoted by :n:`@qualid`: its kind (module, constant, assumption, inductive,
+constructor, abbreviation, …), long name, type, implicit arguments and
+argument scopes. It does not print the body of definitions or proofs.
+
+.. cmdv:: Print @qualid\@@name
+
+This 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.
+
+This command displays information about the current state of the
+environment, including sections and modules.
+
+
+Variants:
+
+
+.. cmdv:: Inspect @num.
+ :name: Inspect
+
+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.
+
+
+.. _flags-options-tables:
+
+Flags, Options and Tables
+-----------------------------
+
+|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.
+
+Variants:
+
+.. cmdv:: Local Set @flag.
+
+This command switches :n:`@flag` on. The original state
+of :n:`@flag` is restored when the current *section* ends.
+
+.. 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.
+
+.. 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.
+
+This command switches :n:`@flag` off. The original state of :n:`@flag` is restored
+when the current module ends.
+
+
+Variants:
+
+.. cmdv:: Local Unset @flag.
+
+This command switches :n:`@flag` off. The original
+state of :n:`@flag` is restored when the current *section* ends.
+
+.. cmdv:: Global 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.
+
+.. cmdv:: Export Unset @flag.
+
+ This command switches :n:`@flag` off. The original state
+ of :n:`@flag` is restored at the end of the current module, but :n:`@flag`
+ is switched off when this module is imported.
+
+
+.. cmd:: Test @flag.
+
+This command prints whether :n:`@flag` is on or off.
+
+
+.. cmd:: Set @option @value.
+
+This command sets :n:`@option` to :n:`@value`. The original value of ` option` is
+restored when the current module ends.
+
+
+Variants:
+
+.. TODO : option and value are not syntax entries
+
+.. cmdv:: Local Set @option @value.
+
+This command sets :n:`@option` to :n:`@value`. The
+original value of :n:`@option` is restored at the end of the module.
+
+.. cmdv:: Global Set @option @value.
+
+This command sets :n:`@option` to :n:`@value`. The
+original value of :n:`@option` is *not* restored at the end of the module.
+Additionally, if set in a file, :n:`@option` is set to value when the file
+is `Require`-d.
+
+.. cmdv:: Export Set @option.
+
+ This command set :n:`@option` to :n:`@value`. The original state
+ of :n:`@option` is restored at the end of the current module, but :n:`@option`
+ is set to :n:`@value` when this module is imported.
+
+
+.. cmd:: Unset @option.
+
+ This command turns off :n:`@option`.
+
+
+Variants:
+
+
+.. cmdv:: Local Unset @option.
+
+ This command turns off :n:`@option`. The original state of :n:`@option` is restored when the current
+ *section* ends.
+
+.. cmdv:: Global Unset @option.
+
+ This command turns off :n:`@option`. The original state of :n:`@option` is *not* restored at the end of the
+ module. Additionally, if unset in a file, :n:`@option` is reset to its
+ default value when the file is `Require`-d.
+
+.. cmdv:: Export Unset @option.
+
+ This command turns off :n:`@option`. The original state of :n:`@option` is restored at the end of the
+ current module, but :n:`@option` is set to its default value when this module
+ is imported.
+
+
+.. cmd:: Test @option.
+
+This command prints the current value of :n:`@option`.
+
+
+.. TODO : table is not a syntax entry
+
+.. cmd:: Add @table @value.
+ :name: Add `table` `value`
+
+.. cmd:: Remove @table @value.
+ :name: Remove `table` `value`
+
+.. cmd:: Test @table @value.
+ :name: Test `table` `value`
+
+.. cmd:: Test @table for @value.
+ :name: Test `table` for `value`
+
+.. cmd:: Print Table @table.
+
+These are general commands for tables.
+
+.. cmd:: Print Options.
+
+This command lists all available flags, options and tables.
+
+
+Variants:
+
+
+.. cmdv:: Print Tables.
+
+This is a synonymous of ``Print Options``.
+
+
+.. _requests-to-the-environment:
+
+Requests to the environment
+-------------------------------
+
+.. 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.
+
+
+Variants:
+
+.. TODO : selector is not a syntax entry
+
+.. cmdv:: @selector: Check @term.
+
+specifies on which subgoal to perform typing
+(see Section :ref:`invocation-of-tactics`).
+
+.. TODO : convtactic is not a syntax entry
+
+.. cmd:: Eval @convtactic in @term.
+
+This command performs the specified reduction on :n:`@term`, and displays
+the resulting term with its type. The term to be reduced may depend on
+hypothesis introduced in the first subgoal (if a proof is in
+progress).
+
+
+See also: Section :ref:`performingcomputations`.
+
+
+.. cmd:: Compute @term.
+
+This command performs a call-by-value evaluation of term by using the
+bytecode-based virtual machine. It is a shortcut for ``Eval vm_compute in``
+:n:`@term`.
+
+
+See also: Section :ref:`performingcomputations`.
+
+
+.. cmd::Extraction @term.
+
+This command displays the extracted term from :n:`@term`. The extraction is
+processed according to the distinction between :g:`Set` and :g:`Prop`; that is
+to say, between logical and computational content (see Section :ref:`sorts`).
+The extracted term is displayed in OCaml syntax, where global identifiers are
+still displayed as in |Coq| terms.
+
+
+Variants:
+
+
+.. cmdv:: Recursive Extraction {+ @qualid }.
+
+Recursively extracts all
+the material needed for the extraction of the qualified identifiers.
+
+
+See also: Chapter :ref:`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.
+
+
+Variants:
+
+
+.. cmdv:: Print Opaque Dependencies @qualid.
+
+Displays the set of opaque constants :n:`@qualid` relies on in addition to
+the assumptions.
+
+.. cmdv:: Print Transparent Dependencies @qualid.
+
+Displays the set of
+transparent constants :n:`@qualid` relies on in addition to the assumptions.
+
+.. cmdv:: Print All Dependencies @qualid.
+
+Displays all assumptions and constants :n:`@qualid` relies on.
+
+
+
+.. cmd:: Search @qualid.
+
+This command displays the name and type of all objects (hypothesis of
+the current goal, theorems, axioms, etc) of the current context whose
+statement contains :n:`@qualid`. This command is useful to remind the user
+of the name of library lemmas.
+
+
+Error messages:
+
+
+.. exn:: The reference @qualid was not found in the current environment
+
+There is no constant in the environment named qualid.
+
+Variants:
+
+.. 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`.
+
+.. cmdv:: Search @string%@key.
+
+The string string must be a notation or the main
+symbol of a notation which is then interpreted in the scope bound to
+the delimiting key :n:`@key` (see Section :ref:`LocalInterpretationRulesForNotations`).
+
+.. cmdv:: Search @term_pattern.
+
+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 }.
+
+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.
+
+.. cmdv:: Search @term_pattern_string … @term_pattern_string inside {+ @qualid } .
+
+This restricts the search to constructions defined in the modules named by the given :n:`qualid` sequence.
+
+.. cmdv:: Search @term_pattern_string … @term_pattern_string outside {+ @qualid }.
+
+This restricts the search to constructions not defined in the modules named by the given :n:`qualid` sequence.
+
+.. cmdv:: @selector: Search [-]@term_pattern_string … [-]@term_pattern_string.
+
+This specifies the goal on which to search hypothesis (see
+Section :ref:`invocation-of-tactics`).
+By default the 1st goal is searched. This variant can
+be combined with other variants presented here.
+
+
+.. coqtop:: in
+
+ Require Import ZArith.
+
+.. coqtop:: all
+
+ Search Z.mul Z.add "distr".
+
+ Search "+"%Z "*"%Z "distr" -positive -Prop.
+
+ Search (?x * _ + ?x * _)%Z outside OmegaLemmas.
+
+.. 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.
+
+
+.. cmd:: SearchHead @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 has the form `(term t1 .. tn)`. This command is
+useful to remind the user of the name of library lemmas.
+
+
+
+.. coqtop:: reset all
+
+ SearchHead le.
+
+ SearchHead (@eq bool).
+
+
+Variants:
+
+.. cmdv:: SearchHead @term inside {+ @qualid }.
+
+This restricts the search to constructions defined in the modules named by the given :n:`qualid` sequence.
+
+.. cmdv:: SearchHead term outside {+ @qualid }.
+
+This restricts the search to constructions not defined in the modules named by the given :n:`qualid` sequence.
+
+Error messages:
+
+.. exn:: Module/section @qualid not found
+
+No module :n:`@qualid` has been required
+(see Section :ref:`compiled-files`).
+
+.. cmdv:: @selector: SearchHead @term.
+
+This specifies the goal on which to
+search hypothesis (see Section :ref:`invocation-of-tactics`).
+By default the 1st goal is
+searched. This variant can be combined with other variants presented
+here.
+
+.. note:: Up to |Coq| version 8.4, ``SearchHead`` was named ``Search``.
+
+
+.. cmd:: SearchPattern @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 or last hypothesis and conclusion matches the
+expressionterm where holes in the latter are denoted by `_`.
+It is a
+variant of Search @term_pattern that does not look for subterms but
+searches for statements whose conclusion has exactly the expected
+form, or whose statement finishes by the given series of
+hypothesis/conclusion.
+
+.. coqtop:: in
+
+ Require Import Arith.
+
+.. coqtop:: all
+
+ SearchPattern (_ + _ = _ + _).
+
+ SearchPattern (nat -> bool).
+
+ SearchPattern (forall l : list _, _ l l).
+
+Patterns need not be linear: you can express that the same expression
+must occur in two places by using pattern variables `?ident`.
+
+
+.. coqtop:: all
+
+ SearchPattern (?X1 + _ = _ + ?X1).
+
+Variants:
+
+
+.. cmdv:: SearchPattern @term inside {+ @qualid } .
+
+This restricts the search to constructions defined in the modules named by the given :n:`qualid` sequence.
+
+.. cmdv:: SearchPattern @term outside {+ @qualid }.
+
+This restricts the search to constructions not defined in the modules named by the given :n:`qualid` sequence.
+
+.. cmdv:: @selector: SearchPattern @term.
+
+This specifies the goal on which to
+search hypothesis (see Section :ref:`invocation-of-tactics`). By default the 1st goal is
+searched. This variant can be combined with other variants presented
+here.
+
+
+
+.. 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:`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:: Locate @qualid.
+
+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.
+
+.. coqtop:: none
+
+ Set Printing Depth 50.
+
+.. coqtop:: all
+
+ Locate nat.
+
+ Locate Datatypes.O.
+
+ Locate Init.Datatypes.O.
+
+ Locate Coq.Init.Datatypes.O.
+
+ Locate I.Dont.Exist.
+
+Variants:
+
+
+.. cmdv:: Locate Term @qualid.
+
+As Locate but restricted to terms.
+
+.. cmdv:: Locate Module @qualid.
+
+As Locate but restricted to modules.
+
+.. cmdv:: Locate Ltac @qualid.
+
+As Locate but restricted to tactics.
+
+
+See also: Section :ref:`locating-notations`
+
+
+.. _loading-files:
+
+Loading files
+-----------------
+
+|Coq| offers the possibility of loading different parts of a whole
+development stored in separate files. Their contents will be loaded as
+if they were entered from the keyboard. This means that the loaded
+files are ASCII files containing sequences of commands for |Coq|’s
+toplevel. This kind of file is called a *script* for |Coq|. The standard
+(and default) extension of |Coq|’s script files is .v.
+
+
+.. cmd:: Load @ident.
+
+This command loads the file named :n:`ident`.v, searching successively in
+each of the directories specified in the *loadpath*. (see Section
+:ref:`libraries-and-filesystem`)
+
+Files loaded this way cannot leave proofs open, and the ``Load``
+command cannot be used inside a proof either.
+
+Variants:
+
+
+.. cmdv:: Load @string.
+
+Loads the file denoted by the string :n:`@string`, where
+string is any complete filename. Then the `~` and .. abbreviations are
+allowed as well as shell variables. If no extension is specified, |Coq|
+will use the default extension ``.v``.
+
+.. cmdv:: Load Verbose @ident.
+
+.. cmdv:: Load Verbose @string.
+
+Display, while loading,
+the answers of |Coq| to each command (including tactics) contained in
+the loaded file See also: Section :ref:`controlling-display`.
+
+Error messages:
+
+.. exn:: Can’t find file @ident on loadpath
+
+.. exn:: Load is not supported inside proofs
+
+.. exn:: Files processed by Load cannot leave open proofs
+
+.. _compiled-files:
+
+Compiled files
+------------------
+
+This section describes the commands used to load compiled files (see
+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.
+
+This command looks in the loadpath for a file containing module :n:`@qualid`
+and adds the corresponding module to the environment of |Coq|. As
+library files have dependencies in other library files, the command
+``Require`` :n:`@qualid` recursively requires all library files the module
+qualid depends on and adds the corresponding modules to the
+environment of |Coq| too. |Coq| assumes that the compiled files have been
+produced by a valid |Coq| compiler and their contents are then not
+replayed nor rechecked.
+
+To locate the file in the file system, :n:`@qualid` is decomposed under the
+form `dirpath.ident` and the file `ident.vo` is searched in the physical
+directory of the file system that is mapped in |Coq| loadpath to the
+logical path dirpath (see Section :ref:`libraries-and-filesystem`). The mapping between
+physical directories and logical names at the time of requiring the
+file must be consistent with the mapping used to compile the file. If
+several files match, one of them is picked in an unspecified fashion.
+
+
+Variants:
+
+.. cmdv:: Require Import @qualid.
+
+This loads and declares the module :n:`@qualid`
+and its dependencies then imports the contents of :n:`@qualid` as described
+:ref:`here <import_qualid>`. It does not import the modules on which
+qualid depends unless these modules were themselves required in module
+:n:`@qualid`
+using ``Require Export``, as described below, or recursively required
+through a sequence of ``Require Export``. If the module required has
+already been loaded, ``Require Import`` :n:`@qualid` simply imports it, as ``Import``
+:n:`@qualid` would.
+
+.. cmdv:: Require Export @qualid.
+
+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 }.
+
+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.
+
+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.
+
+
+
+Error messages:
+
+.. 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`).
+
+.. exn:: Compiled library @ident.vo makes inconsistent assumptions over library qualid
+
+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:: 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:: The file `ident.vo` contains library dirpath and not library dirpath’
+
+The library file `dirpath’` is indirectly required by the
+``Require`` command but it is bound in the current loadpath to the
+file `ident.vo` which was bound to a different library name `dirpath` at
+the time it was compiled.
+
+
+.. exn:: Require is not allowed inside a module or a module type
+
+This command
+is not allowed inside a module or a module type being defined. It is
+meant to describe a dependency between compilation units. Note however
+that the commands ``Import`` and ``Export`` alone can be used inside modules
+(see Section :ref:`Import <import_qualid>`).
+
+
+
+See also: Chapter :ref:`thecoqcommands`
+
+
+.. cmd:: Print Libraries.
+
+This command displays the list of library files loaded in the
+current |Coq| session. For each of these libraries, it also tells if it
+is imported.
+
+
+.. cmd:: Declare ML Module {+ @string } .
+
+This commands loads the OCaml compiled files
+with names given by the :n:`@string` sequence
+(dynamic link). It is mainly used to load tactics dynamically. The
+files are searched into the current OCaml loadpath (see the
+command ``Add ML Path`` in Section :ref:`libraries-and-filesystem`). Loading of OCaml files is only possible under the bytecode version of ``coqtop`` (i.e.
+``coqtop`` called with option ``-byte``, see chapter :ref:`thecoqcommands`), or when |Coq| has been compiled with a
+version of OCaml that supports native Dynlink (≥ 3.11).
+
+
+Variants:
+
+
+.. 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 :ref:`here <locate-file>`)
+
+
+.. _loadpath:
+
+Loadpath
+------------
+
+Loadpaths are preferably managed using |Coq| command line options (see
+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.
+
+Is equivalent to Pwd.
+
+
+
+.. cmd:: Add LoadPath @string as @dirpath.
+
+This command is equivalent to the command line option
+``-Q`` :n:`@string` :n:`@dirpath`. It adds the physical directory string to the current
+|Coq| loadpath and maps it to the logical directory dirpath.
+
+Variants:
+
+
+.. 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.
+
+Variants:
+
+
+.. cmdv:: Add Rec LoadPath @string.
+
+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:: Print LoadPath.
+
+This command displays the current |Coq| loadpath.
+
+
+Variants:
+
+
+.. cmdv:: Print LoadPath @dirpath.
+
+Works as ``Print LoadPath`` but displays only
+the paths that extend the :n:`@dirpath` prefix.
+
+
+.. 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`).
+
+
+.. cmd:: Add Rec ML Path @string.
+
+This command adds the directory :n:`@string` and all its subdirectories to
+the current OCaml loadpath (see the command ``Declare ML Module``
+in Section :ref:`compiled-files`).
+
+
+.. 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`).
+
+.. _locate-file:
+
+.. 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`.
+
+
+.. _backtracking:
+
+Backtracking
+----------------
+
+The backtracking commands described in this section can only be used
+interactively, they cannot be part of a vernacular file loaded via
+``Load`` or compiled by ``coqc``.
+
+
+.. cmd:: Reset @ident.
+
+This command removes all the objects in the environment since :n:`@ident`
+was introduced, including :n:`@ident`. :n:`@ident` may be the name of a defined or
+declared object as well as the name of a section. One cannot reset
+over the name of a module or of an object inside a module.
+
+
+Error messages:
+
+.. exn:: @ident: no such entry
+
+Variants:
+
+.. cmd:: Reset Initial.
+
+Goes back to the initial state, just after the start
+of the interactive session.
+
+
+
+.. cmd:: Back.
+
+This commands undoes all the effects of the last vernacular command.
+Commands read from a vernacular file via a ``Load`` are considered as a
+single command. Proof management commands are also handled by this
+command (see Chapter :ref:`proofhandling`). For that, Back may have to undo more than
+one command in order to reach a state where the proof management
+information is available. For instance, when the last command is a
+``Qed``, the management information about the closed proof has been
+discarded. In this case, ``Back`` will then undo all the proof steps up to
+the statement of this proof.
+
+
+Variants:
+
+
+.. cmdv:: Back @num.
+
+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.
+
+
+
+Error messages:
+
+
+.. exn:: Invalid backtrack
+
+The user wants to undo more commands than available in the history.
+
+.. cmd:: BackTo @num.
+
+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.
+
+
+Variants:
+
+
+.. cmdv:: Backtrack @num @num @num.
+
+`Backtrack` is a *deprecated* form of
+`BackTo` which allows explicitly manipulating the proof environment. The
+three numbers represent the following:
+
+ + *first number* : State label to reach, as for BackTo.
+ + *second number* : *Proof state number* to unbury once aborts have been done.
+ |Coq| will compute the number of Undo to perform (see Chapter :ref:`proofhandling`).
+ + *third number* : Number of Abort to perform, i.e. the number of currently
+ opened nested proofs that must be canceled (see Chapter :ref:`proofhandling`).
+
+
+
+
+Error messages:
+
+
+.. exn:: Invalid backtrack
+
+
+The destination state label is unknown.
+
+
+.. _quitting-and-debugging:
+
+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:
+
+
+::
+
+ #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();;
+
+.. warning::
+
+ #. It only works with the bytecode version of |Coq| (i.e. `coqtop.byte`,
+ see Section `interactive-use`).
+ #. You must have compiled |Coq| from the source package and set the
+ environment variable COQTOP to the root of your copy of the sources
+ (see Section `customization-by-environment-variables`).
+
+
+
+.. TODO : command is not a syntax entry
+
+.. cmd:: Time @command.
+
+This command executes the vernacular command :n:`@command` and displays the
+time needed to execute it.
+
+
+.. cmd:: Redirect @string @command.
+
+This command executes the vernacular command :n:`@command`, redirecting its
+output to ":n:`@string`.out".
+
+
+.. cmd:: Timeout @num @command.
+
+This command executes the vernacular command :n:`@command`. If the command
+has not terminated after the time specified by the :n:`@num` (time
+expressed in seconds), then it is interrupted and an error message is
+displayed.
+
+
+.. 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:: 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
+
+ This option controls the normal displaying.
+
+.. opt:: Warnings "{+, {? %( - %| + %) } @ident }"
+
+ 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`.
+
+.. 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.
+
+.. opt:: Printing Width @integer
+
+ This command sets which left-aligned part of the width of the screen is used
+ for display. At the time of writing this documentation, the default value
+ is 78.
+
+.. opt:: Printing Depth @integer
+
+ 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.
+
+.. 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.
+
+.. opt:: Printing Unfocused
+
+ 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
+
+ This option controls the printing of the “(dependent evars: …)” line when
+ ``-emacs`` is passed.
+
+
+.. _vernac-controlling-the-reduction-strategies:
+
+Controlling the reduction strategies and the conversion algorithm
+----------------------------------------------------------------------
+
+
+|Coq| provides reduction strategies that the tactics can invoke and two
+different algorithms to check the convertibility of types. The first
+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 :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:`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:`performingcomputations`, :ref:`tactics-automatizing`, :ref:`proof-editing-mode`
+
+
+Error messages:
+
+
+.. exn:: The reference @qualid was not found in the current environment
+
+There is no constant referred by :n:`@qualid` in the environment.
+Nevertheless, if you asked ``Opaque`` `foo` `bar` and if `bar` does not exist, `foo` is set opaque.
+
+.. cmd:: Transparent {+ @qualid }.
+
+This command is the converse of `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.
+
+The scope of Transparent is limited to the current section, or current
+file, unless the variant ``Global Transparent`` is
+used.
+
+
+Error messages:
+
+
+.. exn:: The reference @qualid was not found in the current environment
+
+There is no constant referred by :n:`@qualid` in the environment.
+
+
+
+See also: sections :ref:`performingcomputations`, :ref:`tactics-automatizing`, :ref:`proof-editing-mode`
+
+.. _vernac-strategy:
+
+.. 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.
+
+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).
+ + :n:`@num` : levels indexed by an integer. Level 0 corresponds to the
+ default behavior, which corresponds to transparent constants. This
+ level can also be referred to as transparent. Negative levels
+ correspond to constants to be expanded before normal transparent
+ constants, while positive levels correspond to constants to be
+ expanded after normal transparent constants.
+ + ``expand`` : level of constants that should be expanded first (behaves
+ like −∞)
+
+
+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.
+
+
+
+Variants:
+
+
+.. 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`.
+
+
+See also: sections :ref:`performingcomputations`
+
+
+.. _controlling-locality-of-commands:
+
+Controlling the locality of commands
+-----------------------------------------
+
+
+.. 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:
+
+
++ Commands whose default is to extend their effect both outside the
+ section and the module or library file they occur in. For these
+ commands, the Local modifier limits the effect of the command to the
+ current section or module it occurs in. As an example, the ``Coercion``
+ (see Section :ref:`coercions`) and ``Strategy`` (see :ref:`here <vernac-strategy>`)
+ commands belong to this category.
++ Commands whose default behavior is to stop their effect at the end
+ of the section they occur in but to extent their effect outside the module or
+ library file they occur in. For these commands, the Local modifier limits the
+ effect of the command to the current module if the command does not occur in a
+ section and the Global modifier extends the effect outside the current
+ sections and current module if the command occurs in a section. As an example,
+ the :cmd:`Implicit Arguments`, :cmd:`Ltac` or :cmd:`Notation` commands belong
+ 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
+ modifier extends their effect outside the sections and modules they
+ occurs in. The ``Transparent`` and ``Opaque`` (see Section :ref:`vernac-controlling-the-reduction-strategies`) commands belong to this category.
++ 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
+ category.
diff --git a/doc/sphinx/replaces.rst b/doc/sphinx/replaces.rst
index d4f6835ef..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}`
@@ -64,6 +66,14 @@
.. |t_i| replace:: `t`\ :math:`_{i}`
.. |t_m| replace:: `t`\ :math:`_{m}`
.. |t_n| replace:: `t`\ :math:`_{n}`
+.. |f_1| replace:: `f`\ :math:`_{1}`
+.. |f_i| replace:: `f`\ :math:`_{i}`
+.. |f_m| replace:: `f`\ :math:`_{m}`
+.. |f_n| replace:: `f`\ :math:`_{n}`
+.. |u_1| replace:: `u`\ :math:`_{1}`
+.. |u_i| replace:: `u`\ :math:`_{i}`
+.. |u_m| replace:: `u`\ :math:`_{m}`
+.. |u_n| replace:: `u`\ :math:`_{n}`
.. |term_0| replace:: `term`\ :math:`_{0}`
.. |term_1| replace:: `term`\ :math:`_{1}`
.. |term_2| replace:: `term`\ :math:`_{2}`
diff --git a/doc/sphinx/user-extensions/proof-schemes.rst b/doc/sphinx/user-extensions/proof-schemes.rst
index 583b73e53..e12e4d897 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,17 @@ 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
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 +103,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 +143,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 +173,8 @@ concluded by the conjunction of their conclusions.
Check tree_forest_mutind.
+.. _functional-scheme:
+
Generation of induction principles with ``Functional`` ``Scheme``
-----------------------------------------------------------------
@@ -172,7 +184,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 +241,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 +317,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 +334,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..c4a7121ce 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.
@@ -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.
-
- .. coqtop:: all
+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.
- 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}
@@ -955,7 +959,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 +1129,8 @@ Displaying informations about scopes
class of all the existing interpretation scopes. It also displays the
lonely notations.
+.. _Abbreviations:
+
Abbreviations
--------------
@@ -1187,6 +1193,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 +1202,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 +1213,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..f09ed4b55 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"
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 5176c51d2..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_]+;
+METACHAR: '%' [|(){}];
+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 ffa774b9b..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*+~~\6\2\"\"BB}}\177\177")
- buf.write("\6\2\62;C\\aac|\2\61\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2")
- buf.write("\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\3")
- buf.write("\21\3\2\2\2\5\24\3\2\2\2\7\26\3\2\2\2\t\30\3\2\2\2\13")
- buf.write("!\3\2\2\2\r#\3\2\2\2\17*\3\2\2\2\21\22\7}\2\2\22\23\t")
- buf.write("\2\2\2\23\4\3\2\2\2\24\25\7}\2\2\25\6\3\2\2\2\26\27\7")
- buf.write("\177\2\2\27\b\3\2\2\2\30\31\7\'\2\2\31\32\t\3\2\2\32\n")
- buf.write("\3\2\2\2\33\"\7B\2\2\34\36\n\4\2\2\35\34\3\2\2\2\36\37")
- buf.write("\3\2\2\2\37\35\3\2\2\2\37 \3\2\2\2 \"\3\2\2\2!\33\3\2")
- buf.write("\2\2!\35\3\2\2\2\"\f\3\2\2\2#%\7B\2\2$&\t\5\2\2%$\3\2")
- buf.write("\2\2&\'\3\2\2\2\'%\3\2\2\2\'(\3\2\2\2(\16\3\2\2\2)+\7")
- buf.write("\"\2\2*)\3\2\2\2+,\3\2\2\2,*\3\2\2\2,-\3\2\2\2-\20\3\2")
- buf.write("\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 44212d788..87a41cf9f 100644
--- a/doc/tools/coqrst/notations/html.py
+++ b/doc/tools/coqrst/notations/html.py
@@ -41,9 +41,16 @@ 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):
- tags.span(ctx.METACHAR().getText()[1:], _class="meta")
+ txt = ctx.METACHAR().getText()[1:]
+ if (txt == "{") or (txt == "}"):
+ tags.span(txt)
+ else:
+ tags.span(txt, _class="meta")
def visitWhitespace(self, ctx:TacticNotationsParser.WhitespaceContext):
tags.span(" ") # TODO: no need for a <span> here
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/engine/eConstr.ml b/engine/eConstr.ml
index bd47a04f1..a72bdee12 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 _
@@ -743,7 +618,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 +776,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 +795,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 +807,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..9a5b5ec3a 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
@@ -287,6 +290,7 @@ val is_global : Evd.evar_map -> Globnames.global_reference -> 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/evarutil.ml b/engine/evarutil.ml
index 45760c6b4..065b42bf6 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
@@ -414,7 +416,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 +425,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
@@ -513,7 +512,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 *)
@@ -549,7 +548,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 +559,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,7 +585,8 @@ 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)
+ 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) ->
raise (ClearDependencyError (Id.Map.find rid rids,err)) in
@@ -597,7 +597,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 +643,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 +656,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 +729,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 +781,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 +795,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 +850,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..40c1ee082 100644
--- a/engine/evarutil.mli
+++ b/engine/evarutil.mli
@@ -201,7 +201,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
diff --git a/engine/evd.ml b/engine/evd.ml
index f6e13e1f4..6dcec2760 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,98 @@ 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 rec to_constr c = match Constr.kind c with
+ | Evar ev ->
+ begin match safe_evar_value sigma ev with
+ | Some c -> to_constr c
+ | None ->
+ if abort_on_undefined_evars then
+ anomaly ~label:"econstr" Pp.(str "grounding a non evar-free term")
+ else
+ Constr.map (fun c -> to_constr c) c
+ end
+ | Sort (Sorts.Type u) ->
+ let u' = normalize_universe sigma u in
+ if u' == u then c else mkSort (Sorts.sort_of_univ u')
+ | Const (c', u) when not (Univ.Instance.is_empty u) ->
+ let u' = normalize_universe_instance sigma u in
+ if u' == u then c else mkConstU (c', u')
+ | Ind (i, u) when not (Univ.Instance.is_empty u) ->
+ let u' = normalize_universe_instance sigma u in
+ if u' == u then c else mkIndU (i, u')
+ | Construct (co, u) when not (Univ.Instance.is_empty u) ->
+ let u' = normalize_universe_instance sigma u in
+ if u' == u then c else mkConstructU (co, u')
+ | _ -> Constr.map (fun c -> to_constr c) c
+ in to_constr c
+
+ let 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..5ce16459c 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 -> Globnames.global_reference -> 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 22271dd02..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));
@@ -710,13 +710,19 @@ let partition_unifiable sigma l =
(** Shelves the unifiable goals under focus, i.e. the goals which
appear in other goals under focus (the unfocused goals are not
considered). *)
-let shelve_unifiable =
+let shelve_unifiable_informative =
let open Proof in
Pv.get >>= fun initial ->
let (u,n) = partition_unifiable initial.solution initial.comb in
Comb.set n >>
InfoL.leaf (Info.Tactic (fun () -> Pp.str"shelve_unifiable")) >>
- Shelf.modify (fun gls -> gls @ CList.map drop_state u)
+ let u = CList.map drop_state u in
+ Shelf.modify (fun gls -> gls @ u) >>
+ tclUNIT u
+
+let shelve_unifiable =
+ let open Proof in
+ shelve_unifiable_informative >>= fun _ -> tclUNIT ()
(** [guard_no_unifiable] returns the list of unifiable goals if some
goals are unifiable (see {!shelve_unifiable}) in the current focus. *)
@@ -869,8 +875,7 @@ module Progress = struct
(** equality function on hypothesis contexts *)
let eq_named_context_val sigma1 sigma2 ctx1 ctx2 =
- let open Environ in
- let c1 = named_context_of_val ctx1 and c2 = named_context_of_val ctx2 in
+ let c1 = EConstr.named_context_of_val ctx1 and c2 = EConstr.named_context_of_val ctx2 in
let eq_named_declaration d1 d2 =
match d1, d2 with
| LocalAssum (i1,t1), LocalAssum (i2,t2) ->
@@ -1035,6 +1040,8 @@ module Unsafe = struct
let advance = Evarutil.advance
+ let undefined = undefined
+
let mark_as_unresolvable p gl =
{ p with solution = mark_in_evm ~goal:false p.solution gl }
@@ -1093,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/proofview.mli b/engine/proofview.mli
index e7be66552..1905686fe 100644
--- a/engine/proofview.mli
+++ b/engine/proofview.mli
@@ -326,6 +326,9 @@ val unifiable : Evd.evar_map -> Evar.t -> Evar.t list -> bool
considered). *)
val shelve_unifiable : unit tactic
+(** Idem but also returns the list of shelved variables *)
+val shelve_unifiable_informative : Evar.t list tactic
+
(** [guard_no_unifiable] returns the list of unifiable goals if some
goals are unifiable (see {!shelve_unifiable}) in the current focus. *)
val guard_no_unifiable : Names.Name.t list option tactic
@@ -466,6 +469,12 @@ module Unsafe : sig
solved. *)
val advance : Evd.evar_map -> Evar.t -> Evar.t option
+ (** [undefined sigma l] applies [advance] to the goals of [l], then
+ returns the subset of resulting goals which have not yet been
+ defined *)
+ val undefined : Evd.evar_map -> Proofview_monad.goal_with_state list ->
+ Proofview_monad.goal_with_state list
+
val typeclass_resolvable : unit Evd.Store.field
end
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/ide/MacOS/relatify_with-respect-to_.sh b/ide/MacOS/relatify_with-respect-to_.sh
deleted file mode 100755
index a24af9395..000000000
--- a/ide/MacOS/relatify_with-respect-to_.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-set -e
-
-for i in "$3/"*.dylib
-do install_name_tool -change "$2"/$(basename $i) @executable_path/../Resources/lib/$(basename $i) "$1"
-done
-case "$1" in
- *.dylib)
- install_name_tool -id @executable_path/../Resources/lib/$(basename $1) $1
- for i in "$3"/*.dylib
- do install_name_tool -change "$2/"$(basename $1) @executable_path/../Resources/lib/$(basename $1) $i
- done;;
- *)
-esac
diff --git a/ide/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 2e552b60b..c66d69c03 100644
--- a/ide/ide_slave.ml
+++ b/ide/ide_slave.ml
@@ -511,7 +511,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.ml b/interp/constrextern.ml
index 19444988b..7792eff66 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -14,7 +14,6 @@ open CErrors
open Util
open Names
open Nameops
-open Constr
open Termops
open Libnames
open Globnames
@@ -479,7 +478,8 @@ and extern_notation_pattern (tmp_scope,scopes as allscopes) vars t = function
if is_inactive_rule keyrule then raise No_match;
let loc = t.loc in
match DAst.get t with
- | PatCstr (cstr,_,na) ->
+ | PatCstr (cstr,args,na) ->
+ let t = if na = Anonymous then t else DAst.make ?loc (PatCstr (cstr,args,Anonymous)) in
let p = apply_notation_to_pattern ?loc (ConstructRef cstr)
(match_notation_constr_cases_pattern t pat) allscopes vars keyrule in
insert_pat_alias ?loc p na
@@ -590,11 +590,17 @@ let explicitize inctx impl (cf,f) args =
let expl () =
match ip with
| Some i ->
- if not (List.is_empty impl) && is_status_implicit (List.nth impl (i-1)) then
- raise Expl
+ (* Careful: It is possible to have declared implicits ending
+ before the principal argument *)
+ let is_impl =
+ try is_status_implicit (List.nth impl (i-1))
+ with Failure _ -> false
+ in
+ if is_impl
+ then raise Expl
else
let (args1,args2) = List.chop i args in
- let (impl1,impl2) = if List.is_empty impl then [],[] else List.chop i impl in
+ let (impl1,impl2) = try List.chop i impl with Failure _ -> impl, [] in
let args1 = exprec 1 (args1,impl1) in
let args2 = exprec (i+1) (args2,impl2) in
let ip = Some (List.length args1) in
@@ -1223,8 +1229,36 @@ let rec glob_of_pat avoid env sigma pat = DAst.make @@ match pat with
| _ -> anomaly (Pp.str "PCase with non-trivial predicate but unknown inductive.")
in
GCases (RegularStyle,rtn,[glob_of_pat avoid env sigma tm,indnames],mat)
- | PFix f -> DAst.get (Detyping.detype_names false avoid env (Global.env()) sigma (EConstr.of_constr (mkFix f))) (** FIXME bad env *)
- | PCoFix c -> DAst.get (Detyping.detype_names false avoid env (Global.env()) sigma (EConstr.of_constr (mkCoFix c)))
+ | PFix ((ln,i),(lna,tl,bl)) ->
+ let def_avoid, def_env, lfi =
+ Array.fold_left
+ (fun (avoid, env, l) na ->
+ let id = Namegen.next_name_away na avoid in
+ (Id.Set.add id avoid, Name id :: env, id::l))
+ (avoid, env, []) lna in
+ let n = Array.length tl in
+ let v = Array.map3
+ (fun c t i -> Detyping.share_pattern_names glob_of_pat (i+1) [] def_avoid def_env sigma c (Patternops.lift_pattern n t))
+ bl tl ln in
+ GRec(GFix (Array.map (fun i -> Some i, GStructRec) ln,i),Array.of_list (List.rev lfi),
+ Array.map (fun (bl,_,_) -> bl) v,
+ Array.map (fun (_,_,ty) -> ty) v,
+ Array.map (fun (_,bd,_) -> bd) v)
+ | PCoFix (ln,(lna,tl,bl)) ->
+ let def_avoid, def_env, lfi =
+ Array.fold_left
+ (fun (avoid, env, l) na ->
+ let id = Namegen.next_name_away na avoid in
+ (Id.Set.add id avoid, Name id :: env, id::l))
+ (avoid, env, []) lna in
+ let ntys = Array.length tl in
+ let v = Array.map2
+ (fun c t -> share_pattern_names glob_of_pat 0 [] def_avoid def_env sigma c (Patternops.lift_pattern ntys t))
+ bl tl in
+ GRec(GCoFix ln,Array.of_list (List.rev lfi),
+ Array.map (fun (bl,_,_) -> bl) v,
+ Array.map (fun (_,_,ty) -> ty) v,
+ Array.map (fun (_,bd,_) -> bd) v)
| PSort s -> GSort s
let extern_constr_pattern env sigma pat =
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index f2cd07c94..7eda89f4e 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")
diff --git a/interp/impargs.ml b/interp/impargs.ml
index 9ad62c0de..b424f73de 100644
--- a/interp/impargs.ml
+++ b/interp/impargs.ml
@@ -139,7 +139,7 @@ let argument_less = function
| Hyp _, Conclusion -> true
| Conclusion, _ -> false
-let update pos rig (na,st) =
+let update pos rig st =
let e =
if rig then
match st with
@@ -163,7 +163,7 @@ let update pos rig (na,st) =
| Some (DepFlex fpos as x) ->
if argument_less (pos,fpos) then DepFlex pos else x
| Some Manual -> assert false
- in na, Some e
+ in Some e
(* modified is_rigid_reference with a truncated env *)
let is_flexible_reference env sigma bound depth f =
@@ -214,6 +214,8 @@ let add_free_rels_until strict strongly_strict revpat bound env sigma m pos acc
let () = if not (Vars.noccur_between sigma 1 bound m) then frec true (env,1) m in
acc
+(* compute the list of implicit arguments *)
+
let rec is_rigid_head sigma t = match kind sigma t with
| Rel _ | Evar _ -> false
| Ind _ | Const _ | Var _ | Sort _ -> true
@@ -226,7 +228,14 @@ let rec is_rigid_head sigma t = match kind sigma t with
| Lambda _ | LetIn _ | Construct _ | CoFix _ | Fix _
| Prod _ | Meta _ | Cast _ -> assert false
-(* calcule la liste des arguments implicites *)
+let is_rigid env sigma t =
+ let open Context.Rel.Declaration in
+ let t = whd_all env sigma t in
+ match kind sigma t with
+ | Prod (na,a,b) ->
+ let (_,t) = splay_prod (push_rel (LocalAssum (na,a)) env) sigma b in
+ is_rigid_head sigma t
+ | _ -> true
let find_displayed_name_in all avoid na (env, b) =
let envnames_b = (env, b) in
@@ -234,43 +243,54 @@ let find_displayed_name_in all avoid na (env, b) =
if all then compute_and_force_displayed_name_in Evd.empty flag avoid na b
else compute_displayed_name_in Evd.empty flag avoid na b
-let compute_implicits_gen strict strongly_strict revpat contextual all env sigma (t : EConstr.t) =
- let rigid = ref true in
+let compute_implicits_names_gen all env sigma t =
+ let open Context.Rel.Declaration in
+ let rec aux env avoid names t =
+ let t = whd_all env sigma t in
+ match kind sigma t with
+ | Prod (na,a,b) ->
+ let na',avoid' = find_displayed_name_in all avoid na (names,b) in
+ aux (push_rel (LocalAssum (na,a)) env) avoid' (na'::names) b
+ | _ -> List.rev names
+ in aux env Id.Set.empty [] t
+
+let compute_implicits_names = compute_implicits_names_gen true
+
+let compute_implicits_explanation_gen strict strongly_strict revpat contextual env sigma t =
let open Context.Rel.Declaration in
- let rec aux env avoid n names (t : EConstr.t) =
+ let rec aux env n t =
let t = whd_all env sigma t in
match kind sigma t with
- | Prod (na,a,b) ->
- let na',avoid' = find_displayed_name_in all avoid na (names,b) in
- add_free_rels_until strict strongly_strict revpat n env sigma a (Hyp (n+1))
- (aux (push_rel (LocalAssum (na',a)) env) avoid' (n+1) (na'::names) b)
- | _ ->
- rigid := is_rigid_head sigma t;
- let names = List.rev names in
- let v = Array.map (fun na -> na,None) (Array.of_list names) in
- if contextual then
- add_free_rels_until strict strongly_strict revpat n env sigma t Conclusion v
- else v
+ | Prod (na,a,b) ->
+ add_free_rels_until strict strongly_strict revpat n env sigma a (Hyp (n+1))
+ (aux (push_rel (LocalAssum (na,a)) env) (n+1) b)
+ | _ ->
+ let v = Array.make n None in
+ if contextual then
+ add_free_rels_until strict strongly_strict revpat n env sigma t Conclusion v
+ else v
in
match kind sigma (whd_all env sigma t) with
- | Prod (na,a,b) ->
- let na',avoid = find_displayed_name_in all Id.Set.empty na ([],b) in
- let v = aux (push_rel (LocalAssum (na',a)) env) avoid 1 [na'] b in
- !rigid, Array.to_list v
- | _ -> true, []
+ | Prod (na,a,b) ->
+ let v = aux (push_rel (LocalAssum (na,a)) env) 1 b in
+ Array.to_list v
+ | _ -> []
-let compute_implicits_flags env sigma f all t =
- compute_implicits_gen
+let compute_implicits_explanation_flags env sigma f t =
+ compute_implicits_explanation_gen
(f.strict || f.strongly_strict) f.strongly_strict
- f.reversible_pattern f.contextual all env sigma t
+ f.reversible_pattern f.contextual env sigma t
-let compute_auto_implicits env sigma flags enriching t =
- if enriching then compute_implicits_flags env sigma flags true t
- else compute_implicits_gen false false false true true env sigma t
+let compute_implicits_flags env sigma f all t =
+ List.combine
+ (compute_implicits_names_gen all env sigma t)
+ (compute_implicits_explanation_flags env sigma f t)
-let compute_implicits_names env sigma t =
- let _, impls = compute_implicits_gen false false false false true env sigma t in
- List.map fst impls
+let compute_auto_implicits env sigma flags enriching t =
+ List.combine
+ (compute_implicits_names env sigma t)
+ (if enriching then compute_implicits_explanation_flags env sigma flags t
+ else compute_implicits_explanation_gen false false false true env sigma t)
(* Extra information about implicit arguments *)
@@ -329,13 +349,16 @@ let rec prepare_implicits f = function
Some (id,imp,(set_maximality imps' f.maximal,true)) :: imps'
| _::imps -> None :: prepare_implicits f imps
-let set_implicit id imp insmax =
- (id,(match imp with None -> Manual | Some imp -> imp),insmax)
-
-let rec assoc_by_pos k = function
- (ExplByPos (k', x), b) :: tl when Int.equal k k' -> (x,b), tl
- | hd :: tl -> let (x, tl) = assoc_by_pos k tl in x, hd :: tl
- | [] -> raise Not_found
+(*
+If found, returns Some (x,(b,fi,fo)) and l with the entry removed,
+otherwise returns None and l unchanged.
+ *)
+let assoc_by_pos k l =
+ let rec aux = function
+ (ExplByPos (k', x), b) :: tl when Int.equal k k' -> Some (x,b), tl
+ | hd :: tl -> let (x, tl) = aux tl in x, hd :: tl
+ | [] -> raise Not_found
+ in try aux l with Not_found -> None, l
let check_correct_manual_implicits autoimps l =
List.iter (function
@@ -352,70 +375,65 @@ let check_correct_manual_implicits autoimps l =
(str "Cannot set implicit argument number " ++ int i ++
str ": it has no name.")) l
-let set_manual_implicits env flags enriching autoimps l =
- let try_forced k l =
- try
- let (id, (b, fi, fo)), l' = assoc_by_pos k l in
- if fo then
- let id = match id with Some id -> id | None -> Id.of_string ("arg_" ^ string_of_int k) in
- l', Some (id,Manual,(b,fi))
- else l, None
- with Not_found -> l, None
- in
+(* Take a list l of explicitations, and map them to positions. *)
+let flatten_explicitations l autoimps =
+ let rec aux k l = function
+ | (Name id,_)::imps ->
+ let value, l' =
+ try
+ let eq = explicitation_eq in
+ let flags = List.assoc_f eq (ExplByName id) l in
+ Some (Some id, flags), List.remove_assoc_f eq (ExplByName id) l
+ with Not_found -> assoc_by_pos k l
+ in value :: aux (k+1) l' imps
+ | (Anonymous,_)::imps ->
+ let value, l' = assoc_by_pos k l
+ in value :: aux (k+1) l' imps
+ | [] when List.is_empty l -> []
+ | [] ->
+ check_correct_manual_implicits autoimps l;
+ []
+ in aux 1 l autoimps
+
+let set_manual_implicits flags enriching autoimps l =
if not (List.distinct l) then
user_err Pp.(str "Some parameters are referred more than once.");
(* Compare with automatic implicits to recover printing data and names *)
- let rec merge k l = function
- | (Name id,imp)::imps ->
- let l',imp,m =
- try
- let eq = explicitation_eq in
- let (b, fi, fo) = List.assoc_f eq (ExplByName id) l in
- List.remove_assoc_f eq (ExplByName id) l, (Some Manual), (Some (b, fi))
- with Not_found ->
- try
- let (id, (b, fi, fo)), l' = assoc_by_pos k l in
- l', (Some Manual), (Some (b,fi))
- with Not_found ->
- let m = match enriching, imp with
- | true, Some _ -> Some (flags.maximal, true)
- | _ -> None
- in
- l, imp, m
- in
- let imps' = merge (k+1) l' imps in
- let m = Option.map (fun (b,f) ->
- (* match imp with Some Manual -> (b,f) *)
- (* | _ -> *)set_maximality imps' b, f) m in
- Option.map (set_implicit id imp) m :: imps'
- | (Anonymous,imp)::imps ->
- let l', forced = try_forced k l in
- forced :: merge (k+1) l' imps
- | [] when begin match l with [] -> true | _ -> false end -> []
- | [] ->
- check_correct_manual_implicits autoimps l;
- []
- in
- merge 1 l autoimps
-
-let compute_semi_auto_implicits env sigma f manual t =
- match manual with
- | [] ->
- if not f.auto then [DefaultImpArgs, []]
- else let _,l = compute_implicits_flags env sigma f false t in
- [DefaultImpArgs, prepare_implicits f l]
- | _ ->
- let _,autoimpls = compute_auto_implicits env sigma f f.auto t in
- [DefaultImpArgs, set_manual_implicits env f f.auto autoimpls manual]
+ let rec merge k autoimps explimps = match autoimps, explimps with
+ | autoimp::autoimps, explimp::explimps ->
+ let imps' = merge (k+1) autoimps explimps in
+ begin match autoimp, explimp with
+ | (Name id,_), Some (_, (b, fi, _)) ->
+ Some (id, Manual, (set_maximality imps' b, fi))
+ | (Name id,Some exp), None when enriching ->
+ Some (id, exp, (set_maximality imps' flags.maximal, true))
+ | (Name _,_), None -> None
+ | (Anonymous,_), Some (Some id, (b, fi, true)) ->
+ Some (id,Manual,(b,fi))
+ | (Anonymous,_), Some (None, (b, fi, true)) ->
+ let id = Id.of_string ("arg_" ^ string_of_int k) in
+ Some (id,Manual,(b,fi))
+ | (Anonymous,_), Some (_, (_, _, false)) -> None
+ | (Anonymous,_), None -> None
+ end :: imps'
+ | [], [] -> []
+ (* flatten_explicitations returns a list of the same length as autoimps *)
+ | _ -> assert false
+ in merge 1 autoimps (flatten_explicitations l autoimps)
+
+let compute_semi_auto_implicits env sigma f t =
+ if not f.auto then [DefaultImpArgs, []]
+ else let l = compute_implicits_flags env sigma f false t in
+ [DefaultImpArgs, prepare_implicits f l]
(*s Constants. *)
-let compute_constant_implicits flags manual cst =
+let compute_constant_implicits flags cst =
let env = Global.env () in
let sigma = Evd.from_env env in
let cb = Environ.lookup_constant cst env in
let ty = of_constr cb.const_type in
- let impls = compute_semi_auto_implicits env sigma flags manual ty in
+ let impls = compute_semi_auto_implicits env sigma flags ty in
impls
(*s Inductives and constructors. Their implicit arguments are stored
@@ -423,7 +441,7 @@ let compute_constant_implicits flags manual cst =
$i$ are the implicit arguments of the inductive and $v$ the array of
implicit arguments of the constructors. *)
-let compute_mib_implicits flags manual kn =
+let compute_mib_implicits flags kn =
let env = Global.env () in
let sigma = Evd.from_env env in
let mib = Environ.lookup_mind kn env in
@@ -439,34 +457,34 @@ let compute_mib_implicits flags manual kn =
let imps_one_inductive i mip =
let ind = (kn,i) in
let ar, _ = Global.type_of_global_in_context env (IndRef ind) in
- ((IndRef ind,compute_semi_auto_implicits env sigma flags manual (of_constr ar)),
+ ((IndRef ind,compute_semi_auto_implicits env sigma flags (of_constr ar)),
Array.mapi (fun j c ->
- (ConstructRef (ind,j+1),compute_semi_auto_implicits env_ar sigma flags manual c))
+ (ConstructRef (ind,j+1),compute_semi_auto_implicits env_ar sigma flags c))
(Array.map of_constr mip.mind_nf_lc))
in
Array.mapi imps_one_inductive mib.mind_packets
-let compute_all_mib_implicits flags manual kn =
- let imps = compute_mib_implicits flags manual kn in
+let compute_all_mib_implicits flags kn =
+ let imps = compute_mib_implicits flags kn in
List.flatten
(Array.map_to_list (fun (ind,cstrs) -> ind::Array.to_list cstrs) imps)
(*s Variables. *)
-let compute_var_implicits flags manual id =
+let compute_var_implicits flags id =
let env = Global.env () in
let sigma = Evd.from_env env in
- compute_semi_auto_implicits env sigma flags manual (NamedDecl.get_type (lookup_named id env))
+ compute_semi_auto_implicits env sigma flags (NamedDecl.get_type (lookup_named id env))
(* Implicits of a global reference. *)
-let compute_global_implicits flags manual = function
- | VarRef id -> compute_var_implicits flags manual id
- | ConstRef kn -> compute_constant_implicits flags manual kn
+let compute_global_implicits flags = function
+ | VarRef id -> compute_var_implicits flags id
+ | ConstRef kn -> compute_constant_implicits flags kn
| IndRef (kn,i) ->
- let ((_,imps),_) = (compute_mib_implicits flags manual kn).(i) in imps
+ let ((_,imps),_) = (compute_mib_implicits flags kn).(i) in imps
| ConstructRef ((kn,i),j) ->
- let (_,cimps) = (compute_mib_implicits flags manual kn).(i) in snd cimps.(j-1)
+ let (_,cimps) = (compute_mib_implicits flags kn).(i) in snd cimps.(j-1)
(* Merge a manual explicitation with an implicit_status list *)
@@ -573,34 +591,34 @@ let rebuild_implicits (req,l) =
| ImplLocal -> assert false
| ImplConstant (con,flags) ->
let oldimpls = snd (List.hd l) in
- let newimpls = compute_constant_implicits flags [] con in
+ let newimpls = compute_constant_implicits flags con in
req, [ConstRef con, List.map2 merge_impls oldimpls newimpls]
| ImplMutualInductive (kn,flags) ->
- let newimpls = compute_all_mib_implicits flags [] kn in
+ let newimpls = compute_all_mib_implicits flags kn in
let rec aux olds news =
- match olds, news with
- | (_, oldimpls) :: old, (gr, newimpls) :: tl ->
- (gr, List.map2 merge_impls oldimpls newimpls) :: aux old tl
- | [], [] -> []
- | _, _ -> assert false
+ match olds, news with
+ | (_, oldimpls) :: old, (gr, newimpls) :: tl ->
+ (gr, List.map2 merge_impls oldimpls newimpls) :: aux old tl
+ | [], [] -> []
+ | _, _ -> assert false
in req, aux l newimpls
| ImplInteractive (ref,flags,o) ->
(if isVarRef ref && is_in_section ref then ImplLocal else req),
match o with
| ImplAuto ->
- let oldimpls = snd (List.hd l) in
- let newimpls = compute_global_implicits flags [] ref in
- [ref,List.map2 merge_impls oldimpls newimpls]
+ let oldimpls = snd (List.hd l) in
+ let newimpls = compute_global_implicits flags ref in
+ [ref,List.map2 merge_impls oldimpls newimpls]
| ImplManual userimplsize ->
- let oldimpls = snd (List.hd l) in
- if flags.auto then
- let newimpls = List.hd (compute_global_implicits flags [] ref) in
- let p = List.length (snd newimpls) - userimplsize in
- let newimpls = on_snd (List.firstn p) newimpls in
- [ref,List.map (fun o -> merge_impls o newimpls) oldimpls]
- else
- [ref,oldimpls]
+ let oldimpls = snd (List.hd l) in
+ if flags.auto then
+ let newimpls = List.hd (compute_global_implicits flags ref) in
+ let p = List.length (snd newimpls) - userimplsize in
+ let newimpls = on_snd (List.firstn p) newimpls in
+ [ref,List.map (fun o -> merge_impls o newimpls) oldimpls]
+ else
+ [ref,oldimpls]
let classify_implicits (req,_ as obj) = match req with
| ImplLocal -> Dispose
@@ -622,7 +640,7 @@ let inImplicits : implicits_obj -> obj =
let is_local local ref = local || isVarRef ref && is_in_section ref
let declare_implicits_gen req flags ref =
- let imps = compute_global_implicits flags [] ref in
+ let imps = compute_global_implicits flags ref in
add_anonymous_leaf (inImplicits (req,[ref,imps]))
let declare_implicits local ref =
@@ -643,7 +661,7 @@ let declare_mib_implicits kn =
let flags = !implicit_args in
let imps = Array.map_to_list
(fun (ind,cstrs) -> ind::(Array.to_list cstrs))
- (compute_mib_implicits flags [] kn) in
+ (compute_mib_implicits flags kn) in
add_anonymous_leaf
(inImplicits (ImplMutualInductive (kn,flags),List.flatten imps))
@@ -653,8 +671,8 @@ type manual_explicitation = Constrexpr.explicitation * (bool * bool * bool)
type manual_implicits = manual_explicitation list
let compute_implicits_with_manual env sigma typ enriching l =
- let _,autoimpls = compute_auto_implicits env sigma !implicit_args enriching typ in
- set_manual_implicits env !implicit_args enriching autoimpls l
+ let autoimpls = compute_auto_implicits env sigma !implicit_args enriching typ in
+ set_manual_implicits !implicit_args enriching autoimpls l
let check_inclusion l =
(* Check strict inclusion *)
@@ -679,26 +697,26 @@ let declare_manual_implicits local ref ?enriching l =
let env = Global.env () in
let sigma = Evd.from_env env in
let t, _ = Global.type_of_global_in_context env ref in
+ let t = of_constr t in
let enriching = Option.default flags.auto enriching in
- let isrigid,autoimpls = compute_auto_implicits env sigma flags enriching (of_constr t) in
+ let autoimpls = compute_auto_implicits env sigma flags enriching t in
let l' = match l with
| [] -> assert false
| [l] ->
- [DefaultImpArgs, set_manual_implicits env flags enriching autoimpls l]
+ [DefaultImpArgs, set_manual_implicits flags enriching autoimpls l]
| _ ->
- check_rigidity isrigid;
- let l = List.map (fun imps -> (imps,List.length imps)) l in
- let l = List.sort (fun (_,n1) (_,n2) -> n2 - n1) l in
- check_inclusion l;
- let nargs = List.length autoimpls in
- List.map (fun (imps,n) ->
- (LessArgsThan (nargs-n),
- set_manual_implicits env flags enriching autoimpls imps)) l in
+ check_rigidity (is_rigid env sigma t);
+ let l = List.map (fun imps -> (imps,List.length imps)) l in
+ let l = List.sort (fun (_,n1) (_,n2) -> n2 - n1) l in
+ check_inclusion l;
+ let nargs = List.length autoimpls in
+ List.map (fun (imps,n) ->
+ (LessArgsThan (nargs-n),
+ set_manual_implicits flags enriching autoimpls imps)) l in
let req =
if is_local local ref then ImplLocal
else ImplInteractive(ref,flags,ImplManual (List.length autoimpls))
- in
- add_anonymous_leaf (inImplicits (req,[ref,l']))
+ in add_anonymous_leaf (inImplicits (req,[ref,l']))
let maybe_declare_manual_implicits local ref ?enriching l =
match l with
diff --git a/interp/impargs.mli b/interp/impargs.mli
index 1eeb8e41a..103a4f9e9 100644
--- a/interp/impargs.mli
+++ b/interp/impargs.mli
@@ -130,7 +130,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.ml b/interp/implicit_quantifiers.ml
index a1a3be70f..58df9abc4 100644
--- a/interp/implicit_quantifiers.ml
+++ b/interp/implicit_quantifiers.ml
@@ -245,6 +245,12 @@ let implicit_application env ?(allow_partial=true) f ty =
CAst.make ?loc @@ CAppExpl ((None, id, inst), args), avoid
in c, avoid
+let warn_ignoring_implicit_status =
+ CWarnings.create ~name:"ignoring_implicit_status" ~category:"implicits"
+ (fun na ->
+ strbrk "Ignoring implicit status of product binder " ++
+ Name.print na ++ strbrk " and following binders")
+
let implicits_of_glob_constr ?(with_products=true) l =
let add_impl i na bk l = match bk with
| Implicit ->
@@ -260,20 +266,18 @@ let implicits_of_glob_constr ?(with_products=true) l =
let abs na bk b =
add_impl i na bk (aux (succ i) b)
in
- match DAst.get c with
- | GProd (na, bk, t, b) ->
- if with_products then abs na bk b
- else
- let () = match bk with
- | Implicit ->
- Feedback.msg_warning (strbrk "Ignoring implicit status of product binder " ++
- Name.print na ++ strbrk " and following binders")
- | _ -> ()
- in []
- | GLambda (na, bk, t, b) -> abs na bk b
- | GLetIn (na, b, t, c) -> aux i b
- | GRec (fix_kind, nas, args, tys, bds) ->
- let nb = match fix_kind with |GFix (_, n) -> n | GCoFix n -> n in
- List.fold_left_i (fun i l (na,bk,_,_) -> add_impl i na bk l) i (aux (List.length args.(nb) + i) bds.(nb)) args.(nb)
- | _ -> []
+ match DAst.get c with
+ | GProd (na, bk, t, b) ->
+ if with_products then abs na bk b
+ else
+ let () = match bk with
+ | Implicit -> warn_ignoring_implicit_status na ?loc:c.CAst.loc
+ | _ -> ()
+ in []
+ | GLambda (na, bk, t, b) -> abs na bk b
+ | GLetIn (na, b, t, c) -> aux i b
+ | GRec (fix_kind, nas, args, tys, bds) ->
+ let nb = match fix_kind with |GFix (_, n) -> n | GCoFix n -> n in
+ List.fold_left_i (fun i l (na,bk,_,_) -> add_impl i na bk l) i (aux (List.length args.(nb) + i) bds.(nb)) args.(nb)
+ | _ -> []
in aux 1 l
diff --git a/interp/notation_ops.ml b/interp/notation_ops.ml
index a0d69ce79..a76f82094 100644
--- a/interp/notation_ops.ml
+++ b/interp/notation_ops.ml
@@ -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
@@ -1335,10 +1335,10 @@ let rec match_cases_pattern metas (terms,termlists,(),() as sigma) a1 a2 =
match DAst.get a1, a2 with
| r1, NVar id2 when Id.List.mem_assoc id2 metas -> (bind_env_cases_pattern sigma id2 a1),(0,[])
| PatVar Anonymous, NHole _ -> sigma,(0,[])
- | PatCstr ((ind,_ as r1),largs,_), NRef (ConstructRef r2) when eq_constructor r1 r2 ->
+ | PatCstr ((ind,_ as r1),largs,Anonymous), NRef (ConstructRef r2) when eq_constructor r1 r2 ->
let l = try add_patterns_for_params_remove_local_defs r1 largs with Not_found -> raise No_match in
sigma,(0,l)
- | PatCstr ((ind,_ as r1),args1,_), NApp (NRef (ConstructRef r2),l2)
+ | PatCstr ((ind,_ as r1),args1,Anonymous), NApp (NRef (ConstructRef r2),l2)
when eq_constructor r1 r2 ->
let l1 = try add_patterns_for_params_remove_local_defs r1 args1 with Not_found -> raise No_match in
let le2 = List.length l2 in
diff --git a/intf/misctypes.ml b/intf/misctypes.ml
index 9eb6f62cc..72db3b31c 100644
--- a/intf/misctypes.ml
+++ b/intf/misctypes.ml
@@ -142,19 +142,6 @@ type multi =
| RepeatStar
| RepeatPlus
-type 'a core_destruction_arg =
- | ElimOnConstr of 'a
- | ElimOnIdent of lident
- | ElimOnAnonHyp of int
-
-type 'a destruction_arg =
- clear_flag * 'a core_destruction_arg
-
-type inversion_kind =
- | SimpleInversion
- | FullInversion
- | FullInversionClear
-
type ('a, 'b) gen_universe_decl = {
univdecl_instance : 'a; (* Declared universes *)
univdecl_extensible_instance : bool; (* Can new universes be added *)
diff --git a/intf/pattern.ml b/intf/pattern.ml
index af2347674..76367b612 100644
--- a/intf/pattern.ml
+++ b/intf/pattern.ml
@@ -10,7 +10,6 @@
open Names
open Globnames
-open Constr
open Misctypes
(** {5 Patterns} *)
@@ -37,8 +36,8 @@ type constr_pattern =
| PIf of constr_pattern * constr_pattern * constr_pattern
| PCase of case_info_pattern * constr_pattern * constr_pattern *
(int * bool list * constr_pattern) list (** index of constructor, nb of args *)
- | PFix of fixpoint
- | PCoFix of cofixpoint
+ | PFix of (int array * int) * (Name.t array * constr_pattern array * constr_pattern array)
+ | PCoFix of int * (Name.t array * constr_pattern array * constr_pattern array)
(** Nota : in a [PCase], the array of branches might be shorter than
expected, denoting the use of a final "_ => _" branch *)
diff --git a/intf/vernacexpr.ml b/intf/vernacexpr.ml
index dc1110ad8..06f969f19 100644
--- a/intf/vernacexpr.ml
+++ b/intf/vernacexpr.ml
@@ -297,13 +297,9 @@ type inline =
type module_ast_inl = module_ast * inline
type module_binder = bool option * lident list * module_ast_inl
-(** Cumulativity can be set globally, locally or unset locally and it
- can not enabled at all. *)
-type cumulative_inductive_parsing_flag =
- | GlobalCumulativity
- | GlobalNonCumulativity
- | LocalCumulativity
- | LocalNonCumulativity
+(** [Some b] if locally enabled/disabled according to [b], [None] if
+ we should use the global flag. *)
+type vernac_cumulative = VernacCumulative | VernacNonCumulative
(** {6 The type of vernacular expressions} *)
@@ -338,7 +334,7 @@ type nonrec vernac_expr =
| VernacExactProof of constr_expr
| VernacAssumption of (Decl_kinds.discharge * Decl_kinds.assumption_object_kind) *
inline * (ident_decl list * constr_expr) with_coercion list
- | VernacInductive of cumulative_inductive_parsing_flag * Decl_kinds.private_flag * inductive_flag * (inductive_expr * decl_notation list) list
+ | VernacInductive of vernac_cumulative option * Decl_kinds.private_flag * inductive_flag * (inductive_expr * decl_notation list) list
| VernacFixpoint of Decl_kinds.discharge * (fixpoint_expr * decl_notation list) list
| VernacCoFixpoint of Decl_kinds.discharge * (cofixpoint_expr * decl_notation list) list
| VernacScheme of (lident option * scheme) list
@@ -409,8 +405,6 @@ type nonrec vernac_expr =
| VernacHints of string list * hints_expr
| VernacSyntacticDefinition of lident * (Id.t list * constr_expr) *
onlyparsing_flag
- | VernacDeclareImplicits of reference or_by_notation *
- (explicitation * bool * bool) list list
| VernacArguments of reference or_by_notation *
vernac_argument_status list (* Main arguments status list *) *
(Name.t * vernac_implicit_status) list list (* Extra implicit status lists *) *
@@ -418,8 +412,6 @@ type nonrec vernac_expr =
[ `ReductionDontExposeCase | `ReductionNeverUnfold | `Rename |
`ExtraScopes | `Assert | `ClearImplicits | `ClearScopes |
`DefaultImplicits ] list
- | VernacArgumentsScope of reference or_by_notation *
- scope_name option list
| VernacReserve of simple_binder list
| VernacGeneralizable of (lident list) option
| VernacSetOpacity of (Conv_oracle.level * reference or_by_notation list)
@@ -446,7 +438,6 @@ type nonrec vernac_expr =
| VernacRestart
| VernacUndo of int
| VernacUndoTo of int
- | VernacBacktrack of int*int*int
| VernacFocus of int option
| VernacUnfocus
| VernacUnfocused
@@ -506,14 +497,13 @@ type vernac_type =
| VtProofMode of string
(* Queries are commands assumed to be "pure", that is to say, they
don't modify the interpretation state. *)
- | VtQuery of vernac_part_of_script * Feedback.route_id
+ | VtQuery
(* To be removed *)
| VtMeta
| VtUnknown
and vernac_qed_type = VtKeep | VtKeepAsAxiom | VtDrop (* Qed/Admitted, Abort *)
and vernac_start = string * opacity_guarantee * Id.t list
and vernac_sideff_type = Id.t list
-and vernac_part_of_script = bool
and opacity_guarantee =
| GuaranteesOpacity (** Only generates opaque terms at [Qed] *)
| Doesn'tGuaranteeOpacity (** May generate transparent terms even with [Qed].*)
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 0766f49b3..70dc6867a 100644
--- a/kernel/cbytegen.ml
+++ b/kernel/cbytegen.ml
@@ -500,22 +500,19 @@ let rec compile_lam env reloc lam sz cont =
| Lsort (Sorts.Prop _ as s) ->
compile_structured_constant reloc (Const_sort s) sz cont
| Lsort (Sorts.Type u) ->
- (* We separate global and local universes in [u]. The former will be part
- of the structured constant, while the later (if any) will be applied as
- arguments. *)
- let open Univ in begin
- let u,s = Universe.compact u in
- (* We assume that [Universe.type0m] is a neutral element for [Universe.sup] *)
- let compile_get_univ reloc idx sz cont =
- set_max_stack_size sz;
- compile_fv_elem reloc (FVuniv_var idx) sz cont
- in
- if List.is_empty s then
- compile_structured_constant reloc (Const_sort (Sorts.Type u)) sz cont
- else
- comp_app compile_structured_constant compile_get_univ reloc
+ (* We represent universes as a global constant with local universes
+ "compacted", i.e. as [u arg0 ... argn] where we will substitute (after
+ evaluation) [Var 0,...,Var n] with values of [arg0,...,argn] *)
+ let u,s = Univ.compact_univ u in
+ let compile_get_univ reloc idx sz cont =
+ set_max_stack_size sz;
+ compile_fv_elem reloc (FVuniv_var idx) sz cont
+ in
+ if List.is_empty s then
+ compile_structured_constant reloc (Const_sort (Sorts.Type u)) sz cont
+ else
+ comp_app compile_structured_constant compile_get_univ reloc
(Const_sort (Sorts.Type u)) (Array.of_list s) sz cont
- end
| Llet (id,def,body) ->
compile_lam env reloc def sz
diff --git a/kernel/constr.ml b/kernel/constr.ml
index ba7fecadf..4f062d72f 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
diff --git a/kernel/constr.mli b/kernel/constr.mli
index 98c0eaa28..0d464840c 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}
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/esubst.ml b/kernel/esubst.ml
index a11a0dc00..91cc64523 100644
--- a/kernel/esubst.ml
+++ b/kernel/esubst.ml
@@ -19,6 +19,8 @@ open Util
(*********************)
(* Explicit lifts and basic operations *)
+(* Invariant to preserve in this module: no lift contains two consecutive
+ [ELSHFT] nor two consecutive [ELLFT]. *)
type lift =
| ELID
| ELSHFT of lift * int (* ELSHFT(l,n) == lift of n, then apply lift l *)
@@ -28,15 +30,15 @@ type lift =
let el_id = ELID
(* compose a relocation of magnitude n *)
-let rec el_shft_rec n = function
- | ELSHFT(el,k) -> el_shft_rec (k+n) el
+let el_shft_rec n = function
+ | ELSHFT(el,k) -> ELSHFT(el,k+n)
| el -> ELSHFT(el,n)
let el_shft n el = if Int.equal n 0 then el else el_shft_rec n el
(* cross n binders *)
-let rec el_liftn_rec n = function
+let el_liftn_rec n = function
| ELID -> ELID
- | ELLFT(k,el) -> el_liftn_rec (n+k) el
+ | ELLFT(k,el) -> ELLFT(n+k, el)
| el -> ELLFT(n, el)
let el_liftn n el = if Int.equal n 0 then el else el_liftn_rec n el
diff --git a/kernel/esubst.mli b/kernel/esubst.mli
index b82d6fdf0..a674c425a 100644
--- a/kernel/esubst.mli
+++ b/kernel/esubst.mli
@@ -56,7 +56,11 @@ val comp : ('a subs * 'a -> 'a) -> 'a subs -> 'a subs -> 'a subs
(** {6 Compact representation } *)
(** Compact representation of explicit relocations
- [ELSHFT(l,n)] == lift of [n], then apply [lift l].
- - [ELLFT(n,l)] == apply [l] to de Bruijn > [n] i.e under n binders. *)
+ - [ELLFT(n,l)] == apply [l] to de Bruijn > [n] i.e under n binders.
+
+ Invariant ensured by the private flag: no lift contains two consecutive
+ [ELSHFT] nor two consecutive [ELLFT].
+*)
type lift = private
| ELID
| ELSHFT of lift * int
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.mli b/kernel/names.mli
index ffd96781b..96e020aed 100644
--- a/kernel/names.mli
+++ b/kernel/names.mli
@@ -547,6 +547,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 +635,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 +747,7 @@ module Projection : sig
end
type projection = Projection.t
+[@@ocaml.deprecated "Alias for [Projection.t]"]
val constant_of_kn_equiv : KerName.t -> KerName.t -> Constant.t
[@@ocaml.deprecated "Same as [Constant.make]"]
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/univ.ml b/kernel/univ.ml
index be21381b7..ea3a52295 100644
--- a/kernel/univ.ml
+++ b/kernel/univ.ml
@@ -490,39 +490,6 @@ struct
in
List.fold_right (fun a acc -> aux a acc) u []
- (** [max_var_pred p u] returns the maximum variable level in [u] satisfying
- [p], -1 if not found *)
- let rec max_var_pred p u =
- let open Level in
- match u with
- | [] -> -1
- | (v, _) :: u ->
- match var_index v with
- | Some i when p i -> max i (max_var_pred p u)
- | _ -> max_var_pred p u
-
- let rec remap_var u i j =
- let open Level in
- match u with
- | [] -> []
- | (v, incr) :: u when var_index v = Some i ->
- (Level.var j, incr) :: remap_var u i j
- | _ :: u -> remap_var u i j
-
- let rec compact u max_var i =
- if i >= max_var then (u,[]) else
- let j = max_var_pred (fun j -> j < i) u in
- if Int.equal i (j+1) then
- let (u,s) = compact u max_var (i+1) in
- (u, i :: s)
- else
- let (u,s) = compact (remap_var u i j) max_var (i+1) in
- (u, j+1 :: s)
-
- let compact u =
- let max_var = max_var_pred (fun _ -> true) u in
- compact u max_var 0
-
(* Returns the formal universe that is greater than the universes u and v.
Used to type the products. *)
let sup x y = merge_univs x y
@@ -1208,6 +1175,20 @@ let abstract_cumulativity_info (univs, variance) =
let subst, univs = abstract_universes univs in
subst, (univs, variance)
+let rec compact_univ s vars i u =
+ match u with
+ | [] -> (s, List.rev vars)
+ | (lvl, _) :: u ->
+ match Level.var_index lvl with
+ | Some k when not (LMap.mem lvl s) ->
+ let lvl' = Level.var i in
+ compact_univ (LMap.add lvl lvl' s) (k :: vars) (i+1) u
+ | _ -> compact_univ s vars i u
+
+let compact_univ u =
+ let (s, s') = compact_univ LMap.empty [] 0 u in
+ (subst_univs_level_universe s u, s')
+
(** Pretty-printing *)
let pr_constraints prl = Constraint.pr prl
diff --git a/kernel/univ.mli b/kernel/univ.mli
index 629d83fb8..aaed899bf 100644
--- a/kernel/univ.mli
+++ b/kernel/univ.mli
@@ -128,12 +128,6 @@ sig
val map : (Level.t * int -> 'a) -> t -> 'a list
- (** [compact u] remaps local variables in [u] such that their indices become
- consecutive. It returns the new universe and the mapping.
- Example: compact [(Var 0, i); (Prop, 0); (Var 2; j))] =
- [(Var 0,i); (Prop, 0); (Var 1; j)], [0; 2]
- *)
- val compact : t -> t * int list
end
type universe = Universe.t
@@ -504,6 +498,13 @@ val abstract_cumulativity_info : CumulativityInfo.t -> Instance.t * ACumulativit
val make_abstract_instance : AUContext.t -> Instance.t
+(** [compact_univ u] remaps local variables in [u] such that their indices become
+ consecutive. It returns the new universe and the mapping.
+ Example: compact_univ [(Var 0, i); (Prop, 0); (Var 2; j))] =
+ [(Var 0,i); (Prop, 0); (Var 1; j)], [0; 2]
+*)
+val compact_univ : Universe.t -> Universe.t * int list
+
(** {6 Pretty-printing of universes. } *)
val pr_constraint_type : constraint_type -> Pp.t
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/aux_file.ml b/lib/aux_file.ml
index 7d9c528e7..0f9476605 100644
--- a/lib/aux_file.ml
+++ b/lib/aux_file.ml
@@ -55,7 +55,7 @@ let record_in_aux_at ?loc key v =
match loc with
| Some loc -> let i, j = Loc.unloc loc in
Printf.fprintf oc "%d %d %s %S\n" i j key v
- | None -> Printf.fprintf oc "--- %s %S\n" key v
+ | None -> Printf.fprintf oc "0 0 %s %S\n" key v
) !oc
let current_loc : Loc.t option ref = ref None
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/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/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index 8543d2b84..593dcbf58 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -161,20 +161,10 @@ GEXTEND Gram
| IDENT "Let"; id = identref; b = def_body ->
VernacDefinition ((DoDischarge, Let), (lname_of_lident id, None), b)
(* Gallina inductive declarations *)
- | cum = cumulativity_token; priv = private_token; f = finite_token;
+ | cum = OPT cumulativity_token; priv = private_token; f = finite_token;
indl = LIST1 inductive_definition SEP "with" ->
let (k,f) = f in
let indl=List.map (fun ((a,b,c,d),e) -> ((a,b,c,k,d),e)) indl in
- let cum =
- match cum with
- Some true -> LocalCumulativity
- | Some false -> LocalNonCumulativity
- | None ->
- if Flags.is_polymorphic_inductive_cumulativity () then
- GlobalCumulativity
- else
- GlobalNonCumulativity
- in
VernacInductive (cum, priv,f,indl)
| "Fixpoint"; recs = LIST1 rec_definition SEP "with" ->
VernacFixpoint (NoDischarge, recs)
@@ -257,7 +247,8 @@ GEXTEND Gram
| IDENT "Class" -> (Class true,BiFinite) ] ]
;
cumulativity_token:
- [ [ IDENT "Cumulative" -> Some true | IDENT "NonCumulative" -> Some false | -> None ] ]
+ [ [ IDENT "Cumulative" -> VernacCumulative
+ | IDENT "NonCumulative" -> VernacNonCumulative ] ]
;
private_token:
[ [ IDENT "Private" -> true | -> false ] ]
@@ -601,14 +592,6 @@ GEXTEND Gram
;
END
-let warn_deprecated_arguments_scope =
- CWarnings.create ~name:"deprecated-arguments-scope" ~category:"deprecated"
- (fun () -> strbrk "Arguments Scope is deprecated; use Arguments instead")
-
-let warn_deprecated_implicit_arguments =
- CWarnings.create ~name:"deprecated-implicit-arguments" ~category:"deprecated"
- (fun () -> strbrk "Implicit Arguments is deprecated; use Arguments instead")
-
(* Extensions: implicits, coercions, etc. *)
GEXTEND Gram
GLOBAL: gallina_ext instance_name hint_info;
@@ -691,20 +674,6 @@ GEXTEND Gram
let more_implicits = Option.default [] more_implicits in
VernacArguments (qid, args, more_implicits, !slash_position, mods)
-
- (* moved there so that camlp5 factors it with the previous rule *)
- | IDENT "Arguments"; IDENT "Scope"; qid = smart_global;
- "["; scl = LIST0 [ "_" -> None | sc = IDENT -> Some sc ]; "]" ->
- warn_deprecated_arguments_scope ~loc:!@loc ();
- VernacArgumentsScope (qid,scl)
-
- (* Implicit *)
- | IDENT "Implicit"; IDENT "Arguments"; qid = smart_global;
- pos = LIST0 [ "["; l = LIST0 implicit_name; "]" ->
- List.map (fun (id,b,f) -> (ExplByName id,b,f)) l ] ->
- warn_deprecated_implicit_arguments ~loc:!@loc ();
- VernacDeclareImplicits (qid,pos)
-
| IDENT "Implicit"; "Type"; bl = reserv_list ->
VernacReserve bl
@@ -734,12 +703,6 @@ GEXTEND Gram
[`ClearImplicits; `ClearScopes]
] ]
;
- implicit_name:
- [ [ "!"; id = ident -> (id, false, true)
- | id = ident -> (id,false,false)
- | "["; "!"; id = ident; "]" -> (id,true,true)
- | "["; id = ident; "]" -> (id,true, false) ] ]
- ;
scope:
[ [ "%"; key = IDENT -> key ] ]
;
@@ -1065,8 +1028,6 @@ GEXTEND Gram
| IDENT "Back" -> VernacBack 1
| IDENT "Back"; n = natural -> VernacBack n
| IDENT "BackTo"; n = natural -> VernacBackTo n
- | IDENT "Backtrack"; n = natural ; m = natural ; p = natural ->
- VernacBacktrack (n,m,p)
(* Tactic Debugger *)
| IDENT "Debug"; IDENT "On" ->
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/firstorder/sequent.ml b/plugins/firstorder/sequent.ml
index 285991797..7c612c0d8 100644
--- a/plugins/firstorder/sequent.ml
+++ b/plugins/firstorder/sequent.ml
@@ -77,14 +77,14 @@ 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
@@ -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
@@ -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/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 7a9bbd92c..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
@@ -628,16 +628,22 @@ let build_scheme fas =
user_err ~hdr:"FunInd.build_scheme"
(str "Cannot find " ++ Libnames.pr_reference f)
in
- let evd',f = Evd.fresh_global (Global.env ()) !evd f_as_constant 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
- (destConst f,sort)
- )
+ 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 =
make_scheme evd pconstants
in
+
List.iter2
(fun (princ_id,_,_) def_entry ->
ignore
diff --git a/plugins/funind/glob_term_to_relation.ml b/plugins/funind/glob_term_to_relation.ml
index 49f7aae43..319b410df 100644
--- a/plugins/funind/glob_term_to_relation.ml
+++ b/plugins/funind/glob_term_to_relation.ml
@@ -1512,7 +1512,7 @@ let do_build_inductive
in
let msg =
str "while trying to define"++ spc () ++
- Ppvernac.pr_vernac Vernacexpr.(VernacExpr([], VernacInductive(GlobalNonCumulativity,false,Declarations.Finite,repacked_rel_inds)))
+ Ppvernac.pr_vernac Vernacexpr.(VernacExpr([], VernacInductive(None,false,Declarations.Finite,repacked_rel_inds)))
++ fnl () ++
msg
in
@@ -1527,7 +1527,7 @@ let do_build_inductive
in
let msg =
str "while trying to define"++ spc () ++
- Ppvernac.pr_vernac Vernacexpr.(VernacExpr([], VernacInductive(GlobalNonCumulativity,false,Declarations.Finite,repacked_rel_inds)))
+ Ppvernac.pr_vernac Vernacexpr.(VernacExpr([], VernacInductive(None,false,Declarations.Finite,repacked_rel_inds)))
++ fnl () ++
CErrors.print reraise
in
diff --git a/plugins/funind/glob_termops.ml b/plugins/funind/glob_termops.ml
index 40ea40b6b..845104c3c 100644
--- a/plugins/funind/glob_termops.ml
+++ b/plugins/funind/glob_termops.ml
@@ -564,6 +564,7 @@ let resolve_and_replace_implicits ?(flags=Pretyping.all_and_fail_flags) ?(expect
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 f c = EConstr.of_constr (f (EConstr.Unsafe.to_constr c)) in
(* then we map [rt] to replace the implicit holes by their values *)
let rec change rt =
@@ -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/indfun.ml b/plugins/funind/indfun.ml
index 9c350483b..748d8add2 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)
diff --git a/plugins/funind/invfun.ml b/plugins/funind/invfun.ml
index 2743a8a2f..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)
@@ -969,7 +965,7 @@ let functional_inversion kn hid fconst f_correct : Tacmach.tactic =
Proofview.V82.of_tactic (generalize [applist(f_correct,(Array.to_list f_args)@[res;mkVar hid])]);
thin [hid];
Proofview.V82.of_tactic (Simple.intro hid);
- Proofview.V82.of_tactic (Inv.inv FullInversion None (NamedHyp hid));
+ Proofview.V82.of_tactic (Inv.inv Inv.FullInversion None (NamedHyp hid));
(fun g ->
let new_ids = List.filter (fun id -> not (Id.Set.mem id old_ids)) (pf_ids_of_hyps g) in
tclMAP (revert_graph kn pre_tac) (hid::new_ids) g
diff --git a/plugins/ltac/extratactics.ml4 b/plugins/ltac/extratactics.ml4
index 2e90ce90c..a5f8060ae 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
diff --git a/plugins/ltac/pltac.mli b/plugins/ltac/pltac.mli
index 6637de745..434feba95 100644
--- a/plugins/ltac/pltac.mli
+++ b/plugins/ltac/pltac.mli
@@ -25,7 +25,7 @@ val constr_may_eval : (constr_expr,reference or_by_notation,constr_expr) may_eva
val constr_eval : (constr_expr,reference or_by_notation,constr_expr) may_eval Gram.entry
val uconstr : constr_expr Gram.entry
val quantified_hypothesis : quantified_hypothesis Gram.entry
-val destruction_arg : constr_expr with_bindings destruction_arg Gram.entry
+val destruction_arg : constr_expr with_bindings Tactics.destruction_arg Gram.entry
val int_or_var : int or_var Gram.entry
val simple_tactic : raw_tactic_expr Gram.entry
val simple_intropattern : constr_expr intro_pattern_expr CAst.t Gram.entry
diff --git a/plugins/ltac/pptactic.mli b/plugins/ltac/pptactic.mli
index 5951f2b11..aea00c240 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 -> goal_selector -> Pp.t
+val pr_goal_selector : toplevel:bool -> Vernacexpr.goal_selector -> 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/tacarg.mli b/plugins/ltac/tacarg.mli
index 5347eda7d..59473a5e5 100644
--- a/plugins/ltac/tacarg.mli
+++ b/plugins/ltac/tacarg.mli
@@ -23,7 +23,7 @@ val wit_tactic : (raw_tactic_expr, glob_tactic_expr, Geninterp.Val.t) genarg_typ
val wit_ltac : (raw_tactic_expr, glob_tactic_expr, unit) genarg_type
val wit_destruction_arg :
- (constr_expr with_bindings Tacexpr.destruction_arg,
- glob_constr_and_expr with_bindings Tacexpr.destruction_arg,
- delayed_open_constr_with_bindings Tacexpr.destruction_arg) genarg_type
+ (constr_expr with_bindings Tactics.destruction_arg,
+ glob_constr_and_expr with_bindings Tactics.destruction_arg,
+ delayed_open_constr_with_bindings Tactics.destruction_arg) genarg_type
diff --git a/plugins/ltac/tacexpr.ml b/plugins/ltac/tacexpr.ml
index 8b0c44041..3baa475ab 100644
--- a/plugins/ltac/tacexpr.ml
+++ b/plugins/ltac/tacexpr.ml
@@ -40,25 +40,29 @@ type goal_selector = Vernacexpr.goal_selector =
| SelectList of (int * int) list
| SelectId of Id.t
| SelectAll
+[@@ocaml.deprecated "Use Vernacexpr.goal_selector"]
-type 'a core_destruction_arg = 'a Misctypes.core_destruction_arg =
+type 'a core_destruction_arg = 'a Tactics.core_destruction_arg =
| ElimOnConstr of 'a
| ElimOnIdent of lident
| ElimOnAnonHyp of int
+[@@ocaml.deprecated "Use Tactics.core_destruction_arg"]
type 'a destruction_arg =
- clear_flag * 'a core_destruction_arg
+ clear_flag * 'a Tactics.core_destruction_arg
+[@@ocaml.deprecated "Use Tactics.destruction_arg"]
-type inversion_kind = Misctypes.inversion_kind =
+type inversion_kind = Inv.inversion_kind =
| SimpleInversion
| FullInversion
| FullInversionClear
+[@@ocaml.deprecated "Use Tactics.inversion_kind"]
type ('c,'d,'id) inversion_strength =
| NonDepInversion of
- inversion_kind * 'id list * 'd or_and_intro_pattern_expr CAst.t or_var option
+ Inv.inversion_kind * 'id list * 'd or_and_intro_pattern_expr CAst.t or_var option
| DepInversion of
- inversion_kind * 'c option * 'd or_and_intro_pattern_expr CAst.t or_var option
+ Inv.inversion_kind * 'c option * 'd or_and_intro_pattern_expr CAst.t or_var option
| InversionUsing of 'c * 'id list
type ('a,'b) location = HypLocation of 'a | ConclLocation of 'b
@@ -69,7 +73,7 @@ type 'id message_token =
| MsgIdent of 'id
type ('dconstr,'id) induction_clause =
- 'dconstr with_bindings destruction_arg *
+ 'dconstr with_bindings Tactics.destruction_arg *
(intro_pattern_naming_expr CAst.t option (* eqn:... *)
* 'dconstr or_and_intro_pattern_expr CAst.t or_var option) (* as ... *)
* 'id clause_expr option (* in ... *)
@@ -265,7 +269,7 @@ and 'a gen_tactic_expr =
('p,'a gen_tactic_expr) match_rule list
| TacFun of 'a gen_tactic_fun_ast
| TacArg of 'a gen_tactic_arg located
- | TacSelect of goal_selector * 'a gen_tactic_expr
+ | TacSelect of Vernacexpr.goal_selector * '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 8b0c44041..3baa475ab 100644
--- a/plugins/ltac/tacexpr.mli
+++ b/plugins/ltac/tacexpr.mli
@@ -40,25 +40,29 @@ type goal_selector = Vernacexpr.goal_selector =
| SelectList of (int * int) list
| SelectId of Id.t
| SelectAll
+[@@ocaml.deprecated "Use Vernacexpr.goal_selector"]
-type 'a core_destruction_arg = 'a Misctypes.core_destruction_arg =
+type 'a core_destruction_arg = 'a Tactics.core_destruction_arg =
| ElimOnConstr of 'a
| ElimOnIdent of lident
| ElimOnAnonHyp of int
+[@@ocaml.deprecated "Use Tactics.core_destruction_arg"]
type 'a destruction_arg =
- clear_flag * 'a core_destruction_arg
+ clear_flag * 'a Tactics.core_destruction_arg
+[@@ocaml.deprecated "Use Tactics.destruction_arg"]
-type inversion_kind = Misctypes.inversion_kind =
+type inversion_kind = Inv.inversion_kind =
| SimpleInversion
| FullInversion
| FullInversionClear
+[@@ocaml.deprecated "Use Tactics.inversion_kind"]
type ('c,'d,'id) inversion_strength =
| NonDepInversion of
- inversion_kind * 'id list * 'd or_and_intro_pattern_expr CAst.t or_var option
+ Inv.inversion_kind * 'id list * 'd or_and_intro_pattern_expr CAst.t or_var option
| DepInversion of
- inversion_kind * 'c option * 'd or_and_intro_pattern_expr CAst.t or_var option
+ Inv.inversion_kind * 'c option * 'd or_and_intro_pattern_expr CAst.t or_var option
| InversionUsing of 'c * 'id list
type ('a,'b) location = HypLocation of 'a | ConclLocation of 'b
@@ -69,7 +73,7 @@ type 'id message_token =
| MsgIdent of 'id
type ('dconstr,'id) induction_clause =
- 'dconstr with_bindings destruction_arg *
+ 'dconstr with_bindings Tactics.destruction_arg *
(intro_pattern_naming_expr CAst.t option (* eqn:... *)
* 'dconstr or_and_intro_pattern_expr CAst.t or_var option) (* as ... *)
* 'id clause_expr option (* in ... *)
@@ -265,7 +269,7 @@ and 'a gen_tactic_expr =
('p,'a gen_tactic_expr) match_rule list
| TacFun of 'a gen_tactic_fun_ast
| TacArg of 'a gen_tactic_arg located
- | TacSelect of goal_selector * 'a gen_tactic_expr
+ | TacSelect of Vernacexpr.goal_selector * '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 e55b49fb4..105b5c59a 100644
--- a/plugins/ltac/tactic_debug.ml
+++ b/plugins/ltac/tactic_debug.ml
@@ -391,19 +391,14 @@ let explain_ltac_call_trace last trace loc =
let skip_extensions trace =
let rec aux = function
- | (_,Tacexpr.LtacNameCall f as tac) :: _
- when Tacenv.is_ltac_for_ml_tactic f -> [tac]
- | (_,Tacexpr.LtacNotationCall _ as tac) :: (_,Tacexpr.LtacMLCall _) :: _ ->
+ | (_,Tacexpr.LtacNotationCall _ as tac) :: (_,Tacexpr.LtacMLCall _) :: tail ->
(* Case of an ML defined tactic with entry of the form <<"foo" args>> *)
(* see tacextend.mlp *)
- [tac]
- | (_,Tacexpr.LtacMLCall _ as tac) :: _ -> [tac]
+ tac :: aux tail
| t :: tail -> t :: aux tail
| [] -> [] in
List.rev (aux (List.rev trace))
-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
@@ -411,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 *)
@@ -420,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/ssr/ssrcommon.ml b/plugins/ssr/ssrcommon.ml
index d5118da4c..d012fd0df 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));
diff --git a/plugins/ssr/ssrelim.ml b/plugins/ssr/ssrelim.ml
index 717657a24..de8ffb976 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
diff --git a/plugins/ssr/ssrequality.ml b/plugins/ssr/ssrequality.ml
index 57635edac..7748ba2b0 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)
@@ -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 42566575c..b397c5531 100644
--- a/plugins/ssr/ssripats.ml
+++ b/plugins/ssr/ssripats.ml
@@ -133,6 +133,12 @@ let intro_clear ids future_ipats =
isCLR_PUSHL clear_ids
end
+let tacCHECK_HYPS_EXIST hyps = Goal.enter begin fun gl ->
+ let ctx = Goal.hyps gl in
+ List.iter (Ssrcommon.check_hyp_exists ctx) hyps;
+ tclUNIT ()
+end
+
(** [=> []] *****************************************************************)
let tac_case t =
Goal.enter begin fun _ ->
@@ -212,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
@@ -229,7 +236,9 @@ let rec ipat_tac1 future_ipats ipat : unit tactic =
| IPatNoop -> tclUNIT ()
| IPatSimpl Nop -> tclUNIT ()
- | IPatClear ids -> intro_clear (List.map Ssrcommon.hyp_id ids) future_ipats
+ | IPatClear ids ->
+ tacCHECK_HYPS_EXIST ids <*>
+ intro_clear (List.map Ssrcommon.hyp_id ids) future_ipats
| IPatSimpl (Simpl n) ->
V82.tactic ~nf_evars:false (Ssrequality.simpltac (Simpl n))
@@ -246,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
@@ -277,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 (* }}} *)
@@ -410,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
@@ -615,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/ssrparser.ml4 b/plugins/ssr/ssrparser.ml4
index 0d82a9f09..5f3967440 100644
--- a/plugins/ssr/ssrparser.ml4
+++ b/plugins/ssr/ssrparser.ml4
@@ -585,21 +585,10 @@ let pr_ssripat _ _ _ = pr_ipat
let pr_ssripats _ _ _ = pr_ipats
let pr_ssriorpat _ _ _ = pr_iorpat
-(*
-let intern_ipat ist ipat =
- let rec check_pat = function
- | IPatClear clr -> ignore (List.map (intern_hyp ist) clr)
- | IPatCase iorpat -> List.iter (List.iter check_pat) iorpat
- | IPatDispatch iorpat -> List.iter (List.iter check_pat) iorpat
- | IPatInj iorpat -> List.iter (List.iter check_pat) iorpat
- | _ -> () in
- check_pat ipat; ipat
-*)
-
let intern_ipat ist =
map_ipat
(fun id -> id)
- (intern_hyp ist) (* TODO: check with ltac, old code was ignoring the result *)
+ (intern_hyp ist)
(glob_ast_closure_term ist)
let intern_ipats ist = List.map (intern_ipat ist)
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/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/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/pretyping/constr_matching.ml b/pretyping/constr_matching.ml
index 888c76e3d..89d490a41 100644
--- a/pretyping/constr_matching.ml
+++ b/pretyping/constr_matching.ml
@@ -183,9 +183,36 @@ let push_binder na1 na2 t ctx =
Namegen.next_ident_away Namegen.default_non_dependent_ident avoid in
(na1, id2, t) :: ctx
-let to_fix (idx, (nas, cs, ts)) =
- let inj = EConstr.of_constr in
- (idx, (nas, Array.map inj cs, Array.map inj ts))
+(* This is an optimization of the main pattern-matching which shares
+ the longest common prefix of the body and type of a fixpoint. The
+ only practical effect at the time of writing is in binding variable
+ names: these variable names must be bound only once since the user
+ view at a fix displays only a (maximal) shared common prefix *)
+
+let rec match_under_common_fix_binders sorec sigma binding_vars ctx ctx' env env' subst t1 t2 b1 b2 =
+ match t1, EConstr.kind sigma t2, b1, EConstr.kind sigma b2 with
+ | PProd(na1,c1,t1'), Prod(na2,c2,t2'), PLambda (_,c1',b1'), Lambda (na2',c2',b2') ->
+ let ctx = push_binder na1 na2 c2 ctx in
+ let ctx' = push_binder na1 na2' c2' ctx' in
+ let env = EConstr.push_rel (LocalAssum (na2,c2)) env in
+ let subst = sorec ctx env subst c1 c2 in
+ let subst = sorec ctx env subst c1' c2' in
+ let subst = add_binders na1 na2 binding_vars subst in
+ match_under_common_fix_binders sorec sigma binding_vars
+ ctx ctx' env env' subst t1' t2' b1' b2'
+ | PLetIn(na1,c1,u1,t1), LetIn(na2,c2,u2,t2), PLetIn(_,c1',u1',b1), LetIn(na2',c2',u2',b2) ->
+ let ctx = push_binder na1 na2 u2 ctx in
+ let ctx' = push_binder na1 na2' u2' ctx' in
+ let env = EConstr.push_rel (LocalDef (na2,c2,t2)) env in
+ let subst = sorec ctx env subst c1 c2 in
+ let subst = sorec ctx env subst c1' c2' in
+ let subst = Option.fold_left (fun subst u1 -> sorec ctx env subst u1 u2) subst u1 in
+ let subst = Option.fold_left (fun subst u1' -> sorec ctx env subst u1' u2') subst u1' in
+ let subst = add_binders na1 na2 binding_vars subst in
+ match_under_common_fix_binders sorec sigma binding_vars
+ ctx ctx' env env' subst t1 t2 b1 b2
+ | _ ->
+ sorec ctx' env' (sorec ctx env subst t1 t2) b1 b2
let merge_binding sigma allow_bound_rels ctx n cT subst =
let c = match ctx with
@@ -364,8 +391,20 @@ let matches_core env sigma allow_bound_rels
let chk_head = sorec ctx env (sorec ctx env subst a1 a2) p1 p2 in
List.fold_left chk_branch chk_head br1
- | PFix c1, Fix _ when eq_constr sigma (mkFix (to_fix c1)) cT -> subst
- | PCoFix c1, CoFix _ when eq_constr sigma (mkCoFix (to_fix c1)) cT -> subst
+ | PFix ((ln1,i1),(lna1,tl1,bl1)), Fix ((ln2,i2),(lna2,tl2,bl2))
+ when Array.equal Int.equal ln1 ln2 && i1 = i2 ->
+ let ctx' = Array.fold_left3 (fun ctx na1 na2 t2 -> push_binder na1 na2 t2 ctx) ctx lna1 lna2 tl2 in
+ let env' = Array.fold_left2 (fun env na2 c2 -> EConstr.push_rel (LocalAssum (na2,c2)) env) env lna2 tl2 in
+ let subst = Array.fold_left4 (match_under_common_fix_binders sorec sigma binding_vars ctx ctx' env env') subst tl1 tl2 bl1 bl2 in
+ Array.fold_left2 (fun subst na1 na2 -> add_binders na1 na2 binding_vars subst) subst lna1 lna2
+
+ | PCoFix (i1,(lna1,tl1,bl1)), CoFix (i2,(lna2,tl2,bl2))
+ when i1 = i2 ->
+ let ctx' = Array.fold_left3 (fun ctx na1 na2 t2 -> push_binder na1 na2 t2 ctx) ctx lna1 lna2 tl2 in
+ let env' = Array.fold_left2 (fun env na2 c2 -> EConstr.push_rel (LocalAssum (na2,c2)) env) env lna2 tl2 in
+ let subst = Array.fold_left4 (match_under_common_fix_binders sorec sigma binding_vars ctx ctx' env env') subst tl1 tl2 bl1 bl2 in
+ Array.fold_left2 (fun subst na1 na2 -> add_binders na1 na2 binding_vars subst) subst lna1 lna2
+
| PEvar (c1,args1), Evar (c2,args2) when Evar.equal c1 c2 ->
Array.fold_left2 (sorec ctx env) subst args1 args2
| (PRef _ | PVar _ | PRel _ | PApp _ | PProj _ | PLambda _
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index 587892141..bb563220b 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -501,6 +501,97 @@ let detype_case computable detype detype_eqns testdep avoid data p c bl =
let eqnl = detype_eqns constructs constagsl bl in
GCases (tag,pred,[tomatch,(alias,aliastyp)],eqnl)
+let rec share_names detype n l avoid env sigma c t =
+ match EConstr.kind sigma c, EConstr.kind sigma t with
+ (* factorize even when not necessary to have better presentation *)
+ | Lambda (na,t,c), Prod (na',t',c') ->
+ let na = match (na,na') with
+ Name _, _ -> na
+ | _, Name _ -> na'
+ | _ -> na in
+ let t' = detype avoid env sigma t in
+ let id = next_name_away na avoid in
+ let avoid = Id.Set.add id avoid and env = add_name (Name id) None t env in
+ share_names detype (n-1) ((Name id,Explicit,None,t')::l) avoid env sigma c c'
+ (* May occur for fix built interactively *)
+ | LetIn (na,b,t',c), _ when n > 0 ->
+ let t'' = detype avoid env sigma t' in
+ let b' = detype avoid env sigma b in
+ let id = next_name_away na avoid in
+ let avoid = Id.Set. add id avoid and env = add_name (Name id) (Some b) t' env in
+ share_names detype n ((Name id,Explicit,Some b',t'')::l) avoid env sigma c (lift 1 t)
+ (* Only if built with the f/n notation or w/o let-expansion in types *)
+ | _, LetIn (_,b,_,t) when n > 0 ->
+ share_names detype n l avoid env sigma c (subst1 b t)
+ (* If it is an open proof: we cheat and eta-expand *)
+ | _, Prod (na',t',c') when n > 0 ->
+ let t'' = detype avoid env sigma t' in
+ let id = next_name_away na' avoid in
+ let avoid = Id.Set.add id avoid and env = add_name (Name id) None t' env in
+ let appc = mkApp (lift 1 c,[|mkRel 1|]) in
+ share_names detype (n-1) ((Name id,Explicit,None,t'')::l) avoid env sigma appc c'
+ (* If built with the f/n notation: we renounce to share names *)
+ | _ ->
+ if n>0 then Feedback.msg_debug (strbrk "Detyping.detype: cannot factorize fix enough");
+ let c = detype avoid env sigma c in
+ let t = detype avoid env sigma t in
+ (List.rev l,c,t)
+
+let rec share_pattern_names detype n l avoid env sigma c t =
+ let open Pattern in
+ if n = 0 then
+ let c = detype avoid env sigma c in
+ let t = detype avoid env sigma t in
+ (List.rev l,c,t)
+ else match c, t with
+ | PLambda (na,t,c), PProd (na',t',c') ->
+ let na = match (na,na') with
+ Name _, _ -> na
+ | _, Name _ -> na'
+ | _ -> na in
+ let t' = detype avoid env sigma t in
+ let id = next_name_away na avoid in
+ let avoid = Id.Set.add id avoid in
+ let env = Name id :: env in
+ share_pattern_names detype (n-1) ((Name id,Explicit,None,t')::l) avoid env sigma c c'
+ | _ ->
+ if n>0 then Feedback.msg_debug (strbrk "Detyping.detype: cannot factorize fix enough");
+ let c = detype avoid env sigma c in
+ let t = detype avoid env sigma t in
+ (List.rev l,c,t)
+
+let detype_fix detype avoid env sigma (vn,_ as nvn) (names,tys,bodies) =
+ let def_avoid, def_env, lfi =
+ Array.fold_left2
+ (fun (avoid, env, l) na ty ->
+ let id = next_name_away na avoid in
+ (Id.Set.add id avoid, add_name (Name id) None ty env, id::l))
+ (avoid, env, []) names tys in
+ let n = Array.length tys in
+ let v = Array.map3
+ (fun c t i -> share_names detype (i+1) [] def_avoid def_env sigma c (lift n t))
+ bodies tys vn in
+ GRec(GFix (Array.map (fun i -> Some i, GStructRec) (fst nvn), snd nvn),Array.of_list (List.rev lfi),
+ Array.map (fun (bl,_,_) -> bl) v,
+ Array.map (fun (_,_,ty) -> ty) v,
+ Array.map (fun (_,bd,_) -> bd) v)
+
+let detype_cofix detype avoid env sigma n (names,tys,bodies) =
+ let def_avoid, def_env, lfi =
+ Array.fold_left2
+ (fun (avoid, env, l) na ty ->
+ let id = next_name_away na avoid in
+ (Id.Set.add id avoid, add_name (Name id) None ty env, id::l))
+ (avoid, env, []) names tys in
+ let ntys = Array.length tys in
+ let v = Array.map2
+ (fun c t -> share_names detype 0 [] def_avoid def_env sigma c (lift ntys t))
+ bodies tys in
+ GRec(GCoFix n,Array.of_list (List.rev lfi),
+ Array.map (fun (bl,_,_) -> bl) v,
+ Array.map (fun (_,_,ty) -> ty) v,
+ Array.map (fun (_,bd,_) -> bd) v)
+
let detype_universe sigma u =
let fn (l, n) = Some (Termops.reference_of_level sigma l, n) in
Univ.Universe.map fn u
@@ -655,76 +746,8 @@ and detype_r d flags avoid env sigma t =
(ci.ci_ind,ci.ci_pp_info.style,
ci.ci_pp_info.cstr_tags,ci.ci_pp_info.ind_tags)
p c bl
- | Fix (nvn,recdef) -> detype_fix d flags avoid env sigma nvn recdef
- | CoFix (n,recdef) -> detype_cofix d flags avoid env sigma n recdef
-
-and detype_fix d flags avoid env sigma (vn,_ as nvn) (names,tys,bodies) =
- let def_avoid, def_env, lfi =
- Array.fold_left2
- (fun (avoid, env, l) na ty ->
- let id = next_name_away na avoid in
- (Id.Set.add id avoid, add_name (Name id) None ty env, id::l))
- (avoid, env, []) names tys in
- let n = Array.length tys in
- let v = Array.map3
- (fun c t i -> share_names d flags (i+1) [] def_avoid def_env sigma c (lift n t))
- bodies tys vn in
- GRec(GFix (Array.map (fun i -> Some i, GStructRec) (fst nvn), snd nvn),Array.of_list (List.rev lfi),
- Array.map (fun (bl,_,_) -> bl) v,
- Array.map (fun (_,_,ty) -> ty) v,
- Array.map (fun (_,bd,_) -> bd) v)
-
-and detype_cofix d flags avoid env sigma n (names,tys,bodies) =
- let def_avoid, def_env, lfi =
- Array.fold_left2
- (fun (avoid, env, l) na ty ->
- let id = next_name_away na avoid in
- (Id.Set.add id avoid, add_name (Name id) None ty env, id::l))
- (avoid, env, []) names tys in
- let ntys = Array.length tys in
- let v = Array.map2
- (fun c t -> share_names d flags 0 [] def_avoid def_env sigma c (lift ntys t))
- bodies tys in
- GRec(GCoFix n,Array.of_list (List.rev lfi),
- Array.map (fun (bl,_,_) -> bl) v,
- Array.map (fun (_,_,ty) -> ty) v,
- Array.map (fun (_,bd,_) -> bd) v)
-
-and share_names d flags n l avoid env sigma c t =
- match EConstr.kind sigma c, EConstr.kind sigma t with
- (* factorize even when not necessary to have better presentation *)
- | Lambda (na,t,c), Prod (na',t',c') ->
- let na = match (na,na') with
- Name _, _ -> na
- | _, Name _ -> na'
- | _ -> na in
- let t' = detype d flags avoid env sigma t in
- let id = next_name_away na avoid in
- let avoid = Id.Set.add id avoid and env = add_name (Name id) None t env in
- share_names d flags (n-1) ((Name id,Explicit,None,t')::l) avoid env sigma c c'
- (* May occur for fix built interactively *)
- | LetIn (na,b,t',c), _ when n > 0 ->
- let t'' = detype d flags avoid env sigma t' in
- let b' = detype d flags avoid env sigma b in
- let id = next_name_away na avoid in
- let avoid = Id.Set. add id avoid and env = add_name (Name id) (Some b) t' env in
- share_names d flags n ((Name id,Explicit,Some b',t'')::l) avoid env sigma c (lift 1 t)
- (* Only if built with the f/n notation or w/o let-expansion in types *)
- | _, LetIn (_,b,_,t) when n > 0 ->
- share_names d flags n l avoid env sigma c (subst1 b t)
- (* If it is an open proof: we cheat and eta-expand *)
- | _, Prod (na',t',c') when n > 0 ->
- let t'' = detype d flags avoid env sigma t' in
- let id = next_name_away na' avoid in
- let avoid = Id.Set.add id avoid and env = add_name (Name id) None t' env in
- let appc = mkApp (lift 1 c,[|mkRel 1|]) in
- share_names d flags (n-1) ((Name id,Explicit,None,t'')::l) avoid env sigma appc c'
- (* If built with the f/n notation: we renounce to share names *)
- | _ ->
- if n>0 then Feedback.msg_debug (strbrk "Detyping.detype: cannot factorize fix enough");
- let c = detype d flags avoid env sigma c in
- let t = detype d flags avoid env sigma t in
- (List.rev l,c,t)
+ | Fix (nvn,recdef) -> detype_fix (detype d flags) avoid env sigma nvn recdef
+ | CoFix (n,recdef) -> detype_cofix (detype d flags) avoid env sigma n recdef
and detype_eqns d flags avoid env sigma ci computable constructs consnargsl bl =
try
diff --git a/pretyping/detyping.mli b/pretyping/detyping.mli
index 32b94e1b0..817b8ba6e 100644
--- a/pretyping/detyping.mli
+++ b/pretyping/detyping.mli
@@ -56,6 +56,13 @@ val detype_sort : evar_map -> Sorts.t -> glob_sort
val detype_rel_context : 'a delay -> ?lax:bool -> constr option -> Id.Set.t -> (names_context * env) ->
evar_map -> rel_context -> 'a glob_decl_g list
+val share_pattern_names :
+ (Id.Set.t -> names_context -> 'c -> Pattern.constr_pattern -> 'a) -> int ->
+ (Name.t * Decl_kinds.binding_kind * 'b option * 'a) list ->
+ Id.Set.t -> names_context -> 'c -> Pattern.constr_pattern ->
+ Pattern.constr_pattern ->
+ (Name.t * Decl_kinds.binding_kind * 'b option * 'a) list * 'a * 'a
+
val detype_closed_glob : ?lax:bool -> bool -> Id.Set.t -> env -> evar_map -> closed_glob_constr -> glob_constr
(** look for the index of a named var or a nondep var as it is renamed *)
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/pretyping/glob_ops.ml b/pretyping/glob_ops.ml
index 74f2cefab..e89bbf7c3 100644
--- a/pretyping/glob_ops.ml
+++ b/pretyping/glob_ops.ml
@@ -136,7 +136,7 @@ let mk_glob_constr_eq f c1 c2 = match DAst.get c1, DAst.get c2 with
| GIf (m1, (pat1, p1), c1, t1), GIf (m2, (pat2, p2), c2, t2) ->
f m1 m2 && Name.equal pat1 pat2 &&
Option.equal f p1 p2 && f c1 c2 && f t1 t2
- | GRec (kn1, id1, decl1, c1, t1), GRec (kn2, id2, decl2, c2, t2) ->
+ | GRec (kn1, id1, decl1, t1, c1), GRec (kn2, id2, decl2, t2, c2) ->
fix_kind_eq f kn1 kn2 && Array.equal Id.equal id1 id2 &&
Array.equal (fun l1 l2 -> List.equal (glob_decl_eq f) l1 l2) decl1 decl2 &&
Array.equal f c1 c2 && Array.equal f t1 t2
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/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/pretyping/patternops.ml b/pretyping/patternops.ml
index dcb93bfb6..27e457e3b 100644
--- a/pretyping/patternops.ml
+++ b/pretyping/patternops.ml
@@ -15,7 +15,6 @@ open Globnames
open Nameops
open Term
open Constr
-open Vars
open Glob_term
open Pp
open Mod_subst
@@ -57,10 +56,10 @@ let rec constr_pattern_eq p1 p2 = match p1, p2 with
constr_pattern_eq p1 p2 &&
constr_pattern_eq r1 r2 &&
List.equal pattern_eq l1 l2
-| PFix f1, PFix f2 ->
- fixpoint_eq f1 f2
-| PCoFix f1, PCoFix f2 ->
- cofixpoint_eq f1 f2
+| PFix ((ln1,i1),f1), PFix ((ln2,i2),f2) ->
+ Array.equal Int.equal ln1 ln2 && Int.equal i1 i2 && rec_declaration_eq f1 f2
+| PCoFix (i1,f1), PCoFix (i2,f2) ->
+ Int.equal i1 i2 && rec_declaration_eq f1 f2
| PProj (p1, t1), PProj (p2, t2) ->
Projection.equal p1 p2 && constr_pattern_eq t1 t2
| (PRef _ | PVar _ | PEvar _ | PRel _ | PApp _ | PSoApp _
@@ -71,19 +70,10 @@ let rec constr_pattern_eq p1 p2 = match p1, p2 with
and pattern_eq (i1, j1, p1) (i2, j2, p2) =
Int.equal i1 i2 && List.equal (==) j1 j2 && constr_pattern_eq p1 p2
-and fixpoint_eq ((arg1, i1), r1) ((arg2, i2), r2) =
- Int.equal i1 i2 &&
- Array.equal Int.equal arg1 arg2 &&
- rec_declaration_eq r1 r2
-
-and cofixpoint_eq (i1, r1) (i2, r2) =
- Int.equal i1 i2 &&
- rec_declaration_eq r1 r2
-
and rec_declaration_eq (n1, c1, r1) (n2, c2, r2) =
Array.equal Name.equal n1 n2 &&
- Array.equal Constr.equal c1 c2 &&
- Array.equal Constr.equal r1 r2
+ Array.equal constr_pattern_eq c1 c2 &&
+ Array.equal constr_pattern_eq r1 r2
let rec occur_meta_pattern = function
| PApp (f,args) ->
@@ -123,8 +113,10 @@ let rec occurn_pattern n = function
| PMeta _ | PSoApp _ -> true
| PEvar (_,args) -> Array.exists (occurn_pattern n) args
| PVar _ | PRef _ | PSort _ -> false
- | PFix fix -> not (noccurn n (mkFix fix))
- | PCoFix cofix -> not (noccurn n (mkCoFix cofix))
+ | PFix (_,(_,tl,bl)) ->
+ Array.exists (occurn_pattern n) tl || Array.exists (occurn_pattern (n+Array.length tl)) bl
+ | PCoFix (_,(_,tl,bl)) ->
+ Array.exists (occurn_pattern n) tl || Array.exists (occurn_pattern (n+Array.length tl)) bl
let noccurn_pattern n c = not (occurn_pattern n c)
@@ -192,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
| _ ->
@@ -209,8 +201,16 @@ let pattern_of_constr env sigma t =
in
PCase (cip, pattern_of_constr env p, pattern_of_constr env a,
Array.to_list (Array.mapi branch_of_constr br))
- | Fix f -> PFix f
- | CoFix f -> PCoFix f in
+ | Fix (lni,(lna,tl,bl)) ->
+ let push env na2 c2 = push_rel (LocalAssum (na2,c2)) env in
+ let env' = Array.fold_left2 push env lna tl in
+ PFix (lni,(lna,Array.map (pattern_of_constr env) tl,
+ Array.map (pattern_of_constr env') bl))
+ | CoFix (ln,(lna,tl,bl)) ->
+ let push env na2 c2 = push_rel (LocalAssum (na2,c2)) env in
+ let env' = Array.fold_left2 push env lna tl in
+ PCoFix (ln,(lna,Array.map (pattern_of_constr env) tl,
+ Array.map (pattern_of_constr env') bl)) in
pattern_of_constr env t
(* To process patterns, we need a translation without typing at all. *)
@@ -225,10 +225,14 @@ let map_pattern_with_binders g f l = function
| PCase (ci,po,p,pl) ->
PCase (ci,f l po,f l p, List.map (fun (i,n,c) -> (i,n,f l c)) pl)
| PProj (p,pc) -> PProj (p, f l pc)
+ | PFix (lni,(lna,tl,bl)) ->
+ let l' = Array.fold_left (fun l na -> g na l) l lna in
+ PFix (lni,(lna,Array.map (f l) tl,Array.map (f l') bl))
+ | PCoFix (ln,(lna,tl,bl)) ->
+ let l' = Array.fold_left (fun l na -> g na l) l lna in
+ PCoFix (ln,(lna,Array.map (f l) tl,Array.map (f l') bl))
(* Non recursive *)
- | (PVar _ | PEvar _ | PRel _ | PRef _ | PSort _ | PMeta _
- (* Bound to terms *)
- | PFix _ | PCoFix _ as x) -> x
+ | (PVar _ | PEvar _ | PRel _ | PRef _ | PSort _ | PMeta _ as x) -> x
let error_instantiate_pattern id l =
let is = match l with
@@ -262,15 +266,12 @@ let instantiate_pattern env sigma lvar c =
error_instantiate_pattern id (List.subtract Id.equal ctx vars)
with Not_found (* Map.find failed *) ->
x)
- | (PFix _ | PCoFix _) -> user_err Pp.(str "Non instantiable pattern.")
| c ->
map_pattern_with_binders (fun id vars -> id::vars) aux vars c in
aux [] c
let rec liftn_pattern k n = function
| PRel i as x -> if i >= n then PRel (i+k) else x
- | PFix x -> PFix (destFix (liftn k n (mkFix x)))
- | PCoFix x -> PCoFix (destCoFix (liftn k n (mkCoFix x)))
| c -> map_pattern_with_binders (fun _ -> succ) (liftn_pattern k) n c
let lift_pattern k = liftn_pattern k 1
@@ -337,19 +338,35 @@ let rec subst_pattern subst pat =
if cip' == cip && typ' == typ && c' == c && branches' == branches
then pat
else PCase(cip', typ', c', branches')
- | PFix fixpoint ->
- let cstr = mkFix fixpoint in
- let fixpoint' = destFix (subst_mps subst cstr) in
- if fixpoint' == fixpoint then pat else
- PFix fixpoint'
- | PCoFix cofixpoint ->
- let cstr = mkCoFix cofixpoint in
- let cofixpoint' = destCoFix (subst_mps subst cstr) in
- if cofixpoint' == cofixpoint then pat else
- PCoFix cofixpoint'
-
-let mkPLambda na b = PLambda(na,PMeta None,b)
-let rev_it_mkPLambda = List.fold_right mkPLambda
+ | PFix (lni,(lna,tl,bl)) ->
+ let tl' = Array.smartmap (subst_pattern subst) tl in
+ let bl' = Array.smartmap (subst_pattern subst) bl in
+ if bl' == bl && tl' == tl then pat
+ else PFix (lni,(lna,tl',bl'))
+ | PCoFix (ln,(lna,tl,bl)) ->
+ let tl' = Array.smartmap (subst_pattern subst) tl in
+ let bl' = Array.smartmap (subst_pattern subst) bl in
+ if bl' == bl && tl' == tl then pat
+ else PCoFix (ln,(lna,tl',bl'))
+
+let mkPLetIn na b t c = PLetIn(na,b,t,c)
+let mkPProd na t u = PProd(na,t,u)
+let mkPLambda na t b = PLambda(na,t,b)
+let mkPLambdaUntyped na b = PLambda(na,PMeta None,b)
+let rev_it_mkPLambdaUntyped = List.fold_right mkPLambdaUntyped
+
+let mkPProd_or_LetIn (na,_,bo,t) c =
+ match bo with
+ | None -> mkPProd na t c
+ | Some b -> mkPLetIn na b (Some t) c
+
+let mkPLambda_or_LetIn (na,_,bo,t) c =
+ match bo with
+ | None -> mkPLambda na t c
+ | Some b -> mkPLetIn na b (Some t) c
+
+let it_mkPProd_or_LetIn = List.fold_left (fun c d -> mkPProd_or_LetIn d c)
+let it_mkPLambda_or_LetIn = List.fold_left (fun c d -> mkPLambda_or_LetIn d c)
let err ?loc pp = user_err ?loc ~hdr:"pattern_of_glob_constr" pp
@@ -428,7 +445,7 @@ let rec pat_of_raw metas vars = DAst.with_loc_val (fun ?loc -> function
let pred = match p,indnames with
| Some p, Some {CAst.v=(_,nal)} ->
let nvars = na :: List.rev nal @ vars in
- rev_it_mkPLambda nal (mkPLambda na (pat_of_raw metas nvars p))
+ rev_it_mkPLambdaUntyped nal (mkPLambdaUntyped na (pat_of_raw metas nvars p))
| None, _ -> PMeta None
| Some p, None ->
match DAst.get p with
@@ -450,9 +467,40 @@ let rec pat_of_raw metas vars = DAst.with_loc_val (fun ?loc -> function
| GProj(p,c) ->
PProj(p, pat_of_raw metas vars c)
- | GPatVar _ | GIf _ | GLetTuple _ | GCases _ | GEvar _ | GRec _ ->
+ | GRec (GFix (ln,n), ids, decls, tl, cl) ->
+ if Array.exists (function (Some n, GStructRec) -> false | _ -> true) ln then
+ err ?loc (Pp.str "\"struct\" annotation is expected.")
+ else
+ let ln = Array.map (fst %> Option.get) ln in
+ let ctxtl = Array.map2 (pat_of_glob_in_context metas vars) decls tl in
+ let tl = Array.map (fun (ctx,tl) -> it_mkPProd_or_LetIn tl ctx) ctxtl in
+ let vars = Array.fold_left (fun vars na -> Name na::vars) vars ids in
+ let ctxtl = Array.map2 (pat_of_glob_in_context metas vars) decls cl in
+ let cl = Array.map (fun (ctx,cl) -> it_mkPLambda_or_LetIn cl ctx) ctxtl in
+ let names = Array.map (fun id -> Name id) ids in
+ PFix ((ln,n), (names, tl, cl))
+
+ | GRec (GCoFix n, ids, decls, tl, cl) ->
+ let ctxtl = Array.map2 (pat_of_glob_in_context metas vars) decls tl in
+ let tl = Array.map (fun (ctx,tl) -> it_mkPProd_or_LetIn tl ctx) ctxtl in
+ let vars = Array.fold_left (fun vars na -> Name na::vars) vars ids in
+ let ctxtl = Array.map2 (pat_of_glob_in_context metas vars) decls cl in
+ let cl = Array.map (fun (ctx,cl) -> it_mkPLambda_or_LetIn cl ctx) ctxtl in
+ let names = Array.map (fun id -> Name id) ids in
+ PCoFix (n, (names, tl, cl))
+
+ | GPatVar _ | GIf _ | GLetTuple _ | GCases _ | GEvar _ ->
err ?loc (Pp.str "Non supported pattern."))
+and pat_of_glob_in_context metas vars decls c =
+ let rec aux acc vars = function
+ | (na,bk,b,t) :: decls ->
+ let decl = (na,bk,Option.map (pat_of_raw metas vars) b,pat_of_raw metas vars t) in
+ aux (decl::acc) (na::vars) decls
+ | [] ->
+ acc, pat_of_raw metas vars c
+ in aux [] vars decls
+
and pats_of_glob_branches loc metas vars ind brs =
let get_arg p = match DAst.get p with
| PatVar na ->
@@ -477,7 +525,7 @@ and pats_of_glob_branches loc metas vars ind brs =
(str "No unique branch for " ++ int j ++ str"-th constructor.");
let lna = List.map get_arg lv in
let vars' = List.rev lna @ vars in
- let pat = rev_it_mkPLambda lna (pat_of_raw metas vars' br) in
+ let pat = rev_it_mkPLambdaUntyped lna (pat_of_raw metas vars' br) in
let ext,pats = get_pat (Int.Set.add (j-1) indexes) brs in
let tags = List.map (fun _ -> false) lv (* approximation, w/o let-in *) in
ext, ((j-1, tags, pat) :: pats)
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index 4962b89a0..947469ca0 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
@@ -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/reductionops.ml b/pretyping/reductionops.ml
index 9e3e68f05..244b8e60b 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -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..b8ac085a7 100644
--- a/pretyping/reductionops.mli
+++ b/pretyping/reductionops.mli
@@ -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..696001ab7 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
diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml
index 08051fd3a..30ddeffa6 100644
--- a/pretyping/typeclasses.ml
+++ b/pretyping/typeclasses.ml
@@ -158,7 +158,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
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/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 7df0a0c94..7eb8396ac 100644
--- a/printing/ppvernac.ml
+++ b/printing/ppvernac.ml
@@ -155,13 +155,6 @@ open Decl_kinds
let pr_locality local = if local then keyword "Local" else keyword "Global"
- let pr_explanation (e,b,f) =
- let a = match e with
- | ExplByPos (n,_) -> anomaly (Pp.str "No more supported.")
- | ExplByName id -> pr_id id in
- let a = if f then str"!" ++ a else a in
- if b then str "[" ++ a ++ str "]" else a
-
let pr_option_ref_value = function
| QualidRefValue id -> pr_reference id
| StringRefValue s -> qs s
@@ -591,8 +584,6 @@ open Decl_kinds
)
| VernacUndoTo i ->
return (keyword "Undo" ++ spc() ++ keyword "To" ++ pr_intarg i)
- | VernacBacktrack (i,j,k) ->
- return (keyword "Backtrack" ++ spc() ++ prlist_with_sep sep int [i;j;k])
| VernacFocus i ->
return (keyword "Focus" ++ pr_opt int i)
| VernacShow s ->
@@ -653,16 +644,6 @@ open Decl_kinds
keyword "Bind Scope" ++ spc () ++ str sc ++
spc() ++ keyword "with" ++ spc () ++ prlist_with_sep spc pr_class_rawexpr cll
)
- | VernacArgumentsScope (q,scl) ->
- let pr_opt_scope = function
- | None -> str"_"
- | Some sc -> str sc
- in
- return (
- keyword "Arguments Scope"
- ++ spc() ++ pr_smart_global q
- ++ spc() ++ str"[" ++ prlist_with_sep sep pr_opt_scope scl ++ str"]"
- )
| VernacInfix (({v=s},mv),q,sn) -> (* A Verifier *)
return (
hov 0 (hov 0 (keyword "Infix "
@@ -786,8 +767,9 @@ open Decl_kinds
if p then
let cm =
match cum with
- | GlobalCumulativity | LocalCumulativity -> "Cumulative"
- | GlobalNonCumulativity | LocalNonCumulativity -> "NonCumulative"
+ | Some VernacCumulative -> "Cumulative"
+ | Some VernacNonCumulative -> "NonCumulative"
+ | None -> ""
in
cm ^ " " ^ kind
else kind
@@ -1016,18 +998,6 @@ open Decl_kinds
| Some Flags.Current -> [SetOnlyParsing]
| Some v -> [SetCompatVersion v]))
)
- | VernacDeclareImplicits (q,[]) ->
- return (
- hov 2 (keyword "Implicit Arguments" ++ spc() ++ pr_smart_global q)
- )
- | VernacDeclareImplicits (q,impls) ->
- return (
- hov 1 (keyword "Implicit Arguments" ++ spc () ++
- spc() ++ pr_smart_global q ++ spc() ++
- prlist_with_sep spc (fun imps ->
- str"[" ++ prlist_with_sep sep pr_explanation imps ++ str"]")
- impls)
- )
| VernacArguments (q, args, more_implicits, nargs, mods) ->
return (
hov 2 (
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/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/pfedit.ml b/proofs/pfedit.ml
index 8725f51cd..abda04ff1 100644
--- a/proofs/pfedit.ml
+++ b/proofs/pfedit.ml
@@ -233,7 +233,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/proof_global.ml b/proofs/proof_global.ml
index d6c0e3341..fc7c437e6 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -340,7 +340,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/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/stm/proofBlockDelimiter.ml b/stm/proofBlockDelimiter.ml
index 23f976120..0af766219 100644
--- a/stm/proofBlockDelimiter.ml
+++ b/stm/proofBlockDelimiter.ml
@@ -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/stm.ml b/stm/stm.ml
index e970a02ee..cbd324f5c 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -92,11 +92,11 @@ let execution_error ?loc state_id msg =
module Hooks = struct
let state_computed, state_computed_hook = Hook.make
- ~default:(fun state_id ~in_cache ->
+ ~default:(fun ~doc:_ state_id ~in_cache ->
feedback ~id:state_id Processed) ()
let state_ready, state_ready_hook = Hook.make
- ~default:(fun state_id -> ()) ()
+ ~default:(fun ~doc:_ state_id -> ()) ()
let forward_feedback, forward_feedback_hook =
let m = Mutex.create () in
@@ -106,7 +106,7 @@ let forward_feedback, forward_feedback_hook =
with e -> Mutex.unlock m; raise e) ()
let unreachable_state, unreachable_state_hook = Hook.make
- ~default:(fun _ _ -> ()) ()
+ ~default:(fun ~doc:_ _ _ -> ()) ()
include Hook
@@ -578,7 +578,7 @@ end = struct (* {{{ *)
| None -> raise Vcs_aux.Expired
let set_state id s =
(get_info id).state <- s;
- if async_proofs_is_master !cur_opt then Hooks.(call state_ready id)
+ if async_proofs_is_master !cur_opt then Hooks.(call state_ready ~doc:dummy_doc (* XXX should be taken in input *) id)
let get_state id = (get_info id).state
let reached id =
let info = get_info id in
@@ -770,6 +770,7 @@ module State : sig
Warning: an optimization in installed_cached requires that state
modifying functions are always executed using this wrapper. *)
val define :
+ doc:doc ->
?safe_id:Stateid.t ->
?redefine:bool -> ?cache:Summary.marshallable ->
?feedback_processed:bool -> (unit -> unit) -> Stateid.t -> unit
@@ -919,7 +920,7 @@ end = struct (* {{{ *)
let e2 = Summary.project_from_summary s2 Global.global_env_summary_tag in
e1 == e2
- let define ?safe_id ?(redefine=false) ?(cache=`No) ?(feedback_processed=true)
+ let define ~doc ?safe_id ?(redefine=false) ?(cache=`No) ?(feedback_processed=true)
f id
=
feedback ~id:id (ProcessingIn !Flags.async_proofs_worker_id);
@@ -938,7 +939,7 @@ end = struct (* {{{ *)
stm_prerr_endline (fun () -> "setting cur id to "^str_id);
cur_id := id;
if feedback_processed then
- Hooks.(call state_computed id ~in_cache:false);
+ Hooks.(call state_computed ~doc id ~in_cache:false);
VCS.reached id;
if Proof_global.there_are_pending_proofs () then
VCS.goals id (Proof_global.get_open_goals ())
@@ -954,7 +955,7 @@ end = struct (* {{{ *)
| Some _, None -> (e, info)
| Some (_,at), Some id -> (e, Stateid.add info ~valid:id at) in
if cache = `Yes || cache = `Shallow then freeze_invalid id ie;
- Hooks.(call unreachable_state id ie);
+ Hooks.(call unreachable_state ~doc id ie);
Exninfo.iraise ie
let init_state = ref None
@@ -1072,7 +1073,7 @@ let stm_vernac_interp ?proof ?route id st { verbose; loc; expr } : Vernacstate.t
let is_filtered_command = function
| VernacResetName _ | VernacResetInitial | VernacBack _
| VernacBackTo _ | VernacRestart | VernacUndo _ | VernacUndoTo _
- | VernacBacktrack _ | VernacAbortAll | VernacAbort _ -> true
+ | VernacAbortAll | VernacAbort _ -> true
| _ -> false
in
let aux_interp st expr =
@@ -1097,7 +1098,6 @@ let stm_vernac_interp ?proof ?route id st { verbose; loc; expr } : Vernacstate.t
module Backtrack : sig
val record : unit -> unit
- val backto : Stateid.t -> unit
(* we could navigate the dag, but this ways easy *)
val branches_of : Stateid.t -> backup
@@ -1122,14 +1122,6 @@ end = struct (* {{{ *)
info.vcs_backup <- backup, branches)
[VCS.current_branch (); VCS.Branch.master]
- let backto oid =
- let info = VCS.get_info oid in
- match info.vcs_backup with
- | None, _ ->
- anomaly Pp.(str"Backtrack.backto "++str(Stateid.to_string oid)++
- str": a state with no vcs_backup.")
- | Some vcs, _ -> VCS.restore vcs
-
let branches_of id =
let info = VCS.get_info id in
match info.vcs_backup with
@@ -1220,7 +1212,6 @@ end = struct (* {{{ *)
match Vcs_.branches vcs with [_] -> `Stop id | _ -> `Cont ())
() id in
oid, VtLater
- | VernacBacktrack (id,_,_)
| VernacBackTo id ->
Stateid.of_int id, VtNow
| _ -> anomaly Pp.(str "incorrect VtMeta classification")
@@ -1362,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 ->
@@ -1476,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));
@@ -1494,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
@@ -1587,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 (* }}} *)
@@ -1597,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
@@ -1644,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
@@ -1657,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
@@ -1764,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
@@ -1779,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
@@ -1902,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)
@@ -1929,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
@@ -2058,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
@@ -2103,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 (* {{{ *)
@@ -2261,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
@@ -2356,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
@@ -2437,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);
@@ -2449,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);
@@ -2522,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
@@ -2611,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
@@ -2632,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 ->
@@ -2725,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 } ->
@@ -2757,9 +2751,7 @@ let snapshot_vio ~doc ldir long_f_dot_vo =
let reset_task_queue = Slaves.reset_task_queue
(* Document building *)
-let process_back_meta_command ~part_of_script ~newtip ~head oid aast w =
- match part_of_script, w with
- | true, w ->
+let process_back_meta_command ~newtip ~head oid aast w =
let id = VCS.new_node ~id:newtip () in
let { mine; others } = Backtrack.branches_of oid in
let valid = VCS.get_branch_pos head in
@@ -2779,16 +2771,7 @@ let process_back_meta_command ~part_of_script ~newtip ~head oid aast w =
VCS.commit id (Alias (oid,aast));
Backtrack.record (); if w == VtNow then ignore(finish ~doc:dummy_doc); `Ok
- | false, VtNow ->
- stm_prerr_endline (fun () -> "undo to state " ^ Stateid.to_string oid);
- Backtrack.backto oid;
- VCS.checkout_shallowest_proof_branch ();
- Reach.known_state ~cache:(VCS.is_interactive ()) oid; `Ok
-
- | false, VtLater ->
- anomaly(str"undo classifier: VtMeta + VtLater must imply part_of_script.")
-
-let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
+let process_transaction ~doc ?(newtip=Stateid.fresh ())
({ verbose; loc; expr } as x) c =
stm_pperr_endline (fun () -> str "{{{ processing: " ++ pr_ast x);
let vcs = VCS.backup () in
@@ -2802,22 +2785,10 @@ let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
(* Meta *)
| VtMeta, _ ->
let id, w = Backtrack.undo_vernac_classifier expr in
- (* Special case Backtrack, as it is never part of a script. See #6240 *)
- let part_of_script = begin match Vernacprop.under_control expr with
- | VernacBacktrack _ -> false
- | _ -> part_of_script
- end in
- process_back_meta_command ~part_of_script ~newtip ~head id x w
+ process_back_meta_command ~newtip ~head id x w
+
(* Query *)
- | VtQuery (false,route), VtNow ->
- let query_sid = VCS.cur_tip () in
- (try
- let st = Vernacstate.freeze_interp_state `No in
- ignore(stm_vernac_interp ~route query_sid st x)
- with e ->
- let e = CErrors.push e in
- Exninfo.iraise (State.exn_on ~valid:Stateid.dummy query_sid e)); `Ok
- | VtQuery (true, route), w ->
+ | VtQuery, w ->
let id = VCS.new_node ~id:newtip () in
let queue =
if !cur_opt.async_proofs_full then `QueryQueue (ref false)
@@ -2829,9 +2800,6 @@ let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
VCS.commit id (mkTransCmd x [] false queue);
Backtrack.record (); if w == VtNow then ignore(finish ~doc:dummy_doc); `Ok
- | VtQuery (false,_), VtLater ->
- anomaly(str"classifier: VtQuery + VtLater must imply part_of_script.")
-
(* Proof *)
| VtStartProof (mode, guarantee, names), w ->
let id = VCS.new_node ~id:newtip () in
@@ -2908,11 +2876,11 @@ let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
let in_proof = not (VCS.Branch.equal head VCS.Branch.master) in
let id = VCS.new_node ~id:newtip () in
let head_id = VCS.get_branch_pos head in
- let _st = Reach.known_state ~cache:`Yes head_id in (* ensure it is ok *)
+ let _st : unit = Reach.known_state ~doc ~cache:`Yes head_id in (* ensure it is ok *)
let step () =
VCS.checkout VCS.Branch.master;
let mid = VCS.get_branch_pos VCS.Branch.master in
- let _st' = Reach.known_state ~cache:(VCS.is_interactive ()) mid in
+ let _st' : unit = Reach.known_state ~doc ~cache:(VCS.is_interactive ()) mid in
let st = Vernacstate.freeze_interp_state `No in
ignore(stm_vernac_interp id st x);
(* Vernac x may or may not start a proof *)
@@ -2938,7 +2906,7 @@ let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
end;
VCS.checkout_shallowest_proof_branch ();
end in
- State.define ~safe_id:head_id ~cache:`Yes step id;
+ State.define ~doc ~safe_id:head_id ~cache:`Yes step id;
Backtrack.record (); `Ok
| VtUnknown, VtLater ->
@@ -3049,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 ())
@@ -3068,19 +3035,14 @@ type focus = {
let query ~doc ~at ~route s =
stm_purify (fun s ->
if Stateid.equal at Stateid.dummy then ignore(finish ~doc:dummy_doc)
- else Reach.known_state ~cache:`Yes at;
+ else Reach.known_state ~doc ~cache:`Yes at;
try
while true do
let { CAst.loc; v=ast } = parse_sentence ~doc at s in
let indentation, strlen = compute_indentation ?loc at in
- CWarnings.set_current_loc loc;
- let clas = Vernac_classifier.classify_vernac ast in
+ let st = State.get_cached at in
let aast = { verbose = true; indentation; strlen; loc; expr = ast } in
- match clas with
- | VtMeta , _ -> (* TODO: can this still happen ? *)
- ignore(process_transaction ~part_of_script:false aast (VtMeta,VtNow))
- | _ ->
- ignore(process_transaction aast (VtQuery (false,route), VtNow))
+ ignore(stm_vernac_interp ~route at st aast)
done;
with
| End_of_input -> ()
@@ -3135,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
@@ -3158,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
@@ -3187,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
@@ -3250,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 a8eb10fb3..aed7274d0 100644
--- a/stm/stm.mli
+++ b/stm/stm.mli
@@ -39,14 +39,25 @@ module AsyncOpts : sig
end
-(** The STM doc type determines some properties such as what
- uncompleted proofs are allowed and recording of aux files. *)
+(** The STM document type [stm_doc_type] determines some properties
+ such as what uncompleted proofs are allowed and what gets recorded
+ to aux files. *)
type stm_doc_type =
- | VoDoc of string
- | VioDoc of string
- | Interactive of DirPath.t
+ | VoDoc of string (* file path *)
+ | VioDoc of string (* file path *)
+ | Interactive of DirPath.t (* module path *)
-(* Main initalization routine *)
+(** Coq initalization options:
+
+ - [doc_type]: Type of document being created.
+
+ - [require_libs]: list of libraries/modules to be pre-loaded at
+ startup. A tuple [(modname,modfrom,import)] is equivalent to [From
+ modfrom Require modname]; [import] works similarly to
+ [Library.require_library_from_dirpath], [Some false] will import
+ the module, [Some true] will additionally export it.
+
+*)
type stm_init_options = {
(* The STM will set some internal flags differently depending on the
specified [doc_type]. This distinction should dissappear at some
@@ -72,12 +83,14 @@ type stm_init_options = {
(** The type of a STM document *)
type doc
+(** [init_core] performs some low-level initalization; should go away
+ in future releases. *)
val init_core : unit -> unit
-(* Starts a new document *)
+(** [new_doc opt] Creates a new document with options [opt] *)
val new_doc : stm_init_options -> doc * Stateid.t
-(* [parse_sentence sid pa] Reads a sentence from [pa] with parsing
+(** [parse_sentence sid pa] Reads a sentence from [pa] with parsing
state [sid] Returns [End_of_input] if the stream ends *)
val parse_sentence : doc:doc -> Stateid.t -> Pcoq.Gram.coq_parsable ->
Vernacexpr.vernac_control CAst.t
@@ -115,14 +128,15 @@ val query : doc:doc ->
type focus = { start : Stateid.t; stop : Stateid.t; tip : Stateid.t }
val edit_at : doc:doc -> Stateid.t -> doc * [ `NewTip | `Focus of focus ]
-(* Evaluates the tip of the current branch *)
+(* [observe doc sid]] Check / execute span [sid] *)
+val observe : doc:doc -> Stateid.t -> doc
+
+(* [finish doc] Fully checks a document up to the "current" tip. *)
val finish : doc:doc -> doc
(* Internal use (fake_ide) only, do not use *)
val wait : doc:doc -> doc
-val observe : doc:doc -> Stateid.t -> doc
-
val stop_worker : string -> unit
(* Joins the entire document. Implies finish, but also checks proofs *)
@@ -249,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
@@ -269,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/vernac_classifier.ml b/stm/vernac_classifier.ml
index 9a8af3a58..c08cc6e36 100644
--- a/stm/vernac_classifier.ml
+++ b/stm/vernac_classifier.ml
@@ -16,8 +16,6 @@ open Vernacexpr
let default_proof_mode () = Proof_global.get_default_proof_mode_name () [@ocaml.warning "-3"]
-let string_of_in_script b = if b then " (inside script)" else ""
-
let string_of_parallel = function
| `Yes (solve,abs) ->
"par" ^ if solve then "solve" else "" ^ if abs then "abs" else ""
@@ -34,7 +32,7 @@ let string_of_vernac_type = function
"ProofStep " ^ string_of_parallel parallel ^
Option.default "" proof_block_detection
| VtProofMode s -> "ProofMode " ^ s
- | VtQuery (b, route) -> "Query " ^ string_of_in_script b ^ " route " ^ string_of_int route
+ | VtQuery -> "Query"
| VtMeta -> "Meta "
let string_of_vernac_when = function
@@ -70,7 +68,7 @@ let classify_vernac e =
| VernacEndProof _ | VernacExactProof _ -> VtQed VtKeep, VtLater
(* Query *)
| VernacShow _ | VernacPrint _ | VernacSearch _ | VernacLocate _
- | VernacCheckMayEval _ -> VtQuery (true,Feedback.default_route), VtLater
+ | VernacCheckMayEval _ -> VtQuery, VtLater
(* ProofStep *)
| VernacProof _
| VernacFocus _ | VernacUnfocus
@@ -145,7 +143,7 @@ let classify_vernac e =
| VernacAddLoadPath _ | VernacRemoveLoadPath _ | VernacAddMLPath _
| VernacChdir _
| VernacCreateHintDb _ | VernacRemoveHints _ | VernacHints _
- | VernacDeclareImplicits _ | VernacArguments _ | VernacArgumentsScope _
+ | VernacArguments _
| VernacReserve _
| VernacGeneralizable _
| VernacSetOpacity _ | VernacSetStrategy _
@@ -183,7 +181,7 @@ let classify_vernac e =
| VernacBack _ | VernacAbortAll
| VernacUndoTo _ | VernacUndo _
| VernacResetName _ | VernacResetInitial
- | VernacBacktrack _ | VernacBackTo _ | VernacRestart -> VtMeta, VtNow
+ | VernacBackTo _ | VernacRestart -> VtMeta, VtNow
(* What are these? *)
| VernacRestoreState _
| VernacWriteState _ -> VtSideff [], VtNow
@@ -205,7 +203,7 @@ let classify_vernac e =
static_control_classifier ~poly e
| VernacFail e -> (* Fail Qed or Fail Lemma must not join/fork the DAG *)
(match static_control_classifier ~poly e with
- | ( VtQuery _ | VtProofStep _ | VtSideff _
+ | ( VtQuery | VtProofStep _ | VtSideff _
| VtProofMode _ | VtMeta), _ as x -> x
| VtQed _, _ ->
VtProofStep { parallel = `No; proof_block_detection = None },
@@ -214,6 +212,6 @@ let classify_vernac e =
in
static_control_classifier ~poly:(Flags.is_universe_polymorphism ()) e
-let classify_as_query = VtQuery (true,Feedback.default_route), VtLater
+let classify_as_query = VtQuery, VtLater
let classify_as_sideeff = VtSideff [], VtLater
let classify_as_proofstep = VtProofStep { parallel = `No; proof_block_detection = None}, VtLater
diff --git a/stm/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/class_tactics.ml b/tactics/class_tactics.ml
index 0260460e6..b11e36bce 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -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/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/equality.mli b/tactics/equality.mli
index c0be917a0..ccf454c3e 100644
--- a/tactics/equality.mli
+++ b/tactics/equality.mli
@@ -80,20 +80,20 @@ val discrConcl : unit Proofview.tactic
val discrHyp : Id.t -> unit Proofview.tactic
val discrEverywhere : evars_flag -> unit Proofview.tactic
val discr_tac : evars_flag ->
- constr with_bindings destruction_arg option -> unit Proofview.tactic
+ constr with_bindings Tactics.destruction_arg option -> unit Proofview.tactic
(* Below, if flag is [None], it takes the value from the dynamic value of the option *)
val inj : inj_flags option -> intro_patterns option -> evars_flag ->
clear_flag -> constr with_bindings -> unit Proofview.tactic
val injClause : inj_flags option -> intro_patterns option -> evars_flag ->
- constr with_bindings destruction_arg option -> unit Proofview.tactic
+ constr with_bindings Tactics.destruction_arg option -> unit Proofview.tactic
val injHyp : inj_flags option -> clear_flag -> Id.t -> unit Proofview.tactic
val injConcl : inj_flags option -> unit Proofview.tactic
val simpleInjClause : inj_flags option -> evars_flag ->
- constr with_bindings destruction_arg option -> unit Proofview.tactic
+ constr with_bindings Tactics.destruction_arg option -> unit Proofview.tactic
-val dEq : keep_proofs:(bool option) -> evars_flag -> constr with_bindings destruction_arg option -> unit Proofview.tactic
-val dEqThen : keep_proofs:(bool option) -> evars_flag -> (clear_flag -> constr -> int -> unit Proofview.tactic) -> constr with_bindings destruction_arg option -> unit Proofview.tactic
+val dEq : keep_proofs:(bool option) -> evars_flag -> constr with_bindings Tactics.destruction_arg option -> unit Proofview.tactic
+val dEqThen : keep_proofs:(bool option) -> evars_flag -> (clear_flag -> constr -> int -> unit Proofview.tactic) -> constr with_bindings Tactics.destruction_arg option -> unit Proofview.tactic
val make_iterated_tuple :
env -> evar_map -> constr -> (constr * types) -> evar_map * (constr * constr * constr)
diff --git a/tactics/hints.ml b/tactics/hints.ml
index a285d6b93..46d162911 100644
--- a/tactics/hints.ml
+++ b/tactics/hints.ml
@@ -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
diff --git a/tactics/inv.ml b/tactics/inv.ml
index 067fc8941..412954989 100644
--- a/tactics/inv.ml
+++ b/tactics/inv.ml
@@ -64,6 +64,11 @@ let var_occurs_in_pf gl id =
type inversion_status = Dep of constr option | NoDep
+type inversion_kind =
+ | SimpleInversion
+ | FullInversion
+ | FullInversionClear
+
let compute_eqn env sigma n i ai =
(mkRel (n-i),get_type_of env sigma (mkRel (n-i)))
@@ -119,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/inv.mli b/tactics/inv.mli
index c63d57af5..9d4ffdd7b 100644
--- a/tactics/inv.mli
+++ b/tactics/inv.mli
@@ -15,6 +15,11 @@ open Tactypes
type inversion_status = Dep of constr option | NoDep
+type inversion_kind =
+ | SimpleInversion
+ | FullInversion
+ | FullInversionClear
+
val inv_clause :
inversion_kind -> or_and_intro_pattern option -> Id.t list ->
quantified_hypothesis -> unit Proofview.tactic
diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml
index 958a205a1..5e81e2d4b 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
@@ -369,9 +369,36 @@ module New = struct
tclTHENSFIRSTn t1 l (tclUNIT())
let tclTHENFIRST t1 t2 =
tclTHENFIRSTn t1 [|t2|]
+
+ let tclBINDFIRST t1 t2 =
+ t1 >>= fun ans ->
+ Proofview.Unsafe.tclGETGOALS >>= fun gls ->
+ match gls with
+ | [] -> tclFAIL 0 (str "Expect at least one goal.")
+ | hd::tl ->
+ Proofview.Unsafe.tclSETGOALS [hd] <*> t2 ans >>= fun ans ->
+ Proofview.Unsafe.tclNEWGOALS tl <*>
+ Proofview.tclUNIT ans
+
let tclTHENLASTn t1 l =
tclTHENS3PARTS t1 [||] (tclUNIT()) l
let tclTHENLAST t1 t2 = tclTHENLASTn t1 [|t2|]
+
+ let option_of_failure f x = try Some (f x) with Failure _ -> None
+
+ let tclBINDLAST t1 t2 =
+ t1 >>= fun ans ->
+ Proofview.Unsafe.tclGETGOALS >>= fun gls ->
+ match option_of_failure List.sep_last gls with
+ | None -> tclFAIL 0 (str "Expect at least one goal.")
+ | Some (last,firstn) ->
+ Proofview.Unsafe.tclSETGOALS [last] <*> t2 ans >>= fun ans ->
+ Proofview.Unsafe.tclGETGOALS >>= fun newgls ->
+ tclEVARMAP >>= fun sigma ->
+ let firstn = Proofview.Unsafe.undefined sigma firstn in
+ Proofview.Unsafe.tclSETGOALS (firstn@newgls) <*>
+ Proofview.tclUNIT ans
+
let tclTHENS t l =
tclINDEPENDENT begin
t <*>Proofview.tclORELSE (* converts the [SizeMismatch] error into an ltac error *)
@@ -479,7 +506,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
@@ -682,7 +709,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 ->
@@ -742,7 +769,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 f0ebac780..340d8fbf3 100644
--- a/tactics/tacticals.mli
+++ b/tactics/tacticals.mli
@@ -196,8 +196,10 @@ module New : sig
(** [tclTHENFIRST tac1 tac2 gls] applies the tactic [tac1] to [gls]
and [tac2] to the first resulting subgoal *)
val tclTHENFIRST : unit tactic -> unit tactic -> unit tactic
+ val tclBINDFIRST : 'a tactic -> ('a -> 'b tactic) -> 'b tactic
val tclTHENLASTn : unit tactic -> unit tactic array -> unit tactic
val tclTHENLAST : unit tactic -> unit tactic -> unit tactic
+ val tclBINDLAST : 'a tactic -> ('a -> 'b tactic) -> 'b tactic
(* [tclTHENS t l = t <*> tclDISPATCH l] *)
val tclTHENS : unit tactic -> unit tactic list -> unit tactic
(* [tclTHENLIST [t1;…;tn]] is [t1<*>…<*>tn] *)
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index 834d73bdd..aae4bc088 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -557,8 +557,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 +615,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
@@ -1159,6 +1165,13 @@ let tactic_infer_flags with_evar = {
Pretyping.fail_evar = not with_evar;
Pretyping.expand_evars = true }
+type 'a core_destruction_arg =
+ | ElimOnConstr of 'a
+ | ElimOnIdent of lident
+ | ElimOnAnonHyp of int
+
+type 'a destruction_arg =
+ clear_flag * 'a core_destruction_arg
let onOpenInductionArg env sigma tac = function
| clear_flag,ElimOnConstr f ->
@@ -1251,7 +1264,6 @@ let cut c =
end
let error_uninstantiated_metas t clenv =
- let t = EConstr.Unsafe.to_constr t in
let na = meta_name clenv.evd (List.hd (Metaset.elements (metavars_of t))) in
let id = match na with Name id -> id | _ -> anomaly (Pp.str "unnamed dependent meta.")
in user_err (str "Cannot find an instance for " ++ Id.print id ++ str".")
@@ -1261,7 +1273,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
@@ -1438,9 +1450,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
@@ -2605,9 +2615,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
@@ -2661,9 +2669,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
@@ -4987,15 +4993,15 @@ let anon_id = Id.of_string "anonymous"
let name_op_to_name name_op object_kind suffix =
let open Proof_global in
let default_gk = (Global, false, object_kind) in
+ let name, gk = match Proof_global.V82.get_current_initial_conclusions () with
+ | (id, (_, gk)) -> Some id, gk
+ | exception NoCurrentProof -> None, default_gk
+ in
match name_op with
- | Some s ->
- (try let _, gk, _ = Pfedit.current_proof_statement () in s, gk
- with NoCurrentProof -> s, default_gk)
- | None ->
- let name, gk =
- try let name, gk, _ = Pfedit.current_proof_statement () in name, gk
- with NoCurrentProof -> anon_id, default_gk in
- add_suffix name suffix, gk
+ | Some s -> s, gk
+ | None ->
+ let name = Option.default anon_id name in
+ add_suffix name suffix, gk
let tclABSTRACT ?(opaque=true) name_op tac =
let s, gk = if opaque
diff --git a/tactics/tactics.mli b/tactics/tactics.mli
index 079baa3ef..7809dbf48 100644
--- a/tactics/tactics.mli
+++ b/tactics/tactics.mli
@@ -95,6 +95,14 @@ val try_intros_until :
(** Apply a tactic on a quantified hypothesis, an hypothesis in context
or a term with bindings *)
+type 'a core_destruction_arg =
+ | ElimOnConstr of 'a
+ | ElimOnIdent of lident
+ | ElimOnAnonHyp of int
+
+type 'a destruction_arg =
+ clear_flag * 'a core_destruction_arg
+
val onInductionArg :
(clear_flag -> constr with_bindings -> unit Proofview.tactic) ->
constr with_bindings destruction_arg -> unit Proofview.tactic
diff --git a/test-suite/bugs/closed/1341.v b/test-suite/bugs/closed/1341.v
index 8c5a38859..79a0a14d7 100644
--- a/test-suite/bugs/closed/1341.v
+++ b/test-suite/bugs/closed/1341.v
@@ -8,7 +8,7 @@ Hypothesis Xst : forall A, Equivalence (Xeq A).
Variable map : forall A B, (A -> B) -> X A -> X B.
-Implicit Arguments map [A B].
+Arguments map [A B].
Goal forall A B (a b:X (B -> A)) (c:X A) (f:A -> B -> A), Xeq _ a b -> Xeq _ b (map f c) -> Xeq _ a (map f c).
intros A B a b c f Hab Hbc.
diff --git a/test-suite/bugs/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/1844.v b/test-suite/bugs/closed/1844.v
index 17eeb3529..c41e45900 100644
--- a/test-suite/bugs/closed/1844.v
+++ b/test-suite/bugs/closed/1844.v
@@ -5,7 +5,7 @@ Definition zeq := Z.eq_dec.
Definition update (A: Set) (x: Z) (v: A) (s: Z -> A) : Z -> A :=
fun y => if zeq x y then v else s y.
-Implicit Arguments update [A].
+Arguments update [A].
Definition ident := Z.
Parameter operator: Set.
diff --git a/test-suite/bugs/closed/1891.v b/test-suite/bugs/closed/1891.v
index 685811176..5024a5bc9 100644
--- a/test-suite/bugs/closed/1891.v
+++ b/test-suite/bugs/closed/1891.v
@@ -3,7 +3,7 @@
Definition f (A: Set) (l: T A): unit := tt.
- Implicit Arguments f [A].
+ Arguments f [A].
Lemma L (x: T unit): (unit -> T unit) -> unit.
Proof.
diff --git a/test-suite/bugs/closed/1951.v b/test-suite/bugs/closed/1951.v
index 7558b0b86..e950554c4 100644
--- a/test-suite/bugs/closed/1951.v
+++ b/test-suite/bugs/closed/1951.v
@@ -42,7 +42,7 @@ match s as a return (S a) with
pair (ind2 a0) IHl) l)
end. (* some induction principle *)
-Implicit Arguments ind [S].
+Arguments ind [S].
Lemma k : a -> Type. (* some ininteresting lemma *)
intro;pattern H;apply ind;intros.
diff --git a/test-suite/bugs/closed/1981.v b/test-suite/bugs/closed/1981.v
index 99952682d..a3d942930 100644
--- a/test-suite/bugs/closed/1981.v
+++ b/test-suite/bugs/closed/1981.v
@@ -1,4 +1,4 @@
-Implicit Arguments ex_intro [A].
+Arguments ex_intro [A].
Goal exists n : nat, True.
eapply ex_intro. exact 0. exact I.
diff --git a/test-suite/bugs/closed/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/closed/2362.v b/test-suite/bugs/closed/2362.v
index febb9c7bb..10e86cd12 100644
--- a/test-suite/bugs/closed/2362.v
+++ b/test-suite/bugs/closed/2362.v
@@ -8,7 +8,7 @@ Class Pointed (M:Type -> Type) :=
Unset Implicit Arguments.
Inductive FPair (A B:Type) (neutral: B) : Type:=
fpair : forall (a:A) (b:B), FPair A B neutral.
-Implicit Arguments fpair [[A] [B] [neutral]].
+Arguments fpair {A B neutral}.
Set Implicit Arguments.
diff --git a/test-suite/bugs/closed/2378.v b/test-suite/bugs/closed/2378.v
index 23a58501f..6d73d58d4 100644
--- a/test-suite/bugs/closed/2378.v
+++ b/test-suite/bugs/closed/2378.v
@@ -63,7 +63,7 @@ Fixpoint lpSat st f: Prop :=
end.
End PropLogic.
-Implicit Arguments lpSat.
+Arguments lpSat : default implicits.
Fixpoint LPTransfo Pred1 Pred2 p2lp (f: LP Pred1): LP Pred2 :=
match f with
@@ -71,7 +71,7 @@ Fixpoint LPTransfo Pred1 Pred2 p2lp (f: LP Pred1): LP Pred2 :=
| LPAnd _ f1 f2 => LPAnd _ (LPTransfo Pred1 Pred2 p2lp f1) (LPTransfo Pred1 Pred2 p2lp f2)
| LPNot _ f1 => LPNot _ (LPTransfo Pred1 Pred2 p2lp f1)
end.
-Implicit Arguments LPTransfo.
+Arguments LPTransfo : default implicits.
Definition addIndex (Ind:Type) (Pred: Ind -> Type) (i: Ind) f :=
LPTransfo (fun p => LPPred _ (existT (fun i => Pred i) i p)) f.
@@ -139,7 +139,7 @@ Definition trProd (State: Type) Ind (Pred: Ind -> Type) (tts: Ind -> TTS State)
{i:Ind & Pred i} -> LP (Predicate _ (TTSIndexedProduct _ Ind tts)) :=
fun p => addIndex Ind _ (projS1 p) (tr (projS1 p) (projS2 p)).
-Implicit Arguments trProd.
+Arguments trProd : default implicits.
Require Import Setoid.
Theorem satTrProd:
diff --git a/test-suite/bugs/closed/2404.v b/test-suite/bugs/closed/2404.v
index 8ac696e91..f6ec67601 100644
--- a/test-suite/bugs/closed/2404.v
+++ b/test-suite/bugs/closed/2404.v
@@ -22,13 +22,13 @@ Section Derived.
Definition bexportw := exportw base.
Definition bwweak := wweak base.
- Implicit Arguments bexportw [a b].
+ Arguments bexportw [a b].
Inductive RstarSetProof {I : Type} (T : I -> I -> Type) : I -> I -> Type :=
starReflS : forall a, RstarSetProof T a a
| starTransS : forall i j k, T i j -> (RstarSetProof T j k) -> RstarSetProof T i k.
-Implicit Arguments starTransS [I T i j k].
+Arguments starTransS [I T i j k].
Definition RstarInv {A : Set} (rel : relation A) : A -> A -> Type := (flip (RstarSetProof (flip rel))).
diff --git a/test-suite/bugs/opened/2456.v b/test-suite/bugs/closed/2456.v
index 6cca5c9fb..e5a392c4d 100644
--- a/test-suite/bugs/opened/2456.v
+++ b/test-suite/bugs/closed/2456.v
@@ -6,7 +6,7 @@ Parameter Patch : nat -> nat -> Set.
Inductive Catch (from to : nat) : Type
:= MkCatch : forall (p : Patch from to),
Catch from to.
-Implicit Arguments MkCatch [from to].
+Arguments MkCatch [from to].
Inductive CatchCommute5
: forall {from mid1 mid2 to : nat},
@@ -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/closed/2584.v b/test-suite/bugs/closed/2584.v
index ef2e4e355..b5a723b47 100644
--- a/test-suite/bugs/closed/2584.v
+++ b/test-suite/bugs/closed/2584.v
@@ -8,7 +8,7 @@ Inductive res (A: Type) : Type :=
| OK: A -> res A
| Error: err -> res A.
-Implicit Arguments Error [A].
+Arguments Error [A].
Set Printing Universes.
diff --git a/test-suite/bugs/closed/2667.v b/test-suite/bugs/closed/2667.v
index 0631e5358..0e6d0108c 100644
--- a/test-suite/bugs/closed/2667.v
+++ b/test-suite/bugs/closed/2667.v
@@ -1,11 +1,11 @@
-(* Check that extra arguments to Arguments Scope do not disturb use of *)
+(* Check that extra arguments to Arguments do not disturb use of *)
(* scopes in constructors *)
Inductive stmt : Type := Sskip: stmt | Scall : nat -> stmt.
Bind Scope Cminor with stmt.
(* extra argument is ok because of possible coercion to funclass *)
-Arguments Scope Scall [_ Cminor ].
+Arguments Scall _ _%Cminor : extra scopes.
(* extra argument is ok because of possible coercion to funclass *)
Fixpoint f (c: stmt) : Prop := match c with Scall _ => False | _ => False end.
diff --git a/test-suite/bugs/closed/2729.v b/test-suite/bugs/closed/2729.v
index 7929b8810..c9d65c12c 100644
--- a/test-suite/bugs/closed/2729.v
+++ b/test-suite/bugs/closed/2729.v
@@ -82,8 +82,8 @@ Inductive SequenceBase (pu : PatchUniverse)
(p : pu_type from mid)
(qs : SequenceBase pu mid to),
SequenceBase pu from to.
-Implicit Arguments Nil [pu cxt].
-Implicit Arguments Cons [pu from mid to].
+Arguments Nil [pu cxt].
+Arguments Cons [pu from mid to].
Program Fixpoint insertBase {pu : PatchUniverse}
{from mid to : NameSet}
diff --git a/test-suite/bugs/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/closed/2830.v b/test-suite/bugs/closed/2830.v
index bb607b785..07a5cf91a 100644
--- a/test-suite/bugs/closed/2830.v
+++ b/test-suite/bugs/closed/2830.v
@@ -49,9 +49,9 @@ Record ageable_facts (A:Type) (level: A -> nat) (age1:A -> option A) :=
; af_level2 : forall x y, age1 x = Some y -> level x = S (level y)
}.
-Implicit Arguments af_unage [[A] [level] [age1]].
-Implicit Arguments af_level1 [[A] [level] [age1]].
-Implicit Arguments af_level2 [[A] [level] [age1]].
+Arguments af_unage {A level age1}.
+Arguments af_level1 {A level age1}.
+Arguments af_level2 {A level age1}.
Class ageable (A:Type) := mkAgeable
{ level : A -> nat
@@ -77,7 +77,7 @@ Coercion app_pred : pred >-> Funclass.
Global Opaque pred.
Definition derives {A} `{ageable A} (P Q:pred A) := forall a:A, P a -> Q a.
-Implicit Arguments derives.
+Arguments derives : default implicits.
Program Definition andp {A} `{ageable A} (P Q:pred A) : pred A :=
fun a:A => P a /\ Q a.
@@ -170,7 +170,7 @@ Class Functor `(C:Category) `(D:Category) (im : C -> D) := {
fmap g ∘ fmap f ≈ fmap (g ∘ f)
}.
Coercion functor_im : Functor >-> Funclass.
-Implicit Arguments fmap [Object Hom C Object0 Hom0 D im a b].
+Arguments fmap [Object Hom C Object0 Hom0 D im] _ [a b].
Add Parametric Morphism `(C:Category) `(D:Category)
(Im:C->D) (F:Functor C D Im) (a b:C) : (@fmap _ _ C _ _ D Im F a b)
diff --git a/test-suite/bugs/closed/3068.v b/test-suite/bugs/closed/3068.v
index 79671ce93..9811733dc 100644
--- a/test-suite/bugs/closed/3068.v
+++ b/test-suite/bugs/closed/3068.v
@@ -33,7 +33,7 @@ Section Counted_list.
End Counted_list.
-Implicit Arguments counted_def_nth [A n].
+Arguments counted_def_nth [A n].
Section Finite_nat_set.
diff --git a/test-suite/bugs/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/3513.v b/test-suite/bugs/closed/3513.v
index 1f0f3b0da..a1d0b9107 100644
--- a/test-suite/bugs/closed/3513.v
+++ b/test-suite/bugs/closed/3513.v
@@ -21,7 +21,7 @@ Section ILogic_Fun.
Local Instance ILFun_Ops : ILogicOps (@ILFunFrm T _ Frm _) := admit.
Definition ILFun_ILogic : ILogic (@ILFunFrm T _ Frm _) := admit.
End ILogic_Fun.
-Implicit Arguments ILFunFrm [[ILOps] [e]].
+Arguments ILFunFrm _ {e} _ {ILOps}.
Instance ILogicOps_Prop : ILogicOps Prop | 2 := {| lentails P Q := (P : Prop) -> Q;
ltrue := True;
land P Q := P /\ Q;
diff --git a/test-suite/bugs/closed/3647.v b/test-suite/bugs/closed/3647.v
index f5a22bd50..e91c004c7 100644
--- a/test-suite/bugs/closed/3647.v
+++ b/test-suite/bugs/closed/3647.v
@@ -26,7 +26,7 @@ Record morphism T T' `{e : type T} `{e' : type T'} :=
mkMorph {
morph :> T -> T';
morph_resp : setoid_resp morph}.
-Implicit Arguments mkMorph [T T' e e0 e' e1].
+Arguments mkMorph [T T' e0 e e1 e'].
Infix "-s>" := morphism (at level 45, right associativity).
Section Morphisms.
Context {S T U V} `{eS : type S} `{eT : type T} `{eU : type U} `{eV : type V}.
@@ -334,8 +334,8 @@ Section ILogic_Fun.
End ILogic_Fun.
-Implicit Arguments ILFunFrm [[ILOps] [e]].
-Implicit Arguments mkILFunFrm [T Frm ILOps].
+Arguments ILFunFrm _ {e} _ {ILOps}.
+Arguments mkILFunFrm [T] _ [Frm ILOps].
Program Definition ILFun_eq {T R} {ILOps: ILogicOps R} {ILogic: ILogic R} (P : T -> R) :
@ILFunFrm T _ R ILOps :=
diff --git a/test-suite/bugs/closed/3732.v b/test-suite/bugs/closed/3732.v
index 09f1149c2..13d62b8ff 100644
--- a/test-suite/bugs/closed/3732.v
+++ b/test-suite/bugs/closed/3732.v
@@ -16,7 +16,7 @@ Section machine.
| Inj : forall G, Prop -> propX G
| ExistsX : forall G A, propX (A :: G) -> propX G.
- Implicit Arguments Inj [G].
+ Arguments Inj [G].
Definition PropX := propX nil.
Fixpoint last (G : list Type) : Type.
diff --git a/test-suite/bugs/closed/4095.v b/test-suite/bugs/closed/4095.v
index 8d7dfbd49..bc9380f90 100644
--- a/test-suite/bugs/closed/4095.v
+++ b/test-suite/bugs/closed/4095.v
@@ -23,7 +23,7 @@ Section ILogic_Fun.
Local Instance ILFun_Ops : ILogicOps (@ILFunFrm T _ Frm _) := admit.
Definition ILFun_ILogic : ILogic (@ILFunFrm T _ Frm _) := admit.
End ILogic_Fun.
-Implicit Arguments ILFunFrm [[ILOps] [e]].
+Arguments ILFunFrm _ {e} _ {ILOps}.
Instance ILogicOps_Prop : ILogicOps Prop | 2 := {| lentails P Q := (P : Prop) -> Q;
ltrue := True;
land P Q := P /\ Q;
diff --git a/test-suite/bugs/closed/4865.v b/test-suite/bugs/closed/4865.v
index c5bf3289b..da4e53aab 100644
--- a/test-suite/bugs/closed/4865.v
+++ b/test-suite/bugs/closed/4865.v
@@ -48,5 +48,5 @@ Fail Check g 0 0 1. (* 2nd 0 in bool *)
Fixpoint arr n := match n with 0%nat => nat | S n => nat -> arr n end.
Fixpoint lam n : arr n := match n with 0%nat => 0%nat | S n => fun x => lam n end.
Notation "0" := true.
-Arguments Scope lam [nat_scope nat_scope].
+Arguments lam _%nat_scope _%nat_scope : extra scopes.
Check (lam 1 0).
diff --git a/test-suite/bugs/closed/6631.v b/test-suite/bugs/closed/6631.v
new file mode 100644
index 000000000..100dc13fc
--- /dev/null
+++ b/test-suite/bugs/closed/6631.v
@@ -0,0 +1,7 @@
+Require Import Coq.derive.Derive.
+
+Derive f SuchThat (f = 1 + 1) As feq.
+Proof.
+ transitivity 2; [refine (eq_refl 2)|].
+ transitivity 2.
+ 2:abstract exact (eq_refl 2).
diff --git a/test-suite/bugs/closed/6956.v b/test-suite/bugs/closed/6956.v
new file mode 100644
index 000000000..ee21adbbf
--- /dev/null
+++ b/test-suite/bugs/closed/6956.v
@@ -0,0 +1,13 @@
+(** Used to trigger an anomaly with VM compilation *)
+
+Set Universe Polymorphism.
+
+Inductive t A : nat -> Type :=
+| nil : t A 0
+| cons : forall (h : A) (n : nat), t A n -> t A (S n).
+
+Definition case0 {A} (P : t A 0 -> Type) (H : P (nil A)) v : P v :=
+match v with
+| nil _ => H
+| _ => fun devil => False_ind (@IDProp) devil
+end.
diff --git a/test-suite/bugs/closed/7092.v b/test-suite/bugs/closed/7092.v
new file mode 100644
index 000000000..d90de8b93
--- /dev/null
+++ b/test-suite/bugs/closed/7092.v
@@ -0,0 +1,70 @@
+(* Examples matching fix/cofix in Ltac pattern-matching *)
+
+Goal True.
+lazymatch (eval cbv delta [Nat.add] in Nat.add) with
+| (fix F (n : nat) (v : ?A) {struct n} : @?P n v
+ := match n with
+ | O => @?O_case v
+ | S n' => @?S_case n' v F
+ end)
+ =>
+ unify A nat;
+ unify P (fun _ _ : nat => nat);
+ unify O_case (fun v : nat => v);
+ unify S_case (fun (p : nat) (m : nat) (add : nat -> nat -> nat)
+ => S (add p m))
+ end.
+Abort.
+
+Fixpoint f l n := match n with 0 => 0 | S n => g n (cons n l) end
+with g n l := match n with 0 => 1 | S n => f (cons 0 l) n end.
+
+Goal True.
+
+lazymatch (eval cbv delta [f] in f) with
+| fix myf (l : ?L) (n : ?N) {struct n} : nat :=
+ match n as _ with
+ | 0 => ?Z
+ | S n0 => @?S myf myg n0 l
+ end
+ with myg (n' : ?N') (l' : ?L') {struct n'} : nat :=
+ match n' as _ with
+ | 0 => ?Z'
+ | S n0' => @?S' myf myg n0' l'
+ end
+ for myf =>
+ unify L (list nat);
+ unify L' (list nat);
+ unify N nat;
+ unify N' nat;
+ unify Z 0;
+ unify Z' 1;
+ unify S (fun (f : L -> N -> nat) (g : N -> L -> nat) n l => g n (cons n l));
+ unify S' (fun (f : L -> N -> nat) (g : N -> L -> nat) (n:N) l => f (cons 0 l) n)
+end.
+
+Abort.
+
+CoInductive S1 := C1 : nat -> S2 -> S1 with S2 := C2 : bool -> S1 -> S2.
+
+CoFixpoint f' n l := C1 n (g' (cons n l) n n)
+with g' l n p := C2 true (f' (S n) l).
+
+Goal True.
+
+lazymatch (eval cbv delta [f'] in f') with
+| cofix myf (n : ?N) (l : ?L) : ?T := @?X n g l
+ with g (l' : ?L') (n' : ?N') (p' : ?N'') : ?T' := @?X' n' myf l'
+ for myf =>
+ unify L (list nat);
+ unify L' (list nat);
+ unify N nat;
+ unify N' nat;
+ unify N'' nat;
+ unify T S1;
+ unify T' S2;
+ unify X (fun n g l => C1 n (g (cons n l) n n));
+ unify X' (fun n f (l : list nat) => C2 true (f (S n) l))
+end.
+
+Abort.
diff --git a/test-suite/bugs/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/3295.v b/test-suite/bugs/opened/3295.v
index 2a156e333..c09649de7 100644
--- a/test-suite/bugs/opened/3295.v
+++ b/test-suite/bugs/opened/3295.v
@@ -5,7 +5,7 @@ Class lops := lmk_ops {
weq: relation car
}.
-Implicit Arguments car [].
+Arguments car : clear implicits.
Coercion car: lops >-> Sortclass.
@@ -23,7 +23,7 @@ Class ops := mk_ops {
dot: forall n m p, mor n m -> mor m p -> mor n p
}.
Coercion mor: ops >-> Funclass.
-Implicit Arguments ob [].
+Arguments ob : clear implicits.
Instance dot_weq `{ops} n m p: Proper (weq ==> weq ==> weq) (dot n m p).
Proof.
diff --git a/test-suite/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/complexity/injection.v b/test-suite/complexity/injection.v
index 08f489d75..a76fa19d3 100644
--- a/test-suite/complexity/injection.v
+++ b/test-suite/complexity/injection.v
@@ -47,7 +47,7 @@ Parameter mkJoinmap : forall (key: Type) (t: Type) (j: joinable t),
joinmap key j.
Parameter ADMIT: forall p: Prop, p.
-Implicit Arguments ADMIT [p].
+Arguments ADMIT [p].
Module Share.
Parameter jb : joinable bool.
diff --git a/test-suite/coq-makefile/coqdoc1/run.sh b/test-suite/coq-makefile/coqdoc1/run.sh
index dc5a500db..88237815b 100755
--- a/test-suite/coq-makefile/coqdoc1/run.sh
+++ b/test-suite/coq-makefile/coqdoc1/run.sh
@@ -9,7 +9,15 @@ make html mlihtml
make install DSTROOT="$PWD/tmp"
make install-doc DSTROOT="$PWD/tmp"
#make debug
-(for d in `find tmp -name user-contrib` ; do pushd $d >/dev/null && find . && popd >/dev/null; done) | sort -u > actual
+
+# to learn about <(cmd) see https://www.gnu.org/software/bash/manual/html_node/Process-Substitution.html
+(
+ while IFS= read -r -d '' d
+ do
+ pushd "$d" >/dev/null && find . && popd >/dev/null
+ done < <(find tmp -name user-contrib -print0)
+) | sort -u > actual
+
sort -u > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/coqdoc2/run.sh b/test-suite/coq-makefile/coqdoc2/run.sh
index dc5a500db..5811dd17e 100755
--- a/test-suite/coq-makefile/coqdoc2/run.sh
+++ b/test-suite/coq-makefile/coqdoc2/run.sh
@@ -9,7 +9,13 @@ make html mlihtml
make install DSTROOT="$PWD/tmp"
make install-doc DSTROOT="$PWD/tmp"
#make debug
-(for d in `find tmp -name user-contrib` ; do pushd $d >/dev/null && find . && popd >/dev/null; done) | sort -u > actual
+(
+ while IFS= read -r -d '' d
+ do
+ pushd "$d" >/dev/null && find . && popd >/dev/null
+ done < <(find tmp -name user-contrib -print0)
+) | sort -u > actual
+
sort -u > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/findlib-package/run.sh b/test-suite/coq-makefile/findlib-package/run.sh
index 5b24df639..5cab400cc 100755
--- a/test-suite/coq-makefile/findlib-package/run.sh
+++ b/test-suite/coq-makefile/findlib-package/run.sh
@@ -7,7 +7,8 @@ export OCAMLPATH=$OCAMLPATH:$PWD/findlib
if which cygpath 2>/dev/null; then
# the only way I found to pass OCAMLPATH on win is to have it contain
# only one entry
- export OCAMLPATH=`cygpath -w $PWD/findlib`
+ OCAMLPATH=$(cygpath -w "$PWD"/findlib)
+ export OCAMLPATH
fi
make -C findlib/foo clean
coq_makefile -f _CoqProject -o Makefile
diff --git a/test-suite/coq-makefile/mlpack1/run.sh b/test-suite/coq-makefile/mlpack1/run.sh
index 03df9cf05..bbd2fc460 100755
--- a/test-suite/coq-makefile/mlpack1/run.sh
+++ b/test-suite/coq-makefile/mlpack1/run.sh
@@ -8,7 +8,7 @@ make
make html mlihtml
make install DSTROOT="$PWD/tmp"
#make debug
-(cd `find tmp -name user-contrib` && find .) | sort > actual
+(cd "$(find tmp -name user-contrib)" && find .) | sort > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/mlpack2/run.sh b/test-suite/coq-makefile/mlpack2/run.sh
index 03df9cf05..bbd2fc460 100755
--- a/test-suite/coq-makefile/mlpack2/run.sh
+++ b/test-suite/coq-makefile/mlpack2/run.sh
@@ -8,7 +8,7 @@ make
make html mlihtml
make install DSTROOT="$PWD/tmp"
#make debug
-(cd `find tmp -name user-contrib` && find .) | sort > actual
+(cd "$(find tmp -name user-contrib)" && find .) | sort > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/multiroot/run.sh b/test-suite/coq-makefile/multiroot/run.sh
index d3bb53106..45bf1481d 100755
--- a/test-suite/coq-makefile/multiroot/run.sh
+++ b/test-suite/coq-makefile/multiroot/run.sh
@@ -11,7 +11,12 @@ make html mlihtml
make install DSTROOT="$PWD/tmp"
make install-doc DSTROOT="$PWD/tmp"
#make debug
-(for d in `find tmp -name user-contrib` ; do pushd $d >/dev/null && find . && popd >/dev/null; done) | sort -u > actual
+(
+ while IFS= read -r -d '' d
+ do
+ pushd "$d" >/dev/null && find . && popd >/dev/null
+ done < <(find tmp -name user-contrib -print0)
+) | sort -u > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/native1/run.sh b/test-suite/coq-makefile/native1/run.sh
index 89bafe9ad..8f9ab9a71 100755
--- a/test-suite/coq-makefile/native1/run.sh
+++ b/test-suite/coq-makefile/native1/run.sh
@@ -1,17 +1,17 @@
#!/usr/bin/env bash
-NATIVECOMP=`grep "let no_native_compiler = false" ../../../config/coq_config.ml`||true
-if [[ `which ocamlopt` && $NATIVECOMP ]]; then
+NATIVECOMP=$(grep "let no_native_compiler = false" ../../../config/coq_config.ml)||true
+if [[ $(which ocamlopt) && $NATIVECOMP ]]; then
. ../template/init.sh
-
+
coq_makefile -f _CoqProject -o Makefile
cat Makefile.conf
make
make html mlihtml
make install DSTROOT="$PWD/tmp"
#make debug
-(cd `find tmp -name user-contrib` && find .) | sort > actual
+(cd "$(find tmp -name user-contrib)" && find .) | sort > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/plugin1/run.sh b/test-suite/coq-makefile/plugin1/run.sh
index 5433d9e92..1e2bd979b 100755
--- a/test-suite/coq-makefile/plugin1/run.sh
+++ b/test-suite/coq-makefile/plugin1/run.sh
@@ -9,7 +9,7 @@ make
make html mlihtml
make install DSTROOT="$PWD/tmp"
#make debug
-(cd `find tmp -name user-contrib` && find .) | sort > actual
+(cd "$(find tmp -name user-contrib)" && find .) | sort > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/plugin2/run.sh b/test-suite/coq-makefile/plugin2/run.sh
index 5433d9e92..1e2bd979b 100755
--- a/test-suite/coq-makefile/plugin2/run.sh
+++ b/test-suite/coq-makefile/plugin2/run.sh
@@ -9,7 +9,7 @@ make
make html mlihtml
make install DSTROOT="$PWD/tmp"
#make debug
-(cd `find tmp -name user-contrib` && find .) | sort > actual
+(cd "$(find tmp -name user-contrib)" && find .) | sort > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/plugin3/run.sh b/test-suite/coq-makefile/plugin3/run.sh
index 5433d9e92..1e2bd979b 100755
--- a/test-suite/coq-makefile/plugin3/run.sh
+++ b/test-suite/coq-makefile/plugin3/run.sh
@@ -9,7 +9,7 @@ make
make html mlihtml
make install DSTROOT="$PWD/tmp"
#make debug
-(cd `find tmp -name user-contrib` && find .) | sort > actual
+(cd "$(find tmp -name user-contrib)" && find .) | sort > actual
sort > desired <<EOT
.
./test
diff --git a/test-suite/coq-makefile/quick2vo/run.sh b/test-suite/coq-makefile/quick2vo/run.sh
index 9e681223b..dda51dd2e 100755
--- a/test-suite/coq-makefile/quick2vo/run.sh
+++ b/test-suite/coq-makefile/quick2vo/run.sh
@@ -1,11 +1,11 @@
#!/usr/bin/env bash
-a=`uname`
+a=$(uname)
. ../template/init.sh
coq_makefile -f _CoqProject -o Makefile
# vio2vo is broken on Windows (#6720)
-if [ "$a" = "Darwin" -o "$a" = "Linux" ]; then
+if [ "$a" = "Darwin" ] || [ "$a" = "Linux" ]; then
make quick2vo J=2
test -f theories/test.vo
make validate
diff --git a/test-suite/coq-makefile/template/init.sh b/test-suite/coq-makefile/template/init.sh
index e19d168cf..2e066d30d 100755
--- a/test-suite/coq-makefile/template/init.sh
+++ b/test-suite/coq-makefile/template/init.sh
@@ -1,10 +1,11 @@
+#!/bin/sh
. ../template/path-init.sh
rm -rf _test
mkdir _test
find . -maxdepth 1 -not -name . -not -name _test -exec cp -r '{}' -t _test ';'
-cd _test
+cd _test || exit 1
mkdir -p src
mkdir -p theories/sub
diff --git a/test-suite/coq-makefile/template/path-init.sh b/test-suite/coq-makefile/template/path-init.sh
index dd19ab2b1..c79b56652 100755
--- a/test-suite/coq-makefile/template/path-init.sh
+++ b/test-suite/coq-makefile/template/path-init.sh
@@ -1,3 +1,4 @@
+#!/bin/sh
set -e
set -o pipefail
diff --git a/test-suite/coq-makefile/timing/precomputed-time-tests/run.sh b/test-suite/coq-makefile/timing/precomputed-time-tests/run.sh
index a918cceb6..9f3b648aa 100755
--- a/test-suite/coq-makefile/timing/precomputed-time-tests/run.sh
+++ b/test-suite/coq-makefile/timing/precomputed-time-tests/run.sh
@@ -4,7 +4,8 @@ set -x
set -e
cd "$(dirname "${BASH_SOURCE[0]}")"
-export COQLIB="$(cd ../../../.. && pwd)"
+COQLIB="$(cd ../../../.. && pwd)"
+export COQLIB
-./001-correct-diff-sorting-order/run.sh || exit $?
-./002-single-file-sorting/run.sh || exit $?
+./001-correct-diff-sorting-order/run.sh
+./002-single-file-sorting/run.sh
diff --git a/test-suite/coq-makefile/timing/run.sh b/test-suite/coq-makefile/timing/run.sh
index aa6b0a9a4..11a04d5c2 100755
--- a/test-suite/coq-makefile/timing/run.sh
+++ b/test-suite/coq-makefile/timing/run.sh
@@ -40,7 +40,7 @@ INFINITY_REPLACEMENT="+.%" # assume that if the before time is zero, we expected
TO_SED_IN_BOTH=(
-e s"/${INFINITY}/${INFINITY_REPLACEMENT}/g" # Whether or not something shows up as ∞ depends on whether a time registers as 0.s or as 0.001s, so we can't rely on this being consistent
- -e s":|\s*N/A\s*$:| ${INFINITY_REPLACEMENT}:g" # Whether or not something shows up as N/A depends on whether a time registers as 0.s or as 0.001s, so we can't rely on this being consistent
+ -e s':|\s*N/A\s*$:| '"${INFINITY_REPLACEMENT}"':g' # Whether or not something shows up as N/A depends on whether a time registers as 0.s or as 0.001s, so we can't rely on this being consistent
-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
@@ -58,16 +58,14 @@ TO_SED_IN_PER_LINE=(
-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 ext in "" .desired; do
- for file in time-of-build-before.log time-of-build-after.log time-of-build-both.log; do
- cat ${file}${ext} | grep -v 'warning: undefined variable' | sed "${TO_SED_IN_BOTH[@]}" "${TO_SED_IN_PER_FILE[@]}" > ${file}${ext}.processed
- done
-done
for file in time-of-build-before.log time-of-build-after.log time-of-build-both.log; do
- echo "cat $file"
- cat "$file"
- echo
- diff -u $file.desired.processed $file.processed || exit $?
+ for ext in "" .desired; do
+ grep -v 'warning: undefined variable' < ${file}${ext} | sed "${TO_SED_IN_BOTH[@]}" "${TO_SED_IN_PER_FILE[@]}" > ${file}${ext}.processed
+ done
+ echo "cat $file"
+ cat "$file"
+ echo
+ diff -u $file.desired.processed $file.processed || exit $?
done
cd ../per-file-before
@@ -92,13 +90,12 @@ echo "cat A.v.timing.diff"
cat A.v.timing.diff
echo
+file=A.v.timing.diff
+
for ext in "" .desired; do
- for file in A.v.timing.diff; do
- cat ${file}${ext} | sed "${TO_SED_IN_BOTH[@]}" "${TO_SED_IN_PER_LINE[@]}" | sort > ${file}${ext}.processed
- done
-done
-for file in A.v.timing.diff; do
- diff -u $file.desired.processed $file.processed || exit $?
+ sed "${TO_SED_IN_BOTH[@]}" "${TO_SED_IN_PER_LINE[@]}" < "${file}${ext}" | sort > "${file}${ext}.processed"
done
+diff -u "$file.desired.processed" "$file.processed" || exit $?
+
exit 0
diff --git a/test-suite/coq-makefile/uninstall1/run.sh b/test-suite/coq-makefile/uninstall1/run.sh
index 5354f794f..fc95d84b9 100755
--- a/test-suite/coq-makefile/uninstall1/run.sh
+++ b/test-suite/coq-makefile/uninstall1/run.sh
@@ -11,7 +11,12 @@ make install-doc DSTROOT="$PWD/tmp"
make uninstall DSTROOT="$PWD/tmp"
make uninstall-doc DSTROOT="$PWD/tmp"
#make debug
-(for d in `find tmp -name user-contrib` ; do pushd $d >/dev/null && find . && popd >/dev/null; done) | sort -u > actual
+(
+ while IFS= read -r -d '' d
+ do
+ pushd "$d" >/dev/null && find . && popd >/dev/null
+ done < <(find tmp -name user-contrib -print0)
+) | sort -u > actual
sort -u > desired <<EOT
.
EOT
diff --git a/test-suite/coq-makefile/uninstall2/run.sh b/test-suite/coq-makefile/uninstall2/run.sh
index 5354f794f..fc95d84b9 100755
--- a/test-suite/coq-makefile/uninstall2/run.sh
+++ b/test-suite/coq-makefile/uninstall2/run.sh
@@ -11,7 +11,12 @@ make install-doc DSTROOT="$PWD/tmp"
make uninstall DSTROOT="$PWD/tmp"
make uninstall-doc DSTROOT="$PWD/tmp"
#make debug
-(for d in `find tmp -name user-contrib` ; do pushd $d >/dev/null && find . && popd >/dev/null; done) | sort -u > actual
+(
+ while IFS= read -r -d '' d
+ do
+ pushd "$d" >/dev/null && find . && popd >/dev/null
+ done < <(find tmp -name user-contrib -print0)
+) | sort -u > actual
sort -u > desired <<EOT
.
EOT
diff --git a/test-suite/coq-makefile/vio2vo/run.sh b/test-suite/coq-makefile/vio2vo/run.sh
index 85656da41..e555d62f3 100755
--- a/test-suite/coq-makefile/vio2vo/run.sh
+++ b/test-suite/coq-makefile/vio2vo/run.sh
@@ -1,12 +1,12 @@
#!/usr/bin/env bash
-a=`uname`
+a=$(uname)
. ../template/init.sh
coq_makefile -f _CoqProject -o Makefile
make quick
# vio2vo is broken on Windows (#6720)
-if [ "$a" = "Darwin" -o "$a" = "Linux" ]; then
+if [ "$a" = "Darwin" ] || [ "$a" = "Linux" ]; then
make vio2vo J=2
test -f theories/test.vo
make validate
diff --git a/test-suite/failure/check.v b/test-suite/failure/check.v
index a148ebe8e..0ef4b417a 100644
--- a/test-suite/failure/check.v
+++ b/test-suite/failure/check.v
@@ -1,3 +1,3 @@
-Implicit Arguments eq [A].
+Arguments eq [A].
Fail Check (bool = true).
diff --git a/test-suite/misc/deps-checksum.sh b/test-suite/misc/deps-checksum.sh
index e07612b84..a15a8fbee 100755
--- a/test-suite/misc/deps-checksum.sh
+++ b/test-suite/misc/deps-checksum.sh
@@ -1,3 +1,4 @@
+#!/bin/sh
rm -f misc/deps/A/*.vo misc/deps/B/*.vo
$coqc -R misc/deps/A A misc/deps/A/A.v
$coqc -R misc/deps/B A misc/deps/B/A.v
diff --git a/test-suite/misc/deps-order.sh b/test-suite/misc/deps-order.sh
index 299f49469..6bb2ba2da 100755
--- a/test-suite/misc/deps-order.sh
+++ b/test-suite/misc/deps-order.sh
@@ -1,17 +1,18 @@
+#!/bin/sh
# Check that both coqdep and coqtop/coqc supports -R
# Check that both coqdep and coqtop/coqc takes the later -R
# See bugs 2242, 2337, 2339
rm -f misc/deps/lib/*.vo misc/deps/client/*.vo
-tmpoutput=`mktemp /tmp/coqcheck.XXXXXX`
-$coqdep -R misc/deps/lib lib -R misc/deps/client client misc/deps/client/bar.v 2>&1 | head -n 1 > $tmpoutput
-diff -u --strip-trailing-cr misc/deps/deps.out $tmpoutput 2>&1
+tmpoutput=$(mktemp /tmp/coqcheck.XXXXXX)
+$coqdep -R misc/deps/lib lib -R misc/deps/client client misc/deps/client/bar.v 2>&1 | head -n 1 > "$tmpoutput"
+diff -u --strip-trailing-cr misc/deps/deps.out "$tmpoutput" 2>&1
R=$?
times
$coqc -R misc/deps/lib lib misc/deps/lib/foo.v 2>&1
$coqc -R misc/deps/lib lib -R misc/deps/client client misc/deps/client/foo.v 2>&1
$coqtop -R misc/deps/lib lib -R misc/deps/client client -load-vernac-source misc/deps/client/bar.v 2>&1
S=$?
-if [ $R = 0 -a $S = 0 ]; then
+if [ $R = 0 ] && [ $S = 0 ]; then
printf "coqdep and coqtop agree\n"
exit 0
else
diff --git a/test-suite/misc/deps-utf8.sh b/test-suite/misc/deps-utf8.sh
index 13e264c09..acb45b229 100755
--- a/test-suite/misc/deps-utf8.sh
+++ b/test-suite/misc/deps-utf8.sh
@@ -1,15 +1,16 @@
+#!/bin/sh
# Check reading directories matching non pure ascii idents
# See bug #5715 (utf-8 working on macos X and linux)
# Windows is still not compliant
-a=`uname`
-if [ "$a" = "Darwin" -o "$a" = "Linux" ]; then
+a=$(uname)
+if [ "$a" = "Darwin" ] || [ "$a" = "Linux" ]; then
rm -f misc/deps/théorèmes/*.v
-tmpoutput=`mktemp /tmp/coqcheck.XXXXXX`
+tmpoutput=$(mktemp /tmp/coqcheck.XXXXXX)
$coqc -R misc/deps AlphaBêta misc/deps/αβ/γδ.v
R=$?
$coqtop -R misc/deps AlphaBêta -load-vernac-source misc/deps/αβ/εζ.v
S=$?
-if [ $R = 0 -a $S = 0 ]; then
+if [ $R = 0 ] && [ $S = 0 ]; then
exit 0
else
exit 1
diff --git a/test-suite/misc/exitstatus.sh b/test-suite/misc/exitstatus.sh
index cea1de862..a327f4248 100755
--- a/test-suite/misc/exitstatus.sh
+++ b/test-suite/misc/exitstatus.sh
@@ -1,7 +1,8 @@
+#!/bin/sh
$coqtop -load-vernac-source misc/exitstatus/illtyped.v
N=$?
$coqc misc/exitstatus/illtyped.v
P=$?
-printf "On ill-typed input, coqtop returned $N.\n"
-printf "On ill-typed input, coqc returned $P.\n"
-if [ $N = 1 -a $P = 1 ]; then exit 0; else exit 1; fi
+printf "On ill-typed input, coqtop returned %s.\n" "$N"
+printf "On ill-typed input, coqc returned %s.\n" "$P"
+if [ $N = 1 ] && [ $P = 1 ]; then exit 0; else exit 1; fi
diff --git a/test-suite/misc/printers.sh b/test-suite/misc/printers.sh
index 28e7dc362..ef3f056d8 100755
--- a/test-suite/misc/printers.sh
+++ b/test-suite/misc/printers.sh
@@ -1,3 +1,2 @@
-printf "Drop. #use\"include\";; #quit;;\n" | $coqtopbyte 2>&1 | egrep "Error|Unbound"
-if [ $? = 0 ]; then exit 1; else exit 0; fi
-
+#!/bin/sh
+if printf "Drop. #use\"include\";; #quit;;\n" | $coqtopbyte 2>&1 | grep -E "Error|Unbound" ; then exit 1; else exit 0; fi
diff --git a/test-suite/misc/universes.sh b/test-suite/misc/universes.sh
index d87a86035..ef61ca624 100755
--- a/test-suite/misc/universes.sh
+++ b/test-suite/misc/universes.sh
@@ -1,8 +1,9 @@
+#!/bin/sh
# Sort universes for the whole standard library
EXPECTED_UNIVERSES=4 # Prop is not counted
$coqc -R misc/universes Universes misc/universes/all_stdlib 2>&1
$coqc -R misc/universes Universes misc/universes/universes 2>&1
mv universes.txt misc/universes
-N=`awk '{print $3}' misc/universes/universes.txt | sort -u | wc -l`
-printf "Found %s/%s universes\n" $N $EXPECTED_UNIVERSES
+N=$(awk '{print $3}' misc/universes/universes.txt | sort -u | wc -l)
+printf "Found %s/%s universes\n" "$N" "$EXPECTED_UNIVERSES"
if [ "$N" -eq $EXPECTED_UNIVERSES ]; then exit 0; else exit 1; fi
diff --git a/test-suite/modules/PO.v b/test-suite/modules/PO.v
index 8ba8525c6..be3310491 100644
--- a/test-suite/modules/PO.v
+++ b/test-suite/modules/PO.v
@@ -1,8 +1,8 @@
Set Implicit Arguments.
Unset Strict Implicit.
-Implicit Arguments fst.
-Implicit Arguments snd.
+Arguments fst : default implicits.
+Arguments snd : default implicits.
Module Type PO.
Parameter T : Set.
diff --git a/test-suite/modules/Przyklad.v b/test-suite/modules/Przyklad.v
index 7214287a6..ece1b47b4 100644
--- a/test-suite/modules/Przyklad.v
+++ b/test-suite/modules/Przyklad.v
@@ -1,7 +1,7 @@
Definition ifte (T : Set) (A B : Prop) (s : {A} + {B})
(th el : T) := if s then th else el.
-Implicit Arguments ifte.
+Arguments ifte : default implicits.
Lemma Reflexivity_provable :
forall (A : Set) (a : A) (s : {a = a} + {a <> a}),
diff --git a/test-suite/output/Notations3.out b/test-suite/output/Notations3.out
index 1987b6a6e..304353f55 100644
--- a/test-suite/output/Notations3.out
+++ b/test-suite/output/Notations3.out
@@ -223,3 +223,11 @@ fun S : nat => [[S | S.S]]
: Set
exists2 '{{y, z}} : nat * nat, y > z & z > y
: Prop
+foo =
+fun l : list nat => match l with
+ | _ :: (_ :: _) as l1 => l1
+ | _ => l
+ end
+ : list nat -> list nat
+
+Argument scope is [list_scope]
diff --git a/test-suite/output/Notations3.v b/test-suite/output/Notations3.v
index c165f9553..d2d136946 100644
--- a/test-suite/output/Notations3.v
+++ b/test-suite/output/Notations3.v
@@ -278,10 +278,12 @@ Set Printing Notations.
(* Check insensitivity of "match" clauses to order *)
+Module IfPat.
Notation "'if' t 'is' n .+ 1 'then' p 'else' q" :=
(match t with S n => p | 0 => q end)
(at level 200).
Check fun x => if x is n.+1 then n else 1.
+End IfPat.
(* Examples with binding patterns *)
@@ -338,11 +340,13 @@ Check ∀ '(((x,y),true)|((x,y),false)), x>y.
(* Check Georges' printability of a "if is then else" notation *)
+Module IfPat2.
Notation "'if' c 'is' p 'then' u 'else' v" :=
(match c with p => u | _ => v end)
(at level 200, p pattern at level 100).
Check fun p => if p is S n then n else 0.
Check fun p => if p is Lt then 1 else 0.
+End IfPat2.
(* Check that mixed binders and terms defaults to ident and not pattern *)
Module F.
@@ -364,3 +368,15 @@ Check {'(x,y)|x+y=0}.
(* Check exists2 with a pattern *)
Check ex2 (fun x => let '(y,z) := x in y>z) (fun x => let '(y,z) := x in z>y).
+
+Module Issue7110.
+Open Scope list_scope.
+Notation "[ :: x1 , x2 , .. , xn & s ]" := (x1 :: x2 :: .. (xn :: s) ..)
+ (at level 0).
+Definition foo (l : list nat) :=
+ match l with
+ | a :: (b :: l) as l1 => l1
+ | _ => l
+end.
+Print foo.
+End Issue7110.
diff --git a/test-suite/output/Projections.out b/test-suite/output/Projections.out
new file mode 100644
index 000000000..e9c28faf1
--- /dev/null
+++ b/test-suite/output/Projections.out
@@ -0,0 +1,2 @@
+fun S : store => S.(store_funcs)
+ : store -> host_func
diff --git a/test-suite/output/Projections.v b/test-suite/output/Projections.v
new file mode 100644
index 000000000..098a518dc
--- /dev/null
+++ b/test-suite/output/Projections.v
@@ -0,0 +1,11 @@
+
+Set Printing Projections.
+
+Class HostFunction := host_func : Type.
+
+Section store.
+ Context `{HostFunction}.
+ Record store := { store_funcs : host_func }.
+End store.
+
+Check (fun (S:@store nat) => S.(store_funcs)).
diff --git a/test-suite/output/bug5778.out b/test-suite/output/bug5778.out
index 91ceb1b58..d6056c509 100644
--- a/test-suite/output/bug5778.out
+++ b/test-suite/output/bug5778.out
@@ -1,4 +1,4 @@
The command has indeed failed with message:
-In nested Ltac calls to "c", "abs" and "abstract b ltac:(())", last call
-failed.
+In nested Ltac calls to "c", "abs", "abstract b ltac:(())",
+"b", "a", "pose (I : I)" and "(I : I)", last term evaluation failed.
The term "I" has type "True" which should be Set, Prop or Type.
diff --git a/test-suite/output/bug6404.out b/test-suite/output/bug6404.out
new file mode 100644
index 000000000..05464755f
--- /dev/null
+++ b/test-suite/output/bug6404.out
@@ -0,0 +1,4 @@
+The command has indeed failed with message:
+In nested Ltac calls to "c", "abs", "transparent_abstract (tactic3)",
+"b", "a", "pose (I : I)" and "(I : I)", last term evaluation failed.
+The term "I" has type "True" which should be Set, Prop or Type.
diff --git a/test-suite/output/bug6404.v b/test-suite/output/bug6404.v
new file mode 100644
index 000000000..bbe6b1a00
--- /dev/null
+++ b/test-suite/output/bug6404.v
@@ -0,0 +1,7 @@
+Ltac a _ := pose (I : I).
+Ltac b _ := a ().
+Ltac abs _ := transparent_abstract b ().
+Ltac c _ := abs ().
+Goal True.
+ Fail c ().
+Abort.
diff --git a/test-suite/output/ssr_clear.out b/test-suite/output/ssr_clear.out
new file mode 100644
index 000000000..151595406
--- /dev/null
+++ b/test-suite/output/ssr_clear.out
@@ -0,0 +1,3 @@
+The command has indeed failed with message:
+Ltac call to "move (ssrmovearg) (ssrclauses)" failed.
+No assumption is named NO_SUCH_NAME
diff --git a/test-suite/output/ssr_clear.v b/test-suite/output/ssr_clear.v
new file mode 100644
index 000000000..573ec47e0
--- /dev/null
+++ b/test-suite/output/ssr_clear.v
@@ -0,0 +1,6 @@
+Require Import ssreflect.
+
+Example foo : True -> True.
+Proof.
+Fail move=> {NO_SUCH_NAME}.
+Abort.
diff --git a/test-suite/prerequisite/make_local.v b/test-suite/prerequisite/make_local.v
index 8700a6c4e..6d9117c05 100644
--- a/test-suite/prerequisite/make_local.v
+++ b/test-suite/prerequisite/make_local.v
@@ -2,8 +2,7 @@
Definition f (A:Type) (a:A) := a.
-Local Arguments Scope f [type_scope type_scope].
-Local Implicit Arguments f [A].
+Local Arguments f [A]%type_scope _%type_scope.
(* Used in ImportedCoercion.v to test the locality flag *)
diff --git a/test-suite/success/AdvancedTypeClasses.v b/test-suite/success/AdvancedTypeClasses.v
index b4efa7edc..d0aa5c857 100644
--- a/test-suite/success/AdvancedTypeClasses.v
+++ b/test-suite/success/AdvancedTypeClasses.v
@@ -28,8 +28,8 @@ Class interp_pair (abs : Type) :=
{ repr : term;
link: abs = interp repr }.
-Implicit Arguments repr [[interp_pair]].
-Implicit Arguments link [[interp_pair]].
+Arguments repr _ {interp_pair}.
+Arguments link _ {interp_pair}.
Lemma prod_interp `{interp_pair a, interp_pair b} : a * b = interp (Prod (repr a) (repr b)).
simpl. intros. rewrite <- link. rewrite <- (link b). reflexivity.
diff --git a/test-suite/success/ImplicitArguments.v b/test-suite/success/ImplicitArguments.v
index 921433cad..9a19b595e 100644
--- a/test-suite/success/ImplicitArguments.v
+++ b/test-suite/success/ImplicitArguments.v
@@ -2,7 +2,7 @@ Inductive vector {A : Type} : nat -> Type :=
| vnil : vector 0
| vcons : A -> forall {n'}, vector n' -> vector (S n').
-Implicit Arguments vector [].
+Arguments vector A : clear implicits.
Require Import Coq.Program.Program.
diff --git a/test-suite/success/Inductive.v b/test-suite/success/Inductive.v
index 5b1482fd5..f07c0191f 100644
--- a/test-suite/success/Inductive.v
+++ b/test-suite/success/Inductive.v
@@ -73,7 +73,7 @@ CoInductive LList (A : Set) : Set :=
| LNil : LList A
| LCons : A -> LList A -> LList A.
-Implicit Arguments LNil [A].
+Arguments LNil [A].
Inductive Finite (A : Set) : LList A -> Prop :=
| Finite_LNil : Finite LNil
diff --git a/test-suite/success/Inversion.v b/test-suite/success/Inversion.v
index 45c71615f..ca8da3948 100644
--- a/test-suite/success/Inversion.v
+++ b/test-suite/success/Inversion.v
@@ -31,7 +31,7 @@ Inductive in_extension (I : Set) (r : rule I) : extension I -> Type :=
| in_first : forall e, in_extension r (add_rule r e)
| in_rest : forall e r', in_extension r e -> in_extension r (add_rule r' e).
-Implicit Arguments NL [I].
+Arguments NL [I].
Inductive super_extension (I : Set) (e : extension I) :
extension I -> Type :=
diff --git a/test-suite/success/RecTutorial.v b/test-suite/success/RecTutorial.v
index 841940492..29350d620 100644
--- a/test-suite/success/RecTutorial.v
+++ b/test-suite/success/RecTutorial.v
@@ -991,10 +991,10 @@ Proof.
Qed.
-Implicit Arguments Vector.cons [A n].
-Implicit Arguments Vector.nil [A].
-Implicit Arguments Vector.hd [A n].
-Implicit Arguments Vector.tl [A n].
+Arguments Vector.cons [A] _ [n].
+Arguments Vector.nil [A].
+Arguments Vector.hd [A n].
+Arguments Vector.tl [A n].
Definition Vid : forall (A : Type)(n:nat), Vector.t A n -> Vector.t A n.
Proof.
@@ -1064,7 +1064,7 @@ Fixpoint vector_nth (A:Set)(n:nat)(p:nat)(v:Vector.t A p){struct v}
| S n', Vector.cons _ v' => vector_nth A n' _ v'
end.
-Implicit Arguments vector_nth [A p].
+Arguments vector_nth [A] _ [p].
Lemma nth_bitwise : forall (n:nat) (v1 v2: Vector.t bool n) i a b,
@@ -1159,7 +1159,7 @@ infiniteproof map_iterate'.
Qed.
-Implicit Arguments LNil [A].
+Arguments LNil [A].
Lemma Lnil_not_Lcons : forall (A:Set)(a:A)(l:LList A),
LNil <> (LCons a l).
diff --git a/test-suite/success/Record.v b/test-suite/success/Record.v
index 6f27c1d36..18ebcd638 100644
--- a/test-suite/success/Record.v
+++ b/test-suite/success/Record.v
@@ -5,7 +5,7 @@ Require Import Program.
Require Import List.
Record vector {A : Type} {n : nat} := { vec_list : list A ; vec_len : length vec_list = n }.
-Implicit Arguments vector [].
+Arguments vector : clear implicits.
Coercion vec_list : vector >-> list.
diff --git a/test-suite/success/Scopes.v b/test-suite/success/Scopes.v
index ca3746716..2da630633 100644
--- a/test-suite/success/Scopes.v
+++ b/test-suite/success/Scopes.v
@@ -11,7 +11,7 @@ Check (A.opp 3).
Record B := { f :> Z -> Z }.
Variable a:B.
-Arguments Scope a [Z_scope].
+Arguments a _%Z_scope : extra scopes.
Check a 0.
(* Check that casts activate scopes if ever possible *)
diff --git a/test-suite/success/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/Typeclasses.v b/test-suite/success/Typeclasses.v
index cd6eac35c..400479ae8 100644
--- a/test-suite/success/Typeclasses.v
+++ b/test-suite/success/Typeclasses.v
@@ -128,8 +128,8 @@ Record Monad {m : Type -> Type} := {
Print Visibility.
Print unit.
-Implicit Arguments unit [[m] [m0] [α]].
-Implicit Arguments Monad [].
+Arguments unit {m m0 α}.
+Arguments Monad : clear implicits.
Notation "'return' t" := (unit t).
(* Test correct handling of existentials and defined fields. *)
diff --git a/test-suite/success/apply.v b/test-suite/success/apply.v
index 02e043bc3..b287b5fac 100644
--- a/test-suite/success/apply.v
+++ b/test-suite/success/apply.v
@@ -39,7 +39,7 @@ Qed.
(* Check apply/eapply distinction in presence of open terms *)
Parameter h : forall x y z : nat, x = z -> x = y.
-Implicit Arguments h [[x] [y]].
+Arguments h {x y}.
Goal 1 = 0 -> True.
intro H.
apply h in H || exact I.
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/dependentind.v b/test-suite/success/dependentind.v
index f5bb884d2..55ae54ca0 100644
--- a/test-suite/success/dependentind.v
+++ b/test-suite/success/dependentind.v
@@ -42,7 +42,7 @@ Inductive ctx : Type :=
Bind Scope context_scope with ctx.
Delimit Scope context_scope with ctx.
-Arguments Scope snoc [context_scope].
+Arguments snoc _%context_scope.
Notation " Γ , τ " := (snoc Γ τ) (at level 25, τ at next level, left associativity) : context_scope.
diff --git a/test-suite/success/evars.v b/test-suite/success/evars.v
index 627794832..5b13f35d5 100644
--- a/test-suite/success/evars.v
+++ b/test-suite/success/evars.v
@@ -386,7 +386,7 @@ Record iffT (X Y:Type) : Type := mkIff { iffLR : X->Y; iffRL : Y->X }.
Record tri (R:Type->Type->Type) (S:Type->Type->Type) (T:Type->Type->Type) := mkTri {
tri0 : forall a b c, R a b -> S a c -> T b c
}.
-Implicit Arguments mkTri [R S T].
+Arguments mkTri [R S T].
Definition tri_iffT : tri iffT iffT iffT :=
(mkTri
(fun X0 X1 X2 E01 E02 =>
diff --git a/test-suite/success/implicit.v b/test-suite/success/implicit.v
index a0981311b..23853890d 100644
--- a/test-suite/success/implicit.v
+++ b/test-suite/success/implicit.v
@@ -33,11 +33,11 @@ Definition eq1 := fun (A:Type) (x y:A) => x=y.
Definition eq2 := fun (A:Type) (x y:A) => x=y.
Definition eq3 := fun (A:Type) (x y:A) => x=y.
-Implicit Arguments op' [].
-Global Implicit Arguments op'' [].
+Arguments op' : clear implicits.
+Global Arguments op'' : clear implicits.
-Implicit Arguments eq2 [].
-Global Implicit Arguments eq3 [].
+Arguments eq2 : clear implicits.
+Global Arguments eq3 : clear implicits.
Check (op 0 0).
Check (op' nat 0 0).
@@ -89,14 +89,14 @@ Fixpoint plus n m {struct n} :=
(* Check multiple implicit arguments signatures *)
-Implicit Arguments eq_refl [[A] [x]] [[A]].
+Arguments eq_refl {A x}, {A}.
Check eq_refl : 0 = 0.
(* Check that notations preserve implicit (since 8.3) *)
Parameter p : forall A, A -> forall n, n = 0 -> True.
-Implicit Arguments p [A n].
+Arguments p [A] _ [n].
Notation Q := (p 0).
Check Q eq_refl.
diff --git a/test-suite/success/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/gallina-syntax.el b/tools/gallina-syntax.el
index 662762b08..7c59fb6ae 100644
--- a/tools/gallina-syntax.el
+++ b/tools/gallina-syntax.el
@@ -432,7 +432,6 @@
("Add Semi Ring" nil "Add Semi Ring #." t "Add\\s-+Semi\\s-+Ring")
("Add Setoid" nil "Add Setoid #." t "Add\\s-+Setoid")
("Admit Obligations" "oblsadmit" "Admit Obligations." nil "Admit\\s-+Obligations")
- ("Arguments Scope" "argsc" "Arguments Scope @{id} [ @{_} ]" t "Arguments\\s-+Scope")
("Bind Scope" "bndsc" "Bind Scope @{scope} with @{type}" t "Bind\\s-+Scope")
("Canonical Structure" nil "Canonical Structure #." t "Canonical\\s-+Structure")
("Cd" nil "Cd #." nil "Cd")
diff --git a/toplevel/coqloop.ml b/toplevel/coqloop.ml
index 64d839f18..63b8b538a 100644
--- a/toplevel/coqloop.ml
+++ b/toplevel/coqloop.ml
@@ -272,6 +272,15 @@ 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
match fb.contents with
@@ -290,6 +299,9 @@ 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 Warning msg top_buffer
| Message (lvl,loc,msg) ->
TopErr.print_error_for_buffer ?loc lvl msg top_buffer
@@ -325,6 +337,24 @@ let cproof p1 p2 =
let drop_last_doc = ref None
+(* We try to behave better when goal printing raises an exception
+ [usually Ctrl-C]
+
+ This is mostly a hack as we should protect printing in a more
+ generic way, but that'll do for now *)
+let top_goal_print oldp newp =
+ try
+ let proof_changed = not (Option.equal cproof oldp newp) in
+ let print_goals = not !Flags.quiet &&
+ proof_changed && Proof_global.there_are_pending_proofs () in
+ if print_goals then Feedback.msg_notice (pr_open_cur_subgoals ())
+ with
+ | exn ->
+ let (e, info) = CErrors.push exn in
+ let loc = Loc.get_loc info in
+ let msg = CErrors.iprint (e, info) in
+ TopErr.print_error_for_buffer ?loc Feedback.Error msg top_buffer
+
(* Careful to keep this loop tail-rec *)
let rec vernac_loop ~state =
let open CAst in
@@ -338,6 +368,13 @@ let rec vernac_loop ~state =
try
let input = top_buffer.tokens in
match read_sentence ~state input with
+ | {v=VernacBacktrack(bid,_,_)} ->
+ let bid = Stateid.of_int bid in
+ let doc, res = Stm.edit_at ~doc:state.doc bid in
+ assert (res = `NewTip);
+ let state = { state with doc; sid = bid } in
+ vernac_loop ~state
+
| {v=VernacQuit} ->
exit 0
| {v=VernacDrop} ->
@@ -346,10 +383,7 @@ let rec vernac_loop ~state =
else (Feedback.msg_warning (str "There is no ML toplevel."); vernac_loop ~state)
| {v=VernacControl c; loc} ->
let nstate = Vernac.process_expr ~state (make ?loc c) in
- let proof_changed = not (Option.equal cproof nstate.proof state.proof) in
- let print_goals = not !Flags.quiet &&
- proof_changed && Proof_global.there_are_pending_proofs () in
- if print_goals then Feedback.msg_notice (pr_open_cur_subgoals ());
+ top_goal_print state.proof nstate.proof;
vernac_loop ~state:nstate
with
| Stm.End_of_input ->
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index a08cfa9f4..668f9b893 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -315,16 +315,24 @@ let check_vio_tasks opts =
(* vio files *)
let schedule_vio opts =
- (* We must add update the loadpath here as the scheduling process
- happens outside of the STM *)
- let iload_path = build_load_path opts in
- List.iter Mltop.add_coq_path iload_path;
-
if opts.vio_checking then
Vio_checking.schedule_vio_checking opts.vio_files_j opts.vio_files
else
Vio_checking.schedule_vio_compilation opts.vio_files_j opts.vio_files
+let do_vio opts =
+ (* We must initialize the loadpath here as the vio scheduling
+ process happens outside of the STM *)
+ if opts.vio_files <> [] || opts.vio_tasks <> [] then
+ let iload_path = build_load_path opts in
+ List.iter Mltop.add_coq_path iload_path;
+
+ (* Vio compile pass *)
+ if opts.vio_files <> [] then schedule_vio opts;
+ (* Vio task pass *)
+ if opts.vio_tasks <> [] then check_vio_tasks opts
+
+
(******************************************************************************)
(* Color Options *)
(******************************************************************************)
@@ -360,7 +368,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 =
@@ -434,7 +442,7 @@ let init_toplevel arglist =
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";
@@ -483,10 +491,9 @@ let init_toplevel arglist =
end else begin
try
compile_files opts;
- (* Vio compile pass *)
- if opts.vio_files <> [] then schedule_vio opts;
- (* Vio task pass *)
- check_vio_tasks 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
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/toplevel/g_toplevel.ml4 b/toplevel/g_toplevel.ml4
index 7526f3071..d5d558b9b 100644
--- a/toplevel/g_toplevel.ml4
+++ b/toplevel/g_toplevel.ml4
@@ -9,10 +9,12 @@
(************************************************************************)
open Pcoq
+open Pcoq.Prim
open Vernacexpr
(* Vernaculars specific to the toplevel *)
type vernac_toplevel =
+ | VernacBacktrack of int * int * int
| VernacDrop
| VernacQuit
| VernacControl of vernac_control
@@ -31,6 +33,8 @@ GEXTEND Gram
vernac_toplevel: FIRST
[ [ IDENT "Drop"; "." -> CAst.make VernacDrop
| IDENT "Quit"; "." -> CAst.make VernacQuit
+ | IDENT "Backtrack"; n = natural ; m = natural ; p = natural; "." ->
+ CAst.make (VernacBacktrack (n,m,p))
| cmd = main_entry ->
match cmd with
| None -> raise Stm.End_of_input
diff --git a/vernac/class.ml b/vernac/class.ml
index 59d933108..f0b01061b 100644
--- a/vernac/class.ml
+++ b/vernac/class.ml
@@ -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/classes.ml b/vernac/classes.ml
index 76d427add..3c133f317 100644
--- a/vernac/classes.ml
+++ b/vernac/classes.ml
@@ -293,7 +293,7 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
(* 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
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..1466fa243 100644
--- a/vernac/comFixpoint.ml
+++ b/vernac/comFixpoint.ml
@@ -225,7 +225,8 @@ 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
+ (* 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..05c40dbdd 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;
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/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/obligations.ml b/vernac/obligations.ml
index 064e40b9b..3f2792518 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
@@ -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
diff --git a/vernac/record.ml b/vernac/record.ml
index 6e745b2af..78e68e8a3 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
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 9ff4e3302..a9d1631ba 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;
@@ -534,17 +534,14 @@ let vernac_assumption ~atts discharge kind l nl =
if not status then Feedback.feedback Feedback.AddedAxiom
let should_treat_as_cumulative cum poly =
- if poly then
- match cum with
- | GlobalCumulativity | LocalCumulativity -> true
- | GlobalNonCumulativity | LocalNonCumulativity -> false
- else
- match cum with
- | GlobalCumulativity | GlobalNonCumulativity -> false
- | LocalCumulativity ->
- user_err Pp.(str "The Cumulative prefix can only be used in a polymorphic context.")
- | LocalNonCumulativity ->
- user_err Pp.(str "The NonCumulative prefix can only be used in a polymorphic context.")
+ match cum with
+ | Some VernacCumulative ->
+ if poly then true
+ else user_err Pp.(str "The Cumulative prefix can only be used in a polymorphic context.")
+ | Some VernacNonCumulative ->
+ if poly then false
+ else user_err Pp.(str "The NonCumulative prefix can only be used in a polymorphic context.")
+ | None -> poly && Flags.is_polymorphic_inductive_cumulativity ()
let vernac_record cum k poly finite struc binders sort nameopt cfs =
let is_cumulative = should_treat_as_cumulative cum poly in
@@ -565,7 +562,6 @@ let vernac_record cum k poly finite struc binders sort nameopt cfs =
indicates whether the type is inductive, co-inductive or
neither. *)
let vernac_inductive ~atts cum lo finite indl =
- let is_cumulative = should_treat_as_cumulative cum atts.polymorphic in
if Dumpglob.dump () then
List.iter (fun (((coe,(lid,_)), _, _, _, cstrs), _) ->
match cstrs with
@@ -602,6 +598,7 @@ let vernac_inductive ~atts cum lo finite indl =
| _ -> user_err Pp.(str "Cannot handle mutually (co)inductive records.")
in
let indl = List.map unpack indl in
+ let is_cumulative = should_treat_as_cumulative cum atts.polymorphic in
ComInductive.do_mutual_inductive indl is_cumulative atts.polymorphic lo finite
let vernac_fixpoint ~atts discharge l =
@@ -2008,7 +2005,6 @@ let interp ?proof ~atts ~st c =
| VernacRestart -> CErrors.user_err (str "Restart cannot be used through the Load command")
| VernacUndo _ -> CErrors.user_err (str "Undo cannot be used through the Load command")
| VernacUndoTo _ -> CErrors.user_err (str "UndoTo cannot be used through the Load command")
- | VernacBacktrack _ -> CErrors.user_err (str "Backtrack cannot be used through the Load command")
(* Resetting *)
| VernacResetName _ -> anomaly (str "VernacResetName not handled by Stm.")
@@ -2025,7 +2021,6 @@ let interp ?proof ~atts ~st c =
| VernacDelimiters (sc,lr) -> vernac_delimiters sc lr
| VernacBindScope (sc,rl) -> vernac_bind_scope sc rl
| VernacOpenCloseScope (b, s) -> vernac_open_close_scope ~atts (b,s)
- | VernacArgumentsScope (qid,scl) -> vernac_arguments_scope ~atts qid scl
| VernacInfix (mv,qid,sc) -> vernac_infix ~atts mv qid sc
| VernacNotation (c,infpl,sc) ->
vernac_notation ~atts c infpl sc
@@ -2099,8 +2094,6 @@ let interp ?proof ~atts ~st c =
vernac_hints ~atts dbnames hints
| VernacSyntacticDefinition (id,c,b) ->
vernac_syntactic_definition ~atts id c b
- | VernacDeclareImplicits (qid,l) ->
- vernac_declare_implicits ~atts qid l
| VernacArguments (qid, args, more_implicits, nargs, flags) ->
vernac_arguments ~atts qid args more_implicits nargs flags
| VernacReserve bl -> vernac_reserve bl
@@ -2168,7 +2161,7 @@ let check_vernac_supports_locality c l =
| VernacDeclareMLModule _
| VernacCreateHintDb _ | VernacRemoveHints _ | VernacHints _
| VernacSyntacticDefinition _
- | VernacArgumentsScope _ | VernacDeclareImplicits _ | VernacArguments _
+ | VernacArguments _
| VernacGeneralizable _
| VernacSetOpacity _ | VernacSetStrategy _
| VernacSetOption _ | VernacUnsetOption _
diff --git a/vernac/vernacprop.ml b/vernac/vernacprop.ml
index a837b77a3..0fdd2faaf 100644
--- a/vernac/vernacprop.ml
+++ b/vernac/vernacprop.ml
@@ -31,7 +31,6 @@ let rec has_Fail = function
let is_navigation_vernac_expr = function
| VernacResetInitial
| VernacResetName _
- | VernacBacktrack _
| VernacBackTo _
| VernacBack _ -> true
| _ -> false