aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore35
-rw-r--r--CHANGES95
-rw-r--r--COMPATIBILITY38
-rw-r--r--INSTALL11
-rw-r--r--INSTALL.ide2
-rw-r--r--Makefile23
-rw-r--r--Makefile.build1062
-rw-r--r--Makefile.checker86
-rw-r--r--Makefile.common348
-rw-r--r--Makefile.dev223
-rw-r--r--Makefile.doc137
-rw-r--r--Makefile.ide254
-rw-r--r--Makefile.install136
-rw-r--r--README66
-rw-r--r--README.md44
-rw-r--r--_tags76
-rwxr-xr-xbuild32
-rw-r--r--checker/check.ml25
-rw-r--r--checker/check.mllib15
-rw-r--r--checker/check_stat.ml7
-rw-r--r--checker/checker.ml17
-rw-r--r--checker/closure.ml2
-rw-r--r--checker/declarations.ml58
-rw-r--r--checker/environ.ml20
-rw-r--r--checker/indtypes.ml8
-rw-r--r--checker/inductive.ml10
-rw-r--r--checker/mod_checking.ml6
-rw-r--r--checker/modops.ml2
-rw-r--r--checker/print.ml8
-rw-r--r--checker/safe_typing.ml4
-rw-r--r--checker/subtyping.ml2
-rw-r--r--checker/typeops.ml8
-rw-r--r--checker/univ.ml14
-rw-r--r--checker/votour.ml48
-rw-r--r--configure.ml107
-rw-r--r--coq-win32.itarget2
-rw-r--r--coq.itarget8
-rw-r--r--dev/README3
-rw-r--r--dev/base_include1
-rw-r--r--dev/doc/README-V1-V5296
-rw-r--r--dev/doc/README-V1-V5.asciidoc378
-rw-r--r--dev/doc/build-system.dev.txt34
-rw-r--r--dev/doc/build-system.txt15
-rw-r--r--dev/doc/changes.txt113
-rw-r--r--dev/doc/coq-src-description.txt7
-rw-r--r--dev/doc/drop.txt44
-rw-r--r--dev/doc/ocamlbuild.txt30
-rw-r--r--dev/doc/profiling.txt76
-rw-r--r--dev/doc/setup.txt289
-rwxr-xr-xdev/make-installer-win32.sh2
-rwxr-xr-xdev/make-installer-win64.sh2
-rwxr-xr-xdev/make-macos-dmg.sh4
-rwxr-xr-xdev/nsis/coq.nsi3
-rw-r--r--dev/ocamldebug-coq.run2
-rw-r--r--dev/printers.mllib38
-rw-r--r--dev/tools/Makefile.common0
-rw-r--r--dev/tools/anomaly-traces-parser.el28
-rw-r--r--dev/top_printers.ml21
-rw-r--r--dev/vm_printers.ml2
-rw-r--r--doc/common/macros.tex4
-rw-r--r--doc/refman/AsyncProofs.tex40
-rw-r--r--doc/refman/CanonicalStructures.tex2
-rw-r--r--doc/refman/RefMan-cic.tex263
-rw-r--r--doc/refman/RefMan-ltac.tex100
-rw-r--r--doc/refman/RefMan-syn.tex10
-rw-r--r--doc/refman/RefMan-tac.tex93
-rw-r--r--doc/refman/Universes.tex4
-rw-r--r--doc/stdlib/index-list.html.template2
-rw-r--r--doc/tutorial/Tutorial.tex56
-rw-r--r--engine/engine.mllib4
-rw-r--r--engine/evarutil.ml (renamed from pretyping/evarutil.ml)245
-rw-r--r--engine/evarutil.mli (renamed from pretyping/evarutil.mli)50
-rw-r--r--engine/evd.ml1
-rw-r--r--engine/evd.mli8
-rw-r--r--engine/ftactic.ml (renamed from tactics/ftactic.ml)2
-rw-r--r--engine/ftactic.mli (renamed from tactics/ftactic.mli)9
-rw-r--r--engine/geninterp.ml98
-rw-r--r--engine/geninterp.mli68
-rw-r--r--engine/logic_monad.ml11
-rw-r--r--engine/logic_monad.mli2
-rw-r--r--engine/namegen.mli2
-rw-r--r--engine/proofview.ml (renamed from proofs/proofview.ml)189
-rw-r--r--engine/proofview.mli (renamed from proofs/proofview.mli)54
-rw-r--r--engine/proofview_monad.ml4
-rw-r--r--engine/proofview_monad.mli7
-rw-r--r--engine/sigma.mli6
-rw-r--r--engine/termops.mli3
-rw-r--r--engine/uState.mli4
-rw-r--r--grammar/argextend.ml4327
-rw-r--r--grammar/argextend.mlp254
-rw-r--r--grammar/gramCompat.mlp86
-rw-r--r--grammar/grammar.mllib66
-rw-r--r--grammar/q_constr.ml4120
-rw-r--r--grammar/q_util.ml4112
-rw-r--r--grammar/q_util.mli33
-rw-r--r--grammar/q_util.mlp118
-rw-r--r--grammar/tacextend.mlp (renamed from grammar/tacextend.ml4)117
-rw-r--r--grammar/vernacextend.mlp (renamed from grammar/vernacextend.ml4)93
-rw-r--r--ide/coq.lang59
-rw-r--r--ide/coq.ml46
-rw-r--r--ide/coq.pngbin71924 -> 12907 bytes
-rw-r--r--ide/coqOps.ml52
-rw-r--r--ide/coqide.ml52
-rw-r--r--ide/coqide_ui.ml12
-rw-r--r--ide/coqidetop.mllib7
-rw-r--r--ide/ide.mllib7
-rw-r--r--ide/ide_slave.ml74
-rw-r--r--ide/ideutils.ml12
-rw-r--r--ide/ideutils.mli2
-rw-r--r--ide/preferences.ml65
-rw-r--r--ide/preferences.mli2
-rw-r--r--ide/project_file.ml414
-rw-r--r--ide/richprinter.ml (renamed from printing/richprinter.ml)1
-rw-r--r--ide/richprinter.mli (renamed from printing/richprinter.mli)3
-rw-r--r--ide/serialize.ml (renamed from lib/serialize.ml)41
-rw-r--r--ide/serialize.mli (renamed from lib/serialize.mli)2
-rw-r--r--ide/texmacspp.ml (renamed from stm/texmacspp.ml)22
-rw-r--r--ide/texmacspp.mli (renamed from stm/texmacspp.mli)0
-rw-r--r--ide/utils/okey.ml27
-rw-r--r--ide/wg_Completion.ml2
-rw-r--r--ide/wg_MessageView.ml6
-rw-r--r--ide/wg_ProofView.ml2
-rw-r--r--ide/wg_ScriptView.ml2
-rw-r--r--ide/wg_Segment.ml9
-rw-r--r--ide/xml_lexer.mli (renamed from lib/xml_lexer.mli)0
-rw-r--r--ide/xml_lexer.mll (renamed from lib/xml_lexer.mll)0
-rw-r--r--ide/xml_parser.ml (renamed from lib/xml_parser.ml)0
-rw-r--r--ide/xml_parser.mli (renamed from lib/xml_parser.mli)0
-rw-r--r--ide/xml_printer.ml (renamed from lib/xml_printer.ml)0
-rw-r--r--ide/xml_printer.mli (renamed from lib/xml_printer.mli)0
-rw-r--r--ide/xmlprotocol.ml189
-rw-r--r--ide/xmlprotocol.mli14
-rw-r--r--interp/constrarg.ml73
-rw-r--r--interp/constrarg.mli28
-rw-r--r--interp/constrexpr_ops.ml2
-rw-r--r--interp/constrextern.ml96
-rw-r--r--interp/constrintern.ml238
-rw-r--r--interp/dumpglob.ml6
-rw-r--r--interp/implicit_quantifiers.ml2
-rw-r--r--interp/notation.ml59
-rw-r--r--interp/notation.mli11
-rw-r--r--interp/notation_ops.ml209
-rw-r--r--interp/notation_ops.mli32
-rw-r--r--interp/stdarg.ml25
-rw-r--r--interp/stdarg.mli5
-rw-r--r--interp/syntax_def.ml2
-rw-r--r--interp/topconstr.ml12
-rw-r--r--interp/topconstr.mli4
-rw-r--r--intf/constrexpr.mli6
-rw-r--r--intf/extend.mli36
-rw-r--r--intf/notation_term.mli1
-rw-r--r--intf/tacexpr.mli43
-rw-r--r--intf/vernacexpr.mli20
-rw-r--r--kernel/byterun/coq_interp.c39
-rw-r--r--kernel/byterun/int64_emul.h270
-rw-r--r--kernel/byterun/int64_native.h48
-rw-r--r--kernel/cbytecodes.ml3
-rw-r--r--kernel/cbytegen.ml4
-rw-r--r--kernel/closure.ml5
-rw-r--r--kernel/closure.mli3
-rw-r--r--kernel/constr.ml28
-rw-r--r--kernel/constr.mli3
-rw-r--r--kernel/cooking.ml12
-rw-r--r--kernel/csymtable.ml6
-rw-r--r--kernel/entries.mli2
-rw-r--r--kernel/indtypes.ml205
-rw-r--r--kernel/inductive.ml14
-rw-r--r--kernel/kernel.mllib1
-rw-r--r--kernel/names.ml60
-rw-r--r--kernel/names.mli42
-rw-r--r--kernel/nativecode.ml13
-rw-r--r--kernel/nativeconv.ml7
-rw-r--r--kernel/nativelib.ml16
-rw-r--r--kernel/nativelibrary.ml10
-rw-r--r--kernel/pre_env.ml9
-rw-r--r--kernel/pre_env.mli2
-rw-r--r--kernel/reduction.ml5
-rw-r--r--kernel/safe_typing.ml4
-rw-r--r--kernel/sorts.ml2
-rw-r--r--kernel/term_typing.ml10
-rw-r--r--kernel/univ.ml22
-rw-r--r--kernel/vconv.ml6
-rw-r--r--lib/aux_file.ml8
-rw-r--r--lib/aux_file.mli3
-rw-r--r--lib/cEphemeron.ml (renamed from lib/ephemeron.ml)0
-rw-r--r--lib/cEphemeron.mli (renamed from lib/ephemeron.mli)0
-rw-r--r--lib/cSet.ml2
-rw-r--r--lib/clib.mllib6
-rw-r--r--lib/dyn.ml44
-rw-r--r--lib/dyn.mli13
-rw-r--r--lib/errors.ml7
-rw-r--r--lib/explore.ml2
-rw-r--r--lib/feedback.ml254
-rw-r--r--lib/feedback.mli97
-rw-r--r--lib/flags.ml6
-rw-r--r--lib/flags.mli7
-rw-r--r--lib/future.ml8
-rw-r--r--lib/genarg.ml210
-rw-r--r--lib/genarg.mli111
-rw-r--r--lib/hashcons.ml12
-rw-r--r--lib/hashcons.mli12
-rw-r--r--lib/hashset.ml4
-rw-r--r--lib/hashset.mli2
-rw-r--r--lib/iStream.ml6
-rw-r--r--lib/lib.mllib3
-rw-r--r--lib/minisys.ml74
-rw-r--r--lib/pp.ml191
-rw-r--r--lib/pp.mli142
-rw-r--r--lib/ppstyle.ml40
-rw-r--r--lib/ppstyle.mli14
-rw-r--r--lib/richpp.ml4
-rw-r--r--lib/richpp.mli5
-rw-r--r--lib/spawn.ml36
-rw-r--r--lib/stateid.ml26
-rw-r--r--lib/stateid.mli11
-rw-r--r--lib/system.ml91
-rw-r--r--lib/system.mli6
-rw-r--r--lib/unicode.ml107
-rw-r--r--lib/unicode.mli22
-rw-r--r--lib/util.ml21
-rw-r--r--lib/util.mli8
-rw-r--r--library/declare.ml47
-rw-r--r--library/declaremods.ml17
-rw-r--r--library/declaremods.mli3
-rw-r--r--library/globnames.ml15
-rw-r--r--library/goptions.ml15
-rw-r--r--library/libobject.ml15
-rw-r--r--library/library.ml47
-rw-r--r--library/library.mli6
-rw-r--r--library/loadpath.ml2
-rw-r--r--library/nametab.ml6
-rw-r--r--library/summary.ml13
-rw-r--r--library/universes.ml3
-rw-r--r--library/universes.mli2
-rw-r--r--ltac/coretactics.ml4 (renamed from tactics/coretactics.ml4)64
-rw-r--r--ltac/evar_tactics.ml (renamed from tactics/evar_tactics.ml)0
-rw-r--r--ltac/evar_tactics.mli (renamed from tactics/evar_tactics.mli)0
-rw-r--r--ltac/extraargs.ml4 (renamed from tactics/extraargs.ml4)85
-rw-r--r--ltac/extraargs.mli (renamed from tactics/extraargs.mli)17
-rw-r--r--ltac/extratactics.ml4 (renamed from tactics/extratactics.ml4)56
-rw-r--r--ltac/extratactics.mli (renamed from tactics/extratactics.mli)0
-rw-r--r--ltac/g_auto.ml4209
-rw-r--r--ltac/g_class.ml4 (renamed from tactics/g_class.ml4)3
-rw-r--r--ltac/g_eqdecide.ml4 (renamed from tactics/g_eqdecide.ml4)0
-rw-r--r--ltac/g_ltac.ml4 (renamed from parsing/g_ltac.ml4)213
-rw-r--r--ltac/g_obligations.ml4 (renamed from toplevel/g_obligations.ml4)28
-rw-r--r--ltac/g_rewrite.ml4 (renamed from tactics/g_rewrite.ml4)19
-rw-r--r--ltac/ltac.mllib21
-rw-r--r--ltac/profile_ltac.ml323
-rw-r--r--ltac/profile_ltac.mli (renamed from tactics/geninterp.mli)22
-rw-r--r--ltac/profile_ltac_tactics.ml439
-rw-r--r--ltac/rewrite.ml (renamed from tactics/rewrite.ml)54
-rw-r--r--ltac/rewrite.mli (renamed from tactics/rewrite.mli)0
-rw-r--r--ltac/tacentries.ml511
-rw-r--r--ltac/tacentries.mli64
-rw-r--r--ltac/tacenv.ml (renamed from tactics/tacenv.ml)5
-rw-r--r--ltac/tacenv.mli (renamed from tactics/tacenv.mli)1
-rw-r--r--ltac/tacintern.ml (renamed from tactics/tacintern.ml)53
-rw-r--r--ltac/tacintern.mli (renamed from tactics/tacintern.mli)0
-rw-r--r--ltac/tacinterp.ml (renamed from tactics/tacinterp.ml)400
-rw-r--r--ltac/tacinterp.mli (renamed from tactics/tacinterp.mli)14
-rw-r--r--ltac/tacsubst.ml (renamed from tactics/tacsubst.ml)17
-rw-r--r--ltac/tacsubst.mli (renamed from tactics/tacsubst.mli)0
-rw-r--r--ltac/tactic_debug.ml (renamed from proofs/tactic_debug.ml)116
-rw-r--r--ltac/tactic_debug.mli (renamed from proofs/tactic_debug.mli)17
-rw-r--r--ltac/tactic_option.ml (renamed from tactics/tactic_option.ml)0
-rw-r--r--ltac/tactic_option.mli (renamed from tactics/tactic_option.mli)0
-rw-r--r--ltac/tauto.ml (renamed from tactics/tauto.ml)23
-rw-r--r--ltac/tauto.mli (renamed from tactics/tauto.mli)0
-rw-r--r--myocamlbuild.ml483
-rw-r--r--parsing/cLexer.ml4 (renamed from parsing/lexer.ml4)13
-rw-r--r--parsing/cLexer.mli (renamed from parsing/lexer.mli)0
-rw-r--r--parsing/compat.ml4102
-rw-r--r--parsing/egramcoq.ml738
-rw-r--r--parsing/egramcoq.mli23
-rw-r--r--parsing/egramml.ml7
-rw-r--r--parsing/egramml.mli2
-rw-r--r--parsing/entry.ml59
-rw-r--r--parsing/entry.mli44
-rw-r--r--parsing/g_constr.ml413
-rw-r--r--parsing/g_prim.ml42
-rw-r--r--parsing/g_tactic.ml421
-rw-r--r--parsing/g_vernac.ml492
-rw-r--r--parsing/highparsing.mllib2
-rw-r--r--parsing/parsing.mllib3
-rw-r--r--parsing/pcoq.ml854
-rw-r--r--parsing/pcoq.mli125
-rw-r--r--parsing/tok.ml20
-rw-r--r--parsing/tok.mli1
-rw-r--r--plugins/btauto/btauto_plugin.mlpack (renamed from plugins/btauto/btauto_plugin.mllib)1
-rw-r--r--plugins/btauto/refl_btauto.ml2
-rw-r--r--plugins/cc/cc_plugin.mlpack (renamed from plugins/cc/cc_plugin.mllib)1
-rw-r--r--plugins/cc/ccalgo.ml33
-rw-r--r--plugins/cc/ccalgo.mli2
-rw-r--r--plugins/cc/ccproof.ml12
-rw-r--r--plugins/cc/cctac.ml37
-rw-r--r--plugins/cc/g_congruence.ml42
-rw-r--r--plugins/decl_mode/decl_expr.mli2
-rw-r--r--plugins/decl_mode/decl_interp.ml2
-rw-r--r--plugins/decl_mode/decl_mode_plugin.mlpack (renamed from plugins/decl_mode/decl_mode_plugin.mllib)1
-rw-r--r--plugins/decl_mode/decl_proof_instr.ml32
-rw-r--r--plugins/decl_mode/g_decl_mode.ml432
-rw-r--r--plugins/derive/derive_plugin.mlpack (renamed from plugins/derive/derive_plugin.mllib)0
-rw-r--r--plugins/derive/g_derive.ml44
-rw-r--r--plugins/extraction/ExtrOcamlZBigInt.v2
-rw-r--r--plugins/extraction/common.ml54
-rw-r--r--plugins/extraction/extract_env.ml5
-rw-r--r--plugins/extraction/extraction.ml80
-rw-r--r--plugins/extraction/extraction_plugin.mlpack (renamed from plugins/extraction/extraction_plugin.mllib)1
-rw-r--r--plugins/extraction/g_extraction.ml410
-rw-r--r--plugins/extraction/haskell.ml4
-rw-r--r--plugins/extraction/json.ml5
-rw-r--r--plugins/extraction/modutil.ml8
-rw-r--r--plugins/extraction/table.ml28
-rw-r--r--plugins/extraction/table.mli2
-rw-r--r--plugins/firstorder/g_ground.ml410
-rw-r--r--plugins/firstorder/ground.ml2
-rw-r--r--plugins/firstorder/ground_plugin.mlpack (renamed from plugins/firstorder/ground_plugin.mllib)1
-rw-r--r--plugins/firstorder/instances.ml11
-rw-r--r--plugins/firstorder/rules.ml14
-rw-r--r--plugins/fourier/fourierR.ml1
-rw-r--r--plugins/fourier/fourier_plugin.mlpack (renamed from plugins/fourier/fourier_plugin.mllib)1
-rw-r--r--plugins/funind/functional_principles_proofs.ml30
-rw-r--r--plugins/funind/functional_principles_types.ml4
-rw-r--r--plugins/funind/g_indfun.ml418
-rw-r--r--plugins/funind/glob_term_to_relation.ml4
-rw-r--r--plugins/funind/indfun.ml8
-rw-r--r--plugins/funind/indfun_common.ml2
-rw-r--r--plugins/funind/indfun_common.mli2
-rw-r--r--plugins/funind/invfun.ml13
-rw-r--r--plugins/funind/merge.ml14
-rw-r--r--plugins/funind/recdef.ml32
-rw-r--r--plugins/funind/recdef_plugin.mlpack (renamed from plugins/funind/recdef_plugin.mllib)1
-rw-r--r--plugins/micromega/Lia.v2
-rw-r--r--plugins/micromega/Psatz.v4
-rw-r--r--plugins/micromega/QMicromega.v2
-rw-r--r--plugins/micromega/RMicromega.v2
-rw-r--r--plugins/micromega/RingMicromega.v2
-rw-r--r--plugins/micromega/ZMicromega.v2
-rw-r--r--plugins/micromega/certificate.ml3
-rw-r--r--plugins/micromega/coq_micromega.ml52
-rw-r--r--plugins/micromega/g_micromega.ml43
-rw-r--r--plugins/micromega/micromega_plugin.mlpack (renamed from plugins/micromega/micromega_plugin.mllib)1
-rw-r--r--plugins/micromega/persistent_cache.ml8
-rw-r--r--plugins/nsatz/g_nsatz.ml4 (renamed from tools/compat5b.ml)12
-rw-r--r--plugins/nsatz/nsatz.ml (renamed from plugins/nsatz/nsatz.ml4)8
-rw-r--r--plugins/nsatz/nsatz_plugin.mlpack (renamed from plugins/nsatz/nsatz_plugin.mllib)2
-rw-r--r--plugins/omega/coq_omega.ml90
-rw-r--r--plugins/omega/g_omega.ml41
-rw-r--r--plugins/omega/omega_plugin.mlpack (renamed from plugins/omega/omega_plugin.mllib)1
-rw-r--r--plugins/plugins.itarget3
-rw-r--r--plugins/pluginsbyte.itarget22
-rw-r--r--plugins/pluginsdyn.itarget25
-rw-r--r--plugins/pluginsopt.itarget22
-rw-r--r--plugins/pluginsvo.itarget13
-rw-r--r--plugins/quote/g_quote.ml43
-rw-r--r--plugins/quote/quote_plugin.mllib3
-rw-r--r--plugins/quote/quote_plugin.mlpack2
-rw-r--r--plugins/romega/ReflOmegaCore.v5
-rw-r--r--plugins/romega/g_romega.ml41
-rw-r--r--plugins/romega/refl_omega.ml8
-rw-r--r--plugins/romega/romega_plugin.mlpack (renamed from plugins/romega/romega_plugin.mllib)1
-rw-r--r--plugins/rtauto/proof_search.ml2
-rw-r--r--plugins/rtauto/refl_tauto.ml14
-rw-r--r--plugins/rtauto/rtauto_plugin.mlpack (renamed from plugins/rtauto/rtauto_plugin.mllib)1
-rw-r--r--plugins/setoid_ring/ArithRing.v4
-rw-r--r--plugins/setoid_ring/InitialRing.v48
-rw-r--r--plugins/setoid_ring/NArithRing.v2
-rw-r--r--plugins/setoid_ring/Ring.v6
-rw-r--r--plugins/setoid_ring/ZArithRing.v8
-rw-r--r--plugins/setoid_ring/g_newring.ml430
-rw-r--r--plugins/setoid_ring/newring.ml57
-rw-r--r--plugins/setoid_ring/newring.mli4
-rw-r--r--plugins/setoid_ring/newring_plugin.mllib3
-rw-r--r--plugins/setoid_ring/newring_plugin.mlpack2
-rw-r--r--plugins/syntax/ascii_syntax.ml4
-rw-r--r--plugins/syntax/ascii_syntax_plugin.mllib2
-rw-r--r--plugins/syntax/ascii_syntax_plugin.mlpack1
-rw-r--r--plugins/syntax/nat_syntax.ml6
-rw-r--r--plugins/syntax/nat_syntax_plugin.mllib2
-rw-r--r--plugins/syntax/nat_syntax_plugin.mlpack1
-rw-r--r--plugins/syntax/numbers_syntax.ml6
-rw-r--r--plugins/syntax/numbers_syntax_plugin.mllib2
-rw-r--r--plugins/syntax/numbers_syntax_plugin.mlpack1
-rw-r--r--plugins/syntax/r_syntax.ml4
-rw-r--r--plugins/syntax/r_syntax_plugin.mllib2
-rw-r--r--plugins/syntax/r_syntax_plugin.mlpack1
-rw-r--r--plugins/syntax/string_syntax.ml6
-rw-r--r--plugins/syntax/string_syntax_plugin.mllib2
-rw-r--r--plugins/syntax/string_syntax_plugin.mlpack1
-rw-r--r--plugins/syntax/z_syntax.ml4
-rw-r--r--plugins/syntax/z_syntax_plugin.mllib2
-rw-r--r--plugins/syntax/z_syntax_plugin.mlpack1
-rw-r--r--pretyping/cases.ml36
-rw-r--r--pretyping/cases.mli2
-rw-r--r--pretyping/cbv.ml2
-rw-r--r--pretyping/classops.ml2
-rw-r--r--pretyping/classops.mli3
-rw-r--r--pretyping/coercion.ml24
-rw-r--r--pretyping/constr_matching.ml4
-rw-r--r--pretyping/detyping.ml2
-rw-r--r--pretyping/evarconv.ml100
-rw-r--r--pretyping/evardefine.ml207
-rw-r--r--pretyping/evardefine.mli46
-rw-r--r--pretyping/evarsolve.ml1
-rw-r--r--pretyping/find_subterm.ml1
-rw-r--r--pretyping/glob_ops.ml16
-rw-r--r--pretyping/glob_ops.mli1
-rw-r--r--pretyping/indrec.ml4
-rw-r--r--pretyping/nativenorm.ml7
-rw-r--r--pretyping/patternops.ml2
-rw-r--r--pretyping/pretype_errors.ml5
-rw-r--r--pretyping/pretype_errors.mli1
-rw-r--r--pretyping/pretyping.ml59
-rw-r--r--pretyping/pretyping.mli14
-rw-r--r--pretyping/pretyping.mllib4
-rw-r--r--pretyping/recordops.ml4
-rw-r--r--pretyping/reductionops.ml41
-rw-r--r--pretyping/typeclasses.ml4
-rw-r--r--pretyping/typing.ml4
-rw-r--r--pretyping/unification.ml55
-rw-r--r--printing/genprint.ml5
-rw-r--r--printing/ppannotation.ml2
-rw-r--r--printing/ppannotation.mli1
-rw-r--r--printing/ppconstr.ml8
-rw-r--r--printing/pptactic.ml763
-rw-r--r--printing/pptactic.mli7
-rw-r--r--printing/pptacticsig.mli16
-rw-r--r--printing/ppvernac.ml98
-rw-r--r--printing/prettyp.ml4
-rw-r--r--printing/printer.ml76
-rw-r--r--printing/printing.mllib4
-rw-r--r--printing/printmod.ml1
-rw-r--r--proofs/clenv.ml3
-rw-r--r--proofs/clenv.mli4
-rw-r--r--proofs/clenvtac.mli2
-rw-r--r--proofs/evar_refiner.ml11
-rw-r--r--proofs/evar_refiner.mli5
-rw-r--r--proofs/goal.mli4
-rw-r--r--proofs/logic.ml102
-rw-r--r--proofs/logic.mli2
-rw-r--r--proofs/pfedit.ml30
-rw-r--r--proofs/pfedit.mli10
-rw-r--r--proofs/proof.ml50
-rw-r--r--proofs/proof_global.ml37
-rw-r--r--proofs/proof_global.mli10
-rw-r--r--proofs/proof_type.ml52
-rw-r--r--proofs/proof_type.mli46
-rw-r--r--proofs/proof_using.ml2
-rw-r--r--proofs/proof_using.mli2
-rw-r--r--proofs/proofs.mllib5
-rw-r--r--proofs/redexpr.ml4
-rw-r--r--proofs/redexpr.mli2
-rw-r--r--proofs/refine.ml120
-rw-r--r--proofs/refine.mli42
-rw-r--r--proofs/refiner.ml5
-rw-r--r--proofs/refiner.mli2
-rw-r--r--proofs/tacmach.ml11
-rw-r--r--proofs/tacmach.mli5
-rw-r--r--stm/asyncTaskQueue.ml18
-rw-r--r--stm/dag.ml94
-rw-r--r--stm/dag.mli50
-rw-r--r--stm/lemmas.ml16
-rw-r--r--stm/lemmas.mli1
-rw-r--r--stm/proofBlockDelimiter.ml184
-rw-r--r--stm/proofBlockDelimiter.mli41
-rw-r--r--stm/spawned.ml13
-rw-r--r--stm/stm.ml851
-rw-r--r--stm/stm.mli91
-rw-r--r--stm/stm.mllib2
-rw-r--r--stm/vcs.ml75
-rw-r--r--stm/vcs.mli66
-rw-r--r--stm/vernac_classifier.ml48
-rw-r--r--tactics/auto.ml23
-rw-r--r--tactics/auto.mli9
-rw-r--r--tactics/autorewrite.ml23
-rw-r--r--tactics/autorewrite.mli6
-rw-r--r--tactics/class_tactics.ml17
-rw-r--r--tactics/class_tactics.mli2
-rw-r--r--tactics/contradiction.ml2
-rw-r--r--tactics/eauto.ml (renamed from tactics/eauto.ml4)186
-rw-r--r--tactics/eauto.mli14
-rw-r--r--tactics/elim.ml6
-rw-r--r--tactics/eqdecide.ml23
-rw-r--r--tactics/equality.ml84
-rw-r--r--tactics/equality.mli5
-rw-r--r--tactics/g_auto.ml476
-rw-r--r--tactics/geninterp.ml35
-rw-r--r--tactics/hightactics.mllib12
-rw-r--r--tactics/hints.ml76
-rw-r--r--tactics/hints.mli2
-rw-r--r--tactics/hipattern.ml (renamed from tactics/hipattern.ml4)78
-rw-r--r--tactics/inv.ml4
-rw-r--r--tactics/taccoerce.ml34
-rw-r--r--tactics/taccoerce.mli4
-rw-r--r--tactics/tactics.ml497
-rw-r--r--tactics/tactics.mli42
-rw-r--r--tactics/tactics.mllib11
-rw-r--r--test-suite/Makefile9
-rw-r--r--test-suite/bugs/4623.v5
-rw-r--r--test-suite/bugs/4624.v7
-rw-r--r--test-suite/bugs/closed/1850.v4
-rw-r--r--test-suite/bugs/closed/2848.v7
-rw-r--r--test-suite/bugs/closed/3080.v18
-rw-r--r--test-suite/bugs/closed/3612.v2
-rw-r--r--test-suite/bugs/closed/3649.v5
-rw-r--r--test-suite/bugs/closed/3699.v4
-rw-r--r--test-suite/bugs/closed/3825.v16
-rw-r--r--test-suite/bugs/closed/3881.v2
-rw-r--r--test-suite/bugs/closed/3922.v2
-rw-r--r--test-suite/bugs/closed/4292.v7
-rw-r--r--test-suite/bugs/closed/4498.v24
-rw-r--r--test-suite/bugs/closed/4533.v226
-rw-r--r--test-suite/bugs/closed/4538.v1
-rw-r--r--test-suite/bugs/closed/4544.v1007
-rw-r--r--test-suite/bugs/closed/4576.v3
-rw-r--r--test-suite/bugs/closed/4588.v10
-rw-r--r--test-suite/bugs/closed/4596.v14
-rw-r--r--test-suite/bugs/closed/4603.v10
-rw-r--r--test-suite/bugs/closed/4616.v4
-rw-r--r--test-suite/bugs/closed/4627.v49
-rw-r--r--test-suite/bugs/closed/4628.v46
-rw-r--r--test-suite/bugs/closed/4634.v16
-rw-r--r--test-suite/bugs/closed/4644.v52
-rw-r--r--test-suite/bugs/closed/4656.v4
-rw-r--r--test-suite/bugs/closed/4663.v3
-rw-r--r--test-suite/bugs/closed/4670.v7
-rw-r--r--test-suite/bugs/closed/4695.v38
-rw-r--r--test-suite/bugs/closed/4710.v12
-rw-r--r--test-suite/bugs/closed/4713.v10
-rw-r--r--test-suite/bugs/closed/4737.v9
-rw-r--r--test-suite/bugs/closed/4746.v14
-rw-r--r--test-suite/bugs/closed/4782.v9
-rw-r--r--test-suite/bugs/closed/4787.v9
-rw-r--r--test-suite/bugs/closed/4813.v9
-rw-r--r--test-suite/bugs/closed/4816.v17
-rw-r--r--test-suite/bugs/opened/3410.v1
-rw-r--r--test-suite/bugs/opened/4813.v5
-rw-r--r--test-suite/complexity/ring2.v2
-rw-r--r--test-suite/failure/int31.v17
-rw-r--r--test-suite/ide/undo013.fake2
-rw-r--r--test-suite/ide/undo014.fake2
-rw-r--r--test-suite/ide/undo015.fake2
-rw-r--r--test-suite/ide/undo016.fake2
-rw-r--r--test-suite/interactive/proof_block.v66
-rw-r--r--test-suite/output/Cases.out4
-rw-r--r--test-suite/output/InitSyntax.out3
-rw-r--r--test-suite/output/Intuition.out2
-rw-r--r--test-suite/output/Naming.out40
-rw-r--r--test-suite/output/Notations2.out4
-rw-r--r--test-suite/output/Notations2.v8
-rw-r--r--test-suite/output/PrintInfos.out4
-rw-r--r--test-suite/output/Quote.out18
-rw-r--r--test-suite/output/ltac.out22
-rw-r--r--test-suite/output/ltac.v28
-rw-r--r--test-suite/output/set.out6
-rw-r--r--test-suite/output/simpl.out6
-rw-r--r--test-suite/output/subst.out97
-rw-r--r--test-suite/output/subst.v48
-rw-r--r--test-suite/success/CaseInClause.v4
-rw-r--r--test-suite/success/Compat84.v19
-rw-r--r--test-suite/success/MatchFail.v8
-rw-r--r--test-suite/success/Notations2.v92
-rw-r--r--test-suite/success/TacticNotation2.v12
-rw-r--r--test-suite/success/auto.v89
-rw-r--r--test-suite/success/bigQ.v66
-rw-r--r--test-suite/success/cc.v7
-rw-r--r--test-suite/success/coindprim.v85
-rw-r--r--test-suite/success/keyedrewrite.v3
-rw-r--r--test-suite/success/ltac.v14
-rw-r--r--test-suite/success/ltacprof.v8
-rw-r--r--test-suite/success/primitiveproj.v16
-rw-r--r--test-suite/success/remember.v13
-rw-r--r--test-suite/success/setoid_test.v13
-rw-r--r--test-suite/success/univers.v17
-rw-r--r--test-suite/typeclasses/open_constr.v12
-rw-r--r--theories/Classes/CMorphisms.v4
-rw-r--r--theories/Classes/Morphisms.v2
-rw-r--r--theories/Classes/SetoidTactics.v16
-rw-r--r--theories/Compat/Coq84.v49
-rw-r--r--theories/Compat/Coq85.v4
-rw-r--r--theories/Init/Notations.v6
-rw-r--r--theories/MSets/MSetAVL.v1
-rw-r--r--theories/Numbers/Cyclic/Int31/Ring31.v20
-rw-r--r--theories/Numbers/Integer/BigZ/BigZ.v22
-rw-r--r--theories/Numbers/Natural/BigN/BigN.v24
-rw-r--r--theories/Numbers/Natural/Peano/NPeano.v84
-rw-r--r--theories/Numbers/Rational/BigQ/BigQ.v14
-rw-r--r--theories/Program/Equality.v4
-rw-r--r--theories/Program/Tactics.v2
-rw-r--r--theories/Reals/Ranalysis_reg.v109
-rw-r--r--theories/Vectors/VectorDef.v2
-rw-r--r--theories/ZArith/Int.v18
-rw-r--r--theories/ZArith/Zsqrt_compat.v4
-rw-r--r--theories/theories.itarget25
-rw-r--r--tools/coq_makefile.ml356
-rw-r--r--tools/coqc.ml3
-rw-r--r--tools/coqdep.ml4
-rw-r--r--tools/coqdep_common.ml6
-rw-r--r--tools/coqdoc/cpretty.mll205
-rw-r--r--tools/coqdoc/index.ml26
-rw-r--r--tools/coqdoc/output.ml3
-rw-r--r--tools/fake_ide.ml16
-rw-r--r--tools/ocamllibdep.mll60
-rw-r--r--toplevel/assumptions.ml95
-rw-r--r--toplevel/cerrors.ml30
-rw-r--r--toplevel/cerrors.mli1
-rw-r--r--toplevel/class.ml4
-rw-r--r--toplevel/classes.ml14
-rw-r--r--toplevel/classes.mli1
-rw-r--r--toplevel/command.ml15
-rw-r--r--toplevel/coqinit.ml12
-rw-r--r--toplevel/coqloop.ml18
-rw-r--r--toplevel/coqtop.ml66
-rw-r--r--toplevel/discharge.ml1
-rw-r--r--toplevel/himsg.ml99
-rw-r--r--toplevel/himsg.mli3
-rw-r--r--toplevel/indschemes.ml17
-rw-r--r--toplevel/locality.ml2
-rw-r--r--toplevel/metasyntax.ml257
-rw-r--r--toplevel/metasyntax.mli9
-rw-r--r--toplevel/mltop.ml10
-rw-r--r--toplevel/obligations.ml55
-rw-r--r--toplevel/obligations.mli6
-rw-r--r--toplevel/record.ml34
-rw-r--r--toplevel/search.ml41
-rw-r--r--toplevel/search.mli10
-rw-r--r--toplevel/usage.ml2
-rw-r--r--toplevel/vernac.ml89
-rw-r--r--toplevel/vernacentries.ml281
-rw-r--r--toplevel/vernacentries.mli5
-rw-r--r--toplevel/vernacinterp.ml4
632 files changed, 15675 insertions, 11603 deletions
diff --git a/.gitignore b/.gitignore
index 5c932ad02..56e190598 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,7 +44,6 @@ TAGS
.pc
bin/
_build
-plugins/*/*_mod.ml
myocamlbuild_config.ml
config/Makefile
config/coq_config.ml
@@ -107,43 +106,28 @@ dev/ocamlweb-doc/lex.ml
ide/coq_lex.ml
ide/config_lexer.ml
ide/utf8_convert.ml
-ide/highlight.ml
-plugins/dp/dp_zenon.ml
tools/gallina_lexer.ml
tools/coqwc.ml
tools/coqdep_lexer.ml
tools/ocamllibdep.ml
tools/coqdoc/cpretty.ml
-lib/xml_lexer.ml
+ide/xml_lexer.ml
-# .ml4 files
+# .ml4 / .mlp files
g_*.ml
ide/project_file.ml
-lib/pp.ml
parsing/compat.ml
grammar/q_util.ml
-grammar/q_constr.ml
-grammar/q_coqast.ml
grammar/tacextend.ml
grammar/vernacextend.ml
grammar/argextend.ml
-parsing/pcoq.ml
-parsing/lexer.ml
-plugins/setoid_ring/newring.ml
-plugins/field/field.ml
-plugins/nsatz/nsatz.ml
-tactics/tauto.ml
-tactics/eauto.ml
-tactics/hipattern.ml
-tactics/class_tactics.ml
-tactics/coretactics.ml
-tactics/rewrite.ml
-tactics/eqdecide.ml
-tactics/extratactics.ml
-tactics/extraargs.ml
-toplevel/whelp.ml
+parsing/cLexer.ml
+ltac/coretactics.ml
+ltac/extratactics.ml
+ltac/extraargs.ml
+ltac/profile_ltac_tactics.ml
ide/coqide_main.ml
# other auto-generated files
@@ -154,6 +138,10 @@ tools/tolink.ml
theories/Numbers/Natural/BigN/NMake_gen.v
ide/index_urls.txt
lia.cache
+checker/names.ml
+checker/names.mli
+checker/esubst.ml
+checker/esubst.mli
# mlis documentation
@@ -171,3 +159,4 @@ dev/myinclude
/doc/refman/Reference-Manual.hoptind
/doc/refman/Reference-Manual.optidx
/doc/refman/Reference-Manual.optind
+user-contrib
diff --git a/CHANGES b/CHANGES
index e80a3b454..ae9b97929 100644
--- a/CHANGES
+++ b/CHANGES
@@ -13,12 +13,107 @@ Tactics
- In introduction patterns of the form (pat1,...,patn), n should match
the exact number of hypotheses introduced (except for local definitions
for which pattern can be omitted, as in regular pattern-matching).
+- Tactic scopes in Ltac like constr: and ltac: now require parentheses around
+ their argument.
+- Every generic argument type declares a tactic scope of the form "name:(...)"
+ where name is the name of the argument. This generalizes the constr: and ltac:
+ instances.
+- When in strict mode (i.e. in a Ltac definition) the "intro" tactic cannot use
+ a locally free identifier anymore. It must use e.g. the "fresh" primitive
+ instead (potential source of incompatibilities).
Program
- The "Shrink Obligations" flag now applies to all obligations, not only those
solved by the automatic tactic.
+Notations
+
+- "Bind Scope" can once again bind "Funclass" and "Sortclass".
+
+Tools
+
+- coqc accepts a -o option to specify the output file name
+
+Changes from V8.5pl1 to V8.5pl2
+===============================
+
+Bugfixes
+
+- #4677: fix alpha-conversion in notations needing eta-expansion.
+- Fully preserve initial order of hypotheses in "Regular Subst Tactic" mode.
+- #4644: a regression in unification.
+- #4777: printing inefficiency with implicit arguments
+- #4752: CoqIDE crash on files not ended by ".v".
+- #4398: type_scope used consistently in "match goal".
+
+Changes from V8.5 to V8.5pl1
+============================
+
+Critical bugfix
+- The subterm relation for the guard condition was incorrectly defined on
+ primitive projections (#4588)
+
+Plugin development tools
+- add a .merlin target to the makefile
+
+Various performance improvements (time, space used by .vo files)
+
+Other bugfixes
+
+- Fix order of arguments to Big.compare_case in ExtrOcamlZBigInt.v
+- Added compatibility coercions from Specif.v which were present in Coq 8.4.
+- Fixing a source of inefficiency and an artificial dependency in the printer in the congruence tactic.
+- Allow to unset the refinement mode of Instance in ML
+- Fixing an incorrect use of prod_appvect on a term which was not a product in setoid_rewrite.
+- Add -compat 8.4 econstructor tactics, and tests
+- Add compatibility Nonrecursive Elimination Schemes
+- Fixing the "No applicable tactic" non informative error message regression on apply.
+- Univs: fix get_current_context (bug #4603, part I)
+- Fix a bug in Program coercion code
+- Fix handling of arity of definitional classes.
+- #4630: Some tactics are 20x slower in 8.5 than 8.4.
+- #4627: records with no declared arity can be template polymorphic.
+- #4623: set tactic too weak with universes (regression)
+- Fix incorrect behavior of CS resolution
+- #4591: Uncaught exception in directory browsing.
+- CoqIDE is more resilient to initialization errors.
+- #4614: "Fully check the document" is uninterruptable.
+- Try eta-expansion of records only on non-recursive ones
+- Fix bug when a sort is ascribed to a Record
+- Primitive projections: protect kernel from erroneous definitions.
+- Fixed bug #4533 with previous Keyed Unification commit
+- Win: kill unreliable hence do not waitpid after kill -9 (Close #4369)
+- Fix strategy of Keyed Unification
+- #4608: Anomaly "output_value: abstract value (outside heap)".
+- #4607: do not read native code files if native compiler was disabled.
+- #4105: poor escaping in the protocol between CoqIDE and coqtop.
+- #4596: [rewrite] broke in the past few weeks.
+- #4533 (partial): respect declared global transparency of projections in unification.ml
+- #4544: Backtrack on using full betaiota reduction during keyed unification.
+- #4540: CoqIDE bottom progress bar does not update.
+- Fix regression from 8.4 in reflexivity
+- #4580: [Set Refine Instance Mode] also used for Program Instance.
+- #4582: cannot override notation [ x ]. MAY CREATE INCOMPATIBILITIES, see #4683.
+- STM: Print/Extraction have to be skipped if -quick
+- #4542: CoqIDE: STOP button also stops workers
+- STM: classify some variants of Instance as regular `Fork nodes.
+- #4574: Anomaly: Uncaught exception Invalid_argument("splay_arity").
+- Do not give a name to anonymous evars anymore. See bug #4547.
+- STM: always stock in vio files the first node (state) of a proof
+- STM: not delegate proofs that contain Vernac(Module|Require|Import), #4530
+- Don't fail fatally if PATH is not set.
+- #4537: Coq 8.5 is slower in typeclass resolution.
+- #4522: Incorrect "Warning..." on windows.
+- #4373: coqdep does not know about .vio files.
+- #3826: "Incompatible module types" is uninformative.
+- #4495: Failed assertion in metasyntax.ml.
+- #4511: evar tactic can create non-typed evars.
+- #4503: mixing universe polymorphic and monomorphic variables and definitions in sections is unsupported.
+- #4519: oops, global shadowed local universe level bindings.
+- #4506: Anomaly: File "pretyping/indrec.ml", line 169, characters 14-20: Assertion failed.
+- #4548: Coqide crashes when going back one command
+
Changes from V8.5beta3 to V8.5
==============================
diff --git a/COMPATIBILITY b/COMPATIBILITY
index ab29903b9..883b8576d 100644
--- a/COMPATIBILITY
+++ b/COMPATIBILITY
@@ -1,6 +1,43 @@
Potential sources of incompatibilities between Coq V8.4 and V8.5
----------------------------------------------------------------
+* List of typical changes to be done to adapt files from Coq 8.4 *
+* to Coq 8.5 when not using compatibility option "-compat 8.4". *
+
+Symptom: "The reference omega was not found in the current environment".
+Cause: "Require Omega" does not import the tactic "omega" any more
+Possible solutions:
+- use "Require Import OmegaTactic" (not compatible with 8.4)
+- use "Require Import Omega" (compatible with 8.4)
+- add definition "Ltac omega := Coq.omega.Omega.omega."
+
+Symptom: "intuition" cannot solve a goal (not working anymore on non standard connective)
+Cause: "intuition" had an accidental non uniform behavior fixed on non standard connectives
+Possible solutions:
+- use "dintuition" instead; it is stronger than "intuition" and works
+ uniformly on non standard connectives, such as n-ary conjunctions or disjunctions
+ (not compatible with 8.4)
+- do the script differently
+
+Symptom: The constructor foo (in type bar) expects n arguments.
+Cause: parameters must now be given in patterns
+Possible solutions:
+- use option "Set Asymmetric Patterns" (compatible with 8.4)
+- add "_" for the parameters (not compatible with 8.4)
+- turn the parameters into implicit arguments (compatible with 8.4)
+
+Symptom: "NPeano.Nat.foo" not existing anymore
+Possible solutions:
+- use "Nat.foo" instead
+
+Symptom: typing problems with proj1_sig or similar
+Cause: coercion from sig to sigT and similar coercions have been
+ removed so as to make the initial state easier to understand for
+ beginners
+Solution: change proj1_sig into projT1 and similarly (compatible with 8.4)
+
+* Other detailed changes *
+
(see also file CHANGES)
- options for *coq* compilation (see below for ocaml).
@@ -30,7 +67,6 @@ Potential sources of incompatibilities between Coq V8.4 and V8.5
for more details: file CHANGES or section "Customization at launch
time" of the reference manual.
-
- Universe Polymorphism.
diff --git a/INSTALL b/INSTALL
index 955150c2c..5a300010d 100644
--- a/INSTALL
+++ b/INSTALL
@@ -29,16 +29,17 @@ WHAT DO YOU NEED ?
To compile Coq V8.5 yourself, you need:
- - Objective Caml version 3.12.1 or later
+ - Objective Caml version 4.01.0 or later
(available at http://caml.inria.fr/)
- Findlib (included in OCaml binary distribution under windows,
probably available in your distribution and for sure at
http://projects.camlcity.org/projects/findlib.html)
-
- - Camlp5 (version >= 6.02) (Coq compiles with Camlp4 but might be less
- well supported)
+ - Camlp5 (version >= 6.02) (Coq compiles with Camlp4 but might be
+ less well supported, for instance, Objective Caml version 4.02.1
+ is then needed or a patched version of 4.01.0 as e.g. version
+ 4.01.0-4 in Debian Jessie)
- GNU Make version 3.81 or later
@@ -64,7 +65,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 3.12.1 are
+ versions of Objective Caml later or equal to 4.01.0 are
supported to the exception of Objective Caml 4.02.0.
To get Coq in native-code, (it runs 4 to 10 times faster than
diff --git a/INSTALL.ide b/INSTALL.ide
index b651e77db..cb7ca325f 100644
--- a/INSTALL.ide
+++ b/INSTALL.ide
@@ -22,7 +22,7 @@ Else, read the rest of this document to compile your own CoqIde.
COMPILATION REQUIREMENTS
-- OCaml >= 3.12.1 with native threads support.
+- OCaml >= 4.01 with native threads support.
- make world must succeed.
- The graphical toolkit GTK+ 2.x. See http://www.gtk.org.
The official supported version is at least 2.24.x.
diff --git a/Makefile b/Makefile
index c5415d9f6..93b89a489 100644
--- a/Makefile
+++ b/Makefile
@@ -63,15 +63,10 @@ define findx
$(shell find . $(FIND_VCS_CLAUSE) '(' -name $(1) ')' -exec $(2) {} \; | sed 's|^\./||')
endef
-# We now discriminate .ml4 files according to their need of grammar.cma
-# or q_constr.cmo
-USEGRAMMAR := '(\*.*camlp4deps.*grammar'
-
## Files in the source tree
LEXFILES := $(call find, '*.mll')
-export MLLIBFILES := $(call find, '*.mllib')
-export ML4BASEFILES := $(call findx, '*.ml4', grep -L -e $(USEGRAMMAR))
+export MLLIBFILES := $(call find, '*.mllib') $(call find, '*.mlpack')
export ML4FILES := $(call find, '*.ml4')
export CFILES := $(call find, '*.c')
@@ -85,9 +80,7 @@ EXISTINGMLI := $(call find, '*.mli')
## Files that will be generated
GENML4FILES:= $(ML4FILES:.ml4=.ml)
-GENPLUGINSMOD:=$(filter plugins/%,$(MLLIBFILES:%.mllib=%_mod.ml))
-export GENMLFILES:=$(LEXFILES:.mll=.ml) $(GENPLUGINSMOD) \
- tools/tolink.ml kernel/copcodes.ml
+export GENMLFILES:=$(LEXFILES:.mll=.ml) tools/tolink.ml kernel/copcodes.ml
export GENHFILES:=kernel/byterun/coq_jumptbl.h
export GENVFILES:=theories/Numbers/Natural/BigN/NMake_gen.v
export GENFILES:=$(GENMLFILES) $(GENMLIFILES) $(GENHFILES) $(GENVFILES)
@@ -150,10 +143,7 @@ endif
MAKE_OPTS := --warn-undefined-variable --no-builtin-rules
-GRAM_TARGETS := grammar/grammar.cma grammar/q_constr.cmo
-
submake:
- $(MAKE) $(MAKE_OPTS) -f Makefile.build BUILDGRAMMAR=1 $(GRAM_TARGETS)
$(MAKE) $(MAKE_OPTS) -f Makefile.build $(MAKECMDGOALS)
noconfig:
@@ -161,7 +151,7 @@ noconfig:
# To speed-up things a bit, let's dissuade make to attempt rebuilding makefiles
-Makefile Makefile.build Makefile.common config/Makefile : ;
+Makefile $(wildcard Makefile.*) config/Makefile : ;
###########################################################################
# Cleaning
@@ -181,7 +171,7 @@ cruftclean: ml4clean
indepclean:
rm -f $(GENFILES)
- rm -f $(COQTOPBYTE) $(CHICKENBYTE) $(FAKEIDE)
+ rm -f $(COQTOPBYTE) $(CHICKENBYTE)
find . \( -name '*~' -o -name '*.cm[ioat]' -o -name '*.cmti' \) -delete
rm -f */*.pp[iox] plugins/*/*.pp[iox]
rm -rf $(SOURCEDOCDIR)
@@ -214,8 +204,8 @@ archclean: clean-ide optclean voclean
rm -f $(ALLSTDLIB).*
optclean:
- rm -f $(COQTOPEXE) $(COQMKTOP) $(COQC) $(CHICKEN) $(COQDEPBOOT)
- rm -f $(TOOLS) $(CSDPCERT)
+ rm -f $(COQTOPEXE) $(COQMKTOP) $(CHICKEN)
+ rm -f $(TOOLS) $(PRIVATEBINARIES) $(CSDPCERT)
find . -name '*.cmx' -o -name '*.cmxs' -o -name '*.cmxa' -o -name '*.[soa]' -o -name '*.so' | xargs rm -f
clean-ide:
@@ -244,6 +234,7 @@ distclean: clean cleanconfig cacheclean
voclean:
find theories plugins test-suite \( -name '*.vo' -o -name '*.glob' -o -name "*.cmxs" -o -name "*.native" -o -name "*.cmx" -o -name "*.cmi" -o -name "*.o" \) -delete
+ find theories plugins test-suite -name .coq-native -empty -delete
devdocclean:
find . -name '*.dep.ps' -o -name '*.dot' | xargs rm -f
diff --git a/Makefile.build b/Makefile.build
index ffac80cb8..4eafe1d61 100644
--- a/Makefile.build
+++ b/Makefile.build
@@ -10,45 +10,48 @@
# some variables.
###########################################################################
-# Starting rule
+# Default starting rule
###########################################################################
-# build the different subsystems: coq, coqide
-world: revision coq coqide documentation
+# build the different subsystems:
-.PHONY: world
+world: coq coqide documentation revision
+
+coq: coqlib coqbinaries tools printers
+
+.PHONY: world coq
###########################################################################
# Includes
###########################################################################
+# This list of ml files used to be in the main Makefile, we moved it here
+# to avoid exhausting the variable env in Win32
+MLFILES := $(MLSTATICFILES) $(GENMLFILES) $(ML4FILES:.ml4=.ml)
+
include Makefile.common
-include Makefile.doc
+include Makefile.doc ## provides the 'documentation' rule
+include Makefile.checker
+include Makefile.ide ## provides the 'coqide' rule
+include Makefile.install
+include Makefile.dev ## provides the 'printers' and 'revision' rules
-# In a first phase, we restrict to the basic .ml4 (the ones without grammar.cma)
+# This include below will lauch the build of all .d.
+# The - at front is for disabling warnings about currently missing ones.
+# For creating the missing .d, make will recursively build things like
+# coqdep_boot (for the .v.d files) or grammar.cma (for .ml4 -> .ml -> .ml.d).
-ifdef BUILDGRAMMAR
- MLFILES := $(MLSTATICFILES) $(GENMLFILES) $(ML4BASEFILES:.ml4=.ml)
- CURFILES := $(MLFILES) $(MLIFILES) $(ML4BASEFILES) grammar/grammar.mllib
-else
- MLFILES := $(MLSTATICFILES) $(GENMLFILES) $(ML4FILES:.ml4=.ml)
- CURFILES := $(MLFILES) $(MLIFILES) $(ML4FILES) $(MLLIBFILES) $(CFILES) $(VFILES)
-endif
+DEPENDENCIES := \
+ $(addsuffix .d, $(MLFILES) $(MLIFILES) $(MLLIBFILES) $(CFILES) $(VFILES))
-CURDEPS:=$(addsuffix .d, $(CURFILES))
+-include $(DEPENDENCIES)
# All dependency includes must be declared secondary, otherwise make will
# delete them if it decided to build them by dependency instead of because
# of include, and they will then be automatically deleted, leading to an
# infinite loop.
-.SECONDARY: $(CURDEPS) $(GENFILES) $(ML4FILES:.ml4=.ml)
-
-# This include below will lauch the build of all concerned .d.
-# The - at front is for disabling warnings about currently missing ones.
-
--include $(CURDEPS)
-
+.SECONDARY: $(DEPENDENCIES) $(GENFILES) $(ML4FILES:.ml4=.ml)
###########################################################################
# Compilation options
@@ -62,14 +65,13 @@ NO_RECALC_DEPS=
READABLE_ML4= # non-empty means .ml of .ml4 will be ascii instead of binary
VALIDATE=
COQ_XML= # is "-xml" when building XML library
-VM= # is "-no-vm" to not use the vm"
TIMED= # non-empty will activate a default time command
# when compiling .v (see $(STDTIME) below)
TIMECMD= # if you prefer a specific time command instead of $(STDTIME)
# e.g. "'time -p'"
-CAMLFLAGS:=${CAMLFLAGS} -w -3
+
# NB: if you want to collect compilation timings of .v and import them
# in a spreadsheet, I suggest something like:
# make TIMED=1 2> timings.csv
@@ -81,7 +83,7 @@ CAMLFLAGS:=${CAMLFLAGS} -w -3
STDTIME=/usr/bin/time -f "$* (user: %U mem: %M ko)"
TIMER=$(if $(TIMED), $(STDTIME), $(TIMECMD))
-COQOPTS=$(COQ_XML) $(VM) $(NATIVECOMPUTE)
+COQOPTS=$(COQ_XML) $(NATIVECOMPUTE)
BOOTCOQC=$(TIMER) $(COQTOPEXE) -boot $(COQOPTS) -compile
# The SHOW and HIDE variables control whether make will echo complete commands
@@ -101,23 +103,42 @@ BYTEFLAGS=-thread $(CAMLDEBUG) $(USERFLAGS)
OPTFLAGS=-thread $(CAMLDEBUGOPT) $(CAMLTIMEPROF) $(USERFLAGS)
DEPFLAGS= $(LOCALINCLUDES) -I ide -I ide/utils
+# On MacOS, the binaries are signed, except our private ones
ifeq ($(shell which codesign > /dev/null 2>&1 && echo $(ARCH)),Darwin)
-LINKMETADATA=-ccopt "-sectcreate __TEXT __info_plist config/Info-$(notdir $@).plist"
-CODESIGN:=codesign -s -
+LINKMETADATA=$(if $(filter $(PRIVATEBINARIES),$@),,-ccopt "-sectcreate __TEXT __info_plist config/Info-$(notdir $@).plist")
+CODESIGN=$(if $(filter $(PRIVATEBINARIES),$@),true,codesign -s -)
else
LINKMETADATA=
-CODESIGN:=true
+CODESIGN=true
endif
+# Best OCaml compiler, used in a generic way
+
+ifeq ($(BEST),opt)
+OPT:=opt
+BESTOBJ:=.cmx
+BESTLIB:=.cmxa
+BESTDYN:=.cmxs
+else
+OPT:=
+BESTOBJ:=.cmo
+BESTLIB:=.cma
+BESTDYN:=.cma
+endif
+
+define bestobj
+$(patsubst %.cma,%$(BESTLIB),$(patsubst %.cmo,%$(BESTOBJ),$(1)))
+endef
+
define bestocaml
$(if $(OPT),\
-$(if $(findstring $@,$(PRIVATEBINARIES)),\
- $(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) -o $@ $(1) $(addsuffix .cmxa,$(2)) $^ && $(STRIP) $@,\
- $(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) $(LINKMETADATA) -o $@ $(1) $(addsuffix .cmxa,$(2)) $^ && $(STRIP) $@ && $(CODESIGN) $@),\
+$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) $(LINKMETADATA) -o $@ $(1) $(addsuffix .cmxa,$(2)) $^ && $(STRIP) $@ && $(CODESIGN) $@,\
$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $(CUSTOM) -o $@ $(1) $(addsuffix .cma,$(2)) $^)
endef
-CAMLP4DEPS=$(shell LC_ALL=C sed -n -e 's@^(\*.*camlp4deps: "\(.*\)".*@\1@p' $(1) \#))
+# Camlp4 / Camlp5 settings
+
+CAMLP4DEPS:=tools/compat5.cmo grammar/grammar.cma
ifeq ($(CAMLP4),camlp5)
CAMLP4USE=pa_extend.cmo q_MLast.cmo pa_macro.cmo -D$(CAMLVERSION)
else
@@ -139,7 +160,6 @@ else
P4CMA:=camlp4lib.cma
endif
-
###########################################################################
# Infrastructure for the rest of the Makefile
###########################################################################
@@ -180,13 +200,11 @@ endif
TOTARGET = > "$@" || (RV=$$?; rm -f "$@"; exit $${RV})
###########################################################################
-# Compilation option for .c files
+# Compilation of .c files
###########################################################################
CINCLUDES= -I $(CAMLHLIB)
-# libcoqrun.a, dllcoqrun.so
-
# NB: We used to do a ranlib after ocamlmklib, but it seems that
# ocamlmklib is already doing it
@@ -194,7 +212,6 @@ $(LIBCOQRUN): kernel/byterun/coq_jumptbl.h $(BYTERUN)
cd $(dir $(LIBCOQRUN)) && \
$(OCAMLFIND) ocamlmklib -oc $(COQRUN) $(foreach u,$(BYTERUN),$(notdir $(u)))
-#coq_jumptbl.h is required only if you have GCC 2.0 or later
kernel/byterun/coq_jumptbl.h : kernel/byterun/coq_instruct.h
sed -n -e '/^ /s/ \([A-Z]\)/ \&\&coq_lbl_\1/gp' \
-e '/^}/q' $< $(TOTARGET)
@@ -203,29 +220,96 @@ kernel/copcodes.ml: kernel/byterun/coq_instruct.h
sed -n -e '/^enum/p' -e 's/,//g' -e '/^ /p' $< | \
awk -f kernel/make-opcodes $(TOTARGET)
+%.o: %.c
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)cd $(dir $<) && $(OCAMLC) -ccopt "$(CFLAGS)" -c $(notdir $<)
+
+%_stubs.c.d: $(D_DEPEND_BEFORE_SRC) %_stubs.c $(D_DEPEND_AFTER_SRC)
+ $(SHOW)'CCDEP $<'
+ $(HIDE)echo "$@ $(@:.c.d=.o): $(@:.c.d=.c)" > $@
+
+%.c.d: $(D_DEPEND_BEFORE_SRC) %.c $(D_DEPEND_AFTER_SRC) $(GENHFILES)
+ $(SHOW)'CCDEP $<'
+ $(HIDE)$(OCAMLC) -ccopt "-MM -MQ $@ -MQ $(<:.c=.o) -isystem $(CAMLHLIB)" $< $(TOTARGET)
+
###########################################################################
-# Main targets (coqmktop, coqtop.opt, coqtop.byte)
+# grammar/grammar.cma
###########################################################################
-.PHONY: coqbinaries coq coqlib coqlight states
+## In this part, we compile grammar/grammar.cma
+## without relying on .d dependency files, for bootstraping the creation
+## and inclusion of these .d files
-coqbinaries: ${COQBINARIES} ${CSDPCERT} ${FAKEIDE}
+## Explicit dependencies for grammar stuff
-coq: coqlib tools coqbinaries
+GRAMBASEDEPS := grammar/gramCompat.cmo grammar/q_util.cmi
+GRAMCMO := grammar/gramCompat.cmo grammar/q_util.cmo \
+ grammar/argextend.cmo grammar/tacextend.cmo grammar/vernacextend.cmo
-coqlib: theories plugins
+grammar/q_util.cmi : grammar/gramCompat.cmo
+grammar/argextend.cmo : $(GRAMBASEDEPS)
+grammar/q_util.cmo : $(GRAMBASEDEPS)
+grammar/tacextend.cmo : $(GRAMBASEDEPS) grammar/argextend.cmo
+grammar/vernacextend.cmo : $(GRAMBASEDEPS) grammar/tacextend.cmo \
+ grammar/argextend.cmo
+
+## Ocaml compiler with the right options and -I for grammar
+
+GRAMC := $(OCAMLFIND) ocamlc $(CAMLFLAGS) $(CAMLDEBUG) $(USERFLAGS) \
+ -I $(MYCAMLP4LIB) -I grammar
-coqlight: theories-light tools coqbinaries
+## Specific rules for grammar.cma
-states: theories/Init/Prelude.vo
+grammar/grammar.cma : $(GRAMCMO)
+ $(SHOW)'Testing $@'
+ @touch grammar/test.mlp
+ $(HIDE)$(GRAMC) -pp '$(CAMLP4O) -I $(MYCAMLP4LIB) $^ -impl' -impl grammar/test.mlp -o grammar/test
+ @rm -f grammar/test.* grammar/test
+ $(SHOW)'OCAMLC -a $@'
+ $(HIDE)$(GRAMC) $^ -linkall -a -o $@
+
+## Support of Camlp5 and Camlp5
+
+# NB: compatibility modules for camlp4:
+# - tools/compat5.cmo changes GEXTEND into EXTEND. Safe, always loaded
+# - tools/compat5b.cmo changes EXTEND into EXTEND Gram. Interact badly with
+# syntax such that VERNAC EXTEND, we only load it in grammar/
+
+ifeq ($(CAMLP4),camlp4)
+ COMPATCMO:=tools/compat5.cmo tools/compat5b.cmo
+ GRAMP4USE:=$(COMPATCMO) -D$(CAMLVERSION)
+ GRAMPP:=$(CAMLP4O) -I $(MYCAMLP4LIB) $(GRAMP4USE) $(CAMLP4COMPAT) -impl
+else
+ COMPATCMO:=
+ GRAMP4USE:=$(COMPATCMO) pa_extend.cmo q_MLast.cmo pa_macro.cmo -D$(CAMLVERSION)
+ GRAMPP:=$(CAMLP4O) -I $(MYCAMLP4LIB) $(GRAMP4USE) $(CAMLP4COMPAT) -impl
+endif
+
+## Rules for standard .mlp and .mli files in grammar/
+
+grammar/%.cmo: grammar/%.mlp | $(COMPATCMO)
+ $(SHOW)'OCAMLC -c -pp $<'
+ $(HIDE)$(GRAMC) -c -pp '$(GRAMPP)' -impl $<
+
+grammar/%.cmi: grammar/%.mli
+ $(SHOW)'OCAMLC -c $<'
+ $(HIDE)$(GRAMC) -c $<
+
+
+###########################################################################
+# Main targets (coqmktop, coqtop.opt, coqtop.byte)
+###########################################################################
+
+.PHONY: coqbinaries
+
+coqbinaries: $(COQMKTOP) $(COQTOPEXE) $(COQTOPBYTE) \
+ $(CHICKEN) $(CHICKENBYTE) $(CSDPCERT) $(FAKEIDE)
-miniopt: $(COQTOPEXE) pluginsopt
-minibyte: $(COQTOPBYTE) pluginsbyte
ifeq ($(BEST),opt)
$(COQTOPEXE): $(COQMKTOP) $(LINKCMX) $(LIBCOQRUN) $(TOPLOOPCMA:.cma=.cmxs)
$(SHOW)'COQMKTOP -o $@'
- $(HIDE)$(COQMKTOP) -boot -opt $(OPTFLAGS) $(LINKMETADATA) -thread -o $@
+ $(HIDE)$(COQMKTOP) -boot -opt $(OPTFLAGS) $(LINKMETADATA) -o $@
$(STRIP) $@
$(CODESIGN) $@
else
@@ -235,28 +319,13 @@ endif
$(COQTOPBYTE): $(COQMKTOP) $(LINKCMO) $(LIBCOQRUN) $(TOPLOOPCMA)
$(SHOW)'COQMKTOP -o $@'
- $(HIDE)$(COQMKTOP) -boot -top $(BYTEFLAGS) -thread -o $@
-
-LOCALCHKLIBS:=$(addprefix -I , $(CHKSRCDIRS) )
-CHKLIBS:=$(LOCALCHKLIBS) -I $(MYCAMLP4LIB)
+ $(HIDE)$(COQMKTOP) -boot -top $(BYTEFLAGS) -o $@
-ifeq ($(BEST),opt)
-$(CHICKEN): checker/check.cmxa checker/main.ml
- $(SHOW)'OCAMLOPT -o $@'
- $(HIDE)$(OCAMLOPT) $(CHKLIBS) $(OPTFLAGS) $(LINKMETADATA) -thread -o $@ $(SYSCMXA) $^
- $(STRIP) $@
- $(CODESIGN) $@
-else
-$(CHICKEN): $(CHICKENBYTE)
- cp $< $@
-endif
+# coqmktop
-$(CHICKENBYTE): checker/check.cma checker/main.ml
- $(SHOW)'OCAMLC -o $@'
- $(HIDE)$(OCAMLC) $(CHKLIBS) $(BYTEFLAGS) $(CUSTOM) -thread -o $@ $(SYSCMA) $^
+COQMKTOPCMO:=lib/clib.cma lib/errors.cmo tools/tolink.cmo tools/coqmktop.cmo
-# coqmktop
-$(COQMKTOP): $(patsubst %.cma,%$(BESTLIB),$(COQMKTOPCMO:.cmo=$(BESTOBJ)))
+$(COQMKTOP): $(call bestobj, $(COQMKTOPCMO))
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, $(OSDEPLIBS), $(SYSMOD))
@@ -267,217 +336,114 @@ tools/tolink.ml: Makefile.build Makefile.common
$(HIDE)echo "let core_objs = \""$(OBJSMOD)"\"" >> $@
# coqc
-$(COQC): $(patsubst %.cma,%$(BESTLIB),$(COQCCMO:.cmo=$(BESTOBJ)))
+
+COQCCMO:=lib/clib.cma lib/errors.cmo toplevel/usage.cmo tools/coqc.cmo
+
+$(COQC): $(call bestobj, $(COQCCMO))
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, $(OSDEPLIBS), $(SYSMOD))
-# target for libraries
+###########################################################################
+# other tools
+###########################################################################
-%.cma: | %.mllib.d
- $(SHOW)'OCAMLC -a -o $@'
- $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) -a -o $@ $^
+.PHONY:
+tools: $(TOOLS) $(OCAMLLIBDEP) $(COQDEPBOOT)
-%.cmxa: | %.mllib.d
- $(SHOW)'OCAMLOPT -a -o $@'
- $(HIDE)$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) -a -o $@ $^
+# coqdep_boot : a basic version of coqdep, with almost no dependencies.
-# For the checker, different flags may be used
+# Here it is important to mention .ml files instead of .cmo in order
+# to avoid using implicit rules : at the time coqdep_boot is being built,
+# some .ml.d files may still be missing or not taken in account yet by make.
-checker/check.cma: | md5chk checker/check.mllib.d
- $(SHOW)'OCAMLC -a -o $@'
- $(HIDE)$(OCAMLC) $(CHKLIBS) $(BYTEFLAGS) -a -o $@ $^
+COQDEPBOOTSRC := \
+ lib/minisys.ml \
+ tools/coqdep_lexer.mli tools/coqdep_lexer.ml \
+ tools/coqdep_common.mli tools/coqdep_common.ml \
+ tools/coqdep_boot.ml
-checker/check.cmxa: | md5chk checker/check.mllib.d
- $(SHOW)'OCAMLOPT -a -o $@'
- $(HIDE)$(OCAMLOPT) $(CHKLIBS) $(OPTFLAGS) -a -o $@ $^
+$(COQDEPBOOT): $(COQDEPBOOTSRC)
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, -I tools, unix)
-###########################################################################
-# Csdp to micromega special targets
-###########################################################################
+# Same for ocamllibdep
-plugins/micromega/csdpcert$(EXE): $(CSDPCERTCMO:.cmo=$(BESTOBJ)) \
- $(addsuffix $(BESTLIB), lib/clib)
+$(OCAMLLIBDEP): tools/ocamllibdep.ml
$(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,,nums unix clib)
-
-###########################################################################
-# CoqIde special targets
-###########################################################################
+ $(HIDE)$(call bestocaml, -I tools, unix)
-.PHONY: coqide coqide-binaries coqide-no coqide-byte coqide-opt coqide-files
+# The full coqdep (unused by this build, but distributed by make install)
-# target to build CoqIde
-coqide: coqide-files coqide-binaries theories/Init/Prelude.vo
+COQDEPCMO:=lib/clib.cma lib/errors.cmo lib/minisys.cmo lib/system.cmo \
+ tools/coqdep_lexer.cmo tools/coqdep_common.cmo tools/coqdep.cmo
-COQIDEFLAGS=$(addprefix -I , $(IDESRCDIRS)) $(COQIDEINCLUDES)
+$(COQDEP): $(call bestobj, $(COQDEPCMO))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, $(OSDEPLIBS), $(SYSMOD))
-.SUFFIXES:.vo
+$(GALLINA): $(call bestobj, tools/gallina_lexer.cmo tools/gallina.cmo)
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml,,)
-IDEFILES=$(wildcard ide/*.lang) ide/coq_style.xml ide/coq.png ide/MacOS/default_accel_map
+COQMAKEFILECMO:=lib/clib.cma ide/project_file.cmo tools/coq_makefile.cmo
-coqide-binaries: coqide-$(HASCOQIDE) ide-toploop
-coqide-no:
-coqide-byte: $(COQIDEBYTE) $(COQIDE)
-coqide-opt: $(COQIDEBYTE) $(COQIDE)
-coqide-files: $(IDEFILES)
-ifeq ($(BEST),opt)
-ide-toploop: $(IDETOPLOOPCMA) $(IDETOPLOOPCMA:.cma=.cmxs)
-else
-ide-toploop: $(IDETOPLOOPCMA)
-endif
+$(COQMAKEFILE): $(call bestobj,$(COQMAKEFILECMO))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml,,str unix threads)
-ifeq ($(HASCOQIDE),opt)
-$(COQIDE): $(LINKIDEOPT)
- $(SHOW)'OCAMLOPT -o $@'
- $(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) -o $@ unix.cmxa threads.cmxa lablgtk.cmxa \
- lablgtksourceview2.cmxa str.cmxa $(IDEFLAGS:.cma=.cmxa) $^
- $(STRIP) $@
-else
-$(COQIDE): $(COQIDEBYTE)
- cp $< $@
-endif
+$(COQTEX): $(call bestobj, tools/coq_tex.cmo)
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml,,str)
-$(COQIDEBYTE): $(LINKIDE)
- $(SHOW)'OCAMLC -o $@'
- $(HIDE)$(OCAMLC) $(COQIDEFLAGS) $(BYTEFLAGS) -o $@ unix.cma threads.cma lablgtk.cma \
- lablgtksourceview2.cma str.cma $(IDEFLAGS) $(IDECDEPSFLAGS) $^
+$(COQWC): $(call bestobj, tools/coqwc.cmo)
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml,,)
-# install targets
+COQDOCCMO:=lib/clib.cma $(addprefix tools/coqdoc/, \
+ cdglobals.cmo alpha.cmo index.cmo tokens.cmo output.cmo cpretty.cmo main.cmo )
-.PHONY: install-coqide install-ide-bin install-ide-toploop install-ide-files install-ide-info install-ide-devfiles
+$(COQDOC): $(call bestobj, $(COQDOCCMO))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml,,str unix)
-ifeq ($(HASCOQIDE),no)
-install-coqide: install-ide-toploop
-else
-install-coqide: install-ide-bin install-ide-toploop install-ide-files install-ide-info install-ide-devfiles
-endif
+$(COQWORKMGR): $(call bestobj, lib/clib.cma stm/coqworkmgrApi.cmo tools/coqworkmgr.cmo)
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml,, $(SYSMOD))
-install-ide-bin:
- $(MKDIR) $(FULLBINDIR)
- $(INSTALLBIN) $(COQIDE) $(FULLBINDIR)
+# fake_ide : for debugging or test-suite purpose, a fake ide simulating
+# a connection to coqtop -ideslave
-install-ide-toploop:
- $(MKDIR) $(FULLCOQLIB)/toploop
- $(INSTALLBIN) $(IDETOPLOOPCMA) $(FULLCOQLIB)/toploop/
-ifeq ($(BEST),opt)
- $(INSTALLBIN) $(IDETOPLOOPCMA:.cma=.cmxs) $(FULLCOQLIB)/toploop/
-endif
+FAKEIDECMO:= lib/clib.cma lib/errors.cmo lib/spawn.cmo ide/document.cmo \
+ ide/serialize.cmo ide/xml_lexer.cmo ide/xml_parser.cmo ide/xml_printer.cmo \
+ ide/xmlprotocol.cmo tools/fake_ide.cmo
-install-ide-devfiles:
- $(MKDIR) $(FULLCOQLIB)
- $(INSTALLSH) $(FULLCOQLIB) $(IDECMA) \
- $(foreach lib,$(IDECMA:.cma=_MLLIB_DEPENDENCIES),$(addsuffix .cmi,$($(lib))))
-ifeq ($(BEST),opt)
- $(INSTALLSH) $(FULLCOQLIB) $(IDECMA:.cma=.cmxa) $(IDECMA:.cma=.a)
-endif
+$(FAKEIDE): $(call bestobj, $(FAKEIDECMO)) | $(IDETOPLOOPCMA:.cma=$(BESTDYN))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml,-I ide,str unix threads)
-install-ide-files: #Please update $(COQIDEAPP)/Contents/Resources/ at the same time
- $(MKDIR) $(FULLDATADIR)
- $(INSTALLLIB) ide/coq.png ide/*.lang ide/coq_style.xml $(FULLDATADIR)
- $(MKDIR) $(FULLCONFIGDIR)
- if [ $(IDEINT) = QUARTZ ] ; then $(INSTALLLIB) ide/mac_default_accel_map $(FULLCONFIGDIR)/coqide.keys ; fi
+# votour: a small vo explorer (based on the checker)
-install-ide-info:
- $(MKDIR) $(FULLDOCDIR)
- $(INSTALLLIB) ide/FAQ $(FULLDOCDIR)/FAQ-CoqIde
+bin/votour: $(call bestobj, lib/cObj.cmo checker/analyze.cmo checker/values.cmo) checker/votour.ml
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, -I checker,)
###########################################################################
-# CoqIde MacOS special targets
+# Csdp to micromega special targets
###########################################################################
-.PHONY: $(COQIDEAPP)/Contents
-
-$(COQIDEAPP)/Contents:
- rm -rdf $@
- $(MKDIR) $@
- sed -e "s/VERSION/$(VERSION4MACOS)/g" ide/MacOS/Info.plist.template > $@/Info.plist
- $(MKDIR) "$@/MacOS"
+CSDPCERTCMO:=lib/clib.cma $(addprefix plugins/micromega/, \
+ mutils.cmo micromega.cmo \
+ sos_types.cmo sos_lib.cmo sos.cmo csdpcert.cmo )
-$(COQIDEINAPP): ide/macos_prehook.cmx $(LINKIDEOPT) | $(COQIDEAPP)/Contents
- $(SHOW)'OCAMLOPT -o $@'
- $(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) -o $@ \
- unix.cmxa lablgtk.cmxa lablgtksourceview2.cmxa str.cmxa \
- threads.cmxa $(IDEFLAGS:.cma=.cmxa) $^
- $(STRIP) $@
-
-$(COQIDEAPP)/Contents/Resources/share: $(COQIDEAPP)/Contents
- $(MKDIR) $@/coq/
- $(INSTALLLIB) ide/coq.png ide/*.lang ide/coq_style.xml $@/coq/
- $(MKDIR) $@/gtksourceview-2.0/{language-specs,styles}
- $(INSTALLLIB) "$(GTKSHARE)/"gtksourceview-2.0/language-specs/{def.lang,language2.rng} $@/gtksourceview-2.0/language-specs/
- $(INSTALLLIB) "$(GTKSHARE)/"gtksourceview-2.0/styles/{styles.rng,classic.xml} $@/gtksourceview-2.0/styles/
- cp -R "$(GTKSHARE)/"locale $@
- cp -R "$(GTKSHARE)/"icons $@
- cp -R "$(GTKSHARE)/"themes $@
-
-$(COQIDEAPP)/Contents/Resources/loaders: $(COQIDEAPP)/Contents
- $(MKDIR) $@
- $(INSTALLLIB) $$("$(GTKBIN)/gdk-pixbuf-query-loaders" | sed -n -e '5 s!.*= \(.*\)$$!\1!p')/libpixbufloader-png.so $@
-
-$(COQIDEAPP)/Contents/Resources/immodules: $(COQIDEAPP)/Contents
- $(MKDIR) $@
- $(INSTALLLIB) "$(GTKLIBS)/gtk-2.0/2.10.0/immodules/"*.so $@
-
-
-$(COQIDEAPP)/Contents/Resources/etc: $(COQIDEAPP)/Contents/Resources/lib
- $(MKDIR) $@/xdg/coq
- $(INSTALLLIB) ide/MacOS/default_accel_map $@/xdg/coq/coqide.keys
- $(MKDIR) $@/gtk-2.0
- { "$(GTKBIN)/gdk-pixbuf-query-loaders" $@/../loaders/*.so |\
- sed -e "s!/.*\(/loaders/.*.so\)!@executable_path/../Resources/\1!"; } \
- > $@/gtk-2.0/gdk-pixbuf.loaders
- { "$(GTKBIN)/gtk-query-immodules-2.0" $@/../immodules/*.so |\
- sed -e "s!/.*\(/immodules/.*.so\)!@executable_path/../Resources/\1!" |\
- sed -e "s!/.*\(/share/locale\)!@executable_path/../Resources/\1!"; } \
- > $@/gtk-2.0/gtk-immodules.loaders
- $(MKDIR) $@/pango
- echo "[Pango]" > $@/pango/pangorc
-
-$(COQIDEAPP)/Contents/Resources/lib: $(COQIDEAPP)/Contents/Resources/immodules $(COQIDEAPP)/Contents/Resources/loaders $(COQIDEAPP)/Contents $(COQIDEINAPP)
- $(MKDIR) $@
- $(INSTALLLIB) $(GTKLIBS)/charset.alias $@/
- $(MKDIR) $@/pango/1.8.0/modules
- $(INSTALLLIB) "$(GTKLIBS)/pango/1.8.0/modules/"*.so $@/pango/1.8.0/modules/
- { "$(GTKBIN)/pango-querymodules" $@/pango/1.8.0/modules/*.so |\
- sed -e "s!/.*\(/pango/1.8.0/modules/.*.so\)!@executable_path/../Resources/lib\1!"; } \
- > $@/pango/1.8.0/modules.cache
-
- for i in $$(otool -L $(COQIDEINAPP) |sed -n -e "\@$(GTKLIBS)@ s/[^/]*\(\/[^ ]*\) .*$$/\1/p"); \
- do cp $$i $@/; \
- ide/MacOS/relatify_with-respect-to_.sh $@/$$(basename $$i) $(GTKLIBS) $@; \
- done
- for i in $@/../loaders/*.so $@/../immodules/*.so $@/pango/1.8.0/modules/*.so; \
- do \
- for j in $$(otool -L $$i | sed -n -e "\@$(GTKLIBS)@ s/[^/]*\(\/[^ ]*\) .*$$/\1/p"); \
- do cp $$j $@/; ide/MacOS/relatify_with-respect-to_.sh $@/$$(basename $$j) $(GTKLIBS) $@; done; \
- ide/MacOS/relatify_with-respect-to_.sh $$i $(GTKLIBS) $@; \
- done
- EXTRAWORK=1; \
- while [ $${EXTRAWORK} -eq 1 ]; \
- do EXTRAWORK=0; \
- for i in $@/*.dylib; \
- do for j in $$(otool -L $$i | sed -n -e "\@$(GTKLIBS)@ s/[^/]*\(\/[^ ]*\) .*$$/\1/p"); \
- do EXTRAWORK=1; cp $$j $@/; ide/MacOS/relatify_with-respect-to_.sh $@/$$(basename $$j) $(GTKLIBS) $@; done; \
- done; \
- done
- ide/MacOS/relatify_with-respect-to_.sh $(COQIDEINAPP) $(GTKLIBS) $@
-
-$(COQIDEAPP)/Contents/Resources:$(COQIDEAPP)/Contents/Resources/etc $(COQIDEAPP)/Contents/Resources/share
- $(INSTALLLIB) ide/MacOS/*.icns $@
-
-$(COQIDEAPP):$(COQIDEAPP)/Contents/Resources
- $(CODESIGN) $@
+$(CSDPCERT): $(call bestobj, $(CSDPCERTCMO))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml,,nums unix)
###########################################################################
# tests
###########################################################################
-.PHONY: validate check test-suite $(ALLSTDLIB).v md5chk
-
-md5chk:
- $(SHOW)'MD5SUM cic.mli'
- $(HIDE)if grep -q `$(MD5SUM) checker/cic.mli` checker/values.ml; \
- then true; else echo "Error: outdated checker/values.ml"; false; fi
+.PHONY: validate check test-suite $(ALLSTDLIB).v
VALIDOPTS=$(if $(VERBOSE),,-silent) -o -m
@@ -498,169 +464,10 @@ test-suite: world $(ALLSTDLIB).v
$(MAKE) $(MAKE_TSOPTS) all
$(MAKE) $(MAKE_TSOPTS) report
-##################################################################
-# partial targets: 1) core ML parts
-##################################################################
-
-.PHONY: lib kernel byterun library proofs tactics interp parsing pretyping
-.PHONY: engine highparsing stm toplevel hightactics
-
-lib: lib/clib.cma lib/lib.cma
-kernel: kernel/kernel.cma
-byterun: $(BYTERUN)
-library: library/library.cma
-engine: engine/engine.cma
-proofs: proofs/proofs.cma
-tactics: tactics/tactics.cma
-interp: interp/interp.cma
-parsing: parsing/parsing.cma
-pretyping: pretyping/pretyping.cma
-highparsing: parsing/highparsing.cma
-stm: stm/stm.cma
-toplevel: toplevel/toplevel.cma
-hightactics: tactics/hightactics.cma
-
###########################################################################
-# 2) theories and plugins files
+### Special rules (Camlp5 / Camlp4)
###########################################################################
-.PHONY: init theories theories-light
-.PHONY: logic arith bool narith zarith qarith lists strings sets
-.PHONY: fsets relations wellfounded reals setoids sorting numbers noreal
-.PHONY: msets mmaps compat
-
-init: $(INITVO)
-
-theories: $(THEORIESVO)
-theories-light: $(THEORIESLIGHTVO)
-
-logic: $(LOGICVO)
-arith: $(ARITHVO)
-bool: $(BOOLVO)
-narith: $(NARITHVO)
-zarith: $(ZARITHVO)
-qarith: $(QARITHVO)
-lists: $(LISTSVO)
-strings: $(STRINGSVO)
-sets: $(SETSVO)
-fsets: $(FSETSVO)
-relations: $(RELATIONSVO)
-wellfounded: $(WELLFOUNDEDVO)
-reals: $(REALSVO)
-setoids: $(SETOIDSVO)
-sorting: $(SORTINGVO)
-numbers: $(NUMBERSVO)
-unicode: $(UNICODEVO)
-classes: $(CLASSESVO)
-program: $(PROGRAMVO)
-structures: $(STRUCTURESVO)
-vectors: $(VECTORSVO)
-msets: $(MSETSVO)
-compat: $(COMPATVO)
-
-noreal: unicode logic arith bool zarith qarith lists sets fsets \
- relations wellfounded setoids sorting
-
-###########################################################################
-# 3) plugins
-###########################################################################
-
-.PHONY: plugins omega micromega setoid_ring nsatz extraction
-.PHONY: fourier funind cc rtauto btauto pluginsopt pluginsbyte
-
-plugins: $(PLUGINSVO)
-omega: $(OMEGAVO) $(OMEGACMA) $(ROMEGAVO) $(ROMEGACMA)
-micromega: $(MICROMEGAVO) $(MICROMEGACMA) $(CSDPCERT)
-setoid_ring: $(RINGVO) $(RINGCMA)
-nsatz: $(NSATZVO) $(NSATZCMA)
-extraction: $(EXTRACTIONCMA)
-fourier: $(FOURIERVO) $(FOURIERCMA)
-funind: $(FUNINDCMA) $(FUNINDVO)
-cc: $(CCVO) $(CCCMA)
-rtauto: $(RTAUTOVO) $(RTAUTOCMA)
-btauto: $(BTAUTOVO) $(BTAUTOCMA)
-
-pluginsopt: $(PLUGINSOPT)
-pluginsbyte: $(PLUGINS)
-
-###########################################################################
-# rules to make theories and plugins
-###########################################################################
-
-theories/Init/%.vo theories/Init/%.glob: theories/Init/%.v $(VO_TOOLS_DEP) | theories/Init/%.v.d
- $(SHOW)'COQC $(COQ_XML) -noinit $<'
- $(HIDE)rm -f theories/Init/$*.glob
- $(HIDE)$(BOOTCOQC) $< $(COQ_XML) -noinit -R theories Coq
-
-theories/Numbers/Natural/BigN/NMake_gen.v: theories/Numbers/Natural/BigN/NMake_gen.ml
- $(OCAML) $< $(TOTARGET)
-
-###########################################################################
-# tools
-###########################################################################
-
-.PHONY: printers tools
-
-printers: $(DEBUGPRINTERS)
-
-tools: $(TOOLS) $(DEBUGPRINTERS) $(OCAMLLIBDEP)
-
-# coqdep_boot : a basic version of coqdep, with almost no dependencies.
-
-# Here it is important to mention .ml files instead of .cmo in order
-# to avoid using implicit rules and hence .ml.d files that would need
-# coqdep_boot.
-
-OCAMLLIBDEPSRC:= tools/ocamllibdep.ml
-
-$(OCAMLLIBDEP): $(OCAMLLIBDEPSRC)
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml, -I tools, unix)
-
-# the full coqdep
-
-$(COQDEP): $(patsubst %.cma,%$(BESTLIB),$(COQDEPCMO:.cmo=$(BESTOBJ)))
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml, $(OSDEPLIBS), $(SYSMOD))
-
-$(GALLINA): $(addsuffix $(BESTOBJ), tools/gallina_lexer tools/gallina)
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,,)
-
-$(COQMAKEFILE): $(patsubst %.cma,%$(BESTLIB),$(COQMAKEFILECMO:.cmo=$(BESTOBJ)))
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,,str unix threads)
-
-$(COQTEX): tools/coq_tex$(BESTOBJ)
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,,str)
-
-$(COQWC): tools/coqwc$(BESTOBJ)
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,,)
-
-$(COQDOC): $(patsubst %.cma,%$(BESTLIB),$(COQDOCCMO:.cmo=$(BESTOBJ)))
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,,str unix)
-
-$(COQWORKMGR): $(addsuffix $(BESTOBJ), stm/coqworkmgrApi tools/coqworkmgr) \
- $(addsuffix $(BESTLIB), lib/clib)
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,, $(SYSMOD) clib)
-
-# fake_ide : for debugging or test-suite purpose, a fake ide simulating
-# a connection to coqtop -ideslave
-
-$(FAKEIDE): lib/clib$(BESTLIB) lib/xml_lexer$(BESTOBJ) lib/xml_parser$(BESTOBJ) lib/xml_printer$(BESTOBJ) lib/errors$(BESTOBJ) lib/spawn$(BESTOBJ) ide/document$(BESTOBJ) ide/xmlprotocol$(BESTOBJ) tools/fake_ide$(BESTOBJ) | $(IDETOPLOOPCMA:.cma=$(BESTDYN))
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml,-I ide,str unix threads)
-
-# votour: a small vo explorer (based on the checker)
-
-bin/votour: lib/cObj$(BESTOBJ) checker/analyze$(BESTOBJ) checker/values$(BESTOBJ) checker/votour.ml
- $(SHOW)'OCAMLBEST -o $@'
- $(HIDE)$(call bestocaml, -I checker,)
-
# Special rule for the compatibility-with-camlp5 extension for camlp4
ifeq ($(CAMLP4),camlp4)
@@ -671,315 +478,51 @@ tools/compat5b.cmo: tools/compat5b.mlp
else
tools/compat5.cmo: tools/compat5.ml
$(OCAMLC) -c $<
-tools/compat5b.cmo: tools/compat5b.ml
- $(OCAMLC) -c $<
endif
###########################################################################
-# Documentation : cf Makefile.doc
-###########################################################################
-
-documentation: doc-$(WITHDOC)
-doc-all: doc
-doc-no:
-
-.PHONY: documentation doc-all doc-no
-
-###########################################################################
-# Installation
+# Default rules for compiling ML code
###########################################################################
-ifeq ($(LOCAL),true)
-install:
- @echo "Nothing to install in a local build!"
-else
-install: install-coq install-coqide install-doc-$(WITHDOC)
-endif
-
-install-doc-all: install-doc
-install-doc-no:
-
-.PHONY: install install-doc-all install-doc-no
-
-#These variables are intended to be set by the caller to make
-#COQINSTALLPREFIX=
-#OLDROOT=
-
- # Can be changed for a local installation (to make packages).
- # You must NOT put a "/" at the end (Cygnus for win32 does not like "//").
-
-ifdef COQINSTALLPREFIX
-FULLBINDIR=$(BINDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
-FULLCOQLIB=$(COQLIBINSTALL:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
-FULLCONFIGDIR=$(CONFIGDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
-FULLDATADIR=$(DATADIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
-FULLMANDIR=$(MANDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
-FULLEMACSLIB=$(EMACSLIB:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
-FULLCOQDOCDIR=$(COQDOCDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
-FULLDOCDIR=$(DOCDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
-else
-FULLBINDIR=$(BINDIR)
-FULLCOQLIB=$(COQLIBINSTALL)
-FULLCONFIGDIR=$(CONFIGDIR)
-FULLDATADIR=$(DATADIR)
-FULLMANDIR=$(MANDIR)
-FULLEMACSLIB=$(EMACSLIB)
-FULLCOQDOCDIR=$(COQDOCDIR)
-FULLDOCDIR=$(DOCDIR)
-endif
-
-.PHONY: install-coq install-coqlight install-binaries install-byte install-opt
-.PHONY: install-tools install-library install-library-light install-devfiles
-.PHONY: install-coq-info install-coq-manpages install-emacs install-latex
-
-install-coq: install-binaries install-library install-coq-info install-devfiles
-install-coqlight: install-binaries install-library-light
-
-install-binaries: install-tools
- $(MKDIR) $(FULLBINDIR)
- $(INSTALLBIN) $(COQC) $(COQTOPBYTE) $(COQTOPEXE) $(CHICKEN) $(FULLBINDIR)
- $(MKDIR) $(FULLCOQLIB)/toploop
- $(INSTALLBIN) $(TOPLOOPCMA) $(FULLCOQLIB)/toploop/
-ifeq ($(BEST),opt)
- $(INSTALLBIN) $(TOPLOOPCMA:.cma=.cmxs) $(FULLCOQLIB)/toploop/
-endif
-
-
-install-tools:
- $(MKDIR) $(FULLBINDIR)
- # recopie des fichiers de style pour coqide
- $(MKDIR) $(FULLCOQLIB)/tools/coqdoc
- touch $(FULLCOQLIB)/tools/coqdoc/coqdoc.sty $(FULLCOQLIB)/tools/coqdoc/coqdoc.css # to have the mode according to umask (bug #1715)
- $(INSTALLLIB) tools/coqdoc/coqdoc.css tools/coqdoc/coqdoc.sty $(FULLCOQLIB)/tools/coqdoc
- $(INSTALLBIN) $(TOOLS) $(FULLBINDIR)
-
-# The list of .cmi to install, including the ones obtained
-# from .mli without .ml, and the ones obtained from .ml without .mli
-
-INSTALLCMI = $(sort \
- $(filter-out checker/% ide/% tools/%, $(MLIFILES:.mli=.cmi)) \
- $(foreach lib,$(CORECMA) $(PLUGINSCMA), $(addsuffix .cmi,$($(lib:.cma=_MLLIB_DEPENDENCIES)))))
-
-install-devfiles:
- $(MKDIR) $(FULLBINDIR)
- $(INSTALLBIN) $(COQMKTOP) $(FULLBINDIR)
- $(MKDIR) $(FULLCOQLIB)
- $(INSTALLSH) $(FULLCOQLIB) $(LINKCMO) $(GRAMMARCMA)
- $(INSTALLSH) $(FULLCOQLIB) $(INSTALLCMI)
-ifeq ($(BEST),opt)
- $(INSTALLSH) $(FULLCOQLIB) $(LINKCMX) $(CORECMA:.cma=.a) $(STATICPLUGINS:.cma=.a)
-endif
-
-install-library:
- $(MKDIR) $(FULLCOQLIB)
- $(INSTALLSH) $(FULLCOQLIB) $(LIBFILES) $(PLUGINS)
- $(MKDIR) $(FULLCOQLIB)/user-contrib
-ifndef CUSTOM
- $(INSTALLLIB) $(DLLCOQRUN) $(FULLCOQLIB)
-endif
-ifeq ($(BEST),opt)
- $(INSTALLLIB) $(LIBCOQRUN) $(FULLCOQLIB)
- $(INSTALLSH) $(FULLCOQLIB) $(PLUGINSOPT)
-endif
-# csdpcert is not meant to be directly called by the user; we install
-# it with libraries
- -$(MKDIR) $(FULLCOQLIB)/plugins/micromega
- $(INSTALLBIN) $(CSDPCERT) $(FULLCOQLIB)/plugins/micromega
- rm -f $(FULLCOQLIB)/revision
- -$(INSTALLLIB) revision $(FULLCOQLIB)
-
-install-library-light:
- $(MKDIR) $(FULLCOQLIB)
- $(INSTALLSH) $(FULLCOQLIB) $(LIBFILESLIGHT) $(INITPLUGINS)
- rm -f $(FULLCOQLIB)/revision
- -$(INSTALLLIB) revision $(FULLCOQLIB)
-ifndef CUSTOM
- $(INSTALLLIB) $(DLLCOQRUN) $(FULLCOQLIB)
-endif
-ifeq ($(BEST),opt)
- $(INSTALLLIB) $(LIBCOQRUN) $(FULLCOQLIB)
- $(INSTALLSH) $(FULLCOQLIB) $(INITPLUGINSOPT)
-endif
-
-install-coq-info: install-coq-manpages install-emacs install-latex
-
-install-coq-manpages:
- $(MKDIR) $(FULLMANDIR)/man1
- $(INSTALLLIB) $(MANPAGES) $(FULLMANDIR)/man1
-
-install-emacs:
- $(MKDIR) $(FULLEMACSLIB)
- $(INSTALLLIB) tools/gallina-db.el tools/coq-font-lock.el tools/gallina-syntax.el tools/gallina.el tools/coq-inferior.el $(FULLEMACSLIB)
-
-# command to update TeX' kpathsea database
-#UPDATETEX = $(MKTEXLSR) /usr/share/texmf /var/spool/texmf $(BASETEXDIR) > /dev/null
-
-install-latex:
- $(MKDIR) $(FULLCOQDOCDIR)
- $(INSTALLLIB) tools/coqdoc/coqdoc.sty $(FULLCOQDOCDIR)
-# -$(UPDATETEX)
-
-###########################################################################
-# Documentation of the source code (using ocamldoc)
-###########################################################################
-
-.PHONY: source-doc mli-doc ml-doc
-
-source-doc: mli-doc $(OCAMLDOCDIR)/coq.pdf
-
-$(OCAMLDOCDIR)/coq.tex: $(DOCMLIS:.mli=.cmi)
- $(SHOW)'OCAMLDOC -latex -o $@'
- $(HIDE)$(OCAMLFIND) ocamldoc -latex -rectypes -I $(MYCAMLP4LIB) $(MLINCLUDES)\
- $(DOCMLIS) -noheader -t "Coq mlis documentation" \
- -intro $(OCAMLDOCDIR)/docintro -o $@.tmp
- $(SHOW)'OCAMLDOC utf8 fix'
- $(HIDE)$(OCAMLDOCDIR)/fix-ocamldoc-utf8 $@.tmp
- $(HIDE)cat $(OCAMLDOCDIR)/header.tex $@.tmp > $@
- rm $@.tmp
-
-mli-doc: $(DOCMLIS:.mli=.cmi)
- $(SHOW)'OCAMLDOC -html'
- $(HIDE)$(OCAMLFIND) ocamldoc -charset utf-8 -html -rectypes -I +threads -I $(MYCAMLP4LIB) $(MLINCLUDES) \
- $(DOCMLIS) -d $(OCAMLDOCDIR)/html -colorize-code \
- -t "Coq mlis documentation" -intro $(OCAMLDOCDIR)/docintro \
- -css-style style.css
-
-ml-dot: $(MLFILES)
- $(OCAMLFIND) ocamldoc -dot -dot-reduce -rectypes -I +threads -I $(CAMLLIB) -I $(MYCAMLP4LIB) $(MLINCLUDES) \
- $(filter $(addsuffix /%.ml,$(CORESRCDIRS)),$(MLFILES)) -o $(OCAMLDOCDIR)/coq.dot
-
-%_dep.png: %.dot
- $(DOT) -Tpng $< -o $@
-
-%_types.dot: %.mli
- $(OCAMLFIND) ocamldoc -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -dot-types -o $@ $<
-
-OCAMLDOC_MLLIBD = $(OCAMLFIND) ocamldoc -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -o $@ \
- $(foreach lib,$(|:.mllib.d=_MLLIB_DEPENDENCIES),$(addsuffix .ml,$($(lib))))
-
-%.dot: | %.mllib.d
- $(OCAMLDOC_MLLIBD)
-
-ml-doc:
- $(OCAMLFIND) ocamldoc -charset utf-8 -html -rectypes -I +threads $(MLINCLUDES) $(COQIDEFLAGS) -d $(OCAMLDOCDIR) $(MLSTATICFILES)
-
-parsing/parsing.dot : | parsing/parsing.mllib.d parsing/highparsing.mllib.d
- $(OCAMLDOC_MLLIBD)
-
-grammar/grammar.dot : | grammar/grammar.mllib.d
- $(OCAMLDOC_MLLIBD)
-
-tactics/tactics.dot: | tactics/tactics.mllib.d tactics/hightactics.mllib.d
- $(OCAMLDOC_MLLIBD)
-
-%.dot: %.mli
- $(OCAMLFIND) ocamldoc -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -o $@ $<
-
-$(OCAMLDOCDIR)/%.pdf: $(OCAMLDOCDIR)/%.tex
- $(SHOW)'PDFLATEX $*.tex'
- $(HIDE)(cd $(OCAMLDOCDIR) ; pdflatex -interaction=batchmode $*.tex && pdflatex -interaction=batchmode $*.tex)
- $(HIDE)(cd doc/tools/; show_latex_messages -no-overfull ../../$(OCAMLDOCDIR)/$*.log)
+# Target for libraries .cma and .cmxa
-###########################################################################
-### Special rules
-###########################################################################
+# The dependency over the .mllib is somewhat artificial, since
+# ocamlc -a won't use this file, hence the $(filter-out ...) below.
+# But this ensures that the .cm(x)a is rebuilt when needed,
+# (especially when removing a module in the .mllib).
+# We used to have a "order-only" dependency over .mllib.d here,
+# but the -include mechanism should already ensure that we have
+# up-to-date dependencies.
-dev/printers.cma: | dev/printers.mllib.d
- $(SHOW)'Testing $@'
- $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) -thread $(SYSCMA) $(P4CMA) $^ -o test-printer
- @rm -f test-printer
- $(SHOW)'OCAMLC -a $@'
- $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) -thread $(SYSCMA) $(P4CMA) $^ -linkall -a -o $@
+%.cma: %.mllib
+ $(SHOW)'OCAMLC -a -o $@'
+ $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) -a -o $@ $(filter-out %.mllib, $^)
-grammar/grammar.cma: | grammar/grammar.mllib.d
- $(SHOW)'Testing $@'
- @touch test.ml4
- $(HIDE)$(CAMLP4O) $(CAMLP4FLAGS) $^ -impl test.ml4 -o test.ml
- $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) test.ml -o test-grammar
- @rm -f test-grammar test.*
- $(SHOW)'OCAMLC -a $@'
- $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $^ -linkall -a -o $@
+%.cmxa: %.mllib
+ $(SHOW)'OCAMLOPT -a -o $@'
+ $(HIDE)$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) -a -o $@ $(filter-out %.mllib, $^)
-ide/coqide_main.ml: ide/coqide_main.ml4 config/Makefile # no camlp4deps here
- $(SHOW)'CAMLP4O $<'
- $(HIDE)$(CAMLP4O) $(CAMLP4FLAGS) $(PR_O) $(CAMLP4USE) -D$(IDEINT) -impl $< -o $@
-
-# pretty printing of the revision number when compiling a checked out
-# source tree
-.PHONY: revision
-
-revision:
- $(SHOW)'CHECK revision'
- $(HIDE)rm -f revision.new
-ifeq ($(CHECKEDOUT),svn)
- $(HIDE)set -e; \
- if test -x "`which svn`"; then \
- export LC_ALL=C;\
- svn info . | sed -ne '/URL/s/.*\/\([^\/]\{1,\}\)/\1/p' > revision.new; \
- svn info . | sed -ne '/Revision/s/Revision: \([0-9]\{1,\}\)/\1/p'>> revision.new; \
- fi
-endif
-ifeq ($(CHECKEDOUT),gnuarch)
- $(HIDE)set -e; \
- if test -x "`which tla`"; then \
- LANG=C; export LANG; \
- tla tree-version > revision.new ; \
- tla tree-revision | sed -ne 's|.*--||p' >> revision.new ; \
- fi
-endif
-ifeq ($(CHECKEDOUT),git)
- $(HIDE)set -e; \
- if test -x "`which git`"; then \
- LANG=C; export LANG; \
- GIT_BRANCH=$$(git branch -a | sed -ne '/^\* /s/^\* \(.*\)/\1/p'); \
- GIT_HOST=$$(hostname); \
- GIT_PATH=$$(pwd); \
- (echo "$${GIT_HOST}:$${GIT_PATH},$${GIT_BRANCH}") > revision.new; \
- (echo "$$(git log -1 --pretty='format:%H')") >> revision.new; \
- fi
-endif
- $(HIDE)set -e; \
- if test -e revision.new; then \
- if test -e revision; then \
- if test "`cat revision`" = "`cat revision.new`" ; then \
- rm -f revision.new; \
- else \
- mv -f revision.new revision; \
- fi; \
- else \
- mv -f revision.new revision; \
- fi \
- fi
+# For plugin packs :
-###########################################################################
-# Default rules
-###########################################################################
+%.cmo: %.mlpack
+ $(SHOW)'OCAMLC -pack -o $@'
+ $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) -pack -o $@ $(filter-out %.mlpack, $^)
-## Three flavor of flags: checker/* ide/* and normal files
+%.cmx: %.mlpack
+ $(SHOW)'OCAMLOPT -pack -o $@'
+ $(HIDE)$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) -pack -o $@ $(filter-out %.mlpack, $^)
COND_BYTEFLAGS= \
- $(if $(filter checker/%,$<), $(CHKLIBS) -thread, \
- $(if $(filter ide/%,$<), $(COQIDEFLAGS), \
- $(if $(filter tools/fake_ide% tools/coq_makefile%,$<), -I ide,) $(MLINCLUDES) -thread)) $(BYTEFLAGS)
+ $(if $(filter tools/fake_ide% tools/coq_makefile%,$<), -I ide,) $(MLINCLUDES) $(BYTEFLAGS)
COND_OPTFLAGS= \
- $(if $(filter checker/%,$<), $(CHKLIBS) -thread, \
- $(if $(filter ide/%,$<), $(COQIDEFLAGS), \
- $(if $(filter tools/fake_ide% tools/coq_makefile%,$<), -I ide,) $(MLINCLUDES) -thread)) $(OPTFLAGS)
-
-%.o: %.c
- $(SHOW)'OCAMLC $<'
- $(HIDE)cd $(dir $<) && $(OCAMLC) -ccopt "$(CFLAGS)" -c $(notdir $<)
-
-%.o: %.rc
- $(SHOW)'WINDRES $<'
- $(HIDE)i686-w64-mingw32-windres -i $< -o $@
+ $(if $(filter tools/fake_ide% tools/coq_makefile%,$<), -I ide,) $(MLINCLUDES) $(OPTFLAGS)
-%.cmi: %.mli | %.mli.d
+%.cmi: %.mli
$(SHOW)'OCAMLC $<'
$(HIDE)$(OCAMLC) $(COND_BYTEFLAGS) -c $<
-%.cmo: %.ml | %.ml.d
+%.cmo: %.ml
$(SHOW)'OCAMLC $<'
$(HIDE)$(OCAMLC) $(COND_BYTEFLAGS) -c $<
@@ -1004,17 +547,21 @@ $(MLWITHOUTMLI:.ml=.cmx): %.cmx: %.cmi # for .ml with .mli this is already the
$(MLWITHOUTMLI:.ml=.cmi): %.cmi: %.cmo
-%.cmx: %.ml | %.ml.d
+# NB: the *_FORPACK variables are generated in *.mlpack.d by ocamllibdep
+# The only exceptions are the sources of the csdpcert binary.
+# To avoid warnings, we set them manually here:
+plugins/micromega/sos_lib_FORPACK:=
+plugins/micromega/sos_FORPACK:=
+plugins/micromega/sos_print_FORPACK:=
+plugins/micromega/csdpcert_FORPACK:=
+
+plugins/%.cmx: plugins/%.ml
$(SHOW)'OCAMLOPT $<'
- $(HIDE)$(OCAMLOPT) $(COND_OPTFLAGS) $(HACKMLI) -c $<
+ $(HIDE)$(OCAMLOPT) $(COND_OPTFLAGS) $(HACKMLI) $($(@:.cmx=_FORPACK)) -c $<
-%.cmxs: %.cmxa
- $(SHOW)'OCAMLOPT -shared -o $@'
-ifeq ($(HASNATDYNLINK),os5fixme)
- $(HIDE)dev/ocamlopt_shared_os5fix.sh "$(OCAMLOPT)" $@
-else
- $(HIDE)$(OCAMLOPT) -linkall -shared -o $@ $<
-endif
+%.cmx: %.ml
+ $(SHOW)'OCAMLOPT $<'
+ $(HIDE)$(OCAMLOPT) $(COND_OPTFLAGS) $(HACKMLI) -c $<
%.cmxs: %.cmx
$(SHOW)'OCAMLOPT -shared -o $@'
@@ -1024,105 +571,84 @@ endif
$(SHOW)'OCAMLLEX $<'
$(HIDE)$(OCAMLLEX) -o $@ "$*.mll"
-plugins/%_mod.ml: plugins/%.mllib
- $(SHOW)'ECHO... > $@'
- $(HIDE)sed -e "s/\([^ ]\{1,\}\)/let _=Mltop.add_known_module\"\1\" /g" $< > $@
- $(HIDE)echo "let _=Mltop.add_known_module\"$(notdir $*)\"" >> $@
-
-# NB: compatibility modules for camlp4:
-# - tools/compat5.cmo changes GEXTEND into EXTEND. Safe, always loaded
-# - tools/compat5b.cmo changes EXTEND into EXTEND Gram. Interact badly with
-# syntax such that VERNAC EXTEND, we only load it for a few files via camlp4deps
-
-%.ml: %.ml4 | %.ml4.d tools/compat5.cmo tools/compat5b.cmo
+%.ml: %.ml4 | $(CAMLP4DEPS)
$(SHOW)'CAMLP4O $<'
- $(HIDE)$(CAMLP4O) $(CAMLP4FLAGS) $(PR_O) tools/compat5.cmo \
- $(call CAMLP4DEPS,$<) $(CAMLP4USE) $(CAMLP4COMPAT) -impl $< -o $@
+ $(HIDE)$(CAMLP4O) $(CAMLP4FLAGS) $(PR_O) \
+ $(CAMLP4DEPS) $(CAMLP4USE) $(CAMLP4COMPAT) -impl $< -o $@
-%.vo %.glob: %.v theories/Init/Prelude.vo $(VO_TOOLS_DEP) | %.v.d
- $(SHOW)'COQC $<'
- $(HIDE)rm -f $*.glob
- $(HIDE)$(BOOTCOQC) $<
-ifdef VALIDATE
- $(SHOW)'COQCHK $(call vo_to_mod,$@)'
- $(HIDE)$(CHICKEN) -boot -silent -norec $(call vo_to_mod,$@) \
- || ( RV=$$?; rm -f "$@"; exit $${RV} )
-endif
###########################################################################
-# Dependencies
+# Dependencies of ML code
###########################################################################
-# .ml4.d contains the dependencies to generate the .ml from the .ml4
-# NOT to generate object code.
-
-%.ml4.d: $(D_DEPEND_BEFORE_SRC) %.ml4
- $(SHOW)'CAMLP4DEPS $<'
- $(HIDE)echo "$*.ml: $(if $(NO_RECOMPILE_ML4),$(ORDER_ONLY_SEP)) $(call CAMLP4DEPS,$<)" $(TOTARGET)
-
-# Since OCaml 3.12.1, we could use again ocamldep directly, thanks to
-# the option -ml-synonym
-
-OCAMLDEP_NG = $(OCAMLFIND) ocamldep -slash -ml-synonym .ml4
-
-checker/%.ml.d: $(D_DEPEND_BEFORE_SRC) checker/%.ml $(D_DEPEND_AFTER_SRC) $(GENFILES)
- $(SHOW)'OCAMLDEP $<'
- $(HIDE)$(OCAMLDEP_NG) $(LOCALCHKLIBS) "$<" $(TOTARGET)
-
-checker/%.mli.d: $(D_DEPEND_BEFORE_SRC) checker/%.mli $(D_DEPEND_AFTER_SRC) $(GENFILES)
- $(SHOW)'OCAMLDEP $<'
- $(HIDE)$(OCAMLDEP_NG) $(LOCALCHKLIBS) "$<" $(TOTARGET)
+# Ocamldep is now used directly again (thanks to -ml-synonym in OCaml >= 3.12)
+OCAMLDEP = $(OCAMLFIND) ocamldep -slash -ml-synonym .ml4 -ml-synonym .mlpack
%.ml.d: $(D_DEPEND_BEFORE_SRC) %.ml $(D_DEPEND_AFTER_SRC) $(GENFILES)
$(SHOW)'OCAMLDEP $<'
- $(HIDE)$(OCAMLDEP_NG) $(DEPFLAGS) "$<" $(TOTARGET)
+ $(HIDE)$(OCAMLDEP) $(DEPFLAGS) "$<" $(TOTARGET)
%.mli.d: $(D_DEPEND_BEFORE_SRC) %.mli $(D_DEPEND_AFTER_SRC) $(GENFILES)
$(SHOW)'OCAMLDEP $<'
- $(HIDE)$(OCAMLDEP_NG) $(DEPFLAGS) "$<" $(TOTARGET)
+ $(HIDE)$(OCAMLDEP) $(DEPFLAGS) "$<" $(TOTARGET)
-checker/%.mllib.d: $(D_DEPEND_BEFORE_SRC) checker/%.mllib $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
+%.mllib.d: $(D_DEPEND_BEFORE_SRC) %.mllib $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
$(SHOW)'OCAMLLIBDEP $<'
- $(HIDE)$(OCAMLLIBDEP) $(LOCALCHKLIBS) "$<" $(TOTARGET)
+ $(HIDE)$(OCAMLLIBDEP) $(DEPFLAGS) "$<" $(TOTARGET)
-dev/%.mllib.d: $(D_DEPEND_BEFORE_SRC) dev/%.mllib $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
- $(SHOW)'OCAMLLIBDEP $<'
- $(HIDE)$(OCAMLLIBDEP) $(DEPFLAGS) -I dev "$<" $(TOTARGET)
-
-%.mllib.d: $(D_DEPEND_BEFORE_SRC) %.mllib $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
+%.mlpack.d: $(D_DEPEND_BEFORE_SRC) %.mlpack $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
$(SHOW)'OCAMLLIBDEP $<'
$(HIDE)$(OCAMLLIBDEP) $(DEPFLAGS) "$<" $(TOTARGET)
-%.v.d: $(D_DEPEND_BEFORE_SRC) %.v $(D_DEPEND_AFTER_SRC) $(COQDEP) $(GENVFILES)
- $(SHOW)'COQDEP $<'
- $(HIDE)$(COQDEP) -boot $(DEPNATDYN) "$<" $(TOTARGET)
+###########################################################################
+# Compilation of .v files
+###########################################################################
-%_stubs.c.d: $(D_DEPEND_BEFORE_SRC) %_stubs.c $(D_DEPEND_AFTER_SRC)
- $(SHOW)'CCDEP $<'
- $(HIDE)echo "$@ $(@:.c.d=.o): $(@:.c.d=.c)" > $@
+# NB: for make world, no need to mention explicitly the .cmxs of the plugins,
+# since they are all mentioned in at least one Declare ML Module in some .v
-%.c.d: $(D_DEPEND_BEFORE_SRC) %.c $(D_DEPEND_AFTER_SRC) $(GENHFILES)
- $(SHOW)'CCDEP $<'
- $(HIDE)$(OCAMLC) -ccopt "-MM -MQ $@ -MQ $(<:.c=.o) -isystem $(CAMLHLIB)" $< $(TOTARGET)
+coqlib: theories plugins
-###########################################################################
-# this sets up developper supporting stuff
-###########################################################################
+theories: $(THEORIESVO)
+plugins: $(PLUGINSVO)
-.PHONY: devel otags
-devel: $(DEBUGPRINTERS)
+.PHONY: coqlib theories plugins
-otags:
- otags $(MLIFILES) $(MLSTATICFILES) \
- $(foreach i,$(ML4FILES),-pc -pa tools/compat5.cmo -pa op -pa g -pa m -pa rq $(patsubst %,-pa %,$(call CAMLP4DEPS,$i)) -impl $i)
+# One of the .v files is macro-generated
+theories/Numbers/Natural/BigN/NMake_gen.v: theories/Numbers/Natural/BigN/NMake_gen.ml
+ $(OCAML) $< $(TOTARGET)
+
+# The .vo files in Init are built with the -noinit option
+
+theories/Init/%.vo theories/Init/%.glob: theories/Init/%.v $(VO_TOOLS_DEP)
+ $(SHOW)'COQC $(COQ_XML) -noinit $<'
+ $(HIDE)rm -f theories/Init/$*.glob
+ $(HIDE)$(BOOTCOQC) $< $(COQ_XML) -noinit -R theories Coq
+
+# The general rule for building .vo files :
+
+%.vo %.glob: %.v theories/Init/Prelude.vo $(VO_TOOLS_DEP)
+ $(SHOW)'COQC $<'
+ $(HIDE)rm -f $*.glob
+ $(HIDE)$(BOOTCOQC) $<
+ifdef VALIDATE
+ $(SHOW)'COQCHK $(call vo_to_mod,$@)'
+ $(HIDE)$(CHICKEN) -boot -silent -norec $(call vo_to_mod,$@) \
+ || ( RV=$$?; rm -f "$@"; exit $${RV} )
+endif
+
+# Dependencies of .v files
+
+%.v.d: $(D_DEPEND_BEFORE_SRC) %.v $(D_DEPEND_AFTER_SRC) $(COQDEPBOOT) $(GENVFILES)
+ $(SHOW)'COQDEP $<'
+ $(HIDE)$(COQDEPBOOT) -boot $(DEPNATDYN) "$<" $(TOTARGET)
###########################################################################
# To speed-up things a bit, let's dissuade make to attempt rebuilding makefiles
-Makefile Makefile.build Makefile.common config/Makefile : ;
-
+Makefile $(wildcard Makefile.*) config/Makefile : ;
# For emacs:
# Local Variables:
diff --git a/Makefile.checker b/Makefile.checker
new file mode 100644
index 000000000..3ea0baced
--- /dev/null
+++ b/Makefile.checker
@@ -0,0 +1,86 @@
+#######################################################################
+# v # The Coq Proof Assistant / The Coq Development Team #
+# <O___,, # INRIA-Rocquencourt & LRI-CNRS-Orsay #
+# \VV/ #############################################################
+# // # This file is distributed under the terms of the #
+# # GNU Lesser General Public License Version 2.1 #
+#######################################################################
+
+## Makefile rules for building Coqchk
+
+## NB: For the moment, the build system of Coqchk is part of
+## the one of Coq. In particular, this Makefile.checker is included in
+## Makefile.build. Please ensure that the rules define here are
+## indeed specific to files of the form checker/*
+
+# The binaries
+
+CHICKENBYTE:=bin/coqchk.byte$(EXE)
+CHICKEN:=bin/coqchk$(EXE)
+
+# The sources
+
+CHKLIBS:= -I config -I lib -I checker
+
+## NB: currently, both $(OPTFLAGS) and $(BYTEFLAGS) contain -thread
+
+# The rules
+
+ifeq ($(BEST),opt)
+$(CHICKEN): checker/check.cmxa checker/main.ml
+ $(SHOW)'OCAMLOPT -o $@'
+ $(HIDE)$(OCAMLOPT) $(SYSCMXA) $(CHKLIBS) $(OPTFLAGS) $(LINKMETADATA) -o $@ $^
+ $(STRIP) $@
+ $(CODESIGN) $@
+else
+$(CHICKEN): $(CHICKENBYTE)
+ cp $< $@
+endif
+
+$(CHICKENBYTE): checker/check.cma checker/main.ml
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(OCAMLC) $(SYSCMA) $(CHKLIBS) $(BYTEFLAGS) $(CUSTOM) -o $@ $^
+
+checker/check.cma: checker/check.mllib | md5chk
+ $(SHOW)'OCAMLC -a -o $@'
+ $(HIDE)$(OCAMLC) $(CHKLIBS) $(BYTEFLAGS) -a -o $@ $(filter-out %.mllib, $^)
+
+checker/check.cmxa: checker/check.mllib | md5chk
+ $(SHOW)'OCAMLOPT -a -o $@'
+ $(HIDE)$(OCAMLOPT) $(CHKLIBS) $(OPTFLAGS) -a -o $@ $(filter-out %.mllib, $^)
+
+checker/%.ml.d: checker/%.ml
+ $(SHOW)'OCAMLDEP $<'
+ $(HIDE)$(OCAMLFIND) ocamldep -slash $(CHKLIBS) "$<" $(TOTARGET)
+
+checker/%.mli.d: checker/%.mli
+ $(SHOW)'OCAMLDEP $<'
+ $(HIDE)$(OCAMLFIND) ocamldep -slash $(CHKLIBS) "$<" $(TOTARGET)
+
+checker/%.mllib.d: checker/%.mllib | $(OCAMLLIBDEP)
+ $(SHOW)'OCAMLLIBDEP $<'
+ $(HIDE)$(OCAMLLIBDEP) $(CHKLIBS) "$<" $(TOTARGET)
+
+checker/%.cmi: checker/%.mli
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(CHKLIBS) $(BYTEFLAGS) -c $<
+
+checker/%.cmo: checker/%.ml
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(CHKLIBS) $(BYTEFLAGS) -c $<
+
+checker/%.cmx: checker/%.ml
+ $(SHOW)'OCAMLOPT $<'
+ $(HIDE)$(OCAMLOPT) $(CHKLIBS) $(OPTFLAGS) $(HACKMLI) -c $<
+
+md5chk:
+ $(SHOW)'MD5SUM cic.mli'
+ $(HIDE)if grep -q `$(MD5SUM) checker/cic.mli` checker/values.ml; \
+ then true; else echo "Error: outdated checker/values.ml"; false; fi
+
+.PHONY: md5chk
+
+# For emacs:
+# Local Variables:
+# mode: makefile
+# End:
diff --git a/Makefile.common b/Makefile.common
index a052bd7a6..95f4c01fd 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -14,19 +14,32 @@
COQMKTOP:=bin/coqmktop$(EXE)
-COQC:=bin/coqc$(EXE)
-
COQTOPBYTE:=bin/coqtop.byte$(EXE)
COQTOPEXE:=bin/coqtop$(EXE)
-CHICKENBYTE:=bin/coqchk.byte$(EXE)
-CHICKEN:=bin/coqchk$(EXE)
+COQDEP:=bin/coqdep$(EXE)
+COQMAKEFILE:=bin/coq_makefile$(EXE)
+GALLINA:=bin/gallina$(EXE)
+COQTEX:=bin/coq-tex$(EXE)
+COQWC:=bin/coqwc$(EXE)
+COQDOC:=bin/coqdoc$(EXE)
+COQC:=bin/coqc$(EXE)
+COQWORKMGR:=bin/coqworkmgr$(EXE)
-ifeq ($(CAMLP4),camlp4)
-CAMLP4MOD:=camlp4lib
-else
-CAMLP4MOD:=gramlib
-endif
+TOOLS:=$(COQDEP) $(COQMAKEFILE) $(GALLINA) $(COQTEX) $(COQWC) $(COQDOC) $(COQC)\
+ $(COQWORKMGR)
+
+COQDEPBOOT:=bin/coqdep_boot$(EXE)
+OCAMLLIBDEP:=bin/ocamllibdep$(EXE)
+FAKEIDE:=bin/fake_ide$(EXE)
+
+PRIVATEBINARIES:=$(FAKEIDE) $(OCAMLLIBDEP) $(COQDEPBOOT)
+
+CSDPCERT:=plugins/micromega/csdpcert$(EXE)
+
+###########################################################################
+# Object and Source files
+###########################################################################
ifeq ($(HASNATDYNLINK)-$(BEST),true-opt)
DEPNATDYN:=
@@ -39,31 +52,10 @@ INSTALLLIB:=install -m 644
INSTALLSH:=./install.sh
MKDIR:=install -d
-COQIDEBYTE:=bin/coqide.byte$(EXE)
-COQIDE:=bin/coqide$(EXE)
-COQIDEAPP:=bin/CoqIDE_$(VERSION).app
-COQIDEINAPP:=$(COQIDEAPP)/Contents/MacOS/coqide
-
-ifeq ($(BEST),opt)
-OPT:=opt
-else
-OPT:=
-endif
-
-BESTOBJ:=$(if $(OPT),.cmx,.cmo)
-BESTLIB:=$(if $(OPT),.cmxa,.cma)
-BESTDYN:=$(if $(OPT),.cmxs,.cma)
-
-COQBINARIES:= $(COQMKTOP) \
- $(COQTOPBYTE) $(COQTOPEXE) \
- $(CHICKENBYTE) $(CHICKEN)
-
-CSDPCERT:=plugins/micromega/csdpcert$(EXE)
-
CORESRCDIRS:=\
config lib kernel kernel/byterun library \
proofs tactics pretyping interp stm \
- toplevel parsing printing grammar intf engine
+ toplevel parsing printing intf engine ltac
PLUGINS:=\
omega romega micromega quote \
@@ -77,83 +69,6 @@ SRCDIRS:=\
tools tools/coqdoc \
$(addprefix plugins/, $(PLUGINS))
-IDESRCDIRS:= $(CORESRCDIRS) ide ide/utils
-
-# Order is relevant here because kernel and checker contain files
-# with the same name
-CHKSRCDIRS:= checker lib config kernel parsing
-
-###########################################################################
-# Tools
-###########################################################################
-
-COQDEP:=bin/coqdep$(EXE)
-OCAMLLIBDEP:=bin/ocamllibdep$(EXE)
-COQMAKEFILE:=bin/coq_makefile$(EXE)
-GALLINA:=bin/gallina$(EXE)
-COQTEX:=bin/coq-tex$(EXE)
-COQWC:=bin/coqwc$(EXE)
-COQDOC:=bin/coqdoc$(EXE)
-FAKEIDE:=bin/fake_ide$(EXE)
-COQWORKMGR:=bin/coqworkmgr$(EXE)
-
-TOOLS:=$(COQDEP) $(COQMAKEFILE) $(GALLINA) $(COQTEX) $(COQWC) $(COQDOC) $(COQC)\
- $(COQWORKMGR)
-
-PRIVATEBINARIES:=$(FAKEIDE) $(OCAMLLIBDEP)
-
-###########################################################################
-# Documentation
-###########################################################################
-
-LATEX:=latex
-BIBTEX:=BIBINPUTS=.: bibtex -min-crossrefs=10
-MAKEINDEX:=makeindex
-PDFLATEX:=pdflatex
-DVIPS:=dvips
-FIG2DEV:=fig2dev
-CONVERT:=convert
-HEVEA:=hevea
-HACHA:=hacha
-HEVEAOPTS:=-fix -exec xxdate.exe
-HEVEALIB:=/usr/local/lib/hevea:/usr/lib/hevea
-HTMLSTYLE:=simple
-export TEXINPUTS:=$(HEVEALIB):
-COQTEXOPTS:=-boot -n 72 -sl -small
-
-DOCCOMMON:=doc/common/version.tex doc/common/title.tex doc/common/macros.tex
-
-REFMANCOQTEXFILES:=$(addprefix doc/refman/, \
- RefMan-gal.v.tex RefMan-ext.v.tex \
- RefMan-mod.v.tex RefMan-tac.v.tex \
- RefMan-cic.v.tex RefMan-lib.v.tex \
- RefMan-tacex.v.tex RefMan-syn.v.tex \
- RefMan-oth.v.tex RefMan-ltac.v.tex \
- RefMan-decl.v.tex RefMan-pro.v.tex RefMan-sch.v.tex \
- Cases.v.tex Coercion.v.tex CanonicalStructures.v.tex Extraction.v.tex \
- Program.v.tex Omega.v.tex Micromega.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-pre.tex RefMan-int.tex RefMan-com.tex \
- RefMan-uti.tex RefMan-ide.tex RefMan-add.tex RefMan-modr.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)
-
-
-
-###########################################################################
-# Object and Source files
-###########################################################################
-
COQRUN := coqrun
LIBCOQRUN:=kernel/byterun/lib$(COQRUN).a
DLLCOQRUN:=$(dir $(LIBCOQRUN))dll$(COQRUN)$(DLLEXT)
@@ -162,42 +77,50 @@ BYTERUN:=$(addprefix kernel/byterun/, \
coq_fix_code.o coq_memory.o coq_values.o coq_interp.o )
# LINK ORDER:
-# Beware that highparsing.cma should appear before hightactics.cma
+# Beware that highparsing.cma should appear before ltac.cma
# respecting this order is useful for developers that want to load or link
# the libraries directly
CORECMA:=lib/clib.cma lib/lib.cma kernel/kernel.cma library/library.cma \
engine/engine.cma pretyping/pretyping.cma interp/interp.cma proofs/proofs.cma \
parsing/parsing.cma printing/printing.cma tactics/tactics.cma \
- stm/stm.cma toplevel/toplevel.cma parsing/highparsing.cma tactics/hightactics.cma
+ stm/stm.cma toplevel/toplevel.cma parsing/highparsing.cma ltac/ltac.cma
TOPLOOPCMA:=stm/proofworkertop.cma stm/tacworkertop.cma stm/queryworkertop.cma
GRAMMARCMA:=tools/compat5.cmo grammar/grammar.cma
-OMEGACMA:=plugins/omega/omega_plugin.cma
-ROMEGACMA:=plugins/romega/romega_plugin.cma
-MICROMEGACMA:=plugins/micromega/micromega_plugin.cma
-QUOTECMA:=plugins/quote/quote_plugin.cma
-RINGCMA:=plugins/setoid_ring/newring_plugin.cma
-NSATZCMA:=plugins/nsatz/nsatz_plugin.cma
-FOURIERCMA:=plugins/fourier/fourier_plugin.cma
-EXTRACTIONCMA:=plugins/extraction/extraction_plugin.cma
-FUNINDCMA:=plugins/funind/recdef_plugin.cma
-FOCMA:=plugins/firstorder/ground_plugin.cma
-CCCMA:=plugins/cc/cc_plugin.cma
-BTAUTOCMA:=plugins/btauto/btauto_plugin.cma
-RTAUTOCMA:=plugins/rtauto/rtauto_plugin.cma
-NATSYNTAXCMA:=plugins/syntax/nat_syntax_plugin.cma
+# modules known by the toplevel of Coq
+
+OBJSMOD:=$(shell cat $(CORECMA:.cma=.mllib))
+
+###########################################################################
+# plugins object files
+###########################################################################
+
+OMEGACMA:=plugins/omega/omega_plugin.cmo
+ROMEGACMA:=plugins/romega/romega_plugin.cmo
+MICROMEGACMA:=plugins/micromega/micromega_plugin.cmo
+QUOTECMA:=plugins/quote/quote_plugin.cmo
+RINGCMA:=plugins/setoid_ring/newring_plugin.cmo
+NSATZCMA:=plugins/nsatz/nsatz_plugin.cmo
+FOURIERCMA:=plugins/fourier/fourier_plugin.cmo
+EXTRACTIONCMA:=plugins/extraction/extraction_plugin.cmo
+FUNINDCMA:=plugins/funind/recdef_plugin.cmo
+FOCMA:=plugins/firstorder/ground_plugin.cmo
+CCCMA:=plugins/cc/cc_plugin.cmo
+BTAUTOCMA:=plugins/btauto/btauto_plugin.cmo
+RTAUTOCMA:=plugins/rtauto/rtauto_plugin.cmo
+NATSYNTAXCMA:=plugins/syntax/nat_syntax_plugin.cmo
OTHERSYNTAXCMA:=$(addprefix plugins/syntax/, \
- z_syntax_plugin.cma \
- numbers_syntax_plugin.cma \
- r_syntax_plugin.cma \
- ascii_syntax_plugin.cma \
- string_syntax_plugin.cma )
-DECLMODECMA:=plugins/decl_mode/decl_mode_plugin.cma
-DERIVECMA:=plugins/derive/derive_plugin.cma
-SSRMATCHINGCMA:=plugins/ssrmatching/ssrmatching.cma
+ z_syntax_plugin.cmo \
+ numbers_syntax_plugin.cmo \
+ r_syntax_plugin.cmo \
+ ascii_syntax_plugin.cmo \
+ string_syntax_plugin.cmo )
+DECLMODECMA:=plugins/decl_mode/decl_mode_plugin.cmo
+DERIVECMA:=plugins/derive/derive_plugin.cmo
+SSRMATCHINGCMA:=plugins/ssrmatching/ssrmatching.cmo
PLUGINSCMA:=$(OMEGACMA) $(ROMEGACMA) $(MICROMEGACMA) $(DECLMODECMA) \
$(QUOTECMA) $(RINGCMA) \
@@ -210,17 +133,17 @@ ifneq ($(HASNATDYNLINK),false)
STATICPLUGINS:=
INITPLUGINS:=$(EXTRACTIONCMA) $(FOCMA) $(CCCMA) \
$(FUNINDCMA) $(NATSYNTAXCMA)
- INITPLUGINSOPT:=$(INITPLUGINS:.cma=.cmxs)
+ INITPLUGINSOPT:=$(INITPLUGINS:.cmo=.cmxs)
PLUGINS:=$(PLUGINSCMA)
- PLUGINSOPT:=$(PLUGINSCMA:.cma=.cmxs)
+ PLUGINSOPT:=$(PLUGINSCMA:.cmo=.cmxs)
else
ifeq ($(BEST),byte)
STATICPLUGINS:=
INITPLUGINS:=$(EXTRACTIONCMA) $(FOCMA) $(CCCMA) \
$(FUNINDCMA) $(NATSYNTAXCMA)
- INITPLUGINSOPT:=$(INITPLUGINS:.cma=.cmxs)
+ INITPLUGINSOPT:=$(INITPLUGINS:.cmo=.cmxs)
PLUGINS:=$(PLUGINSCMA)
- PLUGINSOPT:=$(PLUGINSCMA:.cma=.cmxs)
+ PLUGINSOPT:=$(PLUGINSCMA:.cmo=.cmxs)
else
STATICPLUGINS:=$(PLUGINSCMA)
INITPLUGINS:=
@@ -231,43 +154,7 @@ endif
endif
LINKCMO:=$(CORECMA) $(STATICPLUGINS)
-LINKCMX:=$(CORECMA:.cma=.cmxa) $(STATICPLUGINS:.cma=.cmxa)
-
-IDEDEPS:=lib/clib.cma lib/xml_lexer.cmo lib/xml_parser.cmo lib/xml_printer.cmo lib/errors.cmo lib/spawn.cmo
-IDECMA:=ide/ide.cma
-IDETOPLOOPCMA=ide/coqidetop.cma
-
-LINKIDE:=$(IDEDEPS) $(IDECDEPS) $(IDECMA) ide/coqide_main.ml
-LINKIDEOPT:=$(IDEOPTCDEPS) $(patsubst %.cma,%.cmxa,$(IDEDEPS:.cmo=.cmx)) $(IDECMA:.cma=.cmxa) ide/coqide_main.ml
-
-# modules known by the toplevel of Coq
-
-OBJSMOD:=$(shell cat $(CORECMA:.cma=.mllib))
-
-IDEMOD:=$(shell cat ide/ide.mllib)
-
-# coqmktop, coqc
-
-COQENVCMO:=lib/clib.cma lib/errors.cmo
-
-COQMKTOPCMO:=$(COQENVCMO) tools/tolink.cmo tools/coqmktop.cmo
-
-COQCCMO:=$(COQENVCMO) toplevel/usage.cmo tools/coqc.cmo
-
-## Misc
-
-CSDPCERTCMO:=$(addprefix plugins/micromega/, \
- mutils.cmo micromega.cmo \
- sos_types.cmo sos_lib.cmo sos.cmo csdpcert.cmo )
-
-DEBUGPRINTERS:=dev/top_printers.cmo dev/vm_printers.cmo dev/printers.cma
-
-COQDEPCMO:=$(COQENVCMO) lib/system.cmo tools/coqdep_lexer.cmo tools/coqdep_common.cmo tools/coqdep.cmo
-
-COQDOCCMO:=lib/clib.cma $(addprefix tools/coqdoc/, \
- cdglobals.cmo alpha.cmo index.cmo tokens.cmo output.cmo cpretty.cmo main.cmo )
-
-COQMAKEFILECMO:=lib/clib.cma ide/project_file.cmo tools/coq_makefile.cmo
+LINKCMX:=$(CORECMA:.cma=.cmxa) $(STATICPLUGINS:.cmo=.cmx)
###########################################################################
# vo files
@@ -275,128 +162,41 @@ COQMAKEFILECMO:=lib/clib.cma ide/project_file.cmo tools/coq_makefile.cmo
## we now retrieve the names of .vo file to compile in */vo.itarget files
-cat_vo_itarget = $(addprefix $(1)/,$(shell cat $(1)/vo.itarget))
-
-## Theories
-
-INITVO:=$(call cat_vo_itarget, theories/Init)
-LOGICVO:=$(call cat_vo_itarget, theories/Logic)
-STRUCTURESVO:=$(call cat_vo_itarget, theories/Structures)
-ARITHVO:=$(call cat_vo_itarget, theories/Arith)
-SORTINGVO:=$(call cat_vo_itarget, theories/Sorting)
-BOOLVO:=$(call cat_vo_itarget, theories/Bool)
-PARITHVO:=$(call cat_vo_itarget, theories/PArith)
-NARITHVO:=$(call cat_vo_itarget, theories/NArith)
-ZARITHVO:=$(call cat_vo_itarget, theories/ZArith)
-QARITHVO:=$(call cat_vo_itarget, theories/QArith)
-LISTSVO:=$(call cat_vo_itarget, theories/Lists)
-VECTORSVO:=$(call cat_vo_itarget, theories/Vectors)
-STRINGSVO:=$(call cat_vo_itarget, theories/Strings)
-SETSVO:=$(call cat_vo_itarget, theories/Sets)
-FSETSVO:=$(call cat_vo_itarget, theories/FSets)
-MSETSVO:=$(call cat_vo_itarget, theories/MSets)
-RELATIONSVO:=$(call cat_vo_itarget, theories/Relations)
-WELLFOUNDEDVO:=$(call cat_vo_itarget, theories/Wellfounded)
-REALSVO:=$(call cat_vo_itarget, theories/Reals)
-NUMBERSVO:=$(call cat_vo_itarget, theories/Numbers)
-SETOIDSVO:=$(call cat_vo_itarget, theories/Setoids)
-UNICODEVO:=$(call cat_vo_itarget, theories/Unicode)
-CLASSESVO:=$(call cat_vo_itarget, theories/Classes)
-PROGRAMVO:=$(call cat_vo_itarget, theories/Program)
-COMPATVO:=$(call cat_vo_itarget, theories/Compat)
-
-THEORIESVO:=\
- $(INITVO) $(LOGICVO) $(ARITHVO) $(BOOLVO) \
- $(UNICODEVO) $(CLASSESVO) $(PROGRAMVO) \
- $(RELATIONSVO) $(WELLFOUNDEDVO) $(SETOIDSVO) \
- $(LISTSVO) $(STRINGSVO) \
- $(PARITHVO) $(NARITHVO) $(ZARITHVO) \
- $(SETSVO) $(FSETSVO) $(MSETSVO) \
- $(REALSVO) $(SORTINGVO) $(QARITHVO) \
- $(NUMBERSVO) $(STRUCTURESVO) $(VECTORSVO) \
- $(COMPATVO)
-
-THEORIESLIGHTVO:= $(INITVO) $(LOGICVO) $(UNICODEVO) $(ARITHVO)
-
-## Plugins
-
-OMEGAVO:=$(call cat_vo_itarget, plugins/omega)
-ROMEGAVO:=$(call cat_vo_itarget, plugins/romega)
-MICROMEGAVO:=$(call cat_vo_itarget, plugins/micromega)
-QUOTEVO:=$(call cat_vo_itarget, plugins/quote)
-RINGVO:=$(call cat_vo_itarget, plugins/setoid_ring)
-NSATZVO:=$(call cat_vo_itarget, plugins/nsatz)
-FOURIERVO:=$(call cat_vo_itarget, plugins/fourier)
-FUNINDVO:=$(call cat_vo_itarget, plugins/funind)
-BTAUTOVO:=$(call cat_vo_itarget, plugins/btauto)
-RTAUTOVO:=$(call cat_vo_itarget, plugins/rtauto)
-EXTRACTIONVO:=$(call cat_vo_itarget, plugins/extraction)
-CCVO:=
-DERIVEVO:=$(call cat_vo_itarget, plugins/derive)
-SSRMATCHINGVO:=$(call cat_vo_itarget, plugins/ssrmatching)
-
-PLUGINSVO:= $(OMEGAVO) $(ROMEGAVO) $(MICROMEGAVO) \
- $(FOURIERVO) $(CCVO) $(FUNINDVO) \
- $(RTAUTOVO) $(BTAUTOVO) $(RINGVO) $(QUOTEVO) \
- $(NSATZVO) $(EXTRACTIONVO) $(DERIVEVO) $(SSRMATCHINGVO)
+THEORIESVO:= $(foreach f, $(wildcard theories/*/vo.itarget), \
+ $(addprefix $(dir $(f)),$(shell cat $(f))))
+
+PLUGINSVO:= $(foreach f, $(wildcard plugins/*/vo.itarget), \
+ $(addprefix $(dir $(f)),$(shell cat $(f))))
ALLVO:= $(THEORIESVO) $(PLUGINSVO)
VFILES:= $(ALLVO:.vo=.v)
+
+## More specific targets
+
+THEORIESLIGHTVO:= \
+ $(filter theories/Init/% theories/Logic/% theories/Unicode/% theories/Arith/%, $(THEORIESVO))
+
ALLSTDLIB := test-suite/misc/universes/all_stdlib
# convert a (stdlib) filename into a module name:
# remove .vo, replace theories and plugins by Coq, and replace slashes by dots
vo_to_mod = $(subst /,.,$(patsubst theories/%,Coq.%,$(patsubst plugins/%,Coq.%,$(1:.vo=))))
+ALLMODS:=$(call vo_to_mod,$(ALLVO))
+
+
# Converting a stdlib filename into native compiler filenames
# Used for install targets
vo_to_cm = $(foreach vo,$(1),$(dir $(vo)).coq-native/$(subst /,_,$(patsubst theories/%,NCoq_%,$(patsubst plugins/%,NCoq_%,$(vo:.vo=.cm*)))))
vo_to_obj = $(foreach vo,$(1),$(dir $(vo)).coq-native/$(subst /,_,$(patsubst theories/%,NCoq_%,$(patsubst plugins/%,NCoq_%,$(vo:.vo=.o)))))
-ALLMODS:=$(call vo_to_mod,$(ALLVO))
-
LIBFILES:=$(THEORIESVO) $(PLUGINSVO) $(call vo_to_cm,$(THEORIESVO)) \
$(call vo_to_cm,$(PLUGINSVO)) $(call vo_to_obj,$(THEORIESVO)) \
$(call vo_to_obj,$(PLUGINSVO)) \
$(PLUGINSVO:.vo=.v) $(THEORIESVO:.vo=.v) \
$(PLUGINSVO:.vo=.glob) $(THEORIESVO:.vo=.glob)
-LIBFILESLIGHT:=$(THEORIESLIGHTVO)
-
-###########################################################################
-# Miscellaneous
-###########################################################################
-
-MANPAGES:=man/coq-tex.1 man/coqdep.1 man/gallina.1 \
- man/coqc.1 man/coqtop.1 man/coqtop.byte.1 man/coqtop.opt.1 \
- man/coqwc.1 man/coqdoc.1 man/coqide.1 \
- man/coq_makefile.1 man/coqmktop.1 man/coqchk.1
-
-###########################################################################
-# Source documentation
-###########################################################################
-
-OCAMLDOCDIR=dev/ocamldoc
-
-DOCMLIS=$(wildcard ./lib/*.mli ./intf/*.mli ./kernel/*.mli ./library/*.mli \
- ./engine/*.mli ./pretyping/*.mli ./interp/*.mli printing/*.mli \
- ./parsing/*.mli ./proofs/*.mli \
- ./tactics/*.mli ./stm/*.mli ./toplevel/*.mli)
-
-# Defining options to generate dependencies graphs
-DOT=dot
-ODOCDOTOPTS=-dot -dot-reduce
-
-###########################################################################
-# GTK for Coqide MacOS bundle
-###########################################################################
-
-GTKSHARE=$(shell pkg-config --variable=prefix gtk+-2.0)/share
-GTKBIN=$(shell pkg-config --variable=prefix gtk+-2.0)/bin
-GTKLIBS=$(shell pkg-config --variable=libdir gtk+-2.0)
-
-
# For emacs:
# Local Variables:
# mode: makefile
diff --git a/Makefile.dev b/Makefile.dev
new file mode 100644
index 000000000..f35b861c1
--- /dev/null
+++ b/Makefile.dev
@@ -0,0 +1,223 @@
+#######################################################################
+# v # The Coq Proof Assistant / The Coq Development Team #
+# <O___,, # INRIA-Rocquencourt & LRI-CNRS-Orsay #
+# \VV/ #############################################################
+# // # This file is distributed under the terms of the #
+# # GNU Lesser General Public License Version 2.1 #
+#######################################################################
+
+# Extra targets for developpers :
+# debug printers, revision, partial targets ...
+
+#########################
+# Debug printers in dev/
+#########################
+
+.PHONY: devel printers
+
+DEBUGPRINTERS:=dev/top_printers.cmo dev/vm_printers.cmo dev/printers.cma
+
+devel: printers
+printers: $(DEBUGPRINTERS)
+
+dev/printers.cma: dev/printers.mllib
+ $(SHOW)'Testing $@'
+ $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $(SYSCMA) $(P4CMA) $(filter-out %.mllib, $^) -o test-printer
+ @rm -f test-printer
+ $(SHOW)'OCAMLC -a $@'
+ $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $(SYSCMA) $(P4CMA) $(filter-out %.mllib, $^) -linkall -a -o $@
+
+dev/%.mllib.d: dev/%.mllib | $(OCAMLLIBDEP) $(GENFILES)
+ $(SHOW)'OCAMLLIBDEP $<'
+ $(HIDE)$(OCAMLLIBDEP) $(DEPFLAGS) -I dev "$<" $(TOTARGET)
+
+############
+# revision
+############
+
+# display the revision number when compiling a checked out source tree
+
+revision:
+ $(SHOW)'CHECK revision'
+ $(HIDE)rm -f revision.new
+ifeq ($(CHECKEDOUT),svn)
+ $(HIDE)set -e; \
+ if test -x "`which svn`"; then \
+ export LC_ALL=C;\
+ svn info . | sed -ne '/URL/s/.*\/\([^\/]\{1,\}\)/\1/p' > revision.new; \
+ svn info . | sed -ne '/Revision/s/Revision: \([0-9]\{1,\}\)/\1/p'>> revision.new; \
+ fi
+endif
+ifeq ($(CHECKEDOUT),gnuarch)
+ $(HIDE)set -e; \
+ if test -x "`which tla`"; then \
+ LANG=C; export LANG; \
+ tla tree-version > revision.new ; \
+ tla tree-revision | sed -ne 's|.*--||p' >> revision.new ; \
+ fi
+endif
+ifeq ($(CHECKEDOUT),git)
+ $(HIDE)set -e; \
+ if test -x "`which git`"; then \
+ LANG=C; export LANG; \
+ GIT_BRANCH=$$(git branch -a | sed -ne '/^\* /s/^\* \(.*\)/\1/p'); \
+ GIT_HOST=$$(hostname); \
+ GIT_PATH=$$(pwd); \
+ (echo "$${GIT_HOST}:$${GIT_PATH},$${GIT_BRANCH}") > revision.new; \
+ (echo "$$(git log -1 --pretty='format:%H')") >> revision.new; \
+ fi
+endif
+ $(HIDE)set -e; \
+ if test -e revision.new; then \
+ if test -e revision; then \
+ if test "`cat revision`" = "`cat revision.new`" ; then \
+ rm -f revision.new; \
+ else \
+ mv -f revision.new revision; \
+ fi; \
+ else \
+ mv -f revision.new revision; \
+ fi \
+ fi
+
+.PHONY: revision
+
+###################
+# Partial builds
+###################
+
+# The following partial targets are normally not necessary
+# for a complete build of coq, see instead 'make world' for that.
+# But these partial targets could be quite handy for quick builds
+# of specific components of Coq.
+
+###############################
+### 1) general-purpose targets
+###############################
+
+coqlight: theories-light tools coqbinaries
+
+states: theories/Init/Prelude.vo
+
+miniopt: $(COQTOPEXE) pluginsopt
+minibyte: $(COQTOPBYTE) pluginsbyte
+
+pluginsopt: $(PLUGINSOPT)
+pluginsbyte: $(PLUGINS)
+
+.PHONY: coqlight states miniopt minibyte pluginsopt pluginsbyte
+
+##########################
+### 2) core ML components
+##########################
+
+lib: lib/clib.cma lib/lib.cma
+kernel: kernel/kernel.cma
+byterun: $(BYTERUN)
+library: library/library.cma
+engine: engine/engine.cma
+proofs: proofs/proofs.cma
+tactics: tactics/tactics.cma
+interp: interp/interp.cma
+parsing: parsing/parsing.cma
+pretyping: pretyping/pretyping.cma
+highparsing: parsing/highparsing.cma
+stm: stm/stm.cma
+toplevel: toplevel/toplevel.cma
+ltac: ltac/ltac.cma
+
+.PHONY: lib kernel byterun library proofs tactics interp parsing pretyping
+.PHONY: engine highparsing stm toplevel ltac
+
+######################
+### 3) theories files
+######################
+
+init: $(filter theories/Init/%, $(THEORIESVO))
+logic: $(filter theories/Logic/%, %(THEORIESVO))
+arith: $(filter theories/Arith/%, $(THEORIESVO))
+bool: $(filter theories/Bool/%, $(THEORIESVO))
+parith: $(filter theories/PArith/%, $(THEORIESVO))
+narith: $(filter theories/NArith/%, $(THEORIESVO))
+zarith: $(filter theories/ZArith/%, $(THEORIESVO))
+qarith: $(filter theories/QArith/%, $(THEORIESVO))
+lists: $(filter theories/Lists/%, $(THEORIESVO))
+strings: $(filter theories/Strings/%, $(THEORIESVO))
+sets: $(filter theories/Sets/%, $(THEORIESVO))
+fsets: $(filter theories/FSets/%, $(THEORIESVO))
+relations: $(filter theories/Relations/%, $(THEORIESVO))
+wellfounded: $(filter theories/Wellfounded/%, $(THEORIESVO))
+reals: $(filter theories/Reals/%, $(THEORIESVO))
+setoids: $(filter theories/Setoids/%, $(THEORIESVO))
+sorting: $(filter theories/Sorting/%, $(THEORIESVO))
+numbers: $(filter theories/Numbers/%, $(THEORIESVO))
+unicode: $(filter theories/Unicode/%, $(THEORIESVO))
+classes: $(filter theories/Classes/%, $(THEORIESVO))
+program: $(filter theories/Program/%, $(THEORIESVO))
+structures: $(filter theories/Structures/%, $(THEORIESVO))
+vectors: $(filter theories/Vectors/%, $(THEORIESVO))
+msets: $(filter theories/MSets/%, $(THEORIESVO))
+compat: $(filter theories/Compat/%, $(THEORIESVO))
+
+theories-light: $(THEORIESLIGHTVO)
+
+noreal: unicode logic arith bool zarith qarith lists sets fsets \
+ relations wellfounded setoids sorting
+
+.PHONY: init theories-light noreal
+.PHONY: logic arith bool narith zarith qarith lists strings sets
+.PHONY: fsets relations wellfounded reals setoids sorting numbers
+.PHONY: msets mmaps compat
+
+################
+### 4) plugins
+################
+
+OMEGAVO:=$(filter plugins/omega/%, $(PLUGINSVO))
+ROMEGAVO:=$(filter plugins/romega/%, $(PLUGINSVO))
+MICROMEGAVO:=$(filter plugins/micromega/%, $(PLUGINSVO))
+QUOTEVO:=$(filter plugins/quote/%, $(PLUGINSVO))
+RINGVO:=$(filter plugins/setoid_ring/%, $(PLUGINSVO))
+NSATZVO:=$(filter plugins/nsatz/%, $(PLUGINSVO))
+FOURIERVO:=$(filter plugins/fourier/%, $(PLUGINSVO))
+FUNINDVO:=$(filter plugins/funind/%, $(PLUGINSVO))
+BTAUTOVO:=$(filter plugins/btauto/%, $(PLUGINSVO))
+RTAUTOVO:=$(filter plugins/rtauto/%, $(PLUGINSVO))
+EXTRACTIONVO:=$(filter plugins/extraction/%, $(PLUGINSVO))
+CCVO:=
+DERIVEVO:=$(filter plugins/derive/%, $(PLUGINSVO))
+
+omega: $(OMEGAVO) $(OMEGACMA) $(ROMEGAVO) $(ROMEGACMA)
+micromega: $(MICROMEGAVO) $(MICROMEGACMA) $(CSDPCERT)
+setoid_ring: $(RINGVO) $(RINGCMA)
+nsatz: $(NSATZVO) $(NSATZCMA)
+extraction: $(EXTRACTIONCMA)
+fourier: $(FOURIERVO) $(FOURIERCMA)
+funind: $(FUNINDCMA) $(FUNINDVO)
+cc: $(CCVO) $(CCCMA)
+rtauto: $(RTAUTOVO) $(RTAUTOCMA)
+btauto: $(BTAUTOVO) $(BTAUTOCMA)
+
+.PHONY: omega micromega setoid_ring nsatz extraction
+.PHONY: fourier funind cc rtauto btauto
+
+#################################
+### Misc other development rules
+#################################
+
+# NOTA : otags only accepts camlp4 as preprocessor, so the following rule
+# won't build tags of .ml4 when compiling with camlp5
+
+otags:
+ otags $(MLIFILES) $(filter-out configure.ml, $(MLSTATICFILES)) \
+ $(if $(filter camlp5,$(CAMLP4)), , \
+ -pa op -pa g -pa m -pa rq $(addprefix -pa , $(CAMLP4DEPS)) \
+ $(addprefix -impl , $(ML4FILES)))
+
+.PHONY: otags
+
+
+# For emacs:
+# Local Variables:
+# mode: makefile
+# End:
diff --git a/Makefile.doc b/Makefile.doc
index b7251ce57..6c345025a 100644
--- a/Makefile.doc
+++ b/Makefile.doc
@@ -1,3 +1,11 @@
+#######################################################################
+# v # The Coq Proof Assistant / The Coq Development Team #
+# <O___,, # INRIA-Rocquencourt & LRI-CNRS-Orsay #
+# \VV/ #############################################################
+# // # This file is distributed under the terms of the #
+# # GNU Lesser General Public License Version 2.1 #
+#######################################################################
+
# Makefile for the Coq documentation
# To compile documentation, you need the following tools:
@@ -5,6 +13,61 @@
# Pdf: pdflatex
# Html: hevea (http://hevea.inria.fr) >= 1.05
+# The main entry point :
+
+documentation: doc-$(WITHDOC) ## see $(WITHDOC) in config/Makefile
+doc-all: doc
+doc-no:
+
+.PHONY: documentation doc-all doc-no
+
+######################################################################
+### Variables
+######################################################################
+
+LATEX:=latex
+BIBTEX:=BIBINPUTS=.: bibtex -min-crossrefs=10
+MAKEINDEX:=makeindex
+PDFLATEX:=pdflatex
+DVIPS:=dvips
+FIG2DEV:=fig2dev
+CONVERT:=convert
+HEVEA:=hevea
+HACHA:=hacha
+HEVEAOPTS:=-fix -exec xxdate.exe
+HEVEALIB:=/usr/local/lib/hevea:/usr/lib/hevea
+HTMLSTYLE:=simple
+export TEXINPUTS:=$(HEVEALIB):
+COQTEXOPTS:=-boot -n 72 -sl -small
+
+DOCCOMMON:=doc/common/version.tex doc/common/title.tex doc/common/macros.tex
+
+REFMANCOQTEXFILES:=$(addprefix doc/refman/, \
+ RefMan-gal.v.tex RefMan-ext.v.tex \
+ RefMan-mod.v.tex RefMan-tac.v.tex \
+ RefMan-cic.v.tex RefMan-lib.v.tex \
+ RefMan-tacex.v.tex RefMan-syn.v.tex \
+ RefMan-oth.v.tex RefMan-ltac.v.tex \
+ RefMan-decl.v.tex RefMan-pro.v.tex RefMan-sch.v.tex \
+ Cases.v.tex Coercion.v.tex CanonicalStructures.v.tex Extraction.v.tex \
+ Program.v.tex Omega.v.tex Micromega.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-pre.tex RefMan-int.tex RefMan-com.tex \
+ RefMan-uti.tex RefMan-ide.tex RefMan-add.tex RefMan-modr.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
######################################################################
@@ -339,6 +402,80 @@ install-doc-index-urls:
$(MKDIR) $(FULLDATADIR)
$(INSTALLLIB) $(INDEXURLS) $(FULLDATADIR)
+
+###########################################################################
+# Documentation of the source code (using ocamldoc)
+###########################################################################
+
+OCAMLDOCDIR=dev/ocamldoc
+
+DOCMLIS=$(wildcard ./lib/*.mli ./intf/*.mli ./kernel/*.mli ./library/*.mli \
+ ./engine/*.mli ./pretyping/*.mli ./interp/*.mli printing/*.mli \
+ ./parsing/*.mli ./proofs/*.mli \
+ ./tactics/*.mli ./stm/*.mli ./toplevel/*.mli ./ltac/*.mli)
+
+# Defining options to generate dependencies graphs
+DOT=dot
+ODOCDOTOPTS=-dot -dot-reduce
+
+.PHONY: source-doc mli-doc ml-doc
+
+source-doc: mli-doc $(OCAMLDOCDIR)/coq.pdf
+
+$(OCAMLDOCDIR)/coq.tex: $(DOCMLIS:.mli=.cmi)
+ $(SHOW)'OCAMLDOC -latex -o $@'
+ $(HIDE)$(OCAMLFIND) ocamldoc -latex -rectypes -I $(MYCAMLP4LIB) $(MLINCLUDES)\
+ $(DOCMLIS) -noheader -t "Coq mlis documentation" \
+ -intro $(OCAMLDOCDIR)/docintro -o $@.tmp
+ $(SHOW)'OCAMLDOC utf8 fix'
+ $(HIDE)$(OCAMLDOCDIR)/fix-ocamldoc-utf8 $@.tmp
+ $(HIDE)cat $(OCAMLDOCDIR)/header.tex $@.tmp > $@
+ rm $@.tmp
+
+mli-doc: $(DOCMLIS:.mli=.cmi)
+ $(SHOW)'OCAMLDOC -html'
+ $(HIDE)$(OCAMLFIND) ocamldoc -charset utf-8 -html -rectypes -I +threads -I $(MYCAMLP4LIB) $(MLINCLUDES) \
+ $(DOCMLIS) -d $(OCAMLDOCDIR)/html -colorize-code \
+ -t "Coq mlis documentation" -intro $(OCAMLDOCDIR)/docintro \
+ -css-style style.css
+
+ml-dot: $(MLFILES)
+ $(OCAMLFIND) ocamldoc -dot -dot-reduce -rectypes -I +threads -I $(CAMLLIB) -I $(MYCAMLP4LIB) $(MLINCLUDES) \
+ $(filter $(addsuffix /%.ml,$(CORESRCDIRS)),$(MLFILES)) -o $(OCAMLDOCDIR)/coq.dot
+
+%_dep.png: %.dot
+ $(DOT) -Tpng $< -o $@
+
+%_types.dot: %.mli
+ $(OCAMLFIND) ocamldoc -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -dot-types -o $@ $<
+
+OCAMLDOC_MLLIBD = $(OCAMLFIND) ocamldoc -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -o $@ \
+ $(foreach lib,$(|:.mllib.d=_MLLIB_DEPENDENCIES),$(addsuffix .ml,$($(lib))))
+
+%.dot: | %.mllib.d
+ $(OCAMLDOC_MLLIBD)
+
+ml-doc:
+ $(OCAMLFIND) ocamldoc -charset utf-8 -html -rectypes -I +threads $(MLINCLUDES) $(COQIDEFLAGS) -d $(OCAMLDOCDIR) $(MLSTATICFILES)
+
+parsing/parsing.dot : | parsing/parsing.mllib.d parsing/highparsing.mllib.d
+ $(OCAMLDOC_MLLIBD)
+
+grammar/grammar.dot : | grammar/grammar.mllib.d
+ $(OCAMLDOC_MLLIBD)
+
+tactics/tactics.dot: | tactics/tactics.mllib.d ltac/ltac.mllib.d
+ $(OCAMLDOC_MLLIBD)
+
+%.dot: %.mli
+ $(OCAMLFIND) ocamldoc -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -o $@ $<
+
+$(OCAMLDOCDIR)/%.pdf: $(OCAMLDOCDIR)/%.tex
+ $(SHOW)'PDFLATEX $*.tex'
+ $(HIDE)(cd $(OCAMLDOCDIR) ; pdflatex -interaction=batchmode $*.tex && pdflatex -interaction=batchmode $*.tex)
+ $(HIDE)(cd doc/tools/; show_latex_messages -no-overfull ../../$(OCAMLDOCDIR)/$*.log)
+
+
# For emacs:
# Local Variables:
# mode: makefile
diff --git a/Makefile.ide b/Makefile.ide
new file mode 100644
index 000000000..8d6b5de36
--- /dev/null
+++ b/Makefile.ide
@@ -0,0 +1,254 @@
+#######################################################################
+# v # The Coq Proof Assistant / The Coq Development Team #
+# <O___,, # INRIA-Rocquencourt & LRI-CNRS-Orsay #
+# \VV/ #############################################################
+# // # This file is distributed under the terms of the #
+# # GNU Lesser General Public License Version 2.1 #
+#######################################################################
+
+## Makefile rules for building the CoqIDE interface
+
+## NB: For the moment, the build system of CoqIDE is part of
+## the one of Coq. In particular, this Makefile.ide is included in
+## Makefile.build. Please ensure that the rules define here are
+## indeed specific to files of the form ide/*
+
+## Coqide-related variables set by ./configure in config/Makefile
+
+#COQIDEINCLUDES : something like -I +lablgtk2
+#HASCOQIDE : opt / byte / no
+#IDEFLAGS : some extra cma, for instance
+#IDEOPTCDEPS : on windows, ide/ide_win32_stubs.o ide/coq_icon.o
+#IDECDEPS
+#IDECDEPSFLAGS
+#IDEINT : X11 / QUARTZ / WIN32
+
+## CoqIDE Executable
+
+COQIDEBYTE:=bin/coqide.byte$(EXE)
+COQIDE:=bin/coqide$(EXE)
+COQIDEAPP:=bin/CoqIDE_$(VERSION).app
+COQIDEINAPP:=$(COQIDEAPP)/Contents/MacOS/coqide
+
+## CoqIDE source directory and files
+
+# Note : for just building bin/coqide, we could only consider
+# config, lib, ide and ide/utils. But the coqidetop plugin (the
+# one that will be loaded by coqtop -ideslave) refers to some
+# core modules of coq, for instance printing/*.
+
+IDESRCDIRS:= $(CORESRCDIRS) ide ide/utils
+
+COQIDEFLAGS=$(addprefix -I , $(IDESRCDIRS)) $(COQIDEINCLUDES)
+
+IDEDEPS:=lib/clib.cma lib/errors.cmo lib/spawn.cmo
+IDECMA:=ide/ide.cma
+IDETOPLOOPCMA=ide/coqidetop.cma
+
+LINKIDE:=$(IDEDEPS) $(IDECDEPS) $(IDECMA) ide/coqide_main.ml
+LINKIDEOPT:=$(IDEOPTCDEPS) $(patsubst %.cma,%.cmxa,$(IDEDEPS:.cmo=.cmx)) $(IDECMA:.cma=.cmxa) ide/coqide_main.ml
+
+IDEFILES=$(wildcard ide/*.lang) ide/coq_style.xml ide/coq.png ide/MacOS/default_accel_map
+
+## GTK for Coqide MacOS bundle
+
+GTKSHARE=$(shell pkg-config --variable=prefix gtk+-2.0)/share
+GTKBIN=$(shell pkg-config --variable=prefix gtk+-2.0)/bin
+GTKLIBS=$(shell pkg-config --variable=libdir gtk+-2.0)
+
+
+###########################################################################
+# CoqIde special targets
+###########################################################################
+
+.PHONY: coqide coqide-binaries coqide-no coqide-byte coqide-opt coqide-files
+
+# target to build CoqIde
+coqide: coqide-files coqide-binaries theories/Init/Prelude.vo
+
+coqide-binaries: coqide-$(HASCOQIDE) ide-toploop
+coqide-no:
+coqide-byte: $(COQIDEBYTE) $(COQIDE)
+coqide-opt: $(COQIDEBYTE) $(COQIDE)
+coqide-files: $(IDEFILES)
+ifeq ($(BEST),opt)
+ide-toploop: $(IDETOPLOOPCMA) $(IDETOPLOOPCMA:.cma=.cmxs)
+else
+ide-toploop: $(IDETOPLOOPCMA)
+endif
+
+ifeq ($(HASCOQIDE),opt)
+$(COQIDE): $(LINKIDEOPT)
+ $(SHOW)'OCAMLOPT -o $@'
+ $(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) -o $@ unix.cmxa threads.cmxa lablgtk.cmxa \
+ lablgtksourceview2.cmxa str.cmxa $(IDEFLAGS:.cma=.cmxa) $^
+ $(STRIP) $@
+else
+$(COQIDE): $(COQIDEBYTE)
+ cp $< $@
+endif
+
+$(COQIDEBYTE): $(LINKIDE)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(OCAMLC) $(COQIDEFLAGS) $(BYTEFLAGS) -o $@ unix.cma threads.cma lablgtk.cma \
+ lablgtksourceview2.cma str.cma $(IDEFLAGS) $(IDECDEPSFLAGS) $^
+
+ide/coqide_main.ml: ide/coqide_main.ml4 config/Makefile # no camlp4deps here
+ $(SHOW)'CAMLP4O $<'
+ $(HIDE)$(CAMLP4O) $(CAMLP4FLAGS) $(PR_O) $(CAMLP4USE) -D$(IDEINT) -impl $< -o $@
+
+
+ide/%.cmi: ide/%.mli
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(COQIDEFLAGS) $(BYTEFLAGS) -c $<
+
+ide/%.cmo: ide/%.ml
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(COQIDEFLAGS) $(BYTEFLAGS) -c $<
+
+ide/%.cmx: ide/%.ml
+ $(SHOW)'OCAMLOPT $<'
+ $(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) $(HACKMLI) -c $<
+
+
+####################
+## Install targets
+####################
+
+.PHONY: install-coqide install-ide-bin install-ide-toploop install-ide-files install-ide-info install-ide-devfiles
+
+ifeq ($(HASCOQIDE),no)
+install-coqide: install-ide-toploop
+else
+install-coqide: install-ide-bin install-ide-toploop install-ide-files install-ide-info install-ide-devfiles
+endif
+
+install-ide-bin:
+ $(MKDIR) $(FULLBINDIR)
+ $(INSTALLBIN) $(COQIDE) $(FULLBINDIR)
+
+install-ide-toploop:
+ $(MKDIR) $(FULLCOQLIB)/toploop
+ $(INSTALLBIN) $(IDETOPLOOPCMA) $(FULLCOQLIB)/toploop/
+ifeq ($(BEST),opt)
+ $(INSTALLBIN) $(IDETOPLOOPCMA:.cma=.cmxs) $(FULLCOQLIB)/toploop/
+endif
+
+install-ide-devfiles:
+ $(MKDIR) $(FULLCOQLIB)
+ $(INSTALLSH) $(FULLCOQLIB) $(IDECMA) \
+ $(foreach lib,$(IDECMA:.cma=_MLLIB_DEPENDENCIES),$(addsuffix .cmi,$($(lib))))
+ifeq ($(BEST),opt)
+ $(INSTALLSH) $(FULLCOQLIB) $(IDECMA:.cma=.cmxa) $(IDECMA:.cma=.a)
+endif
+
+install-ide-files: #Please update $(COQIDEAPP)/Contents/Resources/ at the same time
+ $(MKDIR) $(FULLDATADIR)
+ $(INSTALLLIB) ide/coq.png ide/*.lang ide/coq_style.xml $(FULLDATADIR)
+ $(MKDIR) $(FULLCONFIGDIR)
+ if [ $(IDEINT) = QUARTZ ] ; then $(INSTALLLIB) ide/mac_default_accel_map $(FULLCONFIGDIR)/coqide.keys ; fi
+
+install-ide-info:
+ $(MKDIR) $(FULLDOCDIR)
+ $(INSTALLLIB) ide/FAQ $(FULLDOCDIR)/FAQ-CoqIde
+
+###########################################################################
+# CoqIde MacOS special targets
+###########################################################################
+
+.PHONY: $(COQIDEAPP)/Contents
+
+$(COQIDEAPP)/Contents:
+ rm -rdf $@
+ $(MKDIR) $@
+ sed -e "s/VERSION/$(VERSION4MACOS)/g" ide/MacOS/Info.plist.template > $@/Info.plist
+ $(MKDIR) "$@/MacOS"
+
+$(COQIDEINAPP): ide/macos_prehook.cmx $(LINKIDEOPT) | $(COQIDEAPP)/Contents
+ $(SHOW)'OCAMLOPT -o $@'
+ $(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) -o $@ \
+ unix.cmxa lablgtk.cmxa lablgtksourceview2.cmxa str.cmxa \
+ threads.cmxa $(IDEFLAGS:.cma=.cmxa) $^
+ $(STRIP) $@
+
+$(COQIDEAPP)/Contents/Resources/share: $(COQIDEAPP)/Contents
+ $(MKDIR) $@/coq/
+ $(INSTALLLIB) ide/coq.png ide/*.lang ide/coq_style.xml $@/coq/
+ $(MKDIR) $@/gtksourceview-2.0/{language-specs,styles}
+ $(INSTALLLIB) "$(GTKSHARE)/"gtksourceview-2.0/language-specs/{def.lang,language2.rng} $@/gtksourceview-2.0/language-specs/
+ $(INSTALLLIB) "$(GTKSHARE)/"gtksourceview-2.0/styles/{styles.rng,classic.xml} $@/gtksourceview-2.0/styles/
+ cp -R "$(GTKSHARE)/"locale $@
+ cp -R "$(GTKSHARE)/"icons $@
+ cp -R "$(GTKSHARE)/"themes $@
+
+$(COQIDEAPP)/Contents/Resources/loaders: $(COQIDEAPP)/Contents
+ $(MKDIR) $@
+ $(INSTALLLIB) $$("$(GTKBIN)/gdk-pixbuf-query-loaders" | sed -n -e '5 s!.*= \(.*\)$$!\1!p')/libpixbufloader-png.so $@
+
+$(COQIDEAPP)/Contents/Resources/immodules: $(COQIDEAPP)/Contents
+ $(MKDIR) $@
+ $(INSTALLLIB) "$(GTKLIBS)/gtk-2.0/2.10.0/immodules/"*.so $@
+
+
+$(COQIDEAPP)/Contents/Resources/etc: $(COQIDEAPP)/Contents/Resources/lib
+ $(MKDIR) $@/xdg/coq
+ $(INSTALLLIB) ide/MacOS/default_accel_map $@/xdg/coq/coqide.keys
+ $(MKDIR) $@/gtk-2.0
+ { "$(GTKBIN)/gdk-pixbuf-query-loaders" $@/../loaders/*.so |\
+ sed -e "s!/.*\(/loaders/.*.so\)!@executable_path/../Resources/\1!"; } \
+ > $@/gtk-2.0/gdk-pixbuf.loaders
+ { "$(GTKBIN)/gtk-query-immodules-2.0" $@/../immodules/*.so |\
+ sed -e "s!/.*\(/immodules/.*.so\)!@executable_path/../Resources/\1!" |\
+ sed -e "s!/.*\(/share/locale\)!@executable_path/../Resources/\1!"; } \
+ > $@/gtk-2.0/gtk-immodules.loaders
+ $(MKDIR) $@/pango
+ echo "[Pango]" > $@/pango/pangorc
+
+$(COQIDEAPP)/Contents/Resources/lib: $(COQIDEAPP)/Contents/Resources/immodules $(COQIDEAPP)/Contents/Resources/loaders $(COQIDEAPP)/Contents $(COQIDEINAPP)
+ $(MKDIR) $@
+ $(INSTALLLIB) $(GTKLIBS)/charset.alias $@/
+ $(MKDIR) $@/pango/1.8.0/modules
+ $(INSTALLLIB) "$(GTKLIBS)/pango/1.8.0/modules/"*.so $@/pango/1.8.0/modules/
+ { "$(GTKBIN)/pango-querymodules" $@/pango/1.8.0/modules/*.so |\
+ sed -e "s!/.*\(/pango/1.8.0/modules/.*.so\)!@executable_path/../Resources/lib\1!"; } \
+ > $@/pango/1.8.0/modules.cache
+
+ for i in $$(otool -L $(COQIDEINAPP) |sed -n -e "\@$(GTKLIBS)@ s/[^/]*\(\/[^ ]*\) .*$$/\1/p"); \
+ do cp $$i $@/; \
+ ide/MacOS/relatify_with-respect-to_.sh $@/$$(basename $$i) $(GTKLIBS) $@; \
+ done
+ for i in $@/../loaders/*.so $@/../immodules/*.so $@/pango/1.8.0/modules/*.so; \
+ do \
+ for j in $$(otool -L $$i | sed -n -e "\@$(GTKLIBS)@ s/[^/]*\(\/[^ ]*\) .*$$/\1/p"); \
+ do cp $$j $@/; ide/MacOS/relatify_with-respect-to_.sh $@/$$(basename $$j) $(GTKLIBS) $@; done; \
+ ide/MacOS/relatify_with-respect-to_.sh $$i $(GTKLIBS) $@; \
+ done
+ EXTRAWORK=1; \
+ while [ $${EXTRAWORK} -eq 1 ]; \
+ do EXTRAWORK=0; \
+ for i in $@/*.dylib; \
+ do for j in $$(otool -L $$i | sed -n -e "\@$(GTKLIBS)@ s/[^/]*\(\/[^ ]*\) .*$$/\1/p"); \
+ do EXTRAWORK=1; cp $$j $@/; ide/MacOS/relatify_with-respect-to_.sh $@/$$(basename $$j) $(GTKLIBS) $@; done; \
+ done; \
+ done
+ ide/MacOS/relatify_with-respect-to_.sh $(COQIDEINAPP) $(GTKLIBS) $@
+
+$(COQIDEAPP)/Contents/Resources:$(COQIDEAPP)/Contents/Resources/etc $(COQIDEAPP)/Contents/Resources/share
+ $(INSTALLLIB) ide/MacOS/*.icns $@
+
+$(COQIDEAPP):$(COQIDEAPP)/Contents/Resources
+ $(CODESIGN) $@
+
+###########################################################################
+# CoqIde for Windows special targets
+###########################################################################
+
+%.o: %.rc
+ $(SHOW)'WINDRES $<'
+ $(HIDE)i686-w64-mingw32-windres -i $< -o $@
+
+
+# For emacs:
+# Local Variables:
+# mode: makefile
+# End:
diff --git a/Makefile.install b/Makefile.install
new file mode 100644
index 000000000..ed29bc1e7
--- /dev/null
+++ b/Makefile.install
@@ -0,0 +1,136 @@
+#######################################################################
+# v # The Coq Proof Assistant / The Coq Development Team #
+# <O___,, # INRIA-Rocquencourt & LRI-CNRS-Orsay #
+# \VV/ #############################################################
+# // # This file is distributed under the terms of the #
+# # GNU Lesser General Public License Version 2.1 #
+#######################################################################
+
+# This makefile regroups installation rules
+# It is included by Makefile.build
+
+ifeq ($(LOCAL),true)
+install:
+ @echo "Nothing to install in a local build!"
+else
+install: install-coq install-coqide install-doc-$(WITHDOC)
+endif
+
+install-doc-all: install-doc
+install-doc-no:
+
+.PHONY: install install-doc-all install-doc-no
+
+#These variables are intended to be set by the caller to make
+#COQINSTALLPREFIX=
+#OLDROOT=
+
+ # Can be changed for a local installation (to make packages).
+ # You must NOT put a "/" at the end (Cygnus for win32 does not like "//").
+
+ifdef COQINSTALLPREFIX
+FULLBINDIR=$(BINDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
+FULLCOQLIB=$(COQLIBINSTALL:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
+FULLCONFIGDIR=$(CONFIGDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
+FULLDATADIR=$(DATADIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
+FULLMANDIR=$(MANDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
+FULLEMACSLIB=$(EMACSLIB:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
+FULLCOQDOCDIR=$(COQDOCDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
+FULLDOCDIR=$(DOCDIR:"$(OLDROOT)%="$(COQINSTALLPREFIX)%)
+else
+FULLBINDIR=$(BINDIR)
+FULLCOQLIB=$(COQLIBINSTALL)
+FULLCONFIGDIR=$(CONFIGDIR)
+FULLDATADIR=$(DATADIR)
+FULLMANDIR=$(MANDIR)
+FULLEMACSLIB=$(EMACSLIB)
+FULLCOQDOCDIR=$(COQDOCDIR)
+FULLDOCDIR=$(DOCDIR)
+endif
+
+.PHONY: install-coq install-binaries install-byte install-opt
+.PHONY: install-tools install-library install-devfiles
+.PHONY: install-coq-info install-coq-manpages install-emacs install-latex
+
+install-coq: install-binaries install-library install-coq-info install-devfiles
+
+install-binaries: install-tools
+ $(MKDIR) $(FULLBINDIR)
+ $(INSTALLBIN) $(COQC) $(COQTOPBYTE) $(COQTOPEXE) $(CHICKEN) $(FULLBINDIR)
+ $(MKDIR) $(FULLCOQLIB)/toploop
+ $(INSTALLBIN) $(TOPLOOPCMA) $(FULLCOQLIB)/toploop/
+ifeq ($(BEST),opt)
+ $(INSTALLBIN) $(TOPLOOPCMA:.cma=.cmxs) $(FULLCOQLIB)/toploop/
+endif
+
+
+install-tools:
+ $(MKDIR) $(FULLBINDIR)
+ # recopie des fichiers de style pour coqide
+ $(MKDIR) $(FULLCOQLIB)/tools/coqdoc
+ touch $(FULLCOQLIB)/tools/coqdoc/coqdoc.sty $(FULLCOQLIB)/tools/coqdoc/coqdoc.css # to have the mode according to umask (bug #1715)
+ $(INSTALLLIB) tools/coqdoc/coqdoc.css tools/coqdoc/coqdoc.sty $(FULLCOQLIB)/tools/coqdoc
+ $(INSTALLBIN) $(TOOLS) $(FULLBINDIR)
+
+# The list of .cmi to install, including the ones obtained
+# from .mli without .ml, and the ones obtained from .ml without .mli
+
+INSTALLCMI = $(sort \
+ $(filter-out checker/% ide/% tools/%, $(MLIFILES:.mli=.cmi)) \
+ $(foreach lib,$(CORECMA) $(PLUGINSCMA), $(addsuffix .cmi,$($(lib:.cma=_MLLIB_DEPENDENCIES)))))
+
+install-devfiles:
+ $(MKDIR) $(FULLBINDIR)
+ $(INSTALLBIN) $(COQMKTOP) $(FULLBINDIR)
+ $(MKDIR) $(FULLCOQLIB)
+ $(INSTALLSH) $(FULLCOQLIB) $(LINKCMO) $(GRAMMARCMA)
+ $(INSTALLSH) $(FULLCOQLIB) $(INSTALLCMI)
+ifeq ($(BEST),opt)
+ $(INSTALLSH) $(FULLCOQLIB) $(LINKCMX) $(CORECMA:.cma=.a) $(STATICPLUGINS:.cma=.a)
+endif
+
+install-library:
+ $(MKDIR) $(FULLCOQLIB)
+ $(INSTALLSH) $(FULLCOQLIB) $(LIBFILES) $(PLUGINS)
+ $(MKDIR) $(FULLCOQLIB)/user-contrib
+ifndef CUSTOM
+ $(INSTALLLIB) $(DLLCOQRUN) $(FULLCOQLIB)
+endif
+ifeq ($(BEST),opt)
+ $(INSTALLLIB) $(LIBCOQRUN) $(FULLCOQLIB)
+ $(INSTALLSH) $(FULLCOQLIB) $(PLUGINSOPT)
+endif
+# csdpcert is not meant to be directly called by the user; we install
+# it with libraries
+ -$(MKDIR) $(FULLCOQLIB)/plugins/micromega
+ $(INSTALLBIN) $(CSDPCERT) $(FULLCOQLIB)/plugins/micromega
+ rm -f $(FULLCOQLIB)/revision
+ -$(INSTALLLIB) revision $(FULLCOQLIB)
+
+install-coq-info: install-coq-manpages install-emacs install-latex
+
+MANPAGES:=man/coq-tex.1 man/coqdep.1 man/gallina.1 \
+ man/coqc.1 man/coqtop.1 man/coqtop.byte.1 man/coqtop.opt.1 \
+ man/coqwc.1 man/coqdoc.1 man/coqide.1 \
+ man/coq_makefile.1 man/coqmktop.1 man/coqchk.1
+
+install-coq-manpages:
+ $(MKDIR) $(FULLMANDIR)/man1
+ $(INSTALLLIB) $(MANPAGES) $(FULLMANDIR)/man1
+
+install-emacs:
+ $(MKDIR) $(FULLEMACSLIB)
+ $(INSTALLLIB) tools/gallina-db.el tools/coq-font-lock.el tools/gallina-syntax.el tools/gallina.el tools/coq-inferior.el $(FULLEMACSLIB)
+
+# command to update TeX' kpathsea database
+#UPDATETEX = $(MKTEXLSR) /usr/share/texmf /var/spool/texmf $(BASETEXDIR) > /dev/null
+
+install-latex:
+ $(MKDIR) $(FULLCOQDOCDIR)
+ $(INSTALLLIB) tools/coqdoc/coqdoc.sty $(FULLCOQDOCDIR)
+# -$(UPDATETEX)
+
+# For emacs:
+# Local Variables:
+# mode: makefile
+# End:
diff --git a/README b/README
deleted file mode 100644
index 293ee4c8f..000000000
--- a/README
+++ /dev/null
@@ -1,66 +0,0 @@
-
- THE COQ V8 SYSTEM
- =================
-
-INSTALLATION.
-=============
-
- See the file INSTALL for installation procedure.
-
-
-DOCUMENTATION.
-==============
-
- The documentation is part of the archive in directory doc. The
- documentation of the last released version is available on the Coq
- web site at http://coq.inria.fr/doc.
-
-
-CHANGES.
-========
-
- There is a file named CHANGES that explains the differences and the
- incompatibilities since last versions. If you upgrade Coq, please read
- it carefully.
-
-
-AVAILABILITY.
-=============
-
- Coq is available from http://coq.inria.fr.
-
-
-THE COQ CLUB.
-=============
-
- The Coq Club moderated mailing list is meant to be a standard way
- to discuss questions about the Coq system and related topics. The
- subscription link can be found at http://coq.inria.fr/community.
-
- The topics to be discussed in the club should include:
-
- * technical problems;
-
- * questions about proof developments;
-
- * suggestions and questions about the implementation;
-
- * announcements of proofs;
-
- * theoretical questions about typed lambda-calculi which are
- closely related to Coq.
-
- For any questions/suggestions about the Coq Club, please write to
- coq-club-request@inria.fr.
-
-
-BUGS REPORT.
-============
-
- Send your bug reports by filling a form at
-
- http://coq.inria.fr/bugs
-
- To be effective, bug reports should mention the Caml version used
- to compile and run Coq, the Coq version (coqtop -v), the configuration
- used, and include a complete source example leading to the bug.
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..a41ee7cc0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,44 @@
+# Coq
+Coq is a formal proof management system. It provides a formal language to write
+mathematical definitions, executable algorithms and theorems together with an
+environment for semi-interactive development of machine-checked proofs.
+
+## Installation
+See the file `INSTALL` for installation procedure.
+
+## Documentation
+The documentation is part of the archive in directory doc. The
+documentation of the last released version is available on the Coq
+web site at [coq.inria.fr/doc](http://coq.inria.fr/doc).
+
+## Changes
+There is a file named `CHANGES` that explains the differences and the
+incompatibilities since last versions. If you upgrade Coq, please read
+it carefully.
+
+## Availability
+Coq is available from [coq.inria.fr](http://coq.inria.fr).
+
+## The Coq Club
+The Coq Club moderated mailing list is meant to be a standard way
+to discuss questions about the Coq system and related topics. The
+subscription link can be found at [coq.inria.fr/community](http://coq.inria.fr/community).
+
+The topics to be discussed in the club should include:
+
+* technical problems;
+* questions about proof developments;
+* suggestions and questions about the implementation;
+* announcements of proofs;
+* theoretical questions about typed lambda-calculi which are
+ closely related to Coq.
+
+For any questions/suggestions about the Coq Club, please write to
+`coq-club-request@inria.fr`.
+
+## Bugs report
+Send your bug reports by filling a form at [coq.inria.fr/bugs](http://coq.inria.fr/bugs).
+
+To be effective, bug reports should mention the OCaml version used
+to compile and run Coq, the Coq version (`coqtop -v`), the configuration
+used, and include a complete source example leading to the bug.
diff --git a/_tags b/_tags
deleted file mode 100644
index f805eeaa3..000000000
--- a/_tags
+++ /dev/null
@@ -1,76 +0,0 @@
-
-## tags for binaries
-
-<tools/coqmktop.{native,byte}> : use_str, use_unix
-<tools/coqc.{native,byte}> : use_str, use_unix
-<tools/coqdep_boot.{native,byte}> : use_unix
-<tools/coqdep.{native,byte}> : use_str, use_unix
-<tools/coq_tex.{native,byte}> : use_str
-<tools/coq_makefile.{native,byte}> : use_str, use_unix
-<tools/coqdoc/main.{native,byte}> : use_str
-<ide/coqide_main.{native,byte}> : use_str, use_unix, ide
-<checker/main.{native,byte}> : use_str, use_unix, thread
-<plugins/micromega/csdpcert.{native,byte}> : use_nums, use_unix
-<tools/mkwinapp.{native,byte}> : use_unix
-<tools/fake_ide.{native,byte}> : use_unix, use_str
-
-## tags for ide
-
-<ide/**/*.{ml,mli}>: ide
-
-## tags for grammar.cm*
-
-<grammar/grammar.{cma,cmxa}> : use_unix
-
-## tags for camlp4 files
-
-"parsing/g_constr.ml4": use_compat5
-"parsing/g_ltac.ml4": use_compat5
-"parsing/g_prim.ml4": use_compat5
-"parsing/g_proofs.ml4": use_compat5
-"parsing/g_tactic.ml4": use_compat5
-"parsing/g_vernac.ml4": use_compat5
-"parsing/g_xml.ml4": use_compat5
-"parsing/pcoq.ml4": use_compat5
-"parsing/g_obligations.ml4": use_grammar
-
-"grammar/argextend.ml4": use_compat5b
-"grammar/q_constr.ml4": use_compat5b
-"grammar/tacextend.ml4": use_compat5b
-"grammar/vernacextend.ml4": use_compat5b
-
-<tactics/*.ml4>: use_grammar
-"tactics/hipattern.ml4": use_constr
-
-<plugins/**/*.ml4>: use_grammar
-"plugins/decl_mode/g_decl_mode.ml4": use_compat5
-"plugins/funind/g_indfun.ml4": use_compat5
-
-## sub-directory inclusion
-
-# Note: "checker" is deliberately not included
-# Note: same for "config" (we create a special coq_config.ml)
-
-"parsing": include
-"ide": include
-"ide/utils": include
-"interp": include
-"intf": include
-"grammar": include
-"kernel": include
-"kernel/byterun": include
-"lib": include
-"library": include
-"parsing": include
-"plugins": include
-"engine": include
-"pretyping": include
-"printing": include
-"proofs": include
-"tactics": include
-"theories": include
-"tools": include
-"tools/coqdoc": include
-"toplevel": include
-
-<plugins/**>: include
diff --git a/build b/build
deleted file mode 100755
index debf29cf4..000000000
--- a/build
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-
-FLAGS="-j 2"
-OCAMLBUILD=ocamlbuild
-MYCFG=myocamlbuild_config.ml
-
-export CAML_LD_LIBRARY_PATH=`pwd`/_build/kernel/byterun
-
-check_config() {
- if [ ! -f $MYCFG ]; then echo "please run ./configure first"; exit 1; fi
-}
-
-ocb() { $OCAMLBUILD $FLAGS $*; }
-
-rule() {
- check_config
- case $1 in
- clean) ocb -clean && rm -rf bin/*;;
- all) ocb coq.otarget;;
- win32) ocb coq-win32.otarget;;
- *) ocb $1;;
- esac;
-}
-
-if [ $# -eq 0 ]; then
- rule all
-else
- while [ $# -gt 0 ]; do
- rule $1;
- shift
- done
-fi
diff --git a/checker/check.ml b/checker/check.ml
index 3a5c91217..da3cd0316 100644
--- a/checker/check.ml
+++ b/checker/check.ml
@@ -111,15 +111,14 @@ let check_one_lib admit (dir,m) =
also check if it carries a validation certificate (yet to
be implemented). *)
if LibrarySet.mem dir admit then
- (Flags.if_verbose ppnl
+ (Flags.if_verbose Feedback.msg_notice
(str "Admitting library: " ++ pr_dirpath dir);
Safe_typing.unsafe_import file md m.library_extra_univs dig)
else
- (Flags.if_verbose ppnl
+ (Flags.if_verbose Feedback.msg_notice
(str "Checking library: " ++ pr_dirpath dir);
Safe_typing.import file md m.library_extra_univs dig);
- Flags.if_verbose pp (fnl());
- pp_flush ();
+ Flags.if_verbose Feedback.msg_notice (fnl());
register_loaded_library m
(*************************************************************************)
@@ -173,7 +172,7 @@ let remove_load_path dir =
let add_load_path (phys_path,coq_path) =
if !Flags.debug then
- ppnl (str "path: " ++ pr_dirpath coq_path ++ str " ->" ++ spc() ++
+ Feedback.msg_notice (str "path: " ++ pr_dirpath coq_path ++ str " ->" ++ spc() ++
str phys_path);
let phys_path = canonical_path_name phys_path in
let physical, logical = !load_paths in
@@ -188,7 +187,7 @@ let add_load_path (phys_path,coq_path) =
begin
(* Assume the user is concerned by library naming *)
if dir <> default_root_prefix then
- msg_warning
+ Feedback.msg_warning
(str phys_path ++ strbrk " was previously bound to " ++
pr_dirpath dir ++ strbrk "; it is remapped to " ++
pr_dirpath coq_path);
@@ -299,12 +298,12 @@ let name_clash_message dir mdir f =
let depgraph = ref LibraryMap.empty
let intern_from_file (dir, f) =
- Flags.if_verbose pp (str"[intern "++str f++str" ..."); pp_flush ();
+ Flags.if_verbose Feedback.msg_notice(str"[intern "++str f++str" ...");
let (sd,md,table,opaque_csts,digest) =
try
let ch = System.with_magic_number_check raw_intern_library f in
let (sd:Cic.summary_disk), _, digest = System.marshal_in_segment f ch in
- let (md:Cic.library_disk), _, _ = System.marshal_in_segment f ch in
+ let (md:Cic.library_disk), _, digest = System.marshal_in_segment f ch in
let (opaque_csts:'a option), _, udg = System.marshal_in_segment f ch in
let (discharging:'a option), _, _ = System.marshal_in_segment f ch in
let (tasks:'a option), _, _ = System.marshal_in_segment f ch in
@@ -323,7 +322,7 @@ let intern_from_file (dir, f) =
errorlabstrm "intern_from_file"
(str "The file "++str f++str " contains unfinished tasks");
if opaque_csts <> None then begin
- pp (str " (was a vio file) ");
+ Feedback.msg_notice(str " (was a vio file) ");
Option.iter (fun (_,_,b) -> if not b then
errorlabstrm "intern_from_file"
(str "The file "++str f++str " is still a .vio"))
@@ -334,12 +333,12 @@ let intern_from_file (dir, f) =
Validate.validate !Flags.debug Values.v_libsum sd;
Validate.validate !Flags.debug Values.v_lib md;
Validate.validate !Flags.debug Values.v_opaques table;
- Flags.if_verbose ppnl (str" done]"); pp_flush ();
+ Flags.if_verbose Feedback.msg_notice (str" done]");
let digest =
if opaque_csts <> None then Cic.Dviovo (digest,udg)
else (Cic.Dvo digest) in
sd,md,table,opaque_csts,digest
- with e -> Flags.if_verbose ppnl (str" failed!]"); raise e in
+ with e -> Flags.if_verbose Feedback.msg_notice (str" failed!]"); raise e in
depgraph := LibraryMap.add sd.md_name sd.md_deps !depgraph;
opaque_tables := LibraryMap.add sd.md_name table !opaque_tables;
Option.iter (fun (opaque_csts,_,_) ->
@@ -407,11 +406,11 @@ let recheck_library ~norec ~admit ~check =
let nochk =
List.fold_right LibrarySet.remove (List.map fst (nrl@ml)) nochk in
(* *)
- Flags.if_verbose ppnl (fnl()++hv 2 (str "Ordered list:" ++ fnl() ++
+ Flags.if_verbose Feedback.msg_notice (fnl()++hv 2 (str "Ordered list:" ++ fnl() ++
prlist
(fun (dir,_) -> pr_dirpath dir ++ fnl()) needed));
List.iter (check_one_lib nochk) needed;
- Flags.if_verbose ppnl (str"Modules were successfully checked")
+ Flags.if_verbose Feedback.msg_notice (str"Modules were successfully checked")
open Printf
diff --git a/checker/check.mllib b/checker/check.mllib
index 3725989e8..2fa4d5797 100644
--- a/checker/check.mllib
+++ b/checker/check.mllib
@@ -22,21 +22,24 @@ CList
CString
Serialize
Stateid
-Feedback
-Pp
-Segmenttree
-Unicodetable
-Unicode
CObj
CArray
CStack
Util
+Pp
Ppstyle
+Xml_datatype
+Richpp
+Feedback
+Segmenttree
+Unicodetable
+Unicode
Errors
-Ephemeron
+CEphemeron
Future
CUnix
+Minisys
System
Profile
RemoteCounter
diff --git a/checker/check_stat.ml b/checker/check_stat.ml
index d031975d7..a26c93a30 100644
--- a/checker/check_stat.ml
+++ b/checker/check_stat.ml
@@ -28,7 +28,7 @@ let pr_engagement (impr_set,type_in_type) =
match impr_set with
| ImpredicativeSet -> str "Theory: Set is impredicative"
| PredicativeSet -> str "Theory: Set is predicative"
- end ++
+ end ++ fnl() ++
begin
match type_in_type with
| StratifiedType -> str "Theory: Stratified type hierarchy"
@@ -57,12 +57,13 @@ let print_context env =
env_modules=mods; env_modtypes=mtys};
env_stratification=
{env_universes=univ; env_engagement=engt}} = env in
- ppnl(hov 0
+ Feedback.msg_notice
+ (hov 0
(fnl() ++ str"CONTEXT SUMMARY" ++ fnl() ++
str"===============" ++ fnl() ++ fnl() ++
str "* " ++ hov 0 (pr_engagement engt ++ fnl()) ++ fnl() ++
str "* " ++ hov 0 (pr_ax csts) ++
- fnl())); pp_flush()
+ fnl()));
end
let stats () =
diff --git a/checker/checker.ml b/checker/checker.ml
index 91a207a60..9d76fb09e 100644
--- a/checker/checker.ml
+++ b/checker/checker.ml
@@ -17,7 +17,7 @@ open Check
let () = at_exit flush_all
let fatal_error info anomaly =
- flush_all (); pperrnl info; flush_all ();
+ flush_all (); Feedback.msg_error info; flush_all ();
exit (if anomaly then 129 else 1)
let coq_root = Id.of_string "Coq"
@@ -67,12 +67,12 @@ let add_path ~unix_path:dir ~coq_root:coq_dirpath =
Check.add_load_path (dir,coq_dirpath)
end
else
- msg_warning (str "Cannot open " ++ str dir)
+ Feedback.msg_warning (str "Cannot open " ++ str dir)
let convert_string d =
try Id.of_string d
with Errors.UserError _ ->
- if_verbose msg_warning
+ if_verbose Feedback.msg_warning
(str "Directory " ++ str d ++ str " cannot be used as a Coq identifier (skipped)");
raise Exit
@@ -90,7 +90,7 @@ let add_rec_path ~unix_path ~coq_root =
List.iter Check.add_load_path dirs;
Check.add_load_path (unix_path, coq_root)
else
- msg_warning (str "Cannot open " ++ str unix_path)
+ Feedback.msg_warning (str "Cannot open " ++ str unix_path)
(* By the option -include -I or -R of the command line *)
let includes = ref []
@@ -123,7 +123,7 @@ let init_load_path () =
add_rec_path ~unix_path:user_contrib ~coq_root:Check.default_root_prefix;
(* then directories in XDG_DATA_DIRS and XDG_DATA_HOME *)
List.iter (fun s -> add_rec_path ~unix_path:s ~coq_root:Check.default_root_prefix)
- (xdg_dirs ~warn:(fun x -> msg_warning (str x)));
+ (xdg_dirs ~warn:(fun x -> Feedback.msg_warning (str x)));
(* then directories in COQPATH *)
List.iter (fun s -> add_rec_path ~unix_path:s ~coq_root:Check.default_root_prefix) coqpath;
(* then current directory *)
@@ -179,10 +179,7 @@ let print_usage_channel co command =
output_string co command;
output_string co "coqchk options are:\n";
output_string co
-" -I dir -as coqdir map physical dir to logical coqdir\
-\n -I dir map directory dir to the empty logical path\
-\n -include dir (idem)\
-\n -R dir coqdir recursively map physical dir to logical coqdir\
+" -R dir coqdir map physical dir to logical coqdir\
\n\
\n -admit module load module and dependencies without checking\
\n -norec module check module but admit dependencies without checking\
@@ -288,7 +285,7 @@ let rec explain_exn = function
Format.printf "@\nis not convertible with@\n";
Print.print_pure_constr a;
Format.printf "@\n====== universes ====@\n";
- Pp.pp (Univ.pr_universes
+ Feedback.msg_notice (Univ.pr_universes
(ctx.Environ.env_stratification.Environ.env_universes));
str "\nCantApplyBadType at argument " ++ int n
| CantApplyNonFunctional _ -> str"CantApplyNonFunctional"
diff --git a/checker/closure.ml b/checker/closure.ml
index c2708e97d..cef1d31a6 100644
--- a/checker/closure.ml
+++ b/checker/closure.ml
@@ -29,7 +29,7 @@ let reset () =
beta := 0; delta := 0; zeta := 0; evar := 0; iota := 0; prune := 0
let stop() =
- msg_debug (str "[Reds: beta=" ++ int !beta ++ str" delta=" ++ int !delta ++
+ Feedback.msg_debug (str "[Reds: beta=" ++ int !beta ++ str" delta=" ++ int !delta ++
str" zeta=" ++ int !zeta ++ str" evar=" ++ int !evar ++
str" iota=" ++ int !iota ++ str" prune=" ++ int !prune ++ str"]")
diff --git a/checker/declarations.ml b/checker/declarations.ml
index 3ce312533..1fe02c8b6 100644
--- a/checker/declarations.ml
+++ b/checker/declarations.ml
@@ -73,32 +73,32 @@ let solve_delta_kn resolve kn =
| Equiv kn1 -> kn1
| Inline _ -> raise Not_found
with Not_found ->
- let mp,dir,l = repr_kn kn in
+ let mp,dir,l = KerName.repr kn in
let new_mp = find_prefix resolve mp in
if mp == new_mp then
kn
else
- make_kn new_mp dir l
+ KerName.make new_mp dir l
let gen_of_delta resolve x kn fix_can =
let new_kn = solve_delta_kn resolve kn in
if kn == new_kn then x else fix_can new_kn
let constant_of_delta resolve con =
- let kn = user_con con in
- gen_of_delta resolve con kn (constant_of_kn_equiv kn)
+ let kn = Constant.user con in
+ gen_of_delta resolve con kn (Constant.make kn)
let constant_of_delta2 resolve con =
- let kn, kn' = canonical_con con, user_con con in
- gen_of_delta resolve con kn (constant_of_kn_equiv kn')
+ let kn, kn' = Constant.canonical con, Constant.user con in
+ gen_of_delta resolve con kn (Constant.make kn')
let mind_of_delta resolve mind =
- let kn = user_mind mind in
- gen_of_delta resolve mind kn (mind_of_kn_equiv kn)
+ let kn = MutInd.user mind in
+ gen_of_delta resolve mind kn (MutInd.make kn)
let mind_of_delta2 resolve mind =
- let kn, kn' = canonical_mind mind, user_mind mind in
- gen_of_delta resolve mind kn (mind_of_kn_equiv kn')
+ let kn, kn' = MutInd.canonical mind, MutInd.user mind in
+ gen_of_delta resolve mind kn (MutInd.make kn')
let find_inline_of_delta kn resolve =
match Deltamap.find_kn kn resolve with
@@ -106,7 +106,7 @@ let find_inline_of_delta kn resolve =
| _ -> raise Not_found
let constant_of_delta_with_inline resolve con =
- let kn1,kn2 = canonical_con con,user_con con in
+ let kn1,kn2 = Constant.canonical con, Constant.user con in
try find_inline_of_delta kn2 resolve
with Not_found ->
try find_inline_of_delta kn1 resolve
@@ -137,17 +137,17 @@ let subst_mp sub mp =
| Some (mp',_) -> mp'
let subst_kn_delta sub kn =
- let mp,dir,l = repr_kn kn in
+ let mp,dir,l = KerName.repr kn in
match subst_mp0 sub mp with
Some (mp',resolve) ->
- solve_delta_kn resolve (make_kn mp' dir l)
+ solve_delta_kn resolve (KerName.make mp' dir l)
| None -> kn
let subst_kn sub kn =
- let mp,dir,l = repr_kn kn in
+ let mp,dir,l = KerName.repr kn in
match subst_mp0 sub mp with
Some (mp',_) ->
- make_kn mp' dir l
+ KerName.make mp' dir l
| None -> kn
exception No_subst
@@ -165,14 +165,14 @@ let gen_subst_mp f sub mp1 mp2 =
| Some (mp1',_), Some (mp2',resolve2) -> Canonical, (f mp1' mp2'), resolve2
let make_mind_equiv mpu mpc dir l =
- let knu = make_kn mpu dir l in
- if mpu == mpc then mind_of_kn knu
- else mind_of_kn_equiv knu (make_kn mpc dir l)
+ let knu = KerName.make mpu dir l in
+ if mpu == mpc then MutInd.make1 knu
+ else MutInd.make knu (KerName.make mpc dir l)
let subst_ind sub mind =
- let kn1,kn2 = user_mind mind, canonical_mind mind in
- let mp1,dir,l = repr_kn kn1 in
- let mp2,_,_ = repr_kn kn2 in
+ let kn1,kn2 = MutInd.user mind, MutInd.canonical mind in
+ let mp1,dir,l = KerName.repr kn1 in
+ let mp2,_,_ = KerName.repr kn2 in
let rebuild_mind mp1 mp2 = make_mind_equiv mp1 mp2 dir l in
try
let side,mind',resolve = gen_subst_mp rebuild_mind sub mp1 mp2 in
@@ -182,14 +182,14 @@ let subst_ind sub mind =
with No_subst -> mind
let make_con_equiv mpu mpc dir l =
- let knu = make_kn mpu dir l in
- if mpu == mpc then constant_of_kn knu
- else constant_of_kn_equiv knu (make_kn mpc dir l)
+ let knu = KerName.make mpu dir l in
+ if mpu == mpc then Constant.make1 knu
+ else Constant.make knu (KerName.make mpc dir l)
let subst_con0 sub con u =
- let kn1,kn2 = user_con con,canonical_con con in
- let mp1,dir,l = repr_kn kn1 in
- let mp2,_,_ = repr_kn kn2 in
+ let kn1,kn2 = Constant.user con, Constant.canonical con in
+ let mp1,dir,l = KerName.repr kn1 in
+ let mp2,_,_ = KerName.repr kn2 in
let rebuild_con mp1 mp2 = make_con_equiv mp1 mp2 dir l in
let dup con = con, Const (con, u) in
let side,con',resolve = gen_subst_mp rebuild_con sub mp1 mp2 in
@@ -304,7 +304,9 @@ let subset_prefixed_by mp resolver =
match hint with
| Inline _ -> rslv
| Equiv _ ->
- if mp_in_mp mp (modpath kn) then Deltamap.add_kn kn hint rslv else rslv
+ if mp_in_mp mp (KerName.modpath kn)
+ then Deltamap.add_kn kn hint rslv
+ else rslv
in
Deltamap.fold mp_prefix kn_prefix resolver empty_delta_resolver
diff --git a/checker/environ.ml b/checker/environ.ml
index 7040fdda4..9352f71ef 100644
--- a/checker/environ.ml
+++ b/checker/environ.ml
@@ -112,7 +112,7 @@ let anomaly s = anomaly (Pp.str s)
let add_constant kn cs env =
if Cmap_env.mem kn env.env_globals.env_constants then
Printf.ksprintf anomaly ("Constant %s is already defined")
- (string_of_con kn);
+ (Constant.to_string kn);
let new_constants =
Cmap_env.add kn cs env.env_globals.env_constants in
let new_globals =
@@ -172,12 +172,14 @@ let lookup_projection p env =
let scrape_mind env kn=
try
KNmap.find kn env.env_globals.env_inductives_eq
- with
- Not_found -> kn
+ with
+ Not_found -> kn
let mind_equiv env (kn1,i1) (kn2,i2) =
Int.equal i1 i2 &&
- KerName.equal (scrape_mind env (user_mind kn1)) (scrape_mind env (user_mind kn2))
+ KerName.equal
+ (scrape_mind env (MutInd.user kn1))
+ (scrape_mind env (MutInd.user kn2))
let lookup_mind kn env =
@@ -186,9 +188,9 @@ let lookup_mind kn env =
let add_mind kn mib env =
if Mindmap_env.mem kn env.env_globals.env_inductives then
Printf.ksprintf anomaly ("Inductive %s is already defined")
- (string_of_mind kn);
+ (MutInd.to_string kn);
let new_inds = Mindmap_env.add kn mib env.env_globals.env_inductives in
- let kn1,kn2 = user_mind kn,canonical_mind kn in
+ let kn1,kn2 = MutInd.user kn, MutInd.canonical kn in
let new_inds_eq = if KerName.equal kn1 kn2 then
env.env_globals.env_inductives_eq
else
@@ -205,7 +207,7 @@ let add_mind kn mib env =
let add_modtype ln mtb env =
if MPmap.mem ln env.env_globals.env_modtypes then
Printf.ksprintf anomaly ("Module type %s is already defined")
- (string_of_mp ln);
+ (ModPath.to_string ln);
let new_modtypes = MPmap.add ln mtb env.env_globals.env_modtypes in
let new_globals =
{ env.env_globals with
@@ -215,7 +217,7 @@ let add_modtype ln mtb env =
let shallow_add_module mp mb env =
if MPmap.mem mp env.env_globals.env_modules then
Printf.ksprintf anomaly ("Module %s is already defined")
- (string_of_mp mp);
+ (ModPath.to_string mp);
let new_mods = MPmap.add mp mb env.env_globals.env_modules in
let new_globals =
{ env.env_globals with
@@ -225,7 +227,7 @@ let shallow_add_module mp mb env =
let shallow_remove_module mp env =
if not (MPmap.mem mp env.env_globals.env_modules) then
Printf.ksprintf anomaly ("Module %s is unknown")
- (string_of_mp mp);
+ (ModPath.to_string mp);
let new_mods = MPmap.remove mp env.env_globals.env_modules in
let new_globals =
{ env.env_globals with
diff --git a/checker/indtypes.ml b/checker/indtypes.ml
index 566df673c..a667bb8a3 100644
--- a/checker/indtypes.ml
+++ b/checker/indtypes.ml
@@ -32,11 +32,11 @@ let string_of_mp mp =
if !Flags.debug then debug_string_of_mp mp else string_of_mp mp
let prkn kn =
- let (mp,_,l) = repr_kn kn in
+ let (mp,_,l) = KerName.repr kn in
str(string_of_mp mp ^ "." ^ Label.to_string l)
let prcon c =
- let ck = canonical_con c in
- let uk = user_con c in
+ let ck = Constant.canonical c in
+ let uk = Constant.user c in
if KerName.equal ck uk then prkn uk else (prkn uk ++str"(="++prkn ck++str")")
(* Same as noccur_between but may perform reductions.
@@ -528,7 +528,7 @@ let check_positivity env_ar mind params nrecp inds =
(************************************************************************)
let check_inductive env kn mib =
- Flags.if_verbose ppnl (str " checking ind: " ++ pr_mind kn); pp_flush ();
+ Flags.if_verbose Feedback.msg_notice (str " checking ind: " ++ MutInd.print kn);
(* check mind_constraints: should be consistent with env *)
let env = add_constraints (Univ.UContext.constraints mib.mind_universes) env in
(* check mind_record : TODO ? check #constructor = 1 ? *)
diff --git a/checker/inductive.ml b/checker/inductive.ml
index 5e2e14f7f..43a32ea24 100644
--- a/checker/inductive.ml
+++ b/checker/inductive.ml
@@ -527,7 +527,7 @@ type guard_env =
let make_renv env recarg tree =
{ env = env;
rel_min = recarg+2; (* recarg = 0 ==> Rel 1 -> recarg; Rel 2 -> fix *)
- genv = [Lazy.lazy_from_val(Subterm(Large,tree))] }
+ genv = [Lazy.from_val(Subterm(Large,tree))] }
let push_var renv (x,ty,spec) =
{ env = push_rel (LocalAssum (x,ty)) renv.env;
@@ -538,7 +538,7 @@ let assign_var_spec renv (i,spec) =
{ renv with genv = List.assign renv.genv (i-1) spec }
let push_var_renv renv (x,ty) =
- push_var renv (x,ty,Lazy.lazy_from_val Not_subterm)
+ push_var renv (x,ty,Lazy.from_val Not_subterm)
(* Fetch recursive information about a variable p *)
let subterm_var p renv =
@@ -549,13 +549,13 @@ let push_ctxt_renv renv ctxt =
let n = rel_context_length ctxt in
{ env = push_rel_context ctxt renv.env;
rel_min = renv.rel_min+n;
- genv = iterate (fun ge -> Lazy.lazy_from_val Not_subterm::ge) n renv.genv }
+ genv = iterate (fun ge -> Lazy.from_val Not_subterm::ge) n renv.genv }
let push_fix_renv renv (_,v,_ as recdef) =
let n = Array.length v in
{ env = push_rec_types recdef renv.env;
rel_min = renv.rel_min+n;
- genv = iterate (fun ge -> Lazy.lazy_from_val Not_subterm::ge) n renv.genv }
+ genv = iterate (fun ge -> Lazy.from_val Not_subterm::ge) n renv.genv }
(* Definition and manipulation of the stack *)
@@ -862,7 +862,7 @@ and stack_element_specif = function
|SArg x -> x
and extract_stack renv a = function
- | [] -> Lazy.lazy_from_val Not_subterm , []
+ | [] -> Lazy.from_val Not_subterm , []
| h::t -> stack_element_specif h, t
diff --git a/checker/mod_checking.ml b/checker/mod_checking.ml
index 3ea5ed0d3..7f93e1560 100644
--- a/checker/mod_checking.ml
+++ b/checker/mod_checking.ml
@@ -18,7 +18,7 @@ let refresh_arity ar =
let ctxt, hd = decompose_prod_assum ar in
match hd with
Sort (Type u) when not (Univ.is_univ_variable u) ->
- let ul = Univ.Level.make empty_dirpath 1 in
+ let ul = Univ.Level.make DirPath.empty 1 in
let u' = Univ.Universe.make ul in
let cst = Univ.enforce_leq u u' Univ.empty_constraint in
let ctx = Univ.ContextSet.make (Univ.LSet.singleton ul) cst in
@@ -26,7 +26,7 @@ let refresh_arity ar =
| _ -> ar, Univ.ContextSet.empty
let check_constant_declaration env kn cb =
- Flags.if_verbose ppnl (str " checking cst: " ++ prcon kn); pp_flush ();
+ Flags.if_verbose Feedback.msg_notice (str " checking cst: " ++ prcon kn);
let env' =
if cb.const_polymorphic then
let inst = Univ.make_abstract_instance cb.const_universes in
@@ -70,7 +70,7 @@ let check_constant_declaration env kn cb =
let lookup_module mp env =
try Environ.lookup_module mp env
with Not_found ->
- failwith ("Unknown module: "^string_of_mp mp)
+ failwith ("Unknown module: "^ModPath.to_string mp)
let mk_mtb mp sign delta =
{ mod_mp = mp;
diff --git a/checker/modops.ml b/checker/modops.ml
index 9f4375262..442f999bb 100644
--- a/checker/modops.ml
+++ b/checker/modops.ml
@@ -28,7 +28,7 @@ let error_not_match l _ =
let error_no_such_label l = error ("No such label "^Label.to_string l)
let error_no_such_label_sub l l1 =
- let l1 = string_of_mp l1 in
+ let l1 = ModPath.to_string l1 in
error ("The field "^
Label.to_string l^" is missing in "^l1^".")
diff --git a/checker/print.ml b/checker/print.ml
index 9cd8fda5d..c0d1ac368 100644
--- a/checker/print.ml
+++ b/checker/print.ml
@@ -10,7 +10,7 @@ open Format
open Cic
open Names
-let print_instance i = Pp.pp (Univ.Instance.pr i)
+let print_instance i = Feedback.msg_notice (Univ.Instance.pr i)
let print_pure_constr csr =
let rec term_display c = match c with
@@ -108,7 +108,7 @@ let print_pure_constr csr =
and sort_display = function
| Prop(Pos) -> print_string "Set"
| Prop(Null) -> print_string "Prop"
- | Type u -> print_string "Type("; Pp.pp (Univ.pr_uni u); print_string ")"
+ | Type u -> print_string "Type("; Feedback.msg_notice (Univ.pr_uni u); print_string ")"
and name_display = function
| Name id -> print_string (Id.to_string id)
@@ -122,7 +122,7 @@ let print_pure_constr csr =
| ("Coq"::_::l) -> l
| l -> l
in List.iter (fun x -> print_string x; print_string ".") ls;*)
- print_string (debug_string_of_mind sp)
+ print_string (MutInd.debug_to_string sp)
and sp_con_display sp =
(* let dir,l = decode_kn sp in
let ls =
@@ -131,7 +131,7 @@ let print_pure_constr csr =
| ("Coq"::_::l) -> l
| l -> l
in List.iter (fun x -> print_string x; print_string ".") ls;*)
- print_string (debug_string_of_con sp)
+ print_string (Constant.debug_to_string sp)
in
try
diff --git a/checker/safe_typing.ml b/checker/safe_typing.ml
index 7f9ed92f9..1071e2f93 100644
--- a/checker/safe_typing.ml
+++ b/checker/safe_typing.ml
@@ -81,7 +81,7 @@ let stamp_library file digest = ()
warning is issued in case of mismatch *)
let import file clib univs digest =
let env = !genv in
- check_imports msg_warning clib.comp_name env clib.comp_deps;
+ check_imports Feedback.msg_warning clib.comp_name env clib.comp_deps;
check_engagement env clib.comp_enga;
let mb = clib.comp_mod in
Mod_checking.check_module
@@ -93,7 +93,7 @@ let import file clib univs digest =
(* When the module is admitted, digests *must* match *)
let unsafe_import file clib univs digest =
let env = !genv in
- if !Flags.debug then check_imports msg_warning clib.comp_name env clib.comp_deps
+ if !Flags.debug then check_imports Feedback.msg_warning clib.comp_name env clib.comp_deps
else check_imports (errorlabstrm"unsafe_import") clib.comp_name env clib.comp_deps;
check_engagement env clib.comp_enga;
full_add_module clib.comp_name clib.comp_mod univs digest
diff --git a/checker/subtyping.ml b/checker/subtyping.ml
index e41922573..46d21f6cc 100644
--- a/checker/subtyping.ml
+++ b/checker/subtyping.ml
@@ -103,7 +103,7 @@ let check_inductive env mp1 l info1 mib2 spec2 subst1 subst2=
in
let eq_projection_body p1 p2 =
let check eq f = if not (eq (f p1) (f p2)) then error () in
- check eq_mind (fun x -> x.proj_ind);
+ check MutInd.equal (fun x -> x.proj_ind);
check (==) (fun x -> x.proj_npars);
check (==) (fun x -> x.proj_arg);
check (eq_constr) (fun x -> x.proj_type);
diff --git a/checker/typeops.ml b/checker/typeops.ml
index 64afd21b2..da9842a8d 100644
--- a/checker/typeops.ml
+++ b/checker/typeops.ml
@@ -92,7 +92,7 @@ let judge_of_constant_knowing_parameters env (kn,u as cst) paramstyp =
let _cb =
try lookup_constant kn env
with Not_found ->
- failwith ("Cannot find constant: "^string_of_con kn)
+ failwith ("Cannot find constant: "^Constant.to_string kn)
in
let ty, cu = type_of_constant_knowing_parameters env cst paramstyp in
let () = check_constraints cu env in
@@ -178,7 +178,7 @@ let judge_of_inductive_knowing_parameters env (ind,u) (paramstyp:constr array) =
let specif =
try lookup_mind_specif env ind
with Not_found ->
- failwith ("Cannot find inductive: "^string_of_mind (fst ind))
+ failwith ("Cannot find inductive: "^MutInd.to_string (fst ind))
in
type_of_inductive_knowing_parameters env (specif,u) paramstyp
@@ -192,7 +192,7 @@ let judge_of_constructor env (c,u) =
let specif =
try lookup_mind_specif env ind
with Not_found ->
- failwith ("Cannot find inductive: "^string_of_mind (fst ind))
+ failwith ("Cannot find inductive: "^MutInd.to_string (fst ind))
in
type_of_constructor (c,u) specif
@@ -223,7 +223,7 @@ let judge_of_projection env p c ct =
try find_rectype env ct
with Not_found -> error_case_not_inductive env (c, ct)
in
- assert(eq_mind pb.proj_ind (fst ind));
+ assert(MutInd.equal pb.proj_ind (fst ind));
let ty = subst_instance_constr u pb.proj_type in
substl (c :: List.rev args) ty
diff --git a/checker/univ.ml b/checker/univ.ml
index cb2eaced7..96d827013 100644
--- a/checker/univ.ml
+++ b/checker/univ.ml
@@ -33,7 +33,7 @@ module type Hashconsed =
sig
type t
val hash : t -> int
- val equal : t -> t -> bool
+ val eq : t -> t -> bool
val hcons : t -> t
end
@@ -51,7 +51,7 @@ struct
type t = _t
type u = (M.t -> M.t)
let hash = function Nil -> 0 | Cons (_, h, _) -> h
- let equal l1 l2 = match l1, l2 with
+ let eq l1 l2 = match l1, l2 with
| Nil, Nil -> true
| Cons (x1, _, l1), Cons (x2, _, l2) -> x1 == x2 && l1 == l2
| _ -> false
@@ -131,7 +131,7 @@ module HList = struct
let rec remove x = function
| Nil -> nil
| Cons (y, _, l) ->
- if H.equal x y then l
+ if H.eq x y then l
else cons y (remove x l)
end
@@ -229,7 +229,7 @@ module Level = struct
type _t = t
type t = _t
type u = unit
- let equal x y = x.hash == y.hash && RawLevel.hequal x.data y.data
+ let eq x y = x.hash == y.hash && RawLevel.hequal x.data y.data
let hash x = x.hash
let hashcons () x =
let data' = RawLevel.hcons x.data in
@@ -320,7 +320,7 @@ struct
let hashcons hdir (b,n as x) =
let b' = hdir b in
if b' == b then x else (b',n)
- let equal l1 l2 =
+ let eq l1 l2 =
l1 == l2 ||
match l1,l2 with
| (b,n), (b',n') -> b == b' && n == n'
@@ -339,7 +339,7 @@ struct
let hcons =
Hashcons.simple_hcons H.generate H.hcons Level.hcons
let hash = ExprHash.hash
- let equal x y = x == y ||
+ let eq x y = x == y ||
(let (u,n) = x and (v,n') = y in
Int.equal n n' && Level.equal u v)
@@ -1089,7 +1089,7 @@ struct
a
end
- let equal t1 t2 =
+ let eq t1 t2 =
t1 == t2 ||
(Int.equal (Array.length t1) (Array.length t2) &&
let rec aux i =
diff --git a/checker/votour.ml b/checker/votour.ml
index 79755da4a..48f9f45e7 100644
--- a/checker/votour.ml
+++ b/checker/votour.ml
@@ -10,6 +10,26 @@ open Values
(** {6 Interactive visit of a vo} *)
+let rec read_num max =
+ let quit () =
+ Printf.printf "\nGoodbye!\n%!";
+ exit 0 in
+ Printf.printf "# %!";
+ let l = try read_line () with End_of_file -> quit () in
+ if l = "u" then None
+ else if l = "x" then quit ()
+ else
+ try
+ let v = int_of_string l in
+ if v < 0 || v >= max then
+ let () =
+ Printf.printf "Out-of-range input! (only %d children)\n%!" max in
+ read_num max
+ else Some v
+ with Failure "int_of_string" ->
+ Printf.printf "Unrecognized input! <n> enters the <n>-th child, u goes up 1 level, x exits\n%!";
+ read_num max
+
type 'a repr =
| INT of int
| STRING of string
@@ -255,15 +275,13 @@ let rec visit v o pos =
(fun i vop -> Printf.printf " %d: %s\n" i (node_info vop))
children;
Printf.printf "-------------\n";
- Printf.printf ("# %!");
- let l = read_line () in
try
- if l = "u" then let info = pop () in visit info.typ info.obj info.pos
- else if l = "x" then (Printf.printf "\nGoodbye!\n\n";exit 0)
- else
- let v',o',pos' = children.(int_of_string l) in
- push (get_name v) v o pos;
- visit v' o' pos'
+ match read_num (Array.length children) with
+ | None -> let info = pop () in visit info.typ info.obj info.pos
+ | Some child ->
+ let v',o',pos' = children.(child) in
+ push (get_name v) v o pos;
+ visit v' o' pos'
with
| Failure "empty stack" -> ()
| Failure "forbidden" -> let info = pop () in visit info.typ info.obj info.pos
@@ -350,13 +368,13 @@ let visit_vo f =
let size = if Sys.word_size = 64 then header.size64 else header.size32 in
Printf.printf " %d: %s, starting at byte %d (size %iw)\n" i name pos size)
segments;
- Printf.printf "# %!";
- let l = read_line () in
- let seg = int_of_string l in
- seek_in ch segments.(seg).pos;
- let o = Repr.input ch in
- let () = Visit.init () in
- Visit.visit segments.(seg).typ o []
+ match read_num (Array.length segments) with
+ | Some seg ->
+ seek_in ch segments.(seg).pos;
+ let o = Repr.input ch in
+ let () = Visit.init () in
+ Visit.visit segments.(seg).typ o []
+ | None -> ()
done
let main =
diff --git a/configure.ml b/configure.ml
index b8bb650b1..71502058f 100644
--- a/configure.ml
+++ b/configure.ml
@@ -251,7 +251,6 @@ module Prefs = struct
let debug = ref false
let profile = ref false
let annotate = ref false
- let makecmd = ref "make"
let nativecompiler = ref (not (os_type_win32 || os_type_cygwin))
let coqwebsite = ref "http://coq.inria.fr/"
let force_caml_version = ref false
@@ -329,14 +328,14 @@ let args_options = Arg.align [
" Add profiling information in the Coq executables";
"-annotate", Arg.Set Prefs.annotate,
" Dumps ml annotation files while compiling Coq";
- "-makecmd", Arg.Set_string Prefs.makecmd,
- "<command> Name of GNU Make command";
+ "-makecmd", Arg.String (fun _ -> printf "Warning: obsolete -makecmd option\n"),
+ "<command> Obsolete: name of GNU Make command";
"-native-compiler", arg_bool Prefs.nativecompiler,
"(yes|no) Compilation to native code for conversion and normalization";
"-coqwebsite", Arg.Set_string Prefs.coqwebsite,
" URL of the coq website";
"-force-caml-version", Arg.Set Prefs.force_caml_version,
- "Force OCaml version";
+ " Force OCaml version";
]
let parse_args () =
@@ -423,18 +422,6 @@ let vcs =
else if dir_exists "{arch}" then "gnuarch"
else "none"
-(** * The make command *)
-
-let make =
- try
- let version_line, _ = run !Prefs.makecmd ["-v"] in
- let version = List.nth (string_split ' ' version_line) 2 in
- match string_split '.' version with
- | major::minor::_ when (s2i major, s2i minor) >= (3,81) ->
- printf "You have GNU Make %s. Good!\n" version
- | _ -> failwith "bad version"
- with _ -> die "Error: Cannot find GNU Make >= 3.81."
-
(** * Browser command *)
let browser =
@@ -487,7 +474,7 @@ let caml_version_nums =
"Is it installed properly?")
let check_caml_version () =
- if caml_version_nums >= [3;12;1] then
+ if caml_version_nums >= [4;1;0] then
if caml_version_nums = [4;2;0] && not !Prefs.force_caml_version then
die ("Your version of OCaml is 4.02.0 which suffers from a bug inducing\n" ^
"very slow compilation times. If you still want to use it, use \n" ^
@@ -499,7 +486,7 @@ let check_caml_version () =
if !Prefs.force_caml_version then
printf "*Warning* Your version of OCaml is outdated.\n"
else
- die "You need OCaml 3.12.1 or later."
+ die "You need OCaml 4.01 or later."
let _ = check_caml_version ()
@@ -526,51 +513,47 @@ exception NoCamlp5
let check_camlp5 testcma = match !Prefs.camlp5dir with
| Some dir ->
- if Sys.file_exists (dir/testcma) then dir
+ if Sys.file_exists (dir/testcma) then
+ let camlp5o =
+ try which_camlpX "camlp5o"
+ with Not_found -> die "Error: cannot find Camlp5 binaries in path.\n" in
+ dir, camlp5o
else
let msg =
sprintf "Cannot find camlp5 libraries in '%s' (%s not found)."
dir testcma
in die msg
| None ->
- let dir,_ = tryrun "camlp5" ["-where"] in
- let dir2 =
- if Sys.file_exists (camllib/"camlp5"/testcma) then
- camllib/"camlp5"
- else if Sys.file_exists (camllib/"site-lib"/"camlp5"/testcma) then
- camllib/"site-lib"/"camlp5"
- else ""
- in
- (* if the two values are different then camlp5 has been relocated
- * and will not be able to find its own files, so we prefer the
- * path where the files actually do exist *)
- if dir2 = "" then
- if dir = "" then
- let () = printf "No Camlp5 installation found." in
- let () = printf "Looking for Camlp4 instead...\n" in
- raise NoCamlp5
- else dir
- else dir2
-
-let check_camlp5_version () =
- try
- let camlp5o = which_camlpX "camlp5o" in
- let version_line, _ = run ~err:StdOut camlp5o ["-v"] in
- let version = List.nth (string_split ' ' version_line) 2 in
- match string_split '.' version with
- | major::minor::_ when s2i major > 5 || (s2i major, s2i minor) >= (5,1) ->
- printf "You have Camlp5 %s. Good!\n" version; camlp5o, version
- | _ -> failwith "bad version"
- with
- | Not_found -> die "Error: cannot find Camlp5 binaries in path.\n"
+ try
+ let camlp5o = which_camlpX "camlp5o" in
+ let dir,_ = tryrun camlp5o ["-where"] in
+ dir, camlp5o
+ with Not_found ->
+ let () = printf "No Camlp5 installation found." in
+ let () = printf "Looking for Camlp4 instead...\n" in
+ raise NoCamlp5
+
+let check_camlp5_version camlp5o =
+ let version_line, _ = run ~err:StdOut camlp5o ["-v"] in
+ let version = List.nth (string_split ' ' version_line) 2 in
+ match string_split '.' version with
+ | major::minor::_ when s2i major > 5 || (s2i major, s2i minor) >= (5,1) ->
+ printf "You have Camlp5 %s. Good!\n" version; version
| _ -> die "Error: unsupported Camlp5 (version < 5.01 or unrecognized).\n"
+let check_caml_version_for_camlp4 () =
+ if caml_version_nums = [4;1;0] && !Prefs.debug && not !Prefs.force_caml_version then
+ die ("Your version of OCaml is detected to be 4.01.0 which fails to compile\n" ^
+ "Coq in -debug mode with Camlp4. Remove -debug option or use a different\n" ^
+ "version of OCaml or use Camlp5, or bypass this test by using option\n" ^
+ "-force-caml-version.\n")
+
let config_camlpX () =
try
if not !Prefs.usecamlp5 then raise NoCamlp5;
let camlp5mod = "gramlib" in
- let camlp5libdir = check_camlp5 (camlp5mod^".cma") in
- let camlp5o, camlp5_version = check_camlp5_version () in
+ let camlp5libdir, camlp5o = check_camlp5 (camlp5mod^".cma") in
+ let camlp5_version = check_camlp5_version camlp5o in
"camlp5", camlp5o, Filename.dirname camlp5o, camlp5libdir, camlp5mod, camlp5_version
with NoCamlp5 ->
(* We now try to use Camlp4, either by explicit choice or
@@ -583,6 +566,7 @@ let config_camlpX () =
let camlp4orf = which_camlpX "camlp4orf" in
let version_line, _ = run ~err:StdOut camlp4orf ["-v"] in
let camlp4_version = List.nth (string_split ' ' version_line) 2 in
+ check_caml_version_for_camlp4 ();
"camlp4", camlp4orf, Filename.dirname camlp4orf, camlp4libdir, camlp4mod, camlp4_version
with _ -> die "No Camlp4 installation found.\n"
@@ -826,7 +810,7 @@ let strip =
(** * md5sum command *)
let md5sum =
- if arch = "Darwin" then "md5 -q" else "md5sum"
+ if arch = "Darwin" || arch = "FreeBSD" then "md5 -q" else "md5sum"
(** * Documentation : do we have latex, hevea, ... *)
@@ -1008,7 +992,7 @@ let write_dbg_wrapper f =
let _ = write_dbg_wrapper "dev/ocamldebug-coq"
-(** * Build the config/coq_config.ml file (+ link to myocamlbuild_config.ml) *)
+(** * Build the config/coq_config.ml file *)
let write_configml f =
safe_remove f;
@@ -1075,15 +1059,18 @@ let write_configml f =
close_out o;
Unix.chmod f 0o444
-let write_configml_my f f' =
- write_configml f;
- if os_type_win32 then
- write_configml f'
- else
- (safe_remove f'; Unix.symlink f f')
+let _ = write_configml "config/coq_config.ml"
-let _ = write_configml_my "config/coq_config.ml" "myocamlbuild_config.ml"
+(** * Symlinks or copies for the checker *)
+let _ =
+ let prog, args, prf =
+ if arch = "win32" then "cp", [], ""
+ else "ln", ["-s"], "../" in
+ List.iter (fun file ->
+ ignore(run "rm" ["-f"; "checker/"^file]);
+ ignore(run ~fatal:true prog (args @ [prf^"kernel/"^file;"checker/"^file])))
+ [ "esubst.ml"; "esubst.mli"; "names.ml"; "names.mli" ]
(** * Build the config/Makefile file *)
diff --git a/coq-win32.itarget b/coq-win32.itarget
deleted file mode 100644
index 9e2c7a2b6..000000000
--- a/coq-win32.itarget
+++ /dev/null
@@ -1,2 +0,0 @@
-binariesopt
-plugins/pluginsdyn.otarget
diff --git a/coq.itarget b/coq.itarget
deleted file mode 100644
index dd8b25905..000000000
--- a/coq.itarget
+++ /dev/null
@@ -1,8 +0,0 @@
-# NB: for the moment we start with bytecode compilation
-# for early error detection in .ml
-binariesbyte
-plugins/pluginsbyte.otarget
-binariesopt
-plugins/pluginsopt.otarget
-theories/theories.otarget
-plugins/pluginsvo.otarget
diff --git a/dev/README b/dev/README
index 5edf64c8f..814f60957 100644
--- a/dev/README
+++ b/dev/README
@@ -45,3 +45,6 @@ Makefile.subdir: makefile dedicated to intensive work in a given subdirectory
Makefile.devel: utilities to automatically launch coq in various states
Makefile.common: used by other Makefiles
objects.el: various development utilities at emacs level
+anomaly-traces-parser.el: a .emacs-ready elisp snippet to parse
+ location of Anomaly backtraces and jump to them conveniently from
+ the Emacs *compilation* output.
diff --git a/dev/base_include b/dev/base_include
index 767e023ea..86f34b2ac 100644
--- a/dev/base_include
+++ b/dev/base_include
@@ -17,6 +17,7 @@
#directory "grammar";;
#directory "intf";;
#directory "stm";;
+#directory "ltac";;
#directory "+camlp4";; (* lazy solution: add both of camlp4/5 so that *)
#directory "+camlp5";; (* Gramext is found in top_printers.ml *)
diff --git a/dev/doc/README-V1-V5 b/dev/doc/README-V1-V5
deleted file mode 100644
index ebbc05773..000000000
--- a/dev/doc/README-V1-V5
+++ /dev/null
@@ -1,296 +0,0 @@
-
- Notes on the prehistory of Coq
-
-This document is a copy within the Coq archive of a document written
-in September 2015 by Gérard Huet, Thierry Coquand and Christine Paulin
-to accompany their public release of the archive of versions 1.10 to 6.2
-of Coq and of its CONSTR ancestor. CONSTR, then Coq, was designed and
-implemented in the Formel team, joint between the INRIA Rocquencourt
-laboratory and the Ecole Normale Supérieure of Paris, from 1984
-onwards.
-
-Version 1
-
-This software is a prototype type-checker for a higher-order logical formalism
-known as the Theory of Constructions, presented in his PhD thesis by
-Thierry Coquand, with influences from Girard's system F and de Bruijn's Automath.
-The metamathematical analysis of the system is the
-PhD work of Thierry Coquand. The software is mostly the work of Gérard Huet.
-Most of the mathematical examples verified with the software are due
-to Thierry Coquand.
-
-The programming language of the CONSTR software (as it was called at the time)
-is a version of ML issued from the Edinburgh LCF system and running on
-a LISP backend. The main improvements from the original LCF ML are that ML
-is compiled rather than interpreted (Gérard Huet building on the original
-translator by Lockwood Morris), and that it is enriched by recursively
-defined types (work of Guy Cousineau). This ancestor of CAML was used
-and improved by Larry Paulson for his implementation of Cambridge LCF.
-
-Software developments of this prototype occurred from late 1983 to early 1985.
-
-Version 1.10 was frozen on December 22nd 1984. It is the version used for the
-examples in Thierry Coquand's thesis, defended on January 31st 1985.
-There was a unique binding operator, used both for universal quantification
-(dependent product) at the level of types and functional abstraction (lambda)
-at the level of terms/proofs, in the manner of Automath. Substitution
-(lambda reduction) was implemented using de Bruijn's indexes.
-
-Version 1.11 was frozen on February 19th, 1985. It is the version used for the
-examples in the paper:
-Th. Coquand, G. Huet. Constructions: A Higher Order Proof System for Mechanizing
-Mathematics. Invited paper, EUROCAL85, April 1985, Linz, Austria. Springer Verlag
-LNCS 203, pp. 151-184.
-
-Christine Paulin joined the team at this point, for her DEA research internship.
-In her DEA memoir (August 1985) she presents developments for the lambo function
-computing the minimal m such that f(m) is greater than n, for f an increasing
-integer function, a challenge for constructive mathematics. She also encoded
-the majority voting algorithm of Boyer and Moore.
-
-Version 2
-
-The formal system, now renamed as the "Calculus of Constructions", was presented
-with a proof of consistency and comparisons with proof systems of Per
-Martin Löf, Girard, and the Automath family of N. de Bruijn, in the paper:
-T. Coquand and G. Huet. The Calculus of Constructions.
-Submitted on June 30th 1985, accepted on December 5th, 1985,
-Information and Computation. Preprint as Rapport de Recherche Inria n°530,
-Mai 1986. Final version in Information and Computation 76,2/3, Feb. 88.
-
-An abstraction of the software design, in the form of an abstract machine
-for proof checking, and a fuller sequence of mathematical developments was
-presented in:
-Th. Coquand, G. Huet. Concepts Mathématiques et Informatiques Formalisés dans le Calcul des Constructions. Invited paper, European Logic Colloquium, Orsay,
-July 1985. Preprint as Rapport de recherche INRIA n°463, Dec. 85.
-Published in Logic Colloquium 1985, North-Holland, 1987.
-
-Version 2.8 was frozen on December 16th, 1985, and served for developing
-the exemples in the above papers.
-
-This calculus was then enriched in version 2.9 with a cumulative hierarchy of
-universes. Universe levels were initially explicit natural numbers.
-Another improvement was the possibility of automatic synthesis of implicit
-type arguments, relieving the user of tedious redundant declarations.
-
-Christine Paulin wrote an article "Algorithm development in the Calculus of
-Constructions", preprint as Rapport de recherche INRIA n°497, March 86.
-Final version in Proceedings Symposium on Logic in Computer Science, Cambridge,
-MA, 1986 (IEEE Computer Society Press). Besides lambo and majority,
-she presents quicksort and a text formatting algorithm.
-
-Version 2.13 of the calculus of constructions with universes was frozen
-on June 25th, 1986.
-
-A synthetic presentation of type theory along constructive lines with ML
-algorithms was given by Gérard Huet in his May 1986 CMU course notes
-"Formal Structures for Computation and Deduction". Its chapter
-"Induction and Recursion in the Theory of Constructions" was presented
-as an invited paper at the Joint Conference on Theory and Practice of Software
-Development TAPSOFT’87 at Pise in March 1987, and published as
-"Induction Principles Formalized in the Calculus of Constructions" in
-Programming of Future Generation Computers, Ed. K. Fuchi and M. Nivat,
-North-Holland, 1988.
-
-Version 3
-
-This version saw the beginning of proof automation, with a search algorithm
-inspired from PROLOG and the applicative logic programming programs
-of the course notes "Formal structures for computation and deduction".
-The search algorithm was implemented in ML by Thierry Coquand.
-The proof system could thus be used in two modes: proof verification and
-proof synthesis, with tactics such as "AUTO".
-
-The implementation language was now called CAML, for "categorical abstract
-machine language". It used as backend the LLM3 virtual machine of Le Lisp
-by Jérôme Chailloux. The main developers of CAML were Michel Mauny,
-Ascander Suarez and Pierre Weis.
-
-V3.1 was started in the summer of 1986, V3.2 was frozen at the end of November
-1986. V3.4 was developed in the first half of 1987.
-
-Thierry Coquand held a post-doctoral position in Cambrige University in 1986-87,
-where he developed a variant implementation in SML, with which he wrote
-some developments on fixpoints in Scott's domains.
-
-Version 4
-
-This version saw the beginning of program extraction from proofs, with
-two varieties of the type Prop of propositions, indicating constructive intent.
-The proof extraction algorithms were implemented by Christine Paulin-Mohring.
-
-V4.1 was frozen on July 24th, 1987. It had a first identified library of
-mathematical developments (directory exemples), with libraries Logic
-(containing impredicative encodings of intuitionistic logic and algebraic
-primitives for booleans, natural numbers and list), Peano developing second-order
-Peano arithmetic, Arith defining addition, multiplication, euclidean division
-and factorial. Typical developments were the Knaster-Tarski theorem
-and Newman's lemma from rewriting theory.
-
-V4.2 was a joint development of a team consisting of Thierry Coquand, Gérard
-Huet and Christine Paulin-Mohring. A file V4.2.log records the log of changes.
-It was frozen on September 1987 as the last version implemented in CAML 2.3,
-and V4.3 followed on CAML 2.5, a more stable development system.
-
-V4.3 saw the first top-level of the system. Instead of evaluating explicit
-quotations, the user could develop his mathematics in a high-level language
-called the mathematical vernacular (following Automath terminology).
-The user could develop files in the vernacular notation (with .v extension)
-which were now separate from the ml sources of the implementation.
-Gilles Dowek joined the team to develop the vernacular language as his
-DEA internship research.
-
-A notion of sticky constant was introduced, in order to keep names of lemmas
-when local hypotheses of proofs were discharged. This gave a notion
-of global mathematical environment with local sections.
-
-Another significant practical change was that the system, originally developped
-on the VAX central computer of our lab, was transferred on SUN personal
-workstations, allowing a level of distributed development.
-The extraction algorithm was modified, with three annotations Pos, Null and
-Typ decorating the sorts Prop and Type.
-
-Version 4.3 was frozen at the end of November 1987, and was distributed to an
-early community of users (among those were Hugo Herbelin and Loic Colson).
-
-V4.4 saw the first version of (encoded) inductive types.
-Now natural numbers could be defined as:
-Inductive NAT : Prop = O : NAT | Succ : NAT->NAT.
-These inductive types were encoded impredicatively in the calculus,
-using a subsystem "rec" due to Christine Paulin.
-V4.4 was frozen on March 6th 1988.
-
-Version 4.5 was the first one to support inductive types and program extraction.
-Its banner was "Calcul des Constructions avec Realisations et Synthese".
-The vernacular language was enriched to accommodate extraction commands.
-
-The verification engine design was presented as:
-G. Huet. The Constructive Engine. Version 4.5. Invited Conference, 2nd European
-Symposium on Programming, Nancy, March 88.
-The final paper, describing the V4.9 implementation, appeared in:
-A perspective in Theoretical Computer Science, Commemorative Volume in memory
-of Gift Siromoney, Ed. R. Narasimhan, World Scientific Publishing, 1989.
-
-Version 4.5 was demonstrated in June 1988 at the YoP Institute on Logical
-Foundations of Functional Programming organized by Gérard Huet at Austin, Texas.
-
-Version 4.6 was started during summer 1988. Its main improvement was the
-complete rehaul of the proof synthesis engine by Thierry Coquand, with
-a tree structure of goals.
-
-Its source code was communicated to Randy Pollack on September 2nd 1988.
-It evolved progressively into LEGO, proof system for Luo's formalism
-of Extended Calculus of Constructions.
-
-The discharge tactic was modified by G. Huet to allow for inter-dependencies
-in discharged lemmas. Christine Paulin improved the inductive definition scheme
-in order to accommodate predicates of any arity.
-
-Version 4.7 was started on September 6th, 1988.
-
-This version starts exploiting the CAML notion of module in order to improve the
-modularity of the implementation. Now the term verifier is identified as
-a proper module Machine, which the structure of its internal data structures
-being hidden and thus accessible only through the legitimate operations.
-This machine (the constructive engine) was the trusted core of the
-implementation. The proof synthesis mechanism was a separate proof term
-generator. Once a complete proof term was synthesized with the help of tactics,
-it was entirely re-checked by the engine. Thus there was no need to certify
-the tactics, and the system took advantage of this fact by having tactics ignore
-the universe levels, universe consistency check being relegated to the final
-type-checking pass. This induced a certain puzzlement of early users who saw
-their successful proof search ended with QED, followed by silence, followed by
-a failure message of universe inconsistency rejection...
-
-The set of examples comprise set theory experiments by Hugo Herbelin,
-and notably the Schroeder-Bernstein theorem.
-
-Version 4.8, started on October 8th, 1988, saw a major re-implementation of the
-abstract syntax type constr, separating variables of the formalism and
-metavariables denoting incomplete terms managed by the search mechanism.
-A notion of level (with three values TYPE, OBJECT and PROOF) is made explicit
-and a type judgement clarifies the constructions, whose implementation is now
-fully explicit. Structural equality is speeded up by using pointer equality,
-yielding spectacular improvements. Thierry Coquand adapts the proof synthesis
-to the new representation, and simplifies pattern matching to 1st order
-predicate calculus matching, with important performance gain.
-
-A new representation of the universe hierarchy is then defined by G. Huet.
-Universe levels are now implemented implicitly, through a hidden graph
-of abstract levels constrained with an order relation.
-Checking acyclicity of the graph insures well-foundedness of the ordering,
-and thus consistency. This was documented in a memo
-"Adding Type:Type to the Calculus of Constructions" which was never published.
-
-The development version is released as a stable 4.8 at the end of 1988.
-
-Version 4.9 is released on March 1st 1989, with the new "elastic"
-universe hierarchy.
-
-The spring 89 saw the first attempt at documenting the system usage,
-with a number of papers describing the formalism:
-- Metamathematical Investigations of a Calculus of Constructions, by
-Thierry Coquand (INRIA Research Report N°1088, Sept. 1989, published in
-Logic and Computer Science, ed. P.G. Odifreddi, Academic Press, 1990)
-- Inductive definitions in the Calculus of Constructions, by
-Christine Paulin-Mohring,
-- Extracting Fomega's programs from proofs in the Calculus of Constructions, by
-Christine Paulin-Mohring (published in POPL'89)
-- The Constructive Engine, by Gérard Huet
-as well as a number of user guides:
-- A short user's guide for the Constructions Version 4.10, by Gérard Huet
-- A Vernacular Syllabus, by Gilles Dowek.
-- The Tactics Theorem Prover, User's guide, Version 4.10, by Thierry Coquand.
-
-Stable V4.10, released on May 1st, 1989, was then a mature system,
-distributed with CAML V2.6.
-
-In the mean time, Thierry Coquand and Christine Paulin-Mohring
-had been investigating how to add native inductive types to the
-Calculus of Constructions, in the manner of Per Martin-Löf's Intuitionistic
-Type Theory. The impredicative encoding had already been presented in:
-F. Pfenning and C. Paulin-Mohring. Inductively defined types in the Calculus
-of Constructions. Preprint technical report CMU-CS-89-209, final version in
-Proceedings of Mathematical Foundations of Programming Semantics,
-volume 442, Lecture Notes in Computer Science. Springer-Verlag, 1990.
-An extension of the calculus with primitive inductive types appeared in:
-Th. Coquand and C. Paulin-Mohring. Inductively defined types.
-In P. Martin-Löf and G. Mints, editors, Proceedings of Colog'88, volume 417,
-Lecture Notes in Computer Science. Springer-Verlag, 1990.
-
-This lead to the Calculus of Inductive Constructions, logical formalism
-implemented in Versions 5 upward of the system, and documented in:
-C. Paulin-Mohring. Inductive Definitions in the System Coq - Rules and
-Properties. In M. Bezem and J.-F. Groote, editors, Proceedings of the conference
-Typed Lambda Calculi and Applications, volume 664, Lecture Notes in Computer
-Science, 1993.
-
-The last version of CONSTR is Version 4.11, which was last distributed
-in Spring 1990. It was demonstrated at the first workshop of the European
-Basic Research Action Logical Frameworks In Sophia Antipolis in May 1990.
-
-At the end of 1989, Version 5.1 was started, and renamed as the system Coq
-for the Calculus of Inductive Constructions. It was then ported to the new
-stand-alone implementation of ML called Caml-light.
-
-In 1990 many changes occurred. Thierry Coquand left for Chalmers University
-in Göteborg. Christine Paulin-Mohring took a CNRS researcher position
-at the LIP laboratory of Ecole Normale Supérieure de Lyon. Project Formel
-was terminated, and gave rise to two teams: Cristal at INRIA-Roquencourt,
-that continued developments in functional programming with Caml-light then
-Ocaml, and Coq, continuing the type theory research, with a joint team
-headed by Gérard Huet at INRIA-Rocquencourt and Christine Paulin-Mohring
-at the LIP laboratory of CNRS-ENS Lyon.
-
-Chetan Murthy joined the team in 1991 and became the main software architect
-of Version 5. He completely rehauled the implementation for efficiency.
-Versions 5.6 and 5.8 were major distributed versions, with complete
-documentation and a library of users' developements. The use of the RCS
-revision control system, and systematic ChangeLog files, allow a more
-precise tracking of the software developments.
-
-Developments from Version 6 upwards are documented in the credits section of
-Coq's Reference Manual.
-
-September 2015
-Thierry Coquand, Gérard Huet and Christine Paulin-Mohring.
diff --git a/dev/doc/README-V1-V5.asciidoc b/dev/doc/README-V1-V5.asciidoc
new file mode 100644
index 000000000..631fb92c9
--- /dev/null
+++ b/dev/doc/README-V1-V5.asciidoc
@@ -0,0 +1,378 @@
+Notes on the prehistory of Coq
+==============================
+:author: Thierry Coquand, Gérard Huet & Christine Paulin-Mohring
+:revdate: September 2015
+:toc:
+:toc-placement: preamble
+:toclevels: 1
+:showtitle:
+
+
+This document is a copy within the Coq archive of a document written
+in September 2015 by Gérard Huet, Thierry Coquand and Christine Paulin
+to accompany their public release of the archive of versions 1.10 to 6.2
+of Coq and of its CONSTR ancestor. CONSTR, then Coq, was designed and
+implemented in the Formel team, joint between the INRIA Rocquencourt
+laboratory and the Ecole Normale Supérieure of Paris, from 1984
+onwards.
+
+Version 1
+---------
+
+This software is a prototype type-checker for a higher-order logical
+formalism known as the Theory of Constructions, presented in his PhD
+thesis by Thierry Coquand, with influences from Girard's system F and
+de Bruijn's Automath. The metamathematical analysis of the system is
+the PhD work of Thierry Coquand. The software is mostly the work of
+Gérard Huet. Most of the mathematical examples verified with the
+software are due to Thierry Coquand.
+
+The programming language of the CONSTR software (as it was called at
+the time) was a version of ML adapted from the Edinburgh LCF system
+and running on a LISP backend. The main improvements from the original
+LCF ML were that ML was compiled rather than interpreted (Gérard Huet
+building on the original translator by Lockwood Morris), and that it
+was enriched by recursively defined types (work of Guy
+Cousineau). This ancestor of CAML was used and improved by Larry
+Paulson for his implementation of Cambridge LCF.
+
+Software developments of this prototype occurred from late 1983 to
+early 1985.
+
+Version 1.10 was frozen on December 22nd 1984. It is the version used
+for the examples in Thierry Coquand's thesis, defended on January 31st
+1985. There was a unique binding operator, used both for universal
+quantification (dependent product) at the level of types and
+functional abstraction (λ) at the level of terms/proofs, in the manner
+of Automath. Substitution (λ-reduction) was implemented using de
+Bruijn's indexes.
+
+Version 1.11 was frozen on February 19th, 1985. It is the version used
+for the examples in the paper: Th. Coquand, G. Huet. __Constructions: A
+Higher Order Proof System for Mechanizing Mathematics__ <<CH85>>.
+
+Christine Paulin joined the team at this point, for her DEA research
+internship. In her DEA memoir (August 1985) she presents developments
+for the _lambo_ function – _lambo(f)(n)_ computes the minimal _m_ such
+that _f(m)_ is greater than _n_, for _f_ an increasing integer
+function, a challenge for constructive mathematics. She also encoded
+the majority voting algorithm of Boyer and Moore.
+
+Version 2
+---------
+
+The formal system, now renamed as the _Calculus of Constructions_, was
+presented with a proof of consistency and comparisons with proof
+systems of Per Martin Löf, Girard, and the Automath family of N. de
+Bruijn, in the paper: T. Coquand and G. Huet. __The Calculus of
+Constructions__ <<CH88>>.
+
+An abstraction of the software design, in the form of an abstract
+machine for proof checking, and a fuller sequence of mathematical
+developments was presented in: Th. Coquand, G. Huet. __Concepts
+Mathématiques et Informatiques Formalisés dans le Calcul des
+Constructions__<<CH87>>.
+
+Version 2.8 was frozen on December 16th, 1985, and served for
+developing the exemples in the above papers.
+
+This calculus was then enriched in version 2.9 with a cumulative
+hierarchy of universes. Universe levels were initially explicit
+natural numbers. Another improvement was the possibility of automatic
+synthesis of implicit type arguments, relieving the user of tedious
+redundant declarations.
+
+Christine Paulin wrote an article __Algorithm development in the
+Calculus of Constructions__ <<P86>>. Besides _lambo_ and _majority_,
+she presents quicksort and a text formatting algorithm.
+
+Version 2.13 of the Calculus of Constructions with universes was
+frozen on June 25th, 1986.
+
+A synthetic presentation of type theory along constructive lines with
+ML algorithms was given by Gérard Huet in his May 1986 CMU course
+notes _Formal Structures for Computation and Deduction_. Its chapter
+_Induction and Recursion in the Theory of Constructions_ was presented
+as an invited paper at the Joint Conference on Theory and Practice of
+Software Development TAPSOFT’87 at Pise in March 1987, and published
+as __Induction Principles Formalized in the Calculus of
+Constructions__ <<H88>>.
+
+Version 3
+---------
+
+This version saw the beginning of proof automation, with a search
+algorithm inspired from PROLOG and the applicative logic programming
+programs of the course notes _Formal structures for computation and
+deduction_. The search algorithm was implemented in ML by Thierry
+Coquand. The proof system could thus be used in two modes: proof
+verification and proof synthesis, with tactics such as `AUTO`.
+
+The implementation language was now called CAML, for Categorical
+Abstract Machine Language. It used as backend the LLM3 virtual machine
+of Le Lisp by Jérôme Chailloux. The main developers of CAML were
+Michel Mauny, Ascander Suarez and Pierre Weis.
+
+V3.1 was started in the summer of 1986, V3.2 was frozen at the end of
+November 1986. V3.4 was developed in the first half of 1987.
+
+Thierry Coquand held a post-doctoral position in Cambrige University
+in 1986-87, where he developed a variant implementation in SML, with
+which he wrote some developments on fixpoints in Scott's domains.
+
+Version 4
+---------
+
+This version saw the beginning of program extraction from proofs, with
+two varieties of the type `Prop` of propositions, indicating
+constructive intent. The proof extraction algorithms were implemented
+by Christine Paulin-Mohring.
+
+V4.1 was frozen on July 24th, 1987. It had a first identified library
+of mathematical developments (directory exemples), with libraries
+Logic (containing impredicative encodings of intuitionistic logic and
+algebraic primitives for booleans, natural numbers and list), `Peano`
+developing second-order Peano arithmetic, `Arith` defining addition,
+multiplication, euclidean division and factorial. Typical developments
+were the Knaster-Tarski theorem and Newman's lemma from rewriting
+theory.
+
+V4.2 was a joint development of a team consisting of Thierry Coquand,
+Gérard Huet and Christine Paulin-Mohring. A file V4.2.log records the
+log of changes. It was frozen on September 1987 as the last version
+implemented in CAML 2.3, and V4.3 followed on CAML 2.5, a more stable
+development system.
+
+V4.3 saw the first top-level of the system. Instead of evaluating
+explicit quotations, the user could develop his mathematics in a
+high-level language called the mathematical vernacular (following
+Automath terminology). The user could develop files in the vernacular
+notation (with .v extension) which were now separate from the `ml`
+sources of the implementation. Gilles Dowek joined the team to
+develop the vernacular language as his DEA internship research.
+
+A notion of sticky constant was introduced, in order to keep names of
+lemmas when local hypotheses of proofs were discharged. This gave a
+notion of global mathematical environment with local sections.
+
+Another significant practical change was that the system, originally
+developped on the VAX central computer of our lab, was transferred on
+SUN personal workstations, allowing a level of distributed
+development. The extraction algorithm was modified, with three
+annotations `Pos`, `Null` and `Typ` decorating the sorts `Prop` and
+`Type`.
+
+Version 4.3 was frozen at the end of November 1987, and was
+distributed to an early community of users (among those were Hugo
+Herbelin and Loic Colson).
+
+V4.4 saw the first version of (encoded) inductive types. Now natural
+numbers could be defined as:
+
+[source, coq]
+Inductive NAT : Prop = O : NAT | Succ : NAT->NAT.
+
+These inductive types were encoded impredicatively in the calculus,
+using a subsystem _rec_ due to Christine Paulin. V4.4 was frozen on
+March 6th 1988.
+
+Version 4.5 was the first one to support inductive types and program
+extraction. Its banner was _Calcul des Constructions avec
+Réalisations et Synthèse_. The vernacular language was enriched to
+accommodate extraction commands.
+
+The verification engine design was presented as: G. Huet. _The
+Constructive Engine_. Version 4.5. Invited Conference, 2nd European
+Symposium on Programming, Nancy, March 88. The final paper,
+describing the V4.9 implementation, appeared in: A perspective in
+Theoretical Computer Science, Commemorative Volume in memory of Gift
+Siromoney, Ed. R. Narasimhan, World Scientific Publishing, 1989.
+
+Version 4.5 was demonstrated in June 1988 at the YoP Institute on
+Logical Foundations of Functional Programming organized by Gérard Huet
+at Austin, Texas.
+
+Version 4.6 was started during the summer of 1988. Its main
+improvement was the complete rehaul of the proof synthesis engine by
+Thierry Coquand, with a tree structure of goals.
+
+Its source code was communicated to Randy Pollack on September 2nd
+1988. It evolved progressively into LEGO, proof system for Luo's
+formalism of Extended Calculus of Constructions.
+
+The discharge tactic was modified by Gérard Huet to allow for
+inter-dependencies in discharged lemmas. Christine Paulin improved the
+inductive definition scheme in order to accommodate predicates of any
+arity.
+
+Version 4.7 was started on September 6th, 1988.
+
+This version starts exploiting the CAML notion of module in order to
+improve the modularity of the implementation. Now the term verifier is
+identified as a proper module Machine, which the structure of its
+internal data structures being hidden and thus accessible only through
+the legitimate operations. This machine (the constructive engine) was
+the trusted core of the implementation. The proof synthesis mechanism
+was a separate proof term generator. Once a complete proof term was
+synthesized with the help of tactics, it was entirely re-checked by
+the engine. Thus there was no need to certify the tactics, and the
+system took advantage of this fact by having tactics ignore the
+universe levels, universe consistency check being relegated to the
+final type-checking pass. This induced a certain puzzlement in early
+users who saw, after a successful proof search, their `QED` followed
+by silence, followed by a failure message due to a universe
+inconsistency…
+
+The set of examples comprise set theory experiments by Hugo Herbelin,
+and notably the Schroeder-Bernstein theorem.
+
+Version 4.8, started on October 8th, 1988, saw a major
+re-implementation of the abstract syntax type `constr`, separating
+variables of the formalism and metavariables denoting incomplete terms
+managed by the search mechanism. A notion of level (with three values
+`TYPE`, `OBJECT` and `PROOF`) is made explicit and a type judgement
+clarifies the constructions, whose implementation is now fully
+explicit. Structural equality is speeded up by using pointer equality,
+yielding spectacular improvements. Thierry Coquand adapts the proof
+synthesis to the new representation, and simplifies pattern matching
+to first-order predicate calculus matching, with important performance
+gain.
+
+A new representation of the universe hierarchy is then defined by
+Gérard Huet. Universe levels are now implemented implicitly, through
+a hidden graph of abstract levels constrained with an order relation.
+Checking acyclicity of the graph insures well-foundedness of the
+ordering, and thus consistency. This was documented in a memo _Adding
+Type:Type to the Calculus of Constructions_ which was never published.
+
+The development version is released as a stable 4.8 at the end of
+1988.
+
+Version 4.9 is released on March 1st 1989, with the new ``elastic''
+universe hierarchy.
+
+The spring of 1989 saw the first attempt at documenting the system
+usage, with a number of papers describing the formalism:
+
+- _Metamathematical Investigations of a Calculus of Constructions_, by
+ Thierry Coquand <<C90>>,
+- _Inductive definitions in the Calculus of Constructions_, by
+ Christine Paulin-Mohrin,
+- _Extracting Fω's programs from proofs in the Calculus of
+ Constructions_, by Christine Paulin-Mohring <<P89>>,
+- _The Constructive Engine_, by Gérard Huet <<H89>>,
+
+as well as a number of user guides:
+
+- _A short user's guide for the Constructions_ Version 4.10, by Gérard Huet
+- _A Vernacular Syllabus_, by Gilles Dowek.
+- _The Tactics Theorem Prover, User's guide_, Version 4.10, by Thierry
+ Coquand.
+
+Stable V4.10, released on May 1st, 1989, was then a mature system,
+distributed with CAML V2.6.
+
+In the mean time, Thierry Coquand and Christine Paulin-Mohring had
+been investigating how to add native inductive types to the Calculus
+of Constructions, in the manner of Per Martin-Löf's Intuitionistic
+Type Theory. The impredicative encoding had already been presented in:
+F. Pfenning and C. Paulin-Mohring. __Inductively defined types in the
+Calculus of Constructions__ <<PP90>>. An extension of the calculus
+with primitive inductive types appeared in: Th. Coquand and
+C. Paulin-Mohring. __Inductively defined types__ <<CP90>>.
+
+This led to the Calculus of Inductive Constructions, logical formalism
+implemented in Versions 5 upward of the system, and documented in:
+C. Paulin-Mohring. __Inductive Definitions in the System Coq - Rules
+and Properties__ <<P93>>.
+
+The last version of CONSTR is Version 4.11, which was last distributed
+in the spring of 1990. It was demonstrated at the first workshop of
+the European Basic Research Action Logical Frameworks In Sophia
+Antipolis in May 1990.
+
+At the end of 1989, Version 5.1 was started, and renamed as the system
+Coq for the Calculus of Inductive Constructions. It was then ported to
+the new stand-alone implementation of ML called Caml-light.
+
+In 1990 many changes occurred. Thierry Coquand left for Chalmers
+University in Göteborg. Christine Paulin-Mohring took a CNRS
+researcher position at the LIP laboratory of École Normale Supérieure
+de Lyon. Project Formel was terminated, and gave rise to two teams:
+Cristal at INRIA-Roquencourt, that continued developments in
+functional programming with Caml-light then Ocaml, and Coq, continuing
+the type theory research, with a joint team headed by Gérard Huet at
+INRIA-Rocquencourt and Christine Paulin-Mohring at the LIP laboratory
+of CNRS-ENS Lyon.
+
+Chetan Murthy joined the team in 1991 and became the main software
+architect of Version 5. He completely rehauled the implementation for
+efficiency. Versions 5.6 and 5.8 were major distributed versions,
+with complete documentation and a library of users' developements. The
+use of the RCS revision control system, and systematic ChangeLog
+files, allow a more precise tracking of the software developments.
+
+Developments from Version 6 upwards are documented in the credits
+section of Coq's Reference Manual.
+
+====
+September 2015 +
+Thierry Coquand, Gérard Huet and Christine Paulin-Mohring.
+====
+
+[bibliography]
+.Bibliographic references
+
+- [[[CH85]]] Th. Coquand, G. Huet. _Constructions: A Higher Order
+ Proof System for Mechanizing Mathematics_. Invited paper, EUROCAL85,
+ April 1985, Linz, Austria. Springer Verlag LNCS 203, pp. 151-184.
+
+- [[[CH88]]] T. Coquand and G. Huet. _The Calculus of Constructions_.
+ Submitted on June 30th 1985, accepted on December 5th, 1985,
+ Information and Computation. Preprint as Rapport de Recherche Inria
+ n°530, Mai 1986. Final version in Information and Computation
+ 76,2/3, Feb. 88.
+
+- [[[CH87]]] Th. Coquand, G. Huet. _Concepts Mathématiques et
+ Informatiques Formalisés dans le Calcul des Constructions_. Invited
+ paper, European Logic Colloquium, Orsay, July 1985. Preprint as
+ Rapport de recherche INRIA n°463, Dec. 85. Published in Logic
+ Colloquium 1985, North-Holland, 1987.
+
+- [[[P86]]] C. Paulin. _Algorithm development in the Calculus of
+ Constructions_, preprint as Rapport de recherche INRIA n°497,
+ March 86. Final version in Proceedings Symposium on Logic in Computer
+ Science, Cambridge, MA, 1986 (IEEE Computer Society Press).
+
+- [[[H88]]] G. Huet. _Induction Principles Formalized in the Calculus
+ of Constructions_ in Programming of Future Generation Computers,
+ Ed. K. Fuchi and M. Nivat, North-Holland, 1988.
+
+- [[[C90]]] Th. Coquand. _Metamathematical Investigations of a
+ Calculus of Constructions_, by INRIA Research Report N°1088,
+ Sept. 1989, published in Logic and Computer Science,
+ ed. P.G. Odifreddi, Academic Press, 1990.
+
+- [[[P89]]] C. Paulin. _Extracting F ω's programs from proofs in the
+ calculus of constructions_. 16th Annual ACM Symposium on Principles
+ of Programming Languages, Austin. 1989.
+
+- [[[H89]]] G. Huet. _The constructive engine_. A perspective in
+ Theoretical Computer Science. Commemorative Volume for Gift
+ Siromoney. World Scientific Publishing (1989).
+
+- [[[PP90]]] F. Pfenning and C. Paulin-Mohring. _Inductively defined
+ types in the Calculus of Constructions_. Preprint technical report
+ CMU-CS-89-209, final version in Proceedings of Mathematical
+ Foundations of Programming Semantics, volume 442, Lecture Notes in
+ Computer Science. Springer-Verlag, 1990
+
+- [[[CP90]]] Th. Coquand and C. Paulin-Mohring. _Inductively defined
+ types_. In P. Martin-Löf and G. Mints, editors, Proceedings of
+ Colog'88, volume 417, Lecture Notes in Computer Science.
+ Springer-Verlag, 1990.
+
+- [[[P93]]] C. Paulin-Mohring. _Inductive Definitions in the System
+ Coq - Rules and Properties_. In M. Bezem and J.-F. Groote, editors,
+ Proceedings of the conference Typed Lambda Calculi and Applications,
+ volume 664, Lecture Notes in Computer Science, 1993.
diff --git a/dev/doc/build-system.dev.txt b/dev/doc/build-system.dev.txt
index af1120e97..fefcb0937 100644
--- a/dev/doc/build-system.dev.txt
+++ b/dev/doc/build-system.dev.txt
@@ -30,6 +30,11 @@ HISTORY:
restricted set of .ml4 (see variable BUILDGRAMMAR).
- then on the true target asked by the user.
+* June 2016 (Pierre Letouzey)
+ The files in grammar/ are now self-contained, we could compile
+ grammar.cma (and q_constr.cmo) directly, no need for a separate
+ subcall to make nor awkward include-failed-and-retry.
+
---------------------------------------------------------------------------
@@ -59,29 +64,14 @@ Cons:
Makefiles hierachy
------------------
-Le Makefile a été séparé en plusieurs fichiers :
-
-- Makefile: coquille vide qui lançant Makefile.build sauf pour
- clean et quelques petites choses ne nécessitant par de calculs
- de dépendances.
-- Makefile.common : définitions des variables (essentiellement des
- listes de fichiers)
-- Makefile.build : contient les regles de compilation, ainsi que
- le "include" des dépendances (restreintes ou non selon la variable
- BUILDGRAMMAR).
-- Makefile.doc : regles specifiques à la compilation de la documentation.
-
-
-Parallélisation
----------------
+The Makefile is separated in several files :
-Il y a actuellement un double appel interne à "make -f Makefile.build",
-d'abord pour construire grammar.cma/q_constr.cmo, puis le reste.
-Cela signifie que ce makefile est un petit peu moins parallélisable
-que strictement possible en théorie: par exemple, certaines choses
-faites lors du second make pourraient être faites en parallèle avec
-le premier. En pratique, ce premier make va suffisemment vite pour
-que cette limitation soit peu gênante.
+- Makefile: wrapper that triggers a call to Makefile.build, except for
+ clean and a few other little things doable without dependency analysis.
+- Makefile.common : variable definitions (mostly lists of files or
+ directories)
+- Makefile.build : contains compilation rules, and the "include" of dependencies
+- Makefile.doc : specific rules for compiling the documentation.
FIND_VCS_CLAUSE
diff --git a/dev/doc/build-system.txt b/dev/doc/build-system.txt
index 31d9875ad..4593a6ad5 100644
--- a/dev/doc/build-system.txt
+++ b/dev/doc/build-system.txt
@@ -113,15 +113,20 @@ Targets for cleaning various parts:
- docclean: clean documentation
-.ml4 files
-----------
+.ml4/.mlp files
+---------------
-If a .ml4 file uses a grammar extension from Coq (such as grammar.cma
-or q_constr.cmo), it must contain a line like:
+There is now two kinds of preprocessed files :
+ - a .mlp do not need grammar.cma (they are in grammar/ and tools/compat5*.mlp)
+ - a .ml4 is now always preprocessed with grammar.cma (and q_constr.cmo),
+ except coqide_main.ml4 and its specific rule
+
+This classification replaces the old mechanism of declaring the use
+of a grammar extension via a line of the form:
(*i camlp4deps: "grammar.cma q_constr.cmo" i*)
The use of (*i camlp4use: ... i*) to mention uses of standard
-extension such as IFDEF has been discontinued, the Makefile now
+extension such as IFDEF has also been discontinued, the Makefile now
always calls camlp4 with pa_macros.cmo and a few others by default.
For debugging a Coq grammar extension, it could be interesting
diff --git a/dev/doc/changes.txt b/dev/doc/changes.txt
index 0581a5f85..4135ddd2d 100644
--- a/dev/doc/changes.txt
+++ b/dev/doc/changes.txt
@@ -2,6 +2,73 @@
= CHANGES BETWEEN COQ V8.5 AND COQ V8.6 =
=========================================
+** Notation_ops **
+
+Use Glob_ops.glob_constr_eq instead of Notation_ops.eq_glob_constr.
+
+** Logging and Pretty Printing: **
+
+* Printing functions have been removed from `Pp.mli`, which is now a
+ purely pretty-printing interface. Functions affected are:
+
+```` ocaml
+val pp : std_ppcmds -> unit
+val ppnl : std_ppcmds -> unit
+val pperr : std_ppcmds -> unit
+val pperrnl : std_ppcmds -> unit
+val pperr_flush : unit -> unit
+val pp_flush : unit -> unit
+val flush_all : unit -> unit
+val msg : std_ppcmds -> unit
+val msgnl : std_ppcmds -> unit
+val msgerr : std_ppcmds -> unit
+val msgerrnl : std_ppcmds -> unit
+val message : string -> unit
+````
+
+ which are no more available. Users of `Pp.pp msg` should now use the
+ proper `Feedback.msg_*` function. Clients also have no control over
+ flushing, the back end takes care of it.
+
+* Feedback related functions and definitions have been moved to the
+ `Feedback` module. `message_level` has been renamed to
+ level. Functions moved from Pp to Feedback are:
+
+```` ocaml
+val set_logger : logger -> unit
+val std_logger : logger
+val emacs_logger : logger
+val feedback_logger : logger
+````
+
+* We now provide several loggers, `log_via_feedback` is removed in
+ favor of `set_logger feedback_logger`. Output functions are:
+
+```` ocaml
+val with_output_to_file : string -> ('a -> 'b) -> 'a -> 'b
+val msg_info : Pp.std_ppcmds -> unit
+val msg_notice : Pp.std_ppcmds -> unit
+val msg_warning : Pp.std_ppcmds -> unit
+val msg_error : Pp.std_ppcmds -> unit
+val msg_debug : Pp.std_ppcmds -> unit
+````
+
+ with the `msg_*` functions being just an alias for `logger $Level`.
+
+* The main feedback functions are:
+
+```` ocaml
+val set_feeder : (feedback -> unit) -> unit
+val feedback : ?id:edit_or_state_id -> ?route:route_id -> feedback_content -> unit
+val set_id_for_feedback : ?route:route_id -> edit_or_state_id -> unit
+````
+ Note that `feedback` doesn't take two parameters anymore. After
+ refactoring the following function has been removed:
+
+```` ocaml
+val get_id_for_feedback : unit -> edit_or_state_id * route_id
+````
+
- The interface of the Context module was changed.
Related types and functions were put in separate submodules.
The mapping from old identifiers to new identifiers is the following:
@@ -66,6 +133,52 @@
Context.Named.t = LocalAssum of Names.Id.t * Constr.t
| LocalDef of Names.Id.t * Constr.t * Constr.t
+- The various EXTEND macros do not handle specially the Coq-defined entries
+ anymore. Instead, they just output a name that have to exist in the scope
+ of the ML code. The parsing rules (VERNAC) ARGUMENT EXTEND will look for
+ variables "$name" of type Gram.entry, while the parsing rules of
+ (VERNAC COMMAND | TACTIC) EXTEND, as well as the various TYPED AS clauses will
+ look for variables "wit_$name" of type Genarg.genarg_type. The small DSL
+ for constructing compound entries still works over this scheme. Note that in
+ the case of (VERNAC) ARGUMENT EXTEND, the name of the argument entry is bound
+ in the parsing rules, so beware of recursive calls.
+
+- Evarutil was split in two parts. The new Evardefine file exposes functions
+define_evar_* mostly used internally in the unification engine.
+
+- The Refine module was move out of Proofview.
+
+ Proofview.Refine.* ---> Refine.*
+
+- A statically monotonous evarmap type was introduced in Sigma. Not all the API
+ has been converted, so that the user may want to use compatibility functions
+ Sigma.to_evar_map and Sigma.Unsafe.of_evar_map or Sigma.Unsafe.of_pair when
+ needed. Code can be straightforwardly adapted in the following way:
+
+ let (sigma, x1) = ... in
+ ...
+ let (sigma, xn) = ... in
+ (sigma, ans)
+
+ should be turned into:
+
+ open Sigma.Notations
+
+ let Sigma (x1, sigma, p1) = ... in
+ ...
+ let Sigma (xn, sigma, pn) = ... in
+ Sigma (ans, sigma, p1 +> ... +> pn)
+
+- The Proofview.Goal.*enter family of functions now takes a polymorphic
+ continuation given as a record as an argument.
+
+ Proofview.Goal.enter begin fun gl -> ... end
+
+ should be turned into
+
+ open Proofview.Notations
+
+ Proofview.Goal.enter { enter = begin fun gl -> ... end }
=========================================
= CHANGES BETWEEN COQ V8.4 AND COQ V8.5 =
diff --git a/dev/doc/coq-src-description.txt b/dev/doc/coq-src-description.txt
index fe896d316..00e7f5c53 100644
--- a/dev/doc/coq-src-description.txt
+++ b/dev/doc/coq-src-description.txt
@@ -19,13 +19,6 @@ highparsing :
Files in parsing/ that cannot be linked too early.
Contains the grammar rules g_*.ml4
-hightactics :
-
- Files in tactics/ that cannot be linked too early.
- These are the .ml4 files that uses the EXTEND possibilities
- provided by grammar.cma, for instance eauto.ml4.
-
-
Special components
------------------
diff --git a/dev/doc/drop.txt b/dev/doc/drop.txt
new file mode 100644
index 000000000..3a584741b
--- /dev/null
+++ b/dev/doc/drop.txt
@@ -0,0 +1,44 @@
+When you start byte-compiled Coq toplevel:
+
+ rlwrap bin/coqtop.byte
+
+then if you type:
+
+ Drop.
+
+you will decend from Coq toplevel down to Ocaml toplevel.
+So if you want to learn:
+- the current values of some global variables you are interested in
+- or see what happens when you invoke certain functions
+this is the place where you can do that.
+
+When you try to print values belonging to abstract data types:
+
+ # let sigma, env = Lemmas.get_current_context ();;
+
+ val sigma : Evd.evar_map = <abstr>
+ val env : Environ.env = <abstr>
+
+ # Typeops.infer env (snd (Pretyping.understand_tcc env sigma (Constrintern.intern_constr env (Pcoq.parse_string Pcoq.Constr.lconstr "plus"))));;
+
+ - : Environ.unsafe_judgment = {Environ.uj_val = <abstr>; uj_type = <abstr>}
+
+the printed values are not very helpful.
+
+One way how to deal with that is to load the corresponding printers:
+
+ # #use "dev/include";;
+
+Consequently, the result of:
+
+ # Typeops.infer env (snd (Pretyping.understand_tcc env sigma (Constrintern.intern_constr env (Pcoq.parse_string Pcoq.Constr.lconstr "plus"))));;
+
+will be printed as:
+
+ - : Environ.unsafe_judgment = Nat.add : nat -> nat -> nat
+
+which makes more sense.
+
+To be able to understand the meaning of the data types,
+sometimes the best option is to turn those data types from abstract to concrete
+and look at them without any kind of pretty printing.
diff --git a/dev/doc/ocamlbuild.txt b/dev/doc/ocamlbuild.txt
new file mode 100644
index 000000000..efedbc506
--- /dev/null
+++ b/dev/doc/ocamlbuild.txt
@@ -0,0 +1,30 @@
+Ocamlbuild & Coq
+----------------
+
+A quick note in case someone else gets interested someday in compiling
+Coq via ocamlbuild : such an experimental build system has existed
+in the past (more or less maintained from 2009 to 2013), in addition
+to the official build system via gnu make. But this build via
+ocamlbuild has been severly broken since early 2014 (and don't work
+in 8.5, for instance). This experiment has attracted very limited
+interest from other developers over the years, and has been quite
+cumbersome to maintain, so it is now officially discontinued.
+If you want to have a look at the files of this build system
+(especially myocamlbuild.ml), you can fetch :
+ - my last effort at repairing this build system (up to coqtop.native) :
+ https://github.com/letouzey/coq-wip/tree/ocamlbuild-partial-repair
+ - coq official v8.5 branch (recent but broken)
+ - coq v8.4 branch(less up-to-date, but works).
+
+For the record, the three main drawbacks of this experiments were:
+ - recurrent issues with circularities reported by ocamlbuild
+ (even though make was happy) during the evolution of Coq sources
+ - no proper support of parallel build
+ - quite slow re-traversal of already built things
+See the two corresponding bug reports on Mantis, or
+https://github.com/ocaml/ocamlbuild/issues/52
+
+As an interesting feature, I successfully used this to cross-compile
+Coq 8.4 from linux to win32 via mingw.
+
+Pierre Letouzey, june 2016
diff --git a/dev/doc/profiling.txt b/dev/doc/profiling.txt
new file mode 100644
index 000000000..9d2ebf0d4
--- /dev/null
+++ b/dev/doc/profiling.txt
@@ -0,0 +1,76 @@
+# How to profile Coq?
+
+I (Pierre-Marie Pédrot) mainly use two OCaml branches to profile Coq, whether I
+want to profile time or memory consumption. AFAIK, this only works for Linux.
+
+## Time
+
+In Coq source folder:
+
+opam switch 4.02.1+fp
+./configure -local -debug
+make
+perf record -g bin/coqtop -compile file.v
+perf report -g fractal,callee --no-children
+
+To profile only part of a file, first load it using
+
+bin/coqtop -l file.v
+
+and plug into the process
+
+perf record -g -p PID
+
+## Memory
+
+You first need a few commits atop trunk for this to work.
+
+git remote add ppedrot https://github.com/ppedrot/coq.git
+git fetch ppedrot
+git checkout ppedrot/allocation-profiling
+git rebase master
+
+Then:
+
+opam switch 4.00.1+alloc-profiling
+./configure -local -debug
+make
+
+Note that linking the coqtop binary takes quite an amount of time with this
+branch, so do not worry too much. There are more recent branches of
+alloc-profiling on mshinwell's repo which can be found at:
+
+https://github.com/mshinwell/opam-repo-dev
+
+### For memory dump:
+
+CAMLRUNPARAM=T,mj bin/coqtop -compile file.v
+
+In another terminal:
+
+pkill -SIGUSR1 $COQTOPPID
+...
+pkill -SIGUSR1 $COQTOPPID
+dev/decode-major-heap.sh heap.$COQTOPPID.$N bin/coqtop
+
+where $COQTOPPID is coqtop pid and $N the index of the call to pkill.
+
+First column is the memory taken by the objects (in words), second one is the
+number of objects and third is the place where the objects where allocated.
+
+### For complete memory graph:
+
+CAMLRUNPARAM=T,gr bin/coqtop -compile file.v
+
+In another terminal:
+
+pkill -SIGUSR1 $COQTOPPID
+...
+pkill -SIGUSR1 $COQTOPPID
+ocaml dev/decodegraph.ml edge.$COQTOPPID.$N bin/coqtop > memory.dot
+dot -Tpdf -o memory.pdf memory.dot
+
+where $COQTOPPID is coqtop pid and $N the index of the call to pkill.
+
+The pdf produced by the last command gives a compact graphical representation of
+the various objects allocated.
diff --git a/dev/doc/setup.txt b/dev/doc/setup.txt
new file mode 100644
index 000000000..1b016a4e2
--- /dev/null
+++ b/dev/doc/setup.txt
@@ -0,0 +1,289 @@
+This document provides detailed guidance on how to:
+- compile Coq
+- take advantage of Merlin in Emacs
+- enable auto-completion for Ocaml source-code
+- use ocamldebug in Emacs for debugging coqtop
+The instructions were tested with Debian 8.3 (Jessie).
+
+The procedure is somewhat tedious, but the final results are (still) worth the effort.
+
+How to compile Coq
+------------------
+
+Getting build dependencies:
+
+ sudo apt-get install make opam git mercurial darcs
+ opam init --comp 4.02.3
+ # Then follow the advice displayed at the end as how to update your ~/.bashrc and ~/.ocamlinit files.
+
+ source ~/.bashrc
+
+ # needed if you want to build "coqtop" target
+ opam install camlp5
+
+ # needed if you want to build "coqide" target
+ sudo apt-get install liblablgtksourceview2-ocaml-dev libgtk2.0-dev libgtksourceview2.0-dev
+ opam install lablgtk
+
+ # needed if you want to build "doc" target
+ sudo apt-get install texlive-latex-recommended texlive-fonts-extra texlive-math-extra \
+ hevea texlive-latex-extra latex-xcolor
+
+Cloning Coq:
+
+ # Go to the directory where you want to clone Coq's source-code. E.g.:
+ cd ~/git
+
+ git clone https://github.com/coq/coq.git
+
+Building coqtop:
+
+ cd ~/git/coq
+ git checkout trunk
+ make distclean
+ ./configure -annotate -with-doc no -local -debug -usecamlp5
+ make clean
+ make -j4 coqide printers
+
+The "-annotate" option is essential when one wants to use Merlin.
+
+The "-local" option is useful if one wants to run the coqtop and coqide binaries without running make install
+
+The "-debug" option is essential if one wants to use ocamldebug with the coqtop binary.
+
+Then check if
+- bin/coqtop
+- bin/coqide
+behave as expected.
+
+
+A note about rlwrap
+-------------------
+
+Running "coqtop" under "rlwrap" is possible, but there is a catch. If you try:
+
+ cd ~/git/coq
+ rlwrap bin/coqtop
+
+you will get an error:
+
+ rlwrap: error: Couldn't read completions from /usr/share/rlwrap/completions/coqtop: No such file or directory
+
+This is a known issue:
+
+ https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=779692
+
+It was fixed upstream in version 0.42, and in a Debian package that, at the time of writing, is not part of Debian stable/testing/sid archives but only of Debian experimental.
+
+ https://packages.debian.org/experimental/rlwrap
+
+The quick solution is to grab it from there, since it installs fine on Debian stable (jessie).
+
+ cd /tmp
+ wget http://ftp.us.debian.org/debian/pool/main/r/rlwrap/rlwrap_0.42-1_amd64.deb
+ sudo dpkg -i rlwrap_0.42-1_amd64.deb
+
+After that, "rlwrap" works fine with "coqtop".
+
+
+How to install and configure Merlin (for Emacs)
+-----------------------------------------------
+
+ sudo apt-get install emacs
+
+ opam install tuareg
+ # Follow the advice displayed at the end as how to update your ~/.emacs file.
+
+ opam install merlin
+ # Follow the advice displayed at the end as how to update your ~/.emacs file.
+
+Then add this:
+
+ (push "~/.opam/4.02.3/share/emacs/site-lisp" load-path) ; directory containing merlin.el
+ (setq merlin-command "~/.opam/4.02.3/bin/ocamlmerlin") ; needed only if ocamlmerlin not already in your PATH
+ (autoload 'merlin-mode "merlin" "Merlin mode" t)
+ (add-hook 'tuareg-mode-hook 'merlin-mode)
+ (add-hook 'caml-mode-hook 'merlin-mode)
+ (load "~/.opam/4.02.3/share/emacs/site-lisp/tuareg-site-file")
+
+ ;; Do not use TABs. These confuse Merlin.
+ (setq-default indent-tabs-mode nil)
+
+to your ~/.emacs file.
+
+Further Emacs configuration when we start it for the first time.
+
+Try to open some *.ml file in Emacs, e.g.:
+
+ cd ~/git/coq
+ emacs toplevel/coqtop.ml &
+
+Emacs display the following strange message:
+
+ The local variables list in ~/git/coq
+ contains values that may be safe (*).
+
+ Do you want to apply it?
+
+Just press "!", i.e. "apply the local variable list, and permanently mark these values (\*) as safe."
+
+Emacs then shows two windows:
+- one window that shows the contents of the "toplevel/coqtop.ml" file
+- and the other window that shows greetings for new Emacs users.
+
+If you do not want to see the second window next time you start Emacs, just check "Never show it again" and click on "Dismiss this startup screen."
+
+The default key-bindings are described here:
+
+ https://github.com/the-lambda-church/merlin/wiki/emacs-from-scratch
+
+If you want, you can customize them by replacing the following lines:
+
+ (define-key merlin-map (kbd "C-c C-x") 'merlin-error-next)
+ (define-key merlin-map (kbd "C-c C-l") 'merlin-locate)
+ (define-key merlin-map (kbd "C-c &") 'merlin-pop-stack)
+ (define-key merlin-map (kbd "C-c C-t") 'merlin-type-enclosing)
+
+in the file "~/.opam/4.02.3/share/emacs/site-lisp/merlin.el" with what you want.
+In the text below we assume that you changed the origin key-bindings in the following way:
+
+ (define-key merlin-map (kbd "C-n") 'merlin-error-next)
+ (define-key merlin-map (kbd "C-l") 'merlin-locate)
+ (define-key merlin-map (kbd "C-b") 'merlin-pop-stack)
+ (define-key merlin-map (kbd "C-t") 'merlin-type-enclosing)
+
+Now, when you press <Ctrl+L>, Merlin will show the definition of the symbol in a separate window.
+If you prefer to jump to the definition within the same window, do this:
+
+ <Alt+X> customize-group <ENTER> merlin <ENTER>
+
+ Merlin Locate In New Window
+
+ Value Menu
+
+ Never Open In New Window
+
+ State
+
+ Set For Future Sessions
+
+Testing (Merlin):
+
+ cd ~/git/coq
+ emacs toplevel/coqtop.ml &
+
+Go to the end of the file where you will see the "start" function.
+
+Go to a line where "init_toplevel" function is called.
+
+If you want to jump to the position where that function or datatype under the cursor is defined, press <Ctrl+L>.
+
+If you want to jump back, type: <Ctrl+B>
+
+If you want to learn the type of the value at current cursor's position, type: <Ctrl+T>
+
+
+Enabling auto-completion in emacs
+---------------------------------
+
+In Emacs, type: <Alt+M> list-packages <ENTER>
+
+In the list that is displayed, click on "company".
+
+A new window appears where just click on "Install" and then answer "Yes".
+
+These lines:
+
+ (package-initialize)
+ (require 'company)
+ ; Make company aware of merlin
+ (add-to-list 'company-backends 'merlin-company-backend)
+ ; Enable company on merlin managed buffers
+ (add-hook 'merlin-mode-hook 'company-mode)
+ (global-set-key [C-tab] 'company-complete)
+
+then need to be added to your "~/.emacs" file.
+
+Next time when you start emacs and partially type some identifier,
+emacs will offer the corresponding completions.
+Auto-completion can also be manually invoked by typing <Ctrl+TAB>.
+Description of various other shortcuts is here.
+
+ http://company-mode.github.io/
+
+
+Getting along with ocamldebug
+-----------------------------
+
+The default ocamldebug key-bindings are described here.
+
+ http://caml.inria.fr/pub/docs/manual-ocaml/debugger.html#sec369
+
+If you want, you can customize them by putting the following commands:
+
+ (global-set-key (kbd "<f5>") 'ocamldebug-break)
+ (global-set-key (kbd "<f6>") 'ocamldebug-run)
+ (global-set-key (kbd "<f7>") 'ocamldebug-next)
+ (global-set-key (kbd "<f8>") 'ocamldebug-step)
+ (global-set-key (kbd "<f9>") 'ocamldebug-finish)
+ (global-set-key (kbd "<f10>") 'ocamldebug-print)
+ (global-set-key (kbd "<f12>") 'camldebug)
+
+to your "~/.emacs" file.
+
+Let us try whether ocamldebug in Emacs works for us.
+(If necessary, re-)compile coqtop:
+
+ cd ~/git/coq
+ make -j4 coqide printers
+
+open Emacs:
+
+ emacs toplevel/coqtop.ml &
+
+and type:
+
+ <F12> ../bin/coqtop.byte <ENTER> ../dev/ocamldebug-coq <ENTER>
+
+As a result, a new window is open at the bottom where you should see:
+
+ (ocd)
+
+i.e. an ocamldebug shell.
+
+ 1. Switch to the window that contains the "coqtop.ml" file.
+ 2. Go to the end of the file.
+ 3. Find the definition of the "start" function.
+ 4. Go to the "let" keyword that is at the beginning of the first line.
+ 5. By pressing <F5> you set a breakpoint to the cursor's position.
+ 6. By pressing <F6> you start the bin/coqtop process.
+ 7. Then you can:
+ - step over function calls: <F7>
+ - step into function calls: <F8>
+ - or finish execution of the current function until it returns: <F9>.
+
+Other ocamldebug commands, can be typed to the window that holds the ocamldebug shell.
+
+The points at which the execution of Ocaml program can stop are defined here:
+
+ http://caml.inria.fr/pub/docs/manual-ocaml/debugger.html#sec350
+
+
+Installing printers to ocamldebug
+---------------------------------
+
+There is a pretty comprehensive set of printers defined for many common data types.
+You can load them by switching to the window holding the "ocamldebug" shell and typing:
+
+ (ocd) source "../dev/db"
+
+
+Some of the functions were you might want to set a breakpoint and see what happens next
+---------------------------------------------------------------------------------------
+
+- Coqtop.start : This function is called by the code produced by "coqmktop".
+- Coqtop.parse_args : This function is responsible for parsing command-line arguments.
+- Coqloop.loop : This function implements the read-eval-print loop.
+- Vernacentries.interp : This function is called to execute the Vernacular command user have typed.\
+ It dispatches the control to specific functions handling different Vernacular command.
+- Vernacentries.vernac_check_may_eval : This function handles the "Check ..." command.
diff --git a/dev/make-installer-win32.sh b/dev/make-installer-win32.sh
index d405e66cc..51d428dd1 100755
--- a/dev/make-installer-win32.sh
+++ b/dev/make-installer-win32.sh
@@ -16,7 +16,7 @@ if [ ! -e bin/make.exe ]; then
fi
VERSION=`grep ^VERSION= config/Makefile | cut -d = -f 2`
cd dev/nsis
-"$NSIS" -DVERSION=$VERSION -DGTK_RUNTIME="`cygpath -w $BASE`" coq.nsi
+"$NSIS" -DVERSION=$VERSION -DGTK_RUNTIME="`cygpath -w $BASE`" -DARCH="win32" coq.nsi
echo Installer:
ls -h $PWD/*exe
cd ../..
diff --git a/dev/make-installer-win64.sh b/dev/make-installer-win64.sh
index 2f765c1a1..438f4ae5b 100755
--- a/dev/make-installer-win64.sh
+++ b/dev/make-installer-win64.sh
@@ -22,7 +22,7 @@ if [ ! -e bin/make.exe ]; then
fi
VERSION=`grep ^VERSION= config/Makefile | cut -d = -f 2`
cd dev/nsis
-"$NSIS" -DVERSION=$VERSION -DGTK_RUNTIME="`cygpath -w $BASE`" coq.nsi
+"$NSIS" -DVERSION=$VERSION -DGTK_RUNTIME="`cygpath -w $BASE`" -DARCH="win64" coq.nsi
echo Installer:
ls -h $PWD/*exe
cd ../..
diff --git a/dev/make-macos-dmg.sh b/dev/make-macos-dmg.sh
index 20b7b5b53..b43ada907 100755
--- a/dev/make-macos-dmg.sh
+++ b/dev/make-macos-dmg.sh
@@ -28,4 +28,8 @@ codesign -f -s - $APP
mkdir -p $DMGDIR
ln -sf /Applications $DMGDIR/Applications
cp -r $APP $DMGDIR
+
+# Temporary countermeasure to hdiutil error 5341
+head -c9703424 /dev/urandom > $DMGDIR/.padding
+
hdiutil create -imagekey zlib-level=9 -volname CoqIDE_$VERSION -srcfolder $DMGDIR -ov -format UDZO CoqIDE_$VERSION.dmg
diff --git a/dev/nsis/coq.nsi b/dev/nsis/coq.nsi
index 676490510..80da84517 100755
--- a/dev/nsis/coq.nsi
+++ b/dev/nsis/coq.nsi
@@ -13,7 +13,7 @@ SetCompressor lzma
!define MY_PRODUCT "Coq" ;Define your own software name here
!define COQ_SRC_PATH "..\.."
-!define OUTFILE "coq-installer-${VERSION}.exe"
+!define OUTFILE "coq-installer-${VERSION}-${ARCH}.exe"
!include "MUI2.nsh"
!include "FileAssociation.nsh"
@@ -83,6 +83,7 @@ FunctionEnd
Section "Coq" Sec1
SetOutPath "$INSTDIR\"
+ File ${COQ_SRC_PATH}\LICENSE
SetOutPath "$INSTDIR\bin"
File ${COQ_SRC_PATH}\bin\*.exe
diff --git a/dev/ocamldebug-coq.run b/dev/ocamldebug-coq.run
index b00d084ed..f9310e076 100644
--- a/dev/ocamldebug-coq.run
+++ b/dev/ocamldebug-coq.run
@@ -20,7 +20,7 @@ exec $OCAMLDEBUG \
-I $COQTOP/library -I $COQTOP/engine \
-I $COQTOP/pretyping -I $COQTOP/parsing \
-I $COQTOP/interp -I $COQTOP/proofs -I $COQTOP/tactics -I $COQTOP/stm \
- -I $COQTOP/toplevel -I $COQTOP/dev -I $COQTOP/config \
+ -I $COQTOP/toplevel -I $COQTOP/dev -I $COQTOP/config -I $COQTOP/ltac \
-I $COQTOP/plugins/cc -I $COQTOP/plugins/dp \
-I $COQTOP/plugins/extraction -I $COQTOP/plugins/field \
-I $COQTOP/plugins/firstorder -I $COQTOP/plugins/fourier \
diff --git a/dev/printers.mllib b/dev/printers.mllib
index bb627f590..e39b78072 100644
--- a/dev/printers.mllib
+++ b/dev/printers.mllib
@@ -19,25 +19,28 @@ Pp_control
Loc
CList
CString
+Tok
Compat
Flags
Control
Loc
Serialize
Stateid
-Feedback
-Pp
-Segmenttree
-Unicodetable
-Unicode
CObj
CArray
CStack
Util
+Pp
Ppstyle
+Richpp
+Feedback
+Segmenttree
+Unicodetable
+Unicode
Errors
Bigint
CUnix
+Minisys
System
Envars
Aux_file
@@ -48,7 +51,7 @@ Rtree
Heap
Genarg
Stateid
-Ephemeron
+CEphemeron
Future
RemoteCounter
Monad
@@ -122,14 +125,16 @@ Evd
Sigma
Glob_ops
Redops
+Pretype_errors
+Evarutil
Reductionops
Inductiveops
Arguments_renaming
Nativenorm
Retyping
Cbv
-Pretype_errors
-Evarutil
+
+Evardefine
Evarsolve
Recordops
Evarconv
@@ -140,6 +145,11 @@ Find_subterm
Tacred
Classops
Typeclasses_errors
+Logic_monad
+Proofview_monad
+Proofview
+Ftactic
+Geninterp
Typeclasses
Detyping
Indrec
@@ -153,8 +163,7 @@ Library
States
Genprint
-Tok
-Lexer
+CLexer
Ppextend
Pputils
Ppannotation
@@ -174,24 +183,18 @@ Implicit_quantifiers
Constrintern
Modintern
Constrextern
-Proof_type
Goal
Miscprint
Logic
Refiner
Clenv
Evar_refiner
-Proof_errors
-Logic_monad
-Proofview_monad
-Proofview
+Refine
Proof
Proof_global
Pfedit
-Tactic_debug
Decl_mode
Ppconstr
-Entry
Pcoq
Printer
Pptactic
@@ -199,7 +202,6 @@ Ppdecl_proof
Egramml
Egramcoq
Tacsubst
-Tacenv
Trie
Dn
Btermdn
diff --git a/dev/tools/Makefile.common b/dev/tools/Makefile.common
deleted file mode 100644
index e69de29bb..000000000
--- a/dev/tools/Makefile.common
+++ /dev/null
diff --git a/dev/tools/anomaly-traces-parser.el b/dev/tools/anomaly-traces-parser.el
new file mode 100644
index 000000000..68f54266f
--- /dev/null
+++ b/dev/tools/anomaly-traces-parser.el
@@ -0,0 +1,28 @@
+;; This Elisp snippet adds a regexp parser for the format of Anomaly
+;; backtraces (coqc -bt ...), to the error parser of the Compilation
+;; mode (C-c C-c: "Compile command: ..."). Once the
+;; coq-change-error-alist-for-backtraces function has run, file
+;; locations in traces are recognized and can be jumped from easily
+;; from the *compilation* buffer.
+
+;; You can just copy everything below to your .emacs and this will be
+;; enabled from any compilation command launched from an OCaml file.
+
+(defun coq-change-error-alist-for-backtraces ()
+ "Hook to change the compilation-error-regexp-alist variable, to
+ search the coq backtraces for error locations"
+ (interactive)
+ (add-to-list
+ 'compilation-error-regexp-alist-alist
+ '(coq-backtrace
+ "^ *\\(?:raise\\|frame\\) @ file \\(\"?\\)\\([^,\" \n\t<>]+\\)\\1,\
+ lines? \\([0-9]+\\)-?\\([0-9]+\\)?\\(?:$\\|,\
+ \\(?: characters? \\([0-9]+\\)-?\\([0-9]+\\)?:?\\)?\\)"
+ 2 (3 . 4) (5 . 6)))
+ (add-to-list 'compilation-error-regexp-alist 'coq-backtrace))
+
+;; this Anomaly parser should be available when one is hacking
+;; on the *OCaml* code of Coq (adding bugs), so we enable it
+;; through the OCaml mode hooks.
+(add-hook 'caml-mode-hook 'coq-change-error-alist-for-backtraces)
+(add-hook 'tuareg-mode-hook 'coq-change-error-alist-for-backtraces)
diff --git a/dev/top_printers.ml b/dev/top_printers.ml
index aef9b10b2..6074acea4 100644
--- a/dev/top_printers.ml
+++ b/dev/top_printers.ml
@@ -29,7 +29,8 @@ let _ = set_bool_option_value ["Printing";"Matching"] false
let _ = Detyping.set_detype_anonymous (fun _ _ -> raise Not_found)
(* std_ppcmds *)
-let pppp x = pp x
+let pp x = Feedback.msg_notice x
+let pppp x = Feedback.msg_notice x
(** Future printer *)
@@ -315,7 +316,7 @@ let constr_display csr =
| Anonymous -> "Anonymous"
in
- Pp.pp (str (term_display csr) ++fnl ()); Pp.pp_flush ()
+ Feedback.msg_notice (str (term_display csr) ++fnl ())
open Format;;
@@ -467,8 +468,8 @@ let pp_generic_argument arg =
pp(str"<genarg:"++pr_argument_type(genarg_tag arg)++str">")
let prgenarginfo arg =
- let Val.Dyn (tag, _) = arg in
- let tpe = Val.repr tag in
+ let Geninterp.Val.Dyn (tag, _) = arg in
+ let tpe = Geninterp.Val.pr tag in
(** FIXME *)
(* try *)
(* let data = Pptactic.pr_top_generic (Global.env ()) arg in *)
@@ -486,9 +487,7 @@ let ppist ist =
(* Vernac-level debugging commands *)
let in_current_context f c =
- let (evmap,sign) =
- try Pfedit.get_current_goal_context ()
- with e when Logic.catchable_exception e -> (Evd.empty, Global.env()) in
+ let (evmap,sign) = Pfedit.get_current_context () in
f (fst (Constrintern.interp_constr sign evmap c))(*FIXME*)
(* We expand the result of preprocessing to be independent of camlp4
@@ -515,12 +514,12 @@ let _ =
(fun () -> in_current_context constr_display c)
| _ -> failwith "Vernac extension: cannot occur")
with
- e -> Pp.pp (Errors.print e)
+ e -> Feedback.msg_notice (Errors.print e)
let _ =
extend_vernac_command_grammar ("PrintConstr", 0) None
[GramTerminal "PrintConstr";
GramNonTerminal
- (Loc.ghost,rawwit wit_constr,Aentry (Entry.unsafe_of_name ("constr","constr")))]
+ (Loc.ghost,rawwit wit_constr,Extend.Aentry Pcoq.Constr.constr)]
let _ =
try
@@ -531,12 +530,12 @@ let _ =
(fun () -> in_current_context print_pure_constr c)
| _ -> failwith "Vernac extension: cannot occur")
with
- e -> Pp.pp (Errors.print e)
+ e -> Feedback.msg_notice (Errors.print e)
let _ =
extend_vernac_command_grammar ("PrintPureConstr", 0) None
[GramTerminal "PrintPureConstr";
GramNonTerminal
- (Loc.ghost,rawwit wit_constr,Aentry (Entry.unsafe_of_name ("constr","constr")))]
+ (Loc.ghost,rawwit wit_constr,Extend.Aentry Pcoq.Constr.constr)]
(* Setting printer of unbound global reference *)
open Names
diff --git a/dev/vm_printers.ml b/dev/vm_printers.ml
index 1c501df80..afa94a63e 100644
--- a/dev/vm_printers.ml
+++ b/dev/vm_printers.ml
@@ -79,7 +79,7 @@ and ppwhd whd =
| Vatom_stk(a,s) ->
open_hbox();ppatom a;close_box();
print_string"@";ppstack s
- | Vuniv_level lvl -> Pp.pp (Univ.Level.pr lvl)
+ | Vuniv_level lvl -> Feedback.msg_notice (Univ.Level.pr lvl)
and ppvblock b =
open_hbox();
diff --git a/doc/common/macros.tex b/doc/common/macros.tex
index 077e2f0df..df5ee405f 100644
--- a/doc/common/macros.tex
+++ b/doc/common/macros.tex
@@ -406,8 +406,8 @@
\newcommand{\Ind}[4]{\mbox{{\sf Ind}$[#2](\begin{array}[t]{@{}l@{}}#3:=#4
\,)\end{array}$}}
%END LATEX
-%HEVEA \newcommand{\NInd}[3]{\mbox{{\sf Ind}$(#1)(#2:=#3\,)$}}
-%HEVEA \newcommand{\Ind}[4]{\mbox{{\sf Ind}$(#1)[#2](#3:=#4\,)$}}
+%HEVEA \newcommand{\NInd}[3]{\mbox{{\sf Ind}$(#2\,:=\,#3)$}}
+%HEVEA \newcommand{\Ind}[4]{\mbox{{\sf Ind}$[#2](#3\,:=\,#4)$}}
\newcommand{\Indp}[5]{\mbox{{\sf Ind}$_{#5}(#1)[#2](\begin{array}[t]{@{}l}#3:=#4
\,)\end{array}$}}
diff --git a/doc/refman/AsyncProofs.tex b/doc/refman/AsyncProofs.tex
index 7cf500400..7ffe25225 100644
--- a/doc/refman/AsyncProofs.tex
+++ b/doc/refman/AsyncProofs.tex
@@ -46,6 +46,43 @@ 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.
+\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''.
+
\subsubsection{Automatic suggestion of proof annotations}
The command \texttt{Set Suggest Proof Using} makes Coq suggest, when a
@@ -85,6 +122,9 @@ 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.
+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
diff --git a/doc/refman/CanonicalStructures.tex b/doc/refman/CanonicalStructures.tex
index a3372c296..275e1c2d5 100644
--- a/doc/refman/CanonicalStructures.tex
+++ b/doc/refman/CanonicalStructures.tex
@@ -4,7 +4,7 @@
\label{CS-full}
\index{Canonical Structures!presentation}
-This chapter explains the basics of Canonical Structure and how thy can be used
+\noindent This chapter explains the basics of Canonical Structure and how they can be used
to overload notations and build a hierarchy of algebraic structures.
The examples are taken from~\cite{CSwcu}. We invite the interested reader
to refer to this paper for all the details that are omitted here for brevity.
diff --git a/doc/refman/RefMan-cic.tex b/doc/refman/RefMan-cic.tex
index 1554ee04d..b9c17d814 100644
--- a/doc/refman/RefMan-cic.tex
+++ b/doc/refman/RefMan-cic.tex
@@ -544,32 +544,109 @@ $\forall\Gamma_P, T^\prime$ where $\Gamma_P$ is called the {\em context of param
\def\colon{@{\hskip.5em:\hskip.5em}}
The declaration for parameterized lists is:
+\begin{latexonly}
\vskip.5em
-\ind{1}{\List:\Set\ra\Set}{\left[\begin{array}{r \colon l}
- \Nil & \forall A:\Set,\List~A \\
- \cons & \forall A:\Set, A \ra \List~A \ra \List~A
- \end{array}\right]}
+\ind{1}{[\List:\Set\ra\Set]}{\left[\begin{array}{r \colon l}
+ \Nil & \forall A:\Set,\List~A \\
+ \cons & \forall A:\Set, A \ra \List~A \ra \List~A
+ \end{array}
+ \right]}
\vskip.5em
-
-which corresponds to the result of the \Coq\ declaration:
+\end{latexonly}
+\begin{rawhtml}<pre><table style="border-spacing:0">
+ <tr style="vertical-align:middle">
+ <td style="width:10pt;text-align:center;font-family:sans-serif;font-style:italic">Ind</td>
+ <td style="width:20pt;text-align:center">[1]</td>
+ <td style="width:5pt;text-align:center">⎛<br>⎝</td>
+ <td style="width:120pt;text-align:center">[ <span style="font-family:monospace">list : Set → Set</span> ]</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:=</td>
+ <td style="width:10pt;text-align:center">⎡<br>⎣</td>
+ <td>
+ <table style="border-spacing:0">
+ <tr>
+ <td style="width:20pt;text-align:right;font-family:monospace">nil</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:=</td>
+ <td style="text-align:left;font-family:monospace">∀A : Set, list A</td>
+ </tr>
+ <tr>
+ <td style="width:20pt;text-align:right;font-family:monospace">cons</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:=</td>
+ <td style="text-align:left;font-family:monospace">∀A : Set, A → list A → list A</td>
+ </tr>
+ </table>
+ </td>
+ <td style="width:10pt;text-align:center">⎤<br>⎦</td>
+ <td style="width:5pt;text-align:center">⎞<br>⎠</td>
+ </tr>
+</table></pre>
+\end{rawhtml}
+\noindent which corresponds to the result of the \Coq\ declaration:
\begin{coq_example*}
Inductive list (A:Set) : Set :=
| nil : list A
| cons : A -> list A -> list A.
\end{coq_example*}
-The declaration for a mutual inductive definition of forests and trees is:
+\noindent The declaration for a mutual inductive definition of {\tree} and {\forest} is:
+\begin{latexonly}
\vskip.5em
-\ind{}{\left[\begin{array}{r \colon l}\tree&\Set\\\forest&\Set\end{array}\right]}
- {\left[\begin{array}{r \colon l}
- \node & \forest \ra \tree\\
- \emptyf & \forest\\
- \consf & \tree \ra \forest \ra \forest\\
- \end{array}\right]}
+\ind{~}{\left[\begin{array}{r \colon l}\tree&\Set\\\forest&\Set\end{array}\right]}
+ {\left[\begin{array}{r \colon l}
+ \node & \forest \ra \tree\\
+ \emptyf & \forest\\
+ \consf & \tree \ra \forest \ra \forest\\
+ \end{array}\right]}
\vskip.5em
-
-which corresponds to the result of the \Coq\
+\end{latexonly}
+\begin{rawhtml}<pre><table style="border-spacing:0">
+ <tr style="vertical-align:middle">
+ <td style="width:10pt;text-align:center;font-family:sans-serif;font-style:italic">Ind</td>
+ <td style="width:20pt;text-align:center">[1]</td>
+ <td style="width:5pt;text-align:center">⎛<br>⎜<br>⎝</td>
+ <td style="width:10pt;text-align:center">⎡<br>⎣</td>
+ <td>
+ <table style="border-spacing:0">
+ <tr>
+ <td style="width:20pt;text-align:right;font-family:monospace">tree</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:</td>
+ <td style="text-align:left;font-family:monospace">Set</td>
+ </tr>
+ <tr>
+ <td style="width:20pt;text-align:right;font-family:monospace">forest</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:</td>
+ <td style="text-align:left;font-family:monospace">Set</td>
+ </tr>
+ </table>
+ </td>
+ <td style="width:10pt;text-align:center">⎤<br>⎦</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:=</td>
+ <td style="width:10pt;text-align:center">⎡<br>⎢<br>⎣</td>
+ <td>
+ <table style="border-spacing:0">
+ <tr>
+ <td style="width:20pt;text-align:right;font-family:monospace">node</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:</td>
+ <td style="text-align:left;font-family:monospace">forest → tree</td>
+ </tr>
+ <tr>
+ <td style="width:20pt;text-align:right;font-family:monospace">emptyf</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:</td>
+ <td style="text-align:left;font-family:monospace">forest</td>
+ </tr>
+ <tr>
+ <td style="width:20pt;text-align:right;font-family:monospace">consf</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:</td>
+ <td style="text-align:left;font-family:monospace">tree → forest → forest</td>
+ </tr>
+ </table>
+ </td>
+ <td style="width:10pt;text-align:center">⎤<br>⎥<br>⎦</td>
+ <td style="width:5pt;text-align:center">⎞<br>⎟<br>⎠</td>
+ </tr>
+</table></pre>
+\end{rawhtml}
+\noindent which corresponds to the result of the \Coq\
declaration:
\begin{coq_example*}
Inductive tree : Set :=
@@ -579,7 +656,8 @@ with forest : Set :=
| consf : tree -> forest -> forest.
\end{coq_example*}
-The declaration for a mutual inductive definition of even and odd is:
+\noindent The declaration for a mutual inductive definition of {\even} and {\odd} is:
+\begin{latexonly}
\newcommand\GammaI{\left[\begin{array}{r \colon l}
\even & \nat\ra\Prop \\
\odd & \nat\ra\Prop
@@ -594,7 +672,55 @@ The declaration for a mutual inductive definition of even and odd is:
\vskip.5em
\ind{1}{\GammaI}{\GammaC}
\vskip.5em
-which corresponds to the result of the \Coq\
+\end{latexonly}
+\begin{rawhtml}<pre><table style="border-spacing:0">
+ <tr style="vertical-align:middle">
+ <td style="width:10pt;text-align:center;font-family:sans-serif;font-style:italic">Ind</td>
+ <td style="width:20pt;text-align:center">[1]</td>
+ <td style="width:5pt;text-align:center">⎛<br>⎜<br>⎝</td>
+ <td style="width:10pt;text-align:center">⎡<br>⎣</td>
+ <td>
+ <table style="border-spacing:0">
+ <tr>
+ <td style="width:20pt;text-align:right;font-family:monospace">even</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:</td>
+ <td style="text-align:left;font-family:monospace">nat → Prop</td>
+ </tr>
+ <tr>
+ <td style="width:20pt;text-align:right;font-family:monospace">odd</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:</td>
+ <td style="text-align:left;font-family:monospace">nat → Prop</td>
+ </tr>
+ </table>
+ </td>
+ <td style="width:10pt;text-align:center">⎤<br>⎦</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:=</td>
+ <td style="width:10pt;text-align:center">⎡<br>⎢<br>⎣</td>
+ <td>
+ <table style="border-spacing:0">
+ <tr>
+ <td style="width:20pt;text-align:right;font-family:monospace">even_O</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:</td>
+ <td style="text-align:left;font-family:monospace">even O</td>
+ </tr>
+ <tr>
+ <td style="width:20pt;text-align:right;font-family:monospace">even_S</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:</td>
+ <td style="text-align:left;font-family:monospace">∀n : nat, odd n → even (S n)</td>
+ </tr>
+ <tr>
+ <td style="width:20pt;text-align:right;font-family:monospace">odd_S</td>
+ <td style="width:20pt;text-align:center;font-family:monospace">:</td>
+ <td style="text-align:left;font-family:monospace">∀n : nat, even n → odd (S n)</td>
+ </tr>
+ </table>
+ </td>
+ <td style="width:10pt;text-align:center">⎤<br>⎥<br>⎦</td>
+ <td style="width:5pt;text-align:center">⎞<br>⎟<br>⎠</td>
+ </tr>
+</table></pre>
+\end{rawhtml}
+\noindent which corresponds to the result of the \Coq\
declaration:
\begin{coq_example*}
Inductive even : nat -> Prop :=
@@ -610,9 +736,9 @@ contains an inductive declaration.
\begin{description}
\item[Ind] \index{Typing rules!Ind}
- \inference{\frac{\WFE{\Gamma}\hskip2em\Ind{}{p}{\Gamma_I}{\Gamma_C} \in E\hskip2em(a:A)\in\Gamma_I}{\WTEG{a}{A}}}
+ \inference{\frac{\WFE{\Gamma}~~~~~~~~\Ind{}{p}{\Gamma_I}{\Gamma_C} \in E~~~~~~~~(a:A)\in\Gamma_I}{\WTEG{a}{A}}}
\item[Constr] \index{Typing rules!Constr}
- \inference{\frac{\WFE{\Gamma}\hskip2em\Ind{}{p}{\Gamma_I}{\Gamma_C} \in E\hskip2em(c:C)\in\Gamma_C}{\WTEG{c}{C}}}
+ \inference{\frac{\WFE{\Gamma}~~~~~~~~\Ind{}{p}{\Gamma_I}{\Gamma_C} \in E~~~~~~~~(c:C)\in\Gamma_C}{\WTEG{c}{C}}}
\end{description}
\begin{latexonly}%
@@ -726,19 +852,16 @@ any $u_i$
the type $V$ satisfies the nested positivity condition for $X$
\end{itemize}
-%% \begin{latexonly}%
- \newcommand\vv{\textSFxi} % │
- \newcommand\hh{\textSFx} % ─
- \newcommand\vh{\textSFviii} % ├
- \newcommand\hv{\textSFii} % └
- \newlength\framecharacterwidth
- \settowidth\framecharacterwidth{\hh}
- \newcommand\ws{\hbox{}\hskip\the\framecharacterwidth}
- \newcommand\ruleref[1]{\hskip.25em\dots\hskip.2em{\em (bullet #1)}}
-%% \def\captionstrut{\vbox to 1.5em{}}
+\newcommand\vv{\textSFxi} % │
+\newcommand\hh{\textSFx} % ─
+\newcommand\vh{\textSFviii} % ├
+\newcommand\hv{\textSFii} % └
+\newlength\framecharacterwidth
+\settowidth\framecharacterwidth{\hh}
+\newcommand\ws{\hbox{}\hskip\the\framecharacterwidth}
+\newcommand\ruleref[1]{\hskip.25em\dots\hskip.2em{\em (bullet #1)}}
-%% \begin{figure}[H]
-For instance, if one considers the type
+\noindent For instance, if one considers the type
\begin{verbatim}
Inductive tree (A:Type) : Type :=
@@ -746,29 +869,49 @@ Inductive tree (A:Type) : Type :=
| node : A -> (nat -> tree A) -> tree A
\end{verbatim}
-Then every instantiated constructor of $\ListA$ satisfies the nested positivity condition for $\List$
-
+\begin{latexonly}
+\noindent Then every instantiated constructor of $\ListA$ satisfies the nested positivity condition for $\List$\\
\noindent
- \ws\ws\ws\ws\vv\\
- \ws\ws\ws\ws\vh\hh\ws concerning type $\ListA$ of constructor $\Nil$:\\
- \ws\ws\ws\ws\vv\ws\ws\ws\ws Type $\ListA$ of constructor $\Nil$ satisfies the positivity condition for $\List$\\
- \ws\ws\ws\ws\vv\ws\ws\ws\ws because $\List$ does not appear in any (real) arguments of the type of that constructor\\
- \ws\ws\ws\ws\vv\ws\ws\ws\ws (primarily because $\List$ does not have any (real) arguments)\ruleref1\\
- \ws\ws\ws\ws\vv\\
- \ws\ws\ws\ws\hv\hh\ws concerning type $\forall~A\ra\ListA\ra\ListA$ of constructor $\cons$:\\
- \ws\ws\ws\ws\ws\ws\ws\ws\ws Type $\forall~A:\Type,A\ra\ListA\ra\ListA$ of constructor $\cons$\\
- \ws\ws\ws\ws\ws\ws\ws\ws\ws satisfies the positivity condition for $\List$ because:\\
- \ws\ws\ws\ws\ws\ws\ws\ws\ws\vv\\
- \ws\ws\ws\ws\ws\ws\ws\ws\ws\vh\hh\ws $\List$ occurs only strictly positively in $\Type$\ruleref3\\
- \ws\ws\ws\ws\ws\ws\ws\ws\ws\vv\\
- \ws\ws\ws\ws\ws\ws\ws\ws\ws\vh\hh\ws $\List$ occurs only strictly positively in $A$\ruleref3\\
- \ws\ws\ws\ws\ws\ws\ws\ws\ws\vv\\
- \ws\ws\ws\ws\ws\ws\ws\ws\ws\vh\hh\ws $\List$ occurs only strictly positively in $\ListA$\ruleref4\\
- \ws\ws\ws\ws\ws\ws\ws\ws\ws\vv\\
- \ws\ws\ws\ws\ws\ws\ws\ws\ws\hv\hh\ws $\List$ satisfies the positivity condition for $\ListA$\ruleref1
-%% \caption{\captionstrut A proof that $X$ occurs strictly positively in $\ListA$}
-%% \end{figure}
-%% \end{latexonly}%
+\ws\ws\vv\\
+\ws\ws\vh\hh\ws concerning type $\ListA$ of constructor $\Nil$:\\
+\ws\ws\vv\ws\ws\ws\ws Type $\ListA$ of constructor $\Nil$ satisfies the positivity condition for $\List$\\
+\ws\ws\vv\ws\ws\ws\ws because $\List$ does not appear in any (real) arguments of the type of that constructor\\
+\ws\ws\vv\ws\ws\ws\ws (primarily because $\List$ does not have any (real) arguments)\ruleref1\\
+\ws\ws\vv\\
+\ws\ws\hv\hh\ws concerning type $\forall~A\ra\ListA\ra\ListA$ of constructor $\cons$:\\
+\ws\ws\ws\ws\ws\ws\ws Type $\forall~A:\Type,A\ra\ListA\ra\ListA$ of constructor $\cons$\\
+\ws\ws\ws\ws\ws\ws\ws satisfies the positivity condition for $\List$ because:\\
+\ws\ws\ws\ws\ws\ws\ws\vv\\
+\ws\ws\ws\ws\ws\ws\ws\vh\hh\ws $\List$ occurs only strictly positively in $\Type$\ruleref3\\
+\ws\ws\ws\ws\ws\ws\ws\vv\\
+\ws\ws\ws\ws\ws\ws\ws\vh\hh\ws $\List$ occurs only strictly positively in $A$\ruleref3\\
+\ws\ws\ws\ws\ws\ws\ws\vv\\
+\ws\ws\ws\ws\ws\ws\ws\vh\hh\ws $\List$ occurs only strictly positively in $\ListA$\ruleref4\\
+\ws\ws\ws\ws\ws\ws\ws\vv\\
+\ws\ws\ws\ws\ws\ws\ws\hv\hh\ws $\List$ satisfies the positivity condition for $\ListA$\ruleref1
+\end{latexonly}
+\begin{rawhtml}
+<pre>
+<span style="font-family:serif">Then every instantiated constructor of <span style="font-family:monospace">list A</span> satisfies the nested positivity condition for <span style="font-family:monospace">list</span></span>
+ │
+ ├─ <span style="font-family:serif">concerning type <span style="font-family:monospace">list A</span> of constructor <span style="font-family:monospace">nil</span>:</span>
+ │ <span style="font-family:serif">Type <span style="font-family:monospace">list A</span> of constructor <span style="font-family:monospace">nil</span> satisfies the positivity condition for <span style="font-family:monospace">list</span></span>
+ │ <span style="font-family:serif">because <span style="font-family:monospace">list</span> does not appear in any (real) arguments of the type of that constructor</span>
+ │ <span style="font-family:serif">(primarily because list does not have any (real) arguments) ... <span style="font-style:italic">(bullet 1)</span></span>
+ │
+ ╰─ <span style="font-family:serif">concerning type <span style="font-family:monospace">∀ A → list A → list A</span> of constructor <span style="font-family:monospace">cons</span>:</span>
+ <span style="font-family:serif">Type <span style="font-family:monospace">∀ A : Type, A → list A → list A</span> of constructor <span style="font-family:monospace">cons</span></span>
+ <span style="font-family:serif">satisfies the positivity condition for <span style="font-family:monospace">list</span> because:</span>
+ │
+ ├─ <span style="font-family:serif"><span style="font-family:monospace">list</span> occurs only strictly positively in <span style="font-family:monospace">Type</span> ... <span style="font-style:italic">(bullet 3)</span></span>
+ │
+ ├─ <span style="font-family:serif"><span style="font-family:monospace">list</span> occurs only strictly positively in <span style="font-family:monospace">A</span> ... <span style="font-style:italic">(bullet 3)</span></span>
+ │
+ ├─ <span style="font-family:serif"><span style="font-family:monospace">list</span> occurs only strictly positively in <span style="font-family:monospace">list A</span> ... <span style="font-style:italic">(bullet 4)</span></span>
+ │
+ ╰─ <span style="font-family:serif"><span style="font-family:monospace">list</span> satisfies the positivity condition for <span style="font-family:monospace">list A</span> ... <span style="font-style:italic">(bullet 1)</span></span>
+</pre>
+\end{rawhtml}
\paragraph{Correctness rules.}
We shall now describe the rules allowing the introduction of a new
@@ -783,7 +926,7 @@ inductive definition.
\inference{
\frac{
(\WTE{\Gamma_P}{A_j}{s'_j})_{j=1\ldots k}
- ~~ (\WTE{\Gamma_I;\Gamma_P}{C_i}{s_{q_i}})_{i=1\ldots n}
+ ~~~~~~~~ (\WTE{\Gamma_I;\Gamma_P}{C_i}{s_{q_i}})_{i=1\ldots n}
}
{\WF{E;\Ind{}{p}{\Gamma_I}{\Gamma_C}}{\Gamma}}}
provided that the following side conditions hold:
@@ -811,23 +954,23 @@ inductive definition.
The following declaration introduces the second-order existential
quantifier $\exists X.P(X)$.
\begin{coq_example*}
-Inductive exProp (P:Prop->Prop) : Prop
- := exP_intro : forall X:Prop, P X -> exProp P.
+Inductive exProp (P:Prop->Prop) : Prop :=
+ exP_intro : forall X:Prop, P X -> exProp P.
\end{coq_example*}
The same definition on \Set{} is not allowed and fails:
% (********** The following is not correct and should produce **********)
% (*** Error: Large non-propositional inductive types must be in Type***)
\begin{coq_example}
-Fail Inductive exSet (P:Set->Prop) : Set
- := exS_intro : forall X:Set, P X -> exSet P.
+Fail Inductive exSet (P:Set->Prop) : Set :=
+ exS_intro : forall X:Set, P X -> exSet P.
\end{coq_example}
It is possible to declare the same inductive definition in the
universe \Type.
The \texttt{exType} inductive definition has type $(\Type_i \ra\Prop)\ra
\Type_j$ with the constraint that the parameter \texttt{X} of \texttt{exT\_intro} has type $\Type_k$ with $k<j$ and $k\leq i$.
\begin{coq_example*}
-Inductive exType (P:Type->Prop) : Type
- := exT_intro : forall X:Type, P X -> exType P.
+Inductive exType (P:Type->Prop) : Type :=
+ exT_intro : forall X:Type, P X -> exType P.
\end{coq_example*}
%We shall assume for the following definitions that, if necessary, we
%annotated the type of constructors such that we know if the argument
diff --git a/doc/refman/RefMan-ltac.tex b/doc/refman/RefMan-ltac.tex
index cc7e6b53b..ffcb37134 100644
--- a/doc/refman/RefMan-ltac.tex
+++ b/doc/refman/RefMan-ltac.tex
@@ -78,7 +78,7 @@ For instance
{\tt try repeat \tac$_1$ ||
\tac$_2$;\tac$_3$;[\tac$_{31}$|\dots|\tac$_{3n}$];\tac$_4$.}
\end{quote}
-is understood as
+is understood as
\begin{quote}
{\tt (try (repeat (\tac$_1$ || \tac$_2$)));} \\
{\tt ((\tac$_3$;[\tac$_{31}$|\dots|\tac$_{3n}$]);\tac$_4$).}
@@ -174,7 +174,7 @@ is understood as
\\
{\messagetoken}\!\!\!\!\!\! & ::= & {\qstring} ~|~ {\ident} ~|~ {\integer} \\
\\
-\tacarg & ::= &
+\tacarg & ::= &
{\qualid}\\
& $|$ & {\tt ()} \\
& $|$ & {\tt ltac :} {\atom}\\
@@ -344,7 +344,7 @@ for $=1,...,n$. It fails if the number of focused goals is not exactly $n$.
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 ]}
+ \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
@@ -782,7 +782,7 @@ setting option {\tt Printing All}, see Section~\ref{SetPrintingAll}).
\begin{coq_example}
Ltac f x :=
match x with
- context f [S ?X] =>
+ 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 *)
@@ -1026,7 +1026,7 @@ Reset Initial.
\index{Tacticals!abstract@{\tt abstract}}}
From the outside ``\texttt{abstract \tacexpr}'' is the same as
-{\tt solve \tacexpr}. Internally it saves an auxiliary lemma called
+{\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 auxiliary lemma is inlined in the final proof term
@@ -1116,6 +1116,8 @@ Defined {\ltac} functions can be displayed using the command
{\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}}
@@ -1194,6 +1196,86 @@ 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}
+
+\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 Profile}.
+\end{quote}
+Resets the profile, that is, deletes all accumulated 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}
+
+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.
+
\endinput
\subsection{Permutation on closed lists}
@@ -1227,7 +1309,7 @@ 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}
@@ -1553,7 +1635,7 @@ Figure~\ref{isoslem} gives examples of what can be solved by {\tt IsoProve}.
\begin{center}
\fbox{\begin{minipage}{0.95\textwidth}
\begin{coq_example*}
-Lemma isos_ex1 :
+Lemma isos_ex1 :
forall A B:Set, A * unit * B = B * (unit * A).
Proof.
intros; IsoProve.
@@ -1573,7 +1655,7 @@ Qed.
\label{isoslem}
\end{figure}
-%%% Local Variables:
+%%% Local Variables:
%%% mode: latex
%%% TeX-master: "Reference-Manual"
-%%% End:
+%%% End:
diff --git a/doc/refman/RefMan-syn.tex b/doc/refman/RefMan-syn.tex
index aabc8a899..1f08b6a2f 100644
--- a/doc/refman/RefMan-syn.tex
+++ b/doc/refman/RefMan-syn.tex
@@ -358,7 +358,7 @@ state of {\Coq}.
Reserved Notation "x = y" (at level 70, no associativity).
\end{coq_example}
-Reserving a notation is also useful for simultaneously defined an
+Reserving a notation is also useful for simultaneously defining an
inductive type or a recursive constant and a notation for it.
\Rem The notations mentioned on Figure~\ref{init-notations} are
@@ -860,11 +860,11 @@ statically. For instance, if {\tt f} is a polymorphic function of type
{\scope}, then {\tt a} of type {\tt t} in {\tt f~t~a} is not
recognized as an argument to be interpreted in scope {\scope}.
-\comindex{Bind Scope}
-Any global reference can be bound by default to an
-interpretation scope. The command to do it is
+\comindex{Bind Scope}
+More generally, any {\class} (see Chapter~\ref{Coercions-full}) can be
+bound to an interpretation scope. The command to do it is
\begin{quote}
-{\tt Bind Scope} {\scope} \texttt{with} {\qualid}
+{\tt Bind Scope} {\scope} \texttt{with} {\class}
\end{quote}
\Example
diff --git a/doc/refman/RefMan-tac.tex b/doc/refman/RefMan-tac.tex
index edf986392..54450fe7d 100644
--- a/doc/refman/RefMan-tac.tex
+++ b/doc/refman/RefMan-tac.tex
@@ -2833,42 +2833,57 @@ This tactic is deprecated. It can be replaced by {\tt enough}
\tacindex{subst}
\optindex{Regular Subst Tactic}
-This tactic applies to a goal that has \ident\ in its context and
-(at least) one hypothesis, say {\tt H}, of type {\tt
- \ident=t} or {\tt t=\ident}. Then it replaces
-\ident\ by {\tt t} everywhere in the goal (in the hypotheses
-and in the conclusion) and clears \ident\ and {\tt H} from the context.
+This tactic applies to a goal that has \ident\ in its context and (at
+least) one hypothesis, say $H$, of type {\tt \ident} = $t$ or $t$
+{\tt = \ident} with {\ident} not occurring in $t$. Then it replaces
+{\ident} by $t$ everywhere in the goal (in the hypotheses and in the
+conclusion) and clears {\ident} and $H$ from the context.
+
+If {\ident} is a local definition of the form {\ident} := $t$, it is
+also unfolded and cleared.
+
+\Rem
+When several hypotheses have the form {\tt \ident} = $t$ or {\tt
+ $t$ = \ident}, the first one is used.
\Rem
-When several hypotheses have the form {\tt \ident=t} or {\tt
- t=\ident}, the first one is used.
+If $H$ is itself dependent in the goal, it is replaced by the
+proof of reflexivity of equality.
\begin{Variants}
- \item {\tt subst \ident$_1$ \dots \ident$_n$}
+ \item {\tt subst \ident$_1$ {\dots} \ident$_n$}
- Is equivalent to {\tt subst \ident$_1$; \dots; subst \ident$_n$}.
+ This is equivalent to {\tt subst \ident$_1$; \dots; subst \ident$_n$}.
\item {\tt subst}
- Applies {\tt subst} repeatedly to all identifiers from the context
- for which an equality exists.
+ This applies {\tt subst} repeatedly from top to bottom to all
+ identifiers of the context for which an equality of the form {\tt
+ \ident} = $t$ or $t$ {\tt = \ident} or {\tt \ident} := $t$ exists, with
+ {\ident} not occurring in $t$.
-\noindent {\bf Remark: } The behavior of {\tt subst} can be controlled using option {\tt Set
- Regular Subst Tactic}. When this option is activated, {\tt subst}
- manages the following corner cases which otherwise it
- does not:
+\noindent {\bf Remark: } The behavior of {\tt subst} can be controlled
+using option {\tt Set Regular Subst Tactic}. When this option is
+activated, {\tt subst} also deals with the following corner cases:
\begin{itemize}
\item A context with ordered hypotheses {\tt \ident$_1$ = \ident$_2$}
and {\tt \ident$_1$ = $t$}, or {$t'$ = \ident$_1$} with $t'$ not a
variable, and no other hypotheses of the form {\tt \ident$_2$ = $u$}
- or {\tt $u$ = \ident$_2$}
+ or {\tt $u$ = \ident$_2$}; without the option, a second call to {\tt
+ subst} would be necessary to replace {\ident$_2$} by $t$ or $t'$
+ respectively.
+
\item A context with cyclic dependencies as with hypotheses {\tt
- \ident$_1$ = f~\ident$_2$} and {\tt \ident$_2$ = g~\ident$_1$}
+ \ident$_1$ = f~\ident$_2$} and {\tt \ident$_2$ = g~\ident$_1$} which
+ without the option would be a cause of failure of {\tt subst}.
\end{itemize}
-Additionally, it prevents a local definition such as {\tt \ident :=
- $t$} to be unfolded which otherwise it would exceptionally unfold in
+Additionally, it prevents a local definition such as {\tt \ident} :=
+ $t$ to be unfolded which otherwise it would exceptionally unfold in
configurations containing hypotheses of the form {\tt {\ident} = $u$},
or {\tt $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.
\end{Variants}
@@ -3648,9 +3663,6 @@ The {\hintdef} is one of the following expressions:
the number of subgoals generated by {\tt simple apply {\term}}.
%{\tt auto} actually uses a slightly modified variant of {\tt simple apply} with use_metas_eagerly_in_conv_on_closed_terms set to false
- The cost of that hint is the number of subgoals generated by that
- tactic.
-
% Is it really needed?
%% In case the inferred type of \term\ does not start with a product
%% the tactic added in the hint list is {\tt exact {\term}}. In case
@@ -3848,7 +3860,25 @@ is to set the cut expression to $c | e$, the initial cut expression
being \texttt{emp}.
+\item \texttt{Mode} {\tt (+ | -)}$^*$ {\qualid}
+\label{HintMode}
+\comindex{Hint Mode}
+This sets an optional mode of use of the identifier {\qualid}. When
+proof-search faces a goal that ends in an application of {\qualid} to
+arguments {\tt \term$_1$ \mbox{\dots} \term$_n$}, the mode tells if the
+hints associated to qualid can be applied or not. A mode specification
+is a list of $n$ {\tt +} or {\tt -} items that specify if an argument is
+to be treated as an input {\tt +} or an output {\tt -} of the
+identifier. For a mode to match a list of arguments, input terms \emph{must
+not} contain existential variables, 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.
+
+{\tt 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.
\end{itemize}
@@ -3856,25 +3886,6 @@ being \texttt{emp}.
pattern-matching on hypotheses using \texttt{match goal with} inside
the tactic.
-\begin{Variants}
-\item {\tt Hint \hintdef}
-
- No database name is given: the hint is registered in the {\tt core}
- database.
-
-\item {\tt Hint Local {\hintdef} : \ident$_1$ \mbox{\dots} \ident$_n$}
-
- 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 {\tt Local} is useless since hints do not
- survive anyway to the closure of sections.
-
-\item {\tt Hint Local \hintdef}
-
- Idem for the {\tt core} database.
-
-\end{Variants}
-
% There are shortcuts that allow to define several goal at once:
% \begin{itemize}
diff --git a/doc/refman/Universes.tex b/doc/refman/Universes.tex
index a08cd1475..36518e6fa 100644
--- a/doc/refman/Universes.tex
+++ b/doc/refman/Universes.tex
@@ -201,7 +201,8 @@ universes and explicitly instantiate polymorphic definitions.
In the monorphic case, this command declares a new global universe named
{\ident}. It supports the polymorphic flag only in sections, meaning the
universe quantification will be discharged on each section definition
-independently.
+independently. One cannot mix polymorphic and monomorphic declarations
+in the same section.
\subsection{\tt Constraint {\ident} {\textit{ord}} {\ident}.
\comindex{Constraint}
@@ -212,6 +213,7 @@ 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}}.
diff --git a/doc/stdlib/index-list.html.template b/doc/stdlib/index-list.html.template
index a12983ab8..fb45777e7 100644
--- a/doc/stdlib/index-list.html.template
+++ b/doc/stdlib/index-list.html.template
@@ -21,6 +21,7 @@ through the <tt>Require Import</tt> command.</p>
theories/Init/Peano.v
theories/Init/Specif.v
theories/Init/Tactics.v
+ theories/Init/Tauto.v
theories/Init/Wf.v
(theories/Init/Prelude.v)
</dd>
@@ -203,6 +204,7 @@ through the <tt>Require Import</tt> command.</p>
(theories/QArith/QArith.v)
theories/QArith/Qreals.v
theories/QArith/Qcanon.v
+ theories/QArith/Qcabs.v
theories/QArith/Qround.v
theories/QArith/QOrderedType.v
theories/QArith/Qminmax.v
diff --git a/doc/tutorial/Tutorial.tex b/doc/tutorial/Tutorial.tex
index e09feeb8e..973a0b75e 100644
--- a/doc/tutorial/Tutorial.tex
+++ b/doc/tutorial/Tutorial.tex
@@ -248,11 +248,14 @@ explicitly the type of the quantified variable. We check:
\begin{coq_example}
Check (forall m:nat, gt m 0).
\end{coq_example}
-We may clean-up the development by removing the contents of the
-current section:
+We may revert to the clean state of
+our initial session using the \Coq~ \verb:Reset: command:
\begin{coq_example}
-Reset Declaration.
+Reset Initial.
\end{coq_example}
+\begin{coq_eval}
+Set Printing Width 60.
+\end{coq_eval}
\section{Introduction to the proof engine: Minimal Logic}
@@ -658,10 +661,8 @@ respectively 1 and 2. Such abstract entities may be entered in the context
as global variables. But we must be careful about the pollution of our
global environment by such declarations. For instance, we have already
polluted our \Coq~ session by declaring the variables
-\verb:n:, \verb:Pos_n:, \verb:A:, \verb:B:, and \verb:C:. If we want to revert to the clean state of
-our initial session, we may use the \Coq~ \verb:Reset: command, which returns
-to the state just prior the given global notion as we did before to
-remove a section, or we may return to the initial state using~:
+\verb:n:, \verb:Pos_n:, \verb:A:, \verb:B:, and \verb:C:.
+
\begin{coq_example}
Reset Initial.
\end{coq_example}
@@ -770,7 +771,7 @@ Let us now close the current section.
End R_sym_trans.
\end{coq_example}
-Here \Coq's printout is a warning that all local hypotheses have been
+All the local hypotheses have been
discharged in the statement of \verb:refl_if:, which now becomes a general
theorem in the first-order language declared in section
\verb:Predicate_calculus:. In this particular example, the use of section
@@ -1105,8 +1106,14 @@ mathematical justification of a logical development relies only on
Conversely, ordinary mathematical definitions can be unfolded at will, they
are {\sl transparent}.
+
\chapter{Induction}
+\begin{coq_eval}
+Reset Initial.
+Set Printing Width 60.
+\end{coq_eval}
+
\section{Data Types as Inductively Defined Mathematical Collections}
All the notions which were studied until now pertain to traditional
@@ -1195,7 +1202,7 @@ That is, instead of computing for natural \verb:i: an element of the indexed
\verb:Set: \verb:(P i):, \verb:prim_rec: computes uniformly an element of
\verb:nat:. Let us check the type of \verb:prim_rec::
\begin{coq_example}
-Check prim_rec.
+About prim_rec.
\end{coq_example}
Oops! Instead of the expected type \verb+nat->(nat->nat->nat)->nat->nat+ we
@@ -1241,22 +1248,16 @@ Fixpoint plus (n m:nat) {struct n} : nat :=
For the rest of the session, we shall clean up what we did so far with
types \verb:bool: and \verb:nat:, in order to use the initial definitions
given in \Coq's \verb:Prelude: module, and not to get confusing error
-messages due to our redefinitions. We thus revert to the state before
-our definition of \verb:bool: with the \verb:Reset: command:
+messages due to our redefinitions. We thus revert to the initial state:
\begin{coq_example}
-Reset bool.
-\end{coq_example}
-
-
-\subsection{Simple proofs by induction}
-
-\begin{coq_eval}
Reset Initial.
-\end{coq_eval}
+\end{coq_example}
\begin{coq_eval}
Set Printing Width 60.
\end{coq_eval}
+\subsection{Simple proofs by induction}
+
Let us now show how to do proofs by structural induction. We start with easy
properties of the \verb:plus: function we just defined. Let us first
show that $n=n+0$.
@@ -1480,6 +1481,11 @@ Qed.
\chapter{Modules}
+\begin{coq_eval}
+Reset Initial.
+Set Printing Width 60.
+\end{coq_eval}
+
\section{Opening library modules}
When you start \Coq~ without further requirements in the command line,
@@ -1543,9 +1549,13 @@ definitions available in the current context, especially if large
libraries have been loaded. A convenient \verb:Search: command
is available to lookup all known facts
concerning a given predicate. For instance, if you want to know all the
-known lemmas about the less or equal relation, just ask:
+known lemmas about both the successor and the less or equal relation, just ask:
+\begin{coq_eval}
+Reset Initial.
+Set Printing Width 60.
+\end{coq_eval}
\begin{coq_example}
-Search le.
+Search S le.
\end{coq_example}
Another command \verb:SearchHead: displays only lemmas where the searched
predicate appears at the head position in the conclusion.
@@ -1553,9 +1563,9 @@ predicate appears at the head position in the conclusion.
SearchHead le.
\end{coq_example}
-A new and more convenient search tool is \textsf{SearchPattern}
+A new and more convenient search tool is \verb:SearchPattern:
developed by Yves Bertot. It allows finding the theorems with a
-conclusion matching a given pattern, where \verb:\_: can be used in
+conclusion matching a given pattern, where \verb:_: can be used in
place of an arbitrary term. We remark in this example, that \Coq{}
provides usual infix notations for arithmetic operators.
diff --git a/engine/engine.mllib b/engine/engine.mllib
index 7197a2583..9ce5af819 100644
--- a/engine/engine.mllib
+++ b/engine/engine.mllib
@@ -5,3 +5,7 @@ UState
Evd
Sigma
Proofview_monad
+Evarutil
+Proofview
+Ftactic
+Geninterp
diff --git a/pretyping/evarutil.ml b/engine/evarutil.ml
index ab70de057..c5dfe3033 100644
--- a/pretyping/evarutil.ml
+++ b/engine/evarutil.ml
@@ -8,7 +8,6 @@
open Errors
open Util
-open Pp
open Names
open Term
open Vars
@@ -17,10 +16,12 @@ open Namegen
open Pre_env
open Environ
open Evd
-open Reductionops
-open Pretype_errors
open Sigma.Notations
+let safe_evar_value sigma ev =
+ try Some (Evd.existential_value sigma ev)
+ with NotInstantiatedEvar | Not_found -> None
+
(** Combinators *)
let evd_comb0 f evdref =
@@ -62,33 +63,41 @@ let rec flush_and_check_evars sigma c =
(* let nf_evar_key = Profile.declare_profile "nf_evar" *)
(* let nf_evar = Profile.profile2 nf_evar_key Reductionops.nf_evar *)
-let nf_evar = Reductionops.nf_evar
+
+let rec whd_evar sigma c =
+ match kind_of_term c with
+ | Evar ev ->
+ let (evk, args) = ev in
+ let args = Array.map (fun c -> whd_evar sigma c) args in
+ (match safe_evar_value sigma (evk, args) with
+ Some c -> whd_evar sigma c
+ | None -> c)
+ | Sort (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')
+ | _ -> c
+
+let rec nf_evar sigma t = Constr.map (fun t -> nf_evar sigma t) (whd_evar sigma t)
+
let j_nf_evar sigma j =
{ uj_val = nf_evar sigma j.uj_val;
uj_type = nf_evar sigma j.uj_type }
-let j_nf_betaiotaevar sigma j =
- { uj_val = nf_evar sigma j.uj_val;
- uj_type = Reductionops.nf_betaiota sigma j.uj_type }
let jl_nf_evar sigma jl = List.map (j_nf_evar sigma) jl
-let jv_nf_betaiotaevar sigma jl =
- Array.map (j_nf_betaiotaevar sigma) jl
let jv_nf_evar sigma = Array.map (j_nf_evar sigma)
let tj_nf_evar sigma {utj_val=v;utj_type=t} =
{utj_val=nf_evar sigma v;utj_type=t}
-let env_nf_evar sigma env =
- let open Context.Rel.Declaration in
- process_rel_context
- (fun d e -> push_rel (map_constr (nf_evar sigma) d) e) env
-
-let env_nf_betaiotaevar sigma env =
- let open Context.Rel.Declaration in
- process_rel_context
- (fun d e ->
- push_rel (map_constr (Reductionops.nf_betaiota sigma) d) e) env
-
let nf_evars_universes evm =
- Universes.nf_evars_and_universes_opt_subst (Reductionops.safe_evar_value evm)
+ Universes.nf_evars_and_universes_opt_subst (safe_evar_value evm)
(Evd.universe_subst evm)
let nf_evars_and_universes evm =
@@ -659,23 +668,6 @@ let undefined_evars_of_evar_info evd evi =
(undefined_evars_of_named_context evd
(named_context_of_val evi.evar_hyps)))
-(* [check_evars] fails if some unresolved evar remains *)
-
-let check_evars env initial_sigma sigma c =
- let rec proc_rec c =
- match kind_of_term c with
- | Evar (evk,_ as ev) ->
- (match existential_opt_value sigma ev with
- | Some c -> proc_rec c
- | None ->
- if not (Evd.mem initial_sigma evk) then
- let (loc,k) = evar_source evk sigma in
- match k with
- | Evar_kinds.ImplicitArg (gr, (i, id), false) -> ()
- | _ -> error_unsolvable_implicit loc env sigma evk None)
- | _ -> iter_constr proc_rec c
- in proc_rec c
-
(* spiwack: this is a more complete version of
{!Termops.occur_evar}. The latter does not look recursively into an
[evar_map]. If unification only need to check superficially, tactics
@@ -688,146 +680,6 @@ let occur_evar_upto sigma n c =
in
try occur_rec c; false with Occur -> true
-
-(****************************************)
-(* Operations on value/type constraints *)
-(****************************************)
-
-type type_constraint = types option
-
-type val_constraint = constr option
-
-(* Old comment...
- * Basically, we have the following kind of constraints (in increasing
- * strength order):
- * (false,(None,None)) -> no constraint at all
- * (true,(None,None)) -> we must build a judgement which _TYPE is a kind
- * (_,(None,Some ty)) -> we must build a judgement which _TYPE is ty
- * (_,(Some v,_)) -> we must build a judgement which _VAL is v
- * Maybe a concrete datatype would be easier to understand.
- * We differentiate (true,(None,None)) from (_,(None,Some Type))
- * because otherwise Case(s) would be misled, as in
- * (n:nat) Case n of bool [_]nat end would infer the predicate Type instead
- * of Set.
- *)
-
-(* The empty type constraint *)
-let empty_tycon = None
-
-(* Builds a type constraint *)
-let mk_tycon ty = Some ty
-
-(* Constrains the value of a type *)
-let empty_valcon = None
-
-(* Builds a value constraint *)
-let mk_valcon c = Some c
-
-let idx = Namegen.default_dependent_ident
-
-(* Refining an evar to a product *)
-
-let define_pure_evar_as_product evd evk =
- let open Context.Named.Declaration in
- let evi = Evd.find_undefined evd evk in
- let evenv = evar_env evi in
- let id = next_ident_away idx (ids_of_named_context (evar_context evi)) in
- let concl = whd_betadeltaiota evenv evd evi.evar_concl in
- let s = destSort concl in
- let evd1,(dom,u1) =
- let evd = Sigma.Unsafe.of_evar_map evd in
- let Sigma (e, evd1, _) = new_type_evar evenv evd univ_flexible_alg ~filter:(evar_filter evi) in
- (Sigma.to_evar_map evd1, e)
- in
- let evd2,rng =
- let newenv = push_named (LocalAssum (id, dom)) evenv in
- let src = evar_source evk evd1 in
- let filter = Filter.extend 1 (evar_filter evi) in
- if is_prop_sort s then
- (* Impredicative product, conclusion must fall in [Prop]. *)
- new_evar_unsafe newenv evd1 concl ~src ~filter
- else
- let status = univ_flexible_alg in
- let evd3, (rng, srng) =
- let evd1 = Sigma.Unsafe.of_evar_map evd1 in
- let Sigma (e, evd3, _) = new_type_evar newenv evd1 status ~src ~filter in
- (Sigma.to_evar_map evd3, e)
- in
- let prods = Univ.sup (univ_of_sort u1) (univ_of_sort srng) in
- let evd3 = Evd.set_leq_sort evenv evd3 (Type prods) s in
- evd3, rng
- in
- let prod = mkProd (Name id, dom, subst_var id rng) in
- let evd3 = Evd.define evk prod evd2 in
- evd3,prod
-
-(* Refine an applied evar to a product and returns its instantiation *)
-
-let define_evar_as_product evd (evk,args) =
- let evd,prod = define_pure_evar_as_product evd evk in
- (* Quick way to compute the instantiation of evk with args *)
- let na,dom,rng = destProd prod in
- let evdom = mkEvar (fst (destEvar dom), args) in
- let evrngargs = Array.cons (mkRel 1) (Array.map (lift 1) args) in
- let evrng = mkEvar (fst (destEvar rng), evrngargs) in
- evd,mkProd (na, evdom, evrng)
-
-(* Refine an evar with an abstraction
-
- I.e., solve x1..xq |- ?e:T(x1..xq) with e:=λy:A.?e'[x1..xq,y] where:
- - either T(x1..xq) = πy:A(x1..xq).B(x1..xq,y)
- or T(x1..xq) = ?d[x1..xq] and we define ?d := πy:?A.?B
- with x1..xq |- ?A:Type and x1..xq,y |- ?B:Type
- - x1..xq,y:A |- ?e':B
-*)
-
-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 = whd_betadeltaiota evenv evd (evar_concl evi) in
- let evd1,(na,dom,rng) = match kind_of_term typ with
- | Prod (na,dom,rng) -> (evd,(na,dom,rng))
- | Evar ev' -> let evd,typ = define_evar_as_product evd ev' in evd,destProd typ
- | _ -> error_not_product_loc Loc.ghost env evd typ in
- let avoid = ids_of_named_context (evar_context evi) in
- let id =
- next_name_away_with_default_using_types "x" na avoid (whd_evar evd dom) in
- let newenv = push_named (LocalAssum (id, dom)) evenv in
- let filter = Filter.extend 1 (evar_filter evi) in
- let src = evar_source evk evd1 in
- let evd2,body = new_evar_unsafe newenv evd1 ~src (subst1 (mkVar id) rng) ~filter in
- let lam = mkLambda (Name id, dom, subst_var id body) in
- 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
- (* Quick way to compute the instantiation of evk with args *)
- let na,dom,body = destLambda lam in
- let evbodyargs = Array.cons (mkRel 1) (Array.map (lift 1) args) in
- let evbody = mkEvar (fst (destEvar body), evbodyargs) in
- evd,mkLambda (na, dom, evbody)
-
-let rec evar_absorb_arguments env evd (evk,args as ev) = function
- | [] -> evd,ev
- | a::l ->
- (* TODO: optimize and avoid introducing intermediate evars *)
- let evd,lam = define_pure_evar_as_lambda env evd evk in
- let _,_,body = destLambda lam in
- let evk = fst (destEvar body) in
- evar_absorb_arguments env evd (evk, Array.cons a args) l
-
-(* Refining an evar to a sort *)
-
-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 = whd_betadeltaiota (evar_env evi) evd evi.evar_concl in
- let sort = destSort concl in
- let evd' = Evd.define ev (mkSort s) evd in
- Evd.set_leq_sort env evd' (Type (Univ.super u)) sort, s
-
(* We don't try to guess in which sort the type should be defined, since
any type has type Type. May cause some trouble, but not so far... *)
@@ -835,38 +687,6 @@ let judge_of_new_Type evd =
let Sigma (s, evd', p) = Sigma.new_univ_variable univ_rigid evd in
Sigma ({ uj_val = mkSort (Type s); uj_type = mkSort (Type (Univ.super s)) }, evd', p)
-(* Propagation of constraints through application and abstraction:
- Given a type constraint on a functional term, returns the type
- constraint on its domain and codomain. If the input constraint is
- an evar instantiate it with the product of 2 new evars. *)
-
-let split_tycon loc env evd tycon =
- let rec real_split evd c =
- let t = whd_betadeltaiota env evd c in
- match kind_of_term t with
- | Prod (na,dom,rng) -> evd, (na, dom, rng)
- | Evar ev (* ev is undefined because of whd_betadeltaiota *) ->
- let (evd',prod) = define_evar_as_product evd ev in
- let (_,dom,rng) = destProd prod in
- evd',(Anonymous, dom, rng)
- | App (c,args) when isEvar c ->
- let (evd',lam) = define_evar_as_lambda env evd (destEvar c) in
- real_split evd' (mkApp (lam,args))
- | _ -> error_not_product_loc loc env evd c
- in
- match tycon with
- | None -> evd,(Anonymous,None,None)
- | Some c ->
- let evd', (n, dom, rng) = real_split evd c in
- evd', (n, mk_tycon dom, mk_tycon rng)
-
-let valcon_of_tycon x = x
-let lift_tycon n = Option.map (lift n)
-
-let pr_tycon env = function
- None -> str "None"
- | Some t -> Termops.print_constr_env env t
-
let subterm_source evk (loc,k) =
let evk = match k with
| Evar_kinds.SubEvar (evk) -> evk
@@ -876,7 +696,7 @@ let subterm_source evk (loc,k) =
(** Term exploration up to instantiation. *)
let kind_of_term_upto sigma t =
- Constr.kind (Reductionops.whd_evar sigma t)
+ Constr.kind (whd_evar sigma t)
(** [eq_constr_univs_test sigma1 sigma2 t u] tests equality of [t] and
[u] up to existential variable instantiation and equalisable
@@ -897,3 +717,6 @@ let eq_constr_univs_test sigma1 sigma2 t u =
(universes sigma2) fold t u sigma2
in
match ans with None -> false | Some _ -> true
+
+type type_constraint = types option
+type val_constraint = constr option
diff --git a/pretyping/evarutil.mli b/engine/evarutil.mli
index bc4c37a91..111d0f3e8 100644
--- a/pretyping/evarutil.mli
+++ b/engine/evarutil.mli
@@ -11,7 +11,7 @@ open Term
open Evd
open Environ
-(** {5 This modules provides useful functions for unification modulo evars } *)
+(** This module provides useful higher-level functions for evar manipulation. *)
(** {6 Metas} *)
@@ -78,6 +78,8 @@ val new_evar_instance :
val make_pure_subst : evar_info -> constr array -> (Id.t * constr) list
+val safe_evar_value : evar_map -> existential -> constr option
+
(** {6 Evars/Metas switching...} *)
val non_instantiated : evar_map -> evar_info Evar.Map.t
@@ -96,20 +98,6 @@ val has_undefined_evars : evar_map -> constr -> bool
val is_ground_term : evar_map -> constr -> bool
val is_ground_env : evar_map -> env -> bool
-(** [check_evars env initial_sigma extended_sigma c] fails if some
- new unresolved evar remains in [c] *)
-val check_evars : env -> evar_map -> evar_map -> constr -> unit
-
-val define_evar_as_product : evar_map -> existential -> evar_map * types
-val define_evar_as_lambda : env -> evar_map -> existential -> evar_map * types
-val define_evar_as_sort : env -> evar_map -> existential -> evar_map * sorts
-
-(** Instantiate an evar by as many lambda's as needed so that its arguments
- are moved to the evar substitution (i.e. turn [?x[vars1:=args1] args] into
- [?y[vars1:=args1,vars:=args]] with
- [vars1 |- ?x:=\vars.?y[vars1:=vars1,vars:=vars]] *)
-val evar_absorb_arguments : env -> evar_map -> existential -> constr list ->
- evar_map * existential
(** [gather_dependent_evars evm seeds] classifies the evars in [evm]
as dependent_evars and goals (these may overlap). A goal is an
@@ -140,26 +128,12 @@ val occur_evar_upto : evar_map -> Evar.t -> Constr.t -> bool
val judge_of_new_Type : 'r Sigma.t -> (unsafe_judgment, 'r) Sigma.sigma
-type type_constraint = types option
-type val_constraint = constr option
-
-val empty_tycon : type_constraint
-val mk_tycon : constr -> type_constraint
-val empty_valcon : val_constraint
-val mk_valcon : constr -> val_constraint
-
-val split_tycon :
- Loc.t -> env -> evar_map -> type_constraint ->
- evar_map * (Name.t * type_constraint * type_constraint)
-
-val valcon_of_tycon : type_constraint -> val_constraint
-val lift_tycon : int -> type_constraint -> type_constraint
-
(***********************************************************)
(** [flush_and_check_evars] raise [Uninstantiated_evar] if an evar remains
uninstantiated; [nf_evar] leaves uninstantiated evars as is *)
+val whd_evar : evar_map -> constr -> constr
val nf_evar : evar_map -> constr -> constr
val j_nf_evar : evar_map -> unsafe_judgment -> unsafe_judgment
val jl_nf_evar :
@@ -177,12 +151,6 @@ val nf_evar_info : evar_map -> evar_info -> evar_info
val nf_evar_map : evar_map -> evar_map
val nf_evar_map_undefined : evar_map -> evar_map
-val env_nf_evar : evar_map -> env -> env
-val env_nf_betaiotaevar : evar_map -> env -> env
-
-val j_nf_betaiotaevar : evar_map -> unsafe_judgment -> unsafe_judgment
-val jv_nf_betaiotaevar :
- evar_map -> unsafe_judgment array -> unsafe_judgment array
(** Presenting terms without solved evars *)
val nf_evars_universes : evar_map -> constr -> constr
@@ -212,11 +180,6 @@ val kind_of_term_upto : evar_map -> constr -> (constr,types) kind_of_term
assumed to be an extention of those in [sigma1]. *)
val eq_constr_univs_test : evar_map -> evar_map -> constr -> constr -> bool
-(** {6 debug pretty-printer:} *)
-
-val pr_tycon : env -> type_constraint -> Pp.std_ppcmds
-
-
(** {6 Removing hyps in evars'context}
raise OccurHypInSimpleClause if the removal breaks dependencies *)
@@ -251,3 +214,8 @@ val subterm_source : existential_key -> Evar_kinds.t Loc.located ->
Evar_kinds.t Loc.located
val meta_counter_summary_name : string
+
+(** Deprecater *)
+
+type type_constraint = types option
+type val_constraint = constr option
diff --git a/engine/evd.ml b/engine/evd.ml
index b6849f7ff..b883db615 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -363,7 +363,6 @@ open Misctypes
type t
val empty : t
-val add_name_newly_undefined : intro_pattern_naming_expr -> Evar.t -> evar_info -> t -> t
val add_name_undefined : intro_pattern_naming_expr -> Evar.t -> evar_info -> t -> t
val remove_name_defined : Evar.t -> t -> t
val rename : Evar.t -> Id.t -> t -> t
diff --git a/engine/evd.mli b/engine/evd.mli
index 3ae6e586c..df491c27b 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -12,7 +12,10 @@ open Names
open Term
open Environ
-(** {5 Existential variables and unification states}
+(** This file defines the pervasive unification state used everywhere in Coq
+ tactic engine. It is very low-level and most of the functions exported here
+ are irrelevant to the standard API user. Consider using {!Evarutil},
+ {!Sigma} or {!Proofview} instead.
A unification state (of type [evar_map]) is primarily a finite mapping
from existential variables to records containing the type of the evar
@@ -23,6 +26,8 @@ open Environ
It also contains conversion constraints, debugging information and
information about meta variables. *)
+(** {5 Existential variables and unification states} *)
+
(** {6 Evars} *)
type evar = existential_key
@@ -343,7 +348,6 @@ val on_sig : 'a sigma -> (evar_map -> evar_map * 'b) -> 'a sigma * 'b
module MonadR : Monad.S with type +'a t = evar_map -> evar_map * 'a
module Monad : Monad.S with type +'a t = evar_map -> 'a * evar_map
-
(** {5 Meta machinery}
These functions are almost deprecated. They were used before the
diff --git a/tactics/ftactic.ml b/engine/ftactic.ml
index 55463afd0..588709873 100644
--- a/tactics/ftactic.ml
+++ b/engine/ftactic.ml
@@ -99,8 +99,6 @@ end
module Ftac = Monad.Make(Self)
module List = Ftac.List
-let debug_prompt = Tactic_debug.debug_prompt
-
module Notations =
struct
let (>>=) = bind
diff --git a/tactics/ftactic.mli b/engine/ftactic.mli
index fd05a4469..5db373199 100644
--- a/tactics/ftactic.mli
+++ b/engine/ftactic.mli
@@ -8,7 +8,9 @@
open Proofview.Notations
-(** Potentially focussing tactics *)
+(** This module defines potentially focussing tactics. They are used by Ltac to
+ emulate the historical behaviour of always-focussed tactics while still
+ allowing to remain global when the goal is not needed. *)
type +'a focus
@@ -70,11 +72,6 @@ val (<*>) : unit t -> 'a t -> 'a t
module List : Monad.ListS with type 'a t := 'a t
-(** {5 Debug} *)
-
-val debug_prompt :
- int -> Tacexpr.glob_tactic_expr -> (Tactic_debug.debug_info -> 'a t) -> 'a t
-
(** {5 Notations} *)
module Notations :
diff --git a/engine/geninterp.ml b/engine/geninterp.ml
new file mode 100644
index 000000000..cfca95d3e
--- /dev/null
+++ b/engine/geninterp.ml
@@ -0,0 +1,98 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Names
+open Genarg
+
+module TacStore = Store.Make(struct end)
+
+(** Dynamic toplevel values *)
+
+module ValT = Dyn.Make(struct end)
+
+module Val =
+struct
+
+ type 'a typ = 'a ValT.tag
+
+ type _ tag =
+ | Base : 'a typ -> 'a tag
+ | List : 'a tag -> 'a list tag
+ | Opt : 'a tag -> 'a option tag
+ | Pair : 'a tag * 'b tag -> ('a * 'b) tag
+
+ type t = Dyn : 'a typ * 'a -> t
+
+ let eq = ValT.eq
+ let repr = ValT.repr
+ let create = ValT.create
+
+ let pr : type a. a typ -> Pp.std_ppcmds = fun t -> Pp.str (repr t)
+
+ let typ_list = ValT.create "list"
+ let typ_opt = ValT.create "option"
+ let typ_pair = ValT.create "pair"
+
+ let rec inject : type a. a tag -> a -> t = fun tag x -> match tag with
+ | Base t -> Dyn (t, x)
+ | List tag -> Dyn (typ_list, List.map (fun x -> inject tag x) x)
+ | Opt tag -> Dyn (typ_opt, Option.map (fun x -> inject tag x) x)
+ | Pair (tag1, tag2) ->
+ Dyn (typ_pair, (inject tag1 (fst x), inject tag2 (snd x)))
+
+end
+
+module ValReprObj =
+struct
+ type ('raw, 'glb, 'top) obj = 'top Val.tag
+ let name = "valrepr"
+ let default _ = None
+end
+
+module ValRepr = Register(ValReprObj)
+
+let rec val_tag : type a b c. (a, b, c) genarg_type -> c Val.tag = function
+| ListArg t -> Val.List (val_tag t)
+| OptArg t -> Val.Opt (val_tag t)
+| PairArg (t1, t2) -> Val.Pair (val_tag t1, val_tag t2)
+| ExtraArg s -> ValRepr.obj (ExtraArg s)
+
+let val_tag = function Topwit t -> val_tag t
+
+let register_val0 wit tag =
+ let tag = match tag with
+ | None ->
+ let name = match wit with
+ | ExtraArg s -> ArgT.repr s
+ | _ -> assert false
+ in
+ Val.Base (Val.create name)
+ | Some tag -> tag
+ in
+ ValRepr.register0 wit tag
+
+(** Interpretation functions *)
+
+type interp_sign = {
+ lfun : Val.t Id.Map.t;
+ extra : TacStore.t }
+
+type ('glb, 'top) interp_fun = interp_sign -> 'glb -> 'top Ftactic.t
+
+module InterpObj =
+struct
+ type ('raw, 'glb, 'top) obj = ('glb, Val.t) interp_fun
+ let name = "interp"
+ let default _ = None
+end
+
+module Interp = Register(InterpObj)
+
+let interp = Interp.obj
+
+let register_interp0 = Interp.register0
diff --git a/engine/geninterp.mli b/engine/geninterp.mli
new file mode 100644
index 000000000..b70671a2d
--- /dev/null
+++ b/engine/geninterp.mli
@@ -0,0 +1,68 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** Interpretation functions for generic arguments and interpreted Ltac
+ values. *)
+
+open Names
+open Genarg
+
+(** {6 Dynamic toplevel values} *)
+
+module Val :
+sig
+ type 'a typ
+
+ val create : string -> 'a typ
+
+ type _ tag =
+ | Base : 'a typ -> 'a tag
+ | List : 'a tag -> 'a list tag
+ | Opt : 'a tag -> 'a option tag
+ | Pair : 'a tag * 'b tag -> ('a * 'b) tag
+
+ type t = Dyn : 'a typ * 'a -> t
+
+ val eq : 'a typ -> 'b typ -> ('a, 'b) CSig.eq option
+ val repr : 'a typ -> string
+ val pr : 'a typ -> Pp.std_ppcmds
+
+ val typ_list : t list typ
+ val typ_opt : t option typ
+ val typ_pair : (t * t) typ
+
+ val inject : 'a tag -> 'a -> t
+
+end
+(** Dynamic types for toplevel values. While the generic types permit to relate
+ objects at various levels of interpretation, toplevel values are wearing
+ their own type regardless of where they came from. This allows to use the
+ same runtime representation for several generic types. *)
+
+val val_tag : 'a typed_abstract_argument_type -> 'a Val.tag
+(** Retrieve the dynamic type associated to a toplevel genarg. *)
+
+val register_val0 : ('raw, 'glb, 'top) genarg_type -> 'top Val.tag option -> unit
+(** Register the representation of a generic argument. If no tag is given as
+ argument, a new fresh tag with the same name as the argument is associated
+ to the generic type. *)
+
+(** {6 Interpretation functions} *)
+
+module TacStore : Store.S
+
+type interp_sign = {
+ lfun : Val.t Id.Map.t;
+ extra : TacStore.t }
+
+type ('glb, 'top) interp_fun = interp_sign -> 'glb -> 'top Ftactic.t
+
+val interp : ('raw, 'glb, 'top) genarg_type -> ('glb, Val.t) interp_fun
+
+val register_interp0 :
+ ('raw, 'glb, 'top) genarg_type -> ('glb, Val.t) interp_fun -> unit
diff --git a/engine/logic_monad.ml b/engine/logic_monad.ml
index 4b78bc05d..64be07b9c 100644
--- a/engine/logic_monad.ml
+++ b/engine/logic_monad.ml
@@ -104,11 +104,11 @@ struct
Util.iraise (Exception e, info)
(** Use the current logger. The buffer is also flushed. *)
- let print_debug s = make (fun _ -> Pp.msg_info s;Pp.pp_flush ())
- let print_info s = make (fun _ -> Pp.msg_info s;Pp.pp_flush ())
- let print_warning s = make (fun _ -> Pp.msg_warning s;Pp.pp_flush ())
- let print_error s = make (fun _ -> Pp.msg_error s;Pp.pp_flush ())
- let print_notice s = make (fun _ -> Pp.msg_notice s;Pp.pp_flush ())
+ let print_debug s = make (fun _ -> Feedback.msg_info s)
+ let print_info s = make (fun _ -> Feedback.msg_info s)
+ let print_warning s = make (fun _ -> Feedback.msg_warning s)
+ let print_error s = make (fun _ -> Feedback.msg_error s)
+ let print_notice s = make (fun _ -> Feedback.msg_notice s)
let run = fun x ->
try x () with Exception e as src ->
@@ -340,7 +340,6 @@ struct
let lift = BackState.lift
let once = BackState.once
let break = BackState.break
- let reflect = BackState.reflect
let split = BackState.split
let repr = BackState.repr
diff --git a/engine/logic_monad.mli b/engine/logic_monad.mli
index c5160443b..dd122cca0 100644
--- a/engine/logic_monad.mli
+++ b/engine/logic_monad.mli
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(** This file defines the low-level monadic operations used by the
+(** This file implements the low-level monadic operations used by the
tactic monad. The monad is divided into two layers: a non-logical
layer which consists in operations which will not (or cannot) be
backtracked in case of failure (input/output or persistent state)
diff --git a/engine/namegen.mli b/engine/namegen.mli
index a2923fee9..e5c156b4e 100644
--- a/engine/namegen.mli
+++ b/engine/namegen.mli
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** This file features facilities to generate fresh names. *)
+
open Names
open Term
open Environ
diff --git a/proofs/proofview.ml b/engine/proofview.ml
index a382e9873..bcdd4da11 100644
--- a/proofs/proofview.ml
+++ b/engine/proofview.ml
@@ -46,7 +46,7 @@ let compact el ({ solution } as pv) =
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
- msg_info (Pp.str (Printf.sprintf "Evars: %d -> %d\n" size new_size));
+ Feedback.msg_info (Pp.str (Printf.sprintf "Evars: %d -> %d\n" size new_size));
new_el, { pv with solution = new_solution; }
@@ -56,10 +56,12 @@ type telescope =
| TNil of Evd.evar_map
| TCons of Environ.env * Evd.evar_map * Term.types * (Evd.evar_map -> Term.constr -> telescope)
+let typeclass_resolvable = Evd.Store.field ()
+
let dependent_init =
(* Goals are created with a store which marks them as unresolvable
for type classes. *)
- let store = Typeclasses.set_resolvable Evd.Store.empty false in
+ let store = Evd.Store.set Evd.Store.empty typeclass_resolvable () in
(* Goals don't have a source location. *)
let src = (Loc.ghost,Evar_kinds.GoalEvar) in
(* Main routine *)
@@ -625,18 +627,18 @@ let shelve_unifiable =
InfoL.leaf (Info.Tactic (fun () -> Pp.str"shelve_unifiable")) >>
Shelf.modify (fun gls -> gls @ u)
-(** [guard_no_unifiable] fails with error [UnresolvedBindings] if some
+(** [guard_no_unifiable] returns the list of unifiable goals if some
goals are unifiable (see {!shelve_unifiable}) in the current focus. *)
let guard_no_unifiable =
let open Proof in
Pv.get >>= fun initial ->
let (u,n) = partition_unifiable initial.solution initial.comb in
match u with
- | [] -> tclUNIT ()
+ | [] -> tclUNIT None
| gls ->
let l = CList.map (fun g -> Evd.dependent_evar_ident g initial.solution) gls in
let l = CList.map (fun id -> Names.Name id) l in
- tclZERO (Logic.RefinerError (Logic.UnresolvedBindings l))
+ tclUNIT (Some l)
(** [unshelve l p] adds all the goals in [l] at the end of the focused
goals of p *)
@@ -663,11 +665,12 @@ let with_shelf tac =
(** [goodmod p m] computes the representative of [p] modulo [m] in the
interval [[0,m-1]].*)
let goodmod p m =
- let p' = p mod m in
- (* if [n] is negative [n mod l] is negative of absolute value less
- than [l], so [(n mod l)+l] is the representative of [n] in the
- interval [[0,l-1]].*)
- if p' < 0 then p'+m else p'
+ if m = 0 then 0 else
+ let p' = p mod m in
+ (* if [n] is negative [n mod l] is negative of absolute value less
+ than [l], so [(n mod l)+l] is the representative of [n] in the
+ interval [[0,l-1]].*)
+ if p' < 0 then p'+m else p'
let cycle n =
let open Proof in
@@ -854,7 +857,7 @@ let tclTIME s t =
else
str (msg ^ " after ") ++ int n ++ str (String.plural n " backtracking")
in
- msg_info(str "Tactic call" ++ pr_opt str s ++ str " ran for " ++
+ Feedback.msg_info(str "Tactic call" ++ pr_opt str s ++ str " ran for " ++
System.fmt_time_difference t1 t2 ++ str " " ++ surround msg) in
let rec aux n t =
let open Proof in
@@ -901,31 +904,45 @@ module Unsafe = struct
let reset_future_goals p =
{ p with solution = Evd.reset_future_goals p.solution }
- let mark_as_goal_evm evd content =
+ let mark_as_goal evd content =
let info = Evd.find evd content in
let info =
{ info with Evd.evar_source = match info.Evd.evar_source with
| _, (Evar_kinds.VarInstance _ | Evar_kinds.GoalEvar) as x -> x
| loc,_ -> loc,Evar_kinds.GoalEvar }
in
- let info = Typeclasses.mark_unresolvable info in
+ let info = match Evd.Store.get info.Evd.evar_extra typeclass_resolvable with
+ | None -> { info with Evd.evar_extra = Evd.Store.set info.Evd.evar_extra typeclass_resolvable () }
+ | Some () -> info
+ in
Evd.add evd content info
- let mark_as_goal p gl =
- { p with solution = mark_as_goal_evm p.solution gl }
+ let advance = advance
+
+ let typeclass_resolvable = typeclass_resolvable
end
module UnsafeRepr = Proof.Unsafe
let (>>=) = tclBIND
-let (<*>) = tclTHEN
-let (<+>) t1 t2 = tclOR t1 (fun _ -> t2)
(** {6 Goal-dependent tactics} *)
-(* To avoid shadowing by the local [Goal] module *)
-module GoalV82 = Goal.V82
+let goal_env evars gl =
+ let evi = Evd.find evars gl in
+ Evd.evar_filtered_env evi
+
+let goal_nf_evar sigma gl =
+ let evi = Evd.find sigma gl in
+ let evi = Evarutil.nf_evar_info sigma evi in
+ let sigma = Evd.add sigma gl evi in
+ (gl, sigma)
+
+let goal_extra evars gl =
+ let evi = Evd.find evars gl in
+ evi.Evd.evar_extra
+
let catchable_exception = function
| Logic_monad.Exception _ -> false
@@ -950,7 +967,7 @@ module Goal = struct
let sigma { sigma=sigma } = Sigma.Unsafe.of_evar_map sigma
let hyps { env=env } = Environ.named_context env
let concl { concl=concl } = concl
- let extra { sigma=sigma; self=self } = Goal.V82.extra sigma self
+ let extra { sigma=sigma; self=self } = goal_extra sigma self
let raw_concl { concl=concl } = concl
@@ -1063,118 +1080,6 @@ end
-(** {6 The refine tactic} *)
-
-module Refine =
-struct
-
- let extract_prefix env info =
- let ctx1 = List.rev (Environ.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 ->
- if d1 == d2 then share l1 l2 (d1 :: accu)
- else (accu, d2 :: l2)
- | _ -> (accu, l2)
- in
- share ctx1 ctx2 []
-
- let typecheck_evar ev env sigma =
- let info = Evd.find sigma ev in
- (** Typecheck the hypotheses. *)
- let type_hyp (sigma, env) decl =
- let t = get_type decl in
- let evdref = ref sigma in
- let _ = Typing.e_sort_of env evdref t in
- let () = match decl with
- | LocalAssum _ -> ()
- | LocalDef (_,body,_) -> Typing.e_check env evdref body t
- in
- (!evdref, Environ.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 (sigma, env) = List.fold_left type_hyp (sigma, env) changed in
- (** Typecheck the conclusion *)
- let evdref = ref sigma in
- let _ = Typing.e_sort_of env evdref (Evd.evar_concl info) in
- !evdref
-
- let typecheck_proof c concl env sigma =
- let evdref = ref sigma in
- let () = Typing.e_check env evdref c concl in
- !evdref
-
- let (pr_constrv,pr_constr) =
- Hook.make ~default:(fun _env _sigma _c -> Pp.str"<constr>") ()
-
- let refine ?(unsafe = true) f = Goal.enter { Goal.enter = begin fun gl ->
- let sigma = Goal.sigma gl in
- let sigma = Sigma.to_evar_map sigma in
- let env = Goal.env gl in
- let concl = Goal.concl gl in
- (** Save the [future_goals] state to restore them after the
- refinement. *)
- let prev_future_goals = Evd.future_goals sigma in
- let prev_principal_goal = Evd.principal_future_goal sigma in
- (** Create the refinement term *)
- let (c, sigma) = Sigma.run (Evd.reset_future_goals sigma) f in
- let evs = Evd.future_goals sigma in
- let evkmain = Evd.principal_future_goal sigma in
- (** Check that the introduced evars are well-typed *)
- let fold accu ev = typecheck_evar ev env accu in
- let sigma = if unsafe then sigma else CList.fold_left fold sigma evs in
- (** Check that the refined term is typesafe *)
- let sigma = if unsafe then sigma else typecheck_proof c concl env sigma in
- (** Check that the goal itself does not appear in the refined term *)
- let _ =
- if not (Evarutil.occur_evar_upto sigma gl.Goal.self c) then ()
- else Pretype_errors.error_occur_check env sigma gl.Goal.self c
- in
- (** Proceed to the refinement *)
- let sigma = match evkmain with
- | None -> Evd.define gl.Goal.self c sigma
- | Some evk ->
- let id = Evd.evar_ident gl.Goal.self sigma in
- let sigma = Evd.define gl.Goal.self c sigma in
- match id with
- | None -> sigma
- | Some id -> Evd.rename evk id sigma
- in
- (** Restore the [future goals] state. *)
- let sigma = Evd.restore_future_goals sigma prev_future_goals prev_principal_goal in
- (** Select the goals *)
- let comb = undefined sigma (CList.rev evs) in
- let sigma = CList.fold_left Unsafe.mark_as_goal_evm sigma comb in
- let open Proof in
- InfoL.leaf (Info.Tactic (fun () -> Pp.(hov 2 (str"refine"++spc()++ Hook.get pr_constrv env sigma c)))) >>
- Pv.modify (fun ps -> { ps with solution = sigma; comb; })
- end }
-
- (** Useful definitions *)
-
- let with_type env evd c t =
- let my_type = Retyping.get_type_of env evd c in
- let j = Environ.make_judge c my_type in
- let (evd,j') =
- Coercion.inh_conv_coerce_to true (Loc.ghost) env evd j t
- in
- evd , j'.Environ.uj_val
-
- let refine_casted ?unsafe f = Goal.enter { Goal.enter = begin fun gl ->
- let concl = Goal.concl gl in
- let env = Goal.env gl in
- let f = { run = fun h ->
- let Sigma (c, h, p) = f.run h in
- let sigma, c = with_type env (Sigma.to_evar_map h) c concl in
- Sigma (c, Sigma.Unsafe.of_evar_map sigma, p)
- } in
- refine ?unsafe f
- end }
-end
-
-
-
(** {6 Trace} *)
module Trace = struct
@@ -1225,7 +1130,7 @@ module V82 = struct
in
(* Old style tactics expect the goals normalized with respect to evars. *)
let (initgoals,initevd) =
- Evd.Monad.List.map (fun g s -> GoalV82.nf_evar s g) ps.comb ps.solution
+ Evd.Monad.List.map (fun g s -> goal_nf_evar s g) ps.comb ps.solution
in
let (goalss,evd) = Evd.Monad.List.map tac initgoals initevd in
let sgs = CList.flatten goalss in
@@ -1241,7 +1146,7 @@ module V82 = struct
solution. *)
let nf_evar_goals =
Pv.modify begin fun ps ->
- let map g s = GoalV82.nf_evar s g in
+ let map g s = goal_nf_evar s g in
let (goals,evd) = Evd.Monad.List.map map ps.comb ps.solution in
{ ps with solution = evd; comb = goals; }
end
@@ -1272,24 +1177,10 @@ module V82 = struct
in
CList.flatten (CList.map evars_of_initial initial)
- let instantiate_evar n com pv =
- let (evk,_) =
- let evl = Evarutil.non_instantiated pv.solution in
- let evl = Evar.Map.bindings evl in
- if (n <= 0) then
- Errors.error "incorrect existential variable index"
- else if CList.length evl < n then
- Errors.error "not so many uninstantiated existential variables"
- else
- CList.nth evl (n-1)
- in
- { pv with
- solution = Evar_refiner.instantiate_pf_com evk com pv.solution }
-
let of_tactic t gls =
try
let init = { shelf = []; solution = gls.Evd.sigma ; comb = [gls.Evd.it] } in
- let (_,final,_,_) = apply (GoalV82.env gls.Evd.sigma gls.Evd.it) t init in
+ let (_,final,_,_) = apply (goal_env gls.Evd.sigma gls.Evd.it) t init in
{ Evd.sigma = final.solution ; it = final.comb }
with Logic_monad.TacticFailure e as src ->
let (_, info) = Errors.push src in
diff --git a/proofs/proofview.mli b/engine/proofview.mli
index dc97e44b6..93ba55c61 100644
--- a/proofs/proofview.mli
+++ b/engine/proofview.mli
@@ -295,14 +295,17 @@ val shelve : unit tactic
considered). *)
val shelve_unifiable : unit tactic
-(** [guard_no_unifiable] fails with error [UnresolvedBindings] if some
+(** [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 : unit tactic
+val guard_no_unifiable : Names.Name.t list option tactic
(** [unshelve l p] adds all the goals in [l] at the end of the focused
goals of p *)
val unshelve : Goal.goal list -> proofview -> proofview
+(** [depends_on g1 g2 sigma] checks if g1 occurs in the type/ctx of g2 *)
+val depends_on : Evd.evar_map -> Goal.goal -> Goal.goal -> bool
+
(** [with_shelf tac] executes [tac] and returns its result together with the set
of goals shelved by [tac]. The current shelf is unchanged. *)
val with_shelf : 'a tactic -> (Goal.goal list * 'a) tactic
@@ -406,7 +409,16 @@ module Unsafe : sig
(** Give an evar the status of a goal (changes its source location
and makes it unresolvable for type classes. *)
- val mark_as_goal : proofview -> Evar.t -> proofview
+ val mark_as_goal : Evd.evar_map -> Evar.t -> Evd.evar_map
+
+ (** [advance sigma g] returns [Some g'] if [g'] is undefined and is
+ the current avatar of [g] (for instance [g] was changed by [clear]
+ into [g']). It returns [None] if [g] has been (partially)
+ solved. *)
+ val advance : Evd.evar_map -> Evar.t -> Evar.t option
+
+ val typeclass_resolvable : unit Evd.Store.field
+
end
(** This module gives access to the innards of the monad. Its use is
@@ -491,39 +503,6 @@ module Goal : sig
end
-(** {6 The refine tactic} *)
-
-module Refine : sig
-
- (** Printer used to print the constr which refine refines. *)
- val pr_constr :
- (Environ.env -> Evd.evar_map -> Term.constr -> Pp.std_ppcmds) Hook.t
-
- (** {7 Refinement primitives} *)
-
- val refine : ?unsafe:bool -> Constr.t Sigma.run -> unit tactic
- (** In [refine ?unsafe t], [t] is a term with holes under some
- [evar_map] context. The term [t] is used as a partial solution
- for the current goal (refine is a goal-dependent tactic), the
- new holes created by [t] become the new subgoals. Exception
- raised during the interpretation of [t] are caught and result in
- tactic failures. If [unsafe] is [true] (default) [t] is
- type-checked beforehand. *)
-
- (** {7 Helper functions} *)
-
- val with_type : Environ.env -> Evd.evar_map ->
- Term.constr -> Term.types -> Evd.evar_map * Term.constr
- (** [with_type env sigma c t] ensures that [c] is of type [t]
- inserting a coercion if needed. *)
-
- val refine_casted : ?unsafe:bool -> Constr.t Sigma.run -> unit tactic
- (** Like {!refine} except the refined term is coerced to the conclusion of the
- current goal. *)
-
-end
-
-
(** {6 Trace} *)
module Trace : sig
@@ -577,9 +556,6 @@ module V82 : sig
(* returns the existential variable used to start the proof *)
val top_evars : entry -> Evd.evar list
-
- (* Implements the Existential command *)
- val instantiate_evar : int -> Constrexpr.constr_expr -> proofview -> proofview
(* Caution: this function loses quite a bit of information. It
should be avoided as much as possible. It should work as
diff --git a/engine/proofview_monad.ml b/engine/proofview_monad.ml
index 2b9db60b4..6f52b3ee9 100644
--- a/engine/proofview_monad.ml
+++ b/engine/proofview_monad.ml
@@ -154,8 +154,8 @@ end
focused goals. *)
type proofview = {
solution : Evd.evar_map;
- comb : Goal.goal list;
- shelf : Goal.goal list;
+ comb : Evar.t list;
+ shelf : Evar.t list;
}
(** {6 Instantiation of the logic monad} *)
diff --git a/engine/proofview_monad.mli b/engine/proofview_monad.mli
index 7a6ea10fe..637414cce 100644
--- a/engine/proofview_monad.mli
+++ b/engine/proofview_monad.mli
@@ -7,7 +7,8 @@
(************************************************************************)
(** This file defines the datatypes used as internal states by the
- tactic monad, and specialises the [Logic_monad] to these type. *)
+ tactic monad, and specialises the [Logic_monad] to these types. It should
+ not be used directly. Consider using {!Proofview} instead. *)
(** {6 Traces} *)
@@ -70,8 +71,8 @@ end
focused goals. *)
type proofview = {
solution : Evd.evar_map;
- comb : Goal.goal list;
- shelf : Goal.goal list;
+ comb : Evar.t list;
+ shelf : Evar.t list;
}
(** {6 Instantiation of the logic monad} *)
diff --git a/engine/sigma.mli b/engine/sigma.mli
index 643bea403..aaf603efd 100644
--- a/engine/sigma.mli
+++ b/engine/sigma.mli
@@ -12,7 +12,9 @@ open Constr
(** Monotonous state enforced by typing.
This module allows to constrain uses of evarmaps in a monotonous fashion,
- and in particular statically suppress evar leaks and the like.
+ and in particular statically suppress evar leaks and the like. To this
+ ends, it defines a type of indexed evarmaps whose phantom typing ensures
+ monotonous use.
*)
(** {5 Stages} *)
@@ -32,7 +34,7 @@ val (+>) : ('a, 'b) le -> ('b, 'c) le -> ('a, 'c) le
(** {5 Monotonous evarmaps} *)
type 'r t
-(** Stage-indexed evarmaps. *)
+(** Stage-indexed evarmaps. This is just a plain evarmap with a phantom type. *)
type ('a, 'r) sigma = Sigma : 'a * 's t * ('r, 's) le -> ('a, 'r) sigma
(** Return values at a later stage *)
diff --git a/engine/termops.mli b/engine/termops.mli
index c2a4f3323..76a31037b 100644
--- a/engine/termops.mli
+++ b/engine/termops.mli
@@ -6,6 +6,9 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** This file defines various utilities for term manipulation that are not
+ needed in the kernel. *)
+
open Pp
open Names
open Term
diff --git a/engine/uState.mli b/engine/uState.mli
index c5c454020..0cdc6277a 100644
--- a/engine/uState.mli
+++ b/engine/uState.mli
@@ -6,7 +6,9 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(** Universe unification states *)
+(** This file defines universe unification states which are part of evarmaps.
+ Most of the API below is reexported in {!Evd}. Consider using higher-level
+ primitives when needed. *)
open Names
diff --git a/grammar/argextend.ml4 b/grammar/argextend.ml4
deleted file mode 100644
index 13f761113..000000000
--- a/grammar/argextend.ml4
+++ /dev/null
@@ -1,327 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(*i camlp4deps: "tools/compat5b.cmo" i*)
-
-open Genarg
-open Q_util
-open Egramml
-open Compat
-open Extend
-open Pcoq
-
-let loc = CompatLoc.ghost
-let default_loc = <:expr< Loc.ghost >>
-
-let qualified_name loc s =
- let path = CString.split '.' s in
- let (name, path) = CList.sep_last path in
- qualified_name loc path name
-
-let mk_extraarg loc s =
- try
- let name = Genarg.get_name0 s in
- qualified_name loc name
- with Not_found ->
- <:expr< $lid:"wit_"^s$ >>
-
-let rec make_wit loc = function
- | ListArgType t -> <:expr< Genarg.wit_list $make_wit loc t$ >>
- | OptArgType t -> <:expr< Genarg.wit_opt $make_wit loc t$ >>
- | PairArgType (t1,t2) ->
- <:expr< Genarg.wit_pair $make_wit loc t1$ $make_wit loc t2$ >>
- | ExtraArgType s -> mk_extraarg loc s
-
-let make_rawwit loc arg = <:expr< Genarg.rawwit $make_wit loc arg$ >>
-let make_globwit loc arg = <:expr< Genarg.glbwit $make_wit loc arg$ >>
-let make_topwit loc arg = <:expr< Genarg.topwit $make_wit loc arg$ >>
-
-let has_extraarg l =
- let check = function
- | ExtNonTerminal(ExtraArgType _, _, _) -> true
- | _ -> false
- in
- List.exists check l
-
-let rec is_possibly_empty = function
-| Uopt _ -> true
-| Ulist0 _ -> true
-| Ulist0sep _ -> true
-| Umodifiers _ -> true
-| Ulist1 t -> is_possibly_empty t
-| Ulist1sep (t, _) -> is_possibly_empty t
-| _ -> false
-
-let rec get_empty_entry = function
-| Uopt _ -> <:expr< None >>
-| Ulist0 _ -> <:expr< [] >>
-| Ulist0sep _ -> <:expr< [] >>
-| Umodifiers _ -> <:expr< [] >>
-| Ulist1 t -> <:expr< [$get_empty_entry t$] >>
-| Ulist1sep (t, _) -> <:expr< [$get_empty_entry t$] >>
-| _ -> assert false
-
-let statically_known_possibly_empty s (prods,_) =
- List.for_all (function
- | ExtNonTerminal(t, e, _) ->
- begin match t with
- | ExtraArgType s' ->
- (* For ExtraArg we don't know (we'll have to test dynamically) *)
- (* unless it is a recursive call *)
- s <> s'
- | _ ->
- is_possibly_empty e
- end
- | ExtTerminal _ ->
- (* This consumes a token for sure *) false)
- prods
-
-let possibly_empty_subentries loc (prods,act) =
- let bind_name id v e =
- let s = Names.Id.to_string id in
- <:expr< let $lid:s$ = $v$ in $e$ >>
- in
- let rec aux = function
- | [] -> <:expr< let loc = $default_loc$ in let _ = loc in $act$ >>
- | ExtNonTerminal(_, e, id) :: tl when is_possibly_empty e ->
- bind_name id (get_empty_entry e) (aux tl)
- | ExtNonTerminal(t, _, id) :: tl ->
- let t = match t with
- | ExtraArgType _ as t -> t
- | _ -> assert false
- in
- (* We check at runtime if extraarg s parses "epsilon" *)
- let s = Names.Id.to_string id in
- <:expr< let $lid:s$ = match Genarg.default_empty_value $make_wit loc t$ with
- [ None -> raise Exit
- | Some v -> v ] in $aux tl$ >>
- | _ -> assert false (* already filtered out *) in
- if has_extraarg prods then
- (* Needs a dynamic check; catch all exceptions if ever some rhs raises *)
- (* an exception rather than returning a value; *)
- (* declares loc because some code can refer to it; *)
- (* ensures loc is used to avoid "unused variable" warning *)
- (true, <:expr< try Some $aux prods$
- with [ Exit -> None ] >>)
- else
- (* Static optimisation *)
- (false, aux prods)
-
-let make_possibly_empty_subentries loc s cl =
- let cl = List.filter (statically_known_possibly_empty s) cl in
- if cl = [] then
- <:expr< None >>
- else
- let rec aux = function
- | (true, e) :: l ->
- <:expr< match $e$ with [ Some v -> Some v | None -> $aux l$ ] >>
- | (false, e) :: _ ->
- <:expr< Some $e$ >>
- | [] ->
- <:expr< None >> in
- aux (List.map (possibly_empty_subentries loc) cl)
-
-let make_act loc act pil =
- let rec make = function
- | [] -> <:expr< (fun loc -> $act$) >>
- | ExtNonTerminal (t, _, p) :: tl ->
- let p = Names.Id.to_string p in
- <:expr<
- (fun $lid:p$ ->
- let _ = Genarg.in_gen $make_rawwit loc t$ $lid:p$ in $make tl$)
- >>
- | ExtTerminal _ :: tl ->
- <:expr< (fun _ -> $make tl$) >> in
- make (List.rev pil)
-
-let make_prod_item = function
- | ExtTerminal s -> <:expr< Pcoq.Atoken (Lexer.terminal $mlexpr_of_string s$) >>
- | ExtNonTerminal (_, g, _) -> mlexpr_of_prod_entry_key g
-
-let rec make_prod = function
-| [] -> <:expr< Extend.Stop >>
-| item :: prods -> <:expr< Extend.Next $make_prod prods$ $make_prod_item item$ >>
-
-let make_rule loc (prods,act) =
- <:expr< Extend.Rule $make_prod (List.rev prods)$ $make_act loc act prods$ >>
-
-let declare_tactic_argument loc s (typ, pr, f, g, h) cl =
- let rawtyp, rawpr, globtyp, globpr = match typ with
- | `Uniform typ ->
- typ, pr, typ, pr
- | `Specialized (a, b, c, d) -> a, b, c, d
- in
- let glob = match g with
- | None ->
- begin match rawtyp with
- | Genarg.ExtraArgType s' when CString.equal s s' ->
- <:expr< fun ist v -> (ist, v) >>
- | _ ->
- <:expr< fun ist v ->
- let ans = out_gen $make_globwit loc rawtyp$
- (Tacintern.intern_genarg ist
- (Genarg.in_gen $make_rawwit loc rawtyp$ v)) in
- (ist, ans) >>
- end
- | Some f ->
- <:expr< fun ist v -> (ist, $lid:f$ ist v) >>
- in
- let interp = match f with
- | None ->
- begin match globtyp with
- | Genarg.ExtraArgType s' when CString.equal s s' ->
- <:expr< fun ist v -> Ftactic.return v >>
- | _ ->
- <:expr< fun ist x ->
- Ftactic.bind
- (Tacinterp.interp_genarg ist (Genarg.in_gen $make_globwit loc globtyp$ x))
- (fun v -> Ftactic.return (Tacinterp.Value.cast $make_topwit loc globtyp$ v)) >>
- end
- | Some f ->
- (** Compatibility layer, TODO: remove me *)
- <:expr<
- let f = $lid:f$ in
- fun ist v -> Ftactic.nf_s_enter { Proofview.Goal.s_enter = fun gl ->
- let (sigma, v) = Tacmach.New.of_old (fun gl -> f ist gl v) gl in
- Sigma.Unsafe.of_pair (Ftactic.return v, sigma)
- }
- >> in
- let subst = match h with
- | None ->
- begin match globtyp with
- | Genarg.ExtraArgType s' when CString.equal s s' ->
- <:expr< fun s v -> v >>
- | _ ->
- <:expr< fun s x ->
- out_gen $make_globwit loc globtyp$
- (Tacsubst.subst_genarg s
- (Genarg.in_gen $make_globwit loc globtyp$ x)) >>
- end
- | Some f -> <:expr< $lid:f$>> in
- let dyn = match typ with
- | `Uniform typ ->
- let is_new = match typ with
- | Genarg.ExtraArgType s' when CString.equal s s' -> true
- | _ -> false
- in
- if is_new then <:expr< None >>
- else <:expr< Some (Genarg.val_tag $make_topwit loc typ$) >>
- | `Specialized _ -> <:expr< None >>
- in
- let se = mlexpr_of_string s in
- let wit = <:expr< $lid:"wit_"^s$ >> in
- let rawwit = <:expr< Genarg.rawwit $wit$ >> in
- let rules = mlexpr_of_list (make_rule loc) (List.rev cl) in
- let default_value = <:expr< $make_possibly_empty_subentries loc s cl$ >> in
- declare_str_items loc
- [ <:str_item<
- value ($lid:"wit_"^s$) =
- let dyn = $dyn$ in
- Genarg.make0 ?dyn $default_value$ $se$ >>;
- <:str_item< Genintern.register_intern0 $wit$ $glob$ >>;
- <:str_item< Genintern.register_subst0 $wit$ $subst$ >>;
- <:str_item< Geninterp.register_interp0 $wit$ $interp$ >>;
- <:str_item<
- value $lid:s$ = Pcoq.create_generic_entry $se$ $rawwit$ >>;
- <:str_item< do {
- Pcoq.grammar_extend $lid:s$ None (None, [(None, None, $rules$)]);
- Pptactic.declare_extra_genarg_pprule
- $wit$ $lid:rawpr$ $lid:globpr$ $lid:pr$ }
- >> ]
-
-let declare_vernac_argument loc s pr cl =
- let se = mlexpr_of_string s in
- let wit = <:expr< $lid:"wit_"^s$ >> in
- let rawwit = <:expr< Genarg.rawwit $wit$ >> in
- let rules = mlexpr_of_list (make_rule loc) (List.rev cl) in
- let pr_rules = match pr with
- | None -> <:expr< fun _ _ _ _ -> str $str:"[No printer for "^s^"]"$ >>
- | Some pr -> <:expr< fun _ _ _ -> $lid:pr$ >> in
- declare_str_items loc
- [ <:str_item<
- value ($lid:"wit_"^s$ : Genarg.genarg_type 'a unit unit) =
- Genarg.create_arg None $se$ >>;
- <:str_item<
- value $lid:s$ = Pcoq.create_generic_entry $se$ $rawwit$ >>;
- <:str_item< do {
- Pcoq.grammar_extend $lid:s$ None (None, [(None, None, $rules$)]);
- Pptactic.declare_extra_genarg_pprule $wit$
- $pr_rules$
- (fun _ _ _ _ -> Errors.anomaly (Pp.str "vernac argument needs not globwit printer"))
- (fun _ _ _ _ -> Errors.anomaly (Pp.str "vernac argument needs not wit printer")) }
- >> ]
-
-open Pcoq
-open Pcaml
-open PcamlSig (* necessary for camlp4 *)
-
-EXTEND
- GLOBAL: str_item;
- str_item:
- [ [ "ARGUMENT"; "EXTEND"; s = entry_name;
- header = argextend_header;
- OPT "|"; l = LIST1 argrule SEP "|";
- "END" ->
- declare_tactic_argument loc s header l
- | "VERNAC"; "ARGUMENT"; "EXTEND"; s = entry_name;
- pr = OPT ["PRINTED"; "BY"; pr = LIDENT -> pr];
- OPT "|"; l = LIST1 argrule SEP "|";
- "END" ->
- declare_vernac_argument loc s pr l ] ]
- ;
- argextend_header:
- [ [ "TYPED"; "AS"; typ = argtype;
- "PRINTED"; "BY"; pr = LIDENT;
- f = OPT [ "INTERPRETED"; "BY"; f = LIDENT -> f ];
- g = OPT [ "GLOBALIZED"; "BY"; f = LIDENT -> f ];
- h = OPT [ "SUBSTITUTED"; "BY"; f = LIDENT -> f ] ->
- (`Uniform typ, pr, f, g, h)
- | "PRINTED"; "BY"; pr = LIDENT;
- f = OPT [ "INTERPRETED"; "BY"; f = LIDENT -> f ];
- g = OPT [ "GLOBALIZED"; "BY"; f = LIDENT -> f ];
- h = OPT [ "SUBSTITUTED"; "BY"; f = LIDENT -> f ];
- "RAW_TYPED"; "AS"; rawtyp = argtype;
- "RAW_PRINTED"; "BY"; rawpr = LIDENT;
- "GLOB_TYPED"; "AS"; globtyp = argtype;
- "GLOB_PRINTED"; "BY"; globpr = LIDENT ->
- (`Specialized (rawtyp, rawpr, globtyp, globpr), pr, f, g, h) ] ]
- ;
- argtype:
- [ "2"
- [ e1 = argtype; "*"; e2 = argtype -> PairArgType (e1, e2) ]
- | "1"
- [ e = argtype; LIDENT "list" -> ListArgType e
- | e = argtype; LIDENT "option" -> OptArgType e ]
- | "0"
- [ e = LIDENT ->
- let e = parse_user_entry e "" in
- type_of_user_symbol e
- | "("; e = argtype; ")" -> e ] ]
- ;
- argrule:
- [ [ "["; l = LIST0 genarg; "]"; "->"; "["; e = Pcaml.expr; "]" -> (l,e) ] ]
- ;
- genarg:
- [ [ e = LIDENT; "("; s = LIDENT; ")" ->
- let e = parse_user_entry e "" in
- ExtNonTerminal (type_of_user_symbol e, e, Names.Id.of_string s)
- | e = LIDENT; "("; s = LIDENT; ","; sep = STRING; ")" ->
- let e = parse_user_entry e sep in
- ExtNonTerminal (type_of_user_symbol e, e, Names.Id.of_string s)
- | s = STRING ->
- if String.length s > 0 && Util.is_letter s.[0] then
- Lexer.add_keyword s;
- ExtTerminal s
- ] ]
- ;
- entry_name:
- [ [ s = LIDENT -> s
- | UIDENT -> failwith "Argument entry names must be lowercase"
- ] ]
- ;
- END
diff --git a/grammar/argextend.mlp b/grammar/argextend.mlp
new file mode 100644
index 000000000..eaaa7f025
--- /dev/null
+++ b/grammar/argextend.mlp
@@ -0,0 +1,254 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Q_util
+open GramCompat
+
+let loc = CompatLoc.ghost
+let default_loc = <:expr< Loc.ghost >>
+
+let mk_extraarg loc s = <:expr< $lid:"wit_"^s$ >>
+
+let rec make_wit loc = function
+ | ListArgType t -> <:expr< Genarg.wit_list $make_wit loc t$ >>
+ | OptArgType t -> <:expr< Genarg.wit_opt $make_wit loc t$ >>
+ | PairArgType (t1,t2) ->
+ <:expr< Genarg.wit_pair $make_wit loc t1$ $make_wit loc t2$ >>
+ | ExtraArgType s -> mk_extraarg loc s
+
+let is_self s = function
+| ExtraArgType s' -> s = s'
+| _ -> false
+
+let make_rawwit loc arg = <:expr< Genarg.rawwit $make_wit loc arg$ >>
+let make_globwit loc arg = <:expr< Genarg.glbwit $make_wit loc arg$ >>
+let make_topwit loc arg = <:expr< Genarg.topwit $make_wit loc arg$ >>
+
+let make_act loc act pil =
+ let rec make = function
+ | [] -> <:expr< (fun loc -> $act$) >>
+ | ExtNonTerminal (_, p) :: tl -> <:expr< (fun $lid:p$ -> $make tl$) >>
+ | ExtTerminal _ :: tl ->
+ <:expr< (fun _ -> $make tl$) >> in
+ make (List.rev pil)
+
+let make_prod_item = function
+ | ExtTerminal s -> <:expr< Extend.Atoken (CLexer.terminal $mlexpr_of_string s$) >>
+ | ExtNonTerminal (g, _) ->
+ let base s = <:expr< $lid:s$ >> in
+ mlexpr_of_prod_entry_key base g
+
+let rec make_prod = function
+| [] -> <:expr< Extend.Stop >>
+| item :: prods -> <:expr< Extend.Next $make_prod prods$ $make_prod_item item$ >>
+
+let make_rule loc (prods,act) =
+ <:expr< Extend.Rule $make_prod (List.rev prods)$ $make_act loc act prods$ >>
+
+let is_ident x = function
+| <:expr< $lid:s$ >> -> (s : string) = x
+| _ -> false
+
+let make_extend loc s cl wit = match cl with
+| [[ExtNonTerminal (Uentry e, id)], act] when is_ident id act ->
+ (** Special handling of identity arguments by not redeclaring an entry *)
+ <:str_item<
+ value $lid:s$ =
+ let () = Pcoq.register_grammar $wit$ $lid:e$ in
+ $lid:e$
+ >>
+| _ ->
+ let se = mlexpr_of_string s in
+ let rules = mlexpr_of_list (make_rule loc) (List.rev cl) in
+ <:str_item<
+ value $lid:s$ =
+ let $lid:s$ = Pcoq.create_generic_entry Pcoq.utactic $se$ (Genarg.rawwit $wit$) in
+ let () = Pcoq.grammar_extend $lid:s$ None (None, [(None, None, $rules$)]) in
+ $lid:s$ >>
+
+let warning_redundant prefix s =
+ Printf.eprintf "Redundant [%sTYPED AS] clause in [ARGUMENT EXTEND %s].\n%!" prefix s
+
+let get_type prefix s = function
+| None -> None
+| Some typ ->
+ if is_self s typ then
+ let () = warning_redundant prefix s in None
+ else Some typ
+
+let check_type prefix s = function
+| None -> ()
+| Some _ -> warning_redundant prefix s
+
+let declare_tactic_argument loc s (typ, f, g, h) cl =
+ let se = mlexpr_of_string s in
+ let rawtyp, rawpr, globtyp, globpr, typ, pr = match typ with
+ | `Uniform (typ, pr) ->
+ let typ = get_type "" s typ in
+ typ, pr, typ, pr, typ, pr
+ | `Specialized (a, rpr, c, gpr, e, tpr) ->
+ (** Check that we actually need the TYPED AS arguments *)
+ let rawtyp = get_type "RAW_" s a in
+ let glbtyp = get_type "GLOB_" s c in
+ let toptyp = get_type "" s e in
+ let () = match g with None -> () | Some _ -> check_type "RAW_" s rawtyp in
+ let () = match f, h with Some _, Some _ -> check_type "GLOB_" s glbtyp | _ -> () in
+ rawtyp, rpr, glbtyp, gpr, toptyp, tpr
+ in
+ let glob = match g with
+ | None ->
+ begin match rawtyp with
+ | None -> <:expr< fun ist v -> (ist, v) >>
+ | Some rawtyp ->
+ <:expr< fun ist v ->
+ let ans = out_gen $make_globwit loc rawtyp$
+ (Tacintern.intern_genarg ist
+ (Genarg.in_gen $make_rawwit loc rawtyp$ v)) in
+ (ist, ans) >>
+ end
+ | Some f ->
+ <:expr< fun ist v -> (ist, $lid:f$ ist v) >>
+ in
+ let interp = match f with
+ | None ->
+ begin match globtyp with
+ | None ->
+ let typ = match globtyp with None -> ExtraArgType s | Some typ -> typ in
+ <:expr< fun ist v -> Ftactic.return (Geninterp.Val.inject (Geninterp.val_tag $make_topwit loc typ$) v) >>
+ | Some globtyp ->
+ <:expr< fun ist x ->
+ Tacinterp.interp_genarg ist (Genarg.in_gen $make_globwit loc globtyp$ x) >>
+ end
+ | Some f ->
+ (** Compatibility layer, TODO: remove me *)
+ let typ = match globtyp with None -> ExtraArgType s | Some typ -> typ in
+ <:expr<
+ let f = $lid:f$ in
+ fun ist v -> Ftactic.nf_s_enter { Proofview.Goal.s_enter = fun gl ->
+ let (sigma, v) = Tacmach.New.of_old (fun gl -> f ist gl v) gl in
+ let v = Geninterp.Val.inject (Geninterp.val_tag $make_topwit loc typ$) v in
+ Sigma.Unsafe.of_pair (Ftactic.return v, sigma)
+ }
+ >> in
+ let subst = match h with
+ | None ->
+ begin match globtyp with
+ | None -> <:expr< fun s v -> v >>
+ | Some globtyp ->
+ <:expr< fun s x ->
+ out_gen $make_globwit loc globtyp$
+ (Tacsubst.subst_genarg s
+ (Genarg.in_gen $make_globwit loc globtyp$ x)) >>
+ end
+ | Some f -> <:expr< $lid:f$>> in
+ let dyn = match typ with
+ | None -> <:expr< None >>
+ | Some typ -> <:expr< Some (Geninterp.val_tag $make_topwit loc typ$) >>
+ in
+ let wit = <:expr< $lid:"wit_"^s$ >> in
+ declare_str_items loc
+ [ <:str_item< value ($lid:"wit_"^s$) = Genarg.make0 $se$ >>;
+ <:str_item< Genintern.register_intern0 $wit$ $glob$ >>;
+ <:str_item< Genintern.register_subst0 $wit$ $subst$ >>;
+ <:str_item< Geninterp.register_interp0 $wit$ $interp$ >>;
+ <:str_item< Geninterp.register_val0 $wit$ $dyn$ >>;
+ make_extend loc s cl wit;
+ <:str_item< do {
+ Pptactic.declare_extra_genarg_pprule
+ $wit$ $lid:rawpr$ $lid:globpr$ $lid:pr$;
+ Tacentries.create_ltac_quotation $se$
+ (fun (loc, v) -> Tacexpr.TacGeneric (Genarg.in_gen (Genarg.rawwit $wit$) v))
+ ($lid:s$, None)
+ } >> ]
+
+let declare_vernac_argument loc s pr cl =
+ let se = mlexpr_of_string s in
+ let wit = <:expr< $lid:"wit_"^s$ >> in
+ let pr_rules = match pr with
+ | None -> <:expr< fun _ _ _ _ -> str $str:"[No printer for "^s^"]"$ >>
+ | Some pr -> <:expr< fun _ _ _ -> $lid:pr$ >> in
+ declare_str_items loc
+ [ <:str_item<
+ value ($lid:"wit_"^s$ : Genarg.genarg_type 'a unit unit) =
+ Genarg.create_arg $se$ >>;
+ make_extend loc s cl wit;
+ <:str_item< do {
+ Pptactic.declare_extra_genarg_pprule $wit$
+ $pr_rules$
+ (fun _ _ _ _ -> Errors.anomaly (Pp.str "vernac argument needs not globwit printer"))
+ (fun _ _ _ _ -> Errors.anomaly (Pp.str "vernac argument needs not wit printer")) }
+ >> ]
+
+open Pcaml
+open PcamlSig (* necessary for camlp4 *)
+
+EXTEND
+ GLOBAL: str_item;
+ str_item:
+ [ [ "ARGUMENT"; "EXTEND"; s = entry_name;
+ header = argextend_header;
+ OPT "|"; l = LIST1 argrule SEP "|";
+ "END" ->
+ declare_tactic_argument loc s header l
+ | "VERNAC"; "ARGUMENT"; "EXTEND"; s = entry_name;
+ pr = OPT ["PRINTED"; "BY"; pr = LIDENT -> pr];
+ OPT "|"; l = LIST1 argrule SEP "|";
+ "END" ->
+ declare_vernac_argument loc s pr l ] ]
+ ;
+ argextend_specialized:
+ [ [ rawtyp = OPT [ "RAW_TYPED"; "AS"; rawtyp = argtype -> rawtyp ];
+ "RAW_PRINTED"; "BY"; rawpr = LIDENT;
+ globtyp = OPT [ "GLOB_TYPED"; "AS"; globtyp = argtype -> globtyp ];
+ "GLOB_PRINTED"; "BY"; globpr = LIDENT ->
+ (rawtyp, rawpr, globtyp, globpr) ] ]
+ ;
+ argextend_header:
+ [ [ typ = OPT [ "TYPED"; "AS"; typ = argtype -> typ ];
+ "PRINTED"; "BY"; pr = LIDENT;
+ f = OPT [ "INTERPRETED"; "BY"; f = LIDENT -> f ];
+ g = OPT [ "GLOBALIZED"; "BY"; f = LIDENT -> f ];
+ h = OPT [ "SUBSTITUTED"; "BY"; f = LIDENT -> f ];
+ special = OPT argextend_specialized ->
+ let repr = match special with
+ | None -> `Uniform (typ, pr)
+ | Some (rtyp, rpr, gtyp, gpr) -> `Specialized (rtyp, rpr, gtyp, gpr, typ, pr)
+ in
+ (repr, f, g, h) ] ]
+ ;
+ argtype:
+ [ "2"
+ [ e1 = argtype; "*"; e2 = argtype -> PairArgType (e1, e2) ]
+ | "1"
+ [ e = argtype; LIDENT "list" -> ListArgType e
+ | e = argtype; LIDENT "option" -> OptArgType e ]
+ | "0"
+ [ e = LIDENT ->
+ let e = parse_user_entry e "" in
+ type_of_user_symbol e
+ | "("; e = argtype; ")" -> e ] ]
+ ;
+ argrule:
+ [ [ "["; l = LIST0 genarg; "]"; "->"; "["; e = Pcaml.expr; "]" -> (l,e) ] ]
+ ;
+ genarg:
+ [ [ e = LIDENT; "("; s = LIDENT; ")" ->
+ let e = parse_user_entry e "" in
+ ExtNonTerminal (e, s)
+ | e = LIDENT; "("; s = LIDENT; ","; sep = STRING; ")" ->
+ let e = parse_user_entry e sep in
+ ExtNonTerminal (e, s)
+ | s = STRING -> ExtTerminal s
+ ] ]
+ ;
+ entry_name:
+ [ [ s = LIDENT -> s
+ | UIDENT -> failwith "Argument entry names must be lowercase"
+ ] ]
+ ;
+ END
diff --git a/grammar/gramCompat.mlp b/grammar/gramCompat.mlp
new file mode 100644
index 000000000..6246da7bb
--- /dev/null
+++ b/grammar/gramCompat.mlp
@@ -0,0 +1,86 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** Compatibility file depending on ocaml/camlp4 version *)
+
+(** Misc module emulation *)
+
+IFDEF CAMLP5 THEN
+
+module CompatLoc = struct
+ include Ploc
+ let ghost = dummy
+ let merge = encl
+end
+
+ELSE
+
+module CompatLoc = Camlp4.PreCast.Loc
+
+END
+
+IFDEF CAMLP5 THEN
+
+module PcamlSig = struct end
+
+ELSE
+
+module PcamlSig = Camlp4.Sig
+module Ast = Camlp4.PreCast.Ast
+module Pcaml = Camlp4.PreCast.Syntax
+module MLast = Ast
+
+END
+
+(** Compatibility with camlp5 strict mode *)
+IFDEF CAMLP5 THEN
+ IFDEF STRICT THEN
+ let vala x = Ploc.VaVal x
+ ELSE
+ let vala x = x
+ END
+ELSE
+ let vala x = x
+END
+
+(** Fix a quotation difference in [str_item] *)
+
+let declare_str_items loc l =
+IFDEF CAMLP5 THEN
+ MLast.StDcl (loc, vala l) (* correspond to <:str_item< declare $list:l'$ end >> *)
+ELSE
+ Ast.stSem_of_list l
+END
+
+(** Quotation difference for match clauses *)
+
+let default_patt loc =
+ (<:patt< _ >>, vala None, <:expr< failwith "Extension: cannot occur" >>)
+
+IFDEF CAMLP5 THEN
+
+let make_fun loc cl =
+ let l = cl @ [default_patt loc] in
+ MLast.ExFun (loc, vala l) (* correspond to <:expr< fun [ $list:l$ ] >> *)
+
+ELSE
+
+let make_fun loc cl =
+ let mk_when = function
+ | Some w -> w
+ | None -> Ast.ExNil loc
+ in
+ let mk_clause (patt,optwhen,expr) =
+ (* correspond to <:match_case< ... when ... -> ... >> *)
+ Ast.McArr (loc, patt, mk_when optwhen, expr) in
+ let init = mk_clause (default_patt loc) in
+ let add_clause x acc = Ast.McOr (loc, mk_clause x, acc) in
+ let l = List.fold_right add_clause cl init in
+ Ast.ExFun (loc,l) (* correspond to <:expr< fun [ $l$ ] >> *)
+
+END
diff --git a/grammar/grammar.mllib b/grammar/grammar.mllib
deleted file mode 100644
index 4432f4306..000000000
--- a/grammar/grammar.mllib
+++ /dev/null
@@ -1,66 +0,0 @@
-Coq_config
-
-Hook
-Terminal
-Canary
-Hashset
-Hashcons
-CSet
-CMap
-Int
-Dyn
-HMap
-Option
-Store
-Exninfo
-Backtrace
-Pp_control
-Flags
-Loc
-CList
-CString
-Serialize
-Stateid
-Feedback
-Pp
-
-CArray
-CStack
-Util
-Ppstyle
-Errors
-Bigint
-Predicate
-Segmenttree
-Unicodetable
-Unicode
-Genarg
-
-Evar
-Names
-
-Libnames
-
-Redops
-Miscops
-Locusops
-
-Stdarg
-Constrarg
-Constrexpr_ops
-
-Compat
-Tok
-Lexer
-Entry
-Pcoq
-G_prim
-G_tactic
-G_ltac
-G_constr
-
-Q_util
-Egramml
-Argextend
-Tacextend
-Vernacextend
diff --git a/grammar/q_constr.ml4 b/grammar/q_constr.ml4
deleted file mode 100644
index 40db81949..000000000
--- a/grammar/q_constr.ml4
+++ /dev/null
@@ -1,120 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(*i camlp4deps: "tools/compat5b.cmo" i*)
-
-open Q_util
-open Compat
-open Pcaml
-open PcamlSig (* necessary for camlp4 *)
-
-let loc = CompatLoc.ghost
-let dloc = <:expr< Loc.ghost >>
-
-let apply_ref f l =
- <:expr<
- Glob_term.GApp ($dloc$, Glob_term.GRef ($dloc$, Lazy.force $f$, None), $mlexpr_of_list (fun x -> x) l$)
- >>
-
-EXTEND
- GLOBAL: expr;
- expr:
- [ [ "PATTERN"; "["; c = constr; "]" ->
- <:expr< snd (Patternops.pattern_of_glob_constr $c$) >> ] ]
- ;
- sort:
- [ [ "Set" -> Misctypes.GSet
- | "Prop" -> Misctypes.GProp
- | "Type" -> Misctypes.GType [] ] ]
- ;
- ident:
- [ [ s = string -> <:expr< Names.Id.of_string $str:s$ >> ] ]
- ;
- name:
- [ [ "_" -> <:expr< Anonymous >> | id = ident -> <:expr< Name $id$ >> ] ]
- ;
- string:
- [ [ s = UIDENT -> s | s = LIDENT -> s ] ]
- ;
- constr:
- [ "200" RIGHTA
- [ LIDENT "forall"; id = ident; ":"; c1 = constr; ","; c2 = constr ->
- <:expr< Glob_term.GProd ($dloc$,Name $id$,Decl_kinds.Explicit,$c1$,$c2$) >>
- | "fun"; id = ident; ":"; c1 = constr; "=>"; c2 = constr ->
- <:expr< Glob_term.GLambda ($dloc$,Name $id$,Decl_kinds.Explicit,$c1$,$c2$) >>
- | "let"; id = ident; ":="; c1 = constr; "in"; c2 = constr ->
- <:expr< Glob_term.RLetin ($dloc$,Name $id$,$c1$,$c2$) >>
- (* fix todo *)
- ]
- | "100" RIGHTA
- [ c1 = constr; ":"; c2 = SELF ->
- <:expr< Glob_term.GCast($dloc$,$c1$,DEFAULTcast,$c2$) >> ]
- | "90" RIGHTA
- [ c1 = constr; "->"; c2 = SELF ->
- <:expr< Glob_term.GProd ($dloc$,Anonymous,Decl_kinds.Explicit,$c1$,$c2$) >> ]
- | "75" RIGHTA
- [ "~"; c = constr ->
- apply_ref <:expr< coq_not_ref >> [c] ]
- | "70" RIGHTA
- [ c1 = constr; "="; c2 = NEXT; ":>"; t = NEXT ->
- apply_ref <:expr< coq_eq_ref >> [t;c1;c2] ]
- | "10" LEFTA
- [ f = constr; args = LIST1 NEXT ->
- let args = mlexpr_of_list (fun x -> x) args in
- <:expr< Glob_term.GApp ($dloc$,$f$,$args$) >> ]
- | "0"
- [ s = sort -> <:expr< Glob_term.GSort ($dloc$,s) >>
- | id = ident -> <:expr< Glob_term.GVar ($dloc$,$id$) >>
- | "_" -> <:expr< Glob_term.GHole ($dloc$,Evar_kinds.QuestionMark (Evar_kinds.Define False),Misctypes.IntroAnonymous,None) >>
- | "?"; id = ident -> <:expr< Glob_term.GPatVar($dloc$,(False,$id$)) >>
- | "{"; c1 = constr; "}"; "+"; "{"; c2 = constr; "}" ->
- apply_ref <:expr< coq_sumbool_ref >> [c1;c2]
- | "%"; e = string -> <:expr< Glob_term.GRef ($dloc$,Lazy.force $lid:e$, None) >>
- | c = match_constr -> c
- | "("; c = constr LEVEL "200"; ")" -> c ] ]
- ;
- match_constr:
- [ [ "match"; c = constr LEVEL "100"; (ty,nal) = match_type;
- "with"; OPT"|"; br = LIST0 eqn SEP "|"; "end" ->
- let br = mlexpr_of_list (fun x -> x) br in
- <:expr< Glob_term.GCases ($dloc$,$ty$,[($c$,$nal$)],$br$) >>
- ] ]
- ;
- match_type:
- [ [ "as"; id = ident; "in"; ind = LIDENT; nal = LIST0 name;
- "return"; ty = constr LEVEL "100" ->
- let nal = mlexpr_of_list (fun x -> x) nal in
- <:expr< Some $ty$ >>,
- <:expr< (Name $id$, Some ($dloc$,$lid:ind$,$nal$)) >>
- | -> <:expr< None >>, <:expr< (Anonymous, None) >> ] ]
- ;
- eqn:
- [ [ (lid,pl) = pattern; "=>"; rhs = constr ->
- let lid = mlexpr_of_list (fun x -> x) lid in
- <:expr< ($dloc$,$lid$,[$pl$],$rhs$) >>
- ] ]
- ;
- pattern:
- [ [ "%"; e = string; lip = LIST0 patvar ->
- let lp = mlexpr_of_list (fun (_,x) -> x) lip in
- let lid = List.flatten (List.map fst lip) in
- lid, <:expr< Glob_term.PatCstr ($dloc$,$lid:e$,$lp$,Anonymous) >>
- | p = patvar -> p
- | "("; p = pattern; ")" -> p ] ]
- ;
- patvar:
- [ [ "_" -> [], <:expr< Glob_term.PatVar ($dloc$,Anonymous) >>
- | id = ident -> [id], <:expr< Glob_term.PatVar ($dloc$,Name $id$) >>
- ] ]
- ;
- END;;
-
-(* Example
-open Coqlib
-let a = PATTERN [ match ?X with %path_of_S n => n | %path_of_O => ?X end ]
-*)
diff --git a/grammar/q_util.ml4 b/grammar/q_util.ml4
deleted file mode 100644
index c6e2e9966..000000000
--- a/grammar/q_util.ml4
+++ /dev/null
@@ -1,112 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(* This file defines standard combinators to build ml expressions *)
-
-open Extend
-open Compat
-
-type extend_token =
-| ExtTerminal of string
-| ExtNonTerminal of Genarg.argument_type * Extend.user_symbol * Names.Id.t
-
-let mlexpr_of_list f l =
- List.fold_right
- (fun e1 e2 ->
- let e1 = f e1 in
- let loc = CompatLoc.merge (MLast.loc_of_expr e1) (MLast.loc_of_expr e2) in
- <:expr< [$e1$ :: $e2$] >>)
- l (let loc = CompatLoc.ghost in <:expr< [] >>)
-
-let mlexpr_of_pair m1 m2 (a1,a2) =
- let e1 = m1 a1 and e2 = m2 a2 in
- let loc = CompatLoc.merge (MLast.loc_of_expr e1) (MLast.loc_of_expr e2) in
- <:expr< ($e1$, $e2$) >>
-
-let mlexpr_of_triple m1 m2 m3 (a1,a2,a3)=
- let e1 = m1 a1 and e2 = m2 a2 and e3 = m3 a3 in
- let loc = CompatLoc.merge (MLast.loc_of_expr e1) (MLast.loc_of_expr e3) in
- <:expr< ($e1$, $e2$, $e3$) >>
-
-let mlexpr_of_quadruple m1 m2 m3 m4 (a1,a2,a3,a4)=
- let e1 = m1 a1 and e2 = m2 a2 and e3 = m3 a3 and e4 = m4 a4 in
- let loc = CompatLoc.merge (MLast.loc_of_expr e1) (MLast.loc_of_expr e4) in
- <:expr< ($e1$, $e2$, $e3$, $e4$) >>
-
-(* We don't give location for tactic quotation! *)
-let loc = CompatLoc.ghost
-
-
-let mlexpr_of_bool = function
- | true -> <:expr< True >>
- | false -> <:expr< False >>
-
-let mlexpr_of_int n = <:expr< $int:string_of_int n$ >>
-
-let mlexpr_of_string s = <:expr< $str:s$ >>
-
-let mlexpr_of_option f = function
- | None -> <:expr< None >>
- | Some e -> <:expr< Some $f e$ >>
-
-let mlexpr_of_ident id =
- <:expr< Names.Id.of_string $str:Names.Id.to_string id$ >>
-
-let mlexpr_of_token = function
-| Tok.KEYWORD s -> <:expr< Tok.KEYWORD $mlexpr_of_string s$ >>
-| Tok.PATTERNIDENT s -> <:expr< Tok.PATTERNIDENT $mlexpr_of_string s$ >>
-| Tok.IDENT s -> <:expr< Tok.IDENT $mlexpr_of_string s$ >>
-| Tok.FIELD s -> <:expr< Tok.FIELD $mlexpr_of_string s$ >>
-| Tok.INT s -> <:expr< Tok.INT $mlexpr_of_string s$ >>
-| Tok.INDEX s -> <:expr< Tok.INDEX $mlexpr_of_string s$ >>
-| Tok.STRING s -> <:expr< Tok.STRING $mlexpr_of_string s$ >>
-| Tok.LEFTQMARK -> <:expr< Tok.LEFTQMARK >>
-| Tok.BULLET s -> <:expr< Tok.BULLET $mlexpr_of_string s$ >>
-| Tok.EOI -> <:expr< Tok.EOI >>
-
-let repr_entry e =
- let entry u =
- let _ = Pcoq.get_entry u e in
- Some (Entry.univ_name u, e)
- in
- try entry Pcoq.uprim with Not_found ->
- try entry Pcoq.uconstr with Not_found ->
- try entry Pcoq.utactic with Not_found -> None
-
-let rec mlexpr_of_prod_entry_key = function
- | Extend.Ulist1 s -> <:expr< Pcoq.Alist1 $mlexpr_of_prod_entry_key s$ >>
- | Extend.Ulist1sep (s,sep) -> <:expr< Pcoq.Alist1sep $mlexpr_of_prod_entry_key s$ $str:sep$ >>
- | Extend.Ulist0 s -> <:expr< Pcoq.Alist0 $mlexpr_of_prod_entry_key s$ >>
- | Extend.Ulist0sep (s,sep) -> <:expr< Pcoq.Alist0sep $mlexpr_of_prod_entry_key s$ $str:sep$ >>
- | Extend.Uopt s -> <:expr< Pcoq.Aopt $mlexpr_of_prod_entry_key s$ >>
- | Extend.Umodifiers s -> <:expr< Pcoq.Amodifiers $mlexpr_of_prod_entry_key s$ >>
- | Extend.Uentry e ->
- begin match repr_entry e with
- | None -> <:expr< Pcoq.Aentry (Pcoq.name_of_entry $lid:e$) >>
- | Some (u, s) -> <:expr< Pcoq.Aentry (Entry.unsafe_of_name ($str:u$, $str:s$)) >>
- end
- | Extend.Uentryl (e, l) ->
- (** Keep in sync with Pcoq! *)
- assert (CString.equal e "tactic");
- if l = 5 then <:expr< Pcoq.Aentry (Pcoq.name_of_entry Pcoq.Tactic.binder_tactic) >>
- else <:expr< Pcoq.Aentryl (Pcoq.name_of_entry Pcoq.Tactic.tactic_expr) $mlexpr_of_int l$ >>
-
-let type_entry u e =
- let Pcoq.TypedEntry (t, _) = Pcoq.get_entry u e in
- Genarg.unquote t
-
-let rec type_of_user_symbol = function
-| Ulist1 s | Ulist1sep (s, _) | Ulist0 s | Ulist0sep (s, _) | Umodifiers s ->
- Genarg.ListArgType (type_of_user_symbol s)
-| Uopt s ->
- Genarg.OptArgType (type_of_user_symbol s)
-| Uentry e | Uentryl (e, _) ->
- try type_entry Pcoq.uprim e with Not_found ->
- try type_entry Pcoq.uconstr e with Not_found ->
- try type_entry Pcoq.utactic e with Not_found ->
- Genarg.ExtraArgType e
diff --git a/grammar/q_util.mli b/grammar/q_util.mli
index d0e0dab22..a5e36e47b 100644
--- a/grammar/q_util.mli
+++ b/grammar/q_util.mli
@@ -6,11 +6,26 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Compat (* necessary for camlp4 *)
+open GramCompat (* necessary for camlp4 *)
+
+type argument_type =
+| ListArgType of argument_type
+| OptArgType of argument_type
+| PairArgType of argument_type * argument_type
+| ExtraArgType of string
+
+type user_symbol =
+| Ulist1 of user_symbol
+| Ulist1sep of user_symbol * string
+| Ulist0 of user_symbol
+| Ulist0sep of user_symbol * string
+| Uopt of user_symbol
+| Uentry of string
+| Uentryl of string * int
type extend_token =
| ExtTerminal of string
-| ExtNonTerminal of Genarg.argument_type * Extend.user_symbol * Names.Id.t
+| ExtNonTerminal of user_symbol * string
val mlexpr_of_list : ('a -> MLast.expr) -> 'a list -> MLast.expr
@@ -18,14 +33,6 @@ val mlexpr_of_pair :
('a -> MLast.expr) -> ('b -> MLast.expr)
-> 'a * 'b -> MLast.expr
-val mlexpr_of_triple :
- ('a -> MLast.expr) -> ('b -> MLast.expr) -> ('c -> MLast.expr)
- -> 'a * 'b * 'c -> MLast.expr
-
-val mlexpr_of_quadruple :
- ('a -> MLast.expr) -> ('b -> MLast.expr) ->
- ('c -> MLast.expr) -> ('d -> MLast.expr) -> 'a * 'b * 'c * 'd -> MLast.expr
-
val mlexpr_of_bool : bool -> MLast.expr
val mlexpr_of_int : int -> MLast.expr
@@ -34,8 +41,8 @@ val mlexpr_of_string : string -> MLast.expr
val mlexpr_of_option : ('a -> MLast.expr) -> 'a option -> MLast.expr
-val mlexpr_of_ident : Names.Id.t -> MLast.expr
+val mlexpr_of_prod_entry_key : (string -> MLast.expr) -> user_symbol -> MLast.expr
-val mlexpr_of_prod_entry_key : Extend.user_symbol -> MLast.expr
+val type_of_user_symbol : user_symbol -> argument_type
-val type_of_user_symbol : Extend.user_symbol -> Genarg.argument_type
+val parse_user_entry : string -> string -> user_symbol
diff --git a/grammar/q_util.mlp b/grammar/q_util.mlp
new file mode 100644
index 000000000..2d5c40894
--- /dev/null
+++ b/grammar/q_util.mlp
@@ -0,0 +1,118 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(* This file defines standard combinators to build ml expressions *)
+
+open GramCompat
+
+type argument_type =
+| ListArgType of argument_type
+| OptArgType of argument_type
+| PairArgType of argument_type * argument_type
+| ExtraArgType of string
+
+type user_symbol =
+| Ulist1 of user_symbol
+| Ulist1sep of user_symbol * string
+| Ulist0 of user_symbol
+| Ulist0sep of user_symbol * string
+| Uopt of user_symbol
+| Uentry of string
+| Uentryl of string * int
+
+type extend_token =
+| ExtTerminal of string
+| ExtNonTerminal of user_symbol * string
+
+let mlexpr_of_list f l =
+ List.fold_right
+ (fun e1 e2 ->
+ let e1 = f e1 in
+ let loc = CompatLoc.merge (MLast.loc_of_expr e1) (MLast.loc_of_expr e2) in
+ <:expr< [$e1$ :: $e2$] >>)
+ l (let loc = CompatLoc.ghost in <:expr< [] >>)
+
+let mlexpr_of_pair m1 m2 (a1,a2) =
+ let e1 = m1 a1 and e2 = m2 a2 in
+ let loc = CompatLoc.merge (MLast.loc_of_expr e1) (MLast.loc_of_expr e2) in
+ <:expr< ($e1$, $e2$) >>
+
+(* We don't give location for tactic quotation! *)
+let loc = CompatLoc.ghost
+
+
+let mlexpr_of_bool = function
+ | true -> <:expr< True >>
+ | false -> <:expr< False >>
+
+let mlexpr_of_int n = <:expr< $int:string_of_int n$ >>
+
+let mlexpr_of_string s = <:expr< $str:s$ >>
+
+let mlexpr_of_option f = function
+ | None -> <:expr< None >>
+ | Some e -> <:expr< Some $f e$ >>
+
+let symbol_of_string s = <:expr< Extend.Atoken (CLexer.terminal $str:s$) >>
+
+let rec mlexpr_of_prod_entry_key f = function
+ | Ulist1 s -> <:expr< Extend.Alist1 $mlexpr_of_prod_entry_key f s$ >>
+ | Ulist1sep (s,sep) -> <:expr< Extend.Alist1sep $mlexpr_of_prod_entry_key f s$ $symbol_of_string sep$ >>
+ | Ulist0 s -> <:expr< Extend.Alist0 $mlexpr_of_prod_entry_key f s$ >>
+ | Ulist0sep (s,sep) -> <:expr< Extend.Alist0sep $mlexpr_of_prod_entry_key f s$ $symbol_of_string sep$ >>
+ | Uopt s -> <:expr< Extend.Aopt $mlexpr_of_prod_entry_key f s$ >>
+ | Uentry e -> <:expr< Extend.Aentry $f e$ >>
+ | Uentryl (e, l) ->
+ (** Keep in sync with Pcoq! *)
+ assert (e = "tactic");
+ if l = 5 then <:expr< Extend.Aentry (Pcoq.Tactic.binder_tactic) >>
+ else <:expr< Extend.Aentryl (Pcoq.Tactic.tactic_expr) $mlexpr_of_int l$ >>
+
+let rec type_of_user_symbol = function
+| Ulist1 s | Ulist1sep (s, _) | Ulist0 s | Ulist0sep (s, _) ->
+ ListArgType (type_of_user_symbol s)
+| Uopt s ->
+ OptArgType (type_of_user_symbol s)
+| Uentry e | Uentryl (e, _) -> ExtraArgType e
+
+let coincide s pat off =
+ let len = String.length pat in
+ let break = ref true in
+ let i = ref 0 in
+ while !break && !i < len do
+ let c = Char.code s.[off + !i] in
+ let d = Char.code pat.[!i] in
+ break := c = d;
+ incr i
+ done;
+ !break
+
+let rec parse_user_entry s sep =
+ let l = String.length s in
+ if l > 8 && coincide s "ne_" 0 && coincide s "_list" (l - 5) then
+ let entry = parse_user_entry (String.sub s 3 (l-8)) "" in
+ Ulist1 entry
+ else if l > 12 && coincide s "ne_" 0 &&
+ coincide s "_list_sep" (l-9) then
+ let entry = parse_user_entry (String.sub s 3 (l-12)) "" in
+ Ulist1sep (entry, sep)
+ else if l > 5 && coincide s "_list" (l-5) then
+ let entry = parse_user_entry (String.sub s 0 (l-5)) "" in
+ Ulist0 entry
+ else if l > 9 && coincide s "_list_sep" (l-9) then
+ let entry = parse_user_entry (String.sub s 0 (l-9)) "" in
+ Ulist0sep (entry, sep)
+ else if l > 4 && coincide s "_opt" (l-4) then
+ let entry = parse_user_entry (String.sub s 0 (l-4)) "" in
+ Uopt entry
+ else if l = 7 && coincide s "tactic" 0 && '5' >= s.[6] && s.[6] >= '0' then
+ let n = Char.code s.[6] - 48 in
+ Uentryl ("tactic", n)
+ else
+ let s = match s with "hyp" -> "var" | _ -> s in
+ Uentry s
diff --git a/grammar/tacextend.ml4 b/grammar/tacextend.mlp
index 10afcdd21..ac6a7ac7f 100644
--- a/grammar/tacextend.ml4
+++ b/grammar/tacextend.mlp
@@ -6,53 +6,31 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i camlp4deps: "tools/compat5b.cmo" i*)
-
(** Implementation of the TACTIC EXTEND macro. *)
-open Util
-open Pp
-open Names
-open Genarg
open Q_util
open Argextend
-open Pcoq
-open Egramml
-open Compat
+open GramCompat
let dloc = <:expr< Loc.ghost >>
let plugin_name = <:expr< __coq_plugin_name >>
+let mlexpr_of_ident id =
+ (** Workaround for badly-designed generic arguments lacking a closure *)
+ let id = "$" ^ id in
+ <:expr< Names.Id.of_string_soft $str:id$ >>
+
let rec make_patt = function
| [] -> <:patt< [] >>
- | ExtNonTerminal (_, _, p) :: l ->
- let p = Names.Id.to_string p in
+ | ExtNonTerminal (_, p) :: l ->
<:patt< [ $lid:p$ :: $make_patt l$ ] >>
| _::l -> make_patt l
-let rec mlexpr_of_argtype loc = function
- | Genarg.ListArgType t -> <:expr< Genarg.ListArgType $mlexpr_of_argtype loc t$ >>
- | Genarg.OptArgType t -> <:expr< Genarg.OptArgType $mlexpr_of_argtype loc t$ >>
- | Genarg.PairArgType (t1,t2) ->
- let t1 = mlexpr_of_argtype loc t1 in
- let t2 = mlexpr_of_argtype loc t2 in
- <:expr< Genarg.PairArgType $t1$ $t2$ >>
- | Genarg.ExtraArgType s -> <:expr< Genarg.ExtraArgType $str:s$ >>
-
-let rec make_when loc = function
- | [] -> <:expr< True >>
- | ExtNonTerminal (t, _, p) :: l ->
- let p = Names.Id.to_string p in
- let l = make_when loc l in
- let t = mlexpr_of_argtype loc t in
- <:expr< Genarg.argument_type_eq (Genarg.genarg_tag $lid:p$) $t$ && $l$ >>
- | _::l -> make_when loc l
-
let rec make_let raw e = function
| [] -> <:expr< fun $lid:"ist"$ -> $e$ >>
- | ExtNonTerminal (t, _, p) :: l ->
- let p = Names.Id.to_string p in
+ | ExtNonTerminal (g, p) :: l ->
+ let t = type_of_user_symbol g in
let loc = MLast.loc_of_expr e in
let e = make_let raw e l in
let v =
@@ -61,56 +39,47 @@ let rec make_let raw e = function
<:expr< let $lid:p$ = $v$ in $e$ >>
| _::l -> make_let raw e l
-let rec extract_signature = function
- | [] -> []
- | ExtNonTerminal (t, _, _) :: l -> t :: extract_signature l
- | _::l -> extract_signature l
-
-
-
-let check_unicity s l =
- let l' = List.map (fun (l,_,_) -> extract_signature l) l in
- if not (Util.List.distinct l') then
- Pp.msg_warning
- (strbrk ("Two distinct rules of tactic entry "^s^" have the same "^
- "non-terminals in the same order: put them in distinct tactic entries"))
-
let make_clause (pt,_,e) =
(make_patt pt,
vala None,
make_let false e pt)
let make_fun_clauses loc s l =
- check_unicity s l;
- let map c = Compat.make_fun loc [make_clause c] in
+ let map c = GramCompat.make_fun loc [make_clause c] in
mlexpr_of_list map l
+let get_argt e = <:expr< match $e$ with [ Genarg.ExtraArg tag -> tag | _ -> assert False ] >>
+
+let rec mlexpr_of_symbol = function
+| Ulist1 s -> <:expr< Extend.Ulist1 $mlexpr_of_symbol s$ >>
+| Ulist1sep (s,sep) -> <:expr< Extend.Ulist1sep $mlexpr_of_symbol s$ $str:sep$ >>
+| Ulist0 s -> <:expr< Extend.Ulist0 $mlexpr_of_symbol s$ >>
+| Ulist0sep (s,sep) -> <:expr< Extend.Ulist0sep $mlexpr_of_symbol s$ $str:sep$ >>
+| Uopt s -> <:expr< Extend.Uopt $mlexpr_of_symbol s$ >>
+| Uentry e ->
+ let arg = get_argt <:expr< $lid:"wit_"^e$ >> in
+ <:expr< Extend.Uentry (Genarg.ArgT.Any $arg$) >>
+| Uentryl (e, l) ->
+ assert (e = "tactic");
+ let arg = get_argt <:expr< Constrarg.wit_tactic >> in
+ <:expr< Extend.Uentryl (Genarg.ArgT.Any $arg$) $mlexpr_of_int l$>>
+
let make_prod_item = function
- | ExtTerminal s -> <:expr< Egramml.GramTerminal $str:s$ >>
- | ExtNonTerminal (nt, g, id) ->
- <:expr< Egramml.GramNonTerminal $default_loc$ $make_rawwit loc nt$
- $mlexpr_of_prod_entry_key g$ >>
+ | ExtTerminal s -> <:expr< Tacentries.TacTerm $str:s$ >>
+ | ExtNonTerminal (g, id) ->
+ <:expr< Tacentries.TacNonTerm $default_loc$ $mlexpr_of_symbol g$ $mlexpr_of_ident id$ >>
let mlexpr_of_clause cl =
mlexpr_of_list (fun (a,_,_) -> mlexpr_of_list make_prod_item a) cl
-let make_one_printing_rule (pt,_,e) =
- let level = mlexpr_of_int 0 in (* only level 0 supported here *)
- let loc = MLast.loc_of_expr e in
- let prods = mlexpr_of_list make_prod_item pt in
- <:expr< { Pptactic.pptac_level = $level$;
- pptac_prods = $prods$ } >>
-
-let make_printing_rule r = mlexpr_of_list make_one_printing_rule r
-
(** Special treatment of constr entries *)
let is_constr_gram = function
| ExtTerminal _ -> false
-| ExtNonTerminal (_, Extend.Uentry "constr", _) -> true
+| ExtNonTerminal (Uentry "constr", _) -> true
| _ -> false
let make_var = function
- | ExtNonTerminal (_, _, p) -> Some p
+ | ExtNonTerminal (_, p) -> Some p
| _ -> assert false
let declare_tactic loc s c cl = match cl with
@@ -124,14 +93,14 @@ let declare_tactic loc s c cl = match cl with
let se = <:expr< { Tacexpr.mltac_tactic = $entry$; Tacexpr.mltac_plugin = $plugin_name$ } >> in
let ml = <:expr< { Tacexpr.mltac_name = $se$; Tacexpr.mltac_index = 0 } >> in
let name = mlexpr_of_string name in
- let tac =
+ let tac = match rem with
+ | [] ->
(** Special handling of tactics without arguments: such tactics do not do
a Proofview.Goal.nf_enter to compute their arguments. It matters for some
whole-prof tactics like [shelve_unifiable]. *)
- if List.is_empty rem then
<:expr< fun _ $lid:"ist"$ -> $tac$ >>
- else
- let f = Compat.make_fun loc [patt, vala None, <:expr< fun $lid:"ist"$ -> $tac$ >>] in
+ | _ ->
+ let f = GramCompat.make_fun loc [patt, vala None, <:expr< fun $lid:"ist"$ -> $tac$ >>] in
<:expr< Tacinterp.lift_constr_tac_to_ml_tac $vars$ $f$ >>
in
(** Arguments are not passed directly to the ML tactic in the TacML node,
@@ -146,7 +115,7 @@ let declare_tactic loc s c cl = match cl with
Tacenv.register_ml_tactic $se$ [|$tac$|];
Mltop.declare_cache_obj obj $plugin_name$; }
with [ e when Errors.noncritical e ->
- Pp.msg_warning
+ Feedback.msg_warning
(Pp.app
(Pp.str ("Exception in tactic extend " ^ $entry$ ^": "))
(Errors.print e)) ]; } >>
@@ -156,17 +125,15 @@ let declare_tactic loc s c cl = match cl with
TacML tactic. *)
let entry = mlexpr_of_string s in
let se = <:expr< { Tacexpr.mltac_tactic = $entry$; Tacexpr.mltac_plugin = $plugin_name$ } >> in
- let pp = make_printing_rule cl in
let gl = mlexpr_of_clause cl in
- let obj = <:expr< fun () -> Metasyntax.add_ml_tactic_notation $se$ $gl$ >> in
+ let obj = <:expr< fun () -> Tacentries.add_ml_tactic_notation $se$ $gl$ >> in
declare_str_items loc
[ <:str_item< do {
try do {
Tacenv.register_ml_tactic $se$ (Array.of_list $make_fun_clauses loc s cl$);
- Mltop.declare_cache_obj $obj$ $plugin_name$;
- Pptactic.declare_ml_tactic_pprule $se$ (Array.of_list $pp$); }
+ Mltop.declare_cache_obj $obj$ $plugin_name$; }
with [ e when Errors.noncritical e ->
- Pp.msg_warning
+ Feedback.msg_warning
(Pp.app
(Pp.str ("Exception in tactic extend " ^ $entry$ ^": "))
(Errors.print e)) ]; } >>
@@ -198,12 +165,12 @@ EXTEND
tacargs:
[ [ e = LIDENT; "("; s = LIDENT; ")" ->
let e = parse_user_entry e "" in
- ExtNonTerminal (type_of_user_symbol e, e, Names.Id.of_string s)
+ ExtNonTerminal (e, s)
| e = LIDENT; "("; s = LIDENT; ","; sep = STRING; ")" ->
let e = parse_user_entry e sep in
- ExtNonTerminal (type_of_user_symbol e, e, Names.Id.of_string s)
+ ExtNonTerminal (e, s)
| s = STRING ->
- if String.is_empty s then Errors.user_err_loc (!@loc,"",Pp.str "Empty terminal.");
+ let () = if s = "" then failwith "Empty terminal." in
ExtTerminal s
] ]
;
diff --git a/grammar/vernacextend.ml4 b/grammar/vernacextend.mlp
index 57079fccd..ce0431889 100644
--- a/grammar/vernacextend.ml4
+++ b/grammar/vernacextend.mlp
@@ -6,18 +6,12 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i camlp4deps: "tools/compat5b.cmo" i*)
-
(** Implementation of the VERNAC EXTEND macro. *)
-open Pp
-open Util
open Q_util
open Argextend
open Tacextend
-open Pcoq
-open Egramml
-open Compat
+open GramCompat
type rule = {
r_head : string option;
@@ -34,8 +28,8 @@ type rule = {
let rec make_let e = function
| [] -> e
- | ExtNonTerminal (t, _, p) :: l ->
- let p = Names.Id.to_string p in
+ | ExtNonTerminal (g, p) :: l ->
+ let t = type_of_user_symbol g in
let loc = MLast.loc_of_expr e in
let e = make_let e l in
<:expr< let $lid:p$ = Genarg.out_gen $make_rawwit loc t$ $lid:p$ in $e$ >>
@@ -43,14 +37,16 @@ let rec make_let e = function
let make_clause { r_patt = pt; r_branch = e; } =
(make_patt pt,
- vala (Some (make_when (MLast.loc_of_expr e) pt)),
+ vala None,
make_let e pt)
(* To avoid warnings *)
let mk_ignore c pt =
- let names = CList.map_filter (function
- | ExtNonTerminal (_, _, p) -> Some (Names.Id.to_string p)
- | _ -> None) pt in
+ let fold accu = function
+ | ExtNonTerminal (_, p) -> p :: accu
+ | _ -> accu
+ in
+ let names = List.fold_left fold [] pt in
let fold accu id = <:expr< let _ = $lid:id$ in $accu$ >> in
let names = List.fold_left fold <:expr< () >> names in
<:expr< do { let _ = $names$ in $c$ } >>
@@ -59,34 +55,34 @@ let make_clause_classifier cg s { r_patt = pt; r_class = c; } =
match c ,cg with
| Some c, _ ->
(make_patt pt,
- vala (Some (make_when (MLast.loc_of_expr c) pt)),
+ vala None,
make_let (mk_ignore c pt) pt)
| None, Some cg ->
(make_patt pt,
- vala (Some (make_when (MLast.loc_of_expr cg) pt)),
+ vala None,
<:expr< fun () -> $cg$ $str:s$ >>)
- | None, None -> msg_warning
- (strbrk("Vernac entry \""^s^"\" misses a classifier. "^
+ | None, None -> prerr_endline
+ (("Vernac entry \""^s^"\" misses a classifier. "^
"A classifier is a function that returns an expression "^
- "of type vernac_classification (see Vernacexpr). You can: ")++
- str"- "++hov 0 (
- strbrk("Use '... EXTEND "^s^" CLASSIFIED AS QUERY ...' if the "^
- "new vernacular command does not alter the system state;"))++fnl()++
- str"- "++hov 0 (
- strbrk("Use '... EXTEND "^s^" CLASSIFIED AS SIDEFF ...' if the "^
+ "of type vernac_classification (see Vernacexpr). You can: ") ^
+ "- " ^ (
+ ("Use '... EXTEND "^s^" CLASSIFIED AS QUERY ...' if the "^
+ "new vernacular command does not alter the system state;"))^ "\n" ^
+ "- " ^ (
+ ("Use '... EXTEND "^s^" CLASSIFIED AS SIDEFF ...' if the "^
"new vernacular command alters the system state but not the "^
- "parser nor it starts a proof or ends one;"))++fnl()++
- str"- "++hov 0 (
- strbrk("Use '... EXTEND "^s^" CLASSIFIED BY f ...' to specify "^
+ "parser nor it starts a proof or ends one;"))^ "\n" ^
+ "- " ^ (
+ ("Use '... EXTEND "^s^" CLASSIFIED BY f ...' to specify "^
"a global function f. The function f will be called passing "^
- "\""^s^"\" as the only argument;")) ++fnl()++
- str"- "++hov 0 (
- strbrk"Add a specific classifier in each clause using the syntax:"
- ++fnl()++strbrk("'[...] => [ f ] -> [...]'. "))++fnl()++
- strbrk("Specific classifiers have precedence over global "^
- "classifiers. Only one classifier is called.")++fnl());
+ "\""^s^"\" as the only argument;")) ^ "\n" ^
+ "- " ^ (
+ "Add a specific classifier in each clause using the syntax:"
+ ^ "\n" ^("'[...] => [ f ] -> [...]'. "))^ "\n" ^
+ ("Specific classifiers have precedence over global "^
+ "classifiers. Only one classifier is called.") ^ "\n");
(make_patt pt,
- vala (Some (make_when loc pt)),
+ vala None,
<:expr< fun () -> (Vernacexpr.VtUnknown, Vernacexpr.VtNow) >>)
let make_fun_clauses loc s l =
@@ -95,19 +91,29 @@ let make_fun_clauses loc s l =
| None -> false
| Some () -> true
in
- let cl = Compat.make_fun loc [make_clause c] in
+ let cl = GramCompat.make_fun loc [make_clause c] in
<:expr< ($mlexpr_of_bool depr$, $cl$)>>
in
mlexpr_of_list map l
let make_fun_classifiers loc s c l =
- let cl = List.map (fun x -> Compat.make_fun loc [make_clause_classifier c s x]) l in
+ let cl = List.map (fun x -> GramCompat.make_fun loc [make_clause_classifier c s x]) l in
mlexpr_of_list (fun x -> x) cl
-let mlexpr_of_clause =
- mlexpr_of_list
- (fun { r_head = a; r_patt = b; } -> mlexpr_of_list make_prod_item
- (Option.List.cons (Option.map (fun a -> ExtTerminal a) a) b))
+let make_prod_item = function
+ | ExtTerminal s -> <:expr< Egramml.GramTerminal $str:s$ >>
+ | ExtNonTerminal (g, id) ->
+ let nt = type_of_user_symbol g in
+ let base s = <:expr< Pcoq.genarg_grammar ($mk_extraarg loc s$) >> in
+ <:expr< Egramml.GramNonTerminal $default_loc$ $make_rawwit loc nt$
+ $mlexpr_of_prod_entry_key base g$ >>
+
+let mlexpr_of_clause cl =
+ let mkexpr { r_head = a; r_patt = b; } = match a with
+ | None -> mlexpr_of_list make_prod_item b
+ | Some a -> mlexpr_of_list make_prod_item (ExtTerminal a :: b)
+ in
+ mlexpr_of_list mkexpr cl
let declare_command loc s c nt cl =
let se = mlexpr_of_string s in
@@ -120,7 +126,7 @@ let declare_command loc s c nt cl =
CList.iteri (fun i (depr, f) -> Vernacinterp.vinterp_add depr ($se$, i) f) $funcl$;
CList.iteri (fun i f -> Vernac_classifier.declare_vernac_classifier ($se$, i) f) $classl$ }
with [ e when Errors.noncritical e ->
- Pp.msg_warning
+ Feedback.msg_warning
(Pp.app
(Pp.str ("Exception in vernac extend " ^ $se$ ^": "))
(Errors.print e)) ];
@@ -165,8 +171,7 @@ EXTEND
rule:
[ [ "["; s = STRING; l = LIST0 args; "]";
d = OPT deprecation; c = OPT classifier; "->"; "["; e = Pcaml.expr; "]" ->
- if String.is_empty s then
- Errors.user_err_loc (!@loc,"",Pp.str"Command name is empty.");
+ let () = if s = "" then failwith "Command name is empty." in
let b = <:expr< fun () -> $e$ >> in
{ r_head = Some s; r_patt = l; r_class = c; r_branch = b; r_depr = d; }
| "[" ; "-" ; l = LIST1 args ; "]" ;
@@ -181,10 +186,10 @@ EXTEND
args:
[ [ e = LIDENT; "("; s = LIDENT; ")" ->
let e = parse_user_entry e "" in
- ExtNonTerminal (type_of_user_symbol e, e, Names.Id.of_string s)
+ ExtNonTerminal (e, s)
| e = LIDENT; "("; s = LIDENT; ","; sep = STRING; ")" ->
let e = parse_user_entry e sep in
- ExtNonTerminal (type_of_user_symbol e, e, Names.Id.of_string s)
+ ExtNonTerminal (e, s)
| s = STRING ->
ExtTerminal s
] ]
diff --git a/ide/coq.lang b/ide/coq.lang
index e25eedbca..484264ece 100644
--- a/ide/coq.lang
+++ b/ide/coq.lang
@@ -95,11 +95,24 @@
<keyword>Type</keyword>
</context>
- <context id="coq" class="no-spell-check">
+ <!-- Terms -->
+ <context id="constr">
<include>
<context ref="string"/>
<context ref="coqdoc"/>
<context ref="comment"/>
+ <context ref="constr-sort"/>
+ <context ref="constr-keyword"/>
+ <context id="dot-nosep">
+ <match>\.\.</match>
+ </context>
+ </include>
+ </context>
+
+ <context id="coq" class="no-spell-check">
+ <include>
+ <context ref="coqdoc"/>
+ <context ref="comment"/>
<context id="declaration">
<start>\%{decl_head}</start>
@@ -110,14 +123,7 @@
<context sub-pattern="gal2" where="start" style-ref="gallina-keyword"/>
<context sub-pattern="id_list" where="start" style-ref="identifier"/>
<context sub-pattern="gal4list" where="start" style-ref="gallina-keyword"/>
- <context ref="constr-keyword"/>
- <context ref="constr-sort"/>
- <context id="dot-nosep">
- <match>\.\.</match>
- </context>
- <context ref="string"/>
- <context ref="coqdoc"/>
- <context ref="comment"/>
+ <context ref="constr"/>
</include>
</context>
@@ -127,21 +133,19 @@
<include>
<context sub-pattern="0" where="start" style-ref="vernac-keyword"/>
<context sub-pattern="0" where="end" style-ref="vernac-keyword"/>
- <context ref="command-in-proof"/>
- <context ref="string"/>
<context ref="coqdoc"/>
<context ref="comment"/>
- <context ref="constr-keyword"/>
- <context ref="constr-sort"/>
- <context id="bullet" extend-parent="false">
- <match>\%{dot_sep}\s*(?'bul'\%{bullet})</match>
+ <context id="bullet" style-ref="vernac-keyword" extend-parent="false">
+ <match>\%{bullet}</match>
+ </context>
+ <context extend-parent="false">
+ <start>\%[</start>
+ <end>\%{dot_sep}</end>
<include>
- <context sub-pattern="bul" style-ref="vernac-keyword"/>
+ <context ref="command-in-proof"/>
+ <context ref="constr"/>
</include>
</context>
- <context id="bullet-sol" style-ref="vernac-keyword">
- <match>^\s*\%{bullet}</match>
- </context>
</include>
</context>
@@ -150,11 +154,19 @@
<end>\%{dot_sep}</end>
<include>
<context sub-pattern="0" where="start" style-ref="vernac-keyword"/>
- <context ref="constr-keyword"/>
- <context ref="constr-sort"/>
+ <context ref="constr"/>
</include>
</context>
+ <context ref="command"/>
+ </include>
+ </context>
+
+ <!-- Toplevel commands -->
+ <context id="command" extend-parent="false">
+ <start>\%[</start>
+ <end>\%{dot_sep}</end>
+ <include>
<context id="command-in-proof" style-ref="vernac-keyword">
<keyword>About</keyword>
<keyword>Check</keyword>
@@ -166,7 +178,7 @@
<keyword>Transparent</keyword>
</context>
- <context id="command" style-ref="vernac-keyword">
+ <context id="toplevel-command" style-ref="vernac-keyword">
<keyword>Add</keyword>
<keyword>Load</keyword>
<keyword>(Print|Reset)\%{space}+Extraction\%{space}+(Inline|Blacklist)</keyword>
@@ -228,7 +240,10 @@
<context sub-pattern="qua_list" style-ref="identifier"/>
</include>
</context>
+
+ <context ref="constr"/>
</include>
</context>
+
</definitions>
</language>
diff --git a/ide/coq.ml b/ide/coq.ml
index fa0adf979..61f002576 100644
--- a/ide/coq.ml
+++ b/ide/coq.ml
@@ -290,23 +290,20 @@ let rec check_errors = function
| `NVAL :: _ -> raise (TubeError "NVAL")
| `OUT :: _ -> raise (TubeError "OUT")
-let handle_intermediate_message handle xml =
- let message = Pp.to_message xml in
- let level = message.Pp.message_level in
- let content = message.Pp.message_content in
- let logger = match handle.waiting_for with
- | Some (_, l) -> l
+let handle_intermediate_message handle level content =
+ let logger = match handle.waiting_for with
+ | Some (_, l) -> l
| None -> function
- | Pp.Error -> fun s -> Minilib.log ~level:`ERROR (xml_to_string s)
- | Pp.Info -> fun s -> Minilib.log ~level:`INFO (xml_to_string s)
- | Pp.Notice -> fun s -> Minilib.log ~level:`NOTICE (xml_to_string s)
- | Pp.Warning -> fun s -> Minilib.log ~level:`WARNING (xml_to_string s)
- | Pp.Debug _ -> fun s -> Minilib.log ~level:`DEBUG (xml_to_string s)
+ | Feedback.Error -> fun s -> Minilib.log ~level:`ERROR (xml_to_string s)
+ | Feedback.Info -> fun s -> Minilib.log ~level:`INFO (xml_to_string s)
+ | Feedback.Notice -> fun s -> Minilib.log ~level:`NOTICE (xml_to_string s)
+ | Feedback.Warning -> fun s -> Minilib.log ~level:`WARNING (xml_to_string s)
+ | Feedback.Debug _ -> fun s -> Minilib.log ~level:`DEBUG (xml_to_string s)
in
- logger level (Richpp.richpp_of_xml content)
+ logger level content
let handle_feedback feedback_processor xml =
- let feedback = Feedback.to_feedback xml in
+ let feedback = Xmlprotocol.to_feedback xml in
feedback_processor feedback
let handle_final_answer handle xml =
@@ -335,15 +332,18 @@ let unsafe_handle_input handle feedback_processor state conds ~read_all =
let l_end = Lexing.lexeme_end lex in
state.fragment <- String.sub s l_end (String.length s - l_end);
state.lexerror <- None;
- if Pp.is_message xml then begin
- handle_intermediate_message handle xml;
+ match Xmlprotocol.is_message xml with
+ | Some (lvl, msg) ->
+ handle_intermediate_message handle lvl msg;
loop ()
- end else if Feedback.is_feedback xml then begin
- handle_feedback feedback_processor xml;
- loop ()
- end else begin
- ignore (handle_final_answer handle xml)
- end
+ | None ->
+ if Xmlprotocol.is_feedback xml then begin
+ handle_feedback feedback_processor xml;
+ loop ()
+ end else
+ begin
+ ignore (handle_final_answer handle xml)
+ end
in
try loop ()
with Xml_parser.Error _ as e ->
@@ -357,7 +357,9 @@ let unsafe_handle_input handle feedback_processor state conds ~read_all =
let print_exception = function
| Xml_parser.Error e -> Xml_parser.error e
- | Serialize.Marshal_error -> "Protocol violation"
+ | Serialize.Marshal_error(expected,actual) ->
+ "Protocol violation. Expected: " ^ expected ^ " Actual: "
+ ^ Xml_printer.to_string actual
| e -> Printexc.to_string e
let input_watch handle respawner feedback_processor =
diff --git a/ide/coq.png b/ide/coq.png
index cccd5a9a1..136bfdd5f 100644
--- a/ide/coq.png
+++ b/ide/coq.png
Binary files differ
diff --git a/ide/coqOps.ml b/ide/coqOps.ml
index 6200f1490..6ffe771da 100644
--- a/ide/coqOps.ml
+++ b/ide/coqOps.ml
@@ -12,7 +12,9 @@ open Ideutils
open Interface
open Feedback
-type flag = [ `INCOMPLETE | `UNSAFE | `PROCESSING | `ERROR of string ]
+let b2c = byte_offset_to_char_offset
+
+type flag = [ `INCOMPLETE | `UNSAFE | `PROCESSING | `ERROR of Loc.t * string ]
type mem_flag = [ `INCOMPLETE | `UNSAFE | `PROCESSING | `ERROR ]
let mem_flag_of_flag : flag -> mem_flag = function
| `ERROR _ -> `ERROR
@@ -44,12 +46,9 @@ module SentenceId : sig
val mk_sentence :
start:GText.mark -> stop:GText.mark -> flag list -> sentence
- val set_flags : sentence -> flag list -> unit
val add_flag : sentence -> flag -> unit
val has_flag : sentence -> mem_flag -> bool
val remove_flag : sentence -> mem_flag -> unit
- val same_sentence : sentence -> sentence -> bool
- val hidden_edit_id : unit -> int
val find_all_tooltips : sentence -> int -> string list
val add_tooltip : sentence -> int -> int -> string -> unit
val set_index : sentence -> int -> unit
@@ -87,18 +86,15 @@ end = struct
index = -1;
changed_sig = new GUtil.signal ();
}
- let hidden_edit_id () = decr id; !id
let changed s =
s.changed_sig#call (s.index, List.map mem_flag_of_flag s.flags)
- let set_flags s f = s.flags <- f; changed s
let add_flag s f = s.flags <- CList.add_set (=) f s.flags; changed s
let has_flag s mf =
List.exists (fun f -> mem_flag_of_flag f = mf) s.flags
let remove_flag s mf =
s.flags <- List.filter (fun f -> mem_flag_of_flag f <> mf) s.flags; changed s
- let same_sentence s1 s2 = s1.edit_id = s2.edit_id
let find_all_tooltips s off =
CList.map_filter (fun (start,stop,t) ->
if start <= off && off <= stop then Some t else None)
@@ -402,8 +398,8 @@ object(self)
let start_sentence, stop_sentence, phrase = self#get_sentence sentence in
let pre_chars, post_chars =
if Loc.is_ghost loc then 0, String.length phrase else Loc.unloc loc in
- let pre = Ideutils.glib_utf8_pos_to_offset phrase ~off:pre_chars in
- let post = Ideutils.glib_utf8_pos_to_offset phrase ~off:post_chars in
+ let pre = b2c phrase pre_chars in
+ let post = b2c phrase post_chars in
let start = start_sentence#forward_chars pre in
let stop = start_sentence#forward_chars post in
let markup = Glib.Markup.escape_text text in
@@ -467,7 +463,7 @@ object(self)
| ErrorMsg(loc, msg), Some (id,sentence) ->
log "ErrorMsg" id;
remove_flag sentence `PROCESSING;
- add_flag sentence (`ERROR msg);
+ add_flag sentence (`ERROR (loc, msg));
self#mark_as_needed sentence;
self#attach_tooltip sentence loc msg;
if not (Loc.is_ghost loc) then
@@ -506,8 +502,8 @@ object(self)
| None -> ()
| Some (start, stop) ->
buffer#apply_tag Tags.Script.error
- ~start:(iter#forward_chars (byte_offset_to_char_offset phrase start))
- ~stop:(iter#forward_chars (byte_offset_to_char_offset phrase stop))
+ ~start:(iter#forward_chars (b2c phrase start))
+ ~stop:(iter#forward_chars (b2c phrase stop))
method private position_error_tag_at_sentence sentence loc =
let start, _, phrase = self#get_sentence sentence in
@@ -523,7 +519,7 @@ object(self)
self#position_error_tag_at_iter start phrase loc;
buffer#place_cursor ~where:stop;
messages#clear;
- messages#push Pp.Error msg;
+ messages#push Feedback.Error msg;
self#show_goals
end else
self#show_goals_aux ~move_insert:true ()
@@ -599,7 +595,8 @@ object(self)
if Queue.is_empty queue then conclude topstack else
match Queue.pop queue, topstack with
| `Skip(start,stop), [] ->
- logger Pp.Error (Richpp.richpp_of_string "You must close the proof with Qed or Admitted");
+
+ logger Feedback.Error (Richpp.richpp_of_string "You must close the proof with Qed or Admitted");
self#discard_command_queue queue;
conclude []
| `Skip(start,stop), (_,s) :: topstack ->
@@ -615,7 +612,7 @@ object(self)
let handle_answer = function
| Good (id, (Util.Inl (* NewTip *) (), msg)) ->
Doc.assign_tip_id document id;
- logger Pp.Notice (Richpp.richpp_of_string msg);
+ logger Feedback.Notice (Richpp.richpp_of_string msg);
self#commit_queue_transaction sentence;
loop id []
| Good (id, (Util.Inr (* Unfocus *) tip, msg)) ->
@@ -623,7 +620,7 @@ object(self)
let topstack, _ = Doc.context document in
self#exit_focus;
self#cleanup (Doc.cut_at document tip);
- logger Pp.Notice (Richpp.richpp_of_string msg);
+ logger Feedback.Notice (Richpp.richpp_of_string msg);
self#mark_as_needed sentence;
if Queue.is_empty queue then loop tip []
else loop tip (List.rev topstack)
@@ -642,7 +639,7 @@ object(self)
let next = function
| Good _ ->
messages#clear;
- messages#push Pp.Info (Richpp.richpp_of_string "All proof terms checked by the kernel");
+ messages#push Feedback.Info (Richpp.richpp_of_string "All proof terms checked by the kernel");
Coq.return ()
| Fail x -> self#handle_failure x in
Coq.bind (Coq.status ~logger:messages#push true) next
@@ -658,7 +655,15 @@ object(self)
method get_errors =
let extract_error s =
match List.find (function `ERROR _ -> true | _ -> false) s.flags with
- | `ERROR msg -> (buffer#get_iter_at_mark s.start)#line + 1, msg
+ | `ERROR (loc, msg) ->
+ let iter =
+ if Loc.is_ghost loc then
+ buffer#get_iter_at_mark s.start
+ else
+ let (iter, _, phrase) = self#get_sentence s in
+ let (start, _) = Loc.unloc loc in
+ iter#forward_chars (b2c phrase start) in
+ iter#line + 1, msg
| _ -> assert false in
List.rev
(Doc.fold_all document [] (fun acc _ _ s ->
@@ -736,8 +741,8 @@ object(self)
self#cleanup (Doc.cut_at document to_id);
conclusion ()
| Fail (safe_id, loc, msg) ->
- if loc <> None then messages#push Pp.Error (Richpp.richpp_of_string "Fixme LOC");
- messages#push Pp.Error msg;
+(* if loc <> None then messages#push Feedback.Error (Richpp.richpp_of_string "Fixme LOC"); *)
+ messages#push Feedback.Error msg;
if Stateid.equal safe_id Stateid.dummy then self#show_goals
else undo safe_id
(Doc.focused document && Doc.is_in_focus document safe_id))
@@ -755,7 +760,7 @@ object(self)
?(move_insert=false) (safe_id, (loc : (int * int) option), msg)
=
messages#clear;
- messages#push Pp.Error msg;
+ messages#push Feedback.Error msg;
ignore(self#process_feedback ());
if Stateid.equal safe_id Stateid.dummy then Coq.lift (fun () -> ())
else
@@ -869,7 +874,10 @@ object(self)
method initialize =
let get_initial_state =
let next = function
- | Fail _ -> messages#set (Richpp.richpp_of_string "Couln't initialize Coq"); Coq.return ()
+ | Fail (_, _, message) ->
+ let message = "Couldn't initialize coqtop\n\n" ^ (Richpp.raw_print message) in
+ let popup = GWindow.message_dialog ~buttons:GWindow.Buttons.ok ~message_type:`ERROR ~message () in
+ ignore (popup#run ()); exit 1
| Good id -> initial_state <- id; Coq.return () in
Coq.bind (Coq.init (get_filename ())) next in
Coq.seq get_initial_state Coq.PrintOpt.enforce
diff --git a/ide/coqide.ml b/ide/coqide.ml
index 1fe393d2b..d1a799a77 100644
--- a/ide/coqide.ml
+++ b/ide/coqide.ml
@@ -677,12 +677,18 @@ let searchabout sn =
let searchabout () = on_current_term searchabout
+let doquery query sn =
+ sn.messages#clear;
+ Coq.try_grab sn.coqtop (sn.coqops#raw_coq_query query) ignore
+
let otherquery command sn =
- let word = get_current_word sn in
- if word <> "" then
- let query = command ^ " " ^ word ^ "." in
- sn.messages#clear;
- Coq.try_grab sn.coqtop (sn.coqops#raw_coq_query query) ignore
+ Option.iter (fun query -> doquery (query ^ ".") sn)
+ begin try
+ let i = CString.string_index_from command 0 "..." in
+ let word = get_current_word sn in
+ if word = "" then None
+ else Some (CString.sub command 0 i ^ " " ^ word)
+ with Not_found -> Some command end
let otherquery command = cb_on_current_term (otherquery command)
@@ -783,7 +789,7 @@ let coqtop_arguments sn =
let args = String.concat " " args in
let msg = Printf.sprintf "Invalid arguments: %s" args in
let () = sn.messages#clear in
- sn.messages#push Pp.Error (Richpp.richpp_of_string msg)
+ sn.messages#push Feedback.Error (Richpp.richpp_of_string msg)
else dialog#destroy ()
in
let _ = entry#connect#activate ok_cb in
@@ -859,12 +865,12 @@ let toggle_items menu_name l =
in
List.iter f l
+let no_under = Util.String.map (fun x -> if x = '_' then '-' else x)
+
(** Create alphabetical menu items with elements in sub-items.
[l] is a list of lists, one per initial letter *)
let alpha_items menu_name item_name l =
- let no_under = Util.String.map (fun x -> if x = '_' then '-' else x)
- in
let mk_item text =
let text' =
let last = String.length text - 1 in
@@ -911,6 +917,16 @@ let template_item (text, offset, len, key) =
in
item name ~label ~callback:(cb_on_current_term callback) ~accel:(modifier^key)
+(** Create menu items for pairs (query, shortcut key). *)
+let user_queries_items menu_name item_name l =
+ let mk_item (query, key) =
+ let callback = Query.query query in
+ let accel = if not (CString.is_empty key) then
+ Some (modifier_for_queries#get^key) else None in
+ item (item_name^" "^(no_under query)) ~label:query ?accel ~callback menu_name
+ in
+ List.iter mk_item l
+
let emit_to_focus window sgn =
let focussed_widget = GtkWindow.Window.get_focus window#as_window in
let obj = Gobject.unsafe_cast focussed_widget in
@@ -1100,16 +1116,22 @@ let build_ui () =
];
alpha_items templates_menu "Template" Coq_commands.commands;
- let qitem s accel = item s ~label:("_"^s) ?accel ~callback:(Query.query s) in
+ let qitem s sc ?(dots = true) =
+ let query = if dots then s ^ "..." else s in
+ item s ~label:("_"^s)
+ ~accel:(modifier_for_queries#get^sc)
+ ~callback:(Query.query query)
+ in
menu queries_menu [
item "Queries" ~label:"_Queries";
- qitem "Search" (Some "<Ctrl><Shift>K");
- qitem "Check" (Some "<Ctrl><Shift>C");
- qitem "Print" (Some "<Ctrl><Shift>P");
- qitem "About" (Some "<Ctrl><Shift>A");
- qitem "Locate" (Some "<Ctrl><Shift>L");
- qitem "Print Assumptions" (Some "<Ctrl><Shift>N");
+ qitem "Search" "K" ~dots:false;
+ qitem "Check" "C";
+ qitem "Print" "P";
+ qitem "About" "A";
+ qitem "Locate" "L";
+ qitem "Print Assumptions" "N";
];
+ user_queries_items queries_menu "User-Query" user_queries#get;
menu tools_menu [
item "Tools" ~label:"_Tools";
diff --git a/ide/coqide_ui.ml b/ide/coqide_ui.ml
index edfe28b26..2ae18593a 100644
--- a/ide/coqide_ui.ml
+++ b/ide/coqide_ui.ml
@@ -18,6 +18,15 @@ let list_items menu li =
let () = List.iter (fun b -> Buffer.add_buffer res_buf (tactic_item b)) li in
res_buf
+let list_queries menu li =
+ let res_buf = Buffer.create 500 in
+ let query_item (q, _) =
+ let s = "<menuitem action='"^menu^" "^(no_under q)^"' />\n" in
+ Buffer.add_string res_buf s
+ in
+ let () = List.iter query_item li in
+ res_buf
+
let init () =
let theui = Printf.sprintf "<ui>
<menubar name='CoqIde MenuBar'>
@@ -119,6 +128,8 @@ let init () =
<menuitem action='About' />
<menuitem action='Locate' />
<menuitem action='Print Assumptions' />
+ <separator />
+ %s
</menu>
<menu name='Tools' action='Tools'>
<menuitem action='Comment' />
@@ -162,5 +173,6 @@ let init () =
(if Coq_config.gtk_platform <> `QUARTZ then "<menuitem action='Quit' />" else "")
(Buffer.contents (list_items "Tactic" Coq_commands.tactics))
(Buffer.contents (list_items "Template" Coq_commands.commands))
+ (Buffer.contents (list_queries "User-Query" Preferences.user_queries#get))
in
ignore (ui_m#add_ui_from_string theui);
diff --git a/ide/coqidetop.mllib b/ide/coqidetop.mllib
index 92301dc30..ed1fa465d 100644
--- a/ide/coqidetop.mllib
+++ b/ide/coqidetop.mllib
@@ -1,2 +1,9 @@
+Xml_lexer
+Xml_parser
+Xml_printer
+Serialize
+Richprinter
Xmlprotocol
+Texmacspp
+Document
Ide_slave
diff --git a/ide/ide.mllib b/ide/ide.mllib
index 83b314283..b2f32fcf7 100644
--- a/ide/ide.mllib
+++ b/ide/ide.mllib
@@ -14,8 +14,13 @@ Config_lexer
Utf8_convert
Preferences
Project_file
-Ideutils
+Serialize
+Richprinter
+Xml_lexer
+Xml_parser
+Xml_printer
Xmlprotocol
+Ideutils
Coq
Coq_lex
Sentence
diff --git a/ide/ide_slave.ml b/ide/ide_slave.ml
index 12ef0e075..79affb36f 100644
--- a/ide/ide_slave.ml
+++ b/ide/ide_slave.ml
@@ -98,11 +98,11 @@ let coqide_cmd_checks (loc,ast) =
if is_debug ast then
user_error "Debug mode not available within CoqIDE";
if is_known_option ast then
- msg_warning (strbrk"This will not work. Use CoqIDE display menu instead");
+ Feedback.msg_warning (strbrk"This will not work. Use CoqIDE display menu instead");
if Vernac.is_navigation_vernac ast || is_undo ast then
- msg_warning (strbrk "Rather use CoqIDE navigation instead");
+ Feedback.msg_warning (strbrk "Rather use CoqIDE navigation instead");
if is_query ast then
- msg_warning (strbrk "Query commands should not be inserted in scripts")
+ Feedback.msg_warning (strbrk "Query commands should not be inserted in scripts")
(** Interpretation (cf. [Ide_intf.interp]) *)
@@ -212,7 +212,7 @@ let export_pre_goals pgs =
let goals () =
Stm.finish ();
let s = read_stdout () in
- if not (String.is_empty s) then msg_info (str s);
+ if not (String.is_empty s) then Feedback.msg_info (str s);
try
let pfts = Proof_global.give_me_the_proof () in
Some (export_pre_goals (Proof.map_structured_proof pfts process_goal))
@@ -222,7 +222,7 @@ let evars () =
try
Stm.finish ();
let s = read_stdout () in
- if not (String.is_empty s) then msg_info (str s);
+ if not (String.is_empty s) then Feedback.msg_info (str s);
let pfts = Proof_global.give_me_the_proof () in
let { Evd.it = all_goals ; sigma = sigma } = Proof.V82.subgoals pfts in
let exl = Evar.Map.bindings (Evarutil.non_instantiated sigma) in
@@ -255,7 +255,7 @@ let status force =
Stm.finish ();
if force then Stm.join ();
let s = read_stdout () in
- if not (String.is_empty s) then msg_info (str s);
+ if not (String.is_empty s) then Feedback.msg_info (str s);
let path =
let l = Names.DirPath.repr (Lib.cwd ()) in
List.rev_map Names.Id.to_string l
@@ -281,11 +281,33 @@ let export_coq_object t = {
Interface.coq_object_object = t.Search.coq_object_object
}
+let pattern_of_string ?env s =
+ let env =
+ match env with
+ | None -> Global.env ()
+ | Some e -> e
+ in
+ let constr = Pcoq.parse_string Pcoq.Constr.lconstr_pattern s in
+ let (_, pat) = Constrintern.intern_constr_pattern env constr in
+ pat
+
+let dirpath_of_string_list s =
+ let path = String.concat "." s in
+ let m = Pcoq.parse_string Pcoq.Constr.global path in
+ let (_, qid) = Libnames.qualid_of_reference m in
+ let id =
+ try Nametab.full_name_module qid
+ with Not_found ->
+ Errors.errorlabstrm "Search.interface_search"
+ (str "Module " ++ str path ++ str " not found.")
+ in
+ id
+
let import_search_constraint = function
- | Interface.Name_Pattern s -> Search.Name_Pattern s
- | Interface.Type_Pattern s -> Search.Type_Pattern s
- | Interface.SubType_Pattern s -> Search.SubType_Pattern s
- | Interface.In_Module ms -> Search.In_Module ms
+ | Interface.Name_Pattern s -> Search.Name_Pattern (Str.regexp s)
+ | Interface.Type_Pattern s -> Search.Type_Pattern (pattern_of_string s)
+ | Interface.SubType_Pattern s -> Search.SubType_Pattern (pattern_of_string s)
+ | Interface.In_Module ms -> Search.In_Module (dirpath_of_string_list ms)
| Interface.Include_Blacklist -> Search.Include_Blacklist
let search flags =
@@ -361,8 +383,6 @@ let init =
match file with
| None -> Stm.get_current_state ()
| Some file ->
- if not (Filename.check_suffix file ".v") then
- error "A file with suffix .v is expected.";
let dir = Filename.dirname file in
let open Loadpath in let open CUnix in
let initial_id, _ =
@@ -371,6 +391,7 @@ let init =
0 (Printf.sprintf "Add LoadPath \"%s\". " dir)
else Stm.get_current_state (), `NewTip in
Stm.set_compilation_hints file;
+ Stm.finish ();
initial_id
end
@@ -392,6 +413,15 @@ let interp ((_raw, verbose), s) =
let quit = ref false
+(** Serializes the output of Stm.get_ast *)
+let print_ast id =
+ match Stm.get_ast id with
+ | Some (expr, loc) -> begin
+ try Texmacspp.tmpp expr loc
+ with e -> Xml_datatype.PCData ("ERROR " ^ Printexc.to_string e)
+ end
+ | None -> Xml_datatype.PCData "ERROR"
+
(** Grouping all call handlers together + error handling *)
let eval_call xml_oc log c =
@@ -422,7 +452,7 @@ let eval_call xml_oc log c =
Interface.interp = interruptible interp;
Interface.handle_exn = handle_exn;
Interface.stop_worker = Stm.stop_worker;
- Interface.print_ast = Stm.print_ast;
+ Interface.print_ast = print_ast;
Interface.annotate = interruptible annotate;
} in
Xmlprotocol.abstract_eval_call handler c
@@ -443,16 +473,12 @@ let print_xml =
let slave_logger xml_oc level message =
(* convert the message into XML *)
let msg = hov 0 message in
- let message = {
- Pp.message_level = level;
- Pp.message_content = (Richpp.repr (Richpp.richpp_of_pp msg));
- } in
- let () = pr_debug (Printf.sprintf "-> %S" (string_of_ppcmds msg)) in
- let xml = Pp.of_message message in
+ let () = pr_debug (Printf.sprintf "-> %S" (string_of_ppcmds msg)) in
+ let xml = Xmlprotocol.of_message level (Richpp.richpp_of_pp message) in
print_xml xml_oc xml
let slave_feeder xml_oc msg =
- let xml = Feedback.of_feedback msg in
+ let xml = Xmlprotocol.of_feedback msg in
print_xml xml_oc xml
(** The main loop *)
@@ -470,8 +496,8 @@ let loop () =
CThread.thread_friendly_read in_ch s ~off:0 ~len) in
let xml_ic = Xml_parser.make (Xml_parser.SLexbuf in_lb) in
let () = Xml_parser.check_eof xml_ic false in
- set_logger (slave_logger xml_oc);
- set_feeder (slave_feeder xml_oc);
+ Feedback.set_logger (slave_logger xml_oc);
+ Feedback.set_feeder (slave_feeder xml_oc);
(* We'll handle goal fetching and display in our own way *)
Vernacentries.enable_goal_printing := false;
Vernacentries.qed_display_script := false;
@@ -481,7 +507,7 @@ let loop () =
(* pr_with_pid (Xml_printer.to_string_fmt xml_query); *)
let Xmlprotocol.Unknown q = Xmlprotocol.to_call xml_query in
let () = pr_debug_call q in
- let r = eval_call xml_oc (slave_logger xml_oc Pp.Notice) q in
+ let r = eval_call xml_oc (slave_logger xml_oc Feedback.Notice) q in
let () = pr_debug_answer q r in
(* pr_with_pid (Xml_printer.to_string_fmt (Xmlprotocol.of_answer q r)); *)
print_xml xml_oc (Xmlprotocol.of_answer q r);
@@ -493,7 +519,7 @@ let loop () =
| Xml_parser.Error (err, loc) ->
pr_debug ("Syntax error in query: " ^ Xml_parser.error_msg err);
exit 1
- | Serialize.Marshal_error ->
+ | Serialize.Marshal_error _ ->
pr_debug "Incorrect query.";
exit 1
| any ->
diff --git a/ide/ideutils.ml b/ide/ideutils.ml
index 508881cad..00c3f88e5 100644
--- a/ide/ideutils.ml
+++ b/ide/ideutils.ml
@@ -297,15 +297,15 @@ let textview_width (view : #GText.view_skel) =
let char_width = GPango.to_pixels metrics#approx_char_width in
pixel_width / char_width
-type logger = Pp.message_level -> Richpp.richpp -> unit
+type logger = Feedback.level -> Richpp.richpp -> unit
let default_logger level message =
let level = match level with
- | Pp.Debug _ -> `DEBUG
- | Pp.Info -> `INFO
- | Pp.Notice -> `NOTICE
- | Pp.Warning -> `WARNING
- | Pp.Error -> `ERROR
+ | Feedback.Debug _ -> `DEBUG
+ | Feedback.Info -> `INFO
+ | Feedback.Notice -> `NOTICE
+ | Feedback.Warning -> `WARNING
+ | Feedback.Error -> `ERROR
in
Minilib.log ~level (xml_to_string message)
diff --git a/ide/ideutils.mli b/ide/ideutils.mli
index 4e35a6f9f..491e8e823 100644
--- a/ide/ideutils.mli
+++ b/ide/ideutils.mli
@@ -69,7 +69,7 @@ val requote : string -> string
val textview_width : #GText.view_skel -> int
(** Returns an approximate value of the character width of a textview *)
-type logger = Pp.message_level -> Richpp.richpp -> unit
+type logger = Feedback.level -> Richpp.richpp -> unit
val default_logger : logger
(** Default logger. It logs messages that the casual user should not see. *)
diff --git a/ide/preferences.ml b/ide/preferences.ml
index addea9074..3a33bbb1d 100644
--- a/ide/preferences.ml
+++ b/ide/preferences.ml
@@ -144,6 +144,18 @@ object
method into s = Some s
end
+let string_pair_list (sep : char) : (string * string) list repr =
+object
+ val sep' = String.make 1 sep
+ method from = CList.map (fun (s1, s2) -> CString.concat sep' [s1; s2])
+ method into l =
+ try
+ Some (CList.map (fun s ->
+ let split = CString.split sep s in
+ CList.nth split 0, CList.nth split 1) l)
+ with Failure _ -> None
+end
+
let bool : bool repr =
object
method from s = [string_of_bool s]
@@ -303,10 +315,14 @@ let modifier_for_tactics =
let modifier_for_display =
new preference ~name:["modifier_for_display"] ~init:"<Alt><Shift>" ~repr:Repr.(string)
+let modifier_for_queries =
+ new preference ~name:["modifier_for_queries"] ~init:"<Control><Shift>" ~repr:Repr.(string)
+
let _ = attach_modifiers modifier_for_navigation "<Actions>/Navigation/"
let _ = attach_modifiers modifier_for_templates "<Actions>/Templates/"
let _ = attach_modifiers modifier_for_tactics "<Actions>/Tactics/"
let _ = attach_modifiers modifier_for_display "<Actions>/View/"
+let _ = attach_modifiers modifier_for_queries "<Actions>/Queries/"
let modifiers_valid =
new preference ~name:["modifiers_valid"] ~init:"<Alt><Control><Shift>" ~repr:Repr.(string)
@@ -386,14 +402,6 @@ let processing_color =
let _ = attach_bg processing_color Tags.Script.to_process
let _ = attach_bg processing_color Tags.Script.incomplete
-let default_tag = {
- tag_fg_color = None;
- tag_bg_color = None;
- tag_bold = false;
- tag_italic = false;
- tag_underline = false;
-}
-
let tags = ref Util.String.Map.empty
let list_tags () = !tags
@@ -515,6 +523,9 @@ let highlight_current_line =
let nanoPG =
new preference ~name:["nanoPG"] ~init:false ~repr:Repr.(bool)
+let user_queries =
+ new preference ~name:["user_queries"] ~init:[] ~repr:Repr.(string_pair_list '$')
+
class tag_button (box : Gtk.box Gtk.obj) =
object (self)
@@ -845,6 +856,9 @@ let configure ?(apply=(fun () -> ())) () =
let modifier_for_display =
pmodifiers "Modifiers for View Menu" modifier_for_display
in
+ let modifier_for_queries =
+ pmodifiers "Modifiers for Queries Menu" modifier_for_queries
+ in
let modifiers_valid =
pmodifiers ~all:true "Allowed modifiers" modifiers_valid
in
@@ -916,6 +930,36 @@ let configure ?(apply=(fun () -> ())) () =
let misc = [contextual_menus_on_goal;stop_before;reset_on_tab_switch;
vertical_tabs;opposite_tabs] in
+ let add_user_query () =
+ let input_string l v =
+ match GToolbox.input_string ~title:l v with
+ | None -> ""
+ | Some s -> s
+ in
+ let q = input_string "User query" "Your query" in
+ let k = input_string "Shortcut key" "Shortcut (a single letter)" in
+ let q = CString.map (fun c -> if c = '$' then ' ' else c) q in
+ (* Anything that is not a simple letter will be ignored. *)
+ let k =
+ if Int.equal (CString.length k) 1 && Util.is_letter k.[0] then k
+ else "" in
+ let k = CString.uppercase k in
+ [q, k]
+ in
+
+ let user_queries =
+ list
+ ~f:user_queries#set
+ (* Disallow same query, key or empty query. *)
+ ~eq:(fun (q1, k1) (q2, k2) -> k1 = k2 || q1 = "" || q2 = "" || q1 = q2)
+ ~add:add_user_query
+ ~titles:["User query"; "Shortcut key"]
+ "User queries"
+ (fun (q, s) -> [q; s])
+ user_queries#get
+
+ in
+
(* ATTENTION !!!!! L'onglet Fonts doit etre en premier pour eviter un bug !!!!
(shame on Benjamin) *)
let cmds =
@@ -945,9 +989,10 @@ let configure ?(apply=(fun () -> ())) () =
[automatic_tactics]);
Section("Shortcuts", Some `PREFERENCES,
[modifiers_valid; modifier_for_tactics;
- modifier_for_templates; modifier_for_display; modifier_for_navigation]);
+ modifier_for_templates; modifier_for_display; modifier_for_navigation;
+ modifier_for_queries; user_queries]);
Section("Misc", Some `ADD,
- misc)]
+ misc)]
in
(*
Format.printf "before edit: current.text_font = %s@." (Pango.Font.to_string current.text_font);
diff --git a/ide/preferences.mli b/ide/preferences.mli
index 1733091a5..426b0a328 100644
--- a/ide/preferences.mli
+++ b/ide/preferences.mli
@@ -65,6 +65,7 @@ val modifier_for_navigation : string preference
val modifier_for_templates : string preference
val modifier_for_tactics : string preference
val modifier_for_display : string preference
+val modifier_for_queries : string preference
val modifiers_valid : string preference
val cmd_browse : string preference
val cmd_editor : string preference
@@ -95,6 +96,7 @@ val spaces_instead_of_tabs : bool preference
val tab_length : int preference
val highlight_current_line : bool preference
val nanoPG : bool preference
+val user_queries : (string * string) list preference
val save_pref : unit -> unit
val load_pref : unit -> unit
diff --git a/ide/project_file.ml4 b/ide/project_file.ml4
index 081094e2b..de0720e03 100644
--- a/ide/project_file.ml4
+++ b/ide/project_file.ml4
@@ -56,24 +56,24 @@ let rec process_cmd_line orig_dir ((project_file,makefile,install,opt) as opts)
| ("-full"|"-opt") :: r ->
process_cmd_line orig_dir (project_file,makefile,install,true) l r
| "-impredicative-set" :: r ->
- Pp.msg_warning (Pp.str "Please now use \"-arg -impredicative-set\" instead of \"-impredicative-set\" alone to be more uniform.");
+ Feedback.msg_warning (Pp.str "Please now use \"-arg -impredicative-set\" instead of \"-impredicative-set\" alone to be more uniform.");
process_cmd_line orig_dir opts (Arg "-impredicative-set" :: l) r
| "-no-install" :: r ->
- Pp.msg_warning (Pp.(++) (Pp.str "Option -no-install is deprecated.") (Pp.(++) (Pp.spc ()) (Pp.str "Use \"-install none\" instead")));
+ Feedback.msg_warning (Pp.(++) (Pp.str "Option -no-install is deprecated.") (Pp.(++) (Pp.spc ()) (Pp.str "Use \"-install none\" instead")));
process_cmd_line orig_dir (project_file,makefile,NoInstall,opt) l r
| "-install" :: d :: r ->
- if install <> UnspecInstall then Pp.msg_warning (Pp.str "-install sets more than once.");
+ if install <> UnspecInstall then Feedback.msg_warning (Pp.str "-install sets more than once.");
let install =
match d with
| "user" -> UserInstall
| "none" -> NoInstall
| "global" -> TraditionalInstall
- | _ -> Pp.msg_warning (Pp.(++) (Pp.str "invalid option '") (Pp.(++) (Pp.str d) (Pp.str "' passed to -install.")));
+ | _ -> Feedback.msg_warning (Pp.(++) (Pp.str "invalid option '") (Pp.(++) (Pp.str d) (Pp.str "' passed to -install.")));
install
in
process_cmd_line orig_dir (project_file,makefile,install,opt) l r
| "-custom" :: com :: dependencies :: file :: r ->
- Pp.msg_warning (Pp.app
+ Feedback.msg_warning (Pp.app
(Pp.str "Please now use \"-extra[-phony] result deps command\" instead of \"-custom command deps result\".")
(Pp.pr_arg Pp.str "It follows makefile target declaration order and has a clearer semantic.")
);
@@ -94,7 +94,7 @@ let rec process_cmd_line orig_dir ((project_file,makefile,install,opt) as opts)
let file = CUnix.remove_path_dot (CUnix.correct_path file orig_dir) in
let () = match project_file with
| None -> ()
- | Some _ -> Pp.msg_warning (Pp.str
+ | Some _ -> Feedback.msg_warning (Pp.str
"Several features will not work with multiple project files.")
in
let (opts',l') = process_cmd_line (Filename.dirname file) (Some file,makefile,install,opt) l (parse file) in
@@ -109,7 +109,7 @@ let rec process_cmd_line orig_dir ((project_file,makefile,install,opt) as opts)
let () = match makefile with
|None -> ()
|Some f ->
- Pp.msg_warning (Pp.(++) (Pp.str "Only one output file is genererated. ") (Pp.(++) (Pp.str f) (Pp.str " will not be.")))
+ Feedback.msg_warning (Pp.(++) (Pp.str "Only one output file is genererated. ") (Pp.(++) (Pp.str f) (Pp.str " will not be.")))
in process_cmd_line orig_dir (project_file,Some file,install,opt) l r
end
| v :: "=" :: def :: r ->
diff --git a/printing/richprinter.ml b/ide/richprinter.ml
index d95e19074..5f39f36ea 100644
--- a/printing/richprinter.ml
+++ b/ide/richprinter.ml
@@ -22,4 +22,3 @@ let make_richpp pr ast =
let richpp_vernac = make_richpp RichppVernac.pr_vernac
let richpp_constr = make_richpp RichppConstr.pr_constr_expr
-let richpp_tactic env = make_richpp (RichppTactic.pr_tactic env)
diff --git a/printing/richprinter.mli b/ide/richprinter.mli
index 261d22c4c..c9e84e3eb 100644
--- a/printing/richprinter.mli
+++ b/ide/richprinter.mli
@@ -34,6 +34,3 @@ val richpp_vernac : Vernacexpr.vernac_expr -> rich_pp
(** [richpp_constr constr] produces a rich pretty-printing of [constr]. *)
val richpp_constr : Constrexpr.constr_expr -> rich_pp
-
-(** [richpp_tactic constr] produces a rich pretty-printing of [tactic]. *)
-val richpp_tactic : Environ.env -> Tacexpr.tactic_expr -> rich_pp
diff --git a/lib/serialize.ml b/ide/serialize.ml
index 685ec6049..7b568501e 100644
--- a/lib/serialize.ml
+++ b/ide/serialize.ml
@@ -8,7 +8,7 @@
open Xml_datatype
-exception Marshal_error
+exception Marshal_error of string * xml
(** Utility functions *)
@@ -19,30 +19,31 @@ let rec get_attr attr = function
let massoc x l =
try get_attr x l
- with Not_found -> raise Marshal_error
+ with Not_found -> raise (Marshal_error("attribute " ^ x,PCData "not there"))
let constructor t c args = Element (t, ["val", c], args)
let do_match t mf = function
| Element (s, attrs, args) when CString.equal s t ->
let c = massoc "val" attrs in
mf c args
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error (t,x))
let singleton = function
| [x] -> x
- | _ -> raise Marshal_error
+ | l -> raise (Marshal_error
+ ("singleton",PCData ("list of length " ^ string_of_int (List.length l))))
let raw_string = function
| [] -> ""
| [PCData s] -> s
- | _ -> raise Marshal_error
+ | x::_ -> raise (Marshal_error("raw string",x))
(** Base types *)
let of_unit () = Element ("unit", [], [])
let to_unit : xml -> unit = function
| Element ("unit", [], []) -> ()
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error ("unit",x))
let of_bool (b : bool) : xml =
if b then constructor "bool" "true" []
@@ -50,13 +51,13 @@ let of_bool (b : bool) : xml =
let to_bool : xml -> bool = do_match "bool" (fun s _ -> match s with
| "true" -> true
| "false" -> false
- | _ -> raise Marshal_error)
+ | x -> raise (Marshal_error("bool",PCData x)))
let of_list (f : 'a -> xml) (l : 'a list) =
Element ("list", [], List.map f l)
let to_list (f : xml -> 'a) : xml -> 'a list = function
| Element ("list", [], l) -> List.map f l
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error("list",x))
let of_option (f : 'a -> xml) : 'a option -> xml = function
| None -> Element ("option", ["val", "none"], [])
@@ -64,24 +65,24 @@ let of_option (f : 'a -> xml) : 'a option -> xml = function
let to_option (f : xml -> 'a) : xml -> 'a option = function
| Element ("option", ["val", "none"], []) -> None
| Element ("option", ["val", "some"], [x]) -> Some (f x)
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error("option",x))
let of_string (s : string) : xml = Element ("string", [], [PCData s])
let to_string : xml -> string = function
| Element ("string", [], l) -> raw_string l
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error("string",x))
let of_int (i : int) : xml = Element ("int", [], [PCData (string_of_int i)])
let to_int : xml -> int = function
| Element ("int", [], [PCData s]) ->
- (try int_of_string s with Failure _ -> raise Marshal_error)
- | _ -> raise Marshal_error
+ (try int_of_string s with Failure _ -> raise(Marshal_error("int",PCData s)))
+ | x -> raise (Marshal_error("int",x))
let of_pair (f : 'a -> xml) (g : 'b -> xml) (x : 'a * 'b) : xml =
Element ("pair", [], [f (fst x); g (snd x)])
let to_pair (f : xml -> 'a) (g : xml -> 'b) : xml -> 'a * 'b = function
| Element ("pair", [], [x; y]) -> (f x, g y)
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error("pair",x))
let of_union (f : 'a -> xml) (g : 'b -> xml) : ('a,'b) CSig.union -> xml = function
| CSig.Inl x -> Element ("union", ["val","in_l"], [f x])
@@ -89,7 +90,7 @@ let of_union (f : 'a -> xml) (g : 'b -> xml) : ('a,'b) CSig.union -> xml = funct
let to_union (f : xml -> 'a) (g : xml -> 'b) : xml -> ('a,'b) CSig.union = function
| Element ("union", ["val","in_l"], [x]) -> CSig.Inl (f x)
| Element ("union", ["val","in_r"], [x]) -> CSig.Inr (g x)
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error("union",x))
(** More elaborate types *)
@@ -99,7 +100,7 @@ let to_edit_id = function
let id = int_of_string i in
assert (id <= 0 );
id
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error("edit_id",x))
let of_loc loc =
let start, stop = Loc.unloc loc in
@@ -107,14 +108,14 @@ let of_loc loc =
let to_loc xml =
match xml with
| Element ("loc", l,[]) ->
+ let start = massoc "start" l in
+ let stop = massoc "stop" l in
(try
- let start = massoc "start" l in
- let stop = massoc "stop" l in
Loc.make_loc (int_of_string start, int_of_string stop)
- with Not_found | Invalid_argument _ -> raise Marshal_error)
- | _ -> raise Marshal_error
+ with Not_found | Invalid_argument _ -> raise (Marshal_error("loc",PCData(start^":"^stop))))
+ | x -> raise (Marshal_error("loc",x))
let of_xml x = Element ("xml", [], [x])
let to_xml xml = match xml with
| Element ("xml", [], [x]) -> x
-| _ -> raise Marshal_error
+| x -> raise (Marshal_error("xml",x))
diff --git a/lib/serialize.mli b/ide/serialize.mli
index d7c14e7e7..bf9e184eb 100644
--- a/lib/serialize.mli
+++ b/ide/serialize.mli
@@ -8,7 +8,7 @@
open Xml_datatype
-exception Marshal_error
+exception Marshal_error of string * xml
val massoc: string -> (string * string) list -> string
val constructor: string -> string -> xml list -> xml
diff --git a/stm/texmacspp.ml b/ide/texmacspp.ml
index 5bd1569ce..d1d6de9ae 100644
--- a/stm/texmacspp.ml
+++ b/ide/texmacspp.ml
@@ -304,7 +304,13 @@ and pp_cases_pattern_expr cpe =
xmlApply loc
(xmlOperator "alias" ~attr:["name", string_of_id id] loc ::
[pp_cases_pattern_expr cpe])
- | CPatCstr (loc, ref, cpel1, cpel2) ->
+ | CPatCstr (loc, ref, None, cpel2) ->
+ xmlApply loc
+ (xmlOperator "reference"
+ ~attr:["name", Libnames.string_of_reference ref] loc ::
+ [Element ("impargs", [], []);
+ Element ("args", [], (List.map pp_cases_pattern_expr cpel2))])
+ | CPatCstr (loc, ref, Some cpel1, cpel2) ->
xmlApply loc
(xmlOperator "reference"
~attr:["name", Libnames.string_of_reference ref] loc ::
@@ -497,9 +503,6 @@ let rec tmpp v loc =
| VernacError _ -> xmlWithLoc loc "error" [] []
(* Syntax *)
- | VernacTacticNotation _ as x ->
- xmlLtac loc [PCData (Pp.string_of_ppcmds (Ppvernac.pr_vernac x))]
-
| VernacSyntaxExtension (_, ((_, name), sml)) ->
let attrs = List.flatten (List.map attribute_of_syntax_modifier sml) in
xmlReservedNotation attrs name loc
@@ -510,13 +513,6 @@ let rec tmpp v loc =
xmlScope loc "delimit" name ~attr:["delimiter",tag] []
| VernacDelimiters (name,None) ->
xmlScope loc "undelimit" name ~attr:[] []
- | VernacBindScope (name,l) ->
- xmlScope loc "bind" name
- (List.map (function
- | ByNotation(loc,name,None) -> xmlNotation [] name loc []
- | ByNotation(loc,name,Some d) ->
- xmlNotation ["delimiter",d] name loc []
- | AN ref -> xmlReference ref) l)
| VernacInfix (_,((_,name),sml),ce,sn) ->
let attrs = List.flatten (List.map attribute_of_syntax_modifier sml) in
let sc_attr =
@@ -532,6 +528,7 @@ let rec tmpp v loc =
| Some scope -> ["scope", scope]
| None -> [] in
xmlNotation (sc_attr @ attrs) name loc [pp_expr ce]
+ | VernacBindScope _ as x -> xmlTODO loc x
| VernacNotationAddFormat _ as x -> xmlTODO loc x
| VernacUniverse _
| VernacConstraint _
@@ -665,7 +662,7 @@ let rec tmpp v loc =
(* Solving *)
- | (VernacSolve _ | VernacSolveExistential _) as x ->
+ | (VernacSolveExistential _) as x ->
xmlLtac loc [PCData (Pp.string_of_ppcmds (Ppvernac.pr_vernac x))]
(* Auxiliary file and library management *)
@@ -691,7 +688,6 @@ let rec tmpp v loc =
| VernacBackTo _ -> PCData "VernacBackTo"
(* Commands *)
- | VernacDeclareTacticDefinition _ as x -> xmlTODO loc x
| VernacCreateHintDb _ as x -> xmlTODO loc x
| VernacRemoveHints _ as x -> xmlTODO loc x
| VernacHints _ as x -> xmlTODO loc x
diff --git a/stm/texmacspp.mli b/ide/texmacspp.mli
index 858847fb6..858847fb6 100644
--- a/stm/texmacspp.mli
+++ b/ide/texmacspp.mli
diff --git a/ide/utils/okey.ml b/ide/utils/okey.ml
index 580f1fbcb..8f6cb382a 100644
--- a/ide/utils/okey.ml
+++ b/ide/utils/okey.ml
@@ -52,33 +52,6 @@ let int_of_modifier = function
| `RELEASE -> 1 lsl 30
| `SUPER -> 1 lsl 21
-let print_modifier l =
- List.iter
- (fun m ->
- print_string
- (((function
- `SHIFT -> "SHIFT"
- | `LOCK -> "LOCK"
- | `CONTROL -> "CONTROL"
- | `MOD1 -> "MOD1"
- | `MOD2 -> "MOD2"
- | `MOD3 -> "MOD3"
- | `MOD4 -> "MOD4"
- | `MOD5 -> "MOD5"
- | `BUTTON1 -> "B1"
- | `BUTTON2 -> "B2"
- | `BUTTON3 -> "B3"
- | `BUTTON4 -> "B4"
- | `BUTTON5 -> "B5"
- | `HYPER -> "HYPER"
- | `META -> "META"
- | `RELEASE -> ""
- | `SUPER -> "SUPER")
- m)^" ")
- )
- l;
- print_newline ()
-
let int_of_modifiers l =
List.fold_left (fun acc -> fun m -> acc + (int_of_modifier m)) 0 l
diff --git a/ide/wg_Completion.ml b/ide/wg_Completion.ml
index 6c53fc013..aeae3e1fd 100644
--- a/ide/wg_Completion.ml
+++ b/ide/wg_Completion.ml
@@ -86,7 +86,7 @@ let signals = [
end_s#disconnect;
] in
object (self : 'a)
- inherit GUtil.ml_signals signals as super
+ inherit GUtil.ml_signals signals
method start_completion = start_s#connect ~after
method update_completion = update_s#connect ~after
method end_completion = end_s#connect ~after
diff --git a/ide/wg_MessageView.ml b/ide/wg_MessageView.ml
index 7728ad236..758f383d6 100644
--- a/ide/wg_MessageView.ml
+++ b/ide/wg_MessageView.ml
@@ -73,8 +73,8 @@ let message_view () : message_view =
method push level msg =
let tags = match level with
- | Pp.Error -> [Tags.Message.error]
- | Pp.Warning -> [Tags.Message.warning]
+ | Feedback.Error -> [Tags.Message.error]
+ | Feedback.Warning -> [Tags.Message.warning]
| _ -> []
in
let rec non_empty = function
@@ -88,7 +88,7 @@ let message_view () : message_view =
push#call (level, msg)
end
- method add msg = self#push Pp.Notice msg
+ method add msg = self#push Feedback.Notice msg
method add_string s = self#add (Richpp.richpp_of_string s)
diff --git a/ide/wg_ProofView.ml b/ide/wg_ProofView.ml
index 4d95fdd0d..47c86045a 100644
--- a/ide/wg_ProofView.ml
+++ b/ide/wg_ProofView.ml
@@ -91,7 +91,7 @@ let mode_tactic sel_cb (proof : #GText.view_skel) goals hints = match goals with
let () = proof#buffer#insert head_str in
let () = insert_hyp hyps_hints hyps in
let () =
- let tags = Tags.Proof.goal :: if goal_hints <> [] then
+ let _ = if goal_hints <> [] then
let tag = proof#buffer#create_tag [] in
let () = hook_tag_cb tag goal_hints sel_cb on_hover in
[tag]
diff --git a/ide/wg_ScriptView.ml b/ide/wg_ScriptView.ml
index 83fbda487..218cedb36 100644
--- a/ide/wg_ScriptView.ml
+++ b/ide/wg_ScriptView.ml
@@ -287,7 +287,7 @@ let completion = new Wg_Completion.complete_model ct view#buffer in
let popup = new Wg_Completion.complete_popup completion (view :> GText.view) in
object (self)
- inherit GSourceView2.source_view (Gobject.unsafe_cast tv) as super
+ inherit GSourceView2.source_view (Gobject.unsafe_cast tv)
val undo_manager = new undo_manager view#buffer
diff --git a/ide/wg_Segment.ml b/ide/wg_Segment.ml
index c2799e40b..dbc1740ef 100644
--- a/ide/wg_Segment.ml
+++ b/ide/wg_Segment.ml
@@ -60,6 +60,8 @@ object (self)
val mutable default : color = `WHITE
val mutable pixmap : GDraw.pixmap = GDraw.pixmap ~width:1 ~height:1 ()
val clicked = new GUtil.signal ()
+ val mutable need_refresh = false
+ val refresh_timer = Ideutils.mktimer ()
initializer
box#misc#set_size_request ~height ();
@@ -88,13 +90,15 @@ object (self)
let cb show = if show then self#misc#show () else self#misc#hide () in
stick show_progress_bar self cb;
(** Initial pixmap *)
- draw#set_pixmap pixmap
+ draw#set_pixmap pixmap;
+ refresh_timer.Ideutils.run ~ms:300
+ ~callback:(fun () -> if need_refresh then self#refresh (); true)
method set_model md =
model <- Some md;
let changed_cb = function
| `INSERT | `REMOVE ->
- if self#misc#visible then self#refresh ()
+ if self#misc#visible then need_refresh <- true
| `SET (i, color) ->
if self#misc#visible then self#fill_range color i (i + 1)
in
@@ -125,6 +129,7 @@ object (self)
method private refresh () = match model with
| None -> ()
| Some md ->
+ need_refresh <- false;
pixmap#set_foreground default;
pixmap#rectangle ~x:0 ~y:0 ~width ~height ~filled:true ();
let make (k, cur, accu) v = match cur with
diff --git a/lib/xml_lexer.mli b/ide/xml_lexer.mli
index e61cb055f..e61cb055f 100644
--- a/lib/xml_lexer.mli
+++ b/ide/xml_lexer.mli
diff --git a/lib/xml_lexer.mll b/ide/xml_lexer.mll
index 290f2c89a..290f2c89a 100644
--- a/lib/xml_lexer.mll
+++ b/ide/xml_lexer.mll
diff --git a/lib/xml_parser.ml b/ide/xml_parser.ml
index 8db3f9e8b..8db3f9e8b 100644
--- a/lib/xml_parser.ml
+++ b/ide/xml_parser.ml
diff --git a/lib/xml_parser.mli b/ide/xml_parser.mli
index ac2eab352..ac2eab352 100644
--- a/lib/xml_parser.mli
+++ b/ide/xml_parser.mli
diff --git a/lib/xml_printer.ml b/ide/xml_printer.ml
index e7e4d0ceb..e7e4d0ceb 100644
--- a/lib/xml_printer.ml
+++ b/ide/xml_printer.ml
diff --git a/lib/xml_printer.mli b/ide/xml_printer.mli
index f24f51fff..f24f51fff 100644
--- a/lib/xml_printer.mli
+++ b/ide/xml_printer.mli
diff --git a/ide/xmlprotocol.ml b/ide/xmlprotocol.ml
index 232630e5b..a55d19aa1 100644
--- a/ide/xmlprotocol.ml
+++ b/ide/xmlprotocol.ml
@@ -39,7 +39,7 @@ let to_search_cst = do_match "search_cst" (fun s args -> match s with
| "subtype_pattern" -> SubType_Pattern (to_string (singleton args))
| "in_module" -> In_Module (to_list to_string (singleton args))
| "include_blacklist" -> Include_Blacklist
- | _ -> raise Marshal_error)
+ | x -> raise (Marshal_error("search",PCData x)))
let of_coq_object f ans =
let prefix = of_list of_string ans.coq_object_prefix in
@@ -56,7 +56,7 @@ let to_coq_object f = function
coq_object_qualid = qualid;
coq_object_object = obj;
}
-| _ -> raise Marshal_error
+| x -> raise (Marshal_error("coq_object",x))
let of_option_value = function
| IntValue i -> constructor "option_value" "intvalue" [of_option of_int i]
@@ -68,7 +68,7 @@ let to_option_value = do_match "option_value" (fun s args -> match s with
| "boolvalue" -> BoolValue (to_bool (singleton args))
| "stringvalue" -> StringValue (to_string (singleton args))
| "stringoptvalue" -> StringOptValue (to_option to_string (singleton args))
- | _ -> raise Marshal_error)
+ | x -> raise (Marshal_error("*value",PCData x)))
let of_option_state s =
Element ("option_state", [], [
@@ -82,8 +82,20 @@ let to_option_state = function
opt_depr = to_bool depr;
opt_name = to_string name;
opt_value = to_option_value value }
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error("option_state",x))
+let to_stateid = function
+ | Element ("state_id",["val",i],[]) ->
+ let id = int_of_string i in
+ Stateid.of_int id
+ | _ -> raise (Invalid_argument "to_state_id")
+
+let of_stateid i = Element ("state_id",["val",string_of_int (Stateid.to_int i)],[])
+
+let of_richpp x = Element ("richpp", [], [Richpp.repr x])
+let to_richpp xml = match xml with
+ | Element ("richpp", [], [x]) -> Richpp.richpp_of_xml x
+ | x -> raise Serialize.(Marshal_error("richpp",x))
let of_value f = function
| Good x -> Element ("value", ["val", "good"], [f x])
@@ -91,8 +103,9 @@ let of_value f = function
let loc = match loc with
| None -> []
| Some (s, e) -> [("loc_s", string_of_int s); ("loc_e", string_of_int e)] in
- let id = Stateid.to_xml id in
- Element ("value", ["val", "fail"] @ loc, [id; Richpp.of_richpp msg])
+ let id = of_stateid id in
+ Element ("value", ["val", "fail"] @ loc, [id; of_richpp msg])
+
let to_value f = function
| Element ("value", attrs, l) ->
let ans = massoc "val" attrs in
@@ -103,14 +116,14 @@ let to_value f = function
let loc_s = int_of_string (Serialize.massoc "loc_s" attrs) in
let loc_e = int_of_string (Serialize.massoc "loc_e" attrs) in
Some (loc_s, loc_e)
- with Marshal_error | Failure _ -> None
+ with Marshal_error _ | Failure _ -> None
in
- let (id, msg) = match l with [id; msg] -> (id, msg) | _ -> raise Marshal_error in
- let id = Stateid.of_xml id in
- let msg = Richpp.to_richpp msg in
+ let (id, msg) = match l with [id; msg] -> (id, msg) | _ -> raise (Marshal_error("val",PCData "no id attribute")) in
+ let id = to_stateid id in
+ let msg = to_richpp msg in
Fail (id, loc, msg)
- else raise Marshal_error
-| _ -> raise Marshal_error
+ else raise (Marshal_error("good or fail",PCData ans))
+| x -> raise (Marshal_error("value",x))
let of_status s =
let of_so = of_option of_string in
@@ -126,25 +139,25 @@ let to_status = function
status_proofname = to_option to_string name;
status_allproofs = to_list to_string prfs;
status_proofnum = to_int pnum; }
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error("status",x))
let of_evar s = Element ("evar", [], [PCData s.evar_info])
let to_evar = function
| Element ("evar", [], data) -> { evar_info = raw_string data; }
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error("evar",x))
let of_goal g =
- let hyp = of_list Richpp.of_richpp g.goal_hyp in
- let ccl = Richpp.of_richpp g.goal_ccl in
+ let hyp = of_list of_richpp g.goal_hyp in
+ let ccl = of_richpp g.goal_ccl in
let id = of_string g.goal_id in
Element ("goal", [], [id; hyp; ccl])
let to_goal = function
| Element ("goal", [], [id; hyp; ccl]) ->
- let hyp = to_list Richpp.to_richpp hyp in
- let ccl = Richpp.to_richpp ccl in
+ let hyp = to_list to_richpp hyp in
+ let ccl = to_richpp ccl in
let id = to_string id in
{ goal_hyp = hyp; goal_ccl = ccl; goal_id = id; }
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error("goal",x))
let of_goals g =
let of_glist = of_list of_goal in
@@ -162,7 +175,7 @@ let to_goals = function
let given_up = to_list to_goal given_up in
{ fg_goals = fg; bg_goals = bg; shelved_goals = shelf;
given_up_goals = given_up }
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error("goals",x))
let of_coq_info info =
let version = of_string info.coqtop_version in
@@ -176,7 +189,7 @@ let to_coq_info = function
protocol_version = to_string protocol;
release_date = to_string release;
compile_date = to_string compile; }
- | _ -> raise Marshal_error
+ | x -> raise (Marshal_error("coq_info",x))
end
include Xml_marshalling
@@ -286,7 +299,7 @@ end = struct
| Coq_object t -> (of_coq_object (convert t))
| Pair (t1,t2) -> (of_pair (convert t1) (convert t2))
| Union (t1,t2) -> (of_union (convert t1) (convert t2))
- | State_id -> Stateid.to_xml
+ | State_id -> of_stateid
| Search_cst -> of_search_cst
in
convert ty
@@ -309,7 +322,7 @@ end = struct
| Coq_object t -> (to_coq_object (convert t))
| Pair (t1,t2) -> (to_pair (convert t1) (convert t2))
| Union (t1,t2) -> (to_union (convert t1) (convert t2))
- | State_id -> Stateid.of_xml
+ | State_id -> to_stateid
| Search_cst -> to_search_cst
in
convert ty
@@ -422,7 +435,7 @@ end = struct
(pr_xml (of_bool true)) (pr_xml (of_bool false));
Printf.printf "%s:\n\n%s\n\n" (print_val_t String) (pr_xml (of_string "hello"));
Printf.printf "%s:\n\n%s\n\n" (print_val_t Int) (pr_xml (of_int 256));
- Printf.printf "%s:\n\n%s\n\n" (print_val_t State_id) (pr_xml (Stateid.to_xml Stateid.initial));
+ Printf.printf "%s:\n\n%s\n\n" (print_val_t State_id) (pr_xml (of_stateid Stateid.initial));
Printf.printf "%s:\n\n%s\n\n" (print_val_t (List Int)) (pr_xml (of_list of_int [3;4;5]));
Printf.printf "%s:\n\n%s\n%s\n\n" (print_val_t (Option Int))
(pr_xml (of_option of_int (Some 3))) (pr_xml (of_option of_int None));
@@ -682,7 +695,7 @@ let to_call : xml -> unknown_call =
| "StopWorker" -> Unknown (StopWorker (mkCallArg stop_worker_sty_t a))
| "PrintAst" -> Unknown (PrintAst (mkCallArg print_ast_sty_t a))
| "Annotate" -> Unknown (Annotate (mkCallArg annotate_sty_t a))
- | _ -> raise Marshal_error)
+ | x -> raise (Marshal_error("call",PCData x)))
(** Debug printing *)
@@ -750,4 +763,130 @@ let document to_string_fmt =
(Fail (Stateid.initial,Some (15,34),Richpp.richpp_of_string "error message"))));
document_type_encoding to_string_fmt
+(* Moved from feedback.mli : This is IDE specific and we don't want to
+ pollute the core with it *)
+
+open Feedback
+
+let of_message_level = function
+ | Debug s ->
+ Serialize.constructor "message_level" "debug" [Xml_datatype.PCData s]
+ | Info -> Serialize.constructor "message_level" "info" []
+ | Notice -> Serialize.constructor "message_level" "notice" []
+ | Warning -> Serialize.constructor "message_level" "warning" []
+ | Error -> Serialize.constructor "message_level" "error" []
+let to_message_level =
+ Serialize.do_match "message_level" (fun s args -> match s with
+ | "debug" -> Debug (Serialize.raw_string args)
+ | "info" -> Info
+ | "notice" -> Notice
+ | "warning" -> Warning
+ | "error" -> Error
+ | x -> raise Serialize.(Marshal_error("error level",PCData x)))
+
+let of_message lvl msg =
+ let lvl = of_message_level lvl in
+ let content = of_richpp msg in
+ Xml_datatype.Element ("message", [], [lvl; content])
+let to_message xml = match xml with
+ | Xml_datatype.Element ("message", [], [lvl; content]) ->
+ Message(to_message_level lvl, to_richpp content)
+ | x -> raise (Marshal_error("message",x))
+
+let is_message = function
+ | Xml_datatype.Element ("message", [], [lvl; content]) ->
+ Some (to_message_level lvl, to_richpp content)
+ | _ -> None
+
+let to_feedback_content = do_match "feedback_content" (fun s a -> match s,a with
+ | "addedaxiom", _ -> AddedAxiom
+ | "processed", _ -> Processed
+ | "processingin", [where] -> ProcessingIn (to_string where)
+ | "incomplete", _ -> Incomplete
+ | "complete", _ -> Complete
+ | "globref", [loc; filepath; modpath; ident; ty] ->
+ GlobRef(to_loc loc, to_string filepath,
+ to_string modpath, to_string ident, to_string ty)
+ | "globdef", [loc; ident; secpath; ty] ->
+ GlobDef(to_loc loc, to_string ident, to_string secpath, to_string ty)
+ | "errormsg", [loc; s] -> ErrorMsg (to_loc loc, to_string s)
+ | "inprogress", [n] -> InProgress (to_int n)
+ | "workerstatus", [ns] ->
+ let n, s = to_pair to_string to_string ns in
+ WorkerStatus(n,s)
+ | "goals", [loc;s] -> Goals (to_loc loc, to_string s)
+ | "custom", [loc;name;x]-> Custom (to_loc loc, to_string name, x)
+ | "filedependency", [from; dep] ->
+ FileDependency (to_option to_string from, to_string dep)
+ | "fileloaded", [dirpath; filename] ->
+ FileLoaded (to_string dirpath, to_string filename)
+ | "message", [x] -> to_message x
+ | x,l -> raise (Marshal_error("feedback_content",PCData (x ^ " with attributes " ^ string_of_int (List.length l)))))
+
+let of_feedback_content = function
+ | AddedAxiom -> constructor "feedback_content" "addedaxiom" []
+ | Processed -> constructor "feedback_content" "processed" []
+ | ProcessingIn where ->
+ constructor "feedback_content" "processingin" [of_string where]
+ | Incomplete -> constructor "feedback_content" "incomplete" []
+ | Complete -> constructor "feedback_content" "complete" []
+ | GlobRef(loc, filepath, modpath, ident, ty) ->
+ constructor "feedback_content" "globref" [
+ of_loc loc;
+ of_string filepath;
+ of_string modpath;
+ of_string ident;
+ of_string ty ]
+ | GlobDef(loc, ident, secpath, ty) ->
+ constructor "feedback_content" "globdef" [
+ of_loc loc;
+ of_string ident;
+ of_string secpath;
+ of_string ty ]
+ | ErrorMsg(loc, s) ->
+ constructor "feedback_content" "errormsg" [of_loc loc; of_string s]
+ | InProgress n -> constructor "feedback_content" "inprogress" [of_int n]
+ | WorkerStatus(n,s) ->
+ constructor "feedback_content" "workerstatus"
+ [of_pair of_string of_string (n,s)]
+ | Goals (loc,s) ->
+ constructor "feedback_content" "goals" [of_loc loc;of_string s]
+ | Custom (loc, name, x) ->
+ constructor "feedback_content" "custom" [of_loc loc; of_string name; x]
+ | FileDependency (from, depends_on) ->
+ constructor "feedback_content" "filedependency" [
+ of_option of_string from;
+ of_string depends_on]
+ | FileLoaded (dirpath, filename) ->
+ constructor "feedback_content" "fileloaded" [
+ of_string dirpath;
+ of_string filename ]
+ | Message (l,m) -> constructor "feedback_content" "message" [ of_message l m ]
+
+let of_edit_or_state_id = function
+ | Edit id -> ["object","edit"], of_edit_id id
+ | State id -> ["object","state"], of_stateid id
+
+let of_feedback msg =
+ let content = of_feedback_content msg.contents in
+ let obj, id = of_edit_or_state_id msg.id in
+ let route = string_of_int msg.route in
+ Element ("feedback", obj @ ["route",route], [id;content])
+
+let to_feedback xml = match xml with
+ | Element ("feedback", ["object","edit";"route",route], [id;content]) -> {
+ id = Edit(to_edit_id id);
+ route = int_of_string route;
+ contents = to_feedback_content content }
+ | Element ("feedback", ["object","state";"route",route], [id;content]) -> {
+ id = State(to_stateid id);
+ route = int_of_string route;
+ contents = to_feedback_content content }
+ | x -> raise (Marshal_error("feedback",x))
+
+let is_feedback = function
+ | Element ("feedback", _, _) -> true
+ | _ -> false
+
(* vim: set foldmethod=marker: *)
+
diff --git a/ide/xmlprotocol.mli b/ide/xmlprotocol.mli
index 265a50c47..6bca8772e 100644
--- a/ide/xmlprotocol.mli
+++ b/ide/xmlprotocol.mli
@@ -56,3 +56,17 @@ val document : (xml -> string) -> unit
val pr_call : 'a call -> string
val pr_value : 'a value -> string
val pr_full_value : 'a call -> 'a value -> string
+
+(** * Serialization of rich documents *)
+val of_richpp : Richpp.richpp -> Xml_datatype.xml
+val to_richpp : Xml_datatype.xml -> Richpp.richpp
+
+(** * Serializaiton of feedback *)
+val of_feedback : Feedback.feedback -> xml
+val to_feedback : xml -> Feedback.feedback
+val is_feedback : xml -> bool
+
+val is_message : xml -> (Feedback.level * Richpp.richpp) option
+val of_message : Feedback.level -> Richpp.richpp -> xml
+(* val to_message : xml -> Feedback.message *)
+
diff --git a/interp/constrarg.ml b/interp/constrarg.ml
index a48d68375..011b31d9a 100644
--- a/interp/constrarg.ml
+++ b/interp/constrarg.ml
@@ -8,9 +8,14 @@
open Loc
open Tacexpr
-open Term
open Misctypes
open Genarg
+open Geninterp
+
+let make0 ?dyn name =
+ let wit = Genarg.make0 name in
+ let () = Geninterp.register_val0 wit dyn in
+ wit
(** This is a hack for now, to break the dependency of Genarg on constr-related
types. We should use dedicated functions someday. *)
@@ -20,65 +25,47 @@ let loc_of_or_by_notation f = function
| ByNotation (loc,s,_) -> loc
let wit_int_or_var =
- Genarg.make0 ~dyn:(val_tag (topwit Stdarg.wit_int)) None "int_or_var"
+ make0 ~dyn:(val_tag (topwit Stdarg.wit_int)) "int_or_var"
let wit_intro_pattern : (Constrexpr.constr_expr intro_pattern_expr located, glob_constr_and_expr intro_pattern_expr located, intro_pattern) genarg_type =
- Genarg.make0 None "intropattern"
+ make0 "intropattern"
let wit_tactic : (raw_tactic_expr, glob_tactic_expr, Val.t) genarg_type =
- Genarg.make0 None "tactic"
+ make0 "tactic"
+
+let wit_ltac = make0 ~dyn:(val_tag (topwit Stdarg.wit_unit)) "ltac"
let wit_ident =
- Genarg.make0 None "ident"
+ make0 "ident"
let wit_var =
- Genarg.make0 ~dyn:(val_tag (topwit wit_ident)) None "var"
-
-let wit_ref = Genarg.make0 None "ref"
+ make0 ~dyn:(val_tag (topwit wit_ident)) "var"
-let wit_quant_hyp = Genarg.make0 None "quant_hyp"
+let wit_ref = make0 "ref"
-let wit_sort : (glob_sort, glob_sort, sorts) genarg_type =
- Genarg.make0 None "sort"
+let wit_quant_hyp = make0 "quant_hyp"
let wit_constr =
- Genarg.make0 None "constr"
+ make0 "constr"
-let wit_constr_may_eval =
- Genarg.make0 ~dyn:(val_tag (topwit wit_constr)) None "constr_may_eval"
+let wit_uconstr = make0 "uconstr"
-let wit_uconstr = Genarg.make0 None "uconstr"
+let wit_open_constr = make0 ~dyn:(val_tag (topwit wit_constr)) "open_constr"
-let wit_open_constr = Genarg.make0 ~dyn:(val_tag (topwit wit_constr)) None "open_constr"
+let wit_constr_with_bindings = make0 "constr_with_bindings"
-let wit_constr_with_bindings = Genarg.make0 None "constr_with_bindings"
+let wit_bindings = make0 "bindings"
-let wit_bindings = Genarg.make0 None "bindings"
+let wit_red_expr = make0 "redexpr"
-let wit_hyp_location_flag : 'a Genarg.uniform_genarg_type =
- Genarg.make0 None "hyp_location_flag"
+let wit_clause_dft_concl =
+ make0 "clause_dft_concl"
-let wit_red_expr = Genarg.make0 None "redexpr"
+(** Aliases *)
-let wit_clause_dft_concl =
- Genarg.make0 None "clause_dft_concl"
-
-(** Register location *)
-
-let () =
- register_name0 wit_int_or_var "Constrarg.wit_int_or_var";
- register_name0 wit_ref "Constrarg.wit_ref";
- register_name0 wit_ident "Constrarg.wit_ident";
- register_name0 wit_var "Constrarg.wit_var";
- register_name0 wit_intro_pattern "Constrarg.wit_intro_pattern";
- register_name0 wit_tactic "Constrarg.wit_tactic";
- register_name0 wit_sort "Constrarg.wit_sort";
- register_name0 wit_constr "Constrarg.wit_constr";
- register_name0 wit_uconstr "Constrarg.wit_uconstr";
- register_name0 wit_open_constr "Constrarg.wit_open_constr";
- register_name0 wit_constr_may_eval "Constrarg.wit_constr_may_eval";
- register_name0 wit_red_expr "Constrarg.wit_red_expr";
- register_name0 wit_clause_dft_concl "Constrarg.wit_clause_dft_concl";
- register_name0 wit_quant_hyp "Constrarg.wit_quant_hyp";
- register_name0 wit_bindings "Constrarg.wit_bindings";
- register_name0 wit_constr_with_bindings "Constrarg.wit_constr_with_bindings";
+let wit_reference = wit_ref
+let wit_global = wit_ref
+let wit_clause = wit_clause_dft_concl
+let wit_quantified_hypothesis = wit_quant_hyp
+let wit_intropattern = wit_intro_pattern
+let wit_redexpr = wit_red_expr
diff --git a/interp/constrarg.mli b/interp/constrarg.mli
index 5c26af3c2..70c9c0de2 100644
--- a/interp/constrarg.mli
+++ b/interp/constrarg.mli
@@ -38,15 +38,8 @@ val wit_ref : (reference, global_reference located or_var, global_reference) gen
val wit_quant_hyp : quantified_hypothesis uniform_genarg_type
-val wit_sort : (glob_sort, glob_sort, sorts) genarg_type
-
val wit_constr : (constr_expr, glob_constr_and_expr, constr) genarg_type
-val wit_constr_may_eval :
- ((constr_expr,reference or_by_notation,constr_expr) may_eval,
- (glob_constr_and_expr,evaluable_global_reference and_short_name or_var,glob_constr_pattern_and_expr) may_eval,
- constr) genarg_type
-
val wit_uconstr : (constr_expr , glob_constr_and_expr, Glob_term.closed_glob_constr) genarg_type
val wit_open_constr :
@@ -62,13 +55,28 @@ val wit_bindings :
glob_constr_and_expr bindings,
constr bindings delayed_open) genarg_type
-val wit_hyp_location_flag : Locus.hyp_location_flag uniform_genarg_type
-
val wit_red_expr :
((constr_expr,reference or_by_notation,constr_expr) red_expr_gen,
(glob_constr_and_expr,evaluable_global_reference and_short_name or_var,glob_constr_pattern_and_expr) red_expr_gen,
(constr,evaluable_global_reference,constr_pattern) red_expr_gen) genarg_type
-val wit_tactic : (raw_tactic_expr, glob_tactic_expr, Val.t) genarg_type
+val wit_tactic : (raw_tactic_expr, glob_tactic_expr, Geninterp.Val.t) genarg_type
+
+(** [wit_ltac] is subtly different from [wit_tactic]: they only change for their
+ toplevel interpretation. The one of [wit_ltac] forces the tactic and
+ discards the result. *)
+val wit_ltac : (raw_tactic_expr, glob_tactic_expr, unit) genarg_type
val wit_clause_dft_concl : (Names.Id.t Loc.located Locus.clause_expr,Names.Id.t Loc.located Locus.clause_expr,Names.Id.t Locus.clause_expr) genarg_type
+
+(** Aliases for compatibility *)
+
+val wit_reference : (reference, global_reference located or_var, global_reference) genarg_type
+val wit_global : (reference, global_reference located or_var, global_reference) genarg_type
+val wit_clause : (Names.Id.t Loc.located Locus.clause_expr,Names.Id.t Loc.located Locus.clause_expr,Names.Id.t Locus.clause_expr) genarg_type
+val wit_quantified_hypothesis : quantified_hypothesis uniform_genarg_type
+val wit_intropattern : (constr_expr intro_pattern_expr located, glob_constr_and_expr intro_pattern_expr located, intro_pattern) genarg_type
+val wit_redexpr :
+ ((constr_expr,reference or_by_notation,constr_expr) red_expr_gen,
+ (glob_constr_and_expr,evaluable_global_reference and_short_name or_var,glob_constr_pattern_and_expr) red_expr_gen,
+ (constr,evaluable_global_reference,constr_pattern) red_expr_gen) genarg_type
diff --git a/interp/constrexpr_ops.ml b/interp/constrexpr_ops.ml
index 9c577034e..c5730e626 100644
--- a/interp/constrexpr_ops.ml
+++ b/interp/constrexpr_ops.ml
@@ -66,7 +66,7 @@ let rec cases_pattern_expr_eq p1 p2 =
Id.equal i1 i2 && cases_pattern_expr_eq a1 a2
| CPatCstr(_,c1,a1,b1), CPatCstr(_,c2,a2,b2) ->
eq_reference c1 c2 &&
- List.equal cases_pattern_expr_eq a1 a2 &&
+ Option.equal (List.equal cases_pattern_expr_eq) a1 a2 &&
List.equal cases_pattern_expr_eq b1 b2
| CPatAtom(_,r1), CPatAtom(_,r2) ->
Option.equal eq_reference r1 r2
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index 367544135..57091ca89 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -175,6 +175,10 @@ let add_patt_for_params ind l =
if !Flags.in_debugger then l else
Util.List.addn (Inductiveops.inductive_nparamdecls ind) (CPatAtom (Loc.ghost,None)) l
+let add_cpatt_for_params ind l =
+ if !Flags.in_debugger then l else
+ Util.List.addn (Inductiveops.inductive_nparamdecls ind) (PatVar (Loc.ghost,Anonymous)) l
+
let drop_implicits_in_patt cst nb_expl args =
let impl_st = (implicits_of_global cst) in
let impl_data = extract_impargs_data impl_st in
@@ -266,7 +270,7 @@ let make_pat_notation loc ntn (terms,termlists as subst) args =
let mkPat loc qid l =
(* Normally irrelevant test with v8 syntax, but let's do it anyway *)
- if List.is_empty l then CPatAtom (loc,Some qid) else CPatCstr (loc,qid,[],l)
+ if List.is_empty l then CPatAtom (loc,Some qid) else CPatCstr (loc,qid,None,l)
let pattern_printable_in_both_syntax (ind,_ as c) =
let impl_st = extract_impargs_data (implicits_of_global (ConstructRef c)) in
@@ -286,7 +290,7 @@ let rec extern_cases_pattern_in_scope (scopes:local_scopes) vars pat =
when !Flags.in_debugger||Inductiveops.constructor_has_local_defs cstrsp ->
let c = extern_reference loc Id.Set.empty (ConstructRef cstrsp) in
let args = List.map (extern_cases_pattern_in_scope scopes vars) args in
- CPatCstr (loc, c, add_patt_for_params (fst cstrsp) args, [])
+ CPatCstr (loc, c, Some (add_patt_for_params (fst cstrsp) args), [])
| _ ->
try
if !Flags.raw_print || !print_no_symbol then raise No_match;
@@ -299,7 +303,7 @@ let rec extern_cases_pattern_in_scope (scopes:local_scopes) vars pat =
with No_match ->
try
if !Flags.raw_print || !print_no_symbol then raise No_match;
- extern_symbol_pattern scopes vars pat
+ extern_notation_pattern scopes vars pat
(uninterp_cases_pattern_notations pat)
with No_match ->
match pat with
@@ -327,15 +331,15 @@ let rec extern_cases_pattern_in_scope (scopes:local_scopes) vars pat =
with
Not_found | No_match | Exit ->
let c = extern_reference loc Id.Set.empty (ConstructRef cstrsp) in
- if !Topconstr.oldfashion_patterns then
+ if !Topconstr.asymmetric_patterns then
if pattern_printable_in_both_syntax cstrsp
- then CPatCstr (loc, c, [], args)
- else CPatCstr (loc, c, add_patt_for_params (fst cstrsp) args, [])
+ then CPatCstr (loc, c, None, args)
+ else CPatCstr (loc, c, Some (add_patt_for_params (fst cstrsp) args), [])
else
let full_args = add_patt_for_params (fst cstrsp) args in
match drop_implicits_in_patt (ConstructRef cstrsp) 0 full_args with
- |Some true_args -> CPatCstr (loc, c, [], true_args)
- |None -> CPatCstr (loc, c, full_args, [])
+ |Some true_args -> CPatCstr (loc, c, None, true_args)
+ |None -> CPatCstr (loc, c, Some full_args, [])
in insert_pat_alias loc p na
and apply_notation_to_pattern loc gr ((subst,substlist),(nb_to_drop,more_args))
(tmp_scope, scopes as allscopes) vars =
@@ -358,7 +362,7 @@ and apply_notation_to_pattern loc gr ((subst,substlist),(nb_to_drop,more_args))
List.map (extern_cases_pattern_in_scope subscope vars) c)
substlist in
let l2 = List.map (extern_cases_pattern_in_scope allscopes vars) more_args in
- let l2' = if !Topconstr.oldfashion_patterns || not (List.is_empty ll) then l2
+ let l2' = if !Topconstr.asymmetric_patterns || not (List.is_empty ll) then l2
else
match drop_implicits_in_patt gr nb_to_drop l2 with
|Some true_args -> true_args
@@ -374,7 +378,7 @@ and apply_notation_to_pattern loc gr ((subst,substlist),(nb_to_drop,more_args))
extern_cases_pattern_in_scope (scopt,scl@scopes) vars c)
subst in
let l2 = List.map (extern_cases_pattern_in_scope allscopes vars) more_args in
- let l2' = if !Topconstr.oldfashion_patterns then l2
+ let l2' = if !Topconstr.asymmetric_patterns then l2
else
match drop_implicits_in_patt gr (nb_to_drop + List.length l1) l2 with
|Some true_args -> true_args
@@ -382,7 +386,7 @@ and apply_notation_to_pattern loc gr ((subst,substlist),(nb_to_drop,more_args))
in
assert (List.is_empty substlist);
mkPat loc qid (List.rev_append l1 l2')
-and extern_symbol_pattern (tmp_scope,scopes as allscopes) vars t = function
+and extern_notation_pattern (tmp_scope,scopes as allscopes) vars t = function
| [] -> raise No_match
| (keyrule,pat,n as _rule)::rules ->
try
@@ -395,9 +399,9 @@ and extern_symbol_pattern (tmp_scope,scopes as allscopes) vars t = function
| PatVar (loc,Anonymous) -> CPatAtom (loc, None)
| PatVar (loc,Name id) -> CPatAtom (loc, Some (Ident (loc,id)))
with
- No_match -> extern_symbol_pattern allscopes vars t rules
+ No_match -> extern_notation_pattern allscopes vars t rules
-let rec extern_symbol_ind_pattern allscopes vars ind args = function
+let rec extern_notation_ind_pattern allscopes vars ind args = function
| [] -> raise No_match
| (keyrule,pat,n as _rule)::rules ->
try
@@ -405,7 +409,7 @@ let rec extern_symbol_ind_pattern allscopes vars ind args = function
apply_notation_to_pattern Loc.ghost (IndRef ind)
(match_notation_constr_ind_pattern ind args pat) allscopes vars keyrule
with
- No_match -> extern_symbol_ind_pattern allscopes vars ind args rules
+ No_match -> extern_notation_ind_pattern allscopes vars ind args rules
let extern_ind_pattern_in_scope (scopes:local_scopes) vars ind args =
(* pboutill: There are letins in pat which is incompatible with notations and
@@ -413,7 +417,7 @@ let extern_ind_pattern_in_scope (scopes:local_scopes) vars ind args =
if !Flags.in_debugger||Inductiveops.inductive_has_local_defs ind then
let c = extern_reference Loc.ghost vars (IndRef ind) in
let args = List.map (extern_cases_pattern_in_scope scopes vars) args in
- CPatCstr (Loc.ghost, c, add_patt_for_params ind args, [])
+ CPatCstr (Loc.ghost, c, Some (add_patt_for_params ind args), [])
else
try
if !Flags.raw_print || !print_no_symbol then raise No_match;
@@ -425,14 +429,14 @@ let extern_ind_pattern_in_scope (scopes:local_scopes) vars ind args =
with No_match ->
try
if !Flags.raw_print || !print_no_symbol then raise No_match;
- extern_symbol_ind_pattern scopes vars ind args
+ extern_notation_ind_pattern scopes vars ind args
(uninterp_ind_pattern_notations ind)
with No_match ->
let c = extern_reference Loc.ghost vars (IndRef ind) in
let args = List.map (extern_cases_pattern_in_scope scopes vars) args in
match drop_implicits_in_patt (IndRef ind) 0 args with
- |Some true_args -> CPatCstr (Loc.ghost, c, [], true_args)
- |None -> CPatCstr (Loc.ghost, c, args, [])
+ |Some true_args -> CPatCstr (Loc.ghost, c, None, true_args)
+ |None -> CPatCstr (Loc.ghost, c, Some args, [])
let extern_cases_pattern vars p =
extern_cases_pattern_in_scope (None,[]) vars p
@@ -477,15 +481,15 @@ let explicitize loc inctx impl (cf,f) args =
(!print_implicits && !print_implicits_explicit_args) ||
(is_needed_for_correct_partial_application tail imp) ||
(!print_implicits_defensive &&
- is_significant_implicit a &&
- not (is_inferable_implicit inctx n imp))
+ not (is_inferable_implicit inctx n imp) &&
+ is_significant_implicit (Lazy.force a))
in
if visible then
- (a,Some (Loc.ghost, ExplByName (name_of_implicit imp))) :: tail
+ (Lazy.force a,Some (Loc.ghost, ExplByName (name_of_implicit imp))) :: tail
else
tail
- | a::args, _::impl -> (a,None) :: exprec (q+1) (args,impl)
- | args, [] -> List.map (fun a -> (a,None)) args (*In case of polymorphism*)
+ | a::args, _::impl -> (Lazy.force a,None) :: exprec (q+1) (args,impl)
+ | args, [] -> List.map (fun a -> (Lazy.force a,None)) args (*In case of polymorphism*)
| [], (imp :: _) when is_status_implicit imp && maximal_insertion_of imp ->
(* The non-explicit application cannot be parsed back with the same type *)
raise Expl
@@ -512,7 +516,7 @@ let explicitize loc inctx impl (cf,f) args =
with Expl ->
let f',us = match f with CRef (f,us) -> f,us | _ -> assert false in
let ip = if !print_projections then ip else None in
- CAppExpl (loc, (ip, f', us), args)
+ CAppExpl (loc, (ip, f', us), List.map Lazy.force args)
let is_start_implicit = function
| imp :: _ -> is_status_implicit imp && maximal_insertion_of imp
@@ -534,19 +538,21 @@ let extern_app loc inctx impl (cf,f) us args =
(!print_implicits && not !print_implicits_explicit_args)) &&
List.exists is_status_implicit impl)
then
+ let args = List.map Lazy.force args in
CAppExpl (loc, (is_projection (List.length args) cf,f,us), args)
else
explicitize loc inctx impl (cf,CRef (f,us)) args
-let rec extern_args extern scopes env args subscopes =
- match args with
- | [] -> []
- | a::args ->
- let argscopes, subscopes = match subscopes with
- | [] -> (None,scopes), []
- | scopt::subscopes -> (scopt,scopes), subscopes in
- extern argscopes env a :: extern_args extern scopes env args subscopes
+let rec fill_arg_scopes args subscopes scopes = match args, subscopes with
+| [], _ -> []
+| a :: args, scopt :: subscopes ->
+ (a, (scopt, scopes)) :: fill_arg_scopes args subscopes scopes
+| a :: args, [] ->
+ (a, (None, scopes)) :: fill_arg_scopes args [] scopes
+let extern_args extern env args =
+ let map (arg, argscopes) = lazy (extern argscopes env arg) in
+ List.map map args
let match_coercion_app = function
| GApp (loc,GRef (_,r,_),args) -> Some (loc, r, 0, args)
@@ -622,7 +628,7 @@ let rec extern inctx scopes vars r =
try
let r'' = flatten_application r' in
if !Flags.raw_print || !print_no_symbol then raise No_match;
- extern_symbol scopes vars r'' (uninterp_notations r'')
+ extern_notation scopes vars r'' (uninterp_notations r'')
with No_match -> match r' with
| GRef (loc,ref,us) ->
extern_global loc (select_stronger_impargs (implicits_of_global ref))
@@ -643,8 +649,7 @@ let rec extern inctx scopes vars r =
(match f with
| GRef (rloc,ref,us) ->
let subscopes = find_arguments_scope ref in
- let args =
- extern_args (extern true) (snd scopes) vars args subscopes in
+ let args = fill_arg_scopes args subscopes (snd scopes) in
begin
try
if !Flags.raw_print then raise Exit;
@@ -679,12 +684,14 @@ let rec extern inctx scopes vars r =
match args with
| [] -> raise No_match
(* we give up since the constructor is not complete *)
- | head :: tail -> ip q locs' tail
- ((extern_reference loc Id.Set.empty (ConstRef c), head) :: acc)
+ | (arg, scopes) :: tail ->
+ let head = extern true scopes vars arg in
+ ip q locs' tail ((extern_reference loc Id.Set.empty (ConstRef c), head) :: acc)
in
CRecord (loc, List.rev (ip projs locals args []))
with
| Not_found | No_match | Exit ->
+ let args = extern_args (extern true) vars args in
extern_app loc inctx
(select_stronger_impargs (implicits_of_global ref))
(Some ref,extern_reference rloc vars ref) (extern_universes us) args
@@ -692,7 +699,7 @@ let rec extern inctx scopes vars r =
| _ ->
explicitize loc inctx [] (None,sub_extern false scopes vars f)
- (List.map (sub_extern true scopes vars) args))
+ (List.map (fun c -> lazy (sub_extern true scopes vars c)) args))
| GLetIn (loc,na,t,c) ->
CLetIn (loc,(loc,na),sub_extern false scopes vars t,
@@ -730,9 +737,7 @@ let rec extern inctx scopes vars r =
na',
Option.map (fun (loc,ind,nal) ->
let args = List.map (fun x -> PatVar (Loc.ghost, x)) nal in
- let fullargs =
- if !Flags.in_debugger then args else
- Notation_ops.add_patterns_for_params ind args in
+ let fullargs = add_cpatt_for_params ind args in
extern_ind_pattern_in_scope scopes vars ind fullargs
) x))
tml
@@ -793,7 +798,7 @@ let rec extern inctx scopes vars r =
Miscops.map_cast_type (extern_typ scopes vars) c')
and extern_typ (_,scopes) =
- extern true (Some Notation.type_scope,scopes)
+ extern true (Notation.current_type_scope_name (),scopes)
and sub_extern inctx (_,scopes) = extern inctx (None,scopes)
@@ -842,7 +847,7 @@ and extern_eqn inctx scopes vars (loc,ids,pl,c) =
(loc,[loc,List.map (extern_cases_pattern_in_scope scopes vars) pl],
extern inctx scopes vars c)
-and extern_symbol (tmp_scope,scopes as allscopes) vars t = function
+and extern_notation (tmp_scope,scopes as allscopes) vars t = function
| [] -> raise No_match
| (keyrule,pat,n as _rule)::rules ->
let loc = Glob_ops.loc_of_glob_constr t in
@@ -914,10 +919,11 @@ and extern_symbol (tmp_scope,scopes as allscopes) vars t = function
if List.is_empty l then a else CApp (loc,(None,a),l) in
if List.is_empty args then e
else
- let args = extern_args (extern true) scopes vars args argsscopes in
+ let args = fill_arg_scopes args argsscopes scopes in
+ let args = extern_args (extern true) vars args in
explicitize loc false argsimpls (None,e) args
with
- No_match -> extern_symbol allscopes vars t rules
+ No_match -> extern_notation allscopes vars t rules
and extern_recursion_order scopes vars = function
GStructRec -> CStructRec
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 36f88fc3c..50252a368 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -300,7 +300,7 @@ let set_var_scope loc id istermvar env ntnvars =
(* Not in a notation *)
()
-let set_type_scope env = {env with tmp_scope = Some Notation.type_scope}
+let set_type_scope env = {env with tmp_scope = Notation.current_type_scope_name ()}
let reset_tmp_scope env = {env with tmp_scope = None}
@@ -451,12 +451,15 @@ let intern_generalization intern env lvar loc bk ak c =
| Some AbsPi -> true
| Some _ -> false
| None ->
- let is_type_scope = match env.tmp_scope with
+ match Notation.current_type_scope_name () with
+ | Some type_scope ->
+ let is_type_scope = match env.tmp_scope with
+ | None -> false
+ | Some sc -> String.equal sc type_scope
+ in
+ is_type_scope ||
+ String.List.mem type_scope env.scopes
| None -> false
- | Some sc -> String.equal sc Notation.type_scope
- in
- is_type_scope ||
- String.List.mem Notation.type_scope env.scopes
in
if pi then
(fun (id, loc') acc ->
@@ -523,7 +526,7 @@ let rec subst_iterator y t = function
| GVar (_,id) as x -> if Id.equal id y then t else x
| x -> map_glob_constr (subst_iterator y t) x
-let subst_aconstr_in_glob_constr loc intern (_,ntnvars as lvar) subst infos c =
+let instantiate_notation_constr loc intern (_,ntnvars as lvar) subst infos c =
let (terms,termlists,binders) = subst in
(* when called while defining a notation, avoid capturing the private binders
of the expression by variables bound by the notation (see #3892) *)
@@ -646,7 +649,7 @@ let intern_notation intern env lvar loc ntn fullargs =
let terms = make_subst ids args in
let termlists = make_subst idsl argslist in
let binders = make_subst idsbl bll in
- subst_aconstr_in_glob_constr loc intern lvar
+ instantiate_notation_constr loc intern lvar
(terms, termlists, binders) (Id.Map.empty, env) c
(**********************************************************************)
@@ -756,7 +759,15 @@ let intern_qualid loc qid intern env lvar us args =
let subst = (terms, Id.Map.empty, Id.Map.empty) in
let infos = (Id.Map.empty, env) in
let projapp = match c with NRef _ -> true | _ -> false in
- subst_aconstr_in_glob_constr loc intern lvar subst infos c, projapp, args2
+ let c = instantiate_notation_constr loc intern lvar subst infos c in
+ let c = match us, c with
+ | None, _ -> c
+ | Some _, GRef (loc, ref, None) -> GRef (loc, ref, us)
+ | Some _, _ ->
+ user_err_loc (loc, "", str "Notation " ++ pr_qualid qid ++
+ str " cannot have a universe instance")
+ in
+ c, projapp, args2
(* Rule out section vars since these should have been found by intern_var *)
let intern_non_secvar_qualid loc qid intern env lvar us args =
@@ -918,7 +929,7 @@ let chop_params_pattern loc ind args with_letin =
args
let find_constructor loc add_params ref =
- let cstr = match ref with
+ let (ind,_ as cstr) = match ref with
| ConstructRef cstr -> cstr
| IndRef _ ->
let error = str "There is an inductive name deep in a \"in\" clause." in
@@ -927,15 +938,15 @@ let find_constructor loc add_params ref =
let error = str "This reference is not a constructor." in
user_err_loc (loc, "find_constructor", error)
in
- cstr, (function (ind,_ as c) -> match add_params with
- |Some nb_args ->
+ cstr, match add_params with
+ | Some nb_args ->
let nb =
- if Int.equal nb_args (Inductiveops.constructor_nrealdecls c)
+ if Int.equal nb_args (Inductiveops.constructor_nrealdecls cstr)
then Inductiveops.inductive_nparamdecls ind
else Inductiveops.inductive_nparams ind
in
List.make nb ([], [(Id.Map.empty, PatVar(Loc.ghost,Anonymous))])
- |None -> []) cstr
+ | None -> []
let find_pattern_variable = function
| Ident (loc,id) -> id
@@ -1058,7 +1069,7 @@ let alias_of als = match als.alias_ids with
| id :: _ -> Name id
let message_redundant_alias id1 id2 =
- msg_warning
+ Feedback.msg_warning
(str "Alias variable " ++ pr_id id1 ++ str " is merged with " ++ pr_id id2)
(** {6 Expanding notations }
@@ -1091,41 +1102,42 @@ let drop_notations_pattern looked_for =
let test_kind top =
if top then looked_for else function ConstructRef _ -> () | _ -> raise Not_found
in
- let rec drop_syndef top env re pats =
+ let rec drop_syndef top scopes re pats =
let (loc,qid) = qualid_of_reference re in
try
match locate_extended qid with
- |SynDef sp ->
+ | SynDef sp ->
let (vars,a) = Syntax_def.search_syntactic_definition sp in
(match a with
| NRef g ->
+ (* Convention: do not deactivate implicit arguments and scopes for further arguments *)
test_kind top g;
let () = assert (List.is_empty vars) in
let (_,argscs) = find_remaining_scopes [] pats g in
- Some (g, [], List.map2 (in_pat_sc env) argscs pats)
- | NApp (NRef g,[]) -> (* special case : Syndef for @Cstr *)
+ Some (g, [], List.map2 (in_pat_sc scopes) argscs pats)
+ | NApp (NRef g,[]) -> (* special case: Syndef for @Cstr, this deactivates *)
test_kind top g;
let () = assert (List.is_empty vars) in
- let (argscs,_) = find_remaining_scopes pats [] g in
- Some (g, List.map2 (in_pat_sc env) argscs pats, [])
+ Some (g, List.map (in_pat false scopes) pats, [])
| NApp (NRef g,args) ->
+ (* Convention: do not deactivate implicit arguments and scopes for further arguments *)
test_kind top g;
let nvars = List.length vars in
if List.length pats < nvars then error_not_enough_arguments loc;
let pats1,pats2 = List.chop nvars pats in
let subst = make_subst vars pats1 in
- let idspl1 = List.map (in_not false loc env (subst, Id.Map.empty) []) args in
+ let idspl1 = List.map (in_not false loc scopes (subst, Id.Map.empty) []) args in
let (_,argscs) = find_remaining_scopes pats1 pats2 g in
- Some (g, idspl1, List.map2 (in_pat_sc env) argscs pats2)
+ Some (g, idspl1, List.map2 (in_pat_sc scopes) argscs pats2)
| _ -> raise Not_found)
- |TrueGlobal g ->
+ | TrueGlobal g ->
test_kind top g;
Dumpglob.add_glob loc g;
let (_,argscs) = find_remaining_scopes [] pats g in
- Some (g,[],List.map2 (fun x -> in_pat false {env with tmp_scope = x}) argscs pats)
+ Some (g,[],List.map2 (fun x -> in_pat false (x,snd scopes)) argscs pats)
with Not_found -> None
- and in_pat top env = function
- | CPatAlias (loc, p, id) -> RCPatAlias (loc, in_pat top env p, id)
+ and in_pat top scopes = function
+ | CPatAlias (loc, p, id) -> RCPatAlias (loc, in_pat top scopes p, id)
| CPatRecord (loc, l) ->
let sorted_fields =
sort_fields false loc l (fun _ l -> (CPatAtom (loc, None))::l) in
@@ -1133,56 +1145,58 @@ let drop_notations_pattern looked_for =
| None -> RCPatAtom (loc, None)
| Some (n, head, pl) ->
let pl =
- if !oldfashion_patterns then pl else
+ if !asymmetric_patterns then pl else
let pars = List.make n (CPatAtom (loc, None)) in
List.rev_append pars pl in
- match drop_syndef top env head pl with
+ match drop_syndef top scopes head pl with
|Some (a,b,c) -> RCPatCstr(loc, a, b, c)
|None -> raise (InternalizationError (loc,NotAConstructor head))
end
- | CPatCstr (loc, head, [], pl) ->
+ | CPatCstr (loc, head, None, pl) ->
begin
- match drop_syndef top env head pl with
+ match drop_syndef top scopes head pl with
| Some (a,b,c) -> RCPatCstr(loc, a, b, c)
| None -> raise (InternalizationError (loc,NotAConstructor head))
end
- | CPatCstr (loc, r, expl_pl, pl) ->
- let g = try
- (locate (snd (qualid_of_reference r)))
- with Not_found ->
+ | CPatCstr (loc, r, Some expl_pl, pl) ->
+ let g = try locate (snd (qualid_of_reference r))
+ with Not_found ->
raise (InternalizationError (loc,NotAConstructor r)) in
- let (argscs1,argscs2) = find_remaining_scopes expl_pl pl g in
- RCPatCstr (loc, g, List.map2 (in_pat_sc env) argscs1 expl_pl, List.map2 (in_pat_sc env) argscs2 pl)
+ if expl_pl == [] then
+ (* Convention: (@r) deactivates all further implicit arguments and scopes *)
+ RCPatCstr (loc, g, List.map (in_pat false scopes) pl, [])
+ else
+ (* Convention: (@r expl_pl) deactivates implicit arguments in expl_pl and in pl *)
+ (* but not scopes in expl_pl *)
+ let (argscs1,_) = find_remaining_scopes expl_pl pl g in
+ RCPatCstr (loc, g, List.map2 (in_pat_sc scopes) argscs1 expl_pl @ List.map (in_pat false scopes) pl, [])
| CPatNotation (loc,"- _",([CPatPrim(_,Numeral p)],[]),[])
when Bigint.is_strictly_pos p ->
- fst (Notation.interp_prim_token_cases_pattern_expr loc (ensure_kind false loc) (Numeral (Bigint.neg p))
- (env.tmp_scope,env.scopes))
+ fst (Notation.interp_prim_token_cases_pattern_expr loc (ensure_kind false loc) (Numeral (Bigint.neg p)) scopes)
| CPatNotation (_,"( _ )",([a],[]),[]) ->
- in_pat top env a
+ in_pat top scopes a
| CPatNotation (loc, ntn, fullargs,extrargs) ->
let ntn,(args,argsl as fullargs) = contract_pat_notation ntn fullargs in
- let ((ids',c),df) = Notation.interp_notation loc ntn (env.tmp_scope,env.scopes) in
+ let ((ids',c),df) = Notation.interp_notation loc ntn scopes in
let (ids',idsl',_) = split_by_type ids' in
Dumpglob.dump_notation_location (patntn_loc loc fullargs ntn) ntn df;
let substlist = make_subst idsl' argsl in
let subst = make_subst ids' args in
- in_not top loc env (subst,substlist) extrargs c
+ in_not top loc scopes (subst,substlist) extrargs c
| CPatDelimiters (loc, key, e) ->
- in_pat top {env with scopes=find_delimiters_scope loc key::env.scopes;
- tmp_scope = None} e
- | CPatPrim (loc,p) -> fst (Notation.interp_prim_token_cases_pattern_expr loc (test_kind false) p
- (env.tmp_scope,env.scopes))
+ in_pat top (None,find_delimiters_scope loc key::snd scopes) e
+ | CPatPrim (loc,p) -> fst (Notation.interp_prim_token_cases_pattern_expr loc (test_kind false) p scopes)
| CPatAtom (loc, Some id) ->
begin
- match drop_syndef top env id [] with
+ match drop_syndef top scopes id [] with
|Some (a,b,c) -> RCPatCstr (loc, a, b, c)
|None -> RCPatAtom (loc, Some (find_pattern_variable id))
end
| CPatAtom (loc,None) -> RCPatAtom (loc,None)
| CPatOr (loc, pl) ->
- RCPatOr (loc,List.map (in_pat top env) pl)
- and in_pat_sc env x = in_pat false {env with tmp_scope = x}
- and in_not top loc env (subst,substlist as fullsubst) args = function
+ RCPatOr (loc,List.map (in_pat top scopes) pl)
+ and in_pat_sc scopes x = in_pat false (x,snd scopes)
+ and in_not top loc scopes (subst,substlist as fullsubst) args = function
| NVar id ->
let () = assert (List.is_empty args) in
begin
@@ -1190,8 +1204,7 @@ let drop_notations_pattern looked_for =
(* of the notations *)
try
let (a,(scopt,subscopes)) = Id.Map.find id subst in
- in_pat top {env with scopes=subscopes@env.scopes;
- tmp_scope = scopt} a
+ in_pat top (scopt,subscopes@snd scopes) a
with Not_found ->
if Id.equal id ldots_var then RCPatAtom (loc,Some id) else
anomaly (str "Unbound pattern notation variable: " ++ Id.print id)
@@ -1199,23 +1212,23 @@ let drop_notations_pattern looked_for =
| NRef g ->
ensure_kind top loc g;
let (_,argscs) = find_remaining_scopes [] args g in
- RCPatCstr (loc, g, [], List.map2 (in_pat_sc env) argscs args)
+ RCPatCstr (loc, g, [], List.map2 (in_pat_sc scopes) argscs args)
| NApp (NRef g,pl) ->
ensure_kind top loc g;
let (argscs1,argscs2) = find_remaining_scopes pl args g in
RCPatCstr (loc, g,
- List.map2 (fun x -> in_not false loc {env with tmp_scope = x} fullsubst []) argscs1 pl,
- List.map2 (in_pat_sc env) argscs2 args)
+ List.map2 (fun x -> in_not false loc (x,snd scopes) fullsubst []) argscs1 pl @
+ List.map (in_pat false scopes) args, [])
| NList (x,_,iter,terminator,lassoc) ->
if not (List.is_empty args) then user_err_loc
(loc,"",strbrk "Application of arguments to a recursive notation not supported in patterns.");
(try
(* All elements of the list are in scopes (scopt,subscopes) *)
let (l,(scopt,subscopes)) = Id.Map.find x substlist in
- let termin = in_not top loc env fullsubst [] terminator in
+ let termin = in_not top loc scopes fullsubst [] terminator in
List.fold_right (fun a t ->
let nsubst = Id.Map.add x (a, (scopt, subscopes)) subst in
- let u = in_not false loc env (nsubst, substlist) [] iter in
+ let u = in_not false loc scopes (nsubst, substlist) [] iter in
subst_pat_iterator ldots_var t u)
(if lassoc then List.rev l else l) termin
with Not_found ->
@@ -1238,7 +1251,7 @@ let rec intern_pat genv aliases pat =
let aliases' = merge_aliases aliases id in
intern_pat genv aliases' p
| RCPatCstr (loc, head, expl_pl, pl) ->
- if !oldfashion_patterns then
+ if !asymmetric_patterns then
let len = if List.is_empty expl_pl then Some (List.length pl) else None in
let c,idslpl1 = find_constructor loc len head in
let with_letin =
@@ -1263,29 +1276,27 @@ let rec intern_pat genv aliases pat =
check_or_pat_variables loc ids (List.tl idsl);
(ids,List.flatten pl')
-let intern_cases_pattern genv env aliases pat =
+let intern_cases_pattern genv scopes aliases pat =
intern_pat genv aliases
- (drop_notations_pattern (function ConstructRef _ -> () | _ -> raise Not_found) env pat)
+ (drop_notations_pattern (function ConstructRef _ -> () | _ -> raise Not_found) scopes pat)
-let intern_ind_pattern genv env pat =
+let intern_ind_pattern genv scopes pat =
let no_not =
try
- drop_notations_pattern (function (IndRef _ | ConstructRef _) -> () | _ -> raise Not_found) env pat
+ drop_notations_pattern (function (IndRef _ | ConstructRef _) -> () | _ -> raise Not_found) scopes pat
with InternalizationError(loc,NotAConstructor _) -> error_bad_inductive_type loc
- in
+ in
match no_not with
- | RCPatCstr (loc, head,expl_pl, pl) ->
- let c = (function IndRef ind -> ind
- |_ -> error_bad_inductive_type loc) head in
+ | RCPatCstr (loc, head, expl_pl, pl) ->
+ let c = (function IndRef ind -> ind | _ -> error_bad_inductive_type loc) head in
let with_letin, pl2 = add_implicits_check_ind_length genv loc c
(List.length expl_pl) pl in
let idslpl1 = List.rev_map (intern_pat genv empty_alias) expl_pl in
let idslpl2 = List.map (intern_pat genv empty_alias) pl2 in
(with_letin,
match product_of_cases_patterns [] (List.rev_append idslpl1 idslpl2) with
- |_,[_,pl] ->
- (c,chop_params_pattern loc c pl with_letin)
- |_ -> error_bad_inductive_type loc)
+ | _,[_,pl] -> (c,chop_params_pattern loc c pl with_letin)
+ | _ -> error_bad_inductive_type loc)
| x -> error_bad_inductive_type (raw_cases_pattern_expr_loc x)
(**********************************************************************)
@@ -1495,36 +1506,44 @@ let internalize globalenv env allow_patvar lvar c =
intern env app
end
| CCases (loc, sty, rtnpo, tms, eqns) ->
- let as_in_vars = List.fold_left (fun acc (_,na,inb) ->
- Option.fold_left (fun x tt -> List.fold_right Id.Set.add (ids_of_cases_indtype tt) x)
- (Option.fold_left (fun x (_,y) -> match y with | Name y' -> Id.Set.add y' x |_ -> x) acc na)
- inb) Id.Set.empty tms in
- (* as, in & return vars *)
- let forbidden_vars = Option.cata free_vars_of_constr_expr as_in_vars rtnpo in
- let tms,ex_ids,match_from_in = List.fold_right
- (fun citm (inds,ex_ids,matchs) ->
- let ((tm,ind),extra_id,match_td) = intern_case_item env forbidden_vars citm in
- (tm,ind)::inds, Option.fold_right Id.Set.add extra_id ex_ids, List.rev_append match_td matchs)
- tms ([],Id.Set.empty,[]) in
- let env' = Id.Set.fold
- (fun var bli -> push_name_env lvar (Variable,[],[],[]) bli (Loc.ghost,Name var))
- (Id.Set.union ex_ids as_in_vars) (reset_hidden_inductive_implicit_test env) in
- (* PatVars before a real pattern do not need to be matched *)
- let stripped_match_from_in = let rec aux = function
- |[] -> []
- |(_,PatVar _) :: q -> aux q
- |l -> l
- in aux match_from_in in
+ let as_in_vars = List.fold_left (fun acc (_,na,inb) ->
+ Option.fold_left (fun acc tt -> Id.Set.union (ids_of_cases_indtype tt) acc)
+ (Option.fold_left (fun acc (_,y) -> name_fold Id.Set.add y acc) acc na)
+ inb) Id.Set.empty tms in
+ (* as, in & return vars *)
+ let forbidden_vars = Option.cata free_vars_of_constr_expr as_in_vars rtnpo in
+ let tms,ex_ids,match_from_in = List.fold_right
+ (fun citm (inds,ex_ids,matchs) ->
+ let ((tm,ind),extra_id,match_td) = intern_case_item env forbidden_vars citm in
+ (tm,ind)::inds, Option.fold_right Id.Set.add extra_id ex_ids, List.rev_append match_td matchs)
+ tms ([],Id.Set.empty,[]) in
+ let env' = Id.Set.fold
+ (fun var bli -> push_name_env lvar (Variable,[],[],[]) bli (Loc.ghost,Name var))
+ (Id.Set.union ex_ids as_in_vars) (reset_hidden_inductive_implicit_test env) in
+ (* PatVars before a real pattern do not need to be matched *)
+ let stripped_match_from_in =
+ let rec aux = function
+ | [] -> []
+ | (_,PatVar _) :: q -> aux q
+ | l -> l
+ in aux match_from_in in
let rtnpo = match stripped_match_from_in with
| [] -> Option.map (intern_type env') rtnpo (* Only PatVar in "in" clauses *)
- | l -> let thevars,thepats=List.split l in
- Some (
- GCases(Loc.ghost,Term.RegularStyle,(* Some (GSort (Loc.ghost,GType None)) *)None, (* "return Type" *)
- List.map (fun id -> GVar (Loc.ghost,id),(Name id,None)) thevars, (* "match v1,..,vn" *)
- [Loc.ghost,[],thepats, (* "|p1,..,pn" *)
- Option.cata (intern_type env') (GHole(Loc.ghost,Evar_kinds.CasesType false,Misctypes.IntroAnonymous,None)) rtnpo; (* "=> P" is there were a P "=> _" else *)
- Loc.ghost,[],List.make (List.length thepats) (PatVar(Loc.ghost,Anonymous)), (* "|_,..,_" *)
- GHole(Loc.ghost,Evar_kinds.ImpossibleCase,Misctypes.IntroAnonymous,None) (* "=> _" *)]))
+ | l ->
+ (* Build a return predicate by expansion of the patterns of the "in" clause *)
+ let thevars,thepats = List.split l in
+ let sub_rtn = (* Some (GSort (Loc.ghost,GType None)) *) None in
+ let sub_tms = List.map (fun id -> GVar (Loc.ghost,id),(Name id,None)) thevars (* "match v1,..,vn" *) in
+ let main_sub_eqn =
+ (Loc.ghost,[],thepats, (* "|p1,..,pn" *)
+ Option.cata (intern_type env')
+ (GHole(Loc.ghost,Evar_kinds.CasesType false,Misctypes.IntroAnonymous,None))
+ rtnpo) (* "=> P" if there were a return predicate P, and "=> _" otherwise *) in
+ let catch_all_sub_eqn =
+ if List.for_all (irrefutable globalenv) thepats then [] else
+ [Loc.ghost,[],List.make (List.length thepats) (PatVar(Loc.ghost,Anonymous)), (* "|_,..,_" *)
+ GHole(Loc.ghost,Evar_kinds.ImpossibleCase,Misctypes.IntroAnonymous,None)] (* "=> _" *) in
+ Some (GCases(Loc.ghost,Term.RegularStyle,sub_rtn,sub_tms,main_sub_eqn::catch_all_sub_eqn))
in
let eqns' = List.map (intern_eqn (List.length tms) env) eqns in
GCases (loc, sty, rtnpo, tms, List.flatten eqns')
@@ -1591,8 +1610,7 @@ let internalize globalenv env allow_patvar lvar c =
(* Expands a multiple pattern into a disjunction of multiple patterns *)
and intern_multiple_pattern env n (loc,pl) =
- let idsl_pll =
- List.map (intern_cases_pattern globalenv {env with tmp_scope = None} empty_alias) pl in
+ let idsl_pll = List.map (intern_cases_pattern globalenv (None,env.scopes) empty_alias) pl in
check_number_of_pattern loc n pl;
product_of_cases_patterns [] idsl_pll
@@ -1618,7 +1636,7 @@ let internalize globalenv env allow_patvar lvar c =
(loc,eqn_ids,pl,rhs')) pll
and intern_case_item env forbidden_names_for_gen (tm,na,t) =
- (*the "match" part *)
+ (* the "match" part *)
let tm' = intern env tm in
(* the "as" part *)
let extra_id,na = match tm', na with
@@ -1629,9 +1647,7 @@ let internalize globalenv env allow_patvar lvar c =
(* the "in" part *)
let match_td,typ = match t with
| Some t ->
- let tids = ids_of_cases_indtype t in
- let tids = List.fold_right Id.Set.add tids Id.Set.empty in
- let with_letin,(ind,l) = intern_ind_pattern globalenv {env with ids = tids; tmp_scope = None} t in
+ let with_letin,(ind,l) = intern_ind_pattern globalenv (None,env.scopes) t in
let (mib,mip) = Inductive.lookup_mind_specif globalenv ind in
let nparams = (List.length (mib.Declarations.mind_params_ctxt)) in
(* for "in Vect n", we answer (["n","n"],[(loc,"n")])
@@ -1643,15 +1659,15 @@ let internalize globalenv env allow_patvar lvar c =
let (match_to_do,nal) =
let rec canonize_args case_rel_ctxt arg_pats forbidden_names match_acc var_acc =
let add_name l = function
- |_,Anonymous -> l
- |loc,(Name y as x) -> (y,PatVar(loc,x)) :: l in
+ | _,Anonymous -> l
+ | loc,(Name y as x) -> (y,PatVar(loc,x)) :: l in
match case_rel_ctxt,arg_pats with
(* LetIn in the rel_context *)
| LocalDef _ :: t, l when not with_letin ->
canonize_args t l forbidden_names match_acc ((Loc.ghost,Anonymous)::var_acc)
- |[],[] ->
+ | [],[] ->
(add_name match_acc na, var_acc)
- |_::t,PatVar (loc,x)::tt ->
+ | _::t,PatVar (loc,x)::tt ->
canonize_args t tt forbidden_names
(add_name match_acc (loc,x)) ((loc,x)::var_acc)
| (LocalAssum (cano_name,ty) | LocalDef (cano_name,_,ty)) :: t, c::tt ->
@@ -1659,7 +1675,7 @@ let internalize globalenv env allow_patvar lvar c =
Namegen.next_name_away_with_default_using_types "iV" cano_name forbidden_names ty in
canonize_args t tt (fresh::forbidden_names)
((fresh,c)::match_acc) ((cases_pattern_loc c,Name fresh)::var_acc)
- |_ -> assert false in
+ | _ -> assert false in
let _,args_rel =
List.chop nparams (List.rev mip.Declarations.mind_arity_ctxt) in
canonize_args args_rel l (Id.Set.elements forbidden_names_for_gen) [] [] in
@@ -1749,7 +1765,7 @@ let extract_ids env =
Id.Set.empty
let scope_of_type_kind = function
- | IsType -> Some Notation.type_scope
+ | IsType -> Notation.current_type_scope_name ()
| OfType typ -> compute_type_scope typ
| WithoutTypeConstraint -> None
@@ -1773,9 +1789,7 @@ let intern_type env c = intern_gen IsType env c
let intern_pattern globalenv patt =
try
- intern_cases_pattern globalenv {ids = extract_ids globalenv; unb = false;
- tmp_scope = None; scopes = [];
- impls = empty_internalization_env} empty_alias patt
+ intern_cases_pattern globalenv (None,[]) empty_alias patt
with
InternalizationError (loc,e) ->
user_err_loc (loc,"internalize",explain_internalization_error e)
diff --git a/interp/dumpglob.ml b/interp/dumpglob.ml
index 44a62ef37..931fc1ca4 100644
--- a/interp/dumpglob.ml
+++ b/interp/dumpglob.ml
@@ -141,7 +141,7 @@ let interval loc =
let dump_ref loc filepath modpath ident ty =
match !glob_output with
| Feedback ->
- Pp.feedback (Feedback.GlobRef (loc, filepath, modpath, ident, ty))
+ Feedback.feedback (Feedback.GlobRef (loc, filepath, modpath, ident, ty))
| NoGlob -> ()
| _ when not (Loc.is_ghost loc) ->
let bl,el = interval loc in
@@ -172,7 +172,7 @@ let cook_notation df sc =
(* - all single quotes in terminal tokens are doubled *)
(* - characters < 32 are represented by '^A, '^B, '^C, etc *)
(* The output is decoded in function Index.prepare_entry of coqdoc *)
- let ntn = String.make (String.length df * 3) '_' in
+ let ntn = String.make (String.length df * 5) '_' in
let j = ref 0 in
let l = String.length df - 1 in
let i = ref 0 in
@@ -240,7 +240,7 @@ let dump_binding loc id = ()
let dump_def ty loc secpath id =
if !glob_output = Feedback then
- Pp.feedback (Feedback.GlobDef (loc, id, secpath, ty))
+ Feedback.feedback (Feedback.GlobDef (loc, id, secpath, ty))
else
let bl,el = interval loc in
dump_string (Printf.sprintf "%s %d:%d %s %s\n" ty bl el secpath id)
diff --git a/interp/implicit_quantifiers.ml b/interp/implicit_quantifiers.ml
index 751b03a4a..567150a5d 100644
--- a/interp/implicit_quantifiers.ml
+++ b/interp/implicit_quantifiers.ml
@@ -310,7 +310,7 @@ let implicits_of_glob_constr ?(with_products=true) l =
else
let () = match bk with
| Implicit ->
- msg_warning (strbrk "Ignoring implicit status of product binder " ++
+ Feedback.msg_warning (strbrk "Ignoring implicit status of product binder " ++
pr_name na ++ strbrk " and following binders")
| _ -> ()
in []
diff --git a/interp/notation.ml b/interp/notation.ml
index 04918bf7d..b19fd9e1f 100644
--- a/interp/notation.ml
+++ b/interp/notation.ml
@@ -13,7 +13,6 @@ open Pp
open Bigint
open Names
open Term
-open Nametab
open Libnames
open Globnames
open Constrexpr
@@ -65,11 +64,9 @@ let empty_scope = {
}
let default_scope = "" (* empty name, not available from outside *)
-let type_scope = "type_scope" (* special scope used for interpreting types *)
let init_scope_map () =
- scope_map := String.Map.add default_scope empty_scope !scope_map;
- scope_map := String.Map.add type_scope empty_scope !scope_map
+ scope_map := String.Map.add default_scope empty_scope !scope_map
(**********************************************************************)
(* Operations on scopes *)
@@ -187,7 +184,7 @@ let declare_delimiters scope key =
| None -> scope_map := String.Map.add scope newsc !scope_map
| Some oldkey when String.equal oldkey key -> ()
| Some oldkey ->
- msg_warning
+ Feedback.msg_warning
(str "Overwriting previous delimiting key " ++ str oldkey ++ str " in scope " ++ str scope);
scope_map := String.Map.add scope newsc !scope_map
end;
@@ -195,7 +192,7 @@ let declare_delimiters scope key =
let oldscope = String.Map.find key !delimiters_map in
if String.equal oldscope scope then ()
else begin
- msg_warning (str "Hiding binding of key " ++ str key ++ str " to " ++ str oldscope);
+ Feedback.msg_warning (str "Hiding binding of key " ++ str key ++ str " to " ++ str oldscope);
delimiters_map := String.Map.add key scope !delimiters_map
end
with Not_found -> delimiters_map := String.Map.add key scope !delimiters_map
@@ -204,7 +201,7 @@ let remove_delimiters scope =
let sc = find_scope scope in
let newsc = { sc with delimiters = None } in
match sc.delimiters with
- | None -> msg_warning (str "No bound key for scope " ++ str scope ++ str ".")
+ | None -> Feedback.msg_warning (str "No bound key for scope " ++ str scope ++ str ".")
| Some key ->
scope_map := String.Map.add scope newsc !scope_map;
try
@@ -314,7 +311,9 @@ let declare_prim_token_interpreter sc interp (patl,uninterp,b) =
patl
let mkNumeral n = Numeral n
-let mkString s = String s
+let mkString = function
+| None -> None
+| Some s -> if Unicode.is_utf8 s then Some (String s) else None
let delay dir int loc x = (dir, (fun () -> int loc x))
@@ -326,7 +325,7 @@ let declare_numeral_interpreter sc dir interp (patl,uninterp,inpat) =
let declare_string_interpreter sc dir interp (patl,uninterp,inpat) =
declare_prim_token_interpreter sc
(fun cont loc -> function String s -> delay dir interp loc s | p -> cont loc p)
- (patl, (fun r -> Option.map mkString (uninterp r)), inpat)
+ (patl, (fun r -> mkString (uninterp r)), inpat)
let check_required_module loc sc (sp,d) =
try let _ = Nametab.global_of_path sp in ()
@@ -389,7 +388,7 @@ let declare_notation_interpretation ntn scopt pat df =
let which_scope = match scopt with
| None -> mt ()
| Some _ -> str " in scope " ++ str scope in
- msg_warning (str "Notation " ++ str ntn ++ str " was already used" ++ which_scope)
+ Feedback.msg_warning (str "Notation " ++ str ntn ++ str " was already used" ++ which_scope)
in
let sc = { sc with notations = String.Map.add ntn (pat,df) sc.notations } in
let () = scope_map := String.Map.add scope sc !scope_map in
@@ -557,23 +556,16 @@ let isNVar_or_NHole = function NVar _ | NHole _ -> true | _ -> false
(**********************************************************************)
(* Mapping classes to scopes *)
-type scope_class = ScopeRef of global_reference | ScopeSort
+open Classops
-let scope_class_compare sc1 sc2 = match sc1, sc2 with
-| ScopeRef gr1, ScopeRef gr2 -> RefOrdered.compare gr1 gr2
-| ScopeRef _, ScopeSort -> -1
-| ScopeSort, ScopeRef _ -> 1
-| ScopeSort, ScopeSort -> 0
+type scope_class = cl_typ
-let scope_class_of_reference x = ScopeRef x
+let scope_class_compare : scope_class -> scope_class -> int =
+ cl_typ_ord
let compute_scope_class t =
- let t', _ = decompose_appvect (Reductionops.whd_betaiotazeta Evd.empty t) in
- match kind_of_term t' with
- | Var _ | Const _ | Ind _ -> ScopeRef (global_of_constr t')
- | Proj (p, c) -> ScopeRef (ConstRef (Projection.constant p))
- | Sort _ -> ScopeSort
- | _ -> raise Not_found
+ let (cl,_,_) = find_class_type Evd.empty t in
+ cl
module ScopeClassOrd =
struct
@@ -584,7 +576,7 @@ end
module ScopeClassMap = Map.Make(ScopeClassOrd)
let initial_scope_class_map : scope_name ScopeClassMap.t =
- ScopeClassMap.add ScopeSort "type_scope" ScopeClassMap.empty
+ ScopeClassMap.empty
let scope_class_map = ref initial_scope_class_map
@@ -618,8 +610,11 @@ let compute_arguments_scope t = fst (compute_arguments_scope_full t)
let compute_type_scope t =
find_scope_class_opt (try Some (compute_scope_class t) with Not_found -> None)
-let compute_scope_of_global ref =
- find_scope_class_opt (Some (ScopeRef ref))
+let current_type_scope_name () =
+ find_scope_class_opt (Some CL_SORT)
+
+let scope_class_of_class (x : cl_typ) : scope_class =
+ x
(** Updating a scope list, thanks to a list of argument classes
and the current Bind Scope base. When some current scope
@@ -651,12 +646,8 @@ let load_arguments_scope _ (_,(_,r,scl,cls)) =
let cache_arguments_scope o =
load_arguments_scope 1 o
-let subst_scope_class subst cs = match cs with
- | ScopeSort -> Some cs
- | ScopeRef t ->
- let (t',c) = subst_global subst t in
- if t == t' then Some cs
- else try Some (compute_scope_class c) with Not_found -> None
+let subst_scope_class subst cs =
+ try Some (subst_cl_typ subst cs) with Not_found -> None
let subst_arguments_scope (subst,(req,r,scl,cls)) =
let r' = fst (subst_global subst r) in
@@ -789,9 +780,7 @@ let pr_delimiters_info = function
let classes_of_scope sc =
ScopeClassMap.fold (fun cl sc' l -> if String.equal sc sc' then cl::l else l) !scope_class_map []
-let pr_scope_class = function
- | ScopeSort -> str "Sort"
- | ScopeRef t -> pr_global_env Id.Set.empty t
+let pr_scope_class = pr_class
let pr_scope_classes sc =
let l = classes_of_scope sc in
diff --git a/interp/notation.mli b/interp/notation.mli
index 7885814c7..480979ccc 100644
--- a/interp/notation.mli
+++ b/interp/notation.mli
@@ -29,7 +29,6 @@ type scopes (** = [scope_name list] *)
type local_scopes = tmp_scope_name option * scope_name list
-val type_scope : scope_name
val declare_scope : scope_name -> unit
val current_scopes : unit -> scopes
@@ -153,7 +152,9 @@ val find_arguments_scope : global_reference -> scope_name option list
type scope_class
-val scope_class_of_reference : global_reference -> scope_class
+(** Comparison of scope_class *)
+val scope_class_compare : scope_class -> scope_class -> int
+
val subst_scope_class :
Mod_subst.substitution -> scope_class -> scope_class option
@@ -162,7 +163,11 @@ val declare_ref_arguments_scope : global_reference -> unit
val compute_arguments_scope : Term.types -> scope_name option list
val compute_type_scope : Term.types -> scope_name option
-val compute_scope_of_global : global_reference -> scope_name option
+
+(** Get the current scope bound to Sortclass, if it exists *)
+val current_type_scope_name : unit -> scope_name option
+
+val scope_class_of_class : Classops.cl_typ -> scope_class
(** Building notation key *)
diff --git a/interp/notation_ops.ml b/interp/notation_ops.ml
index 6561000c4..b4cf6e943 100644
--- a/interp/notation_ops.ml
+++ b/interp/notation_ops.ml
@@ -12,15 +12,103 @@ open Util
open Names
open Nameops
open Globnames
+open Decl_kinds
open Misctypes
open Glob_term
open Glob_ops
open Mod_subst
open Notation_term
-open Decl_kinds
(**********************************************************************)
-(* Re-interpret a notation as a glob_constr, taking care of binders *)
+(* Utilities *)
+
+let on_true_do b f c = if b then (f c; b) else b
+
+let compare_glob_constr f add t1 t2 = match t1,t2 with
+ | GRef (_,r1,_), GRef (_,r2,_) -> eq_gr r1 r2
+ | GVar (_,v1), GVar (_,v2) -> on_true_do (Id.equal v1 v2) add (Name v1)
+ | GApp (_,f1,l1), GApp (_,f2,l2) -> f f1 f2 && List.for_all2eq f l1 l2
+ | GLambda (_,na1,bk1,ty1,c1), GLambda (_,na2,bk2,ty2,c2)
+ when Name.equal na1 na2 && Constrexpr_ops.binding_kind_eq bk1 bk2 ->
+ on_true_do (f ty1 ty2 && f c1 c2) add na1
+ | GProd (_,na1,bk1,ty1,c1), GProd (_,na2,bk2,ty2,c2)
+ when Name.equal na1 na2 && Constrexpr_ops.binding_kind_eq bk1 bk2 ->
+ on_true_do (f ty1 ty2 && f c1 c2) add na1
+ | GHole _, GHole _ -> true
+ | GSort (_,s1), GSort (_,s2) -> Miscops.glob_sort_eq s1 s2
+ | GLetIn (_,na1,b1,c1), GLetIn (_,na2,b2,c2) when Name.equal na1 na2 ->
+ on_true_do (f b1 b2 && f c1 c2) add na1
+ | (GCases _ | GRec _
+ | GPatVar _ | GEvar _ | GLetTuple _ | GIf _ | GCast _),_
+ | _,(GCases _ | GRec _
+ | GPatVar _ | GEvar _ | GLetTuple _ | GIf _ | GCast _)
+ -> error "Unsupported construction in recursive notations."
+ | (GRef _ | GVar _ | GApp _ | GLambda _ | GProd _
+ | GHole _ | GSort _ | GLetIn _), _
+ -> false
+
+let rec eq_notation_constr t1 t2 = match t1, t2 with
+| NRef gr1, NRef gr2 -> eq_gr gr1 gr2
+| NVar id1, NVar id2 -> Id.equal id1 id2
+| NApp (t1, a1), NApp (t2, a2) ->
+ eq_notation_constr t1 t2 && List.equal eq_notation_constr a1 a2
+| NHole (_, _, _), NHole (_, _, _) -> true (** FIXME? *)
+| NList (i1, j1, t1, u1, b1), NList (i2, j2, t2, u2, b2) ->
+ Id.equal i1 i2 && Id.equal j1 j2 && eq_notation_constr t1 t2 &&
+ eq_notation_constr u1 u2 && b1 == b2
+| NLambda (na1, t1, u1), NLambda (na2, t2, u2) ->
+ Name.equal na1 na2 && eq_notation_constr t1 t2 && eq_notation_constr u1 u2
+| NProd (na1, t1, u1), NProd (na2, t2, u2) ->
+ Name.equal na1 na2 && eq_notation_constr t1 t2 && eq_notation_constr u1 u2
+| NBinderList (i1, j1, t1, u1), NBinderList (i2, j2, t2, u2) ->
+ Id.equal i1 i2 && Id.equal j1 j2 && eq_notation_constr t1 t2 &&
+ eq_notation_constr u1 u2
+| NLetIn (na1, t1, u1), NLetIn (na2, t2, u2) ->
+ Name.equal na1 na2 && eq_notation_constr t1 t2 && eq_notation_constr u1 u2
+| NCases (_, o1, r1, p1), NCases (_, o2, r2, p2) -> (** FIXME? *)
+ let eqpat (p1, t1) (p2, t2) =
+ List.equal cases_pattern_eq p1 p2 &&
+ eq_notation_constr t1 t2
+ in
+ let eqf (t1, (na1, o1)) (t2, (na2, o2)) =
+ let eq (i1, n1) (i2, n2) = eq_ind i1 i2 && List.equal Name.equal n1 n2 in
+ eq_notation_constr t1 t2 && Name.equal na1 na2 && Option.equal eq o1 o2
+ in
+ Option.equal eq_notation_constr o1 o2 &&
+ List.equal eqf r1 r2 &&
+ List.equal eqpat p1 p2
+| NLetTuple (nas1, (na1, o1), t1, u1), NLetTuple (nas2, (na2, o2), t2, u2) ->
+ List.equal Name.equal nas1 nas2 &&
+ Name.equal na1 na2 &&
+ Option.equal eq_notation_constr o1 o2 &&
+ eq_notation_constr t1 t2 &&
+ eq_notation_constr u1 u2
+| NIf (t1, (na1, o1), u1, r1), NIf (t2, (na2, o2), u2, r2) ->
+ eq_notation_constr t1 t2 &&
+ Name.equal na1 na2 &&
+ Option.equal eq_notation_constr o1 o2 &&
+ eq_notation_constr u1 u2 &&
+ eq_notation_constr r1 r2
+| NRec (_, ids1, ts1, us1, rs1), NRec (_, ids2, ts2, us2, rs2) -> (** FIXME? *)
+ let eq (na1, o1, t1) (na2, o2, t2) =
+ Name.equal na1 na2 &&
+ Option.equal eq_notation_constr o1 o2 &&
+ eq_notation_constr t1 t2
+ in
+ Array.equal Id.equal ids1 ids2 &&
+ Array.equal (List.equal eq) ts1 ts2 &&
+ Array.equal eq_notation_constr us1 us2 &&
+ Array.equal eq_notation_constr rs1 rs2
+| NSort s1, NSort s2 ->
+ Miscops.glob_sort_eq s1 s2
+| NCast (t1, c1), NCast (t2, c2) ->
+ eq_notation_constr t1 t2 && cast_type_eq eq_notation_constr c1 c2
+| (NRef _ | NVar _ | NApp _ | NHole _ | NList _ | NLambda _ | NProd _
+ | NBinderList _ | NLetIn _ | NCases _ | NLetTuple _ | NIf _
+ | NRec _ | NSort _ | NCast _), _ -> false
+
+(**********************************************************************)
+(* Re-interpret a notation as a glob_constr, taking care of binders *)
let name_to_ident = function
| Anonymous -> Errors.error "This expression should be a simple identifier."
@@ -105,7 +193,6 @@ let glob_constr_of_notation_constr_with_binders loc g f e = function
| NCast (c,k) -> GCast (loc,f e c,Miscops.map_cast_type (f e) k)
| NSort x -> GSort (loc,x)
| NHole (x, naming, arg) -> GHole (loc, x, naming, arg)
- | NPatVar n -> GPatVar (loc,(false,n))
| NRef x -> GRef (loc,x,None)
let glob_constr_of_notation_constr loc x =
@@ -113,7 +200,7 @@ let glob_constr_of_notation_constr loc x =
glob_constr_of_notation_constr_with_binders loc (fun () id -> ((),id)) aux () x
in aux () x
-(****************************************************************************)
+(******************************************************************************)
(* Translating a glob_constr into a notation, interpreting recursive patterns *)
let add_id r id = r := (id :: pi1 !r, pi2 !r, pi3 !r)
@@ -143,96 +230,6 @@ let split_at_recursive_part c =
| GVar (_,v) when Id.equal v ldots_var -> (* Not enough context *) raise Not_found
| _ -> outer_iterator, c
-let on_true_do b f c = if b then (f c; b) else b
-
-let compare_glob_constr f add t1 t2 = match t1,t2 with
- | GRef (_,r1,_), GRef (_,r2,_) -> eq_gr r1 r2
- | GVar (_,v1), GVar (_,v2) -> on_true_do (Id.equal v1 v2) add (Name v1)
- | GApp (_,f1,l1), GApp (_,f2,l2) -> f f1 f2 && List.for_all2eq f l1 l2
- | GLambda (_,na1,bk1,ty1,c1), GLambda (_,na2,bk2,ty2,c2)
- when Name.equal na1 na2 && Constrexpr_ops.binding_kind_eq bk1 bk2 ->
- on_true_do (f ty1 ty2 && f c1 c2) add na1
- | GProd (_,na1,bk1,ty1,c1), GProd (_,na2,bk2,ty2,c2)
- when Name.equal na1 na2 && Constrexpr_ops.binding_kind_eq bk1 bk2 ->
- on_true_do (f ty1 ty2 && f c1 c2) add na1
- | GHole _, GHole _ -> true
- | GSort (_,s1), GSort (_,s2) -> Miscops.glob_sort_eq s1 s2
- | GLetIn (_,na1,b1,c1), GLetIn (_,na2,b2,c2) when Name.equal na1 na2 ->
- on_true_do (f b1 b2 && f c1 c2) add na1
- | (GCases _ | GRec _
- | GPatVar _ | GEvar _ | GLetTuple _ | GIf _ | GCast _),_
- | _,(GCases _ | GRec _
- | GPatVar _ | GEvar _ | GLetTuple _ | GIf _ | GCast _)
- -> error "Unsupported construction in recursive notations."
- | (GRef _ | GVar _ | GApp _ | GLambda _ | GProd _
- | GHole _ | GSort _ | GLetIn _), _
- -> false
-
-let rec eq_glob_constr t1 t2 = compare_glob_constr eq_glob_constr (fun _ -> ()) t1 t2
-
-let rec eq_notation_constr t1 t2 = match t1, t2 with
-| NRef gr1, NRef gr2 -> eq_gr gr1 gr2
-| NVar id1, NVar id2 -> Id.equal id1 id2
-| NApp (t1, a1), NApp (t2, a2) ->
- eq_notation_constr t1 t2 && List.equal eq_notation_constr a1 a2
-| NHole (_, _, _), NHole (_, _, _) -> true (** FIXME? *)
-| NList (i1, j1, t1, u1, b1), NList (i2, j2, t2, u2, b2) ->
- Id.equal i1 i2 && Id.equal j1 j2 && eq_notation_constr t1 t2 &&
- eq_notation_constr u1 u2 && b1 == b2
-| NLambda (na1, t1, u1), NLambda (na2, t2, u2) ->
- Name.equal na1 na2 && eq_notation_constr t1 t2 && eq_notation_constr u1 u2
-| NProd (na1, t1, u1), NProd (na2, t2, u2) ->
- Name.equal na1 na2 && eq_notation_constr t1 t2 && eq_notation_constr u1 u2
-| NBinderList (i1, j1, t1, u1), NBinderList (i2, j2, t2, u2) ->
- Id.equal i1 i2 && Id.equal j1 j2 && eq_notation_constr t1 t2 &&
- eq_notation_constr u1 u2
-| NLetIn (na1, t1, u1), NLetIn (na2, t2, u2) ->
- Name.equal na1 na2 && eq_notation_constr t1 t2 && eq_notation_constr u1 u2
-| NCases (_, o1, r1, p1), NCases (_, o2, r2, p2) -> (** FIXME? *)
- let eqpat (p1, t1) (p2, t2) =
- List.equal cases_pattern_eq p1 p2 &&
- eq_notation_constr t1 t2
- in
- let eqf (t1, (na1, o1)) (t2, (na2, o2)) =
- let eq (i1, n1) (i2, n2) = eq_ind i1 i2 && List.equal Name.equal n1 n2 in
- eq_notation_constr t1 t2 && Name.equal na1 na2 && Option.equal eq o1 o2
- in
- Option.equal eq_notation_constr o1 o2 &&
- List.equal eqf r1 r2 &&
- List.equal eqpat p1 p2
-| NLetTuple (nas1, (na1, o1), t1, u1), NLetTuple (nas2, (na2, o2), t2, u2) ->
- List.equal Name.equal nas1 nas2 &&
- Name.equal na1 na2 &&
- Option.equal eq_notation_constr o1 o2 &&
- eq_notation_constr t1 t2 &&
- eq_notation_constr u1 u2
-| NIf (t1, (na1, o1), u1, r1), NIf (t2, (na2, o2), u2, r2) ->
- eq_notation_constr t1 t2 &&
- Name.equal na1 na2 &&
- Option.equal eq_notation_constr o1 o2 &&
- eq_notation_constr u1 u2 &&
- eq_notation_constr r1 r2
-| NRec (_, ids1, ts1, us1, rs1), NRec (_, ids2, ts2, us2, rs2) -> (** FIXME? *)
- let eq (na1, o1, t1) (na2, o2, t2) =
- Name.equal na1 na2 &&
- Option.equal eq_notation_constr o1 o2 &&
- eq_notation_constr t1 t2
- in
- Array.equal Id.equal ids1 ids2 &&
- Array.equal (List.equal eq) ts1 ts2 &&
- Array.equal eq_notation_constr us1 us2 &&
- Array.equal eq_notation_constr rs1 rs2
-| NSort s1, NSort s2 ->
- Miscops.glob_sort_eq s1 s2
-| NPatVar p1, NPatVar p2 ->
- Id.equal p1 p2
-| NCast (t1, c1), NCast (t2, c2) ->
- eq_notation_constr t1 t2 && cast_type_eq eq_notation_constr c1 c2
-| (NRef _ | NVar _ | NApp _ | NHole _ | NList _ | NLambda _ | NProd _
- | NBinderList _ | NLetIn _ | NCases _ | NLetTuple _ | NIf _
- | NRec _ | NSort _ | NPatVar _ | NCast _), _ -> false
-
-
let subtract_loc loc1 loc2 = Loc.make_loc (fst (Loc.unloc loc1),fst (Loc.unloc loc2)-1)
let check_is_hole id = function GHole _ -> () | t ->
@@ -352,8 +349,7 @@ let notation_constr_and_vars_of_glob_constr a =
| GSort (_,s) -> NSort s
| GHole (_,w,naming,arg) -> NHole (w, naming, arg)
| GRef (_,r,_) -> NRef r
- | GPatVar (_,(_,n)) -> NPatVar n
- | GEvar _ ->
+ | GEvar _ | GPatVar _ ->
error "Existential variables not allowed in notations."
in
@@ -413,6 +409,7 @@ let notation_constr_of_glob_constr nenv a =
let () = check_variables nenv found in
a
+(**********************************************************************)
(* Substitution of kernel names, avoiding a list of bound identifiers *)
let notation_constr_of_constr avoiding t =
@@ -526,7 +523,7 @@ let rec subst_notation_constr subst bound raw =
if dll' == dll && tl' == tl && bl' == bl then raw else
NRec (fk,idl,dll',tl',bl')
- | NPatVar _ | NSort _ -> raw
+ | NSort _ -> raw
| NHole (knd, naming, solve) ->
let nknd = match knd with
@@ -548,7 +545,8 @@ let subst_interpretation subst (metas,pat) =
let bound = List.map fst metas in
(metas,subst_notation_constr subst bound pat)
-(* Pattern-matching glob_constr and notation_constr *)
+(**********************************************************************)
+(* Pattern-matching a [glob_constr] against a [notation_constr] *)
let abstract_return_type_context pi mklam tml rtno =
Option.map (fun rtn ->
@@ -782,7 +780,6 @@ let rec match_ inner u alp metas sigma a1 a2 =
(* Matching compositionally *)
| GVar (_,id1), NVar id2 when alpha_var id1 id2 (fst alp) -> sigma
| GRef (_,r1,_), NRef r2 when (eq_gr r1 r2) -> sigma
- | GPatVar (_,(_,n1)), NPatVar n2 when Id.equal n1 n2 -> sigma
| GApp (loc,f1,l1), NApp (f2,l2) ->
let n1 = List.length l1 and n2 = List.length l2 in
let f1,l1,f2,l2 =
@@ -854,15 +851,21 @@ let rec match_ inner u alp metas sigma a1 a2 =
otherwise how to ensure it corresponds to a well-typed eta-expansion;
we make an exception for types which are metavariables: this is useful e.g.
to print "{x:_ & P x}" knowing that notation "{x & P x}" is not defined. *)
- | b1, NLambda (Name id,(NHole _ | NVar _ as t2),b2) when inner ->
- let id' = Namegen.next_ident_away id (free_glob_vars b1) in
+ | b1, NLambda (Name id as na,(NHole _ | NVar _ as t2),b2) when inner ->
+ let avoid =
+ free_glob_vars b1 @ (* as in Namegen: *) glob_visible_short_qualid b1 in
+ let id' = Namegen.next_ident_away id avoid in
let t1 = GHole(Loc.ghost,Evar_kinds.BinderType (Name id'),Misctypes.IntroAnonymous,None) in
let sigma = match t2 with
| NHole _ -> sigma
| NVar id2 -> bind_term_env alp sigma id2 t1
| _ -> assert false in
- match_in u alp metas (add_bindinglist_env sigma id [(Name id',Explicit,None,t1)])
- (mkGApp Loc.ghost b1 (GVar (Loc.ghost,id'))) b2
+ let (alp,sigma) =
+ if is_bindinglist_meta id metas then
+ alp, add_bindinglist_env sigma id [(Name id',Explicit,None,t1)]
+ else
+ match_names metas (alp,sigma) (Name id') na in
+ match_in u alp metas sigma (mkGApp Loc.ghost b1 (GVar (Loc.ghost,id'))) b2
| (GRec _ | GEvar _), _
| _,_ -> raise No_match
diff --git a/interp/notation_ops.mli b/interp/notation_ops.mli
index 280ccfd21..576c5b943 100644
--- a/interp/notation_ops.mli
+++ b/interp/notation_ops.mli
@@ -10,24 +10,28 @@ open Names
open Notation_term
open Glob_term
-(** Utilities about [notation_constr] *)
+(** {5 Utilities about [notation_constr]} *)
-(** Translate a [glob_constr] into a notation given the list of variables
- bound by the notation; also interpret recursive patterns *)
+val eq_notation_constr : notation_constr -> notation_constr -> bool
-val notation_constr_of_glob_constr : notation_interp_env ->
- glob_constr -> notation_constr
+(** Substitution of kernel names in interpretation data *)
+val subst_interpretation :
+ Mod_subst.substitution -> interpretation -> interpretation
+
(** Name of the special identifier used to encode recursive notations *)
+
val ldots_var : Id.t
-(** Equality of [glob_constr] (warning: only partially implemented) *)
-(** FIXME: nothing to do here *)
-val eq_glob_constr : glob_constr -> glob_constr -> bool
+(** {5 Translation back and forth between [glob_constr] and [notation_constr] *)
-val eq_notation_constr : notation_constr -> notation_constr -> bool
+(** Translate a [glob_constr] into a notation given the list of variables
+ bound by the notation; also interpret recursive patterns *)
+
+val notation_constr_of_glob_constr : notation_interp_env ->
+ glob_constr -> notation_constr
-(** Re-interpret a notation as a [glob_constr], taking care of binders *)
+(** Re-interpret a notation as a [glob_constr], taking care of binders *)
val glob_constr_of_notation_constr_with_binders : Loc.t ->
('a -> Name.t -> 'a * Name.t) ->
@@ -36,6 +40,8 @@ val glob_constr_of_notation_constr_with_binders : Loc.t ->
val glob_constr_of_notation_constr : Loc.t -> notation_constr -> glob_constr
+(** {5 Matching a notation pattern against a [glob_constr] *)
+
(** [match_notation_constr] matches a [glob_constr] against a notation
interpretation; raise [No_match] if the matching fails *)
@@ -55,9 +61,5 @@ val match_notation_constr_ind_pattern :
((cases_pattern * subscopes) list * (cases_pattern list * subscopes) list) *
(int * cases_pattern list)
-(** Substitution of kernel names in interpretation data *)
-
-val subst_interpretation :
- Mod_subst.substitution -> interpretation -> interpretation
+(** {5 Matching a notation pattern against a [glob_constr] *)
-val add_patterns_for_params : inductive -> cases_pattern list -> cases_pattern list
diff --git a/interp/stdarg.ml b/interp/stdarg.ml
index 9c3ed9413..2a7d52e3a 100644
--- a/interp/stdarg.ml
+++ b/interp/stdarg.ml
@@ -7,24 +7,29 @@
(************************************************************************)
open Genarg
+open Geninterp
+
+let make0 ?dyn name =
+ let wit = Genarg.make0 name in
+ let () = register_val0 wit dyn in
+ wit
let wit_unit : unit uniform_genarg_type =
- make0 None "unit"
+ make0 "unit"
let wit_bool : bool uniform_genarg_type =
- make0 None "bool"
+ make0 "bool"
let wit_int : int uniform_genarg_type =
- make0 None "int"
+ make0 "int"
let wit_string : string uniform_genarg_type =
- make0 None "string"
+ make0 "string"
let wit_pre_ident : string uniform_genarg_type =
- make0 None "preident"
+ make0 ~dyn:(val_tag (topwit wit_string)) "preident"
+
+(** Aliases for compatibility *)
-let () = register_name0 wit_unit "Stdarg.wit_unit"
-let () = register_name0 wit_bool "Stdarg.wit_bool"
-let () = register_name0 wit_int "Stdarg.wit_int"
-let () = register_name0 wit_string "Stdarg.wit_string"
-let () = register_name0 wit_pre_ident "Stdarg.wit_pre_ident"
+let wit_integer = wit_int
+let wit_preident = wit_pre_ident
diff --git a/interp/stdarg.mli b/interp/stdarg.mli
index d8904dab8..e1f648d7f 100644
--- a/interp/stdarg.mli
+++ b/interp/stdarg.mli
@@ -19,3 +19,8 @@ val wit_int : int uniform_genarg_type
val wit_string : string uniform_genarg_type
val wit_pre_ident : string uniform_genarg_type
+
+(** Aliases for compatibility *)
+
+val wit_integer : int uniform_genarg_type
+val wit_preident : string uniform_genarg_type
diff --git a/interp/syntax_def.ml b/interp/syntax_def.ml
index db548ec32..891b64fa1 100644
--- a/interp/syntax_def.ml
+++ b/interp/syntax_def.ml
@@ -93,7 +93,7 @@ let is_verbose_compat () =
let verbose_compat kn def = function
| Some v when is_verbose_compat () && Flags.version_strictly_greater v ->
let act =
- if !verbose_compat_notations then msg_warning else errorlabstrm ""
+ if !verbose_compat_notations then Feedback.msg_warning else errorlabstrm ""
in
let pp_def = match def with
| [], NRef r -> str " is " ++ pr_global_env Id.Set.empty r
diff --git a/interp/topconstr.ml b/interp/topconstr.ml
index 8293f7f88..91099bbb1 100644
--- a/interp/topconstr.ml
+++ b/interp/topconstr.ml
@@ -19,14 +19,14 @@ open Constrexpr_ops
(*i*)
-let oldfashion_patterns = ref (false)
+let asymmetric_patterns = ref (false)
let _ = Goptions.declare_bool_option {
Goptions.optsync = true; Goptions.optdepr = false;
Goptions.optname =
"Constructors in patterns require all their arguments but no parameters instead of explicit parameters and arguments";
Goptions.optkey = ["Asymmetric";"Patterns"];
- Goptions.optread = (fun () -> !oldfashion_patterns);
- Goptions.optwrite = (fun a -> oldfashion_patterns:=a);
+ Goptions.optread = (fun () -> !asymmetric_patterns);
+ Goptions.optwrite = (fun a -> asymmetric_patterns:=a);
}
(**********************************************************************)
@@ -52,7 +52,7 @@ let rec cases_pattern_fold_names f a = function
List.fold_left (cases_pattern_fold_names f) a patl
| CPatCstr (_,_,patl1,patl2) ->
List.fold_left (cases_pattern_fold_names f)
- (List.fold_left (cases_pattern_fold_names f) a patl1) patl2
+ (Option.fold_left (List.fold_left (cases_pattern_fold_names f)) a patl1) patl2
| CPatNotation (_,_,(patl,patll),patl') ->
List.fold_left (cases_pattern_fold_names f)
(List.fold_left (cases_pattern_fold_names f) a (patl@List.flatten patll)) patl'
@@ -67,7 +67,7 @@ let ids_of_pattern_list =
Id.Set.empty
let ids_of_cases_indtype p =
- Id.Set.elements (cases_pattern_fold_names Id.Set.add Id.Set.empty p)
+ cases_pattern_fold_names Id.Set.add Id.Set.empty p
let ids_of_cases_tomatch tms =
List.fold_right
@@ -132,7 +132,7 @@ let fold_constr_expr_with_binders g f n acc = function
fold_local_binders g f n'
(fold_local_binders g f n acc t lb) c lb) l acc
| CCoFix (loc,_,_) ->
- msg_warning (strbrk "Capture check in multiple binders not done"); acc
+ Feedback.msg_warning (strbrk "Capture check in multiple binders not done"); acc
let free_vars_of_constr_expr c =
let rec aux bdvars l = function
diff --git a/interp/topconstr.mli b/interp/topconstr.mli
index 1e867c19c..58edd4ddf 100644
--- a/interp/topconstr.mli
+++ b/interp/topconstr.mli
@@ -12,7 +12,7 @@ open Constrexpr
(** Topconstr *)
-val oldfashion_patterns : bool ref
+val asymmetric_patterns : bool ref
(** Utilities on constr_expr *)
@@ -23,7 +23,7 @@ val free_vars_of_constr_expr : constr_expr -> Id.Set.t
val occur_var_constr_expr : Id.t -> constr_expr -> bool
(** Specific function for interning "in indtype" syntax of "match" *)
-val ids_of_cases_indtype : cases_pattern_expr -> Id.t list
+val ids_of_cases_indtype : cases_pattern_expr -> Id.Set.t
val split_at_annot : local_binder list -> Id.t located option -> local_binder list * local_binder list
diff --git a/intf/constrexpr.mli b/intf/constrexpr.mli
index 40812a3d8..efd5129b6 100644
--- a/intf/constrexpr.mli
+++ b/intf/constrexpr.mli
@@ -40,15 +40,15 @@ type raw_cases_pattern_expr =
| RCPatAlias of Loc.t * raw_cases_pattern_expr * Id.t
| RCPatCstr of Loc.t * Globnames.global_reference
* raw_cases_pattern_expr list * raw_cases_pattern_expr list
- (** [CPatCstr (_, Inl c, l1, l2)] represents (@c l1) l2 *)
+ (** [CPatCstr (_, c, l1, l2)] represents ((@c l1) l2) *)
| RCPatAtom of Loc.t * Id.t option
| RCPatOr of Loc.t * raw_cases_pattern_expr list
type cases_pattern_expr =
| CPatAlias of Loc.t * cases_pattern_expr * Id.t
| CPatCstr of Loc.t * reference
- * cases_pattern_expr list * cases_pattern_expr list
- (** [CPatCstr (_, Inl c, l1, l2)] represents (@c l1) l2 *)
+ * cases_pattern_expr list option * cases_pattern_expr list
+ (** [CPatCstr (_, c, Some l1, l2)] represents (@c l1) l2 *)
| CPatAtom of Loc.t * reference option
| CPatOr of Loc.t * cases_pattern_expr list
| CPatNotation of Loc.t * notation * cases_pattern_notation_substitution
diff --git a/intf/extend.mli b/intf/extend.mli
index 57abdc38f..7ba332f70 100644
--- a/intf/extend.mli
+++ b/intf/extend.mli
@@ -8,6 +8,8 @@
(** Entry keys for constr notations *)
+type 'a entry = 'a Compat.GrammarMake(CLexer).entry
+
type side = Left | Right
type gram_assoc = NonA | RightA | LeftA
@@ -53,35 +55,39 @@ type simple_constr_prod_entry_key =
(** {5 AST for user-provided entries} *)
-type user_symbol =
-| Ulist1 : user_symbol -> user_symbol
-| Ulist1sep : user_symbol * string -> user_symbol
-| Ulist0 : user_symbol -> user_symbol
-| Ulist0sep : user_symbol * string -> user_symbol
-| Uopt : user_symbol -> user_symbol
-| Umodifiers : user_symbol -> user_symbol
-| Uentry : string -> user_symbol
-| Uentryl : string * int -> user_symbol
+type 'a user_symbol =
+| Ulist1 of 'a user_symbol
+| Ulist1sep of 'a user_symbol * string
+| Ulist0 of 'a user_symbol
+| Ulist0sep of 'a user_symbol * string
+| Uopt of 'a user_symbol
+| Uentry of 'a
+| Uentryl of 'a * int
(** {5 Type-safe grammar extension} *)
type ('self, 'a) symbol =
| Atoken : Tok.t -> ('self, string) symbol
| Alist1 : ('self, 'a) symbol -> ('self, 'a list) symbol
-| Alist1sep : ('self, 'a) symbol * string -> ('self, 'a list) symbol
+| Alist1sep : ('self, 'a) symbol * ('self, _) symbol -> ('self, 'a list) symbol
| Alist0 : ('self, 'a) symbol -> ('self, 'a list) symbol
-| Alist0sep : ('self, 'a) symbol * string -> ('self, 'a list) symbol
+| Alist0sep : ('self, 'a) symbol * ('self, _) symbol -> ('self, 'a list) symbol
| Aopt : ('self, 'a) symbol -> ('self, 'a option) symbol
-| Amodifiers : ('self, 'a) symbol -> ('self, 'a list) symbol
| Aself : ('self, 'self) symbol
| Anext : ('self, 'self) symbol
-| Aentry : 'a Entry.t -> ('self, 'a) symbol
-| Aentryl : 'a Entry.t * int -> ('self, 'a) symbol
+| Aentry : 'a entry -> ('self, 'a) symbol
+| Aentryl : 'a entry * int -> ('self, 'a) symbol
+| Arules : 'a rules list -> ('self, 'a) symbol
-type ('self, _, 'r) rule =
+and ('self, _, 'r) rule =
| Stop : ('self, 'r, 'r) rule
| Next : ('self, 'a, 'r) rule * ('self, 'b) symbol -> ('self, 'b -> 'a, 'r) rule
+and ('a, 'r) norec_rule = { norec_rule : 's. ('s, 'a, 'r) rule }
+
+and 'a rules =
+| Rules : ('act, Loc.t -> 'a) norec_rule * 'act -> 'a rules
+
type 'a production_rule =
| Rule : ('a, 'act, Loc.t -> 'a) rule * 'act -> 'a production_rule
diff --git a/intf/notation_term.mli b/intf/notation_term.mli
index 39a36310d..7c5d7657b 100644
--- a/intf/notation_term.mli
+++ b/intf/notation_term.mli
@@ -42,7 +42,6 @@ type notation_constr =
(Name.t * notation_constr option * notation_constr) list array *
notation_constr array * notation_constr array
| NSort of glob_sort
- | NPatVar of patvar
| NCast of notation_constr * notation_constr cast_type
(** Note concerning NList: first constr is iterator, second is terminator;
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index 7366bc03e..379dd59d3 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -120,9 +120,9 @@ type open_constr_expr = unit * constr_expr
type open_glob_constr = unit * glob_constr_and_expr
type binding_bound_vars = Id.Set.t
-type glob_constr_pattern_and_expr = glob_constr_and_expr * constr_pattern
+type glob_constr_pattern_and_expr = binding_bound_vars * glob_constr_and_expr * constr_pattern
-type 'a delayed_open =
+type 'a delayed_open = 'a Pretyping.delayed_open =
{ delayed : 'r. Environ.env -> 'r Sigma.t -> ('a, 'r) Sigma.sigma }
type delayed_open_constr_with_bindings = Term.constr with_bindings delayed_open
@@ -139,8 +139,6 @@ type intro_pattern_naming = intro_pattern_naming_expr located
type 'a gen_atomic_tactic_expr =
(* Basic tactics *)
| TacIntroPattern of 'dtrm intro_pattern_expr located list
- | TacIntroMove of Id.t option * 'nam move_location
- | TacExact of 'trm
| TacApply of advanced_flag * evars_flag * 'trm with_bindings_arg list *
('nam * 'dtrm intro_pattern_expr located option) option
| TacElim of evars_flag * 'trm with_bindings_arg * 'trm with_bindings option
@@ -157,10 +155,6 @@ type 'a gen_atomic_tactic_expr =
(* Derived basic tactics *)
| TacInductionDestruct of
rec_flag * evars_flag * ('trm,'dtrm,'nam) induction_clause_list
- | TacDoubleInduction of quantified_hypothesis * quantified_hypothesis
-
- (* Context management *)
- | TacRename of ('nam *'nam) list
(* Conversion *)
| TacReduce of ('trm,'cst,'pat) red_expr_gen * 'nam clause_expr
@@ -180,7 +174,6 @@ type 'a gen_atomic_tactic_expr =
constraint 'a = <
term:'trm;
- utrm: 'utrm;
dterm: 'dtrm;
pattern:'pat;
constant:'cst;
@@ -192,10 +185,9 @@ constraint 'a = <
(** Possible arguments of a tactic definition *)
-and 'a gen_tactic_arg =
+type 'a gen_tactic_arg =
| TacGeneric of 'lev generic_argument
| ConstrMayEval of ('trm,'cst,'pat) may_eval
- | UConstr of 'utrm
| Reference of 'ref
| TacCall of Loc.t * 'ref *
'a gen_tactic_arg list
@@ -206,7 +198,6 @@ and 'a gen_tactic_arg =
constraint 'a = <
term:'trm;
- utrm: 'utrm;
dterm: 'dtrm;
pattern:'pat;
constant:'cst;
@@ -285,7 +276,6 @@ and 'a gen_tactic_expr =
constraint 'a = <
term:'t;
- utrm: 'utrm;
dterm: 'dtrm;
pattern:'p;
constant:'c;
@@ -300,7 +290,6 @@ and 'a gen_tactic_fun_ast =
constraint 'a = <
term:'t;
- utrm: 'utrm;
dterm: 'dtrm;
pattern:'p;
constant:'c;
@@ -313,7 +302,6 @@ constraint 'a = <
(** Globalized tactics *)
type g_trm = glob_constr_and_expr
-type g_utrm = g_trm
type g_pat = glob_constr_pattern_and_expr
type g_cst = evaluable_global_reference and_short_name or_var
type g_ref = ltac_constant located or_var
@@ -321,7 +309,6 @@ type g_nam = Id.t located
type g_dispatch = <
term:g_trm;
- utrm:g_utrm;
dterm:g_trm;
pattern:g_pat;
constant:g_cst;
@@ -343,7 +330,6 @@ type glob_tactic_arg =
(** Raw tactics *)
type r_trm = constr_expr
-type r_utrm = r_trm
type r_pat = constr_pattern_expr
type r_cst = reference or_by_notation
type r_ref = reference
@@ -352,7 +338,6 @@ type r_lev = rlevel
type r_dispatch = <
term:r_trm;
- utrm:r_utrm;
dterm:r_trm;
pattern:r_pat;
constant:r_cst;
@@ -374,7 +359,6 @@ type raw_tactic_arg =
(** Interpreted tactics *)
type t_trm = Term.constr
-type t_utrm = Glob_term.closed_glob_constr
type t_pat = constr_pattern
type t_cst = evaluable_global_reference
type t_ref = ltac_constant located
@@ -382,26 +366,31 @@ type t_nam = Id.t
type t_dispatch = <
term:t_trm;
- utrm:t_utrm;
dterm:g_trm;
pattern:t_pat;
constant:t_cst;
reference:t_ref;
name:t_nam;
- tacexpr:glob_tactic_expr;
+ tacexpr:unit;
level:tlevel
>
-type tactic_expr =
- t_dispatch gen_tactic_expr
-
type atomic_tactic_expr =
t_dispatch gen_atomic_tactic_expr
-type tactic_arg =
- t_dispatch gen_tactic_arg
-
(** Misc *)
type raw_red_expr = (r_trm, r_cst, r_pat) red_expr_gen
type glob_red_expr = (g_trm, g_cst, g_pat) red_expr_gen
+
+(** Traces *)
+
+type ltac_call_kind =
+ | LtacMLCall of glob_tactic_expr
+ | LtacNotationCall of KerName.t
+ | LtacNameCall of ltac_constant
+ | LtacAtomCall of glob_atomic_tactic_expr
+ | LtacVarCall of Id.t * glob_tactic_expr
+ | LtacConstrInterp of Glob_term.glob_constr * Pretyping.ltac_var_map
+
+type ltac_trace = (Loc.t * ltac_call_kind) list
diff --git a/intf/vernacexpr.mli b/intf/vernacexpr.mli
index 7273b92b9..6ce15a7c5 100644
--- a/intf/vernacexpr.mli
+++ b/intf/vernacexpr.mli
@@ -31,7 +31,6 @@ type goal_selector =
| SelectNth of int
| SelectId of Id.t
| SelectAll
- | SelectAllParallel
type goal_identifier = string
type scope_name = string
@@ -61,7 +60,6 @@ type printable =
| PrintClasses
| PrintTypeClasses
| PrintInstances of reference or_by_notation
- | PrintLtac of reference
| PrintCoercions
| PrintCoercionPaths of class_rawexpr * class_rawexpr
| PrintCanonicalConversions
@@ -69,7 +67,6 @@ type printable =
| PrintHint of reference or_by_notation
| PrintHintGoal
| PrintHintDbName of string
- | PrintRewriteHintDbName of string
| PrintHintDb
| PrintScopes
| PrintScope of string
@@ -203,10 +200,6 @@ type one_inductive_expr =
type proof_expr =
plident option * (local_binder list * constr_expr * (lident option * recursion_order_expr) option)
-type grammar_tactic_prod_item_expr =
- | TacTerm of string
- | TacNonTerm of Loc.t * string * (Names.Id.t * string)
-
type syntax_modifier =
| SetItemLevel of string list * Extend.production_level
| SetLevel of int
@@ -293,13 +286,11 @@ type vernac_expr =
| VernacError of exn (* always fails *)
(* Syntax *)
- | VernacTacticNotation of
- int * grammar_tactic_prod_item_expr list * raw_tactic_expr
| VernacSyntaxExtension of
obsolete_locality * (lstring * syntax_modifier list)
| VernacOpenCloseScope of obsolete_locality * (bool * scope_name)
| VernacDelimiters of scope_name * string option
- | VernacBindScope of scope_name * reference or_by_notation list
+ | VernacBindScope of scope_name * class_rawexpr list
| VernacInfix of obsolete_locality * (lstring * syntax_modifier list) *
constr_expr * scope_name option
| VernacNotation of
@@ -364,7 +355,6 @@ type vernac_expr =
(* Solving *)
- | VernacSolve of goal_selector * int option * raw_tactic_expr * bool
| VernacSolveExistential of int * constr_expr
(* Auxiliary file and library management *)
@@ -385,7 +375,6 @@ type vernac_expr =
| VernacBackTo of int
(* Commands *)
- | VernacDeclareTacticDefinition of tacdef_body list
| VernacCreateHintDb of string * bool
| VernacRemoveHints of string list * reference list
| VernacHints of obsolete_locality * string list * hints_expr
@@ -465,7 +454,7 @@ type vernac_type =
| VtStartProof of vernac_start
| VtSideff of vernac_sideff_type
| VtQed of vernac_qed_type
- | VtProofStep of bool (* parallelize *)
+ | VtProofStep of proof_step
| VtProofMode of string
| VtQuery of vernac_part_of_script * report_with
| VtStm of vernac_control * vernac_part_of_script
@@ -487,6 +476,11 @@ and vernac_control =
and opacity_guarantee =
| GuaranteesOpacity (** Only generates opaque terms at [Qed] *)
| Doesn'tGuaranteeOpacity (** May generate transparent terms even with [Qed].*)
+and proof_step = { (* TODO: inline with OCaml 4.03 *)
+ parallel : bool;
+ proof_block_detection : proof_block_name option
+}
+and proof_block_name = string (* open type of delimiters *)
type vernac_when =
| VtNow
| VtLater
diff --git a/kernel/byterun/coq_interp.c b/kernel/byterun/coq_interp.c
index dc571699e..df5fdce75 100644
--- a/kernel/byterun/coq_interp.c
+++ b/kernel/byterun/coq_interp.c
@@ -22,18 +22,10 @@
#include "coq_memory.h"
#include "coq_values.h"
-/*spiwack : imports support functions for 64-bit integers */
-#include <caml/config.h>
-#ifdef ARCH_INT64_TYPE
-#include "int64_native.h"
-#else
-#include "int64_emul.h"
-#endif
-
/* spiwack: I append here a few macros for value/number manipulation */
#define uint32_of_value(val) (((uint32_t)val >> 1))
#define value_of_uint32(i) ((value)(((uint32_t)(i) << 1) | 1))
-#define UI64_of_uint32(lo) ((uint64_t)(I64_literal(0,(uint32_t)(lo))))
+#define UI64_of_uint32(lo) ((uint64_t)(lo))
#define UI64_of_value(val) (UI64_of_uint32(uint32_of_value(val)))
/* /spiwack */
@@ -911,10 +903,12 @@ value coq_interprete
Alloc_small(block, 2, ATOM_PROJ_TAG);
Field(block, 0) = Field(coq_global_data, *pc);
Field(block, 1) = accu;
- /* Create accumulator */
- Alloc_small(accu, 2, Accu_tag);
- Code_val(accu) = accumulate;
- Field(accu, 1) = block;
+ accu = block;
+ /* Create accumulator */
+ Alloc_small(block, 2, Accu_tag);
+ Code_val(block) = accumulate;
+ Field(block, 1) = accu;
+ accu = block;
} else {
accu = Field(accu, *pc++);
}
@@ -1201,8 +1195,8 @@ value coq_interprete
print_instr("MULCINT31");
uint64_t p;
/*accu = 2v+1, *sp=2w+1 ==> p = 2v*w */
- p = I64_mul (UI64_of_value (accu), UI64_of_uint32 ((*sp++)^1));
- if ( I64_is_zero(p) ) {
+ p = UI64_of_value (accu) * UI64_of_uint32 ((*sp++)^1);
+ if (p == 0) {
accu = (value)1;
}
else {
@@ -1211,8 +1205,8 @@ value coq_interprete
of the non-constant constructor is then 1 */
Alloc_small(accu, 2, 1); /* ( _ , arity, tag ) */
/*unsigned shift*/
- Field(accu, 0) = (value)(I64_lsr(p,31)|1) ; /*higher part*/
- Field(accu, 1) = (value)(I64_to_int32(p)|1); /*lower part*/
+ Field(accu, 0) = (value)((p >> 31)|1) ; /*higher part*/
+ Field(accu, 1) = (value)((int32_t)p|1); /*lower part*/
}
Next;
}
@@ -1224,19 +1218,20 @@ value coq_interprete
int62 by the int31 */
uint64_t bigint;
bigint = UI64_of_value(accu);
- bigint = I64_or(I64_lsl(bigint, 31),UI64_of_value(*sp++));
+ bigint = (bigint << 31) | UI64_of_value(*sp++);
uint64_t divisor;
divisor = UI64_of_value(*sp++);
Alloc_small(accu, 2, 1); /* ( _ , arity, tag ) */
- if (I64_is_zero (divisor)) {
+ if (divisor == 0) {
Field(accu, 0) = 1; /* 2*0+1 */
Field(accu, 1) = 1; /* 2*0+1 */
}
else {
uint64_t quo, mod;
- I64_udivmod(bigint, divisor, &quo, &mod);
- Field(accu, 0) = value_of_uint32(I64_to_int32(quo));
- Field(accu, 1) = value_of_uint32(I64_to_int32(mod));
+ quo = bigint / divisor;
+ mod = bigint % divisor;
+ Field(accu, 0) = value_of_uint32((uint32_t)(quo));
+ Field(accu, 1) = value_of_uint32((uint32_t)(mod));
}
Next;
}
diff --git a/kernel/byterun/int64_emul.h b/kernel/byterun/int64_emul.h
deleted file mode 100644
index 86bee72ed..000000000
--- a/kernel/byterun/int64_emul.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/***********************************************************************/
-/* */
-/* Objective Caml */
-/* */
-/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
-/* */
-/* Copyright 2002 Institut National de Recherche en Informatique et */
-/* en Automatique. All rights reserved. This file is distributed */
-/* under the terms of the GNU Library General Public License, with */
-/* the special exception on linking described in file ../LICENSE. */
-/* */
-/***********************************************************************/
-
-/* Software emulation of 64-bit integer arithmetic, for C compilers
- that do not support it. */
-
-#ifndef CAML_INT64_EMUL_H
-#define CAML_INT64_EMUL_H
-
-#include <math.h>
-
-#ifdef ARCH_BIG_ENDIAN
-#define I64_literal(hi,lo) { hi, lo }
-#else
-#define I64_literal(hi,lo) { lo, hi }
-#endif
-
-/* Unsigned comparison */
-static int I64_ucompare(uint64 x, uint64 y)
-{
- if (x.h > y.h) return 1;
- if (x.h < y.h) return -1;
- if (x.l > y.l) return 1;
- if (x.l < y.l) return -1;
- return 0;
-}
-
-#define I64_ult(x, y) (I64_ucompare(x, y) < 0)
-
-/* Signed comparison */
-static int I64_compare(int64 x, int64 y)
-{
- if ((int32)x.h > (int32)y.h) return 1;
- if ((int32)x.h < (int32)y.h) return -1;
- if (x.l > y.l) return 1;
- if (x.l < y.l) return -1;
- return 0;
-}
-
-/* Negation */
-static int64 I64_neg(int64 x)
-{
- int64 res;
- res.l = -x.l;
- res.h = ~x.h;
- if (res.l == 0) res.h++;
- return res;
-}
-
-/* Addition */
-static int64 I64_add(int64 x, int64 y)
-{
- int64 res;
- res.l = x.l + y.l;
- res.h = x.h + y.h;
- if (res.l < x.l) res.h++;
- return res;
-}
-
-/* Subtraction */
-static int64 I64_sub(int64 x, int64 y)
-{
- int64 res;
- res.l = x.l - y.l;
- res.h = x.h - y.h;
- if (x.l < y.l) res.h--;
- return res;
-}
-
-/* Multiplication */
-static int64 I64_mul(int64 x, int64 y)
-{
- int64 res;
- uint32 prod00 = (x.l & 0xFFFF) * (y.l & 0xFFFF);
- uint32 prod10 = (x.l >> 16) * (y.l & 0xFFFF);
- uint32 prod01 = (x.l & 0xFFFF) * (y.l >> 16);
- uint32 prod11 = (x.l >> 16) * (y.l >> 16);
- res.l = prod00;
- res.h = prod11 + (prod01 >> 16) + (prod10 >> 16);
- prod01 = prod01 << 16; res.l += prod01; if (res.l < prod01) res.h++;
- prod10 = prod10 << 16; res.l += prod10; if (res.l < prod10) res.h++;
- res.h += x.l * y.h + x.h * y.l;
- return res;
-}
-
-#define I64_is_zero(x) (((x).l | (x).h) == 0)
-
-#define I64_is_negative(x) ((int32) (x).h < 0)
-
-/* Bitwise operations */
-static int64 I64_and(int64 x, int64 y)
-{
- int64 res;
- res.l = x.l & y.l;
- res.h = x.h & y.h;
- return res;
-}
-
-static int64 I64_or(int64 x, int64 y)
-{
- int64 res;
- res.l = x.l | y.l;
- res.h = x.h | y.h;
- return res;
-}
-
-static int64 I64_xor(int64 x, int64 y)
-{
- int64 res;
- res.l = x.l ^ y.l;
- res.h = x.h ^ y.h;
- return res;
-}
-
-/* Shifts */
-static int64 I64_lsl(int64 x, int s)
-{
- int64 res;
- s = s & 63;
- if (s == 0) return x;
- if (s < 32) {
- res.l = x.l << s;
- res.h = (x.h << s) | (x.l >> (32 - s));
- } else {
- res.l = 0;
- res.h = x.l << (s - 32);
- }
- return res;
-}
-
-static int64 I64_lsr(int64 x, int s)
-{
- int64 res;
- s = s & 63;
- if (s == 0) return x;
- if (s < 32) {
- res.l = (x.l >> s) | (x.h << (32 - s));
- res.h = x.h >> s;
- } else {
- res.l = x.h >> (s - 32);
- res.h = 0;
- }
- return res;
-}
-
-static int64 I64_asr(int64 x, int s)
-{
- int64 res;
- s = s & 63;
- if (s == 0) return x;
- if (s < 32) {
- res.l = (x.l >> s) | (x.h << (32 - s));
- res.h = (int32) x.h >> s;
- } else {
- res.l = (int32) x.h >> (s - 32);
- res.h = (int32) x.h >> 31;
- }
- return res;
-}
-
-/* Division and modulus */
-
-#define I64_SHL1(x) x.h = (x.h << 1) | (x.l >> 31); x.l <<= 1
-#define I64_SHR1(x) x.l = (x.l >> 1) | (x.h << 31); x.h >>= 1
-
-static void I64_udivmod(uint64 modulus, uint64 divisor,
- uint64 * quo, uint64 * mod)
-{
- int64 quotient, mask;
- int cmp;
-
- quotient.h = 0; quotient.l = 0;
- mask.h = 0; mask.l = 1;
- while ((int32) divisor.h >= 0) {
- cmp = I64_ucompare(divisor, modulus);
- I64_SHL1(divisor);
- I64_SHL1(mask);
- if (cmp >= 0) break;
- }
- while (mask.l | mask.h) {
- if (I64_ucompare(modulus, divisor) >= 0) {
- quotient.h |= mask.h; quotient.l |= mask.l;
- modulus = I64_sub(modulus, divisor);
- }
- I64_SHR1(mask);
- I64_SHR1(divisor);
- }
- *quo = quotient;
- *mod = modulus;
-}
-
-static int64 I64_div(int64 x, int64 y)
-{
- int64 q, r;
- int32 sign;
-
- sign = x.h ^ y.h;
- if ((int32) x.h < 0) x = I64_neg(x);
- if ((int32) y.h < 0) y = I64_neg(y);
- I64_udivmod(x, y, &q, &r);
- if (sign < 0) q = I64_neg(q);
- return q;
-}
-
-static int64 I64_mod(int64 x, int64 y)
-{
- int64 q, r;
- int32 sign;
-
- sign = x.h;
- if ((int32) x.h < 0) x = I64_neg(x);
- if ((int32) y.h < 0) y = I64_neg(y);
- I64_udivmod(x, y, &q, &r);
- if (sign < 0) r = I64_neg(r);
- return r;
-}
-
-/* Coercions */
-
-static int64 I64_of_int32(int32 x)
-{
- int64 res;
- res.l = x;
- res.h = x >> 31;
- return res;
-}
-
-#define I64_to_int32(x) ((int32) (x).l)
-
-/* Note: we assume sizeof(intnat) = 4 here, which is true otherwise
- autoconfiguration would have selected native 64-bit integers */
-#define I64_of_intnat I64_of_int32
-#define I64_to_intnat I64_to_int32
-
-static double I64_to_double(int64 x)
-{
- double res;
- int32 sign = x.h;
- if (sign < 0) x = I64_neg(x);
- res = ldexp((double) x.h, 32) + x.l;
- if (sign < 0) res = -res;
- return res;
-}
-
-static int64 I64_of_double(double f)
-{
- int64 res;
- double frac, integ;
- int neg;
-
- neg = (f < 0);
- f = fabs(f);
- frac = modf(ldexp(f, -32), &integ);
- res.h = (uint32) integ;
- res.l = (uint32) ldexp(frac, 32);
- if (neg) res = I64_neg(res);
- return res;
-}
-
-#endif /* CAML_INT64_EMUL_H */
diff --git a/kernel/byterun/int64_native.h b/kernel/byterun/int64_native.h
deleted file mode 100644
index 657d0a07e..000000000
--- a/kernel/byterun/int64_native.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/***********************************************************************/
-/* */
-/* Objective Caml */
-/* */
-/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
-/* */
-/* Copyright 2002 Institut National de Recherche en Informatique et */
-/* en Automatique. All rights reserved. This file is distributed */
-/* under the terms of the GNU Library General Public License, with */
-/* the special exception on linking described in file ../LICENSE. */
-/* */
-/***********************************************************************/
-
-/* Wrapper macros around native 64-bit integer arithmetic,
- so that it has the same interface as the software emulation
- provided in int64_emul.h */
-
-#ifndef CAML_INT64_NATIVE_H
-#define CAML_INT64_NATIVE_H
-
-#define I64_literal(hi,lo) ((int64_t)(hi) << 32 | (lo))
-#define I64_compare(x,y) (((x) > (y)) - ((x) < (y)))
-#define I64_ult(x,y) ((uint64_t)(x) < (uint64_t)(y))
-#define I64_neg(x) (-(x))
-#define I64_add(x,y) ((x) + (y))
-#define I64_sub(x,y) ((x) - (y))
-#define I64_mul(x,y) ((x) * (y))
-#define I64_is_zero(x) ((x) == 0)
-#define I64_is_negative(x) ((x) < 0)
-#define I64_div(x,y) ((x) / (y))
-#define I64_mod(x,y) ((x) % (y))
-#define I64_udivmod(x,y,quo,rem) \
- (*(rem) = (uint64_t)(x) % (uint64_t)(y), \
- *(quo) = (uint64_t)(x) / (uint64_t)(y))
-#define I64_and(x,y) ((x) & (y))
-#define I64_or(x,y) ((x) | (y))
-#define I64_xor(x,y) ((x) ^ (y))
-#define I64_lsl(x,y) ((x) << (y))
-#define I64_asr(x,y) ((x) >> (y))
-#define I64_lsr(x,y) ((uint64_t)(x) >> (y))
-#define I64_to_intnat(x) ((intnat) (x))
-#define I64_of_intnat(x) ((intnat) (x))
-#define I64_to_int32(x) ((int32_t) (x))
-#define I64_of_int32(x) ((int64_t) (x))
-#define I64_to_double(x) ((double)(x))
-#define I64_of_double(x) ((int64_t)(x))
-
-#endif /* CAML_INT64_NATIVE_H */
diff --git a/kernel/cbytecodes.ml b/kernel/cbytecodes.ml
index f9cf2691e..a705e3004 100644
--- a/kernel/cbytecodes.ml
+++ b/kernel/cbytecodes.ml
@@ -184,9 +184,6 @@ let rec pp_struct_const = function
let pp_lbl lbl = str "L" ++ int lbl
-let pp_pcon (id,u) =
- pr_con id ++ str "@{" ++ Univ.Instance.pr Univ.Level.pr u ++ str "}"
-
let pp_fv_elem = function
| FVnamed id -> str "FVnamed(" ++ Id.print id ++ str ")"
| FVrel i -> str "Rel(" ++ int i ++ str ")"
diff --git a/kernel/cbytegen.ml b/kernel/cbytegen.ml
index 77eac9ee9..431c914c0 100644
--- a/kernel/cbytegen.ml
+++ b/kernel/cbytegen.ml
@@ -904,10 +904,10 @@ let compile fail_on_error ?universes:(universes=0) env c =
in
let fv = List.rev (!(reloc.in_env).fv_rev) in
(if !Flags.dump_bytecode then
- Pp.msg_debug (dump_bytecodes init_code !fun_code fv)) ;
+ Feedback.msg_debug (dump_bytecodes init_code !fun_code fv)) ;
Some (init_code,!fun_code, Array.of_list fv)
with TooLargeInductive tname ->
- let fn = if fail_on_error then Errors.errorlabstrm "compile" else Pp.msg_warning in
+ let fn = if fail_on_error then Errors.errorlabstrm "compile" else Feedback.msg_warning in
(Pp.(fn
(str "Cannot compile code for virtual machine as it uses inductive " ++
Id.print tname ++ str str_max_constructors));
diff --git a/kernel/closure.ml b/kernel/closure.ml
index 4476fe524..960bdb649 100644
--- a/kernel/closure.ml
+++ b/kernel/closure.ml
@@ -45,7 +45,7 @@ let reset () =
prune := 0
let stop() =
- msg_debug (str "[Reds: beta=" ++ int !beta ++ str" delta=" ++ int !delta ++
+ Feedback.msg_debug (str "[Reds: beta=" ++ int !beta ++ str" delta=" ++ int !delta ++
str " eta=" ++ int !eta ++ str" zeta=" ++ int !zeta ++ str" evar=" ++
int !evar ++ str" iota=" ++ int !iota ++ str" prune=" ++ int !prune ++
str"]")
@@ -363,6 +363,7 @@ let set_norm v = v.norm <- Norm
let is_val v = match v.norm with Norm -> true | _ -> false
let mk_atom c = {norm=Norm;term=FAtom c}
+let mk_red f = {norm=Red;term=f}
(* Could issue a warning if no is still Red, pointing out that we loose
sharing. *)
@@ -778,7 +779,7 @@ let eta_expand_ind_stack env ind m s (f, s') =
let mib = lookup_mind (fst ind) env in
match mib.Declarations.mind_record with
| Some (Some (_,projs,pbs)) when
- mib.Declarations.mind_finite <> Decl_kinds.CoFinite ->
+ mib.Declarations.mind_finite == Decl_kinds.BiFinite ->
(* (Construct, pars1 .. parsm :: arg1...argn :: []) ~= (f, s') ->
arg1..argn ~= (proj1 t...projn t) where t = zip (f,s') *)
let pars = mib.Declarations.mind_nparams in
diff --git a/kernel/closure.mli b/kernel/closure.mli
index 07176cb7d..8e172290f 100644
--- a/kernel/closure.mli
+++ b/kernel/closure.mli
@@ -164,6 +164,9 @@ val inject : constr -> fconstr
(** mk_atom: prevents a term from being evaluated *)
val mk_atom : constr -> fconstr
+(** mk_red: makes a reducible term (used in newring) *)
+val mk_red : fterm -> fconstr
+
val fterm_of : fconstr -> fterm
val term_of_fconstr : fconstr -> constr
val destFLambda :
diff --git a/kernel/constr.ml b/kernel/constr.ml
index 8e05e29eb..ce20751ab 100644
--- a/kernel/constr.ml
+++ b/kernel/constr.ml
@@ -744,12 +744,10 @@ let hasheq t1 t2 =
n1 == n2 && b1 == b2 && t1 == t2 && c1 == c2
| App (c1,l1), App (c2,l2) -> c1 == c2 && array_eqeq l1 l2
| Proj (p1,c1), Proj(p2,c2) -> p1 == p2 && c1 == c2
- | Evar (e1,l1), Evar (e2,l2) -> Evar.equal e1 e2 && array_eqeq l1 l2
+ | Evar (e1,l1), Evar (e2,l2) -> e1 == e2 && array_eqeq l1 l2
| Const (c1,u1), Const (c2,u2) -> c1 == c2 && u1 == u2
- | Ind ((sp1,i1),u1), Ind ((sp2,i2),u2) ->
- sp1 == sp2 && Int.equal i1 i2 && u1 == u2
- | Construct (((sp1,i1),j1),u1), Construct (((sp2,i2),j2),u2) ->
- sp1 == sp2 && Int.equal i1 i2 && Int.equal j1 j2 && u1 == u2
+ | Ind (ind1,u1), Ind (ind2,u2) -> ind1 == ind2 && u1 == u2
+ | Construct (cstr1,u1), Construct (cstr2,u2) -> cstr1 == cstr2 && u1 == u2
| Case (ci1,p1,c1,bl1), Case (ci2,p2,c2,bl2) ->
ci1 == ci2 && p1 == p2 && c1 == c2 && array_eqeq bl1 bl2
| Fix ((ln1, i1),(lna1,tl1,bl1)), Fix ((ln2, i2),(lna2,tl2,bl2)) ->
@@ -769,10 +767,10 @@ let hasheq t1 t2 =
once and for all the table we'll use for hash-consing all constr *)
module HashsetTerm =
- Hashset.Make(struct type t = constr let equal = hasheq end)
+ Hashset.Make(struct type t = constr let eq = hasheq end)
module HashsetTermArray =
- Hashset.Make(struct type t = constr array let equal = array_eqeq end)
+ Hashset.Make(struct type t = constr array let eq = array_eqeq end)
let term_table = HashsetTerm.create 19991
(* The associative table to hashcons terms. *)
@@ -827,19 +825,19 @@ let hashcons (sh_sort,sh_ci,sh_construct,sh_ind,sh_con,sh_na,sh_id) =
| Proj (p,c) ->
let c, hc = sh_rec c in
let p' = Projection.hcons p in
- (Proj (p', c), combinesmall 17 (combine (Projection.hash p') hc))
+ (Proj (p', c), combinesmall 17 (combine (Projection.SyntacticOrd.hash p') hc))
| Const (c,u) ->
let c' = sh_con c in
let u', hu = sh_instance u in
- (Const (c', u'), combinesmall 9 (combine (Constant.hash c) hu))
- | Ind ((kn,i) as ind,u) ->
+ (Const (c', u'), combinesmall 9 (combine (Constant.SyntacticOrd.hash c) hu))
+ | Ind (ind,u) ->
let u', hu = sh_instance u in
(Ind (sh_ind ind, u'),
- combinesmall 10 (combine (ind_hash ind) hu))
- | Construct ((((kn,i),j) as c,u))->
+ combinesmall 10 (combine (ind_syntactic_hash ind) hu))
+ | Construct (c,u) ->
let u', hu = sh_instance u in
(Construct (sh_construct c, u'),
- combinesmall 11 (combine (constructor_hash c) hu))
+ combinesmall 11 (combine (constructor_syntactic_hash c) hu))
| Case (ci,p,c,bl) ->
let p, hp = sh_rec p
and c, hc = sh_rec c in
@@ -942,7 +940,7 @@ struct
List.equal (==) info1.ind_tags info2.ind_tags &&
Array.equal (List.equal (==)) info1.cstr_tags info2.cstr_tags &&
info1.style == info2.style
- let equal ci ci' =
+ let eq ci ci' =
ci.ci_ind == ci'.ci_ind &&
Int.equal ci.ci_npar ci'.ci_npar &&
Array.equal Int.equal ci.ci_cstr_ndecls ci'.ci_cstr_ndecls && (* we use [Array.equal] on purpose *)
@@ -984,7 +982,7 @@ module Hsorts =
let hashcons huniv = function
Prop c -> Prop c
| Type u -> Type (huniv u)
- let equal s1 s2 =
+ let eq s1 s2 =
s1 == s2 ||
match (s1,s2) with
(Prop c1, Prop c2) -> c1 == c2
diff --git a/kernel/constr.mli b/kernel/constr.mli
index f76b5ae4f..42d298e3b 100644
--- a/kernel/constr.mli
+++ b/kernel/constr.mli
@@ -6,6 +6,9 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** This file defines the most important datatype of Coq, namely kernel terms,
+ as well as a handful of generic manipulation functions. *)
+
open Names
(** {6 Value under universe substitution } *)
diff --git a/kernel/cooking.ml b/kernel/cooking.ml
index 86d786b09..6dc2a617d 100644
--- a/kernel/cooking.ml
+++ b/kernel/cooking.ml
@@ -44,15 +44,15 @@ module RefHash =
struct
type t = my_global_reference
let equal gr1 gr2 = match gr1, gr2 with
- | ConstRef c1, ConstRef c2 -> Constant.CanOrd.equal c1 c2
- | IndRef i1, IndRef i2 -> eq_ind i1 i2
- | ConstructRef c1, ConstructRef c2 -> eq_constructor c1 c2
+ | ConstRef c1, ConstRef c2 -> Constant.SyntacticOrd.equal c1 c2
+ | IndRef i1, IndRef i2 -> eq_syntactic_ind i1 i2
+ | ConstructRef c1, ConstructRef c2 -> eq_syntactic_constructor c1 c2
| _ -> false
open Hashset.Combine
let hash = function
- | ConstRef c -> combinesmall 1 (Constant.hash c)
- | IndRef i -> combinesmall 2 (ind_hash i)
- | ConstructRef c -> combinesmall 3 (constructor_hash c)
+ | ConstRef c -> combinesmall 1 (Constant.SyntacticOrd.hash c)
+ | IndRef i -> combinesmall 2 (ind_syntactic_hash i)
+ | ConstructRef c -> combinesmall 3 (constructor_syntactic_hash c)
end
module RefTable = Hashtbl.Make(RefHash)
diff --git a/kernel/csymtable.ml b/kernel/csymtable.ml
index 9d58f6615..047da682a 100644
--- a/kernel/csymtable.ml
+++ b/kernel/csymtable.ml
@@ -130,8 +130,8 @@ let key rk =
match !rk with
| None -> raise NotEvaluated
| Some k ->
- try Ephemeron.get k
- with Ephemeron.InvalidKey -> raise NotEvaluated
+ try CEphemeron.get k
+ with CEphemeron.InvalidKey -> raise NotEvaluated
(************************)
(* traduction des patch *)
@@ -170,7 +170,7 @@ let rec slot_for_getglobal env kn =
| BCconstant -> set_global (val_of_constant kn)
in
(*Pp.msgnl(str"value stored at: "++int pos);*)
- rk := Some (Ephemeron.create pos);
+ rk := Some (CEphemeron.create pos);
pos
and slot_for_fv env fv =
diff --git a/kernel/entries.mli b/kernel/entries.mli
index 3ecfcca64..d07ca2103 100644
--- a/kernel/entries.mli
+++ b/kernel/entries.mli
@@ -104,7 +104,7 @@ type side_eff =
| SEscheme of (inductive * constant * Declarations.constant_body * seff_env) list * string
type side_effect = {
- from_env : Declarations.structure_body Ephemeron.key;
+ from_env : Declarations.structure_body CEphemeron.key;
eff : side_eff;
}
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml
index 4834f95d1..edb758f07 100644
--- a/kernel/indtypes.ml
+++ b/kernel/indtypes.ml
@@ -22,6 +22,16 @@ open Entries
open Pp
open Context.Rel.Declaration
+(* Terminology:
+paramdecls (ou paramsctxt?)
+args = params + realargs (called vargs when an array, largs when a list)
+params = recparams + nonrecparams
+nonrecargs = nonrecparams + realargs
+env_ar = initial env + declaration of inductive types
+env_ar_par = env_ar + declaration of parameters
+nmr = ongoing computation of recursive parameters
+*)
+
(* Tell if indices (aka real arguments) contribute to size of inductive type *)
(* If yes, this is compatible with the univalent model *)
@@ -186,15 +196,16 @@ let is_impredicative env u =
polymorphism. The elements x_k is None if the k-th parameter (starting
from the most recent and ignoring let-definitions) is not contributing
or is Some u_k if its level is u_k and is contributing. *)
-let param_ccls params =
- let fold acc = function (LocalAssum (_, p)) ->
+let param_ccls paramsctxt =
+ let fold acc = function
+ | (LocalAssum (_, p)) ->
(let c = strip_prod_assum p in
match kind_of_term c with
| Sort (Type u) -> Univ.Universe.level u
| _ -> None) :: acc
| LocalDef _ -> acc
in
- List.fold_left fold [] params
+ List.fold_left fold [] paramsctxt
(* Type-check an inductive definition. Does not check positivity
conditions. *)
@@ -210,7 +221,7 @@ let typecheck_inductive env mie =
mind_check_names mie;
(* Params are typed-checked here *)
let env' = push_context mie.mind_entry_universes env in
- let (env_params, params) = infer_local_decls env' mie.mind_entry_params in
+ let (env_params,paramsctxt) = infer_local_decls env' mie.mind_entry_params in
(* We first type arity of each inductive definition *)
(* This allows building the environment of arities and to share *)
(* the set of constraints *)
@@ -249,26 +260,26 @@ let typecheck_inductive env mie =
later, after the validation of the inductive definition,
full_arity is used as argument or subject to cast, an
upper universe will be generated *)
- let full_arity = it_mkProd_or_LetIn arity params in
+ let full_arity = it_mkProd_or_LetIn arity paramsctxt in
let id = ind.mind_entry_typename in
let env_ar' =
push_rel (LocalAssum (Name id, full_arity)) env_ar in
(* (add_constraints cst2 env_ar) in *)
- (env_ar', (id,full_arity,sign @ params,expltype,deflev,inflev)::l))
+ (env_ar', (id,full_arity,sign @ paramsctxt,expltype,deflev,inflev)::l))
(env',[])
mie.mind_entry_inds in
let arity_list = List.rev rev_arity_list in
(* builds the typing context "Gamma, I1:A1, ... In:An, params" *)
- let env_ar_par = push_rel_context params env_arities in
+ let env_ar_par = push_rel_context paramsctxt env_arities in
(* Now, we type the constructors (without params) *)
let inds =
List.fold_right2
(fun ind arity_data inds ->
let (lc',cstrs_univ) =
- infer_constructor_packet env_ar_par params ind.mind_entry_lc in
+ infer_constructor_packet env_ar_par paramsctxt ind.mind_entry_lc in
let consnames = ind.mind_entry_consnames in
let ind' = (arity_data,consnames,lc',cstrs_univ) in
ind'::inds)
@@ -324,7 +335,7 @@ let typecheck_inductive env mie =
Universe.pr u ++ Pp.str " declared for inductive type, inferred level is "
++ Universe.pr clev)
else
- TemplateArity (param_ccls params, infu)
+ TemplateArity (param_ccls paramsctxt, infu)
| _ (* Not an explicit occurrence of Type *) ->
full_polymorphic ()
in
@@ -334,7 +345,7 @@ let typecheck_inductive env mie =
in
(id,cn,lc,(sign,arity)))
inds
- in (env_arities, env_ar_par, params, inds)
+ in (env_arities, env_ar_par, paramsctxt, inds)
(************************************************************************)
(************************************************************************)
@@ -354,21 +365,22 @@ exception IllFormedInd of ill_formed_ind
let mind_extract_params = decompose_prod_n_assum
-let explain_ind_err id ntyp env nbpar c err =
- let (lpar,c') = mind_extract_params nbpar c in
+let explain_ind_err id ntyp env nparamsctxt c err =
+ let (lparams,c') = mind_extract_params nparamsctxt c in
match err with
| LocalNonPos kt ->
- raise (InductiveError (NonPos (env,c',mkRel (kt+nbpar))))
+ raise (InductiveError (NonPos (env,c',mkRel (kt+nparamsctxt))))
| LocalNotEnoughArgs kt ->
raise (InductiveError
- (NotEnoughArgs (env,c',mkRel (kt+nbpar))))
+ (NotEnoughArgs (env,c',mkRel (kt+nparamsctxt))))
| LocalNotConstructor (paramsctxt,nargs)->
let nparams = Context.Rel.nhyps paramsctxt in
raise (InductiveError
- (NotConstructor (env,id,c',mkRel (ntyp+nbpar),nparams,nargs)))
+ (NotConstructor (env,id,c',mkRel (ntyp+nparamsctxt),
+ nparams,nargs)))
| LocalNonPar (n,i,l) ->
raise (InductiveError
- (NonPar (env,c',n,mkRel i, mkRel (l+nbpar))))
+ (NonPar (env,c',n,mkRel i,mkRel (l+nparamsctxt))))
let failwith_non_pos n ntypes c =
for k = n to n + ntypes - 1 do
@@ -384,43 +396,50 @@ let failwith_non_pos_list n ntypes l =
anomaly ~label:"failwith_non_pos_list" (Pp.str "some k in [n;n+ntypes-1] should occur")
(* Check the inductive type is called with the expected parameters *)
-let check_correct_par (env,n,ntypes,_) hyps l largs =
- let nparams = Context.Rel.nhyps hyps in
- let largs = Array.of_list largs in
- if Array.length largs < nparams then
- raise (IllFormedInd (LocalNotEnoughArgs l));
- let (lpar,largs') = Array.chop nparams largs in
- let nhyps = List.length hyps in
- let rec check k index = function
+(* [n] is the index of the last inductive type in [env] *)
+let check_correct_par (env,n,ntypes,_) paramdecls ind_index args =
+ let nparams = Context.Rel.nhyps paramdecls in
+ let args = Array.of_list args in
+ if Array.length args < nparams then
+ raise (IllFormedInd (LocalNotEnoughArgs ind_index));
+ let (params,realargs) = Array.chop nparams args in
+ let nparamdecls = List.length paramdecls in
+ let rec check param_index paramdecl_index = function
| [] -> ()
- | LocalDef _ :: hyps -> check k (index+1) hyps
- | _::hyps ->
- match kind_of_term (whd_betadeltaiota env lpar.(k)) with
- | Rel w when Int.equal w index -> check (k-1) (index+1) hyps
- | _ -> raise (IllFormedInd (LocalNonPar (k+1, index-n+nhyps+1, l)))
- in check (nparams-1) (n-nhyps) hyps;
- if not (Array.for_all (noccur_between n ntypes) largs') then
- failwith_non_pos_vect n ntypes largs'
-
-(* Computes the maximum number of recursive parameters :
- the first parameters which are constant in recursive arguments
- n is the current depth, nmr is the maximum number of possible
- recursive parameters *)
-
-let compute_rec_par (env,n,_,_) hyps nmr largs =
+ | LocalDef _ :: paramdecls ->
+ check param_index (paramdecl_index+1) paramdecls
+ | _::paramdecls ->
+ match kind_of_term (whd_betadeltaiota env params.(param_index)) with
+ | Rel w when Int.equal w paramdecl_index ->
+ check (param_index-1) (paramdecl_index+1) paramdecls
+ | _ ->
+ let paramdecl_index_in_env = paramdecl_index-n+nparamdecls+1 in
+ let err =
+ LocalNonPar (param_index+1, paramdecl_index_in_env, ind_index) in
+ raise (IllFormedInd err)
+ in check (nparams-1) (n-nparamdecls) paramdecls;
+ if not (Array.for_all (noccur_between n ntypes) realargs) then
+ failwith_non_pos_vect n ntypes realargs
+
+(* Computes the maximum number of recursive parameters:
+ the first parameters which are constant in recursive arguments
+ [n] is the current depth, [nmr] is the maximum number of possible
+ recursive parameters *)
+
+let compute_rec_par (env,n,_,_) paramsctxt nmr largs =
if Int.equal nmr 0 then 0 else
-(* start from 0, hyps will be in reverse order *)
+(* start from 0, params will be in reverse order *)
let (lpar,_) = List.chop nmr largs in
let rec find k index =
function
([],_) -> nmr
- | (_,[]) -> assert false (* |hyps|>=nmr *)
- | (lp, LocalDef _ :: hyps) -> find k (index-1) (lp,hyps)
- | (p::lp,_::hyps) ->
+ | (_,[]) -> assert false (* |paramsctxt|>=nmr *)
+ | (lp, LocalDef _ :: paramsctxt) -> find k (index-1) (lp,paramsctxt)
+ | (p::lp,_::paramsctxt) ->
( match kind_of_term (whd_betadeltaiota env p) with
- | Rel w when Int.equal w index -> find (k+1) (index-1) (lp,hyps)
+ | Rel w when Int.equal w index -> find (k+1) (index-1) (lp,paramsctxt)
| _ -> k)
- in find 0 (n-1) (lpar,List.rev hyps)
+ in find 0 (n-1) (lpar,List.rev paramsctxt)
(* [env] is the typing environment
[n] is the dB of the last inductive type
@@ -431,12 +450,12 @@ if Int.equal nmr 0 then 0 else
let ienv_push_var (env, n, ntypes, lra) (x,a,ra) =
(push_rel (LocalAssum (x,a)) env, n+1, ntypes, (Norec,ra)::lra)
-let ienv_push_inductive (env, n, ntypes, ra_env) ((mi,u),lpar) =
+let ienv_push_inductive (env, n, ntypes, ra_env) ((mi,u),lrecparams) =
let auxntyp = 1 in
let specif = (lookup_mind_specif env mi, u) in
let ty = type_of_inductive env specif in
let env' =
- let decl = LocalAssum (Anonymous, hnf_prod_applist env ty lpar) in
+ let decl = LocalAssum (Anonymous, hnf_prod_applist env ty lrecparams) in
push_rel decl env in
let ra_env' =
(Imbr mi,(Rtree.mk_rec_calls 1).(0)) ::
@@ -457,7 +476,7 @@ let rec ienv_decompose_prod (env,_,_,_ as ienv) n c =
let array_min nmr a = if Int.equal nmr 0 then 0 else
Array.fold_left (fun k (nmri,_) -> min k nmri) nmr a
-(** [check_positivity_one ienv hyps (mind,i) nargs lcnames indlc]
+(** [check_positivity_one ienv paramsctxt (mind,i) nnonrecargs lcnames indlc]
checks the positivity of the [i]-th member of the mutually
inductive definition [mind]. It returns an [Rtree.t] which
represents the position of the recursive calls of inductive in [i]
@@ -465,9 +484,9 @@ let array_min nmr a = if Int.equal nmr 0 then 0 else
considered sub-terms) as well as the number of of non-uniform
arguments (used to generate induction schemes, so a priori less
relevant to the kernel). *)
-let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcnames indlc =
- let lparams = Context.Rel.length hyps in
- let nmr = Context.Rel.nhyps hyps in
+let check_positivity_one recursive (env,_,ntypes,_ as ienv) paramsctxt (_,i as ind) nnonrecargs lcnames indlc =
+ let nparamsctxt = Context.Rel.length paramsctxt in
+ let nmr = Context.Rel.nhyps paramsctxt in
(** Positivity of one argument [c] of a constructor (i.e. the
constructor [cn] has a type of the shape [… -> c … -> P], where,
more generally, the arrows may be dependent). *)
@@ -490,7 +509,7 @@ let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcname
let largs = List.map (whd_betadeltaiota env) largs in
let nmr1 =
(match ra with
- Mrec _ -> compute_rec_par ienv hyps nmr largs
+ Mrec _ -> compute_rec_par ienv paramsctxt nmr largs
| _ -> nmr)
in
(** The case where one of the inductives of the mutually
@@ -525,27 +544,27 @@ let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcname
(* accesses to the environment are not factorised, but is it worth? *)
and check_positive_nested (env,n,ntypes,ra_env as ienv) nmr ((mi,u), largs) =
let (mib,mip) = lookup_mind_specif env mi in
- let auxnpar = mib.mind_nparams_rec in
- let nonrecpar = mib.mind_nparams - auxnpar in
- let (lpar,auxlargs) =
- try List.chop auxnpar largs
+ let auxnrecpar = mib.mind_nparams_rec in
+ let auxnnonrecpar = mib.mind_nparams - auxnrecpar in
+ let (auxrecparams,auxnonrecargs) =
+ try List.chop auxnrecpar largs
with Failure _ -> raise (IllFormedInd (LocalNonPos n)) in
(** Inductives of the inductive block being defined are only
allowed to appear nested in the parameters of another inductive
type. Not in the proper indices. *)
- if not (List.for_all (noccur_between n ntypes) auxlargs) then
- failwith_non_pos_list n ntypes auxlargs;
+ if not (List.for_all (noccur_between n ntypes) auxnonrecargs) then
+ failwith_non_pos_list n ntypes auxnonrecargs;
(* Nested mutual inductive types are not supported *)
let auxntyp = mib.mind_ntypes in
if not (Int.equal auxntyp 1) then raise (IllFormedInd (LocalNonPos n));
(* The nested inductive type with parameters removed *)
- let auxlcvect = abstract_mind_lc auxntyp auxnpar mip.mind_nf_lc in
+ let auxlcvect = abstract_mind_lc auxntyp auxnrecpar mip.mind_nf_lc in
(* Extends the environment with a variable corresponding to
the inductive def *)
- let (env',_,_,_ as ienv') = ienv_push_inductive ienv ((mi,u),lpar) in
+ let (env',_,_,_ as ienv') = ienv_push_inductive ienv ((mi,u),auxrecparams) in
(* Parameters expressed in env' *)
- let lpar' = List.map (lift auxntyp) lpar in
+ let auxrecparams' = List.map (lift auxntyp) auxrecparams in
let irecargs_nmr =
(** Checks that the "nesting" inductive type is covariant in
the relevant parameters. In other words, that the
@@ -554,9 +573,9 @@ let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcname
positively in the types of the nested constructors. *)
Array.map
(function c ->
- let c' = hnf_prod_applist env' c lpar' in
+ let c' = hnf_prod_applist env' c auxrecparams' in
(* skip non-recursive parameters *)
- let (ienv',c') = ienv_decompose_prod ienv' nonrecpar c' in
+ let (ienv',c') = ienv_decompose_prod ienv' auxnnonrecpar c' in
check_constructors ienv' false nmr c')
auxlcvect
in
@@ -580,6 +599,8 @@ let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcname
| Prod (na,b,d) ->
let () = assert (List.is_empty largs) in
+ if not recursive && not (noccur_between n ntypes b) then
+ raise (InductiveError BadEntry);
let nmr',recarg = check_pos ienv nmr b in
let ienv' = ienv_push_var ienv (na,b,mk_norec) in
check_constr_rec ienv' nmr' (recarg::lrec) d
@@ -588,8 +609,8 @@ let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcname
if check_head then
begin match hd with
| Rel j when Int.equal j (n + ntypes - i - 1) ->
- check_correct_par ienv hyps (ntypes - i) largs
- | _ -> raise (IllFormedInd (LocalNotConstructor(hyps,nargs)))
+ check_correct_par ienv paramsctxt (ntypes - i) largs
+ | _ -> raise (IllFormedInd (LocalNotConstructor(paramsctxt,nnonrecargs)))
end
else
if not (List.for_all (noccur_between n ntypes) largs)
@@ -601,31 +622,32 @@ let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcname
let irecargs_nmr =
Array.map2
(fun id c ->
- let _,rawc = mind_extract_params lparams c in
+ let _,rawc = mind_extract_params nparamsctxt c in
try
check_constructors ienv true nmr rawc
with IllFormedInd err ->
- explain_ind_err id (ntypes-i) env lparams c err)
+ explain_ind_err id (ntypes-i) env nparamsctxt c err)
(Array.of_list lcnames) indlc
in
let irecargs = Array.map snd irecargs_nmr
and nmr' = array_min nmr irecargs_nmr
in (nmr', mk_paths (Mrec ind) irecargs)
-(** [check_positivity kn env_ar params] checks that the mutually
+(** [check_positivity kn env_ar paramsctxt inds] checks that the mutually
inductive block [inds] is strictly positive. *)
-let check_positivity kn env_ar params inds =
+let check_positivity kn env_ar_par paramsctxt finite inds =
let ntypes = Array.length inds in
+ let recursive = finite != Decl_kinds.BiFinite in
let rc = Array.mapi (fun j t -> (Mrec (kn,j),t)) (Rtree.mk_rec_calls ntypes) in
- let lra_ind = Array.rev_to_list rc in
- let lparams = Context.Rel.length params in
- let nmr = Context.Rel.nhyps params in
+ let ra_env_ar = Array.rev_to_list rc in
+ let nparamsctxt = Context.Rel.length paramsctxt in
+ let nmr = Context.Rel.nhyps paramsctxt in
let check_one i (_,lcnames,lc,(sign,_)) =
- let ra_env =
- List.init lparams (fun _ -> (Norec,mk_norec)) @ lra_ind in
- let ienv = (env_ar, 1+lparams, ntypes, ra_env) in
- let nargs = Context.Rel.nhyps sign - nmr in
- check_positivity_one ienv params (kn,i) nargs lcnames lc
+ let ra_env_ar_par =
+ List.init nparamsctxt (fun _ -> (Norec,mk_norec)) @ ra_env_ar in
+ let ienv = (env_ar_par, 1+nparamsctxt, ntypes, ra_env_ar_par) in
+ let nnonrecargs = Context.Rel.nhyps sign - nmr in
+ check_positivity_one recursive ienv paramsctxt (kn,i) nnonrecargs lcnames lc
in
let irecargs_nmr = Array.mapi check_one inds in
let irecargs = Array.map snd irecargs_nmr
@@ -780,14 +802,14 @@ let compute_projections ((kn, _ as ind), u as indu) n x nparamargs params
Array.of_list (List.rev kns),
Array.of_list (List.rev pbs)
-let build_inductive env p prv ctx env_ar params kn isrecord isfinite inds nmr recargs =
+let build_inductive env p prv ctx env_ar paramsctxt kn isrecord isfinite inds nmr recargs =
let ntypes = Array.length inds in
(* Compute the set of used section variables *)
let hyps = used_section_variables env inds in
- let nparamargs = Context.Rel.nhyps params in
- let nparamdecls = Context.Rel.length params in
+ let nparamargs = Context.Rel.nhyps paramsctxt in
+ let nparamsctxt = Context.Rel.length paramsctxt in
let subst, ctx = Univ.abstract_universes p ctx in
- let params = Vars.subst_univs_level_context subst params in
+ let paramsctxt = Vars.subst_univs_level_context subst paramsctxt in
let env_ar =
let ctx = Environ.rel_context env_ar in
let ctx' = Vars.subst_univs_level_context subst ctx in
@@ -800,10 +822,10 @@ let build_inductive env p prv ctx env_ar params kn isrecord isfinite inds nmr re
let splayed_lc = Array.map (dest_prod_assum env_ar) lc in
let nf_lc = Array.map (fun (d,b) -> it_mkProd_or_LetIn b d) splayed_lc in
let consnrealdecls =
- Array.map (fun (d,_) -> Context.Rel.length d - Context.Rel.length params)
+ Array.map (fun (d,_) -> Context.Rel.length d - nparamsctxt)
splayed_lc in
let consnrealargs =
- Array.map (fun (d,_) -> Context.Rel.nhyps d - Context.Rel.nhyps params)
+ Array.map (fun (d,_) -> Context.Rel.nhyps d - nparamargs)
splayed_lc in
(* Elimination sorts *)
let arkind,kelim =
@@ -837,7 +859,7 @@ let build_inductive env p prv ctx env_ar params kn isrecord isfinite inds nmr re
mind_arity = arkind;
mind_arity_ctxt = Vars.subst_univs_level_context subst ar_sign;
mind_nrealargs = Context.Rel.nhyps ar_sign - nparamargs;
- mind_nrealdecls = Context.Rel.length ar_sign - nparamdecls;
+ mind_nrealdecls = Context.Rel.length ar_sign - nparamsctxt;
mind_kelim = kelim;
mind_consnames = Array.of_list cnames;
mind_consnrealdecls = consnrealdecls;
@@ -850,10 +872,11 @@ let build_inductive env p prv ctx env_ar params kn isrecord isfinite inds nmr re
mind_reloc_tbl = rtbl;
} in
let packets = Array.map2 build_one_packet inds recargs in
- let pkt = packets.(0) in
+ let pkt = packets.(0) in
let isrecord =
match isrecord with
- | Some (Some rid) when pkt.mind_kelim == all_sorts && Array.length pkt.mind_consnames == 1
+ | Some (Some rid) when pkt.mind_kelim == all_sorts
+ && Array.length pkt.mind_consnames == 1
&& pkt.mind_consnrealargs.(0) > 0 ->
(** The elimination criterion ensures that all projections can be defined. *)
let u =
@@ -866,7 +889,7 @@ let build_inductive env p prv ctx env_ar params kn isrecord isfinite inds nmr re
(try
let fields, paramslet = List.chop pkt.mind_consnrealdecls.(0) rctx in
let kns, projs =
- compute_projections indsp pkt.mind_typename rid nparamargs params
+ compute_projections indsp pkt.mind_typename rid nparamargs paramsctxt
pkt.mind_consnrealdecls pkt.mind_consnrealargs paramslet fields
in Some (Some (rid, kns, projs))
with UndefinableExpansion -> Some None)
@@ -880,7 +903,7 @@ let build_inductive env p prv ctx env_ar params kn isrecord isfinite inds nmr re
mind_hyps = hyps;
mind_nparams = nparamargs;
mind_nparams_rec = nmr;
- mind_params_ctxt = params;
+ mind_params_ctxt = paramsctxt;
mind_packets = packets;
mind_polymorphic = p;
mind_universes = ctx;
@@ -892,11 +915,11 @@ let build_inductive env p prv ctx env_ar params kn isrecord isfinite inds nmr re
let check_inductive env kn mie =
(* First type-check the inductive definition *)
- let (env_ar, env_ar_par, params, inds) = typecheck_inductive env mie in
+ let (env_ar, env_ar_par, paramsctxt, inds) = typecheck_inductive env mie in
(* Then check positivity conditions *)
- let (nmr,recargs) = check_positivity kn env_ar_par params inds in
+ let (nmr,recargs) = check_positivity kn env_ar_par paramsctxt mie.mind_entry_finite inds in
(* Build the inductive packets *)
build_inductive env mie.mind_entry_polymorphic mie.mind_entry_private
mie.mind_entry_universes
- env_ar params kn mie.mind_entry_record mie.mind_entry_finite
+ env_ar paramsctxt kn mie.mind_entry_record mie.mind_entry_finite
inds nmr recargs
diff --git a/kernel/inductive.ml b/kernel/inductive.ml
index 229508ea3..499cbf0df 100644
--- a/kernel/inductive.ml
+++ b/kernel/inductive.ml
@@ -480,7 +480,7 @@ type guard_env =
let make_renv env recarg tree =
{ env = env;
rel_min = recarg+2; (* recarg = 0 ==> Rel 1 -> recarg; Rel 2 -> fix *)
- genv = [Lazy.lazy_from_val(Subterm(Large,tree))] }
+ genv = [Lazy.from_val(Subterm(Large,tree))] }
let push_var renv (x,ty,spec) =
{ env = push_rel (LocalAssum (x,ty)) renv.env;
@@ -794,7 +794,15 @@ let rec subterm_specif renv stack t =
| Proj (p, c) ->
let subt = subterm_specif renv stack c in
(match subt with
- | Subterm (s, wf) -> Subterm (Strict, wf)
+ | Subterm (s, wf) ->
+ (* We take the subterm specs of the constructor of the record *)
+ let wf_args = (dest_subterms wf).(0) in
+ (* We extract the tree of the projected argument *)
+ let kn = Projection.constant p in
+ let cb = lookup_constant kn renv.env in
+ let pb = Option.get cb.const_proj in
+ let n = pb.proj_arg in
+ Subterm (Strict, List.nth wf_args n)
| Dead_code -> Dead_code
| Not_subterm -> Not_subterm)
@@ -809,7 +817,7 @@ and stack_element_specif = function
|SArg x -> x
and extract_stack renv a = function
- | [] -> Lazy.lazy_from_val Not_subterm , []
+ | [] -> Lazy.from_val Not_subterm , []
| h::t -> stack_element_specif h, t
(* Check term c can be applied to one of the mutual fixpoints. *)
diff --git a/kernel/kernel.mllib b/kernel/kernel.mllib
index f7220c94a..1e132e3ab 100644
--- a/kernel/kernel.mllib
+++ b/kernel/kernel.mllib
@@ -15,7 +15,6 @@ Copcodes
Cemitcodes
Nativevalues
Primitives
-Nativeinstr
Opaqueproof
Declareops
Retroknowledge
diff --git a/kernel/names.ml b/kernel/names.ml
index 0aa26fb9c..9abc9842a 100644
--- a/kernel/names.ml
+++ b/kernel/names.ml
@@ -36,7 +36,7 @@ struct
let check_soft ?(warn = true) x =
let iter (fatal, x) =
- if fatal then Errors.error x else if warn then Pp.msg_warning (str x)
+ if fatal then Errors.error x else if warn then Feedback.msg_warning (str x)
in
Option.iter iter (Unicode.ident_refutation x)
@@ -111,7 +111,7 @@ struct
let hashcons hident = function
| Name id -> Name (hident id)
| n -> n
- let equal n1 n2 =
+ let eq n1 n2 =
n1 == n2 ||
match (n1,n2) with
| (Name id1, Name id2) -> id1 == id2
@@ -245,7 +245,7 @@ struct
type t = _t
type u = (Id.t -> Id.t) * (DirPath.t -> DirPath.t)
let hashcons (hid,hdir) (n,s,dir) = (n,hid s,hdir dir)
- let equal ((n1,s1,dir1) as x) ((n2,s2,dir2) as y) =
+ let eq ((n1,s1,dir1) as x) ((n2,s2,dir2) as y) =
(x == y) ||
(Int.equal n1 n2 && s1 == s2 && dir1 == dir2)
let hash = hash
@@ -341,7 +341,7 @@ module ModPath = struct
| MPfile dir -> MPfile (hdir dir)
| MPbound m -> MPbound (huniqid m)
| MPdot (md,l) -> MPdot (hashcons hfuns md, hstr l)
- let rec equal d1 d2 =
+ let eq d1 d2 =
d1 == d2 ||
match d1,d2 with
| MPfile dir1, MPfile dir2 -> dir1 == dir2
@@ -441,7 +441,7 @@ module KerName = struct
let hashcons (hmod,hdir,hstr) kn =
let { modpath = mp; dirpath = dp; knlabel = l; refhash; } = kn in
{ modpath = hmod mp; dirpath = hdir dp; knlabel = hstr l; refhash; canary; }
- let equal kn1 kn2 =
+ let eq kn1 kn2 =
kn1.modpath == kn2.modpath && kn1.dirpath == kn2.dirpath &&
kn1.knlabel == kn2.knlabel
let hash = hash
@@ -495,7 +495,7 @@ module KerPair = struct
| Dual (kn,_) -> kn
let same kn = Same kn
- let make knu knc = if knu == knc then Same knc else Dual (knu,knc)
+ let make knu knc = if KerName.equal knu knc then Same knc else Dual (knu,knc)
let make1 = same
let make2 mp l = same (KerName.make2 mp l)
@@ -542,6 +542,23 @@ module KerPair = struct
let hash x = KerName.hash (canonical x)
end
+ module SyntacticOrd = struct
+ type t = kernel_pair
+ let compare x y = match x, y with
+ | Same knx, Same kny -> KerName.compare knx kny
+ | Dual (knux,kncx), Dual (knuy,kncy) ->
+ let c = KerName.compare knux knuy in
+ if not (Int.equal c 0) then c
+ else KerName.compare kncx kncy
+ | Same _, _ -> -1
+ | Dual _, _ -> 1
+ let equal x y = x == y || compare x y = 0
+ let hash = function
+ | Same kn -> KerName.hash kn
+ | Dual (knu, knc) ->
+ Hashset.Combine.combine (KerName.hash knu) (KerName.hash knc)
+ end
+
(** Default (logical) comparison and hash is on the canonical part *)
let equal = CanOrd.equal
let hash = CanOrd.hash
@@ -553,7 +570,7 @@ module KerPair = struct
let hashcons hkn = function
| Same kn -> Same (hkn kn)
| Dual (knu,knc) -> make (hkn knu) (hkn knc)
- let equal x y = (* physical comparison on subterms *)
+ let eq x y = (* physical comparison on subterms *)
x == y ||
match x,y with
| Same x, Same y -> x == y
@@ -613,6 +630,8 @@ let index_of_constructor (ind, i) = i
let eq_ind (m1, i1) (m2, i2) = Int.equal i1 i2 && MutInd.equal m1 m2
let eq_user_ind (m1, i1) (m2, i2) =
Int.equal i1 i2 && MutInd.UserOrd.equal m1 m2
+let eq_syntactic_ind (m1, i1) (m2, i2) =
+ Int.equal i1 i2 && MutInd.SyntacticOrd.equal m1 m2
let ind_ord (m1, i1) (m2, i2) =
let c = Int.compare i1 i2 in
@@ -620,15 +639,22 @@ let ind_ord (m1, i1) (m2, i2) =
let ind_user_ord (m1, i1) (m2, i2) =
let c = Int.compare i1 i2 in
if Int.equal c 0 then MutInd.UserOrd.compare m1 m2 else c
+let ind_syntactic_ord (m1, i1) (m2, i2) =
+ let c = Int.compare i1 i2 in
+ if Int.equal c 0 then MutInd.SyntacticOrd.compare m1 m2 else c
let ind_hash (m, i) =
Hashset.Combine.combine (MutInd.hash m) (Int.hash i)
let ind_user_hash (m, i) =
Hashset.Combine.combine (MutInd.UserOrd.hash m) (Int.hash i)
+let ind_syntactic_hash (m, i) =
+ Hashset.Combine.combine (MutInd.SyntacticOrd.hash m) (Int.hash i)
let eq_constructor (ind1, j1) (ind2, j2) = Int.equal j1 j2 && eq_ind ind1 ind2
let eq_user_constructor (ind1, j1) (ind2, j2) =
Int.equal j1 j2 && eq_user_ind ind1 ind2
+let eq_syntactic_constructor (ind1, j1) (ind2, j2) =
+ Int.equal j1 j2 && eq_syntactic_ind ind1 ind2
let constructor_ord (ind1, j1) (ind2, j2) =
let c = Int.compare j1 j2 in
@@ -636,11 +662,16 @@ let constructor_ord (ind1, j1) (ind2, j2) =
let constructor_user_ord (ind1, j1) (ind2, j2) =
let c = Int.compare j1 j2 in
if Int.equal c 0 then ind_user_ord ind1 ind2 else c
+let constructor_syntactic_ord (ind1, j1) (ind2, j2) =
+ let c = Int.compare j1 j2 in
+ if Int.equal c 0 then ind_syntactic_ord ind1 ind2 else c
let constructor_hash (ind, i) =
Hashset.Combine.combine (ind_hash ind) (Int.hash i)
let constructor_user_hash (ind, i) =
Hashset.Combine.combine (ind_user_hash ind) (Int.hash i)
+let constructor_syntactic_hash (ind, i) =
+ Hashset.Combine.combine (ind_syntactic_hash ind) (Int.hash i)
module InductiveOrdered = struct
type t = inductive
@@ -685,7 +716,7 @@ module Hind = Hashcons.Make(
type t = inductive
type u = MutInd.t -> MutInd.t
let hashcons hmind (mind, i) = (hmind mind, i)
- let equal (mind1,i1) (mind2,i2) = mind1 == mind2 && Int.equal i1 i2
+ let eq (mind1,i1) (mind2,i2) = mind1 == mind2 && Int.equal i1 i2
let hash = ind_hash
end)
@@ -694,7 +725,7 @@ module Hconstruct = Hashcons.Make(
type t = constructor
type u = inductive -> inductive
let hashcons hind (ind, j) = (hind ind, j)
- let equal (ind1, j1) (ind2, j2) = ind1 == ind2 && Int.equal j1 j2
+ let eq (ind1, j1) (ind2, j2) = ind1 == ind2 && Int.equal j1 j2
let hash = constructor_hash
end)
@@ -828,13 +859,22 @@ struct
let hash (c, b) = (if b then 0 else 1) + Constant.hash c
+ module SyntacticOrd = struct
+ type t = constant * bool
+ let compare (c, b) (c', b') =
+ if b = b' then Constant.SyntacticOrd.compare c c' else -1
+ let equal (c, b as x) (c', b' as x') =
+ x == x' || b = b' && Constant.SyntacticOrd.equal c c'
+ let hash (c, b) = (if b then 0 else 1) + Constant.SyntacticOrd.hash c
+ end
+
module Self_Hashcons =
struct
type _t = t
type t = _t
type u = Constant.t -> Constant.t
let hashcons hc (c,b) = (hc c,b)
- let equal ((c,b) as x) ((c',b') as y) =
+ let eq ((c,b) as x) ((c',b') as y) =
x == y || (c == c' && b == b')
let hash = hash
end
diff --git a/kernel/names.mli b/kernel/names.mli
index 6380b17fb..feaedc775 100644
--- a/kernel/names.mli
+++ b/kernel/names.mli
@@ -6,6 +6,20 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** This file defines a lot of different notions of names used pervasively in
+ the kernel as well as in other places. The essential datatypes exported by
+ this API are:
+
+ - Id.t is the type of identifiers, that is morally a subset of strings which
+ only contains Unicode characters of the Letter kind (and a few more).
+ - Name.t is an ad-hoc variant of Id.t option allowing to handle optionally
+ named objects.
+ - DirPath.t represents generic paths as sequences of identifiers.
+ - Label.t is an equivalent of Id.t made distinct for semantical purposes.
+ - ModPath.t are module paths.
+ - KerName.t are absolute names of objects in Coq.
+*)
+
open Util
(** {6 Identifiers } *)
@@ -325,6 +339,12 @@ sig
val hash : t -> int
end
+ module SyntacticOrd : sig
+ val compare : t -> t -> int
+ val equal : t -> t -> bool
+ val hash : t -> int
+ end
+
val equal : t -> t -> bool
(** Default comparison, alias for [CanOrd.equal] *)
@@ -399,6 +419,12 @@ sig
val hash : t -> int
end
+ module SyntacticOrd : sig
+ val compare : t -> t -> int
+ val equal : t -> t -> bool
+ val hash : t -> int
+ end
+
val equal : t -> t -> bool
(** Default comparison, alias for [CanOrd.equal] *)
@@ -442,16 +468,22 @@ val inductive_of_constructor : constructor -> inductive
val index_of_constructor : constructor -> int
val eq_ind : inductive -> inductive -> bool
val eq_user_ind : inductive -> inductive -> bool
+val eq_syntactic_ind : inductive -> inductive -> bool
val ind_ord : inductive -> inductive -> int
val ind_hash : inductive -> int
val ind_user_ord : inductive -> inductive -> int
val ind_user_hash : inductive -> int
+val ind_syntactic_ord : inductive -> inductive -> int
+val ind_syntactic_hash : inductive -> int
val eq_constructor : constructor -> constructor -> bool
val eq_user_constructor : constructor -> constructor -> bool
+val eq_syntactic_constructor : constructor -> constructor -> bool
val constructor_ord : constructor -> constructor -> int
-val constructor_user_ord : constructor -> constructor -> int
val constructor_hash : constructor -> int
+val constructor_user_ord : constructor -> constructor -> int
val constructor_user_hash : constructor -> int
+val constructor_syntactic_ord : constructor -> constructor -> int
+val constructor_syntactic_hash : constructor -> int
(** Better to have it here that in Closure, since required in grammar.cma *)
type evaluable_global_reference =
@@ -665,6 +697,12 @@ module Projection : sig
val make : constant -> bool -> t
+ module SyntacticOrd : sig
+ val compare : t -> t -> int
+ val equal : t -> t -> bool
+ val hash : t -> int
+ end
+
val constant : t -> constant
val unfolded : t -> bool
val unfold : t -> t
@@ -742,7 +780,7 @@ val mind_of_kn : KerName.t -> mutual_inductive
(** @deprecated Same as [MutInd.make1] *)
val mind_of_kn_equiv : KerName.t -> KerName.t -> mutual_inductive
-(** @deprecated Same as [MutInd.make2] *)
+(** @deprecated Same as [MutInd.make] *)
val make_mind : ModPath.t -> DirPath.t -> Label.t -> mutual_inductive
(** @deprecated Same as [MutInd.make3] *)
diff --git a/kernel/nativecode.ml b/kernel/nativecode.ml
index dabe905de..44cf21cff 100644
--- a/kernel/nativecode.ml
+++ b/kernel/nativecode.ml
@@ -1486,8 +1486,8 @@ let optimize_stk stk =
(** Printing to ocaml **)
(* Redefine a bunch of functions in module Names to generate names
acceptable to OCaml. *)
-let string_of_id s = Unicode.ascii_of_ident (string_of_id s)
-let string_of_label l = Unicode.ascii_of_ident (string_of_label l)
+let string_of_id s = Unicode.ascii_of_ident (Id.to_string s)
+let string_of_label l = string_of_id (Label.to_id l)
let string_of_dirpath = function
| [] -> "_"
@@ -1560,8 +1560,7 @@ let pp_gname fmt g =
Format.fprintf fmt "%s" (string_of_gname g)
let pp_lname fmt ln =
- let s = Unicode.ascii_of_ident (string_of_name ln.lname) in
- Format.fprintf fmt "x_%s_%i" s ln.luid
+ Format.fprintf fmt "x_%s_%i" (string_of_name ln.lname) ln.luid
let pp_ldecls fmt ids =
let len = Array.length ids in
@@ -1864,7 +1863,7 @@ let compile_constant env sigma prefix ~interactive con cb =
| Def t ->
let t = Mod_subst.force_constr t in
let code = lambda_of_constr env sigma t in
- if !Flags.debug then Pp.msg_debug (Pp.str "Generated lambda code");
+ if !Flags.debug then Feedback.msg_debug (Pp.str "Generated lambda code");
let is_lazy = is_lazy prefix t in
let code = if is_lazy then mk_lazy code else code in
let name =
@@ -1879,11 +1878,11 @@ let compile_constant env sigma prefix ~interactive con cb =
let (auxdefs,code) = compile_with_fv env sigma (Some univ) [] (Some l) code in
(auxdefs,mkMLlam [|univ|] code)
in
- if !Flags.debug then Pp.msg_debug (Pp.str "Generated mllambda code");
+ if !Flags.debug then Feedback.msg_debug (Pp.str "Generated mllambda code");
let code =
optimize_stk (Glet(Gconstant ("",(con,u)),code)::auxdefs)
in
- if !Flags.debug then Pp.msg_debug (Pp.str "Optimized mllambda code");
+ if !Flags.debug then Feedback.msg_debug (Pp.str "Optimized mllambda code");
code, name
| _ ->
let i = push_symbol (SymbConst con) in
diff --git a/kernel/nativeconv.ml b/kernel/nativeconv.ml
index 7ac5b8d7b..a0ff9e123 100644
--- a/kernel/nativeconv.ml
+++ b/kernel/nativeconv.ml
@@ -7,7 +7,6 @@
(************************************************************************)
open Errors
open Names
-open Univ
open Nativelib
open Reduction
open Util
@@ -135,12 +134,12 @@ let native_conv_gen pb sigma env univs t1 t2 =
match compile ml_filename code with
| (true, fn) ->
begin
- if !Flags.debug then Pp.msg_debug (Pp.str "Running test...");
+ if !Flags.debug then Feedback.msg_debug (Pp.str "Running test...");
let t0 = Sys.time () in
call_linker ~fatal:true prefix fn (Some upds);
let t1 = Sys.time () in
let time_info = Format.sprintf "Evaluation done in %.5f@." (t1 -. t0) in
- if !Flags.debug then Pp.msg_debug (Pp.str time_info);
+ if !Flags.debug then Feedback.msg_debug (Pp.str time_info);
(* TODO change 0 when we can have deBruijn *)
fst (conv_val env pb 0 !rt1 !rt2 univs)
end
@@ -150,7 +149,7 @@ let native_conv_gen pb sigma env univs t1 t2 =
let native_conv cv_pb sigma env t1 t2 =
if Coq_config.no_native_compiler then begin
let msg = "Native compiler is disabled, falling back to VM conversion test." in
- Pp.msg_warning (Pp.str msg);
+ Feedback.msg_warning (Pp.str msg);
vm_conv cv_pb env t1 t2
end
else
diff --git a/kernel/nativelib.ml b/kernel/nativelib.ml
index 4296b73ab..5b92e9554 100644
--- a/kernel/nativelib.ml
+++ b/kernel/nativelib.ml
@@ -73,20 +73,20 @@ let call_compiler ml_filename =
::"-w"::"a"
::include_dirs
@ ["-impl"; ml_filename] in
- if !Flags.debug then Pp.msg_debug (Pp.str (ocamlfind () ^ " " ^ (String.concat " " args)));
+ if !Flags.debug then Feedback.msg_debug (Pp.str (ocamlfind () ^ " " ^ (String.concat " " args)));
try
let res = CUnix.sys_command (ocamlfind ()) args in
let res = match res with
| Unix.WEXITED 0 -> true
| Unix.WEXITED n ->
- Pp.(msg_warning (str "command exited with status " ++ int n)); false
+ Feedback.msg_warning Pp.(str "command exited with status " ++ int n); false
| Unix.WSIGNALED n ->
- Pp.(msg_warning (str "command killed by signal " ++ int n)); false
+ Feedback.msg_warning Pp.(str "command killed by signal " ++ int n); false
| Unix.WSTOPPED n ->
- Pp.(msg_warning (str "command stopped by signal " ++ int n)); false in
+ Feedback.msg_warning Pp.(str "command stopped by signal " ++ int n); false in
res, link_filename
with Unix.Unix_error (e,_,_) ->
- Pp.(msg_warning (str (Unix.error_message e)));
+ Feedback.msg_warning Pp.(str (Unix.error_message e));
false, link_filename
let compile fn code =
@@ -120,7 +120,7 @@ let call_linker ?(fatal=true) prefix f upds =
begin
let msg = "Cannot find native compiler file " ^ f in
if fatal then Errors.error msg
- else if !Flags.debug then Pp.msg_debug (Pp.str msg)
+ else if !Flags.debug then Feedback.msg_debug (Pp.str msg)
end
else
(try
@@ -129,8 +129,8 @@ let call_linker ?(fatal=true) prefix f upds =
with Dynlink.Error e as exn ->
let exn = Errors.push exn in
let msg = "Dynlink error, " ^ Dynlink.error_message e in
- if fatal then (Pp.msg_error (Pp.str msg); iraise exn)
- else if !Flags.debug then Pp.msg_debug (Pp.str msg));
+ if fatal then (Feedback.msg_error (Pp.str msg); iraise exn)
+ else if !Flags.debug then Feedback.msg_debug (Pp.str msg));
match upds with Some upds -> update_locations upds | _ -> ()
let link_library ~prefix ~dirname ~basename =
diff --git a/kernel/nativelibrary.ml b/kernel/nativelibrary.ml
index 9d159be64..246b00da4 100644
--- a/kernel/nativelibrary.ml
+++ b/kernel/nativelibrary.ml
@@ -29,13 +29,13 @@ and translate_field prefix mp env acc (l,x) =
let con = make_con mp empty_dirpath l in
(if !Flags.debug then
let msg = Printf.sprintf "Compiling constant %s..." (Constant.to_string con) in
- Pp.msg_debug (Pp.str msg));
+ Feedback.msg_debug (Pp.str msg));
compile_constant_field (pre_env env) prefix con acc cb
| SFBmind mb ->
(if !Flags.debug then
let id = mb.mind_packets.(0).mind_typename in
let msg = Printf.sprintf "Compiling inductive %s..." (Id.to_string id) in
- Pp.msg_debug (Pp.str msg));
+ Feedback.msg_debug (Pp.str msg));
compile_mind_field prefix mp l acc mb
| SFBmodule md ->
let mp = md.mod_mp in
@@ -43,7 +43,7 @@ and translate_field prefix mp env acc (l,x) =
let msg =
Printf.sprintf "Compiling module %s..." (ModPath.to_string mp)
in
- Pp.msg_debug (Pp.str msg));
+ Feedback.msg_debug (Pp.str msg));
translate_mod prefix mp env md.mod_type acc
| SFBmodtype mdtyp ->
let mp = mdtyp.mod_mp in
@@ -51,11 +51,11 @@ and translate_field prefix mp env acc (l,x) =
let msg =
Printf.sprintf "Compiling module type %s..." (ModPath.to_string mp)
in
- Pp.msg_debug (Pp.str msg));
+ Feedback.msg_debug (Pp.str msg));
translate_mod prefix mp env mdtyp.mod_type acc
let dump_library mp dp env mod_expr =
- if !Flags.debug then Pp.msg_debug (Pp.str "Compiling library...");
+ if !Flags.debug then Feedback.msg_debug (Pp.str "Compiling library...");
match mod_expr with
| NoFunctor struc ->
let env = add_structure mp struc empty_delta_resolver env in
diff --git a/kernel/pre_env.ml b/kernel/pre_env.ml
index 99d99e694..c30789641 100644
--- a/kernel/pre_env.ml
+++ b/kernel/pre_env.ml
@@ -15,7 +15,6 @@
open Util
open Names
-open Univ
open Term
open Declarations
open Context.Named.Declaration
@@ -25,7 +24,7 @@ open Context.Named.Declaration
(* The key attached to each constant is used by the VM to retrieve previous *)
(* evaluations of the constant. It is essentially an index in the symbols table *)
(* used by the VM. *)
-type key = int Ephemeron.key option ref
+type key = int CEphemeron.key option ref
(** Linking information for the native compiler. *)
@@ -50,17 +49,17 @@ type stratification = {
}
type val_kind =
- | VKvalue of (values * Id.Set.t) Ephemeron.key
+ | VKvalue of (values * Id.Set.t) CEphemeron.key
| VKnone
type lazy_val = val_kind ref
let force_lazy_val vk = match !vk with
| VKnone -> None
-| VKvalue v -> try Some (Ephemeron.get v) with Ephemeron.InvalidKey -> None
+| VKvalue v -> try Some (CEphemeron.get v) with CEphemeron.InvalidKey -> None
let dummy_lazy_val () = ref VKnone
-let build_lazy_val vk key = vk := VKvalue (Ephemeron.create key)
+let build_lazy_val vk key = vk := VKvalue (CEphemeron.create key)
type named_vals = (Id.t * lazy_val) list
diff --git a/kernel/pre_env.mli b/kernel/pre_env.mli
index f626aa0d3..353c46112 100644
--- a/kernel/pre_env.mli
+++ b/kernel/pre_env.mli
@@ -17,7 +17,7 @@ type link_info =
| LinkedInteractive of string
| NotLinked
-type key = int Ephemeron.key option ref
+type key = int CEphemeron.key option ref
type constant_key = constant_body * (link_info ref * key)
diff --git a/kernel/reduction.ml b/kernel/reduction.ml
index cfc286135..30a346c91 100644
--- a/kernel/reduction.ml
+++ b/kernel/reduction.ml
@@ -20,7 +20,6 @@ open Util
open Names
open Term
open Vars
-open Univ
open Environ
open Closure
open Esubst
@@ -177,7 +176,7 @@ let convert_instances ~flex u u' (s, check) =
let conv_table_key infos k1 k2 cuniv =
if k1 == k2 then cuniv else
match k1, k2 with
- | ConstKey (cst, u), ConstKey (cst', u') when eq_constant_key cst cst' ->
+ | ConstKey (cst, u), ConstKey (cst', u') when Constant.equal cst cst' ->
if Univ.Instance.equal u u' then cuniv
else
let flex = evaluable_constant cst (info_env infos)
@@ -682,7 +681,7 @@ let vm_conv cv_pb env t1 t2 =
try
!vm_conv cv_pb env t1 t2
with Not_found | Invalid_argument _ ->
- Pp.msg_warning (Pp.str "Bytecode compilation failed, falling back to standard conversion");
+ Feedback.msg_warning (Pp.str "Bytecode compilation failed, falling back to standard conversion");
gen_conv cv_pb env t1 t2
let default_conv cv_pb ?(l2r=false) env t1 t2 =
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index 8a402322f..ce05190b6 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -225,11 +225,11 @@ let side_effects_of_private_constants x = Term_typing.uniq_seff (List.rev x)
let private_con_of_con env c =
let cbo = Environ.lookup_constant c env.env in
- { Entries.from_env = Ephemeron.create env.revstruct;
+ { Entries.from_env = CEphemeron.create env.revstruct;
Entries.eff = Entries.SEsubproof (c,cbo,get_opaque_body env.env cbo) }
let private_con_of_scheme ~kind env cl =
- { Entries.from_env = Ephemeron.create env.revstruct;
+ { Entries.from_env = CEphemeron.create env.revstruct;
Entries.eff = Entries.SEscheme(
List.map (fun (i,c) ->
let cbo = Environ.lookup_constant c env.env in
diff --git a/kernel/sorts.ml b/kernel/sorts.ml
index a90736884..62013b38f 100644
--- a/kernel/sorts.ml
+++ b/kernel/sorts.ml
@@ -98,7 +98,7 @@ module Hsorts =
let u' = huniv u in
if u' == u then c else Type u'
| s -> s
- let equal s1 s2 = match (s1,s2) with
+ let eq s1 s2 = match (s1,s2) with
| (Prop c1, Prop c2) -> c1 == c2
| (Type u1, Type u2) -> u1 == u2
|_ -> false
diff --git a/kernel/term_typing.ml b/kernel/term_typing.ml
index 2a3ac957f..6bfd2457a 100644
--- a/kernel/term_typing.ml
+++ b/kernel/term_typing.ml
@@ -125,14 +125,14 @@ let check_signatures curmb sl =
| None -> None, None
| Some curmb ->
try
- let mb = Ephemeron.get mb in
+ let mb = CEphemeron.get mb in
match sl with
| None -> sl, None
| Some n ->
if List.length mb >= how_many && CList.skipn how_many mb == curmb
then Some (n + how_many), Some mb
else None, None
- with Ephemeron.InvalidKey -> None, None in
+ with CEphemeron.InvalidKey -> None, None in
let sl, _ = List.fold_left is_direct_ancestor (Some 0,Some curmb) sl in
sl
@@ -167,8 +167,10 @@ let hcons_j j =
{ uj_val = hcons_constr j.uj_val; uj_type = hcons_constr j.uj_type}
let feedback_completion_typecheck =
- Option.iter (fun state_id -> Pp.feedback ~state_id Feedback.Complete)
-
+ let open Feedback in
+ Option.iter (fun state_id ->
+ feedback ~id:(State state_id) Feedback.Complete)
+
let infer_declaration ~trust env kn dcl =
match dcl with
| ParameterEntry (ctx,poly,(t,uctx),nl) ->
diff --git a/kernel/univ.ml b/kernel/univ.ml
index 9d62c9af5..126f95f1f 100644
--- a/kernel/univ.ml
+++ b/kernel/univ.ml
@@ -35,7 +35,7 @@ module type Hashconsed =
sig
type t
val hash : t -> int
- val equal : t -> t -> bool
+ val eq : t -> t -> bool
val hcons : t -> t
end
@@ -53,7 +53,7 @@ struct
type t = _t
type u = (M.t -> M.t)
let hash = function Nil -> 0 | Cons (_, h, _) -> h
- let equal l1 l2 = match l1, l2 with
+ let eq l1 l2 = match l1, l2 with
| Nil, Nil -> true
| Cons (x1, _, l1), Cons (x2, _, l2) -> x1 == x2 && l1 == l2
| _ -> false
@@ -135,12 +135,12 @@ module HList = struct
let rec remove x = function
| Nil -> nil
| Cons (y, _, l) ->
- if H.equal x y then l
+ if H.eq x y then l
else cons y (remove x l)
let rec mem x = function
| Nil -> false
- | Cons (y, _, l) -> H.equal x y || mem x l
+ | Cons (y, _, l) -> H.eq x y || mem x l
let rec compare cmp l1 l2 = match l1, l2 with
| Nil, Nil -> 0
@@ -251,7 +251,7 @@ module Level = struct
type _t = t
type t = _t
type u = unit
- let equal x y = x.hash == y.hash && RawLevel.hequal x.data y.data
+ let eq x y = x.hash == y.hash && RawLevel.hequal x.data y.data
let hash x = x.hash
let hashcons () x =
let data' = RawLevel.hcons x.data in
@@ -400,7 +400,7 @@ struct
let hashcons hdir (b,n as x) =
let b' = hdir b in
if b' == b then x else (b',n)
- let equal l1 l2 =
+ let eq l1 l2 =
l1 == l2 ||
match l1,l2 with
| (b,n), (b',n') -> b == b' && n == n'
@@ -419,7 +419,7 @@ struct
let hcons =
Hashcons.simple_hcons H.generate H.hcons Level.hcons
let hash = ExprHash.hash
- let equal x y = x == y ||
+ let eq x y = x == y ||
(let (u,n) = x and (v,n') = y in
Int.equal n n' && Level.equal u v)
@@ -724,7 +724,7 @@ module Hconstraint =
type t = univ_constraint
type u = universe_level -> universe_level
let hashcons hul (l1,k,l2) = (hul l1, k, hul l2)
- let equal (l1,k,l2) (l1',k',l2') =
+ let eq (l1,k,l2) (l1',k',l2') =
l1 == l1' && k == k' && l2 == l2'
let hash = Hashtbl.hash
end)
@@ -736,7 +736,7 @@ module Hconstraints =
type u = univ_constraint -> univ_constraint
let hashcons huc s =
Constraint.fold (fun x -> Constraint.add (huc x)) s Constraint.empty
- let equal s s' =
+ let eq s s' =
List.for_all2eq (==)
(Constraint.elements s)
(Constraint.elements s')
@@ -901,7 +901,7 @@ struct
a
end
- let equal t1 t2 =
+ let eq t1 t2 =
t1 == t2 ||
(Int.equal (Array.length t1) (Array.length t2) &&
let rec aux i =
@@ -1235,7 +1235,7 @@ module Huniverse_set =
type u = universe_level -> universe_level
let hashcons huc s =
LSet.fold (fun x -> LSet.add (huc x)) s LSet.empty
- let equal s s' =
+ let eq s s' =
LSet.equal s s'
let hash = Hashtbl.hash
end)
diff --git a/kernel/vconv.ml b/kernel/vconv.ml
index 4610dbcb0..53db6f5be 100644
--- a/kernel/vconv.ml
+++ b/kernel/vconv.ml
@@ -1,13 +1,9 @@
open Util
open Names
-open Term
open Environ
-open Conv_oracle
open Reduction
-open Closure
open Vm
open Csymtable
-open Univ
let val_of_constr env c =
val_of_constr (pre_env env) c
@@ -189,7 +185,7 @@ let vm_conv_gen cv_pb env univs t1 t2 =
let v2 = val_of_constr env t2 in
fst (conv_val env cv_pb (nb_rel env) v1 v2 univs)
with Not_found | Invalid_argument _ ->
- (Pp.msg_warning
+ (Feedback.msg_warning
(Pp.str "Bytecode compilation failed, falling back to default conversion");
Reduction.generic_conv cv_pb ~l2r:false (fun _ -> None)
full_transparent_state env univs t1 t2)
diff --git a/lib/aux_file.ml b/lib/aux_file.ml
index f7bd81f85..096305b98 100644
--- a/lib/aux_file.ml
+++ b/lib/aux_file.ml
@@ -25,9 +25,9 @@ let mk_absolute vfile =
if Filename.is_relative vfile then CUnix.correct_path vfile (Sys.getcwd ())
else vfile
-let start_aux_file_for vfile =
- let vfile = mk_absolute vfile in
- oc := Some (open_out (aux_file_name_for vfile));
+let start_aux_file ~aux_file:output_file ~v_file =
+ let vfile = mk_absolute v_file in
+ oc := Some (open_out output_file);
Printf.fprintf (Option.get !oc) "COQAUX%d %s %s\n"
version (Digest.to_hex (Digest.file vfile)) vfile
@@ -88,7 +88,7 @@ let load_aux_file_for vfile =
| Sys_error s | Scanf.Scan_failure s
| Failure s | Invalid_argument s ->
Flags.if_verbose
- Pp.msg_warning Pp.(str"Loading file "++str aux_fname++str": "++str s);
+ Feedback.msg_warning Pp.(str"Loading file "++str aux_fname++str": "++str s);
empty_aux_file
let set h loc k v = set h (Loc.unloc loc) k v
diff --git a/lib/aux_file.mli b/lib/aux_file.mli
index 127827ab6..86e322b71 100644
--- a/lib/aux_file.mli
+++ b/lib/aux_file.mli
@@ -17,7 +17,8 @@ module H : Map.S with type key = int * int
module M : Map.S with type key = string
val contents : aux_file -> string M.t H.t
-val start_aux_file_for : string -> unit
+val aux_file_name_for : string -> string
+val start_aux_file : aux_file:string -> v_file:string -> unit
val stop_aux_file : unit -> unit
val recording : unit -> bool
diff --git a/lib/ephemeron.ml b/lib/cEphemeron.ml
index a38ea11e1..a38ea11e1 100644
--- a/lib/ephemeron.ml
+++ b/lib/cEphemeron.ml
diff --git a/lib/ephemeron.mli b/lib/cEphemeron.mli
index 1200e4e20..1200e4e20 100644
--- a/lib/ephemeron.mli
+++ b/lib/cEphemeron.mli
diff --git a/lib/cSet.ml b/lib/cSet.ml
index 3eeff29fe..037cdc356 100644
--- a/lib/cSet.ml
+++ b/lib/cSet.ml
@@ -57,7 +57,7 @@ struct
open Hashset.Combine
type t = set
type u = M.t -> M.t
- let equal s1 s2 = s1 == s2 || eqeq (spine s1 []) (spine s2 [])
+ let eq s1 s2 = s1 == s2 || eqeq (spine s1 []) (spine s2 [])
let hash s = Set.fold (fun v accu -> combine (H.hash v) accu) s 0
let hashcons = umap
end
diff --git a/lib/clib.mllib b/lib/clib.mllib
index 3c1c5da33..1e33173ee 100644
--- a/lib/clib.mllib
+++ b/lib/clib.mllib
@@ -21,20 +21,16 @@ Control
Loc
CList
CString
-Serialize
Deque
CObj
CArray
CStack
Util
Stateid
-Feedback
Pp
Ppstyle
-Xml_lexer
-Xml_parser
-Xml_printer
Richpp
+Feedback
CUnix
Envars
Aux_file
diff --git a/lib/dyn.ml b/lib/dyn.ml
index 676467e46..65d1442ac 100644
--- a/lib/dyn.ml
+++ b/lib/dyn.ml
@@ -11,7 +11,7 @@ sig
type 'a t
end
-module type S =
+module type PreS =
sig
type 'a tag
type t = Dyn : 'a tag * 'a -> t
@@ -44,10 +44,23 @@ sig
end
val dump : unit -> (int * string) list
+
end
-module Make(M : CSig.EmptyS) =
-struct
+module type S =
+sig
+ include PreS
+
+ module Easy : sig
+ val make_dyn : string -> ('a -> t) * (t -> 'a)
+ val inj : 'a -> 'a tag -> t
+ val prj : t -> 'a tag -> 'a option
+ end
+
+end
+
+module Make(M : CSig.EmptyS) = struct
+module Self : PreS = struct
(* Dynamics, programmed with DANGER !!! *)
type 'a tag = int
@@ -108,3 +121,28 @@ let fold f m accu = Int.Map.fold (fun k v accu -> f (Any (k, v)) accu) m accu
end
end
+include Self
+
+module Easy = struct
+(* now tags are opaque, we can do the trick *)
+let make_dyn (s : string) =
+ (fun (type a) (tag : a tag) ->
+ let infun : (a -> t) = fun x -> Dyn (tag, x) in
+ let outfun : (t -> a) = fun (Dyn (t, x)) ->
+ match eq tag t with
+ | None -> assert false
+ | Some CSig.Refl -> x
+ in
+ (infun, outfun))
+ (create s)
+
+let inj x tag = Dyn(tag,x)
+let prj : type a. t -> a tag -> a option =
+ fun (Dyn(tag',x)) tag ->
+ match eq tag tag' with
+ | None -> None
+ | Some CSig.Refl -> Some x
+end
+
+end
+
diff --git a/lib/dyn.mli b/lib/dyn.mli
index c94fa764b..448b11a18 100644
--- a/lib/dyn.mli
+++ b/lib/dyn.mli
@@ -6,7 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(** Dynamics. Use with extreme care. Not for kids. *)
+(** Dynamically typed values *)
+
module type TParam =
sig
type 'a t
@@ -46,6 +47,16 @@ end
val dump : unit -> (int * string) list
+module Easy : sig
+
+ (* To create a dynamic type on the fly *)
+ val make_dyn : string -> ('a -> t) * (t -> 'a)
+
+ (* For types declared with the [create] function above *)
+ val inj : 'a -> 'a tag -> t
+ val prj : t -> 'a tag -> 'a option
+end
+
end
(** FIXME: use OCaml 4.02 generative functors when available *)
diff --git a/lib/errors.ml b/lib/errors.ml
index c1d224dfc..8982dde14 100644
--- a/lib/errors.ml
+++ b/lib/errors.ml
@@ -16,6 +16,13 @@ let push = Backtrace.add_backtrace
exception Anomaly of string option * std_ppcmds (* System errors *)
+let _ =
+ let pr = function
+ | Anomaly (s, pp) -> Some ("\"Anomaly: " ^ string_of_ppcmds pp ^ "\"")
+ | _ -> None
+ in
+ Printexc.register_printer pr
+
let make_anomaly ?label pp =
Anomaly (label, pp)
diff --git a/lib/explore.ml b/lib/explore.ml
index 587db1156..aa7bddf2b 100644
--- a/lib/explore.ml
+++ b/lib/explore.ml
@@ -27,7 +27,7 @@ module Make = functor(S : SearchProblem) -> struct
| [i] -> int i
| i :: l -> pp_rec l ++ str "." ++ int i
in
- msg_debug (h 0 (pp_rec p) ++ pp)
+ Feedback.msg_debug (h 0 (pp_rec p) ++ pp)
(*s Depth first search. *)
diff --git a/lib/feedback.ml b/lib/feedback.ml
index 1a90685de..d6f580fd1 100644
--- a/lib/feedback.ml
+++ b/lib/feedback.ml
@@ -7,51 +7,14 @@
(************************************************************************)
open Xml_datatype
-open Serialize
-type message_level =
+type level =
| Debug of string
| Info
| Notice
| Warning
| Error
-type message = {
- message_level : message_level;
- message_content : xml;
-}
-
-let of_message_level = function
- | Debug s ->
- Serialize.constructor "message_level" "debug" [Xml_datatype.PCData s]
- | Info -> Serialize.constructor "message_level" "info" []
- | Notice -> Serialize.constructor "message_level" "notice" []
- | Warning -> Serialize.constructor "message_level" "warning" []
- | Error -> Serialize.constructor "message_level" "error" []
-let to_message_level =
- Serialize.do_match "message_level" (fun s args -> match s with
- | "debug" -> Debug (Serialize.raw_string args)
- | "info" -> Info
- | "notice" -> Notice
- | "warning" -> Warning
- | "error" -> Error
- | _ -> raise Serialize.Marshal_error)
-
-let of_message msg =
- let lvl = of_message_level msg.message_level in
- let content = Serialize.of_xml msg.message_content in
- Xml_datatype.Element ("message", [], [lvl; content])
-let to_message xml = match xml with
- | Xml_datatype.Element ("message", [], [lvl; content]) -> {
- message_level = to_message_level lvl;
- message_content = Serialize.to_xml content }
- | _ -> raise Serialize.Marshal_error
-
-let is_message = function
- | Xml_datatype.Element ("message", _, _) -> true
- | _ -> false
-
-
type edit_id = int
type state_id = Stateid.t
type edit_or_state_id = Edit of edit_id | State of state_id
@@ -71,8 +34,10 @@ type feedback_content =
| GlobDef of Loc.t * string * string * string
| FileDependency of string option * string
| FileLoaded of string * string
+ (* Extra metadata *)
| Custom of Loc.t * string * xml
- | Message of message
+ (* Old generic messages *)
+ | Message of level * Richpp.richpp
type feedback = {
id : edit_or_state_id;
@@ -80,92 +45,127 @@ type feedback = {
route : route_id;
}
-let to_feedback_content = do_match "feedback_content" (fun s a -> match s,a with
- | "addedaxiom", _ -> AddedAxiom
- | "processed", _ -> Processed
- | "processingin", [where] -> ProcessingIn (to_string where)
- | "incomplete", _ -> Incomplete
- | "complete", _ -> Complete
- | "globref", [loc; filepath; modpath; ident; ty] ->
- GlobRef(to_loc loc, to_string filepath,
- to_string modpath, to_string ident, to_string ty)
- | "globdef", [loc; ident; secpath; ty] ->
- GlobDef(to_loc loc, to_string ident, to_string secpath, to_string ty)
- | "errormsg", [loc; s] -> ErrorMsg (to_loc loc, to_string s)
- | "inprogress", [n] -> InProgress (to_int n)
- | "workerstatus", [ns] ->
- let n, s = to_pair to_string to_string ns in
- WorkerStatus(n,s)
- | "goals", [loc;s] -> Goals (to_loc loc, to_string s)
- | "custom", [loc;name;x]-> Custom (to_loc loc, to_string name, x)
- | "filedependency", [from; dep] ->
- FileDependency (to_option to_string from, to_string dep)
- | "fileloaded", [dirpath; filename] ->
- FileLoaded (to_string dirpath, to_string filename)
- | "message", [m] -> Message (to_message m)
- | _ -> raise Marshal_error)
-let of_feedback_content = function
- | AddedAxiom -> constructor "feedback_content" "addedaxiom" []
- | Processed -> constructor "feedback_content" "processed" []
- | ProcessingIn where ->
- constructor "feedback_content" "processingin" [of_string where]
- | Incomplete -> constructor "feedback_content" "incomplete" []
- | Complete -> constructor "feedback_content" "complete" []
- | GlobRef(loc, filepath, modpath, ident, ty) ->
- constructor "feedback_content" "globref" [
- of_loc loc;
- of_string filepath;
- of_string modpath;
- of_string ident;
- of_string ty ]
- | GlobDef(loc, ident, secpath, ty) ->
- constructor "feedback_content" "globdef" [
- of_loc loc;
- of_string ident;
- of_string secpath;
- of_string ty ]
- | ErrorMsg(loc, s) ->
- constructor "feedback_content" "errormsg" [of_loc loc; of_string s]
- | InProgress n -> constructor "feedback_content" "inprogress" [of_int n]
- | WorkerStatus(n,s) ->
- constructor "feedback_content" "workerstatus"
- [of_pair of_string of_string (n,s)]
- | Goals (loc,s) ->
- constructor "feedback_content" "goals" [of_loc loc;of_string s]
- | Custom (loc, name, x) ->
- constructor "feedback_content" "custom" [of_loc loc; of_string name; x]
- | FileDependency (from, depends_on) ->
- constructor "feedback_content" "filedependency" [
- of_option of_string from;
- of_string depends_on]
- | FileLoaded (dirpath, filename) ->
- constructor "feedback_content" "fileloaded" [
- of_string dirpath;
- of_string filename ]
- | Message m -> constructor "feedback_content" "message" [ of_message m ]
-
-let of_edit_or_state_id = function
- | Edit id -> ["object","edit"], of_edit_id id
- | State id -> ["object","state"], Stateid.to_xml id
-
-let of_feedback msg =
- let content = of_feedback_content msg.contents in
- let obj, id = of_edit_or_state_id msg.id in
- let route = string_of_int msg.route in
- Element ("feedback", obj @ ["route",route], [id;content])
-let to_feedback xml = match xml with
- | Element ("feedback", ["object","edit";"route",route], [id;content]) -> {
- id = Edit(to_edit_id id);
- route = int_of_string route;
- contents = to_feedback_content content }
- | Element ("feedback", ["object","state";"route",route], [id;content]) -> {
- id = State(Stateid.of_xml id);
- route = int_of_string route;
- contents = to_feedback_content content }
- | _ -> raise Marshal_error
-
-let is_feedback = function
- | Element ("feedback", _, _) -> true
- | _ -> false
-
let default_route = 0
+
+(** Feedback and logging *)
+open Pp
+open Pp_control
+
+type logger = level -> std_ppcmds -> unit
+
+let msgnl_with fmt strm = msg_with fmt (strm ++ fnl ())
+let msgnl strm = msgnl_with !std_ft strm
+
+(* XXX: This is really painful! *)
+module Emacs = struct
+
+ (* Special chars for emacs, to detect warnings inside goal output *)
+ let emacs_quote_start = String.make 1 (Char.chr 254)
+ let emacs_quote_end = String.make 1 (Char.chr 255)
+
+ let emacs_quote_err g =
+ hov 0 (str emacs_quote_start ++ g ++ str emacs_quote_end)
+
+ let emacs_quote_info_start = "<infomsg>"
+ let emacs_quote_info_end = "</infomsg>"
+
+ let emacs_quote_info g =
+ hov 0 (str emacs_quote_info_start++ brk(0,0) ++ g ++ brk(0,0) ++ str emacs_quote_info_end)
+
+end
+
+open Emacs
+
+let dbg_str = str "Debug:" ++ spc ()
+let info_str = mt ()
+let warn_str = str "Warning:" ++ spc ()
+let err_str = str "Error:" ++ spc ()
+
+let make_body quoter info s = quoter (hov 0 (info ++ s))
+
+(* Generic logger *)
+let gen_logger dbg err level msg = match level with
+ | Debug _ -> msgnl (make_body dbg dbg_str msg)
+ | Info -> msgnl (make_body dbg info_str msg)
+ | Notice -> msgnl msg
+ | Warning -> Flags.if_warn (fun () ->
+ msgnl_with !err_ft (make_body err warn_str msg)) ()
+ | Error -> msgnl_with !err_ft (make_body err err_str msg)
+
+(** Standard loggers *)
+let std_logger = gen_logger (fun x -> x) (fun x -> x)
+
+(* Color logger *)
+let color_terminal_logger level strm =
+ let msg = Ppstyle.color_msg in
+ match level with
+ | Debug _ -> msg ~header:("Debug", Ppstyle.debug_tag) !std_ft strm
+ | Info -> msg !std_ft strm
+ | Notice -> msg !std_ft strm
+ | Warning ->
+ let header = ("Warning", Ppstyle.warning_tag) in
+ Flags.if_warn (fun () -> msg ~header !err_ft strm) ()
+ | Error -> msg ~header:("Error", Ppstyle.error_tag) !err_ft strm
+
+(* Rules for emacs:
+ - Debug/info: emacs_quote_info
+ - Warning/Error: emacs_quote_err
+ - Notice: unquoted
+ *)
+let emacs_logger = gen_logger emacs_quote_info emacs_quote_err
+
+let logger = ref std_logger
+let set_logger l = logger := l
+
+let msg_info x = !logger Info x
+let msg_notice x = !logger Notice x
+let msg_warning x = !logger Warning x
+let msg_error x = !logger Error x
+let msg_debug x = !logger (Debug "_") x
+
+(** Feeders *)
+let feeder = ref ignore
+let set_feeder f = feeder := f
+
+let feedback_id = ref (Edit 0)
+let feedback_route = ref default_route
+
+let set_id_for_feedback ?(route=default_route) i =
+ feedback_id := i; feedback_route := route
+
+let feedback ?id ?route what =
+ !feeder {
+ contents = what;
+ route = Option.default !feedback_route route;
+ id = Option.default !feedback_id id;
+ }
+
+let feedback_logger lvl msg =
+ feedback ~route:!feedback_route ~id:!feedback_id
+ (Message (lvl, Richpp.richpp_of_pp msg))
+
+(* Output to file *)
+let ft_logger old_logger ft level mesg =
+ let id x = x in
+ match level with
+ | Debug _ -> msgnl_with ft (make_body id dbg_str mesg)
+ | Info -> msgnl_with ft (make_body id info_str mesg)
+ | Notice -> msgnl_with ft mesg
+ | Warning -> old_logger level mesg
+ | Error -> old_logger level mesg
+
+let with_output_to_file fname func input =
+ let old_logger = !logger in
+ let channel = open_out (String.concat "." [fname; "out"]) in
+ logger := ft_logger old_logger (Format.formatter_of_out_channel channel);
+ try
+ let output = func input in
+ logger := old_logger;
+ close_out channel;
+ output
+ with reraise ->
+ let reraise = Backtrace.add_backtrace reraise in
+ logger := old_logger;
+ close_out channel;
+ Exninfo.iraise reraise
+
diff --git a/lib/feedback.mli b/lib/feedback.mli
index 0d8e20230..50ffd22db 100644
--- a/lib/feedback.mli
+++ b/lib/feedback.mli
@@ -9,27 +9,19 @@
open Xml_datatype
(* Old plain messages (used to be in Pp) *)
-type message_level =
+type level =
| Debug of string
| Info
| Notice
| Warning
| Error
-type message = {
- message_level : message_level;
- message_content : xml;
-}
-
-val of_message : message -> xml
-val to_message : xml -> message
-val is_message : xml -> bool
-
(** Coq "semantic" infos obtained during parsing/execution *)
type edit_id = int
type state_id = Stateid.t
type edit_or_state_id = Edit of edit_id | State of state_id
+
type route_id = int
val default_route : route_id
@@ -54,15 +46,88 @@ type feedback_content =
(* Extra metadata *)
| Custom of Loc.t * string * xml
(* Old generic messages *)
- | Message of message
+ | Message of level * Richpp.richpp
type feedback = {
- id : edit_or_state_id; (* The document part concerned *)
+ id : edit_or_state_id; (* The document part concerned *)
contents : feedback_content; (* The payload *)
- route : route_id; (* Extra routing info *)
+ route : route_id; (* Extra routing info *)
}
-val of_feedback : feedback -> xml
-val to_feedback : xml -> feedback
-val is_feedback : xml -> bool
+(** {6 Feedback sent, even asynchronously, to the user interface} *)
+
+(** Moved here from pp.ml *)
+
+(* Morally the parser gets a string and an edit_id, and gives back an AST.
+ * Feedbacks during the parsing phase are attached to this edit_id.
+ * The interpreter assignes an exec_id to the ast, and feedbacks happening
+ * during interpretation are attached to the exec_id.
+ * Only one among state_id and edit_id can be provided. *)
+
+(** A [logger] takes a level plus a pretty printing doc and logs it *)
+type logger = level -> Pp.std_ppcmds -> unit
+
+(** [set_logger l] makes the [msg_*] to use [l] for logging *)
+val set_logger : logger -> unit
+
+(** [std_logger] standard logger to [stdout/stderr] *)
+val std_logger : logger
+
+val color_terminal_logger : logger
+(* This logger will apply the proper {!Pp_style} tags, and in
+ particular use the formatters {!Pp_control.std_ft} and
+ {!Pp_control.err_ft} to display those messages. Be careful this is
+ not compatible with the Emacs mode! *)
+
+(** [feedback_logger] will produce feedback messages instead IO events *)
+val feedback_logger : logger
+val emacs_logger : logger
+
+
+(** [set_feeder] A feeder processes the feedback, [ignore] by default *)
+val set_feeder : (feedback -> unit) -> unit
+
+(** [feedback ?id ?route fb] produces feedback fb, with [route] and
+ [id] set appropiatedly, if absent, it will use the defaults set by
+ [set_id_for_feedback] *)
+val feedback :
+ ?id:edit_or_state_id -> ?route:route_id -> feedback_content -> unit
+
+(** [set_id_for_feedback route id] Set the defaults for feedback *)
+val set_id_for_feedback : ?route:route_id -> edit_or_state_id -> unit
+
+(** [with_output_to_file file f x] executes [f x] with logging
+ redirected to a file [file] *)
+val with_output_to_file : string -> ('a -> 'b) -> 'a -> 'b
+
+(** {6 output functions}
+
+[msg_notice] do not put any decoration on output by default. If
+possible don't mix it with goal output (prefer msg_info or
+msg_warning) so that interfaces can dispatch outputs easily. Once all
+interfaces use the xml-like protocol this constraint can be
+relaxed. *)
+(* Should we advertise these functions more? Should they be the ONLY
+ allowed way to output something? *)
+
+val msg_info : Pp.std_ppcmds -> unit
+(** Message that displays information, usually in verbose mode, such as [Foobar
+ is defined] *)
+
+val msg_notice : Pp.std_ppcmds -> unit
+(** Message that should be displayed, such as [Print Foo] or [Show Bar]. *)
+
+val msg_warning : Pp.std_ppcmds -> unit
+(** Message indicating that something went wrong, but without serious
+ consequences. *)
+
+val msg_error : Pp.std_ppcmds -> unit
+(** Message indicating that something went really wrong, though still
+ recoverable; otherwise an exception would have been raised. *)
+
+val msg_debug : Pp.std_ppcmds -> unit
+(** For debugging purposes *)
+
+
+
diff --git a/lib/flags.ml b/lib/flags.ml
index c1ec9738c..ba19c7a63 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -47,6 +47,7 @@ let batch_mode = ref false
type compilation_mode = BuildVo | BuildVio | Vio2Vo
let compilation_mode = ref BuildVo
+let compilation_output_name = ref None
let test_mode = ref false
@@ -68,11 +69,15 @@ let priority_of_string = function
| "low" -> Low
| "high" -> High
| _ -> raise (Invalid_argument "priority_of_string")
+type tac_error_filter = [ `None | `Only of string list | `All ]
+let async_proofs_tac_error_resilience = ref (`Only [ "par" ; "curly" ])
+let async_proofs_cmd_error_resilience = ref true
let async_proofs_is_worker () =
!async_proofs_worker_id <> "master"
let async_proofs_is_master () =
!async_proofs_mode = APon && !async_proofs_worker_id = "master"
+let async_proofs_delegation_threshold = ref 0.03
let debug = ref false
let in_debugger = ref false
@@ -220,6 +225,7 @@ let native_compiler = ref false
let print_mod_uid = ref false
let tactic_context_compat = ref false
+let profile_ltac = ref false
let dump_bytecode = ref false
let set_dump_bytecode = (:=) dump_bytecode
diff --git a/lib/flags.mli b/lib/flags.mli
index 24780f0dc..8fe64d24f 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -14,6 +14,7 @@ val load_init : bool ref
val batch_mode : bool ref
type compilation_mode = BuildVo | BuildVio | Vio2Vo
val compilation_mode : compilation_mode ref
+val compilation_output_name : string option ref
val test_mode : bool ref
@@ -34,6 +35,10 @@ type priority = Low | High
val async_proofs_worker_priority : priority ref
val string_of_priority : priority -> string
val priority_of_string : string -> priority
+type tac_error_filter = [ `None | `Only of string list | `All ]
+val async_proofs_tac_error_resilience : tac_error_filter ref
+val async_proofs_cmd_error_resilience : bool ref
+val async_proofs_delegation_threshold : float ref
val debug : bool ref
val in_debugger : bool ref
@@ -143,6 +148,8 @@ val tactic_context_compat : bool ref
(** Set to [true] to trigger the compatibility bugged context matching (old
context vs. appcontext) is set. *)
+val profile_ltac : bool ref
+
(** Dump the bytecode after compilation (for debugging purposes) *)
val dump_bytecode : bool ref
val set_dump_bytecode : bool -> unit
diff --git a/lib/future.ml b/lib/future.ml
index ff16286c4..9cdc1c20e 100644
--- a/lib/future.ml
+++ b/lib/future.ml
@@ -63,7 +63,7 @@ and 'a comp =
| Exn of Exninfo.iexn (* Invariant: this exception is always "fixed" as in fix_exn *)
and 'a comput =
- | Ongoing of string * (UUID.t * fix_exn * 'a comp ref) Ephemeron.key
+ | Ongoing of string * (UUID.t * fix_exn * 'a comp ref) CEphemeron.key
| Finished of 'a
and 'a computation = 'a comput ref
@@ -71,13 +71,13 @@ and 'a computation = 'a comput ref
let unnamed = "unnamed"
let create ?(name=unnamed) ?(uuid=UUID.fresh ()) f x =
- ref (Ongoing (name, Ephemeron.create (uuid, f, Pervasives.ref x)))
+ ref (Ongoing (name, CEphemeron.create (uuid, f, Pervasives.ref x)))
let get x =
match !x with
| Finished v -> unnamed, UUID.invalid, id, ref (Val (v,None))
| Ongoing (name, x) ->
- try let uuid, fix, c = Ephemeron.get x in name, uuid, fix, c
- with Ephemeron.InvalidKey ->
+ try let uuid, fix, c = CEphemeron.get x in name, uuid, fix, c
+ with CEphemeron.InvalidKey ->
name, UUID.invalid, id, ref (Exn (NotHere name, Exninfo.null))
type 'a value = [ `Val of 'a | `Exn of Exninfo.iexn ]
diff --git a/lib/genarg.ml b/lib/genarg.ml
index c7273ac93..69408fb1a 100644
--- a/lib/genarg.ml
+++ b/lib/genarg.ml
@@ -9,83 +9,30 @@
open Pp
open Util
-module ValT = Dyn.Make(struct end)
-module ArgT = Dyn.Make(struct end)
-
-module Val =
+module ArgT =
struct
-
- type 'a typ = 'a ValT.tag
-
- type _ tag =
- | Base : 'a typ -> 'a tag
- | List : 'a tag -> 'a list tag
- | Opt : 'a tag -> 'a option tag
- | Pair : 'a tag * 'b tag -> ('a * 'b) tag
-
- type t = Dyn : 'a tag * 'a -> t
-
- let rec eq : type a b. a tag -> b tag -> (a, b) CSig.eq option =
- fun t1 t2 -> match t1, t2 with
- | Base t1, Base t2 -> ValT.eq t1 t2
- | List t1, List t2 ->
- begin match eq t1 t2 with
- | None -> None
- | Some Refl -> Some Refl
- end
- | Opt t1, Opt t2 ->
- begin match eq t1 t2 with
- | None -> None
- | Some Refl -> Some Refl
- end
- | Pair (t1, u1), Pair (t2, u2) ->
- begin match eq t1 t2 with
- | None -> None
- | Some Refl ->
- match eq u1 u2 with
- | None -> None
- | Some Refl -> Some Refl
- end
- | _ -> None
-
- let rec repr : type a. a tag -> std_ppcmds = function
- | Base t -> str (ValT.repr t)
- | List t -> repr t ++ spc () ++ str "list"
- | Opt t -> repr t ++ spc () ++ str "option"
- | Pair (t1, t2) -> str "(" ++ repr t1 ++ str " * " ++ repr t2 ++ str ")"
-
+ module DYN = Dyn.Make(struct end)
+ module Map = DYN.Map
+ type ('a, 'b, 'c) tag = ('a * 'b * 'c) DYN.tag
+ type any = Any : ('a, 'b, 'c) tag -> any
+ let eq = DYN.eq
+ let repr = DYN.repr
+ let create = DYN.create
+ let name s = match DYN.name s with
+ | None -> None
+ | Some (DYN.Any t) ->
+ Some (Any (Obj.magic t)) (** All created tags are made of triples *)
end
-type argument_type =
- (* Specific types *)
- | ListArgType of argument_type
- | OptArgType of argument_type
- | PairArgType of argument_type * argument_type
- | ExtraArgType of string
-
-let rec argument_type_eq arg1 arg2 = match arg1, arg2 with
-| ListArgType arg1, ListArgType arg2 -> argument_type_eq arg1 arg2
-| OptArgType arg1, OptArgType arg2 -> argument_type_eq arg1 arg2
-| PairArgType (arg1l, arg1r), PairArgType (arg2l, arg2r) ->
- argument_type_eq arg1l arg2l && argument_type_eq arg1r arg2r
-| ExtraArgType s1, ExtraArgType s2 -> CString.equal s1 s2
-| _ -> false
-
-let rec pr_argument_type = function
-| ListArgType t -> pr_argument_type t ++ spc () ++ str "list"
-| OptArgType t -> pr_argument_type t ++ spc () ++ str "opt"
-| PairArgType (t1, t2) ->
- str "("++ pr_argument_type t1 ++ spc () ++
- str "*" ++ spc () ++ pr_argument_type t2 ++ str ")"
-| ExtraArgType s -> str s
-
type (_, _, _) genarg_type =
-| ExtraArg : ('a * 'b * 'c) ArgT.tag -> ('a, 'b, 'c) genarg_type
+| ExtraArg : ('a, 'b, 'c) ArgT.tag -> ('a, 'b, 'c) genarg_type
| ListArg : ('a, 'b, 'c) genarg_type -> ('a list, 'b list, 'c list) genarg_type
| OptArg : ('a, 'b, 'c) genarg_type -> ('a option, 'b option, 'c option) genarg_type
| PairArg : ('a1, 'b1, 'c1) genarg_type * ('a2, 'b2, 'c2) genarg_type ->
('a1 * 'a2, 'b1 * 'b2, 'c1 * 'c2) genarg_type
+type argument_type = ArgumentType : ('a, 'b, 'c) genarg_type -> argument_type
+
let rec genarg_type_eq : type a1 a2 b1 b2 c1 c2.
(a1, b1, c1) genarg_type -> (a2, b2, c2) genarg_type ->
(a1 * b1 * c1, a2 * b2 * c2) CSig.eq option =
@@ -111,6 +58,22 @@ fun t1 t2 -> match t1, t2 with
end
| _ -> None
+let rec pr_genarg_type : type a b c. (a, b, c) genarg_type -> std_ppcmds = function
+| ListArg t -> pr_genarg_type t ++ spc () ++ str "list"
+| OptArg t -> pr_genarg_type t ++ spc () ++ str "opt"
+| PairArg (t1, t2) ->
+ str "("++ pr_genarg_type t1 ++ spc () ++
+ str "*" ++ spc () ++ pr_genarg_type t2 ++ str ")"
+| ExtraArg s -> str (ArgT.repr s)
+
+let argument_type_eq arg1 arg2 = match arg1, arg2 with
+| ArgumentType t1, ArgumentType t2 ->
+ match genarg_type_eq t1 t2 with
+ | None -> false
+ | Some Refl -> true
+
+let pr_argument_type (ArgumentType t) = pr_genarg_type t
+
type 'a uniform_genarg_type = ('a, 'a, 'a) genarg_type
(** Alias for concision *)
@@ -120,11 +83,6 @@ type rlevel = [ `rlevel ]
type glevel = [ `glevel ]
type tlevel = [ `tlevel ]
-type _ level =
-| Rlevel : rlevel level
-| Glevel : glevel level
-| Tlevel : tlevel level
-
type (_, _) abstract_argument_type =
| Rawwit : ('a, 'b, 'c) genarg_type -> ('a, rlevel) abstract_argument_type
| Glbwit : ('a, 'b, 'c) genarg_type -> ('b, glevel) abstract_argument_type
@@ -177,16 +135,10 @@ let has_type (GenArg (t, v)) u = match abstract_argument_type_eq t u with
| None -> false
| Some _ -> true
-let rec untype : type a b c. (a, b, c) genarg_type -> argument_type = function
-| ExtraArg t -> ExtraArgType (ArgT.repr t)
-| ListArg t -> ListArgType (untype t)
-| OptArg t -> OptArgType (untype t)
-| PairArg (t1, t2) -> PairArgType (untype t1, untype t2)
-
let unquote : type l. (_, l) abstract_argument_type -> _ = function
-| Rawwit t -> untype t
-| Glbwit t -> untype t
-| Topwit t -> untype t
+| Rawwit t -> ArgumentType t
+| Glbwit t -> ArgumentType t
+| Topwit t -> ArgumentType t
let genarg_tag (GenArg (t, _)) = unquote t
@@ -194,48 +146,6 @@ type 'a raw_abstract_argument_type = ('a,rlevel) abstract_argument_type
type 'a glob_abstract_argument_type = ('a,glevel) abstract_argument_type
type 'a typed_abstract_argument_type = ('a,tlevel) abstract_argument_type
-type ('a, 'b, 'c, 'l) cast =
-| Rcast : 'a -> ('a, 'b, 'c, rlevel) cast
-| Gcast : 'b -> ('a, 'b, 'c, glevel) cast
-| Tcast : 'c -> ('a, 'b, 'c, tlevel) cast
-
-let raw : ('a, 'b, 'c, rlevel) cast -> _ = function Rcast x -> x
-let glb : ('a, 'b, 'c, glevel) cast -> _ = function Gcast x -> x
-let top : ('a, 'b, 'c, tlevel) cast -> _ = function Tcast x -> x
-
-(** Type transformers *)
-
-type ('r, 'l) list_unpacker =
- { list_unpacker : 'a 'b 'c. ('a, 'b, 'c) genarg_type ->
- ('a list, 'b list, 'c list, 'l) cast -> 'r }
-
-let list_unpack (type l) (pack : (_, l) list_unpacker) (GenArg (t, obj) : l generic_argument) = match t with
-| Rawwit (ListArg t) -> pack.list_unpacker t (Rcast obj)
-| Glbwit (ListArg t) -> pack.list_unpacker t (Gcast obj)
-| Topwit (ListArg t) -> pack.list_unpacker t (Tcast obj)
-| _ -> failwith "out_gen"
-
-type ('r, 'l) opt_unpacker =
- { opt_unpacker : 'a 'b 'c. ('a, 'b, 'c) genarg_type ->
- ('a option, 'b option, 'c option, 'l) cast -> 'r }
-
-let opt_unpack (type l) (pack : (_, l) opt_unpacker) (GenArg (t, obj) : l generic_argument) = match t with
-| Rawwit (OptArg t) -> pack.opt_unpacker t (Rcast obj)
-| Glbwit (OptArg t) -> pack.opt_unpacker t (Gcast obj)
-| Topwit (OptArg t) -> pack.opt_unpacker t (Tcast obj)
-| _ -> failwith "out_gen"
-
-type ('r, 'l) pair_unpacker =
- { pair_unpacker : 'a1 'a2 'b1 'b2 'c1 'c2.
- ('a1, 'b1, 'c1) genarg_type -> ('a2, 'b2, 'c2) genarg_type ->
- (('a1 * 'a2), ('b1 * 'b2), ('c1 * 'c2), 'l) cast -> 'r }
-
-let pair_unpack (type l) (pack : (_, l) pair_unpacker) (GenArg (t, obj) : l generic_argument) = match t with
-| Rawwit (PairArg (t1, t2)) -> pack.pair_unpacker t1 t2 (Rcast obj)
-| Glbwit (PairArg (t1, t2)) -> pack.pair_unpacker t1 t2 (Gcast obj)
-| Topwit (PairArg (t1, t2)) -> pack.pair_unpacker t1 t2 (Tcast obj)
-| _ -> failwith "out_gen"
-
(** Creating args *)
module type Param = sig type ('raw, 'glb, 'top) t end
@@ -245,48 +155,14 @@ struct
include ArgT.Map(struct type 'a t = 'a pack end)
end
-type ('raw, 'glb, 'top) load = {
- nil : 'raw option;
- dyn : 'top Val.tag;
-}
-
-module LoadMap = ArgMap(struct type ('r, 'g, 't) t = ('r, 'g, 't) load end)
-
-let arg0_map = ref LoadMap.empty
-
-let create_arg opt ?dyn name =
+let create_arg name =
match ArgT.name name with
+ | None -> ExtraArg (ArgT.create name)
| Some _ ->
Errors.anomaly (str "generic argument already declared: " ++ str name)
- | None ->
- let dyn = match dyn with None -> Val.Base (ValT.create name) | Some dyn -> dyn in
- let obj = LoadMap.Pack { nil = opt; dyn; } in
- let name = ArgT.create name in
- let () = arg0_map := LoadMap.add name obj !arg0_map in
- ExtraArg name
let make0 = create_arg
-let rec default_empty_value : type a b c. (a, b, c) genarg_type -> a option = function
-| ListArg _ -> Some []
-| OptArg _ -> Some None
-| PairArg (t1, t2) ->
- begin match default_empty_value t1, default_empty_value t2 with
- | Some v1, Some v2 -> Some (v1, v2)
- | _ -> None
- end
-| ExtraArg s ->
- match LoadMap.find s !arg0_map with LoadMap.Pack obj -> obj.nil
-
-let rec val_tag : type a b c. (a, b, c) genarg_type -> c Val.tag = function
-| ListArg t -> Val.List (val_tag t)
-| OptArg t -> Val.Opt (val_tag t)
-| PairArg (t1, t2) -> Val.Pair (val_tag t1, val_tag t2)
-| ExtraArg s ->
- match LoadMap.find s !arg0_map with LoadMap.Pack obj -> obj.dyn
-
-let val_tag = function Topwit t -> val_tag t
-
(** Registering genarg-manipulating functions *)
module type GenObj =
@@ -326,17 +202,3 @@ struct
| _ -> assert false
end
-
-(** Hackish part *)
-
-let arg0_names = ref (String.Map.empty : string String.Map.t)
-
-let register_name0 t name = match t with
-| ExtraArg s ->
- let s = ArgT.repr s in
- let () = assert (not (String.Map.mem s !arg0_names)) in
- arg0_names := String.Map.add s name !arg0_names
-| _ -> failwith "register_name0"
-
-let get_name0 name =
- String.Map.find name !arg0_names
diff --git a/lib/genarg.mli b/lib/genarg.mli
index ce0536cf4..d7ad9b93b 100644
--- a/lib/genarg.mli
+++ b/lib/genarg.mli
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** Generic arguments used by the extension mechanisms of several Coq ASTs. *)
+
(** The route of a generic argument, from parsing to evaluation.
In the following diagram, "object" can be tactic_expr, constr, tactic_arg, etc.
@@ -34,107 +36,57 @@ In the following diagram, "object" can be tactic_expr, constr, tactic_arg, etc.
effective use
{% \end{%}verbatim{% }%}
-To distinguish between the uninterpreted (raw), globalized and
+To distinguish between the uninterpreted, globalized and
interpreted worlds, we annotate the type [generic_argument] by a
-phantom argument which is either [constr_expr], [glob_constr] or
-[constr].
+phantom argument.
-Transformation for each type :
-{% \begin{%}verbatim{% }%}
-tag raw open type cooked closed type
-
-BoolArgType bool bool
-IntArgType int int
-IntOrVarArgType int or_var int
-StringArgType string (parsed w/ "") string
-PreIdentArgType string (parsed w/o "") (vernac only)
-IdentArgType true identifier identifier
-IdentArgType false identifier (pattern_ident) identifier
-IntroPatternArgType intro_pattern_expr intro_pattern_expr
-VarArgType identifier located identifier
-RefArgType reference global_reference
-QuantHypArgType quantified_hypothesis quantified_hypothesis
-ConstrArgType constr_expr constr
-ConstrMayEvalArgType constr_expr may_eval constr
-OpenConstrArgType open_constr_expr open_constr
-ConstrWithBindingsArgType constr_expr with_bindings constr with_bindings
-BindingsArgType constr_expr bindings constr bindings
-List0ArgType of argument_type
-List1ArgType of argument_type
-OptArgType of argument_type
-ExtraArgType of string '_a '_b
-{% \end{%}verbatim{% }%}
*)
(** {5 Generic types} *)
module ArgT :
sig
- type 'a tag
- val eq : 'a tag -> 'b tag -> ('a, 'b) CSig.eq option
- val repr : 'a tag -> string
- type any = Any : 'a tag -> any
+ type ('a, 'b, 'c) tag
+ val eq : ('a1, 'b1, 'c1) tag -> ('a2, 'b2, 'c2) tag -> ('a1 * 'b1 * 'c1, 'a2 * 'b2 * 'c2) CSig.eq option
+ val repr : ('a, 'b, 'c) tag -> string
+ type any = Any : ('a, 'b, 'c) tag -> any
val name : string -> any option
end
+(** Generic types. The first parameter is the OCaml lowest level, the second one
+ is the globalized level, and third one the internalized level. *)
type (_, _, _) genarg_type =
-| ExtraArg : ('a * 'b * 'c) ArgT.tag -> ('a, 'b, 'c) genarg_type
+| ExtraArg : ('a, 'b, 'c) ArgT.tag -> ('a, 'b, 'c) genarg_type
| ListArg : ('a, 'b, 'c) genarg_type -> ('a list, 'b list, 'c list) genarg_type
| OptArg : ('a, 'b, 'c) genarg_type -> ('a option, 'b option, 'c option) genarg_type
| PairArg : ('a1, 'b1, 'c1) genarg_type * ('a2, 'b2, 'c2) genarg_type ->
('a1 * 'a2, 'b1 * 'b2, 'c1 * 'c2) genarg_type
-(** Generic types. ['raw] is the OCaml lowest level, ['glob] is the globalized
- one, and ['top] the internalized one. *)
-
-module Val :
-sig
- type 'a typ
-
- type _ tag =
- | Base : 'a typ -> 'a tag
- | List : 'a tag -> 'a list tag
- | Opt : 'a tag -> 'a option tag
- | Pair : 'a tag * 'b tag -> ('a * 'b) tag
-
- type t = Dyn : 'a tag * 'a -> t
-
- val eq : 'a tag -> 'b tag -> ('a, 'b) CSig.eq option
- val repr: 'a tag -> Pp.std_ppcmds
-
-end
-(** Dynamic types for toplevel values. While the generic types permit to relate
- objects at various levels of interpretation, toplevel values are wearing
- their own type regardless of where they came from. This allows to use the
- same runtime representation for several generic types. *)
type 'a uniform_genarg_type = ('a, 'a, 'a) genarg_type
(** Alias for concision when the three types agree. *)
-val make0 : 'raw option -> ?dyn:'top Val.tag -> string -> ('raw, 'glob, 'top) genarg_type
+val make0 : string -> ('raw, 'glob, 'top) genarg_type
(** Create a new generic type of argument: force to associate
unique ML types at each of the three levels. *)
-val create_arg : 'raw option -> ?dyn:'top Val.tag -> string -> ('raw, 'glob, 'top) genarg_type
+val create_arg : string -> ('raw, 'glob, 'top) genarg_type
(** Alias for [make0]. *)
(** {5 Specialized types} *)
(** All of [rlevel], [glevel] and [tlevel] must be non convertible
- to ensure the injectivity of the type inference from type
- ['co generic_argument] to [('a,'co) abstract_argument_type];
- this guarantees that, for 'co fixed, the type of
- out_gen is monomorphic over 'a, hence type-safe
-*)
+ to ensure the injectivity of the GADT type inference. *)
type rlevel = [ `rlevel ]
type glevel = [ `glevel ]
type tlevel = [ `tlevel ]
+(** Generic types at a fixed level. The first parameter embeds the OCaml type
+ and the second one the level. *)
type (_, _) abstract_argument_type =
| Rawwit : ('a, 'b, 'c) genarg_type -> ('a, rlevel) abstract_argument_type
| Glbwit : ('a, 'b, 'c) genarg_type -> ('b, glevel) abstract_argument_type
| Topwit : ('a, 'b, 'c) genarg_type -> ('c, tlevel) abstract_argument_type
-(** Type at level ['co] represented by an OCaml value of type ['a]. *)
type 'a raw_abstract_argument_type = ('a, rlevel) abstract_argument_type
(** Specialized type at raw level. *)
@@ -179,20 +131,9 @@ val has_type : 'co generic_argument -> ('a, 'co) abstract_argument_type -> bool
(** [has_type v t] tells whether [v] has type [t]. If true, it ensures that
[out_gen t v] will not raise a dynamic type exception. *)
-(** {6 Dynamic toplevel values} *)
-
-val val_tag : 'a typed_abstract_argument_type -> 'a Val.tag
-(** Retrieve the dynamic type associated to a toplevel genarg. Only works for
- ground generic arguments. *)
-
(** {6 Type reification} *)
-type argument_type =
- (** Specific types *)
- | ListArgType of argument_type
- | OptArgType of argument_type
- | PairArgType of argument_type * argument_type
- | ExtraArgType of string
+type argument_type = ArgumentType : ('a, 'b, 'c) genarg_type -> argument_type
(** {6 Equalities} *)
@@ -239,23 +180,13 @@ sig
end
-(** {5 Basic generic type constructors} *)
+(** {5 Compatibility layer}
-(** {6 Parameterized types} *)
+The functions below are aliases for generic_type constructors.
+
+*)
val wit_list : ('a, 'b, 'c) genarg_type -> ('a list, 'b list, 'c list) genarg_type
val wit_opt : ('a, 'b, 'c) genarg_type -> ('a option, 'b option, 'c option) genarg_type
val wit_pair : ('a1, 'b1, 'c1) genarg_type -> ('a2, 'b2, 'c2) genarg_type ->
('a1 * 'a2, 'b1 * 'b2, 'c1 * 'c2) genarg_type
-
-(** {5 Magic used by the parser} *)
-
-val default_empty_value : ('raw, 'glb, 'top) genarg_type -> 'raw option
-
-val register_name0 : ('a, 'b, 'c) genarg_type -> string -> unit
-(** Used by the extension to give a name to types. The string should be the
- absolute path of the argument witness, e.g.
- [register_name0 wit_toto "MyArg.wit_toto"]. *)
-
-val get_name0 : string -> string
-(** Return the absolute path of a given witness. *)
diff --git a/lib/hashcons.ml b/lib/hashcons.ml
index b5192dbb8..4eaacf914 100644
--- a/lib/hashcons.ml
+++ b/lib/hashcons.ml
@@ -15,7 +15,7 @@
* of objects of type t (u usually has the form (t1->t1)*(t2->t2)*...).
* [hashcons u x] is a function that hash-cons the sub-structures of x using
* the hash-consing functions u provides.
- * [equal] is a comparison function. It is allowed to use physical equality
+ * [eq] is a comparison function. It is allowed to use physical equality
* on the sub-terms hash-consed by the hashcons function.
* [hash] is the hash function given to the Hashtbl.Make function
*
@@ -27,7 +27,7 @@ module type HashconsedType =
type t
type u
val hashcons : u -> t -> t
- val equal : t -> t -> bool
+ val eq : t -> t -> bool
val hash : t -> int
end
@@ -53,7 +53,7 @@ module Make (X : HashconsedType) : (S with type t = X.t and type u = X.u) =
(* We create the type of hashtables for t, with our comparison fun.
* An invariant is that the table never contains two entries equals
- * w.r.t (=), although the equality on keys is X.equal. This is
+ * w.r.t (=), although the equality on keys is X.eq. This is
* granted since we hcons the subterms before looking up in the table.
*)
module Htbl = Hashset.Make(X)
@@ -110,7 +110,7 @@ module Hlist (D:HashedType) =
let hashcons (hrec,hdata) = function
| x :: l -> hdata x :: hrec l
| l -> l
- let equal l1 l2 =
+ let eq l1 l2 =
l1 == l2 ||
match l1, l2 with
| [], [] -> true
@@ -130,7 +130,7 @@ module Hstring = Make(
type t = string
type u = unit
let hashcons () s =(* incr accesstr;*) s
- external equal : string -> string -> bool = "caml_string_equal" "noalloc"
+ external eq : string -> string -> bool = "caml_string_equal" "noalloc"
(** Copy from CString *)
let rec hash len s i accu =
if i = len then accu
@@ -177,6 +177,6 @@ module Hobj = Make(
type t = Obj.t
type u = (Obj.t -> Obj.t) * unit
let hashcons (hrec,_) = hash_obj hrec
- let equal = comp_obj
+ let eq = comp_obj
let hash = Hashtbl.hash
end)
diff --git a/lib/hashcons.mli b/lib/hashcons.mli
index 04754ba1d..150899cef 100644
--- a/lib/hashcons.mli
+++ b/lib/hashcons.mli
@@ -14,9 +14,9 @@ module type HashconsedType =
sig
(** {6 Generic hashconsing signature}
- Given an equivalence relation [equal], a hashconsing function is a
+ Given an equivalence relation [eq], a hashconsing function is a
function that associates the same canonical element to two elements
- related by [equal]. Usually, the element chosen is canonical w.r.t.
+ related by [eq]. Usually, the element chosen is canonical w.r.t.
physical equality [(==)], so as to reduce memory consumption and
enhance efficiency of equality tests.
@@ -32,15 +32,15 @@ module type HashconsedType =
Usually a tuple of functions. *)
val hashcons : u -> t -> t
(** The actual hashconsing function, using its fist argument to recursively
- hashcons substructures. It should be compatible with [equal], that is
- [equal x (hashcons f x) = true]. *)
- val equal : t -> t -> bool
+ hashcons substructures. It should be compatible with [eq], that is
+ [eq x (hashcons f x) = true]. *)
+ val eq : t -> t -> bool
(** A comparison function. It is allowed to use physical equality
on the sub-terms hashconsed by the [hashcons] function, but it should be
insensible to shallow copy of the compared object. *)
val hash : t -> int
(** A hash function passed to the underlying hashtable structure. [hash]
- should be compatible with [equal], i.e. if [equal x y = true] then
+ should be compatible with [eq], i.e. if [eq x y = true] then
[hash x = hash y]. *)
end
diff --git a/lib/hashset.ml b/lib/hashset.ml
index b2795c6b1..af33544dc 100644
--- a/lib/hashset.ml
+++ b/lib/hashset.ml
@@ -16,7 +16,7 @@
module type EqType = sig
type t
- val equal : t -> t -> bool
+ val eq : t -> t -> bool
end
type statistics = {
@@ -183,7 +183,7 @@ module Make (E : EqType) =
if i >= sz then ifnotfound index
else if h = hashes.(i) then begin
match Weak.get bucket i with
- | Some v when E.equal v d -> v
+ | Some v when E.eq v d -> v
| _ -> loop (i + 1)
end else loop (i + 1)
in
diff --git a/lib/hashset.mli b/lib/hashset.mli
index 05d4fe379..733c89621 100644
--- a/lib/hashset.mli
+++ b/lib/hashset.mli
@@ -16,7 +16,7 @@
module type EqType = sig
type t
- val equal : t -> t -> bool
+ val eq : t -> t -> bool
end
type statistics = {
diff --git a/lib/iStream.ml b/lib/iStream.ml
index c9f4d4a11..26a666e17 100644
--- a/lib/iStream.ml
+++ b/lib/iStream.ml
@@ -14,11 +14,11 @@ type 'a node = ('a,'a t) u
and 'a t = 'a node Lazy.t
-let empty = Lazy.lazy_from_val Nil
+let empty = Lazy.from_val Nil
-let cons x s = Lazy.lazy_from_val (Cons (x, s))
+let cons x s = Lazy.from_val (Cons (x, s))
-let thunk = Lazy.lazy_from_fun
+let thunk = Lazy.from_fun
let rec make_node f s = match f s with
| Nil -> Nil
diff --git a/lib/lib.mllib b/lib/lib.mllib
index a9181c51c..a6c09058d 100644
--- a/lib/lib.mllib
+++ b/lib/lib.mllib
@@ -3,6 +3,7 @@ Bigint
Segmenttree
Unicodetable
Unicode
+Minisys
System
CThread
Spawn
@@ -14,6 +15,6 @@ Rtree
Heap
Unionfind
Genarg
-Ephemeron
+CEphemeron
Future
RemoteCounter
diff --git a/lib/minisys.ml b/lib/minisys.ml
new file mode 100644
index 000000000..25e4d79c4
--- /dev/null
+++ b/lib/minisys.ml
@@ -0,0 +1,74 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** Minisys regroups some code that used to be in System.
+ Unlike System, this module has no dependency and could
+ be used for initial compilation target such as coqdep_boot.
+ The functions here are still available in System thanks to
+ an include. For the signature, look at the top of system.mli
+*)
+
+(** Dealing with directories *)
+
+type unix_path = string (* path in unix-style, with '/' separator *)
+
+type file_kind =
+ | FileDir of unix_path * (* basename of path: *) string
+ | FileRegular of string (* basename of file *)
+
+(* Copy of Filename.concat but assuming paths to always be POSIX *)
+
+let (//) dirname filename =
+ let l = String.length dirname in
+ if l = 0 || dirname.[l-1] = '/'
+ then dirname ^ filename
+ else dirname ^ "/" ^ filename
+
+(* Excluding directories; We avoid directories starting with . as well
+ as CVS and _darcs and any subdirs given via -exclude-dir *)
+
+let skipped_dirnames = ref ["CVS"; "_darcs"]
+
+let exclude_directory f = skipped_dirnames := f :: !skipped_dirnames
+
+let ok_dirname f =
+ not (f = "") && f.[0] != '.' &&
+ not (List.mem f !skipped_dirnames) (*&&
+ (match Unicode.ident_refutation f with None -> true | _ -> false)*)
+
+(* Check directory can be opened *)
+
+let exists_dir dir =
+ try Sys.is_directory dir with Sys_error _ -> false
+
+let check_unix_dir warn dir =
+ if (Sys.os_type = "Win32" || Sys.os_type = "Cygwin") &&
+ (String.length dir > 2 && dir.[1] = ':' ||
+ String.contains dir '\\' ||
+ String.contains dir ';')
+ then warn ("assuming " ^ dir ^
+ " to be a Unix path even if looking like a Win32 path.")
+
+let apply_subdir f path name =
+ (* we avoid all files and subdirs starting by '.' (e.g. .svn) *)
+ (* as well as skipped files like CVS, ... *)
+ if ok_dirname name then
+ let path = if path = "." then name else path//name in
+ match try (Unix.stat path).Unix.st_kind with Unix.Unix_error _ -> Unix.S_BLK with
+ | Unix.S_DIR -> f (FileDir (path,name))
+ | Unix.S_REG -> f (FileRegular name)
+ | _ -> ()
+
+let readdir dir = try Sys.readdir dir with any -> [||]
+
+let process_directory f path =
+ Array.iter (apply_subdir f path) (readdir path)
+
+let process_subdirectories f path =
+ let f = function FileDir (path,base) -> f path base | FileRegular _ -> () in
+ process_directory f path
diff --git a/lib/pp.ml b/lib/pp.ml
index 0260f98fa..d07f01b90 100644
--- a/lib/pp.ml
+++ b/lib/pp.ml
@@ -57,24 +57,13 @@ module Dyn = Dyn.Make(struct end)
type t = Dyn.t
type 'a key = 'a Dyn.tag
let create = Dyn.create
-let inj x k = Dyn.Dyn (k, x)
-let prj : type a. t -> a key -> a option = fun dyn k ->
- let Dyn.Dyn (k', x) = dyn in
- match Dyn.eq k k' with
- | None -> None
- | Some CSig.Refl -> Some x
+let inj = Dyn.Easy.inj
+let prj = Dyn.Easy.prj
end
open Pp_control
-(* This should not be used outside of this file. Use
- Flags.print_emacs instead. This one is updated when reading
- command line options. This was the only way to make [Pp] depend on
- an option without creating a circularity: [Flags] -> [Util] ->
- [Pp] -> [Flags] *)
-let print_emacs = ref false
-
(* The different kinds of blocks are:
\begin{description}
\item[hbox:] Horizontal block no line breaking;
@@ -261,7 +250,7 @@ let rec pr_com ft s =
let n = String.index s '\n' in
String.sub s 0 n, Some (String.sub s (n+1) (String.length s - n - 1))
with Not_found -> s,None in
- com_if ft (Lazy.lazy_from_val());
+ com_if ft (Lazy.from_val());
(* let s1 =
if String.length s1 <> 0 && s1.[0] = ' ' then
(Format.pp_print_space ft (); String.sub s1 1 (String.length s1 - 1))
@@ -290,29 +279,29 @@ let pp_dirs ?pp_tag ft =
begin match tok with
| Str_def s ->
let n = utf8_length s in
- com_if ft (Lazy.lazy_from_val()); Format.pp_print_as ft n s
+ com_if ft (Lazy.from_val()); Format.pp_print_as ft n s
| Str_len (s, n) ->
- com_if ft (Lazy.lazy_from_val()); Format.pp_print_as ft n s
+ com_if ft (Lazy.from_val()); Format.pp_print_as ft n s
end
| Ppcmd_box(bty,ss) -> (* Prevent evaluation of the stream! *)
- com_if ft (Lazy.lazy_from_val());
+ com_if ft (Lazy.from_val());
pp_open_box bty ;
if not (Format.over_max_boxes ()) then Glue.iter pp_cmd ss;
Format.pp_close_box ft ()
- | Ppcmd_open_box bty -> com_if ft (Lazy.lazy_from_val()); pp_open_box bty
+ | Ppcmd_open_box bty -> com_if ft (Lazy.from_val()); pp_open_box bty
| Ppcmd_close_box -> Format.pp_close_box ft ()
| Ppcmd_close_tbox -> Format.pp_close_tbox ft ()
| Ppcmd_white_space n ->
- com_if ft (Lazy.lazy_from_fun (fun()->Format.pp_print_break ft n 0))
+ com_if ft (Lazy.from_fun (fun()->Format.pp_print_break ft n 0))
| Ppcmd_print_break(m,n) ->
- com_if ft (Lazy.lazy_from_fun(fun()->Format.pp_print_break ft m n))
+ com_if ft (Lazy.from_fun(fun()->Format.pp_print_break ft m n))
| Ppcmd_set_tab -> Format.pp_set_tab ft ()
| Ppcmd_print_tbreak(m,n) ->
- com_if ft (Lazy.lazy_from_fun(fun()->Format.pp_print_tbreak ft m n))
+ com_if ft (Lazy.from_fun(fun()->Format.pp_print_tbreak ft m n))
| Ppcmd_force_newline ->
com_brk ft; Format.pp_force_newline ft ()
| Ppcmd_print_if_broken ->
- com_if ft (Lazy.lazy_from_fun(fun()->Format.pp_print_if_newline ft ()))
+ com_if ft (Lazy.from_fun(fun()->Format.pp_print_if_newline ft ()))
| Ppcmd_comment i ->
let coms = split_com [] [] i !comments in
(* Format.pp_open_hvbox ft 0;*)
@@ -343,181 +332,30 @@ let pp_dirs ?pp_tag ft =
let () = Format.pp_print_flush ft () in
Exninfo.iraise reraise
-
-
-(* pretty print on stdout and stderr *)
-
-(* Special chars for emacs, to detect warnings inside goal output *)
-let emacs_quote_start = String.make 1 (Char.chr 254)
-let emacs_quote_end = String.make 1 (Char.chr 255)
-
-let emacs_quote_info_start = "<infomsg>"
-let emacs_quote_info_end = "</infomsg>"
-
-let emacs_quote g =
- if !print_emacs then hov 0 (str emacs_quote_start ++ g ++ str emacs_quote_end)
- else hov 0 g
-
-let emacs_quote_info g =
- if !print_emacs then hov 0 (str emacs_quote_info_start++ brk(0,0) ++ g ++ brk(0,0) ++ str emacs_quote_info_end)
- else hov 0 g
-
-
(* pretty printing functions WITHOUT FLUSH *)
let pp_with ?pp_tag ft strm =
pp_dirs ?pp_tag ft (Glue.atom (Ppdir_ppcmds strm))
-let ppnl_with ft strm =
- pp_dirs ft (Glue.atom (Ppdir_ppcmds (strm ++ fnl ())))
-
(* pretty printing functions WITH FLUSH *)
let msg_with ft strm =
pp_dirs ft (Glue.atom(Ppdir_ppcmds strm) ++ Glue.atom(Ppdir_print_flush))
-let msgnl_with ft strm =
- pp_dirs ft (Glue.atom(Ppdir_ppcmds strm) ++ Glue.atom(Ppdir_print_newline))
-
-(* pretty printing functions WITHOUT FLUSH *)
-let pp x = pp_with !std_ft x
-let ppnl x = ppnl_with !std_ft x
-let pperr x = pp_with !err_ft x
-let pperrnl x = ppnl_with !err_ft x
-let message s = ppnl (str s)
-let pp_flush x = Format.pp_print_flush !std_ft x
-let pperr_flush x = Format.pp_print_flush !err_ft x
-let flush_all () =
- flush stderr; flush stdout; pp_flush (); pperr_flush ()
-
-(* pretty printing functions WITH FLUSH *)
-let msg x = msg_with !std_ft x
-let msgnl x = msgnl_with !std_ft x
-let msgerr x = msg_with !err_ft x
-let msgerrnl x = msgnl_with !err_ft x
-
-(* Logging management *)
-
-type message_level = Feedback.message_level =
- | Debug of string
- | Info
- | Notice
- | Warning
- | Error
-
-type message = Feedback.message = {
- message_level : message_level;
- message_content : Xml_datatype.xml;
-}
-
-let of_message = Feedback.of_message
-let to_message = Feedback.to_message
-let is_message = Feedback.is_message
-
-type logger = message_level -> std_ppcmds -> unit
-
-let make_body info s =
- emacs_quote (hov 0 (info ++ spc () ++ s))
-
-let debugbody strm = emacs_quote_info (hov 0 (str "Debug:" ++ spc () ++ strm))
-let warnbody strm = make_body (str "Warning:") strm
-let errorbody strm = make_body (str "Error:") strm
-let infobody strm = emacs_quote_info strm
-
-let std_logger ~id:_ level msg = match level with
-| Debug _ -> msgnl (debugbody msg)
-| Info -> msgnl (hov 0 msg)
-| Notice -> msgnl msg
-| Warning -> Flags.if_warn (fun () -> msgnl_with !err_ft (warnbody msg)) ()
-| Error -> msgnl_with !err_ft (errorbody msg)
-
-let emacs_logger ~id:_ level mesg = match level with
-| Debug _ -> msgnl (debugbody mesg)
-| Info -> msgnl (infobody mesg)
-| Notice -> msgnl mesg
-| Warning -> Flags.if_warn (fun () -> msgnl_with !err_ft (warnbody mesg)) ()
-| Error -> msgnl_with !err_ft (errorbody mesg)
-
-let logger = ref std_logger
-
-let make_pp_emacs() = print_emacs:=true; logger:=emacs_logger
-let make_pp_nonemacs() = print_emacs:=false; logger := std_logger
-
-let ft_logger old_logger ft ~id level mesg = match level with
- | Debug _ -> msgnl_with ft (debugbody mesg)
- | Info -> msgnl_with ft (infobody mesg)
- | Notice -> msgnl_with ft mesg
- | Warning -> old_logger ~id:id level mesg
- | Error -> old_logger ~id:id level mesg
-
-let with_output_to_file fname func input =
- let old_logger = !logger in
- let channel = open_out (String.concat "." [fname; "out"]) in
- logger := ft_logger old_logger (Format.formatter_of_out_channel channel);
- try
- let output = func input in
- logger := old_logger;
- close_out channel;
- output
- with reraise ->
- let reraise = Backtrace.add_backtrace reraise in
- logger := old_logger;
- close_out channel;
- Exninfo.iraise reraise
-
-let feedback_id = ref (Feedback.Edit 0)
-let feedback_route = ref Feedback.default_route
-
(* If mixing some output and a goal display, please use msg_warning,
so that interfaces (proofgeneral for example) can easily dispatch
them to different windows. *)
-let msg_info x = !logger ~id:!feedback_id Info x
-let msg_notice x = !logger ~id:!feedback_id Notice x
-let msg_warning x = !logger ~id:!feedback_id Warning x
-let msg_error x = !logger ~id:!feedback_id Error x
-let msg_debug x = !logger ~id:!feedback_id (Debug "_") x
-
-let set_logger l = logger := (fun ~id:_ lvl msg -> l lvl msg)
-
-let std_logger lvl msg = std_logger ~id:!feedback_id lvl msg
-
-(** Feedback *)
-
-let feeder = ref ignore
-let set_id_for_feedback ?(route=Feedback.default_route) i =
- feedback_id := i; feedback_route := route
-let feedback ?state_id ?edit_id ?route what =
- !feeder {
- Feedback.contents = what;
- Feedback.route = Option.default !feedback_route route;
- Feedback.id =
- match state_id, edit_id with
- | Some id, _ -> Feedback.State id
- | None, Some eid -> Feedback.Edit eid
- | None, None -> !feedback_id;
- }
-let set_feeder f = feeder := f
-let get_id_for_feedback () = !feedback_id, !feedback_route
-
-(** Utility *)
-
+(** Output to a string formatter *)
let string_of_ppcmds c =
- msg_with Format.str_formatter c;
+ Format.fprintf Format.str_formatter "@[%a@]" msg_with c;
Format.flush_str_formatter ()
-let log_via_feedback printer = logger := (fun ~id lvl msg ->
- !feeder {
- Feedback.contents = Feedback.Message {
- message_level = lvl;
- message_content = printer msg };
- Feedback.route = !feedback_route;
- Feedback.id = id })
-
(* Copy paste from Util *)
let pr_comma () = str "," ++ spc ()
let pr_semicolon () = str ";" ++ spc ()
let pr_bar () = str "|" ++ spc ()
let pr_arg pr x = spc () ++ pr x
+let pr_non_empty_arg pr x = let pp = pr x in if ismt pp then mt () else spc () ++ pr x
let pr_opt pr = function None -> mt () | Some x -> pr_arg pr x
let pr_opt_no_spc pr = function None -> mt () | Some x -> pr x
@@ -600,3 +438,4 @@ let prvect_with_sep sep elem v = prvecti_with_sep sep (fun _ -> elem) v
let prvect elem v = prvect_with_sep mt elem v
let surround p = hov 1 (str"(" ++ p ++ str")")
+
diff --git a/lib/pp.mli b/lib/pp.mli
index 015151bc9..a18744c37 100644
--- a/lib/pp.mli
+++ b/lib/pp.mli
@@ -6,32 +6,24 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(** Modify pretty printing functions behavior for emacs ouput (special
- chars inserted at some places). This function should called once in
- module [Options], that's all. *)
-val make_pp_emacs:unit -> unit
-val make_pp_nonemacs:unit -> unit
-
-val with_output_to_file : string -> ('a -> 'b) -> 'a -> 'b
-
(** Pretty-printers. *)
type std_ppcmds
(** {6 Formatting commands} *)
-val str : string -> std_ppcmds
+val str : string -> std_ppcmds
val stras : int * string -> std_ppcmds
-val brk : int * int -> std_ppcmds
-val tbrk : int * int -> std_ppcmds
-val tab : unit -> std_ppcmds
-val fnl : unit -> std_ppcmds
-val pifb : unit -> std_ppcmds
-val ws : int -> std_ppcmds
-val mt : unit -> std_ppcmds
-val ismt : std_ppcmds -> bool
-
-val comment : int -> std_ppcmds
+val brk : int * int -> std_ppcmds
+val tbrk : int * int -> std_ppcmds
+val tab : unit -> std_ppcmds
+val fnl : unit -> std_ppcmds
+val pifb : unit -> std_ppcmds
+val ws : int -> std_ppcmds
+val mt : unit -> std_ppcmds
+val ismt : std_ppcmds -> bool
+
+val comment : int -> std_ppcmds
val comments : ((int * int) * string) list ref
(** {6 Manipulation commands} *)
@@ -100,87 +92,10 @@ sig
(** Project an object from a tag. *)
end
-type tag_handler = Tag.t -> Format.tag
-
val tag : Tag.t -> std_ppcmds -> std_ppcmds
val open_tag : Tag.t -> std_ppcmds
val close_tag : unit -> std_ppcmds
-(** {6 Sending messages to the user} *)
-type message_level = Feedback.message_level =
- | Debug of string
- | Info
- | Notice
- | Warning
- | Error
-
-type message = Feedback.message = {
- message_level : message_level;
- message_content : Xml_datatype.xml;
-}
-
-type logger = message_level -> std_ppcmds -> unit
-
-(** {6 output functions}
-
-[msg_notice] do not put any decoration on output by default. If
-possible don't mix it with goal output (prefer msg_info or
-msg_warning) so that interfaces can dispatch outputs easily. Once all
-interfaces use the xml-like protocol this constraint can be
-relaxed. *)
-(* Should we advertise these functions more? Should they be the ONLY
- allowed way to output something? *)
-
-val msg_info : std_ppcmds -> unit
-(** Message that displays information, usually in verbose mode, such as [Foobar
- is defined] *)
-
-val msg_notice : std_ppcmds -> unit
-(** Message that should be displayed, such as [Print Foo] or [Show Bar]. *)
-
-val msg_warning : std_ppcmds -> unit
-(** Message indicating that something went wrong, but without serious
- consequences. *)
-
-val msg_error : std_ppcmds -> unit
-(** Message indicating that something went really wrong, though still
- recoverable; otherwise an exception would have been raised. *)
-
-val msg_debug : std_ppcmds -> unit
-(** For debugging purposes *)
-
-val std_logger : logger
-(** Standard logging function *)
-
-val set_logger : logger -> unit
-
-val log_via_feedback : (std_ppcmds -> Xml_datatype.xml) -> unit
-
-val of_message : message -> Xml_datatype.xml
-val to_message : Xml_datatype.xml -> message
-val is_message : Xml_datatype.xml -> bool
-
-
-(** {6 Feedback sent, even asynchronously, to the user interface} *)
-
-(* This stuff should be available to most of the system, line msg_* above.
- * But I'm unsure this is the right place, especially for the global edit_id.
- *
- * Morally the parser gets a string and an edit_id, and gives back an AST.
- * Feedbacks during the parsing phase are attached to this edit_id.
- * The interpreter assignes an exec_id to the ast, and feedbacks happening
- * during interpretation are attached to the exec_id.
- * Only one among state_id and edit_id can be provided. *)
-
-val feedback :
- ?state_id:Feedback.state_id -> ?edit_id:Feedback.edit_id ->
- ?route:Feedback.route_id -> Feedback.feedback_content -> unit
-
-val set_id_for_feedback :
- ?route:Feedback.route_id -> Feedback.edit_or_state_id -> unit
-val set_feeder : (Feedback.feedback -> unit) -> unit
-val get_id_for_feedback : unit -> Feedback.edit_or_state_id * Feedback.route_id
-
(** {6 Utilities} *)
val string_of_ppcmds : std_ppcmds -> string
@@ -199,6 +114,9 @@ val pr_bar : unit -> std_ppcmds
val pr_arg : ('a -> std_ppcmds) -> 'a -> std_ppcmds
(** Adds a space in front of its argument. *)
+val pr_non_empty_arg : ('a -> std_ppcmds) -> 'a -> std_ppcmds
+(** Adds a space in front of its argument if non empty. *)
+
val pr_opt : ('a -> std_ppcmds) -> 'a option -> std_ppcmds
(** Inner object preceded with a space if [Some], nothing otherwise. *)
@@ -248,31 +166,13 @@ val surround : std_ppcmds -> std_ppcmds
val pr_vertical_list : ('b -> std_ppcmds) -> 'b list -> std_ppcmds
-(** {6 Low-level pretty-printing functions {% \emph{%}without flush{% }%}. } *)
-
-val pp_with : ?pp_tag:tag_handler -> Format.formatter -> std_ppcmds -> unit
-
-(** {6 Pretty-printing functions {% \emph{%}without flush{% }%} on [stdout] and [stderr]. } *)
-
-(** These functions are low-level interface to printing and should not be used
- in usual code. Consider using the [msg_*] function family instead. *)
+(** {6 Low-level pretty-printing functions with and without flush} *)
-val pp : std_ppcmds -> unit
-val ppnl : std_ppcmds -> unit
-val pperr : std_ppcmds -> unit
-val pperrnl : std_ppcmds -> unit
-val pperr_flush : unit -> unit
-val pp_flush : unit -> unit
-val flush_all: unit -> unit
-
-(** {6 Deprecated functions} *)
-
-(** DEPRECATED. Do not use in newly written code. *)
+(** FIXME: These ignore the logging settings and call [Format] directly *)
+type tag_handler = Tag.t -> Format.tag
-val msg_with : Format.formatter -> std_ppcmds -> unit
+(** [msg_with fmt pp] Print [pp] to [fmt] and flush [fmt] *)
+val msg_with : Format.formatter -> std_ppcmds -> unit
-val msg : std_ppcmds -> unit
-val msgnl : std_ppcmds -> unit
-val msgerr : std_ppcmds -> unit
-val msgerrnl : std_ppcmds -> unit
-val message : string -> unit (** = pPNL *)
+(** [msg_with fmt pp] Print [pp] to [fmt] and don't flush [fmt] *)
+val pp_with : ?pp_tag:tag_handler -> Format.formatter -> std_ppcmds -> unit
diff --git a/lib/ppstyle.ml b/lib/ppstyle.ml
index bb73fbdf5..b068788c9 100644
--- a/lib/ppstyle.ml
+++ b/lib/ppstyle.ml
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Util
+module String = CString
type t = string
(** We use the concatenated string, with dots separating each string. We
@@ -107,8 +107,11 @@ let pp_tag t = match Pp.Tag.prj t tag with
| None -> ""
| Some key -> key
+let clear_tag_fn = ref (fun () -> ())
+
let init_color_output () =
let push_tag, pop_tag, clear_tag = make_style_stack !tags in
+ clear_tag_fn := clear_tag;
let tag_handler = {
Format.mark_open_tag = push_tag;
Format.mark_close_tag = pop_tag;
@@ -116,34 +119,23 @@ let init_color_output () =
Format.print_close_tag = ignore;
} in
let open Pp_control in
- let () = Format.pp_set_mark_tags !std_ft true in
- let () = Format.pp_set_mark_tags !err_ft true in
- let () = Format.pp_set_formatter_tag_functions !std_ft tag_handler in
- let () = Format.pp_set_formatter_tag_functions !err_ft tag_handler in
+ Format.pp_set_mark_tags !std_ft true;
+ Format.pp_set_mark_tags !err_ft true;
+ Format.pp_set_formatter_tag_functions !std_ft tag_handler;
+ Format.pp_set_formatter_tag_functions !err_ft tag_handler
+
+let color_msg ?header ft strm =
let pptag = tag in
let open Pp in
- let msg ?header ft strm =
- let strm = match header with
+ let strm = match header with
| None -> hov 0 strm
| Some (h, t) ->
let tag = Pp.Tag.inj t pptag in
let h = Pp.tag tag (str h ++ str ":") in
hov 0 (h ++ spc () ++ strm)
- in
- pp_with ~pp_tag ft strm;
- Format.pp_print_newline ft ();
- Format.pp_print_flush ft ();
- (** In case something went wrong, we reset the stack *)
- clear_tag ();
- in
- let logger level strm = match level with
- | Debug _ -> msg ~header:("Debug", debug_tag) !std_ft strm
- | Info -> msg !std_ft strm
- | Notice -> msg !std_ft strm
- | Warning ->
- let header = ("Warning", warning_tag) in
- Flags.if_warn (fun () -> msg ~header !err_ft strm) ()
- | Error -> msg ~header:("Error", error_tag) !err_ft strm
in
- let () = set_logger logger in
- ()
+ pp_with ~pp_tag ft strm;
+ Format.pp_print_newline ft ();
+ Format.pp_print_flush ft ();
+ (** In case something went wrong, we reset the stack *)
+ !clear_tag_fn ()
diff --git a/lib/ppstyle.mli b/lib/ppstyle.mli
index 97b5869f9..1cd701ed4 100644
--- a/lib/ppstyle.mli
+++ b/lib/ppstyle.mli
@@ -11,7 +11,8 @@
(** {5 Style tags} *)
-type t
+type t = string
+
(** Style tags *)
val make : ?style:Terminal.style -> string list -> t
@@ -46,12 +47,11 @@ val dump : unit -> (t * Terminal.style option) list
(** {5 Setting color output} *)
val init_color_output : unit -> unit
-(** Once called, all tags defined here will use their current style when
- printed. To this end, this function redefines the loggers used when sending
- messages to the user. The program will in particular use the formatters
- {!Pp_control.std_ft} and {!Pp_control.err_ft} to display those messages,
- with additional syle information provided by this module. Be careful this is
- not compatible with the Emacs mode! *)
+
+val color_msg : ?header:string * Format.tag ->
+ Format.formatter -> Pp.std_ppcmds -> unit
+(** {!color_msg ?header fmt pp} will format according to the tags
+ defined in this file *)
val pp_tag : Pp.tag_handler
(** Returns the name of a style tag that is understandable by the formatters
diff --git a/lib/richpp.ml b/lib/richpp.ml
index fe3edd99c..a98273edb 100644
--- a/lib/richpp.ml
+++ b/lib/richpp.ml
@@ -194,7 +194,3 @@ let raw_print xml =
let () = print xml in
Buffer.contents buf
-let of_richpp x = Element ("richpp", [], [x])
-let to_richpp xml = match xml with
-| Element ("richpp", [], [x]) -> x
-| _ -> raise Serialize.Marshal_error
diff --git a/lib/richpp.mli b/lib/richpp.mli
index 807d52aba..287d265a8 100644
--- a/lib/richpp.mli
+++ b/lib/richpp.mli
@@ -57,10 +57,7 @@ val richpp_of_string : string -> richpp
val repr : richpp -> Xml_datatype.xml
(** Observe the styled text as XML *)
-(** {5 Serialization} *)
-
-val of_richpp : richpp -> Xml_datatype.xml
-val to_richpp : Xml_datatype.xml -> richpp
+(** {5 Debug/Compat} *)
(** Represent the semi-structured document as a string, dropping any additional
information. *)
diff --git a/lib/spawn.ml b/lib/spawn.ml
index 4d35ded90..2b9c4ccac 100644
--- a/lib/spawn.ml
+++ b/lib/spawn.ml
@@ -78,20 +78,6 @@ let accept (sr,sw) =
set_binary_mode_out cout true;
(csr, csw), cin, cout
-let handshake cin cout =
- try
- output_value cout (Hello (proto_version,Unix.getpid ())); flush cout;
- match input_value cin with
- | Hello(v, pid) when v = proto_version ->
- prerr_endline (Printf.sprintf "Handshake with %d OK" pid);
- pid
- | _ -> raise (Failure "handshake protocol")
- with
- | Failure s | Invalid_argument s | Sys_error s ->
- pr_err ("Handshake failed: " ^ s); raise (Failure "handshake")
- | End_of_file ->
- pr_err "Handshake failed: End_of_file"; raise (Failure "handshake")
-
let spawn_sock env prog args =
let main_sock, main_sock_name = mk_socket_channel () in
let extra = [| prog; "-main-channel"; main_sock_name |] in
@@ -220,10 +206,13 @@ let stats { oob_req; oob_resp; alive } =
input_value oob_resp
let rec wait p =
- try snd (Unix.waitpid [] p.pid)
- with
- | Unix.Unix_error (Unix.EINTR, _, _) -> wait p
- | Unix.Unix_error _ -> Unix.WEXITED 0o400
+ (* On windows kill is not reliable, so wait may never return. *)
+ if Sys.os_type = "Unix" then
+ try snd (Unix.waitpid [] p.pid)
+ with
+ | Unix.Unix_error (Unix.EINTR, _, _) -> wait p
+ | Unix.Unix_error _ -> Unix.WEXITED 0o400
+ else Unix.WEXITED 0o400
end
@@ -267,8 +256,13 @@ let stats { oob_req; oob_resp; alive } =
flush oob_req;
let RespStats g = input_value oob_resp in g
-let wait { pid = unixpid } =
- try snd (Unix.waitpid [] unixpid)
- with Unix.Unix_error _ -> Unix.WEXITED 0o400
+let rec wait p =
+ (* On windows kill is not reliable, so wait may never return. *)
+ if Sys.os_type = "Unix" then
+ try snd (Unix.waitpid [] p.pid)
+ with
+ | Unix.Unix_error (Unix.EINTR, _, _) -> wait p
+ | Unix.Unix_error _ -> Unix.WEXITED 0o400
+ else Unix.WEXITED 0o400
end
diff --git a/lib/stateid.ml b/lib/stateid.ml
index 59cf206e2..500581a39 100644
--- a/lib/stateid.ml
+++ b/lib/stateid.ml
@@ -6,8 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Xml_datatype
-
type t = int
let initial = 1
let dummy = 0
@@ -15,20 +13,14 @@ let fresh, in_range =
let cur = ref initial in
(fun () -> incr cur; !cur), (fun id -> id >= 0 && id <= !cur)
let to_string = string_of_int
-let of_int id = assert(in_range id); id
+let of_int id =
+ (* Coqide too to parse ids too, but cannot check if they are valid.
+ * Hence we check for validity only if we are an ide slave. *)
+ if !Flags.ide_slave then assert (in_range id);
+ id
let to_int id = id
let newer_than id1 id2 = id1 > id2
-let of_xml = function
- | Element ("state_id",["val",i],[]) ->
- let id = int_of_string i in
- (* Coqide too to parse ids too, but cannot check if they are valid.
- * Hence we check for validity only if we are an ide slave. *)
- if !Flags.ide_slave then assert(in_range id);
- id
- | _ -> raise (Invalid_argument "to_state_id")
-let to_xml i = Element ("state_id",["val",string_of_int i],[])
-
let state_id_info : (t * t) Exninfo.t = Exninfo.make ()
let add exn ?(valid = initial) id =
Exninfo.add exn state_id_info (valid, id)
@@ -37,7 +29,13 @@ let get exn = Exninfo.get exn state_id_info
let equal = Int.equal
let compare = Int.compare
-module Set = Set.Make(struct type t = int let compare = compare end)
+module Self = struct
+ type t = int
+ let compare = compare
+ let equal = equal
+end
+
+module Set = Set.Make(Self)
type ('a,'b) request = {
exn_info : t * t;
diff --git a/lib/stateid.mli b/lib/stateid.mli
index 2c12c30c3..cd8fddf0c 100644
--- a/lib/stateid.mli
+++ b/lib/stateid.mli
@@ -6,26 +6,23 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Xml_datatype
-
type t
val equal : t -> t -> bool
val compare : t -> t -> int
-module Set : Set.S with type elt = t
+module Self : Map.OrderedType with type t = t
+module Set : Set.S with type elt = t and type t = Set.Make(Self).t
val initial : t
val dummy : t
val fresh : unit -> t
val to_string : t -> string
+
val of_int : int -> t
val to_int : t -> int
-val newer_than : t -> t -> bool
-(* XML marshalling *)
-val to_xml : t -> xml
-val of_xml : xml -> t
+val newer_than : t -> t -> bool
(* Attaches to an exception the concerned state id, plus an optional
* state id that is a valid state id before the error.
diff --git a/lib/system.ml b/lib/system.ml
index 13cfad4ae..8b53a11d6 100644
--- a/lib/system.ml
+++ b/lib/system.ml
@@ -12,63 +12,7 @@ open Pp
open Errors
open Util
-(** Dealing with directories *)
-
-type unix_path = string (* path in unix-style, with '/' separator *)
-
-type file_kind =
- | FileDir of unix_path * (* basename of path: *) string
- | FileRegular of string (* basename of file *)
-
-(* Copy of Filename.concat but assuming paths to always be POSIX *)
-
-let (//) dirname filename =
- let l = String.length dirname in
- if l = 0 || dirname.[l-1] = '/'
- then dirname ^ filename
- else dirname ^ "/" ^ filename
-
-(* Excluding directories; We avoid directories starting with . as well
- as CVS and _darcs and any subdirs given via -exclude-dir *)
-
-let skipped_dirnames = ref ["CVS"; "_darcs"]
-
-let exclude_directory f = skipped_dirnames := f :: !skipped_dirnames
-
-let ok_dirname f =
- not (f = "") && f.[0] != '.' &&
- not (List.mem f !skipped_dirnames) (*&&
- (match Unicode.ident_refutation f with None -> true | _ -> false)*)
-
-(* Check directory can be opened *)
-
-let exists_dir dir =
- try Sys.is_directory dir with Sys_error _ -> false
-
-let check_unix_dir warn dir =
- if (Sys.os_type = "Win32" || Sys.os_type = "Cygwin") &&
- (String.length dir > 2 && dir.[1] = ':' ||
- String.contains dir '\\' ||
- String.contains dir ';')
- then warn ("assuming " ^ dir ^
- " to be a Unix path even if looking like a Win32 path.")
-
-let apply_subdir f path name =
- (* we avoid all files and subdirs starting by '.' (e.g. .svn) *)
- (* as well as skipped files like CVS, ... *)
- if ok_dirname name then
- let path = if path = "." then name else path//name in
- match try (Unix.stat path).Unix.st_kind with Unix.Unix_error _ -> Unix.S_BLK with
- | Unix.S_DIR -> f (FileDir (path,name))
- | Unix.S_REG -> f (FileRegular name)
- | _ -> ()
-
-let process_directory f path =
- Array.iter (apply_subdir f path) (Sys.readdir path)
-
-let process_subdirectories f path =
- let f = function FileDir (path,base) -> f path base | FileRegular _ -> () in
- process_directory f path
+include Minisys
(** Returns the list of all recursive subdirectories of [root] in
depth-first search, with sons ordered as on the file system;
@@ -86,9 +30,9 @@ let all_subdirs ~unix_path:root =
| _ -> ()
in process_directory f path
in
- check_unix_dir (fun s -> msg_warning (str s)) root;
+ check_unix_dir (fun s -> Feedback.msg_warning (str s)) root;
if exists_dir root then traverse root []
- else msg_warning (str ("Cannot open " ^ root));
+ else Feedback.msg_warning (str ("Cannot open " ^ root));
List.rev !l
(* Caching directory contents for efficient syntactic equality of file
@@ -106,7 +50,7 @@ let dirmap = ref StrMap.empty
let make_dir_table dir =
let filter_dotfiles s f = if f.[0] = '.' then s else StrSet.add f s in
- Array.fold_left filter_dotfiles StrSet.empty (Sys.readdir dir)
+ Array.fold_left filter_dotfiles StrSet.empty (readdir dir)
let exists_in_dir_respecting_case dir bf =
let cache_dir dir =
@@ -147,7 +91,7 @@ let where_in_path ?(warn=true) path filename =
| (lpe, f) :: l' ->
let () = match l' with
| _ :: _ when warn ->
- msg_warning
+ Feedback.msg_warning
(str filename ++ str " has been found in" ++ spc () ++
hov 0 (str "[ " ++
hv 0 (prlist_with_sep (fun () -> str " " ++ pr_semicolon())
@@ -203,7 +147,7 @@ let is_in_system_path filename =
let lpath = CUnix.path_to_list (Sys.getenv "PATH") in
is_in_path lpath filename
with Not_found ->
- msg_warning (str "system variable PATH not found");
+ Feedback.msg_warning (str "system variable PATH not found");
false
let open_trapping_failure name =
@@ -214,7 +158,7 @@ let open_trapping_failure name =
let try_remove filename =
try Sys.remove filename
with e when Errors.noncritical e ->
- msg_warning
+ Feedback.msg_warning
(str"Could not remove file " ++ str filename ++ str" which is corrupted!")
let error_corrupted file s =
@@ -262,7 +206,8 @@ let skip_in_segment f ch =
seek_in ch stop;
stop, digest_in f ch
-exception Bad_magic_number of string
+type magic_number_error = {filename: string; actual: int; expected: int}
+exception Bad_magic_number of magic_number_error
let raw_extern_state magic filename =
let channel = open_trapping_failure filename in
@@ -272,8 +217,12 @@ let raw_extern_state magic filename =
let raw_intern_state magic filename =
try
let channel = open_in_bin filename in
- if not (Int.equal (input_binary_int filename channel) magic) then
- raise (Bad_magic_number filename);
+ let actual_magic = input_binary_int filename channel in
+ if not (Int.equal actual_magic magic) then
+ raise (Bad_magic_number {
+ filename=filename;
+ actual=actual_magic;
+ expected=magic});
channel
with
| End_of_file -> error_corrupted filename "premature end of file"
@@ -303,9 +252,11 @@ let intern_state magic filename =
let with_magic_number_check f a =
try f a
- with Bad_magic_number fname ->
+ with Bad_magic_number {filename=fname;actual=actual;expected=expected} ->
errorlabstrm "with_magic_number_check"
- (str"File " ++ str fname ++ strbrk" has bad magic number." ++ spc () ++
+ (str"File " ++ str fname ++ strbrk" has bad magic number " ++
+ int actual ++ str" (expected " ++ int expected ++ str")." ++
+ spc () ++
strbrk "It is corrupted or was compiled with another version of Coq.")
(* Time stamps. *)
@@ -336,13 +287,13 @@ let with_time time f x =
let y = f x in
let tend = get_time() in
let msg2 = if time then "" else " (successful)" in
- msg_info (str msg ++ fmt_time_difference tstart tend ++ str msg2);
+ Feedback.msg_info (str msg ++ fmt_time_difference tstart tend ++ str msg2);
y
with e ->
let tend = get_time() in
let msg = if time then "" else "Finished failing transaction in " in
let msg2 = if time then "" else " (failure)" in
- msg_info (str msg ++ fmt_time_difference tstart tend ++ str msg2);
+ Feedback.msg_info (str msg ++ fmt_time_difference tstart tend ++ str msg2);
raise e
let process_id () =
diff --git a/lib/system.mli b/lib/system.mli
index e1190dfb5..4dbb3695d 100644
--- a/lib/system.mli
+++ b/lib/system.mli
@@ -64,9 +64,11 @@ val file_exists_respecting_case : string -> string -> bool
(** {6 I/O functions } *)
(** Generic input and output functions, parameterized by a magic number
and a suffix. The intern functions raise the exception [Bad_magic_number]
- when the check fails, with the full file name. *)
+ when the check fails, with the full file name and expected/observed magic
+ numbers. *)
-exception Bad_magic_number of string
+type magic_number_error = {filename: string; actual: int; expected: int}
+exception Bad_magic_number of magic_number_error
val raw_extern_state : int -> string -> out_channel
diff --git a/lib/unicode.ml b/lib/unicode.ml
index 05998bb80..dc852d981 100644
--- a/lib/unicode.ml
+++ b/lib/unicode.ml
@@ -173,6 +173,13 @@ let next_utf8 s i =
(c land 0x3F) lsl 6 + (d land 0x3F)
else err ()
+let is_utf8 s =
+ let rec check i =
+ let (off, _) = next_utf8 s i in
+ check (i + off)
+ in
+ try check 0 with End_of_input -> true | Invalid_argument _ -> false
+
(* Check the well-formedness of an identifier *)
let initial_refutation j n s =
@@ -233,14 +240,94 @@ let is_basic_ascii s =
!ok
let ascii_of_ident s =
- if is_basic_ascii s then s else
- let i = ref 0 and out = ref "" in
- begin try while true do
+ let len = String.length s in
+ let has_UU i =
+ i+2 < len && s.[i]='_' && s.[i+1]='U' && s.[i+2]='U'
+ in
+ let i = ref 0 in
+ while !i < len && Char.code s.[!i] < 128 && not (has_UU !i) do
+ incr i
+ done;
+ if !i = len then s else
+ let out = Buffer.create (2*len) in
+ Buffer.add_substring out s 0 !i;
+ while !i < len do
let j, n = next_utf8 s !i in
- out :=
- if n >= 128
- then Printf.sprintf "%s__U%04x_" !out n
- else Printf.sprintf "%s%c" !out s.[!i];
- i := !i + j
- done with End_of_input -> () end;
- !out
+ if n >= 128 then
+ (Printf.bprintf out "_UU%04x_" n; i := !i + j)
+ else if has_UU !i then
+ (Buffer.add_string out "_UUU"; i := !i + 3)
+ else
+ (Buffer.add_char out s.[!i]; incr i)
+ done;
+ Buffer.contents out
+
+(* Compute length of an UTF-8 encoded string
+ Rem 1 : utf8_length <= String.length (equal if pure ascii)
+ Rem 2 : if used for an iso8859_1 encoded string, the result is
+ wrong in very rare cases. Such a wrong case corresponds to any
+ sequence of a character in range 192..253 immediately followed by a
+ character in range 128..191 (typical case in french is "déçu" which
+ is counted 3 instead of 4); then no real harm to use always
+ utf8_length even if using an iso8859_1 encoding *)
+
+(** FIXME: duplicate code with Pp *)
+
+let utf8_length s =
+ let len = String.length s
+ and cnt = ref 0
+ and nc = ref 0
+ and p = ref 0 in
+ while !p < len do
+ begin
+ match s.[!p] with
+ | '\000'..'\127' -> nc := 0 (* ascii char *)
+ | '\128'..'\191' -> nc := 0 (* cannot start with a continuation byte *)
+ | '\192'..'\223' -> nc := 1 (* expect 1 continuation byte *)
+ | '\224'..'\239' -> nc := 2 (* expect 2 continuation bytes *)
+ | '\240'..'\247' -> nc := 3 (* expect 3 continuation bytes *)
+ | '\248'..'\251' -> nc := 4 (* expect 4 continuation bytes *)
+ | '\252'..'\253' -> nc := 5 (* expect 5 continuation bytes *)
+ | '\254'..'\255' -> nc := 0 (* invalid byte *)
+ end ;
+ incr p ;
+ while !p < len && !nc > 0 do
+ match s.[!p] with
+ | '\128'..'\191' (* next continuation byte *) -> incr p ; decr nc
+ | _ (* not a continuation byte *) -> nc := 0
+ done ;
+ incr cnt
+ done ;
+ !cnt
+
+(* Variant of String.sub for UTF8 character positions *)
+let utf8_sub s start_u len_u =
+ let len_b = String.length s
+ and end_u = start_u + len_u
+ and cnt = ref 0
+ and nc = ref 0
+ and p = ref 0 in
+ let start_b = ref len_b in
+ while !p < len_b && !cnt < end_u do
+ if !cnt <= start_u then start_b := !p ;
+ begin
+ match s.[!p] with
+ | '\000'..'\127' -> nc := 0 (* ascii char *)
+ | '\128'..'\191' -> nc := 0 (* cannot start with a continuation byte *)
+ | '\192'..'\223' -> nc := 1 (* expect 1 continuation byte *)
+ | '\224'..'\239' -> nc := 2 (* expect 2 continuation bytes *)
+ | '\240'..'\247' -> nc := 3 (* expect 3 continuation bytes *)
+ | '\248'..'\251' -> nc := 4 (* expect 4 continuation bytes *)
+ | '\252'..'\253' -> nc := 5 (* expect 5 continuation bytes *)
+ | '\254'..'\255' -> nc := 0 (* invalid byte *)
+ end ;
+ incr p ;
+ while !p < len_b && !nc > 0 do
+ match s.[!p] with
+ | '\128'..'\191' (* next continuation byte *) -> incr p ; decr nc
+ | _ (* not a continuation byte *) -> nc := 0
+ done ;
+ incr cnt
+ done ;
+ let end_b = !p in
+ String.sub s !start_b (end_b - !start_b)
diff --git a/lib/unicode.mli b/lib/unicode.mli
index 72d1f2950..1f8bd44ee 100644
--- a/lib/unicode.mli
+++ b/lib/unicode.mli
@@ -27,12 +27,22 @@ val ident_refutation : string -> (bool * string) option
@raise Assert_failure if the input string is empty. *)
val lowercase_first_char : string -> string
-(** Return [true] if all UTF-8 characters in the input string are just plain ASCII characters.
- Returns [false] otherwise. *)
+(** Return [true] if all UTF-8 characters in the input string are just plain
+ ASCII characters. Returns [false] otherwise. *)
val is_basic_ascii : string -> bool
-(** [ascii_of_ident s] maps UTF-8 string to a string composed solely from ASCII characters.
- Those UTF-8 characters which do not have their ASCII counterparts are
- translated to ["__Uxxxx_"] where {i xxxx} are four hexadecimal digits.
- @raise Unsupported if the input string contains unsupported UTF-8 characters. *)
+(** [ascii_of_ident s] maps UTF-8 string to a string composed solely from ASCII
+ characters. The non-ASCII characters are translated to ["_UUxxxx_"] where
+ {i xxxx} is the Unicode index of the character in hexadecimal (from four
+ to six hex digits). To avoid potential name clashes, any preexisting
+ substring ["_UU"] is turned into ["_UUU"]. *)
val ascii_of_ident : string -> string
+
+(** Validate an UTF-8 string *)
+val is_utf8 : string -> bool
+
+(** Return the length of a valid UTF-8 string. *)
+val utf8_length : string -> int
+
+(** Variant of {!String.sub} for UTF-8 strings. *)
+val utf8_sub : string -> int -> int -> string
diff --git a/lib/util.ml b/lib/util.ml
index 0f79c10df..009dfbe1c 100644
--- a/lib/util.ml
+++ b/lib/util.ml
@@ -132,9 +132,24 @@ type ('a, 'b) union = ('a, 'b) CSig.union = Inl of 'a | Inr of 'b
type 'a until = 'a CSig.until = Stop of 'a | Cont of 'a
type ('a, 'b) eq = ('a, 'b) CSig.eq = Refl : ('a, 'a) eq
-let map_union f g = function
- | Inl a -> Inl (f a)
- | Inr b -> Inr (g b)
+module Union =
+struct
+ let map f g = function
+ | Inl a -> Inl (f a)
+ | Inr b -> Inr (g b)
+
+ (** Lifting equality onto union types. *)
+ let equal f g x y = match x, y with
+ | Inl x, Inl y -> f x y
+ | Inr x, Inr y -> g x y
+ | _, _ -> false
+
+ let fold_left f g a = function
+ | Inl y -> f a y
+ | Inr y -> g a y
+end
+
+let map_union = Union.map
type iexn = Exninfo.iexn
diff --git a/lib/util.mli b/lib/util.mli
index 559874bb8..6bed7e355 100644
--- a/lib/util.mli
+++ b/lib/util.mli
@@ -114,7 +114,15 @@ val iraise : iexn -> 'a
type ('a, 'b) union = ('a, 'b) CSig.union = Inl of 'a | Inr of 'b
(** Union type *)
+module Union :
+sig
+ val map : ('a -> 'c) -> ('b -> 'd) -> ('a, 'b) union -> ('c, 'd) union
+ val equal : ('a -> 'a -> bool) -> ('b -> 'b -> bool) -> ('a, 'b) union -> ('a, 'b) union -> bool
+ val fold_left : ('c -> 'a -> 'c) -> ('c -> 'b -> 'c) -> 'c -> ('a, 'b) union -> 'c
+end
+
val map_union : ('a -> 'c) -> ('b -> 'd) -> ('a, 'b) union -> ('c, 'd) union
+(** Alias for [Union.map] *)
type 'a until = 'a CSig.until = Stop of 'a | Cont of 'a
(** Used for browsable-until structures. *)
diff --git a/library/declare.ml b/library/declare.ml
index c59d190a0..84284fd18 100644
--- a/library/declare.ml
+++ b/library/declare.ml
@@ -398,7 +398,7 @@ let declare_mind mie =
let pr_rank i = pr_nth (i+1)
let fixpoint_message indexes l =
- Flags.if_verbose msg_info (match l with
+ Flags.if_verbose Feedback.msg_info (match l with
| [] -> anomaly (Pp.str "no recursive definition")
| [id] -> pr_id id ++ str " is recursively defined" ++
(match indexes with
@@ -413,7 +413,7 @@ let fixpoint_message indexes l =
| None -> mt ()))
let cofixpoint_message l =
- Flags.if_verbose msg_info (match l with
+ Flags.if_verbose Feedback.msg_info (match l with
| [] -> anomaly (Pp.str "No corecursive definition.")
| [id] -> pr_id id ++ str " is corecursively defined"
| l -> hov 0 (prlist_with_sep pr_comma pr_id l ++
@@ -423,13 +423,13 @@ let recursive_message isfix i l =
(if isfix then fixpoint_message i else cofixpoint_message) l
let definition_message id =
- Flags.if_verbose msg_info (pr_id id ++ str " is defined")
+ Flags.if_verbose Feedback.msg_info (pr_id id ++ str " is defined")
let assumption_message id =
(* Changing "assumed" to "declared", "assuming" referring more to
the type of the object than to the name of the object (see
discussion on coqdev: "Chapter 4 of the Reference Manual", 8/10/2015) *)
- Flags.if_verbose msg_info (pr_id id ++ str " is declared")
+ Flags.if_verbose Feedback.msg_info (pr_id id ++ str " is declared")
(** Global universe names, in a different summary *)
@@ -440,8 +440,9 @@ let cache_universes (p, l) =
let glob = Universes.global_universe_names () in
let glob', ctx =
List.fold_left (fun ((idl,lid),ctx) (id, lev) ->
- ((Idmap.add id lev idl, Univ.LMap.add lev id lid),
- Univ.ContextSet.add_universe lev ctx))
+ ((Idmap.add id (p, lev) idl,
+ Univ.LMap.add lev id lid),
+ Univ.ContextSet.add_universe lev ctx))
(glob, Univ.ContextSet.empty) l
in
Global.push_context_set p ctx;
@@ -457,6 +458,12 @@ let input_universes : universe_decl -> Libobject.obj =
classify_function = (fun a -> Keep a) }
let do_universe poly l =
+ let in_section = Lib.sections_are_opened () in
+ let () =
+ if poly && not in_section then
+ user_err_loc (Loc.ghost, "Constraint",
+ str"Cannot declare polymorphic universes outside sections")
+ in
let l =
List.map (fun (l, id) ->
let lev = Universes.new_univ_level (Global.current_dirpath ()) in
@@ -485,14 +492,30 @@ let input_constraints : constraint_decl -> Libobject.obj =
let do_constraint poly l =
let u_of_id =
let names, _ = Universes.global_universe_names () in
- fun (loc, id) ->
- try Idmap.find id names
- with Not_found ->
- user_err_loc (loc, "Constraint", str "Undeclared universe " ++ pr_id id)
+ fun (loc, id) ->
+ try Idmap.find id names
+ with Not_found ->
+ user_err_loc (loc, "Constraint", str "Undeclared universe " ++ pr_id id)
+ in
+ let in_section = Lib.sections_are_opened () in
+ let () =
+ if poly && not in_section then
+ user_err_loc (Loc.ghost, "Constraint",
+ str"Cannot declare polymorphic constraints outside sections")
+ in
+ let check_poly loc p loc' p' =
+ if poly then ()
+ else if p || p' then
+ let loc = if p then loc else loc' in
+ user_err_loc (loc, "Constraint",
+ str "Cannot declare a global constraint on " ++
+ str "a polymorphic universe, use "
+ ++ str "Polymorphic Constraint instead")
in
let constraints = List.fold_left (fun acc (l, d, r) ->
- let lu = u_of_id l and ru = u_of_id r in
- Univ.Constraint.add (lu, d, ru) acc)
+ let p, lu = u_of_id l and p', ru = u_of_id r in
+ check_poly (fst l) p (fst r) p';
+ Univ.Constraint.add (lu, d, ru) acc)
Univ.Constraint.empty l
in
Lib.add_anonymous_leaf (input_constraints (poly, constraints))
diff --git a/library/declaremods.ml b/library/declaremods.ml
index 4c9c40a73..dcd63c769 100644
--- a/library/declaremods.ml
+++ b/library/declaremods.ml
@@ -642,7 +642,11 @@ let declare_module interp_modast id args res mexpr_o fs =
let env = Global.env () in
let mty_entry_o, subs, inl_res = match res with
| Enforce (mty,ann) ->
- Some (fst (interp_modast env ModType mty)), [], inl2intopt ann
+ let inl = inl2intopt ann in
+ let mte, _ = interp_modast env ModType mty in
+ (* We check immediately that mte is well-formed *)
+ let _ = Mod_typing.translate_mse env None inl mte in
+ Some mte, [], inl
| Check mtys ->
None, build_subtypes interp_modast env mp arg_entries_r mtys,
default_inline ()
@@ -727,7 +731,10 @@ let declare_modtype interp_modast id args mtys (mty,ann) fs =
let arg_entries_r = intern_args interp_modast args in
let params = mk_params_entry arg_entries_r in
let env = Global.env () in
- let entry = params, fst (interp_modast env ModType mty) in
+ let mte, _ = interp_modast env ModType mty in
+ (* We check immediately that mte is well-formed *)
+ let _ = Mod_typing.translate_mse env None inl mte in
+ let entry = params, mte in
let sub_mty_l = build_subtypes interp_modast env mp arg_entries_r mtys in
let sobjs = get_functor_sobjs false env inl entry in
let subst = map_mp (get_module_path (snd entry)) mp empty_delta_resolver in
@@ -890,7 +897,13 @@ let start_library dir =
Lib.start_compilation dir mp;
Lib.add_frozen_state ()
+let end_library_hook = ref ignore
+let append_end_library_hook f =
+ let old_f = !end_library_hook in
+ end_library_hook := fun () -> old_f(); f ()
+
let end_library ?except dir =
+ !end_library_hook();
let oname = Lib.end_compilation_checks dir in
let mp,cenv,ast = Global.export ?except dir in
let prefix, lib_stack = Lib.end_compilation oname in
diff --git a/library/declaremods.mli b/library/declaremods.mli
index 2b440c087..3917fe8d6 100644
--- a/library/declaremods.mli
+++ b/library/declaremods.mli
@@ -90,6 +90,9 @@ val end_library :
?except:Future.UUIDSet.t -> library_name ->
Safe_typing.compiled_library * library_objects * Safe_typing.native_library
+(** append a function to be executed at end_library *)
+val append_end_library_hook : (unit -> unit) -> unit
+
(** [really_import_module mp] opens the module [mp] (in a Caml sense).
It modifies Nametab and performs the [open_object] function for
every object of the module. Raises [Not_found] when [mp] is unknown
diff --git a/library/globnames.ml b/library/globnames.ml
index cf0e37174..bec463ecf 100644
--- a/library/globnames.ml
+++ b/library/globnames.ml
@@ -107,17 +107,16 @@ let global_eq_gen eq_cst eq_ind eq_cons x y =
let global_ord_gen ord_cst ord_ind ord_cons x y =
if x == y then 0
else match x, y with
+ | VarRef v1, VarRef v2 -> Id.compare v1 v2
+ | VarRef _, _ -> -1
+ | _, VarRef _ -> 1
| ConstRef cx, ConstRef cy -> ord_cst cx cy
+ | ConstRef _, _ -> -1
+ | _, ConstRef _ -> 1
| IndRef indx, IndRef indy -> ord_ind indx indy
+ | IndRef _, _ -> -1
+ | _ , IndRef _ -> 1
| ConstructRef consx, ConstructRef consy -> ord_cons consx consy
- | VarRef v1, VarRef v2 -> Id.compare v1 v2
-
- | VarRef _, (ConstRef _ | IndRef _ | ConstructRef _) -> -1
- | ConstRef _, VarRef _ -> 1
- | ConstRef _, (IndRef _ | ConstructRef _) -> -1
- | IndRef _, (VarRef _ | ConstRef _) -> 1
- | IndRef _, ConstructRef _ -> -1
- | ConstructRef _, (VarRef _ | ConstRef _ | IndRef _) -> 1
let global_hash_gen hash_cst hash_ind hash_cons gr =
let open Hashset.Combine in
diff --git a/library/goptions.ml b/library/goptions.ml
index 5f6512e11..4aa3a2a21 100644
--- a/library/goptions.ml
+++ b/library/goptions.ml
@@ -108,7 +108,8 @@ module MakeTable =
(fun c -> t := MySet.remove c !t))
let print_table table_name printer table =
- pp (str table_name ++
+ Feedback.msg_notice
+ (str table_name ++
(hov 0
(if MySet.is_empty table then str " None" ++ fnl ()
else MySet.fold
@@ -122,7 +123,7 @@ module MakeTable =
method mem x =
let y = A.encode x in
let answer = MySet.mem y !t in
- msg_info (A.member_message y answer)
+ Feedback.msg_info (A.member_message y answer)
method print = print_table A.title A.printer !t
end
@@ -271,7 +272,7 @@ let declare_option cast uncast
in
let warn () =
if depr then
- msg_warning (str "Option " ++ str (nickname key) ++ str " is deprecated")
+ Feedback.msg_warning (str "Option " ++ str (nickname key) ++ str " is deprecated")
in
let cread () = cast (read ()) in
let cwrite v = warn (); write (uncast v) in
@@ -346,12 +347,12 @@ let set_int_option_value_gen locality =
set_option_value locality check_int_value
let set_bool_option_value_gen locality key v =
try set_option_value locality check_bool_value key v
- with UserError (_,s) -> msg_warning s
+ with UserError (_,s) -> Feedback.msg_warning s
let set_string_option_value_gen locality =
set_option_value locality check_string_value
let unset_option_value_gen locality key =
try set_option_value locality check_unset_value key ()
- with UserError (_,s) -> msg_warning s
+ with UserError (_,s) -> Feedback.msg_warning s
let set_int_option_value = set_int_option_value_gen None
let set_bool_option_value = set_bool_option_value_gen None
@@ -375,9 +376,9 @@ let print_option_value key =
let s = read () in
match s with
| BoolValue b ->
- msg_info (str "The " ++ str name ++ str " mode is " ++ str (if b then "on" else "off"))
+ Feedback.msg_info (str "The " ++ str name ++ str " mode is " ++ str (if b then "on" else "off"))
| _ ->
- msg_info (str "Current value of " ++ str name ++ str " is " ++ msg_option_value (name, s))
+ Feedback.msg_info (str "Current value of " ++ str name ++ str " is " ++ msg_option_value (name, s))
let get_tables () =
let tables = !value_tab in
diff --git a/library/libobject.ml b/library/libobject.ml
index bbbb134df..b12d2038a 100644
--- a/library/libobject.ml
+++ b/library/libobject.ml
@@ -78,20 +78,9 @@ let object_tag (Dyn.Dyn (t, _)) = Dyn.repr t
let cache_tab =
(Hashtbl.create 17 : (string,dynamic_object_declaration) Hashtbl.t)
-let make_dyn (type a) (tag : a Dyn.tag) =
- let infun x = Dyn.Dyn (tag, x) in
- let outfun : (Dyn.t -> a) = fun dyn ->
- let Dyn.Dyn (t, x) = dyn in
- match Dyn.eq t tag with
- | None -> assert false
- | Some Refl -> x
- in
- (infun, outfun)
-
let declare_object_full odecl =
let na = odecl.object_name in
- let tag = Dyn.create na in
- let (infun, outfun) = make_dyn tag in
+ let (infun, outfun) = Dyn.Easy.make_dyn na in
let cacher (oname,lobj) = odecl.cache_function (oname,outfun lobj)
and loader i (oname,lobj) = odecl.load_function i (oname,outfun lobj)
and opener i (oname,lobj) = odecl.open_function i (oname,outfun lobj)
@@ -144,7 +133,7 @@ let apply_dyn_fun deflt f lobj =
Failure "local to_apply_dyn_fun" ->
if not (!relax_flag || Hashtbl.mem missing_tab tag) then
begin
- Pp.msg_warning
+ Feedback.msg_warning
(Pp.str ("Cannot find library functions for an object with tag "
^ tag ^ " (a plugin may be missing)"));
Hashtbl.add missing_tab tag ()
diff --git a/library/library.ml b/library/library.ml
index c41e10608..bc7723f48 100644
--- a/library/library.ml
+++ b/library/library.ml
@@ -35,7 +35,7 @@ module Delayed :
sig
type 'a delayed
-val in_delayed : string -> in_channel -> 'a delayed
+val in_delayed : string -> in_channel -> 'a delayed * Digest.t
val fetch_delayed : 'a delayed -> 'a
end =
@@ -50,7 +50,7 @@ type 'a delayed = {
let in_delayed f ch =
let pos = pos_in ch in
let _, digest = System.skip_in_segment f ch in
- { del_file = f; del_digest = digest; del_off = pos; }
+ ({ del_file = f; del_digest = digest; del_off = pos; }, digest)
(** Fetching a table of opaque terms at position [pos] in file [f],
expecting to find first a copy of [digest]. *)
@@ -171,9 +171,8 @@ let register_loaded_library m =
let prefix = Nativecode.mod_uid_of_dirpath libname ^ "." in
let f = prefix ^ "cmo" in
let f = Dynlink.adapt_filename f in
- (* This will not produce errors or warnings if the native compiler was
- not enabled *)
- Nativelib.link_library ~prefix ~dirname ~basename:f
+ if not Coq_config.no_native_compiler then
+ Nativelib.link_library ~prefix ~dirname ~basename:f
in
let rec aux = function
| [] -> link m; [libname]
@@ -288,7 +287,7 @@ let locate_absolute_library dir =
| [] -> raise LibNotFound
| [file] -> file
| [vo;vi] when Unix.((stat vo).st_mtime < (stat vi).st_mtime) ->
- msg_warning (str"Loading " ++ str vi ++ str " instead of " ++
+ Feedback.msg_warning (str"Loading " ++ str vi ++ str " instead of " ++
str vo ++ str " because it is more recent");
vi
| [vo;vi] -> vo
@@ -312,7 +311,7 @@ let locate_qualified_library ?root ?(warn = true) qid =
| [lpath, file] -> lpath, file
| [lpath_vo, vo; lpath_vi, vi]
when Unix.((stat vo).st_mtime < (stat vi).st_mtime) ->
- msg_warning (str"Loading " ++ str vi ++ str " instead of " ++
+ Feedback.msg_warning (str"Loading " ++ str vi ++ str " instead of " ++
str vo ++ str " because it is more recent");
lpath_vi, vi
| [lpath_vo, vo; _ ] -> lpath_vo, vo
@@ -371,7 +370,7 @@ let access_table what tables dp i =
| Fetched t -> t
| ToFetch f ->
let dir_path = Names.DirPath.to_string dp in
- Flags.if_verbose msg_info (str"Fetching " ++ str what++str" from disk for " ++ str dir_path);
+ Flags.if_verbose Feedback.msg_info (str"Fetching " ++ str what++str" from disk for " ++ str dir_path);
let t =
try fetch_delayed f
with Faulty f ->
@@ -428,28 +427,28 @@ let mk_summary m = {
let intern_from_file f =
let ch = raw_intern_library f in
let (lsd : seg_sum), _, digest_lsd = System.marshal_in_segment f ch in
- let (lmd : seg_lib delayed) = in_delayed f ch in
+ let ((lmd : seg_lib delayed), digest_lmd) = in_delayed f ch in
let (univs : seg_univ option), _, digest_u = System.marshal_in_segment f ch in
let _ = System.skip_in_segment f ch in
let _ = System.skip_in_segment f ch in
- let (del_opaque : seg_proofs delayed) = in_delayed f ch in
+ let ((del_opaque : seg_proofs delayed),_) = in_delayed f ch in
close_in ch;
register_library_filename lsd.md_name f;
add_opaque_table lsd.md_name (ToFetch del_opaque);
let open Safe_typing in
match univs with
- | None -> mk_library lsd lmd (Dvo_or_vi digest_lsd) Univ.ContextSet.empty
+ | None -> mk_library lsd lmd (Dvo_or_vi digest_lmd) Univ.ContextSet.empty
| Some (utab,uall,true) ->
add_univ_table lsd.md_name (Fetched utab);
- mk_library lsd lmd (Dvivo (digest_lsd,digest_u)) uall
+ mk_library lsd lmd (Dvivo (digest_lmd,digest_u)) uall
| Some (utab,_,false) ->
add_univ_table lsd.md_name (Fetched utab);
- mk_library lsd lmd (Dvo_or_vi digest_lsd) Univ.ContextSet.empty
+ mk_library lsd lmd (Dvo_or_vi digest_lmd) Univ.ContextSet.empty
module DPMap = Map.Make(DirPath)
let rec intern_library (needed, contents) (dir, f) from =
- Pp.feedback(Feedback.FileDependency (from, DirPath.to_string dir));
+ Feedback.feedback(Feedback.FileDependency (from, DirPath.to_string dir));
(* Look if in the current logical environment *)
try (find_library dir).libsum_digests, (needed, contents)
with Not_found ->
@@ -464,7 +463,7 @@ let rec intern_library (needed, contents) (dir, f) from =
(str "The file " ++ str f ++ str " contains library" ++ spc () ++
pr_dirpath m.library_name ++ spc () ++ str "and not library" ++
spc() ++ pr_dirpath dir);
- Pp.feedback(Feedback.FileLoaded(DirPath.to_string dir, f));
+ Feedback.feedback (Feedback.FileLoaded(DirPath.to_string dir, f));
m.library_digests, intern_library_deps (needed, contents) dir m (Some f)
and intern_library_deps libs dir m from =
@@ -629,17 +628,14 @@ let check_module_name s =
done
| c -> err c
-let start_library f =
- let () = if not (Sys.file_exists f) then
- errorlabstrm "" (hov 0 (str "Can't find file" ++ spc () ++ str f))
- in
+let start_library fo =
let ldir0 =
try
- let lp = Loadpath.find_load_path (Filename.dirname f) in
+ let lp = Loadpath.find_load_path (Filename.dirname fo) in
Loadpath.logical lp
with Not_found -> Nameops.default_root_prefix
in
- let file = Filename.chop_extension (Filename.basename f) in
+ let file = Filename.chop_extension (Filename.basename fo) in
let id = Id.of_string file in
check_module_name file;
check_coq_overwriting ldir0 id;
@@ -694,12 +690,13 @@ let error_recursively_dependent_library dir =
writing the content and computing the checksum... *)
let save_library_to ?todo dir f otab =
- let f, except = match todo with
+ let except = match todo with
| None ->
assert(!Flags.compilation_mode = Flags.BuildVo);
- f ^ "o", Future.UUIDSet.empty
+ assert(Filename.check_suffix f ".vo");
+ Future.UUIDSet.empty
| Some (l,_) ->
- f ^ "io",
+ assert(Filename.check_suffix f ".vio");
List.fold_left (fun e (r,_) -> Future.UUIDSet.add r.Stateid.uuid e)
Future.UUIDSet.empty l in
let cenv, seg, ast = Declaremods.end_library ~except dir in
@@ -756,7 +753,7 @@ let save_library_to ?todo dir f otab =
error "Could not compile the library to native code."
with reraise ->
let reraise = Errors.push reraise in
- let () = msg_warning (str "Removed file " ++ str f') in
+ let () = Feedback.msg_warning (str "Removed file " ++ str f') in
let () = close_out ch in
let () = Sys.remove f' in
iraise reraise
diff --git a/library/library.mli b/library/library.mli
index 8f5b775d8..b9044b60d 100644
--- a/library/library.mli
+++ b/library/library.mli
@@ -37,9 +37,9 @@ type seg_proofs = Term.constr Future.computation array
an export otherwise just a simple import *)
val import_module : bool -> qualid located list -> unit
-(** Start the compilation of a file as a library. The argument must be an
- existing file on the system, and the returned path is the associated
- absolute logical path of the library. *)
+(** Start the compilation of a file as a library. The first argument must be
+ output file, and the
+ returned path is the associated absolute logical path of the library. *)
val start_library : CUnix.physical_path -> DirPath.t
(** End the compilation of a library and save it to a ".vo" file *)
diff --git a/library/loadpath.ml b/library/loadpath.ml
index f8169576d..33c0f41e1 100644
--- a/library/loadpath.ml
+++ b/library/loadpath.ml
@@ -72,7 +72,7 @@ let add_load_path phys_path coq_path ~implicit =
let () =
(* Do not warn when overriding the default "-I ." path *)
if not (DirPath.equal old_path Nameops.default_root_prefix) then
- msg_warning
+ Feedback.msg_warning
(str phys_path ++ strbrk " was previously bound to " ++
pr_dirpath old_path ++ strbrk "; it is remapped to " ++
pr_dirpath coq_path) in
diff --git a/library/nametab.ml b/library/nametab.ml
index bbae98fc0..db902d625 100644
--- a/library/nametab.ml
+++ b/library/nametab.ml
@@ -119,7 +119,7 @@ struct
| Absolute (n,_) ->
(* This is an absolute name, we must keep it
otherwise it may become unaccessible forever *)
- msg_warning (str ("Trying to mask the absolute name \""
+ Feedback.msg_warning (str ("Trying to mask the absolute name \""
^ U.to_string n ^ "\"!"));
tree.path
| Nothing
@@ -155,7 +155,7 @@ let rec push_exactly uname o level tree = function
| Absolute (n,_) ->
(* This is an absolute name, we must keep it
otherwise it may become unaccessible forever *)
- msg_warning (str ("Trying to mask the absolute name \""
+ Feedback.msg_warning (str ("Trying to mask the absolute name \""
^ U.to_string n ^ "\"!"));
tree.path
| Nothing
@@ -525,7 +525,7 @@ let shortest_qualid_of_tactic kn =
let pr_global_env env ref =
try pr_qualid (shortest_qualid_of_global env ref)
with Not_found as e ->
- if !Flags.debug then Pp.msg_debug (Pp.str "pr_global_env not found"); raise e
+ if !Flags.debug then Feedback.msg_debug (Pp.str "pr_global_env not found"); raise e
let global_inductive r =
match global r with
diff --git a/library/summary.ml b/library/summary.ml
index 19e7e5fd9..edea7dbe5 100644
--- a/library/summary.ml
+++ b/library/summary.ml
@@ -22,19 +22,8 @@ let summaries = ref Int.Map.empty
let mangle id = id ^ "-SUMMARY"
-let make_dyn (type a) (tag : a Dyn.tag) =
- let infun x = Dyn.Dyn (tag, x) in
- let outfun : (Dyn.t -> a) = fun dyn ->
- let Dyn.Dyn (t, x) = dyn in
- match Dyn.eq t tag with
- | None -> assert false
- | Some Refl -> x
- in
- (infun, outfun)
-
let internal_declare_summary hash sumname sdecl =
- let tag = Dyn.create (mangle sumname) in
- let (infun, outfun) = make_dyn tag in
+ let (infun, outfun) = Dyn.Easy.make_dyn (mangle sumname) in
let dyn_freeze b = infun (sdecl.freeze_function b)
and dyn_unfreeze sum = sdecl.unfreeze_function (outfun sum)
and dyn_init = sdecl.init_function in
diff --git a/library/universes.ml b/library/universes.ml
index c4eb2afcb..75cbd5604 100644
--- a/library/universes.ml
+++ b/library/universes.ml
@@ -13,10 +13,11 @@ open Term
open Environ
open Univ
open Globnames
+open Decl_kinds
(** Global universe names *)
type universe_names =
- Univ.universe_level Idmap.t * Id.t Univ.LMap.t
+ (polymorphic * Univ.universe_level) Idmap.t * Id.t Univ.LMap.t
let global_universes =
Summary.ref ~name:"Global universe names"
diff --git a/library/universes.mli b/library/universes.mli
index 53cf5f384..a5740ec49 100644
--- a/library/universes.mli
+++ b/library/universes.mli
@@ -19,7 +19,7 @@ val is_set_minimization : unit -> bool
(** Global universe name <-> level mapping *)
type universe_names =
- Univ.universe_level Idmap.t * Id.t Univ.LMap.t
+ (Decl_kinds.polymorphic * Univ.universe_level) Idmap.t * Id.t Univ.LMap.t
val global_universe_names : unit -> universe_names
val set_global_universe_names : universe_names -> unit
diff --git a/tactics/coretactics.ml4 b/ltac/coretactics.ml4
index 74d98176a..9879cfc28 100644
--- a/tactics/coretactics.ml4
+++ b/ltac/coretactics.ml4
@@ -13,16 +13,23 @@ open Names
open Locus
open Misctypes
open Genredexpr
+open Constrarg
+open Extraargs
-open Proofview.Notations
open Sigma.Notations
DECLARE PLUGIN "coretactics"
+(** Basic tactics *)
+
TACTIC EXTEND reflexivity
[ "reflexivity" ] -> [ Tactics.intros_reflexivity ]
END
+TACTIC EXTEND exact
+ [ "exact" casted_constr(c) ] -> [ Tactics.exact_no_check c ]
+END
+
TACTIC EXTEND assumption
[ "assumption" ] -> [ Tactics.assumption ]
END
@@ -36,15 +43,15 @@ TACTIC EXTEND cut
END
TACTIC EXTEND exact_no_check
- [ "exact_no_check" constr(c) ] -> [ Proofview.V82.tactic (Tactics.exact_no_check c) ]
+ [ "exact_no_check" constr(c) ] -> [ Tactics.exact_no_check c ]
END
TACTIC EXTEND vm_cast_no_check
- [ "vm_cast_no_check" constr(c) ] -> [ Proofview.V82.tactic (Tactics.vm_cast_no_check c) ]
+ [ "vm_cast_no_check" constr(c) ] -> [ Tactics.vm_cast_no_check c ]
END
TACTIC EXTEND native_cast_no_check
- [ "native_cast_no_check" constr(c) ] -> [ Proofview.V82.tactic (Tactics.native_cast_no_check c) ]
+ [ "native_cast_no_check" constr(c) ] -> [ Tactics.native_cast_no_check c ]
END
TACTIC EXTEND casetype
@@ -141,7 +148,7 @@ END
TACTIC EXTEND symmetry
[ "symmetry" ] -> [ Tactics.intros_symmetry {onhyps=Some[];concl_occs=AllOccurrences} ]
-| [ "symmetry" clause(cl) ] -> [ Tactics.intros_symmetry cl ]
+| [ "symmetry" clause_dft_concl(cl) ] -> [ Tactics.intros_symmetry cl ]
END
(** Split *)
@@ -194,13 +201,32 @@ TACTIC EXTEND intros_until
[ "intros" "until" quantified_hypothesis(h) ] -> [ Tactics.intros_until h ]
END
+TACTIC EXTEND intro
+| [ "intro" ] -> [ Tactics.intro_move None MoveLast ]
+| [ "intro" ident(id) ] -> [ Tactics.intro_move (Some id) MoveLast ]
+| [ "intro" ident(id) "at" "top" ] -> [ Tactics.intro_move (Some id) MoveFirst ]
+| [ "intro" ident(id) "at" "bottom" ] -> [ Tactics.intro_move (Some id) MoveLast ]
+| [ "intro" ident(id) "after" hyp(h) ] -> [ Tactics.intro_move (Some id) (MoveAfter h) ]
+| [ "intro" ident(id) "before" hyp(h) ] -> [ Tactics.intro_move (Some id) (MoveBefore h) ]
+| [ "intro" "at" "top" ] -> [ Tactics.intro_move None MoveFirst ]
+| [ "intro" "at" "bottom" ] -> [ Tactics.intro_move None MoveLast ]
+| [ "intro" "after" hyp(h) ] -> [ Tactics.intro_move None (MoveAfter h) ]
+| [ "intro" "before" hyp(h) ] -> [ Tactics.intro_move None (MoveBefore h) ]
+END
+
(** Move *)
TACTIC EXTEND move
- [ "move" hyp(id) "at" "top" ] -> [ Proofview.V82.tactic (Tactics.move_hyp id MoveFirst) ]
-| [ "move" hyp(id) "at" "bottom" ] -> [ Proofview.V82.tactic (Tactics.move_hyp id MoveLast) ]
-| [ "move" hyp(id) "after" hyp(h) ] -> [ Proofview.V82.tactic (Tactics.move_hyp id (MoveAfter h)) ]
-| [ "move" hyp(id) "before" hyp(h) ] -> [ Proofview.V82.tactic (Tactics.move_hyp id (MoveBefore h)) ]
+ [ "move" hyp(id) "at" "top" ] -> [ Tactics.move_hyp id MoveFirst ]
+| [ "move" hyp(id) "at" "bottom" ] -> [ Tactics.move_hyp id MoveLast ]
+| [ "move" hyp(id) "after" hyp(h) ] -> [ Tactics.move_hyp id (MoveAfter h) ]
+| [ "move" hyp(id) "before" hyp(h) ] -> [ Tactics.move_hyp id (MoveBefore h) ]
+END
+
+(** Rename *)
+
+TACTIC EXTEND rename
+| [ "rename" ne_rename_list_sep(ids, ",") ] -> [ Tactics.rename_hyp ids ]
END
(** Revert *)
@@ -219,6 +245,13 @@ TACTIC EXTEND simple_destruct
[ "simple" "destruct" quantified_hypothesis(h) ] -> [ Tactics.simple_destruct h ]
END
+(** Double induction *)
+
+TACTIC EXTEND double_induction
+ [ "double" "induction" quantified_hypothesis(h1) quantified_hypothesis(h2) ] ->
+ [ Elim.h_double_induction h1 h2 ]
+END
+
(* Admit *)
TACTIC EXTEND admit
@@ -228,15 +261,15 @@ END
(* Fix *)
TACTIC EXTEND fix
- [ "fix" natural(n) ] -> [ Proofview.V82.tactic (Tactics.fix None n) ]
-| [ "fix" ident(id) natural(n) ] -> [ Proofview.V82.tactic (Tactics.fix (Some id) n) ]
+ [ "fix" natural(n) ] -> [ Tactics.fix None n ]
+| [ "fix" ident(id) natural(n) ] -> [ Tactics.fix (Some id) n ]
END
(* Cofix *)
TACTIC EXTEND cofix
- [ "cofix" ] -> [ Proofview.V82.tactic (Tactics.cofix None) ]
-| [ "cofix" ident(id) ] -> [ Proofview.V82.tactic (Tactics.cofix (Some id)) ]
+ [ "cofix" ] -> [ Tactics.cofix None ]
+| [ "cofix" ident(id) ] -> [ Tactics.cofix (Some id) ]
END
(* Clear *)
@@ -244,7 +277,7 @@ END
TACTIC EXTEND clear
[ "clear" hyp_list(ids) ] -> [
if List.is_empty ids then Tactics.keep []
- else Proofview.V82.tactic (Tactics.clear ids)
+ else Tactics.clear ids
]
| [ "clear" "-" ne_hyp_list(ids) ] -> [ Tactics.keep ids ]
END
@@ -258,7 +291,7 @@ END
(* Generalize dependent *)
TACTIC EXTEND generalize_dependent
- [ "generalize" "dependent" constr(c) ] -> [ Proofview.V82.tactic (Tactics.generalize_dep c) ]
+ [ "generalize" "dependent" constr(c) ] -> [ Tactics.generalize_dep c ]
END
(* Table of "pervasives" macros tactics (e.g. auto, simpl, etc.) *)
@@ -277,7 +310,6 @@ let initial_atomic () =
"hnf", TacReduce(Hnf,nocl);
"simpl", TacReduce(Simpl (Redops.all_flags,None),nocl);
"compute", TacReduce(Cbv Redops.all_flags,nocl);
- "intro", TacIntroMove(None,MoveLast);
"intros", TacIntroPattern [];
]
in
diff --git a/tactics/evar_tactics.ml b/ltac/evar_tactics.ml
index 2e0996bf5..2e0996bf5 100644
--- a/tactics/evar_tactics.ml
+++ b/ltac/evar_tactics.ml
diff --git a/tactics/evar_tactics.mli b/ltac/evar_tactics.mli
index e67540c05..e67540c05 100644
--- a/tactics/evar_tactics.mli
+++ b/ltac/evar_tactics.mli
diff --git a/tactics/extraargs.ml4 b/ltac/extraargs.ml4
index 8f336cdb3..e6d0a9c69 100644
--- a/tactics/extraargs.ml4
+++ b/ltac/extraargs.ml4
@@ -10,13 +10,47 @@
open Pp
open Genarg
+open Stdarg
+open Constrarg
+open Pcoq.Prim
+open Pcoq.Constr
open Names
+open Tacmach
open Tacexpr
open Taccoerce
open Tacinterp
open Misctypes
open Locus
+(** Adding scopes for generic arguments not defined through ARGUMENT EXTEND *)
+
+let create_generic_quotation name e wit =
+ let inject (loc, v) = Tacexpr.TacGeneric (Genarg.in_gen (Genarg.rawwit wit) v) in
+ Tacentries.create_ltac_quotation name inject (e, None)
+
+let () = create_generic_quotation "integer" Pcoq.Prim.integer Stdarg.wit_int
+let () = create_generic_quotation "string" Pcoq.Prim.string Stdarg.wit_string
+
+let () = create_generic_quotation "ident" Pcoq.Prim.ident Constrarg.wit_ident
+let () = create_generic_quotation "reference" Pcoq.Prim.reference Constrarg.wit_ref
+let () = create_generic_quotation "uconstr" Pcoq.Constr.lconstr Constrarg.wit_uconstr
+let () = create_generic_quotation "constr" Pcoq.Constr.lconstr Constrarg.wit_constr
+let () = create_generic_quotation "ipattern" Pcoq.Tactic.simple_intropattern Constrarg.wit_intro_pattern
+let () = create_generic_quotation "open_constr" Pcoq.Constr.lconstr Constrarg.wit_open_constr
+let () =
+ let inject (loc, v) = Tacexpr.Tacexp v in
+ Tacentries.create_ltac_quotation "ltac" inject (Pcoq.Tactic.tactic_expr, Some 5)
+
+(** Backward-compatible tactic notation entry names *)
+
+let () =
+ let register name entry = Tacentries.register_tactic_notation_entry name entry in
+ register "hyp" wit_var;
+ register "simple_intropattern" wit_intro_pattern;
+ register "integer" wit_integer;
+ register "reference" wit_ref;
+ ()
+
(* Rewriting orientation *)
let _ = Metasyntax.add_token_obj "<-"
@@ -32,6 +66,14 @@ ARGUMENT EXTEND orient TYPED AS bool PRINTED BY pr_orient
| [ ] -> [ true ]
END
+let pr_int _ _ _ i = Pp.int i
+
+let _natural = Pcoq.Prim.natural
+
+ARGUMENT EXTEND natural TYPED AS int PRINTED BY pr_int
+| [ _natural(i) ] -> [ i ]
+END
+
let pr_orient = pr_orient () () ()
@@ -73,16 +115,14 @@ let glob_occs ist l = l
let subst_occs evm l = l
ARGUMENT EXTEND occurrences
+ TYPED AS int list
PRINTED BY pr_int_list_full
INTERPRETED BY interp_occs
GLOBALIZED BY glob_occs
SUBSTITUTED BY subst_occs
- RAW_TYPED AS occurrences_or_var
RAW_PRINTED BY pr_occurrences
-
- GLOB_TYPED AS occurrences_or_var
GLOB_PRINTED BY pr_occurrences
| [ ne_integer_list(l) ] -> [ ArgArg l ]
@@ -99,6 +139,8 @@ let interp_glob ist gl (t,_) = Tacmach.project gl , (ist,t)
let glob_glob = Tacintern.intern_constr
+let pr_lconstr _ prc _ c = prc c
+
let subst_glob = Tacsubst.subst_glob_constr_and_expr
ARGUMENT EXTEND glob
@@ -108,29 +150,42 @@ ARGUMENT EXTEND glob
GLOBALIZED BY glob_glob
SUBSTITUTED BY subst_glob
- RAW_TYPED AS constr_expr
RAW_PRINTED BY pr_gen
-
- GLOB_TYPED AS glob_constr_and_expr
GLOB_PRINTED BY pr_gen
[ constr(c) ] -> [ c ]
END
+let l_constr = Pcoq.Constr.lconstr
+
+ARGUMENT EXTEND lconstr
+ TYPED AS constr
+ PRINTED BY pr_lconstr
+ [ l_constr(c) ] -> [ c ]
+END
+
ARGUMENT EXTEND lglob
+ TYPED AS glob
PRINTED BY pr_globc
INTERPRETED BY interp_glob
GLOBALIZED BY glob_glob
SUBSTITUTED BY subst_glob
- RAW_TYPED AS constr_expr
RAW_PRINTED BY pr_gen
-
- GLOB_TYPED AS glob_constr_and_expr
GLOB_PRINTED BY pr_gen
[ lconstr(c) ] -> [ c ]
END
+let interp_casted_constr ist gl c =
+ interp_constr_gen (Pretyping.OfType (pf_concl gl)) ist (pf_env gl) (project gl) c
+
+ARGUMENT EXTEND casted_constr
+ TYPED AS constr
+ PRINTED BY pr_gen
+ INTERPRETED BY interp_casted_constr
+ [ constr(c) ] -> [ c ]
+END
+
type 'id gen_place= ('id * hyp_location_flag,unit) location
type loc_place = Id.t Loc.located gen_place
@@ -166,9 +221,7 @@ ARGUMENT EXTEND hloc
INTERPRETED BY interp_place
GLOBALIZED BY intern_place
SUBSTITUTED BY subst_place
- RAW_TYPED AS loc_place
RAW_PRINTED BY pr_loc_place
- GLOB_TYPED AS loc_place
GLOB_PRINTED BY pr_loc_place
[ ] ->
[ ConclLocation () ]
@@ -183,11 +236,13 @@ ARGUMENT EXTEND hloc
END
+let pr_rename _ _ _ (n, m) = Nameops.pr_id n ++ str " into " ++ Nameops.pr_id m
-
-
-
-
+ARGUMENT EXTEND rename
+ TYPED AS ident * ident
+ PRINTED BY pr_rename
+| [ ident(n) "into" ident(m) ] -> [ (n, m) ]
+END
(* Julien: Mise en commun des differentes version de replace with in by *)
diff --git a/tactics/extraargs.mli b/ltac/extraargs.mli
index 7df845e4b..0cf77935c 100644
--- a/tactics/extraargs.mli
+++ b/ltac/extraargs.mli
@@ -16,11 +16,15 @@ val wit_orient : bool Genarg.uniform_genarg_type
val orient : bool Pcoq.Gram.entry
val pr_orient : bool -> Pp.std_ppcmds
+val wit_rename : (Id.t * Id.t) Genarg.uniform_genarg_type
+
val occurrences : (int list or_var) Pcoq.Gram.entry
val wit_occurrences : (int list or_var, int list or_var, int list) Genarg.genarg_type
val pr_occurrences : int list or_var -> Pp.std_ppcmds
val occurrences_of : int list -> Locus.occurrences
+val wit_natural : int Genarg.uniform_genarg_type
+
val wit_glob :
(constr_expr,
Tacexpr.glob_constr_and_expr,
@@ -31,6 +35,16 @@ val wit_lglob :
Tacexpr.glob_constr_and_expr,
Tacinterp.interp_sign * glob_constr) Genarg.genarg_type
+val wit_lconstr :
+ (constr_expr,
+ Tacexpr.glob_constr_and_expr,
+ Constr.t) Genarg.genarg_type
+
+val wit_casted_constr :
+ (constr_expr,
+ Tacexpr.glob_constr_and_expr,
+ Constr.t) Genarg.genarg_type
+
val glob : constr_expr Pcoq.Gram.entry
val lglob : constr_expr Pcoq.Gram.entry
@@ -47,13 +61,12 @@ val by_arg_tac : Tacexpr.raw_tactic_expr option Pcoq.Gram.entry
val wit_by_arg_tac :
(raw_tactic_expr option,
glob_tactic_expr option,
- Genarg.Val.t option) Genarg.genarg_type
+ Geninterp.Val.t option) Genarg.genarg_type
val pr_by_arg_tac :
(int * Ppextend.parenRelation -> raw_tactic_expr -> Pp.std_ppcmds) ->
raw_tactic_expr option -> Pp.std_ppcmds
-
(** Spiwack: Primitive for retroknowledge registration *)
val retroknowledge_field : Retroknowledge.field Pcoq.Gram.entry
diff --git a/tactics/extratactics.ml4 b/ltac/extratactics.ml4
index 85b9d6a08..57fad8511 100644
--- a/tactics/extratactics.ml4
+++ b/ltac/extratactics.ml4
@@ -10,12 +10,15 @@
open Pp
open Genarg
+open Stdarg
+open Constrarg
open Extraargs
+open Pcoq.Prim
+open Pcoq.Tactic
open Mod_subst
open Names
open Tacexpr
open Glob_ops
-open Tactics
open Errors
open Util
open Evd
@@ -39,7 +42,7 @@ let with_delayed_uconstr ist c tac =
fail_evar = false;
expand_evars = true
} in
- let c = Tacinterp.type_uconstr ~flags ist c in
+ let c = Pretyping.type_uconstr ~flags ist c in
Tacticals.New.tclDELAYEDWITHHOLES false c tac
let replace_in_clause_maybe_by ist c1 c2 cl tac =
@@ -49,6 +52,8 @@ let replace_in_clause_maybe_by ist c1 c2 cl tac =
let replace_term ist dir_opt c cl =
with_delayed_uconstr ist c (fun c -> replace_term dir_opt c cl)
+let clause = Pcoq.Tactic.clause_dft_concl
+
TACTIC EXTEND replace
["replace" uconstr(c1) "with" constr(c2) clause(cl) by_arg_tac(tac) ]
-> [ replace_in_clause_maybe_by ist c1 c2 cl tac ]
@@ -121,7 +126,6 @@ TACTIC EXTEND ediscriminate
[ discr_tac true (Some (induction_arg_of_quantified_hyp h)) ]
END
-open Proofview.Notations
let discrHyp id =
Proofview.tclEVARMAP >>= fun sigma ->
discr_main { delayed = fun env sigma -> Sigma.here (Term.mkVar id, NoBindings) sigma }
@@ -147,23 +151,23 @@ TACTIC EXTEND einjection
| [ "einjection" quantified_hypothesis(h) ] -> [ injClause None true (Some (induction_arg_of_quantified_hyp h)) ]
END
TACTIC EXTEND injection_as_main
-| [ "injection" constr_with_bindings(c) "as" simple_intropattern_list(ipat)] ->
+| [ "injection" constr_with_bindings(c) "as" intropattern_list(ipat)] ->
[ elimOnConstrWithHoles (injClause (Some ipat)) false c ]
END
TACTIC EXTEND injection_as
-| [ "injection" "as" simple_intropattern_list(ipat)] ->
+| [ "injection" "as" intropattern_list(ipat)] ->
[ injClause (Some ipat) false None ]
-| [ "injection" quantified_hypothesis(h) "as" simple_intropattern_list(ipat) ] ->
+| [ "injection" quantified_hypothesis(h) "as" intropattern_list(ipat) ] ->
[ injClause (Some ipat) false (Some (induction_arg_of_quantified_hyp h)) ]
END
TACTIC EXTEND einjection_as_main
-| [ "einjection" constr_with_bindings(c) "as" simple_intropattern_list(ipat)] ->
+| [ "einjection" constr_with_bindings(c) "as" intropattern_list(ipat)] ->
[ elimOnConstrWithHoles (injClause (Some ipat)) true c ]
END
TACTIC EXTEND einjection_as
-| [ "einjection" "as" simple_intropattern_list(ipat)] ->
+| [ "einjection" "as" intropattern_list(ipat)] ->
[ injClause (Some ipat) true None ]
-| [ "einjection" quantified_hypothesis(h) "as" simple_intropattern_list(ipat) ] ->
+| [ "einjection" quantified_hypothesis(h) "as" intropattern_list(ipat) ] ->
[ injClause (Some ipat) true (Some (induction_arg_of_quantified_hyp h)) ]
END
@@ -251,7 +255,7 @@ END
(**********************************************************************)
(* Rewrite star *)
-let rewrite_star ist clause orient occs c (tac : Val.t option) =
+let rewrite_star ist clause orient occs c (tac : Geninterp.Val.t option) =
let tac' = Option.map (fun t -> Tacinterp.tactic_of_value ist t, FirstSolved) tac in
with_delayed_uconstr ist c
(fun c -> general_rewrite_ebindings_clause clause orient occs ?tac:tac' true true (c,NoBindings) true)
@@ -283,7 +287,7 @@ let add_rewrite_hint bases ort t lcsr =
if poly then ctx
else (Global.push_context_set false ctx; Univ.ContextSet.empty)
in
- Constrexpr_ops.constr_loc ce, (c, ctx), ort, t in
+ Constrexpr_ops.constr_loc ce, (c, ctx), ort, Option.map (in_gen (rawwit wit_ltac)) t in
let eqs = List.map f lcsr in
let add_hints base = add_rew_rules base eqs in
List.iter add_hints bases
@@ -361,9 +365,9 @@ let refine_tac ist simple c =
let env = Proofview.Goal.env gl in
let flags = Pretyping.all_no_fail_flags in
let expected_type = Pretyping.OfType concl in
- let c = Tacinterp.type_uconstr ~flags ~expected_type ist c in
+ let c = Pretyping.type_uconstr ~flags ~expected_type ist c in
let update = { run = fun sigma -> c.delayed env sigma } in
- let refine = Proofview.Refine.refine ~unsafe:false update in
+ let refine = Refine.refine ~unsafe:false update in
if simple then refine
else refine <*>
Tactics.New.reduce_after_refine <*>
@@ -386,6 +390,12 @@ open Leminv
let seff id = Vernacexpr.VtSideff [id], Vernacexpr.VtLater
+VERNAC ARGUMENT EXTEND sort
+| [ "Set" ] -> [ GSet ]
+| [ "Prop" ] -> [ GProp ]
+| [ "Type" ] -> [ GType [] ]
+END
+
VERNAC COMMAND EXTEND DeriveInversionClear
| [ "Derive" "Inversion_clear" ident(na) "with" constr(c) "Sort" sort(s) ]
=> [ seff na ]
@@ -445,8 +455,6 @@ TACTIC EXTEND evar
| [ "evar" constr(typ) ] -> [ let_evar Anonymous typ ]
END
-open Tacticals
-
TACTIC EXTEND instantiate
[ "instantiate" "(" ident(id) ":=" lglob(c) ")" ] ->
[ Tacticals.New.tclTHEN (instantiate_tac_by_name id c) Proofview.V82.nf_evar_goals ]
@@ -574,7 +582,7 @@ END
during dependent induction. For internal use. *)
TACTIC EXTEND specialize_eqs
-[ "specialize_eqs" hyp(id) ] -> [ Proofview.V82.tactic (specialize_eqs id) ]
+[ "specialize_eqs" hyp(id) ] -> [ specialize_eqs id ]
END
(**********************************************************************)
@@ -720,7 +728,7 @@ let mkCaseEq a : unit Proofview.tactic =
Proofview.Goal.nf_enter { enter = begin fun gl ->
let type_of_a = Tacmach.New.of_old (fun g -> Tacmach.pf_unsafe_type_of g a) gl in
Tacticals.New.tclTHENLIST
- [Proofview.V82.tactic (Tactics.generalize [mkApp(delayed_force refl_equal, [| type_of_a; a|])]);
+ [Tactics.generalize [mkApp(delayed_force refl_equal, [| type_of_a; a|])];
Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let env = Proofview.Goal.env gl in
@@ -864,7 +872,7 @@ END;;
mode. *)
VERNAC COMMAND EXTEND GrabEvars
[ "Grab" "Existential" "Variables" ]
- => [ Vernacexpr.VtProofStep false, Vernacexpr.VtLater ]
+ => [ Vernac_classifier.classify_as_proofstep ]
-> [ Proof_global.simple_with_current_proof (fun _ p -> Proof.V82.grab_evars p) ]
END
@@ -895,7 +903,7 @@ END
(* Command to add every unshelved variables to the focus *)
VERNAC COMMAND EXTEND Unshelve
[ "Unshelve" ]
- => [ Vernacexpr.VtProofStep false, Vernacexpr.VtLater ]
+ => [ Vernac_classifier.classify_as_proofstep ]
-> [ Proof_global.simple_with_current_proof (fun _ p -> Proof.unshelve p) ]
END
@@ -931,10 +939,6 @@ type cmp =
type 'i test =
| Test of cmp * 'i * 'i
-let wit_cmp : (cmp,cmp,cmp) Genarg.genarg_type = Genarg.make0 None "cmp"
-let wit_test : (int or_var test,int or_var test,int test) Genarg.genarg_type =
- Genarg.make0 None "tactest"
-
let pr_cmp = function
| Eq -> Pp.str"="
| Lt -> Pp.str"<"
@@ -957,7 +961,7 @@ let pr_itest' _prc _prlc _prt = pr_itest
-ARGUMENT EXTEND comparison TYPED AS cmp PRINTED BY pr_cmp'
+ARGUMENT EXTEND comparison PRINTED BY pr_cmp'
| [ "=" ] -> [ Eq ]
| [ "<" ] -> [ Lt ]
| [ "<=" ] -> [ Le ]
@@ -973,9 +977,7 @@ let interp_test ist gls = function
ARGUMENT EXTEND test
PRINTED BY pr_itest'
INTERPRETED BY interp_test
- RAW_TYPED AS test
RAW_PRINTED BY pr_test'
- GLOB_TYPED AS test
GLOB_PRINTED BY pr_test'
| [ int_or_var(x) comparison(c) int_or_var(y) ] -> [ Test(c,x,y) ]
END
@@ -1029,7 +1031,7 @@ VERNAC COMMAND EXTEND Declare_keys CLASSIFIED AS SIDEFF
END
VERNAC COMMAND EXTEND Print_keys CLASSIFIED AS QUERY
-| [ "Print" "Equivalent" "Keys" ] -> [ msg_info (Keys.pr_keys Printer.pr_global) ]
+| [ "Print" "Equivalent" "Keys" ] -> [ Feedback.msg_info (Keys.pr_keys Printer.pr_global) ]
END
diff --git a/tactics/extratactics.mli b/ltac/extratactics.mli
index 18334dafe..18334dafe 100644
--- a/tactics/extratactics.mli
+++ b/ltac/extratactics.mli
diff --git a/ltac/g_auto.ml4 b/ltac/g_auto.ml4
new file mode 100644
index 000000000..d4fd8a1df
--- /dev/null
+++ b/ltac/g_auto.ml4
@@ -0,0 +1,209 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(*i camlp4deps: "grammar/grammar.cma" i*)
+
+open Pp
+open Genarg
+open Stdarg
+open Constrarg
+open Pcoq.Prim
+open Pcoq.Constr
+open Pcoq.Tactic
+open Tacexpr
+
+DECLARE PLUGIN "g_auto"
+
+(* Hint bases *)
+
+
+TACTIC EXTEND eassumption
+| [ "eassumption" ] -> [ Eauto.e_assumption ]
+END
+
+TACTIC EXTEND eexact
+| [ "eexact" constr(c) ] -> [ Eauto.e_give_exact c ]
+END
+
+let pr_hintbases _prc _prlc _prt = Pptactic.pr_hintbases
+
+ARGUMENT EXTEND hintbases
+ TYPED AS preident_list_opt
+ PRINTED BY pr_hintbases
+| [ "with" "*" ] -> [ None ]
+| [ "with" ne_preident_list(l) ] -> [ Some l ]
+| [ ] -> [ Some [] ]
+END
+
+let eval_uconstrs ist cs =
+ let flags = {
+ Pretyping.use_typeclasses = false;
+ use_unif_heuristics = true;
+ use_hook = Some Pfedit.solve_by_implicit_tactic;
+ fail_evar = false;
+ expand_evars = true
+ } in
+ List.map (fun c -> Pretyping.type_uconstr ~flags ist c) cs
+
+let pr_auto_using _ _ _ = Pptactic.pr_auto_using (fun _ -> mt ())
+
+ARGUMENT EXTEND auto_using
+ TYPED AS uconstr_list
+ PRINTED BY pr_auto_using
+| [ "using" ne_uconstr_list_sep(l, ",") ] -> [ l ]
+| [ ] -> [ [] ]
+END
+
+(** Auto *)
+
+TACTIC EXTEND trivial
+| [ "trivial" auto_using(lems) hintbases(db) ] ->
+ [ Auto.h_trivial (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND info_trivial
+| [ "info_trivial" auto_using(lems) hintbases(db) ] ->
+ [ Auto.h_trivial ~debug:Info (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND debug_trivial
+| [ "debug" "trivial" auto_using(lems) hintbases(db) ] ->
+ [ Auto.h_trivial ~debug:Debug (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND auto
+| [ "auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
+ [ Auto.h_auto n (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND info_auto
+| [ "info_auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
+ [ Auto.h_auto ~debug:Info n (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND debug_auto
+| [ "debug" "auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
+ [ Auto.h_auto ~debug:Debug n (eval_uconstrs ist lems) db ]
+END
+
+(** Eauto *)
+
+TACTIC EXTEND prolog
+| [ "prolog" "[" uconstr_list(l) "]" int_or_var(n) ] ->
+ [ Eauto.prolog_tac (eval_uconstrs ist l) n ]
+END
+
+let make_depth n = snd (Eauto.make_dimension n None)
+
+TACTIC EXTEND eauto
+| [ "eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
+ hintbases(db) ] ->
+ [ Eauto.gen_eauto (Eauto.make_dimension n p) (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND new_eauto
+| [ "new" "auto" int_or_var_opt(n) auto_using(lems)
+ hintbases(db) ] ->
+ [ match db with
+ | None -> Auto.new_full_auto (make_depth n) (eval_uconstrs ist lems)
+ | Some l -> Auto.new_auto (make_depth n) (eval_uconstrs ist lems) l ]
+END
+
+TACTIC EXTEND debug_eauto
+| [ "debug" "eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
+ hintbases(db) ] ->
+ [ Eauto.gen_eauto ~debug:Debug (Eauto.make_dimension n p) (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND info_eauto
+| [ "info_eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
+ hintbases(db) ] ->
+ [ Eauto.gen_eauto ~debug:Info (Eauto.make_dimension n p) (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND dfs_eauto
+| [ "dfs" "eauto" int_or_var_opt(p) auto_using(lems)
+ hintbases(db) ] ->
+ [ Eauto.gen_eauto (Eauto.make_dimension p None) (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND autounfold
+| [ "autounfold" hintbases(db) clause_dft_concl(cl) ] -> [ Eauto.autounfold_tac db cl ]
+END
+
+TACTIC EXTEND autounfold_one
+| [ "autounfold_one" hintbases(db) "in" hyp(id) ] ->
+ [ Eauto.autounfold_one (match db with None -> ["core"] | Some x -> "core"::x) (Some (id, Locus.InHyp)) ]
+| [ "autounfold_one" hintbases(db) ] ->
+ [ Eauto.autounfold_one (match db with None -> ["core"] | Some x -> "core"::x) None ]
+ END
+
+TACTIC EXTEND autounfoldify
+| [ "autounfoldify" constr(x) ] -> [
+ let db = match Term.kind_of_term x with
+ | Term.Const (c,_) -> Names.Label.to_string (Names.con_label c)
+ | _ -> assert false
+ in Eauto.autounfold ["core";db] Locusops.onConcl
+ ]
+END
+
+TACTIC EXTEND unify
+| ["unify" constr(x) constr(y) ] -> [ Tactics.unify x y ]
+| ["unify" constr(x) constr(y) "with" preident(base) ] -> [
+ let table = try Some (Hints.searchtable_map base) with Not_found -> None in
+ match table with
+ | None ->
+ let msg = str "Hint table " ++ str base ++ str " not found" in
+ Tacticals.New.tclZEROMSG msg
+ | Some t ->
+ let state = Hints.Hint_db.transparent_state t in
+ Tactics.unify ~state x y
+ ]
+END
+
+
+TACTIC EXTEND convert_concl_no_check
+| ["convert_concl_no_check" constr(x) ] -> [ Tactics.convert_concl_no_check x Term.DEFAULTcast ]
+END
+
+let pr_hints_path_atom _ _ _ = Hints.pp_hints_path_atom
+
+ARGUMENT EXTEND hints_path_atom
+ PRINTED BY pr_hints_path_atom
+| [ global_list(g) ] -> [ Hints.PathHints (List.map Nametab.global g) ]
+| [ "*" ] -> [ Hints.PathAny ]
+END
+
+let pr_hints_path prc prx pry c = Hints.pp_hints_path c
+
+ARGUMENT EXTEND hints_path
+ PRINTED BY pr_hints_path
+| [ "(" hints_path(p) ")" ] -> [ p ]
+| [ "!" hints_path(p) ] -> [ Hints.PathStar p ]
+| [ "emp" ] -> [ Hints.PathEmpty ]
+| [ "eps" ] -> [ Hints.PathEpsilon ]
+| [ hints_path_atom(a) ] -> [ Hints.PathAtom a ]
+| [ hints_path(p) "|" hints_path(q) ] -> [ Hints.PathOr (p, q) ]
+| [ hints_path(p) ";" hints_path(q) ] -> [ Hints.PathSeq (p, q) ]
+END
+
+let pr_hintbases _prc _prlc _prt = Pptactic.pr_hintbases
+
+ARGUMENT EXTEND opthints
+ TYPED AS preident_list_opt
+ PRINTED BY pr_hintbases
+| [ ":" ne_preident_list(l) ] -> [ Some l ]
+| [ ] -> [ None ]
+END
+
+VERNAC COMMAND EXTEND HintCut CLASSIFIED AS SIDEFF
+| [ "Hint" "Cut" "[" hints_path(p) "]" opthints(dbnames) ] -> [
+ let entry = Hints.HintsCutEntry p in
+ Hints.add_hints (Locality.make_section_locality (Locality.LocalityFixme.consume ()))
+ (match dbnames with None -> ["core"] | Some l -> l) entry ]
+END
diff --git a/tactics/g_class.ml4 b/ltac/g_class.ml4
index 766593543..77075ec4c 100644
--- a/tactics/g_class.ml4
+++ b/ltac/g_class.ml4
@@ -10,6 +10,9 @@
open Misctypes
open Class_tactics
+open Pcoq.Tactic
+open Stdarg
+open Constrarg
DECLARE PLUGIN "g_class"
diff --git a/tactics/g_eqdecide.ml4 b/ltac/g_eqdecide.ml4
index 905653281..905653281 100644
--- a/tactics/g_eqdecide.ml4
+++ b/ltac/g_eqdecide.ml4
diff --git a/parsing/g_ltac.ml4 b/ltac/g_ltac.ml4
index 0a11d3928..7c161e5cd 100644
--- a/parsing/g_ltac.ml4
+++ b/ltac/g_ltac.ml4
@@ -6,6 +6,9 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(*i camlp4deps: "grammar/grammar.cma" i*)
+
+open Util
open Pp
open Compat
open Constrexpr
@@ -28,6 +31,7 @@ let arg_of_expr = function
let genarg_of_unit () = in_gen (rawwit Stdarg.wit_unit) ()
let genarg_of_int n = in_gen (rawwit Stdarg.wit_int) n
let genarg_of_ipattern pat = in_gen (rawwit Constrarg.wit_intro_pattern) pat
+let genarg_of_uconstr c = in_gen (rawwit Constrarg.wit_uconstr) c
let reference_to_id = function
| Libnames.Ident (loc, id) -> (loc, id)
@@ -35,11 +39,41 @@ let reference_to_id = function
Errors.user_err_loc (loc, "",
str "This expression should be a simple identifier.")
+let tactic_mode = Gram.entry_create "vernac:tactic_command"
+
+let new_entry name =
+ let e = Gram.entry_create name in
+ e
+
+let selector = new_entry "vernac:selector"
+let tacdef_body = new_entry "tactic:tacdef_body"
+
+(* Registers the Classic Proof Mode (which uses [tactic_mode] as a parser for
+ proof editing and changes nothing else). Then sets it as the default proof mode. *)
+let _ =
+ let mode = {
+ Proof_global.name = "Classic";
+ set = (fun () -> set_command_entry tactic_mode);
+ reset = (fun () -> set_command_entry Pcoq.Vernac_.noedit_mode);
+ } in
+ Proof_global.register_proof_mode mode
+
+(* Hack to parse "[ id" without dropping [ *)
+let test_bracket_ident =
+ Gram.Entry.of_parser "test_bracket_ident"
+ (fun strm ->
+ match get_tok (stream_nth 0 strm) with
+ | KEYWORD "[" ->
+ (match get_tok (stream_nth 1 strm) with
+ | IDENT _ -> ()
+ | _ -> raise Stream.Failure)
+ | _ -> raise Stream.Failure)
+
(* Tactics grammar rules *)
GEXTEND Gram
GLOBAL: tactic tacdef_body tactic_expr binder_tactic tactic_arg
- constr_may_eval constr_eval;
+ tactic_mode constr_may_eval constr_eval selector;
tactic_then_last:
[ [ "|"; lta = LIST0 OPT tactic_expr SEP "|" ->
@@ -111,10 +145,8 @@ GEXTEND Gram
| g=failkw; n = [ n = int_or_var -> n | -> fail_default_value ];
l = LIST0 message_token -> TacFail (g,n,l)
| st = simple_tactic -> st
- | IDENT "constr"; ":"; c = Constr.constr ->
- TacArg(!@loc,ConstrMayEval(ConstrTerm c))
- | a = tactic_top_or_arg -> TacArg(!@loc,a)
- | r = reference; la = LIST0 tactic_arg ->
+ | a = tactic_arg -> TacArg(!@loc,a)
+ | r = reference; la = LIST0 tactic_arg_compat ->
TacArg(!@loc,TacCall (!@loc,r,la)) ]
| "0"
[ "("; a = tactic_expr; ")" -> a
@@ -138,22 +170,17 @@ GEXTEND Gram
body = tactic_expr LEVEL "5" -> TacLetIn (isrec,llc,body)
| IDENT "info"; tc = tactic_expr LEVEL "5" -> TacInfo tc ] ]
;
- (* Tactic arguments *)
- tactic_arg:
- [ [ "ltac:"; a = tactic_expr LEVEL "0" -> arg_of_expr a
- | "ltac:"; n = natural -> TacGeneric (genarg_of_int n)
- | a = tactic_top_or_arg -> a
+ (* Tactic arguments to the right of an application *)
+ tactic_arg_compat:
+ [ [ a = tactic_arg -> a
| r = reference -> Reference r
| c = Constr.constr -> ConstrMayEval (ConstrTerm c)
(* Unambigous entries: tolerated w/o "ltac:" modifier *)
| "()" -> TacGeneric (genarg_of_unit ()) ] ]
;
(* Can be used as argument and at toplevel in tactic expressions. *)
- tactic_top_or_arg:
- [ [ IDENT "uconstr"; ":" ; c = uconstr -> UConstr c
- | IDENT "ipattern"; ":"; ipat = simple_intropattern ->
- TacGeneric (genarg_of_ipattern ipat)
- | c = constr_eval -> ConstrMayEval c
+ tactic_arg:
+ [ [ c = constr_eval -> ConstrMayEval c
| IDENT "fresh"; l = LIST0 fresh_id -> TacFreshId l
| IDENT "type_term"; c=uconstr -> TacPretype c
| IDENT "numgoals" -> TacNumgoals ] ]
@@ -204,7 +231,7 @@ GEXTEND Gram
Subterm (mode, oid, pc)
| IDENT "appcontext"; oid = OPT Constr.ident;
"["; pc = Constr.lconstr_pattern; "]" ->
- msg_warning (strbrk "appcontext is deprecated");
+ Feedback.msg_warning (strbrk "appcontext is deprecated");
Subterm (true,oid, pc)
| pc = Constr.lconstr_pattern -> Term pc ] ]
;
@@ -268,4 +295,158 @@ GEXTEND Gram
tactic:
[ [ tac = tactic_expr -> tac ] ]
;
+ selector:
+ [ [ n=natural; ":" -> Vernacexpr.SelectNth n
+ | test_bracket_ident; "["; id = ident; "]"; ":" -> Vernacexpr.SelectId id
+ | IDENT "all" ; ":" -> Vernacexpr.SelectAll ] ]
+ ;
+ tactic_mode:
+ [ [ g = OPT selector; tac = G_vernac.subgoal_command -> tac g ] ]
+ ;
END
+
+open Constrarg
+open Vernacexpr
+open Vernac_classifier
+open Goptions
+open Libnames
+
+let print_info_trace = ref None
+
+let _ = declare_int_option {
+ optsync = true;
+ optdepr = false;
+ optname = "print info trace";
+ optkey = ["Info" ; "Level"];
+ optread = (fun () -> !print_info_trace);
+ optwrite = fun n -> print_info_trace := n;
+}
+
+let vernac_solve n info tcom b =
+ let status = Proof_global.with_current_proof (fun etac p ->
+ let with_end_tac = if b then Some etac else None in
+ let global = match n with SelectAll -> true | _ -> false in
+ let info = Option.append info !print_info_trace in
+ let (p,status) =
+ Pfedit.solve n info (Tacinterp.hide_interp global tcom None) ?with_end_tac p
+ in
+ (* in case a strict subtree was completed,
+ go back to the top of the prooftree *)
+ let p = Proof.maximal_unfocus Vernacentries.command_focus p in
+ p,status) in
+ if not status then Feedback.feedback Feedback.AddedAxiom
+
+let pr_ltac_selector = function
+| SelectNth i -> int i ++ str ":"
+| SelectId id -> str "[" ++ Nameops.pr_id id ++ str "]" ++ str ":"
+| SelectAll -> str "all" ++ str ":"
+
+VERNAC ARGUMENT EXTEND ltac_selector PRINTED BY pr_ltac_selector
+| [ selector(s) ] -> [ s ]
+END
+
+let pr_ltac_info n = str "Info" ++ spc () ++ int n
+
+VERNAC ARGUMENT EXTEND ltac_info PRINTED BY pr_ltac_info
+| [ "Info" natural(n) ] -> [ n ]
+END
+
+let pr_ltac_use_default b =
+ if b then (* Bug: a space is inserted before "..." *) str ".." else mt ()
+
+VERNAC ARGUMENT EXTEND ltac_use_default PRINTED BY pr_ltac_use_default
+| [ "." ] -> [ false ]
+| [ "..." ] -> [ true ]
+END
+
+VERNAC tactic_mode EXTEND VernacSolve
+| [ - ltac_selector_opt(g) ltac_info_opt(n) tactic(t) ltac_use_default(def) ] =>
+ [ classify_as_proofstep ] -> [
+ let g = Option.default (Proof_global.get_default_goal_selector ()) g in
+ vernac_solve g n t def
+ ]
+| [ - "par" ":" ltac_info_opt(n) tactic(t) ltac_use_default(def) ] =>
+ [ VtProofStep{ parallel = true; proof_block_detection = Some "par" },
+ VtLater ] -> [
+ vernac_solve SelectAll n t def
+ ]
+END
+
+let pr_ltac_tactic_level n = str "(at level " ++ int n ++ str ")"
+
+VERNAC ARGUMENT EXTEND ltac_tactic_level PRINTED BY pr_ltac_tactic_level
+| [ "(" "at" "level" natural(n) ")" ] -> [ n ]
+END
+
+VERNAC ARGUMENT EXTEND ltac_production_sep
+| [ "," string(sep) ] -> [ sep ]
+END
+
+let pr_ltac_production_item = function
+| Tacentries.TacTerm s -> quote (str s)
+| Tacentries.TacNonTerm (_, (arg, sep), id) ->
+ let sep = match sep with
+ | None -> mt ()
+ | Some sep -> str "," ++ spc () ++ quote (str sep)
+ in
+ str arg ++ str "(" ++ Nameops.pr_id id ++ sep ++ str ")"
+
+VERNAC ARGUMENT EXTEND ltac_production_item PRINTED BY pr_ltac_production_item
+| [ string(s) ] -> [ Tacentries.TacTerm s ]
+| [ ident(nt) "(" ident(p) ltac_production_sep_opt(sep) ")" ] ->
+ [ Tacentries.TacNonTerm (loc, (Names.Id.to_string nt, sep), p) ]
+END
+
+VERNAC COMMAND EXTEND VernacTacticNotation
+| [ "Tactic" "Notation" ltac_tactic_level_opt(n) ne_ltac_production_item_list(r) ":=" tactic(e) ] =>
+ [ VtUnknown, VtNow ] ->
+ [
+ let l = Locality.LocalityFixme.consume () in
+ let n = Option.default 0 n in
+ Tacentries.add_tactic_notation (Locality.make_module_locality l) n r e
+ ]
+END
+
+VERNAC COMMAND EXTEND VernacPrintLtac CLASSIFIED AS QUERY
+| [ "Print" "Ltac" reference(r) ] ->
+ [ Feedback.msg_notice (Tacintern.print_ltac (snd (Libnames.qualid_of_reference r))) ]
+END
+
+let pr_ltac_ref = Libnames.pr_reference
+
+let pr_tacdef_body tacdef_body =
+ let id, redef, body =
+ match tacdef_body with
+ | TacticDefinition ((_,id), body) -> Nameops.pr_id id, false, body
+ | TacticRedefinition (id, body) -> pr_ltac_ref id, true, body
+ in
+ let idl, body =
+ match body with
+ | Tacexpr.TacFun (idl,b) -> idl,b
+ | _ -> [], body in
+ id ++
+ prlist (function None -> str " _"
+ | Some id -> spc () ++ Nameops.pr_id id) idl
+ ++ (if redef then str" ::=" else str" :=") ++ brk(1,1)
+ ++ Pptactic.pr_raw_tactic body
+
+VERNAC ARGUMENT EXTEND ltac_tacdef_body
+PRINTED BY pr_tacdef_body
+| [ tacdef_body(t) ] -> [ t ]
+END
+
+VERNAC COMMAND EXTEND VernacDeclareTacticDefinition
+| [ "Ltac" ne_ltac_tacdef_body_list_sep(l, "with") ] => [
+ VtSideff (List.map (function
+ | TacticDefinition ((_,r),_) -> r
+ | TacticRedefinition (Ident (_,r),_) -> r
+ | TacticRedefinition (Qualid (_,q),_) -> snd(repr_qualid q)) l), VtLater
+ ] -> [
+ let lc = Locality.LocalityFixme.consume () in
+ Tacentries.register_ltac (Locality.make_module_locality lc) l
+ ]
+END
+
+VERNAC COMMAND EXTEND VernacPrintLtacs CLASSIFIED AS QUERY
+| [ "Print" "Ltac" "Signatures" ] -> [ Tacentries.print_ltacs () ]
+END
diff --git a/toplevel/g_obligations.ml4 b/ltac/g_obligations.ml4
index d620febbc..987b9d538 100644
--- a/toplevel/g_obligations.ml4
+++ b/ltac/g_obligations.ml4
@@ -16,13 +16,25 @@
open Libnames
open Constrexpr
open Constrexpr_ops
+open Stdarg
+open Constrarg
+open Extraargs
+
+let (set_default_tactic, get_default_tactic, print_default_tactic) =
+ Tactic_option.declare_tactic_option "Program tactic"
+
+let () =
+ (** Delay to recover the tactic imperatively *)
+ let tac = Proofview.tclBIND (Proofview.tclUNIT ()) begin fun () ->
+ snd (get_default_tactic ())
+ end in
+ Obligations.default_tactic := tac
(* We define new entries for programs, with the use of this module
* Subtac. These entries are named Subtac.<foo>
*)
module Gram = Pcoq.Gram
-module Vernac = Pcoq.Vernac_
module Tactic = Pcoq.Tactic
open Pcoq
@@ -32,9 +44,9 @@ let sigref = mkRefC (Qualid (Loc.ghost, Libnames.qualid_of_string "Coq.Init.Spec
type 'a withtac_argtype = (Tacexpr.raw_tactic_expr option, 'a) Genarg.abstract_argument_type
let wit_withtac : Tacexpr.raw_tactic_expr option Genarg.uniform_genarg_type =
- Genarg.create_arg None "withtac"
+ Genarg.create_arg "withtac"
-let withtac = Pcoq.create_generic_entry "withtac" (Genarg.rawwit wit_withtac)
+let withtac = Pcoq.create_generic_entry Pcoq.utactic "withtac" (Genarg.rawwit wit_withtac)
GEXTEND Gram
GLOBAL: withtac;
@@ -57,11 +69,11 @@ open Obligations
let classify_obbl _ = Vernacexpr.(VtStartProof ("Classic",Doesn'tGuaranteeOpacity,[]), VtLater)
VERNAC COMMAND EXTEND Obligations CLASSIFIED BY classify_obbl
-| [ "Obligation" integer(num) "of" ident(name) ":" lconstr(t) withtac(tac) ] ->
+| [ "Obligation" integer(num) "of" ident(name) ":" lglob(t) withtac(tac) ] ->
[ obligation (num, Some name, Some t) tac ]
| [ "Obligation" integer(num) "of" ident(name) withtac(tac) ] ->
[ obligation (num, Some name, None) tac ]
-| [ "Obligation" integer(num) ":" lconstr(t) withtac(tac) ] ->
+| [ "Obligation" integer(num) ":" lglob(t) withtac(tac) ] ->
[ obligation (num, None, Some t) tac ]
| [ "Obligation" integer(num) withtac(tac) ] ->
[ obligation (num, None, None) tac ]
@@ -109,7 +121,7 @@ open Pp
VERNAC COMMAND EXTEND Show_Solver CLASSIFIED AS QUERY
| [ "Show" "Obligation" "Tactic" ] -> [
- msg_info (str"Program obligation tactic is " ++ print_default_tactic ()) ]
+ Feedback.msg_info (str"Program obligation tactic is " ++ print_default_tactic ()) ]
END
VERNAC COMMAND EXTEND Show_Obligations CLASSIFIED AS QUERY
@@ -118,8 +130,8 @@ VERNAC COMMAND EXTEND Show_Obligations CLASSIFIED AS QUERY
END
VERNAC COMMAND EXTEND Show_Preterm CLASSIFIED AS QUERY
-| [ "Preterm" "of" ident(name) ] -> [ msg_info (show_term (Some name)) ]
-| [ "Preterm" ] -> [ msg_info (show_term None) ]
+| [ "Preterm" "of" ident(name) ] -> [ Feedback.msg_info (show_term (Some name)) ]
+| [ "Preterm" ] -> [ Feedback.msg_info (show_term None) ]
END
open Pp
diff --git a/tactics/g_rewrite.ml4 b/ltac/g_rewrite.ml4
index 72cfb01a5..29ffbed19 100644
--- a/tactics/g_rewrite.ml4
+++ b/ltac/g_rewrite.ml4
@@ -20,6 +20,11 @@ open Extraargs
open Tacmach
open Tacticals
open Rewrite
+open Stdarg
+open Constrarg
+open Pcoq.Prim
+open Pcoq.Constr
+open Pcoq.Tactic
DECLARE PLUGIN "g_rewrite"
@@ -42,10 +47,7 @@ ARGUMENT EXTEND glob_constr_with_bindings
GLOBALIZED BY glob_glob_constr_with_bindings
SUBSTITUTED BY subst_glob_constr_with_bindings
- RAW_TYPED AS constr_expr_with_bindings
RAW_PRINTED BY pr_constr_expr_with_bindings
-
- GLOB_TYPED AS glob_constr_with_bindings
GLOB_PRINTED BY pr_glob_constr_with_bindings
[ constr_with_bindings(bl) ] -> [ bl ]
@@ -71,10 +73,7 @@ ARGUMENT EXTEND rewstrategy
GLOBALIZED BY glob_strategy
SUBSTITUTED BY subst_strategy
- RAW_TYPED AS raw_strategy
RAW_PRINTED BY pr_raw_strategy
-
- GLOB_TYPED AS glob_strategy
GLOB_PRINTED BY pr_glob_strategy
[ glob(c) ] -> [ StratConstr (c, true) ]
@@ -184,9 +183,9 @@ END
type binders_argtype = local_binder list
let wit_binders =
- (Genarg.create_arg None "binders" : binders_argtype Genarg.uniform_genarg_type)
+ (Genarg.create_arg "binders" : binders_argtype Genarg.uniform_genarg_type)
-let binders = Pcoq.create_generic_entry "binders" (Genarg.rawwit wit_binders)
+let binders = Pcoq.create_generic_entry Pcoq.utactic "binders" (Genarg.rawwit wit_binders)
open Pcoq
@@ -261,3 +260,7 @@ TACTIC EXTEND setoid_transitivity
[ "setoid_transitivity" constr(t) ] -> [ setoid_transitivity (Some t) ]
| [ "setoid_etransitivity" ] -> [ setoid_transitivity None ]
END
+
+VERNAC COMMAND EXTEND PrintRewriteHintDb CLASSIFIED AS QUERY
+ [ "Print" "Rewrite" "HintDb" preident(s) ] -> [ Feedback.msg_notice (Autorewrite.print_rewrite_hintdb s) ]
+END
diff --git a/ltac/ltac.mllib b/ltac/ltac.mllib
new file mode 100644
index 000000000..65ed114cf
--- /dev/null
+++ b/ltac/ltac.mllib
@@ -0,0 +1,21 @@
+Tacsubst
+Tacenv
+Tactic_debug
+Tacintern
+Tacentries
+Profile_ltac
+Tacinterp
+Evar_tactics
+Tactic_option
+Extraargs
+G_obligations
+Coretactics
+Extratactics
+Profile_ltac_tactics
+G_auto
+G_class
+Rewrite
+G_rewrite
+Tauto
+G_eqdecide
+G_ltac
diff --git a/ltac/profile_ltac.ml b/ltac/profile_ltac.ml
new file mode 100644
index 000000000..7a8ef32c3
--- /dev/null
+++ b/ltac/profile_ltac.ml
@@ -0,0 +1,323 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Unicode
+open Pp
+open Printer
+open Util
+
+(** [is_profiling] and the profiling info ([stack]) should be synchronized with
+ the document; the rest of the ref cells are either local to individual
+ tactic invocations, or global flags, and need not be synchronized, since no
+ document-level backtracking happens within tactics. We synchronize
+ is_profiling via an option. *)
+let is_profiling = Flags.profile_ltac
+
+let set_profiling b = is_profiling := b
+let get_profiling () = !is_profiling
+
+let new_call = ref false
+let entered_call () = new_call := true
+let is_new_call () = let b = !new_call in new_call := false; b
+
+(** LtacProf cannot yet handle backtracking into multi-success tactics.
+ To properly support this, we'd have to somehow recreate our location in the
+ call-stack, and stop/restart the intervening timers. This is tricky and
+ possibly expensive, so instead we currently just emit a warning that
+ profiling results will be off. *)
+let encountered_multi_success_backtracking = ref false
+
+let warn_encountered_multi_success_backtracking () =
+ if !encountered_multi_success_backtracking then
+ Feedback.msg_warning (str "Ltac Profiler cannot yet handle backtracking \
+ into multi-success tactics; profiling results may be wildly inaccurate.")
+
+let encounter_multi_success_backtracking () =
+ if not !encountered_multi_success_backtracking
+ then begin
+ encountered_multi_success_backtracking := true;
+ warn_encountered_multi_success_backtracking ()
+ end
+
+type entry = {
+ mutable total : float;
+ mutable local : float;
+ mutable ncalls : int;
+ mutable max_total : float
+}
+
+let empty_entry () = { total = 0.; local = 0.; ncalls = 0; max_total = 0. }
+
+let add_entry e add_total { total; local; ncalls; max_total } =
+ if add_total then e.total <- e.total +. total;
+ e.local <- e.local +. local;
+ e.ncalls <- e.ncalls + ncalls;
+ if add_total then e.max_total <- max e.max_total max_total
+
+type treenode = {
+ entry : entry;
+ children : (string, treenode) Hashtbl.t
+}
+
+let empty_treenode n = { entry = empty_entry (); children = Hashtbl.create n }
+
+(** Tobias Tebbi wrote some tricky code involving mutation. Rather than
+ rewriting it in a functional style, we simply freeze the state when we need
+ to by issuing a deep copy of the profiling data. *)
+(** TODO: rewrite me in purely functional style *)
+let deepcopy_entry { total; local; ncalls; max_total } =
+ { total; local; ncalls; max_total }
+
+let rec deepcopy_treenode { entry; children } =
+ let children' = Hashtbl.create (Hashtbl.length children) in
+ let iter key subtree = Hashtbl.add children' key (deepcopy_treenode subtree) in
+ let () = Hashtbl.iter iter children in
+ { entry = deepcopy_entry entry; children = children' }
+
+let stack =
+ let freeze _ = List.map deepcopy_treenode in
+ Summary.ref ~freeze [empty_treenode 20] ~name:"LtacProf-stack"
+
+let on_stack = Hashtbl.create 5
+
+let get_node c table =
+ try Hashtbl.find table c
+ with Not_found ->
+ let new_node = empty_treenode 5 in
+ Hashtbl.add table c new_node;
+ new_node
+
+let rec add_node node node' =
+ add_entry node.entry true node'.entry;
+ Hashtbl.iter
+ (fun s node' -> add_node (get_node s node.children) node')
+ node'.children
+
+let time () =
+ let times = Unix.times () in
+ times.Unix.tms_utime +. times.Unix.tms_stime
+
+(*
+let msgnl_with fmt strm = msg_with fmt (strm ++ fnl ())
+let msgnl strm = msgnl_with !Pp_control.std_ft strm
+
+let rec print_treenode indent (tn : treenode) =
+ msgnl (str (indent^"{ entry = {"));
+ Feedback.msg_notice (str (indent^"total = "));
+ msgnl (str (indent^(string_of_float (tn.entry.total))));
+ Feedback.msg_notice (str (indent^"local = "));
+ msgnl (str (indent^(string_of_float tn.entry.local)));
+ Feedback.msg_notice (str (indent^"ncalls = "));
+ msgnl (str (indent^(string_of_int tn.entry.ncalls)));
+ Feedback.msg_notice (str (indent^"max_total = "));
+ msgnl (str (indent^(string_of_float tn.entry.max_total)));
+ msgnl (str (indent^"}"));
+ msgnl (str (indent^"children = {"));
+ Hashtbl.iter
+ (fun s node ->
+ msgnl (str (indent^" "^s^" |-> "));
+ print_treenode (indent^" ") node
+ )
+ tn.children;
+ msgnl (str (indent^"} }"))
+
+let rec print_stack (st : treenode list) = match st with
+| [] -> msgnl (str "[]")
+| x :: xs -> print_treenode "" x; msgnl (str ("::")); print_stack xs
+*)
+
+let string_of_call ck =
+ let s =
+ string_of_ppcmds
+ (match ck with
+ | Tacexpr.LtacNotationCall s -> Names.KerName.print s
+ | Tacexpr.LtacNameCall cst -> Pptactic.pr_ltac_constant cst
+ | Tacexpr.LtacVarCall (id, t) -> Nameops.pr_id id
+ | Tacexpr.LtacAtomCall te ->
+ (Pptactic.pr_glob_tactic (Global.env ())
+ (Tacexpr.TacAtom (Loc.ghost, te)))
+ | Tacexpr.LtacConstrInterp (c, _) ->
+ pr_glob_constr_env (Global.env ()) c
+ | Tacexpr.LtacMLCall te ->
+ (Pptactic.pr_glob_tactic (Global.env ())
+ te)
+ ) in
+ for i = 0 to String.length s - 1 do if s.[i] = '\n' then s.[i] <- ' ' done;
+ let s = try String.sub s 0 (CString.string_index_from s 0 "(*") with Not_found -> s in
+ CString.strip s
+
+let exit_tactic start_time add_total c = match !stack with
+| [] | [_] ->
+ (* oops, our stack is invalid *)
+ encounter_multi_success_backtracking ()
+| node :: (parent :: _ as stack') ->
+ stack := stack';
+ if add_total then Hashtbl.remove on_stack (string_of_call c);
+ let diff = time () -. start_time in
+ parent.entry.local <- parent.entry.local -. diff;
+ let node' = { total = diff; local = diff; ncalls = 1; max_total = diff } in
+ add_entry node.entry add_total node'
+
+let tclFINALLY tac (finally : unit Proofview.tactic) =
+ let open Proofview.Notations in
+ Proofview.tclIFCATCH
+ tac
+ (fun v -> finally <*> Proofview.tclUNIT v)
+ (fun (exn, info) -> finally <*> Proofview.tclZERO ~info exn)
+
+let do_profile s call_trace tac =
+ let open Proofview.Notations in
+ Proofview.tclLIFT (Proofview.NonLogical.make (fun () ->
+ if !is_profiling && is_new_call () then
+ match call_trace with
+ | (_, c) :: _ ->
+ let s = string_of_call c in
+ let parent = List.hd !stack in
+ let node, add_total = try Hashtbl.find on_stack s, false
+ with Not_found ->
+ let node = get_node s parent.children in
+ Hashtbl.add on_stack s node;
+ node, true
+ in
+ if not add_total && node = List.hd !stack then None else (
+ stack := node :: !stack;
+ let start_time = time () in
+ Some (start_time, add_total)
+ )
+ | [] -> None
+ else None)) >>= function
+ | Some (start_time, add_total) ->
+ tclFINALLY
+ tac
+ (Proofview.tclLIFT (Proofview.NonLogical.make (fun () ->
+ (match call_trace with
+ | (_, c) :: _ ->
+ exit_tactic start_time add_total c
+ | [] -> ()))))
+ | None -> tac
+
+
+
+let format_sec x = (Printf.sprintf "%.3fs" x)
+let format_ratio x = (Printf.sprintf "%.1f%%" (100. *. x))
+let padl n s = ws (max 0 (n - utf8_length s)) ++ str s
+let padr n s = str s ++ ws (max 0 (n - utf8_length s))
+let padr_with c n s =
+ let ulength = utf8_length s in
+ str (utf8_sub s 0 n) ++ str (String.make (max 0 (n - ulength)) c)
+
+let rec list_iter_is_last f = function
+ | [] -> []
+ | [x] -> [f true x]
+ | x :: xs -> f false x :: list_iter_is_last f xs
+
+let header =
+ str " tactic self total calls max" ++
+ fnl () ++
+ str "────────────────────────────────────────┴──────┴──────┴───────┴─────────┘"
+
+let rec print_node all_total indent prefix (s, n) =
+ let e = n.entry in
+ h 0 (
+ padr_with '-' 40 (prefix ^ s ^ " ")
+ ++ padl 7 (format_ratio (e.local /. all_total))
+ ++ padl 7 (format_ratio (e.total /. all_total))
+ ++ padl 8 (string_of_int e.ncalls)
+ ++ padl 10 (format_sec (e.max_total))
+ ) ++
+ print_table all_total indent false n.children
+
+and print_table all_total indent first_level table =
+ let fold s n l = if n.entry.total /. all_total < 0.02 then l else (s, n) :: l in
+ let ls = Hashtbl.fold fold table [] in
+ match ls with
+ | [s, n] when not first_level ->
+ print_node all_total indent (indent ^ "└") (s, n)
+ | _ ->
+ let ls = List.sort (fun (_, n1) (_, n2) -> compare n2.entry.total n1.entry.total) ls in
+ let iter is_last =
+ let sep0 = if first_level then "" else if is_last then " " else " │" in
+ let sep1 = if first_level then "─" else if is_last then " └─" else " ├─" in
+ print_node all_total (indent ^ sep0) (indent ^ sep1)
+ in
+ prlist_with_sep fnl (fun pr -> pr) (list_iter_is_last iter ls)
+
+let print_results () =
+ let tree = (List.hd !stack).children in
+ let all_total = -. (List.hd !stack).entry.local in
+ let global = Hashtbl.create 20 in
+ let rec cumulate table =
+ let iter s node =
+ let node' = get_node s global in
+ add_entry node'.entry true node.entry;
+ cumulate node.children
+ in
+ Hashtbl.iter iter table
+ in
+ cumulate tree;
+ warn_encountered_multi_success_backtracking ();
+ let msg =
+ h 0 (str "total time: " ++ padl 11 (format_sec (all_total))) ++
+ fnl () ++
+ header ++
+ print_table all_total "" true global ++
+ fnl () ++
+ header ++
+ print_table all_total "" true tree
+ in
+ Feedback.msg_notice msg
+ (* FOR DEBUGGING *)
+ (* ;
+ msgnl (str"");
+ print_stack (!stack)
+ *)
+
+let print_results_tactic tactic =
+ let tree = (List.hd !stack).children in
+ let table_tactic = Hashtbl.create 20 in
+ let rec cumulate table =
+ let iter s node =
+ if String.sub (s ^ ".") 0 (min (1 + String.length s) (String.length tactic)) = tactic
+ then add_node (get_node s table_tactic) node
+ else cumulate node.children
+ in
+ Hashtbl.iter iter table
+ in
+ cumulate tree;
+ let all_total = -. (List.hd !stack).entry.local in
+ let tactic_total =
+ Hashtbl.fold
+ (fun _ node all_total -> node.entry.total +. all_total)
+ table_tactic 0. in
+ warn_encountered_multi_success_backtracking ();
+ let msg =
+ h 0 (str"total time: " ++ padl 11 (format_sec (all_total))) ++
+ h 0 (str"time spent in tactic: " ++ padl 11 (format_sec (tactic_total))) ++
+ fnl () ++
+ header ++
+ print_table tactic_total "" true table_tactic
+ in
+ Feedback.msg_notice msg
+
+let reset_profile () =
+ stack := [empty_treenode 20];
+ encountered_multi_success_backtracking := false
+
+let do_print_results_at_close () = if get_profiling () then print_results ()
+
+let _ = Declaremods.append_end_library_hook do_print_results_at_close
+
+let _ =
+ let open Goptions in
+ declare_bool_option
+ { optsync = true;
+ optdepr = false;
+ optname = "Ltac Profiling";
+ optkey = ["Ltac"; "Profiling"];
+ optread = get_profiling;
+ optwrite = set_profiling }
diff --git a/tactics/geninterp.mli b/ltac/profile_ltac.mli
index 0992db7a2..7bbdca942 100644
--- a/tactics/geninterp.mli
+++ b/ltac/profile_ltac.mli
@@ -6,22 +6,20 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(** Interpretation functions for generic arguments. *)
+(** Ltac profiling primitives *)
-open Names
-open Genarg
+val do_profile : string -> ('a * Tacexpr.ltac_call_kind) list -> 'b Proofview.tactic -> 'b Proofview.tactic
-module TacStore : Store.S
+val set_profiling : bool -> unit
-type interp_sign = {
- lfun : Val.t Id.Map.t;
- extra : TacStore.t }
+val get_profiling : unit -> bool
-type ('glb, 'top) interp_fun = interp_sign -> 'glb -> 'top Ftactic.t
+val entered_call : unit -> unit
-val interp : ('raw, 'glb, 'top) genarg_type -> ('glb, 'top) interp_fun
+val print_results : unit -> unit
-val generic_interp : (glob_generic_argument, Val.t) interp_fun
+val print_results_tactic : string -> unit
-val register_interp0 :
- ('raw, 'glb, 'top) genarg_type -> ('glb, 'top) interp_fun -> unit
+val reset_profile : unit -> unit
+
+val do_print_results_at_close : unit -> unit
diff --git a/ltac/profile_ltac_tactics.ml4 b/ltac/profile_ltac_tactics.ml4
new file mode 100644
index 000000000..c092a0cb6
--- /dev/null
+++ b/ltac/profile_ltac_tactics.ml4
@@ -0,0 +1,39 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(*i camlp4deps: "grammar/grammar.cma" i*)
+
+(** Ltac profiling entrypoints *)
+
+open Profile_ltac
+open Stdarg
+
+DECLARE PLUGIN "profile_ltac_plugin"
+
+let tclSET_PROFILING b =
+ Proofview.tclLIFT (Proofview.NonLogical.make (fun () -> set_profiling b))
+
+TACTIC EXTEND start_ltac_profiling
+| [ "start" "ltac" "profiling" ] -> [ tclSET_PROFILING true ]
+END
+
+TACTIC EXTEND stop_profiling
+| [ "stop" "ltac" "profiling" ] -> [ tclSET_PROFILING false ]
+END
+
+VERNAC COMMAND EXTEND ResetLtacProfiling CLASSIFIED AS SIDEFF
+ [ "Reset" "Ltac" "Profile" ] -> [ reset_profile() ]
+END
+
+VERNAC COMMAND EXTEND ShowLtacProfile CLASSIFIED AS QUERY
+ [ "Show" "Ltac" "Profile" ] -> [ print_results() ]
+END
+
+VERNAC COMMAND EXTEND ShowLtacProfileTactic CLASSIFIED AS QUERY
+ [ "Show" "Ltac" "Profile" string(s) ] -> [ print_results_tactic s ]
+END
diff --git a/tactics/rewrite.ml b/ltac/rewrite.ml
index 8123bd755..cb39df8ab 100644
--- a/tactics/rewrite.ml
+++ b/ltac/rewrite.ml
@@ -6,8 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i camlp4deps: "grammar/grammar.cma" i*)
-
open Names
open Pp
open Errors
@@ -361,7 +359,7 @@ end) = struct
let env' = Environ.push_rel_context rels env in
let sigma = Sigma.Unsafe.of_evar_map sigma in
let Sigma ((evar, _), evars, _) = Evarutil.new_type_evar env' sigma Evd.univ_flexible in
- let evars = Sigma.to_evar_map sigma in
+ let evars = Sigma.to_evar_map evars in
let evars, inst =
app_poly env (evars,Evar.Set.empty)
rewrite_relation_class [| evar; mkApp (c, params) |] in
@@ -484,11 +482,15 @@ let rec decompose_app_rel env evd t =
let len = Array.length args in
let fargs = Array.sub args 0 (Array.length args - 2) in
let rel = mkApp (f, fargs) in
- let ty = Retyping.get_type_of env evd rel in
- let () = if not (Reduction.is_arity env ty) then error_no_relation () in
rel, args.(len - 2), args.(len - 1)
| _ -> error_no_relation ()
+let decompose_app_rel env evd t =
+ let (rel, t1, t2) = decompose_app_rel env evd t in
+ let ty = Retyping.get_type_of env evd rel in
+ let () = if not (Reduction.is_arity env ty) then error_no_relation () in
+ (rel, t1, t2)
+
let decompose_applied_relation env sigma (c,l) =
let open Context.Rel.Declaration in
let ctype = Retyping.get_type_of env sigma c in
@@ -610,7 +612,12 @@ let solve_remaining_by env sigma holes by =
in
(** Only solve independent holes *)
let indep = List.map_filter map holes in
- let solve_tac = Tacticals.New.tclCOMPLETE (Tacinterp.eval_tactic tac) in
+ let ist = { Geninterp.lfun = Id.Map.empty; extra = Geninterp.TacStore.empty } in
+ let solve_tac = match tac with
+ | Genarg.GenArg (Genarg.Glbwit tag, tac) ->
+ Ftactic.run (Geninterp.interp tag ist tac) (fun _ -> Proofview.tclUNIT ())
+ in
+ let solve_tac = Tacticals.New.tclCOMPLETE solve_tac in
let solve sigma evk =
let evi =
try Some (Evd.find_undefined sigma evk)
@@ -1041,7 +1048,7 @@ let subterm all flags (s : 'a pure_strategy) : 'a pure_strategy =
| x -> x
in
let res =
- { rew_car = prod_appvect r.rew_car args;
+ { rew_car = Reductionops.hnf_prod_appvect env (goalevars evars) r.rew_car args;
rew_from = mkApp(r.rew_from, args); rew_to = mkApp(r.rew_to, args);
rew_prf = prf; rew_evars = r.rew_evars }
in
@@ -1537,7 +1544,7 @@ let assert_replacing id newt tac =
| d :: rem -> insert_dependent env (LocalAssum (get_id d, newt)) [] after @ rem
in
let env' = Environ.reset_with_named_context (val_of_named_context nc) env in
- Proofview.Refine.refine ~unsafe:false { run = begin fun sigma ->
+ Refine.refine ~unsafe:false { run = begin fun sigma ->
let Sigma (ev, sigma, p) = Evarutil.new_evar env' sigma concl in
let Sigma (ev', sigma, q) = Evarutil.new_evar env sigma newt in
let map d =
@@ -1566,7 +1573,7 @@ let cl_rewrite_clause_newtac ?abs ?origsigma ~progress strat clause =
let gls = List.rev (Evd.fold_undefined fold undef []) in
match clause, prf with
| Some id, Some p ->
- let tac = Proofview.Refine.refine ~unsafe:false { run = fun h -> Sigma (p, h, Sigma.refl) } <*> Proofview.Unsafe.tclNEWGOALS gls in
+ let tac = Refine.refine ~unsafe:false { run = fun h -> Sigma (p, h, Sigma.refl) } <*> Proofview.Unsafe.tclNEWGOALS gls in
Proofview.Unsafe.tclEVARS undef <*>
assert_replacing id newt tac
| Some id, None ->
@@ -1580,7 +1587,7 @@ let cl_rewrite_clause_newtac ?abs ?origsigma ~progress strat clause =
let Sigma (ev, sigma, q) = Evarutil.new_evar env sigma newt in
Sigma (mkApp (p, [| ev |]), sigma, q)
end } in
- Proofview.Refine.refine ~unsafe:false make <*> Proofview.Unsafe.tclNEWGOALS gls
+ Refine.refine ~unsafe:false make <*> Proofview.Unsafe.tclNEWGOALS gls
end }
| None, None ->
Proofview.Unsafe.tclEVARS undef <*>
@@ -1744,7 +1751,7 @@ let declare_instance a aeq n s = declare_an_instance n s [a;aeq]
let anew_instance global binders instance fields =
new_instance (Flags.is_universe_polymorphism ())
binders instance (Some (true, CRecord (Loc.ghost,fields)))
- ~global ~generalize:false None
+ ~global ~generalize:false ~refine:false None
let declare_instance_refl global binders a aeq n lemma =
let instance = declare_instance a aeq (add_suffix n "_Reflexive") "Coq.Classes.RelationClasses.Reflexive"
@@ -1818,10 +1825,10 @@ let declare_projection n instance_id r =
let poly = Global.is_polymorphic r in
let env = Global.env () in
let sigma = Evd.from_env env in
- let evd,c = Evd.fresh_global env sigma r in
+ let sigma,c = Evd.fresh_global env sigma r in
let ty = Retyping.get_type_of env sigma c in
let term = proper_projection c ty in
- let typ = Typing.unsafe_type_of env sigma term in
+ let sigma, typ = Typing.type_of env sigma term in
let ctx, typ = decompose_prod_assum typ in
let typ =
let n =
@@ -1850,9 +1857,7 @@ let declare_projection n instance_id r =
ignore(Declare.declare_constant n
(Entries.DefinitionEntry cst, Decl_kinds.IsDefinition Decl_kinds.Definition))
-let build_morphism_signature m =
- let env = Global.env () in
- let sigma = Evd.from_env env in
+let build_morphism_signature env sigma m =
let m,ctx = Constrintern.interp_constr env sigma m in
let sigma = Evd.from_ctx ctx in
let t = Typing.unsafe_type_of env sigma m in
@@ -1877,8 +1882,10 @@ let build_morphism_signature m =
in
let morph = e_app_poly env evd PropGlobal.proper_type [| t; sig_; m |] in
let evd = solve_constraints env !evd in
- let m = Evarutil.nf_evar evd morph in
- Evarutil.check_evars env Evd.empty evd m; m
+ let evd = Evd.nf_constraints evd in
+ let m = Evarutil.nf_evars_universes evd morph in
+ Pretyping.check_evars env Evd.empty evd m;
+ Evd.evar_universe_context evd, m
let default_morphism sign m =
let env = Global.env () in
@@ -1915,12 +1922,13 @@ let add_morphism_infer glob m n =
init_setoid ();
let poly = Flags.is_universe_polymorphism () in
let instance_id = add_suffix n "_Proper" in
- let instance = build_morphism_signature m in
- let evd = Evd.from_env (Global.env ()) in
+ let env = Global.env () in
+ let evd = Evd.from_env env in
+ let uctx, instance = build_morphism_signature env evd m in
if Lib.is_modtype () then
let cst = Declare.declare_constant ~internal:Declare.InternalTacticRequest instance_id
(Entries.ParameterEntry
- (None,poly,(instance,Univ.UContext.empty),None),
+ (None,poly,(instance,Evd.evar_context_universe_context uctx),None),
Decl_kinds.IsAssumption Decl_kinds.Logical)
in
add_instance (Typeclasses.new_instance
@@ -1943,7 +1951,7 @@ let add_morphism_infer glob m n =
let hook = Lemmas.mk_hook hook in
Flags.silently
(fun () ->
- Lemmas.start_proof instance_id kind evd instance hook;
+ Lemmas.start_proof instance_id kind (Evd.from_ctx uctx) instance hook;
ignore (Pfedit.by (Tacinterp.interp tac))) ()
let add_morphism glob binders m s n =
@@ -2084,7 +2092,7 @@ let setoid_proof ty fn fallback =
let open Context.Rel.Declaration in
let (sigma, t) = Typing.type_of env sigma rel in
let car = get_type (List.hd (fst (Reduction.dest_prod env t))) in
- (try init_setoid () with _ -> raise Not_found);
+ (try init_relation_classes () with _ -> raise Not_found);
fn env sigma car rel
with e -> Proofview.tclZERO e
end
diff --git a/tactics/rewrite.mli b/ltac/rewrite.mli
index 01709f29f..01709f29f 100644
--- a/tactics/rewrite.mli
+++ b/ltac/rewrite.mli
diff --git a/ltac/tacentries.ml b/ltac/tacentries.ml
new file mode 100644
index 000000000..f00adecf2
--- /dev/null
+++ b/ltac/tacentries.ml
@@ -0,0 +1,511 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Pp
+open Errors
+open Util
+open Names
+open Libobject
+open Genarg
+open Extend
+open Pcoq
+open Egramml
+open Egramcoq
+open Vernacexpr
+open Libnames
+open Nameops
+
+type 'a grammar_tactic_prod_item_expr = 'a Pptactic.grammar_tactic_prod_item_expr =
+| TacTerm of string
+| TacNonTerm of Loc.t * 'a * Names.Id.t
+
+type raw_argument = string * string option
+type argument = Genarg.ArgT.any Extend.user_symbol
+
+(**********************************************************************)
+(* Interpret entry names of the form "ne_constr_list" as entry keys *)
+
+let coincide s pat off =
+ let len = String.length pat in
+ let break = ref true in
+ let i = ref 0 in
+ while !break && !i < len do
+ let c = Char.code s.[off + !i] in
+ let d = Char.code pat.[!i] in
+ break := Int.equal c d;
+ incr i
+ done;
+ !break
+
+let atactic n =
+ if n = 5 then Aentry Tactic.binder_tactic
+ else Aentryl (Tactic.tactic_expr, n)
+
+type entry_name = EntryName :
+ 'a raw_abstract_argument_type * (Tacexpr.raw_tactic_expr, 'a) Extend.symbol -> entry_name
+
+(** Quite ad-hoc *)
+let get_tacentry n m =
+ let check_lvl n =
+ Int.equal m n
+ && not (Int.equal m 5) (* Because tactic5 is at binder_tactic *)
+ && not (Int.equal m 0) (* Because tactic0 is at simple_tactic *)
+ in
+ if check_lvl n then EntryName (rawwit Constrarg.wit_tactic, Aself)
+ else if check_lvl (n + 1) then EntryName (rawwit Constrarg.wit_tactic, Anext)
+ else EntryName (rawwit Constrarg.wit_tactic, atactic n)
+
+let get_separator = function
+| None -> error "Missing separator."
+| Some sep -> sep
+
+let rec parse_user_entry s sep =
+ let l = String.length s in
+ if l > 8 && coincide s "ne_" 0 && coincide s "_list" (l - 5) then
+ let entry = parse_user_entry (String.sub s 3 (l-8)) None in
+ Ulist1 entry
+ else if l > 12 && coincide s "ne_" 0 &&
+ coincide s "_list_sep" (l-9) then
+ let entry = parse_user_entry (String.sub s 3 (l-12)) None in
+ Ulist1sep (entry, get_separator sep)
+ else if l > 5 && coincide s "_list" (l-5) then
+ let entry = parse_user_entry (String.sub s 0 (l-5)) None in
+ Ulist0 entry
+ else if l > 9 && coincide s "_list_sep" (l-9) then
+ let entry = parse_user_entry (String.sub s 0 (l-9)) None in
+ Ulist0sep (entry, get_separator sep)
+ else if l > 4 && coincide s "_opt" (l-4) then
+ let entry = parse_user_entry (String.sub s 0 (l-4)) None in
+ Uopt entry
+ else if Int.equal l 7 && coincide s "tactic" 0 && '5' >= s.[6] && s.[6] >= '0' then
+ let n = Char.code s.[6] - 48 in
+ Uentryl ("tactic", n)
+ else
+ Uentry s
+
+let arg_list = function Rawwit t -> Rawwit (ListArg t)
+let arg_opt = function Rawwit t -> Rawwit (OptArg t)
+
+let interp_entry_name interp symb =
+ let rec eval = function
+ | Ulist1 e -> Ulist1 (eval e)
+ | Ulist1sep (e, sep) -> Ulist1sep (eval e, sep)
+ | Ulist0 e -> Ulist0 (eval e)
+ | Ulist0sep (e, sep) -> Ulist0sep (eval e, sep)
+ | Uopt e -> Uopt (eval e)
+ | Uentry s -> Uentry (interp s None)
+ | Uentryl (s, n) -> Uentryl (interp s (Some n), n)
+ in
+ eval symb
+
+(**********************************************************************)
+(** Grammar declaration for Tactic Notation (Coq level) *)
+
+let get_tactic_entry n =
+ if Int.equal n 0 then
+ Tactic.simple_tactic, None
+ else if Int.equal n 5 then
+ Tactic.binder_tactic, None
+ else if 1<=n && n<5 then
+ Tactic.tactic_expr, Some (Extend.Level (string_of_int n))
+ else
+ error ("Invalid Tactic Notation level: "^(string_of_int n)^".")
+
+(**********************************************************************)
+(** State of the grammar extensions *)
+
+type tactic_grammar = {
+ tacgram_level : int;
+ tacgram_prods : Pptactic.grammar_terminals;
+}
+
+(* Declaration of the tactic grammar rule *)
+
+let head_is_ident tg = match tg.tacgram_prods with
+| TacTerm _ :: _ -> true
+| _ -> false
+
+let rec prod_item_of_symbol lev = function
+| Extend.Ulist1 s ->
+ let EntryName (Rawwit typ, e) = prod_item_of_symbol lev s in
+ EntryName (Rawwit (ListArg typ), Alist1 e)
+| Extend.Ulist0 s ->
+ let EntryName (Rawwit typ, e) = prod_item_of_symbol lev s in
+ EntryName (Rawwit (ListArg typ), Alist0 e)
+| Extend.Ulist1sep (s, sep) ->
+ let EntryName (Rawwit typ, e) = prod_item_of_symbol lev s in
+ EntryName (Rawwit (ListArg typ), Alist1sep (e, Atoken (CLexer.terminal sep)))
+| Extend.Ulist0sep (s, sep) ->
+ let EntryName (Rawwit typ, e) = prod_item_of_symbol lev s in
+ EntryName (Rawwit (ListArg typ), Alist0sep (e, Atoken (CLexer.terminal sep)))
+| Extend.Uopt s ->
+ let EntryName (Rawwit typ, e) = prod_item_of_symbol lev s in
+ EntryName (Rawwit (OptArg typ), Aopt e)
+| Extend.Uentry arg ->
+ let ArgT.Any tag = arg in
+ let wit = ExtraArg tag in
+ EntryName (Rawwit wit, Extend.Aentry (genarg_grammar wit))
+| Extend.Uentryl (s, n) ->
+ let ArgT.Any tag = s in
+ assert (coincide (ArgT.repr tag) "tactic" 0);
+ get_tacentry n lev
+
+(** Tactic grammar extensions *)
+
+let add_tactic_entry (kn, ml, tg) state =
+ let open Tacexpr in
+ let entry, pos = get_tactic_entry tg.tacgram_level in
+ let mkact loc l =
+ let map arg =
+ (** HACK to handle especially the tactic(...) entry *)
+ let wit = Genarg.rawwit Constrarg.wit_tactic in
+ if Genarg.has_type arg wit && not ml then
+ Tacexp (Genarg.out_gen wit arg)
+ else
+ TacGeneric arg
+ in
+ let l = List.map map l in
+ (TacAlias (loc,kn,l):raw_tactic_expr)
+ in
+ let () =
+ if Int.equal tg.tacgram_level 0 && not (head_is_ident tg) then
+ error "Notation for simple tactic must start with an identifier."
+ in
+ let map = function
+ | TacTerm s -> GramTerminal s
+ | TacNonTerm (loc, s, _) ->
+ let EntryName (typ, e) = prod_item_of_symbol tg.tacgram_level s in
+ GramNonTerminal (loc, typ, e)
+ in
+ let prods = List.map map tg.tacgram_prods in
+ let rules = make_rule mkact prods in
+ let r = ExtendRule (entry, None, (pos, [(None, None, [rules])])) in
+ ([r], state)
+
+let tactic_grammar =
+ create_grammar_command "TacticGrammar" add_tactic_entry
+
+let extend_tactic_grammar kn ml ntn = extend_grammar_command tactic_grammar (kn, ml, ntn)
+
+(**********************************************************************)
+(* Tactic Notation *)
+
+let entry_names = ref String.Map.empty
+
+let register_tactic_notation_entry name entry =
+ let entry = match entry with
+ | ExtraArg arg -> ArgT.Any arg
+ | _ -> assert false
+ in
+ entry_names := String.Map.add name entry !entry_names
+
+let interp_prod_item = function
+ | TacTerm s -> TacTerm s
+ | TacNonTerm (loc, (nt, sep), id) ->
+ let symbol = parse_user_entry nt sep in
+ let interp s = function
+ | None ->
+ if String.Map.mem s !entry_names then String.Map.find s !entry_names
+ else begin match ArgT.name s with
+ | None -> error ("Unknown entry "^s^".")
+ | Some arg -> arg
+ end
+ | Some n ->
+ (** FIXME: do better someday *)
+ assert (String.equal s "tactic");
+ begin match Constrarg.wit_tactic with
+ | ExtraArg tag -> ArgT.Any tag
+ | _ -> assert false
+ end
+ in
+ let symbol = interp_entry_name interp symbol in
+ TacNonTerm (loc, symbol, id)
+
+let make_fresh_key =
+ let id = Summary.ref ~name:"TACTIC-NOTATION-COUNTER" 0 in
+ fun prods ->
+ let cur = incr id; !id in
+ let map = function
+ | TacTerm s -> s
+ | TacNonTerm _ -> "#"
+ in
+ let prods = String.concat "_" (List.map map prods) in
+ (** We embed the hash of the kernel name in the label so that the identifier
+ should be mostly unique. This ensures that including two modules
+ together won't confuse the corresponding labels. *)
+ let hash = (cur lxor (ModPath.hash (Lib.current_mp ()))) land 0x7FFFFFFF in
+ let lbl = Id.of_string_soft (Printf.sprintf "%s_%08X" prods hash) in
+ Lib.make_kn lbl
+
+type tactic_grammar_obj = {
+ tacobj_key : KerName.t;
+ tacobj_local : locality_flag;
+ tacobj_tacgram : tactic_grammar;
+ tacobj_body : Id.t list * Tacexpr.glob_tactic_expr;
+ tacobj_forml : bool;
+}
+
+let pprule pa = {
+ Pptactic.pptac_level = pa.tacgram_level;
+ pptac_prods = pa.tacgram_prods;
+}
+
+let check_key key =
+ if Tacenv.check_alias key then
+ error "Conflicting tactic notations keys. This can happen when including \
+ twice the same module."
+
+let cache_tactic_notation (_, tobj) =
+ let key = tobj.tacobj_key in
+ let () = check_key key in
+ Tacenv.register_alias key tobj.tacobj_body;
+ extend_tactic_grammar key tobj.tacobj_forml tobj.tacobj_tacgram;
+ Pptactic.declare_notation_tactic_pprule key (pprule tobj.tacobj_tacgram)
+
+let open_tactic_notation i (_, tobj) =
+ let key = tobj.tacobj_key in
+ if Int.equal i 1 && not tobj.tacobj_local then
+ extend_tactic_grammar key tobj.tacobj_forml tobj.tacobj_tacgram
+
+let load_tactic_notation i (_, tobj) =
+ let key = tobj.tacobj_key in
+ let () = check_key key in
+ (** Only add the printing and interpretation rules. *)
+ Tacenv.register_alias key tobj.tacobj_body;
+ Pptactic.declare_notation_tactic_pprule key (pprule tobj.tacobj_tacgram);
+ if Int.equal i 1 && not tobj.tacobj_local then
+ extend_tactic_grammar key tobj.tacobj_forml tobj.tacobj_tacgram
+
+let subst_tactic_notation (subst, tobj) =
+ let (ids, body) = tobj.tacobj_body in
+ { tobj with
+ tacobj_key = Mod_subst.subst_kn subst tobj.tacobj_key;
+ tacobj_body = (ids, Tacsubst.subst_tactic subst body);
+ }
+
+let classify_tactic_notation tacobj = Substitute tacobj
+
+let inTacticGrammar : tactic_grammar_obj -> obj =
+ declare_object {(default_object "TacticGrammar") with
+ open_function = open_tactic_notation;
+ load_function = load_tactic_notation;
+ cache_function = cache_tactic_notation;
+ subst_function = subst_tactic_notation;
+ classify_function = classify_tactic_notation}
+
+let cons_production_parameter = function
+| TacTerm _ -> None
+| TacNonTerm (_, _, id) -> Some id
+
+let add_glob_tactic_notation local n prods forml ids tac =
+ let parule = {
+ tacgram_level = n;
+ tacgram_prods = prods;
+ } in
+ let tacobj = {
+ tacobj_key = make_fresh_key prods;
+ tacobj_local = local;
+ tacobj_tacgram = parule;
+ tacobj_body = (ids, tac);
+ tacobj_forml = forml;
+ } in
+ Lib.add_anonymous_leaf (inTacticGrammar tacobj)
+
+let add_tactic_notation local n prods e =
+ let ids = List.map_filter cons_production_parameter prods in
+ let prods = List.map interp_prod_item prods in
+ let tac = Tacintern.glob_tactic_env ids (Global.env()) e in
+ add_glob_tactic_notation local n prods false ids tac
+
+(**********************************************************************)
+(* ML Tactic entries *)
+
+exception NonEmptyArgument
+
+(** ML tactic notations whose use can be restricted to an identifier are added
+ as true Ltac entries. *)
+let extend_atomic_tactic name entries =
+ let open Tacexpr in
+ let map_prod prods =
+ let (hd, rem) = match prods with
+ | TacTerm s :: rem -> (s, rem)
+ | _ -> assert false (** Not handled by the ML extension syntax *)
+ in
+ let empty_value = function
+ | TacTerm s -> raise NonEmptyArgument
+ | TacNonTerm (_, symb, _) ->
+ let EntryName (typ, e) = prod_item_of_symbol 0 symb in
+ let Genarg.Rawwit wit = typ in
+ let inj x = TacArg (Loc.ghost, TacGeneric (Genarg.in_gen typ x)) in
+ let default = epsilon_value inj e in
+ match default with
+ | None -> raise NonEmptyArgument
+ | Some def -> Tacintern.intern_tactic_or_tacarg Tacintern.fully_empty_glob_sign def
+ in
+ try Some (hd, List.map empty_value rem) with NonEmptyArgument -> None
+ in
+ let entries = List.map map_prod entries in
+ let add_atomic i args = match args with
+ | None -> ()
+ | Some (id, args) ->
+ let args = List.map (fun a -> Tacexp a) args in
+ let entry = { mltac_name = name; mltac_index = i } in
+ let body = TacML (Loc.ghost, entry, args) in
+ Tacenv.register_ltac false false (Names.Id.of_string id) body
+ in
+ List.iteri add_atomic entries
+
+let add_ml_tactic_notation name prods =
+ let len = List.length prods in
+ let iter i prods =
+ let open Tacexpr in
+ let get_id = function
+ | TacTerm s -> None
+ | TacNonTerm (_, _, id) -> Some id
+ in
+ let ids = List.map_filter get_id prods in
+ let entry = { mltac_name = name; mltac_index = len - i - 1 } in
+ let map id = Reference (Misctypes.ArgVar (Loc.ghost, id)) in
+ let tac = TacML (Loc.ghost, entry, List.map map ids) in
+ add_glob_tactic_notation false 0 prods true ids tac
+ in
+ List.iteri iter (List.rev prods);
+ extend_atomic_tactic name prods
+
+(**********************************************************************)
+(** Ltac quotations *)
+
+let ltac_quotations = ref String.Set.empty
+
+let create_ltac_quotation name cast (e, l) =
+ let () =
+ if String.Set.mem name !ltac_quotations then
+ failwith ("Ltac quotation " ^ name ^ " already registered")
+ in
+ let () = ltac_quotations := String.Set.add name !ltac_quotations in
+ let entry = match l with
+ | None -> Aentry e
+ | Some l -> Aentryl (e, l)
+ in
+(* let level = Some "1" in *)
+ let level = None in
+ let assoc = None in
+ let rule =
+ Next (Next (Next (Next (Next (Stop,
+ Atoken (CLexer.terminal name)),
+ Atoken (CLexer.terminal ":")),
+ Atoken (CLexer.terminal "(")),
+ entry),
+ Atoken (CLexer.terminal ")"))
+ in
+ let action _ v _ _ _ loc = cast (loc, v) in
+ let gram = (level, assoc, [Rule (rule, action)]) in
+ Pcoq.grammar_extend Tactic.tactic_arg None (None, [gram])
+
+(** Command *)
+
+
+type tacdef_kind =
+ | NewTac of Id.t
+ | UpdateTac of Nametab.ltac_constant
+
+let is_defined_tac kn =
+ try ignore (Tacenv.interp_ltac kn); true with Not_found -> false
+
+let register_ltac local tacl =
+ let map tactic_body =
+ match tactic_body with
+ | TacticDefinition ((loc,id), body) ->
+ let kn = Lib.make_kn id in
+ let id_pp = pr_id id in
+ let () = if is_defined_tac kn then
+ Errors.user_err_loc (loc, "",
+ str "There is already an Ltac named " ++ id_pp ++ str".")
+ in
+ let is_primitive =
+ try
+ match Pcoq.parse_string Pcoq.Tactic.tactic (Id.to_string id) with
+ | Tacexpr.TacArg _ -> false
+ | _ -> true (* most probably TacAtom, i.e. a primitive tactic ident *)
+ with e when Errors.noncritical e -> true (* prim tactics with args, e.g. "apply" *)
+ in
+ let () = if is_primitive then
+ Feedback.msg_warning (str "The Ltac name " ++ id_pp ++
+ str " may be unusable because of a conflict with a notation.")
+ in
+ NewTac id, body
+ | TacticRedefinition (ident, body) ->
+ let loc = loc_of_reference ident in
+ let kn =
+ try Nametab.locate_tactic (snd (qualid_of_reference ident))
+ with Not_found ->
+ Errors.user_err_loc (loc, "",
+ str "There is no Ltac named " ++ pr_reference ident ++ str ".")
+ in
+ UpdateTac kn, body
+ in
+ let rfun = List.map map tacl in
+ let recvars =
+ let fold accu (op, _) = match op with
+ | UpdateTac _ -> accu
+ | NewTac id -> (Lib.make_path id, Lib.make_kn id) :: accu
+ in
+ List.fold_left fold [] rfun
+ in
+ let ist = Tacintern.make_empty_glob_sign () in
+ let map (name, body) =
+ let body = Flags.with_option Tacintern.strict_check (Tacintern.intern_tactic_or_tacarg ist) body in
+ (name, body)
+ in
+ let defs () =
+ (** Register locally the tactic to handle recursivity. This function affects
+ the whole environment, so that we transactify it afterwards. *)
+ let iter_rec (sp, kn) = Nametab.push_tactic (Nametab.Until 1) sp kn in
+ let () = List.iter iter_rec recvars in
+ List.map map rfun
+ in
+ let defs = Future.transactify defs () in
+ let iter (def, tac) = match def with
+ | NewTac id ->
+ Tacenv.register_ltac false local id tac;
+ Flags.if_verbose Feedback.msg_info (Nameops.pr_id id ++ str " is defined")
+ | UpdateTac kn ->
+ Tacenv.redefine_ltac local kn tac;
+ let name = Nametab.shortest_qualid_of_tactic kn in
+ Flags.if_verbose Feedback.msg_info (Libnames.pr_qualid name ++ str " is redefined")
+ in
+ List.iter iter defs
+
+(** Queries *)
+
+let print_ltacs () =
+ let entries = KNmap.bindings (Tacenv.ltac_entries ()) in
+ let sort (kn1, _) (kn2, _) = KerName.compare kn1 kn2 in
+ let entries = List.sort sort entries in
+ let map (kn, entry) =
+ let qid =
+ try Some (Nametab.shortest_qualid_of_tactic kn)
+ with Not_found -> None
+ in
+ match qid with
+ | None -> None
+ | Some qid -> Some (qid, entry.Tacenv.tac_body)
+ in
+ let entries = List.map_filter map entries in
+ let pr_entry (qid, body) =
+ let (l, t) = match body with
+ | Tacexpr.TacFun (l, t) -> (l, t)
+ | _ -> ([], body)
+ in
+ let pr_ltac_fun_arg = function
+ | None -> spc () ++ str "_"
+ | Some id -> spc () ++ pr_id id
+ in
+ hov 2 (pr_qualid qid ++ prlist pr_ltac_fun_arg l)
+ in
+ Feedback.msg_notice (prlist_with_sep fnl pr_entry entries)
diff --git a/ltac/tacentries.mli b/ltac/tacentries.mli
new file mode 100644
index 000000000..27df819ee
--- /dev/null
+++ b/ltac/tacentries.mli
@@ -0,0 +1,64 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** Ltac toplevel command entries. *)
+
+open Vernacexpr
+open Tacexpr
+
+(** {5 Tactic Definitions} *)
+
+val register_ltac : locality_flag -> Vernacexpr.tacdef_body list -> unit
+(** Adds new Ltac definitions to the environment. *)
+
+(** {5 Tactic Notations} *)
+
+type 'a grammar_tactic_prod_item_expr = 'a Pptactic.grammar_tactic_prod_item_expr =
+| TacTerm of string
+| TacNonTerm of Loc.t * 'a * Names.Id.t
+
+type raw_argument = string * string option
+(** An argument type as provided in Tactic notations, i.e. a string like
+ "ne_foo_list_opt" together with a separator that only makes sense in the
+ "_sep" cases. *)
+
+type argument = Genarg.ArgT.any Extend.user_symbol
+(** A fully resolved argument type given as an AST with generic arguments on the
+ leaves. *)
+
+val add_tactic_notation :
+ locality_flag -> int -> raw_argument grammar_tactic_prod_item_expr list ->
+ raw_tactic_expr -> unit
+(** [add_tactic_notation local level prods expr] adds a tactic notation in the
+ environment at level [level] with locality [local] made of the grammar
+ productions [prods] and returning the body [expr] *)
+
+val register_tactic_notation_entry : string -> ('a, 'b, 'c) Genarg.genarg_type -> unit
+(** Register an argument under a given entry name for tactic notations. When
+ translating [raw_argument] into [argument], atomic names will be first
+ looked up according to names registered through this function and fallback
+ to finding an argument by name (as in {!Genarg}) if there is none
+ matching. *)
+
+val add_ml_tactic_notation : ml_tactic_name ->
+ argument grammar_tactic_prod_item_expr list list -> unit
+(** A low-level variant of {!add_tactic_notation} used by the TACTIC EXTEND
+ ML-side macro. *)
+
+(** {5 Tactic Quotations} *)
+
+val create_ltac_quotation : string ->
+ ('grm Loc.located -> raw_tactic_arg) -> ('grm Pcoq.Gram.entry * int option) -> unit
+(** [create_ltac_quotation name f e] adds a quotation rule to Ltac, that is,
+ Ltac grammar now accepts arguments of the form ["name" ":" "(" <e> ")"], and
+ generates an argument using [f] on the entry parsed by [e]. *)
+
+(** {5 Queries} *)
+
+val print_ltacs : unit -> unit
+(** Display the list of ltac definitions currently available. *)
diff --git a/tactics/tacenv.ml b/ltac/tacenv.ml
index d2d3f3117..005d1f5f4 100644
--- a/tactics/tacenv.ml
+++ b/ltac/tacenv.ml
@@ -7,7 +7,6 @@
(************************************************************************)
open Util
-open Genarg
open Pp
open Names
open Tacexpr
@@ -32,7 +31,7 @@ let check_alias key = KNmap.mem key !alias_map
(** ML tactic extensions (TacML) *)
type ml_tactic =
- Val.t list -> Geninterp.interp_sign -> unit Proofview.tactic
+ Geninterp.Val.t list -> Geninterp.interp_sign -> unit Proofview.tactic
module MLName =
struct
@@ -55,7 +54,7 @@ let register_ml_tactic ?(overwrite = false) s (t : ml_tactic array) =
if MLTacMap.mem s !tac_tab then
if overwrite then
let () = tac_tab := MLTacMap.remove s !tac_tab in
- msg_warning (str "Overwriting definition of tactic " ++ pr_tacname s)
+ Feedback.msg_warning (str "Overwriting definition of tactic " ++ pr_tacname s)
else
Errors.anomaly (str "Cannot redeclare tactic " ++ pr_tacname s ++ str ".")
in
diff --git a/tactics/tacenv.mli b/ltac/tacenv.mli
index 88b54993b..94e14223a 100644
--- a/tactics/tacenv.mli
+++ b/ltac/tacenv.mli
@@ -9,6 +9,7 @@
open Genarg
open Names
open Tacexpr
+open Geninterp
(** This module centralizes the various ways of registering tactics. *)
diff --git a/tactics/tacintern.ml b/ltac/tacintern.ml
index a069fd755..7cda7d137 100644
--- a/tactics/tacintern.ml
+++ b/ltac/tacintern.ml
@@ -325,8 +325,9 @@ let intern_constr_pattern ist ~as_type ~ltacvars pc =
let metas,pat = Constrintern.intern_constr_pattern
ist.genv ~as_type ~ltacvars pc
in
- let c = intern_constr_gen true false ist pc in
- metas,(c,pat)
+ let (glob,_ as c) = intern_constr_gen true false ist pc in
+ let bound_names = Glob_ops.bound_glob_vars glob in
+ metas,(bound_names,c,pat)
let dummy_pat = PRel 0
@@ -334,7 +335,9 @@ let intern_typed_pattern ist p =
(* we cannot ensure in non strict mode that the pattern is closed *)
(* keeping a constr_expr copy is too complicated and we want anyway to *)
(* type it, so we remember the pattern as a glob_constr only *)
- (intern_constr_gen true false ist p,dummy_pat)
+ let (glob,_ as c) = intern_constr_gen true false ist p in
+ let bound_names = Glob_ops.bound_glob_vars glob in
+ (bound_names,c,dummy_pat)
let intern_typed_pattern_or_ref_with_occurrences ist (l,p) =
let interp_ref r =
@@ -358,7 +361,8 @@ let intern_typed_pattern_or_ref_with_occurrences ist (l,p) =
let r = evaluable_of_global_reference ist.genv (VarRef id) in
Inl (ArgArg (r,None))
| _ ->
- Inr ((c,None),dummy_pat) in
+ let bound_names = Glob_ops.bound_glob_vars c in
+ Inr (bound_names,(c,None),dummy_pat) in
(l, match p with
| Inl r -> interp_ref r
| Inr (CAppExpl(_,(None,r,None),[])) ->
@@ -420,7 +424,7 @@ let intern_hyp_location ist ((occs,id),hl) =
(* Reads a pattern *)
let intern_pattern ist ?(as_type=false) ltacvars = function
| Subterm (b,ido,pc) ->
- let (metas,pc) = intern_constr_pattern ist ~as_type ~ltacvars pc in
+ let (metas,pc) = intern_constr_pattern ist ~as_type:false ~ltacvars pc in
ido, metas, Subterm (b,ido,pc)
| Term pc ->
let (metas,pc) = intern_constr_pattern ist ~as_type ~ltacvars pc in
@@ -442,7 +446,7 @@ let opt_cons accu = function
| Some id -> Id.Set.add id accu
(* Reads the hypotheses of a "match goal" rule *)
-let rec intern_match_goal_hyps ist lfun = function
+let rec intern_match_goal_hyps ist ?(as_type=false) lfun = function
| (Hyp ((_,na) as locna,mp))::tl ->
let ido, metas1, pat = intern_pattern ist ~as_type:true lfun mp in
let lfun, metas2, hyps = intern_match_goal_hyps ist lfun tl in
@@ -451,7 +455,7 @@ let rec intern_match_goal_hyps ist lfun = function
| (Def ((_,na) as locna,mv,mp))::tl ->
let ido, metas1, patv = intern_pattern ist ~as_type:false lfun mv in
let ido', metas2, patt = intern_pattern ist ~as_type:true lfun mp in
- let lfun, metas3, hyps = intern_match_goal_hyps ist lfun tl in
+ let lfun, metas3, hyps = intern_match_goal_hyps ist ~as_type lfun tl in
let lfun' = name_cons (opt_cons (opt_cons lfun ido) ido') na in
lfun', metas1@metas2@metas3, Def (locna,patv,patt)::hyps
| [] -> lfun, [], []
@@ -471,19 +475,12 @@ let clause_app f = function
| { onhyps=Some l; concl_occs=nl } ->
{ onhyps=Some(List.map f l); concl_occs=nl}
-let map_raw wit f ist x =
- in_gen (glbwit wit) (f ist (out_gen (rawwit wit) x))
-
(* Globalizes tactics : raw_tactic_expr -> glob_tactic_expr *)
let rec intern_atomic lf ist x =
match (x:raw_atomic_tactic_expr) with
(* Basic tactics *)
| TacIntroPattern l ->
TacIntroPattern (List.map (intern_intro_pattern lf ist) l)
- | TacIntroMove (ido,hto) ->
- TacIntroMove (Option.map (intern_ident lf ist) ido,
- intern_move_location ist hto)
- | TacExact c -> TacExact (intern_constr ist c)
| TacApply (a,ev,cb,inhyp) ->
TacApply (a,ev,List.map (intern_constr_with_bindings_arg ist) cb,
Option.map (intern_in_hyp_as ist lf) inhyp)
@@ -519,16 +516,6 @@ let rec intern_atomic lf ist x =
Option.map (intern_or_and_intro_pattern_loc lf ist) ipats),
Option.map (clause_app (intern_hyp_location ist)) cls)) l,
Option.map (intern_constr_with_bindings ist) el))
- | TacDoubleInduction (h1,h2) ->
- let h1 = intern_quantified_hypothesis ist h1 in
- let h2 = intern_quantified_hypothesis ist h2 in
- TacDoubleInduction (h1,h2)
- (* Context management *)
- | TacRename l ->
- TacRename (List.map (fun (id1,id2) ->
- intern_hyp ist id1,
- intern_hyp ist id2) l)
-
(* Conversion *)
| TacReduce (r,cl) ->
dump_glob_red_expr r;
@@ -577,7 +564,7 @@ and intern_tactic_seq onlytac ist = function
ist.ltacvars, TacLetIn (isrec,l,intern_tactic onlytac ist' u)
| TacMatchGoal (lz,lr,lmr) ->
- ist.ltacvars, TacMatchGoal(lz,lr, intern_match_rule onlytac ist lmr)
+ ist.ltacvars, (TacMatchGoal(lz,lr, intern_match_rule onlytac ist ~as_type:true lmr))
| TacMatch (lz,c,lmr) ->
ist.ltacvars,
TacMatch (lz,intern_tactic_or_tacarg ist c,intern_match_rule onlytac ist lmr)
@@ -651,7 +638,7 @@ and intern_tactic_as_arg loc onlytac ist a =
| TacCall _ | Reference _
| TacGeneric _ as a -> TacArg (loc,a)
| Tacexp a -> a
- | ConstrMayEval _ | UConstr _ | TacFreshId _ | TacPretype _ | TacNumgoals as a ->
+ | ConstrMayEval _ | TacFreshId _ | TacPretype _ | TacNumgoals as a ->
if onlytac then error_tactic_expected loc else TacArg (loc,a)
and intern_tactic_or_tacarg ist = intern_tactic false ist
@@ -665,7 +652,6 @@ and intern_tactic_fun ist (var,body) =
and intern_tacarg strict onlytac ist = function
| Reference r -> intern_non_tactic_reference strict ist r
| ConstrMayEval c -> ConstrMayEval (intern_constr_may_eval ist c)
- | UConstr c -> UConstr (intern_constr ist c)
| TacCall (loc,f,[]) -> intern_isolated_tactic_reference strict ist f
| TacCall (loc,f,l) ->
TacCall (loc,
@@ -680,18 +666,18 @@ and intern_tacarg strict onlytac ist = function
TacGeneric arg
(* Reads the rules of a Match Context or a Match *)
-and intern_match_rule onlytac ist = function
+and intern_match_rule onlytac ist ?(as_type=false) = function
| (All tc)::tl ->
- All (intern_tactic onlytac ist tc) :: (intern_match_rule onlytac ist tl)
+ All (intern_tactic onlytac ist tc) :: (intern_match_rule onlytac ist ~as_type tl)
| (Pat (rl,mp,tc))::tl ->
let {ltacvars=lfun; genv=env} = ist in
- let lfun',metas1,hyps = intern_match_goal_hyps ist lfun rl in
- let ido,metas2,pat = intern_pattern ist lfun mp in
+ let lfun',metas1,hyps = intern_match_goal_hyps ist ~as_type lfun rl in
+ let ido,metas2,pat = intern_pattern ist ~as_type lfun mp in
let fold accu x = Id.Set.add x accu in
let ltacvars = List.fold_left fold (opt_cons lfun' ido) metas1 in
let ltacvars = List.fold_left fold ltacvars metas2 in
let ist' = { ist with ltacvars } in
- Pat (hyps,pat,intern_tactic onlytac ist' tc) :: (intern_match_rule onlytac ist tl)
+ Pat (hyps,pat,intern_tactic onlytac ist' tc) :: (intern_match_rule onlytac ist ~as_type tl)
| [] -> []
and intern_genarg ist (GenArg (Rawwit wit, x)) =
@@ -796,7 +782,7 @@ let () =
Genintern.register_intern0 wit_ident intern_ident';
Genintern.register_intern0 wit_var (lift intern_hyp);
Genintern.register_intern0 wit_tactic (lift intern_tactic_or_tacarg);
- Genintern.register_intern0 wit_sort (fun ist s -> (ist, s));
+ Genintern.register_intern0 wit_ltac (lift intern_tactic_or_tacarg);
Genintern.register_intern0 wit_quant_hyp (lift intern_quantified_hypothesis);
Genintern.register_intern0 wit_constr (fun ist c -> (ist,intern_constr ist c));
Genintern.register_intern0 wit_uconstr (fun ist c -> (ist,intern_constr ist c));
@@ -804,7 +790,6 @@ let () =
Genintern.register_intern0 wit_red_expr (lift intern_red_expr);
Genintern.register_intern0 wit_bindings (lift intern_bindings);
Genintern.register_intern0 wit_constr_with_bindings (lift intern_constr_with_bindings);
- Genintern.register_intern0 wit_constr_may_eval (lift intern_constr_may_eval);
()
(***************************************************************************)
diff --git a/tactics/tacintern.mli b/ltac/tacintern.mli
index 71ca354fa..71ca354fa 100644
--- a/tactics/tacintern.mli
+++ b/ltac/tacintern.mli
diff --git a/tactics/tacinterp.ml b/ltac/tacinterp.ml
index 1a8a95158..ab61c8abb 100644
--- a/tactics/tacinterp.ml
+++ b/ltac/tacinterp.ml
@@ -21,7 +21,6 @@ open Libnames
open Globnames
open Nametab
open Pfedit
-open Proof_type
open Refiner
open Tacmach.New
open Tactic_debug
@@ -30,12 +29,11 @@ open Term
open Termops
open Tacexpr
open Genarg
+open Geninterp
open Stdarg
open Constrarg
open Printer
open Pretyping
-module Monad_ = Monad
-open Evd
open Misctypes
open Locus
open Tacintern
@@ -44,26 +42,45 @@ open Sigma.Notations
open Proofview.Notations
open Context.Named.Declaration
+let ltac_trace_info = Tactic_debug.ltac_trace_info
+
let has_type : type a. Val.t -> a typed_abstract_argument_type -> bool = fun v wit ->
let Val.Dyn (t, _) = v in
- match Val.eq t (val_tag wit) with
+ let t' = match val_tag wit with
+ | Val.Base t' -> t'
+ | _ -> assert false (** not used in this module *)
+ in
+ match Val.eq t t' with
| None -> false
| Some Refl -> true
-let prj : type a. a Val.tag -> Val.t -> a option = fun t v ->
+let prj : type a. a Val.typ -> Val.t -> a option = fun t v ->
let Val.Dyn (t', x) = v in
match Val.eq t t' with
| None -> None
| Some Refl -> Some x
-let in_gen wit v = Val.Dyn (val_tag wit, v)
-let out_gen wit v = match prj (val_tag wit) v with None -> assert false | Some x -> x
+let in_list tag v =
+ let tag = match tag with Val.Base tag -> tag | _ -> assert false in
+ Val.Dyn (Val.typ_list, List.map (fun x -> Val.Dyn (tag, x)) v)
+let in_gen wit v =
+ let t = match val_tag wit with
+ | Val.Base t -> t
+ | _ -> assert false (** not used in this module *)
+ in
+ Val.Dyn (t, v)
+let out_gen wit v =
+ let t = match val_tag wit with
+ | Val.Base t -> t
+ | _ -> assert false (** not used in this module *)
+ in
+ match prj t v with None -> assert false | Some x -> x
let val_tag wit = val_tag (topwit wit)
let pr_argument_type arg =
let Val.Dyn (tag, _) = arg in
- Val.repr tag
+ Val.pr tag
let safe_msgnl s =
Proofview.NonLogical.catch
@@ -81,9 +98,9 @@ let push_appl appl args =
match appl with
| UnnamedAppl -> UnnamedAppl
| GlbAppl l -> GlbAppl (List.map (fun (h,vs) -> (h,vs@args)) l)
-let pr_generic arg = (** FIXME *)
+let pr_generic arg =
let Val.Dyn (tag, _) = arg in
- str"<" ++ Val.repr tag ++ str ">"
+ str"<" ++ Val.pr tag ++ str ":(" ++ Pptactic.pr_value Pptactic.ltop arg ++ str ")>"
let pr_appl h vs =
Pptactic.pr_ltac_constant h ++ spc () ++
Pp.prlist_with_sep spc pr_generic vs
@@ -107,7 +124,9 @@ type tacvalue =
| VRec of value Id.Map.t ref * glob_tactic_expr
let (wit_tacvalue : (Empty.t, tacvalue, tacvalue) Genarg.genarg_type) =
- Genarg.create_arg None "tacvalue"
+ let wit = Genarg.create_arg "tacvalue" in
+ let () = register_val0 wit None in
+ wit
let of_tacvalue v = in_gen (topwit wit_tacvalue) v
let to_tacvalue v = out_gen (topwit wit_tacvalue) v
@@ -146,57 +165,41 @@ module Value = struct
of_tacvalue closure
let cast_error wit v =
- let pr_v = mt () in (** FIXME *)
+ let pr_v = Pptactic.pr_value Pptactic.ltop v in
let Val.Dyn (tag, _) = v in
- let tag = Val.repr tag in
+ let tag = Val.pr tag in
errorlabstrm "" (str "Type error: value " ++ pr_v ++ str "is a " ++ tag
- ++ str " while type " ++ Genarg.pr_argument_type (unquote (rawwit wit)) ++ str " was expected.")
+ ++ str " while type " ++ Val.pr wit ++ str " was expected.")
+
+ let unbox wit v ans = match ans with
+ | None -> cast_error wit v
+ | Some x -> x
- let prj : type a. a Val.tag -> Val.t -> a option = fun t v ->
+ let rec prj : type a. a Val.tag -> Val.t -> a = fun tag v -> match tag with
+ | Val.List tag -> List.map (fun v -> prj tag v) (unbox Val.typ_list v (to_list v))
+ | Val.Opt tag -> Option.map (fun v -> prj tag v) (unbox Val.typ_opt v (to_option v))
+ | Val.Pair (tag1, tag2) ->
+ let (x, y) = unbox Val.typ_pair v (to_pair v) in
+ (prj tag1 x, prj tag2 y)
+ | Val.Base t ->
let Val.Dyn (t', x) = v in
match Val.eq t t' with
- | None -> None
- | Some Refl -> Some x
+ | None -> cast_error t v
+ | Some Refl -> x
- let try_prj wit v = match prj (val_tag wit) v with
- | None -> cast_error wit v
- | Some x -> x
+ let rec tag_of_arg : type a b c. (a, b, c) genarg_type -> c Val.tag = fun wit -> match wit with
+ | ExtraArg _ -> val_tag wit
+ | ListArg t -> Val.List (tag_of_arg t)
+ | OptArg t -> Val.Opt (tag_of_arg t)
+ | PairArg (t1, t2) -> Val.Pair (tag_of_arg t1, tag_of_arg t2)
- let rec val_cast : type a b c. (a, b, c) genarg_type -> Val.t -> c =
- fun wit v -> match wit with
- | ExtraArg _ -> try_prj wit v
- | ListArg t ->
- let Val.Dyn (tag, v) = v in
- begin match tag with
- | Val.List tag ->
- let map x = val_cast t (Val.Dyn (tag, x)) in
- List.map map v
- | _ -> cast_error wit (Val.Dyn (tag, v))
- end
- | OptArg t ->
- let Val.Dyn (tag, v) = v in
- begin match tag with
- | Val.Opt tag ->
- let map x = val_cast t (Val.Dyn (tag, x)) in
- Option.map map v
- | _ -> cast_error wit (Val.Dyn (tag, v))
- end
- | PairArg (t1, t2) ->
- let Val.Dyn (tag, v) = v in
- begin match tag with
- | Val.Pair (tag1, tag2) ->
- let (v1, v2) = v in
- let v1 = Val.Dyn (tag1, v1) in
- let v2 = Val.Dyn (tag2, v2) in
- (val_cast t1 v1, val_cast t2 v2)
- | _ -> cast_error wit (Val.Dyn (tag, v))
- end
+ let val_cast arg v = prj (tag_of_arg arg) v
let cast (Topwit wit) v = val_cast wit v
end
-let print_top_val env v = mt () (** FIXME *)
+let print_top_val env v = Pptactic.pr_value Pptactic.ltop v
let dloc = Loc.ghost
@@ -283,9 +286,10 @@ let constr_of_id env id =
(** Generic arguments : table of interpretation functions *)
+(* Some of the code further down depends on the fact that push_trace does not modify sigma (the evar map) *)
let push_trace call ist = match TacStore.get ist.extra f_trace with
-| None -> [call]
-| Some trace -> call :: trace
+| None -> Proofview.tclUNIT [call]
+| Some trace -> Proofview.tclLIFT (Proofview.NonLogical.make Profile_ltac.entered_call) <*> Proofview.tclUNIT (call :: trace)
let propagate_trace ist loc id v =
let v = Value.normalize v in
@@ -294,10 +298,11 @@ let propagate_trace ist loc id v =
match tacv with
| VFun (appl,_,lfun,it,b) ->
let t = if List.is_empty it then b else TacFun (it,b) in
- let ans = VFun (appl,push_trace(loc,LtacVarCall (id,t)) ist,lfun,it,b) in
- of_tacvalue ans
- | _ -> v
- else v
+ push_trace(loc,LtacVarCall (id,t)) ist >>= fun trace ->
+ let ans = VFun (appl,trace,lfun,it,b) in
+ Proofview.tclUNIT (of_tacvalue ans)
+ | _ -> Proofview.tclUNIT v
+ else Proofview.tclUNIT v
let append_trace trace v =
let v = Value.normalize v in
@@ -363,7 +368,7 @@ let debugging_exception_step ist signal_anomaly e pp =
if signal_anomaly then explain_logic_error
else explain_logic_error_no_anomaly in
debugging_step ist (fun () ->
- pp() ++ spc() ++ str "raised the exception" ++ fnl() ++ !explain_exc e)
+ pp() ++ spc() ++ str "raised the exception" ++ fnl() ++ explain_exc e)
let error_ltac_variable loc id env v s =
user_err_loc (loc, "", str "Ltac variable " ++ pr_id id ++
@@ -549,7 +554,7 @@ let interp_fresh_id ist env sigma l =
String.concat "" (List.map (function
| ArgArg s -> s
| ArgVar (_,id) -> Id.to_string (interp_ident ist env sigma id)) l) in
- let s = if Lexer.is_keyword s then s^"0" else s in
+ let s = if CLexer.is_keyword s then s^"0" else s in
Id.of_string s in
Tactics.fresh_id_in_env avoid id env
@@ -619,8 +624,13 @@ let interp_gen kind ist allow_patvar flags env sigma (c,ce) =
match kind with OfType _ -> WithoutTypeConstraint | _ -> kind in
intern_gen kind_for_intern ~allow_patvar ~ltacvars env c
in
- let trace =
- push_trace (loc_of_glob_constr c,LtacConstrInterp (c,vars)) ist in
+ (* Jason Gross: To avoid unnecessary modifications to tacinterp, as
+ suggested by Arnaud Spiwack, we run push_trace immediately. We do
+ this with the kludge of an empty proofview, and rely on the
+ invariant that running the tactic returned by push_trace does
+ not modify sigma. *)
+ let (_, dummy_proofview) = Proofview.init sigma [] in
+ let (trace,_,_,_) = Proofview.apply env (push_trace (loc_of_glob_constr c,LtacConstrInterp (c,vars)) ist) dummy_proofview in
let (evd,c) =
catch_error trace (understand_ltac flags env sigma vars kind) c
in
@@ -676,26 +686,15 @@ let interp_open_constr ?(expected_type=WithoutTypeConstraint) ist =
let interp_pure_open_constr ist =
interp_gen WithoutTypeConstraint ist false pure_open_constr_flags
-let interp_typed_pattern ist env sigma (c,_) =
+let interp_typed_pattern ist env sigma (_,c,_) =
let sigma, c =
interp_gen WithoutTypeConstraint ist true pure_open_constr_flags env sigma c in
pattern_of_constr env sigma c
-(* Interprets a constr expression casted by the current goal *)
-let pf_interp_casted_constr ist gl c =
- interp_constr_gen (OfType (pf_concl gl)) ist (pf_env gl) (project gl) c
-
(* Interprets a constr expression *)
let pf_interp_constr ist gl =
interp_constr ist (pf_env gl) (project gl)
-let new_interp_constr ist c k =
- let open Proofview in
- Proofview.Goal.s_enter { s_enter = begin fun gl ->
- let (sigma, c) = interp_constr ist (Goal.env gl) (project gl) c in
- Sigma.Unsafe.of_pair (k c, sigma)
- end }
-
let interp_constr_in_compound_list inj_fun dest_fun interp_fun ist env sigma l =
let try_expand_ltac_var sigma x =
try match dest_fun x with
@@ -721,24 +720,6 @@ let interp_open_constr_list =
let pf_interp_type ist env sigma =
interp_type ist env sigma
-(* Fully evaluate an untyped constr *)
-let type_uconstr ?(flags = constr_flags)
- ?(expected_type = WithoutTypeConstraint) ist c =
- { delayed = begin fun env sigma ->
- let open Pretyping in
- let { closure; term } = c in
- let vars = {
- ltac_constrs = closure.typed;
- ltac_uconstrs = closure.untyped;
- ltac_idents = closure.idents;
- ltac_genargs = ist.lfun;
- } in
- let sigma = Sigma.to_evar_map sigma in
- let (sigma, c) = understand_ltac flags env sigma vars expected_type term in
- Sigma.Unsafe.of_pair (c, sigma)
- end }
-
-
(* Interprets a reduction expression *)
let interp_unfold ist env sigma (occs,qid) =
(interp_occurrences ist occs,interp_evaluable ist env sigma qid)
@@ -1122,12 +1103,11 @@ let interp_context ctxt = in_gen (topwit wit_constr_context) ctxt
(* Reads a pattern by substituting vars of lfun *)
let use_types = false
-let eval_pattern lfun ist env sigma ((glob,_),pat as c) =
- let bound_names = bound_glob_vars glob in
+let eval_pattern lfun ist env sigma (bvars,(glob,_),pat as c) =
if use_types then
- (bound_names,interp_typed_pattern ist env sigma c)
+ (bvars,interp_typed_pattern ist env sigma c)
else
- (bound_names,instantiate_pattern env sigma lfun pat)
+ (bvars,instantiate_pattern env sigma lfun pat)
let read_pattern lfun ist env sigma = function
| Subterm (b,ido,c) -> Subterm (b,ido,eval_pattern lfun ist env sigma c)
@@ -1161,17 +1141,6 @@ let rec read_match_rule lfun ist env sigma = function
| [] -> []
-(* misc *)
-
-let interp_focussed wit f v =
- Ftactic.nf_enter { enter = begin fun gl ->
- let v = Genarg.out_gen (glbwit wit) v in
- let env = Proofview.Goal.env gl in
- let sigma = Sigma.to_evar_map (Proofview.Goal.sigma gl) in
- let v = in_gen (topwit wit) (f env sigma v) in
- Ftactic.return v
- end }
-
(* Interprets an l-tac expression into a value *)
let rec val_interp ist ?(appl=UnnamedAppl) (tac:glob_tactic_expr) : Val.t Ftactic.t =
(* The name [appl] of applied top-level Ltac names is ignored in
@@ -1200,14 +1169,16 @@ let rec val_interp ist ?(appl=UnnamedAppl) (tac:glob_tactic_expr) : Val.t Ftacti
let ist = { ist with extra = TacStore.set ist.extra f_debug v } in
value_interp ist >>= fun v -> return (name_vfun appl v)
in
- Ftactic.debug_prompt lev tac eval
+ Tactic_debug.debug_prompt lev tac eval
| _ -> value_interp ist >>= fun v -> return (name_vfun appl v)
and eval_tactic ist tac : unit Proofview.tactic = match tac with
| TacAtom (loc,t) ->
let call = LtacAtomCall t in
- catch_error_tac (push_trace(loc,call) ist) (interp_atomic ist t)
+ push_trace(loc,call) ist >>= fun trace ->
+ Profile_ltac.do_profile "eval_tactic:2" trace
+ (catch_error_tac trace (interp_atomic ist t))
| TacFun _ | TacLetIn _ -> assert false
| TacMatchGoal _ | TacMatch _ -> assert false
| TacId [] -> Proofview.tclLIFT (db_breakpoint (curr_debug ist) [])
@@ -1276,7 +1247,7 @@ and eval_tactic ist tac : unit Proofview.tactic = match tac with
| TacComplete tac -> Tacticals.New.tclCOMPLETE (interp_tactic ist tac)
| TacArg a -> interp_tactic ist (TacArg a)
| TacInfo tac ->
- msg_warning
+ Feedback.msg_warning
(strbrk "The general \"info\" tactic is currently not working." ++ spc()++
strbrk "There is an \"Info\" command to replace it." ++fnl () ++
strbrk "Some specific verbose tactics may also exist, such as info_eauto.");
@@ -1289,7 +1260,7 @@ and eval_tactic ist tac : unit Proofview.tactic = match tac with
let tac l =
let addvar x v accu = Id.Map.add x v accu in
let lfun = List.fold_right2 addvar ids l ist.lfun in
- let trace = push_trace (loc,LtacNotationCall s) ist in
+ Ftactic.lift (push_trace (loc,LtacNotationCall s) ist) >>= fun trace ->
let ist = {
lfun = lfun;
extra = TacStore.set ist.extra f_trace trace; } in
@@ -1314,8 +1285,7 @@ and eval_tactic ist tac : unit Proofview.tactic = match tac with
Ftactic.run tac (fun () -> Proofview.tclUNIT ())
| TacML (loc,opn,l) ->
- let open Ftactic.Notations in
- let trace = push_trace (loc,LtacMLCall tac) ist in
+ push_trace (loc,LtacMLCall tac) ist >>= fun trace ->
let ist = { ist with extra = TacStore.set ist.extra f_trace trace; } in
let tac = Tacenv.interp_ml_tactic opn in
let args = Ftactic.List.map_right (fun a -> interp_tacarg ist a) l in
@@ -1341,15 +1311,17 @@ and interp_ltac_reference loc' mustbetac ist r : Val.t Ftactic.t =
try Id.Map.find id ist.lfun
with Not_found -> in_gen (topwit wit_var) id
in
- Ftactic.bind (force_vrec ist v) begin fun v ->
- let v = propagate_trace ist loc id v in
+ let open Ftactic in
+ force_vrec ist v >>= begin fun v ->
+ Ftactic.lift (propagate_trace ist loc id v) >>= fun v ->
if mustbetac then Ftactic.return (coerce_to_tactic loc id v) else Ftactic.return v
end
| ArgArg (loc,r) ->
let ids = extract_ids [] ist.lfun in
let loc_info = ((if Loc.is_ghost loc' then loc else loc'),LtacNameCall r) in
- let extra = TacStore.set ist.extra f_avoid_ids ids in
- let extra = TacStore.set extra f_trace (push_trace loc_info ist) in
+ let extra = TacStore.set ist.extra f_avoid_ids ids in
+ push_trace loc_info ist >>= fun trace ->
+ let extra = TacStore.set extra f_trace trace in
let ist = { lfun = Id.Map.empty; extra = extra; } in
let appl = GlbAppl[r,[]] in
val_interp ~appl ist (Tacenv.interp_ltac r)
@@ -1365,11 +1337,6 @@ and interp_tacarg ist arg : Val.t Ftactic.t =
let (sigma,c_interp) = interp_constr_may_eval ist env sigma c in
Sigma.Unsafe.of_pair (Ftactic.return (Value.of_constr c_interp), sigma)
end }
- | UConstr c ->
- Ftactic.enter { enter = begin fun gl ->
- let env = Proofview.Goal.env gl in
- Ftactic.return (Value.of_uconstr (interp_uconstr ist env c))
- end }
| TacCall (loc,r,[]) ->
interp_ltac_reference loc true ist r
| TacCall (loc,f,l) ->
@@ -1452,7 +1419,7 @@ and tactic_of_value ist vle =
lfun = lfun;
extra = TacStore.set ist.extra f_trace []; } in
let tac = name_if_glob appl (eval_tactic ist t) in
- catch_error_tac trace tac
+ Profile_ltac.do_profile "tactic_of_value" trace (catch_error_tac trace tac)
| (VFun _|VRec _) -> Tacticals.New.tclZEROMSG (str "A fully applied tactic is expected.")
else if has_type vle (topwit wit_tactic) then
let tac = out_gen (topwit wit_tactic) vle in
@@ -1575,30 +1542,23 @@ and interp_genarg ist x : Val.t Ftactic.t =
let GenArg (Glbwit wit, x) = x in
match wit with
| ListArg wit ->
- let map x =
- interp_genarg ist (Genarg.in_gen (glbwit wit) x) >>= fun x ->
- Ftactic.return (Value.cast (topwit wit) x)
- in
+ let map x = interp_genarg ist (Genarg.in_gen (glbwit wit) x) in
Ftactic.List.map map x >>= fun l ->
- Ftactic.return (Value.of_list (val_tag wit) l)
+ Ftactic.return (Val.Dyn (Val.typ_list, l))
| OptArg wit ->
- let ans = match x with
- | None -> Ftactic.return (Value.of_option (val_tag wit) None)
+ begin match x with
+ | None -> Ftactic.return (Val.Dyn (Val.typ_opt, None))
| Some x ->
interp_genarg ist (Genarg.in_gen (glbwit wit) x) >>= fun x ->
- let x = Value.cast (topwit wit) x in
- Ftactic.return (Value.of_option (val_tag wit) (Some x))
- in
- ans
+ Ftactic.return (Val.Dyn (Val.typ_opt, Some x))
+ end
| PairArg (wit1, wit2) ->
let (p, q) = x in
interp_genarg ist (Genarg.in_gen (glbwit wit1) p) >>= fun p ->
interp_genarg ist (Genarg.in_gen (glbwit wit2) q) >>= fun q ->
- let p = Value.cast (topwit wit1) p in
- let q = Value.cast (topwit wit2) q in
- Ftactic.return (Val.Dyn (Val.Pair (val_tag wit1, val_tag wit2), (p, q)))
+ Ftactic.return (Val.Dyn (Val.typ_pair, (p, q)))
| ExtraArg s ->
- Geninterp.generic_interp ist (Genarg.in_gen (glbwit wit) x)
+ Geninterp.interp wit ist x
(** returns [true] for genargs which have the same meaning
independently of goals. *)
@@ -1609,7 +1569,7 @@ and interp_genarg_constr_list ist x =
let sigma = Sigma.to_evar_map (Proofview.Goal.sigma gl) in
let lc = Genarg.out_gen (glbwit (wit_list wit_constr)) x in
let (sigma,lc) = interp_constr_list ist env sigma lc in
- let lc = Value.of_list (val_tag wit_constr) lc in
+ let lc = in_list (val_tag wit_constr) lc in
Sigma.Unsafe.of_pair (Ftactic.return lc, sigma)
end }
@@ -1619,7 +1579,8 @@ and interp_genarg_var_list ist x =
let sigma = Sigma.to_evar_map (Proofview.Goal.sigma gl) in
let lc = Genarg.out_gen (glbwit (wit_list wit_var)) x in
let lc = interp_hyp_list ist env sigma lc in
- Ftactic.return (Value.of_list (val_tag wit_var) lc)
+ let lc = in_list (val_tag wit_var) lc in
+ Ftactic.return lc
end }
(* Interprets tactic expressions : returns a "constr" *)
@@ -1671,7 +1632,7 @@ and name_atomic ?env tacexpr tac : unit Proofview.tactic =
| Some e -> Proofview.tclUNIT e
| None -> Proofview.tclENV
end >>= fun env ->
- let name () = Pptactic.pr_tactic env (TacAtom (Loc.ghost,tacexpr)) in
+ let name () = Pptactic.pr_atomic_tactic env tacexpr in
Proofview.Trace.name_tactic name tac
(* Interprets a primitive tactic *)
@@ -1690,24 +1651,6 @@ and interp_atomic ist tac : unit Proofview.tactic =
expected behaviour. *)
(Tactics.intro_patterns l')) sigma
end }
- | TacIntroMove (ido,hto) ->
- Proofview.Goal.enter { enter = begin fun gl ->
- let env = Proofview.Goal.env gl in
- let sigma = project gl in
- let mloc = interp_move_location ist env sigma hto in
- let ido = Option.map (interp_ident ist env sigma) ido in
- name_atomic ~env
- (TacIntroMove(ido,mloc))
- (Tactics.intro_move ido mloc)
- end }
- | TacExact c ->
- (* spiwack: until the tactic is in the monad *)
- Proofview.Trace.name_tactic (fun () -> Pp.str"<exact>") begin
- Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
- let (sigma, c_interp) = pf_interp_casted_constr ist gl c in
- Sigma.Unsafe.of_pair (Proofview.V82.tactic (Tactics.exact_no_check c_interp), sigma)
- end }
- end
| TacApply (a,ev,cb,cl) ->
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"<apply>") begin
@@ -1760,7 +1703,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
let (sigma,l_interp) =
Evd.MonadR.List.map_right (fun c sigma -> f sigma c) l (project gl)
in
- let tac = Proofview.V82.tactic (Tactics.mutual_fix (interp_ident ist env sigma id) n l_interp 0) in
+ let tac = Tactics.mutual_fix (interp_ident ist env sigma id) n l_interp 0 in
Sigma.Unsafe.of_pair (tac, sigma)
end }
end
@@ -1775,7 +1718,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
let (sigma,l_interp) =
Evd.MonadR.List.map_right (fun c sigma -> f sigma c) l (project gl)
in
- let tac = Proofview.V82.tactic (Tactics.mutual_cofix (interp_ident ist env sigma id) l_interp 0) in
+ let tac = Tactics.mutual_cofix (interp_ident ist env sigma id) l_interp 0 in
Sigma.Unsafe.of_pair (tac, sigma)
end }
end
@@ -1790,7 +1733,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
let tac = Option.map (interp_tactic ist) t in
Tacticals.New.tclWITHHOLES false
(name_atomic ~env
- (TacAssert(b,t,ipat,c))
+ (TacAssert(b,Option.map ignore t,ipat,c))
(Tactics.forward b tac ipat' c)) sigma
end }
| TacGeneralize cl ->
@@ -1801,7 +1744,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
Tacticals.New.tclWITHHOLES false
(name_atomic ~env
(TacGeneralize cl)
- (Proofview.V82.tactic (Tactics.generalize_gen cl))) sigma
+ (Tactics.generalize_gen cl)) sigma
end }
| TacLetTac (na,c,clp,b,eqpat) ->
Proofview.V82.nf_evar_goals <*>
@@ -1868,26 +1811,6 @@ and interp_atomic ist tac : unit Proofview.tactic =
in
Sigma.Unsafe.of_pair (tac, sigma)
end }
- | TacDoubleInduction (h1,h2) ->
- let h1 = interp_quantified_hypothesis ist h1 in
- let h2 = interp_quantified_hypothesis ist h2 in
- name_atomic
- (TacDoubleInduction (h1,h2))
- (Elim.h_double_induction h1 h2)
- (* Context management *)
- | TacRename l ->
- Proofview.Goal.enter { enter = begin fun gl ->
- let env = pf_env gl in
- let sigma = project gl in
- let l =
- List.map (fun (id1,id2) ->
- interp_hyp ist env sigma id1,
- interp_ident ist env sigma (snd id2)) l
- in
- name_atomic ~env
- (TacRename l)
- (Tactics.rename_hyp l)
- end }
(* Conversion *)
| TacReduce (r,cl) ->
@@ -1925,7 +1848,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
in
Sigma.Unsafe.of_pair (c, sigma)
end } in
- Proofview.V82.tactic (Tactics.change None c_interp (interp_clause ist (pf_env gl) (project gl) cl))
+ Tactics.change None c_interp (interp_clause ist (pf_env gl) (project gl) cl)
end }
end
| TacChange (Some op,c,cl) ->
@@ -1935,25 +1858,22 @@ and interp_atomic ist tac : unit Proofview.tactic =
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = project gl in
- Proofview.V82.tactic begin fun gl ->
- let op = interp_typed_pattern ist env sigma op in
- let to_catch = function Not_found -> true | e -> Errors.is_anomaly e in
- let c_interp patvars = { Sigma.run = begin fun sigma ->
- let lfun' = Id.Map.fold (fun id c lfun ->
- Id.Map.add id (Value.of_constr c) lfun)
- patvars ist.lfun
- in
- let ist = { ist with lfun = lfun' } in
- try
- let sigma = Sigma.to_evar_map sigma in
- let (sigma, c) = interp_constr ist env sigma c in
- Sigma.Unsafe.of_pair (c, sigma)
- with e when to_catch e (* Hack *) ->
- errorlabstrm "" (strbrk "Failed to get enough information from the left-hand side to type the right-hand side.")
- end } in
- (Tactics.change (Some op) c_interp (interp_clause ist env sigma cl))
- gl
- end
+ let op = interp_typed_pattern ist env sigma op in
+ let to_catch = function Not_found -> true | e -> Errors.is_anomaly e in
+ let c_interp patvars = { Sigma.run = begin fun sigma ->
+ let lfun' = Id.Map.fold (fun id c lfun ->
+ Id.Map.add id (Value.of_constr c) lfun)
+ patvars ist.lfun
+ in
+ let ist = { ist with lfun = lfun' } in
+ try
+ let sigma = Sigma.to_evar_map sigma in
+ let (sigma, c) = interp_constr ist env sigma c in
+ Sigma.Unsafe.of_pair (c, sigma)
+ with e when to_catch e (* Hack *) ->
+ errorlabstrm "" (strbrk "Failed to get enough information from the left-hand side to type the right-hand side.")
+ end } in
+ Tactics.change (Some op) c_interp (interp_clause ist env sigma cl)
end }
end
@@ -1972,7 +1892,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
let sigma = project gl in
let cl = interp_clause ist env sigma cl in
name_atomic ~env
- (TacRewrite (ev,l,cl,by))
+ (TacRewrite (ev,l,cl,Option.map ignore by))
(Equality.general_multi_rewrite ev l' cl
(Option.map (fun by -> Tacticals.New.tclCOMPLETE (interp_tactic ist by),
Equality.Naive)
@@ -2077,6 +1997,13 @@ let hide_interp global t ot =
(***************************************************************************)
(** Register standard arguments *)
+let register_interp0 wit f =
+ let open Ftactic.Notations in
+ let interp ist v =
+ f ist v >>= fun v -> Ftactic.return (Val.inject (val_tag wit) v)
+ in
+ Geninterp.register_interp0 wit interp
+
let def_intern ist x = (ist, x)
let def_subst _ x = x
let def_interp ist x = Ftactic.return x
@@ -2084,7 +2011,7 @@ let def_interp ist x = Ftactic.return x
let declare_uniform t =
Genintern.register_intern0 t def_intern;
Genintern.register_subst0 t def_subst;
- Geninterp.register_interp0 t def_interp
+ register_interp0 t def_interp
let () =
declare_uniform wit_unit
@@ -2125,29 +2052,31 @@ let interp_constr_with_bindings' ist c = Ftactic.return { delayed = fun env sigm
}
let () =
- Geninterp.register_interp0 wit_int_or_var (fun ist n -> Ftactic.return (interp_int_or_var ist n));
- Geninterp.register_interp0 wit_ref (lift interp_reference);
- Geninterp.register_interp0 wit_ident (lift interp_ident);
- Geninterp.register_interp0 wit_var (lift interp_hyp);
- Geninterp.register_interp0 wit_intro_pattern (lifts interp_intro_pattern);
- Geninterp.register_interp0 wit_clause_dft_concl (lift interp_clause);
- Geninterp.register_interp0 wit_constr (lifts interp_constr);
- Geninterp.register_interp0 wit_sort (lifts (fun _ _ evd s -> interp_sort evd s));
- Geninterp.register_interp0 wit_tacvalue (fun ist v -> Ftactic.return v);
- Geninterp.register_interp0 wit_red_expr (lifts interp_red_expr);
- Geninterp.register_interp0 wit_quant_hyp (lift interp_declared_or_quantified_hypothesis);
- Geninterp.register_interp0 wit_open_constr (lifts interp_open_constr);
- Geninterp.register_interp0 wit_bindings interp_bindings';
- Geninterp.register_interp0 wit_constr_with_bindings interp_constr_with_bindings';
- Geninterp.register_interp0 wit_constr_may_eval (lifts interp_constr_may_eval);
+ register_interp0 wit_int_or_var (fun ist n -> Ftactic.return (interp_int_or_var ist n));
+ register_interp0 wit_ref (lift interp_reference);
+ register_interp0 wit_ident (lift interp_ident);
+ register_interp0 wit_var (lift interp_hyp);
+ register_interp0 wit_intro_pattern (lifts interp_intro_pattern);
+ register_interp0 wit_clause_dft_concl (lift interp_clause);
+ register_interp0 wit_constr (lifts interp_constr);
+ register_interp0 wit_tacvalue (fun ist v -> Ftactic.return v);
+ register_interp0 wit_red_expr (lifts interp_red_expr);
+ register_interp0 wit_quant_hyp (lift interp_declared_or_quantified_hypothesis);
+ register_interp0 wit_open_constr (lifts interp_open_constr);
+ register_interp0 wit_bindings interp_bindings';
+ register_interp0 wit_constr_with_bindings interp_constr_with_bindings';
()
let () =
let interp ist tac = Ftactic.return (Value.of_closure ist tac) in
- Geninterp.register_interp0 wit_tactic interp
+ register_interp0 wit_tactic interp
let () =
- Geninterp.register_interp0 wit_uconstr (fun ist c -> Ftactic.nf_enter { enter = begin fun gl ->
+ let interp ist tac = interp_tactic ist tac >>= fun () -> Ftactic.return () in
+ register_interp0 wit_ltac interp
+
+let () =
+ register_interp0 wit_uconstr (fun ist c -> Ftactic.nf_enter { enter = begin fun gl ->
Ftactic.return (interp_uconstr ist (Proofview.Goal.env gl) c)
end })
@@ -2178,12 +2107,6 @@ let _ =
in
Hook.set Pretyping.genarg_interp_hook eval
-let _ = Hook.set Auto.extern_interp
- (fun l ->
- let lfun = Id.Map.map (fun c -> Value.of_constr c) l in
- let ist = { (default_ist ()) with lfun; } in
- interp_tactic ist)
-
(** Used in tactic extension **)
let dummy_id = Id.of_string "_"
@@ -2204,3 +2127,28 @@ let lift_constr_tac_to_ml_tac vars tac =
tac args ist
end } in
tac
+
+let vernac_debug b =
+ set_debug (if b then Tactic_debug.DebugOn 0 else Tactic_debug.DebugOff)
+
+let _ =
+ let open Goptions in
+ declare_bool_option
+ { optsync = false;
+ optdepr = false;
+ optname = "Ltac debug";
+ optkey = ["Ltac";"Debug"];
+ optread = (fun () -> get_debug () != Tactic_debug.DebugOff);
+ optwrite = vernac_debug }
+
+let _ =
+ let open Goptions in
+ declare_bool_option
+ { optsync = false;
+ optdepr = false;
+ optname = "Ltac debug";
+ optkey = ["Debug";"Ltac"];
+ optread = (fun () -> get_debug () != Tactic_debug.DebugOff);
+ optwrite = vernac_debug }
+
+let () = Hook.set Vernacentries.interp_redexp_hook interp_redexp
diff --git a/tactics/tacinterp.mli b/ltac/tacinterp.mli
index c5da3494c..6f64981ef 100644
--- a/tactics/tacinterp.mli
+++ b/ltac/tacinterp.mli
@@ -14,16 +14,18 @@ open Genarg
open Redexpr
open Misctypes
+val ltac_trace_info : ltac_trace Exninfo.t
+
module Value :
sig
- type t = Val.t
+ type t = Geninterp.Val.t
val of_constr : constr -> t
val to_constr : t -> constr option
val of_int : int -> t
val to_int : t -> int option
val to_list : t -> t list option
val of_closure : Geninterp.interp_sign -> glob_tactic_expr -> t
- val cast : 'a typed_abstract_argument_type -> Val.t -> 'a
+ val cast : 'a typed_abstract_argument_type -> Geninterp.Val.t -> 'a
end
(** Values for interpretation *)
@@ -62,11 +64,6 @@ val val_interp : interp_sign -> glob_tactic_expr -> (value -> unit Proofview.tac
(** Interprets an expression that evaluates to a constr *)
val interp_ltac_constr : interp_sign -> glob_tactic_expr -> (constr -> unit Proofview.tactic) -> unit Proofview.tactic
-val type_uconstr :
- ?flags:Pretyping.inference_flags ->
- ?expected_type:Pretyping.typing_constraint ->
- interp_sign -> Glob_term.closed_glob_constr -> constr delayed_open
-
(** Interprets redexp arguments *)
val interp_redexp : Environ.env -> Evd.evar_map -> raw_red_expr -> Evd.evar_map * red_expr
@@ -75,6 +72,9 @@ val interp_redexp : Environ.env -> Evd.evar_map -> raw_red_expr -> Evd.evar_map
val interp_hyp : interp_sign -> Environ.env -> Evd.evar_map ->
Id.t Loc.located -> Id.t
+val interp_constr_gen : Pretyping.typing_constraint -> interp_sign ->
+ Environ.env -> Evd.evar_map -> glob_constr_and_expr -> Evd.evar_map * constr
+
val interp_bindings : interp_sign -> Environ.env -> Evd.evar_map ->
glob_constr_and_expr bindings -> Evd.evar_map * constr bindings
diff --git a/tactics/tacsubst.ml b/ltac/tacsubst.ml
index 3f103a290..2c3c76ef7 100644
--- a/tactics/tacsubst.ml
+++ b/ltac/tacsubst.ml
@@ -16,7 +16,6 @@ open Globnames
open Term
open Genredexpr
open Patternops
-open Pretyping
(** Substitution of tactics at module closing time *)
@@ -94,7 +93,7 @@ let subst_global_reference subst =
let subst_global ref =
let ref',t' = subst_global subst ref in
if not (eq_constr (Universes.constr_of_global ref') t') then
- msg_warning (strbrk "The reference " ++ pr_global ref ++ str " is not " ++
+ Feedback.msg_warning (strbrk "The reference " ++ pr_global ref ++ str " is not " ++
str " expanded to \"" ++ pr_lconstr t' ++ str "\", but to " ++
pr_global ref') ;
ref'
@@ -107,8 +106,8 @@ let subst_evaluable subst =
let subst_constr_with_occurrences subst (l,c) = (l,subst_glob_constr subst c)
-let subst_glob_constr_or_pattern subst (c,p) =
- (subst_glob_constr subst c,subst_pattern subst p)
+let subst_glob_constr_or_pattern subst (bvars,c,p) =
+ (bvars,subst_glob_constr subst c,subst_pattern subst p)
let subst_redexp subst =
Miscops.map_red_expr_gen
@@ -138,8 +137,6 @@ let rec subst_match_goal_hyps subst = function
let rec subst_atomic subst (t:glob_atomic_tactic_expr) = match t with
(* Basic tactics *)
| TacIntroPattern l -> TacIntroPattern (List.map (subst_intro_pattern subst) l)
- | TacIntroMove _ as x -> x
- | TacExact c -> TacExact (subst_glob_constr subst c)
| TacApply (a,ev,cb,cl) ->
TacApply (a,ev,List.map (subst_glob_with_bindings_arg subst) cb,cl)
| TacElim (ev,cb,cbo) ->
@@ -163,10 +160,6 @@ let rec subst_atomic subst (t:glob_atomic_tactic_expr) = match t with
subst_induction_arg subst c, ids, cls) l in
let el' = Option.map (subst_glob_with_bindings subst) el in
TacInductionDestruct (isrec,ev,(l',el'))
- | TacDoubleInduction (h1,h2) as x -> x
-
- (* Context management *)
- | TacRename l as x -> x
(* Conversion *)
| TacReduce (r,cl) -> TacReduce (subst_redexp subst r, cl)
@@ -247,7 +240,6 @@ and subst_tactic_fun subst (var,body) = (var,subst_tactic subst body)
and subst_tacarg subst = function
| Reference r -> Reference (subst_reference subst r)
| ConstrMayEval c -> ConstrMayEval (subst_raw_may_eval subst c)
- | UConstr c -> UConstr (subst_glob_constr subst c)
| TacCall (_loc,f,l) ->
TacCall (_loc, subst_reference subst f, List.map (subst_tacarg subst) l)
| TacFreshId _ as x -> x
@@ -300,8 +292,8 @@ let () =
Genintern.register_subst0 wit_var (fun _ v -> v);
Genintern.register_subst0 wit_intro_pattern (fun _ v -> v);
Genintern.register_subst0 wit_tactic subst_tactic;
+ Genintern.register_subst0 wit_ltac subst_tactic;
Genintern.register_subst0 wit_constr subst_glob_constr;
- Genintern.register_subst0 wit_sort (fun _ v -> v);
Genintern.register_subst0 wit_clause_dft_concl (fun _ v -> v);
Genintern.register_subst0 wit_uconstr (fun subst c -> subst_glob_constr subst c);
Genintern.register_subst0 wit_open_constr (fun subst c -> subst_glob_constr subst c);
@@ -309,5 +301,4 @@ let () =
Genintern.register_subst0 wit_quant_hyp subst_declared_or_quantified_hypothesis;
Genintern.register_subst0 wit_bindings subst_bindings;
Genintern.register_subst0 wit_constr_with_bindings subst_glob_with_bindings;
- Genintern.register_subst0 wit_constr_may_eval subst_raw_may_eval;
()
diff --git a/tactics/tacsubst.mli b/ltac/tacsubst.mli
index c1bf27257..c1bf27257 100644
--- a/tactics/tacsubst.mli
+++ b/ltac/tacsubst.mli
diff --git a/proofs/tactic_debug.ml b/ltac/tactic_debug.ml
index d33278ff8..e657eb9bc 100644
--- a/proofs/tactic_debug.ml
+++ b/ltac/tactic_debug.ml
@@ -14,10 +14,16 @@ open Termops
open Nameops
open Proofview.Notations
-let (prtac, tactic_printer) = Hook.make ()
-let (prmatchpatt, match_pattern_printer) = Hook.make ()
-let (prmatchrl, match_rule_printer) = Hook.make ()
+let (ltac_trace_info : ltac_trace Exninfo.t) = Exninfo.make ()
+
+let prtac x =
+ Pptactic.pr_glob_tactic (Global.env()) x
+let prmatchpatt env sigma hyp =
+ Pptactic.pr_match_pattern (Printer.pr_constr_pattern_env env sigma) hyp
+let prmatchrl rl =
+ Pptactic.pr_match_rule false (Pptactic.pr_glob_tactic (Global.env()))
+ (fun (_,p) -> Printer.pr_constr_pattern p) rl
(* This module intends to be a beginning of debugger for tactic expressions.
Currently, it is quite simple and we can hope to have, in the future, a more
@@ -29,9 +35,11 @@ type debug_info =
| DebugOff
(* An exception handler *)
-let explain_logic_error = ref (fun e -> mt())
+let explain_logic_error e =
+ Errors.print (fst (Cerrors.process_vernac_interp_error (e, Exninfo.null)))
-let explain_logic_error_no_anomaly = ref (fun e -> mt())
+let explain_logic_error_no_anomaly e =
+ Errors.print_no_report (fst (Cerrors.process_vernac_interp_error (e, Exninfo.null)))
let msg_tac_debug s = Proofview.NonLogical.print_debug (s++fnl())
let msg_tac_notice s = Proofview.NonLogical.print_notice (s++fnl())
@@ -67,7 +75,7 @@ let help () =
let goal_com tac =
Proofview.tclTHEN
db_pr_goal
- (Proofview.tclLIFT (msg_tac_debug (str "Going to execute:" ++ fnl () ++ Hook.get prtac tac)))
+ (Proofview.tclLIFT (msg_tac_debug (str "Going to execute:" ++ fnl () ++ prtac tac)))
(* [run (new_ref _)] gives us a ref shared among [NonLogical.t]
expressions. It avoids parametrizing everything over a
@@ -197,7 +205,7 @@ let debug_prompt lev tac f =
(Proofview.tclLIFT begin
(skip:=0) >> (skipped:=0) >>
if Logic.catchable_exception reraise then
- msg_tac_debug (str "Level " ++ int lev ++ str ": " ++ Pervasives.(!) explain_logic_error reraise)
+ msg_tac_debug (str "Level " ++ int lev ++ str ": " ++ explain_logic_error reraise)
else return ()
end)
(Proofview.tclZERO ~info reraise)
@@ -228,7 +236,7 @@ let db_pattern_rule debug num r =
if db then
begin
msg_tac_debug (str "Pattern rule " ++ int num ++ str ":" ++ fnl () ++
- str "|" ++ spc () ++ Hook.get prmatchrl r)
+ str "|" ++ spc () ++ prmatchrl r)
end
else return ()
@@ -270,7 +278,7 @@ let db_hyp_pattern_failure debug env sigma (na,hyp) =
if db then
msg_tac_debug (str "The pattern hypothesis" ++ hyp_bound na ++
str " cannot match: " ++
- Hook.get prmatchpatt env sigma hyp)
+ prmatchpatt env sigma hyp)
else return ()
(* Prints a matching failure message for a rule *)
@@ -299,7 +307,7 @@ let db_logic_failure debug err =
is_debug debug >>= fun db ->
if db then
begin
- msg_tac_debug (Pervasives.(!) explain_logic_error err) >>
+ msg_tac_debug (explain_logic_error err) >>
msg_tac_debug (str "This rule has failed due to a logic error!" ++ fnl() ++
str "Let us try the next one...")
end
@@ -317,3 +325,91 @@ let db_breakpoint debug s =
breakpoint:=None
| _ ->
return ()
+
+(** Extrating traces *)
+
+let is_defined_ltac trace =
+ let rec aux = function
+ | (_, Tacexpr.LtacNameCall f) :: _ -> not (Tacenv.is_ltac_for_ml_tactic f)
+ | (_, Tacexpr.LtacNotationCall f) :: _ -> true
+ | (_, Tacexpr.LtacAtomCall _) :: _ -> false
+ | _ :: tail -> aux tail
+ | [] -> false in
+ aux (List.rev trace)
+
+let explain_ltac_call_trace last trace loc =
+ let calls = last :: List.rev_map snd trace in
+ let pr_call ck = match ck with
+ | Tacexpr.LtacNotationCall kn -> quote (Pptactic.pr_alias_key kn)
+ | Tacexpr.LtacNameCall cst -> quote (Pptactic.pr_ltac_constant cst)
+ | Tacexpr.LtacMLCall t ->
+ quote (Pptactic.pr_glob_tactic (Global.env()) t)
+ | Tacexpr.LtacVarCall (id,t) ->
+ quote (Nameops.pr_id id) ++ strbrk " (bound to " ++
+ Pptactic.pr_glob_tactic (Global.env()) t ++ str ")"
+ | Tacexpr.LtacAtomCall te ->
+ quote (Pptactic.pr_glob_tactic (Global.env())
+ (Tacexpr.TacAtom (Loc.ghost,te)))
+ | Tacexpr.LtacConstrInterp (c, { Pretyping.ltac_constrs = vars }) ->
+ quote (Printer.pr_glob_constr_env (Global.env()) c) ++
+ (if not (Id.Map.is_empty vars) then
+ strbrk " (with " ++
+ prlist_with_sep pr_comma
+ (fun (id,c) ->
+ pr_id id ++ str ":=" ++ Printer.pr_lconstr_under_binders c)
+ (List.rev (Id.Map.bindings vars)) ++ str ")"
+ else mt())
+ in
+ match calls with
+ | [] -> mt ()
+ | [a] -> hov 0 (str "Ltac call to " ++ pr_call a ++ str " failed.")
+ | _ ->
+ let kind_of_last_call = match List.last calls with
+ | Tacexpr.LtacConstrInterp _ -> ", last term evaluation failed."
+ | _ -> ", last call failed."
+ in
+ hov 0 (str "In nested Ltac calls to " ++
+ pr_enum pr_call calls ++ strbrk kind_of_last_call)
+
+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 _) :: _ ->
+ (* Case of an ML defined tactic with entry of the form <<"foo" args>> *)
+ (* see tacextend.mlp *)
+ [tac]
+ | (_,Tacexpr.LtacMLCall _ as tac) :: _ -> [tac]
+ | t :: tail -> t :: aux tail
+ | [] -> [] in
+ List.rev (aux (List.rev trace))
+
+let extract_ltac_trace trace eloc =
+ let trace = skip_extensions trace in
+ let (loc,c),tail = List.sep_last trace in
+ if is_defined_ltac trace then
+ (* 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 eloc ++ fnl()) in
+ Some msg, loc
+ else
+ (* We entered a primitive tactic, we don't display trace but
+ report on the finest location *)
+ let best_loc =
+ if not (Loc.is_ghost eloc) then eloc else
+ (* trace is with innermost call coming first *)
+ let rec aux = function
+ | (loc,_)::tail when not (Loc.is_ghost loc) -> loc
+ | _::tail -> aux tail
+ | [] -> Loc.ghost in
+ aux trace in
+ None, best_loc
+
+let get_ltac_trace (_, info) =
+ let ltac_trace = Exninfo.get info ltac_trace_info in
+ let loc = Option.default Loc.ghost (Loc.get_loc info) in
+ match ltac_trace with
+ | None -> None
+ | Some trace -> Some (extract_ltac_trace trace loc)
+
+let () = Cerrors.register_additional_error_info get_ltac_trace
diff --git a/proofs/tactic_debug.mli b/ltac/tactic_debug.mli
index 215c5b29b..520fb41ef 100644
--- a/proofs/tactic_debug.mli
+++ b/ltac/tactic_debug.mli
@@ -13,16 +13,14 @@ open Tacexpr
open Term
open Evd
+(** TODO: Move those definitions somewhere sensible *)
+
+val ltac_trace_info : ltac_trace Exninfo.t
+
(** This module intends to be a beginning of debugger for tactic expressions.
Currently, it is quite simple and we can hope to have, in the future, a more
complete panel of commands dedicated to a proof assistant framework *)
-val tactic_printer : (glob_tactic_expr -> Pp.std_ppcmds) Hook.t
-val match_pattern_printer :
- (env -> evar_map -> constr_pattern match_pattern -> Pp.std_ppcmds) Hook.t
-val match_rule_printer :
- ((Tacexpr.glob_constr_and_expr * constr_pattern,glob_tactic_expr) match_rule -> Pp.std_ppcmds) Hook.t
-
(** Debug information *)
type debug_info =
| DebugOn of int
@@ -63,13 +61,13 @@ val db_matching_failure : debug_info -> unit Proofview.NonLogical.t
val db_eval_failure : debug_info -> Pp.std_ppcmds -> unit Proofview.NonLogical.t
(** An exception handler *)
-val explain_logic_error: (exn -> Pp.std_ppcmds) ref
+val explain_logic_error: exn -> Pp.std_ppcmds
(** For use in the Ltac debugger: some exception that are usually
consider anomalies are acceptable because they are caught later in
the process that is being debugged. One should not require
from users that they report these anomalies. *)
-val explain_logic_error_no_anomaly : (exn -> Pp.std_ppcmds) ref
+val explain_logic_error_no_anomaly : exn -> Pp.std_ppcmds
(** Prints a logic failure message for a rule *)
val db_logic_failure : debug_info -> exn -> unit Proofview.NonLogical.t
@@ -77,3 +75,6 @@ val db_logic_failure : debug_info -> exn -> unit Proofview.NonLogical.t
(** Prints a logic failure message for a rule *)
val db_breakpoint : debug_info ->
Id.t Loc.located message_token list -> unit Proofview.NonLogical.t
+
+val extract_ltac_trace :
+ Tacexpr.ltac_trace -> Loc.t -> Pp.std_ppcmds option * Loc.t
diff --git a/tactics/tactic_option.ml b/ltac/tactic_option.ml
index a5ba3b837..a5ba3b837 100644
--- a/tactics/tactic_option.ml
+++ b/ltac/tactic_option.ml
diff --git a/tactics/tactic_option.mli b/ltac/tactic_option.mli
index ed759a76d..ed759a76d 100644
--- a/tactics/tactic_option.mli
+++ b/ltac/tactic_option.mli
diff --git a/tactics/tauto.ml b/ltac/tauto.ml
index 67ef25d49..c0cae84c0 100644
--- a/tactics/tauto.ml
+++ b/ltac/tauto.ml
@@ -6,22 +6,16 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i camlp4deps: "grammar/grammar.cma" i*)
-
open Term
open Hipattern
open Names
open Pp
-open Genarg
-open Stdarg
+open Geninterp
open Misctypes
open Tacexpr
open Tacinterp
-open Tactics
-open Errors
open Util
open Tacticals.New
-open Proofview.Notations
let tauto_plugin = "tauto"
let () = Mltop.add_known_module tauto_plugin
@@ -56,12 +50,13 @@ type tauto_flags = {
strict_unit : bool;
}
-let wit_tauto_flags : tauto_flags uniform_genarg_type =
- Genarg.create_arg None "tauto_flags"
+let tag_tauto_flags : tauto_flags Val.typ = Val.create "tauto_flags"
-let assoc_flags ist =
- let v = Id.Map.find (Names.Id.of_string "tauto_flags") ist.lfun in
- try Value.cast (topwit wit_tauto_flags) v with _ -> assert false
+let assoc_flags ist : tauto_flags =
+ let Val.Dyn (tag, v) = Id.Map.find (Names.Id.of_string "tauto_flags") ist.lfun in
+ match Val.eq tag tag_tauto_flags with
+ | None -> assert false
+ | Some Refl -> v
(* Whether inner not are unfolded *)
let negation_unfolding = ref true
@@ -107,7 +102,7 @@ let assert_ ?by c =
let apply c = Tactics.apply c
-let clear id = Proofview.V82.tactic (fun gl -> Tactics.clear [id] gl)
+let clear id = Tactics.clear [id]
let assumption = Tactics.assumption
@@ -258,7 +253,7 @@ let tauto_power_flags = {
let with_flags flags _ ist =
let f = (loc, Id.of_string "f") in
let x = (loc, Id.of_string "x") in
- let arg = Val.Dyn (val_tag (topwit wit_tauto_flags), flags) in
+ let arg = Val.Dyn (tag_tauto_flags, flags) in
let ist = { ist with lfun = Id.Map.add (snd x) arg ist.lfun } in
eval_tactic_ist ist (TacArg (loc, TacCall (loc, ArgVar f, [Reference (ArgVar x)])))
diff --git a/tactics/tauto.mli b/ltac/tauto.mli
index e69de29bb..e69de29bb 100644
--- a/tactics/tauto.mli
+++ b/ltac/tauto.mli
diff --git a/myocamlbuild.ml b/myocamlbuild.ml
deleted file mode 100644
index 73ef7e1ed..000000000
--- a/myocamlbuild.ml
+++ /dev/null
@@ -1,483 +0,0 @@
-(** * Plugin for building Coq via Ocamlbuild *)
-
-open Ocamlbuild_plugin
-open Ocamlbuild_pack
-open Printf
-open Scanf
-
-(** WARNING !! this is preliminary stuff. It should allows you to
- build coq and its libraries if everything goes right.
- Support for all the build rules and configuration options
- is progressively added. Tested only on linux + ocaml 3.11 +
- local + natdynlink for now.
-
- Usage:
- ./configure -local -opt
- ./build (which launches ocamlbuild coq.otarget)
-
- Then you can (hopefully) launch bin/coqtop, bin/coqide and so on.
- Apart from the links in bin, every created files are in _build.
- A "./build clean" should give you back a clean source tree
-
-*)
-
-(** F.A.Q about ocamlbuild:
-
-* P / Px ?
-
- Same, except that the second can be use to signal the main target
- of a rule, in order to get a nicer log (otherwise the full command
- is used as target name)
-
-*)
-
-
-
-(** Generic file reader, which produces a list of strings, one per line *)
-
-let read_file f =
- let ic = open_in f and l = ref [] in
- (try while true do l := (input_line ic)::!l done with End_of_file -> ());
- close_in ic; List.rev !l
-
-
-(** Configuration *)
-
-(** First, we access coq_config.ml indirectly : we symlink it to
- myocamlbuild_config.ml, which is linked with this myocamlbuild.ml *)
-
-module Coq_config = struct include Myocamlbuild_config end
-
-let _ = begin
- Options.ocamlc := A Coq_config.ocamlc;
- Options.ocamlopt := A Coq_config.ocamlopt;
- Options.ocamlmklib := A Coq_config.ocamlmklib;
- Options.ocamldep := A Coq_config.ocamldep;
- Options.ocamldoc := A Coq_config.ocamldoc;
- Options.ocamlyacc := A Coq_config.ocamlyacc;
- Options.ocamllex := A Coq_config.ocamllex;
-end
-
-let w32 = Coq_config.arch_is_win32
-
-let w32pref = "i586-mingw32msvc"
-let w32ocamlc = w32pref^"-ocamlc"
-let w32ocamlopt = w32pref^"-ocamlopt"
-let w32ocamlmklib = w32pref^"-ocamlmklib"
-let w32res = w32pref^"-windres"
-let w32lib = "/usr/"^w32pref^"/lib/"
-let w32bin = "/usr/"^w32pref^"/bin/"
-let w32ico = "ide/coq_icon.o"
-
-let _ = if w32 then begin
- Options.ocamlopt := A w32ocamlopt;
- Options.ocamlmklib := A w32ocamlmklib;
-end
-
-let use_camlp5 = (Coq_config.camlp4 = "camlp5")
-
-let camlp4args =
- if use_camlp5 then [A "pa_extend.cmo";A "q_MLast.cmo";A "pa_macro.cmo"]
- else []
-
-let ocaml = A Coq_config.ocaml
-let camlp4o = S ((A Coq_config.camlp4o) :: camlp4args)
-let camlp4incl = S[A"-I"; A Coq_config.camlp4lib]
-let camlp4compat = Sh Coq_config.camlp4compat
-let opt = (Coq_config.best = "opt")
-let ide = Coq_config.has_coqide
-let hasdynlink = Coq_config.has_natdynlink
-let os5fix = (Coq_config.natdynlinkflag = "os5fixme")
-let dep_dynlink = if hasdynlink then N else Sh"-natdynlink no"
-let lablgtkincl = Sh Coq_config.coqideincl
-let local = Coq_config.local
-let cflags = S[A"-ccopt";A Coq_config.cflags]
-
-(** Do we want to inspect .ml generated from .ml4 ? *)
-let readable_genml = false
-let readable_flag = if readable_genml then A"pr_o.cmo" else N
-
-let _build = Options.build_dir
-
-
-(** Abbreviations about files *)
-
-let core_libs =
- ["lib/clib"; "lib/lib"; "kernel/kernel"; "library/library";
- "engine/engine"; "pretyping/pretyping"; "interp/interp"; "proofs/proofs";
- "parsing/parsing"; "printing/printing"; "tactics/tactics";
- "stm/stm"; "toplevel/toplevel"; "parsing/highparsing";
- "tactics/hightactics"]
-let core_cma = List.map (fun s -> s^".cma") core_libs
-let core_cmxa = List.map (fun s -> s^".cmxa") core_libs
-let core_mllib = List.map (fun s -> s^".mllib") core_libs
-
-let tolink = "tools/tolink.ml"
-
-let c_headers_base =
- ["coq_fix_code.h";"coq_instruct.h"; "coq_memory.h"; "int64_emul.h";
- "coq_gc.h"; "coq_interp.h"; "coq_values.h"; "int64_native.h";
- "coq_jumptbl.h"]
-let c_headers = List.map ((^) "kernel/byterun/") c_headers_base
-
-let coqinstrs = "kernel/byterun/coq_instruct.h"
-let coqjumps = "kernel/byterun/coq_jumptbl.h"
-let copcodes = "kernel/copcodes.ml"
-
-let libcoqrun = "kernel/byterun/libcoqrun.a"
-
-let init_vo = "theories/Init/Prelude.vo"
-
-let nmake = "theories/Numbers/Natural/BigN/NMake_gen.v"
-let nmakegen = "theories/Numbers/Natural/BigN/NMake_gen.ml"
-
-let adapt_name (pref,oldsuf,newsuf) f =
- pref ^ (Filename.chop_suffix f oldsuf) ^ newsuf
-
-let get_names (oldsuf,newsuf) s =
- let pref = Filename.dirname s ^ "/" in
- List.map (adapt_name (pref,oldsuf,newsuf)) (string_list_of_file s)
-
-let get_vo_itargets f =
- let vo_itargets = get_names (".otarget",".itarget") f in
- List.flatten (List.map (get_names (".vo",".v")) vo_itargets)
-
-let theoriesv = get_vo_itargets "theories/theories.itarget"
-
-let pluginsv = get_vo_itargets "plugins/pluginsvo.itarget"
-
-let pluginsmllib = get_names (".cma",".mllib") "plugins/pluginsbyte.itarget"
-
-(** for correct execution of coqdep_boot, source files should have
- been imported in _build (and NMake_gen.v should have been created). *)
-
-let coqdepdeps = theoriesv @ pluginsv @ pluginsmllib
-
-let coqtop = "toplevel/coqtop"
-let coqide = "ide/coqide"
-let coqdepboot = "tools/coqdep_boot"
-let coqmktop = "tools/coqmktop"
-
-(** The list of binaries to build:
- (name of link in bin/, name in _build, install both or only best) *)
-
-type links = Both | Best | BestInPlace | Ide
-
-let all_binaries =
- (if w32 then [ "mkwinapp", "tools/mkwinapp", Best ] else []) @
- [ "coqtop", coqtop, Both;
- "coqide", "ide/coqide_main", Ide;
- "coqmktop", coqmktop, Both;
- "coqc", "tools/coqc", Both;
- "coqchk", "checker/main", Both;
- "coqdep_boot", coqdepboot, Best;
- "coqdep", "tools/coqdep", Best;
- "coqdoc", "tools/coqdoc/main", Best;
- "coqwc", "tools/coqwc", Best;
- "coq_makefile", "tools/coq_makefile", Best;
- "coq-tex", "tools/coq_tex", Best;
- "gallina", "tools/gallina", Best;
- "csdpcert", "plugins/micromega/csdpcert", BestInPlace;
- "fake_ide", "tools/fake_ide", Best;
- ]
-
-
-let best_oext = if opt then ".native" else ".byte"
-let best_ext = if opt then ".opt" else ".byte"
-let best_iext = if ide = "opt" then ".opt" else ".byte"
-
-let coqtopbest = coqtop^best_oext
-(* For inner needs, we rather use the bytecode versions of coqdep
- and coqmktop: slightly slower but compile quickly, and ok with
- w32 cross-compilation *)
-let coqdep_boot = coqdepboot^".byte"
-let coqmktop_boot = coqmktop^".byte"
-
-let binariesopt_deps =
- let addext b = b ^ ".native" in
- let rec deps = function
- | [] -> []
- | (_,b,Ide)::l -> if ide="opt" then addext b :: deps l else deps l
- | (_,b,_)::l -> if opt then addext b :: deps l else deps l
- in deps all_binaries
-
-let binariesbyte_deps =
- let addext b = b ^ ".byte" in
- let rec deps = function
- | [] -> []
- | (_,b,Ide)::l -> if ide<>"no" then addext b :: deps l else deps l
- | (_,b,Both)::l -> addext b :: deps l
- | (_,b,_)::l -> if not opt then addext b :: deps l else deps l
- in deps all_binaries
-
-let ln_sf toward f =
- Command.execute ~quiet:true (Cmd (S [A"ln";A"-sf";P toward;P f]))
-
-let rec make_bin_links = function
- | [] -> ()
- | (b,ob,kind)::l ->
- make_bin_links l;
- let obd = "../"^ !_build^"/"^ob and bd = "bin/"^b in
- match kind with
- | Ide when ide <> "no" ->
- ln_sf (obd^".byte") (bd^".byte");
- if ide = "opt" then ln_sf (obd^".native") (bd^".opt");
- ln_sf (b^best_iext) bd
- | Ide (* when ide = "no" *) -> ()
- | Both ->
- ln_sf (obd^".byte") (bd^".byte");
- if opt then ln_sf (obd^".native") (bd^".opt");
- ln_sf (b^best_ext) bd
- | Best -> ln_sf (obd^best_oext) bd
- | BestInPlace -> ln_sf (b^best_oext) (!_build^"/"^ob)
-
-let incl f = Ocaml_utils.ocaml_include_flags f
-
-let cmd cl = (fun _ _ -> (Cmd (S cl)))
-
-let initial_actions () = begin
- (** We "pre-create" a few subdirs in _build *)
- Shell.mkdir_p (!_build^"/dev");
- Shell.mkdir_p (!_build^"/bin");
- Shell.mkdir_p (!_build^"/plugins/micromega");
- make_bin_links all_binaries;
-end
-
-let extra_rules () = begin
-
-(** Virtual target for building all binaries *)
-
- rule "binariesopt" ~stamp:"binariesopt" ~deps:binariesopt_deps (fun _ _ -> Nop);
- rule "binariesbyte" ~stamp:"binariesbyte" ~deps:binariesbyte_deps (fun _ _ -> Nop);
- rule "binaries" ~stamp:"binaries" ~deps:["binariesbyte";"binariesopt"] (fun _ _ -> Nop);
-
-(** We create a special coq_config which mentions _build *)
-
- rule "coq_config.ml" ~prod:"coq_config.ml" ~dep:"config/coq_config.ml"
- (fun _ _ ->
- if w32 then cp "config/coq_config.ml" "coq_config.ml" else
- let lines = read_file "config/coq_config.ml" in
- let lines = List.map (fun s -> s^"\n") lines in
- let line0 = "\n(* Adapted variables for ocamlbuild *)\n" in
- (* TODO : line2 isn't completely accurate with respect to ./configure:
- the case of -local -vmbyteflags foo isn't supported *)
- let line1 =
- "let vmbyteflags = [\"-dllib\";\"-lcoqrun\"]\n"
- in
- Echo (lines @ (if local then [line0;line1] else []),
- "coq_config.ml"));
-
-(** Camlp4 extensions *)
-
- rule ".ml4.ml" ~dep:"%.ml4" ~prod:"%.ml"
- (fun env _ ->
- let ml4 = env "%.ml4" and ml = env "%.ml" in
- Cmd (S[camlp4o;T(tags_of_pathname ml4 ++ "p4mod");readable_flag;
- T(tags_of_pathname ml4 ++ "p4option"); camlp4compat;
- A"-o"; Px ml; A"-impl"; P ml4]));
-
- flag_and_dep ["p4mod"; "use_grammar"] (P "grammar/grammar.cma");
- flag_and_dep ["p4mod"; "use_constr"] (P "grammar/q_constr.cmo");
-
- flag_and_dep ["p4mod"; "use_compat5"] (P "tools/compat5.cmo");
- flag_and_dep ["p4mod"; "use_compat5b"] (P "tools/compat5b.cmo");
-
- if w32 then begin
- flag ["p4mod"] (A "-DWIN32");
- dep ["ocaml"; "link"; "ide"] ["ide/ide_win32_stubs.o"];
- end;
-
- if not use_camlp5 then begin
- let mlp_cmo s =
- let src=s^".mlp" and dst=s^".cmo" in
- rule (src^".cmo") ~dep:src ~prod:dst ~insert:`top
- (fun env _ ->
- Cmd (S [!Options.ocamlc; A"-c"; A"-pp";
- Quote (S [camlp4o;A"-impl"]); camlp4incl; A"-impl"; P src]))
- in
- mlp_cmo "tools/compat5";
- mlp_cmo "tools/compat5b";
- end;
-
-(** All caml files are compiled with +camlp4/5
- and ide files need +lablgtk2 *)
-
- flag ["compile"; "ocaml"] (S [A"-thread";A"-rectypes"; camlp4incl]);
- flag ["link"; "ocaml"] (S [A"-rectypes"; camlp4incl]);
- flag ["ocaml"; "ide"; "compile"] lablgtkincl;
- flag ["ocaml"; "ide"; "link"] lablgtkincl;
- flag ["ocaml"; "ide"; "link"; "byte"]
- (S [A"lablgtk.cma"; A"lablgtksourceview2.cma"]);
- flag ["ocaml"; "ide"; "link"; "native"]
- (S [A"lablgtk.cmxa"; A"lablgtksourceview2.cmxa"]);
-
-(** C code for the VM *)
-
- dep ["compile"; "c"] c_headers;
- flag ["compile"; "c"] cflags;
- dep ["ocaml"; "use_libcoqrun"; "compile"] [libcoqrun];
- dep ["ocaml"; "use_libcoqrun"; "link"; "native"] [libcoqrun];
- flag ["ocaml"; "use_libcoqrun"; "link"; "byte"] (Sh Coq_config.vmbyteflags);
-
- (* we need to use a different ocamlc. For now we copy the rule *)
- if w32 then
- rule ".c.o" ~deps:("%.c"::c_headers) ~prod:"%.o" ~insert:`top
- (fun env _ ->
- let c = env "%.c" in
- let o = env "%.o" in
- Seq [Cmd (S [P w32ocamlc;cflags;A"-c";Px c]);
- mv (Filename.basename o) o]);
-
-(** VM: Generation of coq_jumbtbl.h and copcodes.ml from coq_instruct.h *)
-
- rule "coqinstrs" ~dep:coqinstrs ~prods:[coqjumps;copcodes]
- (fun _ _ ->
- let jmps = ref [] and ops = ref [] and i = ref 0 in
- let add_instr instr comma =
- if instr = "" then failwith "Empty" else begin
- jmps:=sprintf "&&coq_lbl_%s%s \n" instr comma :: !jmps;
- ops:=sprintf "let op%s = %d\n" instr !i :: !ops;
- incr i
- end
- in
- (** we recognize comma-separated uppercase instruction names *)
- let parse_line s =
- let b = Scanning.from_string s in
- try while true do bscanf b " %[A-Z0-9_]%[,]" add_instr done
- with _ -> ()
- in
- List.iter parse_line (read_file coqinstrs);
- Seq [Echo (List.rev !jmps, coqjumps);
- Echo (List.rev !ops, copcodes)]);
-
-(** Generation of tolink.ml *)
-
- rule tolink ~deps:core_mllib ~prod:tolink
- (fun _ _ ->
- let cat s = String.concat " " (string_list_of_file s) in
- let core_mods = String.concat " " (List.map cat core_mllib) in
- let core_cmas = String.concat " " core_cma in
- Echo (["let copts = \"-cclib -lcoqrun\"\n";
- "let core_libs = \""^core_cmas^"\"\n";
- "let core_objs = \""^core_mods^"\"\n"],
- tolink));
-
-(** For windows, building coff object file from a .rc (for the icon) *)
-
- if w32 then rule ".rc.o" ~deps:["%.rc";"ide/coq.ico"] ~prod:"%.o"
- (fun env _ ->
- let rc = env "%.rc" and o = env "%.o" in
- Cmd (S [P w32res;A "--input-format";A "rc";A "--input";P rc;
- A "--output-format";A "coff";A "--output"; Px o]));
-
-(** The windows version of Coqide is now a console-free win32 app,
- which moreover contains the Coq icon. If necessary, the mkwinapp
- tool can be used later to restore or suppress the console of Coqide. *)
-
- if w32 then dep ["link"; "ocaml"; "program"; "ide"] [w32ico];
-
- if w32 then flag ["link"; "ocaml"; "program"; "ide"]
- (S [A "-ccopt"; A "-link -Wl,-subsystem,windows"; P w32ico]);
-
-(** Coqtop *)
-
- let () =
- let fo = coqtop^".native" and fb = coqtop^".byte" in
- let depsall = (if w32 then [w32ico] else [])@[coqmktop_boot;libcoqrun] in
- let depso = core_cmxa in
- let depsb = core_cma in
- let w32flag =
- if not w32 then N else S ([A"-camlbin";A w32bin;A "-ccopt";P w32ico])
- in
- if opt then rule fo ~prod:fo ~deps:(depsall@depso) ~insert:`top
- (cmd [P coqmktop_boot;w32flag;A"-boot";A"-opt";incl fo;A"-thread";camlp4incl;A"-o";Px fo]);
- rule fb ~prod:fb ~deps:(depsall@depsb) ~insert:`top
- (cmd [P coqmktop_boot;w32flag;A"-boot";A"-top";incl fb;A"-thread";camlp4incl;A"-o";Px fb]);
- in
-
-(** Coq files dependencies *)
-
- rule "coqdepready" ~stamp:"coqdepready" ~deps:coqdepdeps (fun _ _ -> Nop);
-
- rule ".v.d" ~prod:"%.v.depends" ~deps:["%.v";coqdep_boot;"coqdepready"]
- (fun env _ ->
- let v = env "%.v" and vd = env "%.v.depends" in
- (** NB: this relies on all .v files being already in _build. *)
- Cmd (S [P coqdep_boot;dep_dynlink;P v;Sh">";Px vd]));
-
-(** Coq files compilation *)
-
- let coq_build_dep f build =
- (** NB: this relies on coqdep producing a single Makefile line
- for one .v file, with some specific shape "f.vo ...: f.v deps.vo ..." *)
- let src = f^".v" in
- let depends = f^".v.depends" in
- let rec get_deps keep = function
- | [] -> []
- | d::deps when d = src -> get_deps keep deps
- | d::deps when keep -> [d] :: get_deps keep deps
- | d::deps -> get_deps (String.contains d ':') deps
- in
- let d = get_deps false (string_list_of_file depends) in
- List.iter Outcome.ignore_good (build d)
-
- in
-
- let coq_v_rule d init =
- let bootflag = if init then A"-noinit" else N in
- let gendep = if init then coqtopbest else init_vo in
- rule (d^".v.vo")
- ~prods:[d^"%.vo";d^"%.glob"] ~deps:[gendep;d^"%.v";d^"%.v.depends"]
- (fun env build ->
- let f = env (d^"%") in
- coq_build_dep f build;
- Cmd (S [P coqtopbest;A"-boot";bootflag;A"-compile";Px f]))
- in
- coq_v_rule "theories/Init/" true;
- coq_v_rule "" false;
-
-(** Generation of _plugin_mod.ml files *)
-
- rule "_mod.ml" ~prod:"%_plugin_mod.ml" ~dep:"%_plugin.mllib"
- (fun env _ ->
- let line s = "let _ = Mltop.add_known_module \""^s^"\"\n" in
- let mods =
- string_list_of_file (env "%_plugin.mllib") @
- [Filename.basename (env "%_plugin")]
- in
- Echo (List.map line mods, env "%_plugin_mod.ml"));
-
-(** Rule for native dynlinkable plugins *)
-
- rule ".cmxa.cmxs" ~prod:"%.cmxs" ~dep:"%.cmxa"
- (fun env _ ->
- let cmxs = Px (env "%.cmxs") and cmxa = P (env "%.cmxa") in
- if os5fix then
- Cmd (S [A"../dev/ocamlopt_shared_os5fix.sh"; !Options.ocamlopt; cmxs])
- else
- Cmd (S [!Options.ocamlopt;A"-linkall";A"-shared";A"-o";cmxs;cmxa]));
-
-(** Generation of NMake.v from NMake_gen.ml *)
-
- rule "NMake" ~prod:nmake ~dep:nmakegen
- (cmd [ocaml;P nmakegen;Sh ">";Px nmake]);
-
-end
-
-(** Registration of our rules (after the standard ones) *)
-
-let _ = dispatch begin function
- | After_rules -> initial_actions (); extra_rules ()
- | _ -> ()
-end
-
-(** TODO / Remarques:
-
- * Apres un premier build, le second prend du temps, meme cached:
- 1 min 25 pour les 2662 targets en cache. Etonnement, refaire
- coqtop.byte ne prend que ~4s, au lieu des ~40s pour coqtop.opt.
- A comprendre ...
-
- * Parallelisation: vraiment pas top
-
-*)
diff --git a/parsing/lexer.ml4 b/parsing/cLexer.ml4
index 232e9aee3..9a7aeaf0c 100644
--- a/parsing/lexer.ml4
+++ b/parsing/cLexer.ml4
@@ -199,7 +199,7 @@ let check_keyword str =
let check_keyword_to_add s =
try check_keyword s
with Error.E (UnsupportedUnicode unicode) ->
- Flags.if_verbose msg_warning
+ Flags.if_verbose Feedback.msg_warning
(strbrk (Printf.sprintf "Token '%s' contains unicode character 0x%x \
which will not be parsable." s unicode))
@@ -322,7 +322,7 @@ let rec string in_comments bp len = parser
| [< '')'; s >] ->
let () = match in_comments with
| Some 0 ->
- msg_warning
+ Feedback.msg_warning
(strbrk
"Not interpreting \"*)\" as the end of current \
non-terminated comment because it occurs in a \
@@ -389,9 +389,10 @@ let comment_stop ep =
let bp = match !comment_begin with
Some bp -> bp
| None ->
- msgerrnl(str "No begin location for comment '"
- ++ str current_s ++str"' ending at "
- ++ int ep);
+ Feedback.msg_notice
+ (str "No begin location for comment '"
+ ++ str current_s ++str"' ending at "
+ ++ int ep);
ep-1 in
Pp.comments := ((bp,ep),current_s) :: !Pp.comments);
Buffer.clear current;
@@ -724,7 +725,7 @@ let strip s =
let terminal s =
let s = strip s in
- let () = match s with "" -> Errors.error "empty token." | _ -> () in
+ let () = match s with "" -> failwith "empty token." | _ -> () in
if is_ident_not_keyword s then IDENT s
else if is_number s then INT s
else KEYWORD s
diff --git a/parsing/lexer.mli b/parsing/cLexer.mli
index 24b0ec847..24b0ec847 100644
--- a/parsing/lexer.mli
+++ b/parsing/cLexer.mli
diff --git a/parsing/compat.ml4 b/parsing/compat.ml4
index 0e416fe32..2b67693d2 100644
--- a/parsing/compat.ml4
+++ b/parsing/compat.ml4
@@ -21,17 +21,11 @@ end
exception Exc_located = Ploc.Exc
IFDEF CAMLP5_6_00 THEN
-let ploc_make_loc fname lnb pos bpep = Ploc.make_loc fname lnb pos bpep ""
let ploc_file_name = Ploc.file_name
ELSE
-let ploc_make_loc fname lnb pos bpep = Ploc.make lnb pos bpep
let ploc_file_name _ = ""
END
-let of_coqloc loc =
- let (fname, lnb, pos, bp, ep) = Loc.represent loc in
- ploc_make_loc fname lnb pos (bp,ep)
-
let to_coqloc loc =
Loc.create (ploc_file_name loc) (Ploc.line_nb loc)
(Ploc.bol_pos loc) (Ploc.first_pos loc, Ploc.last_pos loc)
@@ -44,10 +38,6 @@ module CompatLoc = Camlp4.PreCast.Loc
exception Exc_located = CompatLoc.Exc_located
-let of_coqloc loc =
- let (fname, lnb, pos, bp, ep) = Loc.represent loc in
- CompatLoc.of_tuple (fname, 0, 0, bp, 0, 0, ep, false)
-
let to_coqloc loc =
Loc.create (CompatLoc.file_name loc) (CompatLoc.start_line loc)
(CompatLoc.start_bol loc) (CompatLoc.start_off loc, CompatLoc.stop_off loc)
@@ -65,6 +55,7 @@ IFDEF CAMLP5 THEN
module PcamlSig = struct end
module Token = Token
+module CompatGramext = struct include Gramext type assoc = g_assoc end
ELSE
@@ -73,69 +64,11 @@ module Ast = Camlp4.PreCast.Ast
module Pcaml = Camlp4.PreCast.Syntax
module MLast = Ast
module Token = struct exception Error of string end
+module CompatGramext = Camlp4.Sig.Grammar
END
-
-(** Grammar auxiliary types *)
-
-IFDEF CAMLP5 THEN
-
-let to_coq_assoc = function
-| Gramext.RightA -> Extend.RightA
-| Gramext.LeftA -> Extend.LeftA
-| Gramext.NonA -> Extend.NonA
-
-let of_coq_assoc = function
-| Extend.RightA -> Gramext.RightA
-| Extend.LeftA -> Gramext.LeftA
-| Extend.NonA -> Gramext.NonA
-
-let of_coq_position = function
-| Extend.First -> Gramext.First
-| Extend.Last -> Gramext.Last
-| Extend.Before s -> Gramext.Before s
-| Extend.After s -> Gramext.After s
-| Extend.Level s -> Gramext.Level s
-
-let to_coq_position = function
-| Gramext.First -> Extend.First
-| Gramext.Last -> Extend.Last
-| Gramext.Before s -> Extend.Before s
-| Gramext.After s -> Extend.After s
-| Gramext.Level s -> Extend.Level s
-| Gramext.Like _ -> assert false (** dont use it, not in camlp4 *)
-
-ELSE
-
-let to_coq_assoc = function
-| PcamlSig.Grammar.RightA -> Extend.RightA
-| PcamlSig.Grammar.LeftA -> Extend.LeftA
-| PcamlSig.Grammar.NonA -> Extend.NonA
-
-let of_coq_assoc = function
-| Extend.RightA -> PcamlSig.Grammar.RightA
-| Extend.LeftA -> PcamlSig.Grammar.LeftA
-| Extend.NonA -> PcamlSig.Grammar.NonA
-
-let of_coq_position = function
-| Extend.First -> PcamlSig.Grammar.First
-| Extend.Last -> PcamlSig.Grammar.Last
-| Extend.Before s -> PcamlSig.Grammar.Before s
-| Extend.After s -> PcamlSig.Grammar.After s
-| Extend.Level s -> PcamlSig.Grammar.Level s
-
-let to_coq_position = function
-| PcamlSig.Grammar.First -> Extend.First
-| PcamlSig.Grammar.Last -> Extend.Last
-| PcamlSig.Grammar.Before s -> Extend.Before s
-| PcamlSig.Grammar.After s -> Extend.After s
-| PcamlSig.Grammar.Level s -> Extend.Level s
-
-END
-
-
-(** Signature of Lexer *)
+(** Signature of CLexer *)
IFDEF CAMLP5 THEN
@@ -193,7 +126,11 @@ module GrammarMake (L:LexerSig) : GrammarSig = struct
let entry_create = Entry.create
let entry_parse e p =
try Entry.parse e p
- with Exc_located (loc,e) -> Loc.raise (to_coqloc loc) e
+ with Exc_located (loc,e) ->
+ let loc' = Loc.get_loc (Exninfo.info e) in
+ let loc = match loc' with None -> to_coqloc loc | Some loc -> loc in
+ Loc.raise loc e
+
IFDEF CAMLP5_6_02_1 THEN
let entry_print ft x = Entry.print ft x
ELSE
@@ -276,7 +213,7 @@ ELSE
module Gramext = G
let stoken tok = match tok with
| Tok.KEYWORD s -> Gramext.Skeyword s
- | tok -> Gramext.Stoken ((=) tok, G.Token.to_string tok)
+ | tok -> Gramext.Stoken (Tok.equal tok, G.Token.to_string tok)
END
IFDEF CAMLP5_6_00 THEN
@@ -366,27 +303,6 @@ let make_fun loc cl =
END
-(** Explicit antiquotation $anti:... $ *)
-
-IFDEF CAMLP5 THEN
-let expl_anti loc e = <:expr< $anti:e$ >>
-ELSE
-let expl_anti _loc e = e (* FIXME: understand someday if we can do better *)
-END
-
-(** Qualified names in OCaml *)
-
-IFDEF CAMLP5 THEN
-let qualified_name loc path name =
- let fold dir accu = <:expr< $uid:dir$.$accu$ >> in
- List.fold_right fold path <:expr< $lid:name$ >>
-ELSE
-let qualified_name loc path name =
- let fold dir accu = Ast.IdAcc (loc, Ast.IdUid (loc, dir), accu) in
- let path = List.fold_right fold path (Ast.IdLid (loc, name)) in
- Ast.ExId (loc, path)
-END
-
IFDEF CAMLP5 THEN
let warning_verbose = Gramext.warning_verbose
ELSE
diff --git a/parsing/egramcoq.ml b/parsing/egramcoq.ml
index 465073b7a..21a9afa29 100644
--- a/parsing/egramcoq.ml
+++ b/parsing/egramcoq.ml
@@ -6,7 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Compat
open Errors
open Util
open Pcoq
@@ -14,9 +13,137 @@ open Extend
open Constrexpr
open Notation_term
open Libnames
-open Tacexpr
open Names
-open Egramml
+
+(**********************************************************************)
+(* This determines (depending on the associativity of the current
+ level and on the expected associativity) if a reference to constr_n is
+ a reference to the current level (to be translated into "SELF" on the
+ left border and into "constr LEVEL n" elsewhere), to the level below
+ (to be translated into "NEXT") or to an below wrt associativity (to be
+ translated in camlp4 into "constr" without level) or to another level
+ (to be translated into "constr LEVEL n")
+
+ The boolean is true if the entry was existing _and_ empty; this to
+ circumvent a weakness of camlp4/camlp5 whose undo mechanism is not the
+ converse of the extension mechanism *)
+
+let constr_level = string_of_int
+
+let default_levels =
+ [200,Extend.RightA,false;
+ 100,Extend.RightA,false;
+ 99,Extend.RightA,true;
+ 10,Extend.RightA,false;
+ 9,Extend.RightA,false;
+ 8,Extend.RightA,true;
+ 1,Extend.LeftA,false;
+ 0,Extend.RightA,false]
+
+let default_pattern_levels =
+ [200,Extend.RightA,true;
+ 100,Extend.RightA,false;
+ 99,Extend.RightA,true;
+ 11,Extend.LeftA,false;
+ 10,Extend.RightA,false;
+ 1,Extend.LeftA,false;
+ 0,Extend.RightA,false]
+
+let default_constr_levels = (default_levels, default_pattern_levels)
+
+(* At a same level, LeftA takes precedence over RightA and NoneA *)
+(* In case, several associativity exists for a level, we make two levels, *)
+(* first LeftA, then RightA and NoneA together *)
+
+let admissible_assoc = function
+ | Extend.LeftA, Some (Extend.RightA | Extend.NonA) -> false
+ | Extend.RightA, Some Extend.LeftA -> false
+ | _ -> true
+
+let create_assoc = function
+ | None -> Extend.RightA
+ | Some a -> a
+
+let error_level_assoc p current expected =
+ let open Pp in
+ let pr_assoc = function
+ | Extend.LeftA -> str "left"
+ | Extend.RightA -> str "right"
+ | Extend.NonA -> str "non" in
+ errorlabstrm ""
+ (str "Level " ++ int p ++ str " is already declared " ++
+ pr_assoc current ++ str " associative while it is now expected to be " ++
+ pr_assoc expected ++ str " associative.")
+
+let create_pos = function
+ | None -> Extend.First
+ | Some lev -> Extend.After (constr_level lev)
+
+type gram_level =
+ gram_position option * gram_assoc option * string option *
+ (** for reinitialization: *) gram_reinit option
+
+let find_position_gen current ensure assoc lev =
+ match lev with
+ | None ->
+ current, (None, None, None, None)
+ | Some n ->
+ let after = ref None in
+ let init = ref None in
+ let rec add_level q = function
+ | (p,_,_ as pa)::l when p > n -> pa :: add_level (Some p) l
+ | (p,a,reinit)::l when Int.equal p n ->
+ if reinit then
+ let a' = create_assoc assoc in
+ (init := Some (a',create_pos q); (p,a',false)::l)
+ else if admissible_assoc (a,assoc) then
+ raise Exit
+ else
+ error_level_assoc p a (Option.get assoc)
+ | l -> after := q; (n,create_assoc assoc,ensure)::l
+ in
+ try
+ let updated = add_level None current in
+ let assoc = create_assoc assoc in
+ begin match !init with
+ | None ->
+ (* Create the entry *)
+ updated, (Some (create_pos !after), Some assoc, Some (constr_level n), None)
+ | _ ->
+ (* The reinit flag has been updated *)
+ updated, (Some (Extend.Level (constr_level n)), None, None, !init)
+ end
+ with
+ (* Nothing has changed *)
+ Exit ->
+ (* Just inherit the existing associativity and name (None) *)
+ current, (Some (Extend.Level (constr_level n)), None, None, None)
+
+let rec list_mem_assoc_triple x = function
+ | [] -> false
+ | (a,b,c) :: l -> Int.equal a x || list_mem_assoc_triple x l
+
+let register_empty_levels accu forpat levels =
+ let rec filter accu = function
+ | [] -> ([], accu)
+ | n :: rem ->
+ let rem, accu = filter accu rem in
+ let (clev, plev) = accu in
+ let levels = if forpat then plev else clev in
+ if not (list_mem_assoc_triple n levels) then
+ let nlev, ans = find_position_gen levels true None (Some n) in
+ let nlev = if forpat then (clev, nlev) else (nlev, plev) in
+ ans :: rem, nlev
+ else rem, accu
+ in
+ filter accu levels
+
+let find_position accu forpat assoc level =
+ let (clev, plev) = accu in
+ let levels = if forpat then plev else clev in
+ let nlev, ans = find_position_gen levels false assoc level in
+ let nlev = if forpat then (clev, nlev) else (nlev, plev) in
+ (ans, nlev)
(**************************************************************************)
(*
@@ -45,6 +172,146 @@ open Egramml
(**********************************************************************)
(** Declare Notations grammar rules *)
+(**********************************************************************)
+(* Binding constr entry keys to entries *)
+
+(* Camlp4 levels do not treat NonA: use RightA with a NEXT on the left *)
+let camlp4_assoc = function
+ | Some NonA | Some RightA -> RightA
+ | None | Some LeftA -> LeftA
+
+let assoc_eq al ar = match al, ar with
+| NonA, NonA
+| RightA, RightA
+| LeftA, LeftA -> true
+| _, _ -> false
+
+(* [adjust_level assoc from prod] where [assoc] and [from] are the name
+ and associativity of the level where to add the rule; the meaning of
+ the result is
+
+ None = SELF
+ Some None = NEXT
+ Some (Some (n,cur)) = constr LEVEL n
+ s.t. if [cur] is set then [n] is the same as the [from] level *)
+let adjust_level assoc from = function
+(* Associativity is None means force the level *)
+ | (NumLevel n,BorderProd (_,None)) -> Some (Some (n,true))
+(* Compute production name on the right side *)
+ (* If NonA or LeftA on the right-hand side, set to NEXT *)
+ | (NumLevel n,BorderProd (Right,Some (NonA|LeftA))) ->
+ Some None
+ (* If RightA on the right-hand side, set to the explicit (current) level *)
+ | (NumLevel n,BorderProd (Right,Some RightA)) ->
+ Some (Some (n,true))
+(* Compute production name on the left side *)
+ (* If NonA on the left-hand side, adopt the current assoc ?? *)
+ | (NumLevel n,BorderProd (Left,Some NonA)) -> None
+ (* If the expected assoc is the current one, set to SELF *)
+ | (NumLevel n,BorderProd (Left,Some a)) when assoc_eq a (camlp4_assoc assoc) ->
+ None
+ (* Otherwise, force the level, n or n-1, according to expected assoc *)
+ | (NumLevel n,BorderProd (Left,Some a)) ->
+ begin match a with
+ | LeftA -> Some (Some (n, true))
+ | _ -> Some None
+ end
+ (* None means NEXT *)
+ | (NextLevel,_) -> Some None
+(* Compute production name elsewhere *)
+ | (NumLevel n,InternalProd) ->
+ if from = n + 1 then Some None else Some (Some (n, Int.equal n from))
+
+type _ target =
+| ForConstr : constr_expr target
+| ForPattern : cases_pattern_expr target
+
+type prod_info = production_level * production_position
+
+type (_, _) entry =
+| TTName : ('self, Name.t Loc.located) entry
+| TTReference : ('self, reference) entry
+| TTBigint : ('self, Bigint.bigint) entry
+| TTBinder : ('self, local_binder list) entry
+| TTConstr : prod_info * 'r target -> ('r, 'r) entry
+| TTConstrList : prod_info * Tok.t list * 'r target -> ('r, 'r list) entry
+| TTBinderListT : ('self, local_binder list) entry
+| TTBinderListF : Tok.t list -> ('self, local_binder list list) entry
+
+type _ any_entry = TTAny : ('s, 'r) entry -> 's any_entry
+
+(* This computes the name of the level where to add a new rule *)
+let interp_constr_entry_key : type r. r target -> int -> r Gram.entry * int option =
+ fun forpat level -> match forpat with
+ | ForConstr ->
+ if level = 200 then Constr.binder_constr, None
+ else Constr.operconstr, Some level
+ | ForPattern -> Constr.pattern, Some level
+
+let target_entry : type s. s target -> s Gram.entry = function
+| ForConstr -> Constr.operconstr
+| ForPattern -> Constr.pattern
+
+let is_self from e = match e with
+| (NumLevel n, BorderProd (Right, _ (* Some(NonA|LeftA) *))) -> false
+| (NumLevel n, BorderProd (Left, _)) -> Int.equal from n
+| _ -> false
+
+let is_binder_level from e = match e with
+| (NumLevel 200, (BorderProd (Right, _) | InternalProd)) -> from = 200
+| _ -> false
+
+let make_sep_rules tkl =
+ let rec mkrule : Tok.t list -> unit rules = function
+ | [] -> Rules ({ norec_rule = Stop }, ignore)
+ | tkn :: rem ->
+ let Rules ({ norec_rule = r }, f) = mkrule rem in
+ let r = { norec_rule = Next (r, Atoken tkn) } in
+ Rules (r, fun _ -> f)
+ in
+ let r = mkrule (List.rev tkl) in
+ Arules [r]
+
+let symbol_of_target : type s. _ -> _ -> _ -> s target -> (s, s) symbol = fun p assoc from forpat ->
+ if is_binder_level from p then Aentryl (target_entry forpat, 200)
+ else if is_self from p then Aself
+ else
+ let g = target_entry forpat in
+ let lev = adjust_level assoc from p in
+ begin match lev with
+ | None -> Aentry g
+ | Some None -> Anext
+ | Some (Some (lev, cur)) -> Aentryl (g, lev)
+ end
+
+let symbol_of_entry : type s r. _ -> _ -> (s, r) entry -> (s, r) symbol = fun assoc from typ -> match typ with
+| TTConstr (p, forpat) -> symbol_of_target p assoc from forpat
+| TTConstrList (typ', [], forpat) ->
+ Alist1 (symbol_of_target typ' assoc from forpat)
+| TTConstrList (typ', tkl, forpat) ->
+ Alist1sep (symbol_of_target typ' assoc from forpat, make_sep_rules tkl)
+| TTBinderListF [] -> Alist1 (Aentry Constr.binder)
+| TTBinderListF tkl -> Alist1sep (Aentry Constr.binder, make_sep_rules tkl)
+| TTName -> Aentry Prim.name
+| TTBinder -> Aentry Constr.binder
+| TTBinderListT -> Aentry Constr.open_binders
+| TTBigint -> Aentry Prim.bigint
+| TTReference -> Aentry Constr.global
+
+let interp_entry forpat e = match e with
+| ETName -> TTAny TTName
+| ETReference -> TTAny TTReference
+| ETBigint -> TTAny TTBigint
+| ETBinder true -> anomaly (Pp.str "Should occur only as part of BinderList")
+| ETBinder false -> TTAny TTBinder
+| ETConstr p -> TTAny (TTConstr (p, forpat))
+| ETPattern -> assert false (** not used *)
+| ETOther _ -> assert false (** not used *)
+| ETConstrList (p, tkl) -> TTAny (TTConstrList (p, tkl, forpat))
+| ETBinderList (true, []) -> TTAny TTBinderListT
+| ETBinderList (true, _) -> assert false
+| ETBinderList (false, tkl) -> TTAny (TTBinderListF tkl)
+
let constr_expr_of_name (loc,na) = match na with
| Anonymous -> CHole (loc,None,Misctypes.IntroAnonymous,None)
| Name id -> CRef (Ident (loc,id), None)
@@ -60,140 +327,122 @@ type grammar_constr_prod_item =
(* tells action rule to make a list of the n previous parsed items;
concat with last parsed list if true *)
-let make_constr_action
- (f : Loc.t -> constr_notation_substitution -> constr_expr) pil =
- let rec make (constrs,constrlists,binders as fullsubst) = function
- | [] ->
- Gram.action (fun (loc:CompatLoc.t) -> f (!@loc) fullsubst)
- | (GramConstrTerminal _ | GramConstrNonTerminal (_,None)) :: tl ->
- (* parse a non-binding item *)
- Gram.action (fun _ -> make fullsubst tl)
- | GramConstrNonTerminal (typ, Some _) :: tl ->
- (* parse a binding non-terminal *)
- (match typ with
- | (ETConstr _| ETOther _) ->
- Gram.action (fun (v:constr_expr) ->
- make (v :: constrs, constrlists, binders) tl)
- | ETReference ->
- Gram.action (fun (v:reference) ->
- make (CRef (v,None) :: constrs, constrlists, binders) tl)
- | ETName ->
- Gram.action (fun (na:Loc.t * Name.t) ->
- make (constr_expr_of_name na :: constrs, constrlists, binders) tl)
- | ETBigint ->
- Gram.action (fun (v:Bigint.bigint) ->
- make (CPrim(Loc.ghost,Numeral v) :: constrs, constrlists, binders) tl)
- | ETConstrList (_,n) ->
- Gram.action (fun (v:constr_expr list) ->
- make (constrs, v::constrlists, binders) tl)
- | ETBinder _ | ETBinderList (true,_) ->
- Gram.action (fun (v:local_binder list) ->
- make (constrs, constrlists, v::binders) tl)
- | ETBinderList (false,_) ->
- Gram.action (fun (v:local_binder list list) ->
- make (constrs, constrlists, List.flatten v::binders) tl)
- | ETPattern ->
- failwith "Unexpected entry of type cases pattern")
- | GramConstrListMark (n,b) :: tl ->
- (* Rebuild expansions of ConstrList *)
- let heads,constrs = List.chop n constrs in
- let constrlists =
- if b then (heads@List.hd constrlists)::List.tl constrlists
- else heads::constrlists
- in make (constrs, constrlists, binders) tl
- in
- make ([],[],[]) (List.rev pil)
-
-let check_cases_pattern_env loc (env,envlist,hasbinders) =
- if hasbinders then Topconstr.error_invalid_pattern_notation loc
- else (env,envlist)
-
-let make_cases_pattern_action
- (f : Loc.t -> cases_pattern_notation_substitution -> cases_pattern_expr) pil =
- let rec make (env,envlist,hasbinders as fullenv) = function
- | [] ->
- Gram.action
- (fun (loc:CompatLoc.t) ->
- let loc = !@loc in
- f loc (check_cases_pattern_env loc fullenv))
- | (GramConstrTerminal _ | GramConstrNonTerminal (_,None)) :: tl ->
- (* parse a non-binding item *)
- Gram.action (fun _ -> make fullenv tl)
- | GramConstrNonTerminal (typ, Some _) :: tl ->
- (* parse a binding non-terminal *)
- (match typ with
- | ETConstr _ -> (* pattern non-terminal *)
- Gram.action (fun (v:cases_pattern_expr) ->
- make (v::env, envlist, hasbinders) tl)
- | ETReference ->
- Gram.action (fun (v:reference) ->
- make (CPatAtom (Loc.ghost,Some v) :: env, envlist, hasbinders) tl)
- | ETName ->
- Gram.action (fun (na:Loc.t * Name.t) ->
- make (cases_pattern_expr_of_name na :: env, envlist, hasbinders) tl)
- | ETBigint ->
- Gram.action (fun (v:Bigint.bigint) ->
- make (CPatPrim (Loc.ghost,Numeral v) :: env, envlist, hasbinders) tl)
- | ETConstrList (_,_) ->
- Gram.action (fun (vl:cases_pattern_expr list) ->
- make (env, vl :: envlist, hasbinders) tl)
- | ETBinder _ | ETBinderList (true,_) ->
- Gram.action (fun (v:local_binder list) ->
- make (env, envlist, hasbinders) tl)
- | ETBinderList (false,_) ->
- Gram.action (fun (v:local_binder list list) ->
- make (env, envlist, true) tl)
- | (ETPattern | ETOther _) ->
- anomaly (Pp.str "Unexpected entry of type cases pattern or other"))
- | GramConstrListMark (n,b) :: tl ->
- (* Rebuild expansions of ConstrList *)
- let heads,env = List.chop n env in
- if b then
- make (env,(heads@List.hd envlist)::List.tl envlist,hasbinders) tl
- else
- make (env,heads::envlist,hasbinders) tl
+type 'r env = {
+ constrs : 'r list;
+ constrlists : 'r list list;
+ binders : (local_binder list * bool) list;
+}
+
+let push_constr subst v = { subst with constrs = v :: subst.constrs }
+
+let push_item : type s r. s target -> (s, r) entry -> s env -> r -> s env = fun forpat e subst v ->
+match e with
+| TTConstr _ -> push_constr subst v
+| TTName ->
+ begin match forpat with
+ | ForConstr -> push_constr subst (constr_expr_of_name v)
+ | ForPattern -> push_constr subst (cases_pattern_expr_of_name v)
+ end
+| TTBinder -> { subst with binders = (v, true) :: subst.binders }
+| TTBinderListT -> { subst with binders = (v, true) :: subst.binders }
+| TTBinderListF _ -> { subst with binders = (List.flatten v, false) :: subst.binders }
+| TTBigint ->
+ begin match forpat with
+ | ForConstr -> push_constr subst (CPrim (Loc.ghost, Numeral v))
+ | ForPattern -> push_constr subst (CPatPrim (Loc.ghost, Numeral v))
+ end
+| TTReference ->
+ begin match forpat with
+ | ForConstr -> push_constr subst (CRef (v, None))
+ | ForPattern -> push_constr subst (CPatAtom (Loc.ghost, Some v))
+ end
+| TTConstrList _ -> { subst with constrlists = v :: subst.constrlists }
+
+type (_, _) ty_symbol =
+| TyTerm : Tok.t -> ('s, string) ty_symbol
+| TyNonTerm : 's target * ('s, 'a) entry * ('s, 'a) symbol * bool -> ('s, 'a) ty_symbol
+
+type ('self, _, 'r) ty_rule =
+| TyStop : ('self, 'r, 'r) ty_rule
+| TyNext : ('self, 'a, 'r) ty_rule * ('self, 'b) ty_symbol -> ('self, 'b -> 'a, 'r) ty_rule
+| TyMark : int * bool * ('self, 'a, 'r) ty_rule -> ('self, 'a, 'r) ty_rule
+
+type 'r gen_eval = Loc.t -> 'r env -> 'r
+
+let rec ty_eval : type s a. (s, a, Loc.t -> s) ty_rule -> s gen_eval -> s env -> a = function
+| TyStop ->
+ fun f env loc -> f loc env
+| TyNext (rem, TyTerm _) ->
+ fun f env _ -> ty_eval rem f env
+| TyNext (rem, TyNonTerm (_, _, _, false)) ->
+ fun f env _ -> ty_eval rem f env
+| TyNext (rem, TyNonTerm (forpat, e, _, true)) ->
+ fun f env v ->
+ ty_eval rem f (push_item forpat e env v)
+| TyMark (n, b, rem) ->
+ fun f env ->
+ let heads, constrs = List.chop n env.constrs in
+ let constrlists =
+ if b then (heads @ List.hd env.constrlists) :: List.tl env.constrlists
+ else heads :: env.constrlists
+ in
+ ty_eval rem f { env with constrs; constrlists; }
+
+let rec ty_erase : type s a r. (s, a, r) ty_rule -> (s, a, r) Extend.rule = function
+| TyStop -> Stop
+| TyMark (_, _, r) -> ty_erase r
+| TyNext (rem, TyTerm tok) -> Next (ty_erase rem, Atoken tok)
+| TyNext (rem, TyNonTerm (_, _, s, _)) -> Next (ty_erase rem, s)
+
+type ('self, 'r) any_ty_rule =
+| AnyTyRule : ('self, 'act, Loc.t -> 'r) ty_rule -> ('self, 'r) any_ty_rule
+
+let make_ty_rule assoc from forpat prods =
+ let rec make_ty_rule = function
+ | [] -> AnyTyRule TyStop
+ | GramConstrTerminal tok :: rem ->
+ let AnyTyRule r = make_ty_rule rem in
+ AnyTyRule (TyNext (r, TyTerm tok))
+ | GramConstrNonTerminal (e, var) :: rem ->
+ let AnyTyRule r = make_ty_rule rem in
+ let TTAny e = interp_entry forpat e in
+ let s = symbol_of_entry assoc from e in
+ let bind = match var with None -> false | Some _ -> true in
+ AnyTyRule (TyNext (r, TyNonTerm (forpat, e, s, bind)))
+ | GramConstrListMark (n, b) :: rem ->
+ let AnyTyRule r = make_ty_rule rem in
+ AnyTyRule (TyMark (n, b, r))
in
- make ([],[],false) (List.rev pil)
-
-let rec make_constr_prod_item assoc from forpat = function
- | GramConstrTerminal tok :: l ->
- gram_token_of_token tok :: make_constr_prod_item assoc from forpat l
- | GramConstrNonTerminal (nt, ovar) :: l ->
- symbol_of_constr_prod_entry_key assoc from forpat nt
- :: make_constr_prod_item assoc from forpat l
- | GramConstrListMark _ :: l ->
- make_constr_prod_item assoc from forpat l
- | [] ->
- []
+ make_ty_rule (List.rev prods)
+
+let target_to_bool : type r. r target -> bool = function
+| ForConstr -> false
+| ForPattern -> true
let prepare_empty_levels forpat (pos,p4assoc,name,reinit) =
let empty = (pos, [(name, p4assoc, [])]) in
- if forpat then grammar_extend Constr.pattern reinit empty
- else grammar_extend Constr.operconstr reinit empty
-
-let pure_sublevels level symbs =
- let filter s =
- try
- let i = level_of_snterml s in
- begin match level with
- | Some j when Int.equal i j -> None
- | _ -> Some i
- end
- with Failure _ -> None
- in
- List.map_filter filter symbs
-
-let extend_constr (entry,level) (n,assoc) mkact forpat rules =
- List.fold_left (fun nb pt ->
- let symbs = make_constr_prod_item assoc n forpat pt in
- let pure_sublevels = pure_sublevels level symbs in
- let needed_levels = register_empty_levels forpat pure_sublevels in
- let pos,p4assoc,name,reinit = find_position forpat assoc level in
- let nb_decls = List.length needed_levels + 1 in
- List.iter (prepare_empty_levels forpat) needed_levels;
- unsafe_grammar_extend entry reinit (Option.map of_coq_position pos,
- [(name, Option.map of_coq_assoc p4assoc, [symbs, mkact pt])]);
- nb_decls) 0 rules
+ if forpat then ExtendRule (Constr.pattern, reinit, empty)
+ else ExtendRule (Constr.operconstr, reinit, empty)
+
+let rec pure_sublevels : type a b c. int option -> (a, b, c) rule -> int list = fun level r -> match r with
+| Stop -> []
+| Next (rem, Aentryl (_, i)) ->
+ let rem = pure_sublevels level rem in
+ begin match level with
+ | Some j when Int.equal i j -> rem
+ | _ -> i :: rem
+ end
+| Next (rem, _) -> pure_sublevels level rem
+
+let make_act : type r. r target -> _ -> r gen_eval = function
+| ForConstr -> fun notation loc env ->
+ let env = (env.constrs, env.constrlists, List.map fst env.binders) in
+ CNotation (loc, notation , env)
+| ForPattern -> fun notation loc env ->
+ let invalid = List.exists (fun (_, b) -> not b) env.binders in
+ let () = if invalid then Topconstr.error_invalid_pattern_notation loc in
+ let env = (env.constrs, env.constrlists) in
+ CPatNotation (loc, notation, env, [])
type notation_grammar = {
notgram_level : int;
@@ -203,200 +452,51 @@ type notation_grammar = {
notgram_typs : notation_var_internalization_type list;
}
-let extend_constr_constr_notation ng =
- let level = ng.notgram_level in
- let mkact loc env = CNotation (loc, ng.notgram_notation, env) in
- let e = interp_constr_entry_key false (ETConstr (level, ())) in
- let ext = (ETConstr (level, ()), ng.notgram_assoc) in
- extend_constr e ext (make_constr_action mkact) false ng.notgram_prods
-
-let extend_constr_pat_notation ng =
- let level = ng.notgram_level in
- let mkact loc env = CPatNotation (loc, ng.notgram_notation, env, []) in
- let e = interp_constr_entry_key true (ETConstr (level, ())) in
- let ext = ETConstr (level, ()), ng.notgram_assoc in
- extend_constr e ext (make_cases_pattern_action mkact) true ng.notgram_prods
-
-let extend_constr_notation ng =
- (* Add the notation in constr *)
- let nb = extend_constr_constr_notation ng in
- (* Add the notation in cases_pattern *)
- let nb' = extend_constr_pat_notation ng in
- nb + nb'
-
-(**********************************************************************)
-(** Grammar declaration for Tactic Notation (Coq level) *)
-
-let get_tactic_entry n =
- if Int.equal n 0 then
- Tactic.simple_tactic, None
- else if Int.equal n 5 then
- Tactic.binder_tactic, None
- else if 1<=n && n<5 then
- Tactic.tactic_expr, Some (Extend.Level (string_of_int n))
- else
- error ("Invalid Tactic Notation level: "^(string_of_int n)^".")
-
-(**********************************************************************)
-(** State of the grammar extensions *)
-
-type tactic_grammar = {
- tacgram_level : int;
- tacgram_prods : Tacexpr.raw_tactic_expr grammar_prod_item list;
-}
-
-type all_grammar_command =
- | Notation of Notation.level * notation_grammar
- | TacticGrammar of KerName.t * tactic_grammar
- | MLTacticGrammar of ml_tactic_name * Tacexpr.raw_tactic_expr grammar_prod_item list list
-
-(** ML Tactic grammar extensions *)
-
-let add_ml_tactic_entry name prods =
- let entry = Tactic.simple_tactic in
- let mkact i loc l : raw_tactic_expr =
- let open Tacexpr in
- let entry = { mltac_name = name; mltac_index = i } in
- let map arg = TacGeneric arg in
- TacML (loc, entry, List.map map l)
+let extend_constr state forpat ng =
+ let n = ng.notgram_level in
+ let assoc = ng.notgram_assoc in
+ let (entry, level) = interp_constr_entry_key forpat n in
+ let fold (accu, state) pt =
+ let AnyTyRule r = make_ty_rule assoc n forpat pt in
+ let symbs = ty_erase r in
+ let pure_sublevels = pure_sublevels level symbs in
+ let isforpat = target_to_bool forpat in
+ let needed_levels, state = register_empty_levels state isforpat pure_sublevels in
+ let (pos,p4assoc,name,reinit), state = find_position state isforpat assoc level in
+ let nb_decls = List.length needed_levels + 1 in
+ let empty_rules = List.map (prepare_empty_levels isforpat) needed_levels in
+ let empty = { constrs = []; constrlists = []; binders = [] } in
+ let act = ty_eval r (make_act forpat ng.notgram_notation) empty in
+ let rule = (name, p4assoc, [Rule (symbs, act)]) in
+ let r = ExtendRule (entry, reinit, (pos, [rule])) in
+ (accu @ empty_rules @ [r], state)
in
- let rules = List.map_i (fun i p -> make_rule (mkact i) p) 0 prods in
- synchronize_level_positions ();
- grammar_extend entry None (None, [(None, None, List.rev rules)]);
- 1
+ List.fold_left fold ([], state) ng.notgram_prods
-(* Declaration of the tactic grammar rule *)
+let constr_levels = GramState.field ()
-let head_is_ident tg = match tg.tacgram_prods with
-| GramTerminal _::_ -> true
-| _ -> false
-
-(** Tactic grammar extensions *)
-
-let add_tactic_entry kn tg =
- let entry, pos = get_tactic_entry tg.tacgram_level in
- let mkact loc l =
- let filter = function
- | GramTerminal _ -> None
- | GramNonTerminal (_, t, _) -> Some (Genarg.unquote t)
- in
- let types = List.map_filter filter tg.tacgram_prods in
- let map arg t =
- (** HACK to handle especially the tactic(...) entry *)
- let wit = Genarg.rawwit Constrarg.wit_tactic in
- if Genarg.argument_type_eq t (Genarg.unquote wit) then
- Tacexp (Genarg.out_gen wit arg)
- else
- TacGeneric arg
- in
- let l = List.map2 map l types in
- (TacAlias (loc,kn,l):raw_tactic_expr)
- in
- let () =
- if Int.equal tg.tacgram_level 0 && not (head_is_ident tg) then
- error "Notation for simple tactic must start with an identifier."
+let extend_constr_notation (_, ng) state =
+ let levels = match GramState.get state constr_levels with
+ | None -> default_constr_levels
+ | Some lev -> lev
in
- let rules = make_rule mkact tg.tacgram_prods in
- synchronize_level_positions ();
- grammar_extend entry None (pos, [(None, None, List.rev [rules])]);
- 1
-
-let (grammar_state : (int * all_grammar_command) list ref) = ref []
-
-let extend_grammar gram =
- let nb = match gram with
- | Notation (_,a) -> extend_constr_notation a
- | TacticGrammar (kn, g) -> add_tactic_entry kn g
- | MLTacticGrammar (name, pr) -> add_ml_tactic_entry name pr
- in
- grammar_state := (nb,gram) :: !grammar_state
-
-let extend_constr_grammar pr ntn =
- extend_grammar (Notation (pr, ntn))
+ (* Add the notation in constr *)
+ let (r, levels) = extend_constr levels ForConstr ng in
+ (* Add the notation in cases_pattern *)
+ let (r', levels) = extend_constr levels ForPattern ng in
+ let state = GramState.set state constr_levels levels in
+ (r @ r', state)
-let extend_tactic_grammar kn ntn =
- extend_grammar (TacticGrammar (kn, ntn))
+let constr_grammar : (Notation.level * notation_grammar) grammar_command =
+ create_grammar_command "Notation" extend_constr_notation
-let extend_ml_tactic_grammar name ntn =
- extend_grammar (MLTacticGrammar (name, ntn))
+let extend_constr_grammar pr ntn = extend_grammar_command constr_grammar (pr, ntn)
let recover_constr_grammar ntn prec =
- let filter = function
- | _, Notation (prec', ng) when
- Notation.level_eq prec prec' &&
- String.equal ntn ng.notgram_notation -> Some ng
- | _ -> None
+ let filter (prec', ng) =
+ if Notation.level_eq prec prec' && String.equal ntn ng.notgram_notation then Some ng
+ else None
in
- match List.map_filter filter !grammar_state with
+ match List.map_filter filter (recover_grammar_command constr_grammar) with
| [x] -> x
| _ -> assert false
-
-(* Summary functions: the state of the lexer is included in that of the parser.
- Because the grammar affects the set of keywords when adding or removing
- grammar rules. *)
-type frozen_t = (int * all_grammar_command) list * Lexer.frozen_t
-
-let freeze _ : frozen_t = (!grammar_state, Lexer.freeze ())
-
-(* We compare the current state of the grammar and the state to unfreeze,
- by computing the longest common suffixes *)
-let factorize_grams l1 l2 =
- if l1 == l2 then ([], [], l1) else List.share_tails l1 l2
-
-let number_of_entries gcl =
- List.fold_left (fun n (p,_) -> n + p) 0 gcl
-
-let unfreeze (grams, lex) =
- let (undo, redo, common) = factorize_grams !grammar_state grams in
- let n = number_of_entries undo in
- remove_grammars n;
- remove_levels n;
- grammar_state := common;
- Lexer.unfreeze lex;
- List.iter extend_grammar (List.rev_map snd redo)
-
-(** No need to provide an init function : the grammar state is
- statically available, and already empty initially, while
- the lexer state should not be resetted, since it contains
- keywords declared in g_*.ml4 *)
-
-let _ =
- Summary.declare_summary "GRAMMAR_LEXER"
- { Summary.freeze_function = freeze;
- Summary.unfreeze_function = unfreeze;
- Summary.init_function = Summary.nop }
-
-let with_grammar_rule_protection f x =
- let fs = freeze false in
- try let a = f x in unfreeze fs; a
- with reraise ->
- let reraise = Errors.push reraise in
- let () = unfreeze fs in
- iraise reraise
-
-(**********************************************************************)
-(** Ltac quotations *)
-
-let ltac_quotations = ref String.Set.empty
-
-let create_ltac_quotation name cast wit e =
- let () =
- if String.Set.mem name !ltac_quotations then
- failwith ("Ltac quotation " ^ name ^ " already registered")
- in
- let () = ltac_quotations := String.Set.add name !ltac_quotations in
-(* let level = Some "1" in *)
- let level = None in
- let assoc = Some Extend.RightA in
- let rule =
- Next (Next (Next (Stop,
- Atoken (Lexer.terminal name)),
- Atoken (Lexer.terminal ":")),
- Aentry (name_of_entry e))
- in
- let action v _ _ loc =
- let arg = TacGeneric (Genarg.in_gen (Genarg.rawwit wit) (cast (loc, v))) in
- TacArg (loc, arg)
- in
- let gram = (level, assoc, [Rule (rule, action)]) in
- Pcoq.grammar_extend Tactic.tactic_expr None (None, [gram])
diff --git a/parsing/egramcoq.mli b/parsing/egramcoq.mli
index 17524971f..1fe06a29d 100644
--- a/parsing/egramcoq.mli
+++ b/parsing/egramcoq.mli
@@ -36,34 +36,11 @@ type notation_grammar = {
notgram_typs : notation_var_internalization_type list;
}
-type tactic_grammar = {
- tacgram_level : int;
- tacgram_prods : Tacexpr.raw_tactic_expr grammar_prod_item list;
-}
-
(** {5 Adding notations} *)
val extend_constr_grammar : Notation.level -> notation_grammar -> unit
(** Add a term notation rule to the parsing system. *)
-val extend_tactic_grammar : KerName.t -> tactic_grammar -> unit
-(** Add a tactic notation rule to the parsing system. This produces a TacAlias
- tactic with the provided kernel name. *)
-
-val extend_ml_tactic_grammar : Tacexpr.ml_tactic_name -> Tacexpr.raw_tactic_expr grammar_prod_item list list -> unit
-(** Add a ML tactic notation rule to the parsing system. This produces a
- TacML tactic with the provided string as name. *)
-
val recover_constr_grammar : notation -> Notation.level -> notation_grammar
(** For a declared grammar, returns the rule + the ordered entry types
of variables in the rule (for use in the interpretation) *)
-
-val with_grammar_rule_protection : ('a -> 'b) -> 'a -> 'b
-
-(** {5 Adding tactic quotations} *)
-
-val create_ltac_quotation : string -> ('grm Loc.located -> 'raw) ->
- ('raw, 'glb, 'top) genarg_type -> 'grm Gram.entry -> unit
-(** [create_ltac_quotation name f wit e] adds a quotation rule to Ltac, that is,
- Ltac grammar now accepts arguments of the form ["name" ":" <e>], and
- generates a generic argument using [f] on the entry parsed by [e]. *)
diff --git a/parsing/egramml.ml b/parsing/egramml.ml
index 77252e742..97a3e89a5 100644
--- a/parsing/egramml.ml
+++ b/parsing/egramml.ml
@@ -7,8 +7,7 @@
(************************************************************************)
open Util
-open Compat
-open Names
+open Extend
open Pcoq
open Genarg
open Vernacexpr
@@ -18,7 +17,7 @@ open Vernacexpr
type 's grammar_prod_item =
| GramTerminal of string
| GramNonTerminal :
- Loc.t * 'a raw_abstract_argument_type * ('s, 'a) entry_key -> 's grammar_prod_item
+ Loc.t * 'a raw_abstract_argument_type * ('s, 'a) symbol -> 's grammar_prod_item
type 'a ty_arg = ('a -> raw_generic_argument)
@@ -34,7 +33,7 @@ let rec ty_rule_of_gram = function
| [] -> AnyTyRule TyStop
| GramTerminal s :: rem ->
let AnyTyRule rem = ty_rule_of_gram rem in
- let tok = Atoken (Lexer.terminal s) in
+ let tok = Atoken (CLexer.terminal s) in
let r = TyNext (rem, tok, None) in
AnyTyRule r
| GramNonTerminal (_, t, tok) :: rem ->
diff --git a/parsing/egramml.mli b/parsing/egramml.mli
index edf971574..1ad947200 100644
--- a/parsing/egramml.mli
+++ b/parsing/egramml.mli
@@ -16,7 +16,7 @@ open Vernacexpr
type 's grammar_prod_item =
| GramTerminal of string
| GramNonTerminal : Loc.t * 'a Genarg.raw_abstract_argument_type *
- ('s, 'a) Pcoq.entry_key -> 's grammar_prod_item
+ ('s, 'a) Extend.symbol -> 's grammar_prod_item
val extend_vernac_command_grammar :
Vernacexpr.extend_name -> vernac_expr Pcoq.Gram.entry option ->
diff --git a/parsing/entry.ml b/parsing/entry.ml
deleted file mode 100644
index 0519903d3..000000000
--- a/parsing/entry.ml
+++ /dev/null
@@ -1,59 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-open Errors
-open Util
-
-type 'a t = string * string
-
-type repr = string * string
-
-type universe = string
-
-(* The univ_tab is not part of the state. It contains all the grammars that
- exist or have existed before in the session. *)
-
-let univ_tab = (Hashtbl.create 7 : (string, unit) Hashtbl.t)
-
-let create_univ s =
- Hashtbl.add univ_tab s (); s
-
-let univ_name s = s
-
-let uprim = create_univ "prim"
-let uconstr = create_univ "constr"
-let utactic = create_univ "tactic"
-let uvernac = create_univ "vernac"
-
-let get_univ s =
- try
- Hashtbl.find univ_tab s; s
- with Not_found ->
- anomaly (Pp.str ("Unknown grammar universe: "^s))
-
-(** Entries are registered with a unique name *)
-
-let entries = ref String.Set.empty
-
-let create u name =
- let uname = u ^ ":" ^ name in
- let () =
- if String.Set.mem uname !entries then
- anomaly (Pp.str ("Entry " ^ uname ^ " already defined"))
- in
- let () = entries := String.Set.add uname !entries in
- (u, name)
-
-let dynamic name = ("", name)
-
-let unsafe_of_name (u, s) =
- let uname = u ^ ":" ^ s in
- assert (String.Set.mem uname !entries);
- (u, s)
-
-let repr (u, s) = (u, s)
diff --git a/parsing/entry.mli b/parsing/entry.mli
deleted file mode 100644
index 97cd5b110..000000000
--- a/parsing/entry.mli
+++ /dev/null
@@ -1,44 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(** Typed grammar entries *)
-
-type 'a t
-(** Typed grammar entries. We need to defined them here so that they are
- marshallable and defined before the Pcoq.Gram module. They are basically
- unique names made of a universe and an entry name. They should be kept
- synchronized with the {!Pcoq} entries though. *)
-
-type repr = string * string
-(** Representation of entries. *)
-
-(** Table of Coq statically defined grammar entries *)
-
-type universe
-
-(** There are four predefined universes: "prim", "constr", "tactic", "vernac" *)
-
-val get_univ : string -> universe
-val univ_name : universe -> string
-
-val uprim : universe
-val uconstr : universe
-val utactic : universe
-val uvernac : universe
-
-(** {5 Uniquely defined entries} *)
-
-val create : universe -> string -> 'a t
-(** Create an entry. They should be synchronized with the entries defined in
- {!Pcoq}. *)
-
-(** {5 Meta-programming} *)
-
-val repr : 'a t -> repr
-
-val unsafe_of_name : (string * string) -> 'a t
diff --git a/parsing/g_constr.ml4 b/parsing/g_constr.ml4
index 0fe0ac42b..243f71416 100644
--- a/parsing/g_constr.ml4
+++ b/parsing/g_constr.ml4
@@ -29,7 +29,7 @@ let constr_kw =
"Prop"; "Set"; "Type"; ".("; "_"; "..";
"`{"; "`("; "{|"; "|}" ]
-let _ = List.iter Lexer.add_keyword constr_kw
+let _ = List.iter CLexer.add_keyword constr_kw
let mk_cast = function
(c,(_,None)) -> c
@@ -215,7 +215,7 @@ GEXTEND Gram
CGeneralization (!@loc, Implicit, None, c)
| "`("; c = operconstr LEVEL "200"; ")" ->
CGeneralization (!@loc, Explicit, None, c)
- | "ltac:"; "("; tac = Tactic.tactic_expr; ")" ->
+ | IDENT "ltac"; ":"; "("; tac = Tactic.tactic_expr; ")" ->
let arg = Genarg.in_gen (Genarg.rawwit Constrarg.wit_tactic) tac in
CHole (!@loc, None, IntroAnonymous, Some arg)
] ]
@@ -379,14 +379,17 @@ GEXTEND Gram
| "10" RIGHTA
[ p = pattern; lp = LIST1 NEXT ->
(match p with
- | CPatAtom (_, Some r) -> CPatCstr (!@loc, r, [], lp)
+ | CPatAtom (_, Some r) -> CPatCstr (!@loc, r, None, lp)
+ | CPatCstr (_, r, None, l2) -> Errors.user_err_loc
+ (cases_pattern_expr_loc p, "compound_pattern",
+ Pp.str "Nested applications not supported.")
| CPatCstr (_, r, l1, l2) -> CPatCstr (!@loc, r, l1 , l2@lp)
| CPatNotation (_, n, s, l) -> CPatNotation (!@loc, n , s, l@lp)
| _ -> Errors.user_err_loc
(cases_pattern_expr_loc p, "compound_pattern",
Pp.str "Such pattern cannot have arguments."))
- |"@"; r = Prim.reference; lp = LIST1 NEXT ->
- CPatCstr (!@loc, r, lp, []) ]
+ |"@"; r = Prim.reference; lp = LIST0 NEXT ->
+ CPatCstr (!@loc, r, Some lp, []) ]
| "1" LEFTA
[ c = pattern; "%"; key=IDENT -> CPatDelimiters (!@loc,key,c) ]
| "0"
diff --git a/parsing/g_prim.ml4 b/parsing/g_prim.ml4
index 5e67e9957..0d72f7b93 100644
--- a/parsing/g_prim.ml4
+++ b/parsing/g_prim.ml4
@@ -15,7 +15,7 @@ open Pcoq
open Pcoq.Prim
let prim_kw = ["{"; "}"; "["; "]"; "("; ")"; "'"]
-let _ = List.iter Lexer.add_keyword prim_kw
+let _ = List.iter CLexer.add_keyword prim_kw
let local_make_qualid l id = make_qualid (DirPath.make l) id
diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4
index 0c90a8bca..36fffd74f 100644
--- a/parsing/g_tactic.ml4
+++ b/parsing/g_tactic.ml4
@@ -25,7 +25,7 @@ open Pcoq
let all_with delta = Redops.make_red_flag [FBeta;FIota;FZeta;delta]
let tactic_kw = [ "->"; "<-" ; "by" ]
-let _ = List.iter Lexer.add_keyword tactic_kw
+let _ = List.iter CLexer.add_keyword tactic_kw
let err () = raise Stream.Failure
@@ -338,9 +338,6 @@ GEXTEND Gram
ExplicitBindings bl
| bl = LIST1 constr -> ImplicitBindings bl ] ]
;
- opt_bindings:
- [ [ bl = LIST1 bindings SEP "," -> bl | -> [NoBindings] ] ]
- ;
constr_with_bindings:
[ [ c = constr; l = with_bindings -> (c, l) ] ]
;
@@ -473,10 +470,10 @@ GEXTEND Gram
[ [ IDENT "eqn"; ":"; pat = naming_intropattern -> Some (!@loc, pat)
| IDENT "_eqn"; ":"; pat = naming_intropattern ->
let msg = "Obsolete syntax \"_eqn:H\" could be replaced by \"eqn:H\"" in
- msg_warning (strbrk msg); Some (!@loc, pat)
+ Feedback.msg_warning (strbrk msg); Some (!@loc, pat)
| IDENT "_eqn" ->
let msg = "Obsolete syntax \"_eqn\" could be replaced by \"eqn:?\"" in
- msg_warning (strbrk msg); Some (!@loc, IntroAnonymous)
+ Feedback.msg_warning (strbrk msg); Some (!@loc, IntroAnonymous)
| -> None ] ]
;
as_name:
@@ -531,13 +528,6 @@ GEXTEND Gram
TacAtom (!@loc, TacIntroPattern pl)
| IDENT "intros" ->
TacAtom (!@loc, TacIntroPattern [!@loc,IntroForthcoming false])
- | IDENT "intro"; id = ident; hto = move_location ->
- TacAtom (!@loc, TacIntroMove (Some id, hto))
- | IDENT "intro"; hto = move_location -> TacAtom (!@loc, TacIntroMove (None, hto))
- | IDENT "intro"; id = ident -> TacAtom (!@loc, TacIntroMove (Some id, MoveLast))
- | IDENT "intro" -> TacAtom (!@loc, TacIntroMove (None, MoveLast))
-
- | IDENT "exact"; c = constr -> TacAtom (!@loc, TacExact c)
| IDENT "apply"; cl = LIST1 constr_with_bindings_arg SEP ",";
inhyp = in_hyp_as -> TacAtom (!@loc, TacApply (true,false,cl,inhyp))
@@ -609,16 +599,11 @@ GEXTEND Gram
TacAtom (!@loc, TacInductionDestruct (true,false,ic))
| IDENT "einduction"; ic = induction_clause_list ->
TacAtom (!@loc, TacInductionDestruct(true,true,ic))
- | IDENT "double"; IDENT "induction"; h1 = quantified_hypothesis;
- h2 = quantified_hypothesis -> TacAtom (!@loc, TacDoubleInduction (h1,h2))
| IDENT "destruct"; icl = induction_clause_list ->
TacAtom (!@loc, TacInductionDestruct(false,false,icl))
| IDENT "edestruct"; icl = induction_clause_list ->
TacAtom (!@loc, TacInductionDestruct(false,true,icl))
- (* Context management *)
- | IDENT "rename"; l = LIST1 rename SEP "," -> TacAtom (!@loc, TacRename l)
-
(* Equality and inversion *)
| IDENT "rewrite"; l = LIST1 oriented_rewriter SEP ",";
cl = clause_dft_concl; t=opt_by_tactic -> TacAtom (!@loc, TacRewrite (false,l,cl,t))
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index b5e9f9e06..0df15babd 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -20,22 +20,19 @@ open Misctypes
open Tok (* necessary for camlp4 *)
open Pcoq
-open Pcoq.Tactic
open Pcoq.Prim
open Pcoq.Constr
open Pcoq.Vernac_
open Pcoq.Module
let vernac_kw = [ ";"; ","; ">->"; ":<"; "<:"; "where"; "at" ]
-let _ = List.iter Lexer.add_keyword vernac_kw
+let _ = List.iter CLexer.add_keyword vernac_kw
(* Rem: do not join the different GEXTEND into one, it breaks native *)
(* compilation on PowerPC and Sun architectures *)
let query_command = Gram.entry_create "vernac:query_command"
-let tactic_mode = Gram.entry_create "vernac:tactic_command"
-let noedit_mode = Gram.entry_create "vernac:noedit_command"
let subprf = Gram.entry_create "vernac:subprf"
let class_rawexpr = Gram.entry_create "vernac:class_rawexpr"
@@ -48,21 +45,6 @@ let subgoal_command = Gram.entry_create "proof_mode:subgoal_command"
let instance_name = Gram.entry_create "vernac:instance_name"
let section_subset_expr = Gram.entry_create "vernac:section_subset_expr"
-let command_entry = ref noedit_mode
-let set_command_entry e = command_entry := e
-let get_command_entry () = !command_entry
-
-
-(* Registers the Classic Proof Mode (which uses [tactic_mode] as a parser for
- proof editing and changes nothing else). Then sets it as the default proof mode. *)
-let set_tactic_mode () = set_command_entry tactic_mode
-let set_noedit_mode () = set_command_entry noedit_mode
-let _ = Proof_global.register_proof_mode {Proof_global.
- name = "Classic" ;
- set = set_tactic_mode ;
- reset = set_noedit_mode
- }
-
let make_bullet s =
let n = String.length s in
match s.[0] with
@@ -71,23 +53,8 @@ let make_bullet s =
| '*' -> Star n
| _ -> assert false
-(* Hack to parse "[ id" without dropping [ *)
-let test_bracket_ident =
- Gram.Entry.of_parser "test_bracket_ident"
- (fun strm ->
- match get_tok (stream_nth 0 strm) with
- | KEYWORD "[" ->
- (match get_tok (stream_nth 1 strm) with
- | IDENT _ -> ()
- | _ -> raise Stream.Failure)
- | _ -> raise Stream.Failure)
-
-let default_command_entry =
- Gram.Entry.of_parser "command_entry"
- (fun strm -> Gram.parse_tokens_after_filter (get_command_entry ()) strm)
-
GEXTEND Gram
- GLOBAL: vernac gallina_ext tactic_mode noedit_mode subprf subgoal_command;
+ GLOBAL: vernac gallina_ext noedit_mode subprf subgoal_command;
vernac: FIRST
[ [ IDENT "Time"; c = located_vernac -> VernacTime c
| IDENT "Redirect"; s = ne_string; c = located_vernac -> VernacRedirect (s, c)
@@ -129,24 +96,12 @@ GEXTEND Gram
] ]
;
vernac_aux: LAST
- [ [ prfcom = default_command_entry -> prfcom ] ]
+ [ [ prfcom = command_entry -> prfcom ] ]
;
noedit_mode:
[ [ c = subgoal_command -> c None] ]
;
- selector:
- [ [ n=natural; ":" -> SelectNth n
- | test_bracket_ident; "["; id = ident; "]"; ":" -> SelectId id
- | IDENT "all" ; ":" -> SelectAll
- | IDENT "par" ; ":" -> SelectAllParallel ] ]
- ;
-
- tactic_mode:
- [ [ gln = OPT selector;
- tac = subgoal_command -> tac gln ] ]
- ;
-
subprf:
[ [ s = BULLET -> VernacBullet (make_bullet s)
| "{" -> VernacSubproof None
@@ -161,13 +116,7 @@ GEXTEND Gram
| None -> c None
| _ ->
VernacError (UserError ("",str"Typing and evaluation commands, cannot be used with the \"all:\" selector."))
- end
- | info = OPT [IDENT "Info";n=natural -> n];
- tac = Tactic.tactic;
- use_dft_tac = [ "." -> false | "..." -> true ] ->
- (fun g ->
- let g = Option.default (Proof_global.get_default_goal_selector ()) g in
- VernacSolve(g,info,tac,use_dft_tac)) ] ]
+ end ] ]
;
located_vernac:
[ [ v = vernac -> !@loc, v ] ]
@@ -176,13 +125,13 @@ END
let test_plural_form = function
| [(_,([_],_))] ->
- Flags.if_verbose msg_warning
+ Flags.if_verbose Feedback.msg_warning
(strbrk "Keywords Variables/Hypotheses/Parameters expect more than one assumption")
| _ -> ()
let test_plural_form_types = function
| [([_],_)] ->
- Flags.if_verbose msg_warning
+ Flags.if_verbose Feedback.msg_warning
(strbrk "Keywords Implicit Types expect more than one type")
| _ -> ()
@@ -499,7 +448,7 @@ GEXTEND Gram
VernacInclude(e::l)
| IDENT "Include"; "Type"; e = module_type_inl; l = LIST0 ext_module_type ->
Flags.if_verbose
- msg_warning (strbrk "Include Type is deprecated; use Include instead");
+ Feedback.msg_warning (strbrk "Include Type is deprecated; use Include instead");
VernacInclude(e::l) ] ]
;
export_token:
@@ -718,7 +667,7 @@ GEXTEND Gram
(* 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 ]; "]" ->
- msg_warning (strbrk "Arguments Scope is deprecated; use Arguments instead");
+ Feedback. msg_warning (strbrk "Arguments Scope is deprecated; use Arguments instead");
VernacArgumentsScope (qid,scl)
(* Implicit *)
@@ -726,7 +675,7 @@ GEXTEND Gram
pos = LIST0 [ "["; l = LIST0 implicit_name; "]" ->
List.map (fun (id,b,f) -> (ExplByName id,b,f)) l ] ->
Flags.if_verbose
- msg_warning (strbrk "Implicit Arguments is deprecated; use Arguments instead");
+ Feedback.msg_warning (strbrk "Implicit Arguments is deprecated; use Arguments instead");
VernacDeclareImplicits (qid,pos)
| IDENT "Implicit"; "Type"; bl = reserv_list ->
@@ -801,11 +750,7 @@ GEXTEND Gram
GLOBAL: command query_command class_rawexpr;
command:
- [ [ IDENT "Ltac";
- l = LIST1 tacdef_body SEP "with" ->
- VernacDeclareTacticDefinition l
-
- | IDENT "Comments"; l = LIST0 comment -> VernacComments l
+ [ [ IDENT "Comments"; l = LIST0 comment -> VernacComments l
(* Hack! Should be in grammar_ext, but camlp4 factorize badly *)
| IDENT "Declare"; IDENT "Instance"; namesup = instance_name; ":";
@@ -940,7 +885,6 @@ GEXTEND Gram
| IDENT "Classes" -> PrintClasses
| IDENT "TypeClasses" -> PrintTypeClasses
| IDENT "Instances"; qid = smart_global -> PrintInstances qid
- | IDENT "Ltac"; qid = global -> PrintLtac qid
| IDENT "Coercions" -> PrintCoercions
| IDENT "Coercion"; IDENT "Paths"; s = class_rawexpr; t = class_rawexpr
-> PrintCoercionPaths (s,t)
@@ -951,7 +895,6 @@ GEXTEND Gram
| IDENT "Hint"; qid = smart_global -> PrintHint qid
| IDENT "Hint"; "*" -> PrintHintDb
| IDENT "HintDb"; s = IDENT -> PrintHintDbName s
- | "Rewrite"; IDENT "HintDb"; s = IDENT -> PrintRewriteHintDbName s
| IDENT "Scopes" -> PrintScopes
| IDENT "Scope"; s = IDENT -> PrintScope s
| IDENT "Visibility"; s = OPT [x = IDENT -> x ] -> PrintVisibility s
@@ -1080,7 +1023,7 @@ GEXTEND Gram
VernacDelimiters (sc, None)
| IDENT "Bind"; IDENT "Scope"; sc = IDENT; "with";
- refl = LIST1 smart_global -> VernacBindScope (sc,refl)
+ refl = LIST1 class_rawexpr -> VernacBindScope (sc,refl)
| IDENT "Infix"; local = obsolete_locality;
op = ne_lstring; ":="; p = constr;
@@ -1099,10 +1042,6 @@ GEXTEND Gram
| IDENT "Format"; IDENT "Notation"; n = STRING; s = STRING; fmt = STRING ->
VernacNotationAddFormat (n,s,fmt)
- | IDENT "Tactic"; IDENT "Notation"; n = tactic_level;
- pil = LIST1 production_item; ":="; t = Tactic.tactic
- -> VernacTacticNotation (n,pil,t)
-
| IDENT "Reserved"; IDENT "Infix"; s = ne_lstring;
l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ] ->
Metasyntax.check_infix_modifiers l;
@@ -1128,9 +1067,6 @@ GEXTEND Gram
obsolete_locality:
[ [ IDENT "Local" -> true | -> false ] ]
;
- tactic_level:
- [ [ "("; "at"; IDENT "level"; n = natural; ")" -> n | -> 0 ] ]
- ;
level:
[ [ IDENT "level"; n = natural -> NumLevel n
| IDENT "next"; IDENT "level" -> NextLevel ] ]
@@ -1162,10 +1098,4 @@ GEXTEND Gram
| IDENT "closed"; IDENT "binder" -> ETBinder false
] ]
;
- production_item:
- [ [ s = ne_string -> TacTerm s
- | nt = IDENT;
- po = [ "("; p = ident; sep = [ -> "" | ","; sep = STRING -> sep ];
- ")" -> (p,sep) ] -> TacNonTerm (!@loc,nt,po) ] ]
- ;
END
diff --git a/parsing/highparsing.mllib b/parsing/highparsing.mllib
index 13ed80464..8df519b56 100644
--- a/parsing/highparsing.mllib
+++ b/parsing/highparsing.mllib
@@ -3,5 +3,3 @@ G_vernac
G_prim
G_proofs
G_tactic
-G_ltac
-G_obligations
diff --git a/parsing/parsing.mllib b/parsing/parsing.mllib
index 024d8607f..0e1c79c91 100644
--- a/parsing/parsing.mllib
+++ b/parsing/parsing.mllib
@@ -1,7 +1,6 @@
Tok
Compat
-Lexer
-Entry
+CLexer
Pcoq
Egramml
Egramcoq
diff --git a/parsing/pcoq.ml b/parsing/pcoq.ml
index cf65262c4..efb89cd6e 100644
--- a/parsing/pcoq.ml
+++ b/parsing/pcoq.ml
@@ -12,20 +12,26 @@ open Errors
open Util
open Extend
open Genarg
-open Stdarg
-open Constrarg
-open Tok (* necessary for camlp4 *)
(** The parser of Coq *)
-module G = GrammarMake (Lexer)
+module G = GrammarMake (CLexer)
let warning_verbose = Compat.warning_verbose
-module Symbols = GramextMake(G)
+let of_coq_assoc = function
+| Extend.RightA -> CompatGramext.RightA
+| Extend.LeftA -> CompatGramext.LeftA
+| Extend.NonA -> CompatGramext.NonA
+
+let of_coq_position = function
+| Extend.First -> CompatGramext.First
+| Extend.Last -> CompatGramext.Last
+| Extend.Before s -> CompatGramext.Before s
+| Extend.After s -> CompatGramext.After s
+| Extend.Level s -> CompatGramext.Level s
-let gram_token_of_token = Symbols.stoken
-let gram_token_of_string s = gram_token_of_token (Lexer.terminal s)
+module Symbols = GramextMake(G)
let camlp4_verbosity silent f x =
let a = !warning_verbose in
@@ -35,51 +41,6 @@ let camlp4_verbosity silent f x =
let camlp4_verbose f x = camlp4_verbosity (Flags.is_verbose ()) f x
-
-(** [grammar_object] is the superclass of all grammar entries *)
-
-module type Gramobj =
-sig
- type grammar_object
- val weaken_entry : 'a G.entry -> grammar_object G.entry
-end
-
-module Gramobj : Gramobj =
-struct
- type grammar_object = Obj.t
- let weaken_entry e = Obj.magic e
-end
-
-(** Grammar entries with associated types *)
-
-type grammar_object = Gramobj.grammar_object
-type typed_entry = TypedEntry : 'a raw_abstract_argument_type * 'a G.entry -> typed_entry
-let object_of_typed_entry (TypedEntry (_, e)) = Gramobj.weaken_entry e
-let weaken_entry x = Gramobj.weaken_entry x
-
-(** General entry keys *)
-
-(** This intermediate abstract representation of entries can
- both be reified into mlexpr for the ML extensions and
- dynamically interpreted as entries for the Coq level extensions
-*)
-
-type ('self, 'a) entry_key = ('self, 'a) Extend.symbol =
-| Atoken : Tok.t -> ('self, string) entry_key
-| Alist1 : ('self, 'a) entry_key -> ('self, 'a list) entry_key
-| Alist1sep : ('self, 'a) entry_key * string -> ('self, 'a list) entry_key
-| Alist0 : ('self, 'a) entry_key -> ('self, 'a list) entry_key
-| Alist0sep : ('self, 'a) entry_key * string -> ('self, 'a list) entry_key
-| Aopt : ('self, 'a) entry_key -> ('self, 'a option) entry_key
-| Amodifiers : ('self, 'a) entry_key -> ('self, 'a list) entry_key
-| Aself : ('self, 'self) entry_key
-| Anext : ('self, 'self) entry_key
-| Aentry : 'a Entry.t -> ('self, 'a) entry_key
-| Aentryl : 'a Entry.t * int -> ('self, 'a) entry_key
-
-type 's entry_name = EntryName :
- 'a raw_abstract_argument_type * ('s, 'a) entry_key -> 's entry_name
-
(** Grammar extensions *)
(** NB: [extend_statment =
@@ -91,14 +52,57 @@ type 's entry_name = EntryName :
In [single_extend_statement], first two parameters are name and
assoc iff a level is created *)
+(** Binding general entry keys to symbol *)
+
+let rec of_coq_action : type a r. (r, a, Loc.t -> r) Extend.rule -> a -> G.action = function
+| Stop -> fun f -> G.action (fun loc -> f (to_coqloc loc))
+| Next (r, _) -> fun f -> G.action (fun x -> of_coq_action r (f x))
+
+let rec symbol_of_prod_entry_key : type s a. (s, a) symbol -> _ = function
+ | Atoken t -> Symbols.stoken t
+ | Alist1 s -> Symbols.slist1 (symbol_of_prod_entry_key s)
+ | Alist1sep (s,sep) ->
+ Symbols.slist1sep (symbol_of_prod_entry_key s, symbol_of_prod_entry_key sep)
+ | Alist0 s -> Symbols.slist0 (symbol_of_prod_entry_key s)
+ | Alist0sep (s,sep) ->
+ Symbols.slist0sep (symbol_of_prod_entry_key s, symbol_of_prod_entry_key sep)
+ | Aopt s -> Symbols.sopt (symbol_of_prod_entry_key s)
+ | Aself -> Symbols.sself
+ | Anext -> Symbols.snext
+ | Aentry e ->
+ Symbols.snterm (G.Entry.obj e)
+ | Aentryl (e, n) ->
+ Symbols.snterml (G.Entry.obj e, string_of_int n)
+ | Arules rs ->
+ G.srules' (List.map symbol_of_rules rs)
+
+and symbol_of_rule : type s a r. (s, a, r) Extend.rule -> _ = function
+| Stop -> fun accu -> accu
+| Next (r, s) -> fun accu -> symbol_of_rule r (symbol_of_prod_entry_key s :: accu)
+
+and symbol_of_rules : type a. a Extend.rules -> _ = function
+| Rules (r, act) ->
+ let symb = symbol_of_rule r.norec_rule [] in
+ let act = of_coq_action r.norec_rule act in
+ (symb, act)
+
+let of_coq_production_rule : type a. a Extend.production_rule -> _ = function
+| Rule (toks, act) -> (symbol_of_rule toks [], of_coq_action toks act)
+
+let of_coq_single_extend_statement (lvl, assoc, rule) =
+ (lvl, Option.map of_coq_assoc assoc, List.map of_coq_production_rule rule)
+
+let of_coq_extend_statement (pos, st) =
+ (Option.map of_coq_position pos, List.map of_coq_single_extend_statement st)
+
(** Type of reinitialization data *)
type gram_reinit = gram_assoc * gram_position
+type extend_rule =
+| ExtendRule : 'a G.entry * gram_reinit option * 'a extend_statment -> extend_rule
+
type ext_kind =
- | ByGrammar of
- grammar_object G.entry
- * gram_reinit option (** for reinitialization if ever needed *)
- * G.extend_statment
+ | ByGrammar of extend_rule
| ByEXTEND of (unit -> unit) * (unit -> unit)
(** The list of extensions *)
@@ -114,13 +118,28 @@ let grammar_delete e reinit (pos,rls) =
(List.rev rls);
match reinit with
| Some (a,ext) ->
- let lev = match Option.map Compat.to_coq_position pos with
- | Some (Level n) -> n
+ let a = of_coq_assoc a in
+ let ext = of_coq_position ext in
+ let lev = match pos with
+ | Some (CompatGramext.Level n) -> n
| _ -> assert false
in
maybe_uncurry (G.extend e) (Some ext, [Some lev,Some a,[]])
| None -> ()
+(** Extension *)
+
+let grammar_extend e reinit ext =
+ let ext = of_coq_extend_statement ext in
+ let undo () = grammar_delete e reinit ext in
+ let redo () = camlp4_verbose (maybe_uncurry (G.extend e)) ext in
+ camlp4_state := ByEXTEND (undo, redo) :: !camlp4_state;
+ redo ()
+
+let grammar_extend_sync e reinit ext =
+ camlp4_state := ByGrammar (ExtendRule (e, reinit, ext)) :: !camlp4_state;
+ camlp4_verbose (maybe_uncurry (G.extend e)) (of_coq_extend_statement ext)
+
(** The apparent parser of Coq; encapsulate G to keep track
of the extensions. *)
@@ -147,12 +166,6 @@ module Gram =
G.delete_rule e pil
end
-(** This extension command is used by the Grammar constr *)
-
-let unsafe_grammar_extend e reinit ext =
- camlp4_state := ByGrammar (weaken_entry e,reinit,ext) :: !camlp4_state;
- camlp4_verbose (maybe_uncurry (G.extend e)) ext
-
(** Remove extensions
[n] is the number of extended entries (not the number of Grammar commands!)
@@ -162,9 +175,8 @@ let rec remove_grammars n =
if n>0 then
(match !camlp4_state with
| [] -> anomaly ~label:"Pcoq.remove_grammars" (Pp.str "too many rules to remove")
- | ByGrammar(g,reinit,ext)::t ->
- let f (a,b) = (of_coq_assoc a, of_coq_position b) in
- grammar_delete g (Option.map f reinit) ext;
+ | ByGrammar (ExtendRule (g, reinit, ext)) :: t ->
+ grammar_delete g reinit (of_coq_extend_statement ext);
camlp4_state := t;
remove_grammars (n-1)
| ByEXTEND (undo,redo)::t ->
@@ -198,92 +210,70 @@ let map_entry f en =
let parse_string f x =
let strm = Stream.of_string x in Gram.entry_parse f (Gram.parsable strm)
-type gram_universe = Entry.universe
+type gram_universe = string
-let trace = ref false
+let utables : (string, unit) Hashtbl.t =
+ Hashtbl.create 97
-let uprim = Entry.uprim
-let uconstr = Entry.uconstr
-let utactic = Entry.utactic
-let uvernac = Entry.uvernac
-let get_univ = Entry.get_univ
+let create_universe u =
+ let () = Hashtbl.add utables u () in
+ u
-let utables : (string, (string, typed_entry) Hashtbl.t) Hashtbl.t =
- Hashtbl.create 97
+let uprim = create_universe "prim"
+let uconstr = create_universe "constr"
+let utactic = create_universe "tactic"
+let uvernac = create_universe "vernac"
+
+let get_univ u =
+ if Hashtbl.mem utables u then u
+ else raise Not_found
-let get_utable u =
- let u = Entry.univ_name u in
- try Hashtbl.find utables u
- with Not_found ->
- let table = Hashtbl.create 97 in
- Hashtbl.add utables u table;
- table
-
-let get_entry u s =
- let utab = get_utable u in
- Hashtbl.find utab s
-
-let get_typed_entry e =
- let (u, s) = Entry.repr e in
- let u = Entry.get_univ u in
- get_entry u s
-
-let new_entry etyp u s =
- let utab = get_utable u in
- let uname = Entry.univ_name u in
- if !trace then (Printf.eprintf "[Creating entry %s:%s]\n" uname s; flush stderr);
- let _ = Entry.create u s in
- let ename = uname ^ ":" ^ s in
+let new_entry u s =
+ let ename = u ^ ":" ^ s in
let e = Gram.entry_create ename in
- Hashtbl.add utab s (TypedEntry (etyp, e)); e
-
-let create_entry (type a) u s (etyp : a raw_abstract_argument_type) : a Gram.entry =
- let utab = get_utable u in
- try
- let TypedEntry (typ, e) = Hashtbl.find utab s in
- match abstract_argument_type_eq typ etyp with
- | None ->
- let u = Entry.univ_name u in
- failwith ("Entry " ^ u ^ ":" ^ s ^ " already exists with another type");
- | Some Refl -> e
- with Not_found ->
- new_entry etyp u s
-
-let create_constr_entry s = create_entry uconstr s (rawwit wit_constr)
-
-let create_generic_entry s wit = create_entry utactic s wit
-
-(* [make_gen_entry] builds entries extensible by giving its name (a string) *)
-(* For entries extensible only via the ML name, Gram.entry_create is enough *)
-
-let make_gen_entry u rawwit s =
- let univ = get_utable u in
- let uname = Entry.univ_name u in
- let e = Gram.entry_create (uname ^ ":" ^ s) in
- let _ = Entry.create u s in
- Hashtbl.add univ s (TypedEntry (rawwit, e)); e
+ e
+
+let make_gen_entry u s = new_entry u s
+
+module GrammarObj =
+struct
+ type ('r, _, _) obj = 'r Gram.entry
+ let name = "grammar"
+ let default _ = None
+end
+
+module Grammar = Register(GrammarObj)
+
+let register_grammar = Grammar.register0
+let genarg_grammar = Grammar.obj
+
+let create_generic_entry (type a) u s (etyp : a raw_abstract_argument_type) : a Gram.entry =
+ let e = new_entry u s in
+ let Rawwit t = etyp in
+ let () = Grammar.register0 t e in
+ e
(* Initial grammar entries *)
module Prim =
struct
- let gec_gen x = make_gen_entry uprim x
+ let gec_gen n = make_gen_entry uprim n
(* Entries that can be referred via the string -> Gram.entry table *)
(* Typically for tactic or vernac extensions *)
- let preident = gec_gen (rawwit wit_pre_ident) "preident"
- let ident = gec_gen (rawwit wit_ident) "ident"
- let natural = gec_gen (rawwit wit_int) "natural"
- let index = gec_gen (rawwit wit_int) "index"
- let integer = gec_gen (rawwit wit_int) "integer"
+ let preident = gec_gen "preident"
+ let ident = gec_gen "ident"
+ let natural = gec_gen "natural"
+ let index = gec_gen "index"
+ let integer = gec_gen "integer"
let bigint = Gram.entry_create "Prim.bigint"
- let string = gec_gen (rawwit wit_string) "string"
- let reference = make_gen_entry uprim (rawwit wit_ref) "reference"
+ let string = gec_gen "string"
+ let reference = make_gen_entry uprim "reference"
let by_notation = Gram.entry_create "by_notation"
let smart_global = Gram.entry_create "smart_global"
(* parsed like ident but interpreted as a term *)
- let var = gec_gen (rawwit wit_var) "var"
+ let var = gec_gen "var"
let name = Gram.entry_create "Prim.name"
let identref = Gram.entry_create "Prim.identref"
@@ -305,17 +295,17 @@ module Prim =
module Constr =
struct
- let gec_constr = make_gen_entry uconstr (rawwit wit_constr)
+ let gec_constr = make_gen_entry uconstr
(* Entries that can be referred via the string -> Gram.entry table *)
let constr = gec_constr "constr"
let operconstr = gec_constr "operconstr"
let constr_eoi = eoi_entry constr
let lconstr = gec_constr "lconstr"
- let binder_constr = create_constr_entry "binder_constr"
- let ident = make_gen_entry uconstr (rawwit wit_ident) "ident"
- let global = make_gen_entry uconstr (rawwit wit_ref) "global"
- let sort = make_gen_entry uconstr (rawwit wit_sort) "sort"
+ let binder_constr = gec_constr "binder_constr"
+ let ident = make_gen_entry uconstr "ident"
+ let global = make_gen_entry uconstr "global"
+ let sort = make_gen_entry uconstr "sort"
let pattern = Gram.entry_create "constr:pattern"
let constr_pattern = gec_constr "constr_pattern"
let lconstr_pattern = gec_constr "lconstr_pattern"
@@ -343,39 +333,36 @@ module Tactic =
(* Entries that can be referred via the string -> Gram.entry table *)
(* Typically for tactic user extensions *)
let open_constr =
- make_gen_entry utactic (rawwit wit_open_constr) "open_constr"
+ make_gen_entry utactic "open_constr"
let constr_with_bindings =
- make_gen_entry utactic (rawwit wit_constr_with_bindings) "constr_with_bindings"
+ make_gen_entry utactic "constr_with_bindings"
let bindings =
- make_gen_entry utactic (rawwit wit_bindings) "bindings"
+ make_gen_entry utactic "bindings"
let hypident = Gram.entry_create "hypident"
- let constr_may_eval = make_gen_entry utactic (rawwit wit_constr_may_eval) "constr_may_eval"
- let constr_eval = make_gen_entry utactic (rawwit wit_constr_may_eval) "constr_eval"
+ let constr_may_eval = make_gen_entry utactic "constr_may_eval"
+ let constr_eval = make_gen_entry utactic "constr_eval"
let uconstr =
- make_gen_entry utactic (rawwit wit_uconstr) "uconstr"
+ make_gen_entry utactic "uconstr"
let quantified_hypothesis =
- make_gen_entry utactic (rawwit wit_quant_hyp) "quantified_hypothesis"
- let int_or_var = make_gen_entry utactic (rawwit wit_int_or_var) "int_or_var"
- let red_expr = make_gen_entry utactic (rawwit wit_red_expr) "red_expr"
+ make_gen_entry utactic "quantified_hypothesis"
+ let int_or_var = make_gen_entry utactic "int_or_var"
+ let red_expr = make_gen_entry utactic "red_expr"
let simple_intropattern =
- make_gen_entry utactic (rawwit wit_intro_pattern) "simple_intropattern"
+ make_gen_entry utactic "simple_intropattern"
let clause_dft_concl =
- make_gen_entry utactic (rawwit wit_clause_dft_concl) "clause"
+ make_gen_entry utactic "clause"
(* Main entries for ltac *)
let tactic_arg = Gram.entry_create "tactic:tactic_arg"
- let tactic_expr = make_gen_entry utactic (rawwit wit_tactic) "tactic_expr"
- let binder_tactic = make_gen_entry utactic (rawwit wit_tactic) "binder_tactic"
+ let tactic_expr = make_gen_entry utactic "tactic_expr"
+ let binder_tactic = make_gen_entry utactic "binder_tactic"
- let tactic = make_gen_entry utactic (rawwit wit_tactic) "tactic"
+ let tactic = make_gen_entry utactic "tactic"
(* Main entry for quotations *)
let tactic_eoi = eoi_entry tactic
- (* For Ltac definition *)
- let tacdef_body = Gram.entry_create "tactic:tacdef_body"
-
end
module Vernac_ =
@@ -392,6 +379,7 @@ module Vernac_ =
let rec_definition = gec_vernac "Vernac.rec_definition"
(* Main vernac entry *)
let main_entry = Gram.entry_create "vernac"
+ let noedit_mode = gec_vernac "noedit_command"
let () =
let act_vernac = Gram.action (fun v loc -> Some (!@loc, v)) in
@@ -402,454 +390,134 @@ module Vernac_ =
] in
maybe_uncurry (Gram.extend main_entry) (None, make_rule rule)
+ let command_entry_ref = ref noedit_mode
+ let command_entry =
+ Gram.Entry.of_parser "command_entry"
+ (fun strm -> Gram.parse_tokens_after_filter !command_entry_ref strm)
+
end
let main_entry = Vernac_.main_entry
-(**********************************************************************)
-(* This determines (depending on the associativity of the current
- level and on the expected associativity) if a reference to constr_n is
- a reference to the current level (to be translated into "SELF" on the
- left border and into "constr LEVEL n" elsewhere), to the level below
- (to be translated into "NEXT") or to an below wrt associativity (to be
- translated in camlp4 into "constr" without level) or to another level
- (to be translated into "constr LEVEL n")
-
- The boolean is true if the entry was existing _and_ empty; this to
- circumvent a weakness of camlp4/camlp5 whose undo mechanism is not the
- converse of the extension mechanism *)
-
-let constr_level = string_of_int
-
-let default_levels =
- [200,Extend.RightA,false;
- 100,Extend.RightA,false;
- 99,Extend.RightA,true;
- 10,Extend.RightA,false;
- 9,Extend.RightA,false;
- 8,Extend.RightA,true;
- 1,Extend.LeftA,false;
- 0,Extend.RightA,false]
-
-let default_pattern_levels =
- [200,Extend.RightA,true;
- 100,Extend.RightA,false;
- 99,Extend.RightA,true;
- 11,Extend.LeftA,false;
- 10,Extend.RightA,false;
- 1,Extend.LeftA,false;
- 0,Extend.RightA,false]
-
-let level_stack =
- ref [(default_levels, default_pattern_levels)]
-
-(* At a same level, LeftA takes precedence over RightA and NoneA *)
-(* In case, several associativity exists for a level, we make two levels, *)
-(* first LeftA, then RightA and NoneA together *)
-
-let admissible_assoc = function
- | Extend.LeftA, Some (Extend.RightA | Extend.NonA) -> false
- | Extend.RightA, Some Extend.LeftA -> false
- | _ -> true
-
-let create_assoc = function
- | None -> Extend.RightA
- | Some a -> a
-
-let error_level_assoc p current expected =
- let pr_assoc = function
- | Extend.LeftA -> str "left"
- | Extend.RightA -> str "right"
- | Extend.NonA -> str "non" in
- errorlabstrm ""
- (str "Level " ++ int p ++ str " is already declared " ++
- pr_assoc current ++ str " associative while it is now expected to be " ++
- pr_assoc expected ++ str " associative.")
-
-let create_pos = function
- | None -> Extend.First
- | Some lev -> Extend.After (constr_level lev)
-
-let find_position_gen forpat ensure assoc lev =
- let ccurrent,pcurrent as current = List.hd !level_stack in
- match lev with
- | None ->
- level_stack := current :: !level_stack;
- None, None, None, None
- | Some n ->
- let after = ref None in
- let init = ref None in
- let rec add_level q = function
- | (p,_,_ as pa)::l when p > n -> pa :: add_level (Some p) l
- | (p,a,reinit)::l when Int.equal p n ->
- if reinit then
- let a' = create_assoc assoc in
- (init := Some (a',create_pos q); (p,a',false)::l)
- else if admissible_assoc (a,assoc) then
- raise Exit
- else
- error_level_assoc p a (Option.get assoc)
- | l -> after := q; (n,create_assoc assoc,ensure)::l
- in
- try
- let updated =
- if forpat then (ccurrent, add_level None pcurrent)
- else (add_level None ccurrent, pcurrent) in
- level_stack := updated:: !level_stack;
- let assoc = create_assoc assoc in
- begin match !init with
- | None ->
- (* Create the entry *)
- Some (create_pos !after), Some assoc, Some (constr_level n), None
- | _ ->
- (* The reinit flag has been updated *)
- Some (Extend.Level (constr_level n)), None, None, !init
- end
- with
- (* Nothing has changed *)
- Exit ->
- level_stack := current :: !level_stack;
- (* Just inherit the existing associativity and name (None) *)
- Some (Extend.Level (constr_level n)), None, None, None
-
-let remove_levels n =
- level_stack := List.skipn n !level_stack
-
-let rec list_mem_assoc_triple x = function
- | [] -> false
- | (a,b,c) :: l -> Int.equal a x || list_mem_assoc_triple x l
-
-let register_empty_levels forpat levels =
- let filter n =
- try
- let levels = (if forpat then snd else fst) (List.hd !level_stack) in
- if not (list_mem_assoc_triple n levels) then
- Some (find_position_gen forpat true None (Some n))
- else None
- with Failure _ -> None
- in
- List.map_filter filter levels
-
-let find_position forpat assoc level =
- find_position_gen forpat false assoc level
-
-(* Synchronise the stack of level updates *)
-let synchronize_level_positions () =
- let _ = find_position true None None in ()
-
-(**********************************************************************)
-(* Binding constr entry keys to entries *)
-
-(* Camlp4 levels do not treat NonA: use RightA with a NEXT on the left *)
-let camlp4_assoc = function
- | Some Extend.NonA | Some Extend.RightA -> Extend.RightA
- | None | Some Extend.LeftA -> Extend.LeftA
-
-let assoc_eq al ar = match al, ar with
-| Extend.NonA, Extend.NonA
-| Extend.RightA, Extend.RightA
-| Extend.LeftA, Extend.LeftA -> true
-| _, _ -> false
-
-(* [adjust_level assoc from prod] where [assoc] and [from] are the name
- and associativity of the level where to add the rule; the meaning of
- the result is
-
- None = SELF
- Some None = NEXT
- Some (Some (n,cur)) = constr LEVEL n
- s.t. if [cur] is set then [n] is the same as the [from] level *)
-let adjust_level assoc from = function
-(* Associativity is None means force the level *)
- | (NumLevel n,BorderProd (_,None)) -> Some (Some (n,true))
-(* Compute production name on the right side *)
- (* If NonA or LeftA on the right-hand side, set to NEXT *)
- | (NumLevel n,BorderProd (Right,Some (Extend.NonA|Extend.LeftA))) ->
- Some None
- (* If RightA on the right-hand side, set to the explicit (current) level *)
- | (NumLevel n,BorderProd (Right,Some Extend.RightA)) ->
- Some (Some (n,true))
-(* Compute production name on the left side *)
- (* If NonA on the left-hand side, adopt the current assoc ?? *)
- | (NumLevel n,BorderProd (Left,Some Extend.NonA)) -> None
- (* If the expected assoc is the current one, set to SELF *)
- | (NumLevel n,BorderProd (Left,Some a)) when assoc_eq a (camlp4_assoc assoc) ->
- None
- (* Otherwise, force the level, n or n-1, according to expected assoc *)
- | (NumLevel n,BorderProd (Left,Some a)) ->
- begin match a with
- | Extend.LeftA -> Some (Some (n, true))
- | _ -> Some None
- end
- (* None means NEXT *)
- | (NextLevel,_) -> Some None
-(* Compute production name elsewhere *)
- | (NumLevel n,InternalProd) ->
- match from with
- | ETConstr (p,()) when Int.equal p (n + 1) -> Some None
- | ETConstr (p,()) -> Some (Some (n, Int.equal n p))
- | _ -> Some (Some (n,false))
-
-let compute_entry allow_create adjust forpat = function
- | ETConstr (n,q) ->
- (if forpat then weaken_entry Constr.pattern
- else weaken_entry Constr.operconstr),
- adjust (n,q), false
- | ETName -> weaken_entry Prim.name, None, false
- | ETBinder true -> anomaly (Pp.str "Should occur only as part of BinderList")
- | ETBinder false -> weaken_entry Constr.binder, None, false
- | ETBinderList (true,tkl) ->
- let () = match tkl with [] -> () | _ -> assert false in
- weaken_entry Constr.open_binders, None, false
- | ETBinderList (false,_) -> anomaly (Pp.str "List of entries cannot be registered.")
- | ETBigint -> weaken_entry Prim.bigint, None, false
- | ETReference -> weaken_entry Constr.global, None, false
- | ETPattern -> weaken_entry Constr.pattern, None, false
- | ETConstrList _ -> anomaly (Pp.str "List of entries cannot be registered.")
- | ETOther (u,n) ->
- let u = get_univ u in
- let e =
- try get_entry u n
- with Not_found when allow_create ->
- let wit = rawwit wit_constr in
- TypedEntry (wit, create_entry u n wit)
- in
- object_of_typed_entry e, None, true
-
-(* This computes the name of the level where to add a new rule *)
-let interp_constr_entry_key forpat = function
- | ETConstr(200,()) when not forpat ->
- weaken_entry Constr.binder_constr, None
- | e ->
- let (e,level,_) = compute_entry true (fun (n,()) -> Some n) forpat e in
- (e, level)
-
-(* This computes the name to give to a production knowing the name and
- associativity of the level where it must be added *)
-let interp_constr_prod_entry_key ass from forpat en =
- compute_entry false (adjust_level ass from) forpat en
-
-(**********************************************************************)
-(* Binding constr entry keys to symbols *)
-
-let is_self from e =
- match from, e with
- ETConstr(n,()), ETConstr(NumLevel n',
- BorderProd(Right, _ (* Some(NonA|LeftA) *))) -> false
- | ETConstr(n,()), ETConstr(NumLevel n',BorderProd(Left,_)) -> Int.equal n n'
- | (ETName,ETName | ETReference, ETReference | ETBigint,ETBigint
- | ETPattern, ETPattern) -> true
- | ETOther(s1,s2), ETOther(s1',s2') ->
- String.equal s1 s1' && String.equal s2 s2'
- | _ -> false
-
-let is_binder_level from e =
- match from, e with
- ETConstr(200,()),
- ETConstr(NumLevel 200,(BorderProd(Right,_)|InternalProd)) -> true
- | _ -> false
-
-let make_sep_rules tkl =
- Gram.srules'
- [List.map gram_token_of_token tkl,
- List.fold_right (fun _ v -> Gram.action (fun _ -> v)) tkl
- (Gram.action (fun loc -> ()))]
-
-let rec symbol_of_constr_prod_entry_key assoc from forpat typ =
- if is_binder_level from typ then
- if forpat then
- Symbols.snterml (Gram.Entry.obj Constr.pattern,"200")
- else
- Symbols.snterml (Gram.Entry.obj Constr.operconstr,"200")
- else if is_self from typ then
- Symbols.sself
- else
- match typ with
- | ETConstrList (typ',[]) ->
- Symbols.slist1 (symbol_of_constr_prod_entry_key assoc from forpat (ETConstr typ'))
- | ETConstrList (typ',tkl) ->
- Symbols.slist1sep
- (symbol_of_constr_prod_entry_key assoc from forpat (ETConstr typ'),
- make_sep_rules tkl)
- | ETBinderList (false,[]) ->
- Symbols.slist1
- (symbol_of_constr_prod_entry_key assoc from forpat (ETBinder false))
- | ETBinderList (false,tkl) ->
- Symbols.slist1sep
- (symbol_of_constr_prod_entry_key assoc from forpat (ETBinder false),
- make_sep_rules tkl)
-
- | _ ->
- match interp_constr_prod_entry_key assoc from forpat typ with
- | (eobj,None,_) -> Symbols.snterm (Gram.Entry.obj eobj)
- | (eobj,Some None,_) -> Symbols.snext
- | (eobj,Some (Some (lev,cur)),_) ->
- Symbols.snterml (Gram.Entry.obj eobj,constr_level lev)
+let set_command_entry e = Vernac_.command_entry_ref := e
+let get_command_entry () = !Vernac_.command_entry_ref
-(** Binding general entry keys to symbol *)
+let epsilon_value f e =
+ let r = Rule (Next (Stop, e), fun x _ -> f x) in
+ let ext = of_coq_extend_statement (None, [None, None, [r]]) in
+ let entry = G.entry_create "epsilon" in
+ let () = maybe_uncurry (G.extend entry) ext in
+ try Some (parse_string entry "") with _ -> None
-let rec symbol_of_prod_entry_key : type s a. (s, a) entry_key -> _ = function
- | Atoken t -> Symbols.stoken t
- | Alist1 s -> Symbols.slist1 (symbol_of_prod_entry_key s)
- | Alist1sep (s,sep) ->
- Symbols.slist1sep (symbol_of_prod_entry_key s, gram_token_of_string sep)
- | Alist0 s -> Symbols.slist0 (symbol_of_prod_entry_key s)
- | Alist0sep (s,sep) ->
- Symbols.slist0sep (symbol_of_prod_entry_key s, gram_token_of_string sep)
- | Aopt s -> Symbols.sopt (symbol_of_prod_entry_key s)
- | Amodifiers s ->
- Gram.srules'
- [([], Gram.action (fun _loc -> []));
- ([gram_token_of_string "(";
- Symbols.slist1sep (symbol_of_prod_entry_key s, gram_token_of_string ",");
- gram_token_of_string ")"],
- Gram.action (fun _ l _ _loc -> l))]
- | Aself -> Symbols.sself
- | Anext -> Symbols.snext
- | Aentry e ->
- let e = get_typed_entry e in
- Symbols.snterm (Gram.Entry.obj (object_of_typed_entry e))
- | Aentryl (e, n) ->
- let e = get_typed_entry e in
- Symbols.snterml (Gram.Entry.obj (object_of_typed_entry e), string_of_int n)
+(** Synchronized grammar extensions *)
-let level_of_snterml e = int_of_string (Symbols.snterml_level e)
+module GramState = Store.Make(struct end)
-let rec of_coq_rule : type self a r. (self, a, r) Extend.rule -> _ = function
-| Stop -> fun accu -> accu
-| Next (r, tok) -> fun accu ->
- let symb = symbol_of_prod_entry_key tok in
- of_coq_rule r (symb :: accu)
+type 'a grammar_extension = 'a -> GramState.t -> extend_rule list * GramState.t
-let rec of_coq_action : type a r. (r, a, Loc.t -> r) Extend.rule -> a -> Gram.action = function
-| Stop -> fun f -> Gram.action (fun loc -> f (to_coqloc loc))
-| Next (r, _) -> fun f -> Gram.action (fun x -> of_coq_action r (f x))
+module GrammarCommand = Dyn.Make(struct end)
+module GrammarInterp = struct type 'a t = 'a grammar_extension end
+module GrammarInterpMap = GrammarCommand.Map(GrammarInterp)
-let of_coq_production_rule : type a. a Extend.production_rule -> _ = function
-| Rule (toks, act) -> (of_coq_rule toks [], of_coq_action toks act)
+let grammar_interp = ref GrammarInterpMap.empty
-let of_coq_single_extend_statement (lvl, assoc, rule) =
- (lvl, Option.map of_coq_assoc assoc, List.map of_coq_production_rule rule)
+let (grammar_stack : (int * GrammarCommand.t * GramState.t) list ref) = ref []
-let of_coq_extend_statement (pos, st) =
- (Option.map of_coq_position pos, List.map of_coq_single_extend_statement st)
+type 'a grammar_command = 'a GrammarCommand.tag
-let grammar_extend e reinit ext =
- let ext = of_coq_extend_statement ext in
- unsafe_grammar_extend e reinit ext
-
-(**********************************************************************)
-(* Interpret entry names of the form "ne_constr_list" as entry keys *)
-
-let coincide s pat off =
- let len = String.length pat in
- let break = ref true in
- let i = ref 0 in
- while !break && !i < len do
- let c = Char.code s.[off + !i] in
- let d = Char.code pat.[!i] in
- break := Int.equal c d;
- incr i
- done;
- !break
-
-let name_of_entry e = match String.split ':' (Gram.Entry.name e) with
-| u :: s :: [] -> Entry.unsafe_of_name (u, s)
-| _ -> assert false
-
-let atactic n =
- if n = 5 then Aentry (name_of_entry Tactic.binder_tactic)
- else Aentryl (name_of_entry Tactic.tactic_expr, n)
-
-let try_get_entry u s =
- (** Order the effects: get_entry can raise Not_found *)
- let TypedEntry (typ, _) = get_entry u s in
- EntryName (typ, Aentry (Entry.unsafe_of_name (Entry.univ_name u, s)))
-
-type _ target =
-| TgAny : 's target
-| TgTactic : int -> Tacexpr.raw_tactic_expr target
-
-(** Quite ad-hoc *)
-let get_tacentry (type s) (n : int) (t : s target) : s entry_name = match t with
-| TgAny -> EntryName (rawwit wit_tactic, atactic n)
-| TgTactic m ->
- let check_lvl n =
- Int.equal m n
- && not (Int.equal m 5) (* Because tactic5 is at binder_tactic *)
- && not (Int.equal m 0) (* Because tactic0 is at simple_tactic *)
+let create_grammar_command name interp : _ grammar_command =
+ let obj = GrammarCommand.create name in
+ let () = grammar_interp := GrammarInterpMap.add obj interp !grammar_interp in
+ obj
+
+let extend_grammar_command tag g =
+ let modify = GrammarInterpMap.find tag !grammar_interp in
+ let grammar_state = match !grammar_stack with
+ | [] -> GramState.empty
+ | (_, _, st) :: _ -> st
in
- if check_lvl n then EntryName (rawwit wit_tactic, Aself)
- else if check_lvl (n + 1) then EntryName (rawwit wit_tactic, Anext)
- else EntryName (rawwit wit_tactic, atactic n)
-
-let rec parse_user_entry s sep =
- let l = String.length s in
- if l > 8 && coincide s "ne_" 0 && coincide s "_list" (l - 5) then
- let entry = parse_user_entry (String.sub s 3 (l-8)) "" in
- Ulist1 entry
- else if l > 12 && coincide s "ne_" 0 &&
- coincide s "_list_sep" (l-9) then
- let entry = parse_user_entry (String.sub s 3 (l-12)) "" in
- Ulist1sep (entry, sep)
- else if l > 5 && coincide s "_list" (l-5) then
- let entry = parse_user_entry (String.sub s 0 (l-5)) "" in
- Ulist0 entry
- else if l > 9 && coincide s "_list_sep" (l-9) then
- let entry = parse_user_entry (String.sub s 0 (l-9)) "" in
- Ulist0sep (entry, sep)
- else if l > 4 && coincide s "_opt" (l-4) then
- let entry = parse_user_entry (String.sub s 0 (l-4)) "" in
- Uopt entry
- else if l > 5 && coincide s "_mods" (l-5) then
- let entry = parse_user_entry (String.sub s 0 (l-1)) "" in
- Umodifiers entry
- else if Int.equal l 7 && coincide s "tactic" 0 && '5' >= s.[6] && s.[6] >= '0' then
- let n = Char.code s.[6] - 48 in
- Uentryl ("tactic", n)
- else
- let s = match s with "hyp" -> "var" | _ -> s in
- Uentry s
-
-let arg_list = function Rawwit t -> Rawwit (ListArg t)
-let arg_opt = function Rawwit t -> Rawwit (OptArg t)
-
-let rec interp_entry_name up_level s sep =
- let rec eval = function
- | Ulist1 e ->
- let EntryName (t, g) = eval e in
- EntryName (arg_list t, Alist1 g)
- | Ulist1sep (e, sep) ->
- let EntryName (t, g) = eval e in
- EntryName (arg_list t, Alist1sep (g, sep))
- | Ulist0 e ->
- let EntryName (t, g) = eval e in
- EntryName (arg_list t, Alist0 g)
- | Ulist0sep (e, sep) ->
- let EntryName (t, g) = eval e in
- EntryName (arg_list t, Alist0sep (g, sep))
- | Uopt e ->
- let EntryName (t, g) = eval e in
- EntryName (arg_opt t, Aopt g)
- | Umodifiers e ->
- let EntryName (t, g) = eval e in
- EntryName (arg_list t, Amodifiers g)
- | Uentry s ->
- begin
- try try_get_entry uprim s with Not_found ->
- try try_get_entry uconstr s with Not_found ->
- try try_get_entry utactic s with Not_found ->
- error ("Unknown entry "^s^".")
- end
- | Uentryl (s, n) ->
- (** FIXME: do better someday *)
- assert (String.equal s "tactic");
- get_tacentry n up_level
+ let (rules, st) = modify g grammar_state in
+ let iter (ExtendRule (e, reinit, ext)) = grammar_extend_sync e reinit ext in
+ let () = List.iter iter rules in
+ let nb = List.length rules in
+ grammar_stack := (nb, GrammarCommand.Dyn (tag, g), st) :: !grammar_stack
+
+let recover_grammar_command (type a) (tag : a grammar_command) : a list =
+ let filter : _ -> a option = fun (_, GrammarCommand.Dyn (tag', v), _) ->
+ match GrammarCommand.eq tag tag' with
+ | None -> None
+ | Some Refl -> Some v
in
- eval (parse_user_entry s sep)
-
-let list_entry_names () =
- let add_entry key (TypedEntry (entry, _)) accu = (key, unquote entry) :: accu in
- let ans = Hashtbl.fold add_entry (get_utable uprim) [] in
- let ans = Hashtbl.fold add_entry (get_utable uconstr) ans in
- Hashtbl.fold add_entry (get_utable utactic) ans
+ List.map_filter filter !grammar_stack
+
+let extend_dyn_grammar (GrammarCommand.Dyn (tag, g)) = extend_grammar_command tag g
+
+(* Summary functions: the state of the lexer is included in that of the parser.
+ Because the grammar affects the set of keywords when adding or removing
+ grammar rules. *)
+type frozen_t = (int * GrammarCommand.t * GramState.t) list * CLexer.frozen_t
+
+let freeze _ : frozen_t = (!grammar_stack, CLexer.freeze ())
+
+(* We compare the current state of the grammar and the state to unfreeze,
+ by computing the longest common suffixes *)
+let factorize_grams l1 l2 =
+ if l1 == l2 then ([], [], l1) else List.share_tails l1 l2
+
+let number_of_entries gcl =
+ List.fold_left (fun n (p,_,_) -> n + p) 0 gcl
+
+let unfreeze (grams, lex) =
+ let (undo, redo, common) = factorize_grams !grammar_stack grams in
+ let n = number_of_entries undo in
+ remove_grammars n;
+ grammar_stack := common;
+ CLexer.unfreeze lex;
+ List.iter extend_dyn_grammar (List.rev_map pi2 redo)
+
+(** No need to provide an init function : the grammar state is
+ statically available, and already empty initially, while
+ the lexer state should not be resetted, since it contains
+ keywords declared in g_*.ml4 *)
+
+let _ =
+ Summary.declare_summary "GRAMMAR_LEXER"
+ { Summary.freeze_function = freeze;
+ Summary.unfreeze_function = unfreeze;
+ Summary.init_function = Summary.nop }
+
+let with_grammar_rule_protection f x =
+ let fs = freeze false in
+ try let a = f x in unfreeze fs; a
+ with reraise ->
+ let reraise = Errors.push reraise in
+ let () = unfreeze fs in
+ iraise reraise
+
+(** Registering grammar of generic arguments *)
+
+let () =
+ let open Stdarg in
+ let open Constrarg in
+(* Grammar.register0 wit_unit; *)
+(* Grammar.register0 wit_bool; *)
+ Grammar.register0 wit_int (Prim.integer);
+ Grammar.register0 wit_string (Prim.string);
+ Grammar.register0 wit_pre_ident (Prim.preident);
+ Grammar.register0 wit_int_or_var (Tactic.int_or_var);
+ Grammar.register0 wit_intro_pattern (Tactic.simple_intropattern);
+ Grammar.register0 wit_ident (Prim.ident);
+ Grammar.register0 wit_var (Prim.var);
+ Grammar.register0 wit_ref (Prim.reference);
+ Grammar.register0 wit_quant_hyp (Tactic.quantified_hypothesis);
+ Grammar.register0 wit_constr (Constr.constr);
+ Grammar.register0 wit_uconstr (Tactic.uconstr);
+ Grammar.register0 wit_open_constr (Tactic.open_constr);
+ Grammar.register0 wit_constr_with_bindings (Tactic.constr_with_bindings);
+ Grammar.register0 wit_bindings (Tactic.bindings);
+(* Grammar.register0 wit_hyp_location_flag; *)
+ Grammar.register0 wit_red_expr (Tactic.red_expr);
+ Grammar.register0 wit_tactic (Tactic.tactic);
+ Grammar.register0 wit_ltac (Tactic.tactic);
+ Grammar.register0 wit_clause_dft_concl (Tactic.clause_dft_concl);
+ ()
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index b26c3044b..319ca256e 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -19,7 +19,7 @@ open Genredexpr
(** The parser of Coq *)
-module Gram : Compat.GrammarSig
+module Gram : module type of Compat.GrammarMake(CLexer)
(** The parser of Coq is built from three kinds of rule declarations:
@@ -96,49 +96,6 @@ module Gram : Compat.GrammarSig
*)
-val gram_token_of_token : Tok.t -> Gram.symbol
-val gram_token_of_string : string -> Gram.symbol
-
-(** The superclass of all grammar entries *)
-type grammar_object
-
-(** Type of reinitialization data *)
-type gram_reinit = gram_assoc * gram_position
-
-(** General entry keys *)
-
-(** This intermediate abstract representation of entries can
- both be reified into mlexpr for the ML extensions and
- dynamically interpreted as entries for the Coq level extensions
-*)
-
-type ('self, 'a) entry_key = ('self, 'a) Extend.symbol =
-| Atoken : Tok.t -> ('self, string) entry_key
-| Alist1 : ('self, 'a) entry_key -> ('self, 'a list) entry_key
-| Alist1sep : ('self, 'a) entry_key * string -> ('self, 'a list) entry_key
-| Alist0 : ('self, 'a) entry_key -> ('self, 'a list) entry_key
-| Alist0sep : ('self, 'a) entry_key * string -> ('self, 'a list) entry_key
-| Aopt : ('self, 'a) entry_key -> ('self, 'a option) entry_key
-| Amodifiers : ('self, 'a) entry_key -> ('self, 'a list) entry_key
-| Aself : ('self, 'self) entry_key
-| Anext : ('self, 'self) entry_key
-| Aentry : 'a Entry.t -> ('self, 'a) entry_key
-| Aentryl : 'a Entry.t * int -> ('self, 'a) entry_key
-
-(** Add one extension at some camlp4 position of some camlp4 entry *)
-val unsafe_grammar_extend :
- grammar_object Gram.entry ->
- gram_reinit option (** for reinitialization if ever needed *) ->
- Gram.extend_statment -> unit
-
-val grammar_extend :
- 'a Gram.entry ->
- gram_reinit option (** for reinitialization if ever needed *) ->
- 'a Extend.extend_statment -> unit
-
-(** Remove the last n extensions *)
-val remove_grammars : int -> unit
-
(** Temporary activate camlp4 verbosity *)
val camlp4_verbosity : bool -> ('a -> unit) -> 'a -> unit
@@ -149,21 +106,20 @@ val parse_string : 'a Gram.entry -> string -> 'a
val eoi_entry : 'a Gram.entry -> 'a Gram.entry
val map_entry : ('a -> 'b) -> 'a Gram.entry -> 'b Gram.entry
-type gram_universe = Entry.universe
+type gram_universe
val get_univ : string -> gram_universe
-type typed_entry = TypedEntry : 'a raw_abstract_argument_type * 'a Gram.entry -> typed_entry
-
val uprim : gram_universe
val uconstr : gram_universe
val utactic : gram_universe
val uvernac : gram_universe
-val get_entry : gram_universe -> string -> typed_entry
+val register_grammar : ('raw, 'glb, 'top) genarg_type -> 'raw Gram.entry -> unit
+val genarg_grammar : ('raw, 'glb, 'top) genarg_type -> 'raw Gram.entry
-val create_generic_entry : string -> ('a, rlevel) abstract_argument_type ->
- 'a Gram.entry
+val create_generic_entry : gram_universe -> string ->
+ ('a, rlevel) abstract_argument_type -> 'a Gram.entry
module Prim :
sig
@@ -242,7 +198,6 @@ module Tactic :
val binder_tactic : raw_tactic_expr Gram.entry
val tactic : raw_tactic_expr Gram.entry
val tactic_eoi : raw_tactic_expr Gram.entry
- val tacdef_body : Vernacexpr.tacdef_body Gram.entry
end
module Vernac_ :
@@ -254,54 +209,56 @@ module Vernac_ :
val vernac : vernac_expr Gram.entry
val rec_definition : (fixpoint_expr * decl_notation list) Gram.entry
val vernac_eoi : vernac_expr Gram.entry
+ val noedit_mode : vernac_expr Gram.entry
+ val command_entry : vernac_expr Gram.entry
end
(** The main entry: reads an optional vernac command *)
val main_entry : (Loc.t * vernac_expr) option Gram.entry
-(** Mapping formal entries into concrete ones *)
-
-(** Binding constr entry keys to entries and symbols *)
-
-val interp_constr_entry_key : bool (** true for cases_pattern *) ->
- constr_entry_key -> grammar_object Gram.entry * int option
-
-val symbol_of_constr_prod_entry_key : gram_assoc option ->
- constr_entry_key -> bool -> constr_prod_entry_key ->
- Gram.symbol
+(** Handling of the proof mode entry *)
+val get_command_entry : unit -> vernac_expr Gram.entry
+val set_command_entry : vernac_expr Gram.entry -> unit
-val name_of_entry : 'a Gram.entry -> 'a Entry.t
+val epsilon_value : ('a -> 'self) -> ('self, 'a) Extend.symbol -> 'self option
-(** Binding general entry keys to symbols *)
+(** {5 Extending the parser without synchronization} *)
-type 's entry_name = EntryName :
- 'a raw_abstract_argument_type * ('s, 'a) entry_key -> 's entry_name
-
-(** Interpret entry names of the form "ne_constr_list" as entry keys *)
+type gram_reinit = gram_assoc * gram_position
+(** Type of reinitialization data *)
-type _ target = TgAny : 's target | TgTactic : int -> raw_tactic_expr target
+val grammar_extend : 'a Gram.entry -> gram_reinit option ->
+ 'a Extend.extend_statment -> unit
+(** Extend the grammar of Coq, without synchronizing it with the bactracking
+ mechanism. This means that grammar extensions defined this way will survive
+ an undo. *)
-val interp_entry_name : 's target -> string -> string -> 's entry_name
+(** {5 Extending the parser with summary-synchronized commands} *)
-val parse_user_entry : string -> string -> user_symbol
+module GramState : Store.S
+(** Auxilliary state of the grammar. Any added data must be marshallable. *)
-(** Recover the list of all known tactic notation entries. *)
-val list_entry_names : unit -> (string * argument_type) list
+type 'a grammar_command
+(** Type of synchronized parsing extensions. The ['a] type should be
+ marshallable. *)
-(** Registering/resetting the level of a constr entry *)
+type extend_rule =
+| ExtendRule : 'a Gram.entry * gram_reinit option * 'a extend_statment -> extend_rule
-val find_position :
- bool (** true if for creation in pattern entry; false if in constr entry *) ->
- Extend.gram_assoc option -> int option ->
- Extend.gram_position option * Extend.gram_assoc option * string option *
- (** for reinitialization: *) gram_reinit option
+type 'a grammar_extension = 'a -> GramState.t -> extend_rule list * GramState.t
+(** Grammar extension entry point. Given some ['a] and a current grammar state,
+ such a function must produce the list of grammar extensions that will be
+ applied in the same order and kept synchronized w.r.t. the summary, together
+ with a new state. It should be pure. *)
-val synchronize_level_positions : unit -> unit
+val create_grammar_command : string -> 'a grammar_extension -> 'a grammar_command
+(** Create a new grammar-modifying command with the given name. The extension
+ function is called to generate the rules for a given data. *)
-val register_empty_levels : bool -> int list ->
- (Extend.gram_position option * Extend.gram_assoc option *
- string option * gram_reinit option) list
+val extend_grammar_command : 'a grammar_command -> 'a -> unit
+(** Extend the grammar of Coq with the given data. *)
-val remove_levels : int -> unit
+val recover_grammar_command : 'a grammar_command -> 'a list
+(** Recover the current stack of grammar extensions. *)
-val level_of_snterml : Gram.symbol -> int
+val with_grammar_rule_protection : ('a -> 'b) -> 'a -> 'b
diff --git a/parsing/tok.ml b/parsing/tok.ml
index 6b9008615..df7e7c2a6 100644
--- a/parsing/tok.ml
+++ b/parsing/tok.ml
@@ -8,6 +8,8 @@
(** The type of token for the Coq lexer and parser *)
+let string_equal (s1 : string) s2 = s1 = s2
+
type t =
| KEYWORD of string
| PATTERNIDENT of string
@@ -21,16 +23,16 @@ type t =
| EOI
let equal t1 t2 = match t1, t2 with
-| IDENT s1, KEYWORD s2 -> CString.equal s1 s2
-| KEYWORD s1, KEYWORD s2 -> CString.equal s1 s2
-| PATTERNIDENT s1, PATTERNIDENT s2 -> CString.equal s1 s2
-| IDENT s1, IDENT s2 -> CString.equal s1 s2
-| FIELD s1, FIELD s2 -> CString.equal s1 s2
-| INT s1, INT s2 -> CString.equal s1 s2
-| INDEX s1, INDEX s2 -> CString.equal s1 s2
-| STRING s1, STRING s2 -> CString.equal s1 s2
+| IDENT s1, KEYWORD s2 -> string_equal s1 s2
+| KEYWORD s1, KEYWORD s2 -> string_equal s1 s2
+| PATTERNIDENT s1, PATTERNIDENT s2 -> string_equal s1 s2
+| IDENT s1, IDENT s2 -> string_equal s1 s2
+| FIELD s1, FIELD s2 -> string_equal s1 s2
+| INT s1, INT s2 -> string_equal s1 s2
+| INDEX s1, INDEX s2 -> string_equal s1 s2
+| STRING s1, STRING s2 -> string_equal s1 s2
| LEFTQMARK, LEFTQMARK -> true
-| BULLET s1, BULLET s2 -> CString.equal s1 s2
+| BULLET s1, BULLET s2 -> string_equal s1 s2
| EOI, EOI -> true
| _ -> false
diff --git a/parsing/tok.mli b/parsing/tok.mli
index 416ce468e..54b747952 100644
--- a/parsing/tok.mli
+++ b/parsing/tok.mli
@@ -20,6 +20,7 @@ type t =
| BULLET of string
| EOI
+val equal : t -> t -> bool
val extract_string : t -> string
val to_string : t -> string
(* Needed to fit Camlp4 signature *)
diff --git a/plugins/btauto/btauto_plugin.mllib b/plugins/btauto/btauto_plugin.mlpack
index 319a9c302..2410f906a 100644
--- a/plugins/btauto/btauto_plugin.mllib
+++ b/plugins/btauto/btauto_plugin.mlpack
@@ -1,3 +1,2 @@
Refl_btauto
G_btauto
-Btauto_plugin_mod
diff --git a/plugins/btauto/refl_btauto.ml b/plugins/btauto/refl_btauto.ml
index 57eb80f5f..aee0bd856 100644
--- a/plugins/btauto/refl_btauto.ml
+++ b/plugins/btauto/refl_btauto.ml
@@ -12,7 +12,7 @@ let get_constant dir s = lazy (Coqlib.gen_constant contrib_name dir s)
let get_inductive dir s =
let glob_ref () = Coqlib.find_reference contrib_name ("Coq" :: dir) s in
- Lazy.lazy_from_fun (fun () -> Globnames.destIndRef (glob_ref ()))
+ Lazy.from_fun (fun () -> Globnames.destIndRef (glob_ref ()))
let decomp_term (c : Term.constr) =
Term.kind_of_term (Term.strip_outer_cast c)
diff --git a/plugins/cc/cc_plugin.mllib b/plugins/cc/cc_plugin.mlpack
index 1bcfc5378..27e903fd3 100644
--- a/plugins/cc/cc_plugin.mllib
+++ b/plugins/cc/cc_plugin.mlpack
@@ -2,4 +2,3 @@ Ccalgo
Ccproof
Cctac
G_congruence
-Cc_plugin_mod
diff --git a/plugins/cc/ccalgo.ml b/plugins/cc/ccalgo.ml
index 359157a4c..76db2f3c2 100644
--- a/plugins/cc/ccalgo.ml
+++ b/plugins/cc/ccalgo.ml
@@ -25,7 +25,7 @@ let init_size=5
let cc_verbose=ref false
let debug x =
- if !cc_verbose then msg_debug x
+ if !cc_verbose then Feedback.msg_debug (x ())
let _=
let gdopt=
@@ -154,11 +154,6 @@ let rec term_equal t1 t2 =
open Hashset.Combine
-let hash_sorts_family = function
-| InProp -> 0
-| InSet -> 1
-| InType -> 2
-
let rec hash_term = function
| Symb c -> combine 1 (hash_constr c)
| Product (s1, s2) -> combine3 2 (Sorts.hash s1) (Sorts.hash s2)
@@ -603,7 +598,7 @@ let add_inst state (inst,int_subst) =
Control.check_for_interrupt ();
if state.rew_depth > 0 then
if is_redundant state inst.qe_hyp_id int_subst then
- debug (str "discarding redundant (dis)equality")
+ debug (fun () -> str "discarding redundant (dis)equality")
else
begin
Identhash.add state.q_history inst.qe_hyp_id int_subst;
@@ -618,7 +613,7 @@ let add_inst state (inst,int_subst) =
state.rew_depth<-pred state.rew_depth;
if inst.qe_pol then
begin
- debug (
+ debug (fun () ->
(str "Adding new equality, depth="++ int state.rew_depth) ++ fnl () ++
(str " [" ++ Termops.print_constr prf ++ str " : " ++
pr_term s ++ str " == " ++ pr_term t ++ str "]"));
@@ -626,7 +621,7 @@ let add_inst state (inst,int_subst) =
end
else
begin
- debug (
+ debug (fun () ->
(str "Adding new disequality, depth="++ int state.rew_depth) ++ fnl () ++
(str " [" ++ Termops.print_constr prf ++ str " : " ++
pr_term s ++ str " <> " ++ pr_term t ++ str "]"));
@@ -657,7 +652,7 @@ let join_path uf i j=
min_path (down_path uf i [],down_path uf j [])
let union state i1 i2 eq=
- debug (str "Linking " ++ pr_idx_term state.uf i1 ++
+ debug (fun () -> str "Linking " ++ pr_idx_term state.uf i1 ++
str " and " ++ pr_idx_term state.uf i2 ++ str ".");
let r1= get_representative state.uf i1
and r2= get_representative state.uf i2 in
@@ -698,7 +693,7 @@ let union state i1 i2 eq=
let merge eq state = (* merge and no-merge *)
debug
- (str "Merging " ++ pr_idx_term state.uf eq.lhs ++
+ (fun () -> str "Merging " ++ pr_idx_term state.uf eq.lhs ++
str " and " ++ pr_idx_term state.uf eq.rhs ++ str ".");
let uf=state.uf in
let i=find uf eq.lhs
@@ -711,7 +706,7 @@ let merge eq state = (* merge and no-merge *)
let update t state = (* update 1 and 2 *)
debug
- (str "Updating term " ++ pr_idx_term state.uf t ++ str ".");
+ (fun () -> str "Updating term " ++ pr_idx_term state.uf t ++ str ".");
let (i,j) as sign = signature state.uf t in
let (u,v) = subterms state.uf t in
let rep = get_representative state.uf i in
@@ -773,7 +768,7 @@ let process_constructor_mark t i rep pac state =
let process_mark t m state =
debug
- (str "Processing mark for term " ++ pr_idx_term state.uf t ++ str ".");
+ (fun () -> str "Processing mark for term " ++ pr_idx_term state.uf t ++ str ".");
let i=find state.uf t in
let rep=get_representative state.uf i in
match m with
@@ -794,7 +789,7 @@ let check_disequalities state =
else (str "No", check_aux q)
in
let _ = debug
- (str "Checking if " ++ pr_idx_term state.uf dis.lhs ++ str " = " ++
+ (fun () -> str "Checking if " ++ pr_idx_term state.uf dis.lhs ++ str " = " ++
pr_idx_term state.uf dis.rhs ++ str " ... " ++ info) in
ans
| [] -> None
@@ -979,7 +974,7 @@ let find_instances state =
let pb_stack= init_pb_stack state in
let res =ref [] in
let _ =
- debug (str "Running E-matching algorithm ... ");
+ debug (fun () -> str "Running E-matching algorithm ... ");
try
while true do
Control.check_for_interrupt ();
@@ -990,7 +985,7 @@ let find_instances state =
!res
let rec execute first_run state =
- debug (str "Executing ... ");
+ debug (fun () -> str "Executing ... ");
try
while
Control.check_for_interrupt ();
@@ -1000,7 +995,7 @@ let rec execute first_run state =
None ->
if not(Int.Set.is_empty state.pa_classes) then
begin
- debug (str "First run was incomplete, completing ... ");
+ debug (fun () -> str "First run was incomplete, completing ... ");
complete state;
execute false state
end
@@ -1015,12 +1010,12 @@ let rec execute first_run state =
end
else
begin
- debug (str "Out of instances ... ");
+ debug (fun () -> str "Out of instances ... ");
None
end
else
begin
- debug (str "Out of depth ... ");
+ debug (fun () -> str "Out of depth ... ");
None
end
| Some dis -> Some
diff --git a/plugins/cc/ccalgo.mli b/plugins/cc/ccalgo.mli
index b73c8eef8..c7fa2f56f 100644
--- a/plugins/cc/ccalgo.mli
+++ b/plugins/cc/ccalgo.mli
@@ -120,7 +120,7 @@ val term_equal : term -> term -> bool
val constr_of_term : term -> constr
-val debug : Pp.std_ppcmds -> unit
+val debug : (unit -> Pp.std_ppcmds) -> unit
val forest : state -> forest
diff --git a/plugins/cc/ccproof.ml b/plugins/cc/ccproof.ml
index c188bf3bc..d2bbaf6a7 100644
--- a/plugins/cc/ccproof.ml
+++ b/plugins/cc/ccproof.ml
@@ -93,13 +93,13 @@ let pinject p c n a =
p_rule=Inject(p,c,n,a)}
let rec equal_proof uf i j=
- debug (str "equal_proof " ++ pr_idx_term uf i ++ brk (1,20) ++ pr_idx_term uf j);
+ debug (fun () -> str "equal_proof " ++ pr_idx_term uf i ++ brk (1,20) ++ pr_idx_term uf j);
if i=j then prefl (term uf i) else
let (li,lj)=join_path uf i j in
ptrans (path_proof uf i li) (psym (path_proof uf j lj))
and edge_proof uf ((i,j),eq)=
- debug (str "edge_proof " ++ pr_idx_term uf i ++ brk (1,20) ++ pr_idx_term uf j);
+ debug (fun () -> str "edge_proof " ++ pr_idx_term uf i ++ brk (1,20) ++ pr_idx_term uf j);
let pi=equal_proof uf i eq.lhs in
let pj=psym (equal_proof uf j eq.rhs) in
let pij=
@@ -115,7 +115,7 @@ and edge_proof uf ((i,j),eq)=
ptrans (ptrans pi pij) pj
and constr_proof uf i ipac=
- debug (str "constr_proof " ++ pr_idx_term uf i ++ brk (1,20));
+ debug (fun () -> str "constr_proof " ++ pr_idx_term uf i ++ brk (1,20));
let t=find_oldest_pac uf i ipac in
let eq_it=equal_proof uf i t in
if ipac.args=[] then
@@ -128,20 +128,20 @@ and constr_proof uf i ipac=
ptrans eq_it (pcongr p (prefl targ))
and path_proof uf i l=
- debug (str "path_proof " ++ pr_idx_term uf i ++ brk (1,20) ++ str "{" ++
+ debug (fun () -> str "path_proof " ++ pr_idx_term uf i ++ brk (1,20) ++ str "{" ++
(prlist_with_sep (fun () -> str ",") (fun ((_,j),_) -> int j) l) ++ str "}");
match l with
| [] -> prefl (term uf i)
| x::q->ptrans (path_proof uf (snd (fst x)) q) (edge_proof uf x)
and congr_proof uf i j=
- debug (str "congr_proof " ++ pr_idx_term uf i ++ brk (1,20) ++ pr_idx_term uf j);
+ debug (fun () -> str "congr_proof " ++ pr_idx_term uf i ++ brk (1,20) ++ pr_idx_term uf j);
let (i1,i2) = subterms uf i
and (j1,j2) = subterms uf j in
pcongr (equal_proof uf i1 j1) (equal_proof uf i2 j2)
and ind_proof uf i ipac j jpac=
- debug (str "ind_proof " ++ pr_idx_term uf i ++ brk (1,20) ++ pr_idx_term uf j);
+ debug (fun () -> str "ind_proof " ++ pr_idx_term uf i ++ brk (1,20) ++ pr_idx_term uf j);
let p=equal_proof uf i j
and p1=constr_proof uf i ipac
and p2=constr_proof uf j jpac in
diff --git a/plugins/cc/cctac.ml b/plugins/cc/cctac.ml
index b52f156a1..bd788a425 100644
--- a/plugins/cc/cctac.ml
+++ b/plugins/cc/cctac.ml
@@ -223,24 +223,9 @@ let make_prb gls depth additionnal_terms =
(* indhyps builds the array of arrays of constructor hyps for (ind largs) *)
-let build_projection intype outtype (cstr:pconstructor) special default gls=
- let env=pf_env gls in
- let (h,argv) = try destApp intype with DestKO -> (intype,[||]) in
- let ind,u=destInd h in
- let types=Inductiveops.arities_of_constructors env (ind,u) in
- let lp=Array.length types in
- let ci=pred (snd(fst cstr)) in
- let branch i=
- let ti= prod_appvect types.(i) argv in
- let rc=fst (decompose_prod_assum ti) in
- let head=
- if Int.equal i ci then special else default in
- it_mkLambda_or_LetIn head rc in
- let branches=Array.init lp branch in
- let casee=mkRel 1 in
- let pred=mkLambda(Anonymous,intype,outtype) in
- let case_info=make_case_info (pf_env gls) ind RegularStyle in
- let body= mkCase(case_info, pred, casee, branches) in
+let build_projection intype (cstr:pconstructor) special default gls=
+ let ci= (snd(fst cstr)) in
+ let body=Equality.build_selector (pf_env gls) (project gls) ci (mkRel 1) intype special default in
let id=pf_get_new_id (Id.of_string "t") gls in
mkLambda(Name id,intype,body)
@@ -322,7 +307,7 @@ let rec proof_tac p : unit Proofview.tactic =
let outtype = (* Termops.refresh_universes *) (type_of default) in
let special=mkRel (1+nargs-argind) in
let proj =
- Tacmach.New.of_old (build_projection intype outtype cstr special default) gl
+ Tacmach.New.of_old (build_projection intype cstr special default) gl
in
let injt=
app_global _f_equal [|intype;outtype;proj;ti;tj;_M 1|] in
@@ -391,7 +376,7 @@ let discriminate_tac (cstr,u as cstru) p =
let outtype = mkSort outtype in
let pred=mkLambda(Name xid,outtype,mkRel 1) in
let hid = Tacmach.New.of_old (pf_get_new_id (Id.of_string "Heq")) gl in
- let proj = Tacmach.New.of_old (build_projection intype outtype cstru trivial concl) gl in
+ let proj = Tacmach.New.of_old (build_projection intype cstru trivial concl) gl in
let injt=app_global _f_equal
[|intype;outtype;proj;t1;t2;mkVar hid|] in
let endt k =
@@ -416,16 +401,16 @@ let build_term_to_complete uf meta pac =
let cc_tactic depth additionnal_terms =
Proofview.Goal.nf_enter { enter = begin fun gl ->
Coqlib.check_required_library Coqlib.logic_module_name;
- let _ = debug (Pp.str "Reading subgoal ...") in
+ let _ = debug (fun () -> Pp.str "Reading subgoal ...") in
let state = Tacmach.New.of_old (fun gls -> make_prb gls depth additionnal_terms) gl in
- let _ = debug (Pp.str "Problem built, solving ...") in
+ let _ = debug (fun () -> Pp.str "Problem built, solving ...") in
let sol = execute true state in
- let _ = debug (Pp.str "Computation completed.") in
+ let _ = debug (fun () -> Pp.str "Computation completed.") in
let uf=forest state in
match sol with
None -> Tacticals.New.tclFAIL 0 (str "congruence failed")
| Some reason ->
- debug (Pp.str "Goal solved, generating proof ...");
+ debug (fun () -> Pp.str "Goal solved, generating proof ...");
match reason with
Discrimination (i,ipac,j,jpac) ->
let p=build_proof uf (`Discr (i,ipac,j,jpac)) in
@@ -439,10 +424,10 @@ let cc_tactic depth additionnal_terms =
List.map
(build_term_to_complete uf newmeta)
(epsilons uf) in
- Pp.msg_info
+ Feedback.msg_info
(Pp.str "Goal is solvable by congruence but \
some arguments are missing.");
- Pp.msg_info
+ Feedback.msg_info
(Pp.str " Try " ++
hov 8
begin
diff --git a/plugins/cc/g_congruence.ml4 b/plugins/cc/g_congruence.ml4
index 5dbc340ca..52a135119 100644
--- a/plugins/cc/g_congruence.ml4
+++ b/plugins/cc/g_congruence.ml4
@@ -9,6 +9,8 @@
(*i camlp4deps: "grammar/grammar.cma" i*)
open Cctac
+open Stdarg
+open Constrarg
DECLARE PLUGIN "cc_plugin"
diff --git a/plugins/decl_mode/decl_expr.mli b/plugins/decl_mode/decl_expr.mli
index 9d78a51ef..29ecb94ca 100644
--- a/plugins/decl_mode/decl_expr.mli
+++ b/plugins/decl_mode/decl_expr.mli
@@ -99,4 +99,4 @@ type proof_instr =
(Term.constr statement,
Term.constr,
proof_pattern,
- Genarg.Val.t) gen_proof_instr
+ Geninterp.Val.t) gen_proof_instr
diff --git a/plugins/decl_mode/decl_interp.ml b/plugins/decl_mode/decl_interp.ml
index 4874552d6..34307a358 100644
--- a/plugins/decl_mode/decl_interp.ml
+++ b/plugins/decl_mode/decl_interp.ml
@@ -96,7 +96,7 @@ let rec add_vars_of_simple_pattern globs = function
add_vars_of_simple_pattern globs p
| CPatCstr (_,_,pl1,pl2) ->
List.fold_left add_vars_of_simple_pattern
- (List.fold_left add_vars_of_simple_pattern globs pl1) pl2
+ (Option.fold_left (List.fold_left add_vars_of_simple_pattern) globs pl1) pl2
| CPatNotation(_,_,(pl,pll),pl') ->
List.fold_left add_vars_of_simple_pattern globs (List.flatten (pl::pl'::pll))
| CPatAtom (_,Some (Libnames.Ident (_,id))) -> add_var id globs
diff --git a/plugins/decl_mode/decl_mode_plugin.mllib b/plugins/decl_mode/decl_mode_plugin.mlpack
index 39342dbd1..1b84a0790 100644
--- a/plugins/decl_mode/decl_mode_plugin.mllib
+++ b/plugins/decl_mode/decl_mode_plugin.mlpack
@@ -3,4 +3,3 @@ Decl_interp
Decl_proof_instr
Ppdecl_proof
G_decl_mode
-Decl_mode_plugin_mod
diff --git a/plugins/decl_mode/decl_proof_instr.ml b/plugins/decl_mode/decl_proof_instr.ml
index 090b293f5..3fa600ac2 100644
--- a/plugins/decl_mode/decl_proof_instr.ml
+++ b/plugins/decl_mode/decl_proof_instr.ml
@@ -34,6 +34,22 @@ open Context.Named.Declaration
(* Strictness option *)
+let clear ids { it = goal; sigma } =
+ let ids = List.fold_left (fun accu x -> Id.Set.add x accu) Id.Set.empty ids in
+ let env = Goal.V82.env sigma goal in
+ let sign = Goal.V82.hyps sigma goal in
+ let cl = Goal.V82.concl sigma goal in
+ let evdref = ref (Evd.clear_metas sigma) in
+ let (hyps, concl) =
+ try Evarutil.clear_hyps_in_evi env evdref sign cl ids
+ with Evarutil.ClearDependencyError (id, _) ->
+ errorlabstrm "" (str "Cannot clear " ++ pr_id id)
+ in
+ let sigma = !evdref in
+ let (gl,ev,sigma) = Goal.V82.mk_goal sigma hyps concl (Goal.V82.extra sigma goal) in
+ let sigma = Goal.V82.partial_solution_to sigma goal gl ev in
+ { it = [gl]; sigma }
+
let get_its_info gls = get_info gls.sigma gls.it
let get_strictness,set_strictness =
@@ -153,7 +169,7 @@ let do_daimon () =
daimon_instr env p
end
in
- if not status then Pp.feedback Feedback.AddedAxiom else ()
+ if not status then Feedback.feedback Feedback.AddedAxiom else ()
(* post-instruction focus management *)
@@ -275,7 +291,7 @@ let justification tac gls=
error "Insufficient justification."
else
begin
- msg_warning (str "Insufficient justification.");
+ Feedback.msg_warning (str "Insufficient justification.");
daimon_tac gls
end) gls
@@ -469,7 +485,7 @@ let thus_tac c ctyp submetas gls =
Proofview.V82.of_tactic (exact_check proof) gls
else
let refiner = concl_refiner list proof gls in
- Tactics.refine refiner gls
+ Tacmach.refine refiner gls
(* general forward step *)
@@ -1273,11 +1289,11 @@ let rec execute_cases fix_name per_info tacnext args objs nhrec tree gls =
(fun id ->
hrec_for (out_name fix_name) per_info gls1 id)
recs in
- generalize hrecs gls1
+ Proofview.V82.of_tactic (generalize hrecs) gls1
end;
match bro with
None ->
- msg_warning (str "missing case");
+ Feedback.msg_warning (str "missing case");
tacnext (mkMeta 1)
| Some (sub_ids,tree) ->
let br_args =
@@ -1349,7 +1365,7 @@ let end_tac et2 gls =
(default_justification (List.map mkVar clauses))
| ET_Induction,EK_nodep ->
tclTHENLIST
- [generalize (pi.per_args@[pi.per_casee]);
+ [Proofview.V82.of_tactic (generalize (pi.per_args@[pi.per_casee]));
Proofview.V82.of_tactic (simple_induct (AnonHyp (succ (List.length pi.per_args))));
default_justification (List.map mkVar clauses)]
| ET_Case_analysis,EK_dep tree ->
@@ -1361,7 +1377,7 @@ let end_tac et2 gls =
(initial_instance_stack clauses) [pi.per_casee] 0 tree
| ET_Induction,EK_dep tree ->
let nargs = (List.length pi.per_args) in
- tclTHEN (generalize (pi.per_args@[pi.per_casee]))
+ tclTHEN (Proofview.V82.of_tactic (generalize (pi.per_args@[pi.per_casee])))
begin
fun gls0 ->
let fix_id =
@@ -1369,7 +1385,7 @@ let end_tac et2 gls =
let c_id =
pf_get_new_id (Id.of_string "_main_arg") gls0 in
tclTHENLIST
- [fix (Some fix_id) (succ nargs);
+ [Proofview.V82.of_tactic (fix (Some fix_id) (succ nargs));
tclDO nargs (Proofview.V82.of_tactic introf);
Proofview.V82.of_tactic (intro_mustbe_force c_id);
execute_cases (Name fix_id) pi
diff --git a/plugins/decl_mode/g_decl_mode.ml4 b/plugins/decl_mode/g_decl_mode.ml4
index b62cfd6ad..73d3d1bab 100644
--- a/plugins/decl_mode/g_decl_mode.ml4
+++ b/plugins/decl_mode/g_decl_mode.ml4
@@ -8,7 +8,8 @@
(*i camlp4deps: "grammar/grammar.cma" i*)
-open Util
+DECLARE PLUGIN "decl_mode_plugin"
+
open Compat
open Pp
open Decl_expr
@@ -24,17 +25,14 @@ open Ppdecl_proof
let pr_goal gs =
let (g,sigma) = Goal.V82.nf_evar (Tacmach.project gs) (Evd.sig_it gs) in
let env = Goal.V82.env sigma g in
- let preamb,thesis,penv,pc =
- (str " *** Declarative Mode ***" ++ fnl ()++fnl ()),
- (str "thesis := " ++ fnl ()),
- Printer.pr_context_of env sigma,
- Printer.pr_goal_concl_style_env env sigma (Goal.V82.concl sigma g)
- in
- preamb ++
- str" " ++ hv 0 (penv ++ fnl () ++
- str (Printer.emacs_str "") ++
- str "============================" ++ fnl () ++
- thesis ++ str " " ++ pc) ++ fnl ()
+ let concl = Goal.V82.concl sigma g in
+ let goal =
+ Printer.pr_context_of env sigma ++ cut () ++
+ str "============================" ++ cut () ++
+ str "thesis :=" ++ cut () ++
+ Printer.pr_goal_concl_style_env env sigma concl in
+ str " *** Declarative Mode ***" ++ fnl () ++ fnl () ++
+ str " " ++ v 0 goal
let pr_subgoals ?(pr_first=true) _ sigma _ _ _ gll =
match gll with
@@ -87,7 +85,7 @@ let vernac_proof_instr instr =
(* Only declared at raw level, because only used in vernac commands. *)
let wit_proof_instr : (raw_proof_instr, glob_proof_instr, proof_instr) Genarg.genarg_type =
- Genarg.make0 None "proof_instr"
+ Genarg.make0 "proof_instr"
(* We create a new parser entry [proof_mode]. The Declarative proof mode
will replace the normal parser entry for tactics with this one. *)
@@ -95,14 +93,14 @@ let proof_mode : vernac_expr Gram.entry =
Gram.entry_create "vernac:proof_command"
(* Auxiliary grammar entry. *)
let proof_instr : raw_proof_instr Gram.entry =
- Pcoq.create_generic_entry "proof_instr" (Genarg.rawwit wit_proof_instr)
+ Pcoq.create_generic_entry Pcoq.utactic "proof_instr" (Genarg.rawwit wit_proof_instr)
let _ = Pptactic.declare_extra_genarg_pprule wit_proof_instr
pr_raw_proof_instr pr_glob_proof_instr pr_proof_instr
let classify_proof_instr = function
| { instr = Pescape |Pend B_proof } -> VtProofMode "Classic", VtNow
- | _ -> VtProofStep false, VtLater
+ | _ -> Vernac_classifier.classify_as_proofstep
(* We use the VERNAC EXTEND facility with a custom non-terminal
to populate [proof_mode] with a new toplevel interpreter.
@@ -135,7 +133,7 @@ let _ =
set = begin fun () ->
(* We set the command non terminal to
[proof_mode] (which we just defined). *)
- G_vernac.set_command_entry proof_mode ;
+ Pcoq.set_command_entry proof_mode ;
(* We substitute the goal printer, by the one we built
for the proof mode. *)
Printer.set_printer_pr { Printer.default_printer_pr with
@@ -147,7 +145,7 @@ let _ =
reset = begin fun () ->
(* We restore the command non terminal to
[noedit_mode]. *)
- G_vernac.set_command_entry G_vernac.noedit_mode ;
+ Pcoq.set_command_entry Pcoq.Vernac_.noedit_mode ;
(* We restore the goal printer to default *)
Printer.set_printer_pr Printer.default_printer_pr
end
diff --git a/plugins/derive/derive_plugin.mllib b/plugins/derive/derive_plugin.mlpack
index 5ee0fc6da..5ee0fc6da 100644
--- a/plugins/derive/derive_plugin.mllib
+++ b/plugins/derive/derive_plugin.mlpack
diff --git a/plugins/derive/g_derive.ml4 b/plugins/derive/g_derive.ml4
index 18570a684..d4dc7e0ee 100644
--- a/plugins/derive/g_derive.ml4
+++ b/plugins/derive/g_derive.ml4
@@ -6,8 +6,12 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+open Constrarg
+
(*i camlp4deps: "grammar/grammar.cma" i*)
+DECLARE PLUGIN "derive_plugin"
+
let classify_derive_command _ = Vernacexpr.(VtStartProof ("Classic",Doesn'tGuaranteeOpacity,[]),VtLater)
VERNAC COMMAND EXTEND Derive CLASSIFIED BY classify_derive_command
diff --git a/plugins/extraction/ExtrOcamlZBigInt.v b/plugins/extraction/ExtrOcamlZBigInt.v
index 9a1a4aa01..c9e8eac0c 100644
--- a/plugins/extraction/ExtrOcamlZBigInt.v
+++ b/plugins/extraction/ExtrOcamlZBigInt.v
@@ -46,7 +46,7 @@ Extract Constant Pos.max => "Big.max".
Extract Constant Pos.compare =>
"fun x y -> Big.compare_case Eq Lt Gt x y".
Extract Constant Pos.compare_cont =>
- "fun x y c -> Big.compare_case c Lt Gt x y".
+ "fun c x y -> Big.compare_case c Lt Gt x y".
Extract Constant N.add => "Big.add".
Extract Constant N.succ => "Big.succ".
diff --git a/plugins/extraction/common.ml b/plugins/extraction/common.ml
index bb9e8e5f5..3c5f6cb72 100644
--- a/plugins/extraction/common.ml
+++ b/plugins/extraction/common.ml
@@ -17,8 +17,8 @@ open Table
open Miniml
open Mlutil
-let string_of_id id =
- let s = Names.Id.to_string id in
+let ascii_of_id id =
+ let s = Id.to_string id in
for i = 0 to String.length s - 2 do
if s.[i] == '_' && s.[i+1] == '_' then warning_id s
done;
@@ -73,18 +73,19 @@ let fnl2 () = fnl () ++ fnl ()
let space_if = function true -> str " " | false -> mt ()
-let is_digit = function
- | '0'..'9' -> true
- | _ -> false
+let begins_with s prefix =
+ let len = String.length prefix in
+ String.length s >= len && String.equal (String.sub s 0 len) prefix
let begins_with_CoqXX s =
let n = String.length s in
n >= 4 && s.[0] == 'C' && s.[1] == 'o' && s.[2] == 'q' &&
let i = ref 3 in
try while !i < n do
- if s.[!i] == '_' then i:=n (*Stop*)
- else if is_digit s.[!i] then incr i
- else raise Not_found
+ match s.[!i] with
+ | '_' -> i:=n (*Stop*)
+ | '0'..'9' -> incr i
+ | _ -> raise Not_found
done; true
with Not_found -> false
@@ -109,9 +110,9 @@ let pseudo_qualify = qualify "__"
let is_upper s = match s.[0] with 'A' .. 'Z' -> true | _ -> false
let is_lower s = match s.[0] with 'a' .. 'z' | '_' -> true | _ -> false
-let lowercase_id id = Id.of_string (String.uncapitalize (string_of_id id))
+let lowercase_id id = Id.of_string (String.uncapitalize (ascii_of_id id))
let uppercase_id id =
- let s = string_of_id id in
+ let s = ascii_of_id id in
assert (not (String.is_empty s));
if s.[0] == '_' then Id.of_string ("Coq_"^s)
else Id.of_string (String.capitalize s)
@@ -331,13 +332,10 @@ let reset_renaming_tables flag =
existing. *)
let modular_rename k id =
- let s = string_of_id id in
- let prefix,is_ok =
- if upperkind k then "Coq_",is_upper else "coq_",is_lower
+ let s = ascii_of_id id in
+ let prefix,is_ok = if upperkind k then "Coq_",is_upper else "coq_",is_lower
in
- if not (is_ok s) ||
- (Id.Set.mem id (get_keywords ())) ||
- (String.length s >= 4 && String.equal (String.sub s 0 4) prefix)
+ if not (is_ok s) || Id.Set.mem id (get_keywords ()) || begins_with s prefix
then prefix ^ s
else s
@@ -345,21 +343,20 @@ let modular_rename k id =
with unique numbers *)
let modfstlev_rename =
- let add_prefixes,get_prefixes,_ = mktable_id true in
+ let add_index,get_index,_ = mktable_id true in
fun l ->
- let coqid = Id.of_string "Coq" in
let id = Label.to_id l in
try
- let coqset = get_prefixes id in
- let nextcoq = next_ident_away coqid coqset in
- add_prefixes id (nextcoq::coqset);
- (string_of_id nextcoq)^"_"^(string_of_id id)
+ let n = get_index id in
+ add_index id (n+1);
+ let s = if n == 0 then "" else string_of_int (n-1) in
+ "Coq"^s^"_"^(ascii_of_id id)
with Not_found ->
- let s = string_of_id id in
+ let s = ascii_of_id id in
if is_lower s || begins_with_CoqXX s then
- (add_prefixes id [coqid]; "Coq_"^s)
+ (add_index id 1; "Coq_"^s)
else
- (add_prefixes id []; s)
+ (add_index id 0; s)
(*s Creating renaming for a [module_path] : first, the real function ... *)
@@ -404,7 +401,7 @@ let ref_renaming_fun (k,r) =
| [""] -> (* this happens only at toplevel of the monolithic case *)
let globs = Id.Set.elements (get_global_ids ()) in
let id = next_ident_away (kindcase_id k idg) globs in
- string_of_id id
+ Id.to_string id
| _ -> modular_rename k idg
in
add_global_ids (Id.of_string s);
@@ -562,7 +559,7 @@ let pp_ocaml_extern k base rls = match rls with
(* Standard situation : object in an opened file *)
dottify rls'
-(* [pp_ocaml_gen] : choosing between [pp_ocaml_extern] or [pp_ocaml_extern] *)
+(* [pp_ocaml_gen] : choosing between [pp_ocaml_local] or [pp_ocaml_extern] *)
let pp_ocaml_gen k mp rls olab =
match common_prefix_from_list mp (get_visible_mps ()) with
@@ -579,8 +576,7 @@ let pp_haskell_gen k mp rls = match rls with
| s::rls' ->
let str = pseudo_qualify rls' in
let str = if is_upper str && not (upperkind k) then ("_"^str) else str in
- let prf = if not (ModPath.equal (base_mp mp) (top_visible_mp ())) then s ^ "." else "" in
- prf ^ str
+ if ModPath.equal (base_mp mp) (top_visible_mp ()) then str else s^"."^str
(* Main name printing function for a reference *)
diff --git a/plugins/extraction/extract_env.ml b/plugins/extraction/extract_env.ml
index 41a068ff3..a03be5743 100644
--- a/plugins/extraction/extract_env.ml
+++ b/plugins/extraction/extract_env.ml
@@ -19,7 +19,6 @@ open Table
open Extraction
open Modutil
open Common
-open Mod_subst
(***************************************)
(*S Part I: computing Coq environment. *)
@@ -542,7 +541,7 @@ let print_structure_to_file (fn,si,mo) dry struc =
(if dry then None else si);
(* Print the buffer content via Coq standard formatter (ok with coqide). *)
if not (Int.equal (Buffer.length buf) 0) then begin
- Pp.msg_notice (str (Buffer.contents buf));
+ Feedback.msg_notice (str (Buffer.contents buf));
Buffer.reset buf
end
@@ -636,7 +635,7 @@ let simple_extraction r =
in
let ans = flag ++ print_one_decl struc (modpath_of_r r) d in
reset ();
- Pp.msg_notice ans
+ Feedback.msg_notice ans
| _ -> assert false
diff --git a/plugins/extraction/extraction.ml b/plugins/extraction/extraction.ml
index 6c57bc2bb..e40621965 100644
--- a/plugins/extraction/extraction.ml
+++ b/plugins/extraction/extraction.ml
@@ -35,17 +35,18 @@ let current_fixpoints = ref ([] : constant list)
let none = Evd.empty
+(* NB: In OCaml, [type_of] and [get_of] might raise
+ [SingletonInductiveBecomeProp]. this exception will be catched
+ in late wrappers around the exported functions of this file,
+ in order to display the location of the issue. *)
+
let type_of env c =
- try
- let polyprop = (lang() == Haskell) in
- Retyping.get_type_of ~polyprop env none (strip_outer_cast c)
- with SingletonInductiveBecomesProp id -> error_singleton_become_prop id
+ let polyprop = (lang() == Haskell) in
+ Retyping.get_type_of ~polyprop env none (strip_outer_cast c)
let sort_of env c =
- try
- let polyprop = (lang() == Haskell) in
- Retyping.get_sort_family_of ~polyprop env none (strip_outer_cast c)
- with SingletonInductiveBecomesProp id -> error_singleton_become_prop id
+ let polyprop = (lang() == Haskell) in
+ Retyping.get_sort_family_of ~polyprop env none (strip_outer_cast c)
(*S Generation of flags and signatures. *)
@@ -285,7 +286,7 @@ let rec extract_type env db j c args =
| Ind ((kn,i),u) ->
let s = (extract_ind env kn).ind_packets.(i).ip_sign in
extract_type_app env db (IndRef (kn,i),s) args
- | Case _ | Fix _ | CoFix _ -> Tunknown
+ | Case _ | Fix _ | CoFix _ | Proj _ -> Tunknown
| _ -> assert false
(*s Auxiliary function dealing with type application.
@@ -328,11 +329,22 @@ and extract_type_scheme env db c p =
(*S Extraction of an inductive type. *)
+(* First, a version with cache *)
+
and extract_ind env kn = (* kn is supposed to be in long form *)
let mib = Environ.lookup_mind kn env in
match lookup_ind kn mib with
| Some ml_ind -> ml_ind
| None ->
+ try
+ extract_really_ind env kn mib
+ with SingletonInductiveBecomesProp id ->
+ (* TODO : which inductive is concerned in the block ? *)
+ error_singleton_become_prop id (Some (IndRef (kn,0)))
+
+(* Then the real function *)
+
+and extract_really_ind env kn mib =
(* First, if this inductive is aliased via a Module,
we process the original inductive if possible.
When at toplevel of the monolithic case, we cannot do much
@@ -934,11 +946,13 @@ let extract_fixpoint env vkn (fi,ti,ci) =
(* for replacing recursive calls [Rel ..] by the corresponding [Const]: *)
let sub = List.rev_map mkConst kns in
for i = 0 to n-1 do
- if sort_of env ti.(i) != InProp then begin
- let e,t = extract_std_constant env vkn.(i) (substl sub ci.(i)) ti.(i) in
- terms.(i) <- e;
- types.(i) <- t;
- end
+ if sort_of env ti.(i) != InProp then
+ try
+ let e,t = extract_std_constant env vkn.(i) (substl sub ci.(i)) ti.(i) in
+ terms.(i) <- e;
+ types.(i) <- t;
+ with SingletonInductiveBecomesProp id ->
+ error_singleton_become_prop id (Some (ConstRef vkn.(i)))
done;
current_fixpoints := [];
Dfix (Array.map (fun kn -> ConstRef kn) vkn, terms, types)
@@ -968,13 +982,17 @@ let extract_constant env kn cb =
let e,t = extract_std_constant env kn c typ in
Dterm (r,e,t)
in
- match flag_of_type env typ with
+ try
+ match flag_of_type env typ with
| (Logic,TypeScheme) -> warn_log (); Dtype (r, [], Tdummy Ktype)
| (Logic,Default) -> warn_log (); Dterm (r, MLdummy Kprop, Tdummy Kprop)
| (Info,TypeScheme) ->
(match cb.const_body with
| Undef _ -> warn_info (); mk_typ_ax ()
- | Def c -> mk_typ (Mod_subst.force_constr c)
+ | Def c ->
+ (match cb.const_proj with
+ | None -> mk_typ (Mod_subst.force_constr c)
+ | Some pb -> mk_typ pb.proj_body)
| OpaqueDef c ->
add_opaque r;
if access_opaque () then
@@ -983,17 +1001,23 @@ let extract_constant env kn cb =
| (Info,Default) ->
(match cb.const_body with
| Undef _ -> warn_info (); mk_ax ()
- | Def c -> mk_def (Mod_subst.force_constr c)
+ | Def c ->
+ (match cb.const_proj with
+ | None -> mk_def (Mod_subst.force_constr c)
+ | Some pb -> mk_def pb.proj_body)
| OpaqueDef c ->
add_opaque r;
if access_opaque () then
mk_def (Opaqueproof.force_proof (Environ.opaque_tables env) c)
else mk_ax ())
+ with SingletonInductiveBecomesProp id ->
+ error_singleton_become_prop id (Some (ConstRef kn))
let extract_constant_spec env kn cb =
let r = ConstRef kn in
let typ = Typeops.type_of_constant_type env cb.const_type in
- match flag_of_type env typ with
+ try
+ match flag_of_type env typ with
| (Logic, TypeScheme) -> Stype (r, [], Some (Tdummy Ktype))
| (Logic, Default) -> Sval (r, Tdummy Kprop)
| (Info, TypeScheme) ->
@@ -1008,26 +1032,34 @@ let extract_constant_spec env kn cb =
| (Info, Default) ->
let t = snd (record_constant_type env kn (Some typ)) in
Sval (r, type_expunge env t)
+ with SingletonInductiveBecomesProp id ->
+ error_singleton_become_prop id (Some (ConstRef kn))
let extract_with_type env c =
- let typ = type_of env c in
- match flag_of_type env typ with
+ try
+ let typ = type_of env c in
+ match flag_of_type env typ with
| (Info, TypeScheme) ->
let s,vl = type_sign_vl env typ in
let db = db_from_sign s in
let t = extract_type_scheme env db c (List.length s) in
Some (vl, t)
| _ -> None
+ with SingletonInductiveBecomesProp id ->
+ error_singleton_become_prop id None
let extract_constr env c =
reset_meta_count ();
- let typ = type_of env c in
- match flag_of_type env typ with
+ try
+ let typ = type_of env c in
+ match flag_of_type env typ with
| (_,TypeScheme) -> MLdummy Ktype, Tdummy Ktype
| (Logic,_) -> MLdummy Kprop, Tdummy Kprop
| (Info,Default) ->
- let mlt = extract_type env [] 1 typ [] in
- extract_term env Mlenv.empty mlt c [], mlt
+ let mlt = extract_type env [] 1 typ [] in
+ extract_term env Mlenv.empty mlt c [], mlt
+ with SingletonInductiveBecomesProp id ->
+ error_singleton_become_prop id None
let extract_inductive env kn =
let ind = extract_ind env kn in
diff --git a/plugins/extraction/extraction_plugin.mllib b/plugins/extraction/extraction_plugin.mlpack
index ad3212434..9184f6501 100644
--- a/plugins/extraction/extraction_plugin.mllib
+++ b/plugins/extraction/extraction_plugin.mlpack
@@ -9,4 +9,3 @@ Scheme
Json
Extract_env
G_extraction
-Extraction_plugin_mod
diff --git a/plugins/extraction/g_extraction.ml4 b/plugins/extraction/g_extraction.ml4
index aec958689..19fda4aea 100644
--- a/plugins/extraction/g_extraction.ml4
+++ b/plugins/extraction/g_extraction.ml4
@@ -8,9 +8,14 @@
(*i camlp4deps: "grammar/grammar.cma" i*)
+DECLARE PLUGIN "extraction_plugin"
+
(* ML names *)
open Genarg
+open Stdarg
+open Constrarg
+open Pcoq.Prim
open Pp
open Names
open Nameops
@@ -31,7 +36,6 @@ let pr_int_or_id _ _ _ = function
| ArgId id -> pr_id id
ARGUMENT EXTEND int_or_id
- TYPED AS int_or_id
PRINTED BY pr_int_or_id
| [ preident(id) ] -> [ ArgId (Id.of_string id) ]
| [ integer(i) ] -> [ ArgInt i ]
@@ -99,7 +103,7 @@ END
VERNAC COMMAND EXTEND PrintExtractionInline CLASSIFIED AS QUERY
| [ "Print" "Extraction" "Inline" ]
- -> [ msg_info (print_extraction_inline ()) ]
+ -> [Feedback. msg_info (print_extraction_inline ()) ]
END
VERNAC COMMAND EXTEND ResetExtractionInline CLASSIFIED AS SIDEFF
@@ -121,7 +125,7 @@ END
VERNAC COMMAND EXTEND PrintExtractionBlacklist CLASSIFIED AS QUERY
| [ "Print" "Extraction" "Blacklist" ]
- -> [ msg_info (print_extraction_blacklist ()) ]
+ -> [ Feedback.msg_info (print_extraction_blacklist ()) ]
END
VERNAC COMMAND EXTEND ResetExtractionBlacklist CLASSIFIED AS SIDEFF
diff --git a/plugins/extraction/haskell.ml b/plugins/extraction/haskell.ml
index 22519e347..764223621 100644
--- a/plugins/extraction/haskell.ml
+++ b/plugins/extraction/haskell.ml
@@ -346,7 +346,7 @@ let pp_decl = function
in
if void then mt ()
else
- names.(i) ++ str " :: " ++ pp_type false [] typs.(i) ++ fnl () ++
+ hov 2 (names.(i) ++ str " :: " ++ pp_type false [] typs.(i)) ++ fnl () ++
(if is_custom r then
(names.(i) ++ str " = " ++ str (find_custom r))
else
@@ -357,7 +357,7 @@ let pp_decl = function
if is_inline_custom r then mt ()
else
let e = pp_global Term r in
- e ++ str " :: " ++ pp_type false [] t ++ fnl () ++
+ hov 2 (e ++ str " :: " ++ pp_type false [] t) ++ fnl () ++
if is_custom r then
hov 0 (e ++ str " = " ++ str (find_custom r) ++ fnl2 ())
else
diff --git a/plugins/extraction/json.ml b/plugins/extraction/json.ml
index df79c585e..8874afef3 100644
--- a/plugins/extraction/json.ml
+++ b/plugins/extraction/json.ml
@@ -1,8 +1,6 @@
open Pp
-open Errors
open Util
open Names
-open Nameops
open Globnames
open Table
open Miniml
@@ -18,9 +16,6 @@ let json_int i =
let json_bool b =
if b then str "true" else str "false"
-let json_null =
- str "null"
-
let json_global typ ref =
json_str (Common.pp_global typ ref)
diff --git a/plugins/extraction/modutil.ml b/plugins/extraction/modutil.ml
index b5e8b4804..bd4831130 100644
--- a/plugins/extraction/modutil.ml
+++ b/plugins/extraction/modutil.ml
@@ -380,14 +380,6 @@ let rec depcheck_struct = function
let lse' = depcheck_se lse in
if List.is_empty lse' then struc' else (mp,lse')::struc'
-let is_prefix pre s =
- let len = String.length pre in
- let rec is_prefix_aux i =
- if Int.equal i len then true
- else pre.[i] == s.[i] && is_prefix_aux (succ i)
- in
- is_prefix_aux 0
-
exception RemainingImplicit of kill_reason
let check_for_remaining_implicits struc =
diff --git a/plugins/extraction/table.ml b/plugins/extraction/table.ml
index 466c8054b..560fe5aea 100644
--- a/plugins/extraction/table.ml
+++ b/plugins/extraction/table.ml
@@ -300,7 +300,7 @@ let warning_axioms () =
if List.is_empty info_axioms then ()
else begin
let s = if Int.equal (List.length info_axioms) 1 then "axiom" else "axioms" in
- msg_warning
+ Feedback.msg_warning
(str ("The following "^s^" must be realized in the extracted code:")
++ hov 1 (spc () ++ prlist_with_sep spc safe_pr_global info_axioms)
++ str "." ++ fnl ())
@@ -310,7 +310,7 @@ let warning_axioms () =
else begin
let s = if Int.equal (List.length log_axioms) 1 then "axiom was" else "axioms were"
in
- msg_warning
+ Feedback.msg_warning
(str ("The following logical "^s^" encountered:") ++
hov 1
(spc () ++ prlist_with_sep spc safe_pr_global log_axioms ++ str ".\n")
@@ -326,12 +326,12 @@ let warning_opaques accessed =
else
let lst = hov 1 (spc () ++ prlist_with_sep spc safe_pr_global opaques) in
if accessed then
- msg_warning
+ Feedback.msg_warning
(str "The extraction is currently set to bypass opacity,\n" ++
str "the following opaque constant bodies have been accessed :" ++
lst ++ str "." ++ fnl ())
else
- msg_warning
+ Feedback.msg_warning
(str "The extraction now honors the opacity constraints by default,\n" ++
str "the following opaque constants have been extracted as axioms :" ++
lst ++ str "." ++ fnl () ++
@@ -339,7 +339,7 @@ let warning_opaques accessed =
++ fnl ())
let warning_both_mod_and_cst q mp r =
- msg_warning
+ Feedback.msg_warning
(str "The name " ++ pr_qualid q ++ str " is ambiguous, " ++
str "do you mean module " ++
pr_long_mp mp ++
@@ -358,7 +358,7 @@ let check_inside_module () =
err (str "You can't do that within a Module Type." ++ fnl () ++
str "Close it and try again.")
else if Lib.is_module () then
- msg_warning
+ Feedback.msg_warning
(str "Extraction inside an opened module is experimental.\n" ++
str "In case of problem, close it first.\n")
@@ -368,7 +368,7 @@ let check_inside_section () =
str "Close it and try again.")
let warning_id s =
- msg_warning (str ("The identifier "^s^
+ Feedback.msg_warning (str ("The identifier "^s^
" contains __ which is reserved for the extraction"))
let error_constant r =
@@ -391,9 +391,15 @@ let error_no_module_expr mp =
++ str "some Declare Module outside any Module Type.\n"
++ str "This situation is currently unsupported by the extraction.")
-let error_singleton_become_prop id =
+let error_singleton_become_prop id og =
+ let loc =
+ match og with
+ | Some g -> fnl () ++ str "in " ++ safe_pr_global g ++
+ str " (or in its mutual block)"
+ | None -> mt ()
+ in
err (str "The informative inductive type " ++ pr_id id ++
- str " has a Prop instance.\n" ++
+ str " has a Prop instance" ++ loc ++ str "." ++ fnl () ++
str "This happens when a sort-polymorphic singleton inductive type\n" ++
str "has logical parameters, such as (I,I) : (True * True) : Prop.\n" ++
str "The Ocaml extraction cannot handle this situation yet.\n" ++
@@ -443,7 +449,7 @@ let error_remaining_implicit k =
let warning_remaining_implicit k =
let s = msg_of_implicit k in
- msg_warning
+ Feedback.msg_warning
(str ("At least an implicit occurs after extraction : "^s^".") ++ fnl () ++
str "Extraction SafeImplicits is unset, extracting nonetheless," ++ fnl ()
++ str "but this code is potentially unsafe, please review it manually.")
@@ -459,7 +465,7 @@ let check_loaded_modfile mp = match base_mp mp with
| _ -> ()
let info_file f =
- Flags.if_verbose msg_info
+ Flags.if_verbose Feedback.msg_info
(str ("The file "^f^" has been created by extraction."))
diff --git a/plugins/extraction/table.mli b/plugins/extraction/table.mli
index 2b163610e..62c20bd3a 100644
--- a/plugins/extraction/table.mli
+++ b/plugins/extraction/table.mli
@@ -30,7 +30,7 @@ val error_inductive : global_reference -> 'a
val error_nb_cons : unit -> 'a
val error_module_clash : module_path -> module_path -> 'a
val error_no_module_expr : module_path -> 'a
-val error_singleton_become_prop : Id.t -> 'a
+val error_singleton_become_prop : Id.t -> global_reference option -> 'a
val error_unknown_module : qualid -> 'a
val error_scheme : unit -> 'a
val error_not_visible : global_reference -> 'a
diff --git a/plugins/firstorder/g_ground.ml4 b/plugins/firstorder/g_ground.ml4
index 3e8be3699..cec3505a9 100644
--- a/plugins/firstorder/g_ground.ml4
+++ b/plugins/firstorder/g_ground.ml4
@@ -15,6 +15,9 @@ open Goptions
open Tacticals
open Tacinterp
open Libnames
+open Constrarg
+open Stdarg
+open Pcoq.Prim
DECLARE PLUGIN "ground_plugin"
@@ -71,7 +74,7 @@ END
VERNAC COMMAND EXTEND Firstorder_Print_Solver CLASSIFIED AS QUERY
| [ "Print" "Firstorder" "Solver" ] -> [
- Pp.msg_info
+ Feedback.msg_info
(Pp.(++) (Pp.str"Firstorder solver tactic is ") (print_default_solver ())) ]
END
@@ -118,6 +121,7 @@ let pr_firstorder_using_glob _ _ _ l = str "using " ++ prlist_with_sep pr_comma
let pr_firstorder_using_typed _ _ _ l = str "using " ++ prlist_with_sep pr_comma pr_global l
ARGUMENT EXTEND firstorder_using
+ TYPED AS reference_list
PRINTED BY pr_firstorder_using_typed
RAW_TYPED AS reference_list
RAW_PRINTED BY pr_firstorder_using_raw
@@ -127,7 +131,7 @@ ARGUMENT EXTEND firstorder_using
| [ "using" reference(a) "," ne_reference_list_sep(l,",") ] -> [ a::l ]
| [ "using" reference(a) reference(b) reference_list(l) ] -> [
Flags.if_verbose
- Pp.msg_warning (Pp.str "Deprecated syntax; use \",\" as separator");
+ Feedback.msg_warning (Pp.str "Deprecated syntax; use \",\" as separator");
a::b::l
]
| [ ] -> [ [] ]
@@ -149,6 +153,8 @@ TACTIC EXTEND gintuition
END
open Proofview.Notations
+open Cc_plugin
+open Decl_mode_plugin
let default_declarative_automation =
Proofview.tclUNIT () >>= fun () -> (* delay for [congruence_depth] *)
diff --git a/plugins/firstorder/ground.ml b/plugins/firstorder/ground.ml
index 3b9f67f66..d7da85b4f 100644
--- a/plugins/firstorder/ground.ml
+++ b/plugins/firstorder/ground.ml
@@ -32,7 +32,7 @@ let ground_tac solver startseq gl=
update_flags ();
let rec toptac skipped seq gl=
if Tacinterp.get_debug()=Tactic_debug.DebugOn 0
- then Pp.msg_debug (Printer.pr_goal gl);
+ then Feedback.msg_debug (Printer.pr_goal gl);
tclORELSE (axiom_tac seq.gl seq)
begin
try
diff --git a/plugins/firstorder/ground_plugin.mllib b/plugins/firstorder/ground_plugin.mlpack
index 447a1fb51..65fb2e9a1 100644
--- a/plugins/firstorder/ground_plugin.mllib
+++ b/plugins/firstorder/ground_plugin.mlpack
@@ -5,4 +5,3 @@ Rules
Instances
Ground
G_ground
-Ground_plugin_mod
diff --git a/plugins/firstorder/instances.ml b/plugins/firstorder/instances.ml
index 0bc40136c..5eff2f277 100644
--- a/plugins/firstorder/instances.ml
+++ b/plugins/firstorder/instances.ml
@@ -12,7 +12,6 @@ open Errors
open Util
open Term
open Vars
-open Glob_term
open Tacmach
open Tactics
open Tacticals
@@ -98,8 +97,6 @@ let rec collect_quantified seq=
(* open instances processor *)
-let dummy_constr=mkMeta (-1)
-
let dummy_bvid=Id.of_string "x"
let mk_open_instance id idc gl m t=
@@ -138,9 +135,9 @@ let left_instance_tac (inst,id) continue seq=
[tclTHENLIST
[Proofview.V82.of_tactic introf;
pf_constr_of_global id (fun idc ->
- (fun gls->generalize
+ (fun gls-> Proofview.V82.of_tactic (generalize
[mkApp(idc,
- [|mkVar (Tacmach.pf_nth_hyp_id gls 1)|])] gls));
+ [|mkVar (Tacmach.pf_nth_hyp_id gls 1)|])]) gls));
Proofview.V82.of_tactic introf;
tclSOLVE [wrap 1 false continue
(deepen (record (id,None) seq))]];
@@ -161,10 +158,10 @@ let left_instance_tac (inst,id) continue seq=
try Typing.type_of (pf_env gl) evmap gt
with e when Errors.noncritical e ->
error "Untypable instance, maybe higher-order non-prenex quantification" in
- tclTHEN (Refiner.tclEVARS evmap) (generalize [gt]) gl)
+ tclTHEN (Refiner.tclEVARS evmap) (Proofview.V82.of_tactic (generalize [gt])) gl)
else
pf_constr_of_global id (fun idc ->
- generalize [mkApp(idc,[|t|])])
+ Proofview.V82.of_tactic (generalize [mkApp(idc,[|t|])]))
in
tclTHENLIST
[special_generalize;
diff --git a/plugins/firstorder/rules.ml b/plugins/firstorder/rules.ml
index c05015c53..92b6e828e 100644
--- a/plugins/firstorder/rules.ml
+++ b/plugins/firstorder/rules.ml
@@ -52,13 +52,13 @@ let basename_of_global=function
| _->assert false
let clear_global=function
- VarRef id->clear [id]
+ VarRef id-> Proofview.V82.of_tactic (clear [id])
| _->tclIDTAC
(* connection rules *)
let axiom_tac t seq=
- try pf_constr_of_global (find_left t seq) exact_no_check
+ try pf_constr_of_global (find_left t seq) (fun c -> Proofview.V82.of_tactic (exact_no_check c))
with Not_found->tclFAIL 0 (Pp.str "No axiom link")
let ll_atom_tac a backtrack id continue seq=
@@ -67,7 +67,7 @@ let ll_atom_tac a backtrack id continue seq=
tclTHENLIST
[pf_constr_of_global (find_left a seq) (fun left ->
pf_constr_of_global id (fun id ->
- generalize [mkApp(id, [|left|])]));
+ Proofview.V82.of_tactic (generalize [mkApp(id, [|left|])])));
clear_global id;
Proofview.V82.of_tactic intro]
with Not_found->tclFAIL 0 (Pp.str "No link"))
@@ -135,7 +135,7 @@ let ll_ind_tac (ind,u as indu) largs backtrack id continue seq gl=
let newhyps idc =List.init lp (myterm idc) in
tclIFTHENELSE
(tclTHENLIST
- [pf_constr_of_global id (fun idc -> generalize (newhyps idc));
+ [pf_constr_of_global id (fun idc -> Proofview.V82.of_tactic (generalize (newhyps idc)));
clear_global id;
tclDO lp (Proofview.V82.of_tactic intro)])
(wrap lp false continue seq) backtrack gl
@@ -151,9 +151,9 @@ let ll_arrow_tac a b c backtrack id continue seq=
clear_global id;
wrap 1 false continue seq];
tclTHENS (Proofview.V82.of_tactic (cut cc))
- [pf_constr_of_global id exact_no_check;
+ [pf_constr_of_global id (fun c -> Proofview.V82.of_tactic (exact_no_check c));
tclTHENLIST
- [pf_constr_of_global id (fun idc -> generalize [d idc]);
+ [pf_constr_of_global id (fun idc -> Proofview.V82.of_tactic (generalize [d idc]));
clear_global id;
Proofview.V82.of_tactic introf;
Proofview.V82.of_tactic introf;
@@ -192,7 +192,7 @@ let ll_forall_tac prod backtrack id continue seq=
(fun gls->
let id0=pf_nth_hyp_id gls 1 in
let term=mkApp(idc,[|mkVar(id0)|]) in
- tclTHEN (generalize [term]) (clear [id0]) gls));
+ tclTHEN (Proofview.V82.of_tactic (generalize [term])) (Proofview.V82.of_tactic (clear [id0])) gls));
clear_global id;
Proofview.V82.of_tactic intro;
tclCOMPLETE (wrap 1 false continue (deepen seq))];
diff --git a/plugins/fourier/fourierR.ml b/plugins/fourier/fourierR.ml
index 8bc84608e..dc5dd45ab 100644
--- a/plugins/fourier/fourierR.ml
+++ b/plugins/fourier/fourierR.ml
@@ -16,7 +16,6 @@ open Term
open Tactics
open Names
open Globnames
-open Tacmach
open Fourier
open Contradiction
open Proofview.Notations
diff --git a/plugins/fourier/fourier_plugin.mllib b/plugins/fourier/fourier_plugin.mlpack
index 0383b1a80..b6262f8ae 100644
--- a/plugins/fourier/fourier_plugin.mllib
+++ b/plugins/fourier/fourier_plugin.mlpack
@@ -1,4 +1,3 @@
Fourier
FourierR
G_fourier
-Fourier_plugin_mod
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index c8f8a19e5..52094cf08 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -5,7 +5,6 @@ open Term
open Vars
open Namegen
open Names
-open Declarations
open Pp
open Tacmach
open Termops
@@ -53,17 +52,17 @@ let rec print_debug_queue e =
let _ =
match e with
| Some e ->
- Pp.msg_debug (hov 0 (lmsg ++ (str " raised exception " ++ Errors.print e) ++ str " on goal" ++ fnl() ++ goal))
+ Feedback.msg_debug (hov 0 (lmsg ++ (str " raised exception " ++ Errors.print e) ++ str " on goal" ++ fnl() ++ goal))
| None ->
begin
- Pp.msg_debug (str " from " ++ lmsg ++ str " on goal" ++ fnl() ++ goal);
+ Feedback.msg_debug (str " from " ++ lmsg ++ str " on goal" ++ fnl() ++ goal);
end in
print_debug_queue None ;
end
let observe strm =
if do_observe ()
- then Pp.msg_debug strm
+ then Feedback.msg_debug strm
else ()
let do_observe_tac s tac g =
@@ -128,8 +127,7 @@ let finish_proof dynamic_infos g =
let refine c =
Tacmach.refine c
-let thin l =
- Tacmach.thin_no_check l
+let thin l = Proofview.V82.of_tactic (Tactics.clear l)
let eq_constr u v = eq_constr_nounivs u v
@@ -706,7 +704,7 @@ let build_proof
in
tclTHENSEQ
[
- generalize (term_eq::(List.map mkVar dyn_infos.rec_hyps));
+ Proofview.V82.of_tactic (generalize (term_eq::(List.map mkVar dyn_infos.rec_hyps)));
thin dyn_infos.rec_hyps;
Proofview.V82.of_tactic (pattern_option [Locus.AllOccurrencesBut [1],t] None);
(fun g -> observe_tac "toto" (
@@ -936,7 +934,7 @@ let generalize_non_dep hyp g =
in
(* observe (str "to_revert := " ++ prlist_with_sep spc Ppconstr.pr_id to_revert); *)
tclTHEN
- ((* observe_tac "h_generalize" *) (generalize (List.map mkVar to_revert) ))
+ ((* observe_tac "h_generalize" *) (Proofview.V82.of_tactic (generalize (List.map mkVar to_revert) )))
((* observe_tac "thin" *) (thin to_revert))
g
@@ -944,7 +942,7 @@ let id_of_decl decl = Nameops.out_name (get_name decl)
let var_of_decl decl = mkVar (id_of_decl decl)
let revert idl =
tclTHEN
- (generalize (List.map mkVar idl))
+ (Proofview.V82.of_tactic (generalize (List.map mkVar idl)))
(thin idl)
let generate_equation_lemma evd fnames f fun_num nb_params nb_args rec_args_num =
@@ -1229,10 +1227,10 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
if this_fix_info.idx + 1 = 0
then tclIDTAC (* Someone tries to defined a principle on a fully parametric definition declared as a fixpoint (strange but ....) *)
else
- observe_tac_stream (str "h_fix " ++ int (this_fix_info.idx +1) ) (fix (Some this_fix_info.name) (this_fix_info.idx +1))
+ observe_tac_stream (str "h_fix " ++ int (this_fix_info.idx +1) ) (Proofview.V82.of_tactic (fix (Some this_fix_info.name) (this_fix_info.idx +1)))
else
- Tactics.mutual_fix this_fix_info.name (this_fix_info.idx + 1)
- other_fix_infos 0
+ Proofview.V82.of_tactic (Tactics.mutual_fix this_fix_info.name (this_fix_info.idx + 1)
+ other_fix_infos 0)
| _ -> anomaly (Pp.str "Not a valid information")
in
let first_tac : tactic = (* every operations until fix creations *)
@@ -1407,7 +1405,7 @@ let prove_with_tcc tcc_lemma_constr eqs : tactic =
(* let ids = List.filter (fun id -> not (List.mem id ids)) ids' in *)
(* rewrite *)
(* ) *)
- Eauto.gen_eauto (false,5) [] (Some [])
+ Proofview.V82.of_tactic (Eauto.gen_eauto (false,5) [] (Some []))
]
gls
@@ -1566,7 +1564,7 @@ let prove_principle_for_gen
Nameops.out_name (fresh_id (Name (Id.of_string ("Acc_"^(Id.to_string rec_arg_id)))))
in
let revert l =
- tclTHEN (Tactics.generalize (List.map mkVar l)) (clear l)
+ tclTHEN (Proofview.V82.of_tactic (Tactics.generalize (List.map mkVar l))) (Proofview.V82.of_tactic (clear l))
in
let fix_id = Nameops.out_name (fresh_id (Name hrec_id)) in
let prove_rec_arg_acc g =
@@ -1612,7 +1610,7 @@ let prove_principle_for_gen
in
tclTHENSEQ
[
- generalize [lemma];
+ Proofview.V82.of_tactic (generalize [lemma]);
Proofview.V82.of_tactic (Simple.intro hid);
Proofview.V82.of_tactic (Elim.h_decompose_and (mkVar hid));
(fun g ->
@@ -1644,7 +1642,7 @@ let prove_principle_for_gen
(* observe_tac "reverting" *) (revert (List.rev (acc_rec_arg_id::args_ids)));
(* (fun g -> observe (Printer.pr_goal (sig_it g) ++ fnl () ++ *)
(* str "fix arg num" ++ int (List.length args_ids + 1) ); tclIDTAC g); *)
- (* observe_tac "h_fix " *) (fix (Some fix_id) (List.length args_ids + 1));
+ (* observe_tac "h_fix " *) (Proofview.V82.of_tactic (fix (Some fix_id) (List.length args_ids + 1)));
(* (fun g -> observe (Printer.pr_goal (sig_it g) ++ fnl() ++ pr_lconstr_env (pf_env g ) (pf_unsafe_type_of g (mkVar fix_id) )); tclIDTAC g); *)
h_intros (List.rev (acc_rec_arg_id::args_ids));
Proofview.V82.of_tactic (Equality.rewriteLR (mkConst eq_ref));
diff --git a/plugins/funind/functional_principles_types.ml b/plugins/funind/functional_principles_types.ml
index 7a933c04b..5b4fb2595 100644
--- a/plugins/funind/functional_principles_types.ml
+++ b/plugins/funind/functional_principles_types.ml
@@ -19,7 +19,7 @@ exception Toberemoved
let observe s =
if do_observe ()
- then Pp.msg_debug s
+ then Feedback.msg_debug s
(*
Transform an inductive induction principle into
@@ -298,7 +298,7 @@ let build_functional_principle (evd:Evd.evar_map ref) interactive_proof old_prin
(* let dur1 = System.time_difference tim1 tim2 in *)
(* Pp.msgnl (str ("Time to compute proof: ") ++ str (string_of_float dur1)); *)
(* end; *)
- get_proof_clean true, Ephemeron.create hook
+ get_proof_clean true, CEphemeron.create hook
end
diff --git a/plugins/funind/g_indfun.ml4 b/plugins/funind/g_indfun.ml4
index 97b9e95e1..c63527dea 100644
--- a/plugins/funind/g_indfun.ml4
+++ b/plugins/funind/g_indfun.ml4
@@ -9,15 +9,16 @@
open Compat
open Util
open Term
-open Vars
-open Names
open Pp
open Constrexpr
open Indfun_common
open Indfun
open Genarg
-open Tacticals
+open Constrarg
open Misctypes
+open Pcoq.Prim
+open Pcoq.Constr
+open Pcoq.Tactic
DECLARE PLUGIN "recdef_plugin"
@@ -61,6 +62,7 @@ let pr_fun_ind_using_typed prc prlc _ opt_c =
ARGUMENT EXTEND fun_ind_using
+ TYPED AS constr_with_bindings option
PRINTED BY pr_fun_ind_using_typed
RAW_TYPED AS constr_with_bindings_opt
RAW_PRINTED BY pr_fun_ind_using
@@ -90,7 +92,7 @@ let out_disjunctive = function
| loc, IntroAction (IntroOrAndPattern l) -> (loc,l)
| _ -> Errors.error "Disjunctive or conjunctive intro pattern expected."
-ARGUMENT EXTEND with_names TYPED AS simple_intropattern_opt PRINTED BY pr_intro_as_pat
+ARGUMENT EXTEND with_names TYPED AS intropattern_opt PRINTED BY pr_intro_as_pat
| [ "as" simple_intropattern(ipat) ] -> [ Some ipat ]
| [] ->[ None ]
END
@@ -146,10 +148,10 @@ module Tactic = Pcoq.Tactic
type function_rec_definition_loc_argtype = (Vernacexpr.fixpoint_expr * Vernacexpr.decl_notation list) Loc.located
let (wit_function_rec_definition_loc : function_rec_definition_loc_argtype Genarg.uniform_genarg_type) =
- Genarg.create_arg None "function_rec_definition_loc"
+ Genarg.create_arg "function_rec_definition_loc"
let function_rec_definition_loc =
- Pcoq.create_generic_entry "function_rec_definition_loc" (Genarg.rawwit wit_function_rec_definition_loc)
+ Pcoq.create_generic_entry Pcoq.utactic "function_rec_definition_loc" (Genarg.rawwit wit_function_rec_definition_loc)
GEXTEND Gram
GLOBAL: function_rec_definition_loc ;
@@ -191,12 +193,12 @@ let warning_error names e =
let (e, _) = Cerrors.process_vernac_interp_error (e, Exninfo.null) in
match e with
| Building_graph e ->
- Pp.msg_warning
+ Feedback.msg_warning
(str "Cannot define graph(s) for " ++
h 1 (pr_enum Libnames.pr_reference names) ++
if do_observe () then (spc () ++ Errors.print e) else mt ())
| Defining_principle e ->
- Pp.msg_warning
+ Feedback.msg_warning
(str "Cannot define principle(s) for "++
h 1 (pr_enum Libnames.pr_reference names) ++
if do_observe () then Errors.print e else mt ())
diff --git a/plugins/funind/glob_term_to_relation.ml b/plugins/funind/glob_term_to_relation.ml
index 8a0a1a064..c424fe122 100644
--- a/plugins/funind/glob_term_to_relation.ml
+++ b/plugins/funind/glob_term_to_relation.ml
@@ -14,7 +14,7 @@ open Misctypes
let observe strm =
if do_observe ()
- then Pp.msg_debug strm
+ then Feedback.msg_debug strm
else ()
(*let observennl strm =
if do_observe ()
@@ -1217,7 +1217,7 @@ let compute_params_name relnames (args : (Name.t * Glob_term.glob_constr * bool)
if Array.for_all
(fun l ->
let (n',nt',is_defined') = List.nth l i in
- Name.equal n n' && Notation_ops.eq_glob_constr nt nt' && (is_defined : bool) == is_defined')
+ Name.equal n n' && glob_constr_eq nt nt' && (is_defined : bool) == is_defined')
rels_params
then
l := param::!l
diff --git a/plugins/funind/indfun.ml b/plugins/funind/indfun.ml
index 84a4d910e..0cacb003d 100644
--- a/plugins/funind/indfun.ml
+++ b/plugins/funind/indfun.ml
@@ -267,12 +267,12 @@ let derive_inversion fix_names =
lind;
with e when Errors.noncritical e ->
let e' = process_vernac_interp_error e in
- msg_warning
+ Feedback.msg_warning
(str "Cannot build inversion information" ++
if do_observe () then (fnl() ++ Errors.print e') else mt ())
with e when Errors.noncritical e ->
let e' = process_vernac_interp_error e in
- msg_warning
+ Feedback.msg_warning
(str "Cannot build inversion information (early)" ++
if do_observe () then (fnl() ++ Errors.print e') else mt ())
@@ -292,12 +292,12 @@ let warning_error names e =
in
match e with
| Building_graph e ->
- Pp.msg_warning
+ Feedback.msg_warning
(str "Cannot define graph(s) for " ++
h 1 (prlist_with_sep (fun _ -> str","++spc ()) Ppconstr.pr_id names) ++
e_explain e)
| Defining_principle e ->
- Pp.msg_warning
+ Feedback.msg_warning
(str "Cannot define principle(s) for "++
h 1 (prlist_with_sep (fun _ -> str","++spc ()) Ppconstr.pr_id names) ++
e_explain e)
diff --git a/plugins/funind/indfun_common.ml b/plugins/funind/indfun_common.ml
index aa47e2619..2449678a1 100644
--- a/plugins/funind/indfun_common.ml
+++ b/plugins/funind/indfun_common.ml
@@ -163,7 +163,7 @@ let save with_clean id const (locality,_,kind) hook =
(locality, ConstRef kn)
in
if with_clean then Pfedit.delete_current_proof ();
- Ephemeron.iter_opt hook (fun f -> Lemmas.call_hook fix_exn f l r);
+ CEphemeron.iter_opt hook (fun f -> Lemmas.call_hook fix_exn f l r);
definition_message id
diff --git a/plugins/funind/indfun_common.mli b/plugins/funind/indfun_common.mli
index 23f1da1ba..e5c756f56 100644
--- a/plugins/funind/indfun_common.mli
+++ b/plugins/funind/indfun_common.mli
@@ -47,7 +47,7 @@ val jmeq : unit -> Term.constr
val jmeq_refl : unit -> Term.constr
val save : bool -> Id.t -> Safe_typing.private_constants Entries.definition_entry -> Decl_kinds.goal_kind ->
- unit Lemmas.declaration_hook Ephemeron.key -> unit
+ unit Lemmas.declaration_hook CEphemeron.key -> unit
(* [get_proof_clean do_reduce] : returns the proof name, definition, kind and hook and
abort the proof
diff --git a/plugins/funind/invfun.ml b/plugins/funind/invfun.ml
index 6a5a5ad53..94530bfde 100644
--- a/plugins/funind/invfun.ml
+++ b/plugins/funind/invfun.ml
@@ -53,7 +53,7 @@ let pr_constr_with_binding prc (c,bl) : Pp.std_ppcmds =
let observe strm =
if do_observe ()
- then Pp.msg_debug strm
+ then Feedback.msg_debug strm
else ()
(*let observennl strm =
@@ -94,6 +94,7 @@ let nf_zeta =
Environ.empty_env
Evd.empty
+let thin ids gl = Proofview.V82.of_tactic (Tactics.clear ids) gl
(* (\* [id_to_constr id] finds the term associated to [id] in the global environment *\) *)
(* let id_to_constr id = *)
@@ -464,7 +465,7 @@ let generalize_dependent_of x hyp g =
tclMAP
(function
| LocalAssum (id,t) when not (Id.equal id hyp) &&
- (Termops.occur_var (pf_env g) x t) -> tclTHEN (Tactics.generalize [mkVar id]) (thin [id])
+ (Termops.occur_var (pf_env g) x t) -> tclTHEN (Proofview.V82.of_tactic (Tactics.generalize [mkVar id])) (thin [id])
| _ -> tclIDTAC
)
(pf_hyps g)
@@ -714,7 +715,7 @@ let prove_fun_complete funcs graphs schemes lemmas_types_infos i : tactic =
})
Locusops.onConcl)
;
- generalize (List.map mkVar ids);
+ Proofview.V82.of_tactic (generalize (List.map mkVar ids));
thin ids
]
else
@@ -753,7 +754,7 @@ let prove_fun_complete funcs graphs schemes lemmas_types_infos i : tactic =
tclTHENSEQ
[ tclMAP (fun id -> Proofview.V82.of_tactic (Simple.intro id)) (args_names@[res;hres]);
observe_tac "h_generalize"
- (generalize [mkApp(applist(graph_principle,params),Array.map (fun c -> applist(c,params)) lemmas)]);
+ (Proofview.V82.of_tactic (generalize [mkApp(applist(graph_principle,params),Array.map (fun c -> applist(c,params)) lemmas)]));
Proofview.V82.of_tactic (Simple.intro graph_principle_id);
observe_tac "" (tclTHEN_i
(observe_tac "elim" (Proofview.V82.of_tactic (elim false None (mkVar hres,NoBindings) (Some (mkVar graph_principle_id,NoBindings)))))
@@ -936,7 +937,7 @@ let revert_graph kn post_tac hid g =
let f_args,res = Array.chop (Array.length args - 1) args in
tclTHENSEQ
[
- generalize [applist(mkConst f_complete,(Array.to_list f_args)@[res.(0);mkVar hid])];
+ Proofview.V82.of_tactic (generalize [applist(mkConst f_complete,(Array.to_list f_args)@[res.(0);mkVar hid])]);
thin [hid];
Proofview.V82.of_tactic (Simple.intro hid);
post_tac hid
@@ -980,7 +981,7 @@ let functional_inversion kn hid fconst f_correct : tactic =
in
tclTHENSEQ[
pre_tac hid;
- generalize [applist(f_correct,(Array.to_list f_args)@[res;mkVar hid])];
+ 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));
diff --git a/plugins/funind/merge.ml b/plugins/funind/merge.ml
index c71d9a9ca..99a165044 100644
--- a/plugins/funind/merge.ml
+++ b/plugins/funind/merge.ml
@@ -504,19 +504,19 @@ let rec merge_app c1 c2 id1 id2 shift filter_shift_stable =
let lnk = Array.append shift.lnk1 shift.lnk2 in
match c1 , c2 with
| GApp(_,f1, arr1), GApp(_,f2,arr2) when isVarf id1 f1 && isVarf id2 f2 ->
- let _ = prstr "\nICI1!\n";Pp.flush_all() in
+ let _ = prstr "\nICI1!\n" in
let args = filter_shift_stable lnk (arr1 @ arr2) in
GApp (Loc.ghost,GVar (Loc.ghost,shift.ident) , args)
| GApp(_,f1, arr1), GApp(_,f2,arr2) -> raise NoMerge
| GLetIn(_,nme,bdy,trm) , _ ->
- let _ = prstr "\nICI2!\n";Pp.flush_all() in
+ let _ = prstr "\nICI2!\n" in
let newtrm = merge_app trm c2 id1 id2 shift filter_shift_stable in
GLetIn(Loc.ghost,nme,bdy,newtrm)
| _, GLetIn(_,nme,bdy,trm) ->
- let _ = prstr "\nICI3!\n";Pp.flush_all() in
+ let _ = prstr "\nICI3!\n" in
let newtrm = merge_app c1 trm id1 id2 shift filter_shift_stable in
GLetIn(Loc.ghost,nme,bdy,newtrm)
- | _ -> let _ = prstr "\nICI4!\n";Pp.flush_all() in
+ | _ -> let _ = prstr "\nICI4!\n" in
raise NoMerge
let rec merge_app_unsafe c1 c2 shift filter_shift_stable =
@@ -527,14 +527,14 @@ let rec merge_app_unsafe c1 c2 shift filter_shift_stable =
GApp (Loc.ghost,GVar(Loc.ghost,shift.ident) , args)
(* FIXME: what if the function appears in the body of the let? *)
| GLetIn(_,nme,bdy,trm) , _ ->
- let _ = prstr "\nICI2 '!\n";Pp.flush_all() in
+ let _ = prstr "\nICI2 '!\n" in
let newtrm = merge_app_unsafe trm c2 shift filter_shift_stable in
GLetIn(Loc.ghost,nme,bdy,newtrm)
| _, GLetIn(_,nme,bdy,trm) ->
- let _ = prstr "\nICI3 '!\n";Pp.flush_all() in
+ let _ = prstr "\nICI3 '!\n" in
let newtrm = merge_app_unsafe c1 trm shift filter_shift_stable in
GLetIn(Loc.ghost,nme,bdy,newtrm)
- | _ -> let _ = prstr "\nICI4 '!\n";Pp.flush_all() in raise NoMerge
+ | _ -> let _ = prstr "\nICI4 '!\n" in raise NoMerge
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index 046c7aa43..95b4967fa 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -208,23 +208,23 @@ let (declare_f : Id.t -> logical_kind -> constr list -> global_reference -> glob
(* Debugging mechanism *)
let debug_queue = Stack.create ()
-let rec print_debug_queue b e =
+let print_debug_queue b e =
if not (Stack.is_empty debug_queue)
then
begin
let lmsg,goal = Stack.pop debug_queue in
if b then
- Pp.msg_debug (hov 1 (lmsg ++ (str " raised exception " ++ Errors.print e) ++ str " on goal" ++ fnl() ++ goal))
+ Feedback.msg_debug (hov 1 (lmsg ++ (str " raised exception " ++ Errors.print e) ++ str " on goal" ++ fnl() ++ goal))
else
begin
- Pp.msg_debug (hov 1 (str " from " ++ lmsg ++ str " on goal"++fnl() ++ goal));
+ Feedback.msg_debug (hov 1 (str " from " ++ lmsg ++ str " on goal"++fnl() ++ goal));
end;
(* print_debug_queue false e; *)
end
let observe strm =
if do_observe ()
- then Pp.msg_debug strm
+ then Feedback.msg_debug strm
else ()
@@ -267,8 +267,8 @@ let observe_tclTHENLIST s tacl =
let tclUSER tac is_mes l g =
let clear_tac =
match l with
- | None -> clear []
- | Some l -> tclMAP (fun id -> tclTRY (clear [id])) (List.rev l)
+ | None -> tclIDTAC
+ | Some l -> tclMAP (fun id -> tclTRY (Proofview.V82.of_tactic (clear [id]))) (List.rev l)
in
observe_tclTHENLIST (str "tclUSER1")
[
@@ -399,7 +399,7 @@ let treat_case forbid_new_ids to_intros finalize_tac nb_lam e infos : tactic =
Proofview.V82.of_tactic (intro_using teq_id);
onLastHypId (fun heq ->
observe_tclTHENLIST (str "treat_case2")[
- thin to_intros;
+ Proofview.V82.of_tactic (clear to_intros);
h_intros to_intros;
(fun g' ->
let ty_teq = pf_unsafe_type_of g' (mkVar heq) in
@@ -560,7 +560,7 @@ let rec destruct_bounds_aux infos (bound,hyple,rechyps) lbounds g =
Proofview.V82.of_tactic (simplest_elim(mkApp(delayed_force lt_n_O,[|s_max|])));
Proofview.V82.of_tactic default_full_auto];
observe_tclTHENLIST (str "destruct_bounds_aux2")[
- observe_tac (str "clearing k ") (clear [id]);
+ observe_tac (str "clearing k ") (Proofview.V82.of_tactic (clear [id]));
h_intros [k;h';def];
observe_tac (str "simple_iter") (Proofview.V82.of_tactic (simpl_iter Locusops.onConcl));
observe_tac (str "unfold functional")
@@ -589,7 +589,7 @@ let rec destruct_bounds_aux infos (bound,hyple,rechyps) lbounds g =
| (_,v_bound)::l ->
observe_tclTHENLIST (str "destruct_bounds_aux3")[
Proofview.V82.of_tactic (simplest_elim (mkVar v_bound));
- clear [v_bound];
+ Proofview.V82.of_tactic (clear [v_bound]);
tclDO 2 (Proofview.V82.of_tactic intro);
onNthHypId 1
(fun p_hyp ->
@@ -689,7 +689,7 @@ let mkDestructEq :
to_revert_constr in
pf_typel new_hyps (fun _ ->
observe_tclTHENLIST (str "mkDestructEq")
- [generalize new_hyps;
+ [Proofview.V82.of_tactic (generalize new_hyps);
(fun g2 ->
let changefun patvars = { run = fun sigma ->
let redfun = pattern_occs [Locus.AllOccurrencesBut [1], expr] in
@@ -948,7 +948,7 @@ let rec destruct_hex expr_info acc l =
| (v,hex)::l ->
observe_tclTHENLIST (str "destruct_hex")[
Proofview.V82.of_tactic (simplest_case (mkVar hex));
- clear [hex];
+ Proofview.V82.of_tactic (clear [hex]);
tclDO 2 (Proofview.V82.of_tactic intro);
onNthHypId 1 (fun hp ->
onNthHypId 2 (fun p ->
@@ -1116,10 +1116,10 @@ let termination_proof_header is_mes input_type ids args_id relation
[observe_tac (str "generalize")
(onNLastHypsId (nargs+1)
(tclMAP (fun id ->
- tclTHEN (Tactics.generalize [mkVar id]) (clear [id]))
+ tclTHEN (Proofview.V82.of_tactic (Tactics.generalize [mkVar id])) (Proofview.V82.of_tactic (clear [id])))
))
;
- observe_tac (str "fix") (fix (Some hrec) (nargs+1));
+ observe_tac (str "fix") (Proofview.V82.of_tactic (fix (Some hrec) (nargs+1)));
h_intros args_id;
Proofview.V82.of_tactic (Simple.intro wf_rec_arg);
observe_tac (str "tac") (tac wf_rec_arg hrec wf_rec_arg acc_inv)
@@ -1306,7 +1306,7 @@ let open_new_goal build_proof sigma using_lemmas ref_ goal_name (gls_type,decomp
let hid = next_ident_away_in_goal h_id (pf_ids_of_hyps gls) in
observe_tclTHENLIST (str "")
[
- generalize [lemma];
+ Proofview.V82.of_tactic (generalize [lemma]);
Proofview.V82.of_tactic (Simple.intro hid);
(fun g ->
let ids = pf_ids_of_hyps g in
@@ -1529,7 +1529,7 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
let hook _ _ =
let term_ref = Nametab.locate (qualid_of_ident term_id) in
let f_ref = declare_f function_name (IsProof Lemma) arg_types term_ref in
- let _ = Table.extraction_inline true [Ident (Loc.ghost,term_id)] in
+ let _ = Extraction_plugin.Table.extraction_inline true [Ident (Loc.ghost,term_id)] in
(* message "start second proof"; *)
let stop =
try com_eqn (List.length res_vars) equation_id functional_ref f_ref term_ref (subst_var function_name equation_lemma_type);
@@ -1537,7 +1537,7 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
with e when Errors.noncritical e ->
begin
if do_observe ()
- then msg_debug (str "Cannot create equation Lemma " ++ Errors.print e)
+ then Feedback.msg_debug (str "Cannot create equation Lemma " ++ Errors.print e)
else anomaly (Pp.str "Cannot create equation Lemma")
;
true
diff --git a/plugins/funind/recdef_plugin.mllib b/plugins/funind/recdef_plugin.mlpack
index ec1f5436c..2b443f2a1 100644
--- a/plugins/funind/recdef_plugin.mllib
+++ b/plugins/funind/recdef_plugin.mlpack
@@ -8,4 +8,3 @@ Invfun
Indfun
Merge
G_indfun
-Recdef_plugin_mod
diff --git a/plugins/micromega/Lia.v b/plugins/micromega/Lia.v
index 3e58e81ac..52bf5ed3d 100644
--- a/plugins/micromega/Lia.v
+++ b/plugins/micromega/Lia.v
@@ -16,7 +16,7 @@ Require Import ZMicromega.
Require Import ZArith.
Require Import RingMicromega.
Require Import VarMap.
-Require Tauto.
+Require Coq.micromega.Tauto.
Declare ML Module "micromega_plugin".
Ltac preprocess :=
diff --git a/plugins/micromega/Psatz.v b/plugins/micromega/Psatz.v
index 50e0033e5..fafd8a5f2 100644
--- a/plugins/micromega/Psatz.v
+++ b/plugins/micromega/Psatz.v
@@ -20,7 +20,7 @@ Require Import ZArith.
Require Import Rdefinitions.
Require Import RingMicromega.
Require Import VarMap.
-Require Tauto.
+Require Coq.micromega.Tauto.
Declare ML Module "micromega_plugin".
Ltac preprocess :=
@@ -69,7 +69,7 @@ Ltac xpsatz dom d :=
end in tac.
Tactic Notation "psatz" constr(dom) int_or_var(n) := xpsatz dom n.
-Tactic Notation "psatz" constr(dom) := xpsatz dom ltac:-1.
+Tactic Notation "psatz" constr(dom) := xpsatz dom ltac:(-1).
Ltac psatzl dom :=
let tac := lazymatch dom with
diff --git a/plugins/micromega/QMicromega.v b/plugins/micromega/QMicromega.v
index 432683635..b13285f53 100644
--- a/plugins/micromega/QMicromega.v
+++ b/plugins/micromega/QMicromega.v
@@ -168,7 +168,7 @@ Proof.
exact H.
Qed.
-Require Import Tauto.
+Require Import Coq.micromega.Tauto.
Definition Qnormalise := @cnf_normalise Q 0 1 Qplus Qmult Qminus Qopp Qeq_bool.
Definition Qnegate := @cnf_negate Q 0 1 Qplus Qmult Qminus Qopp Qeq_bool.
diff --git a/plugins/micromega/RMicromega.v b/plugins/micromega/RMicromega.v
index 72353a99e..2352d78d6 100644
--- a/plugins/micromega/RMicromega.v
+++ b/plugins/micromega/RMicromega.v
@@ -533,7 +533,7 @@ Proof.
exact H.
Qed.
-Require Import Tauto.
+Require Import Coq.micromega.Tauto.
Definition Rnormalise := @cnf_normalise Q 0%Q 1%Q Qplus Qmult Qminus Qopp Qeq_bool.
Definition Rnegate := @cnf_negate Q 0%Q 1%Q Qplus Qmult Qminus Qopp Qeq_bool.
diff --git a/plugins/micromega/RingMicromega.v b/plugins/micromega/RingMicromega.v
index 751a81df1..ed49c3df4 100644
--- a/plugins/micromega/RingMicromega.v
+++ b/plugins/micromega/RingMicromega.v
@@ -794,7 +794,7 @@ Definition xnormalise (t:Formula C) : list (NFormula) :=
| OpLe => (psub lhs rhs ,Strict) :: nil
end.
-Require Import Tauto.
+Require Import Coq.micromega.Tauto.
Definition cnf_normalise (t:Formula C) : cnf (NFormula) :=
List.map (fun x => x::nil) (xnormalise t).
diff --git a/plugins/micromega/ZMicromega.v b/plugins/micromega/ZMicromega.v
index d7ddef2be..5aa8d03f9 100644
--- a/plugins/micromega/ZMicromega.v
+++ b/plugins/micromega/ZMicromega.v
@@ -198,7 +198,7 @@ Definition xnormalise (t:Formula Z) : list (NFormula Z) :=
| OpLe => (psub lhs (padd rhs (Pc 1)),NonStrict) :: nil
end.
-Require Import Tauto BinNums.
+Require Import Coq.micromega.Tauto BinNums.
Definition normalise (t:Formula Z) : cnf (NFormula Z) :=
List.map (fun x => x::nil) (xnormalise t).
diff --git a/plugins/micromega/certificate.ml b/plugins/micromega/certificate.ml
index 914881db0..1561c811c 100644
--- a/plugins/micromega/certificate.ml
+++ b/plugins/micromega/certificate.ml
@@ -430,9 +430,6 @@ let nlinear_prover prfdepth (sys: (Mc.q Mc.pExpr * Mc.op1) list) =
MonMap.fold (fun s m acc -> ((pol_of_mon m , Mc.NonStrict), Mc.PsatzSquare(norm0 (pol_of_mon s)))::acc) square [] in
- Printf.printf "#square %i\n" (List.length square) ;
- flush stdout ;
-
let sys = sys @ square in
diff --git a/plugins/micromega/coq_micromega.ml b/plugins/micromega/coq_micromega.ml
index 27daa7e3c..e4aa1448e 100644
--- a/plugins/micromega/coq_micromega.ml
+++ b/plugins/micromega/coq_micromega.ml
@@ -18,9 +18,7 @@
open Pp
open Mutils
-open Proofview
open Goptions
-open Proofview.Notations
(**
* Debug flag
@@ -353,7 +351,8 @@ struct
let r_modules =
[["Coq";"Reals" ; "Rdefinitions"];
["Coq";"Reals" ; "Rpow_def"] ;
-]
+ ["Coq";"Reals" ; "Raxioms"] ;
+ ]
let z_modules = [["Coq";"ZArith";"BinInt"]]
@@ -466,8 +465,9 @@ struct
let coq_Rdiv = lazy (r_constant "Rdiv")
let coq_Rinv = lazy (r_constant "Rinv")
let coq_Rpower = lazy (r_constant "pow")
+ let coq_IZR = lazy (r_constant "IZR")
let coq_IQR = lazy (constant "IQR")
- let coq_IZR = lazy (constant "IZR")
+
let coq_PEX = lazy (constant "PEX" )
let coq_PEc = lazy (constant"PEc")
@@ -961,7 +961,7 @@ struct
let parse_expr parse_constant parse_exp ops_spec env term =
if debug
- then Pp.msg_debug (Pp.str "parse_expr: " ++ Printer.prterm term);
+ then Feedback.msg_debug (Pp.str "parse_expr: " ++ Printer.prterm term);
(*
let constant_or_variable env term =
@@ -1045,7 +1045,7 @@ struct
coq_Rplus , (fun x y -> Mc.CPlus(x,y)) ;
coq_Rminus , (fun x y -> Mc.CMinus(x,y)) ;
coq_Rmult , (fun x y -> Mc.CMult(x,y)) ;
- coq_Rdiv , (fun x y -> Mc.CMult(x,Mc.CInv y)) ;
+ (* coq_Rdiv , (fun x y -> Mc.CMult(x,Mc.CInv y)) ;*)
]
let rec rconstant term =
@@ -1067,10 +1067,14 @@ struct
with
ParseError ->
match op with
- | op when Constr.equal op (Lazy.force coq_Rinv) -> Mc.CInv(rconstant args.(0))
- | op when Constr.equal op (Lazy.force coq_IQR) -> Mc.CQ (parse_q args.(0))
-(* | op when op = Lazy.force coq_IZR -> Mc.CZ (parse_z args.(0))*)
- | _ -> raise ParseError
+ | op when Constr.equal op (Lazy.force coq_Rinv) ->
+ let arg = rconstant args.(0) in
+ if Mc.qeq_bool (Mc.q_of_Rcst arg) {Mc.qnum = Mc.Z0 ; Mc.qden = Mc.XH}
+ then raise ParseError (* This is a division by zero -- no semantics *)
+ else Mc.CInv(arg)
+ | op when Constr.equal op (Lazy.force coq_IQR) -> Mc.CQ (parse_q args.(0))
+ | op when Constr.equal op (Lazy.force coq_IZR) -> Mc.CZ (parse_z args.(0))
+ | _ -> raise ParseError
end
| _ -> raise ParseError
@@ -1078,7 +1082,7 @@ struct
let rconstant term =
if debug
- then Pp.msg_debug (Pp.str "rconstant: " ++ Printer.prterm term ++ fnl ());
+ then Feedback.msg_debug (Pp.str "rconstant: " ++ Printer.prterm term ++ fnl ());
let res = rconstant term in
if debug then
(Printf.printf "rconstant -> %a\n" pp_Rcst res ; flush stdout) ;
@@ -1118,7 +1122,7 @@ struct
let parse_arith parse_op parse_expr env cstr gl =
if debug
- then Pp.msg_debug (Pp.str "parse_arith: " ++ Printer.prterm cstr ++ fnl ());
+ then Feedback.msg_debug (Pp.str "parse_arith: " ++ Printer.prterm cstr ++ fnl ());
match kind_of_term cstr with
| App(op,args) ->
let (op,lhs,rhs) = parse_op gl (op,args) in
@@ -1460,7 +1464,7 @@ let micromega_order_change spec cert cert_typ env ff (*: unit Proofview.tactic*
]
(Tacmach.pf_concl gl))
;
- Tactics.new_generalize env ;
+ Tactics.generalize env ;
Tacticals.New.tclTHENLIST (List.map (fun id -> (Tactics.introduction id)) ids)
]
end }
@@ -1647,12 +1651,12 @@ let micromega_tauto negate normalise unsat deduce spec prover env polys1 polys2
if debug then
begin
- Pp.pp (Pp.str "Formula....\n") ;
+ Feedback.msg_notice (Pp.str "Formula....\n") ;
let formula_typ = (Term.mkApp(Lazy.force coq_Cstr, [|spec.coeff|])) in
let ff = dump_formula formula_typ
(dump_cstr spec.typ spec.dump_coeff) ff in
- Pp.pp (Printer.prterm ff) ; Pp.pp_flush ();
- Printf.fprintf stdout "cnf : %a\n" (pp_cnf (fun o _ -> ())) cnf_ff
+ Feedback.msg_notice (Printer.prterm ff);
+ Printf.fprintf stdout "cnf : %a\n" (pp_cnf (fun o _ -> ())) cnf_ff
end;
match witness_list_tags prover cnf_ff with
@@ -1672,11 +1676,11 @@ let micromega_tauto negate normalise unsat deduce spec prover env polys1 polys2
if debug then
begin
- Pp.pp (Pp.str "\nAFormula\n") ;
+ Feedback.msg_notice (Pp.str "\nAFormula\n") ;
let formula_typ = (Term.mkApp( Lazy.force coq_Cstr,[| spec.coeff|])) in
let ff' = dump_formula formula_typ
(dump_cstr spec.typ spec.dump_coeff) ff' in
- Pp.pp (Printer.prterm ff') ; Pp.pp_flush ();
+ Feedback.msg_notice (Printer.prterm ff');
Printf.fprintf stdout "cnf : %a\n" (pp_cnf (fun o _ -> ())) cnf_ff'
end;
@@ -1722,14 +1726,14 @@ let micromega_gen
| Some (ids,ff',res') ->
(Tacticals.New.tclTHENLIST
[
- Tactics.new_generalize (List.map Term.mkVar ids) ;
+ Tactics.generalize (List.map Term.mkVar ids) ;
micromega_order_change spec res'
(Term.mkApp(Lazy.force coq_list, [|spec.proof_typ|])) env ff'
])
with
| ParseError -> Tacticals.New.tclFAIL 0 (Pp.str "Bad logical fragment")
| Mfourier.TimeOut -> Tacticals.New.tclFAIL 0 (Pp.str "Timeout")
- | CsdpNotFound -> flush stdout ; Pp.pp_flush () ;
+ | CsdpNotFound -> flush stdout ;
Tacticals.New.tclFAIL 0 (Pp.str
(" Skipping what remains of this tactic: the complexity of the goal requires "
^ "the use of a specialized external tool called csdp. \n\n"
@@ -1770,7 +1774,7 @@ let micromega_order_changer cert env ff =
("__wit", cert, cert_typ)
]
(Tacmach.pf_concl gl)));
- Tactics.new_generalize env ;
+ Tactics.generalize env ;
Tacticals.New.tclTHENLIST (List.map (fun id -> (Tactics.introduction id)) ids)
]
end }
@@ -1808,13 +1812,13 @@ let micromega_genr prover =
(List.filter (fun (n,_) -> List.mem n ids) hyps) concl in
(Tacticals.New.tclTHENLIST
[
- Tactics.new_generalize (List.map Term.mkVar ids) ;
+ Tactics.generalize (List.map Term.mkVar ids) ;
micromega_order_changer res' env (abstract_wrt_formula ff' ff)
])
with
| Mfourier.TimeOut -> Tacticals.New.tclFAIL 0 (Pp.str "TimeOut")
| ParseError -> Tacticals.New.tclFAIL 0 (Pp.str "Bad logical fragment")
- | CsdpNotFound -> flush stdout ; Pp.pp_flush () ;
+ | CsdpNotFound ->
Tacticals.New.tclFAIL 0 (Pp.str
(" Skipping what remains of this tactic: the complexity of the goal requires "
^ "the use of a specialized external tool called csdp. \n\n"
@@ -1899,7 +1903,7 @@ let call_csdpcert_q provername poly =
let cert = Certificate.q_cert_of_pos cert in
if Mc.qWeakChecker poly cert
then Some cert
- else ((print_string "buggy certificate" ; flush stdout) ;None)
+ else ((print_string "buggy certificate") ;None)
let call_csdpcert_z provername poly =
let l = List.map (fun (e,o) -> (z_to_q_pol e,o)) poly in
diff --git a/plugins/micromega/g_micromega.ml4 b/plugins/micromega/g_micromega.ml4
index bfc9c727d..e6b5cc60d 100644
--- a/plugins/micromega/g_micromega.ml4
+++ b/plugins/micromega/g_micromega.ml4
@@ -16,8 +16,7 @@
(*i camlp4deps: "grammar/grammar.cma" i*)
-open Errors
-open Misctypes
+open Constrarg
DECLARE PLUGIN "micromega_plugin"
diff --git a/plugins/micromega/micromega_plugin.mllib b/plugins/micromega/micromega_plugin.mlpack
index f53a9e379..ed253da3f 100644
--- a/plugins/micromega/micromega_plugin.mllib
+++ b/plugins/micromega/micromega_plugin.mlpack
@@ -7,4 +7,3 @@ Certificate
Persistent_cache
Coq_micromega
G_micromega
-Micromega_plugin_mod
diff --git a/plugins/micromega/persistent_cache.ml b/plugins/micromega/persistent_cache.ml
index 6a03e2d61..88b13abf9 100644
--- a/plugins/micromega/persistent_cache.ml
+++ b/plugins/micromega/persistent_cache.ml
@@ -212,9 +212,11 @@ let find t k =
res
let memo cache f =
- let tbl = lazy (open_in cache) in
- fun x ->
- let tbl = Lazy.force tbl in
+ let tbl = lazy (try Some (open_in cache) with _ -> None) in
+ fun x ->
+ match Lazy.force tbl with
+ | None -> f x
+ | Some tbl ->
try
find tbl x
with
diff --git a/tools/compat5b.ml b/plugins/nsatz/g_nsatz.ml4
index 37cb487c5..5f906a8da 100644
--- a/tools/compat5b.ml
+++ b/plugins/nsatz/g_nsatz.ml4
@@ -1,3 +1,5 @@
+DECLARE PLUGIN "nsatz_plugin"
+
(************************************************************************)
(* v * The Coq Proof Assistant / The Coq Development Team *)
(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
@@ -6,8 +8,10 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(* This file is meant for camlp5, for which there is nothing to
- add to gain camlp5 compatibility :-).
+(*i camlp4deps: "grammar/grammar.cma" i*)
+
+DECLARE PLUGIN "nsatz_plugin"
- See [compat5b.mlp] for the [camlp4] counterpart
-*)
+TACTIC EXTEND nsatz_compute
+| [ "nsatz_compute" constr(lt) ] -> [ Nsatz.nsatz_compute lt ]
+END
diff --git a/plugins/nsatz/nsatz.ml4 b/plugins/nsatz/nsatz.ml
index ced53d82f..ee1904a66 100644
--- a/plugins/nsatz/nsatz.ml4
+++ b/plugins/nsatz/nsatz.ml
@@ -6,8 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i camlp4deps: "grammar/grammar.cma" i*)
-
open Errors
open Util
open Term
@@ -17,8 +15,6 @@ open Coqlib
open Num
open Utile
-DECLARE PLUGIN "nsatz_plugin"
-
(***********************************************************************
Operations on coefficients
*)
@@ -591,8 +587,4 @@ let nsatz_compute t =
error "nsatz cannot solve this problem" in
return_term lpol
-TACTIC EXTEND nsatz_compute
-| [ "nsatz_compute" constr(lt) ] -> [ Proofview.V82.tactic (nsatz_compute lt) ]
-END
-
diff --git a/plugins/nsatz/nsatz_plugin.mllib b/plugins/nsatz/nsatz_plugin.mlpack
index a25e649d0..b55adf43c 100644
--- a/plugins/nsatz/nsatz_plugin.mllib
+++ b/plugins/nsatz/nsatz_plugin.mlpack
@@ -2,4 +2,4 @@ Utile
Polynom
Ideal
Nsatz
-Nsatz_plugin_mod
+G_nsatz
diff --git a/plugins/omega/coq_omega.ml b/plugins/omega/coq_omega.ml
index 1f420cf6a..0bf30e7fd 100644
--- a/plugins/omega/coq_omega.ml
+++ b/plugins/omega/coq_omega.ml
@@ -150,7 +150,7 @@ let exists_tac c = constructor_tac false (Some 1) 1 (ImplicitBindings [c])
let generalize_tac t = generalize t
let elim t = simplest_elim t
-let exact t = Tactics.refine t
+let exact t = Tacmach.refine t
let unfold s = Tactics.unfold_in_concl [Locus.AllOccurrences, Lazy.force s]
let rev_assoc k =
@@ -1067,12 +1067,12 @@ let replay_history tactic_normalisation =
let p_initial = [P_APP 1;P_TYPE] in
let tac= shuffle_mult_right p_initial e1.body k e2.body in
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ generalize_tac
[mkApp (Lazy.force coq_OMEGA17, [|
val_of eq1;
val_of eq2;
mk_integer k;
- mkVar id1; mkVar id2 |])]);
+ mkVar id1; mkVar id2 |])];
Proofview.V82.tactic (mk_then tac);
(intros_using [aux]);
Proofview.V82.tactic (resolve_id aux);
@@ -1104,7 +1104,7 @@ let replay_history tactic_normalisation =
mkVar (hyp_of_tag e1.id);
mkVar (hyp_of_tag e2.id) |])
in
- Proofview.tclTHEN (Proofview.V82.tactic (tclTHEN (generalize_tac [theorem]) (mk_then tac))) (solve_le)
+ Proofview.tclTHEN (Proofview.V82.tactic (tclTHEN (Proofview.V82.of_tactic (generalize_tac [theorem])) (mk_then tac))) (solve_le)
| DIVIDE_AND_APPROX (e1,e2,k,d) :: l ->
let id = hyp_of_tag e1.id in
let eq1 = val_of(decompile e1)
@@ -1119,20 +1119,20 @@ let replay_history tactic_normalisation =
[ Tacticals.New.tclTHENS
(Tacticals.New.tclTHENLIST [
(intros_using [aux]);
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_OMEGA1,
[| eq1; rhs; mkVar aux; mkVar id |])]);
- Proofview.V82.tactic (clear [aux;id]);
+ (clear [aux;id]);
(intros_using [id]);
(cut (mk_gt kk dd)) ])
[ Tacticals.New.tclTHENS
(cut (mk_gt kk izero))
[ Tacticals.New.tclTHENLIST [
(intros_using [aux1; aux2]);
- (Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_Zmult_le_approx,
- [| kk;eq2;dd;mkVar aux1;mkVar aux2; mkVar id |])]));
- Proofview.V82.tactic (clear [aux1;aux2;id]);
+ [| kk;eq2;dd;mkVar aux1;mkVar aux2; mkVar id |])]);
+ (clear [aux1;aux2;id]);
(intros_using [id]);
(loop l) ];
Tacticals.New.tclTHENLIST [
@@ -1157,10 +1157,10 @@ let replay_history tactic_normalisation =
[ Tacticals.New.tclTHENS (cut (mk_gt kk dd))
[Tacticals.New.tclTHENLIST [
(intros_using [aux2;aux1]);
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_OMEGA4,
[| dd;kk;eq2;mkVar aux1; mkVar aux2 |])]);
- Proofview.V82.tactic (clear [aux1;aux2]);
+ (clear [aux1;aux2]);
unfold sp_not;
(intros_using [aux]);
Proofview.V82.tactic (resolve_id aux);
@@ -1187,10 +1187,10 @@ let replay_history tactic_normalisation =
(cut state_eq)
[Tacticals.New.tclTHENLIST [
(intros_using [aux1]);
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_OMEGA18,
[| eq1;eq2;kk;mkVar aux1; mkVar id |])]);
- Proofview.V82.tactic (clear [aux1;id]);
+ (clear [aux1;id]);
(intros_using [id]);
(loop l) ];
Tacticals.New.tclTHEN (Proofview.V82.tactic (mk_then tac)) reflexivity ]
@@ -1202,10 +1202,10 @@ let replay_history tactic_normalisation =
(cut (mk_gt kk izero))
[Tacticals.New.tclTHENLIST [
(intros_using [aux2;aux1]);
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_OMEGA3,
[| eq1; eq2; kk; mkVar aux2; mkVar aux1;mkVar id|])]);
- Proofview.V82.tactic (clear [aux1;aux2;id]);
+ (clear [aux1;aux2;id]);
(intros_using [id]);
(loop l) ];
Tacticals.New.tclTHENLIST [
@@ -1229,9 +1229,9 @@ let replay_history tactic_normalisation =
(cut (mk_eq eq1 (mk_inv eq2)))
[Tacticals.New.tclTHENLIST [
(intros_using [aux]);
- Proofview.V82.tactic (generalize_tac [mkApp (Lazy.force coq_OMEGA8,
+ (generalize_tac [mkApp (Lazy.force coq_OMEGA8,
[| eq1;eq2;mkVar id1;mkVar id2; mkVar aux|])]);
- Proofview.V82.tactic (clear [id1;id2;aux]);
+ (clear [id1;id2;aux]);
(intros_using [id]);
(loop l) ];
Tacticals.New.tclTHEN (Proofview.V82.tactic (mk_then tac)) reflexivity]
@@ -1263,13 +1263,13 @@ let replay_history tactic_normalisation =
[Tacticals.New.tclTHENLIST [
(intros_using [aux]);
(elim_id aux);
- Proofview.V82.tactic (clear [aux]);
+ (clear [aux]);
(intros_using [vid; aux]);
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_OMEGA9,
[| mkVar vid;eq2;eq1;mm; mkVar id2;mkVar aux |])]);
Proofview.V82.tactic (mk_then tac);
- Proofview.V82.tactic (clear [aux]);
+ (clear [aux]);
(intros_using [id]);
(loop l) ];
Tacticals.New.tclTHEN (exists_tac eq1) reflexivity ]
@@ -1304,7 +1304,7 @@ let replay_history tactic_normalisation =
if e1.kind == DISE then [P_APP 1; P_TYPE] else [P_APP 2; P_TYPE] in
let tac = shuffle_mult_right p_initial e1.body k2 e2.body in
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (tac_thm, [| eq1; eq2; kk; mkVar id1; mkVar id2 |])]);
Proofview.V82.tactic (mk_then tac);
(intros_using [id]);
@@ -1320,12 +1320,12 @@ let replay_history tactic_normalisation =
(cut (mk_gt kk2 izero))
[Tacticals.New.tclTHENLIST [
(intros_using [aux2;aux1]);
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_OMEGA7, [|
eq1;eq2;kk1;kk2;
mkVar aux1;mkVar aux2;
mkVar id1;mkVar id2 |])]);
- Proofview.V82.tactic (clear [aux1;aux2]);
+ (clear [aux1;aux2]);
Proofview.V82.tactic (mk_then tac);
(intros_using [id]);
(loop l) ];
@@ -1338,12 +1338,12 @@ let replay_history tactic_normalisation =
simpl_in_concl;
reflexivity ] ]
| CONSTANT_NOT_NUL(e,k) :: l ->
- Tacticals.New.tclTHEN (Proofview.V82.tactic (generalize_tac [mkVar (hyp_of_tag e)])) Equality.discrConcl
+ Tacticals.New.tclTHEN ((generalize_tac [mkVar (hyp_of_tag e)])) Equality.discrConcl
| CONSTANT_NUL(e) :: l ->
Tacticals.New.tclTHEN (Proofview.V82.tactic (resolve_id (hyp_of_tag e))) reflexivity
| CONSTANT_NEG(e,k) :: l ->
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac [mkVar (hyp_of_tag e)]);
+ (generalize_tac [mkVar (hyp_of_tag e)]);
unfold sp_Zle;
simpl_in_concl;
unfold sp_not;
@@ -1366,8 +1366,8 @@ let normalize_equation id flag theorem pos t t1 t2 (tactic,defs) =
let (tac,t') = normalize p_initial t in
let shift_left =
tclTHEN
- (generalize_tac [mkApp (theorem, [| t1; t2; mkVar id |]) ])
- (tclTRY (clear [id]))
+ (Proofview.V82.of_tactic (generalize_tac [mkApp (theorem, [| t1; t2; mkVar id |]) ]))
+ (tclTRY (Proofview.V82.of_tactic (clear [id])))
in
if not (List.is_empty tac) then
let id' = new_identifier () in
@@ -1412,7 +1412,7 @@ let destructure_omega gl tac_def (id,c) =
let reintroduce id =
(* [id] cannot be cleared if dependent: protect it by a try *)
- Tacticals.New.tclTHEN (Proofview.V82.tactic (tclTRY (clear [id]))) (intro_using id)
+ Tacticals.New.tclTHEN (Tacticals.New.tclTRY (clear [id])) (intro_using id)
open Proofview.Notations
@@ -1435,7 +1435,7 @@ let coq_omega =
(simplest_elim (applist (Lazy.force coq_intro_Z, [t])));
(intros_using [v; id]);
(elim_id id);
- Proofview.V82.tactic (clear [id]);
+ (clear [id]);
(intros_using [th;id]);
tac ]),
{kind = INEQ;
@@ -1546,7 +1546,7 @@ let nat_inject =
begin try match destructurate_prop t with
Kapp(Le,[t1;t2]) ->
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_inj_le, [| t1;t2;mkVar i |]) ]);
(explore [P_APP 1; P_TYPE] t1);
(explore [P_APP 2; P_TYPE] t2);
@@ -1555,7 +1555,7 @@ let nat_inject =
]
| Kapp(Lt,[t1;t2]) ->
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_inj_lt, [| t1;t2;mkVar i |]) ]);
(explore [P_APP 1; P_TYPE] t1);
(explore [P_APP 2; P_TYPE] t2);
@@ -1564,7 +1564,7 @@ let nat_inject =
]
| Kapp(Ge,[t1;t2]) ->
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_inj_ge, [| t1;t2;mkVar i |]) ]);
(explore [P_APP 1; P_TYPE] t1);
(explore [P_APP 2; P_TYPE] t2);
@@ -1573,7 +1573,7 @@ let nat_inject =
]
| Kapp(Gt,[t1;t2]) ->
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_inj_gt, [| t1;t2;mkVar i |]) ]);
(explore [P_APP 1; P_TYPE] t1);
(explore [P_APP 2; P_TYPE] t2);
@@ -1582,7 +1582,7 @@ let nat_inject =
]
| Kapp(Neq,[t1;t2]) ->
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_inj_neq, [| t1;t2;mkVar i |]) ]);
(explore [P_APP 1; P_TYPE] t1);
(explore [P_APP 2; P_TYPE] t2);
@@ -1592,7 +1592,7 @@ let nat_inject =
| Kapp(Eq,[typ;t1;t2]) ->
if is_conv typ (Lazy.force coq_nat) then
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_inj_eq, [| t1;t2;mkVar i |]) ]);
(explore [P_APP 2; P_TYPE] t1);
(explore [P_APP 3; P_TYPE] t2);
@@ -1674,7 +1674,7 @@ let onClearedName id tac =
(* We cannot ensure that hyps can be cleared (because of dependencies), *)
(* so renaming may be necessary *)
Tacticals.New.tclTHEN
- (Proofview.V82.tactic (tclTRY (clear [id])))
+ (Tacticals.New.tclTRY (clear [id]))
(Proofview.Goal.nf_enter { enter = begin fun gl ->
let id = Tacmach.New.of_old (fresh_id [] id) gl in
Tacticals.New.tclTHEN (introduction id) (tac id)
@@ -1682,7 +1682,7 @@ let onClearedName id tac =
let onClearedName2 id tac =
Tacticals.New.tclTHEN
- (Proofview.V82.tactic (tclTRY (clear [id])))
+ (Tacticals.New.tclTRY (clear [id]))
(Proofview.Goal.nf_enter { enter = begin fun gl ->
let id1 = Tacmach.New.of_old (fresh_id [] (add_suffix id "_left")) gl in
let id2 = Tacmach.New.of_old (fresh_id [] (add_suffix id "_right")) gl in
@@ -1723,7 +1723,7 @@ let destructure_hyps =
then
let d1 = decidability t1 in
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac [mkApp (Lazy.force coq_imp_simp,
+ (generalize_tac [mkApp (Lazy.force coq_imp_simp,
[| t1; t2; d1; mkVar i|])]);
(onClearedName i (fun i ->
(loop (LocalAssum (i,mk_or (mk_not t1) t2) :: lit))))
@@ -1734,7 +1734,7 @@ let destructure_hyps =
begin match destructurate_prop t with
Kapp(Or,[t1;t2]) ->
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_not_or,[| t1; t2; mkVar i |])]);
(onClearedName i (fun i ->
(loop (LocalAssum (i,mk_and (mk_not t1) (mk_not t2)) :: lit))))
@@ -1742,7 +1742,7 @@ let destructure_hyps =
| Kapp(And,[t1;t2]) ->
let d1 = decidability t1 in
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_not_and,
[| t1; t2; d1; mkVar i |])]);
(onClearedName i (fun i ->
@@ -1752,7 +1752,7 @@ let destructure_hyps =
let d1 = decidability t1 in
let d2 = decidability t2 in
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_not_iff,
[| t1; t2; d1; d2; mkVar i |])]);
(onClearedName i (fun i ->
@@ -1764,7 +1764,7 @@ let destructure_hyps =
For t1, being decidable implies being Prop. *)
let d1 = decidability t1 in
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_not_imp,
[| t1; t2; d1; mkVar i |])]);
(onClearedName i (fun i ->
@@ -1773,7 +1773,7 @@ let destructure_hyps =
| Kapp(Not,[t]) ->
let d = decidability t in
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force coq_not_not, [| t; d; mkVar i |])]);
(onClearedName i (fun i -> (loop (LocalAssum (i,t) :: lit))))
]
@@ -1781,7 +1781,7 @@ let destructure_hyps =
(try
let thm = not_binop op in
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (generalize_tac
+ (generalize_tac
[mkApp (Lazy.force thm, [| t1;t2;mkVar i|])]);
(onClearedName i (fun _ -> loop lit))
]
@@ -1847,7 +1847,7 @@ let destructure_goal =
try
let dec = decidability t in
Tacticals.New.tclTHEN
- (Proofview.V82.tactic (Tactics.refine
+ (Proofview.V82.tactic (Tacmach.refine
(mkApp (Lazy.force coq_dec_not_not, [| t; dec; mkNewMeta () |]))))
intro
with Undecidable -> Tactics.elim_type (build_coq_False ())
diff --git a/plugins/omega/g_omega.ml4 b/plugins/omega/g_omega.ml4
index 04c62eb48..d7538146f 100644
--- a/plugins/omega/g_omega.ml4
+++ b/plugins/omega/g_omega.ml4
@@ -19,6 +19,7 @@ DECLARE PLUGIN "omega_plugin"
open Names
open Coq_omega
+open Constrarg
let eval_tactic name =
let dp = DirPath.make (List.map Id.of_string ["PreOmega"; "omega"; "Coq"]) in
diff --git a/plugins/omega/omega_plugin.mllib b/plugins/omega/omega_plugin.mlpack
index 2b387fdce..df7f1047f 100644
--- a/plugins/omega/omega_plugin.mllib
+++ b/plugins/omega/omega_plugin.mlpack
@@ -1,4 +1,3 @@
Omega
Coq_omega
G_omega
-Omega_plugin_mod
diff --git a/plugins/plugins.itarget b/plugins/plugins.itarget
deleted file mode 100644
index 56aa42b06..000000000
--- a/plugins/plugins.itarget
+++ /dev/null
@@ -1,3 +0,0 @@
-pluginsopt.otarget
-pluginsbyte.otarget
-pluginsvo.otarget \ No newline at end of file
diff --git a/plugins/pluginsbyte.itarget b/plugins/pluginsbyte.itarget
deleted file mode 100644
index f3b2b5a3e..000000000
--- a/plugins/pluginsbyte.itarget
+++ /dev/null
@@ -1,22 +0,0 @@
-btauto/btauto_plugin.cma
-setoid_ring/newring_plugin.cma
-extraction/extraction_plugin.cma
-decl_mode/decl_mode_plugin.cma
-firstorder/ground_plugin.cma
-rtauto/rtauto_plugin.cma
-fourier/fourier_plugin.cma
-romega/romega_plugin.cma
-omega/omega_plugin.cma
-micromega/micromega_plugin.cma
-cc/cc_plugin.cma
-nsatz/nsatz_plugin.cma
-funind/recdef_plugin.cma
-syntax/ascii_syntax_plugin.cma
-syntax/nat_syntax_plugin.cma
-syntax/numbers_syntax_plugin.cma
-syntax/r_syntax_plugin.cma
-syntax/string_syntax_plugin.cma
-syntax/z_syntax_plugin.cma
-quote/quote_plugin.cma
-derive/derive_plugin.cma
-ssrmatching/ssrmatching_plugin.cma
diff --git a/plugins/pluginsdyn.itarget b/plugins/pluginsdyn.itarget
deleted file mode 100644
index aabd0e56d..000000000
--- a/plugins/pluginsdyn.itarget
+++ /dev/null
@@ -1,25 +0,0 @@
-btauto/btauto_plugin.cmxs
-field/field_plugin.cmxs
-setoid_ring/newring_plugin.cmxs
-extraction/extraction_plugin.cmxs
-decl_mode/decl_mode_plugin.cmxs
-firstorder/ground_plugin.cmxs
-rtauto/rtauto_plugin.cmxs
-fourier/fourier_plugin.cmxs
-romega/romega_plugin.cmxs
-omega/omega_plugin.cmxs
-micromega/micromega_plugin.cmxs
-subtac/subtac_plugin.cmxs
-ring/ring_plugin.cmxs
-cc/cc_plugin.cmxs
-nsatz/nsatz_plugin.cmxs
-funind/recdef_plugin.cmxs
-syntax/ascii_syntax_plugin.cmxs
-syntax/nat_syntax_plugin.cmxs
-syntax/numbers_syntax_plugin.cmxs
-syntax/r_syntax_plugin.cmxs
-syntax/string_syntax_plugin.cmxs
-syntax/z_syntax_plugin.cmxs
-quote/quote_plugin.cmxs
-derive/derive_plugin.cmxs
-ssrmatching/ssrmatching_plugin.cmxs
diff --git a/plugins/pluginsopt.itarget b/plugins/pluginsopt.itarget
deleted file mode 100644
index 5e8e6cc9a..000000000
--- a/plugins/pluginsopt.itarget
+++ /dev/null
@@ -1,22 +0,0 @@
-btauto/btauto_plugin.cmxa
-setoid_ring/newring_plugin.cmxa
-extraction/extraction_plugin.cmxa
-decl_mode/decl_mode_plugin.cmxa
-firstorder/ground_plugin.cmxa
-rtauto/rtauto_plugin.cmxa
-fourier/fourier_plugin.cmxa
-romega/romega_plugin.cmxa
-omega/omega_plugin.cmxa
-micromega/micromega_plugin.cmxa
-cc/cc_plugin.cmxa
-nsatz/nsatz_plugin.cmxa
-funind/recdef_plugin.cmxa
-syntax/ascii_syntax_plugin.cmxa
-syntax/nat_syntax_plugin.cmxa
-syntax/numbers_syntax_plugin.cmxa
-syntax/r_syntax_plugin.cmxa
-syntax/string_syntax_plugin.cmxa
-syntax/z_syntax_plugin.cmxa
-quote/quote_plugin.cmxa
-derive/derive_plugin.cmxa
-ssrmatching/ssrmatching_plugin.cmxa
diff --git a/plugins/pluginsvo.itarget b/plugins/pluginsvo.itarget
deleted file mode 100644
index 74b8d5e03..000000000
--- a/plugins/pluginsvo.itarget
+++ /dev/null
@@ -1,13 +0,0 @@
-btauto/vo.otarget
-fourier/vo.otarget
-funind/vo.otarget
-nsatz/vo.otarget
-micromega/vo.otarget
-omega/vo.otarget
-quote/vo.otarget
-romega/vo.otarget
-rtauto/vo.otarget
-setoid_ring/vo.otarget
-extraction/vo.otarget
-derive/vo.otarget
-ssrmatching/vo.otarget
diff --git a/plugins/quote/g_quote.ml4 b/plugins/quote/g_quote.ml4
index 7a3d7936a..fd87d5b7d 100644
--- a/plugins/quote/g_quote.ml4
+++ b/plugins/quote/g_quote.ml4
@@ -13,6 +13,7 @@ open Misctypes
open Tacexpr
open Geninterp
open Quote
+open Constrarg
DECLARE PLUGIN "quote_plugin"
@@ -20,7 +21,7 @@ let loc = Loc.ghost
let cont = Id.of_string "cont"
let x = Id.of_string "x"
-let make_cont (k : Genarg.Val.t) (c : Constr.t) =
+let make_cont (k : Val.t) (c : Constr.t) =
let c = Tacinterp.Value.of_constr c in
let tac = TacCall (loc, ArgVar (loc, cont), [Reference (ArgVar (loc, x))]) in
let ist = { lfun = Id.Map.add cont k (Id.Map.singleton x c); extra = TacStore.empty; } in
diff --git a/plugins/quote/quote_plugin.mllib b/plugins/quote/quote_plugin.mllib
deleted file mode 100644
index d1b3ccbe1..000000000
--- a/plugins/quote/quote_plugin.mllib
+++ /dev/null
@@ -1,3 +0,0 @@
-Quote
-G_quote
-Quote_plugin_mod
diff --git a/plugins/quote/quote_plugin.mlpack b/plugins/quote/quote_plugin.mlpack
new file mode 100644
index 000000000..2e9be09d8
--- /dev/null
+++ b/plugins/quote/quote_plugin.mlpack
@@ -0,0 +1,2 @@
+Quote
+G_quote
diff --git a/plugins/romega/ReflOmegaCore.v b/plugins/romega/ReflOmegaCore.v
index b84cf2540..5e43dfc42 100644
--- a/plugins/romega/ReflOmegaCore.v
+++ b/plugins/romega/ReflOmegaCore.v
@@ -1074,16 +1074,19 @@ Qed.
avait utilisé le test précédent et fait une elimination dessus. *)
Ltac elim_eq_term t1 t2 :=
+ let Aux := fresh "Aux" in
pattern (eq_term t1 t2); apply bool_eq_ind; intro Aux;
[ generalize (eq_term_true t1 t2 Aux); clear Aux
| generalize (eq_term_false t1 t2 Aux); clear Aux ].
Ltac elim_beq t1 t2 :=
+ let Aux := fresh "Aux" in
pattern (beq t1 t2); apply bool_eq_ind; intro Aux;
[ generalize (beq_true t1 t2 Aux); clear Aux
| generalize (beq_false t1 t2 Aux); clear Aux ].
Ltac elim_bgt t1 t2 :=
+ let Aux := fresh "Aux" in
pattern (bgt t1 t2); apply bool_eq_ind; intro Aux;
[ generalize (bgt_true t1 t2 Aux); clear Aux
| generalize (bgt_false t1 t2 Aux); clear Aux ].
@@ -1492,7 +1495,7 @@ with Simplify := match goal with
end.
Ltac prove_stable x th :=
- match constr:x with
+ match constr:(x) with
| ?X1 =>
unfold term_stable, X1; intros; Simplify; simpl;
apply th
diff --git a/plugins/romega/g_romega.ml4 b/plugins/romega/g_romega.ml4
index 6b2b2bbfa..fd4ede6c3 100644
--- a/plugins/romega/g_romega.ml4
+++ b/plugins/romega/g_romega.ml4
@@ -12,6 +12,7 @@ DECLARE PLUGIN "romega_plugin"
open Names
open Refl_omega
+open Constrarg
let eval_tactic name =
let dp = DirPath.make (List.map Id.of_string ["PreOmega"; "omega"; "Coq"]) in
diff --git a/plugins/romega/refl_omega.ml b/plugins/romega/refl_omega.ml
index 177c870b3..a059512d8 100644
--- a/plugins/romega/refl_omega.ml
+++ b/plugins/romega/refl_omega.ml
@@ -9,7 +9,7 @@
open Pp
open Util
open Const_omega
-module OmegaSolver = Omega.MakeOmegaSolver (Bigint)
+module OmegaSolver = Omega_plugin.Omega.MakeOmegaSolver (Bigint)
open OmegaSolver
(* \section{Useful functions and flags} *)
@@ -172,7 +172,7 @@ let print_env_reification env =
in
let prop_info = str "ENVIRONMENT OF PROPOSITIONS :" ++ fnl () ++ loop 'P' 0 env.props in
let term_info = str "ENVIRONMENT OF TERMS :" ++ fnl () ++ loop 'V' 0 env.terms in
- msg_debug (prop_info ++ fnl () ++ term_info)
+ Feedback.msg_debug (prop_info ++ fnl () ++ term_info)
(* \subsection{Gestion des environnements de variable pour Omega} *)
(* generation d'identifiant d'equation pour Omega *)
@@ -1280,8 +1280,8 @@ let resolution env full_reified_goal systems_list =
CCHyp{o_hyp=id_concl;o_path=[]} :: hyp_stated_vars @ initial_context in
let decompose_tactic = decompose_tree env context solution_tree in
- Tactics.generalize
- (l_generalize_arg @ List.map Term.mkVar (List.tl l_hyps)) >>
+ Proofview.V82.of_tactic (Tactics.generalize
+ (l_generalize_arg @ List.map Term.mkVar (List.tl l_hyps))) >>
Proofview.V82.of_tactic (Tactics.change_concl reified) >>
Proofview.V82.of_tactic (Tactics.apply (app coq_do_omega [|decompose_tactic; normalization_trace|])) >>
show_goal >>
diff --git a/plugins/romega/romega_plugin.mllib b/plugins/romega/romega_plugin.mlpack
index 1625009d0..38d0e9411 100644
--- a/plugins/romega/romega_plugin.mllib
+++ b/plugins/romega/romega_plugin.mlpack
@@ -1,4 +1,3 @@
Const_omega
Refl_omega
G_romega
-Romega_plugin_mod
diff --git a/plugins/rtauto/proof_search.ml b/plugins/rtauto/proof_search.ml
index 3ba92b9f2..f3eae5f50 100644
--- a/plugins/rtauto/proof_search.ml
+++ b/plugins/rtauto/proof_search.ml
@@ -547,7 +547,7 @@ let pp_info () =
int s_info.created_branches ++ str " created" ++ fnl () ++
str "Hypotheses : " ++
int s_info.created_hyps ++ str " created" ++ fnl () in
- msg_info
+ Feedback.msg_info
( str "Proof-search statistics :" ++ fnl () ++
count_info ++
str "Branch ends: " ++
diff --git a/plugins/rtauto/refl_tauto.ml b/plugins/rtauto/refl_tauto.ml
index 2f3a3e551..0a0b45915 100644
--- a/plugins/rtauto/refl_tauto.ml
+++ b/plugins/rtauto/refl_tauto.ml
@@ -276,7 +276,7 @@ let rtauto_tac gls=
begin
reset_info ();
if !verbose then
- msg_info (str "Starting proof-search ...");
+ Feedback.msg_info (str "Starting proof-search ...");
end in
let search_start_time = System.get_time () in
let prf =
@@ -286,10 +286,10 @@ let rtauto_tac gls=
let search_end_time = System.get_time () in
let _ = if !verbose then
begin
- msg_info (str "Proof tree found in " ++
+ Feedback.msg_info (str "Proof tree found in " ++
System.fmt_time_difference search_start_time search_end_time);
pp_info ();
- msg_info (str "Building proof term ... ")
+ Feedback.msg_info (str "Building proof term ... ")
end in
let build_start_time=System.get_time () in
let _ = step_count := 0; node_count := 0 in
@@ -302,7 +302,7 @@ let rtauto_tac gls=
let build_end_time=System.get_time () in
let _ = if !verbose then
begin
- msg_info (str "Proof term built in " ++
+ Feedback.msg_info (str "Proof term built in " ++
System.fmt_time_difference build_start_time build_end_time ++
fnl () ++
str "Proof size : " ++ int !step_count ++
@@ -316,12 +316,12 @@ let rtauto_tac gls=
if !check then
Proofview.V82.of_tactic (Tactics.exact_check term) gls
else
- Tactics.exact_no_check term gls in
+ Proofview.V82.of_tactic (Tactics.exact_no_check term) gls in
let tac_end_time = System.get_time () in
let _ =
- if !check then msg_info (str "Proof term type-checking is on");
+ if !check then Feedback.msg_info (str "Proof term type-checking is on");
if !verbose then
- msg_info (str "Internal tactic executed in " ++
+ Feedback.msg_info (str "Internal tactic executed in " ++
System.fmt_time_difference tac_start_time tac_end_time) in
result
diff --git a/plugins/rtauto/rtauto_plugin.mllib b/plugins/rtauto/rtauto_plugin.mlpack
index 0e3460449..61c5e945b 100644
--- a/plugins/rtauto/rtauto_plugin.mllib
+++ b/plugins/rtauto/rtauto_plugin.mlpack
@@ -1,4 +1,3 @@
Proof_search
Refl_tauto
G_rtauto
-Rtauto_plugin_mod
diff --git a/plugins/setoid_ring/ArithRing.v b/plugins/setoid_ring/ArithRing.v
index 04decbce1..5f5b97925 100644
--- a/plugins/setoid_ring/ArithRing.v
+++ b/plugins/setoid_ring/ArithRing.v
@@ -32,13 +32,13 @@ Qed.
Ltac natcst t :=
match isnatcst t with
true => constr:(N.of_nat t)
- | _ => constr:InitialRing.NotConstant
+ | _ => constr:(InitialRing.NotConstant)
end.
Ltac Ss_to_add f acc :=
match f with
| S ?f1 => Ss_to_add f1 (S acc)
- | _ => constr:(acc + f)%nat
+ | _ => constr:((acc + f)%nat)
end.
Ltac natprering :=
diff --git a/plugins/setoid_ring/InitialRing.v b/plugins/setoid_ring/InitialRing.v
index 8362c8c26..8fcc07716 100644
--- a/plugins/setoid_ring/InitialRing.v
+++ b/plugins/setoid_ring/InitialRing.v
@@ -612,32 +612,32 @@ End GEN_DIV.
Ltac inv_gen_phi_pos rI add mul t :=
let rec inv_cst t :=
match t with
- rI => constr:1%positive
- | (add rI rI) => constr:2%positive
- | (add rI (add rI rI)) => constr:3%positive
+ rI => constr:(1%positive)
+ | (add rI rI) => constr:(2%positive)
+ | (add rI (add rI rI)) => constr:(3%positive)
| (mul (add rI rI) ?p) => (* 2p *)
match inv_cst p with
- NotConstant => constr:NotConstant
- | 1%positive => constr:NotConstant (* 2*1 is not convertible to 2 *)
+ NotConstant => constr:(NotConstant)
+ | 1%positive => constr:(NotConstant) (* 2*1 is not convertible to 2 *)
| ?p => constr:(xO p)
end
| (add rI (mul (add rI rI) ?p)) => (* 1+2p *)
match inv_cst p with
- NotConstant => constr:NotConstant
- | 1%positive => constr:NotConstant
+ NotConstant => constr:(NotConstant)
+ | 1%positive => constr:(NotConstant)
| ?p => constr:(xI p)
end
- | _ => constr:NotConstant
+ | _ => constr:(NotConstant)
end in
inv_cst t.
(* The (partial) inverse of gen_phiNword *)
Ltac inv_gen_phiNword rO rI add mul opp t :=
match t with
- rO => constr:NwO
+ rO => constr:(NwO)
| _ =>
match inv_gen_phi_pos rI add mul t with
- NotConstant => constr:NotConstant
+ NotConstant => constr:(NotConstant)
| ?p => constr:(Npos p::nil)
end
end.
@@ -646,10 +646,10 @@ End GEN_DIV.
(* The inverse of gen_phiN *)
Ltac inv_gen_phiN rO rI add mul t :=
match t with
- rO => constr:0%N
+ rO => constr:(0%N)
| _ =>
match inv_gen_phi_pos rI add mul t with
- NotConstant => constr:NotConstant
+ NotConstant => constr:(NotConstant)
| ?p => constr:(Npos p)
end
end.
@@ -657,15 +657,15 @@ End GEN_DIV.
(* The inverse of gen_phiZ *)
Ltac inv_gen_phiZ rO rI add mul opp t :=
match t with
- rO => constr:0%Z
+ rO => constr:(0%Z)
| (opp ?p) =>
match inv_gen_phi_pos rI add mul p with
- NotConstant => constr:NotConstant
+ NotConstant => constr:(NotConstant)
| ?p => constr:(Zneg p)
end
| _ =>
match inv_gen_phi_pos rI add mul t with
- NotConstant => constr:NotConstant
+ NotConstant => constr:(NotConstant)
| ?p => constr:(Zpos p)
end
end.
@@ -681,7 +681,7 @@ Ltac inv_gen_phi rO rI cO cI t :=
end.
(* A simple tactic recognizing no constant *)
- Ltac inv_morph_nothing t := constr:NotConstant.
+ Ltac inv_morph_nothing t := constr:(NotConstant).
Ltac coerce_to_almost_ring set ext rspec :=
match type of rspec with
@@ -825,31 +825,31 @@ Ltac ring_elements set ext rspec pspec sspec dspec rk :=
(* Tactic for constant *)
Ltac isnatcst t :=
match t with
- O => constr:true
+ O => constr:(true)
| S ?p => isnatcst p
- | _ => constr:false
+ | _ => constr:(false)
end.
Ltac isPcst t :=
match t with
| xI ?p => isPcst p
| xO ?p => isPcst p
- | xH => constr:true
+ | xH => constr:(true)
(* nat -> positive *)
| Pos.of_succ_nat ?n => isnatcst n
- | _ => constr:false
+ | _ => constr:(false)
end.
Ltac isNcst t :=
match t with
- N0 => constr:true
+ N0 => constr:(true)
| Npos ?p => isPcst p
- | _ => constr:false
+ | _ => constr:(false)
end.
Ltac isZcst t :=
match t with
- Z0 => constr:true
+ Z0 => constr:(true)
| Zpos ?p => isPcst p
| Zneg ?p => isPcst p
(* injection nat -> Z *)
@@ -857,7 +857,7 @@ Ltac isZcst t :=
(* injection N -> Z *)
| Z.of_N ?n => isNcst n
(* *)
- | _ => constr:false
+ | _ => constr:(false)
end.
diff --git a/plugins/setoid_ring/NArithRing.v b/plugins/setoid_ring/NArithRing.v
index 6c1a79e4e..54e2789ba 100644
--- a/plugins/setoid_ring/NArithRing.v
+++ b/plugins/setoid_ring/NArithRing.v
@@ -15,7 +15,7 @@ Set Implicit Arguments.
Ltac Ncst t :=
match isNcst t with
true => t
- | _ => constr:NotConstant
+ | _ => constr:(NotConstant)
end.
Add Ring Nr : Nth (decidable Neqb_ok, constants [Ncst]).
diff --git a/plugins/setoid_ring/Ring.v b/plugins/setoid_ring/Ring.v
index a0844100c..77576cb93 100644
--- a/plugins/setoid_ring/Ring.v
+++ b/plugins/setoid_ring/Ring.v
@@ -36,9 +36,9 @@ Qed.
Ltac bool_cst t :=
let t := eval hnf in t in
match t with
- true => constr:true
- | false => constr:false
- | _ => constr:NotConstant
+ true => constr:(true)
+ | false => constr:(false)
+ | _ => constr:(NotConstant)
end.
Add Ring bool_ring : BoolTheory (decidable bool_eq_ok, constants [bool_cst]).
diff --git a/plugins/setoid_ring/ZArithRing.v b/plugins/setoid_ring/ZArithRing.v
index 914843727..23784cf33 100644
--- a/plugins/setoid_ring/ZArithRing.v
+++ b/plugins/setoid_ring/ZArithRing.v
@@ -17,14 +17,14 @@ Set Implicit Arguments.
Ltac Zcst t :=
match isZcst t with
true => t
- | _ => constr:NotConstant
+ | _ => constr:(NotConstant)
end.
Ltac isZpow_coef t :=
match t with
| Zpos ?p => isPcst p
- | Z0 => constr:true
- | _ => constr:false
+ | Z0 => constr:(true)
+ | _ => constr:(false)
end.
Notation N_of_Z := Z.to_N (only parsing).
@@ -32,7 +32,7 @@ Notation N_of_Z := Z.to_N (only parsing).
Ltac Zpow_tac t :=
match isZpow_coef t with
| true => constr:(N_of_Z t)
- | _ => constr:NotConstant
+ | _ => constr:(NotConstant)
end.
Ltac Zpower_neg :=
diff --git a/plugins/setoid_ring/g_newring.ml4 b/plugins/setoid_ring/g_newring.ml4
index 856ec0db5..f64226e33 100644
--- a/plugins/setoid_ring/g_newring.ml4
+++ b/plugins/setoid_ring/g_newring.ml4
@@ -14,6 +14,10 @@ open Libnames
open Printer
open Newring_ast
open Newring
+open Stdarg
+open Constrarg
+open Pcoq.Constr
+open Pcoq.Tactic
DECLARE PLUGIN "newring_plugin"
@@ -46,14 +50,19 @@ VERNAC ARGUMENT EXTEND ring_mod
| [ "div" constr(div_spec) ] -> [ Div_spec div_spec ]
END
+VERNAC ARGUMENT EXTEND ring_mods
+ | [ "(" ne_ring_mod_list_sep(mods, ",") ")" ] -> [ mods ]
+END
+
VERNAC COMMAND EXTEND AddSetoidRing CLASSIFIED AS SIDEFF
- | [ "Add" "Ring" ident(id) ":" constr(t) ring_mods(l) ] ->
- [ let (k,set,cst,pre,post,power,sign, div) = process_ring_mods l in
+ | [ "Add" "Ring" ident(id) ":" constr(t) ring_mods_opt(l) ] ->
+ [ let l = match l with None -> [] | Some l -> l in
+ let (k,set,cst,pre,post,power,sign, div) = process_ring_mods l in
add_theory id (ic t) set k cst (pre,post) power sign div]
| [ "Print" "Rings" ] => [Vernac_classifier.classify_as_query] -> [
- msg_notice (strbrk "The following ring structures have been declared:");
+ Feedback.msg_notice (strbrk "The following ring structures have been declared:");
Spmap.iter (fun fn fi ->
- msg_notice (hov 2
+ Feedback.msg_notice (hov 2
(Ppconstr.pr_id (Libnames.basename fn)++spc()++
str"with carrier "++ pr_constr fi.ring_carrier++spc()++
str"and equivalence relation "++ pr_constr fi.ring_req))
@@ -70,14 +79,19 @@ VERNAC ARGUMENT EXTEND field_mod
| [ "completeness" constr(inj) ] -> [ Inject inj ]
END
+VERNAC ARGUMENT EXTEND field_mods
+ | [ "(" ne_field_mod_list_sep(mods, ",") ")" ] -> [ mods ]
+END
+
VERNAC COMMAND EXTEND AddSetoidField CLASSIFIED AS SIDEFF
-| [ "Add" "Field" ident(id) ":" constr(t) field_mods(l) ] ->
- [ let (k,set,inj,cst_tac,pre,post,power,sign,div) = process_field_mods l in
+| [ "Add" "Field" ident(id) ":" constr(t) field_mods_opt(l) ] ->
+ [ let l = match l with None -> [] | Some l -> l in
+ let (k,set,inj,cst_tac,pre,post,power,sign,div) = process_field_mods l in
add_field_theory id (ic t) set k cst_tac inj (pre,post) power sign div]
| [ "Print" "Fields" ] => [Vernac_classifier.classify_as_query] -> [
- msg_notice (strbrk "The following field structures have been declared:");
+ Feedback.msg_notice (strbrk "The following field structures have been declared:");
Spmap.iter (fun fn fi ->
- msg_notice (hov 2
+ Feedback.msg_notice (hov 2
(Ppconstr.pr_id (Libnames.basename fn)++spc()++
str"with carrier "++ pr_constr fi.field_carrier++spc()++
str"and equivalence relation "++ pr_constr fi.field_req))
diff --git a/plugins/setoid_ring/newring.ml b/plugins/setoid_ring/newring.ml
index 37a895976..57ef92032 100644
--- a/plugins/setoid_ring/newring.ml
+++ b/plugins/setoid_ring/newring.ml
@@ -6,8 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i camlp4deps: "grammar/grammar.cma" i*)
-
open Pp
open Errors
open Util
@@ -36,15 +34,6 @@ open Proofview.Notations
(****************************************************************************)
(* controlled reduction *)
-(** ppedrot: something dubious here, we're obviously using evars the wrong
- way. FIXME! *)
-
-let mark_arg i c = mkEvar(Evar.unsafe_of_int i,[|c|])
-let unmark_arg f c =
- match destEvar c with
- | (i,[|c|]) -> f (Evar.repr i) c
- | _ -> assert false
-
type protect_flag = Eval|Prot|Rec
let tag_arg tag_rec map subs i c =
@@ -77,12 +66,10 @@ and mk_clos_app_but f_map subs f args n =
let fargs, args' = Array.chop n args in
let f' = mkApp(f,fargs) in
match f_map (global_of_constr_nofail f') with
- Some map ->
- mk_clos_deep
- (fun s' -> unmark_arg (tag_arg (mk_clos_but f_map s') map s'))
- subs
- (mkApp (mark_arg (-1) f', Array.mapi mark_arg args'))
- | None -> mk_clos_app_but f_map subs f args (n+1)
+ | Some map ->
+ let f i t = tag_arg (mk_clos_but f_map subs) map subs i t in
+ mk_red (FApp (f (-1) f', Array.mapi f args'))
+ | None -> mk_atom (mkApp (f, args))
let interp_map l t =
try Some(List.assoc_f eq_gr t l) with Not_found -> None
@@ -108,6 +95,7 @@ let protect_tac_in map id =
(****************************************************************************)
let closed_term t l =
+ let open Quote_plugin in
let l = List.map Universes.constr_of_global l in
let cs = List.fold_right Quote.ConstrSet.add l Quote.ConstrSet.empty in
if Quote.closed_under cs t then tclIDTAC else tclFAIL 0 (mt())
@@ -155,11 +143,6 @@ let ic_unsafe c = (*FIXME remove *)
let sigma = Evd.from_env env in
fst (Constrintern.interp_constr env sigma c)
-let ty c =
- let env = Global.env() in
- let sigma = Evd.from_env env in
- Typing.unsafe_type_of env sigma c
-
let decl_constant na ctx c =
let vars = Universes.universes_of_constr c in
let ctx = Universes.restrict_universe_context (Univ.ContextSet.of_context ctx) vars in
@@ -187,9 +170,6 @@ let ltac_apply (f : Value.t) (args: Tacinterp.Value.t list) =
let ist = { (Tacinterp.default_ist ()) with Tacinterp.lfun = lfun; } in
Tacinterp.eval_tactic_ist ist (ltac_lcall "F" args)
-let ltac_record flds =
- TacFun([Some(Id.of_string"proj")], ltac_lcall "proj" flds)
-
let dummy_goal env sigma =
let (gl,_,sigma) =
Goal.V82.mk_goal sigma (named_context_val env) mkProp Evd.Store.empty in
@@ -292,8 +272,6 @@ let my_reference c =
let new_ring_path =
DirPath.make (List.map Id.of_string ["Ring_tac";plugin_dir;"Coq"])
-let ltac s =
- lazy(make_kn (MPfile new_ring_path) DirPath.empty (Label.make s))
let znew_ring_path =
DirPath.make (List.map Id.of_string ["InitialRing";plugin_dir;"Coq"])
let zltac s =
@@ -320,21 +298,12 @@ let coq_mk_reqe = my_constant "mk_reqe"
let coq_semi_ring_theory = my_constant "semi_ring_theory"
let coq_mk_seqe = my_constant "mk_seqe"
-let ltac_inv_morph_gen = zltac"inv_gen_phi"
-let ltac_inv_morphZ = zltac"inv_gen_phiZ"
-let ltac_inv_morphN = zltac"inv_gen_phiN"
-let ltac_inv_morphNword = zltac"inv_gen_phiNword"
let coq_abstract = my_constant"Abstract"
let coq_comp = my_constant"Computational"
let coq_morph = my_constant"Morphism"
-(* morphism *)
-let coq_ring_morph = my_constant "ring_morph"
-let coq_semi_morph = my_constant "semi_morph"
-
(* power function *)
let ltac_inv_morph_nothing = zltac"inv_morph_nothing"
-let coq_pow_N_pow_N = my_constant "pow_N_pow_N"
(* hypothesis *)
let coq_mkhypo = my_reference "mkhypo"
@@ -548,7 +517,7 @@ let ring_equality env evd (r,add,mul,opp,req) =
let op_morph =
op_morph r add mul opp req add_m_lem mul_m_lem opp_m_lem in
Flags.if_verbose
- msg_info
+ Feedback.msg_info
(str"Using setoid \""++pr_constr req++str"\""++spc()++
str"and morphisms \""++pr_constr add_m_lem ++
str"\","++spc()++ str"\""++pr_constr mul_m_lem++
@@ -557,7 +526,7 @@ let ring_equality env evd (r,add,mul,opp,req) =
op_morph)
| None ->
(Flags.if_verbose
- msg_info
+ Feedback.msg_info
(str"Using setoid \""++pr_constr req ++str"\"" ++ spc() ++
str"and morphisms \""++pr_constr add_m_lem ++
str"\""++spc()++str"and \""++
@@ -585,18 +554,6 @@ let dest_ring env sigma th_spec =
| _ -> error "bad ring structure"
-let dest_morph env sigma m_spec =
- let m_typ = Retyping.get_type_of env sigma m_spec in
- match kind_of_term m_typ with
- App(f,[|r;zero;one;add;mul;sub;opp;req;
- c;czero;cone;cadd;cmul;csub;copp;ceqb;phi|])
- when eq_constr_nounivs f (Lazy.force coq_ring_morph) ->
- (c,czero,cone,cadd,cmul,Some csub,Some copp,ceqb,phi)
- | App(f,[|r;zero;one;add;mul;req;c;czero;cone;cadd;cmul;ceqb;phi|])
- when eq_constr_nounivs f (Lazy.force coq_semi_morph) ->
- (c,czero,cone,cadd,cmul,None,None,ceqb,phi)
- | _ -> error "bad morphism structure"
-
let reflect_coeff rkind =
(* We build an ill-typed terms on purpose... *)
match rkind with
diff --git a/plugins/setoid_ring/newring.mli b/plugins/setoid_ring/newring.mli
index 07a1ae833..ca6aba9a0 100644
--- a/plugins/setoid_ring/newring.mli
+++ b/plugins/setoid_ring/newring.mli
@@ -45,7 +45,7 @@ val ic : constr_expr -> Evd.evar_map * constr
val from_name : ring_info Spmap.t ref
val ring_lookup :
- Genarg.Val.t ->
+ Geninterp.Val.t ->
constr list ->
constr list -> constr -> unit Proofview.tactic
@@ -73,6 +73,6 @@ val add_field_theory :
val field_from_name : field_info Spmap.t ref
val field_lookup :
- Genarg.Val.t ->
+ Geninterp.Val.t ->
constr list ->
constr list -> constr -> unit Proofview.tactic
diff --git a/plugins/setoid_ring/newring_plugin.mllib b/plugins/setoid_ring/newring_plugin.mllib
deleted file mode 100644
index 7d6c49588..000000000
--- a/plugins/setoid_ring/newring_plugin.mllib
+++ /dev/null
@@ -1,3 +0,0 @@
-Newring
-Newring_plugin_mod
-G_newring
diff --git a/plugins/setoid_ring/newring_plugin.mlpack b/plugins/setoid_ring/newring_plugin.mlpack
new file mode 100644
index 000000000..23663b409
--- /dev/null
+++ b/plugins/setoid_ring/newring_plugin.mlpack
@@ -0,0 +1,2 @@
+Newring
+G_newring
diff --git a/plugins/syntax/ascii_syntax.ml b/plugins/syntax/ascii_syntax.ml
index 67c9dd0a3..03b49e333 100644
--- a/plugins/syntax/ascii_syntax.ml
+++ b/plugins/syntax/ascii_syntax.ml
@@ -6,6 +6,10 @@
(* * GNU Lesser General Public License Version 2.1 *)
(***********************************************************************)
+(* Poor's man DECLARE PLUGIN *)
+let __coq_plugin_name = "ascii_syntax_plugin"
+let () = Mltop.add_known_module __coq_plugin_name
+
open Pp
open Errors
open Util
diff --git a/plugins/syntax/ascii_syntax_plugin.mllib b/plugins/syntax/ascii_syntax_plugin.mllib
deleted file mode 100644
index b00f92506..000000000
--- a/plugins/syntax/ascii_syntax_plugin.mllib
+++ /dev/null
@@ -1,2 +0,0 @@
-Ascii_syntax
-Ascii_syntax_plugin_mod
diff --git a/plugins/syntax/ascii_syntax_plugin.mlpack b/plugins/syntax/ascii_syntax_plugin.mlpack
new file mode 100644
index 000000000..7b9213a0e
--- /dev/null
+++ b/plugins/syntax/ascii_syntax_plugin.mlpack
@@ -0,0 +1 @@
+Ascii_syntax
diff --git a/plugins/syntax/nat_syntax.ml b/plugins/syntax/nat_syntax.ml
index 5f44904c3..3142c8cf0 100644
--- a/plugins/syntax/nat_syntax.ml
+++ b/plugins/syntax/nat_syntax.ml
@@ -6,6 +6,10 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(* Poor's man DECLARE PLUGIN *)
+let __coq_plugin_name = "nat_syntax_plugin"
+let () = Mltop.add_known_module __coq_plugin_name
+
(* This file defines the printer for natural numbers in [nat] *)
(*i*)
@@ -25,7 +29,7 @@ let threshold = of_int 5000
let nat_of_int dloc n =
if is_pos_or_zero n then begin
if less_than threshold n then
- msg_warning
+ Feedback.msg_warning
(strbrk "Stack overflow or segmentation fault happens when " ++
strbrk "working with large numbers in nat (observed threshold " ++
strbrk "may vary from 5000 to 70000 depending on your system " ++
diff --git a/plugins/syntax/nat_syntax_plugin.mllib b/plugins/syntax/nat_syntax_plugin.mllib
deleted file mode 100644
index 69b0cb20f..000000000
--- a/plugins/syntax/nat_syntax_plugin.mllib
+++ /dev/null
@@ -1,2 +0,0 @@
-Nat_syntax
-Nat_syntax_plugin_mod
diff --git a/plugins/syntax/nat_syntax_plugin.mlpack b/plugins/syntax/nat_syntax_plugin.mlpack
new file mode 100644
index 000000000..39bdd62f4
--- /dev/null
+++ b/plugins/syntax/nat_syntax_plugin.mlpack
@@ -0,0 +1 @@
+Nat_syntax
diff --git a/plugins/syntax/numbers_syntax.ml b/plugins/syntax/numbers_syntax.ml
index fe9f1319e..57cb2f897 100644
--- a/plugins/syntax/numbers_syntax.ml
+++ b/plugins/syntax/numbers_syntax.ml
@@ -6,6 +6,10 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(* Poor's man DECLARE PLUGIN *)
+let __coq_plugin_name = "numbers_syntax_plugin"
+let () = Mltop.add_known_module __coq_plugin_name
+
(* digit-based syntax for int31, bigN bigZ and bigQ *)
open Bigint
@@ -180,7 +184,7 @@ let bigN_of_pos_bigint dloc n =
let word = word_of_pos_bigint dloc h n in
let args =
if h < n_inlined then [word]
- else [Nat_syntax.nat_of_int dloc (of_int (h-n_inlined));word]
+ else [Nat_syntax_plugin.Nat_syntax.nat_of_int dloc (of_int (h-n_inlined));word]
in
GApp (dloc, ref_constructor, args)
diff --git a/plugins/syntax/numbers_syntax_plugin.mllib b/plugins/syntax/numbers_syntax_plugin.mllib
deleted file mode 100644
index ebc0bb202..000000000
--- a/plugins/syntax/numbers_syntax_plugin.mllib
+++ /dev/null
@@ -1,2 +0,0 @@
-Numbers_syntax
-Numbers_syntax_plugin_mod
diff --git a/plugins/syntax/numbers_syntax_plugin.mlpack b/plugins/syntax/numbers_syntax_plugin.mlpack
new file mode 100644
index 000000000..e48c00a0d
--- /dev/null
+++ b/plugins/syntax/numbers_syntax_plugin.mlpack
@@ -0,0 +1 @@
+Numbers_syntax
diff --git a/plugins/syntax/r_syntax.ml b/plugins/syntax/r_syntax.ml
index 05d73f9ec..3ae2d45f3 100644
--- a/plugins/syntax/r_syntax.ml
+++ b/plugins/syntax/r_syntax.ml
@@ -10,6 +10,10 @@ open Util
open Names
open Globnames
+(* Poor's man DECLARE PLUGIN *)
+let __coq_plugin_name = "r_syntax_plugin"
+let () = Mltop.add_known_module __coq_plugin_name
+
exception Non_closed_number
(**********************************************************************)
diff --git a/plugins/syntax/r_syntax_plugin.mllib b/plugins/syntax/r_syntax_plugin.mllib
deleted file mode 100644
index 5c173a140..000000000
--- a/plugins/syntax/r_syntax_plugin.mllib
+++ /dev/null
@@ -1,2 +0,0 @@
-R_syntax
-R_syntax_plugin_mod
diff --git a/plugins/syntax/r_syntax_plugin.mlpack b/plugins/syntax/r_syntax_plugin.mlpack
new file mode 100644
index 000000000..d4ee75ea4
--- /dev/null
+++ b/plugins/syntax/r_syntax_plugin.mlpack
@@ -0,0 +1 @@
+R_syntax
diff --git a/plugins/syntax/string_syntax.ml b/plugins/syntax/string_syntax.ml
index 2e696f391..de0fa77ef 100644
--- a/plugins/syntax/string_syntax.ml
+++ b/plugins/syntax/string_syntax.ml
@@ -7,10 +7,14 @@
(***********************************************************************)
open Globnames
-open Ascii_syntax
+open Ascii_syntax_plugin.Ascii_syntax
open Glob_term
open Coqlib
+(* Poor's man DECLARE PLUGIN *)
+let __coq_plugin_name = "string_syntax_plugin"
+let () = Mltop.add_known_module __coq_plugin_name
+
exception Non_closed_string
(* make a string term from the string s *)
diff --git a/plugins/syntax/string_syntax_plugin.mllib b/plugins/syntax/string_syntax_plugin.mllib
deleted file mode 100644
index b108c9e00..000000000
--- a/plugins/syntax/string_syntax_plugin.mllib
+++ /dev/null
@@ -1,2 +0,0 @@
-String_syntax
-String_syntax_plugin_mod
diff --git a/plugins/syntax/string_syntax_plugin.mlpack b/plugins/syntax/string_syntax_plugin.mlpack
new file mode 100644
index 000000000..45d6e0fa2
--- /dev/null
+++ b/plugins/syntax/string_syntax_plugin.mlpack
@@ -0,0 +1 @@
+String_syntax
diff --git a/plugins/syntax/z_syntax.ml b/plugins/syntax/z_syntax.ml
index 53c1b5d7a..ce86c0a65 100644
--- a/plugins/syntax/z_syntax.ml
+++ b/plugins/syntax/z_syntax.ml
@@ -12,6 +12,10 @@ open Util
open Names
open Bigint
+(* Poor's man DECLARE PLUGIN *)
+let __coq_plugin_name = "z_syntax_plugin"
+let () = Mltop.add_known_module __coq_plugin_name
+
exception Non_closed_number
(**********************************************************************)
diff --git a/plugins/syntax/z_syntax_plugin.mllib b/plugins/syntax/z_syntax_plugin.mllib
deleted file mode 100644
index 36d41acc2..000000000
--- a/plugins/syntax/z_syntax_plugin.mllib
+++ /dev/null
@@ -1,2 +0,0 @@
-Z_syntax
-Z_syntax_plugin_mod
diff --git a/plugins/syntax/z_syntax_plugin.mlpack b/plugins/syntax/z_syntax_plugin.mlpack
new file mode 100644
index 000000000..411260c04
--- /dev/null
+++ b/plugins/syntax/z_syntax_plugin.mlpack
@@ -0,0 +1 @@
+Z_syntax
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index 8a55a7aaa..b8fb61e35 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -25,6 +25,7 @@ open Glob_ops
open Retyping
open Pretype_errors
open Evarutil
+open Evardefine
open Evarsolve
open Evarconv
open Evd
@@ -1764,12 +1765,12 @@ let build_inversion_problem loc env sigma tms t =
Pushed (true,((tm,tmtyp),deps,na)))
dep_sign decls in
let subst = List.map (fun (na,t) -> (na,lift n t)) subst in
- (* [eqn1] is the first clause of the auxiliary pattern-matching that
+ (* [main_eqn] is the main clause of the auxiliary pattern-matching that
serves as skeleton for the return type: [patl] is the
substructure of constructors extracted from the list of
constraints on the inductive types of the multiple terms matched
in the original pattern-matching problem Xi *)
- let eqn1 =
+ let main_eqn =
{ patterns = patl;
alias_stack = [];
eqn_loc = Loc.ghost;
@@ -1780,19 +1781,24 @@ let build_inversion_problem loc env sigma tms t =
rhs_vars = List.map fst subst;
avoid_ids = avoid;
it = Some (lift n t) } } in
- (* [eqn2] is the default clause of the auxiliary pattern-matching: it will
- catch the clauses of the original pattern-matching problem Xi whose
- type constraints are incompatible with the constraints on the
+ (* [catch_all] is a catch-all default clause of the auxiliary
+ pattern-matching, if needed: it will catch the clauses
+ of the original pattern-matching problem Xi whose type
+ constraints are incompatible with the constraints on the
inductive types of the multiple terms matched in Xi *)
- let eqn2 =
- { patterns = List.map (fun _ -> PatVar (Loc.ghost,Anonymous)) patl;
- alias_stack = [];
- eqn_loc = Loc.ghost;
- used = ref false;
- rhs = { rhs_env = pb_env;
- rhs_vars = [];
- avoid_ids = avoid0;
- it = None } } in
+ let catch_all_eqn =
+ if List.for_all (irrefutable env) patl then
+ (* No need for a catch all clause *)
+ []
+ else
+ [ { patterns = List.map (fun _ -> PatVar (Loc.ghost,Anonymous)) patl;
+ alias_stack = [];
+ eqn_loc = Loc.ghost;
+ used = ref false;
+ rhs = { rhs_env = pb_env;
+ rhs_vars = [];
+ avoid_ids = avoid0;
+ it = None } } ] in
(* [pb] is the auxiliary pattern-matching serving as skeleton for the
return type of the original problem Xi *)
(* let sigma, s = Evd.new_sort_variable sigma in *)
@@ -1809,7 +1815,7 @@ let build_inversion_problem loc env sigma tms t =
pred = (*ty *) mkSort s;
tomatch = sub_tms;
history = start_history n;
- mat = [eqn1;eqn2];
+ mat = main_eqn :: catch_all_eqn;
caseloc = loc;
casestyle = RegularStyle;
typing_function = build_tycon loc env pb_env s subst} in
diff --git a/pretyping/cases.mli b/pretyping/cases.mli
index 257d1e578..d7fff8af4 100644
--- a/pretyping/cases.mli
+++ b/pretyping/cases.mli
@@ -32,6 +32,8 @@ val error_wrong_numarg_constructor_loc : Loc.t -> env -> constructor -> int -> '
val error_wrong_numarg_inductive_loc : Loc.t -> env -> inductive -> int -> 'a
+val irrefutable : env -> cases_pattern -> bool
+
(** {6 Compilation primitive. } *)
val compile_cases :
diff --git a/pretyping/cbv.ml b/pretyping/cbv.ml
index 43062a0e8..afd86420e 100644
--- a/pretyping/cbv.ml
+++ b/pretyping/cbv.ml
@@ -310,7 +310,7 @@ and cbv_stack_value info env = function
| (CONSTR(((sp,n),u),[||]), APP(args,PROJ(p,pi,stk)))
when red_set (info_flags info) fIOTA && Projection.unfolded p ->
let arg = args.(pi.Declarations.proj_npars + pi.Declarations.proj_arg) in
- cbv_stack_value info env (arg, stk)
+ cbv_stack_value info env (strip_appl arg stk)
(* may be reduced later by application *)
| (FIXP(fix,env,[||]), APP(appl,TOP)) -> FIXP(fix,env,appl)
diff --git a/pretyping/classops.ml b/pretyping/classops.ml
index ece92b66b..55220f44c 100644
--- a/pretyping/classops.ml
+++ b/pretyping/classops.ml
@@ -387,7 +387,7 @@ let add_coercion_in_graph (ic,source,target) =
end;
let is_ambig = match !ambig_paths with [] -> false | _ -> true in
if is_ambig && is_verbose () then
- msg_warning (message_ambig !ambig_paths)
+ Feedback.msg_warning (message_ambig !ambig_paths)
type coercion = {
coercion_type : coe_typ;
diff --git a/pretyping/classops.mli b/pretyping/classops.mli
index cf88be629..d509739cf 100644
--- a/pretyping/classops.mli
+++ b/pretyping/classops.mli
@@ -26,6 +26,9 @@ val cl_typ_eq : cl_typ -> cl_typ -> bool
val subst_cl_typ : substitution -> cl_typ -> cl_typ
+(** Comparison of [cl_typ] *)
+val cl_typ_ord : cl_typ -> cl_typ -> int
+
(** This is the type of infos for declared classes *)
type cl_info_typ = {
cl_param : int }
diff --git a/pretyping/coercion.ml b/pretyping/coercion.ml
index 57b273d0d..5c7adf1aa 100644
--- a/pretyping/coercion.ml
+++ b/pretyping/coercion.ml
@@ -129,7 +129,7 @@ let mu env evdref t =
let rec aux v =
let v' = hnf env !evdref v in
match disc_subset v' with
- Some (u, p) ->
+ | Some (u, p) ->
let f, ct = aux u in
let p = hnf_nodelta env !evdref p in
(Some (fun x ->
@@ -243,9 +243,8 @@ and coerce loc env evdref (x : Term.constr) (y : Term.constr)
let remove_head a c =
match kind_of_term c with
| Lambda (n, t, t') -> c, t'
- (*| Prod (n, t, t') -> t'*)
| Evar (k, args) ->
- let (evs, t) = Evarutil.define_evar_as_lambda env !evdref (k,args) in
+ let (evs, t) = Evardefine.define_evar_as_lambda env !evdref (k,args) in
evdref := evs;
let (n, dom, rng) = destLambda t in
let dom = whd_evar !evdref dom in
@@ -299,9 +298,7 @@ and coerce loc env evdref (x : Term.constr) (y : Term.constr)
with NoSubtacCoercion ->
let typ = Typing.unsafe_type_of env evm c in
let typ' = Typing.unsafe_type_of env evm c' in
- (* if not (is_arity env evm typ) then *)
coerce_application typ typ' c c' l l')
- (* else subco () *)
else
subco ()
| x, y when Constr.equal c c' ->
@@ -309,9 +306,7 @@ and coerce loc env evdref (x : Term.constr) (y : Term.constr)
let evm = !evdref in
let lam_type = Typing.unsafe_type_of env evm c in
let lam_type' = Typing.unsafe_type_of env evm c' in
- (* if not (is_arity env evm lam_type) then ( *)
coerce_application lam_type lam_type' c c' l l'
- (* ) else subco () *)
else subco ()
| _ -> subco ())
| _, _ -> subco ()
@@ -337,10 +332,17 @@ and coerce loc env evdref (x : Term.constr) (y : Term.constr)
raise NoSubtacCoercion
in coerce_unify env x y
+let app_coercion env evdref coercion v =
+ match coercion with
+ | None -> v
+ | Some f ->
+ let v' = Typing.e_solve_evars env evdref (f v) in
+ whd_betaiota !evdref v'
+
let coerce_itf loc env evd v t c1 =
let evdref = ref evd in
let coercion = coerce loc env evdref t c1 in
- let t = Option.map (app_opt env evdref coercion) v in
+ let t = Option.map (app_coercion env evdref coercion) v in
!evdref, t
let saturate_evd env evd =
@@ -375,7 +377,7 @@ let inh_app_fun_core env evd j =
match kind_of_term t with
| Prod (_,_,_) -> (evd,j)
| Evar ev ->
- let (evd',t) = define_evar_as_product evd ev in
+ let (evd',t) = Evardefine.define_evar_as_product evd ev in
(evd',{ uj_val = j.uj_val; uj_type = t })
| _ ->
try let t,p =
@@ -416,7 +418,7 @@ let inh_coerce_to_sort loc env evd j =
match kind_of_term typ with
| Sort s -> (evd,{ utj_val = j.uj_val; utj_type = s })
| Evar ev when not (is_defined evd (fst ev)) ->
- let (evd',s) = define_evar_as_sort env evd ev in
+ let (evd',s) = Evardefine.define_evar_as_sort env evd ev in
(evd',{ utj_val = j.uj_val; utj_type = s })
| _ ->
inh_tosort_force loc env evd j
@@ -426,7 +428,7 @@ let inh_coerce_to_base loc env evd j =
let evdref = ref evd in
let ct, typ' = mu env evdref j.uj_type in
let res =
- { uj_val = app_opt env evdref ct j.uj_val;
+ { uj_val = app_coercion env evdref ct j.uj_val;
uj_type = typ' }
in !evdref, res
else (evd, j)
diff --git a/pretyping/constr_matching.ml b/pretyping/constr_matching.ml
index 4fb411202..129725c6d 100644
--- a/pretyping/constr_matching.ml
+++ b/pretyping/constr_matching.ml
@@ -50,11 +50,11 @@ type bound_ident_map = Id.t Id.Map.t
exception PatternMatchingFailure
let warn_bound_meta name =
- msg_warning (str "Collision between bound variable " ++ pr_id name ++
+ Feedback.msg_warning (str "Collision between bound variable " ++ pr_id name ++
str " and a metavariable of same name.")
let warn_bound_bound name =
- msg_warning (str "Collision between bound variables of name " ++ pr_id name)
+ Feedback.msg_warning (str "Collision between bound variables of name " ++ pr_id name)
let constrain n (ids, m as x) (names, terms as subst) =
try
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index c973e1cef..86921c49b 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -620,7 +620,7 @@ and share_names flags n l avoid env sigma c t =
share_names 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 msg_warning (strbrk "Detyping.detype: cannot factorize fix enough");
+ if n>0 then Feedback.msg_warning (strbrk "Detyping.detype: cannot factorize fix enough");
let c = detype flags avoid env sigma c in
let t = detype flags avoid env sigma t in
(List.rev l,c,t)
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 0ccc5b654..e5fc5a188 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -18,6 +18,7 @@ open Termops
open Environ
open Recordops
open Evarutil
+open Evardefine
open Evarsolve
open Globnames
open Evd
@@ -102,8 +103,7 @@ let position_problem l2r = function
| CUMUL -> Some l2r
let occur_rigidly ev evd t =
- let (l, app) = decompose_app_vect t in
- let rec aux t =
+ let rec aux t =
match kind_of_term (whd_evar evd t) with
| App (f, c) -> if aux f then Array.exists aux c else false
| Construct _ | Ind _ | Sort _ | Meta _ | Fix _ | CoFix _ -> true
@@ -115,7 +115,7 @@ let occur_rigidly ev evd t =
| Prod (_, b, t) -> ignore(aux b || aux t); true
| Rel _ | Var _ -> false
| Case _ -> false
- in Array.exists (fun t -> try ignore(aux t); false with Occur -> true) app
+ in try ignore(aux t); false with Occur -> true
(* [check_conv_record env sigma (t1,stack1) (t2,stack2)] tries to decompose
the problem (t1 stack1) = (t2 stack2) into a problem
@@ -143,6 +143,7 @@ let check_conv_record env sigma (t1,sk1) (t2,sk2) =
try
match kind_of_term t2 with
Prod (_,a,b) -> (* assert (l2=[]); *)
+ let _, a, b = destProd (Evarutil.nf_evar sigma t2) in
if dependent (mkRel 1) b then raise Not_found
else lookup_canonical_conversion (proji, Prod_cs),
(Stack.append_app [|a;pop b|] Stack.empty)
@@ -366,8 +367,6 @@ let rec evar_conv_x ts env evd pbty term1 term2 =
and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
((term1,sk1 as appr1),csts1) ((term2,sk2 as appr2),csts2) =
- let default_fail i = (* costly *)
- UnifFailure (i,ConversionFailed (env, Stack.zip appr1, Stack.zip appr2)) in
let quick_fail i = (* not costly, loses info *)
UnifFailure (i, NotSameHead)
in
@@ -419,7 +418,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
let not_only_app = Stack.not_purely_applicative skM in
let f1 i =
match Stack.list_of_app_stack skF with
- | None -> default_fail evd
+ | None -> quick_fail evd
| Some lF ->
let tM = Stack.zip apprM in
miller_pfenning on_left
@@ -466,10 +465,11 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
let flex_rigid on_left ev (termF, skF as apprF) (termR, skR as apprR) =
let switch f a b = if on_left then f a b else f b a in
let eta evd =
- match kind_of_term termR with
- | Lambda _ -> eta env evd false skR termR skF termF
- | Construct u -> eta_constructor ts env evd skR u skF termF
- | _ -> UnifFailure (evd,NotSameHead)
+ match kind_of_term termR with
+ | Lambda _ when (* if ever problem is ill-typed: *) List.is_empty skR ->
+ eta env evd false skR termR skF termF
+ | Construct u -> eta_constructor ts env evd skR u skF termF
+ | _ -> UnifFailure (evd,NotSameHead)
in
match Stack.list_of_app_stack skF with
| None ->
@@ -499,15 +499,18 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
(* Evar must be undefined since we have flushed evars *)
let () = if !debug_unification then
let open Pp in
- pp (v 0 (pr_state appr1 ++ cut () ++ pr_state appr2 ++ cut ())
+ Feedback.msg_notice (v 0 (pr_state appr1 ++ cut () ++ pr_state appr2 ++ cut ())
++ fnl ()) in
match (flex_kind_of_term (fst ts) env evd term1 sk1,
flex_kind_of_term (fst ts) env evd term2 sk2) with
| Flexible (sp1,al1 as ev1), Flexible (sp2,al2 as ev2) ->
+ (* sk1[?ev1] =? sk2[?ev2] *)
let f1 i =
+ (* Try first-order unification *)
match ise_stack2 false env i (evar_conv_x ts) sk1 sk2 with
- |None, Success i' ->
- (* Evar can be defined in i' *)
+ | None, Success i' ->
+ (* We do have sk1[] = sk2[]: we now unify ?ev1 and ?ev2 *)
+ (* Note that ?ev1 and ?ev2, may have been instantiated in the meantime *)
let ev1' = whd_evar i' (mkEvar ev1) in
if isEvar ev1' then
solve_simple_eqn (evar_conv_x ts) env i'
@@ -515,7 +518,9 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
else
evar_eqappr_x ts env evd pbty
((ev1', sk1), csts1) ((term2, sk2), csts2)
- |Some (r,[]), Success i' ->
+ | Some (r,[]), Success i' ->
+ (* We have sk1'[] = sk2[] for some sk1' s.t. sk1[]=sk1'[r[]] *)
+ (* we now unify r[?ev1] and ?ev2 *)
let ev2' = whd_evar i' (mkEvar ev2) in
if isEvar ev2' then
solve_simple_eqn (evar_conv_x ts) env i'
@@ -523,16 +528,46 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
else
evar_eqappr_x ts env evd pbty
((ev2', sk1), csts1) ((term2, sk2), csts2)
-
- |Some ([],r), Success i' ->
+ | Some ([],r), Success i' ->
+ (* Symmetrically *)
+ (* We have sk1[] = sk2'[] for some sk2' s.t. sk2[]=sk2'[r[]] *)
+ (* we now unify ?ev1 and r[?ev2] *)
let ev1' = whd_evar i' (mkEvar ev1) in
if isEvar ev1' then
solve_simple_eqn (evar_conv_x ts) env i'
(position_problem true pbty,destEvar ev1',Stack.zip(term2,r))
else evar_eqappr_x ts env evd pbty
((ev1', sk1), csts1) ((term2, sk2), csts2)
- |_, (UnifFailure _ as x) -> x
- |Some _, _ -> UnifFailure (i,NotSameArgSize)
+ | None, (UnifFailure _ as x) ->
+ (* sk1 and sk2 have no common outer part *)
+ if Stack.not_purely_applicative sk2 then
+ (* Ad hoc compatibility with 8.4 which treated non-app as rigid *)
+ flex_rigid true ev1 appr1 appr2
+ else
+ if Stack.not_purely_applicative sk1 then
+ (* Ad hoc compatibility with 8.4 which treated non-app as rigid *)
+ flex_rigid false ev2 appr2 appr1
+ else
+ (* We could instead try Miller unification, then
+ postpone to see if other equations help, as in:
+ [Check fun a b : unit => (eqᵣefl : _ a = _ a b)] *)
+ x
+ | Some _, Success _ ->
+ (* sk1 and sk2 have a common outer part *)
+ if Stack.not_purely_applicative sk2 then
+ (* Ad hoc compatibility with 8.4 which treated non-app as rigid *)
+ flex_rigid true ev1 appr1 appr2
+ else
+ if Stack.not_purely_applicative sk1 then
+ (* Ad hoc compatibility with 8.4 which treated non-app as rigid *)
+ flex_rigid false ev2 appr2 appr1
+ else
+ (* We could instead try Miller unification, then
+ postpone to see if other equations help, as in:
+ [Check fun a b c : unit => (eqᵣefl : _ a b = _ c a b)] *)
+ UnifFailure (i,NotSameArgSize)
+ | _, _ -> anomaly (Pp.str "Unexpected result from ise_stack2.")
+
and f2 i =
if Evar.equal sp1 sp2 then
match ise_stack2 false env i (evar_conv_x ts) sk1 sk2 with
@@ -710,10 +745,10 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
ise_try evd [f3; f4]
(* Eta-expansion *)
- | Rigid, _ when isLambda term1 ->
+ | Rigid, _ when isLambda term1 && (* if ever ill-typed: *) List.is_empty sk1 ->
eta env evd true sk1 term1 sk2 term2
- | _, Rigid when isLambda term2 ->
+ | _, Rigid when isLambda term2 && (* if ever ill-typed: *) List.is_empty sk2 ->
eta env evd false sk2 term2 sk1 term1
| Rigid, Rigid -> begin
@@ -858,7 +893,7 @@ and conv_record trs env evd (ctx,(h,h2),c,bs,(params,params1),(us,us2),(sk1,sk2)
and eta_constructor ts env evd sk1 ((ind, i), u) sk2 term2 =
let mib = lookup_mind (fst ind) env in
match mib.Declarations.mind_record with
- | Some (Some (id, projs, pbs)) when mib.Declarations.mind_finite <> Decl_kinds.CoFinite ->
+ | Some (Some (id, projs, pbs)) when mib.Declarations.mind_finite == Decl_kinds.BiFinite ->
let pars = mib.Declarations.mind_nparams in
(try
let l1' = Stack.tail pars sk1 in
@@ -1069,7 +1104,7 @@ let second_order_matching ts env_rhs evd (evk,args) argoccs rhs =
abstract_free_holes evd subst, true
with TypingFailed evd -> evd, false
-let second_order_matching_with_args ts env evd ev l t =
+let second_order_matching_with_args ts env evd pbty ev l t =
(*
let evd,ev = evar_absorb_arguments env evd ev l in
let argoccs = Array.map_to_list (fun _ -> None) (snd ev) in
@@ -1077,8 +1112,9 @@ let second_order_matching_with_args ts env evd ev l t =
if b then Success evd
else UnifFailure (evd, ConversionFailed (env,mkApp(mkEvar ev,l),t))
if b then Success evd else
-*)
- UnifFailure (evd, ConversionFailed (env,mkApp(mkEvar ev,l),t))
+ *)
+ 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 =
let t1 = apprec_nohdbeta ts env evd (whd_head_evar evd t1) in
@@ -1094,7 +1130,9 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
type inference *)
(match choose_less_dependent_instance evk1 evd term2 args1 with
| Some evd -> Success evd
- | None -> UnifFailure (evd, ConversionFailed (env,term1,term2)))
+ | None ->
+ let reason = ProblemBeyondCapabilities in
+ UnifFailure (evd, CannotSolveConstraint ((pbty,env,t1,t2),reason)))
| (Rel _|Var _), Evar (evk2,args2) when app_empty
&& List.for_all (fun a -> Term.eq_constr a term1 || isEvar a)
(remove_instance_local_defs evd evk2 args2) ->
@@ -1102,7 +1140,9 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
type inference *)
(match choose_less_dependent_instance evk2 evd term1 args2 with
| Some evd -> Success evd
- | None -> UnifFailure (evd, ConversionFailed (env,term1,term2)))
+ | None ->
+ let reason = ProblemBeyondCapabilities in
+ 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
@@ -1117,20 +1157,20 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
ise_try evd
[(fun evd -> first_order_unification ts env evd (ev1,l1) appr2);
(fun evd ->
- second_order_matching_with_args ts env evd ev1 l1 t2)]
+ second_order_matching_with_args ts env evd pbty ev1 l1 t2)]
| _,Evar ev2 when Array.length l2 <= Array.length l1 ->
(* On "u u1 .. u(n+p) = ?n t1 .. tn", try first-order unification *)
(* and otherwise second-order matching *)
ise_try evd
[(fun evd -> first_order_unification ts env evd (ev2,l2) appr1);
(fun evd ->
- second_order_matching_with_args ts env evd ev2 l2 t1)]
+ second_order_matching_with_args ts env evd pbty ev2 l2 t1)]
| Evar ev1,_ ->
(* Try second-order pattern-matching *)
- second_order_matching_with_args ts env evd ev1 l1 t2
+ second_order_matching_with_args ts env evd pbty ev1 l1 t2
| _,Evar ev2 ->
(* Try second-order pattern-matching *)
- second_order_matching_with_args ts env evd ev2 l2 t1
+ second_order_matching_with_args ts env evd pbty ev2 l2 t1
| _ ->
(* Some head evar have been instantiated, or unknown kind of problem *)
evar_conv_x ts env evd pbty t1 t2
diff --git a/pretyping/evardefine.ml b/pretyping/evardefine.ml
new file mode 100644
index 000000000..d349cf821
--- /dev/null
+++ b/pretyping/evardefine.ml
@@ -0,0 +1,207 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Util
+open Pp
+open Names
+open Term
+open Vars
+open Termops
+open Namegen
+open Environ
+open Evd
+open Evarutil
+open Pretype_errors
+open Sigma.Notations
+
+let new_evar_unsafe env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
+ let evd = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (evk, evd, _) = new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ in
+ (Sigma.to_evar_map evd, evk)
+
+let env_nf_evar sigma env =
+ let open Context.Rel.Declaration in
+ process_rel_context
+ (fun d e -> push_rel (map_constr (nf_evar sigma) d) e) env
+
+let env_nf_betaiotaevar sigma env =
+ let open Context.Rel.Declaration in
+ process_rel_context
+ (fun d e ->
+ push_rel (map_constr (Reductionops.nf_betaiota sigma) d) e) env
+
+(****************************************)
+(* Operations on value/type constraints *)
+(****************************************)
+
+type type_constraint = types option
+
+type val_constraint = constr option
+
+(* Old comment...
+ * Basically, we have the following kind of constraints (in increasing
+ * strength order):
+ * (false,(None,None)) -> no constraint at all
+ * (true,(None,None)) -> we must build a judgement which _TYPE is a kind
+ * (_,(None,Some ty)) -> we must build a judgement which _TYPE is ty
+ * (_,(Some v,_)) -> we must build a judgement which _VAL is v
+ * Maybe a concrete datatype would be easier to understand.
+ * We differentiate (true,(None,None)) from (_,(None,Some Type))
+ * because otherwise Case(s) would be misled, as in
+ * (n:nat) Case n of bool [_]nat end would infer the predicate Type instead
+ * of Set.
+ *)
+
+(* The empty type constraint *)
+let empty_tycon = None
+
+(* Builds a type constraint *)
+let mk_tycon ty = Some ty
+
+(* Constrains the value of a type *)
+let empty_valcon = None
+
+(* Builds a value constraint *)
+let mk_valcon c = Some c
+
+let idx = Namegen.default_dependent_ident
+
+(* Refining an evar to a product *)
+
+let define_pure_evar_as_product evd evk =
+ let open Context.Named.Declaration in
+ let evi = Evd.find_undefined evd evk in
+ let evenv = evar_env evi in
+ let id = next_ident_away idx (ids_of_named_context (evar_context evi)) in
+ let concl = Reductionops.whd_betadeltaiota evenv evd evi.evar_concl in
+ let s = destSort concl in
+ let evd1,(dom,u1) =
+ let evd = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (e, evd1, _) = new_type_evar evenv evd univ_flexible_alg ~filter:(evar_filter evi) in
+ (Sigma.to_evar_map evd1, e)
+ in
+ let evd2,rng =
+ let newenv = push_named (LocalAssum (id, dom)) evenv in
+ let src = evar_source evk evd1 in
+ let filter = Filter.extend 1 (evar_filter evi) in
+ if is_prop_sort s then
+ (* Impredicative product, conclusion must fall in [Prop]. *)
+ new_evar_unsafe newenv evd1 concl ~src ~filter
+ else
+ let status = univ_flexible_alg in
+ let evd3, (rng, srng) =
+ let evd1 = Sigma.Unsafe.of_evar_map evd1 in
+ let Sigma (e, evd3, _) = new_type_evar newenv evd1 status ~src ~filter in
+ (Sigma.to_evar_map evd3, e)
+ in
+ let prods = Univ.sup (univ_of_sort u1) (univ_of_sort srng) in
+ let evd3 = Evd.set_leq_sort evenv evd3 (Type prods) s in
+ evd3, rng
+ in
+ let prod = mkProd (Name id, dom, subst_var id rng) in
+ let evd3 = Evd.define evk prod evd2 in
+ evd3,prod
+
+(* Refine an applied evar to a product and returns its instantiation *)
+
+let define_evar_as_product evd (evk,args) =
+ let evd,prod = define_pure_evar_as_product evd evk in
+ (* Quick way to compute the instantiation of evk with args *)
+ let na,dom,rng = destProd prod in
+ let evdom = mkEvar (fst (destEvar dom), args) in
+ let evrngargs = Array.cons (mkRel 1) (Array.map (lift 1) args) in
+ let evrng = mkEvar (fst (destEvar rng), evrngargs) in
+ evd,mkProd (na, evdom, evrng)
+
+(* Refine an evar with an abstraction
+
+ I.e., solve x1..xq |- ?e:T(x1..xq) with e:=λy:A.?e'[x1..xq,y] where:
+ - either T(x1..xq) = πy:A(x1..xq).B(x1..xq,y)
+ or T(x1..xq) = ?d[x1..xq] and we define ?d := πy:?A.?B
+ with x1..xq |- ?A:Type and x1..xq,y |- ?B:Type
+ - x1..xq,y:A |- ?e':B
+*)
+
+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_betadeltaiota evenv evd (evar_concl evi) in
+ let evd1,(na,dom,rng) = match kind_of_term typ with
+ | Prod (na,dom,rng) -> (evd,(na,dom,rng))
+ | Evar ev' -> let evd,typ = define_evar_as_product evd ev' in evd,destProd typ
+ | _ -> error_not_product_loc Loc.ghost env evd typ in
+ let avoid = ids_of_named_context (evar_context evi) in
+ let id =
+ next_name_away_with_default_using_types "x" na avoid (Reductionops.whd_evar evd dom) in
+ let newenv = push_named (LocalAssum (id, dom)) evenv in
+ let filter = Filter.extend 1 (evar_filter evi) in
+ let src = evar_source evk evd1 in
+ let evd2,body = new_evar_unsafe newenv evd1 ~src (subst1 (mkVar id) rng) ~filter in
+ let lam = mkLambda (Name id, dom, subst_var id body) in
+ 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
+ (* Quick way to compute the instantiation of evk with args *)
+ let na,dom,body = destLambda lam in
+ let evbodyargs = Array.cons (mkRel 1) (Array.map (lift 1) args) in
+ let evbody = mkEvar (fst (destEvar body), evbodyargs) in
+ evd,mkLambda (na, dom, evbody)
+
+let rec evar_absorb_arguments env evd (evk,args as ev) = function
+ | [] -> evd,ev
+ | a::l ->
+ (* TODO: optimize and avoid introducing intermediate evars *)
+ let evd,lam = define_pure_evar_as_lambda env evd evk in
+ let _,_,body = destLambda lam in
+ let evk = fst (destEvar body) in
+ evar_absorb_arguments env evd (evk, Array.cons a args) l
+
+(* Refining an evar to a sort *)
+
+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_betadeltaiota (evar_env evi) evd evi.evar_concl in
+ let sort = destSort concl in
+ let evd' = Evd.define ev (mkSort s) evd in
+ Evd.set_leq_sort env evd' (Type (Univ.super u)) sort, s
+
+(* Propagation of constraints through application and abstraction:
+ Given a type constraint on a functional term, returns the type
+ constraint on its domain and codomain. If the input constraint is
+ an evar instantiate it with the product of 2 new evars. *)
+
+let split_tycon loc env evd tycon =
+ let rec real_split evd c =
+ let t = Reductionops.whd_betadeltaiota env evd c in
+ match kind_of_term t with
+ | Prod (na,dom,rng) -> evd, (na, dom, rng)
+ | Evar ev (* ev is undefined because of whd_betadeltaiota *) ->
+ let (evd',prod) = define_evar_as_product evd ev in
+ let (_,dom,rng) = destProd prod in
+ evd',(Anonymous, dom, rng)
+ | App (c,args) when isEvar c ->
+ let (evd',lam) = define_evar_as_lambda env evd (destEvar c) in
+ real_split evd' (mkApp (lam,args))
+ | _ -> error_not_product_loc loc env evd c
+ in
+ match tycon with
+ | None -> evd,(Anonymous,None,None)
+ | Some c ->
+ let evd', (n, dom, rng) = real_split evd c in
+ evd', (n, mk_tycon dom, mk_tycon rng)
+
+let valcon_of_tycon x = x
+let lift_tycon n = Option.map (lift n)
+
+let pr_tycon env = function
+ None -> str "None"
+ | Some t -> Termops.print_constr_env env t
diff --git a/pretyping/evardefine.mli b/pretyping/evardefine.mli
new file mode 100644
index 000000000..07b0e69d9
--- /dev/null
+++ b/pretyping/evardefine.mli
@@ -0,0 +1,46 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Names
+open Term
+open Evd
+open Environ
+
+val env_nf_evar : evar_map -> env -> env
+val env_nf_betaiotaevar : evar_map -> env -> env
+
+type type_constraint = types option
+type val_constraint = constr option
+
+val empty_tycon : type_constraint
+val mk_tycon : constr -> type_constraint
+val empty_valcon : val_constraint
+val mk_valcon : constr -> val_constraint
+
+(** Instantiate an evar by as many lambda's as needed so that its arguments
+ are moved to the evar substitution (i.e. turn [?x[vars1:=args1] args] into
+ [?y[vars1:=args1,vars:=args]] with
+ [vars1 |- ?x:=\vars.?y[vars1:=vars1,vars:=vars]] *)
+val evar_absorb_arguments : env -> evar_map -> existential -> constr list ->
+ evar_map * existential
+
+val split_tycon :
+ Loc.t -> env -> evar_map -> type_constraint ->
+ evar_map * (Name.t * type_constraint * type_constraint)
+
+val valcon_of_tycon : type_constraint -> val_constraint
+val lift_tycon : int -> type_constraint -> type_constraint
+
+val define_evar_as_product : evar_map -> existential -> evar_map * types
+val define_evar_as_lambda : env -> evar_map -> existential -> evar_map * types
+val define_evar_as_sort : env -> evar_map -> existential -> evar_map * sorts
+
+(** {6 debug pretty-printer:} *)
+
+val pr_tycon : env -> type_constraint -> Pp.std_ppcmds
+
diff --git a/pretyping/evarsolve.ml b/pretyping/evarsolve.ml
index 3d1822102..455a7dbd6 100644
--- a/pretyping/evarsolve.ml
+++ b/pretyping/evarsolve.ml
@@ -20,7 +20,6 @@ open Reductionops
open Evarutil
open Pretype_errors
open Sigma.Notations
-open Context.Rel.Declaration
let normalize_evar evd ev =
match kind_of_term (whd_evar evd (mkEvar ev)) with
diff --git a/pretyping/find_subterm.ml b/pretyping/find_subterm.ml
index ae8b91c34..df1fc20f1 100644
--- a/pretyping/find_subterm.ml
+++ b/pretyping/find_subterm.ml
@@ -108,7 +108,6 @@ let replace_term_occ_gen_modulo occs like_first test bywhat cl occ t =
raise (SubtermUnificationError (!nested,((cl,!pos),t),lastpos,e)) in
let rec substrec k t =
if nowhere_except_in && !pos > maxocc then t else
- if not (Vars.closed0 t) then subst_below k t else
try
let subst = test.match_fun test.testing_state t in
if Locusops.is_selected !pos occs then
diff --git a/pretyping/glob_ops.ml b/pretyping/glob_ops.ml
index c9860864a..04100c8a7 100644
--- a/pretyping/glob_ops.ml
+++ b/pretyping/glob_ops.ml
@@ -266,7 +266,7 @@ let add_name_to_ids set na =
| Anonymous -> set
| Name id -> Id.Set.add id set
-let free_glob_vars =
+let free_glob_vars =
let rec vars bounded vs = function
| GVar (loc,id') -> if Id.Set.mem id' bounded then vs else Id.Set.add id' vs
| GApp (loc,f,args) -> List.fold_left (vars bounded) vs (f::args)
@@ -324,10 +324,20 @@ let free_glob_vars =
let vs = vars Id.Set.empty Id.Set.empty rt in
Id.Set.elements vs
+let glob_visible_short_qualid c =
+ let rec aux acc = function
+ | GRef (_,c,_) ->
+ let qualid = Nametab.shortest_qualid_of_global Id.Set.empty c in
+ let dir,id = Libnames.repr_qualid qualid in
+ if DirPath.is_empty dir then id :: acc else acc
+ | c ->
+ fold_glob_constr aux acc c
+ in aux [] c
+
let add_and_check_ident id set =
if Id.Set.mem id set then
- Pp.(msg_warning
- (str "Collision between bound variables of name " ++ Id.print id));
+ Feedback.msg_warning
+ Pp.(str "Collision between bound variables of name " ++ Id.print id);
Id.Set.add id set
let bound_glob_vars =
diff --git a/pretyping/glob_ops.mli b/pretyping/glob_ops.mli
index 45444234a..e0a2de032 100644
--- a/pretyping/glob_ops.mli
+++ b/pretyping/glob_ops.mli
@@ -40,6 +40,7 @@ val occur_glob_constr : Id.t -> glob_constr -> bool
val free_glob_vars : glob_constr -> Id.t list
val bound_glob_vars : glob_constr -> Id.Set.t
val loc_of_glob_constr : glob_constr -> Loc.t
+val glob_visible_short_qualid : glob_constr -> Id.t list
(** [map_pattern_binders f m c] applies [f] to all the binding names
in a pattern-matching expression ({!Glob_term.GCases}) represented
diff --git a/pretyping/indrec.ml b/pretyping/indrec.ml
index 713c99597..5d36fc78e 100644
--- a/pretyping/indrec.ml
+++ b/pretyping/indrec.ml
@@ -184,7 +184,7 @@ let type_rec_branch is_rec dep env sigma (vargs,depPvect,decP) tyi cs recargs =
(match dest_recarg ra with
| Mrec (_,j) when is_rec -> (depPvect.(j),rest)
| Imbr _ ->
- msg_warning (strbrk "Ignoring recursive call");
+ Feedback.msg_warning (strbrk "Ignoring recursive call");
(None,rest)
| _ -> (None, rest))
in
@@ -592,7 +592,7 @@ let make_elimination_ident id s = add_suffix id (elimination_suffix s)
let lookup_eliminator ind_sp s =
let kn,i = ind_sp in
- let mp,dp,l = repr_mind kn in
+ let mp,dp,l = KerName.repr (MutInd.canonical kn) in
let ind_id = (Global.lookup_mind kn).mind_packets.(i).mind_typename in
let id = add_suffix ind_id (elimination_suffix s) in
(* Try first to get an eliminator defined in the same section as the *)
diff --git a/pretyping/nativenorm.ml b/pretyping/nativenorm.ml
index 8ddfeaf2f..2a5e99965 100644
--- a/pretyping/nativenorm.ml
+++ b/pretyping/nativenorm.ml
@@ -18,7 +18,6 @@ open Inductive
open Util
open Nativecode
open Nativevalues
-open Nativelambda
open Context.Rel.Declaration
(** This module implements normalization by evaluation to OCaml code *)
@@ -390,16 +389,16 @@ let native_norm env sigma c ty =
let code, upd = mk_norm_code penv sigma prefix c in
match Nativelib.compile ml_filename code with
| true, fn ->
- if !Flags.debug then Pp.msg_debug (Pp.str "Running norm ...");
+ if !Flags.debug then Feedback.msg_debug (Pp.str "Running norm ...");
let t0 = Sys.time () in
Nativelib.call_linker ~fatal:true prefix fn (Some upd);
let t1 = Sys.time () in
let time_info = Format.sprintf "Evaluation done in %.5f@." (t1 -. t0) in
- if !Flags.debug then Pp.msg_debug (Pp.str time_info);
+ if !Flags.debug then Feedback.msg_debug (Pp.str time_info);
let res = nf_val env !Nativelib.rt1 ty in
let t2 = Sys.time () in
let time_info = Format.sprintf "Reification done in %.5f@." (t2 -. t1) in
- if !Flags.debug then Pp.msg_debug (Pp.str time_info);
+ if !Flags.debug then Feedback.msg_debug (Pp.str time_info);
res
| _ -> anomaly (Pp.str "Compilation failure")
diff --git a/pretyping/patternops.ml b/pretyping/patternops.ml
index 827071054..d6305d81a 100644
--- a/pretyping/patternops.ml
+++ b/pretyping/patternops.ml
@@ -348,7 +348,7 @@ let rec pat_of_raw metas vars = function
| GHole _ ->
PMeta None
| GCast (_,c,_) ->
- Pp.msg_warning (strbrk "Cast not taken into account in constr pattern");
+ Feedback.msg_warning (strbrk "Cast not taken into account in constr pattern");
pat_of_raw metas vars c
| GIf (_,c,(_,None),b1,b2) ->
PIf (pat_of_raw metas vars c,
diff --git a/pretyping/pretype_errors.ml b/pretyping/pretype_errors.ml
index cf5b08c58..b0715af73 100644
--- a/pretyping/pretype_errors.ml
+++ b/pretyping/pretype_errors.ml
@@ -14,15 +14,16 @@ open Type_errors
type unification_error =
| OccurCheck of existential_key * constr
- | NotClean of existential * env * constr
+ | NotClean of existential * env * constr (* Constr is a variable not in scope *)
| NotSameArgSize
| NotSameHead
| NoCanonicalStructure
- | ConversionFailed of env * constr * constr
+ | ConversionFailed of env * constr * constr (* Non convertible closed terms *)
| MetaOccurInBody of existential_key
| InstanceNotSameType of existential_key * env * types * types
| UnifUnivInconsistency of Univ.univ_inconsistency
| CannotSolveConstraint of Evd.evar_constraint * unification_error
+ | ProblemBeyondCapabilities
type position = (Id.t * Locus.hyp_location_flag) option
diff --git a/pretyping/pretype_errors.mli b/pretyping/pretype_errors.mli
index f617df9ee..880f48e5f 100644
--- a/pretyping/pretype_errors.mli
+++ b/pretyping/pretype_errors.mli
@@ -24,6 +24,7 @@ type unification_error =
| InstanceNotSameType of existential_key * env * types * types
| UnifUnivInconsistency of Univ.univ_inconsistency
| CannotSolveConstraint of Evd.evar_constraint * unification_error
+ | ProblemBeyondCapabilities
type position = (Id.t * Locus.hyp_location_flag) option
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index 8329de2ee..378294c98 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -36,6 +36,7 @@ open Typeops
open Globnames
open Nameops
open Evarutil
+open Evardefine
open Pretype_errors
open Glob_term
open Glob_ops
@@ -48,7 +49,7 @@ open Context.Named.Declaration
type typing_constraint = OfType of types | IsType | WithoutTypeConstraint
type var_map = constr_under_binders Id.Map.t
type uconstr_var_map = Glob_term.closed_glob_constr Id.Map.t
-type unbound_ltac_var_map = Genarg.Val.t Id.Map.t
+type unbound_ltac_var_map = Geninterp.Val.t Id.Map.t
type ltac_var_map = {
ltac_constrs : var_map;
ltac_uconstrs : uconstr_var_map;
@@ -57,6 +58,8 @@ type ltac_var_map = {
}
type glob_constr_ltac_closure = ltac_var_map * glob_constr
type pure_open_constr = evar_map * constr
+type 'a delayed_open =
+ { delayed : 'r. Environ.env -> 'r Sigma.t -> ('a, 'r) Sigma.sigma }
(************************************************************************)
(* This concerns Cases *)
@@ -140,7 +143,7 @@ let interp_universe_level_name evd (loc,s) =
with Not_found ->
try
let id = try Id.of_string s with _ -> raise Not_found in
- evd, Idmap.find id names
+ evd, snd (Idmap.find id names)
with Not_found ->
if not (is_strict_universe_declarations ()) then
new_univ_level_variable ~loc ~name:s univ_rigid evd
@@ -181,8 +184,7 @@ type inference_flags = {
}
let frozen_holes (sigma, sigma') =
- let fold evk _ accu = Evar.Set.add evk accu in
- Evd.fold_undefined fold sigma Evar.Set.empty
+ (); fun ev -> Evar.Map.mem ev (Evd.undefined_map sigma)
let pending_holes (sigma, sigma') =
let fold evk _ accu =
@@ -191,7 +193,7 @@ let pending_holes (sigma, sigma') =
Evd.fold_undefined fold sigma' Evar.Set.empty
let apply_typeclasses env evdref frozen fail_evar =
- let filter_frozen evk = Evar.Set.mem evk frozen in
+ let filter_frozen = frozen in
evdref := Typeclasses.resolve_typeclasses
~filter:(if Flags.is_program_mode ()
then (fun evk evi -> Typeclasses.no_goals_or_obligations evk evi && not (filter_frozen evk))
@@ -234,6 +236,23 @@ let check_extra_evars_are_solved env current_sigma pending =
| _ ->
error_unsolvable_implicit loc env current_sigma evk None) pending
+(* [check_evars] fails if some unresolved evar remains *)
+
+let check_evars env initial_sigma sigma c =
+ let rec proc_rec c =
+ match kind_of_term c with
+ | Evar (evk,_ as ev) ->
+ (match existential_opt_value sigma ev with
+ | Some c -> proc_rec c
+ | None ->
+ if not (Evd.mem initial_sigma evk) then
+ let (loc,k) = evar_source evk sigma in
+ match k with
+ | Evar_kinds.ImplicitArg (gr, (i, id), false) -> ()
+ | _ -> Pretype_errors.error_unsolvable_implicit loc env sigma evk None)
+ | _ -> Constr.iter proc_rec c
+ in proc_rec c
+
let check_evars_are_solved env current_sigma frozen pending =
check_typeclasses_instances_are_solved env current_sigma frozen;
check_problems_are_solved env current_sigma;
@@ -369,9 +388,12 @@ let pretype_id pretype k0 loc env evdref lvar id =
with Not_found ->
(* Check if [id] is a ltac variable not bound to a term *)
(* and build a nice error message *)
- if Id.Map.mem id lvar.ltac_genargs then
+ if Id.Map.mem id lvar.ltac_genargs then begin
+ let Geninterp.Val.Dyn (typ, _) = Id.Map.find id lvar.ltac_genargs in
user_err_loc (loc,"",
- str "Variable " ++ pr_id id ++ str " should be bound to a term.");
+ str "Variable " ++ pr_id id ++ str " should be bound to a term but is \
+ bound to a " ++ Geninterp.Val.pr typ ++ str ".")
+ end;
(* Check if [id] is a section or goal variable *)
try
{ uj_val = mkVar id; uj_type = (get_type (lookup_named id env)) }
@@ -1089,3 +1111,26 @@ let understand_tcc_evars ?(flags=all_no_fail_flags) env evdref ?(expected_type=W
let understand_ltac flags env sigma lvar kind c =
ise_pretype_gen flags env sigma lvar kind c
+
+let constr_flags = {
+ use_typeclasses = true;
+ use_unif_heuristics = true;
+ use_hook = None;
+ fail_evar = true;
+ expand_evars = true }
+
+(* Fully evaluate an untyped constr *)
+let type_uconstr ?(flags = constr_flags)
+ ?(expected_type = WithoutTypeConstraint) ist c =
+ { delayed = begin fun env sigma ->
+ let { closure; term } = c in
+ let vars = {
+ ltac_constrs = closure.typed;
+ ltac_uconstrs = closure.untyped;
+ ltac_idents = closure.idents;
+ ltac_genargs = Id.Map.empty;
+ } in
+ let sigma = Sigma.to_evar_map sigma in
+ let (sigma, c) = understand_ltac flags env sigma vars expected_type term in
+ Sigma.Unsafe.of_pair (c, sigma)
+ end }
diff --git a/pretyping/pretyping.mli b/pretyping/pretyping.mli
index 40745ed09..824bb11aa 100644
--- a/pretyping/pretyping.mli
+++ b/pretyping/pretyping.mli
@@ -29,7 +29,7 @@ type typing_constraint = OfType of types | IsType | WithoutTypeConstraint
type var_map = Pattern.constr_under_binders Id.Map.t
type uconstr_var_map = Glob_term.closed_glob_constr Id.Map.t
-type unbound_ltac_var_map = Genarg.Val.t Id.Map.t
+type unbound_ltac_var_map = Geninterp.Val.t Id.Map.t
type ltac_var_map = {
ltac_constrs : var_map;
@@ -55,6 +55,9 @@ type inference_flags = {
expand_evars : bool
}
+type 'a delayed_open =
+ { delayed : 'r. Environ.env -> 'r Sigma.t -> ('a, 'r) Sigma.sigma }
+
val default_inference_flags : bool -> inference_flags
val no_classes_no_fail_inference_flags : inference_flags
@@ -114,6 +117,11 @@ val understand_judgment : env -> evar_map ->
val understand_judgment_tcc : env -> evar_map ref ->
glob_constr -> unsafe_judgment
+val type_uconstr :
+ ?flags:inference_flags ->
+ ?expected_type:typing_constraint ->
+ Geninterp.interp_sign -> Glob_term.closed_glob_constr -> constr delayed_open
+
(** Trying to solve remaining evars and remaining conversion problems
possibly using type classes, heuristics, external tactic solver
hook depending on given flags. *)
@@ -130,6 +138,10 @@ val solve_remaining_evars : inference_flags ->
val check_evars_are_solved :
env -> (* current map: *) evar_map -> (* map to check: *) pending -> unit
+(** [check_evars env initial_sigma extended_sigma c] fails if some
+ new unresolved evar remains in [c] *)
+val check_evars : env -> evar_map -> evar_map -> constr -> unit
+
(**/**)
(** Internal of Pretyping... *)
val pretype :
diff --git a/pretyping/pretyping.mllib b/pretyping/pretyping.mllib
index b59589bda..c8b3307d7 100644
--- a/pretyping/pretyping.mllib
+++ b/pretyping/pretyping.mllib
@@ -1,4 +1,5 @@
Locusops
+Pretype_errors
Reductionops
Inductiveops
Vnorm
@@ -6,9 +7,8 @@ Arguments_renaming
Nativenorm
Retyping
Cbv
-Pretype_errors
Find_subterm
-Evarutil
+Evardefine
Evarsolve
Recordops
Evarconv
diff --git a/pretyping/recordops.ml b/pretyping/recordops.ml
index 6499ddd53..bbb6a9266 100644
--- a/pretyping/recordops.ml
+++ b/pretyping/recordops.ml
@@ -216,7 +216,7 @@ let compute_canonical_projections (con,ind) =
if Flags.is_verbose () then
(let con_pp = Nametab.pr_global_env Id.Set.empty (ConstRef con)
and proji_sp_pp = Nametab.pr_global_env Id.Set.empty (ConstRef proji_sp) in
- msg_warning (strbrk "No global reference exists for projection value"
+ Feedback.msg_warning (strbrk "No global reference exists for projection value"
++ Termops.print_constr t ++ strbrk " in instance "
++ con_pp ++ str " of " ++ proji_sp_pp ++ strbrk ", ignoring it."));
l
@@ -250,7 +250,7 @@ let open_canonical_structure i (_,o) =
and new_can_s = (Termops.print_constr s.o_DEF) in
let prj = (Nametab.pr_global_env Id.Set.empty proj)
and hd_val = (pr_cs_pattern cs_pat) in
- msg_warning (strbrk "Ignoring canonical projection to " ++ hd_val
+ Feedback.msg_warning (strbrk "Ignoring canonical projection to " ++ hd_val
++ strbrk " by " ++ prj ++ strbrk " in "
++ new_can_s ++ strbrk ": redundant with " ++ old_can_s)) lo
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml
index 935e18d8d..79cb7a2f6 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -594,9 +594,7 @@ let pr_state (tm,sk) =
(*** Reduction Functions Operators ***)
(*************************************)
-let safe_evar_value sigma ev =
- try Some (Evd.existential_value sigma ev)
- with NotInstantiatedEvar | Not_found -> None
+let safe_evar_value = Evarutil.safe_evar_value
let safe_meta_value sigma ev =
try Some (Evd.meta_value sigma ev)
@@ -804,15 +802,16 @@ let rec whd_state_gen ?csts tactic_mode flags env sigma =
let rec whrec cst_l (x, stack as s) =
let () = if !debug_RAKAM then
let open Pp in
- pp (h 0 (str "<<" ++ Termops.print_constr x ++
+ Feedback.msg_notice
+ (h 0 (str "<<" ++ Termops.print_constr x ++
str "|" ++ cut () ++ Cst_stack.pr cst_l ++
str "|" ++ cut () ++ Stack.pr Termops.print_constr stack ++
str ">>") ++ fnl ())
in
let fold () =
let () = if !debug_RAKAM then
- let open Pp in pp (str "<><><><><>" ++ fnl ()) in
- if tactic_mode then (Stack.best_state s cst_l,Cst_stack.empty) else (s,cst_l)
+ let open Pp in Feedback.msg_notice (str "<><><><><>" ++ fnl ()) in
+ (s,cst_l)
in
match kind_of_term x with
| Rel n when Closure.RedFlags.red_set flags Closure.RedFlags.fDELTA ->
@@ -1003,7 +1002,9 @@ let rec whd_state_gen ?csts tactic_mode flags env sigma =
| Rel _ | Var _ | Const _ | LetIn _ | Proj _ -> fold ()
| Sort _ | Ind _ | Prod _ -> fold ()
in
- whrec (Option.default Cst_stack.empty csts)
+ fun xs ->
+ let (s,cst_l as res) = whrec (Option.default Cst_stack.empty csts) xs in
+ if tactic_mode then (Stack.best_state s cst_l,Cst_stack.empty) else res
(** reduction machine without global env and refold machinery *)
let local_whd_state_gen flags sigma =
@@ -1183,30 +1184,8 @@ let whd_zeta c = Stack.zip (local_whd_state_gen zeta Evd.empty (c,Stack.empty))
(****************************************************************************)
(* Replacing defined evars for error messages *)
-let rec whd_evar sigma c =
- match kind_of_term c with
- | Evar ev ->
- let (evk, args) = ev in
- let args = Array.map (fun c -> whd_evar sigma c) args in
- (match safe_evar_value sigma (evk, args) with
- Some c -> whd_evar sigma c
- | None -> c)
- | Sort (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')
- | _ -> c
-
-let nf_evar =
- local_strong whd_evar
+let whd_evar = Evarutil.whd_evar
+let nf_evar = Evarutil.nf_evar
(* lazy reduction functions. The infos must be created for each term *)
(* Note by HH [oct 08] : why would it be the job of clos_norm_flags to add
diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml
index 0faa35c87..3ff96cd72 100644
--- a/pretyping/typeclasses.ml
+++ b/pretyping/typeclasses.ml
@@ -25,7 +25,7 @@ let get_typeclasses_unique_solutions () = !typeclasses_unique_solutions
open Goptions
-let set_typeclasses_unique_solutions =
+let _ =
declare_bool_option
{ optsync = true;
optdepr = false;
@@ -490,7 +490,7 @@ let is_instance = function
Nota: we will only check the resolvability status of undefined evars.
*)
-let resolvable = Store.field ()
+let resolvable = Proofview.Unsafe.typeclass_resolvable
let set_resolvable s b =
if b then Store.remove s resolvable
diff --git a/pretyping/typing.ml b/pretyping/typing.ml
index 5347d965b..52afa7f83 100644
--- a/pretyping/typing.ml
+++ b/pretyping/typing.ml
@@ -39,7 +39,7 @@ let e_type_judgment env evdref j =
match kind_of_term (whd_betadeltaiota env !evdref j.uj_type) with
| Sort s -> {utj_val = j.uj_val; utj_type = s }
| Evar ev ->
- let (evd,s) = Evarutil.define_evar_as_sort env !evdref ev in
+ let (evd,s) = Evardefine.define_evar_as_sort env !evdref ev in
evdref := evd; { utj_val = j.uj_val; utj_type = s }
| _ -> error_not_type env j
@@ -61,7 +61,7 @@ let e_judge_of_apply env evdref funj argjv =
else
error_cant_apply_bad_type env (n,c1, hj.uj_type) funj argjv
| Evar ev ->
- let (evd',t) = Evarutil.define_evar_as_product !evdref ev in
+ let (evd',t) = Evardefine.define_evar_as_product !evdref ev in
evdref := evd';
let (_,_,c2) = destProd t in
apply_rec (n+1) (subst1 hj.uj_val c2) restjl
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index e68961da7..21cf5548f 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -19,6 +19,7 @@ open Evd
open Reduction
open Reductionops
open Evarutil
+open Evardefine
open Evarsolve
open Pretype_errors
open Retyping
@@ -363,6 +364,22 @@ let set_no_delta_flags flags = {
resolve_evars = flags.resolve_evars
}
+(* For the first phase of keyed unification, restrict
+ to conversion (including beta-iota) only on closed terms *)
+let set_no_delta_open_core_flags flags = { flags with
+ modulo_delta = empty_transparent_state;
+ modulo_betaiota = false;
+}
+
+let set_no_delta_open_flags flags = {
+ core_unify_flags = set_no_delta_open_core_flags flags.core_unify_flags;
+ merge_unify_flags = set_no_delta_open_core_flags flags.merge_unify_flags;
+ subterm_unify_flags = set_no_delta_open_core_flags flags.subterm_unify_flags;
+ allow_K_in_toplevel_higher_order_unification =
+ flags.allow_K_in_toplevel_higher_order_unification;
+ resolve_evars = flags.resolve_evars
+}
+
(* Default flag for the "simple apply" version of unification of a *)
(* type against a type (e.g. apply) *)
(* We set only the flags available at the time the new "apply" extended *)
@@ -488,7 +505,8 @@ let key_of env b flags f =
Id.Pred.mem id (fst flags.modulo_delta) ->
Some (IsKey (VarKey id))
| Proj (p, c) when Projection.unfolded p
- || Cpred.mem (Projection.constant p) (snd flags.modulo_delta) ->
+ || (is_transparent env (ConstKey (Projection.constant p)) &&
+ (Cpred.mem (Projection.constant p) (snd flags.modulo_delta))) ->
Some (IsProj (p, c))
| _ -> None
@@ -612,7 +630,7 @@ let is_eta_constructor_app env ts f l1 term =
| Construct (((_, i as ind), j), u) when i == 0 && j == 1 ->
let mib = lookup_mind (fst ind) env in
(match mib.Declarations.mind_record with
- | Some (Some (_,exp,projs)) when mib.Declarations.mind_finite <> Decl_kinds.CoFinite &&
+ | Some (Some (_,exp,projs)) when mib.Declarations.mind_finite == Decl_kinds.BiFinite &&
Array.length projs == Array.length l1 - mib.Declarations.mind_nparams ->
(** Check that the other term is neutral *)
is_neutral env ts term
@@ -639,7 +657,7 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb
and cN = Evarutil.whd_head_evar sigma curn in
let () =
if !debug_unification then
- msg_debug (Termops.print_constr_env curenv cM ++ str" ~= " ++ Termops.print_constr_env curenv cN)
+ Feedback.msg_debug (Termops.print_constr_env curenv cM ++ str" ~= " ++ Termops.print_constr_env curenv cN)
in
match (kind_of_term cM,kind_of_term cN) with
| Meta k1, Meta k2 ->
@@ -1036,12 +1054,14 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb
else error_cannot_unify (fst curenvnb) sigma (cM,cN)
in
- if !debug_unification then msg_debug (str "Starting unification");
+ if !debug_unification then Feedback.msg_debug (str "Starting unification");
let opt = { at_top = conv_at_top; with_types = false; with_cs = true } in
try
let res =
- if occur_meta_or_undefined_evar sigma m || occur_meta_or_undefined_evar sigma n
- || subterm_restriction opt flags then None
+ if subterm_restriction opt flags ||
+ occur_meta_or_undefined_evar sigma m || occur_meta_or_undefined_evar sigma n
+ then
+ None
else
let sigma, b = match flags.modulo_conv_on_closed_terms with
| Some convflags -> infer_conv ~pb:cv_pb ~ts:convflags env sigma m n
@@ -1057,10 +1077,10 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb
let a = match res with
| Some sigma -> sigma, ms, es
| None -> unirec_rec (env,0) cv_pb opt subst m n in
- if !debug_unification then msg_debug (str "Leaving unification with success");
+ if !debug_unification then Feedback.msg_debug (str "Leaving unification with success");
a
with e ->
- if !debug_unification then msg_debug (str "Leaving unification with failure");
+ if !debug_unification then Feedback.msg_debug (str "Leaving unification with failure");
raise e
@@ -1538,8 +1558,9 @@ let make_pattern_test from_prefix_of_ind is_correct_type env sigma (pending,c) =
| e when Errors.noncritical e -> raise (NotUnifiable None) in
let merge_fun c1 c2 =
match c1, c2 with
- | Some (evd,c1,_) as x, Some (_,c2,_) ->
- if is_conv env sigma c1 c2 then x else raise (NotUnifiable None)
+ | Some (evd,c1,x), Some (_,c2,_) ->
+ let (evd,b) = infer_conv ~pb:CONV env evd c1 c2 in
+ if b then Some (evd, c1, x) else raise (NotUnifiable None)
| Some _, None -> c1
| None, Some _ -> c2
| None, None -> None in
@@ -1818,17 +1839,25 @@ let w_unify_to_subterm_list env evd flags hdmeta oplist t =
let allow_K = flags.allow_K_in_toplevel_higher_order_unification in
let flags =
if occur_meta_or_existential op || !keyed_unification then
+ (* This is up to delta for subterms w/o metas ... *)
flags
else
(* up to Nov 2014, unification was bypassed on evar/meta-free terms;
now it is called in a minimalistic way, at least to possibly
unify pre-existing non frozen evars of the goal or of the
pattern *)
- set_no_delta_flags flags in
+ set_no_delta_flags flags in
+ let t' = (strip_outer_cast op,t) in
let (evd',cl) =
try
- (* This is up to delta for subterms w/o metas ... *)
- w_unify_to_subterm env evd ~flags (strip_outer_cast op,t)
+ if is_keyed_unification () then
+ try (* First try finding a subterm w/o conversion on open terms *)
+ let flags = set_no_delta_open_flags flags in
+ w_unify_to_subterm env evd ~flags t'
+ with e ->
+ (* If this fails, try with full conversion *)
+ w_unify_to_subterm env evd ~flags t'
+ else w_unify_to_subterm env evd ~flags t'
with PretypeError (env,_,NoOccurrenceFound _) when
allow_K ||
(* w_unify_to_subterm does not go through evars, so
diff --git a/printing/genprint.ml b/printing/genprint.ml
index d8bd81c4c..0ec35e07b 100644
--- a/printing/genprint.ml
+++ b/printing/genprint.ml
@@ -19,8 +19,9 @@ module PrintObj =
struct
type ('raw, 'glb, 'top) obj = ('raw, 'glb, 'top) printer
let name = "printer"
- let default wit = match unquote (rawwit wit) with
- | ExtraArgType name ->
+ let default wit = match wit with
+ | ExtraArg tag ->
+ let name = ArgT.repr tag in
let printer = {
raw = (fun _ -> str "<genarg:" ++ str name ++ str ">");
glb = (fun _ -> str "<genarg:" ++ str name ++ str ">");
diff --git a/printing/ppannotation.ml b/printing/ppannotation.ml
index df7f925b7..511f93569 100644
--- a/printing/ppannotation.ml
+++ b/printing/ppannotation.ml
@@ -20,7 +20,6 @@ type t =
| AGlobAtomicTacticExpr of glob_atomic_tactic_expr
| ARawTacticExpr of raw_tactic_expr
| ARawAtomicTacticExpr of raw_atomic_tactic_expr
- | ATacticExpr of tactic_expr
| AAtomicTacticExpr of atomic_tactic_expr
let tag_of_annotation = function
@@ -32,7 +31,6 @@ let tag_of_annotation = function
| AGlobAtomicTacticExpr _ -> "glob_atomic_tactic_expr"
| ARawTacticExpr _ -> "raw_tactic_expr"
| ARawAtomicTacticExpr _ -> "raw_atomic_tactic_expr"
- | ATacticExpr _ -> "tactic_expr"
| AAtomicTacticExpr _ -> "atomic_tactic_expr"
let attributes_of_annotation a =
diff --git a/printing/ppannotation.mli b/printing/ppannotation.mli
index 84724053e..a0fef1a75 100644
--- a/printing/ppannotation.mli
+++ b/printing/ppannotation.mli
@@ -23,7 +23,6 @@ type t =
| AGlobAtomicTacticExpr of glob_atomic_tactic_expr
| ARawTacticExpr of raw_tactic_expr
| ARawAtomicTacticExpr of raw_atomic_tactic_expr
- | ATacticExpr of tactic_expr
| AAtomicTacticExpr of atomic_tactic_expr
val tag_of_annotation : t -> string
diff --git a/printing/ppconstr.ml b/printing/ppconstr.ml
index 8a0df18ca..1866ca504 100644
--- a/printing/ppconstr.ml
+++ b/printing/ppconstr.ml
@@ -244,16 +244,16 @@ end) = struct
| CPatAlias (_, p, id) ->
pr_patt mt (las,E) p ++ str " as " ++ pr_id id, las
- | CPatCstr (_,c, [], []) ->
+ | CPatCstr (_,c, None, []) ->
pr_reference c, latom
- | CPatCstr (_, c, [], args) ->
+ | CPatCstr (_, c, None, args) ->
pr_reference c ++ prlist (pr_patt spc (lapp,L)) args, lapp
- | CPatCstr (_, c, args, []) ->
+ | CPatCstr (_, c, Some args, []) ->
str "@" ++ pr_reference c ++ prlist (pr_patt spc (lapp,L)) args, lapp
- | CPatCstr (_, c, expl_args, extra_args) ->
+ | CPatCstr (_, c, Some expl_args, extra_args) ->
surround (str "@" ++ pr_reference c ++ prlist (pr_patt spc (lapp,L)) expl_args)
++ prlist (pr_patt spc (lapp,L)) extra_args, lapp
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index 36863906e..5356cdee8 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -14,6 +14,7 @@ open Util
open Constrexpr
open Tacexpr
open Genarg
+open Geninterp
open Constrarg
open Libnames
open Ppextend
@@ -26,23 +27,20 @@ open Printer
let pr_global x = Nametab.pr_global_env Id.Set.empty x
-type grammar_terminals = Tacexpr.raw_tactic_expr Egramml.grammar_prod_item list
+type 'a grammar_tactic_prod_item_expr =
+| TacTerm of string
+| TacNonTerm of Loc.t * 'a * Names.Id.t
+
+type grammar_terminals = Genarg.ArgT.any Extend.user_symbol grammar_tactic_prod_item_expr list
type pp_tactic = {
pptac_level : int;
pptac_prods : grammar_terminals;
}
-(* ML Extensions *)
-let prtac_tab : (ml_tactic_name, pp_tactic array) Hashtbl.t =
- Hashtbl.create 17
-
(* Tactic notations *)
let prnotation_tab = Summary.ref ~name:"pptactic-notation" KNmap.empty
-let declare_ml_tactic_pprule key pt =
- Hashtbl.add prtac_tab key pt
-
let declare_notation_tactic_pprule kn pt =
prnotation_tab := KNmap.add kn pt !prnotation_tab
@@ -67,8 +65,8 @@ type 'a extra_genarg_printer =
let genarg_pprule = ref String.Map.empty
let declare_extra_genarg_pprule wit f g h =
- let s = match unquote (topwit wit) with
- | ExtraArgType s -> s
+ let s = match wit with
+ | ExtraArg s -> ArgT.repr s
| _ -> error
"Can declare a pretty-printing rule only for extra argument types."
in
@@ -94,8 +92,6 @@ module Make
: raw_tactic_expr -> std_ppcmds -> std_ppcmds
val tag_raw_atomic_tactic_expr
: raw_atomic_tactic_expr -> std_ppcmds -> std_ppcmds
- val tag_tactic_expr
- : tactic_expr -> std_ppcmds -> std_ppcmds
val tag_atomic_tactic_expr
: atomic_tactic_expr -> std_ppcmds -> std_ppcmds
end)
@@ -106,7 +102,38 @@ module Make
let keyword x = tag_keyword (str x)
let primitive x = tag_primitive (str x)
- let pr_value _ _ = str "(* FIXME *)"
+ let has_type (Val.Dyn (tag, x)) t = match Val.eq tag t with
+ | None -> false
+ | Some _ -> true
+
+ let unbox : type a. Val.t -> a Val.typ -> a= fun (Val.Dyn (tag, x)) t ->
+ match Val.eq tag t with
+ | None -> assert false
+ | Some Refl -> x
+
+ let rec pr_value lev v : std_ppcmds =
+ if has_type v Val.typ_list then
+ pr_sequence (fun x -> pr_value lev x) (unbox v Val.typ_list)
+ else if has_type v Val.typ_opt then
+ pr_opt_no_spc (fun x -> pr_value lev x) (unbox v Val.typ_opt)
+ else if has_type v Val.typ_pair then
+ let (v1, v2) = unbox v Val.typ_pair in
+ str "(" ++ pr_value lev v1 ++ str ", " ++ pr_value lev v2 ++ str ")"
+ else
+ let Val.Dyn (tag, x) = v in
+ let name = Val.repr tag in
+ let default = str "<" ++ str name ++ str ">" in
+ match ArgT.name name with
+ | None -> default
+ | Some (ArgT.Any arg) ->
+ let wit = ExtraArg arg in
+ match val_tag (Topwit wit) with
+ | Val.Base t ->
+ begin match Val.eq t tag with
+ | None -> default
+ | Some Refl -> Genprint.generic_top_print (in_gen (Topwit wit) x)
+ end
+ | _ -> default
let pr_with_occurrences pr (occs,c) =
match occs with
@@ -266,24 +293,25 @@ module Make
let with_evars ev s = if ev then "e" ^ s else s
+ let hov_if_not_empty n p = if Pp.ismt p then p else hov n p
let rec pr_raw_generic_rec prc prlc prtac prpat prref (GenArg (Rawwit wit, x)) =
match wit with
| ListArg wit ->
let map x = pr_raw_generic_rec prc prlc prtac prpat prref (in_gen (rawwit wit) x) in
let ans = pr_sequence map x in
- hov 0 ans
+ hov_if_not_empty 0 ans
| OptArg wit ->
let ans = match x with
| None -> mt ()
| Some x -> pr_raw_generic_rec prc prlc prtac prpat prref (in_gen (rawwit wit) x)
in
- hov 0 ans
+ hov_if_not_empty 0 ans
| PairArg (wit1, wit2) ->
let p, q = x in
let p = in_gen (rawwit wit1) p in
let q = in_gen (rawwit wit2) q in
- hov 0 (pr_sequence (pr_raw_generic_rec prc prlc prtac prpat prref) [p; q])
+ hov_if_not_empty 0 (pr_sequence (pr_raw_generic_rec prc prlc prtac prpat prref) [p; q])
| ExtraArg s ->
try pi1 (String.Map.find (ArgT.repr s) !genarg_pprule) prc prlc prtac (in_gen (rawwit wit) x)
with Not_found -> Genprint.generic_raw_print (in_gen (rawwit wit) x)
@@ -294,78 +322,40 @@ module Make
| ListArg wit ->
let map x = pr_glb_generic_rec prc prlc prtac prpat (in_gen (glbwit wit) x) in
let ans = pr_sequence map x in
- hov 0 ans
+ hov_if_not_empty 0 ans
| OptArg wit ->
let ans = match x with
| None -> mt ()
| Some x -> pr_glb_generic_rec prc prlc prtac prpat (in_gen (glbwit wit) x)
in
- hov 0 ans
+ hov_if_not_empty 0 ans
| PairArg (wit1, wit2) ->
let p, q = x in
let p = in_gen (glbwit wit1) p in
let q = in_gen (glbwit wit2) q in
let ans = pr_sequence (pr_glb_generic_rec prc prlc prtac prpat) [p; q] in
- hov 0 ans
+ hov_if_not_empty 0 ans
| ExtraArg s ->
try pi2 (String.Map.find (ArgT.repr s) !genarg_pprule) prc prlc prtac (in_gen (glbwit wit) x)
with Not_found -> Genprint.generic_glb_print (in_gen (glbwit wit) x)
- let rec pr_top_generic_rec prc prlc prtac prpat (GenArg (Topwit wit, x)) =
- match wit with
- | ListArg wit ->
- let map x = pr_top_generic_rec prc prlc prtac prpat (in_gen (topwit wit) x) in
- let ans = pr_sequence map x in
- hov 0 ans
- | OptArg wit ->
- let ans = match x with
- | None -> mt ()
- | Some x -> pr_top_generic_rec prc prlc prtac prpat (in_gen (topwit wit) x)
- in
- hov 0 ans
- | PairArg (wit1, wit2) ->
- let p, q = x in
- let p = in_gen (topwit wit1) p in
- let q = in_gen (topwit wit2) q in
- let ans = pr_sequence (pr_top_generic_rec prc prlc prtac prpat) [p; q] in
- hov 0 ans
- | ExtraArg s ->
- try pi3 (String.Map.find (ArgT.repr s) !genarg_pprule) prc prlc prtac (in_gen (topwit wit) x)
- with Not_found -> Genprint.generic_top_print (in_gen (topwit wit) x)
-
let rec tacarg_using_rule_token pr_gen = function
- | Egramml.GramTerminal s :: l, al -> keyword s :: tacarg_using_rule_token pr_gen (l,al)
- | Egramml.GramNonTerminal _ :: l, a :: al ->
- let r = tacarg_using_rule_token pr_gen (l,al) in
- pr_gen a :: r
- | [], [] -> []
- | _ -> failwith "Inconsistent arguments of extended tactic"
-
- type any_arg = AnyArg : 'a Genarg.raw_abstract_argument_type -> any_arg
-
- let filter_arg = function
- | Egramml.GramTerminal _ -> None
- | Egramml.GramNonTerminal (_, t, _) -> Some (AnyArg t)
+ | [] -> []
+ | TacTerm s :: l -> keyword s :: tacarg_using_rule_token pr_gen l
+ | TacNonTerm (_, (symb, arg), _) :: l ->
+ pr_gen symb arg :: tacarg_using_rule_token pr_gen l
let pr_tacarg_using_rule pr_gen l =
let l = match l with
- | (Egramml.GramTerminal s :: l, al) ->
+ | TacTerm s :: l ->
(** First terminal token should be considered as the name of the tactic,
so we tag it differently than the other terminal tokens. *)
- primitive s :: (tacarg_using_rule_token pr_gen (l, al))
+ primitive s :: tacarg_using_rule_token pr_gen l
| _ -> tacarg_using_rule_token pr_gen l
in
pr_sequence (fun x -> x) l
- let pr_extend_gen check pr_gen lev { mltac_name = s; mltac_index = i } l =
- try
- let pp_rules = Hashtbl.find prtac_tab s in
- let pp = pp_rules.(i) in
- let args = List.map_filter filter_arg pp.pptac_prods in
- let () = if not (List.for_all2eq check args l) then raise Not_found in
- let p = pr_tacarg_using_rule pr_gen (pp.pptac_prods, l) in
- if pp.pptac_level > lev then surround p else p
- with Not_found ->
+ let pr_extend_gen pr_gen lev { mltac_name = s; mltac_index = i } l =
let name =
str s.mltac_plugin ++ str "::" ++ str s.mltac_tactic ++
str "@" ++ int i
@@ -376,35 +366,99 @@ module Make
in
str "<" ++ name ++ str ">" ++ args
- let pr_alias_gen check pr_gen lev key l =
+ let pr_alias_key key =
+ try
+ let prods = (KNmap.find key !prnotation_tab).pptac_prods in
+ (* First printing strategy: only the head symbol *)
+ match prods with
+ | TacTerm s :: prods -> str s
+ | _ ->
+ (* Second printing strategy; if ever Tactic Notation is eventually *)
+ (* accepting notations not starting with an identifier *)
+ let rec pr = function
+ | [] -> []
+ | TacTerm s :: prods -> s :: pr prods
+ | TacNonTerm (_,_,id) :: prods -> ".." :: pr prods in
+ str (String.concat " " (pr prods))
+ with Not_found ->
+ KerName.print key
+
+ let pr_alias_gen pr_gen lev key l =
try
let pp = KNmap.find key !prnotation_tab in
- let args = List.map_filter filter_arg pp.pptac_prods in
- let () = if not (List.for_all2eq check args l) then raise Not_found in
- let p = pr_tacarg_using_rule pr_gen (pp.pptac_prods, l) in
+ let rec pack prods args = match prods, args with
+ | [], [] -> []
+ | TacTerm s :: prods, args -> TacTerm s :: pack prods args
+ | TacNonTerm (loc, symb, id) :: prods, arg :: args ->
+ TacNonTerm (loc, (symb, arg), id) :: pack prods args
+ | _ -> raise Not_found
+ in
+ let prods = pack pp.pptac_prods l in
+ let p = pr_tacarg_using_rule pr_gen prods in
if pp.pptac_level > lev then surround p else p
with Not_found ->
- KerName.print key ++ spc() ++ pr_sequence pr_gen l ++ str" (* Generic printer *)"
-
- let check_type t arg = match t, arg with
- | AnyArg t, TacGeneric arg -> argument_type_eq (unquote t) (genarg_tag arg)
- | _ -> false
-
- let unwrap_gen f = function TacGeneric x -> f x | _ -> assert false
+ let pr arg = str "_" in
+ KerName.print key ++ spc() ++ pr_sequence pr l ++ str" (* Generic printer *)"
+
+ let pr_farg prtac arg = prtac (1, Any) (TacArg (Loc.ghost, arg))
+
+ let is_genarg tag wit =
+ let ArgT.Any tag = tag in
+ argument_type_eq (ArgumentType (ExtraArg tag)) wit
+
+ let get_list : type l. l generic_argument -> l generic_argument list option =
+ function (GenArg (wit, arg)) -> match wit with
+ | Rawwit (ListArg wit) -> Some (List.map (in_gen (rawwit wit)) arg)
+ | Glbwit (ListArg wit) -> Some (List.map (in_gen (glbwit wit)) arg)
+ | _ -> None
+
+ let get_opt : type l. l generic_argument -> l generic_argument option option =
+ function (GenArg (wit, arg)) -> match wit with
+ | Rawwit (OptArg wit) -> Some (Option.map (in_gen (rawwit wit)) arg)
+ | Glbwit (OptArg wit) -> Some (Option.map (in_gen (glbwit wit)) arg)
+ | _ -> None
+
+ let rec pr_any_arg : type l. (_ -> l generic_argument -> std_ppcmds) -> _ -> l generic_argument -> std_ppcmds =
+ fun prtac symb arg -> match symb with
+ | Extend.Uentry tag when is_genarg tag (genarg_tag arg) -> prtac (1, Any) arg
+ | Extend.Ulist1 s | Extend.Ulist0 s ->
+ begin match get_list arg with
+ | None -> str "ltac:(" ++ prtac (1, Any) arg ++ str ")"
+ | Some l -> pr_sequence (pr_any_arg prtac s) l
+ end
+ | Extend.Ulist1sep (s, sep) | Extend.Ulist0sep (s, sep) ->
+ begin match get_list arg with
+ | None -> str "ltac:(" ++ prtac (1, Any) arg ++ str ")"
+ | Some l -> prlist_with_sep (fun () -> str sep) (pr_any_arg prtac s) l
+ end
+ | Extend.Uopt s ->
+ begin match get_opt arg with
+ | None -> str "ltac:(" ++ prtac (1, Any) arg ++ str ")"
+ | Some l -> pr_opt (pr_any_arg prtac s) l
+ end
+ | Extend.Uentry _ | Extend.Uentryl _ ->
+ str "ltac:(" ++ prtac (1, Any) arg ++ str ")"
+
+ let rec pr_targ prtac symb arg = match symb with
+ | Extend.Uentry tag when is_genarg tag (ArgumentType wit_tactic) ->
+ prtac (1, Any) arg
+ | Extend.Uentryl (_, l) -> prtac (l, Any) arg
+ | _ ->
+ match arg with
+ | TacGeneric arg ->
+ let pr l arg = prtac l (TacGeneric arg) in
+ pr_any_arg pr symb arg
+ | _ -> str "ltac:(" ++ prtac (1, Any) arg ++ str ")"
let pr_raw_extend_rec prc prlc prtac prpat =
- pr_extend_gen check_type (unwrap_gen (pr_raw_generic_rec prc prlc prtac prpat pr_reference))
+ pr_extend_gen (pr_farg prtac)
let pr_glob_extend_rec prc prlc prtac prpat =
- pr_extend_gen check_type (unwrap_gen (pr_glb_generic_rec prc prlc prtac prpat))
- let pr_extend_rec prc prlc prtac prpat =
- pr_extend_gen check_type (unwrap_gen (pr_top_generic_rec prc prlc prtac prpat))
+ pr_extend_gen (pr_farg prtac)
- let pr_raw_alias prc prlc prtac prpat =
- pr_alias_gen check_type (unwrap_gen (pr_raw_generic_rec prc prlc prtac prpat pr_reference))
- let pr_glob_alias prc prlc prtac prpat =
- pr_alias_gen check_type (unwrap_gen (pr_glb_generic_rec prc prlc prtac prpat))
- let pr_alias prc prlc prtac prpat =
- pr_alias_gen check_type (unwrap_gen (pr_top_generic_rec prc prlc prtac prpat))
+ let pr_raw_alias prc prlc prtac prpat lev key args =
+ pr_alias_gen (pr_targ (fun l a -> prtac l (TacArg (Loc.ghost, a)))) lev key args
+ let pr_glob_alias prc prlc prtac prpat lev key args =
+ pr_alias_gen (pr_targ (fun l a -> prtac l (TacArg (Loc.ghost, a)))) lev key args
(**********************************************************************)
(* The tactic printer *)
@@ -513,9 +567,8 @@ module Make
| ipat ->
spc() ++ prc c ++ pr_as_ipat prdc ipat
- let pr_by_tactic prt = function
- | TacId [] -> mt ()
- | tac -> spc() ++ keyword "by" ++ spc () ++ prt tac
+ let pr_by_tactic prt tac =
+ spc() ++ keyword "by" ++ spc () ++ prt tac
let pr_hyp_location pr_id = function
| occs, InHyp -> spc () ++ pr_with_occurrences pr_id occs
@@ -528,7 +581,7 @@ module Make
str "(" ++ keyword "value of" ++ spc () ++ pr_id id ++ str ")"
) occs
- let pr_in pp = spc () ++ hov 0 (keyword "in" ++ pp)
+ let pr_in pp = hov 0 (keyword "in" ++ pp)
let pr_simple_hyp_clause pr_id = function
| [] -> mt ()
@@ -661,15 +714,13 @@ module Make
str " ]")
let pr_hintbases = function
- | None -> spc () ++ keyword "with" ++ str" *"
+ | None -> keyword "with" ++ str" *"
| Some [] -> mt ()
- | Some l ->
- spc () ++ hov 2 (keyword "with" ++ prlist (fun s -> spc () ++ str s) l)
+ | Some l -> hov 2 (keyword "with" ++ prlist (fun s -> spc () ++ str s) l)
let pr_auto_using prc = function
| [] -> mt ()
- | l -> spc () ++
- hov 2 (keyword "using" ++ spc () ++ prlist_with_sep pr_comma prc l)
+ | l -> hov 2 (keyword "using" ++ spc () ++ prlist_with_sep pr_comma prc l)
let pr_then () = str ";"
@@ -696,7 +747,6 @@ module Make
type 'a printer = {
pr_tactic : tolerability -> 'tacexpr -> std_ppcmds;
pr_constr : 'trm -> std_ppcmds;
- pr_uconstr : 'utrm -> std_ppcmds;
pr_lconstr : 'trm -> std_ppcmds;
pr_dconstr : 'dtrm -> std_ppcmds;
pr_pattern : 'pat -> std_ppcmds;
@@ -711,7 +761,6 @@ module Make
constraint 'a = <
term :'trm;
- utrm :'utrm;
dterm :'dtrm;
pattern :'pat;
constant :'cst;
@@ -721,247 +770,219 @@ module Make
level :'lev
>
- let make_pr_tac pr strip_prod_binders tag_atom tag =
+ let pr_atom pr strip_prod_binders tag_atom =
+ let pr_with_bindings = pr_with_bindings pr.pr_constr pr.pr_lconstr in
+ let pr_with_bindings_arg_full = pr_with_bindings_arg in
+ let pr_with_bindings_arg = pr_with_bindings_arg pr.pr_constr pr.pr_lconstr in
+ let pr_red_expr = pr_red_expr (pr.pr_constr,pr.pr_lconstr,pr.pr_constant,pr.pr_pattern) in
+
+ let pr_constrarg c = spc () ++ pr.pr_constr c in
+ let pr_lconstrarg c = spc () ++ pr.pr_lconstr c in
+ let pr_intarg n = spc () ++ int n in
+
+ (* Some printing combinators *)
+ let pr_eliminator cb = keyword "using" ++ pr_arg pr_with_bindings cb in
+
+ let pr_binder_fix (nal,t) =
+ (* match t with
+ | CHole _ -> spc() ++ prlist_with_sep spc (pr_lname) nal
+ | _ ->*)
+ let s = prlist_with_sep spc pr_lname nal ++ str ":" ++ pr.pr_lconstr t in
+ spc() ++ hov 1 (str"(" ++ s ++ str")") in
+
+ let pr_fix_tac (id,n,c) =
+ let rec set_nth_name avoid n = function
+ (nal,ty)::bll ->
+ if n <= List.length nal then
+ match List.chop (n-1) nal with
+ _, (_,Name id) :: _ -> id, (nal,ty)::bll
+ | bef, (loc,Anonymous) :: aft ->
+ let id = next_ident_away (Id.of_string"y") avoid in
+ id, ((bef@(loc,Name id)::aft, ty)::bll)
+ | _ -> assert false
+ else
+ let (id,bll') = set_nth_name avoid (n-List.length nal) bll in
+ (id,(nal,ty)::bll')
+ | [] -> assert false in
+ let (bll,ty) = strip_prod_binders n c in
+ let names =
+ List.fold_left
+ (fun ln (nal,_) -> List.fold_left
+ (fun ln na -> match na with (_,Name id) -> id::ln | _ -> ln)
+ ln nal)
+ [] bll in
+ let idarg,bll = set_nth_name names n bll in
+ let annot = match names with
+ | [_] ->
+ mt ()
+ | _ ->
+ spc() ++ str"{"
+ ++ keyword "struct" ++ spc ()
+ ++ pr_id idarg ++ str"}"
+ in
+ hov 1 (str"(" ++ pr_id id ++
+ prlist pr_binder_fix bll ++ annot ++ str" :" ++
+ pr_lconstrarg ty ++ str")") in
+ (* spc() ++
+ hov 0 (pr_id id ++ pr_intarg n ++ str":" ++ pr_constrarg
+ c)
+ *)
+ let pr_cofix_tac (id,c) =
+ hov 1 (str"(" ++ pr_id id ++ str" :" ++ pr_lconstrarg c ++ str")") in
+
+ (* Printing tactics as arguments *)
+ let rec pr_atom0 a = tag_atom a (match a with
+ | TacIntroPattern [] -> primitive "intros"
+ | t -> str "(" ++ pr_atom1 t ++ str ")"
+ )
+
+ (* Main tactic printer *)
+ and pr_atom1 a = tag_atom a (match a with
+ (* Basic tactics *)
+ | TacIntroPattern [] as t ->
+ pr_atom0 t
+ | TacIntroPattern (_::_ as p) ->
+ hov 1 (primitive "intros" ++ spc () ++
+ prlist_with_sep spc (Miscprint.pr_intro_pattern pr.pr_dconstr) p)
+ | TacApply (a,ev,cb,inhyp) ->
+ hov 1 (
+ (if a then mt() else primitive "simple ") ++
+ primitive (with_evars ev "apply") ++ spc () ++
+ prlist_with_sep pr_comma pr_with_bindings_arg cb ++
+ pr_non_empty_arg (pr_in_hyp_as pr.pr_dconstr pr.pr_name) inhyp
+ )
+ | TacElim (ev,cb,cbo) ->
+ hov 1 (
+ primitive (with_evars ev "elim")
+ ++ pr_arg pr_with_bindings_arg cb
+ ++ pr_opt pr_eliminator cbo)
+ | TacCase (ev,cb) ->
+ hov 1 (primitive (with_evars ev "case") ++ spc () ++ pr_with_bindings_arg cb)
+ | TacMutualFix (id,n,l) ->
+ hov 1 (
+ primitive "fix" ++ spc () ++ pr_id id ++ pr_intarg n ++ spc()
+ ++ keyword "with" ++ spc () ++ prlist_with_sep spc pr_fix_tac l)
+ | TacMutualCofix (id,l) ->
+ hov 1 (
+ primitive "cofix" ++ spc () ++ pr_id id ++ spc()
+ ++ keyword "with" ++ spc () ++ prlist_with_sep spc pr_cofix_tac l
+ )
+ | TacAssert (b,Some tac,ipat,c) ->
+ hov 1 (
+ primitive (if b then "assert" else "enough") ++
+ pr_assumption pr.pr_constr pr.pr_dconstr pr.pr_lconstr ipat c ++
+ pr_by_tactic (pr.pr_tactic ltop) tac
+ )
+ | TacAssert (_,None,ipat,c) ->
+ hov 1 (
+ primitive "pose proof"
+ ++ pr_assertion pr.pr_constr pr.pr_dconstr pr.pr_lconstr ipat c
+ )
+ | TacGeneralize l ->
+ hov 1 (
+ primitive "generalize" ++ spc ()
+ ++ prlist_with_sep pr_comma (fun (cl,na) ->
+ pr_with_occurrences pr.pr_constr cl ++ pr_as_name na)
+ l
+ )
+ | TacLetTac (na,c,cl,true,_) when Locusops.is_nowhere cl ->
+ hov 1 (primitive "pose" ++ pr_pose pr.pr_constr pr.pr_lconstr na c)
+ | TacLetTac (na,c,cl,b,e) ->
+ hov 1 (
+ (if b then primitive "set" else primitive "remember") ++
+ (if b then pr_pose pr.pr_constr pr.pr_lconstr na c
+ else pr_pose_as_style pr.pr_constr na c) ++
+ pr_opt (fun p -> pr_eqn_ipat p ++ spc ()) e ++
+ pr_non_empty_arg (pr_clauses (Some b) pr.pr_name) cl)
+ (* | TacInstantiate (n,c,ConclLocation ()) ->
+ hov 1 (str "instantiate" ++ spc() ++
+ hov 1 (str"(" ++ pr_arg int n ++ str" :=" ++
+ pr_lconstrarg c ++ str ")" ))
+ | TacInstantiate (n,c,HypLocation (id,hloc)) ->
+ hov 1 (str "instantiate" ++ spc() ++
+ hov 1 (str"(" ++ pr_arg int n ++ str" :=" ++
+ pr_lconstrarg c ++ str ")" )
+ ++ str "in" ++ pr_hyp_location pr.pr_name (id,[],(hloc,ref None)))
+ *)
- (* some shortcuts *)
- let _pr_bindings = pr_bindings pr.pr_constr pr.pr_lconstr in
- let pr_with_bindings = pr_with_bindings pr.pr_constr pr.pr_lconstr in
- let pr_with_bindings_arg_full = pr_with_bindings_arg in
- let pr_with_bindings_arg = pr_with_bindings_arg pr.pr_constr pr.pr_lconstr in
- let pr_red_expr = pr_red_expr (pr.pr_constr,pr.pr_lconstr,pr.pr_constant,pr.pr_pattern) in
+ (* Derived basic tactics *)
+ | TacInductionDestruct (isrec,ev,(l,el)) ->
+ hov 1 (
+ primitive (with_evars ev (if isrec then "induction" else "destruct"))
+ ++ spc ()
+ ++ prlist_with_sep pr_comma (fun ((clear_flag,h),ids,cl) ->
+ pr_clear_flag clear_flag (pr_induction_arg pr.pr_dconstr pr.pr_dconstr) h ++
+ pr_with_induction_names pr.pr_dconstr ids ++
+ pr_opt (pr_clauses None pr.pr_name) cl) l ++
+ pr_opt pr_eliminator el
+ )
- let pr_constrarg c = spc () ++ pr.pr_constr c in
- let pr_lconstrarg c = spc () ++ pr.pr_lconstr c in
- let pr_intarg n = spc () ++ int n in
+ (* Conversion *)
+ | TacReduce (r,h) ->
+ hov 1 (
+ pr_red_expr r
+ ++ pr_non_empty_arg (pr_clauses (Some true) pr.pr_name) h
+ )
+ | TacChange (op,c,h) ->
+ hov 1 (
+ primitive "change" ++ brk (1,1)
+ ++ (
+ match op with
+ None ->
+ mt ()
+ | Some p ->
+ pr.pr_pattern p ++ spc ()
+ ++ keyword "with" ++ spc ()
+ ) ++ pr.pr_dconstr c ++ pr_non_empty_arg (pr_clauses (Some true) pr.pr_name) h
+ )
+
+ (* Equality and inversion *)
+ | TacRewrite (ev,l,cl,by) ->
+ hov 1 (
+ primitive (with_evars ev "rewrite") ++ spc ()
+ ++ prlist_with_sep
+ (fun () -> str ","++spc())
+ (fun (b,m,c) ->
+ pr_orient b ++ pr_multi m ++
+ pr_with_bindings_arg_full pr.pr_dconstr pr.pr_dconstr c)
+ l
+ ++ pr_non_empty_arg (pr_clauses (Some true) pr.pr_name) cl
+ ++ (
+ match by with
+ | Some by -> pr_by_tactic (pr.pr_tactic ltop) by
+ | None -> mt()
+ )
+ )
+ | TacInversion (DepInversion (k,c,ids),hyp) ->
+ hov 1 (
+ primitive "dependent " ++ pr_induction_kind k ++ spc ()
+ ++ pr_quantified_hypothesis hyp
+ ++ pr_with_inversion_names pr.pr_dconstr ids
+ ++ pr_with_constr pr.pr_constr c
+ )
+ | TacInversion (NonDepInversion (k,cl,ids),hyp) ->
+ hov 1 (
+ pr_induction_kind k ++ spc ()
+ ++ pr_quantified_hypothesis hyp
+ ++ pr_with_inversion_names pr.pr_dconstr ids
+ ++ pr_non_empty_arg (pr_simple_hyp_clause pr.pr_name) cl
+ )
+ | TacInversion (InversionUsing (c,cl),hyp) ->
+ hov 1 (
+ primitive "inversion" ++ spc()
+ ++ pr_quantified_hypothesis hyp ++ spc ()
+ ++ keyword "using" ++ spc () ++ pr.pr_constr c
+ ++ pr_non_empty_arg (pr_simple_hyp_clause pr.pr_name) cl
+ )
+ )
+ in
+ pr_atom1
- (* Some printing combinators *)
- let pr_eliminator cb = keyword "using" ++ pr_arg pr_with_bindings cb in
+ let make_pr_tac pr strip_prod_binders tag_atom tag =
let extract_binders = function
| Tacexp (TacFun (lvar,body)) -> (lvar,Tacexp body)
| body -> ([],body) in
-
- let pr_binder_fix (nal,t) =
- (* match t with
- | CHole _ -> spc() ++ prlist_with_sep spc (pr_lname) nal
- | _ ->*)
- let s = prlist_with_sep spc pr_lname nal ++ str ":" ++ pr.pr_lconstr t in
- spc() ++ hov 1 (str"(" ++ s ++ str")") in
-
- let pr_fix_tac (id,n,c) =
- let rec set_nth_name avoid n = function
- (nal,ty)::bll ->
- if n <= List.length nal then
- match List.chop (n-1) nal with
- _, (_,Name id) :: _ -> id, (nal,ty)::bll
- | bef, (loc,Anonymous) :: aft ->
- let id = next_ident_away (Id.of_string"y") avoid in
- id, ((bef@(loc,Name id)::aft, ty)::bll)
- | _ -> assert false
- else
- let (id,bll') = set_nth_name avoid (n-List.length nal) bll in
- (id,(nal,ty)::bll')
- | [] -> assert false in
- let (bll,ty) = strip_prod_binders n c in
- let names =
- List.fold_left
- (fun ln (nal,_) -> List.fold_left
- (fun ln na -> match na with (_,Name id) -> id::ln | _ -> ln)
- ln nal)
- [] bll in
- let idarg,bll = set_nth_name names n bll in
- let annot = match names with
- | [_] ->
- mt ()
- | _ ->
- spc() ++ str"{"
- ++ keyword "struct" ++ spc ()
- ++ pr_id idarg ++ str"}"
- in
- hov 1 (str"(" ++ pr_id id ++
- prlist pr_binder_fix bll ++ annot ++ str" :" ++
- pr_lconstrarg ty ++ str")") in
- (* spc() ++
- hov 0 (pr_id id ++ pr_intarg n ++ str":" ++ pr_constrarg
- c)
- *)
- let pr_cofix_tac (id,c) =
- hov 1 (str"(" ++ pr_id id ++ str" :" ++ pr_lconstrarg c ++ str")") in
-
- (* Printing tactics as arguments *)
- let rec pr_atom0 a = tag_atom a (match a with
- | TacIntroPattern [] -> primitive "intros"
- | TacIntroMove (None,MoveLast) -> primitive "intro"
- | t -> str "(" ++ pr_atom1 t ++ str ")"
- )
-
- (* Main tactic printer *)
- and pr_atom1 a = tag_atom a (match a with
- (* Basic tactics *)
- | TacIntroPattern [] as t ->
- pr_atom0 t
- | TacIntroPattern (_::_ as p) ->
- hov 1 (primitive "intros" ++ spc () ++
- prlist_with_sep spc (Miscprint.pr_intro_pattern pr.pr_dconstr) p)
- | TacIntroMove (None,MoveLast) as t ->
- pr_atom0 t
- | TacIntroMove (Some id,MoveLast) ->
- primitive "intro" ++ spc () ++ pr_id id
- | TacIntroMove (ido,hto) ->
- hov 1 (primitive "intro" ++ pr_opt pr_id ido ++
- Miscprint.pr_move_location pr.pr_name hto)
- | TacExact c ->
- hov 1 (primitive "exact" ++ pr_constrarg c)
- | TacApply (a,ev,cb,inhyp) ->
- hov 1 (
- (if a then mt() else primitive "simple ") ++
- primitive (with_evars ev "apply") ++ spc () ++
- prlist_with_sep pr_comma pr_with_bindings_arg cb ++
- pr_in_hyp_as pr.pr_dconstr pr.pr_name inhyp
- )
- | TacElim (ev,cb,cbo) ->
- hov 1 (
- primitive (with_evars ev "elim")
- ++ pr_arg pr_with_bindings_arg cb
- ++ pr_opt pr_eliminator cbo)
- | TacCase (ev,cb) ->
- hov 1 (primitive (with_evars ev "case") ++ spc () ++ pr_with_bindings_arg cb)
- | TacMutualFix (id,n,l) ->
- hov 1 (
- primitive "fix" ++ spc () ++ pr_id id ++ pr_intarg n ++ spc()
- ++ keyword "with" ++ spc () ++ prlist_with_sep spc pr_fix_tac l)
- | TacMutualCofix (id,l) ->
- hov 1 (
- primitive "cofix" ++ spc () ++ pr_id id ++ spc()
- ++ keyword "with" ++ spc () ++ prlist_with_sep spc pr_cofix_tac l
- )
- | TacAssert (b,Some tac,ipat,c) ->
- hov 1 (
- primitive (if b then "assert" else "enough") ++
- pr_assumption pr.pr_constr pr.pr_dconstr pr.pr_lconstr ipat c ++
- pr_by_tactic (pr.pr_tactic ltop) tac
- )
- | TacAssert (_,None,ipat,c) ->
- hov 1 (
- primitive "pose proof"
- ++ pr_assertion pr.pr_constr pr.pr_dconstr pr.pr_lconstr ipat c
- )
- | TacGeneralize l ->
- hov 1 (
- primitive "generalize" ++ spc ()
- ++ prlist_with_sep pr_comma (fun (cl,na) ->
- pr_with_occurrences pr.pr_constr cl ++ pr_as_name na)
- l
- )
- | TacLetTac (na,c,cl,true,_) when Locusops.is_nowhere cl ->
- hov 1 (primitive "pose" ++ pr_pose pr.pr_constr pr.pr_lconstr na c)
- | TacLetTac (na,c,cl,b,e) ->
- hov 1 (
- (if b then primitive "set" else primitive "remember") ++
- (if b then pr_pose pr.pr_constr pr.pr_lconstr na c
- else pr_pose_as_style pr.pr_constr na c) ++
- pr_opt (fun p -> pr_eqn_ipat p ++ spc ()) e ++
- pr_clauses (Some b) pr.pr_name cl)
- (* | TacInstantiate (n,c,ConclLocation ()) ->
- hov 1 (str "instantiate" ++ spc() ++
- hov 1 (str"(" ++ pr_arg int n ++ str" :=" ++
- pr_lconstrarg c ++ str ")" ))
- | TacInstantiate (n,c,HypLocation (id,hloc)) ->
- hov 1 (str "instantiate" ++ spc() ++
- hov 1 (str"(" ++ pr_arg int n ++ str" :=" ++
- pr_lconstrarg c ++ str ")" )
- ++ str "in" ++ pr_hyp_location pr.pr_name (id,[],(hloc,ref None)))
- *)
-
- (* Derived basic tactics *)
- | TacInductionDestruct (isrec,ev,(l,el)) ->
- hov 1 (
- primitive (with_evars ev (if isrec then "induction" else "destruct"))
- ++ spc ()
- ++ prlist_with_sep pr_comma (fun ((clear_flag,h),ids,cl) ->
- pr_clear_flag clear_flag (pr_induction_arg pr.pr_dconstr pr.pr_dconstr) h ++
- pr_with_induction_names pr.pr_dconstr ids ++
- pr_opt_no_spc (pr_clauses None pr.pr_name) cl) l ++
- pr_opt pr_eliminator el
- )
- | TacDoubleInduction (h1,h2) ->
- hov 1 (
- primitive "double induction"
- ++ pr_arg pr_quantified_hypothesis h1
- ++ pr_arg pr_quantified_hypothesis h2
- )
-
- (* Context management *)
- | TacRename l ->
- hov 1 (
- primitive "rename" ++ brk (1,1)
- ++ prlist_with_sep
- (fun () -> str "," ++ brk (1,1))
- (fun (i1,i2) ->
- pr.pr_name i1 ++ spc () ++ str "into" ++ spc () ++ pr.pr_name i2)
- l
- )
-
- (* Conversion *)
- | TacReduce (r,h) ->
- hov 1 (
- pr_red_expr r
- ++ pr_clauses (Some true) pr.pr_name h
- )
- | TacChange (op,c,h) ->
- hov 1 (
- primitive "change" ++ brk (1,1)
- ++ (
- match op with
- None ->
- mt ()
- | Some p ->
- pr.pr_pattern p ++ spc ()
- ++ keyword "with" ++ spc ()
- ) ++ pr.pr_dconstr c ++ pr_clauses (Some true) pr.pr_name h
- )
-
- (* Equality and inversion *)
- | TacRewrite (ev,l,cl,by) ->
- hov 1 (
- primitive (with_evars ev "rewrite") ++ spc ()
- ++ prlist_with_sep
- (fun () -> str ","++spc())
- (fun (b,m,c) ->
- pr_orient b ++ pr_multi m ++
- pr_with_bindings_arg_full pr.pr_dconstr pr.pr_dconstr c)
- l
- ++ pr_clauses (Some true) pr.pr_name cl
- ++ (
- match by with
- | Some by -> pr_by_tactic (pr.pr_tactic ltop) by
- | None -> mt()
- )
- )
- | TacInversion (DepInversion (k,c,ids),hyp) ->
- hov 1 (
- primitive "dependent " ++ pr_induction_kind k ++ spc ()
- ++ pr_quantified_hypothesis hyp
- ++ pr_with_inversion_names pr.pr_dconstr ids
- ++ pr_with_constr pr.pr_constr c
- )
- | TacInversion (NonDepInversion (k,cl,ids),hyp) ->
- hov 1 (
- pr_induction_kind k ++ spc ()
- ++ pr_quantified_hypothesis hyp
- ++ pr_with_inversion_names pr.pr_dconstr ids
- ++ pr_simple_hyp_clause pr.pr_name cl
- )
- | TacInversion (InversionUsing (c,cl),hyp) ->
- hov 1 (
- primitive "inversion" ++ spc()
- ++ pr_quantified_hypothesis hyp ++ spc ()
- ++ keyword "using" ++ spc () ++ pr.pr_constr c
- ++ pr_simple_hyp_clause pr.pr_name cl
- )
- )
- in
-
let rec pr_tac inherited tac =
let return (doc, l) = (tag tac doc, l) in
let (strm, prec) = return (match tac with
@@ -1119,7 +1140,7 @@ module Make
| TacId l ->
keyword "idtac" ++ prlist (pr_arg (pr_message_token pr.pr_name)) l, latom
| TacAtom (loc,t) ->
- pr_with_comments loc (hov 1 (pr_atom1 t)), ltatom
+ pr_with_comments loc (hov 1 (pr_atom pr strip_prod_binders tag_atom t)), ltatom
| TacArg(_,Tacexp e) ->
pr.pr_tactic (latom,E) e, latom
| TacArg(_,ConstrMayEval (ConstrTerm c)) ->
@@ -1153,8 +1174,6 @@ module Make
pr.pr_reference r
| ConstrMayEval c ->
pr_may_eval pr.pr_constr pr.pr_lconstr pr.pr_constant pr.pr_pattern c
- | UConstr c ->
- keyword "uconstr:" ++ pr.pr_uconstr c
| TacFreshId l ->
keyword "fresh" ++ pr_fresh_ids l
| TacPretype c ->
@@ -1182,7 +1201,6 @@ module Make
let pr = {
pr_tactic = pr_raw_tactic_level;
pr_constr = pr_constr_expr;
- pr_uconstr = pr_constr_expr;
pr_dconstr = pr_constr_expr;
pr_lconstr = pr_lconstr_expr;
pr_pattern = pr_constr_pattern_expr;
@@ -1190,7 +1208,7 @@ module Make
pr_constant = pr_or_by_notation pr_reference;
pr_reference = pr_reference;
pr_name = pr_lident;
- pr_generic = Genprint.generic_raw_print;
+ pr_generic = pr_raw_generic_rec pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr pr_reference;
pr_extend = pr_raw_extend_rec pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr;
pr_alias = pr_raw_alias pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr;
} in
@@ -1203,7 +1221,7 @@ module Make
let pr_and_constr_expr pr (c,_) = pr c
- let pr_pat_and_constr_expr pr ((c,_),_) = pr c
+ let pr_pat_and_constr_expr pr (_,(c,_),_) = pr c
let pr_glob_tactic_level env n t =
let glob_printers =
@@ -1213,7 +1231,6 @@ module Make
let pr = {
pr_tactic = prtac;
pr_constr = pr_and_constr_expr (pr_glob_constr_env env);
- pr_uconstr = pr_and_constr_expr (pr_glob_constr_env env);
pr_dconstr = pr_and_constr_expr (pr_glob_constr_env env);
pr_lconstr = pr_and_constr_expr (pr_lglob_constr_env env);
pr_pattern = pr_pat_and_constr_expr (pr_glob_constr_env env);
@@ -1221,7 +1238,9 @@ module Make
pr_constant = pr_or_var (pr_and_short_name (pr_evaluable_reference_env env));
pr_reference = pr_ltac_or_var (pr_located pr_ltac_constant);
pr_name = pr_lident;
- pr_generic = Genprint.generic_glb_print;
+ pr_generic = pr_glb_generic_rec
+ (pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
+ prtac (pr_pat_and_constr_expr (pr_glob_constr_env env));
pr_extend = pr_glob_extend_rec
(pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
prtac (pr_pat_and_constr_expr (pr_glob_constr_env env));
@@ -1247,15 +1266,11 @@ module Make
| _ -> error "Cannot translate fix tactic: not enough products" in
strip_ty [] n ty
- let pr_tactic_level env n t =
- let typed_printers =
- (strip_prod_binders_constr)
- in
- let prtac n (t:tactic_expr) =
+ let pr_atomic_tactic_level env n t =
+ let prtac n (t:atomic_tactic_expr) =
let pr = {
- pr_tactic = pr_glob_tactic_level env;
+ pr_tactic = (fun _ _ -> str "<tactic>");
pr_constr = pr_constr_env env Evd.empty;
- pr_uconstr = pr_closed_glob_env env Evd.empty;
pr_dconstr = pr_and_constr_expr (pr_glob_constr_env env);
pr_lconstr = pr_lconstr_env env Evd.empty;
pr_pattern = pr_constr_pattern_env env Evd.empty;
@@ -1263,19 +1278,13 @@ module Make
pr_constant = pr_evaluable_reference_env env;
pr_reference = pr_located pr_ltac_constant;
pr_name = pr_id;
- pr_generic = Genprint.generic_top_print;
- pr_extend = pr_extend_rec
- (pr_constr_env env Evd.empty) (pr_lconstr_env env Evd.empty)
- pr_value pr_constr_pattern;
- pr_alias = pr_alias
- (pr_constr_env env Evd.empty) (pr_lconstr_env env Evd.empty)
- pr_value pr_constr_pattern;
+ (** Those are not used by the atomic printer *)
+ pr_generic = (fun _ -> assert false);
+ pr_extend = (fun _ _ _ -> assert false);
+ pr_alias = (fun _ _ _ -> assert false);
}
in
- make_pr_tac
- pr typed_printers
- tag_atomic_tactic_expr tag_tactic_expr
- n t
+ pr_atom pr strip_prod_binders_constr tag_atomic_tactic_expr t
in
prtac n t
@@ -1286,10 +1295,6 @@ module Make
(pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
(pr_glob_tactic_level env) (pr_pat_and_constr_expr (pr_glob_constr_env env))
- let pr_top_generic env = pr_top_generic_rec
- (pr_constr_env env Evd.empty) (pr_lconstr_env env Evd.empty)
- pr_value pr_constr_pattern
-
let pr_raw_extend env = pr_raw_extend_rec
pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr
@@ -1297,22 +1302,13 @@ module Make
(pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
(pr_glob_tactic_level env) (pr_pat_and_constr_expr (pr_glob_constr_env env))
- let check_val_type t arg =
- let AnyArg t = t in
-(* let t = Genarg.val_tag (Obj.magic t) in *)
-(* let Val.Dyn (t', _) = arg in *)
-(* match Genarg.Val.eq t t' with *)
-(* | None -> false *)
-(* | Some _ -> true *)
- true (** FIXME *)
-
let pr_alias pr lev key args =
- pr_alias_gen check_val_type pr lev key args
+ pr_alias_gen (fun _ arg -> pr arg) lev key args
let pr_extend pr lev ml args =
- pr_extend_gen check_val_type pr lev ml args
+ pr_extend_gen pr lev ml args
- let pr_tactic env = pr_tactic_level env ltop
+ let pr_atomic_tactic env = pr_atomic_tactic_level env ltop
end
@@ -1342,7 +1338,6 @@ include Make (Ppconstr) (struct
let tag_glob_atomic_tactic_expr = do_not_tag
let tag_raw_tactic_expr = do_not_tag
let tag_raw_atomic_tactic_expr = do_not_tag
- let tag_tactic_expr = do_not_tag
let tag_atomic_tactic_expr = do_not_tag
end)
@@ -1374,8 +1369,6 @@ let () =
(pr_clauses (Some true) pr_lident)
(pr_clauses (Some true) (fun id -> pr_lident (Loc.ghost,id)))
;
- Genprint.register_print0 Constrarg.wit_sort
- pr_glob_sort pr_glob_sort (pr_sort Evd.empty);
Genprint.register_print0
Constrarg.wit_constr
Ppconstr.pr_constr_expr
@@ -1403,11 +1396,6 @@ let () =
(pr_bindings_no_with pr_constr_expr pr_lconstr_expr)
(pr_bindings_no_with (pr_and_constr_expr pr_glob_constr) (pr_and_constr_expr pr_lglob_constr))
(fun it -> pr_bindings_no_with pr_constr pr_lconstr (fst (run_delayed it)));
- Genprint.register_print0 Constrarg.wit_constr_may_eval
- (pr_may_eval pr_constr_expr pr_lconstr_expr (pr_or_by_notation pr_reference) pr_constr_pattern_expr)
- (pr_may_eval (pr_and_constr_expr pr_glob_constr) (pr_and_constr_expr pr_lglob_constr)
- (pr_or_var (pr_and_short_name pr_evaluable_reference)) (pr_pat_and_constr_expr pr_glob_constr))
- pr_constr;
Genprint.register_print0 Constrarg.wit_constr_with_bindings
(pr_with_bindings pr_constr_expr pr_lconstr_expr)
(pr_with_bindings (pr_and_constr_expr pr_glob_constr) (pr_and_constr_expr pr_lglob_constr))
@@ -1422,16 +1410,10 @@ let () =
let printer _ _ prtac = prtac (0, E) in
declare_extra_genarg_pprule wit_tactic printer printer printer
-let _ = Hook.set Tactic_debug.tactic_printer
- (fun x -> pr_glob_tactic (Global.env()) x)
-
-let _ = Hook.set Tactic_debug.match_pattern_printer
- (fun env sigma hyp -> pr_match_pattern (pr_constr_pattern_env env sigma) hyp)
-
-let _ = Hook.set Tactic_debug.match_rule_printer
- (fun rl ->
- pr_match_rule false (pr_glob_tactic (Global.env()))
- (fun (_,p) -> pr_constr_pattern p) rl)
+let () =
+ let pr_unit _ _ _ () = str "()" in
+ let printer _ _ prtac = prtac (0, E) in
+ declare_extra_genarg_pprule wit_ltac printer printer pr_unit
module Richpp = struct
@@ -1446,7 +1428,6 @@ module Richpp = struct
let tag_glob_atomic_tactic_expr a = tag (AGlobAtomicTacticExpr a)
let tag_raw_tactic_expr e = tag (ARawTacticExpr e)
let tag_raw_atomic_tactic_expr a = tag (ARawAtomicTacticExpr a)
- let tag_tactic_expr e = tag (ATacticExpr e)
let tag_atomic_tactic_expr a = tag (AAtomicTacticExpr a)
end)
diff --git a/printing/pptactic.mli b/printing/pptactic.mli
index 31a5a5d4a..86e3ea548 100644
--- a/printing/pptactic.mli
+++ b/printing/pptactic.mli
@@ -11,11 +11,15 @@
open Pp
open Genarg
+open Geninterp
open Names
open Constrexpr
open Tacexpr
open Ppextend
+type 'a grammar_tactic_prod_item_expr =
+| TacTerm of string
+| TacNonTerm of Loc.t * 'a * Names.Id.t
type 'a raw_extra_genarg_printer =
(constr_expr -> std_ppcmds) ->
@@ -41,14 +45,13 @@ val declare_extra_genarg_pprule :
'b glob_extra_genarg_printer ->
'c extra_genarg_printer -> unit
-type grammar_terminals = Tacexpr.raw_tactic_expr Egramml.grammar_prod_item list
+type grammar_terminals = Genarg.ArgT.any Extend.user_symbol grammar_tactic_prod_item_expr list
type pp_tactic = {
pptac_level : int;
pptac_prods : grammar_terminals;
}
-val declare_ml_tactic_pprule : ml_tactic_name -> pp_tactic array -> unit
val declare_notation_tactic_pprule : KerName.t -> pp_tactic -> unit
(** The default pretty-printers produce {!Pp.std_ppcmds} that are
diff --git a/printing/pptacticsig.mli b/printing/pptacticsig.mli
index c5ec6bb09..c08d6044d 100644
--- a/printing/pptacticsig.mli
+++ b/printing/pptacticsig.mli
@@ -8,6 +8,7 @@
open Pp
open Genarg
+open Geninterp
open Tacexpr
open Ppextend
open Environ
@@ -35,8 +36,6 @@ module type Pp = sig
val pr_glb_generic : env -> glevel generic_argument -> std_ppcmds
- val pr_top_generic : env -> tlevel generic_argument -> std_ppcmds
-
val pr_raw_extend: env -> int ->
ml_tactic_entry -> raw_tactic_arg list -> std_ppcmds
@@ -46,9 +45,13 @@ module type Pp = sig
val pr_extend :
(Val.t -> std_ppcmds) -> int -> ml_tactic_entry -> Val.t list -> std_ppcmds
+ val pr_alias_key : Names.KerName.t -> std_ppcmds
+
val pr_alias : (Val.t -> std_ppcmds) ->
int -> Names.KerName.t -> Val.t list -> std_ppcmds
+ val pr_alias_key : Names.KerName.t -> std_ppcmds
+
val pr_ltac_constant : Nametab.ltac_constant -> std_ppcmds
val pr_raw_tactic : raw_tactic_expr -> std_ppcmds
@@ -57,7 +60,7 @@ module type Pp = sig
val pr_glob_tactic : env -> glob_tactic_expr -> std_ppcmds
- val pr_tactic : env -> tactic_expr -> std_ppcmds
+ val pr_atomic_tactic : env -> atomic_tactic_expr -> std_ppcmds
val pr_hintbases : string list option -> std_ppcmds
@@ -67,4 +70,11 @@ module type Pp = sig
('constr -> std_ppcmds) ->
('constr -> std_ppcmds) -> 'constr bindings -> std_ppcmds
+ val pr_match_pattern : ('a -> std_ppcmds) -> 'a match_pattern -> std_ppcmds
+
+ val pr_match_rule : bool -> ('a -> std_ppcmds) -> ('b -> std_ppcmds) ->
+ ('b, 'a) match_rule -> std_ppcmds
+
+ val pr_value : tolerability -> Val.t -> std_ppcmds
+
end
diff --git a/printing/ppvernac.ml b/printing/ppvernac.ml
index ffec926a8..10b2bda05 100644
--- a/printing/ppvernac.ml
+++ b/printing/ppvernac.ml
@@ -99,17 +99,6 @@ module Make
| ETBinder false -> str "closed binder"
| ETBinderList _ | ETConstrList _ -> failwith "Internal entry type"
- let strip_meta id =
- let s = Id.to_string id in
- if s.[0] == '$' then Id.of_string (String.sub s 1 (String.length s - 1))
- else id
-
- let pr_production_item = function
- | TacNonTerm (loc, nt, (p, sep)) ->
- let pp_sep = if not (String.is_empty sep) then str "," ++ quote (str sep) else mt () in
- str nt ++ str"(" ++ pr_id (strip_meta p) ++ pp_sep ++ str")"
- | TacTerm s -> qs s
-
let pr_comment pr_c = function
| CommentConstr c -> pr_c c
| CommentString s -> qs s
@@ -378,17 +367,6 @@ module Make
| l -> spc() ++
hov 1 (str"(" ++ prlist_with_sep sep_v2 pr_syntax_modifier l ++ str")")
- let print_level n =
- if not (Int.equal n 0) then
- spc () ++ tag_keyword (str "(at level " ++ int n ++ str ")")
- else
- mt ()
-
- let pr_grammar_tactic_rule n (_,pil,t) =
- hov 2 (keyword "Tactic Notation" ++ print_level n ++ spc() ++
- hov 0 (prlist_with_sep sep pr_production_item pil ++
- spc() ++ str":=" ++ spc() ++ pr_raw_tactic t))
-
let pr_univs pl =
match pl with
| None -> mt ()
@@ -466,8 +444,6 @@ module Make
keyword "Print TypeClasses"
| PrintInstances qid ->
keyword "Print Instances" ++ spc () ++ pr_smart_global qid
- | PrintLtac qid ->
- keyword "Print Ltac" ++ spc() ++ pr_ltac_ref qid
| PrintCoercions ->
keyword "Print Coercions"
| PrintCoercionPaths (s,t) ->
@@ -486,8 +462,6 @@ module Make
keyword "Print Hint *"
| PrintHintDbName s ->
keyword "Print HintDb" ++ spc () ++ str s
- | PrintRewriteHintDbName s ->
- keyword "Print Rewrite HintDb" ++ spc() ++ str s
| PrintUniverses (b, fopt) ->
let cmd =
if b then "Print Sorted Universes"
@@ -646,8 +620,6 @@ module Make
return (keyword "No-parsing-rule for VernacError")
(* Syntax *)
- | VernacTacticNotation (n,r,e) ->
- return (pr_grammar_tactic_rule n ("",r,e))
| VernacOpenCloseScope (_,(opening,sc)) ->
return (
keyword (if opening then "Open " else "Close ") ++
@@ -665,7 +637,7 @@ module Make
| VernacBindScope (sc,cll) ->
return (
keyword "Bind Scope" ++ spc () ++ str sc ++
- spc() ++ keyword "with" ++ spc () ++ prlist_with_sep spc pr_smart_global cll
+ spc() ++ keyword "with" ++ spc () ++ prlist_with_sep spc pr_class_rawexpr cll
)
| VernacArgumentsScope (q,scl) ->
let pr_opt_scope = function
@@ -795,8 +767,8 @@ module Make
hov 0 (
str key ++ spc() ++
(if coe then str"> " else str"") ++ pr_lident id ++ pr_univs pl ++
- pr_and_type_binders_arg indpar ++ spc() ++
- Option.cata (fun s -> str":" ++ spc() ++ pr_lconstr_expr s) (mt()) s ++
+ pr_and_type_binders_arg indpar ++
+ pr_opt (fun s -> str":" ++ spc() ++ pr_lconstr_expr s) s ++
str" :=") ++ pr_constructor_list k lc ++
prlist (pr_decl_notation pr_constr) ntn
in
@@ -981,24 +953,6 @@ module Make
prlist_with_sep (fun () -> str " <+ ") pr_m mexprs)
)
(* Solving *)
- | VernacSolve (i,info,tac,deftac) ->
- let pr_goal_selector = function
- | SelectNth i -> int i ++ str":"
- | SelectId id -> pr_id id ++ str":"
- | SelectAll -> str"all" ++ str":"
- | SelectAllParallel -> str"par"
- in
- let pr_info =
- match info with
- | None -> mt ()
- | Some i -> str"Info"++spc()++int i++spc()
- in
- return (
- (if i = Proof_global.get_default_goal_selector () then mt() else pr_goal_selector i) ++
- pr_info ++
- pr_raw_tactic tac
- ++ (if deftac then str ".." else mt ())
- )
| VernacSolveExistential (i,c) ->
return (keyword "Existential" ++ spc () ++ int i ++ pr_lconstrarg c)
@@ -1030,29 +984,6 @@ module Make
return (keyword "Cd" ++ pr_opt qs s)
(* Commands *)
- | VernacDeclareTacticDefinition l ->
- let pr_tac_body tacdef_body =
- let id, redef, body =
- match tacdef_body with
- | TacticDefinition ((_,id), body) -> pr_id id, false, body
- | TacticRedefinition (id, body) -> pr_ltac_ref id, true, body
- in
- let idl, body =
- match body with
- | Tacexpr.TacFun (idl,b) -> idl,b
- | _ -> [], body in
- id ++
- prlist (function None -> str " _"
- | Some id -> spc () ++ pr_id id) idl
- ++ (if redef then str" ::=" else str" :=") ++ brk(1,1) ++
- pr_raw_tactic body
- in
- return (
- hov 1
- (keyword "Ltac" ++ spc () ++
- prlist_with_sep (fun () ->
- fnl() ++ keyword "with" ++ spc ()) pr_tac_body l)
- )
| VernacCreateHintDb (dbname,b) ->
return (
hov 1 (keyword "Create HintDb" ++ spc () ++
@@ -1271,22 +1202,15 @@ module Make
with Failure _ -> str "<error in " ++ str (fst s) ++ str ">" in
try
let rl = Egramml.get_extend_vernac_rule s in
- let start,rl,cl =
- match rl with
- | Egramml.GramTerminal s :: rl -> str s, rl, cl
- | Egramml.GramNonTerminal _ :: rl -> pr_arg (List.hd cl), rl, List.tl cl
- | [] -> anomaly (Pp.str "Empty entry") in
- let (pp,_) =
- List.fold_left
- (fun (strm,args) pi ->
- let pp,args = match pi with
- | Egramml.GramNonTerminal _ -> (pr_arg (List.hd args), List.tl args)
- | Egramml.GramTerminal s -> (str s, args) in
- (strm ++ spc() ++ pp), args)
- (start,cl) rl in
- hov 1 pp
+ let rec aux rl cl =
+ match rl, cl with
+ | Egramml.GramNonTerminal _ :: rl, arg :: cl -> pr_arg arg :: aux rl cl
+ | Egramml.GramTerminal s :: rl, cl -> str s :: aux rl cl
+ | [], [] -> []
+ | _ -> assert false in
+ hov 1 (pr_sequence (fun x -> x) (aux rl cl))
with Not_found ->
- hov 1 (str "TODO(" ++ str (fst s) ++ prlist_with_sep sep pr_arg cl ++ str ")")
+ hov 1 (str "TODO(" ++ str (fst s) ++ spc () ++ prlist_with_sep sep pr_arg cl ++ str ")")
in pr_vernac
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index b7b1d67f0..9745a7925 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -218,8 +218,8 @@ let print_polymorphism ref =
let print_primitive_record recflag mipv = function
| Some (Some (_, ps,_)) ->
let eta = match recflag with
- | Decl_kinds.CoFinite -> mt ()
- | Decl_kinds.Finite | Decl_kinds.BiFinite -> str " and has eta conversion"
+ | Decl_kinds.CoFinite | Decl_kinds.Finite -> mt ()
+ | Decl_kinds.BiFinite -> str " and has eta conversion"
in
[pr_id mipv.(0).mind_typename ++ str" is primitive" ++ eta ++ str"."]
| _ -> []
diff --git a/printing/printer.ml b/printing/printer.ml
index b89005887..cc8da4097 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -28,9 +28,7 @@ let delayed_emacs_cmd s =
if !Flags.print_emacs then s () else str ""
let get_current_context () =
- try Pfedit.get_current_goal_context ()
- with e when Logic.catchable_exception e ->
- (Evd.empty, Global.env())
+ Pfedit.get_current_context ()
(**********************************************************************)
(** Terms *)
@@ -50,7 +48,7 @@ let pr_lconstr_core goal_concl_style env sigma t =
let pr_lconstr_env env = pr_lconstr_core false env
let pr_constr_env env = pr_constr_core false env
-let _ = Hook.set Proofview.Refine.pr_constr pr_constr_env
+let _ = Hook.set Refine.pr_constr pr_constr_env
let pr_lconstr_goal_style_env env = pr_lconstr_core true env
let pr_constr_goal_style_env env = pr_constr_core true env
@@ -383,16 +381,12 @@ let pr_transparent_state (ids, csts) =
let default_pr_goal gs =
let (g,sigma) = Goal.V82.nf_evar (project gs) (sig_it gs) in
let env = Goal.V82.env sigma g in
- let preamb,thesis,penv,pc =
- mt (), mt (),
- pr_context_of env sigma,
- pr_goal_concl_style_env env sigma (Goal.V82.concl sigma g)
- in
- preamb ++
- str" " ++ hv 0 (penv ++ fnl () ++
- str (emacs_str "") ++
- str "============================" ++ fnl () ++
- thesis ++ str " " ++ pc)
+ let concl = Goal.V82.concl sigma g in
+ let goal =
+ pr_context_of env sigma ++ cut () ++
+ str "============================" ++ cut () ++
+ pr_goal_concl_style_env env sigma concl in
+ str " " ++ v 0 goal
(* display a goal tag *)
let pr_goal_tag g =
@@ -554,7 +548,7 @@ let default_pr_subgoals ?(pr_first=true) close_cmd sigma seeds shelf stack goals
(* Side effect! This has to be made more robust *)
let () =
match close_cmd with
- | Some cmd -> msg_info cmd
+ | Some cmd -> Feedback.msg_info cmd
| None -> ()
in
match goals with
@@ -632,12 +626,12 @@ let pr_open_subgoals ?(proof=Proof_global.give_me_the_proof ()) () =
begin match bgoals,shelf,given_up with
| [] , [] , [] -> pr_subgoals None sigma seeds shelf stack goals
| [] , [] , _ ->
- msg_info (str "No more subgoals, but there are some goals you gave up:");
+ Feedback.msg_info (str "No more subgoals, but there are some goals you gave up:");
fnl ()
++ pr_subgoals ~pr_first:false None bsigma seeds [] [] given_up
++ fnl () ++ str "You need to go back and solve them."
| [] , _ , _ ->
- msg_info (str "All the remaining goals are on the shelf.");
+ Feedback.msg_info (str "All the remaining goals are on the shelf.");
fnl ()
++ pr_subgoals ~pr_first:false None bsigma seeds [] [] shelf
| _ , _, _ ->
@@ -688,35 +682,10 @@ let pr_prim_rule = function
(str"cut " ++ pr_constr t ++
str ";[" ++ cl ++ str"intro " ++ pr_id id ++ str"|idtac]")
- | FixRule (f,n,[],_) ->
- (str"fix " ++ pr_id f ++ str"/" ++ int n)
-
- | FixRule (f,n,others,j) ->
- if not (Int.equal j 0) then msg_warning (strbrk "Unsupported printing of \"fix\"");
- let rec print_mut = function
- | (f,n,ar)::oth ->
- pr_id f ++ str"/" ++ int n ++ str" : " ++ pr_lconstr ar ++ print_mut oth
- | [] -> mt () in
- (str"fix " ++ pr_id f ++ str"/" ++ int n ++
- str" with " ++ print_mut others)
-
- | Cofix (f,[],_) ->
- (str"cofix " ++ pr_id f)
-
- | Cofix (f,others,j) ->
- if not (Int.equal j 0) then msg_warning (strbrk "Unsupported printing of \"fix\"");
- let rec print_mut = function
- | (f,ar)::oth ->
- (pr_id f ++ str" : " ++ pr_lconstr ar ++ print_mut oth)
- | [] -> mt () in
- (str"cofix " ++ pr_id f ++ str" with " ++ print_mut others)
| Refine c ->
str(if Termops.occur_meta c then "refine " else "exact ") ++
Constrextern.with_meta_as_hole pr_constr c
- | Thin ids ->
- (str"clear " ++ pr_sequence pr_id ids)
-
| Move (id1,id2) ->
(str"move " ++ pr_id id1 ++ Miscprint.pr_move_location pr_id id2)
@@ -739,18 +708,17 @@ module OrderedContextObject =
struct
type t = context_object
let compare x y =
- match x , y with
- | Variable i1 , Variable i2 -> Id.compare i1 i2
- | Axiom (k1,_) , Axiom (k2, _) -> con_ord k1 k2
- | Opaque k1 , Opaque k2 -> con_ord k1 k2
- | Transparent k1 , Transparent k2 -> con_ord k1 k2
- | Axiom _ , Variable _ -> 1
- | Opaque _ , Variable _
- | Opaque _ , Axiom _ -> 1
- | Transparent _ , Variable _
- | Transparent _ , Axiom _
- | Transparent _ , Opaque _ -> 1
- | _ , _ -> -1
+ match x , y with
+ | Variable i1 , Variable i2 -> Id.compare i1 i2
+ | Variable _ , _ -> -1
+ | _ , Variable _ -> 1
+ | Axiom (k1,_) , Axiom (k2, _) -> con_ord k1 k2
+ | Axiom _ , _ -> -1
+ | _ , Axiom _ -> 1
+ | Opaque k1 , Opaque k2 -> con_ord k1 k2
+ | Opaque _ , _ -> -1
+ | _ , Opaque _ -> 1
+ | Transparent k1 , Transparent k2 -> con_ord k1 k2
end
module ContextObjectSet = Set.Make (OrderedContextObject)
diff --git a/printing/printing.mllib b/printing/printing.mllib
index 652a34fa1..bc8f0750e 100644
--- a/printing/printing.mllib
+++ b/printing/printing.mllib
@@ -2,12 +2,8 @@ Genprint
Pputils
Ppannotation
Ppconstr
-Ppconstrsig
Printer
Pptactic
-Pptacticsig
Printmod
Prettyp
Ppvernac
-Ppvernacsig
-Richprinter
diff --git a/printing/printmod.ml b/printing/printmod.ml
index 9354cd28d..5f98eeeab 100644
--- a/printing/printmod.ml
+++ b/printing/printmod.ml
@@ -65,7 +65,6 @@ let get_new_id locals id =
(** Inductive declarations *)
-open Termops
open Reduction
let print_params env sigma params =
diff --git a/proofs/clenv.ml b/proofs/clenv.ml
index 1ef0b087b..78dce0d64 100644
--- a/proofs/clenv.ml
+++ b/proofs/clenv.ml
@@ -491,7 +491,8 @@ let clenv_unify_binding_type clenv c t u =
let evd,c = w_coerce_to_type (cl_env clenv) clenv.evd c t u in
TypeProcessed, { clenv with evd = evd }, c
with
- | PretypeError (_,_,ActualTypeNotCoercible (_,_,NotClean _)) as e ->
+ | PretypeError (_,_,ActualTypeNotCoercible (_,_,
+ (NotClean _ | ConversionFailed _))) as e ->
raise e
| e when precatchable_exception e ->
TypeNotProcessed, clenv, c
diff --git a/proofs/clenv.mli b/proofs/clenv.mli
index 59b166ea0..e9236b1da 100644
--- a/proofs/clenv.mli
+++ b/proofs/clenv.mli
@@ -6,6 +6,10 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** This file defines clausenv, which is a deprecated way to handle open terms
+ in the proof engine. Most of the API here is legacy except for the
+ evar-based clauses. *)
+
open Names
open Term
open Environ
diff --git a/proofs/clenvtac.mli b/proofs/clenvtac.mli
index 00e74a247..aa091aecd 100644
--- a/proofs/clenvtac.mli
+++ b/proofs/clenvtac.mli
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** Legacy components of the previous proof engine. *)
+
open Term
open Clenv
open Tacexpr
diff --git a/proofs/evar_refiner.ml b/proofs/evar_refiner.ml
index 059ae54c9..3192a6a29 100644
--- a/proofs/evar_refiner.ml
+++ b/proofs/evar_refiner.ml
@@ -59,14 +59,3 @@ let w_refine (evk,evi) (ltac_var,rawc) sigma =
str (string_of_existential evk))
in
define_and_solve_constraints evk typed_c env (evars_reset_evd sigma' sigma)
-
-(* vernac command Existential *)
-
-(* Main component of vernac command Existential *)
-let instantiate_pf_com evk com sigma =
- let evi = Evd.find sigma evk in
- let env = Evd.evar_filtered_env evi in
- let rawc = Constrintern.intern_constr env com in
- let ltac_vars = Pretyping.empty_lvar in
- let sigma' = w_refine (evk, evi) (ltac_vars, rawc) sigma in
- sigma'
diff --git a/proofs/evar_refiner.mli b/proofs/evar_refiner.mli
index 35a3e5d82..e3778e94c 100644
--- a/proofs/evar_refiner.mli
+++ b/proofs/evar_refiner.mli
@@ -13,8 +13,3 @@ open Pretyping
val w_refine : evar * evar_info ->
glob_constr_ltac_closure -> evar_map -> evar_map
-
-val instantiate_pf_com :
- Evd.evar -> Constrexpr.constr_expr -> Evd.evar_map -> Evd.evar_map
-
-(** the instantiate tactic was moved to [tactics/evar_tactics.ml] *)
diff --git a/proofs/goal.mli b/proofs/goal.mli
index 8a3d6e815..6a79c1f45 100644
--- a/proofs/goal.mli
+++ b/proofs/goal.mli
@@ -6,7 +6,9 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(* This module implements the abstract interface to goals *)
+(** This module implements the abstract interface to goals. Most of the code
+ here is useless and should be eventually removed. Consider using
+ {!Proofview.Goal} instead. *)
type goal = Evar.t
diff --git a/proofs/logic.ml b/proofs/logic.ml
index 09f308abe..fd8a70c65 100644
--- a/proofs/logic.ml
+++ b/proofs/logic.ml
@@ -77,10 +77,10 @@ let with_check = Flags.with_option check
(* [apply_to_hyp sign id f] splits [sign] into [tail::[id,_,_]::head] and
returns [tail::(f head (id,_,_) (rev tail))] *)
-let apply_to_hyp sign id f =
+let apply_to_hyp check sign id f =
try apply_to_hyp sign id f
with Hyp_not_found ->
- if !check then error_no_such_hypothesis id
+ if check then error_no_such_hypothesis id
else sign
let check_typability env sigma c =
@@ -493,7 +493,7 @@ let convert_hyp check sign sigma d =
let env = Global.env() in
let reorder = ref [] in
let sign' =
- apply_to_hyp sign id
+ apply_to_hyp check sign id
(fun _ d' _ ->
let _,c,ct = to_tuple d' in
let env = Global.env_of_context sign in
@@ -543,92 +543,6 @@ let prim_refiner r sigma goal =
let sigma = Goal.V82.partial_solution_to sigma goal sg2 oterm in
if b then ([sg1;sg2],sigma) else ([sg2;sg1],sigma)
- | FixRule (f,n,rest,j) ->
- let rec check_ind env k cl =
- match kind_of_term (strip_outer_cast cl) with
- | Prod (na,c1,b) ->
- if Int.equal k 1 then
- try
- fst (find_inductive env sigma c1)
- with Not_found ->
- error "Cannot do a fixpoint on a non inductive type."
- else
- let open Context.Rel.Declaration in
- check_ind (push_rel (LocalAssum (na,c1)) env) (k-1) b
- | _ -> error "Not enough products."
- in
- let ((sp,_),u) = check_ind env n cl in
- let firsts,lasts = List.chop j rest in
- let all = firsts@(f,n,cl)::lasts in
- let rec mk_sign sign = function
- | (f,n,ar)::oth ->
- let ((sp',_),u') = check_ind env n ar in
- if not (eq_mind sp sp') then
- error "Fixpoints should be on the same mutual inductive declaration.";
- if !check && mem_named_context f (named_context_of_val sign) then
- errorlabstrm "Logic.prim_refiner"
- (str "Name " ++ pr_id f ++ str " already used in the environment");
- mk_sign (push_named_context_val (LocalAssum (f,ar)) sign) oth
- | [] ->
- Evd.Monad.List.map (fun (_,_,c) sigma ->
- let gl,ev,sig' =
- Goal.V82.mk_goal sigma sign c (Goal.V82.extra sigma goal) in
- (gl,ev),sig')
- all sigma
- in
- let (gls_evs,sigma) = mk_sign sign all in
- let (gls,evs) = List.split gls_evs in
- let ids = List.map pi1 all in
- let evs = List.map (Vars.subst_vars (List.rev ids)) evs in
- let indxs = Array.of_list (List.map (fun n -> n-1) (List.map pi2 all)) in
- let funnames = Array.of_list (List.map (fun i -> Name i) ids) in
- let typarray = Array.of_list (List.map pi3 all) in
- let bodies = Array.of_list evs in
- let oterm = Term.mkFix ((indxs,0),(funnames,typarray,bodies)) in
- let sigma = Goal.V82.partial_solution sigma goal oterm in
- (gls,sigma)
-
- | Cofix (f,others,j) ->
- let rec check_is_coind env cl =
- let b = whd_betadeltaiota env sigma cl in
- match kind_of_term b with
- | Prod (na,c1,b) -> let open Context.Rel.Declaration in
- check_is_coind (push_rel (LocalAssum (na,c1)) env) b
- | _ ->
- try
- let _ = find_coinductive env sigma b in ()
- with Not_found ->
- error "All methods must construct elements in coinductive types."
- in
- let firsts,lasts = List.chop j others in
- let all = firsts@(f,cl)::lasts in
- List.iter (fun (_,c) -> check_is_coind env c) all;
- let rec mk_sign sign = function
- | (f,ar)::oth ->
- (try
- (let _ = lookup_named_val f sign in
- error "Name already used in the environment.")
- with
- | Not_found ->
- mk_sign (push_named_context_val (LocalAssum (f,ar)) sign) oth)
- | [] ->
- Evd.Monad.List.map (fun (_,c) sigma ->
- let gl,ev,sigma =
- Goal.V82.mk_goal sigma sign c (Goal.V82.extra sigma goal) in
- (gl,ev),sigma)
- all sigma
- in
- let (gls_evs,sigma) = mk_sign sign all in
- let (gls,evs) = List.split gls_evs in
- let (ids,types) = List.split all in
- let evs = List.map (Vars.subst_vars (List.rev ids)) evs in
- let funnames = Array.of_list (List.map (fun i -> Name i) ids) in
- let typarray = Array.of_list types in
- let bodies = Array.of_list evs in
- let oterm = Term.mkCoFix (0,(funnames,typarray,bodies)) in
- let sigma = Goal.V82.partial_solution sigma goal oterm in
- (gls,sigma)
-
| Refine c ->
check_meta_variables c;
let (sgl,cl',sigma,oterm) = mk_refgoals sigma goal [] cl c in
@@ -636,16 +550,6 @@ let prim_refiner r sigma goal =
let sigma = Goal.V82.partial_solution sigma goal oterm in
(sgl, sigma)
- (* And now the structural rules *)
- | Thin ids ->
- let ids = List.fold_left (fun accu x -> Id.Set.add x accu) Id.Set.empty ids in
- let (hyps,concl,nsigma) = clear_hyps env sigma ids sign cl in
- let (gl,ev,sigma) =
- Goal.V82.mk_goal nsigma hyps concl (Goal.V82.extra nsigma goal)
- in
- let sigma = Goal.V82.partial_solution_to sigma goal gl ev in
- ([gl], sigma)
-
| Move (hfrom, hto) ->
let (left,right,declfrom,toleft) =
split_sign hfrom hto (named_context_of_val sign) in
diff --git a/proofs/logic.mli b/proofs/logic.mli
index 9aa4ac207..2764d28c0 100644
--- a/proofs/logic.mli
+++ b/proofs/logic.mli
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** Legacy proof engine. Do not use in newly written code. *)
+
open Names
open Term
open Evd
diff --git a/proofs/pfedit.ml b/proofs/pfedit.ml
index 20d696fd9..2863384b5 100644
--- a/proofs/pfedit.ml
+++ b/proofs/pfedit.ml
@@ -71,21 +71,33 @@ let get_nth_V82_goal i =
with Failure _ -> raise NoSuchGoal
let get_goal_context_gen i =
- try
-let { it=goal ; sigma=sigma; } = get_nth_V82_goal i in
-(sigma, Refiner.pf_env { it=goal ; sigma=sigma; })
- with Proof_global.NoCurrentProof -> Errors.error "No focused proof."
+ let { it=goal ; sigma=sigma; } = get_nth_V82_goal i in
+ (sigma, Refiner.pf_env { it=goal ; sigma=sigma; })
let get_goal_context i =
try get_goal_context_gen i
- with NoSuchGoal -> Errors.error "No such goal."
+ with Proof_global.NoCurrentProof -> Errors.error "No focused proof."
+ | NoSuchGoal -> Errors.error "No such goal."
let get_current_goal_context () =
try get_goal_context_gen 1
- with NoSuchGoal ->
+ with Proof_global.NoCurrentProof -> Errors.error "No focused proof."
+ | NoSuchGoal ->
(* spiwack: returning empty evar_map, since if there is no goal, under focus,
there is no accessible evar either *)
- (Evd.empty, Global.env ())
+ let env = Global.env () in
+ (Evd.from_env env, env)
+
+let get_current_context () =
+ try get_goal_context_gen 1
+ with Proof_global.NoCurrentProof ->
+ let env = Global.env () in
+ (Evd.from_env env, env)
+ | NoSuchGoal ->
+ (* No more focused goals ? *)
+ let p = get_pftreestate () in
+ let evd = Proof.in_proof p (fun x -> x) in
+ (evd, Global.env ())
let current_proof_statement () =
match Proof_global.V82.get_current_initial_conclusions () with
@@ -105,14 +117,12 @@ let solve ?with_end_tac gi info_lvl tac pr =
| Vernacexpr.SelectNth i -> Proofview.tclFOCUS i i tac
| Vernacexpr.SelectId id -> Proofview.tclFOCUSID id tac
| Vernacexpr.SelectAll -> tac
- | Vernacexpr.SelectAllParallel ->
- Errors.anomaly(str"SelectAllParallel not handled by Stm")
in
let (p,(status,info)) = Proof.run_tactic (Global.env ()) tac pr in
let () =
match info_lvl with
| None -> ()
- | Some i -> Pp.msg_info (hov 0 (Proofview.Trace.pr_info ~lvl:i info))
+ | Some i -> Feedback.msg_info (hov 0 (Proofview.Trace.pr_info ~lvl:i info))
in
(p,status)
with
diff --git a/proofs/pfedit.mli b/proofs/pfedit.mli
index cd8992015..666730e1a 100644
--- a/proofs/pfedit.mli
+++ b/proofs/pfedit.mli
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** Global proof state. A quite redundant wrapper on {!Proof_global}. *)
+
open Loc
open Names
open Term
@@ -93,6 +95,14 @@ val get_goal_context : int -> Evd.evar_map * env
val get_current_goal_context : unit -> Evd.evar_map * env
+(** [get_current_context ()] returns the context of the
+ current focused goal. If there is no focused goal but there
+ is a proof in progress, it returns the corresponding evar_map.
+ If there is no pending proof then it returns the current global
+ environment and empty evar_map. *)
+
+val get_current_context : unit -> Evd.evar_map * env
+
(** [current_proof_statement] *)
val current_proof_statement :
diff --git a/proofs/proof.ml b/proofs/proof.ml
index 0489305aa..86af420dc 100644
--- a/proofs/proof.ml
+++ b/proofs/proof.ml
@@ -334,22 +334,24 @@ let compact p =
(*** Tactics ***)
let run_tactic env tac pr =
+ let open Proofview.Notations in
let sp = pr.proofview in
- let (_,tacticced_proofview,(status,to_shelve,give_up),info_trace) =
- Proofview.apply env tac sp
+ let undef sigma l = List.filter (fun g -> Evd.is_undefined sigma g) l in
+ let tac =
+ tac >>= fun () ->
+ Proofview.tclEVARMAP >>= fun sigma ->
+ (* Already solved goals are not to be counted as shelved. Nor are
+ they to be marked as unresolvable. *)
+ let retrieved = undef sigma (List.rev (Evd.future_goals sigma)) in
+ let sigma = List.fold_left Proofview.Unsafe.mark_as_goal sigma retrieved in
+ Proofview.Unsafe.tclEVARS sigma >>= fun () ->
+ Proofview.tclUNIT retrieved
in
- let sigma = Proofview.return tacticced_proofview in
- (* Already solved goals are not to be counted as shelved. Nor are
- they to be marked as unresolvable. *)
- let undef l = List.filter (fun g -> Evd.is_undefined sigma g) l in
- let retrieved = undef (List.rev (Evd.future_goals sigma)) in
- let shelf = (undef pr.shelf)@retrieved@(undef to_shelve) in
- let proofview =
- List.fold_left
- Proofview.Unsafe.mark_as_goal
- tacticced_proofview
- retrieved
+ let (retrieved,proofview,(status,to_shelve,give_up),info_trace) =
+ Proofview.apply env tac sp
in
+ let sigma = Proofview.return proofview in
+ let shelf = (undef sigma pr.shelf)@retrieved@(undef sigma to_shelve) in
let given_up = pr.given_up@give_up in
let proofview = Proofview.Unsafe.reset_future_goals proofview in
{ pr with proofview ; shelf ; given_up },(status,info_trace)
@@ -387,9 +389,27 @@ module V82 = struct
{ p with proofview = Proofview.V82.grab p.proofview }
+ (* Main component of vernac command Existential *)
let instantiate_evar n com pr =
- let sp = pr.proofview in
- let proofview = Proofview.V82.instantiate_evar n com sp in
+ let tac =
+ Proofview.tclBIND Proofview.tclEVARMAP begin fun sigma ->
+ let (evk, evi) =
+ let evl = Evarutil.non_instantiated sigma in
+ let evl = Evar.Map.bindings evl in
+ if (n <= 0) then
+ Errors.error "incorrect existential variable index"
+ else if CList.length evl < n then
+ Errors.error "not so many uninstantiated existential variables"
+ else
+ CList.nth evl (n-1)
+ in
+ let env = Evd.evar_filtered_env evi in
+ let rawc = Constrintern.intern_constr env com in
+ let ltac_vars = Pretyping.empty_lvar in
+ let sigma = Evar_refiner.w_refine (evk, evi) (ltac_vars, rawc) sigma in
+ Proofview.Unsafe.tclEVARS sigma
+ end in
+ let ((), proofview, _, _) = Proofview.apply (Global.env ()) tac pr.proofview in
let shelf =
List.filter begin fun g ->
Evd.is_undefined (Proofview.return proofview) g
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index 403a36141..36277bf58 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -23,8 +23,9 @@ open Names
(* Type of proof modes :
- A function [set] to set it *from standard mode*
- A function [reset] to reset the *standard mode* from it *)
+type proof_mode_name = string
type proof_mode = {
- name : string ;
+ name : proof_mode_name ;
set : unit -> unit ;
reset : unit -> unit
}
@@ -36,7 +37,7 @@ let find_proof_mode n =
Errors.error (Format.sprintf "No proof mode named \"%s\"." n)
let register_proof_mode ({name = n} as m) =
- Hashtbl.add proof_modes n (Ephemeron.create m)
+ Hashtbl.add proof_modes n (CEphemeron.create m)
(* initial mode: standard mode *)
let standard = { name = "No" ; set = (fun ()->()) ; reset = (fun () -> ()) }
@@ -45,6 +46,9 @@ let _ = register_proof_mode standard
(* Default proof mode, to be set at the beginning of proofs. *)
let default_proof_mode = ref (find_proof_mode "No")
+let get_default_proof_mode_name () =
+ (CEphemeron.default !default_proof_mode standard).name
+
let _ =
Goptions.declare_string_option {Goptions.
optsync = true ;
@@ -52,7 +56,7 @@ let _ =
optname = "default proof mode" ;
optkey = ["Default";"Proof";"Mode"] ;
optread = begin fun () ->
- (Ephemeron.default !default_proof_mode standard).name
+ (CEphemeron.default !default_proof_mode standard).name
end;
optwrite = begin fun n ->
default_proof_mode := find_proof_mode n
@@ -83,12 +87,12 @@ type closed_proof = proof_object * proof_terminator
type pstate = {
pid : Id.t;
- terminator : proof_terminator Ephemeron.key;
+ terminator : proof_terminator CEphemeron.key;
endline_tactic : Tacexpr.raw_tactic_expr option;
section_vars : Context.section_context option;
proof : Proof.proof;
strength : Decl_kinds.goal_kind;
- mode : proof_mode Ephemeron.key;
+ mode : proof_mode CEphemeron.key;
universe_binders: universe_binders option;
}
@@ -106,11 +110,11 @@ let current_proof_mode = ref !default_proof_mode
let update_proof_mode () =
match !pstates with
| { mode = m } :: _ ->
- Ephemeron.iter_opt !current_proof_mode (fun x -> x.reset ());
+ CEphemeron.iter_opt !current_proof_mode (fun x -> x.reset ());
current_proof_mode := m;
- Ephemeron.iter_opt !current_proof_mode (fun x -> x.set ())
+ CEphemeron.iter_opt !current_proof_mode (fun x -> x.set ())
| _ ->
- Ephemeron.iter_opt !current_proof_mode (fun x -> x.reset ());
+ CEphemeron.iter_opt !current_proof_mode (fun x -> x.reset ());
current_proof_mode := find_proof_mode "No"
(* combinators for the current_proof lists *)
@@ -218,9 +222,9 @@ let set_proof_mode mn =
set_proof_mode (find_proof_mode mn) (get_current_proof_name ())
let activate_proof_mode mode =
- Ephemeron.iter_opt (find_proof_mode mode) (fun x -> x.set ())
-let disactivate_proof_mode mode =
- Ephemeron.iter_opt (find_proof_mode mode) (fun x -> x.reset ())
+ CEphemeron.iter_opt (find_proof_mode mode) (fun x -> x.set ())
+let disactivate_current_proof_mode () =
+ CEphemeron.iter_opt !current_proof_mode (fun x -> x.reset ())
(** [start_proof sigma id str goals terminator] starts a proof of name
[id] with goals [goals] (a list of pairs of environment and
@@ -233,7 +237,7 @@ let disactivate_proof_mode mode =
let start_proof sigma id ?pl str goals terminator =
let initial_state = {
pid = id;
- terminator = Ephemeron.create terminator;
+ terminator = CEphemeron.create terminator;
proof = Proof.start sigma goals;
endline_tactic = None;
section_vars = None;
@@ -245,7 +249,7 @@ let start_proof sigma id ?pl str goals terminator =
let start_dependent_proof id ?pl str goals terminator =
let initial_state = {
pid = id;
- terminator = Ephemeron.create terminator;
+ terminator = CEphemeron.create terminator;
proof = Proof.dependent_start goals;
endline_tactic = None;
section_vars = None;
@@ -384,7 +388,7 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now fpl =
in
{ id = pid; entries = entries; persistence = strength;
universes = (universes, binders) },
- fun pr_ending -> Ephemeron.get terminator pr_ending
+ fun pr_ending -> CEphemeron.get terminator pr_ending
type closed_proof_output = (Term.constr * Safe_typing.private_constants) list * Evd.evar_universe_context
@@ -432,11 +436,11 @@ let close_proof ~keep_body_ucst_separate fix_exn =
(** Gets the current terminator without checking that the proof has
been completed. Useful for the likes of [Admitted]. *)
-let get_terminator () = Ephemeron.get ( cur_pstate() ).terminator
+let get_terminator () = CEphemeron.get ( cur_pstate() ).terminator
let set_terminator hook =
match !pstates with
| [] -> raise NoCurrentProof
- | p :: ps -> pstates := { p with terminator = Ephemeron.create hook } :: ps
+ | p :: ps -> pstates := { p with terminator = CEphemeron.create hook } :: ps
@@ -664,7 +668,6 @@ let print_goal_selector = function
| Vernacexpr.SelectAll -> "all"
| Vernacexpr.SelectNth i -> string_of_int i
| Vernacexpr.SelectId id -> Id.to_string id
- | Vernacexpr.SelectAllParallel -> "par"
let parse_goal_selector = function
| "all" -> Vernacexpr.SelectAll
diff --git a/proofs/proof_global.mli b/proofs/proof_global.mli
index ebe7f6d6f..59daa2968 100644
--- a/proofs/proof_global.mli
+++ b/proofs/proof_global.mli
@@ -16,8 +16,9 @@
- A function [reset] to reset the *standard mode* from it
*)
+type proof_mode_name = string
type proof_mode = {
- name : string ;
+ name : proof_mode_name ;
set : unit -> unit ;
reset : unit -> unit
}
@@ -27,6 +28,7 @@ type proof_mode = {
One mode is already registered - the standard mode - named "No",
It corresponds to Coq default setting are they are set when coqtop starts. *)
val register_proof_mode : proof_mode -> unit
+val get_default_proof_mode_name : unit -> proof_mode_name
val there_are_pending_proofs : unit -> bool
val check_no_pending_proof : unit -> unit
@@ -40,7 +42,7 @@ val discard_all : unit -> unit
(** [set_proof_mode] sets the proof mode to be used after it's called. It is
typically called by the Proof Mode command. *)
-val set_proof_mode : string -> unit
+val set_proof_mode : proof_mode_name -> unit
exception NoCurrentProof
val give_me_the_proof : unit -> Proof.proof
@@ -153,8 +155,8 @@ val get_universe_binders : unit -> universe_binders option
(**********************************************************)
-val activate_proof_mode : string -> unit
-val disactivate_proof_mode : string -> unit
+val activate_proof_mode : proof_mode_name -> unit
+val disactivate_current_proof_mode : unit -> unit
(**********************************************************)
(* *)
diff --git a/proofs/proof_type.ml b/proofs/proof_type.ml
deleted file mode 100644
index dd2c7b253..000000000
--- a/proofs/proof_type.ml
+++ /dev/null
@@ -1,52 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(*i*)
-open Evd
-open Names
-open Term
-open Tacexpr
-open Glob_term
-open Nametab
-open Misctypes
-(*i*)
-
-(* This module defines the structure of proof tree and the tactic type. So, it
- is used by Proof_tree and Refiner *)
-
-(** Types of goals, tactics, rules ... *)
-
-type goal = Goal.goal
-
-type tactic = goal sigma -> goal list sigma
-
-type prim_rule =
- | Cut of bool * bool * Id.t * types
- | FixRule of Id.t * int * (Id.t * int * constr) list * int
- | Cofix of Id.t * (Id.t * constr) list * int
- | Refine of constr
- | Thin of Id.t list
- | Move of Id.t * Id.t move_location
-
-(** Nowadays, the only rules we'll consider are the primitive rules *)
-
-type rule = prim_rule
-
-(** Ltac traces *)
-
-type ltac_call_kind =
- | LtacMLCall of glob_tactic_expr
- | LtacNotationCall of KerName.t
- | LtacNameCall of ltac_constant
- | LtacAtomCall of glob_atomic_tactic_expr
- | LtacVarCall of Id.t * glob_tactic_expr
- | LtacConstrInterp of glob_constr * Pretyping.ltac_var_map
-
-type ltac_trace = (Loc.t * ltac_call_kind) list
-
-let (ltac_trace_info : ltac_trace Exninfo.t) = Exninfo.make ()
diff --git a/proofs/proof_type.mli b/proofs/proof_type.mli
index aa05f58ab..f7798a0ed 100644
--- a/proofs/proof_type.mli
+++ b/proofs/proof_type.mli
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** Legacy proof engine. Do not use in newly written code. *)
+
open Evd
open Names
open Term
@@ -19,57 +21,13 @@ open Misctypes
type prim_rule =
| Cut of bool * bool * Id.t * types
- | FixRule of Id.t * int * (Id.t * int * constr) list * int
- | Cofix of Id.t * (Id.t * constr) list * int
| Refine of constr
- | Thin of Id.t list
| Move of Id.t * Id.t move_location
(** Nowadays, the only rules we'll consider are the primitive rules *)
type rule = prim_rule
-(** The type [goal sigma] is the type of subgoal. It has the following form
-{v it = \{ evar_concl = [the conclusion of the subgoal]
- evar_hyps = [the hypotheses of the subgoal]
- evar_body = Evar_Empty;
- evar_info = \{ pgm : [The Realizer pgm if any]
- lc : [Set of evar num occurring in subgoal] \}\}
- sigma = \{ stamp = [an int chardacterizing the ed field, for quick compare]
- ed : [A set of existential variables depending in the subgoal]
- number of first evar,
- it = \{ evar_concl = [the type of first evar]
- evar_hyps = [the context of the evar]
- evar_body = [the body of the Evar if any]
- evar_info = \{ pgm : [Useless ??]
- lc : [Set of evars occurring
- in the type of evar] \} \};
- ...
- number of last evar,
- it = \{ evar_concl = [the type of evar]
- evar_hyps = [the context of the evar]
- evar_body = [the body of the Evar if any]
- evar_info = \{ pgm : [Useless ??]
- lc : [Set of evars occurring
- in the type of evar] \} \} \} v}
-*)
-
type goal = Goal.goal
type tactic = goal sigma -> goal list sigma
-
-(** Ltac traces *)
-
-(** TODO: Move those definitions somewhere sensible *)
-
-type ltac_call_kind =
- | LtacMLCall of glob_tactic_expr
- | LtacNotationCall of KerName.t
- | LtacNameCall of ltac_constant
- | LtacAtomCall of glob_atomic_tactic_expr
- | LtacVarCall of Id.t * glob_tactic_expr
- | LtacConstrInterp of glob_constr * Pretyping.ltac_var_map
-
-type ltac_trace = (Loc.t * ltac_call_kind) list
-
-val ltac_trace_info : ltac_trace Exninfo.t
diff --git a/proofs/proof_using.ml b/proofs/proof_using.ml
index 681a7fa1a..caa9b328a 100644
--- a/proofs/proof_using.ml
+++ b/proofs/proof_using.ml
@@ -128,7 +128,7 @@ let suggest_Proof_using name env vars ids_typ context_ids =
if S.equal all_needed fwd_typ then valid (str "Type*");
if S.equal all all_needed then valid(str "All");
valid (pr_set false needed);
- msg_info (
+ Feedback.msg_info (
str"The proof of "++ str name ++ spc() ++
str "should start with one of the following commands:"++spc()++
v 0 (
diff --git a/proofs/proof_using.mli b/proofs/proof_using.mli
index 1bf38b690..b2c65412f 100644
--- a/proofs/proof_using.mli
+++ b/proofs/proof_using.mli
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** Utility code for section variables handling in Proof using... *)
+
val process_expr :
Environ.env -> Vernacexpr.section_subset_expr -> Constr.types list ->
Names.Id.t list
diff --git a/proofs/proofs.mllib b/proofs/proofs.mllib
index 1bd701cb9..804a54360 100644
--- a/proofs/proofs.mllib
+++ b/proofs/proofs.mllib
@@ -2,16 +2,13 @@ Miscprint
Goal
Evar_refiner
Proof_using
-Proof_type
-Proof_errors
Logic
-Proofview
+Refine
Proof
Proof_global
Redexpr
Refiner
Tacmach
Pfedit
-Tactic_debug
Clenv
Clenvtac
diff --git a/proofs/redexpr.ml b/proofs/redexpr.ml
index 2d886b8e1..13b5848a3 100644
--- a/proofs/redexpr.ml
+++ b/proofs/redexpr.ml
@@ -31,7 +31,7 @@ let cbv_vm env sigma c =
let cbv_native env sigma c =
if Coq_config.no_native_compiler then
- let () = msg_warning (str "native_compute disabled at configure time; falling back to vm_compute.") in
+ let () = Feedback.msg_warning (str "native_compute disabled at configure time; falling back to vm_compute.") in
cbv_vm env sigma c
else
let ctyp = Retyping.get_type_of env sigma c in
@@ -221,7 +221,7 @@ let reduction_of_red_expr env =
let am = if !simplIsCbn then strong_cbn (make_flag f) else simpl in
let () =
if not (!simplIsCbn || List.is_empty f.rConst) then
- Pp.msg_warning (Pp.strbrk "The legacy simpl does not deal with delta flags.") in
+ Feedback.msg_warning (Pp.strbrk "The legacy simpl does not deal with delta flags.") in
(contextualize (if head_style then whd_am else am) am o,DEFAULTcast)
| Cbv f -> (e_red (cbv_norm_flags (make_flag f)),DEFAULTcast)
| Cbn f ->
diff --git a/proofs/redexpr.mli b/proofs/redexpr.mli
index b91911087..d4c2c4a6c 100644
--- a/proofs/redexpr.mli
+++ b/proofs/redexpr.mli
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** Interpretation layer of redexprs such as hnf, cbv, etc. *)
+
open Names
open Term
open Pattern
diff --git a/proofs/refine.ml b/proofs/refine.ml
new file mode 100644
index 000000000..76e2d7dc5
--- /dev/null
+++ b/proofs/refine.ml
@@ -0,0 +1,120 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Util
+open Sigma.Notations
+open Proofview.Notations
+open Context.Named.Declaration
+
+let extract_prefix env info =
+ let ctx1 = List.rev (Environ.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 ->
+ if d1 == d2 then share l1 l2 (d1 :: accu)
+ else (accu, d2 :: l2)
+ | _ -> (accu, l2)
+ in
+ share ctx1 ctx2 []
+
+let typecheck_evar ev env sigma =
+ let info = Evd.find sigma ev in
+ (** Typecheck the hypotheses. *)
+ let type_hyp (sigma, env) decl =
+ let t = get_type decl in
+ let evdref = ref sigma in
+ let _ = Typing.e_sort_of env evdref t in
+ let () = match decl with
+ | LocalAssum _ -> ()
+ | LocalDef (_,body,_) -> Typing.e_check env evdref body t
+ in
+ (!evdref, Environ.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 (sigma, env) = List.fold_left type_hyp (sigma, env) changed in
+ (** Typecheck the conclusion *)
+ let evdref = ref sigma in
+ let _ = Typing.e_sort_of env evdref (Evd.evar_concl info) in
+ !evdref
+
+let typecheck_proof c concl env sigma =
+ let evdref = ref sigma in
+ let () = Typing.e_check env evdref c concl in
+ !evdref
+
+let (pr_constrv,pr_constr) =
+ Hook.make ~default:(fun _env _sigma _c -> Pp.str"<constr>") ()
+
+let refine ?(unsafe = true) f = Proofview.Goal.enter { enter = begin fun gl ->
+ let gl = Proofview.Goal.assume gl in
+ let sigma = Proofview.Goal.sigma gl in
+ let sigma = Sigma.to_evar_map sigma in
+ let env = Proofview.Goal.env gl in
+ let concl = Proofview.Goal.concl gl in
+ (** Save the [future_goals] state to restore them after the
+ refinement. *)
+ let prev_future_goals = Evd.future_goals sigma in
+ let prev_principal_goal = Evd.principal_future_goal sigma in
+ (** Create the refinement term *)
+ let (c, sigma) = Sigma.run (Evd.reset_future_goals sigma) f in
+ let evs = Evd.future_goals sigma in
+ let evkmain = Evd.principal_future_goal sigma in
+ (** Check that the introduced evars are well-typed *)
+ let fold accu ev = typecheck_evar ev env accu in
+ let sigma = if unsafe then sigma else CList.fold_left fold sigma evs in
+ (** Check that the refined term is typesafe *)
+ let sigma = if unsafe then sigma else typecheck_proof c concl env sigma in
+ (** Check that the goal itself does not appear in the refined term *)
+ let self = Proofview.Goal.goal gl in
+ let _ =
+ if not (Evarutil.occur_evar_upto sigma self c) then ()
+ else Pretype_errors.error_occur_check env sigma self c
+ in
+ (** Proceed to the refinement *)
+ let sigma = match evkmain with
+ | None -> Evd.define self c sigma
+ | Some evk ->
+ let id = Evd.evar_ident self sigma in
+ let sigma = Evd.define self c sigma in
+ match id with
+ | None -> sigma
+ | Some id -> Evd.rename evk id sigma
+ in
+ (** Restore the [future goals] state. *)
+ let sigma = Evd.restore_future_goals sigma prev_future_goals prev_principal_goal in
+ (** Select the goals *)
+ let comb = CList.map_filter (Proofview.Unsafe.advance sigma) (CList.rev evs) in
+ let sigma = CList.fold_left Proofview.Unsafe.mark_as_goal sigma comb in
+ let trace () = Pp.(hov 2 (str"refine"++spc()++ Hook.get pr_constrv env sigma c)) in
+ Proofview.Trace.name_tactic trace (Proofview.tclUNIT ()) >>= fun () ->
+ Proofview.Unsafe.tclEVARS sigma >>= fun () ->
+ Proofview.Unsafe.tclSETGOALS comb
+end }
+
+(** Useful definitions *)
+
+let with_type env evd c t =
+ let my_type = Retyping.get_type_of env evd c in
+ let j = Environ.make_judge c my_type in
+ let (evd,j') =
+ Coercion.inh_conv_coerce_to true (Loc.ghost) env evd j t
+ in
+ evd , j'.Environ.uj_val
+
+let refine_casted ?unsafe f = Proofview.Goal.enter { enter = begin fun gl ->
+ let gl = Proofview.Goal.assume gl in
+ let concl = Proofview.Goal.concl gl in
+ let env = Proofview.Goal.env gl in
+ let f = { run = fun h ->
+ let Sigma (c, h, p) = f.run h in
+ let sigma, c = with_type env (Sigma.to_evar_map h) c concl in
+ Sigma (c, Sigma.Unsafe.of_evar_map sigma, p)
+ } in
+ refine ?unsafe f
+end }
diff --git a/proofs/refine.mli b/proofs/refine.mli
new file mode 100644
index 000000000..a9798b704
--- /dev/null
+++ b/proofs/refine.mli
@@ -0,0 +1,42 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** The primitive refine tactic used to fill the holes in partial proofs. This
+ is the recommanded way to write tactics when the proof term is easy to
+ write down. Note that this is not the user-level refine tactic defined
+ in Ltac which is actually based on the one below. *)
+
+open Proofview
+
+(** {6 The refine tactic} *)
+
+(** Printer used to print the constr which refine refines. *)
+val pr_constr :
+ (Environ.env -> Evd.evar_map -> Term.constr -> Pp.std_ppcmds) Hook.t
+
+(** {7 Refinement primitives} *)
+
+val refine : ?unsafe:bool -> Constr.t Sigma.run -> unit tactic
+(** In [refine ?unsafe t], [t] is a term with holes under some
+ [evar_map] context. The term [t] is used as a partial solution
+ for the current goal (refine is a goal-dependent tactic), the
+ new holes created by [t] become the new subgoals. Exceptions
+ raised during the interpretation of [t] are caught and result in
+ tactic failures. If [unsafe] is [false] (default is [true]) [t] is
+ type-checked beforehand. *)
+
+(** {7 Helper functions} *)
+
+val with_type : Environ.env -> Evd.evar_map ->
+ Term.constr -> Term.types -> Evd.evar_map * Term.constr
+(** [with_type env sigma c t] ensures that [c] is of type [t]
+ inserting a coercion if needed. *)
+
+val refine_casted : ?unsafe:bool -> Constr.t Sigma.run -> unit tactic
+(** Like {!refine} except the refined term is coerced to the conclusion of the
+ current goal. *)
diff --git a/proofs/refiner.ml b/proofs/refiner.ml
index 186525e15..23433692c 100644
--- a/proofs/refiner.ml
+++ b/proofs/refiner.ml
@@ -57,7 +57,7 @@ let tclIDTAC gls = goal_goal_list gls
(* the message printing identity tactic *)
let tclIDTAC_MESSAGE s gls =
- Pp.msg_info (hov 0 s); pp_flush (); tclIDTAC gls
+ Feedback.msg_info (hov 0 s); tclIDTAC gls
(* General failure tactic *)
let tclFAIL_s s gls = errorlabstrm "Refiner.tclFAIL_s" (str s)
@@ -218,7 +218,8 @@ let tclSHOWHYPS (tac : tactic) (goal: Goal.goal Evd.sigma)
(fun acc d -> (Names.Id.to_string (get_id d)) ^ " " ^ acc)
"" lh))
"" newhyps in
- pp (str (emacs_str "<infoH>")
+ Feedback.msg_notice
+ (str (emacs_str "<infoH>")
++ (hov 0 (str s))
++ (str (emacs_str "</infoH>")) ++ fnl());
tclIDTAC goal;;
diff --git a/proofs/refiner.mli b/proofs/refiner.mli
index dd9153a02..6dcafb77a 100644
--- a/proofs/refiner.mli
+++ b/proofs/refiner.mli
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** Legacy proof engine. Do not use in newly written code. *)
+
open Evd
open Proof_type
diff --git a/proofs/tacmach.ml b/proofs/tacmach.ml
index 33cef7486..8c0b4ba98 100644
--- a/proofs/tacmach.ml
+++ b/proofs/tacmach.ml
@@ -121,25 +121,14 @@ let internal_cut_rev_no_check replace id t gl =
let refine_no_check c gl =
refiner (Refine c) gl
-(* This does not check dependencies *)
-let thin_no_check ids gl =
- if List.is_empty ids then tclIDTAC gl else refiner (Thin ids) gl
-
let move_hyp_no_check id1 id2 gl =
refiner (Move (id1,id2)) gl
-let mutual_fix f n others j gl =
- with_check (refiner (FixRule (f,n,others,j))) gl
-
-let mutual_cofix f others j gl =
- with_check (refiner (Cofix (f,others,j))) gl
-
(* Versions with consistency checks *)
let internal_cut b d t = with_check (internal_cut_no_check b d t)
let internal_cut_rev b d t = with_check (internal_cut_rev_no_check b d t)
let refine c = with_check (refine_no_check c)
-let thin c = with_check (thin_no_check c)
let move_hyp id id' = with_check (move_hyp_no_check id id')
(* Pretty-printers *)
diff --git a/proofs/tacmach.mli b/proofs/tacmach.mli
index f786b5f21..182433cb3 100644
--- a/proofs/tacmach.mli
+++ b/proofs/tacmach.mli
@@ -86,17 +86,12 @@ val pf_is_matching : goal sigma -> constr_pattern -> constr -> bool
val refiner : rule -> tactic
val internal_cut_no_check : bool -> Id.t -> types -> tactic
val refine_no_check : constr -> tactic
-val thin_no_check : Id.t list -> tactic
-val mutual_fix :
- Id.t -> int -> (Id.t * int * constr) list -> int -> tactic
-val mutual_cofix : Id.t -> (Id.t * constr) list -> int -> tactic
(** {6 The most primitive tactics with consistency and type checking } *)
val internal_cut : bool -> Id.t -> types -> tactic
val internal_cut_rev : bool -> Id.t -> types -> tactic
val refine : constr -> tactic
-val thin : Id.t list -> tactic
val move_hyp : Id.t -> Id.t move_location -> tactic
(** {6 Pretty-printing functions (debug only). } *)
diff --git a/stm/asyncTaskQueue.ml b/stm/asyncTaskQueue.ml
index bb312e3b1..a7b381ad6 100644
--- a/stm/asyncTaskQueue.ml
+++ b/stm/asyncTaskQueue.ml
@@ -104,7 +104,8 @@ module Make(T : Task) = struct
marshal_err ("unmarshal_more_data: "^s)
let report_status ?(id = !Flags.async_proofs_worker_id) s =
- Pp.feedback ~state_id:Stateid.initial (Feedback.WorkerStatus(id, s))
+ let open Feedback in
+ feedback ~id:(State Stateid.initial) (WorkerStatus(id, s))
module Worker = Spawn.Sync(struct end)
@@ -123,7 +124,7 @@ module Make(T : Task) = struct
"-async-proofs-worker-priority";
Flags.string_of_priority !Flags.async_proofs_worker_priority]
| ("-ideslave"|"-emacs"|"-emacs-U"|"-batch")::tl -> set_slave_opt tl
- | ("-async-proofs" |"-toploop" |"-vi2vo"
+ | ("-async-proofs" |"-toploop" |"-vio2vo"
|"-load-vernac-source" |"-l" |"-load-vernac-source-verbose" |"-lv"
|"-compile" |"-compile-verbose"
|"-async-proofs-worker-priority" |"-worker-id") :: _ :: tl ->
@@ -182,6 +183,13 @@ module Make(T : Task) = struct
let () = Unix.sleep 1 in
kill_if ()
in
+ let kill_if () =
+ try kill_if ()
+ with Sys.Break ->
+ let () = stop_waiting := true in
+ let () = TQueue.broadcast queue in
+ Worker.kill proc
+ in
let _ = Thread.create kill_if () in
try while true do
@@ -295,8 +303,8 @@ module Make(T : Task) = struct
let main_loop () =
let slave_feeder oc fb =
Marshal.to_channel oc (RespFeedback fb) []; flush oc in
- Pp.set_feeder (fun x -> slave_feeder (Option.get !slave_oc) x);
- Pp.log_via_feedback (fun msg -> Richpp.repr (Richpp.richpp_of_pp msg));
+ Feedback.set_feeder (fun x -> slave_feeder (Option.get !slave_oc) x);
+ Feedback.set_logger Feedback.feedback_logger;
Universes.set_remote_new_univ_level (bufferize (fun () ->
marshal_response (Option.get !slave_oc) RespGetCounterNewUnivLevel;
match unmarshal_more_data (Option.get !slave_ic) with
@@ -312,7 +320,7 @@ module Make(T : Task) = struct
let response = slave_respond request in
report_status "Idle";
marshal_response (Option.get !slave_oc) response;
- Ephemeron.clear ()
+ CEphemeron.clear ()
with
| MarshalError s ->
pr_err ("Fatal marshal error: " ^ s); flush_all (); exit 2
diff --git a/stm/dag.ml b/stm/dag.ml
index 0c7f9f34b..99e7c9264 100644
--- a/stm/dag.ml
+++ b/stm/dag.ml
@@ -8,15 +8,6 @@
module type S = sig
- module Cluster :
- sig
- type 'd t
- val equal : 'd t -> 'd t -> bool
- val compare : 'd t -> 'd t -> int
- val to_string : 'd t -> string
- val data : 'd t -> 'd
- end
-
type node
module NodeSet : Set.S with type elt = node
@@ -31,45 +22,57 @@ module type S = sig
val del_nodes : ('e,'i,'d) t -> NodeSet.t -> ('e,'i,'d) t
val all_nodes : ('e,'i,'d) t -> NodeSet.t
- val iter : ('e,'i,'d) t ->
- (node -> 'd Cluster.t option -> 'i option ->
- (node * 'e) list -> unit) -> unit
-
- val create_cluster : ('e,'i,'d) t -> node list -> 'd -> ('e,'i,'d) t
- val cluster_of : ('e,'i,'d) t -> node -> 'd Cluster.t option
- val del_cluster : ('e,'i,'d) t -> 'd Cluster.t -> ('e,'i,'d) t
-
val get_info : ('e,'i,'d) t -> node -> 'i option
val set_info : ('e,'i,'d) t -> node -> 'i -> ('e,'i,'d) t
val clear_info : ('e,'i,'d) t -> node -> ('e,'i,'d) t
+ module Property :
+ sig
+ type 'd t
+ val equal : 'd t -> 'd t -> bool
+ val compare : 'd t -> 'd t -> int
+ val to_string : 'd t -> string
+ val data : 'd t -> 'd
+ val having_it : 'd t -> NodeSet.t
+ end
+
+ val create_property : ('e,'i,'d) t -> node list -> 'd -> ('e,'i,'d) t
+ val property_of : ('e,'i,'d) t -> node -> 'd Property.t list
+ val del_property : ('e,'i,'d) t -> 'd Property.t -> ('e,'i,'d) t
+
+ val iter : ('e,'i,'d) t ->
+ (node -> 'd Property.t list -> 'i option ->
+ (node * 'e) list -> unit) -> unit
+
end
module Make(OT : Map.OrderedType) = struct
-module Cluster =
+module NodeSet = Set.Make(OT)
+
+module Property =
struct
- type 'd t = 'd * int
- let equal (_,i1) (_,i2) = Int.equal i1 i2
- let compare (_,i1) (_,i2) = Int.compare i1 i2
- let to_string (_,i) = string_of_int i
- let data (d,_) = d
+ type 'd t = { data : 'd; uid : int; having_it : NodeSet.t }
+ let equal { uid = i1 } { uid = i2 } = Int.equal i1 i2
+ let compare { uid = i1 } { uid = i2 } = Int.compare i1 i2
+ let to_string { uid = i } = string_of_int i
+ let data { data = d } = d
+ let having_it { having_it } = having_it
end
type node = OT.t
module NodeMap = CMap.Make(OT)
-module NodeSet = Set.Make(OT)
type ('edge,'info,'data) t = {
graph : (node * 'edge) list NodeMap.t;
- clusters : 'data Cluster.t NodeMap.t;
+ properties : 'data Property.t list NodeMap.t;
infos : 'info NodeMap.t;
}
let empty = {
graph = NodeMap.empty;
- clusters = NodeMap.empty;
+ properties = NodeMap.empty;
infos = NodeMap.empty;
}
@@ -94,7 +97,7 @@ let del_edge dag id tgt = { dag with
let del_nodes dag s = {
infos = NodeMap.filter (fun n _ -> not(NodeSet.mem n s)) dag.infos;
- clusters = NodeMap.filter (fun n _ -> not(NodeSet.mem n s)) dag.clusters;
+ properties = NodeMap.filter (fun n _ -> not(NodeSet.mem n s)) dag.properties;
graph = NodeMap.filter (fun n l ->
let drop = NodeSet.mem n s in
if not drop then
@@ -102,20 +105,31 @@ let del_nodes dag s = {
not drop)
dag.graph }
+let map_add_list k v m =
+ try
+ let l = NodeMap.find k m in
+ NodeMap.add k (v::l) m
+ with Not_found -> NodeMap.add k [v] m
+
let clid = ref 1
-let create_cluster dag l data =
+let create_property dag l data =
incr clid;
- { dag with clusters =
- List.fold_right (fun x clusters ->
- NodeMap.add x (data, !clid) clusters) l dag.clusters }
-
-let cluster_of dag id =
- try Some (NodeMap.find id dag.clusters)
- with Not_found -> None
-
-let del_cluster dag c =
- { dag with clusters =
- NodeMap.filter (fun _ c' -> not (Cluster.equal c' c)) dag.clusters }
+ let having_it = List.fold_right NodeSet.add l NodeSet.empty in
+ let property = { Property.data; uid = !clid; having_it } in
+ { dag with properties =
+ List.fold_right (fun x ps -> map_add_list x property ps) l dag.properties }
+
+let property_of dag id =
+ try NodeMap.find id dag.properties
+ with Not_found -> []
+
+let del_property dag c =
+ { dag with properties =
+ NodeMap.filter (fun _ cl -> cl <> [])
+ (NodeMap.map (fun cl ->
+ List.filter (fun c' ->
+ not (Property.equal c' c)) cl)
+ dag.properties) }
let get_info dag id =
try Some (NodeMap.find id dag.infos)
@@ -126,7 +140,7 @@ let set_info dag id info = { dag with infos = NodeMap.add id info dag.infos }
let clear_info dag id = { dag with infos = NodeMap.remove id dag.infos }
let iter dag f =
- NodeMap.iter (fun k v -> f k (cluster_of dag k) (get_info dag k) v) dag.graph
+ NodeMap.iter (fun k v -> f k (property_of dag k) (get_info dag k) v) dag.graph
let all_nodes dag = NodeMap.domain dag.graph
diff --git a/stm/dag.mli b/stm/dag.mli
index 6b4442df0..e783cd8ee 100644
--- a/stm/dag.mli
+++ b/stm/dag.mli
@@ -7,19 +7,7 @@
(************************************************************************)
module type S = sig
-
- (* A cluster is just a set of nodes. This set holds some data.
- Stm uses this to group nodes contribution to the same proofs and
- that can be evaluated asynchronously *)
- module Cluster :
- sig
- type 'd t
- val equal : 'd t -> 'd t -> bool
- val compare : 'd t -> 'd t -> int
- val to_string : 'd t -> string
- val data : 'd t -> 'd
- end
-
+
type node
module NodeSet : Set.S with type elt = node
@@ -34,19 +22,35 @@ module type S = sig
val del_nodes : ('e,'i,'d) t -> NodeSet.t -> ('e,'i,'d) t
val all_nodes : ('e,'i,'d) t -> NodeSet.t
- val iter : ('e,'i,'d) t ->
- (node -> 'd Cluster.t option -> 'i option ->
- (node * 'e) list -> unit) -> unit
-
- val create_cluster : ('e,'i,'d) t -> node list -> 'd -> ('e,'i,'d) t
- val cluster_of : ('e,'i,'d) t -> node -> 'd Cluster.t option
- val del_cluster : ('e,'i,'d) t -> 'd Cluster.t -> ('e,'i,'d) t
-
val get_info : ('e,'i,'d) t -> node -> 'i option
val set_info : ('e,'i,'d) t -> node -> 'i -> ('e,'i,'d) t
val clear_info : ('e,'i,'d) t -> node -> ('e,'i,'d) t
-end
+ (* A property applies to a set of nodes and holds some data.
+ Stm uses this feature to group nodes contributing to the same proofs and
+ to structure proofs in boxes limiting the scope of errors *)
+ module Property :
+ sig
+ type 'd t
+ val equal : 'd t -> 'd t -> bool
+ val compare : 'd t -> 'd t -> int
+ val to_string : 'd t -> string
+ val data : 'd t -> 'd
+ val having_it : 'd t -> NodeSet.t
+ end
+
+ val create_property : ('e,'i,'d) t -> node list -> 'd -> ('e,'i,'d) t
+ val property_of : ('e,'i,'d) t -> node -> 'd Property.t list
+ val del_property : ('e,'i,'d) t -> 'd Property.t -> ('e,'i,'d) t
+
+ val iter : ('e,'i,'d) t ->
+ (node -> 'd Property.t list -> 'i option ->
+ (node * 'e) list -> unit) -> unit
+
+ end
-module Make(OT : Map.OrderedType) : S with type node = OT.t
+module Make(OT : Map.OrderedType) : S
+with type node = OT.t
+and type NodeSet.t = Set.Make(OT).t
+and type NodeSet.elt = OT.t
diff --git a/stm/lemmas.ml b/stm/lemmas.ml
index ac54028eb..0a63a3a0f 100644
--- a/stm/lemmas.ml
+++ b/stm/lemmas.ml
@@ -150,7 +150,7 @@ let find_mutually_recursive_statements thms =
assert (List.is_empty rest);
(* One occ. of common coind ccls and no common inductive hyps *)
if not (List.is_empty common_same_indhyp) then
- if_verbose msg_info (str "Assuming mutual coinductive statements.");
+ if_verbose Feedback.msg_info (str "Assuming mutual coinductive statements.");
flush_all ();
indccl, true, []
| [], _::_ ->
@@ -158,7 +158,7 @@ let find_mutually_recursive_statements thms =
| ind :: _ ->
if List.distinct_f ind_ord (List.map pi1 ind)
then
- if_verbose msg_info
+ if_verbose Feedback.msg_info
(strbrk
("Coinductive statements do not follow the order of "^
"definition, assuming the proof to be by induction."));
@@ -306,7 +306,7 @@ let admit (id,k,e) pl hook () =
let () = match k with
| Global, _, _ -> ()
| Local, _, _ | Discharge, _, _ ->
- msg_warning (str "Let definition" ++ spc () ++ pr_id id ++ spc () ++
+ Feedback.msg_warning (str "Let definition" ++ spc () ++ pr_id id ++ spc () ++
str "declared as an axiom.")
in
let () = assumption_message id in
@@ -336,7 +336,7 @@ let universe_proof_terminator compute_guard hook =
make_terminator begin function
| Admitted (id,k,pe,(ctx,pl)) ->
admit (id,k,pe) pl (hook (Some ctx)) ();
- Pp.feedback Feedback.AddedAxiom
+ Feedback.feedback Feedback.AddedAxiom
| Proved (opaque,idopt,proof) ->
let is_opaque, export_seff, exports = match opaque with
| Vernacexpr.Transparent -> false, true, []
@@ -403,7 +403,7 @@ let start_proof_with_initialization kind ctx recguard thms snl hook =
| Anonymous -> Tactics.intro) (List.rev ids) in
let init_tac,guard = match recguard with
| Some (finite,guard,init_tac) ->
- let rec_tac = Proofview.V82.tactic (rec_tac_initializer finite guard thms snl) in
+ let rec_tac = rec_tac_initializer finite guard thms snl in
Some (match init_tac with
| None ->
if Flags.is_auto_intros () then
@@ -520,7 +520,5 @@ let save_proof ?proof = function
(* Miscellaneous *)
let get_current_context () =
- try Pfedit.get_current_goal_context ()
- with e when Logic.catchable_exception e ->
- let env = Global.env () in
- (Evd.from_env env, env)
+ Pfedit.get_current_context ()
+
diff --git a/stm/lemmas.mli b/stm/lemmas.mli
index 9120787d1..f751598f0 100644
--- a/stm/lemmas.mli
+++ b/stm/lemmas.mli
@@ -65,4 +65,3 @@ val save_proof : ?proof:Proof_global.closed_proof -> Vernacexpr.proof_end -> uni
and the current global env *)
val get_current_context : unit -> Evd.evar_map * Environ.env
-
diff --git a/stm/proofBlockDelimiter.ml b/stm/proofBlockDelimiter.ml
new file mode 100644
index 000000000..ce12185cb
--- /dev/null
+++ b/stm/proofBlockDelimiter.ml
@@ -0,0 +1,184 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Stm
+
+module Util : sig
+
+val simple_goal : Evd.evar_map -> Goal.goal -> Goal.goal list -> bool
+val is_focused_goal_simple : Stateid.t -> [ `Simple of Goal.goal list | `Not ]
+
+type 'a until = [ `Stop | `Found of static_block_declaration | `Cont of 'a ]
+
+val crawl :
+ document_view -> ?init:document_node option ->
+ ('a -> document_node -> 'a until) -> 'a ->
+ static_block_declaration option
+
+val unit_val : Stm.DynBlockData.t
+val of_bullet_val : Vernacexpr.bullet -> Stm.DynBlockData.t
+val to_bullet_val : Stm.DynBlockData.t -> Vernacexpr.bullet
+val of_vernac_expr_val : Vernacexpr.vernac_expr -> Stm.DynBlockData.t
+val to_vernac_expr_val : Stm.DynBlockData.t -> Vernacexpr.vernac_expr
+
+end = struct
+
+let unit_tag = DynBlockData.create "unit"
+let unit_val = DynBlockData.Easy.inj () unit_tag
+
+let of_bullet_val, to_bullet_val = DynBlockData.Easy.make_dyn "bullet"
+let of_vernac_expr_val, to_vernac_expr_val = DynBlockData.Easy.make_dyn "vernac_expr"
+
+let simple_goal sigma g gs =
+ let open Evar in
+ 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_filtered_evar_info (nf_evar_info sigma evi)) &&
+ not (List.exists (Proofview.depends_on sigma g) gs)
+
+let is_focused_goal_simple id =
+ match state_of_id id with
+ | `Expired | `Error _ | `Valid None -> `Not
+ | `Valid (Some { proof }) ->
+ let proof = Proof_global.proof_of_state proof in
+ let focused, r1, r2, r3, sigma = Proof.proof proof in
+ let rest = List.(flatten (map (fun (x,y) -> x @ y) r1)) @ r2 @ r3 in
+ if List.for_all (fun x -> simple_goal sigma x rest) focused
+ then `Simple focused
+ else `Not
+
+type 'a until = [ `Stop | `Found of static_block_declaration | `Cont of 'a ]
+
+let crawl { entry_point; prev_node } ?(init=Some entry_point) f acc =
+ let rec crawl node acc =
+ match node with
+ | None -> None
+ | Some node ->
+ match f acc node with
+ | `Stop -> None
+ | `Found x -> Some x
+ | `Cont acc -> crawl (prev_node node) acc in
+ crawl init acc
+
+end
+
+include Util
+
+(* ****************** - foo - bar - baz *********************************** *)
+
+let static_bullet ({ entry_point; prev_node } as view) =
+ match entry_point.ast with
+ | Vernacexpr.VernacBullet b ->
+ let base = entry_point.indentation in
+ let last_tac = prev_node entry_point in
+ crawl view ~init:last_tac (fun prev node ->
+ if node.indentation < base then `Stop else
+ if node.indentation > base then `Cont node else
+ match node.ast with
+ | Vernacexpr.VernacBullet b' when b = b' ->
+ `Found { stop = entry_point.id; start = prev.id;
+ dynamic_switch = node.id; carry_on_data = of_bullet_val b }
+ | _ -> `Stop) entry_point
+ | _ -> assert false
+
+let dynamic_bullet { dynamic_switch = id; carry_on_data = b } =
+ match is_focused_goal_simple id with
+ | `Simple focused ->
+ `ValidBlock {
+ base_state = id;
+ goals_to_admit = focused;
+ recovery_command = Some (Vernacexpr.VernacBullet (to_bullet_val b))
+ }
+ | `Not -> `Leaks
+
+let () = register_proof_block_delimiter
+ "bullet" static_bullet dynamic_bullet
+
+(* ******************** { block } ***************************************** *)
+
+let static_curly_brace ({ entry_point; prev_node } as view) =
+ assert(entry_point.ast = Vernacexpr.VernacEndSubproof);
+ crawl view (fun (nesting,prev) node ->
+ match node.ast with
+ | Vernacexpr.VernacSubproof _ when nesting = 0 ->
+ `Found { stop = entry_point.id; start = prev.id;
+ dynamic_switch = node.id; carry_on_data = unit_val }
+ | Vernacexpr.VernacSubproof _ ->
+ `Cont (nesting - 1,node)
+ | Vernacexpr.VernacEndSubproof ->
+ `Cont (nesting + 1,node)
+ | _ -> `Cont (nesting,node)) (-1, entry_point)
+
+let dynamic_curly_brace { dynamic_switch = id } =
+ match is_focused_goal_simple id with
+ | `Simple focused ->
+ `ValidBlock {
+ base_state = id;
+ goals_to_admit = focused;
+ recovery_command = Some Vernacexpr.VernacEndSubproof
+ }
+ | `Not -> `Leaks
+
+let () = register_proof_block_delimiter
+ "curly" static_curly_brace dynamic_curly_brace
+
+(* ***************** par: ************************************************* *)
+
+let static_par { entry_point; prev_node } =
+ match prev_node entry_point with
+ | None -> None
+ | Some { id = pid } ->
+ Some { stop = entry_point.id; start = pid;
+ dynamic_switch = pid; carry_on_data = unit_val }
+
+let dynamic_par { dynamic_switch = id } =
+ match is_focused_goal_simple id with
+ | `Simple focused ->
+ `ValidBlock {
+ base_state = id;
+ goals_to_admit = focused;
+ recovery_command = None;
+ }
+ | `Not -> `Leaks
+
+let () = register_proof_block_delimiter "par" static_par dynamic_par
+
+(* ***************** simple indentation *********************************** *)
+
+let static_indent ({ entry_point; prev_node } as view) =
+ Printf.eprintf "@%d\n" (Stateid.to_int entry_point.id);
+ match prev_node entry_point with
+ | None -> None
+ | Some last_tac ->
+ if last_tac.indentation <= entry_point.indentation then None
+ else
+ crawl view ~init:(Some last_tac) (fun prev node ->
+ if node.indentation >= last_tac.indentation then `Cont node
+ else
+ `Found { stop = entry_point.id; start = node.id;
+ dynamic_switch = node.id;
+ carry_on_data = of_vernac_expr_val entry_point.ast }
+ ) last_tac
+
+let dynamic_indent { dynamic_switch = id; carry_on_data = e } =
+ Printf.eprintf "%s\n" (Stateid.to_string id);
+ match is_focused_goal_simple id with
+ | `Simple [] -> `Leaks
+ | `Simple focused ->
+ let but_last = List.tl (List.rev focused) in
+ `ValidBlock {
+ base_state = id;
+ goals_to_admit = but_last;
+ recovery_command = Some (to_vernac_expr_val e);
+ }
+ | `Not -> `Leaks
+
+let () = register_proof_block_delimiter "indent" static_indent dynamic_indent
+
diff --git a/stm/proofBlockDelimiter.mli b/stm/proofBlockDelimiter.mli
new file mode 100644
index 000000000..a55032a47
--- /dev/null
+++ b/stm/proofBlockDelimiter.mli
@@ -0,0 +1,41 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(* This file implements proof block detection for:
+ - blocks delimited by { and }
+ - bullets with indentation
+ - par: terminator
+
+ It exports utility functions to ease the development of other proof block
+ detection code.
+*)
+
+(** A goal is simple if it nor depends on nor impacts on any other goal.
+ This function is used to detect, dynamically, if a proof block leaks,
+ i.e. if skipping it could impact other goals (like not instantiating their
+ type). `Simple carries the list of focused goals.
+*)
+val simple_goal : Evd.evar_map -> Goal.goal -> Goal.goal list -> bool
+val is_focused_goal_simple : Stateid.t -> [ `Simple of Goal.goal list | `Not ]
+
+type 'a until = [ `Stop | `Found of Stm.static_block_declaration | `Cont of 'a ]
+
+(* Simpler function to crawl the document backward to detect the block.
+ * ?init is the entry point of the document view if not given *)
+val crawl :
+ Stm.document_view -> ?init:Stm.document_node option ->
+ ('a -> Stm.document_node -> 'a until) -> 'a ->
+ Stm.static_block_declaration option
+
+(* Dummy value for static_block_declaration when no real value is needed *)
+val unit_val : Stm.DynBlockData.t
+
+(* Bullets *)
+val of_bullet_val : Vernacexpr.bullet -> Stm.DynBlockData.t
+val to_bullet_val : Stm.DynBlockData.t -> Vernacexpr.bullet
+
diff --git a/stm/spawned.ml b/stm/spawned.ml
index c6df87267..2eae6f5e2 100644
--- a/stm/spawned.ml
+++ b/stm/spawned.ml
@@ -13,19 +13,6 @@ let prerr_endline s = if !Flags.debug then begin pr_err s end else ()
type chandescr = AnonPipe | Socket of string * int * int
-let handshake cin cout =
- try
- match input_value cin with
- | Hello(v, pid) when v = proto_version ->
- prerr_endline (Printf.sprintf "Handshake with %d OK" pid);
- output_value cout (Hello (proto_version,Unix.getpid ())); flush cout
- | _ -> raise (Failure "handshake protocol")
- with
- | Failure s | Invalid_argument s | Sys_error s ->
- pr_err ("Handshake failed: " ^ s); raise (Failure "handshake")
- | End_of_file ->
- pr_err "Handshake failed: End_of_file"; raise (Failure "handshake")
-
let open_bin_connection h pr pw =
let open Unix in
let _, cout = open_connection (ADDR_INET (inet_addr_of_string h,pr)) in
diff --git a/stm/stm.ml b/stm/stm.ml
index 07262ef68..c0813827d 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -8,8 +8,8 @@
let pr_err s = Printf.eprintf "%s] %s\n" (System.process_id ()) s; flush stderr
-let prerr_endline s = if false then begin pr_err s end else ()
-let prerr_debug s = if !Flags.debug then begin pr_err s end else ()
+let prerr_endline s = if false then begin pr_err (s ()) end else ()
+let prerr_debug s = if !Flags.debug then begin pr_err (s ()) end else ()
open Vernacexpr
open Errors
@@ -18,6 +18,7 @@ open Names
open Util
open Ppvernac
open Vernac_classifier
+open Feedback
module Hooks = struct
@@ -27,28 +28,23 @@ let with_fail, with_fail_hook = Hook.make ()
let state_computed, state_computed_hook = Hook.make
~default:(fun state_id ~in_cache ->
- feedback ~state_id Feedback.Processed) ()
+ feedback ~id:(State state_id) Processed) ()
let state_ready, state_ready_hook = Hook.make
~default:(fun state_id -> ()) ()
let forward_feedback, forward_feedback_hook = Hook.make
~default:(function
- | { Feedback.id = Feedback.Edit edit_id; route; contents } ->
- feedback ~edit_id ~route contents
- | { Feedback.id = Feedback.State state_id; route; contents } ->
- feedback ~state_id ~route contents) ()
+ | { id = id; route; contents } ->
+ feedback ~id:id ~route contents) ()
let parse_error, parse_error_hook = Hook.make
- ~default:(function
- | Feedback.Edit edit_id -> fun loc msg ->
- feedback ~edit_id (Feedback.ErrorMsg (loc, string_of_ppcmds msg))
- | Feedback.State state_id -> fun loc msg ->
- feedback ~state_id (Feedback.ErrorMsg (loc, string_of_ppcmds msg))) ()
+ ~default:(fun id loc msg ->
+ feedback ~id (ErrorMsg (loc, Pp.string_of_ppcmds msg))) ()
let execution_error, execution_error_hook = Hook.make
~default:(fun state_id loc msg ->
- feedback ~state_id (Feedback.ErrorMsg (loc, string_of_ppcmds msg))) ()
+ feedback ~id:(State state_id) (ErrorMsg (loc, Pp.string_of_ppcmds msg))) ()
let unreachable_state, unreachable_state_hook = Hook.make
~default:(fun _ _ -> ()) ()
@@ -80,12 +76,20 @@ let interactive () =
let async_proofs_workers_extra_env = ref [||]
-type ast = { verbose : bool; loc : Loc.t; mutable expr : vernac_expr }
-let pr_ast { expr } = pr_vernac expr
+type aast = {
+ verbose : bool;
+ loc : Loc.t;
+ indentation : int;
+ strlen : int;
+ mutable expr : vernac_expr; (* mutable: Proof using hinted by aux file *)
+}
+let pr_ast { expr; indentation } = int indentation ++ str " " ++ pr_vernac expr
+
+let default_proof_mode () = Proof_global.get_default_proof_mode_name ()
(* Commands piercing opaque *)
let may_pierce_opaque = function
- | { expr = VernacPrint (PrintName _) } -> true
+ | { expr = VernacPrint _ } -> true
| { expr = VernacExtend (("Extraction",_), _) } -> true
| { expr = VernacExtend (("SeparateExtraction",_), _) } -> true
| { expr = VernacExtend (("ExtractionLibrary",_), _) } -> true
@@ -101,14 +105,14 @@ let vernac_interp ?proof id ?route { verbose; loc; expr } =
| VernacResetName _ | VernacResetInitial | VernacBack _
| VernacBackTo _ | VernacRestart | VernacUndo _ | VernacUndoTo _
| VernacBacktrack _ | VernacAbortAll | VernacAbort _ -> true
- | VernacTime (_,e) | VernacRedirect (_,(_,e)) -> internal_command e
+ | VernacTime (_,e) | VernacTimeout (_,e) | VernacRedirect (_,(_,e)) -> internal_command e
| _ -> false in
if internal_command expr then begin
- prerr_endline ("ignoring " ^ string_of_ppcmds(pr_vernac expr))
+ prerr_endline (fun () -> "ignoring " ^ Pp.string_of_ppcmds(pr_vernac expr))
end else begin
- set_id_for_feedback ?route (Feedback.State id);
+ set_id_for_feedback ?route (State id);
Aux_file.record_in_aux_set_at loc;
- prerr_endline ("interpreting " ^ string_of_ppcmds(pr_vernac expr));
+ prerr_endline (fun () -> "interpreting " ^ Pp.string_of_ppcmds(pr_vernac expr));
try Hooks.(call interp ?verbosely:(Some verbose) ?proof (loc, expr))
with e ->
let e = Errors.push e in
@@ -116,17 +120,31 @@ let vernac_interp ?proof id ?route { verbose; loc; expr } =
end
(* Wrapper for Vernac.parse_sentence to set the feedback id *)
-let vernac_parse ?newtip ?route eid s =
+let indentation_of_string s =
+ let len = String.length s in
+ let rec aux n i precise =
+ if i >= len then 0, precise, len
+ else
+ match s.[i] with
+ | ' ' | '\t' -> aux (succ n) (succ i) precise
+ | '\n' | '\r' -> aux 0 (succ i) true
+ | _ -> n, precise, len in
+ aux 0 0 false
+
+let vernac_parse ?(indlen_prev=fun() -> 0) ?newtip ?route eid s =
let feedback_id =
- if Option.is_empty newtip then Feedback.Edit eid
- else Feedback.State (Option.get newtip) in
+ if Option.is_empty newtip then Edit eid
+ else State (Option.get newtip) in
+ let indentation, precise, strlen = indentation_of_string s in
+ let indentation =
+ if precise then indentation else indlen_prev () + indentation in
set_id_for_feedback ?route feedback_id;
let pa = Pcoq.Gram.parsable (Stream.of_string s) in
Flags.with_option Flags.we_are_parsing (fun () ->
try
match Pcoq.Gram.entry_parse Pcoq.main_entry pa with
| None -> raise (Invalid_argument "vernac_parse")
- | Some ast -> ast
+ | Some (loc, ast) -> indentation, strlen, loc, ast
with e when Errors.noncritical e ->
let (e, info) = Errors.push e in
let loc = Option.default Loc.ghost (Loc.get_loc info) in
@@ -136,13 +154,13 @@ let vernac_parse ?newtip ?route eid s =
let pr_open_cur_subgoals () =
try Printer.pr_open_subgoals ()
- with Proof_global.NoCurrentProof -> str""
+ with Proof_global.NoCurrentProof -> Pp.str ""
let update_global_env () =
if Proof_global.there_are_pending_proofs () then
Proof_global.update_global_env ()
-module Vcs_ = Vcs.Make(Stateid)
+module Vcs_ = Vcs.Make(Stateid.Self)
type future_proof = Proof_global.closed_proof_output Future.computation
type proof_mode = string
type depth = int
@@ -152,22 +170,27 @@ type branch_type =
| `Proof of proof_mode * depth
| `Edit of
proof_mode * Stateid.t * Stateid.t * vernac_qed_type * Vcs_.Branch.t ]
+(* TODO 8.7 : split commands and tactics, since this type is too messy now *)
type cmd_t = {
- ctac : bool; (* is a tactic, needed by the 8.4 semantics of Undo *)
- ceff : bool; (* is a side-effecting command *)
- cast : ast;
+ ctac : bool; (* is a tactic *)
+ ceff : bool; (* is a side-effecting command in the middle of a proof *)
+ cast : aast;
cids : Id.t list;
- cqueue : [ `MainQueue | `TacQueue of cancel_switch | `QueryQueue of cancel_switch | `SkipQueue ] }
-type fork_t = ast * Vcs_.Branch.t * Vernacexpr.opacity_guarantee * Id.t list
+ cblock : proof_block_name option;
+ cqueue : [ `MainQueue
+ | `TacQueue of cancel_switch
+ | `QueryQueue of cancel_switch
+ | `SkipQueue ] }
+type fork_t = aast * Vcs_.Branch.t * Vernacexpr.opacity_guarantee * Id.t list
type qed_t = {
- qast : ast;
+ qast : aast;
keep : vernac_qed_type;
mutable fproof : (future_proof * cancel_switch) option;
brname : Vcs_.Branch.t;
brinfo : branch_type Vcs_.branch_info
}
-type seff_t = ast option
-type alias_t = Stateid.t * ast
+type seff_t = aast option
+type alias_t = Stateid.t * aast
type transaction =
| Cmd of cmd_t
| Fork of fork_t
@@ -179,40 +202,69 @@ type step =
[ `Cmd of cmd_t
| `Fork of fork_t * Stateid.t option
| `Qed of qed_t * Stateid.t
- | `Sideff of [ `Ast of ast * Stateid.t | `Id of Stateid.t ]
+ | `Sideff of [ `Ast of aast * Stateid.t | `Id of Stateid.t ]
| `Alias of alias_t ]
type visit = { step : step; next : Stateid.t }
+let mkTransTac cast cblock cqueue =
+ Cmd { ctac = true; cast; cblock; cqueue; cids = []; ceff = false }
+let mkTransCmd cast cids ceff cqueue =
+ Cmd { ctac = false; cast; cblock = None; cqueue; cids; ceff }
(* Parts of the system state that are morally part of the proof state *)
let summary_pstate = [ Evarutil.meta_counter_summary_name;
Evd.evar_counter_summary_name;
"program-tcc-table" ]
-type state = {
- system : States.state;
- proof : Proof_global.state;
- shallow : bool
+type cached_state =
+ | Empty
+ | Error of Exninfo.iexn
+ | Valid of state
+and state = { (* TODO: inline records in OCaml 4.03 *)
+ system : States.state; (* summary + libstack *)
+ proof : Proof_global.state; (* proof state *)
+ shallow : bool (* is the state trimmed down (libstack) *)
}
type branch = Vcs_.Branch.t * branch_type Vcs_.branch_info
type backup = { mine : branch; others : branch list }
-type 'vcs state_info = { (* Make private *)
- mutable n_reached : int;
- mutable n_goals : int;
- mutable state : state option;
+type 'vcs state_info = { (* TODO: Make this record private to VCS *)
+ mutable n_reached : int; (* debug cache: how many times was computed *)
+ mutable n_goals : int; (* open goals: indentation *)
+ mutable state : cached_state; (* state value *)
mutable vcs_backup : 'vcs option * backup option;
}
let default_info () =
- { n_reached = 0; n_goals = 0; state = None; vcs_backup = None,None }
+ { n_reached = 0; n_goals = 0; state = Empty; vcs_backup = None,None }
+
+module DynBlockData : Dyn.S = Dyn.Make(struct end)
+
+(* Clusters of nodes implemented as Dag properties. While Dag and Vcs impose
+ * no constraint on properties, here we impose boxes to be non overlapping.
+ * Such invariant makes sense for the current kinds of boxes (proof blocks and
+ * entire proofs) but may make no sense and dropped/refined in the future.
+ * Such invariant is useful to detect broken proof block detection code *)
+type box =
+ | ProofTask of pt
+ | ProofBlock of static_block_declaration * proof_block_name
+and pt = { (* TODO: inline records in OCaml 4.03 *)
+ lemma : Stateid.t;
+ qed : Stateid.t;
+}
+and static_block_declaration = {
+ start : Stateid.t;
+ stop : Stateid.t;
+ dynamic_switch : Stateid.t;
+ carry_on_data : DynBlockData.t;
+}
(* Functions that work on a Vcs with a specific branch type *)
module Vcs_aux : sig
- val proof_nesting : (branch_type, 't,'i) Vcs_.t -> int
+ val proof_nesting : (branch_type, 't,'i,'c) Vcs_.t -> int
val find_proof_at_depth :
- (branch_type, 't, 'i) Vcs_.t -> int ->
+ (branch_type, 't, 'i,'c) Vcs_.t -> int ->
Vcs_.Branch.t * branch_type Vcs_.branch_info
exception Expired
- val visit : (branch_type, transaction,'i) Vcs_.t -> Vcs_.Dag.node -> visit
+ val visit : (branch_type, transaction,'i,'c) Vcs_.t -> Vcs_.Dag.node -> visit
end = struct (* {{{ *)
@@ -228,7 +280,7 @@ end = struct (* {{{ *)
let find_proof_at_depth vcs pl =
try List.find (function
| _, { Vcs_.kind = `Proof(m, n) } -> Int.equal n pl
- | _, { Vcs_.kind = `Edit _ } -> anomaly(str"find_proof_at_depth")
+ | _, { Vcs_.kind = `Edit _ } -> anomaly(Pp.str "find_proof_at_depth")
| _ -> false)
(List.map (fun h -> h, Vcs_.get_branch vcs h) (Vcs_.branches vcs))
with Not_found -> failwith "find_proof_at_depth"
@@ -236,9 +288,9 @@ end = struct (* {{{ *)
exception Expired
let visit vcs id =
if Stateid.equal id Stateid.initial then
- anomaly(str"Visiting the initial state id")
+ anomaly(Pp.str "Visiting the initial state id")
else if Stateid.equal id Stateid.dummy then
- anomaly(str"Visiting the dummy state id")
+ anomaly(Pp.str "Visiting the dummy state id")
else
try
match Vcs_.Dag.from_node (Vcs_.dag vcs) id with
@@ -254,7 +306,7 @@ end = struct (* {{{ *)
| [n, Sideff (Some x); p, Noop]
| [p, Noop; n, Sideff (Some x)]-> { step = `Sideff(`Ast (x,p)); next = n }
| [n, Sideff (Some x)]-> {step = `Sideff(`Ast (x,Stateid.dummy)); next=n}
- | _ -> anomaly (str ("Malformed VCS at node "^Stateid.to_string id))
+ | _ -> anomaly (Pp.str ("Malformed VCS at node "^Stateid.to_string id))
with Not_found -> raise Expired
end (* }}} *)
@@ -276,7 +328,7 @@ module VCS : sig
pos : id;
}
- type vcs = (branch_type, transaction, vcs state_info) Vcs_.t
+ type vcs = (branch_type, transaction, vcs state_info, box) Vcs_.t
val init : id -> unit
@@ -290,30 +342,32 @@ module VCS : sig
val rewrite_merge : id -> ours:transaction -> at:id -> Branch.t -> unit
val delete_branch : Branch.t -> unit
val commit : id -> transaction -> unit
- val mk_branch_name : ast -> Branch.t
+ val mk_branch_name : aast -> Branch.t
val edit_branch : Branch.t
val branch : ?root:id -> ?pos:id -> Branch.t -> branch_type -> unit
val reset_branch : Branch.t -> id -> unit
- val reachable : id -> Vcs_.NodeSet.t
+ val reachable : id -> Stateid.Set.t
val cur_tip : unit -> id
val get_info : id -> vcs state_info
- val reached : id -> bool -> unit
+ val reached : id -> unit
val goals : id -> int -> unit
- val set_state : id -> state -> unit
- val get_state : id -> state option
+ val set_state : id -> cached_state -> unit
+ val get_state : id -> cached_state
(* cuts from start -> stop, raising Expired if some nodes are not there *)
val slice : start:id -> stop:id -> vcs
val nodes_in_slice : start:id -> stop:id -> Stateid.t list
- val create_cluster : id list -> qed:id -> start:id -> unit
- val cluster_of : id -> (id * id) option
- val delete_cluster_of : id -> unit
+ val create_proof_task_box : id list -> qed:id -> start:id -> unit
+ val create_proof_block : static_block_declaration -> string -> unit
+ val box_of : id -> box list
+ val delete_boxes_of : id -> unit
+ val proof_task_box_of : id -> pt option
val proof_nesting : unit -> int
val checkout_shallowest_proof_branch : unit -> unit
- val propagate_sideff : ast option -> unit
+ val propagate_sideff : replay:aast option -> unit
val gc : unit -> unit
@@ -329,7 +383,6 @@ end = struct (* {{{ *)
include Vcs_
exception Expired = Vcs_aux.Expired
- module StateidSet = Set.Make(Stateid)
open Printf
let print_dag vcs () =
@@ -337,21 +390,21 @@ end = struct (* {{{ *)
"stm_" ^ Str.global_replace (Str.regexp " ") "_" (System.process_id ()) in
let string_of_transaction = function
| Cmd { cast = t } | Fork (t, _,_,_) ->
- (try string_of_ppcmds (pr_ast t) with _ -> "ERR")
+ (try Pp.string_of_ppcmds (pr_ast t) with _ -> "ERR")
| Sideff (Some t) ->
sprintf "Sideff(%s)"
- (try string_of_ppcmds (pr_ast t) with _ -> "ERR")
+ (try Pp.string_of_ppcmds (pr_ast t) with _ -> "ERR")
| Sideff None -> "EnvChange"
| Noop -> " "
| Alias (id,_) -> sprintf "Alias(%s)" (Stateid.to_string id)
| Qed { qast } -> string_of_ppcmds (pr_ast qast) in
let is_green id =
match get_info vcs id with
- | Some { state = Some _ } -> true
+ | Some { state = Valid _ } -> true
| _ -> false in
let is_red id =
match get_info vcs id with
- | Some s -> Int.equal s.n_reached ~-1
+ | Some { state = Error _ } -> true
| _ -> false in
let head = current_branch vcs in
let heads =
@@ -371,8 +424,6 @@ end = struct (* {{{ *)
let edge tr =
sprintf "<<FONT POINT-SIZE=\"12\" FACE=\"sans\">%s</FONT>>"
(quote (string_of_transaction tr)) in
- let ids = ref StateidSet.empty in
- let clus = Hashtbl.create 13 in
let node_info id =
match get_info vcs id with
| None -> ""
@@ -385,39 +436,71 @@ end = struct (* {{{ *)
let nodefmt oc id =
fprintf oc "%s [label=%s,style=filled,fillcolor=%s];\n"
(node id) (node_info id) (color id) in
- let add_to_clus_or_ids from cf =
- match cf with
- | None -> ids := StateidSet.add from !ids; false
- | Some c -> Hashtbl.replace clus c
- (try let n = Hashtbl.find clus c in from::n
- with Not_found -> [from]); true in
+
+ let ids = ref Stateid.Set.empty in
+ let boxes = ref [] in
+ (* Fill in *)
+ Dag.iter graph (fun from _ _ l ->
+ ids := Stateid.Set.add from !ids;
+ List.iter (fun box -> boxes := box :: !boxes)
+ (Dag.property_of graph from);
+ List.iter (fun (dest, _) ->
+ ids := Stateid.Set.add dest !ids;
+ List.iter (fun box -> boxes := box :: !boxes)
+ (Dag.property_of graph dest))
+ l);
+ boxes := CList.sort_uniquize Dag.Property.compare !boxes;
+
let oc = open_out fname_dot in
output_string oc "digraph states {\n";
Dag.iter graph (fun from cf _ l ->
- let c1 = add_to_clus_or_ids from cf in
List.iter (fun (dest, trans) ->
- let c2 = add_to_clus_or_ids dest (Dag.cluster_of graph dest) in
- fprintf oc "%s -> %s [xlabel=%s,labelfloat=%b];\n"
- (node from) (node dest) (edge trans) (c1 && c2)) l
+ fprintf oc "%s -> %s [xlabel=%s,labelfloat=true];\n"
+ (node from) (node dest) (edge trans)) l
);
- StateidSet.iter (nodefmt oc) !ids;
- Hashtbl.iter (fun c nodes ->
- fprintf oc "subgraph cluster_%s {\n" (Dag.Cluster.to_string c);
- List.iter (nodefmt oc) nodes;
- fprintf oc "color=blue; }\n"
- ) clus;
+
+ let contains b1 b2 =
+ Stateid.Set.subset
+ (Dag.Property.having_it b2) (Dag.Property.having_it b1) in
+ let same_box = Dag.Property.equal in
+ let outerboxes boxes =
+ List.filter (fun b ->
+ not (List.exists (fun b1 ->
+ not (same_box b1 b) && contains b1 b) boxes)
+ ) boxes in
+ let rec rec_print b =
+ boxes := CList.remove same_box b !boxes;
+ let sub_boxes = List.filter (contains b) (outerboxes !boxes) in
+ fprintf oc "subgraph cluster_%s {\n" (Dag.Property.to_string b);
+ List.iter rec_print sub_boxes;
+ Stateid.Set.iter (fun id ->
+ if Stateid.Set.mem id !ids then begin
+ ids := Stateid.Set.remove id !ids;
+ nodefmt oc id
+ end)
+ (Dag.Property.having_it b);
+ match Dag.Property.data b with
+ | ProofBlock ({ dynamic_switch = id }, lbl) ->
+ fprintf oc "label=\"%s (test:%s)\";\n" lbl (Stateid.to_string id);
+ fprintf oc "color=red; }\n"
+ | ProofTask _ -> fprintf oc "color=blue; }\n"
+ in
+ List.iter rec_print (outerboxes !boxes);
+ Stateid.Set.iter (nodefmt oc) !ids;
+
List.iteri (fun i (b,id) ->
let shape = if Branch.equal head b then "box3d" else "box" in
fprintf oc "b%d -> %s;\n" i (node id);
fprintf oc "b%d [shape=%s,label=\"%s\"];\n" i shape
(Branch.to_string b);
) heads;
+
output_string oc "}\n";
close_out oc;
ignore(Sys.command
("dot -Tpdf -Gcharset=latin1 " ^ fname_dot ^ " -o" ^ fname_ps))
- type vcs = (branch_type, transaction, vcs state_info) t
+ type vcs = (branch_type, transaction, vcs state_info, box) t
let vcs : vcs ref = ref (empty Stateid.dummy)
let init id =
@@ -454,13 +537,12 @@ end = struct (* {{{ *)
| Some x -> x
| None -> raise Vcs_aux.Expired
let set_state id s =
- (get_info id).state <- Some s;
+ (get_info id).state <- s;
if Flags.async_proofs_is_master () then Hooks.(call state_ready id)
let get_state id = (get_info id).state
- let reached id b =
+ let reached id =
let info = get_info id in
- if b then info.n_reached <- info.n_reached + 1
- else info.n_reached <- -1
+ info.n_reached <- info.n_reached + 1
let goals id n = (get_info id).n_goals <- n
let cur_tip () = get_branch_pos (current_branch ())
@@ -478,14 +560,14 @@ end = struct (* {{{ *)
let branch, mode = match Vcs_aux.find_proof_at_depth !vcs pl with
| h, { Vcs_.kind = `Proof (m, _) } -> h, m | _ -> assert false in
checkout branch;
- prerr_endline ("mode:" ^ mode);
+ prerr_endline (fun () -> "mode:" ^ mode);
Proof_global.activate_proof_mode mode
with Failure _ ->
checkout Branch.master;
- Proof_global.disactivate_proof_mode "Classic"
+ Proof_global.disactivate_current_proof_mode ()
(* copies the transaction on every open branch *)
- let propagate_sideff t =
+ let propagate_sideff ~replay:t =
List.iter (fun b ->
checkout b;
let id = new_node () in
@@ -510,9 +592,19 @@ end = struct (* {{{ *)
let l = nodes_in_slice ~start ~stop in
let copy_info v id =
Vcs_.set_info v id
- { (get_info id) with state = None; vcs_backup = None,None } in
+ { (get_info id) with state = Empty; vcs_backup = None,None } in
let copy_info_w_state v id =
Vcs_.set_info v id { (get_info id) with vcs_backup = None,None } in
+ let copy_proof_blockes v =
+ let nodes = Vcs_.Dag.all_nodes (Vcs_.dag v) in
+ let props =
+ Stateid.Set.fold (fun n pl -> Vcs_.property_of !vcs n @ pl) nodes [] in
+ let props = CList.sort_uniquize Vcs_.Dag.Property.compare props in
+ List.fold_left (fun v p ->
+ Vcs_.create_property v
+ (Stateid.Set.elements (Vcs_.Dag.Property.having_it p))
+ (Vcs_.Dag.Property.data p)) v props
+ in
let v = Vcs_.empty start in
let v = copy_info v start in
let v = List.fold_right (fun (id,tr) v ->
@@ -520,28 +612,52 @@ end = struct (* {{{ *)
let v = copy_info v id in
v) l v in
(* Stm should have reached the beginning of proof *)
- assert (not (Option.is_empty (get_info start).state));
+ assert (match (get_info start).state with Valid _ -> true | _ -> false);
(* We put in the new dag the most recent state known to master *)
let rec fill id =
- if (get_info id).state = None then fill (Vcs_aux.visit v id).next
- else copy_info_w_state v id in
+ match (get_info id).state with
+ | Empty | Error _ -> fill (Vcs_aux.visit v id).next
+ | Valid _ -> copy_info_w_state v id in
let v = fill stop in
(* We put in the new dag the first state (since Qed shall run on it,
* see check_task_aux) *)
- copy_info_w_state v start
+ let v = copy_info_w_state v start in
+ copy_proof_blockes v
let nodes_in_slice ~start ~stop =
List.rev (List.map fst (nodes_in_slice ~start ~stop))
- let create_cluster l ~qed ~start = vcs := create_cluster !vcs l (qed,start)
- let cluster_of id = Option.map Dag.Cluster.data (cluster_of !vcs id)
- let delete_cluster_of id =
- Option.iter (fun x -> vcs := delete_cluster !vcs x) (Vcs_.cluster_of !vcs id)
+ let topo_invariant l =
+ let all = List.fold_right Stateid.Set.add l Stateid.Set.empty in
+ List.for_all
+ (fun x ->
+ let props = property_of !vcs x in
+ let sets = List.map Dag.Property.having_it props in
+ List.for_all (fun s -> Stateid.Set.(subset s all || subset all s)) sets)
+ l
+
+ let create_proof_task_box l ~qed ~start:lemma =
+ if not (topo_invariant l) then anomaly (str "overlapping boxes");
+ vcs := create_property !vcs l (ProofTask { qed; lemma })
+ let create_proof_block ({ start; stop} as decl) name =
+ let l = nodes_in_slice ~start ~stop in
+ if not (topo_invariant l) then anomaly (str "overlapping boxes");
+ vcs := create_property !vcs l (ProofBlock (decl, name))
+ let box_of id = List.map Dag.Property.data (property_of !vcs id)
+ let delete_boxes_of id =
+ List.iter (fun x -> vcs := delete_property !vcs x) (property_of !vcs id)
+ let proof_task_box_of id =
+ match
+ CList.map_filter (function ProofTask x -> Some x | _ -> None) (box_of id)
+ with
+ | [] -> None
+ | [x] -> Some x
+ | _ -> anomaly (str "node with more than 1 proof task box")
let gc () =
let old_vcs = !vcs in
let new_vcs, erased_nodes = gc old_vcs in
- Vcs_.NodeSet.iter (fun id ->
+ Stateid.Set.iter (fun id ->
match (Vcs_aux.visit old_vcs id).step with
| `Qed ({ fproof = Some (_, cancel_switch) }, _)
| `Cmd { cqueue = `TacQueue cancel_switch }
@@ -598,7 +714,10 @@ end = struct (* {{{ *)
end (* }}} *)
let state_of_id id =
- try `Valid (VCS.get_info id).state
+ try match (VCS.get_info id).state with
+ | Valid s -> `Valid (Some s)
+ | Error (e,_) -> `Error e
+ | Empty -> `Valid None
with VCS.Expired -> `Expired
@@ -618,6 +737,7 @@ module State : sig
val install_cached : Stateid.t -> unit
val is_cached : ?cache:Summary.marshallable -> Stateid.t -> bool
+ val is_cached_and_valid : ?cache:Summary.marshallable -> Stateid.t -> bool
val exn_on : Stateid.t -> ?valid:Stateid.t -> iexn -> iexn
@@ -663,51 +783,60 @@ end = struct (* {{{ *)
proof,
Summary.project_summary (States.summary_of_state system) summary_pstate
- let freeze marshallable id = VCS.set_state id (freeze_global_state marshallable)
+ let freeze marshallable id =
+ VCS.set_state id (Valid (freeze_global_state marshallable))
+ let freeze_invalid id iexn = VCS.set_state id (Error iexn)
- let is_cached ?(cache=`No) id =
+ let is_cached ?(cache=`No) id only_valid =
if Stateid.equal id !cur_id then
try match VCS.get_info id with
- | { state = None } when cache = `Yes -> freeze `No id; true
- | { state = None } when cache = `Shallow -> freeze `Shallow id; true
+ | { state = Empty } when cache = `Yes -> freeze `No id; true
+ | { state = Empty } when cache = `Shallow -> freeze `Shallow id; true
| _ -> true
with VCS.Expired -> false
else
try match VCS.get_info id with
- | { state = Some _ } -> true
- | _ -> false
+ | { state = Empty } -> false
+ | { state = Valid _ } -> true
+ | { state = Error _ } -> not only_valid
with VCS.Expired -> false
+ let is_cached_and_valid ?cache id = is_cached ?cache id true
+ let is_cached ?cache id = is_cached ?cache id false
+
let install_cached id =
- if Stateid.equal id !cur_id then () else (* optimization *)
- let s =
- match VCS.get_info id with
- | { state = Some s } -> s
- | _ -> anomaly (str "unfreezing a non existing state") in
- unfreeze_global_state s; cur_id := id
+ match VCS.get_info id with
+ | { state = Valid s } ->
+ if Stateid.equal id !cur_id then () (* optimization *)
+ else begin unfreeze_global_state s; cur_id := id end
+ | { state = Error ie } -> cur_id := id; Exninfo.iraise ie
+ | _ ->
+ (* coqc has a 1 slot cache and only for valid states *)
+ if interactive () = `No && Stateid.equal id !cur_id then ()
+ else anomaly (str "installing a non cached state")
let get_cached id =
try match VCS.get_info id with
- | { state = Some s } -> s
+ | { state = Valid s } -> s
| _ -> anomaly (str "not a cached state")
with VCS.Expired -> anomaly (str "not a cached state (expired)")
let assign id what =
- if VCS.get_state id <> None then () else
+ if VCS.get_state id <> Empty then () else
try match what with
| `Full s ->
let s =
try
let prev = (VCS.visit id).next in
- if is_cached prev
+ if is_cached_and_valid prev
then { s with proof =
Proof_global.copy_terminators
~src:(get_cached prev).proof ~tgt:s.proof }
else s
with VCS.Expired -> s in
- VCS.set_state id s
+ VCS.set_state id (Valid s)
| `Proof(ontop,(pstate,counters)) ->
- if is_cached ontop then
+ if is_cached_and_valid ontop then
let s = get_cached ontop in
let s = { s with proof =
Proof_global.copy_terminators ~src:s.proof ~tgt:pstate } in
@@ -716,7 +845,7 @@ end = struct (* {{{ *)
(Summary.surgery_summary
(States.summary_of_state s.system)
counters) } in
- VCS.set_state id s
+ VCS.set_state id (Valid s)
with VCS.Expired -> ()
let exn_on id ?valid (e, info) =
@@ -738,12 +867,12 @@ end = struct (* {{{ *)
let define ?safe_id ?(redefine=false) ?(cache=`No) ?(feedback_processed=true)
f id
=
- feedback ~state_id:id Feedback.(ProcessingIn !Flags.async_proofs_worker_id);
+ feedback ~id:(State id) (ProcessingIn !Flags.async_proofs_worker_id);
let str_id = Stateid.to_string id in
if is_cached id && not redefine then
anomaly (str"defining state "++str str_id++str" twice");
try
- prerr_endline("defining "^str_id^" (cache="^
+ prerr_endline (fun () -> "defining "^str_id^" (cache="^
if cache = `Yes then "Y)" else if cache = `Shallow then "S)" else "N)");
let good_id = match safe_id with None -> !cur_id | Some id -> id in
fix_exn_ref := exn_on id ~valid:good_id;
@@ -751,24 +880,26 @@ end = struct (* {{{ *)
fix_exn_ref := (fun x -> x);
if cache = `Yes then freeze `No id
else if cache = `Shallow then freeze `Shallow id;
- prerr_endline ("setting cur id to "^str_id);
+ prerr_endline (fun () -> "setting cur id to "^str_id);
cur_id := id;
if feedback_processed then
Hooks.(call state_computed id ~in_cache:false);
- VCS.reached id true;
+ VCS.reached id;
if Proof_global.there_are_pending_proofs () then
VCS.goals id (Proof_global.get_open_goals ())
with e ->
let (e, info) = Errors.push e in
let good_id = !cur_id in
- cur_id := Stateid.dummy;
- VCS.reached id false;
- Hooks.(call unreachable_state id (e, info));
- match Stateid.get info, safe_id with
- | None, None -> iraise (exn_on id ~valid:good_id (e, info))
- | None, Some good_id -> iraise (exn_on id ~valid:good_id (e, info))
- | Some _, None -> iraise (e, info)
- | Some (_,at), Some id -> iraise (e, Stateid.add info ~valid:id at)
+ VCS.reached id;
+ let ie =
+ match Stateid.get info, safe_id with
+ | None, None -> (exn_on id ~valid:good_id (e, info))
+ | None, Some good_id -> (exn_on id ~valid:good_id (e, info))
+ | 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);
+ Exninfo.iraise ie
end (* }}} *)
@@ -844,7 +975,7 @@ end = struct (* {{{ *)
let back_safe () =
let id =
fold_until (fun n (id,_,_,_,_) ->
- if n >= 0 && State.is_cached id then `Stop id else `Cont (succ n))
+ if n >= 0 && State.is_cached_and_valid id then `Stop id else `Cont (succ n))
0 (VCS.get_branch_pos (VCS.current_branch ())) in
backto id
@@ -943,6 +1074,75 @@ let _ = Errors.register_handler (function
| RemoteException ppcmd -> ppcmd
| _ -> raise Unhandled)
+(****************** proof structure for error recovery ************************)
+(******************************************************************************)
+
+type document_node = {
+ indentation : int;
+ ast : Vernacexpr.vernac_expr;
+ id : Stateid.t;
+}
+
+type document_view = {
+ entry_point : document_node;
+ prev_node : document_node -> document_node option;
+}
+
+type static_block_detection =
+ document_view -> static_block_declaration option
+
+type recovery_action = {
+ base_state : Stateid.t;
+ goals_to_admit : Goal.goal list;
+ recovery_command : Vernacexpr.vernac_expr option;
+}
+
+type dynamic_block_error_recovery =
+ static_block_declaration -> [ `ValidBlock of recovery_action | `Leaks ]
+
+let proof_block_delimiters = ref []
+
+let register_proof_block_delimiter name static dynamic =
+ if List.mem_assoc name !proof_block_delimiters then
+ Errors.errorlabstrm "STM" (str "Duplicate block delimiter " ++ str name);
+ proof_block_delimiters := (name, (static,dynamic)) :: !proof_block_delimiters
+
+let mk_doc_node id = function
+ | { step = `Cmd { ctac; cast = { indentation; expr }}; next } when ctac ->
+ Some { indentation; ast = expr; id }
+ | { step = `Sideff (`Ast ({ indentation; expr }, _)); next } ->
+ Some { indentation; ast = expr; id }
+ | _ -> None
+let prev_node { id } =
+ let id = (VCS.visit id).next in
+ mk_doc_node id (VCS.visit id)
+let cur_node id = mk_doc_node id (VCS.visit id)
+
+let is_block_name_enabled name =
+ match !Flags.async_proofs_tac_error_resilience with
+ | `None -> false
+ | `All -> true
+ | `Only l -> List.mem name l
+
+let detect_proof_block id name =
+ let name = match name with None -> "indent" | Some x -> x in
+ if is_block_name_enabled name &&
+ (if Flags.async_proofs_is_master () then
+ !Flags.async_proofs_mode != Flags.APoff else true)
+ then
+ match cur_node id with
+ | None -> ()
+ | Some entry_point -> try
+ let static, _ = List.assoc name !proof_block_delimiters in
+ begin match static { prev_node; entry_point } with
+ | None -> ()
+ | Some ({ start; stop } as decl) ->
+ VCS.create_proof_block decl name
+ end
+ with Not_found ->
+ Errors.errorlabstrm "STM"
+ (str "Unknown proof block delimiter " ++ str name)
+
(****************************** THE SCHEDULER *********************************)
(******************************************************************************)
@@ -1060,7 +1260,7 @@ end = struct (* {{{ *)
List.iter (fun (id,s) -> State.assign id s) l; `End
| `Fresh, BuildProof { t_assign; t_loc; t_name; t_states; t_drop },
RespBuiltProof (pl, time) ->
- feedback (Feedback.InProgress ~-1);
+ feedback (InProgress ~-1);
t_assign (`Val pl);
record_pb_time t_name t_loc time;
if !Flags.async_proofs_full || t_drop
@@ -1068,7 +1268,7 @@ end = struct (* {{{ *)
else `End
| `Fresh, BuildProof { t_assign; t_loc; t_name; t_states },
RespError { e_error_at; e_safe_id = valid; e_msg; e_safe_states } ->
- feedback (Feedback.InProgress ~-1);
+ feedback (InProgress ~-1);
let info = Stateid.add ~valid Exninfo.null e_error_at in
let e = (RemoteException e_msg, info) in
t_assign (`Exn e);
@@ -1084,7 +1284,7 @@ end = struct (* {{{ *)
let e = (RemoteException (strbrk s), info) in
t_assign (`Exn e);
Hooks.(call execution_error start Loc.ghost (strbrk s));
- feedback (Feedback.InProgress ~-1)
+ feedback (InProgress ~-1)
let build_proof_here ~drop_pt (id,valid) loc eop =
Future.create (State.exn_on id ~valid) (fun () ->
@@ -1095,7 +1295,7 @@ end = struct (* {{{ *)
Aux_file.record_in_aux_at loc "proof_build_time"
(Printf.sprintf "%.3f" (wall_clock2 -. wall_clock1));
let p = Proof_global.return_proof ~allow_partial:drop_pt () in
- if drop_pt then Pp.feedback ~state_id:id Feedback.Complete;
+ if drop_pt then feedback ~id:(State id) Complete;
p)
let perform_buildp { Stateid.exn_info; stop; document; loc } drop my_states =
@@ -1119,7 +1319,7 @@ end = struct (* {{{ *)
Lemmas.(standard_proof_terminator [] (mk_hook (fun _ _ -> ()))) in
vernac_interp stop
~proof:(pobject, terminator)
- { verbose = false; loc;
+ { verbose = false; loc; indentation = 0; strlen = 0;
expr = (VernacEndProof (Proved (Opaque None,None))) }) in
ignore(Future.join checked_proof);
end;
@@ -1133,16 +1333,17 @@ end = struct (* {{{ *)
| Some (safe, err) -> err, safe
| None -> Stateid.dummy, Stateid.dummy in
let e_msg = iprint (e, info) in
- prerr_endline "failed with the following exception:";
- prerr_endline (string_of_ppcmds e_msg);
- let e_safe_states = List.filter State.is_cached my_states in
+ prerr_endline (fun () -> "failed with the following exception:");
+ prerr_endline (fun () -> string_of_ppcmds e_msg);
+ let e_safe_states = List.filter State.is_cached_and_valid my_states in
RespError { e_error_at; e_safe_id; e_msg; e_safe_states }
let perform_states query =
if query = [] then [] else
- let is_tac = function
- | VernacSolve _ | VernacFocus _ | VernacUnfocus | VernacBullet _ -> true
- | _ -> false in
+ let is_tac e = match classify_vernac e with
+ | VtProofStep _, _ -> true
+ | _ -> false
+ in
let initial =
let rec aux id =
try match VCS.visit id with { next } -> aux next
@@ -1152,12 +1353,12 @@ end = struct (* {{{ *)
let prev =
try
let { next = prev; step } = VCS.visit id in
- if State.is_cached prev && List.mem prev seen
+ if State.is_cached_and_valid prev && List.mem prev seen
then Some (prev, State.get_cached prev, step)
else None
with VCS.Expired -> None in
let this =
- if State.is_cached id then Some (State.get_cached id) else None in
+ if State.is_cached_and_valid id then Some (State.get_cached id) else None in
match prev, this with
| _, None -> None
| Some (prev, o, `Cmd { cast = { expr }}), Some n
@@ -1187,7 +1388,7 @@ end = struct (* {{{ *)
"The system state could not be sent to the worker process. "^
"Falling back to local, lazy, evaluation."));
t_assign(`Comp(build_proof_here ~drop_pt t_exn_info t_loc t_stop));
- feedback (Feedback.InProgress ~-1)
+ feedback (InProgress ~-1)
end (* }}} *)
@@ -1259,7 +1460,7 @@ end = struct (* {{{ *)
* looking at the ones that happen to be present in the current env *)
Reach.known_state ~cache:`No start;
vernac_interp stop ~proof
- { verbose = false; loc;
+ { verbose = false; loc; indentation = 0; strlen = 0;
expr = (VernacEndProof (Proved (Opaque None,None))) };
`OK proof
end
@@ -1267,7 +1468,7 @@ end = struct (* {{{ *)
let (e, info) = Errors.push e in
(try match Stateid.get info with
| None ->
- pperrnl (
+ msg_error (
str"File " ++ str name ++ str ": proof of " ++ str r_name ++
spc () ++ iprint (e, info))
| Some (_, cur) ->
@@ -1277,12 +1478,12 @@ end = struct (* {{{ *)
| { step = `Qed ( { qast = { loc } }, _) }
| { step = `Sideff (`Ast ( { loc }, _)) } ->
let start, stop = Loc.unloc loc in
- pperrnl (
+ msg_error (
str"File " ++ str name ++ str ": proof of " ++ str r_name ++
str ": chars " ++ int start ++ str "-" ++ int stop ++
spc () ++ iprint (e, info))
| _ ->
- pperrnl (
+ msg_error (
str"File " ++ str name ++ str ": proof of " ++ str r_name ++
spc () ++ iprint (e, info))
with e ->
@@ -1342,7 +1543,6 @@ end = struct (* {{{ *)
let set_perspective idl =
ProofTask.set_perspective idl;
TaskQueue.broadcast (Option.get !queue);
- let open Stateid in
let open ProofTask in
let overlap s1 s2 =
List.exists (fun x -> CList.mem_f Stateid.equal x s2) s1 in
@@ -1376,7 +1576,7 @@ end = struct (* {{{ *)
else
let f, t_assign = Future.create_delegate ~name:pname (State.exn_on id ~valid) in
let t_uuid = Future.uuid f in
- feedback (Feedback.InProgress 1);
+ feedback (InProgress 1);
let task = ProofTask.(BuildProof {
t_exn_info; t_start = start; t_stop = stop; t_assign; t_drop = drop_pt;
t_loc = loc; t_uuid; t_name = pname;
@@ -1399,7 +1599,7 @@ end = struct (* {{{ *)
| Some (ReqBuildProof (r, b, _)) -> Some(r, b)
| _ -> None)
tasks in
- prerr_endline (Printf.sprintf "dumping %d tasks\n" (List.length reqs));
+ prerr_endline (fun () -> Printf.sprintf "dumping %d tasks\n" (List.length reqs));
reqs
let reset_task_queue () = TaskQueue.clear (Option.get !queue)
@@ -1413,7 +1613,7 @@ and TacTask : sig
t_state : Stateid.t;
t_state_fb : Stateid.t;
t_assign : output Future.assignement -> unit;
- t_ast : ast;
+ t_ast : int * aast;
t_goal : Goal.goal;
t_kill : unit -> unit;
t_name : string }
@@ -1430,7 +1630,7 @@ end = struct (* {{{ *)
t_state : Stateid.t;
t_state_fb : Stateid.t;
t_assign : output Future.assignement -> unit;
- t_ast : ast;
+ t_ast : int * aast;
t_goal : Goal.goal;
t_kill : unit -> unit;
t_name : string }
@@ -1439,7 +1639,7 @@ end = struct (* {{{ *)
r_state : Stateid.t;
r_state_fb : Stateid.t;
r_document : VCS.vcs option;
- r_ast : ast;
+ r_ast : int * aast;
r_goal : Goal.goal;
r_name : string }
@@ -1469,8 +1669,7 @@ end = struct (* {{{ *)
match resp with
| RespBuiltSubProof o -> t_assign (`Val o); `Stay ((),[])
| RespError msg ->
- let info = Stateid.add ~valid:t_state Exninfo.null t_state_fb in
- let e = (RemoteException msg, info) in
+ let e = (RemoteException msg, Exninfo.null) in
t_assign (`Exn e);
t_kill ();
`Stay ((),[])
@@ -1483,6 +1682,9 @@ end = struct (* {{{ *)
| Some { t_kill } -> t_kill ()
| _ -> ()
+ let command_focus = Proof.new_focus_kind ()
+ let focus_cond = Proof.no_cond command_focus
+
let perform { r_state = id; r_state_fb; r_document = vcs; r_ast; r_goal } =
Option.iter VCS.restore vcs;
try
@@ -1495,18 +1697,20 @@ end = struct (* {{{ *)
List.for_all (Context.Named.Declaration.for_all (Evarutil.is_ground_term sigma0))
Evd.(evar_context g))
then
- Errors.errorlabstrm "Stm" (strbrk("the par: goal selector supports ground "^
+ Errors.errorlabstrm "STM" (strbrk("the par: goal selector supports ground "^
"goals only"))
else begin
- vernac_interp r_state_fb r_ast;
+ let (i, ast) = r_ast in
+ Proof_global.simple_with_current_proof (fun _ p -> Proof.focus focus_cond () i p);
+ vernac_interp r_state_fb ast;
let _,_,_,_,sigma = Proof.proof (Proof_global.give_me_the_proof ()) in
match Evd.(evar_body (find sigma r_goal)) with
- | Evd.Evar_empty -> Errors.errorlabstrm "Stm" (str "no progress")
+ | Evd.Evar_empty -> Errors.errorlabstrm "STM" (str "no progress")
| Evd.Evar_defined t ->
let t = Evarutil.nf_evar sigma t in
if Evarutil.is_ground_term sigma t then
t, Evd.evar_universe_context sigma
- else Errors.errorlabstrm "Stm" (str"The solution is not ground")
+ else Errors.errorlabstrm "STM" (str"The solution is not ground")
end) ()
in
RespBuiltSubProof (t,uc)
@@ -1520,19 +1724,20 @@ end (* }}} *)
and Partac : sig
val vernac_interp :
- cancel_switch -> int -> Stateid.t -> Stateid.t -> ast -> unit
+ cancel_switch -> int -> Stateid.t -> Stateid.t -> aast -> unit
end = struct (* {{{ *)
module TaskQueue = AsyncTaskQueue.MakeQueue(TacTask)
- let vernac_interp cancel nworkers safe_id id { verbose; loc; expr = e } =
- let e, etac, time, fail =
+ let vernac_interp cancel nworkers safe_id id
+ { indentation; verbose; loc; expr = e; strlen }
+ =
+ let e, time, fail =
let rec find time fail = function
- | VernacSolve(_,_,re,b) -> re, b, time, fail
| VernacTime (_,e) | VernacRedirect (_,(_,e)) -> find true fail e
| VernacFail e -> find time true e
- | _ -> errorlabstrm "Stm" (str"unsupported") in find false false e in
+ | _ -> e, time, fail in find false false e in
Hooks.call Hooks.with_fail fail (fun () ->
(if time then System.with_time false else (fun x -> x)) (fun () ->
ignore(TaskQueue.with_n_workers nworkers (fun queue ->
@@ -1544,8 +1749,7 @@ end = struct (* {{{ *)
Future.create_delegate
~name:(Printf.sprintf "subgoal %d" i)
(State.exn_on id ~valid:safe_id) in
- let t_ast =
- { verbose;loc;expr = VernacSolve(SelectNth i,None,e,etac) } in
+ let t_ast = (i, { indentation; verbose; loc; expr = e; strlen }) in
let t_name = Goal.uid g in
TaskQueue.enqueue_task queue
({ t_state = safe_id; t_state_fb = id;
@@ -1564,7 +1768,7 @@ end = struct (* {{{ *)
with Not_found -> Errors.anomaly(str"Partac: wrong focus") in
if Future.is_over f then
let pt, uc = Future.join f in
- prerr_endline (string_of_ppcmds(hov 0 (
+ prerr_endline (fun () -> string_of_ppcmds(hov 0 (
str"g=" ++ str gid ++ spc () ++
str"t=" ++ (Printer.pr_constr pt) ++ spc () ++
str"uc=" ++ Evd.pr_evar_universe_context uc)));
@@ -1579,16 +1783,16 @@ end (* }}} *)
and QueryTask : sig
- type task = { t_where : Stateid.t; t_for : Stateid.t ; t_what : ast }
+ type task = { t_where : Stateid.t; t_for : Stateid.t ; t_what : aast }
include AsyncTaskQueue.Task with type task := task
end = struct (* {{{ *)
type task =
- { t_where : Stateid.t; t_for : Stateid.t ; t_what : ast }
+ { t_where : Stateid.t; t_for : Stateid.t ; t_what : aast }
type request =
- { r_where : Stateid.t ; r_for : Stateid.t ; r_what : ast; r_doc : VCS.vcs }
+ { r_where : Stateid.t ; r_for : Stateid.t ; r_what : aast; r_doc : VCS.vcs }
type response = unit
let name = ref "queryworker"
@@ -1620,11 +1824,11 @@ end = struct (* {{{ *)
Reach.known_state ~cache:`No r_where;
try
vernac_interp r_for { r_what with verbose = true };
- feedback ~state_id:r_for Feedback.Processed
+ feedback ~id:(State r_for) Processed
with e when Errors.noncritical e ->
let e = Errors.push e in
let msg = string_of_ppcmds (iprint e) in
- feedback ~state_id:r_for (Feedback.ErrorMsg (Loc.ghost, msg))
+ feedback ~id:(State r_for) (ErrorMsg (Loc.ghost, msg))
let name_of_task { t_what } = string_of_ppcmds (pr_ast t_what)
let name_of_request { r_what } = string_of_ppcmds (pr_ast r_what)
@@ -1634,7 +1838,7 @@ end (* }}} *)
and Query : sig
val init : unit -> unit
- val vernac_interp : cancel_switch -> Stateid.t -> Stateid.t -> ast -> unit
+ val vernac_interp : cancel_switch -> Stateid.t -> Stateid.t -> aast -> unit
end = struct (* {{{ *)
@@ -1671,12 +1875,12 @@ let async_policy () =
(!compilation_mode = BuildVio || !async_proofs_mode <> APoff)
let delegate name =
- let time = get_hint_bp_time name in
- time >= 1.0 || !Flags.compilation_mode = Flags.BuildVio
- || !Flags.async_proofs_full
+ get_hint_bp_time name >= !Flags.async_proofs_delegation_threshold
+ || !Flags.compilation_mode = Flags.BuildVio
+ || !Flags.async_proofs_full
let collect_proof keep cur hd brkind id =
- prerr_endline ("Collecting proof ending at "^Stateid.to_string id);
+ prerr_endline (fun () -> "Collecting proof ending at "^Stateid.to_string id);
let no_name = "" in
let name = function
| [] -> no_name
@@ -1723,7 +1927,7 @@ let collect_proof keep cur hd brkind id =
let name = name ids in
`ASync (parent last,proof_using_ast last,accn,name,delegate name)
| `Fork((_, hd', GuaranteesOpacity, ids), _) when
- has_proof_no_using last && not (State.is_cached (parent last)) &&
+ has_proof_no_using last && not (State.is_cached_and_valid (parent last)) &&
!Flags.compilation_mode = Flags.BuildVio ->
assert (VCS.Branch.equal hd hd'||VCS.Branch.equal hd VCS.edit_branch);
(try
@@ -1759,7 +1963,7 @@ let collect_proof keep cur hd brkind id =
let rc = collect (Some cur) [] id in
if is_empty rc then make_sync `AlreadyEvaluated rc
else if (keep == VtKeep || keep == VtKeepAsAxiom) &&
- (not(State.is_cached id) || !Flags.async_proofs_full)
+ (not(State.is_cached_and_valid id) || !Flags.async_proofs_full)
then check_policy rc
else make_sync `AlreadyEvaluated rc
@@ -1777,7 +1981,7 @@ let string_of_reason = function
| `NoPU_NoHint_NoES -> "no 'Proof using..', no .aux file, inside a section"
| `Unknown -> "unsupported case"
-let log_string s = prerr_debug ("STM: " ^ s)
+let log_string s = prerr_debug (fun () -> "STM: " ^ s)
let log_processing_async id name = log_string Printf.(sprintf
"%s: proof %s: asynch" (Stateid.to_string id) name
)
@@ -1789,6 +1993,71 @@ 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 error_absorbing_tactic id blockname exn =
+ (* We keep the static/dynamic part of block detection separate, since
+ the static part could be performed earlier. As of today there is
+ no advantage in doing so since no UI can exploit such piece of info *)
+ detect_proof_block id blockname;
+
+ let boxes = VCS.box_of id in
+ let valid_boxes = CList.map_filter (function
+ | ProofBlock ({ stop } as decl, name) when Stateid.equal stop id ->
+ Some (decl, name)
+ | _ -> None) boxes in
+ assert(List.length valid_boxes < 2);
+ if valid_boxes = [] then iraise exn
+ else
+ let decl, name = List.hd valid_boxes in
+ try
+ let _, dynamic_check = List.assoc name !proof_block_delimiters in
+ match dynamic_check decl with
+ | `Leaks -> iraise exn
+ | `ValidBlock { base_state; goals_to_admit; recovery_command } -> begin
+ let tac =
+ let open Proofview.Notations in
+ Proofview.Goal.nf_enter { enter = fun gl ->
+ if CList.mem_f Evar.equal
+ (Proofview.Goal.goal gl) goals_to_admit then
+ Proofview.give_up else Proofview.tclUNIT ()
+ } in
+ match (VCS.get_info base_state).state with
+ | Valid { proof } ->
+ Proof_global.unfreeze proof;
+ Proof_global.with_current_proof (fun _ p ->
+ feedback ~id:(State id) Feedback.AddedAxiom;
+ fst (Pfedit.solve Vernacexpr.SelectAll None tac p), ());
+ Option.iter (fun expr -> vernac_interp id {
+ verbose = true; loc = Loc.ghost; expr; indentation = 0;
+ strlen = 0 })
+ recovery_command
+ | _ -> assert false
+ end
+ with Not_found ->
+ Errors.errorlabstrm "STM"
+ (str "Unknown proof block delimiter " ++ str name)
+ in
+
+ (* Absorb tactic errors from f () *)
+ let resilient_tactic id blockname f =
+ if !Flags.async_proofs_tac_error_resilience = `None ||
+ (Flags.async_proofs_is_master () &&
+ !Flags.async_proofs_mode = Flags.APoff)
+ then f ()
+ else
+ try f ()
+ with e when Errors.noncritical e ->
+ let ie = Errors.push e in
+ error_absorbing_tactic id blockname ie in
+ (* Absorb errors from f x *)
+ let resilient_command f x =
+ if not !Flags.async_proofs_cmd_error_resilience ||
+ (Flags.async_proofs_is_master () &&
+ !Flags.async_proofs_mode = Flags.APoff)
+ then f x
+ else
+ try f x
+ with e when Errors.noncritical e -> () in
(* ugly functions to process nested lemmas, i.e. hard to reproduce
* side effects *)
@@ -1799,17 +2068,17 @@ let known_state ?(redefine_qed=false) ~cache id =
Summary.unfreeze_summary s; Lib.unfreeze l; update_global_env ()
in
let rec pure_cherry_pick_non_pstate id = Future.purify (fun id ->
- prerr_endline ("cherry-pick non pstate " ^ Stateid.to_string id);
+ prerr_endline (fun () -> "cherry-pick non pstate " ^ Stateid.to_string id);
reach id;
cherry_pick_non_pstate ()) id
(* traverses the dag backward from nodes being already calculated *)
and reach ?(redefine_qed=false) ?(cache=cache) id =
- prerr_endline ("reaching: " ^ Stateid.to_string id);
+ prerr_endline (fun () -> "reaching: " ^ Stateid.to_string id);
if not redefine_qed && State.is_cached ~cache id then begin
- State.install_cached id;
Hooks.(call state_computed id ~in_cache:true);
- prerr_endline ("reached (cache)")
+ prerr_endline (fun () -> "reached (cache)");
+ State.install_cached id
end else
let step, cache_step, feedback_processed =
let view = VCS.visit id in
@@ -1819,29 +2088,38 @@ let known_state ?(redefine_qed=false) ~cache id =
), cache, true
| `Cmd { cast = x; cqueue = `SkipQueue } -> (fun () ->
reach view.next), cache, true
- | `Cmd { cast = x; cqueue = `TacQueue cancel } -> (fun () ->
- reach ~cache:`Shallow view.next;
- Hooks.(call tactic_being_run true);
- Partac.vernac_interp
- cancel !Flags.async_proofs_n_tacworkers view.next id x;
- Hooks.(call tactic_being_run false)
+ | `Cmd { cast = x; cqueue = `TacQueue cancel; cblock } -> (fun () ->
+ resilient_tactic id cblock (fun () ->
+ reach ~cache:`Shallow view.next;
+ Hooks.(call tactic_being_run true);
+ Partac.vernac_interp
+ cancel !Flags.async_proofs_n_tacworkers view.next id x;
+ Hooks.(call tactic_being_run false))
), cache, true
| `Cmd { cast = x; cqueue = `QueryQueue cancel }
when Flags.async_proofs_is_master () -> (fun () ->
reach view.next;
Query.vernac_interp cancel view.next id x
), cache, false
- | `Cmd { cast = x; ceff = eff; ctac } -> (fun () ->
- reach view.next;
- if ctac then Hooks.(call tactic_being_run true);
+ | `Cmd { cast = x; ceff = eff; ctac = true; cblock } -> (fun () ->
+ resilient_tactic id cblock (fun () ->
+ reach view.next;
+ Hooks.(call tactic_being_run true);
+ vernac_interp id x;
+ Hooks.(call tactic_being_run false));
+ if eff then update_global_env ()
+ ), (if eff then `Yes else cache), true
+ | `Cmd { cast = x; ceff = eff } -> (fun () ->
+ resilient_command reach view.next;
vernac_interp id x;
- if ctac then Hooks.(call tactic_being_run false);
- if eff then update_global_env ()), cache, true
+ if eff then update_global_env ()
+ ), (if eff then `Yes else cache), true
| `Fork ((x,_,_,_), None) -> (fun () ->
- reach view.next; vernac_interp id x;
+ resilient_command reach view.next;
+ vernac_interp id x;
wall_clock_last_fork := Unix.gettimeofday ()
), `Yes, true
- | `Fork ((x,_,_,_), Some prev) -> (fun () ->
+ | `Fork ((x,_,_,_), Some prev) -> (fun () -> (* nested proof *)
reach ~cache:`Shallow prev;
reach view.next;
(try vernac_interp id x;
@@ -1858,7 +2136,7 @@ let known_state ?(redefine_qed=false) ~cache id =
let drop_pt = keep == VtKeepAsAxiom in
let stop, exn_info, loc = eop, (id, eop), x.loc in
log_processing_async id name;
- VCS.create_cluster nodes ~qed:id ~start;
+ VCS.create_proof_task_box nodes ~qed:id ~start;
begin match brinfo, qed.fproof with
| { VCS.kind = `Edit _ }, None -> assert false
| { VCS.kind = `Edit (_,_,_, okeep, _) }, Some (ofp, cancel) ->
@@ -1892,7 +2170,7 @@ let known_state ?(redefine_qed=false) ~cache id =
if not delegate then ignore(Future.compute fp);
reach view.next;
vernac_interp id ~proof x;
- feedback ~state_id:id Feedback.Incomplete
+ feedback ~id:(State id) Incomplete
| { VCS.kind = `Master }, _ -> assert false
end;
Proof_global.discard_all ()
@@ -1947,7 +2225,7 @@ let known_state ?(redefine_qed=false) ~cache id =
else cache_step in
State.define
~cache:cache_step ~redefine:redefine_qed ~feedback_processed step id;
- prerr_endline ("reached: "^ Stateid.to_string id) in
+ prerr_endline (fun () -> "reached: "^ Stateid.to_string id) in
reach ~redefine_qed id
end (* }}} *)
@@ -1962,7 +2240,7 @@ let init () =
Backtrack.record ();
Slaves.init ();
if Flags.async_proofs_is_master () then begin
- prerr_endline "Initializing workers";
+ prerr_endline (fun () -> "Initializing workers");
Query.init ();
let opts = match !Flags.async_proofs_private_flags with
| None -> []
@@ -2014,9 +2292,9 @@ let rec join_admitted_proofs id =
let join () =
finish ();
wait ();
- prerr_endline "Joining the environment";
+ prerr_endline (fun () -> "Joining the environment");
Global.join_safe_environment ();
- prerr_endline "Joining Admitted proofs";
+ prerr_endline (fun () -> "Joining Admitted proofs");
join_admitted_proofs (VCS.get_branch_pos (VCS.current_branch ()));
VCS.print ();
VCS.print ()
@@ -2029,7 +2307,6 @@ let check_task name (tasks,rcbackup) i =
let vcs = VCS.backup () in
try
let rc = Future.purify (Slaves.check_task name tasks) i in
- pperr_flush ();
VCS.restore vcs;
rc
with e when Errors.noncritical e -> VCS.restore vcs; false
@@ -2039,7 +2316,6 @@ let finish_tasks name u d p (t,rcbackup as tasks) =
let finish_task u (_,_,i) =
let vcs = VCS.backup () in
let u = Future.purify (Slaves.finish_task name u d p t) i in
- pperr_flush ();
VCS.restore vcs;
u in
try
@@ -2047,7 +2323,7 @@ let finish_tasks name u d p (t,rcbackup as tasks) =
(u,a,true), p
with e ->
let e = Errors.push e in
- pperrnl (str"File " ++ str name ++ str ":" ++ spc () ++ iprint e);
+ msg_error (str"File " ++ str name ++ str ":" ++ spc () ++ iprint e);
exit 1
let merge_proof_branch ?valid ?id qast keep brname =
@@ -2092,7 +2368,7 @@ let handle_failure (e, info) vcs tty =
anomaly(str"error with no safe_id attached:" ++ spc() ++
Errors.iprint_no_report (e, info))
| Some (safe_id, id) ->
- prerr_endline ("Failed at state " ^ Stateid.to_string id);
+ prerr_endline (fun () -> "Failed at state " ^ Stateid.to_string id);
VCS.restore vcs;
if tty && interactive () = `Yes then begin
(* We stay on a valid state *)
@@ -2103,27 +2379,29 @@ let handle_failure (e, info) vcs tty =
VCS.print ();
iraise (e, info)
-let snapshot_vio ldir long_f_dot_v =
+let snapshot_vio ldir long_f_dot_vo =
finish ();
if List.length (VCS.branches ()) > 1 then
Errors.errorlabstrm "stm" (str"Cannot dump a vio with open proofs");
- Library.save_library_to ~todo:(dump_snapshot ()) ldir long_f_dot_v
+ Library.save_library_to ~todo:(dump_snapshot ()) ldir long_f_dot_vo
(Global.opaque_tables ())
let reset_task_queue = Slaves.reset_task_queue
(* Document building *)
-let process_transaction ?(newtip=Stateid.fresh ()) ~tty verbose c (loc, expr) =
+let process_transaction ?(newtip=Stateid.fresh ()) ~tty
+ ({ verbose; loc; expr } as x) c
+ =
let warn_if_pos a b =
if b then msg_warning(pr_ast a ++ str" should not be part of a script") in
- let v, x = expr, { verbose = verbose; loc; expr } in
- prerr_endline ("{{{ processing: "^ string_of_ppcmds (pr_ast x));
+ prerr_endline (fun () -> "{{{ processing: "^ string_of_ppcmds (pr_ast x));
let vcs = VCS.backup () in
try
let head = VCS.current_branch () in
VCS.checkout head;
let rc = begin
- prerr_endline (" classified as: " ^ string_of_vernac_classification c);
+ prerr_endline (fun () ->
+ " classified as: " ^ string_of_vernac_classification c);
match c with
(* PG stuff *)
| VtStm(VtPG,false), VtNow -> vernac_interp Stateid.dummy x; `Ok
@@ -2159,7 +2437,7 @@ let process_transaction ?(newtip=Stateid.fresh ()) ~tty verbose c (loc, expr) =
VCS.commit id (Alias (oid,x));
Backtrack.record (); if w == VtNow then finish (); `Ok
| VtStm (VtBack id, false), VtNow ->
- prerr_endline ("undo to state " ^ Stateid.to_string id);
+ prerr_endline (fun () -> "undo to state " ^ Stateid.to_string id);
Backtrack.backto id;
VCS.checkout_shallowest_proof_branch ();
Reach.known_state ~cache:(interactive ()) id; `Ok
@@ -2170,7 +2448,7 @@ let process_transaction ?(newtip=Stateid.fresh ()) ~tty verbose c (loc, expr) =
| VtQuery (false,(report_id,route)), VtNow when tty = true ->
finish ();
(try Future.purify (vernac_interp report_id ~route)
- { verbose = true; loc; expr }
+ {x with verbose = true }
with e when Errors.noncritical e ->
let e = Errors.push e in
iraise (State.exn_on report_id e)); `Ok
@@ -2189,7 +2467,7 @@ let process_transaction ?(newtip=Stateid.fresh ()) ~tty verbose c (loc, expr) =
may_pierce_opaque x
then `SkipQueue
else `MainQueue in
- VCS.commit id (Cmd {ctac=false;ceff=false;cast = x; cids = []; cqueue = queue });
+ VCS.commit id (mkTransCmd x [] false queue);
Backtrack.record (); if w == VtNow then finish (); `Ok
| VtQuery (false,_), VtLater ->
anomaly(str"classifier: VtQuery + VtLater must imply part_of_script")
@@ -2212,7 +2490,7 @@ let process_transaction ?(newtip=Stateid.fresh ()) ~tty verbose c (loc, expr) =
anomaly(str"VtProofMode must be executed VtNow")
| VtProofMode mode, VtNow ->
let id = VCS.new_node ~id:newtip () in
- VCS.commit id (Cmd {ctac=false;ceff=false;cast = x;cids=[];cqueue = `MainQueue});
+ VCS.commit id (mkTransCmd x [] false `MainQueue);
List.iter
(fun bn -> match VCS.get_branch bn with
| { VCS.root; kind = `Master; pos } -> ()
@@ -2227,10 +2505,14 @@ let process_transaction ?(newtip=Stateid.fresh ()) ~tty verbose c (loc, expr) =
Backtrack.record ();
finish ();
`Ok
- | VtProofStep paral, w ->
+ | VtProofStep { parallel; proof_block_detection = cblock }, w ->
let id = VCS.new_node ~id:newtip () in
- let queue = if paral then `TacQueue (ref false) else `MainQueue in
- VCS.commit id (Cmd {ctac = true;ceff = false;cast = x;cids = [];cqueue = queue });
+ let queue = if parallel then `TacQueue (ref false) else `MainQueue in
+ VCS.commit id (mkTransTac x cblock queue);
+ (* Static proof block detection delayed until an error really occurs.
+ If/when and UI will make something useful with this piece of info,
+ detection should occur here.
+ detect_proof_block id cblock; *)
Backtrack.record (); if w == VtNow then finish (); `Ok
| VtQed keep, w ->
let valid = if tty then Some(VCS.get_branch_pos head) else None in
@@ -2244,15 +2526,22 @@ let process_transaction ?(newtip=Stateid.fresh ()) ~tty verbose c (loc, expr) =
vernac_interp (VCS.get_branch_pos head) x; `Ok
| VtSideff l, w ->
+ let in_proof = not (VCS.Branch.equal head VCS.Branch.master) in
let id = VCS.new_node ~id:newtip () in
VCS.checkout VCS.Branch.master;
- VCS.commit id (Cmd {ctac=false;ceff=true;cast=x;cids=l;cqueue=`MainQueue});
- VCS.propagate_sideff (Some x);
+ VCS.commit id (mkTransCmd x l in_proof `MainQueue);
+ (* We can't replay a Definition since universes may be differently
+ * inferred. This holds in Coq >= 8.5 *)
+ let replay = match x.expr with
+ | VernacDefinition(_, _, DefineBody _) -> None
+ | _ -> Some x in
+ VCS.propagate_sideff ~replay;
VCS.checkout_shallowest_proof_branch ();
Backtrack.record (); if w == VtNow then finish (); `Ok
(* Unknown: we execute it, check for open goals and propagate sideeff *)
| VtUnknown, VtNow ->
+ 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
Reach.known_state ~cache:`Yes head_id; (* ensure it is ok *)
@@ -2262,21 +2551,22 @@ let process_transaction ?(newtip=Stateid.fresh ()) ~tty verbose c (loc, expr) =
Reach.known_state ~cache:(interactive ()) mid;
vernac_interp id x;
(* Vernac x may or may not start a proof *)
- if VCS.Branch.equal head VCS.Branch.master &&
- Proof_global.there_are_pending_proofs ()
- then begin
+ if not in_proof && Proof_global.there_are_pending_proofs () then
+ begin
let bname = VCS.mk_branch_name x in
let opacity_of_produced_term =
match x.expr with
+ (* This AST is ambiguous, hence we check it dynamically *)
| VernacInstance (false, _,_ , None, _) -> GuaranteesOpacity
| _ -> Doesn'tGuaranteeOpacity in
VCS.commit id (Fork (x,bname,opacity_of_produced_term,[]));
- VCS.branch bname (`Proof ("Classic", VCS.proof_nesting () + 1));
- Proof_global.activate_proof_mode "Classic";
+ let proof_mode = default_proof_mode () in
+ VCS.branch bname (`Proof (proof_mode, VCS.proof_nesting () + 1));
+ Proof_global.activate_proof_mode proof_mode;
end else begin
- VCS.commit id (Cmd {ctac = false; ceff = true;
- cast = x; cids = []; cqueue = `MainQueue});
- VCS.propagate_sideff (Some x);
+ VCS.commit id (mkTransCmd x [] in_proof `MainQueue);
+ (* We hope it can be replayed, but we can't really know *)
+ VCS.propagate_sideff ~replay:(Some x);
VCS.checkout_shallowest_proof_branch ();
end in
State.define ~safe_id:head_id ~cache:`Yes step id;
@@ -2286,49 +2576,55 @@ let process_transaction ?(newtip=Stateid.fresh ()) ~tty verbose c (loc, expr) =
anomaly(str"classifier: VtUnknown must imply VtNow")
end in
(* Proof General *)
- begin match v with
+ begin match expr with
| VernacStm (PGLast _) ->
if not (VCS.Branch.equal head VCS.Branch.master) then
vernac_interp Stateid.dummy
- { verbose = true; loc = Loc.ghost;
+ { verbose = true; loc = Loc.ghost; indentation = 0; strlen = 0;
expr = VernacShow (ShowGoal OpenSubgoals) }
| _ -> ()
end;
- prerr_endline "processed }}}";
+ prerr_endline (fun () -> "processed }}}");
VCS.print ();
rc
with e ->
let e = Errors.push e in
handle_failure e vcs tty
-let print_ast id =
- try
- match VCS.visit id with
- | { step = `Cmd { cast = { loc; expr } } }
- | { step = `Fork (({ loc; expr }, _, _, _), _) }
- | { step = `Qed ({ qast = { loc; expr } }, _) } ->
- let xml =
- try Texmacspp.tmpp expr loc
- with e -> Xml_datatype.PCData ("ERROR " ^ Printexc.to_string e) in
- xml;
- | _ -> Xml_datatype.PCData "ERROR"
- with _ -> Xml_datatype.PCData "ERROR"
+let get_ast id =
+ match VCS.visit id with
+ | { step = `Cmd { cast = { loc; expr } } }
+ | { step = `Fork (({ loc; expr }, _, _, _), _) }
+ | { step = `Qed ({ qast = { loc; expr } }, _) } ->
+ Some (expr, loc)
+ | _ -> None
let stop_worker n = Slaves.cancel_worker n
+(* You may need to know the len + indentation of previous command to compute
+ * the indentation of the current one.
+ * Eg. foo. bar.
+ * Here bar is indented of the indentation of foo + its strlen (4) *)
+let ind_len_of id =
+ if Stateid.equal id Stateid.initial then 0
+ else match (VCS.visit id).step with
+ | `Cmd { ctac = true; cast = { indentation; strlen } } ->
+ indentation + strlen
+ | _ -> 0
+
let add ~ontop ?newtip ?(check=ignore) verb eid s =
let cur_tip = VCS.cur_tip () in
- if Stateid.equal ontop cur_tip then begin
- let _, ast as loc_ast = vernac_parse ?newtip eid s in
- check(loc_ast);
- let clas = classify_vernac ast in
- match process_transaction ?newtip ~tty:false verb clas loc_ast with
- | `Ok -> VCS.cur_tip (), `NewTip
- | `Unfocus qed_id -> qed_id, `Unfocus (VCS.cur_tip ())
- end else begin
+ if not (Stateid.equal ontop cur_tip) then
(* For now, arbitrary edits should be announced with edit_at *)
- anomaly(str"Not yet implemented, the GUI should not try this")
- end
+ anomaly(str"Not yet implemented, the GUI should not try this");
+ let indentation, strlen, loc, ast =
+ vernac_parse ~indlen_prev:(fun () -> ind_len_of ontop) ?newtip eid s in
+ check(loc,ast);
+ let clas = classify_vernac ast in
+ let aast = { verbose = verb; indentation; strlen; loc; expr = ast } in
+ match process_transaction ?newtip ~tty:false aast clas with
+ | `Ok -> VCS.cur_tip (), `NewTip
+ | `Unfocus qed_id -> qed_id, `Unfocus (VCS.cur_tip ())
let set_perspective id_list = Slaves.set_perspective id_list
@@ -2338,20 +2634,20 @@ type focus = {
tip : Stateid.t
}
-let query ~at ?(report_with=(Stateid.dummy,Feedback.default_route)) s =
+let query ~at ?(report_with=(Stateid.dummy,default_route)) s =
Future.purify (fun s ->
if Stateid.equal at Stateid.dummy then finish ()
else Reach.known_state ~cache:`Yes at;
let newtip, route = report_with in
- let _, ast as loc_ast = vernac_parse ~newtip ~route 0 s in
+ let indentation, strlen, loc, ast = vernac_parse ~newtip ~route 0 s in
let clas = classify_vernac ast in
+ let aast = { verbose = true; indentation; strlen; loc; expr = ast } in
match clas with
| VtStm (w,_), _ ->
- ignore(process_transaction
- ~tty:false true (VtStm (w,false), VtNow) loc_ast)
+ ignore(process_transaction ~tty:false aast (VtStm (w,false), VtNow))
| _ ->
ignore(process_transaction
- ~tty:false true (VtQuery (false,report_with), VtNow) loc_ast))
+ ~tty:false aast (VtQuery (false,report_with), VtNow)))
s
let edit_at id =
@@ -2376,7 +2672,7 @@ let edit_at id =
| _ -> assert false
in
let is_ancestor_of_cur_branch id =
- Vcs_.NodeSet.mem id
+ Stateid.Set.mem id
(VCS.reachable (VCS.get_branch_pos (VCS.current_branch ()))) in
let has_failed qed_id =
match VCS.visit qed_id with
@@ -2391,13 +2687,13 @@ let edit_at id =
| { next } -> master_for_br root next in
let reopen_branch start at_id mode qed_id tip old_branch =
let master_id, cancel_switch, keep =
- (* Hum, this should be the real start_id in the clusted and not next *)
+ (* Hum, this should be the real start_id in the cluster and not next *)
match VCS.visit qed_id with
| { step = `Qed ({ fproof = Some (_,cs); keep },_) } -> start, cs, keep
- | _ -> anomaly (str "Cluster not ending with Qed") in
+ | _ -> anomaly (str "ProofTask not ending with Qed") in
VCS.branch ~root:master_id ~pos:id
VCS.edit_branch (`Edit (mode, qed_id, master_id, keep, old_branch));
- VCS.delete_cluster_of id;
+ VCS.delete_boxes_of id;
cancel_switch := true;
Reach.known_state ~cache:(interactive ()) id;
VCS.checkout_shallowest_proof_branch ();
@@ -2411,14 +2707,14 @@ let edit_at id =
let { mine = brname, brinfo; others } = Backtrack.branches_of id in
List.iter (fun (name,{ VCS.kind = k; root; pos }) ->
if not(VCS.Branch.equal name VCS.Branch.master) &&
- Vcs_.NodeSet.mem root ancestors then
+ Stateid.Set.mem root ancestors then
VCS.branch ~root ~pos name k)
others;
VCS.reset_branch VCS.Branch.master (master_for_br brinfo.VCS.root id);
VCS.branch ~root:brinfo.VCS.root ~pos:brinfo.VCS.pos
(Option.default brname bn)
(no_edit brinfo.VCS.kind);
- VCS.delete_cluster_of id;
+ VCS.delete_boxes_of id;
VCS.gc ();
VCS.print ();
if not !Flags.async_proofs_full then
@@ -2433,14 +2729,14 @@ let edit_at id =
| Some{ mine = bn, { VCS.kind = `Proof(m,_) }} -> Some(m,bn)
| Some{ mine = _, { VCS.kind = `Edit(m,_,_,_,bn) }} -> Some (m,bn)
| _ -> None in
- match focused, VCS.cluster_of id, branch_info with
+ match focused, VCS.proof_task_box_of id, branch_info with
| _, Some _, None -> assert false
- | false, Some (qed_id,start), Some(mode,bn) ->
+ | false, Some { qed = qed_id ; lemma = start }, Some(mode,bn) ->
let tip = VCS.cur_tip () in
if has_failed qed_id && is_pure qed_id && not !Flags.async_proofs_never_reopen_branch
then reopen_branch start id mode qed_id tip bn
else backto id (Some bn)
- | true, Some (qed_id,_), Some(mode,bn) ->
+ | true, Some { qed = qed_id }, Some(mode,bn) ->
if on_cur_branch id then begin
assert false
end else if is_ancestor_of_cur_branch id then begin
@@ -2472,7 +2768,7 @@ let edit_at id =
anomaly (str ("edit_at "^Stateid.to_string id^": ") ++
Errors.print_no_report e)
| Some (_, id) ->
- prerr_endline ("Failed at state " ^ Stateid.to_string id);
+ prerr_endline (fun () -> "Failed at state " ^ Stateid.to_string id);
VCS.restore vcs;
VCS.print ();
iraise (e, info)
@@ -2483,9 +2779,10 @@ let restore d = VCS.restore d
(*********************** TTY API (PG, coqtop, coqc) ***************************)
(******************************************************************************)
-let interp verb (_,e as lexpr) =
+let interp verb (loc,e) =
let clas = classify_vernac e in
- let rc = process_transaction ~tty:true verb clas lexpr in
+ let aast = { verbose = verb; indentation = 0; strlen = 0; loc; expr = e } in
+ let rc = process_transaction ~tty:true aast clas in
if rc <> `Ok then anomaly(str"tty loop can't be mixed with the STM protocol");
if interactive () = `Yes ||
(!Flags.async_proofs_mode = Flags.APoff &&
diff --git a/stm/stm.mli b/stm/stm.mli
index 4279921b3..37ec1f0a1 100644
--- a/stm/stm.mli
+++ b/stm/stm.mli
@@ -20,7 +20,9 @@ open Loc
The sentence [s] is parsed in the state [ontop].
If [newtip] is provided, then the returned state id is guaranteed to be
[newtip] *)
-val add : ontop:Stateid.t -> ?newtip:Stateid.t -> ?check:(vernac_expr located -> unit) ->
+val add :
+ ontop:Stateid.t -> ?newtip:Stateid.t ->
+ ?check:(vernac_expr located -> unit) ->
bool -> edit_id -> string ->
Stateid.t * [ `NewTip | `Unfocus of Stateid.t ]
@@ -76,7 +78,9 @@ val get_current_state : unit -> Stateid.t
(* Misc *)
val init : unit -> unit
-val print_ast : Stateid.t -> Xml_datatype.xml
+
+(* This returns the node at that position *)
+val get_ast : Stateid.t -> (Vernacexpr.vernac_expr * Loc.t) option
(* Filename *)
val set_compilation_hints : string -> unit
@@ -94,6 +98,82 @@ module ProofTask : AsyncTaskQueue.Task
module TacTask : AsyncTaskQueue.Task
module QueryTask : AsyncTaskQueue.Task
+(** document structure customization *************************************** **)
+
+(* A proof block delimiter defines a syntactic delimiter for sub proofs
+ that, when contain an error, do not impact the rest of the proof.
+ While checking a proof, if an error occurs in a (valid) block then
+ processing can skip the entire block and go on to give feedback
+ on the rest of the proof.
+
+ static_block_detection and dynamic_block_validation are run when
+ the closing block marker is parsed/executed respectively.
+
+ static_block_detection is for example called when "}" is parsed and
+ declares a block containing all proof steps between it and the matching
+ "{".
+
+ dynamic_block_validation is called when an error "crosses" the "}" statement.
+ Depending on the nature of the goal focused by "{" the block may absorb the
+ error or not. For example if the focused goal occurs in the type of
+ another goal, then the block is leaky.
+ Note that one can design proof commands that need no dynamic validation.
+
+ Example of document:
+
+ .. { tac1. tac2. } ..
+
+ Corresponding DAG:
+
+ .. (3) <-- { -- (4) <-- tac1 -- (5) <-- tac2 -- (6) <-- } -- (7) ..
+
+ Declaration of block [-------------------------------------------]
+
+ start = 5 the first state_id that could fail in the block
+ stop = 7 the node that may absorb the error
+ dynamic_switch = 4 dynamic check on this node
+ carry_on_data = () no need to carry extra data from static to dynamic
+ checks
+*)
+
+module DynBlockData : Dyn.S
+
+type static_block_declaration = {
+ start : Stateid.t;
+ stop : Stateid.t;
+ dynamic_switch : Stateid.t;
+ carry_on_data : DynBlockData.t;
+}
+
+type document_node = {
+ indentation : int;
+ ast : Vernacexpr.vernac_expr;
+ id : Stateid.t;
+}
+
+type document_view = {
+ entry_point : document_node;
+ prev_node : document_node -> document_node option;
+}
+
+type static_block_detection =
+ document_view -> static_block_declaration option
+
+type recovery_action = {
+ base_state : Stateid.t;
+ goals_to_admit : Goal.goal list;
+ recovery_command : Vernacexpr.vernac_expr option;
+}
+
+type dynamic_block_error_recovery =
+ static_block_declaration -> [ `ValidBlock of recovery_action | `Leaks ]
+
+val register_proof_block_delimiter :
+ Vernacexpr.proof_block_name ->
+ static_block_detection ->
+ dynamic_block_error_recovery ->
+ unit
+
(** customization ********************************************************** **)
(* From the master (or worker, but beware that to install the hook
@@ -120,12 +200,13 @@ type state = {
proof : Proof_global.state;
shallow : bool
}
-val state_of_id : Stateid.t -> [ `Valid of state option | `Expired ]
+val state_of_id :
+ Stateid.t -> [ `Valid of state option | `Expired | `Error of exn ]
(** read-eval-print loop compatible interface ****************************** **)
(* Adds a new line to the document. It replaces the core of Vernac.interp.
- [finish] is called as the last bit of this function is the system
+ [finish] is called as the last bit of this function if the system
is running interactively (-emacs or coqtop). *)
val interp : bool -> vernac_expr located -> unit
@@ -135,7 +216,7 @@ val get_all_proof_names : unit -> Id.t list
val get_current_proof_name : unit -> Id.t option
val show_script : ?proof:Proof_global.closed_proof -> unit -> unit
-(** Reverse dependency hooks *)
+(* Hooks to be set by other Coq components in order to break file cycles *)
val process_error_hook : Future.fix_exn Hook.t
val interp_hook : (?verbosely:bool -> ?proof:Proof_global.closed_proof ->
Loc.t * Vernacexpr.vernac_expr -> unit) Hook.t
diff --git a/stm/stm.mllib b/stm/stm.mllib
index 92b3a869a..939ee187a 100644
--- a/stm/stm.mllib
+++ b/stm/stm.mllib
@@ -7,6 +7,6 @@ Vernac_classifier
Lemmas
CoqworkmgrApi
AsyncTaskQueue
-Texmacspp
Stm
+ProofBlockDelimiter
Vio_checking
diff --git a/stm/vcs.ml b/stm/vcs.ml
index 38c029901..c483ea4a9 100644
--- a/stm/vcs.ml
+++ b/stm/vcs.ml
@@ -22,51 +22,49 @@ module type S = sig
end
type id
-
- (* Branches have [branch_info] attached to them. *)
+
type ('kind) branch_info = {
kind : [> `Master] as 'kind;
root : id;
pos : id;
}
-
- type ('kind,'diff,'info) t constraint 'kind = [> `Master ]
-
- val empty : id -> ('kind,'diff,'info) t
-
- val current_branch : ('k,'e,'i) t -> Branch.t
- val branches : ('k,'e,'i) t -> Branch.t list
-
- val get_branch : ('k,'e,'i) t -> Branch.t -> 'k branch_info
- val reset_branch : ('k,'e,'i) t -> Branch.t -> id -> ('k,'e,'i) t
+
+ type ('kind,'diff,'info,'property_data) t constraint 'kind = [> `Master ]
+
+ val empty : id -> ('kind,'diff,'info,'property_data) t
+
+ val current_branch : ('k,'e,'i,'c) t -> Branch.t
+ val branches : ('k,'e,'i,'c) t -> Branch.t list
+
+ val get_branch : ('k,'e,'i,'c) t -> Branch.t -> 'k branch_info
+ val reset_branch : ('k,'e,'i,'c) t -> Branch.t -> id -> ('k,'e,'i,'c) t
val branch :
- ('kind,'e,'i) t -> ?root:id -> ?pos:id ->
- Branch.t -> 'kind -> ('kind,'e,'i) t
- val delete_branch : ('k,'e,'i) t -> Branch.t -> ('k,'e,'i) t
+ ('kind,'e,'i,'c) t -> ?root:id -> ?pos:id ->
+ Branch.t -> 'kind -> ('kind,'e,'i,'c) t
+ val delete_branch : ('k,'e,'i,'c) t -> Branch.t -> ('k,'e,'i,'c) t
val merge :
- ('k,'diff,'i) t -> id -> ours:'diff -> theirs:'diff -> ?into:Branch.t ->
- Branch.t -> ('k,'diff,'i) t
- val commit : ('k,'diff,'i) t -> id -> 'diff -> ('k,'diff,'i) t
+ ('k,'diff,'i,'c) t -> id -> ours:'diff -> theirs:'diff -> ?into:Branch.t ->
+ Branch.t -> ('k,'diff,'i,'c) t
+ val commit : ('k,'diff,'i,'c) t -> id -> 'diff -> ('k,'diff,'i,'c) t
val rewrite_merge :
- ('k,'diff,'i) t -> id -> ours:'diff -> theirs:'diff -> at:id ->
- Branch.t -> ('k,'diff,'i) t
- val checkout : ('k,'e,'i) t -> Branch.t -> ('k,'e,'i) t
-
- val set_info : ('k,'e,'info) t -> id -> 'info -> ('k,'e,'info) t
- val get_info : ('k,'e,'info) t -> id -> 'info option
+ ('k,'diff,'i,'c) t -> id -> ours:'diff -> theirs:'diff -> at:id ->
+ Branch.t -> ('k,'diff,'i,'c) t
+ val checkout : ('k,'e,'i,'c) t -> Branch.t -> ('k,'e,'i,'c) t
- module NodeSet : Set.S with type elt = id
-
- val gc : ('k,'e,'info) t -> ('k,'e,'info) t * NodeSet.t
-
- val reachable : ('k,'e,'info) t -> id -> NodeSet.t
+ val set_info : ('k,'e,'info,'c) t -> id -> 'info -> ('k,'e,'info,'c) t
+ val get_info : ('k,'e,'info,'c) t -> id -> 'info option
+ (* Read only dag *)
module Dag : Dag.S with type node = id
- val dag : ('kind,'diff,'info) t -> ('diff,'info,id*id) Dag.t
+ val dag : ('kind,'diff,'info,'cdata) t -> ('diff,'info,'cdata) Dag.t
+
+ val create_property : ('k,'e,'i,'c) t -> id list -> 'c -> ('k,'e,'i,'c) t
+ val property_of : ('k,'e,'i,'c) t -> id -> 'c Dag.Property.t list
+ val delete_property : ('k,'e,'i,'c) t -> 'c Dag.Property.t -> ('k,'e,'i,'c) t
- val create_cluster : ('k,'e,'i) t -> id list -> (id * id) -> ('k,'e,'i) t
- val cluster_of : ('k,'e,'i) t -> id -> (id * id) Dag.Cluster.t option
- val delete_cluster : ('k,'e,'i) t -> (id * id) Dag.Cluster.t -> ('k,'e,'i) t
+ (* Removes all unreachable nodes and returns them *)
+ val gc : ('k,'e,'info,'c) t -> ('k,'e,'info,'c) t * Dag.NodeSet.t
+ val reachable : ('k,'e,'info,'c) t -> id -> Dag.NodeSet.t
end
@@ -78,7 +76,6 @@ type id = OT.t
module NodeSet = Dag.NodeSet
-
module Branch =
struct
type t = string
@@ -99,10 +96,10 @@ type 'kind branch_info = {
pos : id;
}
-type ('kind,'edge,'info) t = {
+type ('kind,'edge,'info,'property_data) t = {
cur_branch : Branch.t;
heads : 'kind branch_info BranchMap.t;
- dag : ('edge,'info,id*id) Dag.t;
+ dag : ('edge,'info,'property_data) Dag.t;
}
let empty root = {
@@ -167,9 +164,9 @@ let checkout vcs name = { vcs with cur_branch = name }
let set_info vcs id info = { vcs with dag = Dag.set_info vcs.dag id info }
let get_info vcs id = Dag.get_info vcs.dag id
-let create_cluster vcs l i = { vcs with dag = Dag.create_cluster vcs.dag l i }
-let cluster_of vcs i = Dag.cluster_of vcs.dag i
-let delete_cluster vcs c = { vcs with dag = Dag.del_cluster vcs.dag c }
+let create_property vcs l i = { vcs with dag = Dag.create_property vcs.dag l i }
+let property_of vcs i = Dag.property_of vcs.dag i
+let delete_property vcs c = { vcs with dag = Dag.del_property vcs.dag c }
let branches vcs = BranchMap.fold (fun x _ accu -> x :: accu) vcs.heads []
let dag vcs = vcs.dag
diff --git a/stm/vcs.mli b/stm/vcs.mli
index 8f22fee84..46b40f8a4 100644
--- a/stm/vcs.mli
+++ b/stm/vcs.mli
@@ -19,10 +19,11 @@
As a consequence, "checkout" just updates the current branch.
The type [id] is the type of commits (a node in the dag)
- The type [Vcs.t] has 3 parameters:
+ The type [Vcs.t] has 4 parameters:
['info] data attached to a node (like a system state)
['diff] data attached to an edge (the commit content, a "patch")
['kind] extra data attached to a branch (like being the master branch)
+ ['cdata] extra data hold by dag properties
*)
module type S = sig
@@ -45,46 +46,51 @@ module type S = sig
pos : id;
}
- type ('kind,'diff,'info) t constraint 'kind = [> `Master ]
+ type ('kind,'diff,'info,'property_data) t constraint 'kind = [> `Master ]
- val empty : id -> ('kind,'diff,'info) t
+ val empty : id -> ('kind,'diff,'info,'property_data) t
- val current_branch : ('k,'e,'i) t -> Branch.t
- val branches : ('k,'e,'i) t -> Branch.t list
+ val current_branch : ('k,'e,'i,'c) t -> Branch.t
+ val branches : ('k,'e,'i,'c) t -> Branch.t list
- val get_branch : ('k,'e,'i) t -> Branch.t -> 'k branch_info
- val reset_branch : ('k,'e,'i) t -> Branch.t -> id -> ('k,'e,'i) t
+ val get_branch : ('k,'e,'i,'c) t -> Branch.t -> 'k branch_info
+ val reset_branch : ('k,'e,'i,'c) t -> Branch.t -> id -> ('k,'e,'i,'c) t
val branch :
- ('kind,'e,'i) t -> ?root:id -> ?pos:id ->
- Branch.t -> 'kind -> ('kind,'e,'i) t
- val delete_branch : ('k,'e,'i) t -> Branch.t -> ('k,'e,'i) t
+ ('kind,'e,'i,'c) t -> ?root:id -> ?pos:id ->
+ Branch.t -> 'kind -> ('kind,'e,'i,'c) t
+ val delete_branch : ('k,'e,'i,'c) t -> Branch.t -> ('k,'e,'i,'c) t
val merge :
- ('k,'diff,'i) t -> id -> ours:'diff -> theirs:'diff -> ?into:Branch.t ->
- Branch.t -> ('k,'diff,'i) t
- val commit : ('k,'diff,'i) t -> id -> 'diff -> ('k,'diff,'i) t
+ ('k,'diff,'i,'c) t -> id -> ours:'diff -> theirs:'diff -> ?into:Branch.t ->
+ Branch.t -> ('k,'diff,'i,'c) t
+ val commit : ('k,'diff,'i,'c) t -> id -> 'diff -> ('k,'diff,'i,'c) t
val rewrite_merge :
- ('k,'diff,'i) t -> id -> ours:'diff -> theirs:'diff -> at:id ->
- Branch.t -> ('k,'diff,'i) t
- val checkout : ('k,'e,'i) t -> Branch.t -> ('k,'e,'i) t
+ ('k,'diff,'i,'c) t -> id -> ours:'diff -> theirs:'diff -> at:id ->
+ Branch.t -> ('k,'diff,'i,'c) t
+ val checkout : ('k,'e,'i,'c) t -> Branch.t -> ('k,'e,'i,'c) t
- val set_info : ('k,'e,'info) t -> id -> 'info -> ('k,'e,'info) t
- val get_info : ('k,'e,'info) t -> id -> 'info option
+ val set_info : ('k,'e,'info,'c) t -> id -> 'info -> ('k,'e,'info,'c) t
+ val get_info : ('k,'e,'info,'c) t -> id -> 'info option
- module NodeSet : Set.S with type elt = id
+ (* Read only dag *)
+ module Dag : Dag.S with type node = id
+ val dag : ('kind,'diff,'info,'cdata) t -> ('diff,'info,'cdata) Dag.t
- (* Removes all unreachable nodes and returns them *)
- val gc : ('k,'e,'info) t -> ('k,'e,'info) t * NodeSet.t
+ (* Properties are not a concept typical of a VCS, but a useful metadata
+ * of a DAG (or graph). *)
+ val create_property : ('k,'e,'i,'c) t -> id list -> 'c -> ('k,'e,'i,'c) t
+ val property_of : ('k,'e,'i,'c) t -> id -> 'c Dag.Property.t list
+ val delete_property : ('k,'e,'i,'c) t -> 'c Dag.Property.t -> ('k,'e,'i,'c) t
- val reachable : ('k,'e,'info) t -> id -> NodeSet.t
+ (* Removes all unreachable nodes and returns them *)
+ val gc : ('k,'e,'info,'c) t -> ('k,'e,'info,'c) t * Dag.NodeSet.t
+ val reachable : ('k,'e,'info,'c) t -> id -> Dag.NodeSet.t
- (* read only dag *)
- module Dag : Dag.S with type node = id
- val dag : ('kind,'diff,'info) t -> ('diff,'info,id * id) Dag.t
- val create_cluster : ('k,'e,'i) t -> id list -> (id * id) -> ('k,'e,'i) t
- val cluster_of : ('k,'e,'i) t -> id -> (id * id) Dag.Cluster.t option
- val delete_cluster : ('k,'e,'i) t -> (id * id) Dag.Cluster.t -> ('k,'e,'i) t
-
end
-module Make(OT : Map.OrderedType) : S with type id = OT.t
+module Make(OT : Map.OrderedType) : S
+with type id = OT.t
+and type Dag.node = OT.t
+and type Dag.NodeSet.t = Set.Make(OT).t
+and type Dag.NodeSet.elt = OT.t
+
diff --git a/stm/vernac_classifier.ml b/stm/vernac_classifier.ml
index f9f08f7af..a602d6b8a 100644
--- a/stm/vernac_classifier.ml
+++ b/stm/vernac_classifier.ml
@@ -10,6 +10,8 @@ open Vernacexpr
open Errors
open Pp
+let default_proof_mode () = Proof_global.get_default_proof_mode_name ()
+
let string_of_in_script b = if b then " (inside script)" else ""
let string_of_vernac_type = function
@@ -19,8 +21,9 @@ let string_of_vernac_type = function
| VtQed VtKeep -> "Qed(keep)"
| VtQed VtKeepAsAxiom -> "Qed(admitted)"
| VtQed VtDrop -> "Qed(drop)"
- | VtProofStep false -> "ProofStep"
- | VtProofStep true -> "ProofStep (parallel)"
+ | VtProofStep { parallel; proof_block_detection } ->
+ "ProofStep " ^ if parallel then "par " else "" ^
+ Option.default "" proof_block_detection
| VtProofMode s -> "ProofMode " ^ s
| VtQuery (b,(id,route)) ->
"Query " ^ string_of_in_script b ^ " report " ^ Stateid.to_string id ^
@@ -91,7 +94,9 @@ let rec classify_vernac e =
(match classify_vernac e with
| ( VtQuery _ | VtProofStep _ | VtSideff _
| VtStm _ | VtProofMode _ ), _ as x -> x
- | VtQed _, _ -> VtProofStep false, VtNow
+ | VtQed _, _ ->
+ VtProofStep { parallel = false; proof_block_detection = None },
+ VtNow
| (VtStartProof _ | VtUnknown), _ -> VtUnknown, VtNow)
(* Qed *)
| VernacAbort _ -> VtQed VtDrop, VtLater
@@ -102,42 +107,47 @@ let rec classify_vernac e =
| VernacCheckMayEval _ ->
VtQuery (true,(Stateid.dummy,Feedback.default_route)), VtLater
(* ProofStep *)
- | VernacSolve (SelectAllParallel,_,_,_) -> VtProofStep true, VtLater
| VernacProof _
- | VernacBullet _
| VernacFocus _ | VernacUnfocus
- | VernacSubproof _ | VernacEndSubproof
- | VernacSolve _
+ | VernacSubproof _
| VernacCheckGuard
| VernacUnfocused
- | VernacSolveExistential _ -> VtProofStep false, VtLater
+ | VernacSolveExistential _ ->
+ VtProofStep { parallel = false; proof_block_detection = None }, VtLater
+ | VernacBullet _ ->
+ VtProofStep { parallel = false; proof_block_detection = Some "bullet" },
+ VtLater
+ | VernacEndSubproof ->
+ VtProofStep { parallel = false;
+ proof_block_detection = Some "curly" },
+ VtLater
(* Options changing parser *)
| VernacUnsetOption (["Default";"Proof";"Using"])
| VernacSetOption (["Default";"Proof";"Using"],_) -> VtSideff [], VtNow
(* StartProof *)
| VernacDefinition (
(Some Decl_kinds.Discharge,Decl_kinds.Definition),((_,i),_),ProveBody _) ->
- VtStartProof("Classic",Doesn'tGuaranteeOpacity,[i]), VtLater
+ VtStartProof(default_proof_mode (),Doesn'tGuaranteeOpacity,[i]), VtLater
| VernacDefinition (_,((_,i),_),ProveBody _) ->
- VtStartProof("Classic",GuaranteesOpacity,[i]), VtLater
+ VtStartProof(default_proof_mode (),GuaranteesOpacity,[i]), VtLater
| VernacStartTheoremProof (_,l,_) ->
let ids =
CList.map_filter (function (Some ((_,i),pl), _) -> Some i | _ -> None) l in
- VtStartProof ("Classic",GuaranteesOpacity,ids), VtLater
- | VernacGoal _ -> VtStartProof ("Classic",GuaranteesOpacity,[]), VtLater
+ VtStartProof (default_proof_mode (),GuaranteesOpacity,ids), VtLater
+ | VernacGoal _ -> VtStartProof (default_proof_mode (),GuaranteesOpacity,[]), VtLater
| VernacFixpoint (_,l) ->
let ids, open_proof =
List.fold_left (fun (l,b) ((((_,id),_),_,_,_,p),_) ->
id::l, b || p = None) ([],false) l in
if open_proof
- then VtStartProof ("Classic",GuaranteesOpacity,ids), VtLater
+ then VtStartProof (default_proof_mode (),GuaranteesOpacity,ids), VtLater
else VtSideff ids, VtLater
| VernacCoFixpoint (_,l) ->
let ids, open_proof =
List.fold_left (fun (l,b) ((((_,id),_),_,_,p),_) ->
id::l, b || p = None) ([],false) l in
if open_proof
- then VtStartProof ("Classic",GuaranteesOpacity,ids), VtLater
+ then VtStartProof (default_proof_mode (),GuaranteesOpacity,ids), VtLater
else VtSideff ids, VtLater
(* Sideff: apply to all open branches. usually run on master only *)
| VernacAssumption (_,_,l) ->
@@ -175,13 +185,6 @@ let rec classify_vernac e =
| VernacRegister _
| VernacNameSectionHypSet _
| VernacComments _ -> VtSideff [], VtLater
- | VernacDeclareTacticDefinition l ->
- let open Libnames in
- let open Vernacexpr in
- VtSideff (List.map (function
- | TacticDefinition ((_,r),_) -> r
- | TacticRedefinition (Ident (_,r),_) -> r
- | TacticRedefinition (Qualid (_,q),_) -> snd(repr_qualid q)) l), VtLater
(* Who knows *)
| VernacLoad _ -> VtSideff [], VtNow
(* (Local) Notations have to disappear *)
@@ -197,7 +200,6 @@ let rec classify_vernac e =
| VernacInfix _ | VernacNotation _ | VernacNotationAddFormat _
| VernacSyntaxExtension _
| VernacSyntacticDefinition _
- | VernacTacticNotation _
| VernacRequire _ | VernacImport _ | VernacInclude _
| VernacDeclareMLModule _
| VernacContext _ (* TASSI: unsure *)
@@ -227,4 +229,4 @@ let rec classify_vernac e =
let classify_as_query =
VtQuery (true,(Stateid.dummy,Feedback.default_route)), VtLater
let classify_as_sideeff = VtSideff [], VtLater
-let classify_as_proofstep = VtProofStep false, VtLater
+let classify_as_proofstep = VtProofStep { parallel = false; proof_block_detection = None}, VtLater
diff --git a/tactics/auto.ml b/tactics/auto.ml
index 761c41da6..e57b48e9e 100644
--- a/tactics/auto.ml
+++ b/tactics/auto.ml
@@ -140,8 +140,6 @@ si après Intros la conclusion matche le pattern.
(* conclPattern doit échouer avec error car il est rattraper par tclFIRST *)
-let (forward_interp_tactic, extern_interp) = Hook.make ()
-
let conclPattern concl pat tac =
let constr_bindings env sigma =
match pat with
@@ -156,7 +154,18 @@ let conclPattern concl pat tac =
let env = Proofview.Goal.env gl in
let sigma = Tacmach.New.project gl in
constr_bindings env sigma >>= fun constr_bindings ->
- Hook.get forward_interp_tactic constr_bindings tac
+ let open Genarg in
+ let open Geninterp in
+ let inj c = match val_tag (topwit Constrarg.wit_constr) with
+ | Val.Base tag -> Val.Dyn (tag, c)
+ | _ -> assert false
+ in
+ let fold id c accu = Id.Map.add id (inj c) accu in
+ let lfun = Id.Map.fold fold constr_bindings Id.Map.empty in
+ let ist = { lfun; extra = TacStore.empty } in
+ match tac with
+ | GenArg (Glbwit wit, tac) ->
+ Ftactic.run (Geninterp.interp wit ist tac) (fun _ -> Proofview.tclUNIT ())
end }
(***********************************************************)
@@ -220,11 +229,11 @@ let tclLOG (dbg,depth,trace) pp tac =
Proofview.V82.tactic begin fun gl ->
try
let out = Proofview.V82.of_tactic tac gl in
- msg_debug (str s ++ spc () ++ pp () ++ str ". (*success*)");
+ Feedback.msg_debug (str s ++ spc () ++ pp () ++ str ". (*success*)");
out
with reraise ->
let reraise = Errors.push reraise in
- msg_debug (str s ++ spc () ++ pp () ++ str ". (*fail*)");
+ Feedback.msg_debug (str s ++ spc () ++ pp () ++ str ". (*fail*)");
iraise reraise
end
| Info ->
@@ -280,10 +289,10 @@ let tclTRY_dbg d tac =
let delay f = Proofview.tclUNIT () >>= fun () -> f () in
let tac = match level with
| Off -> tac
- | Debug | Info -> delay (fun () -> msg_debug (pr_dbg_header d ++ fnl () ++ pr_info_trace d); tac)
+ | Debug | Info -> delay (fun () -> Feedback.msg_debug (pr_dbg_header d ++ fnl () ++ pr_info_trace d); tac)
in
let after = match level with
- | Info -> delay (fun () -> msg_debug (pr_info_nop d); Proofview.tclUNIT ())
+ | Info -> delay (fun () -> Feedback.msg_debug (pr_info_nop d); Proofview.tclUNIT ())
| Off | Debug -> Proofview.tclUNIT ()
in
Tacticals.New.tclORELSE0 tac after
diff --git a/tactics/auto.mli b/tactics/auto.mli
index cd2de99be..0fd95aead 100644
--- a/tactics/auto.mli
+++ b/tactics/auto.mli
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** This files implements auto and related automation tactics *)
+
open Names
open Term
open Clenv
@@ -13,11 +15,6 @@ open Pattern
open Decl_kinds
open Hints
-val extern_interp :
- (patvar_map -> Tacexpr.glob_tactic_expr -> unit Proofview.tactic) Hook.t
-
-(** Auto and related automation tactics *)
-
val priority : ('a * full_hint) list -> ('a * full_hint) list
val default_search_depth : int ref
@@ -35,7 +32,7 @@ val unify_resolve : polymorphic -> Unification.unify_flags -> (raw_hint * clause
[Pattern.somatches], then replace [?1] [?2] metavars in tacast by the
right values to build a tactic *)
-val conclPattern : constr -> constr_pattern option -> Tacexpr.glob_tactic_expr -> unit Proofview.tactic
+val conclPattern : constr -> constr_pattern option -> Genarg.glob_generic_argument -> unit Proofview.tactic
(** The Auto tactic *)
diff --git a/tactics/autorewrite.ml b/tactics/autorewrite.ml
index ea598b61c..9ae0ab90b 100644
--- a/tactics/autorewrite.ml
+++ b/tactics/autorewrite.ml
@@ -15,10 +15,8 @@ open Term
open Termops
open Errors
open Util
-open Tacexpr
open Mod_subst
open Locus
-open Sigma.Notations
open Proofview.Notations
(* Rewriting rules *)
@@ -27,13 +25,13 @@ type rew_rule = { rew_lemma: constr;
rew_pat: constr;
rew_ctx: Univ.universe_context_set;
rew_l2r: bool;
- rew_tac: glob_tactic_expr option }
+ rew_tac: Genarg.glob_generic_argument option }
let subst_hint subst hint =
let cst' = subst_mps subst hint.rew_lemma in
let typ' = subst_mps subst hint.rew_type in
let pat' = subst_mps subst hint.rew_pat in
- let t' = Option.smartmap (Tacsubst.subst_tactic subst) hint.rew_tac in
+ let t' = Option.smartmap (Genintern.generic_substitute subst) hint.rew_tac in
if hint.rew_lemma == cst' && hint.rew_type == typ' && hint.rew_tac == t' then hint else
{ hint with
rew_lemma = cst'; rew_type = typ';
@@ -85,10 +83,10 @@ let print_rewrite_hintdb bas =
str (if h.rew_l2r then "rewrite -> " else "rewrite <- ") ++
Printer.pr_lconstr h.rew_lemma ++ str " of type " ++ Printer.pr_lconstr h.rew_type ++
Option.cata (fun tac -> str " then use tactic " ++
- Pptactic.pr_glob_tactic (Global.env()) tac) (mt ()) h.rew_tac)
+ Pptactic.pr_glb_generic (Global.env()) tac) (mt ()) h.rew_tac)
(find_rewrites bas))
-type raw_rew_rule = Loc.t * constr Univ.in_universe_context_set * bool * raw_tactic_expr option
+type raw_rew_rule = Loc.t * constr Univ.in_universe_context_set * bool * Genarg.raw_generic_argument option
(* Applies all the rules of one base *)
let one_base general_rewrite_maybe_in tac_main bas =
@@ -104,7 +102,12 @@ let one_base general_rewrite_maybe_in tac_main bas =
Sigma.Unsafe.of_pair (tac, sigma)
end } in
let lrul = List.map (fun h ->
- let tac = match h.rew_tac with None -> Proofview.tclUNIT () | Some t -> Tacinterp.eval_tactic t in
+ let tac = match h.rew_tac with
+ | None -> Proofview.tclUNIT ()
+ | Some (Genarg.GenArg (Genarg.Glbwit wit, tac)) ->
+ let ist = { Geninterp.lfun = Id.Map.empty; extra = Geninterp.TacStore.empty } in
+ Ftactic.run (Geninterp.interp wit ist tac) (fun _ -> Proofview.tclUNIT ())
+ in
(h.rew_ctx,h.rew_lemma,h.rew_l2r,tac)) lrul in
Tacticals.New.tclREPEAT_MAIN (Proofview.tclPROGRESS (List.fold_left (fun tac (ctx,csr,dir,tc) ->
Tacticals.New.tclTHEN tac
@@ -148,7 +151,7 @@ let autorewrite_multi_in ?(conds=Naive) idl tac_main lbas =
begin
let gl'' =
if !to_be_cleared then
- tclTHEN (fun _ -> gl') (tclTRY (clear [!id])) gl
+ tclTHEN (fun _ -> gl') (tclTRY (Proofview.V82.of_tactic (clear [!id]))) gl
else gl' in
id := lastid ;
to_be_cleared := true ;
@@ -300,6 +303,8 @@ let add_rew_rules base lrul =
let counter = ref 0 in
let env = Global.env () in
let sigma = Evd.from_env env in
+ let ist = { Genintern.ltacvars = Id.Set.empty; genv = Global.env () } in
+ let intern tac = snd (Genintern.generic_intern ist tac) in
let lrul =
List.fold_left
(fun dn (loc,(c,ctx),b,t) ->
@@ -308,7 +313,7 @@ let add_rew_rules base lrul =
let pat = if b then info.hyp_left else info.hyp_right in
let rul = { rew_lemma = c; rew_type = info.hyp_ty;
rew_pat = pat; rew_ctx = ctx; rew_l2r = b;
- rew_tac = Option.map Tacintern.glob_tactic t}
+ rew_tac = Option.map intern t}
in incr counter;
HintDN.add pat (!counter, rul) dn) HintDN.empty lrul
in Lib.add_anonymous_leaf (inHintRewrite (base,lrul))
diff --git a/tactics/autorewrite.mli b/tactics/autorewrite.mli
index 6196b04e1..070657179 100644
--- a/tactics/autorewrite.mli
+++ b/tactics/autorewrite.mli
@@ -6,12 +6,14 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** This files implements the autorewrite tactic. *)
+
open Term
open Tacexpr
open Equality
(** Rewriting rules before tactic interpretation *)
-type raw_rew_rule = Loc.t * Term.constr Univ.in_universe_context_set * bool * Tacexpr.raw_tactic_expr option
+type raw_rew_rule = Loc.t * constr Univ.in_universe_context_set * bool * Genarg.raw_generic_argument option
(** To add rewriting rules to a base *)
val add_rew_rules : string -> raw_rew_rule list -> unit
@@ -29,7 +31,7 @@ type rew_rule = { rew_lemma: constr;
rew_pat: constr;
rew_ctx: Univ.universe_context_set;
rew_l2r: bool;
- rew_tac: glob_tactic_expr option }
+ rew_tac: Genarg.glob_generic_argument option }
val find_rewrites : string -> rew_rule list
diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml
index 485559898..0172d28c5 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -164,7 +164,7 @@ let e_give_exact flags poly (c,clenv) gl =
else c, gl
in
let t1 = pf_unsafe_type_of gl c in
- tclTHEN (Proofview.V82.of_tactic (Clenvtac.unify ~flags t1)) (exact_no_check c) gl
+ Proofview.V82.of_tactic (Clenvtac.unify ~flags t1 <*> exact_no_check c) gl
let unify_e_resolve poly flags = { enter = begin fun gls (c,clenv) ->
let clenv', c = connect_hint_clenv poly c clenv gls in
@@ -455,7 +455,7 @@ let hints_tac hints =
| None -> aux i foundone tl
| Some {it = gls; sigma = s';} ->
if !typeclasses_debug then
- msg_debug (pr_depth (i :: info.auto_depth) ++ str": " ++ Lazy.force pp
+ Feedback.msg_debug (pr_depth (i :: info.auto_depth) ++ str": " ++ Lazy.force pp
++ str" on" ++ spc () ++ pr_ev s gl);
let sgls =
evars_to_goals
@@ -504,7 +504,7 @@ let hints_tac hints =
in
let e' = match foundone with None -> e | Some e' -> merge_failures e e' in
if !typeclasses_debug then
- msg_debug
+ Feedback.msg_debug
((if do_backtrack then str"Backtracking after "
else str "Not backtracking after ")
++ Lazy.force pp);
@@ -514,7 +514,7 @@ let hints_tac hints =
sk glsv fk')
| [] ->
if foundone == None && !typeclasses_debug then
- msg_debug (pr_depth info.auto_depth ++ str": no match for " ++
+ Feedback.msg_debug (pr_depth info.auto_depth ++ str": no match for " ++
Printer.pr_constr_env (Goal.V82.env s gl) s concl ++
spc () ++ str ", " ++ int (List.length poss) ++ str" possibilities");
match foundone with
@@ -851,6 +851,15 @@ let set_typeclasses_debug =
optread = get_typeclasses_debug;
optwrite = set_typeclasses_debug; }
+let set_typeclasses_debug =
+ declare_bool_option
+ { optsync = true;
+ optdepr = false;
+ optname = "debug output for typeclasses proof search";
+ optkey = ["Debug";"Typeclasses"];
+ optread = get_typeclasses_debug;
+ optwrite = set_typeclasses_debug; }
+
let set_typeclasses_depth =
declare_int_option
{ optsync = true;
diff --git a/tactics/class_tactics.mli b/tactics/class_tactics.mli
index f1bcfa7dd..cac4b8844 100644
--- a/tactics/class_tactics.mli
+++ b/tactics/class_tactics.mli
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** This files implements typeclasses eauto *)
+
open Names
open Constr
open Tacmach
diff --git a/tactics/contradiction.ml b/tactics/contradiction.ml
index ab6fb37fd..26166bd83 100644
--- a/tactics/contradiction.ml
+++ b/tactics/contradiction.ml
@@ -6,14 +6,12 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Errors
open Term
open Hipattern
open Tactics
open Coqlib
open Reductionops
open Misctypes
-open Sigma.Notations
open Proofview.Notations
open Context.Named.Declaration
diff --git a/tactics/eauto.ml4 b/tactics/eauto.ml
index f2d26ec86..2cae9b794 100644
--- a/tactics/eauto.ml4
+++ b/tactics/eauto.ml
@@ -6,8 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i camlp4deps: "grammar/grammar.cma" i*)
-
open Pp
open Errors
open Util
@@ -19,19 +17,15 @@ open Proof_type
open Tacticals
open Tacmach
open Tactics
-open Patternops
open Clenv
open Auto
open Genredexpr
open Tacexpr
-open Misctypes
open Locus
open Locusops
open Hints
open Proofview.Notations
-DECLARE PLUGIN "eauto"
-
let eauto_unif_flags = auto_flags_of_state full_transparent_state
let e_give_exact ?(flags=eauto_unif_flags) c =
@@ -39,7 +33,7 @@ let e_give_exact ?(flags=eauto_unif_flags) c =
let t1 = Tacmach.New.pf_unsafe_type_of gl c in
let t2 = Tacmach.New.pf_concl gl in
if occur_existential t1 || occur_existential t2 then
- Tacticals.New.tclTHEN (Clenvtac.unify ~flags t1) (Proofview.V82.tactic (exact_no_check c))
+ Tacticals.New.tclTHEN (Clenvtac.unify ~flags t1) (exact_no_check c)
else exact_check c
end }
@@ -50,30 +44,12 @@ let e_assumption =
Tacticals.New.tclFIRST (List.map assumption (Tacmach.New.pf_ids_of_hyps gl))
end }
-TACTIC EXTEND eassumption
-| [ "eassumption" ] -> [ e_assumption ]
-END
-
-TACTIC EXTEND eexact
-| [ "eexact" constr(c) ] -> [ e_give_exact c ]
-END
-
let registered_e_assumption =
Proofview.Goal.enter { enter = begin fun gl ->
Tacticals.New.tclFIRST (List.map (fun id -> e_give_exact (mkVar id))
(Tacmach.New.pf_ids_of_hyps gl))
end }
-let eval_uconstrs ist cs =
- let flags = {
- Pretyping.use_typeclasses = false;
- use_unif_heuristics = true;
- use_hook = Some Pfedit.solve_by_implicit_tactic;
- fail_evar = false;
- expand_evars = true
- } in
- List.map (fun c -> Tacinterp.type_uconstr ~flags ist c) cs
-
(************************************************************************)
(* PROLOG tactic *)
(************************************************************************)
@@ -112,7 +88,8 @@ let out_term = function
| IsConstr (c, _) -> c
| IsGlobRef gr -> fst (Universes.fresh_global_instance (Global.env ()) gr)
-let prolog_tac l n gl =
+let prolog_tac l n =
+ Proofview.V82.tactic begin fun gl ->
let map c =
let (c, sigma) = Tactics.run_delayed (pf_env gl) (project gl) c in
let c = pf_apply (prepare_hint false (false,true)) gl (sigma, c) in
@@ -122,14 +99,9 @@ let prolog_tac l n gl =
try (prolog l n gl)
with UserError ("Refiner.tclFIRST",_) ->
errorlabstrm "Prolog.prolog" (str "Prolog failed.")
-
-TACTIC EXTEND prolog
-| [ "prolog" "[" uconstr_list(l) "]" int_or_var(n) ] ->
- [ Proofview.V82.tactic (prolog_tac (eval_uconstrs ist l) n) ]
-END
+ end
open Auto
-open Unification
(***************************************************************************)
(* A tactic similar to Auto, but using EApply, Assumption and e_give_exact *)
@@ -372,13 +344,13 @@ let mk_eauto_dbg d =
else Off
let pr_info_nop = function
- | Info -> msg_debug (str "idtac.")
+ | Info -> Feedback.msg_debug (str "idtac.")
| _ -> ()
let pr_dbg_header = function
| Off -> ()
- | Debug -> msg_debug (str "(* debug eauto : *)")
- | Info -> msg_debug (str "(* info eauto : *)")
+ | Debug -> Feedback.msg_debug (str "(* debug eauto : *)")
+ | Info -> Feedback.msg_debug (str "(* info eauto : *)")
let pr_info dbg s =
if dbg != Info then ()
@@ -389,7 +361,7 @@ let pr_info dbg s =
| State sp ->
let mindepth = loop sp in
let indent = String.make (mindepth - sp.depth) ' ' in
- msg_debug (str indent ++ Lazy.force s.last_tactic ++ str ".");
+ Feedback.msg_debug (str indent ++ Lazy.force s.last_tactic ++ str ".");
mindepth
in
ignore (loop s)
@@ -442,8 +414,8 @@ let full_eauto ?(debug=Off) n lems gl =
tclTRY (e_search_auto debug n lems db_list) gl
let gen_eauto ?(debug=Off) np lems = function
- | None -> full_eauto ~debug np lems
- | Some l -> eauto ~debug np lems l
+ | None -> Proofview.V82.tactic (full_eauto ~debug np lems)
+ | Some l -> Proofview.V82.tactic (eauto ~debug np lems l)
let make_depth = function
| None -> !default_search_depth
@@ -453,44 +425,6 @@ let make_dimension n = function
| None -> (true,make_depth n)
| Some d -> (false,d)
-open Genarg
-open G_auto
-
-let hintbases = G_auto.hintbases
-let wit_hintbases = G_auto.wit_hintbases
-
-TACTIC EXTEND eauto
-| [ "eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
- hintbases(db) ] ->
- [ Proofview.V82.tactic (gen_eauto (make_dimension n p) (eval_uconstrs ist lems) db) ]
-END
-
-TACTIC EXTEND new_eauto
-| [ "new" "auto" int_or_var_opt(n) auto_using(lems)
- hintbases(db) ] ->
- [ match db with
- | None -> new_full_auto (make_depth n) (eval_uconstrs ist lems)
- | Some l -> new_auto (make_depth n) (eval_uconstrs ist lems) l ]
-END
-
-TACTIC EXTEND debug_eauto
-| [ "debug" "eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
- hintbases(db) ] ->
- [ Proofview.V82.tactic (gen_eauto ~debug:Debug (make_dimension n p) (eval_uconstrs ist lems) db) ]
-END
-
-TACTIC EXTEND info_eauto
-| [ "info_eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
- hintbases(db) ] ->
- [ Proofview.V82.tactic (gen_eauto ~debug:Info (make_dimension n p) (eval_uconstrs ist lems) db) ]
-END
-
-TACTIC EXTEND dfs_eauto
-| [ "dfs" "eauto" int_or_var_opt(p) auto_using(lems)
- hintbases(db) ] ->
- [ Proofview.V82.tactic (gen_eauto (true, make_depth p) (eval_uconstrs ist lems) db) ]
-END
-
let cons a l = a :: l
let autounfolds db occs cls gl =
@@ -505,25 +439,24 @@ let autounfolds db occs cls gl =
(Id.Set.fold (fun id -> cons (AllOccurrences, EvalVarRef id)) ids [])) db)
in Proofview.V82.of_tactic (unfold_option unfolds cls) gl
-let autounfold db cls gl =
+let autounfold db cls =
+ Proofview.V82.tactic begin fun gl ->
let cls = concrete_clause_of (fun () -> pf_ids_of_hyps gl) cls in
let tac = autounfolds db in
tclMAP (function
| OnHyp (id,occs,where) -> tac occs (Some (id,where))
| OnConcl occs -> tac occs None)
cls gl
+ end
-let autounfold_tac db cls gl =
+let autounfold_tac db cls =
+ Proofview.tclUNIT () >>= fun () ->
let dbs = match db with
| None -> String.Set.elements (current_db_names ())
| Some [] -> ["core"]
| Some l -> l
in
- autounfold dbs cls gl
-
-TACTIC EXTEND autounfold
-| [ "autounfold" hintbases(db) clause(cl) ] -> [ Proofview.V82.tactic (autounfold_tac db cl) ]
-END
+ autounfold dbs cls
let unfold_head env (ids, csts) c =
let rec aux c =
@@ -578,90 +511,3 @@ let autounfold_one db cl =
| None -> convert_concl_no_check c' DEFAULTcast
else Tacticals.New.tclFAIL 0 (str "Nothing to unfold")
end }
-
-(* Cset.fold (fun cst -> cons (all_occurrences, EvalConstRef cst)) csts *)
-(* (Id.Set.fold (fun id -> cons (all_occurrences, EvalVarRef id)) ids [])) db) *)
-(* in unfold_option unfolds cl *)
-
-(* let db = try searchtable_map dbname *)
-(* with Not_found -> errorlabstrm "autounfold" (str "Unknown database " ++ str dbname) *)
-(* in *)
-(* let (ids, csts) = Hint_db.unfolds db in *)
-(* Cset.fold (fun cst -> tclORELSE (unfold_option [(occ, EvalVarRef id)] cst)) csts *)
-(* (Id.Set.fold (fun id -> tclORELSE (unfold_option [(occ, EvalVarRef id)] cl) ids acc))) *)
-(* (tclFAIL 0 (mt())) db *)
-
-TACTIC EXTEND autounfold_one
-| [ "autounfold_one" hintbases(db) "in" hyp(id) ] ->
- [ autounfold_one (match db with None -> ["core"] | Some x -> "core"::x) (Some (id, InHyp)) ]
-| [ "autounfold_one" hintbases(db) ] ->
- [ autounfold_one (match db with None -> ["core"] | Some x -> "core"::x) None ]
- END
-
-TACTIC EXTEND autounfoldify
-| [ "autounfoldify" constr(x) ] -> [
- Proofview.V82.tactic (
- let db = match kind_of_term x with
- | Const (c,_) -> Label.to_string (con_label c)
- | _ -> assert false
- in autounfold ["core";db] onConcl
- )]
-END
-
-TACTIC EXTEND unify
-| ["unify" constr(x) constr(y) ] -> [ unify x y ]
-| ["unify" constr(x) constr(y) "with" preident(base) ] -> [
- let table = try Some (searchtable_map base) with Not_found -> None in
- match table with
- | None ->
- let msg = str "Hint table " ++ str base ++ str " not found" in
- Tacticals.New.tclZEROMSG msg
- | Some t ->
- let state = Hint_db.transparent_state t in
- unify ~state x y
- ]
-END
-
-
-TACTIC EXTEND convert_concl_no_check
-| ["convert_concl_no_check" constr(x) ] -> [ convert_concl_no_check x DEFAULTcast ]
-END
-
-let pr_hints_path_atom _ _ _ = Hints.pp_hints_path_atom
-
-ARGUMENT EXTEND hints_path_atom
- TYPED AS hints_path_atom
- PRINTED BY pr_hints_path_atom
-| [ global_list(g) ] -> [ PathHints (List.map Nametab.global g) ]
-| [ "*" ] -> [ PathAny ]
-END
-
-let pr_hints_path prc prx pry c = Hints.pp_hints_path c
-
-ARGUMENT EXTEND hints_path
- TYPED AS hints_path
- PRINTED BY pr_hints_path
-| [ "(" hints_path(p) ")" ] -> [ p ]
-| [ "!" hints_path(p) ] -> [ PathStar p ]
-| [ "emp" ] -> [ PathEmpty ]
-| [ "eps" ] -> [ PathEpsilon ]
-| [ hints_path_atom(a) ] -> [ PathAtom a ]
-| [ hints_path(p) "|" hints_path(q) ] -> [ PathOr (p, q) ]
-| [ hints_path(p) ";" hints_path(q) ] -> [ PathSeq (p, q) ]
-END
-
-let pr_hintbases _prc _prlc _prt = Pptactic.pr_hintbases
-
-ARGUMENT EXTEND opthints
- TYPED AS preident_list_opt
- PRINTED BY pr_hintbases
-| [ ":" ne_preident_list(l) ] -> [ Some l ]
-| [ ] -> [ None ]
-END
-
-VERNAC COMMAND EXTEND HintCut CLASSIFIED AS SIDEFF
-| [ "Hint" "Cut" "[" hints_path(p) "]" opthints(dbnames) ] -> [
- let entry = HintsCutEntry p in
- Hints.add_hints (Locality.make_section_locality (Locality.LocalityFixme.consume ()))
- (match dbnames with None -> ["core"] | Some l -> l) entry ]
-END
diff --git a/tactics/eauto.mli b/tactics/eauto.mli
index 0a490c65d..8812093d5 100644
--- a/tactics/eauto.mli
+++ b/tactics/eauto.mli
@@ -10,22 +10,24 @@ open Term
open Proof_type
open Hints
-val hintbases : hint_db_name list option Pcoq.Gram.entry
-
-val wit_hintbases : hint_db_name list option Genarg.uniform_genarg_type
-
val e_assumption : unit Proofview.tactic
val registered_e_assumption : unit Proofview.tactic
val e_give_exact : ?flags:Unification.unify_flags -> constr -> unit Proofview.tactic
+val prolog_tac : Tacexpr.delayed_open_constr list -> int -> unit Proofview.tactic
+
val gen_eauto : ?debug:Tacexpr.debug -> bool * int -> Tacexpr.delayed_open_constr list ->
- hint_db_name list option -> tactic
+ hint_db_name list option -> unit Proofview.tactic
val eauto_with_bases :
?debug:Tacexpr.debug ->
bool * int ->
Tacexpr.delayed_open_constr list -> hint_db list -> Proof_type.tactic
-val autounfold : hint_db_name list -> Locus.clause -> tactic
+val autounfold : hint_db_name list -> Locus.clause -> unit Proofview.tactic
+val autounfold_tac : hint_db_name list option -> Locus.clause -> unit Proofview.tactic
+val autounfold_one : hint_db_name list -> Locus.hyp_location option -> unit Proofview.tactic
+
+val make_dimension : int option -> int option -> bool * int
diff --git a/tactics/elim.ml b/tactics/elim.ml
index d441074f6..d59c2fba4 100644
--- a/tactics/elim.ml
+++ b/tactics/elim.ml
@@ -63,7 +63,7 @@ and general_decompose_aux recognizer id =
elimHypThen
(introElimAssumsThen
(fun bas ->
- tclTHEN (Proofview.V82.tactic (clear [id]))
+ tclTHEN (clear [id])
(tclMAP (general_decompose_on_hyp recognizer)
(ids_of_named_context bas.Tacticals.assums))))
id
@@ -83,8 +83,8 @@ let general_decompose recognizer c =
[ tclTHEN (intro_using tmphyp_name)
(onLastHypId
(ifOnHyp recognizer (general_decompose_aux recognizer)
- (fun id -> Proofview.V82.tactic (clear [id]))));
- Proofview.V82.tactic (exact_no_check c) ]
+ (fun id -> clear [id])));
+ exact_no_check c ]
end }
let head_in indl t gl =
diff --git a/tactics/eqdecide.ml b/tactics/eqdecide.ml
index 7c821ddcb..b1d3290aa 100644
--- a/tactics/eqdecide.ml
+++ b/tactics/eqdecide.ml
@@ -12,9 +12,6 @@
(* by Eduardo Gimenez *)
(************************************************************************)
-(*i camlp4deps: "grammar/grammar.cma" i*)
-
-open Errors
open Util
open Names
open Namegen
@@ -24,10 +21,11 @@ open Tactics
open Tacticals.New
open Auto
open Constr_matching
+open Misctypes
open Hipattern
+open Pretyping
open Tacmach.New
open Coqlib
-open Proofview.Notations
(* This file containts the implementation of the tactics ``Decide
Equality'' and ``Compare''. They can be used to decide the
@@ -51,7 +49,6 @@ open Proofview.Notations
Eduardo Gimenez (30/3/98).
*)
-let clear ids = Proofview.V82.tactic (clear ids)
let clear_last = (onLastHyp (fun c -> (clear [destVar c])))
let choose_eq eqonleft =
@@ -67,17 +64,22 @@ let choose_noteq eqonleft =
let mkBranches c1 c2 =
tclTHENLIST
- [Proofview.V82.tactic (generalize [c2]);
+ [generalize [c2];
Simple.elim c1;
intros;
onLastHyp Simple.case;
clear_last;
intros]
+let discrHyp id =
+ let c = { delayed = fun env sigma -> Sigma.here (Term.mkVar id, NoBindings) sigma } in
+ let tac c = Equality.discr_tac false (Some (None, Tacexpr.ElimOnConstr c)) in
+ Tacticals.New.tclDELAYEDWITHHOLES false c tac
+
let solveNoteqBranch side =
tclTHEN (choose_noteq side)
(tclTHEN introf
- (onLastHypId (fun id -> Extratactics.discrHyp id)))
+ (onLastHypId (fun id -> discrHyp id)))
(* Constructs the type {c1=c2}+{~c1=c2} *)
@@ -117,6 +119,11 @@ let rec rewrite_and_clear hyps = match hyps with
let eqCase tac =
tclTHEN intro (onLastHypId tac)
+let injHyp id =
+ let c = { delayed = fun env sigma -> Sigma.here (Term.mkVar id, NoBindings) sigma } in
+ let tac c = Equality.injClause None false (Some (None, Tacexpr.ElimOnConstr c)) in
+ Tacticals.New.tclDELAYEDWITHHOLES false c tac
+
let diseqCase hyps eqonleft =
let diseq = Id.of_string "diseq" in
let absurd = Id.of_string "absurd" in
@@ -126,7 +133,7 @@ let diseqCase hyps eqonleft =
(tclTHEN (red_in_concl)
(tclTHEN (intro_using absurd)
(tclTHEN (Simple.apply (mkVar diseq))
- (tclTHEN (Extratactics.injHyp absurd)
+ (tclTHEN (injHyp absurd)
(full_trivial []))))))))
open Proofview.Notations
diff --git a/tactics/equality.ml b/tactics/equality.ml
index 453f81af5..12d31d0f3 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -79,8 +79,6 @@ let _ =
(* Rewriting tactics *)
-let clear ids = Proofview.V82.tactic (clear ids)
-
let tclNOTSAMEGOAL tac =
Proofview.V82.tactic (Tacticals.tclNOTSAMEGOAL (Proofview.V82.of_tactic tac))
@@ -231,7 +229,7 @@ let rewrite_keyed_core_unif_flags = {
restrict_conv_on_strict_subterms = false;
modulo_betaiota = true;
- (* Different from conv_closed *)
+
modulo_eta = true;
}
@@ -861,13 +859,13 @@ let descend_then env sigma head dirn =
*)
-(* [construct_discriminator env dirn headval]
- constructs a case-split on [headval], with the [dirn]-th branch
- giving [True], and all the rest giving False. *)
+(* [construct_discriminator env sigma dirn c ind special default]]
+ constructs a case-split on [c] of type [ind], with the [dirn]-th
+ branch giving [special], and all the rest giving [default]. *)
-let construct_discriminator env sigma dirn c sort =
+let build_selector env sigma dirn c ind special default =
let IndType(indf,_) =
- try find_rectype env sigma (get_type_of env sigma c)
+ try find_rectype env sigma ind
with Not_found ->
(* one can find Rel(k) in case of dependent constructors
like T := c : (A:Set)A->T and a discrimination
@@ -879,25 +877,29 @@ let construct_discriminator env sigma dirn c sort =
dependent types.") in
let (indp,_) = dest_ind_family indf in
let ind, _ = check_privacy env indp in
+ let typ = Retyping.get_type_of env sigma default in
let (mib,mip) = lookup_mind_specif env ind in
- let (true_0,false_0,sort_0) = build_coq_True(),build_coq_False(),Prop Null in
let deparsign = make_arity_signature env true indf in
- let p = it_mkLambda_or_LetIn (mkSort sort_0) deparsign in
+ let p = it_mkLambda_or_LetIn typ deparsign in
let cstrs = get_constructors env indf in
let build_branch i =
- let endpt = if Int.equal i dirn then true_0 else false_0 in
+ let endpt = if Int.equal i dirn then special else default in
it_mkLambda_or_LetIn endpt cstrs.(i-1).cs_args in
let brl =
List.map build_branch(List.interval 1 (Array.length mip.mind_consnames)) in
let ci = make_case_info env ind RegularStyle in
mkCase (ci, p, c, Array.of_list brl)
-let rec build_discriminator env sigma dirn c sort = function
- | [] -> construct_discriminator env sigma dirn c sort
+let rec build_discriminator env sigma dirn c = function
+ | [] ->
+ let ind = get_type_of env sigma c in
+ let true_0,false_0 =
+ build_coq_True(),build_coq_False() in
+ build_selector env sigma dirn c ind true_0 false_0
| ((sp,cnum),argnum)::l ->
let (cnum_nlams,cnum_env,kont) = descend_then env sigma c cnum in
let newc = mkRel(cnum_nlams-argnum) in
- let subval = build_discriminator cnum_env sigma dirn newc sort l in
+ let subval = build_discriminator cnum_env sigma dirn newc l in
kont subval (build_coq_False (),mkSort (Prop Null))
(* Note: discrimination could be more clever: if some elimination is
@@ -959,11 +961,11 @@ let apply_on_clause (f,t) clause =
| _ -> errorlabstrm "" (str "Ill-formed clause applicator.")) in
clenv_fchain ~with_univs:false argmv f_clause clause
-let discr_positions env sigma (lbeq,eqn,(t,t1,t2)) eq_clause cpath dirn sort =
+let discr_positions env sigma (lbeq,eqn,(t,t1,t2)) eq_clause cpath dirn =
let e = next_ident_away eq_baseid (ids_of_context env) in
let e_env = push_named (Context.Named.Declaration.LocalAssum (e,t)) env in
let discriminator =
- build_discriminator e_env sigma dirn (mkVar e) sort cpath in
+ build_discriminator e_env sigma dirn (mkVar e) cpath in
let sigma,(pf, absurd_term), eff =
discrimination_pf env sigma e (t,t1,t2) discriminator lbeq in
let pf_ty = mkArrow eqn absurd_term in
@@ -972,19 +974,17 @@ let discr_positions env sigma (lbeq,eqn,(t,t1,t2)) eq_clause cpath dirn sort =
Proofview.Unsafe.tclEVARS sigma <*>
Proofview.tclEFFECTS eff <*>
tclTHENS (assert_after Anonymous absurd_term)
- [onLastHypId gen_absurdity; (Proofview.V82.tactic (refine pf))]
+ [onLastHypId gen_absurdity; (Proofview.V82.tactic (Tacmach.refine pf))]
let discrEq (lbeq,_,(t,t1,t2) as u) eq_clause =
let sigma = eq_clause.evd in
Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let concl = Proofview.Goal.concl gl in
match find_positions env sigma t1 t2 with
| Inr _ ->
tclZEROMSG (str"Not a discriminable equality.")
| Inl (cpath, (_,dirn), _) ->
- let sort = pf_apply get_type_of gl concl in
- discr_positions env sigma u eq_clause cpath dirn sort
+ discr_positions env sigma u eq_clause cpath dirn
end }
let onEquality with_evars tac (c,lbindc) =
@@ -1316,7 +1316,7 @@ let inject_if_homogenous_dependent_pair ty =
onLastHyp (fun hyp ->
tclTHENS (cut (mkApp (ceq,new_eq_args)))
[clear [destVar hyp];
- Proofview.V82.tactic (refine
+ Proofview.V82.tactic (Tacmach.refine
(mkApp(inj2,[|ar1.(0);mkConst c;ar1.(1);ar1.(2);ar1.(3);ar2.(3);hyp|])))
])]
with Exit ->
@@ -1362,7 +1362,7 @@ let inject_at_positions env sigma l2r (eq,_,(t,t1,t2)) eq_clause posns tac =
(Proofview.tclIGNORE (Proofview.Monad.List.map
(fun (pf,ty) -> tclTHENS (cut ty)
[inject_if_homogenous_dependent_pair ty;
- Proofview.V82.tactic (refine pf)])
+ Proofview.V82.tactic (Tacmach.refine pf)])
(if l2r then List.rev injectors else injectors)))
(tac (List.length injectors)))
@@ -1414,12 +1414,11 @@ let injHyp clear_flag id = injClause None false (Some (clear_flag,ElimOnIdent (L
let decompEqThen ntac (lbeq,_,(t,t1,t2) as u) clause =
Proofview.Goal.nf_enter { enter = begin fun gl ->
- let sort = pf_apply get_type_of gl (Proofview.Goal.concl gl) in
let sigma = clause.evd in
let env = Proofview.Goal.env gl in
match find_positions env sigma t1 t2 with
| Inl (cpath, (_,dirn), _) ->
- discr_positions env sigma u clause cpath dirn sort
+ discr_positions env sigma u clause cpath dirn
| Inr [] -> (* Change: do not fail, simplify clear this trivial hyp *)
ntac (clenv_value clause) 0
| Inr posns ->
@@ -1583,7 +1582,7 @@ let substClause l2r c cls =
Proofview.Goal.enter { enter = begin fun gl ->
let eq = pf_apply get_type_of gl c in
tclTHENS (cutSubstClause l2r eq cls)
- [Proofview.tclUNIT (); Proofview.V82.tactic (exact_no_check c)]
+ [Proofview.tclUNIT (); exact_no_check c]
end }
let rewriteClause l2r c cls = try_rewrite (substClause l2r c cls)
@@ -1609,6 +1608,17 @@ user = raise user error specific to rewrite
(**********************************************************************)
(* Substitutions tactics (JCF) *)
+let regular_subst_tactic = ref true
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optdepr = false;
+ optname = "more regular behavior of tactic subst";
+ optkey = ["Regular";"Subst";"Tactic"];
+ optread = (fun () -> !regular_subst_tactic);
+ optwrite = (:=) regular_subst_tactic }
+
let restrict_to_eq_and_identity eq = (* compatibility *)
if not (is_global glob_eq eq) &&
not (is_global glob_identity eq)
@@ -1637,24 +1647,25 @@ let subst_one dep_proof_ok x (hyp,rhs,dir) =
let concl = Proofview.Goal.concl (Proofview.Goal.assume gl) in
(* The set of hypotheses using x *)
let dephyps =
- List.rev (snd (List.fold_right (fun dcl (deps,allhyps) ->
+ List.rev (pi3 (List.fold_right (fun dcl (dest,deps,allhyps) ->
let id = get_id dcl in
if not (Id.equal id hyp)
&& List.exists (fun y -> occur_var_in_decl env y dcl) deps
then
- ((if is_local_assum dcl then deps else id::deps), id::allhyps)
+ let id_dest = if !regular_subst_tactic then dest else MoveLast in
+ (dest,(if is_local_assum dcl then deps else id::deps), (id_dest,id)::allhyps)
else
- (deps,allhyps))
+ (MoveBefore id,deps,allhyps))
hyps
- ([x],[]))) in
+ (MoveBefore x,[x],[]))) in (* In practice, no dep hyps before x, so MoveBefore x is good enough *)
(* Decides if x appears in conclusion *)
let depconcl = occur_var env x concl in
let need_rewrite = not (List.is_empty dephyps) || depconcl in
tclTHENLIST
((if need_rewrite then
- [revert dephyps;
+ [revert (List.map snd dephyps);
general_rewrite dir AllOccurrences true dep_proof_ok (mkVar hyp);
- (tclMAP intro_using dephyps)]
+ (tclMAP (fun (dest,id) -> intro_move (Some id) dest) dephyps)]
else
[Proofview.tclUNIT ()]) @
[tclTRY (clear [x; hyp])])
@@ -1705,17 +1716,6 @@ let default_subst_tactic_flags () =
else
{ only_leibniz = true; rewrite_dependent_proof = false }
-let regular_subst_tactic = ref true
-
-let _ =
- declare_bool_option
- { optsync = true;
- optdepr = false;
- optname = "more regular behavior of tactic subst";
- optkey = ["Regular";"Subst";"Tactic"];
- optread = (fun () -> !regular_subst_tactic);
- optwrite = (:=) regular_subst_tactic }
-
let subst_all ?(flags=default_subst_tactic_flags ()) () =
if !regular_subst_tactic then
diff --git a/tactics/equality.mli b/tactics/equality.mli
index f84dafb31..458d8f372 100644
--- a/tactics/equality.mli
+++ b/tactics/equality.mli
@@ -117,3 +117,8 @@ val subst_all : ?flags:subst_tactic_flags -> unit -> unit Proofview.tactic
val replace_term : bool option -> constr -> clause -> unit Proofview.tactic
val set_eq_dec_scheme_kind : mutual scheme_kind -> unit
+
+(* [build_selector env sigma i c t u v] matches on [c] of
+ type [t] and returns [u] in branch [i] and [v] on other branches *)
+val build_selector : env -> evar_map -> int -> constr -> types ->
+ constr -> constr -> constr
diff --git a/tactics/g_auto.ml4 b/tactics/g_auto.ml4
deleted file mode 100644
index 3a2cee9f7..000000000
--- a/tactics/g_auto.ml4
+++ /dev/null
@@ -1,76 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(*i camlp4deps: "grammar/grammar.cma" i*)
-
-open Pp
-open Genarg
-open Tacexpr
-
-DECLARE PLUGIN "g_auto"
-
-(* Hint bases *)
-
-let pr_hintbases _prc _prlc _prt = Pptactic.pr_hintbases
-
-ARGUMENT EXTEND hintbases
- TYPED AS preident_list_opt
- PRINTED BY pr_hintbases
-| [ "with" "*" ] -> [ None ]
-| [ "with" ne_preident_list(l) ] -> [ Some l ]
-| [ ] -> [ Some [] ]
-END
-
-let eval_uconstrs ist cs =
- let flags = {
- Pretyping.use_typeclasses = false;
- use_unif_heuristics = true;
- use_hook = Some Pfedit.solve_by_implicit_tactic;
- fail_evar = false;
- expand_evars = true
- } in
- List.map (fun c -> Tacinterp.type_uconstr ~flags ist c) cs
-
-let pr_auto_using _ _ _ = Pptactic.pr_auto_using (fun _ -> mt ())
-
-ARGUMENT EXTEND auto_using
- TYPED AS uconstr_list
- PRINTED BY pr_auto_using
-| [ "using" ne_uconstr_list_sep(l, ",") ] -> [ l ]
-| [ ] -> [ [] ]
-END
-
-TACTIC EXTEND trivial
-| [ "trivial" auto_using(lems) hintbases(db) ] ->
- [ Auto.h_trivial (eval_uconstrs ist lems) db ]
-END
-
-TACTIC EXTEND info_trivial
-| [ "info_trivial" auto_using(lems) hintbases(db) ] ->
- [ Auto.h_trivial ~debug:Info (eval_uconstrs ist lems) db ]
-END
-
-TACTIC EXTEND debug_trivial
-| [ "debug" "trivial" auto_using(lems) hintbases(db) ] ->
- [ Auto.h_trivial ~debug:Debug (eval_uconstrs ist lems) db ]
-END
-
-TACTIC EXTEND auto
-| [ "auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
- [ Auto.h_auto n (eval_uconstrs ist lems) db ]
-END
-
-TACTIC EXTEND info_auto
-| [ "info_auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
- [ Auto.h_auto ~debug:Info n (eval_uconstrs ist lems) db ]
-END
-
-TACTIC EXTEND debug_auto
-| [ "debug" "auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
- [ Auto.h_auto ~debug:Debug n (eval_uconstrs ist lems) db ]
-END
diff --git a/tactics/geninterp.ml b/tactics/geninterp.ml
deleted file mode 100644
index 008075800..000000000
--- a/tactics/geninterp.ml
+++ /dev/null
@@ -1,35 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2016 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-open Names
-open Genarg
-
-module TacStore = Store.Make(struct end)
-
-type interp_sign = {
- lfun : Val.t Id.Map.t;
- extra : TacStore.t }
-
-type ('glb, 'top) interp_fun = interp_sign -> 'glb -> 'top Ftactic.t
-
-module InterpObj =
-struct
- type ('raw, 'glb, 'top) obj = ('glb, 'top) interp_fun
- let name = "interp"
- let default _ = None
-end
-
-module Interp = Register(InterpObj)
-
-let interp = Interp.obj
-let register_interp0 = Interp.register0
-
-let generic_interp ist (GenArg (Glbwit wit, v)) =
- let open Ftactic.Notations in
- interp wit ist v >>= fun ans ->
- Ftactic.return (Val.Dyn (val_tag (topwit wit), ans))
diff --git a/tactics/hightactics.mllib b/tactics/hightactics.mllib
deleted file mode 100644
index 30e97f62d..000000000
--- a/tactics/hightactics.mllib
+++ /dev/null
@@ -1,12 +0,0 @@
-Extraargs
-Coretactics
-Extratactics
-G_auto
-Eauto
-Class_tactics
-G_class
-Rewrite
-G_rewrite
-Tauto
-Eqdecide
-G_eqdecide
diff --git a/tactics/hints.ml b/tactics/hints.ml
index 730da147a..6f8da00d8 100644
--- a/tactics/hints.ml
+++ b/tactics/hints.ml
@@ -76,7 +76,7 @@ type 'a hint_ast =
| Give_exact of 'a
| Res_pf_THEN_trivial_fail of 'a (* Hint Immediate *)
| Unfold_nth of evaluable_global_reference (* Hint Unfold *)
- | Extern of glob_tactic_expr (* Hint Extern *)
+ | Extern of Genarg.glob_generic_argument (* Hint Extern *)
type hints_path_atom =
| PathHints of global_reference list
@@ -692,7 +692,7 @@ let make_apply_entry env sigma (eapply,hnf,verbose) pri poly ?(name=PathAny) (c,
else begin
if not eapply then failwith "make_apply_entry";
if verbose then
- msg_warning (str "the hint: eapply " ++ pr_lconstr c ++
+ Feedback.msg_warning (str "the hint: eapply " ++ pr_lconstr c ++
str " will only be used by eauto");
(Some hd,
{ pri = (match pri with None -> nb_hyp cty + nmiss | Some p -> p);
@@ -707,10 +707,43 @@ let make_apply_entry env sigma (eapply,hnf,verbose) pri poly ?(name=PathAny) (c,
c is a constr
cty is the type of constr *)
+let pr_hint_term env sigma ctx = function
+ | IsGlobRef gr -> pr_global gr
+ | IsConstr (c, ctx) ->
+ let sigma = Evd.merge_context_set Evd.univ_flexible sigma ctx in
+ pr_constr_env env sigma c
+
+(** We need an object to record the side-effect of registering
+ global universes associated with a hint. *)
+let cache_context_set (_,c) =
+ Global.push_context_set false c
+
+let input_context_set : Univ.ContextSet.t -> Libobject.obj =
+ let open Libobject in
+ declare_object
+ { (default_object "Global universe context") with
+ cache_function = cache_context_set;
+ load_function = (fun _ -> cache_context_set);
+ discharge_function = (fun (_,a) -> Some a);
+ classify_function = (fun a -> Keep a) }
+
let fresh_global_or_constr env sigma poly cr =
- match cr with
- | IsGlobRef gr -> Universes.fresh_global_instance env gr
- | IsConstr (c, ctx) -> (c, ctx)
+ let isgr, (c, ctx) =
+ match cr with
+ | IsGlobRef gr ->
+ true, Universes.fresh_global_instance env gr
+ | IsConstr (c, ctx) -> false, (c, ctx)
+ in
+ if poly then (c, ctx)
+ else if Univ.ContextSet.is_empty ctx then (c, ctx)
+ else begin
+ if isgr then
+ Feedback.msg_warning (str"Using polymorphic hint " ++
+ pr_hint_term env sigma ctx cr ++ str" monomorphically" ++
+ str" use Polymorphic Hint to use it polymorphically.");
+ Lib.add_anonymous_leaf (input_context_set ctx);
+ (c, Univ.ContextSet.empty)
+ end
let make_resolves env sigma flags pri poly ?name cr =
let c, ctx = fresh_global_or_constr env sigma poly cr in
@@ -749,6 +782,7 @@ let make_unfold eref =
code = with_uid (Unfold_nth eref) })
let make_extern pri pat tacast =
+ let tacast = Genarg.in_gen (Genarg.glbwit Constrarg.wit_ltac) tacast in
let hdconstr = Option.map try_head_pattern pat in
(hdconstr,
{ pri = pri;
@@ -900,7 +934,7 @@ let subst_autohint (subst, obj) =
let ref' = subst_evaluable_reference subst ref in
if ref==ref' then data.code.obj else Unfold_nth ref'
| Extern tac ->
- let tac' = Tacsubst.subst_tactic subst tac in
+ let tac' = Genintern.generic_substitute subst tac in
if tac==tac' then data.code.obj else Extern tac'
in
let name' = subst_path_atom subst data.name in
@@ -1072,11 +1106,11 @@ let prepare_hint check (poly,local) env init (sigma,c) =
subst := (evar,mkVar id)::!subst;
mkNamedLambda id t (iter (replace_term evar (mkVar id) c)) in
let c' = iter c in
- if check then Evarutil.check_evars (Global.env()) Evd.empty sigma c';
+ if check then Pretyping.check_evars (Global.env()) Evd.empty sigma c';
let diff = Univ.ContextSet.diff (Evd.universe_context_set sigma) (Evd.universe_context_set init) in
if poly then IsConstr (c', diff)
else if local then IsConstr (c', diff)
- else (Global.push_context_set false diff;
+ else (Lib.add_anonymous_leaf (input_context_set diff);
IsConstr (c', Univ.ContextSet.empty))
let interp_hints poly =
@@ -1151,18 +1185,24 @@ let expand_constructor_hints env sigma lems =
match kind_of_term lem with
| Ind (ind,u) ->
List.init (nconstructors ind)
- (fun i -> IsConstr (mkConstructU ((ind,i+1),u),
- Univ.ContextSet.empty))
+ (fun i ->
+ let ctx = Univ.ContextSet.diff (Evd.universe_context_set evd)
+ (Evd.universe_context_set sigma) in
+ not (Univ.ContextSet.is_empty ctx),
+ IsConstr (mkConstructU ((ind,i+1),u),ctx))
| _ ->
- [prepare_hint false (false,true) env sigma (evd,lem)]) lems
-
+ [match prepare_hint false (false,true) env sigma (evd,lem) with
+ | IsConstr (c, ctx) ->
+ not (Univ.ContextSet.is_empty ctx), IsConstr (c, ctx)
+ | IsGlobRef _ -> assert false (* Impossible return value *) ]) lems
(* builds a hint database from a constr signature *)
(* typically used with (lid, ltyp) = pf_hyps_types <some goal> *)
let add_hint_lemmas env sigma eapply lems hint_db =
let lems = expand_constructor_hints env sigma lems in
let hintlist' =
- List.map_append (make_resolves env sigma (eapply,true,false) None false) lems in
+ List.map_append (fun (poly, lem) ->
+ make_resolves env sigma (eapply,true,false) None poly lem) lems in
Hint_db.add_list env sigma hintlist' hint_db
let make_local_hint_db env sigma ts eapply lems =
@@ -1181,12 +1221,6 @@ let make_local_hint_db env sigma ts eapply lems =
add_hint_lemmas env sigma eapply lems
(Hint_db.add_list env sigma hintlist (Hint_db.empty ts false))
-let make_local_hint_db =
- if Flags.profile then
- let key = Profile.declare_profile "make_local_hint_db" in
- Profile.profile4 key make_local_hint_db
- else make_local_hint_db
-
let make_local_hint_db env sigma ?ts eapply lems =
make_local_hint_db env sigma ts eapply lems
@@ -1219,7 +1253,7 @@ let pr_hint h = match h.obj with
env
with e when Errors.noncritical e -> Global.env ()
in
- (str "(*external*) " ++ Pptactic.pr_glob_tactic env tac)
+ (str "(*external*) " ++ Pptactic.pr_glb_generic env tac)
let pr_id_hint (id, v) =
(pr_hint v.code ++ str"(level " ++ int v.pri ++ str", id " ++ int id ++ str ")" ++ spc ())
@@ -1335,7 +1369,7 @@ let is_imported h = try KNmap.find h.uid !statustable with Not_found -> true
let warn h x =
let hint = pr_hint h in
let (mp, _, _) = KerName.repr h.uid in
- let () = msg_warning (str "Hint used but not imported: " ++ hint ++ print_mp mp) in
+ let () = Feedback.msg_warning (str "Hint used but not imported: " ++ hint ++ print_mp mp) in
Proofview.tclUNIT x
let run_hint tac k = match !warn_hint with
diff --git a/tactics/hints.mli b/tactics/hints.mli
index 3e08060f8..df9d79212 100644
--- a/tactics/hints.mli
+++ b/tactics/hints.mli
@@ -33,7 +33,7 @@ type 'a hint_ast =
| Give_exact of 'a
| Res_pf_THEN_trivial_fail of 'a (* Hint Immediate *)
| Unfold_nth of evaluable_global_reference (* Hint Unfold *)
- | Extern of Tacexpr.glob_tactic_expr (* Hint Extern *)
+ | Extern of Genarg.glob_generic_argument (* Hint Extern *)
type hint
type raw_hint = constr * types * Univ.universe_context_set
diff --git a/tactics/hipattern.ml4 b/tactics/hipattern.ml
index bcec90f80..fded54fcb 100644
--- a/tactics/hipattern.ml4
+++ b/tactics/hipattern.ml
@@ -6,8 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i camlp4deps: "grammar/grammar.cma grammar/q_constr.cmo" i*)
-
open Pp
open Errors
open Util
@@ -243,9 +241,36 @@ type equation_kind =
exception NoEquationFound
-let coq_refl_leibniz1_pattern = PATTERN [ forall x:_, _ x x ]
-let coq_refl_leibniz2_pattern = PATTERN [ forall A:_, forall x:A, _ A x x ]
-let coq_refl_jm_pattern = PATTERN [ forall A:_, forall x:A, _ A x A x ]
+open Glob_term
+open Decl_kinds
+open Evar_kinds
+
+let mkPattern c = snd (Patternops.pattern_of_glob_constr c)
+let mkGApp f args = GApp (Loc.ghost, f, args)
+let mkGHole =
+ GHole (Loc.ghost, QuestionMark (Define false), Misctypes.IntroAnonymous, None)
+let mkGProd id c1 c2 =
+ GProd (Loc.ghost, Name (Id.of_string id), Explicit, c1, c2)
+let mkGArrow c1 c2 =
+ GProd (Loc.ghost, Anonymous, Explicit, c1, c2)
+let mkGVar id = GVar (Loc.ghost, Id.of_string id)
+let mkGPatVar id = GPatVar(Loc.ghost, (false, Id.of_string id))
+let mkGRef r = GRef (Loc.ghost, Lazy.force r, None)
+let mkGAppRef r args = mkGApp (mkGRef r) args
+
+(** forall x : _, _ x x *)
+let coq_refl_leibniz1_pattern =
+ mkPattern (mkGProd "x" mkGHole (mkGApp mkGHole [mkGVar "x"; mkGVar "x";]))
+
+(** forall A:_, forall x:A, _ A x x *)
+let coq_refl_leibniz2_pattern =
+ mkPattern (mkGProd "A" mkGHole (mkGProd "x" (mkGVar "A")
+ (mkGApp mkGHole [mkGVar "A"; mkGVar "x"; mkGVar "x";])))
+
+(** forall A:_, forall x:A, _ A x A x *)
+let coq_refl_jm_pattern =
+ mkPattern (mkGProd "A" mkGHole (mkGProd "x" (mkGVar "A")
+ (mkGApp mkGHole [mkGVar "A"; mkGVar "x"; mkGVar "A"; mkGVar "x";])))
open Globnames
@@ -301,7 +326,8 @@ let is_equality_type t = op2bool (match_with_equality_type t)
(* Arrows/Implication/Negation *)
-let coq_arrow_pattern = PATTERN [ ?X1 -> ?X2 ]
+(** X1 -> X2 **)
+let coq_arrow_pattern = mkPattern (mkGArrow (mkGPatVar "X1") (mkGPatVar "X2"))
let match_arrow_pattern t =
let result = matches coq_arrow_pattern t in
@@ -381,10 +407,15 @@ let rec first_match matcher = function
(*** Equality *)
(* Patterns "(eq ?1 ?2 ?3)" and "(identity ?1 ?2 ?3)" *)
-let coq_eq_pattern_gen eq = lazy PATTERN [ %eq ?X1 ?X2 ?X3 ]
+(** %eq ?X1 ?X2 ?X3 *)
+let coq_eq_pattern_gen eq =
+ lazy (mkPattern (mkGAppRef eq (List.map mkGPatVar ["X1"; "X2"; "X3";])))
let coq_eq_pattern = coq_eq_pattern_gen coq_eq_ref
let coq_identity_pattern = coq_eq_pattern_gen coq_identity_ref
-let coq_jmeq_pattern = lazy PATTERN [ %coq_jmeq_ref ?X1 ?X2 ?X3 ?X4 ]
+(** %coq_jmeq_ref ?X1 ?X2 ?X3 ?X4 *)
+let coq_jmeq_pattern =
+ lazy (mkPattern
+ (mkGAppRef coq_jmeq_ref (List.map mkGPatVar ["X1"; "X2"; "X3"; "X4"])))
let match_eq eqn eq_pat =
let pat =
@@ -464,7 +495,8 @@ let find_sigma_data_decompose ex = (* fails with PatternMatchingFailure *)
match_sigma ex
(* Pattern "(sig ?1 ?2)" *)
-let coq_sig_pattern = lazy PATTERN [ %coq_sig_ref ?X1 ?X2 ]
+let coq_sig_pattern =
+ lazy (mkPattern (mkGAppRef coq_sig_ref [mkGPatVar "X1"; mkGPatVar "X2"]))
let match_sigma t =
match Id.Map.bindings (matches (Lazy.force coq_sig_pattern) t) with
@@ -480,17 +512,25 @@ let is_matching_sigma t = is_matching (Lazy.force coq_sig_pattern) t
(* Pattern "{<?1>x=y}+{~(<?1>x=y)}" *)
(* i.e. "(sumbool (eq ?1 x y) ~(eq ?1 x y))" *)
-let coq_eqdec_inf_pattern =
- lazy PATTERN [ { ?X2 = ?X3 :> ?X1 } + { ~ ?X2 = ?X3 :> ?X1 } ]
+let coq_eqdec ~sum ~rev =
+ lazy (
+ let eqn = mkGAppRef coq_eq_ref (List.map mkGPatVar ["X1"; "X2"; "X3"]) in
+ let args = [eqn; mkGAppRef coq_not_ref [eqn]] in
+ let args = if rev then List.rev args else args in
+ mkPattern (mkGAppRef sum [eqn; mkGAppRef coq_not_ref [eqn]])
+ )
+
+(** { ?X2 = ?X3 :> ?X1 } + { ~ ?X2 = ?X3 :> ?X1 } *)
+let coq_eqdec_inf_pattern = coq_eqdec ~sum:coq_sumbool_ref ~rev:false
-let coq_eqdec_inf_rev_pattern =
- lazy PATTERN [ { ~ ?X2 = ?X3 :> ?X1 } + { ?X2 = ?X3 :> ?X1 } ]
+(** { ~ ?X2 = ?X3 :> ?X1 } + { ?X2 = ?X3 :> ?X1 } *)
+let coq_eqdec_inf_rev_pattern = coq_eqdec ~sum:coq_sumbool_ref ~rev:true
-let coq_eqdec_pattern =
- lazy PATTERN [ %coq_or_ref (?X2 = ?X3 :> ?X1) (~ ?X2 = ?X3 :> ?X1) ]
+(** %coq_or_ref (?X2 = ?X3 :> ?X1) (~ ?X2 = ?X3 :> ?X1) *)
+let coq_eqdec_pattern = coq_eqdec ~sum:coq_or_ref ~rev:false
-let coq_eqdec_rev_pattern =
- lazy PATTERN [ %coq_or_ref (~ ?X2 = ?X3 :> ?X1) (?X2 = ?X3 :> ?X1) ]
+(** %coq_or_ref (~ ?X2 = ?X3 :> ?X1) (?X2 = ?X3 :> ?X1) *)
+let coq_eqdec_rev_pattern = coq_eqdec ~sum:coq_or_ref ~rev:true
let op_or = coq_or_ref
let op_sum = coq_sumbool_ref
@@ -510,8 +550,8 @@ let match_eqdec t =
| _ -> anomaly (Pp.str "Unexpected pattern")
(* Patterns "~ ?" and "? -> False" *)
-let coq_not_pattern = lazy PATTERN [ ~ _ ]
-let coq_imp_False_pattern = lazy PATTERN [ _ -> %coq_False_ref ]
+let coq_not_pattern = lazy (mkPattern (mkGAppRef coq_not_ref [mkGHole]))
+let coq_imp_False_pattern = lazy (mkPattern (mkGArrow mkGHole (mkGRef coq_False_ref)))
let is_matching_not t = is_matching (Lazy.force coq_not_pattern) t
let is_matching_imp_False t = is_matching (Lazy.force coq_imp_False_pattern) t
diff --git a/tactics/inv.ml b/tactics/inv.ml
index 6841ab0ec..3707ef90b 100644
--- a/tactics/inv.ml
+++ b/tactics/inv.ml
@@ -30,8 +30,6 @@ open Sigma.Notations
open Proofview.Notations
open Context.Named.Declaration
-let clear hyps = Proofview.V82.tactic (clear hyps)
-
let var_occurs_in_pf gl id =
let env = Proofview.Goal.env gl in
occur_var env id (Proofview.Goal.concl gl) ||
@@ -459,7 +457,7 @@ let raw_inversion inv_kind id status names =
in
let refined id =
let prf = mkApp (mkVar id, args) in
- Proofview.Refine.refine { run = fun h -> Sigma (prf, h, Sigma.refl) }
+ Refine.refine { run = fun h -> Sigma (prf, h, Sigma.refl) }
in
let neqns = List.length realargs in
let as_mode = names != None in
diff --git a/tactics/taccoerce.ml b/tactics/taccoerce.ml
index 0cd3e0944..d53c1cc04 100644
--- a/tactics/taccoerce.ml
+++ b/tactics/taccoerce.ml
@@ -14,15 +14,25 @@ open Misctypes
open Genarg
open Stdarg
open Constrarg
+open Geninterp
exception CannotCoerceTo of string
let (wit_constr_context : (Empty.t, Empty.t, constr) Genarg.genarg_type) =
- Genarg.create_arg None "constr_context"
+ let wit = Genarg.create_arg "constr_context" in
+ let () = register_val0 wit None in
+ wit
(* includes idents known to be bound and references *)
let (wit_constr_under_binders : (Empty.t, Empty.t, constr_under_binders) Genarg.genarg_type) =
- Genarg.create_arg None "constr_under_binders"
+ let wit = Genarg.create_arg "constr_under_binders" in
+ let () = register_val0 wit None in
+ wit
+
+(** All the types considered here are base types *)
+let val_tag wit = match val_tag wit with
+| Val.Base t -> t
+| _ -> assert false
let has_type : type a. Val.t -> a typed_abstract_argument_type -> bool = fun v wit ->
let Val.Dyn (t, _) = v in
@@ -30,7 +40,7 @@ let has_type : type a. Val.t -> a typed_abstract_argument_type -> bool = fun v w
| None -> false
| Some Refl -> true
-let prj : type a. a Val.tag -> Val.t -> a option = fun t v ->
+let prj : type a. a Val.typ -> Val.t -> a option = fun t v ->
let Val.Dyn (t', x) = v in
match Val.eq t t' with
| None -> None
@@ -74,23 +84,11 @@ let to_int v =
Some (out_gen (topwit wit_int) v)
else None
-let to_list v =
- let v = normalize v in
- let Val.Dyn (tag, v) = v in
- match tag with
- | Val.List t -> Some (List.map (fun x -> Val.Dyn (t, x)) v)
- | _ -> None
-
-let of_list t v = Val.Dyn (Val.List t, v)
+let to_list v = prj Val.typ_list v
-let to_option v =
- let v = normalize v in
- let Val.Dyn (tag, v) = v in
- match tag with
- | Val.Opt t -> Some (Option.map (fun x -> Val.Dyn (t, x)) v)
- | _ -> None
+let to_option v = prj Val.typ_opt v
-let of_option t v = Val.Dyn (Val.Opt t, v)
+let to_pair v = prj Val.typ_pair v
end
diff --git a/tactics/taccoerce.mli b/tactics/taccoerce.mli
index 87137fd2e..7a963f95f 100644
--- a/tactics/taccoerce.mli
+++ b/tactics/taccoerce.mli
@@ -12,6 +12,7 @@ open Term
open Misctypes
open Pattern
open Genarg
+open Geninterp
(** Coercions from highest level generic arguments to actual data used by Ltac
interpretation. Those functions examinate dynamic types and try to return
@@ -41,9 +42,8 @@ sig
val of_int : int -> t
val to_int : t -> int option
val to_list : t -> t list option
- val of_list : 'a Val.tag -> 'a list -> t
val to_option : t -> t option option
- val of_option : 'a Val.tag -> 'a option -> t
+ val to_pair : t -> (t * t) option
end
(** {5 Coercion functions} *)
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index f725a0654..991922d90 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -163,7 +163,7 @@ let _ =
does not check anything. *)
let unsafe_intro env store decl b =
let open Context.Named.Declaration in
- Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
+ Refine.refine ~unsafe:true { run = begin fun sigma ->
let ctx = named_context_val env in
let nctx = push_named_context_val decl ctx in
let inst = List.map (mkVar % get_id) (named_context env) in
@@ -199,7 +199,7 @@ let convert_concl ?(check=true) ty k =
let env = Proofview.Goal.env gl in
let store = Proofview.Goal.extra gl in
let conclty = Proofview.Goal.raw_concl gl in
- Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
+ Refine.refine ~unsafe:true { run = begin fun sigma ->
let Sigma ((), sigma, p) =
if check then begin
let sigma = Sigma.to_evar_map sigma in
@@ -222,7 +222,7 @@ let convert_hyp ?(check=true) d =
let store = Proofview.Goal.extra gl in
let sign = convert_hyp check (named_context_val env) sigma d in
let env = reset_with_named_context sign env in
- Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
+ Refine.refine ~unsafe:true { run = begin fun sigma ->
Evarutil.new_evar env sigma ~principal:true ~store ty
end }
end }
@@ -271,29 +271,49 @@ let replacing_dependency_msg env sigma id = function
let error_replacing_dependency env sigma id err =
errorlabstrm "" (replacing_dependency_msg env sigma id err)
-let thin l gl =
- try Tacmach.thin l gl
- with Evarutil.ClearDependencyError (id,err) ->
- error_clear_dependency (pf_env gl) (project gl) id err
+(* This tactic enables the user to remove hypotheses from the signature.
+ * Some care is taken to prevent him from removing variables that are
+ * subsequently used in other hypotheses or in the conclusion of the
+ * goal. *)
-let thin_for_replacing l gl =
- try Tacmach.thin l gl
- with Evarutil.ClearDependencyError (id,err) ->
- error_replacing_dependency (pf_env gl) (project gl) id err
+let clear_gen fail = function
+| [] -> Proofview.tclUNIT ()
+| ids ->
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
+ let ids = List.fold_right Id.Set.add ids Id.Set.empty in
+ (** clear_hyps_in_evi does not require nf terms *)
+ let gl = Proofview.Goal.assume gl in
+ let env = Proofview.Goal.env gl in
+ let sigma = Tacmach.New.project gl in
+ let concl = Proofview.Goal.concl gl in
+ let evdref = ref sigma in
+ let (hyps, concl) =
+ try clear_hyps_in_evi env evdref (named_context_val env) concl ids
+ with Evarutil.ClearDependencyError (id,err) -> fail env sigma id err
+ in
+ let env = reset_with_named_context hyps env in
+ let tac = Refine.refine ~unsafe:true { run = fun sigma ->
+ Evarutil.new_evar env sigma ~principal:true concl
+ } in
+ Sigma.Unsafe.of_pair (tac, !evdref)
+ end }
+
+let clear ids = clear_gen error_clear_dependency ids
+let clear_for_replacing ids = clear_gen error_replacing_dependency ids
let apply_clear_request clear_flag dft c =
let check_isvar c =
if not (isVar c) then
error "keep/clear modifiers apply only to hypothesis names." in
- let clear = match clear_flag with
+ let doclear = match clear_flag with
| None -> dft && isVar c
| Some true -> check_isvar c; true
| Some false -> false in
- if clear then Proofview.V82.tactic (thin [destVar c])
+ if doclear then clear [destVar c]
else Tacticals.New.tclIDTAC
(* Moving hypotheses *)
-let move_hyp id dest gl = Tacmach.move_hyp id dest gl
+let move_hyp id dest = Proofview.V82.tactic (Tacmach.move_hyp id dest)
(* Renaming hypotheses *)
let rename_hyp repl =
@@ -345,7 +365,7 @@ let rename_hyp repl =
let nconcl = subst concl in
let nctx = Environ.val_of_named_context nhyps in
let instance = List.map (mkVar % get_id) hyps in
- Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
+ Refine.refine ~unsafe:true { run = begin fun sigma ->
Evarutil.new_evar_instance nctx sigma nconcl ~store instance
end }
end }
@@ -452,23 +472,120 @@ let assert_after_replacing id = assert_after_gen true (NamingMustBe (dloc,id))
(* Fixpoints and CoFixpoints *)
(**************************************************************)
+let rec mk_holes : type r s. _ -> r Sigma.t -> (s, r) Sigma.le -> _ -> (_, s) Sigma.sigma =
+fun env sigma p -> function
+| [] -> Sigma ([], sigma, p)
+| arg :: rem ->
+ let Sigma (arg, sigma, q) = Evarutil.new_evar env sigma arg in
+ let Sigma (rem, sigma, r) = mk_holes env sigma (p +> q) rem in
+ Sigma (arg :: rem, sigma, r)
+
+let rec check_mutind env sigma k cl = match kind_of_term (strip_outer_cast cl) with
+| Prod (na, c1, b) ->
+ if Int.equal k 1 then
+ try
+ let ((sp, _), u), _ = find_inductive env sigma c1 in
+ (sp, u)
+ with Not_found -> error "Cannot do a fixpoint on a non inductive type."
+ else
+ let open Context.Rel.Declaration in
+ check_mutind (push_rel (LocalAssum (na, c1)) env) sigma (pred k) b
+| _ -> error "Not enough products."
+
(* Refine as a fixpoint *)
-let mutual_fix = Tacmach.mutual_fix
+let mutual_fix f n rest j = Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let sigma = Tacmach.New.project gl in
+ let concl = Proofview.Goal.concl gl in
+ let (sp, u) = check_mutind env sigma n concl in
+ let firsts, lasts = List.chop j rest in
+ let all = firsts @ (f, n, concl) :: lasts in
+ let rec mk_sign sign = function
+ | [] -> sign
+ | (f, n, ar) :: oth ->
+ let open Context.Named.Declaration in
+ let (sp', u') = check_mutind env sigma n ar in
+ if not (eq_mind sp sp') then
+ error "Fixpoints should be on the same mutual inductive declaration.";
+ if mem_named_context f (named_context_of_val sign) then
+ errorlabstrm "Logic.prim_refiner"
+ (str "Name " ++ pr_id f ++ str " already used in the environment");
+ mk_sign (push_named_context_val (LocalAssum (f, ar)) sign) oth
+ in
+ let nenv = reset_with_named_context (mk_sign (named_context_val env) all) env in
+ Refine.refine { run = begin fun sigma ->
+ let Sigma (evs, sigma, p) = mk_holes nenv sigma Sigma.refl (List.map pi3 all) in
+ let ids = List.map pi1 all in
+ let evs = List.map (Vars.subst_vars (List.rev ids)) evs in
+ let indxs = Array.of_list (List.map (fun n -> n-1) (List.map pi2 all)) in
+ let funnames = Array.of_list (List.map (fun i -> Name i) ids) in
+ let typarray = Array.of_list (List.map pi3 all) in
+ let bodies = Array.of_list evs in
+ let oterm = Term.mkFix ((indxs,0),(funnames,typarray,bodies)) in
+ Sigma (oterm, sigma, p)
+ end }
+end }
-let fix ido n gl = match ido with
+let fix ido n = match ido with
| None ->
- mutual_fix (fresh_id [] (Pfedit.get_current_proof_name ()) gl) n [] 0 gl
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let name = Pfedit.get_current_proof_name () in
+ let id = new_fresh_id [] name gl in
+ mutual_fix id n [] 0
+ end }
| Some id ->
- mutual_fix id n [] 0 gl
+ mutual_fix id n [] 0
+
+let rec check_is_mutcoind env sigma cl =
+ let b = whd_betadeltaiota env sigma cl in
+ match kind_of_term b with
+ | Prod (na, c1, b) ->
+ let open Context.Rel.Declaration in
+ check_is_mutcoind (push_rel (LocalAssum (na,c1)) env) sigma b
+ | _ ->
+ try
+ let _ = find_coinductive env sigma b in ()
+ with Not_found ->
+ error "All methods must construct elements in coinductive types."
(* Refine as a cofixpoint *)
-let mutual_cofix = Tacmach.mutual_cofix
+let mutual_cofix f others j = Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let sigma = Tacmach.New.project gl in
+ let concl = Proofview.Goal.concl gl in
+ let firsts,lasts = List.chop j others in
+ let all = firsts @ (f, concl) :: lasts in
+ List.iter (fun (_, c) -> check_is_mutcoind env sigma c) all;
+ let rec mk_sign sign = function
+ | [] -> sign
+ | (f, ar) :: oth ->
+ let open Context.Named.Declaration in
+ if mem_named_context f (named_context_of_val sign) then
+ error "Name already used in the environment.";
+ mk_sign (push_named_context_val (LocalAssum (f, ar)) sign) oth
+ in
+ let nenv = reset_with_named_context (mk_sign (named_context_val env) all) env in
+ Refine.refine { run = begin fun sigma ->
+ let (ids, types) = List.split all in
+ let Sigma (evs, sigma, p) = mk_holes nenv sigma Sigma.refl types in
+ let evs = List.map (Vars.subst_vars (List.rev ids)) evs in
+ let funnames = Array.of_list (List.map (fun i -> Name i) ids) in
+ let typarray = Array.of_list types in
+ let bodies = Array.of_list evs in
+ let oterm = Term.mkCoFix (0, (funnames, typarray, bodies)) in
+ Sigma (oterm, sigma, p)
+ end }
+end }
-let cofix ido gl = match ido with
+let cofix ido = match ido with
| None ->
- mutual_cofix (fresh_id [] (Pfedit.get_current_proof_name ()) gl) [] 0 gl
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let name = Pfedit.get_current_proof_name () in
+ let id = new_fresh_id [] name gl in
+ mutual_cofix id [] 0
+ end }
| Some id ->
- mutual_cofix id [] 0 gl
+ mutual_cofix id [] 0
(**************************************************************)
(* Reduction and conversion tactics *)
@@ -591,11 +708,11 @@ let pf_e_reduce_decl redfun where decl gl =
let Sigma (ty', sigma, q) = if where != InHypValueOnly then redfun sigma ty else Sigma.here ty sigma in
Sigma (LocalDef (id, b', ty'), sigma, p +> q)
-let e_reduct_in_concl (redfun, sty) =
+let e_reduct_in_concl ~check (redfun, sty) =
Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
let Sigma (c', sigma, p) = redfun.e_redfun (Tacmach.New.pf_env gl) sigma (Tacmach.New.pf_concl gl) in
- Sigma (convert_concl_no_check c' sty, sigma, p)
+ Sigma (convert_concl ~check c' sty, sigma, p)
end }
let e_reduct_in_hyp ?(check=false) redfun (id, where) =
@@ -606,7 +723,7 @@ let e_reduct_in_hyp ?(check=false) redfun (id, where) =
let e_reduct_option ?(check=false) redfun = function
| Some id -> e_reduct_in_hyp ~check (fst redfun) id
- | None -> e_reduct_in_concl (revert_cast redfun)
+ | None -> e_reduct_in_concl ~check (revert_cast redfun)
(** Versions with evars to maintain the unification of universes resulting
from conversions. *)
@@ -708,14 +825,16 @@ let change_option occl t = function
| Some id -> change_in_hyp occl t id
| None -> change_in_concl occl t
-let change chg c cls gl =
- let cls = concrete_clause_of (fun () -> Tacmach.pf_ids_of_hyps gl) cls in
- Proofview.V82.of_tactic (Tacticals.New.tclMAP (function
+let change chg c cls =
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let cls = concrete_clause_of (fun () -> Tacmach.New.pf_ids_of_hyps gl) cls in
+ Tacticals.New.tclMAP (function
| OnHyp (id,occs,where) ->
change_option (bind_change_occurrences occs chg) c (Some (id,where))
| OnConcl occs ->
change_option (bind_change_occurrences occs chg) c None)
- cls) gl
+ cls
+ end }
let change_concl t =
change_in_concl None (make_change_arg t)
@@ -754,10 +873,9 @@ let reduce redexp cl =
let cl = concrete_clause_of (fun () -> Tacmach.New.pf_ids_of_hyps gl) cl in
let redexps = reduction_clause redexp cl in
let check = match redexp with Fold _ | Pattern _ -> true | _ -> false in
- let tac = Tacticals.New.tclMAP (fun (where,redexp) ->
+ Tacticals.New.tclMAP (fun (where,redexp) ->
e_reduct_option ~check
- (Redexpr.reduction_of_red_expr (Tacmach.New.pf_env gl) redexp) where) redexps in
- if check then Proofview.V82.tactic (fun gl -> with_check (Proofview.V82.of_tactic tac) gl) else tac (** FIXME *)
+ (Redexpr.reduction_of_red_expr (Tacmach.New.pf_env gl) redexp) where) redexps
end }
(* Unfolding occurrences of a constant *)
@@ -789,9 +907,8 @@ let find_intro_names ctxt gl =
let build_intro_tac id dest tac = match dest with
| MoveLast -> Tacticals.New.tclTHEN (introduction id) (tac id)
| dest -> Tacticals.New.tclTHENLIST
- [introduction id;
- Proofview.V82.tactic (move_hyp id dest); tac id]
-
+ [introduction id; move_hyp id dest; tac id]
+
let rec intro_then_gen name_flag move_flag force_flag dep_flag tac =
let open Context.Rel.Declaration in
Proofview.Goal.enter { enter = begin fun gl ->
@@ -890,9 +1007,9 @@ let intro_replacing id =
Proofview.Goal.enter { enter = begin fun gl ->
let next_hyp = get_next_hyp_position id gl in
Tacticals.New.tclTHENLIST [
- Proofview.V82.tactic (thin_for_replacing [id]);
+ clear_for_replacing [id];
introduction id;
- Proofview.V82.tactic (move_hyp id next_hyp);
+ move_hyp id next_hyp;
]
end }
@@ -910,7 +1027,7 @@ let intros_possibly_replacing ids =
let posl = List.map (fun id -> (id, get_next_hyp_position id gl)) ids in
Tacticals.New.tclTHEN
(Tacticals.New.tclMAP (fun id ->
- Tacticals.New.tclTRY (Proofview.V82.tactic (thin_for_replacing [id])))
+ Tacticals.New.tclTRY (clear_for_replacing [id]))
(if suboptimal then ids else List.rev ids))
(Tacticals.New.tclMAP (fun (id,pos) ->
Tacticals.New.tclORELSE (intro_move (Some id) pos) (intro_using id))
@@ -922,7 +1039,7 @@ let intros_replacing ids =
Proofview.Goal.enter { enter = begin fun gl ->
let posl = List.map (fun id -> (id, get_next_hyp_position id gl)) ids in
Tacticals.New.tclTHEN
- (Proofview.V82.tactic (thin_for_replacing ids))
+ (clear_for_replacing ids)
(Tacticals.New.tclMAP (fun (id,pos) -> intro_move (Some id) pos) posl)
end }
@@ -979,10 +1096,14 @@ let intros_until_n_gen red n = intros_until_gen red (AnonHyp n)
let intros_until = intros_until_gen true
let intros_until_n = intros_until_n_gen true
-let tclCHECKVAR id gl = ignore (Tacmach.pf_get_hyp gl id); tclIDTAC gl
+let tclCHECKVAR id =
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let _ = Tacmach.New.pf_get_hyp id (Proofview.Goal.assume gl) in
+ Proofview.tclUNIT ()
+ end }
let try_intros_until_id_check id =
- Tacticals.New.tclORELSE (intros_until_id id) (Proofview.V82.tactic (tclCHECKVAR id))
+ Tacticals.New.tclORELSE (intros_until_id id) (tclCHECKVAR id)
let try_intros_until tac = function
| NamedHyp id -> Tacticals.New.tclTHEN (try_intros_until_id_check id) (tac id)
@@ -1070,7 +1191,7 @@ let cut c =
let id = next_name_away_with_default "H" Anonymous (Tacmach.New.pf_ids_of_hyps gl) in
(** Backward compat: normalize [c]. *)
let c = if normalize_cut then local_strong whd_betaiota sigma c else c in
- Proofview.Refine.refine ~unsafe:true { run = begin fun h ->
+ Refine.refine ~unsafe:true { run = begin fun h ->
let Sigma (f, h, p) = Evarutil.new_evar ~principal:true env h (mkArrow c (Vars.lift 1 concl)) in
let Sigma (x, h, q) = Evarutil.new_evar env h c in
let f = mkLetIn (Name id, x, c, mkApp (Vars.lift 1 f, [|mkRel 1|])) in
@@ -1186,7 +1307,7 @@ let enforce_prop_bound_names rename tac =
mkProd (Anonymous,t,aux (push_rel (LocalAssum (Anonymous,t)) env) sigma (i-1) t')
| LetIn (na,c,t,t') ->
mkLetIn (na,c,t,aux (push_rel (LocalDef (na,c,t)) env) sigma (i-1) t')
- | _ -> print_int i; Pp.msg (print_constr t); assert false in
+ | _ -> print_int i; Feedback.msg_notice (print_constr t); assert false in
let rename_branch i =
Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
@@ -1256,6 +1377,8 @@ let general_elim with_evars clear_flag (c, lbindc) elim =
let t = try snd (reduce_to_quantified_ind env sigma ct) with UserError _ -> ct in
let elimtac = elimination_clause_scheme with_evars in
let indclause = make_clenv_binding env sigma (c, t) lbindc in
+ let sigma = meta_merge sigma (clear_metas indclause.evd) in
+ Proofview.Unsafe.tclEVARS sigma <*>
Tacticals.New.tclTHEN
(general_elim_clause_gen elimtac indclause elim)
(apply_clear_request clear_flag (use_clear_hyp_by_default ()) c)
@@ -1468,7 +1591,8 @@ let descend_in_conjunctions avoid tac (err, info) c =
let sigma = Sigma.Unsafe.of_evar_map sigma in
let Sigma (elim, _, _) = build_case_analysis_scheme env sigma (ind,u) false sort in
NotADefinedRecordUseScheme elim in
- Tacticals.New.tclFIRST
+ Tacticals.New.tclORELSE0
+ (Tacticals.New.tclFIRST
(List.init n (fun i ->
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
@@ -1481,7 +1605,8 @@ let descend_in_conjunctions avoid tac (err, info) c =
[Proofview.V82.tactic (refine p);
(* Might be ill-typed due to forbidden elimination. *)
Tacticals.New.onLastHypId (tac (not isrec))]
- end }))
+ end })))
+ (Proofview.tclZERO ~info err)
| None -> Proofview.tclZERO ~info err
with RefinerError _|UserError _ -> Proofview.tclZERO ~info err
end }
@@ -1500,9 +1625,7 @@ let solve_remaining_apply_goals =
let concl = Proofview.Goal.concl gl in
if Typeclasses.is_class_type evd concl then
let evd', c' = Typeclasses.resolve_one_typeclass env evd concl in
- let tac =
- (Proofview.V82.tactic (Tacmach.refine_no_check c'))
- in
+ let tac = Refine.refine ~unsafe:true { run = fun h -> Sigma.here c' h } in
Sigma.Unsafe.of_pair (tac, evd')
else Sigma.here (Proofview.tclUNIT ()) sigma
with Not_found -> Sigma.here (Proofview.tclUNIT ()) sigma
@@ -1538,7 +1661,7 @@ let general_apply with_delta with_destruct with_evars clear_flag (loc,(c,lbind))
if n<0 then error "Applied theorem has not enough premisses.";
let clause = make_clenv_binding_apply env sigma (Some n) (c,thm_ty) lbind in
Clenvtac.res_pf clause ~with_evars ~flags
- with UserError _ as exn ->
+ with exn when catchable_exception exn ->
Proofview.tclZERO exn
in
let rec try_red_apply thm_ty (exn0, info) =
@@ -1561,7 +1684,7 @@ let general_apply with_delta with_destruct with_evars clear_flag (loc,(c,lbind))
(fun b id ->
Tacticals.New.tclTHEN
(try_main_apply b (mkVar id))
- (Proofview.V82.tactic (thin [id])))
+ (clear [id]))
(exn0, info) c
else
Proofview.tclZERO ~info exn0 in
@@ -1688,7 +1811,7 @@ let apply_in_once sidecond_first with_delta with_destruct with_evars naming
(fun id ->
Tacticals.New.tclTHENLIST [
apply_clear_request clear_flag false c;
- Proofview.V82.tactic (thin idstoclear);
+ clear idstoclear;
tac id
])
with e when with_destruct && Errors.noncritical e ->
@@ -1736,7 +1859,7 @@ let cut_and_apply c =
| Prod (_,c1,c2) when not (dependent (mkRel 1) c2) ->
let concl = Proofview.Goal.concl gl in
let env = Tacmach.New.pf_env gl in
- Proofview.Refine.refine { run = begin fun sigma ->
+ Refine.refine { run = begin fun sigma ->
let typ = mkProd (Anonymous, c2, concl) in
let Sigma (f, sigma, p) = Evarutil.new_evar env sigma typ in
let Sigma (x, sigma, q) = Evarutil.new_evar env sigma c1 in
@@ -1756,8 +1879,8 @@ let cut_and_apply c =
(* let refine_no_checkkey = Profile.declare_profile "refine_no_check";; *)
(* let refine_no_check = Profile.profile2 refine_no_checkkey refine_no_check *)
-let new_exact_no_check c =
- Proofview.Refine.refine ~unsafe:true { run = fun h -> Sigma.here c h }
+let exact_no_check c =
+ Refine.refine ~unsafe:true { run = fun h -> Sigma.here c h }
let exact_check c =
Proofview.Goal.s_enter { s_enter = begin fun gl ->
@@ -1768,25 +1891,32 @@ let exact_check c =
let sigma = Sigma.to_evar_map sigma in
let sigma, ct = Typing.type_of env sigma c in
let tac =
- Tacticals.New.tclTHEN (convert_leq ct concl) (new_exact_no_check c)
+ Tacticals.New.tclTHEN (convert_leq ct concl) (exact_no_check c)
in
Sigma.Unsafe.of_pair (tac, sigma)
end }
-let exact_no_check = Tacmach.refine_no_check
-
-let vm_cast_no_check c gl =
- let concl = Tacmach.pf_concl gl in
- Tacmach.refine_no_check (Term.mkCast(c,Term.VMcast,concl)) gl
-
-let native_cast_no_check c gl =
- let concl = Tacmach.pf_concl gl in
- Tacmach.refine_no_check (Term.mkCast(c,Term.NATIVEcast,concl)) gl
+let cast_no_check cast c =
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let concl = Proofview.Goal.concl (Proofview.Goal.assume gl) in
+ Refine.refine ~unsafe:true { run = begin fun sigma ->
+ Sigma.here (Term.mkCast (c, cast, concl)) sigma
+ end }
+ end }
+let vm_cast_no_check c = cast_no_check Term.VMcast c
+let native_cast_no_check c = cast_no_check Term.NATIVEcast c
-let exact_proof c gl =
- let c,ctx = Constrintern.interp_casted_constr (Tacmach.pf_env gl) (Tacmach.project gl) c (Tacmach.pf_concl gl)
- in tclTHEN (tclEVARUNIVCONTEXT ctx) (Tacmach.refine_no_check c) gl
+let exact_proof c =
+ let open Tacmach.New in
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ Refine.refine { run = begin fun sigma ->
+ let sigma = Sigma.to_evar_map sigma in
+ let (c, ctx) = Constrintern.interp_casted_constr (pf_env gl) sigma c (pf_concl gl) in
+ let sigma = Evd.merge_universe_context sigma ctx in
+ Sigma.Unsafe.of_pair (c, sigma)
+ end }
+ end }
let assumption =
let open Context.Named.Declaration in
@@ -1808,7 +1938,7 @@ let assumption =
in
if is_same_type then
(Proofview.Unsafe.tclEVARS sigma) <*>
- Proofview.Refine.refine ~unsafe:true { run = fun h -> Sigma.here (mkVar (get_id decl)) h }
+ Refine.refine ~unsafe:true { run = fun h -> Sigma.here (mkVar (get_id decl)) h }
else arec gl only_eq rest
in
let assumption_tac = { enter = begin fun gl ->
@@ -1821,32 +1951,24 @@ let assumption =
(* Modification of a local context *)
(*****************************************************************)
-(* This tactic enables the user to remove hypotheses from the signature.
- * Some care is taken to prevent him from removing variables that are
- * subsequently used in other hypotheses or in the conclusion of the
- * goal. *)
-
-let clear ids = (* avant seul dyn_clear n'echouait pas en [] *)
- if List.is_empty ids then tclIDTAC else thin ids
-
let on_the_bodies = function
| [] -> assert false
| [id] -> str " depends on the body of " ++ pr_id id
| l -> str " depends on the bodies of " ++ pr_sequence pr_id l
-let check_is_type env ty msg =
- Proofview.tclEVARMAP >>= fun sigma ->
+exception DependsOnBody of Id.t option
+
+let check_is_type env sigma ty =
let evdref = ref sigma in
try
let _ = Typing.e_sort_of env evdref ty in
- Proofview.Unsafe.tclEVARS !evdref
+ !evdref
with e when Errors.noncritical e ->
- msg e
+ raise (DependsOnBody None)
-let check_decl env decl msg =
+let check_decl env sigma decl =
let open Context.Named.Declaration in
let ty = get_type decl in
- Proofview.tclEVARMAP >>= fun sigma ->
let evdref = ref sigma in
try
let _ = Typing.e_sort_of env evdref ty in
@@ -1854,15 +1976,17 @@ let check_decl env decl msg =
| LocalAssum _ -> ()
| LocalDef (_,c,_) -> Typing.e_check env evdref c ty
in
- Proofview.Unsafe.tclEVARS !evdref
+ !evdref
with e when Errors.noncritical e ->
- msg e
+ let id = get_id decl in
+ raise (DependsOnBody (Some id))
let clear_body ids =
let open Context.Named.Declaration in
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let concl = Proofview.Goal.concl (Proofview.Goal.assume gl) in
+ let sigma = Tacmach.New.project gl in
let ctx = named_context env in
let map = function
| LocalAssum (id,t) as decl ->
@@ -1876,36 +2000,39 @@ let clear_body ids =
let ctx = List.map map ctx in
let base_env = reset_context env in
let env = push_named_context ctx base_env in
- let check_hyps =
- let check env decl =
- let msg _ = Tacticals.New.tclZEROMSG
- (str "Hypothesis " ++ pr_id (get_id decl) ++ on_the_bodies ids)
+ let check =
+ try
+ let check (env, sigma) decl =
+ (** Do no recheck hypotheses that do not depend *)
+ let sigma =
+ if List.exists (fun id -> occur_var_in_decl env id decl) ids then
+ check_decl env sigma decl
+ else sigma
+ in
+ (push_named decl env, sigma)
in
- check_decl env decl msg <*> Proofview.tclUNIT (push_named decl env)
- in
- let checks = Proofview.Monad.List.fold_left check base_env (List.rev ctx) in
- Proofview.tclIGNORE checks
- in
- let check_concl =
- let msg _ = Tacticals.New.tclZEROMSG
- (str "Conclusion" ++ on_the_bodies ids)
- in
- check_is_type env concl msg
+ let (env, sigma) = List.fold_left check (base_env, sigma) (List.rev ctx) in
+ let sigma =
+ if List.exists (fun id -> occur_var env id concl) ids then
+ check_is_type env sigma concl
+ else sigma
+ in
+ Proofview.Unsafe.tclEVARS sigma
+ with DependsOnBody where ->
+ let msg = match where with
+ | None -> str "Conclusion" ++ on_the_bodies ids
+ | Some id -> str "Hypothesis " ++ pr_id id ++ on_the_bodies ids
+ in
+ Tacticals.New.tclZEROMSG msg
in
- check_hyps <*> check_concl <*>
- Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
+ check <*>
+ Refine.refine ~unsafe:true { run = begin fun sigma ->
Evarutil.new_evar env sigma ~principal:true concl
end }
end }
let clear_wildcards ids =
- Proofview.V82.tactic (tclMAP (fun (loc,id) gl ->
- try with_check (Tacmach.thin_no_check [id]) gl
- with ClearDependencyError (id,err) ->
- (* Intercept standard [thin] error message *)
- Loc.raise loc
- (error_clear_dependency (pf_env gl) (project gl) (Id.of_string "_") err))
- ids)
+ Tacticals.New.tclMAP (fun (loc, id) -> clear [id]) ids
(* Takes a list of booleans, and introduces all the variables
* quantified in the goal which are associated with a value
@@ -1916,7 +2043,7 @@ let rec intros_clearing = function
| (false::tl) -> Tacticals.New.tclTHEN intro (intros_clearing tl)
| (true::tl) ->
Tacticals.New.tclTHENLIST
- [ intro; Tacticals.New.onLastHypId (fun id -> Proofview.V82.tactic (clear [id])); intros_clearing tl]
+ [ intro; Tacticals.New.onLastHypId (fun id -> clear [id]); intros_clearing tl]
(* Keeping only a few hypotheses *)
@@ -1935,7 +2062,7 @@ let keep hyps =
else (hyp::clear,keep))
~init:([],[]) (Proofview.Goal.env gl)
in
- Proofview.V82.tactic (fun gl -> thin cl gl)
+ clear cl
end }
(*********************************)
@@ -1950,7 +2077,7 @@ let apply_type newcl args =
Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let store = Proofview.Goal.extra gl in
- Proofview.Refine.refine { run = begin fun sigma ->
+ Refine.refine { run = begin fun sigma ->
let newcl = nf_betaiota (Sigma.to_evar_map sigma) newcl (* As in former Logic.refine *) in
let Sigma (ev, sigma, p) =
Evarutil.new_evar env sigma ~principal:true ~store newcl in
@@ -1971,7 +2098,7 @@ let bring_hyps hyps =
let concl = Tacmach.New.pf_nf_concl gl in
let newcl = List.fold_right mkNamedProd_or_LetIn hyps concl in
let args = Array.of_list (Context.Named.to_instance hyps) in
- Proofview.Refine.refine { run = begin fun sigma ->
+ Refine.refine { run = begin fun sigma ->
let Sigma (ev, sigma, p) =
Evarutil.new_evar env sigma ~principal:true ~store newcl in
Sigma (mkApp (ev, args), sigma, p)
@@ -1982,7 +2109,7 @@ let revert hyps =
Proofview.Goal.enter { enter = begin fun gl ->
let gl = Proofview.Goal.assume gl in
let ctx = List.map (fun id -> Tacmach.New.pf_get_hyp id gl) hyps in
- (bring_hyps ctx) <*> (Proofview.V82.tactic (clear hyps))
+ (bring_hyps ctx) <*> (clear hyps)
end }
(************************)
@@ -2124,7 +2251,7 @@ let intro_or_and_pattern loc bracketed ll thin tac id =
let ll = fix_empty_or_and_pattern (Array.length branchsigns) ll in
let ll = get_and_check_or_and_pattern loc ll branchsigns in
Tacticals.New.tclTHENLASTn
- (Tacticals.New.tclTHEN (simplest_case c) (Proofview.V82.tactic (clear [id])))
+ (Tacticals.New.tclTHEN (simplest_case c) (clear [id]))
(Array.map2 (fun n l -> tac thin (Some (bracketed,n)) l)
nv_with_let ll)
end }
@@ -2151,20 +2278,20 @@ let rewrite_hyp_then assert_style thin l2r id tac =
let id' = destVar rhs in
subst_on l2r id' lhs, early_clear id' thin
else
- Tacticals.New.tclTHEN (rew_on l2r onConcl) (Proofview.V82.tactic (clear [id])),
+ Tacticals.New.tclTHEN (rew_on l2r onConcl) (clear [id]),
thin
| Some (hdcncl,[c]) ->
let l2r = not l2r in (* equality of the form eq_true *)
if isVar c then
let id' = destVar c in
Tacticals.New.tclTHEN (rew_on l2r allHypsAndConcl)
- (Proofview.V82.tactic (clear_var_and_eq id')),
+ (clear_var_and_eq id'),
early_clear id' thin
else
- Tacticals.New.tclTHEN (rew_on l2r onConcl) (Proofview.V82.tactic (clear [id])),
+ Tacticals.New.tclTHEN (rew_on l2r onConcl) (clear [id]),
thin
| _ ->
- Tacticals.New.tclTHEN (rew_on l2r onConcl) (Proofview.V82.tactic (clear [id])),
+ Tacticals.New.tclTHEN (rew_on l2r onConcl) (clear [id]),
thin in
(* Skip the side conditions of the rewriting step *)
Tacticals.New.tclTHENFIRST eqtac (tac thin)
@@ -2301,7 +2428,7 @@ and intro_pattern_action loc b style pat thin destopt tac id = match pat with
if naming = NamingMustBe (loc,id) then
Proofview.tclUNIT () (* apply_in_once do a replacement *)
else
- Proofview.V82.tactic (clear [id]) in
+ clear [id] in
let f = { delayed = fun env sigma ->
let Sigma (c, sigma, p) = f.delayed env sigma in
Sigma ((c, NoBindings), sigma, p)
@@ -2312,7 +2439,7 @@ and intro_pattern_action loc b style pat thin destopt tac id = match pat with
and prepare_intros_loc loc dft destopt = function
| IntroNaming ipat ->
prepare_naming loc ipat,
- (fun id -> Proofview.V82.tactic (move_hyp id destopt))
+ (fun id -> move_hyp id destopt)
| IntroAction ipat ->
prepare_naming loc dft,
(let tac thin bound =
@@ -2326,9 +2453,10 @@ let intro_patterns_bound_to n destopt =
intro_patterns_core true [] [] [] destopt
(Some (true,n)) 0 (fun _ l -> clear_wildcards l)
-let intro_patterns_to destopt =
+let intro_patterns_to destopt l =
+ (* Eta-expansion because of a side-effect *)
intro_patterns_core (use_bracketing_last_or_and_intro_pattern ())
- [] [] [] destopt None 0 (fun _ l -> clear_wildcards l)
+ [] [] [] destopt None 0 (fun _ l -> clear_wildcards l) l
let intro_pattern_to destopt pat =
intro_patterns_to destopt [dloc,pat]
@@ -2545,8 +2673,7 @@ let forward b usetac ipat c =
Proofview.Goal.enter { enter = begin fun gl ->
let t = Tacmach.New.pf_unsafe_type_of gl c in
let hd = head_ident c in
- Tacticals.New.tclTHENFIRST (assert_as true hd ipat t)
- (Proofview.V82.tactic (exact_no_check c))
+ Tacticals.New.tclTHENFIRST (assert_as true hd ipat t) (exact_no_check c)
end }
| Some tac ->
if b then
@@ -2605,7 +2732,7 @@ let generalize_goal gl i ((occs,c,b),na as o) (cl,sigma) =
let sigma, t = Typing.type_of env sigma c in
generalize_goal_gen env sigma ids i o t cl
-let generalize_dep ?(with_let=false) c gl =
+let old_generalize_dep ?(with_let=false) c gl =
let open Context.Named.Declaration in
let env = pf_env gl in
let sign = pf_hyps gl in
@@ -2640,18 +2767,22 @@ let generalize_dep ?(with_let=false) c gl =
tclTHENLIST
[tclEVARS evd;
Proofview.V82.of_tactic (apply_type cl'' (if Option.is_empty body then c::args else args));
- thin (List.rev tothin')]
+ Proofview.V82.of_tactic (clear (List.rev tothin'))]
gl
+let generalize_dep ?(with_let = false) c =
+ Proofview.V82.tactic (old_generalize_dep ~with_let c)
+
(** *)
-let generalize_gen_let lconstr gl =
+let generalize_gen_let lconstr = Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let newcl, evd =
- List.fold_right_i (generalize_goal gl) 0 lconstr
- (Tacmach.pf_concl gl,Tacmach.project gl)
+ List.fold_right_i (Tacmach.New.of_old generalize_goal gl) 0 lconstr
+ (Tacmach.New.pf_concl gl,Tacmach.New.project gl)
in
- Proofview.V82.of_tactic (Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS evd)
- (apply_type newcl (List.map_filter (fun ((_,c,b),_) ->
- if Option.is_empty b then Some c else None) lconstr))) gl
+ let map ((_, c, b),_) = if Option.is_empty b then Some c else None in
+ let tac = apply_type newcl (List.map_filter map lconstr) in
+ Sigma.Unsafe.of_pair (tac, evd)
+end }
let new_generalize_gen_let lconstr =
Proofview.Goal.s_enter { s_enter = begin fun gl ->
@@ -2671,7 +2802,7 @@ let new_generalize_gen_let lconstr =
0 lconstr (concl, sigma, [])
in
let tac =
- Proofview.Refine.refine { run = begin fun sigma ->
+ Refine.refine { run = begin fun sigma ->
let Sigma (ev, sigma, p) = Evarutil.new_evar env sigma ~principal:true newcl in
Sigma ((applist (ev, args)), sigma, p)
end }
@@ -2687,11 +2818,8 @@ let generalize_gen lconstr =
let new_generalize_gen lconstr =
new_generalize_gen_let (List.map (fun ((occs,c),na) ->
(occs,c,None),na) lconstr)
-
-let generalize l =
- generalize_gen_let (List.map (fun c -> ((AllOccurrences,c,None),Anonymous)) l)
-let new_generalize l =
+let generalize l =
new_generalize_gen_let (List.map (fun c -> ((AllOccurrences,c,None),Anonymous)) l)
(* Faudra-t-il une version avec plusieurs args de generalize_dep ?
@@ -2739,14 +2867,14 @@ let specialize (c,lbind) =
(Proofview.Unsafe.tclEVARS sigma)
(Tacticals.New.tclTHENFIRST
(assert_before_replacing id typ)
- (new_exact_no_check term))
+ (exact_no_check term))
| _ ->
(* To deprecate in favor of generalize? *)
Tacticals.New.tclTHEN
(Proofview.Unsafe.tclEVARS sigma)
(Tacticals.New.tclTHENLAST
(cut typ)
- (new_exact_no_check term))
+ (exact_no_check term))
end }
(*****************************)
@@ -2776,7 +2904,7 @@ let unfold_body x =
end }
(* Either unfold and clear if defined or simply clear if not a definition *)
-let expand_hyp id = Tacticals.New.tclTHEN (Tacticals.New.tclTRY (unfold_body id)) (Proofview.V82.tactic (clear [id]))
+let expand_hyp id = Tacticals.New.tclTRY (unfold_body id) <*> clear [id]
(*****************************)
(* High-level induction *)
@@ -2814,7 +2942,7 @@ let expand_hyp id = Tacticals.New.tclTHEN (Tacticals.New.tclTRY (unfold_body id)
let check_unused_names names =
if not (List.is_empty names) && Flags.is_verbose () then
- msg_warning
+ Feedback.msg_warning
(str"Unused introduction " ++ str (String.plural (List.length names) "pattern")
++ str": " ++ prlist_with_sep spc
(Miscprint.pr_intro_pattern
@@ -3325,7 +3453,7 @@ let mk_term_eq env sigma ty t ty' t' =
let make_abstract_generalize env id typ concl dep ctx body c eqs args refls =
let open Context.Rel.Declaration in
- Proofview.Refine.refine { run = begin fun sigma ->
+ Refine.refine { run = begin fun sigma ->
let eqslen = List.length eqs in
(* Abstract by the "generalized" hypothesis equality proof if necessary. *)
let abshypeq, abshypt =
@@ -3507,18 +3635,18 @@ let abstract_generalize ?(generalize_vars=true) ?(force_dep=false) id =
Tacticals.New.tclTHENLIST [
tac;
rename_hyp [(id, oldid)]; Tacticals.New.tclDO n intro;
- Proofview.V82.tactic (generalize_dep ~with_let:true (mkVar oldid))]
+ generalize_dep ~with_let:true (mkVar oldid)]
else Tacticals.New.tclTHENLIST [
tac;
- Proofview.V82.tactic (clear [id]);
+ clear [id];
Tacticals.New.tclDO n intro]
in
if List.is_empty vars then tac
else Tacticals.New.tclTHEN tac
(Tacticals.New.tclFIRST
[revert vars ;
- Proofview.V82.tactic (fun gl -> tclMAP (fun id ->
- tclTRY (generalize_dep ~with_let:true (mkVar id))) vars gl)])
+ Tacticals.New.tclMAP (fun id ->
+ Tacticals.New.tclTRY (generalize_dep ~with_let:true (mkVar id))) vars])
end }
let rec compare_upto_variables x y =
@@ -3571,17 +3699,16 @@ let specialize_eqs id gl =
let ty' = Evarutil.nf_evar !evars ty' in
if worked then
tclTHENFIRST (Tacmach.internal_cut true id ty')
- (exact_no_check ((* refresh_universes_strict *) acc')) gl
+ (Proofview.V82.of_tactic (exact_no_check ((* refresh_universes_strict *) acc'))) gl
else tclFAIL 0 (str "Nothing to do in hypothesis " ++ pr_id id) gl
-let specialize_eqs id gl =
- if
- (try ignore(clear [id] gl); false
- with e when Errors.noncritical e -> true)
- then
- tclFAIL 0 (str "Specialization not allowed on dependent hypotheses") gl
- else specialize_eqs id gl
+let specialize_eqs id = Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let msg = str "Specialization not allowed on dependent hypotheses" in
+ Proofview.tclOR (clear [id])
+ (fun _ -> Tacticals.New.tclZEROMSG msg) >>= fun () ->
+ Proofview.V82.tactic (specialize_eqs id)
+end }
let occur_rel n c =
let res = not (noccurn n c) in
@@ -3880,10 +4007,10 @@ let recolle_clenv i params args elimclause gl =
let k = match i with -1 -> Array.length lindmv - List.length args | _ -> i in
(* parameters correspond to first elts of lid. *)
let clauses_params =
- List.map_i (fun i id -> mkVar id , Tacmach.pf_get_hyp_typ gl id , lindmv.(i))
+ List.map_i (fun i id -> mkVar id , pf_get_hyp_typ id gl, lindmv.(i))
0 params in
let clauses_args =
- List.map_i (fun i id -> mkVar id , Tacmach.pf_get_hyp_typ gl id , lindmv.(k+i))
+ List.map_i (fun i id -> mkVar id , pf_get_hyp_typ id gl, lindmv.(k+i))
0 args in
let clauses = clauses_params@clauses_args in
(* iteration of clenv_fchain with all infos we have. *)
@@ -3893,7 +4020,7 @@ let recolle_clenv i params args elimclause gl =
(* from_n (Some 0) means that x should be taken "as is" without
trying to unify (which would lead to trying to apply it to
evars if y is a product). *)
- let indclause = mk_clenv_from_n gl (Some 0) (x,y) in
+ let indclause = Tacmach.New.of_old (fun gl -> mk_clenv_from_n gl (Some 0) (x,y)) gl in
let elimclause' = clenv_fchain ~with_univs:false i acc indclause in
elimclause')
(List.rev clauses)
@@ -3903,19 +4030,20 @@ let recolle_clenv i params args elimclause gl =
(elimc ?i ?j ?k...?l). This solves partly meta variables (and may
produce new ones). Then refine with the resulting term with holes.
*)
-let induction_tac with_evars params indvars elim gl =
+let induction_tac with_evars params indvars elim =
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let ({elimindex=i;elimbody=(elimc,lbindelimc);elimrename=rename},elimt) = elim in
let i = match i with None -> index_of_ind_arg elimt | Some i -> i in
(* elimclause contains this: (elimc ?i ?j ?k...?l) *)
let elimc = contract_letin_in_lam_header elimc in
let elimc = mkCast (elimc, DEFAULTcast, elimt) in
- let elimclause =
- Tacmach.pf_apply make_clenv_binding gl (elimc,elimt) lbindelimc in
+ let elimclause = pf_apply make_clenv_binding gl (elimc,elimt) lbindelimc in
(* elimclause' is built from elimclause by instanciating all args and params. *)
let elimclause' = recolle_clenv i params indvars elimclause gl in
(* one last resolution (useless?) *)
- let resolved = clenv_unique_resolver ~flags:(elim_flags ()) elimclause' gl in
- Proofview.V82.of_tactic (enforce_prop_bound_names rename (Clenvtac.clenv_refine with_evars resolved)) gl
+ let resolved = Tacmach.New.of_old (clenv_unique_resolver ~flags:(elim_flags ()) elimclause') gl in
+ enforce_prop_bound_names rename (Clenvtac.clenv_refine with_evars resolved)
+ end }
(* Apply induction "in place" taking into account dependent
hypotheses from the context, replacing the main hypothesis on which
@@ -3962,7 +4090,7 @@ let induction_with_atomization_of_ind_arg isrec with_evars elim names hyp0 inhyp
let elim_info = find_induction_type isrec elim hyp0 (Proofview.Goal.assume gl) in
atomize_param_of_ind_then elim_info hyp0 (fun indvars ->
apply_induction_in_context (Some hyp0) inhyps (pi3 elim_info) indvars names
- (fun elim -> Proofview.V82.tactic (induction_tac with_evars [] [hyp0] elim)))
+ (fun elim -> induction_tac with_evars [] [hyp0] elim))
end }
let msg_not_right_number_induction_arguments scheme =
@@ -4000,23 +4128,24 @@ let induction_without_atomization isrec with_evars elim names lid =
but by chance, because of the addition of at least hyp0 for
cook_sign, it behaved as if there was a real induction arg. *)
if indvars = [] then [List.hd lid_params] else indvars in
- let induct_tac elim = Proofview.V82.tactic (tclTHENLIST [
+ let induct_tac elim = Tacticals.New.tclTHENLIST [
(* pattern to make the predicate appear. *)
- Proofview.V82.of_tactic (reduce (Pattern (List.map inj_with_occurrences lidcstr)) onConcl);
+ reduce (Pattern (List.map inj_with_occurrences lidcstr)) onConcl;
(* Induction by "refine (indscheme ?i ?j ?k...)" + resolution of all
possible holes using arguments given by the user (but the
functional one). *)
(* FIXME: Tester ca avec un principe dependant et non-dependant *)
- induction_tac with_evars params realindvars elim
- ]) in
+ induction_tac with_evars params realindvars elim;
+ ] in
let elim = ElimUsing (({elimindex = Some (-1); elimbody = Option.get scheme.elimc; elimrename = None}, scheme.elimt), indsign) in
apply_induction_in_context None [] elim indvars names induct_tac
end }
(* assume that no occurrences are selected *)
-let clear_unselected_context id inhyps cls gl =
+let clear_unselected_context id inhyps cls =
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let open Context.Named.Declaration in
- if occur_var (Tacmach.pf_env gl) id (Tacmach.pf_concl gl) &&
+ if occur_var (Tacmach.New.pf_env gl) id (Tacmach.New.pf_concl gl) &&
cls.concl_occs == NoOccurrences
then errorlabstrm ""
(str "Conclusion must be mentioned: it depends on " ++ pr_id id
@@ -4028,11 +4157,12 @@ let clear_unselected_context id inhyps cls gl =
if Id.List.mem id' inhyps then (* if selected, do not erase *) None
else
(* erase if not selected and dependent on id or selected hyps *)
- let test id = occur_var_in_decl (pf_env gl) id d in
+ let test id = occur_var_in_decl (Tacmach.New.pf_env gl) id d in
if List.exists test (id::inhyps) then Some id' else None in
- let ids = List.map_filter to_erase (pf_hyps gl) in
- thin ids gl
- | None -> tclIDTAC gl
+ let ids = List.map_filter to_erase (Proofview.Goal.hyps gl) in
+ clear ids
+ | None -> Proofview.tclUNIT ()
+ end }
let use_bindings env sigma elim must_be_closed (c,lbind) typ =
let sigma = Sigma.to_evar_map sigma in
@@ -4095,6 +4225,10 @@ let check_enough_applied env sigma elim =
(* Last argument is supposed to be the induction argument *)
check_expected_type env sigma elimc elimt
+let guard_no_unifiable = Proofview.guard_no_unifiable >>= function
+| None -> Proofview.tclUNIT ()
+| Some l -> Proofview.tclZERO (RefinerError (UnresolvedBindings l))
+
let pose_induction_arg_then isrec with_evars (is_arg_pure_hyp,from_prefix) elim
id ((pending,(c0,lbind)),(eqname,names)) t0 inhyps cls tac =
Proofview.Goal.s_enter { s_enter = begin fun gl ->
@@ -4122,16 +4256,16 @@ let pose_induction_arg_then isrec with_evars (is_arg_pure_hyp,from_prefix) elim
(* and destruct has side conditions first *)
Tacticals.New.tclTHENLAST)
(Tacticals.New.tclTHENLIST [
- Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
+ Refine.refine ~unsafe:true { run = begin fun sigma ->
let b = not with_evars && with_eq != None in
let Sigma (c, sigma, p) = use_bindings env sigma elim b (c0,lbind) t0 in
let t = Retyping.get_type_of env (Sigma.to_evar_map sigma) c in
let Sigma (ans, sigma, q) = mkletin_goal env sigma store with_eq false (id,lastlhyp,ccl,c) (Some t) in
Sigma (ans, sigma, p +> q)
end };
- Proofview.(if with_evars then shelve_unifiable else guard_no_unifiable);
+ if with_evars then Proofview.shelve_unifiable else guard_no_unifiable;
if is_arg_pure_hyp
- then Tacticals.New.tclTRY (Proofview.V82.tactic (thin [destVar c0]))
+ then Tacticals.New.tclTRY (clear [destVar c0])
else Proofview.tclUNIT ();
if isrec then Proofview.cycle (-1) else Proofview.tclUNIT ()
])
@@ -4146,7 +4280,7 @@ let pose_induction_arg_then isrec with_evars (is_arg_pure_hyp,from_prefix) elim
let env = reset_with_named_context sign env in
let tac =
Tacticals.New.tclTHENLIST [
- Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
+ Refine.refine ~unsafe:true { run = begin fun sigma ->
mkletin_goal env sigma store with_eq true (id,lastlhyp,ccl,c) None
end };
tac
@@ -4185,7 +4319,7 @@ let induction_gen clear_flag isrec with_evars elim
and w/o equality kept: no need to generalize *)
let id = destVar c in
Tacticals.New.tclTHEN
- (Proofview.V82.tactic (clear_unselected_context id inhyps cls))
+ (clear_unselected_context id inhyps cls)
(induction_with_atomization_of_ind_arg
isrec with_evars elim names id inhyps)
else
@@ -4635,7 +4769,6 @@ let rec shrink ctx sign c t accu =
| _ -> assert false
let shrink_entry sign const =
- let open Context.Named.Declaration in
let open Entries in
let typ = match const.const_entry_type with
| None -> assert false
@@ -4714,7 +4847,7 @@ let abstract_subproof id gk tac =
Entries.(snd (Future.force const.const_entry_body)) in
let solve =
Proofview.tclEFFECTS effs <*>
- new_exact_no_check (applist (lem, args))
+ exact_no_check (applist (lem, args))
in
let tac = if not safe then Proofview.mark_as_unsafe <*> solve else solve in
Sigma.Unsafe.of_pair (tac, evd)
@@ -4780,7 +4913,7 @@ end
module New = struct
open Proofview.Notations
- let exact_proof c = Proofview.V82.tactic (exact_proof c)
+ let exact_proof c = exact_proof c
open Genredexpr
open Locus
@@ -4791,6 +4924,6 @@ module New = struct
{onhyps=None; concl_occs=AllOccurrences }
let refine ?unsafe c =
- Proofview.Refine.refine ?unsafe c <*>
+ Refine.refine ?unsafe c <*>
reduce_after_refine
end
diff --git a/tactics/tactics.mli b/tactics/tactics.mli
index 26ea01769..fa7b6791e 100644
--- a/tactics/tactics.mli
+++ b/tactics/tactics.mli
@@ -21,7 +21,10 @@ open Unification
open Misctypes
open Locus
-(** Main tactics. *)
+(** Main tactics defined in ML. This file is huge and should probably be split
+ in more reasonable units at some point. Because of its size and age, the
+ implementation features various styles and stages of the proof engine.
+ This has to be uniformized someday. *)
(** {6 General functions. } *)
@@ -30,17 +33,15 @@ val is_quantified_hypothesis : Id.t -> ([`NF],'b) Proofview.Goal.t -> bool
(** {6 Primitive tactics. } *)
val introduction : ?check:bool -> Id.t -> unit Proofview.tactic
-val refine : constr -> tactic
val convert_concl : ?check:bool -> types -> cast_kind -> unit Proofview.tactic
val convert_hyp : ?check:bool -> Context.Named.Declaration.t -> unit Proofview.tactic
val convert_concl_no_check : types -> cast_kind -> unit Proofview.tactic
val convert_hyp_no_check : Context.Named.Declaration.t -> unit Proofview.tactic
-val thin : Id.t list -> tactic
val mutual_fix :
- Id.t -> int -> (Id.t * int * constr) list -> int -> tactic
-val fix : Id.t option -> int -> tactic
-val mutual_cofix : Id.t -> (Id.t * constr) list -> int -> tactic
-val cofix : Id.t option -> tactic
+ Id.t -> int -> (Id.t * int * constr) list -> int -> unit Proofview.tactic
+val fix : Id.t option -> int -> unit Proofview.tactic
+val mutual_cofix : Id.t -> (Id.t * constr) list -> int -> unit Proofview.tactic
+val cofix : Id.t option -> unit Proofview.tactic
val convert : constr -> constr -> unit Proofview.tactic
val convert_leq : constr -> constr -> unit Proofview.tactic
@@ -115,11 +116,11 @@ val intros_patterns : intro_patterns -> unit Proofview.tactic
(** {6 Exact tactics. } *)
val assumption : unit Proofview.tactic
-val exact_no_check : constr -> tactic
-val vm_cast_no_check : constr -> tactic
-val native_cast_no_check : constr -> tactic
+val exact_no_check : constr -> unit Proofview.tactic
+val vm_cast_no_check : constr -> unit Proofview.tactic
+val native_cast_no_check : constr -> unit Proofview.tactic
val exact_check : constr -> unit Proofview.tactic
-val exact_proof : Constrexpr.constr_expr -> tactic
+val exact_proof : Constrexpr.constr_expr -> unit Proofview.tactic
(** {6 Reduction tactics. } *)
@@ -155,7 +156,7 @@ val unfold_in_hyp :
val unfold_option :
(occurrences * evaluable_global_reference) list -> goal_location -> unit Proofview.tactic
val change :
- constr_pattern option -> change_arg -> clause -> tactic
+ constr_pattern option -> change_arg -> clause -> unit Proofview.tactic
val pattern_option :
(occurrences * constr) list -> goal_location -> unit Proofview.tactic
val reduce : red_expr -> clause -> unit Proofview.tactic
@@ -163,7 +164,7 @@ val unfold_constr : global_reference -> unit Proofview.tactic
(** {6 Modification of the local context. } *)
-val clear : Id.t list -> tactic
+val clear : Id.t list -> unit Proofview.tactic
val clear_body : Id.t list -> unit Proofview.tactic
val unfold_body : Id.t -> unit Proofview.tactic
val keep : Id.t list -> unit Proofview.tactic
@@ -171,7 +172,7 @@ val apply_clear_request : clear_flag -> bool -> constr -> unit Proofview.tactic
val specialize : constr with_bindings -> unit Proofview.tactic
-val move_hyp : Id.t -> Id.t move_location -> tactic
+val move_hyp : Id.t -> Id.t move_location -> unit Proofview.tactic
val rename_hyp : (Id.t * Id.t) list -> unit Proofview.tactic
val revert : Id.t list -> unit Proofview.tactic
@@ -384,13 +385,12 @@ val letin_pat_tac : (bool * intro_pattern_naming) option ->
(** {6 Generalize tactics. } *)
-val generalize : constr list -> tactic
-val generalize_gen : (constr Locus.with_occurrences * Name.t) list -> tactic
+val generalize : constr list -> unit Proofview.tactic
+val generalize_gen : (constr Locus.with_occurrences * Name.t) list -> unit Proofview.tactic
-val new_generalize : constr list -> unit Proofview.tactic
val new_generalize_gen : ((occurrences * constr) * Name.t) list -> unit Proofview.tactic
-val generalize_dep : ?with_let:bool (** Don't lose let bindings *) -> constr -> tactic
+val generalize_dep : ?with_let:bool (** Don't lose let bindings *) -> constr -> unit Proofview.tactic
(** {6 Other tactics. } *)
@@ -399,7 +399,7 @@ val unify : ?state:Names.transparent_state -> constr -> constr -> unit
val tclABSTRACT : Id.t option -> unit Proofview.tactic -> unit Proofview.tactic
val abstract_generalize : ?generalize_vars:bool -> ?force_dep:bool -> Id.t -> unit Proofview.tactic
-val specialize_eqs : Id.t -> tactic
+val specialize_eqs : Id.t -> unit Proofview.tactic
val general_rewrite_clause :
(bool -> evars_flag -> constr with_bindings -> clause -> unit Proofview.tactic) Hook.t
@@ -431,12 +431,10 @@ end
module New : sig
val refine : ?unsafe:bool -> constr Sigma.run -> unit Proofview.tactic
- (** [refine ?unsafe c] is [Proofview.Refine.refine ?unsafe c]
+ (** [refine ?unsafe c] is [Refine.refine ?unsafe c]
followed by beta-iota-reduction of the conclusion. *)
val reduce_after_refine : unit Proofview.tactic
(** The reducing tactic called after {!refine}. *)
- open Proofview
- val exact_proof : Constrexpr.constr_expr -> unit tactic
end
diff --git a/tactics/tactics.mllib b/tactics/tactics.mllib
index 2c5edc20e..48722f655 100644
--- a/tactics/tactics.mllib
+++ b/tactics/tactics.mllib
@@ -1,5 +1,3 @@
-Ftactic
-Geninterp
Dnet
Dn
Btermdn
@@ -14,15 +12,12 @@ Equality
Contradiction
Inv
Leminv
-Tacsubst
Taccoerce
-Tacenv
Hints
Auto
-Tacintern
+Eauto
+Class_tactics
Tactic_matching
-Tacinterp
-Evar_tactics
Term_dnet
+Eqdecide
Autorewrite
-Tactic_option
diff --git a/test-suite/Makefile b/test-suite/Makefile
index f333ae63e..b9c27a2fc 100644
--- a/test-suite/Makefile
+++ b/test-suite/Makefile
@@ -92,7 +92,7 @@ SUBSYSTEMS := $(VSUBSYSTEMS) misc bugs ide vio coqchk
.PHONY: all run clean $(SUBSYSTEMS)
all: run
- $(MAKE) --quiet summary.log
+ $(MAKE) report
run: $(SUBSYSTEMS)
bugs: $(BUGS)
@@ -151,11 +151,11 @@ summary:
}
summary.log:
- $(SHOW) SUMMARY
+ $(SHOW) BUILDING SUMMARY FILE
$(HIDE)$(MAKE) --quiet summary > "$@"
report: summary.log
- $(HIDE)if grep -F 'Error!' summary.log ; then false; fi
+ $(HIDE)if grep -q -F 'Error!' summary.log ; then echo FAILURES; grep -F 'Error!' summary.log; false; else echo NO FAILURES; fi
#######################################################################
# Regression (and progression) tests
@@ -242,7 +242,6 @@ $(addsuffix .log,$(wildcard stm/*.v)): %.v.log: %.v
$(HIDE){ \
echo $(call log_intro,$<); \
$(coqc) "$<" $(call get_coq_prog_args,"$<") -async-proofs on \
- -async-proofs-private-flags fallback-to-lazy-if-marshal-error=no,fallback-to-lazy-if-slave-dies=no \
$$opts 2>&1; R=$$?; times; \
if [ $$R = 0 ]; then \
echo $(log_success); \
@@ -422,7 +421,7 @@ ide : $(patsubst %.fake,%.fake.log,$(wildcard ide/*.fake))
@echo "TEST $<"
$(HIDE){ \
echo $(call log_intro,$<); \
- $(BIN)fake_ide $< "$(BIN)coqtop -boot -async-proofs on" 2>&1; \
+ $(BIN)fake_ide $< "$(BIN)coqtop -boot -async-proofs on -async-proofs-tactic-error-resiliency off -async-proofs-command-error-resiliency off" 2>&1; \
if [ $$? = 0 ]; then \
echo $(log_success); \
echo " $<...Ok"; \
diff --git a/test-suite/bugs/4623.v b/test-suite/bugs/4623.v
new file mode 100644
index 000000000..405d09809
--- /dev/null
+++ b/test-suite/bugs/4623.v
@@ -0,0 +1,5 @@
+Goal Type -> Type.
+set (T := Type).
+clearbody T.
+refine (@id _).
+Qed. \ No newline at end of file
diff --git a/test-suite/bugs/4624.v b/test-suite/bugs/4624.v
new file mode 100644
index 000000000..a737afcda
--- /dev/null
+++ b/test-suite/bugs/4624.v
@@ -0,0 +1,7 @@
+Record foo := mkfoo { type : Type }.
+
+Canonical Structure fooA (T : Type) := mkfoo (T -> T).
+
+Definition id (t : foo) (x : type t) := x.
+
+Definition bar := id _ ((fun x : nat => x) : _). \ No newline at end of file
diff --git a/test-suite/bugs/closed/1850.v b/test-suite/bugs/closed/1850.v
new file mode 100644
index 000000000..26b48093b
--- /dev/null
+++ b/test-suite/bugs/closed/1850.v
@@ -0,0 +1,4 @@
+Parameter P : Type -> Type -> Type.
+Notation "e |= t --> v" := (P e t v) (at level 100, t at level 54).
+Fail Check (nat |= nat --> nat).
+
diff --git a/test-suite/bugs/closed/2848.v b/test-suite/bugs/closed/2848.v
index de137d39d..828e3b8c1 100644
--- a/test-suite/bugs/closed/2848.v
+++ b/test-suite/bugs/closed/2848.v
@@ -2,8 +2,9 @@ Require Import Setoid.
Parameter value' : Type.
Parameter equiv' : value' -> value' -> Prop.
-
+Axiom cheat : forall {A}, A.
Add Parametric Relation : _ equiv'
- reflexivity proved by (Equivalence.equiv_reflexive _)
- transitivity proved by (Equivalence.equiv_transitive _)
+ reflexivity proved by (Equivalence.equiv_reflexive cheat)
+ transitivity proved by (Equivalence.equiv_transitive cheat)
as apply_equiv'_rel.
+Check apply_equiv'_rel : PreOrder equiv'. \ No newline at end of file
diff --git a/test-suite/bugs/closed/3080.v b/test-suite/bugs/closed/3080.v
new file mode 100644
index 000000000..7d0dc090e
--- /dev/null
+++ b/test-suite/bugs/closed/3080.v
@@ -0,0 +1,18 @@
+(* -*- coq-prog-args: ("-emacs" "-nois") -*- *)
+Delimit Scope type_scope with type.
+Delimit Scope function_scope with function.
+
+Bind Scope type_scope with Sortclass.
+Bind Scope function_scope with Funclass.
+
+Reserved Notation "x -> y" (at level 99, right associativity, y at level 200).
+Notation "A -> B" := (forall (_ : A), B) : type_scope.
+
+Definition compose {A B C} (g : B -> C) (f : A -> B) :=
+ fun x : A => g (f x).
+
+Notation " g ∘ f " := (compose g f)
+ (at level 40, left associativity) : function_scope.
+
+Fail Check (fun x => x) ∘ (fun x => x). (* this [Check] should fail, as [function_scope] is not opened *)
+Check compose ((fun x => x) ∘ (fun x => x)) (fun x => x). (* this check should succeed, as [function_scope] should be automatically bound in the arugments to [compose] *)
diff --git a/test-suite/bugs/closed/3612.v b/test-suite/bugs/closed/3612.v
index 25060debe..a54768507 100644
--- a/test-suite/bugs/closed/3612.v
+++ b/test-suite/bugs/closed/3612.v
@@ -6,6 +6,8 @@ lines, then from 421 lines to 428 lines, then from 444 lines to 429 lines, then
Reserved Notation "x -> y" (at level 99, right associativity, y at level 200).
Reserved Notation "x = y :> T" (at level 70, y at next level, no associativity).
Reserved Notation "x = y" (at level 70, no associativity).
+Delimit Scope type_scope with type.
+Bind Scope type_scope with Sortclass.
Open Scope type_scope.
Global Set Universe Polymorphism.
Notation "A -> B" := (forall (_ : A), B) : type_scope.
diff --git a/test-suite/bugs/closed/3649.v b/test-suite/bugs/closed/3649.v
index 06188e7b1..fc4c171e2 100644
--- a/test-suite/bugs/closed/3649.v
+++ b/test-suite/bugs/closed/3649.v
@@ -2,8 +2,11 @@
(* File reduced by coq-bug-finder from original input, then from 9518 lines to 404 lines, then from 410 lines to 208 lines, then from 162 lines to 77 lines *)
(* coqc version trunk (September 2014) compiled on Sep 18 2014 21:0:5 with OCaml 4.01.0
coqtop version cagnode16:/afs/csail.mit.edu/u/j/jgross/coq-trunk,trunk (07e4438bd758c2ced8caf09a6961ccd77d84e42b) *)
+Declare ML Module "coretactics".
Reserved Notation "x -> y" (at level 99, right associativity, y at level 200).
Reserved Notation "x = y" (at level 70, no associativity).
+Delimit Scope type_scope with type.
+Bind Scope type_scope with Sortclass.
Open Scope type_scope.
Axiom admit : forall {T}, T.
Notation "A -> B" := (forall (_ : A), B) : type_scope.
@@ -54,4 +57,4 @@ Goal forall (C D : PreCategory) (G G' : Functor C D)
(** This [change] succeeded, but did not progress, in 07e4438bd758c2ced8caf09a6961ccd77d84e42b, because [T0 x o T1 x] was not found in the goal *)
let T0 := match goal with |- context[components_of ?T0 ?x o components_of ?T1 ?x] => constr:(T0) end in
let T1 := match goal with |- context[components_of ?T0 ?x o components_of ?T1 ?x] => constr:(T1) end in
- progress change (T0 x o T1 x) with ((fun y => y) (T0 x o T1 x)). \ No newline at end of file
+ progress change (T0 x o T1 x) with ((fun y => y) (T0 x o T1 x)).
diff --git a/test-suite/bugs/closed/3699.v b/test-suite/bugs/closed/3699.v
index aad0bb44d..8dadc2419 100644
--- a/test-suite/bugs/closed/3699.v
+++ b/test-suite/bugs/closed/3699.v
@@ -65,7 +65,7 @@ Module NonPrim.
set (fibermap := fun a0p : hfiber f (f a)
=> let (a0, p) := a0p in transport P p (d a0)).
Set Printing Implicit.
- let G := match goal with |- ?G => constr:G end in
+ let G := match goal with |- ?G => constr:(G) end in
first [ match goal with
| [ |- (@isconnected_elim n (@hfiber A B f (f a))
(@isconnected_hfiber_conn_map n A B f H (f a))
@@ -142,7 +142,7 @@ Module Prim.
set (fibermap := fun a0p : hfiber f (f a)
=> let (a0, p) := a0p in transport P p (d a0)).
Set Printing Implicit.
- let G := match goal with |- ?G => constr:G end in
+ let G := match goal with |- ?G => constr:(G) end in
first [ match goal with
| [ |- (@isconnected_elim n (@hfiber A B f (f a))
(@isconnected_hfiber_conn_map n A B f H (f a))
diff --git a/test-suite/bugs/closed/3825.v b/test-suite/bugs/closed/3825.v
new file mode 100644
index 000000000..e594b74b6
--- /dev/null
+++ b/test-suite/bugs/closed/3825.v
@@ -0,0 +1,16 @@
+Set Universe Polymorphism.
+Set Printing Universes.
+
+Axiom foo@{i j} : Type@{i} -> Type@{j}.
+
+Notation bar := foo.
+
+Monomorphic Universes i j.
+
+Check bar@{i j}.
+Fail Check bar@{i}.
+
+Notation qux := (nat -> nat).
+
+Fail Check qux@{i}.
+
diff --git a/test-suite/bugs/closed/3881.v b/test-suite/bugs/closed/3881.v
index 070d1e9c7..a327bbf2a 100644
--- a/test-suite/bugs/closed/3881.v
+++ b/test-suite/bugs/closed/3881.v
@@ -23,7 +23,7 @@ Proof.
pose (fun H => @isequiv_homotopic _ _ ((g o f) o f^-1) _ H
(fun b => ap g (eisretr f b))) as k.
revert k.
- let x := match goal with |- let k := ?x in _ => constr:x end in
+ let x := match goal with |- let k := ?x in _ => constr:(x) end in
intro k; clear k;
pose (x _).
pose (@isequiv_homotopic _ _ ((g o f) o f^-1) g _
diff --git a/test-suite/bugs/closed/3922.v b/test-suite/bugs/closed/3922.v
index 5013bc6ac..d88e8c332 100644
--- a/test-suite/bugs/closed/3922.v
+++ b/test-suite/bugs/closed/3922.v
@@ -73,7 +73,7 @@ Definition Trunc_ind {n A}
(P : Trunc n A -> Type) {Pt : forall aa, IsTrunc n (P aa)}
: (forall a, P (tr a)) -> (forall aa, P aa)
:= (fun f aa => match aa with tr a => fun _ => f a end Pt).
-Definition merely (A : Type@{i}) : hProp@{i} := BuildhProp (Trunc -1 A).
+Definition merely (A : Type@{i}) : hProp := BuildhProp (Trunc -1 A).
Definition cconst_factors_contr `{Funext} {X Y : Type} (f : X -> Y)
(P : Type) `{Pc : X -> Contr P}
(g : X -> P) (h : P -> Y) (p : h o g == f)
diff --git a/test-suite/bugs/closed/4292.v b/test-suite/bugs/closed/4292.v
new file mode 100644
index 000000000..403e155ea
--- /dev/null
+++ b/test-suite/bugs/closed/4292.v
@@ -0,0 +1,7 @@
+Module Type S. End S.
+
+Declare Module M : S.
+
+Module Type F (T: S). End F.
+
+Fail Module Type N := F with Module T := M.
diff --git a/test-suite/bugs/closed/4498.v b/test-suite/bugs/closed/4498.v
new file mode 100644
index 000000000..ccdb2dddd
--- /dev/null
+++ b/test-suite/bugs/closed/4498.v
@@ -0,0 +1,24 @@
+Require Export Coq.Unicode.Utf8.
+Require Export Coq.Classes.Morphisms.
+Require Export Coq.Relations.Relation_Definitions.
+
+Set Universe Polymorphism.
+
+Reserved Notation "a ~> b" (at level 90, right associativity).
+
+Class Category := {
+ ob : Type;
+ uhom := Type : Type;
+ hom : ob → ob → uhom where "a ~> b" := (hom a b);
+ compose : ∀ {A B C}, (B ~> C) → (A ~> B) → (A ~> C);
+ equiv : ∀ {A B}, relation (A ~> B);
+ is_equiv : ∀ {A B}, @Equivalence (A ~> B) equiv;
+ comp_respects : ∀ {A B C},
+ Proper (@equiv B C ==> @equiv A B ==> @equiv A C) (@compose A B C);
+}.
+
+Require Export Coq.Setoids.Setoid.
+
+Add Parametric Morphism `{C : Category} {A B C} : (@compose _ A B C) with
+ signature equiv ==> equiv ==> equiv as compose_mor.
+Proof. apply comp_respects. Qed. \ No newline at end of file
diff --git a/test-suite/bugs/closed/4533.v b/test-suite/bugs/closed/4533.v
new file mode 100644
index 000000000..ae17fb145
--- /dev/null
+++ b/test-suite/bugs/closed/4533.v
@@ -0,0 +1,226 @@
+(* -*- mode: coq; coq-prog-args: ("-emacs" "-nois" "-indices-matter" "-R" "." "Top" "-top" "bug_lex_wrong_rewrite_02") -*- *)
+(* File reduced by coq-bug-finder from original input, then from 1125 lines to
+346 lines, then from 360 lines to 346 lines, then from 822 lines to 271 lines,
+then from 285 lines to 271 lines *)
+(* coqc version 8.5 (January 2016) compiled on Jan 23 2016 16:15:22 with OCaml
+4.01.0
+ coqtop version 8.5 (January 2016) *)
+Inductive False := .
+Axiom proof_admitted : False.
+Tactic Notation "admit" := case proof_admitted.
+Require Coq.Init.Datatypes.
+Import Coq.Init.Notations.
+Global Set Universe Polymorphism.
+Global Set Primitive Projections.
+Notation "A -> B" := (forall (_ : A), B) : type_scope.
+Module Export Datatypes.
+ Set Implicit Arguments.
+ Notation nat := Coq.Init.Datatypes.nat.
+ Notation S := Coq.Init.Datatypes.S.
+ Record prod (A B : Type) := pair { fst : A ; snd : B }.
+ Notation "x * y" := (prod x y) : type_scope.
+ Delimit Scope nat_scope with nat.
+ Open Scope nat_scope.
+End Datatypes.
+Module Export Specif.
+ Set Implicit Arguments.
+ Record sig {A} (P : A -> Type) := exist { proj1_sig : A ; proj2_sig : P
+proj1_sig }.
+ Notation sigT := sig (only parsing).
+ Notation "{ x : A & P }" := (sigT (fun x:A => P)) : type_scope.
+ Notation projT1 := proj1_sig (only parsing).
+ Notation projT2 := proj2_sig (only parsing).
+End Specif.
+Global Set Keyed Unification.
+Global Unset Strict Universe Declaration.
+Definition Type1@{i} := Eval hnf in let gt := (Set : Type@{i}) in Type@{i}.
+Definition Type2@{i j} := Eval hnf in let gt := (Type1@{j} : Type@{i}) in
+Type@{i}.
+Definition Type2le@{i j} := Eval hnf in let gt := (Set : Type@{i}) in
+ let ge := ((fun x => x) : Type1@{j} ->
+Type@{i}) in Type@{i}.
+Notation idmap := (fun x => x).
+Delimit Scope function_scope with function.
+Delimit Scope path_scope with path.
+Delimit Scope fibration_scope with fibration.
+Open Scope fibration_scope.
+Open Scope function_scope.
+Notation pr1 := projT1.
+Notation pr2 := projT2.
+Notation "x .1" := (pr1 x) (at level 3, format "x '.1'") : fibration_scope.
+Notation "x .2" := (pr2 x) (at level 3, format "x '.2'") : fibration_scope.
+Notation compose := (fun g f x => g (f x)).
+Notation "g 'o' f" := (compose g%function f%function) (at level 40, left
+associativity) : function_scope.
+Inductive paths {A : Type} (a : A) : A -> Type := idpath : paths a a.
+Arguments idpath {A a} , [A] a.
+Notation "x = y :> A" := (@paths A x y) : type_scope.
+Notation "x = y" := (x = y :>_) : type_scope.
+Definition inverse {A : Type} {x y : A} (p : x = y) : y = x
+ := match p with idpath => idpath end.
+Definition concat {A : Type} {x y z : A} (p : x = y) (q : y = z) : x = z :=
+ match p, q with idpath, idpath => idpath end.
+Notation "1" := idpath : path_scope.
+Notation "p @ q" := (concat p%path q%path) (at level 20) : path_scope.
+Notation "p ^" := (inverse p%path) (at level 3, format "p '^'") : path_scope.
+Definition ap {A B:Type} (f:A -> B) {x y:A} (p:x = y) : f x = f y
+ := match p with idpath => idpath end.
+Definition pointwise_paths {A} {P:A->Type} (f g:forall x:A, P x)
+ := forall x:A, f x = g x.
+Notation "f == g" := (pointwise_paths f g) (at level 70, no associativity) :
+type_scope.
+Definition Sect {A B : Type} (s : A -> B) (r : B -> A) :=
+ forall x : A, r (s x) = x.
+Class IsEquiv {A B : Type} (f : A -> B) := BuildIsEquiv {
+ equiv_inv : B -> A ;
+ eisretr : Sect equiv_inv f;
+ eissect : Sect f equiv_inv;
+ eisadj : forall x : A, eisretr
+(f x) = ap f (eissect x)
+ }.
+Arguments eissect {A B}%type_scope f%function_scope {_} _.
+Inductive Unit : Type1 := tt : Unit.
+Local Open Scope path_scope.
+Definition concat_p_pp {A : Type} {x y z t : A} (p : x = y) (q : y = z) (r : z
+= t) :
+ p @ (q @ r) = (p @ q) @ r :=
+ match r with idpath =>
+ match q with idpath =>
+ match p with idpath => 1
+ end end end.
+Section Adjointify.
+ Context {A B : Type} (f : A -> B) (g : B -> A).
+ Context (isretr : Sect g f) (issect : Sect f g).
+ Let issect' := fun x =>
+ ap g (ap f (issect x)^) @ ap g (isretr (f x)) @ issect x.
+
+ Let is_adjoint' (a : A) : isretr (f a) = ap f (issect' a).
+ admit.
+ Defined.
+
+ Definition isequiv_adjointify : IsEquiv f
+ := BuildIsEquiv A B f g isretr issect' is_adjoint'.
+End Adjointify.
+Definition ExtensionAlong {A B : Type} (f : A -> B)
+ (P : B -> Type) (d : forall x:A, P (f x))
+ := { s : forall y:B, P y & forall x:A, s (f x) = d x }.
+Fixpoint ExtendableAlong@{i j k l}
+ (n : nat) {A : Type@{i}} {B : Type@{j}}
+ (f : A -> B) (C : B -> Type@{k}) : Type@{l}
+ := match n with
+ | 0 => Unit@{l}
+ | S n => (forall (g : forall a, C (f a)),
+ ExtensionAlong@{i j k l l} f C g) *
+ forall (h k : forall b, C b),
+ ExtendableAlong n f (fun b => h b = k b)
+ end.
+
+Definition ooExtendableAlong@{i j k l}
+ {A : Type@{i}} {B : Type@{j}}
+ (f : A -> B) (C : B -> Type@{k}) : Type@{l}
+ := forall n, ExtendableAlong@{i j k l} n f C.
+
+Module Type ReflectiveSubuniverses.
+
+ Parameter ReflectiveSubuniverse@{u a} : Type2@{u a}.
+
+ Parameter O_reflector@{u a i} : forall (O : ReflectiveSubuniverse@{u a}),
+ Type2le@{i a} -> Type2le@{i a}.
+
+ Parameter In@{u a i} : forall (O : ReflectiveSubuniverse@{u a}),
+ Type2le@{i a} -> Type2le@{i a}.
+
+ Parameter O_inO@{u a i} : forall (O : ReflectiveSubuniverse@{u a}) (T :
+Type@{i}),
+ In@{u a i} O (O_reflector@{u a i} O T).
+
+ Parameter to@{u a i} : forall (O : ReflectiveSubuniverse@{u a}) (T :
+Type@{i}),
+ T -> O_reflector@{u a i} O T.
+
+ Parameter extendable_to_O@{u a i j k}
+ : forall (O : ReflectiveSubuniverse@{u a}) {P : Type2le@{i a}} {Q :
+Type2le@{j a}} {Q_inO : In@{u a j} O Q},
+ ooExtendableAlong@{i i j k} (to O P) (fun _ => Q).
+
+End ReflectiveSubuniverses.
+
+Module ReflectiveSubuniverses_Theory (Os : ReflectiveSubuniverses).
+ Export Os.
+ Existing Class In.
+ Module Export Coercions.
+ Coercion O_reflector : ReflectiveSubuniverse >-> Funclass.
+ End Coercions.
+ Global Existing Instance O_inO.
+
+ Section ORecursion.
+ Context {O : ReflectiveSubuniverse}.
+
+ Definition O_rec {P Q : Type} {Q_inO : In O Q}
+ (f : P -> Q)
+ : O P -> Q
+ := (fst (extendable_to_O O 1%nat) f).1.
+
+ Definition O_rec_beta {P Q : Type} {Q_inO : In O Q}
+ (f : P -> Q) (x : P)
+ : O_rec f (to O P x) = f x
+ := (fst (extendable_to_O O 1%nat) f).2 x.
+
+ Definition O_indpaths {P Q : Type} {Q_inO : In O Q}
+ (g h : O P -> Q) (p : g o to O P == h o to O P)
+ : g == h
+ := (fst (snd (extendable_to_O O 2) g h) p).1.
+
+ End ORecursion.
+
+
+ Section Reflective_Subuniverse.
+ Context (O : ReflectiveSubuniverse@{Ou Oa}).
+
+ Definition isequiv_to_O_inO@{u a i} (T : Type@{i}) `{In@{u a i} O T} :
+IsEquiv@{i i} (to O T).
+ Proof.
+
+ pose (g := O_rec@{u a i i i i i} idmap).
+ refine (isequiv_adjointify (to O T) g _ _).
+ -
+ refine (O_indpaths@{u a i i i i i} (to O T o g) idmap _).
+ intros x.
+ apply ap.
+ apply O_rec_beta.
+ -
+ intros x.
+ apply O_rec_beta.
+ Defined.
+ Global Existing Instance isequiv_to_O_inO.
+
+ End Reflective_Subuniverse.
+
+End ReflectiveSubuniverses_Theory.
+
+Module Type Preserves_Fibers (Os : ReflectiveSubuniverses).
+ Module Export Os_Theory := ReflectiveSubuniverses_Theory Os.
+End Preserves_Fibers.
+
+Opaque eissect.
+Module Lex_Reflective_Subuniverses
+ (Os : ReflectiveSubuniverses) (Opf : Preserves_Fibers Os).
+ Import Opf.
+ Goal forall (O : ReflectiveSubuniverse) (A : Type) (B : A -> Type) (A_inO :
+In O A),
+
+ forall g,
+ forall (x : O {x : A & B x}) v v' v'' (p2 : v'' = v') (p0 : v' = v) (p1 :
+v = _) r,
+ (p2
+ @ (p0
+ @ p1))
+ @ eissect (to O A) (g x) = r.
+ intros.
+ cbv zeta.
+ rewrite concat_p_pp.
+ match goal with
+ | [ |- p2 @ p0 @ p1 @ eissect (to O A) (g x) = r ] => idtac "good"
+ | [ |- ?G ] => fail 1 "bad" G
+ end.
+ Fail rewrite concat_p_pp. \ No newline at end of file
diff --git a/test-suite/bugs/closed/4538.v b/test-suite/bugs/closed/4538.v
new file mode 100644
index 000000000..f925aae9e
--- /dev/null
+++ b/test-suite/bugs/closed/4538.v
@@ -0,0 +1 @@
+Reserved Notation " (u *) ".
diff --git a/test-suite/bugs/closed/4544.v b/test-suite/bugs/closed/4544.v
new file mode 100644
index 000000000..048f31ce3
--- /dev/null
+++ b/test-suite/bugs/closed/4544.v
@@ -0,0 +1,1007 @@
+(* -*- mode: coq; coq-prog-args: ("-emacs" "-nois" "-indices-matter" "-R" "." "Top" "-top" "bug_oog_looping_rewrite_01") -*- *)
+(* File reduced by coq-bug-finder from original input, then from 2553 lines to 1932 lines, then from 1946 lines to 1932 lines, then from 2467 lines to 1002 lines, then from 1016 lines to 1002 lines *)
+(* coqc version 8.5 (January 2016) compiled on Jan 23 2016 16:15:22 with OCaml 4.01.0
+ coqtop version 8.5 (January 2016) *)
+Inductive False := .
+Axiom proof_admitted : False.
+Tactic Notation "admit" := case proof_admitted.
+Require Coq.Init.Datatypes.
+
+Import Coq.Init.Notations.
+
+Global Set Universe Polymorphism.
+
+Notation "A -> B" := (forall (_ : A), B) : type_scope.
+Global Set Primitive Projections.
+
+Inductive sum (A B : Type) : Type :=
+ | inl : A -> sum A B
+ | inr : B -> sum A B.
+Notation nat := Coq.Init.Datatypes.nat.
+Notation S := Coq.Init.Datatypes.S.
+Notation "x + y" := (sum x y) : type_scope.
+
+Record prod (A B : Type) := pair { fst : A ; snd : B }.
+
+Notation "x * y" := (prod x y) : type_scope.
+Module Export Specif.
+
+Set Implicit Arguments.
+
+Record sig {A} (P : A -> Type) := exist { proj1_sig : A ; proj2_sig : P proj1_sig }.
+Arguments proj1_sig {A P} _ / .
+
+Notation sigT := sig (only parsing).
+Notation existT := exist (only parsing).
+
+Notation "{ x : A & P }" := (sigT (fun x:A => P)) : type_scope.
+
+Notation projT1 := proj1_sig (only parsing).
+Notation projT2 := proj2_sig (only parsing).
+
+End Specif.
+Module Export HoTT_DOT_Basics_DOT_Overture.
+Module Export HoTT.
+Module Export Basics.
+Module Export Overture.
+
+Global Set Keyed Unification.
+
+Global Unset Strict Universe Declaration.
+
+Notation Type0 := Set.
+
+Definition Type1@{i} := Eval hnf in let gt := (Set : Type@{i}) in Type@{i}.
+
+Definition Type2@{i j} := Eval hnf in let gt := (Type1@{j} : Type@{i}) in Type@{i}.
+
+Definition Type2le@{i j} := Eval hnf in let gt := (Set : Type@{i}) in
+ let ge := ((fun x => x) : Type1@{j} -> Type@{i}) in Type@{i}.
+
+Notation idmap := (fun x => x).
+Delimit Scope function_scope with function.
+Delimit Scope path_scope with path.
+Delimit Scope fibration_scope with fibration.
+Delimit Scope trunc_scope with trunc.
+
+Open Scope trunc_scope.
+Open Scope path_scope.
+Open Scope fibration_scope.
+Open Scope nat_scope.
+Open Scope function_scope.
+
+Notation "( x ; y )" := (existT _ x y) : fibration_scope.
+
+Notation pr1 := projT1.
+Notation pr2 := projT2.
+
+Notation "x .1" := (pr1 x) (at level 3, format "x '.1'") : fibration_scope.
+Notation "x .2" := (pr2 x) (at level 3, format "x '.2'") : fibration_scope.
+
+Notation compose := (fun g f x => g (f x)).
+
+Notation "g 'o' f" := (compose g%function f%function) (at level 40, left associativity) : function_scope.
+
+Inductive paths {A : Type} (a : A) : A -> Type :=
+ idpath : paths a a.
+
+Arguments idpath {A a} , [A] a.
+
+Notation "x = y :> A" := (@paths A x y) : type_scope.
+Notation "x = y" := (x = y :>_) : type_scope.
+
+Definition inverse {A : Type} {x y : A} (p : x = y) : y = x
+ := match p with idpath => idpath end.
+
+Definition concat {A : Type} {x y z : A} (p : x = y) (q : y = z) : x = z :=
+ match p, q with idpath, idpath => idpath end.
+
+Notation "1" := idpath : path_scope.
+
+Notation "p @ q" := (concat p%path q%path) (at level 20) : path_scope.
+
+Notation "p ^" := (inverse p%path) (at level 3, format "p '^'") : path_scope.
+
+Definition transport {A : Type} (P : A -> Type) {x y : A} (p : x = y) (u : P x) : P y :=
+ match p with idpath => u end.
+
+Notation "p # x" := (transport _ p x) (right associativity, at level 65, only parsing) : path_scope.
+
+Definition ap {A B:Type} (f:A -> B) {x y:A} (p:x = y) : f x = f y
+ := match p with idpath => idpath end.
+
+Definition pointwise_paths {A} {P:A->Type} (f g:forall x:A, P x)
+ := forall x:A, f x = g x.
+
+Notation "f == g" := (pointwise_paths f g) (at level 70, no associativity) : type_scope.
+
+Definition Sect {A B : Type} (s : A -> B) (r : B -> A) :=
+ forall x : A, r (s x) = x.
+
+Class IsEquiv {A B : Type} (f : A -> B) := BuildIsEquiv {
+ equiv_inv : B -> A ;
+ eisretr : Sect equiv_inv f;
+ eissect : Sect f equiv_inv;
+ eisadj : forall x : A, eisretr (f x) = ap f (eissect x)
+}.
+
+Arguments eisretr {A B}%type_scope f%function_scope {_} _.
+
+Record Equiv A B := BuildEquiv {
+ equiv_fun : A -> B ;
+ equiv_isequiv : IsEquiv equiv_fun
+}.
+
+Coercion equiv_fun : Equiv >-> Funclass.
+
+Global Existing Instance equiv_isequiv.
+
+Notation "A <~> B" := (Equiv A B) (at level 85) : type_scope.
+
+Notation "f ^-1" := (@equiv_inv _ _ f _) (at level 3, format "f '^-1'") : function_scope.
+
+Class Contr_internal (A : Type) := BuildContr {
+ center : A ;
+ contr : (forall y : A, center = y)
+}.
+
+Arguments center A {_}.
+
+Inductive trunc_index : Type :=
+| minus_two : trunc_index
+| trunc_S : trunc_index -> trunc_index.
+
+Notation "n .+1" := (trunc_S n) (at level 2, left associativity, format "n .+1") : trunc_scope.
+Notation "-2" := minus_two (at level 0) : trunc_scope.
+Notation "-1" := (-2.+1) (at level 0) : trunc_scope.
+Notation "0" := (-1.+1) : trunc_scope.
+
+Fixpoint IsTrunc_internal (n : trunc_index) (A : Type) : Type :=
+ match n with
+ | -2 => Contr_internal A
+ | n'.+1 => forall (x y : A), IsTrunc_internal n' (x = y)
+ end.
+
+Class IsTrunc (n : trunc_index) (A : Type) : Type :=
+ Trunc_is_trunc : IsTrunc_internal n A.
+
+Global Instance istrunc_paths (A : Type) n `{H : IsTrunc n.+1 A} (x y : A)
+: IsTrunc n (x = y)
+ := H x y.
+
+Notation Contr := (IsTrunc -2).
+Notation IsHProp := (IsTrunc -1).
+
+Hint Extern 0 => progress change Contr_internal with Contr in * : typeclass_instances.
+
+Monomorphic Axiom dummy_funext_type : Type0.
+Monomorphic Class Funext := { dummy_funext_value : dummy_funext_type }.
+
+Inductive Unit : Type1 :=
+ tt : Unit.
+
+Class IsPointed (A : Type) := point : A.
+
+Arguments point A {_}.
+
+Record pType :=
+ { pointed_type : Type ;
+ ispointed_type : IsPointed pointed_type }.
+
+Coercion pointed_type : pType >-> Sortclass.
+
+Global Existing Instance ispointed_type.
+
+Definition hfiber {A B : Type} (f : A -> B) (y : B) := { x : A & f x = y }.
+
+Ltac revert_opaque x :=
+ revert x;
+ match goal with
+ | [ |- forall _, _ ] => idtac
+ | _ => fail 1 "Reverted constant is not an opaque variable"
+ end.
+
+End Overture.
+
+End Basics.
+
+End HoTT.
+
+End HoTT_DOT_Basics_DOT_Overture.
+Module Export HoTT_DOT_Basics_DOT_PathGroupoids.
+Module Export HoTT.
+Module Export Basics.
+Module Export PathGroupoids.
+
+Local Open Scope path_scope.
+
+Definition concat_p1 {A : Type} {x y : A} (p : x = y) :
+ p @ 1 = p
+ :=
+ match p with idpath => 1 end.
+
+Definition concat_1p {A : Type} {x y : A} (p : x = y) :
+ 1 @ p = p
+ :=
+ match p with idpath => 1 end.
+
+Definition concat_p_pp {A : Type} {x y z t : A} (p : x = y) (q : y = z) (r : z = t) :
+ p @ (q @ r) = (p @ q) @ r :=
+ match r with idpath =>
+ match q with idpath =>
+ match p with idpath => 1
+ end end end.
+
+Definition concat_pp_p {A : Type} {x y z t : A} (p : x = y) (q : y = z) (r : z = t) :
+ (p @ q) @ r = p @ (q @ r) :=
+ match r with idpath =>
+ match q with idpath =>
+ match p with idpath => 1
+ end end end.
+
+Definition concat_pV {A : Type} {x y : A} (p : x = y) :
+ p @ p^ = 1
+ :=
+ match p with idpath => 1 end.
+
+Definition moveR_Vp {A : Type} {x y z : A} (p : x = z) (q : y = z) (r : x = y) :
+ p = r @ q -> r^ @ p = q.
+admit.
+Defined.
+
+Definition moveL_Vp {A : Type} {x y z : A} (p : x = z) (q : y = z) (r : x = y) :
+ r @ q = p -> q = r^ @ p.
+admit.
+Defined.
+
+Definition moveR_M1 {A : Type} {x y : A} (p q : x = y) :
+ 1 = p^ @ q -> p = q.
+admit.
+Defined.
+
+Definition ap_pp {A B : Type} (f : A -> B) {x y z : A} (p : x = y) (q : y = z) :
+ ap f (p @ q) = (ap f p) @ (ap f q)
+ :=
+ match q with
+ idpath =>
+ match p with idpath => 1 end
+ end.
+
+Definition ap_V {A B : Type} (f : A -> B) {x y : A} (p : x = y) :
+ ap f (p^) = (ap f p)^
+ :=
+ match p with idpath => 1 end.
+
+Definition ap_compose {A B C : Type} (f : A -> B) (g : B -> C) {x y : A} (p : x = y) :
+ ap (g o f) p = ap g (ap f p)
+ :=
+ match p with idpath => 1 end.
+
+Definition concat_pA1 {A : Type} {f : A -> A} (p : forall x, x = f x) {x y : A} (q : x = y) :
+ (p x) @ (ap f q) = q @ (p y)
+ :=
+ match q as i in (_ = y) return (p x @ ap f i = i @ p y) with
+ | idpath => concat_p1 _ @ (concat_1p _)^
+ end.
+
+End PathGroupoids.
+
+End Basics.
+
+End HoTT.
+
+End HoTT_DOT_Basics_DOT_PathGroupoids.
+Module Export HoTT_DOT_Basics_DOT_Equivalences.
+Module Export HoTT.
+Module Export Basics.
+Module Export Equivalences.
+
+Definition isequiv_commsq {A B C D}
+ (f : A -> B) (g : C -> D) (h : A -> C) (k : B -> D)
+ (p : k o f == g o h)
+ `{IsEquiv _ _ f} `{IsEquiv _ _ h} `{IsEquiv _ _ k}
+: IsEquiv g.
+admit.
+Defined.
+
+Section Adjointify.
+
+ Context {A B : Type} (f : A -> B) (g : B -> A).
+ Context (isretr : Sect g f) (issect : Sect f g).
+
+ Let issect' := fun x =>
+ ap g (ap f (issect x)^) @ ap g (isretr (f x)) @ issect x.
+
+ Let is_adjoint' (a : A) : isretr (f a) = ap f (issect' a).
+ Proof.
+ unfold issect'.
+ apply moveR_M1.
+ repeat rewrite ap_pp, concat_p_pp; rewrite <- ap_compose.
+ rewrite (concat_pA1 (fun b => (isretr b)^) (ap f (issect a)^)).
+ repeat rewrite concat_pp_p; rewrite ap_V; apply moveL_Vp; rewrite concat_p1.
+ rewrite concat_p_pp, <- ap_compose.
+ rewrite (concat_pA1 (fun b => (isretr b)^) (isretr (f a))).
+ rewrite concat_pV, concat_1p; reflexivity.
+ Qed.
+
+ Definition isequiv_adjointify : IsEquiv f
+ := BuildIsEquiv A B f g isretr issect' is_adjoint'.
+
+End Adjointify.
+
+End Equivalences.
+
+End Basics.
+
+End HoTT.
+
+End HoTT_DOT_Basics_DOT_Equivalences.
+Module Export HoTT_DOT_Basics_DOT_Trunc.
+Module Export HoTT.
+Module Export Basics.
+Module Export Trunc.
+Generalizable Variables A B m n f.
+
+Definition trunc_equiv A {B} (f : A -> B)
+ `{IsTrunc n A} `{IsEquiv A B f}
+ : IsTrunc n B.
+admit.
+Defined.
+
+Record TruncType (n : trunc_index) := BuildTruncType {
+ trunctype_type : Type ;
+ istrunc_trunctype_type : IsTrunc n trunctype_type
+}.
+
+Arguments BuildTruncType _ _ {_}.
+
+Coercion trunctype_type : TruncType >-> Sortclass.
+
+Notation "n -Type" := (TruncType n) (at level 1) : type_scope.
+Notation hProp := (-1)-Type.
+
+Notation BuildhProp := (BuildTruncType -1).
+
+End Trunc.
+
+End Basics.
+
+End HoTT.
+
+End HoTT_DOT_Basics_DOT_Trunc.
+Module Export HoTT_DOT_Types_DOT_Unit.
+Module Export HoTT.
+Module Export Types.
+Module Export Unit.
+
+Notation unit_name x := (fun (_ : Unit) => x).
+
+End Unit.
+
+End Types.
+
+End HoTT.
+
+End HoTT_DOT_Types_DOT_Unit.
+Module Export HoTT_DOT_Types_DOT_Sigma.
+Module Export HoTT.
+Module Export Types.
+Module Export Sigma.
+Local Open Scope path_scope.
+
+Definition path_sigma_uncurried {A : Type} (P : A -> Type) (u v : sigT P)
+ (pq : {p : u.1 = v.1 & p # u.2 = v.2})
+: u = v
+ := match pq.2 in (_ = v2) return u = (v.1; v2) with
+ | 1 => match pq.1 as p in (_ = v1) return u = (v1; p # u.2) with
+ | 1 => 1
+ end
+ end.
+
+Definition path_sigma {A : Type} (P : A -> Type) (u v : sigT P)
+ (p : u.1 = v.1) (q : p # u.2 = v.2)
+: u = v
+ := path_sigma_uncurried P u v (p;q).
+
+Definition path_sigma' {A : Type} (P : A -> Type) {x x' : A} {y : P x} {y' : P x'}
+ (p : x = x') (q : p # y = y')
+: (x;y) = (x';y')
+ := path_sigma P (x;y) (x';y') p q.
+
+Global Instance isequiv_pr1_contr {A} {P : A -> Type}
+ `{forall a, Contr (P a)}
+: IsEquiv (@pr1 A P) | 100.
+Proof.
+ refine (isequiv_adjointify (@pr1 A P)
+ (fun a => (a ; center (P a))) _ _).
+ -
+ intros a; reflexivity.
+ -
+ intros [a p].
+ refine (path_sigma' P 1 (contr _)).
+Defined.
+
+Definition path_sigma_hprop {A : Type} {P : A -> Type}
+ `{forall x, IsHProp (P x)}
+ (u v : sigT P)
+: u.1 = v.1 -> u = v
+ := path_sigma_uncurried P u v o pr1^-1.
+
+End Sigma.
+
+End Types.
+
+End HoTT.
+
+End HoTT_DOT_Types_DOT_Sigma.
+Module Export HoTT_DOT_Extensions.
+Module Export HoTT.
+Module Export Extensions.
+
+Section Extensions.
+
+ Definition ExtensionAlong {A B : Type} (f : A -> B)
+ (P : B -> Type) (d : forall x:A, P (f x))
+ := { s : forall y:B, P y & forall x:A, s (f x) = d x }.
+
+ Fixpoint ExtendableAlong@{i j k l}
+ (n : nat) {A : Type@{i}} {B : Type@{j}}
+ (f : A -> B) (C : B -> Type@{k}) : Type@{l}
+ := match n with
+ | 0 => Unit@{l}
+ | S n => (forall (g : forall a, C (f a)),
+ ExtensionAlong@{i j k l l} f C g) *
+ forall (h k : forall b, C b),
+ ExtendableAlong n f (fun b => h b = k b)
+ end.
+
+ Definition ooExtendableAlong@{i j k l}
+ {A : Type@{i}} {B : Type@{j}}
+ (f : A -> B) (C : B -> Type@{k}) : Type@{l}
+ := forall n, ExtendableAlong@{i j k l} n f C.
+
+End Extensions.
+
+End Extensions.
+
+End HoTT.
+
+End HoTT_DOT_Extensions.
+Module Export HoTT.
+Module Export Modalities.
+Module Export ReflectiveSubuniverse.
+
+Module Type ReflectiveSubuniverses.
+
+ Parameter ReflectiveSubuniverse@{u a} : Type2@{u a}.
+
+ Parameter O_reflector@{u a i} : forall (O : ReflectiveSubuniverse@{u a}),
+ Type2le@{i a} -> Type2le@{i a}.
+
+ Parameter In@{u a i} : forall (O : ReflectiveSubuniverse@{u a}),
+ Type2le@{i a} -> Type2le@{i a}.
+
+ Parameter O_inO@{u a i} : forall (O : ReflectiveSubuniverse@{u a}) (T : Type@{i}),
+ In@{u a i} O (O_reflector@{u a i} O T).
+
+ Parameter to@{u a i} : forall (O : ReflectiveSubuniverse@{u a}) (T : Type@{i}),
+ T -> O_reflector@{u a i} O T.
+
+ Parameter inO_equiv_inO@{u a i j k} :
+ forall (O : ReflectiveSubuniverse@{u a}) (T : Type@{i}) (U : Type@{j})
+ (T_inO : In@{u a i} O T) (f : T -> U) (feq : IsEquiv f),
+
+ let gei := ((fun x => x) : Type@{i} -> Type@{k}) in
+ let gej := ((fun x => x) : Type@{j} -> Type@{k}) in
+ In@{u a j} O U.
+
+ Parameter hprop_inO@{u a i}
+ : Funext -> forall (O : ReflectiveSubuniverse@{u a}) (T : Type@{i}),
+ IsHProp (In@{u a i} O T).
+
+ Parameter extendable_to_O@{u a i j k}
+ : forall (O : ReflectiveSubuniverse@{u a}) {P : Type2le@{i a}} {Q : Type2le@{j a}} {Q_inO : In@{u a j} O Q},
+ ooExtendableAlong@{i i j k} (to O P) (fun _ => Q).
+
+End ReflectiveSubuniverses.
+
+Module ReflectiveSubuniverses_Theory (Os : ReflectiveSubuniverses).
+Export Os.
+
+Module Export Coercions.
+
+ Coercion O_reflector : ReflectiveSubuniverse >-> Funclass.
+
+End Coercions.
+
+End ReflectiveSubuniverses_Theory.
+
+Module Type ReflectiveSubuniverses_Restriction_Data (Os : ReflectiveSubuniverses).
+
+ Parameter New_ReflectiveSubuniverse@{u a} : Type2@{u a}.
+
+ Parameter ReflectiveSubuniverses_restriction@{u a}
+ : New_ReflectiveSubuniverse@{u a} -> Os.ReflectiveSubuniverse@{u a}.
+
+End ReflectiveSubuniverses_Restriction_Data.
+
+Module ReflectiveSubuniverses_Restriction
+ (Os : ReflectiveSubuniverses)
+ (Res : ReflectiveSubuniverses_Restriction_Data Os)
+<: ReflectiveSubuniverses.
+
+ Definition ReflectiveSubuniverse := Res.New_ReflectiveSubuniverse.
+
+ Definition O_reflector@{u a i} (O : ReflectiveSubuniverse@{u a})
+ := Os.O_reflector@{u a i} (Res.ReflectiveSubuniverses_restriction O).
+ Definition In@{u a i} (O : ReflectiveSubuniverse@{u a})
+ := Os.In@{u a i} (Res.ReflectiveSubuniverses_restriction O).
+ Definition O_inO@{u a i} (O : ReflectiveSubuniverse@{u a})
+ := Os.O_inO@{u a i} (Res.ReflectiveSubuniverses_restriction O).
+ Definition to@{u a i} (O : ReflectiveSubuniverse@{u a})
+ := Os.to@{u a i} (Res.ReflectiveSubuniverses_restriction O).
+ Definition inO_equiv_inO@{u a i j k} (O : ReflectiveSubuniverse@{u a})
+ := Os.inO_equiv_inO@{u a i j k} (Res.ReflectiveSubuniverses_restriction O).
+ Definition hprop_inO@{u a i} (H : Funext) (O : ReflectiveSubuniverse@{u a})
+ := Os.hprop_inO@{u a i} H (Res.ReflectiveSubuniverses_restriction O).
+ Definition extendable_to_O@{u a i j k} (O : ReflectiveSubuniverse@{u a})
+ := @Os.extendable_to_O@{u a i j k} (Res.ReflectiveSubuniverses_restriction@{u a} O).
+
+End ReflectiveSubuniverses_Restriction.
+
+Module ReflectiveSubuniverses_FamUnion
+ (Os1 Os2 : ReflectiveSubuniverses)
+<: ReflectiveSubuniverses.
+
+ Definition ReflectiveSubuniverse@{u a} : Type2@{u a}
+ := Os1.ReflectiveSubuniverse@{u a} + Os2.ReflectiveSubuniverse@{u a}.
+
+ Definition O_reflector@{u a i} : forall (O : ReflectiveSubuniverse@{u a}),
+ Type2le@{i a} -> Type2le@{i a}.
+admit.
+Defined.
+
+ Definition In@{u a i} : forall (O : ReflectiveSubuniverse@{u a}),
+ Type2le@{i a} -> Type2le@{i a}.
+ Proof.
+ intros [O|O]; [ exact (Os1.In@{u a i} O)
+ | exact (Os2.In@{u a i} O) ].
+ Defined.
+
+ Definition O_inO@{u a i}
+ : forall (O : ReflectiveSubuniverse@{u a}) (T : Type@{i}),
+ In@{u a i} O (O_reflector@{u a i} O T).
+admit.
+Defined.
+
+ Definition to@{u a i} : forall (O : ReflectiveSubuniverse@{u a}) (T : Type@{i}),
+ T -> O_reflector@{u a i} O T.
+admit.
+Defined.
+
+ Definition inO_equiv_inO@{u a i j k} :
+ forall (O : ReflectiveSubuniverse@{u a}) (T : Type@{i}) (U : Type@{j})
+ (T_inO : In@{u a i} O T) (f : T -> U) (feq : IsEquiv f),
+ In@{u a j} O U.
+ Proof.
+ intros [O|O]; [ exact (Os1.inO_equiv_inO@{u a i j k} O)
+ | exact (Os2.inO_equiv_inO@{u a i j k} O) ].
+ Defined.
+
+ Definition hprop_inO@{u a i}
+ : Funext -> forall (O : ReflectiveSubuniverse@{u a}) (T : Type@{i}),
+ IsHProp (In@{u a i} O T).
+admit.
+Defined.
+
+ Definition extendable_to_O@{u a i j k}
+ : forall (O : ReflectiveSubuniverse@{u a}) {P : Type2le@{i a}} {Q : Type2le@{j a}} {Q_inO : In@{u a j} O Q},
+ ooExtendableAlong@{i i j k} (to O P) (fun _ => Q).
+admit.
+Defined.
+
+End ReflectiveSubuniverses_FamUnion.
+
+End ReflectiveSubuniverse.
+
+End Modalities.
+
+End HoTT.
+
+Module Type Modalities.
+
+ Parameter Modality@{u a} : Type2@{u a}.
+
+ Parameter O_reflector@{u a i} : forall (O : Modality@{u a}),
+ Type2le@{i a} -> Type2le@{i a}.
+
+ Parameter In@{u a i} : forall (O : Modality@{u a}),
+ Type2le@{i a} -> Type2le@{i a}.
+
+ Parameter O_inO@{u a i} : forall (O : Modality@{u a}) (T : Type@{i}),
+ In@{u a i} O (O_reflector@{u a i} O T).
+
+ Parameter to@{u a i} : forall (O : Modality@{u a}) (T : Type@{i}),
+ T -> O_reflector@{u a i} O T.
+
+ Parameter inO_equiv_inO@{u a i j k} :
+ forall (O : Modality@{u a}) (T : Type@{i}) (U : Type@{j})
+ (T_inO : In@{u a i} O T) (f : T -> U) (feq : IsEquiv f),
+
+ let gei := ((fun x => x) : Type@{i} -> Type@{k}) in
+ let gej := ((fun x => x) : Type@{j} -> Type@{k}) in
+ In@{u a j} O U.
+
+ Parameter hprop_inO@{u a i}
+ : Funext -> forall (O : Modality@{u a}) (T : Type@{i}),
+ IsHProp (In@{u a i} O T).
+
+End Modalities.
+
+Module Modalities_to_ReflectiveSubuniverses
+ (Os : Modalities) <: ReflectiveSubuniverses.
+
+ Import Os.
+
+ Fixpoint O_extendable@{u a i j k} (O : Modality@{u a})
+ (A : Type@{i}) (B : O_reflector O A -> Type@{j})
+ (B_inO : forall a, In@{u a j} O (B a)) (n : nat)
+ : ExtendableAlong@{i i j k} n (to O A) B.
+admit.
+Defined.
+
+ Definition ReflectiveSubuniverse := Modality.
+
+ Definition O_reflector := O_reflector.
+
+ Definition In@{u a i} : forall (O : ReflectiveSubuniverse@{u a}),
+ Type2le@{i a} -> Type2le@{i a}
+ := In@{u a i}.
+ Definition O_inO@{u a i} : forall (O : ReflectiveSubuniverse@{u a}) (T : Type@{i}),
+ In@{u a i} O (O_reflector@{u a i} O T)
+ := O_inO@{u a i}.
+ Definition to := to.
+ Definition inO_equiv_inO@{u a i j k} :
+ forall (O : ReflectiveSubuniverse@{u a}) (T : Type@{i}) (U : Type@{j})
+ (T_inO : In@{u a i} O T) (f : T -> U) (feq : IsEquiv f),
+ In@{u a j} O U
+ := inO_equiv_inO@{u a i j k}.
+ Definition hprop_inO@{u a i}
+ : Funext -> forall (O : ReflectiveSubuniverse@{u a}) (T : Type@{i}),
+ IsHProp (In@{u a i} O T)
+ := hprop_inO@{u a i}.
+
+ Definition extendable_to_O@{u a i j k} (O : ReflectiveSubuniverse@{u a})
+ {P : Type2le@{i a}} {Q : Type2le@{j a}} {Q_inO : In@{u a j} O Q}
+ : ooExtendableAlong@{i i j k} (to O P) (fun _ => Q)
+ := fun n => O_extendable O P (fun _ => Q) (fun _ => Q_inO) n.
+
+End Modalities_to_ReflectiveSubuniverses.
+
+Module Type EasyModalities.
+
+ Parameter Modality@{u a} : Type2@{u a}.
+
+ Parameter O_reflector@{u a i} : forall (O : Modality@{u a}),
+ Type2le@{i a} -> Type2le@{i a}.
+
+ Parameter to@{u a i} : forall (O : Modality@{u a}) (T : Type@{i}),
+ T -> O_reflector@{u a i} O T.
+
+ Parameter minO_pathsO@{u a i}
+ : forall (O : Modality@{u a}) (A : Type@{i})
+ (z z' : O_reflector@{u a i} O A),
+ IsEquiv (to@{u a i} O (z = z')).
+
+End EasyModalities.
+
+Module EasyModalities_to_Modalities (Os : EasyModalities)
+<: Modalities.
+
+ Import Os.
+
+ Definition Modality := Modality.
+
+ Definition O_reflector@{u a i} := O_reflector@{u a i}.
+ Definition to@{u a i} := to@{u a i}.
+
+ Definition In@{u a i}
+ : forall (O : Modality@{u a}), Type@{i} -> Type@{i}
+ := fun O A => IsEquiv@{i i} (to O A).
+
+ Definition hprop_inO@{u a i} `{Funext} (O : Modality@{u a})
+ (T : Type@{i})
+ : IsHProp (In@{u a i} O T).
+admit.
+Defined.
+
+ Definition O_ind_internal@{u a i j k} (O : Modality@{u a})
+ (A : Type@{i}) (B : O_reflector@{u a i} O A -> Type@{j})
+ (B_inO : forall oa, In@{u a j} O (B oa))
+ : let gei := ((fun x => x) : Type@{i} -> Type@{k}) in
+ let gej := ((fun x => x) : Type@{j} -> Type@{k}) in
+ (forall a, B (to O A a)) -> forall oa, B oa.
+admit.
+Defined.
+
+ Definition O_ind_beta_internal@{u a i j k} (O : Modality@{u a})
+ (A : Type@{i}) (B : O_reflector@{u a i} O A -> Type@{j})
+ (B_inO : forall oa, In@{u a j} O (B oa))
+ (f : forall a : A, B (to O A a)) (a:A)
+ : O_ind_internal@{u a i j k} O A B B_inO f (to O A a) = f a.
+admit.
+Defined.
+
+ Definition O_inO@{u a i} (O : Modality@{u a}) (A : Type@{i})
+ : In@{u a i} O (O_reflector@{u a i} O A).
+admit.
+Defined.
+
+ Definition inO_equiv_inO@{u a i j k} (O : Modality@{u a}) (A : Type@{i}) (B : Type@{j})
+ (A_inO : In@{u a i} O A) (f : A -> B) (feq : IsEquiv f)
+ : In@{u a j} O B.
+ Proof.
+ simple refine (isequiv_commsq (to O A) (to O B) f
+ (O_ind_internal O A (fun _ => O_reflector O B) _ (fun a => to O B (f a))) _).
+ -
+ intros; apply O_inO.
+ -
+ intros a; refine (O_ind_beta_internal@{u a i j k} O A (fun _ => O_reflector O B) _ _ a).
+ -
+ apply A_inO.
+ -
+ simple refine (isequiv_adjointify _
+ (O_ind_internal O B (fun _ => O_reflector O A) _ (fun b => to O A (f^-1 b))) _ _);
+ intros x.
+ +
+ apply O_inO.
+ +
+ pattern x; refine (O_ind_internal O B _ _ _ x); intros.
+ *
+ apply minO_pathsO.
+ *
+ simpl; admit.
+ +
+ pattern x; refine (O_ind_internal O A _ _ _ x); intros.
+ *
+ apply minO_pathsO.
+ *
+ simpl; admit.
+ Defined.
+
+End EasyModalities_to_Modalities.
+
+Module Modalities_Theory (Os : Modalities).
+
+Export Os.
+Module Export Os_ReflectiveSubuniverses
+ := Modalities_to_ReflectiveSubuniverses Os.
+Module Export RSU
+ := ReflectiveSubuniverses_Theory Os_ReflectiveSubuniverses.
+
+Module Export Coercions.
+ Coercion modality_to_reflective_subuniverse
+ := idmap : Modality -> ReflectiveSubuniverse.
+End Coercions.
+
+Class IsConnected (O : Modality@{u a}) (A : Type@{i})
+
+ := isconnected_contr_O : IsTrunc@{i} -2 (O A).
+
+Class IsConnMap (O : Modality@{u a})
+ {A : Type@{i}} {B : Type@{j}} (f : A -> B)
+ := isconnected_hfiber_conn_map
+
+ : forall b:B, IsConnected@{u a k} O (hfiber@{i j} f b).
+
+End Modalities_Theory.
+
+Private Inductive Trunc (n : trunc_index) (A :Type) : Type :=
+ tr : A -> Trunc n A.
+Arguments tr {n A} a.
+
+Global Instance istrunc_truncation (n : trunc_index) (A : Type@{i})
+: IsTrunc@{j} n (Trunc@{i} n A).
+Admitted.
+
+Definition Trunc_ind {n A}
+ (P : Trunc n A -> Type) {Pt : forall aa, IsTrunc n (P aa)}
+ : (forall a, P (tr a)) -> (forall aa, P aa)
+:= (fun f aa => match aa with tr a => fun _ => f a end Pt).
+
+Definition Truncation_Modality := trunc_index.
+
+Module Truncation_Modalities <: Modalities.
+
+ Definition Modality : Type2@{u a} := Truncation_Modality.
+
+ Definition O_reflector (n : Modality@{u u'}) A := Trunc n A.
+
+ Definition In (n : Modality@{u u'}) A := IsTrunc n A.
+
+ Definition O_inO (n : Modality@{u u'}) A : In n (O_reflector n A).
+admit.
+Defined.
+
+ Definition to (n : Modality@{u u'}) A := @tr n A.
+
+ Definition inO_equiv_inO (n : Modality@{u u'})
+ (A : Type@{i}) (B : Type@{j}) Atr f feq
+ : let gei := ((fun x => x) : Type@{i} -> Type@{k}) in
+ let gej := ((fun x => x) : Type@{j} -> Type@{k}) in
+ In n B
+ := @trunc_equiv A B f n Atr feq.
+
+ Definition hprop_inO `{Funext} (n : Modality@{u u'}) A
+ : IsHProp (In n A).
+admit.
+Defined.
+
+End Truncation_Modalities.
+
+Module Import TrM := Modalities_Theory Truncation_Modalities.
+
+Definition merely (A : Type@{i}) : hProp := BuildhProp (Trunc -1 A).
+
+Notation IsSurjection := (IsConnMap -1).
+
+Definition BuildIsSurjection {A B} (f : A -> B) :
+ (forall b, merely (hfiber f b)) -> IsSurjection f.
+admit.
+Defined.
+
+Ltac strip_truncations :=
+
+ progress repeat match goal with
+ | [ T : _ |- _ ]
+ => revert_opaque T;
+ refine (@Trunc_ind _ _ _ _ _);
+
+ [];
+ intro T
+ end.
+Local Open Scope trunc_scope.
+
+Global Instance conn_pointed_type {n : trunc_index} {A : Type} (a0:A)
+ `{IsConnMap n _ _ (unit_name a0)} : IsConnected n.+1 A | 1000.
+admit.
+Defined.
+
+Definition loops (A : pType) : pType :=
+ Build_pType (point A = point A) idpath.
+
+Record pMap (A B : pType) :=
+ { pointed_fun : A -> B ;
+ point_eq : pointed_fun (point A) = point B }.
+
+Arguments point_eq {A B} f : rename.
+Coercion pointed_fun : pMap >-> Funclass.
+
+Infix "->*" := pMap (at level 99) : pointed_scope.
+Local Open Scope pointed_scope.
+
+Definition pmap_compose {A B C : pType}
+ (g : B ->* C) (f : A ->* B)
+: A ->* C
+ := Build_pMap A C (g o f)
+ (ap g (point_eq f) @ point_eq g).
+
+Record pHomotopy {A B : pType} (f g : pMap A B) :=
+ { pointed_htpy : f == g ;
+ point_htpy : pointed_htpy (point A) @ point_eq g = point_eq f }.
+Arguments pointed_htpy {A B f g} p x.
+
+Infix "==*" := pHomotopy (at level 70, no associativity) : pointed_scope.
+
+Definition loops_functor {A B : pType} (f : A ->* B)
+: (loops A) ->* (loops B).
+Proof.
+ refine (Build_pMap (loops A) (loops B)
+ (fun p => (point_eq f)^ @ (ap f p @ point_eq f)) _).
+ apply moveR_Vp; simpl.
+ refine (concat_1p _ @ (concat_p1 _)^).
+Defined.
+
+Definition loops_functor_compose {A B C : pType}
+ (g : B ->* C) (f : A ->* B)
+: (loops_functor (pmap_compose g f))
+ ==* (pmap_compose (loops_functor g) (loops_functor f)).
+admit.
+Defined.
+
+Local Open Scope path_scope.
+
+Record ooGroup :=
+ { classifying_space : pType@{i} ;
+ isconn_classifying_space : IsConnected@{u a i} 0 classifying_space
+ }.
+
+Local Notation B := classifying_space.
+
+Definition group_type (G : ooGroup) : Type
+ := point (B G) = point (B G).
+
+Coercion group_type : ooGroup >-> Sortclass.
+
+Definition group_loops (X : pType)
+: ooGroup.
+Proof.
+
+ pose (x0 := point X);
+ pose (BG := (Build_pType
+ { x:X & merely (x = point X) }
+ (existT (fun x:X => merely (x = point X)) x0 (tr 1)))).
+
+ cut (IsConnected 0 BG).
+ {
+ exact (Build_ooGroup BG).
+}
+ cut (IsSurjection (unit_name (point BG))).
+ {
+ intros; refine (conn_pointed_type (point _)).
+}
+ apply BuildIsSurjection; simpl; intros [x p].
+ strip_truncations; apply tr; exists tt.
+ apply path_sigma_hprop; simpl.
+ exact (p^).
+Defined.
+
+Definition loops_group (X : pType)
+: loops X <~> group_loops X.
+admit.
+Defined.
+
+Definition ooGroupHom (G H : ooGroup)
+ := pMap (B G) (B H).
+
+Definition grouphom_fun {G H} (phi : ooGroupHom G H) : G -> H
+ := loops_functor phi.
+
+Coercion grouphom_fun : ooGroupHom >-> Funclass.
+
+Definition group_loops_functor
+ {X Y : pType} (f : pMap X Y)
+: ooGroupHom (group_loops X) (group_loops Y).
+Proof.
+ simple refine (Build_pMap _ _ _ _); simpl.
+ -
+ intros [x p].
+ exists (f x).
+ strip_truncations; apply tr.
+ exact (ap f p @ point_eq f).
+ -
+ apply path_sigma_hprop; simpl.
+ apply point_eq.
+Defined.
+
+Definition loops_functor_group
+ {X Y : pType} (f : pMap X Y)
+: loops_functor (group_loops_functor f) o loops_group X
+ == loops_group Y o loops_functor f.
+admit.
+Defined.
+
+Definition grouphom_compose {G H K : ooGroup}
+ (psi : ooGroupHom H K) (phi : ooGroupHom G H)
+: ooGroupHom G K
+ := pmap_compose psi phi.
+
+Definition group_loops_functor_compose
+ {X Y Z : pType}
+ (psi : pMap Y Z) (phi : pMap X Y)
+: grouphom_compose (group_loops_functor psi) (group_loops_functor phi)
+ == group_loops_functor (pmap_compose psi phi).
+Proof.
+ intros g.
+ unfold grouphom_fun, grouphom_compose.
+ refine (pointed_htpy (loops_functor_compose _ _) g @ _).
+ pose (p := eisretr (loops_group X) g).
+ change (loops_functor (group_loops_functor psi)
+ (loops_functor (group_loops_functor phi) g)
+ = loops_functor (group_loops_functor
+ (pmap_compose psi phi)) g).
+ rewrite <- p.
+ Fail Timeout 1 Time rewrite !loops_functor_group.
+ (* 0.004 s in 8.5rc1, 8.677 s in 8.5 *)
+ Timeout 1 do 3 rewrite loops_functor_group.
+Abort. \ No newline at end of file
diff --git a/test-suite/bugs/closed/4576.v b/test-suite/bugs/closed/4576.v
new file mode 100644
index 000000000..2c643ea77
--- /dev/null
+++ b/test-suite/bugs/closed/4576.v
@@ -0,0 +1,3 @@
+Definition foo := O.
+Arguments foo : simpl nomatch.
+Timeout 1 Eval cbn in id foo.
diff --git a/test-suite/bugs/closed/4588.v b/test-suite/bugs/closed/4588.v
new file mode 100644
index 000000000..ff66277e0
--- /dev/null
+++ b/test-suite/bugs/closed/4588.v
@@ -0,0 +1,10 @@
+Set Primitive Projections.
+
+(* This proof was accepted in Coq 8.5 because the subterm specs were not
+projected correctly *)
+Inductive foo : Prop := mkfoo { proj1 : False -> foo; proj2 : (forall P : Prop, P -> P) }.
+
+Fail Fixpoint loop (x : foo) : False :=
+ loop (proj2 x _ x).
+
+Fail Definition bad : False := loop (mkfoo (fun x => match x with end) (fun _ x => x)).
diff --git a/test-suite/bugs/closed/4596.v b/test-suite/bugs/closed/4596.v
new file mode 100644
index 000000000..592fdb658
--- /dev/null
+++ b/test-suite/bugs/closed/4596.v
@@ -0,0 +1,14 @@
+Require Import Coq.Setoids.Setoid Coq.Classes.Morphisms.
+
+Definition T (x : bool) := x = true.
+
+Goal forall (S : Type) (b b0 : S -> nat -> bool) (str : S) (p : nat)
+ (s : forall n : nat, bool)
+ (s0 s1 : nat -> S -> S),
+ (forall (str0 : S) (n m : nat),
+ (if s m then T (b0 (s1 n str0) 0) else T (b (s1 n str0) 0)) -> T (b (s0 n str0) m) ->
+ T (b str0 m)) ->
+ T (b str p).
+Proof.
+intros ???????? H0.
+rewrite H0.
diff --git a/test-suite/bugs/closed/4603.v b/test-suite/bugs/closed/4603.v
new file mode 100644
index 000000000..e7567623a
--- /dev/null
+++ b/test-suite/bugs/closed/4603.v
@@ -0,0 +1,10 @@
+Axiom A : Type.
+
+Goal True. exact I.
+Check (fun P => P A).
+Abort.
+
+Goal True.
+Definition foo (A : Type) : Prop:= True.
+ set (x:=foo). split.
+Qed. \ No newline at end of file
diff --git a/test-suite/bugs/closed/4616.v b/test-suite/bugs/closed/4616.v
new file mode 100644
index 000000000..c862f8206
--- /dev/null
+++ b/test-suite/bugs/closed/4616.v
@@ -0,0 +1,4 @@
+Set Primitive Projections.
+Record Foo' := Foo { foo : Type }.
+Axiom f : forall t : Foo', foo t.
+Extraction f.
diff --git a/test-suite/bugs/closed/4627.v b/test-suite/bugs/closed/4627.v
new file mode 100644
index 000000000..e1206bb37
--- /dev/null
+++ b/test-suite/bugs/closed/4627.v
@@ -0,0 +1,49 @@
+Class sa (A:Type) := { }.
+
+Record predicate A (sa:sa A) :=
+ { pred_fun: A->Prop }.
+Record ABC : Type :=
+ { abc: Type }.
+Record T :=
+ { T_abc: ABC }.
+
+
+(*
+sa: forall _ : Type@{Top.179}, Prop
+predicate: forall (A : Type@{Top.205}) (_ : sa A), Type@{max(Set+1, Top.205)}
+T: Type@{Top.208+1}
+ABC: Type@{Top.208+1}
+abc: forall _ : ABC, Type@{Top.208}
+
+Top.205 <= Top.179 predicate <= sa.A
+Set < Top.208 Set < abc
+Set < Top.205 Set < predicate
+*)
+
+Definition foo : predicate T (Build_sa T) :=
+ {| pred_fun:= fun w => True |}.
+(* *)
+(* Top.208 < Top.205 <--- added by foo *)
+(* *)
+
+Check predicate nat (Build_sa nat).
+(*
+
+The issue is that the template polymorphic universe of [predicate], Top.205, does not get replaced with the universe of [nat] in the above line.
+ -Jason Gross
+
+8.5 -- predicate nat (Build_sa nat): Type@{max(Set+1, Top.205)}
+8.5 EXPECTED -- predicate nat (Build_sa nat): Type@{Set+1}
+8.4pl4 -- predicate nat {| |}: Type (* max(Set, (Set)+1) *)
+*)
+
+(* This works in 8.4pl4 and SHOULD work in 8.5 *)
+Definition bar : ABC :=
+ {| abc:= predicate nat (Build_sa nat) |}.
+(*
+The term "predicate nat (Build_sa nat)" has type
+ "Type@{max(Set+1, Top.205)}"
+while it is expected to have type "Type@{Top.208}"
+(universe inconsistency: Cannot enforce Top.205 <=
+Top.208 because Top.208 < Top.205).
+*) \ No newline at end of file
diff --git a/test-suite/bugs/closed/4628.v b/test-suite/bugs/closed/4628.v
new file mode 100644
index 000000000..7d4a15d68
--- /dev/null
+++ b/test-suite/bugs/closed/4628.v
@@ -0,0 +1,46 @@
+Module first.
+ Polymorphic Record BAR (A:Type) :=
+ { foo: A->Prop; bar: forall (x y: A), foo x -> foo y}.
+
+Section A.
+Context {A:Type}.
+
+Set Printing Universes.
+
+Hint Resolve bar.
+Goal forall (P:BAR A) x y, foo _ P x -> foo _ P y.
+intros.
+eauto.
+Qed.
+End A.
+End first.
+
+Module firstbest.
+ Polymorphic Record BAR (A:Type) :=
+ { foo: A->Prop; bar: forall (x y: A), foo x -> foo y}.
+
+Section A.
+Context {A:Type}.
+
+Set Printing Universes.
+
+Polymorphic Hint Resolve bar.
+Goal forall (P:BAR A) x y, foo _ P x -> foo _ P y.
+intros.
+eauto.
+Qed.
+End A.
+End firstbest.
+
+Module second.
+Axiom foo: Set.
+Axiom foo': Set.
+
+Polymorphic Record BAR (A:Type) :=
+ { bar: foo' -> foo}.
+Set Printing Universes.
+
+Lemma baz@{i}: forall (P:BAR@{Set} nat), foo' -> foo.
+ eauto using bar.
+Qed.
+End second.
diff --git a/test-suite/bugs/closed/4634.v b/test-suite/bugs/closed/4634.v
new file mode 100644
index 000000000..77e31e108
--- /dev/null
+++ b/test-suite/bugs/closed/4634.v
@@ -0,0 +1,16 @@
+Set Primitive Projections.
+
+Polymorphic Record pair {A B : Type} : Type :=
+ prod { pr1 : A; pr2 : B }.
+
+Notation " ( x ; y ) " := (@prod _ _ x y).
+Notation " x .1 " := (pr1 x) (at level 3).
+Notation " x .2 " := (pr2 x) (at level 3).
+
+Goal ((0; 1); 2).1.2 = 1.
+Proof.
+ cbv.
+ match goal with
+ | |- ?t = ?t => exact (eq_refl t)
+ end.
+Qed.
diff --git a/test-suite/bugs/closed/4644.v b/test-suite/bugs/closed/4644.v
new file mode 100644
index 000000000..f09b27c2b
--- /dev/null
+++ b/test-suite/bugs/closed/4644.v
@@ -0,0 +1,52 @@
+(* Testing a regression of unification in 8.5 in problems of the form
+ "match ?y with ... end = ?x args" *)
+
+Lemma foo : exists b, forall a, match a with tt => tt end = b a.
+Proof.
+eexists. intro.
+refine (_ : _ = match _ with tt => _ end).
+refine eq_refl.
+Qed.
+
+(**********************************************************************)
+
+Axiom proof_admitted : False.
+Tactic Notation "admit" := case proof_admitted.
+Require Export Coq.Classes.Morphisms.
+Require Import Coq.Lists.List.
+
+Global Set Implicit Arguments.
+
+Definition list_caset A (P : list A -> Type) (N : P nil) (C : forall x xs, P (x::xs))
+ ls
+ : P ls
+ := match ls with
+ | nil => N
+ | x::xs => C x xs
+ end.
+
+Axiom list_caset_Proper'
+ : forall {A P},
+ Proper (eq
+ ==> pointwise_relation _ (pointwise_relation _ eq)
+ ==> eq
+ ==> eq)
+ (@list_caset A (fun _ => P)).
+Goal forall (T T' : Set) (a3 : list T), exists y2, forall (a4 : T' -> bool),
+ match a3 with
+ | nil => 0
+ | (_ :: _)%list => 1
+ end = y2 a4.
+ clear; eexists; intros.
+ reflexivity. Undo.
+ Local Ltac t :=
+ lazymatch goal with
+ | [ |- match ?v with nil => ?N | cons x xs => @?C x xs end = _ :> ?P ]
+ => let T := type of v in
+ let A := match (eval hnf in T) with list ?A => A end in
+ refine (@list_caset_Proper' A P _ _ _ _ _ _ _ _ _
+ : @list_caset A (fun _ => P) N C v = match _ with nil => _ | cons x xs => _ end)
+ end.
+ (etransitivity; [ t | reflexivity ]) || fail 0 "too early".
+ Undo.
+ t.
diff --git a/test-suite/bugs/closed/4656.v b/test-suite/bugs/closed/4656.v
new file mode 100644
index 000000000..c89a86d63
--- /dev/null
+++ b/test-suite/bugs/closed/4656.v
@@ -0,0 +1,4 @@
+(* -*- coq-prog-args: ("-emacs" "-compat" "8.4") -*- *)
+Goal True.
+ constructor 1.
+Qed.
diff --git a/test-suite/bugs/closed/4663.v b/test-suite/bugs/closed/4663.v
new file mode 100644
index 000000000..b76619882
--- /dev/null
+++ b/test-suite/bugs/closed/4663.v
@@ -0,0 +1,3 @@
+Coercion foo (n : nat) : Set.
+Admitted.
+Check (0 : Set).
diff --git a/test-suite/bugs/closed/4670.v b/test-suite/bugs/closed/4670.v
new file mode 100644
index 000000000..611399295
--- /dev/null
+++ b/test-suite/bugs/closed/4670.v
@@ -0,0 +1,7 @@
+Require Import Coq.Vectors.Vector.
+Module Bar.
+ Definition foo A n (l : Vector.t A n) : True.
+ Proof.
+ induction l ; exact I.
+ Defined.
+End Bar.
diff --git a/test-suite/bugs/closed/4695.v b/test-suite/bugs/closed/4695.v
new file mode 100644
index 000000000..a42271811
--- /dev/null
+++ b/test-suite/bugs/closed/4695.v
@@ -0,0 +1,38 @@
+(*
+The Qed at the end of this file was slow in 8.5 and 8.5pl1 because the kernel
+term comparison after evaluation was done on constants according to their user
+names. The conversion still succeeded because delta applied, but was much
+slower than with a canonical names comparison.
+*)
+
+Module Mod0.
+
+ Fixpoint rec_ t d : nat :=
+ match d with
+ | O => O
+ | S d' =>
+ match t with
+ | true => rec_ t d'
+ | false => rec_ t d'
+ end
+ end.
+
+ Definition depth := 1000.
+
+ Definition rec t := rec_ t depth.
+
+End Mod0.
+
+
+Module Mod1.
+ Module M := Mod0.
+End Mod1.
+
+
+Axiom rec_prop : forall t d n, Mod1.M.rec_ t d = n.
+
+Lemma slow_qed : forall t n,
+ Mod0.rec t = n.
+Proof.
+ intros; unfold Mod0.rec; apply rec_prop.
+Timeout 2 Qed.
diff --git a/test-suite/bugs/closed/4710.v b/test-suite/bugs/closed/4710.v
new file mode 100644
index 000000000..fdc850109
--- /dev/null
+++ b/test-suite/bugs/closed/4710.v
@@ -0,0 +1,12 @@
+Set Primitive Projections.
+Record Foo' := Foo { foo : nat }.
+Extraction foo.
+Record Foo2 (a : nat) := Foo2c { foo2p : nat; foo2b : bool }.
+Extraction Language Ocaml.
+Extraction foo2p.
+
+Definition bla (x : Foo2 0) := foo2p _ x.
+Extraction bla.
+
+Definition bla' (a : nat) (x : Foo2 a) := foo2b _ x.
+Extraction bla'.
diff --git a/test-suite/bugs/closed/4713.v b/test-suite/bugs/closed/4713.v
new file mode 100644
index 000000000..5d4d73be3
--- /dev/null
+++ b/test-suite/bugs/closed/4713.v
@@ -0,0 +1,10 @@
+Module Type T.
+ Parameter t : Type.
+End T.
+Module M : T.
+ Definition t := unit.
+End M.
+
+Fail Module Z : T with Module t := M := M.
+Fail Module Z <: T with Module t := M := M.
+Fail Declare Module Z : T with Module t := M.
diff --git a/test-suite/bugs/closed/4737.v b/test-suite/bugs/closed/4737.v
new file mode 100644
index 000000000..84ed45e45
--- /dev/null
+++ b/test-suite/bugs/closed/4737.v
@@ -0,0 +1,9 @@
+Goal True.
+Proof.
+exact I; cycle 1.
+Qed.
+
+Goal True.
+Proof.
+exact I; swap 1 2.
+Qed.
diff --git a/test-suite/bugs/closed/4746.v b/test-suite/bugs/closed/4746.v
new file mode 100644
index 000000000..d64cc6fe6
--- /dev/null
+++ b/test-suite/bugs/closed/4746.v
@@ -0,0 +1,14 @@
+Variables P Q : nat -> Prop.
+Variable f : nat -> nat.
+
+Goal forall (x:nat), (forall y, P y -> forall z, Q z -> y=f z -> False) -> False.
+Proof.
+intros.
+ecase H with (3:=eq_refl).
+Abort.
+
+Goal forall (x:nat), (forall y, y=x -> False) -> False.
+Proof.
+intros.
+unshelve ecase H with (1:=eq_refl).
+Qed.
diff --git a/test-suite/bugs/closed/4782.v b/test-suite/bugs/closed/4782.v
new file mode 100644
index 000000000..ed4443786
--- /dev/null
+++ b/test-suite/bugs/closed/4782.v
@@ -0,0 +1,9 @@
+(* About typing of with bindings *)
+
+Record r : Type := mk_r { type : Type; cond : type -> Prop }.
+
+Inductive p : Prop := consp : forall (e : r) (x : type e), cond e x -> p.
+
+Goal p.
+Fail apply consp with (fun _ : bool => mk_r unit (fun x => True)) nil.
+
diff --git a/test-suite/bugs/closed/4787.v b/test-suite/bugs/closed/4787.v
new file mode 100644
index 000000000..b586cba50
--- /dev/null
+++ b/test-suite/bugs/closed/4787.v
@@ -0,0 +1,9 @@
+(* [Unset Bracketing Last Introduction Pattern] was not working *)
+
+Unset Bracketing Last Introduction Pattern.
+
+Goal forall T (x y : T * T), fst x = fst y /\ snd x = snd y -> x = y.
+do 10 ((intros [] || intro); simpl); reflexivity.
+Qed.
+
+
diff --git a/test-suite/bugs/closed/4813.v b/test-suite/bugs/closed/4813.v
new file mode 100644
index 000000000..5f8ea74c1
--- /dev/null
+++ b/test-suite/bugs/closed/4813.v
@@ -0,0 +1,9 @@
+(* On the strength of "apply with" (see also #4782) *)
+
+Record ProverT := { Facts : Type }.
+Record ProverT_correct (P : ProverT) := { Valid : Facts P -> Prop ;
+ Valid_weaken : Valid = Valid }.
+Definition reflexivityValid (_ : unit) := True.
+Definition reflexivityProver_correct : ProverT_correct {| Facts := unit |}.
+Proof.
+ eapply Build_ProverT_correct with (Valid := reflexivityValid).
diff --git a/test-suite/bugs/closed/4816.v b/test-suite/bugs/closed/4816.v
new file mode 100644
index 000000000..86597c88f
--- /dev/null
+++ b/test-suite/bugs/closed/4816.v
@@ -0,0 +1,17 @@
+Section foo.
+Polymorphic Universes A B.
+Fail Constraint A <= B.
+End foo.
+(* gives an anomaly Universe undefined *)
+
+Universes X Y.
+Section Foo.
+ Polymorphic Universes Z W.
+ Polymorphic Constraint W < Z.
+
+ Fail Definition bla := Type@{W}.
+ Polymorphic Definition bla := Type@{W}.
+ Section Bar.
+ Fail Constraint X <= Z.
+ End Bar.
+End Foo.
diff --git a/test-suite/bugs/opened/3410.v b/test-suite/bugs/opened/3410.v
deleted file mode 100644
index 0d259181a..000000000
--- a/test-suite/bugs/opened/3410.v
+++ /dev/null
@@ -1 +0,0 @@
-Fail repeat match goal with H:_ |- _ => setoid_rewrite X in H end.
diff --git a/test-suite/bugs/opened/4813.v b/test-suite/bugs/opened/4813.v
new file mode 100644
index 000000000..7c65accfe
--- /dev/null
+++ b/test-suite/bugs/opened/4813.v
@@ -0,0 +1,5 @@
+(* An example one would like to see succeeding *)
+
+Record T := BT { t : Set }.
+Record U (x : T) := BU { u : t x -> Prop }.
+Definition A (H : unit -> Prop) : U (BT unit) := BU _ H.
diff --git a/test-suite/complexity/ring2.v b/test-suite/complexity/ring2.v
index 52dae265b..04fa59075 100644
--- a/test-suite/complexity/ring2.v
+++ b/test-suite/complexity/ring2.v
@@ -39,7 +39,7 @@ Admitted.
Ltac Zcst t :=
match isZcst t with
true => t
- | _ => constr:NotConstant
+ | _ => constr:(NotConstant)
end.
Add Ring Zr : Zth
diff --git a/test-suite/failure/int31.v b/test-suite/failure/int31.v
new file mode 100644
index 000000000..b1d112247
--- /dev/null
+++ b/test-suite/failure/int31.v
@@ -0,0 +1,17 @@
+Require Import Int31 BigN.
+
+Open Scope int31_scope.
+
+(* This used to go through because of an unbalanced stack bug in the bytecode
+interpreter *)
+
+Lemma bad : False.
+assert (1 = 2).
+change 1 with (add31 (addmuldiv31 65 (add31 1 1) 2) 1).
+Fail vm_compute; reflexivity.
+(*
+discriminate.
+Qed.
+*)
+Abort.
+
diff --git a/test-suite/ide/undo013.fake b/test-suite/ide/undo013.fake
index f44156aa3..921a9d0f0 100644
--- a/test-suite/ide/undo013.fake
+++ b/test-suite/ide/undo013.fake
@@ -23,5 +23,5 @@ ADD { Qed. }
ADD { apply H. }
# </replay>
ADD { Qed. }
-QUERY { Fail idtac. }
+QUERY { Fail Show. }
QUERY { Check (aa,bb,cc). }
diff --git a/test-suite/ide/undo014.fake b/test-suite/ide/undo014.fake
index 6d58b061e..f5fe77470 100644
--- a/test-suite/ide/undo014.fake
+++ b/test-suite/ide/undo014.fake
@@ -22,5 +22,5 @@ ADD { destruct H. }
ADD { Qed. }
ADD { apply H. }
ADD { Qed. }
-QUERY { Fail idtac. }
+QUERY { Fail Show. }
QUERY { Check (aa,bb,cc). }
diff --git a/test-suite/ide/undo015.fake b/test-suite/ide/undo015.fake
index ac17985aa..a1e5c947b 100644
--- a/test-suite/ide/undo015.fake
+++ b/test-suite/ide/undo015.fake
@@ -25,5 +25,5 @@ ADD { destruct H. }
ADD { Qed. }
ADD { apply H. }
ADD { Qed. }
-QUERY { Fail idtac. }
+QUERY { Fail Show. }
QUERY { Check (aa,bb,cc). }
diff --git a/test-suite/ide/undo016.fake b/test-suite/ide/undo016.fake
index bdb81ecd9..f9414c1ea 100644
--- a/test-suite/ide/undo016.fake
+++ b/test-suite/ide/undo016.fake
@@ -27,5 +27,5 @@ ADD { destruct H. }
ADD { Qed. }
ADD { apply H. }
ADD { Qed. }
-QUERY { Fail idtac. }
+QUERY { Fail Show. }
QUERY { Check (aa,bb,cc). }
diff --git a/test-suite/interactive/proof_block.v b/test-suite/interactive/proof_block.v
new file mode 100644
index 000000000..31e349376
--- /dev/null
+++ b/test-suite/interactive/proof_block.v
@@ -0,0 +1,66 @@
+Goal False /\ True.
+Proof.
+split.
+ idtac.
+ idtac.
+ exact I.
+idtac.
+idtac.
+exact I.
+Qed.
+
+Lemma baz : (exists n, n = 3 /\ n = 3) /\ True.
+Proof.
+split. { eexists. split. par: trivial. }
+trivial.
+Qed.
+
+Lemma baz1 : (True /\ False) /\ True.
+Proof.
+split. { split. par: trivial. }
+trivial.
+Qed.
+
+Lemma foo : (exists n, n = 3 /\ n = 3) /\ True.
+Proof.
+split.
+ { idtac.
+ unshelve eexists.
+ { apply 3. }
+ { split.
+ { idtac. trivialx. }
+ { reflexivity. } } }
+ trivial.
+Qed.
+
+Lemma foo1 : False /\ True.
+Proof.
+split.
+ { exact I. }
+ { exact I. }
+Qed.
+
+Definition banana := true + 4.
+
+Check banana.
+
+Lemma bar : (exists n, n = 3 /\ n = 3) /\ True.
+Proof.
+split.
+ - idtac.
+ unshelve eexists.
+ + apply 3.
+ + split.
+ * idtacx. trivial.
+ * reflexivity.
+ - trivial.
+Qed.
+
+Lemma baz2 : ((1=0 /\ False) /\ True) /\ False.
+Proof.
+split. split. split.
+ - solve [ auto ].
+ - solve [ trivial ].
+ - solve [ trivial ].
+ - exact 6.
+Qed. \ No newline at end of file
diff --git a/test-suite/output/Cases.out b/test-suite/output/Cases.out
index f44465456..2b828d382 100644
--- a/test-suite/output/Cases.out
+++ b/test-suite/output/Cases.out
@@ -6,6 +6,8 @@ fix F (t : t) : P t :=
end
: forall P : t -> Type,
(let x := t in forall x0 : x, P x0 -> P (k x0)) -> forall t : t, P t
+
+Argument scopes are [function_scope function_scope _]
= fun d : TT => match d with
| @CTT _ _ b => b
end
@@ -24,7 +26,7 @@ match Nat.eq_dec x y with
end
: forall (x y : nat) (P : nat -> Type), P x -> P y -> P y
-Argument scopes are [nat_scope nat_scope _ _ _]
+Argument scopes are [nat_scope nat_scope function_scope _ _]
foo =
fix foo (A : Type) (l : list A) {struct l} : option A :=
match l with
diff --git a/test-suite/output/InitSyntax.out b/test-suite/output/InitSyntax.out
index bbfd3405a..c17c63e72 100644
--- a/test-suite/output/InitSyntax.out
+++ b/test-suite/output/InitSyntax.out
@@ -4,7 +4,8 @@ Inductive sig2 (A : Type) (P Q : A -> Prop) : Type :=
For sig2: Argument A is implicit
For exist2: Argument A is implicit
For sig2: Argument scopes are [type_scope type_scope type_scope]
-For exist2: Argument scopes are [type_scope _ _ _ _ _]
+For exist2: Argument scopes are [type_scope function_scope function_scope _ _
+ _]
exists x : nat, x = x
: Prop
fun b : bool => if b then b else b
diff --git a/test-suite/output/Intuition.out b/test-suite/output/Intuition.out
index e99d9fdeb..f2bf25ca6 100644
--- a/test-suite/output/Intuition.out
+++ b/test-suite/output/Intuition.out
@@ -3,4 +3,4 @@
m, n : Z
H : (m >= n)%Z
============================
- (m >= m)%Z
+ (m >= m)%Z
diff --git a/test-suite/output/Naming.out b/test-suite/output/Naming.out
index f0d2562e0..c142d28eb 100644
--- a/test-suite/output/Naming.out
+++ b/test-suite/output/Naming.out
@@ -2,40 +2,40 @@
x3 : nat
============================
- forall x x1 x4 x0 : nat,
- (forall x2 x5 : nat, x2 + x1 = x4 + x5) -> x + x1 = x4 + x0
+ forall x x1 x4 x0 : nat,
+ (forall x2 x5 : nat, x2 + x1 = x4 + x5) -> x + x1 = x4 + x0
1 subgoal
x3, x, x1, x4, x0 : nat
H : forall x x3 : nat, x + x1 = x4 + x3
============================
- x + x1 = x4 + x0
+ x + x1 = x4 + x0
1 subgoal
x3 : nat
============================
- forall x x1 x4 x0 : nat,
- (forall x2 x5 : nat, x2 + x1 = x4 + x5 -> foo (S x2 + x1)) ->
- x + x1 = x4 + x0 -> foo (S x)
+ forall x x1 x4 x0 : nat,
+ (forall x2 x5 : nat, x2 + x1 = x4 + x5 -> foo (S x2 + x1)) ->
+ x + x1 = x4 + x0 -> foo (S x)
1 subgoal
x3 : nat
============================
- forall x x1 x4 x0 : nat,
- (forall x2 x5 : nat,
- x2 + x1 = x4 + x5 ->
- forall x6 x7 x8 S0 : nat, x6 + S0 = x7 + x8 + (S x2 + x1)) ->
- x + x1 = x4 + x0 ->
- forall x5 x6 x7 S : nat, x5 + S = x6 + x7 + Datatypes.S x
+ forall x x1 x4 x0 : nat,
+ (forall x2 x5 : nat,
+ x2 + x1 = x4 + x5 ->
+ forall x6 x7 x8 S0 : nat, x6 + S0 = x7 + x8 + (S x2 + x1)) ->
+ x + x1 = x4 + x0 ->
+ forall x5 x6 x7 S : nat, x5 + S = x6 + x7 + Datatypes.S x
1 subgoal
x3, x, x1, x4, x0 : nat
============================
- (forall x2 x5 : nat,
- x2 + x1 = x4 + x5 ->
- forall x6 x7 x8 S0 : nat, x6 + S0 = x7 + x8 + (S x2 + x1)) ->
- x + x1 = x4 + x0 ->
- forall x5 x6 x7 S : nat, x5 + S = x6 + x7 + Datatypes.S x
+ (forall x2 x5 : nat,
+ x2 + x1 = x4 + x5 ->
+ forall x6 x7 x8 S0 : nat, x6 + S0 = x7 + x8 + (S x2 + x1)) ->
+ x + x1 = x4 + x0 ->
+ forall x5 x6 x7 S : nat, x5 + S = x6 + x7 + Datatypes.S x
1 subgoal
x3, x, x1, x4, x0 : nat
@@ -44,7 +44,7 @@
forall x0 x4 x5 S0 : nat, x0 + S0 = x4 + x5 + (S x + x1)
H0 : x + x1 = x4 + x0
============================
- forall x5 x6 x7 S : nat, x5 + S = x6 + x7 + Datatypes.S x
+ forall x5 x6 x7 S : nat, x5 + S = x6 + x7 + Datatypes.S x
1 subgoal
x3, x, x1, x4, x0 : nat
@@ -54,10 +54,10 @@
H0 : x + x1 = x4 + x0
x5, x6, x7, S : nat
============================
- x5 + S = x6 + x7 + Datatypes.S x
+ x5 + S = x6 + x7 + Datatypes.S x
1 subgoal
x3, a : nat
H : a = 0 -> forall a : nat, a = 0
============================
- a = 0
+ a = 0
diff --git a/test-suite/output/Notations2.out b/test-suite/output/Notations2.out
index 58ec1de56..6ff1d3837 100644
--- a/test-suite/output/Notations2.out
+++ b/test-suite/output/Notations2.out
@@ -50,3 +50,7 @@ end
: nat -> nat
# _ : nat => 2
: nat -> nat
+# x : nat => # H : x <= 0 => exist (le x) 0 H
+ : ∀ x : nat, x <= 0 -> {x0 : nat | x <= x0}
+exist (Q x) y conj
+ : {x0 : A | Q x x0}
diff --git a/test-suite/output/Notations2.v b/test-suite/output/Notations2.v
index e53c94ef0..4e0d135d7 100644
--- a/test-suite/output/Notations2.v
+++ b/test-suite/output/Notations2.v
@@ -68,6 +68,7 @@ Check let' f x y (a:=0) z (b:bool) := x+y+z+1 in f 0 1 2.
(* In practice, only the printing rule is used here *)
(* Note: does not work for pattern *)
+Module A.
Notation "f ( x )" := (f x) (at level 10, format "f ( x )").
Check fun f x => f x + S x.
@@ -77,6 +78,7 @@ Notation plus2 n := (S (S n)).
(* plus2 was not correctly printed in the two following tests in 8.3pl1 *)
Print plus2.
Check fun n => match n with list1 => 0 | _ => 2 end.
+End A.
(* This one is not fully satisfactory because binders in the same type
are re-factorized and parentheses are needed even for atomic binder
@@ -98,3 +100,9 @@ Notation "# x : T => t" := (fun x : T => t)
Check # x : nat => x.
Check # _ : nat => 2.
+
+(* Check bug 4677 *)
+Check fun x (H:le x 0) => exist (le x) 0 H.
+
+Parameters (A : Set) (x y : A) (Q : A -> A -> Prop) (conj : Q x y).
+Check (exist (Q x) y conj).
diff --git a/test-suite/output/PrintInfos.out b/test-suite/output/PrintInfos.out
index ba076f050..98420409e 100644
--- a/test-suite/output/PrintInfos.out
+++ b/test-suite/output/PrintInfos.out
@@ -2,7 +2,7 @@ existT : forall (A : Type) (P : A -> Type) (x : A), P x -> {x : A & P x}
existT is template universe polymorphic
Argument A is implicit
-Argument scopes are [type_scope _ _ _]
+Argument scopes are [type_scope function_scope _ _]
Expands to: Constructor Coq.Init.Specif.existT
Inductive sigT (A : Type) (P : A -> Type) : Type :=
existT : forall x : A, P x -> {x : A & P x}
@@ -10,7 +10,7 @@ Inductive sigT (A : Type) (P : A -> Type) : Type :=
For sigT: Argument A is implicit
For existT: Argument A is implicit
For sigT: Argument scopes are [type_scope type_scope]
-For existT: Argument scopes are [type_scope _ _ _]
+For existT: Argument scopes are [type_scope function_scope _ _]
existT : forall (A : Type) (P : A -> Type) (x : A), P x -> {x : A & P x}
Argument A is implicit
diff --git a/test-suite/output/Quote.out b/test-suite/output/Quote.out
index ca7fc3624..998eb37cc 100644
--- a/test-suite/output/Quote.out
+++ b/test-suite/output/Quote.out
@@ -8,17 +8,17 @@
H : interp_f (Node_vm A (Empty_vm Prop) (Empty_vm Prop)) (f_atom End_idx) \/
B
============================
- interp_f
- (Node_vm B (Node_vm A (Empty_vm Prop) (Empty_vm Prop)) (Empty_vm Prop))
- (f_and (f_atom (Left_idx End_idx))
- (f_and (f_or (f_atom End_idx) (f_atom (Left_idx End_idx)))
- (f_or (f_atom (Left_idx End_idx)) (f_not (f_atom End_idx)))))
+ interp_f
+ (Node_vm B (Node_vm A (Empty_vm Prop) (Empty_vm Prop)) (Empty_vm Prop))
+ (f_and (f_atom (Left_idx End_idx))
+ (f_and (f_or (f_atom End_idx) (f_atom (Left_idx End_idx)))
+ (f_or (f_atom (Left_idx End_idx)) (f_not (f_atom End_idx)))))
1 subgoal
H : interp_f (Node_vm A (Empty_vm Prop) (Empty_vm Prop)) (f_atom End_idx) \/
B
============================
- interp_f (Node_vm B (Empty_vm Prop) (Empty_vm Prop))
- (f_and (f_const A)
- (f_and (f_or (f_atom End_idx) (f_const A))
- (f_or (f_const A) (f_not (f_atom End_idx)))))
+ interp_f (Node_vm B (Empty_vm Prop) (Empty_vm Prop))
+ (f_and (f_const A)
+ (f_and (f_or (f_atom End_idx) (f_const A))
+ (f_or (f_const A) (f_not (f_atom End_idx)))))
diff --git a/test-suite/output/ltac.out b/test-suite/output/ltac.out
index d003c70df..21a8cf9ed 100644
--- a/test-suite/output/ltac.out
+++ b/test-suite/output/ltac.out
@@ -1,2 +1,24 @@
The command has indeed failed with message:
Error: Ltac variable y depends on pattern variable name z which is not bound in current context.
+Ltac f x y z :=
+ symmetry in x, y; auto with z; auto; intros **; clearbody x; generalize
+ dependent z
+The command has indeed failed with message:
+In nested Ltac calls to "g1" and "refine", last call failed.
+The term "I" has type "True" while it is expected to have type "False".
+The command has indeed failed with message:
+In nested Ltac calls to "f1" and "refine", last call failed.
+The term "I" has type "True" while it is expected to have type "False".
+The command has indeed failed with message:
+In nested Ltac calls to "g2", "g1" and "refine", last call failed.
+The term "I" has type "True" while it is expected to have type "False".
+The command has indeed failed with message:
+In nested Ltac calls to "f2", "f1" and "refine", last call failed.
+The term "I" has type "True" while it is expected to have type "False".
+The command has indeed failed with message:
+Ltac call to "h" failed.
+Error: Ltac variable x is bound to I which cannot be coerced to
+a declared or quantified hypothesis.
+The command has indeed failed with message:
+In nested Ltac calls to "h" and "injection", last call failed.
+Error: No primitive equality found.
diff --git a/test-suite/output/ltac.v b/test-suite/output/ltac.v
index 7e2610c7d..dfa60eeda 100644
--- a/test-suite/output/ltac.v
+++ b/test-suite/output/ltac.v
@@ -15,3 +15,31 @@ lazymatch goal with
| H1 : HT |- _ => idtac
end.
Abort.
+
+Ltac f x y z :=
+ symmetry in x, y;
+ auto with z;
+ auto;
+ intros;
+ clearbody x;
+ generalize dependent z.
+
+Print Ltac f.
+
+(* Error messages *)
+
+Ltac g1 x := refine x.
+Tactic Notation "g2" constr(x) := g1 x.
+Tactic Notation "f1" constr(x) := refine x.
+Ltac f2 x := f1 x.
+Goal False.
+Fail g1 I.
+Fail f1 I.
+Fail g2 I.
+Fail f2 I.
+
+Ltac h x := injection x.
+Goal True -> False.
+Fail h I.
+intro H.
+Fail h H.
diff --git a/test-suite/output/set.out b/test-suite/output/set.out
index 4dfd2bc22..4b72d73eb 100644
--- a/test-suite/output/set.out
+++ b/test-suite/output/set.out
@@ -3,16 +3,16 @@
y1 := 0 : nat
x := 0 + 0 : nat
============================
- x = x
+ x = x
1 subgoal
y1, y2 := 0 : nat
x := y2 + 0 : nat
============================
- x = x
+ x = x
1 subgoal
y1, y2, y3 := 0 : nat
x := y2 + y3 : nat
============================
- x = x
+ x = x
diff --git a/test-suite/output/simpl.out b/test-suite/output/simpl.out
index 73888da9a..526e468f5 100644
--- a/test-suite/output/simpl.out
+++ b/test-suite/output/simpl.out
@@ -2,14 +2,14 @@
x : nat
============================
- x = S x
+ x = S x
1 subgoal
x : nat
============================
- 0 + x = S x
+ 0 + x = S x
1 subgoal
x : nat
============================
- x = 1 + x
+ x = 1 + x
diff --git a/test-suite/output/subst.out b/test-suite/output/subst.out
new file mode 100644
index 000000000..209b2bc26
--- /dev/null
+++ b/test-suite/output/subst.out
@@ -0,0 +1,97 @@
+1 subgoal
+
+ y, z : nat
+ Hy : y = 0
+ Hz : z = 0
+ H1 : 0 = 1
+ HA : True
+ H2 : 0 = 2
+ H3 : y = 3
+ HB : True
+ H4 : z = 4
+ ============================
+ True
+1 subgoal
+
+ x, z : nat
+ Hx : x = 0
+ Hz : z = 0
+ H1 : x = 1
+ HA : True
+ H2 : x = 2
+ H3 : 0 = 3
+ HB : True
+ H4 : z = 4
+ ============================
+ True
+1 subgoal
+
+ x, y : nat
+ Hx : x = 0
+ Hy : y = 0
+ H1 : x = 1
+ HA : True
+ H2 : x = 2
+ H3 : y = 3
+ HB : True
+ H4 : 0 = 4
+ ============================
+ True
+1 subgoal
+
+ H1 : 0 = 1
+ HA : True
+ H2 : 0 = 2
+ H3 : 0 = 3
+ HB : True
+ H4 : 0 = 4
+ ============================
+ True
+1 subgoal
+
+ y, z : nat
+ Hy : y = 0
+ Hz : z = 0
+ HA : True
+ H3 : y = 3
+ HB : True
+ H4 : z = 4
+ H1 : 0 = 1
+ H2 : 0 = 2
+ ============================
+ True
+1 subgoal
+
+ x, z : nat
+ Hx : x = 0
+ Hz : z = 0
+ H1 : x = 1
+ HA : True
+ H2 : x = 2
+ HB : True
+ H4 : z = 4
+ H3 : 0 = 3
+ ============================
+ True
+1 subgoal
+
+ x, y : nat
+ Hx : x = 0
+ Hy : y = 0
+ H1 : x = 1
+ HA : True
+ H2 : x = 2
+ H3 : y = 3
+ HB : True
+ H4 : 0 = 4
+ ============================
+ True
+1 subgoal
+
+ HA, HB : True
+ H4 : 0 = 4
+ H3 : 0 = 3
+ H1 : 0 = 1
+ H2 : 0 = 2
+ ============================
+ True
diff --git a/test-suite/output/subst.v b/test-suite/output/subst.v
new file mode 100644
index 000000000..e48aa6bb2
--- /dev/null
+++ b/test-suite/output/subst.v
@@ -0,0 +1,48 @@
+(* Ensure order of hypotheses is respected after "subst" *)
+
+Set Regular Subst Tactic.
+Goal forall x y z, x = 0 -> y = 0 -> z = 0 -> x = 1 -> True -> x = 2 -> y = 3 -> True -> z = 4 -> True.
+intros * Hx Hy Hz H1 HA H2 H3 HB H4.
+(* From now on, the order after subst is consistently H1, HA, H2, H3, HB, H4 *)
+subst x.
+(* In 8.4 or 8.5 without regular subst tactic mode, the order was HA, H3, HB, H4, H1, H2 *)
+Show.
+Undo.
+subst y.
+(* In 8.4 or 8.5 without regular subst tactic mode, the order was H1, HA, H2, HB, H4, H3 *)
+Show.
+Undo.
+subst z.
+(* In 8.4 or 8.5 without regular subst tactic mode, the order was H1, HA, H2, H3, HB, H4 *)
+Show.
+Undo.
+subst.
+(* In 8.4 or 8.5 without regular subst tactic mode, the order was HA, HB, H4, H3, H1, H2 *)
+(* In 8.5pl0 and 8.5pl1 with regular subst tactic mode, the order was HA, HB, H1, H2, H3, H4 *)
+Show.
+trivial.
+Qed.
+
+Unset Regular Subst Tactic.
+Goal forall x y z, x = 0 -> y = 0 -> z = 0 -> x = 1 -> True -> x = 2 -> y = 3 -> True -> z = 4 -> True.
+intros * Hx Hy Hz H1 HA H2 H3 HB H4.
+subst x.
+(* In 8.4 or 8.5 without regular subst tactic mode, the order was HA, H3, HB, H4, H1, H2 *)
+Show.
+Undo.
+subst y.
+(* In 8.4 or 8.5 without regular subst tactic mode, the order was H1, HA, H2, HB, H4, H3 *)
+Show.
+Undo.
+subst z.
+(* In 8.4 or 8.5 without regular subst tactic mode, the order was H1, HA, H2, H3, HB, H4 *)
+Show.
+Undo.
+subst.
+(* In 8.4 or 8.5 without regular subst tactic mode, the order was HA, HB, H4, H3, H1, H2 *)
+(* In 8.5pl0 and 8.5pl1 with regular subst tactic mode, the order was HA, HB, H1, H2, H3, H4 *)
+Show.
+trivial.
+Qed.
+
+
diff --git a/test-suite/success/CaseInClause.v b/test-suite/success/CaseInClause.v
index 3679eead7..599b9566c 100644
--- a/test-suite/success/CaseInClause.v
+++ b/test-suite/success/CaseInClause.v
@@ -20,3 +20,7 @@ Theorem foo : forall (n m : nat) (pf : n = m),
match pf in _ = N with
| eq_refl => unit
end.
+
+(* Check redundant clause is removed *)
+Inductive I : nat * nat -> Type := C : I (0,0).
+Check fun x : I (1,1) => match x in I (y,z) return y = z with C => eq_refl end.
diff --git a/test-suite/success/Compat84.v b/test-suite/success/Compat84.v
new file mode 100644
index 000000000..db6348fa1
--- /dev/null
+++ b/test-suite/success/Compat84.v
@@ -0,0 +1,19 @@
+(* -*- coq-prog-args: ("-emacs" "-compat" "8.4") -*- *)
+
+Goal True.
+ solve [ constructor 1 ]. Undo.
+ solve [ econstructor 1 ]. Undo.
+ solve [ constructor ]. Undo.
+ solve [ econstructor ]. Undo.
+ solve [ constructor (fail) ]. Undo.
+ solve [ econstructor (fail) ]. Undo.
+ split.
+Qed.
+
+Goal False \/ True.
+ solve [ constructor (constructor) ]. Undo.
+ solve [ econstructor (econstructor) ]. Undo.
+ solve [ constructor 2; constructor ]. Undo.
+ solve [ econstructor 2; econstructor ]. Undo.
+ right; esplit.
+Qed.
diff --git a/test-suite/success/MatchFail.v b/test-suite/success/MatchFail.v
index 7069bba43..8462d3627 100644
--- a/test-suite/success/MatchFail.v
+++ b/test-suite/success/MatchFail.v
@@ -9,14 +9,14 @@ Require Export ZArithRing.
Ltac compute_POS :=
match goal with
| |- context [(Zpos (xI ?X1))] =>
- let v := constr:X1 in
- match constr:v with
+ let v := constr:(X1) in
+ match constr:(v) with
| 1%positive => fail 1
| _ => rewrite (BinInt.Pos2Z.inj_xI v)
end
| |- context [(Zpos (xO ?X1))] =>
- let v := constr:X1 in
- match constr:v with
+ let v := constr:(X1) in
+ match constr:(v) with
| 1%positive => fail 1
| _ => rewrite (BinInt.Pos2Z.inj_xO v)
end
diff --git a/test-suite/success/Notations2.v b/test-suite/success/Notations2.v
new file mode 100644
index 000000000..9505a56e3
--- /dev/null
+++ b/test-suite/success/Notations2.v
@@ -0,0 +1,92 @@
+(* This file is giving some examples about how implicit arguments and
+ scopes are treated when using abbreviations or notations, in terms
+ or patterns, or when using @ and parentheses in terms and patterns.
+
+The convention is:
+
+Constant foo with implicit arguments and scopes used in a term or a pattern:
+
+ foo do not deactivate further arguments and scopes
+ @foo deactivates further arguments and scopes
+ (foo x) deactivates further arguments and scopes
+ (@foo x) deactivates further arguments and scopes
+
+Notations binding to foo:
+
+# := foo do not deactivate further arguments and scopes
+# := @foo deactivates further arguments and scopes
+# x := foo x deactivates further arguments and scopes
+# x := @foo x deactivates further arguments and scopes
+
+Abbreviations binding to foo:
+
+f := foo do not deactivate further arguments and scopes
+f := @foo deactivates further arguments and scopes
+f x := foo x do not deactivate further arguments and scopes
+f x := @foo x do not deactivate further arguments and scopes
+*)
+
+(* One checks that abbreviations and notations in patterns now behave like in terms *)
+
+Inductive prod' A : Type -> Type :=
+| pair' (a:A) B (b:B) (c:bool) : prod' A B.
+Arguments pair' [A] a%bool_scope [B] b%bool_scope c%bool_scope.
+Notation "0" := true : bool_scope.
+
+(* 1. Abbreviations do not stop implicit arguments to be inserted and scopes to be used *)
+Notation c1 x := (pair' x).
+Check pair' 0 0 0 : prod' bool bool.
+Check (pair' 0) _ 0%bool 0%bool : prod' bool bool. (* parentheses are blocking implicit and scopes *)
+Check c1 0 0 0 : prod' bool bool.
+Check fun x : prod' bool bool => match x with c1 0 y 0 => 2 | _ => 1 end.
+
+(* 2. Abbreviations do not stop implicit arguments to be inserted and scopes to be used *)
+Notation c2 x := (@pair' _ x).
+Check (@pair' _ 0) _ 0%bool 0%bool : prod' bool bool. (* parentheses are blocking implicit and scopes *)
+Check c2 0 0 0 : prod' bool bool.
+Check fun A (x : prod' bool A) => match x with c2 0 y 0 => 2 | _ => 1 end.
+Check fun A (x : prod' bool A) => match x with (@pair' _ 0) _ y 0%bool => 2 | _ => 1 end.
+
+(* 3. Abbreviations do not stop implicit arguments to be inserted and scopes to be used *)
+Notation c3 x := ((@pair') _ x).
+Check (@pair') _ 0%bool _ 0%bool 0%bool : prod' bool bool. (* @ is blocking implicit and scopes *)
+Check ((@pair') _ 0%bool) _ 0%bool 0%bool : prod' bool bool. (* parentheses and @ are blocking implicit and scopes *)
+Check c3 0 0 0 : prod' nat bool. (* First scope is blocked but not the last two scopes *)
+Check fun A (x :prod' nat A) => match x with c3 0 y 0 => 2 | _ => 1 end.
+
+(* 4. Abbreviations do not stop implicit arguments to be inserted and scopes to be used *)
+(* unless an atomic @ is given *)
+Notation c4 := (@pair').
+Check (@pair') _ 0%bool _ 0%bool 0%bool : prod' bool bool.
+Check c4 _ 0%bool _ 0%bool 0%bool : prod' bool bool.
+Check fun A (x :prod' bool A) => match x with c4 _ 0%bool _ y 0%bool => 2 | _ => 1 end.
+Check fun A (x :prod' bool A) => match x with (@pair') _ 0%bool _ y 0%bool => 2 | _ => 1 end.
+
+(* 5. Notations stop further implicit arguments to be inserted and scopes to be used *)
+Notation "# x" := (pair' x) (at level 0, x at level 1).
+Check pair' 0 0 0 : prod' bool bool.
+Check # 0 _ 0%bool 0%bool : prod' bool bool.
+Check fun A (x :prod' bool A) => match x with # 0 _ y 0%bool => 2 | _ => 1 end.
+
+(* 6. Notations stop further implicit arguments to be inserted and scopes to be used *)
+Notation "## x" := ((@pair') _ x) (at level 0, x at level 1).
+Check (@pair') _ 0%bool _ 0%bool 0%bool : prod' bool bool.
+Check ((@pair') _ 0%bool) _ 0%bool 0%bool : prod' bool bool.
+Check ## 0%bool _ 0%bool 0%bool : prod' bool bool.
+Check fun A (x :prod' bool A) => match x with ## 0%bool _ y 0%bool => 2 | _ => 1 end.
+
+(* 7. Notations stop further implicit arguments to be inserted and scopes to be used *)
+Notation "###" := (@pair') (at level 0).
+Check (@pair') _ 0%bool _ 0%bool 0%bool : prod' bool bool.
+Check ### _ 0%bool _ 0%bool 0%bool : prod' bool bool.
+Check fun A (x :prod' bool A) => match x with ### _ 0%bool _ y 0%bool => 2 | _ => 1 end.
+
+(* 8. Notations w/o @ preserves implicit arguments and scopes *)
+Notation "####" := pair' (at level 0).
+Check #### 0 0 0 : prod' bool bool.
+Check fun A (x :prod' bool A) => match x with #### 0 y 0 => 2 | _ => 1 end.
+
+(* 9. Notations w/o @ but arguments do not preserve further implicit arguments and scopes *)
+Notation "##### x" := (pair' x) (at level 0, x at level 1).
+Check ##### 0 _ 0%bool 0%bool : prod' bool bool.
+Check fun A (x :prod' bool A) => match x with ##### 0 _ y 0%bool => 2 | _ => 1 end.
diff --git a/test-suite/success/TacticNotation2.v b/test-suite/success/TacticNotation2.v
new file mode 100644
index 000000000..cb341b8e1
--- /dev/null
+++ b/test-suite/success/TacticNotation2.v
@@ -0,0 +1,12 @@
+Tactic Notation "complete" tactic(tac) := tac; fail.
+
+Ltac f0 := complete (intuition idtac).
+(** FIXME: This is badly printed because of bug #3079.
+ At least we check that it does not fail anomalously. *)
+Print Ltac f0.
+
+Ltac f1 := complete f1.
+Print Ltac f1.
+
+Ltac f2 := complete intuition.
+Print Ltac f2.
diff --git a/test-suite/success/auto.v b/test-suite/success/auto.v
index aaa7b3a51..5477c8331 100644
--- a/test-suite/success/auto.v
+++ b/test-suite/success/auto.v
@@ -45,3 +45,92 @@ Proof.
eexists. Fail progress debug eauto with test2.
progress eauto with test.
Qed.
+
+(** Patterns of Extern have a "matching" semantics.
+ It is not so for apply/exact hints *)
+
+Class B (A : Type).
+Class I.
+Instance i : I.
+
+Definition flip {A B C : Type} (f : A -> B -> C) := fun y x => f x y.
+Class D (f : nat -> nat -> nat).
+Definition ftest (x y : nat) := x + y.
+Definition flipD (f : nat -> nat -> nat) : D f -> D (flip f).
+ Admitted.
+Module Instnopat.
+ Local Instance: B nat.
+ (* pattern_of_constr -> B nat *)
+ (* exact hint *)
+ Check (_ : B nat).
+ (* map_eauto -> B_instance0 *)
+ (* NO Constr_matching.matches !!! *)
+ Check (_ : B _).
+
+ Goal exists T, B T.
+ eexists.
+ eauto with typeclass_instances.
+ Qed.
+
+ Local Instance: D ftest.
+ Local Hint Resolve flipD | 0 : typeclass_instances.
+ (* pattern: D (flip _) *)
+ Fail Timeout 1 Check (_ : D _). (* loops applying flipD *)
+
+End Instnopat.
+
+Module InstnopatApply.
+ Local Instance: I -> B nat.
+ (* pattern_of_constr -> B nat *)
+ (* apply hint *)
+ Check (_ : B nat).
+ (* map_eauto -> B_instance0 *)
+ (* NO Constr_matching.matches !!! *)
+ Check (_ : B _).
+
+ Goal exists T, B T.
+ eexists.
+ eauto with typeclass_instances.
+ Qed.
+End InstnopatApply.
+
+Module InstPat.
+ Hint Extern 3 (B nat) => split : typeclass_instances.
+ (* map_eauto -> Extern hint *)
+ (* Constr_matching.matches -> true *)
+ Check (_ : B nat).
+ (* map_eauto -> Extern hint *)
+ (* Constr_matching.matches -> false:
+ Because an inductive in the pattern does not match an evar in the goal *)
+ Check (_ : B _).
+
+ Goal exists T, B T.
+ eexists.
+ (* map_existential -> Extern hint *)
+ (* Constr_matching.matches -> false *)
+ Fail progress eauto with typeclass_instances.
+ (* map_eauto -> Extern hint *)
+ (* Constr_matching.matches -> false *)
+ Fail typeclasses eauto.
+ Abort.
+
+ Hint Extern 0 (D (flip _)) => apply flipD : typeclass_instances.
+ Module withftest.
+ Local Instance: D ftest.
+
+ Check (_ : D _).
+ (* D_instance_0 : D ftest *)
+ Check (_ : D (flip _)).
+ (* ... : D (flip ftest) *)
+ End withftest.
+ Module withoutftest.
+ Hint Extern 0 (D ftest) => split : typeclass_instances.
+ Check (_ : D _).
+ (* ? : D ?, _not_ looping *)
+ Check (_ : D (flip _)).
+ (* ? : D (flip ?), _not_ looping *)
+
+ Check (_ : D (flip ftest)).
+ (* flipD ftest {| |} : D (flip ftest) *)
+ End withoutftest.
+End InstPat.
diff --git a/test-suite/success/bigQ.v b/test-suite/success/bigQ.v
new file mode 100644
index 000000000..7fd0cf669
--- /dev/null
+++ b/test-suite/success/bigQ.v
@@ -0,0 +1,66 @@
+Require Import BigQ.
+Import List.
+
+Definition pi_4_approx_low' :=
+(5066193963420194617885108698600649932059391557720145469382602092416947640628637390992675949693715109726079394291478795603894419483819297806310615866892414925850691415582239745615128821983865262221858109336884967754871321668348027076234335167119885298878199925731495390387858629042311908406056230882123787019283378509712244687397013657159455607193734144010901984756727174636853404278421831024545476850410085042498464474261035780891759930905778986584183710930670670301831474144997069400304290351567959717683444430666444319233768399342338059169002790777424962570605618705584660815518973602995097110557181643034682308210782171804373210646804613922337450953858508244032293753591878060539465788294318856859293281629951093130167801471787011911886414492513677892193100809508943832528344473873460853362957387889412799458784754514139679847887887544849825173792522272708046699681079289358082661375778523609867456540595586031625044964543428047238934233579184772793670436643502740076366994465457847106782560289782615794595755672643440040123002018908935362541166831619056664637901929131328502017686713274283777724453661234225382109584471950444925886358166551424008707439387934109226545596919797083495958300914344992836193126080289565652575543234385558967555959267746932292860747199382633363026440008828134867747920263181610216905129926037611247017868033961426567047355301676870662406173724238530061264149506666345040372864118731705584795947926329181826992456072045382170981478151356381437136818835196834068650217794381425547036331194595892801393225038235274901050364737353586927051766717037643833477566087835266968086513005761986678747515870298138062157791066648217784877968385924845017637219384732843791052551854695220023477365706464590594542001161575677402761543188277502092362285265847964496740584911576627239093631932307473445797386335961743298553548881544486940399236133577915988716682746485564575640818803540680574730591500432326858763829791848612343662539095316357052823005419355719381626599487868023399182174939253393897549026675976384326749445831606130546375395770778462506203752920470130305293966478109733954117063941901686840180727195741528561335809865193566993349413786715403053579411364371500063193205131503024022217701373077790337150298315820556080596579100618643147698304927957576213733526923182742441048553793831725592624850721293495085399785588171300815789795594858916409701139277050529011775828846362873246196866089783324522718656445008090114701320562608474099248873638488023114015981013142490827777895317580810590743940417298263300561876701828404744082864248409230009391001735746615476377303707782123483770118391136826609366946585715225248587168403619476143657107412319421501162805102723455593551478028055839072686207007765300258935153546418515706362733656094770289090398825190320430416955807878686642673124733998295439657633866090085982598765253268688814792672416195730086607425842181518560588819896560847103627615434844684536463752986969865794019299978956052589825441828842338163389851892617560591840546654410705167593310272272965900821031821380595084783691324416454359888103920904935692840264474003367023256964191100139001239923263691779167792867186165635514824889759796850863175082506408142175595463676408992027105356481220754473245821534527625758942093801142305560662681150069082553674495761075895588095760081401141419460482860852822686860785424514171214889677926763812031823537071721974799922995763666175738785000806081164280471363125324839717808977470218218571800106898347366938927189989988149888641129263448064762730769285877330997355234347773807099829665997515649429224335217107760728789764718885665291038706425454675746218345291274054088843647602239258308472486102933167465443294268551209015027897159307743987020521392788721231001835675584104894174434637260464035122611721657641428625505184886116917149318963070896162119215386541876236027342810162765609201440423207771441367926085768438143507025739041041240810056881304230519058117534418374553879198061289605354335880794397478047346975609179199801003098836622253165101961484972165230151495472006888128587168049198312469715081555662345452800468933420359802645393289853553618279788400476187713990872203669487294118461245455333004125835663010526985716431187034663870796866708678078952110615910196519835267441831874676895301527286826106517027821074816850326548617513767142627360001181210946100011774672126943957522004190414960909074050454565964857276407084991922274068961845339154089866785707764290964299529444616711194034827611771558783466230353209661849406004241580029437779784290315347968833708422223285859451369907260780956405036020581705441364379616715041818815829810906212826084485200785283123265202151252852134381195424724503189247411069117189489985791487434549080447866370484866697404176437230771558469231403088139693477706784802801265075586678597768511791952562627345622499328
+ # 100788726492580594349650258277496659410917619472657560321971265983799894639441017438166498752997098978003489632843381325240982516059309714013145358125224597827602157516585886911710102182473475545864474089191789296685473601331678556438310133356793199956062857423397512495293688453655805536015029176541424005214818033707522950635262669828538132795615008381824067071229426026518897202246241637377064076189277685257166926338187911595052586669184297526234794666364657344206795357967279911782849686515024121916258300642000317525374433525235296287037535618423661645124459323811792936193272341688261801253469089129439519903538495370298752436267926761998785090092411372633429302950606054074205533246665546979112178855223925266166034953000200646676762301817000435641690517142795144469005596172113586738287118865058604922865654348297975054956781513943444060257230946224520058527667925776273088622386666860662470481606622952298649177217986593047495967209669116410592230626047083795555559776477430548946990993890380787911273437967786556742804566652408275798339221179283430482118140020742719695900657696142739101628984271513292954605191778803974738871043737934546460016184719168074062912083778327025499841998124431899131874519812228674255796948879306477894924710085384116453080236862135706628989104070747737689294987000148388110561753028594988959655591699155508380909698460304884908709246116411180876105681720036833487450945730831039969246996849503525429840196651386469599438064049723005123629385485140945945416764414133189625489032807860400751723995946290581976152580477047961138617997133510128194027510895265424780627975864980749945631413855375897945293107842908479797077570371447220506451229526132919408351287454305932886749170523056147842439813407002950370505941417426433452282518739345666494683448699945734453214481915512562995906034771246088038719298959180199052759295868161570318718927430655393250250811804905393113074074574608255523847592006804881016594060188745212933427473833239777228852952217878690668413947367586040297784502192683200664398064682201012931468052982448022330449955215606614483165425935154496289535573901139223034819824408001205784146243892228030383941863746839845526558421740316887532141893650230936137269356278754487130882868595412163277284772124736531380334814212708066069618080153747333573454834500999083737284449542481264971030785043701582134343596645346132964567391370300568578875509971483039720438955919863275044932311289587494336123538202079503922025306586828117649623642521324286648529829664567232756108169459356549144779085080036654897525078792273443307070502103724611233768453196294899770515940520895908289018412144327894912660060761908970811602375085884115384049610753387776858733798341463052471017393165656926510611173543365663267563198760597092606598728110197523695339144204179424646442294307593146446562536865057987897899655645968129515654148044008249646703504419478535298270862753806142083172190778193001810574370442181909146645889199829207284871551220439225371051511970054965951914399901815408791418836185742573331879114400013259342896515702942707292473805188905427717363630137869116872433627556880809120353079342030725196065815470427569172350436988386579444534375353968759750750178342190349607711313840613843718547859929387259163285524671855725511880656411741012446023392964655239624520090988149679656514996202498334816938716757663800773997302639681907686195671083505910700098597156238624351157219093280177066146218516478636356056420098245995113668018177690728654922707281126889313941750547830163078886329630807850633273613622550216189245162735650139455042125252043274668279981753287687674520319519360593091620297805736177366738063651905396783336064579717230286821545930579779462534206093794040878198825916141099864730374109311705285661056855668930671948265232862757146615431791375559792290479316263924560826544387396762768331402198937951439504767950821089741987629257538953417586416459087855138539304027013800937360598578194413362672871055543854633921502486683911956250444582746421552178164852341035733290405311280719066037175324627429434912416361334254696649419037348733709488576582107382055914938194078813926926742828297826939120316120573453588052056773875836843924877773978390546387248009519202370375478981843515393806263037580338009594022254079586380520797699651840576286033587273591899639699077044271208886940540056794360292760863657703246410020854088849880453524038877935317875884698324859548991680533307680053872403383516589028793015681082435908524045497475001609824047204954932626536311826911363867426654549346914317405110707189532251727848751560224936842128628673253616256326013555922159336370177663785738170802777550686079119049748734352584409583136667752555307842739679930698964098088960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)%bigQ
+.
+
+Definition pi_4_approx_high' :=
+(5066193963420194617885108698600649932059391557720145469382602092416947640628637390992675949693715109726079394291478795603894419483819297806310615866892414925850691415582239745615128821983865262221858109336884967754871321668348027076234335167119885298878199925731495390387858629042311908406056230882123787019283378509712244687397013657159455607193734144010901984756727174636853404278421831024545476850410085042498464474261035780891759930905778986584183710930670670301831474144997069400304290351567959717683444430666444319233768399342338059169002790777424962570605618705584660815518973602995097110557181643034682308210788409308322071457087096445676662503017187903223859814905546579050729173916234740628466315449085686468204847296426235788544874405450791749423436215032927889914519102361378633666267941326393265376660400091389373564825046526561381561278586121772300141564909333667988204680492088607706214346458601842899721615765319505314310192693665547163360402786722105590252780194994950097926184146718893770363322073641336811404180286358079915338791029818581497746089864894356686643882883410392601500048021013346713450539807687779704798018559373507951388092945938366448668853081682176581336156031434604604833692503597621519809826880683536141897075567053733515342478008373282599947520770191238802249392773327261328133194484586433840861730959791563023761306622956165536481335792721379318928171897265310054788931201902441066997927781894934061720760080768154565282051604447333036111267534150649674590201404453202347064545359869105856798745664471694795576801148562495225166002814304124970965817043547048503388910163287916513427409193998045119986267987892522931703487420953769290650229176116308194977201080691718825944370436642709192983358059711255925052564016519597530235976618244111239816418652282585432539731271068892992142956810775762851238126881225206289553948196520384709574383566733478326330112084307565420647201107231840508040019131253750047046446929758911912155202166566751947087545292626353331520202690130850009389387290465497377022080531269511355734944672010542204118978272180881335465227900174033380001851066811103401787656367819132934758616060307366679580043123632565656840669377840733018248707250548277181001911990237151790533341326223932843775840498222236867608395855700891719880219904948672458645420169533565809609056209006342663841718949396996175294237942265325043426430990062217643279654512512640557763489491751115437780462208361129433667449740743123546232162409802316714286708788831227582498585478334315076725145986771341647015244092760289407649044493584479944044779273447198382196766547779885914425854375158084417582279211000449529495605127376707776277159376010648950025135061284601443461110447113346277147728593420397807946636800365109579479211273476195727270004743568492888900356505584731622538401071221591141889158461271000051210318027818802379539544396973228585821742794928813630781709195703717312953337431290682263448669168179857644544116657440168099166467471736180072984407514757289757495435699300593165669101965987430482600019222913485092771346963058673132443387835726110205958057187517487684058179749952286341120230051432903482992282688283815697442898155194928723360957436110770317998431272108100149791425689283090777721270428030993332057319821685391144252815655146410678839177846108260765981523812232294638190350688210999605869296307711846463311346627138400477211801219366400312514793356564308532012682051019030257269068628100171220662165246389309014292764479226570049772046255291379151017129899157296574099437276707879597755725339406865738613810979022640265737120949077721294633786520294559343155148383011293584240192753971366644780434237846862975993387453786681995831719537733846579480995517357440575781962659282856696638992709756358478461648462532279323701121386551383509193782388241965285971965887701816406255233933761008649762854363984142178331798953040874526844255758512982810004271235810681505829473926495256537353108899526434200682024946218302499640511518360332022463196599199779172637638655415918976955930735312156870786600023896830267884391447789311101069654521354446521135407720085038662159974712373018912537116964809382149581004863115431780452188813210275393919111435118030412595133958954313836191108258769640843644195537185904547405641078708492098917460393911427237155683288565433183738513871595286090814836422982384810033331519971102974091067660369548406192526284519976668985518575216481570167748402860759832933071281814538397923687510782620605409323050353840034866296214149657376249634795555007199540807313397329050410326609108411299737760271566308288500400587417017113933243099961248847368789383209110747378488312550109911605079801570534271874115018095746872468910162721975463388518648962869080447866370484866697404176437230771558469231403088139693477706784802801265075586678597768511791952562627345622499328
+ # 100788726492580594349650258277496659410917619472657560321971265983799894639441017438166498752997098978003489632843381325240982516059309714013145358125224597827602157516585886911710102182473475545864474089191789296685473601331678556438310133356793199956062857423397512495293688453655805536015029176541424005214818033707522950635262669828538132795615008381824067071229426026518897202246241637377064076189277685257166926338187911595052586669184297526234794666364657344206795357967279911782849686515024121916258300642000317525374433525235296287037535618423661645124459323811792936193272341688261801253469089129439519903538495370298752436267926761998785090092411372633429302950606054074205533246665546979112178855223925266166034953000200646676762301817000435641690517142795144469005596172113586738287118865058604922865654348297975054956781513943444060257230946224520058527667925776273088622386666860662470481606622952298649177217986593047495967209669116410592230626047083795555559776477430548946990993890380787911273437967786556742804566652408275798339221179283430482118140020742719695900657696142739101628984271513292954605191778803974738871043737934546460016184719168074062912083778327025499841998124431899131874519812228674255796948879306477894924710085384116453080236862135706628989104070747737689294987000148388110561753028594988959655591699155508380909698460304884908709246116411180876105681720036833487450945730831039969246996849503525429840196651386469599438064049723005123629385485140945945416764414133189625489032807860400751723995946290581976152580477047961138617997133510128194027510895265424780627975864980749945631413855375897945293107842908479797077570371447220506451229526132919408351287454305932886749170523056147842439813407002950370505941417426433452282518739345666494683448699945734453214481915512562995906034771246088038719298959180199052759295868161570318718927430655393250250811804905393113074074574608255523847592006804881016594060188745212933427473833239777228852952217878690668413947367586040297784502192683200664398064682201012931468052982448022330449955215606614483165425935154496289535573901139223034819824408001205784146243892228030383941863746839845526558421740316887532141893650230936137269356278754487130882868595412163277284772124736531380334814212708066069618080153747333573454834500999083737284449542481264971030785043701582134343596645346132964567391370300568578875509971483039720438955919863275044932311289587494336123538202079503922025306586828117649623642521324286648529829664567232756108169459356549144779085080036654897525078792273443307070502103724611233768453196294899770515940520895908289018412144327894912660060761908970811602375085884115384049610753387776858733798341463052471017393165656926510611173543365663267563198760597092606598728110197523695339144204179424646442294307593146446562536865057987897899655645968129515654148044008249646703504419478535298270862753806142083172190778193001810574370442181909146645889199829207284871551220439225371051511970054965951914399901815408791418836185742573331879114400013259342896515702942707292473805188905427717363630137869116872433627556880809120353079342030725196065815470427569172350436988386579444534375353968759750750178342190349607711313840613843718547859929387259163285524671855725511880656411741012446023392964655239624520090988149679656514996202498334816938716757663800773997302639681907686195671083505910700098597156238624351157219093280177066146218516478636356056420098245995113668018177690728654922707281126889313941750547830163078886329630807850633273613622550216189245162735650139455042125252043274668279981753287687674520319519360593091620297805736177366738063651905396783336064579717230286821545930579779462534206093794040878198825916141099864730374109311705285661056855668930671948265232862757146615431791375559792290479316263924560826544387396762768331402198937951439504767950821089741987629257538953417586416459087855138539304027013800937360598578194413362672871055543854633921502486683911956250444582746421552178164852341035733290405311280719066037175324627429434912416361334254696649419037348733709488576582107382055914938194078813926926742828297826939120316120573453588052056773875836843924877773978390546387248009519202370375478981843515393806263037580338009594022254079586380520797699651840576286033587273591899639699077044271208886940540056794360292760863657703246410020854088849880453524038877935317875884698324859548991680533307680053872403383516589028793015681082435908524045497475001609824047204954932626536311826911363867426654549346914317405110707189532251727848751560224936842128628673253616256326013555922159336370177663785738170802777550686079119049748734352584409583136667752555307842739679930698964098088960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)%bigQ
+.
+
+Fixpoint numden_Rcontfrac_tailrecB (accu: list bigZ) (n1 d1: bigZ) (n2 d2: bigZ) (fuel: nat) {struct fuel}:
+ (list bigZ * bigQ * bigQ) :=
+ let default := (rev_append accu nil, BigQ.div (BigQ.Qz n1) (BigQ.Qz d1), BigQ.div (BigQ.Qz n2) (BigQ.Qz d2)) in
+ match fuel with
+ | O => default
+ | S fuel' =>
+ let '(q1, r1) := BigZ.div_eucl n1 d1 in
+ let '(q2, r2) := BigZ.div_eucl n2 d2 in
+ match BigZ.eqb q1 q2 with
+ | false => default
+ | true =>
+ let r1_is_zero := BigZ.eqb r1 0 in
+ let r2_is_zero := BigZ.eqb r2 0 in
+ match Bool.eqb r1_is_zero r2_is_zero with
+ | false => default
+ | true =>
+ match r1_is_zero with
+ | true =>
+ match BigZ.eqb q1 1 with
+ | true => (rev_append accu nil, 1%bigQ, 1%bigQ)
+ | false => (rev_append ((q1 - 1)%bigZ :: accu) nil, 1%bigQ, 1%bigQ)
+ end
+ | false => numden_Rcontfrac_tailrecB (q1 :: accu) d1 r1 d2 r2 fuel'
+ end
+ end
+ end
+ end.
+
+Definition Bnum b :=
+ match b with
+ | BigQ.Qz t => t
+ | BigQ.Qq n d =>
+ if (d =? BigN.zero)%bigN then 0%bigZ else n
+ end.
+
+Definition Bden b :=
+ match b with
+ | BigQ.Qz _ => 1%bigN
+ | BigQ.Qq _ d => if (d =? BigN.zero)%bigN then 1%bigN else d
+ end.
+
+Definition rat_Rcontfrac_tailrecB q1 q2 :=
+ numden_Rcontfrac_tailrecB nil (Bnum q1) (BigZ.Pos (Bden q1)) (Bnum q2) (BigZ.Pos (Bden q2)).
+
+Definition pi_4_contfrac :=
+ rat_Rcontfrac_tailrecB pi_4_approx_low' pi_4_approx_high' 3000.
+
+(* The following used to fail because of a non canonical representation of 0 in
+the bytecode interpreter. Bug reported privately by Tahina Ramananandro. *)
+Goal pi_4_contfrac = pi_4_contfrac.
+vm_compute.
+reflexivity.
+Qed.
diff --git a/test-suite/success/cc.v b/test-suite/success/cc.v
index a70d91963..dc0527d82 100644
--- a/test-suite/success/cc.v
+++ b/test-suite/success/cc.v
@@ -129,5 +129,10 @@ Qed.
End bug_2447.
+(* congruence was supposed to do discriminate but it was bugged for
+ types with indices *)
-
+Inductive I : nat -> Type := C : I 0 | D : I 0.
+Goal ~C=D.
+congruence.
+Qed.
diff --git a/test-suite/success/coindprim.v b/test-suite/success/coindprim.v
index 4e0b7bf5c..5b9265b6a 100644
--- a/test-suite/success/coindprim.v
+++ b/test-suite/success/coindprim.v
@@ -1,36 +1,75 @@
+Require Import Program.
+
Set Primitive Projections.
-CoInductive stream A := { hd : A; tl : stream A }.
+CoInductive Stream (A : Type) := mkStream { hd : A; tl : Stream A}.
-CoFixpoint ticks : stream unit :=
- {| hd := tt; tl := ticks |}.
+Arguments mkStream [A] hd tl.
+Arguments hd [A] s.
+Arguments tl [A] s.
-Arguments hd [ A ] s.
-Arguments tl [ A ] s.
+Definition eta {A} (s : Stream A) := {| hd := s.(hd); tl := s.(tl) |}.
-CoInductive bisim {A} : stream A -> stream A -> Prop :=
- | bisims s s' : hd s = hd s' -> bisim (tl s) (tl s') -> bisim s s'.
+CoFixpoint ones := {| hd := 1; tl := ones |}.
+CoFixpoint ticks := {| hd := tt; tl := ticks |}.
-Lemma bisim_refl {A} (s : stream A) : bisim s s.
-Proof.
- revert s.
- cofix aux. intros. constructor. reflexivity. apply aux.
-Defined.
+CoInductive stream_equiv {A} {s : Stream A} {s' : Stream A} : Prop :=
+ mkStreamEq { hdeq : s.(hd) = s'.(hd); tleq : stream_equiv _ s.(tl) s'.(tl) }.
+Arguments stream_equiv {A} s s'.
-Lemma constr : forall (A : Type) (s : stream A),
- bisim s (Build_stream _ s.(hd) s.(tl)).
-Proof.
- intros. constructor. reflexivity. simpl. apply bisim_refl.
-Defined.
+Program CoFixpoint ones_eq : stream_equiv ones ones.(tl) :=
+ {| hdeq := eq_refl; tleq := ones_eq |}.
+
+CoFixpoint stream_equiv_refl {A} (s : Stream A) : stream_equiv s s :=
+ {| hdeq := eq_refl; tleq := stream_equiv_refl (tl s) |}.
+
+CoFixpoint stream_equiv_sym {A} (s s' : Stream A) (H : stream_equiv s s') : stream_equiv s' s :=
+ {| hdeq := eq_sym H.(hdeq); tleq := stream_equiv_sym _ _ H.(tleq) |}.
+
+CoFixpoint stream_equiv_trans {A} {s s' s'' : Stream A}
+ (H : stream_equiv s s') (H' : stream_equiv s' s'') : stream_equiv s s'' :=
+ {| hdeq := eq_trans H.(hdeq) H'.(hdeq);
+ tleq := stream_equiv_trans H.(tleq) H'.(tleq) |}.
-Lemma constr' : forall (A : Type) (s : stream A),
- s = Build_stream _ s.(hd) s.(tl).
+Program Definition eta_eq {A} (s : Stream A) : stream_equiv s (eta s):=
+ {| hdeq := eq_refl; tleq := stream_equiv_refl (tl (eta s))|}.
+
+Section Parks.
+ Variable A : Type.
+
+ Variable R : Stream A -> Stream A -> Prop.
+ Hypothesis bisim1 : forall s1 s2:Stream A,
+ R s1 s2 -> hd s1 = hd s2.
+ Hypothesis bisim2 : forall s1 s2:Stream A,
+ R s1 s2 -> R (tl s1) (tl s2).
+ CoFixpoint park_ppl :
+ forall s1 s2:Stream A, R s1 s2 -> stream_equiv s1 s2 :=
+ fun s1 s2 (p : R s1 s2) =>
+ mkStreamEq _ _ _ (bisim1 s1 s2 p)
+ (park_ppl (tl s1)
+ (tl s2)
+ (bisim2 s1 s2 p)).
+End Parks.
+
+Program CoFixpoint iterate {A} (f : A -> A) (x : A) : Stream A :=
+ {| hd := x; tl := iterate f (f x) |}.
+
+Program CoFixpoint map {A B} (f : A -> B) (s : Stream A) : Stream B :=
+ {| hd := f s.(hd); tl := map f s.(tl) |}.
+
+Theorem map_iterate A (f : A -> A) (x : A) : stream_equiv (iterate f (f x))
+ (map f (iterate f x)).
Proof.
- intros.
- Fail destruct s.
-Abort.
+apply park_ppl with
+(R:= fun s1 s2 => exists x : A, s1 = iterate f (f x) /\
+ s2 = map f (iterate f x)).
+now intros s1 s2 (x0,(->,->)).
+intros s1 s2 (x0,(->,->)).
+now exists (f x0).
+now exists x.
+Qed.
-Eval compute in constr _ ticks.
+Fail Check (fun A (s : Stream A) => eq_refl : s = eta s).
Notation convertible x y := (eq_refl x : x = y).
diff --git a/test-suite/success/keyedrewrite.v b/test-suite/success/keyedrewrite.v
index 5b0502cf1..b88c142be 100644
--- a/test-suite/success/keyedrewrite.v
+++ b/test-suite/success/keyedrewrite.v
@@ -58,4 +58,5 @@ Qed.
Lemma test b : b && true = b.
Fail rewrite andb_true_l.
- Admitted. \ No newline at end of file
+ Admitted.
+ \ No newline at end of file
diff --git a/test-suite/success/ltac.v b/test-suite/success/ltac.v
index 6c4d4ae98..ce9099059 100644
--- a/test-suite/success/ltac.v
+++ b/test-suite/success/ltac.v
@@ -15,7 +15,7 @@ Ltac F x := idtac; G x
with G y := idtac; F y.
(* Check that Match Context keeps a closure *)
-Ltac U := let a := constr:I in
+Ltac U := let a := constr:(I) in
match goal with
| |- _ => apply a
end.
@@ -75,7 +75,7 @@ Qed.
(* Check context binding *)
Ltac sym t :=
- match constr:t with
+ match constr:(t) with
| context C[(?X1 = ?X2)] => context C [X1 = X2]
end.
@@ -143,7 +143,7 @@ Qed.
Ltac check_binding y := cut ((fun y => y) = S).
Goal True.
-check_binding ipattern:H.
+check_binding ipattern:(H).
Abort.
(* Check that variables explicitly parsed as ltac variables are not
@@ -151,7 +151,7 @@ Abort.
Ltac afi tac := intros; tac.
Goal 1 = 2.
-afi ltac:auto.
+afi ltac:(auto).
Abort.
(* Tactic Notation avec listes *)
@@ -174,7 +174,7 @@ Abort.
empty args *)
Goal True.
-match constr:@None with @None => exact I end.
+match constr:(@None) with @None => exact I end.
Abort.
(* Check second-order pattern unification *)
@@ -218,7 +218,7 @@ Ltac Z1 t := set (x:=t).
Ltac Z2 t := t.
Goal True -> True.
Z1 O.
-Z2 ltac:O.
+Z2 ltac:(O).
exact I.
Qed.
@@ -302,7 +302,7 @@ Abort.
(* Check instantiation of binders using ltac names *)
Goal True.
-let x := ipattern:y in assert (forall x y, x = y + 0).
+let x := ipattern:(y) in assert (forall x y, x = y + 0).
intro.
destruct y. (* Check that the name is y here *)
Abort.
diff --git a/test-suite/success/ltacprof.v b/test-suite/success/ltacprof.v
new file mode 100644
index 000000000..d5552695c
--- /dev/null
+++ b/test-suite/success/ltacprof.v
@@ -0,0 +1,8 @@
+(** Some LtacProf tests *)
+
+Set Ltac Profiling.
+Ltac multi := (idtac + idtac).
+Goal True.
+ try (multi; fail). (* Used to result in: Anomaly: Uncaught exception Failure("hd"). Please report. *)
+Admitted.
+Show Ltac Profile.
diff --git a/test-suite/success/primitiveproj.v b/test-suite/success/primitiveproj.v
index 281d707cb..b5e6ccd61 100644
--- a/test-suite/success/primitiveproj.v
+++ b/test-suite/success/primitiveproj.v
@@ -35,10 +35,6 @@ Set Implicit Arguments.
Check nat.
-(* Inductive X (U:Type) := Foo (k : nat) (x : X U). *)
-(* Parameter x : X nat. *)
-(* Check x.(k). *)
-
Inductive X (U:Type) := { k : nat; a: k = k -> X U; b : let x := a eq_refl in X U }.
Parameter x:X nat.
@@ -49,18 +45,8 @@ Inductive Y := { next : option Y }.
Check _.(next) : option Y.
Lemma eta_ind (y : Y) : y = Build_Y y.(next).
-Proof. reflexivity. Defined.
-
-Variable t : Y.
-
-Fixpoint yn (n : nat) (y : Y) : Y :=
- match n with
- | 0 => t
- | S n => {| next := Some (yn n y) |}
- end.
+Proof. Fail reflexivity. Abort.
-Lemma eta_ind' (y: Y) : Some (yn 100 y) = Some {| next := (yn 100 y).(next) |}.
-Proof. reflexivity. Defined.
(*
diff --git a/test-suite/success/remember.v b/test-suite/success/remember.v
index 0befe054a..b26a9ff1e 100644
--- a/test-suite/success/remember.v
+++ b/test-suite/success/remember.v
@@ -14,3 +14,16 @@ let name := fresh "fresh" in
remember (1 + 2) as x eqn:name.
rewrite fresh.
Abort.
+
+(* An example which was working in 8.4 but failing in 8.5 and 8.5pl1 *)
+
+Module A.
+Axiom N : nat.
+End A.
+Module B.
+Include A.
+End B.
+Goal id A.N = B.N.
+reflexivity.
+Qed.
+
diff --git a/test-suite/success/setoid_test.v b/test-suite/success/setoid_test.v
index 0465c4b3f..1f24ef2a6 100644
--- a/test-suite/success/setoid_test.v
+++ b/test-suite/success/setoid_test.v
@@ -166,3 +166,16 @@ Proof. intros. setoid_rewrite <- foo_prf. change (beq_nat x 0 = y). Abort.
Goal forall (x : nat) (y : bool), beq_nat (foo_neg x) 0 = foo_neg y.
Proof. intros. setoid_rewrite <- @foo_prf at 1. change (beq_nat x 0 = foo_neg y). Abort.
+(* This should not raise an anomaly as it did for some time in early 2016 *)
+
+Definition t := nat -> bool.
+Definition h (a b : t) := forall n, a n = b n.
+
+Instance subrelh : subrelation h (Morphisms.pointwise_relation nat eq).
+Proof. intros x y H; assumption. Qed.
+
+Goal forall a b, h a b -> a 0 = b 0.
+intros.
+setoid_rewrite H. (* Fallback on ordinary rewrite without anomaly *)
+reflexivity.
+Qed.
diff --git a/test-suite/success/univers.v b/test-suite/success/univers.v
index e00701fb6..269359ae6 100644
--- a/test-suite/success/univers.v
+++ b/test-suite/success/univers.v
@@ -60,3 +60,20 @@ Qed.
(* Submitted by Danko Ilik (bug report #1507); related to LetIn *)
Record U : Type := { A:=Type; a:A }.
+
+(** Check assignement of sorts to inductives and records. *)
+
+Variable sh : list nat.
+
+Definition is_box_in_shape (b :nat * nat) := True.
+Definition myType := Type.
+
+Module Ind.
+Inductive box_in : myType :=
+ myBox (coord : nat * nat) (_ : is_box_in_shape coord) : box_in.
+End Ind.
+
+Module Rec.
+Record box_in : myType :=
+ BoxIn { coord :> nat * nat; _ : is_box_in_shape coord }.
+End Rec. \ No newline at end of file
diff --git a/test-suite/typeclasses/open_constr.v b/test-suite/typeclasses/open_constr.v
new file mode 100644
index 000000000..5f1785c70
--- /dev/null
+++ b/test-suite/typeclasses/open_constr.v
@@ -0,0 +1,12 @@
+Tactic Notation "opose" open_constr(foo) := pose foo.
+Class Foo := Build_Foo : Set.
+Axiom f : forall `{Foo}, Set.
+Set Printing Implicit.
+Goal forall `{Foo}, True.
+Proof.
+ intro H.
+ pose f.
+ opose f.
+ Fail let x := (eval hnf in P) in has_evar x.
+ let x := (eval hnf in P0) in has_evar x.
+
diff --git a/theories/Classes/CMorphisms.v b/theories/Classes/CMorphisms.v
index c41eb2fa2..1cfca4169 100644
--- a/theories/Classes/CMorphisms.v
+++ b/theories/Classes/CMorphisms.v
@@ -452,7 +452,7 @@ Ltac partial_application_tactic :=
let rec do_partial_apps H m cont :=
match m with
| ?m' ?x => class_apply @Reflexive_partial_app_morphism ;
- [(do_partial_apps H m' ltac:idtac)|clear H]
+ [(do_partial_apps H m' ltac:(idtac))|clear H]
| _ => cont
end
in
@@ -527,7 +527,7 @@ Hint Extern 7 (@Proper _ _ _) => proper_reflexive
Section Normalize.
Context (A : Type).
- Class Normalizes (m : crelation A) (m' : crelation A) : Prop :=
+ Class Normalizes (m : crelation A) (m' : crelation A) :=
normalizes : relation_equivalence m m'.
(** Current strategy: add [flip] everywhere and reduce using [subrelation]
diff --git a/theories/Classes/Morphisms.v b/theories/Classes/Morphisms.v
index 8d942d908..81b31d783 100644
--- a/theories/Classes/Morphisms.v
+++ b/theories/Classes/Morphisms.v
@@ -465,7 +465,7 @@ Ltac partial_application_tactic :=
let rec do_partial_apps H m cont :=
match m with
| ?m' ?x => class_apply @Reflexive_partial_app_morphism ;
- [(do_partial_apps H m' ltac:idtac)|clear H]
+ [(do_partial_apps H m' ltac:(idtac))|clear H]
| _ => cont
end
in
diff --git a/theories/Classes/SetoidTactics.v b/theories/Classes/SetoidTactics.v
index 145d451f0..190397ae4 100644
--- a/theories/Classes/SetoidTactics.v
+++ b/theories/Classes/SetoidTactics.v
@@ -77,23 +77,23 @@ Tactic Notation "setoid_replace" constr(x) "with" constr(y)
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"by" tactic3(t) :=
- setoidreplace (default_relation x y) ltac:t.
+ setoidreplace (default_relation x y) ltac:(t).
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"at" int_or_var_list(o)
"by" tactic3(t) :=
- setoidreplaceat (default_relation x y) ltac:t o.
+ setoidreplaceat (default_relation x y) ltac:(t) o.
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"in" hyp(id)
"by" tactic3(t) :=
- setoidreplacein (default_relation x y) id ltac:t.
+ setoidreplacein (default_relation x y) id ltac:(t).
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"in" hyp(id)
"at" int_or_var_list(o)
"by" tactic3(t) :=
- setoidreplaceinat (default_relation x y) id ltac:t o.
+ setoidreplaceinat (default_relation x y) id ltac:(t) o.
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"using" "relation" constr(rel) :=
@@ -107,13 +107,13 @@ Tactic Notation "setoid_replace" constr(x) "with" constr(y)
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"using" "relation" constr(rel)
"by" tactic3(t) :=
- setoidreplace (rel x y) ltac:t.
+ setoidreplace (rel x y) ltac:(t).
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"using" "relation" constr(rel)
"at" int_or_var_list(o)
"by" tactic3(t) :=
- setoidreplaceat (rel x y) ltac:t o.
+ setoidreplaceat (rel x y) ltac:(t) o.
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"using" "relation" constr(rel)
@@ -130,14 +130,14 @@ Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"using" "relation" constr(rel)
"in" hyp(id)
"by" tactic3(t) :=
- setoidreplacein (rel x y) id ltac:t.
+ setoidreplacein (rel x y) id ltac:(t).
Tactic Notation "setoid_replace" constr(x) "with" constr(y)
"using" "relation" constr(rel)
"in" hyp(id)
"at" int_or_var_list(o)
"by" tactic3(t) :=
- setoidreplaceinat (rel x y) id ltac:t o.
+ setoidreplaceinat (rel x y) id ltac:(t) o.
(** The [add_morphism_tactic] tactic is run at each [Add Morphism]
command before giving the hand back to the user to discharge the
diff --git a/theories/Compat/Coq84.v b/theories/Compat/Coq84.v
index 90083b00d..39bc59a65 100644
--- a/theories/Compat/Coq84.v
+++ b/theories/Compat/Coq84.v
@@ -7,6 +7,10 @@
(************************************************************************)
(** Compatibility file for making Coq act similar to Coq v8.4 *)
+
+(** Any compatibility changes to make future versions of Coq behave like Coq 8.5 are likely needed to make them behave like Coq 8.4. *)
+Require Export Coq.Compat.Coq85.
+
(** See https://coq.inria.fr/bugs/show_bug.cgi?id=4319 for updates *)
(** This is required in Coq 8.5 to use the [omega] tactic; in Coq 8.4, it's automatically available. But ZArith_base puts infix ~ at level 7, and we don't want that, so we don't [Import] it. *)
Require Coq.omega.Omega.
@@ -15,21 +19,28 @@ Ltac omega := Coq.omega.Omega.omega.
(** The number of arguments given in [match] statements has changed from 8.4 to 8.5. *)
Global Set Asymmetric Patterns.
+(** The automatic elimination schemes for records were dropped by default in 8.5. This restores the default behavior of Coq 8.4. *)
+Global Set Nonrecursive Elimination Schemes.
+
(** See bug 3545 *)
Global Set Universal Lemma Under Conjunction.
-(** In 8.5, [refine] leaves over dependent subgoals. *)
-Tactic Notation "refine" uconstr(term) := refine term; shelve_unifiable.
-
(** In 8.4, [constructor (tac)] allowed backtracking across the use of [constructor]; it has been subsumed by [constructor; tac]. *)
-Ltac constructor_84 := constructor.
Ltac constructor_84_n n := constructor n.
Ltac constructor_84_tac tac := once (constructor; tac).
-Tactic Notation "constructor" := constructor_84.
+Tactic Notation "constructor" := Coq.Init.Notations.constructor.
Tactic Notation "constructor" int_or_var(n) := constructor_84_n n.
Tactic Notation "constructor" "(" tactic(tac) ")" := constructor_84_tac tac.
+(** In 8.4, [econstructor (tac)] allowed backtracking across the use of [econstructor]; it has been subsumed by [econstructor; tac]. *)
+Ltac econstructor_84_n n := econstructor n.
+Ltac econstructor_84_tac tac := once (econstructor; tac).
+
+Tactic Notation "econstructor" := Coq.Init.Notations.econstructor.
+Tactic Notation "econstructor" int_or_var(n) := econstructor_84_n n.
+Tactic Notation "econstructor" "(" tactic(tac) ")" := econstructor_84_tac tac.
+
(** Some tactic notations do not factor well with tactics; we add global parsing entries for some tactics that would otherwise be overwritten by custom variants. See https://coq.inria.fr/bugs/show_bug.cgi?id=4392. *)
Tactic Notation "reflexivity" := reflexivity.
Tactic Notation "assumption" := assumption.
@@ -45,29 +56,17 @@ Tactic Notation "left" := left.
Tactic Notation "eleft" := eleft.
Tactic Notation "right" := right.
Tactic Notation "eright" := eright.
-Tactic Notation "constructor" := constructor.
-Tactic Notation "econstructor" := econstructor.
Tactic Notation "symmetry" := symmetry.
Tactic Notation "split" := split.
Tactic Notation "esplit" := esplit.
-Global Set Regular Subst Tactic.
-
-(** Some names have changed in the standard library, so we add aliases. *)
-Require Coq.ZArith.Int.
-Module Export Coq.
- Module Export ZArith.
- Module Int.
- Module Z_as_Int.
- Include Coq.ZArith.Int.Z_as_Int.
- (* FIXME: Should these get a (compat "8.4")? Or be moved to Z_as_Int, probably? *)
- Notation plus := Coq.ZArith.Int.Z_as_Int.add (only parsing).
- Notation minus := Coq.ZArith.Int.Z_as_Int.sub (only parsing).
- Notation mult := Coq.ZArith.Int.Z_as_Int.mul (only parsing).
- End Z_as_Int.
- End Int.
- End ZArith.
-End Coq.
-
(** Many things now import [PeanoNat] rather than [NPeano], so we require it so that the old absolute names in [NPeano.Nat] are available. *)
Require Coq.Numbers.Natural.Peano.NPeano.
+
+(** The following coercions were declared by default in Specif.v. *)
+Coercion sig_of_sig2 : sig2 >-> sig.
+Coercion sigT_of_sigT2 : sigT2 >-> sigT.
+Coercion sigT_of_sig : sig >-> sigT.
+Coercion sig_of_sigT : sigT >-> sig.
+Coercion sigT2_of_sig2 : sig2 >-> sigT2.
+Coercion sig2_of_sigT2 : sigT2 >-> sig2.
diff --git a/theories/Compat/Coq85.v b/theories/Compat/Coq85.v
index af2e04f88..3fc74943e 100644
--- a/theories/Compat/Coq85.v
+++ b/theories/Compat/Coq85.v
@@ -12,5 +12,5 @@
behave as "intros [H|H]" but leave instead hypotheses quantified in
the goal, here producing subgoals A->C and B->C. *)
-Unset Bracketing Last Introduction Pattern.
-
+Global Unset Bracketing Last Introduction Pattern.
+Global Unset Regular Subst Tactic.
diff --git a/theories/Init/Notations.v b/theories/Init/Notations.v
index 55eb699be..48fbe0793 100644
--- a/theories/Init/Notations.v
+++ b/theories/Init/Notations.v
@@ -76,9 +76,14 @@ Reserved Notation "{ x : A & P }" (at level 0, x at level 99).
Reserved Notation "{ x : A & P & Q }" (at level 0, x at level 99).
Delimit Scope type_scope with type.
+Delimit Scope function_scope with function.
Delimit Scope core_scope with core.
+Bind Scope type_scope with Sortclass.
+Bind Scope function_scope with Funclass.
+
Open Scope core_scope.
+Open Scope function_scope.
Open Scope type_scope.
(** ML Tactic Notations *)
@@ -86,7 +91,6 @@ Open Scope type_scope.
Declare ML Module "coretactics".
Declare ML Module "extratactics".
Declare ML Module "g_auto".
-Declare ML Module "eauto".
Declare ML Module "g_class".
Declare ML Module "g_eqdecide".
Declare ML Module "g_rewrite".
diff --git a/theories/MSets/MSetAVL.v b/theories/MSets/MSetAVL.v
index cc023cc3f..a3c265a21 100644
--- a/theories/MSets/MSetAVL.v
+++ b/theories/MSets/MSetAVL.v
@@ -417,6 +417,7 @@ Local Open Scope Int_scope.
Let's do its job by hand: *)
Ltac join_tac :=
+ let l := fresh "l" in
intro l; induction l as [| lh ll _ lx lr Hlr];
[ | intros x r; induction r as [| rh rl Hrl rx rr _]; unfold join;
[ | destruct ((rh+2) <? lh) eqn:LT;
diff --git a/theories/Numbers/Cyclic/Int31/Ring31.v b/theories/Numbers/Cyclic/Int31/Ring31.v
index 215b8bd58..d160f5f1d 100644
--- a/theories/Numbers/Cyclic/Int31/Ring31.v
+++ b/theories/Numbers/Cyclic/Int31/Ring31.v
@@ -19,13 +19,13 @@ Local Open Scope list_scope.
Ltac isInt31cst_lst l :=
match l with
- | nil => constr:true
+ | nil => constr:(true)
| ?t::?l => match t with
| D1 => isInt31cst_lst l
| D0 => isInt31cst_lst l
- | _ => constr:false
+ | _ => constr:(false)
end
- | _ => constr:false
+ | _ => constr:(false)
end.
Ltac isInt31cst t :=
@@ -38,17 +38,17 @@ Ltac isInt31cst t :=
::i11::i12::i13::i14::i15::i16::i17::i18::i19::i20
::i21::i22::i23::i24::i25::i26::i27::i28::i29::i30::nil)
in isInt31cst_lst l
- | Int31.On => constr:true
- | Int31.In => constr:true
- | Int31.Tn => constr:true
- | Int31.Twon => constr:true
- | _ => constr:false
+ | Int31.On => constr:(true)
+ | Int31.In => constr:(true)
+ | Int31.Tn => constr:(true)
+ | Int31.Twon => constr:(true)
+ | _ => constr:(false)
end.
Ltac Int31cst t :=
match isInt31cst t with
- | true => constr:t
- | false => constr:NotConstant
+ | true => constr:(t)
+ | false => constr:(NotConstant)
end.
(** The generic ring structure inferred from the Cyclic structure *)
diff --git a/theories/Numbers/Integer/BigZ/BigZ.v b/theories/Numbers/Integer/BigZ/BigZ.v
index ec495d094..56cb9bbc2 100644
--- a/theories/Numbers/Integer/BigZ/BigZ.v
+++ b/theories/Numbers/Integer/BigZ/BigZ.v
@@ -148,26 +148,26 @@ Ltac isBigZcst t :=
match t with
| BigZ.Pos ?t => isBigNcst t
| BigZ.Neg ?t => isBigNcst t
- | BigZ.zero => constr:true
- | BigZ.one => constr:true
- | BigZ.two => constr:true
- | BigZ.minus_one => constr:true
- | _ => constr:false
+ | BigZ.zero => constr:(true)
+ | BigZ.one => constr:(true)
+ | BigZ.two => constr:(true)
+ | BigZ.minus_one => constr:(true)
+ | _ => constr:(false)
end.
Ltac BigZcst t :=
match isBigZcst t with
- | true => constr:t
- | false => constr:NotConstant
+ | true => constr:(t)
+ | false => constr:(NotConstant)
end.
Ltac BigZ_to_N t :=
match t with
| BigZ.Pos ?t => BigN_to_N t
- | BigZ.zero => constr:0%N
- | BigZ.one => constr:1%N
- | BigZ.two => constr:2%N
- | _ => constr:NotConstant
+ | BigZ.zero => constr:(0%N)
+ | BigZ.one => constr:(1%N)
+ | BigZ.two => constr:(2%N)
+ | _ => constr:(NotConstant)
end.
(** Registration for the "ring" tactic *)
diff --git a/theories/Numbers/Natural/BigN/BigN.v b/theories/Numbers/Natural/BigN/BigN.v
index 29a1145e0..ec1017f50 100644
--- a/theories/Numbers/Natural/BigN/BigN.v
+++ b/theories/Numbers/Natural/BigN/BigN.v
@@ -119,10 +119,10 @@ Qed.
Ltac isStaticWordCst t :=
match t with
- | W0 => constr:true
+ | W0 => constr:(true)
| WW ?t1 ?t2 =>
match isStaticWordCst t1 with
- | false => constr:false
+ | false => constr:(false)
| true => isStaticWordCst t2
end
| _ => isInt31cst t
@@ -139,30 +139,30 @@ Ltac isBigNcst t :=
| BigN.N6 ?t => isStaticWordCst t
| BigN.Nn ?n ?t => match isnatcst n with
| true => isStaticWordCst t
- | false => constr:false
+ | false => constr:(false)
end
- | BigN.zero => constr:true
- | BigN.one => constr:true
- | BigN.two => constr:true
- | _ => constr:false
+ | BigN.zero => constr:(true)
+ | BigN.one => constr:(true)
+ | BigN.two => constr:(true)
+ | _ => constr:(false)
end.
Ltac BigNcst t :=
match isBigNcst t with
- | true => constr:t
- | false => constr:NotConstant
+ | true => constr:(t)
+ | false => constr:(NotConstant)
end.
Ltac BigN_to_N t :=
match isBigNcst t with
| true => eval vm_compute in (BigN.to_N t)
- | false => constr:NotConstant
+ | false => constr:(NotConstant)
end.
Ltac Ncst t :=
match isNcst t with
- | true => constr:t
- | false => constr:NotConstant
+ | true => constr:(t)
+ | false => constr:(NotConstant)
end.
(** Registration for the "ring" tactic *)
diff --git a/theories/Numbers/Natural/Peano/NPeano.v b/theories/Numbers/Natural/Peano/NPeano.v
index 58b1b0180..d0168bd9e 100644
--- a/theories/Numbers/Natural/Peano/NPeano.v
+++ b/theories/Numbers/Natural/Peano/NPeano.v
@@ -8,8 +8,88 @@
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
-Require Import PeanoNat NAxioms.
+Require Import PeanoNat Even NAxioms.
-(** * [PeanoNat.Nat] already implements [NAxiomSig] *)
+(** This file is DEPRECATED ! Use [PeanoNat] (or [Arith]) instead. *)
+
+(** [PeanoNat.Nat] already implements [NAxiomSig] *)
Module Nat <: NAxiomsSig := Nat.
+
+(** Compat notations for stuff that used to be at the beginning of NPeano. *)
+
+Notation leb := Nat.leb (compat "8.4").
+Notation ltb := Nat.ltb (compat "8.4").
+Notation leb_le := Nat.leb_le (compat "8.4").
+Notation ltb_lt := Nat.ltb_lt (compat "8.4").
+Notation pow := Nat.pow (compat "8.4").
+Notation pow_0_r := Nat.pow_0_r (compat "8.4").
+Notation pow_succ_r := Nat.pow_succ_r (compat "8.4").
+Notation square := Nat.square (compat "8.4").
+Notation square_spec := Nat.square_spec (compat "8.4").
+Notation Even := Nat.Even (compat "8.4").
+Notation Odd := Nat.Odd (compat "8.4").
+Notation even := Nat.even (compat "8.4").
+Notation odd := Nat.odd (compat "8.4").
+Notation even_spec := Nat.even_spec (compat "8.4").
+Notation odd_spec := Nat.odd_spec (compat "8.4").
+
+Lemma Even_equiv n : Even n <-> Even.even n.
+Proof. symmetry. apply Even.even_equiv. Qed.
+Lemma Odd_equiv n : Odd n <-> Even.odd n.
+Proof. symmetry. apply Even.odd_equiv. Qed.
+
+Notation divmod := Nat.divmod (compat "8.4").
+Notation div := Nat.div (compat "8.4").
+Notation modulo := Nat.modulo (compat "8.4").
+Notation divmod_spec := Nat.divmod_spec (compat "8.4").
+Notation div_mod := Nat.div_mod (compat "8.4").
+Notation mod_bound_pos := Nat.mod_bound_pos (compat "8.4").
+Notation sqrt_iter := Nat.sqrt_iter (compat "8.4").
+Notation sqrt := Nat.sqrt (compat "8.4").
+Notation sqrt_iter_spec := Nat.sqrt_iter_spec (compat "8.4").
+Notation sqrt_spec := Nat.sqrt_spec (compat "8.4").
+Notation log2_iter := Nat.log2_iter (compat "8.4").
+Notation log2 := Nat.log2 (compat "8.4").
+Notation log2_iter_spec := Nat.log2_iter_spec (compat "8.4").
+Notation log2_spec := Nat.log2_spec (compat "8.4").
+Notation log2_nonpos := Nat.log2_nonpos (compat "8.4").
+Notation gcd := Nat.gcd (compat "8.4").
+Notation divide := Nat.divide (compat "8.4").
+Notation gcd_divide := Nat.gcd_divide (compat "8.4").
+Notation gcd_divide_l := Nat.gcd_divide_l (compat "8.4").
+Notation gcd_divide_r := Nat.gcd_divide_r (compat "8.4").
+Notation gcd_greatest := Nat.gcd_greatest (compat "8.4").
+Notation testbit := Nat.testbit (compat "8.4").
+Notation shiftl := Nat.shiftl (compat "8.4").
+Notation shiftr := Nat.shiftr (compat "8.4").
+Notation bitwise := Nat.bitwise (compat "8.4").
+Notation land := Nat.land (compat "8.4").
+Notation lor := Nat.lor (compat "8.4").
+Notation ldiff := Nat.ldiff (compat "8.4").
+Notation lxor := Nat.lxor (compat "8.4").
+Notation double_twice := Nat.double_twice (compat "8.4").
+Notation testbit_0_l := Nat.testbit_0_l (compat "8.4").
+Notation testbit_odd_0 := Nat.testbit_odd_0 (compat "8.4").
+Notation testbit_even_0 := Nat.testbit_even_0 (compat "8.4").
+Notation testbit_odd_succ := Nat.testbit_odd_succ (compat "8.4").
+Notation testbit_even_succ := Nat.testbit_even_succ (compat "8.4").
+Notation shiftr_spec := Nat.shiftr_spec (compat "8.4").
+Notation shiftl_spec_high := Nat.shiftl_spec_high (compat "8.4").
+Notation shiftl_spec_low := Nat.shiftl_spec_low (compat "8.4").
+Notation div2_bitwise := Nat.div2_bitwise (compat "8.4").
+Notation odd_bitwise := Nat.odd_bitwise (compat "8.4").
+Notation div2_decr := Nat.div2_decr (compat "8.4").
+Notation testbit_bitwise_1 := Nat.testbit_bitwise_1 (compat "8.4").
+Notation testbit_bitwise_2 := Nat.testbit_bitwise_2 (compat "8.4").
+Notation land_spec := Nat.land_spec (compat "8.4").
+Notation ldiff_spec := Nat.ldiff_spec (compat "8.4").
+Notation lor_spec := Nat.lor_spec (compat "8.4").
+Notation lxor_spec := Nat.lxor_spec (compat "8.4").
+
+Infix "<=?" := Nat.leb (at level 70) : nat_scope.
+Infix "<?" := Nat.ltb (at level 70) : nat_scope.
+Infix "^" := Nat.pow : nat_scope.
+Infix "/" := Nat.div : nat_scope.
+Infix "mod" := Nat.modulo (at level 40, no associativity) : nat_scope.
+Notation "( x | y )" := (Nat.divide x y) (at level 0) : nat_scope.
diff --git a/theories/Numbers/Rational/BigQ/BigQ.v b/theories/Numbers/Rational/BigQ/BigQ.v
index fe38ea4f2..850afe534 100644
--- a/theories/Numbers/Rational/BigQ/BigQ.v
+++ b/theories/Numbers/Rational/BigQ/BigQ.v
@@ -104,18 +104,18 @@ Ltac isBigQcst t :=
| BigQ.Qz ?t => isBigZcst t
| BigQ.Qq ?n ?d => match isBigZcst n with
| true => isBigNcst d
- | false => constr:false
+ | false => constr:(false)
end
- | BigQ.zero => constr:true
- | BigQ.one => constr:true
- | BigQ.minus_one => constr:true
- | _ => constr:false
+ | BigQ.zero => constr:(true)
+ | BigQ.one => constr:(true)
+ | BigQ.minus_one => constr:(true)
+ | _ => constr:(false)
end.
Ltac BigQcst t :=
match isBigQcst t with
- | true => constr:t
- | false => constr:NotConstant
+ | true => constr:(t)
+ | false => constr:(NotConstant)
end.
Add Field BigQfield : BigQfieldth
diff --git a/theories/Program/Equality.v b/theories/Program/Equality.v
index 27e1ca844..17f05c511 100644
--- a/theories/Program/Equality.v
+++ b/theories/Program/Equality.v
@@ -238,8 +238,8 @@ Ltac inject_left H :=
Ltac inject_right H :=
progress (inversion H ; subst_right_no_fail ; clear_dups) ; clear H.
-Ltac autoinjections_left := repeat autoinjection ltac:inject_left.
-Ltac autoinjections_right := repeat autoinjection ltac:inject_right.
+Ltac autoinjections_left := repeat autoinjection ltac:(inject_left).
+Ltac autoinjections_right := repeat autoinjection ltac:(inject_right).
Ltac simpl_depind := subst_no_fail ; autoinjections ; try discriminates ;
simpl_JMeq ; simpl_existTs ; simplify_IH_hyps.
diff --git a/theories/Program/Tactics.v b/theories/Program/Tactics.v
index 66ca3e577..7384790da 100644
--- a/theories/Program/Tactics.v
+++ b/theories/Program/Tactics.v
@@ -252,7 +252,7 @@ Ltac autoinjection tac :=
Ltac inject H := progress (inversion H ; subst*; clear_dups) ; clear H.
-Ltac autoinjections := repeat (clear_dups ; autoinjection ltac:inject).
+Ltac autoinjections := repeat (clear_dups ; autoinjection ltac:(inject)).
(** Destruct an hypothesis by first copying it to avoid dependencies. *)
diff --git a/theories/Reals/Ranalysis_reg.v b/theories/Reals/Ranalysis_reg.v
index 2465f0399..0c27d407c 100644
--- a/theories/Reals/Ranalysis_reg.v
+++ b/theories/Reals/Ranalysis_reg.v
@@ -35,7 +35,7 @@ Qed.
(**********)
Ltac intro_hyp_glob trm :=
- match constr:trm with
+ match constr:(trm) with
| (?X1 + ?X2)%F =>
match goal with
| |- (derivable _) => intro_hyp_glob X1; intro_hyp_glob X2
@@ -55,7 +55,7 @@ Ltac intro_hyp_glob trm :=
| _ => idtac
end
| (?X1 / ?X2)%F =>
- let aux := constr:X2 in
+ let aux := constr:(X2) in
match goal with
| _:(forall x0:R, aux x0 <> 0) |- (derivable _) =>
intro_hyp_glob X1; intro_hyp_glob X2
@@ -82,7 +82,7 @@ Ltac intro_hyp_glob trm :=
| _ => idtac
end
| (/ ?X1)%F =>
- let aux := constr:X1 in
+ let aux := constr:(X1) in
match goal with
| _:(forall x0:R, aux x0 <> 0) |- (derivable _) =>
intro_hyp_glob X1
@@ -108,7 +108,8 @@ Ltac intro_hyp_glob trm :=
| (pow_fct _) => idtac
| Rabs => idtac
| ?X1 =>
- let p := constr:X1 in
+ let p := constr:(X1) in
+ let HYPPD := fresh "HYPPD" in
match goal with
| _:(derivable p) |- _ => idtac
| |- (derivable p) => idtac
@@ -130,7 +131,7 @@ Ltac intro_hyp_glob trm :=
(**********)
Ltac intro_hyp_pt trm pt :=
- match constr:trm with
+ match constr:(trm) with
| (?X1 + ?X2)%F =>
match goal with
| |- (derivable_pt _ _) => intro_hyp_pt X1 pt; intro_hyp_pt X2 pt
@@ -156,7 +157,7 @@ Ltac intro_hyp_pt trm pt :=
| _ => idtac
end
| (?X1 / ?X2)%F =>
- let aux := constr:X2 in
+ let aux := constr:(X2) in
match goal with
| _:(aux pt <> 0) |- (derivable_pt _ _) =>
intro_hyp_pt X1 pt; intro_hyp_pt X2 pt
@@ -202,7 +203,7 @@ Ltac intro_hyp_pt trm pt :=
| _ => idtac
end
| (/ ?X1)%F =>
- let aux := constr:X1 in
+ let aux := constr:(X1) in
match goal with
| _:(aux pt <> 0) |- (derivable_pt _ _) =>
intro_hyp_pt X1 pt
@@ -249,7 +250,8 @@ Ltac intro_hyp_pt trm pt :=
| _ => idtac
end
| ?X1 =>
- let p := constr:X1 in
+ let p := constr:(X1) in
+ let HYPPD := fresh "HYPPD" in
match goal with
| _:(derivable_pt p pt) |- _ => idtac
| |- (derivable_pt p pt) => idtac
@@ -341,8 +343,10 @@ Ltac is_diff_pt :=
| _:(derivable_pt ?X1 ?X2) |- (derivable_pt ?X1 ?X2) =>
assumption
| _:(derivable ?X1) |- (derivable_pt ?X1 ?X2) =>
+ let HypDDPT := fresh "HypDDPT" in
cut (derivable X1); [ intro HypDDPT; apply HypDDPT | assumption ]
| |- (True -> derivable_pt _ _) =>
+ let HypTruE := fresh "HypTruE" in
intro HypTruE; clear HypTruE; is_diff_pt
| _ =>
try
@@ -411,6 +415,7 @@ Ltac is_diff_glob :=
apply (derivable_comp X2 X1); is_diff_glob
| _:(derivable ?X1) |- (derivable ?X1) => assumption
| |- (True -> derivable _) =>
+ let HypTruE := fresh "HypTruE" in
intro HypTruE; clear HypTruE; is_diff_glob
| _ =>
try
@@ -490,14 +495,17 @@ Ltac is_cont_pt :=
| _:(continuity_pt ?X1 ?X2) |- (continuity_pt ?X1 ?X2) =>
assumption
| _:(continuity ?X1) |- (continuity_pt ?X1 ?X2) =>
+ let HypDDPT := fresh "HypDDPT" in
cut (continuity X1); [ intro HypDDPT; apply HypDDPT | assumption ]
| _:(derivable_pt ?X1 ?X2) |- (continuity_pt ?X1 ?X2) =>
apply derivable_continuous_pt; assumption
| _:(derivable ?X1) |- (continuity_pt ?X1 ?X2) =>
+ let HypDDPT := fresh "HypDDPT" in
cut (continuity X1);
[ intro HypDDPT; apply HypDDPT
| apply derivable_continuous; assumption ]
| |- (True -> continuity_pt _ _) =>
+ let HypTruE := fresh "HypTruE" in
intro HypTruE; clear HypTruE; is_cont_pt
| _ =>
try
@@ -567,6 +575,7 @@ Ltac is_cont_glob :=
apply (continuity_comp X2 X1); try is_cont_glob || assumption
| _:(continuity ?X1) |- (continuity ?X1) => assumption
| |- (True -> continuity _) =>
+ let HypTruE := fresh "HypTruE" in
intro HypTruE; clear HypTruE; is_cont_glob
| _:(derivable ?X1) |- (continuity ?X1) =>
apply derivable_continuous; assumption
@@ -578,89 +587,89 @@ Ltac is_cont_glob :=
(**********)
Ltac rew_term trm :=
- match constr:trm with
+ match constr:(trm) with
| (?X1 + ?X2) =>
let p1 := rew_term X1 with p2 := rew_term X2 in
- match constr:p1 with
+ match constr:(p1) with
| (fct_cte ?X3) =>
- match constr:p2 with
+ match constr:(p2) with
| (fct_cte ?X4) => constr:(fct_cte (X3 + X4))
- | _ => constr:(p1 + p2)%F
+ | _ => constr:((p1 + p2)%F)
end
- | _ => constr:(p1 + p2)%F
+ | _ => constr:((p1 + p2)%F)
end
| (?X1 - ?X2) =>
let p1 := rew_term X1 with p2 := rew_term X2 in
- match constr:p1 with
+ match constr:(p1) with
| (fct_cte ?X3) =>
- match constr:p2 with
+ match constr:(p2) with
| (fct_cte ?X4) => constr:(fct_cte (X3 - X4))
- | _ => constr:(p1 - p2)%F
+ | _ => constr:((p1 - p2)%F)
end
- | _ => constr:(p1 - p2)%F
+ | _ => constr:((p1 - p2)%F)
end
| (?X1 / ?X2) =>
let p1 := rew_term X1 with p2 := rew_term X2 in
- match constr:p1 with
+ match constr:(p1) with
| (fct_cte ?X3) =>
- match constr:p2 with
+ match constr:(p2) with
| (fct_cte ?X4) => constr:(fct_cte (X3 / X4))
- | _ => constr:(p1 / p2)%F
+ | _ => constr:((p1 / p2)%F)
end
| _ =>
- match constr:p2 with
- | (fct_cte ?X4) => constr:(p1 * fct_cte (/ X4))%F
- | _ => constr:(p1 / p2)%F
+ match constr:(p2) with
+ | (fct_cte ?X4) => constr:((p1 * fct_cte (/ X4))%F)
+ | _ => constr:((p1 / p2)%F)
end
end
| (?X1 * / ?X2) =>
let p1 := rew_term X1 with p2 := rew_term X2 in
- match constr:p1 with
+ match constr:(p1) with
| (fct_cte ?X3) =>
- match constr:p2 with
+ match constr:(p2) with
| (fct_cte ?X4) => constr:(fct_cte (X3 / X4))
- | _ => constr:(p1 / p2)%F
+ | _ => constr:((p1 / p2)%F)
end
| _ =>
- match constr:p2 with
- | (fct_cte ?X4) => constr:(p1 * fct_cte (/ X4))%F
- | _ => constr:(p1 / p2)%F
+ match constr:(p2) with
+ | (fct_cte ?X4) => constr:((p1 * fct_cte (/ X4))%F)
+ | _ => constr:((p1 / p2)%F)
end
end
| (?X1 * ?X2) =>
let p1 := rew_term X1 with p2 := rew_term X2 in
- match constr:p1 with
+ match constr:(p1) with
| (fct_cte ?X3) =>
- match constr:p2 with
+ match constr:(p2) with
| (fct_cte ?X4) => constr:(fct_cte (X3 * X4))
- | _ => constr:(p1 * p2)%F
+ | _ => constr:((p1 * p2)%F)
end
- | _ => constr:(p1 * p2)%F
+ | _ => constr:((p1 * p2)%F)
end
| (- ?X1) =>
let p := rew_term X1 in
- match constr:p with
+ match constr:(p) with
| (fct_cte ?X2) => constr:(fct_cte (- X2))
- | _ => constr:(- p)%F
+ | _ => constr:((- p)%F)
end
| (/ ?X1) =>
let p := rew_term X1 in
- match constr:p with
+ match constr:(p) with
| (fct_cte ?X2) => constr:(fct_cte (/ X2))
- | _ => constr:(/ p)%F
+ | _ => constr:((/ p)%F)
end
- | (?X1 AppVar) => constr:X1
+ | (?X1 AppVar) => constr:(X1)
| (?X1 ?X2) =>
let p := rew_term X2 in
- match constr:p with
+ match constr:(p) with
| (fct_cte ?X3) => constr:(fct_cte (X1 X3))
| _ => constr:(comp X1 p)
end
- | AppVar => constr:id
+ | AppVar => constr:(id)
| (AppVar ^ ?X1) => constr:(pow_fct X1)
| (?X1 ^ ?X2) =>
let p := rew_term X1 in
- match constr:p with
+ match constr:(p) with
| (fct_cte ?X3) => constr:(fct_cte (pow_fct X2 X3))
| _ => constr:(comp (pow_fct X2) p)
end
@@ -669,7 +678,7 @@ Ltac rew_term trm :=
(**********)
Ltac deriv_proof trm pt :=
- match constr:trm with
+ match constr:(trm) with
| (?X1 + ?X2)%F =>
let p1 := deriv_proof X1 pt with p2 := deriv_proof X2 pt in
constr:(derivable_pt_plus X1 X2 pt p1 p2)
@@ -684,14 +693,14 @@ Ltac deriv_proof trm pt :=
| id:(?X2 pt <> 0) |- _ =>
let p1 := deriv_proof X1 pt with p2 := deriv_proof X2 pt in
constr:(derivable_pt_div X1 X2 pt p1 p2 id)
- | _ => constr:False
+ | _ => constr:(False)
end
| (/ ?X1)%F =>
match goal with
| id:(?X1 pt <> 0) |- _ =>
let p1 := deriv_proof X1 pt in
constr:(derivable_pt_inv X1 pt p1 id)
- | _ => constr:False
+ | _ => constr:(False)
end
| (comp ?X1 ?X2) =>
let pt_f1 := eval cbv beta in (X2 pt) in
@@ -710,21 +719,21 @@ Ltac deriv_proof trm pt :=
| sqrt =>
match goal with
| id:(0 < pt) |- _ => constr:(derivable_pt_sqrt pt id)
- | _ => constr:False
+ | _ => constr:(False)
end
| (fct_cte ?X1) => constr:(derivable_pt_const X1 pt)
| ?X1 =>
- let aux := constr:X1 in
+ let aux := constr:(X1) in
match goal with
- | id:(derivable_pt aux pt) |- _ => constr:id
+ | id:(derivable_pt aux pt) |- _ => constr:(id)
| id:(derivable aux) |- _ => constr:(id pt)
- | _ => constr:False
+ | _ => constr:(False)
end
end.
(**********)
Ltac simplify_derive trm pt :=
- match constr:trm with
+ match constr:(trm) with
| (?X1 + ?X2)%F =>
try rewrite derive_pt_plus; simplify_derive X1 pt;
simplify_derive X2 pt
@@ -753,7 +762,7 @@ Ltac simplify_derive trm pt :=
| Rsqr => try rewrite derive_pt_Rsqr
| sqrt => try rewrite derive_pt_sqrt
| ?X1 =>
- let aux := constr:X1 in
+ let aux := constr:(X1) in
match goal with
| id:(derive_pt aux pt ?X2 = _),H:(derivable aux) |- _ =>
try replace (derive_pt aux pt (H pt)) with (derive_pt aux pt X2);
diff --git a/theories/Vectors/VectorDef.v b/theories/Vectors/VectorDef.v
index 45c13e5ce..c69223804 100644
--- a/theories/Vectors/VectorDef.v
+++ b/theories/Vectors/VectorDef.v
@@ -297,7 +297,7 @@ Notation "[]" := [] : vector_scope.
Notation "h :: t" := (h :: t) (at level 60, right associativity)
: vector_scope.
Notation " [ x ] " := (x :: []) : vector_scope.
-Notation " [ x ; .. ; y ] " := (cons _ x _ .. (cons _ y _ (nil _)) ..) : vector_scope
+Notation " [ x ; y ; .. ; z ] " := (cons _ x _ (cons _ y _ .. (cons _ z _ (nil _)) ..)) : vector_scope
.
Notation "v [@ p ]" := (nth v p) (at level 1, format "v [@ p ]") : vector_scope.
Open Scope vector_scope.
diff --git a/theories/ZArith/Int.v b/theories/ZArith/Int.v
index d210792f9..72021f2e4 100644
--- a/theories/ZArith/Int.v
+++ b/theories/ZArith/Int.v
@@ -225,11 +225,11 @@ Module MoreInt (Import I:Int).
(** [int] to [ExprI] *)
Ltac i2ei trm :=
- match constr:trm with
- | 0 => constr:EI0
- | 1 => constr:EI1
- | 2 => constr:EI2
- | 3 => constr:EI3
+ match constr:(trm) with
+ | 0 => constr:(EI0)
+ | 1 => constr:(EI1)
+ | 2 => constr:(EI2)
+ | 3 => constr:(EI3)
| ?x + ?y => let ex := i2ei x with ey := i2ei y in constr:(EIadd ex ey)
| ?x - ?y => let ex := i2ei x with ey := i2ei y in constr:(EIsub ex ey)
| ?x * ?y => let ex := i2ei x with ey := i2ei y in constr:(EImul ex ey)
@@ -241,7 +241,7 @@ Module MoreInt (Import I:Int).
(** [Z] to [ExprZ] *)
with z2ez trm :=
- match constr:trm with
+ match constr:(trm) with
| (?x + ?y)%Z => let ex := z2ez x with ey := z2ez y in constr:(EZadd ex ey)
| (?x - ?y)%Z => let ex := z2ez x with ey := z2ez y in constr:(EZsub ex ey)
| (?x * ?y)%Z => let ex := z2ez x with ey := z2ez y in constr:(EZmul ex ey)
@@ -254,7 +254,7 @@ Module MoreInt (Import I:Int).
(** [Prop] to [ExprP] *)
Ltac p2ep trm :=
- match constr:trm with
+ match constr:(trm) with
| (?x <-> ?y) => let ex := p2ep x with ey := p2ep y in constr:(EPequiv ex ey)
| (?x -> ?y) => let ex := p2ep x with ey := p2ep y in constr:(EPimpl ex ey)
| (?x /\ ?y) => let ex := p2ep x with ey := p2ep y in constr:(EPand ex ey)
@@ -451,4 +451,8 @@ Module Z_as_Int <: Int.
Lemma i2z_ltb n p : ltb n p = Z.ltb (i2z n) (i2z p).
Proof. reflexivity. Qed.
+ (** Compatibility notations for Coq v8.4 *)
+ Notation plus := add (compat "8.4").
+ Notation minus := sub (compat "8.4").
+ Notation mult := mul (compat "8.4").
End Z_as_Int.
diff --git a/theories/ZArith/Zsqrt_compat.v b/theories/ZArith/Zsqrt_compat.v
index b80eb4451..f4baba190 100644
--- a/theories/ZArith/Zsqrt_compat.v
+++ b/theories/ZArith/Zsqrt_compat.v
@@ -30,12 +30,12 @@ Local Open Scope Z_scope.
Ltac compute_POS :=
match goal with
| |- context [(Zpos (xI ?X1))] =>
- match constr:X1 with
+ match constr:(X1) with
| context [1%positive] => fail 1
| _ => rewrite (Pos2Z.inj_xI X1)
end
| |- context [(Zpos (xO ?X1))] =>
- match constr:X1 with
+ match constr:(X1) with
| context [1%positive] => fail 1
| _ => rewrite (Pos2Z.inj_xO X1)
end
diff --git a/theories/theories.itarget b/theories/theories.itarget
deleted file mode 100644
index aacab2d97..000000000
--- a/theories/theories.itarget
+++ /dev/null
@@ -1,25 +0,0 @@
-Arith/vo.otarget
-Bool/vo.otarget
-Classes/vo.otarget
-Compat/vo.otarget
-FSets/vo.otarget
-MSets/vo.otarget
-Structures/vo.otarget
-Init/vo.otarget
-Lists/vo.otarget
-Vectors/vo.otarget
-Logic/vo.otarget
-PArith/vo.otarget
-NArith/vo.otarget
-Numbers/vo.otarget
-Program/vo.otarget
-QArith/vo.otarget
-Reals/vo.otarget
-Relations/vo.otarget
-Setoids/vo.otarget
-Sets/vo.otarget
-Sorting/vo.otarget
-Strings/vo.otarget
-Unicode/vo.otarget
-Wellfounded/vo.otarget
-ZArith/vo.otarget
diff --git a/tools/coq_makefile.ml b/tools/coq_makefile.ml
index 147759f5f..45e843e60 100644
--- a/tools/coq_makefile.ml
+++ b/tools/coq_makefile.ml
@@ -27,8 +27,9 @@ let rec print_list sep = function
| x :: l -> print x; print sep; print_list sep l
| [] -> ()
-let list_iter_i f =
- let rec aux i = function [] -> () | a::l -> f i a; aux (i+1) l in aux 1
+let rec print_prefix_list sep = function
+ | x :: l -> print sep; print x; print_prefix_list sep l
+ | [] -> ()
let section s =
let l = String.length s in
@@ -43,6 +44,17 @@ let section s =
print_com (String.make (l+2) '#');
print "\n"
+(* These are the Coq library directories that are used for
+ * plugin development
+ *)
+let lib_dirs =
+ ["kernel"; "lib"; "library"; "parsing";
+ "pretyping"; "interp"; "printing"; "intf";
+ "proofs"; "tactics"; "tools"; "ltacprof";
+ "toplevel"; "stm"; "grammar"; "config";
+ "ltac"; "engine"]
+
+
let usage () =
output_string stderr "Usage summary:
@@ -93,8 +105,10 @@ let is_genrule r = (* generic rule (like bar%foo: ...) *)
Str.string_match genrule r 0
let string_prefix a b =
- let rec aux i = try if a.[i] = b.[i] then aux (i+1) else i with |Invalid_argument _ -> i in
- String.sub a 0 (aux 0)
+ let rec aux i =
+ try if a.[i] = b.[i] then aux (i+1) else i with Invalid_argument _ -> i
+ in
+ String.sub a 0 (aux 0)
let is_prefix dir1 dir2 =
let l1 = String.length dir1 in
@@ -109,7 +123,10 @@ let is_prefix dir1 dir2 =
let physical_dir_of_logical_dir ldir =
let le = String.length ldir - 1 in
- let pdir = if le >= 0 && ldir.[le] = '.' then String.sub ldir 0 (le - 1) else String.copy ldir in
+ let pdir =
+ if le >= 0 && ldir.[le] = '.' then String.sub ldir 0 (le - 1)
+ else String.copy ldir
+ in
for i = 0 to le - 1 do
if pdir.[i] = '.' then pdir.[i] <- '/';
done;
@@ -124,62 +141,74 @@ let standard opt =
print "\"\n\n"
let classify_files_by_root var files (inc_ml,inc_i,inc_r) =
- if not (List.exists (fun (pdir,_,_) -> pdir = ".") inc_r)
- && not (List.exists (fun (pdir,_,_) -> pdir = ".") inc_i) then
- begin
- let absdir_of_files = List.rev_map
+ if List.exists (fun (pdir,_,_) -> pdir = ".") inc_r
+ || List.exists (fun (pdir,_,_) -> pdir = ".") inc_i
+ then ()
+ else
+ let absdir_of_files =List.rev_map
(fun x -> CUnix.canonical_path_name (Filename.dirname x))
- files in
- (* files in scope of a -I option (assuming they are no overlapping) *)
- let has_inc_i = List.exists (fun (_,a) -> List.mem a absdir_of_files) inc_ml in
- if has_inc_i then
- begin
- printf "%sINC=" var;
- List.iter (fun (pdir,absdir) ->
- if List.mem absdir absdir_of_files
- then printf
- "$(filter $(wildcard %s/*),$(%s)) "
- pdir var
- ) inc_ml;
- printf "\n";
- end;
- (* Files in the scope of a -R option (assuming they are disjoint) *)
- list_iter_i (fun i (pdir,_,abspdir) ->
- if List.exists (is_prefix abspdir) absdir_of_files then
- printf "%s%d=$(patsubst %s/%%,%%,$(filter %s/%%,$(%s)))\n"
- var i pdir pdir var)
- (inc_i@inc_r);
- end
+ files
+ in
+ (* files in scope of a -I option (assuming they are no overlapping) *)
+ if List.exists (fun (_,a) -> List.mem a absdir_of_files) inc_ml then
+ begin
+ printf "%sINC=" var;
+ List.iter (fun (pdir,absdir) ->
+ if List.mem absdir absdir_of_files
+ then printf "$(filter $(wildcard %s/*),$(%s)) " pdir var)
+ inc_ml;
+ printf "\n";
+ end;
+ (* Files in the scope of a -R option (assuming they are disjoint) *)
+ List.iteri (fun i (pdir,_,abspdir) ->
+ if List.exists (is_prefix abspdir) absdir_of_files then
+ printf "%s%d=$(patsubst %s/%%,%%,$(filter %s/%%,$(%s)))\n"
+ var i pdir pdir var)
+ (inc_i@inc_r)
let vars_to_put_by_root var_x_files_l (inc_ml,inc_i,inc_r) =
- let var_x_absdirs_l = List.rev_map
- (fun (v,l) -> (v,List.rev_map (fun x -> CUnix.canonical_path_name (Filename.dirname x)) l))
- var_x_files_l in
- let var_filter f g = List.fold_left (fun acc (var,dirs) ->
- if f dirs
- then (g var)::acc else acc) [] var_x_absdirs_l in
- (* All files caught by a -R . option (assuming it is the only one) *)
+ let var_x_absdirs_l =
+ List.rev_map
+ (fun (v,l) ->
+ (v,List.rev_map
+ (fun x -> CUnix.canonical_path_name (Filename.dirname x)) l))
+ var_x_files_l
+ in
+ let var_filter f g =
+ List.fold_left
+ (fun acc (var,dirs) -> if f dirs then (g var)::acc else acc)
+ [] var_x_absdirs_l
+ in
+ (* All files caught by a -R . option (assuming it is the only one) *)
match inc_i@inc_r with
- |[(".",t,_)] -> (None,[".",physical_dir_of_logical_dir t,List.rev_map fst var_x_files_l])
+ |[(".",t,_)] ->
+ (None,[".",physical_dir_of_logical_dir t,List.rev_map fst var_x_files_l])
|l ->
try
let out = List.assoc "." (List.rev_map (fun (p,l,_) -> (p,l)) l) in
- let () = prerr_string "Warning: install rule assumes that -R/-Q . _ is the only -R/-Q option\n" in
+ let () = prerr_string "Warning: install rule assumes that -R/-Q . _ is the only -R/-Q option\n"
+ in
(None,[".",physical_dir_of_logical_dir out,List.rev_map fst var_x_files_l])
with Not_found ->
- (
(* vars for -Q options *)
- Some (var_filter (fun l -> List.exists (fun (_,a) -> List.mem a l) inc_ml) (fun x -> x)),
+ let varq = var_filter
+ (fun l -> List.exists (fun (_,a) -> List.mem a l) inc_ml)
+ (fun x -> x)
+ in
(* (physical dir, physical dir of logical path,vars) for -R options
(assuming physical dirs are disjoint) *)
- if l = [] then
- [".","$(INSTALLDEFAULTROOT)",[]]
- else
- Util.List.fold_left_i (fun i out (pdir,ldir,abspdir) ->
- let vars_r = var_filter (List.exists (is_prefix abspdir)) (fun x -> x^string_of_int i) in
- let pdir' = physical_dir_of_logical_dir ldir in
- (pdir,pdir',vars_r)::out) 1 [] l
- )
+ let other =
+ if l = [] then
+ [".","$(INSTALLDEFAULTROOT)",[]]
+ else
+ Util.List.fold_left_i (fun i out (pdir,ldir,abspdir) ->
+ let vars_r = var_filter
+ (List.exists (is_prefix abspdir))
+ (fun x -> x^string_of_int i)
+ in
+ let pdir' = physical_dir_of_logical_dir ldir in
+ (pdir,pdir',vars_r)::out) 1 [] l
+ in (Some varq, other)
let install_include_by_root perms =
let install_dir for_i (pdir,pdir',vars) =
@@ -255,33 +284,38 @@ let where_put_doc = function
install-doc will put anything in $INSTALLDEFAULTROOT\n" in
"$(INSTALLDEFAULTROOT)"
-let install (vfiles,(mlifiles,ml4files,mlfiles,mllibfiles,mlpackfiles),_,sds) inc = function
+let install (vfiles,(mlis,ml4s,mls,mllibs,mlpacks),_,sds) inc = function
|Project_file.NoInstall -> ()
|is_install ->
let not_empty = function |[] -> false |_::_ -> true in
- let cmofiles = List.rev_append mlpackfiles (List.rev_append mlfiles ml4files) in
- let cmifiles = List.rev_append mlifiles cmofiles in
- let cmxsfiles = List.rev_append cmofiles mllibfiles in
- let where_what_cmxs = vars_to_put_by_root [("CMXSFILES",cmxsfiles)] inc in
+ let cmos = List.rev_append mlpacks (List.rev_append mls ml4s) in
+ let cmis = List.rev_append mlis cmos in
+ let cmxss = List.rev_append cmos mllibs in
+ let where_what_cmxs = vars_to_put_by_root [("CMXSFILES",cmxss)] inc in
let where_what_oth = vars_to_put_by_root
- [("VOFILES",vfiles);("VFILES",vfiles);("GLOBFILES",vfiles);("NATIVEFILES",vfiles);("CMOFILES",cmofiles);("CMIFILES",cmifiles);("CMAFILES",mllibfiles)]
+ [("VOFILES",vfiles);("VFILES",vfiles);
+ ("GLOBFILES",vfiles);("NATIVEFILES",vfiles);
+ ("CMOFILES",cmos);("CMIFILES",cmis);("CMAFILES",mllibs)]
inc in
let doc_dir = where_put_doc inc in
- let () = if is_install = Project_file.UnspecInstall then
- print "userinstall:\n\t+$(MAKE) USERINSTALL=true install\n\n" in
- if (not_empty cmxsfiles) then begin
+ if is_install = Project_file.UnspecInstall then begin
+ print "userinstall:\n\t+$(MAKE) USERINSTALL=true install\n\n"
+ end;
+ if not_empty cmxss then begin
print "install-natdynlink:\n";
install_include_by_root "0755" where_what_cmxs;
print "\n";
end;
- if (not_empty cmxsfiles) then begin
+ if not_empty cmxss then begin
print "install-toploop: $(MLLIBFILES:.mllib=.cmxs)\n";
printf "\t install -d \"$(DSTROOT)\"$(COQTOPINSTALL)/\n";
printf "\t install -m 0755 $? \"$(DSTROOT)\"$(COQTOPINSTALL)/\n";
print "\n";
end;
print "install:";
- if (not_empty cmxsfiles) then print "$(if $(HASNATDYNLINK_OR_EMPTY),install-natdynlink)";
+ if not_empty cmxss then begin
+ print "$(if $(HASNATDYNLINK_OR_EMPTY),install-natdynlink)";
+ end;
print "\n";
install_include_by_root "0644" where_what_oth;
List.iter
@@ -296,7 +330,7 @@ let install (vfiles,(mlifiles,ml4files,mlfiles,mllibfiles,mlpackfiles),_,sds) in
print "\tdone\n" in
print "install-doc:\n";
if not_empty vfiles then install_one_kind "html" doc_dir;
- if not_empty mlifiles then install_one_kind "mlihtml" doc_dir;
+ if not_empty mlis then install_one_kind "mlihtml" doc_dir;
print "\n";
let uninstall_one_kind kind dir =
printf "\tprintf 'cd \"$${DSTROOT}\"$(COQDOCINSTALL)/%s \\\\\\n' >> \"$@\"\n" dir;
@@ -306,10 +340,10 @@ let install (vfiles,(mlifiles,ml4files,mlfiles,mllibfiles,mlpackfiles),_,sds) in
in
printf "uninstall_me.sh: %s\n" !makefile_name;
print "\techo '#!/bin/sh' > $@\n";
- if (not_empty cmxsfiles) then uninstall_by_root where_what_cmxs;
+ if not_empty cmxss then uninstall_by_root where_what_cmxs;
uninstall_by_root where_what_oth;
if not_empty vfiles then uninstall_one_kind "html" doc_dir;
- if not_empty mlifiles then uninstall_one_kind "mlihtml" doc_dir;
+ if not_empty mlis then uninstall_one_kind "mlihtml" doc_dir;
print "\tchmod +x $@\n";
print "\n";
print "uninstall: uninstall_me.sh\n";
@@ -328,11 +362,14 @@ let make_makefile sds =
let clean sds sps =
print "clean::\n";
- if !some_mlfile || !some_mlifile || !some_ml4file || !some_mllibfile || !some_mlpackfile then begin
- print "\trm -f $(ALLCMOFILES) $(CMIFILES) $(CMAFILES)\n";
- print "\trm -f $(ALLCMOFILES:.cmo=.cmx) $(CMXAFILES) $(CMXSFILES) $(ALLCMOFILES:.cmo=.o) $(CMXAFILES:.cmxa=.a)\n";
- print "\trm -f $(addsuffix .d,$(MLFILES) $(MLIFILES) $(ML4FILES) $(MLLIBFILES) $(MLPACKFILES))\n";
- end;
+ if !some_mlfile || !some_mlifile || !some_ml4file
+ || !some_mllibfile || !some_mlpackfile
+ then
+ begin
+ print "\trm -f $(ALLCMOFILES) $(CMIFILES) $(CMAFILES)\n";
+ print "\trm -f $(ALLCMOFILES:.cmo=.cmx) $(CMXAFILES) $(CMXSFILES) $(ALLCMOFILES:.cmo=.o) $(CMXAFILES:.cmxa=.a)\n";
+ print "\trm -f $(addsuffix .d,$(MLFILES) $(MLIFILES) $(ML4FILES) $(MLLIBFILES) $(MLPACKFILES))\n";
+ end;
if !some_vfile then
begin
print "\trm -f $(OBJFILES) $(OBJFILES:.o=.native) $(NATIVEFILES)\n";
@@ -369,38 +406,67 @@ let header_includes () = ()
let implicit () =
section "Implicit rules.";
let mli_rules () =
- print "$(MLIFILES:.mli=.cmi): %.cmi: %.mli\n\t$(CAMLC) $(ZDEBUG) $(ZFLAGS) $<\n\n";
+ print "$(MLIFILES:.mli=.cmi): %.cmi: %.mli\n";
+ print "\t$(SHOW)'CAMLC -c $<'\n";
+ print "\t$(HIDE)$(CAMLC) $(ZDEBUG) $(ZFLAGS) $<\n\n";
print "$(addsuffix .d,$(MLIFILES)): %.mli.d: %.mli\n";
- print "\t$(OCAMLFIND) ocamldep -slash $(OCAMLLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
+ print "\t$(SHOW)'CAMLDEP $<'\n";
+ print "\t$(HIDE)$(CAMLDEP) $(OCAMLLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n"
+ in
let ml4_rules () =
- print "$(ML4FILES:.ml4=.cmo): %.cmo: %.ml4\n\t$(CAMLC) $(ZDEBUG) $(ZFLAGS) $(PP) -impl $<\n\n";
+ print "$(ML4FILES:.ml4=.cmo): %.cmo: %.ml4\n";
+ print "\t$(SHOW)'CAMLC -pp -c $<'\n";
+ print "\t$(HIDE)$(CAMLC) $(ZDEBUG) $(ZFLAGS) $(PP) -impl $<\n\n";
print "$(filter-out $(addsuffix .cmx,$(foreach lib,$(MLPACKFILES:.mlpack=_MLPACK_DEPENDENCIES),$($(lib)))),$(ML4FILES:.ml4=.cmx)): %.cmx: %.ml4\n";
- print "\t$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) $(PP) -impl $<\n\n";
+ print "\t$(SHOW)'CAMLOPT -pp -c $<'\n";
+ print "\t$(HIDE)$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) $(PP) -impl $<\n\n";
print "$(addsuffix .d,$(ML4FILES)): %.ml4.d: %.ml4\n";
- print "\t$(OCAMLFIND) ocamldep -slash $(OCAMLLIBS) $(PP) -impl \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
+ print "\t$(SHOW)'CAMLDEP -pp $<'\n";
+ print "\t$(HIDE)$(CAMLDEP) $(OCAMLLIBS) $(PP) -impl \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
let ml_rules () =
- print "$(MLFILES:.ml=.cmo): %.cmo: %.ml\n\t$(CAMLC) $(ZDEBUG) $(ZFLAGS) $<\n\n";
+ print "$(MLFILES:.ml=.cmo): %.cmo: %.ml\n";
+ print "\t$(SHOW)'CAMLC -c $<'\n";
+ print "\t$(HIDE)$(CAMLC) $(ZDEBUG) $(ZFLAGS) $<\n\n";
print "$(filter-out $(addsuffix .cmx,$(foreach lib,$(MLPACKFILES:.mlpack=_MLPACK_DEPENDENCIES),$($(lib)))),$(MLFILES:.ml=.cmx)): %.cmx: %.ml\n";
- print "\t$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) $<\n\n";
+ print "\t$(SHOW)'CAMLOPT -c $<'\n";
+ print "\t$(HIDE)$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) $<\n\n";
print "$(addsuffix .d,$(MLFILES)): %.ml.d: %.ml\n";
- print "\t$(OCAMLFIND) ocamldep -slash $(OCAMLLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
+ print "\t$(SHOW)'CAMLDEP $<'\n";
+ print "\t$(HIDE)$(CAMLDEP) $(OCAMLLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
let cmxs_rules () = (* order is important here when there is foo.ml and foo.mllib *)
- print "$(filter-out $(MLLIBFILES:.mllib=.cmxs),$(MLFILES:.ml=.cmxs) $(ML4FILES:.ml4=.cmxs) $(MLPACKFILES:.mlpack=.cmxs)): %.cmxs: %.cmx
-\t$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -shared -o $@ $<\n\n";
- print "$(MLLIBFILES:.mllib=.cmxs): %.cmxs: %.cmxa\n\t$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -linkall -shared -o $@ $<\n\n" in
+ print "$(filter-out $(MLLIBFILES:.mllib=.cmxs),$(MLFILES:.ml=.cmxs) $(ML4FILES:.ml4=.cmxs) $(MLPACKFILES:.mlpack=.cmxs)): %.cmxs: %.cmx\n";
+ print "\t$(SHOW)'CAMLOPT -shared -o $@'\n";
+ print "\t$(HIDE)$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -shared -o $@ $<\n\n";
+ print "$(MLLIBFILES:.mllib=.cmxs): %.cmxs: %.cmxa\n";
+ print "\t$(SHOW)'CAMLOPT -shared -o $@'\n";
+ print "\t$(HIDE)$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -linkall -shared -o $@ $<\n\n"
+ in
let mllib_rules () =
- print "$(MLLIBFILES:.mllib=.cma): %.cma: | %.mllib\n\t$(CAMLLINK) $(ZDEBUG) $(ZFLAGS) -a -o $@ $^\n\n";
- print "$(MLLIBFILES:.mllib=.cmxa): %.cmxa: | %.mllib\n\t$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -a -o $@ $^\n\n";
+ print "$(MLLIBFILES:.mllib=.cma): %.cma: | %.mllib\n";
+ print "\t$(SHOW)'CAMLC -a -o $@'\n";
+ print "\t$(HIDE)$(CAMLLINK) $(ZDEBUG) $(ZFLAGS) -a -o $@ $^\n\n";
+ print "$(MLLIBFILES:.mllib=.cmxa): %.cmxa: | %.mllib\n";
+ print "\t$(SHOW)'CAMLOPT -a -o $@'\n";
+ print "\t$(HIDE)$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -a -o $@ $^\n\n";
print "$(addsuffix .d,$(MLLIBFILES)): %.mllib.d: %.mllib\n";
- print "\t$(COQDEP) $(OCAMLLIBS) -c \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
+ print "\t$(SHOW)'COQDEP $<'\n";
+ print "\t$(HIDE)$(COQDEP) $(OCAMLLIBS) -c \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n"
+ in
let mlpack_rules () =
- print "$(MLPACKFILES:.mlpack=.cmo): %.cmo: | %.mlpack\n\t$(CAMLLINK) $(ZDEBUG) $(ZFLAGS) -pack -o $@ $^\n\n";
- print "$(MLPACKFILES:.mlpack=.cmx): %.cmx: | %.mlpack\n\t$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -pack -o $@ $^\n\n";
+ print "$(MLPACKFILES:.mlpack=.cmo): %.cmo: | %.mlpack\n";
+ print "\t$(SHOW)'CAMLC -pack -o $@'\n";
+ print "\t$(HIDE)$(CAMLLINK) $(ZDEBUG) $(ZFLAGS) -pack -o $@ $^\n\n";
+ print "$(MLPACKFILES:.mlpack=.cmx): %.cmx: | %.mlpack\n";
+ print "\t$(SHOW)'CAMLOPT -pack -o $@'\n";
+ print "\t$(HIDE)$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -pack -o $@ $^\n\n";
print "$(addsuffix .d,$(MLPACKFILES)): %.mlpack.d: %.mlpack\n";
- print "\t$(COQDEP) $(OCAMLLIBS) -c \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n";
-in
+ print "\t$(SHOW)'COQDEP $<'\n";
+ print "\t$(HIDE)$(COQDEP) $(OCAMLLIBS) -c \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n"
+ in
let v_rules () =
- print "$(VOFILES): %.vo: %.v\n\t$(COQC) $(COQDEBUG) $(COQFLAGS) $*\n\n";
+ print "$(VOFILES): %.vo: %.v\n";
+ print "\t$(SHOW)COQC $*\n";
+ print "\t$(HIDE)$(COQC) $(COQDEBUG) $(COQFLAGS) $*\n\n";
print "$(GLOBFILES): %.glob: %.v\n\t$(COQC) $(COQDEBUG) $(COQFLAGS) $*\n\n";
print "$(VFILES:.v=.vio): %.vio: %.v\n\t$(COQC) -quick $(COQDEBUG) $(COQFLAGS) $*\n\n";
print "$(GFILES): %.g: %.v\n\t$(GALLINA) $<\n\n";
@@ -409,7 +475,8 @@ in
print "$(VFILES:.v=.g.tex): %.g.tex: %.v\n\t$(COQDOC) $(COQDOCFLAGS) -latex -g $< -o $@\n\n";
print "$(GHTMLFILES): %.g.html: %.v %.glob\n\t$(COQDOC) $(COQDOCFLAGS) -html -g $< -o $@\n\n";
print "$(addsuffix .d,$(VFILES)): %.v.d: %.v\n";
- print "\t$(COQDEP) $(COQLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n";
+ print "\t$(SHOW)'COQDEP $<'\n";
+ print "\t$(HIDE)$(COQDEP) $(COQLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n";
print "$(addsuffix .beautified,$(VFILES)): %.v.beautified:\n\t$(COQC) $(COQDEBUG) $(COQFLAGS) -beautify $*\n\n"
in
if !some_mlifile then mli_rules ();
@@ -452,12 +519,8 @@ let variables is_install opt (args,defs) =
end;
(* Caml executables and relative variables *)
if !some_ml4file || !some_mlfile || !some_mlifile then begin
- print "COQSRCLIBS?=-I \"$(COQLIB)kernel\" -I \"$(COQLIB)lib\" \\
- -I \"$(COQLIB)library\" -I \"$(COQLIB)parsing\" -I \"$(COQLIB)engine\" -I \"$(COQLIB)pretyping\" \\
- -I \"$(COQLIB)interp\" -I \"$(COQLIB)printing\" -I \"$(COQLIB)intf\" \\
- -I \"$(COQLIB)proofs\" -I \"$(COQLIB)tactics\" -I \"$(COQLIB)tools\" \\
- -I \"$(COQLIB)toplevel\" -I \"$(COQLIB)stm\" -I \"$(COQLIB)grammar\" \\
- -I \"$(COQLIB)config\"";
+ print "COQSRCLIBS?=" ;
+ List.iter (fun c -> print "-I \"$(COQLIB)"; print c ; print "\" \\\n") lib_dirs ;
List.iter (fun c -> print " \\
-I \"$(COQLIB)/"; print c; print "\"") Coq_config.plugins_dirs; print "\n";
print "ZFLAGS=$(OCAMLLIBS) $(COQSRCLIBS) -I $(CAMLP4LIB)\n\n";
@@ -465,6 +528,7 @@ let variables is_install opt (args,defs) =
print "CAMLOPTC?=$(OCAMLFIND) opt -c -rectypes -thread\n";
print "CAMLLINK?=$(OCAMLFIND) ocamlc -rectypes -thread\n";
print "CAMLOPTLINK?=$(OCAMLFIND) opt -rectypes -thread\n";
+ print "CAMLDEP?=$(OCAMLFIND) ocamldep -slash -ml-synonym .ml4 -ml-synonym .mlpack\n";
print "CAMLLIB?=$(shell $(OCAMLFIND) printconf stdlib)\n";
print "GRAMMARS?=grammar.cma\n";
print "ifeq ($(CAMLP4),camlp5)
@@ -509,7 +573,11 @@ let parameters () =
print "# TIMECMD set a command to log .v compilation time;\n";
print "# TIMED if non empty, use the default time command as TIMECMD;\n";
print "# ZDEBUG/COQDEBUG to specify debug flags for ocamlc&ocamlopt/coqc;\n";
- print "# DSTROOT to specify a prefix to install path.\n\n";
+ print "# DSTROOT to specify a prefix to install path.\n";
+ print "# VERBOSE to disable the short display of compilation rules.\n\n";
+ print "VERBOSE?=\n";
+ print "SHOW := $(if $(VERBOSE),@true \"\",@echo \"\")\n";
+ print "HIDE := $(if $(VERBOSE),,@)\n\n";
print "# Here is a hack to make $(eval $(shell works:\n";
print "define donewline\n\n\nendef\n";
print "includecmdwithout@ = $(eval $(subst @,$(donewline),$(shell { $(1) | tr -d '\\r' | tr '\\n' '@'; })))\n";
@@ -520,28 +588,35 @@ let parameters () =
print " $(filter-out Warning: Error:,\\\n";
print " $(shell $(COQBIN)coqtop -q -noinit -batch -quiet -print-mod-uid $(1))))\n\n"
-let include_dirs (inc_ml,inc_i,inc_r) =
+let include_dirs (inc_ml,inc_q,inc_r) =
let parse_ml_includes l = List.map (fun (x,_) -> "-I \"" ^ x ^ "\"") l in
- let parse_includes l = List.map (fun (x,l,_) ->
- let l' = if l = "" then "\"\"" else l in
- "-Q \"" ^ x ^ "\" " ^ l' ^"") l in
- let parse_rec_includes l = List.map (fun (p,l,_) ->
- let l' = if l = "" then "\"\"" else l in
- "-R \"" ^ p ^ "\" " ^ l' ^"") l in
+ let includes =
+ List.map (fun (p,l,_) ->
+ let l' = if l = "" then "\"\"" else l in
+ " \"" ^ p ^ "\" " ^ l' ^"") in
let str_ml = parse_ml_includes inc_ml in
- let str_i = parse_includes inc_i in
- let str_r = parse_rec_includes inc_r in
- section "Libraries definitions.";
- if !some_ml4file || !some_mlfile || !some_mlifile then begin
- print "OCAMLLIBS?="; print_list "\\\n " str_ml; print "\n";
- end;
- if !some_vfile || !some_mllibfile || !some_mlpackfile then begin
- print "COQLIBS?="; print_list "\\\n " str_i;
- List.iter (fun x -> print "\\\n "; print x) str_r;
- List.iter (fun x -> print "\\\n "; print x) str_ml; print "\n";
- print "COQDOCLIBS?="; print_list "\\\n " str_i;
- List.iter (fun x -> print "\\\n "; print x) str_r; print "\n\n";
- end
+ section "Libraries definitions.";
+ if !some_ml4file || !some_mlfile || !some_mlifile then begin
+ print "OCAMLLIBS?="; print_list "\\\n " str_ml; print "\n";
+ end;
+ if !some_vfile || !some_mllibfile || !some_mlpackfile then begin
+ print "COQLIBS?=";
+ print_prefix_list "\\\n -Q" (includes inc_q);
+ print_prefix_list "\\\n -R" (includes inc_r);
+ print_prefix_list "\\\n " str_ml;
+ print "\n";
+ end;
+ if !some_vfile then begin
+ print "COQCHKLIBS?=";
+ print_prefix_list "\\\n -R" (includes inc_q);
+ print_prefix_list "\\\n -R" (includes inc_r);
+ print "\n";
+ print "COQDOCLIBS?=";
+ print_prefix_list "\\\n -R" (includes inc_q);
+ print_prefix_list "\\\n -R" (includes inc_r);
+ print "\n";
+ end;
+ print "\n"
let double_colon = ["clean"; "cleanall"; "archclean"]
@@ -572,10 +647,13 @@ let forpacks l =
let () = if l <> [] then section "Ad-hoc implicit rules for mlpack." in
List.iter (fun it ->
let h = Filename.chop_extension it in
+ let pk = String.capitalize (Filename.basename h) in
printf "$(addsuffix .cmx,$(filter $(basename $(MLFILES)),$(%s_MLPACK_DEPENDENCIES))): %%.cmx: %%.ml\n" h;
- printf "\t$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) -for-pack %s $<\n\n" (String.capitalize (Filename.basename h));
+ printf "\t$(SHOW)'CAMLOPT -c -for-pack %s $<'\n" pk;
+ printf "\t$(HIDE)$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) -for-pack %s $<\n\n" pk;
printf "$(addsuffix .cmx,$(filter $(basename $(ML4FILES)),$(%s_MLPACK_DEPENDENCIES))): %%.cmx: %%.ml4\n" h;
- printf "\t$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) -for-pack %s $(PP) -impl $<\n\n" (String.capitalize (Filename.basename h))
+ printf "\t$(SHOW)'CAMLOPT -c -pp -for-pack %s $<'\n" pk;
+ printf "\t$(HIDE)$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) -for-pack %s $(PP) -impl $<\n\n" pk
) l
let main_targets vfiles (mlifiles,ml4files,mlfiles,mllibfiles,mlpackfiles) other_targets inc =
@@ -714,7 +792,7 @@ let main_targets vfiles (mlifiles,ml4files,mlfiles,mllibfiles,mlpackfiles) other
print "all-gal.pdf: $(VFILES)\n";
print "\t$(COQDOC) -toc $(COQDOCFLAGS) -pdf -g $(COQDOCLIBS) -o $@ `$(COQDEP) -sort -suffix .v $^`\n\n";
print "validate: $(VOFILES)\n";
- print "\t$(COQCHK) $(COQCHKFLAGS) $(COQLIBS) $(notdir $(^:.vo=))\n\n";
+ print "\t$(COQCHK) $(COQCHKFLAGS) $(COQCHKLIBS) $(notdir $(^:.vo=))\n\n";
print "beautify: $(VFILES:=.beautified)\n";
print "\tfor file in $^; do mv $${file%.beautified} $${file%beautified}old && mv $${file} $${file%.beautified}; done\n";
print "\t@echo \'Do not do \"make clean\" until you are sure that everything went well!\'\n";
@@ -767,22 +845,24 @@ let command_line args =
print_list args;
print "\n#\n\n"
-let ensure_root_dir (v,(mli,ml4,ml,mllib,mlpack),_,_) ((ml_inc,i_inc,r_inc) as l) =
+let ensure_root_dir (vfiles,(mlis,ml4s,mls,mllibs,mlpacks),_,_) inc =
+ let (ml_inc,i_inc,r_inc) = inc in
let here = Sys.getcwd () in
- let not_tops =List.for_all (fun s -> s <> Filename.basename s) in
+ let not_tops = List.for_all (fun s -> s <> Filename.basename s) in
if List.exists (fun (_,_,x) -> x = here) i_inc
|| List.exists (fun (_,_,x) -> is_prefix x here) r_inc
- || (not_tops v && not_tops mli && not_tops ml4 && not_tops ml
- && not_tops mllib && not_tops mlpack) then
- l
+ || (not_tops vfiles && not_tops mlis && not_tops ml4s && not_tops mls
+ && not_tops mllibs && not_tops mlpacks)
+ then
+ inc
else
((".",here)::ml_inc,i_inc,(".","Top",here)::r_inc)
-let warn_install_at_root_directory
- (vfiles,(mlifiles,ml4files,mlfiles,mllibfiles,mlpackfiles),_,_) (inc_ml,inc_i,inc_r) =
+let warn_install_at_root_directory (vfiles,(mlis,ml4s,mls,mllibs,mlpacks),_,_) inc =
+ let (inc_ml,inc_i,inc_r) = inc in
let inc_top = List.filter (fun (_,ldir,_) -> ldir = "") (inc_r@inc_i) in
let inc_top_p = List.map (fun (p,_,_) -> p) inc_top in
- let files = vfiles @ mlifiles @ ml4files @ mlfiles @ mllibfiles @ mlpackfiles in
+ let files = vfiles @ mlis @ ml4s @ mls @ mllibs @ mlpacks in
if List.exists (fun f -> List.mem (Filename.dirname f) inc_top_p) files
then
Printf.eprintf "Warning: install target will copy files at the first level of the coq contributions installation directory; option -R or -Q %sis recommended\n"
@@ -800,12 +880,29 @@ let check_overlapping_include (_,inc_i,inc_r) =
Printf.eprintf "Warning: in options -R/-Q, %s and %s overlap\n" pdir pdir') l;
in aux (inc_i@inc_r)
+(* Generate a .merlin file that references the standard library and
+ * any -I included paths.
+ *)
+let merlin targets (ml_inc,_,_) =
+ print ".merlin:\n";
+ print "\t@echo 'FLG -rectypes' > .merlin\n" ;
+ List.iter (fun c ->
+ printf "\t@echo \"B $(COQLIB) %s\" >> .merlin\n" c)
+ lib_dirs ;
+ List.iter (fun (_,c) ->
+ printf "\t@echo \"B %s\" >> .merlin\n" c;
+ printf "\t@echo \"S %s\" >> .merlin\n" c)
+ ml_inc;
+ print "\n"
+
let do_makefile args =
let has_file var = function
|[] -> var := false
|_::_ -> var := true in
let (project_file,makefile,is_install,opt),l =
- try Project_file.process_cmd_line Filename.current_dir_name (None,None,Project_file.UnspecInstall,true) [] args
+ try
+ Project_file.process_cmd_line Filename.current_dir_name
+ (None,None,Project_file.UnspecInstall,true) [] args
with Project_file.Parsing_error -> usage () in
let (v_f,(mli_f,ml4_f,ml_f,mllib_f,mlpack_f),sps,sds as targets), inc, defs =
Project_file.split_arguments l in
@@ -829,7 +926,9 @@ let do_makefile args =
List.iter check_dep (Str.split (Str.regexp "[ \t]+") dependencies)) sps;
let inc = ensure_root_dir targets inc in
- if is_install <> Project_file.NoInstall then warn_install_at_root_directory targets inc;
+ if is_install <> Project_file.NoInstall then begin
+ warn_install_at_root_directory targets inc;
+ end;
check_overlapping_include inc;
banner ();
header_includes ();
@@ -842,6 +941,7 @@ let do_makefile args =
section "Special targets.";
standard opt;
install targets inc is_install;
+ merlin targets inc;
clean sds sps;
make_makefile sds;
implicit ();
diff --git a/tools/coqc.ml b/tools/coqc.ml
index f957200ab..ecbbfefac 100644
--- a/tools/coqc.ml
+++ b/tools/coqc.ml
@@ -88,7 +88,7 @@ let parse_args () =
(* Options for coqtop : a) options with 0 argument *)
- | ("-notactics"|"-bt"|"-debug"|"-nolib"|"-boot"|"-time"
+ | ("-notactics"|"-bt"|"-debug"|"-nolib"|"-boot"|"-time"|"-profile-ltac"
|"-batch"|"-noinit"|"-nois"|"-noglob"|"-no-glob"
|"-q"|"-full"|"-profile"|"-just-parsing"|"-echo" |"-unsafe"|"-quiet"
|"-silent"|"-m"|"-xml"|"-v7"|"-v8"|"-beautify"|"-strict-implicit"
@@ -107,6 +107,7 @@ let parse_args () =
|"-load-ml-source"|"-require"|"-load-ml-object"
|"-init-file"|"-dump-glob"|"-compat"|"-coqlib"|"-top"
|"-async-proofs-j" |"-async-proofs-private-flags" |"-async-proofs" |"-w"
+ |"-o"
as o) :: rem ->
begin
match rem with
diff --git a/tools/coqdep.ml b/tools/coqdep.ml
index 13705edaa..9886b263c 100644
--- a/tools/coqdep.ml
+++ b/tools/coqdep.ml
@@ -502,7 +502,7 @@ let coqdep () =
let user = coqlib//"user-contrib" in
if Sys.file_exists user then add_rec_dir_no_import add_coqlib_known user [];
List.iter (fun s -> add_rec_dir_no_import add_coqlib_known s [])
- (Envars.xdg_dirs (fun x -> Pp.msg_warning (Pp.str x)));
+ (Envars.xdg_dirs (fun x -> Feedback.msg_warning (Pp.str x)));
List.iter (fun s -> add_rec_dir_no_import add_coqlib_known s []) Envars.coqpath;
end;
List.iter (fun (f,d) -> add_mli_known f d ".mli") !mliAccu;
@@ -527,4 +527,4 @@ let _ =
coqdep ()
with Errors.UserError(s,p) ->
let pp = if s <> "_" then Pp.(str s ++ str ": " ++ p) else p in
- Pp.msgerrnl pp
+ Feedback.msg_error pp
diff --git a/tools/coqdep_common.ml b/tools/coqdep_common.ml
index c63e4aaa6..0f7937d72 100644
--- a/tools/coqdep_common.ml
+++ b/tools/coqdep_common.ml
@@ -9,11 +9,11 @@
open Printf
open Coqdep_lexer
open Unix
-open System
+open Minisys
(** [coqdep_boot] is a stripped-down version of [coqdep], whose
behavior is the one of [coqdep -boot]. Its only dependencies
- are [Coqdep_lexer] and [Unix], and it should stay so.
+ are [Coqdep_lexer], [Unix] and [Minisys], and it should stay so.
If it need someday some additional information, pass it via
options (see for instance [option_natdynlk] below).
*)
@@ -526,7 +526,7 @@ let rec add_directory recur add_file phys_dir log_dir =
| FileRegular f ->
add_file phys_dir log_dir f
in
- System.check_unix_dir (fun s -> eprintf "*** Warning: %s\n" s) phys_dir;
+ check_unix_dir (fun s -> eprintf "*** Warning: %s\n" s) phys_dir;
if exists_dir phys_dir then
process_directory f phys_dir
else
diff --git a/tools/coqdoc/cpretty.mll b/tools/coqdoc/cpretty.mll
index 431080c6b..005ffdae7 100644
--- a/tools/coqdoc/cpretty.mll
+++ b/tools/coqdoc/cpretty.mll
@@ -75,7 +75,7 @@
let stop_env () = if !r then stop (); r := false in
(fun x -> !r), start_env, stop_env
- let in_emph, start_emph, stop_emph = in_env Output.start_emph Output.stop_emph
+ let _, start_emph, stop_emph = in_env Output.start_emph Output.stop_emph
let in_quote, start_quote, stop_quote = in_env Output.start_quote Output.stop_quote
let url_buffer = Buffer.create 40
@@ -111,12 +111,6 @@
Cdglobals.gallina := s.st_gallina;
Cdglobals.light := s.st_light
- let without_ref r f x = save_state (); r := false; f x; restore_state ()
-
- let without_gallina = without_ref Cdglobals.gallina
-
- let without_light = without_ref Cdglobals.light
-
let begin_show () = save_state (); Cdglobals.gallina := false; Cdglobals.light := false
let end_show () = restore_state ()
@@ -245,6 +239,12 @@
let s = String.sub s isp (String.length s - isp) in
Output.keyword s (lexeme_start lexbuf + isp)
+ let only_gallina () =
+ !Cdglobals.gallina && !in_proof <> None
+
+ let parse_comments () =
+ !Cdglobals.parse_comments && not (only_gallina ())
+
}
(*s Regular expressions *)
@@ -486,7 +486,7 @@ rule coq_bol = parse
in if eol then coq_bol lexbuf else coq lexbuf }
| space* end_kw {
let eol =
- if not (!in_proof <> None && !Cdglobals.gallina) then
+ if not (only_gallina ()) then
begin backtrack lexbuf; body_bol lexbuf end
else skip_to_dot lexbuf
in
@@ -535,14 +535,15 @@ rule coq_bol = parse
coq_bol lexbuf }
| space* "(*"
{ comment_level := 1;
- if !Cdglobals.parse_comments then begin
- let s = lexeme lexbuf in
- let nbsp,isp = count_spaces s in
- Output.indentation nbsp;
- Output.start_comment ();
- end;
- let eol = comment lexbuf in
- if eol then coq_bol lexbuf else coq lexbuf }
+ let eol =
+ if parse_comments () then begin
+ let s = lexeme lexbuf in
+ let nbsp, isp = count_spaces s in
+ Output.indentation nbsp;
+ Output.start_comment ();
+ comment lexbuf
+ end else skipped_comment lexbuf in
+ if eol then coq_bol lexbuf else coq lexbuf }
| eof
{ () }
| _
@@ -550,7 +551,7 @@ rule coq_bol = parse
if not !Cdglobals.gallina then
begin backtrack lexbuf; body_bol lexbuf end
else
- skip_to_dot lexbuf
+ skip_to_dot_or_brace lexbuf
in
if eol then coq_bol lexbuf else coq lexbuf }
@@ -558,7 +559,7 @@ rule coq_bol = parse
and coq = parse
| nl
- { if not (!in_proof <> None && !Cdglobals.gallina) then Output.line_break(); coq_bol lexbuf }
+ { if not (only_gallina ()) then Output.line_break(); coq_bol lexbuf }
| "(**" space_nl
{ Output.end_coq (); Output.start_doc ();
let eol = doc_bol lexbuf in
@@ -566,16 +567,12 @@ and coq = parse
if eol then coq_bol lexbuf else coq lexbuf }
| "(*"
{ comment_level := 1;
- if !Cdglobals.parse_comments then begin
- let s = lexeme lexbuf in
- let nbsp,isp = count_spaces s in
- Output.indentation nbsp;
- Output.start_comment ();
- end;
- let eol = comment lexbuf in
- if eol then coq_bol lexbuf
- else coq lexbuf
- }
+ let eol =
+ if parse_comments () then begin
+ Output.start_comment ();
+ comment lexbuf
+ end else skipped_comment lexbuf in
+ if eol then coq_bol lexbuf else coq lexbuf }
| nl+ space* "]]"
{ if not !formatted then
begin
@@ -650,7 +647,7 @@ and coq = parse
if not !Cdglobals.gallina then
begin backtrack lexbuf; body lexbuf end
else
- skip_to_dot lexbuf
+ skip_to_dot_or_brace lexbuf
in
if eol then coq_bol lexbuf else coq lexbuf}
@@ -820,9 +817,10 @@ and doc indents = parse
| Some is -> doc_list_bol is
| None -> doc_bol
in
- let eol = comment lexbuf in
- if eol then bol_parse lexbuf else doc indents lexbuf
- }
+ let eol =
+ if !Cdglobals.parse_comments then comment lexbuf
+ else skipped_comment lexbuf in
+ if eol then bol_parse lexbuf else doc indents lexbuf }
| '*'* "*)" space_nl* "(**"
{(match indents with
| Some _ -> Output.stop_item ()
@@ -941,7 +939,9 @@ and escaped_coq = parse
Output.sublexer_in_doc '['; escaped_coq lexbuf }
| "(*"
{ Tokens.flush_sublexer (); comment_level := 1;
- ignore (comment lexbuf); escaped_coq lexbuf }
+ ignore (if !Cdglobals.parse_comments then comment lexbuf
+ else skipped_comment lexbuf);
+ escaped_coq lexbuf }
| "*)"
{ (* likely to be a syntax error: we escape *) backtrack lexbuf }
| eof
@@ -981,76 +981,101 @@ and comments = parse
| _
{ Output.char (lexeme_char lexbuf 0); comments lexbuf }
-(*s Skip comments *)
+and skipped_comment = parse
+ | "(*"
+ { incr comment_level;
+ skipped_comment lexbuf }
+ | "*)" space* nl
+ { decr comment_level;
+ if !comment_level > 0 then skipped_comment lexbuf else true }
+ | "*)"
+ { decr comment_level;
+ if !comment_level > 0 then skipped_comment lexbuf else false }
+ | eof { false }
+ | _ { skipped_comment lexbuf }
and comment = parse
- | "(*" { incr comment_level;
- if !Cdglobals.parse_comments then Output.start_comment ();
- comment lexbuf }
- | "*)" space* nl {
- if !Cdglobals.parse_comments then
- (Output.end_comment (); Output.line_break ());
- decr comment_level; if !comment_level > 0 then comment lexbuf else true }
- | "*)" {
- if !Cdglobals.parse_comments then (Output.end_comment ());
- decr comment_level; if !comment_level > 0 then comment lexbuf else false }
- | "[" {
- if !Cdglobals.parse_comments then
- if !Cdglobals.plain_comments then Output.char '['
+ | "(*"
+ { incr comment_level;
+ Output.start_comment ();
+ comment lexbuf }
+ | "*)" space* nl
+ { Output.end_comment ();
+ Output.line_break ();
+ decr comment_level;
+ if !comment_level > 0 then comment lexbuf else true }
+ | "*)"
+ { Output.end_comment ();
+ decr comment_level;
+ if !comment_level > 0 then comment lexbuf else false }
+ | "["
+ { if !Cdglobals.plain_comments then Output.char '['
else (brackets := 1; Output.start_inline_coq ();
escaped_coq lexbuf; Output.end_inline_coq ());
- comment lexbuf }
- | "[[" nl {
- if !Cdglobals.parse_comments then
- if !Cdglobals.plain_comments then (Output.char '['; Output.char '[')
+ comment lexbuf }
+ | "[[" nl
+ { if !Cdglobals.plain_comments then (Output.char '['; Output.char '[')
else (formatted := true;
Output.start_inline_coq_block ();
let _ = body_bol lexbuf in
Output.end_inline_coq_block (); formatted := false);
- comment lexbuf}
+ comment lexbuf }
| "$"
- { if !Cdglobals.parse_comments then
- if !Cdglobals.plain_comments then Output.char '$'
- else (Output.start_latex_math (); escaped_math_latex lexbuf);
+ { if !Cdglobals.plain_comments then Output.char '$'
+ else (Output.start_latex_math (); escaped_math_latex lexbuf);
comment lexbuf }
| "$$"
- { if !Cdglobals.parse_comments
- then
- (if !Cdglobals.plain_comments then Output.char '$'; Output.char '$');
- doc None lexbuf }
+ { if !Cdglobals.plain_comments then Output.char '$';
+ Output.char '$';
+ comment lexbuf }
| "%"
- { if !Cdglobals.parse_comments
- then
- if !Cdglobals.plain_comments then Output.char '%'
- else escaped_latex lexbuf; comment lexbuf }
+ { if !Cdglobals.plain_comments then Output.char '%'
+ else escaped_latex lexbuf;
+ comment lexbuf }
| "%%"
- { if !Cdglobals.parse_comments
- then
- (if !Cdglobals.plain_comments then Output.char '%'; Output.char '%');
+ { if !Cdglobals.plain_comments then Output.char '%';
+ Output.char '%';
comment lexbuf }
| "#"
- { if !Cdglobals.parse_comments
- then
- if !Cdglobals.plain_comments then Output.char '$'
- else escaped_html lexbuf; comment lexbuf }
+ { if !Cdglobals.plain_comments then Output.char '#'
+ else escaped_html lexbuf;
+ comment lexbuf }
| "##"
- { if !Cdglobals.parse_comments
- then
- (if !Cdglobals.plain_comments then Output.char '#'; Output.char '#');
+ { if !Cdglobals.plain_comments then Output.char '#';
+ Output.char '#';
comment lexbuf }
| eof { false }
- | space+ { if !Cdglobals.parse_comments
- then Output.indentation (fst (count_spaces (lexeme lexbuf)));
- comment lexbuf }
- | nl { if !Cdglobals.parse_comments
- then Output.line_break (); comment lexbuf }
- | _ { if !Cdglobals.parse_comments then Output.char (lexeme_char lexbuf 0);
- comment lexbuf }
+ | space+
+ { Output.indentation (fst (count_spaces (lexeme lexbuf)));
+ comment lexbuf }
+ | nl
+ { Output.line_break ();
+ comment lexbuf }
+ | _ { Output.char (lexeme_char lexbuf 0);
+ comment lexbuf }
and skip_to_dot = parse
| '.' space* nl { true }
| eof | '.' space+ { false }
- | "(*" { comment_level := 1; ignore (comment lexbuf); skip_to_dot lexbuf }
+ | "(*"
+ { comment_level := 1;
+ ignore (skipped_comment lexbuf);
+ skip_to_dot lexbuf }
+ | _ { skip_to_dot lexbuf }
+
+and skip_to_dot_or_brace = parse
+ | '.' space* nl { true }
+ | eof | '.' space+ { false }
+ | "(*"
+ { comment_level := 1;
+ ignore (skipped_comment lexbuf);
+ skip_to_dot_or_brace lexbuf }
+ | "}" space* nl
+ { true }
+ | "}"
+ { false }
+ | space*
+ { skip_to_dot_or_brace lexbuf }
| _ { skip_to_dot lexbuf }
and body_bol = parse
@@ -1120,12 +1145,18 @@ and body = parse
let eol = doc_bol lexbuf in
Output.end_doc (); Output.start_coq ();
if eol then body_bol lexbuf else body lexbuf }
- | "(*" { Tokens.flush_sublexer(); comment_level := 1;
- if !Cdglobals.parse_comments then Output.start_comment ();
- let eol = comment lexbuf in
- if eol
- then begin if not !Cdglobals.parse_comments then Output.line_break(); body_bol lexbuf end
- else body lexbuf }
+ | "(*"
+ { Tokens.flush_sublexer(); comment_level := 1;
+ let eol =
+ if parse_comments () then begin
+ Output.start_comment ();
+ comment lexbuf
+ end else begin
+ let eol = skipped_comment lexbuf in
+ if eol then Output.line_break();
+ eol
+ end in
+ if eol then body_bol lexbuf else body lexbuf }
| "where"
{ Tokens.flush_sublexer();
Output.ident (lexeme lexbuf) None;
diff --git a/tools/coqdoc/index.ml b/tools/coqdoc/index.ml
index 47acc7b43..9be791a8d 100644
--- a/tools/coqdoc/index.ml
+++ b/tools/coqdoc/index.ml
@@ -77,32 +77,6 @@ let find m l = Hashtbl.find reftable (m, l)
let find_string m s = let (m,s,t) = Hashtbl.find byidtable s in Ref (m,s,t)
-(*s Manipulating path prefixes *)
-
-type stack = string list
-
-let rec string_of_stack st =
- match st with
- | [] -> ""
- | x::[] -> x
- | x::tl -> (string_of_stack tl) ^ "." ^ x
-
-let empty_stack = []
-
-let module_stack = ref empty_stack
-let section_stack = ref empty_stack
-
-let push st p = st := p::!st
-let pop st =
- match !st with
- | [] -> ()
- | _::tl -> st := tl
-
-let head st =
- match st with
- | [] -> ""
- | x::_ -> x
-
(* Coq modules *)
let split_sp s =
diff --git a/tools/coqdoc/output.ml b/tools/coqdoc/output.ml
index 2b2690968..82d3d62b5 100644
--- a/tools/coqdoc/output.ml
+++ b/tools/coqdoc/output.ml
@@ -953,7 +953,7 @@ module TeXmacs = struct
(*s Latex preamble *)
- let (preamble : string Queue.t) =
+ let (_ : string Queue.t) =
in_doc := false; Queue.create ()
let header () =
@@ -1122,7 +1122,6 @@ module Raw = struct
for i = 0 to String.length s - 1 do char s.[i] done
let start_module () = ()
- let end_module () = ()
let start_latex_math () = ()
let stop_latex_math () = ()
diff --git a/tools/fake_ide.ml b/tools/fake_ide.ml
index e81f4038d..221fb36d8 100644
--- a/tools/fake_ide.ml
+++ b/tools/fake_ide.ml
@@ -28,7 +28,8 @@ let error_xml s =
Printf.eprintf "fake_id: error: %a\n%!" print_xml s;
exit 1
-let logger level content = Printf.eprintf "%a\n%! " print_xml content
+let logger level content =
+ Printf.eprintf "%a\n%! " print_xml (Richpp.repr content)
let base_eval_call ?(print=true) ?(fail=true) call coqtop =
if print then prerr_endline (Xmlprotocol.pr_call call);
@@ -36,15 +37,14 @@ let base_eval_call ?(print=true) ?(fail=true) call coqtop =
Xml_printer.print coqtop.xml_printer xml_query;
let rec loop () =
let xml = Xml_parser.parse coqtop.xml_parser in
- if Pp.is_message xml then
- let message = Pp.to_message xml in
- let level = message.Pp.message_level in
- let content = message.Pp.message_content in
+ match Xmlprotocol.is_message xml with
+ | Some (level, content) ->
logger level content;
loop ()
- else if Feedback.is_feedback xml then
- loop ()
- else (Xmlprotocol.to_answer call xml)
+ | None ->
+ if Xmlprotocol.is_feedback xml then
+ loop ()
+ else Xmlprotocol.to_answer call xml
in
let res = loop () in
if print then prerr_endline (Xmlprotocol.pr_full_value call res);
diff --git a/tools/ocamllibdep.mll b/tools/ocamllibdep.mll
index 670ff487c..57fcd5dd2 100644
--- a/tools/ocamllibdep.mll
+++ b/tools/ocamllibdep.mll
@@ -33,10 +33,6 @@ rule mllib_list = parse
open Printf
open Unix
-(** [coqdep_boot] is a stripped-down version of [coqdep] used to treat
- with mllib files.
-*)
-
(* Makefile's escaping rules are awful: $ is escaped by doubling and
other special characters are escaped by backslash prefixing while
backslashes themselves must be escaped only if part of a sequence
@@ -132,6 +128,7 @@ let add_ml_known, search_ml_known = mkknown ()
let add_mlpack_known, search_mlpack_known = mkknown ()
let mllibAccu = ref ([] : (string * dir) list)
+let mlpackAccu = ref ([] : (string * dir) list)
let add_caml_known phys_dir f =
let basename,suff = get_extension f [".ml";".ml4";".mlpack"] in
@@ -148,18 +145,15 @@ let traite_fichier_modules md ext =
let chan = open_in (md ^ ext) in
let list = mllib_list (Lexing.from_channel chan) in
List.fold_left
- (fun a_faire str -> match search_mlpack_known str with
- | Some mldir ->
- let file = file_name str mldir in
- a_faire^" "^file
- | None ->
+ (fun acc str ->
+ match search_mlpack_known str with
+ | Some mldir -> (file_name str mldir) :: acc
+ | None ->
match search_ml_known str with
- | Some mldir ->
- let file = file_name str mldir in
- a_faire^" "^file
- | None -> a_faire) "" list
+ | Some mldir -> (file_name str mldir) :: acc
+ | None -> acc) [] (List.rev list)
with
- | Sys_error _ -> ""
+ | Sys_error _ -> []
| Syntax_error (i,j) -> error_cannot_parse (md^ext) (i,j)
let addQueue q v = q := v :: !q
@@ -167,22 +161,43 @@ let addQueue q v = q := v :: !q
let treat_file old_name =
let name = Filename.basename old_name in
let dirname = Some (Filename.dirname old_name) in
- match get_extension name [".mllib"] with
+ match get_extension name [".mllib";".mlpack"] with
| (base,".mllib") -> addQueue mllibAccu (base,dirname)
+ | (base,".mlpack") -> addQueue mlpackAccu (base,dirname)
| _ -> ()
let mllib_dependencies () =
List.iter
(fun (name,dirname) ->
let fullname = file_name name dirname in
- let dep = traite_fichier_modules fullname ".mllib" in
+ let deps = traite_fichier_modules fullname ".mllib" in
+ let sdeps = String.concat " " deps in
let efullname = escape fullname in
- printf "%s_MLLIB_DEPENDENCIES:=%s\n" efullname dep;
- printf "%s.cma:$(addsuffix .cmo,$(%s_MLLIB_DEPENDENCIES))\n" efullname efullname;
- printf "%s.cmxa %s.cmxs:$(addsuffix .cmx,$(%s_MLLIB_DEPENDENCIES))\n" efullname efullname efullname;
+ printf "%s_MLLIB_DEPENDENCIES:=%s\n" efullname sdeps;
+ printf "%s.cma:$(addsuffix .cmo,$(%s_MLLIB_DEPENDENCIES))\n"
+ efullname efullname;
+ printf "%s.cmxa %s.cmxs:$(addsuffix .cmx,$(%s_MLLIB_DEPENDENCIES))\n"
+ efullname efullname efullname;
flush Pervasives.stdout)
(List.rev !mllibAccu)
+let mlpack_dependencies () =
+ List.iter
+ (fun (name,dirname) ->
+ let fullname = file_name name dirname in
+ let modname = String.capitalize name in
+ let deps = traite_fichier_modules fullname ".mlpack" in
+ let sdeps = String.concat " " deps in
+ let efullname = escape fullname in
+ printf "%s_MLPACK_DEPENDENCIES:=%s\n" efullname sdeps;
+ List.iter (fun d -> printf "%s_FORPACK:= -for-pack %s\n" d modname) deps;
+ printf "%s.cmo:$(addsuffix .cmo,$(%s_MLPACK_DEPENDENCIES))\n"
+ efullname efullname;
+ printf "%s.cmx %s.cmxs:$(addsuffix .cmx,$(%s_MLPACK_DEPENDENCIES))\n"
+ efullname efullname efullname;
+ flush Pervasives.stdout)
+ (List.rev !mlpackAccu)
+
let rec parse = function
| "-I" :: r :: ll ->
(* To solve conflict (e.g. same filename in kernel and checker)
@@ -192,10 +207,11 @@ let rec parse = function
| f :: ll -> treat_file f; parse ll
| [] -> ()
-let coqdep_boot () =
+let main () =
if Array.length Sys.argv < 2 then exit 1;
parse (List.tl (Array.to_list Sys.argv));
- mllib_dependencies ()
+ mllib_dependencies ();
+ mlpack_dependencies ()
-let _ = Printexc.catch coqdep_boot ()
+let _ = Printexc.catch main ()
}
diff --git a/toplevel/assumptions.ml b/toplevel/assumptions.ml
index b29ceb78b..1802b2d36 100644
--- a/toplevel/assumptions.ml
+++ b/toplevel/assumptions.ml
@@ -142,8 +142,6 @@ let label_of = function
| ConstructRef ((kn,_),_) -> pi3 (repr_mind kn)
| VarRef id -> Label.of_id id
-let push (r : Context.Rel.Declaration.t) (ctx : Context.Rel.t) = r :: ctx
-
let rec traverse current ctx accu t = match kind_of_term t with
| Var id ->
let body () = Global.lookup_named id |> get_value in
@@ -151,13 +149,13 @@ let rec traverse current ctx accu t = match kind_of_term t with
| Const (kn, _) ->
let body () = Global.body_of_constant_body (lookup_constant kn) in
traverse_object accu body (ConstRef kn)
-| Ind (ind, _) ->
- traverse_object accu (fun () -> None) (IndRef ind)
-| Construct (cst, _) ->
- traverse_object accu (fun () -> None) (ConstructRef cst)
+| Ind ((mind, _) as ind, _) ->
+ traverse_inductive accu mind (IndRef ind)
+| Construct (((mind, _), _) as cst, _) ->
+ traverse_inductive accu mind (ConstructRef cst)
| Meta _ | Evar _ -> assert false
| Case (_,oty,c,[||]) ->
- (* non dependent match on an inductive with no constructors *)
+ (* non dependent match on an inductive with no constructors *)
begin match Constr.(kind oty, kind c) with
| Lambda(_,_,oty), Const (kn, _)
when Vars.noccurn 1 oty &&
@@ -166,9 +164,11 @@ let rec traverse current ctx accu t = match kind_of_term t with
traverse_object
~inhabits:(current,ctx,Vars.subst1 mkProp oty) accu body (ConstRef kn)
| _ ->
- Termops.fold_constr_with_full_binders push (traverse current) ctx accu t
+ Termops.fold_constr_with_full_binders
+ Context.Rel.add (traverse current) ctx accu t
end
-| _ -> Termops.fold_constr_with_full_binders push (traverse current) ctx accu t
+| _ -> Termops.fold_constr_with_full_binders
+ Context.Rel.add (traverse current) ctx accu t
and traverse_object ?inhabits (curr, data, ax2ty) body obj =
let data, ax2ty =
@@ -186,14 +186,87 @@ and traverse_object ?inhabits (curr, data, ax2ty) body obj =
| Some body ->
if already_in then data, ax2ty else
let contents,data,ax2ty =
- traverse (label_of obj) [] (Refset_env.empty,data,ax2ty) body in
+ traverse (label_of obj) Context.Rel.empty
+ (Refset_env.empty,data,ax2ty) body in
Refmap_env.add obj contents data, ax2ty
in
(Refset_env.add obj curr, data, ax2ty)
+(** Collects the references occurring in the declaration of mutual inductive
+ definitions. All the constructors and names of a mutual inductive
+ definition share exactly the same dependencies. Also, there is no explicit
+ dependency between mutually defined inductives and constructors. *)
+and traverse_inductive (curr, data, ax2ty) mind obj =
+ let firstind_ref = (IndRef (mind, 0)) in
+ let label = label_of obj in
+ let data, ax2ty =
+ (* Invariant : I_0 \in data iff I_i \in data iff c_ij \in data
+ where I_0, I_1, ... are in the same mutual definition and c_ij
+ are all their constructors. *)
+ if Refmap_env.mem firstind_ref data then data, ax2ty else
+ let mib = Global.lookup_mind mind in
+ (* Collects references of parameters *)
+ let param_ctx = mib.mind_params_ctxt in
+ let nparam = List.length param_ctx in
+ let accu =
+ traverse_context label Context.Rel.empty
+ (Refset_env.empty, data, ax2ty) param_ctx
+ in
+ (* Build the context of all arities *)
+ let arities_ctx =
+ let global_env = Global.env () in
+ Array.fold_left (fun accu oib ->
+ let pspecif = Univ.in_punivs (mib, oib) in
+ let ind_type = Inductive.type_of_inductive global_env pspecif in
+ let ind_name = Name oib.mind_typename in
+ Context.Rel.add (Context.Rel.Declaration.LocalAssum (ind_name, ind_type)) accu)
+ Context.Rel.empty mib.mind_packets
+ in
+ (* For each inductive, collects references in their arity and in the type
+ of constructors*)
+ let (contents, data, ax2ty) = Array.fold_left (fun accu oib ->
+ let arity_wo_param =
+ List.rev (List.skipn nparam (List.rev oib.mind_arity_ctxt))
+ in
+ let accu =
+ traverse_context
+ label param_ctx accu arity_wo_param
+ in
+ Array.fold_left (fun accu cst_typ ->
+ let param_ctx, cst_typ_wo_param = Term.decompose_prod_n_assum nparam cst_typ in
+ let ctx = Context.(Rel.fold_outside Context.Rel.add ~init:arities_ctx param_ctx) in
+ traverse label ctx accu cst_typ_wo_param)
+ accu oib.mind_user_lc)
+ accu mib.mind_packets
+ in
+ (* Maps all these dependencies to inductives and constructors*)
+ let data = Array.fold_left_i (fun n data oib ->
+ let ind = (mind, n) in
+ let data = Refmap_env.add (IndRef ind) contents data in
+ Array.fold_left_i (fun k data _ ->
+ Refmap_env.add (ConstructRef (ind, k+1)) contents data
+ ) data oib.mind_consnames) data mib.mind_packets
+ in
+ data, ax2ty
+ in
+ (Refset_env.add obj curr, data, ax2ty)
+
+(** Collects references in a rel_context. *)
+and traverse_context current ctx accu ctxt =
+ snd (Context.Rel.fold_outside (fun decl (ctx, accu) ->
+ match decl with
+ | Context.Rel.Declaration.LocalDef (_,c,t) ->
+ let accu = traverse current ctx (traverse current ctx accu t) c in
+ let ctx = Context.Rel.add decl ctx in
+ ctx, accu
+ | Context.Rel.Declaration.LocalAssum (_,t) ->
+ let accu = traverse current ctx accu t in
+ let ctx = Context.Rel.add decl ctx in
+ ctx, accu) ctxt ~init:(ctx, accu))
+
let traverse current t =
let () = modcache := MPmap.empty in
- traverse current [] (Refset_env.empty, Refmap_env.empty, Refmap_env.empty) t
+ traverse current Context.Rel.empty (Refset_env.empty, Refmap_env.empty, Refmap_env.empty) t
(** Hopefully bullet-proof function to recover the type of a constant. It just
ignores all the universe stuff. There are many issues that can arise when
diff --git a/toplevel/cerrors.ml b/toplevel/cerrors.ml
index 600683d35..0bb7966d7 100644
--- a/toplevel/cerrors.ml
+++ b/toplevel/cerrors.ml
@@ -35,7 +35,7 @@ let explain_exn_default = function
(* Basic interaction exceptions *)
| Stream.Error txt -> hov 0 (str "Syntax error: " ++ str txt ++ str ".")
| Compat.Token.Error txt -> hov 0 (str "Syntax error: " ++ str txt ++ str ".")
- | Lexer.Error.E err -> hov 0 (str (Lexer.Error.to_string err))
+ | CLexer.Error.E err -> hov 0 (str (CLexer.Error.to_string err))
| Sys_error msg -> hov 0 (str "System error: " ++ guill msg)
| Out_of_memory -> hov 0 (str "Out of memory.")
| Stack_overflow -> hov 0 (str "Stack overflow.")
@@ -110,6 +110,11 @@ let rec strip_wrapping_exceptions = function
strip_wrapping_exceptions e
| exc -> exc
+let additional_error_info = ref []
+
+let register_additional_error_info f =
+ additional_error_info := f :: !additional_error_info
+
let process_vernac_interp_error ?(allow_uncaught=true) ?(with_header=true) (exc, info) =
let exc = strip_wrapping_exceptions exc in
let e = process_vernac_interp_error with_header (exc, info) in
@@ -120,19 +125,12 @@ let process_vernac_interp_error ?(allow_uncaught=true) ?(with_header=true) (exc,
let err = Errors.make_anomaly msg in
Util.iraise (err, info)
in
- let ltac_trace = Exninfo.get info Proof_type.ltac_trace_info in
- let loc = Option.default Loc.ghost (Loc.get_loc info) in
- match ltac_trace with
+ let e' =
+ try Some (CList.find_map (fun f -> f e) !additional_error_info)
+ with _ -> None
+ in
+ match e' with
| None -> e
- | Some trace ->
- let (e, info) = e in
- match Himsg.extract_ltac_trace trace loc with
- | None, loc -> (e, Loc.add_loc info loc)
- | Some msg, loc ->
- (EvaluatedError (msg, Some e), Loc.add_loc info loc)
-
-let _ = Tactic_debug.explain_logic_error :=
- (fun e -> Errors.print (fst (process_vernac_interp_error (e, Exninfo.null))))
-
-let _ = Tactic_debug.explain_logic_error_no_anomaly :=
- (fun e -> Errors.print_no_report (fst (process_vernac_interp_error (e, Exninfo.null))))
+ | Some (None, loc) -> (fst e, Loc.add_loc (snd e) loc)
+ | Some (Some msg, loc) ->
+ (EvaluatedError (msg, Some (fst e)), Loc.add_loc (snd e) loc)
diff --git a/toplevel/cerrors.mli b/toplevel/cerrors.mli
index 68c46010b..a0e3e3c19 100644
--- a/toplevel/cerrors.mli
+++ b/toplevel/cerrors.mli
@@ -19,3 +19,4 @@ val process_vernac_interp_error : ?allow_uncaught:bool -> ?with_header:bool -> U
val explain_exn_default : exn -> Pp.std_ppcmds
+val register_additional_error_info : (Util.iexn -> (Pp.std_ppcmds option * Loc.t) option) -> unit
diff --git a/toplevel/class.ml b/toplevel/class.ml
index a9c53b4d4..10e9b30be 100644
--- a/toplevel/class.ml
+++ b/toplevel/class.ml
@@ -262,7 +262,7 @@ let add_new_coercion_core coef stre poly source target isid =
in
check_source (Some cls);
if not (uniform_cond (llp-ind) lvs) then
- msg_warning (explain_coercion_error coef NotUniform);
+ Feedback.msg_warning (explain_coercion_error coef NotUniform);
let clt =
try
get_target tg ind
@@ -310,7 +310,7 @@ let add_coercion_hook poly local ref =
in
let () = try_add_new_coercion ref stre poly in
let msg = pr_global_env Id.Set.empty ref ++ str " is now a coercion" in
- Flags.if_verbose msg_info msg
+ Flags.if_verbose Feedback.msg_info msg
let add_coercion_hook poly = Lemmas.mk_hook (add_coercion_hook poly)
diff --git a/toplevel/classes.ml b/toplevel/classes.ml
index 898ef0d9e..235732b52 100644
--- a/toplevel/classes.ml
+++ b/toplevel/classes.ml
@@ -121,7 +121,7 @@ let declare_instance_constant k pri global imps ?hook id pl poly evm term termty
instance_hook k pri global imps ?hook (ConstRef kn);
id
-let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) props
+let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance) poly ctx (instid, bk, cl) props
?(generalize=true)
?(tac:unit Proofview.tactic option) ?hook pri =
let env = Global.env() in
@@ -191,14 +191,14 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
let t = it_mkProd_or_LetIn ty_constr (ctx' @ ctx) in
nf t
in
- Evarutil.check_evars env Evd.empty !evars termtype;
+ Pretyping.check_evars env Evd.empty !evars termtype;
let pl, ctx = Evd.universe_context ?names:pl !evars in
let cst = Declare.declare_constant ~internal:Declare.InternalTacticRequest id
(ParameterEntry
(None,poly,(termtype,ctx),None), Decl_kinds.IsAssumption Decl_kinds.Logical)
in
Universes.register_universe_binders (ConstRef cst) pl;
- instance_hook k None global imps ?hook (ConstRef cst); id
+ instance_hook k pri global imps ?hook (ConstRef cst); id
end
else (
let props =
@@ -287,13 +287,13 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
let evm, nf = Evarutil.nf_evar_map_universes !evars in
let termtype = nf termtype in
let _ = (* Check that the type is free of evars now. *)
- Evarutil.check_evars env Evd.empty evm termtype
+ Pretyping.check_evars env Evd.empty evm termtype
in
let term = Option.map nf term in
if not (Evd.has_undefined evm) && not (Option.is_empty term) then
declare_instance_constant k pri global imps ?hook id pl
poly evm (Option.get term) termtype
- else if Flags.is_program_mode () || !refine_instance || Option.is_empty term then begin
+ else if Flags.is_program_mode () || refine || Option.is_empty term then begin
let kind = Decl_kinds.Global, poly, Decl_kinds.DefinitionBody Decl_kinds.Instance in
if Flags.is_program_mode () then
let hook vis gr _ =
@@ -330,7 +330,7 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
if not (Option.is_empty term) then
let init_refine =
Tacticals.New.tclTHENLIST [
- Proofview.Refine.refine { run = fun evm -> Sigma (Option.get term, evm, Sigma.refl) };
+ Refine.refine { run = fun evm -> Sigma (Option.get term, evm, Sigma.refl) };
Proofview.Unsafe.tclNEWGOALS gls;
Tactics.New.reduce_after_refine;
]
@@ -361,7 +361,7 @@ let context poly l =
let _, ((env', fullctx), impls) = interp_context_evars env evars l in
let subst = Evarutil.evd_comb0 Evarutil.nf_evars_and_universes evars in
let fullctx = Context.Rel.map subst fullctx in
- let ce t = Evarutil.check_evars env Evd.empty !evars t in
+ let ce t = Pretyping.check_evars env Evd.empty !evars t in
let () = List.iter (fun decl -> Context.Rel.Declaration.iter_constr ce decl) fullctx in
let ctx =
try named_of_rel_context fullctx
diff --git a/toplevel/classes.mli b/toplevel/classes.mli
index a3e948d96..7beb873e6 100644
--- a/toplevel/classes.mli
+++ b/toplevel/classes.mli
@@ -40,6 +40,7 @@ val declare_instance_constant :
val new_instance :
?abstract:bool -> (** Not abstract by default. *)
?global:bool -> (** Not global by default. *)
+ ?refine:bool -> (** Allow refinement *)
Decl_kinds.polymorphic ->
local_binder list ->
typeclass_constraint ->
diff --git a/toplevel/command.ml b/toplevel/command.ml
index 284bcd75e..f0f678e08 100644
--- a/toplevel/command.ml
+++ b/toplevel/command.ml
@@ -13,7 +13,6 @@ open Flags
open Term
open Vars
open Termops
-open Entries
open Environ
open Redexpr
open Declare
@@ -120,7 +119,7 @@ let interp_definition pl bl p red_option c ctypopt =
impl_eq (List.assoc_f Pervasives.(=) key impsty) va (* FIXME *)
in
if not (try List.for_all chk imps2 with Not_found -> false)
- then msg_warning
+ then Feedback.msg_warning
(strbrk "Implicit arguments declaration relies on type." ++ spc () ++
strbrk "The term declares more implicits than the type here.");
let vars = Univ.LSet.union (Universes.universes_of_constr body)
@@ -141,7 +140,7 @@ let get_locality id = function
| Discharge ->
(** If a Let is defined outside a section, then we consider it as a local definition *)
let msg = pr_id id ++ strbrk " is declared as a local definition" in
- let () = msg_warning msg in
+ let () = Feedback.msg_warning msg in
true
| Local -> true
| Global -> false
@@ -172,7 +171,7 @@ let declare_definition ident (local, p, k) ce pl imps hook =
let () = if Pfedit.refining () then
let msg = strbrk "Section definition " ++
pr_id ident ++ strbrk " is not visible from current goals" in
- msg_warning msg
+ Feedback.msg_warning msg
in
gr
| Discharge | Local | Global ->
@@ -218,7 +217,7 @@ match local with
let () = assumption_message ident in
let () =
if is_verbose () && Pfedit.refining () then
- msg_warning (str"Variable" ++ spc () ++ pr_id ident ++
+ Feedback.msg_warning (str"Variable" ++ spc () ++ pr_id ident ++
strbrk " is not visible from current goals")
in
let r = VarRef ident in
@@ -707,7 +706,7 @@ let declare_mutual_inductive_with_eliminations mie pl impls =
constrimpls)
impls;
let warn_prim = match mie.mind_entry_record with Some (Some _) -> not prim | _ -> false in
- if_verbose msg_info (minductive_message warn_prim names);
+ if_verbose Feedback.msg_info (minductive_message warn_prim names);
if mie.mind_entry_private == None
then declare_default_schemes mind;
mind
@@ -800,7 +799,7 @@ let check_mutuality env isfix fixl =
let po = partial_order Id.equal preorder in
match List.filter (function (_,Inr _) -> true | _ -> false) po with
| (x,Inr xge)::(y,Inr yge)::rest ->
- msg_warning (non_full_mutual_message x xge y yge isfix rest)
+ Feedback.msg_warning (non_full_mutual_message x xge y yge isfix rest)
| _ -> ()
type structured_fixpoint_expr = {
@@ -877,7 +876,7 @@ let well_founded = init_constant ["Init"; "Wf"] "well_founded"
let mkSubset name typ prop =
mkApp (Universes.constr_of_global (delayed_force build_sigma).typ,
[| typ; mkLambda (name, typ, prop) |])
-let sigT = Lazy.lazy_from_fun build_sigma_type
+let sigT = Lazy.from_fun build_sigma_type
let make_qref s = Qualid (Loc.ghost, qualid_of_string s)
let lt_ref = make_qref "Init.Peano.lt"
diff --git a/toplevel/coqinit.ml b/toplevel/coqinit.ml
index b81c8da71..65c5917b7 100644
--- a/toplevel/coqinit.ml
+++ b/toplevel/coqinit.ml
@@ -36,7 +36,7 @@ let load_rcfile() =
else raise (Sys_error ("Cannot read rcfile: "^ !rcfile))
else
try
- let warn x = msg_warning (str x) in
+ let warn x = Feedback.msg_warning (str x) in
let inferedrc = List.find CUnix.file_readable_p [
Envars.xdg_config_home warn / rcdefaultname^"."^Coq_config.version;
Envars.xdg_config_home warn / rcdefaultname;
@@ -52,10 +52,10 @@ let load_rcfile() =
*)
with reraise ->
let reraise = Errors.push reraise in
- let () = msg_info (str"Load of rcfile failed.") in
+ let () = Feedback.msg_info (str"Load of rcfile failed.") in
iraise reraise
else
- Flags.if_verbose msg_info (str"Skipping rcfile loading.")
+ Flags.if_verbose Feedback.msg_info (str"Skipping rcfile loading.")
(* Recursively puts dir in the LoadPath if -nois was not passed *)
let add_stdlib_path ~unix_path ~coq_root ~with_ml =
@@ -78,7 +78,7 @@ let push_ml_include s = ml_includes := s :: !ml_includes
let init_load_path () =
let coqlib = Envars.coqlib () in
let user_contrib = coqlib/"user-contrib" in
- let xdg_dirs = Envars.xdg_dirs ~warn:(fun x -> msg_warning (str x)) in
+ let xdg_dirs = Envars.xdg_dirs ~warn:(fun x -> Feedback.msg_warning (str x)) in
let coqpath = Envars.coqpath in
let coq_root = Names.DirPath.make [Nameops.coq_root] in
(* NOTE: These directories are searched from last to first *)
@@ -127,7 +127,7 @@ let init_ocaml_path () =
[ [ "config" ]; [ "dev" ]; [ "lib" ]; [ "kernel" ]; [ "library" ];
[ "engine" ]; [ "pretyping" ]; [ "interp" ]; [ "parsing" ]; [ "proofs" ];
[ "tactics" ]; [ "toplevel" ]; [ "printing" ]; [ "intf" ];
- [ "grammar" ]; [ "ide" ] ]
+ [ "grammar" ]; [ "ide" ]; [ "ltac" ]; ]
let get_compat_version = function
| "8.5" -> Flags.Current
@@ -135,6 +135,6 @@ let get_compat_version = function
| "8.3" -> Flags.V8_3
| "8.2" -> Flags.V8_2
| ("8.1" | "8.0") as s ->
- msg_warning (str "Compatibility with version " ++ str s ++ str " not supported.");
+ Feedback.msg_warning (str "Compatibility with version " ++ str s ++ str " not supported.");
Flags.V8_2
| s -> Errors.errorlabstrm "get_compat_version" (str "Unknown compatibility version \"" ++ str s ++ str "\".")
diff --git a/toplevel/coqloop.ml b/toplevel/coqloop.ml
index 063ed8964..c8879963e 100644
--- a/toplevel/coqloop.ml
+++ b/toplevel/coqloop.ml
@@ -13,6 +13,8 @@ open Flags
open Vernac
open Pcoq
+let top_stderr x = msg_with !Pp_control.err_ft x
+
(* A buffer for the character read from a channel. We store the command
* entered to be able to report errors without pretty-printing. *)
@@ -59,7 +61,7 @@ let prompt_char ic ibuf count =
| ll::_ -> Int.equal ibuf.len ll
| [] -> Int.equal ibuf.len 0
in
- if bol && not !print_emacs then msgerr (str (ibuf.prompt()));
+ if bol && not !print_emacs then top_stderr (str (ibuf.prompt()));
try
let c = input_char ic in
if c == '\n' then ibuf.bols <- (ibuf.len+1) :: ibuf.bols;
@@ -288,7 +290,7 @@ let rec discard_to_dot () =
try
Gram.entry_parse parse_to_dot top_buffer.tokens
with
- | Compat.Token.Error _ | Lexer.Error.E _ -> discard_to_dot ()
+ | Compat.Token.Error _ | CLexer.Error.E _ -> discard_to_dot ()
| End_of_input -> raise End_of_input
| e when Errors.noncritical e -> ()
@@ -310,23 +312,23 @@ let read_sentence () =
*)
let do_vernac () =
- msgerrnl (mt ());
- if !print_emacs then msgerr (str (top_buffer.prompt()));
+ top_stderr (fnl());
+ if !print_emacs then top_stderr (str (top_buffer.prompt()));
resynch_buffer top_buffer;
try
Vernac.eval_expr (read_sentence ())
with
| End_of_input | Errors.Quit ->
- msgerrnl (mt ()); pp_flush(); raise Errors.Quit
+ top_stderr (fnl ()); raise Errors.Quit
| Errors.Drop -> (* Last chance *)
if Mltop.is_ocaml_top() then raise Errors.Drop
- else ppnl (str"Error: There is no ML toplevel." ++ fnl ())
+ else Feedback.msg_error (str"There is no ML toplevel.")
| any ->
let any = Errors.push any in
Format.set_formatter_out_channel stdout;
let msg = print_toplevel_error any ++ fnl () in
pp_with ~pp_tag:Ppstyle.pp_tag !Pp_control.std_ft msg;
- pp_flush ()
+ flush_all ()
(** Main coq loop : read vernacular expressions until Drop is entered.
Ctrl-C is handled internally as Sys.Break instead of aborting Coq.
@@ -354,7 +356,7 @@ let rec loop () =
| Errors.Drop -> ()
| Errors.Quit -> exit 0
| any ->
- msgerrnl (str"Anomaly: main loop exited with exception: " ++
+ Feedback.msg_error (str"Anomaly: main loop exited with exception: " ++
str (Printexc.to_string any) ++
fnl() ++ str"Please report.");
loop ()
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index f46b90111..a820008d2 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -9,7 +9,6 @@
open Pp
open Errors
open Util
-open System
open Flags
open Names
open Libnames
@@ -32,10 +31,10 @@ let get_version_date () =
let print_header () =
let (ver,rev) = get_version_date () in
- ppnl (str "Welcome to Coq " ++ str ver ++ str " (" ++ str rev ++ str ")");
- pp_flush ()
+ Feedback.msg_notice (str "Welcome to Coq " ++ str ver ++ str " (" ++ str rev ++ str ")");
+ flush_all ()
-let warning s = with_option Flags.warn msg_warning (strbrk s)
+let warning s = with_option Flags.warn Feedback.msg_warning (strbrk s)
let toploop = ref None
@@ -62,7 +61,8 @@ let init_color () =
match colors with
| None ->
(** Default colors *)
- Ppstyle.init_color_output ()
+ Ppstyle.init_color_output ();
+ Feedback.set_logger Feedback.color_terminal_logger
| Some "" ->
(** No color output *)
()
@@ -70,7 +70,8 @@ let init_color () =
(** Overwrite all colors *)
Ppstyle.clear_styles ();
Ppstyle.parse_config s;
- Ppstyle.init_color_output ()
+ Ppstyle.init_color_output ();
+ Feedback.set_logger Feedback.color_terminal_logger
end
let toploop_init = ref begin fun x ->
@@ -96,8 +97,8 @@ let memory_stat = ref false
let print_memory_stat () =
begin (* -m|--memory from the command-line *)
if !memory_stat then
- ppnl
- (str "total heap size = " ++ int (CObj.heap_size_kb ()) ++ str " kbytes");
+ Feedback.msg_notice
+ (str "total heap size = " ++ int (CObj.heap_size_kb ()) ++ str " kbytes" ++ fnl ());
end;
begin
(* operf-macro interface:
@@ -142,7 +143,7 @@ let remove_top_ml () = Mltop.remove ()
let inputstate = ref ""
let set_inputstate s =
- let () = msg_warning (str "The inputstate option is deprecated and discouraged.") in
+ let () = Feedback.msg_warning (str "The inputstate option is deprecated and discouraged.") in
inputstate:=s
let inputstate () =
if not (String.is_empty !inputstate) then
@@ -151,7 +152,7 @@ let inputstate () =
let outputstate = ref ""
let set_outputstate s =
- let () = msg_warning (str "The outputstate option is deprecated and discouraged.") in
+ let () = Feedback.msg_warning (str "The outputstate option is deprecated and discouraged.") in
outputstate:=s
let outputstate () =
if not (String.is_empty !outputstate) then
@@ -230,22 +231,37 @@ let compile_files () =
| [vf] -> compile_file vf (* One compilation : no need to save init state *)
| l ->
let init_state = States.freeze ~marshallable:`No in
- let coqdoc_init_state = Lexer.location_table () in
+ let coqdoc_init_state = CLexer.location_table () in
List.iter
(fun vf ->
States.unfreeze init_state;
- Lexer.restore_location_table coqdoc_init_state;
+ CLexer.restore_location_table coqdoc_init_state;
compile_file vf)
(List.rev l)
(** Options for proof general *)
let set_emacs () =
+ if not (Option.is_empty !toploop) then
+ error "Flag -emacs is incompatible with a custom toplevel loop";
Flags.print_emacs := true;
- Pp.make_pp_emacs ();
+ Feedback.(set_logger emacs_logger);
Vernacentries.qed_display_script := false;
color := `OFF
+(** Options for CoqIDE *)
+
+let set_ideslave () =
+ if !Flags.print_emacs then error "Flags -ideslave and -emacs are incompatible";
+ toploop := Some "coqidetop";
+ Flags.ide_slave := true
+
+(** Options for slaves *)
+
+let set_toploop name =
+ if !Flags.print_emacs then error "Flags -toploop and -emacs are incompatible";
+ toploop := Some name
+
(** GC tweaking *)
(** Coq is a heavy user of persistent data structures and symbolic ASTs, so the
@@ -354,6 +370,11 @@ let get_int opt n =
with Failure _ ->
prerr_endline ("Error: integer expected after option "^opt); exit 1
+let get_float opt n =
+ try float_of_string n
+ with Failure _ ->
+ prerr_endline ("Error: float expected after option "^opt); exit 1
+
let get_host_port opt s =
match CString.split ':' s with
| [host; portr; portw] ->
@@ -363,6 +384,11 @@ let get_host_port opt s =
prerr_endline ("Error: host:port or stdfds expected after option "^opt);
exit 1
+let get_error_resilience opt = function
+ | "on" | "all" | "yes" -> `All
+ | "off" | "no" -> `None
+ | s -> `Only (String.split ',' s)
+
let get_task_list s = List.map int_of_string (Str.split (Str.regexp ",") s)
let vio_tasks = ref []
@@ -476,6 +502,12 @@ let parse_args arglist =
Flags.async_proofs_worker_priority := get_priority opt (next ())
|"-async-proofs-private-flags" ->
Flags.async_proofs_private_flags := Some (next ());
+ |"-async-proofs-tactic-error-resilience" ->
+ Flags.async_proofs_tac_error_resilience := get_error_resilience opt (next ())
+ |"-async-proofs-command-error-resilience" ->
+ Flags.async_proofs_cmd_error_resilience := get_bool opt (next ())
+ |"-async-proofs-delegation-threshold" ->
+ Flags.async_proofs_delegation_threshold:= get_float opt (next ())
|"-worker-id" -> set_worker_id opt (next ())
|"-compat" -> let v = get_compat_version (next ()) in Flags.compat_version := v; add_compat_require v
|"-compile" -> add_compile false (next ())
@@ -498,8 +530,9 @@ let parse_args arglist =
|"-main-channel" -> Spawned.main_channel := get_host_port opt (next())
|"-control-channel" -> Spawned.control_channel := get_host_port opt (next())
|"-vio2vo" -> add_compile false (next ()); Flags.compilation_mode := Vio2Vo
- |"-toploop" -> toploop := Some (next ())
+ |"-toploop" -> set_toploop (next ())
|"-w" -> set_warning (next ())
+ |"-o" -> Flags.compilation_output_name := Some (next())
(* Options with zero arg *)
|"-async-queries-always-delegate"
@@ -519,7 +552,7 @@ let parse_args arglist =
|"-emacs" -> set_emacs ()
|"-filteropts" -> filter_opts := true
|"-h"|"-H"|"-?"|"-help"|"--help" -> usage ()
- |"-ideslave" -> toploop := Some "coqidetop"; Flags.ide_slave := true
+ |"-ideslave" -> set_ideslave ()
|"-impredicative-set" -> set_impredicative_set ()
|"-indices-matter" -> Indtypes.enforce_indices_matter ()
|"-just-parsing" -> Vernac.just_parsing := true
@@ -533,6 +566,7 @@ let parse_args arglist =
else native_compiler := true
|"-notop" -> unset_toplevel_name ()
|"-output-context" -> output_context := true
+ |"-profile-ltac" -> Flags.profile_ltac := true
|"-q" -> no_load_rc ()
|"-quiet"|"-silent" -> Flags.make_silent true; Flags.make_warn false
|"-quick" -> Flags.compilation_mode := BuildVio
@@ -632,7 +666,7 @@ let init_toplevel arglist =
if !batch_mode then begin
flush_all();
if !output_context then
- Pp.ppnl (with_option raw_print Prettyp.print_full_pure_context ());
+ Feedback.msg_notice (with_option raw_print Prettyp.print_full_pure_context () ++ fnl ());
Profile.print_profile ();
exit 0
end
diff --git a/toplevel/discharge.ml b/toplevel/discharge.ml
index ffa11679c..6b267283a 100644
--- a/toplevel/discharge.ml
+++ b/toplevel/discharge.ml
@@ -11,7 +11,6 @@ open Errors
open Util
open Term
open Vars
-open Entries
open Declarations
open Cooking
open Entries
diff --git a/toplevel/himsg.ml b/toplevel/himsg.ml
index de7ec61c8..e17cd2086 100644
--- a/toplevel/himsg.ml
+++ b/toplevel/himsg.ml
@@ -69,12 +69,21 @@ let rec contract3' env a b c = function
let (env',t1,t2) = contract2 env' t1 t2 in
contract3 env a b c, ConversionFailed (env',t1,t2)
| NotSameArgSize | NotSameHead | NoCanonicalStructure
- | MetaOccurInBody _ | InstanceNotSameType _
+ | MetaOccurInBody _ | InstanceNotSameType _ | ProblemBeyondCapabilities
| UnifUnivInconsistency _ as x -> contract3 env a b c, x
- | CannotSolveConstraint ((pb,env,t,u),x) ->
- let env,t,u = contract2 env t u in
+ | CannotSolveConstraint ((pb,env',t,u),x) ->
+ let env',t,u = contract2 env' t u in
let y,x = contract3' env a b c x in
- y,CannotSolveConstraint ((pb,env,t,u),x)
+ y,CannotSolveConstraint ((pb,env',t,u),x)
+
+(** Ad-hoc reductions *)
+
+let j_nf_betaiotaevar sigma j =
+ { uj_val = Evarutil.nf_evar sigma j.uj_val;
+ uj_type = Reductionops.nf_betaiota sigma j.uj_type }
+
+let jv_nf_betaiotaevar sigma jl =
+ Array.map (j_nf_betaiotaevar sigma) jl
(** Printers *)
@@ -314,6 +323,8 @@ let explain_unification_error env sigma p1 p2 = function
(strbrk "cannot satisfy constraint " ++ pr_lconstr_env env sigma t ++
str " == " ++ pr_lconstr_env env sigma u)
:: aux t u e
+ | ProblemBeyondCapabilities ->
+ []
in
match aux p1 p2 e with
| [] -> mt ()
@@ -322,7 +333,7 @@ let explain_unification_error env sigma p1 p2 = function
let explain_actual_type env sigma j t reason =
let env = make_all_name_different env in
- let j = Evarutil.j_nf_betaiotaevar sigma j in
+ let j = j_nf_betaiotaevar sigma j in
let t = Reductionops.nf_betaiota sigma t in
(** Actually print *)
let pe = pr_ne_context_of (str "In environment") env sigma in
@@ -337,7 +348,7 @@ let explain_actual_type env sigma j t reason =
ppreason ++ str ".")
let explain_cant_apply_bad_type env sigma (n,exptyp,actualtyp) rator randl =
- let randl = Evarutil.jv_nf_betaiotaevar sigma randl in
+ let randl = jv_nf_betaiotaevar sigma randl in
let exptyp = Evarutil.nf_evar sigma exptyp in
let actualtyp = Reductionops.nf_betaiota sigma actualtyp in
let rator = Evarutil.j_nf_evar sigma rator in
@@ -779,7 +790,7 @@ let explain_unsatisfiable_constraints env sigma constr comp =
explain_typeclass_resolution env sigma info k ++ fnl () ++ cstr
let explain_pretype_error env sigma err =
- let env = Evarutil.env_nf_betaiotaevar sigma env in
+ let env = Evardefine.env_nf_betaiotaevar sigma env in
let env = make_all_name_different env in
match err with
| CantFindCaseType c -> explain_cant_find_case_type env sigma c
@@ -1244,77 +1255,3 @@ let explain_reduction_tactic_error = function
quote (pr_goal_concl_style_env env sigma c) ++
spc () ++ str "is not well typed." ++ fnl () ++
explain_type_error env' Evd.empty e
-
-let is_defined_ltac trace =
- let rec aux = function
- | (_, Proof_type.LtacNameCall f) :: tail ->
- not (Tacenv.is_ltac_for_ml_tactic f)
- | (_, Proof_type.LtacAtomCall _) :: tail ->
- false
- | _ :: tail -> aux tail
- | [] -> false in
- aux (List.rev trace)
-
-let explain_ltac_call_trace last trace loc =
- let calls = last :: List.rev_map snd trace in
- let pr_call ck = match ck with
- | Proof_type.LtacNotationCall kn -> quote (KerName.print kn)
- | Proof_type.LtacNameCall cst -> quote (Pptactic.pr_ltac_constant cst)
- | Proof_type.LtacMLCall t ->
- quote (Pptactic.pr_glob_tactic (Global.env()) t)
- | Proof_type.LtacVarCall (id,t) ->
- quote (Nameops.pr_id id) ++ strbrk " (bound to " ++
- Pptactic.pr_glob_tactic (Global.env()) t ++ str ")"
- | Proof_type.LtacAtomCall te ->
- quote (Pptactic.pr_glob_tactic (Global.env())
- (Tacexpr.TacAtom (Loc.ghost,te)))
- | Proof_type.LtacConstrInterp (c, { Pretyping.ltac_constrs = vars }) ->
- quote (pr_glob_constr_env (Global.env()) c) ++
- (if not (Id.Map.is_empty vars) then
- strbrk " (with " ++
- prlist_with_sep pr_comma
- (fun (id,c) ->
- pr_id id ++ str ":=" ++ Printer.pr_lconstr_under_binders c)
- (List.rev (Id.Map.bindings vars)) ++ str ")"
- else mt())
- in
- match calls with
- | [] -> mt ()
- | _ ->
- let kind_of_last_call = match List.last calls with
- | Proof_type.LtacConstrInterp _ -> ", last term evaluation failed."
- | _ -> ", last call failed."
- in
- hov 0 (str "In nested Ltac calls to " ++
- pr_enum pr_call calls ++ strbrk kind_of_last_call)
-
-let skip_extensions trace =
- let rec aux = function
- | (_,Proof_type.LtacNameCall f as tac) :: _
- when Tacenv.is_ltac_for_ml_tactic f -> [tac]
- | (_,(Proof_type.LtacNotationCall _ | Proof_type.LtacMLCall _) as tac)
- :: _ -> [tac]
- | t :: tail -> t :: aux tail
- | [] -> [] in
- List.rev (aux (List.rev trace))
-
-let extract_ltac_trace trace eloc =
- let trace = skip_extensions trace in
- let (loc,c),tail = List.sep_last trace in
- if is_defined_ltac trace then
- (* 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 eloc ++ fnl()) in
- Some msg, loc
- else
- (* We entered a primitive tactic, we don't display trace but
- report on the finest location *)
- let best_loc =
- if not (Loc.is_ghost eloc) then eloc else
- (* trace is with innermost call coming first *)
- let rec aux = function
- | (loc,_)::tail when not (Loc.is_ghost loc) -> loc
- | _::tail -> aux tail
- | [] -> Loc.ghost in
- aux trace in
- None, best_loc
diff --git a/toplevel/himsg.mli b/toplevel/himsg.mli
index 3ef98380b..ced54fd27 100644
--- a/toplevel/himsg.mli
+++ b/toplevel/himsg.mli
@@ -36,9 +36,6 @@ val explain_pattern_matching_error :
val explain_reduction_tactic_error :
Tacred.reduction_tactic_error -> std_ppcmds
-val extract_ltac_trace :
- Proof_type.ltac_trace -> Loc.t -> std_ppcmds option * Loc.t
-
val explain_module_error : Modops.module_typing_error -> std_ppcmds
val explain_module_internalization_error :
diff --git a/toplevel/indschemes.ml b/toplevel/indschemes.ml
index 251d14af7..f995a390c 100644
--- a/toplevel/indschemes.ml
+++ b/toplevel/indschemes.ml
@@ -150,13 +150,15 @@ let alarm what internal msg =
| UserAutomaticRequest
| InternalTacticRequest ->
(if debug then
- msg_warning
- (hov 0 msg ++ fnl () ++ what ++ str " not defined."))
- | _ -> errorlabstrm "" msg
+ Feedback.msg_warning
+ (hov 0 msg ++ fnl () ++ what ++ str " not defined.")); None
+ | _ -> Some msg
let try_declare_scheme what f internal names kn =
try f internal names kn
- with
+ with e ->
+ let e = Errors.push e in
+ let msg = match fst e with
| ParameterWithoutEquality cst ->
alarm what internal
(str "Boolean equality not found for parameter " ++ pr_con cst ++
@@ -187,6 +189,11 @@ let try_declare_scheme what f internal names kn =
| e when Errors.noncritical e ->
alarm what internal
(str "Unexpected error during scheme creation: " ++ Errors.print e)
+ | _ -> iraise e
+ in
+ match msg with
+ | None -> ()
+ | Some msg -> iraise (UserError ("", msg), snd e)
let beq_scheme_msg mind =
let mib = Global.lookup_mind mind in
@@ -296,7 +303,7 @@ let declare_congr_scheme ind =
then
ignore (define_individual_scheme congr_scheme_kind UserAutomaticRequest None ind)
else
- msg_warning (strbrk "Cannot build congruence scheme because eq is not found")
+ Feedback.msg_warning (strbrk "Cannot build congruence scheme because eq is not found")
end
let declare_sym_scheme ind =
diff --git a/toplevel/locality.ml b/toplevel/locality.ml
index ef789aa5c..c4c891b89 100644
--- a/toplevel/locality.ml
+++ b/toplevel/locality.ml
@@ -35,7 +35,7 @@ let enforce_locality_full locality_flag local =
Errors.error "Use only prefix \"Local\"."
| None ->
if local then begin
- Pp.msg_warning (Pp.str "Obsolete syntax: use \"Local\" as a prefix.");
+ Feedback.msg_warning (Pp.str "Obsolete syntax: use \"Local\" as a prefix.");
Some true
end else
None
diff --git a/toplevel/metasyntax.ml b/toplevel/metasyntax.ml
index 98d1a2377..b22d53f54 100644
--- a/toplevel/metasyntax.ml
+++ b/toplevel/metasyntax.ml
@@ -23,7 +23,6 @@ open Vernacexpr
open Pcoq
open Libnames
open Tok
-open Egramml
open Egramcoq
open Notation
open Nameops
@@ -31,7 +30,7 @@ open Nameops
(**********************************************************************)
(* Tokens *)
-let cache_token (_,s) = Lexer.add_keyword s
+let cache_token (_,s) = CLexer.add_keyword s
let inToken : string -> obj =
declare_object {(default_object "TOKEN") with
@@ -43,200 +42,6 @@ let inToken : string -> obj =
let add_token_obj s = Lib.add_anonymous_leaf (inToken s)
(**********************************************************************)
-(* Tactic Notation *)
-
-let interp_prod_item lev = function
- | TacTerm s -> GramTerminal s
- | TacNonTerm (loc, nt, (_, sep)) ->
- let EntryName (etyp, e) = interp_entry_name (TgTactic lev) nt sep in
- GramNonTerminal (loc, etyp, e)
-
-let make_terminal_status = function
- | GramTerminal s -> Some s
- | GramNonTerminal _ -> None
-
-let make_fresh_key =
- let id = Summary.ref ~name:"TACTIC-NOTATION-COUNTER" 0 in
- fun () ->
- let cur = incr id; !id in
- let lbl = Id.of_string ("_" ^ string_of_int cur) in
- let kn = Lib.make_kn lbl in
- let (mp, dir, _) = KerName.repr kn in
- (** We embed the full path of the kernel name in the label so that the
- identifier should be unique. This ensures that including two modules
- together won't confuse the corresponding labels. *)
- let lbl = Id.of_string_soft (Printf.sprintf "%s#%s#%i"
- (ModPath.to_string mp) (DirPath.to_string dir) cur)
- in
- KerName.make mp dir (Label.of_id lbl)
-
-type tactic_grammar_obj = {
- tacobj_key : KerName.t;
- tacobj_local : locality_flag;
- tacobj_tacgram : tactic_grammar;
- tacobj_tacpp : Pptactic.pp_tactic;
- tacobj_body : Id.t list * Tacexpr.glob_tactic_expr;
-}
-
-let check_key key =
- if Tacenv.check_alias key then
- error "Conflicting tactic notations keys. This can happen when including \
- twice the same module."
-
-let cache_tactic_notation (_, tobj) =
- let key = tobj.tacobj_key in
- let () = check_key key in
- Tacenv.register_alias key tobj.tacobj_body;
- Egramcoq.extend_tactic_grammar key tobj.tacobj_tacgram;
- Pptactic.declare_notation_tactic_pprule key tobj.tacobj_tacpp
-
-let open_tactic_notation i (_, tobj) =
- let key = tobj.tacobj_key in
- if Int.equal i 1 && not tobj.tacobj_local then
- Egramcoq.extend_tactic_grammar key tobj.tacobj_tacgram
-
-let load_tactic_notation i (_, tobj) =
- let key = tobj.tacobj_key in
- let () = check_key key in
- (** Only add the printing and interpretation rules. *)
- Tacenv.register_alias key tobj.tacobj_body;
- Pptactic.declare_notation_tactic_pprule key tobj.tacobj_tacpp;
- if Int.equal i 1 && not tobj.tacobj_local then
- Egramcoq.extend_tactic_grammar key tobj.tacobj_tacgram
-
-let subst_tactic_notation (subst, tobj) =
- let (ids, body) = tobj.tacobj_body in
- { tobj with
- tacobj_key = Mod_subst.subst_kn subst tobj.tacobj_key;
- tacobj_body = (ids, Tacsubst.subst_tactic subst body);
- }
-
-let classify_tactic_notation tacobj = Substitute tacobj
-
-let inTacticGrammar : tactic_grammar_obj -> obj =
- declare_object {(default_object "TacticGrammar") with
- open_function = open_tactic_notation;
- load_function = load_tactic_notation;
- cache_function = cache_tactic_notation;
- subst_function = subst_tactic_notation;
- classify_function = classify_tactic_notation}
-
-let cons_production_parameter = function
-| TacTerm _ -> None
-| TacNonTerm (_, _, (id, _)) -> Some id
-
-let add_tactic_notation (local,n,prods,e) =
- let ids = List.map_filter cons_production_parameter prods in
- let prods = List.map (interp_prod_item n) prods in
- let pprule = {
- Pptactic.pptac_level = n;
- pptac_prods = prods;
- } in
- let tac = Tacintern.glob_tactic_env ids (Global.env()) e in
- let parule = {
- tacgram_level = n;
- tacgram_prods = prods;
- } in
- let tacobj = {
- tacobj_key = make_fresh_key ();
- tacobj_local = local;
- tacobj_tacgram = parule;
- tacobj_tacpp = pprule;
- tacobj_body = (ids, tac);
- } in
- Lib.add_anonymous_leaf (inTacticGrammar tacobj)
-
-(**********************************************************************)
-(* ML Tactic entries *)
-
-type ml_tactic_grammar_obj = {
- mltacobj_name : Tacexpr.ml_tactic_name;
- (** ML-side unique name *)
- mltacobj_prod : Tacexpr.raw_tactic_expr grammar_prod_item list list;
- (** Grammar rules generating the ML tactic. *)
-}
-
-exception NonEmptyArgument
-
-let default_empty_value wit = match Genarg.default_empty_value wit with
-| None -> raise NonEmptyArgument
-| Some v -> v
-
-let rec empty_value : type a b c s. (a, b, c) Genarg.genarg_type -> (s, a) entry_key -> a =
-fun wit key -> match key with
-| Alist1 key ->
- begin match wit with
- | Genarg.ListArg wit -> [empty_value wit key]
- | Genarg.ExtraArg _ -> default_empty_value wit
- end
-| Alist1sep (key, _) ->
- begin match wit with
- | Genarg.ListArg wit -> [empty_value wit key]
- | Genarg.ExtraArg _ -> default_empty_value wit
- end
-| Alist0 _ -> []
-| Alist0sep (_, _) -> []
-| Amodifiers _ -> []
-| Aopt _ -> None
-| Aentry _ -> default_empty_value wit
-| Aentryl (_, _) -> default_empty_value wit
-
-| Atoken _ -> raise NonEmptyArgument
-| Aself -> raise NonEmptyArgument
-| Anext -> raise NonEmptyArgument
-
-(** ML tactic notations whose use can be restricted to an identifier are added
- as true Ltac entries. *)
-let extend_atomic_tactic name entries =
- let map_prod prods =
- let (hd, rem) = match prods with
- | GramTerminal s :: rem -> (s, rem)
- | _ -> assert false (** Not handled by the ML extension syntax *)
- in
- let empty_value = function
- | GramTerminal s -> raise NonEmptyArgument
- | GramNonTerminal (_, typ, e) ->
- let Genarg.Rawwit wit = typ in
- let def = Genarg.in_gen typ (empty_value wit e) in
- Tacintern.intern_genarg Tacintern.fully_empty_glob_sign def
- in
- try Some (hd, List.map empty_value rem) with NonEmptyArgument -> None
- in
- let entries = List.map map_prod entries in
- let add_atomic i args = match args with
- | None -> ()
- | Some (id, args) ->
- let open Tacexpr in
- let args = List.map (fun a -> TacGeneric a) args in
- let entry = { mltac_name = name; mltac_index = i } in
- let body = TacML (Loc.ghost, entry, args) in
- Tacenv.register_ltac false false (Names.Id.of_string id) body
- in
- List.iteri add_atomic entries
-
-let cache_ml_tactic_notation (_, obj) =
- extend_ml_tactic_grammar obj.mltacobj_name obj.mltacobj_prod
-
-let open_ml_tactic_notation i obj =
- if Int.equal i 1 then cache_ml_tactic_notation obj
-
-let inMLTacticGrammar : ml_tactic_grammar_obj -> obj =
- declare_object { (default_object "MLTacticGrammar") with
- open_function = open_ml_tactic_notation;
- cache_function = cache_ml_tactic_notation;
- classify_function = (fun o -> Substitute o);
- subst_function = (fun (_, o) -> o);
- }
-
-let add_ml_tactic_notation name prods =
- let obj = {
- mltacobj_name = name;
- mltacobj_prod = prods;
- } in
- Lib.add_anonymous_leaf (inMLTacticGrammar obj);
- extend_atomic_tactic name prods
-
-(**********************************************************************)
(* Printing grammar entries *)
let entry_buf = Buffer.create 64
@@ -467,7 +272,7 @@ let rec interp_list_parser hd = function
(* To protect alphabetic tokens and quotes from being seen as variables *)
let quote_notation_token x =
let n = String.length x in
- let norm = Lexer.is_ident x in
+ let norm = CLexer.is_ident x in
if (n > 0 && norm) || (n > 2 && x.[0] == '\'') then "'"^x^"'"
else x
@@ -475,7 +280,7 @@ let rec raw_analyze_notation_tokens = function
| [] -> []
| String ".." :: sl -> NonTerminal ldots_var :: raw_analyze_notation_tokens sl
| String "_" :: _ -> error "_ must be quoted."
- | String x :: sl when Lexer.is_ident x ->
+ | String x :: sl when CLexer.is_ident x ->
NonTerminal (Names.Id.of_string x) :: raw_analyze_notation_tokens sl
| String s :: sl ->
Terminal (String.drop_simple_quotes s) :: raw_analyze_notation_tokens sl
@@ -763,8 +568,8 @@ let is_not_small_constr = function
let rec define_keywords_aux = function
| GramConstrNonTerminal(e,Some _) as n1 :: GramConstrTerminal(IDENT k) :: l
when is_not_small_constr e ->
- Flags.if_verbose msg_info (str "Identifier '" ++ str k ++ str "' now a keyword");
- Lexer.add_keyword k;
+ Flags.if_verbose Feedback.msg_info (str "Identifier '" ++ str k ++ str "' now a keyword");
+ CLexer.add_keyword k;
n1 :: GramConstrTerminal(KEYWORD k) :: define_keywords_aux l
| n :: l -> n :: define_keywords_aux l
| [] -> []
@@ -772,8 +577,8 @@ let rec define_keywords_aux = function
(* Ensure that IDENT articulation terminal symbols are keywords *)
let define_keywords = function
| GramConstrTerminal(IDENT k)::l ->
- Flags.if_verbose msg_info (str "Identifier '" ++ str k ++ str "' now a keyword");
- Lexer.add_keyword k;
+ Flags.if_verbose Feedback.msg_info (str "Identifier '" ++ str k ++ str "' now a keyword");
+ CLexer.add_keyword k;
GramConstrTerminal(KEYWORD k) :: define_keywords_aux l
| l -> define_keywords_aux l
@@ -802,12 +607,12 @@ let make_production etyps symbols =
let typ = List.assoc m etyps in
distribute [GramConstrNonTerminal (typ, Some m)] ll
| Terminal s ->
- distribute [GramConstrTerminal (Lexer.terminal s)] ll
+ distribute [GramConstrTerminal (CLexer.terminal s)] ll
| Break _ ->
ll
| SProdList (x,sl) ->
let tkl = List.flatten
- (List.map (function Terminal s -> [Lexer.terminal s]
+ (List.map (function Terminal s -> [CLexer.terminal s]
| Break _ -> []
| _ -> anomaly (Pp.str "Found a non terminal token in recursive notation separator")) sl) in
match List.assoc x etyps with
@@ -1022,7 +827,7 @@ let make_interpretation_type isrec isonlybinding = function
| NtnInternTypeConstr | NtnInternTypeIdent ->
if isonlybinding then NtnTypeOnlyBinder else NtnTypeConstr
| NtnInternTypeBinder when isrec -> NtnTypeBinderList
- | NtnInternTypeBinder -> error "Type not allowed in recursive notation."
+ | NtnInternTypeBinder -> error "Type binder is only for use in recursive notations for binders."
let make_interpretation_vars recvars allvars =
let eq_subscope (sc1, l1) (sc2, l2) =
@@ -1042,7 +847,7 @@ let make_interpretation_vars recvars allvars =
(sc, make_interpretation_type (Id.List.mem_assoc x recvars) isonlybinding typ)) mainvars
let check_rule_productivity l =
- if List.for_all (function NonTerminal _ -> true | _ -> false) l then
+ if List.for_all (function NonTerminal _ | Break _ -> true | _ -> false) l then
error "A notation must include at least one symbol.";
if (match l with SProdList _ :: _ -> true | _ -> false) then
error "A recursive notation must start with at least one symbol."
@@ -1050,25 +855,38 @@ let check_rule_productivity l =
let is_not_printable onlyparse noninjective = function
| NVar _ ->
let () = if not onlyparse then
- msg_warning (strbrk "This notation will not be used for printing as it is bound to a single variable.")
+ Feedback.msg_warning (strbrk "This notation will not be used for printing as it is bound to a single variable.")
in
true
| _ ->
if not onlyparse && noninjective then
- let () = msg_warning (strbrk "This notation will not be used for printing as it is not reversible.") in
+ let () = Feedback.msg_warning (strbrk "This notation will not be used for printing as it is not reversible.") in
true
else onlyparse
let find_precedence lev etyps symbols =
- match symbols with
- | NonTerminal x :: _ ->
+ let first_symbol =
+ let rec aux = function
+ | Break _ :: t -> aux t
+ | h :: t -> h
+ | [] -> assert false (* rule is known to be productive *) in
+ aux symbols in
+ let last_is_terminal () =
+ let rec aux b = function
+ | Break _ :: t -> aux b t
+ | Terminal _ :: t -> aux true t
+ | _ :: t -> aux false t
+ | [] -> b in
+ aux false symbols in
+ match first_symbol with
+ | NonTerminal x ->
(try match List.assoc x etyps with
| ETConstr _ ->
error "The level of the leftmost non-terminal cannot be changed."
| ETName | ETBigint | ETReference ->
begin match lev with
| None ->
- ([msg_info,strbrk "Setting notation at level 0."],0)
+ ([Feedback.msg_info,strbrk "Setting notation at level 0."],0)
| Some 0 ->
([],0)
| _ ->
@@ -1084,11 +902,9 @@ let find_precedence lev etyps symbols =
if Option.is_empty lev then
error "A left-recursive notation must have an explicit level."
else [],Option.get lev)
- | Terminal _ ::l when
- (match List.last symbols with Terminal _ -> true |_ -> false)
- ->
+ | Terminal _ when last_is_terminal () ->
if Option.is_empty lev then
- ([msg_info,strbrk "Setting notation at level 0."], 0)
+ ([Feedback.msg_info,strbrk "Setting notation at level 0."], 0)
else [],Option.get lev
| _ ->
if Option.is_empty lev then error "Cannot determine the level.";
@@ -1115,7 +931,7 @@ let remove_curly_brackets l =
(match next' with
| Terminal "}" as t2 :: l'' as l1 ->
if not (List.equal Notation.symbol_eq l l0) || not (List.equal Notation.symbol_eq l' l1) then
- msg_warning (strbrk "Skipping spaces inside curly brackets");
+ Feedback.msg_warning (strbrk "Skipping spaces inside curly brackets");
if deb && List.is_empty l'' then [t1;x;t2] else begin
check_curly_brackets_notation_exists ();
x :: aux false l''
@@ -1160,7 +976,7 @@ let compute_pure_syntax_data df mods =
let (msgs,(onlyparse,_,_,_),_,sy_data,extra) = compute_syntax_data df mods in
let msgs =
if onlyparse then
- (msg_warning,
+ (Feedback.msg_warning,
strbrk "The only parsing modifier has no effect in Reserved Notation.")::msgs
else msgs in
msgs, sy_data, extra
@@ -1493,12 +1309,7 @@ let add_syntactic_definition ident (vars,c) local onlyparse =
} in
let nvars, pat = interp_notation_constr nenv c in
let () = nonprintable := nenv.ninterp_only_parse in
- let map id =
- let (isonlybinding,sc, _) = Id.Map.find id nvars in
- (* if a notation contains an ltac:, the body is not analyzed
- and onlybinding detection fails *)
- assert (!nonprintable || not isonlybinding);
- (id, sc) in
+ let map id = let (_,sc,_) = Id.Map.find id nvars in (id, sc) in
List.map map vars, pat
in
let onlyparse = match onlyparse with
diff --git a/toplevel/metasyntax.mli b/toplevel/metasyntax.mli
index 5d01405b2..085cc87c8 100644
--- a/toplevel/metasyntax.mli
+++ b/toplevel/metasyntax.mli
@@ -15,15 +15,6 @@ open Notation_term
val add_token_obj : string -> unit
-(** Adding a tactic notation in the environment *)
-
-val add_tactic_notation :
- locality_flag * int * grammar_tactic_prod_item_expr list * raw_tactic_expr ->
- unit
-
-val add_ml_tactic_notation : ml_tactic_name ->
- Tacexpr.raw_tactic_expr Egramml.grammar_prod_item list list -> unit
-
(** Adding a (constr) notation in the environment*)
val add_infix : locality_flag -> (lstring * syntax_modifier list) ->
diff --git a/toplevel/mltop.ml b/toplevel/mltop.ml
index d0fa7a80c..36c16208c 100644
--- a/toplevel/mltop.ml
+++ b/toplevel/mltop.ml
@@ -146,7 +146,7 @@ let dir_ml_load s =
let dir_ml_use s =
match !load with
| WithTop t -> t.use_file s
- | _ -> msg_warning (str "Cannot access the ML compiler")
+ | _ -> Feedback.msg_warning (str "Cannot access the ML compiler")
(* Adds a path to the ML paths *)
let add_ml_dir s =
@@ -164,7 +164,7 @@ let add_rec_ml_dir unix_path =
let convert_string d =
try Names.Id.of_string d
with UserError _ ->
- msg_warning (str "Directory " ++ str d ++ str " cannot be used as a Coq identifier (skipped)");
+ Feedback.msg_warning (str "Directory " ++ str d ++ str " cannot be used as a Coq identifier (skipped)");
raise Exit
let add_rec_path ~unix_path ~coq_root ~implicit =
@@ -184,7 +184,7 @@ let add_rec_path ~unix_path ~coq_root ~implicit =
let () = List.iter add dirs in
Loadpath.add_load_path unix_path ~implicit coq_root
else
- msg_warning (str "Cannot open " ++ str unix_path)
+ Feedback.msg_warning (str "Cannot open " ++ str unix_path)
(* convertit un nom quelconque en nom de fichier ou de module *)
let mod_of_name name =
@@ -324,10 +324,10 @@ let if_verbose_load verb f name ?path fname =
let info = str "[Loading ML file " ++ str fname ++ str " ..." in
try
let path = f name ?path fname in
- msg_info (info ++ str " done]");
+ Feedback.msg_info (info ++ str " done]");
path
with reraise ->
- msg_info (info ++ str " failed]");
+ Feedback.msg_info (info ++ str " failed]");
raise reraise
(** Load a module for the first time (i.e. dynlink it)
diff --git a/toplevel/obligations.ml b/toplevel/obligations.ml
index 0e8d224e4..dbc3ccaac 100644
--- a/toplevel/obligations.ml
+++ b/toplevel/obligations.ml
@@ -24,7 +24,7 @@ let declare_fix_ref = ref (fun ?opaque _ _ _ _ _ _ -> assert false)
let declare_definition_ref = ref (fun _ _ _ _ _ -> assert false)
let trace s =
- if !Flags.debug then msg_debug s
+ if !Flags.debug then Feedback.msg_debug s
else ()
let succfix (depth, fixrels) =
@@ -314,17 +314,16 @@ type program_info_aux = {
prg_sign: named_context_val;
}
-type program_info = program_info_aux Ephemeron.key
+type program_info = program_info_aux CEphemeron.key
let get_info x =
- try Ephemeron.get x
- with Ephemeron.InvalidKey ->
+ try CEphemeron.get x
+ with CEphemeron.InvalidKey ->
Errors.anomaly Pp.(str "Program obligation can't be accessed by a worker")
let assumption_message = Declare.assumption_message
-let (set_default_tactic, get_default_tactic, print_default_tactic) =
- Tactic_option.declare_tactic_option "Program tactic"
+let default_tactic = ref (Proofview.tclUNIT ())
(* true = All transparent, false = Opaque if possible *)
let proofs_transparency = ref true
@@ -449,9 +448,9 @@ let subst_deps_obl obls obl =
let t' = subst_deps true obls obl.obl_deps obl.obl_type in
{ obl with obl_type = t' }
-module ProgMap = Map.Make(Id)
+module ProgMap = Id.Map
-let map_replace k v m = ProgMap.add k (Ephemeron.create v) (ProgMap.remove k m)
+let map_replace k v m = ProgMap.add k (CEphemeron.create v) (ProgMap.remove k m)
let map_keys m = ProgMap.fold (fun k _ l -> k :: l) m []
@@ -675,7 +674,7 @@ let init_prog_info ?(opaque = false) sign n pl b t ctx deps fixkind
let map_cardinal m =
let i = ref 0 in
ProgMap.iter (fun _ v ->
- if snd (Ephemeron.get v).prg_obligations > 0 then incr i) m;
+ if snd (CEphemeron.get v).prg_obligations > 0 then incr i) m;
!i
exception Found of program_info
@@ -683,7 +682,7 @@ exception Found of program_info
let map_first m =
try
ProgMap.iter (fun _ v ->
- if snd (Ephemeron.get v).prg_obligations > 0 then
+ if snd (CEphemeron.get v).prg_obligations > 0 then
raise (Found v)) m;
assert(false)
with Found x -> x
@@ -699,11 +698,13 @@ let get_prog name =
match n with
0 -> raise (NoObligations None)
| 1 -> get_info (map_first prg_infos)
- | _ ->
- error ("More than one program with unsolved obligations: "^
- String.concat ", "
- (List.map string_of_id
- (ProgMap.fold (fun k _ s -> k::s) prg_infos []))))
+ | _ ->
+ let progs = Id.Set.elements (ProgMap.domain prg_infos) in
+ let prog = List.hd progs in
+ let progs = prlist_with_sep pr_comma Nameops.pr_id progs in
+ errorlabstrm ""
+ (str "More than one program with unsolved obligations: " ++ progs
+ ++ str "; use the \"of\" clause to specify, as in \"Obligation 1 of " ++ Nameops.pr_id prog ++ str "\""))
let get_any_prog () =
let prg_infos = !from_prg in
@@ -730,11 +731,11 @@ type progress =
let obligations_message rem =
if rem > 0 then
if Int.equal rem 1 then
- Flags.if_verbose msg_info (int rem ++ str " obligation remaining")
+ Flags.if_verbose Feedback.msg_info (int rem ++ str " obligation remaining")
else
- Flags.if_verbose msg_info (int rem ++ str " obligations remaining")
+ Flags.if_verbose Feedback.msg_info (int rem ++ str " obligations remaining")
else
- Flags.if_verbose msg_info (str "No more obligations remaining")
+ Flags.if_verbose Feedback.msg_info (str "No more obligations remaining")
let update_obls prg obls rem =
let prg' = { prg with prg_obligations = (obls, rem) } in
@@ -895,7 +896,7 @@ let rec solve_obligation prg num tac =
let () = Lemmas.start_proof_univs ~sign:prg.prg_sign obl.obl_name kind evd obl.obl_type ~terminator hook in
let () = trace (str "Started obligation " ++ int user_num ++ str " proof: " ++
Printer.pr_constr_env (Global.env ()) Evd.empty obl.obl_type) in
- let _ = Pfedit.by (snd (get_default_tactic ())) in
+ let _ = Pfedit.by !default_tactic in
Option.iter (fun tac -> Pfedit.set_end_tac tac) tac
and obligation (user_num, name, typ) tac =
@@ -924,7 +925,7 @@ and solve_obligation_by_tac prg obls i tac =
| None ->
match obl.obl_tac with
| Some t -> t
- | None -> snd (get_default_tactic ())
+ | None -> !default_tactic
in
let evd = Evd.from_ctx !prg.prg_ctx in
let evd = Evd.update_sigma_env evd (Global.env ()) in
@@ -991,7 +992,7 @@ and try_solve_obligations n tac =
try ignore (solve_obligations n tac) with NoObligations _ -> ()
and auto_solve_obligations n ?oblset tac : progress =
- Flags.if_verbose msg_info (str "Solving obligations automatically...");
+ Flags.if_verbose Feedback.msg_info (str "Solving obligations automatically...");
try solve_prg_obligations (get_prog_err n) ?oblset tac with NoObligations _ -> Dependent
open Pp
@@ -999,13 +1000,13 @@ let show_obligations_of_prg ?(msg=true) prg =
let n = prg.prg_name in
let obls, rem = prg.prg_obligations in
let showed = ref 5 in
- if msg then msg_info (int rem ++ str " obligation(s) remaining: ");
+ if msg then Feedback.msg_info (int rem ++ str " obligation(s) remaining: ");
Array.iteri (fun i x ->
match x.obl_body with
| None ->
if !showed > 0 then (
decr showed;
- msg_info (str "Obligation" ++ spc() ++ int (succ i) ++ spc () ++
+ Feedback.msg_info (str "Obligation" ++ spc() ++ int (succ i) ++ spc () ++
str "of" ++ spc() ++ Id.print n ++ str ":" ++ spc () ++
hov 1 (Printer.pr_constr_env (Global.env ()) Evd.empty x.obl_type ++
str "." ++ fnl ())))
@@ -1034,13 +1035,13 @@ let add_definition n ?term t ctx ?pl ?(implicits=[]) ?(kind=Global,false,Definit
let prg = init_prog_info sign ~opaque n pl term t ctx [] None [] obls implicits kind reduce hook in
let obls,_ = prg.prg_obligations in
if Int.equal (Array.length obls) 0 then (
- Flags.if_verbose msg_info (info ++ str ".");
+ Flags.if_verbose Feedback.msg_info (info ++ str ".");
let cst = declare_definition prg in
Defined cst)
else (
let len = Array.length obls in
- let _ = Flags.if_verbose msg_info (info ++ str ", generating " ++ int len ++ str " obligation(s)") in
- progmap_add n (Ephemeron.create prg);
+ let _ = Flags.if_verbose Feedback.msg_info (info ++ str ", generating " ++ int len ++ str " obligation(s)") in
+ progmap_add n (CEphemeron.create prg);
let res = auto_solve_obligations (Some n) tactic in
match res with
| Remain rem -> Flags.if_verbose (fun () -> show_obligations ~msg:false (Some n)) (); res
@@ -1054,7 +1055,7 @@ let add_mutual_definitions l ctx ?pl ?tactic ?(kind=Global,false,Definition) ?(r
(fun (n, b, t, imps, obls) ->
let prg = init_prog_info sign ~opaque n pl (Some b) t ctx deps (Some fixkind)
notations obls imps kind reduce hook
- in progmap_add n (Ephemeron.create prg)) l;
+ in progmap_add n (CEphemeron.create prg)) l;
let _defined =
List.fold_left (fun finished x ->
if finished then finished
diff --git a/toplevel/obligations.mli b/toplevel/obligations.mli
index e257da016..3e99f5760 100644
--- a/toplevel/obligations.mli
+++ b/toplevel/obligations.mli
@@ -54,10 +54,8 @@ type progress = (* Resolution status of a program *)
| Remain of int (* n obligations remaining *)
| Dependent (* Dependent on other definitions *)
| Defined of global_reference (* Defined as id *)
-
-val set_default_tactic : bool -> Tacexpr.glob_tactic_expr -> unit
-val get_default_tactic : unit -> locality_flag * unit Proofview.tactic
-val print_default_tactic : unit -> Pp.std_ppcmds
+
+val default_tactic : unit Proofview.tactic ref
val set_proofs_transparency : bool -> unit (* true = All transparent, false = Opaque if possible *)
val get_proofs_transparency : unit -> bool
diff --git a/toplevel/record.ml b/toplevel/record.ml
index c0bb9eb86..0c3bd953c 100644
--- a/toplevel/record.ml
+++ b/toplevel/record.ml
@@ -26,7 +26,6 @@ open Constrexpr_ops
open Goptions
open Sigma.Notations
open Context.Rel.Declaration
-open Entries
(********** definition d'un record (structure) **************)
@@ -119,13 +118,13 @@ let typecheck_params_and_fields def id pl t ps nots fs =
(match kind_of_term sred with
| Sort s' ->
(match Evd.is_sort_variable !evars s' with
- | Some l -> evars := Evd.make_flexible_variable !evars true (* (not def) *) l;
+ | Some l -> evars := Evd.make_flexible_variable !evars true l;
sred, true
| None -> s, false)
| _ -> user_err_loc (constr_loc t,"", str"Sort expected."))
| None ->
- let uvarkind = if (* not def *) true then Evd.univ_flexible_alg else Evd.univ_flexible in
- mkSort (Evarutil.evd_comb0 (Evd.new_sort_variable uvarkind) evars), false
+ let uvarkind = Evd.univ_flexible_alg in
+ mkSort (Evarutil.evd_comb0 (Evd.new_sort_variable uvarkind) evars), true
in
let fullarity = it_mkProd_or_LetIn t' newps in
let env_ar = push_rel_context newps (push_rel (LocalAssum (Name id,fullarity)) env0) in
@@ -140,22 +139,23 @@ let typecheck_params_and_fields def id pl t ps nots fs =
let _, univ = compute_constructor_level evars env_ar newfs in
let ctx, aritysort = Reduction.dest_arity env0 arity in
assert(List.is_empty ctx); (* Ensured by above analysis *)
- if Sorts.is_prop aritysort ||
- (Sorts.is_set aritysort && is_impredicative_set env0) then
+ if not def && (Sorts.is_prop aritysort ||
+ (Sorts.is_set aritysort && is_impredicative_set env0)) then
arity, evars
else
let evars = Evd.set_leq_sort env_ar evars (Type univ) aritysort in
- if Univ.is_small_univ univ then
- (* We can assume that the level aritysort is not constrained
- and clear it. *)
- mkArity (ctx, Sorts.sort_of_univ univ),
- Evd.set_eq_sort env_ar evars (Prop Pos) aritysort
- else arity, evars
+ if Univ.is_small_univ univ &&
+ Option.cata (Evd.is_flexible_level evars) false (Evd.is_sort_variable evars aritysort) then
+ (* We can assume that the level in aritysort is not constrained
+ and clear it, if it is flexible *)
+ mkArity (ctx, Sorts.sort_of_univ univ),
+ Evd.set_eq_sort env_ar evars (Prop Pos) aritysort
+ else arity, evars
in
let evars, nf = Evarutil.nf_evars_and_universes evars in
let newps = Context.Rel.map nf newps in
let newfs = Context.Rel.map nf newfs in
- let ce t = Evarutil.check_evars env0 Evd.empty evars t in
+ let ce t = Pretyping.check_evars env0 Evd.empty evars t in
List.iter (iter_constr ce) (List.rev newps);
List.iter (iter_constr ce) (List.rev newfs);
Evd.universe_context ?names:pl evars, nf arity, template, imps, newps, impls, newfs
@@ -196,7 +196,7 @@ let warning_or_error coe indsp err =
(pr_id fi ++ strbrk " cannot be defined because it is not typable.")
in
if coe then errorlabstrm "structure" st;
- Flags.if_verbose msg_warning (hov 0 st)
+ Flags.if_verbose Feedback.msg_warning (hov 0 st)
type field_status =
| NoProjection of Name.t
@@ -262,7 +262,7 @@ let declare_projections indsp ?(kind=StructureComponent) binder_name coers field
| Some None | None -> false
in
if not is_primitive then
- Flags.if_verbose msg_warning
+ Flags.if_verbose Feedback.msg_warning
(hov 0 (str "The record " ++ Printer.pr_inductive env indsp ++
str" could not be defined as a primitive record"));
is_primitive
@@ -418,9 +418,9 @@ let declare_class finite def poly ctx id idbuild paramimpls params arity
match fields with
| [LocalAssum (Name proj_name, field) | LocalDef (Name proj_name, _, field)] when def ->
let class_body = it_mkLambda_or_LetIn field params in
- let _class_type = it_mkProd_or_LetIn arity params in
+ let class_type = it_mkProd_or_LetIn arity params in
let class_entry =
- Declare.definition_entry (* ?types:class_type *) ~poly ~univs:ctx class_body in
+ Declare.definition_entry ~types:class_type ~poly ~univs:ctx class_body in
let cst = Declare.declare_constant (snd id)
(DefinitionEntry class_entry, IsDefinition Definition)
in
diff --git a/toplevel/search.ml b/toplevel/search.ml
index 646e2e08a..e670b59b7 100644
--- a/toplevel/search.ml
+++ b/toplevel/search.ml
@@ -257,10 +257,10 @@ let search_about gopt items mods =
format_display !ans
type search_constraint =
- | Name_Pattern of string
- | Type_Pattern of string
- | SubType_Pattern of string
- | In_Module of string list
+ | Name_Pattern of Str.regexp
+ | Type_Pattern of Pattern.constr_pattern
+ | SubType_Pattern of Pattern.constr_pattern
+ | In_Module of Names.DirPath.t
| Include_Blacklist
type 'a coq_object = {
@@ -269,40 +269,21 @@ type 'a coq_object = {
coq_object_object : 'a;
}
-let interface_search flags =
- let env = Global.env () in
+let interface_search =
let rec extract_flags name tpe subtpe mods blacklist = function
| [] -> (name, tpe, subtpe, mods, blacklist)
- | (Name_Pattern s, b) :: l ->
- let regexp =
- try Str.regexp s
- with e when Errors.noncritical e ->
- Errors.errorlabstrm "Search.interface_search"
- (str "Invalid regexp: " ++ str s)
- in
+ | (Name_Pattern regexp, b) :: l ->
extract_flags ((regexp, b) :: name) tpe subtpe mods blacklist l
- | (Type_Pattern s, b) :: l ->
- let constr = Pcoq.parse_string Pcoq.Constr.lconstr_pattern s in
- let (_, pat) = Constrintern.intern_constr_pattern env constr in
+ | (Type_Pattern pat, b) :: l ->
extract_flags name ((pat, b) :: tpe) subtpe mods blacklist l
- | (SubType_Pattern s, b) :: l ->
- let constr = Pcoq.parse_string Pcoq.Constr.lconstr_pattern s in
- let (_, pat) = Constrintern.intern_constr_pattern env constr in
+ | (SubType_Pattern pat, b) :: l ->
extract_flags name tpe ((pat, b) :: subtpe) mods blacklist l
- | (In_Module m, b) :: l ->
- let path = String.concat "." m in
- let m = Pcoq.parse_string Pcoq.Constr.global path in
- let (_, qid) = Libnames.qualid_of_reference m in
- let id =
- try Nametab.full_name_module qid
- with Not_found ->
- Errors.errorlabstrm "Search.interface_search"
- (str "Module " ++ str path ++ str " not found.")
- in
+ | (In_Module id, b) :: l ->
extract_flags name tpe subtpe ((id, b) :: mods) blacklist l
| (Include_Blacklist, b) :: l ->
extract_flags name tpe subtpe mods b l
in
+ fun ?glnum flags ->
let (name, tpe, subtpe, mods, blacklist) =
extract_flags [] [] [] [] false flags
in
@@ -359,5 +340,5 @@ let interface_search flags =
let iter ref env typ =
if filter_function ref env typ then print_function ref env typ
in
- let () = generic_search None iter in (* TODO: chose a goal number? *)
+ let () = generic_search glnum iter in
!ans
diff --git a/toplevel/search.mli b/toplevel/search.mli
index 78b0c45c0..9f209a17e 100644
--- a/toplevel/search.mli
+++ b/toplevel/search.mli
@@ -47,13 +47,13 @@ val search_about : int option -> (bool * glob_search_about_item) list
type search_constraint =
(** Whether the name satisfies a regexp (uses Ocaml Str syntax) *)
- | Name_Pattern of string
+ | Name_Pattern of Str.regexp
(** Whether the object type satisfies a pattern *)
- | Type_Pattern of string
+ | Type_Pattern of Pattern.constr_pattern
(** Whether some subtype of object type satisfies a pattern *)
- | SubType_Pattern of string
+ | SubType_Pattern of Pattern.constr_pattern
(** Whether the object pertains to a module *)
- | In_Module of string list
+ | In_Module of Names.DirPath.t
(** Bypass the Search blacklist *)
| Include_Blacklist
@@ -63,7 +63,7 @@ type 'a coq_object = {
coq_object_object : 'a;
}
-val interface_search : (search_constraint * bool) list ->
+val interface_search : ?glnum:int -> (search_constraint * bool) list ->
string coq_object list
(** {6 Generic search function} *)
diff --git a/toplevel/usage.ml b/toplevel/usage.ml
index f855c096e..ffbbe7ed4 100644
--- a/toplevel/usage.ml
+++ b/toplevel/usage.ml
@@ -45,6 +45,7 @@ let print_usage_channel co command =
\n -require path load Coq library path and import it (Require Import path.)\
\n -compile f.v compile Coq file f.v (implies -batch)\
\n -compile-verbose f.v verbosely compile Coq file f.v (implies -batch)\
+\n -o f.vo use f.vo as the output file name\
\n -quick quickly compile .v files to .vio files (skip proofs)\
\n -schedule-vio2vo j f1..fn run up to j instances of Coq to turn each fi.vio\
\n into fi.vo\
@@ -77,6 +78,7 @@ let print_usage_channel co command =
\n the directory $COQ_XML_LIBRARY_ROOT (if set) or to\
\n stdout (if unset)\
\n -time display the time taken by each command\
+\n -profile-ltac display the time taken by each (sub)tactic\
\n -m, --memory display total heap size at program exit\
\n (use environment variable\
\n OCAML_GC_STATS=\"/tmp/gclog.txt\"\
diff --git a/toplevel/vernac.ml b/toplevel/vernac.ml
index 89bc31d0a..0a32c88d6 100644
--- a/toplevel/vernac.ml
+++ b/toplevel/vernac.ml
@@ -12,7 +12,6 @@ open Pp
open Errors
open Util
open Flags
-open System
open Vernacexpr
(* The functions in this module may raise (unexplainable!) exceptions.
@@ -120,8 +119,7 @@ let verbose_phrase verbch loc =
let s = String.create len in
seek_in ch (fst loc);
really_input ch s 0 len;
- ppnl (str s);
- pp_flush()
+ Feedback.msg_notice (str s ++ fnl ())
| None -> ()
exception End_of_input
@@ -153,9 +151,9 @@ let pr_new_syntax loc ocom =
| Some com -> Ppvernac.pr_vernac com
| None -> mt() in
if !beautify_file then
- msg (hov 0 (comment (fst loc) ++ com ++ comment (snd loc)))
+ Feedback.msg_notice (hov 0 (comment (fst loc) ++ com ++ comment (snd loc)))
else
- msg_info (hov 4 (str"New Syntax:" ++ fnl() ++ (hov 0 com)));
+ Feedback.msg_info (hov 4 (str"New Syntax:" ++ fnl() ++ (hov 0 com)));
States.unfreeze fs;
Format.set_formatter_out_channel stdout
@@ -163,17 +161,17 @@ let save_translator_coqdoc () =
(* translator state *)
let ch = !chan_beautify in
let cl = !Pp.comments in
- let cs = Lexer.com_state() in
+ let cs = CLexer.com_state() in
(* end translator state *)
- let coqdocstate = Lexer.location_table () in
+ let coqdocstate = CLexer.location_table () in
ch,cl,cs,coqdocstate
let restore_translator_coqdoc (ch,cl,cs,coqdocstate) =
if !Flags.beautify_file then close_out !chan_beautify;
chan_beautify := ch;
Pp.comments := cl;
- Lexer.restore_com_state cs;
- Lexer.restore_location_table coqdocstate
+ CLexer.restore_com_state cs;
+ CLexer.restore_location_table coqdocstate
(* For coqtop -time, we display the position in the file,
and a glimpse of the executed command *)
@@ -194,14 +192,15 @@ let display_cmd_header loc com =
with e -> str (Printexc.to_string e) in
let cmd = noblank (shorten (string_of_ppcmds (safe_pr_vernac com)))
in
- Pp.pp (str "Chars " ++ int start ++ str " - " ++ int stop ++
- str " [" ++ str cmd ++ str "] ");
- Pp.flush_all ()
+ Feedback.msg_notice
+ (str "Chars " ++ int start ++ str " - " ++ int stop ++
+ str " [" ++ str cmd ++ str "] ")
+
let rec vernac_com verbose checknav (loc,com) =
let interp = function
| VernacLoad (verbosely, fname) ->
- let fname = Envars.expand_path_macros ~warn:(fun x -> msg_warning (str x)) fname in
+ let fname = Envars.expand_path_macros ~warn:(fun x -> Feedback.msg_warning (str x)) fname in
let fname = CUnix.make_suffix fname ".v" in
let f = Loadpath.locate_file fname in
let st = save_translator_coqdoc () in
@@ -249,8 +248,7 @@ and read_vernac_file verbosely s =
* raised, which means that we raised the end of the file being loaded *)
while true do
let loc_ast = parse_sentence input in
- vernac_com verbosely checknav loc_ast;
- pp_flush ()
+ vernac_com verbosely checknav loc_ast
done
with any -> (* whatever the exception *)
let (e, info) = Errors.push any in
@@ -292,12 +290,35 @@ let load_vernac verb file =
if !Flags.beautify_file then close_out !chan_beautify;
raise_with_file file (disable_drop e, info)
-let ensure_v f =
- if Filename.check_suffix f ".v" then f
+let ensure_ext ext f =
+ if Filename.check_suffix f ext then f
else begin
- msg_warning (str "File \"" ++ str f ++ strbrk "\" has been implicitly \
- expanded to \"" ++ str f ++ str ".v\"");
- f ^ ".v"
+ Feedback.msg_warning (str "File \"" ++ str f ++ strbrk "\" has been implicitly \
+ expanded to \"" ++ str f ++ str ext ++ str "\"");
+ f ^ ext
+ end
+
+let ensure_bname src tgt =
+ let src, tgt = Filename.basename src, Filename.basename tgt in
+ let src, tgt = Filename.chop_extension src, Filename.chop_extension tgt in
+ if src <> tgt then begin
+ Feedback.msg_error (str "Source and target file names must coincide, directories can differ");
+ Feedback.msg_error (str "Source: " ++ str src);
+ Feedback.msg_error (str "Target: " ++ str tgt);
+ flush_all ();
+ exit 1
+ end
+
+let ensure ext src tgt = ensure_bname src tgt; ensure_ext ext tgt
+
+let ensure_v v = ensure ".v" v v
+let ensure_vo v vo = ensure ".vo" v vo
+let ensure_vio v vio = ensure ".vio" v vio
+
+let ensure_exists f =
+ if not (Sys.file_exists f) then begin
+ Feedback.msg_error (hov 0 (str "Can't find file" ++ spc () ++ str f));
+ exit 1
end
(* Compile a vernac file *)
@@ -305,13 +326,20 @@ let compile verbosely f =
let check_pending_proofs () =
let pfs = Pfedit.get_all_proof_names () in
if not (List.is_empty pfs) then
- (msg_error (str "There are pending proofs"); flush_all (); exit 1) in
+ (Feedback.msg_error (str "There are pending proofs"); flush_all (); exit 1) in
match !Flags.compilation_mode with
| BuildVo ->
let long_f_dot_v = ensure_v f in
- let ldir = Flags.verbosely Library.start_library long_f_dot_v in
- Stm.set_compilation_hints long_f_dot_v;
- Aux_file.start_aux_file_for long_f_dot_v;
+ ensure_exists long_f_dot_v;
+ let long_f_dot_vo =
+ match !Flags.compilation_output_name with
+ | None -> long_f_dot_v ^ "o"
+ | Some f -> ensure_vo long_f_dot_v f in
+ let ldir = Flags.verbosely Library.start_library long_f_dot_vo in
+ Stm.set_compilation_hints long_f_dot_vo;
+ Aux_file.(start_aux_file
+ ~aux_file:(aux_file_name_for long_f_dot_vo)
+ ~v_file:long_f_dot_v);
Dumpglob.start_dump_glob long_f_dot_v;
Dumpglob.dump_string ("F" ^ Names.DirPath.to_string ldir ^ "\n");
if !Flags.xml_export then Hook.get f_xml_start_library ();
@@ -320,7 +348,7 @@ let compile verbosely f =
Stm.join ();
let wall_clock2 = Unix.gettimeofday () in
check_pending_proofs ();
- Library.save_library_to ldir long_f_dot_v (Global.opaque_tables ());
+ Library.save_library_to ldir long_f_dot_vo (Global.opaque_tables ());
Aux_file.record_in_aux_at Loc.ghost "vo_compile_time"
(Printf.sprintf "%.3f" (wall_clock2 -. wall_clock1));
Aux_file.stop_aux_file ();
@@ -328,13 +356,18 @@ let compile verbosely f =
Dumpglob.end_dump_glob ()
| BuildVio ->
let long_f_dot_v = ensure_v f in
- let ldir = Flags.verbosely Library.start_library long_f_dot_v in
+ ensure_exists long_f_dot_v;
+ let long_f_dot_vio =
+ match !Flags.compilation_output_name with
+ | None -> long_f_dot_v ^ "io"
+ | Some f -> ensure_vio long_f_dot_v f in
+ let ldir = Flags.verbosely Library.start_library long_f_dot_vio in
Dumpglob.noglob ();
- Stm.set_compilation_hints long_f_dot_v;
+ Stm.set_compilation_hints long_f_dot_vio;
let _ = load_vernac verbosely long_f_dot_v in
Stm.finish ();
check_pending_proofs ();
- Stm.snapshot_vio ldir long_f_dot_v;
+ Stm.snapshot_vio ldir long_f_dot_vio;
Stm.reset_task_queue ()
| Vio2Vo ->
let open Filename in
diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml
index 38832b422..222b7d3df 100644
--- a/toplevel/vernacentries.ml
+++ b/toplevel/vernacentries.ml
@@ -20,7 +20,6 @@ open Tacmach
open Constrintern
open Prettyp
open Printer
-open Tacinterp
open Command
open Goptions
open Libnames
@@ -34,9 +33,12 @@ open Misctypes
open Locality
open Sigma.Notations
+(** TODO: make this function independent of Ltac *)
+let (f_interp_redexp, interp_redexp_hook) = Hook.make ()
+
let debug = false
-let prerr_endline =
- if debug then prerr_endline else fun _ -> ()
+let prerr_endline x =
+ if debug then prerr_endline (x ()) else ()
(* Misc *)
@@ -46,7 +48,7 @@ let cl_of_qualid = function
| RefClass r -> Class.class_of_global (Smartlocate.smart_global ~head:true r)
let scope_class_of_qualid qid =
- Notation.scope_class_of_reference (Smartlocate.smart_global qid)
+ Notation.scope_class_of_class (cl_of_qualid qid)
(*******************)
(* "Show" commands *)
@@ -55,7 +57,7 @@ let show_proof () =
(* spiwack: this would probably be cooler with a bit of polishing. *)
let p = Proof_global.give_me_the_proof () in
let pprf = Proof.partial_proof p in
- msg_notice (Pp.prlist_with_sep Pp.fnl Printer.pr_constr pprf)
+ Feedback.msg_notice (Pp.prlist_with_sep Pp.fnl Printer.pr_constr pprf)
let show_node () =
(* spiwack: I'm have little clue what this function used to do. I deactivated it,
@@ -63,22 +65,22 @@ let show_node () =
()
let show_thesis () =
- msg_error (anomaly (Pp.str "TODO") )
+ Feedback.msg_error (anomaly (Pp.str "TODO") )
let show_top_evars () =
(* spiwack: new as of Feb. 2010: shows goal evars in addition to non-goal evars. *)
let pfts = get_pftreestate () in
let gls = Proof.V82.subgoals pfts in
let sigma = gls.Evd.sigma in
- msg_notice (pr_evars_int sigma 1 (Evarutil.non_instantiated sigma))
+ Feedback.msg_notice (pr_evars_int sigma 1 (Evarutil.non_instantiated sigma))
let show_universes () =
let pfts = get_pftreestate () in
let gls = Proof.V82.subgoals pfts in
let sigma = gls.Evd.sigma in
let ctx = Evd.universe_context_set (Evd.nf_constraints sigma) in
- msg_notice (Evd.pr_evar_universe_context (Evd.evar_universe_context sigma));
- msg_notice (str"Normalized constraints: " ++ Univ.pr_universe_context_set (Evd.pr_evd_level sigma) ctx)
+ Feedback.msg_notice (Evd.pr_evar_universe_context (Evd.evar_universe_context sigma));
+ Feedback.msg_notice (str"Normalized constraints: " ++ Univ.pr_universe_context_set (Evd.pr_evd_level sigma) ctx)
let show_prooftree () =
(* Spiwack: proof tree is currently not working *)
@@ -89,11 +91,10 @@ let enable_goal_printing = ref true
let print_subgoals () =
if !enable_goal_printing && is_verbose ()
then begin
- msg_notice (pr_open_subgoals ())
+ Feedback.msg_notice (pr_open_subgoals ())
end
let try_print_subgoals () =
- Pp.flush_all();
try print_subgoals () with Proof_global.NoCurrentProof | UserError _ -> ()
@@ -107,10 +108,10 @@ let show_intro all =
let l,_= decompose_prod_assum (strip_outer_cast (pf_concl gl)) in
if all then
let lid = Tactics.find_intro_names l gl in
- msg_notice (hov 0 (prlist_with_sep spc pr_id lid))
+ Feedback.msg_notice (hov 0 (prlist_with_sep spc pr_id lid))
else if not (List.is_empty l) then
let n = List.last l in
- msg_notice (pr_id (List.hd (Tactics.find_intro_names [n] gl)))
+ Feedback.msg_notice (pr_id (List.hd (Tactics.find_intro_names [n] gl)))
end
(** Prepare a "match" template for a given inductive type.
@@ -151,7 +152,7 @@ let show_match id =
let pr_branch l =
str "| " ++ hov 1 (prlist_with_sep spc str l) ++ str " =>"
in
- msg_notice (v 1 (str "match # with" ++ fnl () ++
+ Feedback.msg_notice (v 1 (str "match # with" ++ fnl () ++
prlist_with_sep fnl pr_branch patterns ++ fnl () ++ str "end" ++ fnl ()))
(* "Print" commands *)
@@ -192,23 +193,23 @@ let print_module r =
let globdir = Nametab.locate_dir qid in
match globdir with
DirModule (dirpath,(mp,_)) ->
- msg_notice (Printmod.print_module (Printmod.printable_body dirpath) mp)
+ Feedback.msg_notice (Printmod.print_module (Printmod.printable_body dirpath) mp)
| _ -> raise Not_found
with
- Not_found -> msg_error (str"Unknown Module " ++ pr_qualid qid)
+ Not_found -> Feedback.msg_error (str"Unknown Module " ++ pr_qualid qid)
let print_modtype r =
let (loc,qid) = qualid_of_reference r in
try
let kn = Nametab.locate_modtype qid in
- msg_notice (Printmod.print_modtype kn)
+ Feedback.msg_notice (Printmod.print_modtype kn)
with Not_found ->
(* Is there a module of this name ? If yes we display its type *)
try
let mp = Nametab.locate_module qid in
- msg_notice (Printmod.print_module false mp)
+ Feedback.msg_notice (Printmod.print_module false mp)
with Not_found ->
- msg_error (str"Unknown Module Type or Module " ++ pr_qualid qid)
+ Feedback.msg_error (str"Unknown Module Type or Module " ++ pr_qualid qid)
let print_namespace ns =
let ns = List.rev (Names.DirPath.repr ns) in
@@ -277,7 +278,7 @@ let print_namespace ns =
acc
) constants (str"")
in
- msg_notice ((print_list pr_id ns)++str":"++fnl()++constants_in_namespace)
+ Feedback.msg_notice ((print_list pr_id ns)++str":"++fnl()++constants_in_namespace)
let print_strategy r =
let open Conv_oracle in
@@ -307,7 +308,7 @@ let print_strategy r =
else str "Constant strategies" ++ fnl () ++
hov 0 (prlist_with_sep fnl pr_strategy cst_lvl)
in
- msg_notice (var_msg ++ cst_msg)
+ Feedback.msg_notice (var_msg ++ cst_msg)
| Some r ->
let r = Smartlocate.smart_global r in
let key = match r with
@@ -316,7 +317,7 @@ let print_strategy r =
| IndRef _ | ConstructRef _ -> error "The reference is not unfoldable"
in
let lvl = get_strategy oracle key in
- msg_notice (pr_strategy (r, lvl))
+ Feedback.msg_notice (pr_strategy (r, lvl))
let dump_universes_gen g s =
let output = open_out s in
@@ -334,7 +335,7 @@ let dump_universes_gen g s =
| Univ.Eq ->
Printf.fprintf output " \"%s\" -> \"%s\" [style=dashed];\n" left right
end, begin fun () ->
- if Lazy.lazy_is_val init then Printf.fprintf output "}\n";
+ if Lazy.is_val init then Printf.fprintf output "}\n";
close_out output
end
end else begin
@@ -350,7 +351,7 @@ let dump_universes_gen g s =
try
UGraph.dump_universes output_constraint g;
close ();
- msg_info (str "Universes written to file \"" ++ str s ++ str "\".")
+ Feedback.msg_info (str "Universes written to file \"" ++ str s ++ str "\".")
with reraise ->
let reraise = Errors.push reraise in
close ();
@@ -365,11 +366,11 @@ let locate_file f =
let msg_found_library = function
| Library.LibLoaded, fulldir, file ->
- msg_info (hov 0
+ Feedback.msg_info (hov 0
(pr_dirpath fulldir ++ strbrk " has been loaded from file " ++
str file))
| Library.LibInPath, fulldir, file ->
- msg_info (hov 0
+ Feedback.msg_info (hov 0
(pr_dirpath fulldir ++ strbrk " is bound to file " ++ str file))
let err_unmapped_library loc ?from qid =
@@ -464,14 +465,14 @@ let vernac_definition locality p (local,k) ((loc,id as lid),pl) def =
in
(match def with
| ProveBody (bl,t) -> (* local binders, typ *)
- start_proof_and_print (local,p,DefinitionBody Definition)
- [Some (lid,pl), (bl,t,None)] no_hook
+ start_proof_and_print (local,p,DefinitionBody k)
+ [Some (lid,pl), (bl,t,None)] hook
| DefineBody (bl,red_option,c,typ_opt) ->
let red_option = match red_option with
| None -> None
| Some r ->
let (evc,env)= get_current_context () in
- Some (snd (interp_redexp env evc r)) in
+ Some (snd (Hook.get f_interp_redexp env evc r)) in
do_definition id (local,p,k) pl bl red_option c typ_opt hook)
let vernac_start_proof locality p kind l lettop =
@@ -502,9 +503,9 @@ let vernac_end_proof ?proof = function
let vernac_exact_proof c =
(* spiwack: for simplicity I do not enforce that "Proof proof_term" is
called only at the begining of a proof. *)
- let status = by (Tactics.New.exact_proof c) in
+ let status = by (Tactics.exact_proof c) in
save_proof (Vernacexpr.(Proved(Opaque None,None)));
- if not status then Pp.feedback Feedback.AddedAxiom
+ if not status then Feedback.feedback Feedback.AddedAxiom
let vernac_assumption locality poly (local, kind) l nl =
let local = enforce_locality_exp locality local in
@@ -516,7 +517,7 @@ let vernac_assumption locality poly (local, kind) l nl =
if global then Dumpglob.dump_definition lid false "ax"
else Dumpglob.dump_definition lid true "var") idl) l;
let status = do_assumptions kind nl l in
- if not status then Pp.feedback Feedback.AddedAxiom
+ if not status then Feedback.feedback Feedback.AddedAxiom
let vernac_record k poly finite struc binders sort nameopt cfs =
let const = match nameopt with
@@ -634,7 +635,7 @@ let vernac_declare_module export (loc, id) binders_ast mty_ast =
id binders_ast (Enforce mty_ast) []
in
Dumpglob.dump_moddef loc mp "mod";
- if_verbose msg_info (str "Module " ++ pr_id id ++ str " is declared");
+ if_verbose Feedback.msg_info (str "Module " ++ pr_id id ++ str " is declared");
Option.iter (fun export -> vernac_import export [Ident (Loc.ghost,id)]) export
let vernac_define_module export (loc, id) binders_ast mty_ast_o mexpr_ast_l =
@@ -655,7 +656,7 @@ let vernac_define_module export (loc, id) binders_ast mty_ast_o mexpr_ast_l =
export id binders_ast mty_ast_o
in
Dumpglob.dump_moddef loc mp "mod";
- if_verbose msg_info
+ if_verbose Feedback.msg_info
(str "Interactive Module " ++ pr_id id ++ str " started");
List.iter
(fun (export,id) ->
@@ -673,7 +674,7 @@ let vernac_define_module export (loc, id) binders_ast mty_ast_o mexpr_ast_l =
id binders_ast mty_ast_o mexpr_ast_l
in
Dumpglob.dump_moddef loc mp "mod";
- if_verbose msg_info
+ if_verbose Feedback.msg_info
(str "Module " ++ pr_id id ++ str " is defined");
Option.iter (fun export -> vernac_import export [Ident (Loc.ghost,id)])
export
@@ -681,7 +682,7 @@ let vernac_define_module export (loc, id) binders_ast mty_ast_o mexpr_ast_l =
let vernac_end_module export (loc,id as lid) =
let mp = Declaremods.end_module () in
Dumpglob.dump_modref loc mp "mod";
- if_verbose msg_info (str "Module " ++ pr_id id ++ str " is defined");
+ if_verbose Feedback.msg_info (str "Module " ++ pr_id id ++ str " is defined");
Option.iter (fun export -> vernac_import export [Ident lid]) export
let vernac_declare_module_type (loc,id) binders_ast mty_sign mty_ast_l =
@@ -702,7 +703,7 @@ let vernac_declare_module_type (loc,id) binders_ast mty_sign mty_ast_l =
id binders_ast mty_sign
in
Dumpglob.dump_moddef loc mp "modtype";
- if_verbose msg_info
+ if_verbose Feedback.msg_info
(str "Interactive Module Type " ++ pr_id id ++ str " started");
List.iter
(fun (export,id) ->
@@ -721,13 +722,13 @@ let vernac_declare_module_type (loc,id) binders_ast mty_sign mty_ast_l =
id binders_ast mty_sign mty_ast_l
in
Dumpglob.dump_moddef loc mp "modtype";
- if_verbose msg_info
+ if_verbose Feedback.msg_info
(str "Module Type " ++ pr_id id ++ str " is defined")
let vernac_end_modtype (loc,id) =
let mp = Declaremods.end_modtype () in
Dumpglob.dump_modref loc mp "modtype";
- if_verbose msg_info (str "Module Type " ++ pr_id id ++ str " is defined")
+ if_verbose Feedback.msg_info (str "Module Type " ++ pr_id id ++ str " is defined")
let vernac_include l =
Declaremods.declare_include Modintern.interp_module_ast l
@@ -795,7 +796,7 @@ let vernac_coercion locality poly local ref qids qidt =
let source = cl_of_qualid qids in
let ref' = smart_global ref in
Class.try_add_new_coercion_with_target ref' ~local poly ~source ~target;
- if_verbose msg_info (pr_global ref' ++ str " is now a coercion")
+ if_verbose Feedback.msg_info (pr_global ref' ++ str " is now a coercion")
let vernac_identity_coercion locality poly local id qids qidt =
let local = enforce_locality locality local in
@@ -811,7 +812,7 @@ let vernac_instance abst locality poly sup inst props pri =
ignore(Classes.new_instance ~abstract:abst ~global poly sup inst props pri)
let vernac_context poly l =
- if not (Classes.context poly l) then Pp.feedback Feedback.AddedAxiom
+ if not (Classes.context poly l) then Feedback.feedback Feedback.AddedAxiom
let vernac_declare_instances locality ids pri =
let glob = not (make_section_locality locality) in
@@ -826,35 +827,6 @@ let vernac_declare_class id =
let command_focus = Proof.new_focus_kind ()
let focus_command_cond = Proof.no_cond command_focus
-
-let print_info_trace = ref None
-
-let _ = let open Goptions in declare_int_option {
- optsync = true;
- optdepr = false;
- optname = "print info trace";
- optkey = ["Info" ; "Level"];
- optread = (fun () -> !print_info_trace);
- optwrite = fun n -> print_info_trace := n;
-}
-
-let vernac_solve n info tcom b =
- if not (refining ()) then
- error "Unknown command of the non proof-editing mode.";
- let status = Proof_global.with_current_proof (fun etac p ->
- let with_end_tac = if b then Some etac else None in
- let global = match n with SelectAll -> true | _ -> false in
- let info = Option.append info !print_info_trace in
- let (p,status) =
- solve n info (Tacinterp.hide_interp global tcom None) ?with_end_tac p
- in
- (* in case a strict subtree was completed,
- go back to the top of the prooftree *)
- let p = Proof.maximal_unfocus command_focus p in
- p,status) in
- if not status then Pp.feedback Feedback.AddedAxiom
-
-
(* A command which should be a tactic. It has been
added by Christine to patch an error in the design of the proof
machine, and enables to instantiate existential variables when
@@ -884,20 +856,19 @@ let vernac_set_used_variables e =
(str "Unknown variable: " ++ pr_id id))
l;
let _, to_clear = set_used_variables l in
- (** FIXME: too fragile *)
- let open Tacexpr in
- let tac = { mltac_plugin = "coretactics"; mltac_tactic = "clear" } in
- let tac = { mltac_name = tac; mltac_index = 0 } in
- let arg = Genarg.in_gen (Genarg.rawwit (Genarg.wit_list Constrarg.wit_var)) to_clear in
- let tac = if List.is_empty to_clear then TacId [] else TacML (Loc.ghost, tac, [TacGeneric arg]) in
- vernac_solve SelectAll None tac false
-
+ let to_clear = List.map snd to_clear in
+ Proof_global.with_current_proof begin fun _ p ->
+ if List.is_empty to_clear then (p, ())
+ else
+ let tac = Tactics.clear to_clear in
+ fst (solve SelectAll None tac p), ()
+ end
(*****************************)
(* Auxiliary file management *)
let expand filename =
- Envars.expand_path_macros ~warn:(fun x -> msg_warning (str x)) filename
+ Envars.expand_path_macros ~warn:(fun x -> Feedback.msg_warning (str x)) filename
let vernac_add_loadpath implicit pdir ldiropt =
let pdir = expand pdir in
@@ -917,13 +888,13 @@ let vernac_declare_ml_module locality l =
Mltop.declare_ml_modules local (List.map expand l)
let vernac_chdir = function
- | None -> msg_notice (str (Sys.getcwd()))
+ | None -> Feedback.msg_notice (str (Sys.getcwd()))
| Some path ->
begin
try Sys.chdir (expand path)
- with Sys_error err -> msg_warning (str "Cd failed: " ++ str err)
+ with Sys_error err -> Feedback.msg_warning (str "Cd failed: " ++ str err)
end;
- if_verbose msg_info (str (Sys.getcwd()))
+ if_verbose Feedback.msg_info (str (Sys.getcwd()))
(********************)
@@ -942,81 +913,6 @@ let vernac_restore_state file =
(************)
(* Commands *)
-type tacdef_kind =
- | NewTac of Id.t
- | UpdateTac of Nametab.ltac_constant
-
-let is_defined_tac kn =
- try ignore (Tacenv.interp_ltac kn); true with Not_found -> false
-
-let register_ltac local tacl =
- let map tactic_body =
- match tactic_body with
- | TacticDefinition ((loc,id), body) ->
- let kn = Lib.make_kn id in
- let id_pp = pr_id id in
- let () = if is_defined_tac kn then
- Errors.user_err_loc (loc, "",
- str "There is already an Ltac named " ++ id_pp ++ str".")
- in
- let is_primitive =
- try
- match Pcoq.parse_string Pcoq.Tactic.tactic (Id.to_string id) with
- | Tacexpr.TacArg _ -> false
- | _ -> true (* most probably TacAtom, i.e. a primitive tactic ident *)
- with e when Errors.noncritical e -> true (* prim tactics with args, e.g. "apply" *)
- in
- let () = if is_primitive then
- msg_warning (str "The Ltac name " ++ id_pp ++
- str " may be unusable because of a conflict with a notation.")
- in
- NewTac id, body
- | TacticRedefinition (ident, body) ->
- let loc = loc_of_reference ident in
- let kn =
- try Nametab.locate_tactic (snd (qualid_of_reference ident))
- with Not_found ->
- Errors.user_err_loc (loc, "",
- str "There is no Ltac named " ++ pr_reference ident ++ str ".")
- in
- UpdateTac kn, body
- in
- let rfun = List.map map tacl in
- let recvars =
- let fold accu (op, _) = match op with
- | UpdateTac _ -> accu
- | NewTac id -> (Lib.make_path id, Lib.make_kn id) :: accu
- in
- List.fold_left fold [] rfun
- in
- let ist = Tacintern.make_empty_glob_sign () in
- let map (name, body) =
- let body = Flags.with_option Tacintern.strict_check (Tacintern.intern_tactic_or_tacarg ist) body in
- (name, body)
- in
- let defs () =
- (** Register locally the tactic to handle recursivity. This function affects
- the whole environment, so that we transactify it afterwards. *)
- let iter_rec (sp, kn) = Nametab.push_tactic (Nametab.Until 1) sp kn in
- let () = List.iter iter_rec recvars in
- List.map map rfun
- in
- let defs = Future.transactify defs () in
- let iter (def, tac) = match def with
- | NewTac id ->
- Tacenv.register_ltac false local id tac;
- Flags.if_verbose msg_info (Nameops.pr_id id ++ str " is defined")
- | UpdateTac kn ->
- Tacenv.redefine_ltac local kn tac;
- let name = Nametab.shortest_qualid_of_tactic kn in
- Flags.if_verbose msg_info (Libnames.pr_qualid name ++ str " is redefined")
- in
- List.iter iter defs
-
-let vernac_declare_tactic_definition locality def =
- let local = make_module_locality locality in
- register_ltac local def
-
let vernac_create_hintdb locality id b =
let local = make_module_locality locality in
Hints.create_hint_db local id full_transparent_state b
@@ -1171,7 +1067,7 @@ let vernac_declare_arguments locality r l nargs flags =
some_scopes_specified ||
some_simpl_flags_specified) &&
no_flags then
- msg_warning (strbrk "This command is just asserting the number and names of arguments of " ++ pr_global sr ++ strbrk". If this is what you want add ': assert' to silence the warning. If you want to clear implicit arguments add ': clear implicits'. If you want to clear notation scopes add ': clear scopes'")
+ Feedback.msg_warning (strbrk "This command is just asserting the number and names of arguments of " ++ pr_global sr ++ strbrk". If this is what you want add ': assert' to silence the warning. If you want to clear implicit arguments add ': clear implicits'. If you want to clear notation scopes add ': clear scopes'")
let default_env () = {
@@ -1433,18 +1329,6 @@ let _ =
optread = Flags.get_dump_bytecode;
optwrite = Flags.set_dump_bytecode }
-let vernac_debug b =
- set_debug (if b then Tactic_debug.DebugOn 0 else Tactic_debug.DebugOff)
-
-let _ =
- declare_bool_option
- { optsync = false;
- optdepr = false;
- optname = "Ltac debug";
- optkey = ["Ltac";"Debug"];
- optread = (fun () -> get_debug () != Tactic_debug.DebugOff);
- optwrite = vernac_debug }
-
let _ =
declare_bool_option
{ optsync = true;
@@ -1538,23 +1422,22 @@ let vernac_check_may_eval redexp glopt rc =
| None ->
let l = Evar.Set.union (Evd.evars_of_term j.Environ.uj_val) (Evd.evars_of_term j.Environ.uj_type) in
let j = { j with Environ.uj_type = Reductionops.nf_betaiota sigma' j.Environ.uj_type } in
- msg_notice (print_judgment env sigma' j ++
+ Feedback.msg_notice (print_judgment env sigma' j ++
pr_ne_evar_set (fnl () ++ str "where" ++ fnl ()) (mt ()) sigma' l ++
Printer.pr_universe_ctx sigma uctx)
| Some r ->
- Tacintern.dump_glob_red_expr r;
- let (sigma',r_interp) = interp_redexp env sigma' r in
+ let (sigma',r_interp) = Hook.get f_interp_redexp env sigma' r in
let redfun env evm c =
let (redfun, _) = reduction_of_red_expr env r_interp in
let evm = Sigma.Unsafe.of_evar_map evm in
let Sigma (c, _, _) = redfun.Reductionops.e_redfun env evm c in
c
in
- msg_notice (print_eval redfun env sigma' rc j)
+ Feedback.msg_notice (print_eval redfun env sigma' rc j)
let vernac_declare_reduction locality s r =
let local = make_locality locality in
- declare_red_expr local s (snd (interp_redexp (Global.env()) Evd.empty r))
+ declare_red_expr local s (snd (Hook.get f_interp_redexp (Global.env()) Evd.empty r))
(* The same but avoiding the current goal context if any *)
let vernac_global_check c =
@@ -1566,7 +1449,7 @@ let vernac_global_check c =
let senv = Safe_typing.add_constraints cstrs senv in
let j = Safe_typing.typing senv c in
let env = Safe_typing.env_of_safe_env senv in
- msg_notice (print_safe_judgment env sigma j)
+ Feedback.msg_notice (print_safe_judgment env sigma j)
let get_nth_goal n =
@@ -1603,7 +1486,7 @@ let print_about_hyp_globs ref_or_by_not glnumopt =
| NoHyp | Not_found -> print_about ref_or_by_not
-let vernac_print = function
+let vernac_print = let open Feedback in function
| PrintTables -> msg_notice (print_tables ())
| PrintFullContext-> msg_notice (print_full_context_typ ())
| PrintSectionContext qid -> msg_notice (print_sec_context_typ qid)
@@ -1622,7 +1505,6 @@ let vernac_print = function
| PrintClasses -> msg_notice (Prettyp.print_classes())
| PrintTypeClasses -> msg_notice (Prettyp.print_typeclasses())
| PrintInstances c -> msg_notice (Prettyp.print_instances (smart_global c))
- | PrintLtac qid -> msg_notice (Tacintern.print_ltac (snd (qualid_of_reference qid)))
| PrintCoercions -> msg_notice (Prettyp.print_coercions())
| PrintCoercionPaths (cls,clt) ->
msg_notice (Prettyp.print_path_between (cl_of_qualid cls) (cl_of_qualid clt))
@@ -1641,7 +1523,6 @@ let vernac_print = function
| PrintHint r -> msg_notice (Hints.pr_hint_ref (smart_global r))
| PrintHintGoal -> msg_notice (Hints.pr_applicable_hint ())
| PrintHintDbName s -> msg_notice (Hints.pr_hint_db_by_name s)
- | PrintRewriteHintDbName s -> msg_notice (Autorewrite.print_rewrite_hintdb s)
| PrintHintDb -> msg_notice (Hints.pr_searchtable ())
| PrintScopes ->
msg_notice (Notation.pr_scopes (Constrextern.without_symbols pr_lglob_constr))
@@ -1704,6 +1585,7 @@ let vernac_search s gopt r =
| Some g -> snd (Pfedit.get_goal_context g) , Some g
in
let get_pattern c = snd (intern_constr_pattern env c) in
+ let open Feedback in
match s with
| SearchPattern c ->
msg_notice (Search.search_pattern gopt (get_pattern c) r)
@@ -1714,8 +1596,8 @@ let vernac_search s gopt r =
| SearchAbout sl ->
msg_notice (Search.search_about gopt (List.map (on_snd (interp_search_about_item env)) sl) r)
-let vernac_locate = function
- | LocateAny (AN qid) -> msg_notice (print_located_qualid qid)
+let vernac_locate = let open Feedback in function
+ | LocateAny (AN qid) -> msg_notice (print_located_qualid qid)
| LocateTerm (AN qid) -> msg_notice (print_located_term qid)
| LocateAny (ByNotation (_, ntn, sc)) (** TODO : handle Ltac notations *)
| LocateTerm (ByNotation (_, ntn, sc)) ->
@@ -1758,7 +1640,7 @@ let vernac_unfocus () =
let vernac_unfocused () =
let p = Proof_global.give_me_the_proof () in
if Proof.unfocused p then
- msg_notice (str"The proof is indeed fully unfocused.")
+ Feedback.msg_notice (str"The proof is indeed fully unfocused.")
else
error "The proof is not fully unfocused."
@@ -1786,7 +1668,7 @@ let vernac_bullet (bullet:Proof_global.Bullet.t) =
Proof_global.simple_with_current_proof (fun _ p ->
Proof_global.Bullet.put p bullet)
-let vernac_show = function
+let vernac_show = let open Feedback in function
| ShowGoal goalref ->
let info = match goalref with
| OpenSubgoals -> pr_open_subgoals ()
@@ -1824,7 +1706,7 @@ let vernac_check_guard () =
with UserError(_,s) ->
(str ("Condition violated: ") ++s)
in
- msg_notice message
+ Feedback.msg_notice message
exception End_of_input
@@ -1835,7 +1717,7 @@ let vernac_load interp fname =
| Some x -> x
| None -> raise End_of_input) in
let fname =
- Envars.expand_path_macros ~warn:(fun x -> msg_warning (str x)) fname in
+ Envars.expand_path_macros ~warn:(fun x -> Feedback.msg_warning (str x)) fname in
let fname = CUnix.make_suffix fname ".v" in
let input =
let longfname = Loadpath.locate_file fname in
@@ -1850,7 +1732,7 @@ let vernac_load interp fname =
* still parsed as the obsolete_locality grammar entry for retrocompatibility.
* loc is the Loc.t of the vernacular command being interpreted. *)
let interp ?proof ~loc locality poly c =
- prerr_endline ("interpreting: " ^ Pp.string_of_ppcmds (Ppvernac.pr_vernac c));
+ prerr_endline (fun () -> "interpreting: " ^ Pp.string_of_ppcmds (Ppvernac.pr_vernac c));
match c with
(* Done later in this file *)
| VernacLoad _ -> assert false
@@ -1863,8 +1745,6 @@ let interp ?proof ~loc locality poly c =
| VernacError e -> raise e
(* Syntax *)
- | VernacTacticNotation (n,r,e) ->
- Metasyntax.add_tactic_notation (make_module_locality locality,n,r,e)
| VernacSyntaxExtension (local,sl) ->
vernac_syntax_extension locality local sl
| VernacDelimiters (sc,lr) -> vernac_delimiters sc lr
@@ -1922,7 +1802,6 @@ let interp ?proof ~loc locality poly c =
| VernacDeclareClass id -> vernac_declare_class id
(* Solving *)
- | VernacSolve (n,info,tac,b) -> vernac_solve n info tac b
| VernacSolveExistential (n,c) -> vernac_solve_existential n c
(* Auxiliary file and library management *)
@@ -1943,8 +1822,6 @@ let interp ?proof ~loc locality poly c =
| VernacBackTo _ -> anomaly (str "VernacBackTo not handled by Stm")
(* Commands *)
- | VernacDeclareTacticDefinition def ->
- vernac_declare_tactic_definition locality def
| VernacCreateHintDb (dbname,b) -> vernac_create_hintdb locality dbname b
| VernacRemoveHints (dbnames,ids) -> vernac_remove_hints locality dbnames ids
| VernacHints (local,dbnames,hints) ->
@@ -1972,15 +1849,15 @@ let interp ?proof ~loc locality poly c =
| VernacSearch (s,g,r) -> vernac_search s g r
| VernacLocate l -> vernac_locate l
| VernacRegister (id, r) -> vernac_register id r
- | VernacComments l -> if_verbose msg_info (str "Comments ok\n")
+ | VernacComments l -> if_verbose Feedback.msg_info (str "Comments ok\n")
(* The STM should handle that, but LOAD bypasses the STM... *)
- | VernacAbort id -> msg_warning (str "VernacAbort not handled by Stm")
- | VernacAbortAll -> msg_warning (str "VernacAbortAll not handled by Stm")
- | VernacRestart -> msg_warning (str "VernacRestart not handled by Stm")
- | VernacUndo _ -> msg_warning (str "VernacUndo not handled by Stm")
- | VernacUndoTo _ -> msg_warning (str "VernacUndoTo not handled by Stm")
- | VernacBacktrack _ -> msg_warning (str "VernacBacktrack not handled by Stm")
+ | VernacAbort id -> Feedback.msg_warning (str "VernacAbort not handled by Stm")
+ | VernacAbortAll -> Feedback.msg_warning (str "VernacAbortAll not handled by Stm")
+ | VernacRestart -> Feedback.msg_warning (str "VernacRestart not handled by Stm")
+ | VernacUndo _ -> Feedback.msg_warning (str "VernacUndo not handled by Stm")
+ | VernacUndoTo _ -> Feedback.msg_warning (str "VernacUndoTo not handled by Stm")
+ | VernacBacktrack _ -> Feedback.msg_warning (str "VernacBacktrack not handled by Stm")
(* Proof management *)
| VernacGoal t -> vernac_start_proof locality poly Theorem [None,([],t,None)] false
@@ -2020,15 +1897,13 @@ let check_vernac_supports_locality c l =
match l, c with
| None, _ -> ()
| Some _, (
- VernacTacticNotation _
- | VernacOpenCloseScope _
+ VernacOpenCloseScope _
| VernacSyntaxExtension _ | VernacInfix _ | VernacNotation _
| VernacDefinition _ | VernacFixpoint _ | VernacCoFixpoint _
| VernacAssumption _ | VernacStartTheoremProof _
| VernacCoercion _ | VernacIdentityCoercion _
| VernacInstance _ | VernacDeclareInstances _
| VernacDeclareMLModule _
- | VernacDeclareTacticDefinition _
| VernacCreateHintDb _ | VernacRemoveHints _ | VernacHints _
| VernacSyntacticDefinition _
| VernacArgumentsScope _ | VernacDeclareImplicits _ | VernacArguments _
@@ -2116,7 +1991,7 @@ let with_fail b f =
| HasNotFailed ->
errorlabstrm "Fail" (str "The command has not failed!")
| HasFailed msg ->
- if is_verbose () || !test_mode || !ide_slave then msg_info
+ if is_verbose () || !test_mode || !ide_slave then Feedback.msg_info
(str "The command has indeed failed with message:" ++ fnl () ++ msg)
| _ -> assert false
end
@@ -2141,7 +2016,7 @@ let interp ?(verbosely=true) ?proof (loc,c) =
current_timeout := Some n;
aux ?locality ?polymorphism isprogcmd v
| VernacRedirect (s, (_,v)) ->
- Pp.with_output_to_file s (aux false) v
+ Feedback.with_output_to_file s (aux false) v
| VernacTime (_,v) ->
System.with_time !Flags.time
(aux ?locality ?polymorphism isprogcmd) v;
diff --git a/toplevel/vernacentries.mli b/toplevel/vernacentries.mli
index 451ccdb4d..4e7fa4a08 100644
--- a/toplevel/vernacentries.mli
+++ b/toplevel/vernacentries.mli
@@ -59,3 +59,8 @@ val vernac_end_proof :
?proof:Proof_global.closed_proof -> Vernacexpr.proof_end -> unit
val with_fail : bool -> (unit -> unit) -> unit
+
+val command_focus : unit Proof.focus_kind
+
+val interp_redexp_hook : (Environ.env -> Evd.evar_map -> Tacexpr.raw_red_expr ->
+ Evd.evar_map * Redexpr.red_expr) Hook.t
diff --git a/toplevel/vernacinterp.ml b/toplevel/vernacinterp.ml
index 7fbd2b119..1116a3104 100644
--- a/toplevel/vernacinterp.ml
+++ b/toplevel/vernacinterp.ml
@@ -55,7 +55,7 @@ let call ?locality (opn,converted_args) =
| Egramml.GramNonTerminal _ -> str "_"
in
let pr = pr_sequence pr_gram rules in
- msg_warning (str "Deprecated vernacular command: " ++ pr)
+ Feedback.msg_warning (str "Deprecated vernacular command: " ++ pr)
in
loc:= "Checking arguments";
let hunk = callback converted_args in
@@ -68,5 +68,5 @@ let call ?locality (opn,converted_args) =
| reraise ->
let reraise = Errors.push reraise in
if !Flags.debug then
- msg_debug (str"Vernac Interpreter " ++ str !loc);
+ Feedback.msg_debug (str"Vernac Interpreter " ++ str !loc);
iraise reraise